void addRule(BoolView hl, vec<BoolView>& posb, vec<BoolView>& negb) { raw_heads.push(hl); raw_posb.push(); posb.copyTo(raw_posb.last()); raw_negb.push(); negb.copyTo(raw_negb.last()); raw_bl.push(bv_false); }
PTRef Logic::insertTerm(SymRef sym, vec<PTRef>& terms, const char** msg) { PTRef res; if (terms.size() == 0) { if (term_store.cterm_map.contains(sym)) res = term_store.cterm_map[sym]; else { res = term_store.pta.alloc(sym, terms); term_store.cterm_map.insert(sym, res); } } else if (!isBooleanOperator(sym)) { if (sym_store[sym].commutes()) { sort(terms, LessThan_PTRef()); } if (!sym_store[sym].left_assoc() && !sym_store[sym].right_assoc() && !sym_store[sym].chainable() && !sym_store[sym].pairwise() && sym_store[sym].nargs() != terms.size_()) { *msg = e_argnum_mismatch; return PTRef_Undef; } PTLKey k; k.sym = sym; terms.copyTo(k.args); if (term_store.cplx_map.contains(k)) res = term_store.cplx_map[k]; else { res = term_store.pta.alloc(sym, terms); term_store.cplx_map.insert(k, res); } } else { // Boolean operator PTLKey k; k.sym = sym; terms.copyTo(k.args); if (term_store.bool_map.contains(k)) { res = term_store.bool_map[k]; #ifdef SIMPLIFY_DEBUG char* ts = printTerm(res); cerr << "duplicate: " << ts << endl; ::free(ts); #endif } else { res = term_store.pta.alloc(sym, terms); term_store.bool_map.insert(k, res); #ifdef SIMPLIFY_DEBUG char* ts = printTerm(res); cerr << "new: " << ts << endl; ::free(ts); #endif } } return res; }
bool SimpSMTSolver::addSMTClause( const vec<Lit>& smt_clause #ifdef PRODUCE_PROOF , const ipartitions_t in #endif ) { assert( config.sat_preprocess_theory == 0 ); #ifdef PRODUCE_PROOF assert(config.produce_inter == 0 || in != 0); #endif for (int i = 0; i < smt_clause.size(); i++) { Lit e = smt_clause[i]; // Do not add false literals // if ( e->isFalse( ) ) continue; // If a literal is true, the clause is true // if ( e->isTrue( ) ) // return true; // Keep track of atoms seen, as they may // be interface equalities to skip later // if (config.logic == QF_UFIDL || config.logic == QF_UFLRA) // atoms_seen.insert( e ); } vec<Lit> cl_out; // addClause will change the contents, and we don't want that here. smt_clause.copyTo(cl_out); #ifdef PRODUCE_PROOF return addClause(smt_clause, in); #else return addClause(cl_out); #endif }
static void unriffle(vec<Formula>& fs) { vec<Formula> tmp; fs.copyTo(tmp); for (int i = 0; i < fs.size() / 2; i++){ fs[i] = tmp[i*2]; fs[i+fs.size() / 2] = tmp[i*2+1]; } }
lbool Solver::solve(const vec<Lit>& assumps) { //start_time = getRunTime(); model.clear(); conflict.clear(); if (!ok) return false; assumps.copyTo(assumptions); double nof_conflicts = restart_first; double nof_learnts = nClauses() * learntsize_factor; lbool status = l_Undef; if (verbosity >= 1){ reportf("============================[ Search Statistics ]==============================\n"); reportf("| Conflicts | ORIGINAL | LEARNT | Progress |\n"); reportf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n"); reportf("===============================================================================\n"); } // Search: bool reached_limit = false; while (status == l_Undef && !reached_limit){ if (verbosity >= 1) reportf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", (int)conflicts, order_heap.size(), nClauses(), (int)clauses_literals, (int)nof_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progress_estimate*100), fflush(stdout); status = search((int)nof_conflicts, (int)nof_learnts); reached_limit = limitsExpired(); nof_conflicts *= restart_inc; nof_learnts *= learntsize_inc; } if (verbosity >= 1) reportf("===============================================================================\n"); if (status == l_True){ // Extend & copy model: model.growTo(nVars()); for (int i = 0; i < nVars(); i++) model[i] = value(i); #ifndef NDEBUG verifyModel(); #endif }else if(status == l_False) { //assert(status == l_False); if (conflict.size() == 0) ok = false; } // else { // // limit reached // } //cancelUntil(init_level); return status; // == l_True; }
lbool Solver::solve(const vec<Lit>& assumps) { model.clear(); conflict.clear(); if (!ok) { return false; } assumps.copyTo(assumptions); double nof_conflicts = restart_first; double nof_learnts = nClauses() * learntsize_factor; lbool status = l_Undef; if (verbosity >= 1){ reportf("============================[ Search Statistics ]==============================\n"); reportf("| Conflicts | ORIGINAL | LEARNT | Progress |\n"); reportf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n"); reportf("===============================================================================\n"); } // Search: while (status == l_Undef){ if (verbosity >= 1) reportf("| .%9d. | .%7d. .%8d. .%8d. | .%8d. .%8d. .%6.0f. | .%6.3f. %% |\n", (int)conflicts, order_heap.size(), nClauses(), (int)clauses_literals, (int)nof_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progress_estimate*100), fflush(stdout); status = search((int)nof_conflicts, (int)nof_learnts); nof_conflicts *= restart_inc; nof_learnts *= learntsize_inc; } if (verbosity >= 1) reportf("===============================================================================\n"); if (status == l_True){ // Extend & copy model: model.growTo(nVars()); for (int i = 0; i < nVars(); i++) model[i] = value(i); // printTrail(); #ifdef _DEBUG verifyModel(); #endif }else{ if (conflict.size() == 0) { ok = false; } } // cancelUntil(0); return status; }
void MIP::addConstraint(vec<int>& a, vec<IntVar*>& x, long double lb, long double ub) { for (int i = 0; i < x.size(); i++) var_set.insert(x[i]); ineqs.push(); LinearIneq& li = ineqs.last(); a.copyTo(li.a); x.copyTo(li.x); int red_lb = 0, red_ub = 0; for (int i = 0; i < a.size(); i++) { if (a[i] > 0) { red_lb += a[i] * x[i]->getMin(); red_ub += a[i] * x[i]->getMax(); } else { red_lb += a[i] * x[i]->getMax(); red_ub += a[i] * x[i]->getMin(); } } li.lb_notR = (lb > red_lb); li.ub_notR = (ub < red_ub); li.lb = (li.lb_notR ? lb : red_lb); li.ub = (li.ub_notR ? ub : red_ub); }
// Check if the term store contains an equality over the given arguments // Return the reference if yes, return PTRef_Undef if no // Changes the argument! PTRef Logic::hasEquality(vec<PTRef>& args) { SymRef sref = term_store.lookupSymbol(tk_equals, args); assert(sref != SymRef_Undef); sort(args, LessThan_PTRef()); PTLKey k; k.sym = sref; args.copyTo(k.args); if (term_store.cplx_map.contains(k)) return term_store.cplx_map[k]; else return PTRef_Undef; }
ClauseId Proof::addRoot(vec<Lit>& cl) { cl.copyTo(clause); sortUnique(clause); if (trav != NULL) trav->root(clause); if (!fp.null()){ putUInt(fp, index(clause[0]) << 1); for (int i = 1; i < clause.size(); i++) putUInt(fp, index(clause[i]) - index(clause[i-1])); putUInt(fp, 0); // (0 is safe terminator since we removed duplicates) } return id_counter++; }
void root (const vec<Lit>& c) { //var(c[i])+1 is used here because the default minisat cnf parser sub 1 from cnf variable index such that 0 can be used //but because we add clause by our self, so +1 is not need //fprintf(ssylog,"%d: ROOT", clauses.size()); for (int i = 0; i < c.size(); i++) fprintf(ssylog," %s%d", sign(c[i])?"-":"", var(c[i])+1); fprintf(ssylog,"\n"); //fprintf(ssylog,"%d: ROOT", clauses.size()); for (int i = 0; i < c.size(); i++) fprintf(ssylog," %s%d", sign(c[i])?"-":"", var(c[i])); fprintf(ssylog,"\n"); //1 means a root clause ssylog.push(esc_int(1)); //followed by a list of var idx //because we addcls by ourself, so no 0 is possible //we can use 0 as end index for (int i = 0; i < c.size(); i++) { long sdf=(long)(sign(c[i])? (- var(c[i])):(var(c[i]))); ssylog.push(esc_int(sdf)); } //end index ssylog.push(0); clauses.push(); c.copyTo(clauses.last()); }
/*_________________________________________________________________________________________________ | | 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'. | * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the | rest of literals. There may be others from the same level though. | |________________________________________________________________________________________________@*/ void Solver::analyze(CRef 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; do{ assert(confl != CRef_Undef); // (otherwise should be UIP) Clause& c = ca[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); } } // 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; out_learnt.copyTo(analyze_toclear); if (ccmin_mode == 2){ 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) for (i = j = 1; i < out_learnt.size(); i++) if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i], abstract_level)) out_learnt[j++] = out_learnt[i]; }else if (ccmin_mode == 1){ for (i = j = 1; i < out_learnt.size(); i++){ Var x = var(out_learnt[i]); if (reason(x) == CRef_Undef) out_learnt[j++] = out_learnt[i]; else{ Clause& c = ca[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; } } } }else i = j = out_learnt.size(); 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; // Find the first literal assigned at the next-highest level: for (i = 2; i < out_learnt.size(); i++) if (level(var(out_learnt[i])) > level(var(out_learnt[max_i]))) max_i = i; // Swap-in this literal at index 1: Lit pNew = out_learnt[max_i]; out_learnt[max_i] = out_learnt[1]; out_learnt[1] = pNew; out_btlevel = level(var(pNew)); } for (i = 0; i < analyze_toclear.size(); i++) seen[var(analyze_toclear[i])] = 0; // ('seen[]' is now cleared) }
static void optimizeBase(vec<Int>& seq, int carry_ins, vec<Int>& rhs, int cost, vec<int>& base, int& cost_bestfound, vec<int>& base_bestfound) { if (cost >= cost_bestfound) return; // "Base case" -- don't split further, build sorting network for current sequence: int final_cost = 0; for (int i = 0; i < seq.size(); i++){ if (seq[i] > INT_MAX) goto TooBig; #ifdef ExpensiveBigConstants final_cost += toint(seq[i]); #else int c; for (c = 1; c*c < seq[i]; c++); final_cost += c; #endif if (final_cost < 0) goto TooBig; } if (cost + final_cost < cost_bestfound){ base.copyTo(base_bestfound); cost_bestfound = cost + final_cost; } TooBig:; /**/static int depth = 0; // <<== could count 1:s here for efficiency vec<Int> new_seq; vec<Int> new_rhs; #ifdef PickSmallest int p = -1; for (int i = 0; i < seq.size(); i++) if (seq[i] > 1){ p = seq[i]; break; } if (p != -1){ #else //int upper_lim = (seq.size() == 0) ? 1 : seq.last(); // <<== Check that sqRoot is an 'int' (no truncation of 'Int') //for (int i = 0; i < (int)elemsof(primes) && primes[i] <= upper_lim; i++){ for (int i = 0; i < (int)elemsof(primes); i++){ int p = primes[i]; #endif int rest = carry_ins; // Sum of all the remainders. Int div, rem; /**/for (int n = depth; n != 0; n--) pf(" "); pf("prime=%d carry_ins=%d\n", p, carry_ins); /**/for (int n = depth; n != 0; n--) pf(" "); pf("New seq:"); for (int j = 0; j < seq.size(); j++){ rest += toint(seq[j] % Int(p)); div = seq[j] / Int(p); if (div > 0) //**/pf(" %d", div), new_seq.push(div); } /**/pf("\n"); /**/for (int n = depth; n != 0; n--) pf(" "); pf("rest=%d\n", rest); /**/for (int n = depth; n != 0; n--) pf(" "); pf("New rhs:"); #ifdef AllDigitsImportant bool digit_important = true; #else bool digit_important = false; #endif for (int j = 0; j < rhs.size(); j++){ div = rhs[j] / p; if (new_rhs.size() == 0 || div > new_rhs.last()){ rem = rhs[j] % p; /**/pf(" %d:%d", div, rem), new_rhs.push(div); if (!(rem == 0 && rest < p) && !(rem > rest)) digit_important = true; } /* <<== om 'rhs' slutar på 0:a och 'rest' inte kan overflowa, då behövs inte det sorterande nätverket för 'rest' ("always TRUE") samma sak om 'rhs' sista siffra är strikt större än 'rest' ("never TRUE") */ } /**/pf("\n\n"); base.push(p); /**/depth++; optimizeBase(new_seq, rest/p, new_rhs, cost+(digit_important ? rest : 0), base, cost_bestfound, base_bestfound); /**/depth--; base.pop(); new_seq.clear(); new_rhs.clear(); } } static void optimizeBase(vec<Int>& seq, vec<Int>& rhs, int& cost_bestfound, vec<int>& base_bestfound) { vec<int> base; cost_bestfound = INT_MAX; base_bestfound.clear(); optimizeBase(seq, 0, rhs, 0, base, cost_bestfound, base_bestfound); }
/*_________________________________________________________________________________________________ | | newClause : (ps : const vec<Lit>&) (learnt : bool) -> [void] | | Description: | Allocate and add a new clause to the SAT solvers clause database. If a conflict is detected, | the 'ok' flag is cleared and the solver is in an unusable state (must be disposed). | | Input: | ps - The new clause as a vector of literals. | learnt - Is the clause a learnt clause? For learnt clauses, 'ps[0]' is assumed to be the | asserting literal. An appropriate 'enqueue()' operation will be performed on this | literal. One of the watches will always be on this literal, the other will be set to | the literal with the highest decision level. | | Effect: | Activity heuristics are updated. |________________________________________________________________________________________________@*/ void Solver::newClause(const vec<Lit>& ps_, bool learnt) { if (!ok) return; vec<Lit> qs; if (!learnt){ assert(decisionLevel() == 0); ps_.copyTo(qs); // Make a copy of the input vector. // Remove duplicates: sortUnique(qs); // Check if clause is satisfied: for (int i = 0; i < qs.size()-1; i++){ if (qs[i] == ~qs[i+1]) return; } for (int i = 0; i < qs.size(); i++){ if (value(qs[i]) == l_True) return; } // Remove false literals: int i, j; for (i = j = 0; i < qs.size(); i++) if (value(qs[i]) != l_False) qs[j++] = qs[i]; qs.shrink(i - j); } const vec<Lit>& ps = learnt ? ps_ : qs; // 'ps' is now the (possibly) reduced vector of literals. if (ps.size() == 0){ ok = false; }else if (ps.size() == 1){ // NOTE: If enqueue takes place at root level, the assignment will be lost in incremental use (it doesn't seem to hurt much though). if (!enqueue(ps[0])) ok = false; }else if (ps.size() == 2){ // Create special binary clause watch: watches[index(~ps[0])].push(GClause_new(ps[1])); watches[index(~ps[1])].push(GClause_new(ps[0])); if (learnt){ check(enqueue(ps[0], GClause_new(~ps[1]))); stats.learnts_literals += ps.size(); }else stats.clauses_literals += ps.size(); n_bin_clauses++; }else{ // Allocate clause: Clause* c = Clause_new(learnt, ps); if (learnt){ // Put the second watch on the literal with highest decision level: int max_i = 1; int max = level[var(ps[1])]; for (int i = 2; i < ps.size(); i++) if (level[var(ps[i])] > max) max = level[var(ps[i])], max_i = i; (*c)[1] = ps[max_i]; (*c)[max_i] = ps[1]; // Bump, enqueue, store clause: claBumpActivity(c); // (newly learnt clauses should be considered active) check(enqueue((*c)[0], GClause_new(c))); learnts.push(c); stats.learnts_literals += c->size(); }else{ // Store clause: clauses.push(c); stats.clauses_literals += c->size(); } // Watch clause: watches[index(~(*c)[0])].push(GClause_new(c)); watches[index(~(*c)[1])].push(GClause_new(c)); } }
/*_________________________________________________________________________________________________ | | 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) }
bool Solver::solve(const vec<Lit>& assumps) { model.clear(); conflict.clear(); nbDecisionLevelHistory.initSize(100); totalSumOfDecisionLevel = 0; if (!ok) return false; assumps.copyTo(assumptions); double nof_conflicts = restart_first; nof_learnts = nClauses() * learntsize_factor; if(nof_learnts <nbclausesbeforereduce) { nbclausesbeforereduce = (nof_learnts/2 < 5000) ? 5000 : nof_learnts/2; } lbool status = l_Undef; if (verbosity >= 1){ reportf("============================[ Search Statistics ]==============================\n"); reportf("| Conflicts | ORIGINAL | LEARNT | Progress |\n"); reportf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n"); reportf("===============================================================================\n"); } // Search: while (status == l_Undef){ if (verbosity >= 1) reportf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", (int)conflicts, order_heap.size(), nClauses(), (int)clauses_literals, (int)nof_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progress_estimate*100), fflush(stdout); status = search((int)nof_conflicts, (int)nof_learnts); nof_conflicts *= restart_inc; //LS mis dans reduceDB lui meme nof_learnts *= learntsize_inc; } if (verbosity >= 1) reportf("===============================================================================\n"); if (status == l_True){ // Extend & copy model: model.growTo(nVars()); for (int i = 0; i < nVars(); i++) model[i] = value(i); #ifndef NDEBUG verifyModel(); #endif }else{ assert(status == l_False); if (conflict.size() == 0) ok = false; } #ifdef LS_STATS_NBBUMP for(int i=0;i<learnts.size();i++) printf("## %d %d %d\n",learnts[i]->size(),learnts[i]->activity(),(unsigned int)learnts[i]->nbBump()); #endif cancelUntil(0); return status == l_True; }
/*_________________________________________________________________________________________________ | | 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) }
bool MiniSATP::solve(const vec<Lit>& assumps) { // Added Line initExpDup( ); model.clear(); conflict.clear(); if (!ok) { // Added Line doneExpDup( ); return false; } assumps.copyTo(assumptions); double nof_conflicts = restart_first; double nof_learnts = nClauses() * learntsize_factor; lbool status = l_Undef; if (verbosity >= 1){ reportf("============================[ Search Statistics ]==============================\n"); reportf("| Conflicts | ORIGINAL | LEARNT | Progress |\n"); reportf("| | Vars Clauses Literals | Limit Clauses Lit/Cl | |\n"); reportf("===============================================================================\n"); } // Search: while (status == l_Undef){ if (verbosity >= 1) reportf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", (int)conflicts, order_heap.size(), nClauses(), (int)clauses_literals, (int)nof_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progress_estimate*100), fflush(stdout); status = search((int)nof_conflicts, (int)nof_learnts); nof_conflicts *= restart_inc; nof_learnts *= learntsize_inc; } if (verbosity >= 1) reportf("===============================================================================\n"); if (status == l_True){ // Extend & copy model: model.growTo(nVars()); for (int i = 0; i < nVars(); i++) model[i] = value(i); #ifndef NDEBUG verifyModel(); #endif }else{ assert(status == l_False); if (conflict.size() == 0) ok = false; } cancelUntil(0); // cerr << "SOLVE: Memory after: " << memUsed( ) / 1024.0 / 1024.0 << endl; // Added Line doneExpDup( ); assert( status == l_True || !explanation.empty( ) ); return status == l_True; }
// Modified line // bool MiniSATP::addClause(vec<Lit>& ps, Enode * e) bool MiniSATP::addClause(vec<Lit>& psin, Enode * e) { assert( decisionLevel() == 0 ); assert( ok ); // Added Lines vec< Lit > ps; psin.copyTo( ps ); if (!ok) return false; // Check if clause is satisfied and remove false/duplicate literals: sort(ps); Lit p; int i, j; for (i = j = 0, p = lit_Undef; i < ps.size(); i++) { if (value(ps[i]) == l_True || ps[i] == ~p) return true; else if (value(ps[i]) != l_False && ps[i] != p) ps[j++] = p = ps[i]; } ps.shrink(i - j); //================================================================================================= // Modified Code assert( psin.size( ) == 1 || ps.size() > 0 ); // // This case happens only when deductions are enabled // if (ps.size() == 0) { Clause * confl = Clause_new( psin ); if ( confl == NULL ) return ok = true; initExpDup( ); explanation.push_back( e ); storeExpDup( e ); fillExplanation( confl ); doneExpDup( ); assert( !explanation.empty( ) ); return ok = false; } if (ps.size() == 1) { assert(value(ps[0]) == l_Undef); uncheckedEnqueue(ps[0]); /* const Var v = var(ps[0]); if ( var_to_enode.size( ) <= v ) var_to_enode.resize( v + 1, NULL ); var_to_enode[ v ] = e; */ /* if ( e != NULL && seen_in_conflict.insert( e->getId( ) ).second ) explanation.push_back( e ); */ // undo_stack_oper.push_back( NEWUNIT ); // undo_stack_elem.push_back( (void *)v ); #define LAZY_PROPAGATION 0 #if LAZY_PROPAGATION #else // Modified Line // return ok = (propagate() == NULL); #if LIMIT_DEDUCTIONS deductions_done_in_call = 0; #endif Clause * confl = propagate( theory_prop ); if ( confl == NULL ) return ok = true; initExpDup( ); fillExplanation( confl ); doneExpDup( ); assert( !explanation.empty( ) ); return ok = false; #endif // Modified Code //================================================================================================= } else { Clause* c = Clause_new(ps, false); clauses.push(c); attachClause(*c); // Added Lines undo_stack_oper.push_back( NEWCLAUSE ); undo_stack_elem.push_back( (void *)c ); } return true; }
/*_________________________________________________________________________________________________ | | 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) }