Commit 5f8a8a59 by Alan Mishchenko

Upgrade to the circuit-based solver.

parent de71e5f6
......@@ -99,15 +99,16 @@ void glucose2_solver_setcallback(Gluco2::SimpSolver* S, void * pman, int(*pfunc)
int glucose2_solver_solve(Gluco2::SimpSolver* S, int * plits, int nlits)
{
vec<Lit> lits;
for (int i=0;i<nlits;i++,plits++)
{
Lit p;
p.x = *plits;
lits.push(p);
}
Gluco2::lbool res = S->solveLimited(lits, 0);
return (res == l_True ? 1 : res == l_False ? -1 : 0);
// vec<Lit> lits;
// for (int i=0;i<nlits;i++,plits++)
// {
// Lit p;
// p.x = *plits;
// lits.push(p);
// }
// Gluco2::lbool res = S->solveLimited(lits, 0);
// return (res == l_True ? 1 : res == l_False ? -1 : 0);
return S->solveLimited(plits, nlits, 0);
}
int glucose2_solver_addvar(Gluco2::SimpSolver* S)
......@@ -383,6 +384,10 @@ void bmcg2_sat_solver_mark_cone(bmcg2_sat_solver* s, int var)
((Gluco2::SimpSolver*)s)->sat_solver_mark_cone(var);
}
void bmcg2_sat_solver_prelocate( bmcg2_sat_solver * s, int var_num ){
((Gluco2::SimpSolver*)s)->prelocate(var_num);
}
#else
/**Function*************************************************************
......@@ -721,6 +726,10 @@ void bmcg2_sat_solver_mark_cone(bmcg2_sat_solver* s, int var)
((Gluco2::Solver*)s)->sat_solver_mark_cone(var);
}
void bmcg2_sat_solver_prelocate( bmcg2_sat_solver * s, int var_num ){
((Gluco2::Solver*)s)->prelocate(var_num);
}
#endif
......
......@@ -103,6 +103,7 @@ extern void bmcg2_sat_solver_set_jftr( bmcg2_sat_solver * s, int jf
extern void bmcg2_sat_solver_set_var_fanin_lit( bmcg2_sat_solver * s, int var, int lit0, int lit1 );
extern void bmcg2_sat_solver_start_new_round( bmcg2_sat_solver * s );
extern void bmcg2_sat_solver_mark_cone( bmcg2_sat_solver * s, int var );
extern void bmcg2_sat_solver_prelocate( bmcg2_sat_solver * s, int var_num );
extern void Glucose2_SolveCnf( char * pFilename, Glucose2_Pars * pPars );
extern int Glucose2_SolveAig( Gia_Man_t * p, Glucose2_Pars * pPars );
......
......@@ -2,5 +2,6 @@
#define Glucose_CGlucose_h
#define CGLUCOSE_EXP 1
#include "sat/glucose2/Heap2.h"
#endif
\ No newline at end of file
......@@ -37,7 +37,10 @@ inline Lit Solver::gateJustFanin(Var v) const {
if(val1 == l_True)
return ~getFaninLit0(v);
//assert( jdata[v].act_fanin == activity[getFaninVar0(v)] || jdata[v].act_fanin == activity[getFaninVar1(v)] );
//assert( jdata[v].act_fanin == (jdata[v].adir? activity[getFaninVar1(v)]: activity[getFaninVar0(v)]) );
return maxActiveLit( ~getFaninLit0(v), ~getFaninLit1(v) );
//return jdata[v].adir? ~getFaninLit1(v): ~getFaninLit0(v);
} else { // xor scope
// should be handled by conflict analysis before entering here
assert( value(v) == l_Undef || value(v) != l_False || val0 == val1 );
......@@ -54,60 +57,68 @@ inline Lit Solver::gateJustFanin(Var v) const {
// a var should at most be enqueued one time
inline void Solver::pushJustQueue(Var v){
inline void Solver::pushJustQueue(Var v, int index){
assert(v < nVars());
assert(isJReason(v));
if( ! isRoundWatch(v) )\
return;
var2NodeData[v].now = true;
jdata[v].act_fanin = activity[getFaninVar0(v)] > activity[getFaninVar1(v)]? activity[getFaninVar0(v)]: activity[getFaninVar1(v)];
jdata[v].now = true;
jheap.update(v);
if( activity[getFaninVar1(v)] > activity[getFaninVar0(v)] )
jheap.update( JustKey( activity[getFaninVar1(v)], v, index ) );
else
jheap.update( JustKey( activity[getFaninVar0(v)], v, index ) );
}
inline void Solver::uncheckedEnqueue2(Lit p, CRef from)
{
//assert( isRoundWatch(var(p)) ); // inplace sorting guarantee this
assert(value(p) == l_Undef);
assigns[var(p)] = lbool(!sign(p));
vardata[var(p)] = mkVarData(from, decisionLevel());
trail.push_(p);
}
inline void Solver::ResetJustData(bool fCleanMemory){
jstack.shrink_( jstack.size() );
jheap .clear(fCleanMemory);
jhead = 0;
jheap .clear_( fCleanMemory );
}
inline Lit Solver::pickJustLit( Var& j_reason ){
inline Lit Solver::pickJustLit( int& index ){
Var next = var_Undef;
Lit jlit = lit_Undef;
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);
for( ; jhead < trail.size() ; jhead++ ){
Var x = var(trail[jhead]);
if( !decisionLevel() && !isRoundWatch(x) ) continue;
if( isJReason(x) && l_Undef == value( getFaninVar0(x) ) && l_Undef == value( getFaninVar1(x) ) )
pushJustQueue(x,jhead);
}
jstack.shrink_( jstack.size() );
while( ! jheap.empty() && var_Undef != (next = jheap.removeMin()) ){
if( ! jdata[next].now )
while( ! jheap.empty() ){
next = jheap.removeMin(index);
if( ! var2NodeData[next].now )
continue;
assert(isJReason(next));
if( lit_Undef != (jlit = gateJustFanin(next)) )
if( lit_Undef != (jlit = gateJustFanin(next)) ){
//assert( jheap.prev.key() == activity[getFaninVar0(next)] || jheap.prev.key() == activity[getFaninVar1(next)] );
break;
gateAddJwatch(next);
}
gateAddJwatch(next,index);
}
j_reason = next;
return jlit;
}
inline void Solver::gateAddJwatch(Var v){
inline void Solver::gateAddJwatch(Var v,int index){
assert(v < nVars());
assert(isJReason(v));
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);
......@@ -119,73 +130,38 @@ inline void Solver::gateAddJwatch(Var v){
assert( isAND(v) || (l_Undef != val0 && l_Undef != val1) );
if( (val0 == l_False && val1 == l_False) || !isAND(v) ){
addJwatch(vardata[var0].level < vardata[var1].level? var0: var1, v);
addJwatch(vardata[var0].level < vardata[var1].level? var0: var1, v, index);
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);
addJwatch(l_False == val0? var0: var1, v, index);
member = next;
}
return;
}
inline void Solver::updateJustActivity( Var v ){
for(Lit lfo = var2Fanout0[ v ]; lfo != toLit(~0); lfo = var2FanoutN[ toInt(lfo) ] ){
if( ! var2NodeData[v].sort )
inplace_sort(v);
int nFanout = 0;
for(Lit lfo = var2Fanout0[ v ]; nFanout < var2NodeData[v].sort; lfo = var2FanoutN[ toInt(lfo) ], nFanout ++ ){
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);
if( var2NodeData[x].now && jheap.inHeap(x) ){
if( activity[getFaninVar1(x)] > activity[getFaninVar0(x)] )
jheap.update( JustKey( activity[getFaninVar1(x)], x, jheap.data_attr(x) ) );
else
jheap.update( JustKey( activity[getFaninVar0(x)], x, jheap.data_attr(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;
inline void Solver::addJwatch( Var host, Var member, int index ){
assert(level(host) >= level(member));
jnext[index] = jlevel[level(host)];
jlevel[level(host)] = index;
}
/*
* circuit propagation
*/
......@@ -270,23 +246,12 @@ 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;
var2NodeData[ v ].lit0 = lit1;
var2NodeData[ v ].lit1 = 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 );
......@@ -301,22 +266,19 @@ inline void Solver::setVarFaninLits( Var v, Lit lit1, Lit lit2 ){
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 ];
Lit lit0 = var2NodeData[ v ].lit0;
Lit lit1 = var2NodeData[ v ].lit1;
assert( toLit(~0) == lit0 || var(lit0) < nVars() );
assert( toLit(~0) == lit1 || var(lit1) < nVars() );
lit0.x = lit1.x = 0; // suppress the warning - alanmi
return toLit(~0) != var2FaninLits[ (v<<1) + 0 ] && toLit(~0) != var2FaninLits[ (v<<1) + 1 ];
return toLit(~0) != var2NodeData[ v ].lit0 && toLit(~0) != var2NodeData[ v ].lit1;
}
// 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) )
if( justUsage() < 2 )
return CRef_Undef;
if( ! isRoundWatch(var(p)) )
......@@ -337,10 +299,12 @@ inline CRef Solver::gatePropagate( Lit p ){
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( ! var2NodeData[var(p)].sort )
inplace_sort(var(p));
int nFanout = 0;
for( Lit lfo = var2Fanout0[ var(p) ]; nFanout < var2NodeData[var(p)].sort; lfo = var2FanoutN[ toInt(lfo) ], nFanout ++ )
{
if( CRef_Undef != (stats = gatePropagateCheckFanout( var(p), lfo )) ){
confl = stats;
if( l_True == value(var(lfo)) )
......@@ -363,8 +327,8 @@ inline CRef Solver::gatePropagateCheckFanout( Var v, Lit lfo ){
if( l_True == value(var(lfo)) )
return Var2CRef(var(lfo));
jwatch[var(lfo)].header.dir = sign(lfo);
uncheckedEnqueue(~mkLit(var(lfo)), Var2CRef( var(lfo) ) );
var2NodeData[var(lfo)].dir = sign(lfo);
uncheckedEnqueue2(~mkLit(var(lfo)), Var2CRef( var(lfo) ) );
} else {
assert( l_True == value(faninLit) );
......@@ -381,11 +345,11 @@ inline CRef Solver::gatePropagateCheckFanout( Var v, Lit lfo ){
if( l_True == value(faninLitP) )
return Var2CRef(var(lfo));
uncheckedEnqueue( ~faninLitP, Var2CRef( var(lfo) ) );
uncheckedEnqueue2( ~faninLitP, Var2CRef( var(lfo) ) );
}
else
if( l_True == value(faninLitP) )
uncheckedEnqueue( mkLit(var(lfo)), Var2CRef( var(lfo) ) );
uncheckedEnqueue2( mkLit(var(lfo)), Var2CRef( var(lfo) ) );
}
} else { // xor scope
// check value of the other fanin
......@@ -400,10 +364,10 @@ inline CRef Solver::gatePropagateCheckFanout( Var v, Lit lfo ){
return CRef_Undef;
else
if( l_Undef == val1 )
uncheckedEnqueue( ~faninLitP ^ ( (l_True == val0) ^ (l_True == valo) ), Var2CRef( var(lfo) ) );
uncheckedEnqueue2( ~faninLitP ^ ( (l_True == val0) ^ (l_True == valo) ), Var2CRef( var(lfo) ) );
else
if( l_Undef == valo )
uncheckedEnqueue( ~mkLit( var(lfo), (l_True == val0) ^ (l_True == val1) ), Var2CRef( var(lfo) ) );
uncheckedEnqueue2( ~mkLit( var(lfo), (l_True == val0) ^ (l_True == val1) ), Var2CRef( var(lfo) ) );
else
if( l_False == (valo ^ (val0 == val1)) )
return Var2CRef(var(lfo));
......@@ -424,19 +388,19 @@ inline CRef Solver::gatePropagateCheckThis( Var v ){
return CRef_Undef;
if( l_True == value(getFaninLit0(v)) )
uncheckedEnqueue(~getFaninLit1( v ), Var2CRef( v ) );
uncheckedEnqueue2(~getFaninLit1( v ), Var2CRef( v ) );
if( l_True == value(getFaninLit1(v)) )
uncheckedEnqueue(~getFaninLit0( v ), Var2CRef( v ) );
uncheckedEnqueue2(~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 ) );
uncheckedEnqueue2( getFaninLit0( v ), Var2CRef( v ) );
if( l_Undef == value( getFaninLit1( v )) )
uncheckedEnqueue( getFaninLit1( v ), Var2CRef( v ) );
uncheckedEnqueue2( getFaninLit1( v ), Var2CRef( v ) );
}
} else { // xor scope
......@@ -447,10 +411,10 @@ inline CRef Solver::gatePropagateCheckThis( Var v ){
if( l_Undef == val0 && l_Undef == val1 )
return CRef_Undef;
if( l_Undef == val0 )
uncheckedEnqueue(~getFaninLit0( v ) ^ ( (l_True == val1) ^ (l_True == valo) ), Var2CRef( v ) );
uncheckedEnqueue2(~getFaninLit0( v ) ^ ( (l_True == val1) ^ (l_True == valo) ), Var2CRef( v ) );
else
if( l_Undef == val1 )
uncheckedEnqueue(~getFaninLit1( v ) ^ ( (l_True == val0) ^ (l_True == valo) ), Var2CRef( v ) );
uncheckedEnqueue2(~getFaninLit1( v ) ^ ( (l_True == val0) ^ (l_True == valo) ), Var2CRef( v ) );
else
if( l_False == (valo ^ (val0 == val1)) )
return Var2CRef(v);
......@@ -530,13 +494,7 @@ inline CRef Solver::interpret( Var v, Var t )
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 );
c[1] = var2NodeData[v].dir ? getFaninLit1( v ): getFaninLit0( v );
} else {
setItpcSize(3);
Clause& c = ca[itpc];
......@@ -594,11 +552,65 @@ inline void Solver::markCone( Var v ){
if( var2TravId[v] >= travId )
return;
var2TravId[v] = travId;
var2NodeData[v].sort = 0;
Var var0, var1;
var0 = getFaninVar0(v);
var1 = getFaninVar1(v);
if( !isTwoFanin(v) )
return;
markCone( getFaninVar0(v) );
markCone( getFaninVar1(v) );
markCone( var0 );
markCone( var1 );
}
inline void Solver::inplace_sort( Var v ){
Lit w, next, prev;
prev= var2Fanout0[v];
if( toLit(~0) == prev ) return;
if( isRoundWatch(var(prev)) )
var2NodeData[v].sort ++ ;
if( toLit(~0) == (w = var2FanoutN[toInt(prev)]) )
return;
while( toLit(~0) != w ){
next = var2FanoutN[toInt(w)];
if( isRoundWatch(var(w)) )
var2NodeData[v].sort ++ ;
if( isRoundWatch(var(w)) && !isRoundWatch(var(prev)) ){
var2FanoutN[toInt(w)] = var2Fanout0[v];
var2Fanout0[v] = w;
var2FanoutN[toInt(prev)] = next;
} else
prev = w;
w = next;
}
}
inline void Solver::prelocate( int base_var_num ){
if( justUsage() ){
var2FanoutN .prelocate( base_var_num << 1 );
var2Fanout0 .prelocate( base_var_num );
var2NodeData.prelocate( base_var_num );
var2TravId .prelocate( base_var_num );
jheap .prelocate( base_var_num );
jlevel .prelocate( base_var_num );
jnext .prelocate( base_var_num );
}
watches .prelocate( base_var_num << 1 );
watchesBin .prelocate( base_var_num << 1 );
decision .prelocate( base_var_num );
trail .prelocate( base_var_num );
assigns .prelocate( base_var_num );
vardata .prelocate( base_var_num );
activity .prelocate( base_var_num );
seen .prelocate( base_var_num );
permDiff .prelocate( base_var_num );
polarity .prelocate( base_var_num );
}
};
......
......@@ -151,7 +151,8 @@ Solver::Solver() :
, nbVarsInitialFormula(INT32_MAX)
#ifdef CGLUCOSE_EXP
, jheap (JustOrderLt(this))
//, jheap (JustOrderLt(this))
, jheap (JustOrderLt2(this))
#endif
{
MYFLAG=0;
......@@ -175,6 +176,7 @@ Solver::Solver() :
}
#ifdef CGLUCOSE_EXP
jhead= 0;
jftr = 0;
travId = 0;
travId_prev = 0;
......@@ -233,18 +235,28 @@ Var Solver::newVar(bool sign, bool dvar)
polarity .push(sign);
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());
//jdata .push(mkJustData(false));
//jwatch .push(mkJustWatch());
jlevel .push(-1);
jnext .push(-1);
var2FanoutN.growTo( nVars()<<1, toLit(~0));
//var2FanoutP.growTo( nVars()<<1, toLit(~0));
var2Fanout0.growTo( nVars(), toLit(~0));
var2NodeData.growTo( nVars(), mkNodeData());
var2TravId .growTo( nVars(), 0);
}
setDecisionVar(v, dvar, false);
} else
setDecisionVar(v, dvar);
#else
setDecisionVar(v, dvar);
#endif
return v;
......@@ -283,7 +295,7 @@ bool Solver::addClause_(vec<Lit>& ps)
return true;
else if (value(ps[i]) != l_False && ps[i] != p)
ps[j++] = p = ps[i];
ps.shrink(i - j);
ps.shrink_(i - j);
if ( 0 ) {
for ( int i = 0; i < ps.size(); i++ )
......@@ -502,31 +514,45 @@ void Solver::minimisationWithBinaryResolution(vec<Lit> &out_learnt) {
void Solver::cancelUntil(int level) {
if (decisionLevel() > level){
#ifdef CGLUCOSE_EXP
if( 0 < justUsage() ){
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
Var x = var(trail[c]);
assigns [x] = l_Undef;
if (phase_saving > 1 || ((phase_saving == 1) && c > trail_lim.last()))
polarity[x] = sign(trail[c]);
insertVarOrder(x); }
qhead = trail_lim[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);
gateClearJwatch(x, level);
jdata[x].now = false;
var2NodeData[x].now = false;
}
for (int l = decisionLevel(); l > level; l -- ){
int q = jlevel[l], k;
jlevel[l] = -1;
while( -1 != q ){
k = jnext[q];
jnext[q] = -1;
Var v = var(trail[q]);
if( Solver::level(v) <= level ){
pushJustQueue(v,q);
}
q = k;
}
}
} else
#endif
for (int c = trail.size()-1; c >= trail_lim[level]; c--){
Var x = var(trail[c]);
assigns [x] = l_Undef;
if (phase_saving > 1 || ((phase_saving == 1) && c > trail_lim.last()))
polarity[x] = sign(trail[c]);
insertVarOrder(x);
}
jhead = qhead = trail_lim[level];
trail.shrink_(trail.size() - trail_lim[level]);
trail_lim.shrink_(trail_lim.size() - level);
jstack.shrink_( jstack.size() );
}
}
......@@ -577,6 +603,7 @@ 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();
heap_rescale = 0;
int pathC = 0;
Lit p = lit_Undef;
......@@ -586,6 +613,7 @@ 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;
analyze_toclear.shrink_( analyze_toclear.size() );
do{
assert(confl != CRef_Undef); // (otherwise should be UIP)
......@@ -624,14 +652,19 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
Lit q = c[j];
bool fBump = 0;
if (!seen[var(q)] && level(var(q)) > 0){
if(!isSelector(var(q)))
if(!isSelector(var(q))){
fBump = 1;
varBumpActivity(var(q));
}
seen[var(q)] = 1;
if (level(var(q)) >= decisionLevel()) {
if( fBump )
analyze_toclear.push(q);
pathC++;
#ifdef UPDATEVARACTIVITY
#ifdef UPDATEVARACTIVITY
// UPDATEVARACTIVITY trick (see competition'09 companion paper)
#ifdef CGLUCOSE_EXP
if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef)
......@@ -641,7 +674,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
if(!isSelector(var(q)) && (reason(var(q))!= CRef_Undef) && ca[reason(var(q))].learnt())
lastDecisionLevel.push(q);
#endif
#endif
#endif
} else {
if(isSelector(var(q))) {
......@@ -667,10 +700,15 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
//
int i, j;
for(i = 0;i<selectors.size();i++)
out_learnt.push(selectors[i]);
for(i = 0;i<selectors.size();i++) out_learnt.push(selectors[i]);
#ifdef CGLUCOSE_EXP
for(i = 0;i<out_learnt.size();i++)
analyze_toclear.push(out_learnt[i]);
#else
out_learnt.copyTo_(analyze_toclear);
#endif
if (ccmin_mode == 2){
uint32_t abstract_level = 0;
for (i = 1; i < out_learnt.size(); i++)
......@@ -752,26 +790,48 @@ 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]));
#endif
//assert( ca[reason(var(t))].learnt() );
if(ca[reason(var(t))].lbd()<lbd)
varBumpActivity(var(t));
}
lastDecisionLevel.clear();
lastDecisionLevel.shrink_( lastDecisionLevel.size() );
}
#endif
if( justUsage() ){
if( heap_rescale )
{
for (j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;
analyze_toclear.shrink_( analyze_toclear.size() );
for (j = 0; j < jheap.size(); j++){
Var x = jheap[j];
if( var2NodeData[x].now )
analyze_toclear.push(mkLit(x));
}
for (j = 0; j < analyze_toclear.size(); j++){
Var x = var(analyze_toclear[j]);
// jdata[x].act_fanin = activity[getFaninVar0(x)] > activity[getFaninVar1(x)]? activity[getFaninVar0(x)]: activity[getFaninVar1(x)];
// jheap.update(x);
if( activity[getFaninVar1(x)] > activity[getFaninVar0(x)] )
jheap.update( JustKey( activity[getFaninVar1(x)], x, jheap.data_attr(x) ) );
else
jheap.update( JustKey( activity[getFaninVar0(x)], x, jheap.data_attr(x) ) );
}
} else {
for (j = 0; j < analyze_toclear.size(); j++)
{
seen[var(analyze_toclear[j])] = 0;
updateJustActivity(var(analyze_toclear[j]));
}
}
} else
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;
}
......@@ -779,7 +839,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt,vec<Lit>&selectors, int& o
// visiting literals at levels that cannot be removed later.
bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
{
analyze_stack.clear(); analyze_stack.push(p);
analyze_stack.shrink_( analyze_stack.size() ); analyze_stack.push(p);
int top = analyze_toclear.size();
while (analyze_stack.size() > 0){
assert(reason(var(analyze_stack.last())) != CRef_Undef);
......@@ -826,7 +886,7 @@ bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
|________________________________________________________________________________________________@*/
void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
{
out_conflict.clear();
out_conflict.shrink_( out_conflict.size() );
out_conflict.push(p);
if (decisionLevel() == 0)
......@@ -863,17 +923,12 @@ void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
void Solver::uncheckedEnqueue(Lit p, CRef from)
{
if( justUsage() && !isRoundWatch(var(p)) )
return;
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( isJReason(var(p)) );
if( isJReason(var(p)) && l_Undef == value( getFaninVar0(var(p)) ) && l_Undef == value( getFaninVar1(var(p)) ) )
jstack.push(var(p));
}
#endif
}
......@@ -905,9 +960,7 @@ CRef Solver::propagate()
CRef stats;
if( CRef_Undef != (stats = gatePropagate(p)) ){
confl = stats;
if( l_True == value(var(p)) )
return confl;
if( l_True == value(var(p)) ) return confl;
}
}
#endif
......@@ -995,7 +1048,7 @@ CRef Solver::propagate()
}
NextClause:;
}
ws.shrink(i - j);
ws.shrink_(i - j);
}
propagations += num_props;
simpDB_props -= num_props;
......@@ -1065,7 +1118,7 @@ void Solver::reduceDB()
learnts[j++] = learnts[i];
}
}
learnts.shrink(i - j);
learnts.shrink_(i - j);
checkGarbage();
}
......@@ -1080,7 +1133,7 @@ void Solver::removeSatisfied(vec<CRef>& cs)
else
cs[j++] = cs[i];
}
cs.shrink(i - j);
cs.shrink_(i - j);
}
......@@ -1119,6 +1172,9 @@ bool Solver::simplify()
checkGarbage();
#ifdef CGLUCOSE_EXP
if( !justUsage() )
#endif
rebuildOrderHeap();
simpDB_assigns = nAssigns();
......@@ -1185,8 +1241,8 @@ lbool Solver::search(int nof_conflicts)
if(!blocked) {lastblockatrestart=starts;nbstopsrestartssame++;blocked=true;}
}
learnt_clause.clear();
selectors.clear();
learnt_clause.shrink_( learnt_clause.size() );
selectors .shrink_( selectors.size() );
analyze(confl, learnt_clause, selectors,backtrack_level,nblevels,szWoutSelectors);
lbdQueue.push(nblevels);
......@@ -1236,7 +1292,6 @@ lbool Solver::search(int nof_conflicts)
// Perform clause database reduction !
if(conflicts>=curRestart* nbclausesbeforereduce)
{
assert(learnts.size()>0);
curRestart = (conflicts/ nbclausesbeforereduce)+1;
reduceDB();
......@@ -1250,10 +1305,10 @@ lbool Solver::search(int nof_conflicts)
if (value(p) == l_True){
// Dummy decision level:
newDecisionLevel();
}else if (value(p) == l_False){
} else if (value(p) == l_False){
analyzeFinal(~p, conflict);
return l_False;
}else{
} else {
next = p;
break;
}
......@@ -1261,15 +1316,17 @@ lbool Solver::search(int nof_conflicts)
#ifdef CGLUCOSE_EXP
// pick from JustQueue
Var j_reason = -1;
if (0 < justUsage())
if ( next == lit_Undef ){
int index = -1;
decisions++;
next = pickJustLit( j_reason );
next = pickJustLit( index );
if(next == lit_Undef)
return l_True;
addJwatch(var(next), j_reason);
//addJwatch(var(next), j_reason);
jnext[index] = jlevel[decisionLevel()+1];
jlevel[decisionLevel()+1] = index;
}
#endif
......@@ -1335,21 +1392,13 @@ 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( isJReason(v) )
jstack.push(v);
}
#endif
if(incremental && certifiedUNSAT) {
printf("Can not use incremental and certified unsat in the same time\n");
exit(-1);
}
JustModel.shrink_(JustModel.size());
model.shrink_(model.size());
conflict.shrink_(conflict.size());
if (!ok){
travId_prev = travId;
......@@ -1403,6 +1452,7 @@ printf("c ==================================[ Search Statistics (every %6d confl
if (status == l_True){
if( justUsage() ){
JustModel.shrink_(JustModel.size());
assert(jheap.empty());
//JustModel.growTo(nVars());
int i = 0, j = 0;
......@@ -1413,6 +1463,7 @@ printf("c ==================================[ Search Statistics (every %6d confl
JustModel[0] = toLit(j);
} else {
// Extend & copy model:
model.shrink_(model.size());
model.growTo(nVars());
for (int i = 0; i < trail.size(); i++) model[ var(trail[i]) ] = value(var(trail[i]));
}
......@@ -1669,16 +1720,19 @@ void Solver::reset()
ResetJustData(false);
jwatch.shrink_(jwatch.size());
jdata .shrink_(jdata .size());
//jwatch.shrink_(jwatch.size());
//jdata .shrink_(jdata .size());
jhead = 0;
travId = 0;
travId_prev = 0;
var2TravId .shrink_(var2TravId.size());
JustModel .shrink_(JustModel .size());
jlevel .shrink_(jlevel.size());
jnext .shrink_(jnext.size());
var2FaninLits.shrink_(var2FaninLits.size());
//var2FaninLits.shrink_(var2FaninLits.size());
var2NodeData .shrink_(var2NodeData .size());
var2Fanout0 .shrink_(var2Fanout0 .size());
var2FanoutN .shrink_(var2FanoutN .size());
//var2FanoutP.clear(false);
......
......@@ -85,7 +85,7 @@ class Heap {
void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
void prelocate (int ext_cap){ indices.prelocate(ext_cap); }
// Safe variant of insert/decrease/increase:
void update(int n)
......@@ -143,6 +143,15 @@ class Heap {
indices[heap[i]] = -1;
heap.clear(dealloc);
}
void clear_(bool dealloc = false)
{
int i;
for (i = 0; i < heap.size(); i++)
indices[heap[i]] = -1;
if( ! dealloc ) heap.shrink_( heap.size() );
else heap.clear(true);
}
};
......
/******************************************************************************************[Heap.h]
Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
Copyright (c) 2007-2010, Niklas Sorensson
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************************************/
#ifndef Glucose_Heap2_h
#define Glucose_Heap2_h
#include "sat/glucose2/Vec.h"
ABC_NAMESPACE_CXX_HEADER_START
namespace Gluco2 {
//=================================================================================================
// A heap implementation with support for decrease/increase key.
template<class Comp, class Obj>
class Heap2 {
Comp lt; // The heap is a minimum-heap with respect to this comparator
vec<Obj> heap; // Heap of integers
vec<int> indices; // Each integers position (index) in the Heap
// Index "traversal" functions
static inline int left (int i) { return i*2+1; }
static inline int right (int i) { return (i+1)*2; }
static inline int parent(int i) { return (i-1) >> 1; }
inline int data (int i) const { return heap[i].data();}
void percolateUp(int i)
{
Obj x = heap[i];
int p = parent(i);
while (i != 0 && lt(x, heap[p])){
heap[i] = heap[p];
indices[data(p)] = i;
i = p;
p = parent(p);
}
heap [i] = x;
indices[x.data()] = i;
}
void percolateDown(int i)
{
Obj x = heap[i];
while (left(i) < heap.size()){
int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
if (!lt(heap[child], x)) break;
heap[i] = heap[child];
indices[data(i)] = i;
i = child;
}
heap [i] = x;
indices[x.data()] = i;
}
public:
Heap2(const Comp& c) : lt(c) { }
int size () const { return heap.size(); }
bool empty () const { return heap.size() == 0; }
bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
int operator[](int index) const { assert(index < heap.size()); return heap[index].data(); }
void decrease (int n) { assert(inHeap(n)); percolateUp (indices[n]); }
void increase (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
void prelocate (int ext_cap){ indices.prelocate(ext_cap); }
int data_attr (int n) const { return heap[indices[n]].attr(); }
// Safe variant of insert/decrease/increase:
void update(const Obj& x)
{
int n = x.data();
if (!inHeap(n))
insert(x);
else {
heap[indices[x.data()]] = x;
percolateUp(indices[n]);
percolateDown(indices[n]); }
}
void insert(const Obj& x)
{
int n = x.data();
indices.growTo(n+1, -1);
assert(!inHeap(n));
indices[n] = heap.size();
heap.push(x);
percolateUp(indices[n]);
}
//Obj prev;
int removeMin(int& _attr)
{
Obj x = heap[0];
heap[0] = heap.last();
indices[heap[0].data()] = 0;
indices[x.data()]= -1;
heap.pop();
if (heap.size() > 1) percolateDown(0);
//prev = x;
_attr = x.attr();
return x.data();
}
// Rebuild the heap from scratch, using the elements in 'ns':
// void build(vec<int>& ns) {
// int i;
// for (i = 0; i < heap.size(); i++)
// indices[heap[i]] = -1;
// heap.clear();
//
// for (i = 0; i < ns.size(); i++){
// indices[ns[i]] = i;
// heap.push(ns[i]); }
//
// for (i = heap.size() / 2 - 1; i >= 0; i--)
// percolateDown(i);
// }
void clear(bool dealloc = false)
{
int i;
for (i = 0; i < heap.size(); i++)
indices[heap[i].data()] = -1;
heap.clear(dealloc);
}
void clear_(bool dealloc = false)
{
int i;
for (i = 0; i < heap.size(); i++)
indices[heap[i].data()] = -1;
if( ! dealloc ) heap.shrink_( heap.size() );
else heap.clear(true);
}
};
//=================================================================================================
}
ABC_NAMESPACE_CXX_HEADER_END
#endif
......@@ -61,12 +61,25 @@ class SimpSolver : public Solver {
//
bool solve (const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
lbool solveLimited(const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
int solveLimited(int * lit0, int nlits, bool do_simp = false, bool turn_off_simp = false);
bool solve ( bool do_simp = true, bool turn_off_simp = false);
bool solve (Lit p , bool do_simp = true, bool turn_off_simp = false);
bool solve (Lit p, Lit q, bool do_simp = true, bool turn_off_simp = false);
bool solve (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false);
bool eliminate (bool turn_off_elim = false); // Perform variable elimination based simplification.
void prelocate(int base_var_num){
Solver::prelocate(base_var_num);
frozen .prelocate( base_var_num );
eliminated.prelocate( base_var_num );
if (use_simplification){
n_occ .prelocate( base_var_num << 1 );
occurs .prelocate( base_var_num );
touched .prelocate( base_var_num );
elim_heap .prelocate( base_var_num );
}
}
// Memory managment:
//
virtual void reset();
......@@ -199,6 +212,14 @@ inline bool SimpSolver::solve (const vec<Lit>& assumps, bool do_simp, boo
inline lbool SimpSolver::solveLimited (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){
assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); }
inline int SimpSolver::solveLimited(int * lit0, int nlits, bool do_simp, bool turn_off_simp){
assumptions.clear();
for(int i = 0; i < nlits; i ++)
assumptions.push(toLit(lit0[i]));
lbool res = solve_(do_simp, turn_off_simp);
return res == l_True ? 1 : (res == l_False ? -1 : 0);
}
inline void SimpSolver::addVar(Var v) { while (v >= nVars()) newVar(); }
//=================================================================================================
......
......@@ -707,7 +707,7 @@ void SimpSolver::cleanUpClauses()
for (i = j = 0; i < clauses.size(); i++)
if (ca[clauses[i]].mark() == 0)
clauses[j++] = clauses[i];
clauses.shrink(i - j);
clauses.shrink_(i - j);
}
......@@ -760,18 +760,22 @@ void SimpSolver::reset()
Solver::reset();
grow = opt_grow;
asymm_lits = eliminated_vars = bwdsub_assigns = n_touched = 0;
elimclauses.clear(false);
touched.clear(false);
occurs.clear(false);
n_occ.clear(false);
elim_heap.clear(false);
subsumption_queue.clear(false);
frozen.clear(false);
eliminated.clear(false);
vec<Lit> dummy(1,lit_Undef);
ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
bwdsub_tmpunit = ca.alloc(dummy);
remove_satisfied = false;
occurs.clear(false);
touched .shrink_( touched .size() );
n_occ .shrink_( n_occ .size() );
eliminated .shrink_( eliminated .size() );
frozen .shrink_( frozen .size() );
elimclauses .shrink_( elimclauses .size() );
elim_heap .clear_(false);
}
ABC_NAMESPACE_IMPL_END
......@@ -71,6 +71,9 @@ public:
void sat_solver_set_var_fanin_lit(int, int, int);
void sat_solver_start_new_round();
void sat_solver_mark_cone(int);
void sat_solver_set_jftr(int);
int sat_solver_jftr();
void sat_solver_reset();
// Problem specification:
//
......@@ -111,7 +114,7 @@ public:
// Variable mode:
//
void setPolarity (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
void setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
void setDecisionVar (Var v, bool b, bool use_oheap = true); // Declare if a variable should be eligible for selection in the decision heuristic.
// Read state:
//
......@@ -365,38 +368,26 @@ protected:
// 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; }
void uncheckedEnqueue2(Lit p, CRef from = CRef_Undef);
bool heap_rescale;
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) { }
};
void addJwatch( Var host, Var member, int index );
//void delJwatch( Var member );
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
struct NodeData { Lit lit0; Lit lit1; unsigned sort:30; unsigned dir:1; unsigned now:1; };
static inline NodeData mkNodeData(){ NodeData w; w.lit0 = toLit(~0); w.lit1 = toLit(~0); w.sort = 0; w.dir = 0; w.now = 0; return w; }
vec<NodeData> var2NodeData;
//vec<Lit> var2FaninLits; // (~0): undefine
vec<unsigned> var2TravId;
vec<Lit> var2Fanout0, var2FanoutN, var2FanoutP;
vec<Lit> var2Fanout0, var2FanoutN;//, var2FanoutP;
CRef itpc; // the interpreted clause of a gate
void inplace_sort( Var v );
bool isTwoFanin ( Var v ) const ; // this var has two fanins
bool isAND ( Var v ) const { return getFaninVar0(v) < getFaninVar1(v); }
bool isJReason ( Var v ) const { return isTwoFanin(v) && ( l_False == value(v) || (!isAND(v) && l_Undef != value(v)) ); }
Lit getFaninLit0( Var v ) const { return var2FaninLits[ (v<<1) + 0 ]; }
Lit getFaninLit1( Var v ) const { return var2FaninLits[ (v<<1) + 1 ]; }
Lit getFaninLit0( Var v ) const { return var2NodeData[ v ].lit0; }
Lit getFaninLit1( Var v ) const { return var2NodeData[ v ].lit1; }
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)); }
......@@ -406,7 +397,7 @@ protected:
Lit maxActiveLit(Lit lit0, Lit lit1) const { return activity[var(lit0)] < activity[var(lit1)]? lit1: lit0; }
Lit gateJustFanin(Var v) const ; // l_Undef=satisfied, 0/1 = fanin0/fanin1 requires justify
void gateAddJwatch(Var v);
void gateAddJwatch(Var v,int index);
CRef gatePropagateCheck( Var v, Var t );
CRef gatePropagateCheckThis( Var v );
CRef gatePropagateCheckFanout( Var v, Lit lfo );
......@@ -415,9 +406,9 @@ protected:
// directly call by original glucose functions
void updateJustActivity( Var v );
void ResetJustData(bool fCleanMemory);
Lit pickJustLit( Var& j_reason );
Lit pickJustLit( int& index );
void justCheck();
void pushJustQueue(Var v);
void pushJustQueue(Var v, int index);
void restoreJustQueue(int level); // call with cancelUntil
void gateClearJwatch( Var v, int backtrack_level );
......@@ -431,31 +422,58 @@ protected:
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;
unsigned travId_prev, travId;
//Heap<JustOrderLt> jheap;
int jhead;
struct JustKey {
typedef double Key;
typedef Var Data;
typedef int Attr;
Key _key;
Data _data;
Attr _attr;
Data data() const { return _data; }
Key key() const { return _key; }
Attr attr() const { return _attr; }
JustKey():_key(0),_data(0),_attr(0){}
JustKey( const Key& nkey, const Data& ndata, const Attr& nattr ): _key(nkey), _data(ndata), _attr(nattr) {}
};
struct JustOrderLt2 {
const Solver * pS;
bool operator () (const JustKey& x, const JustKey& y) const {
if( x.key() != y.key() ) return x.key() > y.key();
if( pS->level( x.data() ) != pS->level( y.data() ) )
return pS->level( x.data() ) < pS->level( y.data() );
return x.data() > y.data();
}
JustOrderLt2(const Solver * _pS) : pS(_pS) { }
};
Heap2<JustOrderLt2, JustKey> jheap;
vec<int> jlevel;
vec<int> jnext;
public:
void prelocate( int var_num );
void setVarFaninLits( Var v, Lit lit1, Lit lit2 );
void setVarFaninLits( int v, int lit1, int lit2 ){ setVarFaninLits( Var(v), toLit(lit1), toLit(lit2) ); }
//void delVarFaninLits( Var v);
int setNewRound(){ return travId ++ ; }
void setNewRound(){ travId ++ ; }
void markCone( Var v );
void setJust( int njftr ){ jftr = njftr; }
bool isRoundWatch( Var v ) const { return travId==var2TravId[v]; }
void justReset(){ jftr = 0; reset(); }
const JustData& getJustData(int v) const { return jdata[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;}
//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 ;
int solveLimited( int * , int nlits );
};
......@@ -466,32 +484,26 @@ inline CRef Solver::reason(Var x) const { return vardata[x].reason; }
inline int Solver::level (Var x) const { return vardata[x].level; }
inline void Solver::insertVarOrder(Var x) {
if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x); }
#ifdef CGLUCOSE_EXP
if (!justUsage() && !order_heap.inHeap(x) && decision[x]) order_heap.insert(x);
#else
if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x);
#endif
}
inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); }
inline void Solver::varBumpActivity(Var v) { varBumpActivity(v, var_inc); }
inline void Solver::varBumpActivity(Var v, double inc) {
if ( (activity[v] += inc) > 1e100 ) {
heap_rescale = 1;
// 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))
if (!justUsage() && order_heap.inHeap(v))
order_heap.decrease(v);
#ifdef CGLUCOSE_EXP
if( justUsage() )
updateJustActivity(v);
#endif
}
inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); }
......@@ -550,13 +562,13 @@ inline int Solver::nVars () const { return vardata.size(); }
inline int Solver::nFreeVars () const { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
inline int * Solver::getCex () const { return (int*) &JustModel[0]; }
inline void Solver::setPolarity (Var v, bool b) { polarity[v] = b; }
inline void Solver::setDecisionVar(Var v, bool b)
inline void Solver::setDecisionVar(Var v, bool b, bool use_oheap)
{
if ( b && !decision[v]) dec_vars++;
else if (!b && decision[v]) dec_vars--;
decision[v] = b;
insertVarOrder(v);
if( use_oheap ) insertVarOrder(v);
}
inline void Solver::setConfBudget(int64_t x){ conflict_budget = conflicts + x; }
inline void Solver::setPropBudget(int64_t x){ propagation_budget = propagations + x; }
......@@ -589,7 +601,16 @@ inline void Solver::addVar(Var v) { while (v >= nVars()) newVar(); }
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); }
inline void Solver::sat_solver_set_jftr( int njftr ){ setJust(njftr); }
inline int Solver::sat_solver_jftr(){ return jftr; }
inline void Solver::sat_solver_reset(){ justReset(); }
inline int Solver::solveLimited( int * lit0, int nlits ){
assumptions.clear();
for(int i = 0; i < nlits; i ++)
assumptions.push(toLit(lit0[i]));
lbool res = solve_();
return res == l_True ? 1 : (res == l_False ? -1 : 0);
}
//=================================================================================================
// Debug etc:
......
......@@ -298,6 +298,7 @@ class OccLists
OccLists(const Deleted& d) : deleted(d) {}
void init (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); }
void prelocate (const int num){ occs.prelocate(num); dirty.prelocate(num); }
// Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
Vec& operator[](const Idx& idx){ return occs[toInt(idx)]; }
Vec& lookup (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; }
......@@ -332,7 +333,7 @@ void OccLists<Idx,Vec,Deleted>::cleanAll()
// Dirties may contain duplicates so check here if a variable is already cleaned:
if (dirty[toInt(dirties[i])])
clean(dirties[i]);
dirties.clear();
dirties.shrink_( dirties.size() );
}
......@@ -344,7 +345,7 @@ void OccLists<Idx,Vec,Deleted>::clean(const Idx& idx)
for (i = j = 0; i < vec.size(); i++)
if (!deleted(vec[i]))
vec[j++] = vec[i];
vec.shrink(i - j);
vec.shrink_(i - j);
dirty[toInt(idx)] = 0;
}
......
......@@ -67,7 +67,9 @@ public:
void shrink_ (int nelems) { assert(nelems <= sz); sz -= nelems; }
int capacity (void) const { return cap; }
void capacity (int min_cap);
void prelocate(int ext_cap);
void growTo (int size);
void growTo_ (int size);
void growTo (int size, const T& pad);
void clear (bool dealloc = false);
......@@ -90,7 +92,7 @@ public:
// 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.shrink_(copy.size()); 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; }
};
......@@ -103,6 +105,14 @@ void vec<T>::capacity(int min_cap) {
throw OutOfMemoryException();
}
template<class T>
void vec<T>::prelocate(int ext_cap) {
if (cap >= ext_cap) return;
if (ext_cap > INT_MAX || (((data = (T*)::realloc(data, ext_cap * sizeof(T))) == NULL) && errno == ENOMEM))
throw OutOfMemoryException();
cap = ext_cap;
}
template<class T>
void vec<T>::growTo(int size, const T& pad) {
......@@ -121,6 +131,13 @@ void vec<T>::growTo(int size) {
template<class T>
void vec<T>::growTo_(int size) {
if (sz >= size) return;
capacity(size);
sz = size; }
template<class T>
void vec<T>::clear(bool dealloc) {
if (data != NULL){
for (int i = 0; i < sz; i++) data[i].~T();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment