mirror of https://github.com/YosysHQ/abc.git
Version abc70123
This commit is contained in:
parent
2167d6c148
commit
b1a913fb5e
2
Makefile
2
Makefile
|
|
@ -12,7 +12,7 @@ MODULES := src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src
|
|||
src/map/fpga src/map/mapper src/map/mio src/map/super src/map/if \
|
||||
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/espresso src/misc/nm src/misc/vec src/misc/hash \
|
||||
src/opt/cut src/opt/dec src/opt/fxu src/opt/rwr src/opt/sim src/opt/ret src/opt/res src/opt/kit \
|
||||
src/sat/asat src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig
|
||||
src/sat/bsat src/sat/csat src/sat/msat src/sat/fraig
|
||||
|
||||
default: $(PROG)
|
||||
|
||||
|
|
|
|||
52
abc.dsp
52
abc.dsp
|
|
@ -1145,42 +1145,6 @@ SOURCE=.\src\bdd\reo\reoUnits.c
|
|||
# Begin Group "sat"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "asat"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\added.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\asatmem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\asatmem.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\jfront.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\satTrace.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\solver.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\solver.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\asat\solver_vec.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "msat"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
|
|
@ -1326,6 +1290,10 @@ SOURCE=.\src\sat\csat\csat_apis.h
|
|||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\bsat\satInter.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\bsat\satMem.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -1342,6 +1310,18 @@ SOURCE=.\src\sat\bsat\satSolver.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\bsat\satStore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\bsat\satStore.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\bsat\satTrace.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\sat\bsat\satUtil.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ extern "C" {
|
|||
#include "cuddInt.h"
|
||||
#include "hop.h"
|
||||
#include "extra.h"
|
||||
#include "solver.h"
|
||||
#include "vec.h"
|
||||
#include "stmm.h"
|
||||
#include "nm.h"
|
||||
|
|
@ -118,6 +117,12 @@ typedef enum {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef signed __int64 sint64; // compatible with MS VS 6.0
|
||||
#else
|
||||
typedef long long sint64;
|
||||
#endif
|
||||
|
||||
typedef struct Abc_Lib_t_ Abc_Lib_t;
|
||||
typedef struct Abc_Ntk_t_ Abc_Ntk_t;
|
||||
typedef struct Abc_Obj_t_ Abc_Obj_t;
|
||||
|
|
@ -725,8 +730,8 @@ extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, i
|
|||
/*=== abcRewrite.c ==========================================================*/
|
||||
extern int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose );
|
||||
/*=== abcSat.c ==========================================================*/
|
||||
extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fJFront, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects );
|
||||
extern solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront, int fAllPrimes );
|
||||
extern int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects );
|
||||
extern void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes );
|
||||
/*=== abcSop.c ==========================================================*/
|
||||
extern char * Abc_SopRegister( Extra_MmFlex_t * pMan, char * pName );
|
||||
extern char * Abc_SopStart( Extra_MmFlex_t * pMan, int nCubes, int nVars );
|
||||
|
|
@ -761,8 +766,6 @@ extern bool Abc_SopIsAndType( char * pSop );
|
|||
extern bool Abc_SopIsOrType( char * pSop );
|
||||
extern int Abc_SopIsExorType( char * pSop );
|
||||
extern bool Abc_SopCheck( char * pSop, int nFanins );
|
||||
extern void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars );
|
||||
extern void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp );
|
||||
extern char * Abc_SopFromTruthBin( char * pTruth );
|
||||
extern char * Abc_SopFromTruthHex( char * pTruth );
|
||||
/*=== abcStrash.c ==========================================================*/
|
||||
|
|
|
|||
|
|
@ -799,77 +799,6 @@ bool Abc_SopCheck( char * pSop, int nFanins )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the CNF of the SOP into file.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SopWriteCnf( FILE * pFile, char * pClauses, Vec_Int_t * vVars )
|
||||
{
|
||||
char * pChar;
|
||||
int i;
|
||||
// check the logic function of the node
|
||||
for ( pChar = pClauses; *pChar; pChar++ )
|
||||
{
|
||||
// write the clause
|
||||
for ( i = 0; i < vVars->nSize; i++, pChar++ )
|
||||
if ( *pChar == '0' )
|
||||
fprintf( pFile, "%d ", vVars->pArray[i] );
|
||||
else if ( *pChar == '1' )
|
||||
fprintf( pFile, "%d ", -vVars->pArray[i] );
|
||||
fprintf( pFile, "0\n" );
|
||||
// check that the remainig part is fine
|
||||
assert( *pChar == ' ' );
|
||||
pChar++;
|
||||
assert( *pChar == '1' );
|
||||
pChar++;
|
||||
assert( *pChar == '\n' );
|
||||
}
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds the clauses of for the CNF to the solver.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SopAddCnfToSolver( solver * pSat, char * pClauses, Vec_Int_t * vVars, Vec_Int_t * vTemp )
|
||||
{
|
||||
char * pChar;
|
||||
int i, RetValue;
|
||||
// check the logic function of the node
|
||||
for ( pChar = pClauses; *pChar; pChar++ )
|
||||
{
|
||||
// add the clause
|
||||
vTemp->nSize = 0;
|
||||
for ( i = 0; i < vVars->nSize; i++, pChar++ )
|
||||
if ( *pChar == '0' )
|
||||
Vec_IntPush( vTemp, toLit(vVars->pArray[i]) );
|
||||
else if ( *pChar == '1' )
|
||||
Vec_IntPush( vTemp, neg(toLit(vVars->pArray[i])) );
|
||||
// add the clause to the solver
|
||||
RetValue = solver_addclause( pSat, vTemp->pArray, vTemp->pArray + vTemp->nSize );
|
||||
assert( RetValue != 1 );
|
||||
// check that the remainig part is fine
|
||||
assert( *pChar == ' ' );
|
||||
pChar++;
|
||||
assert( *pChar == '1' );
|
||||
pChar++;
|
||||
assert( *pChar == '\n' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -9206,7 +9206,6 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
Abc_Ntk_t * pNtk;
|
||||
int c;
|
||||
int RetValue;
|
||||
int fJFront;
|
||||
int fVerbose;
|
||||
int nConfLimit;
|
||||
int nInsLimit;
|
||||
|
|
@ -9217,12 +9216,11 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
pErr = Abc_FrameReadErr(pAbc);
|
||||
|
||||
// set defaults
|
||||
fJFront = 0;
|
||||
fVerbose = 0;
|
||||
nConfLimit = 100000;
|
||||
nInsLimit = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CIvjh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "CIvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -9248,9 +9246,6 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( nInsLimit < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'j':
|
||||
fJFront ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -9275,13 +9270,13 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
clk = clock();
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
{
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)nConfLimit, (sint64)nInsLimit, fJFront, fVerbose, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)nConfLimit, (sint64)nInsLimit, fVerbose, NULL, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( Abc_NtkIsLogic(pNtk) );
|
||||
Abc_NtkLogicToBdd( pNtk );
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)nConfLimit, (sint64)nInsLimit, fJFront, fVerbose, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)nConfLimit, (sint64)nInsLimit, fVerbose, NULL, NULL );
|
||||
}
|
||||
|
||||
// verify that the pattern is correct
|
||||
|
|
@ -9316,12 +9311,11 @@ int Abc_CommandSat( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pErr, "usage: sat [-C num] [-I num] [-jvh]\n" );
|
||||
fprintf( pErr, "usage: sat [-C num] [-I num] [-vh]\n" );
|
||||
fprintf( pErr, "\t solves the combinational miter using SAT solver MiniSat-1.14\n" );
|
||||
fprintf( pErr, "\t derives CNF from the current network and leave it unchanged\n" );
|
||||
fprintf( pErr, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfLimit );
|
||||
fprintf( pErr, "\t-I num : limit on the number of inspections [default = %d]\n", nInsLimit );
|
||||
fprintf( pErr, "\t-j : toggle the use of J-frontier [default = %s]\n", fJFront? "yes": "no" );
|
||||
fprintf( pErr, "\t-v : prints verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pErr, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -491,7 +491,7 @@ int Abc_NtkIvyProve( Abc_Ntk_t ** ppNtk, void * pPars )
|
|||
}
|
||||
|
||||
// if SAT only, solve without iteration
|
||||
RetValue = Abc_NtkMiterSat( pNtk, 2*(sint64)pParams->nMiteringLimitStart, (sint64)0, 0, 0, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pNtk, 2*(sint64)pParams->nMiteringLimitStart, (sint64)0, 0, NULL, NULL );
|
||||
if ( RetValue >= 0 )
|
||||
return RetValue;
|
||||
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
|
|||
if ( !pParams->fUseRewriting && !pParams->fUseFraiging )
|
||||
{
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, 0, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, NULL, NULL );
|
||||
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
|
||||
*ppNtk = pNtk;
|
||||
return RetValue;
|
||||
|
|
@ -99,7 +99,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
|
|||
// try brute-force SAT
|
||||
clk = clock();
|
||||
nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), (sint64)nInspectLimit, 0, 0, &nSatConfs, &nSatInspects );
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), (sint64)nInspectLimit, 0, &nSatConfs, &nSatInspects );
|
||||
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
|
||||
if ( RetValue >= 0 )
|
||||
break;
|
||||
|
|
@ -213,7 +213,7 @@ int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
|
|||
}
|
||||
clk = clock();
|
||||
nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)nInspectLimit, 0, 0, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pNtk, (sint64)pParams->nMiteringLimitLast, (sint64)nInspectLimit, 0, NULL, NULL );
|
||||
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
PackageName [Network and node package.]
|
||||
|
||||
Synopsis [Procedures to solve the miter using the internal SAT solver.]
|
||||
Synopsis [Procedures to solve the miter using the internal SAT sat_solver.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
|
|
@ -19,12 +19,13 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "abc.h"
|
||||
#include "satSolver.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes );
|
||||
static sat_solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes );
|
||||
extern Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk );
|
||||
static nMuxes;
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ static nMuxes;
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Attempts to solve the miter using an internal SAT solver.]
|
||||
Synopsis [Attempts to solve the miter using an internal SAT sat_solver.]
|
||||
|
||||
Description [Returns -1 if timed out; 0 if SAT; 1 if UNSAT.]
|
||||
|
||||
|
|
@ -43,9 +44,9 @@ static nMuxes;
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fJFront, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects )
|
||||
int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVerbose, sint64 * pNumConfs, sint64 * pNumInspects )
|
||||
{
|
||||
solver * pSat;
|
||||
sat_solver * pSat;
|
||||
lbool status;
|
||||
int RetValue, clk;
|
||||
|
||||
|
|
@ -59,22 +60,22 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int
|
|||
// if ( Abc_NtkPoNum(pNtk) > 1 )
|
||||
// fprintf( stdout, "Warning: The miter has %d outputs. SAT will try to prove all of them.\n", Abc_NtkPoNum(pNtk) );
|
||||
|
||||
// load clauses into the solver
|
||||
// load clauses into the sat_solver
|
||||
clk = clock();
|
||||
pSat = Abc_NtkMiterSatCreate( pNtk, fJFront, 0 );
|
||||
pSat = Abc_NtkMiterSatCreate( pNtk, 0 );
|
||||
if ( pSat == NULL )
|
||||
return 1;
|
||||
// printf( "Created SAT problem with %d variable and %d clauses. ", solver_nvars(pSat), solver_nclauses(pSat) );
|
||||
// printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
|
||||
// PRT( "Time", clock() - clk );
|
||||
|
||||
// simplify the problem
|
||||
clk = clock();
|
||||
status = solver_simplify(pSat);
|
||||
// printf( "Simplified the problem to %d variables and %d clauses. ", solver_nvars(pSat), solver_nclauses(pSat) );
|
||||
status = sat_solver_simplify(pSat);
|
||||
// printf( "Simplified the problem to %d variables and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) );
|
||||
// PRT( "Time", clock() - clk );
|
||||
if ( status == 0 )
|
||||
{
|
||||
solver_delete( pSat );
|
||||
sat_solver_delete( pSat );
|
||||
// printf( "The problem is UNSATISFIABLE after simplification.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -83,7 +84,7 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int
|
|||
clk = clock();
|
||||
if ( fVerbose )
|
||||
pSat->verbosity = 1;
|
||||
status = solver_solve( pSat, NULL, NULL, (sint64)nConfLimit, (sint64)nInsLimit );
|
||||
status = sat_solver_solve( pSat, NULL, NULL, (sint64)nConfLimit, (sint64)nInsLimit, (sint64)0, (sint64)0 );
|
||||
if ( status == l_Undef )
|
||||
{
|
||||
// printf( "The problem timed out.\n" );
|
||||
|
|
@ -101,30 +102,30 @@ int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int
|
|||
}
|
||||
else
|
||||
assert( 0 );
|
||||
// PRT( "SAT solver time", clock() - clk );
|
||||
// printf( "The number of conflicts = %d.\n", (int)pSat->solver_stats.conflicts );
|
||||
// PRT( "SAT sat_solver time", clock() - clk );
|
||||
// printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts );
|
||||
|
||||
// if the problem is SAT, get the counterexample
|
||||
if ( status == l_True )
|
||||
{
|
||||
// Vec_Int_t * vCiIds = Abc_NtkGetCiIds( pNtk );
|
||||
Vec_Int_t * vCiIds = Abc_NtkGetCiSatVarNums( pNtk );
|
||||
pNtk->pModel = solver_get_model( pSat, vCiIds->pArray, vCiIds->nSize );
|
||||
pNtk->pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize );
|
||||
Vec_IntFree( vCiIds );
|
||||
}
|
||||
// free the solver
|
||||
// free the sat_solver
|
||||
if ( fVerbose )
|
||||
Asat_SatPrintStats( stdout, pSat );
|
||||
Sat_SolverPrintStats( stdout, pSat );
|
||||
|
||||
if ( pNumConfs )
|
||||
*pNumConfs = (int)pSat->solver_stats.conflicts;
|
||||
*pNumConfs = (int)pSat->stats.conflicts;
|
||||
if ( pNumInspects )
|
||||
*pNumInspects = (int)pSat->solver_stats.inspects;
|
||||
*pNumInspects = (int)pSat->stats.inspects;
|
||||
|
||||
Sat_SolverTraceWrite( pSat, NULL, NULL, 0 );
|
||||
Sat_SolverTraceStop( pSat );
|
||||
sat_solver_store_write( pSat, "trace.cnf" );
|
||||
sat_solver_store_free( pSat );
|
||||
|
||||
solver_delete( pSat );
|
||||
sat_solver_delete( pSat );
|
||||
return RetValue;
|
||||
}
|
||||
|
||||
|
|
@ -163,13 +164,13 @@ Vec_Int_t * Abc_NtkGetCiSatVarNums( Abc_Ntk_t * pNtk )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkClauseTriv( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
||||
int Abc_NtkClauseTriv( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
||||
{
|
||||
//printf( "Adding triv %d. %d\n", Abc_ObjRegular(pNode)->Id, (int)pSat->solver_stats.clauses );
|
||||
//printf( "Adding triv %d. %d\n", Abc_ObjRegular(pNode)->Id, (int)pSat->sat_solver_stats.clauses );
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLitCond( (int)Abc_ObjRegular(pNode)->pCopy, Abc_ObjIsComplement(pNode) ) );
|
||||
// Vec_IntPush( vVars, toLitCond( (int)Abc_ObjRegular(pNode)->Id, Abc_ObjIsComplement(pNode) ) );
|
||||
return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -183,16 +184,16 @@ int Abc_NtkClauseTriv( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkClauseTop( solver * pSat, Vec_Ptr_t * vNodes, Vec_Int_t * vVars )
|
||||
int Abc_NtkClauseTop( sat_solver * pSat, Vec_Ptr_t * vNodes, Vec_Int_t * vVars )
|
||||
{
|
||||
Abc_Obj_t * pNode;
|
||||
int i;
|
||||
//printf( "Adding triv %d. %d\n", Abc_ObjRegular(pNode)->Id, (int)pSat->solver_stats.clauses );
|
||||
//printf( "Adding triv %d. %d\n", Abc_ObjRegular(pNode)->Id, (int)pSat->sat_solver_stats.clauses );
|
||||
vVars->nSize = 0;
|
||||
Vec_PtrForEachEntry( vNodes, pNode, i )
|
||||
Vec_IntPush( vVars, toLitCond( (int)Abc_ObjRegular(pNode)->pCopy, Abc_ObjIsComplement(pNode) ) );
|
||||
// Vec_IntPush( vVars, toLitCond( (int)Abc_ObjRegular(pNode)->Id, Abc_ObjIsComplement(pNode) ) );
|
||||
return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -206,15 +207,15 @@ int Abc_NtkClauseTop( solver * pSat, Vec_Ptr_t * vNodes, Vec_Int_t * vVars )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkClauseAnd( solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_Int_t * vVars )
|
||||
int Abc_NtkClauseAnd( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_Int_t * vVars )
|
||||
{
|
||||
int fComp1, Var, Var1, i;
|
||||
//printf( "Adding AND %d. (%d) %d\n", pNode->Id, vSuper->nSize+1, (int)pSat->solver_stats.clauses );
|
||||
//printf( "Adding AND %d. (%d) %d\n", pNode->Id, vSuper->nSize+1, (int)pSat->sat_solver_stats.clauses );
|
||||
|
||||
assert( !Abc_ObjIsComplement( pNode ) );
|
||||
assert( Abc_ObjIsNode( pNode ) );
|
||||
|
||||
// nVars = solver_nvars(pSat);
|
||||
// nVars = sat_solver_nvars(pSat);
|
||||
Var = (int)pNode->pCopy;
|
||||
// Var = pNode->Id;
|
||||
|
||||
|
|
@ -237,7 +238,7 @@ int Abc_NtkClauseAnd( solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_
|
|||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLitCond(Var1, fComp1) );
|
||||
Vec_IntPush( vVars, toLitCond(Var, 1 ) );
|
||||
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -256,7 +257,7 @@ int Abc_NtkClauseAnd( solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_
|
|||
Vec_IntPush( vVars, toLitCond(Var1, !fComp1) );
|
||||
}
|
||||
Vec_IntPush( vVars, toLitCond(Var, 0) );
|
||||
return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -270,10 +271,10 @@ int Abc_NtkClauseAnd( solver * pSat, Abc_Obj_t * pNode, Vec_Ptr_t * vSuper, Vec_
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkClauseMux( solver * pSat, Abc_Obj_t * pNode, Abc_Obj_t * pNodeC, Abc_Obj_t * pNodeT, Abc_Obj_t * pNodeE, Vec_Int_t * vVars )
|
||||
int Abc_NtkClauseMux( sat_solver * pSat, Abc_Obj_t * pNode, Abc_Obj_t * pNodeC, Abc_Obj_t * pNodeT, Abc_Obj_t * pNodeE, Vec_Int_t * vVars )
|
||||
{
|
||||
int VarF, VarI, VarT, VarE, fCompT, fCompE;
|
||||
//printf( "Adding mux %d. %d\n", pNode->Id, (int)pSat->solver_stats.clauses );
|
||||
//printf( "Adding mux %d. %d\n", pNode->Id, (int)pSat->sat_solver_stats.clauses );
|
||||
|
||||
assert( !Abc_ObjIsComplement( pNode ) );
|
||||
assert( Abc_NodeIsMuxType( pNode ) );
|
||||
|
|
@ -301,25 +302,25 @@ int Abc_NtkClauseMux( solver * pSat, Abc_Obj_t * pNode, Abc_Obj_t * pNodeC, Abc_
|
|||
Vec_IntPush( vVars, toLitCond(VarI, 1) );
|
||||
Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) );
|
||||
Vec_IntPush( vVars, toLitCond(VarF, 0) );
|
||||
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
return 0;
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLitCond(VarI, 1) );
|
||||
Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) );
|
||||
Vec_IntPush( vVars, toLitCond(VarF, 1) );
|
||||
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
return 0;
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLitCond(VarI, 0) );
|
||||
Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) );
|
||||
Vec_IntPush( vVars, toLitCond(VarF, 0) );
|
||||
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
return 0;
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLitCond(VarI, 0) );
|
||||
Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) );
|
||||
Vec_IntPush( vVars, toLitCond(VarF, 1) );
|
||||
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
return 0;
|
||||
|
||||
if ( VarT == VarE )
|
||||
|
|
@ -335,13 +336,13 @@ int Abc_NtkClauseMux( solver * pSat, Abc_Obj_t * pNode, Abc_Obj_t * pNodeC, Abc_
|
|||
Vec_IntPush( vVars, toLitCond(VarT, 0^fCompT) );
|
||||
Vec_IntPush( vVars, toLitCond(VarE, 0^fCompE) );
|
||||
Vec_IntPush( vVars, toLitCond(VarF, 1) );
|
||||
if ( !solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
if ( !sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize ) )
|
||||
return 0;
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLitCond(VarT, 1^fCompT) );
|
||||
Vec_IntPush( vVars, toLitCond(VarE, 1^fCompE) );
|
||||
Vec_IntPush( vVars, toLitCond(VarF, 0) );
|
||||
return solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
return sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
|
@ -442,7 +443,7 @@ int Abc_NtkNodeFactor( Abc_Obj_t * pObj, int nLevelMax )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets up the SAT solver.]
|
||||
Synopsis [Sets up the SAT sat_solver.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -451,16 +452,14 @@ int Abc_NtkNodeFactor( Abc_Obj_t * pObj, int nLevelMax )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
|
||||
int Abc_NtkMiterSatCreateInt( sat_solver * pSat, Abc_Ntk_t * pNtk )
|
||||
{
|
||||
Abc_Obj_t * pNode, * pFanin, * pNodeC, * pNodeT, * pNodeE;
|
||||
Vec_Ptr_t * vNodes, * vSuper;
|
||||
Vec_Flt_t * vFactors;
|
||||
Vec_Int_t * vVars, * vFanio;
|
||||
Vec_Vec_t * vCircuit;
|
||||
Vec_Int_t * vVars;
|
||||
int i, k, fUseMuxes = 1;
|
||||
int clk1 = clock(), clk;
|
||||
int fOrderCiVarsFirst = 0;
|
||||
int clk1 = clock();
|
||||
// int fOrderCiVarsFirst = 0;
|
||||
int nLevelsMax = Abc_AigLevel(pNtk);
|
||||
int RetValue = 0;
|
||||
|
||||
|
|
@ -471,12 +470,9 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
|
|||
pNode->pCopy = NULL;
|
||||
|
||||
// start the data structures
|
||||
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the solver
|
||||
vNodes = Vec_PtrAlloc( 1000 ); // the nodes corresponding to vars in the sat_solver
|
||||
vSuper = Vec_PtrAlloc( 100 ); // the nodes belonging to the given implication supergate
|
||||
vVars = Vec_IntAlloc( 100 ); // the temporary array for variables in the clause
|
||||
if ( fJFront )
|
||||
vCircuit = Vec_VecAlloc( 1000 );
|
||||
// vCircuit = Vec_VecStart( 184 );
|
||||
|
||||
// add the clause for the constant node
|
||||
pNode = Abc_AigConst1(pNtk);
|
||||
|
|
@ -574,23 +570,8 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
|
|||
goto Quits;
|
||||
}
|
||||
}
|
||||
// add the variables to the J-frontier
|
||||
if ( !fJFront )
|
||||
continue;
|
||||
// make sure that the fanin entries go first
|
||||
assert( pNode->pCopy );
|
||||
Vec_VecExpand( vCircuit, (int)pNode->pCopy );
|
||||
vFanio = Vec_VecEntry( vCircuit, (int)pNode->pCopy );
|
||||
Vec_PtrForEachEntryReverse( vSuper, pFanin, k )
|
||||
// Vec_PtrForEachEntry( vSuper, pFanin, k )
|
||||
{
|
||||
pFanin = Abc_ObjRegular( pFanin );
|
||||
assert( pFanin->pCopy && pFanin->pCopy != pNode->pCopy );
|
||||
Vec_IntPushFirst( vFanio, (int)pFanin->pCopy );
|
||||
Vec_VecPush( vCircuit, (int)pFanin->pCopy, pNode->pCopy );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// set preferred variables
|
||||
if ( fOrderCiVarsFirst )
|
||||
{
|
||||
|
|
@ -603,45 +584,8 @@ int Abc_NtkMiterSatCreateInt( solver * pSat, Abc_Ntk_t * pNtk, int fJFront )
|
|||
pPrefVars[nVars++] = (int)pNode->pCopy;
|
||||
}
|
||||
nVars = ABC_MIN( nVars, 10 );
|
||||
Asat_SolverSetPrefVars( pSat, pPrefVars, nVars );
|
||||
ASat_SolverSetPrefVars( pSat, pPrefVars, nVars );
|
||||
}
|
||||
|
||||
// create the variable order
|
||||
if ( fJFront )
|
||||
{
|
||||
clk = clock();
|
||||
Asat_JManStart( pSat, vCircuit );
|
||||
Vec_VecFree( vCircuit );
|
||||
PRT( "Setup", clock() - clk );
|
||||
// Asat_JManStop( pSat );
|
||||
// PRT( "Total", clock() - clk1 );
|
||||
}
|
||||
|
||||
Abc_NtkStartReverseLevels( pNtk );
|
||||
vFactors = Vec_FltStart( solver_nvars(pSat) );
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
if ( pNode->fMarkA )
|
||||
Vec_FltWriteEntry( vFactors, (int)pNode->pCopy, (float)pow(0.97, Abc_NodeReadReverseLevel(pNode)) );
|
||||
Abc_NtkForEachCi( pNtk, pNode, i )
|
||||
if ( pNode->fMarkA )
|
||||
Vec_FltWriteEntry( vFactors, (int)pNode->pCopy, (float)pow(0.97, nLevelsMax+1) );
|
||||
// set the PI levels
|
||||
// Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
// if ( pNode->fMarkA )
|
||||
// printf( "(%d) %.3f ", Abc_NodeReadReverseLevel(pNode), Vec_FltEntry(vFactors, (int)pNode->pCopy) );
|
||||
// printf( "\n" );
|
||||
Asat_SolverSetFactors( pSat, Vec_FltReleaseArray(vFactors) );
|
||||
Vec_FltFree( vFactors );
|
||||
|
||||
/*
|
||||
// create factors
|
||||
vLevels = Vec_IntStart( Vec_PtrSize(vNodes) ); // the reverse levels of the nodes
|
||||
Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
if ( pNode->fMarkA )
|
||||
Vec_IntWriteEntry( vLevels, (int)pNode->pCopy, Abc_NtkNodeFactor(pNode, nLevelsMax) );
|
||||
assert( Vec_PtrSize(vNodes) == Vec_IntSize(vLevels) );
|
||||
Asat_SolverSetFactors( pSat, Vec_IntReleaseArray(vLevels) );
|
||||
Vec_IntFree( vLevels );
|
||||
*/
|
||||
RetValue = 1;
|
||||
Quits :
|
||||
|
|
@ -654,7 +598,7 @@ Quits :
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets up the SAT solver.]
|
||||
Synopsis [Sets up the SAT sat_solver.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -663,9 +607,9 @@ Quits :
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront, int fAllPrimes )
|
||||
void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes )
|
||||
{
|
||||
solver * pSat;
|
||||
sat_solver * pSat;
|
||||
Abc_Obj_t * pNode;
|
||||
int RetValue, i, clk = clock();
|
||||
|
||||
|
|
@ -674,18 +618,21 @@ solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront, int fAllPrimes )
|
|||
return Abc_NtkMiterSatCreateLogic(pNtk, fAllPrimes);
|
||||
|
||||
nMuxes = 0;
|
||||
pSat = solver_new();
|
||||
RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk, fJFront );
|
||||
pSat = sat_solver_new();
|
||||
sat_solver_store_alloc( pSat );
|
||||
RetValue = Abc_NtkMiterSatCreateInt( pSat, pNtk );
|
||||
sat_solver_store_mark_roots( pSat );
|
||||
|
||||
Abc_NtkForEachObj( pNtk, pNode, i )
|
||||
pNode->fMarkA = 0;
|
||||
// Asat_SolverWriteDimacs( pSat, "temp_sat.cnf", NULL, NULL, 1 );
|
||||
// ASat_SolverWriteDimacs( pSat, "temp_sat.cnf", NULL, NULL, 1 );
|
||||
if ( RetValue == 0 )
|
||||
{
|
||||
solver_delete(pSat);
|
||||
sat_solver_delete(pSat);
|
||||
return NULL;
|
||||
}
|
||||
// printf( "Ands = %6d. Muxes = %6d (%5.2f %%). ", Abc_NtkNodeNum(pNtk), nMuxes, 300.0*nMuxes/Abc_NtkNodeNum(pNtk) );
|
||||
// PRT( "Creating solver", clock() - clk );
|
||||
// PRT( "Creating sat_solver", clock() - clk );
|
||||
return pSat;
|
||||
}
|
||||
|
||||
|
|
@ -703,7 +650,7 @@ solver * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fJFront, int fAllPrimes )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
||||
int Abc_NodeAddClauses( sat_solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int i, c, nFanins;
|
||||
|
|
@ -721,8 +668,8 @@ int Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * p
|
|||
if ( !Cudd_IsComplement(pNode->pData) )
|
||||
Vec_IntPush( vVars, toLit(pNode->Id) );
|
||||
else
|
||||
Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -745,10 +692,10 @@ int Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * p
|
|||
if ( pCube[i] == '0' )
|
||||
Vec_IntPush( vVars, toLit(pFanin->Id) );
|
||||
else if ( pCube[i] == '1' )
|
||||
Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
|
||||
}
|
||||
Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -770,10 +717,10 @@ int Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * p
|
|||
if ( pCube[i] == '0' )
|
||||
Vec_IntPush( vVars, toLit(pFanin->Id) );
|
||||
else if ( pCube[i] == '1' )
|
||||
Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
|
||||
}
|
||||
Vec_IntPush( vVars, toLit(pNode->Id) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -794,7 +741,7 @@ int Abc_NodeAddClauses( solver * pSat, char * pSop0, char * pSop1, Abc_Obj_t * p
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
||||
int Abc_NodeAddClausesTop( sat_solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
||||
{
|
||||
Abc_Obj_t * pFanin;
|
||||
int RetValue;
|
||||
|
|
@ -805,7 +752,7 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLit(pFanin->Id) );
|
||||
Vec_IntPush( vVars, toLit(pNode->Id) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -813,9 +760,9 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
}
|
||||
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
|
||||
Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -825,9 +772,9 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
else
|
||||
{
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, neg(toLit(pFanin->Id)) );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pFanin->Id)) );
|
||||
Vec_IntPush( vVars, toLit(pNode->Id) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -836,8 +783,8 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLit(pFanin->Id) );
|
||||
Vec_IntPush( vVars, neg(toLit(pNode->Id)) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
Vec_IntPush( vVars, lit_neg(toLit(pNode->Id)) );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -847,7 +794,7 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
|
||||
vVars->nSize = 0;
|
||||
Vec_IntPush( vVars, toLit(pNode->Id) );
|
||||
RetValue = solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
RetValue = sat_solver_addclause( pSat, vVars->pArray, vVars->pArray + vVars->nSize );
|
||||
if ( !RetValue )
|
||||
{
|
||||
printf( "The CNF is trivially UNSAT.\n" );
|
||||
|
|
@ -858,7 +805,7 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets up the SAT solver.]
|
||||
Synopsis [Sets up the SAT sat_solver.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -867,9 +814,9 @@ int Abc_NodeAddClausesTop( solver * pSat, Abc_Obj_t * pNode, Vec_Int_t * vVars )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes )
|
||||
sat_solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes )
|
||||
{
|
||||
solver * pSat;
|
||||
sat_solver * pSat;
|
||||
Extra_MmFlex_t * pMmFlex;
|
||||
Abc_Obj_t * pNode;
|
||||
Vec_Str_t * vCube;
|
||||
|
|
@ -884,22 +831,21 @@ solver * Abc_NtkMiterSatCreateLogic( Abc_Ntk_t * pNtk, int fAllPrimes )
|
|||
pNode->pCopy = (void *)pNode->Id;
|
||||
|
||||
// start the data structures
|
||||
pSat = solver_new();
|
||||
pSat = sat_solver_new();
|
||||
sat_solver_store_alloc( pSat );
|
||||
pMmFlex = Extra_MmFlexStart();
|
||||
vCube = Vec_StrAlloc( 100 );
|
||||
vVars = Vec_IntAlloc( 100 );
|
||||
|
||||
Sat_SolverTraceStart( pSat, "trace.cnf" );
|
||||
|
||||
// add clauses for each internal nodes
|
||||
Abc_NtkForEachNode( pNtk, pNode, i )
|
||||
{
|
||||
// derive SOPs for both phases of the node
|
||||
Abc_NodeBddToCnf( pNode, pMmFlex, vCube, fAllPrimes, &pSop0, &pSop1 );
|
||||
// add the clauses to the solver
|
||||
// add the clauses to the sat_solver
|
||||
if ( !Abc_NodeAddClauses( pSat, pSop0, pSop1, pNode, vVars ) )
|
||||
{
|
||||
solver_delete( pSat );
|
||||
sat_solver_delete( pSat );
|
||||
pSat = NULL;
|
||||
goto finish;
|
||||
}
|
||||
|
|
@ -909,11 +855,12 @@ Sat_SolverTraceStart( pSat, "trace.cnf" );
|
|||
{
|
||||
if ( !Abc_NodeAddClausesTop( pSat, pNode, vVars ) )
|
||||
{
|
||||
solver_delete( pSat );
|
||||
sat_solver_delete( pSat );
|
||||
pSat = NULL;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
sat_solver_store_mark_roots( pSat );
|
||||
|
||||
finish:
|
||||
// delete
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ void Abc_NtkCecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
|
|||
}
|
||||
|
||||
// solve the CNF using the SAT solver
|
||||
RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, 0, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, NULL, NULL );
|
||||
if ( RetValue == -1 )
|
||||
printf( "Networks are undecided (SAT solver timed out).\n" );
|
||||
else if ( RetValue == 0 )
|
||||
|
|
@ -268,7 +268,7 @@ void Abc_NtkSecSat( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nConfLimit, int nI
|
|||
}
|
||||
|
||||
// solve the CNF using the SAT solver
|
||||
RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, 0, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pCnf, (sint64)nConfLimit, (sint64)nInsLimit, 0, NULL, NULL );
|
||||
if ( RetValue == -1 )
|
||||
printf( "Networks are undecided (SAT solver timed out).\n" );
|
||||
else if ( RetValue == 0 )
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
***********************************************************************/
|
||||
|
||||
#include "io.h"
|
||||
#include "satSolver.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -43,7 +44,7 @@ static Abc_Ntk_t * s_pNtk = NULL;
|
|||
***********************************************************************/
|
||||
int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName, int fAllPrimes )
|
||||
{
|
||||
solver * pSat;
|
||||
sat_solver * pSat;
|
||||
if ( Abc_NtkIsStrash(pNtk) )
|
||||
printf( "Io_WriteCnf() warning: Generating CNF by applying heuristic AIG to CNF conversion.\n" );
|
||||
else
|
||||
|
|
@ -67,7 +68,7 @@ int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName, int fAllPrimes )
|
|||
if ( Abc_NtkIsLogic(pNtk) )
|
||||
Abc_NtkLogicToBdd( pNtk );
|
||||
// create solver with clauses
|
||||
pSat = Abc_NtkMiterSatCreate( pNtk, 0, fAllPrimes );
|
||||
pSat = Abc_NtkMiterSatCreate( pNtk, fAllPrimes );
|
||||
if ( pSat == NULL )
|
||||
{
|
||||
fprintf( stdout, "The problem is trivially UNSAT. No CNF file is generated.\n" );
|
||||
|
|
@ -75,10 +76,10 @@ int Io_WriteCnf( Abc_Ntk_t * pNtk, char * pFileName, int fAllPrimes )
|
|||
}
|
||||
// write the clauses
|
||||
s_pNtk = pNtk;
|
||||
Asat_SolverWriteDimacs( pSat, pFileName, 0, 0, 1 );
|
||||
Sat_SolverWriteDimacs( pSat, pFileName, 0, 0, 1 );
|
||||
s_pNtk = NULL;
|
||||
// free the solver
|
||||
solver_delete( pSat );
|
||||
sat_solver_delete( pSat );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,9 +93,9 @@ static inline void Res_WinAddNode( Res_Win_t * p, Abc_Obj_t * pObj )
|
|||
extern void Res_WinDivisors( Res_Win_t * p, int nLevDivMax );
|
||||
extern int Res_WinVisitMffc( Res_Win_t * p );
|
||||
/*=== resFilter.c ==========================================================*/
|
||||
extern Vec_Ptr_t * Res_FilterCandidates( Res_Win_t * pWin, Res_Sim_t * pSim );
|
||||
extern Vec_Vec_t * Res_FilterCandidates( Res_Win_t * pWin, Res_Sim_t * pSim );
|
||||
/*=== resSat.c ==========================================================*/
|
||||
extern Hop_Obj_t * Res_SatFindFunction( Hop_Man_t * pMan, Res_Win_t * pWin, Vec_Ptr_t * vFanins, Abc_Ntk_t * pAig );
|
||||
extern void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins );
|
||||
/*=== resSim.c ==========================================================*/
|
||||
extern Res_Sim_t * Res_SimAlloc( int nWords );
|
||||
extern void Res_SimFree( Res_Sim_t * p );
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "abc.h"
|
||||
#include "res.h"
|
||||
#include "kit.h"
|
||||
#include "satStore.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
|
|
@ -42,15 +44,24 @@
|
|||
***********************************************************************/
|
||||
int Abc_NtkResynthesize( Abc_Ntk_t * pNtk, int nWindow, int nSimWords, int fVerbose, int fVeryVerbose )
|
||||
{
|
||||
Int_Man_t * pMan;
|
||||
Sto_Man_t * pCnf;
|
||||
Res_Win_t * pWin;
|
||||
Res_Sim_t * pSim;
|
||||
Abc_Ntk_t * pAig;
|
||||
Abc_Obj_t * pObj;
|
||||
Hop_Obj_t * pFunc;
|
||||
Kit_Graph_t * pGraph;
|
||||
Vec_Vec_t * vResubs;
|
||||
Vec_Ptr_t * vFanins;
|
||||
int i, nNodesOld;
|
||||
Vec_Int_t * vMemory;
|
||||
unsigned * puTruth;
|
||||
int i, k, nNodesOld, nFanins;
|
||||
assert( Abc_NtkHasAig(pNtk) );
|
||||
assert( nWindow > 0 && nWindow < 100 );
|
||||
vMemory = Vec_IntAlloc(0);
|
||||
// start the interpolation manager
|
||||
pMan = Int_ManAlloc( 512 );
|
||||
// start the window
|
||||
pWin = Res_WinAlloc();
|
||||
pSim = Res_SimAlloc( nSimWords );
|
||||
|
|
@ -72,20 +83,44 @@ int Abc_NtkResynthesize( Abc_Ntk_t * pNtk, int nWindow, int nSimWords, int fVerb
|
|||
// create the AIG for the window
|
||||
pAig = Res_WndStrash( pWin );
|
||||
// prepare simulation info
|
||||
if ( Res_SimPrepare( pSim, pAig ) )
|
||||
if ( !Res_SimPrepare( pSim, pAig ) )
|
||||
{
|
||||
// find resub candidates for the node
|
||||
vFanins = Res_FilterCandidates( pWin, pSim );
|
||||
// check using SAT
|
||||
pFunc = Res_SatFindFunction( pNtk->pManFunc, pWin, vFanins, pAig );
|
||||
// update the network
|
||||
if ( pFunc == NULL )
|
||||
Res_UpdateNetwork( pObj, vFanins, pFunc, pWin->vLevels );
|
||||
Abc_NtkDelete( pAig );
|
||||
continue;
|
||||
}
|
||||
// find resub candidates for the node
|
||||
vResubs = Res_FilterCandidates( pWin, pSim );
|
||||
if ( vResubs )
|
||||
{
|
||||
// iterate through the resubstitutions
|
||||
Vec_VecForEachLevel( vResubs, vFanins, k )
|
||||
{
|
||||
extern Hop_Obj_t * Kit_GraphToHop( Hop_Man_t * pMan, Kit_Graph_t * pGraph );
|
||||
pCnf = Res_SatProveUnsat( pAig, vFanins );
|
||||
if ( pCnf == NULL )
|
||||
continue;
|
||||
// interplate this proof
|
||||
nFanins = Int_ManInterpolate( pMan, pCnf, fVerbose, &puTruth );
|
||||
assert( nFanins == Vec_PtrSize(vFanins) - 2 );
|
||||
Sto_ManFree( pCnf );
|
||||
// transform interpolant into the AIG
|
||||
pGraph = Kit_TruthToGraph( puTruth, nFanins, vMemory );
|
||||
// derive the AIG for the decomposition tree
|
||||
pFunc = Kit_GraphToHop( pNtk->pManFunc, pGraph );
|
||||
Kit_GraphFree( pGraph );
|
||||
// update the network
|
||||
if ( pFunc == NULL )
|
||||
Res_UpdateNetwork( pObj, vFanins, pFunc, pWin->vLevels );
|
||||
break;
|
||||
}
|
||||
Vec_VecFree( vResubs );
|
||||
}
|
||||
Abc_NtkDelete( pAig );
|
||||
}
|
||||
Res_WinFree( pWin );
|
||||
Res_SimFree( pSim );
|
||||
Int_ManFree( pMan );
|
||||
Vec_IntFree( vMemory );
|
||||
// check the resulting network
|
||||
if ( !Abc_NtkCheck( pNtk ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Ptr_t * Res_FilterCandidates( Res_Win_t * pWin, Res_Sim_t * pSim )
|
||||
Vec_Vec_t * Res_FilterCandidates( Res_Win_t * pWin, Res_Sim_t * pSim )
|
||||
{
|
||||
unsigned * pInfo;
|
||||
Abc_Obj_t * pFanin;
|
||||
|
|
|
|||
|
|
@ -21,19 +21,23 @@
|
|||
#include "abc.h"
|
||||
#include "res.h"
|
||||
#include "hop.h"
|
||||
//#include "bf.h"
|
||||
#include "satSolver.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern int Res_SatAddConst1( sat_solver * pSat, int iVar );
|
||||
extern int Res_SatAddEqual( sat_solver * pSat, int iVar0, int iVar1, int fCompl );
|
||||
extern int Res_SatAddAnd( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
Synopsis [Loads AIG into the SAT solver.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -42,11 +46,149 @@
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Hop_Obj_t * Res_SatFindFunction( Hop_Man_t * pMan, Res_Win_t * pWin, Vec_Ptr_t * vFanins, Abc_Ntk_t * pAig )
|
||||
void * Res_SatProveUnsat( Abc_Ntk_t * pAig, Vec_Ptr_t * vFanins )
|
||||
{
|
||||
return NULL;
|
||||
void * pCnf;
|
||||
sat_solver * pSat;
|
||||
Vec_Ptr_t * vNodes;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, nNodes, status;
|
||||
|
||||
// make sure the constant node is not involved
|
||||
assert( Abc_ObjFanoutNum(Abc_AigConst1(pAig)) == 0 );
|
||||
|
||||
// collect reachable nodes
|
||||
vNodes = Abc_NtkDfsNodes( pAig, (Abc_Obj_t **)vFanins->pArray, vFanins->nSize );
|
||||
// assign unique numbers to each node
|
||||
nNodes = 0;
|
||||
Abc_NtkForEachPi( pAig, pObj, i )
|
||||
pObj->pCopy = (void *)nNodes++;
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
pObj->pCopy = (void *)nNodes++;
|
||||
Vec_PtrForEachEntry( vFanins, pObj, i )
|
||||
pObj->pCopy = (void *)nNodes++;
|
||||
|
||||
// start the solver
|
||||
pSat = sat_solver_new();
|
||||
sat_solver_store_alloc( pSat );
|
||||
|
||||
// add clause for AND gates
|
||||
Vec_PtrForEachEntry( vNodes, pObj, i )
|
||||
Res_SatAddAnd( pSat, (int)pObj->pCopy,
|
||||
(int)Abc_ObjFanin0(pObj)->pCopy, (int)Abc_ObjFanin1(pObj)->pCopy, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
|
||||
// add clauses for the POs
|
||||
Vec_PtrForEachEntry( vFanins, pObj, i )
|
||||
Res_SatAddEqual( pSat, (int)pObj->pCopy,
|
||||
(int)Abc_ObjFanin0(pObj)->pCopy, Abc_ObjFaninC0(pObj) );
|
||||
// add trivial clauses
|
||||
pObj = Vec_PtrEntry(vFanins, 0);
|
||||
Res_SatAddConst1( pSat, (int)pObj->pCopy );
|
||||
pObj = Vec_PtrEntry(vFanins, 1);
|
||||
Res_SatAddConst1( pSat, (int)pObj->pCopy );
|
||||
// bookmark the clauses of A
|
||||
sat_solver_store_mark_clauses_a( pSat );
|
||||
// duplicate the clauses
|
||||
pObj = Vec_PtrEntry(vFanins, 1);
|
||||
Sat_SolverDoubleClauses( pSat, (int)pObj->pCopy );
|
||||
// add the equality clauses
|
||||
Vec_PtrForEachEntryStart( vFanins, pObj, i, 2 )
|
||||
Res_SatAddEqual( pSat, (int)pObj->pCopy, ((int)pObj->pCopy) + nNodes, 0 );
|
||||
// bookmark the roots
|
||||
sat_solver_store_mark_roots( pSat );
|
||||
Vec_PtrFree( vNodes );
|
||||
|
||||
// solve the problem
|
||||
status = sat_solver_solve( pSat, NULL, NULL, (sint64)10000, (sint64)0, (sint64)0, (sint64)0 );
|
||||
if ( status == l_False )
|
||||
pCnf = sat_solver_store_release( pSat );
|
||||
else if ( status == l_True )
|
||||
pCnf = NULL;
|
||||
else
|
||||
pCnf = NULL;
|
||||
sat_solver_delete( pSat );
|
||||
return pCnf;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Loads two-input AND-gate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Res_SatAddConst1( sat_solver * pSat, int iVar )
|
||||
{
|
||||
lit Lit = lit_var(iVar);
|
||||
if ( !sat_solver_addclause( pSat, &Lit, &Lit + 1 ) )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Loads two-input AND-gate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Res_SatAddEqual( sat_solver * pSat, int iVar0, int iVar1, int fCompl )
|
||||
{
|
||||
lit Lits[2];
|
||||
|
||||
Lits[0] = toLitCond( iVar0, 0 );
|
||||
Lits[1] = toLitCond( iVar1, !fCompl );
|
||||
if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
|
||||
return 0;
|
||||
|
||||
Lits[0] = toLitCond( iVar0, 1 );
|
||||
Lits[1] = toLitCond( iVar1, fCompl );
|
||||
if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Loads two-input AND-gate.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Res_SatAddAnd( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 )
|
||||
{
|
||||
lit Lits[3];
|
||||
|
||||
Lits[0] = toLitCond( iVar, 1 );
|
||||
Lits[1] = toLitCond( iVar0, fCompl0 );
|
||||
if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
|
||||
return 0;
|
||||
|
||||
Lits[0] = toLitCond( iVar, 1 );
|
||||
Lits[1] = toLitCond( iVar1, fCompl1 );
|
||||
if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
|
||||
return 0;
|
||||
|
||||
Lits[0] = toLitCond( iVar, 0 );
|
||||
Lits[1] = toLitCond( iVar0, !fCompl0 );
|
||||
Lits[2] = toLitCond( iVar1, !fCompl1 );
|
||||
if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ Vec_Int_t * Abc_NtkRetimeInitialValues( Abc_Ntk_t * pNtkCone, Vec_Int_t * vValue
|
|||
printf( "The miter for initial state computation has %d AIG nodes. ", Abc_NtkNodeNum(pNtkMiter) );
|
||||
// solve the miter
|
||||
clk = clock();
|
||||
RetValue = Abc_NtkMiterSat( pNtkMiter, (sint64)500000, (sint64)50000000, 0, 0, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( pNtkMiter, (sint64)500000, (sint64)50000000, 0, NULL, NULL );
|
||||
if ( fVerbose )
|
||||
{ PRT( "SAT solving time", clock() - clk ); }
|
||||
// analyze the result
|
||||
|
|
|
|||
|
|
@ -1,234 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [added.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [C-language MiniSat solver.]
|
||||
|
||||
Synopsis [Additional SAT solver procedures.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: added.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "solver.h"
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct clause_t
|
||||
{
|
||||
int size_learnt;
|
||||
lit lits[0];
|
||||
};
|
||||
|
||||
static inline int clause_size (clause* c) { return c->size_learnt >> 1; }
|
||||
static inline lit* clause_begin (clause* c) { return c->lits; }
|
||||
|
||||
static inline int lit_var(lit l) { return l >> 1; }
|
||||
static inline int lit_sign(lit l) { return (l & 1); }
|
||||
|
||||
static void Asat_ClauseWriteDimacs( FILE * pFile, clause * pC, bool fIncrement );
|
||||
|
||||
extern void Io_WriteCnfOutputPiMapping( FILE * pFile, int incrementVars );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Write the clauses in the solver into a file in DIMACS format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_SolverWriteDimacs( solver * p, char * pFileName, lit* assumptionsBegin, lit* assumptionsEnd, int incrementVars )
|
||||
{
|
||||
FILE * pFile;
|
||||
void ** pClauses;
|
||||
int nClauses, i;
|
||||
|
||||
// count the number of clauses
|
||||
nClauses = p->clauses.size + p->learnts.size;
|
||||
for ( i = 0; i < p->size; i++ )
|
||||
if ( p->levels[i] == 0 && p->assigns[i] != l_Undef )
|
||||
nClauses++;
|
||||
|
||||
// start the file
|
||||
pFile = fopen( pFileName, "wb" );
|
||||
if ( pFile == NULL )
|
||||
{
|
||||
printf( "Asat_SolverWriteDimacs(): Cannot open the ouput file.\n" );
|
||||
return;
|
||||
}
|
||||
fprintf( pFile, "c CNF generated by ABC on %s\n", Extra_TimeStamp() );
|
||||
// Io_WriteCnfOutputPiMapping( pFile, incrementVars );
|
||||
fprintf( pFile, "p cnf %d %d\n", p->size, nClauses );
|
||||
|
||||
// write the original clauses
|
||||
nClauses = p->clauses.size;
|
||||
pClauses = p->clauses.ptr;
|
||||
for ( i = 0; i < nClauses; i++ )
|
||||
Asat_ClauseWriteDimacs( pFile, pClauses[i], incrementVars );
|
||||
|
||||
// write the learned clauses
|
||||
nClauses = p->learnts.size;
|
||||
pClauses = p->learnts.ptr;
|
||||
for ( i = 0; i < nClauses; i++ )
|
||||
Asat_ClauseWriteDimacs( pFile, pClauses[i], incrementVars );
|
||||
|
||||
// write zero-level assertions
|
||||
for ( i = 0; i < p->size; i++ )
|
||||
if ( p->levels[i] == 0 && p->assigns[i] != l_Undef )
|
||||
fprintf( pFile, "%s%d%s\n",
|
||||
(p->assigns[i] == l_False)? "-": "",
|
||||
i + (int)(incrementVars>0),
|
||||
(incrementVars) ? " 0" : "");
|
||||
|
||||
// write the assumptions
|
||||
if (assumptionsBegin) {
|
||||
for (; assumptionsBegin != assumptionsEnd; assumptionsBegin++) {
|
||||
fprintf( pFile, "%s%d%s\n",
|
||||
lit_sign(*assumptionsBegin)? "-": "",
|
||||
lit_var(*assumptionsBegin) + (int)(incrementVars>0),
|
||||
(incrementVars) ? " 0" : "");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf( pFile, "\n" );
|
||||
fclose( pFile );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Writes the given clause in a file in DIMACS format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_ClauseWriteDimacs( FILE * pFile, clause * pC, bool fIncrement )
|
||||
{
|
||||
lit * pLits = clause_begin(pC);
|
||||
int nLits = clause_size(pC);
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < nLits; i++ )
|
||||
fprintf( pFile, "%s%d ", (lit_sign(pLits[i])? "-": ""), lit_var(pLits[i]) + (int)(fIncrement>0) );
|
||||
if ( fIncrement )
|
||||
fprintf( pFile, "0" );
|
||||
fprintf( pFile, "\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns a counter-example.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * solver_get_model( 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 [Writes the given clause in a file in DIMACS format.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_SatPrintStats( FILE * pFile, solver * p )
|
||||
{
|
||||
printf( "Start = %4d. Conf = %6d. Dec = %6d. Prop = %7d. Insp = %8d.\n",
|
||||
(int)p->solver_stats.starts,
|
||||
(int)p->solver_stats.conflicts,
|
||||
(int)p->solver_stats.decisions,
|
||||
(int)p->solver_stats.propagations,
|
||||
(int)p->solver_stats.inspects );
|
||||
printf( "Total runtime = %7.2f sec. Var select = %7.2f sec. Var update = %7.2f sec.\n",
|
||||
(float)(p->timeTotal)/(float)(CLOCKS_PER_SEC),
|
||||
(float)(p->timeSelect)/(float)(CLOCKS_PER_SEC),
|
||||
(float)(p->timeUpdate)/(float)(CLOCKS_PER_SEC) );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the preferred variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_SolverSetPrefVars(solver * s, int * pPrefVars, int nPrefVars)
|
||||
{
|
||||
int i;
|
||||
assert( s->pPrefVars == NULL );
|
||||
for ( i = 0; i < nPrefVars; i++ )
|
||||
assert( pPrefVars[i] < s->size );
|
||||
s->pPrefVars = pPrefVars;
|
||||
s->nPrefVars = nPrefVars;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Sets the preferred variables.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_SolverSetFactors(solver * s, float * pFactors)
|
||||
{
|
||||
assert( s->factors == NULL );
|
||||
s->factors = pFactors;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,527 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [asatmem.c]
|
||||
|
||||
PackageName [SAT solver.]
|
||||
|
||||
Synopsis [Memory management.]
|
||||
|
||||
Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - January 1, 2004.]
|
||||
|
||||
Revision [$Id: asatmem.c,v 1.0 2004/01/01 1:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "asatmem.h"
|
||||
#include "extra.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct Asat_MmFixed_t_
|
||||
{
|
||||
// information about individual entries
|
||||
int nEntrySize; // the size of one entry
|
||||
int nEntriesAlloc; // the total number of entries allocated
|
||||
int nEntriesUsed; // the number of entries in use
|
||||
int nEntriesMax; // the max number of entries in use
|
||||
char * pEntriesFree; // the linked list of free entries
|
||||
|
||||
// this is where the memory is stored
|
||||
int nChunkSize; // the size of one chunk
|
||||
int nChunksAlloc; // the maximum number of memory chunks
|
||||
int nChunks; // the current number of memory chunks
|
||||
char ** pChunks; // the allocated memory
|
||||
|
||||
// statistics
|
||||
int nMemoryUsed; // memory used in the allocated entries
|
||||
int nMemoryAlloc; // memory allocated
|
||||
};
|
||||
|
||||
struct Asat_MmFlex_t_
|
||||
{
|
||||
// information about individual entries
|
||||
int nEntriesUsed; // the number of entries allocated
|
||||
char * pCurrent; // the current pointer to free memory
|
||||
char * pEnd; // the first entry outside the free memory
|
||||
|
||||
// this is where the memory is stored
|
||||
int nChunkSize; // the size of one chunk
|
||||
int nChunksAlloc; // the maximum number of memory chunks
|
||||
int nChunks; // the current number of memory chunks
|
||||
char ** pChunks; // the allocated memory
|
||||
|
||||
// statistics
|
||||
int nMemoryUsed; // memory used in the allocated entries
|
||||
int nMemoryAlloc; // memory allocated
|
||||
};
|
||||
|
||||
struct Asat_MmStep_t_
|
||||
{
|
||||
int nMems; // the number of fixed memory managers employed
|
||||
Asat_MmFixed_t ** pMems; // memory managers: 2^1 words, 2^2 words, etc
|
||||
int nMapSize; // the size of the memory array
|
||||
Asat_MmFixed_t ** pMap; // maps the number of bytes into its memory manager
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates memory pieces of fixed size.]
|
||||
|
||||
Description [The size of the chunk is computed as the minimum of
|
||||
1024 entries and 64K. Can only work with entry size at least 4 byte long.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Asat_MmFixed_t * Asat_MmFixedStart( int nEntrySize )
|
||||
{
|
||||
Asat_MmFixed_t * p;
|
||||
|
||||
p = ALLOC( Asat_MmFixed_t, 1 );
|
||||
memset( p, 0, sizeof(Asat_MmFixed_t) );
|
||||
|
||||
p->nEntrySize = nEntrySize;
|
||||
p->nEntriesAlloc = 0;
|
||||
p->nEntriesUsed = 0;
|
||||
p->pEntriesFree = NULL;
|
||||
|
||||
if ( nEntrySize * (1 << 10) < (1<<16) )
|
||||
p->nChunkSize = (1 << 10);
|
||||
else
|
||||
p->nChunkSize = (1<<16) / nEntrySize;
|
||||
if ( p->nChunkSize < 8 )
|
||||
p->nChunkSize = 8;
|
||||
|
||||
p->nChunksAlloc = 64;
|
||||
p->nChunks = 0;
|
||||
p->pChunks = ALLOC( char *, p->nChunksAlloc );
|
||||
|
||||
p->nMemoryUsed = 0;
|
||||
p->nMemoryAlloc = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_MmFixedStop( Asat_MmFixed_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
if ( p == NULL )
|
||||
return;
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n",
|
||||
p->nEntrySize, p->nChunkSize, p->nChunks );
|
||||
printf( " Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n",
|
||||
p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc );
|
||||
}
|
||||
for ( i = 0; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
free( p->pChunks );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Asat_MmFixedEntryFetch( Asat_MmFixed_t * p )
|
||||
{
|
||||
char * pTemp;
|
||||
int i;
|
||||
|
||||
// check if there are still free entries
|
||||
if ( p->nEntriesUsed == p->nEntriesAlloc )
|
||||
{ // need to allocate more entries
|
||||
assert( p->pEntriesFree == NULL );
|
||||
if ( p->nChunks == p->nChunksAlloc )
|
||||
{
|
||||
p->nChunksAlloc *= 2;
|
||||
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
|
||||
}
|
||||
p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize );
|
||||
p->nMemoryAlloc += p->nEntrySize * p->nChunkSize;
|
||||
// transform these entries into a linked list
|
||||
pTemp = p->pEntriesFree;
|
||||
for ( i = 1; i < p->nChunkSize; i++ )
|
||||
{
|
||||
*((char **)pTemp) = pTemp + p->nEntrySize;
|
||||
pTemp += p->nEntrySize;
|
||||
}
|
||||
// set the last link
|
||||
*((char **)pTemp) = NULL;
|
||||
// add the chunk to the chunk storage
|
||||
p->pChunks[ p->nChunks++ ] = p->pEntriesFree;
|
||||
// add to the number of entries allocated
|
||||
p->nEntriesAlloc += p->nChunkSize;
|
||||
}
|
||||
// incrememt the counter of used entries
|
||||
p->nEntriesUsed++;
|
||||
if ( p->nEntriesMax < p->nEntriesUsed )
|
||||
p->nEntriesMax = p->nEntriesUsed;
|
||||
// return the first entry in the free entry list
|
||||
pTemp = p->pEntriesFree;
|
||||
p->pEntriesFree = *((char **)pTemp);
|
||||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_MmFixedEntryRecycle( Asat_MmFixed_t * p, char * pEntry )
|
||||
{
|
||||
// decrement the counter of used entries
|
||||
p->nEntriesUsed--;
|
||||
// add the entry to the linked list of free entries
|
||||
*((char **)pEntry) = p->pEntriesFree;
|
||||
p->pEntriesFree = pEntry;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description [Relocates all the memory except the first chunk.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_MmFixedRestart( Asat_MmFixed_t * p )
|
||||
{
|
||||
int i;
|
||||
char * pTemp;
|
||||
|
||||
// deallocate all chunks except the first one
|
||||
for ( i = 1; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
p->nChunks = 1;
|
||||
// transform these entries into a linked list
|
||||
pTemp = p->pChunks[0];
|
||||
for ( i = 1; i < p->nChunkSize; i++ )
|
||||
{
|
||||
*((char **)pTemp) = pTemp + p->nEntrySize;
|
||||
pTemp += p->nEntrySize;
|
||||
}
|
||||
// set the last link
|
||||
*((char **)pTemp) = NULL;
|
||||
// set the free entry list
|
||||
p->pEntriesFree = p->pChunks[0];
|
||||
// set the correct statistics
|
||||
p->nMemoryAlloc = p->nEntrySize * p->nChunkSize;
|
||||
p->nMemoryUsed = 0;
|
||||
p->nEntriesAlloc = p->nChunkSize;
|
||||
p->nEntriesUsed = 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Asat_MmFixedReadMemUsage( Asat_MmFixed_t * p )
|
||||
{
|
||||
return p->nMemoryAlloc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Allocates entries of flexible size.]
|
||||
|
||||
Description [Can only work with entry size at least 4 byte long.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Asat_MmFlex_t * Asat_MmFlexStart()
|
||||
{
|
||||
Asat_MmFlex_t * p;
|
||||
|
||||
p = ALLOC( Asat_MmFlex_t, 1 );
|
||||
memset( p, 0, sizeof(Asat_MmFlex_t) );
|
||||
|
||||
p->nEntriesUsed = 0;
|
||||
p->pCurrent = NULL;
|
||||
p->pEnd = NULL;
|
||||
|
||||
p->nChunkSize = (1 << 12);
|
||||
p->nChunksAlloc = 64;
|
||||
p->nChunks = 0;
|
||||
p->pChunks = ALLOC( char *, p->nChunksAlloc );
|
||||
|
||||
p->nMemoryUsed = 0;
|
||||
p->nMemoryAlloc = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_MmFlexStop( Asat_MmFlex_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
if ( p == NULL )
|
||||
return;
|
||||
if ( fVerbose )
|
||||
{
|
||||
printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n",
|
||||
p->nChunkSize, p->nChunks );
|
||||
printf( " Entries used = %d. Memory used = %d. Memory alloc = %d.\n",
|
||||
p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc );
|
||||
}
|
||||
for ( i = 0; i < p->nChunks; i++ )
|
||||
free( p->pChunks[i] );
|
||||
free( p->pChunks );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Asat_MmFlexEntryFetch( Asat_MmFlex_t * p, int nBytes )
|
||||
{
|
||||
char * pTemp;
|
||||
// check if there are still free entries
|
||||
if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd )
|
||||
{ // need to allocate more entries
|
||||
if ( p->nChunks == p->nChunksAlloc )
|
||||
{
|
||||
p->nChunksAlloc *= 2;
|
||||
p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );
|
||||
}
|
||||
if ( nBytes > p->nChunkSize )
|
||||
{
|
||||
// resize the chunk size if more memory is requested than it can give
|
||||
// (ideally, this should never happen)
|
||||
p->nChunkSize = 2 * nBytes;
|
||||
}
|
||||
p->pCurrent = ALLOC( char, p->nChunkSize );
|
||||
p->pEnd = p->pCurrent + p->nChunkSize;
|
||||
p->nMemoryAlloc += p->nChunkSize;
|
||||
// add the chunk to the chunk storage
|
||||
p->pChunks[ p->nChunks++ ] = p->pCurrent;
|
||||
}
|
||||
assert( p->pCurrent + nBytes <= p->pEnd );
|
||||
// increment the counter of used entries
|
||||
p->nEntriesUsed++;
|
||||
// keep track of the memory used
|
||||
p->nMemoryUsed += nBytes;
|
||||
// return the next entry
|
||||
pTemp = p->pCurrent;
|
||||
p->pCurrent += nBytes;
|
||||
return pTemp;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Asat_MmFlexReadMemUsage( Asat_MmFlex_t * p )
|
||||
{
|
||||
return p->nMemoryAlloc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Starts the hierarchical memory manager.]
|
||||
|
||||
Description [This manager can allocate entries of any size.
|
||||
Iternally they are mapped into the entries with the number of bytes
|
||||
equal to the power of 2. The smallest entry size is 8 bytes. The
|
||||
next one is 16 bytes etc. So, if the user requests 6 bytes, he gets
|
||||
8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc.
|
||||
The input parameters "nSteps" says how many fixed memory managers
|
||||
are employed internally. Calling this procedure with nSteps equal
|
||||
to 10 results in 10 hierarchically arranged internal memory managers,
|
||||
which can allocate up to 4096 (1Kb) entries. Requests for larger
|
||||
entries are handed over to malloc() and then free()ed.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Asat_MmStep_t * Asat_MmStepStart( int nSteps )
|
||||
{
|
||||
Asat_MmStep_t * p;
|
||||
int i, k;
|
||||
p = ALLOC( Asat_MmStep_t, 1 );
|
||||
p->nMems = nSteps;
|
||||
// start the fixed memory managers
|
||||
p->pMems = ALLOC( Asat_MmFixed_t *, p->nMems );
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
p->pMems[i] = Asat_MmFixedStart( (8<<i) );
|
||||
// set up the mapping of the required memory size into the corresponding manager
|
||||
p->nMapSize = (4<<p->nMems);
|
||||
p->pMap = ALLOC( Asat_MmFixed_t *, p->nMapSize+1 );
|
||||
p->pMap[0] = NULL;
|
||||
for ( k = 1; k <= 4; k++ )
|
||||
p->pMap[k] = p->pMems[0];
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
for ( k = (4<<i)+1; k <= (8<<i); k++ )
|
||||
p->pMap[k] = p->pMems[i];
|
||||
//for ( i = 1; i < 100; i ++ )
|
||||
//printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize );
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the memory manager.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_MmStepStop( Asat_MmStep_t * p, int fVerbose )
|
||||
{
|
||||
int i;
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
Asat_MmFixedStop( p->pMems[i], fVerbose );
|
||||
free( p->pMems );
|
||||
free( p->pMap );
|
||||
free( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Creates the entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
char * Asat_MmStepEntryFetch( Asat_MmStep_t * p, int nBytes )
|
||||
{
|
||||
if ( nBytes == 0 )
|
||||
return NULL;
|
||||
if ( nBytes > p->nMapSize )
|
||||
{
|
||||
// printf( "Allocating %d bytes.\n", nBytes );
|
||||
return ALLOC( char, nBytes );
|
||||
}
|
||||
return Asat_MmFixedEntryFetch( p->pMap[nBytes] );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Recycles the entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_MmStepEntryRecycle( Asat_MmStep_t * p, char * pEntry, int nBytes )
|
||||
{
|
||||
if ( nBytes == 0 )
|
||||
return;
|
||||
if ( nBytes > p->nMapSize )
|
||||
{
|
||||
free( pEntry );
|
||||
return;
|
||||
}
|
||||
Asat_MmFixedEntryRecycle( p->pMap[nBytes], pEntry );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Asat_MmStepReadMemUsage( Asat_MmStep_t * p )
|
||||
{
|
||||
int i, nMemTotal = 0;
|
||||
for ( i = 0; i < p->nMems; i++ )
|
||||
nMemTotal += p->pMems[i]->nMemoryAlloc;
|
||||
return nMemTotal;
|
||||
}
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [asatmem.h]
|
||||
|
||||
PackageName [SAT solver.]
|
||||
|
||||
Synopsis [Memory management.]
|
||||
|
||||
Author [Alan Mishchenko <alanmi@eecs.berkeley.edu>]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - January 1, 2004.]
|
||||
|
||||
Revision [$Id: asatmem.h,v 1.0 2004/01/01 1:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef __ASAT_MEM_H__
|
||||
#define __ASAT_MEM_H__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//#include "leaks.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// STRUCTURE DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct Asat_MmFixed_t_ Asat_MmFixed_t;
|
||||
typedef struct Asat_MmFlex_t_ Asat_MmFlex_t;
|
||||
typedef struct Asat_MmStep_t_ Asat_MmStep_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// GLOBAL VARIABLES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// MACRO DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// fixed-size-block memory manager
|
||||
extern Asat_MmFixed_t * Asat_MmFixedStart( int nEntrySize );
|
||||
extern void Asat_MmFixedStop( Asat_MmFixed_t * p, int fVerbose );
|
||||
extern char * Asat_MmFixedEntryFetch( Asat_MmFixed_t * p );
|
||||
extern void Asat_MmFixedEntryRecycle( Asat_MmFixed_t * p, char * pEntry );
|
||||
extern void Asat_MmFixedRestart( Asat_MmFixed_t * p );
|
||||
extern int Asat_MmFixedReadMemUsage( Asat_MmFixed_t * p );
|
||||
// flexible-size-block memory manager
|
||||
extern Asat_MmFlex_t * Asat_MmFlexStart();
|
||||
extern void Asat_MmFlexStop( Asat_MmFlex_t * p, int fVerbose );
|
||||
extern char * Asat_MmFlexEntryFetch( Asat_MmFlex_t * p, int nBytes );
|
||||
extern int Asat_MmFlexReadMemUsage( Asat_MmFlex_t * p );
|
||||
// hierarchical memory manager
|
||||
extern Asat_MmStep_t * Asat_MmStepStart( int nSteps );
|
||||
extern void Asat_MmStepStop( Asat_MmStep_t * p, int fVerbose );
|
||||
extern char * Asat_MmStepEntryFetch( Asat_MmStep_t * p, int nBytes );
|
||||
extern void Asat_MmStepEntryRecycle( Asat_MmStep_t * p, char * pEntry, int nBytes );
|
||||
extern int Asat_MmStepReadMemUsage( Asat_MmStep_t * p );
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -1,514 +0,0 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [jfront.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [C-language MiniSat solver.]
|
||||
|
||||
Synopsis [Implementation of J-frontier.]
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: jfront.c,v 1.4 2005/09/16 22:55:03 casem Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "solver.h"
|
||||
#include "extra.h"
|
||||
#include "vec.h"
|
||||
|
||||
/*
|
||||
At any time during the solving process, the J-frontier is the set of currently
|
||||
unassigned variables, each of which has at least one fanin/fanout variable that
|
||||
is currently assigned. In the context of a CNF-based solver, default decisions
|
||||
based on variable activity are modified to choose the most active variable among
|
||||
those currently on the J-frontier.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// variable on the J-frontier
|
||||
typedef struct Asat_JVar_t_ Asat_JVar_t;
|
||||
struct Asat_JVar_t_
|
||||
{
|
||||
unsigned int Num; // variable number
|
||||
unsigned int nRefs; // the number of adjacent assigned vars
|
||||
unsigned int Prev; // the previous variable
|
||||
unsigned int Next; // the next variable
|
||||
unsigned int nFans; // the number of fanins/fanouts
|
||||
unsigned int Fans[0]; // the fanin/fanout variables
|
||||
};
|
||||
|
||||
// the J-frontier as a ring of variables
|
||||
// (ring is used instead of list because it allows to control the insertion point)
|
||||
typedef struct Asat_JRing_t_ Asat_JRing_t;
|
||||
struct Asat_JRing_t_
|
||||
{
|
||||
Asat_JVar_t * pRoot; // the pointer to the root
|
||||
int nItems; // the number of variables in the ring
|
||||
};
|
||||
|
||||
// the J-frontier manager
|
||||
struct Asat_JMan_t_
|
||||
{
|
||||
solver * pSat; // the SAT solver
|
||||
Asat_JRing_t rVars; // the ring of variables
|
||||
Vec_Ptr_t * vVars; // the pointers to variables
|
||||
Extra_MmFlex_t * pMem; // the memory manager for variables
|
||||
};
|
||||
|
||||
// getting hold of the given variable
|
||||
static inline Asat_JVar_t * Asat_JManVar( Asat_JMan_t * p, int Num ) { return !Num? NULL : Vec_PtrEntry(p->vVars, Num); }
|
||||
static inline Asat_JVar_t * Asat_JVarPrev( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return Asat_JManVar(p, pVar->Prev); }
|
||||
static inline Asat_JVar_t * Asat_JVarNext( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return Asat_JManVar(p, pVar->Next); }
|
||||
|
||||
//The solver can communicate to the variable order the following parts:
|
||||
//- the array of current assignments (pSat->pAssigns)
|
||||
//- the array of variable activities (pSat->pdActivity)
|
||||
//- the array of variables currently in the cone
|
||||
//- the array of arrays of variables adjacent to each other
|
||||
|
||||
static inline int Asat_JVarIsInBoundary( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return pVar->Next > 0; }
|
||||
static inline int Asat_JVarIsAssigned( Asat_JMan_t * p, Asat_JVar_t * pVar ) { return p->pSat->assigns[pVar->Num] != l_Undef; }
|
||||
//static inline int Asat_JVarIsUsedInCone( Asat_JMan_t * p, int Var ) { return p->pSat->vVarsUsed->pArray[i]; }
|
||||
|
||||
// manipulating the ring of variables
|
||||
static void Asat_JRingAddLast( Asat_JMan_t * p, Asat_JVar_t * pVar );
|
||||
static void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar );
|
||||
|
||||
// iterator through the entries in J-boundary
|
||||
#define Asat_JRingForEachEntry( p, pVar, pNext ) \
|
||||
for ( pVar = p->rVars.pRoot, \
|
||||
pNext = pVar? Asat_JVarNext(p, pVar) : NULL; \
|
||||
pVar; \
|
||||
pVar = (pNext != p->rVars.pRoot)? pNext : NULL, \
|
||||
pNext = pVar? Asat_JVarNext(p, pVar) : NULL )
|
||||
|
||||
// iterator through the adjacent variables
|
||||
#define Asat_JVarForEachFanio( p, pVar, pFan, i ) \
|
||||
for ( i = 0; (i < (int)pVar->nFans) && (((pFan) = Asat_JManVar(p, pVar->Fans[i])), 1); i++ )
|
||||
|
||||
extern void Asat_JManAssign( Asat_JMan_t * p, int Var );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Start the J-frontier.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Asat_JMan_t * Asat_JManStart( solver * pSat, void * pCircuit )
|
||||
{
|
||||
Vec_Vec_t * vCircuit = pCircuit;
|
||||
Asat_JMan_t * p;
|
||||
Asat_JVar_t * pVar;
|
||||
Vec_Int_t * vConnect;
|
||||
int i, nBytes, Entry, k;
|
||||
// make sure the number of variables is less than sizeof(unsigned int)
|
||||
assert( Vec_VecSize(vCircuit) < (1 << 16) );
|
||||
assert( Vec_VecSize(vCircuit) == pSat->size );
|
||||
// allocate the manager
|
||||
p = ALLOC( Asat_JMan_t, 1 );
|
||||
memset( p, 0, sizeof(Asat_JMan_t) );
|
||||
p->pSat = pSat;
|
||||
p->pMem = Extra_MmFlexStart();
|
||||
// fill in the variables
|
||||
p->vVars = Vec_PtrAlloc( Vec_VecSize(vCircuit) );
|
||||
for ( i = 0; i < Vec_VecSize(vCircuit); i++ )
|
||||
{
|
||||
vConnect = Vec_VecEntry( vCircuit, i );
|
||||
nBytes = sizeof(Asat_JVar_t) + sizeof(int) * Vec_IntSize(vConnect);
|
||||
nBytes = sizeof(void *) * (nBytes / sizeof(void *) + ((nBytes % sizeof(void *)) != 0));
|
||||
pVar = (Asat_JVar_t *)Extra_MmFlexEntryFetch( p->pMem, nBytes );
|
||||
memset( pVar, 0, nBytes );
|
||||
pVar->Num = i;
|
||||
// add fanins/fanouts
|
||||
pVar->nFans = Vec_IntSize( vConnect );
|
||||
Vec_IntForEachEntry( vConnect, Entry, k )
|
||||
pVar->Fans[k] = Entry;
|
||||
// add the variable
|
||||
Vec_PtrPush( p->vVars, pVar );
|
||||
}
|
||||
// set the current assignments
|
||||
Vec_PtrForEachEntryStart( p->vVars, pVar, i, 1 )
|
||||
{
|
||||
// if ( !Asat_JVarIsUsedInCone(p, pVar) )
|
||||
// continue;
|
||||
// skip assigned vars, vars in the boundary, and vars not used in the cone
|
||||
if ( Asat_JVarIsAssigned(p, pVar) )
|
||||
Asat_JManAssign( p, pVar->Num );
|
||||
}
|
||||
|
||||
pSat->pJMan = p;
|
||||
return p;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Stops the J-frontier.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_JManStop( solver * pSat )
|
||||
{
|
||||
Asat_JMan_t * p = pSat->pJMan;
|
||||
if ( p == NULL )
|
||||
return;
|
||||
pSat->pJMan = NULL;
|
||||
Extra_MmFlexStop( p->pMem );
|
||||
Vec_PtrFree( p->vVars );
|
||||
free( p );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Asat_JManCheck( Asat_JMan_t * p )
|
||||
{
|
||||
Asat_JVar_t * pVar, * pNext, * pFan;
|
||||
// Msat_IntVec_t * vRound;
|
||||
// int * pRound, nRound;
|
||||
// int * pVars, nVars, i, k;
|
||||
int i, k;
|
||||
int Counter = 0;
|
||||
|
||||
// go through all the variables in the boundary
|
||||
Asat_JRingForEachEntry( p, pVar, pNext )
|
||||
{
|
||||
assert( !Asat_JVarIsAssigned(p, pVar) );
|
||||
// go though all the variables in the neighborhood
|
||||
// and check that it is true that there is least one assigned
|
||||
// vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVar->Num );
|
||||
// nRound = Msat_IntVecReadSize( vRound );
|
||||
// pRound = Msat_IntVecReadArray( vRound );
|
||||
// for ( i = 0; i < nRound; i++ )
|
||||
Asat_JVarForEachFanio( p, pVar, pFan, i )
|
||||
{
|
||||
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
|
||||
// continue;
|
||||
if ( Asat_JVarIsAssigned(p, pFan) )
|
||||
break;
|
||||
}
|
||||
// assert( i != pVar->nFans );
|
||||
// if ( i == pVar->nFans )
|
||||
// return 0;
|
||||
if ( i == (int)pVar->nFans )
|
||||
Counter++;
|
||||
}
|
||||
if ( Counter > 0 )
|
||||
printf( "%d(%d) ", Counter, p->rVars.nItems );
|
||||
|
||||
// we may also check other unassigned variables in the cone
|
||||
// to make sure that if they are not in J-boundary,
|
||||
// then they do not have an assigned neighbor
|
||||
// nVars = Msat_IntVecReadSize( p->pSat->vConeVars );
|
||||
// pVars = Msat_IntVecReadArray( p->pSat->vConeVars );
|
||||
// for ( i = 0; i < nVars; i++ )
|
||||
Vec_PtrForEachEntry( p->vVars, pVar, i )
|
||||
{
|
||||
// assert( Asat_JVarIsUsedInCone(p, pVar) );
|
||||
// skip assigned vars, vars in the boundary, and vars not used in the cone
|
||||
if ( Asat_JVarIsAssigned(p, pVar) || Asat_JVarIsInBoundary(p, pVar) )
|
||||
continue;
|
||||
// make sure, it does not have assigned neighbors
|
||||
// vRound = (Msat_IntVec_t *)Msat_ClauseVecReadEntry( p->pSat->vAdjacents, pVars[i] );
|
||||
// nRound = Msat_IntVecReadSize( vRound );
|
||||
// pRound = Msat_IntVecReadArray( vRound );
|
||||
// for ( i = 0; i < nRound; i++ )
|
||||
Asat_JVarForEachFanio( p, pVar, pFan, k )
|
||||
{
|
||||
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
|
||||
// continue;
|
||||
if ( Asat_JVarIsAssigned(p, pFan) )
|
||||
break;
|
||||
}
|
||||
// assert( k == pVar->nFans );
|
||||
// if ( k != pVar->nFans )
|
||||
// return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_JManAssign( Asat_JMan_t * p, int Var )
|
||||
{
|
||||
// Msat_IntVec_t * vRound;
|
||||
Asat_JVar_t * pVar, * pFan;
|
||||
int i, clk = clock();
|
||||
|
||||
// make sure the variable is in the boundary
|
||||
assert( Var < Vec_PtrSize(p->vVars) );
|
||||
// if it is not in the boundary (initial decision, random decision), do not remove
|
||||
pVar = Asat_JManVar( p, Var );
|
||||
if ( Asat_JVarIsInBoundary( p, pVar ) )
|
||||
Asat_JRingRemove( p, pVar );
|
||||
// add to the boundary those neighbors that are (1) unassigned, (2) not in boundary
|
||||
// because for them we know that there is a variable (Var) which is assigned
|
||||
// vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
|
||||
// for ( i = 0; i < vRound->nSize; i++ )
|
||||
Asat_JVarForEachFanio( p, pVar, pFan, i )
|
||||
{
|
||||
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
|
||||
// continue;
|
||||
pFan->nRefs++;
|
||||
if ( Asat_JVarIsAssigned(p, pFan) || Asat_JVarIsInBoundary(p, pFan) )
|
||||
continue;
|
||||
Asat_JRingAddLast( p, pFan );
|
||||
}
|
||||
//timeSelect += clock() - clk;
|
||||
// Asat_JManCheck( p );
|
||||
p->pSat->timeUpdate += clock() - clk;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_JManUnassign( Asat_JMan_t * p, int Var )
|
||||
{
|
||||
// Msat_IntVec_t * vRound, * vRound2;
|
||||
Asat_JVar_t * pVar, * pFan;
|
||||
int i, clk = clock();//, k
|
||||
|
||||
// make sure the variable is not in the boundary
|
||||
assert( Var < Vec_PtrSize(p->vVars) );
|
||||
pVar = Asat_JManVar( p, Var );
|
||||
assert( !Asat_JVarIsInBoundary( p, pVar ) );
|
||||
// go through its neigbors - if one of them is assigned add this var
|
||||
// add to the boundary those neighbors that are not there already
|
||||
// this will also get rid of variable outside of the current cone
|
||||
// because they are unassigned in Msat_SolverPrepare()
|
||||
// vRound = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[Var];
|
||||
// for ( i = 0; i < vRound->nSize; i++ )
|
||||
// if ( Asat_JVarIsAssigned(p, vRound->pArray[i]) )
|
||||
// break;
|
||||
// if ( i != vRound->nSize )
|
||||
// Asat_JRingAddLast( &p->rVars, &p->pVars[Var] );
|
||||
if ( pVar->nRefs != 0 )
|
||||
Asat_JRingAddLast( p, pVar );
|
||||
|
||||
/*
|
||||
// unassigning a variable may lead to its adjacents dropping from the boundary
|
||||
for ( i = 0; i < vRound->nSize; i++ )
|
||||
if ( Asat_JVarIsInBoundary(p, vRound->pArray[i]) )
|
||||
{ // the neighbor is in the J-boundary (and unassigned)
|
||||
assert( !Asat_JVarIsAssigned(p, vRound->pArray[i]) );
|
||||
vRound2 = (Msat_IntVec_t *)p->pSat->vAdjacents->pArray[vRound->pArray[i]];
|
||||
// go through its neighbors and determine if there is at least one assigned
|
||||
for ( k = 0; k < vRound2->nSize; k++ )
|
||||
if ( Asat_JVarIsAssigned(p, vRound2->pArray[k]) )
|
||||
break;
|
||||
if ( k == vRound2->nSize ) // there is no assigned vars, delete this one
|
||||
Asat_JRingRemove( &p->rVars, &p->pVars[vRound->pArray[i]] );
|
||||
}
|
||||
*/
|
||||
Asat_JVarForEachFanio( p, pVar, pFan, i )
|
||||
{
|
||||
// if ( !Asat_JVarIsUsedInCone(p, pFan) )
|
||||
// continue;
|
||||
assert( pFan->nRefs > 0 );
|
||||
pFan->nRefs--;
|
||||
if ( !Asat_JVarIsInBoundary(p, pFan) )
|
||||
continue;
|
||||
// the neighbor is in the J-boundary (and unassigned)
|
||||
assert( !Asat_JVarIsAssigned(p, pFan) );
|
||||
// if there is no assigned vars, delete this one
|
||||
if ( pFan->nRefs == 0 )
|
||||
Asat_JRingRemove( p, pFan );
|
||||
}
|
||||
|
||||
//timeSelect += clock() - clk;
|
||||
// Asat_JManCheck( p );
|
||||
p->pSat->timeUpdate += clock() - clk;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Asat_JManSelect( Asat_JMan_t * p )
|
||||
{
|
||||
Asat_JVar_t * pVar, * pNext, * pVarBest;
|
||||
double * pdActs = p->pSat->activity;
|
||||
double dfActBest;
|
||||
int clk = clock();
|
||||
|
||||
pVarBest = NULL;
|
||||
dfActBest = -1.0;
|
||||
Asat_JRingForEachEntry( p, pVar, pNext )
|
||||
{
|
||||
if ( dfActBest <= pdActs[pVar->Num] )//+ 0.00001 )
|
||||
{
|
||||
dfActBest = pdActs[pVar->Num];
|
||||
pVarBest = pVar;
|
||||
}
|
||||
}
|
||||
//timeSelect += clock() - clk;
|
||||
//timeAssign += clock() - clk;
|
||||
//if ( pVarBest && pVarBest->Num % 1000 == 0 )
|
||||
//printf( "%d ", p->rVars.nItems );
|
||||
|
||||
// Asat_JManCheck( p );
|
||||
p->pSat->timeSelect += clock() - clk;
|
||||
if ( pVarBest )
|
||||
{
|
||||
// assert( Asat_JVarIsUsedInCone(p, pVarBest) );
|
||||
return pVarBest->Num;
|
||||
}
|
||||
return var_Undef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Adds node to the end of the ring.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_JRingAddLast( Asat_JMan_t * p, Asat_JVar_t * pVar )
|
||||
{
|
||||
Asat_JRing_t * pRing = &p->rVars;
|
||||
//printf( "adding %d\n", pVar->Num );
|
||||
// check that the node is not in a ring
|
||||
assert( pVar->Prev == 0 );
|
||||
assert( pVar->Next == 0 );
|
||||
// if the ring is empty, make the node point to itself
|
||||
pRing->nItems++;
|
||||
if ( pRing->pRoot == NULL )
|
||||
{
|
||||
pRing->pRoot = pVar;
|
||||
// pVar->pPrev = pVar;
|
||||
pVar->Prev = pVar->Num;
|
||||
// pVar->pNext = pVar;
|
||||
pVar->Next = pVar->Num;
|
||||
return;
|
||||
}
|
||||
// if the ring is not empty, add it as the last entry
|
||||
// pVar->pPrev = pRing->pRoot->pPrev;
|
||||
pVar->Prev = pRing->pRoot->Prev;
|
||||
// pVar->pNext = pRing->pRoot;
|
||||
pVar->Next = pRing->pRoot->Num;
|
||||
// pVar->pPrev->pNext = pVar;
|
||||
Asat_JVarPrev(p, pVar)->Next = pVar->Num;
|
||||
// pVar->pNext->pPrev = pVar;
|
||||
Asat_JVarNext(p, pVar)->Prev = pVar->Num;
|
||||
|
||||
// move the root so that it points to the new entry
|
||||
// pRing->pRoot = pRing->pRoot->pPrev;
|
||||
pRing->pRoot = Asat_JVarPrev(p, pRing->pRoot);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes the node from the ring.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Asat_JRingRemove( Asat_JMan_t * p, Asat_JVar_t * pVar )
|
||||
{
|
||||
Asat_JRing_t * pRing = &p->rVars;
|
||||
//printf( "removing %d\n", pVar->Num );
|
||||
// check that the var is in a ring
|
||||
assert( pVar->Prev );
|
||||
assert( pVar->Next );
|
||||
pRing->nItems--;
|
||||
if ( pRing->nItems == 0 )
|
||||
{
|
||||
assert( pRing->pRoot == pVar );
|
||||
// pVar->pPrev = NULL;
|
||||
pVar->Prev = 0;
|
||||
// pVar->pNext = NULL;
|
||||
pVar->Next = 0;
|
||||
pRing->pRoot = NULL;
|
||||
return;
|
||||
}
|
||||
// move the root if needed
|
||||
if ( pRing->pRoot == pVar )
|
||||
// pRing->pRoot = pVar->pNext;
|
||||
pRing->pRoot = Asat_JVarNext(p, pVar);
|
||||
// move the root to the next entry after pVar
|
||||
// this way all the additions to the list will be traversed first
|
||||
// pRing->pRoot = pVar->pNext;
|
||||
pRing->pRoot = Asat_JVarPrev(p, pVar);
|
||||
// delete the node
|
||||
// pVar->pPrev->pNext = pVar->pNext;
|
||||
Asat_JVarPrev(p, pVar)->Next = Asat_JVarNext(p, pVar)->Num;
|
||||
// pVar->pNext->pPrev = pVar->pPrev;
|
||||
Asat_JVarNext(p, pVar)->Prev = Asat_JVarPrev(p, pVar)->Num;
|
||||
// pVar->pPrev = NULL;
|
||||
pVar->Prev = 0;
|
||||
// pVar->pNext = NULL;
|
||||
pVar->Next = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
MiniSat -- Copyright (c) 2005, Niklas Sorensson
|
||||
http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
// Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko
|
||||
|
||||
#include "solver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
//#include <unistd.h>
|
||||
//#include <signal.h>
|
||||
//#include <zlib.h>
|
||||
//#include <sys/time.h>
|
||||
//#include <sys/resource.h>
|
||||
|
||||
//=================================================================================================
|
||||
// Helpers:
|
||||
|
||||
|
||||
// Reads an input stream to end-of-file and returns the result as a 'char*' terminated by '\0'
|
||||
// (dynamic allocation in case 'in' is standard input).
|
||||
//
|
||||
char* readFile(FILE * in)
|
||||
{
|
||||
char* data = malloc(65536);
|
||||
int cap = 65536;
|
||||
int size = 0;
|
||||
|
||||
while (!feof(in)){
|
||||
if (size == cap){
|
||||
cap *= 2;
|
||||
data = realloc(data, cap); }
|
||||
size += fread(&data[size], 1, 65536, in);
|
||||
}
|
||||
data = realloc(data, size+1);
|
||||
data[size] = '\0';
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//static inline double cpuTime(void) {
|
||||
// struct rusage ru;
|
||||
// getrusage(RUSAGE_SELF, &ru);
|
||||
// return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
// DIMACS Parser:
|
||||
|
||||
|
||||
static inline void skipWhitespace(char** in) {
|
||||
while ((**in >= 9 && **in <= 13) || **in == 32)
|
||||
(*in)++; }
|
||||
|
||||
static inline void skipLine(char** in) {
|
||||
for (;;){
|
||||
if (**in == 0) return;
|
||||
if (**in == '\n') { (*in)++; return; }
|
||||
(*in)++; } }
|
||||
|
||||
static inline int parseInt(char** in) {
|
||||
int val = 0;
|
||||
int _neg = 0;
|
||||
skipWhitespace(in);
|
||||
if (**in == '-') _neg = 1, (*in)++;
|
||||
else if (**in == '+') (*in)++;
|
||||
if (**in < '0' || **in > '9') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", **in), exit(1);
|
||||
while (**in >= '0' && **in <= '9')
|
||||
val = val*10 + (**in - '0'),
|
||||
(*in)++;
|
||||
return _neg ? -val : val; }
|
||||
|
||||
static void readClause(char** in, solver* s, vec* lits) {
|
||||
int parsed_lit, var;
|
||||
vec_resize(lits,0);
|
||||
for (;;){
|
||||
parsed_lit = parseInt(in);
|
||||
if (parsed_lit == 0) break;
|
||||
var = abs(parsed_lit)-1;
|
||||
vec_push(lits, (void*)(parsed_lit > 0 ? toLit(var) : neg(toLit(var))));
|
||||
}
|
||||
}
|
||||
|
||||
static lbool parse_DIMACS_main(char* in, solver* s) {
|
||||
vec lits;
|
||||
vec_new(&lits);
|
||||
|
||||
for (;;){
|
||||
skipWhitespace(&in);
|
||||
if (*in == 0)
|
||||
break;
|
||||
else if (*in == 'c' || *in == 'p')
|
||||
skipLine(&in);
|
||||
else{
|
||||
lit* begin;
|
||||
readClause(&in, s, &lits);
|
||||
begin = (lit*)vec_begin(&lits);
|
||||
if (solver_addclause(s, begin, begin+vec_size(&lits)) == l_False){
|
||||
vec_delete(&lits);
|
||||
return l_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
vec_delete(&lits);
|
||||
return solver_simplify(s);
|
||||
}
|
||||
|
||||
|
||||
// Inserts problem into solver. Returns FALSE upon immediate conflict.
|
||||
//
|
||||
static lbool parse_DIMACS(FILE * in, solver* s) {
|
||||
char* text = readFile(in);
|
||||
lbool ret = parse_DIMACS_main(text, s);
|
||||
free(text);
|
||||
return ret; }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
|
||||
void printStats(stats* stats, int cpu_time)
|
||||
{
|
||||
double Time = (float)(cpu_time)/(float)(CLOCKS_PER_SEC);
|
||||
printf("restarts : %12d\n", stats->starts);
|
||||
printf("conflicts : %12.0f (%9.0f / sec )\n", (double)stats->conflicts , (double)stats->conflicts /Time);
|
||||
printf("decisions : %12.0f (%9.0f / sec )\n", (double)stats->decisions , (double)stats->decisions /Time);
|
||||
printf("propagations : %12.0f (%9.0f / sec )\n", (double)stats->propagations, (double)stats->propagations/Time);
|
||||
printf("inspects : %12.0f (%9.0f / sec )\n", (double)stats->inspects , (double)stats->inspects /Time);
|
||||
printf("conflict literals : %12.0f (%9.2f %% deleted )\n", (double)stats->tot_literals, (double)(stats->max_literals - stats->tot_literals) * 100.0 / (double)stats->max_literals);
|
||||
printf("CPU time : %12.2f sec\n", Time);
|
||||
}
|
||||
|
||||
//solver* slv;
|
||||
//static void SIGINT_handler(int signum) {
|
||||
// printf("\n"); printf("*** INTERRUPTED ***\n");
|
||||
// printStats(&slv->stats, cpuTime());
|
||||
// printf("\n"); printf("*** INTERRUPTED ***\n");
|
||||
// exit(0); }
|
||||
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
solver* s = solver_new();
|
||||
lbool st;
|
||||
FILE * in;
|
||||
int clk = clock();
|
||||
|
||||
if (argc != 2)
|
||||
fprintf(stderr, "ERROR! Not enough command line arguments.\n"),
|
||||
exit(1);
|
||||
|
||||
in = fopen(argv[1], "rb");
|
||||
if (in == NULL)
|
||||
fprintf(stderr, "ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]),
|
||||
exit(1);
|
||||
st = parse_DIMACS(in, s);
|
||||
fclose(in);
|
||||
|
||||
if (st == l_False){
|
||||
solver_delete(s);
|
||||
printf("Trivial problem\nUNSATISFIABLE\n");
|
||||
exit(20);
|
||||
}
|
||||
|
||||
s->verbosity = 1;
|
||||
// slv = s;
|
||||
// signal(SIGINT,SIGINT_handler);
|
||||
st = solver_solve(s,0,0);
|
||||
printStats(&s->stats, clock() - clk);
|
||||
printf("\n");
|
||||
printf(st == l_True ? "SATISFIABLE\n" : "UNSATISFIABLE\n");
|
||||
|
||||
solver_delete(s);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
SRC += src/sat/asat/added.c \
|
||||
src/sat/asat/asatmem.c \
|
||||
src/sat/asat/jfront.c \
|
||||
src/sat/asat/solver.c
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,189 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
MiniSat -- Copyright (c) 2005, Niklas Sorensson
|
||||
http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
// Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko
|
||||
|
||||
#ifndef solver_h
|
||||
#define solver_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline __inline // compatible with MS VS 6.0
|
||||
#endif
|
||||
|
||||
#include "solver_vec.h"
|
||||
#include "asatmem.h"
|
||||
|
||||
//=================================================================================================
|
||||
// Simple types:
|
||||
|
||||
//typedef int bool;
|
||||
#ifndef __cplusplus
|
||||
#ifndef bool
|
||||
#define bool int
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef int lit;
|
||||
typedef char lbool;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef signed __int64 sint64; // compatible with MS VS 6.0
|
||||
#else
|
||||
typedef long long sint64;
|
||||
#endif
|
||||
|
||||
static const int var_Undef = -1;
|
||||
static const lit lit_Undef = -2;
|
||||
|
||||
static const lbool l_Undef = 0;
|
||||
static const lbool l_True = 1;
|
||||
static const lbool l_False = -1;
|
||||
|
||||
static inline lit neg (lit l) { return l ^ 1; }
|
||||
static inline lit toLit (int v) { return v + v; }
|
||||
static inline lit toLitCond (int v, int c) { return v + v + (int)(c != 0); }
|
||||
|
||||
//=================================================================================================
|
||||
// Public interface:
|
||||
|
||||
typedef struct Asat_JMan_t_ Asat_JMan_t;
|
||||
|
||||
struct solver_t;
|
||||
typedef struct solver_t solver;
|
||||
|
||||
extern solver* solver_new(void);
|
||||
extern void solver_delete(solver* s);
|
||||
|
||||
extern bool solver_addclause(solver* s, lit* begin, lit* end);
|
||||
extern bool solver_simplify(solver* s);
|
||||
extern int solver_solve(solver* s, lit* begin, lit* end, sint64 nConfLimit, sint64 nInsLimit);
|
||||
extern int * solver_get_model( solver * p, int * pVars, int nVars );
|
||||
|
||||
extern int solver_nvars(solver* s);
|
||||
extern int solver_nclauses(solver* s);
|
||||
|
||||
|
||||
// additional procedures
|
||||
extern void Asat_SolverWriteDimacs( solver * pSat, char * pFileName,
|
||||
lit* assumptionsBegin, lit* assumptionsEnd,
|
||||
int incrementVars);
|
||||
extern void Asat_SatPrintStats( FILE * pFile, solver * p );
|
||||
extern void Asat_SolverSetPrefVars( solver * s, int * pPrefVars, int nPrefVars );
|
||||
extern void Asat_SolverSetFactors( solver * s, float * pFactors );
|
||||
|
||||
// trace recording
|
||||
extern void Sat_SolverTraceStart( solver * pSat, char * pName );
|
||||
extern void Sat_SolverTraceStop( solver * pSat );
|
||||
extern void Sat_SolverTraceWrite( solver * pSat, int * pBeg, int * pEnd, int fRoot );
|
||||
|
||||
// J-frontier support
|
||||
extern Asat_JMan_t * Asat_JManStart( solver * pSat, void * vCircuit );
|
||||
extern void Asat_JManStop( solver * pSat );
|
||||
|
||||
|
||||
struct stats_t
|
||||
{
|
||||
sint64 starts, decisions, propagations, inspects, conflicts;
|
||||
sint64 clauses, clauses_literals, learnts, learnts_literals, max_literals, tot_literals;
|
||||
};
|
||||
typedef struct stats_t stats;
|
||||
|
||||
//=================================================================================================
|
||||
// Solver representation:
|
||||
|
||||
struct clause_t;
|
||||
typedef struct clause_t clause;
|
||||
|
||||
struct solver_t
|
||||
{
|
||||
int size; // nof variables
|
||||
int cap; // size of varmaps
|
||||
int qhead; // Head index of queue.
|
||||
int qtail; // Tail index of queue.
|
||||
|
||||
// clauses
|
||||
vec clauses; // List of problem constraints. (contains: clause*)
|
||||
vec learnts; // List of learnt clauses. (contains: clause*)
|
||||
|
||||
// activities
|
||||
double var_inc; // Amount to bump next variable with.
|
||||
double var_decay; // INVERSE decay factor for variable activity: stores 1/decay.
|
||||
float cla_inc; // Amount to bump next clause with.
|
||||
float cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
|
||||
|
||||
vec* wlists; //
|
||||
double* activity; // A heuristic measurement of the activity of a variable.
|
||||
float * factors; // the factor of variable activity
|
||||
lbool* assigns; // Current values of variables.
|
||||
int* orderpos; // Index in variable order.
|
||||
clause** reasons; //
|
||||
int* levels; //
|
||||
lit* trail;
|
||||
|
||||
clause* binary; // A temporary binary clause
|
||||
lbool* tags; //
|
||||
veci tagged; // (contains: var)
|
||||
veci stack; // (contains: var)
|
||||
|
||||
veci order; // Variable order. (heap) (contains: var)
|
||||
veci trail_lim; // Separator indices for different decision levels in 'trail'. (contains: int)
|
||||
veci model; // If problem is solved, this vector contains the model (contains: lbool).
|
||||
|
||||
int root_level; // Level of first proper decision.
|
||||
int simpdb_assigns;// Number of top-level assignments at last 'simplifyDB()'.
|
||||
int simpdb_props; // Number of propagations before next 'simplifyDB()'.
|
||||
double random_seed;
|
||||
double progress_estimate;
|
||||
int verbosity; // Verbosity level. 0=silent, 1=some progress report, 2=everything
|
||||
|
||||
sint64 nConfLimit; // external limit on the number of conflicts
|
||||
sint64 nInsLimit; // external limit on the number of implications
|
||||
|
||||
// the memory manager
|
||||
Asat_MmStep_t * pMem;
|
||||
|
||||
// J-frontier
|
||||
Asat_JMan_t * pJMan;
|
||||
|
||||
// for making decisions on some variables first
|
||||
int nPrefDecNum;
|
||||
int * pPrefVars;
|
||||
int nPrefVars;
|
||||
|
||||
// solver statistics
|
||||
stats solver_stats;
|
||||
int timeTotal;
|
||||
int timeSelect;
|
||||
int timeUpdate;
|
||||
|
||||
// trace recording
|
||||
FILE * pFile;
|
||||
int nClauses;
|
||||
int nRoots;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
MiniSat -- Copyright (c) 2005, Niklas Sorensson
|
||||
http://www.cs.chalmers.se/Cs/Research/FormalMethods/MiniSat/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
// Modified to compile with MS Visual Studio 6.0 by Alan Mishchenko
|
||||
|
||||
#ifndef vec_h
|
||||
#define vec_h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// vector of 32-bit intergers (added for 64-bit portability)
|
||||
struct veci_t {
|
||||
int size;
|
||||
int cap;
|
||||
int* ptr;
|
||||
};
|
||||
typedef struct veci_t veci;
|
||||
|
||||
static inline void veci_new (veci* v) {
|
||||
v->size = 0;
|
||||
v->cap = 4;
|
||||
v->ptr = (int*)malloc(sizeof(int)*v->cap);
|
||||
}
|
||||
|
||||
static inline void veci_delete (veci* v) { free(v->ptr); }
|
||||
static inline int* veci_begin (veci* v) { return v->ptr; }
|
||||
static inline int veci_size (veci* v) { return v->size; }
|
||||
static inline void veci_resize (veci* v, int k) { v->size = k; } // only safe to shrink !!
|
||||
static inline void veci_push (veci* v, int e)
|
||||
{
|
||||
if (v->size == v->cap) {
|
||||
int newsize = v->cap * 2+1;
|
||||
v->ptr = (int*)realloc(v->ptr,sizeof(int)*newsize);
|
||||
v->cap = newsize; }
|
||||
v->ptr[v->size++] = e;
|
||||
}
|
||||
|
||||
|
||||
// vector of 32- or 64-bit pointers
|
||||
struct vec_t {
|
||||
int size;
|
||||
int cap;
|
||||
void** ptr;
|
||||
};
|
||||
typedef struct vec_t vec;
|
||||
|
||||
static inline void vec_new (vec* v) {
|
||||
v->size = 0;
|
||||
v->cap = 4;
|
||||
v->ptr = (void**)malloc(sizeof(void*)*v->cap);
|
||||
}
|
||||
|
||||
static inline void vec_delete (vec* v) { free(v->ptr); }
|
||||
static inline void** vec_begin (vec* v) { return v->ptr; }
|
||||
static inline int vec_size (vec* v) { return v->size; }
|
||||
static inline void vec_resize (vec* v, int k) { v->size = k; } // only safe to shrink !!
|
||||
static inline void vec_push (vec* v, void* e)
|
||||
{
|
||||
if (v->size == v->cap) {
|
||||
int newsize = v->cap * 2+1;
|
||||
v->ptr = (void**)realloc(v->ptr,sizeof(void*)*newsize);
|
||||
v->cap = newsize; }
|
||||
v->ptr[v->size++] = e;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -1219,6 +1251,51 @@ int sat_solver_nconflicts(sat_solver* s)
|
|||
return (int)s->stats.conflicts;
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
// 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):
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -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 ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [C-language MiniSat solver.]
|
||||
PackageName [SAT sat_solver.]
|
||||
|
||||
Synopsis [Records the trace of SAT solving in the CNF form.]
|
||||
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "solver.h"
|
||||
#include "satSolver.h"
|
||||
|
||||
/*
|
||||
The trace of SAT solving contains the original clause of the problem
|
||||
|
|
@ -33,9 +33,6 @@
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
|
|
@ -52,7 +49,7 @@ static inline int lit_print(lit l) { return lit_sign(l)? -lit_var(l)-1 :
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sat_SolverTraceStart( solver * pSat, char * pName )
|
||||
void Sat_SolverTraceStart( sat_solver * pSat, char * pName )
|
||||
{
|
||||
assert( pSat->pFile == NULL );
|
||||
pSat->pFile = fopen( pName, "w" );
|
||||
|
|
@ -72,12 +69,12 @@ void Sat_SolverTraceStart( solver * pSat, char * pName )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sat_SolverTraceStop( solver * pSat )
|
||||
void Sat_SolverTraceStop( sat_solver * pSat )
|
||||
{
|
||||
if ( pSat->pFile == NULL )
|
||||
return;
|
||||
rewind( pSat->pFile );
|
||||
fprintf( pSat->pFile, "p %d %d %d", solver_nvars(pSat), pSat->nClauses, pSat->nRoots );
|
||||
fprintf( pSat->pFile, "p %d %d %d", sat_solver_nvars(pSat), pSat->nClauses, pSat->nRoots );
|
||||
fclose( pSat->pFile );
|
||||
pSat->pFile = NULL;
|
||||
}
|
||||
|
|
@ -94,7 +91,7 @@ void Sat_SolverTraceStop( solver * pSat )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Sat_SolverTraceWrite( solver * pSat, int * pBeg, int * pEnd, int fRoot )
|
||||
void Sat_SolverTraceWrite( sat_solver * pSat, int * pBeg, int * pEnd, int fRoot )
|
||||
{
|
||||
if ( pSat->pFile == NULL )
|
||||
return;
|
||||
|
|
@ -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 ///
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ enum CSAT_StatusT ABC_Solve( ABC_Manager mng )
|
|||
|
||||
// try to prove the miter using a number of techniques
|
||||
if ( mng->mode )
|
||||
RetValue = Abc_NtkMiterSat( mng->pTarget, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, 0, NULL, NULL );
|
||||
RetValue = Abc_NtkMiterSat( mng->pTarget, (sint64)pParams->nMiteringLimitLast, (sint64)0, 0, NULL, NULL );
|
||||
else
|
||||
// RetValue = Abc_NtkMiterProve( &mng->pTarget, pParams ); // old CEC engine
|
||||
RetValue = Abc_NtkIvyProve( &mng->pTarget, pParams ); // new CEC engine
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ extern "C" {
|
|||
/// INCLUDES ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "solver.h"
|
||||
#ifdef _WIN32
|
||||
typedef signed __int64 sint64; // compatible with MS VS 6.0
|
||||
#else
|
||||
typedef long long sint64;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// PARAMETERS ///
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include "vec.h"
|
||||
//#include "vec.h"
|
||||
#include "pr.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -150,7 +150,7 @@ Pr_Man_t * Pr_ManAlloc( int nVarsAlloc )
|
|||
// set the starting number of variables
|
||||
p->nVars = 0;
|
||||
// memory management
|
||||
p->nChunkSize = (1<<18); // use 256K chunks
|
||||
p->nChunkSize = (1<<16); // use 64K chunks
|
||||
// verification
|
||||
p->nResLitsAlloc = (1<<16);
|
||||
p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc );
|
||||
|
|
@ -329,13 +329,6 @@ int Pr_ManAddClause( Pr_Man_t * p, lit * pBeg, lit * pEnd, int fRoot, int fClaus
|
|||
printf( "More than one empty clause!\n" );
|
||||
p->pEmpty = pClause;
|
||||
}
|
||||
|
||||
// create watcher lists for the root clauses
|
||||
if ( fRoot && pClause->nLits > 1 )
|
||||
{
|
||||
Pr_ManWatchClause( p, pClause, pClause->pLits[0] );
|
||||
Pr_ManWatchClause( p, pClause, pClause->pLits[1] );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -386,6 +379,29 @@ void Pr_ManMemoryStop( Pr_Man_t * p )
|
|||
free( pMem );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reports memory usage in bytes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Pr_ManMemoryReport( Pr_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 [Records the proof.]
|
||||
|
|
@ -688,6 +704,7 @@ int Pr_ManProofTraceOne( Pr_Man_t * p, Pr_Cls_t * pConflict, Pr_Cls_t * pFinal )
|
|||
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];
|
||||
|
|
@ -695,6 +712,11 @@ int Pr_ManProofTraceOne( Pr_Man_t * p, Pr_Cls_t * pConflict, Pr_Cls_t * pFinal )
|
|||
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( pReason->pProof > 0 );
|
||||
p->Counter++;
|
||||
|
|
@ -751,16 +773,15 @@ int Pr_ManProofTraceOne( Pr_Man_t * p, Pr_Cls_t * pConflict, Pr_Cls_t * pFinal )
|
|||
}
|
||||
}
|
||||
|
||||
// add the variables to seen
|
||||
for ( v = 1; v < (int)pReason->nLits; v++ )
|
||||
p->pSeens[lit_var(pReason->pLits[v])] = 1;
|
||||
|
||||
// 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;
|
||||
// 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 )
|
||||
|
|
@ -904,6 +925,12 @@ int Pr_ManProcessRoots( Pr_Man_t * p )
|
|||
p->nTrailSize = 0;
|
||||
Pr_ManForEachClauseRoot( p, pClause )
|
||||
{
|
||||
// create watcher lists for the root clauses
|
||||
if ( pClause->nLits > 1 )
|
||||
{
|
||||
Pr_ManWatchClause( p, pClause, pClause->pLits[0] );
|
||||
Pr_ManWatchClause( p, pClause, pClause->pLits[1] );
|
||||
}
|
||||
// empty clause and large clauses
|
||||
if ( pClause->nLits != 1 )
|
||||
continue;
|
||||
|
|
@ -1218,9 +1245,10 @@ p->timeRead = clock() - clk;
|
|||
1.0*(p->Counter-p->nRoots)/(p->nClauses-p->nRoots),
|
||||
nUsed, 1.0*nUsed/(p->nClauses-p->nRoots) );
|
||||
*/
|
||||
printf( "Vars = %d. Roots = %d. Learned = %d. Resolution steps = %d. Ave = %.2f.\n",
|
||||
printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d. Ave = %.2f. Mem = %.2f Mb\n",
|
||||
p->nVars, p->nRoots, p->nClauses-p->nRoots, p->Counter,
|
||||
1.0*(p->Counter-p->nRoots)/(p->nClauses-p->nRoots) );
|
||||
1.0*(p->Counter-p->nRoots)/(p->nClauses-p->nRoots),
|
||||
1.0*Pr_ManMemoryReport(p)/(1<<20) );
|
||||
|
||||
p->timeTotal = clock() - clkTotal;
|
||||
Pr_ManFree( p );
|
||||
|
|
|
|||
Loading…
Reference in New Issue