summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2015-04-16 20:58:23 +0900
committerAlan Mishchenko <alanmi@berkeley.edu>2015-04-16 20:58:23 +0900
commitcd4807ea043b6179b22bdb281318e8d3b6911c8b (patch)
tree50ece19517585eae60f53e71a37b70a3ad8c7a3c
parent4b2205ce6e2fe09f00d339f0f3ef8d3fc04449df (diff)
downloadabc-cd4807ea043b6179b22bdb281318e8d3b6911c8b.tar.gz
abc-cd4807ea043b6179b22bdb281318e8d3b6911c8b.tar.bz2
abc-cd4807ea043b6179b22bdb281318e8d3b6911c8b.zip
Adding support for cardinality constraints in &fftest (switches -K and -k).
-rw-r--r--src/base/abci/abc.c26
-rw-r--r--src/sat/bmc/bmc.h2
-rw-r--r--src/sat/bmc/bmcFault.c62
3 files changed, 84 insertions, 6 deletions
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index 286ec39d..8b96bba1 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -36342,7 +36342,7 @@ int Abc_CommandAbc9FFTest( Abc_Frame_t * pAbc, int argc, char ** argv )
int c;
Gia_ParFfSetDefault( pPars );
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "ATNSGsbfdeuvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "ATNKSGkbsfdeuvh" ) ) != EOF )
{
switch ( c )
{
@@ -36379,6 +36379,17 @@ int Abc_CommandAbc9FFTest( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nIterCheck < 0 )
goto usage;
break;
+ case 'K':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
+ goto usage;
+ }
+ pPars->nCardConstr = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( pPars->nCardConstr <= 0 )
+ goto usage;
+ break;
case 'S':
if ( globalUtilOptind >= argc )
{
@@ -36397,12 +36408,15 @@ int Abc_CommandAbc9FFTest( Abc_Frame_t * pAbc, int argc, char ** argv )
pFileName = argv[globalUtilOptind];
globalUtilOptind++;
break;
- case 's':
- pPars->fStartPats ^= 1;
+ case 'k':
+ pPars->fNonStrict ^= 1;
break;
case 'b':
pPars->fBasic ^= 1;
break;
+ case 's':
+ pPars->fStartPats ^= 1;
+ break;
case 'f':
pPars->fFfOnly ^= 1;
break;
@@ -36493,7 +36507,7 @@ int Abc_CommandAbc9FFTest( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- Abc_Print( -2, "usage: &fftest [-ATN num] [-sbfdeuvh] <file> [-G file] [-S str]\n" );
+ Abc_Print( -2, "usage: &fftest [-ATNK num] [-kbsfdeuvh] <file> [-G file] [-S str]\n" );
Abc_Print( -2, "\t performs functional fault test generation\n" );
Abc_Print( -2, "\t-A num : selects fault model for all gates [default = %d]\n", pPars->Algo );
Abc_Print( -2, "\t 0: fault model is not selected (use -S str)\n" );
@@ -36503,8 +36517,10 @@ usage:
Abc_Print( -2, "\t 4: functionally observable fault\n" );
Abc_Print( -2, "\t-T num : specifies approximate runtime limit in seconds [default = %d]\n", pPars->nTimeOut );
Abc_Print( -2, "\t-N num : specifies iteration to check for fixed parameters [default = %d]\n", pPars->nIterCheck );
+ Abc_Print( -2, "\t-K num : specifies cardinality constraint (num > 0) [default = unused]\n" );
+ Abc_Print( -2, "\t-k : toggles non-strict cardinality (n <= K, instead of n == K) [default = %s]\n",pPars->fNonStrict? "yes": "no" );
+ Abc_Print( -2, "\t-b : toggles testing for single faults (the same as \"-K 1\") [default = %s]\n", pPars->fBasic? "yes": "no" );
Abc_Print( -2, "\t-s : toggles starting with the all-0 and all-1 patterns [default = %s]\n", pPars->fStartPats? "yes": "no" );
- Abc_Print( -2, "\t-b : toggles testing for single faults only [default = %s]\n", pPars->fBasic? "yes": "no" );
Abc_Print( -2, "\t-f : toggles faults at flop inputs only with \"-A 1\" and \"-S str\" [default = %s]\n", pPars->fFfOnly? "yes": "no" );
Abc_Print( -2, "\t-d : toggles dumping test patterns into file \"tests.txt\" [default = %s]\n", pPars->fDump? "yes": "no" );
Abc_Print( -2, "\t-e : toggles dumping test pattern pairs (delay faults only) [default = %s]\n", pPars->fDumpDelay? "yes": "no" );
diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h
index 75529f7b..14ffec12 100644
--- a/src/sat/bmc/bmc.h
+++ b/src/sat/bmc/bmc.h
@@ -130,6 +130,8 @@ struct Bmc_ParFf_t_
int fStartPats;
int nTimeOut;
int nIterCheck;
+ int nCardConstr;
+ int fNonStrict;
int fBasic;
int fFfOnly;
int fDump;
diff --git a/src/sat/bmc/bmcFault.c b/src/sat/bmc/bmcFault.c
index 50477f21..e91c76ac 100644
--- a/src/sat/bmc/bmcFault.c
+++ b/src/sat/bmc/bmcFault.c
@@ -65,6 +65,56 @@ void Gia_ParFfSetDefault( Bmc_ParFf_t * p )
/**Function*************************************************************
+ Synopsis [Adds a general cardinality constraint in terms of vVars.]
+
+ Description [Strict is "exactly K out of N". Non-strict is
+ "less or equal than K out of N".]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Cnf_AddCardinVar( int Level, int Base, Vec_Int_t * vVars, int k )
+{
+ return Level ? Base + k : Vec_IntEntry( vVars, k );
+}
+static inline void Cnf_AddCardinConstrGeneral( sat_solver * p, Vec_Int_t * vVars, int K, int fStrict )
+{
+ int i, k, iCur, iNext, iVar, Lit;
+ int nVars = sat_solver_nvars(p);
+ int nBits = Vec_IntSize(vVars);
+ Vec_IntForEachEntry( vVars, iVar, i )
+ assert( iVar >= 0 && iVar < nVars );
+ sat_solver_setnvars( p, nVars + nBits * nBits );
+ for ( i = 0; i < nBits; i++ )
+ {
+ iCur = nVars + nBits * (i-1);
+ iNext = nVars + nBits * i;
+ if ( i & 1 )
+ sat_solver_add_buffer( p, iNext, Cnf_AddCardinVar(i, iCur, vVars, 0), 0 );
+ for ( k = i & 1; k + 1 < nBits; k += 2 )
+ {
+ sat_solver_add_and( p, iNext+k , Cnf_AddCardinVar(i, iCur, vVars, k), Cnf_AddCardinVar(i, iCur, vVars, k+1), 1, 1, 1 );
+ sat_solver_add_and( p, iNext+k+1, Cnf_AddCardinVar(i, iCur, vVars, k), Cnf_AddCardinVar(i, iCur, vVars, k+1), 0, 0, 0 );
+ }
+ if ( k == nBits - 1 )
+ sat_solver_add_buffer( p, iNext + nBits-1, Cnf_AddCardinVar(i, iCur, vVars, nBits-1), 0 );
+ }
+ // add final constraint
+ assert( K > 0 && K < nBits );
+ Lit = Abc_Var2Lit( nVars + nBits * (nBits - 1) + K, 1 );
+ if ( !sat_solver_addclause( p, &Lit, &Lit+1 ) )
+ assert( 0 );
+ if ( fStrict )
+ {
+ Lit = Abc_Var2Lit( nVars + nBits * (nBits - 1) + K - 1, 0 );
+ if ( !sat_solver_addclause( p, &Lit, &Lit+1 ) )
+ assert( 0 );
+ }
+}
+/**Function*************************************************************
+
Synopsis [Add constraint that no more than 1 variable is 1.]
Description []
@@ -99,17 +149,19 @@ static inline int Cnf_AddCardinConstr( sat_solver * p, Vec_Int_t * vVars )
}
void Cnf_AddCardinConstrTest()
{
- int i, status, nVars = 7;
+ int i, status, Count = 1, nVars = 6;
Vec_Int_t * vVars = Vec_IntStartNatural( nVars );
sat_solver * pSat = sat_solver_new();
sat_solver_setnvars( pSat, nVars );
Cnf_AddCardinConstr( pSat, vVars );
+ //Cnf_AddCardinConstrGeneral( pSat, vVars, 1, 1 );
while ( 1 )
{
status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
if ( status != l_True )
break;
Vec_IntClear( vVars );
+ printf( "%3d : ", Count++ );
for ( i = 0; i < nVars; i++ )
{
Vec_IntPush( vVars, Abc_Var2Lit(i, sat_solver_var_value(pSat, i)) );
@@ -1078,6 +1130,14 @@ int Gia_ManFaultPrepare( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars, int
Vec_IntPush( vLits, pCnf->pVarNums[Gia_ObjId(pM, pObj)] );
Cnf_AddCardinConstr( pSat, vLits );
}
+ else if ( pPars->nCardConstr )
+ {
+ Vec_IntClear( vLits );
+ Gia_ManForEachPi( pM, pObj, i )
+ if ( i >= nFuncVars )
+ Vec_IntPush( vLits, pCnf->pVarNums[Gia_ObjId(pM, pObj)] );
+ Cnf_AddCardinConstrGeneral( pSat, vLits, pPars->nCardConstr, !pPars->fNonStrict );
+ }
// add available test-patterns
if ( Vec_IntSize(vTests) > 0 )