ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ivyFraig.c
Go to the documentation of this file.
1
20
21#include <math.h>
22
23#include "sat/bsat/satSolver.h"
24#include "misc/extra/extra.h"
25#include "ivy.h"
26
28
32
36
43
52
54{
55 // general info
56 Ivy_FraigParams_t * pParams; // various parameters
57 // temporary backtrack limits because "ABC_INT64_T" cannot be defined in Ivy_FraigParams_t ...
58 ABC_INT64_T nBTLimitGlobal; // global limit on the number of backtracks
59 ABC_INT64_T nInsLimitGlobal;// global limit on the number of clause inspects
60 // AIG manager
61 Ivy_Man_t * pManAig; // the starting AIG manager
62 Ivy_Man_t * pManFraig; // the final AIG manager
63 // simulation information
64 int nSimWords; // the number of words
65 char * pSimWords; // the simulation info
66 Ivy_FraigSim_t * pSimStart; // the list of simulation info for internal nodes
67 // counter example storage
68 int nPatWords; // the number of words in the counter example
69 unsigned * pPatWords; // the counter example
70 int * pPatScores; // the scores of each pattern
71 // equivalence classes
72 Ivy_FraigList_t lClasses; // equivalence classes
73 Ivy_FraigList_t lCand; // candidatates
74 int nPairs; // the number of pairs of nodes
75 // equivalence checking
76 sat_solver * pSat; // SAT solver
77 int nSatVars; // the number of variables currently used
78 Vec_Ptr_t * vPiVars; // the PIs of the cone used
79 // other
81 // statistics
95 // runtime
106};
107
110{
111 // general parameters
112 int fUseFraiging; // enables fraiging
113 int fUseRewriting; // enables rewriting
114 int fUseBdds; // enables BDD construction when other methods fail
115 int fVerbose; // prints verbose stats
116 // iterations
117 int nItersMax; // the number of iterations
118 // mitering
119 int nMiteringLimitStart; // starting mitering limit
120 float nMiteringLimitMulti; // multiplicative coefficient to increase the limit in each iteration
121 // rewriting
122 int nRewritingLimitStart; // the number of rewriting iterations
123 float nRewritingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
124 // fraiging
125 int nFraigingLimitStart; // starting backtrack(conflict) limit
126 float nFraigingLimitMulti; // multiplicative coefficient to increase the limit in each iteration
127 // last-gasp BDD construction
128 int nBddSizeLimit; // the number of BDD nodes when construction is aborted
129 int fBddReorder; // enables dynamic BDD variable reordering
130 // last-gasp mitering
131 int nMiteringLimitLast; // final mitering limit
132 // global SAT solver limits
133 ABC_INT64_T nTotalBacktrackLimit; // global limit on the number of backtracks
134 ABC_INT64_T nTotalInspectLimit; // global limit on the number of clause inspects
135 // global resources applied
136 ABC_INT64_T nTotalBacktracksMade; // the total number of backtracks made
137 ABC_INT64_T nTotalInspectsMade; // the total number of inspects made
138};
139
140static inline Ivy_FraigSim_t * Ivy_ObjSim( Ivy_Obj_t * pObj ) { return (Ivy_FraigSim_t *)pObj->pFanout; }
141static inline Ivy_Obj_t * Ivy_ObjClassNodeLast( Ivy_Obj_t * pObj ) { return pObj->pNextFan0; }
142static inline Ivy_Obj_t * Ivy_ObjClassNodeRepr( Ivy_Obj_t * pObj ) { return pObj->pNextFan0; }
143static inline Ivy_Obj_t * Ivy_ObjClassNodeNext( Ivy_Obj_t * pObj ) { return pObj->pNextFan1; }
144static inline Ivy_Obj_t * Ivy_ObjNodeHashNext( Ivy_Obj_t * pObj ) { return pObj->pPrevFan0; }
145static inline Ivy_Obj_t * Ivy_ObjEquivListNext( Ivy_Obj_t * pObj ) { return pObj->pPrevFan0; }
146static inline Ivy_Obj_t * Ivy_ObjEquivListPrev( Ivy_Obj_t * pObj ) { return pObj->pPrevFan1; }
147static inline Ivy_Obj_t * Ivy_ObjFraig( Ivy_Obj_t * pObj ) { return pObj->pEquiv; }
148static inline int Ivy_ObjSatNum( Ivy_Obj_t * pObj ) { return (int)(ABC_PTRUINT_T)pObj->pNextFan0; }
149static inline Vec_Ptr_t * Ivy_ObjFaninVec( Ivy_Obj_t * pObj ) { return (Vec_Ptr_t *)pObj->pNextFan1; }
150
151static inline void Ivy_ObjSetSim( Ivy_Obj_t * pObj, Ivy_FraigSim_t * pSim ) { pObj->pFanout = (Ivy_Obj_t *)pSim; }
152static inline void Ivy_ObjSetClassNodeLast( Ivy_Obj_t * pObj, Ivy_Obj_t * pLast ) { pObj->pNextFan0 = pLast; }
153static inline void Ivy_ObjSetClassNodeRepr( Ivy_Obj_t * pObj, Ivy_Obj_t * pRepr ) { pObj->pNextFan0 = pRepr; }
154static inline void Ivy_ObjSetClassNodeNext( Ivy_Obj_t * pObj, Ivy_Obj_t * pNext ) { pObj->pNextFan1 = pNext; }
155static inline void Ivy_ObjSetNodeHashNext( Ivy_Obj_t * pObj, Ivy_Obj_t * pNext ) { pObj->pPrevFan0 = pNext; }
156static inline void Ivy_ObjSetEquivListNext( Ivy_Obj_t * pObj, Ivy_Obj_t * pNext ) { pObj->pPrevFan0 = pNext; }
157static inline void Ivy_ObjSetEquivListPrev( Ivy_Obj_t * pObj, Ivy_Obj_t * pPrev ) { pObj->pPrevFan1 = pPrev; }
158static inline void Ivy_ObjSetFraig( Ivy_Obj_t * pObj, Ivy_Obj_t * pNode ) { pObj->pEquiv = pNode; }
159static inline void Ivy_ObjSetSatNum( Ivy_Obj_t * pObj, int Num ) { pObj->pNextFan0 = (Ivy_Obj_t *)(ABC_PTRUINT_T)Num; }
160static inline void Ivy_ObjSetFaninVec( Ivy_Obj_t * pObj, Vec_Ptr_t * vFanins ) { pObj->pNextFan1 = (Ivy_Obj_t *)vFanins; }
161
162static inline unsigned Ivy_ObjRandomSim() { return (rand() << 24) ^ (rand() << 12) ^ rand(); }
163
164// iterate through equivalence classes
165#define Ivy_FraigForEachEquivClass( pList, pEnt ) \
166 for ( pEnt = pList; \
167 pEnt; \
168 pEnt = Ivy_ObjEquivListNext(pEnt) )
169#define Ivy_FraigForEachEquivClassSafe( pList, pEnt, pEnt2 ) \
170 for ( pEnt = pList, \
171 pEnt2 = pEnt? Ivy_ObjEquivListNext(pEnt): NULL; \
172 pEnt; \
173 pEnt = pEnt2, \
174 pEnt2 = pEnt? Ivy_ObjEquivListNext(pEnt): NULL )
175// iterate through nodes in one class
176#define Ivy_FraigForEachClassNode( pClass, pEnt ) \
177 for ( pEnt = pClass; \
178 pEnt; \
179 pEnt = Ivy_ObjClassNodeNext(pEnt) )
180// iterate through nodes in the hash table
181#define Ivy_FraigForEachBinNode( pBin, pEnt ) \
182 for ( pEnt = pBin; \
183 pEnt; \
184 pEnt = Ivy_ObjNodeHashNext(pEnt) )
185
186static Ivy_FraigMan_t * Ivy_FraigStart( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams );
187static Ivy_FraigMan_t * Ivy_FraigStartSimple( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams );
188static Ivy_Man_t * Ivy_FraigPerform_int( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams, ABC_INT64_T nBTLimitGlobal, ABC_INT64_T nInsLimitGlobal, ABC_INT64_T * pnSatConfs, ABC_INT64_T * pnSatInspects );
189static void Ivy_FraigPrint( Ivy_FraigMan_t * p );
190static void Ivy_FraigStop( Ivy_FraigMan_t * p );
191static void Ivy_FraigSimulate( Ivy_FraigMan_t * p );
192static void Ivy_FraigSweep( Ivy_FraigMan_t * p );
193static Ivy_Obj_t * Ivy_FraigAnd( Ivy_FraigMan_t * p, Ivy_Obj_t * pObjOld );
194static int Ivy_FraigNodesAreEquiv( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 );
195static int Ivy_FraigNodeIsConst( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj );
196static void Ivy_FraigNodeAddToSolver( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj0, Ivy_Obj_t * pObj1 );
197static int Ivy_FraigSetActivityFactors( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew );
198static void Ivy_FraigAddToPatScores( Ivy_FraigMan_t * p, Ivy_Obj_t * pClass, Ivy_Obj_t * pClassNew );
199static int Ivy_FraigMiterStatus( Ivy_Man_t * pMan );
200static void Ivy_FraigMiterProve( Ivy_FraigMan_t * p );
201static void Ivy_FraigMiterPrint( Ivy_Man_t * pNtk, char * pString, abctime clk, int fVerbose );
202static int * Ivy_FraigCreateModel( Ivy_FraigMan_t * p );
203
204static int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 );
205static int Ivy_FraigCheckCone( Ivy_FraigMan_t * pGlo, Ivy_Man_t * p, Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2, int nConfLimit );
206
207static ABC_INT64_T s_nBTLimitGlobal = 0;
208static ABC_INT64_T s_nInsLimitGlobal = 0;
209
213
226{
227 memset( pParams, 0, sizeof(Ivy_FraigParams_t) );
228 pParams->nSimWords = 32; // the number of words in the simulation info
229 pParams->dSimSatur = 0.005; // the ratio of refined classes when saturation is reached
230 pParams->fPatScores = 0; // enables simulation pattern scoring
231 pParams->MaxScore = 25; // max score after which resimulation is used
232 pParams->fDoSparse = 1; // skips sparse functions
233// pParams->dActConeRatio = 0.05; // the ratio of cone to be bumped
234// pParams->dActConeBumpMax = 5.0; // the largest bump of activity
235 pParams->dActConeRatio = 0.3; // the ratio of cone to be bumped
236 pParams->dActConeBumpMax = 10.0; // the largest bump of activity
237
238 pParams->nBTLimitNode = 100; // conflict limit at a node
239 pParams->nBTLimitMiter = 500000; // conflict limit at an output
240// pParams->nBTLimitGlobal = 0; // conflict limit global
241// pParams->nInsLimitGlobal = 0; // inspection limit global
242}
243
255int Ivy_FraigProve( Ivy_Man_t ** ppManAig, void * pPars )
256{
257 Prove_Params_t * pParams = (Prove_Params_t *)pPars;
258 Ivy_FraigParams_t Params, * pIvyParams = &Params;
259 Ivy_Man_t * pManAig, * pManTemp;
260 int RetValue, nIter;
261 abctime clk;//, Counter;
262 ABC_INT64_T nSatConfs = 0, nSatInspects = 0;
263
264 // start the network and parameters
265 pManAig = *ppManAig;
266 Ivy_FraigParamsDefault( pIvyParams );
267 pIvyParams->fVerbose = pParams->fVerbose;
268 pIvyParams->fProve = 1;
269
270 if ( pParams->fVerbose )
271 {
272 printf( "RESOURCE LIMITS: Iterations = %d. Rewriting = %s. Fraiging = %s.\n",
273 pParams->nItersMax, pParams->fUseRewriting? "yes":"no", pParams->fUseFraiging? "yes":"no" );
274 printf( "Miter = %d (%3.1f). Rwr = %d (%3.1f). Fraig = %d (%3.1f). Last = %d.\n",
275 pParams->nMiteringLimitStart, pParams->nMiteringLimitMulti,
277 pParams->nFraigingLimitStart, pParams->nFraigingLimitMulti, pParams->nMiteringLimitLast );
278 }
279
280 // if SAT only, solve without iteration
281 if ( !pParams->fUseRewriting && !pParams->fUseFraiging )
282 {
283 clk = Abc_Clock();
284 pIvyParams->nBTLimitMiter = pParams->nMiteringLimitLast / Ivy_ManPoNum(pManAig);
285 pManAig = Ivy_FraigMiter( pManTemp = pManAig, pIvyParams ); Ivy_ManStop( pManTemp );
286 RetValue = Ivy_FraigMiterStatus( pManAig );
287 Ivy_FraigMiterPrint( pManAig, "SAT solving", clk, pParams->fVerbose );
288 *ppManAig = pManAig;
289 return RetValue;
290 }
291
292 if ( Ivy_ManNodeNum(pManAig) < 500 )
293 {
294 // run the first mitering
295 clk = Abc_Clock();
296 pIvyParams->nBTLimitMiter = pParams->nMiteringLimitStart / Ivy_ManPoNum(pManAig);
297 pManAig = Ivy_FraigMiter( pManTemp = pManAig, pIvyParams ); Ivy_ManStop( pManTemp );
298 RetValue = Ivy_FraigMiterStatus( pManAig );
299 Ivy_FraigMiterPrint( pManAig, "SAT solving", clk, pParams->fVerbose );
300 if ( RetValue >= 0 )
301 {
302 *ppManAig = pManAig;
303 return RetValue;
304 }
305 }
306
307 // check the current resource limits
308 RetValue = -1;
309 for ( nIter = 0; nIter < pParams->nItersMax; nIter++ )
310 {
311 if ( pParams->fVerbose )
312 {
313 printf( "ITERATION %2d : Confs = %6d. FraigBTL = %3d. \n", nIter+1,
314 (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)),
315 (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)) );
316 fflush( stdout );
317 }
318
319 // try rewriting
320 if ( pParams->fUseRewriting )
321 { // bug in Ivy_NodeFindCutsAll() when leaves are identical!
322/*
323 clk = Abc_Clock();
324 Counter = (int)(pParams->nRewritingLimitStart * pow(pParams->nRewritingLimitMulti,nIter));
325 pManAig = Ivy_ManRwsat( pManAig, 0 );
326 RetValue = Ivy_FraigMiterStatus( pManAig );
327 Ivy_FraigMiterPrint( pManAig, "Rewriting ", clk, pParams->fVerbose );
328*/
329 }
330 if ( RetValue >= 0 )
331 break;
332
333 // catch the situation when ref pattern detects the bug
334 RetValue = Ivy_FraigMiterStatus( pManAig );
335 if ( RetValue >= 0 )
336 break;
337
338 // try fraiging followed by mitering
339 if ( pParams->fUseFraiging )
340 {
341 clk = Abc_Clock();
342 pIvyParams->nBTLimitNode = (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter));
343 pIvyParams->nBTLimitMiter = 1 + (int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)) / Ivy_ManPoNum(pManAig);
344 pManAig = Ivy_FraigPerform_int( pManTemp = pManAig, pIvyParams, pParams->nTotalBacktrackLimit, pParams->nTotalInspectLimit, &nSatConfs, &nSatInspects ); Ivy_ManStop( pManTemp );
345 RetValue = Ivy_FraigMiterStatus( pManAig );
346 Ivy_FraigMiterPrint( pManAig, "Fraiging ", clk, pParams->fVerbose );
347 }
348 if ( RetValue >= 0 )
349 break;
350
351 // add to the number of backtracks and inspects
352 pParams->nTotalBacktracksMade += nSatConfs;
353 pParams->nTotalInspectsMade += nSatInspects;
354 // check if global resource limit is reached
355 if ( (pParams->nTotalBacktrackLimit && pParams->nTotalBacktracksMade >= pParams->nTotalBacktrackLimit) ||
356 (pParams->nTotalInspectLimit && pParams->nTotalInspectsMade >= pParams->nTotalInspectLimit) )
357 {
358 printf( "Reached global limit on conflicts/inspects. Quitting.\n" );
359 *ppManAig = pManAig;
360 return -1;
361 }
362 }
363/*
364 if ( RetValue < 0 )
365 {
366 if ( pParams->fVerbose )
367 {
368 printf( "Attempting SAT with conflict limit %d ...\n", pParams->nMiteringLimitLast );
369 fflush( stdout );
370 }
371 clk = Abc_Clock();
372 pIvyParams->nBTLimitMiter = pParams->nMiteringLimitLast / Ivy_ManPoNum(pManAig);
373 if ( pParams->nTotalBacktrackLimit )
374 s_nBTLimitGlobal = pParams->nTotalBacktrackLimit - pParams->nTotalBacktracksMade;
375 if ( pParams->nTotalInspectLimit )
376 s_nInsLimitGlobal = pParams->nTotalInspectLimit - pParams->nTotalInspectsMade;
377 pManAig = Ivy_FraigMiter( pManTemp = pManAig, pIvyParams ); Ivy_ManStop( pManTemp );
378 s_nBTLimitGlobal = 0;
379 s_nInsLimitGlobal = 0;
380 RetValue = Ivy_FraigMiterStatus( pManAig );
381 Ivy_FraigMiterPrint( pManAig, "SAT solving", clk, pParams->fVerbose );
382 // make sure that the sover never returns "undecided" when infinite resource limits are set
383 if( RetValue == -1 && pParams->nTotalInspectLimit == 0 &&
384 pParams->nTotalBacktrackLimit == 0 )
385 {
386 extern void Prove_ParamsPrint( Prove_Params_t * pParams );
387 Prove_ParamsPrint( pParams );
388 printf("ERROR: ABC has returned \"undecided\" in spite of no limits...\n");
389 exit(1);
390 }
391 }
392*/
393 // assign the model if it was proved by rewriting (const 1 miter)
394 if ( RetValue == 0 && pManAig->pData == NULL )
395 {
396 pManAig->pData = ABC_ALLOC( int, Ivy_ManPiNum(pManAig) );
397 memset( pManAig->pData, 0, sizeof(int) * Ivy_ManPiNum(pManAig) );
398 }
399 *ppManAig = pManAig;
400 return RetValue;
401}
402
414Ivy_Man_t * Ivy_FraigPerform_int( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams, ABC_INT64_T nBTLimitGlobal, ABC_INT64_T nInsLimitGlobal, ABC_INT64_T * pnSatConfs, ABC_INT64_T * pnSatInspects )
415{
417 Ivy_Man_t * pManAigNew;
418 abctime clk;
419 if ( Ivy_ManNodeNum(pManAig) == 0 )
420 return Ivy_ManDup(pManAig);
421clk = Abc_Clock();
422 assert( Ivy_ManLatchNum(pManAig) == 0 );
423 p = Ivy_FraigStart( pManAig, pParams );
424 // set global limits
425 p->nBTLimitGlobal = nBTLimitGlobal;
426 p->nInsLimitGlobal = nInsLimitGlobal;
427
428 Ivy_FraigSimulate( p );
429 Ivy_FraigSweep( p );
430 pManAigNew = p->pManFraig;
431p->timeTotal = Abc_Clock() - clk;
432 if ( pnSatConfs )
433 *pnSatConfs = p->pSat? p->pSat->stats.conflicts : 0;
434 if ( pnSatInspects )
435 *pnSatInspects = p->pSat? p->pSat->stats.inspects : 0;
436 Ivy_FraigStop( p );
437 return pManAigNew;
438}
439
452{
454 Ivy_Man_t * pManAigNew;
455 abctime clk;
456 if ( Ivy_ManNodeNum(pManAig) == 0 )
457 return Ivy_ManDup(pManAig);
458clk = Abc_Clock();
459 assert( Ivy_ManLatchNum(pManAig) == 0 );
460 p = Ivy_FraigStart( pManAig, pParams );
461 Ivy_FraigSimulate( p );
462 Ivy_FraigSweep( p );
463 pManAigNew = p->pManFraig;
464p->timeTotal = Abc_Clock() - clk;
465 Ivy_FraigStop( p );
466 return pManAigNew;
467}
468
481{
483 Ivy_Man_t * pManAigNew;
484 Ivy_Obj_t * pObj;
485 int i;
486 abctime clk;
487clk = Abc_Clock();
488 assert( Ivy_ManLatchNum(pManAig) == 0 );
489 p = Ivy_FraigStartSimple( pManAig, pParams );
490 // set global limits
491 p->nBTLimitGlobal = s_nBTLimitGlobal;
492 p->nInsLimitGlobal = s_nInsLimitGlobal;
493 // duplicate internal nodes
494 Ivy_ManForEachNode( p->pManAig, pObj, i )
495 pObj->pEquiv = Ivy_And( p->pManFraig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
496 // try to prove each output of the miter
497 Ivy_FraigMiterProve( p );
498 // add the POs
499 Ivy_ManForEachPo( p->pManAig, pObj, i )
500 Ivy_ObjCreatePo( p->pManFraig, Ivy_ObjChild0Equiv(pObj) );
501 // clean the new manager
502 Ivy_ManForEachObj( p->pManFraig, pObj, i )
503 {
504 if ( Ivy_ObjFaninVec(pObj) )
505 Vec_PtrFree( Ivy_ObjFaninVec(pObj) );
506 pObj->pNextFan0 = pObj->pNextFan1 = NULL;
507 }
508 // remove dangling nodes
509 Ivy_ManCleanup( p->pManFraig );
510 pManAigNew = p->pManFraig;
511p->timeTotal = Abc_Clock() - clk;
512
513//printf( "Final nodes = %6d. ", Ivy_ManNodeNum(pManAigNew) );
514//ABC_PRT( "Time", p->timeTotal );
515 Ivy_FraigStop( p );
516 return pManAigNew;
517}
518
530Ivy_FraigMan_t * Ivy_FraigStartSimple( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams )
531{
533 // allocat the fraiging manager
534 p = ABC_ALLOC( Ivy_FraigMan_t, 1 );
535 memset( p, 0, sizeof(Ivy_FraigMan_t) );
536 p->pParams = pParams;
537 p->pManAig = pManAig;
538 p->pManFraig = Ivy_ManStartFrom( pManAig );
539 p->vPiVars = Vec_PtrAlloc( 100 );
540 return p;
541}
542
554Ivy_FraigMan_t * Ivy_FraigStart( Ivy_Man_t * pManAig, Ivy_FraigParams_t * pParams )
555{
557 Ivy_FraigSim_t * pSims;
558 Ivy_Obj_t * pObj;
559 int i, k, EntrySize;
560 // clean the fanout representation
561 Ivy_ManForEachObj( pManAig, pObj, i )
562// pObj->pEquiv = pObj->pFanout = pObj->pNextFan0 = pObj->pNextFan1 = pObj->pPrevFan0 = pObj->pPrevFan1 = NULL;
563 assert( !pObj->pEquiv && !pObj->pFanout );
564 // allocat the fraiging manager
565 p = ABC_ALLOC( Ivy_FraigMan_t, 1 );
566 memset( p, 0, sizeof(Ivy_FraigMan_t) );
567 p->pParams = pParams;
568 p->pManAig = pManAig;
569 p->pManFraig = Ivy_ManStartFrom( pManAig );
570 // allocate simulation info
571 p->nSimWords = pParams->nSimWords;
572// p->pSimWords = ABC_ALLOC( unsigned, Ivy_ManObjNum(pManAig) * p->nSimWords );
573 EntrySize = sizeof(Ivy_FraigSim_t) + sizeof(unsigned) * p->nSimWords;
574 p->pSimWords = (char *)ABC_ALLOC( char, Ivy_ManObjNum(pManAig) * EntrySize );
575 memset( p->pSimWords, 0, (size_t)EntrySize );
576 k = 0;
577 Ivy_ManForEachObj( pManAig, pObj, i )
578 {
579 pSims = (Ivy_FraigSim_t *)(p->pSimWords + EntrySize * k++);
580 pSims->pNext = NULL;
581 if ( Ivy_ObjIsNode(pObj) )
582 {
583 if ( p->pSimStart == NULL )
584 p->pSimStart = pSims;
585 else
586 ((Ivy_FraigSim_t *)(p->pSimWords + EntrySize * (k-2)))->pNext = pSims;
587 pSims->pFanin0 = Ivy_ObjSim( Ivy_ObjFanin0(pObj) );
588 pSims->pFanin1 = Ivy_ObjSim( Ivy_ObjFanin1(pObj) );
589 pSims->Type = (Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)) << 2) | (Ivy_ObjFaninPhase(Ivy_ObjChild1(pObj)) << 1) | pObj->fPhase;
590 }
591 else
592 {
593 pSims->pFanin0 = NULL;
594 pSims->pFanin1 = NULL;
595 pSims->Type = 0;
596 }
597 Ivy_ObjSetSim( pObj, pSims );
598 }
599 assert( k == Ivy_ManObjNum(pManAig) );
600 // allocate storage for sim pattern
601 p->nPatWords = Ivy_BitWordNum( Ivy_ManPiNum(pManAig) );
602 p->pPatWords = ABC_ALLOC( unsigned, p->nPatWords );
603 p->pPatScores = ABC_ALLOC( int, 32 * p->nSimWords );
604 p->vPiVars = Vec_PtrAlloc( 100 );
605 // set random number generator
606 srand( 0xABCABC );
607 return p;
608}
609
621void Ivy_FraigStop( Ivy_FraigMan_t * p )
622{
623 if ( p->pParams->fVerbose )
624 Ivy_FraigPrint( p );
625 if ( p->vPiVars ) Vec_PtrFree( p->vPiVars );
626 if ( p->pSat ) sat_solver_delete( p->pSat );
627 ABC_FREE( p->pPatScores );
628 ABC_FREE( p->pPatWords );
629 ABC_FREE( p->pSimWords );
630 ABC_FREE( p );
631}
632
644void Ivy_FraigPrint( Ivy_FraigMan_t * p )
645{
646 double nMemory;
647 nMemory = (double)Ivy_ManObjNum(p->pManAig)*p->nSimWords*sizeof(unsigned)/(1<<20);
648 printf( "SimWords = %d. Rounds = %d. Mem = %0.2f MB. ", p->nSimWords, p->nSimRounds, nMemory );
649 printf( "Classes: Beg = %d. End = %d.\n", p->nClassesBeg, p->nClassesEnd );
650// printf( "Limits: BTNode = %d. BTMiter = %d.\n", p->pParams->nBTLimitNode, p->pParams->nBTLimitMiter );
651 printf( "Proof = %d. Counter-example = %d. Fail = %d. FailReal = %d. Zero = %d.\n",
652 p->nSatProof, p->nSatCallsSat, p->nSatFails, p->nSatFailsReal, p->nClassesZero );
653 printf( "Final = %d. Miter = %d. Total = %d. Mux = %d. (Exor = %d.) SatVars = %d.\n",
654 Ivy_ManNodeNum(p->pManFraig), p->nNodesMiter, Ivy_ManNodeNum(p->pManAig), 0, 0, p->nSatVars );
655 if ( p->pSat ) Sat_SolverPrintStats( stdout, p->pSat );
656 ABC_PRT( "AIG simulation ", p->timeSim );
657 ABC_PRT( "AIG traversal ", p->timeTrav );
658 ABC_PRT( "SAT solving ", p->timeSat );
659 ABC_PRT( " Unsat ", p->timeSatUnsat );
660 ABC_PRT( " Sat ", p->timeSatSat );
661 ABC_PRT( " Fail ", p->timeSatFail );
662 ABC_PRT( "Class refining ", p->timeRef );
663 ABC_PRT( "TOTAL RUNTIME ", p->timeTotal );
664 if ( p->time1 ) { ABC_PRT( "time1 ", p->time1 ); }
665}
666
667
668
681{
682 Ivy_FraigSim_t * pSims;
683 int i;
684 assert( Ivy_ObjIsPi(pObj) );
685 pSims = Ivy_ObjSim(pObj);
686 for ( i = 0; i < p->nSimWords; i++ )
687 pSims->pData[i] = Ivy_ObjRandomSim();
688}
689
701void Ivy_NodeAssignConst( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj, int fConst1 )
702{
703 Ivy_FraigSim_t * pSims;
704 int i;
705 assert( Ivy_ObjIsPi(pObj) );
706 pSims = Ivy_ObjSim(pObj);
707 for ( i = 0; i < p->nSimWords; i++ )
708 pSims->pData[i] = fConst1? ~(unsigned)0 : 0;
709}
710
723{
724 Ivy_Obj_t * pObj;
725 int i;
726 Ivy_ManForEachPi( p->pManAig, pObj, i )
727 Ivy_NodeAssignRandom( p, pObj );
728}
729
741void Ivy_FraigAssignDist1( Ivy_FraigMan_t * p, unsigned * pPat )
742{
743 Ivy_Obj_t * pObj;
744 int i, Limit;
745 Ivy_ManForEachPi( p->pManAig, pObj, i )
746 {
747 Ivy_NodeAssignConst( p, pObj, Ivy_InfoHasBit(pPat, i) );
748// printf( "%d", Ivy_InfoHasBit(pPat, i) );
749 }
750// printf( "\n" );
751
752 Limit = IVY_MIN( Ivy_ManPiNum(p->pManAig), p->nSimWords * 32 - 1 );
753 for ( i = 0; i < Limit; i++ )
754 Ivy_InfoXorBit( Ivy_ObjSim( Ivy_ManPi(p->pManAig,i) )->pData, i+1 );
755}
756
769{
770 Ivy_FraigSim_t * pSims;
771 int i;
772 pSims = Ivy_ObjSim(pObj);
773 for ( i = 0; i < p->nSimWords; i++ )
774 if ( pSims->pData[i] )
775 return 0;
776 return 1;
777}
778
791{
792 Ivy_FraigSim_t * pSims;
793 int i;
794 pSims = Ivy_ObjSim(pObj);
795 for ( i = 0; i < p->nSimWords; i++ )
796 pSims->pData[i] = ~pSims->pData[i];
797}
798
811{
812 Ivy_FraigSim_t * pSims0, * pSims1;
813 int i;
814 pSims0 = Ivy_ObjSim(pObj0);
815 pSims1 = Ivy_ObjSim(pObj1);
816 for ( i = 0; i < p->nSimWords; i++ )
817 if ( pSims0->pData[i] != pSims1->pData[i] )
818 return 0;
819 return 1;
820}
821
834{
835 unsigned * pData, * pData0, * pData1;
836 int i;
837 pData = pSims->pData;
838 pData0 = pSims->pFanin0->pData;
839 pData1 = pSims->pFanin1->pData;
840 switch( pSims->Type )
841 {
842 case 0:
843 for ( i = 0; i < p->nSimWords; i++ )
844 pData[i] = (pData0[i] & pData1[i]);
845 break;
846 case 1:
847 for ( i = 0; i < p->nSimWords; i++ )
848 pData[i] = ~(pData0[i] & pData1[i]);
849 break;
850 case 2:
851 for ( i = 0; i < p->nSimWords; i++ )
852 pData[i] = (pData0[i] & ~pData1[i]);
853 break;
854 case 3:
855 for ( i = 0; i < p->nSimWords; i++ )
856 pData[i] = (~pData0[i] | pData1[i]);
857 break;
858 case 4:
859 for ( i = 0; i < p->nSimWords; i++ )
860 pData[i] = (~pData0[i] & pData1[i]);
861 break;
862 case 5:
863 for ( i = 0; i < p->nSimWords; i++ )
864 pData[i] = (pData0[i] | ~pData1[i]);
865 break;
866 case 6:
867 for ( i = 0; i < p->nSimWords; i++ )
868 pData[i] = ~(pData0[i] | pData1[i]);
869 break;
870 case 7:
871 for ( i = 0; i < p->nSimWords; i++ )
872 pData[i] = (pData0[i] | pData1[i]);
873 break;
874 }
875}
876
889{
890 Ivy_FraigSim_t * pSims, * pSims0, * pSims1;
891 int fCompl, fCompl0, fCompl1, i;
892 assert( !Ivy_IsComplement(pObj) );
893 // get hold of the simulation information
894 pSims = Ivy_ObjSim(pObj);
895 pSims0 = Ivy_ObjSim(Ivy_ObjFanin0(pObj));
896 pSims1 = Ivy_ObjSim(Ivy_ObjFanin1(pObj));
897 // get complemented attributes of the children using their random info
898 fCompl = pObj->fPhase;
899 fCompl0 = Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj));
900 fCompl1 = Ivy_ObjFaninPhase(Ivy_ObjChild1(pObj));
901 // simulate
902 if ( fCompl0 && fCompl1 )
903 {
904 if ( fCompl )
905 for ( i = 0; i < p->nSimWords; i++ )
906 pSims->pData[i] = (pSims0->pData[i] | pSims1->pData[i]);
907 else
908 for ( i = 0; i < p->nSimWords; i++ )
909 pSims->pData[i] = ~(pSims0->pData[i] | pSims1->pData[i]);
910 }
911 else if ( fCompl0 && !fCompl1 )
912 {
913 if ( fCompl )
914 for ( i = 0; i < p->nSimWords; i++ )
915 pSims->pData[i] = (pSims0->pData[i] | ~pSims1->pData[i]);
916 else
917 for ( i = 0; i < p->nSimWords; i++ )
918 pSims->pData[i] = (~pSims0->pData[i] & pSims1->pData[i]);
919 }
920 else if ( !fCompl0 && fCompl1 )
921 {
922 if ( fCompl )
923 for ( i = 0; i < p->nSimWords; i++ )
924 pSims->pData[i] = (~pSims0->pData[i] | pSims1->pData[i]);
925 else
926 for ( i = 0; i < p->nSimWords; i++ )
927 pSims->pData[i] = (pSims0->pData[i] & ~pSims1->pData[i]);
928 }
929 else // if ( !fCompl0 && !fCompl1 )
930 {
931 if ( fCompl )
932 for ( i = 0; i < p->nSimWords; i++ )
933 pSims->pData[i] = ~(pSims0->pData[i] & pSims1->pData[i]);
934 else
935 for ( i = 0; i < p->nSimWords; i++ )
936 pSims->pData[i] = (pSims0->pData[i] & pSims1->pData[i]);
937 }
938}
939
952{
953 static int s_FPrimes[128] = {
954 1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
955 1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
956 2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
957 2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
958 3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
959 3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
960 4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
961 4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
962 5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
963 6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
964 6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
965 7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
966 8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
967 };
968 Ivy_FraigSim_t * pSims;
969 unsigned uHash;
970 int i;
971 assert( p->nSimWords <= 128 );
972 uHash = 0;
973 pSims = Ivy_ObjSim(pObj);
974 for ( i = 0; i < p->nSimWords; i++ )
975 uHash ^= pSims->pData[i] * s_FPrimes[i];
976 return uHash;
977}
978
991{
992 Ivy_Obj_t * pObj;
993 int i;
994 abctime clk;
995clk = Abc_Clock();
996 Ivy_ManForEachNode( p->pManAig, pObj, i )
997 {
998 Ivy_NodeSimulate( p, pObj );
999/*
1000 if ( Ivy_ObjFraig(pObj) == NULL )
1001 printf( "%3d --- -- %d : ", pObj->Id, pObj->fPhase );
1002 else
1003 printf( "%3d %3d %2d %d : ", pObj->Id, Ivy_Regular(Ivy_ObjFraig(pObj))->Id, Ivy_ObjSatNum(Ivy_Regular(Ivy_ObjFraig(pObj))), pObj->fPhase );
1004 Extra_PrintBinary( stdout, Ivy_ObjSim(pObj), 30 );
1005 printf( "\n" );
1006*/
1007 }
1008p->timeSim += Abc_Clock() - clk;
1009p->nSimRounds++;
1010}
1011
1024{
1025 Ivy_FraigSim_t * pSims;
1026 abctime clk;
1027clk = Abc_Clock();
1028 for ( pSims = p->pSimStart; pSims; pSims = pSims->pNext )
1029 Ivy_NodeSimulateSim( p, pSims );
1030p->timeSim += Abc_Clock() - clk;
1031p->nSimRounds++;
1032}
1033
1046{
1047 if ( Ivy_ObjClassNodeNext(pClass) == NULL )
1048 Ivy_ObjSetClassNodeNext( pClass, pObj );
1049 else
1050 Ivy_ObjSetClassNodeNext( Ivy_ObjClassNodeLast(pClass), pObj );
1051 Ivy_ObjSetClassNodeLast( pClass, pObj );
1052 Ivy_ObjSetClassNodeRepr( pObj, pClass );
1053 Ivy_ObjSetClassNodeNext( pObj, NULL );
1054}
1055
1068{
1069 if ( pList->pHead == NULL )
1070 {
1071 pList->pHead = pClass;
1072 pList->pTail = pClass;
1073 Ivy_ObjSetEquivListPrev( pClass, NULL );
1074 Ivy_ObjSetEquivListNext( pClass, NULL );
1075 }
1076 else
1077 {
1078 Ivy_ObjSetEquivListNext( pList->pTail, pClass );
1079 Ivy_ObjSetEquivListPrev( pClass, pList->pTail );
1080 Ivy_ObjSetEquivListNext( pClass, NULL );
1081 pList->pTail = pClass;
1082 }
1083 pList->nItems++;
1084}
1085
1098{
1099 Ivy_ObjSetEquivListPrev( pClass, pBase );
1100 Ivy_ObjSetEquivListNext( pClass, Ivy_ObjEquivListNext(pBase) );
1101 if ( Ivy_ObjEquivListNext(pBase) )
1102 Ivy_ObjSetEquivListPrev( Ivy_ObjEquivListNext(pBase), pClass );
1103 Ivy_ObjSetEquivListNext( pBase, pClass );
1104 if ( pList->pTail == pBase )
1105 pList->pTail = pClass;
1106 pList->nItems++;
1107}
1108
1121{
1122 if ( pList->pHead == pClass )
1123 pList->pHead = Ivy_ObjEquivListNext(pClass);
1124 if ( pList->pTail == pClass )
1125 pList->pTail = Ivy_ObjEquivListPrev(pClass);
1126 if ( Ivy_ObjEquivListPrev(pClass) )
1127 Ivy_ObjSetEquivListNext( Ivy_ObjEquivListPrev(pClass), Ivy_ObjEquivListNext(pClass) );
1128 if ( Ivy_ObjEquivListNext(pClass) )
1129 Ivy_ObjSetEquivListPrev( Ivy_ObjEquivListNext(pClass), Ivy_ObjEquivListPrev(pClass) );
1130 Ivy_ObjSetEquivListNext( pClass, NULL );
1131 Ivy_ObjSetEquivListPrev( pClass, NULL );
1132 pClass->fMarkA = 0;
1133 pList->nItems--;
1134}
1135
1148{
1149 Ivy_Obj_t * pClass, * pNode;
1150 int nPairs = 0, nNodes;
1151 return nPairs;
1152
1153 Ivy_FraigForEachEquivClass( p->lClasses.pHead, pClass )
1154 {
1155 nNodes = 0;
1156 Ivy_FraigForEachClassNode( pClass, pNode )
1157 nNodes++;
1158 nPairs += nNodes * (nNodes - 1) / 2;
1159 }
1160 return nPairs;
1161}
1162
1175{
1176 Ivy_Obj_t ** pTable;
1177 Ivy_Obj_t * pObj, * pConst1, * pBin, * pEntry;
1178 int i, nTableSize;
1179 unsigned Hash;
1180 pConst1 = Ivy_ManConst1(p->pManAig);
1181 // allocate the table
1182 nTableSize = Ivy_ManObjNum(p->pManAig) / 2 + 13;
1183 pTable = ABC_ALLOC( Ivy_Obj_t *, nTableSize );
1184 memset( pTable, 0, sizeof(Ivy_Obj_t *) * nTableSize );
1185 // collect nodes into the table
1186 Ivy_ManForEachObj( p->pManAig, pObj, i )
1187 {
1188 if ( !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsNode(pObj) )
1189 continue;
1190 Hash = Ivy_NodeHash( p, pObj );
1191 if ( Hash == 0 && Ivy_NodeHasZeroSim( p, pObj ) )
1192 {
1193 Ivy_NodeAddToClass( pConst1, pObj );
1194 continue;
1195 }
1196 // add the node to the table
1197 pBin = pTable[Hash % nTableSize];
1198 Ivy_FraigForEachBinNode( pBin, pEntry )
1199 if ( Ivy_NodeCompareSims( p, pEntry, pObj ) )
1200 {
1201 Ivy_NodeAddToClass( pEntry, pObj );
1202 break;
1203 }
1204 // check if the entry was added
1205 if ( pEntry )
1206 continue;
1207 Ivy_ObjSetNodeHashNext( pObj, pBin );
1208 pTable[Hash % nTableSize] = pObj;
1209 }
1210 // collect non-trivial classes
1211 assert( p->lClasses.pHead == NULL );
1212 Ivy_ManForEachObj( p->pManAig, pObj, i )
1213 {
1214 if ( !Ivy_ObjIsConst1(pObj) && !Ivy_ObjIsPi(pObj) && !Ivy_ObjIsNode(pObj) )
1215 continue;
1216 Ivy_ObjSetNodeHashNext( pObj, NULL );
1217 if ( Ivy_ObjClassNodeRepr(pObj) == NULL )
1218 {
1219 assert( Ivy_ObjClassNodeNext(pObj) == NULL );
1220 continue;
1221 }
1222 // recognize the head of the class
1223 if ( Ivy_ObjClassNodeNext( Ivy_ObjClassNodeRepr(pObj) ) != NULL )
1224 continue;
1225 // clean the class representative and add it to the list
1226 Ivy_ObjSetClassNodeRepr( pObj, NULL );
1227 Ivy_FraigAddClass( &p->lClasses, pObj );
1228 }
1229 // free the table
1230 ABC_FREE( pTable );
1231}
1232
1245{
1246 Ivy_Obj_t * pClassNew, * pListOld, * pListNew, * pNode;
1247 int RetValue = 0;
1248 // check if there is refinement
1249 pListOld = pClass;
1250 Ivy_FraigForEachClassNode( Ivy_ObjClassNodeNext(pClass), pClassNew )
1251 {
1252 if ( !Ivy_NodeCompareSims(p, pClass, pClassNew) )
1253 {
1254 if ( p->pParams->fPatScores )
1255 Ivy_FraigAddToPatScores( p, pClass, pClassNew );
1256 break;
1257 }
1258 pListOld = pClassNew;
1259 }
1260 if ( pClassNew == NULL )
1261 return 0;
1262 // set representative of the new class
1263 Ivy_ObjSetClassNodeRepr( pClassNew, NULL );
1264 // start the new list
1265 pListNew = pClassNew;
1266 // go through the remaining nodes and sort them into two groups:
1267 // (1) matches of the old node; (2) non-matches of the old node
1268 Ivy_FraigForEachClassNode( Ivy_ObjClassNodeNext(pClassNew), pNode )
1269 if ( Ivy_NodeCompareSims( p, pClass, pNode ) )
1270 {
1271 Ivy_ObjSetClassNodeNext( pListOld, pNode );
1272 pListOld = pNode;
1273 }
1274 else
1275 {
1276 Ivy_ObjSetClassNodeNext( pListNew, pNode );
1277 Ivy_ObjSetClassNodeRepr( pNode, pClassNew );
1278 pListNew = pNode;
1279 }
1280 // finish both lists
1281 Ivy_ObjSetClassNodeNext( pListNew, NULL );
1282 Ivy_ObjSetClassNodeNext( pListOld, NULL );
1283 // update the list of classes
1284 Ivy_FraigInsertClass( &p->lClasses, pClass, pClassNew );
1285 // if the old class is trivial, remove it
1286 if ( Ivy_ObjClassNodeNext(pClass) == NULL )
1287 Ivy_FraigRemoveClass( &p->lClasses, pClass );
1288 // if the new class is trivial, remove it; otherwise, try to refine it
1289 if ( Ivy_ObjClassNodeNext(pClassNew) == NULL )
1290 Ivy_FraigRemoveClass( &p->lClasses, pClassNew );
1291 else
1292 RetValue = Ivy_FraigRefineClass_rec( p, pClassNew );
1293 return RetValue + 1;
1294}
1295
1308{
1309 Ivy_FraigSim_t * pSims;
1310 int i, k, BestPat, * pModel;
1311 // find the word of the pattern
1312 pSims = Ivy_ObjSim(pObj);
1313 for ( i = 0; i < p->nSimWords; i++ )
1314 if ( pSims->pData[i] )
1315 break;
1316 assert( i < p->nSimWords );
1317 // find the bit of the pattern
1318 for ( k = 0; k < 32; k++ )
1319 if ( pSims->pData[i] & (1 << k) )
1320 break;
1321 assert( k < 32 );
1322 // determine the best pattern
1323 BestPat = i * 32 + k;
1324 // fill in the counter-example data
1325 pModel = ABC_ALLOC( int, Ivy_ManPiNum(p->pManFraig) );
1326 Ivy_ManForEachPi( p->pManAig, pObj, i )
1327 {
1328 pModel[i] = Ivy_InfoHasBit(Ivy_ObjSim(pObj)->pData, BestPat);
1329// printf( "%d", pModel[i] );
1330 }
1331// printf( "\n" );
1332 // set the model
1333 assert( p->pManFraig->pData == NULL );
1334 p->pManFraig->pData = pModel;
1335 return;
1336}
1337
1350{
1351 Ivy_Obj_t * pObj;
1352 int i;
1353 // make sure the reference simulation pattern does not detect the bug
1354// pObj = Ivy_ManPo( p->pManAig, 0 );
1355 Ivy_ManForEachPo( p->pManAig, pObj, i )
1356 {
1357 //assert( Ivy_ObjFanin0(pObj)->fPhase == (unsigned)Ivy_ObjFaninC0(pObj) ); // Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj)) == 0
1358 // complement simulation info
1359// if ( Ivy_ObjFanin0(pObj)->fPhase ^ Ivy_ObjFaninC0(pObj) ) // Ivy_ObjFaninPhase(Ivy_ObjChild0(pObj))
1360// Ivy_NodeComplementSim( p, Ivy_ObjFanin0(pObj) );
1361 // check
1362 if ( !Ivy_NodeHasZeroSim( p, Ivy_ObjFanin0(pObj) ) )
1363 {
1364 // create the counter-example from this pattern
1365 Ivy_FraigCheckOutputSimsSavePattern( p, Ivy_ObjFanin0(pObj) );
1366 return 1;
1367 }
1368 // complement simulation info
1369// if ( Ivy_ObjFanin0(pObj)->fPhase ^ Ivy_ObjFaninC0(pObj) )
1370// Ivy_NodeComplementSim( p, Ivy_ObjFanin0(pObj) );
1371 }
1372 return 0;
1373}
1374
1388{
1389 Ivy_Obj_t * pClass, * pClass2;
1390 int RetValue, Counter = 0;
1391 abctime clk;
1392 // check if some outputs already became non-constant
1393 // this is a special case when computation can be stopped!!!
1394 if ( p->pParams->fProve )
1396 if ( p->pManFraig->pData )
1397 return 0;
1398 // refine the classed
1399clk = Abc_Clock();
1400 Ivy_FraigForEachEquivClassSafe( p->lClasses.pHead, pClass, pClass2 )
1401 {
1402 if ( pClass->fMarkA )
1403 continue;
1404 RetValue = Ivy_FraigRefineClass_rec( p, pClass );
1405 Counter += ( RetValue > 0 );
1406//if ( Ivy_ObjIsConst1(pClass) )
1407//printf( "%d ", RetValue );
1408//if ( Ivy_ObjIsConst1(pClass) )
1409// p->time1 += Abc_Clock() - clk;
1410 }
1411p->timeRef += Abc_Clock() - clk;
1412 return Counter;
1413}
1414
1427{
1428 Ivy_Obj_t * pObj;
1429 printf( "Class {" );
1430 Ivy_FraigForEachClassNode( pClass, pObj )
1431 printf( " %d(%d)%c", pObj->Id, pObj->Level, pObj->fPhase? '+' : '-' );
1432 printf( " }\n" );
1433}
1434
1447{
1448 Ivy_Obj_t * pObj;
1449 int Counter = 0;
1450 Ivy_FraigForEachClassNode( pClass, pObj )
1451 Counter++;
1452 return Counter;
1453}
1454
1467{
1468 Ivy_Obj_t * pClass;
1469 Ivy_FraigForEachEquivClass( p->lClasses.pHead, pClass )
1470 {
1471// Ivy_FraigPrintClass( pClass );
1472 printf( "%d ", Ivy_FraigCountClassNodes( pClass ) );
1473 }
1474// printf( "\n" );
1475}
1476
1489{
1490 memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
1491}
1492
1505{
1506 memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords );
1507}
1508
1520int * Ivy_FraigCreateModel( Ivy_FraigMan_t * p )
1521{
1522 int * pModel;
1523 Ivy_Obj_t * pObj;
1524 int i;
1525 pModel = ABC_ALLOC( int, Ivy_ManPiNum(p->pManFraig) );
1526 Ivy_ManForEachPi( p->pManFraig, pObj, i )
1527// pModel[i] = ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True );
1528 pModel[i] = ( p->pSat->model[Ivy_ObjSatNum(pObj)] == l_True );
1529 return pModel;
1530}
1531
1544{
1545 Ivy_Obj_t * pObj;
1546 int i;
1547 memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
1548 Ivy_ManForEachPi( p->pManFraig, pObj, i )
1549// Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPiVars, pObj, i )
1550// if ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True )
1551 if ( p->pSat->model[Ivy_ObjSatNum(pObj)] == l_True )
1552 Ivy_InfoSetBit( p->pPatWords, i );
1553// Ivy_InfoSetBit( p->pPatWords, pObj->Id - 1 );
1554}
1555
1568{
1569 Ivy_Obj_t * pObj;
1570 int i;
1571 memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
1572// Ivy_ManForEachPi( p->pManFraig, pObj, i )
1573 Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPiVars, pObj, i )
1574// if ( p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True )
1575 if ( p->pSat->model[Ivy_ObjSatNum(pObj)] == l_True )
1576// Ivy_InfoSetBit( p->pPatWords, i );
1577 Ivy_InfoSetBit( p->pPatWords, pObj->Id - 1 );
1578}
1579
1592{
1593 Ivy_Obj_t * pObj;
1594 int i;
1595 for ( i = 0; i < p->nPatWords; i++ )
1596 p->pPatWords[i] = Ivy_ObjRandomSim();
1597 Vec_PtrForEachEntry( Ivy_Obj_t *, p->vPiVars, pObj, i )
1598// if ( Ivy_InfoHasBit( p->pPatWords, pObj->Id - 1 ) ^ (p->pSat->model.ptr[Ivy_ObjSatNum(pObj)] == l_True) )
1599 if ( Ivy_InfoHasBit( p->pPatWords, pObj->Id - 1 ) ^ sat_solver_var_value(p->pSat, Ivy_ObjSatNum(pObj)) )
1600 Ivy_InfoXorBit( p->pPatWords, pObj->Id - 1 );
1601}
1602
1603
1615void Ivy_FraigSimulate( Ivy_FraigMan_t * p )
1616{
1617 int nChanges, nClasses;
1618 // start the classes
1622//printf( "Starting classes = %5d. Pairs = %6d.\n", p->lClasses.nItems, Ivy_FraigCountPairsClasses(p) );
1623 // refine classes by walking 0/1 patterns
1625 Ivy_FraigAssignDist1( p, p->pPatWords );
1627 nChanges = Ivy_FraigRefineClasses( p );
1628 if ( p->pManFraig->pData )
1629 return;
1630//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
1632 Ivy_FraigAssignDist1( p, p->pPatWords );
1634 nChanges = Ivy_FraigRefineClasses( p );
1635 if ( p->pManFraig->pData )
1636 return;
1637//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
1638 // refine classes by random simulation
1639 do {
1642 nClasses = p->lClasses.nItems;
1643 nChanges = Ivy_FraigRefineClasses( p );
1644 if ( p->pManFraig->pData )
1645 return;
1646//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
1647 } while ( (double)nChanges / nClasses > p->pParams->dSimSatur );
1648// Ivy_FraigPrintSimClasses( p );
1649}
1650
1651
1652
1665{
1666 int i, nLimit = p->nSimWords * 32;
1667 for ( i = 0; i < nLimit; i++ )
1668 p->pPatScores[i] = 0;
1669}
1670
1682void Ivy_FraigAddToPatScores( Ivy_FraigMan_t * p, Ivy_Obj_t * pClass, Ivy_Obj_t * pClassNew )
1683{
1684 Ivy_FraigSim_t * pSims0, * pSims1;
1685 unsigned uDiff;
1686 int i, w;
1687 // get hold of the simulation information
1688 pSims0 = Ivy_ObjSim(pClass);
1689 pSims1 = Ivy_ObjSim(pClassNew);
1690 // iterate through the differences and record the score
1691 for ( w = 0; w < p->nSimWords; w++ )
1692 {
1693 uDiff = pSims0->pData[w] ^ pSims1->pData[w];
1694 if ( uDiff == 0 )
1695 continue;
1696 for ( i = 0; i < 32; i++ )
1697 if ( uDiff & ( 1 << i ) )
1698 p->pPatScores[w*32+i]++;
1699 }
1700}
1701
1714{
1715 Ivy_FraigSim_t * pSims;
1716 Ivy_Obj_t * pObj;
1717 int i, nLimit = p->nSimWords * 32, MaxScore = 0, BestPat = -1;
1718 for ( i = 1; i < nLimit; i++ )
1719 {
1720 if ( MaxScore < p->pPatScores[i] )
1721 {
1722 MaxScore = p->pPatScores[i];
1723 BestPat = i;
1724 }
1725 }
1726 if ( MaxScore == 0 )
1727 return 0;
1728// if ( MaxScore > p->pParams->MaxScore )
1729// printf( "Max score is %3d. ", MaxScore );
1730 // copy the best pattern into the selected pattern
1731 memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
1732 Ivy_ManForEachPi( p->pManAig, pObj, i )
1733 {
1734 pSims = Ivy_ObjSim(pObj);
1735 if ( Ivy_InfoHasBit(pSims->pData, BestPat) )
1736 Ivy_InfoSetBit(p->pPatWords, i);
1737 }
1738 return MaxScore;
1739}
1740
1753{
1754 int nChanges;
1755 Ivy_FraigAssignDist1( p, p->pPatWords );
1757 if ( p->pParams->fPatScores )
1759 nChanges = Ivy_FraigRefineClasses( p );
1760 if ( p->pManFraig->pData )
1761 return;
1762 if ( nChanges < 1 )
1763 printf( "Error: A counter-example did not refine classes!\n" );
1764 assert( nChanges >= 1 );
1765//printf( "Refined classes! = %5d. Changes = %4d.\n", p->lClasses.nItems, nChanges );
1766 if ( !p->pParams->fPatScores )
1767 return;
1768
1769 // perform additional simulation using dist1 patterns derived from successful patterns
1770 while ( Ivy_FraigSelectBestPat(p) > p->pParams->MaxScore )
1771 {
1772 Ivy_FraigAssignDist1( p, p->pPatWords );
1775 nChanges = Ivy_FraigRefineClasses( p );
1776 if ( p->pManFraig->pData )
1777 return;
1778//printf( "Refined class!!! = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Ivy_FraigCountPairsClasses(p) );
1779 if ( nChanges == 0 )
1780 break;
1781 }
1782}
1783
1784
1796void Ivy_FraigMiterPrint( Ivy_Man_t * pNtk, char * pString, abctime clk, int fVerbose )
1797{
1798 if ( !fVerbose )
1799 return;
1800 printf( "Nodes = %7d. Levels = %4d. ", Ivy_ManNodeNum(pNtk), Ivy_ManLevels(pNtk) );
1801 ABC_PRT( pString, Abc_Clock() - clk );
1802}
1803
1815int Ivy_FraigMiterStatus( Ivy_Man_t * pMan )
1816{
1817 Ivy_Obj_t * pObj, * pObjNew;
1818 int i, CountConst0 = 0, CountNonConst0 = 0, CountUndecided = 0;
1819 if ( pMan->pData )
1820 return 0;
1821 Ivy_ManForEachPo( pMan, pObj, i )
1822 {
1823 pObjNew = Ivy_ObjChild0(pObj);
1824 // check if the output is constant 1
1825 if ( pObjNew == pMan->pConst1 )
1826 {
1827 CountNonConst0++;
1828 continue;
1829 }
1830 // check if the output is constant 0
1831 if ( pObjNew == Ivy_Not(pMan->pConst1) )
1832 {
1833 CountConst0++;
1834 continue;
1835 }
1836/*
1837 // check if the output is a primary input
1838 if ( Ivy_ObjIsPi(Ivy_Regular(pObjNew)) )
1839 {
1840 CountNonConst0++;
1841 continue;
1842 }
1843*/
1844 // check if the output can be constant 0
1845 if ( Ivy_Regular(pObjNew)->fPhase != (unsigned)Ivy_IsComplement(pObjNew) )
1846 {
1847 CountNonConst0++;
1848 continue;
1849 }
1850 CountUndecided++;
1851 }
1852/*
1853 if ( p->pParams->fVerbose )
1854 {
1855 printf( "Miter has %d outputs. ", Ivy_ManPoNum(p->pManAig) );
1856 printf( "Const0 = %d. ", CountConst0 );
1857 printf( "NonConst0 = %d. ", CountNonConst0 );
1858 printf( "Undecided = %d. ", CountUndecided );
1859 printf( "\n" );
1860 }
1861*/
1862 if ( CountNonConst0 )
1863 return 0;
1864 if ( CountUndecided )
1865 return -1;
1866 return 1;
1867}
1868
1880void Ivy_FraigMiterProve( Ivy_FraigMan_t * p )
1881{
1882 Ivy_Obj_t * pObj, * pObjNew;
1883 int i, RetValue;
1884 abctime clk = Abc_Clock();
1885 int fVerbose = 0;
1886 Ivy_ManForEachPo( p->pManAig, pObj, i )
1887 {
1888 if ( i && fVerbose )
1889 {
1890 ABC_PRT( "Time", Abc_Clock() -clk );
1891 }
1892 pObjNew = Ivy_ObjChild0Equiv(pObj);
1893 // check if the output is constant 1
1894 if ( pObjNew == p->pManFraig->pConst1 )
1895 {
1896 if ( fVerbose )
1897 printf( "Output %2d (out of %2d) is constant 1. ", i, Ivy_ManPoNum(p->pManAig) );
1898 // assing constant 0 model
1899 p->pManFraig->pData = ABC_ALLOC( int, Ivy_ManPiNum(p->pManFraig) );
1900 memset( p->pManFraig->pData, 0, sizeof(int) * Ivy_ManPiNum(p->pManFraig) );
1901 break;
1902 }
1903 // check if the output is constant 0
1904 if ( pObjNew == Ivy_Not(p->pManFraig->pConst1) )
1905 {
1906 if ( fVerbose )
1907 printf( "Output %2d (out of %2d) is already constant 0. ", i, Ivy_ManPoNum(p->pManAig) );
1908 continue;
1909 }
1910 // check if the output can be constant 0
1911 if ( Ivy_Regular(pObjNew)->fPhase != (unsigned)Ivy_IsComplement(pObjNew) )
1912 {
1913 if ( fVerbose )
1914 printf( "Output %2d (out of %2d) cannot be constant 0. ", i, Ivy_ManPoNum(p->pManAig) );
1915 // assing constant 0 model
1916 p->pManFraig->pData = ABC_ALLOC( int, Ivy_ManPiNum(p->pManFraig) );
1917 memset( p->pManFraig->pData, 0, sizeof(int) * Ivy_ManPiNum(p->pManFraig) );
1918 break;
1919 }
1920/*
1921 // check the representative of this node
1922 pRepr = Ivy_ObjClassNodeRepr(Ivy_ObjFanin0(pObj));
1923 if ( Ivy_Regular(pRepr) != p->pManAig->pConst1 )
1924 printf( "Representative is not constant 1.\n" );
1925 else
1926 printf( "Representative is constant 1.\n" );
1927*/
1928 // try to prove the output constant 0
1929 RetValue = Ivy_FraigNodeIsConst( p, Ivy_Regular(pObjNew) );
1930 if ( RetValue == 1 ) // proved equivalent
1931 {
1932 if ( fVerbose )
1933 printf( "Output %2d (out of %2d) was proved constant 0. ", i, Ivy_ManPoNum(p->pManAig) );
1934 // set the constant miter
1935 Ivy_ObjFanin0(pObj)->pEquiv = Ivy_NotCond( p->pManFraig->pConst1, !Ivy_ObjFaninC0(pObj) );
1936 continue;
1937 }
1938 if ( RetValue == -1 ) // failed
1939 {
1940 if ( fVerbose )
1941 printf( "Output %2d (out of %2d) has timed out at %d backtracks. ", i, Ivy_ManPoNum(p->pManAig), p->pParams->nBTLimitMiter );
1942 continue;
1943 }
1944 // proved satisfiable
1945 if ( fVerbose )
1946 printf( "Output %2d (out of %2d) was proved NOT a constant 0. ", i, Ivy_ManPoNum(p->pManAig) );
1947 // create the model
1948 p->pManFraig->pData = Ivy_FraigCreateModel(p);
1949 break;
1950 }
1951 if ( fVerbose )
1952 {
1953 ABC_PRT( "Time", Abc_Clock() -clk );
1954 }
1955}
1956
1968void Ivy_FraigSweep( Ivy_FraigMan_t * p )
1969{
1970 Ivy_Obj_t * pObj;//, * pTemp;
1971 int i, k = 0;
1972p->nClassesZero = p->lClasses.pHead? (Ivy_ObjIsConst1(p->lClasses.pHead) ? Ivy_FraigCountClassNodes(p->lClasses.pHead) : 0) : 0;
1973p->nClassesBeg = p->lClasses.nItems;
1974 // duplicate internal nodes
1975 p->pProgress = Extra_ProgressBarStart( stdout, Ivy_ManNodeNum(p->pManAig) );
1976 Ivy_ManForEachNode( p->pManAig, pObj, i )
1977 {
1978 Extra_ProgressBarUpdate( p->pProgress, k++, NULL );
1979 // default to simple strashing if simulation detected a counter-example for a PO
1980 if ( p->pManFraig->pData )
1981 pObj->pEquiv = Ivy_And( p->pManFraig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
1982 else
1983 pObj->pEquiv = Ivy_FraigAnd( p, pObj );
1984 assert( pObj->pEquiv != NULL );
1985// pTemp = Ivy_Regular(pObj->pEquiv);
1986// assert( Ivy_Regular(pObj->pEquiv)->Type );
1987 }
1988 Extra_ProgressBarStop( p->pProgress );
1989p->nClassesEnd = p->lClasses.nItems;
1990 // try to prove the outputs of the miter
1991 p->nNodesMiter = Ivy_ManNodeNum(p->pManFraig);
1992// Ivy_FraigMiterStatus( p->pManFraig );
1993 if ( p->pParams->fProve && p->pManFraig->pData == NULL )
1994 Ivy_FraigMiterProve( p );
1995 // add the POs
1996 Ivy_ManForEachPo( p->pManAig, pObj, i )
1997 Ivy_ObjCreatePo( p->pManFraig, Ivy_ObjChild0Equiv(pObj) );
1998 // clean the old manager
1999 Ivy_ManForEachObj( p->pManAig, pObj, i )
2000 pObj->pFanout = pObj->pNextFan0 = pObj->pNextFan1 = pObj->pPrevFan0 = pObj->pPrevFan1 = NULL;
2001 // clean the new manager
2002 Ivy_ManForEachObj( p->pManFraig, pObj, i )
2003 {
2004 if ( Ivy_ObjFaninVec(pObj) )
2005 Vec_PtrFree( Ivy_ObjFaninVec(pObj) );
2006 pObj->pNextFan0 = pObj->pNextFan1 = NULL;
2007 pObj->pEquiv = NULL;
2008 }
2009 // remove dangling nodes
2010 Ivy_ManCleanup( p->pManFraig );
2011 // clean up the class marks
2012 Ivy_FraigForEachEquivClass( p->lClasses.pHead, pObj )
2013 pObj->fMarkA = 0;
2014}
2015
2027Ivy_Obj_t * Ivy_FraigAnd( Ivy_FraigMan_t * p, Ivy_Obj_t * pObjOld )
2028{
2029 Ivy_Obj_t * pObjNew, * pFanin0New, * pFanin1New, * pObjReprNew;
2030 int RetValue;
2031 // get the fraiged fanins
2032 pFanin0New = Ivy_ObjChild0Equiv(pObjOld);
2033 pFanin1New = Ivy_ObjChild1Equiv(pObjOld);
2034 // get the candidate fraig node
2035 pObjNew = Ivy_And( p->pManFraig, pFanin0New, pFanin1New );
2036 // get representative of this class
2037 if ( Ivy_ObjClassNodeRepr(pObjOld) == NULL || // this is a unique node
2038 (!p->pParams->fDoSparse && Ivy_ObjClassNodeRepr(pObjOld) == p->pManAig->pConst1) ) // this is a sparse node
2039 {
2040// assert( Ivy_Regular(pFanin0New) != Ivy_Regular(pFanin1New) );
2041// assert( pObjNew != Ivy_Regular(pFanin0New) );
2042// assert( pObjNew != Ivy_Regular(pFanin1New) );
2043 return pObjNew;
2044 }
2045 // get the fraiged representative
2046 pObjReprNew = Ivy_ObjFraig(Ivy_ObjClassNodeRepr(pObjOld));
2047 // if the fraiged nodes are the same return
2048 if ( Ivy_Regular(pObjNew) == Ivy_Regular(pObjReprNew) )
2049 return pObjNew;
2050 assert( Ivy_Regular(pObjNew) != Ivy_ManConst1(p->pManFraig) );
2051// printf( "Node = %d. Repr = %d.\n", pObjOld->Id, Ivy_ObjClassNodeRepr(pObjOld)->Id );
2052
2053 // they are different (the counter-example is in p->pPatWords)
2054 RetValue = Ivy_FraigNodesAreEquiv( p, Ivy_Regular(pObjReprNew), Ivy_Regular(pObjNew) );
2055 if ( RetValue == 1 ) // proved equivalent
2056 {
2057 // mark the class as proved
2058 if ( Ivy_ObjClassNodeNext(pObjOld) == NULL )
2059 Ivy_ObjClassNodeRepr(pObjOld)->fMarkA = 1;
2060 return Ivy_NotCond( pObjReprNew, pObjOld->fPhase ^ Ivy_ObjClassNodeRepr(pObjOld)->fPhase );
2061 }
2062 if ( RetValue == -1 ) // failed
2063 return pObjNew;
2064 // simulate the counter-example and return the new node
2066 return pObjNew;
2067}
2068
2081{
2082 int i;
2083 for ( i = 0; i < p->nSatVars; i++ )
2084 printf( "%d %d ", i, (int)p->pSat->activity[i] );
2085 printf( "\n" );
2086}
2087
2099int Ivy_FraigNodesAreEquiv( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew )
2100{
2101 int pLits[4], RetValue, RetValue1, nBTLimit;
2102 abctime clk; //, clk2 = Abc_Clock();
2103
2104 // make sure the nodes are not complemented
2105 assert( !Ivy_IsComplement(pNew) );
2106 assert( !Ivy_IsComplement(pOld) );
2107 assert( pNew != pOld );
2108
2109 // if at least one of the nodes is a failed node, perform adjustments:
2110 // if the backtrack limit is small, simply skip this node
2111 // if the backtrack limit is > 10, take the quare root of the limit
2112 nBTLimit = p->pParams->nBTLimitNode;
2113 if ( nBTLimit > 0 && (pOld->fFailTfo || pNew->fFailTfo) )
2114 {
2115 p->nSatFails++;
2116 // fail immediately
2117// return -1;
2118 if ( nBTLimit <= 10 )
2119 return -1;
2120 nBTLimit = (int)pow(nBTLimit, 0.7);
2121 }
2122 p->nSatCalls++;
2123
2124 // make sure the solver is allocated and has enough variables
2125 if ( p->pSat == NULL )
2126 {
2127 p->pSat = sat_solver_new();
2128 sat_solver_setnvars( p->pSat, 1000 );
2129 p->pSat->factors = ABC_CALLOC( double, p->pSat->cap );
2130 p->nSatVars = 1;
2131 // var 0 is reserved for const1 node - add the clause
2132// pLits[0] = toLit( 0 );
2133// sat_solver_addclause( p->pSat, pLits, pLits + 1 );
2134 }
2135
2136 // if the nodes do not have SAT variables, allocate them
2137 Ivy_FraigNodeAddToSolver( p, pOld, pNew );
2138
2139 // prepare variable activity
2140 Ivy_FraigSetActivityFactors( p, pOld, pNew );
2141
2142 // solve under assumptions
2143 // A = 1; B = 0 OR A = 1; B = 1
2144clk = Abc_Clock();
2145 pLits[0] = toLitCond( Ivy_ObjSatNum(pOld), 0 );
2146 pLits[1] = toLitCond( Ivy_ObjSatNum(pNew), pOld->fPhase == pNew->fPhase );
2147//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
2148 RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2,
2149 (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0,
2150 p->nBTLimitGlobal, p->nInsLimitGlobal );
2151p->timeSat += Abc_Clock() - clk;
2152 if ( RetValue1 == l_False )
2153 {
2154p->timeSatUnsat += Abc_Clock() - clk;
2155 pLits[0] = lit_neg( pLits[0] );
2156 pLits[1] = lit_neg( pLits[1] );
2157 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
2158 assert( RetValue );
2159 // continue solving the other implication
2160 p->nSatCallsUnsat++;
2161 }
2162 else if ( RetValue1 == l_True )
2163 {
2164p->timeSatSat += Abc_Clock() - clk;
2166 p->nSatCallsSat++;
2167 return 0;
2168 }
2169 else // if ( RetValue1 == l_Undef )
2170 {
2171p->timeSatFail += Abc_Clock() - clk;
2172/*
2173 if ( nBTLimit > 1000 )
2174 {
2175 RetValue = Ivy_FraigCheckCone( p, p->pManFraig, pOld, pNew, nBTLimit );
2176 if ( RetValue != -1 )
2177 return RetValue;
2178 }
2179*/
2180 // mark the node as the failed node
2181 if ( pOld != p->pManFraig->pConst1 )
2182 pOld->fFailTfo = 1;
2183 pNew->fFailTfo = 1;
2184 p->nSatFailsReal++;
2185 return -1;
2186 }
2187
2188 // if the old node was constant 0, we already know the answer
2189 if ( pOld == p->pManFraig->pConst1 )
2190 {
2191 p->nSatProof++;
2192 return 1;
2193 }
2194
2195 // solve under assumptions
2196 // A = 0; B = 1 OR A = 0; B = 0
2197clk = Abc_Clock();
2198 pLits[0] = toLitCond( Ivy_ObjSatNum(pOld), 1 );
2199 pLits[1] = toLitCond( Ivy_ObjSatNum(pNew), pOld->fPhase ^ pNew->fPhase );
2200 RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2,
2201 (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0,
2202 p->nBTLimitGlobal, p->nInsLimitGlobal );
2203p->timeSat += Abc_Clock() - clk;
2204 if ( RetValue1 == l_False )
2205 {
2206p->timeSatUnsat += Abc_Clock() - clk;
2207 pLits[0] = lit_neg( pLits[0] );
2208 pLits[1] = lit_neg( pLits[1] );
2209 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
2210 assert( RetValue );
2211 p->nSatCallsUnsat++;
2212 }
2213 else if ( RetValue1 == l_True )
2214 {
2215p->timeSatSat += Abc_Clock() - clk;
2217 p->nSatCallsSat++;
2218 return 0;
2219 }
2220 else // if ( RetValue1 == l_Undef )
2221 {
2222p->timeSatFail += Abc_Clock() - clk;
2223/*
2224 if ( nBTLimit > 1000 )
2225 {
2226 RetValue = Ivy_FraigCheckCone( p, p->pManFraig, pOld, pNew, nBTLimit );
2227 if ( RetValue != -1 )
2228 return RetValue;
2229 }
2230*/
2231 // mark the node as the failed node
2232 pOld->fFailTfo = 1;
2233 pNew->fFailTfo = 1;
2234 p->nSatFailsReal++;
2235 return -1;
2236 }
2237/*
2238 // check BDD proof
2239 {
2240 int RetVal;
2241 ABC_PRT( "Sat", Abc_Clock() - clk2 );
2242 clk2 = Abc_Clock();
2243 RetVal = Ivy_FraigNodesAreEquivBdd( pOld, pNew );
2244// printf( "%d ", RetVal );
2245 assert( RetVal );
2246 ABC_PRT( "Bdd", Abc_Clock() - clk2 );
2247 printf( "\n" );
2248 }
2249*/
2250 // return SAT proof
2251 p->nSatProof++;
2252 return 1;
2253}
2254
2266int Ivy_FraigNodeIsConst( Ivy_FraigMan_t * p, Ivy_Obj_t * pNew )
2267{
2268 int pLits[2], RetValue1;
2269 abctime clk;
2270 int RetValue;
2271
2272 // make sure the nodes are not complemented
2273 assert( !Ivy_IsComplement(pNew) );
2274 assert( pNew != p->pManFraig->pConst1 );
2275 p->nSatCalls++;
2276
2277 // make sure the solver is allocated and has enough variables
2278 if ( p->pSat == NULL )
2279 {
2280 p->pSat = sat_solver_new();
2281 sat_solver_setnvars( p->pSat, 1000 );
2282 p->pSat->factors = ABC_CALLOC( double, p->pSat->cap );
2283 p->nSatVars = 1;
2284 // var 0 is reserved for const1 node - add the clause
2285// pLits[0] = toLit( 0 );
2286// sat_solver_addclause( p->pSat, pLits, pLits + 1 );
2287 }
2288
2289 // if the nodes do not have SAT variables, allocate them
2290 Ivy_FraigNodeAddToSolver( p, NULL, pNew );
2291
2292 // prepare variable activity
2293 Ivy_FraigSetActivityFactors( p, NULL, pNew );
2294
2295 // solve under assumptions
2296clk = Abc_Clock();
2297 pLits[0] = toLitCond( Ivy_ObjSatNum(pNew), pNew->fPhase );
2298 RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 1,
2299 (ABC_INT64_T)p->pParams->nBTLimitMiter, (ABC_INT64_T)0,
2300 p->nBTLimitGlobal, p->nInsLimitGlobal );
2301p->timeSat += Abc_Clock() - clk;
2302 if ( RetValue1 == l_False )
2303 {
2304p->timeSatUnsat += Abc_Clock() - clk;
2305 pLits[0] = lit_neg( pLits[0] );
2306 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 );
2307 assert( RetValue );
2308 // continue solving the other implication
2309 p->nSatCallsUnsat++;
2310 }
2311 else if ( RetValue1 == l_True )
2312 {
2313p->timeSatSat += Abc_Clock() - clk;
2314 if ( p->pPatWords )
2316 p->nSatCallsSat++;
2317 return 0;
2318 }
2319 else // if ( RetValue1 == l_Undef )
2320 {
2321p->timeSatFail += Abc_Clock() - clk;
2322/*
2323 if ( p->pParams->nBTLimitMiter > 1000 )
2324 {
2325 RetValue = Ivy_FraigCheckCone( p, p->pManFraig, p->pManFraig->pConst1, pNew, p->pParams->nBTLimitMiter );
2326 if ( RetValue != -1 )
2327 return RetValue;
2328 }
2329*/
2330 // mark the node as the failed node
2331 pNew->fFailTfo = 1;
2332 p->nSatFailsReal++;
2333 return -1;
2334 }
2335
2336 // return SAT proof
2337 p->nSatProof++;
2338 return 1;
2339}
2340
2353{
2354 Ivy_Obj_t * pNodeI, * pNodeT, * pNodeE;
2355 int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
2356
2357 assert( !Ivy_IsComplement( pNode ) );
2358 assert( Ivy_ObjIsMuxType( pNode ) );
2359 // get nodes (I = if, T = then, E = else)
2360 pNodeI = Ivy_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
2361 // get the variable numbers
2362 VarF = Ivy_ObjSatNum(pNode);
2363 VarI = Ivy_ObjSatNum(pNodeI);
2364 VarT = Ivy_ObjSatNum(Ivy_Regular(pNodeT));
2365 VarE = Ivy_ObjSatNum(Ivy_Regular(pNodeE));
2366 // get the complementation flags
2367 fCompT = Ivy_IsComplement(pNodeT);
2368 fCompE = Ivy_IsComplement(pNodeE);
2369
2370 // f = ITE(i, t, e)
2371
2372 // i' + t' + f
2373 // i' + t + f'
2374 // i + e' + f
2375 // i + e + f'
2376
2377 // create four clauses
2378 pLits[0] = toLitCond(VarI, 1);
2379 pLits[1] = toLitCond(VarT, 1^fCompT);
2380 pLits[2] = toLitCond(VarF, 0);
2381 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
2382 assert( RetValue );
2383 pLits[0] = toLitCond(VarI, 1);
2384 pLits[1] = toLitCond(VarT, 0^fCompT);
2385 pLits[2] = toLitCond(VarF, 1);
2386 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
2387 assert( RetValue );
2388 pLits[0] = toLitCond(VarI, 0);
2389 pLits[1] = toLitCond(VarE, 1^fCompE);
2390 pLits[2] = toLitCond(VarF, 0);
2391 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
2392 assert( RetValue );
2393 pLits[0] = toLitCond(VarI, 0);
2394 pLits[1] = toLitCond(VarE, 0^fCompE);
2395 pLits[2] = toLitCond(VarF, 1);
2396 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
2397 assert( RetValue );
2398
2399 // two additional clauses
2400 // t' & e' -> f'
2401 // t & e -> f
2402
2403 // t + e + f'
2404 // t' + e' + f
2405
2406 if ( VarT == VarE )
2407 {
2408// assert( fCompT == !fCompE );
2409 return;
2410 }
2411
2412 pLits[0] = toLitCond(VarT, 0^fCompT);
2413 pLits[1] = toLitCond(VarE, 0^fCompE);
2414 pLits[2] = toLitCond(VarF, 1);
2415 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
2416 assert( RetValue );
2417 pLits[0] = toLitCond(VarT, 1^fCompT);
2418 pLits[1] = toLitCond(VarE, 1^fCompE);
2419 pLits[2] = toLitCond(VarF, 0);
2420 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
2421 assert( RetValue );
2422}
2423
2436{
2437 Ivy_Obj_t * pFanin;
2438 int * pLits, nLits, RetValue, i;
2439 assert( !Ivy_IsComplement(pNode) );
2440 assert( Ivy_ObjIsNode( pNode ) );
2441 // create storage for literals
2442 nLits = Vec_PtrSize(vSuper) + 1;
2443 pLits = ABC_ALLOC( int, nLits );
2444 // suppose AND-gate is A & B = C
2445 // add !A => !C or A + !C
2446 Vec_PtrForEachEntry( Ivy_Obj_t *, vSuper, pFanin, i )
2447 {
2448 pLits[0] = toLitCond(Ivy_ObjSatNum(Ivy_Regular(pFanin)), Ivy_IsComplement(pFanin));
2449 pLits[1] = toLitCond(Ivy_ObjSatNum(pNode), 1);
2450 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
2451 assert( RetValue );
2452 }
2453 // add A & B => C or !A + !B + C
2454 Vec_PtrForEachEntry( Ivy_Obj_t *, vSuper, pFanin, i )
2455 pLits[i] = toLitCond(Ivy_ObjSatNum(Ivy_Regular(pFanin)), !Ivy_IsComplement(pFanin));
2456 pLits[nLits-1] = toLitCond(Ivy_ObjSatNum(pNode), 0);
2457 RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits );
2458 assert( RetValue );
2459 ABC_FREE( pLits );
2460}
2461
2473void Ivy_FraigCollectSuper_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
2474{
2475 // if the new node is complemented or a PI, another gate begins
2476 if ( Ivy_IsComplement(pObj) || Ivy_ObjIsPi(pObj) || (!fFirst && Ivy_ObjRefs(pObj) > 1) ||
2477 (fUseMuxes && Ivy_ObjIsMuxType(pObj)) )
2478 {
2479 Vec_PtrPushUnique( vSuper, pObj );
2480 return;
2481 }
2482 // go through the branches
2483 Ivy_FraigCollectSuper_rec( Ivy_ObjChild0(pObj), vSuper, 0, fUseMuxes );
2484 Ivy_FraigCollectSuper_rec( Ivy_ObjChild1(pObj), vSuper, 0, fUseMuxes );
2485}
2486
2499{
2500 Vec_Ptr_t * vSuper;
2501 assert( !Ivy_IsComplement(pObj) );
2502 assert( !Ivy_ObjIsPi(pObj) );
2503 vSuper = Vec_PtrAlloc( 4 );
2504 Ivy_FraigCollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
2505 return vSuper;
2506}
2507
2520{
2521 assert( !Ivy_IsComplement(pObj) );
2522 if ( Ivy_ObjSatNum(pObj) )
2523 return;
2524 assert( Ivy_ObjSatNum(pObj) == 0 );
2525 assert( Ivy_ObjFaninVec(pObj) == NULL );
2526 if ( Ivy_ObjIsConst1(pObj) )
2527 return;
2528//printf( "Assigning node %d number %d\n", pObj->Id, p->nSatVars );
2529 Ivy_ObjSetSatNum( pObj, p->nSatVars++ );
2530 if ( Ivy_ObjIsNode(pObj) )
2531 Vec_PtrPush( vFrontier, pObj );
2532}
2533
2545void Ivy_FraigNodeAddToSolver( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew )
2546{
2547 Vec_Ptr_t * vFrontier, * vFanins;
2548 Ivy_Obj_t * pNode, * pFanin;
2549 int i, k, fUseMuxes = 1;
2550 assert( pOld || pNew );
2551 // quit if CNF is ready
2552 if ( (!pOld || Ivy_ObjFaninVec(pOld)) && (!pNew || Ivy_ObjFaninVec(pNew)) )
2553 return;
2554 // start the frontier
2555 vFrontier = Vec_PtrAlloc( 100 );
2556 if ( pOld ) Ivy_FraigObjAddToFrontier( p, pOld, vFrontier );
2557 if ( pNew ) Ivy_FraigObjAddToFrontier( p, pNew, vFrontier );
2558 // explore nodes in the frontier
2559 Vec_PtrForEachEntry( Ivy_Obj_t *, vFrontier, pNode, i )
2560 {
2561 // create the supergate
2562 assert( Ivy_ObjSatNum(pNode) );
2563 assert( Ivy_ObjFaninVec(pNode) == NULL );
2564 if ( fUseMuxes && Ivy_ObjIsMuxType(pNode) )
2565 {
2566 vFanins = Vec_PtrAlloc( 4 );
2567 Vec_PtrPushUnique( vFanins, Ivy_ObjFanin0( Ivy_ObjFanin0(pNode) ) );
2568 Vec_PtrPushUnique( vFanins, Ivy_ObjFanin0( Ivy_ObjFanin1(pNode) ) );
2569 Vec_PtrPushUnique( vFanins, Ivy_ObjFanin1( Ivy_ObjFanin0(pNode) ) );
2570 Vec_PtrPushUnique( vFanins, Ivy_ObjFanin1( Ivy_ObjFanin1(pNode) ) );
2571 Vec_PtrForEachEntry( Ivy_Obj_t *, vFanins, pFanin, k )
2572 Ivy_FraigObjAddToFrontier( p, Ivy_Regular(pFanin), vFrontier );
2573 Ivy_FraigAddClausesMux( p, pNode );
2574 }
2575 else
2576 {
2577 vFanins = Ivy_FraigCollectSuper( pNode, fUseMuxes );
2578 Vec_PtrForEachEntry( Ivy_Obj_t *, vFanins, pFanin, k )
2579 Ivy_FraigObjAddToFrontier( p, Ivy_Regular(pFanin), vFrontier );
2580 Ivy_FraigAddClausesSuper( p, pNode, vFanins );
2581 }
2582 assert( Vec_PtrSize(vFanins) > 1 );
2583 Ivy_ObjSetFaninVec( pNode, vFanins );
2584 }
2585 Vec_PtrFree( vFrontier );
2586 sat_solver_simplify( p->pSat );
2587}
2588
2600int Ivy_FraigSetActivityFactors_rec( Ivy_FraigMan_t * p, Ivy_Obj_t * pObj, int LevelMin, int LevelMax )
2601{
2602 Vec_Ptr_t * vFanins;
2603 Ivy_Obj_t * pFanin;
2604 int i, Counter = 0;
2605 assert( !Ivy_IsComplement(pObj) );
2606 assert( Ivy_ObjSatNum(pObj) );
2607 // skip visited variables
2608 if ( Ivy_ObjIsTravIdCurrent(p->pManFraig, pObj) )
2609 return 0;
2610 Ivy_ObjSetTravIdCurrent(p->pManFraig, pObj);
2611 // add the PI to the list
2612 if ( pObj->Level <= (unsigned)LevelMin || Ivy_ObjIsPi(pObj) )
2613 return 0;
2614 // set the factor of this variable
2615 // (LevelMax-LevelMin) / (pObj->Level-LevelMin) = p->pParams->dActConeBumpMax / ThisBump
2616 p->pSat->factors[Ivy_ObjSatNum(pObj)] = p->pParams->dActConeBumpMax * (pObj->Level - LevelMin)/(LevelMax - LevelMin);
2617 veci_push(&p->pSat->act_vars, Ivy_ObjSatNum(pObj));
2618 // explore the fanins
2619 vFanins = Ivy_ObjFaninVec( pObj );
2620 Vec_PtrForEachEntry( Ivy_Obj_t *, vFanins, pFanin, i )
2621 Counter += Ivy_FraigSetActivityFactors_rec( p, Ivy_Regular(pFanin), LevelMin, LevelMax );
2622 return 1 + Counter;
2623}
2624
2636int Ivy_FraigSetActivityFactors( Ivy_FraigMan_t * p, Ivy_Obj_t * pOld, Ivy_Obj_t * pNew )
2637{
2638 int LevelMin, LevelMax;
2639 abctime clk;
2640 assert( pOld || pNew );
2641clk = Abc_Clock();
2642 // reset the active variables
2643 veci_resize(&p->pSat->act_vars, 0);
2644 // prepare for traversal
2645 Ivy_ManIncrementTravId( p->pManFraig );
2646 // determine the min and max level to visit
2647 assert( p->pParams->dActConeRatio > 0 && p->pParams->dActConeRatio < 1 );
2648 LevelMax = IVY_MAX( (pNew ? pNew->Level : 0), (pOld ? pOld->Level : 0) );
2649 LevelMin = (int)(LevelMax * (1.0 - p->pParams->dActConeRatio));
2650 // traverse
2651 if ( pOld && !Ivy_ObjIsConst1(pOld) )
2652 Ivy_FraigSetActivityFactors_rec( p, pOld, LevelMin, LevelMax );
2653 if ( pNew && !Ivy_ObjIsConst1(pNew) )
2654 Ivy_FraigSetActivityFactors_rec( p, pNew, LevelMin, LevelMax );
2655//Ivy_FraigPrintActivity( p );
2656p->timeTrav += Abc_Clock() - clk;
2657 return 1;
2658}
2659
2661
2662#ifdef ABC_USE_CUDD
2663#include "bdd/cudd/cuddInt.h"
2664#endif
2665
2667
2668#ifdef ABC_USE_CUDD
2669
2681DdNode * Ivy_FraigNodesAreEquivBdd_int( DdManager * dd, DdNode * bFunc, Vec_Ptr_t * vFront, int Level )
2682{
2683 DdNode ** pFuncs;
2684 DdNode * bFuncNew;
2685 Vec_Ptr_t * vTemp;
2686 Ivy_Obj_t * pObj, * pFanin;
2687 int i, NewSize;
2688 // create new frontier
2689 vTemp = Vec_PtrAlloc( 100 );
2690 Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, i )
2691 {
2692 if ( (int)pObj->Level != Level )
2693 {
2694 pObj->fMarkB = 1;
2695 pObj->TravId = Vec_PtrSize(vTemp);
2696 Vec_PtrPush( vTemp, pObj );
2697 continue;
2698 }
2699
2700 pFanin = Ivy_ObjFanin0(pObj);
2701 if ( pFanin->fMarkB == 0 )
2702 {
2703 pFanin->fMarkB = 1;
2704 pFanin->TravId = Vec_PtrSize(vTemp);
2705 Vec_PtrPush( vTemp, pFanin );
2706 }
2707
2708 pFanin = Ivy_ObjFanin1(pObj);
2709 if ( pFanin->fMarkB == 0 )
2710 {
2711 pFanin->fMarkB = 1;
2712 pFanin->TravId = Vec_PtrSize(vTemp);
2713 Vec_PtrPush( vTemp, pFanin );
2714 }
2715 }
2716 // collect the permutation
2717 NewSize = IVY_MAX(dd->size, Vec_PtrSize(vTemp));
2718 pFuncs = ABC_ALLOC( DdNode *, NewSize );
2719 Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, i )
2720 {
2721 if ( (int)pObj->Level != Level )
2722 pFuncs[i] = Cudd_bddIthVar( dd, pObj->TravId );
2723 else
2724 pFuncs[i] = Cudd_bddAnd( dd,
2725 Cudd_NotCond( Cudd_bddIthVar(dd, Ivy_ObjFanin0(pObj)->TravId), Ivy_ObjFaninC0(pObj) ),
2726 Cudd_NotCond( Cudd_bddIthVar(dd, Ivy_ObjFanin1(pObj)->TravId), Ivy_ObjFaninC1(pObj) ) );
2727 Cudd_Ref( pFuncs[i] );
2728 }
2729 // add the remaining vars
2730 assert( NewSize == dd->size );
2731 for ( i = Vec_PtrSize(vFront); i < dd->size; i++ )
2732 {
2733 pFuncs[i] = Cudd_bddIthVar( dd, i );
2734 Cudd_Ref( pFuncs[i] );
2735 }
2736
2737 // create new
2738 bFuncNew = Cudd_bddVectorCompose( dd, bFunc, pFuncs ); Cudd_Ref( bFuncNew );
2739 // clean trav Id
2740 Vec_PtrForEachEntry( Ivy_Obj_t *, vTemp, pObj, i )
2741 {
2742 pObj->fMarkB = 0;
2743 pObj->TravId = 0;
2744 }
2745 // deref
2746 for ( i = 0; i < dd->size; i++ )
2747 Cudd_RecursiveDeref( dd, pFuncs[i] );
2748 ABC_FREE( pFuncs );
2749
2750 ABC_FREE( vFront->pArray );
2751 *vFront = *vTemp;
2752
2753 vTemp->nCap = vTemp->nSize = 0;
2754 vTemp->pArray = NULL;
2755 Vec_PtrFree( vTemp );
2756
2757 Cudd_Deref( bFuncNew );
2758 return bFuncNew;
2759}
2760
2772int Ivy_FraigNodesAreEquivBdd( Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2 )
2773{
2774 static DdManager * dd = NULL;
2775 DdNode * bFunc, * bTemp;
2776 Vec_Ptr_t * vFront;
2777 Ivy_Obj_t * pObj;
2778 int i, RetValue, Iter, Level;
2779 // start the manager
2780 if ( dd == NULL )
2781 dd = Cudd_Init( 50, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
2782 // create front
2783 vFront = Vec_PtrAlloc( 100 );
2784 Vec_PtrPush( vFront, pObj1 );
2785 Vec_PtrPush( vFront, pObj2 );
2786 // get the function
2787 bFunc = Cudd_bddXor( dd, Cudd_bddIthVar(dd,0), Cudd_bddIthVar(dd,1) ); Cudd_Ref( bFunc );
2788 bFunc = Cudd_NotCond( bFunc, pObj1->fPhase != pObj2->fPhase );
2789 // try running BDDs
2790 for ( Iter = 0; ; Iter++ )
2791 {
2792 // find max level
2793 Level = 0;
2794 Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pObj, i )
2795 if ( Level < (int)pObj->Level )
2796 Level = (int)pObj->Level;
2797 if ( Level == 0 )
2798 break;
2799 bFunc = Ivy_FraigNodesAreEquivBdd_int( dd, bTemp = bFunc, vFront, Level ); Cudd_Ref( bFunc );
2800 Cudd_RecursiveDeref( dd, bTemp );
2801 if ( bFunc == Cudd_ReadLogicZero(dd) ) // proved
2802 {printf( "%d", Iter ); break;}
2803 if ( Cudd_DagSize(bFunc) > 1000 )
2804 {printf( "b" ); break;}
2805 if ( dd->size > 120 )
2806 {printf( "s" ); break;}
2807 if ( Iter > 50 )
2808 {printf( "i" ); break;}
2809 }
2810 if ( bFunc == Cudd_ReadLogicZero(dd) ) // unsat
2811 RetValue = 1;
2812 else if ( Level == 0 ) // sat
2813 RetValue = 0;
2814 else
2815 RetValue = -1; // spaceout/timeout
2816 Cudd_RecursiveDeref( dd, bFunc );
2817 Vec_PtrFree( vFront );
2818 return RetValue;
2819}
2820#endif
2821
2823
2824#include "aig/aig/aig.h"
2825
2827
2828
2840void Ivy_FraigExtractCone_rec( Ivy_Man_t * p, Ivy_Obj_t * pNode, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
2841{
2842 if ( pNode->fMarkB )
2843 return;
2844 pNode->fMarkB = 1;
2845 if ( Ivy_ObjIsPi(pNode) )
2846 {
2847 Vec_IntPush( vLeaves, pNode->Id );
2848 return;
2849 }
2850 assert( Ivy_ObjIsAnd(pNode) );
2851 Ivy_FraigExtractCone_rec( p, Ivy_ObjFanin0(pNode), vLeaves, vNodes );
2852 Ivy_FraigExtractCone_rec( p, Ivy_ObjFanin1(pNode), vLeaves, vNodes );
2853 Vec_IntPush( vNodes, pNode->Id );
2854}
2855
2868{
2869 Aig_Man_t * pMan;
2870 Aig_Obj_t * pMiter;
2871 Vec_Int_t * vNodes;
2872 Ivy_Obj_t * pObjIvy;
2873 int i;
2874 // collect nodes
2875 vNodes = Vec_IntAlloc( 100 );
2876 Ivy_ManConst1(p)->fMarkB = 1;
2877 Ivy_FraigExtractCone_rec( p, pObj1, vLeaves, vNodes );
2878 Ivy_FraigExtractCone_rec( p, pObj2, vLeaves, vNodes );
2879 Ivy_ManConst1(p)->fMarkB = 0;
2880 // create new manager
2881 pMan = Aig_ManStart( 1000 );
2882 Ivy_ManConst1(p)->pEquiv = (Ivy_Obj_t *)Aig_ManConst1(pMan);
2883 Ivy_ManForEachNodeVec( p, vLeaves, pObjIvy, i )
2884 {
2885 pObjIvy->pEquiv = (Ivy_Obj_t *)Aig_ObjCreateCi( pMan );
2886 pObjIvy->fMarkB = 0;
2887 }
2888 // duplicate internal nodes
2889 Ivy_ManForEachNodeVec( p, vNodes, pObjIvy, i )
2890 {
2891
2892 pObjIvy->pEquiv = (Ivy_Obj_t *)Aig_And( pMan, (Aig_Obj_t *)Ivy_ObjChild0Equiv(pObjIvy), (Aig_Obj_t *)Ivy_ObjChild1Equiv(pObjIvy) );
2893 pObjIvy->fMarkB = 0;
2894
2895 pMiter = (Aig_Obj_t *)pObjIvy->pEquiv;
2896 assert( pMiter->fPhase == pObjIvy->fPhase );
2897 }
2898 // create the PO
2899 pMiter = Aig_Exor( pMan, (Aig_Obj_t *)pObj1->pEquiv, (Aig_Obj_t *)pObj2->pEquiv );
2900 pMiter = Aig_NotCond( pMiter, Aig_Regular(pMiter)->fPhase ^ Aig_IsComplement(pMiter) );
2901
2902/*
2903printf( "Polarity = %d\n", pMiter->fPhase );
2904 if ( Ivy_ObjIsConst1(pObj1) || Ivy_ObjIsConst1(pObj2) )
2905 {
2906 pMiter = Aig_NotCond( pMiter, 1 );
2907printf( "***************\n" );
2908 }
2909*/
2910 pMiter = Aig_ObjCreateCo( pMan, pMiter );
2911//printf( "Polarity = %d\n", pMiter->fPhase );
2912 Aig_ManCleanup( pMan );
2913 Vec_IntFree( vNodes );
2914 return pMan;
2915}
2916
2928int Ivy_FraigCheckCone( Ivy_FraigMan_t * pGlo, Ivy_Man_t * p, Ivy_Obj_t * pObj1, Ivy_Obj_t * pObj2, int nConfLimit )
2929{
2930 extern int Fra_FraigSat( Aig_Man_t * pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int nLearnedStart, int nLearnedDelta, int nLearnedPerce, int fFlipBits, int fAndOuts, int fNewSolver, int fVerbose );
2931 Vec_Int_t * vLeaves;
2932 Aig_Man_t * pMan;
2933 Aig_Obj_t * pObj;
2934 int i, RetValue;
2935 vLeaves = Vec_IntAlloc( 100 );
2936 pMan = Ivy_FraigExtractCone( p, pObj1, pObj2, vLeaves );
2937 RetValue = Fra_FraigSat( pMan, nConfLimit, 0, 0, 0, 0, 0, 0, 0, 1 );
2938 if ( RetValue == 0 )
2939 {
2940 int Counter = 0;
2941 memset( pGlo->pPatWords, 0, sizeof(unsigned) * pGlo->nPatWords );
2942 Aig_ManForEachCi( pMan, pObj, i )
2943 if ( ((int *)pMan->pData)[i] )
2944 {
2945 int iObjIvy = Vec_IntEntry( vLeaves, i );
2946 assert( iObjIvy > 0 && iObjIvy <= Ivy_ManPiNum(p) );
2947 Ivy_InfoSetBit( pGlo->pPatWords, iObjIvy-1 );
2948//printf( "%d ", iObjIvy );
2949Counter++;
2950 }
2951 assert( Counter > 0 );
2952 }
2953 Vec_IntFree( vLeaves );
2954 if ( RetValue == 1 )
2955 printf( "UNSAT\n" );
2956 else if ( RetValue == 0 )
2957 printf( "SAT\n" );
2958 else if ( RetValue == -1 )
2959 printf( "UNDEC\n" );
2960
2961// p->pModel = (int *)pMan->pData, pMan2->pData = NULL;
2962 Aig_ManStop( pMan );
2963 return RetValue;
2964}
2965
2969
2970
2972
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#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
void Aig_ManStop(Aig_Man_t *p)
Definition aigMan.c:187
#define Aig_ManForEachCi(p, pObj, i)
ITERATORS ///.
Definition aig.h:393
Aig_Obj_t * Aig_And(Aig_Man_t *p, Aig_Obj_t *p0, Aig_Obj_t *p1)
Definition aigOper.c:104
Aig_Obj_t * Aig_ObjCreateCo(Aig_Man_t *p, Aig_Obj_t *pDriver)
Definition aigObj.c:66
struct Aig_Obj_t_ Aig_Obj_t
Definition aig.h:51
Aig_Obj_t * Aig_Exor(Aig_Man_t *p, Aig_Obj_t *p0, Aig_Obj_t *p1)
Definition aigOper.c:220
Aig_Man_t * Aig_ManStart(int nNodesMax)
DECLARATIONS ///.
Definition aigMan.c:47
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition aig.h:50
int Aig_ManCleanup(Aig_Man_t *p)
Definition aigMan.c:265
Aig_Obj_t * Aig_ObjCreateCi(Aig_Man_t *p)
DECLARATIONS ///.
Definition aigObj.c:45
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
ABC_NAMESPACE_IMPL_START typedef char ProgressBar
Definition bbrNtbdd.c:27
#define l_True
Definition bmcBmcS.c:35
#define l_False
Definition bmcBmcS.c:36
#define sat_solver_addclause
Definition cecSatG2.c:37
#define sat_solver
Definition cecSatG2.c:34
#define sat_solver_solve
Definition cecSatG2.c:45
Cube * p
Definition exorList.c:222
void Extra_ProgressBarStop(ProgressBar *p)
ProgressBar * Extra_ProgressBarStart(FILE *pFile, int nItemsTotal)
FUNCTION DEFINITIONS ///.
int Fra_FraigSat(Aig_Man_t *pMan, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int nLearnedStart, int nLearnedDelta, int nLearnedPerce, int fFlipBits, int fAndOuts, int fNewSolver, int fVerbose)
ITERATORS ///.
Definition fraCec.c:47
Ivy_Man_t * Ivy_FraigPerform(Ivy_Man_t *pManAig, Ivy_FraigParams_t *pParams)
Definition ivyFraig.c:451
int Ivy_FraigCountPairsClasses(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1147
void Ivy_FraigCleanPatScores(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1664
void Ivy_NodeAssignConst(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj, int fConst1)
Definition ivyFraig.c:701
Aig_Man_t * Ivy_FraigExtractCone(Ivy_Man_t *p, Ivy_Obj_t *pObj1, Ivy_Obj_t *pObj2, Vec_Int_t *vLeaves)
Definition ivyFraig.c:2867
void Ivy_FraigSavePattern0(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1488
void Ivy_FraigResimulate(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1752
void Ivy_FraigSimulateOne(Ivy_FraigMan_t *p)
Definition ivyFraig.c:990
int Ivy_FraigRefineClasses(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1387
void Ivy_FraigPrintClass(Ivy_Obj_t *pClass)
Definition ivyFraig.c:1426
void Ivy_FraigSavePattern2(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1567
struct Prove_ParamsStruct_t_ Prove_Params_t
Definition ivyFraig.c:108
void Ivy_FraigCheckOutputSimsSavePattern(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj)
Definition ivyFraig.c:1307
int Ivy_FraigSetActivityFactors_rec(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj, int LevelMin, int LevelMax)
Definition ivyFraig.c:2600
void Ivy_FraigRemoveClass(Ivy_FraigList_t *pList, Ivy_Obj_t *pClass)
Definition ivyFraig.c:1120
void Ivy_FraigPrintSimClasses(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1466
void Ivy_FraigSimulateOneSim(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1023
int Ivy_FraigRefineClass_rec(Ivy_FraigMan_t *p, Ivy_Obj_t *pClass)
Definition ivyFraig.c:1244
void Ivy_FraigAssignDist1(Ivy_FraigMan_t *p, unsigned *pPat)
Definition ivyFraig.c:741
int Ivy_FraigSelectBestPat(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1713
int Ivy_FraigCheckOutputSims(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1349
int Ivy_NodeHasZeroSim(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj)
Definition ivyFraig.c:768
void Ivy_FraigInsertClass(Ivy_FraigList_t *pList, Ivy_Obj_t *pBase, Ivy_Obj_t *pClass)
Definition ivyFraig.c:1097
void Ivy_FraigSavePattern1(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1504
#define Ivy_FraigForEachEquivClassSafe(pList, pEnt, pEnt2)
Definition ivyFraig.c:169
#define Ivy_FraigForEachBinNode(pBin, pEnt)
Definition ivyFraig.c:181
#define Ivy_FraigForEachEquivClass(pList, pEnt)
Definition ivyFraig.c:165
void Ivy_NodeAssignRandom(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj)
Definition ivyFraig.c:680
void Ivy_FraigParamsDefault(Ivy_FraigParams_t *pParams)
FUNCTION DEFINITIONS ///.
Definition ivyFraig.c:225
void Ivy_FraigCreateClasses(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1174
ABC_NAMESPACE_IMPL_END ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_END ABC_NAMESPACE_IMPL_START void Ivy_FraigExtractCone_rec(Ivy_Man_t *p, Ivy_Obj_t *pNode, Vec_Int_t *vLeaves, Vec_Int_t *vNodes)
Definition ivyFraig.c:2840
void Ivy_NodeSimulate(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj)
Definition ivyFraig.c:888
Vec_Ptr_t * Ivy_FraigCollectSuper(Ivy_Obj_t *pObj, int fUseMuxes)
Definition ivyFraig.c:2498
int Ivy_FraigCountClassNodes(Ivy_Obj_t *pClass)
Definition ivyFraig.c:1446
void Ivy_FraigPrintActivity(Ivy_FraigMan_t *p)
Definition ivyFraig.c:2080
void Ivy_NodeSimulateSim(Ivy_FraigMan_t *p, Ivy_FraigSim_t *pSims)
Definition ivyFraig.c:833
void Ivy_FraigAddClass(Ivy_FraigList_t *pList, Ivy_Obj_t *pClass)
Definition ivyFraig.c:1067
struct Ivy_FraigList_t_ Ivy_FraigList_t
Definition ivyFraig.c:35
void Ivy_FraigCollectSuper_rec(Ivy_Obj_t *pObj, Vec_Ptr_t *vSuper, int fFirst, int fUseMuxes)
Definition ivyFraig.c:2473
void Ivy_FraigObjAddToFrontier(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj, Vec_Ptr_t *vFrontier)
Definition ivyFraig.c:2519
#define Ivy_FraigForEachClassNode(pClass, pEnt)
Definition ivyFraig.c:176
typedefABC_NAMESPACE_IMPL_START struct Ivy_FraigMan_t_ Ivy_FraigMan_t
DECLARATIONS ///.
Definition ivyFraig.c:33
unsigned Ivy_NodeHash(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj)
Definition ivyFraig.c:951
void Ivy_NodeComplementSim(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj)
Definition ivyFraig.c:790
struct Ivy_FraigSim_t_ Ivy_FraigSim_t
Definition ivyFraig.c:34
int Ivy_NodeCompareSims(Ivy_FraigMan_t *p, Ivy_Obj_t *pObj0, Ivy_Obj_t *pObj1)
Definition ivyFraig.c:810
void Ivy_FraigAddClausesSuper(Ivy_FraigMan_t *p, Ivy_Obj_t *pNode, Vec_Ptr_t *vSuper)
Definition ivyFraig.c:2435
void Ivy_FraigAssignRandom(Ivy_FraigMan_t *p)
Definition ivyFraig.c:722
void Ivy_FraigAddClausesMux(Ivy_FraigMan_t *p, Ivy_Obj_t *pNode)
Definition ivyFraig.c:2352
Ivy_Man_t * Ivy_FraigMiter(Ivy_Man_t *pManAig, Ivy_FraigParams_t *pParams)
Definition ivyFraig.c:480
void Ivy_FraigSavePattern3(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1591
void Ivy_FraigSavePattern(Ivy_FraigMan_t *p)
Definition ivyFraig.c:1543
void Ivy_NodeAddToClass(Ivy_Obj_t *pClass, Ivy_Obj_t *pObj)
Definition ivyFraig.c:1045
int Ivy_FraigProve(Ivy_Man_t **ppManAig, void *pPars)
Definition ivyFraig.c:255
typedefABC_NAMESPACE_HEADER_START struct Ivy_Man_t_ Ivy_Man_t
INCLUDES ///.
Definition ivy.h:46
void Ivy_ManIncrementTravId(Ivy_Man_t *p)
DECLARATIONS ///.
Definition ivyUtil.c:45
#define IVY_MAX(a, b)
Definition ivy.h:183
int Ivy_ManCleanup(Ivy_Man_t *p)
Definition ivyMan.c:265
#define Ivy_ManForEachObj(p, pObj, i)
Definition ivy.h:393
#define Ivy_ManForEachNode(p, pObj, i)
Definition ivy.h:402
#define IVY_MIN(a, b)
MACRO DEFINITIONS ///.
Definition ivy.h:182
Ivy_Obj_t * Ivy_ObjCreatePo(Ivy_Man_t *p, Ivy_Obj_t *pDriver)
Definition ivyObj.c:61
struct Ivy_FraigParams_t_ Ivy_FraigParams_t
Definition ivy.h:49
#define Ivy_ManForEachPo(p, pObj, i)
Definition ivy.h:390
void Ivy_ManStop(Ivy_Man_t *p)
Definition ivyMan.c:238
struct Ivy_Obj_t_ Ivy_Obj_t
Definition ivy.h:47
int Ivy_ObjIsMuxType(Ivy_Obj_t *pObj)
Definition ivyUtil.c:479
Ivy_Obj_t * Ivy_ObjRecognizeMux(Ivy_Obj_t *pObj, Ivy_Obj_t **ppObjT, Ivy_Obj_t **ppObjE)
Definition ivyUtil.c:517
#define Ivy_ManForEachNodeVec(p, vIds, pObj, i)
Definition ivy.h:408
Ivy_Man_t * Ivy_ManStartFrom(Ivy_Man_t *p)
Definition ivyMan.c:85
#define Ivy_ManForEachPi(p, pObj, i)
ITERATORS ///.
Definition ivy.h:387
Ivy_Man_t * Ivy_ManDup(Ivy_Man_t *p)
Definition ivyMan.c:110
Ivy_Obj_t * Ivy_And(Ivy_Man_t *p, Ivy_Obj_t *p0, Ivy_Obj_t *p1)
Definition ivyOper.c:84
int Ivy_ManLevels(Ivy_Man_t *p)
Definition ivyUtil.c:249
sat_solver * sat_solver_new(void)
Definition satSolver.c:1137
int sat_solver_simplify(sat_solver *s)
Definition satSolver.c:1515
void sat_solver_setnvars(sat_solver *s, int n)
Definition satSolver.c:1272
void sat_solver_delete(sat_solver *s)
Definition satSolver.c:1341
void Sat_SolverPrintStats(FILE *pFile, sat_solver *p)
Definition satUtil.c:193
unsigned int fPhase
Definition aig.h:78
Ivy_Obj_t * pTail
Definition ivyFraig.c:40
Ivy_Obj_t * pHead
Definition ivyFraig.c:39
abctime timeSat
Definition ivyFraig.c:98
abctime timeSatFail
Definition ivyFraig.c:101
int * pPatScores
Definition ivyFraig.c:70
ABC_INT64_T nInsLimitGlobal
Definition ivyFraig.c:59
Ivy_FraigList_t lCand
Definition ivyFraig.c:73
Ivy_Man_t * pManAig
Definition ivyFraig.c:61
sat_solver * pSat
Definition ivyFraig.c:76
abctime timeSim
Definition ivyFraig.c:96
abctime timeSatSat
Definition ivyFraig.c:100
Ivy_FraigList_t lClasses
Definition ivyFraig.c:72
abctime timeTrav
Definition ivyFraig.c:97
Ivy_FraigParams_t * pParams
Definition ivyFraig.c:56
abctime timeRef
Definition ivyFraig.c:102
Ivy_Man_t * pManFraig
Definition ivyFraig.c:62
abctime timeSatUnsat
Definition ivyFraig.c:99
abctime time1
Definition ivyFraig.c:104
Vec_Ptr_t * vPiVars
Definition ivyFraig.c:78
Ivy_FraigSim_t * pSimStart
Definition ivyFraig.c:66
unsigned * pPatWords
Definition ivyFraig.c:69
ABC_INT64_T nBTLimitGlobal
Definition ivyFraig.c:58
abctime time2
Definition ivyFraig.c:105
ProgressBar * pProgress
Definition ivyFraig.c:80
abctime timeTotal
Definition ivyFraig.c:103
char * pSimWords
Definition ivyFraig.c:65
double dActConeBumpMax
Definition ivy.h:139
double dActConeRatio
Definition ivy.h:138
double dSimSatur
Definition ivy.h:135
int nBTLimitMiter
Definition ivy.h:144
Ivy_FraigSim_t * pNext
Definition ivyFraig.c:47
Ivy_FraigSim_t * pFanin0
Definition ivyFraig.c:48
unsigned pData[0]
Definition ivyFraig.c:50
Ivy_FraigSim_t * pFanin1
Definition ivyFraig.c:49
Ivy_Obj_t * pPrevFan0
Definition ivy.h:91
Ivy_Obj_t * pFanout
Definition ivy.h:88
Ivy_Obj_t * pPrevFan1
Definition ivy.h:92
unsigned fMarkB
Definition ivy.h:79
Ivy_Obj_t * pNextFan1
Definition ivy.h:90
Ivy_Obj_t * pEquiv
Definition ivy.h:93
int TravId
Definition ivy.h:76
int Id
Definition ivy.h:75
Ivy_Obj_t * pNextFan0
Definition ivy.h:89
unsigned fFailTfo
Definition ivy.h:82
unsigned Level
Definition ivy.h:84
unsigned fMarkA
Definition ivy.h:78
unsigned fPhase
Definition ivy.h:81
ABC_INT64_T nTotalBacktracksMade
Definition ivyFraig.c:136
ABC_INT64_T nTotalInspectsMade
Definition ivyFraig.c:137
ABC_INT64_T nTotalBacktrackLimit
Definition ivyFraig.c:133
ABC_INT64_T nTotalInspectLimit
Definition ivyFraig.c:134
#define assert(ex)
Definition util_old.h:213
char * memset()
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55