00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "minisat_solver.h"
00041 #include "minisat_types.h"
00042 #include <cmath>
00043 #include <iostream>
00044 #include <algorithm>
00045
00046 using namespace std;
00047 using namespace MiniSat;
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 const bool defer_theory_propagation = true;
00064
00065
00066
00067
00068
00069
00070 const bool eager_explanation = true;
00071
00072
00073
00074
00075
00076 const bool keep_lazy_explanation = true;
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 const bool push_theory_propagation = true;
00088
00089
00090
00091 const bool push_theory_implication = true;
00092
00093
00094
00095 const bool push_theory_clause = true;
00096
00097
00098
00099
00100
00101 const vector<Var>::size_type prop_lookahead = 1;
00102
00103
00104
00105 const bool protocol = false;
00106
00107
00108
00109
00110
00111
00112 const bool debug_full = false;
00113
00114
00115
00116
00117
00118
00119
00120
00121 bool MiniSat::cvcToMiniSat(const SAT::Clause& clause, std::vector<Lit>& literals) {
00122
00123 SAT::Clause::const_iterator j, jend;
00124
00125 for (j = clause.begin(), jend = clause.end(); j != jend; ++j) {
00126 const SAT::Lit& literal = *j;
00127
00128
00129 if (literal.isTrue())
00130 return false;
00131
00132 if (!literal.isFalse())
00133 literals.push_back(cvcToMiniSat(literal));
00134 }
00135
00136 return true;
00137 }
00138
00139 Clause* Solver::cvcToMiniSat(const SAT::Clause& clause, int id) {
00140 vector<MiniSat::Lit> literals;
00141 if (MiniSat::cvcToMiniSat(clause, literals)) {
00142 if (getDerivation() != NULL)
00143 return Clause_new(literals, clause.getClauseTheorem(), id);
00144 else
00145 return Clause_new(literals, CVC3::Theorem(), id);
00146 }
00147 else {
00148 return NULL;
00149 }
00150 }
00151
00152
00153
00154
00155
00156
00157
00158 Solver::Solver(SAT::DPLLT::TheoryAPI* theoryAPI, SAT::DPLLT::Decider* decider,
00159 bool logDerivation) :
00160 d_inSearch(false),
00161 d_ok(true),
00162 d_conflict(NULL),
00163 d_qhead (0),
00164 d_thead (0),
00165 d_registeredVars (1),
00166 d_clauseIDCounter (3),
00167
00168
00169 d_popRequests (0),
00170 d_cla_inc (1),
00171 d_cla_decay (1),
00172 d_var_inc (1),
00173 d_var_decay (1),
00174 d_order (d_assigns, d_activity),
00175 d_simpDB_assigns (0),
00176 d_simpDB_props (0),
00177 d_simpRD_learnts (0),
00178 d_theoryAPI(theoryAPI),
00179 d_decider(decider),
00180 d_derivation(NULL),
00181 d_default_params(SearchParams(0.95, 0.999, 0.02)),
00182 d_expensive_ccmin(true)
00183 {
00184 if (logDerivation) d_derivation = new Derivation();
00185 }
00186
00187
00188
00189
00190 void Solver::insertLemma(const Clause* lemma, int clauseID, int pushID) {
00191
00192
00193
00194 vector<Lit> literals;
00195 lemma->toLit(literals);
00196
00197
00198
00199
00200
00201
00202
00203 for (vector<Lit>::const_iterator i = literals.begin(); i != literals.end(); ++i) {
00204 registerVar(i->var());
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 orderClause(literals);
00220
00221 Clause* newLemma = Lemma_new(literals, clauseID, pushID);
00222 if (getDerivation() != NULL) getDerivation()->registerClause(newLemma);
00223
00224 newLemma->setActivity(lemma->activity());
00225
00226
00227 if (newLemma->size() >= 2) {
00228 addWatch(~(*newLemma)[0], newLemma);
00229 addWatch(~(*newLemma)[1], newLemma);
00230 }
00231 d_learnts.push_back(newLemma);
00232 d_stats.learnts_literals += newLemma->size();
00233
00234
00235 if (newLemma->size() == 0 || getValue((*newLemma)[0]) == l_False) {
00236 updateConflict(newLemma);
00237 }
00238
00239 if (newLemma->size() == 1 || getValue((*newLemma)[1]) == l_False) {
00240 if (!enqueue((*newLemma)[0], d_rootLevel, newLemma)) {
00241 DebugAssert(false, "MiniSat::Solver::insertLemma: conflicting/implying lemma");
00242 }
00243 }
00244
00245 }
00246
00247
00248 Solver* Solver::createFrom(const Solver* oldSolver) {
00249 Solver* solver = new MiniSat::Solver(oldSolver->d_theoryAPI,
00250 oldSolver->d_decider, oldSolver->d_derivation != NULL);
00251
00252
00253
00254
00255 solver->d_cla_inc = oldSolver->d_cla_inc;
00256 solver->d_var_inc = oldSolver->d_var_inc;
00257 solver->d_activity = oldSolver->d_activity;
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 const vector<MiniSat::Lit>& trail = oldSolver->getTrail();
00268 for (vector<MiniSat::Lit>::const_iterator i = trail.begin(); i != trail.end(); ++i) {
00269
00270 solver->addClause(*i, CVC3::Theorem());
00271 }
00272
00273
00274 const vector<MiniSat::Clause*>& clauses = oldSolver->getClauses();
00275 for (vector<MiniSat::Clause*>::const_iterator i = clauses.begin(); i != clauses.end(); ++i) {
00276 solver->addClause(**i, false);
00277 }
00278
00279
00280 const vector<MiniSat::Clause*>& lemmas = oldSolver->getLemmas();
00281 for (vector<MiniSat::Clause*>::const_iterator i = lemmas.begin();
00282 !solver->isConflicting() && i != lemmas.end(); ++i) {
00283
00284
00285 int clauseID = solver->nextClauseID();
00286 solver->insertLemma(*i, clauseID, clauseID);
00287 }
00288
00289 return solver;
00290 }
00291
00292 Solver::~Solver() {
00293 for (vector<Clause*>::const_iterator i = d_learnts.begin(); i != d_learnts.end(); ++i)
00294 remove(*i, true);
00295
00296 for (vector<Clause*>::const_iterator i = d_clauses.begin(); i != d_clauses.end(); ++i)
00297 remove(*i, true);
00298
00299 while (!d_pendingClauses.empty()) {
00300 xfree(d_pendingClauses.front());
00301 d_pendingClauses.pop();
00302 }
00303
00304 while (!d_theoryExplanations.empty()) {
00305 xfree(d_theoryExplanations.top().second);
00306 d_theoryExplanations.pop();
00307 }
00308
00309 delete d_derivation;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319 std::string Solver::toString(Lit literal, bool showAssignment) const {
00320 ostringstream buffer;
00321 buffer << literal.toString();
00322
00323 if (showAssignment) {
00324 if (getValue(literal) == l_True)
00325 buffer << "(+)";
00326 else if (getValue(literal) == l_False)
00327 buffer << "(-)";
00328 }
00329
00330 return buffer.str();
00331 }
00332
00333
00334 std::string Solver::toString(const std::vector<Lit>& clause, bool showAssignment) const {
00335 ostringstream buffer;
00336 for (size_type j = 0; j < clause.size(); ++j) {
00337 buffer << toString(clause[j], showAssignment) << " ";
00338 }
00339 buffer << endl;
00340
00341 return buffer.str();
00342 }
00343
00344 std::string Solver::toString(const Clause& clause, bool showAssignment) const {
00345 std::vector<Lit> literals;
00346 clause.toLit(literals);
00347 return toString(literals, showAssignment);
00348 }
00349
00350
00351 std::vector<SAT::Lit> Solver::curAssigns(){
00352 vector<SAT::Lit> res;
00353 cout << "current Assignment: " << endl;
00354 for (size_type i = 0; i < d_trail.size(); ++i) {
00355 res.push_back(miniSatToCVC(d_trail[i]));
00356 }
00357 return res;
00358 }
00359
00360 std::vector<std::vector<SAT::Lit> > Solver::curClauses(){
00361 std::vector<std::vector< SAT::Lit> > res;
00362 cout << "current Clauses: " << endl;
00363 for (size_t i = 0; i < d_clauses.size(); ++i) {
00364 std::vector<SAT::Lit> oneClause;
00365 oneClause.clear();
00366 for (int j = 0; j < (*d_clauses[i]).size(); ++j) {
00367 oneClause.push_back(miniSatToCVC((*d_clauses[i])[j]));
00368 }
00369 res.push_back(oneClause);
00370 }
00371 return res;
00372 }
00373
00374
00375 void Solver::printState() const {
00376 cout << "Lemmas: " << endl;
00377 for (size_type i = 0; i < d_learnts.size(); ++i) {
00378 cout << toString(*(d_learnts[i]), true);
00379 }
00380
00381 cout << endl;
00382
00383 cout << "Clauses: " << endl;
00384 for (size_type i = 0; i < d_clauses.size(); ++i) {
00385 cout << toString(*(d_clauses[i]), true);
00386 }
00387
00388 cout << endl;
00389
00390 cout << "Assignment: " << endl;
00391
00392 for (size_type i = 0; i < d_trail.size(); ++i) {
00393 string split = "";
00394 if (getReason(d_trail[i].var()) == Clause::Decision()) {
00395 split = "(S)";
00396 }
00397 cout << toString(d_trail[i], false) << split << " ";
00398 }
00399 cout << endl;
00400 }
00401
00402
00403
00404
00405 void Solver::printDIMACS() const {
00406 int max_id = nVars();
00407 int num_clauses = d_clauses.size() + d_trail.size();
00408
00409
00410 cout << "c minisat test" << endl;
00411 cout << "p cnf " << max_id << " " << num_clauses << endl;
00412
00413
00414 for (size_type i = 0; i < d_clauses.size(); ++i) {
00415 Clause& clause = *d_clauses[i];
00416 for (int j = 0; j < clause.size(); ++j) {
00417 Lit lit = clause[j];
00418 cout << toString(lit, false) << " ";
00419 }
00420 cout << "0" << endl;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 for (vector<Lit>::const_iterator i = d_trail.begin(); i != d_trail.end(); ++i) {
00435 Lit lit(*i);
00436 if (getReason(lit.var()) == Clause::Decision())
00437 cout << toString(lit, false) << " 0" << endl;
00438 else
00439 cout << toString(lit, false) << " 0" << endl;
00440 }
00441 }
00442
00443
00444
00445
00446
00447
00448 bool Solver::isRegistered(Var var) {
00449 for (vector<Hash::hash_set<Var> >::const_iterator i = d_registeredVars.begin();
00450 i != d_registeredVars.end(); ++i) {
00451 if ((*i).count(var) > 0) return true;
00452 }
00453 return false;
00454 }
00455
00456
00457 void Solver::registerVar(Var index) {
00458 if (isRegistered(index)) return;
00459
00460
00461 if (nVars() <= index) {
00462
00463
00464 d_watches .resize(2 * index + 2);
00465 d_reason .resize(index + 1, NULL);
00466 d_assigns .resize(index + 1, toInt(l_Undef));
00467 d_level .resize(index + 1, -1);
00468 d_activity .resize(index + 1, 0);
00469 d_analyze_seen.resize(index + 1, 0);
00470 d_pushIDs .resize(index + 1, -1);
00471 if (d_derivation != NULL) d_trail_pos.resize(index + 1, d_trail.max_size());
00472 }
00473
00474
00475 d_order .newVar(index);
00476
00477
00478 DebugAssert(!d_registeredVars.empty(), "MiniSat::Solver::registerVar: d_registeredVars is empty");
00479 d_registeredVars.back().insert(index);
00480 }
00481
00482 void Solver::addClause(Lit p, CVC3::Theorem theorem) {
00483 vector<Lit> literals;
00484 literals.push_back(p);
00485 addClause(literals, theorem, nextClauseID());
00486 }
00487
00488 void Solver::addClause(const SAT::Clause& clause, bool isTheoryClause) {
00489 vector<MiniSat::Lit> literals;
00490 if (MiniSat::cvcToMiniSat(clause, literals)) {
00491 int clauseID = nextClauseID();
00492
00493 if (isTheoryClause) clauseID = -clauseID;
00494 CVC3::Theorem theorem;
00495 if (getDerivation() != NULL) {
00496 getDerivation()->registerInputClause(clauseID);
00497 theorem = clause.getClauseTheorem();
00498 }
00499 addClause(literals, theorem, clauseID);
00500 }
00501 else {
00502
00503 return;
00504 }
00505 }
00506
00507 void Solver::addClause(const Clause& clause, bool keepClauseID) {
00508 vector<Lit> literals;
00509 for (int i = 0; i < clause.size(); ++i) {
00510 literals.push_back(clause[i]);
00511 }
00512 if (keepClauseID) {
00513 addClause(literals, clause.getTheorem(), clause.id());
00514 } else {
00515 addClause(literals, clause.getTheorem(), nextClauseID());
00516 }
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 void Solver::addFormula(const SAT::CNF_Formula& cnf, bool isTheoryClause) {
00530 SAT::CNF_Formula::const_iterator i, iend;
00531
00532
00533 for (i = cnf.begin(), iend = cnf.end(); i != iend; i++) {
00534
00535
00536
00537 addClause(*i, isTheoryClause);
00538 }
00539 }
00540
00541
00542
00543
00544
00545 bool Solver::simplifyClause(vector<Lit>& literals, int clausePushID) const {
00546
00547 for (size_type i = 1; i < literals.size(); i++){
00548 if (literals[i-1] == ~literals[i]){
00549 return true;
00550 }
00551 }
00552
00553
00554 size_type i, j;
00555 for (i = j = 0; i < literals.size(); i++) {
00556 bool rootAssign = (
00557 getLevel(literals[i]) == d_rootLevel
00558 && isImpliedAt(literals[i], clausePushID) );
00559
00560 if (rootAssign && (getValue(literals[i]) == l_True)){
00561 return true;
00562 }
00563 else if (rootAssign && (getValue(literals[i]) == l_False)){
00564
00565 ;
00566 }
00567 else{
00568 literals[j++] = literals[i];
00569 }
00570 }
00571 literals.resize(j);
00572 return false;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 void Solver::orderClause(vector<Lit>& literals) const {
00589 if (literals.size() >= 2) {
00590 int first = 0;
00591 int levelFirst = getLevel(literals[first]);
00592 lbool valueFirst = getValue(literals[first]);
00593 int second = 1;
00594 int levelSecond = getLevel(literals[second]);
00595 lbool valueSecond = getValue(literals[second]);
00596 for (size_type i = 2; i < literals.size(); i++) {
00597
00598 if (!(valueFirst == l_False) && !(valueSecond == l_False))
00599 break;
00600
00601
00602 int levelNew = getLevel(literals[i]);
00603 lbool valueNew = getValue(literals[i]);
00604
00605
00606 if (!(valueNew == l_False)) {
00607 if ((valueFirst == l_False) && (valueSecond == l_False)) {
00608 if (levelFirst > levelSecond) {
00609 second = i; levelSecond = levelNew; valueSecond = valueNew;
00610 } else {
00611 first = i; levelFirst = levelNew; valueFirst = valueNew;
00612 }
00613 }
00614 else if (valueFirst == l_False) {
00615 first = i; levelFirst = levelNew; valueFirst = valueNew;
00616 }
00617 else {
00618 second = i; levelSecond = levelNew; valueSecond = valueNew;
00619 }
00620 }
00621
00622 else {
00623 if ((valueFirst == l_False) && (valueSecond == l_False)) {
00624 if ((levelNew > levelFirst) && (levelNew > levelSecond)) {
00625 if (levelSecond > levelFirst) {
00626 first = i; levelFirst = levelNew; valueFirst = valueNew;
00627 }
00628 else {
00629 second = i; levelSecond = levelNew; valueSecond = valueNew;
00630 }
00631 }
00632 else if (levelNew > levelFirst) {
00633 first = i; levelFirst = levelNew; valueFirst = valueNew;
00634 }
00635 else if (levelNew > levelSecond) {
00636 second = i; levelSecond = levelNew; valueSecond = valueNew;
00637 }
00638 }
00639 else if (valueFirst == l_False) {
00640 if (levelNew > levelFirst) {
00641 first = i; levelFirst = levelNew; valueFirst = valueNew;
00642 }
00643 }
00644 else {
00645 if (levelNew > levelSecond) {
00646 second = i; levelSecond = levelNew; valueSecond = valueNew;
00647 }
00648 }
00649 }
00650 }
00651
00652 Lit swap = literals[0]; literals[0] = literals[first]; literals[first] = swap;
00653 swap = literals[1]; literals[1] = literals[second]; literals[second] = swap;
00654
00655
00656
00657 if (
00658
00659 ((getValue(literals[0]) != l_True) && (getValue(literals[1]) == l_True))
00660 ||
00661
00662 (getValue(literals[0]) == l_False)
00663 )
00664 {
00665 Lit swap = literals[0]; literals[0] = literals[1]; literals[1] = swap;
00666 }
00667 }
00668 }
00669
00670
00671 void Solver::addClause(vector<Lit>& literals, CVC3::Theorem theorem, int clauseID) {
00672
00673 std::sort(literals.begin(), literals.end());
00674
00675
00676 vector<Lit>::iterator end = std::unique(literals.begin(), literals.end());
00677 literals.erase(end, literals.end());
00678
00679
00680 for (vector<Lit>::const_iterator i = literals.begin(); i != literals.end(); ++i){
00681 registerVar(i->var());
00682 }
00683
00684
00685 vector<Lit> simplified(literals);
00686
00687 bool replaceReason = false;
00688 if (simplifyClause(simplified, clauseID)) {
00689
00690
00691
00692
00693
00694
00695 if (literals.size() == 1 && getReason(literals[0].var())->learnt()) {
00696 replaceReason = true;
00697 }
00698 else {
00699
00700 return;
00701 }
00702 }
00703
00704
00705 if (getDerivation() != NULL && simplified.size() < literals.size()) {
00706
00707 Clause* c = Clause_new(literals, theorem, clauseID);
00708 getDerivation()->registerClause(c);
00709 getDerivation()->removedClause(c);
00710
00711
00712 Inference* inference = new Inference(clauseID);
00713 size_type j = 0;
00714 for (size_type i = 0; i < literals.size(); ++i) {
00715
00716 if (j >= simplified.size() || literals[i] != simplified[j]) {
00717 inference->add(literals[i], getDerivation()->computeRootReason(~literals[i], this));
00718 }
00719
00720 else {
00721 ++j;
00722 }
00723 }
00724
00725
00726 clauseID = nextClauseID();
00727 getDerivation()->registerInference(clauseID, inference);
00728 }
00729
00730
00731 orderClause(simplified);
00732 Clause* c;
00733 if (simplified.size() < literals.size()) {
00734 c = Clause_new(simplified, CVC3::Theorem(), clauseID);
00735 } else {
00736 c = Clause_new(simplified, theorem, clauseID);
00737 }
00738
00739
00740
00741 insertClause(c);
00742
00743 if (replaceReason) {
00744 d_reason[literals[0].var()] = c;
00745 }
00746
00747 }
00748
00749
00750 void Solver::insertClause(Clause* c) {
00751
00752 if (!d_ok) {
00753 remove(c, true);
00754 return;
00755 }
00756
00757 if (getDerivation() != NULL) getDerivation()->registerClause(c);
00758
00759 if (c->size() == 0){
00760 d_conflict = c;
00761
00762
00763 if (!c->learnt()) {
00764 d_clauses.push_back(c);
00765 } else {
00766 d_learnts.push_back(c);
00767 }
00768
00769 d_ok = false;
00770 return;
00771 }
00772
00773
00774
00775
00776
00777 if (c->size() == 1) {
00778 if (!enqueue((*c)[0], d_rootLevel, c)) {
00779
00780
00781 updateConflict(c);
00782 d_pendingClauses.push(c);
00783 return;
00784 }
00785 }
00786
00787 else {
00788
00789 if (c->learnt()){
00790 DebugAssert(getValue((*c)[0]) == l_Undef,
00791 "MiniSat::Solver::insertClause: first literal of new lemma not undefined");
00792 IF_DEBUG (
00793 for (int i = 1; i < c->size(); ++i) {
00794 DebugAssert(getValue((*c)[i]) == l_False,
00795 "MiniSat::Solver::insertClause: lemma literal not false");
00796 }
00797 )
00798
00799
00800 int max_i = 1;
00801 int max = getLevel((*c)[1]);
00802 for (int i = 2; i < c->size(); i++) {
00803 if (getLevel((*c)[i]) > max) {
00804 max = getLevel((*c)[i]);
00805 max_i = i;
00806 }
00807 }
00808 Lit swap((*c)[1]);
00809 (*c)[1] = (*c)[max_i];
00810 (*c)[max_i] = swap;
00811
00812
00813 claBumpActivity(c);
00814 }
00815
00816
00817 if (getValue((*c)[0]) == l_True) {
00818 ;
00819 }
00820
00821 else if (getValue((*c)[0]) == l_False) {
00822 IF_DEBUG (
00823 for (int i = 1; i < c->size(); ++i) {
00824 DebugAssert(getValue((*c)[i]) == l_False,
00825 "MiniSat::Solver::insertClause: bogus conflicting clause");
00826 }
00827 )
00828
00829 updateConflict(c);
00830 d_pendingClauses.push(c);
00831 return;
00832 }
00833
00834 else if (getValue((*c)[1]) == l_False) {
00835 DebugAssert(getValue((*c)[0]) == l_Undef,
00836 "MiniSat::Solver::insertClause: bogus propagating clause");
00837 IF_DEBUG (
00838 for (int i = 1; i < c->size(); ++i) {
00839 DebugAssert(getValue((*c)[i]) == l_False,
00840 "MiniSat::Solver::insertClause: bogus propagating clause");
00841 }
00842 )
00843 if (!enqueue((*c)[0], getImplicationLevel(*c), c)) {
00844 DebugAssert(false, "MiniSat::Solver::insertClause: conflicting/implying clause");
00845 }
00846 }
00847
00848
00849 addWatch(~(*c)[0], c);
00850 addWatch(~(*c)[1], c);
00851 }
00852
00853
00854 d_stats.max_literals += c->size();
00855 if (!c->learnt()) {
00856 d_clauses.push_back(c);
00857 d_stats.clauses_literals += c->size();
00858 } else {
00859 d_learnts.push_back(c);
00860 d_stats.learnts_literals += c->size();
00861 }
00862 }
00863
00864
00865
00866
00867
00868
00869 void Solver::remove(Clause* c, bool just_dealloc) {
00870
00871 if (!just_dealloc && c->size() >= 2){
00872 removeWatch(getWatches(~(*c)[0]), c);
00873 removeWatch(getWatches(~(*c)[1]), c);
00874 }
00875
00876 if (c->learnt()) d_stats.learnts_literals -= c->size();
00877 else d_stats.clauses_literals -= c->size();
00878
00879 if (getDerivation() == NULL) xfree(c);
00880 else getDerivation()->removedClause(c);
00881 }
00882
00883
00884
00885
00886
00887
00888
00889 void Solver::removeWatch(std::vector<Clause*>& ws, Clause* elem) {
00890 if (ws.size() == 0) return;
00891 size_type j = 0;
00892 for (; ws[j] != elem; j++) {
00893
00894
00895 DebugAssert(j < ws.size(), "MiniSat::Solver::removeWatch: elem not in watched list");
00896 }
00897
00898 ws[j] = ws.back();
00899 ws.pop_back();
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 int Solver::getImplicationLevel(const Clause& clause) const {
00911 int currentLevel = decisionLevel();
00912 int maxLevel = d_rootLevel;
00913
00914 for (int i = 1; i < clause.size(); ++i) {
00915 DebugAssert(getValue(clause[i]) == l_False,
00916 "MiniSat::Solver::getImplicationLevelFull: literal not false");
00917
00918 int newLevel = getLevel(clause[i]);
00919
00920
00921 if (newLevel == currentLevel)
00922 return currentLevel;
00923
00924
00925 if (newLevel > maxLevel)
00926 maxLevel = newLevel;
00927 }
00928
00929 return maxLevel;
00930 }
00931
00932
00933
00934
00935 int Solver::getConflictLevel(const Clause& clause) const {
00936 int decisionLevel = d_rootLevel;
00937
00938 for (int i = 0; i < clause.size(); ++i) {
00939 DebugAssert(getValue(clause[i]) == l_False, "MiniSat::Solver::getConflictLevel: literal not false");
00940
00941 int newLevel = getLevel(clause[i]);
00942 if (newLevel > decisionLevel)
00943 decisionLevel = newLevel;
00944 }
00945
00946 return decisionLevel;
00947 }
00948
00949
00950 Clause* Solver::getReason(Lit literal, bool _resolveTheoryImplication) {
00951 Var var = literal.var();
00952 Clause* reason = d_reason[var];
00953
00954 if (!_resolveTheoryImplication)
00955 return reason;
00956
00957 DebugAssert(reason != NULL, "MiniSat::getReason: reason[var] == NULL.");
00958
00959 if (reason == Clause::TheoryImplication()) {
00960 if (getValue(literal) == l_True)
00961 resolveTheoryImplication(literal);
00962 else
00963 resolveTheoryImplication(~literal);
00964 reason = d_reason[var];
00965 }
00966
00967 DebugAssert(d_reason[var] != Clause::TheoryImplication(),
00968 "MiniSat::getReason: reason[var] == TheoryImplication.");
00969
00970 return reason;
00971 }
00972
00973 bool Solver::isConflicting() const {
00974 return (d_conflict != NULL);
00975 }
00976
00977 void Solver::updateConflict(Clause* clause) {
00978 DebugAssert(clause != NULL, "MiniSat::updateConflict: clause == NULL.");
00979 IF_DEBUG (
00980 for (int i = 0; i < clause->size(); ++i) {
00981 DebugAssert(getValue((*clause)[i]) == l_False, "MiniSat::Solver::updateConflict: literal not false");
00982 }
00983 )
00984
00985 if (
00986 (d_conflict == NULL)
00987 ||
00988 (clause->size() < d_conflict->size())
00989 ) {
00990 d_conflict = clause;
00991 }
00992 }
00993
00994
00995
00996
00997
00998
00999 void Solver::resolveTheoryImplication(Lit literal) {
01000 if (eager_explanation) return;
01001
01002 if (d_reason[literal.var()] == Clause::TheoryImplication()) {
01003
01004
01005 stack<Lit> toRegress;
01006 stack<Clause*> toComplete;
01007 toRegress.push(literal);
01008
01009 SAT::Clause clauseCVC;
01010 while (!toRegress.empty()) {
01011
01012 literal = toRegress.top();
01013 DebugAssert(getValue(literal) == l_True,
01014 "MiniSat::Solver::resolveTheoryImplication: literal is not true");
01015 toRegress.pop();
01016 FatalAssert(false, "Not implemented yet");
01017
01018 Clause* explanation = cvcToMiniSat(clauseCVC, nextClauseID());
01019
01020
01021 for (int i = 0; i < (*explanation).size(); ++i) {
01022 if ((*explanation)[i] == literal) {
01023 MiniSat::Lit swap = (*explanation)[0];
01024 (*explanation)[0] = (*explanation)[i];
01025 (*explanation)[i] = swap;
01026 break;
01027 }
01028 }
01029
01030 IF_DEBUG(
01031 DebugAssert((*explanation)[0] == literal,
01032 "MiniSat::Solver::resolveTheoryImplication: literal not implied by clause 1");
01033 DebugAssert(getValue((*explanation)[0]) == l_True,
01034 "MiniSat::Solver::resolveTheoryImplication: literal not implied by clause 2");
01035 for (int i = 1; i < (*explanation).size(); ++i) {
01036 DebugAssert(getValue((*explanation)[i]) == l_False,
01037 "MiniSat::Solver::resolveTheoryImplication: literal not implied by clause 3");
01038 }
01039 )
01040 d_reason[literal.var()] = explanation;
01041
01042
01043
01044 for (int i = 1; i < (*explanation).size(); ++i) {
01045 if (d_reason[(*explanation)[i].var()] == Clause::TheoryImplication()) {
01046 toRegress.push((*explanation)[i]);
01047 }
01048 }
01049
01050 toComplete.push(explanation);
01051 }
01052
01053
01054
01055 while (!toComplete.empty()) {
01056 Clause* explanation = toComplete.top();
01057 toComplete.pop();
01058
01059 IF_DEBUG (
01060 for (int i = 1; i < explanation->size(); ++i) {
01061 DebugAssert (d_reason[(*explanation)[i].var()] != Clause::TheoryImplication(),
01062 "MiniSat::Solver::resolveTheoryImplication: not done to completion");
01063 }
01064 )
01065
01066
01067 int level = getImplicationLevel(*explanation);
01068 setLevel((*explanation)[0], level);
01069 setPushID((*explanation)[0].var(), explanation);
01070
01071 if (keep_lazy_explanation) {
01072
01073
01074
01075
01076 addClause(*explanation, true);
01077 xfree(explanation);
01078 } else {
01079
01080 d_theoryExplanations.push(std::make_pair(level, explanation));
01081 }
01082 }
01083 }
01084
01085 }
01086
01087
01088
01089
01090
01091 Clause* Solver::analyze(int& out_btlevel) {
01092 DebugAssert(d_conflict != NULL, "MiniSat::Solver::analyze called when no conflict was detected");
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136 for (int j = 0; j < d_conflict->size(); j++){
01137 resolveTheoryImplication(~((*d_conflict)[j]));
01138 }
01139 int UIPLevel = getConflictLevel(*d_conflict);
01140
01141
01142
01143 IF_DEBUG (
01144 for (size_type i = 0; i < d_analyze_seen.size(); ++i) {
01145 DebugAssert (d_analyze_seen[i] == 0, "MiniSat::Solver::analyze: analyze_seen is not clear at: " );
01146 }
01147 )
01148
01149 int index = d_trail.size() - 1;
01150
01151 vector<Lit> out_learnt;
01152
01153 int pathC = 0;
01154
01155 out_btlevel = 0;
01156
01157 Lit p = lit_Undef;
01158
01159
01160 Inference* inference = NULL;
01161 if (getDerivation() != NULL) inference = new Inference(d_conflict->id());
01162
01163
01164 Clause* confl = d_conflict;
01165 d_conflict = NULL;
01166
01167
01168 int pushID = confl->pushID();
01169
01170
01171 if (confl->size() == 1) {
01172 out_learnt.push_back((*confl)[0]);
01173 } else {
01174
01175
01176 if (UIPLevel != d_rootLevel) out_learnt.push_back(lit_Undef);
01177
01178 do {
01179 DebugAssert (confl != Clause::Decision(), "MiniSat::Solver::analyze: no reason for conflict");
01180 DebugAssert (confl != Clause::TheoryImplication(), "MiniSat::Solver::analyze: theory implication not resolved");
01181
01182 if (confl->learnt()) claBumpActivity(confl);
01183
01184
01185 for (int j = (p == lit_Undef) ? 0 : 1; j < confl->size(); j++){
01186 Lit q = (*confl)[j];
01187 DebugAssert(getValue(q) == l_False, "MiniSat::Solver::analyze: literal to regress is not false");
01188 DebugAssert(getLevel(q) <= UIPLevel, "MiniSat::Solver::analyze: literal above UIP level");
01189
01190
01191 resolveTheoryImplication(~q);
01192
01193
01194 if (!d_analyze_seen[q.var()]) {
01195
01196 if (getLevel(q) == d_rootLevel) {
01197 d_analyze_redundant.push_back(q);
01198 d_analyze_seen[q.var()] = 1;
01199 }
01200 else {
01201 varBumpActivity(q);
01202 d_analyze_seen[q.var()] = 1;
01203
01204 if (getLevel(q) == UIPLevel)
01205 pathC++;
01206
01207 else{
01208 out_learnt.push_back(q);
01209 out_btlevel = max(out_btlevel, getLevel(q));
01210 }
01211 }
01212 }
01213 }
01214
01215
01216 if (pathC == 0) break;
01217
01218
01219
01220
01221 while (!d_analyze_seen[d_trail[index].var()] || (getLevel(d_trail[index])) != UIPLevel) {
01222 --index;
01223 }
01224 --index;
01225
01226
01227
01228 DebugAssert(index >= -1, "MiniSat::Solver::analyze: index out of bound");
01229
01230
01231 p = d_trail[index+1];
01232 d_analyze_seen[p.var()] = 0;
01233 pathC--;
01234
01235 confl = getReason(p);
01236 pushID = max(pushID, confl->pushID());
01237 if (getDerivation() != NULL && pathC > 0) inference->add(~p, confl);
01238 } while (pathC > 0);
01239
01240 if (UIPLevel != d_rootLevel) out_learnt[0] = ~p;
01241 }
01242
01243
01244 IF_DEBUG (
01245 DebugAssert ((out_learnt.size() == 0 && UIPLevel == d_rootLevel)
01246 || getLevel(out_learnt[0]) == UIPLevel,
01247 "MiniSat::Solver::analyze: backtracked past UIP level.");
01248 for (size_type i = 1; i < out_learnt.size(); ++i) {
01249 DebugAssert (getLevel(out_learnt[i]) < UIPLevel,
01250 "MiniSat::Solver::analyze: conflict clause contains literal from UIP level or higher.");
01251 }
01252 )
01253
01254 analyze_minimize(out_learnt, inference, pushID);
01255
01256
01257 for (vector<Lit>::const_iterator j = out_learnt.begin(); j != out_learnt.end(); ++j) {
01258 d_analyze_seen[j->var()] = 0;
01259 }
01260
01261
01262 int clauseID = nextClauseID();
01263 if (getDerivation() != NULL) getDerivation()->registerInference(clauseID, inference);
01264
01265 return Lemma_new(out_learnt, clauseID, pushID);
01266 }
01267
01268 class lastToFirst_lt {
01269 const vector<MiniSat::size_type>& d_trail_pos;
01270 public:
01271 lastToFirst_lt(const vector<MiniSat::size_type>& trail_pos) : d_trail_pos(trail_pos) {}
01272
01273 bool operator () (Lit p, Lit q) {
01274 return d_trail_pos[p.var()] > d_trail_pos[q.var()];
01275 }
01276 };
01277
01278 void Solver::analyze_minimize(vector<Lit>& out_learnt, Inference* inference, int& pushID) {
01279
01280 if (out_learnt.size() > 1) {
01281
01282
01283
01284
01285 size_type i, j;
01286
01287
01288
01289
01290 if (d_expensive_ccmin){
01291
01292 unsigned int min_level = 0;
01293 for (i = 1; i < out_learnt.size(); i++)
01294 min_level |= 1 << (getLevel(out_learnt[i]) & 31);
01295
01296 for (i = j = 1; i < out_learnt.size(); i++) {
01297 Lit lit(out_learnt[i]);
01298 if (getReason(lit) == Clause::Decision() || !analyze_removable(lit, min_level, pushID))
01299 out_learnt[j++] = lit;
01300 }
01301 }
01302
01303
01304
01305
01306 else {
01307 for (i = j = 1; i < out_learnt.size(); i++) {
01308 Lit lit(out_learnt[i]);
01309 Clause& c = *getReason(lit);
01310 if (&c == Clause::Decision()) {
01311 out_learnt[j++] = lit;
01312 } else {
01313 bool keep = false;
01314
01315 for (int k = 1; !keep && k < c.size(); k++) {
01316 if (
01317
01318 !d_analyze_seen[c[k].var()]
01319 &&
01320
01321 getLevel(c[k]) != d_rootLevel
01322 ) {
01323
01324 out_learnt[j++] = lit;
01325 keep = true;
01326 }
01327 }
01328 if (!keep) {
01329 d_analyze_redundant.push_back(lit);
01330 }
01331 }
01332 }
01333 }
01334
01335 out_learnt.resize(j);
01336 }
01337
01338
01339
01340
01341
01342
01343
01344 if (getDerivation() != NULL) {
01345 std::sort(d_analyze_redundant.begin(), d_analyze_redundant.end(), lastToFirst_lt(d_trail_pos));
01346 }
01347 for (vector<Lit>::const_iterator i = d_analyze_redundant.begin(); i != d_analyze_redundant.end(); ++i) {
01348 Lit lit(*i);
01349 d_analyze_seen[lit.var()] = 0;
01350
01351
01352
01353
01354
01355
01356
01357 if (out_learnt.size() > 0
01358 &&
01359 getLevel(lit) == d_rootLevel
01360 &&
01361 getPushID(lit) > pushID
01362 &&
01363 !d_pushes.empty()
01364 &&
01365 getPushID(lit) > d_pushes.front().d_clauseID
01366 ) {
01367 out_learnt.push_back(lit);
01368 continue;
01369 }
01370
01371
01372
01373 pushID = max(pushID, getPushID(lit));
01374
01375 if (getDerivation() != NULL) {
01376
01377 if (getLevel(lit) == d_rootLevel) {
01378 inference->add(lit, getDerivation()->computeRootReason(~lit, this));
01379 }
01380 else {
01381 Clause* reason = getReason(lit);
01382 inference->add(lit, reason);
01383 }
01384 }
01385 }
01386
01387 d_analyze_redundant.clear();
01388 }
01389
01390
01391
01392
01393
01394
01395 bool Solver::analyze_removable(Lit p, unsigned int min_level, int pushID) {
01396 DebugAssert(getReason(p) != Clause::Decision(), "MiniSat::Solver::analyze_removable: p is a decision.");
01397
01398 d_analyze_stack.clear();
01399 d_analyze_stack.push_back(p);
01400 int top = d_analyze_redundant.size();
01401
01402 while (d_analyze_stack.size() > 0){
01403 DebugAssert(getReason(d_analyze_stack.back()) != Clause::Decision(),
01404 "MiniSat::Solver::analyze_removable: stack var is a decision.");
01405 DebugAssert(getReason(d_analyze_stack.back()) != Clause::TheoryImplication(),
01406 "MiniSat::Solver::analyze_removable: stack var is an unresolved theory implication.");
01407 Clause& c = *getReason(d_analyze_stack.back()); d_analyze_stack.pop_back();
01408 for (int i = 1; i < c.size(); i++) {
01409 Lit p = c[i];
01410
01411 if (!d_analyze_seen[p.var()]) {
01412 if (getLevel(p) == d_rootLevel) {
01413 d_analyze_redundant.push_back(p);
01414 d_analyze_seen[p.var()] = 1;
01415 }
01416 else {
01417
01418
01419
01420 if (getReason(p) != Clause::Decision() && ((1 << (getLevel(p) & 31)) & min_level) != 0){
01421 d_analyze_seen[p.var()] = 1;
01422 d_analyze_stack.push_back(p);
01423 d_analyze_redundant.push_back(p);
01424 } else {
01425
01426 for (size_type j = top; j < d_analyze_redundant.size(); ++j) {
01427 d_analyze_seen[d_analyze_redundant[j].var()] = 0;
01428 }
01429 d_analyze_redundant.resize(top);
01430 return false;
01431 }
01432 }
01433 }
01434 }
01435 }
01436
01437 d_analyze_redundant.push_back(p);
01438 return true;
01439 }
01440
01441
01442
01443 bool Solver::isImpliedAt(Lit lit, int clausePushID) const {
01444 return
01445
01446 (d_pushes.empty() || getPushID(lit) <= d_pushes.front().d_clauseID)
01447 ||
01448
01449 getPushID(lit) < clausePushID;
01450
01451 }
01452
01453
01454
01455
01456
01457
01458 bool Solver::isPermSatisfied(Clause* c) const {
01459 for (int i = 0; i < c->size(); i++){
01460 Lit lit((*c)[i]);
01461 if (getValue(lit) == l_True
01462 && getLevel(lit) == d_rootLevel
01463 && isImpliedAt(lit, c->pushID())
01464 )
01465 return true;
01466 }
01467 return false;
01468 }
01469
01470
01471
01472
01473 bool Solver::assume(Lit p) {
01474 d_trail_lim.push_back(d_trail.size());
01475 d_stats.max_level = std::max(d_trail_lim.size(), size_type(d_stats.max_level));
01476 return enqueue(p, decisionLevel(), Clause::Decision());
01477 }
01478
01479
01480
01481 void Solver::backtrack(int toLevel, Clause* learnt_clause) {
01482 DebugAssert (decisionLevel() > toLevel, "MiniSat::Solver::backtrack: backtrack not to previous level");
01483
01484
01485 DebugAssert(toLevel >= d_rootLevel, "MiniSat::Solver::backtrack: backtrack beyond root level");
01486 for (int i = toLevel; i < decisionLevel(); ++i) {
01487 d_theoryAPI->pop();
01488 }
01489
01490
01491 int trail_size = d_trail.size();
01492 int trail_jump = d_trail_lim[toLevel];
01493 int first_invalid = d_trail_lim[toLevel];
01494 for (int c = first_invalid; c < trail_size; ++c) {
01495 Var x = d_trail[c].var();
01496
01497 if (getLevel(x) > toLevel) {
01498
01499 d_assigns[x] = toInt(l_Undef);
01500 d_reason [x] = NULL;
01501
01502 d_order.undo(x);
01503 }
01504 else {
01505 d_trail[first_invalid] = d_trail[c];
01506 if (d_derivation != NULL) d_trail_pos[x] = first_invalid;
01507 ++first_invalid;
01508 }
01509 }
01510
01511 d_trail.resize(first_invalid);
01512 d_trail_lim.resize(toLevel);
01513 d_qhead = trail_jump;
01514 d_thead = d_qhead;
01515
01516
01517
01518
01519
01520
01521 insertClause(learnt_clause);
01522
01523
01524
01525 while (!isConflicting() && !d_pendingClauses.empty()) {
01526 Clause* c = d_pendingClauses.front();
01527 d_pendingClauses.pop();
01528 addClause(*c, true);
01529 xfree(c);
01530 }
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540 bool done = false;
01541 while (!done && !d_theoryExplanations.empty()) {
01542 std::pair<int, Clause*> pair = d_theoryExplanations.top();
01543 if (pair.first > toLevel) {
01544 d_theoryExplanations.pop();
01545 remove(pair.second, true);
01546 }
01547 else {
01548 done = true;
01549 }
01550 }
01551 }
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575 bool Solver::enqueue(Lit p, int decisionLevel, Clause* from) {
01576 lbool value(getValue(p));
01577 if (value != l_Undef) {
01578 return value != l_False;
01579 }
01580 else {
01581 Var var(p.var());
01582 d_assigns[var] = toInt(lbool(p.sign()));
01583 setLevel(var, decisionLevel);
01584 d_reason [var] = from;
01585 setPushID(var, from);
01586 d_trail.push_back(p);
01587 if (d_derivation != NULL) d_trail_pos[var] = d_trail.size();
01588 return true;
01589 }
01590 }
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 void Solver::propagate() {
01690 Lit p = d_trail[d_qhead++];
01691 vector<Clause*>& ws = getWatches(p);
01692
01693 d_stats.propagations++;
01694 --d_simpDB_props;
01695 if (getLevel(p) == d_rootLevel) ++d_simpDB_assigns;
01696
01697
01698 if (!defer_theory_propagation) {
01699 d_theoryAPI->assertLit(miniSatToCVC(p));
01700 ++d_thead;
01701 }
01702
01703 vector<Clause*>::iterator j = ws.begin();
01704 vector<Clause*>::iterator i = ws.begin();
01705 vector<Clause*>::iterator end = ws.end();
01706 while (i != end) {
01707 Clause& c = **i;
01708 ++i;
01709
01710
01711 Lit false_lit = ~p;
01712 if (c[0] == false_lit) {
01713 c[0] = c[1];
01714 c[1] = false_lit;
01715 }
01716
01717 Lit first = c[0];
01718 lbool val = getValue(first);
01719
01720
01721 if (val == l_True) {
01722 DebugAssert(getValue(c[0]) == l_True && getValue(c[1]) == l_False,
01723 "MiniSat::Solver:::propagate: True/False");
01724 *j = &c; ++j;
01725 }
01726
01727 else {
01728 for (int k = 2; k < c.size(); k++) {
01729 if (getValue(c[k]) != l_False) {
01730 c[1] = c[k];
01731 c[k] = false_lit;
01732 addWatch(~c[1], &c);
01733 goto FoundWatch;
01734 }
01735 }
01736
01737
01738
01739
01740 IF_DEBUG(
01741 for (int z = 1; z < c.size(); ++z) {
01742 DebugAssert(getValue(c[z]) == l_False,
01743 "MiniSat::Solver:::propagate: Unit Propagation");
01744 }
01745 )
01746
01747 *j = &c; ++j;
01748 if (!enqueue(first, getImplicationLevel(c), &c)){
01749
01750 updateConflict(&c);
01751 d_qhead = d_trail.size();
01752
01753
01754 if (i != j) ws.erase(j, i);
01755 return;
01756 }
01757
01758 FoundWatch:;
01759 }
01760 }
01761
01762
01763 ws.erase(j, ws.end());
01764 }
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775 struct reduceDB_lt {
01776 bool operator () (Clause* x, Clause* y) {
01777 return x->size() > 2 && (y->size() == 2 || x->activity() < y->activity());
01778 }
01779 };
01780
01781 void Solver::reduceDB() {
01782 d_stats.lm_simpl++;
01783
01784 size_type i, j;
01785 double extra_lim = d_cla_inc / d_learnts.size();
01786
01787 std::sort(d_learnts.begin(), d_learnts.end(), reduceDB_lt());
01788 for (i = j = 0; i < d_learnts.size() / 2; i++){
01789 if (d_learnts[i]->size() > 2 && !isReason(d_learnts[i]))
01790 remove(d_learnts[i]);
01791 else
01792 d_learnts[j++] = d_learnts[i];
01793 }
01794 for (; i < d_learnts.size(); i++){
01795 if (d_learnts[i]->size() > 2 && !isReason(d_learnts[i]) && d_learnts[i]->activity() < extra_lim)
01796 remove(d_learnts[i]);
01797 else
01798 d_learnts[j++] = d_learnts[i];
01799 }
01800
01801 d_learnts.resize(d_learnts.size() - (i - j), NULL);
01802 d_stats.del_lemmas += (i - j);
01803
01804 d_simpRD_learnts = d_learnts.size();
01805 }
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816 void Solver::simplifyDB() {
01817
01818 if (isConflicting()) return;
01819
01820
01821
01822
01823
01824
01825
01826
01827 DebugAssert(d_qhead == d_trail.size(),
01828 "MiniSat::Solver::simplifyDB: called while propagation queue was not empty");
01829
01830 d_stats.db_simpl++;
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857 for (int type = 0; type < 2; type++){
01858 vector<Clause*>& cs = type ? d_learnts : d_clauses;
01859 size_type j = 0;
01860 bool satisfied = false;
01861 for (vector<Clause*>::const_iterator i = cs.begin(); i != cs.end(); ++i) {
01862 Clause* clause = *i;
01863
01864
01865 if (isReason(clause)) {
01866 cs[j++] = clause;
01867 }
01868 else {
01869 satisfied = false;
01870
01871 int k = 0;
01872 int end = clause->size() - 1;
01873
01874
01875
01876 while (
01877 (getLevel((*clause)[end]) == d_rootLevel)
01878 &&
01879 (getValue((*clause)[end]) == l_False)) {
01880 DebugAssert(end > 0,
01881 "MiniSat::Solver::simplifyDB: permanently falsified clause found");
01882 --end;
01883 }
01884
01885 while (k < end) {
01886 Lit lit((*clause)[k]);
01887 if (getLevel(lit) != d_rootLevel) {
01888 ++k;
01889 }
01890 else if (getValue(lit) == l_True) {
01891 if (isImpliedAt(lit, clause->pushID())) {
01892 satisfied = true;
01893 break;
01894 }
01895 else {
01896 ++k;
01897 }
01898 }
01899 else if (k > 1 && getValue(lit) == l_False) {
01900 --end;
01901 (*clause)[k] = (*clause)[end];
01902 (*clause)[end] = lit;
01903 } else {
01904 ++k;
01905 }
01906 }
01907
01908 if (satisfied) {
01909 d_stats.del_clauses++;
01910 remove(clause);
01911 }
01912 else {
01913 cs[j++] = clause;
01914 }
01915 }
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928 }
01929 cs.resize(j);
01930 }
01931
01932 d_simpDB_assigns = 0;
01933 d_simpDB_props = d_stats.clauses_literals + d_stats.learnts_literals;
01934 }
01935
01936
01937 void Solver::protocolPropagation() const {
01938 if (protocol) {
01939 Lit lit(d_trail[d_qhead]);
01940 cout << "propagate: " << decisionLevel() << " : " << lit.index() << endl;
01941 cout << "propagate: " << decisionLevel() << " : " << toString(lit, true)
01942 << " at: " << getLevel(lit);
01943 if (getReason(lit.var()) != Clause::Decision())
01944 cout << " from: " << toString(*getReason(lit.var()), true);
01945 cout << endl;
01946 }
01947 }
01948
01949
01950 void Solver::propLookahead(const SearchParams& params) {
01951
01952 vector<Var> nextVars(prop_lookahead);
01953 vector<Var>::size_type fetchedVars = 0;
01954 while (fetchedVars < nextVars.size()) {
01955 Var nextVar = d_order.select(params.random_var_freq);
01956 if (isRegistered(nextVar) || nextVar == var_Undef) {
01957 nextVars[fetchedVars] = nextVar;
01958 ++fetchedVars;
01959 }
01960 }
01961
01962 for (vector<Var>::size_type i = 0; i < nextVars.size(); ++i) {
01963 if (nextVars[i] != var_Undef) d_order.undo(nextVars[i]);
01964 }
01965
01966
01967
01968 int level = decisionLevel();
01969 int first_invalid = d_trail.size();
01970
01971 for (vector<Var>::size_type i = 0; i < nextVars.size(); ++i) {
01972 Var nextVar = nextVars[i];
01973 if (nextVar == var_Undef) continue;
01974
01975 for (int sign = 0; sign < 2; ++sign) {
01976
01977 if (sign == 0) {
01978 assume(Lit(nextVar, true));
01979 } else {
01980 assume(Lit(nextVar, false));
01981 }
01982
01983 while (d_qhead < d_trail.size() && !isConflicting()) {
01984 protocolPropagation();
01985 propagate();
01986 }
01987
01988 if (isConflicting()) return;
01989
01990
01991 for (int i = d_trail.size() - 1; i >= first_invalid; --i) {
01992 Var x = d_trail[i].var();
01993 d_assigns[x] = toInt(l_Undef);
01994 d_reason [x] = NULL;
01995 d_order.undo(x);
01996 }
01997 d_trail.resize(first_invalid);
01998 d_trail_lim.resize(level);
01999 d_qhead = first_invalid;
02000 }
02001 }
02002 }
02003
02004
02005 CVC3::QueryResult Solver::search() {
02006 DebugAssert(d_popRequests == 0, "MiniSat::Solver::search: pop requests pending");
02007 DebugAssert(!d_pushes.empty(), "MiniSat::Solver::search: no push before search");
02008
02009 d_inSearch = true;
02010
02011 SearchParams params(d_default_params);
02012 d_stats.starts++;
02013 d_var_decay = 1 / params.var_decay;
02014 d_cla_decay = 1 / params.clause_decay;
02015
02016 if (protocol) printState();
02017
02018
02019
02020 if (!d_ok) {
02021 if (getDerivation() != NULL) getDerivation()->finish(d_conflict, this);
02022 return CVC3::UNSATISFIABLE;
02023 }
02024
02025
02026 SAT::Lit literal;
02027 SAT::CNF_Formula_Impl clauses;
02028 for (;;){
02029
02030
02031 DebugAssert(d_thead <= d_qhead, "MiniSat::Solver::search: thead <= qhead");
02032 DebugAssert(d_trail_lim.size() == 0 || d_qhead >= (size_type)d_trail_lim[decisionLevel() - 1],
02033 "MiniSat::Solver::search: qhead >= trail_lim[decisionLevel()");
02034 DebugAssert(d_trail_lim.size() == 0 || d_thead >= (size_type)d_trail_lim[decisionLevel() - 1],
02035 "MiniSat::Solver::search: thead >= trail_lim[decisionLevel()");
02036
02037
02038 if (!d_ok) {
02039 d_stats.conflicts++;
02040 if (getDerivation() != NULL) getDerivation()->finish(d_conflict, this);
02041 return CVC3::UNSATISFIABLE;
02042 }
02043
02044
02045 if (d_theoryAPI->outOfResources()) {
02046 return CVC3::ABORT;
02047 }
02048
02049
02050 if (d_conflict != NULL){
02051 d_stats.conflicts++;
02052
02053
02054 if (decisionLevel() == d_rootLevel){
02055 d_ok = false;
02056 if (getDerivation() != NULL) getDerivation()->finish(d_conflict, this);
02057 return CVC3::UNSATISFIABLE;
02058 }
02059
02060 int backtrack_level;
02061 Clause* learnt_clause = analyze(backtrack_level);
02062 backtrack(backtrack_level, learnt_clause);
02063 if (protocol) {
02064 cout << "conflict clause: " << toString(*learnt_clause, true);
02065 clauses.print();
02066 }
02067 varDecayActivity();
02068 claDecayActivity();
02069
02070 if (protocol) {
02071 cout << "backtrack to: " << backtrack_level << endl;
02072 }
02073 }
02074
02075
02076 else if (d_theoryAPI->checkConsistent(clauses, false) == SAT::DPLLT::INCONSISTENT) {
02077 if (protocol) {
02078 cout << "theory inconsistency: " << endl;
02079 clauses.print();
02080 }
02081 d_stats.theory_conflicts++;
02082 addFormula(clauses, true);
02083 clauses.reset();
02084 while (!isConflicting() && d_ok && d_qhead < d_trail.size() && !isConflicting()) {
02085 protocolPropagation();
02086 propagate();
02087 }
02088 DebugAssert(isConflicting(), "expected conflict");
02089 }
02090
02091
02092 else if (d_qhead < d_trail.size()) {
02093
02094
02095 if (defer_theory_propagation) {
02096 while (d_ok && d_qhead < d_trail.size() && !isConflicting()) {
02097 protocolPropagation();
02098 propagate();
02099 }
02100 }
02101
02102 else {
02103 protocolPropagation();
02104 propagate();
02105 }
02106 }
02107
02108
02109
02110
02111
02112 else if (defer_theory_propagation && d_thead < d_qhead) {
02113 while (d_thead < d_qhead) {
02114 d_theoryAPI->assertLit(miniSatToCVC(d_trail[d_thead]));
02115 ++d_thead;
02116 }
02117 }
02118
02119
02120 else {
02121 DebugAssert(d_qhead == d_thead, "MiniSat::Solver::search: d_qhead != d_thead");
02122
02123
02124 if (d_theoryAPI->getNewClauses(clauses)) {
02125 if (protocol) {
02126 cout << "theory clauses: " << endl;
02127 clauses.print();
02128 printState();
02129 }
02130
02131 addFormula(clauses, true);
02132 clauses.reset();
02133 continue;
02134 }
02135
02136
02137 literal = d_theoryAPI->getImplication();
02138 if (!literal.isNull()) {
02139 Lit lit = MiniSat::cvcToMiniSat(literal);
02140 if (protocol) {
02141 cout << "theory implication: " << lit.index() << endl;
02142 }
02143 if (
02144
02145 eager_explanation
02146 ||
02147
02148
02149 !enqueue(lit, decisionLevel(), Clause::TheoryImplication())
02150 ) {
02151 d_theoryAPI->getExplanation(literal, clauses);
02152 if (protocol) {
02153 cout << "theory implication reason: " << endl;
02154 clauses.print();
02155 }
02156 addFormula(clauses, true);
02157 clauses.reset();
02158 }
02159 continue;
02160 }
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171 Lit next = lit_Undef;
02172
02173
02174
02175 if (d_decider != NULL) {
02176 literal = d_decider->makeDecision();
02177 if (!literal.isNull()) {
02178 next = MiniSat::cvcToMiniSat(literal);
02179 }
02180 }
02181
02182 else {
02183 Var nextVar = d_order.select(params.random_var_freq);
02184 if (nextVar != var_Undef){
02185 next = ~Lit(nextVar, false);
02186 }
02187 }
02188 if (next != lit_Undef) {
02189
02190
02191
02192 if (false && d_simpDB_props <= 0 && d_simpDB_assigns > (nAssigns() / 10)) {
02193 simplifyDB();
02194 DebugAssert(d_ok, "MiniSat::Solver::search: simplifyDB resulted in conflict");
02195 }
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209 d_stats.decisions++;
02210 d_theoryAPI->push();
02211
02212 DebugAssert(getValue(next) == l_Undef,
02213 "MiniSat::Solver::search not undefined split variable chosen.");
02214
02215 if (protocol) {
02216 cout << "Split: " << next.index() << endl;
02217 }
02218
02219
02220 if (d_decider != NULL) propLookahead(params);
02221 if (isConflicting()) {
02222 ++d_stats.debug;
02223 continue;
02224 }
02225
02226
02227 if (!assume(next)) {
02228 DebugAssert(false, "MiniSat::Solver::search contradictory split variable chosen.");
02229 }
02230 continue;
02231 }
02232
02233
02234 SAT::DPLLT::ConsistentResult result = d_theoryAPI->checkConsistent(clauses, true);
02235
02236 if (result == SAT::DPLLT::INCONSISTENT) {
02237 if (protocol) {
02238 cout << "theory conflict (FULL): " << endl;
02239 clauses.print();
02240 printState();
02241 }
02242 d_stats.theory_conflicts++;
02243 addFormula(clauses, true);
02244 clauses.reset();
02245 while (!isConflicting() && d_ok && d_qhead < d_trail.size() && !isConflicting()) {
02246 protocolPropagation();
02247 propagate();
02248 }
02249 DebugAssert(isConflicting(), "expected conflict");
02250 continue;
02251 }
02252
02253 if (result == SAT::DPLLT::MAYBE_CONSISTENT) {
02254 if (d_theoryAPI->getNewClauses(clauses)) {
02255 if (protocol) {
02256 cout << "theory clauses: " << endl;
02257 clauses.print();
02258 }
02259 addFormula(clauses, true);
02260 clauses.reset();
02261 }
02262
02263
02264
02265 continue;
02266 }
02267
02268 if (result == SAT::DPLLT::CONSISTENT) {
02269 DebugAssert(d_decider == NULL || d_decider->makeDecision().isNull(),
02270 "DPLLTMiniSat::search: consistent result, but decider not done yet.");
02271 DebugAssert(allClausesSatisfied(),
02272 "DPLLTMiniSat::search: consistent result, but not all clauses satisfied.");
02273 return CVC3::SATISFIABLE;
02274 }
02275
02276 FatalAssert(false, "DPLLTMiniSat::search: unreachable");
02277 return CVC3::SATISFIABLE;
02278 }
02279 }
02280 }
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290 void Solver::varRescaleActivity() {
02291 for (int i = 0; i < nVars(); i++)
02292 d_activity[i] *= 1e-100;
02293 d_var_inc *= 1e-100;
02294 }
02295
02296
02297
02298
02299 void Solver::claRescaleActivity() {
02300 for (vector<Clause*>::const_iterator i = d_learnts.begin(); i != d_learnts.end(); i++) {
02301 (*i)->setActivity((*i)->activity() * (float)1e-20);
02302 }
02303 d_cla_inc *= 1e-20;
02304 }
02305
02306
02307
02308
02309
02310
02311
02312
02313 bool Solver::allClausesSatisfied() {
02314 if (!debug_full) return true;
02315
02316 for (size_type i = 0; i < d_clauses.size(); ++i) {
02317 Clause& clause = *d_clauses[i];
02318 int size = clause.size();
02319 bool satisfied = false;
02320 for (int j = 0; j < size; ++j) {
02321 if (getValue(clause[j]) == l_True) {
02322 satisfied = true;
02323 break;
02324 }
02325 }
02326 if (!satisfied) {
02327 cout << "Clause not satisfied:" << endl;
02328 cout << toString(clause, true);
02329
02330 for (int j = 0; j < size; ++j) {
02331 Lit lit = clause[j];
02332 bool found = false;
02333 const vector<Clause*>& ws = getWatches(~lit);
02334 if (getLevel(lit) == d_rootLevel) {
02335 found = true;
02336 } else {
02337 for (size_type j = 0; !found && j < ws.size(); ++j) {
02338 if (ws[j] == &clause) {
02339 found = true;
02340 break;
02341 }
02342 }
02343 }
02344
02345 if (found) {
02346 cout << " watched: " << toString(lit, true) << endl;
02347 } else {
02348 cout << "not watched: " << toString(lit, true) << endl;
02349 }
02350 }
02351
02352 return false;
02353 }
02354 }
02355 return true;
02356 }
02357
02358
02359 void Solver::checkWatched(const Clause& clause) const {
02360
02361 if (clause.size() < 2) return;
02362
02363 for (int i = 0; i < 2; ++i) {
02364 Lit lit = clause[i];
02365 bool found = false;
02366 const vector<Clause*>& ws = getWatches(~lit);
02367
02368
02369 if (getLevel(lit) == d_rootLevel) found = true;
02370
02371
02372 for (size_type j = 0; !found && j < ws.size(); ++j) {
02373 if (ws[j] == &clause) found = true;
02374 }
02375
02376 if (!found) {
02377 printState();
02378 cout << toString(clause, true) << " : " << toString(clause[i], false) << endl;
02379 FatalAssert(false, "MiniSat::Solver::checkWatched");
02380 }
02381 }
02382 }
02383
02384 void Solver::checkWatched() const {
02385 if (!debug_full) return;
02386
02387 for (size_type i = 0; i < d_clauses.size(); ++i) {
02388 checkWatched(*d_clauses[i]);
02389 }
02390
02391 for (size_type i = 0; i < d_learnts.size(); ++i) {
02392 checkWatched(*d_learnts[i]);
02393 }
02394 }
02395
02396
02397
02398 void Solver::checkClause(const Clause& clause) const {
02399
02400 if (clause.size() < 2) return;
02401
02402
02403 if (getValue(clause[0]) == l_Undef && getValue(clause[1]) == l_Undef)
02404 return;
02405
02406
02407 else if (getValue(clause[0]) == l_True || getValue(clause[1]) == l_True)
02408 return;
02409
02410
02411
02412 else {
02413 bool ok = true;
02414 if (getValue(clause[0]) == l_True)
02415 ok = false;
02416
02417 for (int j = 1; ok && j < clause.size(); ++j) {
02418 if (getValue(clause[j]) != l_False) {
02419 ok = false;
02420 }
02421 }
02422
02423 if (ok) return;
02424 }
02425
02426 printState();
02427 cout << endl;
02428 cout << toString(clause, true) << endl;
02429 FatalAssert(false, "MiniSat::Solver::checkClause");
02430 }
02431
02432 void Solver::checkClauses() const {
02433 if (!debug_full) return;
02434
02435 for (size_type i = 0; i < d_clauses.size(); ++i) {
02436 checkClause(*d_clauses[i]);
02437 }
02438
02439 for (size_type i = 0; i < d_learnts.size(); ++i) {
02440 checkClause(*d_learnts[i]);
02441 }
02442 }
02443
02444
02445
02446 void Solver::checkTrail() const {
02447 if (!debug_full) return;
02448
02449 for (size_type i = 0; i < d_trail.size(); ++i) {
02450 Lit lit = d_trail[i];
02451 Var var = lit.var();
02452 Clause* reason = d_reason[var];
02453
02454 if (reason == Clause::Decision()
02455 ||
02456 reason == Clause::TheoryImplication()) {
02457 }
02458
02459 else {
02460 const Clause& clause = *reason;
02461
02462
02463 FatalAssert(clause.size() > 0, "MiniSat::Solver::checkTrail: empty clause as reason for " );
02464 FatalAssert(lit == clause[0], "MiniSat::Solver::checkTrail: incorrect reason for " );
02465 FatalAssert(d_assigns[var] == toInt(lbool(lit.sign())), "MiniSat::Solver::checkTrail: incorrect value for " );
02466
02467
02468 for (int j = 1; j < clause.size(); ++j) {
02469 Lit clauseLit = clause[j];
02470 Var clauseVar = clauseLit.var();
02471 FatalAssert(getLevel(var) >= getLevel(clauseVar),
02472 "MiniSat::Solver::checkTrail: depends on later asserted literal " );
02473
02474 bool found = false;
02475 for (size_type k = 0; k < i; ++k) {
02476 if (d_trail[k] == ~clauseLit) {
02477 found = true;
02478 break;
02479 }
02480 }
02481 FatalAssert(found, "MiniSat::Solver::checkTrail: depends on literal not in context " );
02482 }
02483 }
02484 }
02485 }
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496 void Solver::setPushID(Var var, Clause* from) {
02497
02498 DebugAssert(getReason(var) == from, "MiniSat::Solver::setPushID: wrong reason given");
02499 int pushID = std::numeric_limits<int>::max();
02500 if (from != Clause::Decision() && from != Clause::TheoryImplication()) {
02501 pushID = from->pushID();
02502 for (int i = 1; i < from->size(); ++i) {
02503 pushID = std::max(pushID, getPushID((*from)[i]));
02504 }
02505 }
02506 d_pushIDs[var] = pushID;
02507 }
02508
02509
02510 void Solver::push() {
02511 DebugAssert(!inSearch(), "MiniSat::Solver::push: already in search");
02512
02513
02514
02515
02516 if (!d_ok) {
02517 d_pushes.push_back(PushEntry(-1, 0, 0, 0, true));
02518 return;
02519 }
02520
02521 d_registeredVars.resize(d_registeredVars.size() + 1);
02522
02523
02524 for (vector<Clause*>::const_iterator i = d_popLemmas.begin(); i != d_popLemmas.end(); ++i) {
02525 Clause* lemma = *i;
02526 insertLemma(lemma, lemma->id(), lemma->pushID());
02527 d_stats.learnts_literals -= lemma->size();
02528 remove(lemma, true);
02529 }
02530 d_popLemmas.clear();
02531
02532
02533 if (push_theory_propagation) {
02534 SAT::Lit literal;
02535 SAT::Clause clause;
02536 SAT::CNF_Formula_Impl clauses;
02537
02538 while (!isConflicting() && (d_qhead < d_trail.size() || d_thead < d_qhead)) {
02539
02540 while (!isConflicting() && d_qhead < d_trail.size()) {
02541 protocolPropagation();
02542 propagate();
02543 }
02544
02545
02546 if (defer_theory_propagation) {
02547 while (!isConflicting() && d_thead < d_qhead) {
02548 d_theoryAPI->assertLit(miniSatToCVC(d_trail[d_thead]));
02549 ++d_thead;
02550 }
02551 }
02552
02553
02554 if (push_theory_implication) {
02555 literal = d_theoryAPI->getImplication();
02556 if (!literal.isNull()) {
02557 Lit lit = MiniSat::cvcToMiniSat(literal);
02558 if (protocol) {
02559 cout << "theory implication: " << lit.index() << endl;
02560 }
02561 if (
02562
02563 eager_explanation
02564 ||
02565
02566
02567 !enqueue(lit, decisionLevel(), Clause::TheoryImplication())
02568 ) {
02569 d_theoryAPI->getExplanation(literal, clauses);
02570 if (protocol) {
02571 cout << "theory implication reason: " << endl;
02572 clauses.print();
02573 }
02574 addFormula(clauses, false);
02575 clauses.reset();
02576 }
02577 continue;
02578 }
02579 }
02580
02581
02582
02583
02584 if (push_theory_clause ) {
02585 bool hasNewClauses = d_theoryAPI->getNewClauses(clauses);
02586 if(hasNewClauses){
02587 if (protocol) {
02588 cout << "theory clauses: " << endl;
02589 clauses.print();
02590 printState();
02591 }
02592 addFormula(clauses, false);
02593 clauses.reset();
02594 continue;
02595 }
02596 }
02597 }
02598 }
02599
02600 else {
02601 while (!isConflicting() && d_qhead < d_trail.size()) {
02602 protocolPropagation();
02603 propagate();
02604 }
02605 }
02606
02607
02608 simplifyDB();
02609
02610
02611
02612
02613 if (isConflicting()) d_ok = false;
02614
02615 if (d_derivation != NULL) d_derivation->push(d_clauseIDCounter - 1);
02616 d_pushes.push_back(PushEntry(d_clauseIDCounter - 1, d_trail.size(), d_qhead, d_thead, d_ok));
02617 }
02618
02619
02620
02621 void Solver::requestPop() {
02622 DebugAssert(inPush(), "MiniSat::Solver::requestPop: no more pushes");
02623
02624
02625
02626 if (d_popRequests == 0 && isConsistent()) popTheories();
02627 ++d_popRequests;
02628 }
02629
02630 void Solver::doPops() {
02631 if (d_popRequests == 0) return;
02632
02633 while (d_popRequests > 1) {
02634 --d_popRequests;
02635 d_pushes.pop_back();
02636 }
02637
02638 pop();
02639 }
02640
02641 void Solver::popTheories() {
02642 for (int i = d_rootLevel; i < decisionLevel(); ++i) {
02643 d_theoryAPI->pop();
02644 }
02645 }
02646
02647 void Solver::popClauses(const PushEntry& pushEntry, vector<Clause*>& clauses) {
02648 size_type i = 0;
02649 while (i != clauses.size()) {
02650
02651 if (clauses[i]->pushID() >= 0
02652 &&
02653 clauses[i]->pushID() <= pushEntry.d_clauseID) {
02654
02655
02656 ++i;
02657 }
02658
02659 else {
02660
02661 remove(clauses[i]);
02662 clauses[i] = clauses.back();
02663 clauses.pop_back();
02664 }
02665 }
02666 }
02667
02668 void Solver::pop() {
02669 DebugAssert(d_popRequests == 1, "Minisat::Solver::pop: d_popRequests != 1");
02670
02671 --d_popRequests;
02672 PushEntry pushEntry = d_pushes.back();
02673 d_pushes.pop_back();
02674
02675
02676 if (pushEntry.d_clauseID == -1) {
02677 DebugAssert(!d_ok, "Minisat::Solver::pop: inconsistent push, but d_ok == true");
02678 return;
02679 }
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689 size_type first_invalid = pushEntry.d_trailSize;
02690 for (size_type i = pushEntry.d_trailSize; i != d_trail.size(); ++i) {
02691 Var x = d_trail[i].var();
02692
02693 d_assigns[x] = toInt(l_Undef);
02694 d_reason [x] = NULL;
02695
02696 d_order.undo(x);
02697 }
02698 d_trail.resize(first_invalid);
02699 d_trail_lim.resize(0);
02700 d_qhead = pushEntry.d_qhead;
02701 d_thead = pushEntry.d_thead;
02702
02703
02704 popClauses(pushEntry, d_clauses);
02705
02706
02707
02708
02709 size_type i = 0;
02710 while (i != d_popLemmas.size()) {
02711 if (d_popLemmas[i]->pushID() <= pushEntry.d_clauseID) {
02712 ++i;
02713 } else {
02714 remove(d_popLemmas[i], true);
02715 d_popLemmas[i] = d_popLemmas.back();
02716 d_popLemmas.pop_back();
02717 }
02718 }
02719
02720 i = 0;
02721 while (i != d_learnts.size()) {
02722 Clause* lemma = d_learnts[i];
02723
02724 if (isReason(lemma)) {
02725
02726
02727 ++i;
02728 }
02729
02730 else {
02731 d_stats.learnts_literals -= lemma->size();
02732
02733 if (lemma->pushID() <= pushEntry.d_clauseID) {
02734
02735
02736 if (lemma->size() >= 2) {
02737 removeWatch(getWatches(~(*lemma)[0]), lemma);
02738 removeWatch(getWatches(~(*lemma)[1]), lemma);
02739 }
02740 d_popLemmas.push_back(lemma);
02741 }
02742
02743 else {
02744
02745 remove(lemma);
02746 }
02747
02748 d_learnts[i] = d_learnts.back();
02749 d_learnts.pop_back();
02750 }
02751 }
02752 d_stats.debug += d_popLemmas.size();
02753
02754
02755
02756 while (!d_pendingClauses.empty()) {
02757 remove(d_pendingClauses.front(), true);
02758 d_pendingClauses.pop();
02759 }
02760 while (!d_theoryExplanations.empty()) {
02761 remove(d_theoryExplanations.top().second, true);
02762 d_theoryExplanations.pop();
02763 }
02764
02765
02766
02767 d_registeredVars.resize(d_pushes.size() + 1);
02768
02769 if (pushEntry.d_ok) {
02770
02771
02772 if (d_derivation != NULL) d_derivation->pop(pushEntry.d_clauseID);
02773
02774
02775 d_conflict = NULL;
02776 d_ok = true;
02777 d_inSearch = false;
02778 } else {
02779 DebugAssert(d_conflict != NULL, "MiniSat::Solver::pop: not in conflict 1");
02780 DebugAssert(!d_ok, "MiniSat::Solver::pop: not in conflict 2");
02781 }
02782 }