ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcSat.c
Go to the documentation of this file.
1
20
21#include "base/abc/abc.h"
22#include "base/main/main.h"
23#include "base/cmd/cmd.h"
24#include "sat/bsat/satSolver.h"
25#include "aig/gia/gia.h"
26#include "aig/gia/giaAig.h"
27
28#ifdef ABC_USE_CUDD
29#include "bdd/extrab/extraBdd.h"
30#endif
31
33
34
38
39static sat_solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes );
41static int nMuxes;
42
46
58int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects )
59{
60 sat_solver * pSat;
61 lbool status;
62 int RetValue = 0;
63 abctime clk;
64
65 if ( pNumConfs )
66 *pNumConfs = 0;
67 if ( pNumInspects )
68 *pNumInspects = 0;
69
70 assert( Abc_NtkLatchNum(pNtk) == 0 );
71
72// if ( Abc_NtkPoNum(pNtk) > 1 )
73// fprintf( stdout, "Warning: The miter has %d outputs. SAT will try to prove all of them.\n", Abc_NtkPoNum(pNtk) );
74
75 // load clauses into the sat_solver
76 clk = Abc_Clock();
77 pSat = (sat_solver *)Abc_NtkMiterSatCreate( pNtk, 0 );
78 if ( pSat == NULL )
79 return 1;
80//printf( "%d \n", pSat->clauses.size );
81//sat_solver_delete( pSat );
82//return 1;
83
84// printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
85// ABC_PRT( "Time", Abc_Clock() - clk );
86
87 // simplify the problem
88 clk = Abc_Clock();
89 status = sat_solver_simplify(pSat);
90// printf( "Simplified the problem to %d variables and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
91// ABC_PRT( "Time", Abc_Clock() - clk );
92 if ( status == 0 )
93 {
94 sat_solver_delete( pSat );
95// printf( "The problem is UNSATISFIABLE after simplification.\n" );
96 return 1;
97 }
98
99 // solve the miter
100 clk = Abc_Clock();
101 if ( fVerbose )
102 pSat->verbosity = 1;
103 status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)nInsLimit, (ABC_INT64_T)0, (ABC_INT64_T)0 );
104 if ( status == l_Undef )
105 {
106// printf( "The problem timed out.\n" );
107 RetValue = -1;
108 }
109 else if ( status == l_True )
110 {
111// printf( "The problem is SATISFIABLE.\n" );
112 RetValue = 0;
113 }
114 else if ( status == l_False )
115 {
116// printf( "The problem is UNSATISFIABLE.\n" );
117 RetValue = 1;
118 }
119 else
120 assert( 0 );
121// ABC_PRT( "SAT sat_solver time", Abc_Clock() - clk );
122// printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts );
123
124 // if the problem is SAT, get the counterexample
125 if ( status == l_True )
126 {
127// Vec_Int_t * vCiIds = Abc_NtkGetCiIds( pNtk );
128 Vec_Int_t * vCiIds = Abc_NtkGetCiSatVarNums( pNtk );
129 pNtk->pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize );
130 Vec_IntFree( vCiIds );
131 }
132 // free the sat_solver
133 if ( fVerbose )
134 Sat_SolverPrintStats( stdout, pSat );
135
136 if ( pNumConfs )
137 *pNumConfs = (int)pSat->stats.conflicts;
138 if ( pNumInspects )
139 *pNumInspects = (int)pSat->stats.inspects;
140
141sat_solver_store_write( pSat, "trace.cnf" );
143
144 sat_solver_delete( pSat );
145 return RetValue;
146}
147
160{
161 extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan );
162 int RetValue = 0;
163 int * pResult = NULL;
164 Abc_Ntk_t * pNtk;
165 Aig_Man_t * pMan;
166 pMan = Gia_ManToAig( p, 0 );
167 pNtk = Abc_NtkFromAigPhase( pMan );
168 pNtk->pName = Extra_UtilStrsav(p->pName);
169 Aig_ManStop( pMan );
170 RetValue = Abc_NtkMiterSat( pNtk, 1000000, 0, 0, NULL, NULL );
171 if ( RetValue == 0 ) // sat
172 pResult = pNtk->pModel, pNtk->pModel = NULL;
173 Abc_NtkDelete( pNtk );
174 return pResult;
175}
176
177
190{
191 Vec_Int_t * vCiIds;
192 Abc_Obj_t * pObj;
193 int i;
194 vCiIds = Vec_IntAlloc( Abc_NtkCiNum(pNtk) );
195 Abc_NtkForEachCi( pNtk, pObj, i )
196 Vec_IntPush( vCiIds, (int)(ABC_PTRINT_T)pObj->pCopy );
197 return vCiIds;
198}
199
200
201
213int Abc_NtkClauseTriv( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
214{
215//printf( "Adding triv %d. %d\n", Abc_ObjRegular(pNode)->Id, (int)pSat->sat_solver_stats.clauses );
216 vVars->nSize = 0;
217 Vec_IntPush( vVars, toLitCond( (int)(ABC_PTRINT_T)Abc_ObjRegular(pNode)->pCopy, Abc_ObjIsComplement(pNode) ) );
218// Vec_IntPush( vVars, toLitCond( (int)Abc_ObjRegular(pNode)->Id, Abc_ObjIsComplement(pNode) ) );
219 return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
220}
221
233int Abc_NtkClauseTop( sat_solver * pSat, Vec_Ptr_t * vNodes, Vec_Int_t * vVars )
234{
235 Abc_Obj_t * pNode;
236 int i;
237//printf( "Adding triv %d. %d\n", Abc_ObjRegular(pNode)->Id, (int)pSat->sat_solver_stats.clauses );
238 vVars->nSize = 0;
239 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
240 Vec_IntPush( vVars, toLitCond( (int)(ABC_PTRINT_T)Abc_ObjRegular(pNode)->pCopy, Abc_ObjIsComplement(pNode) ) );
241// Vec_IntPush( vVars, toLitCond( (int)Abc_ObjRegular(pNode)->Id, Abc_ObjIsComplement(pNode) ) );
242 return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
243}
244
256int Abc_NtkClauseAnd( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_Int_t * vVars )
257{
258 int fComp1, Var, Var1, i;
259//printf( "Adding AND %d. (%d) %d\n", pNode->Id, vSuper->nSize+1, (int)pSat->sat_solver_stats.clauses );
260
261 assert( !Abc_ObjIsComplement( pNode ) );
262 assert( Abc_ObjIsNode( pNode ) );
263
264// nVars = sat_solver_nvars(pSat);
265 Var = (int)(ABC_PTRINT_T)pNode->pCopy;
266// Var = pNode->Id;
267
268// assert( Var < nVars );
269 for ( i = 0; i < vSuper->nSize; i++ )
270 {
271 // get the predecessor nodes
272 // get the complemented attributes of the nodes
273 fComp1 = Abc_ObjIsComplement((Abc_Obj_t *)vSuper->pArray[i]);
274 // determine the variable numbers
275 Var1 = (int)(ABC_PTRINT_T)Abc_ObjRegular((Abc_Obj_t *)vSuper->pArray[i])->pCopy;
276// Var1 = (int)Abc_ObjRegular(vSuper->pArray[i])->Id;
277
278 // check that the variables are in the SAT manager
279// assert( Var1 < nVars );
280
281 // suppose the AND-gate is A * B = C
282 // add !A => !C or A + !C
283 // fprintf( pFile, "%d %d 0%c", Var1, -Var, 10 );
284 vVars->nSize = 0;
285 Vec_IntPush( vVars, toLitCond(Var1, fComp1) );
286 Vec_IntPush( vVars, toLitCond(Var, 1 ) );
287 if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
288 return 0;
289 }
290
291 // add A & B => C or !A + !B + C
292// fprintf( pFile, "%d %d %d 0%c", -Var1, -Var2, Var, 10 );
293 vVars->nSize = 0;
294 for ( i = 0; i < vSuper->nSize; i++ )
295 {
296 // get the predecessor nodes
297 // get the complemented attributes of the nodes
298 fComp1 = Abc_ObjIsComplement((Abc_Obj_t *)vSuper->pArray[i]);
299 // determine the variable numbers
300 Var1 = (int)(ABC_PTRINT_T)Abc_ObjRegular((Abc_Obj_t *)vSuper->pArray[i])->pCopy;
301// Var1 = (int)Abc_ObjRegular(vSuper->pArray[i])->Id;
302 // add this variable to the array
303 Vec_IntPush( vVars, toLitCond(Var1, !fComp1) );
304 }
305 Vec_IntPush( vVars, toLitCond(Var, 0) );
306 return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
307}
308
320int Abc_NtkClauseMux( sat_solver * pSat, Abc_Obj_t * pNode, Abc_Obj_t * pNodeC, Abc_Obj_t * pNodeT, Abc_Obj_t * pNodeE, Vec_Int_t * vVars )
321{
322 int VarF, VarI, VarT, VarE, fCompT, fCompE;
323//printf( "Adding mux %d. %d\n", pNode->Id, (int)pSat->sat_solver_stats.clauses );
324
325 assert( !Abc_ObjIsComplement( pNode ) );
326 assert( Abc_NodeIsMuxType( pNode ) );
327 // get the variable numbers
328 VarF = (int)(ABC_PTRINT_T)pNode->pCopy;
329 VarI = (int)(ABC_PTRINT_T)pNodeC->pCopy;
330 VarT = (int)(ABC_PTRINT_T)Abc_ObjRegular(pNodeT)->pCopy;
331 VarE = (int)(ABC_PTRINT_T)Abc_ObjRegular(pNodeE)->pCopy;
332// VarF = (int)pNode->Id;
333// VarI = (int)pNodeC->Id;
334// VarT = (int)Abc_ObjRegular(pNodeT)->Id;
335// VarE = (int)Abc_ObjRegular(pNodeE)->Id;
336
337 // get the complementation flags
338 fCompT = Abc_ObjIsComplement(pNodeT);
339 fCompE = Abc_ObjIsComplement(pNodeE);
340
341 // f = ITE(i, t, e)
342 // i' + t' + f
343 // i' + t + f'
344 // i + e' + f
345 // i + e + f'
346 // create four clauses
347 vVars->nSize = 0;
348 Vec_IntPush( vVars, toLitCond(VarI, 1) );
349 Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) );
350 Vec_IntPush( vVars, toLitCond(VarF, 0) );
351 if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
352 return 0;
353 vVars->nSize = 0;
354 Vec_IntPush( vVars, toLitCond(VarI, 1) );
355 Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) );
356 Vec_IntPush( vVars, toLitCond(VarF, 1) );
357 if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
358 return 0;
359 vVars->nSize = 0;
360 Vec_IntPush( vVars, toLitCond(VarI, 0) );
361 Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) );
362 Vec_IntPush( vVars, toLitCond(VarF, 0) );
363 if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
364 return 0;
365 vVars->nSize = 0;
366 Vec_IntPush( vVars, toLitCond(VarI, 0) );
367 Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) );
368 Vec_IntPush( vVars, toLitCond(VarF, 1) );
369 if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
370 return 0;
371
372 if ( VarT == VarE )
373 {
374// assert( fCompT == !fCompE );
375 return 1;
376 }
377
378 // two additional clauses
379 // t' & e' -> f' t + e + f'
380 // t & e -> f t' + e' + f
381 vVars->nSize = 0;
382 Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) );
383 Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) );
384 Vec_IntPush( vVars, toLitCond(VarF, 1) );
385 if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
386 return 0;
387 vVars->nSize = 0;
388 Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) );
389 Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) );
390 Vec_IntPush( vVars, toLitCond(VarF, 0) );
391 return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
392}
393
405int Abc_NtkCollectSupergate_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, int fFirst, int fStopAtMux )
406{
407 int RetValue1, RetValue2, i;
408 // check if the node is visited
409 if ( Abc_ObjRegular(pNode)->fMarkB )
410 {
411 // check if the node occurs in the same polarity
412 for ( i = 0; i < vSuper->nSize; i++ )
413 if ( vSuper->pArray[i] == pNode )
414 return 1;
415 // check if the node is present in the opposite polarity
416 for ( i = 0; i < vSuper->nSize; i++ )
417 if ( vSuper->pArray[i] == Abc_ObjNot(pNode) )
418 return -1;
419 assert( 0 );
420 return 0;
421 }
422 // if the new node is complemented or a PI, another gate begins
423 if ( !fFirst )
424 if ( Abc_ObjIsComplement(pNode) || !Abc_ObjIsNode(pNode) || Abc_ObjFanoutNum(pNode) > 1 || (fStopAtMux && Abc_NodeIsMuxType(pNode)) )
425 {
426 Vec_PtrPush( vSuper, pNode );
427 Abc_ObjRegular(pNode)->fMarkB = 1;
428 return 0;
429 }
430 assert( !Abc_ObjIsComplement(pNode) );
431 assert( Abc_ObjIsNode(pNode) );
432 // go through the branches
433 RetValue1 = Abc_NtkCollectSupergate_rec( Abc_ObjChild0(pNode), vSuper, 0, fStopAtMux );
434 RetValue2 = Abc_NtkCollectSupergate_rec( Abc_ObjChild1(pNode), vSuper, 0, fStopAtMux );
435 if ( RetValue1 == -1 || RetValue2 == -1 )
436 return -1;
437 // return 1 if at least one branch has a duplicate
438 return RetValue1 || RetValue2;
439}
440
452void Abc_NtkCollectSupergate( Abc_Obj_t * pNode, int fStopAtMux, Vec_Ptr_t * vNodes )
453{
454 int RetValue, i;
455 assert( !Abc_ObjIsComplement(pNode) );
456 // collect the nodes in the implication supergate
457 Vec_PtrClear( vNodes );
458 RetValue = Abc_NtkCollectSupergate_rec( pNode, vNodes, 1, fStopAtMux );
459 assert( vNodes->nSize > 1 );
460 // unmark the visited nodes
461 for ( i = 0; i < vNodes->nSize; i++ )
462 Abc_ObjRegular((Abc_Obj_t *)vNodes->pArray[i])->fMarkB = 0;
463 // if we found the node and its complement in the same implication supergate,
464 // return empty set of nodes (meaning that we should use constant-0 node)
465 if ( RetValue == -1 )
466 vNodes->nSize = 0;
467}
468
469
481int Abc_NtkNodeFactor( Abc_Obj_t * pObj, int nLevelMax )
482{
483// nLevelMax = ((nLevelMax)/2)*3;
484 assert( (int)pObj->Level <= nLevelMax );
485// return (int)(100000000.0 * pow(0.999, nLevelMax - pObj->Level));
486 return (int)(100000000.0 * (1 + 0.01 * pObj->Level));
487// return (int)(100000000.0 / ((nLevelMax)/2)*3 - pObj->Level);
488}
489
502{
503 Abc_Obj_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE;
504 Vec_Ptr_t * vNodes, * vSuper;
505 Vec_Int_t * vVars;
506 int i, k, fUseMuxes = 1;
507// int fOrderCiVarsFirst = 0;
508 int RetValue = 0;
509
510 assert( Abc_NtkIsStrash(pNtk) );
511
512 // clean the CI node pointers
513 Abc_NtkForEachCi( pNtk, pNode, i )
514 pNode->pCopy = NULL;
515
516 // start the data structures
517 vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the sat_solver
518 vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
519 vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
520
521 // add the clause for the constant node
522 pNode = Abc_AigConst1(pNtk);
523 pNode->fMarkA = 1;
524 pNode->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)vNodes->nSize;
525 Vec_PtrPush( vNodes, pNode );
526 Abc_NtkClauseTriv( pSat, pNode, vVars );
527/*
528 // add the PI variables first
529 Abc_NtkForEachCi( pNtk, pNode, i )
530 {
531 pNode->fMarkA = 1;
532 pNode->pCopy = (Abc_Obj_t *)vNodes->nSize;
533 Vec_PtrPush( vNodes, pNode );
534 }
535*/
536 // collect the nodes that need clauses and top-level assignments
537 Vec_PtrClear( vSuper );
538 Abc_NtkForEachCo( pNtk, pNode, i )
539 {
540 // get the fanin
541 pFanin = Abc_ObjFanin0(pNode);
542 // create the node's variable
543 if ( pFanin->fMarkA == 0 )
544 {
545 pFanin->fMarkA = 1;
546 pFanin->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)vNodes->nSize;
547 Vec_PtrPush( vNodes, pFanin );
548 }
549 // add the trivial clause
550 Vec_PtrPush( vSuper, Abc_ObjChild0(pNode) );
551 }
552 if ( !Abc_NtkClauseTop( pSat, vSuper, vVars ) )
553 goto Quits;
554
555
556 // add the clauses
557 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
558 {
559 assert( !Abc_ObjIsComplement(pNode) );
560 if ( !Abc_AigNodeIsAnd(pNode) )
561 continue;
562//printf( "%d ", pNode->Id );
563
564 // add the clauses
565 if ( fUseMuxes && Abc_NodeIsMuxType(pNode) )
566 {
567 nMuxes++;
568
569 pNodeC = Abc_NodeRecognizeMux( pNode, &pNodeT, &pNodeE );
570 Vec_PtrClear( vSuper );
571 Vec_PtrPush( vSuper, pNodeC );
572 Vec_PtrPush( vSuper, pNodeT );
573 Vec_PtrPush( vSuper, pNodeE );
574 // add the fanin nodes to explore
575 Vec_PtrForEachEntry( Abc_Obj_t *, vSuper, pFanin, k )
576 {
577 pFanin = Abc_ObjRegular(pFanin);
578 if ( pFanin->fMarkA == 0 )
579 {
580 pFanin->fMarkA = 1;
581 pFanin->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)vNodes->nSize;
582 Vec_PtrPush( vNodes, pFanin );
583 }
584 }
585 // add the clauses
586 if ( !Abc_NtkClauseMux( pSat, pNode, pNodeC, pNodeT, pNodeE, vVars ) )
587 goto Quits;
588 }
589 else
590 {
591 // get the supergate
592 Abc_NtkCollectSupergate( pNode, fUseMuxes, vSuper );
593 // add the fanin nodes to explore
594 Vec_PtrForEachEntry( Abc_Obj_t *, vSuper, pFanin, k )
595 {
596 pFanin = Abc_ObjRegular(pFanin);
597 if ( pFanin->fMarkA == 0 )
598 {
599 pFanin->fMarkA = 1;
600 pFanin->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)vNodes->nSize;
601 Vec_PtrPush( vNodes, pFanin );
602 }
603 }
604 // add the clauses
605 if ( vSuper->nSize == 0 )
606 {
607 if ( !Abc_NtkClauseTriv( pSat, Abc_ObjNot(pNode), vVars ) )
608// if ( !Abc_NtkClauseTriv( pSat, pNode, vVars ) )
609 goto Quits;
610 }
611 else
612 {
613 if ( !Abc_NtkClauseAnd( pSat, pNode, vSuper, vVars ) )
614 goto Quits;
615 }
616 }
617 }
618/*
619 // set preferred variables
620 if ( fOrderCiVarsFirst )
621 {
622 int * pPrefVars = ABC_ALLOC( int, Abc_NtkCiNum(pNtk) );
623 int nVars = 0;
624 Abc_NtkForEachCi( pNtk, pNode, i )
625 {
626 if ( pNode->fMarkA == 0 )
627 continue;
628 pPrefVars[nVars++] = (int)pNode->pCopy;
629 }
630 nVars = Abc_MinInt( nVars, 10 );
631 ASat_SolverSetPrefVars( pSat, pPrefVars, nVars );
632 }
633*/
634/*
635 Abc_NtkForEachObj( pNtk, pNode, i )
636 {
637 if ( !pNode->fMarkA )
638 continue;
639 printf( "%10s : ", Abc_ObjName(pNode) );
640 printf( "%3d\n", (int)pNode->pCopy );
641 }
642 printf( "\n" );
643*/
644 RetValue = 1;
645Quits :
646 // delete
647 Vec_IntFree( vVars );
648 Vec_PtrFree( vNodes );
649 Vec_PtrFree( vSuper );
650 return RetValue;
651}
652
664void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes )
665{
666 sat_solver * pSat;
667 Abc_Obj_t * pNode;
668 int RetValue, i; //, clk = Abc_Clock();
669
670 assert( Abc_NtkIsStrash(pNtk) || Abc_NtkIsBddLogic(pNtk) );
671 if ( Abc_NtkIsBddLogic(pNtk) )
672 return Abc_NtkMiterSatCreateLogic(pNtk, fAllPrimes);
673
674 nMuxes = 0;
675 pSat = sat_solver_new();
676//sat_solver_store_alloc( pSat );
677 RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk );
679
680 Abc_NtkForEachObj( pNtk, pNode, i )
681 pNode->fMarkA = 0;
682// ASat_SolverWriteDimacs( pSat, "temp_sat.cnf", NULL, NULL, 1 );
683 if ( RetValue == 0 )
684 {
685 sat_solver_delete(pSat);
686 return NULL;
687 }
688// printf( "Ands = %6d. Muxes = %6d (%5.2f %%). ", Abc_NtkNodeNum(pNtk), nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) );
689// ABC_PRT( "Creating sat_solver", Abc_Clock() - clk );
690 return pSat;
691}
692
693
694
695#ifdef ABC_USE_CUDD
696
708int Abc_NodeAddClauses( sat_solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars )
709{
710 Abc_Obj_t * pFanin;
711 int i, c, nFanins;
712 int RetValue = 0;
713 char * pCube;
714
715 nFanins = Abc_ObjFaninNum( pNode );
716 assert( nFanins == Abc_SopGetVarNum( pSop0 ) );
717
718// if ( nFanins == 0 )
719 if ( Cudd_Regular((Abc_Obj_t *)pNode->pData) == Cudd_ReadOne((DdManager *)pNode->pNtk->pManFunc) )
720 {
721 vVars->nSize = 0;
722// if ( Abc_SopIsConst1(pSop1) )
723 if ( !Cudd_IsComplement(pNode->pData) )
724 Vec_IntPush( vVars, toLit(pNode->Id) );
725 else
726 Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
727 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
728 if ( !RetValue )
729 {
730 printf( "The CNF is trivially UNSAT.\n" );
731 return 0;
732 }
733 return 1;
734 }
735
736 // add clauses for the negative phase
737 for ( c = 0; ; c++ )
738 {
739 // get the cube
740 pCube = pSop0 + c * (nFanins + 3);
741 if ( *pCube == 0 )
742 break;
743 // add the clause
744 vVars->nSize = 0;
745 Abc_ObjForEachFanin( pNode, pFanin, i )
746 {
747 if ( pCube[i] == '0' )
748 Vec_IntPush( vVars, toLit(pFanin->Id) );
749 else if ( pCube[i] == '1' )
750 Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
751 }
752 Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
753 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
754 if ( !RetValue )
755 {
756 printf( "The CNF is trivially UNSAT.\n" );
757 return 0;
758 }
759 }
760
761 // add clauses for the positive phase
762 for ( c = 0; ; c++ )
763 {
764 // get the cube
765 pCube = pSop1 + c * (nFanins + 3);
766 if ( *pCube == 0 )
767 break;
768 // add the clause
769 vVars->nSize = 0;
770 Abc_ObjForEachFanin( pNode, pFanin, i )
771 {
772 if ( pCube[i] == '0' )
773 Vec_IntPush( vVars, toLit(pFanin->Id) );
774 else if ( pCube[i] == '1' )
775 Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
776 }
777 Vec_IntPush( vVars, toLit(pNode->Id) );
778 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
779 if ( !RetValue )
780 {
781 printf( "The CNF is trivially UNSAT.\n" );
782 return 0;
783 }
784 }
785 return 1;
786}
787
799int Abc_NodeAddClausesTop( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
800{
801 Abc_Obj_t * pFanin;
802 int RetValue = 0;
803
804 pFanin = Abc_ObjFanin0(pNode);
805 if ( Abc_ObjFaninC0(pNode) )
806 {
807 vVars->nSize = 0;
808 Vec_IntPush( vVars, toLit(pFanin->Id) );
809 Vec_IntPush( vVars, toLit(pNode->Id) );
810 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
811 if ( !RetValue )
812 {
813 printf( "The CNF is trivially UNSAT.\n" );
814 return 0;
815 }
816
817 vVars->nSize = 0;
818 Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
819 Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
820 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
821 if ( !RetValue )
822 {
823 printf( "The CNF is trivially UNSAT.\n" );
824 return 0;
825 }
826 }
827 else
828 {
829 vVars->nSize = 0;
830 Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
831 Vec_IntPush( vVars, toLit(pNode->Id) );
832 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
833 if ( !RetValue )
834 {
835 printf( "The CNF is trivially UNSAT.\n" );
836 return 0;
837 }
838
839 vVars->nSize = 0;
840 Vec_IntPush( vVars, toLit(pFanin->Id) );
841 Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
842 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
843 if ( !RetValue )
844 {
845 printf( "The CNF is trivially UNSAT.\n" );
846 return 0;
847 }
848 }
849
850 vVars->nSize = 0;
851 Vec_IntPush( vVars, toLit(pNode->Id) );
852 RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
853 if ( !RetValue )
854 {
855 printf( "The CNF is trivially UNSAT.\n" );
856 return 0;
857 }
858 return 1;
859}
860
872sat_solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes )
873{
874 sat_solver * pSat;
875 Mem_Flex_t * pMmFlex;
876 Abc_Obj_t * pNode;
877 Vec_Str_t * vCube;
878 Vec_Int_t * vVars;
879 char * pSop0, * pSop1;
880 int i;
881
882 assert( Abc_NtkIsBddLogic(pNtk) );
883
884 // transfer the IDs to the copy field
885 Abc_NtkForEachPi( pNtk, pNode, i )
886 pNode->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)pNode->Id;
887
888 // start the data structures
889 pSat = sat_solver_new();
891 pMmFlex = Mem_FlexStart();
892 vCube = Vec_StrAlloc( 100 );
893 vVars = Vec_IntAlloc( 100 );
894
895 // add clauses for each internal nodes
896 Abc_NtkForEachNode( pNtk, pNode, i )
897 {
898 // derive SOPs for both phases of the node
899 Abc_NodeBddToCnf( pNode, pMmFlex, vCube, fAllPrimes, &pSop0, &pSop1 );
900 // add the clauses to the sat_solver
901 if ( !Abc_NodeAddClauses( pSat, pSop0, pSop1, pNode, vVars ) )
902 {
903 sat_solver_delete( pSat );
904 pSat = NULL;
905 goto finish;
906 }
907 }
908 // add clauses for each PO
909 Abc_NtkForEachPo( pNtk, pNode, i )
910 {
911 if ( !Abc_NodeAddClausesTop( pSat, pNode, vVars ) )
912 {
913 sat_solver_delete( pSat );
914 pSat = NULL;
915 goto finish;
916 }
917 }
919
920finish:
921 // delete
922 Vec_StrFree( vCube );
923 Vec_IntFree( vVars );
924 Mem_FlexStop( pMmFlex, 0 );
925 return pSat;
926}
927
928#else
929
930sat_solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes ) { return NULL; }
931
932#endif
933
945void Abc_NtkWriteSorterCnf( char * pFileName, int nVars, int nQueens )
946{
947 char Command[100];
948 void * pAbc;
949 Abc_Ntk_t * pNtk;
950 Abc_Obj_t * pObj, * ppNodes[2], * ppRoots[2];
951 Vec_Ptr_t * vNodes;
952 FILE * pFile;
953 int i, Counter;
954
955 if ( nQueens <= 0 && nQueens >= nVars )
956 {
957 printf( "The number of queens (Q = %d) should belong to the interval: 0 < Q < %d.\n", nQueens, nQueens);
958 return;
959 }
960 assert( nQueens > 0 && nQueens < nVars );
962 // generate sorter
963 sprintf( Command, "gen -s -N %d sorter%d.blif", nVars, nVars );
964 if ( Cmd_CommandExecute( (Abc_Frame_t *)pAbc, Command ) )
965 {
966 fprintf( stdout, "Cannot execute command \"%s\".\n", Command );
967 return;
968 }
969 // read the file
970 sprintf( Command, "read sorter%d.blif; strash", nVars );
971 if ( Cmd_CommandExecute( (Abc_Frame_t *)pAbc, Command ) )
972 {
973 fprintf( stdout, "Cannot execute command \"%s\".\n", Command );
974 return;
975 }
976
977 // get the current network
978 pNtk = Abc_FrameReadNtk((Abc_Frame_t *)pAbc);
979 // collect the nodes for the given two primary outputs
980 ppNodes[0] = Abc_NtkPo( pNtk, nVars - nQueens - 1 );
981 ppNodes[1] = Abc_NtkPo( pNtk, nVars - nQueens );
982 ppRoots[0] = Abc_ObjFanin0( ppNodes[0] );
983 ppRoots[1] = Abc_ObjFanin0( ppNodes[1] );
984 vNodes = Abc_NtkDfsNodes( pNtk, ppRoots, 2 );
985
986 // assign CNF variables
987 Counter = 0;
988 Abc_NtkForEachObj( pNtk, pObj, i )
989 pObj->pCopy = (Abc_Obj_t *)~0;
990 Abc_NtkForEachPi( pNtk, pObj, i )
991 pObj->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)Counter++;
992 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
993 pObj->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)Counter++;
994
995/*
996 OutVar = pCnf->pVarNums[ pObj->Id ];
997 pVars[0] = pCnf->pVarNums[ Aig_ObjFanin0(pObj)->Id ];
998 pVars[1] = pCnf->pVarNums[ Aig_ObjFanin1(pObj)->Id ];
999
1000 // positive phase
1001 *pClas++ = pLits;
1002 *pLits++ = 2 * OutVar;
1003 *pLits++ = 2 * pVars[0] + !Aig_ObjFaninC0(pObj);
1004 *pLits++ = 2 * pVars[1] + !Aig_ObjFaninC1(pObj);
1005 // negative phase
1006 *pClas++ = pLits;
1007 *pLits++ = 2 * OutVar + 1;
1008 *pLits++ = 2 * pVars[0] + Aig_ObjFaninC0(pObj);
1009 *pClas++ = pLits;
1010 *pLits++ = 2 * OutVar + 1;
1011 *pLits++ = 2 * pVars[1] + Aig_ObjFaninC1(pObj);
1012*/
1013
1014 // add clauses for these nodes
1015 pFile = fopen( pFileName, "w" );
1016 fprintf( pFile, "c CNF for %d-bit sorter with %d bits set to 1 generated by ABC.\n", nVars, nQueens );
1017 fprintf( pFile, "p cnf %d %d\n", Counter, 3 * Vec_PtrSize(vNodes) + 2 );
1018 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
1019 {
1020 // positive phase
1021 fprintf( pFile, "%d %s%d %s%d 0\n", 1+(int)(ABC_PTRINT_T)pObj->pCopy,
1022 Abc_ObjFaninC0(pObj)? "" : "-", 1+(int)(ABC_PTRINT_T)Abc_ObjFanin0(pObj)->pCopy,
1023 Abc_ObjFaninC1(pObj)? "" : "-", 1+(int)(ABC_PTRINT_T)Abc_ObjFanin1(pObj)->pCopy );
1024 // negative phase
1025 fprintf( pFile, "-%d %s%d 0\n", 1+(int)(ABC_PTRINT_T)pObj->pCopy,
1026 Abc_ObjFaninC0(pObj)? "-" : "", 1+(int)(ABC_PTRINT_T)Abc_ObjFanin0(pObj)->pCopy );
1027 fprintf( pFile, "-%d %s%d 0\n", 1+(int)(ABC_PTRINT_T)pObj->pCopy,
1028 Abc_ObjFaninC1(pObj)? "-" : "", 1+(int)(ABC_PTRINT_T)Abc_ObjFanin1(pObj)->pCopy );
1029 }
1030 Vec_PtrFree( vNodes );
1031
1032/*
1033 *pClas++ = pLits;
1034 *pLits++ = 2 * OutVar + Aig_ObjFaninC0(pObj);
1035*/
1036 // assert the first literal to zero
1037 fprintf( pFile, "%s%d 0\n",
1038 Abc_ObjFaninC0(ppNodes[0])? "" : "-", 1+(int)(ABC_PTRINT_T)Abc_ObjFanin0(ppNodes[0])->pCopy );
1039 // assert the second literal to one
1040 fprintf( pFile, "%s%d 0\n",
1041 Abc_ObjFaninC0(ppNodes[1])? "-" : "", 1+(int)(ABC_PTRINT_T)Abc_ObjFanin0(ppNodes[1])->pCopy );
1042 fclose( pFile );
1043}
1044
1045
1049
1050
1052
void * Abc_NtkMiterSatCreate(Abc_Ntk_t *pNtk, int fAllPrimes)
Definition abcSat.c:664
int Abc_NtkClauseTop(sat_solver *pSat, Vec_Ptr_t *vNodes, Vec_Int_t *vVars)
Definition abcSat.c:233
void Abc_NtkWriteSorterCnf(char *pFileName, int nVars, int nQueens)
Definition abcSat.c:945
int Abc_NtkCollectSupergate_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vSuper, int fFirst, int fStopAtMux)
Definition abcSat.c:405
int Abc_NtkClauseAnd(sat_solver *pSat, Abc_Obj_t *pNode, Vec_Ptr_t *vSuper, Vec_Int_t *vVars)
Definition abcSat.c:256
int Abc_NtkNodeFactor(Abc_Obj_t *pObj, int nLevelMax)
Definition abcSat.c:481
int Abc_NtkMiterSatCreateInt(sat_solver *pSat, Abc_Ntk_t *pNtk)
Definition abcSat.c:501
Vec_Int_t * Abc_NtkGetCiSatVarNums(Abc_Ntk_t *pNtk)
Definition abcSat.c:189
void Abc_NtkCollectSupergate(Abc_Obj_t *pNode, int fStopAtMux, Vec_Ptr_t *vNodes)
Definition abcSat.c:452
int Abc_NtkMiterSat(Abc_Ntk_t *pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T *pNumConfs, ABC_INT64_T *pNumInspects)
FUNCTION DEFINITIONS ///.
Definition abcSat.c:58
int Abc_NtkClauseMux(sat_solver *pSat, Abc_Obj_t *pNode, Abc_Obj_t *pNodeC, Abc_Obj_t *pNodeT, Abc_Obj_t *pNodeE, Vec_Int_t *vVars)
Definition abcSat.c:320
int * Abc_NtkSolveGiaMiter(Gia_Man_t *p)
Definition abcSat.c:159
int Abc_NtkClauseTriv(sat_solver *pSat, Abc_Obj_t *pNode, Vec_Int_t *vVars)
Definition abcSat.c:213
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition abc.h:522
#define Abc_NtkForEachPo(pNtk, pPo, i)
Definition abc.h:520
#define Abc_NtkForEachObj(pNtk, pObj, i)
ITERATORS ///.
Definition abc.h:449
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL void Abc_NodeBddToCnf(Abc_Obj_t *pNode, Mem_Flex_t *pMmMan, Vec_Str_t *vCube, int fAllPrimes, char **ppSop0, char **ppSop1)
Definition abcFunc.c:867
#define Abc_NtkForEachPi(pNtk, pPi, i)
Definition abc.h:516
ABC_DLL int Abc_SopGetVarNum(char *pSop)
Definition abcSop.c:584
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition abc.h:518
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition abcNtk.c:1421
ABC_DLL Vec_Ptr_t * Abc_NtkDfsNodes(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition abcDfs.c:151
ABC_DLL int Abc_NodeIsMuxType(Abc_Obj_t *pNode)
Definition abcUtil.c:1342
ABC_DLL Abc_Obj_t * Abc_NodeRecognizeMux(Abc_Obj_t *pNode, Abc_Obj_t **ppNodeT, Abc_Obj_t **ppNodeE)
Definition abcUtil.c:1430
ABC_DLL Abc_Obj_t * Abc_AigConst1(Abc_Ntk_t *pNtk)
Definition abcAig.c:683
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition abc.h:464
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_HEADER_START struct Abc_Frame_t_ Abc_Frame_t
INCLUDES ///.
Definition abcapis.h:38
ABC_DLL Abc_Frame_t * Abc_FrameGetGlobalFrame()
Definition mainFrame.c:643
void Aig_ManStop(Aig_Man_t *p)
Definition aigMan.c:187
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition aig.h:50
ABC_DLL Abc_Ntk_t * Abc_FrameReadNtk(Abc_Frame_t *p)
Definition mainFrame.c:327
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
#define l_True
Definition bmcBmcS.c:35
#define l_Undef
Definition bmcBmcS.c:34
#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
ABC_DLL int Cmd_CommandExecute(Abc_Frame_t *pAbc, const char *sCommand)
Definition cmdApi.c:193
Cube * p
Definition exorList.c:222
int Var
Definition exorList.c:228
char * Extra_UtilStrsav(const char *s)
Aig_Man_t * Gia_ManToAig(Gia_Man_t *p, int fChoices)
Definition giaAig.c:318
ABC_NAMESPACE_IMPL_START Abc_Ntk_t * Abc_NtkFromAigPhase(Aig_Man_t *pMan)
DECLARATIONS ///.
Definition abcDar.c:595
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
Mem_Flex_t * Mem_FlexStart()
Definition mem.c:327
void Mem_FlexStop(Mem_Flex_t *p, int fVerbose)
Definition mem.c:359
struct Mem_Flex_t_ Mem_Flex_t
Definition mem.h:34
sat_solver * sat_solver_new(void)
Definition satSolver.c:1137
int sat_solver_simplify(sat_solver *s)
Definition satSolver.c:1515
void sat_solver_store_free(sat_solver *s)
Definition satSolver.c:2400
void sat_solver_store_write(sat_solver *s, char *pFileName)
Definition satSolver.c:2395
void sat_solver_store_alloc(sat_solver *s)
Definition satSolver.c:2389
void sat_solver_store_mark_roots(sat_solver *s)
Definition satSolver.c:2412
void sat_solver_delete(sat_solver *s)
Definition satSolver.c:1341
int * Sat_SolverGetModel(sat_solver *p, int *pVars, int nVars)
Definition satUtil.c:270
void Sat_SolverPrintStats(FILE *pFile, sat_solver *p)
Definition satUtil.c:193
signed char lbool
Definition satVec.h:135
char * pName
Definition abc.h:158
void * pManFunc
Definition abc.h:191
int * pModel
Definition abc.h:198
void * pData
Definition abc.h:145
Abc_Ntk_t * pNtk
Definition abc.h:130
int Id
Definition abc.h:132
Abc_Obj_t * pCopy
Definition abc.h:148
unsigned fMarkA
Definition abc.h:134
unsigned Level
Definition abc.h:142
stats_t stats
Definition satSolver.h:163
ABC_INT64_T conflicts
Definition satVec.h:156
ABC_INT64_T inspects
Definition satVec.h:156
#define assert(ex)
Definition util_old.h:213
char * sprintf()
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
@ Var1
Definition xsatSolver.h:56