diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2017-10-19 13:38:09 +0900 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2017-10-19 13:38:09 +0900 |
commit | 8f690fe8623fa1ce49274f0146b2d90d42e24749 (patch) | |
tree | bc58c0f49677a566bfe2c4913c2972205896d1f2 /src/sat | |
parent | 298ec14efa83fcb435971c2b987afa84f1a9f767 (diff) | |
download | abc-8f690fe8623fa1ce49274f0146b2d90d42e24749.tar.gz abc-8f690fe8623fa1ce49274f0146b2d90d42e24749.tar.bz2 abc-8f690fe8623fa1ce49274f0146b2d90d42e24749.zip |
Integrating old SAT solver into majexact and twoexact.
Diffstat (limited to 'src/sat')
-rw-r--r-- | src/sat/bmc/bmcMaj2.c | 745 | ||||
-rw-r--r-- | src/sat/bmc/module.make | 1 |
2 files changed, 746 insertions, 0 deletions
diff --git a/src/sat/bmc/bmcMaj2.c b/src/sat/bmc/bmcMaj2.c new file mode 100644 index 00000000..7ccfbe28 --- /dev/null +++ b/src/sat/bmc/bmcMaj2.c @@ -0,0 +1,745 @@ +/**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 + diff --git a/src/sat/bmc/module.make b/src/sat/bmc/module.make index 94fb27cc..cf19feaa 100644 --- a/src/sat/bmc/module.make +++ b/src/sat/bmc/module.make @@ -23,6 +23,7 @@ SRC += src/sat/bmc/bmcBCore.c \ src/sat/bmc/bmcInse.c \ src/sat/bmc/bmcLoad.c \ src/sat/bmc/bmcMaj.c \ + src/sat/bmc/bmcMaj2.c \ src/sat/bmc/bmcMaxi.c \ src/sat/bmc/bmcMesh.c \ src/sat/bmc/bmcMesh2.c \ |