core_theorem_producer.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file core_theorem_producer.cpp
00004  * 
00005  * Author: Sergey Berezin
00006  * 
00007  * Created: Feb 05 03:40:36 GMT 2003
00008  *
00009  * <hr>
00010  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00011  * Junior University and by New York University. 
00012  *
00013  * License to use, copy, modify, sell and/or distribute this software
00014  * and its documentation for any purpose is hereby granted without
00015  * royalty, subject to the terms and conditions defined in the \ref
00016  * LICENSE file provided with this distribution.  In particular:
00017  *
00018  * - The above copyright notice and this permission notice must appear
00019  * in all copies of the software and related documentation.
00020  *
00021  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00022  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00023  * 
00024  * <hr>
00025  * 
00026  */
00027 /*****************************************************************************/
00028 // CLASS: CoreTheoremProducer
00029 //
00030 // AUTHOR: Sergey Berezin, 12/09/2002
00031 //         Vijay Ganesh, september 15th, 2004 (CNF Converter rules)
00032 //
00033 // Description: Implementation of the proof rules for ground
00034 // equational logic (reflexivity, symmetry, transitivity, and
00035 // substitutivity).
00036 //
00037 ///////////////////////////////////////////////////////////////////////////////
00038 
00039 
00040 // This code is trusted
00041 #define _CVCL_TRUSTED_
00042 
00043 
00044 #include "core_theorem_producer.h"
00045 #include "theory_core.h"
00046 
00047 
00048 using namespace CVCL;
00049 using namespace std;
00050 
00051 
00052 // The trusted method of TheoryCore which creates this theorem producer
00053 CoreProofRules* TheoryCore::createProofRules(TheoremManager* tm) {
00054   return new CoreTheoremProducer(tm, this);
00055 }
00056 
00057 
00058 ////////////////////////////////////////////////////////////////////////
00059 // TCC rules (3-valued logic)
00060 ////////////////////////////////////////////////////////////////////////
00061 
00062 //  G1 |- phi   G2 |- D_phi
00063 // -------------------------
00064 //       G1,G2 |-_3 phi
00065 Theorem3
00066 CoreTheoremProducer::queryTCC(const Theorem& phi, const Theorem& D_phi) {
00067   Assumptions a;
00068   Proof pf;
00069   if(CHECK_PROOFS)
00070     CHECK_SOUND(D_phi.getExpr() == d_core->getTCC(phi.getExpr()),
00071                 "CoreTheoremProducer::queryTCC: "
00072                 "bad TCC for a formula:\n\n  "
00073                 +phi.getExpr().toString()
00074                 +"\n\n  TCC must be the following:\n\n  "
00075                 +d_core->getTCC(phi.getExpr()).toString()
00076                 +"\n\nBut given this as a TCC:\n\n  "
00077                 +D_phi.getExpr().toString());
00078   if(withAssumptions())
00079     a = merge(phi.getAssumptions(), D_phi);
00080   if(withProof()) {
00081     vector<Expr> args;
00082     vector<Proof> pfs;
00083     args.push_back(phi.getExpr());
00084     args.push_back(D_phi.getExpr());
00085     pfs.push_back(phi.getProof());
00086     pfs.push_back(D_phi.getProof());
00087     pf = newPf("queryTCC", args, pfs);
00088     }
00089   return newTheorem3(phi.getExpr(), a, pf);
00090 }
00091 
00092 
00093 //  G0,a1,...,an |-_3 phi  G1 |- D_a1 ... Gn |- D_an
00094 // -------------------------------------------------
00095 //    G0,G1,...,Gn |-_3 (a1 & ... & an) -> phi
00096 Theorem3
00097 CoreTheoremProducer::implIntro3(const Theorem3& phi,
00098                                   const std::vector<Expr>& assump,
00099                                   const vector<Theorem>& tccs) {
00100   bool checkProofs(CHECK_PROOFS);
00101   // This rule only makes sense when runnnig with assumptions
00102   if(checkProofs) {
00103     CHECK_SOUND(withAssumptions(),
00104                 "implIntro3: called while running without assumptions");
00105   }
00106 
00107   const Assumptions& phiAssump = phi.getAssumptionsRef();
00108 
00109   if(checkProofs) {
00110     CHECK_SOUND(assump.size() == tccs.size(),
00111                 "implIntro3: number of assumptions ("
00112                 +int2string(assump.size())+") and number of TCCs ("
00113                 +int2string(tccs.size())
00114                 +") does not match");
00115     for(size_t i=0; i<assump.size(); i++) {
00116       const Theorem& thm = phiAssump[assump[i]];
00117       CHECK_SOUND(!thm.isNull() && thm.isAssump(),
00118                   "implIntro3: this is not an assumption of phi:\n\n"
00119                   "  a["+int2string(i)+"] = "+assump[i].toString()
00120                   +"\n\n  phi = "+phi.getExpr().toString());
00121       CHECK_SOUND(tccs[i].getExpr() == d_core->getTCC(assump[i]),
00122                   "implIntro3: Assumption does not match its TCC:\n\n"
00123                   "  a["+int2string(i)+"] = "+assump[i].toString()
00124                   +"  TCC(a["+int2string(i)+"]) = "
00125                   +d_core->getTCC(assump[i]).toString()
00126                   +"\n\n  tccs["+int2string(i)+"] = "
00127                   +tccs[i].getExpr().toString());
00128     }
00129   }
00130 
00131   // Proof compaction: trivial derivation
00132   if(assump.size() == 0) return phi;
00133 
00134   Assumptions a(phiAssump - assump);
00135   a.add(merge(tccs));
00136   Proof pf;
00137   if(withProof()) {
00138     vector<Proof> u; // Proof labels for assumptions
00139     for(vector<Expr>::const_iterator i=assump.begin(), iend=assump.end();
00140         i!=iend; ++i) {
00141       const Theorem& t = phiAssump[*i];
00142       u.push_back(t.getProof());
00143     }
00144     // Arguments to the proof rule:
00145     // impl_intro_3(phi, a1,...,an,tcc1,...tccn,pf_tcc1,...pf_tccn,
00146     //              [lambda(a1,...,an): pf_phi])
00147     vector<Expr> args;
00148     vector<Proof> pfs;
00149     args.push_back(phi.getExpr());
00150     args.insert(args.end(), assump.begin(), assump.end());
00151     for(vector<Theorem>::const_iterator i=tccs.begin(), iend=tccs.end();
00152         i!=iend; ++i) {
00153       args.push_back(i->getExpr());
00154       pfs.push_back(i->getProof());
00155     }
00156     // Lambda-abstraction of pf_phi
00157     pfs.push_back(newPf(u, assump, phi.getProof()));
00158     pf = newPf("impl_intro_3", args, pfs);
00159   }
00160   Expr conj(andExpr(assump));
00161   return newTheorem3(conj.impExpr(phi.getExpr()), a, pf);
00162 }
00163 
00164 
00165 // e: T ==> |- typePred_T(e)  [asserting the type predicate of e]
00166 Theorem
00167 CoreTheoremProducer::typePred(const Expr& e) {
00168   Type tp(e.getType());
00169   Expr pred(d_core->getTypePred(tp, e));
00170   Assumptions a;
00171   Proof pf;
00172   if(withProof()) {
00173     pf = newPf("type_pred", e, tp.getExpr());
00174   }
00175   return newTheorem(pred, a, pf);
00176 }
00177 
00178 
00179 // Rewrite rules used only in TheoryCore to replace LETDECL and
00180 // CONSTDEF with their definitions
00181 Theorem
00182 CoreTheoremProducer::rewriteLetDecl(const Expr& e) {
00183   if(CHECK_PROOFS)
00184     CHECK_SOUND(e.getKind() == LETDECL,
00185                 "rewriteLetDecl: wrong expression: " + e.toString());
00186   Assumptions a;
00187   Proof pf;
00188   if(withProof()) // FIXME: implement this in flea
00189     pf = newPf("rewrite_letdecl", e[1]);
00190   return newRWTheorem(e, e[1], a, pf);
00191 }
00192 
00193 Theorem
00194 CoreTheoremProducer::rewriteConstDef(const Expr& e) {
00195   if(CHECK_PROOFS)
00196     CHECK_SOUND(e.getKind() == CONSTDEF,
00197                 "rewriteConstDef: wrong expression: " + e.toString());
00198   Assumptions a;
00199   Proof pf;
00200   if(withProof()) // FIXME: implement this in flea
00201     pf = newPf("rewrite_constdef", e[1]);
00202   return newRWTheorem(e, e[1], a, pf);
00203 }
00204 
00205 
00206 // ==> NOT (AND e1 ... en) IFF (OR !e1 ... !en), takes (AND ...)
00207 Theorem CoreTheoremProducer::rewriteNotAnd(const Expr& e) {
00208  if(CHECK_PROOFS)
00209   CHECK_SOUND(e.isNot() && e[0].isAnd(),
00210                 "rewriteNotAnd: precondition violated: " + e.toString());
00211 
00212   
00213   vector<Expr> kids; // vector of <!e1,...,!en>
00214   for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00215     // Collapse double negations
00216     kids.push_back(i->negate());
00217   Assumptions a;
00218   Proof pf;
00219   if(withProof())
00220     pf = newPf("rewrite_not_and", e);
00221   return newRWTheorem(e, orExpr(kids), a, pf);
00222 }
00223 
00224 // ==> NOT (OR e1 ... en) IFF (AND !e1 ... !en), takes (OR ...)
00225 Theorem
00226 CoreTheoremProducer::rewriteNotOr(const Expr& e) {
00227   if(CHECK_PROOFS)
00228     CHECK_SOUND(e.isNot() && e[0].isOr(),
00229                 "rewriteNotOr: precondition violated: " + e.toString());
00230   vector<Expr> kids; // vector of <!e1,...,!en>
00231   for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00232     // Collapse double negations
00233     kids.push_back(i->negate());
00234   Assumptions a;
00235   Proof pf;
00236   if(withProof())
00237     pf = newPf("rewrite_not_or", e);
00238   return newRWTheorem(e, andExpr(kids), a, pf);
00239 }
00240 
00241 
00242 // ==> NOT IFF(e1,e2) IFF IFF(e1,NOT e2)
00243 Theorem
00244 CoreTheoremProducer::rewriteNotIff(const Expr& e) {
00245   Assumptions a;
00246   Proof pf;
00247   if(CHECK_PROOFS)
00248     CHECK_SOUND(e.isNot() && e[0].isIff(), "rewriteNotIff precondition violated");
00249   if(withProof()) {
00250     pf = newPf("rewrite_not_iff", e);
00251   }
00252   return newRWTheorem(e, e[0][0].iffExpr(!e[0][1]), a, pf);
00253 }
00254 
00255 
00256 // ==> NOT ITE(a,b,c) IFF ITE(a,NOT b,NOT c)
00257 Theorem
00258 CoreTheoremProducer::rewriteNotIte(const Expr& e) {
00259   Assumptions a;
00260   Proof pf;
00261   if(CHECK_PROOFS)
00262     CHECK_SOUND(e.isNot() && e[0].isITE(), "rewriteNotIte precondition violated");
00263   if(withProof()) {
00264     pf = newPf("rewrite_not_ite", e);
00265   }
00266   return newRWTheorem(e, e[0][0].iteExpr(!e[0][1], !e[0][2]), a, pf);
00267 }
00268 
00269 
00270 // ==> ITE(TRUE, e1, e2) == e1
00271 Theorem
00272 CoreTheoremProducer::rewriteIteTrue(const Expr& e) {
00273   Assumptions a;
00274   Proof pf;
00275   if(CHECK_PROOFS)
00276     CHECK_SOUND(e.isITE() && e[0].isTrue(),
00277                 "rewriteIteTrue precondition violated");
00278   if(withProof()) {
00279     Type t = e[1].getType();
00280     DebugAssert(!t.isNull(), "rewriteIteTrue: e1 has no type: "
00281                 + e[1].toString());
00282     bool useIff = t.isBool();
00283     if(useIff)
00284       pf = newPf("rewrite_ite_true_iff", e[1], e[2]);
00285     else {
00286       pf = newPf("rewrite_ite_true", t.getExpr(), e[1], e[2]);
00287     }
00288   }
00289   return newRWTheorem(e, e[1], a, pf);
00290 }
00291 
00292 
00293 // ==> ITE(FALSE, e1, e2) == e2
00294 Theorem
00295 CoreTheoremProducer::rewriteIteFalse(const Expr& e) {
00296   Assumptions a;
00297   Proof pf;
00298   if(CHECK_PROOFS)
00299     CHECK_SOUND(e.isITE() && e[0].isFalse(),
00300                 "rewriteIteFalse precondition violated");
00301   if(withProof()) {
00302     Type t = e[1].getType();
00303     DebugAssert(!t.isNull(), "rewriteIteFalse: e1 has no type: "
00304                 + e[1].toString());
00305     bool useIff = t.isBool();
00306     if(useIff)
00307       pf = newPf("rewrite_ite_false_iff", e[1], e[2]);
00308     else {
00309       pf = newPf("rewrite_ite_false", t.getExpr(), e[1], e[2]);
00310     }
00311   }
00312   return newRWTheorem(e, e[2], a, pf);
00313 }
00314 
00315 // ==> ITE(c, e, e) == e
00316 Theorem
00317 CoreTheoremProducer::rewriteIteSame(const Expr& e) {
00318   Assumptions a;
00319   Proof pf;
00320   if(CHECK_PROOFS)
00321     CHECK_SOUND(e.isITE() && e[1] == e[2],
00322                 "rewriteIteSame precondition violated");
00323   if(withProof()) {
00324     Type t = e[1].getType();
00325     DebugAssert(!t.isNull(), "rewriteIteSame: e[1] has no type: "
00326                 + e[1].toString());
00327     bool useIff = t.isBool();
00328     if(useIff)
00329       pf = newPf("rewrite_ite_same_iff", e[0], e[1]);
00330     else {
00331       pf = newPf("rewrite_ite_same", t.getExpr(), e[0], e[1]);
00332     }
00333   }
00334   return newRWTheorem(e, e[1], a, pf);
00335 }
00336 
00337 // a |- b == d ==> ITE(a, b, c) == ITE(a, d, c)
00338 Theorem
00339 CoreTheoremProducer::rewriteIteThen(const Expr& e, const Theorem& thenThm) {
00340   Assumptions a;
00341   Proof pf;
00342   if(CHECK_PROOFS) {
00343     CHECK_SOUND(withAssumptions(), "Cannot check proof without assumptions");
00344     CHECK_SOUND(e.isITE() && thenThm.isRewrite() && e[1] == thenThm.getLHS(),
00345                 "rewriteIteThen precondition violated \n then expression: "
00346                 + thenThm.getExpr().toString() + "\n e = " + e.toString());
00347   }
00348   if (withAssumptions()) {
00349     a = thenThm.getAssumptions() - e[0];
00350   }
00351   if(withProof()) {
00352     Type t = e.getType();
00353     DebugAssert(!t.isNull(), "rewriteIteThen: e has no type: "
00354                 + e.toString());
00355     bool useIff = t.isBool();
00356     if(useIff)
00357       pf = newPf("rewrite_ite_then_iff", e, thenThm.getProof());
00358     else {
00359       pf = newPf("rewrite_ite_then", e, thenThm.getProof());
00360     }
00361   }
00362   return newRWTheorem(e, e[0].iteExpr(thenThm.getRHS(), e[2]), a, pf);
00363 }
00364 
00365 // !a |- c == d ==> ITE(a, b, c) == ITE(a, b, d)
00366 Theorem
00367 CoreTheoremProducer::rewriteIteElse(const Expr& e, const Theorem& elseThm) {
00368   Assumptions a;
00369   Proof pf;
00370   if(CHECK_PROOFS) {
00371     CHECK_SOUND(withAssumptions(), "Cannot check proof without assumptions");
00372     CHECK_SOUND(e.isITE() && elseThm.isRewrite() && e[2] == elseThm.getLHS(),
00373                 "rewriteIteElse precondition violated \n else expression: "
00374                 + elseThm.getExpr().toString() + "\n e = " + e.toString());
00375   }
00376   if (withAssumptions()) {
00377     a = elseThm.getAssumptions() - !e[0];
00378   }
00379   if(withProof()) {
00380     Type t = e.getType();
00381     DebugAssert(!t.isNull(), "rewriteIteElse: e has no type: "
00382                 + e.toString());
00383     bool useIff = t.isBool();
00384     if(useIff)
00385       pf = newPf("rewrite_ite_else_iff", e, elseThm.getProof());
00386     else {
00387       pf = newPf("rewrite_ite_else", e, elseThm.getProof());
00388     }
00389   }
00390   return newRWTheorem(e, e[0].iteExpr(e[1], elseThm.getRHS()), a, pf);
00391 }
00392 
00393 // ==> ITE(c, e1, e2) <=> (!c OR e1) AND (c OR e2)
00394 Theorem 
00395 CoreTheoremProducer::rewriteIteBool(const Expr& c,
00396                                       const Expr& e1, const Expr& e2) {
00397   if(CHECK_PROOFS)
00398     CHECK_SOUND(e1.getType().isBool() && e2.getType().isBool(),
00399                 "rewriteIteBool: Not a boolean ITE: "
00400                 + c.iteExpr(e1, e2).toString());
00401   Assumptions a;
00402   Proof pf;
00403   if(withProof())
00404     pf = newPf("rewrite_ite_bool", c, e1, e2);
00405   return newRWTheorem(c.iteExpr(e1,e2),
00406                       (e1.orExpr(!c).andExpr(c.orExpr(e2))), a, pf);
00407 }
00408 
00409 
00410 //! |= (A & B1) | (A & B2) | ... | (A & bn) <=> A & (B1 | B2 | ...| Bn)
00411 Theorem
00412 CoreTheoremProducer::orDistributivityRule(const Expr& e) {
00413   if(CHECK_PROOFS) {
00414     CHECK_SOUND(e.isOr() && e.arity() >= 2,
00415                 "CoreTheoremProducer::orDistributivityRule: "
00416                 "input must be an OR expr: \n" + e.toString());
00417     const Expr& e0 = e[0];
00418 
00419     CHECK_SOUND(e0.isAnd() && e0.arity() == 2,
00420                 "CoreTheoremProducer::orDistributivityRule: "
00421                 "input must be an OR of binary ANDs: \n" + e.toString());
00422   }
00423 
00424   const Expr& A = e[0][0];
00425 
00426   if(CHECK_PROOFS) {
00427     for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00428       const Expr& ei = *i;
00429       CHECK_SOUND(ei.isAnd() && ei.arity() == 2,
00430                 "CoreTheoremProducer::orDistributivityRule: "
00431                 "input must be an OR of binary ANDs: \n" + e.toString());
00432       CHECK_SOUND(A == ei[0],
00433                   "CoreTheoremProducer::orDistributivityRule: "
00434                   "input must have a common factor: \n" + e.toString());
00435     }
00436   }
00437   vector<Expr> output;
00438   for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00439     Expr ei = *i;
00440     output.push_back(ei[1]);
00441   }
00442   Expr out = A.andExpr(orExpr(output));
00443 
00444   Assumptions a;
00445   Proof pf;
00446   if(withProof())
00447     pf = newPf("or_distribuitivity_rule", e);
00448   
00449   return newRWTheorem(e, out, a, pf);
00450 } 
00451 
00452 
00453 
00454 //! |= (A | B1) & (A | B2) & ... & (A | bn) <=> A | (B1 & B2 & ...& Bn)
00455 Theorem
00456 CoreTheoremProducer::andDistributivityRule(const Expr& e) {
00457   if(CHECK_PROOFS) {
00458     CHECK_SOUND(e.isAnd() && e.arity() >= 2,
00459                 "CoreTheoremProducer::andDistributivityRule: "
00460                 "input must be an AND expr: \n" + e.toString());
00461     const Expr& e0 = e[0];
00462 
00463     CHECK_SOUND(e0.isOr() && e0.arity() == 2,
00464                 "CoreTheoremProducer::orDistributivityRule: "
00465                 "input must be an AND of binary ORs: \n" + e.toString());
00466   }
00467 
00468   const Expr& A = e[0][0];
00469 
00470   if(CHECK_PROOFS) {
00471     for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00472       const Expr& ei = *i;
00473       CHECK_SOUND(ei.isOr() && ei.arity() == 2,
00474                 "CoreTheoremProducer::andDistributivityRule: "
00475                 "input must be an AND of binary ORs: \n" + e.toString());
00476       CHECK_SOUND(A == ei[0],
00477                   "CoreTheoremProducer::andDistributivityRule: "
00478                   "input must have a common factor: \n" + e.toString());
00479     }
00480   }
00481   vector<Expr> output;
00482   for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00483     output.push_back((*i)[1]);
00484   }
00485   Expr out = A.orExpr(andExpr(output));
00486 
00487   Assumptions a;
00488   Proof pf;
00489   if(withProof())
00490     pf = newPf("and_distribuitivity_rule", e);
00491   
00492   return newRWTheorem(e, out, a, pf);
00493 } 
00494 
00495 // ==> IMPLIES(e1,e2) IFF OR(!e1, e2)
00496 Theorem
00497 CoreTheoremProducer::rewriteImplies(const Expr& e) {
00498   Assumptions a;
00499   Proof pf;
00500   if(CHECK_PROOFS)
00501     CHECK_SOUND(e.isImpl(), "rewriteImplies precondition violated");
00502   if(withProof()) {
00503     pf = newPf("rewrite_implies", e[0], e[1]);
00504   }
00505   return newRWTheorem(e, !e[0] || e[1], a, pf);
00506 }
00507 
00508 // ==> NOT(e) == ITE(e, FALSE, TRUE)
00509 Theorem
00510 CoreTheoremProducer::NotToIte(const Expr& not_e){
00511   Assumptions a;
00512   Proof pf;
00513   if(CHECK_PROOFS)
00514     CHECK_SOUND(not_e.isNot() && not_e[0].getType().isBool(),
00515                 "NotToIte precondition violated");
00516   if(withProof())
00517     pf = newPf("NotToIte", not_e[0]);
00518   if(not_e[0].isTrue())
00519     return d_core->getCommonRules()->rewriteNotTrue(not_e);
00520   else if(not_e[0].isFalse())
00521     return d_core->getCommonRules()->rewriteNotFalse(not_e);
00522   Expr ite(not_e[0].iteExpr(d_em->falseExpr(), d_em->trueExpr()));
00523   return newRWTheorem(not_e, ite, a, pf);  
00524 }
00525 
00526 // ==> Or(e) == ITE(e[1], TRUE, e[0])
00527 Theorem
00528 CoreTheoremProducer::OrToIte(const Expr& e){
00529   if(CHECK_PROOFS)
00530     CHECK_SOUND(e.isOr(),
00531                 "OrToIte: precondition violated: " + e.toString());
00532   Assumptions a;
00533   Proof pf;
00534   if(withProof()) {
00535     pf = newPf("OrToIte", e);
00536   }
00537   const vector<Expr>& kids = e.getKids();
00538   unsigned k(kids.size());
00539   if(k==0)
00540     return newRWTheorem(e, d_em->falseExpr(), a, pf);
00541   if(k==1)
00542     return newRWTheorem(e, e[0], a, pf);
00543   Expr ite(kids[k-1]);
00544   if(CHECK_PROOFS)
00545     CHECK_SOUND(!ite.getType().isNull(),
00546                 "OrToIte: kid " + int2string(k-1) + " has no type: "
00547                 + (ite).toString());
00548   for (; k > 1; k--) {
00549     if (kids[k-2].isTrue()) {
00550       ite = d_em->trueExpr();
00551       break;
00552     }
00553     else if(kids[k-2].isFalse()) continue;
00554     else{
00555       if(CHECK_PROOFS)
00556         CHECK_SOUND(!kids[k-2].getType().isNull(),
00557                   "OrToIte: kid " + int2string(k-2) + " has no type: "
00558                   + (kids[k-2]).toString());
00559       ite = ite.iteExpr(d_em->trueExpr(), kids[k-2]);
00560     }
00561   }
00562   return newRWTheorem(e, ite, a, pf);
00563 }
00564 
00565 // ==> And(e) == ITE(e[1], e[0], FALSE)
00566 Theorem
00567 CoreTheoremProducer::AndToIte(const Expr& e){
00568   if(CHECK_PROOFS)
00569     CHECK_SOUND(e.isAnd(),
00570                 "AndToIte: precondition violated: " + e.toString());
00571   Assumptions a;
00572   Proof pf;
00573   if(withProof()) {
00574     pf = newPf("AndToIte", e);
00575   }
00576   const vector<Expr>& kids = e.getKids();
00577   unsigned k(kids.size());
00578   if(k==0)
00579     return newRWTheorem(e, d_em->trueExpr(), a, pf);
00580   if(k==1)
00581     return newRWTheorem(e, e[0], a, pf);
00582   Expr ite(kids[k-1]);
00583   if(CHECK_PROOFS)
00584     CHECK_SOUND(!ite.getType().isNull(),
00585                 "AndToIte: kid " + int2string(k-1) + " has no type: "
00586                 + (ite).toString());
00587   for (; k > 1; k--) {
00588     if (kids[k-2].isFalse()) {
00589       ite = d_em->falseExpr();
00590       break;
00591     }
00592     else if(kids[k-2].isTrue()) {
00593       continue;
00594     }
00595     else{
00596       if(CHECK_PROOFS)
00597         CHECK_SOUND(!kids[k-2].getType().isNull(),
00598                     "AndToIte: kid " + int2string(k-2) + " has no type: "
00599                     + (kids[k-2]).toString());
00600       ite = ite.iteExpr(kids[k-2], d_em->falseExpr());
00601     }
00602   }
00603   return newRWTheorem(e, ite, a, pf);
00604 }
00605 
00606 // ==> IFF(a,b) == ITE(a, b, !b)
00607 Theorem
00608 CoreTheoremProducer::IffToIte(const Expr& e){
00609   if(CHECK_PROOFS)
00610     CHECK_SOUND(e.isIff() && e[0].getType().isBool() && e[1].getType().isBool(),
00611                 "IffToIte: precondition violated: " + e.toString());
00612   Assumptions a;
00613   Proof pf;
00614   if(e[0] == e[1]) return d_core->getCommonRules()->reflexivityRule(e);
00615   Expr ite(e[0].iteExpr(e[1], e[1].iteExpr(d_em->falseExpr(),
00616                                            d_em->trueExpr())));
00617   if(withProof()) {
00618     pf = newPf("iff_to_ite", e);
00619   }
00620   return newRWTheorem(e, ite, a, pf); 
00621 }
00622 
00623 // ==> IMPLIES(a,b) == ITE(a, b, TRUE)
00624 Theorem
00625 CoreTheoremProducer::ImpToIte(const Expr& e){
00626   if(CHECK_PROOFS)
00627     CHECK_SOUND(e.isImpl() && e[0].getType().isBool() && e[1].getType().isBool(),
00628                 "ImpToIte: precondition violated: " + e.toString());
00629   Assumptions a;
00630   Proof pf;
00631   if(e[0] == e[1]) return d_core->getCommonRules()->reflexivityRule(e);
00632   Expr ite(e[0].iteExpr(e[1], d_em->trueExpr()));
00633   if(withProof()) {
00634     pf = newPf("imp_to_ite", e);
00635   }
00636   return newRWTheorem(e, ite, a, pf); 
00637 }
00638 
00639 
00640 // ==> ITE(e, FALSE, TRUE) IFF NOT(e)
00641 Theorem
00642 CoreTheoremProducer::rewriteIteToNot(const Expr& e)
00643 {
00644   if (CHECK_PROOFS)
00645     CHECK_SOUND(e.isITE() && e[1].isFalse() && e[2].isTrue(),
00646                 "rewriteIteToNot: " + e.toString());
00647   Assumptions a;
00648   Proof pf;
00649   if (withProof()) pf = newPf("rewrite_ite_to_not", e);
00650   return newRWTheorem(e, e[0].negate(), a, pf);
00651 }
00652 
00653 // ==> ITE(a, TRUE, b) IFF OR(a, b)
00654 Theorem
00655 CoreTheoremProducer::rewriteIteToOr(const Expr& e)
00656 {
00657   if (CHECK_PROOFS)
00658     CHECK_SOUND(e.isITE() && e[1].isTrue(),
00659                 "rewriteIteToOr: " + e.toString());
00660   Assumptions a;
00661   Proof pf;
00662   if (withProof()) pf = newPf("rewrite_ite_to_or", e);
00663   return newRWTheorem(e, e[0] || e[2], a, pf);
00664 }
00665 
00666 // ==> ITE(a, b, FALSE) IFF AND(a, b)
00667 Theorem
00668 CoreTheoremProducer::rewriteIteToAnd(const Expr& e)
00669 {
00670   if (CHECK_PROOFS)
00671     CHECK_SOUND(e.isITE() && e[2].isFalse(),
00672                 "rewriteIteToAnd: " + e.toString());
00673   Assumptions a;
00674   Proof pf;
00675   if (withProof()) pf = newPf("rewrite_ite_to_and", e);
00676   return newRWTheorem(e, e[0] && e[1], a, pf);
00677 }
00678 
00679 // ==> ITE(a, b, !b) IFF IFF(a, b)
00680 Theorem
00681 CoreTheoremProducer::rewriteIteToIff(const Expr& e)
00682 {
00683   if (CHECK_PROOFS)
00684     CHECK_SOUND(e.isITE() && e[1] == e[2].negate(),
00685                 "rewriteIteToIff: " + e.toString());
00686   Assumptions a;
00687   Proof pf;
00688   if (withProof()) pf = newPf("rewrite_ite_to_iff", e);
00689   return newRWTheorem(e, e[0].iffExpr(e[1]), a, pf);
00690 }
00691 
00692 // ==> ITE(a, b, TRUE) IFF IMPLIES(a, b)
00693 Theorem
00694 CoreTheoremProducer::rewriteIteToImp(const Expr& e)
00695 {
00696   if (CHECK_PROOFS)
00697     CHECK_SOUND(e.isITE() && e[2].isTrue(),
00698                 "rewriteIteToImp: " + e.toString());
00699   Assumptions a;
00700   Proof pf;
00701   if (withProof()) pf = newPf("rewrite_ite_to_imp", e);
00702   return newRWTheorem(e, e[0].impExpr(e[1]), a, pf);
00703 }
00704 
00705 
00706 // ==> ITE(a, b(a), c(a)) IFF ITE(a, b(TRUE), c(FALSE))
00707 Theorem
00708 CoreTheoremProducer::rewriteIteCond(const Expr& e) {
00709   if (CHECK_PROOFS)
00710     CHECK_SOUND(e.isITE() && e.arity()==3, "rewriteIteCond: " + e.toString());
00711 
00712   vector<Expr> oldTerms, newTerms;
00713   oldTerms.push_back(e[0]);
00714   newTerms.push_back(d_em->trueExpr());
00715   
00716   Expr e1(e[1].substExpr(oldTerms, newTerms));
00717   newTerms[0] = d_em->falseExpr();
00718   Expr e2(e[2].substExpr(oldTerms, newTerms));
00719 
00720   Assumptions a;
00721   Proof pf;
00722   if (withProof()) pf = newPf("rewrite_ite_cond", e);
00723   return newRWTheorem(e, e[0].iteExpr(e1, e2), a, pf);
00724 }
00725 
00726 
00727 Theorem
00728 CoreTheoremProducer::iffOrDistrib(const Expr& iff) {
00729   if(CHECK_PROOFS) {
00730     CHECK_SOUND(iff.isIff() && iff.arity()==2, "iffOrDistrib("
00731                 +iff.toString()+")");
00732     CHECK_SOUND(iff[0].isOr() && iff[0].arity()==2, "iffOrDistrib("
00733                 +iff.toString()+")");
00734     CHECK_SOUND(iff[1].isOr() && iff[1].arity()==2, "iffOrDistrib("
00735                 +iff.toString()+")");
00736     CHECK_SOUND(iff[0][0]==iff[1][0], "iffOrDistrib("
00737                 +iff.toString()+")");
00738   }
00739   const Expr& a = iff[0][0];
00740   const Expr& b = iff[0][1];
00741   const Expr& c = iff[1][1];
00742   Assumptions assump;
00743   Proof pf;
00744   if(withProof())
00745     pf = newPf("iff_or_distrib", iff);
00746   return newRWTheorem(iff, (a || (b.iffExpr(c))), assump, pf);
00747 }
00748 
00749 
00750 Theorem
00751 CoreTheoremProducer::iffAndDistrib(const Expr& iff) {
00752   if(CHECK_PROOFS) {
00753     CHECK_SOUND(iff.isIff() && iff.arity()==2, "iffAndDistrib("
00754                 +iff.toString()+")");
00755     CHECK_SOUND(iff[0].isAnd() && iff[0].arity()==2, "iffAndDistrib("
00756                 +iff.toString()+")");
00757     CHECK_SOUND(iff[1].isAnd() && iff[1].arity()==2, "iffAndDistrib("
00758                 +iff.toString()+")");
00759     CHECK_SOUND(iff[0][0]==iff[1][0], "iffOrDistrib("
00760                 +iff.toString()+")");
00761   }
00762   const Expr& a = iff[0][0];
00763   const Expr& b = iff[0][1];
00764   const Expr& c = iff[1][1];
00765   Assumptions assump;
00766   Proof pf;
00767   if(withProof())
00768     pf = newPf("iff_and_distrib", iff);
00769   return newRWTheorem(iff, (!a || (b.iffExpr(c))), assump, pf);
00770 }
00771 
00772 
00773 // |- op(ITE(cond,a,b)) =/<=> ITE(cond,op(a),op(b))
00774 Theorem
00775 CoreTheoremProducer::ifLiftUnaryRule(const Expr& e) {
00776   if(CHECK_PROOFS) {
00777     CHECK_SOUND(e.arity()==1 && e[0].isITE(),
00778                 "CoreTheoremProducer::ifLiftUnaryRule("
00779                 "e = " + e.toString() + ")");
00780   }
00781   Op op(e.getOp());
00782   const Expr& ite = e[0];
00783   const Expr& cond = ite[0];
00784   const Expr& t1 = ite[1];
00785   const Expr& t2 = ite[2];
00786 
00787   if(CHECK_PROOFS) {
00788     CHECK_SOUND(cond.getType().isBool(),
00789                 "CoreTheoremProducer::ifLiftUnaryRule("
00790                 "e = " + e.toString()+")");      
00791   }    
00792 
00793   Expr e1 =  Expr(op, t1);
00794   Expr e2 =  Expr(op, t2);
00795 
00796   Expr resultITE = cond.iteExpr(e1, e2);
00797 
00798   Assumptions a; Proof pf;
00799   if (withProof())
00800     pf = newPf("if_lift_unary_rule", e);
00801   return newRWTheorem(e, resultITE, a, pf);
00802 }
00803 
00804 
00805 // (a & b) <=> a & b[a/true]; takes the index of a and rewrites all
00806 // the other conjuncts.
00807 Theorem
00808 CoreTheoremProducer::rewriteAndSubterms(const Expr& e, int idx) {
00809   if(CHECK_PROOFS) {
00810     CHECK_SOUND(e.isAnd() && 0 <= idx && idx < e.arity(),
00811                 "rewriteAndSubterms("+e.toString()
00812                 +", idx="+int2string(idx)
00813                 +"):\n Expected an AND and a valid index of a child");
00814   }
00815   vector<Expr> kids;
00816   ExprHashMap<Expr> subst;
00817   subst.insert(e[idx], d_em->trueExpr());
00818   for(int i=0, iend=e.arity(); i<iend; ++i) {
00819     if(i==idx)
00820       kids.push_back(e[i]);
00821     else
00822       kids.push_back(e[i].substExpr(subst));
00823   }
00824   Assumptions a;
00825   Proof pf;
00826   if(withProof())
00827     pf = newPf("rewrite_and_subterms", e, d_em->newRatExpr(idx));
00828   return newRWTheorem(e, Expr(e.getOp(), kids), a, pf);
00829 }
00830 
00831 
00832 // (a | b) <=> a | b[a/false]; takes the index of a and rewrites all
00833 // the other disjuncts.
00834 Theorem
00835 CoreTheoremProducer::rewriteOrSubterms(const Expr& e, int idx) {
00836   if(CHECK_PROOFS) {
00837     CHECK_SOUND(e.isOr() && 0 <= idx && idx < e.arity(),
00838                 "rewriteOrSubterms("+e.toString()
00839                 +", idx="+int2string(idx)
00840                 +"):\n Expected an OR and a valid index of a child");
00841   }
00842   vector<Expr> kids;
00843   ExprHashMap<Expr> subst;
00844   subst.insert(e[idx], d_em->falseExpr());
00845   for(int i=0, iend=e.arity(); i<iend; ++i) {
00846     if(i==idx)
00847       kids.push_back(e[i]);
00848     else
00849       kids.push_back(e[i].substExpr(subst));
00850   }
00851   Assumptions a;
00852   Proof pf;
00853   if(withProof())
00854     pf = newPf("rewrite_or_subterms", e, d_em->newRatExpr(idx));
00855   return newRWTheorem(e, Expr(e.getOp(), kids), a, pf);
00856 }

Generated on Thu Apr 13 16:57:30 2006 for CVC Lite by  doxygen 1.4.4