summaryrefslogtreecommitdiffstats
path: root/src/sat/bsat
diff options
context:
space:
mode:
Diffstat (limited to 'src/sat/bsat')
-rw-r--r--src/sat/bsat/satInter.c980
-rw-r--r--src/sat/bsat/satSolver.c79
-rw-r--r--src/sat/bsat/satSolver.h33
-rw-r--r--src/sat/bsat/satStore.c437
-rw-r--r--src/sat/bsat/satStore.h135
-rw-r--r--src/sat/bsat/satTrace.c109
-rw-r--r--src/sat/bsat/satUtil.c71
7 files changed, 1842 insertions, 2 deletions
diff --git a/src/sat/bsat/satInter.c b/src/sat/bsat/satInter.c
new file mode 100644
index 00000000..e22b309c
--- /dev/null
+++ b/src/sat/bsat/satInter.c
@@ -0,0 +1,980 @@
+/**CFile****************************************************************
+
+ FileName [satInter.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT sat_solver.]
+
+ Synopsis [Interpolation package.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: satInter.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "satStore.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+// variable assignments
+static const lit LIT_UNDEF = 0xffffffff;
+
+// interpolation manager
+struct Int_Man_t_
+{
+ // clauses of the problems
+ Sto_Man_t * pCnf; // the set of CNF clauses for A and B
+ // various parameters
+ int fVerbose; // verbosiness flag
+ int fProofVerif; // verifies the proof
+ int fProofWrite; // writes the proof file
+ int nVarsAlloc; // the allocated size of var arrays
+ int nClosAlloc; // the allocated size of clause arrays
+ // internal BCP
+ int nRootSize; // the number of root level assignments
+ int nTrailSize; // the number of assignments made
+ lit * pTrail; // chronological order of assignments (size nVars)
+ lit * pAssigns; // assignments by variable (size nVars)
+ char * pSeens; // temporary mark (size nVars)
+ Sto_Cls_t ** pReasons; // reasons for each assignment (size nVars)
+ Sto_Cls_t ** pWatches; // watched clauses for each literal (size 2*nVars)
+ // interpolation data
+ int nVarsAB; // the number of global variables
+ char * pVarTypes; // variable type (size nVars) [1=A, 0=B, <0=AB]
+ unsigned * pInters; // storage for interpolants as truth tables (size nClauses)
+ int nIntersAlloc; // the allocated size of truth table array
+ int nWords; // the number of words in the truth table
+ // proof recording
+ int Counter; // counter of resolved clauses
+ int * pProofNums; // the proof numbers for each clause (size nClauses)
+ FILE * pFile; // the file for proof recording
+ // internal verification
+ lit * pResLits; // the literals of the resolvent
+ int nResLits; // the number of literals of the resolvent
+ int nResLitsAlloc;// the number of literals of the resolvent
+ // runtime stats
+ int timeBcp; // the runtime for BCP
+ int timeTrace; // the runtime of trace construction
+ int timeTotal; // the total runtime of interpolation
+};
+
+// procedure to get hold of the clauses' truth table
+static inline unsigned * Int_ManTruthRead( Int_Man_t * p, Sto_Cls_t * pCls ) { return p->pInters + pCls->Id * p->nWords; }
+static inline void Int_ManTruthClear( unsigned * p, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] = 0; }
+static inline void Int_ManTruthFill( unsigned * p, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] = ~0; }
+static inline void Int_ManTruthCopy( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] = q[i]; }
+static inline void Int_ManTruthAnd( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] &= q[i]; }
+static inline void Int_ManTruthOr( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] |= q[i]; }
+static inline void Int_ManTruthOrNot( unsigned * p, unsigned * q, int nWords ) { int i; for ( i = nWords - 1; i >= 0; i-- ) p[i] |= ~q[i]; }
+
+// reading/writing the proof for a clause
+static inline int Int_ManProofRead( Int_Man_t * p, Sto_Cls_t * pCls ) { return p->pProofNums[pCls->Id]; }
+static inline void Int_ManProofWrite( Int_Man_t * p, Sto_Cls_t * pCls, int n ) { p->pProofNums[pCls->Id] = n; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Allocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Int_Man_t * Int_ManAlloc( int nVarsAlloc )
+{
+ Int_Man_t * p;
+ // allocate the manager
+ p = (Int_Man_t *)malloc( sizeof(Int_Man_t) );
+ memset( p, 0, sizeof(Int_Man_t) );
+ // verification
+ p->nResLitsAlloc = (1<<16);
+ p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc );
+ // parameters
+ p->fProofWrite = 0;
+ p->fProofVerif = 0;
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Count common variables in the clauses of A and B.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Int_ManCommonVars( Int_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int Var, nVarsAB, v;
+
+ // mark the variable encountered in the clauses of A
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( !pClause->fA )
+ break;
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ p->pVarTypes[lit_var(pClause->pLits[v])] = 1;
+ }
+
+ // check variables that appear in clauses of B
+ nVarsAB = 0;
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( pClause->fA )
+ continue;
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( p->pVarTypes[Var] == 1 ) // var of A
+ {
+ // change it into a global variable
+ nVarsAB++;
+ p->pVarTypes[Var] = -1;
+ }
+ }
+ }
+
+ // order global variables
+ nVarsAB = 0;
+ for ( v = 0; v < p->pCnf->nVars; v++ )
+ if ( p->pVarTypes[v] == -1 )
+ p->pVarTypes[v] -= p->nVarsAB++;
+printf( "There are %d global variables.\n", nVarsAB );
+ return nVarsAB;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resize proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Int_ManResize( Int_Man_t * p )
+{
+ // check if resizing is needed
+ if ( p->nVarsAlloc < p->pCnf->nVars )
+ {
+ int nVarsAllocOld = p->nVarsAlloc;
+ // find the new size
+ if ( p->nVarsAlloc == 0 )
+ p->nVarsAlloc = 1;
+ while ( p->nVarsAlloc < p->pCnf->nVars )
+ p->nVarsAlloc *= 2;
+ // resize the arrays
+ p->pTrail = (lit *) realloc( p->pTrail, sizeof(lit) * p->nVarsAlloc );
+ p->pAssigns = (lit *) realloc( p->pAssigns, sizeof(lit) * p->nVarsAlloc );
+ p->pSeens = (char *) realloc( p->pSeens, sizeof(char) * p->nVarsAlloc );
+ p->pVarTypes = (char *) realloc( p->pVarTypes, sizeof(char) * p->nVarsAlloc );
+ p->pReasons = (Sto_Cls_t **)realloc( p->pReasons, sizeof(Sto_Cls_t *) * p->nVarsAlloc );
+ p->pWatches = (Sto_Cls_t **)realloc( p->pWatches, sizeof(Sto_Cls_t *) * p->nVarsAlloc*2 );
+ }
+
+ // clean the free space
+ memset( p->pAssigns , 0xff, sizeof(lit) * p->pCnf->nVars );
+ memset( p->pSeens , 0, sizeof(char) * p->pCnf->nVars );
+ memset( p->pVarTypes, 0, sizeof(char) * p->pCnf->nVars );
+ memset( p->pReasons , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars );
+ memset( p->pWatches , 0, sizeof(Sto_Cls_t *) * p->pCnf->nVars*2 );
+
+ // compute the number of common variables
+ p->nVarsAB = Int_ManCommonVars( p );
+ // compute the number of words in the truth table
+ p->nWords = (p->nVarsAB <= 5 ? 1 : (1 << (p->nVarsAB - 5)));
+
+ // check if resizing of clauses is needed
+ if ( p->nClosAlloc < p->pCnf->nClauses )
+ {
+ // find the new size
+ if ( p->nClosAlloc == 0 )
+ p->nClosAlloc = 1;
+ while ( p->nClosAlloc < p->pCnf->nClauses )
+ p->nClosAlloc *= 2;
+ // resize the arrays
+ p->pProofNums = (int *) realloc( p->pProofNums, sizeof(int) * p->nClosAlloc );
+ }
+ memset( p->pProofNums, 0, sizeof(int) * p->pCnf->nClauses );
+
+ // check if resizing of truth tables is needed
+ if ( p->nIntersAlloc < p->nWords * p->pCnf->nClauses )
+ {
+ p->nIntersAlloc = p->nWords * p->pCnf->nClauses;
+ p->pInters = (unsigned *) realloc( p->pInters, sizeof(unsigned) * p->nIntersAlloc );
+ }
+ memset( p->pInters, 0, sizeof(unsigned) * p->nIntersAlloc );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deallocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Int_ManFree( Int_Man_t * p )
+{
+ printf( "Runtime stats:\n" );
+PRT( "BCP ", p->timeBcp );
+PRT( "Trace ", p->timeTrace );
+PRT( "TOTAL ", p->timeTotal );
+
+ free( p->pInters );
+ free( p->pProofNums );
+ free( p->pTrail );
+ free( p->pAssigns );
+ free( p->pSeens );
+ free( p->pVarTypes );
+ free( p->pReasons );
+ free( p->pWatches );
+ free( p->pResLits );
+ free( p );
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Prints the clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Int_ManPrintClause( Int_Man_t * p, Sto_Cls_t * pClause )
+{
+ int i;
+ printf( "Clause ID = %d. Proof = %d. {", pClause->Id, Int_ManProofRead(p, pClause) );
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ printf( " %d", pClause->pLits[i] );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the resolvent.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Int_ManPrintResolvent( lit * pResLits, int nResLits )
+{
+ int i;
+ printf( "Resolvent: {" );
+ for ( i = 0; i < nResLits; i++ )
+ printf( " %d", pResLits[i] );
+ printf( " }\n" );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records the proof.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Extra_PrintBinary__( FILE * pFile, unsigned Sign[], int nBits )
+{
+ int Remainder, nWords;
+ int w, i;
+
+ Remainder = (nBits%(sizeof(unsigned)*8));
+ nWords = (nBits/(sizeof(unsigned)*8)) + (Remainder>0);
+
+ for ( w = nWords-1; w >= 0; w-- )
+ for ( i = ((w == nWords-1 && Remainder)? Remainder-1: 31); i >= 0; i-- )
+ fprintf( pFile, "%c", '0' + (int)((Sign[w] & (1<<i)) > 0) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prints the interpolant for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Int_ManPrintInterOne( Int_Man_t * p, Sto_Cls_t * pClause )
+{
+ printf( "Clause %2d : ", pClause->Id );
+ Extra_PrintBinary__( stdout, Int_ManTruthRead(p, pClause), (1 << p->nVarsAB) );
+ printf( "\n" );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Adds one clause to the watcher list.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Int_ManWatchClause( Int_Man_t * p, Sto_Cls_t * pClause, lit Lit )
+{
+ assert( lit_check(Lit, p->pCnf->nVars) );
+ if ( pClause->pLits[0] == Lit )
+ pClause->pNext0 = p->pWatches[lit_neg(Lit)];
+ else
+ {
+ assert( pClause->pLits[1] == Lit );
+ pClause->pNext1 = p->pWatches[lit_neg(Lit)];
+ }
+ p->pWatches[lit_neg(Lit)] = pClause;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Records implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int Int_ManEnqueue( Int_Man_t * p, lit Lit, Sto_Cls_t * pReason )
+{
+ int Var = lit_var(Lit);
+ if ( p->pAssigns[Var] != LIT_UNDEF )
+ return p->pAssigns[Var] == Lit;
+ p->pAssigns[Var] = Lit;
+ p->pReasons[Var] = pReason;
+ p->pTrail[p->nTrailSize++] = Lit;
+//printf( "assigning var %d value %d\n", Var, !lit_sign(Lit) );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records implication.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void Int_ManCancelUntil( Int_Man_t * p, int Level )
+{
+ lit Lit;
+ int i, Var;
+ for ( i = p->nTrailSize - 1; i >= Level; i-- )
+ {
+ Lit = p->pTrail[i];
+ Var = lit_var( Lit );
+ p->pReasons[Var] = NULL;
+ p->pAssigns[Var] = LIT_UNDEF;
+//printf( "cancelling var %d\n", Var );
+ }
+ p->nTrailSize = Level;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate one assignment.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline Sto_Cls_t * Int_ManPropagateOne( Int_Man_t * p, lit Lit )
+{
+ Sto_Cls_t ** ppPrev, * pCur, * pTemp;
+ lit LitF = lit_neg(Lit);
+ int i;
+ // iterate through the literals
+ ppPrev = p->pWatches + Lit;
+ for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev )
+ {
+ // make sure the false literal is in the second literal of the clause
+ if ( pCur->pLits[0] == LitF )
+ {
+ pCur->pLits[0] = pCur->pLits[1];
+ pCur->pLits[1] = LitF;
+ pTemp = pCur->pNext0;
+ pCur->pNext0 = pCur->pNext1;
+ pCur->pNext1 = pTemp;
+ }
+ assert( pCur->pLits[1] == LitF );
+
+ // if the first literal is true, the clause is satisfied
+ if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] )
+ {
+ ppPrev = &pCur->pNext1;
+ continue;
+ }
+
+ // look for a new literal to watch
+ for ( i = 2; i < (int)pCur->nLits; i++ )
+ {
+ // skip the case when the literal is false
+ if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] )
+ continue;
+ // the literal is either true or unassigned - watch it
+ pCur->pLits[1] = pCur->pLits[i];
+ pCur->pLits[i] = LitF;
+ // remove this clause from the watch list of Lit
+ *ppPrev = pCur->pNext1;
+ // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1])
+ Int_ManWatchClause( p, pCur, pCur->pLits[1] );
+ break;
+ }
+ if ( i < (int)pCur->nLits ) // found new watch
+ continue;
+
+ // clause is unit - enqueue new implication
+ if ( Int_ManEnqueue(p, pCur->pLits[0], pCur) )
+ {
+ ppPrev = &pCur->pNext1;
+ continue;
+ }
+
+ // conflict detected - return the conflict clause
+ return pCur;
+ }
+ return NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate the current assignments.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Sto_Cls_t * Int_ManPropagate( Int_Man_t * p, int Start )
+{
+ Sto_Cls_t * pClause;
+ int i;
+ int clk = clock();
+ for ( i = Start; i < p->nTrailSize; i++ )
+ {
+ pClause = Int_ManPropagateOne( p, p->pTrail[i] );
+ if ( pClause )
+ {
+p->timeBcp += clock() - clk;
+ return pClause;
+ }
+ }
+p->timeBcp += clock() - clk;
+ return NULL;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes one root clause into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Int_ManProofWriteOne( Int_Man_t * p, Sto_Cls_t * pClause )
+{
+ Int_ManProofWrite( p, pClause, ++p->Counter );
+
+ if ( p->fProofWrite )
+ {
+ int v;
+ fprintf( p->pFile, "%d", Int_ManProofRead(p, pClause) );
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ fprintf( p->pFile, " %d", lit_print(pClause->pLits[v]) );
+ fprintf( p->pFile, " 0 0\n" );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Traces the proof for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Int_ManProofTraceOne( Int_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFinal )
+{
+ Sto_Cls_t * pReason;
+ int i, v, Var, PrevId;
+ int fPrint = 0;
+ int clk = clock();
+
+ // collect resolvent literals
+ if ( p->fProofVerif )
+ {
+ assert( (int)pConflict->nLits <= p->nResLitsAlloc );
+ memcpy( p->pResLits, pConflict->pLits, sizeof(lit) * pConflict->nLits );
+ p->nResLits = pConflict->nLits;
+ }
+
+ // mark all the variables in the conflict as seen
+ for ( v = 0; v < (int)pConflict->nLits; v++ )
+ p->pSeens[lit_var(pConflict->pLits[v])] = 1;
+
+ // start the anticedents
+// pFinal->pAntis = Vec_PtrAlloc( 32 );
+// Vec_PtrPush( pFinal->pAntis, pConflict );
+
+ if ( p->pCnf->nClausesA )
+ Int_ManTruthCopy( Int_ManTruthRead(p, pFinal), Int_ManTruthRead(p, pConflict), p->nWords );
+
+ // follow the trail backwards
+ PrevId = Int_ManProofRead(p, pConflict);
+ for ( i = p->nTrailSize - 1; i >= 0; i-- )
+ {
+ // skip literals that are not involved
+ Var = lit_var(p->pTrail[i]);
+ if ( !p->pSeens[Var] )
+ continue;
+ p->pSeens[Var] = 0;
+
+ // skip literals of the resulting clause
+ pReason = p->pReasons[Var];
+ if ( pReason == NULL )
+ continue;
+ assert( p->pTrail[i] == pReason->pLits[0] );
+
+ // add the variables to seen
+ for ( v = 1; v < (int)pReason->nLits; v++ )
+ p->pSeens[lit_var(pReason->pLits[v])] = 1;
+
+
+ // record the reason clause
+ assert( Int_ManProofRead(p, pReason) > 0 );
+ p->Counter++;
+ if ( p->fProofWrite )
+ fprintf( p->pFile, "%d * %d %d 0\n", p->Counter, PrevId, Int_ManProofRead(p, pReason) );
+ PrevId = p->Counter;
+
+ if ( p->pCnf->nClausesA )
+ {
+ if ( p->pVarTypes[Var] == 1 ) // var of A
+ Int_ManTruthOr( Int_ManTruthRead(p, pFinal), Int_ManTruthRead(p, pReason), p->nWords );
+ else
+ Int_ManTruthAnd( Int_ManTruthRead(p, pFinal), Int_ManTruthRead(p, pReason), p->nWords );
+ }
+
+ // resolve the temporary resolvent with the reason clause
+ if ( p->fProofVerif )
+ {
+ int v1, v2;
+ if ( fPrint )
+ Int_ManPrintResolvent( p->pResLits, p->nResLits );
+ // check that the var is present in the resolvent
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ if ( lit_var(p->pResLits[v1]) == Var )
+ break;
+ if ( v1 == p->nResLits )
+ printf( "Recording clause %d: Cannot find variable %d in the temporary resolvent.\n", pFinal->Id, Var );
+ if ( p->pResLits[v1] != lit_neg(pReason->pLits[0]) )
+ printf( "Recording clause %d: The resolved variable %d is in the wrong polarity.\n", pFinal->Id, Var );
+ // remove this variable from the resolvent
+ assert( lit_var(p->pResLits[v1]) == Var );
+ p->nResLits--;
+ for ( ; v1 < p->nResLits; v1++ )
+ p->pResLits[v1] = p->pResLits[v1+1];
+ // add variables of the reason clause
+ for ( v2 = 1; v2 < (int)pReason->nLits; v2++ )
+ {
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ if ( lit_var(p->pResLits[v1]) == lit_var(pReason->pLits[v2]) )
+ break;
+ // if it is a new variable, add it to the resolvent
+ if ( v1 == p->nResLits )
+ {
+ if ( p->nResLits == p->nResLitsAlloc )
+ printf( "Recording clause %d: Ran out of space for intermediate resolvent.\n, pFinal->Id" );
+ p->pResLits[ p->nResLits++ ] = pReason->pLits[v2];
+ continue;
+ }
+ // if the variable is the same, the literal should be the same too
+ if ( p->pResLits[v1] == pReason->pLits[v2] )
+ continue;
+ // the literal is different
+ printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id );
+ }
+ }
+
+// Vec_PtrPush( pFinal->pAntis, pReason );
+ }
+
+ // unmark all seen variables
+// for ( i = p->nTrailSize - 1; i >= 0; i-- )
+// p->pSeens[lit_var(p->pTrail[i])] = 0;
+ // check that the literals are unmarked
+// for ( i = p->nTrailSize - 1; i >= 0; i-- )
+// assert( p->pSeens[lit_var(p->pTrail[i])] == 0 );
+
+ // use the resulting clause to check the correctness of resolution
+ if ( p->fProofVerif )
+ {
+ int v1, v2;
+ if ( fPrint )
+ Int_ManPrintResolvent( p->pResLits, p->nResLits );
+ for ( v1 = 0; v1 < p->nResLits; v1++ )
+ {
+ for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ )
+ if ( pFinal->pLits[v2] == p->pResLits[v1] )
+ break;
+ if ( v2 < (int)pFinal->nLits )
+ continue;
+ break;
+ }
+ if ( v1 < p->nResLits )
+ {
+ printf( "Recording clause %d: The final resolvent is wrong.\n", pFinal->Id );
+ Int_ManPrintClause( p, pConflict );
+ Int_ManPrintResolvent( p->pResLits, p->nResLits );
+ Int_ManPrintClause( p, pFinal );
+ }
+ }
+p->timeTrace += clock() - clk;
+
+ // return the proof pointer
+ if ( p->pCnf->nClausesA )
+ {
+// Int_ManPrintInterOne( p, pFinal );
+ }
+ Int_ManProofWrite( p, pFinal, p->Counter );
+ return p->Counter;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records the proof for one clause.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Int_ManProofRecordOne( Int_Man_t * p, Sto_Cls_t * pClause )
+{
+ Sto_Cls_t * pConflict;
+ int i;
+
+ // empty clause never ends up there
+ assert( pClause->nLits > 0 );
+ if ( pClause->nLits == 0 )
+ printf( "Error: Empty clause is attempted.\n" );
+
+ // add assumptions to the trail
+ assert( !pClause->fRoot );
+ assert( p->nTrailSize == p->nRootSize );
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ if ( !Int_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )
+ {
+ assert( 0 ); // impossible
+ return 0;
+ }
+
+ // propagate the assumptions
+ pConflict = Int_ManPropagate( p, p->nRootSize );
+ if ( pConflict == NULL )
+ {
+ assert( 0 ); // cannot prove
+ return 0;
+ }
+
+ // construct the proof
+ Int_ManProofTraceOne( p, pConflict, pClause );
+
+ // undo to the root level
+ Int_ManCancelUntil( p, p->nRootSize );
+
+ // add large clauses to the watched lists
+ if ( pClause->nLits > 1 )
+ {
+ Int_ManWatchClause( p, pClause, pClause->pLits[0] );
+ Int_ManWatchClause( p, pClause, pClause->pLits[1] );
+ return 1;
+ }
+ assert( pClause->nLits == 1 );
+
+ // if the clause proved is unit, add it and propagate
+ if ( !Int_ManEnqueue( p, pClause->pLits[0], pClause ) )
+ {
+ assert( 0 ); // impossible
+ return 0;
+ }
+
+ // propagate the assumption
+ pConflict = Int_ManPropagate( p, p->nRootSize );
+ if ( pConflict )
+ {
+ // construct the proof
+ Int_ManProofTraceOne( p, pConflict, p->pCnf->pEmpty );
+ printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id );
+ return 0;
+ }
+
+ // update the root level
+ p->nRootSize = p->nTrailSize;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Propagate the root clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Int_ManProcessRoots( Int_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ int Counter;
+
+ // make sure the root clauses are preceeding the learnt clauses
+ Counter = 0;
+ Sto_ManForEachClause( p->pCnf, pClause )
+ {
+ assert( (int)pClause->fA == (Counter < (int)p->pCnf->nClausesA) );
+ assert( (int)pClause->fRoot == (Counter < (int)p->pCnf->nRoots) );
+ Counter++;
+ }
+ assert( p->pCnf->nClauses == Counter );
+
+ // make sure the last clause if empty
+ assert( p->pCnf->pTail->nLits == 0 );
+
+ // go through the root unit clauses
+ p->nTrailSize = 0;
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ // create watcher lists for the root clauses
+ if ( pClause->nLits > 1 )
+ {
+ Int_ManWatchClause( p, pClause, pClause->pLits[0] );
+ Int_ManWatchClause( p, pClause, pClause->pLits[1] );
+ }
+ // empty clause and large clauses
+ if ( pClause->nLits != 1 )
+ continue;
+ // unit clause
+ assert( lit_check(pClause->pLits[0], p->pCnf->nVars) );
+ if ( !Int_ManEnqueue( p, pClause->pLits[0], pClause ) )
+ {
+ // detected root level conflict
+ printf( "Int_ManProcessRoots(): Detected a root-level conflict\n" );
+ assert( 0 );
+ return 0;
+ }
+ }
+
+ // propagate the root unit clauses
+ pClause = Int_ManPropagate( p, 0 );
+ if ( pClause )
+ {
+ // detected root level conflict
+ printf( "Int_ManProcessRoots(): Detected a root-level conflict\n" );
+ assert( 0 );
+ return 0;
+ }
+
+ // set the root level
+ p->nRootSize = p->nTrailSize;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Records the proof.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Int_ManPrepareInter( Int_Man_t * p )
+{
+ // elementary truth tables
+ unsigned uTruths[8][8] = {
+ { 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA },
+ { 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC },
+ { 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
+ { 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
+ { 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
+ { 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
+ { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
+ };
+ Sto_Cls_t * pClause;
+ int Var, v;
+ assert( p->nVarsAB <= 8 );
+
+ // set interpolants for root clauses
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ {
+ if ( !pClause->fA ) // clause of B
+ {
+ Int_ManTruthFill( Int_ManTruthRead(p, pClause), p->nWords );
+// Int_ManPrintInterOne( p, pClause );
+ continue;
+ }
+ // clause of A
+ Int_ManTruthClear( Int_ManTruthRead(p, pClause), p->nWords );
+ for ( v = 0; v < (int)pClause->nLits; v++ )
+ {
+ Var = lit_var(pClause->pLits[v]);
+ if ( p->pVarTypes[Var] < 0 ) // global var
+ {
+ if ( lit_sign(pClause->pLits[v]) ) // negative var
+ Int_ManTruthOrNot( Int_ManTruthRead(p, pClause), uTruths[ -p->pVarTypes[Var]-1 ], p->nWords );
+ else
+ Int_ManTruthOr( Int_ManTruthRead(p, pClause), uTruths[ -p->pVarTypes[Var]-1 ], p->nWords );
+ }
+ }
+// Int_ManPrintInterOne( p, pClause );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Computes interpolant for the given CNF.]
+
+ Description [Returns the number of common variable found and interpolant.
+ Returns 0, if something did not work.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Int_ManInterpolate( Int_Man_t * p, Sto_Man_t * pCnf, int fVerbose, unsigned ** ppResult )
+{
+ Sto_Cls_t * pClause;
+ int RetValue = 1;
+ int clkTotal = clock();
+
+ // check that the CNF makes sense
+ assert( pCnf->nVars > 0 && pCnf->nClauses > 0 );
+
+ // adjust the manager
+ Int_ManResize( p );
+
+ // propagate root level assignments
+ Int_ManProcessRoots( p );
+
+ // prepare the interpolant computation
+ Int_ManPrepareInter( p );
+
+ // construct proof for each clause
+ // start the proof
+ if ( p->fProofWrite )
+ {
+ p->pFile = fopen( "proof.cnf_", "w" );
+ p->Counter = 0;
+ }
+
+ // write the root clauses
+ Sto_ManForEachClauseRoot( p->pCnf, pClause )
+ Int_ManProofWriteOne( p, pClause );
+
+ // consider each learned clause
+ Sto_ManForEachClause( p->pCnf, pClause )
+ {
+ if ( pClause->fRoot )
+ continue;
+ if ( !Int_ManProofRecordOne( p, pClause ) )
+ {
+ RetValue = 0;
+ break;
+ }
+ }
+
+ // stop the proof
+ if ( p->fProofWrite )
+ {
+ fclose( p->pFile );
+ p->pFile = NULL;
+ }
+
+ printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d. Ave = %.2f. Mem = %.2f Mb\n",
+ p->pCnf->nVars, p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, p->Counter,
+ 1.0*(p->Counter-p->pCnf->nRoots)/(p->pCnf->nClauses-p->pCnf->nRoots),
+ 1.0*Sto_ManMemoryReport(p->pCnf)/(1<<20) );
+
+p->timeTotal += clock() - clkTotal;
+ Int_ManFree( p );
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c
index 1dd40155..6aafc187 100644
--- a/src/sat/bsat/satSolver.c
+++ b/src/sat/bsat/satSolver.c
@@ -477,6 +477,16 @@ static void sat_solver_record(sat_solver* s, veci* cls)
clause* c = (veci_size(cls) > 1) ? clause_new(s,begin,end,1) : (clause*)0;
enqueue(s,*begin,c);
+ ///////////////////////////////////
+ // add clause to internal storage
+ if ( s->pStore )
+ {
+ extern int Sto_ManAddClause( void * p, lit * pBeg, lit * pEnd );
+ int RetValue = Sto_ManAddClause( s->pStore, begin, end );
+ assert( RetValue );
+ }
+ ///////////////////////////////////
+
assert(veci_size(cls) > 0);
if (c != 0) {
@@ -1022,6 +1032,7 @@ void sat_solver_delete(sat_solver* s)
free(s->tags );
}
+ sat_solver_store_free(s);
free(s);
}
@@ -1046,6 +1057,7 @@ bool sat_solver_addclause(sat_solver* s, lit* begin, lit* end)
*j = l;
}
sat_solver_setnvars(s,maxvar+1);
+// sat_solver_setnvars(s, lit_var(*(end-1))+1 );
//printlits(begin,end); printf("\n");
values = s->assigns;
@@ -1065,7 +1077,18 @@ bool sat_solver_addclause(sat_solver* s, lit* begin, lit* end)
if (j == begin) // empty clause
return false;
- else if (j - begin == 1) // unit clause
+
+ ///////////////////////////////////
+ // add clause to internal storage
+ if ( s->pStore )
+ {
+ extern int Sto_ManAddClause( void * p, lit * pBeg, lit * pEnd );
+ int RetValue = Sto_ManAddClause( s->pStore, begin, j );
+ assert( RetValue );
+ }
+ ///////////////////////////////////
+
+ if (j - begin == 1) // unit clause
return enqueue(s,*begin,(clause*)0);
// create new clause
@@ -1198,6 +1221,15 @@ int sat_solver_solve(sat_solver* s, lit* begin, lit* end, sint64 nConfLimit, sin
printf("==============================================================================\n");
sat_solver_canceluntil(s,0);
+
+ ////////////////////////////////////////////////
+ if ( status == l_Undef && s->pStore )
+ {
+ extern int Sto_ManAddClause( void * p, lit * pBeg, lit * pEnd );
+ int RetValue = Sto_ManAddClause( s->pStore, NULL, NULL );
+ assert( RetValue );
+ }
+ ////////////////////////////////////////////////
return status;
}
@@ -1220,6 +1252,51 @@ int sat_solver_nconflicts(sat_solver* s)
}
//=================================================================================================
+// Clause storage functions:
+
+void sat_solver_store_alloc( sat_solver * s )
+{
+ extern void * Sto_ManAlloc();
+ assert( s->pStore == NULL );
+ s->pStore = Sto_ManAlloc();
+}
+
+void sat_solver_store_write( sat_solver * s, char * pFileName )
+{
+ extern void Sto_ManDumpClauses( void * p, char * pFileName );
+ Sto_ManDumpClauses( s->pStore, pFileName );
+}
+
+void sat_solver_store_free( sat_solver * s )
+{
+ extern void Sto_ManFree( void * p );
+ if ( s->pStore ) Sto_ManFree( s->pStore );
+ s->pStore = NULL;
+}
+
+void sat_solver_store_mark_roots( sat_solver * s )
+{
+ extern void Sto_ManMarkRoots( void * p );
+ if ( s->pStore ) Sto_ManMarkRoots( s->pStore );
+}
+
+void sat_solver_store_mark_clauses_a( sat_solver * s )
+{
+ extern void Sto_ManMarkClausesA( void * p );
+ if ( s->pStore ) Sto_ManMarkClausesA( s->pStore );
+}
+
+void * sat_solver_store_release( sat_solver * s )
+{
+ void * pTemp;
+ if ( s->pStore == NULL )
+ return NULL;
+ pTemp = s->pStore;
+ s->pStore = NULL;
+ return pTemp;
+}
+
+//=================================================================================================
// Sorting functions (sigh):
static inline void selectionsort(void** array, int size, int(*comp)(const void *, const void *))
diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h
index 6c05a14a..8f71370f 100644
--- a/src/sat/bsat/satSolver.h
+++ b/src/sat/bsat/satSolver.h
@@ -33,7 +33,13 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
// Simple types:
// does not work for c++
-typedef int bool;
+//typedef int bool;
+#ifndef __cplusplus
+#ifndef bool
+#define bool int
+#endif
+#endif
+
static const bool true = 1;
static const bool false = 0;
@@ -58,6 +64,8 @@ static inline lit toLitCond(int v, int c) { return v + v + (c != 0); }
static inline lit lit_neg (lit l) { return l ^ 1; }
static inline int lit_var (lit l) { return l >> 1; }
static inline int lit_sign (lit l) { return l & 1; }
+static inline int lit_print(lit l) { return lit_sign(l)? -lit_var(l)-1 : lit_var(l)+1; }
+static inline lit lit_read (int s) { return s > 0 ? toLit(s-1) : lit_neg(toLit(-s-1)); }
//=================================================================================================
@@ -88,6 +96,21 @@ typedef struct stats_t stats;
extern void Sat_SolverWriteDimacs( sat_solver * p, char * pFileName, lit* assumptionsBegin, lit* assumptionsEnd, int incrementVars );
extern void Sat_SolverPrintStats( FILE * pFile, sat_solver * p );
+extern int * Sat_SolverGetModel( sat_solver * p, int * pVars, int nVars );
+extern void Sat_SolverDoubleClauses( sat_solver * p, int iVar );
+
+// trace recording
+extern void Sat_SolverTraceStart( sat_solver * pSat, char * pName );
+extern void Sat_SolverTraceStop( sat_solver * pSat );
+extern void Sat_SolverTraceWrite( sat_solver * pSat, int * pBeg, int * pEnd, int fRoot );
+
+// clause storage
+extern void sat_solver_store_alloc( sat_solver * s );
+extern void sat_solver_store_write( sat_solver * s, char * pFileName );
+extern void sat_solver_store_free( sat_solver * s );
+extern void sat_solver_store_mark_roots( sat_solver * s );
+extern void sat_solver_store_mark_clauses_a( sat_solver * s );
+extern void * sat_solver_store_release( sat_solver * s );
//=================================================================================================
// Solver representation:
@@ -146,6 +169,14 @@ struct sat_solver_t
int nRestarts; // the number of local restarts
Sat_MmStep_t * pMem;
+
+ // clause store
+ void * pStore;
+
+ // trace recording
+ FILE * pFile;
+ int nClauses;
+ int nRoots;
};
#endif
diff --git a/src/sat/bsat/satStore.c b/src/sat/bsat/satStore.c
new file mode 100644
index 00000000..33cba6a7
--- /dev/null
+++ b/src/sat/bsat/satStore.c
@@ -0,0 +1,437 @@
+/**CFile****************************************************************
+
+ FileName [satStore.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT solver.]
+
+ Synopsis [Records the trace of SAT solving in the CNF form.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: satStore.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <time.h>
+#include "satStore.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Fetches memory.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * Sto_ManMemoryFetch( Sto_Man_t * p, int nBytes )
+{
+ char * pMem;
+ if ( p->pChunkLast == NULL || nBytes > p->nChunkSize - p->nChunkUsed )
+ {
+ pMem = (char *)malloc( p->nChunkSize );
+ *(char **)pMem = p->pChunkLast;
+ p->pChunkLast = pMem;
+ p->nChunkUsed = sizeof(char *);
+ }
+ pMem = p->pChunkLast + p->nChunkUsed;
+ p->nChunkUsed += nBytes;
+ return pMem;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Frees memory manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sto_ManMemoryStop( Sto_Man_t * p )
+{
+ char * pMem, * pNext;
+ if ( p->pChunkLast == NULL )
+ return;
+ for ( pMem = p->pChunkLast; pNext = *(char **)pMem; pMem = pNext )
+ free( pMem );
+ free( pMem );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reports memory usage in bytes.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sto_ManMemoryReport( Sto_Man_t * p )
+{
+ int Total;
+ char * pMem, * pNext;
+ if ( p->pChunkLast == NULL )
+ return 0;
+ Total = p->nChunkUsed;
+ for ( pMem = p->pChunkLast; pNext = *(char **)pMem; pMem = pNext )
+ Total += p->nChunkSize;
+ return Total;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Allocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Sto_Man_t * Sto_ManAlloc()
+{
+ Sto_Man_t * p;
+ // allocate the manager
+ p = (Sto_Man_t *)malloc( sizeof(Sto_Man_t) );
+ memset( p, 0, sizeof(Sto_Man_t) );
+ // memory management
+ p->nChunkSize = (1<<16); // use 64K chunks
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Deallocate proof manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sto_ManFree( Sto_Man_t * p )
+{
+ Sto_ManMemoryStop( p );
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Adds one clause to the manager.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sto_ManAddClause( Sto_Man_t * p, lit * pBeg, lit * pEnd )
+{
+ Sto_Cls_t * pClause;
+ lit Lit, * i, * j;
+ int nSize;
+
+ // process the literals
+ if ( pBeg < pEnd )
+ {
+ // insertion sort
+ for ( i = pBeg + 1; i < pEnd; i++ )
+ {
+ Lit = *i;
+ for ( j = i; j > pBeg && *(j-1) > Lit; j-- )
+ *j = *(j-1);
+ *j = Lit;
+ }
+ // make sure there is no duplicated variables
+ for ( i = pBeg + 1; i < pEnd; i++ )
+ if ( lit_var(*(i-1)) == lit_var(*i) )
+ {
+ printf( "The clause contains two literals of the same variable: %d and %d.\n", *(i-1), *i );
+ return 0;
+ }
+ // check the largest var size
+ p->nVars = STO_MAX( p->nVars, lit_var(*(pEnd-1)) + 1 );
+ }
+
+ // get memory for the clause
+ nSize = sizeof(Sto_Cls_t) + sizeof(lit) * (pEnd - pBeg);
+ pClause = (Sto_Cls_t *)Sto_ManMemoryFetch( p, nSize );
+ memset( pClause, 0, sizeof(Sto_Cls_t) );
+
+ // assign the clause
+ pClause->Id = p->nClauses++;
+ pClause->nLits = pEnd - pBeg;
+ memcpy( pClause->pLits, pBeg, sizeof(lit) * (pEnd - pBeg) );
+
+ // add the clause to the list
+ if ( p->pHead == NULL )
+ p->pHead = pClause;
+ if ( p->pTail == NULL )
+ p->pTail = pClause;
+ else
+ {
+ p->pTail->pNext = pClause;
+ p->pTail = pClause;
+ }
+
+ // add the empty clause
+ if ( pClause->nLits == 0 )
+ {
+ if ( p->pEmpty )
+ {
+ printf( "More than one empty clause!\n" );
+ return 0;
+ }
+ p->pEmpty = pClause;
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Mark all clauses added so far as root clauses.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sto_ManMarkRoots( Sto_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ p->nRoots = 0;
+ Sto_ManForEachClause( p, pClause )
+ {
+ pClause->fRoot = 1;
+ p->nRoots++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Mark all clauses added so far as clause of A.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sto_ManMarkClausesA( Sto_Man_t * p )
+{
+ Sto_Cls_t * pClause;
+ p->nClausesA = 0;
+ Sto_ManForEachClause( p, pClause )
+ {
+ pClause->fA = 1;
+ p->nClausesA++;
+ }
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes the stored clauses into a file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sto_ManDumpClauses( Sto_Man_t * p, char * pFileName )
+{
+ FILE * pFile;
+ Sto_Cls_t * pClause;
+ int i;
+ // start the file
+ pFile = fopen( pFileName, "w" );
+ if ( pFile == NULL )
+ {
+ printf( "Error: Cannot open output file (%s).\n", pFileName );
+ return;
+ }
+ // write the data
+ fprintf( pFile, "p %d %d %d %d\n", p->nVars, p->nClauses, p->nRoots, p->nClausesA );
+ Sto_ManForEachClause( p, pClause )
+ {
+ for ( i = 0; i < (int)pClause->nLits; i++ )
+ fprintf( pFile, " %d", lit_print(pClause->pLits[i]) );
+ fprintf( pFile, "\n" );
+ }
+ fprintf( pFile, "\n" );
+ fclose( pFile );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads one literal from file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Sto_ManLoadNumber( FILE * pFile, int * pNumber )
+{
+ int Char, Number = 0, Sign = 0;
+ // skip space-like chars
+ do {
+ Char = fgetc( pFile );
+ if ( Char == EOF )
+ return 0;
+ } while ( Char == ' ' || Char == '\t' || Char == '\r' || Char == '\n' );
+ // read the literal
+ while ( 1 )
+ {
+ // get the next character
+ Char = fgetc( pFile );
+ if ( Char == ' ' || Char == '\t' || Char == '\r' || Char == '\n' )
+ break;
+ // check that the char is a digit
+ if ( (Char < '0' || Char > '9') && Char != '-' )
+ {
+ printf( "Error: Wrong char (%c) in the input file.\n", Char );
+ return 0;
+ }
+ // check if this is a minus
+ if ( Char == '-' )
+ Sign = 1;
+ else
+ Number = 10 * Number + Char;
+ }
+ // return the number
+ *pNumber = Sign? -Number : Number;
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads CNF from file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Sto_Man_t * Sto_ManLoadClauses( char * pFileName )
+{
+ FILE * pFile;
+ Sto_Man_t * p;
+ Sto_Cls_t * pClause;
+ char pBuffer[1024];
+ int nLits, nLitsAlloc, Counter, Number;
+ lit * pLits;
+
+ // start the file
+ pFile = fopen( pFileName, "r" );
+ if ( pFile == NULL )
+ {
+ printf( "Error: Cannot open input file (%s).\n", pFileName );
+ return NULL;
+ }
+
+ // create the manager
+ p = Sto_ManAlloc();
+
+ // alloc the array of literals
+ nLitsAlloc = 1024;
+ pLits = (lit *)malloc( sizeof(lit) * nLitsAlloc );
+
+ // read file header
+ p->nVars = p->nClauses = p->nRoots = p->nClausesA = 0;
+ while ( fgets( pBuffer, 1024, pFile ) )
+ {
+ if ( pBuffer[0] == 'c' )
+ continue;
+ if ( pBuffer[0] == 'p' )
+ {
+ sscanf( pBuffer + 1, "%d %d %d %d", p->nVars, p->nClauses, p->nRoots, p->nClausesA );
+ break;
+ }
+ printf( "Warning: Skipping line: \"%s\"\n", pBuffer );
+ }
+
+ // read the clauses
+ nLits = 0;
+ while ( Sto_ManLoadNumber(pFile, &Number) )
+ {
+ if ( Number == 0 )
+ {
+ int RetValue;
+ RetValue = Sto_ManAddClause( p, pLits, pLits + nLits );
+ assert( RetValue );
+ nLits = 0;
+ continue;
+ }
+ if ( nLits == nLitsAlloc )
+ {
+ nLitsAlloc *= 2;
+ pLits = (lit *)realloc( pLits, sizeof(lit) * nLitsAlloc );
+ }
+ pLits[ nLits++ ] = lit_read(Number);
+ }
+ if ( nLits > 0 )
+ printf( "Error: The last clause was not saved.\n" );
+
+ // count clauses
+ Counter = 0;
+ Sto_ManForEachClause( p, pClause )
+ Counter++;
+
+ // check the number of clauses
+ if ( p->nClauses != Counter )
+ {
+ printf( "Error: The actual number of clauses (%d) is different than declared (%d).\n", Counter, p->nClauses );
+ Sto_ManFree( p );
+ return NULL;
+ }
+
+ free( pLits );
+ fclose( pFile );
+ return p;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/sat/bsat/satStore.h b/src/sat/bsat/satStore.h
new file mode 100644
index 00000000..3db52ada
--- /dev/null
+++ b/src/sat/bsat/satStore.h
@@ -0,0 +1,135 @@
+/**CFile****************************************************************
+
+ FileName [pr.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Proof recording.]
+
+ Synopsis [External declarations.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: pr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#ifndef __PR_H__
+#define __PR_H__
+
+/*
+ The trace of SAT solving contains the original clause of the problem
+ along with the learned clauses derived during SAT solving.
+ The first line of the resulting file contains 3 numbers instead of 2:
+ c <num_vars> <num_all_clauses> <num_root_clauses>
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+#define inline __inline // compatible with MS VS 6.0
+#endif
+
+#ifndef PRT
+#define PRT(a,t) printf("%s = ", (a)); printf("%6.2f sec\n", (float)(t)/(float)(CLOCKS_PER_SEC))
+#endif
+
+#define STO_MAX(a,b) ((a) > (b) ? (a) : (b))
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// PARAMETERS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// BASIC TYPES ///
+////////////////////////////////////////////////////////////////////////
+
+typedef unsigned lit;
+
+typedef struct Sto_Cls_t_ Sto_Cls_t;
+struct Sto_Cls_t_
+{
+ Sto_Cls_t * pNext; // the next clause
+ Sto_Cls_t * pNext0; // the next 0-watch
+ Sto_Cls_t * pNext1; // the next 0-watch
+ int Id; // the clause ID
+ unsigned fA : 1; // belongs to A
+ unsigned fRoot : 1; // original clause
+ unsigned fVisit : 1; // visited clause
+ unsigned nLits : 24; // the number of literals
+ lit pLits[0]; // literals of this clause
+};
+
+typedef struct Sto_Man_t_ Sto_Man_t;
+struct Sto_Man_t_
+{
+ // general data
+ int nVars; // the number of variables
+ int nRoots; // the number of root clauses
+ int nClauses; // the number of all clauses
+ int nClausesA; // the number of clauses of A
+ Sto_Cls_t * pHead; // the head clause
+ Sto_Cls_t * pTail; // the tail clause
+ Sto_Cls_t * pEmpty; // the empty clause
+ // memory management
+ int nChunkSize; // the number of bytes in a chunk
+ int nChunkUsed; // the number of bytes used in the last chunk
+ char * pChunkLast; // the last memory chunk
+};
+
+// variable/literal conversions (taken from MiniSat)
+static inline lit toLit (int v) { return v + v; }
+static inline lit toLitCond(int v, int c) { return v + v + (c != 0); }
+static inline lit lit_neg (lit l) { return l ^ 1; }
+static inline int lit_var (lit l) { return l >> 1; }
+static inline int lit_sign (lit l) { return l & 1; }
+static inline int lit_print(lit l) { return lit_sign(l)? -lit_var(l)-1 : lit_var(l)+1; }
+static inline lit lit_read (int s) { return s > 0 ? toLit(s-1) : lit_neg(toLit(-s-1)); }
+static inline int lit_check(lit l, int n) { return l >= 0 && lit_var(l) < n; }
+
+// iterators through the clauses
+#define Sto_ManForEachClause( p, pCls ) for( pCls = p->pHead; pCls; pCls = pCls->pNext )
+#define Sto_ManForEachClauseRoot( p, pCls ) for( pCls = p->pHead; pCls && pCls->fRoot; pCls = pCls->pNext )
+
+////////////////////////////////////////////////////////////////////////
+/// MACRO DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/*=== satStore.c ==========================================================*/
+extern Sto_Man_t * Sto_ManAlloc();
+extern void Sto_ManFree( Sto_Man_t * p );
+extern int Sto_ManAddClause( Sto_Man_t * p, lit * pBeg, lit * pEnd );
+extern int Sto_ManMemoryReport( Sto_Man_t * p );
+extern void Sto_ManMarkRoots( Sto_Man_t * p );
+extern void Sto_ManMarkClausesA( Sto_Man_t * p );
+
+/*=== satInter.c ==========================================================*/
+typedef struct Int_Man_t_ Int_Man_t;
+extern Int_Man_t * Int_ManAlloc( int nVarsAlloc );
+extern void Int_ManFree( Int_Man_t * p );
+extern int Int_ManInterpolate( Int_Man_t * p, Sto_Man_t * pCnf, int fVerbose, unsigned ** ppResult );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
diff --git a/src/sat/bsat/satTrace.c b/src/sat/bsat/satTrace.c
new file mode 100644
index 00000000..111e8dfb
--- /dev/null
+++ b/src/sat/bsat/satTrace.c
@@ -0,0 +1,109 @@
+/**CFile****************************************************************
+
+ FileName [satTrace.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT sat_solver.]
+
+ Synopsis [Records the trace of SAT solving in the CNF form.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: satTrace.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
+
+***********************************************************************/
+
+#include <stdio.h>
+#include <assert.h>
+#include "satSolver.h"
+
+/*
+ The trace of SAT solving contains the original clause of the problem
+ along with the learned clauses derived during SAT solving.
+ The first line of the resulting file contains 3 numbers instead of 2:
+ c <num_vars> <num_all_clauses> <num_root_clauses>
+*/
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Start the trace recording.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sat_SolverTraceStart( sat_solver * pSat, char * pName )
+{
+ assert( pSat->pFile == NULL );
+ pSat->pFile = fopen( pName, "w" );
+ fprintf( pSat->pFile, " \n" );
+ pSat->nClauses = 0;
+ pSat->nRoots = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Stops the trace recording.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sat_SolverTraceStop( sat_solver * pSat )
+{
+ if ( pSat->pFile == NULL )
+ return;
+ rewind( pSat->pFile );
+ fprintf( pSat->pFile, "p %d %d %d", sat_solver_nvars(pSat), pSat->nClauses, pSat->nRoots );
+ fclose( pSat->pFile );
+ pSat->pFile = NULL;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Writes one clause into the trace file.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sat_SolverTraceWrite( sat_solver * pSat, int * pBeg, int * pEnd, int fRoot )
+{
+ if ( pSat->pFile == NULL )
+ return;
+ pSat->nClauses++;
+ pSat->nRoots += fRoot;
+ for ( ; pBeg < pEnd ; pBeg++ )
+ fprintf( pSat->pFile, " %d", lit_print(*pBeg) );
+ fprintf( pSat->pFile, " 0\n" );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
diff --git a/src/sat/bsat/satUtil.c b/src/sat/bsat/satUtil.c
index f2b78fe6..76cb2dc2 100644
--- a/src/sat/bsat/satUtil.c
+++ b/src/sat/bsat/satUtil.c
@@ -153,6 +153,77 @@ void Sat_SolverPrintStats( FILE * pFile, sat_solver * p )
printf( "inspects : %d\n", (int)p->stats.inspects );
}
+/**Function*************************************************************
+
+ Synopsis [Returns a counter-example.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int * Sat_SolverGetModel( sat_solver * p, int * pVars, int nVars )
+{
+ int * pModel;
+ int i;
+ pModel = ALLOC( int, nVars );
+ for ( i = 0; i < nVars; i++ )
+ {
+ assert( pVars[i] >= 0 && pVars[i] < p->size );
+ pModel[i] = (int)(p->model.ptr[pVars[i]] == l_True);
+ }
+ return pModel;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates all clauses, complements unit clause of the given var.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Sat_SolverDoubleClauses( sat_solver * p, int iVar )
+{
+ clause ** pClauses;
+ lit Lit, * pLits;
+ int RetValue, nClauses, nVarsOld, nLitsOld, nLits, c, v;
+ // get the number of variables
+ nVarsOld = p->size;
+ nLitsOld = 2 * p->size;
+ // extend the solver to depend on two sets of variables
+ sat_solver_setnvars( p, 2 * p->size );
+ // duplicate implications
+ for ( v = 0; v < nVarsOld; v++ )
+ if ( p->assigns[v] != l_Undef )
+ {
+ Lit = nLitsOld + toLitCond( v, p->assigns[v]==l_False );
+ if ( v == iVar )
+ Lit = lit_neg(Lit);
+ RetValue = sat_solver_addclause( p, &Lit, &Lit + 1 );
+ assert( RetValue );
+ }
+ // duplicate clauses
+ nClauses = vecp_size(&p->clauses);
+ pClauses = (clause**)vecp_begin(&p->clauses);
+ for ( c = 0; c < nClauses; c++ )
+ {
+ nLits = clause_size(pClauses[c]);
+ pLits = clause_begin(pClauses[c]);
+ for ( v = 0; v < nLits; v++ )
+ pLits[v] += nLitsOld;
+ RetValue = sat_solver_addclause( p, pLits, pLits + nLits );
+ assert( RetValue );
+ for ( v = 0; v < nLits; v++ )
+ pLits[v] -= nLitsOld;
+ }
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///