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 }