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 #include "expr_transform.h"
00031 #include "theory_core.h"
00032 #include "dictionary.h"
00033 #include "hash.h"
00034 #include "command_line_flags.h"
00035 #include "core_proof_rules.h"
00036
00037
00038 using namespace std;
00039 using namespace CVCL;
00040
00041
00042 ExprTransform::ExprTransform(TheoryCore* core) : d_core(core)
00043 {
00044 d_commonRules = d_core->getCommonRules();
00045 d_rules = d_core->getCoreRules();
00046 }
00047
00048
00049 Theorem ExprTransform::preprocess(const Expr& e)
00050 {
00051 Theorem thm1;
00052 if (d_core->getFlags()["pp-pushneg"].getBool())
00053 thm1 = pushNegation(e);
00054 else
00055 thm1 = d_commonRules->reflexivityRule(e);
00056 thm1 = d_commonRules->transitivityRule(thm1, d_core->simplify(thm1.getRHS()));
00057 if (d_core->getFlags()["ite-ify"].getBool())
00058 thm1 = d_commonRules->transitivityRule(thm1,ite_convert(thm1.getRHS()));
00059 if (d_core->getFlags()["pp-ite"].getBool())
00060 return d_commonRules->transitivityRule(thm1,ite_simplify(thm1.getRHS()));
00061 return thm1;
00062 }
00063
00064
00065 Theorem ExprTransform::preprocess(const Theorem& thm)
00066 {
00067 return d_commonRules->iffMP(thm, preprocess(thm.getExpr()));
00068 }
00069
00070
00071
00072 Theorem ExprTransform::pushNegation(const Expr& e) {
00073 if(e.isTerm()) return d_commonRules->reflexivityRule(e);
00074 Theorem res(pushNegationRec(e, false));
00075 d_pushNegCache.clear();
00076 return res;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086 Theorem ExprTransform::pushNegationRec(const Expr& e, bool neg) {
00087 TRACE("pushNegation", "pushNegationRec(", e,
00088 ", neg=" + string(neg? "true":"false") + ") {");
00089 DebugAssert(!e.isTerm(), "pushNegationRec: not boolean e = "+e.toString());
00090 ExprMap<Theorem>::iterator i = d_pushNegCache.find(neg? !e : e);
00091 if(i != d_pushNegCache.end()) {
00092 TRACE("pushNegation", "pushNegationRec [cached] => ", (*i).second, "}");
00093 return (*i).second;
00094 }
00095
00096 Theorem res(d_core->reflexivityRule((neg)? !e : e));
00097 if(neg) {
00098 switch(e.getKind()) {
00099 case TRUE: res = d_commonRules->rewriteNotTrue(!e); break;
00100 case FALSE: res = d_commonRules->rewriteNotFalse(!e); break;
00101 case NOT:
00102 res = pushNegationRec(d_commonRules->rewriteNotNot(!e), false);
00103 break;
00104 case AND:
00105 res = pushNegationRec(d_rules->rewriteNotAnd(!e), false);
00106 break;
00107 case OR:
00108 res = pushNegationRec(d_rules->rewriteNotOr(!e), false);
00109 break;
00110 case IMPLIES: {
00111 vector<Theorem> thms;
00112 thms.push_back(d_rules->rewriteImplies(e));
00113 res = pushNegationRec
00114 (d_commonRules->substitutivityRule(NOT, thms), true);
00115 break;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 case ITE:
00125 res = pushNegationRec(d_rules->rewriteNotIte(!e), false);
00126 break;
00127
00128
00129
00130 case LETDECL: {
00131 vector<Theorem> thms;
00132 thms.push_back(d_rules->rewriteLetDecl(e));
00133 res = pushNegationRec
00134 (d_commonRules->substitutivityRule(NOT, thms), true);
00135 break;
00136 }
00137 case CONSTDEF:
00138 {
00139 vector<Theorem> thms;
00140 thms.push_back(d_rules->rewriteConstDef(e));
00141 res = pushNegationRec
00142 (d_commonRules->substitutivityRule(NOT, thms), true);
00143 break;
00144 }
00145 default:
00146 res = d_commonRules->reflexivityRule(!e);
00147 }
00148 } else {
00149 switch(e.getKind()) {
00150 case NOT: res = pushNegationRec(e[0], true); break;
00151 case AND:
00152 case OR:
00153 case IFF:
00154 case ITE: {
00155 Op op = e.getOp();
00156 vector<Theorem> thms;
00157 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
00158 thms.push_back(pushNegationRec(*i, false));
00159 res = d_commonRules->substitutivityRule(op, thms);
00160 break;
00161 }
00162 case IMPLIES:
00163 res = pushNegationRec(d_rules->rewriteImplies(e), false);
00164 break;
00165 case LETDECL:
00166 res = pushNegationRec(d_rules->rewriteLetDecl(e), false);
00167 break;
00168 case CONSTDEF:
00169 res = pushNegationRec(d_rules->rewriteConstDef(e), false);
00170 break;
00171 default:
00172 res = d_commonRules->reflexivityRule(e);
00173 }
00174 }
00175 TRACE("pushNegation", "pushNegationRec => ", res, "}");
00176 d_pushNegCache[neg? !e : e] = res;
00177 return res;
00178 }
00179
00180
00181 Theorem ExprTransform::pushNegationRec(const Theorem& thm, bool neg) {
00182 DebugAssert(thm.isRewrite(), "pushNegationRec(Theorem): bad theorem: "
00183 + thm.toString());
00184 Expr e(thm.getRHS());
00185 if(neg) {
00186 DebugAssert(e.isNot(),
00187 "pushNegationRec(Theorem, neg = true): bad Theorem: "
00188 + thm.toString());
00189 e = e[0];
00190 }
00191 return d_commonRules->transitivityRule(thm, pushNegationRec(e, neg));
00192 }
00193
00194
00195 Theorem ExprTransform::pushNegation1(const Expr& e) {
00196 TRACE("pushNegation1", "pushNegation1(", e, ") {");
00197 DebugAssert(e.isNot(), "pushNegation1("+e.toString()+")");
00198 Theorem res;
00199 switch(e[0].getKind()) {
00200 case TRUE: res = d_commonRules->rewriteNotTrue(e); break;
00201 case FALSE: res = d_commonRules->rewriteNotFalse(e); break;
00202 case NOT:
00203 res = d_commonRules->rewriteNotNot(e);
00204 break;
00205 case AND:
00206 res = d_rules->rewriteNotAnd(e);
00207 break;
00208 case OR:
00209 res = d_rules->rewriteNotOr(e);
00210 break;
00211 case IMPLIES: {
00212 vector<Theorem> thms;
00213 thms.push_back(d_rules->rewriteImplies(e[0]));
00214 res = d_commonRules->substitutivityRule(e.getOp(), thms);
00215 res = d_commonRules->transitivityRule(res, d_rules->rewriteNotOr(res.getRHS()));
00216 break;
00217 }
00218 case ITE:
00219 res = d_rules->rewriteNotIte(e);
00220 break;
00221
00222
00223 case LETDECL: {
00224 vector<Theorem> thms;
00225 thms.push_back(d_rules->rewriteLetDecl(e[0]));
00226 res = d_commonRules->substitutivityRule(e.getOp(), thms);
00227 res = d_commonRules->transitivityRule(res, pushNegation1(res.getRHS()));
00228 break;
00229 }
00230 case CONSTDEF: {
00231 vector<Theorem> thms;
00232 thms.push_back(d_rules->rewriteConstDef(e[0]));
00233 res = d_commonRules->substitutivityRule(e.getOp(), thms);
00234 res = d_commonRules->transitivityRule(res, pushNegation1(res.getRHS()));
00235 break;
00236 }
00237 default:
00238 res = d_commonRules->reflexivityRule(e);
00239 }
00240 TRACE("pushNegation1", "pushNegation1 => ", res.getExpr(), " }");
00241 return res;
00242 }
00243
00244
00245 typedef Hash_Table<Expr, Expr> CareSet;
00246 typedef Hash_Ptr<Expr, Expr> CareSetPtr;
00247 typedef Dict<Expr, CareSet*> Queue;
00248 typedef Dict_Ptr<Expr, CareSet*> QueuePtr;
00249
00250 typedef ExprMap<Theorem> Table;
00251
00252 static int cf(Expr x, Expr y) {
00253 return (x.getIndex() < y.getIndex()) ? -1 : (x.getIndex() == y.getIndex()) ? 0 : 1; }
00254 static size_t hf(const Expr x) {
00255 return x.getEM()->hash(x);; }
00256 static size_t mf(const Expr x, const Expr y) { return x==y; }
00257
00258 static void update_queue(Queue *q, Expr e, CareSet *cs_prime){
00259 CareSet **cs=q->Fetch(e);
00260
00261
00262
00263
00264 if (cs) {
00265 CareSetPtr p(*cs);
00266 while (p!=NULL) {
00267 if (!cs_prime->Fetch(p->Key()) ||
00268 (*cs_prime)[p->Key()]!=p->Data()) {
00269 Expr key=p->Key();
00270 ++p;
00271 (*cs)->Delete(key);
00272 }
00273 else
00274 ++p;
00275 }
00276 }
00277 else
00278 q->Insert(e, new CareSet(*cs_prime));
00279 }
00280
00281 Theorem ExprTransform::substitute(Expr e, Table *init_st) {
00282 static Table *memoize;
00283 static Table *st;
00284
00285
00286 if (init_st) {
00287 if (memoize) delete memoize;
00288 memoize = new Table();
00289 st = init_st;
00290 }
00291
00292
00293 if(e.isNull() || e.isBoolConst()
00294 || e.isString() || e.isRational())
00295 return d_commonRules->reflexivityRule(e);
00296
00297
00298 ExprMap<Theorem>::iterator i = memoize->find(e);
00299 if(i != memoize->end()) {
00300 return (*i).second;
00301 }
00302
00303
00304 i = st->find(e);
00305 if (i != st->end()) {
00306 return d_commonRules->transitivityRule((*i).second, substitute((*i).second.getRHS()));
00307 }
00308
00309
00310 Theorem thm;
00311 if(e.getKind() != ITE)
00312 thm = d_commonRules->reflexivityRule(e);
00313 else{
00314 vector<Theorem> thms;
00315 vector<unsigned> changed;
00316 Expr tmp;
00317 thm = substitute(e[0]);
00318 if(thm.getRHS() == e[0]){
00319 thm = d_commonRules->reflexivityRule(e);
00320 tmp = e;
00321 }
00322 else{
00323 thms.push_back(thm);
00324 changed.push_back(0);
00325 thm = d_commonRules->substitutivityRule(e, changed, thms);
00326 tmp = thm.getRHS();
00327 }
00328 Theorem thm1 = d_rules->rewriteIteThen(tmp, substitute(tmp[1]));
00329
00330 thm = d_commonRules->transitivityRule(thm, thm1);
00331 tmp = thm.getRHS();
00332 thm1 = d_rules->rewriteIteElse(tmp, substitute(tmp[2]));
00333
00334 thm = d_commonRules->transitivityRule(thm, thm1);
00335 }
00336
00337 (*memoize)[e] = thm;
00338 return thm;
00339 }
00340
00341 Theorem ExprTransform::ite_simplify(Expr e){
00342
00343 Queue q(cf);
00344 Table st;
00345
00346
00347
00348 q.Insert(e, new CareSet(hf, mf));
00349 for (QueuePtr p(&q); p!=NULL; ++p) {
00350
00351 Expr e = Expr(p->Key());
00352
00353 if(e.isNull() || e.isBoolConst() || e.isVar()
00354 || e.isString() || e.isRational() || e.isApply())
00355 continue;
00356
00357 CareSet cs(*p->Data());
00358
00359
00360 delete p->Data();
00361 p->Data() = NULL;
00362
00363
00364 if (e.getKind()==ITE) {
00365 const Expr e1 = Expr(e);
00366 Expr *v = cs.Fetch(e1[0]);
00367 if (v) {
00368 vector<Theorem> thms;
00369 vector<unsigned> changed;
00370 if((*v).isTrue()){
00371
00372 Theorem thm0 = d_commonRules->iffTrue(d_commonRules->assumpRule(e1[0]));
00373 thms.push_back(thm0);
00374 changed.push_back(0);
00375 thm0 = d_commonRules->substitutivityRule(e1, changed, thms);
00376 Theorem thm1 = d_rules->rewriteIteTrue(thm0.getRHS());
00377 thm0 = d_commonRules->transitivityRule(thm0, thm1);
00378 st[e1] = thm0;
00379 if(e1[1].getKind() != TRUE && e1[1].getKind() != FALSE)
00380 update_queue(&q, e1[1], &cs);
00381 continue;
00382 }
00383 else {
00384
00385 Theorem thm0 = d_commonRules->assumpRule(e1[0].iffExpr(d_core->falseExpr()));
00386 thms.push_back(thm0);
00387 changed.push_back(0);
00388 thm0 = d_commonRules->substitutivityRule(e1, changed, thms);
00389 Theorem thm1 = d_rules->rewriteIteFalse(thm0.getRHS());
00390 thm0 = d_commonRules->transitivityRule(thm0, thm1);
00391 st[e1] = thm0;
00392 if(e1[2].getKind() != TRUE && e1[2].getKind() != FALSE)
00393 update_queue(&q, e1[2], &cs);
00394 continue;
00395 }
00396 }
00397 }
00398
00399
00400 if (e.getKind()==ITE) {
00401 CareSet cs_prime(cs);
00402 const Expr ite = Expr(e);
00403 if(ite[0].getKind() != TRUE && ite[0].getKind() != FALSE)
00404 update_queue(&q, ite[0], &cs);
00405
00406 cs_prime.Insert(ite[0], d_core->trueExpr());
00407 if(ite[1].getKind() != TRUE && ite[1].getKind() != FALSE)
00408 update_queue(&q, ite[1], &cs_prime);
00409
00410 cs_prime[ite[0]]=d_core->falseExpr();
00411 if(ite[2].getKind() != TRUE && ite[2].getKind() != FALSE)
00412 update_queue(&q, ite[2], &cs_prime);
00413 }
00414 }
00415
00416
00417 return substitute(e, &st);
00418 }
00419
00420 Theorem ExprTransform::ite_convert(const Expr& e){
00421 switch(e.getKind()){
00422 case TRUE:
00423 case FALSE:
00424 return d_commonRules->reflexivityRule(e); break;
00425 case ITE:
00426 {
00427 Theorem thm0 = ite_convert(e[0]);
00428 Theorem thm1 = ite_convert(e[1]);
00429 Theorem thm2 = ite_convert(e[2]);
00430 vector<Theorem> thms;
00431 thms.push_back(thm0);
00432 thms.push_back(thm1);
00433 thms.push_back(thm2);
00434
00435 return d_commonRules->substitutivityRule(e.getOp(), thms);
00436 }
00437 break;
00438 case NOT:
00439 {
00440 Theorem thm = ite_convert(e[0]);
00441 vector<Theorem> thms;
00442 thms.push_back(thm);
00443 thm = d_commonRules->substitutivityRule(e.getOp(), thms);
00444 return d_commonRules->transitivityRule(thm, d_rules->NotToIte(thm.getRHS()));
00445 }
00446 break;
00447 case AND:
00448 {
00449 DebugAssert(e.arity() > 0, "Expected non-empty AND");
00450 const vector<Expr>& kids = e.getKids();
00451 unsigned i(0), ar(kids.size());
00452 vector<Theorem> thms;
00453 for(; i < ar; i++){
00454 thms.push_back(ite_convert(kids[i]));
00455 }
00456 Theorem thm = d_commonRules->substitutivityRule(e.getOp(), thms);
00457 thm = d_commonRules->transitivityRule(thm, d_rules->AndToIte(thm.getRHS()));
00458 return thm;
00459 }
00460 break;
00461 case OR:
00462 {
00463 DebugAssert(e.arity() > 0, "Expected non-empty OR");
00464 const vector<Expr>& kids = e.getKids();
00465 unsigned i(0), ar(kids.size());
00466 vector<Theorem> thms;
00467 for(; i < ar; i++){
00468 thms.push_back(ite_convert(kids[i]));
00469 }
00470 Theorem thm = d_commonRules->substitutivityRule(e.getOp(), thms);
00471 return d_commonRules->transitivityRule(thm, d_rules->OrToIte(thm.getRHS()));
00472 }
00473 break;
00474 case IMPLIES:
00475 {
00476 vector<Theorem> thms;
00477 thms.push_back(ite_convert(e[0]));
00478 thms.push_back(ite_convert(e[1]));
00479 Theorem thm = d_commonRules->substitutivityRule(e.getOp(), thms);
00480 return d_commonRules->transitivityRule(thm, d_rules->ImpToIte(thm.getRHS()));
00481 }
00482 break;
00483 case IFF:
00484 {
00485 vector<Theorem> thms;
00486 thms.push_back(ite_convert(e[0]));
00487 thms.push_back(ite_convert(e[1]));
00488 Theorem thm = d_commonRules->substitutivityRule(e.getOp(), thms);
00489 return d_commonRules->transitivityRule(thm, d_rules->IffToIte(thm.getRHS()));
00490 }
00491 break;
00492 default:
00493 return d_commonRules->reflexivityRule(e);
00494 }
00495 }
00496
00497 Expr ExprTransform::ite_reorder(const Expr& e){
00498 switch(e.getKind()){
00499 case TRUE:
00500 case FALSE:
00501 return e; break;
00502 case ITE:
00503 {
00504 int x = random();
00505 if(x < 1073741824)
00506 return ite_reorder(e[0]).iteExpr(ite_reorder(e[1]), ite_reorder(e[2]));
00507 if(e[0].isTrue()){
00508 return ite_reorder(e[1]);
00509 }
00510 else if(e[0].isFalse()){
00511 return ite_reorder(e[2]);
00512 }
00513 else if(e[1].isTrue())
00514 return ite_reorder(e[2]).iteExpr(e[1], ite_reorder(e[0]));
00515 else if(e[1].isFalse() && e[2].isTrue())
00516 return ite_reorder(e[0]).iteExpr(e[1], e[2]);
00517 else if(e[1].isFalse()){
00518 Expr e0 = ite_reorder(e[2]);
00519 if(e0.isTrue())
00520 return getNeg(ite_reorder(e[0]));
00521 else if(e0.isFalse())
00522 return e[1];
00523 else
00524 return getNeg(e0).iteExpr(e[1], getNeg(ite_reorder(e[0])));
00525 }
00526 else if(e[2].isTrue()){
00527 Expr e0 = ite_reorder(e[1]);
00528 if(e0.isTrue())
00529 return e[2];
00530 else if(e0.isFalse())
00531 return getNeg(ite_reorder(e[0])) ;
00532 else
00533 return getNeg(e0).iteExpr(getNeg(ite_reorder(e[0])), e[2]);
00534 }
00535 else if(e[2].isFalse()){
00536 Expr e0 = ite_reorder(e[1]);
00537 if(e0.isTrue())
00538 return ite_reorder(e[0]);
00539 else if(e0.isFalse())
00540 return e[2];
00541 else
00542 return e0.iteExpr(ite_reorder(e[0]), e[2]);
00543 }
00544 else{
00545 Expr e0 = getNeg(ite_reorder(e[0]));
00546 if(e0.isTrue())
00547 return ite_reorder(e[2]);
00548 else if(e0.isFalse())
00549 return ite_reorder(e[1]);
00550 else
00551 return e0.iteExpr(ite_reorder(e[2]), ite_reorder(e[1]));
00552 }
00553 }
00554 break;
00555 default:
00556 return e;
00557 }
00558 }
00559
00560 Expr ExprTransform::getNeg(const Expr& e){
00561 switch(e.getKind()){
00562 case TRUE:
00563 return d_core->falseExpr(); break;
00564 case FALSE:
00565 return d_core->trueExpr(); break;
00566 case ITE:
00567 {
00568 if(e[1].isFalse() && e[2].isTrue())
00569 return e[0];
00570 else
00571 return e.iteExpr(d_core->falseExpr(), d_core->trueExpr());
00572 }
00573 break;
00574 default:
00575 return e.iteExpr(d_core->falseExpr(), d_core->trueExpr());
00576 }
00577 }
00578
00579