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
00034
00035
00036
00037
00038
00039
00040
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
00053 CoreProofRules* TheoryCore::createProofRules(TheoremManager* tm) {
00054 return new CoreTheoremProducer(tm, this);
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
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
00094
00095
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
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
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;
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
00145
00146
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
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
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
00180
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())
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())
00201 pf = newPf("rewrite_constdef", e[1]);
00202 return newRWTheorem(e, e[1], a, pf);
00203 }
00204
00205
00206
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;
00214 for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00215
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
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;
00231 for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i)
00232
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
00806
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
00833
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 }