ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
bmcMaj3.c
Go to the documentation of this file.
1
20
21#include "bmc.h"
22#include "misc/extra/extra.h"
23#include "misc/util/utilTruth.h"
25#include "opt/dau/dau.h"
26
28
29
33
34#define MAJ3_OBJS 32 // nVars + nNodes
35
36typedef struct Maj3_Man_t_ Maj3_Man_t;
38{
39 int nVars; // inputs
40 int nNodes; // internal nodes
41 int nObjs; // total objects (nVars inputs, nNodes internal nodes)
42 int nWords; // the truth table size in 64-bit words
43 int iVar; // the next available SAT variable
44 Vec_Wrd_t * vInfo; // nVars + nNodes + 1
45 Vec_Int_t * vLevels; // distriction of nodes by levels
46 int VarMarks[MAJ3_OBJS][MAJ3_OBJS]; // variable marks
47 int ObjVals[MAJ3_OBJS]; // object values
48 int pLits[2][MAJ3_OBJS]; // neg, pos literals
49 int nLits[3]; // neg, pos, fixed literal
50 bmcg_sat_solver * pSat; // SAT solver
51};
52
53static inline word * Maj3_ManTruth( Maj3_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); }
54
58
70static inline int Maj3_ManValue( int iMint, int nVars )
71{
72 int k, Count = 0;
73 for ( k = 0; k < nVars; k++ )
74 Count += (iMint >> k) & 1;
75 return (int)(Count > nVars/2);
76}
78{
79 Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs + 1) );
80 int i, nMints = Abc_MaxInt( 64, 1 << p->nVars );
81 for ( i = 0; i < p->nVars; i++ )
82 Abc_TtIthVar( Maj3_ManTruth(p, i), i, p->nVars );
83 for ( i = 0; i < nMints; i++ )
84 if ( Maj3_ManValue(i, p->nVars) )
85 Abc_TtSetBit( Maj3_ManTruth(p, p->nObjs), i );
86 //Dau_DsdPrintFromTruth( Maj3_ManTruth(p, p->nObjs), p->nVars );
87 return vInfo;
88}
89void Maj3_ManFirstAndLevel( Vec_Int_t * vLevels, int Firsts[MAJ3_OBJS], int Levels[MAJ3_OBJS], int nVars, int nObjs )
90{
91 int i, k, Entry, Obj = 0;
92 Firsts[0] = Obj;
93 for ( k = 0; k < nVars; k++ )
94 Levels[Obj++] = 0;
95 Vec_IntReverseOrder( vLevels );
96 Vec_IntForEachEntry( vLevels, Entry, i )
97 {
98 Firsts[i+1] = Obj;
99 for ( k = 0; k < Entry; k++ )
100 Levels[Obj++] = i+1;
101 }
102 Vec_IntReverseOrder( vLevels );
103 assert( Obj == nObjs );
104}
106{
107 int nSatVars = 2; // SAT variable counter
108 int nLevels = Vec_IntSize(p->vLevels);
109 int nSecond = Vec_IntEntry(p->vLevels, 1);
110 int i, k, Firsts[MAJ3_OBJS], Levels[MAJ3_OBJS];
111 assert( Vec_IntEntry(p->vLevels, 0) == 1 );
112 assert( p->nObjs <= MAJ3_OBJS );
113 assert( p->nNodes == Vec_IntSum(p->vLevels) );
114 Maj3_ManFirstAndLevel( p->vLevels, Firsts, Levels, p->nVars, p->nObjs );
115 // create map
116 for ( i = 0; i < p->nObjs; i++ )
117 for ( k = 0; k < p->nObjs; k++ )
118 p->VarMarks[i][k] = -1;
119 for ( k = 0; k < 3; k++ ) // first node
120 p->VarMarks[p->nVars][k] = 1;
121 for ( k = 0; k < nSecond; k++ ) // top node
122 p->VarMarks[p->nObjs-1][p->nObjs-2-k] = 1;
123 for ( k = 2; k < nLevels; k++ ) // cascade
124 p->VarMarks[Firsts[k]][Firsts[k-1]] = 1;
125 for ( i = p->nVars+1; i < (nSecond == 3 ? p->nObjs-1 : p->nObjs); i++ )
126 for ( k = 0; k < Firsts[Levels[i]]; k++ )
127 if ( p->VarMarks[i][k] == -1 )
128 p->VarMarks[i][k] = nSatVars++;
129 //printf( "The number of variables is %d.\n", nSatVars );
130 return nSatVars;
131}
133{
134 int i, k, Firsts[MAJ3_OBJS], Levels[MAJ3_OBJS];
135 Maj3_ManFirstAndLevel( p->vLevels, Firsts, Levels, p->nVars, p->nObjs );
136 // print
137 printf( "Variable map for problem with %d inputs, %d nodes and %d levels: ", p->nVars, p->nNodes, Vec_IntSize(p->vLevels) );
138 Vec_IntPrint( p->vLevels );
139 printf( " " );
140 printf( " " );
141 for ( i = 0; i < p->nObjs; i++ )
142 printf( "%3d ", i );
143 printf( "\n" );
144 for ( i = p->nObjs-1; i >= p->nVars; i-- )
145 {
146 printf( " %2d ", i );
147 printf( " %2d ", Levels[i] );
148 for ( k = 0; k < p->nObjs; k++ )
149 if ( p->VarMarks[i][k] == -1 )
150 printf( " . " );
151 else if ( p->VarMarks[i][k] == 1 )
152 printf( " + " );
153 else
154 printf( "%3d%c ", p->VarMarks[i][k], bmcg_sat_solver_read_cex_varvalue(p->pSat, p->VarMarks[i][k]) ? '+' : ' ' );
155 printf( "\n" );
156 }
157}
158
170static inline int Maj3_ManFindFanin( Maj3_Man_t * p, int i, int * pFanins )
171{
172 int f, nFanins = 0;
173 p->nLits[0] = p->nLits[1] = p->nLits[2] = 0;
174 for ( f = 0; f < i; f++ )
175 {
176 if ( p->VarMarks[i][f] < 0 )
177 continue;
178 assert( p->VarMarks[i][f] > 0 );
179 if ( p->VarMarks[i][f] == 1 ) // fixed
180 {
181 p->nLits[2]++;
182 pFanins[nFanins++] = f;
183 }
184 else if ( bmcg_sat_solver_read_cex_varvalue(p->pSat, p->VarMarks[i][f]) ) // pos
185 {
186 p->pLits[1][p->nLits[1]++] = Abc_Var2Lit(p->VarMarks[i][f], 1);
187 pFanins[nFanins++] = f;
188 }
189 else // neg
190 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit(p->VarMarks[i][f], 0);
191 }
192 return nFanins;
193}
194static inline void Maj3_ManPrintSolution( Maj3_Man_t * p )
195{
196 int i, k, iVar, nFanins, pFanins[MAJ3_OBJS];
197 printf( "Realization of %d-input majority using %d MAJ3 gates:\n", p->nVars, p->nNodes );
198// for ( i = p->nVars; i < p->nObjs; i++ )
199 for ( i = p->nObjs - 1; i >= p->nVars; i-- )
200 {
201 printf( "%02d = MAJ(", i );
202 nFanins = Maj3_ManFindFanin( p, i, pFanins );
203 assert( nFanins == 3 );
204 for ( k = 0; k < 3; k++ )
205 {
206 iVar = pFanins[k];
207 if ( iVar >= 0 && iVar < p->nVars )
208 printf( " %c", 'a'+iVar );
209 else
210 printf( " %02d", iVar );
211 }
212 printf( " )\n" );
213 }
214}
215static inline int Maj3_ManEval( Maj3_Man_t * p )
216{
217 int fUseMiddle = 1;
218 static int Flag = 0;
219 int i, k, iMint, pFanins[3]; word * pFaninsW[3];
220 for ( i = p->nVars; i < p->nObjs; i++ )
221 {
222 int nFanins = Maj3_ManFindFanin( p, i, pFanins );
223 assert( nFanins == 3 );
224 for ( k = 0; k < 3; k++ )
225 pFaninsW[k] = Maj3_ManTruth( p, pFanins[k] );
226 Abc_TtMaj( Maj3_ManTruth(p, i), pFaninsW[0], pFaninsW[1], pFaninsW[2], p->nWords );
227 }
228 if ( fUseMiddle )
229 {
230 iMint = -1;
231 for ( i = 0; i < (1 << p->nVars); i++ )
232 {
233 int nOnes = Abc_TtBitCount16(i);
234 if ( nOnes < p->nVars/2 || nOnes > p->nVars/2+1 )
235 continue;
236 if ( Abc_TtGetBit(Maj3_ManTruth(p, p->nObjs), i) == Abc_TtGetBit(Maj3_ManTruth(p, p->nObjs-1), i) )
237 continue;
238 iMint = i;
239 break;
240 }
241 }
242 else
243 {
244 if ( Flag && p->nVars >= 6 )
245 iMint = Abc_TtFindLastDiffBit( Maj3_ManTruth(p, p->nObjs-1), Maj3_ManTruth(p, p->nObjs), p->nVars );
246 else
247 iMint = Abc_TtFindFirstDiffBit( Maj3_ManTruth(p, p->nObjs-1), Maj3_ManTruth(p, p->nObjs), p->nVars );
248 }
249 //Flag ^= 1;
250 assert( iMint < (1 << p->nVars) );
251 return iMint;
252}
253
254
266void Maj3_PrintClause( int * pLits, int nLits )
267{
268 int i;
269 for ( i = 0; i < nLits; i++ )
270 printf( "%c%d ", Abc_LitIsCompl(pLits[i]) ? '-' : '+', Abc_Lit2Var(pLits[i]) );
271 printf( "\n" );
272}
274{
275 int i, k, status, nLits, pLits[MAJ3_OBJS];
276 // nodes have at least one fanin
277 //printf( "Fanin clauses:\n" );
278 for ( i = p->nVars; i < p->nObjs; i++ )
279 {
280 // check if it is already connected
281 int Count = 0;
282 for ( k = 0; k < p->nObjs; k++ )
283 Count += p->VarMarks[i][k] == 1;
284 assert( Count <= 3 );
285 if ( Count == 3 )
286 continue;
287 // collect connections
288 nLits = 0;
289 for ( k = 0; k < p->nObjs; k++ )
290 if ( p->VarMarks[i][k] > 1 )
291 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k], 0 );
292 //Maj3_PrintClause( pLits, nLits );
293 assert( nLits > 0 );
294 if ( nLits > 0 && !bmcg_sat_solver_addclause( p->pSat, pLits, nLits ) )
295 assert(0);
296 }
297 // nodes have at least one fanout
298 //printf( "Fanout clauses:\n" );
299 for ( k = 0; k < p->nObjs-1; k++ )
300 {
301 // check if it is already connected
302 int Count = 0;
303 for ( i = 0; i < p->nObjs; i++ )
304 Count += p->VarMarks[i][k] == 1;
305 assert( Count <= 3 );
306 if ( Count > 0 )
307 continue;
308 // collect connections
309 nLits = 0;
310 for ( i = 0; i < p->nObjs; i++ )
311 if ( p->VarMarks[i][k] > 1 )
312 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k], 0 );
313 //Maj3_PrintClause( pLits, nLits );
314 //assert( nLits > 0 );
315 if ( nLits > 0 && !bmcg_sat_solver_addclause( p->pSat, pLits, nLits ) )
316 assert(0);
317 }
318 status = bmcg_sat_solver_solve( p->pSat, NULL, 0 );
319 assert( status == GLUCOSE_SAT );
321 return 1;
322}
323int Maj3_ManAddCnf( Maj3_Man_t * p, int iMint )
324{
325 // input values
326 int i, k, j, n, * pVals = p->ObjVals;
327 for ( i = 0; i < p->nVars; i++ )
328 pVals[i] = (iMint >> i) & 1;
329 // first node value
330 pVals[p->nVars] = (pVals[0] && pVals[1]) || (pVals[0] && pVals[2]) || (pVals[1] && pVals[2]);
331 // last node value
332 pVals[p->nObjs-1] = Maj3_ManValue(iMint, p->nVars);
333 // intermediate node values
334 for ( i = p->nVars + 1; i < p->nObjs - 1; i++ )
335 pVals[i] = p->iVar++;
336 //printf( "Adding clauses for minterm %d.\n", iMint );
337 bmcg_sat_solver_set_nvars( p->pSat, p->iVar );
338 for ( n = 0; n < 2; n++ )
339 for ( i = p->nVars + 1; i < p->nObjs; i++ )
340 {
341 //printf( "\nNode %d. Phase %d.\n", i, n );
342 for ( k = 0; k < p->nObjs; k++ ) if ( p->VarMarks[i][k] >= 1 )
343 {
344 // add first input
345 int pLits[5], nLits = 0;
346 if ( pVals[k] == !n )
347 continue;
348 if ( pVals[k] > 1 )
349 pLits[nLits++] = Abc_Var2Lit( pVals[k], n );
350 if ( p->VarMarks[i][k] > 1 )
351 pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k], 1 );
352 for ( j = k+1; j < p->nObjs; j++ ) if ( p->VarMarks[i][j] >= 1 )
353 {
354 // add second input
355 int nLits2 = nLits;
356 if ( pVals[j] == !n )
357 continue;
358 if ( pVals[j] > 1 )
359 pLits[nLits2++] = Abc_Var2Lit( pVals[j], n );
360 if ( p->VarMarks[i][j] > 1 )
361 pLits[nLits2++] = Abc_Var2Lit( p->VarMarks[i][j], 1 );
362 // add output
363 if ( pVals[i] == n )
364 continue;
365 if ( pVals[i] > 1 )
366 pLits[nLits2++] = Abc_Var2Lit( pVals[i], !n );
367 assert( nLits2 > 0 && nLits2 <= 5 );
368 //Maj3_PrintClause( pLits, nLits2 );
369 if ( !bmcg_sat_solver_addclause( p->pSat, pLits, nLits2 ) )
370 return 0;
371 }
372 }
373 }
374 return 1;
375}
377{
378 int i, pFanins[MAJ3_OBJS], nConstr = 0;
379 //Maj3_ManVarMapPrint( p );
380 for ( i = p->nVars+1; i < p->nObjs; i++ )
381 {
382 int nFanins = Maj3_ManFindFanin( p, i, pFanins );
383 if ( nFanins == 3 )
384 continue;
385 //printf( "Node %d has %d fanins.\n", i, nFanins );
386 nConstr++;
387 if ( nFanins < 3 )
388 {
389 assert( p->nLits[0] > 0 );
390 //Maj3_PrintClause( p->pLits[0], p->nLits[0] );
391 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
392 return -1;
393 }
394 else if ( nFanins > 3 )
395 {
396 int nLits = Abc_MinInt(4 - p->nLits[2], p->nLits[1]);
397 assert( nLits > 0 );
398 //Maj3_PrintClause( p->pLits[1], nLits );
399 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[1], nLits ) )
400 return -1;
401 }
402 }
403 return nConstr;
404}
405
417Maj3_Man_t * Maj3_ManAlloc( int nVars, int nNodes, Vec_Int_t * vLevels )
418{
420 p->vLevels = vLevels;
421 p->nVars = nVars;
422 p->nNodes = nNodes;
423 p->nObjs = nVars + nNodes;
424 p->nWords = Abc_TtWordNum(nVars);
425 p->iVar = Maj3_ManMarkup( p );
426 p->vInfo = Maj3_ManTruthTables( p );
427 p->pSat = bmcg_sat_solver_start();
428 bmcg_sat_solver_set_nvars( p->pSat, p->iVar );
430 return p;
431}
433{
434 bmcg_sat_solver_stop( p->pSat );
435 Vec_WrdFree( p->vInfo );
436 ABC_FREE( p );
437}
438
450int Maj3_ManExactSynthesis( int nVars, int nNodes, int fVerbose, Vec_Int_t * vLevels )
451{
452 Maj3_Man_t * p; abctime clkTotal = Abc_Clock();
453 int i, status, nLazy, nLazyAll = 0, iMint = 0;
454 printf( "Running exact synthesis for %d-input majority with %d MAJ3 gates...\n", nVars, nNodes );
455 p = Maj3_ManAlloc( nVars, nNodes, vLevels );
456 for ( i = 0; iMint != -1; i++ )
457 {
458 abctime clk = Abc_Clock();
459 if ( !Maj3_ManAddCnf( p, iMint ) )
460 break;
461 while ( (status = bmcg_sat_solver_solve(p->pSat, NULL, 0)) == GLUCOSE_SAT )
462 {
463 nLazy = Maj3_ManAddConstraintsLazy( p );
464 if ( nLazy == -1 )
465 {
466 printf( "Became UNSAT after adding lazy constraints.\n" );
467 status = GLUCOSE_UNSAT;
468 break;
469 }
470 //printf( "Added %d lazy constraints.\n\n", nLazy );
471 if ( nLazy == 0 )
472 break;
473 nLazyAll += nLazy;
474 }
475 if ( fVerbose )
476 {
477 printf( "Iter %3d : ", i );
478 Extra_PrintBinary( stdout, (unsigned *)&iMint, p->nVars );
479 printf( " Var =%5d ", p->iVar );
480 printf( "Cla =%6d ", bmcg_sat_solver_clausenum(p->pSat) );
481 printf( "Conf =%9d ", bmcg_sat_solver_conflictnum(p->pSat) );
482 printf( "Lazy =%9d ", nLazyAll );
483 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
484 }
485 if ( status == GLUCOSE_UNSAT )
486 {
487 printf( "The problem has no solution.\n" );
488 break;
489 }
490 iMint = Maj3_ManEval( p );
491 }
492 if ( iMint == -1 )
493 Maj3_ManPrintSolution( p );
494 Maj3_ManFree( p );
495 Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
496 return iMint == -1;
497}
498
511{
512/*
513 int nVars = 5;
514 int nNodes = 4;
515 int fVerbose = 1;
516 int Levels[MAJ3_OBJS] = { 1, 2, 1 };
517 Vec_Int_t vLevels = { 3, 3, Levels };
518*/
519
520 int nVars = 7;
521 int nNodes = 7;
522 int fVerbose = 1;
523 int Levels[MAJ3_OBJS] = { 1, 2, 2, 2 };
524 Vec_Int_t vLevels = { 4, 4, Levels };
525
526/*
527 int nVars = 9;
528 int nNodes = 10;
529 int fVerbose = 1;
530 int Levels[MAJ3_OBJS] = { 1, 2, 3, 2, 2 };
531 Vec_Int_t vLevels = { 5, 5, Levels };
532*/
533/*
534 int nVars = 9;
535 int nNodes = 10;
536 int fVerbose = 1;
537 int Levels[MAJ3_OBJS] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
538 Vec_Int_t vLevels = { 10, 10, Levels };
539*/
540
541// Maj3_Man_t * p = Maj3_ManAlloc( nVars, nNodes, &vLevels );
542// Maj3_ManFree( p );
543 Maj3_ManExactSynthesis( nVars, nNodes, fVerbose, &vLevels );
544 return 0;
545}
546
547
548
549
550
551typedef struct Zyx_Man_t_ Zyx_Man_t;
553{
554 Bmc_EsPar_t * pPars; // parameters
555 word * pTruth; // truth table
556 int nObjs; // total objects (nVars inputs, nNodes internal nodes)
557 int nWords; // the truth table size in 64-bit words
558 int LutMask; // 1 << nLutSize
559 int TopoBase; // (1 << nLutSize) * nObjs
560 int MintBase; // TopoBase + nObjs * nObjs
561 Vec_Wrd_t * vInfo; // nVars + nNodes + 1
562 Vec_Int_t * vVarValues; // variable values
563 Vec_Int_t * vMidMints; // middle minterms
564 Vec_Bit_t * vUsed2; // bit masks
565 Vec_Bit_t * vUsed3; // bit masks
566 Vec_Int_t * vPairs; // sym var pairs
567 int nUsed[2];
568 int pFanins[MAJ3_OBJS][MAJ3_OBJS]; // fanins
569 int pLits[2][2*MAJ3_OBJS]; // neg/pos literals
570 int nLits[2]; // neg/pos literal
571 int Counts[1024];
572 bmcg_sat_solver * pSat; // SAT solver
574};
575
576static inline word * Zyx_ManTruth( Zyx_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); }
577
578static inline int Zyx_FuncVar( Zyx_Man_t * p, int i, int m ) { return (p->LutMask + 1) * (i - p->pPars->nVars) + m; }
579static inline int Zyx_TopoVar( Zyx_Man_t * p, int i, int f ) { return p->TopoBase + p->nObjs * (i - p->pPars->nVars) + f; }
580static inline int Zyx_MintVar( Zyx_Man_t * p, int m, int i ) { return p->MintBase + p->nObjs * m + i; }
581
582//static inline int Zyx_MintVar2( Zyx_Man_t * p, int m, int i, int f ) { assert(i >= p->pPars->nVars); return p->MintBase + m * p->pPars->nNodes * (p->pPars->nLutSize + 1) + (i - p->pPars->nVars) * (p->pPars->nLutSize + 1) + f; }
583
584static inline int Zyx_ManIsUsed2( Zyx_Man_t * p, int m, int n, int i, int j )
585{
586 int Pos = ((m * p->pPars->nNodes + n - p->pPars->nVars) * p->nObjs + i) * p->nObjs + j;
587 p->nUsed[0]++;
588 assert( i < n && j < n && i < j );
589 if ( Vec_BitEntry(p->vUsed2, Pos) )
590 return 1;
591 p->nUsed[1]++;
592 Vec_BitWriteEntry( p->vUsed2, Pos, 1 );
593 return 0;
594}
595
596static inline int Zyx_ManIsUsed3( Zyx_Man_t * p, int m, int n, int i, int j, int k )
597{
598 int Pos = (((m * p->pPars->nNodes + n - p->pPars->nVars) * p->nObjs + i) * p->nObjs + j) * p->nObjs + k;
599 p->nUsed[0]++;
600 assert( i < n && j < n && k < n && i < j && j < k );
601 if ( Vec_BitEntry(p->vUsed3, Pos) )
602 return 1;
603 p->nUsed[1]++;
604 Vec_BitWriteEntry( p->vUsed3, Pos, 1 );
605 return 0;
606}
607
619void Zyx_SetConstVar( Zyx_Man_t * p, int Var, int Value )
620{
621 int iLit = Abc_Var2Lit( Var, !Value );
622 int status = bmcg_sat_solver_addclause( p->pSat, &iLit, 1 );
623 assert( status );
624 assert( Vec_IntEntry(p->vVarValues, Var) == -1 );
625 Vec_IntWriteEntry( p->vVarValues, Var, Value );
626 //printf( "Setting var %d to value %d.\n", Var, Value );
627}
629{
630 int i, k, m;
631 word * pSpec = p->pPars->fMajority ? Zyx_ManTruth(p, p->nObjs) : p->pTruth;
632 // set unused functionality vars to 0
633 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
634 Zyx_SetConstVar( p, Zyx_FuncVar(p, i, 0), 0 );
635 // set unused topology vars
636 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
637 for ( k = i; k < p->nObjs; k++ )
638 Zyx_SetConstVar( p, Zyx_TopoVar(p, i, k), 0 );
639 // connect topmost node
640 Zyx_SetConstVar( p, Zyx_TopoVar(p, p->nObjs-1, p->nObjs-2), 1 );
641 // connect first node
642 if ( p->pPars->fMajority )
643 for ( k = 0; k < p->pPars->nVars; k++ )
644 Zyx_SetConstVar( p, Zyx_TopoVar(p, p->pPars->nVars, k), k < 3 );
645 // set minterm vars
646 for ( m = 0; m < (1 << p->pPars->nVars); m++ )
647 {
648 for ( i = 0; i < p->pPars->nVars; i++ )
649 Zyx_SetConstVar( p, Zyx_MintVar(p, m, i), (m >> i) & 1 );
650 Zyx_SetConstVar( p, Zyx_MintVar(p, m, p->nObjs-1), Abc_TtGetBit(pSpec, m) );
651 }
652}
654{
655 // nodes have fanins
656 int i, k, pLits[MAJ3_OBJS];
657 //printf( "Adding initial clauses:\n" );
658 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
659 {
660 int nLits = 0;
661 for ( k = 0; k < i; k++ )
662 pLits[nLits++] = Abc_Var2Lit( Zyx_TopoVar(p, i, k), 0 );
663 assert( nLits > 0 );
664 if ( !bmcg_sat_solver_addclause( p->pSat, pLits, nLits ) )
665 return 0;
666 }
667
668 // nodes have fanouts
669 for ( k = 0; k < p->nObjs-1; k++ )
670 {
671 int nLits = 0;
672 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
673 pLits[nLits++] = Abc_Var2Lit( Zyx_TopoVar(p, i, k), 0 );
674 assert( nLits > 0 );
675 if ( !bmcg_sat_solver_addclause( p->pSat, pLits, nLits ) )
676 return 0;
677 }
678
679 // two input functions
680 if ( p->pPars->nLutSize != 2 )
681 return 1;
682 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
683 {
684 for ( k = 0; k < 3; k++ )
685 {
686 pLits[0] = Abc_Var2Lit( Zyx_FuncVar(p, i, 1), k==1 );
687 pLits[1] = Abc_Var2Lit( Zyx_FuncVar(p, i, 2), k==2 );
688 pLits[2] = Abc_Var2Lit( Zyx_FuncVar(p, i, 3), k!=0 );
689 if ( !bmcg_sat_solver_addclause( p->pSat, pLits, 3 ) )
690 return 0;
691 }
692 if ( p->pPars->fOnlyAnd )
693 {
694 pLits[0] = Abc_Var2Lit( Zyx_FuncVar(p, i, 1), 1 );
695 pLits[1] = Abc_Var2Lit( Zyx_FuncVar(p, i, 2), 1 );
696 pLits[2] = Abc_Var2Lit( Zyx_FuncVar(p, i, 3), 0 );
697 if ( !bmcg_sat_solver_addclause( p->pSat, pLits, 3 ) )
698 return 0;
699 }
700 }
701 return 1;
702}
703void Zyx_ManPrintVarMap( Zyx_Man_t * p, int fSat )
704{
705 int i, k, nTopoVars = 0;
706 printf( " " );
707 for ( k = 0; k < p->nObjs-1; k++ )
708 printf( "%3d ", k );
709 printf( "\n" );
710 for ( i = p->nObjs-1; i >= p->pPars->nVars; i-- )
711 {
712 printf( "%3d ", i );
713 for ( k = 0; k < p->nObjs-1; k++ )
714 {
715 int iVar = Zyx_TopoVar(p, i, k);
716 if ( Vec_IntEntry(p->vVarValues, iVar) == -1 )
717 printf( "%3d%c ", iVar, (fSat && bmcg_sat_solver_read_cex_varvalue(p->pSat, iVar)) ? '*' : ' ' ), nTopoVars++;
718 else
719 printf( "%3d ", Vec_IntEntry(p->vVarValues, iVar) );
720 }
721 printf( "\n" );
722 }
723 if ( fSat ) return;
724 printf( "Using %d active functionality vars and %d active topology vars (out of %d SAT vars).\n",
725 p->pPars->fMajority ? 0 : p->pPars->nNodes * p->LutMask, nTopoVars, bmcg_sat_solver_varnum(p->pSat) );
726}
727void Zyx_PrintClause( int * pLits, int nLits )
728{
729 int i;
730 for ( i = 0; i < nLits; i++ )
731 printf( "%c%d ", Abc_LitIsCompl(pLits[i]) ? '-' : '+', Abc_Lit2Var(pLits[i]) );
732 printf( "\n" );
733}
734
746static inline int Zyx_ManValue( int iMint, int nVars )
747{
748 int k, Count = 0;
749 for ( k = 0; k < nVars; k++ )
750 Count += (iMint >> k) & 1;
751 return (int)(Count > nVars/2);
752}
754{
755 Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs + 1) );
756 int i, nMints = Abc_MaxInt( 64, 1 << p->pPars->nVars );
757 assert( p->pPars->fMajority == (pTruth == NULL) );
758 for ( i = 0; i < p->pPars->nVars; i++ )
759 Abc_TtIthVar( Zyx_ManTruth(p, i), i, p->pPars->nVars );
760 if ( p->pPars->fMajority )
761 {
762 for ( i = 0; i < nMints; i++ )
763 if ( Zyx_ManValue(i, p->pPars->nVars) )
764 Abc_TtSetBit( Zyx_ManTruth(p, p->nObjs), i );
765 for ( i = 0; i < nMints; i++ )
766 if ( Abc_TtBitCount16(i) == p->pPars->nVars/2 || Abc_TtBitCount16(i) == p->pPars->nVars/2+1 )
767 Vec_IntPush( p->vMidMints, i );
768 }
769 //Dau_DsdPrintFromTruth( Zyx_ManTruth(p, p->nObjs), p->pPars->nVars );
770 return vInfo;
771}
773{
774 Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
775 int i, k, nWords = Abc_TtWordNum(nVars);
776 word Cof0[64], Cof1[64];
777 word Cof01[64], Cof10[64];
778 assert( nVars <= 12 );
779 for ( i = 0; i < nVars; i++ )
780 {
781 Abc_TtCofactor0p( Cof0, pTruth, nWords, i );
782 Abc_TtCofactor1p( Cof1, pTruth, nWords, i );
783 for ( k = i+1; k < nVars; k++ )
784 {
785 Abc_TtCofactor1p( Cof01, Cof0, nWords, k );
786 Abc_TtCofactor0p( Cof10, Cof1, nWords, k );
787 if ( Abc_TtEqual( Cof01, Cof10, nWords ) )
788 Vec_IntPushTwo( vPairs, i, k );
789 }
790 }
791 return vPairs;
792}
794{
796 p->pPars = pPars;
797 p->pTruth = pTruth;
798 p->nObjs = p->pPars->nVars + p->pPars->nNodes;
799 p->nWords = Abc_TtWordNum(p->pPars->nVars);
800 p->LutMask = (1 << p->pPars->nLutSize) - 1;
801 p->TopoBase = (1 << p->pPars->nLutSize) * p->pPars->nNodes;
802 p->MintBase = p->TopoBase + p->pPars->nNodes * p->nObjs;
803 p->vVarValues = Vec_IntStartFull( p->MintBase + (1 << p->pPars->nVars) * p->nObjs );
804 p->vMidMints = Vec_IntAlloc( 1 << p->pPars->nVars );
805 p->vInfo = Zyx_ManTruthTables( p, pTruth );
806 p->vPairs = Zyx_ManCreateSymVarPairs( p->pPars->fMajority ? Zyx_ManTruth(p, p->nObjs) : pTruth, p->pPars->nVars );
807 p->pSat = bmcg_sat_solver_start();
808 if ( pPars->fUseIncr )
809 {
810 if ( p->pPars->nLutSize == 2 || p->pPars->fMajority )
811 p->vUsed2 = Vec_BitStart( (1 << p->pPars->nVars) * p->pPars->nNodes * p->nObjs * p->nObjs );
812 else if ( p->pPars->nLutSize == 3 )
813 p->vUsed3 = Vec_BitStart( (1 << p->pPars->nVars) * p->pPars->nNodes * p->nObjs * p->nObjs * p->nObjs );
814 }
815 bmcg_sat_solver_set_nvars( p->pSat, p->MintBase + (1 << p->pPars->nVars) * p->nObjs );
818 Zyx_ManPrintVarMap( p, 0 );
819 return p;
820}
822{
823 bmcg_sat_solver_stop( p->pSat );
824 Vec_WrdFree( p->vInfo );
825 Vec_BitFreeP( &p->vUsed2 );
826 Vec_BitFreeP( &p->vUsed3 );
827 Vec_IntFree( p->vPairs );
828 Vec_IntFree( p->vMidMints );
829 Vec_IntFree( p->vVarValues );
830 ABC_FREE( p );
831}
832
845{
846 int k, Val;
847 assert( i >= p->pPars->nVars && i < p->nObjs );
848 p->nLits[0] = p->nLits[1] = 0;
849 for ( k = 0; k < i; k++ )
850 {
851 Val = bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i, k));
852 p->pFanins[i][p->nLits[1]] = k;
853 p->pLits[Val][p->nLits[Val]++] = Abc_Var2Lit(Zyx_TopoVar(p, i, k), Val);
854 }
855 return p->nLits[1];
856}
858{
859 int i, k, j, Entry[2], Node[2], nLazy = 0;
860 // fanin count
861 //printf( "Adding topology clauses.\n" );
862 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
863 {
864 int nFanins = Zyx_ManCollectFanins( p, i );
865 if ( nFanins == p->pPars->nLutSize )
866 continue;
867 nLazy++;
868 assert( nFanins == p->nLits[1] );
869 if ( p->nLits[1] > p->pPars->nLutSize )
870 {
871 p->nLits[1] = p->pPars->nLutSize + 1;
872 //Zyx_PrintClause( p->pLits[1], p->nLits[1] );
873 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[1], p->nLits[1] ) )
874 return -1;
875 }
876 else // if ( p->nLits[1] < p->pPars->nLutSize )
877 {
878 //Zyx_PrintClause( p->pLits[0], p->nLits[0] );
879 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
880 return -1;
881 }
882 }
883 if ( nLazy || !p->pPars->fOrderNodes )
884 return nLazy;
885 // ordering
886 for ( i = p->pPars->nVars + 1; i < p->nObjs; i++ )
887 {
888 for ( k = p->pPars->nLutSize - 1; k >= 0; k-- )
889 if ( p->pFanins[i-1][k] != p->pFanins[i][k] )
890 break;
891 if ( k == -1 ) // fanins are equal
892 {
893 if ( p->pPars->fMajority )
894 continue;
895 // compare by LUT functions
896 for ( k = p->LutMask; k >= 0; k-- )
897 if ( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i-1, k)) !=
898 bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i , k)) )
899 break;
900 if ( k == -1 ) // truth tables cannot be equal
901 continue;
902 // rule out these truth tables
903 if ( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i-1, k)) == 0 &&
904 bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i , k)) == 1 )
905 {
906 continue;
907 }
908 nLazy++;
909 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i-1, k)) == 1 );
910 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i , k)) == 0 );
911 // rule out this order
912 p->nLits[0] = 0;
913 for ( j = p->LutMask; j >= k; j-- )
914 {
915 int ValA = bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i-1, j));
916 int ValB = bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i, j));
917 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit(Zyx_FuncVar(p, i-1, j), ValA );
918 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit(Zyx_FuncVar(p, i, j), ValB );
919 }
920 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
921 return -1;
922 continue;
923 }
924 if ( p->pFanins[i-1][k] < p->pFanins[i][k] )
925 {
926 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i-1, p->pFanins[i][k])) == 0 );
927 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i , p->pFanins[i][k])) == 1 );
928 continue;
929 }
930 nLazy++;
931 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i-1, p->pFanins[i-1][k])) == 1 );
932 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i , p->pFanins[i-1][k])) == 0 );
933 // rule out this order
934 p->nLits[0] = 0;
935 for ( j = p->pFanins[i-1][k]; j < p->nObjs-1; j++ )
936 {
937 int ValA = bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i-1, j));
938 int ValB = bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i, j));
939 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(p, i-1, j), ValA );
940 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(p, i, j), ValB );
941 }
942 //printf( "\n" );
943 //Zyx_ManPrintVarMap( p, 1 );
944 //Zyx_PrintClause( p->pLits[0], p->nLits[0] );
945 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
946 return -1;
947 //break;
948 }
949 // check symmetric variables
950 Vec_IntForEachEntryDouble( p->vPairs, Entry[0], Entry[1], k )
951 {
952 assert( Entry[0] < Entry[1] );
953 for ( j = 0; j < 2; j++ )
954 {
955 Node[j] = -1;
956 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
957 if ( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i, Entry[j])) )
958 {
959 Node[j] = i;
960 break;
961 }
962 assert( Node[j] >= p->pPars->nVars );
963 }
964 // compare the nodes
965 if ( Node[0] <= Node[1] )
966 continue;
967 assert( Node[0] > Node[1] );
968 // create blocking clause
969 nLazy++;
970 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, Node[1], Entry[0])) == 0 );
971 assert( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, Node[1], Entry[1])) == 1 );
972 // rule out this order
973 p->nLits[0] = 0;
974 for ( j = p->pPars->nVars; j <= Node[1]; j++ )
975 {
976 int ValA = bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, j, Entry[0]));
977 int ValB = bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, j, Entry[1]));
978 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(p, j, Entry[0]), ValA );
979 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit(Zyx_TopoVar(p, j, Entry[1]), ValB );
980 }
981 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
982 return -1;
983 }
984 return nLazy;
985}
987{
988 Vec_Int_t * vLits = Vec_IntAlloc( 100 ); int i, k;
989 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
990 {
991 int nFanins = Zyx_ManCollectFanins( p, i );
992 assert( nFanins == p->pPars->nLutSize );
993 for ( k = 0; k < p->pPars->nLutSize; k++ )
994 Vec_IntPush( vLits, Abc_Var2Lit(Zyx_TopoVar(p, i, p->pFanins[i][k]), 1) );
995 }
996 //Zyx_ManPrintVarMap( p, 1 );
997 //Zyx_PrintClause( Vec_IntArray(vLits), Vec_IntSize(vLits) );
998 if ( !bmcg_sat_solver_addclause( p->pSat, Vec_IntArray(vLits), Vec_IntSize(vLits) ) )
999 return 0;
1000 Vec_IntFree( vLits );
1001 return 1;
1002}
1004{
1005 int i, k, n, j, s;
1006 assert( !p->pPars->fMajority || p->pPars->nLutSize == 3 );
1007 //printf( "Adding functionality clauses for minterm %d.\n", iMint );
1008 p->Counts[iMint]++;
1009 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
1010 {
1011 int nFanins = Zyx_ManCollectFanins( p, i );
1012 assert( nFanins == p->pPars->nLutSize );
1013 if ( p->pPars->fMajority )
1014 {
1015 int Sets[3][2] = {{0, 1}, {0, 2}, {1, 2}};
1016 for ( k = 0; k < 3; k++ )
1017 {
1018 if ( Zyx_ManIsUsed2(p, iMint, i, p->pFanins[i][Sets[k][0]], p->pFanins[i][Sets[k][1]]) )
1019 continue;
1020 for ( n = 0; n < 2; n++ )
1021 {
1022 p->nLits[0] = 0;
1023 for ( s = 0; s < 2; s++ )
1024 {
1025 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(p, i, p->pFanins[i][Sets[k][s]]), 1 );
1026 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, p->pFanins[i][Sets[k][s]]), n );
1027 }
1028 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, i), !n );
1029 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
1030 return 0;
1031 }
1032 }
1033 }
1034 else
1035 {
1036 if ( p->pPars->nLutSize == 2 && Zyx_ManIsUsed2(p, iMint, i, p->pFanins[i][0], p->pFanins[i][1]) )
1037 continue;
1038 if ( p->pPars->nLutSize == 3 && Zyx_ManIsUsed3(p, iMint, i, p->pFanins[i][0], p->pFanins[i][1], p->pFanins[i][2]) )
1039 continue;
1040 for ( k = 0; k <= p->LutMask; k++ )
1041 for ( n = 0; n < 2; n++ )
1042 {
1043 p->nLits[0] = 0;
1044 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_FuncVar(p, i, k), n );
1045 for ( j = 0; j < p->pPars->nLutSize; j++ )
1046 {
1047 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(p, i, p->pFanins[i][j]), 1 );
1048 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, p->pFanins[i][j]), (k >> j) & 1 );
1049 }
1050 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, i), !n );
1051 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
1052 return 0;
1053 }
1054 }
1055 }
1056 return 1;
1057}
1058
1060{
1061 int i, k, n, j, s, t, u;
1062 //printf( "Adding clauses for minterm %d with value %d.\n", iMint, Value );
1063 assert( !p->pPars->fMajority && p->pPars->nLutSize < 4 );
1064 p->Counts[iMint]++;
1065 if ( p->pPars->nLutSize == 2 )
1066 {
1067 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
1068 for ( s = 0; s < i; s++ )
1069 for ( t = s+1; t < i; t++ )
1070 {
1071 p->pFanins[i][0] = s;
1072 p->pFanins[i][1] = t;
1073 for ( k = 0; k <= p->LutMask; k++ )
1074 for ( n = 0; n < 2; n++ )
1075 {
1076 p->nLits[0] = 0;
1077 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_FuncVar(p, i, k), n );
1078 for ( j = 0; j < p->pPars->nLutSize; j++ )
1079 {
1080 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(p, i, p->pFanins[i][j]), 1 );
1081 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, p->pFanins[i][j]), (k >> j) & 1 );
1082 }
1083 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, i), !n );
1084 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
1085 return 0;
1086 }
1087 }
1088 }
1089 else if ( p->pPars->nLutSize == 3 )
1090 {
1091 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
1092 for ( s = 0; s < i; s++ )
1093 for ( t = s+1; t < i; t++ )
1094 for ( u = t+1; u < i; u++ )
1095 {
1096 p->pFanins[i][0] = s;
1097 p->pFanins[i][1] = t;
1098 p->pFanins[i][2] = u;
1099 for ( k = 0; k <= p->LutMask; k++ )
1100 for ( n = 0; n < 2; n++ )
1101 {
1102 p->nLits[0] = 0;
1103 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_FuncVar(p, i, k), n );
1104 for ( j = 0; j < p->pPars->nLutSize; j++ )
1105 {
1106 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_TopoVar(p, i, p->pFanins[i][j]), 1 );
1107 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, p->pFanins[i][j]), (k >> j) & 1 );
1108 }
1109 p->pLits[0][p->nLits[0]++] = Abc_Var2Lit( Zyx_MintVar(p, iMint, i), !n );
1110 if ( !bmcg_sat_solver_addclause( p->pSat, p->pLits[0], p->nLits[0] ) )
1111 return 0;
1112 }
1113 }
1114 }
1115 return 1;
1116}
1117
1129static void Zyx_ManPrintSolutionFile( Zyx_Man_t * p, int fCompl, int fFirst )
1130{
1131 FILE * pFile;
1132 char FileName[1000]; int i, k;
1133 if ( fCompl ) Abc_TtNot( p->pTruth, Abc_TtWordNum(p->pPars->nVars) );
1134 Abc_TtWriteHexRev( FileName, p->pTruth, p->pPars->nVars );
1135 if ( fCompl ) Abc_TtNot( p->pTruth, Abc_TtWordNum(p->pPars->nVars) );
1136 sprintf( FileName + (1 << (p->pPars->nVars-2)), "-%d-%d.bool", p->pPars->nLutSize, p->pPars->nNodes );
1137 pFile = fopen( FileName, fFirst ? "wb" : "ab" );
1138 if ( pFile == NULL )
1139 {
1140 printf( "Cannot open input file \"%s\".\n", FileName );
1141 return;
1142 }
1143 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
1144 {
1145 fprintf( pFile, "%c", 'A' + i );
1146 if ( p->pPars->fMajority )
1147 fprintf( pFile, "maj3" );
1148 else
1149 {
1150 for ( k = p->LutMask; k >= 0; k-- )
1151 fprintf( pFile, "%d", bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i, k)) ^ (i == p->nObjs - 1 && fCompl) );
1152 for ( k = 0; k < i; k++ )
1153 if ( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i, k)) )
1154 {
1155 if ( k >= 0 && k < p->pPars->nVars )
1156 fprintf( pFile, "%c", 'a' + k );
1157 else
1158 fprintf( pFile, "%c", 'A' + k );
1159 }
1160 }
1161 fprintf( pFile, "\n" );
1162 }
1163 fprintf( pFile, "\n" );
1164 fclose( pFile );
1165 printf( "Dumped solution into file \"%s\".\n", FileName );
1166}
1167static void Zyx_ManPrintSolution( Zyx_Man_t * p, int fCompl, int fFirst )
1168{
1169 int i, k;
1170 printf( "Realization of given %d-input function using %d %d-input %s:\n",
1171 p->pPars->nVars, p->pPars->nNodes, p->pPars->nLutSize, p->pPars->fMajority ? "MAJ-gates" : "LUTs" );
1172 for ( i = p->nObjs - 1; i >= p->pPars->nVars; i-- )
1173 {
1174 printf( "%02d = ", i );
1175 if ( p->pPars->fMajority )
1176 printf( "MAJ3" );
1177 else
1178 {
1179 printf( "%d\'b", 1 << p->pPars->nLutSize );
1180 for ( k = p->LutMask; k >= 0; k-- )
1181 printf( "%d", bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i, k)) ^ (i == p->nObjs - 1 && fCompl) );
1182 }
1183 printf( "(" );
1184 for ( k = 0; k < i; k++ )
1185 if ( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_TopoVar(p, i, k)) )
1186 {
1187 if ( k >= 0 && k < p->pPars->nVars )
1188 printf( " %c", 'a'+k );
1189 else
1190 printf( " %02d", k );
1191 }
1192 printf( " )\n" );
1193 }
1194 if ( !p->pPars->fMajority )
1195 Zyx_ManPrintSolutionFile( p, fCompl, fFirst );
1196}
1197static inline int Zyx_ManEval( Zyx_Man_t * p )
1198{
1199 static int Flag = 0;
1200 //abctime clk = Abc_Clock();
1201 int i, k, j, iMint; word * pFaninsW[6], * pSpec;
1202 for ( i = p->pPars->nVars; i < p->nObjs; i++ )
1203 {
1204 int nFanins = Zyx_ManCollectFanins( p, i );
1205 assert( nFanins == p->pPars->nLutSize );
1206 for ( k = 0; k < p->pPars->nLutSize; k++ )
1207 pFaninsW[k] = Zyx_ManTruth( p, p->pFanins[i][k] );
1208 if ( p->pPars->fMajority )
1209 Abc_TtMaj( Zyx_ManTruth(p, i), pFaninsW[0], pFaninsW[1], pFaninsW[2], p->nWords );
1210 else
1211 {
1212 Abc_TtConst0( Zyx_ManTruth(p, i), p->nWords );
1213 for ( k = 1; k <= p->LutMask; k++ )
1214 if ( bmcg_sat_solver_read_cex_varvalue(p->pSat, Zyx_FuncVar(p, i, k)) )
1215 {
1216 Abc_TtConst1( Zyx_ManTruth(p, p->nObjs), p->nWords );
1217 for ( j = 0; j < p->pPars->nLutSize; j++ )
1218 Abc_TtAndCompl( Zyx_ManTruth(p, p->nObjs), Zyx_ManTruth(p, p->nObjs), 0, pFaninsW[j], !((k >> j) & 1), p->nWords );
1219 Abc_TtOr( Zyx_ManTruth(p, i), Zyx_ManTruth(p, i), Zyx_ManTruth(p, p->nObjs), p->nWords );
1220 }
1221 }
1222 }
1223 pSpec = p->pPars->fMajority ? Zyx_ManTruth(p, p->nObjs) : p->pTruth;
1224 if ( p->pPars->fMajority )
1225 {
1226 Vec_IntForEachEntry( p->vMidMints, iMint, i )
1227 if ( Abc_TtGetBit(pSpec, iMint) != Abc_TtGetBit(Zyx_ManTruth(p, p->nObjs-1), iMint) )
1228 return iMint;
1229 return -1;
1230 }
1231 else
1232 {
1233 if ( Flag && p->pPars->nVars >= 6 )
1234 iMint = Abc_TtFindLastDiffBit( Zyx_ManTruth(p, p->nObjs-1), pSpec, p->pPars->nVars );
1235 else
1236 iMint = Abc_TtFindFirstDiffBit( Zyx_ManTruth(p, p->nObjs-1), pSpec, p->pPars->nVars );
1237 }
1238 //Flag ^= 1;
1239 assert( iMint < (1 << p->pPars->nVars) );
1240 //p->clkEval += Abc_Clock() - clk;
1241 return iMint;
1242}
1243static inline void Zyx_ManEvalStats( Zyx_Man_t * p )
1244{
1245 int i;
1246 for ( i = 0; i < (1 << p->pPars->nVars); i++ )
1247 printf( "%d=%d ", i, p->Counts[i] );
1248 printf( "\n" );
1249}
1250static inline void Zyx_ManPrint( Zyx_Man_t * p, int Iter, int iMint, int nLazyAll, abctime clk )
1251{
1252 printf( "Iter %6d : ", Iter );
1253 Extra_PrintBinary( stdout, (unsigned *)&iMint, p->pPars->nVars );
1254 printf( " " );
1255 printf( "Cla =%9d ", bmcg_sat_solver_clausenum(p->pSat) );
1256 printf( "Lazy =%6d ", nLazyAll );
1257 printf( "Conf =%9d ", bmcg_sat_solver_conflictnum(p->pSat) );
1258 Abc_PrintTime( 1, "Time", clk );
1259 //Zyx_ManEvalStats( p );
1260 //Abc_PrintTime( 1, "Eval", p->clkEval );
1261}
1263{
1264 int status, Iter, iMint = 0, fCompl = 0, nLazyAll = 0, nSols = 0;
1265 abctime clkTotal = Abc_Clock(), clk = Abc_Clock(); Zyx_Man_t * p;
1266 word pTruth[16];
1267 if ( !pPars->fMajority )
1268 {
1269 Abc_TtReadHex( pTruth, pPars->pTtStr );
1270 if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, Abc_TtWordNum(pPars->nVars) ); }
1271 }
1272 assert( pPars->nVars <= 10 );
1273 assert( pPars->nLutSize <= 6 );
1274 p = Zyx_ManAlloc( pPars, pPars->fMajority ? NULL : pTruth );
1275 printf( "Running exact synthesis for %d-input function with %d %d-input %s...\n",
1276 p->pPars->nVars, p->pPars->nNodes, p->pPars->nLutSize, p->pPars->fMajority ? "MAJ-gates" : "LUTs" );
1277 for ( Iter = 0 ; ; Iter++ )
1278 {
1279 while ( (status = bmcg_sat_solver_solve(p->pSat, NULL, 0)) == GLUCOSE_SAT )
1280 {
1281 int nLazy = Zyx_ManAddCnfLazyTopo( p );
1282 if ( nLazy == -1 )
1283 {
1284 printf( "Became UNSAT after adding lazy constraints.\n" );
1285 status = GLUCOSE_UNSAT;
1286 break;
1287 }
1288 //printf( "Added %d lazy constraints.\n\n", nLazy );
1289 if ( nLazy == 0 )
1290 break;
1291 nLazyAll += nLazy;
1292 }
1293 if ( status == GLUCOSE_UNSAT )
1294 break;
1295 // find mismatch
1296 iMint = Zyx_ManEval( p );
1297 if ( iMint == -1 )
1298 {
1299 if ( pPars->fEnumSols )
1300 {
1301 nSols++;
1302 if ( pPars->fVerbose )
1303 {
1304 Zyx_ManPrint( p, Iter, iMint, nLazyAll, Abc_Clock() - clkTotal );
1305 clk = Abc_Clock();
1306 }
1307 Zyx_ManPrintSolution( p, fCompl, nSols==1 );
1308 if ( !Zyx_ManAddCnfBlockSolution( p ) )
1309 {
1310 status = GLUCOSE_UNSAT;
1311 break;
1312 }
1313 continue;
1314 }
1315 else
1316 break;
1317 }
1318 if ( pPars->fUseIncr ? !Zyx_ManAddCnfLazyFunc2(p, iMint) : !Zyx_ManAddCnfLazyFunc(p, iMint) )
1319 {
1320 printf( "Became UNSAT after adding constraints for minterm %d\n", iMint );
1321 status = GLUCOSE_UNSAT;
1322 break;
1323 }
1324 status = bmcg_sat_solver_solve( p->pSat, NULL, 0 );
1325 if ( pPars->fVerbose && (!pPars->fUseIncr || Iter % 100 == 0) )
1326 {
1327 Zyx_ManPrint( p, Iter, iMint, nLazyAll, Abc_Clock() - clk );
1328 clk = Abc_Clock();
1329 }
1330 if ( status == GLUCOSE_UNSAT )
1331 break;
1332 }
1333 if ( pPars->fVerbose )
1334 Zyx_ManPrint( p, Iter, iMint, nLazyAll, Abc_Clock() - clkTotal );
1335 if ( pPars->fEnumSols )
1336 printf( "Finished enumerating %d solutions.\n", nSols );
1337 else if ( iMint == -1 )
1338 Zyx_ManPrintSolution( p, fCompl, 1 );
1339 else
1340 printf( "The problem has no solution.\n" );
1341 //Zyx_ManEvalStats( p );
1342 printf( "Added = %d. Tried = %d. ", p->nUsed[1], p->nUsed[0] );
1343 Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
1344 Zyx_ManFree( p );
1345}
1346
1347
1348
1360int Zyx_TestGetTruthTablePars( char * pFileName, word * pTruth, int * nVars, int * nLutSize, int * nNodes )
1361{
1362 char Symb, * pCur, * pBuffer = Abc_UtilStrsav( pFileName );
1363 int nLength;
1364 for ( pCur = pBuffer; *pCur; pCur++ )
1365 if ( !Abc_TtIsHexDigit(*pCur) )
1366 break;
1367 Symb = *pCur; *pCur = 0;
1368 nLength = (int)strlen(pBuffer);
1369 if ( nLength == 1 )
1370 *nVars = 2;
1371 else if ( nLength == 2 )
1372 *nVars = 3;
1373 else if ( nLength == 4 )
1374 *nVars = 4;
1375 else if ( nLength == 8 )
1376 *nVars = 5;
1377 else if ( nLength == 16 )
1378 *nVars = 6;
1379 else if ( nLength == 32 )
1380 *nVars = 7;
1381 else if ( nLength == 64 )
1382 *nVars = 8;
1383 else
1384 {
1385 ABC_FREE( pBuffer );
1386 printf( "Invalid truth table size.\n" );
1387 return 0;
1388 }
1389 Abc_TtReadHex( pTruth, pBuffer );
1390 *pCur = Symb;
1391 // read LUT size
1392 while ( *pCur && *pCur++ != '-' );
1393 if ( *pCur == 0 )
1394 {
1395 ABC_FREE( pBuffer );
1396 printf( "Expecting \'-\' after truth table before LUT size.\n" );
1397 return 0;
1398 }
1399 // read node count
1400 *nLutSize = atoi(pCur);
1401 while ( *pCur && *pCur++ != '-' );
1402 if ( *pCur == 0 )
1403 {
1404 ABC_FREE( pBuffer );
1405 printf( "Expecting \'-\' after LUT size before node count.\n" );
1406 return 0;
1407 }
1408 *nNodes = atoi(pCur);
1409 ABC_FREE( pBuffer );
1410 return 1;
1411}
1412
1413static inline word * Zyx_TestTruth( Vec_Wrd_t * vInfo, int i, int nWords ) { return Vec_WrdEntryP(vInfo, nWords * i); }
1414
1415Vec_Wrd_t * Zyx_TestCreateTruthTables( int nVars, int nNodes )
1416{
1417 int i, nWords = Abc_TtWordNum(nVars);
1418 Vec_Wrd_t * vInfo = Vec_WrdStart( nWords * (nVars + nNodes + 1) );
1419 for ( i = 0; i < nVars; i++ )
1420 Abc_TtIthVar( Zyx_TestTruth(vInfo, i, nWords), i, nVars );
1421 //Dau_DsdPrintFromTruth( Maj3_ManTruth(p, p->nObjs), p->nVars );
1422 return vInfo;
1423}
1424int Zyx_TestReadNode( char * pLine, Vec_Wrd_t * vTruths, int nVars, int nLutSize, int iObj )
1425{
1426 int k, j, nWords = Abc_TtWordNum(nVars);
1427 word * pFaninsW[6]; char * pTruth, * pFanins;
1428 word * pThis, * pLast = Zyx_TestTruth( vTruths, Vec_WrdSize(vTruths)/nWords - 1, nWords );
1429 if ( pLine[strlen(pLine)-1] == '\n' ) pLine[strlen(pLine)-1] = 0;
1430 if ( pLine[strlen(pLine)-1] == '\r' ) pLine[strlen(pLine)-1] = 0;
1431 if ( pLine[0] == 0 )
1432 return 0;
1433 if ( (int)strlen(pLine) != 1 + nLutSize + (1 << nLutSize) )
1434 {
1435 printf( "Node representation has %d chars (expecting %d chars).\n", (int)strlen(pLine), 1 + nLutSize + (1 << nLutSize) );
1436 return 0;
1437 }
1438 if ( pLine[0] != 'A' + iObj )
1439 {
1440 printf( "The output node in line %s is not correct.\n", pLine );
1441 return 0;
1442 }
1443 pTruth = pLine + 1;
1444 pFanins = pTruth + (1 << nLutSize);
1445 for ( k = nLutSize - 1; k >= 0; k-- )
1446 pFaninsW[k] = Zyx_TestTruth( vTruths, pFanins[k] >= 'a' ? pFanins[k] - 'a' : pFanins[k] - 'A', nWords );
1447 pThis = Zyx_TestTruth(vTruths, iObj, nWords);
1448 Abc_TtConst0( pThis, nWords );
1449 for ( k = 0; k < (1 << nLutSize); k++ )
1450 {
1451 if ( pTruth[(1 << nLutSize) - 1 - k] == '0' )
1452 continue;
1453 Abc_TtConst1( pLast, nWords );
1454 for ( j = 0; j < nLutSize; j++ )
1455 Abc_TtAndCompl( pLast, pLast, 0, pFaninsW[j], !((k >> j) & 1), nWords );
1456 Abc_TtOr( pThis, pThis, pLast, nWords );
1457 }
1458 //Dau_DsdPrintFromTruth( pThis, nVars );
1459 return 1;
1460}
1461void Zyx_TestExact( char * pFileName )
1462{
1463 int iObj, nStrs = 0, nVars = -1, nLutSize = -1, nNodes = -1;
1464 word * pImpl, pSpec[4]; Vec_Wrd_t * vInfo; char Line[1000];
1465 FILE * pFile = fopen( pFileName, "rb" );
1466 if ( pFile == NULL )
1467 {
1468 printf( "Cannot open input file \"%s\".\n", pFileName );
1469 return;
1470 }
1471 if ( !Zyx_TestGetTruthTablePars( pFileName, pSpec, &nVars, &nLutSize, &nNodes ) )
1472 return;
1473 if ( nVars > 8 )
1474 {
1475 printf( "This tester does not support functions with more than 8 inputs.\n" );
1476 return;
1477 }
1478 if ( nLutSize > 6 )
1479 {
1480 printf( "This tester does not support nodes with more than 6 inputs.\n" );
1481 return;
1482 }
1483 if ( nNodes > 16 )
1484 {
1485 printf( "This tester does not support structures with more than 16 inputs.\n" );
1486 return;
1487 }
1488 vInfo = Zyx_TestCreateTruthTables( nVars, nNodes );
1489 for ( iObj = nVars; fgets(Line, 1000, pFile) != NULL; iObj++ )
1490 {
1491 if ( Zyx_TestReadNode( Line, vInfo, nVars, nLutSize, iObj ) )
1492 continue;
1493 if ( iObj != nVars + nNodes )
1494 {
1495 printf( "The number of nodes in the structure is not correct.\n" );
1496 break;
1497 }
1498 nStrs++;
1499 pImpl = Zyx_TestTruth( vInfo, iObj-1, Abc_TtWordNum(nVars) );
1500 if ( Abc_TtEqual( pImpl, pSpec, Abc_TtWordNum(nVars) ) )
1501 printf( "Structure %3d : Verification successful.\n", nStrs );
1502 else
1503 {
1504 printf( "Structure %3d : Verification FAILED.\n", nStrs );
1505 printf( "Implementation: " ); Dau_DsdPrintFromTruth( pImpl, nVars );
1506 printf( "Specification: " ); Dau_DsdPrintFromTruth( pSpec, nVars );
1507 }
1508 iObj = nVars - 1;
1509 }
1510 Vec_WrdFree( vInfo );
1511 fclose( pFile );
1512}
1513
1517
1518
1520
int bmcg_sat_solver_conflictnum(bmcg_sat_solver *s)
int bmcg_sat_solver_varnum(bmcg_sat_solver *s)
bmcg_sat_solver * bmcg_sat_solver_start()
MACRO DEFINITIONS ///.
int bmcg_sat_solver_solve(bmcg_sat_solver *s, int *plits, int nlits)
int bmcg_sat_solver_addclause(bmcg_sat_solver *s, int *plits, int nlits)
int bmcg_sat_solver_read_cex_varvalue(bmcg_sat_solver *s, int ivar)
void bmcg_sat_solver_set_nvars(bmcg_sat_solver *s, int nvars)
int bmcg_sat_solver_clausenum(bmcg_sat_solver *s)
void bmcg_sat_solver_stop(bmcg_sat_solver *s)
#define GLUCOSE_UNSAT
INCLUDES ///.
Definition AbcGlucose.h:34
void bmcg_sat_solver
Definition AbcGlucose.h:63
#define GLUCOSE_SAT
Definition AbcGlucose.h:35
int nWords
Definition abcNpn.c:127
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
int Zyx_TestReadNode(char *pLine, Vec_Wrd_t *vTruths, int nVars, int nLutSize, int iObj)
Definition bmcMaj3.c:1424
int Maj3_ManAddCnfStart(Maj3_Man_t *p)
Definition bmcMaj3.c:273
int Maj3_ManMarkup(Maj3_Man_t *p)
Definition bmcMaj3.c:105
void Zyx_SetConstVar(Zyx_Man_t *p, int Var, int Value)
Definition bmcMaj3.c:619
void Zyx_ManExactSynthesis(Bmc_EsPar_t *pPars)
Definition bmcMaj3.c:1262
struct Maj3_Man_t_ Maj3_Man_t
Definition bmcMaj3.c:36
int Zyx_ManAddCnfBlockSolution(Zyx_Man_t *p)
Definition bmcMaj3.c:986
void Zyx_ManPrintVarMap(Zyx_Man_t *p, int fSat)
Definition bmcMaj3.c:703
void Zyx_ManFree(Zyx_Man_t *p)
Definition bmcMaj3.c:821
int Zyx_ManAddCnfLazyFunc2(Zyx_Man_t *p, int iMint)
Definition bmcMaj3.c:1003
#define MAJ3_OBJS
DECLARATIONS ///.
Definition bmcMaj3.c:34
void Zyx_ManSetupVars(Zyx_Man_t *p)
Definition bmcMaj3.c:628
Vec_Wrd_t * Zyx_TestCreateTruthTables(int nVars, int nNodes)
Definition bmcMaj3.c:1415
void Maj3_PrintClause(int *pLits, int nLits)
Definition bmcMaj3.c:266
int Zyx_ManAddCnfStart(Zyx_Man_t *p)
Definition bmcMaj3.c:653
int Zyx_ManCollectFanins(Zyx_Man_t *p, int i)
Definition bmcMaj3.c:844
int Zyx_TestGetTruthTablePars(char *pFileName, word *pTruth, int *nVars, int *nLutSize, int *nNodes)
Definition bmcMaj3.c:1360
void Zyx_TestExact(char *pFileName)
Definition bmcMaj3.c:1461
int Maj3_ManAddConstraintsLazy(Maj3_Man_t *p)
Definition bmcMaj3.c:376
Vec_Wrd_t * Maj3_ManTruthTables(Maj3_Man_t *p)
Definition bmcMaj3.c:77
int Maj3_ManTest()
Definition bmcMaj3.c:510
struct Zyx_Man_t_ Zyx_Man_t
Definition bmcMaj3.c:551
int Maj3_ManAddCnf(Maj3_Man_t *p, int iMint)
Definition bmcMaj3.c:323
void Zyx_PrintClause(int *pLits, int nLits)
Definition bmcMaj3.c:727
Vec_Int_t * Zyx_ManCreateSymVarPairs(word *pTruth, int nVars)
Definition bmcMaj3.c:772
int Zyx_ManAddCnfLazyTopo(Zyx_Man_t *p)
Definition bmcMaj3.c:857
void Maj3_ManVarMapPrint(Maj3_Man_t *p)
Definition bmcMaj3.c:132
int Zyx_ManAddCnfLazyFunc(Zyx_Man_t *p, int iMint)
Definition bmcMaj3.c:1059
void Maj3_ManFirstAndLevel(Vec_Int_t *vLevels, int Firsts[MAJ3_OBJS], int Levels[MAJ3_OBJS], int nVars, int nObjs)
Definition bmcMaj3.c:89
Vec_Wrd_t * Zyx_ManTruthTables(Zyx_Man_t *p, word *pTruth)
Definition bmcMaj3.c:753
int Maj3_ManExactSynthesis(int nVars, int nNodes, int fVerbose, Vec_Int_t *vLevels)
Definition bmcMaj3.c:450
void Maj3_ManFree(Maj3_Man_t *p)
Definition bmcMaj3.c:432
Zyx_Man_t * Zyx_ManAlloc(Bmc_EsPar_t *pPars, word *pTruth)
Definition bmcMaj3.c:793
Maj3_Man_t * Maj3_ManAlloc(int nVars, int nNodes, Vec_Int_t *vLevels)
Definition bmcMaj3.c:417
typedefABC_NAMESPACE_HEADER_START struct Bmc_EsPar_t_ Bmc_EsPar_t
INCLUDES ///.
Definition bmc.h:47
void Dau_DsdPrintFromTruth(word *pTruth, int nVarsInit)
Definition dauDsd.c:1968
ush Pos
Definition deflate.h:88
Cube * p
Definition exorList.c:222
int Var
Definition exorList.c:228
void Extra_PrintBinary(FILE *pFile, unsigned Sign[], int nBits)
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
int nObjs
Definition bmcMaj3.c:41
int nLits[3]
Definition bmcMaj3.c:49
int nWords
Definition bmcMaj3.c:42
Vec_Wrd_t * vInfo
Definition bmcMaj3.c:44
int ObjVals[MAJ3_OBJS]
Definition bmcMaj3.c:47
int pLits[2][MAJ3_OBJS]
Definition bmcMaj3.c:48
int nVars
Definition bmcMaj3.c:39
int nNodes
Definition bmcMaj3.c:40
bmcg_sat_solver * pSat
Definition bmcMaj3.c:50
Vec_Int_t * vLevels
Definition bmcMaj3.c:45
int VarMarks[MAJ3_OBJS][MAJ3_OBJS]
Definition bmcMaj3.c:46
int nWords
Definition bmcMaj3.c:557
word * pTruth
Definition bmcMaj3.c:555
int LutMask
Definition bmcMaj3.c:558
Vec_Bit_t * vUsed2
Definition bmcMaj3.c:564
Bmc_EsPar_t * pPars
Definition bmcMaj3.c:554
int MintBase
Definition bmcMaj3.c:560
Vec_Int_t * vVarValues
Definition bmcMaj3.c:562
Vec_Int_t * vMidMints
Definition bmcMaj3.c:563
bmcg_sat_solver * pSat
Definition bmcMaj3.c:572
abctime clkEval
Definition bmcMaj3.c:573
Vec_Wrd_t * vInfo
Definition bmcMaj3.c:561
int pLits[2][2 *MAJ3_OBJS]
Definition bmcMaj3.c:569
int Counts[1024]
Definition bmcMaj3.c:571
int nUsed[2]
Definition bmcMaj3.c:567
Vec_Int_t * vPairs
Definition bmcMaj3.c:566
Vec_Bit_t * vUsed3
Definition bmcMaj3.c:565
int TopoBase
Definition bmcMaj3.c:559
int pFanins[MAJ3_OBJS][MAJ3_OBJS]
Definition bmcMaj3.c:568
int nObjs
Definition bmcMaj3.c:556
int nLits[2]
Definition bmcMaj3.c:570
#define assert(ex)
Definition util_old.h:213
int strlen()
char * sprintf()
typedefABC_NAMESPACE_HEADER_START struct Vec_Bit_t_ Vec_Bit_t
INCLUDES ///.
Definition vecBit.h:42
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
Definition vecInt.h:72
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition vecWrd.h:42