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"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\proof\cec\cecSatG2.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\base\main\main.c
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
|
|||
|
|
@ -2395,6 +2395,14 @@ SOURCE=.\src\sat\glucose2\BoundedQueue.h
|
|||
# End 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
|
||||
# End 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;
|
||||
int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoG2 = 0;
|
||||
Cec_ManFraSetDefaultParams( pPars );
|
||||
pPars->jType = 0; // solver type
|
||||
pPars->jType = 2; // solver type
|
||||
pPars->fSatSweeping = 1; // conflict limit at a node
|
||||
pPars->nWords = 8; // simulation words
|
||||
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->nGenIters = 100; // pattern generation iterations
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCPrmdckngxwvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxwvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
|
|
@ -36381,6 +36381,17 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( pPars->nBTLimit < 0 )
|
||||
goto usage;
|
||||
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':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
|
|
@ -36443,7 +36454,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
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-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 );
|
||||
|
|
@ -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-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-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-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" );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
//Vec_IntForEachEntryDouble( &p->pNew->vCopiesTwo, IdAig, IdSat, i )
|
||||
// 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 );
|
||||
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;
|
||||
int i, fSimulate = 1;
|
||||
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",
|
||||
pPars->nWords, pPars->nRounds, pPars->nGenIters, pPars->nBTLimit, pPars->nCallsRecycle );
|
||||
printf( "Solver type = %d. Simulate %d words in %d rounds. SAT with %d confs. Recycle after %d SAT calls.\n",
|
||||
pPars->jType, pPars->nWords, pPars->nRounds, pPars->nBTLimit, pPars->nCallsRecycle );
|
||||
|
||||
// this is currently needed to have a correct mapping
|
||||
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 );
|
||||
if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
@ -1510,9 +1510,11 @@ int Cec4_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** p
|
|||
Cec4_ManSimulate( p, pMan );
|
||||
if ( pPars->fCheckMiter && !Cec4_ManSimulateCos(p) ) // cex detected
|
||||
goto finalize;
|
||||
if ( pPars->fVerbose )
|
||||
if ( i && i % 5 == 0 && pPars->fVerbose )
|
||||
Cec4_ManPrintStats( p, pPars, pMan, 1 );
|
||||
}
|
||||
if ( i && i % 5 && pPars->fVerbose )
|
||||
Cec4_ManPrintStats( p, pPars, pMan, 1 );
|
||||
|
||||
p->iPatsPi = 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++)
|
||||
out_learnt.push(selectors[i]);
|
||||
|
||||
out_learnt.copyTo(analyze_toclear);
|
||||
out_learnt.copyTo_(analyze_toclear);
|
||||
if (ccmin_mode == 2){
|
||||
uint32_t abstract_level = 0;
|
||||
for (i = 1; i < out_learnt.size(); i++)
|
||||
|
|
|
|||
|
|
@ -306,9 +306,15 @@ class OccLists
|
|||
}
|
||||
|
||||
void clear(bool free = true){
|
||||
occs .clear(free);
|
||||
dirty .clear(free);
|
||||
dirties.clear(free);
|
||||
if(free){
|
||||
occs .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]; }
|
||||
|
||||
// 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; }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
**************************************************************************************************/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "sat/glucose2/Sort.h"
|
||||
#include "sat/glucose2/Solver.h"
|
||||
#include "sat/glucose2/Constants.h"
|
||||
#include "sat/glucose2/System.h"
|
||||
#include "sat/glucose2/Solver.h"
|
||||
|
||||
#include "sat/glucose2/CGlucose.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
|
@ -40,7 +41,7 @@ using namespace Gluco2;
|
|||
|
||||
//=================================================================================================
|
||||
// Options:
|
||||
|
||||
namespace Gluco2 {
|
||||
static const char* _cat = "CORE";
|
||||
static const char* _cr = "CORE -- RESTART";
|
||||
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));
|
||||
|
||||
|
||||
BoolOption opt2_certified_ (_certified, "certified", "Certified UNSAT using DRUP format", false );
|
||||
StringOption opt2_certified_file_ (_certified, "certified-output", "Certified UNSAT output file", "NULL");
|
||||
|
||||
BoolOption opt_certified_ (_certified, "certified", "Certified UNSAT using DRUP format", false );
|
||||
StringOption opt_certified_file_ (_certified, "certified-output", "Certified UNSAT output file", "NULL");
|
||||
};
|
||||
|
||||
//=================================================================================================
|
||||
// Constructor/Destructor:
|
||||
|
|
@ -121,7 +122,7 @@ Solver::Solver() :
|
|||
, rnd_init_act (opt_rnd_init_act)
|
||||
, garbage_frac (opt_garbage_frac)
|
||||
, certifiedOutput (NULL)
|
||||
, certifiedUNSAT (opt2_certified_)
|
||||
, certifiedUNSAT (opt_certified_)
|
||||
// Statistics: (formerly in 'SolverStats')
|
||||
//
|
||||
, nbRemovedClauses(0),nbReducedClauses(0), nbDL2(0),nbBin(0),nbUn(0) , nbReduceDB(0)
|
||||
|
|
@ -148,8 +149,13 @@ Solver::Solver() :
|
|||
, asynch_interrupt (false)
|
||||
, incremental(opt_incremental)
|
||||
, nbVarsInitialFormula(INT32_MAX)
|
||||
|
||||
#ifdef CGLUCOSE_EXP
|
||||
, jheap (JustOrderLt(this))
|
||||
#endif
|
||||
{
|
||||
MYFLAG=0;
|
||||
|
||||
// Initialize only first time. Useful for incremental solving, useless otherwise
|
||||
lbdQueue.initSize(sizeLBDQueue);
|
||||
trailQueue.initSize(sizeTrailQueue);
|
||||
|
|
@ -160,13 +166,24 @@ Solver::Solver() :
|
|||
|
||||
|
||||
if(certifiedUNSAT) {
|
||||
if(!strcmp(opt2_certified_file_,"NULL")) {
|
||||
if(!strcmp(opt_certified_file_,"NULL")) {
|
||||
certifiedOutput = fopen("/dev/stdout", "wb");
|
||||
} else {
|
||||
certifiedOutput = fopen(opt2_certified_file_, "wb");
|
||||
certifiedOutput = fopen(opt_certified_file_, "wb");
|
||||
}
|
||||
// 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();
|
||||
trail .capacity(v+1);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -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) {
|
||||
if (decisionLevel() > level){
|
||||
|
||||
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
|
||||
Var x = var(trail[c]);
|
||||
assigns [x] = l_Undef;
|
||||
|
|
@ -477,9 +508,25 @@ void Solver::cancelUntil(int level) {
|
|||
polarity[x] = sign(trail[c]);
|
||||
insertVarOrder(x); }
|
||||
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)
|
||||
{
|
||||
//double clk = Abc_Clock();
|
||||
|
||||
int pathC = 0;
|
||||
Lit p = lit_Undef;
|
||||
|
||||
|
|
@ -535,10 +584,15 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
|||
//
|
||||
out_learnt.push(); // (leave room for the asserting literal)
|
||||
int index = trail.size() - 1;
|
||||
|
||||
|
||||
do{
|
||||
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];
|
||||
#endif
|
||||
|
||||
// Special case for binary clauses
|
||||
// The first one has to be SAT
|
||||
|
|
@ -554,7 +608,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
|||
|
||||
#ifdef DYNAMICNBLEVEL
|
||||
// DYNAMIC NBLEVEL trick (see competition'09 companion paper)
|
||||
if(c.learnt() && c.lbd()>2) {
|
||||
if(c.learnt() && c.lbd()>2) {
|
||||
unsigned int nblevels = computeLBD(c);
|
||||
if(nblevels+1<c.lbd() ) { // improve the LBD
|
||||
if(c.lbd()<=lbLBDFrozenClause) {
|
||||
|
|
@ -578,8 +632,14 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
|
|||
pathC++;
|
||||
#ifdef UPDATEVARACTIVITY
|
||||
// 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())
|
||||
lastDecisionLevel.push(q);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} 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++)
|
||||
out_learnt.push(selectors[i]);
|
||||
|
||||
out_learnt.copyTo(analyze_toclear);
|
||||
out_learnt.copyTo_(analyze_toclear);
|
||||
if (ccmin_mode == 2){
|
||||
uint32_t abstract_level = 0;
|
||||
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)
|
||||
out_learnt[j++] = out_learnt[i];
|
||||
else{
|
||||
#ifdef CGLUCOSE_EXP
|
||||
Clause& c = ca[castCRef(out_learnt[i])];
|
||||
#else
|
||||
Clause& c = ca[reason(var(out_learnt[i]))];
|
||||
#endif
|
||||
// Thanks to Siert Wieringa for this bug fix!
|
||||
for (int k = ((c.size()==2) ? 0:1); k < c.size(); k++)
|
||||
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();
|
||||
|
||||
max_literals += out_learnt.size();
|
||||
out_learnt.shrink(i - j);
|
||||
out_learnt.shrink_(i - j);
|
||||
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)
|
||||
if(lastDecisionLevel.size()>0) {
|
||||
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)
|
||||
varBumpActivity(var(lastDecisionLevel[i]));
|
||||
varBumpActivity(var(lastDecisionLevel[i]));
|
||||
#endif
|
||||
|
||||
}
|
||||
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<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();
|
||||
while (analyze_stack.size() > 0){
|
||||
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();
|
||||
#endif
|
||||
if(c.size()==2 && value(c[0])==l_False) {
|
||||
assert(value(c[1])==l_True);
|
||||
Lit tmp = c[0];
|
||||
|
|
@ -726,7 +803,7 @@ bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
|
|||
}else{
|
||||
for (int j = top; j < analyze_toclear.size(); j++)
|
||||
seen[var(analyze_toclear[j])] = 0;
|
||||
analyze_toclear.shrink(analyze_toclear.size() - top);
|
||||
analyze_toclear.shrink_(analyze_toclear.size() - top);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -763,7 +840,11 @@ void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
|
|||
assert(level(x) > 0);
|
||||
out_conflict.push(~trail[i]);
|
||||
}else{
|
||||
#ifdef CGLUCOSE_EXP
|
||||
Clause& c = ca[castCRef(trail[i])];
|
||||
#else
|
||||
Clause& c = ca[reason(x)];
|
||||
#endif
|
||||
// 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.
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
void Solver::uncheckedEnqueue(Lit p, CRef from)
|
||||
{
|
||||
assert(value(p) == l_Undef);
|
||||
assigns[var(p)] = lbool(!sign(p));
|
||||
vardata[var(p)] = mkVarData(from, decisionLevel());
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -811,7 +899,19 @@ CRef Solver::propagate()
|
|||
vec<Watcher>& ws = watches[p];
|
||||
Watcher *i, *j, *end;
|
||||
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
|
||||
vec<Watcher>& wbin = watchesBin[p];
|
||||
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;){
|
||||
// Try to avoid inspecting the clause:
|
||||
Lit blocker = i->blocker;
|
||||
|
|
@ -897,11 +999,15 @@ CRef Solver::propagate()
|
|||
}
|
||||
propagations += num_props;
|
||||
simpDB_props -= num_props;
|
||||
|
||||
|
||||
return confl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*_________________________________________________________________________________________________
|
||||
|
|
||||
| reduceDB : () -> [void]
|
||||
|
|
@ -1044,24 +1150,25 @@ lbool Solver::search(int nof_conflicts)
|
|||
unsigned int nblevels,szWoutSelectors;
|
||||
bool blocked=false;
|
||||
starts++;
|
||||
|
||||
for (;;){
|
||||
CRef confl = propagate();
|
||||
if (confl != CRef_Undef){
|
||||
|
||||
// CONFLICT
|
||||
conflicts++; conflictC++;conflictsRestarts++;
|
||||
if(conflicts%5000==0 && var_decay<0.95)
|
||||
var_decay += 0.01;
|
||||
|
||||
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)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals,
|
||||
(int)nbReduceDB, nLearnts(), (int)nbDL2,(int)nbRemovedClauses, progressEstimate()*100);
|
||||
}
|
||||
if (decisionLevel() == 0) {
|
||||
if (decisionLevel() == 0)
|
||||
return l_False;
|
||||
|
||||
}
|
||||
|
||||
|
||||
trailQueue.push(trail.size());
|
||||
// BLOCK RESTART (CP 2012 paper)
|
||||
|
|
@ -1077,9 +1184,7 @@ lbool Solver::search(int nof_conflicts)
|
|||
|
||||
lbdQueue.push(nblevels);
|
||||
sumLBD += nblevels;
|
||||
|
||||
cancelUntil(backtrack_level);
|
||||
|
||||
if (certifiedUNSAT) {
|
||||
for (int i = 0; i < learnt_clause.size(); i++)
|
||||
fprintf(certifiedOutput, "%i " , (var(learnt_clause[i]) + 1) *
|
||||
|
|
@ -1104,9 +1209,7 @@ lbool Solver::search(int nof_conflicts)
|
|||
varDecayActivity();
|
||||
claDecayActivity();
|
||||
|
||||
|
||||
}else{
|
||||
|
||||
// Our dynamic restart, see the SAT09 competition compagnion paper
|
||||
if ( (conflictsRestarts && lbdQueue.isvalid() && lbdQueue.getavg()*K > sumLBD/conflictsRestarts) || (pstop && *pstop) ) {
|
||||
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){
|
||||
// New variable decision:
|
||||
decisions++;
|
||||
next = pickBranchLit();
|
||||
|
||||
if (next == lit_Undef){
|
||||
//printf("c last restart ## conflicts : %d %d \n",conflictC,decisionLevel());
|
||||
// Model found:
|
||||
return l_True;
|
||||
}
|
||||
|
|
@ -1169,6 +1285,7 @@ lbool Solver::search(int nof_conflicts)
|
|||
}
|
||||
|
||||
|
||||
|
||||
double Solver::progressEstimate() const
|
||||
{
|
||||
double progress = 0;
|
||||
|
|
@ -1209,19 +1326,31 @@ void Solver::printIncrementalStats() {
|
|||
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) {
|
||||
printf("Can not use incremental and certified unsat in the same time\n");
|
||||
exit(-1);
|
||||
}
|
||||
model.clear();
|
||||
conflict.clear();
|
||||
if (!ok) return l_False;
|
||||
JustModel.shrink_(JustModel.size());
|
||||
model.shrink_(model.size());
|
||||
conflict.shrink_(conflict.size());
|
||||
if (!ok){
|
||||
travId_prev = travId;
|
||||
return l_False;
|
||||
}
|
||||
double curTime = cpuTime();
|
||||
|
||||
|
||||
solves++;
|
||||
|
||||
|
||||
|
||||
lbool status = l_Undef;
|
||||
if(!incremental && verbosity>=1) {
|
||||
|
|
@ -1240,7 +1369,7 @@ printf("c ==================================[ Search Statistics (every %6d confl
|
|||
printf("c | |\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");
|
||||
}
|
||||
|
||||
|
|
@ -1265,12 +1394,29 @@ printf("c ==================================[ Search Statistics (every %6d confl
|
|||
|
||||
|
||||
if (status == l_True){
|
||||
// Extend & copy model:
|
||||
model.growTo(nVars());
|
||||
for (int i = 0; i < nVars(); i++) model[i] = value(i);
|
||||
|
||||
if( justUsage() && false ){
|
||||
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)
|
||||
ok = false;
|
||||
|
||||
//#ifdef CGLUCOSE_EXP
|
||||
//if(status == l_True && 0 < justUsage())
|
||||
// justCheck();
|
||||
//#endif
|
||||
|
||||
cancelUntil(0);
|
||||
|
||||
double finalTime = cpuTime();
|
||||
|
|
@ -1299,6 +1445,7 @@ printf("c ==================================[ Search Statistics (every %6d confl
|
|||
else if (pCnfFunc)
|
||||
terminate_search_early = false; // for next run
|
||||
|
||||
travId_prev = travId;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -1385,6 +1532,12 @@ void Solver::toDimacs(FILE* f, const vec<Lit>& assumps)
|
|||
|
||||
void Solver::relocAll(ClauseAllocator& to)
|
||||
{
|
||||
#ifdef CGLUCOSE_EXP
|
||||
if( CRef_Undef != itpc ){
|
||||
setItpcSize(3);
|
||||
ca.reloc(itpc, to);
|
||||
}
|
||||
#endif
|
||||
int v, s, i, j;
|
||||
// All watchers:
|
||||
//
|
||||
|
|
@ -1408,6 +1561,10 @@ void Solver::relocAll(ClauseAllocator& to)
|
|||
for (i = 0; i < trail.size(); 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)])))
|
||||
ca.reloc(vardata[v].reason, to);
|
||||
}
|
||||
|
|
@ -1477,27 +1634,55 @@ void Solver::reset()
|
|||
learnts.clear(false);
|
||||
//permanentLearnts.clear(false);
|
||||
//unaryWatchedClauses.clear(false);
|
||||
model.clear(false);
|
||||
conflict.clear(false);
|
||||
activity.clear(false);
|
||||
assigns.clear(false);
|
||||
polarity.clear(false);
|
||||
model .shrink_(model .size());
|
||||
conflict.shrink_(conflict.size());
|
||||
activity.shrink_(activity.size());
|
||||
assigns .shrink_(assigns .size());
|
||||
polarity.shrink_(polarity.size());
|
||||
//forceUNSAT.clear(false);
|
||||
decision.clear(false);
|
||||
trail.clear(false);
|
||||
nbpos.clear(false);
|
||||
trail_lim.clear(false);
|
||||
vardata.clear(false);
|
||||
assumptions.clear(false);
|
||||
permDiff.clear(false);
|
||||
lastDecisionLevel.clear(false);
|
||||
decision .shrink_(decision .size());
|
||||
trail .shrink_(trail .size());
|
||||
trail_lim .shrink_(trail_lim .size());
|
||||
vardata .shrink_(vardata .size());
|
||||
assumptions.shrink_(assumptions.size());
|
||||
nbpos .shrink_(nbpos .size());
|
||||
permDiff .shrink_(permDiff .size());
|
||||
#ifdef UPDATEVARACTIVITY
|
||||
lastDecisionLevel.shrink_(lastDecisionLevel.size());
|
||||
#endif
|
||||
ca.clear();
|
||||
seen.clear(false);
|
||||
analyze_stack.clear(false);
|
||||
analyze_toclear.clear(false);
|
||||
seen .shrink_(seen.size());
|
||||
analyze_stack .shrink_(analyze_stack .size());
|
||||
analyze_toclear.shrink_(analyze_toclear.size());
|
||||
add_tmp.clear(false);
|
||||
assumptionPositions.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
|
||||
|
|
|
|||
|
|
@ -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/Solver.h"
|
||||
|
||||
#include "sat/glucose2/CGlucose.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Gluco2 {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ SimpSolver::SimpSolver() :
|
|||
ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
|
||||
bwdsub_tmpunit = ca.alloc(dummy);
|
||||
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/Constants.h"
|
||||
|
||||
#include "sat/glucose2/CGlucose.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Gluco2 {
|
||||
|
|
@ -123,6 +125,7 @@ public:
|
|||
int nVars () const; // The current number of variables.
|
||||
int nFreeVars () const;
|
||||
int * getCex () const;
|
||||
int level (Var x) const; // moved level() to public to compile "struct JustOrderLt" -- alanmi
|
||||
|
||||
// Incremental mode
|
||||
void setIncrementalMode();
|
||||
|
|
@ -341,7 +344,6 @@ protected:
|
|||
int decisionLevel () const; // Gives the current decisionlevel.
|
||||
uint32_t abstractLevel (Var x) const; // Used to represent an abstraction of sets of decision levels.
|
||||
CRef reason (Var x) const;
|
||||
int level (Var x) const;
|
||||
double progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
|
||||
bool withinBudget () const;
|
||||
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.
|
||||
static inline int irand(double& seed, int 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:
|
||||
for (int i = 0; i < nVars(); i++)
|
||||
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; }
|
||||
|
||||
// Update order_heap with respect to new activity:
|
||||
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::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, 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 {
|
||||
#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)
|
||||
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)
|
||||
||
|
||||
(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 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::sat_solver_set_var_fanin_lit(int var, int lit0, int lit1) {}
|
||||
inline void Solver::sat_solver_start_new_round() {}
|
||||
inline void Solver::sat_solver_mark_cone(int var) {}
|
||||
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() { setNewRound(); }
|
||||
inline void Solver::sat_solver_mark_cone(int v) { markCone(v); }
|
||||
|
||||
//=================================================================================================
|
||||
// Debug etc:
|
||||
|
|
@ -501,6 +622,9 @@ inline void Solver::printInitialClause(CRef cr)
|
|||
//=================================================================================================
|
||||
}
|
||||
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_END
|
||||
|
||||
#include "sat/glucose2/CGlucoseCore.h"
|
||||
|
||||
#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/Alloc.h"
|
||||
|
||||
#include "sat/glucose2/CGlucose.h"
|
||||
|
||||
ABC_NAMESPACE_CXX_HEADER_START
|
||||
|
||||
namespace Gluco2 {
|
||||
|
|
@ -145,6 +147,10 @@ class Clause {
|
|||
|
||||
friend class ClauseAllocator;
|
||||
|
||||
#ifdef CGLUCOSE_EXP
|
||||
friend class Solver;
|
||||
#endif
|
||||
|
||||
// NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
|
||||
template<class V>
|
||||
Clause(const V& ps, bool use_extra, bool learnt) {
|
||||
|
|
@ -306,9 +312,15 @@ class OccLists
|
|||
}
|
||||
|
||||
void clear(bool free = true){
|
||||
occs .clear(free);
|
||||
dirty .clear(free);
|
||||
dirties.clear(free);
|
||||
if(free){
|
||||
occs .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]; }
|
||||
|
||||
// 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; }
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue