/**Function************************************************************* Synopsis [Determine starting cut-points.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Llb_ManMarkPivotNodes( Aig_Man_t * p, int fUseInternal ) { Vec_Int_t * vVar2Obj; Aig_Obj_t * pObj; int i; // mark inputs/outputs Aig_ManForEachPi( p, pObj, i ) pObj->fMarkA = 1; Saig_ManForEachLi( p, pObj, i ) pObj->fMarkA = 1; // mark internal pivot nodes if ( fUseInternal ) Llb_ManMarkInternalPivots( p ); // assign variable numbers Aig_ManConst1(p)->fMarkA = 0; vVar2Obj = Vec_IntAlloc( 100 ); Aig_ManForEachPi( p, pObj, i ) Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); Aig_ManForEachNode( p, pObj, i ) if ( pObj->fMarkA ) Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); Saig_ManForEachLi( p, pObj, i ) Vec_IntPush( vVar2Obj, Aig_ObjId(pObj) ); return vVar2Obj; }
/**Function************************************************************* Synopsis [Returns the probability of POs being 1 under rand seq sim.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_ManProfileConstraints( Aig_Man_t * p, int nWords, int nFrames, int fVerbose ) { Vec_Ptr_t * vInfo; Vec_Int_t * vProbs, * vProbs2; Aig_Obj_t * pObj, * pObjLi; unsigned * pInfo, * pInfo0, * pInfo1, * pInfoMask, * pInfoMask2; int i, w, f, RetValue = 1, clk = clock(); if ( fVerbose ) printf( "Simulating %d nodes and %d flops for %d frames with %d words... ", Aig_ManNodeNum(p), Aig_ManRegNum(p), nFrames, nWords ); Aig_ManRandom( 1 ); vInfo = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p)+2, nWords ); Vec_PtrCleanSimInfo( vInfo, 0, nWords ); vProbs = Vec_IntStart( Saig_ManPoNum(p) ); vProbs2 = Vec_IntStart( Saig_ManPoNum(p) ); // start the constant pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(Aig_ManConst1(p)) ); for ( w = 0; w < nWords; w++ ) pInfo[w] = ~0; // start the flop inputs Saig_ManForEachLi( p, pObj, i ) { pInfo = (unsigned *)Vec_PtrEntry( vInfo, Aig_ObjId(pObj) ); for ( w = 0; w < nWords; w++ ) pInfo[w] = 0; }
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 [Returns array of NS variables.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Llb_DriverCollectNs( Aig_Man_t * pAig, Vec_Int_t * vDriRefs ) { Vec_Int_t * vVars; Aig_Obj_t * pObj, * pDri; int i; vVars = Vec_IntAlloc( Aig_ManRegNum(pAig) ); Saig_ManForEachLi( pAig, pObj, i ) { pDri = Aig_ObjFanin0(pObj); if ( Vec_IntEntry( vDriRefs, Aig_ObjId(pDri) ) != 1 || Saig_ObjIsPi(pAig, pDri) || Aig_ObjIsConst1(pDri) ) Vec_IntPush( vVars, Aig_ObjId(pObj) ); else Vec_IntPush( vVars, Aig_ObjId(pDri) ); }
/**Function************************************************************* Synopsis [Returns the array of constraint candidates.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Llb_ManComputeIndCase( Aig_Man_t * p, DdManager * dd, Vec_Int_t * vNodes ) { Vec_Ptr_t * vBdds; Aig_Obj_t * pObj; DdNode * bFunc; int i, Entry; vBdds = Vec_PtrStart( Aig_ManObjNumMax(p) ); bFunc = Cudd_ReadOne(dd); Cudd_Ref( bFunc ); Vec_PtrWriteEntry( vBdds, Aig_ObjId(Aig_ManConst1(p)), bFunc ); Saig_ManForEachPi( p, pObj, i ) { bFunc = Cudd_bddIthVar( dd, Aig_ManPiNum(p) + i ); Cudd_Ref( bFunc ); Vec_PtrWriteEntry( vBdds, Aig_ObjId(pObj), bFunc ); }
/**Function************************************************************* Synopsis [Procedure used for sorting the nodes in decreasing order of levels.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Aig_NodeCompareLevelsDecrease( Aig_Obj_t ** pp1, Aig_Obj_t ** pp2 ) { int Diff = Aig_ObjLevel(Aig_Regular(*pp1)) - Aig_ObjLevel(Aig_Regular(*pp2)); if ( Diff > 0 ) return -1; if ( Diff < 0 ) return 1; Diff = Aig_ObjId(Aig_Regular(*pp1)) - Aig_ObjId(Aig_Regular(*pp2)); if ( Diff > 0 ) return -1; if ( Diff < 0 ) return 1; return 0; }
/**Function************************************************************* Synopsis [Transforms sequential AIG into dual-rail miter.] Description [Transforms sequential AIG into a miter encoding ternary problem formulated as follows "none of the POs has a ternary value". Interprets the first nDualPis as having ternary value. Sets flops to have ternary intial value when fDualFfs is set to 1.] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Saig_ManDupDual( Aig_Man_t * pAig, Vec_Int_t * vDcFlops, int nDualPis, int fDualFfs, int fMiterFfs, int fComplPo, int fCheckZero, int fCheckOne ) { Vec_Ptr_t * vCopies; Aig_Man_t * pAigNew; Aig_Obj_t * pObj, * pTemp0, * pTemp1, * pTemp2, * pTemp3, * pCare, * pMiter; int i; assert( Saig_ManPoNum(pAig) > 0 ); assert( nDualPis >= 0 && nDualPis <= Saig_ManPiNum(pAig) ); assert( vDcFlops == NULL || Vec_IntSize(vDcFlops) == Aig_ManRegNum(pAig) ); vCopies = Vec_PtrStart( 2*Aig_ManObjNum(pAig) ); // start the new manager pAigNew = Aig_ManStart( Aig_ManNodeNum(pAig) ); pAigNew->pName = Abc_UtilStrsav( pAig->pName ); // map the constant node Saig_ObjSetDual( vCopies, 0, 0, Aig_ManConst0(pAigNew) ); Saig_ObjSetDual( vCopies, 0, 1, Aig_ManConst1(pAigNew) ); // create variables for PIs Aig_ManForEachCi( pAig, pObj, i ) { if ( i < nDualPis ) { pTemp0 = Aig_ObjCreateCi( pAigNew ); pTemp1 = Aig_ObjCreateCi( pAigNew ); } else if ( i < Saig_ManPiNum(pAig) ) { pTemp1 = Aig_ObjCreateCi( pAigNew ); pTemp0 = Aig_Not( pTemp1 ); } else { pTemp0 = Aig_ObjCreateCi( pAigNew ); pTemp1 = Aig_ObjCreateCi( pAigNew ); if ( vDcFlops ) pTemp0 = Aig_NotCond( pTemp0, !Vec_IntEntry(vDcFlops, i-Saig_ManPiNum(pAig)) ); else pTemp0 = Aig_NotCond( pTemp0, !fDualFfs ); } Saig_ObjSetDual( vCopies, Aig_ObjId(pObj), 0, Aig_And(pAigNew, pTemp0, Aig_Not(pTemp1)) ); Saig_ObjSetDual( vCopies, Aig_ObjId(pObj), 1, Aig_And(pAigNew, pTemp1, Aig_Not(pTemp0)) ); } // create internal nodes Aig_ManForEachNode( pAig, pObj, i ) { Saig_ObjDualFanin( pAigNew, vCopies, pObj, 0, &pTemp0, &pTemp1 ); Saig_ObjDualFanin( pAigNew, vCopies, pObj, 1, &pTemp2, &pTemp3 ); Saig_ObjSetDual( vCopies, Aig_ObjId(pObj), 0, Aig_Or (pAigNew, pTemp0, pTemp2) ); Saig_ObjSetDual( vCopies, Aig_ObjId(pObj), 1, Aig_And(pAigNew, pTemp1, pTemp3) ); }
/**Function************************************************************* Synopsis [Returns the array of constraint candidates.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Llb_ManComputeIndCase_rec( Aig_Man_t * p, Aig_Obj_t * pObj, DdManager * dd, Vec_Ptr_t * vBdds ) { DdNode * bBdd0, * bBdd1; DdNode * bFunc = (DdNode *)Vec_PtrEntry( vBdds, Aig_ObjId(pObj) ); if ( bFunc != NULL ) return bFunc; assert( Aig_ObjIsNode(pObj) ); bBdd0 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin0(pObj), dd, vBdds ); bBdd1 = Llb_ManComputeIndCase_rec( p, Aig_ObjFanin1(pObj), dd, vBdds ); bBdd0 = Cudd_NotCond( bBdd0, Aig_ObjFaninC0(pObj) ); bBdd1 = Cudd_NotCond( bBdd1, Aig_ObjFaninC1(pObj) ); bFunc = Cudd_bddAnd( dd, bBdd0, bBdd1 ); Cudd_Ref( bFunc ); Vec_PtrWriteEntry( vBdds, Aig_ObjId(pObj), bFunc ); return bFunc; }
static inline void Saig_ManSimInfoSet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame, int Value ) { unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); assert( Value >= SAIG_ZER && Value <= SAIG_UND ); Value ^= Saig_ManSimInfoGet( vSimInfo, pObj, iFrame ); pInfo[iFrame >> 4] ^= (Value << ((iFrame & 15) << 1)); }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// /* The CNF (p->pCnf2) is expressed in terms of object IDs. Each node in the CNF is marked if it has clauses (p->pCnf2->pObj2Count[Id] > 0). Each node in the CNF has the first clause (p->pCnf2->pObj2Clause) and the number of clauses (p->pCnf2->pObj2Count). Each node used in a CNF of any timeframe has its SAT var recorded. Each frame has a reserve mapping of SAT variables into ObjIds. */ //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Returns SAT variable of the given object.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Pdr_ObjSatVar1( Pdr_Man_t * p, int k, Aig_Obj_t * pObj ) { return p->pCnf1->pVarNums[ Aig_ObjId(pObj) ]; }
/**Function************************************************************* Synopsis [Returns 1 if simulation does not filter out this candidate.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Cgt_SimulationFilter( Cgt_Man_t * p, Aig_Obj_t * pCandPart, Aig_Obj_t * pMiterPart ) { unsigned * pInfoCand, * pInfoMiter; int w, nWords = Aig_BitWordNum( p->nPatts ); pInfoCand = (unsigned *)Vec_PtrEntry( p->vPatts, Aig_ObjId(Aig_Regular(pCandPart)) ); pInfoMiter = (unsigned *)Vec_PtrEntry( p->vPatts, Aig_ObjId(pMiterPart) ); // C => !M -- true is the same as C & M -- false if ( !Aig_IsComplement(pCandPart) ) { for ( w = 0; w < nWords; w++ ) if ( pInfoCand[w] & pInfoMiter[w] ) return 0; } else { for ( w = 0; w < nWords; w++ ) if ( ~pInfoCand[w] & pInfoMiter[w] ) return 0; } return 1; }
/**Function************************************************************* Synopsis [Partitioning using levelized order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Aig_ManPartitionLevelized( Aig_Man_t * p, int nPartSize ) { Vec_Int_t * vId2Part; Vec_Vec_t * vNodes; Aig_Obj_t * pObj; int i, k, Counter = 0; vNodes = Aig_ManLevelize( p ); vId2Part = Vec_IntStart( Aig_ManObjNumMax(p) ); Vec_VecForEachEntryReverseReverse( Aig_Obj_t *, vNodes, pObj, i, k ) Vec_IntWriteEntry( vId2Part, Aig_ObjId(pObj), Counter++/nPartSize ); Vec_VecFree( vNodes ); return vId2Part; }
/**Function************************************************************* Synopsis [Performs fraiging for one node.] Description [Returns the fraiged node.] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_ManSetConstrPhases_( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits ) { Vec_Int_t * vLits; sat_solver * pSat; Cnf_Dat_t * pCnf; Aig_Obj_t * pObj; int i, f, iVar, RetValue, nRegs; if ( pvInits ) *pvInits = NULL; assert( p->nConstrs > 0 ); // create CNF nRegs = p->nRegs; p->nRegs = 0; pCnf = Cnf_Derive( p, Aig_ManCoNum(p) ); p->nRegs = nRegs; // create SAT solver pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, nFrames, 0 ); assert( pSat->size == nFrames * pCnf->nVars ); // collect constraint literals vLits = Vec_IntAlloc( 100 ); Saig_ManForEachLo( p, pObj, i ) { assert( pCnf->pVarNums[Aig_ObjId(pObj)] >= 0 ); Vec_IntPush( vLits, toLitCond(pCnf->pVarNums[Aig_ObjId(pObj)], 1) ); }
/**Function************************************************************* Synopsis [Partitioning using DFS order.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Aig_ManPartitionDfs( Aig_Man_t * p, int nPartSize, int fPreorder ) { Vec_Int_t * vId2Part; Vec_Ptr_t * vNodes; Aig_Obj_t * pObj; int i, Counter = 0; vId2Part = Vec_IntStart( Aig_ManObjNumMax(p) ); if ( fPreorder ) { vNodes = Aig_ManDfsPreorder( p, 1 ); Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Vec_IntWriteEntry( vId2Part, Aig_ObjId(pObj), Counter++/nPartSize ); } else {
/**Function************************************************************* Synopsis [Finds one satisfiable assignment of the timeframes.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Ssw_ManSetConstrPhases( Aig_Man_t * p, int nFrames, Vec_Int_t ** pvInits ) { Aig_Man_t * pFrames; sat_solver * pSat; Cnf_Dat_t * pCnf; Aig_Obj_t * pObj; int i, RetValue; if ( pvInits ) *pvInits = NULL; // assert( p->nConstrs > 0 ); // derive the timeframes pFrames = Ssw_FramesWithConstraints( p, nFrames ); // create CNF pCnf = Cnf_Derive( pFrames, 0 ); // create SAT solver pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); if ( pSat == NULL ) { Cnf_DataFree( pCnf ); Aig_ManStop( pFrames ); return 1; } // solve RetValue = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)1000000, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 ); if ( RetValue == l_True && pvInits ) { *pvInits = Vec_IntAlloc( 1000 ); Aig_ManForEachCi( pFrames, pObj, i ) Vec_IntPush( *pvInits, sat_solver_var_value(pSat, pCnf->pVarNums[Aig_ObjId(pObj)]) ); // Aig_ManForEachCi( pFrames, pObj, i ) // Abc_Print( 1, "%d", Vec_IntEntry(*pvInits, i) ); // Abc_Print( 1, "\n" ); } sat_solver_delete( pSat ); Cnf_DataFree( pCnf ); Aig_ManStop( pFrames ); if ( RetValue == l_False ) return 1; if ( RetValue == l_True ) return 0; return -1; }
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; }
ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ char * Saig_ObjName( Aig_Man_t * p, Aig_Obj_t * pObj ) { static char Buffer[16]; if ( Aig_ObjIsNode(pObj) || Aig_ObjIsConst1(pObj) ) sprintf( Buffer, "n%0*d", Aig_Base10Log(Aig_ManObjNumMax(p)), Aig_ObjId(pObj) ); else if ( Saig_ObjIsPi(p, pObj) ) sprintf( Buffer, "pi%0*d", Aig_Base10Log(Saig_ManPiNum(p)), Aig_ObjPioNum(pObj) ); else if ( Saig_ObjIsPo(p, pObj) ) sprintf( Buffer, "po%0*d", Aig_Base10Log(Saig_ManPoNum(p)), Aig_ObjPioNum(pObj) ); else if ( Saig_ObjIsLo(p, pObj) ) sprintf( Buffer, "lo%0*d", Aig_Base10Log(Saig_ManRegNum(p)), Aig_ObjPioNum(pObj) - Saig_ManPiNum(p) ); else if ( Saig_ObjIsLi(p, pObj) ) sprintf( Buffer, "li%0*d", Aig_Base10Log(Saig_ManRegNum(p)), Aig_ObjPioNum(pObj) - Saig_ManPoNum(p) ); else assert( 0 ); return Buffer; }
/**Function************************************************************* Synopsis [Create mapping of node IDs of pNtk into equiv classes of pMiter.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Abc_NtkDressMapClasses( Aig_Man_t * pMiter, Abc_Ntk_t * pNtk ) { Vec_Int_t * vId2Lit; Abc_Obj_t * pObj, * pAnd; Aig_Obj_t * pObjMan, * pObjMiter, * pObjRepr; int i; vId2Lit = Vec_IntAlloc( 0 ); Vec_IntFill( vId2Lit, Abc_NtkObjNumMax(pNtk), -1 ); Abc_NtkForEachNode( pNtk, pObj, i ) { // get the pointer to the miter node corresponding to pObj if ( (pAnd = Abc_ObjRegular(pObj->pCopy)) && Abc_ObjType(pAnd) != ABC_OBJ_NONE && // strashed node is present and legal (pObjMan = Aig_Regular((Aig_Obj_t *)pAnd->pCopy)) && Aig_ObjType(pObjMan) != AIG_OBJ_NONE && // AIG node is present and legal (pObjMiter = Aig_Regular((Aig_Obj_t *)pObjMan->pData)) && Aig_ObjType(pObjMiter) != AIG_OBJ_NONE ) // miter node is present and legal { // get the representative of the miter node pObjRepr = Aig_ObjRepr( pMiter, pObjMiter ); pObjRepr = pObjRepr? pObjRepr : pObjMiter; // map pObj (whose ID is i) into the repr node ID (i.e. equiv class) Vec_IntWriteEntry( vId2Lit, i, Aig_ObjId(pObjRepr) ); } } return vId2Lit; }
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; } }
Saig_ManForEachLi( p, pObj, i ) { bFunc = (DdNode *)pObj->pData; Cudd_Ref( bFunc ); Vec_PtrWriteEntry( vBdds, Aig_ObjId(Saig_ObjLiToLo(p, pObj)), bFunc ); }
Vec_Int_t * vId2Part; Vec_Ptr_t * vNodes; Aig_Obj_t * pObj; int i, Counter = 0; vId2Part = Vec_IntStart( Aig_ManObjNumMax(p) ); if ( fPreorder ) { vNodes = Aig_ManDfsPreorder( p, 1 ); Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i ) Vec_IntWriteEntry( vId2Part, Aig_ObjId(pObj), Counter++/nPartSize ); } else { vNodes = Aig_ManDfs( p, 1 ); Vec_PtrForEachEntryReverse( Aig_Obj_t *, vNodes, pObj, i ) Vec_IntWriteEntry( vId2Part, Aig_ObjId(pObj), Counter++/nPartSize ); } Vec_PtrFree( vNodes ); return vId2Part; } /**Function************************************************************* Synopsis [Recursively constructs the partition.] Description [] SideEffects [] SeeAlso []
static inline int Saig_ManSimInfoGet( Vec_Ptr_t * vSimInfo, Aig_Obj_t * pObj, int iFrame ) { unsigned * pInfo = (unsigned *)Vec_PtrEntry( vSimInfo, Aig_ObjId(pObj) ); return 3 & (pInfo[iFrame >> 4] >> ((iFrame & 15) << 1)); }
static inline int Saig_ManBmcSimInfoGet( unsigned * pInfo, Aig_Obj_t * pObj ) { return 3 & (pInfo[Aig_ObjId(pObj) >> 4] >> ((Aig_ObjId(pObj) & 15) << 1)); }
/**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] ); } }
static inline void Saig_ManBmcSimInfoSet( unsigned * pInfo, Aig_Obj_t * pObj, int Value ) { assert( Value >= SAIG_TER_ZER && Value <= SAIG_TER_UND ); Value ^= Saig_ManBmcSimInfoGet( pInfo, pObj ); pInfo[Aig_ObjId(pObj) >> 4] ^= (Value << ((Aig_ObjId(pObj) & 15) << 1)); }