00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "minisat_derivation.h"
00023 #include "minisat_solver.h"
00024 #include <set>
00025 #include <iostream>
00026
00027 using namespace MiniSat;
00028 using namespace std;
00029
00030 std::string Inference::toString() const {
00031 ostringstream buffer;
00032 buffer << getStart();
00033 for (Inference::TSteps::const_iterator step = d_steps.begin(); step != d_steps.end(); ++step) {
00034 buffer << " " << step->first.toString() << " " << step->second;
00035 }
00036 return buffer.str();
00037 }
00038
00039
00040
00041
00042
00043 Derivation::~Derivation() {
00044
00045 for (TClauses::iterator i = d_unitClauses.begin(); i != d_unitClauses.end(); ++i) {
00046 xfree(i->second);
00047 }
00048
00049
00050 for (std::deque<Clause*>::iterator i = d_removedClauses.begin(); i != d_removedClauses.end(); ++i) {
00051 xfree(*i);
00052 }
00053
00054
00055 for (TInferences::iterator i = d_inferences.begin(); i != d_inferences.end(); ++i) {
00056 delete i->second;
00057 }
00058 }
00059
00060
00061 int Derivation::computeRootReason(Lit implied, Solver* solver) {
00062 Clause* reason = solver->getReason(implied);
00063 DebugAssert(reason != NULL, "MiniSat::Derivation::computeRootReason: implied reason is NULL");
00064 DebugAssert(reason != Clause::Decision(), "MiniSat::Derivation::computeRootReason: implied is a decision");
00065 DebugAssert((*reason)[0] == implied, "MiniSat::Derivation::computeRootReason: implied is not in its reason");
00066 IF_DEBUG (
00067 DebugAssert(solver->getValue((*reason)[0]) == l_True,
00068 "MiniSat::Derivation::computeRootReason: literal not implied (TRUE)");
00069 for (int i = 1; i < reason->size(); ++i) {
00070 DebugAssert(solver->getValue((*reason)[i]) == l_False,
00071 "MiniSat::Derivation::computeRootReason: literal not implied (FALSE)");
00072 }
00073 )
00074
00075
00076 if (reason->size() == 1) {
00077 return reason->id();
00078 }
00079
00080
00081 TClauses::const_iterator iter = d_unitClauses.find(implied.index());
00082 if (iter != d_unitClauses.end()) {
00083 return iter->second->id();
00084 }
00085
00086
00087
00088 Inference* inference = new Inference(reason->id());
00089 for (int i = 1; i < reason->size(); ++i) {
00090 Lit lit((*reason)[i]);
00091 inference->add(lit, computeRootReason(~lit, solver));
00092 }
00093
00094
00095
00096 vector<Lit> literals;
00097 literals.push_back(implied);
00098 Clause* unit = Clause_new(literals, solver->nextClauseID());
00099
00100 d_unitClauses[implied.index()] = unit;
00101 registerClause(unit);
00102 registerInference(unit->id(), inference);
00103
00104 return unit->id();
00105 }
00106
00107
00108 void Derivation::finish(Clause* clause, Solver* solver) {
00109 DebugAssert(clause != NULL, "MiniSat::derivation:finish:");
00110
00111
00112 if (clause->size() == 0) {
00113 d_emptyClause = clause;
00114 }
00115
00116 else {
00117 Inference* inference = new Inference(clause->id());
00118 for (int i = 0; i < clause->size(); ++i) {
00119 Lit lit((*clause)[i]);
00120 inference->add(lit, computeRootReason(~lit, solver));
00121 }
00122 vector<Lit> literals;
00123 Clause* empty = Clause_new(literals, solver->nextClauseID());
00124 removedClause(empty);
00125 d_emptyClause = empty;
00126 registerClause(empty);
00127 registerInference(empty->id(), inference);
00128 }
00129
00130
00131
00132
00133 };
00134
00135
00136 void Derivation::printProof() {
00137 DebugAssert(d_emptyClause != NULL, "MiniSat::Derivation:printProof: no empty clause");
00138 printProof(d_emptyClause);
00139 }
00140
00141 void Derivation::printProof(Clause* clause) {
00142
00143
00144
00145
00146 std::set<int> relevant;
00147 std::set<int> regress;
00148
00149 regress.insert(clause->id());
00150 while (!regress.empty()) {
00151
00152 int clauseID = *(regress.rbegin());
00153 regress.erase(clauseID);
00154
00155
00156 DebugAssert(relevant.count(clauseID) == 0, "Solver::printProof: already in relevant");
00157 relevant.insert(clauseID);
00158
00159
00160 TInferences::const_iterator iter = d_inferences.find(clauseID);
00161
00162 if (iter == d_inferences.end()) {
00163 DebugAssert(d_inputClauses.contains(clauseID),
00164 "Solver::printProof: clause without antecedents is not marked as input clause");
00165 }
00166
00167 else {
00168 Inference* inference = iter->second;
00169 regress.insert(inference->getStart());
00170 const Inference::TSteps& steps = inference->getSteps();
00171 for (Inference::TSteps::const_iterator step = steps.begin(); step != steps.end(); ++step) {
00172 regress.insert(step->second);
00173 }
00174 }
00175 }
00176
00177
00178
00179 for (std::set<int>::iterator i = relevant.begin(); i != relevant.end(); ++i) {
00180 int clauseID = *i;
00181 DebugAssert(d_clauses.contains(clauseID), "Solver::printProof: clause id in proof is not in clauses");
00182 Clause* clause = d_clauses.find(clauseID)->second;
00183
00184 Inference* inference = NULL;
00185 TInferences::const_iterator j = d_inferences.find(clauseID);
00186 if (j != d_inferences.end()) {
00187 inference = j->second;
00188 }
00189
00190
00191 cout << clauseID;
00192
00193 if (d_inputClauses.contains(clauseID)) {
00194 cout << " I ";
00195 } else {
00196 cout << " D ";
00197 }
00198 cout << ": " << clause->toString() << " : ";
00199 if (inference != NULL) cout << inference->toString();
00200 cout << endl;
00201 }
00202 }
00203
00204
00205 void Derivation::push(int clauseID) {
00206 }
00207
00208 void Derivation::pop(int clauseID) {
00209
00210 TClauses::iterator i = d_clauses.begin();
00211 while (i != d_clauses.end()) {
00212 if ((*i).second->pushID() > clauseID) {
00213 int id = (*i).first;
00214 ++i;
00215 d_clauses.erase(id);
00216 d_unitClauses.erase(id);
00217 d_inferences.erase(id);
00218 }
00219 else {
00220 ++i;
00221 }
00222 }
00223
00224
00225 if (d_emptyClause != NULL && d_emptyClause->pushID() > clauseID)
00226 d_emptyClause = NULL;
00227
00228
00229 std::deque<Clause*>::iterator j = d_removedClauses.begin();
00230 while (j != d_removedClauses.end()) {
00231 if ((*j)->pushID() > clauseID) {
00232 xfree(*j);
00233 j = d_removedClauses.erase(j);
00234 } else {
00235 ++j;
00236 }
00237 }
00238 }