diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2017-08-09 17:38:40 +0900 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2017-08-09 17:38:40 +0900 |
commit | a1d1a7b8cd1e58473efb7fadfdb117b044f98197 (patch) | |
tree | 3140ea888ec59156ac8ea82cde781d4274cad4e7 | |
parent | 9edf6ea091000eac047eb6a372a9dc79767d0e99 (diff) | |
download | abc-a1d1a7b8cd1e58473efb7fadfdb117b044f98197.tar.gz abc-a1d1a7b8cd1e58473efb7fadfdb117b044f98197.tar.bz2 abc-a1d1a7b8cd1e58473efb7fadfdb117b044f98197.zip |
Experiments with BMC.
-rw-r--r-- | src/aig/gia/giaMf.c | 1 | ||||
-rw-r--r-- | src/base/abci/abc.c | 106 | ||||
-rw-r--r-- | src/sat/bmc/bmcBmcS.c | 425 |
3 files changed, 530 insertions, 2 deletions
diff --git a/src/aig/gia/giaMf.c b/src/aig/gia/giaMf.c index 24c1e6a0..a84690e9 100644 --- a/src/aig/gia/giaMf.c +++ b/src/aig/gia/giaMf.c @@ -545,6 +545,7 @@ static inline int Mf_CutComputeTruth6( Mf_Man_t * p, Mf_Cut_t * pCut0, Mf_Cut_t t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves ); t = fIsXor ? t0 ^ t1 : t0 & t1; if ( (fCompl = (int)(t & 1)) ) t = ~t; + if ( !p->pPars->fCnfObjIds ) pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves ); assert( (int)(t & 1) == 0 ); truthId = Vec_MemHashInsert(p->vTtMem, &t); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 4dbbd155..89a3b299 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -481,6 +481,7 @@ static int Abc_CommandAbc9GroupProve ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9MultiProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9SplitProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Bmc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9SBmc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9ChainBmc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9BCore ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9ICheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1143,6 +1144,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&mprove", Abc_CommandAbc9MultiProve, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&splitprove", Abc_CommandAbc9SplitProve, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&bmc", Abc_CommandAbc9Bmc, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&bmcs", Abc_CommandAbc9SBmc, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&chainbmc", Abc_CommandAbc9ChainBmc, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&bcore", Abc_CommandAbc9BCore, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&icheck", Abc_CommandAbc9ICheck, 0 ); @@ -39977,6 +39979,110 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9SBmc( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern int Bmcs_ManPerform( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ); + Bmc_AndPar_t Pars, * pPars = &Pars; int c; + memset( pPars, 0, sizeof(Bmc_AndPar_t) ); + pPars->nStart = 0; // starting timeframe + pPars->nFramesMax = 100; // maximum number of timeframes + pPars->nFramesAdd = 0; // the number of additional frames + pPars->nConfLimit = 0; // maximum number of conflicts at a node + pPars->nTimeOut = 0; // timeout in seconds + pPars->nLutSize = 0; // max LUT size for CNF computation + pPars->fLoadCnf = 0; // dynamic CNF loading + pPars->fDumpFrames = 0; // dump unrolled timeframes + pPars->fUseSynth = 0; // use synthesis + pPars->fUseOldCnf = 0; // use old CNF construction + pPars->fVerbose = 0; // verbose + pPars->fVeryVerbose = 0; // very verbose + pPars->fNotVerbose = 0; // skip line-by-line print-out + pPars->iFrame = 0; // explored up to this frame + pPars->nFailOuts = 0; // the number of failed outputs + pPars->nDropOuts = 0; // the number of dropped outputs + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CFTvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nConfLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nConfLimit < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nFramesMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nFramesMax < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nTimeOut = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nTimeOut < 0 ) + goto usage; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fVeryVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9SBmc(): There is no AIG.\n" ); + return 0; + } + pAbc->Status = Bmcs_ManPerform( pAbc->pGia, pPars ); + pAbc->nFrames = pPars->iFrame; + Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); + return 0; + +usage: + Abc_Print( -2, "usage: &bmcs [-CFT num] [-vwh]\n" ); + Abc_Print( -2, "\t performs bounded model checking\n" ); + Abc_Print( -2, "\t-C num : the SAT solver conflict limit [default = %d]\n", pPars->nConfLimit ); + Abc_Print( -2, "\t-F num : the maximum number of timeframes [default = %d]\n", pPars->nFramesMax ); + Abc_Print( -2, "\t-T num : approximate timeout in seconds [default = %d]\n", pPars->nTimeOut ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing information about unfolding [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9ChainBmc( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Bmc_ChainTest( Gia_Man_t * p, int nFrameMax, int nConfMax, int fVerbose, int fVeryVerbose, Vec_Ptr_t ** pvCexes ); diff --git a/src/sat/bmc/bmcBmcS.c b/src/sat/bmc/bmcBmcS.c index b1754361..d6452340 100644 --- a/src/sat/bmc/bmcBmcS.c +++ b/src/sat/bmc/bmcBmcS.c @@ -18,9 +18,10 @@ ***********************************************************************/ -#include "sat/cnf/cnf.h" -#include "sat/bsat/satStore.h" #include "bmc.h" +#include "sat/cnf/cnf.h" +#include "sat/satoko/satoko.h" +#include "sat/satoko/solver.h" ABC_NAMESPACE_IMPL_START @@ -176,6 +177,426 @@ Gia_Man_t * Bmc_SuperBuildTents( Gia_Man_t * p, Vec_Int_t ** pvMap ) return pNew; } + + +/**Function************************************************************* + + Synopsis [Count tents.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCountTents_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vRoots ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManCountTents_rec( p, Gia_ObjFaninId0(pObj, iObj), vRoots ); + Gia_ManCountTents_rec( p, Gia_ObjFaninId1(pObj, iObj), vRoots ); + } + else if ( Gia_ObjIsRo(p, pObj) ) + Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, Gia_ObjRoToRi(p, pObj)) ); + else if ( !Gia_ObjIsPi(p, pObj) ) + assert( 0 ); +} +int Gia_ManCountTents( Gia_Man_t * p ) +{ + Vec_Int_t * vRoots; + Gia_Obj_t * pObj; + int t, i, iObj, nSizeCurr = 0; + assert( Gia_ManPoNum(p) > 0 ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrentId( p, 0 ); + vRoots = Vec_IntAlloc( 100 ); + Gia_ManForEachPo( p, pObj, i ) + Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pObj) ); + for ( t = 0; nSizeCurr < Vec_IntSize(vRoots); t++ ) + { + int nSizePrev = nSizeCurr; + nSizeCurr = Vec_IntSize(vRoots); + Vec_IntForEachEntryStartStop( vRoots, iObj, i, nSizePrev, nSizeCurr ) + Gia_ManCountTents_rec( p, iObj, vRoots ); + } + Vec_IntFree( vRoots ); + return t; +} + +/**Function************************************************************* + + Synopsis [Count tents.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCountRanks_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vRoots, Vec_Int_t * vRanks, Vec_Int_t * vCands, int Rank ) +{ + Gia_Obj_t * pObj; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + { + if ( Vec_IntEntry(vRanks, iObj) < Rank ) + Vec_IntWriteEntry( vCands, iObj, 1 ); + return; + } + Gia_ObjSetTravIdCurrentId(p, iObj); + Vec_IntWriteEntry( vRanks, iObj, Rank ); + pObj = Gia_ManObj( p, iObj ); + if ( Gia_ObjIsAnd(pObj) ) + { + Gia_ManCountRanks_rec( p, Gia_ObjFaninId0(pObj, iObj), vRoots, vRanks, vCands, Rank ); + Gia_ManCountRanks_rec( p, Gia_ObjFaninId1(pObj, iObj), vRoots, vRanks, vCands, Rank ); + } + else if ( Gia_ObjIsRo(p, pObj) ) + Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, Gia_ObjRoToRi(p, pObj)) ); + else if ( !Gia_ObjIsPi(p, pObj) ) + assert( 0 ); +} +int Gia_ManCountRanks( Gia_Man_t * p ) +{ + Vec_Int_t * vRoots; + Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vCands = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; + int t, i, iObj, nSizeCurr = 0; + assert( Gia_ManPoNum(p) > 0 ); + Gia_ManIncrementTravId( p ); + Gia_ObjSetTravIdCurrentId( p, 0 ); + vRoots = Vec_IntAlloc( 100 ); + Gia_ManForEachPo( p, pObj, i ) + Vec_IntPush( vRoots, Gia_ObjFaninId0p(p, pObj) ); + for ( t = 0; nSizeCurr < Vec_IntSize(vRoots); t++ ) + { + int nSizePrev = nSizeCurr; + nSizeCurr = Vec_IntSize(vRoots); + Vec_IntForEachEntryStartStop( vRoots, iObj, i, nSizePrev, nSizeCurr ) + Gia_ManCountRanks_rec( p, iObj, vRoots, vRanks, vCands, t ); + } + Vec_IntWriteEntry( vCands, 0, 0 ); + printf( "Tents = %6d. Cands = %6d. %10.2f %%\n", t, Vec_IntSum(vCands), 100.0*Vec_IntSum(vCands)/Gia_ManCandNum(p) ); + Vec_IntFree( vRoots ); + Vec_IntFree( vRanks ); + Vec_IntFree( vCands ); + return t; +} + + + +typedef struct Bmcs_Man_t_ Bmcs_Man_t; +struct Bmcs_Man_t_ +{ + int nFrames; // the limit on the number of frames + int nConfs; // the max number of conflicts at a target + int TimeOut; // the max number of conflicts for all targets + int fVerbose; // enables verbose output + Gia_Man_t * pGia; // user's AIG + Gia_Man_t * pFrames; // unfolded AIG (pFrames->vCopies point to pClean) + Gia_Man_t * pClean; // incremental AIG (pClean->Value point to pFrames) + Vec_Ptr_t vGia2Fr; // copies of GIA in each timeframe + Vec_Int_t vFr2Sat; // mapping of objects in pFrames into SAT variables + Vec_Int_t vCiMap; // maps CIs of pFrames into CIs/frames of GIA + satoko_t * pSat; // SAT solver + int nSatVars; // number of SAT variables used +}; + +static inline int * Bmcs_ManCopies( Bmcs_Man_t * p, int f ) { return (int*)Vec_PtrEntry(&p->vGia2Fr, f % Vec_PtrSize(&p->vGia2Fr)); } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bmcs_Man_t * Bmcs_ManStart( Gia_Man_t * pGia, int nFrames, int nConfs, int TimeOut, int fVerbose ) +{ + Bmcs_Man_t * p = (Bmcs_Man_t *)ABC_CALLOC( Bmcs_Man_t, 1 ); + int i, Lit = Abc_Var2Lit( 0, 1 ); + satoko_opts_t opts; + satoko_default_opts(&opts); + opts.conf_limit = nConfs; + assert( Gia_ManRegNum(pGia) > 0 ); + p->nFrames = nFrames; + p->nConfs = nConfs; + p->TimeOut = TimeOut; + p->fVerbose = fVerbose; + p->pGia = pGia; + p->pFrames = Gia_ManStart( 3*Gia_ManObjNum(pGia) ); Gia_ManHashStart(p->pFrames); + p->pClean = NULL; + Vec_PtrFill( &p->vGia2Fr, Gia_ManCountTents(pGia)+1, NULL ); + for ( i = 0; i < Vec_PtrSize(&p->vGia2Fr); i++ ) + Vec_PtrWriteEntry( &p->vGia2Fr, i, ABC_FALLOC(int, Gia_ManObjNum(pGia)) ); + Vec_IntGrow( &p->vFr2Sat, 3*Gia_ManCiNum(pGia) ); + Vec_IntPush( &p->vFr2Sat, 0 ); + Vec_IntGrow( &p->vCiMap, 3*Gia_ManCiNum(pGia) ); + p->pSat = satoko_create(); satoko_configure(p->pSat, &opts); + p->nSatVars = 1; + satoko_add_clause( p->pSat, &Lit, 1 ); + return p; +} +void Bmcs_ManStop( Bmcs_Man_t * p ) +{ + Gia_ManStopP( &p->pFrames ); + Gia_ManStopP( &p->pClean ); + Vec_PtrFreeData( &p->vGia2Fr ); + Vec_PtrErase( &p->vGia2Fr ); + Vec_IntErase( &p->vFr2Sat ); + Vec_IntErase( &p->vCiMap ); + satoko_destroy( p->pSat ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Incremental unfolding.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bmcs_ManUnfold_rec( Bmcs_Man_t * p, int iObj, int f ) +{ + Gia_Obj_t * pObj; + int iLit = 0, * pCopies = Bmcs_ManCopies( p, f ); + if ( pCopies[iObj] >= 0 ) + return pCopies[iObj]; + pObj = Gia_ManObj( p->pGia, iObj ); + if ( Gia_ObjIsCi(pObj) ) + { + if ( Gia_ObjIsPi(p->pGia, pObj) ) + { + Vec_IntPushTwo( &p->vCiMap, Gia_ObjCioId(pObj), f ); + iLit = Gia_ManAppendCi( p->pFrames ); + } + else if ( f > 0 ) + { + pObj = Gia_ObjRoToRi( p->pGia, pObj ); + iLit = Bmcs_ManUnfold_rec( p, Gia_ObjFaninId0p(p->pGia, pObj), f-1 ); + iLit = Abc_LitNotCond( iLit, Gia_ObjFaninC0(pObj) ); + } + } + else if ( Gia_ObjIsAnd(pObj) ) + { + iLit = Bmcs_ManUnfold_rec( p, Gia_ObjFaninId0(pObj, iObj), f ); + iLit = Abc_LitNotCond( iLit, Gia_ObjFaninC0(pObj) ); + if ( iLit > 0 ) + { + int iNew; + iNew = Bmcs_ManUnfold_rec( p, Gia_ObjFaninId1(pObj, iObj), f ); + iNew = Abc_LitNotCond( iNew, Gia_ObjFaninC1(pObj) ); + iLit = Gia_ManHashAnd( p->pFrames, iLit, iNew ); + } + } + else assert( 0 ); + return (pCopies[iObj] = iLit); +} +int Bmcs_ManCollect_rec( Bmcs_Man_t * p, int iObj ) +{ + Gia_Obj_t * pObj; + int iSatVar, iLitClean = Gia_ObjCopyArray( p->pFrames, iObj ); + if ( iLitClean >= 0 ) + return iLitClean; + pObj = Gia_ManObj( p->pFrames, iObj ); + iSatVar = Vec_IntEntry( &p->vFr2Sat, iObj ); + if ( iSatVar > 0 || Gia_ObjIsCi(pObj) ) + iLitClean = Gia_ManAppendCi( p->pClean ); + else if ( Gia_ObjIsAnd(pObj) ) + { + int iLit0 = Bmcs_ManCollect_rec( p, Gia_ObjFaninId0(pObj, iObj) ); + int iLit1 = Bmcs_ManCollect_rec( p, Gia_ObjFaninId1(pObj, iObj) ); + iLit0 = Abc_LitNotCond( iLit0, Gia_ObjFaninC0(pObj) ); + iLit1 = Abc_LitNotCond( iLit1, Gia_ObjFaninC1(pObj) ); + iLitClean = Gia_ManAppendAnd( p->pClean, iLit0, iLit1 ); + } + else assert( 0 ); + assert( !Abc_LitIsCompl(iLitClean) ); + Gia_ManObj( p->pClean, Abc_Lit2Var(iLitClean) )->Value = iObj; + Gia_ObjSetCopyArray( p->pFrames, iObj, iLitClean ); + return iLitClean; +} +Gia_Man_t * Bmcs_ManUnfold( Bmcs_Man_t * p, int f ) +{ + Gia_Man_t * pNew = NULL; Gia_Obj_t * pObj; + int i, iLitFrame, iLitClean, fTrivial = 1; + int nFrameObjs = Gia_ManObjNum(p->pFrames); + // unfold this timeframe + int * pCopies = Bmcs_ManCopies( p, f ); + memset( pCopies, 0xFF, sizeof(int)*Gia_ManObjNum(p->pGia) ); + pCopies[0] = 0; + assert( Gia_ManPoNum(p->pFrames) == f * Gia_ManPoNum(p->pGia) ); + Gia_ManForEachPo( p->pGia, pObj, i ) + { + iLitFrame = Bmcs_ManUnfold_rec( p, Gia_ObjFaninId0p(p->pGia, pObj), f ); + iLitFrame = Abc_LitNotCond( iLitFrame, Gia_ObjFaninC0(pObj) ); + pCopies[Gia_ObjId(p->pGia, pObj)] = Gia_ManAppendCo( p->pFrames, iLitFrame ); + fTrivial &= (iLitFrame == 0); + } + if ( fTrivial ) + return NULL; + // create a clean copy of the new nodes of this timeframe + Vec_IntFillExtra( &p->vFr2Sat, Gia_ManObjNum(p->pFrames), -1 ); + Vec_IntFillExtra( &p->pFrames->vCopies, Gia_ManObjNum(p->pFrames), -1 ); + assert( Vec_IntCountEntry(&p->pFrames->vCopies, -1) == Vec_IntSize(&p->pFrames->vCopies) ); + Gia_ManStopP( &p->pClean ); + p->pClean = Gia_ManStart( Gia_ManObjNum(p->pFrames) - nFrameObjs + 1000 ); + Gia_ObjSetCopyArray( p->pFrames, 0, 0 ); + for ( i = 0; i < Gia_ManPoNum(p->pGia); i++ ) + { + pObj = Gia_ManCo( p->pFrames, f * Gia_ManPoNum(p->pGia) + i ); + iLitClean = Bmcs_ManCollect_rec( p, Gia_ObjFaninId0p(p->pFrames, pObj) ); + iLitClean = Abc_LitNotCond( iLitClean, Gia_ObjFaninC0(pObj) ); + iLitClean = Gia_ManAppendCo( p->pClean, iLitClean ); + Gia_ManObj( p->pClean, Abc_Lit2Var(iLitClean) )->Value = Gia_ObjId(p->pFrames, pObj); + Gia_ObjSetCopyArray( p->pFrames, Gia_ObjId(p->pFrames, pObj), iLitClean ); + } + pNew = p->pClean; p->pClean = NULL; + Gia_ManForEachObj( pNew, pObj, i ) + Gia_ObjSetCopyArray( p->pFrames, pObj->Value, -1 ); + return pNew; +} +Cnf_Dat_t * Bmcs_ManAddNewCnf( Bmcs_Man_t * p, int f ) +{ + Gia_Man_t * pNew = Bmcs_ManUnfold( p, f ); + Cnf_Dat_t * pCnf; + Gia_Obj_t * pObj; + int i, iVar, * pMap; + if ( pNew == NULL ) + return NULL; + pCnf = Mf_ManGenerateCnf( pNew, 8, 1, 0, 0, 0 ); + pMap = ABC_FALLOC( int, Gia_ManObjNum(pNew) ); + pMap[0] = 0; + Gia_ManForEachObj1( pNew, pObj, i ) + { + if ( pCnf->pObj2Count[i] <= 0 && !Gia_ObjIsCi(pObj) ) + continue; + iVar = Vec_IntEntry( &p->vFr2Sat, pObj->Value ); + if ( iVar == -1 ) + Vec_IntWriteEntry( &p->vFr2Sat, pObj->Value, (iVar = p->nSatVars++) ); + pMap[i] = iVar; + } + Gia_ManStop( pNew ); + for ( i = 0; i < pCnf->nLiterals; i++ ) + pCnf->pClauses[0][i] = Abc_Lit2LitV( pMap, pCnf->pClauses[0][i] ); + ABC_FREE( pMap ); + return pCnf; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bmcs_ManPrintFrame( Bmcs_Man_t * p, int f, int nClauses, abctime clkStart ) +{ + int fUnfinished = 0; + if ( !p->fVerbose ) + return; + Abc_Print( 1, "%4d %s : ", f, fUnfinished ? "-" : "+" ); + Abc_Print( 1, "Var =%8.0f. ", (double)solver_varnum(p->pSat) ); + Abc_Print( 1, "Cla =%9.0f. ", (double)nClauses ); + Abc_Print( 1, "Conf =%7.0f. ", (double)satoko_stats(p->pSat).n_conflicts ); + Abc_Print( 1, "%4.0f MB", 1.0*((int)Gia_ManMemory(p->pFrames) + Vec_IntMemory(&p->vFr2Sat))/(1<<20) ); + Abc_Print( 1, "%9.2f sec ", (float)(Abc_Clock() - clkStart)/(float)(CLOCKS_PER_SEC) ); + printf( "\n" ); + fflush( stdout ); +} +Abc_Cex_t * Bmcs_ManGenerateCex( Bmcs_Man_t * p, int i, int f ) +{ + Abc_Cex_t * pCex = Abc_CexMakeTriv( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), Gia_ManPoNum(p->pGia), f*Gia_ManPoNum(p->pGia)+i ); + Gia_Obj_t * pObj; int k; + Gia_ManForEachPi( p->pFrames, pObj, k ) + { + int iSatVar = Vec_IntEntry( &p->vFr2Sat, Gia_ObjId(p->pFrames, pObj) ); + if ( iSatVar > 0 && var_polarity(p->pSat, iSatVar) == LIT_TRUE ) + { + int iCiId = Vec_IntEntry( &p->vCiMap, 2*k+0 ); + int iFrame = Vec_IntEntry( &p->vCiMap, 2*k+1 ); + Abc_InfoSetBit( pCex->pData, Gia_ManRegNum(p->pGia) + iFrame * Gia_ManPiNum(p->pGia) + iCiId ); + } + } + return pCex; +} +int Bmcs_ManPerform( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ) +{ + abctime clkStart = Abc_Clock(); + Bmcs_Man_t * p = Bmcs_ManStart( pGia, pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->fVerbose ); + int f, i = Gia_ManPoNum(pGia), status, RetValue = -1, nClauses = 0; + for ( f = 0; (!pPars->nFramesMax || f < pPars->nFramesMax) && i == Gia_ManPoNum(pGia); f++ ) + { + Cnf_Dat_t * pCnf = Bmcs_ManAddNewCnf( p, f ); + if ( pCnf == NULL ) + { + Bmcs_ManPrintFrame( p, f, nClauses, clkStart ); + continue; + } + nClauses += pCnf->nClauses; + for ( i = 0; i < pCnf->nClauses; i++ ) + if ( !satoko_add_clause( p->pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + assert( 0 ); + Cnf_DataFree( pCnf ); + assert( Gia_ManPoNum(p->pFrames) == (f + 1) * Gia_ManPoNum(pGia) ); + for ( i = 0; i < Gia_ManPoNum(pGia); i++ ) + { + int iObj = Gia_ObjId( p->pFrames, Gia_ManCo(p->pFrames, f * Gia_ManPoNum(pGia) + i) ); + int iLit = Abc_Var2Lit( Vec_IntEntry(&p->vFr2Sat, iObj), 0 ); + if ( pPars->nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= pPars->nTimeOut ) + break; + satoko_assump_push( p->pSat, iLit ); + status = satoko_solve( p->pSat ); + satoko_assump_pop( p->pSat ); + if ( status == SATOKO_UNSAT ) + { + Bmcs_ManPrintFrame( p, f, nClauses, clkStart ); + continue; + } + if ( status == SATOKO_SAT ) + { + RetValue = 0; + pPars->iFrame = f; + pPars->nFailOuts++; + if ( !pPars->fNotVerbose ) + { + int nOutDigits = Abc_Base10Log( Gia_ManPoNum(pGia) ); + Abc_Print( 1, "Output %*d was asserted in frame %2d (solved %*d out of %*d outputs). ", + nOutDigits, i, f, nOutDigits, pPars->nFailOuts, nOutDigits, Gia_ManPoNum(pGia) ); + fflush( stdout ); + pGia->pCexSeq = Bmcs_ManGenerateCex( p, i, f ); + } + } + break; + } + } + Bmcs_ManStop( p ); + if ( RetValue == -1 && !pPars->fNotVerbose ) + printf( "No output failed in %d frames. ", f ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); + return RetValue; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// |