/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline Cnf_Dat_t * Cnf_DeriveGiaRemapped( Gia_Man_t * p ) { Cnf_Dat_t * pCnf; Aig_Man_t * pAig = Gia_ManToAigSimple( p ); pAig->nRegs = 0; pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) ); Aig_ManStop( pAig ); return pCnf; }
/**Function************************************************************* Synopsis [Finds one satisfiable assignment of the timeframes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_ManSetConstrPhases( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits ) { Aig_Man_t * pFrames; sat_solver * pSat; Cnf_Dat_t * pCnf; Aig_Obj_t * pObj; int i, RetValue; if ( pvInits ) *pvInits = NULL; // assert( p->nConstrs > 0 ); // derive the timeframes pFrames = Ssw_FramesWithConstraints( p, nFrames ); // create CNF pCnf = Cnf_Derive( pFrames, 0 ); // create SAT solver pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { Cnf_DataFree( pCnf ); Aig_ManStop( pFrames ); return 1; } // solve RetValue = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); if ( RetValue == l_True && pvInits ) { *pvInits = Vec_IntAlloc( 1000 ); Aig_ManForEachCi( pFrames, pObj, i ) Vec_IntPush( *pvInits, sat_solver_var_value(pSat, pCnf->pVarNums[Aig_ObjId(pObj)]) ); // Aig_ManForEachCi( pFrames, pObj, i ) // Abc_Print( 1, "%d", Vec_IntEntry(*pvInits, i) ); // Abc_Print( 1, "\n" ); } sat_solver_delete( pSat ); Cnf_DataFree( pCnf ); Aig_ManStop( pFrames ); if ( RetValue == l_False ) return 1; if ( RetValue == l_True ) return 0; return -1; }
/**Function************************************************************* Synopsis [Performs fraiging for one node.] Description [Returns the fraiged node.] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_ManSetConstrPhases_( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits ) { Vec_Int_t * vLits; sat_solver * pSat; Cnf_Dat_t * pCnf; Aig_Obj_t * pObj; int i, f, iVar, RetValue, nRegs; if ( pvInits ) *pvInits = NULL; assert( p->nConstrs > 0 ); // create CNF nRegs = p->nRegs; p->nRegs = 0; pCnf = Cnf_Derive( p, Aig_ManCoNum(p) ); p->nRegs = nRegs; // create SAT solver pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 ); assert( pSat->size == nFrames * pCnf->nVars ); // collect constraint literals vLits = Vec_IntAlloc( 100 ); Saig_ManForEachLo( p, pObj, i ) { assert( pCnf->pVarNums[Aig_ObjId(pObj)] >= 0 ); Vec_IntPush( vLits, toLitCond(pCnf->pVarNums[Aig_ObjId(pObj)], 1) ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Aig_ManInterRepar( Aig_Man_t * pMan, int fVerbose ) { Aig_Man_t * pAigTemp, * pInter, * pBase = NULL; sat_solver2 * pSat; Vec_Int_t * vVars; Cnf_Dat_t * pCnf, * pCnfInter; Aig_Obj_t * pObj; int nOuts = Aig_ManCoNum(pMan); int ShiftP[2], ShiftCnf[2], ShiftOr[2], ShiftAssume; int Cid, Lit, status, i, k, c; clock_t clk = clock(); assert( Aig_ManRegNum(pMan) == 0 ); // derive CNFs pCnf = Cnf_Derive( pMan, nOuts ); // start the solver pSat = sat_solver2_new(); sat_solver2_setnvars( pSat, 4*pCnf->nVars + 6*nOuts ); // vars: pGlobal + (p0 + A1 + A2 + or0) + (p1 + B1 + B2 + or1) + pAssume; ShiftP[0] = nOuts; ShiftP[1] = 2*pCnf->nVars + 3*nOuts; ShiftCnf[0] = ShiftP[0] + nOuts; ShiftCnf[1] = ShiftP[1] + nOuts; ShiftOr[0] = ShiftCnf[0] + 2*pCnf->nVars; ShiftOr[1] = ShiftCnf[1] + 2*pCnf->nVars; ShiftAssume = ShiftOr[1] + nOuts; assert( ShiftAssume + nOuts == pSat->size ); // mark variables of A for ( i = ShiftCnf[0]; i < ShiftP[1]; i++ ) var_set_partA( pSat, i, 1 ); // add clauses of A, then B vVars = Vec_IntAlloc( 2*nOuts ); for ( k = 0; k < 2; k++ ) { // copy A1 Cnf_DataLift( pCnf, ShiftCnf[k] ); for ( i = 0; i < pCnf->nClauses; i++ ) { Cid = sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); clause2_set_partA( pSat, Cid, k==0 ); } // add equality p[k] == A1/B1 Aig_ManForEachCo( pMan, pObj, i ) Aig_ManInterAddBuffer( pSat, ShiftP[k] + i, pCnf->pVarNums[pObj->Id], k==1, k==0 ); // copy A2 Cnf_DataLift( pCnf, pCnf->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) { Cid = sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); clause2_set_partA( pSat, Cid, k==0 ); } // add comparator (!p[k] ^ A2/B2) == or[k] Vec_IntClear( vVars ); Aig_ManForEachCo( pMan, pObj, i ) { Aig_ManInterAddXor( pSat, ShiftP[k] + i, pCnf->pVarNums[pObj->Id], ShiftOr[k] + i, k==1, k==0 ); Vec_IntPush( vVars, toLitCond(ShiftOr[k] + i, 1) ); } Cid = sat_solver2_addclause( pSat, Vec_IntArray(vVars), Vec_IntArray(vVars) + Vec_IntSize(vVars), 0 ); clause2_set_partA( pSat, Cid, k==0 ); // return to normal Cnf_DataLift( pCnf, -ShiftCnf[k]-pCnf->nVars ); }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManInterTest( Aig_Man_t * pMan, int fVerbose ) { sat_solver2 * pSat; // Aig_Man_t * pInter; word * pInter; Vec_Int_t * vVars; Cnf_Dat_t * pCnf; Aig_Obj_t * pObj; int Lit, Cid, Var, status, i; clock_t clk = clock(); assert( Aig_ManRegNum(pMan) == 0 ); assert( Aig_ManCoNum(pMan) == 1 ); // derive CNFs pCnf = Cnf_Derive( pMan, 1 ); // start the solver pSat = sat_solver2_new(); sat_solver2_setnvars( pSat, 2*pCnf->nVars+1 ); // set A-variables (all used except PI/PO) Aig_ManForEachObj( pMan, pObj, i ) { if ( pCnf->pVarNums[pObj->Id] < 0 ) continue; if ( !Aig_ObjIsCi(pObj) && !Aig_ObjIsCo(pObj) ) var_set_partA( pSat, pCnf->pVarNums[pObj->Id], 1 ); } // add clauses of A for ( i = 0; i < pCnf->nClauses; i++ ) { Cid = sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); clause2_set_partA( pSat, Cid, 1 ); } // add clauses of B Cnf_DataLift( pCnf, pCnf->nVars ); for ( i = 0; i < pCnf->nClauses; i++ ) sat_solver2_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1], 0 ); Cnf_DataLift( pCnf, -pCnf->nVars ); // add PI equality clauses vVars = Vec_IntAlloc( Aig_ManCoNum(pMan)+1 ); Aig_ManForEachCi( pMan, pObj, i ) { if ( Aig_ObjRefs(pObj) == 0 ) continue; Var = pCnf->pVarNums[pObj->Id]; Aig_ManInterAddBuffer( pSat, Var, pCnf->nVars + Var, 0, 0 ); Vec_IntPush( vVars, Var ); } // add an XOR clause in the end Var = pCnf->pVarNums[Aig_ManCo(pMan,0)->Id]; Aig_ManInterAddXor( pSat, Var, pCnf->nVars + Var, 2*pCnf->nVars, 0, 0 ); Vec_IntPush( vVars, Var ); // solve the problem Lit = toLitCond( 2*pCnf->nVars, 0 ); status = sat_solver2_solve( pSat, &Lit, &Lit + 1, 0, 0, 0, 0 ); assert( status == l_False ); Sat_Solver2PrintStats( stdout, pSat ); // derive interpolant // pInter = Sat_ProofInterpolant( pSat, vVars ); // Aig_ManPrintStats( pInter ); // Aig_ManDumpBlif( pInter, "int.blif", NULL, NULL ); //pInter = Sat_ProofInterpolantTruth( pSat, vVars ); pInter = NULL; // Extra_PrintHex( stdout, pInter, Vec_IntSize(vVars) ); printf( "\n" ); // clean up // Aig_ManStop( pInter ); ABC_FREE( pInter ); Vec_IntFree( vVars ); Cnf_DataFree( pCnf ); sat_solver2_delete( pSat ); ABC_PRT( "Total interpolation time", clock() - clk ); }
/**Function************************************************************* Synopsis [Run the SAT solver on the unrolled instance.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void * Inter_ManGetCounterExample( Aig_Man_t * pAig, int nFrames, int fVerbose ) { int nConfLimit = 1000000; Abc_Cex_t * pCtrex = NULL; Aig_Man_t * pFrames; sat_solver * pSat; Cnf_Dat_t * pCnf; int status; clock_t clk = clock(); Vec_Int_t * vCiIds; // create timeframes assert( Saig_ManPoNum(pAig) == 1 ); pFrames = Inter_ManFramesBmc( pAig, nFrames ); // derive CNF pCnf = Cnf_Derive( pFrames, 0 ); Cnf_DataTranformPolarity( pCnf, 0 ); vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames ); Aig_ManStop( pFrames ); // convert into SAT solver pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); Cnf_DataFree( pCnf ); if ( pSat == NULL ) { printf( "Counter-example generation in command \"int\" has failed.\n" ); printf( "Use command \"bmc2\" to produce a valid counter-example.\n" ); Vec_IntFree( vCiIds ); return NULL; } // simplify the problem status = sat_solver_simplify(pSat); if ( status == 0 ) { Vec_IntFree( vCiIds ); sat_solver_delete( pSat ); return NULL; } // solve the miter status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); // if the problem is SAT, get the counterexample if ( status == l_True ) { int i, * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize ); pCtrex = Abc_CexAlloc( Saig_ManRegNum(pAig), Saig_ManPiNum(pAig), nFrames ); pCtrex->iFrame = nFrames - 1; pCtrex->iPo = 0; for ( i = 0; i < Vec_IntSize(vCiIds); i++ ) if ( pModel[i] ) Abc_InfoSetBit( pCtrex->pData, Saig_ManRegNum(pAig) + i ); ABC_FREE( pModel ); } // free the sat_solver sat_solver_delete( pSat ); Vec_IntFree( vCiIds ); // verify counter-example status = Saig_ManVerifyCex( pAig, pCtrex ); if ( status == 0 ) printf( "Inter_ManGetCounterExample(): Counter-example verification has FAILED.\n" ); // report the results if ( fVerbose ) { ABC_PRT( "Total ctrex generation time", clock() - clk ); } return pCtrex; }
/**Function************************************************************* Synopsis [Performs induction by unrolling timeframes backward.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fUnique, int fUniqueAll, int fGetCex, int fVerbose, int fVeryVerbose ) { sat_solver * pSat; Aig_Man_t * pAigPart; Cnf_Dat_t * pCnfPart; Vec_Int_t * vTopVarNums, * vState, * vTopVarIds = NULL; Vec_Ptr_t * vTop, * vBot; Aig_Obj_t * pObjPi, * pObjPiCopy, * pObjPo; int i, k, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev; int nOldSize, iReg, iLast, fAdded, nConstrs = 0, nClauses = 0; assert( fUnique == 0 || fUniqueAll == 0 ); assert( Saig_ManPoNum(p) == 1 ); Aig_ManSetPioNumbers( p ); // start the top by including the PO vBot = Vec_PtrAlloc( 100 ); vTop = Vec_PtrAlloc( 100 ); vState = Vec_IntAlloc( 1000 ); Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); // start the array of CNF variables vTopVarNums = Vec_IntAlloc( 100 ); // start the solver pSat = sat_solver_new(); sat_solver_setnvars( pSat, 1000 ); // iterate backward unrolling RetValue = -1; nSatVarNum = 0; if ( fVerbose ) printf( "Induction parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax ); for ( f = 0; ; f++ ) { if ( f > 0 ) { Aig_ManStop( pAigPart ); Cnf_DataFree( pCnfPart ); } clk = clock(); // get the bottom Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vTop), Vec_PtrSize(vTop), vBot ); // derive AIG for the part between top and bottom pAigPart = Aig_ManDupSimpleDfsPart( p, vBot, vTop ); // convert it into CNF pCnfPart = Cnf_Derive( pAigPart, Aig_ManPoNum(pAigPart) ); Cnf_DataLift( pCnfPart, nSatVarNum ); nSatVarNum += pCnfPart->nVars; nClauses += pCnfPart->nClauses; // remember top frame var IDs if ( fGetCex && vTopVarIds == NULL ) { vTopVarIds = Vec_IntStartFull( Aig_ManPiNum(p) ); Aig_ManForEachPi( p, pObjPi, i ) { if ( pObjPi->pData == NULL ) continue; pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; assert( Aig_ObjIsPi(pObjPiCopy) ); if ( Saig_ObjIsPi(p, pObjPi) ) Vec_IntWriteEntry( vTopVarIds, Aig_ObjPioNum(pObjPi) + Saig_ManRegNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] ); else if ( Saig_ObjIsLo(p, pObjPi) ) Vec_IntWriteEntry( vTopVarIds, Aig_ObjPioNum(pObjPi) - Saig_ManPiNum(p), pCnfPart->pVarNums[Aig_ObjId(pObjPiCopy)] ); else assert( 0 ); } } // stitch variables of top and bot assert( Aig_ManPoNum(pAigPart)-1 == Vec_IntSize(vTopVarNums) ); Aig_ManForEachPo( pAigPart, pObjPo, i ) { if ( i == 0 ) { // do not perform inductive strengthening // if ( f > 0 ) // continue; // add topmost literal Lits[0] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], f>0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) ) assert( 0 ); nClauses++; continue; } Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 0 ); Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 1 ); Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); nClauses += 2; } // add CNF to the SAT solver for ( i = 0; i < pCnfPart->nClauses; i++ ) if ( !sat_solver_addclause( pSat, pCnfPart->pClauses[i], pCnfPart->pClauses[i+1] ) ) break; if ( i < pCnfPart->nClauses ) { // printf( "SAT solver became UNSAT after adding clauses.\n" ); RetValue = 1; break; } // create new set of POs to derive new top Vec_PtrClear( vTop ); Vec_PtrPush( vTop, Aig_ManPo(p, 0) ); Vec_IntClear( vTopVarNums ); nOldSize = Vec_IntSize(vState); Vec_IntFillExtra( vState, nOldSize + Aig_ManRegNum(p), -1 ); Vec_PtrForEachEntry( Aig_Obj_t *, vBot, pObjPi, i ) { assert( Aig_ObjIsPi(pObjPi) ); if ( Saig_ObjIsLo(p, pObjPi) ) { pObjPiCopy = (Aig_Obj_t *)pObjPi->pData; assert( pObjPiCopy != NULL ); Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) ); Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] ); iReg = pObjPi->PioNum - Saig_ManPiNum(p); assert( iReg >= 0 && iReg < Aig_ManRegNum(p) ); Vec_IntWriteEntry( vState, nOldSize+iReg, pCnfPart->pVarNums[pObjPiCopy->Id] ); } }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Aig_ManInterFast( Aig_Man_t * pManOn, Aig_Man_t * pManOff, int fVerbose ) { sat_solver * pSat; Cnf_Dat_t * pCnfOn, * pCnfOff; Aig_Obj_t * pObj, * pObj2; int Lits[3], status, i; // abctime clk = Abc_Clock(); assert( Aig_ManCiNum(pManOn) == Aig_ManCiNum(pManOff) ); assert( Aig_ManCoNum(pManOn) == Aig_ManCoNum(pManOff) ); // derive CNFs pManOn->nRegs = Aig_ManCoNum(pManOn); pCnfOn = Cnf_Derive( pManOn, Aig_ManCoNum(pManOn) ); pManOn->nRegs = 0; pManOff->nRegs = Aig_ManCoNum(pManOn); pCnfOff = Cnf_Derive( pManOff, Aig_ManCoNum(pManOff) ); pManOff->nRegs = 0; // pCnfOn = Cnf_DeriveSimple( pManOn, Aig_ManCoNum(pManOn) ); // pCnfOff = Cnf_DeriveSimple( pManOff, Aig_ManCoNum(pManOn) ); Cnf_DataLift( pCnfOff, pCnfOn->nVars ); // start the solver pSat = sat_solver_new(); sat_solver_setnvars( pSat, pCnfOn->nVars + pCnfOff->nVars ); // add clauses of A for ( i = 0; i < pCnfOn->nClauses; i++ ) { if ( !sat_solver_addclause( pSat, pCnfOn->pClauses[i], pCnfOn->pClauses[i+1] ) ) { Cnf_DataFree( pCnfOn ); Cnf_DataFree( pCnfOff ); sat_solver_delete( pSat ); return; } } // add clauses of B for ( i = 0; i < pCnfOff->nClauses; i++ ) { if ( !sat_solver_addclause( pSat, pCnfOff->pClauses[i], pCnfOff->pClauses[i+1] ) ) { Cnf_DataFree( pCnfOn ); Cnf_DataFree( pCnfOff ); sat_solver_delete( pSat ); return; } } // add PI clauses // collect the common variables Aig_ManForEachCi( pManOn, pObj, i ) { pObj2 = Aig_ManCi( pManOff, i ); Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 0 ); Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 1 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 1 ); Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 0 ); if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) ) assert( 0 ); }
void ToCNFAIG::toCNF(const BBNodeAIG& top, Cnf_Dat_t*& cnfData, ToSATBase::ASTNodeToSATVar& nodeToVar, bool needAbsRef, BBNodeManagerAIG& mgr) { assert(cnfData == NULL); Aig_ObjCreatePo(mgr.aigMgr, top.n); if (!needAbsRef) { Aig_ManCleanup( mgr.aigMgr); // remove nodes not connected to the PO. } Aig_ManCheck( mgr.aigMgr); // check that AIG looks ok. assert(Aig_ManPoNum(mgr.aigMgr) == 1); // UseZeroes gives assertion errors. // Rewriting is sometimes very slow. Can it be configured to be faster? // What about refactoring??? int nodeCount = mgr.aigMgr->nObjs[AIG_OBJ_AND]; if (uf.stats_flag) cerr << "Nodes before AIG rewrite:" << nodeCount << endl; if (!needAbsRef && uf.isSet("aig-rewrite","0")) { Dar_LibStart(); Aig_Man_t * pTemp; Dar_RwrPar_t Pars, *pPars = &Pars; Dar_ManDefaultRwrParams(pPars); // Assertion errors occur with this enabled. // pPars->fUseZeros = 1; // For mul63bit.smt2 with iterations =3 & nCutsMax = 8 // CNF generation was taking 139 seconds, solving 10 seconds. // With nCutsMax =2, CNF generation takes 16 seconds, solving 10 seconds. // The rewriting doesn't remove as many nodes of course.. int iterations = 3; for (int i = 0; i < iterations; i++) { mgr.aigMgr = Aig_ManDup(pTemp = mgr.aigMgr, 0); Aig_ManStop(pTemp); Dar_ManRewrite(mgr.aigMgr, pPars); mgr.aigMgr = Aig_ManDup(pTemp = mgr.aigMgr, 0); Aig_ManStop(pTemp); if (uf.stats_flag) cerr << "After rewrite [" << i << "] nodes:" << mgr.aigMgr->nObjs[AIG_OBJ_AND] << endl; if (nodeCount == mgr.aigMgr->nObjs[AIG_OBJ_AND]) break; } } if (!uf.isSet("simple-cnf","0")) { cnfData = Cnf_Derive(mgr.aigMgr, 0); if (uf.stats_flag) cerr << "advanced CNF" << endl; } else { cnfData = Cnf_DeriveSimple(mgr.aigMgr, 0); if (uf.stats_flag) cerr << "simple CNF" << endl; } BBNodeManagerAIG::SymbolToBBNode::const_iterator it; assert(nodeToVar.size() == 0); //todo. cf. with addvariables above... // Each symbol maps to a vector of CNF variables. for (it = mgr.symbolToBBNode.begin(); it != mgr.symbolToBBNode.end(); it++) { const ASTNode& n = it->first; const vector<BBNodeAIG> &b = it->second; assert(nodeToVar.find(n) == nodeToVar.end()); const int width = (n.GetType() == BOOLEAN_TYPE) ? 1 : n.GetValueWidth(); // INT_MAX for parts of symbols that didn't get encoded. vector<unsigned> v(width, ~((unsigned) 0)); for (unsigned i = 0; i < b.size(); i++) { if (!b[i].IsNull()) { Aig_Obj_t * pObj; pObj = (Aig_Obj_t*) Vec_PtrEntry(mgr.aigMgr->vPis, b[i].symbol_index); v[i] = cnfData->pVarNums[pObj->Id]; } } nodeToVar.insert(make_pair(n, v)); } assert(cnfData != NULL); }
/**Function************************************************************* Synopsis [Interplates while the number of conflicts is not exceeded.] Description [Returns 1 if proven. 0 if failed. -1 if undecided.] SideEffects [Does not check the property in 0-th frame.] SeeAlso [] ***********************************************************************/ int Inter_ManPerformInterpolation( Aig_Man_t * pAig, Inter_ManParams_t * pPars, int * piFrame ) { extern int Inter_ManCheckInductiveContainment( Aig_Man_t * pTrans, Aig_Man_t * pInter, int nSteps, int fBackward ); Inter_Man_t * p; Inter_Check_t * pCheck = NULL; Aig_Man_t * pAigTemp; int s, i, RetValue, Status; abctime clk, clk2, clkTotal = Abc_Clock(), timeTemp = 0; abctime nTimeNewOut = pPars->nSecLimit ? pPars->nSecLimit * CLOCKS_PER_SEC + Abc_Clock() : 0; // enable ORing of the interpolants, if containment check is performed inductively with K > 1 if ( pPars->nFramesK > 1 ) pPars->fTransLoop = 1; // sanity checks assert( Saig_ManRegNum(pAig) > 0 ); assert( Saig_ManPiNum(pAig) > 0 ); assert( Saig_ManPoNum(pAig)-Saig_ManConstrNum(pAig) == 1 ); if ( pPars->fVerbose && Saig_ManConstrNum(pAig) ) printf( "Performing interpolation with %d constraints...\n", Saig_ManConstrNum(pAig) ); if ( Inter_ManCheckInitialState(pAig) ) { *piFrame = -1; printf( "Property trivially fails in the initial state.\n" ); return 0; } /* if ( Inter_ManCheckAllStates(pAig) ) { printf( "Property trivially holds in all states.\n" ); return 1; } */ // create interpolation manager // can perform SAT sweeping and/or rewriting of this AIG... p = Inter_ManCreate( pAig, pPars ); if ( pPars->fTransLoop ) p->pAigTrans = Inter_ManStartOneOutput( pAig, 0 ); else p->pAigTrans = Inter_ManStartDuplicated( pAig ); // derive CNF for the transformed AIG clk = Abc_Clock(); p->pCnfAig = Cnf_Derive( p->pAigTrans, Aig_ManRegNum(p->pAigTrans) ); p->timeCnf += Abc_Clock() - clk; if ( pPars->fVerbose ) { printf( "AIG: PI/PO/Reg = %d/%d/%d. And = %d. Lev = %d. CNF: Var/Cla = %d/%d.\n", Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig), Aig_ManAndNum(pAig), Aig_ManLevelNum(pAig), p->pCnfAig->nVars, p->pCnfAig->nClauses ); } // derive interpolant *piFrame = -1; p->nFrames = 1; for ( s = 0; ; s++ ) { Cnf_Dat_t * pCnfInter2; clk2 = Abc_Clock(); // initial state if ( pPars->fUseBackward ) p->pInter = Inter_ManStartOneOutput( pAig, 1 ); else p->pInter = Inter_ManStartInitState( Aig_ManRegNum(pAig) ); assert( Aig_ManCoNum(p->pInter) == 1 ); clk = Abc_Clock(); p->pCnfInter = Cnf_Derive( p->pInter, 0 ); p->timeCnf += Abc_Clock() - clk; // timeframes p->pFrames = Inter_ManFramesInter( pAig, p->nFrames, pPars->fUseBackward, pPars->fUseTwoFrames ); clk = Abc_Clock(); if ( pPars->fRewrite ) { p->pFrames = Dar_ManRwsat( pAigTemp = p->pFrames, 1, 0 ); Aig_ManStop( pAigTemp ); // p->pFrames = Fra_FraigEquivence( pAigTemp = p->pFrames, 100, 0 ); // Aig_ManStop( pAigTemp ); } p->timeRwr += Abc_Clock() - clk; // can also do SAT sweeping on the timeframes... clk = Abc_Clock(); if ( pPars->fUseBackward ) p->pCnfFrames = Cnf_Derive( p->pFrames, Aig_ManCoNum(p->pFrames) ); else // p->pCnfFrames = Cnf_Derive( p->pFrames, 0 ); p->pCnfFrames = Cnf_DeriveSimple( p->pFrames, 0 ); p->timeCnf += Abc_Clock() - clk; // report statistics if ( pPars->fVerbose ) { printf( "Step = %2d. Frames = 1 + %d. And = %5d. Lev = %5d. ", s+1, p->nFrames, Aig_ManNodeNum(p->pFrames), Aig_ManLevelNum(p->pFrames) ); ABC_PRT( "Time", Abc_Clock() - clk2 ); } ////////////////////////////////////////// // start containment checking if ( !(pPars->fTransLoop || pPars->fUseBackward || pPars->nFramesK > 1) ) { pCheck = Inter_CheckStart( p->pAigTrans, pPars->nFramesK ); // try new containment check for the initial state clk = Abc_Clock(); pCnfInter2 = Cnf_Derive( p->pInter, 1 ); p->timeCnf += Abc_Clock() - clk; clk = Abc_Clock(); RetValue = Inter_CheckPerform( pCheck, pCnfInter2, nTimeNewOut ); p->timeEqu += Abc_Clock() - clk; // assert( RetValue == 0 ); Cnf_DataFree( pCnfInter2 ); if ( p->vInters ) Vec_PtrPush( p->vInters, Aig_ManDupSimple(p->pInter) ); } ////////////////////////////////////////// // iterate the interpolation procedure for ( i = 0; ; i++ ) { if ( pPars->nFramesMax && p->nFrames + i >= pPars->nFramesMax ) { if ( pPars->fVerbose ) printf( "Reached limit (%d) on the number of timeframes.\n", pPars->nFramesMax ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 0 ); Inter_CheckStop( pCheck ); return -1; } // perform interpolation clk = Abc_Clock(); #ifdef ABC_USE_LIBRARIES if ( pPars->fUseMiniSat ) { assert( !pPars->fUseBackward ); RetValue = Inter_ManPerformOneStepM114p( p, pPars->fUsePudlak, pPars->fUseOther ); } else #endif RetValue = Inter_ManPerformOneStep( p, pPars->fUseBias, pPars->fUseBackward, nTimeNewOut ); if ( pPars->fVerbose ) { printf( " I = %2d. Bmc =%3d. IntAnd =%6d. IntLev =%5d. Conf =%6d. ", i+1, i + 1 + p->nFrames, Aig_ManNodeNum(p->pInter), Aig_ManLevelNum(p->pInter), p->nConfCur ); ABC_PRT( "Time", Abc_Clock() - clk ); } // remember the number of timeframes completed pPars->iFrameMax = i - 1 + p->nFrames; if ( RetValue == 0 ) // found a (spurious?) counter-example { if ( i == 0 ) // real counterexample { if ( pPars->fVerbose ) printf( "Found a real counterexample in frame %d.\n", p->nFrames ); p->timeTotal = Abc_Clock() - clkTotal; *piFrame = p->nFrames; // pAig->pSeqModel = (Abc_Cex_t *)Inter_ManGetCounterExample( pAig, p->nFrames+1, pPars->fVerbose ); { int RetValue; Saig_ParBmc_t ParsBmc, * pParsBmc = &ParsBmc; Saig_ParBmcSetDefaultParams( pParsBmc ); pParsBmc->nConfLimit = 100000000; pParsBmc->nStart = p->nFrames; pParsBmc->fVerbose = pPars->fVerbose; RetValue = Saig_ManBmcScalable( pAig, pParsBmc ); if ( RetValue == 1 ) printf( "Error: The problem should be SAT but it is UNSAT.\n" ); else if ( RetValue == -1 ) printf( "Error: The problem timed out.\n" ); } Inter_ManStop( p, 0 ); Inter_CheckStop( pCheck ); return 0; } // likely spurious counter-example p->nFrames += i; Inter_ManClean( p ); break; } else if ( RetValue == -1 ) { if ( pPars->nSecLimit && Abc_Clock() > nTimeNewOut ) // timed out { if ( pPars->fVerbose ) printf( "Reached timeout (%d seconds).\n", pPars->nSecLimit ); } else { assert( p->nConfCur >= p->nConfLimit ); if ( pPars->fVerbose ) printf( "Reached limit (%d) on the number of conflicts.\n", p->nConfLimit ); } p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 0 ); Inter_CheckStop( pCheck ); return -1; } assert( RetValue == 1 ); // found new interpolant // compress the interpolant clk = Abc_Clock(); if ( p->pInterNew ) { // save the timeout value p->pInterNew->Time2Quit = nTimeNewOut; // Ioa_WriteAiger( p->pInterNew, "interpol.aig", 0, 0 ); p->pInterNew = Dar_ManRwsat( pAigTemp = p->pInterNew, 1, 0 ); // p->pInterNew = Dar_ManRwsat( pAigTemp = p->pInterNew, 0, 0 ); Aig_ManStop( pAigTemp ); if ( p->pInterNew == NULL ) { printf( "Reached timeout (%d seconds) during rewriting.\n", pPars->nSecLimit ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return -1; } } p->timeRwr += Abc_Clock() - clk; // check if interpolant is trivial if ( p->pInterNew == NULL || Aig_ObjChild0(Aig_ManCo(p->pInterNew,0)) == Aig_ManConst0(p->pInterNew) ) { // printf( "interpolant is constant 0\n" ); if ( pPars->fVerbose ) printf( "The problem is trivially true for all states.\n" ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return 1; } // check containment of interpolants clk = Abc_Clock(); if ( pPars->fCheckKstep ) // k-step unique-state induction { if ( Aig_ManCiNum(p->pInterNew) == Aig_ManCiNum(p->pInter) ) { if ( pPars->fTransLoop || pPars->fUseBackward || pPars->nFramesK > 1 ) { clk2 = Abc_Clock(); Status = Inter_ManCheckInductiveContainment( p->pAigTrans, p->pInterNew, Abc_MinInt(i + 1, pPars->nFramesK), pPars->fUseBackward ); timeTemp = Abc_Clock() - clk2; } else { // new containment check clk2 = Abc_Clock(); pCnfInter2 = Cnf_Derive( p->pInterNew, 1 ); p->timeCnf += Abc_Clock() - clk2; timeTemp = Abc_Clock() - clk2; Status = Inter_CheckPerform( pCheck, pCnfInter2, nTimeNewOut ); Cnf_DataFree( pCnfInter2 ); if ( p->vInters ) Vec_PtrPush( p->vInters, Aig_ManDupSimple(p->pInterNew) ); } } else Status = 0; } else // combinational containment { if ( Aig_ManCiNum(p->pInterNew) == Aig_ManCiNum(p->pInter) ) Status = Inter_ManCheckContainment( p->pInterNew, p->pInter ); else Status = 0; } p->timeEqu += Abc_Clock() - clk - timeTemp; if ( Status ) // contained { if ( pPars->fVerbose ) printf( "Proved containment of interpolants.\n" ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return 1; } if ( pPars->nSecLimit && Abc_Clock() > nTimeNewOut ) { printf( "Reached timeout (%d seconds).\n", pPars->nSecLimit ); p->timeTotal = Abc_Clock() - clkTotal; Inter_ManStop( p, 1 ); Inter_CheckStop( pCheck ); return -1; } // save interpolant and convert it into CNF if ( pPars->fTransLoop ) { Aig_ManStop( p->pInter ); p->pInter = p->pInterNew; } else { if ( pPars->fUseBackward ) { p->pInter = Aig_ManCreateMiter( pAigTemp = p->pInter, p->pInterNew, 2 ); Aig_ManStop( pAigTemp ); Aig_ManStop( p->pInterNew ); // compress the interpolant clk = Abc_Clock(); p->pInter = Dar_ManRwsat( pAigTemp = p->pInter, 1, 0 ); Aig_ManStop( pAigTemp ); p->timeRwr += Abc_Clock() - clk; } else // forward with the new containment checking (using only the frontier) { Aig_ManStop( p->pInter ); p->pInter = p->pInterNew; } } p->pInterNew = NULL; Cnf_DataFree( p->pCnfInter ); clk = Abc_Clock(); p->pCnfInter = Cnf_Derive( p->pInter, 0 ); p->timeCnf += Abc_Clock() - clk; } // start containment checking Inter_CheckStop( pCheck ); } assert( 0 ); return RetValue; }