// solve incremental SAT problems Aig_ManForEachCo( pManOn, pObj, i ) { pObj2 = Aig_ManCo( pManOff, i ); Lits[0] = toLitCond( pCnfOn->pVarNums[pObj->Id], 0 ); Lits[1] = toLitCond( pCnfOff->pVarNums[pObj2->Id], 0 ); status = sat_solver_solve( pSat, Lits, Lits+2, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); if ( status != l_False ) printf( "The incremental SAT problem is not UNSAT.\n" ); }
/**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 ); }
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 ); }
// add A & B => C or !A + !B + C Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) { pLits[i] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); if ( p->pPars->fPolarFlip ) { if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] ); } }
/**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 [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 ); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Adds buffer to the solver.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Aig_ManInterAddBuffer( sat_solver2 * pSat, int iVarA, int iVarB, int fCompl, int fMark ) { lit Lits[2]; int Cid; assert( iVarA >= 0 && iVarB >= 0 ); Lits[0] = toLitCond( iVarA, 0 ); Lits[1] = toLitCond( iVarB, !fCompl ); Cid = sat_solver2_addclause( pSat, Lits, Lits + 2, 0 ); if ( fMark ) clause2_set_partA( pSat, Cid, 1 ); Lits[0] = toLitCond( iVarA, 1 ); Lits[1] = toLitCond( iVarB, fCompl ); Cid = sat_solver2_addclause( pSat, Lits, Lits + 2, 0 ); if ( fMark ) clause2_set_partA( pSat, Cid, 1 ); }
/**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 [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; }
int Saig_ManFilterUsingIndOne2( Aig_Man_t * p, Aig_Man_t * pFrame, sat_solver * pSat, Cnf_Dat_t * pCnf, int nConfs, int nProps, int Counter , int type_ /* jlong -- */ ) { Aig_Obj_t * pObj; int Lit, status; pObj = Aig_ManCo( pFrame, Counter*3+type_ ); /* which co */ Lit = toLitCond( pCnf->pVarNums[Aig_ObjId(pObj)], 0 ); status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfs, 0, 0, 0 ); if ( status == l_False ) /* unsat */ return status; if ( status == l_Undef ) { printf( "Solver returned undecided.\n" ); return status; } assert( status == l_True ); return status; }
/**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 [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) ); }
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 [] 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 [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; }
/**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 [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 ); }
/**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 ); }
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; }
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 ); } // add A & B => C or !A + !B + C Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) { pLits[i] = toLitCond(Cec_ObjSatNum(p,Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); if ( p->pPars->fPolarFlip ) { if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] ); } } pLits[nLits-1] = toLitCond(Cec_ObjSatNum(p,pNode), 0); if ( p->pPars->fPolarFlip ) { if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] ); } RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits ); assert( RetValue ); ABC_FREE( pLits ); } /**Function************************************************************* Synopsis [Collects the supergate.] Description []
/**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 [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 [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 ); }
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 [Adds constraints for the two-input AND-gate.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Aig_ManInterAddXor( sat_solver2 * pSat, int iVarA, int iVarB, int iVarC, int fCompl, int fMark ) { lit Lits[3]; int Cid; assert( iVarA >= 0 && iVarB >= 0 && iVarC >= 0 ); Lits[0] = toLitCond( iVarA, !fCompl ); Lits[1] = toLitCond( iVarB, 1 ); Lits[2] = toLitCond( iVarC, 1 ); Cid = sat_solver2_addclause( pSat, Lits, Lits + 3, 0 ); if ( fMark ) clause2_set_partA( pSat, Cid, 1 ); Lits[0] = toLitCond( iVarA, !fCompl ); Lits[1] = toLitCond( iVarB, 0 ); Lits[2] = toLitCond( iVarC, 0 ); Cid = sat_solver2_addclause( pSat, Lits, Lits + 3, 0 ); if ( fMark ) clause2_set_partA( pSat, Cid, 1 ); Lits[0] = toLitCond( iVarA, fCompl ); Lits[1] = toLitCond( iVarB, 1 ); Lits[2] = toLitCond( iVarC, 0 ); Cid = sat_solver2_addclause( pSat, Lits, Lits + 3, 0 ); if ( fMark ) clause2_set_partA( pSat, Cid, 1 ); Lits[0] = toLitCond( iVarA, fCompl ); Lits[1] = toLitCond( iVarB, 0 ); Lits[2] = toLitCond( iVarC, 1 ); Cid = sat_solver2_addclause( pSat, Lits, Lits + 3, 0 ); if ( fMark ) clause2_set_partA( pSat, Cid, 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; }