/**CFile**************************************************************** FileName [fraClau.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [New FRAIG package.] Synopsis [Induction with clause strengthening.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 30, 2007.] Revision [$Id: fraClau.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $] ***********************************************************************/ #include "fra.h" #include "sat/cnf/cnf.h" #include "sat/bsat/satSolver.h" ABC_NAMESPACE_IMPL_START /* This code is inspired by the paper: Aaron Bradley and Zohar Manna, "Checking safety by inductive generalization of counterexamples to induction", FMCAD '07. */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// typedef struct Cla_Man_t_ Cla_Man_t; struct Cla_Man_t_ { // SAT solvers sat_solver * pSatMain; sat_solver * pSatTest; sat_solver * pSatBmc; // CNF for the test solver // Cnf_Dat_t * pCnfTest; // SAT variables Vec_Int_t * vSatVarsMainCs; Vec_Int_t * vSatVarsTestCs; Vec_Int_t * vSatVarsTestNs; Vec_Int_t * vSatVarsBmcNs; // helper variables int nSatVarsTestBeg; int nSatVarsTestCur; // counter-examples Vec_Int_t * vCexMain0; Vec_Int_t * vCexMain; Vec_Int_t * vCexTest; Vec_Int_t * vCexBase; Vec_Int_t * vCexAssm; Vec_Int_t * vCexBmc; // mapping of CS into NS var numbers int * pMapCsMainToCsTest; int * pMapCsTestToCsMain; int * pMapCsTestToNsTest; int * pMapCsTestToNsBmc; }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Saves variables corresponding to latch outputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Fra_ClauSaveLatchVars( Aig_Man_t * pMan, Cnf_Dat_t * pCnf, int fCsVars ) { Vec_Int_t * vVars; Aig_Obj_t * pObjLo, * pObjLi; int i; vVars = Vec_IntAlloc( Aig_ManRegNum(pMan) ); Aig_ManForEachLiLoSeq( pMan, pObjLi, pObjLo, i ) Vec_IntPush( vVars, pCnf->pVarNums[fCsVars? pObjLo->Id : pObjLi->Id] ); return vVars; } /**Function************************************************************* Synopsis [Saves variables corresponding to latch outputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Fra_ClauSaveOutputVars( Aig_Man_t * pMan, Cnf_Dat_t * pCnf ) { Vec_Int_t * vVars; Aig_Obj_t * pObj; int i; vVars = Vec_IntAlloc( Aig_ManCoNum(pMan) ); Aig_ManForEachCo( pMan, pObj, i ) Vec_IntPush( vVars, pCnf->pVarNums[pObj->Id] ); return vVars; } /**Function************************************************************* Synopsis [Saves variables corresponding to latch outputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Fra_ClauSaveInputVars( Aig_Man_t * pMan, Cnf_Dat_t * pCnf, int nStarting ) { Vec_Int_t * vVars; Aig_Obj_t * pObj; int i; vVars = Vec_IntAlloc( Aig_ManCiNum(pMan) - nStarting ); Aig_ManForEachCi( pMan, pObj, i ) { if ( i < nStarting ) continue; Vec_IntPush( vVars, pCnf->pVarNums[pObj->Id] ); } return vVars; } /**Function************************************************************* Synopsis [Saves variables corresponding to latch outputs.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int * Fra_ClauCreateMapping( Vec_Int_t * vSatVarsFrom, Vec_Int_t * vSatVarsTo, int nVarsMax ) { int * pMapping, Var, i; assert( Vec_IntSize(vSatVarsFrom) == Vec_IntSize(vSatVarsTo) ); pMapping = ABC_ALLOC( int, nVarsMax ); for ( i = 0; i < nVarsMax; i++ ) pMapping[i] = -1; Vec_IntForEachEntry( vSatVarsFrom, Var, i ) pMapping[Var] = Vec_IntEntry(vSatVarsTo,i); return pMapping; } /**Function************************************************************* Synopsis [Deletes the manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_ClauStop( Cla_Man_t * p ) { ABC_FREE( p->pMapCsMainToCsTest ); ABC_FREE( p->pMapCsTestToCsMain ); ABC_FREE( p->pMapCsTestToNsTest ); ABC_FREE( p->pMapCsTestToNsBmc ); Vec_IntFree( p->vSatVarsMainCs ); Vec_IntFree( p->vSatVarsTestCs ); Vec_IntFree( p->vSatVarsTestNs ); Vec_IntFree( p->vSatVarsBmcNs ); Vec_IntFree( p->vCexMain0 ); Vec_IntFree( p->vCexMain ); Vec_IntFree( p->vCexTest ); Vec_IntFree( p->vCexBase ); Vec_IntFree( p->vCexAssm ); Vec_IntFree( p->vCexBmc ); if ( p->pSatMain ) sat_solver_delete( p->pSatMain ); if ( p->pSatTest ) sat_solver_delete( p->pSatTest ); if ( p->pSatBmc ) sat_solver_delete( p->pSatBmc ); ABC_FREE( p ); } /**Function************************************************************* Synopsis [Takes the AIG with the single output to be checked.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Cla_Man_t * Fra_ClauStart( Aig_Man_t * pMan ) { Cla_Man_t * p; Cnf_Dat_t * pCnfMain; Cnf_Dat_t * pCnfTest; Cnf_Dat_t * pCnfBmc; Aig_Man_t * pFramesMain; Aig_Man_t * pFramesTest; Aig_Man_t * pFramesBmc; assert( Aig_ManCoNum(pMan) - Aig_ManRegNum(pMan) == 1 ); // start the manager p = ABC_ALLOC( Cla_Man_t, 1 ); memset( p, 0, sizeof(Cla_Man_t) ); p->vCexMain0 = Vec_IntAlloc( Aig_ManRegNum(pMan) ); p->vCexMain = Vec_IntAlloc( Aig_ManRegNum(pMan) ); p->vCexTest = Vec_IntAlloc( Aig_ManRegNum(pMan) ); p->vCexBase = Vec_IntAlloc( Aig_ManRegNum(pMan) ); p->vCexAssm = Vec_IntAlloc( Aig_ManRegNum(pMan) ); p->vCexBmc = Vec_IntAlloc( Aig_ManRegNum(pMan) ); // derive two timeframes to be checked pFramesMain = Aig_ManFrames( pMan, 2, 0, 1, 0, 0, NULL ); // nFrames, fInit, fOuts, fRegs //Aig_ManShow( pFramesMain, 0, NULL ); assert( Aig_ManCoNum(pFramesMain) == 2 ); Aig_ObjChild0Flip( Aig_ManCo(pFramesMain, 0) ); // complement the first output pCnfMain = Cnf_DeriveSimple( pFramesMain, 0 ); //Cnf_DataWriteIntoFile( pCnfMain, "temp.cnf", 1 ); p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( pCnfMain, 1, 0 ); /* { int i; Aig_Obj_t * pObj; Aig_ManForEachObj( pFramesMain, pObj, i ) printf( "%d -> %d \n", pObj->Id, pCnfMain->pVarNums[pObj->Id] ); printf( "\n" ); } */ // derive one timeframe to be checked pFramesTest = Aig_ManFrames( pMan, 1, 0, 0, 1, 0, NULL ); assert( Aig_ManCoNum(pFramesTest) == Aig_ManRegNum(pMan) ); pCnfTest = Cnf_DeriveSimple( pFramesTest, Aig_ManRegNum(pMan) ); p->pSatTest = (sat_solver *)Cnf_DataWriteIntoSolver( pCnfTest, 1, 0 ); p->nSatVarsTestBeg = p->nSatVarsTestCur = sat_solver_nvars( p->pSatTest ); // derive one timeframe to be checked for BMC pFramesBmc = Aig_ManFrames( pMan, 1, 1, 0, 1, 0, NULL ); //Aig_ManShow( pFramesBmc, 0, NULL ); assert( Aig_ManCoNum(pFramesBmc) == Aig_ManRegNum(pMan) ); pCnfBmc = Cnf_DeriveSimple( pFramesBmc, Aig_ManRegNum(pMan) ); p->pSatBmc = (sat_solver *)Cnf_DataWriteIntoSolver( pCnfBmc, 1, 0 ); // create variable sets p->vSatVarsMainCs = Fra_ClauSaveInputVars( pFramesMain, pCnfMain, 2 * (Aig_ManCiNum(pMan)-Aig_ManRegNum(pMan)) ); p->vSatVarsTestCs = Fra_ClauSaveLatchVars( pFramesTest, pCnfTest, 1 ); p->vSatVarsTestNs = Fra_ClauSaveLatchVars( pFramesTest, pCnfTest, 0 ); p->vSatVarsBmcNs = Fra_ClauSaveOutputVars( pFramesBmc, pCnfBmc ); assert( Vec_IntSize(p->vSatVarsTestCs) == Vec_IntSize(p->vSatVarsMainCs) ); assert( Vec_IntSize(p->vSatVarsTestCs) == Vec_IntSize(p->vSatVarsBmcNs) ); // create mapping of CS into NS vars p->pMapCsMainToCsTest = Fra_ClauCreateMapping( p->vSatVarsMainCs, p->vSatVarsTestCs, Aig_ManObjNumMax(pFramesMain) ); p->pMapCsTestToCsMain = Fra_ClauCreateMapping( p->vSatVarsTestCs, p->vSatVarsMainCs, Aig_ManObjNumMax(pFramesTest) ); p->pMapCsTestToNsTest = Fra_ClauCreateMapping( p->vSatVarsTestCs, p->vSatVarsTestNs, Aig_ManObjNumMax(pFramesTest) ); p->pMapCsTestToNsBmc = Fra_ClauCreateMapping( p->vSatVarsTestCs, p->vSatVarsBmcNs, Aig_ManObjNumMax(pFramesTest) ); // cleanup Cnf_DataFree( pCnfMain ); Cnf_DataFree( pCnfTest ); Cnf_DataFree( pCnfBmc ); Aig_ManStop( pFramesMain ); Aig_ManStop( pFramesTest ); Aig_ManStop( pFramesBmc ); if ( p->pSatMain == NULL || p->pSatTest == NULL || p->pSatBmc == NULL ) { Fra_ClauStop( p ); return NULL; } return p; } /**Function************************************************************* Synopsis [Splits off second half and returns it as a new vector.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static Vec_Int_t * Vec_IntSplitHalf( Vec_Int_t * vVec ) { Vec_Int_t * vPart; int Entry, i; assert( Vec_IntSize(vVec) > 1 ); vPart = Vec_IntAlloc( Vec_IntSize(vVec) / 2 + 1 ); Vec_IntForEachEntryStart( vVec, Entry, i, Vec_IntSize(vVec) / 2 ) Vec_IntPush( vPart, Entry ); Vec_IntShrink( vVec, Vec_IntSize(vVec) / 2 ); return vPart; } /**Function************************************************************* Synopsis [Complements all literals in the clause.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Vec_IntComplement( Vec_Int_t * vVec ) { int i; for ( i = 0; i < Vec_IntSize(vVec); i++ ) vVec->pArray[i] = lit_neg( vVec->pArray[i] ); } /**Function************************************************************* Synopsis [Checks if the property holds. Returns counter-example if not.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_ClauCheckProperty( Cla_Man_t * p, Vec_Int_t * vCex ) { int nBTLimit = 0; int RetValue, iVar, i; sat_solver_act_var_clear( p->pSatMain ); RetValue = sat_solver_solve( p->pSatMain, NULL, NULL, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); Vec_IntClear( vCex ); if ( RetValue == l_False ) return 1; assert( RetValue == l_True ); Vec_IntForEachEntry( p->vSatVarsMainCs, iVar, i ) Vec_IntPush( vCex, sat_solver_var_literal(p->pSatMain, iVar) ); /* { int i; for (i = 0; i < p->pSatMain->size; i++) printf( "%d=%d ", i, p->pSatMain->model.ptr[i] == l_True ); printf( "\n" ); } */ return 0; } /**Function************************************************************* Synopsis [Checks if the clause holds using BMC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_ClauCheckBmc( Cla_Man_t * p, Vec_Int_t * vClause ) { int nBTLimit = 0; int RetValue; RetValue = sat_solver_solve( p->pSatBmc, Vec_IntArray(vClause), Vec_IntArray(vClause) + Vec_IntSize(vClause), (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); if ( RetValue == l_False ) return 1; assert( RetValue == l_True ); return 0; } /**Function************************************************************* Synopsis [Lifts the clause to depend on NS variables.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_ClauRemapClause( int * pMap, Vec_Int_t * vClause, Vec_Int_t * vRemapped, int fInv ) { int iLit, i; Vec_IntClear( vRemapped ); Vec_IntForEachEntry( vClause, iLit, i ) { assert( pMap[lit_var(iLit)] >= 0 ); iLit = toLitCond( pMap[lit_var(iLit)], lit_sign(iLit) ^ fInv ); Vec_IntPush( vRemapped, iLit ); } } /**Function************************************************************* Synopsis [Checks if the clause holds. Returns counter example if not.] Description [Uses test SAT solver.] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_ClauCheckClause( Cla_Man_t * p, Vec_Int_t * vClause, Vec_Int_t * vCex ) { int nBTLimit = 0; int RetValue, iVar, i; // complement literals Vec_IntPush( vClause, toLit( p->nSatVarsTestCur++ ) ); // helper positive Vec_IntComplement( vClause ); // helper negative (the clause is C v h') // add the clause RetValue = sat_solver_addclause( p->pSatTest, Vec_IntArray(vClause), Vec_IntArray(vClause) + Vec_IntSize(vClause) ); assert( RetValue == 1 ); // complement all literals Vec_IntPop( vClause ); // helper removed Vec_IntComplement( vClause ); // create the assumption in terms of NS variables Fra_ClauRemapClause( p->pMapCsTestToNsTest, vClause, p->vCexAssm, 0 ); // add helper literals for ( i = p->nSatVarsTestBeg; i < p->nSatVarsTestCur - 1; i++ ) Vec_IntPush( p->vCexAssm, toLitCond(i,1) ); // other helpers negative Vec_IntPush( p->vCexAssm, toLitCond(i,0) ); // positive helper // try to solve RetValue = sat_solver_solve( p->pSatTest, Vec_IntArray(p->vCexAssm), Vec_IntArray(p->vCexAssm) + Vec_IntSize(p->vCexAssm), (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); if ( vCex ) Vec_IntClear( vCex ); if ( RetValue == l_False ) return 1; assert( RetValue == l_True ); if ( vCex ) { Vec_IntForEachEntry( p->vSatVarsTestCs, iVar, i ) Vec_IntPush( vCex, sat_solver_var_literal(p->pSatTest, iVar) ); } return 0; } /**Function************************************************************* Synopsis [Reduces the counter-example by removing complemented literals.] Description [Removes literals from vMain that differ from those in the counter-example (vNew). Relies on the fact that the PI variables are assigned in the increasing order.] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_ClauReduceClause( Vec_Int_t * vMain, Vec_Int_t * vNew ) { int LitM, LitN, VarM, VarN, i, j, k; assert( Vec_IntSize(vMain) <= Vec_IntSize(vNew) ); for ( i = j = k = 0; i < Vec_IntSize(vMain) && j < Vec_IntSize(vNew); ) { LitM = Vec_IntEntry( vMain, i ); LitN = Vec_IntEntry( vNew, j ); VarM = lit_var( LitM ); VarN = lit_var( LitN ); if ( VarM < VarN ) { assert( 0 ); } else if ( VarM > VarN ) { j++; } else // if ( VarM == VarN ) { i++; j++; if ( LitM == LitN ) Vec_IntWriteEntry( vMain, k++, LitM ); } } assert( i == Vec_IntSize(vMain) ); Vec_IntShrink( vMain, k ); } /**Function************************************************************* Synopsis [Computes the minimal invariant that holds.] Description [On entrace, vBasis does not hold, vBasis+vExtra holds but is not minimal. On exit, vBasis is unchanged, vBasis+vExtra is minimal.] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_ClauMinimizeClause_rec( Cla_Man_t * p, Vec_Int_t * vBasis, Vec_Int_t * vExtra ) { Vec_Int_t * vExtra2; int nSizeOld; if ( Vec_IntSize(vExtra) == 1 ) return; nSizeOld = Vec_IntSize( vBasis ); vExtra2 = Vec_IntSplitHalf( vExtra ); // try the first half Vec_IntAppend( vBasis, vExtra ); if ( Fra_ClauCheckClause( p, vBasis, NULL ) ) { Vec_IntShrink( vBasis, nSizeOld ); Fra_ClauMinimizeClause_rec( p, vBasis, vExtra ); return; } Vec_IntShrink( vBasis, nSizeOld ); // try the second half Vec_IntAppend( vBasis, vExtra2 ); if ( Fra_ClauCheckClause( p, vBasis, NULL ) ) { Vec_IntShrink( vBasis, nSizeOld ); Fra_ClauMinimizeClause_rec( p, vBasis, vExtra2 ); return; } // Vec_IntShrink( vBasis, nSizeOld ); // find the smallest with the second half added Fra_ClauMinimizeClause_rec( p, vBasis, vExtra ); Vec_IntShrink( vBasis, nSizeOld ); Vec_IntAppend( vBasis, vExtra ); // find the smallest with the second half added Fra_ClauMinimizeClause_rec( p, vBasis, vExtra2 ); Vec_IntShrink( vBasis, nSizeOld ); Vec_IntAppend( vExtra, vExtra2 ); Vec_IntFree( vExtra2 ); } /**Function************************************************************* Synopsis [Minimizes the clauses using a simple method.] Description [The input and output clause are in vExtra.] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_ClauMinimizeClause( Cla_Man_t * p, Vec_Int_t * vBasis, Vec_Int_t * vExtra ) { int iLit, iLit2, i, k; Vec_IntForEachEntryReverse( vExtra, iLit, i ) { // copy literals without the given one Vec_IntClear( vBasis ); Vec_IntForEachEntry( vExtra, iLit2, k ) if ( k != i ) Vec_IntPush( vBasis, iLit2 ); // try whether it is inductive if ( !Fra_ClauCheckClause( p, vBasis, NULL ) ) continue; // the clause is inductive // remove the literal for ( k = i; k < Vec_IntSize(vExtra)-1; k++ ) Vec_IntWriteEntry( vExtra, k, Vec_IntEntry(vExtra,k+1) ); Vec_IntShrink( vExtra, Vec_IntSize(vExtra)-1 ); } } /**Function************************************************************* Synopsis [Prints the clause.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fra_ClauPrintClause( Vec_Int_t * vSatCsVars, Vec_Int_t * vCex ) { int LitM, VarM, VarN, i, j, k; assert( Vec_IntSize(vCex) <= Vec_IntSize(vSatCsVars) ); for ( i = j = k = 0; i < Vec_IntSize(vCex) && j < Vec_IntSize(vSatCsVars); ) { LitM = Vec_IntEntry( vCex, i ); VarM = lit_var( LitM ); VarN = Vec_IntEntry( vSatCsVars, j ); if ( VarM < VarN ) { assert( 0 ); } else if ( VarM > VarN ) { j++; printf( "-" ); } else // if ( VarM == VarN ) { i++; j++; printf( "%d", !lit_sign(LitM) ); } } assert( i == Vec_IntSize(vCex) ); } /**Function************************************************************* Synopsis [Takes the AIG with the single output to be checked.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_Clau( Aig_Man_t * pMan, int nIters, int fVerbose, int fVeryVerbose ) { Cla_Man_t * p; int Iter, RetValue, fFailed, i; assert( Aig_ManCoNum(pMan) - Aig_ManRegNum(pMan) == 1 ); // create the manager p = Fra_ClauStart( pMan ); if ( p == NULL ) { printf( "The property is trivially inductive.\n" ); return 1; } // generate counter-examples and expand them for ( Iter = 0; !Fra_ClauCheckProperty( p, p->vCexMain0 ) && Iter < nIters; Iter++ ) { if ( fVerbose ) printf( "%4d : ", Iter ); // remap clause into the test manager Fra_ClauRemapClause( p->pMapCsMainToCsTest, p->vCexMain0, p->vCexMain, 0 ); if ( fVerbose && fVeryVerbose ) Fra_ClauPrintClause( p->vSatVarsTestCs, p->vCexMain ); // the main counter-example is in p->vCexMain // intermediate counter-examples are in p->vCexTest // generate the reduced counter-example to the inductive property fFailed = 0; for ( i = 0; !Fra_ClauCheckClause( p, p->vCexMain, p->vCexTest ); i++ ) { Fra_ClauReduceClause( p->vCexMain, p->vCexTest ); Fra_ClauRemapClause( p->pMapCsTestToNsBmc, p->vCexMain, p->vCexBmc, 0 ); // if ( !Fra_ClauCheckBmc(p, p->vCexBmc) ) if ( Vec_IntSize(p->vCexMain) < 1 ) { Vec_IntComplement( p->vCexMain0 ); RetValue = sat_solver_addclause( p->pSatMain, Vec_IntArray(p->vCexMain0), Vec_IntArray(p->vCexMain0) + Vec_IntSize(p->vCexMain0) ); if ( RetValue == 0 ) { printf( "\nProperty is proved after %d iterations.\n", Iter+1 ); return 0; } fFailed = 1; break; } } if ( fFailed ) { if ( fVerbose ) printf( " Reducing failed after %d iterations (BMC failed).\n", i ); continue; } if ( Vec_IntSize(p->vCexMain) == 0 ) { if ( fVerbose ) printf( " Reducing failed after %d iterations (nothing left).\n", i ); continue; } if ( fVerbose ) printf( " " ); if ( fVerbose && fVeryVerbose ) Fra_ClauPrintClause( p->vSatVarsTestCs, p->vCexMain ); if ( fVerbose ) printf( " LitsInd = %3d. ", Vec_IntSize(p->vCexMain) ); // minimize the inductive property Vec_IntClear( p->vCexBase ); if ( Vec_IntSize(p->vCexMain) > 1 ) // Fra_ClauMinimizeClause_rec( p, p->vCexBase, p->vCexMain ); Fra_ClauMinimizeClause( p, p->vCexBase, p->vCexMain ); assert( Vec_IntSize(p->vCexMain) > 0 ); if ( fVerbose && fVeryVerbose ) Fra_ClauPrintClause( p->vSatVarsTestCs, p->vCexMain ); if ( fVerbose ) printf( " LitsRed = %3d. ", Vec_IntSize(p->vCexMain) ); if ( fVerbose ) printf( "\n" ); // add the clause to the solver Fra_ClauRemapClause( p->pMapCsTestToCsMain, p->vCexMain, p->vCexAssm, 1 ); RetValue = sat_solver_addclause( p->pSatMain, Vec_IntArray(p->vCexAssm), Vec_IntArray(p->vCexAssm) + Vec_IntSize(p->vCexAssm) ); if ( RetValue == 0 ) { Iter++; break; } if ( p->pSatMain->qtail != p->pSatMain->qhead ) { RetValue = sat_solver_simplify(p->pSatMain); assert( RetValue != 0 ); assert( p->pSatMain->qtail == p->pSatMain->qhead ); } } // report the results if ( Iter == nIters ) { printf( "Property is not proved after %d iterations.\n", nIters ); return 0; } printf( "Property is proved after %d iterations.\n", Iter ); Fra_ClauStop( p ); return 1; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END