diff options
Diffstat (limited to 'src/sat/glucose2/CGlucoseCore.h')
-rw-r--r-- | src/sat/glucose2/CGlucoseCore.h | 455 |
1 files changed, 206 insertions, 249 deletions
diff --git a/src/sat/glucose2/CGlucoseCore.h b/src/sat/glucose2/CGlucoseCore.h index 3400b114..b558f257 100644 --- a/src/sat/glucose2/CGlucoseCore.h +++ b/src/sat/glucose2/CGlucoseCore.h @@ -13,68 +13,50 @@ 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 int Solver::justUsage() const { return jftr; } 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 + assert(isJReason(v)); - 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); + lbool val0, val1; + val0 = value(getFaninLit0(v)); + val1 = value(getFaninLit1(v)); + + if(isAND(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); + + return maxActiveLit( ~getFaninLit0(v), ~getFaninLit1(v) ); + } else { // xor scope + // should be handled by conflict analysis before entering here + assert( value(v) == l_Undef || value(v) != l_False || val0 == val1 ); + + // both are assigned + if( l_Undef != val0 && l_Undef != val1 ) + return lit_Undef; + + // should be handled by propagation before entering here + assert( l_Undef == val0 && l_Undef == val1 ); + return maxActiveLit( getFaninPlt0(v), getFaninPlt1(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)); + assert(isJReason(v)); if( ! isRoundWatch(v) )\ return; @@ -94,7 +76,7 @@ inline void Solver::ResetJustData(bool 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)) ) @@ -106,13 +88,12 @@ inline Lit Solver::pickJustLit( Var& j_reason ){ if( ! jdata[next].now ) continue; - assert( l_False == value(next) ); + assert(isJReason(next)); if( lit_Undef != (jlit = gateJustFanin(next)) ) break; gateAddJwatch(next); } - j_reason = next; return jlit; } @@ -120,8 +101,7 @@ inline Lit Solver::pickJustLit( Var& j_reason ){ inline void Solver::gateAddJwatch(Var v){ assert(v < nVars()); - assert(isTwoFanin(v)); - assert(value(v) == l_False); // l_True should be handled by propagation + assert(isJReason(v)); if( var_Undef != jwatch[v].prev ) // already in jwatch return; @@ -132,16 +112,13 @@ inline void Solver::gateAddJwatch(Var v){ 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); + val0 = value(getFaninLit0(v)); + val1 = value(getFaninLit1(v)); - assert( l_False == val0 || l_False == val1 ); + assert( !isAND(v) || l_False == val0 || l_False == val1 ); + assert( isAND(v) || (l_Undef != val0 && l_Undef != val1) ); - if(val0 == l_False && val1 == l_False){ + if( (val0 == l_False && val1 == l_False) || !isAND(v) ){ addJwatch(vardata[var0].level < vardata[var1].level? var0: var1, v); return; } @@ -182,7 +159,7 @@ 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[jwatch[host].head].prev = member; jwatch[member].next = jwatch[host].head; jwatch[member].prev = host; @@ -197,12 +174,12 @@ inline void Solver::delJwatch( Var member ){ assert( jwatch[prev].next == member || jwatch[prev].head == member ); if( jwatch[prev].next == member ) - jwatch[prev].next = next; + jwatch[prev].next = next; else - jwatch[prev].head = next; + jwatch[prev].head = next; if( var_Undef != next ) - jwatch[next].prev = prev; + jwatch[next].prev = prev; jwatch[member].prev = var_Undef; jwatch[member].next = var_Undef; @@ -215,17 +192,12 @@ inline void Solver::delJwatch( Var member ){ 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) ) + if( !isJReason(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 ++ ; @@ -235,15 +207,6 @@ inline void Solver::justCheck(){ } 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 ){ @@ -303,6 +266,7 @@ inline void Solver::delVarFaninLits( Var v ){ } **/ inline void Solver::setVarFaninLits( Var v, Lit lit1, Lit lit2 ){ + assert( var(lit1) != var(lit2) ); int mincap = var(lit1) < var(lit2)? var(lit2): var(lit1); mincap = (v < mincap? mincap: v) + 1; @@ -344,6 +308,7 @@ inline bool Solver::isTwoFanin( Var v ) const { Lit lit1 = var2FaninLits[ (v<<1) + 1 ]; 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 ]; } @@ -389,66 +354,106 @@ check_fanout: inline CRef Solver::gatePropagateCheckFanout( Var v, Lit lfo ){ Lit faninLit = sign(lfo)? getFaninLit1(var(lfo)): getFaninLit0(var(lfo)); assert( var(faninLit) == v ); + if( isAND(var(lfo)) ){ + if( l_False == value(faninLit) ) + { + if( l_False == value(var(lfo)) ) + return CRef_Undef; - 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 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(var(lfo)) ) - 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) ) ); + } + } else { // xor scope // 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)); + lbool val0, val1, valo; + val0 = value(faninLit ); + val1 = value(faninLitP); + valo = value(var(lfo)); - uncheckedEnqueue( ~faninLitP, Var2CRef( var(lfo) ) ); - } + if( l_Undef == val1 && l_Undef == valo ) + return CRef_Undef; + else + if( l_Undef == val1 ) + uncheckedEnqueue( ~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) ) ); else - if( l_True == value(faninLitP) ) - uncheckedEnqueue( mkLit(var(lfo)), Var2CRef( var(lfo) ) ); + if( l_False == (valo ^ (val0 == val1)) ) + return 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( isAND(v) ){ + 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_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_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( getFaninLit0( v )) ) + uncheckedEnqueue( getFaninLit0( v ), Var2CRef( v ) ); - if( l_Undef == value( getFaninLit1( v )) ) - uncheckedEnqueue( getFaninLit1( v ), Var2CRef( v ) ); + if( l_Undef == value( getFaninLit1( v )) ) + uncheckedEnqueue( getFaninLit1( v ), Var2CRef( v ) ); + } + } else { // xor scope + lbool val0, val1, valo; + val0 = value(getFaninLit0(v)); + val1 = value(getFaninLit1(v)); + valo = value(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 ) ); + else + if( l_Undef == val1 ) + uncheckedEnqueue(~getFaninLit1( v ) ^ ( (l_True == val0) ^ (l_True == valo) ), Var2CRef( v ) ); + else + if( l_False == (valo ^ (val0 == val1)) ) + return Var2CRef(v); } return confl; @@ -460,97 +465,39 @@ inline CRef Solver::getConfClause( CRef 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(isAND(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); - if( l_True == val0 && l_True == val1 ) - { // conflict - confl = Var2CRef(v); - } + lbool val0 = value(getFaninLit0(v)); + lbool val1 = value(getFaninLit1(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 ) ); + 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 ); } - + } else { // xor scope + setItpcSize(3); + Clause& c = ca[itpc]; + c[0] = mkLit(v, l_True == value(v)); + c[1] = mkLit(getFaninVar0(v), l_True == value(getFaninVar0(v))); + c[2] = mkLit(getFaninVar1(v), l_True == value(getFaninVar1(v))); } + - return confl; + return itpc; } inline void Solver::setItpcSize( int sz ){ @@ -576,43 +523,57 @@ inline CRef Solver::interpret( Var v, Var t ) 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 ); + if( isAND(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 { - setItpcSize(3); - Clause& c = ca[itpc]; - c[0] = mkLit(v); - c[1] = ~getFaninLit0( v ); - c[2] = ~getFaninLit1( v ); + 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 ) + 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); + } } - } 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 { // xor scope + setItpcSize(3); + Clause& c = ca[itpc]; + if( v == t ){ + c[0] = mkLit(v, l_False == value(v)); + c[1] = mkLit(var0, l_True == value(var0)); + c[2] = mkLit(var1, l_True == value(var1)); } else { - setItpcSize(2); - Clause& c = ca[itpc]; - c[0] = t == var0? getFaninLit0( v ): getFaninLit1( v ); - c[1] = ~mkLit(v); + if( t == var0) + c[0] = mkLit(var0, l_False == value(var0)), c[1] = mkLit(var1, l_True == value(var1)); + else + c[1] = mkLit(var0, l_True == value(var0)), c[0] = mkLit(var1, l_False == value(var1)); + c[2] = mkLit(v, l_True == value(v)); } } @@ -640,12 +601,8 @@ inline void Solver::markCone( Var v ){ markCone( getFaninVar1(v) ); } - - }; - ABC_NAMESPACE_IMPL_END - -#endif
\ No newline at end of file +#endif |