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