diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/base/abci/abc.c | 16 | ||||
-rw-r--r-- | src/sat/bmc/bmc.h | 1 | ||||
-rw-r--r-- | src/sat/bmc/bmcBmcG.c | 426 | ||||
-rw-r--r-- | src/sat/bmc/module.make | 1 | ||||
-rw-r--r-- | src/sat/glucose/AbcGlucose.cpp | 92 | ||||
-rw-r--r-- | src/sat/glucose/AbcGlucose.h | 37 | ||||
-rw-r--r-- | src/sat/glucose/AbcGlucoseCmd.cpp | 13 | ||||
-rw-r--r-- | src/sat/glucose/Glucose.cpp | 14 |
8 files changed, 558 insertions, 42 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 57ff5ab0..2b5df5cd 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -39998,6 +39998,7 @@ usage: int Abc_CommandAbc9SBmc( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Bmcs_ManPerform( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ); + extern int Bmcg_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 @@ -40011,6 +40012,7 @@ int Abc_CommandAbc9SBmc( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fDumpFrames = 0; // dump unrolled timeframes pPars->fUseSynth = 0; // use synthesis pPars->fUseOldCnf = 0; // use old CNF construction + pPars->fUseGlucose = 0; // use Glucose 3.0 pPars->fVerbose = 0; // verbose pPars->fVeryVerbose = 0; // very verbose pPars->fNotVerbose = 0; // skip line-by-line print-out @@ -40020,7 +40022,7 @@ int Abc_CommandAbc9SBmc( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->pFuncOnFrameDone = pAbc->pFuncOnFrameDone; // frame done callback Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "PCFATvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "PCFATgvwh" ) ) != EOF ) { switch ( c ) { @@ -40079,6 +40081,9 @@ int Abc_CommandAbc9SBmc( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nTimeOut < 0 ) goto usage; break; + case 'g': + pPars->fUseGlucose ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -40096,24 +40101,25 @@ int Abc_CommandAbc9SBmc( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Bmcs(): There is no AIG.\n" ); return 0; } - if ( pPars->nProcs > 3 ) + if ( pPars->nProcs > 4 ) { - Abc_Print( -1, "Abc_CommandAbc9Bmcs(): Currently this command can run at most 3 concurrent solvers.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Bmcs(): Currently this command can run at most 4 concurrent solvers.\n" ); return 0; } - pAbc->Status = Bmcs_ManPerform( pAbc->pGia, pPars ); + pAbc->Status = pPars->fUseGlucose ? Bmcg_ManPerform(pAbc->pGia, pPars) : Bmcs_ManPerform(pAbc->pGia, pPars); pAbc->nFrames = pPars->iFrame; Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); return 0; usage: - Abc_Print( -2, "usage: &bmcs [-PCFAT num] [-vwh]\n" ); + Abc_Print( -2, "usage: &bmcs [-PCFAT num] [-gvwh]\n" ); Abc_Print( -2, "\t performs bounded model checking\n" ); Abc_Print( -2, "\t-P num : the number of parallel solvers [default = %d]\n", pPars->nProcs ); 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-A num : the number of additional frames to unroll [default = %d]\n", pPars->nFramesAdd ); Abc_Print( -2, "\t-T num : approximate timeout in seconds [default = %d]\n", pPars->nTimeOut ); + Abc_Print( -2, "\t-g : toggle using Glucose 3.0 [default = %s]\n", pPars->fUseGlucose? "Glucose" : "Satoko" ); 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"); diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h index 689647e7..06c503ac 100644 --- a/src/sat/bmc/bmc.h +++ b/src/sat/bmc/bmc.h @@ -93,6 +93,7 @@ struct Bmc_AndPar_t_ int fDumpFrames; // dump unrolled timeframes int fUseSynth; // use synthesis int fUseOldCnf; // use old CNF construction + int fUseGlucose; // use Glucose 3.0 as the default solver int fVerbose; // verbose int fVeryVerbose; // very verbose int fNotVerbose; // skip line-by-line print-out diff --git a/src/sat/bmc/bmcBmcG.c b/src/sat/bmc/bmcBmcG.c new file mode 100644 index 00000000..27d6b8d3 --- /dev/null +++ b/src/sat/bmc/bmcBmcG.c @@ -0,0 +1,426 @@ +/**CFile**************************************************************** + + FileName [bmcBmcG.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [SAT-based bounded model checking.] + + Synopsis [New BMC package.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - July 20, 2017.] + + Revision [$Id: bmcBmcG.c,v 1.00 2017/07/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "bmc.h" +#include "sat/cnf/cnf.h" +#include "sat/glucose/AbcGlucose.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define PAR_THR_MAX 100 + +typedef struct Bmcg_Man_t_ Bmcg_Man_t; +struct Bmcg_Man_t_ +{ + Bmc_AndPar_t * pPars; // parameters + 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 + bmcg_sat_solver * pSats[PAR_THR_MAX]; // concurrent SAT solvers + int nSatVars; // number of SAT variables used + int nSatVarsOld; // number of SAT variables used + int fStopNow; // signal when it is time to stop + abctime timeUnf; // runtime of unfolding + abctime timeCnf; // runtime of CNF generation + abctime timeSat; // runtime of the solvers + abctime timeOth; // other runtime +}; + +static inline int * Bmcg_ManCopies( Bmcg_Man_t * p, int f ) { return (int*)Vec_PtrEntry(&p->vGia2Fr, f); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Bmcg_Man_t * Bmcg_ManStart( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ) +{ + Bmcg_Man_t * p = ABC_CALLOC( Bmcg_Man_t, 1 ); + int i, Lit = Abc_Var2Lit( 0, 1 ); +// opts.conf_limit = pPars->nConfLimit; + assert( Gia_ManRegNum(pGia) > 0 ); + p->pPars = pPars; + 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_PtrGrow( &p->vGia2Fr, 1000 ); + Vec_IntGrow( &p->vFr2Sat, 3*Gia_ManCiNum(pGia) ); + Vec_IntPush( &p->vFr2Sat, 0 ); + Vec_IntGrow( &p->vCiMap, 3*Gia_ManCiNum(pGia) ); + for ( i = 0; i < p->pPars->nProcs; i++ ) + { + p->pSats[i] = bmcg_sat_solver_start(); +// p->pSats[i]->SolverType = i; + bmcg_sat_solver_addvar( p->pSats[i] ); + bmcg_sat_solver_addclause( p->pSats[i], &Lit, 1 ); + bmcg_sat_solver_setstop( p->pSats[i], &p->fStopNow ); + } + p->nSatVars = 1; + return p; +} +void Bmcg_ManStop( Bmcg_Man_t * p ) +{ + int i; + Gia_ManStopP( &p->pFrames ); + Gia_ManStopP( &p->pClean ); + Vec_PtrFreeData( &p->vGia2Fr ); + Vec_PtrErase( &p->vGia2Fr ); + Vec_IntErase( &p->vFr2Sat ); + Vec_IntErase( &p->vCiMap ); + for ( i = 0; i < p->pPars->nProcs; i++ ) + if ( p->pSats[i] ) + bmcg_sat_solver_stop( p->pSats[i] ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [Incremental unfolding.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bmcg_ManUnfold_rec( Bmcg_Man_t * p, int iObj, int f ) +{ + Gia_Obj_t * pObj; + int iLit = 0, * pCopies = Bmcg_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 = Bmcg_ManUnfold_rec( p, Gia_ObjFaninId0p(p->pGia, pObj), f-1 ); + iLit = Abc_LitNotCond( iLit, Gia_ObjFaninC0(pObj) ); + } + } + else if ( Gia_ObjIsAnd(pObj) ) + { + iLit = Bmcg_ManUnfold_rec( p, Gia_ObjFaninId0(pObj, iObj), f ); + iLit = Abc_LitNotCond( iLit, Gia_ObjFaninC0(pObj) ); + if ( iLit > 0 ) + { + int iNew; + iNew = Bmcg_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 Bmcg_ManCollect_rec( Bmcg_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 = Bmcg_ManCollect_rec( p, Gia_ObjFaninId0(pObj, iObj) ); + int iLit1 = Bmcg_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 * Bmcg_ManUnfold( Bmcg_Man_t * p, int f, int nFramesAdd ) +{ + Gia_Man_t * pNew = NULL; Gia_Obj_t * pObj; + int i, k, iLitFrame, iLitClean, fTrivial = 1; + int * pCopies, nFrameObjs = Gia_ManObjNum(p->pFrames); + assert( Gia_ManPoNum(p->pFrames) == f * Gia_ManPoNum(p->pGia) ); + for ( k = 0; k < nFramesAdd; k++ ) + { + // unfold this timeframe + Vec_PtrPush( &p->vGia2Fr, ABC_FALLOC(int, Gia_ManObjNum(p->pGia)) ); + assert( Vec_PtrSize(&p->vGia2Fr) == f+k+1 ); + pCopies = Bmcg_ManCopies( p, f+k ); + //memset( pCopies, 0xFF, sizeof(int)*Gia_ManObjNum(p->pGia) ); + pCopies[0] = 0; + Gia_ManForEachPo( p->pGia, pObj, i ) + { + iLitFrame = Bmcg_ManUnfold_rec( p, Gia_ObjFaninId0p(p->pGia, pObj), f+k ); + 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 ( k = 0; k < nFramesAdd; k++ ) + for ( i = 0; i < Gia_ManPoNum(p->pGia); i++ ) + { + pObj = Gia_ManCo( p->pFrames, (f+k) * Gia_ManPoNum(p->pGia) + i ); + iLitClean = Bmcg_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 * Bmcg_ManAddNewCnf( Bmcg_Man_t * p, int f, int nFramesAdd ) +{ + abctime clk = Abc_Clock(); + Gia_Man_t * pNew = Bmcg_ManUnfold( p, f, nFramesAdd ); + Cnf_Dat_t * pCnf; + Gia_Obj_t * pObj; + int i, iVar, * pMap; + p->timeUnf += Abc_Clock() - clk; + if ( pNew == NULL ) + return NULL; + clk = Abc_Clock(); + pCnf = (Cnf_Dat_t *) 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 ); + p->timeCnf += Abc_Clock() - clk; + return pCnf; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Bmcg_ManPrintFrame( Bmcg_Man_t * p, int f, int nClauses, int Solver, abctime clkStart ) +{ + int fUnfinished = 0; + if ( !p->pPars->fVerbose ) + return; + Abc_Print( 1, "%4d %s : ", f, fUnfinished ? "-" : "+" ); +// Abc_Print( 1, "Var =%8.0f. ", (double)p->nSatVars ); +// Abc_Print( 1, "Cla =%9.0f. ", (double)nClauses ); + Abc_Print( 1, "Var =%8.0f. ", (double)bmcg_sat_solver_varnum(p->pSats[0]) ); + Abc_Print( 1, "Cla =%9.0f. ", (double)bmcg_sat_solver_clausenum(p->pSats[0]) ); + Abc_Print( 1, "Learn =%9.0f. ",(double)bmcg_sat_solver_learntnum(p->pSats[0]) ); + Abc_Print( 1, "Conf =%9.0f. ", (double)bmcg_sat_solver_conflictnum(p->pSats[0]) ); + if ( p->pPars->nProcs > 1 ) + Abc_Print( 1, "S = %3d. ", Solver ); + 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 ); +} +void Bmcg_ManPrintTime( Bmcg_Man_t * p ) +{ + abctime clkTotal = p->timeUnf + p->timeCnf + p->timeSat + p->timeOth; + if ( !p->pPars->fVerbose ) + return; + ABC_PRTP( "Unfolding ", p->timeUnf, clkTotal ); + ABC_PRTP( "CNF generation", p->timeCnf, clkTotal ); + ABC_PRTP( "SAT solving ", p->timeSat, clkTotal ); + ABC_PRTP( "Other ", p->timeOth, clkTotal ); + ABC_PRTP( "TOTAL ", clkTotal , clkTotal ); +} +Abc_Cex_t * Bmcg_ManGenerateCex( Bmcg_Man_t * p, int i, int f, int s ) +{ + 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 && bmcg_sat_solver_read_cex_varvalue(p->pSats[s], iSatVar) ) // 1 bit + { + 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; +} +void Bmcg_ManAddCnf( Bmcg_Man_t * p, bmcg_sat_solver * pSat, Cnf_Dat_t * pCnf ) +{ + int i; + for ( i = p->nSatVarsOld; i < p->nSatVars; i++ ) + bmcg_sat_solver_addvar( pSat ); + for ( i = 0; i < pCnf->nClauses; i++ ) + if ( !bmcg_sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1]-pCnf->pClauses[i] ) ) + assert( 0 ); +} +int Bmcg_ManPerformOne( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ) +{ + abctime clkStart = Abc_Clock(); + Bmcg_Man_t * p = Bmcg_ManStart( pGia, pPars ); + int f, k = 0, i = Gia_ManPoNum(pGia), status, RetValue = -1, nClauses = 0; + Abc_CexFreeP( &pGia->pCexSeq ); + for ( f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; f += pPars->nFramesAdd ) + { + Cnf_Dat_t * pCnf = Bmcg_ManAddNewCnf( p, f, pPars->nFramesAdd ); + if ( pCnf == NULL ) + { + Bmcg_ManPrintFrame( p, f, nClauses, -1, clkStart ); + if( pPars->pFuncOnFrameDone) + for ( k = 0; k < pPars->nFramesAdd; k++ ) + for ( i = 0; i < Gia_ManPoNum(pGia); i++ ) + pPars->pFuncOnFrameDone(f+k, i, 0); + continue; + } + nClauses += pCnf->nClauses; + Bmcg_ManAddCnf( p, p->pSats[0], pCnf ); + p->nSatVarsOld = p->nSatVars; + Cnf_DataFree( pCnf ); + assert( Gia_ManPoNum(p->pFrames) == (f + pPars->nFramesAdd) * Gia_ManPoNum(pGia) ); + for ( k = 0; k < pPars->nFramesAdd; k++ ) + { + for ( i = 0; i < Gia_ManPoNum(pGia); i++ ) + { + abctime clk = Abc_Clock(); + int iObj = Gia_ObjId( p->pFrames, Gia_ManCo(p->pFrames, (f+k) * 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; + status = bmcg_sat_solver_solve( p->pSats[0], &iLit, 1 ); + p->timeSat += Abc_Clock() - clk; + if ( status == -1 ) // unsat + { + if ( i == Gia_ManPoNum(pGia)-1 ) + Bmcg_ManPrintFrame( p, f+k, nClauses, -1, clkStart ); + if( pPars->pFuncOnFrameDone) + pPars->pFuncOnFrameDone(f+k, i, 0); + continue; + } + if ( status == 1 ) // sat + { + RetValue = 0; + pPars->iFrame = f+k; + pGia->pCexSeq = Bmcg_ManGenerateCex( p, i, f+k, 0 ); + 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+k, nOutDigits, pPars->nFailOuts, nOutDigits, Gia_ManPoNum(pGia) ); + fflush( stdout ); + } + if( pPars->pFuncOnFrameDone) + pPars->pFuncOnFrameDone(f+k, i, 1); + } + break; + } + if ( i < Gia_ManPoNum(pGia) || f+k == pPars->nFramesMax-1 ) + break; + } + if ( k < pPars->nFramesAdd ) + break; + } + p->timeOth = Abc_Clock() - clkStart - p->timeUnf - p->timeCnf - p->timeSat; + if ( RetValue == -1 && !pPars->fNotVerbose ) + printf( "No output failed in %d frames. ", f + (k < pPars->nFramesAdd ? k+1 : 0) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart ); + Bmcg_ManPrintTime( p ); + Bmcg_ManStop( p ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Bmcg_ManPerform( Gia_Man_t * pGia, Bmc_AndPar_t * pPars ) +{ + pPars->nProcs = 1; + return Bmcg_ManPerformOne( pGia, pPars ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/sat/bmc/module.make b/src/sat/bmc/module.make index 30970877..a88db8dd 100644 --- a/src/sat/bmc/module.make +++ b/src/sat/bmc/module.make @@ -4,6 +4,7 @@ SRC += src/sat/bmc/bmcBCore.c \ src/sat/bmc/bmcBmc3.c \ src/sat/bmc/bmcBmcAnd.c \ src/sat/bmc/bmcBmci.c \ + src/sat/bmc/bmcBmcG.c \ src/sat/bmc/bmcBmcS.c \ src/sat/bmc/bmcCexCare.c \ src/sat/bmc/bmcCexCut.c \ diff --git a/src/sat/glucose/AbcGlucose.cpp b/src/sat/glucose/AbcGlucose.cpp index 7601ac39..b5c6b592 100644 --- a/src/sat/glucose/AbcGlucose.cpp +++ b/src/sat/glucose/AbcGlucose.cpp @@ -81,12 +81,11 @@ int glucose_solver_addclause(Glucose::Solver* S, int * plits, int nlits) return S->addClause(lits); // returns 0 if the problem is UNSAT } -int glucose_solver_setcallback(Glucose::Solver* S, void * pman, int(*pfunc)(void*, int, int*)) +void glucose_solver_setcallback(Glucose::Solver* S, void * pman, int(*pfunc)(void*, int, int*)) { S->pCnfMan = pman; S->pCnfFunc = pfunc; S->nCallConfl = 1000; - return 0; } int glucose_solver_solve(Glucose::Solver* S, int * plits, int nlits) @@ -141,6 +140,73 @@ void glucose_print_stats(Solver& s, abctime clk) /**Function************************************************************* + Synopsis [Wrapper APIs to calling from ABC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +bmcg_sat_solver * bmcg_sat_solver_start() +{ + return (bmcg_sat_solver *)glucose_solver_start(); +} +void bmcg_sat_solver_stop(bmcg_sat_solver* s) +{ + glucose_solver_stop((Glucose::Solver*)s); +} + +int bmcg_sat_solver_addclause(bmcg_sat_solver* s, int * plits, int nlits) +{ + return glucose_solver_addclause((Glucose::Solver*)s,plits,nlits); +} + +void bmcg_sat_solver_setcallback(bmcg_sat_solver* s, void * pman, int(*pfunc)(void*, int, int*)) +{ + glucose_solver_setcallback((Glucose::Solver*)s,pman,pfunc); +} + +int bmcg_sat_solver_solve(bmcg_sat_solver* s, int * plits, int nlits) +{ + return glucose_solver_solve((Glucose::Solver*)s,plits,nlits); +} + +int bmcg_sat_solver_addvar(bmcg_sat_solver* s) +{ + return glucose_solver_addvar((Glucose::Solver*)s); +} + +int bmcg_sat_solver_read_cex_varvalue(bmcg_sat_solver* s, int ivar) +{ + return glucose_solver_read_cex_varvalue((Glucose::Solver*)s, ivar); +} + +void bmcg_sat_solver_setstop(bmcg_sat_solver* s, int * pstop) +{ + glucose_solver_setstop((Glucose::Solver*)s, pstop); +} + +int bmcg_sat_solver_varnum(bmcg_sat_solver* s) +{ + return ((Glucose::Solver*)s)->nVars(); +} +int bmcg_sat_solver_clausenum(bmcg_sat_solver* s) +{ + return ((Glucose::Solver*)s)->nClauses(); +} +int bmcg_sat_solver_learntnum(bmcg_sat_solver* s) +{ + return ((Glucose::Solver*)s)->nLearnts(); +} +int bmcg_sat_solver_conflictnum(bmcg_sat_solver* s) +{ + return ((Glucose::Solver*)s)->conflicts; +} + +/**Function************************************************************* + Synopsis [] Description [] @@ -150,9 +216,10 @@ void glucose_print_stats(Solver& s, abctime clk) SeeAlso [] ***********************************************************************/ -void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars ) +void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars ) { abctime clk = Abc_Clock(); + SimpSolver S; S.verbosity = pPars->verb; S.setConfBudget( pPars->nConfls > 0 ? (int64_t)pPars->nConfls : -1 ); @@ -161,10 +228,13 @@ void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars ) parse_DIMACS(in, S); gzclose(in); - printf("c ============================[ Problem Statistics ]=============================\n"); - printf("c | |\n"); - printf("c | Number of variables: %12d |\n", S.nVars()); - printf("c | Number of clauses: %12d |\n", S.nClauses()); + if ( pPars->verb ) + { + printf("c ============================[ Problem Statistics ]=============================\n"); + printf("c | |\n"); + printf("c | Number of variables: %12d |\n", S.nVars()); + printf("c | Number of clauses: %12d |\n", S.nClauses()); + } if ( pPars->pre ) S.eliminate(true); @@ -172,7 +242,7 @@ void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars ) lbool ret = S.solveLimited(dummy); if ( pPars->verb ) glucose_print_stats(S, Abc_Clock() - clk); printf(ret == l_True ? "SATISFIABLE" : ret == l_False ? "UNSATISFIABLE" : "INDETERMINATE"); - Abc_PrintTime( 1, " Time", Abc_Clock() - clk ); + Abc_PrintTime( 1, " Time", Abc_Clock() - clk ); } /**Function************************************************************* @@ -188,7 +258,7 @@ void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars ) ***********************************************************************/ Vec_Int_t * Glucose_SolverFromAig( Gia_Man_t * p, SimpSolver& S ) { - abctime clk = Abc_Clock(); + //abctime clk = Abc_Clock(); int * pLit, * pStop, i; Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8 /*nLutSize*/, 0 /*fCnfObjIds*/, 1/*fAddOrCla*/, 0, 0/*verbose*/ ); for ( i = 0; i < pCnf->nClauses; i++ ) @@ -211,7 +281,7 @@ Vec_Int_t * Glucose_SolverFromAig( Gia_Man_t * p, SimpSolver& S ) return vCnfIds; } -int Glucose_SolveAig(Gia_Man_t * p, ExtSat_Pars * pPars) +int Glucose_SolveAig(Gia_Man_t * p, Glucose_Pars * pPars) { abctime clk = Abc_Clock(); @@ -241,7 +311,7 @@ int Glucose_SolveAig(Gia_Man_t * p, ExtSat_Pars * pPars) if ( pPars->verb ) glucose_print_stats(S, Abc_Clock() - clk); printf(ret == l_True ? "SATISFIABLE" : ret == l_False ? "UNSATISFIABLE" : "INDETERMINATE"); - Abc_PrintTime( 1, " Time", Abc_Clock() - clk ); + Abc_PrintTime( 1, " Time", Abc_Clock() - clk ); // port counterexample if (ret == l_True) diff --git a/src/sat/glucose/AbcGlucose.h b/src/sat/glucose/AbcGlucose.h index 68f793dd..92a6594e 100644 --- a/src/sat/glucose/AbcGlucose.h +++ b/src/sat/glucose/AbcGlucose.h @@ -18,8 +18,8 @@ ***********************************************************************/ -#ifndef SRC_EXTSAT_GLUCOSE_ABC_H_ -#define SRC_EXTSAT_GLUCOSE_ABC_H_ +#ifndef ABC_SAT_GLUCOSE_H_ +#define ABC_SAT_GLUCOSE_H_ //////////////////////////////////////////////////////////////////////// /// INCLUDES /// @@ -37,24 +37,26 @@ ABC_NAMESPACE_HEADER_START /// BASIC TYPES /// //////////////////////////////////////////////////////////////////////// -typedef struct ExtSat_Pars_ ExtSat_Pars; -struct ExtSat_Pars_ { +typedef struct Glucose_Pars_ Glucose_Pars; +struct Glucose_Pars_ { int pre; // preprocessing int verb; // verbosity int cust; // customizable int nConfls; // conflict limit (0 = no limit) }; -static inline ExtSat_Pars ExtSat_CreatePars(int p, int v, int c, int nConfls) +static inline Glucose_Pars Glucose_CreatePars(int p, int v, int c, int nConfls) { - ExtSat_Pars pars; - pars.pre = p; - pars.verb = v; - pars.cust = c; + Glucose_Pars pars; + pars.pre = p; + pars.verb = v; + pars.cust = c; pars.nConfls = nConfls; return pars; } +typedef void bmcg_sat_solver; + //////////////////////////////////////////////////////////////////////// /// MACRO DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -63,8 +65,21 @@ static inline ExtSat_Pars ExtSat_CreatePars(int p, int v, int c, int nConfls) /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -extern void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars ); -extern int Glucose_SolveAig( Gia_Man_t * p, ExtSat_Pars * pPars ); +extern bmcg_sat_solver * bmcg_sat_solver_start(); +extern void bmcg_sat_solver_stop( bmcg_sat_solver* s ); +extern int bmcg_sat_solver_addclause( bmcg_sat_solver* s, int * plits, int nlits ); +extern void bmcg_sat_solver_setcallback( bmcg_sat_solver* s, void * pman, int(*pfunc)(void*, int, int*) ); +extern int bmcg_sat_solver_solve( bmcg_sat_solver* s, int * plits, int nlits ); +extern int bmcg_sat_solver_addvar( bmcg_sat_solver* s ); +extern int bmcg_sat_solver_read_cex_varvalue( bmcg_sat_solver* s, int ); +extern void bmcg_sat_solver_setstop( bmcg_sat_solver* s, int * ); +extern int bmcg_sat_solver_varnum(bmcg_sat_solver* s); +extern int bmcg_sat_solver_clausenum(bmcg_sat_solver* s); +extern int bmcg_sat_solver_learntnum(bmcg_sat_solver* s); +extern int bmcg_sat_solver_conflictnum(bmcg_sat_solver* s); + +extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars ); +extern int Glucose_SolveAig( Gia_Man_t * p, Glucose_Pars * pPars ); ABC_NAMESPACE_HEADER_END diff --git a/src/sat/glucose/AbcGlucoseCmd.cpp b/src/sat/glucose/AbcGlucoseCmd.cpp index 80fdb77f..8dbe3790 100644 --- a/src/sat/glucose/AbcGlucoseCmd.cpp +++ b/src/sat/glucose/AbcGlucoseCmd.cpp @@ -72,15 +72,12 @@ void Glucose_End( Abc_Frame_t * pAbc ) ***********************************************************************/ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Glucose_SolveCnf( char * pFilename, ExtSat_Pars * pPars ); - extern int Glucose_SolveAig( Gia_Man_t * p, ExtSat_Pars * pPars ); - - int c = 0; - int pre = 1; - int verb = 0; + int c = 0; + int pre = 1; + int verb = 0; int nConfls = 0; - ExtSat_Pars pPars; + Glucose_Pars pPars; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "Cpvh" ) ) != EOF ) { @@ -110,7 +107,7 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv ) } } - pPars = ExtSat_CreatePars(pre,verb,0,nConfls); + pPars = Glucose_CreatePars(pre,verb,0,nConfls); if ( argc == globalUtilOptind + 1 ) { diff --git a/src/sat/glucose/Glucose.cpp b/src/sat/glucose/Glucose.cpp index 05f2945d..ac849584 100644 --- a/src/sat/glucose/Glucose.cpp +++ b/src/sat/glucose/Glucose.cpp @@ -1156,7 +1156,7 @@ lbool Solver::search(int nof_conflicts) next = pickBranchLit(); if (next == lit_Undef){ - printf("c last restart ## conflicts : %d %d \n",conflictC,decisionLevel()); + //printf("c last restart ## conflicts : %d %d \n",conflictC,decisionLevel()); // Model found: return l_True; } @@ -1189,17 +1189,17 @@ void Solver::printIncrementalStats() { printf("c---------- Glucose Stats -------------------------\n"); printf("c restarts : %lld\n", starts); printf("c nb ReduceDB : %lld\n", nbReduceDB); - printf("c nb removed Clauses : %lld\n",nbRemovedClauses); + printf("c nb removed Clauses : %lld\n", nbRemovedClauses); printf("c nb learnts DL2 : %lld\n", nbDL2); printf("c nb learnts size 2 : %lld\n", nbBin); printf("c nb learnts size 1 : %lld\n", nbUn); - printf("c conflicts : %lld \n",conflicts); - printf("c decisions : %lld\n",decisions); - printf("c propagations : %lld\n",propagations); + printf("c conflicts : %lld\n", conflicts); + printf("c decisions : %lld\n", decisions); + printf("c propagations : %lld\n", propagations); - printf("c SAT Calls : %d in %g seconds\n",nbSatCalls,totalTime4Sat); - printf("c UNSAT Calls : %d in %g seconds\n",nbUnsatCalls,totalTime4Unsat); + printf("c SAT Calls : %d in %g seconds\n", nbSatCalls, totalTime4Sat); + printf("c UNSAT Calls : %d in %g seconds\n", nbUnsatCalls, totalTime4Unsat); printf("c--------------------------------------------------\n"); |