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 #define _CVCL_TRUSTED_
00033
00034
00035 #include "common_theorem_producer.h"
00036
00037
00038 using namespace CVCL;
00039 using namespace std;
00040
00041
00042
00043 CommonProofRules* TheoremManager::createProofRules() {
00044 return new CommonTheoremProducer(this);
00045 }
00046
00047
00048 CommonTheoremProducer::CommonTheoremProducer(TheoremManager* tm)
00049 : TheoremProducer(tm),
00050 d_skolemized_thms(tm->getCM()->getCurrentContext()),
00051 d_skolemVars(tm->getCM()->getCurrentContext())
00052 {}
00053
00054
00055 Theorem CommonTheoremProducer::assumpRule(const Expr& e, int scope) {
00056 TRACE("assump", "assumpRule(", e, ")");
00057 Proof pf;
00058 if(withProof()) pf = newLabel(e);
00059 return newAssumption(e, pf, scope);
00060 }
00061
00062
00063 Theorem CommonTheoremProducer::reflexivityRule(const Expr& a) {
00064 Proof pf;
00065 if(withProof()) {
00066 Type t = a.getType();
00067 if(CHECK_PROOFS)
00068 CHECK_SOUND(!t.isNull(),
00069 "reflexivityRule: 'a' has no type: " + a.toString());
00070 bool useIff = (t.isBool());
00071 pf = newPf(useIff? "iff_refl" : "eq_refl", t.getExpr(), a);
00072 }
00073 return newReflTheorem(a, pf);
00074 }
00075
00076
00077
00078 Theorem CommonTheoremProducer::rewriteReflexivity(const Expr& t) {
00079 if(CHECK_PROOFS)
00080 CHECK_SOUND((t.isEq() || t.isIff()) && t[0] == t[1],
00081 "rewriteReflexivity: wrong expression: "
00082 + t.toString());
00083 Assumptions a;
00084 Proof pf;
00085 if(withProof()) {
00086 if(t.isEq()) {
00087 DebugAssert(!t[0].getType().isNull(),
00088 "rewriteReflexivity: t[0] has no type: "
00089 + t[0].toString());
00090 pf = newPf("rewrite_eq_refl", t[0].getType().getExpr(), t[0]);
00091 } else
00092 pf = newPf("rewrite_iff_refl", t[0]);
00093 }
00094 return newRWTheorem(t, d_em->trueExpr(), a, pf);
00095 }
00096
00097
00098 Theorem CommonTheoremProducer::symmetryRule(const Theorem& a1_eq_a2) {
00099 if(CHECK_PROOFS)
00100 CHECK_SOUND(a1_eq_a2.isRewrite(),
00101 ("CVCL::CommonTheoremProducer: "
00102 "theorem is not an equality or iff:\n "
00103 + a1_eq_a2.getExpr().toString()).c_str());
00104 const Expr& a1 = a1_eq_a2.getLHS();
00105 const Expr& a2 = a1_eq_a2.getRHS();
00106
00107 Proof pf;
00108 Assumptions a;
00109
00110
00111
00112
00113 if(a1 == a2) return reflexivityRule(a1);
00114
00115 if (withAssumptions()) a = a1_eq_a2.getAssumptionsCopy();
00116 if(withProof()) {
00117 Type t = a1.getType();
00118
00119 IF_DEBUG(a1_eq_a2.getExpr().getType());
00120 bool isEquality = !t.isBool();
00121 if(isEquality) {
00122 vector<Expr> args;
00123 args.push_back(t.getExpr());
00124 args.push_back(a1);
00125 args.push_back(a2);
00126 pf = newPf("eq_symm", args, a1_eq_a2.getProof());
00127 } else
00128 pf = newPf("iff_symm", a1, a2, a1_eq_a2.getProof());
00129 }
00130 return newRWTheorem(a2, a1, a, pf);
00131 }
00132
00133
00134 Theorem CommonTheoremProducer::rewriteUsingSymmetry(const Expr& a1_eq_a2) {
00135 bool isIff = a1_eq_a2.isIff();
00136 if(CHECK_PROOFS)
00137 CHECK_SOUND(a1_eq_a2.isEq() || isIff, "rewriteUsingSymmetry precondition violated");
00138 const Expr& a1 = a1_eq_a2[0];
00139 const Expr& a2 = a1_eq_a2[1];
00140
00141 if(a1 == a2) return reflexivityRule(a1_eq_a2);
00142
00143 Assumptions assump;
00144 Proof pf;
00145 if(withProof()) {
00146 Type t = a1.getType();
00147 DebugAssert(!t.isNull(),
00148 "rewriteUsingSymmetry: a1 has no type: " + a1.toString());
00149 if(isIff)
00150 pf = newPf("rewrite_iff_symm", a1, a2);
00151 else {
00152 pf = newPf("rewrite_eq_symm", t.getExpr(), a1, a2);
00153 }
00154 }
00155 return newRWTheorem(a1_eq_a2, isIff ? a2.iffExpr(a1) : a2.eqExpr(a1), assump, pf);
00156 }
00157
00158
00159 Theorem CommonTheoremProducer::transitivityRule(const Theorem& a1_eq_a2,
00160 const Theorem& a2_eq_a3) {
00161 DebugAssert(!a1_eq_a2.isNull(), "transitivityRule()");
00162 DebugAssert(!a2_eq_a3.isNull(), "transitivityRule()");
00163 if(CHECK_PROOFS) {
00164 CHECK_SOUND(a1_eq_a2.isRewrite() && a2_eq_a3.isRewrite(),
00165 "CVCL::CommonTheoremProducer::transitivityRule:\n "
00166 "Wrong premises: first = "
00167 + a1_eq_a2.getExpr().toString() + ", second = "
00168 + a2_eq_a3.getExpr().toString());
00169 CHECK_SOUND(a1_eq_a2.getRHS() == a2_eq_a3.getLHS(),
00170 "CVCL::CommonTheoremProducer::transitivityRule:\n "
00171 "Wrong premises: first = "
00172 + a1_eq_a2.getExpr().toString() + ", second = "
00173 + a2_eq_a3.getExpr().toString());
00174 }
00175 const Expr& a1 = a1_eq_a2.getLHS();
00176 const Expr& a2 = a1_eq_a2.getRHS();
00177 const Expr& a3 = a2_eq_a3.getRHS();
00178
00179
00180
00181
00182
00183 if(a1 == a3) return reflexivityRule(a1);
00184
00185 if(a1 == a2) return a2_eq_a3;
00186 if(a2 == a3) return a1_eq_a2;
00187
00188
00189
00190
00191
00192 Assumptions a;
00193 Proof pf;
00194
00195 if(withAssumptions())
00196 a = merge(a1_eq_a2, a2_eq_a3);
00197
00198 if(withProof()) {
00199 Type t = a1.getType();
00200 bool isEquality = (!t.isBool());
00201 string name((isEquality)? "eq_trans" : "iff_trans");
00202 vector<Expr> args;
00203 vector<Proof> pfs;
00204 DebugAssert(!t.isNull(), "transitivityRule: "
00205 "Type is not computed for a1: " + a1.toString());
00206
00207 if(isEquality) args.push_back(t.getExpr());
00208 args.push_back(a1);
00209 args.push_back(a2);
00210 args.push_back(a3);
00211 pfs.push_back(a1_eq_a2.getProof());
00212 pfs.push_back(a2_eq_a3.getProof());
00213 pf = newPf(name, args, pfs);
00214 }
00215 return newRWTheorem(a1, a3, a, pf);
00216 }
00217
00218
00219 Theorem CommonTheoremProducer::substitutivityRule(const Op& op,
00220 const vector<Theorem>& thms) {
00221 IF_DEBUG
00222 (static DebugTimer
00223 accum0(debugger.timer("substitutivityRule time"));
00224 static DebugTimer tmpTimer(debugger.newTimer());
00225 static DebugCounter count(debugger.counter("substitutivityRule calls"));
00226 debugger.setCurrentTime(tmpTimer);
00227 count++);
00228
00229 unsigned size(thms.size());
00230 if(size == 0)
00231 return reflexivityRule(d_tm->getEM()->newLeafExpr(op));
00232
00233
00234 vector<Expr> c, d;
00235 vector<Proof> pfs;
00236
00237
00238 c.reserve(size); d.reserve(size);
00239 for(vector<Theorem>::const_iterator i = thms.begin(), iend = thms.end();
00240 i != iend; ++i) {
00241
00242 if(CHECK_PROOFS)
00243 CHECK_SOUND(i->isRewrite(),
00244 "CVCL::CommonTheoremProducer::substitutivityRule:\n "
00245 "premis is not an equality or IFF: "
00246 + i->getExpr().toString()
00247 + "\n op = " + op.toString());
00248
00249 c.push_back(i->getLHS());
00250 d.push_back(i->getRHS());
00251 if(withProof()) pfs.push_back(i->getProof());
00252 }
00253 Expr e1(op, c), e2(op, d);
00254
00255 if(e1 == e2) return reflexivityRule(e1);
00256
00257 Assumptions a;
00258 Proof pf;
00259 if(withAssumptions()) a = merge(thms);
00260 if(withProof())
00261
00262 pf = newPf("basic_subst_op",e1,e2,pfs);
00263 Theorem res = newRWTheorem(e1, e2, a, pf);
00264 IF_DEBUG(debugger.setElapsed(tmpTimer);
00265 accum0 += tmpTimer);
00266 return res;
00267 }
00268
00269
00270 Theorem CommonTheoremProducer::substitutivityRule(const Expr& e,
00271 const vector<unsigned>& changed,
00272 const vector<Theorem>& thms) {
00273 IF_DEBUG
00274 (static DebugTimer
00275 accum0(debugger.timer("substitutivityRule2 time"));
00276 static DebugTimer tmpTimer(debugger.newTimer());
00277 static DebugCounter count(debugger.counter("substitutivityRule2 calls"));
00278 debugger.setCurrentTime(tmpTimer);
00279 count++);
00280 unsigned csize = changed.size();
00281 DebugAssert(csize > 0, "substitutivityRule2 should not be called");
00282 DebugAssert(csize == thms.size(), "substitutivityRule2: wrong args");
00283
00284
00285
00286 unsigned size = e.arity();
00287 DebugAssert(size >= csize, "Bad call to substitutivityRule2");
00288 vector<Expr> c;
00289 bool checkProofs(CHECK_PROOFS);
00290 for(unsigned j = 0, k = 0; k < size; ++k) {
00291 if (j == csize || changed[j] != k) {
00292 c.push_back(e[k]);
00293 continue;
00294 }
00295
00296 if(checkProofs)
00297 CHECK_SOUND(thms[j].isRewrite() && thms[j].getLHS() == e[k],
00298 "CVCL::CommonTheoremProducer::substitutivityRule:\n "
00299 "premis is not an equality or IFF: "
00300 + thms[j].getExpr().toString()
00301 + "\n e = " + e.toString());
00302
00303 c.push_back(thms[j].getRHS());
00304 ++j;
00305 }
00306 Expr e2(e.getOp(), c);
00307 IF_DEBUG(if(e == e2) {
00308 ostream& os = debugger.getOS();
00309 os << "substitutivityRule2: e = " << e << "\n e2 = " << e2
00310 << "\n changed kids: [\n";
00311 for(unsigned j=0; j<changed.size(); j++)
00312 os << " (" << changed[j] << ") " << thms[j] << "\n";
00313 os << "]\n";
00314 });
00315 DebugAssert(e != e2,
00316 "substitutivityRule2 should not be called in this case:\n"
00317 "e = "+e.toString());
00318
00319 Assumptions a;
00320 Proof pf;
00321 if(withAssumptions()) a = merge(thms);
00322 vector<Proof> pfs;
00323 if(withProof())
00324 for(vector<Theorem>::const_iterator i = thms.begin(), iend = thms.end();
00325 i != iend; ++i) {
00326
00327 if(CHECK_PROOFS)
00328 CHECK_SOUND(i->isRewrite(),
00329 "CVCL::CommonTheoremProducer::substitutivityRule:\n "
00330 "premis is not an equality or IFF: "
00331 + i->getExpr().toString());
00332
00333 pfs.push_back(i->getProof());
00334 pf = newPf("optimized_subst_op",e,e2,pfs);
00335 }
00336 Theorem res = newRWTheorem(e, e2, a, pf);
00337 IF_DEBUG(debugger.setElapsed(tmpTimer);
00338 accum0 += tmpTimer);
00339 return res;
00340 }
00341
00342
00343
00344 Theorem CommonTheoremProducer::contradictionRule(const Theorem& e,
00345 const Theorem& not_e) {
00346 Assumptions a;
00347 Proof pf;
00348 if(CHECK_PROOFS)
00349 CHECK_SOUND(!e.getExpr() == not_e.getExpr(),
00350 "CommonTheoremProducer::contraditionRule: "
00351 "theorems don't match:\n e = "+e.toString()
00352 +"\n not_e = "+not_e.toString());
00353 if(withAssumptions()) a = merge(e, not_e);
00354 if(withProof()) {
00355 vector<Proof> pfs;
00356 pfs.push_back(e.getProof());
00357 pfs.push_back(not_e.getProof());
00358 pf = newPf("contradition", e.getExpr(), pfs);
00359 }
00360 return newTheorem(d_em->falseExpr(), a, pf);
00361 }
00362
00363
00364
00365 Theorem CommonTheoremProducer::iffTrue(const Theorem& e)
00366 {
00367 Assumptions a;
00368 Proof pf;
00369 if (withAssumptions()) a = e.getAssumptions().copy();
00370 if(withProof()) {
00371 pf = newPf("iff_true", e.getExpr(), e.getProof());
00372 }
00373 return newRWTheorem(e.getExpr(), d_em->trueExpr(), a, pf);
00374 }
00375
00376
00377
00378 Theorem CommonTheoremProducer::iffNotFalse(const Theorem& e) {
00379 Assumptions a;
00380 Proof pf;
00381 if (withAssumptions()) a = e.getAssumptions().copy();
00382 if(withProof()) {
00383 pf = newPf("iff_not_false", e.getExpr(), e.getProof());
00384 }
00385 return newRWTheorem(!e.getExpr(), d_em->falseExpr(), a, pf);
00386 }
00387
00388
00389
00390 Theorem CommonTheoremProducer::iffTrueElim(const Theorem& e) {
00391 if(CHECK_PROOFS)
00392 CHECK_SOUND(e.isRewrite() && e.getRHS().isTrue(),
00393 "CommonTheoremProducer::iffTrueElim: "
00394 "theorem is not e<=>TRUE: "+ e.toString());
00395 Assumptions a;
00396 Proof pf;
00397 if (withAssumptions()) a = e.getAssumptions().copy();
00398 if(withProof()) {
00399 pf = newPf("iff_true_elim", e.getLHS(), e.getProof());
00400 }
00401 return newTheorem(e.getLHS(), a, pf);
00402 }
00403
00404
00405
00406 Theorem CommonTheoremProducer::iffFalseElim(const Theorem& e) {
00407 if(CHECK_PROOFS)
00408 CHECK_SOUND(e.isRewrite() && e.getRHS().isFalse(),
00409 "CommonTheoremProducer::iffFalseElim: "
00410 "theorem is not e<=>FALSE: "+ e.toString());
00411 const Expr& lhs = e.getLHS();
00412 Assumptions a;
00413 Proof pf;
00414 if (withAssumptions()) a = e.getAssumptions().copy();
00415 if(withProof()) {
00416 pf = newPf("iff_false_elim", lhs, e.getProof());
00417 }
00418 return newTheorem(!lhs, a, pf);
00419 }
00420
00421
00422
00423 Theorem CommonTheoremProducer::iffContrapositive(const Theorem& e) {
00424 if(CHECK_PROOFS)
00425 CHECK_SOUND(e.isRewrite() && e.getRHS().getType().isBool(),
00426 "CommonTheoremProducer::iffContrapositive: "
00427 "theorem is not e1<=>e2: "+ e.toString());
00428 Assumptions a;
00429 Proof pf;
00430 if (withAssumptions()) a = e.getAssumptions().copy();
00431 if(withProof()) {
00432 pf = newPf("iff_contrapositive", e.getExpr(), e.getProof());
00433 }
00434 return newRWTheorem(e.getLHS().negate(),e.getRHS().negate(), a, pf);
00435 }
00436
00437
00438
00439 Theorem CommonTheoremProducer::notNotElim(const Theorem& not_not_e) {
00440 if(CHECK_PROOFS)
00441 CHECK_SOUND(not_not_e.getExpr().isNot() && not_not_e.getExpr()[0].isNot(),
00442 "CommonTheoremProducer::notNotElim: bad theorem: !!e = "
00443 + not_not_e.toString());
00444 Assumptions a;
00445 Proof pf;
00446 if(withAssumptions()) a = not_not_e.getAssumptionsCopy();
00447 if(withProof())
00448 pf = newPf("not_not_elim", not_not_e.getExpr(), not_not_e.getProof());
00449 return newTheorem(not_not_e.getExpr()[0][0], a, pf);
00450 }
00451
00452
00453 Theorem CommonTheoremProducer::iffMP(const Theorem& e1, const Theorem& e1_iff_e2)
00454 {
00455 if(CHECK_PROOFS) {
00456 CHECK_SOUND(e1_iff_e2.isRewrite(),
00457 "iffMP: not IFF: "+e1_iff_e2.toString());
00458 CHECK_SOUND(e1.getExpr() == (e1_iff_e2.getLHS()),
00459 "iffMP: theorems don't match:\n e1 = " + e1.toString()
00460 + ", e1_iff_e2 = " + e1_iff_e2.toString());
00461 }
00462 const Expr& e2(e1_iff_e2.getRHS());
00463
00464 if (e1_iff_e2.getLHS() == e2) return e1;
00465 Assumptions a;
00466 Proof pf;
00467 if(withAssumptions()) a = merge(e1, e1_iff_e2);
00468 if(withProof()) {
00469 vector<Proof> pfs;
00470 pfs.push_back(e1.getProof());
00471 pfs.push_back(e1_iff_e2.getProof());
00472 pf = newPf("iff_mp", e1.getExpr(), e2, pfs);
00473 }
00474 return newTheorem(e2, a, pf);
00475 }
00476
00477
00478
00479 Theorem CommonTheoremProducer::implMP(const Theorem& e1,
00480 const Theorem& e1_impl_e2) {
00481 const Expr& impl = e1_impl_e2.getExpr();
00482 if(CHECK_PROOFS) {
00483 CHECK_SOUND(impl.isImpl() && impl.arity()==2,
00484 "implMP: not IMPLIES: "+impl.toString());
00485 CHECK_SOUND(e1.getExpr() == impl[0],
00486 "implMP: theorems don't match:\n e1 = " + e1.toString()
00487 + ", e1_impl_e2 = " + impl.toString());
00488 }
00489 const Expr& e2 = impl[1];
00490
00491 if (impl[0] == e2) return e1;
00492 Assumptions a;
00493 Proof pf;
00494 if(withAssumptions()) a = merge(e1, e1_impl_e2);
00495 if(withProof()) {
00496 vector<Proof> pfs;
00497 pfs.push_back(e1.getProof());
00498 pfs.push_back(e1_impl_e2.getProof());
00499 pf = newPf("impl_mp", e1.getExpr(), e2, pfs);
00500 }
00501 return newTheorem(e2, a, pf);
00502 }
00503
00504
00505
00506 Theorem CommonTheoremProducer::andElim(const Theorem& e, int i) {
00507 if(CHECK_PROOFS) {
00508 CHECK_SOUND(e.getExpr().isAnd(), "andElim: not an AND: " + e.toString());
00509 CHECK_SOUND(i < e.getExpr().arity(), "andElim: i = " + int2string(i)
00510 + " >= arity = " + int2string(e.getExpr().arity())
00511 + " in " + e.toString());
00512 }
00513 Assumptions a;
00514 Proof pf;
00515 if(withAssumptions())
00516 a = e.getAssumptions().copy();
00517 if(withProof())
00518 pf = newPf("andE", d_em->newRatExpr(i), e.getExpr(), e.getProof());
00519 return newTheorem(e.getExpr()[i], a, pf);
00520 }
00521
00522
00523
00524 Theorem CommonTheoremProducer::andIntro(const Theorem& e1, const Theorem& e2) {
00525 vector<Theorem> thms;
00526 thms.push_back(e1);
00527 thms.push_back(e2);
00528 return andIntro(thms);
00529 }
00530
00531
00532 Theorem CommonTheoremProducer::andIntro(const vector<Theorem>& es) {
00533 Assumptions a;
00534 Proof pf;
00535 if(CHECK_PROOFS)
00536 CHECK_SOUND(es.size() > 0,
00537 "andIntro(vector<Theorem>): vector must be non-empty");
00538 if(withAssumptions()) {
00539 a = merge(es);
00540 }
00541 if(withProof()) {
00542 vector<Proof> pfs;
00543 for(vector<Theorem>::const_iterator i=es.begin(), iend=es.end();
00544 i!=iend; ++i)
00545 pfs.push_back(i->getProof());
00546 pf = newPf("andI", pfs);
00547 }
00548 vector<Expr> kids;
00549 for(vector<Theorem>::const_iterator i=es.begin(), iend=es.end();
00550 i!=iend; ++i)
00551 kids.push_back(i->getExpr());
00552 return newTheorem(andExpr(kids), a, pf);
00553 }
00554
00555
00556
00557
00558
00559 Theorem CommonTheoremProducer::implIntro(const Theorem& phi,
00560 const std::vector<Expr>& assump) {
00561 bool checkProofs(CHECK_PROOFS);
00562
00563 if(checkProofs) {
00564 CHECK_SOUND(withAssumptions(),
00565 "implIntro: called while running without assumptions");
00566 }
00567
00568 const Assumptions& phiAssump = phi.getAssumptionsRef();
00569
00570 if(checkProofs) {
00571 for(size_t i=0; i<assump.size(); i++) {
00572 const Theorem& thm = phiAssump[assump[i]];
00573 CHECK_SOUND(!thm.isNull() && thm.isAssump(),
00574 "implIntro: this is not an assumption of phi:\n\n"
00575 " a["+int2string(i)+"] = "+assump[i].toString()
00576 +"\n\n phi = "+phi.getExpr().toString());
00577 }
00578 }
00579
00580
00581 if(assump.size() == 0) return phi;
00582
00583 Assumptions a(phiAssump - assump);
00584 Proof pf;
00585 if(withProof()) {
00586 vector<Proof> u;
00587 for(vector<Expr>::const_iterator i=assump.begin(), iend=assump.end();
00588 i!=iend; ++i) {
00589 const Theorem& t = phiAssump[*i];
00590 u.push_back(t.getProof());
00591 }
00592
00593
00594
00595 vector<Expr> args;
00596 vector<Proof> pfs;
00597 args.push_back(phi.getExpr());
00598 args.insert(args.end(), assump.begin(), assump.end());
00599
00600 pfs.push_back(newPf(u, assump, phi.getProof()));
00601 pf = newPf("impl_intro", args, pfs);
00602 }
00603 Expr conj(andExpr(assump));
00604 return newTheorem(conj.impExpr(phi.getExpr()), a, pf);
00605 }
00606
00607
00608
00609 Theorem CommonTheoremProducer::implContrapositive(const Theorem& thm) {
00610 const Expr& impl = thm.getExpr();
00611 if(CHECK_PROOFS) {
00612 CHECK_SOUND(impl.isImpl() && impl.arity()==2,
00613 "CommonTheoremProducer::implContrapositive: thm="
00614 +impl.toString());
00615 }
00616 Assumptions a;
00617 Proof pf;
00618 if(withAssumptions()) a = thm.getAssumptionsCopy();
00619 if(withProof())
00620 pf = newPf("impl_contrapositive", impl, thm.getProof());
00621 return newTheorem(impl[1].negate().impExpr(impl[0].negate()), a, pf);
00622 }
00623
00624
00625
00626 Theorem CommonTheoremProducer::notToIff(const Theorem& not_e)
00627 {
00628 if(CHECK_PROOFS)
00629 CHECK_SOUND(not_e.getExpr().isNot(),
00630 "notToIff: not NOT: "+not_e.toString());
00631
00632
00633 Expr e(not_e.getExpr()[0]);
00634 Assumptions a;
00635 Proof pf;
00636 if(withAssumptions()) a = not_e.getAssumptions().copy();
00637 if(withProof())
00638 pf=newPf("not_to_iff", e, not_e.getProof());
00639 return newRWTheorem(e, d_em->falseExpr(), a, pf);
00640 }
00641
00642
00643
00644 Theorem CommonTheoremProducer::rewriteIff(const Expr& e) {
00645 Assumptions a;
00646 Proof pf;
00647 if(CHECK_PROOFS)
00648 CHECK_SOUND(e.isIff(), "rewriteIff precondition violated");
00649 if(withProof()) {
00650 pf = newPf("rewrite_iff", e[0], e[1]);
00651 }
00652
00653 if(e[0] == e[1]) return rewriteReflexivity(e);
00654
00655 switch(e[0].getKind()) {
00656 case TRUE:
00657 return newRWTheorem(e, e[1], a, pf);
00658 case FALSE:
00659 return newRWTheorem(e, !e[1], a ,pf);
00660 case NOT:
00661 if(e[0][0]==e[1])
00662 return newRWTheorem(e, d_em->falseExpr(), a, pf);
00663 break;
00664 default: break;
00665 }
00666
00667 switch(e[1].getKind()) {
00668 case TRUE:
00669 return newRWTheorem(e, e[0], a, pf);
00670 case FALSE:
00671 return newRWTheorem(e, !e[0], a, pf);
00672 case NOT:
00673 if(e[0]==e[1][0])
00674 return newRWTheorem(e, d_em->falseExpr(), a, pf);
00675 break;
00676 default:
00677 break;
00678 }
00679
00680 if(e[0] < e[1])
00681 return rewriteUsingSymmetry(e);
00682 else
00683 return reflexivityRule(e);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693 Theorem CommonTheoremProducer::rewriteAnd(const Expr& e) {
00694 if(CHECK_PROOFS)
00695 CHECK_SOUND(e.isAnd(), "rewriteAnd: bad Expr: " + e.toString());
00696 Assumptions a;
00697 Proof pf;
00698 ExprMap<bool> newKids;
00699 bool isFalse (false);
00700 for (Expr::iterator k=e.begin(), kend=e.end(); !isFalse && k != kend; ++k) {
00701 const Expr& ek = *k;
00702 if (ek.isFalse()) { isFalse=true; break; }
00703 if (ek.isAnd()) {
00704 for(Expr::iterator j=ek.begin(), jend=ek.end(); j!=jend; ++j) {
00705 if(newKids.count(j->negate()) > 0) { isFalse=true; break; }
00706 newKids[*j]=true;
00707 }
00708 } else if(!ek.isTrue()) {
00709 if(newKids.count(ek.negate()) > 0) { isFalse=true; break; }
00710 newKids[ek]=true;
00711 }
00712 }
00713 Expr res;
00714 if (isFalse) res = d_em->falseExpr();
00715 else if (newKids.size() == 0) res = d_em->trueExpr();
00716 else if (newKids.size() == 1)
00717 res = newKids.begin()->first;
00718 else {
00719 vector<Expr> v;
00720 for(ExprMap<bool>::iterator i=newKids.begin(), iend=newKids.end();
00721 i!=iend; ++i)
00722 v.push_back(i->first);
00723 res = andExpr(v);
00724 }
00725 if(withProof()) {
00726 pf = newPf("rewrite_and", e,res);
00727 }
00728 return newRWTheorem(e, res, a, pf);
00729 }
00730
00731
00732
00733 Theorem CommonTheoremProducer::rewriteOr(const Expr& e) {
00734 if(CHECK_PROOFS)
00735 CHECK_SOUND(e.isOr(), "rewriteOr: bad Expr: " + e.toString());
00736 Assumptions a;
00737 Proof pf;
00738 ExprMap<bool> newKids;
00739 bool isTrue (false);
00740 for (Expr::iterator k=e.begin(), kend=e.end(); !isTrue && k != kend; ++k) {
00741 const Expr& ek = *k;
00742 if (ek.isTrue()) { isTrue=true; break; }
00743 else if (ek.isOr()) {
00744 for(Expr::iterator j=ek.begin(), jend=ek.end(); j!=jend; ++j) {
00745 if(newKids.count(j->negate()) > 0) { isTrue=true; break; }
00746 newKids[*j]=true;
00747 }
00748 } else if(!ek.isFalse()) {
00749 if(newKids.count(ek.negate()) > 0) { isTrue=true; break; }
00750 newKids[ek]=true;
00751 }
00752 }
00753 Expr res;
00754 if (isTrue) res = d_em->trueExpr();
00755 else if (newKids.size() == 0) res = d_em->falseExpr();
00756 else if (newKids.size() == 1) res = newKids.begin()->first;
00757 else {
00758 vector<Expr> v;
00759 for(ExprMap<bool>::iterator i=newKids.begin(), iend=newKids.end();
00760 i!=iend; ++i)
00761 v.push_back(i->first);
00762 res = orExpr(v);
00763 }
00764 if(withProof()) {
00765 pf = newPf("rewrite_or", e, res);
00766 }
00767 return newRWTheorem(e, res, a, pf);
00768 }
00769
00770
00771
00772 Theorem CommonTheoremProducer::rewriteNotTrue(const Expr& e) {
00773 Assumptions a;
00774 Proof pf;
00775 if(CHECK_PROOFS)
00776 CHECK_SOUND(e.isNot() && e[0].isTrue(),
00777 "rewriteNotTrue precondition violated");
00778 if(withProof())
00779 pf = newPf("rewrite_not_true");
00780 return newRWTheorem(e, d_em->falseExpr(), a, pf);
00781 }
00782
00783
00784
00785 Theorem CommonTheoremProducer::rewriteNotFalse(const Expr& e) {
00786 Assumptions a;
00787 Proof pf;
00788 if(CHECK_PROOFS)
00789 CHECK_SOUND(e.isNot() && e[0].isFalse(),
00790 "rewriteNotFalse precondition violated");
00791 if(withProof())
00792 pf = newPf("rewrite_not_false");
00793 return newRWTheorem(e, d_em->trueExpr(), a, pf);
00794 }
00795
00796
00797
00798 Theorem CommonTheoremProducer::rewriteNotNot(const Expr& e) {
00799 Assumptions a;
00800 Proof pf;
00801 if(CHECK_PROOFS)
00802 CHECK_SOUND(e.isNot() && e[0].isNot(),
00803 "rewriteNotNot precondition violated");
00804 if(withProof())
00805 pf = newPf("rewrite_not_not", e[0][0]);
00806 return newRWTheorem(e, e[0][0], a, pf);
00807 }
00808
00809
00810
00811 Theorem CommonTheoremProducer::rewriteNotForall(const Expr& e) {
00812 if(CHECK_PROOFS) {
00813 CHECK_SOUND(e.isNot() && e[0].isForall(),
00814 "rewriteNotForall: expr must be NOT FORALL:\n"
00815 +e.toString());
00816 }
00817 Assumptions a;
00818 Proof pf;
00819 if(withProof())
00820 pf = newPf("rewrite_not_forall", e);
00821 return newRWTheorem(e, d_em->newClosureExpr(EXISTS, e[0].getVars(),
00822 !e[0].getBody()), a, pf);
00823 }
00824
00825
00826
00827 Theorem CommonTheoremProducer::rewriteNotExists(const Expr& e) {
00828 if(CHECK_PROOFS) {
00829 CHECK_SOUND(e.isNot() && e[0].isExists(),
00830 "rewriteNotExists: expr must be NOT FORALL:\n"
00831 +e.toString());
00832 }
00833 Assumptions a;
00834 Proof pf;
00835 if(withProof())
00836 pf = newPf("rewrite_not_exists", e);
00837 return newRWTheorem(e, d_em->newClosureExpr(FORALL, e[0].getVars(),
00838 !e[0].getBody()), a, pf);
00839 }
00840
00841
00842 Expr CommonTheoremProducer::skolemize(const Expr& e)
00843 {
00844 vector<Expr> vars;
00845 const vector<Expr>& boundVars = e.getVars();
00846 for(unsigned int i=0; i<boundVars.size(); i++) {
00847 Expr skolV(e.skolemExpr(i));
00848 Type tp(e.getVars()[i].getType());
00849 skolV.setType(tp);
00850 vars.push_back(skolV);
00851 }
00852 return(e.getBody().substExpr(boundVars, vars));
00853 }
00854
00855
00856 Theorem CommonTheoremProducer::skolemizeRewrite(const Expr& e)
00857 {
00858 Assumptions a;
00859 Proof pf;
00860 if(CHECK_PROOFS) {
00861 CHECK_SOUND(e.isExists(), "skolemize rewrite called on non-existential: "
00862 + e.toString());
00863 }
00864 Expr skol = skolemize(e);
00865 if(withProof()) {
00866 Expr rw(e.iffExpr(skol));
00867 pf = newLabel(rw);
00868 }
00869 return newRWTheorem(e, skol, a, pf);
00870
00871 }
00872
00873
00874 Theorem CommonTheoremProducer::skolemizeRewriteVar(const Expr& e)
00875 {
00876 Assumptions a;
00877 Proof pf;
00878 if(CHECK_PROOFS) {
00879 CHECK_SOUND(e.isExists(), "skolemizeRewriteVar("
00880 +e.toString()+")");
00881 }
00882
00883 const vector<Expr>& boundVars = e.getVars();
00884 const Expr& body = e.getBody();
00885
00886 if(CHECK_PROOFS) {
00887 CHECK_SOUND(boundVars.size()==1, "skolemizeRewriteVar("
00888 +e.toString()+")");
00889 CHECK_SOUND(body.isEq() || body.isIff(), "skolemizeRewriteVar("
00890 +e.toString()+")");
00891 const Expr& v = boundVars[0];
00892 CHECK_SOUND(body[1] == v, "skolemizeRewriteVar("
00893 +e.toString()+")");
00894 CHECK_SOUND(!(v.subExprOf(body[0])), "skolemizeRewriteVar("
00895 +e.toString()+")");
00896 }
00897
00898 Expr skolV(e.skolemExpr(0));
00899 Type tp(e.getVars()[0].getType());
00900 skolV.setType(tp);
00901
00902 Expr skol = Expr(body.getOp(), body[0], skolV);
00903
00904 if(withProof()) {
00905 Expr rw(e.iffExpr(skol));
00906 pf = newLabel(rw);
00907 }
00908 return newRWTheorem(e, skol, a, pf);
00909 }
00910
00911
00912 Theorem CommonTheoremProducer::varIntroRule(const Expr& phi) {
00913
00914 Assumptions a; Proof pf;
00915 const Expr boundVar = d_em->newBoundVarExpr(phi.getType());
00916
00917 Expr body;
00918 if(phi.getType().isBool())
00919 body = phi.iffExpr(boundVar);
00920 else
00921 body = phi.eqExpr(boundVar);
00922
00923 std::vector<Expr> v;
00924 v.push_back(boundVar);
00925 const Expr result = d_em->newClosureExpr(EXISTS, v, body);
00926
00927 if(withProof())
00928 pf = newPf("var_intro", phi, boundVar);
00929 return newTheorem(result, a, pf);
00930 }
00931
00932
00933 Theorem CommonTheoremProducer::skolemize(const Theorem& thm) {
00934 const Expr& e = thm.getExpr();
00935 if(e.isExists()) {
00936 TRACE("skolem", "Skolemizing existential:", "", "{");
00937 CDMap<Expr, Theorem>::iterator i=d_skolemized_thms.find(e),
00938 iend=d_skolemized_thms.end();
00939 if(i!=iend) {
00940 TRACE("skolem", "Skolemized theorem found in map: ", (*i).second, "}");
00941 return iffMP(thm, (*i).second);
00942 }
00943 Theorem skol = skolemizeRewrite(e);
00944 for(unsigned int i=0; i<e.getVars().size(); i++) {
00945 Expr skolV(e.skolemExpr(i));
00946 Type tp(e.getVars()[i].getType());
00947 skolV.setType(tp);
00948 }
00949 d_skolem_axioms.push_back(skol);
00950 d_skolemized_thms.insert(e, skol, 0);
00951 skol = iffMP(thm, skol);
00952 TRACE("skolem", "skolemized new theorem: ", skol, "}");
00953 return skol;
00954 }
00955 return thm;
00956 }
00957
00958
00959 Theorem CommonTheoremProducer::varIntroSkolem(const Expr& e) {
00960
00961 CDMap<Expr, Theorem>::iterator i=d_skolemVars.find(e),
00962 iend=d_skolemVars.end();
00963 if(i!=iend) return (*i).second;
00964
00965 Theorem thm = varIntroRule(e);
00966 const Expr& e2 = thm.getExpr();
00967 DebugAssert(e2.isExists() && e2.getVars().size()==1, "varIntroSkolem: e2 = "
00968 +e2.toString());
00969 Theorem skolThm;
00970
00971 CDMap<Expr, Theorem>::iterator j=d_skolemized_thms.find(e2),
00972 jend=d_skolemized_thms.end();
00973 if(j!=jend) {
00974 skolThm = (*i).second;
00975 } else {
00976 skolThm = skolemizeRewriteVar(e2);
00977 d_skolem_axioms.push_back(skolThm);
00978 d_skolemized_thms.insert(e2, skolThm, 0);
00979 }
00980 thm = iffMP(thm, skolThm);
00981 d_skolemVars.insert(e, thm, 0);
00982 return thm;
00983 }
00984
00985
00986
00987
00988
00989 Theorem CommonTheoremProducer::trueTheorem()
00990 {
00991 return iffTrueElim(reflexivityRule(d_em->trueExpr()));
00992 }
00993
00994
00995 Theorem CommonTheoremProducer::rewriteAnd(const Theorem& e)
00996 {
00997 return iffMP(e, rewriteAnd(e.getExpr()));
00998 }
00999
01000
01001 Theorem CommonTheoremProducer::rewriteOr(const Theorem& e)
01002 {
01003 return iffMP(e, rewriteOr(e.getExpr()));
01004 }