abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
bmcEco.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [bmcEco.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [SAT-based bounded model checking.]
8 
9  Synopsis []
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: bmcEco.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "bmc.h"
22 #include "sat/cnf/cnf.h"
23 #include "sat/bsat/satSolver.h"
24 #include "aig/gia/giaAig.h"
25 
27 
28 
29 ////////////////////////////////////////////////////////////////////////
30 /// DECLARATIONS ///
31 ////////////////////////////////////////////////////////////////////////
32 
33 ////////////////////////////////////////////////////////////////////////
34 /// FUNCTION DEFINITIONS ///
35 ////////////////////////////////////////////////////////////////////////
36 
37 /**Function*************************************************************
38 
39  Synopsis [Computes miter for ECO with given root node and fanins.]
40 
41  Description []
42 
43  SideEffects []
44 
45  SeeAlso []
46 
47 ***********************************************************************/
48 Gia_Man_t * Bmc_EcoMiter( Gia_Man_t * pGold, Gia_Man_t * pOld, Vec_Int_t * vFans )
49 {
50  Gia_Man_t * pNew, * pTemp;
51  Gia_Obj_t * pRoot = Gia_ObjFanin0( Gia_ManPo(pOld, Gia_ManPoNum(pOld)-1) ); // fanin of the last PO
52  Gia_Obj_t * pObj;
53  int i, NewPi, Miter;
54  assert( Gia_ManCiNum(pGold) == Gia_ManCiNum(pOld) );
55  assert( Gia_ManCoNum(pGold) == Gia_ManCoNum(pOld) - 1 );
56  assert( Gia_ObjIsAnd(pRoot) );
57  // create the miter
58  pNew = Gia_ManStart( 3 * Gia_ManObjNum(pGold) );
59  pNew->pName = Abc_UtilStrsav( pGold->pName );
60  Gia_ManHashAlloc( pNew );
61  // copy gold
62  Gia_ManConst0(pGold)->Value = 0;
63  Gia_ManForEachCi( pGold, pObj, i )
64  pObj->Value = Gia_ManAppendCi( pNew );
65  NewPi = Gia_ManAppendCi( pNew );
66  Gia_ManForEachAnd( pGold, pObj, i )
67  pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
68  Gia_ManForEachCo( pGold, pObj, i )
69  pObj->Value = Gia_ObjFanin0Copy( pObj );
70  // create onset
71  Gia_ManConst0(pOld)->Value = 0;
72  Gia_ManForEachCi( pOld, pObj, i )
73  pObj->Value = Gia_ManCi(pGold, i)->Value;
74  Gia_ManForEachAnd( pOld, pObj, i )
75  if ( pObj == pRoot )
76  pObj->Value = NewPi;
77  else
78  pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
79  Gia_ManForEachCo( pOld, pObj, i )
80  pObj->Value = Gia_ObjFanin0Copy( pObj );
81  Gia_ManForEachCo( pGold, pObj, i )
82  Gia_ManAppendCo( pNew, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) );
83  // create offset
84  Gia_ManForEachAnd( pOld, pObj, i )
85  if ( pObj == pRoot )
86  pObj->Value = Abc_LitNot(NewPi);
87  else
88  pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
89  Gia_ManForEachCo( pOld, pObj, i )
90  pObj->Value = Gia_ObjFanin0Copy( pObj );
91  Miter = 0;
92  Gia_ManForEachCo( pGold, pObj, i )
93  Miter = Gia_ManHashOr( pNew, Miter, Gia_ManHashXor(pNew, pObj->Value, Gia_ManCo(pOld, i)->Value) );
94  Gia_ManAppendCo( pNew, Miter );
95  // add outputs for the nodes
96  Gia_ManForEachObjVec( vFans, pOld, pObj, i )
97  Gia_ManAppendCo( pNew, pObj->Value );
98  // cleanup
99  pNew = Gia_ManCleanup( pTemp = pNew );
100  Gia_ManStop( pTemp );
101  assert( Gia_ManPiNum(pNew) == Gia_ManCiNum(pGold) + 1 );
102  assert( Gia_ManPoNum(pNew) == Gia_ManCoNum(pGold) + 1 + Vec_IntSize(vFans) );
103  return pNew;
104 }
105 
106 /**Function*************************************************************
107 
108  Synopsis []
109 
110  Description []
111 
112  SideEffects []
113 
114  SeeAlso []
115 
116 ***********************************************************************/
118 {
119  Cnf_Dat_t * pCnf;
120  Aig_Man_t * pAig = Gia_ManToAigSimple( p );
121  pAig->nRegs = 0;
122  pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
123  Aig_ManStop( pAig );
124  return pCnf;
125 }
126 
127 /**Function*************************************************************
128 
129  Synopsis [Solve the enumeration problem.]
130 
131  Description []
132 
133  SideEffects []
134 
135  SeeAlso []
136 
137 ***********************************************************************/
138 int Bmc_EcoSolve( sat_solver * pSat, int Root, Vec_Int_t * vVars )
139 {
140  int nBTLimit = 1000000;
141  Vec_Int_t * vValues = Vec_IntAlloc( Vec_IntSize(vVars) );
142  Vec_Int_t * vLits = Vec_IntAlloc( Vec_IntSize(vVars) );
143  int status, i, Div, iVar, nFinal, * pFinal, nIter = 0, RetValue = 0;
144  int pLits[2], nVars = sat_solver_nvars( pSat );
145  sat_solver_setnvars( pSat, nVars + 1 );
146  pLits[0] = Abc_Var2Lit( Root, 0 ); // F = 1
147  pLits[1] = Abc_Var2Lit( nVars, 0 ); // iNewLit
148  while ( 1 )
149  {
150  // find onset minterm
151  status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 );
152  if ( status == l_Undef )
153  { RetValue = -1; break; }
154  if ( status == l_False )
155  { RetValue = 1; break; }
156  assert( status == l_True );
157  // remember variable values
158  Vec_IntClear( vValues );
159  Vec_IntForEachEntry( vVars, iVar, i )
160  Vec_IntPush( vValues, sat_solver_var_value(pSat, iVar) );
161  // collect divisor literals
162  Vec_IntClear( vLits );
163  Vec_IntPush( vLits, Abc_LitNot(pLits[0]) ); // F = 0
164  Vec_IntForEachEntry( vVars, Div, i )
165  Vec_IntPush( vLits, sat_solver_var_literal(pSat, Div) );
166  // check against offset
167  status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 );
168  if ( status == l_Undef )
169  { RetValue = -1; break; }
170  if ( status == l_True )
171  break;
172  assert( status == l_False );
173  // compute cube and add clause
174  nFinal = sat_solver_final( pSat, &pFinal );
175  Vec_IntClear( vLits );
176  Vec_IntPush( vLits, Abc_LitNot(pLits[1]) ); // NOT(iNewLit)
177  printf( "Cube %d : ", nIter );
178  for ( i = 0; i < nFinal; i++ )
179  {
180  if ( pFinal[i] == pLits[0] )
181  continue;
182  Vec_IntPush( vLits, pFinal[i] );
183  iVar = Vec_IntFind( vVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 );
184  printf( "%s%d ", Abc_LitIsCompl(pFinal[i]) ? "+":"-", iVar );
185  }
186  printf( "\n" );
187  status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) );
188  assert( status );
189  nIter++;
190  }
191 // assert( status == l_True );
192  Vec_IntFree( vValues );
193  Vec_IntFree( vLits );
194  return RetValue;
195 }
196 
197 /**Function*************************************************************
198 
199  Synopsis [Compute the patch function.]
200 
201  Description []
202 
203  SideEffects []
204 
205  SeeAlso []
206 
207 ***********************************************************************/
208 int Bmc_EcoPatch( Gia_Man_t * p, int nIns, int nOuts )
209 {
210  int i, Lit, RetValue, Root;
211  Gia_Obj_t * pObj;
212  Vec_Int_t * vVars;
213  // generate CNF and solver
214  Cnf_Dat_t * pCnf = Cnf_DeriveGiaRemapped( p );
215  sat_solver * pSat = sat_solver_new();
216  sat_solver_setnvars( pSat, pCnf->nVars );
217  // add timeframe clauses
218  for ( i = 0; i < pCnf->nClauses; i++ )
219  if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
220  assert( 0 );
221  // add equality constraints
222  assert( Gia_ManPoNum(p) == nOuts + 1 + nIns );
223  Gia_ManForEachPo( p, pObj, i )
224  {
225  if ( i == nOuts )
226  break;
227  Lit = Abc_Var2Lit( pCnf->pVarNums[Gia_ObjId(p, pObj)], 1 ); // neg lit
228  RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 );
229  assert( RetValue );
230  }
231  // add inequality constraint
232  pObj = Gia_ManPo( p, nOuts );
233  Lit = Abc_Var2Lit( pCnf->pVarNums[Gia_ObjId(p, pObj)], 0 ); // pos lit
234  RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 );
235  assert( RetValue );
236  // simplify the SAT solver
237  RetValue = sat_solver_simplify( pSat );
238  assert( RetValue );
239  // collect input variables
240  vVars = Vec_IntAlloc( nIns );
241  Gia_ManForEachPo( p, pObj, i )
242  if ( i >= nOuts + 1 )
243  Vec_IntPush( vVars, pCnf->pVarNums[Gia_ObjId(p, pObj)] );
244  assert( Vec_IntSize(vVars) == nIns );
245  // derive the root variable
246  pObj = Gia_ManPi( p, Gia_ManPiNum(p) - 1 );
247  Root = pCnf->pVarNums[Gia_ObjId(p, pObj)];
248  // solve the problem
249  RetValue = Bmc_EcoSolve( pSat, Root, vVars );
250  Vec_IntFree( vVars );
251  return RetValue;
252 }
253 
254 /**Function*************************************************************
255 
256  Synopsis [Tests the ECO miter.]
257 
258  Description []
259 
260  SideEffects []
261 
262  SeeAlso []
263 
264 ***********************************************************************/
266 {
267  char * pFileGold = "eco_gold.aig";
268  char * pFileOld = "eco_old.aig";
269  Vec_Int_t * vFans;
270  FILE * pFile;
271  Gia_Man_t * pMiter;
272  Gia_Obj_t * pObj;
273  Gia_Man_t * pGold;
274  Gia_Man_t * pOld;
275  int i, RetValue;
276  // check that the files exist
277  pFile = fopen( pFileGold, "r" );
278  if ( pFile == NULL )
279  {
280  printf( "File \"%s\" does not exist.\n", pFileGold );
281  return;
282  }
283  fclose( pFile );
284  pFile = fopen( pFileOld, "r" );
285  if ( pFile == NULL )
286  {
287  printf( "File \"%s\" does not exist.\n", pFileOld );
288  return;
289  }
290  fclose( pFile );
291  // read files
292  pGold = Gia_AigerRead( pFileGold, 0, 0 );
293  pOld = Gia_AigerRead( pFileOld, 0, 0 );
294  // create ECO miter
295  vFans = Vec_IntAlloc( Gia_ManCiNum(pOld) );
296  Gia_ManForEachCi( pOld, pObj, i )
297  Vec_IntPush( vFans, Gia_ObjId(pOld, pObj) );
298  pMiter = Bmc_EcoMiter( pGold, pOld, vFans );
299  Vec_IntFree( vFans );
300  Gia_AigerWrite( pMiter, "eco_miter.aig", 0, 0 );
301  // find the patch
302  RetValue = Bmc_EcoPatch( pMiter, Gia_ManCiNum(pGold), Gia_ManCoNum(pGold) );
303  if ( RetValue == 1 )
304  printf( "Patch is computed.\n" );
305  if ( RetValue == 0 )
306  printf( "Cannot be patched.\n" );
307  if ( RetValue == -1 )
308  printf( "Resource limit exceeded.\n" );
309  Gia_ManStop( pMiter );
310 }
311 
312 ////////////////////////////////////////////////////////////////////////
313 /// END OF FILE ///
314 ////////////////////////////////////////////////////////////////////////
315 
316 
318 
static int * Vec_IntArray(Vec_Int_t *p)
Definition: vecInt.h:328
void Gia_ManStop(Gia_Man_t *p)
Definition: giaMan.c:77
Aig_Man_t * Gia_ManToAigSimple(Gia_Man_t *p)
Definition: giaAig.c:367
#define Gia_ManForEachCo(p, pObj, i)
Definition: gia.h:1022
Gia_Man_t * Gia_AigerRead(char *pFileName, int fSkipStrash, int fCheck)
Definition: giaAiger.c:821
static int Gia_ManPoNum(Gia_Man_t *p)
Definition: gia.h:386
Cnf_Dat_t * Cnf_Derive(Aig_Man_t *pAig, int nOutputs)
Definition: cnfCore.c:165
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition: aig.h:50
static Gia_Obj_t * Gia_ManCi(Gia_Man_t *p, int v)
Definition: gia.h:403
static int Gia_ManAppendCo(Gia_Man_t *p, int iLit0)
Definition: gia.h:703
static Llb_Mgr_t * p
Definition: llb3Image.c:950
int sat_solver_addclause(sat_solver *s, lit *begin, lit *end)
Definition: satSolver.c:1492
int Gia_ManHashXor(Gia_Man_t *p, int iLit0, int iLit1)
Definition: giaHash.c:658
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
void Aig_ManStop(Aig_Man_t *p)
Definition: aigMan.c:187
#define l_Undef
Definition: SolverTypes.h:86
int nClauses
Definition: cnf.h:61
static Gia_Obj_t * Gia_ManPo(Gia_Man_t *p, int v)
Definition: gia.h:406
int sat_solver_solve(sat_solver *s, lit *begin, lit *end, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal)
Definition: satSolver.c:1700
static int Gia_ManAppendCi(Gia_Man_t *p)
Definition: gia.h:583
int nVars
Definition: cnf.h:59
static int Abc_Var2Lit(int Var, int fCompl)
Definition: abc_global.h:263
int Bmc_EcoPatch(Gia_Man_t *p, int nIns, int nOuts)
Definition: bmcEco.c:208
int * pVarNums
Definition: cnf.h:63
static int Vec_IntFind(Vec_Int_t *p, int Entry)
Definition: vecInt.h:895
#define l_True
Definition: SolverTypes.h:84
Definition: cnf.h:56
ABC_NAMESPACE_IMPL_START Gia_Man_t * Bmc_EcoMiter(Gia_Man_t *pGold, Gia_Man_t *pOld, Vec_Int_t *vFans)
DECLARATIONS ///.
Definition: bmcEco.c:48
Definition: gia.h:75
static int sat_solver_var_value(sat_solver *s, int v)
Definition: satSolver.h:200
static int sat_solver_final(sat_solver *s, int **ppArray)
Definition: satSolver.h:227
#define Gia_ManForEachCi(p, pObj, i)
Definition: gia.h:1016
static int Aig_ManCoNum(Aig_Man_t *p)
Definition: aig.h:252
static int Abc_LitIsCompl(int Lit)
Definition: abc_global.h:265
static Gia_Obj_t * Gia_ManPi(Gia_Man_t *p, int v)
Definition: gia.h:405
int ** pClauses
Definition: cnf.h:62
static Gia_Obj_t * Gia_ObjFanin0(Gia_Obj_t *pObj)
Definition: gia.h:454
char * pName
Definition: gia.h:97
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
static int Gia_ObjFanin1Copy(Gia_Obj_t *pObj)
Definition: gia.h:482
void sat_solver_setnvars(sat_solver *s, int n)
Definition: satSolver.c:1072
int sat_solver_nvars(sat_solver *s)
Definition: satSolver.c:1896
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
Gia_Man_t * Gia_ManStart(int nObjsMax)
DECLARATIONS ///.
Definition: giaMan.c:52
#define Gia_ManForEachAnd(p, pObj, i)
Definition: gia.h:1002
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
static Cnf_Dat_t * Cnf_DeriveGiaRemapped(Gia_Man_t *p)
Definition: bmcEco.c:117
static int Gia_ObjId(Gia_Man_t *p, Gia_Obj_t *pObj)
Definition: gia.h:410
void Gia_AigerWrite(Gia_Man_t *p, char *pFileName, int fWriteSymbols, int fCompact)
Definition: giaAiger.c:1024
static int Gia_ObjFanin0Copy(Gia_Obj_t *pObj)
Definition: gia.h:481
#define Gia_ManForEachObjVec(vVec, p, pObj, i)
Definition: gia.h:988
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static int Gia_ManCiNum(Gia_Man_t *p)
Definition: gia.h:383
static int Abc_LitNot(int Lit)
Definition: abc_global.h:266
int sat_solver_simplify(sat_solver *s)
Definition: satSolver.c:1276
static Gia_Obj_t * Gia_ManCo(Gia_Man_t *p, int v)
Definition: gia.h:404
sat_solver * sat_solver_new(void)
Definition: satSolver.c:1001
static int Vec_IntSize(Vec_Int_t *p)
Definition: bblif.c:252
static int sat_solver_var_literal(sat_solver *s, int v)
Definition: satSolver.h:205
Definition: gia.h:95
static int Gia_ObjIsAnd(Gia_Obj_t *pObj)
Definition: gia.h:422
static Gia_Obj_t * Gia_ManConst0(Gia_Man_t *p)
Definition: gia.h:400
static int Abc_Lit2Var(int Lit)
Definition: abc_global.h:264
int Bmc_EcoSolve(sat_solver *pSat, int Root, Vec_Int_t *vVars)
Definition: bmcEco.c:138
#define l_False
Definition: SolverTypes.h:85
#define assert(ex)
Definition: util_old.h:213
unsigned Value
Definition: gia.h:87
void Gia_ManHashAlloc(Gia_Man_t *p)
Definition: giaHash.c:99
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
static int Gia_ManPiNum(Gia_Man_t *p)
Definition: gia.h:385
static void Vec_IntClear(Vec_Int_t *p)
Definition: bblif.c:452
Gia_Man_t * Gia_ManCleanup(Gia_Man_t *p)
Definition: giaScl.c:84
char * Abc_UtilStrsav(char *s)
Definition: starter.c:47
#define Gia_ManForEachPo(p, pObj, i)
Definition: gia.h:1036
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition: vecInt.h:54
int Gia_ManHashOr(Gia_Man_t *p, int iLit0, int iLit1)
Definition: giaHash.c:611
int Gia_ManHashAnd(Gia_Man_t *p, int iLit0, int iLit1)
Definition: giaHash.c:572
static int Gia_ManObjNum(Gia_Man_t *p)
Definition: gia.h:388
void Bmc_EcoMiterTest()
Definition: bmcEco.c:265
static int Gia_ManCoNum(Gia_Man_t *p)
Definition: gia.h:384