diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2020-11-09 13:24:07 -0800 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2020-11-09 13:24:07 -0800 |
commit | 40bfe2fb88b4a4dc32fa280e66f66dcefb4a4b1d (patch) | |
tree | 7d6e9b334e56967c5867e8d90e4f126a5fb914a1 /src/proof/cec | |
parent | 0b89fd387e71aeaf9595190eac2326a796ff6fc6 (diff) | |
download | abc-40bfe2fb88b4a4dc32fa280e66f66dcefb4a4b1d.tar.gz abc-40bfe2fb88b4a4dc32fa280e66f66dcefb4a4b1d.tar.bz2 abc-40bfe2fb88b4a4dc32fa280e66f66dcefb4a4b1d.zip |
Experiments with SAT sweeping.
Diffstat (limited to 'src/proof/cec')
-rw-r--r-- | src/proof/cec/cecCore.c | 5 | ||||
-rw-r--r-- | src/proof/cec/cecInt.h | 3 | ||||
-rw-r--r-- | src/proof/cec/cecSatG2.c | 1153 | ||||
-rw-r--r-- | src/proof/cec/cecSweep.c | 3 | ||||
-rw-r--r-- | src/proof/cec/module.make | 1 |
5 files changed, 1165 insertions, 0 deletions
diff --git a/src/proof/cec/cecCore.c b/src/proof/cec/cecCore.c index 22b38cb9..1ae34278 100644 --- a/src/proof/cec/cecCore.c +++ b/src/proof/cec/cecCore.c @@ -348,6 +348,8 @@ Gia_Man_t * Cec_ManSatSweeping( Gia_Man_t * pAig, Cec_ParFra_t * pPars, int fSil Cec_ManPat_t * pPat; int i, fTimeOut = 0, nMatches = 0; abctime clk, clk2, clkTotal = Abc_Clock(); + if ( pPars->fVerbose ) + printf( "Simulating %d words for %d rounds. SAT solving with %d conflicts.\n", pPars->nWords, pPars->nRounds, pPars->nBTLimit ); // duplicate AIG and transfer equivalence classes Gia_ManRandom( 1 ); @@ -519,6 +521,9 @@ p->timeSat += Abc_Clock() - clk; } } finalize: + if ( pPars->fVerbose ) + printf( "Performed %d SAT calls: P = %d D = %d F = %d\n", + p->nAllProvedS + p->nAllDisprovedS + p->nAllFailedS, p->nAllProvedS, p->nAllDisprovedS, p->nAllFailedS ); if ( p->pPars->fVerbose && p->pAig ) { Abc_Print( 1, "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", diff --git a/src/proof/cec/cecInt.h b/src/proof/cec/cecInt.h index d93e5e86..d5456897 100644 --- a/src/proof/cec/cecInt.h +++ b/src/proof/cec/cecInt.h @@ -153,6 +153,9 @@ struct Cec_ManFra_t_ int nAllProved; // total number of proved nodes int nAllDisproved; // total number of disproved nodes int nAllFailed; // total number of failed nodes + int nAllProvedS; // total number of proved nodes + int nAllDisprovedS; // total number of disproved nodes + int nAllFailedS; // total number of failed nodes // runtime stats abctime timeSim; // unsat abctime timePat; // unsat diff --git a/src/proof/cec/cecSatG2.c b/src/proof/cec/cecSatG2.c new file mode 100644 index 00000000..2890a364 --- /dev/null +++ b/src/proof/cec/cecSatG2.c @@ -0,0 +1,1153 @@ +/**CFile**************************************************************** + + FileName [cecSatG2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Detection of structural isomorphism.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSatG2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/gia/gia.h" +#include "misc/util/utilTruth.h" +#include "sat/glucose/AbcGlucose.h" +#include "cec.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// sweeping manager +typedef struct Cec4_Par_t_ Cec4_Par_t; +struct Cec4_Par_t_ +{ + int nSimWords; // simulation words + int nSimRounds; // simulation rounds + int nItersMax; // max number of iterations + int nConfLimit; // SAT solver conflict limit + int nSatVarMax; // the max number of SAT variables + int nCallsRecycle; // calls to perform before recycling SAT solver + int fIsMiter; // this is a miter + int fUseCones; // use logic cones + int fVeryVerbose; // verbose stats + int fVerbose; // verbose stats +}; + +// SAT solving manager +typedef struct Cec4_Man_t_ Cec4_Man_t; +struct Cec4_Man_t_ +{ + Cec4_Par_t * pPars; // parameters + Gia_Man_t * pAig; // user's AIG + Gia_Man_t * pNew; // internal AIG + // SAT solving + bmcg_sat_solver* pSat; // SAT solver + Vec_Ptr_t * vFrontier; // CNF construction + Vec_Ptr_t * vFanins; // CNF construction + Vec_Wrd_t * vSims; // CI simulation info + Vec_Int_t * vCexMin; // minimized CEX + Vec_Int_t * vClassUpdates; // updated equiv classes + Vec_Int_t * vCexStamps; // time stamps + int iLastConst; // last const node proved + // statistics + int nPatterns; + int nSatSat; + int nSatUnsat; + int nSatUndec; + int nCallsSince; + int nSimulates; + int nRecycles; + int nConflicts[2][3]; + abctime timeSatSat0; + abctime timeSatUnsat0; + abctime timeSatSat; + abctime timeSatUnsat; + abctime timeSatUndec; + abctime timeSim; + abctime timeRefine; + abctime timeResimGlo; + abctime timeResimLoc; + abctime timeStart; +}; + +static inline int Cec4_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopy2Array(p, Gia_ObjId(p, pObj)); } +static inline int Cec4_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec4_ObjSatId(p, pObj) == -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), Num); Vec_IntPush(&p->vSuppVars, Gia_ObjId(p, pObj)); if ( Gia_ObjIsCi(pObj) ) Vec_IntPushTwo(&p->vCopiesTwo, Gia_ObjId(p, pObj), Num); return Num; } +static inline void Cec4_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec4_ObjSatId(p, pObj) != -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), -1); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets parameter defaults.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec4_SetDefaultParams( Cec4_Par_t * p ) +{ + memset( p, 0, sizeof(Cec4_Par_t) ); + p->nSimWords = 4; // simulation words + p->nSimRounds = 250; // simulation rounds + p->nItersMax = 10; // max number of iterations + p->nConfLimit = 1000; // conflict limit at a node + p->nSatVarMax = 1000; // the max number of SAT variables before recycling SAT solver + p->nCallsRecycle = 200; // calls to perform before recycling SAT solver + p->fIsMiter = 0; // this is a miter + p->fUseCones = 0; // use logic cones + p->fVeryVerbose = 0; // verbose stats + p->fVerbose = 0; // verbose stats +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec4_Man_t * Cec4_ManCreate( Gia_Man_t * pAig, Cec4_Par_t * pPars ) +{ + Cec4_Man_t * p; + Gia_Obj_t * pObj; int i; + //assert( Gia_ManRegNum(pAig) == 0 ); + p = ABC_CALLOC( Cec4_Man_t, 1 ); + memset( p, 0, sizeof(Cec4_Man_t) ); + p->timeStart = Abc_Clock(); + p->pPars = pPars; + p->pAig = pAig; + pAig->pData = p->pSat; // point AIG manager to the solver + // create new manager + p->pNew = Gia_ManStart( Gia_ManObjNum(pAig) ); + Gia_ManFillValue( pAig ); + Gia_ManConst0(pAig)->Value = 0; + Gia_ManForEachCi( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi( p->pNew ); + Gia_ManHashAlloc( p->pNew ); + Vec_IntFill( &p->pNew->vCopies2, Gia_ManObjNum(pAig), -1 ); + // SAT solving + p->pSat = bmcg_sat_solver_start(); + p->vFrontier = Vec_PtrAlloc( 1000 ); + p->vFanins = Vec_PtrAlloc( 100 ); + p->vCexMin = Vec_IntAlloc( 100 ); + p->vClassUpdates = Vec_IntAlloc( 100 ); + p->vCexStamps = Vec_IntStart( Gia_ManObjNum(pAig) ); + return p; +} +void Cec4_ManDestroy( Cec4_Man_t * p ) +{ + if ( p->pPars->fVerbose ) + { + abctime timeTotal = Abc_Clock() - p->timeStart; + abctime timeSat = p->timeSatSat0 + p->timeSatSat + p->timeSatUnsat0 + p->timeSatUnsat + p->timeSatUndec; + abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeResimLoc;// - p->timeResimGlo; + ABC_PRTP( "SAT solving ", timeSat, timeTotal ); + ABC_PRTP( " sat(easy) ", p->timeSatSat0, timeTotal ); + ABC_PRTP( " sat ", p->timeSatSat, timeTotal ); + ABC_PRTP( " unsat(easy)", p->timeSatUnsat0, timeTotal ); + ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal ); + ABC_PRTP( " fail ", p->timeSatUndec, timeTotal ); + ABC_PRTP( "Simulation ", p->timeSim, timeTotal ); + ABC_PRTP( "Refinement ", p->timeRefine, timeTotal ); + ABC_PRTP( "Resim global ", p->timeResimGlo, timeTotal ); + ABC_PRTP( "Resim local ", p->timeResimLoc, timeTotal ); + ABC_PRTP( "Other ", timeOther, timeTotal ); + ABC_PRTP( "TOTAL ", timeTotal, timeTotal ); + fflush( stdout ); + } + Vec_WrdFreeP( &p->pAig->vSims ); + Gia_ManCleanMark01( p->pAig ); + bmcg_sat_solver_stop( p->pSat ); + Gia_ManStopP( &p->pNew ); + Vec_PtrFreeP( &p->vFrontier ); + Vec_PtrFreeP( &p->vFanins ); + Vec_IntFreeP( &p->vCexMin ); + Vec_IntFreeP( &p->vClassUpdates ); + Vec_IntFreeP( &p->vCexStamps ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Adds clauses to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec4_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, bmcg_sat_solver * pSat ) +{ + int fPolarFlip = 0; + Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; + int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; + + assert( !Gia_IsComplement( pNode ) ); + assert( pNode->fMark0 ); + // get nodes (I = if, T = then, E = else) + pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); + // get the variable numbers + VarF = Cec4_ObjSatId(p, pNode); + VarI = Cec4_ObjSatId(p, pNodeI); + VarT = Cec4_ObjSatId(p, Gia_Regular(pNodeT)); + VarE = Cec4_ObjSatId(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] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, 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] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); +} +void Cec4_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, bmcg_sat_solver * pSat ) +{ + int fPolarFlip = 0; + 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] = Abc_Var2Lit(Cec4_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); + pLits[1] = Abc_Var2Lit(Cec4_ObjSatId(p, pNode), 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, pLits, 2 ); + assert( RetValue ); + } + // add A & B => C or !A + !B + C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[i] = Abc_Var2Lit(Cec4_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] ); + } + } + pLits[nLits-1] = Abc_Var2Lit(Cec4_ObjSatId(p, pNode), 0); + if ( fPolarFlip ) + { + if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] ); + } + RetValue = bmcg_sat_solver_addclause( pSat, pLits, nLits ); + assert( RetValue ); + ABC_FREE( pLits ); +} + +/**Function************************************************************* + + Synopsis [Adds clauses and returns CNF variable of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec4_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) || + (!fFirst && Gia_ObjValue(pObj) > 1) || + (fUseMuxes && pObj->fMark0) ) + { + Vec_PtrPushUnique( vSuper, pObj ); + return; + } + // go through the branches + Cec4_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes ); + Cec4_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes ); +} +void Cec4_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsCi(pObj) ); + Vec_PtrClear( vSuper ); + Cec4_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); +} +void Cec4_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, bmcg_sat_solver * pSat ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsConst0(pObj) ); + if ( Cec4_ObjSatId(p, pObj) >= 0 ) + return; + assert( Cec4_ObjSatId(p, pObj) == -1 ); + Cec4_ObjSetSatId( p, pObj, bmcg_sat_solver_addvar(pSat) ); + if ( Gia_ObjIsAnd(pObj) ) + Vec_PtrPush( vFrontier, pObj ); +} +int Cec4_ObjGetCnfVar( Cec4_Man_t * p, int iObj ) +{ + int fUseAnd2 = 1; // enable simple CNF + int fUseMuxes = 1; // enable MUXes when using complex CNF + Gia_Obj_t * pNode, * pFanin; + Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj); + int i, k; + // quit if CNF is ready + if ( Cec4_ObjSatId(p->pNew,pObj) >= 0 ) + return Cec4_ObjSatId(p->pNew,pObj); + assert( iObj > 0 ); + if ( Gia_ObjIsCi(pObj) ) + return Cec4_ObjSetSatId( p->pNew, pObj, bmcg_sat_solver_addvar(p->pSat) ); + assert( Gia_ObjIsAnd(pObj) ); + if ( fUseAnd2 ) + { + Cec4_ObjGetCnfVar( p, Gia_ObjFaninId0(pObj, iObj) ); + Cec4_ObjGetCnfVar( p, Gia_ObjFaninId1(pObj, iObj) ); + Vec_PtrClear( p->vFanins ); + Vec_PtrPush( p->vFanins, Gia_ObjChild0(pObj) ); + Vec_PtrPush( p->vFanins, Gia_ObjChild1(pObj) ); + Cec4_ObjSetSatId( p->pNew, pObj, bmcg_sat_solver_addvar(p->pSat) ); + Cec4_AddClausesSuper( p->pNew, pObj, p->vFanins, p->pSat ); + return Cec4_ObjSatId( p->pNew, pObj ); + } + // start the frontier + Vec_PtrClear( p->vFrontier ); + Cec4_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat ); + // explore nodes in the frontier + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i ) + { + // create the supergate + assert( Cec4_ObjSatId(p->pNew,pNode) >= 0 ); + if ( fUseMuxes && pNode->fMark0 ) + { + Vec_PtrClear( p->vFanins ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec4_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec4_AddClausesMux( p->pNew, pNode, p->pSat ); + } + else + { + Cec4_CollectSuper( pNode, fUseMuxes, p->vFanins ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec4_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec4_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat ); + } + assert( Vec_PtrSize(p->vFanins) > 1 ); + } + return Cec4_ObjSatId(p->pNew,pObj); +} + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word * Cec4_ObjSim( Gia_Man_t * p, int iObj ) +{ + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); +} +static inline void Cec4_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit ) +{ + word * pSim = Cec4_ObjSim( p, iObj ); + if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit ) + Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi ); +} +static inline void Cec4_ObjSimRo( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSimRo = Cec4_ObjSim( p, iObj ); + word * pSimRi = Cec4_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); + for ( w = 0; w < p->nSimWords; w++ ) + pSimRo[w] = pSimRi[w]; +} +static inline void Cec4_ObjSimCo( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSimCo = Cec4_ObjSim( p, iObj ); + word * pSimDri = Cec4_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = ~pSimDri[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = pSimDri[w]; +} +static inline void Cec4_ObjSimAnd( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSim = Cec4_ObjSim( p, iObj ); + word * pSim0 = Cec4_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + word * pSim1 = Cec4_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & ~pSim1[w]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & pSim1[w]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & ~pSim1[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & pSim1[w]; +} +static inline int Cec4_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 ) +{ + int w; + word * pSim0 = Cec4_ObjSim( p, iObj0 ); + word * pSim1 = Cec4_ObjSim( p, iObj1 ); + if ( (pSim0[0] & 1) == (pSim1[0] & 1) ) + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != pSim1[w] ) + return 0; + return 1; + } + else + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != ~pSim1[w] ) + return 0; + return 1; + } +} +static inline void Cec4_ObjSimCi( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSim = Cec4_ObjSim( p, iObj ); + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = Gia_ManRandomW( 0 ); + pSim[0] <<= 1; +} +static inline void Cec4_ObjClearSimCi( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSim = Cec4_ObjSim( p, iObj ); + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = 0; +} +void Cec4_ManSimulateCis( Gia_Man_t * p ) +{ + int i, Id; + Gia_ManForEachCiId( p, Id, i ) + Cec4_ObjSimCi( p, Id ); + p->iPatsPi = 0; +} +void Cec4_ManClearCis( Gia_Man_t * p ) +{ + int i, Id; + Gia_ManForEachCiId( p, Id, i ) + Cec4_ObjClearSimCi( p, Id ); + p->iPatsPi = 0; +} +Abc_Cex_t * Cec4_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat ) +{ + Abc_Cex_t * pCex; + int i, Id; + pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 ); + pCex->iPo = iOut; + if ( iPat == -1 ) + return pCex; + Gia_ManForEachCiId( p, Id, i ) + if ( Abc_InfoHasBit((unsigned *)Cec4_ObjSim(p, Id), iPat) ) + Abc_InfoSetBit( pCex->pData, i ); + return pCex; +} +int Cec4_ManSimulateCos( Gia_Man_t * p ) +{ + int i, Id; + // check outputs and generate CEX if they fail + Gia_ManForEachCoId( p, Id, i ) + { + Cec4_ObjSimCo( p, Id ); + if ( Cec4_ObjSimEqual(p, Id, 0) ) + continue; + p->pCexSeq = Cec4_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec4_ObjSim(p, Id), p->nSimWords) ); + return 0; + } + return 1; +} +void Cec4_ManSimulate( Gia_Man_t * p, Cec4_Man_t * pMan, int fRefine ) +{ + extern void Cec4_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); + abctime clk = Abc_Clock(); + Gia_Obj_t * pObj; int i; + pMan->nSimulates++; + Gia_ManForEachAnd( p, pObj, i ) + Cec4_ObjSimAnd( p, i ); + pMan->timeSim += Abc_Clock() - clk; + if ( !fRefine ) + return; + clk = Abc_Clock(); + Gia_ManForEachClass0( p, i ) + Cec4_ManSimClassRefineOne( p, i ); + pMan->timeRefine += Abc_Clock() - clk; +} +void Cec4_ManSimulate_rec( Gia_Man_t * p, Cec4_Man_t * pMan, int iObj ) +{ + Gia_Obj_t * pObj; + if ( !iObj || Vec_IntEntry(pMan->vCexStamps, iObj) == p->iPatsPi ) + return; + Vec_IntWriteEntry( pMan->vCexStamps, iObj, p->iPatsPi ); + pObj = Gia_ManObj(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Cec4_ManSimulate_rec( p, pMan, Gia_ObjFaninId0(pObj, iObj) ); + Cec4_ManSimulate_rec( p, pMan, Gia_ObjFaninId1(pObj, iObj) ); + Cec4_ObjSimAnd( p, iObj ); +} +void Cec4_ManSimAlloc( Gia_Man_t * p, int nWords ) +{ + Vec_WrdFreeP( &p->vSims ); + p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); + p->nSimWords = nWords; +} + + +/**Function************************************************************* + + Synopsis [Creating initial equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec4_ManPrintTfiConeStats( Gia_Man_t * p ) +{ + Vec_Int_t * vRoots = Vec_IntAlloc( 100 ); + Vec_Int_t * vNodes = Vec_IntAlloc( 100 ); + Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); + int i, k; + Gia_ManForEachClass0( p, i ) + { + Vec_IntClear( vRoots ); + if ( i % 100 != 0 ) + continue; + Vec_IntPush( vRoots, i ); + Gia_ClassForEachObj1( p, i, k ) + Vec_IntPush( vRoots, k ); + Gia_ManCollectTfi( p, vRoots, vNodes ); + printf( "Class %6d : ", i ); + printf( "Roots = %6d ", Vec_IntSize(vRoots) ); + printf( "Nodes = %6d ", Vec_IntSize(vNodes) ); + printf( "\n" ); + } + Vec_IntFree( vRoots ); + Vec_IntFree( vNodes ); + Vec_IntFree( vLeaves ); +} +void Cec4_ManPrintStats( Gia_Man_t * p, Cec4_Par_t * pPars, Cec4_Man_t * pMan ) +{ + if ( !pPars->fVerbose ) + return; + printf( "P =%6d ", pMan ? pMan->nSatUnsat : 0 ); + printf( "D =%6d ", pMan ? pMan->nSatSat : 0 ); + printf( "F =%6d ", pMan ? pMan->nSatUndec : 0 ); + //printf( "Last =%6d ", pMan ? pMan->iLastConst : 0 ); + Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); +} +void Cec4_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ) +{ + int iObj, iPrev = iRepr, iPrev2, iRepr2; + Gia_ClassForEachObj1( p, iRepr, iRepr2 ) + if ( Cec4_ObjSimEqual(p, iRepr, iRepr2) ) + iPrev = iRepr2; + else + break; + if ( iRepr2 <= 0 ) // no refinement + return; + // relink remaining nodes of the class + // nodes that are equal to iRepr, remain in the class of iRepr + // nodes that are not equal to iRepr, move to the class of iRepr2 + Gia_ObjSetRepr( p, iRepr2, GIA_VOID ); + iPrev2 = iRepr2; + for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) + { + if ( Cec4_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr + { + Gia_ObjSetNext( p, iPrev, iObj ); + iPrev = iObj; + } + else // moves to iRepr2 + { + Gia_ObjSetRepr( p, iObj, iRepr2 ); + Gia_ObjSetNext( p, iPrev2, iObj ); + iPrev2 = iObj; + } + } + Gia_ObjSetNext( p, iPrev, -1 ); + Gia_ObjSetNext( p, iPrev2, -1 ); +} + +void Cec4_ManPrintClasses2( Gia_Man_t * p ) +{ + int i, k; + Gia_ManForEachClass0( p, i ) + { + printf( "Class %d : ", i ); + Gia_ClassForEachObj1( p, i, k ) + printf( "%d ", k ); + printf( "\n" ); + } +} +void Cec4_ManPrintClasses( Gia_Man_t * p ) +{ + int k, Count = 0; + Gia_ClassForEachObj1( p, 0, k ) + Count++; + printf( "Const0 class has %d entries.\n", Count ); +} +int Cec4_ManSimHashKey( word * pSim, int nSims, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0, * pSimU = (unsigned *)pSim; + int i, nSimsU = 2 * nSims; + if ( pSimU[0] & 1 ) + for ( i = 0; i < nSimsU; i++ ) + uHash ^= ~pSimU[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nSimsU; i++ ) + uHash ^= pSimU[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} +void Cec4_ManCreateClasses( Gia_Man_t * p, Cec4_Man_t * pMan ) +{ + abctime clk; + Gia_Obj_t * pObj; + int nWords = p->nSimWords; + int * pTable, nTableSize, i, Key; + // allocate representation + ABC_FREE( p->pReprs ); + ABC_FREE( p->pNexts ); + p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) ); + p->pReprs[0].iRepr = GIA_VOID; + Gia_ManForEachCoId( p, Key, i ) + p->pReprs[Key].iRepr = GIA_VOID; + Cec4_ManPrintStats( p, pMan->pPars, pMan ); + // hash each node by its simulation info + nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) ); + pTable = ABC_FALLOC( int, nTableSize ); + Gia_ManForEachObj( p, pObj, i ) + { + p->pReprs[i].iRepr = GIA_VOID; + if ( Gia_ObjIsCo(pObj) ) + continue; + Key = Cec4_ManSimHashKey( Cec4_ObjSim(p, i), nWords, nTableSize ); + assert( Key >= 0 && Key < nTableSize ); + if ( pTable[Key] == -1 ) + pTable[Key] = i; + else + Gia_ObjSetRepr( p, i, pTable[Key] ); + } + // create classes + for ( i = Gia_ManObjNum(p) - 1; i >= 0; i-- ) + { + int iRepr = Gia_ObjRepr(p, i); + if ( iRepr == GIA_VOID ) + continue; + Gia_ObjSetNext( p, i, Gia_ObjNext(p, iRepr) ); + Gia_ObjSetNext( p, iRepr, i ); + } + ABC_FREE( pTable ); + clk = Abc_Clock(); + Gia_ManForEachClass0( p, i ) + Cec4_ManSimClassRefineOne( p, i ); + pMan->timeRefine += Abc_Clock() - clk; +} + + + +/**Function************************************************************* + + Synopsis [Verify counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec4_ManVerify_rec( Gia_Man_t * p, int iObj, bmcg_sat_solver * pSat ) +{ + int Value0, Value1; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( iObj == 0 ) return 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return pObj->fMark1; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) +// return pObj->fMark1 = satoko_var_polarity(pSat, Cec4_ObjSatId(p, pObj)) == SATOKO_LIT_TRUE; + return pObj->fMark1 = bmcg_sat_solver_read_cex_varvalue(pSat, Cec4_ObjSatId(p, pObj)); + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Cec4_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj); + Value1 = Cec4_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj); + return pObj->fMark1 = Value0 & Value1; +} +void Cec4_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, bmcg_sat_solver * pSat ) +{ + int Value0, Value1; + Gia_ManIncrementTravId( p ); + Value0 = Cec4_ManVerify_rec( p, iObj0, pSat ); + Value1 = Cec4_ManVerify_rec( p, iObj1, pSat ); + if ( (Value0 ^ Value1) == fPhase ) + printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 ); +// else +// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );; +} + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec4_ManSatSolverRecycle( Cec4_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + p->nRecycles++; + p->nCallsSince = 0; + bmcg_sat_solver_reset( p->pSat ); + // clean mapping of AigIds into SatIds + Gia_ManForEachObjVec( &p->pNew->vSuppVars, p->pNew, pObj, i ) + Cec4_ObjCleanSatId( p->pNew, pObj ); + Vec_IntClear( &p->pNew->vSuppVars ); // AigIds for which SatId is defined + Vec_IntClear( &p->pNew->vCopiesTwo ); // pairs (CiAigId, SatId) +} +int Cec4_ManSolveTwo( Cec4_Man_t * p, int iObj0, int iObj1, int fPhase, int * pfEasy, int fVerbose ) +{ + int nConfEnd, nConfBeg; + int status, iVar0, iVar1, Lits[2]; + int UnsatConflicts[3] = {0}; + if ( iObj1 < iObj0 ) + iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; + assert( iObj0 < iObj1 ); + *pfEasy = 0; + // check if SAT solver needs recycling + p->nCallsSince++; + if ( p->nCallsSince > p->pPars->nCallsRecycle && + Vec_IntSize(&p->pNew->vSuppVars) > p->pPars->nSatVarMax && p->pPars->nSatVarMax ) + Cec4_ManSatSolverRecycle( p ); + // add more logic to the solver + if ( !iObj0 && Cec4_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 ) + Cec4_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), bmcg_sat_solver_addvar(p->pSat) ); + iVar0 = Cec4_ObjGetCnfVar( p, iObj0 ); + iVar1 = Cec4_ObjGetCnfVar( p, iObj1 ); + // perform solving + Lits[0] = Abc_Var2Lit(iVar0, 1); + Lits[1] = Abc_Var2Lit(iVar1, fPhase); + bmcg_sat_solver_set_conflict_budget( p->pSat, p->pPars->nConfLimit ); + nConfBeg = bmcg_sat_solver_conflictnum( p->pSat ); + status = bmcg_sat_solver_solve( p->pSat, Lits, 2 ); + nConfEnd = bmcg_sat_solver_conflictnum( p->pSat ); + assert( nConfEnd >= nConfBeg ); + if ( fVerbose ) + { + if ( status == GLUCOSE_SAT ) + { + p->nConflicts[0][0] += nConfEnd == nConfBeg; + p->nConflicts[0][1] += nConfEnd - nConfBeg; + p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + else if ( status == GLUCOSE_UNSAT ) + { + if ( iObj0 > 0 ) + { + UnsatConflicts[0] = nConfEnd == nConfBeg; + UnsatConflicts[1] = nConfEnd - nConfBeg; + UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + } + else + { + p->nConflicts[1][0] += nConfEnd == nConfBeg; + p->nConflicts[1][1] += nConfEnd - nConfBeg; + p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + } + } + if ( status == GLUCOSE_UNSAT && iObj0 > 0 ) + { + Lits[0] = Abc_Var2Lit(iVar0, 0); + Lits[1] = Abc_Var2Lit(iVar1, !fPhase); + bmcg_sat_solver_set_conflict_budget( p->pSat, p->pPars->nConfLimit ); + nConfBeg = bmcg_sat_solver_conflictnum( p->pSat ); + status = bmcg_sat_solver_solve( p->pSat, Lits, 2 ); + nConfEnd = bmcg_sat_solver_conflictnum( p->pSat ); + assert( nConfEnd >= nConfBeg ); + if ( fVerbose ) + { + if ( status == GLUCOSE_SAT ) + { + p->nConflicts[0][0] += nConfEnd == nConfBeg; + p->nConflicts[0][1] += nConfEnd - nConfBeg; + p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + else if ( status == GLUCOSE_UNSAT ) + { + UnsatConflicts[0] &= nConfEnd == nConfBeg; + UnsatConflicts[1] += nConfEnd - nConfBeg; + UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + + p->nConflicts[1][0] += UnsatConflicts[0]; + p->nConflicts[1][1] += UnsatConflicts[1]; + p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]); + *pfEasy = UnsatConflicts[0]; + } + } + } + return status; +} +int Cec4_ManSweepNode( Cec4_Man_t * p, int iObj, int iRepr ) +{ + abctime clk = Abc_Clock(); + int i, IdAig, IdSat, status, fEasy, RetValue = 1; + Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); + Gia_Obj_t * pRepr = Gia_ManObj( p->pAig, iRepr ); + int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase; + status = Cec4_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose ); + if ( status == GLUCOSE_SAT ) + { + //printf( "Disproved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) ); + p->nSatSat++; + p->nPatterns++; + p->pAig->iPatsPi++; + assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords ); + Vec_IntForEachEntryDouble( &p->pNew->vCopiesTwo, IdAig, IdSat, i ) + Cec4_ObjSimSetInputBit( p->pAig, IdAig, bmcg_sat_solver_read_cex_varvalue(p->pSat, IdSat) ); + if ( fEasy ) + p->timeSatSat0 += Abc_Clock() - clk; + else + p->timeSatSat += Abc_Clock() - clk; + RetValue = 0; + // this is not needed, but we keep it here anyway, because it takes very little time + Cec4_ManVerify( p->pNew, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, p->pSat ); + // resimulated once in a while + if ( p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 1 ) + { + abctime clk2 = Abc_Clock(); + Cec4_ManSimulate( p->pAig, p, 1 ); + //if ( p->nSatSat && p->nSatSat % 100 == 0 ) + Cec4_ManPrintStats( p->pAig, p->pPars, p ); + Vec_IntFill( p->vCexStamps, Gia_ManObjNum(p->pAig), 0 ); + p->pAig->iPatsPi = 0; + p->timeResimGlo += Abc_Clock() - clk2; + } + } + else if ( status == GLUCOSE_UNSAT ) + { + //printf( "Proved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) ); + p->nSatUnsat++; + pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); + Gia_ObjSetProved( p->pAig, iObj ); + if ( iRepr == 0 ) + p->iLastConst = iObj; + if ( fEasy ) + p->timeSatUnsat0 += Abc_Clock() - clk; + else + p->timeSatUnsat += Abc_Clock() - clk; + RetValue = 1; + } + else + { + p->nSatUndec++; + assert( status == GLUCOSE_UNDEC ); + Gia_ObjSetFailed( p->pAig, iObj ); + p->timeSatUndec += Abc_Clock() - clk; + RetValue = 2; + } + return RetValue; +} +Gia_Obj_t * Cec4_ManFindRepr( Gia_Man_t * p, Cec4_Man_t * pMan, int iObj ) +{ + abctime clk = Abc_Clock(); + int iMem, iRepr; + assert( Gia_ObjHasRepr(p, iObj) ); + assert( !Gia_ObjProved(p, iObj) ); + iRepr = Gia_ObjRepr(p, iObj); + assert( iRepr != iObj ); + assert( !Gia_ObjProved(p, iRepr) ); + Cec4_ManSimulate_rec( p, pMan, iObj ); + Cec4_ManSimulate_rec( p, pMan, iRepr ); + if ( Cec4_ObjSimEqual(p, iObj, iRepr) ) + { + pMan->timeResimLoc += Abc_Clock() - clk; + return Gia_ManObj(p, iRepr); + } + Gia_ClassForEachObj1( p, iRepr, iMem ) + { + if ( iObj == iMem ) + break; + if ( Gia_ObjProved(p, iMem) ) + continue; + Cec4_ManSimulate_rec( p, pMan, iMem ); + if ( Cec4_ObjSimEqual(p, iObj, iMem) ) + { + pMan->timeResimLoc += Abc_Clock() - clk; + return Gia_ManObj(p, iMem); + } + } + pMan->timeResimLoc += Abc_Clock() - clk; + return NULL; +} +int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec4_Par_t * pPars, Gia_Man_t ** ppNew ) +{ + Cec4_Man_t * pMan = Cec4_ManCreate( p, pPars ); + Gia_Obj_t * pObj, * pRepr; int i; + //Gia_Obj_t * pObjNew; + if ( pPars->fVerbose ) + printf( "Simulating %d words for %d rounds. SAT solving with %d conflicts. Recycle after %d SAT calls.\n", + pPars->nSimWords, pPars->nSimRounds, pPars->nConfLimit, pPars->nCallsRecycle ); + + // check if any output trivially fails under all-0 pattern + Gia_ManRandomW( 1 ); + Gia_ManSetPhase( p ); + Gia_ManStaticFanoutStart( p ); + if ( pPars->fIsMiter ) + { + Gia_ManForEachCo( p, pObj, i ) + if ( pObj->fPhase ) + { + p->pCexSeq = Cec4_ManDeriveCex( p, i, -1 ); + goto finalize; + } + } + + // simulate one round and create classes + Cec4_ManSimAlloc( p, pPars->nSimWords ); + Cec4_ManSimulateCis( p ); + Cec4_ManSimulate( p, pMan, 0 ); + if ( pPars->fIsMiter && !Cec4_ManSimulateCos(p) ) // cex detected + goto finalize; + Cec4_ManCreateClasses( p, pMan ); + if ( pPars->fVerbose ) + Cec4_ManPrintStats( p, pPars, pMan ); + + // perform additional simulation + for ( i = 0; i < pPars->nSimRounds; i++ ) + { + Cec4_ManSimulateCis( p ); + Cec4_ManSimulate( p, pMan, 1 ); + if ( pPars->fIsMiter && !Cec4_ManSimulateCos(p) ) // cex detected + goto finalize; + if ( i % (pPars->nSimRounds / 5) == 0 && pPars->fVerbose ) + Cec4_ManPrintStats( p, pPars, pMan ); + } + p->iPatsPi = 0; + Gia_ManForEachAnd( p, pObj, i ) + { + pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + //pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) ); + //if ( Gia_ObjIsAnd(pObjNew) ) + // Gia_ObjSetAndLevel( pMan->pNew, pObjNew ); + // select representative based on candidate equivalence classes + pRepr = Gia_ObjReprObj( p, i ); + if ( pRepr == NULL ) + continue; + if ( 1 ) // select representative based on recent counter-examples + { + pRepr = Cec4_ManFindRepr( p, pMan, i ); + if ( pRepr == NULL ) + continue; + } + if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) + { + assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) ); + Gia_ObjSetProved( p, i ); + if ( Gia_ObjId(p, pRepr) == 0 ) + pMan->iLastConst = i; + continue; + } + if ( Cec4_ManSweepNode(pMan, i, Gia_ObjId(p, pRepr)) && Gia_ObjProved(p, i) ) + pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase ); + } + if ( p->iPatsPi > 0 ) + { + abctime clk2 = Abc_Clock(); + Cec4_ManSimulate( p, pMan, 1 ); + Vec_IntFill( pMan->vCexStamps, Gia_ManObjNum(p), 0 ); + p->iPatsPi = 0; + pMan->timeResimGlo += Abc_Clock() - clk2; + } + if ( pPars->fVerbose ) + Cec4_ManPrintStats( p, pPars, pMan ); + if ( ppNew ) + { + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pMan->pNew, Gia_ObjFanin0Copy(pObj) ); + *ppNew = Gia_ManCleanup( pMan->pNew ); + (*ppNew)->pName = Abc_UtilStrsav( p->pName ); + (*ppNew)->pSpec = Abc_UtilStrsav( p->pSpec ); + } +finalize: + if ( pPars->fVerbose ) + printf( "Performed %d SAT calls: P = %d (0=%d a=%.2f m=%d) D = %d (0=%d a=%.2f m=%d) F = %d Sim = %d Recyc = %d\n", + pMan->nSatUnsat + pMan->nSatSat + pMan->nSatUndec, + pMan->nSatUnsat, pMan->nConflicts[1][0], (float)pMan->nConflicts[1][1]/Abc_MaxInt(1, pMan->nSatUnsat-pMan->nConflicts[1][0]), pMan->nConflicts[1][2], + pMan->nSatSat, pMan->nConflicts[0][0], (float)pMan->nConflicts[0][1]/Abc_MaxInt(1, pMan->nSatSat -pMan->nConflicts[0][0]), pMan->nConflicts[0][2], + pMan->nSatUndec, + pMan->nSimulates, pMan->nRecycles ); + Cec4_ManDestroy( pMan ); + Gia_ManStaticFanoutStop( p ); + //Gia_ManEquivPrintClasses( p, 1, 0 ); + return p->pCexSeq ? 0 : 1; +} +Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars0 ) +{ + Gia_Man_t * pNew = NULL; + //abctime clk = Abc_Clock(); + Cec4_Par_t Pars, * pPars = &Pars; + Cec4_SetDefaultParams( pPars ); + pPars->nConfLimit = pPars0->nBTLimit; // conflict limit at a node + pPars->fUseCones = pPars0->fUseCones; + pPars->fVerbose = pPars0->fVerbose; + Cec4_ManPerformSweeping( p, pPars, &pNew ); + //Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); + return pNew; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/cecSweep.c b/src/proof/cec/cecSweep.c index 55f2219f..abe77960 100644 --- a/src/proof/cec/cecSweep.c +++ b/src/proof/cec/cecSweep.c @@ -289,6 +289,9 @@ p->timeSim += Abc_Clock() - clk; p->nAllFailed++; } } + p->nAllProvedS += p->nAllProved; + p->nAllDisprovedS += p->nAllDisproved; + p->nAllFailedS += p->nAllFailed; return 0; } diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make index 86ec2677..fa33ef82 100644 --- a/src/proof/cec/module.make +++ b/src/proof/cec/module.make @@ -8,6 +8,7 @@ SRC += src/proof/cec/cecCec.c \ src/proof/cec/cecPat.c \ src/proof/cec/cecSat.c \ src/proof/cec/cecSatG.c \ + src/proof/cec/cecSatG2.c \ src/proof/cec/cecSeq.c \ src/proof/cec/cecSolve.c \ src/proof/cec/cecSplit.c \ |