/*_________________________________________________________________________________________________ | | analyze : (confl : Constr*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void] | | Description: | Analyze conflict and produce a reason clause. | | Pre-conditions: | * 'out_learnt' is assumed to be cleared. | * Current decision level must be greater than root level. | | Post-conditions: | * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. | | Effect: | Will undo part of the trail, upto but not beyond the assumption of the current decision level. |________________________________________________________________________________________________@*/ void Solver::analyze(Constr* confl, vec<Lit>& out_learnt, int& out_btlevel, Deriv* out_deriv) { vec<char>& seen = analyze_seen; int pathC = 0; Lit p = lit_Undef; vec<Lit> p_reason; seen.growTo(nVars, 0); vec<unsigned> seenForDerivNotLearnt; // Generate conflict clause: // out_learnt.push(); // (leave room for the asserting literal) out_btlevel = 0; do{ assert(confl != NULL); // (otherwise should be UIP) if (doDeriv) { //std::cout << "Adding in analyze(): " << confl->getDeriv() << std::endl; out_deriv->addDeriv(confl->getDeriv()); } p_reason.clear(); confl->calcReason(*this, p, p_reason); for (int j = 0; j < p_reason.size(); j++){ Lit q = p_reason[j]; if (seen[var(q)]) continue; if (level[var(q)] == 0) { if (doDeriv) { out_deriv->addDeriv(var_deriv[var(q)]); seen[var(q)] = 1; seenForDerivNotLearnt.push(var(q)); } } else { seen[var(q)] = 1; varBumpActivity(q); if (level[var(q)] == decisionLevel) pathC++; else { out_learnt.push(~q), out_btlevel = max(out_btlevel, level[var(q)]); } } } // Select next clause to look at: do { p = trail.last(); confl = reason[var(p)]; undoOne(); } while (!seen[var(p)]); pathC--; seen[var(p)] = 0; } while (pathC > 0); out_learnt[0] = ~p; for (int j = 0; j < out_learnt.size(); j++) seen[var(out_learnt[j])] = 0; // ('seen[]' is now cleared) if (doDeriv) for (int j = 0; j < seenForDerivNotLearnt.size(); j++) seen[seenForDerivNotLearnt[j]] = 0; // ('seen[]' is now *really* cleared) /* if (verbosity >= 2){ printf(L_IND"Learnt {", L_ind); for (int i = 0; i < out_learnt.size(); i++) printf(" "L_LIT, L_lit(out_learnt[i])); printf(" } at level %d\n", out_btlevel); } */ /* printf(L_IND"Learnt {", L_ind); for (int i = 0; i < out_learnt.size(); i++) printf(" "L_LIT, L_lit(out_learnt[i])); printf(" } Because of {"); Ancestors foo = out_deriv.getAncestors(); for (Ancestors::iterator itfoo = foo.begin() ; itfoo != foo.end() ; itfoo++) { printf(" %d", *itfoo); } printf(" } at level %d\n", out_btlevel); */ }
/*_________________________________________________________________________________________________ | | analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void] | | Description: | Analyze conflict and produce a reason clause. | | Pre-conditions: | * 'out_learnt' is assumed to be cleared. | * Current decision level must be greater than root level. | | Post-conditions: | * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. | | Effect: | Will undo part of the trail, upto but not beyond the assumption of the current decision level. |________________________________________________________________________________________________@*/ void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel) { int pathC = 0; Lit p = lit_Undef; // Generate conflict clause: // out_learnt.push(); // (leave room for the asserting literal) int index = trail.size() - 1; out_btlevel = 0; do{ assert(confl != NULL); // (otherwise should be UIP) Clause& c = *confl; if (c.learnt()) claBumpActivity(c); for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ Lit q = c[j]; if (!seen[var(q)] && level[var(q)] > 0){ varBumpActivity(var(q)); seen[var(q)] = 1; if (level[var(q)] >= decisionLevel()) pathC++; else{ out_learnt.push(q); if (level[var(q)] > out_btlevel) out_btlevel = level[var(q)]; } } } // Select next clause to look at: while (!seen[var(trail[index--])]); p = trail[index+1]; confl = reason[var(p)]; seen[var(p)] = 0; pathC--; }while (pathC > 0); out_learnt[0] = ~p; // Simplify conflict clause: // int i, j; if (expensive_ccmin){ uint32_t abstract_level = 0; for (i = 1; i < out_learnt.size(); i++) abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict) out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++) if (reason[var(out_learnt[i])] == NULL || !litRedundant(out_learnt[i], abstract_level)) out_learnt[j++] = out_learnt[i]; }else{ out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++){ Clause& c = *reason[var(out_learnt[i])]; for (int k = 1; k < c.size(); k++) if (!seen[var(c[k])] && level[var(c[k])] > 0){ out_learnt[j++] = out_learnt[i]; break; } } } max_literals += out_learnt.size(); out_learnt.shrink(i - j); tot_literals += out_learnt.size(); // Find correct backtrack level: // if (out_learnt.size() == 1) out_btlevel = init_level; else{ int max_i = 1; for (int i = 2; i < out_learnt.size(); i++) if (level[var(out_learnt[i])] > level[var(out_learnt[max_i])]) max_i = i; Lit p = out_learnt[max_i]; out_learnt[max_i] = out_learnt[1]; out_learnt[1] = p; out_btlevel = level[var(p)]; } for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) }
/*_________________________________________________________________________________________________ | | analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void] | | Description: | Analyze conflict and produce a reason clause. | | Pre-conditions: | * 'out_learnt' is assumed to be cleared. | * Current decision level must be greater than root level. | | Post-conditions: | * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. | | Effect: | Will undo part of the trail, upto but not beyond the assumption of the current decision level. |________________________________________________________________________________________________@*/ void Solver::analyze(Clause* _confl, vec<Lit>& out_learnt, int& out_btlevel) { GClause confl = GClause_new(_confl); vec<char>& seen = analyze_seen; int pathC = 0; Lit p = lit_Undef; // Generate conflict clause: // out_learnt.push(); // (leave room for the asserting literal) out_btlevel = 0; int index = trail.size()-1; do{ assert(confl != GClause_NULL); // (otherwise should be UIP) Clause& c = confl.isLit() ? ((*analyze_tmpbin)[1] = confl.lit(), *analyze_tmpbin) : *confl.clause(); if (c.learnt()) claBumpActivity(&c); for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ Lit q = c[j]; if (!seen[var(q)] && level[var(q)] > 0){ varBumpActivity(q); seen[var(q)] = 1; if (level[var(q)] == decisionLevel()) pathC++; else{ out_learnt.push(q); out_btlevel = max(out_btlevel, level[var(q)]); } } } // Select next clause to look at: while (!seen[var(trail[index--])]); p = trail[index+1]; confl = reason[var(p)]; seen[var(p)] = 0; pathC--; }while (pathC > 0); out_learnt[0] = ~p; int i, j; if (expensive_ccmin){ // Simplify conflict clause (a lot): // unsigned int min_level = 0; for (i = 1; i < out_learnt.size(); i++) min_level |= 1 << (level[var(out_learnt[i])] & 31); // (maintain an abstraction of levels involved in conflict) out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++) if (reason[var(out_learnt[i])] == GClause_NULL || !analyze_removable(out_learnt[i], min_level)) out_learnt[j++] = out_learnt[i]; }else{ // Simplify conflict clause (a little): // out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++){ GClause r = reason[var(out_learnt[i])]; if (r == GClause_NULL) out_learnt[j++] = out_learnt[i]; else if (r.isLit()){ Lit q = r.lit(); if (!seen[var(q)] && level[var(q)] != 0) out_learnt[j++] = out_learnt[i]; }else{ Clause& c = *r.clause(); for (int k = 1; k < c.size(); k++) if (!seen[var(c[k])] && level[var(c[k])] != 0){ out_learnt[j++] = out_learnt[i]; break; } } } } stats.max_literals += out_learnt.size(); out_learnt.shrink(i - j); stats.tot_literals += out_learnt.size(); for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) }
/*_________________________________________________________________________________________________ | | analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void] | | Description: | Analyze conflict and produce a reason clause. | | Pre-conditions: | * 'out_learnt' is assumed to be cleared. | * Current decision level must be greater than root level. | | Post-conditions: | * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. | | Effect: | Will undo part of the trail, upto but not beyond the assumption of the current decision level. |________________________________________________________________________________________________@*/ void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel,int &nbl,int &mer) { int pathC = 0; Lit p = lit_Undef; out_learnt.push(); // (leave room for the asserting literal) int index = trail.size() - 1; out_btlevel = 0; do{ assert(confl != NULL); // (otherwise should be UIP) Clause& c = *confl; // The first one has to be SAT if( p != lit_Undef && c.size()==2 && value(c[0])==l_False) { assert(value(c[1])==l_True); Lit tmp = c[0]; c[0] = c[1], c[1] = tmp; } for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ Lit q = c[j]; if (!seen[var(q)] && level[var(q)] > 0){ varBumpActivity(var(q)); seen[var(q)] = 1; if (level[var(q)] >= decisionLevel()){ pathC++; #ifdef UPDATEVARACTIVITY if((reason[var(q)]!=NULL) && (reason[var(q)]->learnt())) lastDecisionLevel.push(q); #endif } else{ out_learnt.push(q); if (level[var(q)] > out_btlevel) out_btlevel = level[var(q)]; } } } // Select next clause to look at: while (!seen[var(trail[index--])]); p = trail[index+1]; confl = reason[var(p)]; seen[var(p)] = 0; pathC--; }while (pathC > 0); out_learnt[0] = ~p; // Simplify conflict clause: // int i, j; if (expensive_ccmin){ uint32_t abstract_level = 0; for (i = 1; i < out_learnt.size(); i++) abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict) out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++) if (reason[var(out_learnt[i])] == NULL || !litRedundant(out_learnt[i], abstract_level)) out_learnt[j++] = out_learnt[i]; }else{ out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++){ Clause& c = *reason[var(out_learnt[i])]; if(c.size()==2 && value(c[0])==l_False) { assert(value(c[1])==l_True); Lit tmp = c[0]; c[0] = c[1], c[1] = tmp; } for (int k = 1; k < c.size(); k++) if (!seen[var(c[k])] && level[var(c[k])] > 0){ out_learnt[j++] = out_learnt[i]; break; } } } max_literals += out_learnt.size(); out_learnt.shrink(i - j); tot_literals += out_learnt.size(); // Find correct backtrack level: // if (out_learnt.size() == 1) out_btlevel = 0; else{ int max_i = 1; for (int i = 2; i < out_learnt.size(); i++) if (level[var(out_learnt[i])] > level[var(out_learnt[max_i])]) max_i = i; Lit p = out_learnt[max_i]; out_learnt[max_i] = out_learnt[1]; out_learnt[1] = p; out_btlevel = level[var(p)]; } nbl = 0;mer = 0; MYFLAG++; for(int i=0;i<out_learnt.size();i++) { int l = level[var(out_learnt[i])]; if (permDiff[l] != MYFLAG) { permDiff[l] = MYFLAG; nbl++; mer +=nbPropagated(l); } } #ifdef UPDATEVARACTIVITY if(lastDecisionLevel.size()>0) { for(int i = 0;i<lastDecisionLevel.size();i++) { if(reason[var(lastDecisionLevel[i])]->activity()<nbl) varBumpActivity(var(lastDecisionLevel[i])); } lastDecisionLevel.clear(); } #endif for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) }
/*_________________________________________________________________________________________________ | | analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&) -> [void] | | Description: | Analyze conflict and produce a reason clause. | | Pre-conditions: | * 'out_learnt' is assumed to be cleared. | * Current decision level must be greater than root level. | | Post-conditions: | * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. | | Effect: | Will undo part of the trail, upto but not beyond the assumption of the current decision level. |________________________________________________________________________________________________@*/ void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel) { int pathC = 0; Lit p = lit_Undef; // Generate conflict clause: // out_learnt.push(); // (leave room for the asserting literal) int index = trail.size() - 1; out_btlevel = 0; do{ Clause& c = *confl; #ifdef __PRINT printf("Explain: "); printClause(c); printf("\n"); #endif if (c.learnt()) claBumpActivity(c); for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){ Lit q = c[j]; if (!seen[var(q)] && level[var(q)] > 0){ #ifdef _MINISAT_DEFAULT_VSS varBumpActivity(var(q)); #endif seen[var(q)] = 1; if (level[var(q)] >= decisionLevel()) { pathC++; }else{ out_learnt.push(q); if (level[var(q)] > out_btlevel) out_btlevel = level[var(q)]; } } } // Select next clause to look at: while (!seen[var(trail[index--])]); p = trail[index+1]; confl = reason[var(p)]; seen[var(p)] = 0; pathC--; } while (pathC > 0); out_learnt[0] = ~p; // Simplify conflict clause: // int i, j; if (expensive_ccmin){ uint32_t abstract_level = 0; for (i = 1; i < out_learnt.size(); i++) abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict) out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++) if (reason[var(out_learnt[i])] == NULL || !litRedundant(out_learnt[i], abstract_level)) out_learnt[j++] = out_learnt[i]; }else{ out_learnt.copyTo(analyze_toclear); for (i = j = 1; i < out_learnt.size(); i++){ Clause& c = *reason[var(out_learnt[i])]; for (int k = 1; k < c.size(); k++) if (!seen[var(c[k])] && level[var(c[k])] > 0){ out_learnt[j++] = out_learnt[i]; break; } } } max_literals += out_learnt.size(); out_learnt.shrink(i - j); tot_literals += out_learnt.size(); // Find correct backtrack level: // if (out_learnt.size() == 1) out_btlevel = 0; else{ int max_i = 1; for (int i = 2; i < out_learnt.size(); i++) if (level[var(out_learnt[i])] > level[var(out_learnt[max_i])]) max_i = i; Lit p = out_learnt[max_i]; out_learnt[max_i] = out_learnt[1]; out_learnt[1] = p; out_btlevel = level[var(p)]; } #ifdef __PRINT printf("Learnt: "); for (int i = 0; i < out_learnt.size(); i++) { printf("%s%d ", sign(out_learnt[i]) ? "-" : "", var(out_learnt[i])); if (value(out_learnt[i]) != l_False) exit(1); } printf("\n"); #endif for (int j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0; // ('seen[]' is now cleared) }