/**Function************************************************************* Synopsis [Adds trivial clause.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkClauseAnd( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_Int_t * vVars ) { int fComp1, Var, Var1, i; //printf( "Adding AND %d. (%d) %d\n", pNode->Id, vSuper->nSize+1, (int)pSat->sat_solver_stats.clauses ); assert( !Abc_ObjIsComplement( pNode ) ); assert( Abc_ObjIsNode( pNode ) ); // nVars = sat_solver_nvars(pSat); Var = (int)(ABC_PTRINT_T)pNode->pCopy; // Var = pNode->Id; // assert( Var < nVars ); for ( i = 0; i < vSuper->nSize; i++ ) { // get the predecessor nodes // get the complemented attributes of the nodes fComp1 = Abc_ObjIsComplement((Abc_Obj_t *)vSuper->pArray[i]); // determine the variable numbers Var1 = (int)(ABC_PTRINT_T)Abc_ObjRegular((Abc_Obj_t *)vSuper->pArray[i])->pCopy; // Var1 = (int)Abc_ObjRegular(vSuper->pArray[i])->Id; // check that the variables are in the SAT manager // assert( Var1 < nVars ); // suppose the AND-gate is A * B = C // add !A => !C or A + !C // fprintf( pFile, "%d %d 0%c", Var1, -Var, 10 ); vVars->nSize = 0; Vec_IntPush( vVars, toLitCond(Var1, fComp1) ); Vec_IntPush( vVars, toLitCond(Var, 1 ) ); if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) return 0; } // add A & B => C or !A + !B + C // fprintf( pFile, "%d %d %d 0%c", -Var1, -Var2, Var, 10 ); vVars->nSize = 0; for ( i = 0; i < vSuper->nSize; i++ ) { // get the predecessor nodes // get the complemented attributes of the nodes fComp1 = Abc_ObjIsComplement((Abc_Obj_t *)vSuper->pArray[i]); // determine the variable numbers Var1 = (int)(ABC_PTRINT_T)Abc_ObjRegular((Abc_Obj_t *)vSuper->pArray[i])->pCopy; // Var1 = (int)Abc_ObjRegular(vSuper->pArray[i])->Id; // add this variable to the array Vec_IntPush( vVars, toLitCond(Var1, !fComp1) ); } Vec_IntPush( vVars, toLitCond(Var, 0) ); return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); }
void Cnf_AddCardinConstrTest() { int i, status, nVars = 7; Vec_Int_t * vVars = Vec_IntStartNatural( nVars ); sat_solver * pSat = sat_solver_new(); sat_solver_setnvars( pSat, nVars ); Cnf_AddCardinConstr( pSat, vVars ); while ( 1 ) { status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 ); if ( status != l_True ) break; Vec_IntClear( vVars ); for ( i = 0; i < nVars; i++ ) { Vec_IntPush( vVars, Abc_Var2Lit(i, sat_solver_var_value(pSat, i)) ); printf( "%d", sat_solver_var_value(pSat, i) ); } printf( "\n" ); status = sat_solver_addclause( pSat, Vec_IntArray(vVars), Vec_IntArray(vVars) + Vec_IntSize(vVars) ); if ( status == 0 ) break; } sat_solver_delete( pSat ); Vec_IntFree( vVars ); }
static inline int Pdr_ObjSatVar2FindOrAdd( Pdr_Man_t * p, int k, Aig_Obj_t * pObj ) { Vec_Int_t * vId2Vars = p->pvId2Vars + Aig_ObjId(pObj); assert( p->pCnf2->pObj2Count[Aig_ObjId(pObj)] >= 0 ); if ( Vec_IntSize(vId2Vars) == 0 ) Vec_IntGrow(vId2Vars, 2 * k + 1); if ( Vec_IntGetEntry(vId2Vars, k) == 0 ) { sat_solver * pSat = Pdr_ManSolver(p, k); Vec_Int_t * vVar2Ids = (Vec_Int_t *)Vec_PtrEntry(&p->vVar2Ids, k); int iVarNew = Vec_IntSize( vVar2Ids ); assert( iVarNew > 0 ); Vec_IntPush( vVar2Ids, Aig_ObjId(pObj) ); Vec_IntWriteEntry( vId2Vars, k, iVarNew << 2 ); sat_solver_setnvars( pSat, iVarNew + 1 ); if ( k == 0 && Saig_ObjIsLo(p->pAig, pObj) ) // initialize the register output { int Lit = toLitCond( iVarNew, 1 ); int RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); assert( RetValue == 1 ); (void) RetValue; sat_solver_compress( pSat ); } } return Vec_IntEntry( vId2Vars, k ); }
/**Function************************************************************* Synopsis [Creating/deleting the manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline Swp_Man_t * Swp_ManStart( Gia_Man_t * pGia ) { Swp_Man_t * p; int Lit; assert( pGia->pHTable != NULL ); pGia->pData = p = ABC_CALLOC( Swp_Man_t, 1 ); p->pGia = pGia; p->nConfMax = 1000; p->vProbes = Vec_IntAlloc( 100 ); p->vProbRefs = Vec_IntAlloc( 100 ); p->vLit2Prob = Vec_IntStartFull( 10000 ); p->vCondProbes = Vec_IntAlloc( 100 ); p->vCondAssump = Vec_IntAlloc( 100 ); p->vId2Lit = Vec_IntAlloc( 10000 ); p->vFront = Vec_IntAlloc( 100 ); p->vFanins = Vec_IntAlloc( 100 ); p->vCexSwp = Vec_IntAlloc( 100 ); p->pSat = sat_solver_new(); p->nSatVars = 1; sat_solver_setnvars( p->pSat, 1000 ); Swp_ManSetObj2Lit( p, 0, (Lit = Abc_Var2Lit(p->nSatVars++, 0)) ); Lit = Abc_LitNot(Lit); sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); p->timeStart = Abc_Clock(); return p; }
/**Function************************************************************* Synopsis [Adds trivial clause.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkClauseTriv( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars ) { //printf( "Adding triv %d. %d\n", Abc_ObjRegular(pNode)->Id, (int)pSat->sat_solver_stats.clauses ); vVars->nSize = 0; Vec_IntPush( vVars, toLitCond( (int)(ABC_PTRINT_T)Abc_ObjRegular(pNode)->pCopy, Abc_ObjIsComplement(pNode) ) ); // Vec_IntPush( vVars, toLitCond( (int)Abc_ObjRegular(pNode)->Id, Abc_ObjIsComplement(pNode) ) ); return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); }
/**Function************************************************************* Synopsis [Compute the patch function.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Bmc_EcoPatch( Gia_Man_t * p, int nIns, int nOuts ) { int i, Lit, RetValue, Root; Gia_Obj_t * pObj; Vec_Int_t * vVars; // generate CNF and solver Cnf_Dat_t * pCnf = Cnf_DeriveGiaRemapped( p ); sat_solver * pSat = sat_solver_new(); sat_solver_setnvars( pSat, pCnf->nVars ); // add timeframe clauses for ( i = 0; i < pCnf->nClauses; i++ ) if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) assert( 0 ); // add equality constraints assert( Gia_ManPoNum(p) == nOuts + 1 + nIns ); Gia_ManForEachPo( p, pObj, i ) { if ( i == nOuts ) break; Lit = Abc_Var2Lit( pCnf->pVarNums[Gia_ObjId(p, pObj)], 1 ); // neg lit RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); assert( RetValue ); } // add inequality constraint pObj = Gia_ManPo( p, nOuts ); Lit = Abc_Var2Lit( pCnf->pVarNums[Gia_ObjId(p, pObj)], 0 ); // pos lit RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 ); assert( RetValue ); // simplify the SAT solver RetValue = sat_solver_simplify( pSat ); assert( RetValue ); // collect input variables vVars = Vec_IntAlloc( nIns ); Gia_ManForEachPo( p, pObj, i ) if ( i >= nOuts + 1 ) Vec_IntPush( vVars, pCnf->pVarNums[Gia_ObjId(p, pObj)] ); assert( Vec_IntSize(vVars) == nIns ); // derive the root variable pObj = Gia_ManPi( p, Gia_ManPiNum(p) - 1 ); Root = pCnf->pVarNums[Gia_ObjId(p, pObj)]; // solve the problem RetValue = Bmc_EcoSolve( pSat, Root, vVars ); Vec_IntFree( vVars ); return RetValue; }
/**Function************************************************************* Synopsis [Solve the enumeration problem.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Bmc_EcoSolve( sat_solver * pSat, int Root, Vec_Int_t * vVars ) { int nBTLimit = 1000000; Vec_Int_t * vLits = Vec_IntAlloc( Vec_IntSize(vVars) ); int status, i, Div, iVar, nFinal, * pFinal, nIter = 0, RetValue = 0; int pLits[2], nVars = sat_solver_nvars( pSat ); sat_solver_setnvars( pSat, nVars + 1 ); pLits[0] = Abc_Var2Lit( Root, 0 ); // F = 1 pLits[1] = Abc_Var2Lit( nVars, 0 ); // iNewLit while ( 1 ) { // find onset minterm status = sat_solver_solve( pSat, pLits, pLits + 2, nBTLimit, 0, 0, 0 ); if ( status == l_Undef ) { RetValue = -1; break; } if ( status == l_False ) { RetValue = 1; break; } assert( status == l_True ); // collect divisor literals Vec_IntClear( vLits ); Vec_IntPush( vLits, Abc_LitNot(pLits[0]) ); // F = 0 Vec_IntForEachEntry( vVars, Div, i ) Vec_IntPush( vLits, sat_solver_var_literal(pSat, Div) ); // check against offset status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits), nBTLimit, 0, 0, 0 ); if ( status == l_Undef ) { RetValue = -1; break; } if ( status == l_True ) break; assert( status == l_False ); // compute cube and add clause nFinal = sat_solver_final( pSat, &pFinal ); Vec_IntClear( vLits ); Vec_IntPush( vLits, Abc_LitNot(pLits[1]) ); // NOT(iNewLit) printf( "Cube %d : ", nIter ); for ( i = 0; i < nFinal; i++ ) { if ( pFinal[i] == pLits[0] ) continue; Vec_IntPush( vLits, pFinal[i] ); iVar = Vec_IntFind( vVars, Abc_Lit2Var(pFinal[i]) ); assert( iVar >= 0 ); printf( "%s%d ", Abc_LitIsCompl(pFinal[i]) ? "+":"-", iVar ); } printf( "\n" ); status = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ); assert( status ); nIter++; } // assert( status == l_True ); Vec_IntFree( vLits ); return RetValue; }
/**Function************************************************************* Synopsis [Constrains one node in the SAT solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_NodeIsConstrained( Ssw_Man_t * p, Aig_Obj_t * pPoObj ) { int RetValue, Lit; Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pPoObj) ); // add constraint A = 1 ----> A Lit = toLitCond( Ssw_ObjSatNum(p->pMSat,Aig_ObjFanin0(pPoObj)), !Aig_ObjFaninC0(pPoObj) ); if ( p->pPars->fPolarFlip ) { if ( Aig_ObjFanin0(pPoObj)->fPhase ) Lit = lit_neg( Lit ); } RetValue = sat_solver_addclause( p->pMSat->pSat, &Lit, &Lit + 1 ); assert( RetValue ); return 1; }
/**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Bmc_Load_t * Bmc_LoadStart( Gia_Man_t * pGia ) { Bmc_Load_t * p; int Lit; Gia_ManSetPhase( pGia ); Gia_ManCleanValue( pGia ); Gia_ManCreateRefs( pGia ); p = ABC_CALLOC( Bmc_Load_t, 1 ); p->pGia = pGia; p->pSat = sat_solver_new(); p->vSat2Id = Vec_IntAlloc( 1000 ); Vec_IntPush( p->vSat2Id, 0 ); // create constant node Lit = Abc_Var2Lit( Bmc_LoadGetSatVar(p, 0), 1 ); sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); return p; }
/**Function************************************************************* Synopsis [Addes clauses to the solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Gia_ManAddClausesSuper( Ssc_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSuper ) { int i, RetValue, Lit, LitNode, pLits[2]; assert( !Gia_IsComplement(pNode) ); assert( Gia_ObjIsAnd( pNode ) ); // suppose AND-gate is A & B = C // add !A => !C or A + !C // add !B => !C or B + !C LitNode = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNode) ); Vec_IntForEachEntry( vSuper, Lit, i ) { pLits[0] = Ssc_ObjSatLit( p, Lit ); pLits[1] = Abc_LitNot( LitNode ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); // update literals Vec_IntWriteEntry( vSuper, i, Abc_LitNot(pLits[0]) ); }
/**Function************************************************************* Synopsis [Add uniqueness constraint.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Saig_ManAddUniqueness( sat_solver * pSat, Vec_Int_t * vState, int nRegs, int i, int k, int * pnSatVarNum, int * pnClauses ) { int * pStateI = (int *)Vec_IntArray(vState) + nRegs * i; int * pStateK = (int *)Vec_IntArray(vState) + nRegs * k; int v, iVars, nSatVarsOld, RetValue, * pClause; assert( i && k && i < k ); assert( nRegs * k <= Vec_IntSize(vState) ); // check if the states are available for ( v = 0; v < nRegs; v++ ) if ( pStateI[v] >= 0 && pStateK[v] == -1 ) { // printf( "Cannot constrain an incomplete state.\n" ); return; } // add XORs nSatVarsOld = *pnSatVarNum; for ( v = 0; v < nRegs; v++ ) if ( pStateI[v] >= 0 ) { *pnClauses += 4; RetValue = Cnf_DataAddXorClause( pSat, pStateI[v], pStateK[v], (*pnSatVarNum)++ ); if ( RetValue == 0 ) { printf( "SAT solver became UNSAT.\n" ); return; } } // add OR clause (*pnClauses)++; iVars = 0; pClause = ABC_ALLOC( int, nRegs ); for ( v = nSatVarsOld; v < *pnSatVarNum; v++ ) pClause[iVars++] = toLitCond( v, 0 ); assert( iVars <= nRegs ); RetValue = sat_solver_addclause( pSat, pClause, pClause + iVars ); ABC_FREE( pClause ); if ( RetValue == 0 ) { printf( "SAT solver became UNSAT.\n" ); return; } }
/**Function************************************************************* Synopsis [Addes clauses to the solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Cec_AddClausesSuper( Cec_ManSat_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper ) { Gia_Obj_t * pFanin; int * pLits, nLits, RetValue, i; assert( !Gia_IsComplement(pNode) ); assert( Gia_ObjIsAnd( pNode ) ); // create storage for literals nLits = Vec_PtrSize(vSuper) + 1; pLits = ABC_ALLOC( int, nLits ); // suppose AND-gate is A & B = C // add !A => !C or A + !C Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) { pLits[0] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); pLits[1] = toLitCond(Cec_ObjSatNum(p,pNode), 1); if ( p->pPars->fPolarFlip ) { if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); }
/**Function************************************************************* Synopsis [Add constraint that no more than 1 variable is 1.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Cnf_AddCardinConstr( sat_solver * p, Vec_Int_t * vVars ) { int i, k, pLits[2], iVar, nVars = sat_solver_nvars(p); Vec_IntForEachEntry( vVars, iVar, i ) assert( iVar >= 0 && iVar < nVars ); iVar = nVars; sat_solver_setnvars( p, nVars + Vec_IntSize(vVars) - 1 ); while ( Vec_IntSize(vVars) > 1 ) { for ( k = i = 0; i < Vec_IntSize(vVars)/2; i++ ) { pLits[0] = Abc_Var2Lit( Vec_IntEntry(vVars, 2*i), 1 ); pLits[1] = Abc_Var2Lit( Vec_IntEntry(vVars, 2*i+1), 1 ); sat_solver_addclause( p, pLits, pLits + 2 ); sat_solver_add_and( p, iVar, Vec_IntEntry(vVars, 2*i), Vec_IntEntry(vVars, 2*i+1), 1, 1, 1 ); Vec_IntWriteEntry( vVars, k++, iVar++ ); } if ( Vec_IntSize(vVars) & 1 ) Vec_IntWriteEntry( vVars, k++, Vec_IntEntryLast(vVars) ); Vec_IntShrink( vVars, k ); } return iVar; }
/**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 [Adds trivial clause.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ 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 ) { int VarF, VarI, VarT, VarE, fCompT, fCompE; //printf( "Adding mux %d. %d\n", pNode->Id, (int)pSat->sat_solver_stats.clauses ); assert( !Abc_ObjIsComplement( pNode ) ); assert( Abc_NodeIsMuxType( pNode ) ); // get the variable numbers VarF = (int)(ABC_PTRINT_T)pNode->pCopy; VarI = (int)(ABC_PTRINT_T)pNodeC->pCopy; VarT = (int)(ABC_PTRINT_T)Abc_ObjRegular(pNodeT)->pCopy; VarE = (int)(ABC_PTRINT_T)Abc_ObjRegular(pNodeE)->pCopy; // VarF = (int)pNode->Id; // VarI = (int)pNodeC->Id; // VarT = (int)Abc_ObjRegular(pNodeT)->Id; // VarE = (int)Abc_ObjRegular(pNodeE)->Id; // get the complementation flags fCompT = Abc_ObjIsComplement(pNodeT); fCompE = Abc_ObjIsComplement(pNodeE); // f = ITE(i, t, e) // i' + t' + f // i' + t + f' // i + e' + f // i + e + f' // create four clauses vVars->nSize = 0; Vec_IntPush( vVars, toLitCond(VarI, 1) ); Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) ); Vec_IntPush( vVars, toLitCond(VarF, 0) ); if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) return 0; vVars->nSize = 0; Vec_IntPush( vVars, toLitCond(VarI, 1) ); Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) ); Vec_IntPush( vVars, toLitCond(VarF, 1) ); if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) return 0; vVars->nSize = 0; Vec_IntPush( vVars, toLitCond(VarI, 0) ); Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) ); Vec_IntPush( vVars, toLitCond(VarF, 0) ); if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) return 0; vVars->nSize = 0; Vec_IntPush( vVars, toLitCond(VarI, 0) ); Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) ); Vec_IntPush( vVars, toLitCond(VarF, 1) ); if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) return 0; if ( VarT == VarE ) { // assert( fCompT == !fCompE ); return 1; } // two additional clauses // t' & e' -> f' t + e + f' // t & e -> f t' + e' + f vVars->nSize = 0; Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) ); Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) ); Vec_IntPush( vVars, toLitCond(VarF, 1) ); if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) ) return 0; vVars->nSize = 0; Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) ); Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) ); Vec_IntPush( vVars, toLitCond(VarF, 0) ); return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Runs equivalence test for the two nodes.] Description [Both nodes should be regular and different from each other.] SideEffects [] SeeAlso [] ***********************************************************************/ int Cgt_CheckImplication( Cgt_Man_t * p, Aig_Obj_t * pGate, Aig_Obj_t * pMiter ) { int nBTLimit = p->pPars->nConfMax; int pLits[2], RetValue, clk; p->nCalls++; // sanity checks assert( p->pSat && p->pCnf ); assert( !Aig_IsComplement(pMiter) ); assert( Aig_Regular(pGate) != pMiter ); // solve under assumptions // G => !M -- true G & M -- false pLits[0] = toLitCond( p->pCnf->pVarNums[Aig_Regular(pGate)->Id], Aig_IsComplement(pGate) ); pLits[1] = toLitCond( p->pCnf->pVarNums[pMiter->Id], 0 ); clk = clock(); RetValue = sat_solver_solve( p->pSat, pLits, pLits + 2, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); p->timeSat += clock() - clk; if ( RetValue == l_False ) { p->timeSatUnsat += clock() - clk; pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); sat_solver_compress( p->pSat ); p->nCallsUnsat++; return 1; } else if ( RetValue == l_True ) { p->timeSatSat += clock() - clk; p->nCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatUndec += clock() - clk; p->nCallsUndec++; return -1; } return -2; }
/**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 ); }
int Pdr_ObjSatVar2( Pdr_Man_t * p, int k, Aig_Obj_t * pObj, int Level, int Pol ) { Vec_Int_t * vLits; sat_solver * pSat; Vec_Int_t * vVar2Ids = (Vec_Int_t *)Vec_PtrEntry(&p->vVar2Ids, k); int nVarCount = Vec_IntSize(vVar2Ids); int iVarThis = Pdr_ObjSatVar2FindOrAdd( p, k, pObj ); int * pLit, i, iVar, iClaBeg, iClaEnd, RetValue; int PolPres = (iVarThis & 3); iVarThis >>= 2; if ( Aig_ObjIsCi(pObj) ) return iVarThis; // Pol = 3; // if ( nVarCount != Vec_IntSize(vVar2Ids) || (Pol & ~PolPres) ) if ( (Pol & ~PolPres) ) { *Vec_IntEntryP( p->pvId2Vars + Aig_ObjId(pObj), k ) |= Pol; iClaBeg = p->pCnf2->pObj2Clause[Aig_ObjId(pObj)]; iClaEnd = iClaBeg + p->pCnf2->pObj2Count[Aig_ObjId(pObj)]; assert( iClaBeg < iClaEnd ); /* if ( (Pol & ~PolPres) != 3 ) for ( i = iFirstClause; i < iFirstClause + nClauses; i++ ) { printf( "Clause %5d : ", i ); for ( iVar = 0; iVar < 4; iVar++ ) printf( "%d ", ((unsigned)p->pCnf2->pClaPols[i] >> (2*iVar)) & 3 ); printf( " " ); for ( pLit = p->pCnf2->pClauses[i]; pLit < p->pCnf2->pClauses[i+1]; pLit++ ) printf( "%6d ", *pLit ); printf( "\n" ); } */ pSat = Pdr_ManSolver(p, k); vLits = Vec_WecEntry( p->vVLits, Level ); if ( (Pol & ~PolPres) == 3 ) { assert( nVarCount + 1 == Vec_IntSize(vVar2Ids) ); for ( i = iClaBeg; i < iClaEnd; i++ ) { Vec_IntClear( vLits ); Vec_IntPush( vLits, toLitCond( iVarThis, lit_sign(p->pCnf2->pClauses[i][0]) ) ); for ( pLit = p->pCnf2->pClauses[i]+1; pLit < p->pCnf2->pClauses[i+1]; pLit++ ) { iVar = Pdr_ObjSatVar2( p, k, Aig_ManObj(p->pAig, lit_var(*pLit)), Level+1, 3 ); Vec_IntPush( vLits, toLitCond( iVar, lit_sign(*pLit) ) ); } RetValue = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits)+Vec_IntSize(vLits) ); assert( RetValue ); (void) RetValue; } } else // if ( (Pol & ~PolPres) == 2 || (Pol & ~PolPres) == 1 ) // write pos/neg polarity { assert( (Pol & ~PolPres) ); for ( i = iClaBeg; i < iClaEnd; i++ ) if ( 2 - !Abc_LitIsCompl(p->pCnf2->pClauses[i][0]) == (Pol & ~PolPres) ) // taking opposite literal { Vec_IntClear( vLits ); Vec_IntPush( vLits, toLitCond( iVarThis, Abc_LitIsCompl(p->pCnf2->pClauses[i][0]) ) ); for ( pLit = p->pCnf2->pClauses[i]+1; pLit < p->pCnf2->pClauses[i+1]; pLit++ ) { iVar = Pdr_ObjSatVar2( p, k, Aig_ManObj(p->pAig, lit_var(*pLit)), Level+1, ((unsigned)p->pCnf2->pClaPols[i] >> (2*(pLit-p->pCnf2->pClauses[i]-1))) & 3 ); Vec_IntPush( vLits, toLitCond( iVar, lit_sign(*pLit) ) ); } RetValue = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits)+Vec_IntSize(vLits) ); assert( RetValue ); (void) RetValue; } }
/**Function************************************************************* Synopsis [Addes clauses to the solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Cec_AddClausesMux( Cec_ManSat_t * p, Gia_Obj_t * pNode ) { Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; assert( !Gia_IsComplement( pNode ) ); assert( Gia_ObjIsMuxType( pNode ) ); // get nodes (I = if, T = then, E = else) pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); // get the variable numbers VarF = Cec_ObjSatNum(p,pNode); VarI = Cec_ObjSatNum(p,pNodeI); VarT = Cec_ObjSatNum(p,Gia_Regular(pNodeT)); VarE = Cec_ObjSatNum(p,Gia_Regular(pNodeE)); // get the complementation flags fCompT = Gia_IsComplement(pNodeT); fCompE = Gia_IsComplement(pNodeE); // f = ITE(i, t, e) // i' + t' + f // i' + t + f' // i + e' + f // i + e + f' // create four clauses pLits[0] = toLitCond(VarI, 1); pLits[1] = toLitCond(VarT, 1^fCompT); pLits[2] = toLitCond(VarF, 0); if ( p->pPars->fPolarFlip ) { if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = toLitCond(VarI, 1); pLits[1] = toLitCond(VarT, 0^fCompT); pLits[2] = toLitCond(VarF, 1); if ( p->pPars->fPolarFlip ) { if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = toLitCond(VarI, 0); pLits[1] = toLitCond(VarE, 1^fCompE); pLits[2] = toLitCond(VarF, 0); if ( p->pPars->fPolarFlip ) { if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = toLitCond(VarI, 0); pLits[1] = toLitCond(VarE, 0^fCompE); pLits[2] = toLitCond(VarF, 1); if ( p->pPars->fPolarFlip ) { if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); // two additional clauses // t' & e' -> f' // t & e -> f // t + e + f' // t' + e' + f if ( VarT == VarE ) { // assert( fCompT == !fCompE ); return; } pLits[0] = toLitCond(VarT, 0^fCompT); pLits[1] = toLitCond(VarE, 0^fCompE); pLits[2] = toLitCond(VarF, 1); if ( p->pPars->fPolarFlip ) { if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = toLitCond(VarT, 1^fCompT); pLits[1] = toLitCond(VarE, 1^fCompE); pLits[2] = toLitCond(VarF, 0); if ( p->pPars->fPolarFlip ) { if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); }
// suppose AND-gate is A & B = C // add !A => !C or A + !C // add !B => !C or B + !C LitNode = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNode) ); Vec_IntForEachEntry( vSuper, Lit, i ) { pLits[0] = Ssc_ObjSatLit( p, Lit ); pLits[1] = Abc_LitNot( LitNode ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); // update literals Vec_IntWriteEntry( vSuper, i, Abc_LitNot(pLits[0]) ); } // add A & B => C or !A + !B + C Vec_IntPush( vSuper, LitNode ); RetValue = sat_solver_addclause( p->pSat, Vec_IntArray(vSuper), Vec_IntArray(vSuper) + Vec_IntSize(vSuper) ); assert( RetValue ); (void) RetValue; } /**Function************************************************************* Synopsis [Collects the supergate.] Description [] SideEffects [] SeeAlso []
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Runs equivalence test for the two nodes.] Description [Both nodes should be regular and different from each other.] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) { int nBTLimit = p->pPars->nBTLimit; int pLits[3], nLits, RetValue, RetValue1, clk;//, status; p->nSatCalls++; p->pMSat->nSolverCalls++; // sanity checks assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); assert( pOld != pNew ); assert( p->pMSat != NULL ); // if the nodes do not have SAT variables, allocate them Ssw_CnfNodeAddToSolver( p->pMSat, pOld ); Ssw_CnfNodeAddToSolver( p->pMSat, pNew ); // solve under assumptions // A = 1; B = 0 OR A = 1; B = 1 nLits = 2; pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 ); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase == pNew->fPhase ); if ( p->iOutputLit > -1 ) pLits[nLits++] = p->iOutputLit; if ( p->pPars->fPolarFlip ) { if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] ); } //Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead ) { RetValue = sat_solver_simplify(p->pMSat->pSat); assert( RetValue != 0 ); } clk = clock(); RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); p->timeSat += clock() - clk; if ( RetValue1 == l_False ) { p->timeSatUnsat += clock() - clk; if ( nLits == 2 ) { pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 ); assert( RetValue ); /* if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead ) { RetValue = sat_solver_simplify(p->pMSat->pSat); assert( RetValue != 0 ); } */ } p->nSatCallsUnsat++; } else if ( RetValue1 == l_True ) { p->timeSatSat += clock() - clk; p->nSatCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatUndec += clock() - clk; p->nSatFailsReal++; return -1; } // if the old node was constant 0, we already know the answer if ( pOld == Aig_ManConst1(p->pFrames) ) { p->nSatProof++; return 1; } // solve under assumptions // A = 0; B = 1 OR A = 0; B = 0 nLits = 2; pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 ); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase ^ pNew->fPhase ); if ( p->iOutputLit > -1 ) pLits[nLits++] = p->iOutputLit; if ( p->pPars->fPolarFlip ) { if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] ); } if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead ) { RetValue = sat_solver_simplify(p->pMSat->pSat); assert( RetValue != 0 ); } clk = clock(); RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); p->timeSat += clock() - clk; if ( RetValue1 == l_False ) { p->timeSatUnsat += clock() - clk; if ( nLits == 2 ) { pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 ); assert( RetValue ); /* if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead ) { RetValue = sat_solver_simplify(p->pMSat->pSat); assert( RetValue != 0 ); } */ } p->nSatCallsUnsat++; } else if ( RetValue1 == l_True ) { p->timeSatSat += clock() - clk; p->nSatCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatUndec += clock() - clk; p->nSatFailsReal++; return -1; } // return SAT proof p->nSatProof++; return 1; }
/**Function************************************************************* Synopsis [Constrains two nodes to be equivalent in the SAT solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) { int pLits[2], RetValue, fComplNew; Aig_Obj_t * pTemp; // sanity checks assert( Aig_Regular(pOld) != Aig_Regular(pNew) ); assert( p->pPars->fConstrs || Aig_ObjPhaseReal(pOld) == Aig_ObjPhaseReal(pNew) ); // move constant to the old node if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) ) { assert( Aig_Regular(pOld) != Aig_ManConst1(p->pFrames) ); pTemp = pOld; pOld = pNew; pNew = pTemp; } // move complement to the new node if ( Aig_IsComplement(pOld) ) { pOld = Aig_Regular(pOld); pNew = Aig_Not(pNew); } assert( p->pMSat != NULL ); // if the nodes do not have SAT variables, allocate them Ssw_CnfNodeAddToSolver( p->pMSat, pOld ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pNew) ); // transform the new node fComplNew = Aig_IsComplement( pNew ); pNew = Aig_Regular( pNew ); // consider the constant 1 case if ( pOld == Aig_ManConst1(p->pFrames) ) { // add constraint A = 1 ----> A pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew ); if ( p->pPars->fPolarFlip ) { if ( pNew->fPhase ) pLits[0] = lit_neg( pLits[0] ); } RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 1 ); assert( RetValue ); } else { // add constraint A = B ----> (A v !B)(!A v B) // (A v !B) pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 ); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), !fComplNew ); if ( p->pPars->fPolarFlip ) { if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] ); } pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 ); assert( RetValue ); // (!A v B) pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 ); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew); if ( p->pPars->fPolarFlip ) { if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] ); } pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 ); assert( RetValue ); } return 1; }
/**Function************************************************************* Synopsis [Addes clauses to the solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static void Gia_ManAddClausesMux( Ssc_Man_t * p, Gia_Obj_t * pNode ) { Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; int pLits[4], LitF, LitI, LitT, LitE, RetValue; assert( !Gia_IsComplement( pNode ) ); assert( Gia_ObjIsMuxType( pNode ) ); // get nodes (I = if, T = then, E = else) pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); // get the Litiable numbers LitF = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNode) ); LitI = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNodeI) ); LitT = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNodeT) ); LitE = Ssc_ObjSatLit( p, Gia_Obj2Lit(p->pFraig,pNodeE) ); // f = ITE(i, t, e) // i' + t' + f // i' + t + f' // i + e' + f // i + e + f' // create four clauses pLits[0] = Abc_LitNotCond(LitI, 1); pLits[1] = Abc_LitNotCond(LitT, 1); pLits[2] = Abc_LitNotCond(LitF, 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitI, 1); pLits[1] = Abc_LitNotCond(LitT, 0); pLits[2] = Abc_LitNotCond(LitF, 1); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitI, 0); pLits[1] = Abc_LitNotCond(LitE, 1); pLits[2] = Abc_LitNotCond(LitF, 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitI, 0); pLits[1] = Abc_LitNotCond(LitE, 0); pLits[2] = Abc_LitNotCond(LitF, 1); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); // two additional clauses // t' & e' -> f' // t & e -> f // t + e + f' // t' + e' + f if ( LitT == LitE ) { // assert( fCompT == !fCompE ); return; } pLits[0] = Abc_LitNotCond(LitT, 0); pLits[1] = Abc_LitNotCond(LitE, 0); pLits[2] = Abc_LitNotCond(LitF, 1); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); pLits[0] = Abc_LitNotCond(LitT, 1); pLits[1] = Abc_LitNotCond(LitE, 1); pLits[2] = Abc_LitNotCond(LitF, 0); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); assert( RetValue ); }
/**Function************************************************************* Synopsis [Runs equivalence test for one node.] Description [Returns the fraiged node.] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_NodeIsConst( Fra_Man_t * p, Aig_Obj_t * pNew ) { int pLits[2], RetValue1, RetValue, clk; // make sure the nodes are not complemented assert( !Aig_IsComplement(pNew) ); assert( pNew != p->pManFraig->pConst1 ); p->nSatCalls++; // make sure the solver is allocated and has enough variables if ( p->pSat == NULL ) { p->pSat = sat_solver_new(); p->nSatVars = 1; sat_solver_setnvars( p->pSat, 1000 ); } // if the nodes do not have SAT variables, allocate them Fra_NodeAddToSolver( p, NULL, pNew ); // prepare variable activity if ( p->pPars->fConeBias ) Fra_SetActivityFactors( p, NULL, pNew ); // solve under assumptions clk = clock(); pLits[0] = toLitCond( Fra_ObjSatNum(pNew), pNew->fPhase ); RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 1, (sint64)p->pPars->nBTLimitMiter, (sint64)0, p->nBTLimitGlobal, p->nInsLimitGlobal ); p->timeSat += clock() - clk; if ( RetValue1 == l_False ) { p->timeSatUnsat += clock() - clk; pLits[0] = lit_neg( pLits[0] ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 ); assert( RetValue ); // continue solving the other implication p->nSatCallsUnsat++; } else if ( RetValue1 == l_True ) { p->timeSatSat += clock() - clk; if ( p->pPatWords ) Fra_SavePattern( p ); p->nSatCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatFail += clock() - clk; // mark the node as the failed node pNew->fMarkB = 1; p->nSatFailsReal++; return -1; } // return SAT proof p->nSatProof++; return 1; }
/**Function************************************************************* Synopsis [Runs equivalence test for the two nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) { int pLits[4], RetValue, RetValue1, nBTLimit, clk, clk2 = clock(); int status; // make sure the nodes are not complemented assert( !Aig_IsComplement(pNew) ); assert( !Aig_IsComplement(pOld) ); assert( pNew != pOld ); // if at least one of the nodes is a failed node, perform adjustments: // if the backtrack limit is small, simply skip this node // if the backtrack limit is > 10, take the quare root of the limit nBTLimit = p->pPars->nBTLimitNode; if ( !p->pPars->fSpeculate && p->pPars->nFramesK == 0 && (nBTLimit > 0 && (pOld->fMarkB || pNew->fMarkB)) ) { p->nSatFails++; // fail immediately // return -1; if ( nBTLimit <= 10 ) return -1; nBTLimit = (int)pow(nBTLimit, 0.7); } p->nSatCalls++; // make sure the solver is allocated and has enough variables if ( p->pSat == NULL ) { p->pSat = sat_solver_new(); p->nSatVars = 1; sat_solver_setnvars( p->pSat, 1000 ); } // if the nodes do not have SAT variables, allocate them Fra_NodeAddToSolver( p, pOld, pNew ); if ( p->pSat->qtail != p->pSat->qhead ) { status = sat_solver_simplify(p->pSat); assert( status != 0 ); assert( p->pSat->qtail == p->pSat->qhead ); } // prepare variable activity if ( p->pPars->fConeBias ) Fra_SetActivityFactors( p, pOld, pNew ); // solve under assumptions // A = 1; B = 0 OR A = 1; B = 1 clk = clock(); pLits[0] = toLitCond( Fra_ObjSatNum(pOld), 0 ); pLits[1] = toLitCond( Fra_ObjSatNum(pNew), pOld->fPhase == pNew->fPhase ); //Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2, (sint64)nBTLimit, (sint64)0, p->nBTLimitGlobal, p->nInsLimitGlobal ); p->timeSat += clock() - clk; if ( RetValue1 == l_False ) { p->timeSatUnsat += clock() - clk; pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); // continue solving the other implication p->nSatCallsUnsat++; } else if ( RetValue1 == l_True ) { p->timeSatSat += clock() - clk; Fra_SavePattern( p ); p->nSatCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatFail += clock() - clk; // mark the node as the failed node if ( pOld != p->pManFraig->pConst1 ) pOld->fMarkB = 1; pNew->fMarkB = 1; p->nSatFailsReal++; return -1; } // if the old node was constant 0, we already know the answer if ( pOld == p->pManFraig->pConst1 ) { p->nSatProof++; return 1; } // solve under assumptions // A = 0; B = 1 OR A = 0; B = 0 clk = clock(); pLits[0] = toLitCond( Fra_ObjSatNum(pOld), 1 ); pLits[1] = toLitCond( Fra_ObjSatNum(pNew), pOld->fPhase ^ pNew->fPhase ); RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2, (sint64)nBTLimit, (sint64)0, p->nBTLimitGlobal, p->nInsLimitGlobal ); p->timeSat += clock() - clk; if ( RetValue1 == l_False ) { p->timeSatUnsat += clock() - clk; pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); p->nSatCallsUnsat++; } else if ( RetValue1 == l_True ) { p->timeSatSat += clock() - clk; Fra_SavePattern( p ); p->nSatCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatFail += clock() - clk; // mark the node as the failed node pOld->fMarkB = 1; pNew->fMarkB = 1; p->nSatFailsReal++; return -1; } /* // check BDD proof { int RetVal; PRT( "Sat", clock() - clk2 ); clk2 = clock(); RetVal = Fra_NodesAreEquivBdd( pOld, pNew ); // printf( "%d ", RetVal ); assert( RetVal ); PRT( "Bdd", clock() - clk2 ); printf( "\n" ); } */ // return SAT proof p->nSatProof++; return 1; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Runs equivalence test for the two nodes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Dch_NodesAreEquiv( Dch_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) { int nBTLimit = p->pPars->nBTLimit; int pLits[2], RetValue, RetValue1, status, clk; p->nSatCalls++; // sanity checks assert( !Aig_IsComplement(pNew) ); assert( !Aig_IsComplement(pOld) ); assert( pNew != pOld ); p->nCallsSince++; // experiment with this!!! // check if SAT solver needs recycling if ( p->pSat == NULL || (p->pPars->nSatVarMax && p->nSatVars > p->pPars->nSatVarMax && p->nCallsSince > p->pPars->nCallsRecycle) ) Dch_ManSatSolverRecycle( p ); // if the nodes do not have SAT variables, allocate them Dch_CnfNodeAddToSolver( p, pOld ); Dch_CnfNodeAddToSolver( p, pNew ); // propage unit clauses if ( p->pSat->qtail != p->pSat->qhead ) { status = sat_solver_simplify(p->pSat); assert( status != 0 ); assert( p->pSat->qtail == p->pSat->qhead ); } // solve under assumptions // A = 1; B = 0 OR A = 1; B = 1 pLits[0] = toLitCond( Dch_ObjSatNum(p,pOld), 0 ); pLits[1] = toLitCond( Dch_ObjSatNum(p,pNew), pOld->fPhase == pNew->fPhase ); if ( p->pPars->fPolarFlip ) { if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] ); } //Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); clk = clock(); RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); p->timeSat += clock() - clk; if ( RetValue1 == l_False ) { p->timeSatUnsat += clock() - clk; pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); p->nSatCallsUnsat++; } else if ( RetValue1 == l_True ) { p->timeSatSat += clock() - clk; p->nSatCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatUndec += clock() - clk; p->nSatFailsReal++; return -1; } // if the old node was constant 0, we already know the answer if ( pOld == Aig_ManConst1(p->pAigFraig) ) { p->nSatProof++; return 1; } // solve under assumptions // A = 0; B = 1 OR A = 0; B = 0 pLits[0] = toLitCond( Dch_ObjSatNum(p,pOld), 1 ); pLits[1] = toLitCond( Dch_ObjSatNum(p,pNew), pOld->fPhase ^ pNew->fPhase ); if ( p->pPars->fPolarFlip ) { if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] ); } clk = clock(); RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2, (ABC_INT64_T)nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); p->timeSat += clock() - clk; if ( RetValue1 == l_False ) { p->timeSatUnsat += clock() - clk; pLits[0] = lit_neg( pLits[0] ); pLits[1] = lit_neg( pLits[1] ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); assert( RetValue ); p->nSatCallsUnsat++; } else if ( RetValue1 == l_True ) { p->timeSatSat += clock() - clk; p->nSatCallsSat++; return 0; } else // if ( RetValue1 == l_Undef ) { p->timeSatUndec += clock() - clk; p->nSatFailsReal++; return -1; } // return SAT proof p->nSatProof++; return 1; }