00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
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 
00045 CoreProofRules* TheoryCore::createProofRules(TheoremManager* tm) {
00046   return new CoreTheoremProducer(tm, this);
00047 }
00048 
00049 
00050 
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()) 
00070     pf = newPf("rewrite_letdecl", e[1]);
00071   return newRWTheorem(e, e[1], Assumptions::emptyAssump(), pf);
00072 }
00073 
00074 
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; 
00082   for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00083     
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 
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; 
00098   for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00099     
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
00674 
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 
00700 
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 }