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 "sat_proof.h"
00025 #include <set>
00026 #include <iostream>
00027
00028 using namespace MiniSat;
00029 using namespace std;
00030
00031 std::string Inference::toString() const {
00032 ostringstream buffer;
00033 buffer << getStart();
00034 for (Inference::TSteps::const_iterator step = d_steps.begin(); step != d_steps.end(); ++step) {
00035 buffer << " " << step->first.toString() << " " << step->second;
00036 }
00037 return buffer.str();
00038 }
00039
00040
00041
00042
00043
00044 Derivation::~Derivation() {
00045
00046 for (TClauses::iterator i = d_unitClauses.begin(); i != d_unitClauses.end(); ++i) {
00047 xfree(i->second);
00048 }
00049
00050
00051 for (std::deque<Clause*>::iterator i = d_removedClauses.begin(); i != d_removedClauses.end(); ++i) {
00052 xfree(*i);
00053 }
00054
00055
00056 for (TInferences::iterator i = d_inferences.begin(); i != d_inferences.end(); ++i) {
00057 delete i->second;
00058 }
00059 }
00060
00061
00062 int Derivation::computeRootReason(Lit implied, Solver* solver) {
00063 Clause* reason = solver->getReason(implied);
00064
00065 FatalAssert(d_clauses.find(reason->id()) != d_clauses.end(),
00066 "MiniSat::Derivation::computeRootReason: implied reason not registered");
00067 FatalAssert(reason == d_clauses.find(reason->id())->second,
00068 "MiniSat::Derivation::computeRootReason: implied reason not same as registered");
00069 FatalAssert(reason != NULL, "MiniSat::Derivation::computeRootReason: implied reason is NULL");
00070 FatalAssert(reason != Clause::Decision(), "MiniSat::Derivation::computeRootReason: implied is a decision");
00071 FatalAssert((*reason)[0] == implied, "MiniSat::Derivation::computeRootReason: implied is not in its reason");
00072 IF_DEBUG (
00073 FatalAssert(solver->getValue((*reason)[0]) == l_True,
00074 "MiniSat::Derivation::computeRootReason: literal not implied (TRUE)");
00075 for (int i = 1; i < reason->size(); ++i) {
00076 FatalAssert(solver->getValue((*reason)[i]) == l_False,
00077 "MiniSat::Derivation::computeRootReason: literal not implied (FALSE)");
00078 }
00079 )
00080
00081
00082 if (reason->size() == 1) {
00083 return reason->id();
00084 }
00085
00086
00087 TClauses::const_iterator iter = d_unitClauses.find(implied.index());
00088 if (iter != d_unitClauses.end()) {
00089 return iter->second->id();
00090 }
00091
00092
00093
00094 Inference* inference = new Inference(reason->id());
00095 for (int i = 1; i < reason->size(); ++i) {
00096 Lit lit((*reason)[i]);
00097 inference->add(lit, computeRootReason(~lit, solver));
00098 }
00099
00100
00101
00102 vector<Lit> literals;
00103 literals.push_back(implied);
00104 Clause* unit = Clause_new(literals, CVC3::Theorem(), solver->nextClauseID());
00105
00106 d_unitClauses[implied.index()] = unit;
00107
00108 registerClause(unit);
00109 registerInference(unit->id(), inference);
00110
00111 return unit->id();
00112 }
00113
00114
00115 void Derivation::finish(Clause* clause, Solver* solver) {
00116 FatalAssert(clause != NULL, "MiniSat::derivation:finish:");
00117
00118
00119 if (clause->size() == 0) {
00120 d_emptyClause = clause;
00121 }
00122
00123 else {
00124 Inference* inference = new Inference(clause->id());
00125 for (int i = 0; i < clause->size(); ++i) {
00126 Lit lit((*clause)[i]);
00127 inference->add(lit, computeRootReason(~lit, solver));
00128 }
00129 vector<Lit> literals;
00130 Clause* empty = Clause_new(literals, CVC3::Theorem(), solver->nextClauseID());
00131 removedClause(empty);
00132 d_emptyClause = empty;
00133 registerClause(empty);
00134 registerInference(empty->id(), inference);
00135 }
00136
00137 checkDerivation(clause);
00138 IF_DEBUG (checkDerivation(clause));
00139
00140
00141
00142
00143
00144 }
00145
00146
00147
00148 void Derivation::checkDerivation(Clause* clause) {
00149
00150
00151
00152
00153 std::set<int> relevant;
00154 std::set<int> regress;
00155
00156 regress.insert(clause->id());
00157 while (!regress.empty()) {
00158
00159 int clauseID = *(regress.rbegin());
00160 regress.erase(clauseID);
00161
00162
00163 FatalAssert(relevant.count(clauseID) == 0, "Solver::printProof: already in relevant");
00164 relevant.insert(clauseID);
00165
00166
00167 TInferences::const_iterator iter = d_inferences.find(clauseID);
00168
00169 if (iter == d_inferences.end()) {
00170 FatalAssert(d_inputClauses.contains(clauseID),
00171 "Solver::printProof: clause without antecedents is not marked as input clause");
00172 }
00173
00174 else {
00175 Inference* inference = iter->second;
00176 regress.insert(inference->getStart());
00177 const Inference::TSteps& steps = inference->getSteps();
00178 for (Inference::TSteps::const_iterator step = steps.begin(); step != steps.end(); ++step) {
00179 regress.insert(step->second);
00180 }
00181 }
00182 }
00183
00184
00185
00186 for (std::set<int>::iterator i = relevant.begin(); i != relevant.end(); ++i) {
00187 int clauseID = *i;
00188 FatalAssert(d_clauses.contains(clauseID),
00189 "MiniSat::Derivation::printProof: clause id in proof is not in clauses");
00190 Clause* clause = d_clauses.find(clauseID)->second;
00191
00192 Inference* inference = NULL;
00193 TInferences::const_iterator j = d_inferences.find(clauseID);
00194 if (j != d_inferences.end()) {
00195 inference = j->second;
00196 }
00197
00198 FatalAssert(inference != NULL || d_inputClauses.contains(clauseID),
00199 "MiniSat::Derivation::printProof: derivation of input clause");
00200 FatalAssert(inference == NULL || !d_inputClauses.contains(clauseID),
00201 "MiniSat::Derivation::printProof: no derivation for derived clause");
00202
00203 if (inference != NULL) {
00204
00205 FatalAssert(d_clauses.find(inference->getStart()) != d_clauses.end(),
00206 "MiniSat::Derivation::printProof: first not in clauses");
00207
00208 Clause* first = d_clauses.find(inference->getStart())->second;
00209
00210
00211 set<Lit> derived;
00212 for (int i = 0; i < first->size(); ++i) {
00213 derived.insert((*first)[i]);
00214 }
00215
00216
00217 for (Inference::TSteps::const_iterator step = inference->getSteps().begin();
00218 step != inference->getSteps().end(); ++step) {
00219 Lit lit = step->first;
00220
00221
00222
00223 FatalAssert(d_clauses.find(step->second) != d_clauses.end(),
00224 "MiniSat::Derivation::printProof: next not in clauses");
00225 Clause* next = d_clauses.find(step->second)->second;
00226
00227 FatalAssert(derived.find(lit) != derived.end(),
00228 "MiniSat::Derivation::printProof: lit not in derived");
00229 FatalAssert(next->contains(~lit),
00230 "MiniSat::Derivation::printProof: ~lit not in next");
00231
00232 derived.erase(lit);
00233 for (int i = 0; i < next->size(); ++i) {
00234 if ((*next)[i] != ~lit) {
00235 derived.insert((*next)[i]);
00236 }
00237 }
00238 }
00239
00240
00241 for (int i = 0; i < clause->size(); ++i) {
00242 FatalAssert(derived.find((*clause)[i]) != derived.end(),
00243 "MiniSat::Derivation::printProof: didn't derive expected clause");
00244 derived.erase((*clause)[i]);
00245 }
00246 FatalAssert(derived.empty(),
00247 "MiniSat::Derivation::printProof: didn't derive expected clause 2");
00248 };
00249 }
00250 }
00251
00252
00253 SAT::SatProof* Derivation::createProof() {
00254 FatalAssert(d_emptyClause != NULL, "MiniSat::Derivation:createProof: no empty clause");
00255 FatalAssert(d_emptyClause->size() == 0,
00256 "MiniSat::Derivation:createProof: empty clause is not empty");
00257 return createProof(d_emptyClause);
00258 }
00259
00260 SAT::SatProof* Derivation::createProof(Clause* clause) {
00261 checkDerivation(clause);
00262
00263
00264
00265
00266
00267
00268 std::set<int> relevant;
00269 std::set<int> regress;
00270 regress.insert(clause->id());
00271 while (!regress.empty()) {
00272
00273 int clauseID = *(regress.rbegin());
00274 regress.erase(clauseID);
00275 relevant.insert(clauseID);
00276
00277
00278 TInferences::const_iterator iter = d_inferences.find(clauseID);
00279
00280 if (iter != d_inferences.end()) {
00281 Inference* inference = iter->second;
00282 regress.insert(inference->getStart());
00283 const Inference::TSteps& steps = inference->getSteps();
00284 for (Inference::TSteps::const_iterator step = steps.begin(); step != steps.end(); ++step) {
00285 regress.insert(step->second);
00286 }
00287 }
00288 }
00289
00290
00291 SAT::SatProof* proof = new SAT::SatProof();
00292 std::hash_map<int, SAT::SatProofNode*> proofNodes;
00293
00294 for (std::set<int>::iterator i = relevant.begin(); i != relevant.end(); ++i) {
00295 int clauseID = *i;
00296 Clause* clause = d_clauses.find(clauseID)->second;
00297
00298 Inference* inference = NULL;
00299 TInferences::const_iterator j = d_inferences.find(clauseID);
00300 if (j == d_inferences.end()) {
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 FatalAssert(!clause->getTheorem().isNull(), "createProof: leaf without clause");
00312 proofNodes[clause->id()] = proof->registerLeaf(clause->getTheorem());
00313
00314
00315
00316 }
00317
00318 else {
00319 inference = j->second;
00320 FatalAssert(proofNodes.contains(inference->getStart()), "createProof: contains inference start");
00321 SAT::SatProofNode* left = proofNodes.find(inference->getStart())->second;
00322 const Inference::TSteps& steps = inference->getSteps();
00323 for (Inference::TSteps::const_iterator step = steps.begin(); step != steps.end(); ++step) {
00324 FatalAssert(proofNodes.contains(step->second), "createProof: contains inference start");
00325 SAT::SatProofNode* right = proofNodes.find(step->second)->second;
00326 left = proof->registerNode(left, right, miniSatToCVC(step->first));
00327 }
00328 proofNodes[clause->id()] = left;
00329 }
00330 }
00331 proof->setRoot(proofNodes[clause->id()]);
00332 return proof;
00333 }
00334
00335
00336 void Derivation::printDerivation() {
00337 FatalAssert(d_emptyClause != NULL, "MiniSat::Derivation:printDerivation: no empty clause");
00338 FatalAssert(d_emptyClause->size() == 0,
00339 "MiniSat::Derivation:printDerivation: empty clause is not empty");
00340 printDerivation(d_emptyClause);
00341 }
00342
00343 void Derivation::printDerivation(Clause* clause) {
00344 IF_DEBUG (checkDerivation(clause));
00345
00346
00347
00348
00349
00350 std::set<int> relevant;
00351 std::set<int> regress;
00352
00353 regress.insert(clause->id());
00354 while (!regress.empty()) {
00355
00356 int clauseID = *(regress.rbegin());
00357 regress.erase(clauseID);
00358
00359
00360 relevant.insert(clauseID);
00361
00362
00363 TInferences::const_iterator iter = d_inferences.find(clauseID);
00364
00365 if (iter != d_inferences.end()) {
00366 Inference* inference = iter->second;
00367 regress.insert(inference->getStart());
00368 const Inference::TSteps& steps = inference->getSteps();
00369 for (Inference::TSteps::const_iterator step = steps.begin(); step != steps.end(); ++step) {
00370 regress.insert(step->second);
00371 }
00372 }
00373 }
00374
00375
00376
00377 for (std::set<int>::iterator i = relevant.begin(); i != relevant.end(); ++i) {
00378 int clauseID = *i;
00379 Clause* clause = d_clauses.find(clauseID)->second;
00380
00381 Inference* inference = NULL;
00382 TInferences::const_iterator j = d_inferences.find(clauseID);
00383 if (j != d_inferences.end()) {
00384 inference = j->second;
00385 }
00386
00387
00388 cout << clauseID;
00389
00390 if (d_inputClauses.contains(clauseID)) {
00391 cout << " I ";
00392 } else {
00393 cout << " D ";
00394 }
00395 cout << ": " << clause->toString() << " : ";
00396 if (inference != NULL) cout << inference->toString();
00397 cout << endl;
00398 }
00399 }
00400
00401
00402 void Derivation::push(int clauseID) {
00403
00404 }
00405
00406 void Derivation::pop(int clauseID) {
00407
00408
00409 TClauses::const_iterator i = d_clauses.begin();
00410 while (i != d_clauses.end()) {
00411 Clause* clause = (*i).second;
00412 if (
00413
00414
00415
00416
00417
00418
00419
00420
00421 clause->pushID() > clauseID) {
00422 int id = clause->id();
00423
00424 d_inputClauses.erase(id);
00425 d_inferences.erase(id);
00426
00427 if (clause->size() == 1) {
00428 int index = (*clause)[0].index();
00429 if (d_unitClauses.contains(index) && d_unitClauses[index] == clause) {
00430 d_unitClauses.erase(index);
00431 FatalAssert(!d_unitClauses.contains(index), "AHA");
00432 }
00433 }
00434
00435 i = d_clauses.erase(i);
00436 }
00437 else {
00438 ++i;
00439 }
00440 }
00441
00442
00443 if (d_emptyClause != NULL && d_emptyClause->pushID() > clauseID)
00444 d_emptyClause = NULL;
00445
00446
00447 std::deque<Clause*>::iterator j = d_removedClauses.begin();
00448 while (j != d_removedClauses.end()) {
00449 if ((*j)->pushID() > clauseID) {
00450 xfree(*j);
00451 j = d_removedClauses.erase(j);
00452 } else {
00453 ++j;
00454 }
00455 }
00456 }