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 #include "search.h"
00031 #include "assumptions_value.h"
00032 #include "theory_core.h"
00033 #include "theorem_manager.h"
00034 #include "common_proof_rules.h"
00035
00036
00037 #define _CVCL_TRUSTED_
00038 #include "search_theorem_producer.h"
00039
00040
00041 using namespace std;
00042 using namespace CVCL;
00043
00044
00045
00046
00047
00048
00049 SearchEngineRules*
00050 SearchEngine::createRules() {
00051 return new SearchEngineTheoremProducer(d_core->getTM());
00052 }
00053
00054
00055 SearchEngineTheoremProducer::SearchEngineTheoremProducer(TheoremManager* tm)
00056 : TheoremProducer(tm), d_commonRules(tm->getRules())
00057 { }
00058
00059
00060
00061
00062
00063
00064
00065
00066 Theorem
00067 SearchEngineTheoremProducer::proofByContradiction(const Expr& a,
00068 const Theorem& pfFalse) {
00069 if(CHECK_PROOFS)
00070 CHECK_SOUND(pfFalse.getExpr().isFalse(),
00071 "proofByContradiction: pfFalse = : " + pfFalse.toString());
00072 Expr not_a(!a);
00073 Assumptions assump;
00074 Proof pf;
00075 if(withAssumptions()) {
00076
00077 assump = pfFalse.getAssumptions() - not_a;
00078 }
00079 if(withProof()) {
00080
00081 Theorem thm(pfFalse.getAssumptions()[not_a]);
00082 Proof u;
00083 if(!thm.isNull()) u = thm.getProof();
00084
00085 if(u.isNull())
00086 pf = newPf("false_implies_anything", a, pfFalse.getProof());
00087 else
00088 pf = newPf("pf_by_contradiction", a,
00089
00090 newPf(u, not_a, pfFalse.getProof()));
00091 }
00092 return newTheorem(a, assump, pf);
00093 }
00094
00095
00096
00097 Theorem
00098 SearchEngineTheoremProducer::negIntro(const Expr& not_a,
00099 const Theorem& pfFalse) {
00100 if(CHECK_PROOFS) {
00101 CHECK_SOUND(pfFalse.getExpr().isFalse(),
00102 "negIntro: pfFalse = : " + pfFalse.toString());
00103 CHECK_SOUND(not_a.isNot(), "negIntro: not_a = "+not_a.toString());
00104 }
00105
00106 Expr a(not_a[0]);
00107 Assumptions assump;
00108 Proof pf;
00109 if(withAssumptions()) {
00110
00111 assump = pfFalse.getAssumptions() - a;
00112 }
00113 if(withProof()) {
00114 Theorem thm(pfFalse.getAssumptions()[a]);
00115 Proof u;
00116 if(!thm.isNull()) u = thm.getProof();
00117
00118 if(u.isNull())
00119 pf = newPf("false_implies_anything", not_a, pfFalse.getProof());
00120 else
00121 pf = newPf("neg_intro", not_a,
00122
00123 newPf(u, a, pfFalse.getProof()));
00124 }
00125 return newTheorem(not_a, assump, pf);
00126 }
00127
00128
00129
00130 Theorem
00131 SearchEngineTheoremProducer::caseSplit(const Expr& a,
00132 const Theorem& a_proves_c,
00133 const Theorem& not_a_proves_c) {
00134 Expr c(a_proves_c.getExpr());
00135
00136 if(CHECK_PROOFS) {
00137 CHECK_SOUND(c == not_a_proves_c.getExpr(),
00138 "caseSplit: conclusions differ:\n positive case C = "
00139 + c.toString() + "\n negative case C = "
00140 + not_a_proves_c.getExpr().toString());
00141
00142
00143
00144
00145
00146
00147
00148
00149 }
00150
00151 Assumptions a1;
00152 Assumptions a2;
00153
00154
00155
00156
00157 if(withAssumptions()) {
00158 a1 = a_proves_c.getAssumptions() - a;
00159 a2 = not_a_proves_c.getAssumptions() - !a;
00160
00161 if (a1 == a_proves_c.getAssumptions()) return a_proves_c;
00162 if (a2 == not_a_proves_c.getAssumptions()) return not_a_proves_c;
00163 }
00164
00165 Assumptions assump;
00166 Proof pf;
00167 if(withAssumptions()) {
00168 assump = a1;
00169 a1.add(a2);
00170 }
00171 if(withProof()) {
00172
00173 vector<Proof> pfs;
00174 pfs.push_back(newPf(a_proves_c.getAssumptions()[a].getProof(),
00175 a, a_proves_c.getProof()));
00176 pfs.push_back(newPf(not_a_proves_c.getAssumptions()[!a].getProof(),
00177 !a, not_a_proves_c.getProof()));
00178 pf = newPf("case_split", a, c, pfs);
00179 }
00180 return newTheorem(c, assump, pf);
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 void SearchEngineTheoremProducer::verifyConflict(const Theorem& thm,
00193 TheoremMap& m) {
00194 const Assumptions::iterator iend = thm.getAssumptions().end();
00195 for (Assumptions::iterator i = thm.getAssumptions().begin();
00196 i != iend; ++i) {
00197 CHECK_SOUND(!i->isNull(),
00198 "SearchEngineTheoremProducer::conflictClause: "
00199 "Found null theorem");
00200 if (!i->isFlagged()) {
00201 i->setFlag();
00202 if (m.count(*i) == 0) {
00203 CHECK_SOUND(!i->isAssump(),
00204 "SearchEngineTheoremProducer::conflictClause: "
00205 "literal and gamma sets do not form a complete "
00206 "cut of Theorem assumptions. Stray theorem: \n"
00207 +i->toString());
00208 verifyConflict(*i, m);
00209 }
00210 else {
00211 m[*i] = true;
00212 }
00213 }
00214 }
00215 }
00216
00217
00218 Theorem
00219 SearchEngineTheoremProducer::
00220 conflictClause(const Theorem& thm, const vector<Theorem>& lits,
00221 const vector<Theorem>& gamma) {
00222 TRACE("search proofs", "conflictClause(", thm.getExpr(), ") {");
00223 IF_DEBUG(if(debugger.trace("search proofs")) {
00224 ostream& os = debugger.getOS();
00225 os << "lits = [";
00226 for(vector<Theorem>::const_iterator i=lits.begin(), iend=lits.end();
00227 i!=iend; ++i)
00228 os << i->getExpr() << ",\n";
00229 os << "]\n\ngamma = [";
00230 for(vector<Theorem>::const_iterator i=gamma.begin(), iend=gamma.end();
00231 i!=iend; ++i)
00232 os << i->getExpr() << ",\n";
00233 os << "]" << endl;
00234 });
00235 bool checkProofs(CHECK_PROOFS);
00236
00237 if(checkProofs) {
00238 CHECK_SOUND(withAssumptions(),
00239 "conflictClause: called while running without assumptions");
00240 }
00241
00242
00243
00244 vector<Expr> literals;
00245 vector<Proof> u;
00246 literals.reserve(lits.size() + 1);
00247 u.reserve(lits.size());
00248 const vector<Theorem>::const_iterator iend = lits.end();
00249 for(vector<Theorem>::const_iterator i=lits.begin(); i!=iend; ++i) {
00250 Expr neg(i->getExpr().negate());
00251
00252 literals.push_back(neg);
00253 if(withProof()) u.push_back(i->getProof());
00254 }
00255
00256 if(checkProofs) {
00257 TheoremMap m;
00258 TRACE_MSG("search proofs", "adding gamma to m: {");
00259 for(vector<Theorem>::const_iterator i = gamma.begin();
00260 i != gamma.end(); ++i) {
00261 TRACE("search proofs", "m[", *i, "]");
00262 m[*i] = false;
00263 }
00264 TRACE_MSG("search proofs", "}");
00265
00266 for(vector<Theorem>::const_iterator i = lits.begin(); i!=iend; ++i) {
00267 TRACE("search proofs", "check lit: ", *i, "");
00268 CHECK_SOUND(m.count(*i) == 0,
00269 "SearchEngineTheoremProducer::conflictClause: "
00270 "literal and gamma sets are not disjoint: lit = "
00271 +i->toString());
00272 m[*i] = false;
00273 }
00274 thm.clearAllFlags();
00275 verifyConflict(thm, m);
00276 TheoremMap::iterator t = m.begin(), tend = m.end();
00277 for (; t != tend; ++t) {
00278 CHECK_SOUND(t->second == true,
00279 "SearchEngineTheoremProducer::conflictClause: "
00280 "literal or gamma set contains extra element : "
00281 + t->first.toString());
00282 }
00283 }
00284
00285 Assumptions a(gamma);
00286
00287 if(!thm.getExpr().isFalse())
00288 literals.push_back(thm.getExpr());
00289
00290 Proof pf;
00291 if(withProof()) {
00292 if(lits.size()>0) {
00293 vector<Expr> assump;
00294
00295
00296
00297 ExprHashMap<Expr> subst;
00298 DebugAssert(u.size() == lits.size(), "");
00299 for(size_t i=0, iend=lits.size(); i<iend; ++i) {
00300 const Expr& e(lits[i].getExpr());
00301 assump.push_back(e);
00302 Proof& v = u[i];
00303 if(!v.getExpr().isVar()) {
00304 Proof label = newLabel(e);
00305 subst[v.getExpr()] = label.getExpr();
00306 v = label;
00307 }
00308 }
00309 Proof body(thm.getProof());
00310 if(!subst.empty())
00311 body = Proof(body.getExpr().substExpr(subst));
00312 pf = newPf("conflict_clause", newPf(u, assump, body));
00313 }
00314 else
00315 pf = newPf("false_to_empty_or", thm.getProof());
00316 }
00317 Theorem res(newTheorem(Expr(OR, literals, d_em), a, pf));
00318 TRACE("search proofs", "conflictClause => ", res.getExpr(), " }");
00319 return res;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 Theorem
00373 SearchEngineTheoremProducer::
00374 cutRule(const vector<Theorem>& thmsA,
00375 const Theorem& as_prove_b) {
00376 if(CHECK_PROOFS)
00377 CHECK_SOUND(withAssumptions(),
00378 "cutRule called without assumptions activated");
00379
00380
00381
00382
00383
00384 Proof pf;
00385 vector<Expr> exprs;
00386 exprs.reserve(thmsA.size() + 1);
00387 const vector<Theorem>::const_iterator iend = thmsA.end();
00388 for(vector<Theorem>::const_iterator i=thmsA.begin(); i!=iend; ++i) {
00389 exprs.push_back(i->getExpr());
00390 }
00391
00392 Assumptions a(thmsA);
00393 a.add(as_prove_b.getAssumptions() - exprs);
00394
00395 if(withProof()) {
00396 vector<Proof> pfs;
00397 pfs.reserve(thmsA.size() + 1);
00398 for(vector<Theorem>::const_iterator i = thmsA.begin(); i != iend; ++i) {
00399 pfs.push_back(i->getProof());
00400 }
00401 exprs.push_back(as_prove_b.getExpr());
00402 pfs.push_back(as_prove_b.getProof());
00403 pf = newPf("cut_rule",exprs,pfs);
00404 }
00405 return newTheorem(as_prove_b.getExpr(), a, pf);
00406 }
00407
00408
00409 void
00410 SearchEngineTheoremProducer::checkSoundNoSkolems(const Expr& e,
00411 ExprMap<bool>& visited,
00412 const ExprMap<bool>& skolems)
00413 {
00414 if(visited.count(e)>0)
00415 return;
00416 else
00417 visited[e] = true;
00418 CHECK_SOUND(skolems.count(e) == 0,
00419 "skolem constant found in axioms of false theorem: "
00420 + e.toString());
00421 for(Expr::iterator it = e.begin(), end = e.end(); it!= end; ++it)
00422 checkSoundNoSkolems(*it, visited, skolems);
00423 if(e.getKind() == FORALL || e.getKind() == EXISTS)
00424 checkSoundNoSkolems(e.getBody(), visited, skolems);
00425 }
00426
00427 void
00428 SearchEngineTheoremProducer::checkSoundNoSkolems(const Theorem& t,
00429 ExprMap<bool>& visited,
00430 const ExprMap<bool>& skolems)
00431 {
00432 if(t.isFlagged())
00433 return;
00434 t.setFlag();
00435 if(t.isAssump())
00436 checkSoundNoSkolems(t.getExpr(), visited, skolems);
00437 else
00438 {
00439 Assumptions a = t.getAssumptions();
00440 Assumptions::iterator it = a.begin(), end = a.end();
00441 for(; it!=end; ++it)
00442 checkSoundNoSkolems(*it, visited, skolems);
00443 }
00444 }
00445
00446
00447
00448
00449
00450
00451
00452 Theorem
00453 SearchEngineTheoremProducer::eliminateSkolemAxioms(const Theorem& tFalse,
00454 const std::vector<Theorem>& delta)
00455 {
00456 TRACE("skolem", "=>eliminateSkolemAxioms ", delta.size(), "{");
00457 if(delta.empty())
00458 {
00459 TRACE("skolem", "eliminateSkolemAxioms","" , "}");
00460 return tFalse;
00461 }
00462 const Expr& falseExpr = tFalse.getExpr();
00463 if(CHECK_PROOFS) {
00464 CHECK_SOUND(falseExpr.isFalse(),
00465 "eliminateSkolemAxiom called on non-false theorem");
00466 ExprMap<bool> visited;
00467 ExprMap<bool> skolems;
00468 vector<Theorem>::const_iterator it = delta.begin(), end = delta.end();
00469 for(; it!=end; ++it) {
00470 CHECK_SOUND(it->isRewrite(),
00471 "eliminateSkolemAxioms(): Skolem axiom is not "
00472 "an IFF: "+it->toString());
00473 const Expr& ex = it->getLHS();
00474 CHECK_SOUND(ex.isExists(),
00475 "Did not receive skolem axioms in Delta"
00476 " of eliminateSkolemAxioms" + it->toString());
00477
00478 for(unsigned int j=0; j<ex.getVars().size(); j++) {
00479 Expr sk_var(ex.skolemExpr(j));
00480 if(sk_var.getType().isBool()) {
00481 sk_var = d_em->newLeafExpr(sk_var.mkOp());
00482 }
00483 skolems[sk_var] = true;
00484 TRACE("skolem", ">> Eliminating variable: ", sk_var, "<<");
00485 }
00486 }
00487 tFalse.clearAllFlags();
00488 checkSoundNoSkolems(tFalse, visited, skolems);
00489 }
00490 Assumptions a;
00491 if(withAssumptions())
00492 a = tFalse.getAssumptionsCopy();
00493 Proof pf;
00494 if(!withProof()) return tFalse;
00495 else
00496 {
00497 Proof origFalse = tFalse.getProof();
00498 std::vector<Proof>skolemizeLabels;
00499 std::vector<Expr> exprs;
00500 for(unsigned int i=0; i<delta.size(); i++)
00501 {
00502 exprs.push_back(delta[i].getExpr());
00503 skolemizeLabels.push_back(delta[i].getProof());
00504 }
00505 pf = newPf(skolemizeLabels, exprs, origFalse);
00506 }
00507 TRACE("skolem", "eliminateSkolemAxioms","" , "}");
00508 return newTheorem(tFalse.getExpr(), a, pf);
00509 }
00510
00511
00512 Theorem
00513 SearchEngineTheoremProducer::unitProp(const std::vector<Theorem>& thms,
00514 const Theorem& clause,
00515 unsigned i) {
00516 Expr e(clause.getExpr());
00517 if(CHECK_PROOFS) {
00518
00519 CHECK_SOUND(e.isOr() && e.arity() > (int)i,
00520 "SearchEngineTheoremProducer::unitProp: bad theorem or i="
00521 +int2string(i)+" > arity="+int2string(e.arity())
00522 +" in clause = " + clause.toString());
00523
00524 CHECK_SOUND(((int)thms.size()) == e.arity() - 1,
00525 "SearchEngineTheoremProducer::unitProp: "
00526 "wrong number of theorems"
00527 "\n thms.size = " + int2string(thms.size())
00528 +"\n clause.arity = " + int2string(e.arity()));
00529
00530 for(unsigned j=0,k=0; j<thms.size(); j++) {
00531 if(j!=i) {
00532 Expr ej(e[j]), ek(thms[k].getExpr());
00533 CHECK_SOUND((ej.isNot() && ej[0] == ek) || (ek.isNot() && ej == ek[0]),
00534 "SearchEngineTheoremProducer::unitProp: "
00535 "wrong theorem["+int2string(k)+"]"
00536 "\n thm = " + thms[k].toString() +
00537 "\n literal = " + e[j].toString() +
00538 "\n clause = " + clause.toString());
00539 k++;
00540 }
00541 }
00542 }
00543
00544 Assumptions a;
00545 Proof pf;
00546 if(withAssumptions()) {
00547 a = Assumptions(thms);
00548 a.add(clause);
00549 }
00550
00551 if(withProof()) {
00552 vector<Proof> pfs;
00553 vector<Expr> exprs;
00554 exprs.reserve(thms.size() + 1);
00555 pfs.reserve(thms.size()+1);
00556 const vector<Theorem>::const_iterator iend = thms.end();
00557 for(vector<Theorem>::const_iterator i=thms.begin(); i!=iend; ++i) {
00558 exprs.push_back(i->getExpr());
00559 pfs.push_back(i->getProof());
00560 }
00561 exprs.push_back(clause.getExpr());
00562 pfs.push_back(clause.getProof());
00563 pf = newPf("unit_prop", exprs, pfs);
00564 }
00565 return newTheorem(e[i], a, pf);
00566 }
00567
00568 Theorem
00569 SearchEngineTheoremProducer::propAndrAF(const Theorem& andr_th,
00570 bool left,
00571 const Theorem& b_th) {
00572 const Expr& andr_e(andr_th.getExpr());
00573 if(CHECK_PROOFS) {
00574 CHECK_SOUND(andr_e.getKind() == AND_R &&
00575 ((left && b_th.refutes(andr_e[1])) ||
00576 (!left && b_th.refutes(andr_e[2]))),
00577 "SearchEngineTheoremProducer::propAndrAF");
00578 }
00579
00580 Assumptions a;
00581 Proof pf;
00582 if(withAssumptions()) {
00583 a.add(andr_th);
00584 a.add(b_th);
00585 }
00586
00587 if(withProof()) {
00588 vector<Proof> pfs;
00589 vector<Expr> exprs;
00590 exprs.push_back(andr_th.getExpr());
00591 exprs.push_back(b_th.getExpr());
00592 pfs.push_back(andr_th.getProof());
00593 pfs.push_back(b_th.getProof());
00594
00595 pf = newPf("prop_andr_af", exprs, pfs);
00596 }
00597
00598 return newTheorem(andr_e[0].negate(), a, pf);
00599 }
00600
00601 Theorem
00602 SearchEngineTheoremProducer::propAndrAT(const Theorem& andr_th,
00603 const Theorem& l_th,
00604 const Theorem& r_th) {
00605 const Expr& andr_e(andr_th.getExpr());
00606 if(CHECK_PROOFS) {
00607 CHECK_SOUND(andr_e.getKind() == AND_R &&
00608 l_th.proves(andr_e[1]) && r_th.proves(andr_e[2]),
00609 "SearchEngineTheoremProducer::propAndrAT");
00610 }
00611
00612 Assumptions a;
00613 Proof pf;
00614 if(withAssumptions()) {
00615 a.add(andr_th);
00616 a.add(l_th);
00617 a.add(r_th);
00618 }
00619
00620 if(withProof()) {
00621 vector<Proof> pfs;
00622 vector<Expr> exprs;
00623 exprs.push_back(andr_th.getExpr());
00624 exprs.push_back(l_th.getExpr());
00625 exprs.push_back(r_th.getExpr());
00626 pfs.push_back(andr_th.getProof());
00627 pfs.push_back(l_th.getProof());
00628 pfs.push_back(r_th.getProof());
00629 pf = newPf("prop_andr_at", exprs, pfs);
00630 }
00631
00632 return newTheorem(andr_e[0], a, pf);
00633 }
00634
00635 void
00636 SearchEngineTheoremProducer::propAndrLRT(const Theorem& andr_th,
00637 const Theorem& a_th,
00638 Theorem* l_th,
00639 Theorem* r_th) {
00640 const Expr& andr_e(andr_th.getExpr());
00641 if(CHECK_PROOFS) {
00642 CHECK_SOUND(andr_e.getKind() == AND_R && a_th.proves(andr_e[0]),
00643 "SearchEngineTheoremProducer::propAndrLRT");
00644 }
00645
00646 Assumptions a;
00647 Proof pf;
00648 if(withAssumptions()) {
00649 a.add(andr_th);
00650 a.add(a_th);
00651 }
00652
00653 if(withProof()) {
00654 vector<Proof> pfs;
00655 vector<Expr> exprs;
00656 exprs.push_back(andr_th.getExpr());
00657 exprs.push_back(a_th.getExpr());
00658 pfs.push_back(andr_th.getProof());
00659 pfs.push_back(a_th.getProof());
00660 pf = newPf("prop_andr_lrt", exprs, pfs);
00661 }
00662
00663 if (l_th) *l_th = newTheorem(andr_e[1], a, pf);
00664 if (r_th) *r_th = newTheorem(andr_e[2], a, pf);
00665 }
00666
00667 Theorem
00668 SearchEngineTheoremProducer::propAndrLF(const Theorem& andr_th,
00669 const Theorem& a_th,
00670 const Theorem& r_th) {
00671 const Expr& andr_e(andr_th.getExpr());
00672 if(CHECK_PROOFS) {
00673 CHECK_SOUND(andr_e.getKind() == AND_R &&
00674 a_th.refutes(andr_e[0]) && r_th.proves(andr_e[2]),
00675 "SearchEngineTheoremProducer::propAndrLF");
00676 }
00677
00678 Assumptions a;
00679 Proof pf;
00680 if(withAssumptions()) {
00681 a.add(andr_th);
00682 a.add(a_th);
00683 a.add(r_th);
00684 }
00685
00686 if(withProof()) {
00687 vector<Proof> pfs;
00688 vector<Expr> exprs;
00689 exprs.push_back(andr_th.getExpr());
00690 exprs.push_back(a_th.getExpr());
00691 exprs.push_back(r_th.getExpr());
00692 pfs.push_back(andr_th.getProof());
00693 pfs.push_back(a_th.getProof());
00694 pfs.push_back(r_th.getProof());
00695 pf = newPf("prop_andr_lf", exprs, pfs);
00696 }
00697
00698 return newTheorem(andr_e[1].negate(), a, pf);
00699 }
00700
00701 Theorem
00702 SearchEngineTheoremProducer::propAndrRF(const Theorem& andr_th,
00703 const Theorem& a_th,
00704 const Theorem& l_th) {
00705 const Expr& andr_e(andr_th.getExpr());
00706 if(CHECK_PROOFS) {
00707 CHECK_SOUND(andr_e.getKind() == AND_R &&
00708 a_th.refutes(andr_e[0]) && l_th.proves(andr_e[1]),
00709 "SearchEngineTheoremProducer::propAndrRF");
00710 }
00711
00712 Assumptions a;
00713 Proof pf;
00714 if(withAssumptions()) {
00715 a.add(andr_th);
00716 a.add(a_th);
00717 a.add(l_th);
00718 }
00719
00720 if(withProof()) {
00721 vector<Proof> pfs;
00722 vector<Expr> exprs;
00723 exprs.push_back(andr_th.getExpr());
00724 exprs.push_back(a_th.getExpr());
00725 exprs.push_back(l_th.getExpr());
00726 pfs.push_back(andr_th.getProof());
00727 pfs.push_back(a_th.getProof());
00728 pfs.push_back(l_th.getProof());
00729 pf = newPf("prop_andr_rf", exprs, pfs);
00730 }
00731
00732 return newTheorem(andr_e[2].negate(), a, pf);
00733 }
00734
00735 Theorem
00736 SearchEngineTheoremProducer::confAndrAT(const Theorem& andr_th,
00737 const Theorem& a_th,
00738 bool left,
00739 const Theorem& b_th) {
00740 const Expr& andr_e(andr_th.getExpr());
00741 if(CHECK_PROOFS) {
00742 CHECK_SOUND(andr_e.getKind() == AND_R && a_th.proves(andr_e[0]) &&
00743 ((left && b_th.refutes(andr_e[1])) ||
00744 (!left && b_th.refutes(andr_e[2]))),
00745 "SearchEngineTheoremProducer::confAndrAT");
00746 }
00747
00748 Assumptions a;
00749 Proof pf;
00750 if(withAssumptions()) {
00751 a.add(andr_th);
00752 a.add(a_th);
00753 a.add(b_th);
00754 }
00755
00756 if(withProof()) {
00757 vector<Proof> pfs;
00758 vector<Expr> exprs;
00759 exprs.push_back(andr_th.getExpr());
00760 exprs.push_back(a_th.getExpr());
00761 exprs.push_back(b_th.getExpr());
00762 pfs.push_back(andr_th.getProof());
00763 pfs.push_back(a_th.getProof());
00764 pfs.push_back(b_th.getProof());
00765
00766 pf = newPf("conf_andr_at", exprs, pfs);
00767 }
00768
00769 return newTheorem(d_em->falseExpr(), a, pf);
00770 }
00771
00772 Theorem
00773 SearchEngineTheoremProducer::confAndrAF(const Theorem& andr_th,
00774 const Theorem& a_th,
00775 const Theorem& l_th,
00776 const Theorem& r_th) {
00777 const Expr& andr_e(andr_th.getExpr());
00778 if(CHECK_PROOFS) {
00779 CHECK_SOUND(andr_e.getKind() == AND_R && a_th.refutes(andr_e[0]) &&
00780 l_th.proves(andr_e[1]) && r_th.proves(andr_e[2]),
00781 "SearchEngineTheoremProducer::confAndrAF");
00782 }
00783
00784 Assumptions a;
00785 Proof pf;
00786 if(withAssumptions()) {
00787 a.add(andr_th);
00788 a.add(a_th);
00789 a.add(l_th);
00790 a.add(r_th);
00791 }
00792
00793 if(withProof()) {
00794 vector<Proof> pfs;
00795 vector<Expr> exprs;
00796 exprs.push_back(andr_th.getExpr());
00797 exprs.push_back(a_th.getExpr());
00798 exprs.push_back(l_th.getExpr());
00799 exprs.push_back(r_th.getExpr());
00800 pfs.push_back(andr_th.getProof());
00801 pfs.push_back(a_th.getProof());
00802 pfs.push_back(l_th.getProof());
00803 pfs.push_back(r_th.getProof());
00804 pf = newPf("conf_andr_af", exprs, pfs);
00805 }
00806
00807 return newTheorem(d_em->falseExpr(), a, pf);
00808 }
00809
00810 Theorem
00811 SearchEngineTheoremProducer::propIffr(const Theorem& iffr_th,
00812 int p,
00813 const Theorem& a_th,
00814 const Theorem& b_th)
00815 {
00816 int a(-1), b(-1);
00817 if(CHECK_PROOFS)
00818 CHECK_SOUND(p == 0 || p == 1 || p == 2,
00819 "SearchEngineTheoremProducer::propIffr: p="
00820 +int2string(p));
00821 switch (p) {
00822 case 0: a = 1; b = 2; break;
00823 case 1: a = 0; b = 2; break;
00824 case 2: a = 0; b = 1; break;
00825 }
00826
00827 const Expr& iffr_e(iffr_th.getExpr());
00828
00829 bool v0 = a_th.proves(iffr_e[a]);
00830 bool v1 = b_th.proves(iffr_e[b]);
00831
00832 if (CHECK_PROOFS) {
00833 CHECK_SOUND(iffr_e.getKind() == IFF_R &&
00834 (v0 || a_th.refutes(iffr_e[a])) &&
00835 (v1 || b_th.refutes(iffr_e[b])),
00836 "SearchEngineTheoremProducer::propIffr");
00837 }
00838
00839 Assumptions aa;
00840 Proof pf;
00841 if (withAssumptions()) {
00842 aa.add(iffr_th);
00843 aa.add(a_th);
00844 aa.add(b_th);
00845 }
00846
00847 if (withProof()) {
00848 vector<Proof> pfs;
00849 vector<Expr> exprs;
00850 exprs.push_back(iffr_th.getExpr());
00851 exprs.push_back(a_th.getExpr());
00852 exprs.push_back(b_th.getExpr());
00853 pfs.push_back(iffr_th.getProof());
00854 pfs.push_back(a_th.getProof());
00855 pfs.push_back(b_th.getProof());
00856 pf = newPf("prop_iffr", exprs, pfs);
00857 }
00858
00859 return newTheorem(v0 == v1 ? iffr_e[p] : iffr_e[p].negate(), aa, pf);
00860 }
00861
00862 Theorem
00863 SearchEngineTheoremProducer::confIffr(const Theorem& iffr_th,
00864 const Theorem& i_th,
00865 const Theorem& l_th,
00866 const Theorem& r_th)
00867 {
00868 const Expr& iffr_e(iffr_th.getExpr());
00869
00870 bool v0 = i_th.proves(iffr_e[0]);
00871 bool v1 = l_th.proves(iffr_e[1]);
00872 bool v2 = r_th.proves(iffr_e[2]);
00873
00874 if (CHECK_PROOFS) {
00875 CHECK_SOUND(iffr_e.getKind() == IFF_R &&
00876 (v0 || i_th.refutes(iffr_e[0])) &&
00877 (v1 || l_th.refutes(iffr_e[1])) &&
00878 (v2 || r_th.refutes(iffr_e[2])) &&
00879 ((v0 && v1 != v2) || (!v0 && v1 == v2)),
00880 "SearchEngineTheoremProducer::confIffr");
00881 }
00882
00883 Assumptions a;
00884 Proof pf;
00885 if (withAssumptions()) {
00886 a.add(iffr_th);
00887 a.add(i_th);
00888 a.add(l_th);
00889 a.add(r_th);
00890 }
00891
00892 if (withProof()) {
00893 vector<Proof> pfs;
00894 vector<Expr> exprs;
00895 exprs.push_back(iffr_th.getExpr());
00896 exprs.push_back(i_th.getExpr());
00897 exprs.push_back(l_th.getExpr());
00898 exprs.push_back(r_th.getExpr());
00899 pfs.push_back(iffr_th.getProof());
00900 pfs.push_back(i_th.getProof());
00901 pfs.push_back(l_th.getProof());
00902 pfs.push_back(r_th.getProof());
00903 pf = newPf("conf_iffr", exprs, pfs);
00904 }
00905
00906 return newTheorem(d_em->falseExpr(), a, pf);
00907 }
00908
00909 Theorem
00910 SearchEngineTheoremProducer::propIterIte(const Theorem& iter_th,
00911 bool left,
00912 const Theorem& if_th,
00913 const Theorem& then_th)
00914 {
00915 const Expr& iter_e(iter_th.getExpr());
00916
00917 bool v0 = if_th.proves(iter_e[1]);
00918 bool v1 = then_th.proves(iter_e[left ? 2 : 3]);
00919
00920 if (CHECK_PROOFS) {
00921 CHECK_SOUND(iter_e.getKind() == ITE_R &&
00922 (v0 || if_th.refutes(iter_e[1])) &&
00923 (v1 || then_th.refutes(iter_e[left ? 2 : 3])) &&
00924 v0 == left,
00925 "SearchEngineTheoremProducer::propIterIte");
00926 }
00927
00928 Assumptions a;
00929 Proof pf;
00930 if (withAssumptions()) {
00931 a.add(iter_th);
00932 a.add(if_th);
00933 a.add(then_th);
00934 }
00935
00936 if (withProof()) {
00937 vector<Proof> pfs;
00938 vector<Expr> exprs;
00939 exprs.push_back(iter_th.getExpr());
00940 exprs.push_back(if_th.getExpr());
00941 exprs.push_back(then_th.getExpr());
00942 pfs.push_back(iter_th.getProof());
00943 pfs.push_back(if_th.getProof());
00944 pfs.push_back(then_th.getProof());
00945 pf = newPf("prop_iter_ite", exprs, pfs);
00946 }
00947
00948 return newTheorem(v1 ? iter_e[0] : iter_e[0].negate(), a, pf);
00949 }
00950
00951 void
00952 SearchEngineTheoremProducer::propIterIfThen(const Theorem& iter_th,
00953 bool left,
00954 const Theorem& ite_th,
00955 const Theorem& then_th,
00956 Theorem* if_th,
00957 Theorem* else_th)
00958 {
00959 const Expr& iter_e(iter_th.getExpr());
00960
00961 bool v0 = ite_th.proves(iter_e[0]);
00962 bool v1 = then_th.proves(iter_e[left ? 2 : 3]);
00963
00964 if (CHECK_PROOFS) {
00965 CHECK_SOUND(iter_e.getKind() == ITE_R &&
00966 (v0 || ite_th.refutes(iter_e[0])) &&
00967 (v1 || then_th.refutes(iter_e[left ? 2 : 3])) &&
00968 v0 != v1,
00969 "SearchEngineTheoremProducer::propIterIfThen");
00970 }
00971
00972 Assumptions a;
00973 Proof pf;
00974 if (withAssumptions()) {
00975 a.add(iter_th);
00976 a.add(ite_th);
00977 a.add(then_th);
00978 }
00979
00980 if (withProof()) {
00981 vector<Proof> pfs;
00982 vector<Expr> exprs;
00983 exprs.push_back(iter_th.getExpr());
00984 exprs.push_back(ite_th.getExpr());
00985 exprs.push_back(then_th.getExpr());
00986 pfs.push_back(iter_th.getProof());
00987 pfs.push_back(ite_th.getProof());
00988 pfs.push_back(then_th.getExpr());
00989 pf = newPf("prop_iter_if_then", exprs, pfs);
00990 }
00991
00992 if (if_th)
00993 *if_th = newTheorem(left ? iter_e[1].negate() : iter_e[1], a, pf);
00994 if (else_th)
00995 *else_th = newTheorem(v0 ? iter_e[left ? 3 : 2] : iter_e[left ? 3 : 2].negate(), a, pf);
00996 }
00997
00998 Theorem
00999 SearchEngineTheoremProducer::propIterThen(const Theorem& iter_th,
01000 const Theorem& ite_th,
01001 const Theorem& if_th)
01002 {
01003 const Expr& iter_e(iter_th.getExpr());
01004
01005 bool v0 = ite_th.proves(iter_e[0]);
01006 bool v1 = if_th.proves(iter_e[1]);
01007
01008 if (CHECK_PROOFS) {
01009 CHECK_SOUND(iter_e.getKind() == ITE_R &&
01010 (v0 || ite_th.refutes(iter_e[0])) &&
01011 (v1 || if_th.refutes(iter_e[1])),
01012 "SearchEngineTheoremProducer::propIterThen");
01013 }
01014
01015 Assumptions a;
01016 Proof pf;
01017 if (withAssumptions()) {
01018 a.add(iter_th);
01019 a.add(ite_th);
01020 a.add(if_th);
01021 }
01022
01023 if (withProof()) {
01024 vector<Proof> pfs;
01025 vector<Expr> exprs;
01026 exprs.push_back(iter_th.getExpr());
01027 exprs.push_back(ite_th.getExpr());
01028 exprs.push_back(if_th.getExpr());
01029 pfs.push_back(iter_th.getProof());
01030 pfs.push_back(ite_th.getProof());
01031 pfs.push_back(if_th.getExpr());
01032 pf = newPf("prop_iter_then", exprs, pfs);
01033 }
01034
01035 return newTheorem(v1 ?
01036 (v0 ? iter_e[2] : iter_e[2].negate()) :
01037 (v0 ? iter_e[3] : iter_e[3].negate()), a, pf);
01038 }
01039
01040 Theorem
01041 SearchEngineTheoremProducer::confIterThenElse(const Theorem& iter_th,
01042 const Theorem& ite_th,
01043 const Theorem& then_th,
01044 const Theorem& else_th)
01045 {
01046 const Expr& iter_e(iter_th.getExpr());
01047
01048 bool v0 = ite_th.proves(iter_e[0]);
01049 bool v1 = then_th.proves(iter_e[2]);
01050 bool v2 = else_th.proves(iter_e[3]);
01051
01052 if (CHECK_PROOFS) {
01053 CHECK_SOUND(iter_e.getKind() == ITE_R &&
01054 (v0 || ite_th.refutes(iter_e[0])) &&
01055 (v1 || then_th.refutes(iter_e[2])) &&
01056 (v2 || else_th.refutes(iter_e[3])) &&
01057 ((v0 && !v1 && !v2) || (!v0 && v1 && v2)),
01058 "SearchEngineTheoremProducer::confIterThenElse");
01059 }
01060
01061 Assumptions a;
01062 Proof pf;
01063 if (withAssumptions()) {
01064 a.add(iter_th);
01065 a.add(ite_th);
01066 a.add(then_th);
01067 a.add(else_th);
01068 }
01069
01070 if (withProof()) {
01071 vector<Proof> pfs;
01072 vector<Expr> exprs;
01073 exprs.push_back(iter_th.getExpr());
01074 exprs.push_back(ite_th.getExpr());
01075 exprs.push_back(then_th.getExpr());
01076 exprs.push_back(else_th.getExpr());
01077 pfs.push_back(iter_th.getProof());
01078 pfs.push_back(ite_th.getProof());
01079 pfs.push_back(then_th.getExpr());
01080 pfs.push_back(else_th.getExpr());
01081 pf = newPf("conf_iter_then_else", exprs, pfs);
01082 }
01083
01084 return newTheorem(d_em->falseExpr(), a, pf);
01085 }
01086
01087 Theorem
01088 SearchEngineTheoremProducer::confIterIfThen(const Theorem& iter_th,
01089 bool left,
01090 const Theorem& ite_th,
01091 const Theorem& if_th,
01092 const Theorem& then_th)
01093 {
01094 const Expr& iter_e(iter_th.getExpr());
01095
01096 bool v0 = ite_th.proves(iter_e[0]);
01097 bool v1 = if_th.proves(iter_e[1]);
01098 bool v2 = then_th.proves(iter_e[left ? 2 : 3]);
01099
01100 if (CHECK_PROOFS) {
01101 CHECK_SOUND(iter_e.getKind() == ITE_R &&
01102 (v0 || ite_th.refutes(iter_e[0])) &&
01103 (v1 || if_th.refutes(iter_e[1])) &&
01104 (v2 || then_th.refutes(iter_e[left ? 2 : 3])) &&
01105 v1 == left && v0 != v2,
01106 "SearchEngineTheoremProducer::confIterThenElse");
01107 }
01108
01109 Assumptions a;
01110 Proof pf;
01111 if (withAssumptions()) {
01112 a.add(iter_th);
01113 a.add(ite_th);
01114 a.add(if_th);
01115 a.add(then_th);
01116 }
01117
01118 if (withProof()) {
01119 vector<Proof> pfs;
01120 vector<Expr> exprs;
01121 exprs.push_back(iter_th.getExpr());
01122 exprs.push_back(ite_th.getExpr());
01123 exprs.push_back(if_th.getExpr());
01124 exprs.push_back(then_th.getExpr());
01125 pfs.push_back(iter_th.getProof());
01126 pfs.push_back(ite_th.getProof());
01127 pfs.push_back(if_th.getExpr());
01128 pfs.push_back(then_th.getExpr());
01129 pf = newPf("conf_iter_then_else", exprs, pfs);
01130 }
01131
01132 return newTheorem(d_em->falseExpr(), a, pf);
01133 }
01134
01135
01136
01137 Theorem
01138 SearchEngineTheoremProducer::conflictRule(const std::vector<Theorem>& thms,
01139 const Theorem& clause) {
01140 Expr e(clause.getExpr());
01141 if(CHECK_PROOFS) {
01142
01143 CHECK_SOUND(e.isOr(),
01144 "SearchEngineTheoremProducer::unitProp: "
01145 "bad theorem in clause = "+clause.toString());
01146
01147 CHECK_SOUND(((int)thms.size()) == e.arity(),
01148 "SearchEngineTheoremProducer::conflictRule: "
01149 "wrong number of theorems"
01150 "\n thms.size = " + int2string(thms.size())
01151 +"\n clause.arity = " + int2string(e.arity()));
01152
01153 for(unsigned j=0; j<thms.size(); j++) {
01154 Expr ej(e[j]), ek(thms[j].getExpr());
01155 CHECK_SOUND((ej.isNot() && ej[0] == ek) || (ek.isNot() && ej == ek[0]),
01156 "SearchEngineTheoremProducer::conflictRule: "
01157 "wrong theorem["+int2string(j)+"]"
01158 "\n thm = " + thms[j].toString() +
01159 "\n literal = " + e[j].toString() +
01160 "\n clause = " + clause.toString());
01161 }
01162 }
01163
01164 Assumptions a;
01165 Proof pf;
01166 if(withAssumptions()) {
01167 a = Assumptions(thms);
01168 a.add(clause);
01169 }
01170 if(withProof()) {
01171 vector<Proof> pfs;
01172 vector<Expr> exprs;
01173 exprs.reserve(thms.size() + 1);
01174 pfs.reserve(thms.size()+1);
01175 const vector<Theorem>::const_iterator iend = thms.end();
01176 for(vector<Theorem>::const_iterator i=thms.begin(); i!=iend; ++i) {
01177 exprs.push_back(i->getExpr());
01178 pfs.push_back(i->getProof());
01179 }
01180 exprs.push_back(clause.getExpr());
01181 pfs.push_back(clause.getProof());
01182 pf = newPf("conflict", exprs, pfs);
01183 }
01184 return newTheorem(d_em->falseExpr(), a, pf);
01185 }
01186
01187
01188
01189
01190
01191 Theorem
01192 SearchEngineTheoremProducer::andCNFRule(const Theorem& thm) {
01193 return opCNFRule(thm, AND, "and_cnf_rule");
01194 }
01195
01196 Theorem
01197 SearchEngineTheoremProducer::orCNFRule(const Theorem& thm) {
01198 return opCNFRule(thm, OR, "or_cnf_rule");
01199 }
01200
01201 Theorem
01202 SearchEngineTheoremProducer::impCNFRule(const Theorem& thm) {
01203 return opCNFRule(thm, IMPLIES, "implies_cnf_rule");
01204 }
01205
01206 Theorem
01207 SearchEngineTheoremProducer::iffCNFRule(const Theorem& thm) {
01208 return opCNFRule(thm, IFF, "iff_cnf_rule");
01209 }
01210
01211 Theorem
01212 SearchEngineTheoremProducer::iteCNFRule(const Theorem& thm) {
01213 return opCNFRule(thm, ITE, "ite_cnf_rule");
01214 }
01215
01216
01217 Theorem
01218 SearchEngineTheoremProducer::iteToClauses(const Theorem& ite) {
01219 const Expr& iteExpr = ite.getExpr();
01220
01221 if(CHECK_PROOFS) {
01222 CHECK_SOUND(iteExpr.isITE() && iteExpr.getType().isBool(),
01223 "SearchEngineTheoremProducer::iteToClauses("+iteExpr.toString()
01224 +")\n Argument must be a Boolean ITE");
01225 }
01226 const Expr& cond = iteExpr[0];
01227 const Expr& t1 = iteExpr[1];
01228 const Expr& t2 = iteExpr[2];
01229
01230 Assumptions a;
01231 Proof pf;
01232 if(withAssumptions()) a = ite.getAssumptionsCopy();
01233 if(withProof())
01234 pf = newPf("ite_to_clauses", iteExpr, ite.getProof());
01235 return newTheorem((cond.negate() || t1) && (cond || t2), a, pf);
01236 }
01237
01238
01239 Theorem
01240 SearchEngineTheoremProducer::iffToClauses(const Theorem& iff) {
01241 if(CHECK_PROOFS) {
01242 CHECK_SOUND(iff.isRewrite() && iff.getLHS().getType().isBool(),
01243 "SearchEngineTheoremProducer::iffToClauses("+iff.getExpr().toString()
01244 +")\n Argument must be a Boolean IFF");
01245 }
01246 const Expr& t1 = iff.getLHS();
01247 const Expr& t2 = iff.getRHS();
01248
01249 Assumptions a;
01250 Proof pf;
01251 if(withAssumptions()) a = iff.getAssumptionsCopy();
01252 if(withProof())
01253 pf = newPf("iff_to_clauses", iff.getExpr(), iff.getProof());
01254 return newTheorem((t1.negate() || t2) && (t1 || t2.negate()), a, pf);
01255 }
01256
01257
01258
01259
01260
01261 Theorem
01262 SearchEngineTheoremProducer::opCNFRule(const Theorem& thm,
01263 int kind,
01264 const string& ruleName) {
01265 TRACE("mycnf", "opCNFRule["+d_em->getKindName(kind)+"](",
01266 thm.getExpr(), ") {");
01267 ExprMap<Expr> localCache;
01268 if(CHECK_PROOFS) {
01269 Expr phiIffVar = thm.getExpr();
01270 CHECK_SOUND(phiIffVar.isIff(),
01271 "SearchEngineTheoremProducer::opCNFRule("
01272 +d_em->getKindName(kind)+"): "
01273 "input must be an IFF: thm = " + phiIffVar.toString());
01274 CHECK_SOUND(phiIffVar[0].getKind() == kind,
01275 "SearchEngineTheoremProducer::opCNFRule("
01276 +d_em->getKindName(kind)+"): "
01277 "input phi has wrong kind: thm = " + phiIffVar.toString());
01278 CHECK_SOUND(phiIffVar[0] != phiIffVar[1],
01279 "SearchEngineTheoremProducer::opCNFRule("
01280 +d_em->getKindName(kind)+"): "
01281 "wrong input thm = " + phiIffVar.toString());
01282 for(Expr::iterator it=phiIffVar[0].begin(), itend=phiIffVar[0].end();
01283 it!=itend;++it){
01284 CHECK_SOUND(phiIffVar[1] != *it,
01285 "SearchEngineTheoremProducer::opCNFRule("
01286 +d_em->getKindName(kind)+"): "
01287 "wrong input thm = " + phiIffVar.toString());
01288 }
01289 }
01290 const Expr& phi = thm.getExpr()[0];
01291 const Expr& phiVar = thm.getExpr()[1];
01292
01293 std::vector<Expr> boundVars;
01294 std::vector<Expr> boundVarsAndLiterals;
01295 std::vector<Expr> equivs;
01296 for(Expr::iterator i=phi.begin(), iend=phi.end(); i != iend; i++) {
01297
01298 Expr tmp(*i);
01299 while(tmp.isNot())
01300 tmp = tmp[0];
01301
01302 if(tmp.isPropAtom())
01303 boundVarsAndLiterals.push_back(*i);
01304 else
01305 boundVarsAndLiterals.push_back(findInLocalCache(*i, localCache,
01306 boundVars));
01307 }
01308
01309 for(ExprMap<Expr>::iterator it=localCache.begin(), itend=localCache.end();
01310 it != itend; it++) {
01311 DebugAssert((*it).second.isIff(),
01312 "SearchEngineTheoremProducer::opCNFRule: " +
01313 (*it).second.toString());
01314 DebugAssert(!(*it).second[0].isPropLiteral() &&
01315 (*it).second[1].isAbsLiteral(),
01316 "SearchEngineTheoremProducer::opCNFRule: " +
01317 (*it).second.toString());
01318 equivs.push_back((*it).second);
01319 }
01320
01321 DebugAssert(boundVarsAndLiterals.size() == (unsigned)phi.arity(),
01322 "SearchEngineTheoremProducer::opCNFRule: "
01323 "wrong size of boundvars: phi = " + phi.toString());
01324
01325 DebugAssert(boundVars.size() == equivs.size(),
01326 "SearchEngineTheoremProducer::opCNFRule: "
01327 "wrong size of boundvars: phi = " + phi.toString());
01328
01329 Expr cnfInput = phi.arity() > 0 ? Expr(phi.getOp(), boundVarsAndLiterals) : phi;
01330 Expr result = convertToCNF(phiVar, cnfInput);
01331 if(boundVars.size() > 0)
01332 result =
01333 d_em->newClosureExpr(EXISTS, boundVars, result.andExpr(andExpr(equivs)));
01334
01335 Assumptions a;
01336 Proof pf;
01337 if(withAssumptions()) a = thm.getAssumptionsCopy();
01338 if(withProof())
01339 pf = newPf(ruleName, thm.getExpr(), thm.getProof());
01340 Theorem res(newTheorem(result, a, pf));
01341 TRACE("mycnf", "opCNFRule["+d_em->getKindName(kind)+"] => ", res.getExpr(),
01342 " }");
01343 return res;
01344 }
01345
01346
01347 Expr SearchEngineTheoremProducer::convertToCNF(const Expr& v, const Expr & phi) {
01348
01349
01350 Expr::iterator i = phi.begin(), iend = phi.end();
01351 std::vector<Expr> clauses;
01352 std::vector<Expr> lastClause;
01353 switch(phi.getKind()) {
01354 case AND: {
01355 const Expr& negV = v.negate();
01356 lastClause.push_back(v);
01357 for(;i!=iend; ++i) {
01358 clauses.push_back(negV.orExpr(*i));
01359 lastClause.push_back(i->negate());
01360 }
01361 clauses.push_back(orExpr(lastClause));
01362 }
01363 break;
01364 case OR:{
01365 lastClause.push_back(v.negate());
01366 for(;i!=iend; ++i) {
01367 clauses.push_back(v.orExpr(i->negate()));
01368 lastClause.push_back(*i);
01369 }
01370 clauses.push_back(orExpr(lastClause));
01371 }
01372 break;
01373 case IFF: {
01374 const Expr& v1 = phi[0];
01375 const Expr& v2 = phi[1];
01376 Expr negV = v.negate();
01377 Expr negv1 = v1.negate();
01378 Expr negv2 = v2.negate();
01379 clauses.push_back(Expr(OR, negV, negv1, v2));
01380 clauses.push_back(Expr(OR, negV, v1, negv2));
01381 clauses.push_back(Expr(OR, v, v1, v2));
01382 clauses.push_back(Expr(OR, v, negv1, negv2));
01383 } break;
01384 case IMPLIES:{
01385 const Expr& v1 = phi[0];
01386 const Expr& v2 = phi[1];
01387 Expr negV = v.negate();
01388 Expr negv1 = v1.negate();
01389 Expr negv2 = v2.negate();
01390 clauses.push_back(Expr(OR, negV, negv1, v2));
01391 clauses.push_back(v.orExpr(v1));
01392 clauses.push_back(v.orExpr(negv2));
01393 }
01394 break;
01395 case ITE: {
01396 const Expr& v1 = phi[0];
01397 const Expr& v2 = phi[1];
01398 const Expr& v3 = phi[2];
01399 const Expr& negV = v.negate();
01400 const Expr& negv1 = v1.negate();
01401 const Expr& negv2 = v2.negate();
01402 const Expr& negv3 = v3.negate();
01403 clauses.push_back(Expr(OR, negV, negv1, v2));
01404 clauses.push_back(Expr(OR, negV, v1, v3));
01405 clauses.push_back(Expr(OR, v, negv1, negv2));
01406 clauses.push_back(Expr(OR, v, v1, negv3));
01407 }
01408 break;
01409 default:
01410 DebugAssert(false, "SearchEngineTheoremProducer::convertToCNF: "
01411 "bad operator in phi = "+phi.toString());
01412 break;
01413 }
01414 return andExpr(clauses);
01415 }
01416
01417
01418
01419
01420
01421 Expr SearchEngineTheoremProducer::findInLocalCache(const Expr& i,
01422 ExprMap<Expr>& localCache,
01423 vector<Expr>& boundVars) {
01424 TRACE("mycnf", "findInLocalCache(", i.toString(), ") { ");
01425 Expr boundVar;
01426 unsigned int negationDepth = 0;
01427 ExprMap<Expr>::iterator it;
01428
01429 Expr phi = i;
01430 while(phi.isNot()) {
01431 phi = phi[0];
01432 negationDepth++;
01433 }
01434
01435 it = localCache.find(phi);
01436 Expr v;
01437 if(it != localCache.end()) {
01438 v = ((*it).second)[1];
01439 IF_DEBUG(debugger.counter("CNF Local Cache Hits")++);
01440 }
01441 else {
01442 v = d_em->newBoundVarExpr(i.getType());
01443 boundVars.push_back(v);
01444 localCache[phi] = phi.iffExpr(v);
01445 }
01446 if(negationDepth % 2 != 0)
01447 v = !v;
01448 TRACE("mycnf", "findInLocalCache => ", v, " }");
01449 return v;
01450 }