Commit 8f690fe8 by Alan Mishchenko

Integrating old SAT solver into majexact and twoexact.

parent 298ec14e
...@@ -2023,6 +2023,10 @@ SOURCE=.\src\sat\bmc\bmcMaj.c ...@@ -2023,6 +2023,10 @@ SOURCE=.\src\sat\bmc\bmcMaj.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\sat\bmc\bmcMaj2.c
# End Source File
# Begin Source File
SOURCE=.\src\sat\bmc\bmcMaxi.c SOURCE=.\src\sat\bmc\bmcMaxi.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -8075,9 +8075,10 @@ usage: ...@@ -8075,9 +8075,10 @@ usage:
int Abc_CommandMajExact( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandMajExact( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
extern void Maj_ManExactSynthesis( int nVars, int nNodes, int fUseConst, int fUseLine, int fVerbose ); extern void Maj_ManExactSynthesis( int nVars, int nNodes, int fUseConst, int fUseLine, int fVerbose );
int c, nVars = 3, nNodes = 1, fUseConst = 0, fUseLine = 0, fVerbose = 1; extern void Maj_ManExactSynthesis2( int nVars, int nNodes, int fUseConst, int fUseLine, int fVerbose );
int c, nVars = 3, nNodes = 1, fUseConst = 0, fUseLine = 0, fGlucose = 0, fVerbose = 1;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "INfcvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "INfcgvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -8109,6 +8110,9 @@ int Abc_CommandMajExact( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -8109,6 +8110,9 @@ int Abc_CommandMajExact( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'c': case 'c':
fUseLine ^= 1; fUseLine ^= 1;
break; break;
case 'g':
fGlucose ^= 1;
break;
case 'v': case 'v':
fVerbose ^= 1; fVerbose ^= 1;
break; break;
...@@ -8123,16 +8127,20 @@ int Abc_CommandMajExact( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -8123,16 +8127,20 @@ int Abc_CommandMajExact( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Cannot sythesize MAJ gate with an even number of inputs (%d).\n", nVars ); Abc_Print( -1, "Cannot sythesize MAJ gate with an even number of inputs (%d).\n", nVars );
return 1; return 1;
} }
Maj_ManExactSynthesis( nVars, nNodes, fUseConst, fUseLine, fVerbose ); if ( fGlucose )
Maj_ManExactSynthesis( nVars, nNodes, fUseConst, fUseLine, fVerbose );
else
Maj_ManExactSynthesis2( nVars, nNodes, fUseConst, fUseLine, fVerbose );
return 0; return 0;
usage: usage:
Abc_Print( -2, "usage: majexact [-IN <num>] [-fcvh]\n" ); Abc_Print( -2, "usage: majexact [-IN <num>] [-fcgvh]\n" );
Abc_Print( -2, "\t exact synthesis of multi-input MAJ using MAJ3 gates\n" ); Abc_Print( -2, "\t exact synthesis of multi-input MAJ using MAJ3 gates\n" );
Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", nVars ); Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", nVars );
Abc_Print( -2, "\t-N <num> : the number of MAJ3 nodes [default = %d]\n", nNodes ); Abc_Print( -2, "\t-N <num> : the number of MAJ3 nodes [default = %d]\n", nNodes );
Abc_Print( -2, "\t-f : toggle using constant fanins [default = %s]\n", fUseConst ? "yes" : "no" ); Abc_Print( -2, "\t-f : toggle using constant fanins [default = %s]\n", fUseConst ? "yes" : "no" );
Abc_Print( -2, "\t-c : toggle using cascade topology [default = %s]\n", fUseLine ? "yes" : "no" ); Abc_Print( -2, "\t-c : toggle using cascade topology [default = %s]\n", fUseLine ? "yes" : "no" );
Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n", fGlucose ? "yes" : "no" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose ? "yes" : "no" ); Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose ? "yes" : "no" );
Abc_Print( -2, "\t-h : print the command usage\n" ); Abc_Print( -2, "\t-h : print the command usage\n" );
return 1; return 1;
...@@ -8152,9 +8160,10 @@ usage: ...@@ -8152,9 +8160,10 @@ usage:
int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
extern void Exa_ManExactSynthesis( char * pTtStr, int nVars, int nNodes, int fVerbose ); extern void Exa_ManExactSynthesis( char * pTtStr, int nVars, int nNodes, int fVerbose );
int c, nVars = 4, nNodes = 3, fVerbose = 1; char * pTtStr = NULL; extern void Exa_ManExactSynthesis2( char * pTtStr, int nVars, int nNodes, int fVerbose );
int c, nVars = 4, nNodes = 3, fGlucose = 0, fVerbose = 1; char * pTtStr = NULL;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "INvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "INgvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -8180,6 +8189,9 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -8180,6 +8189,9 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nNodes < 0 ) if ( nNodes < 0 )
goto usage; goto usage;
break; break;
case 'g':
fGlucose ^= 1;
break;
case 'v': case 'v':
fVerbose ^= 1; fVerbose ^= 1;
break; break;
...@@ -8201,14 +8213,18 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -8201,14 +8213,18 @@ int Abc_CommandTwoExact( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Function should not have more than 10 inputs.\n" ); Abc_Print( -1, "Function should not have more than 10 inputs.\n" );
return 1; return 1;
} }
Exa_ManExactSynthesis( pTtStr, nVars, nNodes, fVerbose ); if ( fGlucose )
Exa_ManExactSynthesis( pTtStr, nVars, nNodes, fVerbose );
else
Exa_ManExactSynthesis2( pTtStr, nVars, nNodes, fVerbose );
return 0; return 0;
usage: usage:
Abc_Print( -2, "usage: twoexact [-IN <num>] [-fcvh] <hex>\n" ); Abc_Print( -2, "usage: twoexact [-IN <num>] [-fcgvh] <hex>\n" );
Abc_Print( -2, "\t exact synthesis of multi-input function using two-input gates\n" ); Abc_Print( -2, "\t exact synthesis of multi-input function using two-input gates\n" );
Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", nVars ); Abc_Print( -2, "\t-I <num> : the number of input variables [default = %d]\n", nVars );
Abc_Print( -2, "\t-N <num> : the number of MAJ3 nodes [default = %d]\n", nNodes ); Abc_Print( -2, "\t-N <num> : the number of MAJ3 nodes [default = %d]\n", nNodes );
Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n", fGlucose ? "yes" : "no" );
Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose ? "yes" : "no" ); Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose ? "yes" : "no" );
Abc_Print( -2, "\t-h : print the command usage\n" ); Abc_Print( -2, "\t-h : print the command usage\n" );
Abc_Print( -2, "\t<hex> : truth table in hex notation\n" ); Abc_Print( -2, "\t<hex> : truth table in hex notation\n" );
...@@ -24685,7 +24701,7 @@ usage: ...@@ -24685,7 +24701,7 @@ usage:
Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" ); Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" );
Abc_Print( -2, "\t-r : toggle the use of rewriting [default = %s]\n", fRewrite? "yes": "no" ); Abc_Print( -2, "\t-r : toggle the use of rewriting [default = %s]\n", fRewrite? "yes": "no" );
// Abc_Print( -2, "\t-a : toggle SAT sweeping and SAT solving [default = %s]\n", fNewAlgo? "SAT solving": "SAT sweeping" ); // Abc_Print( -2, "\t-a : toggle SAT sweeping and SAT solving [default = %s]\n", fNewAlgo? "SAT solving": "SAT sweeping" );
Abc_Print( -2, "\t-s : toggle using Satoko instead of build-in MiniSAT [default = %s]\n", fUseSatoko? "yes": "no" ); Abc_Print( -2, "\t-s : toggle using Satoko by Bruno Schmitt [default = %s]\n", fUseSatoko? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t-h : print the command usage\n");
return 1; return 1;
...@@ -24881,7 +24897,7 @@ usage: ...@@ -24881,7 +24897,7 @@ usage:
Abc_Print( -2, "\t-D num : the delta in the number of nodes [default = %d]\n", nNodeDelta ); Abc_Print( -2, "\t-D num : the delta in the number of nodes [default = %d]\n", nNodeDelta );
Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" ); Abc_Print( -2, "\t-L file: the log file name [default = %s]\n", pLogFileName ? pLogFileName : "no logging" );
Abc_Print( -2, "\t-u : toggle performing structural OR-decomposition [default = %s]\n", fOrDecomp? "yes": "no" ); Abc_Print( -2, "\t-u : toggle performing structural OR-decomposition [default = %s]\n", fOrDecomp? "yes": "no" );
Abc_Print( -2, "\t-s : toggle using Satoko instead of build-in MiniSAT [default = %s]\n", fUseSatoko? "yes": "no" ); Abc_Print( -2, "\t-s : toggle using Satoko by Bruno Schmitt [default = %s]\n", fUseSatoko? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t-h : print the command usage\n");
return 1; return 1;
...@@ -25172,7 +25188,7 @@ usage: ...@@ -25172,7 +25188,7 @@ usage:
Abc_Print( -2, "\t-d : toggle dropping (replacing by 0) SAT outputs [default = %s]\n", pPars->fDropSatOuts? "yes": "no" ); Abc_Print( -2, "\t-d : toggle dropping (replacing by 0) SAT outputs [default = %s]\n", pPars->fDropSatOuts? "yes": "no" );
Abc_Print( -2, "\t-u : toggle performing structural OR-decomposition [default = %s]\n", fOrDecomp? "yes": "not" ); Abc_Print( -2, "\t-u : toggle performing structural OR-decomposition [default = %s]\n", fOrDecomp? "yes": "not" );
Abc_Print( -2, "\t-r : toggle disabling periodic restarts [default = %s]\n", pPars->fNoRestarts? "yes": "no" ); Abc_Print( -2, "\t-r : toggle disabling periodic restarts [default = %s]\n", pPars->fNoRestarts? "yes": "no" );
Abc_Print( -2, "\t-s : toggle using Satoko instead of build-in MiniSAT [default = %s]\n", pPars->fUseSatoko? "yes": "no" ); Abc_Print( -2, "\t-s : toggle using Satoko by Bruno Schmitt [default = %s]\n", pPars->fUseSatoko? "yes": "no" );
Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n",pPars->fUseGlucose? "yes": "no" ); Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n",pPars->fUseGlucose? "yes": "no" );
Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" ); Abc_Print( -2, "\t-z : toggle suppressing report about solved outputs [default = %s]\n", pPars->fNotVerbose? "yes": "no" );
/**CFile****************************************************************
FileName [bmcMaj2.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [SAT-based bounded model checking.]
Synopsis [Exact synthesis with majority gates.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - October 1, 2017.]
Revision [$Id: bmcMaj.c,v 1.00 2017/10/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "bmc.h"
#include "misc/extra/extra.h"
#include "misc/util/utilTruth.h"
#include "sat/cnf/cnf.h"
#include "sat/bsat/satStore.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define MAJ_NOBJS 32 // Const0 + Const1 + nVars + nNodes
typedef struct Maj_Man_t_ Maj_Man_t;
struct Maj_Man_t_
{
int nVars; // inputs
int nNodes; // internal nodes
int nObjs; // total objects (2 consts, nVars inputs, nNodes internal nodes)
int nWords; // the truth table size in 64-bit words
int iVar; // the next available SAT variable
int fUseConst; // use constant fanins
int fUseLine; // use cascade topology
Vec_Wrd_t * vInfo; // Const0 + Const1 + nVars + nNodes + Maj(nVars)
int VarMarks[MAJ_NOBJS][3][MAJ_NOBJS]; // variable marks
int VarVals[MAJ_NOBJS+2]; // values of the first 2 + nVars variables
Vec_Wec_t * vOutLits; // output vars
sat_solver * pSat; // SAT solver
};
static inline word * Maj_ManTruth( Maj_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static int Maj_ManValue( int iMint, int nVars )
{
int k, Count = 0;
for ( k = 0; k < nVars; k++ )
Count += (iMint >> k) & 1;
return (int)(Count > nVars/2);
}
static Vec_Wrd_t * Maj_ManTruthTables( Maj_Man_t * p )
{
Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs + 1) );
int i, nMints = Abc_MaxInt( 64, 1 << p->nVars );
Abc_TtFill( Maj_ManTruth(p, 1), p->nWords );
for ( i = 0; i < p->nVars; i++ )
Abc_TtIthVar( Maj_ManTruth(p, i+2), i, p->nVars );
for ( i = 0; i < nMints; i++ )
if ( Maj_ManValue(i, p->nVars) )
Abc_TtSetBit( Maj_ManTruth(p, p->nObjs), i );
//Dau_DsdPrintFromTruth( Maj_ManTruth(p, p->nObjs), p->nVars );
return vInfo;
}
static int Maj_ManMarkup( Maj_Man_t * p )
{
int i, k, j;
p->iVar = 1;
assert( p->nObjs <= MAJ_NOBJS );
// make exception for the first node
i = p->nVars + 2;
for ( k = 0; k < 3; k++ )
{
j = 4-k;
Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
p->VarMarks[i][k][j] = p->iVar++;
}
// assign variables for other nodes
for ( i = p->nVars + 3; i < p->nObjs; i++ )
{
for ( k = 0; k < 3; k++ )
{
if ( p->fUseLine && k == 0 )
{
j = i-1;
Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
p->VarMarks[i][k][j] = p->iVar++;
continue;
}
for ( j = (p->fUseConst && k == 2) ? 0 : 2; j < i - k; j++ )
{
Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
p->VarMarks[i][k][j] = p->iVar++;
}
}
}
//printf( "The number of parameter variables = %d.\n", p->iVar );
return p->iVar;
// printout
for ( i = p->nVars + 2; i < p->nObjs; i++ )
{
printf( "Node %d\n", i );
for ( j = 0; j < p->nObjs; j++ )
{
for ( k = 0; k < 3; k++ )
printf( "%3d ", p->VarMarks[i][k][j] );
printf( "\n" );
}
}
return p->iVar;
}
static Maj_Man_t * Maj_ManAlloc( int nVars, int nNodes, int fUseConst, int fUseLine )
{
Maj_Man_t * p = ABC_CALLOC( Maj_Man_t, 1 );
p->nVars = nVars;
p->nNodes = nNodes;
p->nObjs = 2 + nVars + nNodes;
p->fUseConst = fUseConst;
p->fUseLine = fUseLine;
p->nWords = Abc_TtWordNum(nVars);
p->vOutLits = Vec_WecStart( p->nObjs );
p->iVar = Maj_ManMarkup( p );
p->VarVals[1] = 1;
p->vInfo = Maj_ManTruthTables( p );
p->pSat = sat_solver_new();
sat_solver_setnvars( p->pSat, p->iVar );
return p;
}
static void Maj_ManFree( Maj_Man_t * p )
{
sat_solver_delete( p->pSat );
Vec_WrdFree( p->vInfo );
Vec_WecFree( p->vOutLits );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Maj_ManFindFanin( Maj_Man_t * p, int i, int k )
{
int j, Count = 0, iVar = -1;
for ( j = 0; j < p->nObjs; j++ )
if ( p->VarMarks[i][k][j] && sat_solver_var_value(p->pSat, p->VarMarks[i][k][j]) )
{
iVar = j;
Count++;
}
assert( Count == 1 );
return iVar;
}
static inline int Maj_ManEval( Maj_Man_t * p )
{
static int Flag = 0;
int i, k, iMint; word * pFanins[3];
for ( i = p->nVars + 2; i < p->nObjs; i++ )
{
for ( k = 0; k < 3; k++ )
pFanins[k] = Maj_ManTruth( p, Maj_ManFindFanin(p, i, k) );
Abc_TtMaj( Maj_ManTruth(p, i), pFanins[0], pFanins[1], pFanins[2], p->nWords );
}
if ( Flag && p->nVars >= 6 )
iMint = Abc_TtFindLastDiffBit( Maj_ManTruth(p, p->nObjs-1), Maj_ManTruth(p, p->nObjs), p->nVars );
else
iMint = Abc_TtFindFirstDiffBit( Maj_ManTruth(p, p->nObjs-1), Maj_ManTruth(p, p->nObjs), p->nVars );
//Flag ^= 1;
assert( iMint < (1 << p->nVars) );
return iMint;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static void Maj_ManPrintSolution( Maj_Man_t * p )
{
int i, k, iVar;
printf( "Realization of %d-input majority using %d MAJ3 gates:\n", p->nVars, p->nNodes );
// for ( i = p->nVars + 2; i < p->nObjs; i++ )
for ( i = p->nObjs - 1; i >= p->nVars + 2; i-- )
{
printf( "%02d = MAJ(", i-2 );
for ( k = 2; k >= 0; k-- )
{
iVar = Maj_ManFindFanin( p, i, k );
if ( iVar >= 2 && iVar < p->nVars + 2 )
printf( " %c", 'a'+iVar-2 );
else if ( iVar < 2 )
printf( " %d", iVar );
else
printf( " %02d", iVar-2 );
}
printf( " )\n" );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static int Maj_ManAddCnfStart( Maj_Man_t * p )
{
int pLits[MAJ_NOBJS], pLits2[2], i, j, k, n, m;
// input constraints
for ( i = p->nVars + 2; i < p->nObjs; i++ )
{
for ( k = 0; k < 3; k++ )
{
int nLits = 0;
for ( j = 0; j < p->nObjs; j++ )
if ( p->VarMarks[i][k][j] )
pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 0 );
assert( nLits > 0 );
// input uniqueness
if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
return 0;
for ( n = 0; n < nLits; n++ )
for ( m = n+1; m < nLits; m++ )
{
pLits2[0] = Abc_LitNot(pLits[n]);
pLits2[1] = Abc_LitNot(pLits[m]);
if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
return 0;
}
if ( k == 2 )
break;
// symmetry breaking
for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
for ( n = j; n < p->nObjs; n++ ) if ( p->VarMarks[i][k+1][n] )
{
pLits2[0] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
pLits2[1] = Abc_Var2Lit( p->VarMarks[i][k+1][n], 1 );
if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
return 0;
}
}
}
// outputs should be used
for ( i = 2; i < p->nObjs - 1; i++ )
{
Vec_Int_t * vArray = Vec_WecEntry(p->vOutLits, i);
assert( Vec_IntSize(vArray) > 0 );
if ( !sat_solver_addclause( p->pSat, Vec_IntArray(vArray), Vec_IntLimit(vArray) ) )
return 0;
}
return 1;
}
static int Maj_ManAddCnf( Maj_Man_t * p, int iMint )
{
// save minterm values
int i, k, n, j, Value = Maj_ManValue(iMint, p->nVars);
for ( i = 0; i < p->nVars; i++ )
p->VarVals[i+2] = (iMint >> i) & 1;
sat_solver_setnvars( p->pSat, p->iVar + 4*p->nNodes );
//printf( "Adding clauses for minterm %d.\n", iMint );
for ( i = p->nVars + 2; i < p->nObjs; i++ )
{
// fanin connectivity
int iBaseSatVarI = p->iVar + 4*(i - p->nVars - 2);
for ( k = 0; k < 3; k++ )
{
for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
{
int iBaseSatVarJ = p->iVar + 4*(j - p->nVars - 2);
for ( n = 0; n < 2; n++ )
{
int pLits[3], nLits = 0;
pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + k, n );
if ( j >= p->nVars + 2 )
pLits[nLits++] = Abc_Var2Lit( iBaseSatVarJ + 3, !n );
else if ( p->VarVals[j] == n )
continue;
if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
return 0;
}
}
}
// node functionality
for ( n = 0; n < 2; n++ )
{
if ( i == p->nObjs - 1 && n == Value )
continue;
for ( k = 0; k < 3; k++ )
{
int pLits[3], nLits = 0;
if ( k != 0 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 0, n );
if ( k != 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 1, n );
if ( k != 2 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 2, n );
if ( i != p->nObjs - 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 3, !n );
assert( nLits <= 3 );
if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
return 0;
}
}
}
p->iVar += 4*p->nNodes;
return 1;
}
void Maj_ManExactSynthesis2( int nVars, int nNodes, int fUseConst, int fUseLine, int fVerbose )
{
int i, iMint = 0;
abctime clkTotal = Abc_Clock();
Maj_Man_t * p = Maj_ManAlloc( nVars, nNodes, fUseConst, fUseLine );
int status = Maj_ManAddCnfStart( p );
assert( status );
printf( "Running exact synthesis for %d-input majority with %d MAJ3 gates...\n", p->nVars, p->nNodes );
for ( i = 0; iMint != -1; i++ )
{
abctime clk = Abc_Clock();
if ( !Maj_ManAddCnf( p, iMint ) )
break;
status = sat_solver_solve( p->pSat, NULL, NULL, 0, 0, 0, 0 );
if ( fVerbose )
{
printf( "Iter %3d : ", i );
Extra_PrintBinary( stdout, (unsigned *)&iMint, p->nVars );
printf( " Var =%5d ", p->iVar );
printf( "Cla =%6d ", sat_solver_nclauses(p->pSat) );
printf( "Conf =%9d ", sat_solver_nconflicts(p->pSat) );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
}
if ( status == l_False )
{
printf( "The problem has no solution.\n" );
break;
}
iMint = Maj_ManEval( p );
}
if ( iMint == -1 )
Maj_ManPrintSolution( p );
Maj_ManFree( p );
Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
}
typedef struct Exa_Man_t_ Exa_Man_t;
struct Exa_Man_t_
{
int nVars; // inputs
int nNodes; // internal nodes
int nObjs; // total objects (nVars inputs + nNodes internal nodes)
int nWords; // the truth table size in 64-bit words
int iVar; // the next available SAT variable
word * pTruth; // truth table
Vec_Wrd_t * vInfo; // nVars + nNodes + 1
int VarMarks[MAJ_NOBJS][2][MAJ_NOBJS]; // variable marks
int VarVals[MAJ_NOBJS]; // values of the first nVars variables
Vec_Wec_t * vOutLits; // output vars
sat_solver * pSat; // SAT solver
};
static inline word * Exa_ManTruth( Exa_Man_t * p, int v ) { return Vec_WrdEntryP( p->vInfo, p->nWords * v ); }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static Vec_Wrd_t * Exa_ManTruthTables( Exa_Man_t * p )
{
Vec_Wrd_t * vInfo = p->vInfo = Vec_WrdStart( p->nWords * (p->nObjs+1) ); int i;
for ( i = 0; i < p->nVars; i++ )
Abc_TtIthVar( Exa_ManTruth(p, i), i, p->nVars );
//Dau_DsdPrintFromTruth( Exa_ManTruth(p, p->nObjs), p->nVars );
return vInfo;
}
static int Exa_ManMarkup( Exa_Man_t * p )
{
int i, k, j;
assert( p->nObjs <= MAJ_NOBJS );
// assign variables for truth tables
p->iVar = 1 + p->nNodes * 3;
// assign variables for other nodes
for ( i = p->nVars; i < p->nObjs; i++ )
{
for ( k = 0; k < 2; k++ )
{
for ( j = 0; j < i - k; j++ )
{
Vec_WecPush( p->vOutLits, j, Abc_Var2Lit(p->iVar, 0) );
p->VarMarks[i][k][j] = p->iVar++;
}
}
}
//printf( "The number of parameter variables = %d.\n", p->iVar );
return p->iVar;
// printout
for ( i = p->nVars; i < p->nObjs; i++ )
{
printf( "Node %d\n", i );
for ( j = 0; j < p->nObjs; j++ )
{
for ( k = 0; k < 2; k++ )
printf( "%3d ", p->VarMarks[i][k][j] );
printf( "\n" );
}
}
return p->iVar;
}
static Exa_Man_t * Exa_ManAlloc( int nVars, int nNodes, word * pTruth )
{
Exa_Man_t * p = ABC_CALLOC( Exa_Man_t, 1 );
p->nVars = nVars;
p->nNodes = nNodes;
p->nObjs = nVars + nNodes;
p->nWords = Abc_TtWordNum(nVars);
p->pTruth = pTruth;
p->vOutLits = Vec_WecStart( p->nObjs );
p->iVar = Exa_ManMarkup( p );
p->vInfo = Exa_ManTruthTables( p );
p->pSat = sat_solver_new();
sat_solver_setnvars( p->pSat, p->iVar );
return p;
}
static void Exa_ManFree( Exa_Man_t * p )
{
sat_solver_delete( p->pSat );
Vec_WrdFree( p->vInfo );
Vec_WecFree( p->vOutLits );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Exa_ManFindFanin( Exa_Man_t * p, int i, int k )
{
int j, Count = 0, iVar = -1;
for ( j = 0; j < p->nObjs; j++ )
if ( p->VarMarks[i][k][j] && sat_solver_var_value(p->pSat, p->VarMarks[i][k][j]) )
{
iVar = j;
Count++;
}
assert( Count == 1 );
return iVar;
}
static inline int Exa_ManEval( Exa_Man_t * p )
{
static int Flag = 0;
int i, k, iMint; word * pFanins[2];
for ( i = p->nVars; i < p->nObjs; i++ )
{
int iVarStart = 1 + 3*(i - p->nVars);
for ( k = 0; k < 2; k++ )
pFanins[k] = Exa_ManTruth( p, Exa_ManFindFanin(p, i, k) );
Abc_TtConst0( Exa_ManTruth(p, i), p->nWords );
for ( k = 1; k < 4; k++ )
{
if ( !sat_solver_var_value(p->pSat, iVarStart+k-1) )
continue;
Abc_TtAndCompl( Exa_ManTruth(p, p->nObjs), pFanins[0], !(k&1), pFanins[1], !(k>>1), p->nWords );
Abc_TtOr( Exa_ManTruth(p, i), Exa_ManTruth(p, i), Exa_ManTruth(p, p->nObjs), p->nWords );
}
}
if ( Flag && p->nVars >= 6 )
iMint = Abc_TtFindLastDiffBit( Exa_ManTruth(p, p->nObjs-1), p->pTruth, p->nVars );
else
iMint = Abc_TtFindFirstDiffBit( Exa_ManTruth(p, p->nObjs-1), p->pTruth, p->nVars );
//Flag ^= 1;
assert( iMint < (1 << p->nVars) );
return iMint;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static void Exa_ManPrintSolution( Exa_Man_t * p, int fCompl )
{
int i, k, iVar;
printf( "Realization of given %d-input function using %d two-input gates:\n", p->nVars, p->nNodes );
// for ( i = p->nVars + 2; i < p->nObjs; i++ )
for ( i = p->nObjs - 1; i >= p->nVars; i-- )
{
int iVarStart = 1 + 3*(i - p->nVars);
int Val1 = sat_solver_var_value(p->pSat, iVarStart);
int Val2 = sat_solver_var_value(p->pSat, iVarStart+1);
int Val3 = sat_solver_var_value(p->pSat, iVarStart+2);
if ( i == p->nObjs - 1 && fCompl )
printf( "%02d = 4\'b%d%d%d1(", i, !Val3, !Val2, !Val1 );
else
printf( "%02d = 4\'b%d%d%d0(", i, Val3, Val2, Val1 );
for ( k = 1; k >= 0; k-- )
{
iVar = Exa_ManFindFanin( p, i, k );
if ( iVar >= 0 && iVar < p->nVars )
printf( " %c", 'a'+iVar );
else
printf( " %02d", iVar );
}
printf( " )\n" );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static int Exa_ManAddCnfStart( Exa_Man_t * p )
{
int pLits[MAJ_NOBJS], pLits2[2], i, j, k, n, m;
// input constraints
for ( i = p->nVars; i < p->nObjs; i++ )
{
int iVarStart = 1 + 3*(i - p->nVars);
for ( k = 0; k < 2; k++ )
{
int nLits = 0;
for ( j = 0; j < p->nObjs; j++ )
if ( p->VarMarks[i][k][j] )
pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 0 );
assert( nLits > 0 );
// input uniqueness
if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
return 0;
for ( n = 0; n < nLits; n++ )
for ( m = n+1; m < nLits; m++ )
{
pLits2[0] = Abc_LitNot(pLits[n]);
pLits2[1] = Abc_LitNot(pLits[m]);
if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
return 0;
}
if ( k == 1 )
break;
// symmetry breaking
for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
for ( n = j; n < p->nObjs; n++ ) if ( p->VarMarks[i][k+1][n] )
{
pLits2[0] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
pLits2[1] = Abc_Var2Lit( p->VarMarks[i][k+1][n], 1 );
if ( !sat_solver_addclause( p->pSat, pLits2, pLits2+2 ) )
return 0;
}
}
// two input functions
for ( k = 0; k < 3; k++ )
{
pLits[0] = Abc_Var2Lit( iVarStart, k==1 );
pLits[1] = Abc_Var2Lit( iVarStart+1, k==2 );
pLits[2] = Abc_Var2Lit( iVarStart+2, k!=0 );
if ( !sat_solver_addclause( p->pSat, pLits, pLits+3 ) )
return 0;
}
}
// outputs should be used
for ( i = 0; i < p->nObjs - 1; i++ )
{
Vec_Int_t * vArray = Vec_WecEntry(p->vOutLits, i);
assert( Vec_IntSize(vArray) > 0 );
if ( !sat_solver_addclause( p->pSat, Vec_IntArray(vArray), Vec_IntLimit(vArray) ) )
return 0;
}
return 1;
}
static int Exa_ManAddCnf( Exa_Man_t * p, int iMint )
{
// save minterm values
int i, k, n, j, Value = Abc_TtGetBit(p->pTruth, iMint);
for ( i = 0; i < p->nVars; i++ )
p->VarVals[i] = (iMint >> i) & 1;
sat_solver_setnvars( p->pSat, p->iVar + 3*p->nNodes );
//printf( "Adding clauses for minterm %d with value %d.\n", iMint, Value );
for ( i = p->nVars; i < p->nObjs; i++ )
{
// fanin connectivity
int iVarStart = 1 + 3*(i - p->nVars);
int iBaseSatVarI = p->iVar + 3*(i - p->nVars);
for ( k = 0; k < 2; k++ )
{
for ( j = 0; j < p->nObjs; j++ ) if ( p->VarMarks[i][k][j] )
{
int iBaseSatVarJ = p->iVar + 3*(j - p->nVars);
for ( n = 0; n < 2; n++ )
{
int pLits[3], nLits = 0;
pLits[nLits++] = Abc_Var2Lit( p->VarMarks[i][k][j], 1 );
pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + k, n );
if ( j >= p->nVars )
pLits[nLits++] = Abc_Var2Lit( iBaseSatVarJ + 2, !n );
else if ( p->VarVals[j] == n )
continue;
if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
return 0;
}
}
}
// node functionality
for ( n = 0; n < 2; n++ )
{
if ( i == p->nObjs - 1 && n == Value )
continue;
for ( k = 0; k < 4; k++ )
{
int pLits[4], nLits = 0;
if ( k == 0 && n == 1 )
continue;
pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 0, (k&1) );
pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 1, (k>>1) );
if ( i != p->nObjs - 1 ) pLits[nLits++] = Abc_Var2Lit( iBaseSatVarI + 2, !n );
if ( k > 0 ) pLits[nLits++] = Abc_Var2Lit( iVarStart + k-1, n );
assert( nLits <= 4 );
if ( !sat_solver_addclause( p->pSat, pLits, pLits+nLits ) )
return 0;
}
}
}
p->iVar += 3*p->nNodes;
return 1;
}
void Exa_ManExactSynthesis2( char * pTtStr, int nVars, int nNodes, int fVerbose )
{
int i, status, iMint = 1;
abctime clkTotal = Abc_Clock();
Exa_Man_t * p; int fCompl = 0;
word pTruth[16]; Abc_TtReadHex( pTruth, pTtStr );
assert( nVars <= 10 );
p = Exa_ManAlloc( nVars, nNodes, pTruth );
if ( pTruth[0] & 1 ) { fCompl = 1; Abc_TtNot( pTruth, p->nWords ); }
status = Exa_ManAddCnfStart( p );
assert( status );
printf( "Running exact synthesis for %d-input function with %d two-input gates...\n", p->nVars, p->nNodes );
for ( i = 0; iMint != -1; i++ )
{
abctime clk = Abc_Clock();
if ( !Exa_ManAddCnf( p, iMint ) )
break;
status = sat_solver_solve( p->pSat, NULL, NULL, 0, 0, 0, 0 );
if ( fVerbose )
{
printf( "Iter %3d : ", i );
Extra_PrintBinary( stdout, (unsigned *)&iMint, p->nVars );
printf( " Var =%5d ", p->iVar );
printf( "Cla =%6d ", sat_solver_nclauses(p->pSat) );
printf( "Conf =%9d ", sat_solver_nconflicts(p->pSat) );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
}
if ( status == l_False )
{
printf( "The problem has no solution.\n" );
break;
}
iMint = Exa_ManEval( p );
}
if ( iMint == -1 )
Exa_ManPrintSolution( p, fCompl );
Exa_ManFree( p );
Abc_PrintTime( 1, "Total runtime", Abc_Clock() - clkTotal );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
...@@ -23,6 +23,7 @@ SRC += src/sat/bmc/bmcBCore.c \ ...@@ -23,6 +23,7 @@ SRC += src/sat/bmc/bmcBCore.c \
src/sat/bmc/bmcInse.c \ src/sat/bmc/bmcInse.c \
src/sat/bmc/bmcLoad.c \ src/sat/bmc/bmcLoad.c \
src/sat/bmc/bmcMaj.c \ src/sat/bmc/bmcMaj.c \
src/sat/bmc/bmcMaj2.c \
src/sat/bmc/bmcMaxi.c \ src/sat/bmc/bmcMaxi.c \
src/sat/bmc/bmcMesh.c \ src/sat/bmc/bmcMesh.c \
src/sat/bmc/bmcMesh2.c \ src/sat/bmc/bmcMesh2.c \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment