mirror of https://github.com/YosysHQ/abc.git
Upgrading the SAT solvers.
This commit is contained in:
parent
cc840d8bd8
commit
bab4c1ddfc
|
|
@ -88,6 +88,10 @@ LINK32=link.exe
|
||||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\proof\cec\cecSatG2.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\src\base\main\main.c
|
SOURCE=.\src\base\main\main.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
|
|
|
||||||
|
|
@ -2395,6 +2395,14 @@ SOURCE=.\src\sat\glucose2\BoundedQueue.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\sat\glucose2\CGlucose.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\sat\glucose2\CGlucoseCore.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\src\sat\glucose2\Constants.h
|
SOURCE=.\src\sat\glucose2\Constants.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
|
||||||
|
|
@ -36290,7 +36290,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp;
|
Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp;
|
||||||
int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoG2 = 0;
|
int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoG2 = 0;
|
||||||
Cec_ManFraSetDefaultParams( pPars );
|
Cec_ManFraSetDefaultParams( pPars );
|
||||||
pPars->jType = 0; // solver type
|
pPars->jType = 2; // solver type
|
||||||
pPars->fSatSweeping = 1; // conflict limit at a node
|
pPars->fSatSweeping = 1; // conflict limit at a node
|
||||||
pPars->nWords = 8; // simulation words
|
pPars->nWords = 8; // simulation words
|
||||||
pPars->nRounds = 10; // simulation rounds
|
pPars->nRounds = 10; // simulation rounds
|
||||||
|
|
@ -36300,7 +36300,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
pPars->nCallsRecycle = 500; // calls to perform before recycling SAT solver
|
pPars->nCallsRecycle = 500; // calls to perform before recycling SAT solver
|
||||||
pPars->nGenIters = 100; // pattern generation iterations
|
pPars->nGenIters = 100; // pattern generation iterations
|
||||||
Extra_UtilGetoptReset();
|
Extra_UtilGetoptReset();
|
||||||
while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCPrmdckngxwvh" ) ) != EOF )
|
while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxwvh" ) ) != EOF )
|
||||||
{
|
{
|
||||||
switch ( c )
|
switch ( c )
|
||||||
{
|
{
|
||||||
|
|
@ -36381,6 +36381,17 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
if ( pPars->nBTLimit < 0 )
|
if ( pPars->nBTLimit < 0 )
|
||||||
goto usage;
|
goto usage;
|
||||||
break;
|
break;
|
||||||
|
case 'N':
|
||||||
|
if ( globalUtilOptind >= argc )
|
||||||
|
{
|
||||||
|
Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
pPars->nCallsRecycle = atoi(argv[globalUtilOptind]);
|
||||||
|
globalUtilOptind++;
|
||||||
|
if ( pPars->nCallsRecycle < 0 )
|
||||||
|
goto usage;
|
||||||
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
if ( globalUtilOptind >= argc )
|
if ( globalUtilOptind >= argc )
|
||||||
{
|
{
|
||||||
|
|
@ -36443,7 +36454,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
Abc_Print( -2, "usage: &fraig [-JWRILDCP <num>] [-rmdckngwvh]\n" );
|
Abc_Print( -2, "usage: &fraig [-JWRILDCNP <num>] [-rmdckngwvh]\n" );
|
||||||
Abc_Print( -2, "\t performs combinational SAT sweeping\n" );
|
Abc_Print( -2, "\t performs combinational SAT sweeping\n" );
|
||||||
Abc_Print( -2, "\t-J num : the solver type [default = %d]\n", pPars->jType );
|
Abc_Print( -2, "\t-J num : the solver type [default = %d]\n", pPars->jType );
|
||||||
Abc_Print( -2, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords );
|
Abc_Print( -2, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords );
|
||||||
|
|
@ -36452,6 +36463,7 @@ usage:
|
||||||
Abc_Print( -2, "\t-L num : the max number of levels of nodes to consider [default = %d]\n", pPars->nLevelMax );
|
Abc_Print( -2, "\t-L num : the max number of levels of nodes to consider [default = %d]\n", pPars->nLevelMax );
|
||||||
Abc_Print( -2, "\t-D num : the max number of steps of speculative reduction [default = %d]\n", pPars->nDepthMax );
|
Abc_Print( -2, "\t-D num : the max number of steps of speculative reduction [default = %d]\n", pPars->nDepthMax );
|
||||||
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
|
Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit );
|
||||||
|
Abc_Print( -2, "\t-N num : the min number of calls to recycle the solver [default = %d]\n", pPars->nCallsRecycle );
|
||||||
Abc_Print( -2, "\t-P num : the number of pattern generation iterations [default = %d]\n", pPars->nGenIters );
|
Abc_Print( -2, "\t-P num : the number of pattern generation iterations [default = %d]\n", pPars->nGenIters );
|
||||||
Abc_Print( -2, "\t-r : toggle the use of AIG rewriting [default = %s]\n", pPars->fRewriting? "yes": "no" );
|
Abc_Print( -2, "\t-r : toggle the use of AIG rewriting [default = %s]\n", pPars->fRewriting? "yes": "no" );
|
||||||
Abc_Print( -2, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "miter": "circuit" );
|
Abc_Print( -2, "\t-m : toggle miter vs. any circuit [default = %s]\n", pPars->fCheckMiter? "miter": "circuit" );
|
||||||
|
|
|
||||||
|
|
@ -1366,7 +1366,7 @@ int Cec4_ManSweepNode( Cec4_Man_t * p, int iObj, int iRepr )
|
||||||
assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords );
|
assert( p->pAig->iPatsPi > 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords );
|
||||||
//Vec_IntForEachEntryDouble( &p->pNew->vCopiesTwo, IdAig, IdSat, i )
|
//Vec_IntForEachEntryDouble( &p->pNew->vCopiesTwo, IdAig, IdSat, i )
|
||||||
// Cec4_ObjSimSetInputBit( p->pAig, IdAig, sat_solver_read_cex_varvalue(p->pSat, IdSat) );
|
// Cec4_ObjSimSetInputBit( p->pAig, IdAig, sat_solver_read_cex_varvalue(p->pSat, IdSat) );
|
||||||
pCex = sat_solver_read_cex( p->pSat );
|
pCex = NULL;//sat_solver_read_cex( p->pSat );
|
||||||
Vec_IntClear( p->vPat );
|
Vec_IntClear( p->vPat );
|
||||||
if ( pCex == NULL )
|
if ( pCex == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -1461,8 +1461,8 @@ int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** p
|
||||||
Gia_Obj_t * pObj, * pRepr;
|
Gia_Obj_t * pObj, * pRepr;
|
||||||
int i, fSimulate = 1;
|
int i, fSimulate = 1;
|
||||||
if ( pPars->fVerbose )
|
if ( pPars->fVerbose )
|
||||||
printf( "Simulate %d words in %d rounds. Easy SAT with %d tries. SAT with %d confs. Recycle after %d SAT calls.\n",
|
printf( "Solver type = %d. Simulate %d words in %d rounds. SAT with %d confs. Recycle after %d SAT calls.\n",
|
||||||
pPars->nWords, pPars->nRounds, pPars->nGenIters, pPars->nBTLimit, pPars->nCallsRecycle );
|
pPars->jType, pPars->nWords, pPars->nRounds, pPars->nBTLimit, pPars->nCallsRecycle );
|
||||||
|
|
||||||
// this is currently needed to have a correct mapping
|
// this is currently needed to have a correct mapping
|
||||||
Gia_ManForEachCi( p, pObj, i )
|
Gia_ManForEachCi( p, pObj, i )
|
||||||
|
|
@ -1498,7 +1498,7 @@ int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** p
|
||||||
Cec4_ManSimulate( p, pMan );
|
Cec4_ManSimulate( p, pMan );
|
||||||
if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
|
if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
|
||||||
goto finalize;
|
goto finalize;
|
||||||
if ( i % (pPars->nRounds / 5) == 0 && pPars->fVerbose )
|
if ( i && i % (pPars->nRounds / 5) == 0 && pPars->fVerbose )
|
||||||
Cec4_ManPrintStats( p, pPars, pMan, 1 );
|
Cec4_ManPrintStats( p, pPars, pMan, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1510,9 +1510,11 @@ int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** p
|
||||||
Cec4_ManSimulate( p, pMan );
|
Cec4_ManSimulate( p, pMan );
|
||||||
if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
|
if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
|
||||||
goto finalize;
|
goto finalize;
|
||||||
if ( pPars->fVerbose )
|
if ( i && i % 5 == 0 && pPars->fVerbose )
|
||||||
Cec4_ManPrintStats( p, pPars, pMan, 1 );
|
Cec4_ManPrintStats( p, pPars, pMan, 1 );
|
||||||
}
|
}
|
||||||
|
if ( i && i % 5 && pPars->fVerbose )
|
||||||
|
Cec4_ManPrintStats( p, pPars, pMan, 1 );
|
||||||
|
|
||||||
p->iPatsPi = 0;
|
p->iPatsPi = 0;
|
||||||
pMan->nSatSat = 0;
|
pMan->nSatSat = 0;
|
||||||
|
|
|
||||||
|
|
@ -609,7 +609,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
for(i = 0;i<selectors.size();i++)
|
for(i = 0;i<selectors.size();i++)
|
||||||
out_learnt.push(selectors[i]);
|
out_learnt.push(selectors[i]);
|
||||||
|
|
||||||
out_learnt.copyTo(analyze_toclear);
|
out_learnt.copyTo_(analyze_toclear);
|
||||||
if (ccmin_mode == 2){
|
if (ccmin_mode == 2){
|
||||||
uint32_t abstract_level = 0;
|
uint32_t abstract_level = 0;
|
||||||
for (i = 1; i < out_learnt.size(); i++)
|
for (i = 1; i < out_learnt.size(); i++)
|
||||||
|
|
|
||||||
|
|
@ -306,9 +306,15 @@ class OccLists
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(bool free = true){
|
void clear(bool free = true){
|
||||||
occs .clear(free);
|
if(free){
|
||||||
dirty .clear(free);
|
occs .clear(free);
|
||||||
dirties.clear(free);
|
dirty .clear(free);
|
||||||
|
dirties.clear(free);
|
||||||
|
} else {
|
||||||
|
occs .shrink_(occs .size());
|
||||||
|
dirty .shrink_(dirty .size());
|
||||||
|
dirties.shrink_(dirties.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,8 @@ public:
|
||||||
T& operator [] (int index) { return data[index]; }
|
T& operator [] (int index) { return data[index]; }
|
||||||
|
|
||||||
// Duplicatation (preferred instead):
|
// Duplicatation (preferred instead):
|
||||||
void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
|
void copyTo (vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
|
||||||
|
void copyTo_(vec<T>& copy) const { copy.shrink_(copy.size()); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
|
||||||
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
|
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef Glucose_CGlucose_h
|
||||||
|
#define Glucose_CGlucose_h
|
||||||
|
|
||||||
|
#define CGLUCOSE_EXP 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,651 @@
|
||||||
|
// The code in this file was developed by He-Teng Zhang (National Taiwan University)
|
||||||
|
|
||||||
|
#ifndef Glucose_CGlucoseCore_h
|
||||||
|
#define Glucose_CGlucoseCore_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
* justification for glucose
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sat/glucose2/Options.h"
|
||||||
|
#include "sat/glucose2/Solver.h"
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
namespace Gluco2 {
|
||||||
|
|
||||||
|
inline int Solver::justUsage() const {
|
||||||
|
return jftr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Lit Solver::maxActiveLit(Lit lit0, Lit lit1) const {
|
||||||
|
return activity[var(lit0)] < activity[var(lit1)]? lit1: lit0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Lit Solver::faninNJustLit(Var v, int idx) const {
|
||||||
|
// assert(isTwoFanin(v));
|
||||||
|
// assert(value(v) == l_False); // l_True should be handled by propagation
|
||||||
|
// return ~ (0 == idx? getFaninLit0(v): );
|
||||||
|
//}
|
||||||
|
|
||||||
|
// select one of fanins to justify
|
||||||
|
inline Lit Solver::fanin2JustLit(Var v) const {
|
||||||
|
assert(v < nVars());
|
||||||
|
Lit lit0, lit1;
|
||||||
|
lit0 = ~getFaninLit0(v);
|
||||||
|
lit1 = ~getFaninLit1(v);
|
||||||
|
// if( (sign(lit0) != polarity[var(lit0)]) ^ (sign(lit1) != polarity[var(lit1)]) )
|
||||||
|
// return sign(lit0) == polarity[var(lit0)]? lit0: lit1;
|
||||||
|
return maxActiveLit(lit0, lit1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Lit Solver::gateJustFanin(Var v) const {
|
||||||
|
assert(v < nVars());
|
||||||
|
assert(isTwoFanin(v));
|
||||||
|
assert(value(v) == l_False); // l_True should be handled by propagation
|
||||||
|
|
||||||
|
lbool val0, val1;
|
||||||
|
val0 = value(getFaninVar0(v));
|
||||||
|
val1 = value(getFaninVar1(v));
|
||||||
|
|
||||||
|
// phased values
|
||||||
|
if(l_Undef != val0) val0 = val0 ^ getFaninC0(v);
|
||||||
|
if(l_Undef != val1) val1 = val1 ^ getFaninC1(v);
|
||||||
|
|
||||||
|
// should be handled by conflict analysis before entering here
|
||||||
|
assert(value(v) != l_False || l_True != val0 || l_True != val1);
|
||||||
|
|
||||||
|
if(val0 == l_False || val1 == l_False)
|
||||||
|
return lit_Undef;
|
||||||
|
|
||||||
|
// branch
|
||||||
|
if(val0 == l_True)
|
||||||
|
return ~getFaninLit1(v);
|
||||||
|
if(val1 == l_True)
|
||||||
|
return ~getFaninLit0(v);
|
||||||
|
|
||||||
|
// both fanins are eligible
|
||||||
|
//return maxActiveLit(faninNJustLit(v, 0), faninNJustLit(v, 1));
|
||||||
|
return fanin2JustLit(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// a var should at most be enqueued one time
|
||||||
|
inline void Solver::pushJustQueue(Var v){
|
||||||
|
assert(v < nVars());
|
||||||
|
assert(value(v) == l_False); // l_True should be handled by propagation
|
||||||
|
assert(isTwoFanin(v));
|
||||||
|
|
||||||
|
if( ! isRoundWatch(v) )\
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
jdata[v].act_fanin = activity[getFaninVar0(v)] > activity[getFaninVar1(v)]? activity[getFaninVar0(v)]: activity[getFaninVar1(v)];
|
||||||
|
jdata[v].now = true;
|
||||||
|
|
||||||
|
jheap.update(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Solver::ResetJustData(bool fCleanMemory){
|
||||||
|
jstack.shrink_( jstack.size() );
|
||||||
|
jheap .clear(fCleanMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Lit Solver::pickJustLit( Var& j_reason ){
|
||||||
|
Var next = var_Undef;
|
||||||
|
Lit jlit = lit_Undef;
|
||||||
|
//double clk = Abc_Clock();
|
||||||
|
for( int i = 0; i < jstack.size(); i ++ ){
|
||||||
|
Var x = jstack[i];
|
||||||
|
if( l_Undef != value(getFaninLit0(x)) || l_Undef != value(getFaninLit1(x)) )
|
||||||
|
continue;
|
||||||
|
pushJustQueue(x);
|
||||||
|
}
|
||||||
|
jstack.shrink_( jstack.size() );
|
||||||
|
while( ! jheap.empty() && var_Undef != (next = jheap.removeMin()) ){
|
||||||
|
if( ! jdata[next].now )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
assert( l_False == value(next) );
|
||||||
|
if( lit_Undef != (jlit = gateJustFanin(next)) )
|
||||||
|
break;
|
||||||
|
gateAddJwatch(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
j_reason = next;
|
||||||
|
return jlit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Solver::gateAddJwatch(Var v){
|
||||||
|
assert(v < nVars());
|
||||||
|
assert(isTwoFanin(v));
|
||||||
|
assert(value(v) == l_False); // l_True should be handled by propagation
|
||||||
|
|
||||||
|
if( var_Undef != jwatch[v].prev ) // already in jwatch
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert( var_Undef == jwatch[v].prev );
|
||||||
|
|
||||||
|
lbool val0, val1;
|
||||||
|
Var var0, var1;
|
||||||
|
var0 = getFaninVar0(v);
|
||||||
|
var1 = getFaninVar1(v);
|
||||||
|
val0 = value(var0);
|
||||||
|
val1 = value(var1);
|
||||||
|
|
||||||
|
// phased values
|
||||||
|
if(l_Undef != val0) val0 = val0 ^ getFaninC0(v);
|
||||||
|
if(l_Undef != val1) val1 = val1 ^ getFaninC1(v);
|
||||||
|
|
||||||
|
assert( l_False == val0 || l_False == val1 );
|
||||||
|
|
||||||
|
if(val0 == l_False && val1 == l_False){
|
||||||
|
addJwatch(vardata[var0].level < vardata[var1].level? var0: var1, v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addJwatch(l_False == val0? var0: var1, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Solver::gateClearJwatch( Var v, int backtrack_level ){
|
||||||
|
if( var_Undef == jwatch[v].head )
|
||||||
|
return ;
|
||||||
|
|
||||||
|
Var member, next;
|
||||||
|
member = jwatch[v].head;
|
||||||
|
while( var_Undef != member ){
|
||||||
|
next = jwatch[member].next;
|
||||||
|
|
||||||
|
delJwatch( member );
|
||||||
|
|
||||||
|
if( vardata[member].level <= backtrack_level )
|
||||||
|
pushJustQueue(member);
|
||||||
|
|
||||||
|
member = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Solver::updateJustActivity( Var v ){
|
||||||
|
for(Lit lfo = var2Fanout0[ v ]; lfo != toLit(~0); lfo = var2FanoutN[ toInt(lfo) ] ){
|
||||||
|
Var x = var(lfo);
|
||||||
|
if( jdata[x].now && jheap.inHeap(x) ){
|
||||||
|
jdata[x].act_fanin = activity[getFaninVar0(x)] > activity[getFaninVar1(x)]? activity[getFaninVar0(x)]: activity[getFaninVar1(x)];
|
||||||
|
jheap.update(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Solver::addJwatch( Var host, Var member ){
|
||||||
|
assert( var_Undef == jwatch[member].next && var_Undef == jwatch[member].prev );
|
||||||
|
|
||||||
|
if( var_Undef != jwatch[host].head )
|
||||||
|
jwatch[jwatch[host].head].prev = member;
|
||||||
|
|
||||||
|
jwatch[member].next = jwatch[host].head;
|
||||||
|
jwatch[member].prev = host;
|
||||||
|
jwatch[host].head = member;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Solver::delJwatch( Var member ){
|
||||||
|
Var prev = jwatch[member].prev;
|
||||||
|
Var next = jwatch[member].next;
|
||||||
|
|
||||||
|
assert( var_Undef != prev ); // must be in a list to be deleted
|
||||||
|
assert( jwatch[prev].next == member || jwatch[prev].head == member );
|
||||||
|
|
||||||
|
if( jwatch[prev].next == member )
|
||||||
|
jwatch[prev].next = next;
|
||||||
|
else
|
||||||
|
jwatch[prev].head = next;
|
||||||
|
|
||||||
|
if( var_Undef != next )
|
||||||
|
jwatch[next].prev = prev;
|
||||||
|
|
||||||
|
jwatch[member].prev = var_Undef;
|
||||||
|
jwatch[member].next = var_Undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* circuit propagation
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline void Solver::justCheck(){
|
||||||
|
Lit lit;
|
||||||
|
//for(int i=0; i<JustQueue.size(); i++)
|
||||||
|
// if(lit_Undef!= (lit = gateJustFanin(JustQueue[i])))
|
||||||
|
// printf("%d is not justified\n", JustQueue[i]);
|
||||||
|
int i, nJustFail = 0;
|
||||||
|
for(i=0; i<trail.size(); i++){
|
||||||
|
Var x = var(trail[i]);
|
||||||
|
if( ! isTwoFanin(x) )
|
||||||
|
continue;
|
||||||
|
if( ! isRoundWatch(x) )
|
||||||
|
continue;
|
||||||
|
if( l_False != value(x) )
|
||||||
|
continue;
|
||||||
|
if( lit_Undef != (lit = gateJustFanin(x)) ){
|
||||||
|
printf("\t%8d is not justified (value=%d, level=%3d)\n", x, l_True == value(x)? 1: 0, vardata[x].level), nJustFail ++ ;
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( nJustFail )
|
||||||
|
printf("%d just-fails\n", nJustFail);
|
||||||
|
|
||||||
|
JustModel.clear(false);
|
||||||
|
JustModel.growTo(nVars(), lit_Undef);
|
||||||
|
|
||||||
|
for (i = 0; i < nVars(); i++){
|
||||||
|
if( l_Undef == value(i) )
|
||||||
|
continue;
|
||||||
|
JustModel[i] = mkLit( i, l_False == value(i) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
inline void Solver::delVarFaninLits( Var v ){
|
||||||
|
if( toLit(~0) != getFaninLit0(v) ){
|
||||||
|
if( toLit(~0) == var2FanoutP[ (v<<1) + 0 ] ){
|
||||||
|
// head of linked-list
|
||||||
|
Lit root = mkLit(getFaninVar0(v));
|
||||||
|
Lit next = var2FanoutN[ (v<<1) + 0 ];
|
||||||
|
if( toLit(~0) != next ){
|
||||||
|
assert( var2Fanout0[ toInt(root) ] == toLit((v<<1) + 0) );
|
||||||
|
assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 0) );
|
||||||
|
var2Fanout0[ getFaninVar0(v) ] = next;
|
||||||
|
var2FanoutP[ toInt(next) ] = toLit(~0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Lit prev = var2FanoutP[ (v<<1) + 0 ];
|
||||||
|
Lit next = var2FanoutN[ (v<<1) + 0 ];
|
||||||
|
if( toLit(~0) != next ){
|
||||||
|
assert( var2FanoutN[ toInt(prev) ] == toLit((v<<1) + 0) );
|
||||||
|
assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 0) );
|
||||||
|
var2FanoutN[ toInt(prev) ] = next;
|
||||||
|
var2FanoutP[ toInt(next) ] = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( toLit(~0) != getFaninLit1(v) ){
|
||||||
|
if( toLit(~0) == var2FanoutP[ (v<<1) + 1 ] ){
|
||||||
|
// head of linked-list
|
||||||
|
Lit root = mkLit(getFaninVar1(v));
|
||||||
|
Lit next = var2FanoutN[ (v<<1) + 1 ];
|
||||||
|
if( toLit(~0) != next ){
|
||||||
|
assert( var2Fanout0[ toInt(root) ] == toLit((v<<1) + 1) );
|
||||||
|
assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 1) );
|
||||||
|
var2Fanout0[ getFaninVar1(v) ] = next;
|
||||||
|
var2FanoutP[ toInt(next) ] = toLit(~0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Lit prev = var2FanoutP[ (v<<1) + 1 ];
|
||||||
|
Lit next = var2FanoutN[ (v<<1) + 1 ];
|
||||||
|
if( toLit(~0) != next ){
|
||||||
|
assert( var2FanoutN[ toInt(prev) ] == toLit((v<<1) + 1) );
|
||||||
|
assert( var2FanoutP[ toInt(next) ] == toLit((v<<1) + 1) );
|
||||||
|
var2FanoutN[ toInt(prev) ] = next;
|
||||||
|
var2FanoutP[ toInt(next) ] = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var2FanoutP [ (v<<1) + 0 ] = toLit(~0);
|
||||||
|
var2FanoutP [ (v<<1) + 1 ] = toLit(~0);
|
||||||
|
var2FanoutN [ (v<<1) + 0 ] = toLit(~0);
|
||||||
|
var2FanoutN [ (v<<1) + 1 ] = toLit(~0);
|
||||||
|
var2FaninLits[ (v<<1) + 0 ] = toLit(~0);
|
||||||
|
var2FaninLits[ (v<<1) + 1 ] = toLit(~0);
|
||||||
|
}
|
||||||
|
**/
|
||||||
|
inline void Solver::setVarFaninLits( Var v, Lit lit1, Lit lit2 ){
|
||||||
|
int mincap = var(lit1) < var(lit2)? var(lit2): var(lit1);
|
||||||
|
mincap = (v < mincap? mincap: v) + 1;
|
||||||
|
|
||||||
|
if( var2FaninLits.size() < (mincap<<1) )
|
||||||
|
var2FaninLits.growTo( (mincap<<1), toLit(~0));
|
||||||
|
assert( (toLit(~0) == lit1 && toLit(~0) == lit2) || ((v<<1)+1 < var2FaninLits.size()) );
|
||||||
|
var2FaninLits[ (v<<1) + 0 ] = lit1;
|
||||||
|
var2FaninLits[ (v<<1) + 1 ] = lit2;
|
||||||
|
|
||||||
|
|
||||||
|
assert( toLit(~0) != lit1 && toLit(~0) != lit2 );
|
||||||
|
|
||||||
|
|
||||||
|
if( var2FanoutN.size() < (mincap<<1) )
|
||||||
|
var2FanoutN.growTo( (mincap<<1), toLit(~0));
|
||||||
|
//if( var2FanoutP.size() < (mincap<<1) )
|
||||||
|
// var2FanoutP.growTo( (mincap<<1), toLit(~0));
|
||||||
|
if( var2Fanout0.size() < mincap )
|
||||||
|
var2Fanout0.growTo( mincap, toLit(~0));
|
||||||
|
|
||||||
|
var2FanoutN[ (v<<1) + 0 ] = var2Fanout0[ var(lit1) ];
|
||||||
|
var2FanoutN[ (v<<1) + 1 ] = var2Fanout0[ var(lit2) ];
|
||||||
|
var2Fanout0[ var(lit1) ] = toLit( (v<<1) + 0 );
|
||||||
|
var2Fanout0[ var(lit2) ] = toLit( (v<<1) + 1 );
|
||||||
|
|
||||||
|
//if( toLit(~0) != var2FanoutN[ (v<<1) + 0 ] )
|
||||||
|
// var2FanoutP[ toInt(var2FanoutN[ (v<<1) + 0 ]) ] = toLit((v<<1) + 0);
|
||||||
|
|
||||||
|
//if( toLit(~0) != var2FanoutN[ (v<<1) + 1 ] )
|
||||||
|
// var2FanoutP[ toInt(var2FanoutN[ (v<<1) + 1 ]) ] = toLit((v<<1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Solver::isTwoFanin( Var v ) const {
|
||||||
|
assert(v < nVars());
|
||||||
|
if( var2FaninLits.size() <= (v<<1)+1 )
|
||||||
|
return false;
|
||||||
|
Lit lit0 = var2FaninLits[ (v<<1) + 0 ];
|
||||||
|
Lit lit1 = var2FaninLits[ (v<<1) + 1 ];
|
||||||
|
assert( toLit(~0) == lit0 || var(lit0) < nVars() );
|
||||||
|
assert( toLit(~0) == lit1 || var(lit1) < nVars() );
|
||||||
|
return toLit(~0) != var2FaninLits[ (v<<1) + 0 ] && toLit(~0) != var2FaninLits[ (v<<1) + 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// this implementation return the last conflict encountered
|
||||||
|
// which follows minisat concept
|
||||||
|
inline CRef Solver::gatePropagate( Lit p ){
|
||||||
|
CRef confl = CRef_Undef, stats;
|
||||||
|
if( justUsage() < 2 || var2FaninLits.size() <= var(p) )
|
||||||
|
return CRef_Undef;
|
||||||
|
|
||||||
|
if( ! isRoundWatch(var(p)) )
|
||||||
|
return CRef_Undef;
|
||||||
|
|
||||||
|
if( ! isTwoFanin( var(p) ) )
|
||||||
|
goto check_fanout;
|
||||||
|
|
||||||
|
|
||||||
|
// check fanin consistency
|
||||||
|
if( CRef_Undef != (stats = gatePropagateCheckThis( var(p) )) ){
|
||||||
|
confl = stats;
|
||||||
|
if( l_True == value(var(p)) )
|
||||||
|
return confl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check fanout consistency
|
||||||
|
check_fanout:
|
||||||
|
assert( var(p) < var2Fanout0.size() );
|
||||||
|
|
||||||
|
for( Lit lfo = var2Fanout0[ var(p) ]; lfo != toLit(~0); lfo = var2FanoutN[ toInt(lfo) ] )
|
||||||
|
{
|
||||||
|
if( ! isRoundWatch(var(lfo)) ) continue;
|
||||||
|
|
||||||
|
if( CRef_Undef != (stats = gatePropagateCheckFanout( var(p), lfo )) ){
|
||||||
|
confl = stats;
|
||||||
|
if( l_True == value(var(lfo)) )
|
||||||
|
return confl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return confl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CRef Solver::gatePropagateCheckFanout( Var v, Lit lfo ){
|
||||||
|
Lit faninLit = sign(lfo)? getFaninLit1(var(lfo)): getFaninLit0(var(lfo));
|
||||||
|
assert( var(faninLit) == v );
|
||||||
|
|
||||||
|
if( l_False == value(faninLit) )
|
||||||
|
{
|
||||||
|
if( l_False == value(var(lfo)) )
|
||||||
|
return CRef_Undef;
|
||||||
|
|
||||||
|
if( l_True == value(var(lfo)) )
|
||||||
|
return Var2CRef(var(lfo));
|
||||||
|
|
||||||
|
jwatch[var(lfo)].header.dir = sign(lfo);
|
||||||
|
uncheckedEnqueue(~mkLit(var(lfo)), Var2CRef( var(lfo) ) );
|
||||||
|
} else {
|
||||||
|
assert( l_True == value(faninLit) );
|
||||||
|
|
||||||
|
if( l_True == value(var(lfo)) )
|
||||||
|
return CRef_Undef;
|
||||||
|
|
||||||
|
// check value of the other fanin
|
||||||
|
Lit faninLitP = sign(lfo)? getFaninLit0(var(lfo)): getFaninLit1(var(lfo));
|
||||||
|
if( l_False == value(var(lfo)) ){
|
||||||
|
|
||||||
|
if( l_False == value(faninLitP) )
|
||||||
|
return CRef_Undef;
|
||||||
|
|
||||||
|
if( l_True == value(faninLitP) )
|
||||||
|
return Var2CRef(var(lfo));
|
||||||
|
|
||||||
|
uncheckedEnqueue( ~faninLitP, Var2CRef( var(lfo) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( l_True == value(faninLitP) )
|
||||||
|
uncheckedEnqueue( mkLit(var(lfo)), Var2CRef( var(lfo) ) );
|
||||||
|
}
|
||||||
|
return CRef_Undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CRef Solver::gatePropagateCheckThis( Var v ){
|
||||||
|
CRef confl = CRef_Undef;
|
||||||
|
if( l_False == value(v) ){
|
||||||
|
if( l_True == value(getFaninLit0(v)) && l_True == value(getFaninLit1(v)) )
|
||||||
|
return Var2CRef(v);
|
||||||
|
|
||||||
|
if( l_False == value(getFaninLit0(v)) || l_False == value(getFaninLit1(v)) )
|
||||||
|
return CRef_Undef;
|
||||||
|
|
||||||
|
if( l_True == value(getFaninLit0(v)) )
|
||||||
|
uncheckedEnqueue(~getFaninLit1( v ), Var2CRef( v ) );
|
||||||
|
if( l_True == value(getFaninLit1(v)) )
|
||||||
|
uncheckedEnqueue(~getFaninLit0( v ), Var2CRef( v ) );
|
||||||
|
} else {
|
||||||
|
assert( l_True == value(v) );
|
||||||
|
if( l_False == value(getFaninLit0(v)) || l_False == value(getFaninLit1(v)) )
|
||||||
|
confl = Var2CRef(v);
|
||||||
|
|
||||||
|
if( l_Undef == value( getFaninLit0( v )) )
|
||||||
|
uncheckedEnqueue( getFaninLit0( v ), Var2CRef( v ) );
|
||||||
|
|
||||||
|
if( l_Undef == value( getFaninLit1( v )) )
|
||||||
|
uncheckedEnqueue( getFaninLit1( v ), Var2CRef( v ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return confl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CRef Solver::getConfClause( CRef r ){
|
||||||
|
if( !isGateCRef(r) )
|
||||||
|
return r;
|
||||||
|
Var v = CRef2Var(r);
|
||||||
|
assert( isTwoFanin(v) );
|
||||||
|
|
||||||
|
if( l_False == value(v) ){
|
||||||
|
setItpcSize(3);
|
||||||
|
Clause& c = ca[itpc];
|
||||||
|
c[0] = mkLit(v);
|
||||||
|
c[1] = ~getFaninLit0( v );
|
||||||
|
c[2] = ~getFaninLit1( v );
|
||||||
|
} else {
|
||||||
|
setItpcSize(2);
|
||||||
|
Clause& c = ca[itpc];
|
||||||
|
c[0] = ~mkLit(v);
|
||||||
|
|
||||||
|
lbool val0 = value(getFaninLit0(v));
|
||||||
|
lbool val1 = value(getFaninLit1(v));
|
||||||
|
|
||||||
|
if( l_False == val0 && l_False == val1 )
|
||||||
|
c[1] = level(getFaninVar0(v)) < level(getFaninVar1(v))? getFaninLit0( v ): getFaninLit1( v );
|
||||||
|
else
|
||||||
|
if( l_False == val0 )
|
||||||
|
c[1] = getFaninLit0( v );
|
||||||
|
else
|
||||||
|
c[1] = getFaninLit1( v );
|
||||||
|
}
|
||||||
|
|
||||||
|
return itpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CRef Solver::gatePropagateCheck( Var v, Var t )
|
||||||
|
{ // check fanin consistency
|
||||||
|
assert( isTwoFanin(v) );
|
||||||
|
CRef confl = CRef_Undef;
|
||||||
|
lbool val0, val1, valo;
|
||||||
|
Var var0, var1;
|
||||||
|
var0 = getFaninVar0( v );
|
||||||
|
var1 = getFaninVar1( v );
|
||||||
|
val0 = value( var0 );
|
||||||
|
val1 = value( var1 );
|
||||||
|
valo = value( v );
|
||||||
|
|
||||||
|
// phased values
|
||||||
|
if(l_Undef != val0) val0 = val0 ^ getFaninC0( v );
|
||||||
|
if(l_Undef != val1) val1 = val1 ^ getFaninC1( v );
|
||||||
|
|
||||||
|
|
||||||
|
if( l_True == valo ){
|
||||||
|
|
||||||
|
|
||||||
|
if( l_False == val0 || l_False == val1 )
|
||||||
|
{ // conflict
|
||||||
|
return Var2CRef(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// propagate 1
|
||||||
|
if( l_Undef == val0 )
|
||||||
|
uncheckedEnqueue( getFaninLit0( v ), Var2CRef( v ) );
|
||||||
|
if( l_Undef == val1 )
|
||||||
|
uncheckedEnqueue( getFaninLit1( v ), Var2CRef( v ) );
|
||||||
|
|
||||||
|
} else
|
||||||
|
if( l_False == valo ){
|
||||||
|
|
||||||
|
if( l_True == val0 && l_True == val1 )
|
||||||
|
{ // conflict
|
||||||
|
confl = Var2CRef(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// propagate 0
|
||||||
|
if( l_True == val0 && l_Undef == val1 )
|
||||||
|
uncheckedEnqueue( ~getFaninLit1( v ), Var2CRef( v ) );
|
||||||
|
else
|
||||||
|
if( l_True == val1 && l_Undef == val0 )
|
||||||
|
uncheckedEnqueue( ~getFaninLit0( v ), Var2CRef( v ) );
|
||||||
|
|
||||||
|
} else
|
||||||
|
if( l_Undef == valo ){
|
||||||
|
|
||||||
|
if( l_True == val0 && l_True == val1 ){
|
||||||
|
jwatch[v].header.dir = t == var1;
|
||||||
|
uncheckedEnqueue( mkLit(v), Var2CRef( v ) );
|
||||||
|
} else
|
||||||
|
if( t == var0 && l_False == val0 ){
|
||||||
|
jwatch[v].header.dir = 0;
|
||||||
|
uncheckedEnqueue( ~mkLit(v), Var2CRef( v ) );
|
||||||
|
} else
|
||||||
|
if( t == var1 && l_False == val1 ){
|
||||||
|
jwatch[v].header.dir = 1;
|
||||||
|
uncheckedEnqueue( ~mkLit(v), Var2CRef( v ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return confl;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Solver::setItpcSize( int sz ){
|
||||||
|
assert( 3 >= sz );
|
||||||
|
assert( CRef_Undef != itpc );
|
||||||
|
ca[itpc].header.size = sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CRef Solver::interpret( Var v, Var t )
|
||||||
|
{ // get gate-clause on implication graph
|
||||||
|
assert( isTwoFanin(v) );
|
||||||
|
|
||||||
|
lbool val0, val1, valo;
|
||||||
|
Var var0, var1;
|
||||||
|
var0 = getFaninVar0( v );
|
||||||
|
var1 = getFaninVar1( v );
|
||||||
|
val0 = value(var0);
|
||||||
|
val1 = value(var1);
|
||||||
|
valo = value( v );
|
||||||
|
|
||||||
|
// phased values
|
||||||
|
if(l_Undef != val0) val0 = val0 ^ getFaninC0( v );
|
||||||
|
if(l_Undef != val1) val1 = val1 ^ getFaninC1( v );
|
||||||
|
|
||||||
|
|
||||||
|
if( v == t ){
|
||||||
|
// tracing output
|
||||||
|
if( l_False == valo ){
|
||||||
|
setItpcSize(2);
|
||||||
|
Clause& c = ca[itpc];
|
||||||
|
c[0] = ~mkLit(v);
|
||||||
|
|
||||||
|
if( l_False == val0 && l_False == val1 )
|
||||||
|
c[1] = 0 == jwatch[v].header.dir ? getFaninLit0( v ): getFaninLit1( v );
|
||||||
|
else
|
||||||
|
if( l_False == val0 )
|
||||||
|
c[1] = getFaninLit0( v );
|
||||||
|
else
|
||||||
|
c[1] = getFaninLit1( v );
|
||||||
|
} else {
|
||||||
|
setItpcSize(3);
|
||||||
|
Clause& c = ca[itpc];
|
||||||
|
c[0] = mkLit(v);
|
||||||
|
c[1] = ~getFaninLit0( v );
|
||||||
|
c[2] = ~getFaninLit1( v );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert( t == var0 || t == var1 );
|
||||||
|
if( l_False == valo ){
|
||||||
|
setItpcSize(3);
|
||||||
|
Clause& c = ca[itpc];
|
||||||
|
c[0] = ~getFaninLit0( v );
|
||||||
|
c[1] = ~getFaninLit1( v );
|
||||||
|
c[2] = mkLit(v);
|
||||||
|
if( t == var1 )
|
||||||
|
//std::swap(c[0],c[1]);
|
||||||
|
c[1].x ^= c[0].x, c[0].x ^= c[1].x, c[1].x ^= c[0].x;
|
||||||
|
} else {
|
||||||
|
setItpcSize(2);
|
||||||
|
Clause& c = ca[itpc];
|
||||||
|
c[0] = t == var0? getFaninLit0( v ): getFaninLit1( v );
|
||||||
|
c[1] = ~mkLit(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CRef Solver::castCRef( Lit p ){
|
||||||
|
CRef cr = reason( var(p) );
|
||||||
|
if( CRef_Undef == cr )
|
||||||
|
return cr;
|
||||||
|
if( ! isGateCRef(cr) )
|
||||||
|
return cr;
|
||||||
|
Var v = CRef2Var(cr);
|
||||||
|
return interpret(v,var(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Solver::markCone( Var v ){
|
||||||
|
if( var2TravId[v] >= travId )
|
||||||
|
return;
|
||||||
|
var2TravId[v] = travId;
|
||||||
|
|
||||||
|
if( !isTwoFanin(v) )
|
||||||
|
return;
|
||||||
|
markCone( getFaninVar0(v) );
|
||||||
|
markCone( getFaninVar1(v) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -26,13 +26,14 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FO
|
||||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
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.
|
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
**************************************************************************************************/
|
**************************************************************************************************/
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "sat/glucose2/Sort.h"
|
#include "sat/glucose2/Sort.h"
|
||||||
#include "sat/glucose2/Solver.h"
|
|
||||||
#include "sat/glucose2/Constants.h"
|
#include "sat/glucose2/Constants.h"
|
||||||
#include "sat/glucose2/System.h"
|
#include "sat/glucose2/System.h"
|
||||||
|
#include "sat/glucose2/Solver.h"
|
||||||
|
|
||||||
|
#include "sat/glucose2/CGlucose.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_START
|
ABC_NAMESPACE_IMPL_START
|
||||||
|
|
||||||
|
|
@ -40,7 +41,7 @@ using namespace Gluco2;
|
||||||
|
|
||||||
//=================================================================================================
|
//=================================================================================================
|
||||||
// Options:
|
// Options:
|
||||||
|
namespace Gluco2 {
|
||||||
static const char* _cat = "CORE";
|
static const char* _cat = "CORE";
|
||||||
static const char* _cr = "CORE -- RESTART";
|
static const char* _cr = "CORE -- RESTART";
|
||||||
static const char* _cred = "CORE -- REDUCE";
|
static const char* _cred = "CORE -- REDUCE";
|
||||||
|
|
@ -79,9 +80,9 @@ static DoubleOption opt_restart_inc (_cat, "rinc", "Restart interv
|
||||||
static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false));
|
static DoubleOption opt_garbage_frac (_cat, "gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered", 0.20, DoubleRange(0, false, HUGE_VAL, false));
|
||||||
|
|
||||||
|
|
||||||
BoolOption opt2_certified_ (_certified, "certified", "Certified UNSAT using DRUP format", false );
|
BoolOption opt_certified_ (_certified, "certified", "Certified UNSAT using DRUP format", false );
|
||||||
StringOption opt2_certified_file_ (_certified, "certified-output", "Certified UNSAT output file", "NULL");
|
StringOption opt_certified_file_ (_certified, "certified-output", "Certified UNSAT output file", "NULL");
|
||||||
|
};
|
||||||
|
|
||||||
//=================================================================================================
|
//=================================================================================================
|
||||||
// Constructor/Destructor:
|
// Constructor/Destructor:
|
||||||
|
|
@ -121,7 +122,7 @@ Solver::Solver() :
|
||||||
, rnd_init_act (opt_rnd_init_act)
|
, rnd_init_act (opt_rnd_init_act)
|
||||||
, garbage_frac (opt_garbage_frac)
|
, garbage_frac (opt_garbage_frac)
|
||||||
, certifiedOutput (NULL)
|
, certifiedOutput (NULL)
|
||||||
, certifiedUNSAT (opt2_certified_)
|
, certifiedUNSAT (opt_certified_)
|
||||||
// Statistics: (formerly in 'SolverStats')
|
// Statistics: (formerly in 'SolverStats')
|
||||||
//
|
//
|
||||||
, nbRemovedClauses(0),nbReducedClauses(0), nbDL2(0),nbBin(0),nbUn(0) , nbReduceDB(0)
|
, nbRemovedClauses(0),nbReducedClauses(0), nbDL2(0),nbBin(0),nbUn(0) , nbReduceDB(0)
|
||||||
|
|
@ -148,8 +149,13 @@ Solver::Solver() :
|
||||||
, asynch_interrupt (false)
|
, asynch_interrupt (false)
|
||||||
, incremental(opt_incremental)
|
, incremental(opt_incremental)
|
||||||
, nbVarsInitialFormula(INT32_MAX)
|
, nbVarsInitialFormula(INT32_MAX)
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
, jheap (JustOrderLt(this))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
MYFLAG=0;
|
MYFLAG=0;
|
||||||
|
|
||||||
// Initialize only first time. Useful for incremental solving, useless otherwise
|
// Initialize only first time. Useful for incremental solving, useless otherwise
|
||||||
lbdQueue.initSize(sizeLBDQueue);
|
lbdQueue.initSize(sizeLBDQueue);
|
||||||
trailQueue.initSize(sizeTrailQueue);
|
trailQueue.initSize(sizeTrailQueue);
|
||||||
|
|
@ -160,13 +166,24 @@ Solver::Solver() :
|
||||||
|
|
||||||
|
|
||||||
if(certifiedUNSAT) {
|
if(certifiedUNSAT) {
|
||||||
if(!strcmp(opt2_certified_file_,"NULL")) {
|
if(!strcmp(opt_certified_file_,"NULL")) {
|
||||||
certifiedOutput = fopen("/dev/stdout", "wb");
|
certifiedOutput = fopen("/dev/stdout", "wb");
|
||||||
} else {
|
} else {
|
||||||
certifiedOutput = fopen(opt2_certified_file_, "wb");
|
certifiedOutput = fopen(opt_certified_file_, "wb");
|
||||||
}
|
}
|
||||||
// fprintf(certifiedOutput,"o proof DRUP\n");
|
// fprintf(certifiedOutput,"o proof DRUP\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
travId = 0;
|
||||||
|
travId_prev = 0;
|
||||||
|
|
||||||
|
// allocate space for clause interpretation
|
||||||
|
vec<Lit> tmp; tmp.growTo(3);
|
||||||
|
itpc = ca.alloc(tmp);
|
||||||
|
ca[itpc].shrink( ca[itpc].size() );
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -216,6 +233,19 @@ Var Solver::newVar(bool sign, bool dvar)
|
||||||
decision .push();
|
decision .push();
|
||||||
trail .capacity(v+1);
|
trail .capacity(v+1);
|
||||||
setDecisionVar(v, dvar);
|
setDecisionVar(v, dvar);
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
//jreason .capacity(v+1);
|
||||||
|
if( justUsage() ){
|
||||||
|
jdata .push(mkJustData(false));
|
||||||
|
jwatch .push(mkJustWatch());
|
||||||
|
var2FanoutN.growTo( nVars()<<1, toLit(~0));
|
||||||
|
//var2FanoutP.growTo( nVars()<<1, toLit(~0));
|
||||||
|
var2Fanout0.growTo( nVars(), toLit(~0));
|
||||||
|
var2TravId .growTo( nVars(), 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,7 +490,7 @@ void Solver::minimisationWithBinaryResolution(vec<Lit> &out_learnt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out_learnt.shrink(nb);
|
out_learnt.shrink_(nb);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -470,6 +500,7 @@ void Solver::minimisationWithBinaryResolution(vec<Lit> &out_learnt) {
|
||||||
//
|
//
|
||||||
void Solver::cancelUntil(int level) {
|
void Solver::cancelUntil(int level) {
|
||||||
if (decisionLevel() > level){
|
if (decisionLevel() > level){
|
||||||
|
|
||||||
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
|
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
|
||||||
Var x = var(trail[c]);
|
Var x = var(trail[c]);
|
||||||
assigns [x] = l_Undef;
|
assigns [x] = l_Undef;
|
||||||
|
|
@ -477,8 +508,24 @@ void Solver::cancelUntil(int level) {
|
||||||
polarity[x] = sign(trail[c]);
|
polarity[x] = sign(trail[c]);
|
||||||
insertVarOrder(x); }
|
insertVarOrder(x); }
|
||||||
qhead = trail_lim[level];
|
qhead = trail_lim[level];
|
||||||
trail.shrink(trail.size() - trail_lim[level]);
|
|
||||||
trail_lim.shrink(trail_lim.size() - level);
|
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
if( 0 < justUsage() ){
|
||||||
|
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
|
||||||
|
Var x = var(trail[c]);
|
||||||
|
|
||||||
|
gateClearJwatch(x, level);
|
||||||
|
|
||||||
|
jdata[x].now = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
trail.shrink_(trail.size() - trail_lim[level]);
|
||||||
|
trail_lim.shrink_(trail_lim.size() - level);
|
||||||
|
jstack.shrink_( jstack.size() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -528,6 +575,8 @@ Lit Solver::pickBranchLit()
|
||||||
|________________________________________________________________________________________________@*/
|
|________________________________________________________________________________________________@*/
|
||||||
void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& out_btlevel,unsigned int &lbd,unsigned int &szWithoutSelectors)
|
void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& out_btlevel,unsigned int &lbd,unsigned int &szWithoutSelectors)
|
||||||
{
|
{
|
||||||
|
//double clk = Abc_Clock();
|
||||||
|
|
||||||
int pathC = 0;
|
int pathC = 0;
|
||||||
Lit p = lit_Undef;
|
Lit p = lit_Undef;
|
||||||
|
|
||||||
|
|
@ -538,7 +587,12 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
|
|
||||||
do{
|
do{
|
||||||
assert(confl != CRef_Undef); // (otherwise should be UIP)
|
assert(confl != CRef_Undef); // (otherwise should be UIP)
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
Clause& c = ca[ lit_Undef != p ? castCRef(p): getConfClause(confl) ];
|
||||||
|
#else
|
||||||
Clause& c = ca[confl];
|
Clause& c = ca[confl];
|
||||||
|
#endif
|
||||||
|
|
||||||
// Special case for binary clauses
|
// Special case for binary clauses
|
||||||
// The first one has to be SAT
|
// The first one has to be SAT
|
||||||
|
|
@ -578,8 +632,14 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
pathC++;
|
pathC++;
|
||||||
#ifdef UPDATEVARACTIVITY
|
#ifdef UPDATEVARACTIVITY
|
||||||
// UPDATEVARACTIVITY trick (see competition'09 companion paper)
|
// UPDATEVARACTIVITY trick (see competition'09 companion paper)
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef)
|
||||||
|
&& ! isGateCRef(reason(var(q))) && ca[reason(var(q))].learnt())
|
||||||
|
lastDecisionLevel.push(q);
|
||||||
|
#else
|
||||||
if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef) && ca[reason(var(q))].learnt())
|
if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef) && ca[reason(var(q))].learnt())
|
||||||
lastDecisionLevel.push(q);
|
lastDecisionLevel.push(q);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -609,7 +669,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
for(i = 0;i<selectors.size();i++)
|
for(i = 0;i<selectors.size();i++)
|
||||||
out_learnt.push(selectors[i]);
|
out_learnt.push(selectors[i]);
|
||||||
|
|
||||||
out_learnt.copyTo(analyze_toclear);
|
out_learnt.copyTo_(analyze_toclear);
|
||||||
if (ccmin_mode == 2){
|
if (ccmin_mode == 2){
|
||||||
uint32_t abstract_level = 0;
|
uint32_t abstract_level = 0;
|
||||||
for (i = 1; i < out_learnt.size(); i++)
|
for (i = 1; i < out_learnt.size(); i++)
|
||||||
|
|
@ -626,7 +686,11 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
if (reason(x) == CRef_Undef)
|
if (reason(x) == CRef_Undef)
|
||||||
out_learnt[j++] = out_learnt[i];
|
out_learnt[j++] = out_learnt[i];
|
||||||
else{
|
else{
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
Clause& c = ca[castCRef(out_learnt[i])];
|
||||||
|
#else
|
||||||
Clause& c = ca[reason(var(out_learnt[i]))];
|
Clause& c = ca[reason(var(out_learnt[i]))];
|
||||||
|
#endif
|
||||||
// Thanks to Siert Wieringa for this bug fix!
|
// Thanks to Siert Wieringa for this bug fix!
|
||||||
for (int k = ((c.size()==2) ? 0:1); k < c.size(); k++)
|
for (int k = ((c.size()==2) ? 0:1); k < c.size(); k++)
|
||||||
if (!seen[var(c[k])] && level(var(c[k])) > 0){
|
if (!seen[var(c[k])] && level(var(c[k])) > 0){
|
||||||
|
|
@ -638,7 +702,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
i = j = out_learnt.size();
|
i = j = out_learnt.size();
|
||||||
|
|
||||||
max_literals += out_learnt.size();
|
max_literals += out_learnt.size();
|
||||||
out_learnt.shrink(i - j);
|
out_learnt.shrink_(i - j);
|
||||||
tot_literals += out_learnt.size();
|
tot_literals += out_learnt.size();
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -687,8 +751,16 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
// UPDATEVARACTIVITY trick (see competition'09 companion paper)
|
// UPDATEVARACTIVITY trick (see competition'09 companion paper)
|
||||||
if(lastDecisionLevel.size()>0) {
|
if(lastDecisionLevel.size()>0) {
|
||||||
for(int i = 0;i<lastDecisionLevel.size();i++) {
|
for(int i = 0;i<lastDecisionLevel.size();i++) {
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
Lit t = lastDecisionLevel[i];
|
||||||
|
if( isGateCRef(reason(var(t))) || ca[reason(var(t))].lbd()<lbd )
|
||||||
|
varBumpActivity(var(lastDecisionLevel[i]));
|
||||||
|
#else
|
||||||
if(ca[reason(var(lastDecisionLevel[i]))].lbd()<lbd)
|
if(ca[reason(var(lastDecisionLevel[i]))].lbd()<lbd)
|
||||||
varBumpActivity(var(lastDecisionLevel[i]));
|
varBumpActivity(var(lastDecisionLevel[i]));
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
lastDecisionLevel.clear();
|
lastDecisionLevel.clear();
|
||||||
}
|
}
|
||||||
|
|
@ -698,6 +770,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
||||||
|
|
||||||
for (j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared)
|
for (j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared)
|
||||||
for(j = 0 ; j<selectors.size() ; j++) seen[var(selectors[j])] = 0;
|
for(j = 0 ; j<selectors.size() ; j++) seen[var(selectors[j])] = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -709,7 +782,11 @@ bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
|
||||||
int top = analyze_toclear.size();
|
int top = analyze_toclear.size();
|
||||||
while (analyze_stack.size() > 0){
|
while (analyze_stack.size() > 0){
|
||||||
assert(reason(var(analyze_stack.last())) != CRef_Undef);
|
assert(reason(var(analyze_stack.last())) != CRef_Undef);
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
Clause& c = ca[castCRef(analyze_stack.last())]; analyze_stack.pop();
|
||||||
|
#else
|
||||||
Clause& c = ca[reason(var(analyze_stack.last()))]; analyze_stack.pop();
|
Clause& c = ca[reason(var(analyze_stack.last()))]; analyze_stack.pop();
|
||||||
|
#endif
|
||||||
if(c.size()==2 && value(c[0])==l_False) {
|
if(c.size()==2 && value(c[0])==l_False) {
|
||||||
assert(value(c[1])==l_True);
|
assert(value(c[1])==l_True);
|
||||||
Lit tmp = c[0];
|
Lit tmp = c[0];
|
||||||
|
|
@ -726,7 +803,7 @@ bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
|
||||||
}else{
|
}else{
|
||||||
for (int j = top; j < analyze_toclear.size(); j++)
|
for (int j = top; j < analyze_toclear.size(); j++)
|
||||||
seen[var(analyze_toclear[j])] = 0;
|
seen[var(analyze_toclear[j])] = 0;
|
||||||
analyze_toclear.shrink(analyze_toclear.size() - top);
|
analyze_toclear.shrink_(analyze_toclear.size() - top);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -763,7 +840,11 @@ void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
|
||||||
assert(level(x) > 0);
|
assert(level(x) > 0);
|
||||||
out_conflict.push(~trail[i]);
|
out_conflict.push(~trail[i]);
|
||||||
}else{
|
}else{
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
Clause& c = ca[castCRef(trail[i])];
|
||||||
|
#else
|
||||||
Clause& c = ca[reason(x)];
|
Clause& c = ca[reason(x)];
|
||||||
|
#endif
|
||||||
// for (int j = 1; j < c.size(); j++) Minisat (glucose 2.0) loop
|
// for (int j = 1; j < c.size(); j++) Minisat (glucose 2.0) loop
|
||||||
// Bug in case of assumptions due to special data structures for Binary.
|
// Bug in case of assumptions due to special data structures for Binary.
|
||||||
// Many thanks to Sam Bayless (sbayless@cs.ubc.ca) for discover this bug.
|
// Many thanks to Sam Bayless (sbayless@cs.ubc.ca) for discover this bug.
|
||||||
|
|
@ -779,13 +860,20 @@ void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
|
||||||
seen[var(p)] = 0;
|
seen[var(p)] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Solver::uncheckedEnqueue(Lit p, CRef from)
|
void Solver::uncheckedEnqueue(Lit p, CRef from)
|
||||||
{
|
{
|
||||||
assert(value(p) == l_Undef);
|
assert(value(p) == l_Undef);
|
||||||
assigns[var(p)] = lbool(!sign(p));
|
assigns[var(p)] = lbool(!sign(p));
|
||||||
vardata[var(p)] = mkVarData(from, decisionLevel());
|
vardata[var(p)] = mkVarData(from, decisionLevel());
|
||||||
trail.push_(p);
|
trail.push_(p);
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
if( 0 < justUsage() ){
|
||||||
|
jdata[var(p)] = mkJustData( l_False == value(var(p)) );
|
||||||
|
if(isTwoFanin(var(p)) && l_False == value(var(p)))
|
||||||
|
if(l_Undef == value( getFaninVar0(var(p)) ) && l_Undef == value( getFaninVar1(var(p)) ))
|
||||||
|
jstack.push(var(p));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -812,6 +900,18 @@ CRef Solver::propagate()
|
||||||
Watcher *i, *j, *end;
|
Watcher *i, *j, *end;
|
||||||
num_props++;
|
num_props++;
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
if( 2 <= justUsage() ){
|
||||||
|
CRef stats;
|
||||||
|
if( CRef_Undef != (stats = gatePropagate(p)) ){
|
||||||
|
confl = stats;
|
||||||
|
if( l_True == value(var(p)) )
|
||||||
|
return confl;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// First, Propagate binary clauses
|
// First, Propagate binary clauses
|
||||||
vec<Watcher>& wbin = watchesBin[p];
|
vec<Watcher>& wbin = watchesBin[p];
|
||||||
for(int k = 0;k<wbin.size();k++) {
|
for(int k = 0;k<wbin.size();k++) {
|
||||||
|
|
@ -824,6 +924,8 @@ CRef Solver::propagate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){
|
for (i = j = (Watcher*)ws, end = i + ws.size(); i != end;){
|
||||||
// Try to avoid inspecting the clause:
|
// Try to avoid inspecting the clause:
|
||||||
Lit blocker = i->blocker;
|
Lit blocker = i->blocker;
|
||||||
|
|
@ -902,6 +1004,10 @@ CRef Solver::propagate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*_________________________________________________________________________________________________
|
/*_________________________________________________________________________________________________
|
||||||
|
|
|
|
||||||
| reduceDB : () -> [void]
|
| reduceDB : () -> [void]
|
||||||
|
|
@ -1044,24 +1150,25 @@ lbool Solver::search(int nof_conflicts)
|
||||||
unsigned int nblevels,szWoutSelectors;
|
unsigned int nblevels,szWoutSelectors;
|
||||||
bool blocked=false;
|
bool blocked=false;
|
||||||
starts++;
|
starts++;
|
||||||
|
|
||||||
for (;;){
|
for (;;){
|
||||||
CRef confl = propagate();
|
CRef confl = propagate();
|
||||||
if (confl != CRef_Undef){
|
if (confl != CRef_Undef){
|
||||||
|
|
||||||
// CONFLICT
|
// CONFLICT
|
||||||
conflicts++; conflictC++;conflictsRestarts++;
|
conflicts++; conflictC++;conflictsRestarts++;
|
||||||
if(conflicts%5000==0 && var_decay<0.95)
|
if(conflicts%5000==0 && var_decay<0.95)
|
||||||
var_decay += 0.01;
|
var_decay += 0.01;
|
||||||
|
|
||||||
if (verbosity >= 1 && conflicts%verbEveryConflicts==0){
|
if (verbosity >= 1 && conflicts%verbEveryConflicts==0){
|
||||||
printf("c | %8d %7d %5d | %7d %8d %8d | %5d %8d %6d %8d | %6.3f %% |\n",
|
printf("c | %8d %7d %5d | %7d %8d %8d | %5d %8d %6d %8d | %6.3f %% \n",
|
||||||
(int)starts,(int)nbstopsrestarts, (int)(conflicts/starts),
|
(int)starts,(int)nbstopsrestarts, (int)(conflicts/starts),
|
||||||
(int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
|
(int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
|
||||||
(int)nbReduceDB, nLearnts(), (int)nbDL2,(int)nbRemovedClauses, progressEstimate()*100);
|
(int)nbReduceDB, nLearnts(), (int)nbDL2,(int)nbRemovedClauses, progressEstimate()*100);
|
||||||
}
|
}
|
||||||
if (decisionLevel() == 0) {
|
if (decisionLevel() == 0)
|
||||||
return l_False;
|
return l_False;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trailQueue.push(trail.size());
|
trailQueue.push(trail.size());
|
||||||
// BLOCK RESTART (CP 2012 paper)
|
// BLOCK RESTART (CP 2012 paper)
|
||||||
|
|
@ -1077,9 +1184,7 @@ lbool Solver::search(int nof_conflicts)
|
||||||
|
|
||||||
lbdQueue.push(nblevels);
|
lbdQueue.push(nblevels);
|
||||||
sumLBD += nblevels;
|
sumLBD += nblevels;
|
||||||
|
|
||||||
cancelUntil(backtrack_level);
|
cancelUntil(backtrack_level);
|
||||||
|
|
||||||
if (certifiedUNSAT) {
|
if (certifiedUNSAT) {
|
||||||
for (int i = 0; i < learnt_clause.size(); i++)
|
for (int i = 0; i < learnt_clause.size(); i++)
|
||||||
fprintf(certifiedOutput, "%i " , (var(learnt_clause[i]) + 1) *
|
fprintf(certifiedOutput, "%i " , (var(learnt_clause[i]) + 1) *
|
||||||
|
|
@ -1104,9 +1209,7 @@ lbool Solver::search(int nof_conflicts)
|
||||||
varDecayActivity();
|
varDecayActivity();
|
||||||
claDecayActivity();
|
claDecayActivity();
|
||||||
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
// Our dynamic restart, see the SAT09 competition compagnion paper
|
// Our dynamic restart, see the SAT09 competition compagnion paper
|
||||||
if ( (conflictsRestarts && lbdQueue.isvalid() && lbdQueue.getavg()*K > sumLBD/conflictsRestarts) || (pstop && *pstop) ) {
|
if ( (conflictsRestarts && lbdQueue.isvalid() && lbdQueue.getavg()*K > sumLBD/conflictsRestarts) || (pstop && *pstop) ) {
|
||||||
lbdQueue.fastclear();
|
lbdQueue.fastclear();
|
||||||
|
|
@ -1149,13 +1252,26 @@ lbool Solver::search(int nof_conflicts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
// pick from JustQueue
|
||||||
|
Var j_reason = -1;
|
||||||
|
if (0 < justUsage())
|
||||||
|
if ( next == lit_Undef ){
|
||||||
|
decisions++;
|
||||||
|
next = pickJustLit( j_reason );
|
||||||
|
if(next == lit_Undef)
|
||||||
|
return l_True;
|
||||||
|
addJwatch(var(next), j_reason);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (next == lit_Undef){
|
if (next == lit_Undef){
|
||||||
// New variable decision:
|
// New variable decision:
|
||||||
decisions++;
|
decisions++;
|
||||||
next = pickBranchLit();
|
next = pickBranchLit();
|
||||||
|
|
||||||
if (next == lit_Undef){
|
if (next == lit_Undef){
|
||||||
//printf("c last restart ## conflicts : %d %d \n",conflictC,decisionLevel());
|
|
||||||
// Model found:
|
// Model found:
|
||||||
return l_True;
|
return l_True;
|
||||||
}
|
}
|
||||||
|
|
@ -1169,6 +1285,7 @@ lbool Solver::search(int nof_conflicts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double Solver::progressEstimate() const
|
double Solver::progressEstimate() const
|
||||||
{
|
{
|
||||||
double progress = 0;
|
double progress = 0;
|
||||||
|
|
@ -1209,20 +1326,32 @@ void Solver::printIncrementalStats() {
|
||||||
lbool Solver::solve_()
|
lbool Solver::solve_()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
ResetJustData(false);
|
||||||
|
|
||||||
|
if( 0 < justUsage() )
|
||||||
|
for(int i=0; i<trail.size(); i++){ // learnt unit clauses
|
||||||
|
Var v = var(trail[i]);
|
||||||
|
if( isTwoFanin(v) && value(v) == l_False )
|
||||||
|
jstack.push(v);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if(incremental && certifiedUNSAT) {
|
if(incremental && certifiedUNSAT) {
|
||||||
printf("Can not use incremental and certified unsat in the same time\n");
|
printf("Can not use incremental and certified unsat in the same time\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
model.clear();
|
JustModel.shrink_(JustModel.size());
|
||||||
conflict.clear();
|
model.shrink_(model.size());
|
||||||
if (!ok) return l_False;
|
conflict.shrink_(conflict.size());
|
||||||
|
if (!ok){
|
||||||
|
travId_prev = travId;
|
||||||
|
return l_False;
|
||||||
|
}
|
||||||
double curTime = cpuTime();
|
double curTime = cpuTime();
|
||||||
|
|
||||||
|
|
||||||
solves++;
|
solves++;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lbool status = l_Undef;
|
lbool status = l_Undef;
|
||||||
if(!incremental && verbosity>=1) {
|
if(!incremental && verbosity>=1) {
|
||||||
printf("c ========================================[ MAGIC CONSTANTS ]==============================================\n");
|
printf("c ========================================[ MAGIC CONSTANTS ]==============================================\n");
|
||||||
|
|
@ -1240,7 +1369,7 @@ printf("c ==================================[ Search Statistics (every %6d confl
|
||||||
printf("c | |\n");
|
printf("c | |\n");
|
||||||
|
|
||||||
printf("c | RESTARTS | ORIGINAL | LEARNT | Progress |\n");
|
printf("c | RESTARTS | ORIGINAL | LEARNT | Progress |\n");
|
||||||
printf("c | NB Blocked Avg Cfc | Vars Clauses Literals | Red Learnts LBD2 Removed | |\n");
|
printf("c | NB Blocked Avg Cfc | Vars Clauses Literals | Red Learnts LBD2 Removed | | pol-inconsist\n");
|
||||||
printf("c =========================================================================================================\n");
|
printf("c =========================================================================================================\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1265,12 +1394,29 @@ printf("c ==================================[ Search Statistics (every %6d confl
|
||||||
|
|
||||||
|
|
||||||
if (status == l_True){
|
if (status == l_True){
|
||||||
// Extend & copy model:
|
|
||||||
model.growTo(nVars());
|
if( justUsage() && false ){
|
||||||
for (int i = 0; i < nVars(); i++) model[i] = value(i);
|
assert(jheap.empty());
|
||||||
|
//JustModel.growTo(nVars());
|
||||||
|
int i = 0;
|
||||||
|
JustModel.push(toLit(0));
|
||||||
|
for (; i < trail.size(); i++)
|
||||||
|
if( isRoundWatch(var(trail[i])) && !isTwoFanin(var(trail[i])) )
|
||||||
|
JustModel.push(trail[i]);
|
||||||
|
JustModel[0] = toLit(i);
|
||||||
|
} else {
|
||||||
|
// Extend & copy model:
|
||||||
|
model.growTo(nVars());
|
||||||
|
for (int i = 0; i < trail.size(); i++) model[ var(trail[i]) ] = value(var(trail[i]));
|
||||||
|
}
|
||||||
}else if (status == l_False && conflict.size() == 0)
|
}else if (status == l_False && conflict.size() == 0)
|
||||||
ok = false;
|
ok = false;
|
||||||
|
|
||||||
|
//#ifdef CGLUCOSE_EXP
|
||||||
|
//if(status == l_True && 0 < justUsage())
|
||||||
|
// justCheck();
|
||||||
|
//#endif
|
||||||
|
|
||||||
cancelUntil(0);
|
cancelUntil(0);
|
||||||
|
|
||||||
double finalTime = cpuTime();
|
double finalTime = cpuTime();
|
||||||
|
|
@ -1299,6 +1445,7 @@ printf("c ==================================[ Search Statistics (every %6d confl
|
||||||
else if (pCnfFunc)
|
else if (pCnfFunc)
|
||||||
terminate_search_early = false; // for next run
|
terminate_search_early = false; // for next run
|
||||||
|
|
||||||
|
travId_prev = travId;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1385,6 +1532,12 @@ void Solver::toDimacs(FILE* f, const vec<Lit>& assumps)
|
||||||
|
|
||||||
void Solver::relocAll(ClauseAllocator& to)
|
void Solver::relocAll(ClauseAllocator& to)
|
||||||
{
|
{
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
if( CRef_Undef != itpc ){
|
||||||
|
setItpcSize(3);
|
||||||
|
ca.reloc(itpc, to);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
int v, s, i, j;
|
int v, s, i, j;
|
||||||
// All watchers:
|
// All watchers:
|
||||||
//
|
//
|
||||||
|
|
@ -1408,6 +1561,10 @@ void Solver::relocAll(ClauseAllocator& to)
|
||||||
for (i = 0; i < trail.size(); i++){
|
for (i = 0; i < trail.size(); i++){
|
||||||
Var v = var(trail[i]);
|
Var v = var(trail[i]);
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
if( isGateCRef(reason(v)) )
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)])))
|
if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)])))
|
||||||
ca.reloc(vardata[v].reason, to);
|
ca.reloc(vardata[v].reason, to);
|
||||||
}
|
}
|
||||||
|
|
@ -1477,27 +1634,55 @@ void Solver::reset()
|
||||||
learnts.clear(false);
|
learnts.clear(false);
|
||||||
//permanentLearnts.clear(false);
|
//permanentLearnts.clear(false);
|
||||||
//unaryWatchedClauses.clear(false);
|
//unaryWatchedClauses.clear(false);
|
||||||
model.clear(false);
|
model .shrink_(model .size());
|
||||||
conflict.clear(false);
|
conflict.shrink_(conflict.size());
|
||||||
activity.clear(false);
|
activity.shrink_(activity.size());
|
||||||
assigns.clear(false);
|
assigns .shrink_(assigns .size());
|
||||||
polarity.clear(false);
|
polarity.shrink_(polarity.size());
|
||||||
//forceUNSAT.clear(false);
|
//forceUNSAT.clear(false);
|
||||||
decision.clear(false);
|
decision .shrink_(decision .size());
|
||||||
trail.clear(false);
|
trail .shrink_(trail .size());
|
||||||
nbpos.clear(false);
|
trail_lim .shrink_(trail_lim .size());
|
||||||
trail_lim.clear(false);
|
vardata .shrink_(vardata .size());
|
||||||
vardata.clear(false);
|
assumptions.shrink_(assumptions.size());
|
||||||
assumptions.clear(false);
|
nbpos .shrink_(nbpos .size());
|
||||||
permDiff.clear(false);
|
permDiff .shrink_(permDiff .size());
|
||||||
lastDecisionLevel.clear(false);
|
#ifdef UPDATEVARACTIVITY
|
||||||
|
lastDecisionLevel.shrink_(lastDecisionLevel.size());
|
||||||
|
#endif
|
||||||
ca.clear();
|
ca.clear();
|
||||||
seen.clear(false);
|
seen .shrink_(seen.size());
|
||||||
analyze_stack.clear(false);
|
analyze_stack .shrink_(analyze_stack .size());
|
||||||
analyze_toclear.clear(false);
|
analyze_toclear.shrink_(analyze_toclear.size());
|
||||||
add_tmp.clear(false);
|
add_tmp.clear(false);
|
||||||
assumptionPositions.clear(false);
|
assumptionPositions.clear(false);
|
||||||
initialPositions.clear(false);
|
initialPositions.clear(false);
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
|
||||||
|
ResetJustData(false);
|
||||||
|
|
||||||
|
jwatch.shrink_(jwatch.size());
|
||||||
|
jdata .shrink_(jdata .size());
|
||||||
|
|
||||||
|
|
||||||
|
travId = 0;
|
||||||
|
travId_prev = 0;
|
||||||
|
var2TravId .shrink_(var2TravId.size());
|
||||||
|
JustModel .shrink_(JustModel .size());
|
||||||
|
|
||||||
|
var2FaninLits.shrink_(var2FaninLits.size());
|
||||||
|
var2Fanout0 .shrink_(var2Fanout0 .size());
|
||||||
|
var2FanoutN .shrink_(var2FanoutN .size());
|
||||||
|
//var2FanoutP.clear(false);
|
||||||
|
if( CRef_Undef != itpc ){
|
||||||
|
itpc = CRef_Undef; // clause allocator has been cleared, do not worry
|
||||||
|
// allocate space for clause interpretation
|
||||||
|
vec<Lit> tmp; tmp.growTo(3);
|
||||||
|
itpc = ca.alloc(tmp);
|
||||||
|
ca[itpc].shrink( ca[itpc].size() );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ABC_NAMESPACE_IMPL_END
|
ABC_NAMESPACE_IMPL_END
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
||||||
#include "sat/glucose2/Queue.h"
|
#include "sat/glucose2/Queue.h"
|
||||||
#include "sat/glucose2/Solver.h"
|
#include "sat/glucose2/Solver.h"
|
||||||
|
|
||||||
|
#include "sat/glucose2/CGlucose.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_CXX_HEADER_START
|
ABC_NAMESPACE_CXX_HEADER_START
|
||||||
|
|
||||||
namespace Gluco2 {
|
namespace Gluco2 {
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ SimpSolver::SimpSolver() :
|
||||||
ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
|
ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
|
||||||
bwdsub_tmpunit = ca.alloc(dummy);
|
bwdsub_tmpunit = ca.alloc(dummy);
|
||||||
remove_satisfied = false;
|
remove_satisfied = false;
|
||||||
|
parsing = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
||||||
#include "sat/glucose2/BoundedQueue.h"
|
#include "sat/glucose2/BoundedQueue.h"
|
||||||
#include "sat/glucose2/Constants.h"
|
#include "sat/glucose2/Constants.h"
|
||||||
|
|
||||||
|
#include "sat/glucose2/CGlucose.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_CXX_HEADER_START
|
ABC_NAMESPACE_CXX_HEADER_START
|
||||||
|
|
||||||
namespace Gluco2 {
|
namespace Gluco2 {
|
||||||
|
|
@ -123,6 +125,7 @@ public:
|
||||||
int nVars () const; // The current number of variables.
|
int nVars () const; // The current number of variables.
|
||||||
int nFreeVars () const;
|
int nFreeVars () const;
|
||||||
int * getCex () const;
|
int * getCex () const;
|
||||||
|
int level (Var x) const; // moved level() to public to compile "struct JustOrderLt" -- alanmi
|
||||||
|
|
||||||
// Incremental mode
|
// Incremental mode
|
||||||
void setIncrementalMode();
|
void setIncrementalMode();
|
||||||
|
|
@ -341,7 +344,6 @@ protected:
|
||||||
int decisionLevel () const; // Gives the current decisionlevel.
|
int decisionLevel () const; // Gives the current decisionlevel.
|
||||||
uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
|
uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
|
||||||
CRef reason (Var x) const;
|
CRef reason (Var x) const;
|
||||||
int level (Var x) const;
|
|
||||||
double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
|
double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
|
||||||
bool withinBudget () const;
|
bool withinBudget () const;
|
||||||
inline bool isSelector(Var v) {return (incremental && v>nbVarsInitialFormula);}
|
inline bool isSelector(Var v) {return (incremental && v>nbVarsInitialFormula);}
|
||||||
|
|
@ -359,6 +361,99 @@ protected:
|
||||||
// Returns a random integer 0 <= x < size. Seed must never be 0.
|
// Returns a random integer 0 <= x < size. Seed must never be 0.
|
||||||
static inline int irand(double& seed, int size) {
|
static inline int irand(double& seed, int size) {
|
||||||
return (int)(drand(seed) * size); }
|
return (int)(drand(seed) * size); }
|
||||||
|
|
||||||
|
|
||||||
|
// circuit-based solver
|
||||||
|
protected:
|
||||||
|
struct JustData { unsigned now: 1; double act_fanin; };
|
||||||
|
vec<JustData> jdata;
|
||||||
|
static inline JustData mkJustData(bool n){ JustData d = {n,0}; return d; }
|
||||||
|
|
||||||
|
struct JustOrderLt {
|
||||||
|
const Solver * pS;
|
||||||
|
bool operator () (Var x, Var y) const {
|
||||||
|
if( pS->justActivity(x) != pS->justActivity(y) )
|
||||||
|
return pS->justActivity(x) > pS->justActivity(y);
|
||||||
|
if( pS->level(x) != pS->level(y) )
|
||||||
|
return pS->level(x) < pS->level(y);
|
||||||
|
return x > y;
|
||||||
|
}
|
||||||
|
JustOrderLt(const Solver * _pS) : pS(_pS) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JustWatch { struct { unsigned dir:1; } header; Var head; Var next; Var prev; };
|
||||||
|
vec<JustWatch> jwatch;
|
||||||
|
static inline JustWatch mkJustWatch(){ JustWatch w = {0, var_Undef, var_Undef, var_Undef}; return w; }
|
||||||
|
void addJwatch( Var host, Var member );
|
||||||
|
void delJwatch( Var member );
|
||||||
|
|
||||||
|
vec<Lit> var2FaninLits; // (~0): undefine
|
||||||
|
vec<unsigned> var2TravId;
|
||||||
|
vec<Lit> var2Fanout0, var2FanoutN, var2FanoutP;
|
||||||
|
CRef itpc; // the interpreted clause of a gate
|
||||||
|
|
||||||
|
bool isTwoFanin( Var v ) const ; // this var has two fanins
|
||||||
|
Lit getFaninLit0( Var v ) const { return var2FaninLits[ (v<<1) + 0 ]; }
|
||||||
|
Lit getFaninLit1( Var v ) const { return var2FaninLits[ (v<<1) + 1 ]; }
|
||||||
|
bool getFaninC0( Var v ) const { return sign(getFaninLit0(v)); }
|
||||||
|
bool getFaninC1( Var v ) const { return sign(getFaninLit1(v)); }
|
||||||
|
Var getFaninVar0( Var v ) const { return var(getFaninLit0(v)); }
|
||||||
|
Var getFaninVar1( Var v ) const { return var(getFaninLit1(v)); }
|
||||||
|
|
||||||
|
Lit maxActiveLit(Lit lit0, Lit lit1) const ;
|
||||||
|
|
||||||
|
Lit fanin2JustLit(Var v) const ;
|
||||||
|
Lit gateJustFanin(Var v) const ; // l_Undef=satisfied, 0/1 = fanin0/fanin1 requires justify
|
||||||
|
void gateAddJwatch(Var v);
|
||||||
|
CRef gatePropagateCheck( Var v, Var t );
|
||||||
|
CRef gatePropagateCheckThis( Var v );
|
||||||
|
CRef gatePropagateCheckFanout( Var v, Lit lfo );
|
||||||
|
void setItpcSize( int sz ); // sz <= 3
|
||||||
|
|
||||||
|
// directly call by original glucose functions
|
||||||
|
void updateJustActivity( Var v );
|
||||||
|
void ResetJustData(bool fCleanMemory);
|
||||||
|
Lit pickJustLit( Var& j_reason );
|
||||||
|
void justCheck();
|
||||||
|
void pushJustQueue(Var v);
|
||||||
|
void restoreJustQueue(int level); // call with cancelUntil
|
||||||
|
void gateClearJwatch( Var v, int backtrack_level );
|
||||||
|
|
||||||
|
CRef gatePropagate( Lit p );
|
||||||
|
|
||||||
|
CRef interpret( Var v, Var t );
|
||||||
|
CRef castCRef( Lit p ); // interpret a gate into a clause
|
||||||
|
CRef getConfClause( CRef r );
|
||||||
|
|
||||||
|
CRef Var2CRef( Var v ) const { return v | (1<<(sizeof(CRef)*8-1)); }
|
||||||
|
Var CRef2Var( CRef cr ) const { return cr & ~(1<<(sizeof(CRef)*8-1)); }
|
||||||
|
bool isGateCRef( CRef cr ) const { return CRef_Undef != cr && 0 != (cr & (1<<(sizeof(CRef)*8-1))); }
|
||||||
|
|
||||||
|
int64_t travId_prev, travId;
|
||||||
|
|
||||||
|
Heap<JustOrderLt> jheap;
|
||||||
|
/* jstack
|
||||||
|
call by unchecked_enqueue
|
||||||
|
consumed by pickJustLit
|
||||||
|
cleaned by cancelUntil
|
||||||
|
*/
|
||||||
|
vec<Var> jstack;
|
||||||
|
public:
|
||||||
|
void setVarFaninLits( Var v, Lit lit1, Lit lit2 );
|
||||||
|
//void delVarFaninLits( Var v);
|
||||||
|
|
||||||
|
int setNewRound(){ return travId ++ ; }
|
||||||
|
void markCone( Var v );
|
||||||
|
bool isRoundWatch( Var v ) const { return travId==var2TravId[v]; }
|
||||||
|
|
||||||
|
|
||||||
|
const JustData& getJustData(int v) const { return jdata[v]; }
|
||||||
|
double varActivity(int v) const { return activity[v];}
|
||||||
|
double justActivity(int v) const { return jdata[v].act_fanin;}
|
||||||
|
int varPolarity(int v){ return polarity[v]? 1: 0;}
|
||||||
|
vec<Lit> JustModel; // model obtained by justification enabled
|
||||||
|
|
||||||
|
int justUsage() const ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -378,11 +473,24 @@ inline void Solver::varBumpActivity(Var v, double inc) {
|
||||||
// Rescale:
|
// Rescale:
|
||||||
for (int i = 0; i < nVars(); i++)
|
for (int i = 0; i < nVars(); i++)
|
||||||
activity[i] *= 1e-100;
|
activity[i] *= 1e-100;
|
||||||
|
|
||||||
|
if( justUsage() )
|
||||||
|
for (int i = 0; i < jheap.size(); i++){
|
||||||
|
Var j = jheap[i];
|
||||||
|
jdata[j].act_fanin = activity[getFaninVar0(j)] > activity[getFaninVar1(j)]? activity[getFaninVar0(j)]: activity[getFaninVar1(j)];
|
||||||
|
}
|
||||||
var_inc *= 1e-100; }
|
var_inc *= 1e-100; }
|
||||||
|
|
||||||
// Update order_heap with respect to new activity:
|
// Update order_heap with respect to new activity:
|
||||||
if (order_heap.inHeap(v))
|
if (order_heap.inHeap(v))
|
||||||
order_heap.decrease(v); }
|
order_heap.decrease(v);
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
if( justUsage() )
|
||||||
|
updateJustActivity(v);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); }
|
inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); }
|
||||||
inline void Solver::claBumpActivity (Clause& c) {
|
inline void Solver::claBumpActivity (Clause& c) {
|
||||||
|
|
@ -405,14 +513,27 @@ inline bool Solver::addClause (Lit p) { add_tmp.clear(
|
||||||
inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
|
inline bool Solver::addClause (Lit p, Lit q) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
|
||||||
inline bool Solver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
|
inline bool Solver::addClause (Lit p, Lit q, Lit r) { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
|
||||||
inline bool Solver::locked (const Clause& c) const {
|
inline bool Solver::locked (const Clause& c) const {
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
|
||||||
|
if(c.size()>2)
|
||||||
|
return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && !isGateCRef(reason(var(c[0]))) && ca.lea(reason(var(c[0]))) == &c;
|
||||||
|
return
|
||||||
|
(value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && !isGateCRef(reason(var(c[0]))) && ca.lea(reason(var(c[0]))) == &c)
|
||||||
|
||
|
||||||
|
(value(c[1]) == l_True && reason(var(c[1])) != CRef_Undef && !isGateCRef(reason(var(c[1]))) && ca.lea(reason(var(c[1]))) == &c);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
if(c.size()>2)
|
if(c.size()>2)
|
||||||
return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c;
|
return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c;
|
||||||
return
|
return
|
||||||
(value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c)
|
(value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c)
|
||||||
||
|
||
|
||||||
(value(c[1]) == l_True && reason(var(c[1])) != CRef_Undef && ca.lea(reason(var(c[1]))) == &c);
|
(value(c[1]) == l_True && reason(var(c[1])) != CRef_Undef && ca.lea(reason(var(c[1]))) == &c);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
inline void Solver::newDecisionLevel() { trail_lim.push(trail.size()); }
|
inline void Solver::newDecisionLevel() {trail_lim.push(trail.size());}
|
||||||
|
|
||||||
inline int Solver::decisionLevel () const { return trail_lim.size(); }
|
inline int Solver::decisionLevel () const { return trail_lim.size(); }
|
||||||
inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); }
|
inline uint32_t Solver::abstractLevel (Var x) const { return 1 << (level(x) & 31); }
|
||||||
|
|
@ -463,9 +584,9 @@ inline void Solver::toDimacs (const char* file, Lit p, Lit q, Lit r){ v
|
||||||
|
|
||||||
inline void Solver::addVar(Var v) { while (v >= nVars()) newVar(); }
|
inline void Solver::addVar(Var v) { while (v >= nVars()) newVar(); }
|
||||||
|
|
||||||
inline void Solver::sat_solver_set_var_fanin_lit(int var, int lit0, int lit1) {}
|
inline void Solver::sat_solver_set_var_fanin_lit(int v, int lit0, int lit1) { setVarFaninLits( Var(v), toLit(lit0), toLit(lit1) ); }
|
||||||
inline void Solver::sat_solver_start_new_round() {}
|
inline void Solver::sat_solver_start_new_round() { setNewRound(); }
|
||||||
inline void Solver::sat_solver_mark_cone(int var) {}
|
inline void Solver::sat_solver_mark_cone(int v) { markCone(v); }
|
||||||
|
|
||||||
//=================================================================================================
|
//=================================================================================================
|
||||||
// Debug etc:
|
// Debug etc:
|
||||||
|
|
@ -501,6 +622,9 @@ inline void Solver::printInitialClause(CRef cr)
|
||||||
//=================================================================================================
|
//=================================================================================================
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ABC_NAMESPACE_CXX_HEADER_END
|
ABC_NAMESPACE_CXX_HEADER_END
|
||||||
|
|
||||||
|
#include "sat/glucose2/CGlucoseCore.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
|
||||||
#include "sat/glucose2/Map.h"
|
#include "sat/glucose2/Map.h"
|
||||||
#include "sat/glucose2/Alloc.h"
|
#include "sat/glucose2/Alloc.h"
|
||||||
|
|
||||||
|
#include "sat/glucose2/CGlucose.h"
|
||||||
|
|
||||||
ABC_NAMESPACE_CXX_HEADER_START
|
ABC_NAMESPACE_CXX_HEADER_START
|
||||||
|
|
||||||
namespace Gluco2 {
|
namespace Gluco2 {
|
||||||
|
|
@ -145,6 +147,10 @@ class Clause {
|
||||||
|
|
||||||
friend class ClauseAllocator;
|
friend class ClauseAllocator;
|
||||||
|
|
||||||
|
#ifdef CGLUCOSE_EXP
|
||||||
|
friend class Solver;
|
||||||
|
#endif
|
||||||
|
|
||||||
// NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
|
// NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
|
||||||
template<class V>
|
template<class V>
|
||||||
Clause(const V& ps, bool use_extra, bool learnt) {
|
Clause(const V& ps, bool use_extra, bool learnt) {
|
||||||
|
|
@ -306,9 +312,15 @@ class OccLists
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(bool free = true){
|
void clear(bool free = true){
|
||||||
occs .clear(free);
|
if(free){
|
||||||
dirty .clear(free);
|
occs .clear(free);
|
||||||
dirties.clear(free);
|
dirty .clear(free);
|
||||||
|
dirties.clear(free);
|
||||||
|
} else {
|
||||||
|
occs .shrink_(occs .size());
|
||||||
|
dirty .shrink_(dirty .size());
|
||||||
|
dirties.shrink_(dirties.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,8 @@ public:
|
||||||
T& operator [] (int index) { return data[index]; }
|
T& operator [] (int index) { return data[index]; }
|
||||||
|
|
||||||
// Duplicatation (preferred instead):
|
// Duplicatation (preferred instead):
|
||||||
void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
|
void copyTo (vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
|
||||||
|
void copyTo_(vec<T>& copy) const { copy.shrink_(copy.size()); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
|
||||||
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
|
void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue