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  *
00011  * License to use, copy, modify, sell and/or distribute this software
00012  * and its documentation for any purpose is hereby granted without
00013  * royalty, subject to the terms and conditions defined in the \ref
00014  * LICENSE file provided with this distribution.
00015  * 
00016  * <hr>
00017  * 
00018  */
00019 /*****************************************************************************/
00020 // CLASS: CoreTheoremProducer
00021 //
00022 // AUTHOR: Sergey Berezin, 12/09/2002
00023 //         Vijay Ganesh, september 15th, 2004 (CNF Converter rules)
00024 //
00025 // Description: Implementation of the proof rules for ground
00026 // equational logic (reflexivity, symmetry, transitivity, and
00027 // substitutivity).
00028 //
00029 ///////////////////////////////////////////////////////////////////////////////
00030 
00031 
00032 // This code is trusted
00033 #define _CVC3_TRUSTED_
00034 
00035 
00036 #include "core_theorem_producer.h"
00037 #include "theory_core.h"
00038 
00039 
00040 using namespace CVC3;
00041 using namespace std;
00042 
00043 
00044 // The trusted method of TheoryCore which creates this theorem producer
00045 CoreProofRules* TheoryCore::createProofRules(TheoremManager* tm) {
00046   return new CoreTheoremProducer(tm, this);
00047 }
00048 
00049 
00050 // e: T ==> |- typePred_T(e)  [asserting the type predicate of e]
00051 Theorem
00052 CoreTheoremProducer::typePred(const Expr& e) {
00053   Type tp(e.getType());
00054   Expr pred(d_core->getTypePred(tp, e));
00055   Proof pf;
00056   if(withProof()) {
00057     pf = newPf("type_pred", e, tp.getExpr());
00058   }
00059   return newTheorem(pred, Assumptions::emptyAssump(), pf);
00060 }
00061 
00062 
00063 Theorem
00064 CoreTheoremProducer::rewriteLetDecl(const Expr& e) {
00065   if(CHECK_PROOFS)
00066     CHECK_SOUND(e.getKind() == LETDECL,
00067     "rewriteLetDecl: wrong expression: " + e.toString());
00068   Proof pf;
00069   if(withProof()) // FIXME: implement this in flea
00070     pf = newPf("rewrite_letdecl", e[1]);
00071   return newRWTheorem(e, e[1], Assumptions::emptyAssump(), pf);
00072 }
00073 
00074 // ==> NOT (AND e1 ... en) IFF (OR !e1 ... !en), takes (AND ...)
00075 Theorem CoreTheoremProducer::rewriteNotAnd(const Expr& e) {
00076  if(CHECK_PROOFS)
00077   CHECK_SOUND(e.isNot() && e[0].isAnd(),
00078     "rewriteNotAnd: precondition violated: " + e.toString());
00079 
00080   
00081   vector<Expr> kids; // vector of <!e1,...,!en>
00082   for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00083     // Collapse double negations
00084     kids.push_back(i->negate());
00085   Proof pf;
00086   if(withProof())
00087     pf = newPf("rewrite_not_and", e);
00088   return newRWTheorem(e, orExpr(kids), Assumptions::emptyAssump(), pf);
00089 }
00090 
00091 // ==> NOT (OR e1 ... en) IFF (AND !e1 ... !en), takes (OR ...)
00092 Theorem
00093 CoreTheoremProducer::rewriteNotOr(const Expr& e) {
00094   if(CHECK_PROOFS)
00095     CHECK_SOUND(e.isNot() && e[0].isOr(),
00096     "rewriteNotOr: precondition violated: " + e.toString());
00097   vector<Expr> kids; // vector of <!e1,...,!en>
00098   for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00099     // Collapse double negations
00100     kids.push_back(i->negate());
00101   Proof pf;
00102   if(withProof())
00103     pf = newPf("rewrite_not_or", e);
00104   return newRWTheorem(e, andExpr(kids), Assumptions::emptyAssump(), pf);
00105 }
00106 
00107 
00108 // ==> NOT IFF(e1,e2) IFF IFF(e1,NOT e2)
00109 Theorem
00110 CoreTheoremProducer::rewriteNotIff(const Expr& e) {
00111   Proof pf;
00112   if(CHECK_PROOFS)
00113     CHECK_SOUND(e.isNot() && e[0].isIff(), "rewriteNotIff precondition violated");
00114   if(withProof()) {
00115     pf = newPf("rewrite_not_iff", e);
00116   }
00117   return newRWTheorem(e, e[0][0].iffExpr(!e[0][1]), Assumptions::emptyAssump(), pf);
00118 }
00119 
00120 
00121 // ==> NOT ITE(a,b,c) IFF ITE(a,NOT b,NOT c)
00122 Theorem
00123 CoreTheoremProducer::rewriteNotIte(const Expr& e) {
00124   Proof pf;
00125   if(CHECK_PROOFS)
00126     CHECK_SOUND(e.isNot() && e[0].isITE(), "rewriteNotIte precondition violated");
00127   if(withProof()) {
00128     pf = newPf("rewrite_not_ite", e);
00129   }
00130   return newRWTheorem(e, e[0][0].iteExpr(!e[0][1], !e[0][2]), Assumptions::emptyAssump(), pf);
00131 }
00132 
00133 
00134 // ==> ITE(TRUE, e1, e2) == e1
00135 Theorem
00136 CoreTheoremProducer::rewriteIteTrue(const Expr& e) {
00137   Proof pf;
00138   if(CHECK_PROOFS)
00139     CHECK_SOUND(e.isITE() && e[0].isTrue(),
00140     "rewriteIteTrue precondition violated");
00141   if(withProof()) {
00142     Type t = e[1].getType();
00143     DebugAssert(!t.isNull(), "rewriteIteTrue: e1 has no type: "
00144     + e[1].toString());
00145     bool useIff = t.isBool();
00146     if(useIff)
00147       pf = newPf("rewrite_ite_true_iff", e[1], e[2]);
00148     else {
00149       pf = newPf("rewrite_ite_true", t.getExpr(), e[1], e[2]);
00150     }
00151   }
00152   return newRWTheorem(e, e[1], Assumptions::emptyAssump(), pf);
00153 }
00154 
00155 
00156 // ==> ITE(FALSE, e1, e2) == e2
00157 Theorem
00158 CoreTheoremProducer::rewriteIteFalse(const Expr& e) {
00159   Proof pf;
00160   if(CHECK_PROOFS)
00161     CHECK_SOUND(e.isITE() && e[0].isFalse(),
00162     "rewriteIteFalse precondition violated");
00163   if(withProof()) {
00164     Type t = e[1].getType();
00165     DebugAssert(!t.isNull(), "rewriteIteFalse: e1 has no type: "
00166     + e[1].toString());
00167     bool useIff = t.isBool();
00168     if(useIff)
00169       pf = newPf("rewrite_ite_false_iff", e[1], e[2]);
00170     else {
00171       pf = newPf("rewrite_ite_false", t.getExpr(), e[1], e[2]);
00172     }
00173   }
00174   return newRWTheorem(e, e[2], Assumptions::emptyAssump(), pf);
00175 }
00176 
00177 // ==> ITE(c, e, e) == e
00178 Theorem
00179 CoreTheoremProducer::rewriteIteSame(const Expr& e) {
00180   Proof pf;
00181   if(CHECK_PROOFS)
00182     CHECK_SOUND(e.isITE() && e[1] == e[2],
00183     "rewriteIteSame precondition violated");
00184   if(withProof()) {
00185     Type t = e[1].getType();
00186     DebugAssert(!t.isNull(), "rewriteIteSame: e[1] has no type: "
00187     + e[1].toString());
00188     bool useIff = t.isBool();
00189     if(useIff)
00190       pf = newPf("rewrite_ite_same_iff", e[0], e[1]);
00191     else {
00192       pf = newPf("rewrite_ite_same", t.getExpr(), e[0], e[1]);
00193     }
00194   }
00195   return newRWTheorem(e, e[1], Assumptions::emptyAssump(), pf);
00196 }
00197 
00198 // a |- b == d ==> ITE(a, b, c) == ITE(a, d, c)
00199 Theorem
00200 CoreTheoremProducer::rewriteIteThen(const Expr& e, const Theorem& thenThm) {
00201   Proof pf;
00202   if(CHECK_PROOFS) {
00203     CHECK_SOUND(withAssumptions(), "Cannot check proof without assumptions");
00204     CHECK_SOUND(e.isITE() && thenThm.isRewrite() && e[1] == thenThm.getLHS(),
00205     "rewriteIteThen precondition violated \n then expression: "
00206     + thenThm.getExpr().toString() + "\n e = " + e.toString());
00207   }
00208   Assumptions a = thenThm.getAssumptionsRef() - e[0];
00209   if(withProof()) {
00210     Type t = e.getType();
00211     DebugAssert(!t.isNull(), "rewriteIteThen: e has no type: "
00212     + e.toString());
00213     bool useIff = t.isBool();
00214     if(useIff)
00215       pf = newPf("rewrite_ite_then_iff", e, thenThm.getProof());
00216     else {
00217       pf = newPf("rewrite_ite_then", e, thenThm.getProof());
00218     }
00219   }
00220   return newRWTheorem(e, e[0].iteExpr(thenThm.getRHS(), e[2]), a, pf);
00221 }
00222 
00223 // !a |- c == d ==> ITE(a, b, c) == ITE(a, b, d)
00224 Theorem
00225 CoreTheoremProducer::rewriteIteElse(const Expr& e, const Theorem& elseThm) {
00226   Proof pf;
00227   if(CHECK_PROOFS) {
00228     CHECK_SOUND(withAssumptions(), "Cannot check proof without assumptions");
00229     CHECK_SOUND(e.isITE() && elseThm.isRewrite() && e[2] == elseThm.getLHS(),
00230     "rewriteIteElse precondition violated \n else expression: "
00231     + elseThm.getExpr().toString() + "\n e = " + e.toString());
00232   }
00233   Assumptions a = elseThm.getAssumptionsRef() - !e[0];
00234   if(withProof()) {
00235     Type t = e.getType();
00236     DebugAssert(!t.isNull(), "rewriteIteElse: e has no type: "
00237     + e.toString());
00238     bool useIff = t.isBool();
00239     if(useIff)
00240       pf = newPf("rewrite_ite_else_iff", e, elseThm.getProof());
00241     else {
00242       pf = newPf("rewrite_ite_else", e, elseThm.getProof());
00243     }
00244   }
00245   return newRWTheorem(e, e[0].iteExpr(e[1], elseThm.getRHS()), a, pf);
00246 }
00247 
00248 // ==> ITE(c, e1, e2) <=> (!c OR e1) AND (c OR e2)
00249 Theorem 
00250 CoreTheoremProducer::rewriteIteBool(const Expr& c,
00251                                     const Expr& e1, const Expr& e2) {
00252   if(CHECK_PROOFS)
00253     CHECK_SOUND(e1.getType().isBool() && e2.getType().isBool(),
00254     "rewriteIteBool: Not a boolean ITE: "
00255     + c.iteExpr(e1, e2).toString());
00256   Proof pf;
00257   if(withProof())
00258     pf = newPf("rewrite_ite_bool", c, e1, e2);
00259   return newRWTheorem(c.iteExpr(e1,e2),
00260           (e1.orExpr(!c).andExpr(c.orExpr(e2))), Assumptions::emptyAssump(), pf);
00261 }
00262 
00263 
00264 //! |= (A & B1) | (A & B2) | ... | (A & bn) <=> A & (B1 | B2 | ...| Bn)
00265 Theorem
00266 CoreTheoremProducer::orDistributivityRule(const Expr& e) {
00267   if(CHECK_PROOFS) {
00268     CHECK_SOUND(e.isOr() && e.arity() >= 2,
00269     "CoreTheoremProducer::orDistributivityRule: "
00270     "input must be an OR expr: \n" + e.toString());
00271     const Expr& e0 = e[0];
00272 
00273     CHECK_SOUND(e0.isAnd() && e0.arity() == 2,
00274     "CoreTheoremProducer::orDistributivityRule: "
00275     "input must be an OR of binary ANDs: \n" + e.toString());
00276   }
00277 
00278   const Expr& A = e[0][0];
00279 
00280   if(CHECK_PROOFS) {
00281     for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00282       const Expr& ei = *i;
00283       CHECK_SOUND(ei.isAnd() && ei.arity() == 2,
00284     "CoreTheoremProducer::orDistributivityRule: "
00285     "input must be an OR of binary ANDs: \n" + e.toString());
00286       CHECK_SOUND(A == ei[0],
00287       "CoreTheoremProducer::orDistributivityRule: "
00288       "input must have a common factor: \n" + e.toString());
00289     }
00290   }
00291   vector<Expr> output;
00292   for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00293     Expr ei = *i;
00294     output.push_back(ei[1]);
00295   }
00296   Expr out = A.andExpr(orExpr(output));
00297 
00298   Proof pf;
00299   if(withProof())
00300     pf = newPf("or_distribuitivity_rule", e);
00301   
00302   return newRWTheorem(e, out, Assumptions::emptyAssump(), pf);
00303 } 
00304 
00305 
00306 
00307 //! |= (A | B1) & (A | B2) & ... & (A | bn) <=> A | (B1 & B2 & ...& Bn)
00308 Theorem
00309 CoreTheoremProducer::andDistributivityRule(const Expr& e) {
00310   if(CHECK_PROOFS) {
00311     CHECK_SOUND(e.isAnd() && e.arity() >= 2,
00312     "CoreTheoremProducer::andDistributivityRule: "
00313     "input must be an AND expr: \n" + e.toString());
00314     const Expr& e0 = e[0];
00315 
00316     CHECK_SOUND(e0.isOr() && e0.arity() == 2,
00317     "CoreTheoremProducer::orDistributivityRule: "
00318     "input must be an AND of binary ORs: \n" + e.toString());
00319   }
00320 
00321   const Expr& A = e[0][0];
00322 
00323   if(CHECK_PROOFS) {
00324     for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00325       const Expr& ei = *i;
00326       CHECK_SOUND(ei.isOr() && ei.arity() == 2,
00327     "CoreTheoremProducer::andDistributivityRule: "
00328     "input must be an AND of binary ORs: \n" + e.toString());
00329       CHECK_SOUND(A == ei[0],
00330       "CoreTheoremProducer::andDistributivityRule: "
00331       "input must have a common factor: \n" + e.toString());
00332     }
00333   }
00334   vector<Expr> output;
00335   for(Expr::iterator i=e.begin(),iend=e.end();i!=iend;++i) {
00336     output.push_back((*i)[1]);
00337   }
00338   Expr out = A.orExpr(andExpr(output));
00339 
00340   Proof pf;
00341   if(withProof())
00342     pf = newPf("and_distribuitivity_rule", e);
00343   
00344   return newRWTheorem(e, out, Assumptions::emptyAssump(), pf);
00345 } 
00346 
00347 // ==> IMPLIES(e1,e2) IFF OR(!e1, e2)
00348 Theorem
00349 CoreTheoremProducer::rewriteImplies(const Expr& e) {
00350   Proof pf;
00351   if(CHECK_PROOFS)
00352     CHECK_SOUND(e.isImpl(), "rewriteImplies precondition violated");
00353   if(withProof()) {
00354     pf = newPf("rewrite_implies", e[0], e[1]);
00355   }
00356   return newRWTheorem(e, !e[0] || e[1], Assumptions::emptyAssump(), pf);
00357 }
00358 
00359 // ==> DISTINCT(e1,...,en) IFF AND 1 <= i < j <= n (e[i] /= e[j])
00360 Theorem
00361 CoreTheoremProducer::rewriteDistinct(const Expr& e) {
00362   Proof pf;
00363   if(CHECK_PROOFS) {
00364     CHECK_SOUND(e.getKind() == DISTINCT, "rewriteDistinct precondition violated");
00365     CHECK_SOUND(e.arity() > 0, "rewriteDistinct precondition violated");
00366   }
00367   if(withProof()) {
00368     pf = newPf("rewrite_distinct");
00369   }
00370   Expr res;
00371   if (e.arity() == 1) {
00372     res = e.getEM()->trueExpr();
00373   }
00374   else if (e.arity() == 2) {
00375     res = !(e[0].eqExpr(e[1]));
00376   }
00377   else {
00378     vector<Expr> tmp;
00379     for (int i = 0; i < e.arity(); ++i) {
00380       for (int j = i+1; j < e.arity(); ++j) {
00381         tmp.push_back(!(e[i].eqExpr(e[j])));
00382       }
00383     }
00384     res = Expr(AND, tmp);
00385   }
00386   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
00387 }
00388 
00389 // ==> NOT(e) == ITE(e, FALSE, TRUE)
00390 Theorem
00391 CoreTheoremProducer::NotToIte(const Expr& not_e){
00392   Proof pf;
00393   if(CHECK_PROOFS)
00394     CHECK_SOUND(not_e.isNot() && not_e[0].getType().isBool(),
00395     "NotToIte precondition violated");
00396   if(withProof())
00397     pf = newPf("NotToIte", not_e[0]);
00398   if(not_e[0].isTrue())
00399     return d_core->getCommonRules()->rewriteNotTrue(not_e);
00400   else if(not_e[0].isFalse())
00401     return d_core->getCommonRules()->rewriteNotFalse(not_e);
00402   Expr ite(not_e[0].iteExpr(d_em->falseExpr(), d_em->trueExpr()));
00403   return newRWTheorem(not_e, ite, Assumptions::emptyAssump(), pf);  
00404 }
00405 
00406 // ==> Or(e) == ITE(e[1], TRUE, e[0])
00407 Theorem
00408 CoreTheoremProducer::OrToIte(const Expr& e){
00409   if(CHECK_PROOFS)
00410     CHECK_SOUND(e.isOr(),
00411     "OrToIte: precondition violated: " + e.toString());
00412   Proof pf;
00413   if(withProof()) {
00414     pf = newPf("OrToIte", e);
00415   }
00416   const vector<Expr>& kids = e.getKids();
00417   unsigned k(kids.size());
00418   if(k==0)
00419     return newRWTheorem(e, d_em->falseExpr(), Assumptions::emptyAssump(), pf);
00420   if(k==1)
00421     return newRWTheorem(e, e[0], Assumptions::emptyAssump(), pf);
00422   Expr ite(kids[k-1]);
00423   if(CHECK_PROOFS)
00424     CHECK_SOUND(!ite.getType().isNull(),
00425     "OrToIte: kid " + int2string(k-1) + " has no type: "
00426     + (ite).toString());
00427   for (; k > 1; k--) {
00428     if (kids[k-2].isTrue()) {
00429       ite = d_em->trueExpr();
00430       break;
00431     }
00432     else if(kids[k-2].isFalse()) continue;
00433     else{
00434       if(CHECK_PROOFS)
00435   CHECK_SOUND(!kids[k-2].getType().isNull(),
00436       "OrToIte: kid " + int2string(k-2) + " has no type: "
00437       + (kids[k-2]).toString());
00438       ite = ite.iteExpr(d_em->trueExpr(), kids[k-2]);
00439     }
00440   }
00441   return newRWTheorem(e, ite, Assumptions::emptyAssump(), pf);
00442 }
00443 
00444 // ==> And(e) == ITE(e[1], e[0], FALSE)
00445 Theorem
00446 CoreTheoremProducer::AndToIte(const Expr& e){
00447   if(CHECK_PROOFS)
00448     CHECK_SOUND(e.isAnd(),
00449     "AndToIte: precondition violated: " + e.toString());
00450   Proof pf;
00451   if(withProof()) {
00452     pf = newPf("AndToIte", e);
00453   }
00454   const vector<Expr>& kids = e.getKids();
00455   unsigned k(kids.size());
00456   if(k==0)
00457     return newRWTheorem(e, d_em->trueExpr(), Assumptions::emptyAssump(), pf);
00458   if(k==1)
00459     return newRWTheorem(e, e[0], Assumptions::emptyAssump(), pf);
00460   Expr ite(kids[k-1]);
00461   if(CHECK_PROOFS)
00462     CHECK_SOUND(!ite.getType().isNull(),
00463     "AndToIte: kid " + int2string(k-1) + " has no type: "
00464     + (ite).toString());
00465   for (; k > 1; k--) {
00466     if (kids[k-2].isFalse()) {
00467       ite = d_em->falseExpr();
00468       break;
00469     }
00470     else if(kids[k-2].isTrue()) {
00471       continue;
00472     }
00473     else{
00474       if(CHECK_PROOFS)
00475   CHECK_SOUND(!kids[k-2].getType().isNull(),
00476         "AndToIte: kid " + int2string(k-2) + " has no type: "
00477         + (kids[k-2]).toString());
00478       ite = ite.iteExpr(kids[k-2], d_em->falseExpr());
00479     }
00480   }
00481   return newRWTheorem(e, ite, Assumptions::emptyAssump(), pf);
00482 }
00483 
00484 // ==> IFF(a,b) == ITE(a, b, !b)
00485 Theorem
00486 CoreTheoremProducer::IffToIte(const Expr& e){
00487   if(CHECK_PROOFS)
00488     CHECK_SOUND(e.isIff() && e[0].getType().isBool() && e[1].getType().isBool(),
00489     "IffToIte: precondition violated: " + e.toString());
00490   Proof pf;
00491   if(e[0] == e[1]) return d_core->getCommonRules()->reflexivityRule(e);
00492   Expr ite(e[0].iteExpr(e[1], e[1].iteExpr(d_em->falseExpr(),
00493              d_em->trueExpr())));
00494   if(withProof()) {
00495     pf = newPf("iff_to_ite", e);
00496   }
00497   return newRWTheorem(e, ite, Assumptions::emptyAssump(), pf); 
00498 }
00499 
00500 // ==> IMPLIES(a,b) == ITE(a, b, TRUE)
00501 Theorem
00502 CoreTheoremProducer::ImpToIte(const Expr& e){
00503   if(CHECK_PROOFS)
00504     CHECK_SOUND(e.isImpl() && e[0].getType().isBool() && e[1].getType().isBool(),
00505     "ImpToIte: precondition violated: " + e.toString());
00506   Proof pf;
00507   if(e[0] == e[1]) return d_core->getCommonRules()->reflexivityRule(e);
00508   Expr ite(e[0].iteExpr(e[1], d_em->trueExpr()));
00509   if(withProof()) {
00510     pf = newPf("imp_to_ite", e);
00511   }
00512   return newRWTheorem(e, ite, Assumptions::emptyAssump(), pf); 
00513 }
00514 
00515 
00516 // ==> ITE(e, FALSE, TRUE) IFF NOT(e)
00517 Theorem
00518 CoreTheoremProducer::rewriteIteToNot(const Expr& e)
00519 {
00520   if (CHECK_PROOFS)
00521     CHECK_SOUND(e.isITE() && e[1].isFalse() && e[2].isTrue(),
00522     "rewriteIteToNot: " + e.toString());
00523   Proof pf;
00524   if (withProof()) pf = newPf("rewrite_ite_to_not", e);
00525   return newRWTheorem(e, e[0].negate(), Assumptions::emptyAssump(), pf);
00526 }
00527 
00528 // ==> ITE(a, TRUE, b) IFF OR(a, b)
00529 Theorem
00530 CoreTheoremProducer::rewriteIteToOr(const Expr& e)
00531 {
00532   if (CHECK_PROOFS)
00533     CHECK_SOUND(e.isITE() && e[1].isTrue(),
00534     "rewriteIteToOr: " + e.toString());
00535   Proof pf;
00536   if (withProof()) pf = newPf("rewrite_ite_to_or", e);
00537   return newRWTheorem(e, e[0] || e[2], Assumptions::emptyAssump(), pf);
00538 }
00539 
00540 // ==> ITE(a, b, FALSE) IFF AND(a, b)
00541 Theorem
00542 CoreTheoremProducer::rewriteIteToAnd(const Expr& e)
00543 {
00544   if (CHECK_PROOFS)
00545     CHECK_SOUND(e.isITE() && e[2].isFalse(),
00546     "rewriteIteToAnd: " + e.toString());
00547   Proof pf;
00548   if (withProof()) pf = newPf("rewrite_ite_to_and", e);
00549   return newRWTheorem(e, e[0] && e[1], Assumptions::emptyAssump(), pf);
00550 }
00551 
00552 // ==> ITE(a, b, !b) IFF IFF(a, b)
00553 Theorem
00554 CoreTheoremProducer::rewriteIteToIff(const Expr& e)
00555 {
00556   if (CHECK_PROOFS)
00557     CHECK_SOUND(e.isITE() && e[1] == e[2].negate(),
00558     "rewriteIteToIff: " + e.toString());
00559   Proof pf;
00560   if (withProof()) pf = newPf("rewrite_ite_to_iff", e);
00561   return newRWTheorem(e, e[0].iffExpr(e[1]), Assumptions::emptyAssump(), pf);
00562 }
00563 
00564 // ==> ITE(a, b, TRUE) IFF IMPLIES(a, b)
00565 Theorem
00566 CoreTheoremProducer::rewriteIteToImp(const Expr& e)
00567 {
00568   if (CHECK_PROOFS)
00569     CHECK_SOUND(e.isITE() && e[2].isTrue(),
00570     "rewriteIteToImp: " + e.toString());
00571   Proof pf;
00572   if (withProof()) pf = newPf("rewrite_ite_to_imp", e);
00573   return newRWTheorem(e, e[0].impExpr(e[1]), Assumptions::emptyAssump(), pf);
00574 }
00575 
00576 
00577 // ==> ITE(a, b(a), c(a)) IFF ITE(a, b(TRUE), c(FALSE))
00578 Theorem
00579 CoreTheoremProducer::rewriteIteCond(const Expr& e) {
00580   if (CHECK_PROOFS)
00581     CHECK_SOUND(e.isITE() && e.arity()==3, "rewriteIteCond: " + e.toString());
00582 
00583   vector<Expr> oldTerms, newTerms;
00584   oldTerms.push_back(e[0]);
00585   newTerms.push_back(d_em->trueExpr());
00586   
00587   Expr e1(e[1].substExpr(oldTerms, newTerms));
00588   newTerms[0] = d_em->falseExpr();
00589   Expr e2(e[2].substExpr(oldTerms, newTerms));
00590 
00591   Proof pf;
00592   if (withProof()) pf = newPf("rewrite_ite_cond", e);
00593   return newRWTheorem(e, e[0].iteExpr(e1, e2), Assumptions::emptyAssump(), pf);
00594 }
00595 
00596 
00597 Theorem
00598 CoreTheoremProducer::iffOrDistrib(const Expr& iff) {
00599   if(CHECK_PROOFS) {
00600     CHECK_SOUND(iff.isIff() && iff.arity()==2, "iffOrDistrib("
00601     +iff.toString()+")");
00602     CHECK_SOUND(iff[0].isOr() && iff[0].arity()==2, "iffOrDistrib("
00603     +iff.toString()+")");
00604     CHECK_SOUND(iff[1].isOr() && iff[1].arity()==2, "iffOrDistrib("
00605     +iff.toString()+")");
00606     CHECK_SOUND(iff[0][0]==iff[1][0], "iffOrDistrib("
00607     +iff.toString()+")");
00608   }
00609   const Expr& a = iff[0][0];
00610   const Expr& b = iff[0][1];
00611   const Expr& c = iff[1][1];
00612   Proof pf;
00613   if(withProof())
00614     pf = newPf("iff_or_distrib", iff);
00615   return newRWTheorem(iff, (a || (b.iffExpr(c))), Assumptions::emptyAssump(), pf);
00616 }
00617 
00618 
00619 Theorem
00620 CoreTheoremProducer::iffAndDistrib(const Expr& iff) {
00621   if(CHECK_PROOFS) {
00622     CHECK_SOUND(iff.isIff() && iff.arity()==2, "iffAndDistrib("
00623     +iff.toString()+")");
00624     CHECK_SOUND(iff[0].isAnd() && iff[0].arity()==2, "iffAndDistrib("
00625     +iff.toString()+")");
00626     CHECK_SOUND(iff[1].isAnd() && iff[1].arity()==2, "iffAndDistrib("
00627     +iff.toString()+")");
00628     CHECK_SOUND(iff[0][0]==iff[1][0], "iffOrDistrib("
00629     +iff.toString()+")");
00630   }
00631   const Expr& a = iff[0][0];
00632   const Expr& b = iff[0][1];
00633   const Expr& c = iff[1][1];
00634   Proof pf;
00635   if(withProof())
00636     pf = newPf("iff_and_distrib", iff);
00637   return newRWTheorem(iff, (!a || (b.iffExpr(c))), Assumptions::emptyAssump(), pf);
00638 }
00639 
00640 
00641 // |- op(ITE(cond,a,b)) =/<=> ITE(cond,op(a),op(b))
00642 Theorem
00643 CoreTheoremProducer::ifLiftUnaryRule(const Expr& e) {
00644   if(CHECK_PROOFS) {
00645     CHECK_SOUND(e.arity()==1 && e[0].isITE(),
00646     "CoreTheoremProducer::ifLiftUnaryRule("
00647     "e = " + e.toString() + ")");
00648   }
00649   Op op(e.getOp());
00650   const Expr& ite = e[0];
00651   const Expr& cond = ite[0];
00652   const Expr& t1 = ite[1];
00653   const Expr& t2 = ite[2];
00654 
00655   if(CHECK_PROOFS) {
00656     CHECK_SOUND(cond.getType().isBool(),
00657     "CoreTheoremProducer::ifLiftUnaryRule("
00658     "e = " + e.toString()+")");      
00659   }    
00660 
00661   Expr e1 =  Expr(op, t1);
00662   Expr e2 =  Expr(op, t2);
00663 
00664   Expr resultITE = cond.iteExpr(e1, e2);
00665 
00666   Proof pf;
00667   if (withProof())
00668     pf = newPf("if_lift_unary_rule", e);
00669   return newRWTheorem(e, resultITE, Assumptions::emptyAssump(), pf);
00670 }
00671 
00672 
00673 // (a & b) <=> a & b[a/true]; takes the index of a and rewrites all
00674 // the other conjuncts.
00675 Theorem
00676 CoreTheoremProducer::rewriteAndSubterms(const Expr& e, int idx) {
00677   if(CHECK_PROOFS) {
00678     CHECK_SOUND(e.isAnd() && 0 <= idx && idx < e.arity(),
00679     "rewriteAndSubterms("+e.toString()
00680     +", idx="+int2string(idx)
00681     +"):\n Expected an AND and a valid index of a child");
00682   }
00683   vector<Expr> kids;
00684   ExprHashMap<Expr> subst;
00685   subst.insert(e[idx], d_em->trueExpr());
00686   for(int i=0, iend=e.arity(); i<iend; ++i) {
00687     if(i==idx)
00688       kids.push_back(e[i]);
00689     else
00690       kids.push_back(e[i].substExpr(subst));
00691   }
00692   Proof pf;
00693   if(withProof())
00694     pf = newPf("rewrite_and_subterms", e, d_em->newRatExpr(idx));
00695   return newRWTheorem(e, Expr(e.getOp(), kids), Assumptions::emptyAssump(), pf);
00696 }
00697 
00698 
00699 // (a | b) <=> a | b[a/false]; takes the index of a and rewrites all
00700 // the other disjuncts.
00701 Theorem
00702 CoreTheoremProducer::rewriteOrSubterms(const Expr& e, int idx) {
00703   if(CHECK_PROOFS) {
00704     CHECK_SOUND(e.isOr() && 0 <= idx && idx < e.arity(),
00705     "rewriteOrSubterms("+e.toString()
00706     +", idx="+int2string(idx)
00707     +"):\n Expected an OR and a valid index of a child");
00708   }
00709   vector<Expr> kids;
00710   ExprHashMap<Expr> subst;
00711   subst.insert(e[idx], d_em->falseExpr());
00712   for(int i=0, iend=e.arity(); i<iend; ++i) {
00713     if(i==idx)
00714       kids.push_back(e[i]);
00715     else
00716       kids.push_back(e[i].substExpr(subst));
00717   }
00718   Proof pf;
00719   if(withProof())
00720     pf = newPf("rewrite_or_subterms", e, d_em->newRatExpr(idx));
00721   return newRWTheorem(e, Expr(e.getOp(), kids), Assumptions::emptyAssump(), pf);
00722 }

Generated on Tue Jul 3 14:33:36 2007 for CVC3 by  doxygen 1.5.1