/*_________________________________________________________________________________________________ | | search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&) -> [lbool] | | Description: | Search for a model the specified number of conflicts, keeping the number of learnt clauses | below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to | indicate infinity. | | Output: | 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If | all variables are decision variables, this means that the clause set is satisfiable. 'l_False' | if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. |________________________________________________________________________________________________@*/ lbool MiniSATP::search(int nof_conflicts, int nof_learnts) { assert(ok); int backtrack_level; int conflictC = 0; vec<Lit> learnt_clause; starts++; bool first = true; for (;;){ Clause* confl = propagate(); if (confl != NULL){ // CONFLICT conflicts++; conflictC++; if (decisionLevel() == 0) { // Added Lines fillExplanation(confl); return l_False; } first = false; learnt_clause.clear(); analyze(confl, learnt_clause, backtrack_level); cancelUntil(backtrack_level); assert(value(learnt_clause[0]) == l_Undef); if (learnt_clause.size() == 1){ uncheckedEnqueue(learnt_clause[0]); }else{ Clause* c = Clause_new(learnt_clause, true); learnts.push(c); attachClause(*c); claBumpActivity(*c); uncheckedEnqueue(learnt_clause[0], c); } varDecayActivity(); claDecayActivity(); }else{ // NO CONFLICT if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ // Reached bound on number of conflicts: progress_estimate = progressEstimate(); cancelUntil(0); return l_Undef; } // Simplify the set of problem clauses: if (decisionLevel() == 0 && !simplify()) { return l_False; } if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts) // Reduce the set of learnt clauses: reduceDB(); Lit next = lit_Undef; while (decisionLevel() < assumptions.size()){ // Perform user provided assumption: Lit p = assumptions[decisionLevel()]; if (value(p) == l_True){ // Dummy decision level: newDecisionLevel(); }else if (value(p) == l_False){ analyzeFinal(~p, conflict); return l_False; }else{ next = p; break; } } if (next == lit_Undef){ // New variable decision: decisions++; next = pickBranchLit(polarity_mode, random_var_freq); if (next == lit_Undef) { // Added Line // Clear explanation vector if satisfiable explanation.clear( ); // Model found: return l_True; } } // Increase decision level and enqueue 'next' assert(value(next) == l_Undef); newDecisionLevel(); uncheckedEnqueue(next); } } }
/*_________________________________________________________________________________________________ | | search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&) -> [lbool] | | Description: | Search for a model the specified number of conflicts, keeping the number of learnt clauses | below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to | indicate infinity. | | Output: | 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If | all variables are decision variables, this means that the clause set is satisfiable. 'l_False' | if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. |________________________________________________________________________________________________@*/ lbool Solver::search(int nof_conflicts, int nof_learnts, const SearchParams& params) { if (!ok) return l_False; // GUARD (public method) assert(root_level == decisionLevel()); stats.starts++; int conflictC = 0; var_decay = 1 / params.var_decay; cla_decay = 1 / params.clause_decay; model.clear(); for (;;){ Clause* confl = propagate(); if (confl != NULL){ // CONFLICT stats.conflicts++; conflictC++; vec<Lit> learnt_clause; int backtrack_level; if (decisionLevel() == root_level){ // Contradiction found: analyzeFinal(confl); return l_False; } analyze(confl, learnt_clause, backtrack_level); cancelUntil(max(backtrack_level, root_level)); newClause(learnt_clause, true); if (learnt_clause.size() == 1) level[var(learnt_clause[0])] = 0; // (this is ugly (but needed for 'analyzeFinal()') -- in future versions, we will backtrack past the 'root_level' and redo the assumptions) varDecayActivity(); claDecayActivity(); }else{ // NO CONFLICT if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ // Reached bound on number of conflicts: progress_estimate = progressEstimate(); cancelUntil(root_level); return l_Undef; } if (decisionLevel() == 0) // Simplify the set of problem clauses: simplifyDB(), assert(ok); if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts) // Reduce the set of learnt clauses: reduceDB(); // New variable decision: stats.decisions++; Var next = order.select(params.random_var_freq); if (next == var_Undef){ // Model found: model.growTo(nVars()); for (int i = 0; i < nVars(); i++) model[i] = value(i); cancelUntil(root_level); return l_True; } check(assume(~Lit(next))); } } }
lbool Solver::search(int nof_conflicts, int nof_learnts) { assert(ok); int backtrack_level; int conflictsC = 0; vec<Lit> learnt_clause; int nblevels=0,nbCC=0,merged=0; starts++; bool first = true; for (;;){ Clause* confl = propagate(); if (confl != NULL){ // CONFLICT conflicts++; conflictsC++;cons++;nbCC++; if (decisionLevel() == 0) return l_False; first = false; learnt_clause.clear(); analyze(confl, learnt_clause, backtrack_level,nblevels,merged); conf4Stats++; nbDecisionLevelHistory.push(nblevels); totalSumOfDecisionLevel += nblevels; cancelUntil(backtrack_level); assert(value(learnt_clause[0]) == l_Undef); if (learnt_clause.size() == 1){ uncheckedEnqueue(learnt_clause[0]); nbUn++; }else{ Clause* c = Clause_new(learnt_clause, true); learnts.push(c); c->setActivity(nblevels); // LS if(nblevels<=2) nbDL2++; if(c->size()==2) nbBin++; attachClause(*c); claBumpActivity(*c); uncheckedEnqueue(learnt_clause[0], c); } varDecayActivity(); claDecayActivity(); }else{ if ( ( nbDecisionLevelHistory.isvalid() && ((nbDecisionLevelHistory.getavg()*0.7) > (totalSumOfDecisionLevel / conf4Stats)))) { nbDecisionLevelHistory.fastclear(); progress_estimate = progressEstimate(); cancelUntil(0); return l_Undef; } // Simplify the set of problem clauses: if (decisionLevel() == 0 && !simplify()) return l_False; // Lit next = lit_Undef; if(cons-curRestart* nbclausesbeforereduce>=0) { curRestart = (conflicts/ nbclausesbeforereduce)+1; reduceDB(); nbclausesbeforereduce += 500; } if (next == lit_Undef){ // New variable decision: decisions++; next = pickBranchLit(polarity_mode, random_var_freq); if (next == lit_Undef) // Model found: return l_True; } // Increase decision level and enqueue 'next' assert(value(next) == l_Undef); newDecisionLevel(); uncheckedEnqueue(next); } } }
/*_________________________________________________________________________________________________ | | search : (nof_conflicts : int) (nof_learnts : int) (params : const SearchParams&) -> [lbool] | | Description: | Search for a model the specified number of conflicts, keeping the number of learnt clauses | below the provided limit. NOTE! Use negative value for 'nof_conflicts' or 'nof_learnts' to | indicate infinity. | | Output: | 'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If | all variables are decision variables, this means that the clause set is satisfiable. 'l_False' | if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. |________________________________________________________________________________________________@*/ lbool Solver::search(int nof_conflicts, int nof_learnts) { int backtrack_level; int conflictC = 0; vec<Lit> learnt_clause; starts++; // bool first = true; for (;;){ Clause* confl = propagate(); if (confl != NULL){ // CONFLICT conflicts++; conflictC++; if (decisionLevel() == 0) return l_False; // first = false; learnt_clause.clear(); analyze(confl, learnt_clause, backtrack_level); cancelUntil(backtrack_level); #ifdef __PRINT char c1 = sign(learnt_clause[0]) ? '-' : '+'; char c2 = polarity[var(learnt_clause[0])] == 0 ? '-' : '+'; if (decisionLevel() < minDecisionLevel && original_activity[var(learnt_clause[0])] > 0) { printf("Conflict record: "); printLit(learnt_clause[0]); printf(" .%d.\t.%d. %c .%c .%g\n", decisionLevel(), trail.size(), c1, c2, original_activity[var(learnt_clause[0])]); if (decisionLevel() == 0) { minDecisionLevel = (unsigned)(-1); } else { minDecisionLevel = decisionLevel(); } } #endif if (learnt_clause.size() == 1){ uncheckedEnqueue(learnt_clause[0]); }else{ Clause* c = Clause::Clause_new(learnt_clause, true); learnts.push(c); attachClause(*c); claBumpActivity(*c); uncheckedEnqueue(learnt_clause[0], c); } #ifdef _MINISAT_DEFAULT_VSS varDecayActivity(); #endif claDecayActivity(); }else{ // NO CONFLICT if (nof_conflicts >= 0 && conflictC >= nof_conflicts){ // Reached bound on number of conflicts: progress_estimate = progressEstimate(); // cancelUntil(0); return l_Undef; } // Simplify the set of problem clauses: if (decisionLevel() == 0 && !simplify()) return l_False; if (nof_learnts >= 0 && learnts.size()-nAssigns() >= nof_learnts) // Reduce the set of learnt clauses: reduceDB(); Lit next = lit_Undef; while (decisionLevel() < assumptions.size()){ // Perform user provided assumption: Lit p = assumptions[decisionLevel()]; if (value(p) == l_True){ // Dummy decision level: newDecisionLevel(); }else if (value(p) == l_False){ analyzeFinal(~p, conflict); return l_False; }else{ next = p; break; } } if (next == lit_Undef){ // New variable decision: decisions++; next = pickBranchLit(polarity_mode, random_var_freq); if (next == lit_Undef) // Model found: return l_True; #ifdef __PRINT printf("Decision: "); printLit(next); printf("\t.%f.\t.%d.\t.%d.", activity[var(next)], decisionLevel(), trail.size()); printf("\n"); #endif } // Increase decision level and enqueue 'next' newDecisionLevel(); uncheckedEnqueue(next); } //#ifdef __PRINT // printTrail(); //#endif } }