00001
00021 #include "abc.h"
00022 #include "resInt.h"
00023 #include "hop.h"
00024 #include "satSolver.h"
00025
00029
00030 extern int Res_SatAddConst1( sat_solver * pSat, int iVar, int fCompl );
00031 extern int Res_SatAddEqual( sat_solver * pSat, int iVar0, int iVar1, int fCompl );
00032 extern int Res_SatAddAnd( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 );
00033
00037
00049 void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins )
00050 {
00051 void * pCnf = NULL;
00052 sat_solver * pSat;
00053 Vec_Ptr_t * vNodes;
00054 Abc_Obj_t * pObj;
00055 int i, nNodes, status;
00056
00057
00058 pObj = Vec_PtrEntry( vFanins, 0 );
00059 assert( pObj->pNtk == pAig && Abc_ObjIsPo(pObj) );
00060
00061
00062 vNodes = Abc_NtkDfsNodes( pAig, (Abc_Obj_t **)vFanins->pArray, vFanins->nSize );
00063
00064
00065 nNodes = 0;
00066 Abc_AigConst1(pAig)->pCopy = (void *)nNodes++;
00067 Abc_NtkForEachPi( pAig, pObj, i )
00068 pObj->pCopy = (void *)nNodes++;
00069 Vec_PtrForEachEntry( vNodes, pObj, i )
00070 pObj->pCopy = (void *)nNodes++;
00071 Vec_PtrForEachEntry( vFanins, pObj, i )
00072 pObj->pCopy = (void *)nNodes++;
00073
00074
00075 pSat = sat_solver_new();
00076 sat_solver_store_alloc( pSat );
00077
00078
00079 Res_SatAddConst1( pSat, (int)Abc_AigConst1(pAig)->pCopy, 0 );
00080
00081 Vec_PtrForEachEntry( vNodes, pObj, i )
00082 Res_SatAddAnd( pSat, (int)pObj->pCopy,
00083 (int)Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
00084 Vec_PtrFree( vNodes );
00085
00086 Vec_PtrForEachEntry( vFanins, pObj, i )
00087 Res_SatAddEqual( pSat, (int)pObj->pCopy,
00088 (int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) );
00089
00090 pObj = Vec_PtrEntry(vFanins, 0);
00091 Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 );
00092 pObj = Vec_PtrEntry(vFanins, 1);
00093 Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 );
00094
00095
00096 sat_solver_store_mark_clauses_a( pSat );
00097
00098
00099 pObj = Vec_PtrEntry(vFanins, 1);
00100 Sat_SolverDoubleClauses( pSat, (int)pObj->pCopy );
00101
00102 Vec_PtrForEachEntryStart( vFanins, pObj, i, 2 )
00103 Res_SatAddEqual( pSat, (int)pObj->pCopy, ((int)pObj->pCopy) + nNodes, 0 );
00104
00105
00106 sat_solver_store_mark_roots( pSat );
00107
00108
00109 status = sat_solver_solve( pSat, NULL, NULL, (sint64)10000, (sint64)0, (sint64)0, (sint64)0 );
00110 if ( status == l_False )
00111 {
00112 pCnf = sat_solver_store_release( pSat );
00113
00114 }
00115 else if ( status == l_True )
00116 {
00117
00118 }
00119 else
00120 {
00121
00122 }
00123 sat_solver_delete( pSat );
00124 return pCnf;
00125 }
00126
00138 void * Res_SatSimulateConstr( Abc_Ntk_t * pAig, int fOnSet )
00139 {
00140 sat_solver * pSat;
00141 Vec_Ptr_t * vFanins;
00142 Vec_Ptr_t * vNodes;
00143 Abc_Obj_t * pObj;
00144 int i, nNodes;
00145
00146
00147 vFanins = Vec_PtrAlloc( 2 );
00148 pObj = Abc_NtkPo( pAig, 0 );
00149 Vec_PtrPush( vFanins, pObj );
00150 pObj = Abc_NtkPo( pAig, 1 );
00151 Vec_PtrPush( vFanins, pObj );
00152
00153
00154 vNodes = Abc_NtkDfsNodes( pAig, (Abc_Obj_t **)vFanins->pArray, vFanins->nSize );
00155
00156
00157 nNodes = 0;
00158 Abc_AigConst1(pAig)->pCopy = (void *)nNodes++;
00159 Abc_NtkForEachPi( pAig, pObj, i )
00160 pObj->pCopy = (void *)nNodes++;
00161 Vec_PtrForEachEntry( vNodes, pObj, i )
00162 pObj->pCopy = (void *)nNodes++;
00163 Vec_PtrForEachEntry( vFanins, pObj, i )
00164 pObj->pCopy = (void *)nNodes++;
00165
00166
00167 pSat = sat_solver_new();
00168
00169
00170 Res_SatAddConst1( pSat, (int)Abc_AigConst1(pAig)->pCopy, 0 );
00171
00172 Vec_PtrForEachEntry( vNodes, pObj, i )
00173 Res_SatAddAnd( pSat, (int)pObj->pCopy,
00174 (int)Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
00175 Vec_PtrFree( vNodes );
00176
00177 pObj = Abc_NtkPo( pAig, 0 );
00178 Res_SatAddEqual( pSat, (int)pObj->pCopy,
00179 (int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) );
00180
00181 pObj = Abc_NtkPo( pAig, 1 );
00182 Res_SatAddEqual( pSat, (int)pObj->pCopy,
00183 (int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) );
00184
00185
00186 pObj = Abc_NtkPo( pAig, 0 );
00187 Res_SatAddConst1( pSat, (int)pObj->pCopy, 0 );
00188
00189 pObj = Abc_NtkPo( pAig, 1 );
00190 Res_SatAddConst1( pSat, (int)pObj->pCopy, !fOnSet );
00191
00192 Vec_PtrFree( vFanins );
00193 return pSat;
00194 }
00195
00209 int Res_SatSimulate( Res_Sim_t * p, int nPatsLimit, int fOnSet )
00210 {
00211 Vec_Int_t * vLits;
00212 Vec_Ptr_t * vPats;
00213 sat_solver * pSat;
00214 int RetValue, i, k, value, status, Lit, Var, iPat;
00215 int clk = clock();
00216
00217
00218
00219
00220 Lit = toLitCond( (int)Abc_NtkPo(p->pAig,1)->pCopy, !fOnSet );
00221 if ( fOnSet )
00222 {
00223 iPat = p->nPats1;
00224 vPats = p->vPats1;
00225 }
00226 else
00227 {
00228 iPat = p->nPats0;
00229 vPats = p->vPats0;
00230 }
00231 assert( iPat < nPatsLimit );
00232
00233
00234 pSat = Res_SatSimulateConstr( p->pAig, fOnSet );
00235 pSat->fSkipSimplify = 1;
00236 status = sat_solver_simplify( pSat );
00237 if ( status == 0 )
00238 {
00239 if ( iPat == 0 )
00240 {
00241
00242
00243
00244
00245 RetValue = 0;
00246 }
00247 goto finish;
00248 }
00249
00250
00251 RetValue = 1;
00252 vLits = Vec_IntAlloc( 32 );
00253 for ( k = iPat; k < nPatsLimit; k++ )
00254 {
00255
00256
00257 status = sat_solver_solve( pSat, NULL, NULL, (sint64)10000, (sint64)0, (sint64)0, (sint64)0 );
00258 if ( status == l_False )
00259 {
00260
00261 if ( k == 0 )
00262 {
00263 if ( fOnSet )
00264 p->fConst0 = 1;
00265 else
00266 p->fConst1 = 1;
00267 RetValue = 0;
00268 }
00269 break;
00270 }
00271 else if ( status == l_True )
00272 {
00273
00274 Vec_IntClear( vLits );
00275 for ( i = 0; i < p->nTruePis; i++ )
00276 {
00277 Var = (int)Abc_NtkPi(p->pAig,i)->pCopy;
00278 value = (int)(pSat->model.ptr[Var] == l_True);
00279 if ( value )
00280 Abc_InfoSetBit( Vec_PtrEntry(vPats, i), k );
00281 Lit = toLitCond( Var, value );
00282 Vec_IntPush( vLits, Lit );
00283
00284 }
00285
00286
00287 status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) );
00288 if ( status == 0 )
00289 {
00290 k++;
00291 RetValue = 1;
00292 break;
00293 }
00294 }
00295 else
00296 {
00297
00298 if ( k == 0 )
00299 RetValue = 0;
00300 else
00301 RetValue = 1;
00302 break;
00303 }
00304 }
00305 Vec_IntFree( vLits );
00306
00307
00308
00309 if ( fOnSet )
00310 p->nPats1 = k;
00311 else
00312 p->nPats0 = k;
00313
00314 finish:
00315
00316 sat_solver_delete( pSat );
00317 p->timeSat += clock() - clk;
00318 return RetValue;
00319 }
00320
00321
00333 int Res_SatAddConst1( sat_solver * pSat, int iVar, int fCompl )
00334 {
00335 lit Lit = toLitCond( iVar, fCompl );
00336 if ( !sat_solver_addclause( pSat, &Lit, &Lit + 1 ) )
00337 return 0;
00338 return 1;
00339 }
00340
00352 int Res_SatAddEqual( sat_solver * pSat, int iVar0, int iVar1, int fCompl )
00353 {
00354 lit Lits[2];
00355
00356 Lits[0] = toLitCond( iVar0, 0 );
00357 Lits[1] = toLitCond( iVar1, !fCompl );
00358 if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
00359 return 0;
00360
00361 Lits[0] = toLitCond( iVar0, 1 );
00362 Lits[1] = toLitCond( iVar1, fCompl );
00363 if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
00364 return 0;
00365
00366 return 1;
00367 }
00368
00380 int Res_SatAddAnd( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 )
00381 {
00382 lit Lits[3];
00383
00384 Lits[0] = toLitCond( iVar, 1 );
00385 Lits[1] = toLitCond( iVar0, fCompl0 );
00386 if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
00387 return 0;
00388
00389 Lits[0] = toLitCond( iVar, 1 );
00390 Lits[1] = toLitCond( iVar1, fCompl1 );
00391 if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
00392 return 0;
00393
00394 Lits[0] = toLitCond( iVar, 0 );
00395 Lits[1] = toLitCond( iVar0, !fCompl0 );
00396 Lits[2] = toLitCond( iVar1, !fCompl1 );
00397 if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) )
00398 return 0;
00399
00400 return 1;
00401 }
00402
00406
00407