summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/base/abci/abc.c17
-rw-r--r--src/sat/bmc/bmc.h1
-rw-r--r--src/sat/bmc/bmcBmcAnd.c252
3 files changed, 219 insertions, 51 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 9c51f5da..122e5b38 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -31619,6 +31619,7 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->nFramesMax = 0; // maximum number of timeframes
pPars->nConfLimit = 0; // maximum number of conflicts at a node
pPars->fLoadCnf = 0; // dynamic CNF loading
+ pPars->fDumpFrames = 0; // dump unrolled timeframes
pPars->fVerbose = 0; // verbose
pPars->fVeryVerbose = 0; // very verbose
pPars->fNotVerbose = 0; // skip line-by-line print-out
@@ -31626,7 +31627,7 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
pPars->nFailOuts = 0; // the number of failed outputs
pPars->nDropOuts = 0; // the number of dropped outputs
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "SFcvwh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "SFcdvwh" ) ) != EOF )
{
switch ( c )
{
@@ -31655,6 +31656,9 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'c':
pPars->fLoadCnf ^= 1;
break;
+ case 'd':
+ pPars->fDumpFrames ^= 1;
+ break;
case 'v':
pPars->fVerbose ^= 1;
break;
@@ -31677,12 +31681,13 @@ int Abc_CommandAbc9Bmc( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &bmc [-SF num] [-cvwh]\n" );
+ Abc_Print( -2, "usage: &bmc [-SF num] [-cdvwh]\n" );
Abc_Print( -2, "\t performs bounded model checking\n" );
- Abc_Print( -2, "\t-S num : the starting timeframe [default = %d]\n", pPars->nStart );
- Abc_Print( -2, "\t-F num : the maximum number of timeframes [default = %d]\n", pPars->nFramesMax );
- Abc_Print( -2, "\t-c : toggle dynamic CNF loading [default = %s]\n", pPars->fLoadCnf? "yes": "no" );
- Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" );
+ Abc_Print( -2, "\t-S num : the starting timeframe [default = %d]\n", pPars->nStart );
+ Abc_Print( -2, "\t-F num : the maximum number of timeframes [default = %d]\n", pPars->nFramesMax );
+ Abc_Print( -2, "\t-c : toggle dynamic CNF loading [default = %s]\n", pPars->fLoadCnf? "yes": "no" );
+ Abc_Print( -2, "\t-d : toggle dumping unfolded timeframes [default = %s]\n", pPars->fDumpFrames? "yes": "no" );
+ 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;
diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h
index 51295a53..3c59f605 100644
--- a/src/sat/bmc/bmc.h
+++ b/src/sat/bmc/bmc.h
@@ -79,6 +79,7 @@ struct Bmc_AndPar_t_
int nFramesMax; // maximum number of timeframes
int nConfLimit; // maximum number of conflicts at a node
int fLoadCnf; // dynamic CNF loading
+ int fDumpFrames; // dump unrolled timeframes
int fVerbose; // verbose
int fVeryVerbose; // very verbose
int fNotVerbose; // skip line-by-line print-out
diff --git a/src/sat/bmc/bmcBmcAnd.c b/src/sat/bmc/bmcBmcAnd.c
index 2bd4d90d..29f5ffa5 100644
--- a/src/sat/bmc/bmcBmcAnd.c
+++ b/src/sat/bmc/bmcBmcAnd.c
@@ -19,6 +19,7 @@
***********************************************************************/
#include "bmc.h"
+#include "aig/gia/giaAig.h"
#include "sat/bsat/satStore.h"
#include "sat/cnf/cnf.h"
@@ -48,7 +49,7 @@ struct Bmc_Mna_t_
/**Function*************************************************************
- Synopsis []
+ Synopsis [BMC manager manipulation.]
Description []
@@ -82,7 +83,7 @@ void Bmc_MnaFree( Bmc_Mna_t * p )
/**Function*************************************************************
- Synopsis [Returns 1 if all outputs are trivial.]
+ Synopsis [Derives GIA for the given cone.]
Description []
@@ -91,13 +92,140 @@ void Bmc_MnaFree( Bmc_Mna_t * p )
SeeAlso []
***********************************************************************/
-int Gia_ManBmcCheckOutputs( Gia_Man_t * pFrames, int iStart )
+Gia_Man_t * Gia_ManBmcDupCone( Gia_Man_t * p, Vec_Int_t * vIns, Vec_Int_t * vNodes, Vec_Int_t * vOuts )
{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vTempIn, * vTempNode;
+ Gia_Obj_t * pObj;
int i;
- for ( i = iStart; i < Gia_ManPoNum(pFrames); i++ )
- if ( Gia_ObjChild0(Gia_ManPo(pFrames, i)) != Gia_ManConst0(pFrames) )
- return 0;
- return 1;
+ // save values
+ vTempIn = Vec_IntAlloc( Vec_IntSize(vIns) );
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ Vec_IntPush( vTempIn, pObj->Value );
+ // save values
+ vTempNode = Vec_IntAlloc( Vec_IntSize(vNodes) );
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ Vec_IntPush( vTempNode, pObj->Value );
+ // derive new GIA
+ pNew = Gia_ManDupFromVecs( p, vIns, vNodes, vOuts, 0 );
+ // reset values
+ Gia_ManForEachObjVec( vIns, p, pObj, i )
+ pObj->Value = Vec_IntEntry( vTempIn, i );
+ // reset values
+ Gia_ManForEachObjVec( vNodes, p, pObj, i )
+ pObj->Value = Vec_IntEntry( vTempNode, i );
+ // reset values
+ Gia_ManForEachObjVec( vOuts, p, pObj, i )
+ pObj->Value = 0;
+ Vec_IntFree( vTempIn );
+ Vec_IntFree( vTempNode );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives GIA for the given cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Gia_ManBmcAssignVarIds( Bmc_Mna_t * p, Vec_Int_t * vIns, Vec_Int_t * vUsed, Vec_Int_t * vOuts )
+{
+ int i, iObj, VarC0 = p->nSatVars++;
+ Vec_IntForEachEntry( vIns, iObj, i )
+ if ( Vec_IntEntry( p->vId2Var, iObj ) == 0 )
+ Vec_IntWriteEntry( p->vId2Var, iObj, p->nSatVars++ );
+ Vec_IntForEachEntryReverse( vUsed, iObj, i )
+ {
+ assert( Vec_IntEntry( p->vId2Var, iObj ) == 0 );
+ Vec_IntWriteEntry( p->vId2Var, iObj, p->nSatVars++ );
+ }
+ Vec_IntForEachEntry( vOuts, iObj, i )
+ {
+ assert( Vec_IntEntry( p->vId2Var, iObj ) == 0 );
+ Vec_IntWriteEntry( p->vId2Var, iObj, p->nSatVars++ );
+ }
+ // extend the SAT solver
+ if ( p->nSatVars > sat_solver_nvars(p->pSat) )
+ sat_solver_setnvars( p->pSat, p->nSatVars );
+ return VarC0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Derives CNF for the given cone.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManBmcAddCnf( Bmc_Mna_t * p, Gia_Man_t * pGia, Vec_Int_t * vIns, Vec_Int_t * vNodes, Vec_Int_t * vOuts )
+{
+ Gia_Man_t * pNew = Gia_ManBmcDupCone( pGia, vIns, vNodes, vOuts );
+ Aig_Man_t * pAig = Gia_ManToAigSimple( pNew );
+ Cnf_Dat_t * pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
+ Vec_Int_t * vUsed, * vMap;
+ Gia_Obj_t * pObj;
+ int i, iObj, VarC0;
+ // collect used variables
+ vUsed = Vec_IntAlloc( pCnf->nVars - Vec_IntSize(vIns) - Vec_IntSize(vOuts) );
+ Gia_ManForEachAnd( pNew, pObj, i )
+ if ( pCnf->pVarNums[i] >= 0 )
+ Vec_IntPush( vUsed, Vec_IntEntry(vNodes, i - Vec_IntSize(vIns) - 1) );
+ // assign variable IDs
+ VarC0 = Gia_ManBmcAssignVarIds( p, vIns, vUsed, vOuts );
+ Vec_IntFree( vUsed );
+ // create variable map from CNF vars into SAT vars
+ vMap = Vec_IntStartFull( pCnf->nVars );
+ assert( pCnf->pVarNums[0] > 0 );
+ Vec_IntWriteEntry( vMap, pCnf->pVarNums[0], VarC0 );
+ Gia_ManForEachObj1( pNew, pObj, i )
+ {
+ if ( pCnf->pVarNums[i] < 0 )
+ continue;
+ assert( pCnf->pVarNums[i] >= 0 && pCnf->pVarNums[i] < pCnf->nVars );
+ if ( Gia_ObjIsCi(pObj) )
+ iObj = Vec_IntEntry( vIns, i - 1 );
+ else if ( Gia_ObjIsAnd(pObj) )
+ iObj = Vec_IntEntry( vNodes, i - Vec_IntSize(vIns) - 1 );
+ else if ( Gia_ObjIsCo(pObj) )
+ iObj = Vec_IntEntry( vOuts, i - Vec_IntSize(vIns) - Vec_IntSize(vNodes) - 1 );
+ else assert( 0 );
+ assert( Vec_IntEntry(p->vId2Var, iObj) > 0 );
+ Vec_IntWriteEntry( vMap, pCnf->pVarNums[i], Vec_IntEntry(p->vId2Var, iObj) );
+ }
+//Vec_IntPrint( vMap );
+ // remap CNF
+ for ( i = 0; i < pCnf->nLiterals; i++ )
+ {
+ assert( pCnf->pClauses[0][i] > 1 && pCnf->pClauses[0][i] < 2 * pCnf->nVars );
+ pCnf->pClauses[0][i] = Abc_Lit2LitV( Vec_IntArray(vMap), pCnf->pClauses[0][i] );
+ }
+ Vec_IntFree( vMap );
+ // add clauses
+ for ( i = 0; i < pCnf->nClauses; i++ )
+ {
+/*
+ int v;
+ for ( v = 0; v < pCnf->pClauses[i+1] - pCnf->pClauses[i]; v++ )
+ printf( "%d ", pCnf->pClauses[i][v] );
+ printf( "\n" );
+*/
+ if ( !sat_solver_addclause( p->pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
+ break;
+ }
+ if ( i < pCnf->nClauses )
+ printf( "SAT solver became UNSAT after adding clauses.\n" );
+ Aig_ManStop( pAig );
+ Cnf_DataFree( pCnf );
+ Gia_ManStop( pNew );
}
/**Function*************************************************************
@@ -111,7 +239,7 @@ int Gia_ManBmcCheckOutputs( Gia_Man_t * pFrames, int iStart )
SeeAlso []
***********************************************************************/
-void Gia_ManBmcAndCone_rec( Bmc_Mna_t * p, Gia_Obj_t * pObj )
+void Gia_ManBmcAddCone_rec( Bmc_Mna_t * p, Gia_Obj_t * pObj )
{
int iObj;
if ( pObj->fMark0 )
@@ -120,14 +248,14 @@ void Gia_ManBmcAndCone_rec( Bmc_Mna_t * p, Gia_Obj_t * pObj )
iObj = Gia_ObjId( p->pFrames, pObj );
if ( Gia_ObjIsAnd(pObj) && Vec_IntEntry(p->vId2Var, iObj) == 0 )
{
- Gia_ManBmcAndCone_rec( p, Gia_ObjFanin0(pObj) );
- Gia_ManBmcAndCone_rec( p, Gia_ObjFanin1(pObj) );
+ Gia_ManBmcAddCone_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManBmcAddCone_rec( p, Gia_ObjFanin1(pObj) );
Vec_IntPush( p->vNodes, iObj );
}
else
Vec_IntPush( p->vInputs, iObj );
}
-void Gia_ManBmcAndCone( Bmc_Mna_t * p, int iStart )
+void Gia_ManBmcAddCone( Bmc_Mna_t * p, int iStart )
{
Gia_Obj_t * pObj;
int i;
@@ -140,28 +268,34 @@ void Gia_ManBmcAndCone( Bmc_Mna_t * p, int iStart )
pObj = Gia_ManPo(p->pFrames, i);
if ( Gia_ObjChild0(pObj) == Gia_ManConst0(p->pFrames) )
continue;
- Gia_ManBmcAndCone_rec( p, Gia_ObjFanin0(pObj) );
+ Gia_ManBmcAddCone_rec( p, Gia_ObjFanin0(pObj) );
Vec_IntPush( p->vOutputs, Gia_ObjId(p->pFrames, pObj) );
}
// clean attributes and create new variables
- Gia_ManForEachObjVec( p->vInputs, p->pFrames, pObj, i )
- {
- int iObj = Vec_IntEntry(p->vInputs, i);
- pObj->fMark0 = 0;
- if ( Vec_IntEntry( p->vId2Var, iObj ) == 0 )
- Vec_IntWriteEntry( p->vId2Var, iObj, p->nSatVars++ );
- }
Gia_ManForEachObjVec( p->vNodes, p->pFrames, pObj, i )
- {
- int iObj = Vec_IntEntry(p->vNodes, i);
pObj->fMark0 = 0;
- assert( Vec_IntEntry( p->vId2Var, iObj ) == 0 );
- Vec_IntWriteEntry( p->vId2Var, iObj, p->nSatVars++ );
- }
- // extend the SAT solver
- if ( p->nSatVars > sat_solver_nvars(p->pSat) )
- sat_solver_setnvars( p->pSat, p->nSatVars );
+ Gia_ManForEachObjVec( p->vInputs, p->pFrames, pObj, i )
+ pObj->fMark0 = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+***********************************************************************/
+int Gia_ManBmcCheckOutputs( Gia_Man_t * pFrames, int iStart )
+{
+ int i;
+ for ( i = iStart; i < Gia_ManPoNum(pFrames); i++ )
+ if ( Gia_ObjChild0(Gia_ManPo(pFrames, i)) != Gia_ManConst0(pFrames) )
+ return 0;
+ return 1;
}
/**Function*************************************************************
@@ -180,42 +314,70 @@ int Gia_ManBmcPerform( Gia_Man_t * pGia, Bmc_AndPar_t * pPars )
Unr_Man_t * pUnroll;
Bmc_Mna_t * p = Bmc_MnaAlloc();
int nFramesMax = pPars->nFramesMax ? pPars->nFramesMax : ABC_INFINITY;
- int f, iStart, status = -1;
+ int f, i, Lit, status, RetValue = -2;
pUnroll = Unr_ManUnrollStart( pGia, pPars->fVeryVerbose );
for ( f = 0; f < nFramesMax; f++ )
{
p->pFrames = Unr_ManUnrollFrame( pUnroll, f );
- iStart = f * Gia_ManPoNum(pGia);
- if ( Gia_ManBmcCheckOutputs(p->pFrames, iStart) )
+ if ( !Gia_ManBmcCheckOutputs( p->pFrames, f * Gia_ManPoNum(pGia) ) )
{
- if ( pPars->fVerbose )
+ // create another slice
+ Gia_ManBmcAddCone( p, f * Gia_ManPoNum(pGia) );
+ // create CNF in the SAT solver
+ Gia_ManBmcAddCnf( p, p->pFrames, p->vInputs, p->vNodes, p->vOutputs );
+ // try solving the outputs
+ for ( i = f * Gia_ManPoNum(pGia); i < Gia_ManPoNum(p->pFrames); i++ )
{
- printf( "%4d : PI =%9d. AIG =%9d. Var =%8d. Trivially UNSAT. Mem =%7.1f Mb ",
- f, Gia_ManPiNum(p->pFrames), Gia_ManAndNum(p->pFrames),
- p->nSatVars-1, Gia_ManMemory(p->pFrames) );
- Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
+ Gia_Obj_t * pObj = Gia_ManPo(p->pFrames, i);
+ if ( Gia_ObjChild0(pObj) == Gia_ManConst0(p->pFrames) )
+ continue;
+ Lit = Abc_Var2Lit( Vec_IntEntry(p->vId2Var, Gia_ObjId(p->pFrames, pObj)), 0 );
+ status = sat_solver_solve( p->pSat, &Lit, &Lit + 1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+ if ( status == l_False ) // unsat
+ continue;
+ if ( status == l_True ) // sat
+ RetValue = 0;
+ if ( status == l_Undef ) // undecided
+ RetValue = -1;
+ break;
}
- continue;
}
- // create another slice
- Gia_ManBmcAndCone(p, iStart);
+ // report statistics
if ( pPars->fVerbose )
{
- printf( "%4d : PI =%9d. AIG =%9d. Var =%8d. In =%6d. And =%9d. Mem =%7.1f Mb ",
+ printf( "%4d : PI =%9d. AIG =%9d. Var =%8d. In =%6d. And =%9d. Cla =%9d. Conf =%9d. Mem =%7.1f Mb ",
f, Gia_ManPiNum(p->pFrames), Gia_ManAndNum(p->pFrames),
- p->nSatVars-1, Vec_IntSize(p->vInputs), Vec_IntSize(p->vNodes), Gia_ManMemory(p->pFrames) );
+ p->nSatVars-1, Vec_IntSize(p->vInputs), Vec_IntSize(p->vNodes),
+ sat_solver_nclauses(p->pSat), sat_solver_nconflicts(p->pSat), Gia_ManMemory(p->pFrames) );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
}
+ if ( RetValue != -2 )
+ {
+ if ( RetValue == -1 )
+ printf( "SAT solver reached conflict/runtime limit in frame %d.\n", f );
+ else
+ {
+ printf( "Output %d of miter \"%s\" was asserted in frame %d. ",
+ i - f * Gia_ManPoNum(pGia), Gia_ManName(pGia), f );
+ Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
+ }
+ break;
+ }
}
+ if ( RetValue == -2 )
+ RetValue = -1;
// dump unfolded frames
- p->pFrames = Gia_ManCleanup( p->pFrames );
- Gia_AigerWrite( p->pFrames, "frames.aig", 0, 0 );
- printf( "Dumped unfolded frames into file \"frames.aig\".\n" );
- Gia_ManStop( p->pFrames );
+ if ( pPars->fDumpFrames )
+ {
+ p->pFrames = Gia_ManCleanup( p->pFrames );
+ Gia_AigerWrite( p->pFrames, "frames.aig", 0, 0 );
+ printf( "Dumped unfolded frames into file \"frames.aig\".\n" );
+ Gia_ManStop( p->pFrames );
+ }
// cleanup
Unr_ManFree( pUnroll );
Bmc_MnaFree( p );
- return status;
+ return RetValue;
}
////////////////////////////////////////////////////////////////////////