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 "command_line_flags.h"
00031 #include "expr.h"
00032 #include "notifylist.h"
00033 #include "pretty_printer.h"
00034 #include "common_proof_rules.h"
00035 #include "parser_exception.h"
00036 #include "typecheck_exception.h"
00037 #include "smtlib_exception.h"
00038 #include "eval_exception.h"
00039 #include "theory_core.h"
00040 #include "expr_transform.h"
00041 #include "core_proof_rules.h"
00042 #include "theorem_manager.h"
00043
00044
00045 using namespace std;
00046
00047
00048 namespace CVCL {
00049
00050
00051
00052
00053 class PrettyPrinterCore: public PrettyPrinter {
00054 private:
00055 TheoryCore *d_core;
00056
00057 PrettyPrinterCore() { }
00058 public:
00059
00060 PrettyPrinterCore(TheoryCore* core): d_core(core) { }
00061 ExprStream& print(ExprStream& os, const Expr& e) {
00062 if(e.isString())
00063 return e.print(os);
00064 else if (e.isApply())
00065 return d_core->theoryOf(e)->print(os, e);
00066 else if(d_core->hasTheory(e.getKind()))
00067 return d_core->theoryOf(e.getKind())->print(os, e);
00068 else
00069 return e.print(os);
00070 }
00071 };
00072
00073
00074 class TypeComputerCore: public ExprManager::TypeComputer {
00075 TheoryCore *d_core;
00076 public:
00077 TypeComputerCore(TheoryCore* core): d_core(core) { }
00078 void computeType(const Expr& e) {
00079 DebugAssert(!e.isVar(), "Variables should have a type: "+e.toString());
00080 Theory* i = d_core->theoryOf(e.getKind());
00081 if (e.isApply()) i = d_core->theoryOf(e);
00082 TRACE("types", "computeType["+i->getName()+"](", e, ") {");
00083 TRACE("types verbose", "kind = ", d_core->getEM()->getKindName(e.getKind()), "");
00084 i->computeType(e);
00085 DebugAssert(!e.lookupType().getExpr().isNull(), "Type not set by computeType");
00086 TRACE("types", "computeType["+i->getName()+"] => ", e.getType(), " }");
00087 }
00088 void checkType(const Expr& e) {
00089 if (!e.isType()) throw Exception
00090 ("Tried to use non-type as a type: "+e.toString());
00091 d_core->theoryOf(e)->checkType(e);
00092 e.setValidType();
00093 }
00094 };
00095
00096
00097 ostream& operator<<(ostream& os, const NotifyList& l) {
00098 os << "NotifyList(\n";
00099 for(size_t i=0,iend=l.size(); i<iend; ++i) {
00100 os << "[" << l.getTheory(i)->getName() << ", " << l.getExpr(i) << "]\n";
00101 }
00102 return os << ")";
00103 }
00104
00105
00106 }
00107
00108
00109 using namespace CVCL;
00110
00111
00112
00113
00114 IF_DEBUG(
00115
00116 static bool isSorted(const vector<Expr>& v) {
00117 Expr prev;
00118 for(vector<Expr>::const_iterator i=v.begin(), iend=v.end(); i!=iend;
00119 prev = *i, ++i) {
00120 if(prev.isNull()) continue;
00121 if(!(prev < *i)) return false;
00122 }
00123 return true;
00124 }
00125 )
00126
00127
00128
00129
00130 static void intersect(const vector<Expr>& a, const vector<Expr>& b,
00131 vector<Expr>& res) {
00132 DebugAssert(isSorted(a) && isSorted(b), "intersect()");
00133 size_t i(0), j(0), iend(a.size()), jend(b.size());
00134 while(i<iend && j<jend) {
00135 if(a[i] == b[j]) {
00136 res.push_back(a[i]);
00137 i++; j++;
00138 } else if(a[i] < b[j]) i++;
00139 else j++;
00140 }
00141 }
00142
00143
00144
00145
00146 static void difference(const vector<Expr>& a, const vector<Expr>& b,
00147 vector<Expr>& res) {
00148 DebugAssert(isSorted(a) && isSorted(b), "difference()");
00149 size_t i(0), j(0), iend(a.size()), jend(b.size());
00150 while(i < iend) {
00151 if(j >= jend) { res.push_back(a[i]); i++; }
00152 else if(a[i]==b[j]) { i++; j++; }
00153 else if(a[i]<b[j]) { res.push_back(a[i]); i++; }
00154 else j++;
00155 }
00156 }
00157
00158 void
00159 TheoryCore::enqueueSE(const Theorem& thm) {
00160 TRACE("enqueueSE", "enqueueSE(", thm.getExpr(), ")");
00161 DebugAssert(d_inAddFact || d_inCheckSATCore || d_inRegisterAtom, "enqueueSE()");
00162 if(thm.isRewrite() || !thm.getExpr().isTrue())
00163 d_queueSE.push_back(thm);
00164 }
00165
00166
00167 Theorem TheoryCore::getModelValue(const Expr& e) {
00168 ExprHashMap<Theorem>::iterator i=d_varAssignments.find(e),
00169 iend=d_varAssignments.end();
00170 if(i!=iend) return (*i).second;
00171 else return find(e);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 TheoryCore::TheoryCore(ContextManager* cm,
00189 ExprManager* em,
00190 TheoremManager* tm,
00191 const CLFlags& flags,
00192 Statistics& statistics)
00193 : Theory(), d_cm(cm), d_tm(tm), d_flags(flags), d_statistics(statistics),
00194 d_inconsistent(cm->getCurrentContext(), false, 0),
00195 d_incomplete(cm->getCurrentContext()),
00196 d_diseq(cm->getCurrentContext()),
00197 d_incThm(cm->getCurrentContext()),
00198 d_terms(cm->getCurrentContext()),
00199 d_vars(cm->getCurrentContext()),
00200 d_sharedTerms(cm->getCurrentContext()),
00201 d_solver(NULL),
00202 d_simplifyInPlace(&(flags["ip"].getBool())),
00203 d_currentRecursiveSimplifier(NULL),
00204 d_cnfOption(&(flags["cnf"].getBool())),
00205 d_resourceLimit(0),
00206 #ifdef DEBUG
00207 d_dumpTrace(&(flags["dump-trace"].getString())),
00208 d_inCheckSATCore(false), d_inAddFact(false), d_inSimplify(false),
00209 d_inRegisterAtom(false),
00210 #endif
00211 d_notifyObj(this, cm->getCurrentContext()),
00212 d_impliedLiterals(cm->getCurrentContext()),
00213 d_impliedLiteralsIdx(cm->getCurrentContext(), 0, 0),
00214 d_coreSatAPI(NULL)
00215 {
00216 IF_DEBUG(d_diseq.setName("CDList[TheoryCore::d_diseq]"));
00217 d_em = em;
00218 d_theoryCore = this;
00219 d_commonRules = tm->getRules();
00220 d_name = "Core";
00221 d_theoryUsed = false;
00222
00223 d_rules = createProofRules(tm);
00224 d_printer = new PrettyPrinterCore(this);
00225 d_typeComputer = new TypeComputerCore(this);
00226 d_em->registerTypeComputer(d_typeComputer);
00227 d_exprTrans = new ExprTransform(this);
00228
00229
00230 d_em->registerPrettyPrinter(*d_printer);
00231
00232
00233
00234 vector<int> kinds;
00235 kinds.push_back(RAW_LIST);
00236 kinds.push_back(BOOLEAN);
00237 kinds.push_back(SUBTYPE);
00238 kinds.push_back(STRING_EXPR);
00239 kinds.push_back(ID);
00240 kinds.push_back(TRUE);
00241 kinds.push_back(FALSE);
00242 kinds.push_back(UCONST);
00243 kinds.push_back(BOUND_VAR);
00244 kinds.push_back(SKOLEM_VAR);
00245 kinds.push_back(EQ);
00246 kinds.push_back(NEQ);
00247 kinds.push_back(ECHO);
00248 kinds.push_back(DBG);
00249 kinds.push_back(TRACE);
00250 kinds.push_back(UNTRACE);
00251 kinds.push_back(OPTION);
00252 kinds.push_back(HELP);
00253 kinds.push_back(AND);
00254 kinds.push_back(OR);
00255 kinds.push_back(IFTHEN);
00256 kinds.push_back(IF);
00257 kinds.push_back(ELSE);
00258 kinds.push_back(COND);
00259 kinds.push_back(XOR);
00260 kinds.push_back(NOT);
00261 kinds.push_back(ITE);
00262 kinds.push_back(IFF);
00263 kinds.push_back(IMPLIES);
00264 kinds.push_back(APPLY);
00265
00266 kinds.push_back(LET);
00267 kinds.push_back(LETDECLS);
00268 kinds.push_back(LETDECL);
00269
00270 kinds.push_back(VARLIST);
00271 kinds.push_back(VARDECLS);
00272 kinds.push_back(VARDECL);
00273
00274
00275 kinds.push_back(TYPE);
00276
00277 kinds.push_back(CONST);
00278
00279 kinds.push_back(CONSTDEF);
00280 kinds.push_back(TYPEDEF);
00281 kinds.push_back(DEFUN);
00282
00283 kinds.push_back(PF_APPLY);
00284 kinds.push_back(PF_HOLE);
00285
00286
00287 kinds.push_back(ASSERT);
00288 kinds.push_back(QUERY);
00289 kinds.push_back(PRINT);
00290
00291 kinds.push_back(DUMP_PROOF);
00292 kinds.push_back(DUMP_ASSUMPTIONS);
00293 kinds.push_back(DUMP_SIG);
00294 kinds.push_back(DUMP_TCC);
00295 kinds.push_back(DUMP_TCC_ASSUMPTIONS);
00296 kinds.push_back(DUMP_TCC_PROOF);
00297 kinds.push_back(DUMP_CLOSURE);
00298 kinds.push_back(DUMP_CLOSURE_PROOF);
00299 kinds.push_back(TRANSFORM);
00300 kinds.push_back(CALL);
00301 kinds.push_back(WHERE);
00302 kinds.push_back(ASSERTIONS);
00303 kinds.push_back(ASSUMPTIONS);
00304 kinds.push_back(COUNTEREXAMPLE);
00305 kinds.push_back(COUNTERMODEL);
00306 kinds.push_back(PUSH);
00307 kinds.push_back(POP);
00308 kinds.push_back(POPTO);
00309 kinds.push_back(PUSH_SCOPE);
00310 kinds.push_back(POP_SCOPE);
00311 kinds.push_back(POPTO_SCOPE);
00312 kinds.push_back(CONTEXT);
00313 kinds.push_back(FORGET);
00314 kinds.push_back(GET_TYPE);
00315 kinds.push_back(CHECK_TYPE);
00316 kinds.push_back(GET_CHILD);
00317 kinds.push_back(SUBSTITUTE);
00318 kinds.push_back(SEQ);
00319
00320
00321 kinds.push_back(AND_R);
00322 kinds.push_back(IFF_R);
00323 kinds.push_back(ITE_R);
00324
00325 registerTheory(this, kinds);
00326 }
00327
00328
00329 TheoryCore::~TheoryCore()
00330 {
00331 delete d_exprTrans;
00332 delete d_rules;
00333 delete d_typeComputer;
00334 d_em->unregisterPrettyPrinter();
00335 delete d_printer;
00336 }
00337
00338
00339
00340
00341
00342
00343 void TheoryCore::assertFact(const Theorem& e) {
00344 DebugAssert(e.getExpr().unnegate().getKind() == SKOLEM_VAR ||
00345 e.getExpr().unnegate().getKind() == UCONST,
00346 "TheoryCore::assertFact("+e.toString()+")");
00347 }
00348
00349
00350 void TheoryCore::checkSat(bool fullEffort) {
00351
00352 for (CDList<Theorem>::const_iterator i = d_diseq.begin(), iend=d_diseq.end();
00353 i!=iend; ++i) {
00354 const Expr& expr = ((*i).getExpr())[0];
00355 Theorem thm0 = find(expr[0]);
00356 Theorem thm1 = find(expr[1]);
00357 if (thm0.getRHS() == thm1.getRHS()) {
00358 Theorem leftEqRight = transitivityRule(thm0, symmetryRule(thm1));
00359 IF_DEBUG(debugger.counter("conflicts from disequalities")++);
00360 setInconsistent(iffMP(leftEqRight, d_commonRules->notToIff(*i)));
00361 return;
00362 }
00363 }
00364 }
00365
00366
00367 Theorem TheoryCore::rewriteLitCore(const Expr& e)
00368 {
00369 switch (e.getKind()) {
00370 case EQ:
00371 if (e[0] == e[1])
00372 return d_commonRules->rewriteReflexivity(e);
00373 else if (e[0] < e[1])
00374 return d_commonRules->rewriteUsingSymmetry(e);
00375 break;
00376 case NOT:
00377 if (e[0].isTrue())
00378 return d_commonRules->rewriteNotTrue(e);
00379 else if (e[0].isFalse())
00380 return d_commonRules->rewriteNotFalse(e);
00381 else if (e[0].isNot())
00382 return d_commonRules->rewriteNotNot(e);
00383 break;
00384 default:
00385 DebugAssert(false,
00386 "TheoryCore::rewriteLitCore("
00387 + e.toString()
00388 + "): Not implemented");
00389 break;
00390 }
00391 return reflexivityRule(e);
00392 }
00393
00394
00395 Theorem TheoryCore::rewriteN(const Expr& e, int n) {
00396 if(n <= 0) return reflexivityRule(e);
00397 if(theoryOf(e) != this) return reflexivityRule(e);
00398 if(n==1) return rewrite(e);
00399 vector<Theorem> thms;
00400 vector<unsigned> changed;
00401 for(int i=0; i<e.arity(); ++i) {
00402 Theorem thm = rewriteN(e[i], n-1);
00403 if(e[i] != thm.getRHS()) {
00404 thms.push_back(thm);
00405 changed.push_back(i);
00406 }
00407 }
00408 Theorem res;
00409 if(changed.size()>0) {
00410 res = substitutivityRule(e, changed, thms);
00411 res = transitivityRule(res, rewrite(res.getRHS()));
00412 } else {
00413 res = rewrite(e);
00414 }
00415 return res;
00416 }
00417
00418
00419 Theorem TheoryCore::rewrite(const Expr& e) {
00420 TRACE("core rewrite", "TheoryCore::rewrite(", e, ") {");
00421 Theorem thm;
00422 switch (e.getKind()) {
00423 case TRUE:
00424 case FALSE:
00425 case UCONST:
00426 case BOUND_VAR:
00427 case SKOLEM_VAR:
00428 thm = reflexivityRule(e);
00429 break;
00430 case LETDECL:
00431
00432
00433 thm = d_rules->rewriteLetDecl(e);
00434 break;
00435 case CONSTDEF:
00436 thm = d_rules->rewriteConstDef(e);
00437 break;
00438 case EQ:
00439 case NOT:
00440 thm = rewriteLitCore(e);
00441 break;
00442 case IMPLIES: {
00443 thm = d_rules->rewriteImplies(e);
00444 const Expr& rhs = thm.getRHS();
00445
00446 DebugAssert(rhs.isOr() && rhs.arity() == 2,
00447 "TheoryCore::rewrite[IMPLIES]: rhs = "+rhs.toString());
00448 Theorem rw = rewriteCore(rhs[0]);
00449 if(rw.getLHS() != rw.getRHS()) {
00450 vector<unsigned> changed;
00451 vector<Theorem> thms;
00452 changed.push_back(0);
00453 thms.push_back(rw);
00454 rw = substitutivityRule(rhs, changed, thms);
00455
00456 rw = transitivityRule(rw, find(rw.getRHS()));
00457
00458 rw = transitivityRule(rw, rewrite(rw.getRHS()));
00459 } else
00460 rw = rewrite(rhs);
00461 thm = transitivityRule(thm, rw);
00462
00463 break;
00464 }
00465 case IFF: {
00466 thm = d_commonRules->rewriteIff(e);
00467 const Expr& e1 = thm.getRHS();
00468
00469
00470 if (e != e1 && e1.isNot())
00471 thm = transitivityRule(thm, rewriteCore(e1));
00472 else if(e1.isIff()) {
00473 TRACE_MSG("core rewrite",
00474 "rewrite[Core]: checking for (a|b)<=>(a|c)...");
00475
00476
00477
00478 vector<Expr> lhs, rhs, av;
00479 int kind(NULL_KIND);
00480 Op op(NULL_KIND);
00481 if ((e1[0].isOr() || e1[0].isAnd()) && e1[0].arity() > 0) {
00482 kind = e1[0].getKind();
00483 op = e1[0].getOp();
00484 }
00485 if (kind==NULL_KIND && (e1[1].isOr() || e1[1].isAnd()) &&
00486 e1[1].arity() > 0) {
00487 kind = e1[1].getKind();
00488 op = e1[1].getOp();
00489 }
00490 if(kind==NULL_KIND) break;
00491
00492 if(e1[0].getKind()==kind) lhs=e1[0].getKids();
00493 else lhs.push_back(e1[0]);
00494 if(e1[1].getKind()==kind) rhs=e1[1].getKids();
00495 else rhs.push_back(e1[1]);
00496 TRACE("core rewrite", "lhs = ", Expr(RAW_LIST, lhs, d_em), "");
00497 TRACE("core rewrite", "rhs = ", Expr(RAW_LIST, rhs, d_em), "");
00498 intersect(lhs, rhs, av);
00499 TRACE("core rewrite", "intersect(lhs,rhs) = ",
00500 Expr(RAW_LIST, av, d_em), "");
00501 if(av.size()>0) {
00502 vector<Expr> bv, cv;
00503 difference(lhs, av, bv);
00504 difference(rhs, av, cv);
00505 TRACE("core rewrite", "bv = ", Expr(RAW_LIST, bv, d_em), "");
00506 TRACE("core rewrite", "cv = ", Expr(RAW_LIST, cv, d_em), "");
00507 Expr empty((kind==AND)? d_em->trueExpr() : d_em->falseExpr());
00508 Expr a((av.size()==1)? av[0] : Expr(op, av));
00509 Expr b((bv.size()==0)? empty : (bv.size()==1)? bv[0]
00510 : Expr(op, bv));
00511 Expr c((cv.size()==0)? empty :(cv.size()==1)? cv[0]
00512 : Expr(op, cv));
00513 TRACE("core rewrite", "a = ", a, "");
00514 TRACE("core rewrite", "b = ", b, "");
00515 TRACE("core rewrite", "c = ", c, "");
00516
00517 vector<Theorem> thms;
00518 vector<unsigned> changed;
00519 Theorem t = rewrite(Expr(op, a, b));
00520 if(t.getLHS() != t.getRHS()) {
00521 thms.push_back(symmetryRule(t));
00522 changed.push_back(0);
00523 }
00524 t = rewrite(Expr(op, a, c));
00525 if(t.getLHS() != t.getRHS()) {
00526 thms.push_back(symmetryRule(t));
00527 changed.push_back(1);
00528 }
00529 if(changed.size()>0) {
00530 t = substitutivityRule(e1, changed, thms);
00531 thm = transitivityRule(thm, t);
00532 }
00533 TRACE("core rewrite", "normalize => ", thm.getRHS(), "");
00534 thms.clear();
00535 changed.clear();
00536 if(kind==OR)
00537 t = d_rules->iffOrDistrib(thm.getRHS());
00538 else
00539 t = d_rules->iffAndDistrib(thm.getRHS());
00540 thm = transitivityRule(thm, t);
00541 TRACE("core rewrite", "iffOrDistrib => ", thm.getRHS(), "");
00542
00543 if(kind==AND) {
00544 t = simplifyRec(!a);
00545 } else {
00546 t = rewriteCore(a);
00547 }
00548 if(t.getLHS() != t.getRHS()) {
00549 thms.push_back(t);
00550 changed.push_back(0);
00551 }
00552
00553 t = rewriteN(b.iffExpr(c), 2);
00554 if(t.getLHS() != t.getRHS()) {
00555
00556
00557
00558 if(t.getRHS().isNot())
00559 t = transitivityRule(t, simplifyRec(t.getRHS()));
00560 thms.push_back(t);
00561 changed.push_back(1);
00562 }
00563 if(changed.size()>0) {
00564 t = substitutivityRule(thm.getRHS(), changed, thms);
00565 thm = transitivityRule(thm, t);
00566 }
00567
00568 thm = transitivityRule(thm, rewrite(thm.getRHS()));
00569 }
00570 }
00571 break;
00572 }
00573 case ITE:
00574 if (e[0].isTrue())
00575 thm = d_rules->rewriteIteTrue(e);
00576 else if (e[0].isFalse())
00577 thm = d_rules->rewriteIteFalse(e);
00578 else if (e[1] == e[2])
00579 thm = d_rules->rewriteIteSame(e);
00580 else if (getFlags()["un-ite-ify"].getBool()) {
00581
00582
00583
00584
00585 if (e[1].isFalse() && e[2].isTrue())
00586 thm = rewriteCore(d_rules->rewriteIteToNot(e));
00587 else if (e[1].isTrue())
00588 thm = rewriteCore(d_rules->rewriteIteToOr(e));
00589 else if (e[2].isFalse())
00590 thm = rewriteCore(d_rules->rewriteIteToAnd(e));
00591 else if (e[2].isTrue())
00592 thm = rewriteCore(d_rules->rewriteIteToImp(e));
00593 else if (e[1] == e[2].negate())
00594 thm = rewriteCore(d_rules->rewriteIteToIff(e));
00595 else thm = reflexivityRule(e);
00596 }
00597 else if(getFlags()["ite-cond-simp"].getBool()) {
00598 thm = d_rules->rewriteIteCond(e);
00599 if(e != thm.getRHS())
00600 thm = transitivityRule(thm, simplifyRec(thm.getRHS()));
00601 }
00602 else thm = reflexivityRule(e);
00603 break;
00604 case AND: {
00605 thm = rewriteAnd(e);
00606 const Expr ee = thm.getRHS();
00607
00608
00609 if(!ee.isAnd()) break;
00610
00611 TRACE("core rewrite", "rewrite[Core]: checking for (a|b) & (a|c) in ",
00612 ee, "");
00613
00614
00615 std::vector<Expr> setIntersect;
00616
00617 if(ee[0].isOr())
00618 setIntersect = ee[0].getKids();
00619 else
00620 setIntersect.push_back(ee[0]);
00621 TRACE("core rewrite", "setIntersect = ",
00622 Expr(RAW_LIST, setIntersect, d_em), "");
00623 for(Expr::iterator i=ee.begin(),iend=ee.end();
00624 i!=iend && !setIntersect.empty();++i) {
00625 vector<Expr> Ai, result;
00626
00627 if(i->isOr())
00628 Ai = i->getKids();
00629 else
00630 Ai.push_back(*i);
00631 TRACE("core rewrite", "Ai = ", Expr(RAW_LIST, Ai, d_em), "");
00632
00633 intersect(setIntersect,Ai,result);
00634 setIntersect = result;
00635 TRACE("core rewrite", "setIntersect = ",
00636 Expr(RAW_LIST, setIntersect, d_em), "");
00637 }
00638
00639 if(setIntersect.empty()) break;
00640
00641 Expr A = orExpr(setIntersect);
00642 TRACE("core rewrite", "A = ", A, "");
00643
00644 vector<Theorem> substThms;
00645 vector<unsigned> changed;
00646 int j(0);
00647 for(Expr::iterator i=ee.begin(),iend=ee.end();i!=iend; ++i, ++j) {
00648 vector<Expr> Ai, setDiff;
00649
00650 if(i->isOr())
00651 Ai = i->getKids();
00652 else
00653 Ai.push_back(*i);
00654 TRACE("core rewrite", "Ai = ", Expr(RAW_LIST, Ai, d_em), "");
00655
00656 difference(Ai,setIntersect,setDiff);
00657 TRACE("core rewrite", "setDiff = ",
00658 Expr(RAW_LIST, setDiff, d_em), "");
00659 Expr Bi = (setDiff.empty())? d_em->falseExpr()
00660 : (setDiff.size()==1)? setDiff[0] : orExpr(setDiff);
00661
00662 Expr iKid = A.orExpr(Bi);
00663 TRACE("core rewrite", "Bi = ", Bi, "");
00664 TRACE("core rewrite", "iKid = ", iKid, "");
00665
00666 Theorem thm0 = symmetryRule(rewriteOr(iKid));
00667 TRACE("core rewrite", "rewriteOr(iKid) = ", thm0.getLHS(), "");
00668 if(thm0.getLHS() != thm0.getRHS()) {
00669 DebugAssert(thm0.getLHS() == ee[j],
00670 "ee["+int2string(j)+"]="+ee[j].toString()
00671 +"\n thm0 = "+thm0.getExpr().toString());
00672 substThms.push_back(thm0);
00673 changed.push_back(j);
00674 }
00675 }
00676 Theorem t = substitutivityRule(ee, changed, substThms);
00677 thm = transitivityRule(thm, t);
00678 t = d_rules->andDistributivityRule(thm.getRHS());
00679 thm = transitivityRule(thm, t);
00680 DebugAssert(thm.getRHS().isOr() && thm.getRHS().arity()==2,
00681 "TheoryCore::rewrite[AND over OR]: thm = "
00682 +thm.getExpr().toString());
00683 t = rewrite(thm.getRHS()[0]);
00684 substThms.clear();
00685 changed.clear();
00686 if(t.getLHS() != t.getRHS()) {
00687 substThms.push_back(t);
00688 changed.push_back(0);
00689 }
00690 t = rewriteN(thm.getRHS()[1], 2);
00691 if(t.getLHS() != t.getRHS()) {
00692 substThms.push_back(t);
00693 changed.push_back(1);
00694 }
00695 if(changed.size()>0) {
00696 t = substitutivityRule(thm.getRHS(), changed, substThms);
00697 thm = transitivityRule(thm, t);
00698 }
00699 t = rewriteOr(thm.getRHS());
00700 thm = transitivityRule(thm, t);
00701 break;
00702 }
00703 case OR: {
00704 thm = rewriteOr(e);
00705 const Expr ee = thm.getRHS();
00706
00707
00708 if(!ee.isOr()) break;
00709
00710 TRACE("core rewrite", "rewrite[Core]: checking for (a&b) | (a&c) in ",
00711 ee, "");
00712
00713
00714 std::vector<Expr> setIntersect;
00715
00716 if(ee[0].isAnd())
00717 setIntersect = ee[0].getKids();
00718 else
00719 setIntersect.push_back(ee[0]);
00720 TRACE("core rewrite", "setIntersect = ",
00721 Expr(RAW_LIST, setIntersect, d_em), "");
00722 for(Expr::iterator i=ee.begin(),iend=ee.end();
00723 i!=iend && !setIntersect.empty();++i) {
00724 vector<Expr> Ai, result;
00725
00726 if(i->isAnd())
00727 Ai = i->getKids();
00728 else
00729 Ai.push_back(*i);
00730 TRACE("core rewrite", "Ai = ", Expr(RAW_LIST, Ai, d_em), "");
00731
00732 intersect(setIntersect,Ai,result);
00733 setIntersect = result;
00734 TRACE("core rewrite", "setIntersect = ",
00735 Expr(RAW_LIST, setIntersect, d_em), "");
00736 }
00737
00738 if(setIntersect.empty()) break;
00739
00740 Expr A = andExpr(setIntersect);
00741 TRACE("core rewrite", "A = ", A, "");
00742
00743 vector<Theorem> substThms;
00744 vector<unsigned> changed;
00745 int j(0);
00746 for(Expr::iterator i=ee.begin(),iend=ee.end();i!=iend; ++i, ++j) {
00747 vector<Expr> Ai, setDiff;
00748
00749 if(i->isAnd())
00750 Ai = i->getKids();
00751 else
00752 Ai.push_back(*i);
00753 TRACE("core rewrite", "Ai = ", Expr(RAW_LIST, Ai, d_em), "");
00754
00755 difference(Ai,setIntersect,setDiff);
00756 TRACE("core rewrite", "setDiff = ",
00757 Expr(RAW_LIST, setDiff, d_em), "");
00758 Expr Bi = (setDiff.empty())? d_em->trueExpr()
00759 : (setDiff.size()==1)? setDiff[0] : andExpr(setDiff);
00760
00761 Expr iKid = A.andExpr(Bi);
00762 TRACE("core rewrite", "Bi = ", Bi, "");
00763 TRACE("core rewrite", "iKid = ", iKid, "");
00764
00765 Theorem thm0 = symmetryRule(rewriteAnd(iKid));
00766
00767 if(thm0.getLHS() != thm0.getRHS()) {
00768 substThms.push_back(thm0);
00769 changed.push_back(j);
00770 }
00771 }
00772 Theorem t = substitutivityRule(ee, changed, substThms);
00773 thm = transitivityRule(thm, t);
00774 t = d_rules->orDistributivityRule(thm.getRHS());
00775 thm = transitivityRule(thm, t);
00776 DebugAssert(thm.getRHS().isAnd() && thm.getRHS().arity()==2,
00777 "TheoryCore::rewrite[OR over AND]: thm = "
00778 +thm.getExpr().toString());
00779 t = rewrite(thm.getRHS()[0]);
00780 substThms.clear();
00781 changed.clear();
00782 if(t.getLHS() != t.getRHS()) {
00783 substThms.push_back(t);
00784 changed.push_back(0);
00785 }
00786 t = rewriteN(thm.getRHS()[1], 2);
00787 if(t.getLHS() != t.getRHS()) {
00788 substThms.push_back(t);
00789 changed.push_back(1);
00790 }
00791 if(changed.size()>0) {
00792 t = substitutivityRule(thm.getRHS(), changed, substThms);
00793 thm = transitivityRule(thm, t);
00794 }
00795 t = rewriteAnd(thm.getRHS());
00796 thm = transitivityRule(thm, t);
00797 break;
00798 }
00799
00800 case FORALL:
00801 case EXISTS:
00802 thm = d_commonRules->reflexivityRule(e);
00803 break;
00804
00805 case AND_R:
00806 case IFF_R:
00807 case ITE_R:
00808 thm = reflexivityRule(e);
00809 break;
00810 default:
00811 DebugAssert(false,
00812 "TheoryCore::rewrite("
00813 + e.toString() + " : " + e.getType().toString()
00814 + "): Not implemented");
00815 break;
00816 }
00817
00818 DebugAssert(thm.getLHS() == e, "TheoryCore::rewrite("+e.toString()
00819 +") = "+thm.getExpr().toString());
00820
00821 Expr rhs = thm.getRHS();
00822
00823 switch(rhs.getKind()) {
00824 case AND:
00825 if(getFlags()["simp-and"].getBool()) {
00826 Theorem tmp(reflexivityRule(rhs));
00827 for(int i=0, iend=rhs.arity(); i<iend; ++i) {
00828 tmp = transitivityRule
00829 (tmp, d_rules->rewriteAndSubterms(tmp.getRHS(), i));
00830 }
00831 if(tmp.getRHS() != rhs) {
00832 thm = transitivityRule(thm, tmp);
00833 thm = transitivityRule(thm, simplifyRec(thm.getRHS()));
00834 rhs = thm.getRHS();
00835 }
00836 }
00837 break;
00838 case OR:
00839 if(getFlags()["simp-or"].getBool()) {
00840 Theorem tmp(reflexivityRule(rhs));
00841 for(int i=0, iend=rhs.arity(); i<iend; ++i) {
00842 tmp = transitivityRule
00843 (tmp, d_rules->rewriteOrSubterms(tmp.getRHS(), i));
00844 }
00845 if(tmp.getRHS() != rhs) {
00846 thm = transitivityRule(thm, tmp);
00847 thm = transitivityRule(thm, simplifyRec(thm.getRHS()));
00848 rhs = thm.getRHS();
00849 }
00850 }
00851 break;
00852 default:
00853 break;
00854 }
00855 if (theoryOf(rhs) == this) {
00856
00857 rhs.setRewriteNormal();
00858 }
00859 TRACE("core rewrite", "TheoryCore::rewrite => ", thm.getExpr(), " }");
00860 return thm;
00861 }
00862
00863
00864 Theorem TheoryCore::simplifyOp(const Expr& e) {
00865 TRACE("core simplifyOp", "TheoryCore::simplifyOp(", e, ") {");
00866 int kind(e.getKind());
00867 Theorem res;
00868
00869 if(getFlags()["ite-lift-unary"].getBool()
00870 && e.arity()==1 && e[0].isITE()) {
00871 res = d_rules->ifLiftUnaryRule(e);
00872 res = transitivityRule(res, simplifyOp(res.getRHS()));
00873 TRACE("core simplifyOp", "TheoryCore::simplifyOp[unary ite] => ",
00874 res.getExpr(), " }");
00875 return res;
00876 }
00877
00878 switch(kind) {
00879 case AND:
00880 case OR: {
00881
00882 int endKind = (kind==AND)? FALSE : TRUE;
00883 int ar = e.arity();
00884
00885
00886 int l(0);
00887 for(; l<ar && e[l].getKind() != endKind; ++l);
00888 if(l < ar) {
00889 IF_DEBUG(debugger.counter("simplified AND/OR topdown")++);
00890 if(kind==AND)
00891 res = rewriteAnd(e);
00892 else
00893 res = rewriteOr(e);
00894 break;
00895 }
00896 vector<Theorem> newChildrenThm;
00897 vector<unsigned> changed;
00898 for(int k = 0; k < ar; ++k) {
00899
00900 Theorem thm = simplifyRec(e[k]);
00901 if (thm.getLHS() != thm.getRHS()) {
00902 if (thm.getRHS().getKind() == endKind) {
00903 newChildrenThm.clear();
00904 changed.clear();
00905 newChildrenThm.push_back(thm);
00906 changed.push_back(k);
00907 thm = substitutivityRule(e, changed, newChildrenThm);
00908
00909 if(kind==AND)
00910 thm = transitivityRule(thm, rewriteAnd(thm.getRHS()));
00911 else
00912 thm = transitivityRule(thm, rewriteOr(thm.getRHS()));
00913 IF_DEBUG(debugger.counter("simplified AND/OR: skipped kids")
00914 += ar-k-1);
00915 TRACE("core simplifyOp",
00916 "TheoryCore::simplifyOp[TRUE/FALSE in OR/AND] => ",
00917 thm.getExpr(), " }");
00918 return thm;
00919 } else {
00920 newChildrenThm.push_back(thm);
00921 changed.push_back(k);
00922 }
00923 }
00924 }
00925 if(changed.size() > 0)
00926 res = substitutivityRule(e, changed, newChildrenThm);
00927 break;
00928 }
00929 case ITE: {
00930 DebugAssert(e.arity()==3, "Bad ITE in TheoryCore::simplify(e="
00931 +e.toString()+")");
00932
00933
00934 if(e[1]==e[2]) {
00935 res = d_rules->rewriteIteSame(e);
00936 res = transitivityRule(res, simplifyRec(res.getRHS()));
00937 IF_DEBUG(debugger.counter("simplified ITE(c,e,e)")++);
00938 break;
00939 }
00940
00941 vector<Theorem> newChildrenThm;
00942 vector<unsigned> changed;
00943 Theorem thm = simplifyRec(e[0]);
00944 if(thm.getLHS() != thm.getRHS()) {
00945 newChildrenThm.push_back(thm);
00946 changed.push_back(0);
00947 }
00948 const Expr& cond = thm.getRHS();
00949 for(int k=1; k<=2; ++k) {
00950
00951
00952 if((k==1 && cond.isFalse()) || (k==2 && cond.isTrue())) {
00953 IF_DEBUG(debugger.counter("simplified ITE: skiped one branch")++);
00954 continue;
00955 }
00956 thm = simplifyRec(e[k]);
00957 if(thm.getLHS() != thm.getRHS()) {
00958 newChildrenThm.push_back(thm);
00959 changed.push_back(k);
00960 }
00961 }
00962 if(changed.size() > 0)
00963 res = substitutivityRule(e, changed, newChildrenThm);
00964 break;
00965 }
00966 case NOT: {
00967 if(getFlags()["pushneg"].getBool()) {
00968 res = d_exprTrans->pushNegation1(e);
00969 if(res.getLHS() != res.getRHS())
00970
00971 res = transitivityRule(res, simplifyOp(res.getRHS()));
00972 else {
00973 res = Theory::simplifyOp(e);
00974
00975 Theorem thm = d_exprTrans->pushNegation1(res.getRHS());
00976 if(thm.getLHS() != thm.getRHS()) {
00977 thm = transitivityRule(thm, simplifyRec(thm.getRHS()));
00978 res = transitivityRule(res, thm);
00979 }
00980 }
00981 } else {
00982 res = Theory::simplifyOp(e);
00983 }
00984 break;
00985 }
00986 case IMPLIES:
00987 res = d_rules->rewriteImplies(e);
00988 res = transitivityRule(res, simplifyOp(res.getRHS()));
00989 break;
00990 default:
00991 res = Theory::simplifyOp(e);
00992 }
00993 if(res.isNull())
00994 res = reflexivityRule(e);
00995 TRACE("core simplifyOp", "TheoryCore::simplifyOp => ", res.getExpr(), " }");
00996 return res;
00997 }
00998
00999
01000
01001
01002
01003 void TheoryCore::setup(const Expr& e) { }
01004
01005
01006
01007
01008
01009 void TheoryCore::update(const Theorem& e, const Expr& d)
01010 {
01011 d_update_thms.push_back(e);
01012 d_update_data.push_back(d);
01013 }
01014
01015 void TheoryCore::processUpdates()
01016 {
01017 Theorem e;
01018 Expr d;
01019 DebugAssert(d_update_thms.size() == d_update_data.size(),
01020 "Expected same size");
01021 while (!d_update_thms.empty()) {
01022 e = d_update_thms.back();
01023 d_update_thms.pop_back();
01024 d = d_update_data.back();
01025 d_update_data.pop_back();
01026
01027 DebugAssert(d.isAbsAtomicFormula(), "Expected atomic formula");
01028 Theorem thm = simplify(d);
01029 if (thm.getRHS().isTrue()) {
01030 if (d.isImpliedLiteral()) continue;
01031 d.setImpliedLiteral();
01032 d_impliedLiterals.push_back(d_commonRules->iffTrueElim(thm));
01033 }
01034 else if (thm.getRHS().isFalse()) {
01035 Expr notd = !d;
01036 if (notd.isImpliedLiteral()) continue;
01037 notd.setImpliedLiteral();
01038 d_impliedLiterals.push_back(d_commonRules->iffFalseElim(thm));
01039 }
01040 else {
01041 DebugAssert(e.isRewrite(), "Unexpected theorem in TheoryCore::update");
01042 if (e.getRHS().getType().isBool()) continue;
01043 find(e.getRHS()).getRHS().addToNotify(this, d);
01044 if (thm.getRHS().isAbsAtomicFormula()) thm.getRHS().addToNotify(this, d);
01045 }
01046 }
01047 }
01048
01049
01050 Expr TheoryCore::computeTypePred(const Type& t, const Expr& e)
01051 {
01052 Expr tExpr = t.getExpr();
01053 switch(tExpr.getKind()) {
01054 case SUBTYPE: {
01055 Expr pred = tExpr[0];
01056
01057 while(pred.getKind()==CONSTDEF) pred = pred[1];
01058 const Type& argTp = pred.lookupType()[0];
01059 return Expr(pred.mkOp(), e).andExpr(getTypePred(argTp, e));
01060 }
01061 case APPLY: {
01062 Theory* i = theoryOf(e);
01063 if (i != this) return i->computeTypePred(t, e);
01064
01065 }
01066 default:
01067 return e.getEM()->trueExpr();
01068 }
01069 }
01070
01071
01072 void TheoryCore::checkType(const Expr& e)
01073 {
01074 switch (e.getKind()) {
01075 case BOOLEAN:
01076 if (e.arity() > 0) {
01077 throw Exception("Ill-formed Boolean type:\n\n"+e.toString());
01078 }
01079 break;
01080 case SUBTYPE: {
01081 if (e.arity() != 1)
01082 throw Exception("Ill-formed SUBTYPE expression:\n\n"+e.toString());
01083 Type t = e[0].getType();
01084 if (!t.isFunction())
01085 throw Exception
01086 ("Non-function argument to SUBTYPE:\n\n"
01087 +e.toString());
01088 if (!t[1].isBool())
01089 throw Exception
01090 ("Non-predicate argument to SUBTYPE:\n\n"
01091 +e.toString());
01092 }
01093 break;
01094 default:
01095 DebugAssert(false, "Unexpected kind in TheoryCore::checkType"
01096 +getEM()->getKindName(e.getKind()));
01097 }
01098 }
01099
01100
01101 void TheoryCore::computeType(const Expr& e)
01102 {
01103 switch (e.getKind()) {
01104 case ITE: {
01105 Type t1(getBaseType(e[1])), t2(getBaseType(e[2]));
01106 if (e[0].getType() != boolType())
01107 throw TypecheckException
01108 ("The conditional in IF-THEN-ELSE must be BOOLEAN, but is:\n\n"
01109 +e[0].getType().toString()
01110 +"\n\nIn the expression:\n\n "
01111 +e.toString());
01112 if(t1 != t2) {
01113 throw TypecheckException
01114 ("The types of the IF-THEN-ELSE branches do not match.\n"
01115 "THEN branch has the type:\n\n "
01116 +e[1].getType().toString()
01117 +"\n\nELSE branch has the type:\n\n "
01118 +e[2].getType().toString()
01119 +"\n\nIn expression:\n\n "+e.toString());
01120 }
01121 Type res(e[1].getType());
01122
01123
01124 if(res == e[2].getType()) {
01125 IF_DEBUG(if(res != t1)
01126 TRACE("ite", "ITE: setting type "+res.toString()
01127 +" to:\n\n ", e, ""));
01128 e.setType(res);
01129 }
01130 else
01131
01132
01133
01134 e.setType(t1);
01135 }
01136 break;
01137 case EQ: {
01138 Type t0(getBaseType(e[0])), t1(getBaseType(e[1]));
01139 if (t0.isBool() || t1.isBool()) {
01140 throw TypecheckException
01141 ("Cannot use EQ ('=') for BOOLEAN type; use IFF ('<=>') instead.\n"
01142 "Error in the following expression:\n"+e.toString());
01143 }
01144 if (t0 != t1) {
01145 throw TypecheckException
01146 ("Type mismatch in equality:\n\n LHS type:\n"+t0.toString()
01147 +"\n\n RHS type: \n"+t1.toString()
01148 +"\n\n in expression: \n"+e.toString());
01149 }
01150 e.setType(boolType());
01151 }
01152 break;
01153 case NOT:
01154 case AND:
01155 case OR:
01156 case XOR:
01157 case IFF:
01158 case IMPLIES:
01159
01160 case AND_R:
01161 case IFF_R:
01162 case ITE_R:
01163
01164 for (int k = 0; k < e.arity(); ++k) {
01165 if (e[k].getType() != boolType()) {
01166 throw TypecheckException(e.toString());
01167 }
01168 }
01169 e.setType(boolType());
01170 break;
01171 case CONSTDEF:
01172 case LETDECL: {
01173 Type varTp(getBaseType(e[0]));
01174 Type valTp(getBaseType(e[1]));
01175 if(valTp != varTp) {
01176 throw TypecheckException("Type mismatch for "+e[0].toString()+":"
01177 +"\n declared: "
01178 + varTp.toString()
01179 +"\n derived: "+ valTp.toString());
01180 }
01181 e.setType(e[0].getType());
01182 }
01183 break;
01184 default:
01185 DebugAssert(false,"TheoryCore::computeType(" + e.toString()
01186 + "):\nNot implemented");
01187 break;
01188 }
01189 }
01190
01191
01192 Type
01193 TheoryCore::computeBaseType(const Type& tp) {
01194 const Expr& e = tp.getExpr();
01195 Type res;
01196 switch(e.getKind()) {
01197 case SUBTYPE: {
01198 DebugAssert(e.arity() == 1, "Expr::computeBaseType(): "+e.toString());
01199 Type lambdaTp = e[0].getType();
01200 Type lambdaBaseTp = getBaseType(lambdaTp);
01201 DebugAssert(lambdaBaseTp.isFunction(),
01202 "Expr::computeBaseType(): lambdaBaseTp = "
01203 +lambdaBaseTp.toString()+" in e = "+e.toString());
01204 res = lambdaBaseTp[0];
01205 break;
01206 }
01207 case BOOLEAN:
01208 res = tp; break;
01209 case TYPEDEF:
01210 res = getBaseType(Type(e[1]));
01211 break;
01212 default:
01213 DebugAssert(false, "TheoryCore::computeBaseType("+tp.toString()+")");
01214 res = tp;
01215 }
01216 return res;
01217 }
01218
01219
01220 Expr
01221 TheoryCore::computeTCC(const Expr& e) {
01222 Expr res;
01223 switch (e.getKind()) {
01224 case NOT:
01225 res = getTCC(e[0]);
01226 break;
01227 case AND: {
01228
01229 vector<Expr> tccs;
01230 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
01231 tccs.push_back(getTCC(*i));
01232 vector<Expr> pairs;
01233 pairs.push_back(rewriteAnd(andExpr(tccs)).getRHS());
01234 for(size_t i=0, iend=tccs.size(); i<iend; ++i)
01235 pairs.push_back(rewriteAnd(tccs[i].andExpr(e[i].negate())).getRHS());
01236 res = rewriteOr(orExpr(pairs)).getRHS();
01237 break;
01238 }
01239 case OR: {
01240
01241 vector<Expr> tccs;
01242 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
01243 tccs.push_back(getTCC(*i));
01244 vector<Expr> pairs;
01245 pairs.push_back(rewriteAnd(andExpr(tccs)).getRHS());
01246 for(size_t i=0, iend=tccs.size(); i<iend; ++i)
01247 pairs.push_back(rewriteAnd(tccs[i].andExpr(e[i])).getRHS());
01248 res = rewriteOr(orExpr(pairs)).getRHS();
01249 break;
01250 }
01251 case ITE: {
01252 Expr tcc1(getTCC(e[1])), tcc2(getTCC(e[2]));
01253
01254 Expr tccITE((tcc1 == tcc2)? tcc1 : e[0].iteExpr(tcc1, tcc2));
01255 res = rewriteAnd(getTCC(e[0]).andExpr(tccITE)).getRHS();
01256 break;
01257 }
01258 case IMPLIES:
01259 res = getTCC(e[0].negate().orExpr(e[1]));
01260 break;
01261 case APPLY: {
01262 Theory* i = theoryOf(e);
01263 if (i != this) return i->computeTCC(e);
01264
01265 }
01266 default:
01267 res = Theory::computeTCC(e);
01268 break;
01269 }
01270 return res;
01271 }
01272
01273
01274
01275
01276
01277 ExprStream&
01278 TheoryCore::print(ExprStream& os, const Expr& e)
01279 {
01280 switch(os.lang()) {
01281 case PRESENTATION_LANG:
01282 switch(e.getKind()) {
01283 case TRUE:
01284 case FALSE:
01285 case UCONST:
01286 case BOOLEAN:
01287 case STRING_EXPR:
01288 e.print(os); break;
01289 case TYPE:
01290 if(e.arity() == 0) os << "TYPE";
01291 else if(e.arity() == 1)
01292 os << e[0] << ": TYPE;";
01293 else if(e.arity() == 2)
01294 os << e[0] << ":" << push << " TYPE = " << e[1] << push << ";";
01295 else e.printAST(os);
01296 break;
01297 case ID:
01298 if(e.arity() == 1 && e[0].isString()) os << e[0].getString();
01299 else e.printAST(os);
01300 break;
01301 case CONST:
01302 if(e.arity() == 2) {
01303 if(e[0].getKind() == RAW_LIST) {
01304 bool first(true);
01305 for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i) {
01306 if(first) first = false;
01307 else os << push << "," << pop << space;
01308 os << (*i);
01309 }
01310 }
01311 else
01312 os << e[0];
01313 os << ":" << push << space << e[1] << push << ";";
01314 } else if(e.arity() == 3)
01315 os << e[0] << ":" << push << space << e[1]
01316 << space << "=" << space << push << e[2] << push << ";";
01317 else
01318 e.printAST(os);
01319 break;
01320 case SUBTYPE:
01321 os << "SUBTYPE(" << push << e[0] << push << ")";
01322 break;
01323 case TYPEDEF: {
01324
01325
01326 if(e.arity() != 2) e.printAST(os);
01327 else if(e[0].isString()) os << e[0].getString();
01328 else e[0].print(os);
01329 break;
01330 }
01331 case EQ:
01332
01333
01334
01335
01336
01337
01338 os << "(" << push << e[0] << space << "= " << e[1] << push << ")";
01339 break;
01340 case NOT: os << "NOT " << e[0]; break;
01341 case AND: {
01342 int i=0, iend=e.arity();
01343 os << "(" << push;
01344 if(i!=iend) { os << e[i]; ++i; }
01345 for(; i!=iend; ++i) os << space << "AND " << e[i];
01346 os << push << ")";
01347 }
01348 break;
01349 case OR: {
01350 int i=0, iend=e.arity();
01351 os << "(" << push;
01352 if(i!=iend) { os << e[i]; ++i; }
01353 for(; i!=iend; ++i) os << space << "OR " << e[i];
01354 os << push << ")";
01355 }
01356 break;
01357 case ITE:
01358 os << push << "IF " << push << e[0] << popSave
01359 << space << "THEN " << pushRestore << e[1] << popSave
01360 << space << "ELSE " << pushRestore << e[2] << pop
01361 << space << "ENDIF";
01362 break;
01363 case IFF:
01364 if(e.arity() == 2)
01365 os << "(" << push << e[0] << space << "<=> " << e[1] << push << ")";
01366 else
01367 e.printAST(os);
01368 break;
01369 case IMPLIES:
01370 os << "(" << push << e[0] << space << "=> " << e[1] << push << ")";
01371 break;
01372
01373 case ASSERT:
01374 os << "ASSERT " << push << e[0] << push << ";";
01375 break;
01376 case TRANSFORM:
01377 os << "TRANSFORM " << push << e[0] << push << ";";
01378 break;
01379 case QUERY:
01380 os << "QUERY " << push << e[0] << push << ";";
01381 break;
01382 case WHERE:
01383 os << "WHERE;";
01384 break;
01385 case ASSERTIONS:
01386 os << "ASSERTIONS;";
01387 break;
01388 case ASSUMPTIONS:
01389 os << "ASSUMPTIONS;";
01390 break;
01391 case COUNTEREXAMPLE:
01392 os << "COUNTEREXAMPLE;";
01393 break;
01394 case COUNTERMODEL:
01395 os << "COUNTERMODEL;";
01396 break;
01397 case PUSH:
01398 if(e.arity()==0)
01399 os << "PUSH;";
01400 else
01401 os << "PUSH" << space << e[0] << push << ";";
01402 break;
01403 case POP:
01404 if(e.arity()==0)
01405 os << "POP;";
01406 else
01407 os << "POP" << space << e[0] << push << ";";
01408 break;
01409 case POPTO:
01410 os << "POPTO" << space << e[0] << push << ";"; break;
01411 case PUSH_SCOPE:
01412 if(e.arity()==0)
01413 os << "PUSH_SCOPE;";
01414 else
01415 os << "PUSH_SCOPE" << space << e[0] << push << ";";
01416 break;
01417 case POP_SCOPE:
01418 if(e.arity()==0)
01419 os << "POP_SCOPE;";
01420 else
01421 os << "POP_SCOPE" << space << e[0] << push << ";";
01422 break;
01423 case POPTO_SCOPE:
01424 os << "POPTO_SCOPE" << space << e[0] << push << ";"; break;
01425 case CONSTDEF:
01426 case LETDECL:
01427 if(e.arity() == 2) os << e[1];
01428 else e.printAST(os);
01429 break;
01430 case LET: {
01431
01432 bool first(true);
01433 os << "(" << push << "LET" << space << push;
01434 for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i) {
01435 if(!first) os << push << "," << pop << endl;
01436 else first = false;
01437 if(i->arity() == 3) {
01438 os << (*i)[0] << ":" << space << push << (*i)[1]
01439 << space << "= " << push << nodag << (*i)[2] << pop << pop;
01440 } else {
01441 os << (*i)[0];
01442 Type tp((*i)[0].lookupType());
01443 if(!tp.isNull()) os << ":" << space << push << tp.getExpr();
01444 else os << push;
01445 os << space << "= " << push << nodag << (*i)[1] << pop << pop;
01446 }
01447 }
01448 os << pop << endl << "IN" << space << push << e[1] << push << ")";
01449 break;
01450 }
01451 case BOUND_VAR:
01452 os << e.getName()+"_"+e.getUid();
01453 break;
01454 case SKOLEM_VAR:
01455 os << "SKOLEM_" + int2string(e.getIndex());
01456 break;
01457 case PF_APPLY:
01458 DebugAssert(e.arity() > 0, "TheoryCore::print(): "
01459 "Proof rule application must have at "
01460 "least one argument (rule name):\n "+e.toString());
01461 os << e[0];
01462 if(e.arity() > 1) {
01463 os << push << "(" << push;
01464 bool first(true);
01465 for(int i=1; i<e.arity(); i++) {
01466 if(first) first=false;
01467 else os << push << "," << pop << space;
01468 os << e[i];
01469 }
01470 os << push << ")";
01471 }
01472 break;
01473 case RAW_LIST: {
01474 os << "[" << push;
01475 bool firstTime(true);
01476 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
01477 if(firstTime) firstTime = false;
01478 else os << push << "," << pop << space;
01479 os << *i;
01480 }
01481 os << push << "]";
01482 break;
01483 }
01484 case PF_HOLE:
01485 default:
01486
01487
01488 e.printAST(os);
01489 }
01490 break;
01491 case SMTLIB_LANG:
01492 switch(e.getKind()) {
01493 case TRUE: os << "true"; break;
01494 case FALSE: os << "false"; break;
01495 case UCONST: e.print(os); break;
01496 case BOOLEAN: e.printAST(os); break;
01497 case STRING_EXPR: e.print(os); break;
01498 case TYPE:
01499 if (e.arity() == 1) {
01500 os << " :extrasorts (";
01501 for (int i=0; i < e[0].arity(); ++i) {
01502 if (i != 0) os << push << space;
01503 os << push << e[0][i];
01504 }
01505 os << push << ")";
01506 }
01507 else if (e.arity() == 2) {
01508 break;
01509 }
01510 else {
01511 throw SmtlibException("TheoryCore::print: SMTLIB: Unexpected TYPE expression");
01512 }
01513 break;
01514 case ID:
01515 if(e.arity() == 1 && e[0].isString()) os << e[0].getString();
01516 else e.printAST(os);
01517 break;
01518 case CONST:
01519 if(e.arity() == 2) {
01520 if (e[1].getKind() == BOOLEAN) {
01521 os << " :extrapreds ((" << push << e[0]
01522 << push << "))";
01523 }
01524 else if (e[1].getKind() == ARROW && e[1][e[1].arity()-1].getKind() == BOOLEAN) {
01525 os << " :extrapreds ((" << push << e[0]
01526 << space << e[1] << push << "))";
01527 }
01528 else {
01529 os << " :extrafuns ((" << push << e[0]
01530 << space << e[1] << push << "))";
01531 }
01532 }
01533 else if (e.arity() == 0) e.printAST(os);
01534 else {
01535 throw SmtlibException("TheoryCore::print: SMTLIB: CONST not implemented");
01536 }
01537 break;
01538 case SUBTYPE:
01539 throw SmtlibException("TheoryCore::print: SMTLIB: SUBTYPE not implemented");
01540 break;
01541 case TYPEDEF: {
01542 throw SmtlibException("TheoryCore::print: SMTLIB: TYPEDEF not implemented");
01543 break;
01544 }
01545 case EQ:
01546 os << "(" << push << "=" << space << e[0]
01547 << space << e[1] << push << ")";
01548 break;
01549 case NOT:
01550 os << "(" << push << "not" << space << e[0] << push << ")";
01551 break;
01552 case AND: {
01553 int i=0, iend=e.arity();
01554 os << "(" << push << "and";
01555 for(; i!=iend; ++i) os << space << e[i];
01556 os << push << ")";
01557 }
01558 break;
01559 case OR: {
01560 int i=0, iend=e.arity();
01561 os << "(" << push << "or";
01562 for(; i!=iend; ++i) os << space << e[i] << space;
01563 os << push << ")";
01564 break;
01565 }
01566 case XOR: {
01567 int i=0, iend=e.arity();
01568 os << "(" << push << "xor";
01569 for(; i!=iend; ++i) os << space << e[i] << space;
01570 os << push << ")";
01571 break;
01572 }
01573 case ITE:
01574 os << "(" << push;
01575 if (e.getType().isBool()) os << "if_then_else";
01576 else os << "ite";
01577 os << space << e[0]
01578 << space << e[1] << space << e[2] << push << ")";
01579 break;
01580 case IFF:
01581 os << "(" << push << "iff" << space
01582 << e[0] << space << e[1] << push << ")";
01583 break;
01584 case IMPLIES:
01585 os << "(" << push << "implies" << space
01586 << e[0] << space << e[1] << push << ")";
01587 break;
01588
01589 case ASSERT:
01590
01591 os << "(" << push << "ASSERT" << space << e[0] << push << ")";
01592 break;
01593 case TRANSFORM:
01594 throw SmtlibException("TheoryCore::print: SMTLIB: TRANSFORM not implemented");
01595 os << "(" << push << "TRANSFORM" << space << e[0] << push << ")";
01596 break;
01597 case QUERY:
01598 throw SmtlibException("TheoryCore::print: SMTLIB: QUERY not implemented");
01599 os << "(" << push << "QUERY" << space << e[0] << push << ")";
01600 break;
01601 case CONSTDEF:
01602 case LETDECL:
01603
01604 if(e.arity() == 2) os << e[1];
01605 else e.printAST(os);
01606 break;
01607 case LET: {
01608
01609 for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i) {
01610 os << "(" << push;
01611 Type tp(i->arity() == 3 ? (*i)[2].getType() : (*i)[1].getType());
01612 DebugAssert(!tp.isNull(), "Unexpected Null type");
01613 if (tp.getExpr().getKind() == BOOLEAN) {
01614 os << "flet" << space << "(" << push;
01615 }
01616 else {
01617 os << "let" << space << "(" << push;
01618 }
01619 if(i->arity() == 3) {
01620 os << (*i)[0] << space << nodag << (*i)[2];
01621 } else {
01622 os << (*i)[0] << space << nodag << (*i)[1];
01623 }
01624 os << push << ")" << pop << pop << space;
01625 }
01626 os << e[1] << push;
01627 for (int j = 0; j < e[0].arity(); ++j)
01628 os << ")";
01629 break;
01630 }
01631 case BOUND_VAR:
01632 os << e.getName()+"_"+e.getUid();
01633 break;
01634 case SKOLEM_VAR:
01635 os << "SKOLEM_" + int2string(e.getIndex());
01636 break;
01637 case PF_APPLY: {
01638 throw SmtlibException("TheoryCore::print: SMTLIB: PF_APPLY not implemented");
01639 break;
01640 }
01641 case RAW_LIST: {
01642 os << "(" << push;
01643 bool firstTime(true);
01644 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
01645 if(firstTime) firstTime = false;
01646 else os << space;
01647 os << *i;
01648 }
01649 os << push << ")";
01650 break;
01651 }
01652 case PUSH:
01653 case POP:
01654 case POPTO:
01655 case PUSH_SCOPE:
01656 case POP_SCOPE:
01657 case POPTO_SCOPE:
01658 throw SmtlibException("TheoryCore::print: SMTLIB: Stack operations not implemented");
01659 break;
01660 case PF_HOLE:
01661 default:
01662 throw SmtlibException("TheoryCore::print: SMTLIB_LANG: Unexpected expression: "
01663 +getEM()->getKindName(e.getKind()));
01664 }
01665 break;
01666 case LISP_LANG:
01667 switch(e.getKind()) {
01668 case TRUE:
01669 case FALSE:
01670 case UCONST:
01671 e.print(os); break;
01672 case TYPE:
01673 if(e.arity() == 0) os << "TYPE";
01674 else if(e.arity() == 1)
01675 os << "(" << push << "TYPE" << space << e[0] << push << ")";
01676 else if(e.arity() == 2)
01677 os << "(" << push << "TYPE" << space << e[0]
01678 << space << e[1] << push << ")";
01679 else e.printAST(os);
01680 break;
01681 case ID:
01682 if(e.arity() == 1 && e[0].isString()) os << e[0].getString();
01683 else e.printAST(os);
01684 break;
01685 case CONST:
01686 if(e.arity() == 2)
01687 os << "(" << push << "CONST" << space << e[0]
01688 << space << e[1] << push << ")";
01689 else
01690 e.printAST(os);
01691 break;
01692 case SUBTYPE:
01693 os << "SUBTYPE(" << push << e[0] << push << ")";
01694 break;
01695 case TYPEDEF: {
01696
01697
01698 if(e.arity() != 2) e.printAST(os);
01699 else if(e[0].isString()) os << e[0].getString();
01700 else e[0].print(os);
01701 break;
01702 }
01703 case EQ:
01704
01705
01706
01707
01708
01709
01710 os << "(" << push << "=" << space << e[0]
01711 << space << e[1] << push << ")";
01712 break;
01713 case NOT:
01714 os << "(" << push << "NOT" << space << e[0] << push << ")";
01715 break;
01716 case AND: {
01717 int i=0, iend=e.arity();
01718 os << "(" << push << "AND";
01719 for(; i!=iend; ++i) os << space << e[i];
01720 os << push << ")";
01721 }
01722 break;
01723 case OR: {
01724 int i=0, iend=e.arity();
01725 os << "(" << push << "OR";
01726 for(; i!=iend; ++i) os << space << e[i] << space;
01727 os << push << ")";
01728 }
01729 break;
01730 case ITE:
01731 os << "(" << push << "IF" << space << e[0]
01732 << space << e[1] << space << e[2] << push << ")";
01733 break;
01734 case IFF:
01735 os << "(" << push << "<=>" << space
01736 << e[0] << space << e[1] << push << ")";
01737 break;
01738 case IMPLIES:
01739 os << "(" << push << "=>" << space
01740 << e[0] << space << e[1] << push << ")";
01741 break;
01742
01743 case ASSERT:
01744 os << "(" << push << "ASSERT" << space << e[0] << push << ")";
01745 break;
01746 case TRANSFORM:
01747 os << "(" << push << "TRANSFORM" << space << e[0] << push << ")";
01748 break;
01749 case QUERY:
01750 os << "(" << push << "QUERY" << space << e[0] << push << ")";
01751 break;
01752 case PUSH:
01753 os << "(PUSH)"; break;
01754 case POP:
01755 os << "(POP)"; break;
01756 case POPTO:
01757 os << "(" << push << "POPTO" << space << e[0] << push << ")"; break;
01758 case CONSTDEF:
01759 case LETDECL:
01760 if(e.arity() == 2) os << e[1];
01761 else if(e.arity()==3)
01762 os << e[0] << push << ":" << space << push << e[1] << push << " ="
01763 << pop << pop << space << e[2];
01764 else e.printAST(os);
01765 break;
01766 case LET: {
01767
01768 bool first(true);
01769 os << "(" << push << "LET" << space << "(" << push;
01770 for(Expr::iterator i=e[0].begin(), iend=e[0].end(); i!=iend; ++i) {
01771 if(!first) os << space;
01772 else first = false;
01773 os << "(" << push;
01774 if(i->arity() == 3) {
01775 os << (*i)[0] << space << (*i)[1]
01776 << space << nodag << (*i)[2];
01777 } else {
01778 os << (*i)[0];
01779 Type tp((*i)[0].lookupType());
01780 if(!tp.isNull()) os << space << tp.getExpr();
01781 os << space << nodag << (*i)[1];
01782 }
01783 os << push << ")" << pop << pop;
01784 }
01785 os << push << ")" << pop << pop << space << e[1] << push << ")";
01786 break;
01787 }
01788 case BOUND_VAR:
01789 os << e.getName()+"_"+e.getUid();
01790 break;
01791 case SKOLEM_VAR:
01792 os << "SKOLEM_" + int2string(e.getIndex());
01793 break;
01794 case PF_APPLY: {
01795 DebugAssert(e.arity() > 0, "TheoryCore::print(): "
01796 "Proof rule application must have at "
01797 "least one argument (rule name):\n "+e.toString());
01798 os << push << "(" << push;
01799 bool first(true);
01800 for(int i=0; i<e.arity(); i++) {
01801 if(first) first=false;
01802 else os << space;
01803 os << e[i];
01804 }
01805 os << push << ")";
01806 break;
01807 }
01808 case RAW_LIST: {
01809 os << "(" << push;
01810 bool firstTime(true);
01811 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
01812 if(firstTime) firstTime = false;
01813 else os << space;
01814 os << *i;
01815 }
01816 os << push << ")";
01817 break;
01818 }
01819 case PF_HOLE:
01820 default:
01821
01822
01823 e.printAST(os);
01824 }
01825 break;
01826 default:
01827
01828
01829 e.printAST(os);
01830 }
01831 return os;
01832 }
01833
01834
01835
01836
01837
01838 Expr TheoryCore::parseExpr(const Expr& e) {
01839 TRACE("parseExpr", "parseExpr(", e, ") {");
01840
01841 size_t boundVarSize = d_boundVarStack.size();
01842 TRACE("parseExpr", "#bound vars = ", d_boundVarStack.size(), "");
01843
01844
01845 int kind = NULL_KIND;
01846
01847 switch(e.getKind()) {
01848 case ID: {
01849 TRACE("parser verbose", "resolving variable/operator(", e[0], ")");
01850 const Expr c1 = e[0];
01851 kind = getEM()->getKind(c1.getString());
01852 if(kind == NULL_KIND) {
01853 Expr res = resolveID(e[0].getString());
01854 if(res.isNull())
01855 throw ParserException("cannot resolve an identifier: "
01856 +e[0].toString());
01857 else {
01858 TRACE("parseExpr", "#bound vars = ", d_boundVarStack.size(), "");
01859 TRACE("parseExpr", "parseExpr => ", res, " }");
01860 DebugAssert(!e.isApply(), "Unexpected apply function");
01861 return res;
01862 }
01863 }
01864
01865 break;
01866 }
01867 case RAW_LIST: {
01868 TRACE("parser verbose", "constructing Expr from list(", e, ")");
01869 if(e.arity() == 0)
01870 throw ParserException("Empty list is not an expression!");
01871 const Expr& op = e[0];
01872
01873 switch(op.getKind()) {
01874 case ID: {
01875 kind = getEM()->getKind(op[0].getString());
01876 if(kind == NULL_KIND) {
01877
01878 Expr res = resolveID(op[0].getString());
01879 if(res.isNull())
01880 throw ParserException("cannot resolve an identifier: "
01881 +op[0].toString());
01882 if(e.arity() < 2)
01883 throw ParserException("Bad function application: "+e.toString());
01884 Expr::iterator i=e.begin(), iend=e.end();
01885 ++i;
01886 vector<Expr> args;
01887 for(; i!=iend; ++i) args.push_back(parseExpr(*i));
01888 return Expr(res.mkOp(), args);
01889 }
01890
01891 break;
01892 }
01893 case RAW_LIST:
01894
01895 kind = LAMBDA;
01896 break;
01897 default:
01898 throw ParserException("Bad operator in "+e.toString());
01899 }
01900 break;
01901 }
01902 default:
01903 TRACE("parseExpr", "parseExpr => ", e, " }");
01904 return e;
01905 }
01906
01907
01908 if(hasTheory(kind)) {
01909 TRACE("parseExpr", "parseExprOp["+theoryOf(kind)->getName()+"](",
01910 e, ") {");
01911 Expr res = theoryOf(kind)->parseExprOp(e);
01912 TRACE("parseExpr",
01913 "parseExprOp["+theoryOf(kind)->getName()+"] => ", res, " }");
01914 TRACE("parseExpr", "#bound vars = ", d_boundVarStack.size(), "");
01915
01916 while(d_boundVarStack.size() > boundVarSize) {
01917 TRACE("parseExpr", "Pop bound var "+d_boundVarStack.back().first+": ",
01918 d_boundVarStack.back().second, "");
01919 d_boundVarStack.pop_back();
01920 }
01921 TRACE("parseExpr", "#bound vars = ", d_boundVarStack.size(), "");
01922 TRACE("parseExpr", "parseExpr => ", res, " }");
01923 return res;
01924 }
01925 else {
01926 TRACE("parseExpr", "parseExpr => ", e, " }");
01927 return e;
01928 }
01929 }
01930
01931
01932 Expr TheoryCore::processCond(const Expr& e, int i) {
01933 DebugAssert(i < e.arity()-1, "e = "+e.toString()+", i = "+int2string(i));
01934 if(i == e.arity()-2) {
01935 if(e[i].getKind() == RAW_LIST && e[i].arity() == 2
01936 && e[i+1].getKind() == RAW_LIST && e[i+1].arity() == 2
01937 && e[i+1][0].getKind() == ID && e[i+1][0][0].getString() == "ELSE") {
01938 Expr c(parseExpr(e[i][0]));
01939 Expr e1(parseExpr(e[i][1]));
01940 Expr e2(parseExpr(e[i+1][1]));
01941 return c.iteExpr(e1,e2);
01942 }
01943 } else {
01944 if(e[i].getKind() == RAW_LIST && e[i].arity() == 2
01945 && e[i+1].getKind() == RAW_LIST && e[i+1].arity() == 2) {
01946 Expr c(parseExpr(e[i][0]));
01947 Expr e1(parseExpr(e[i][1]));
01948 Expr e2(processCond(e, i+1));
01949 return c.iteExpr(e1,e2);
01950 }
01951 }
01952 throw ParserException("Parse Error: bad COND expression: "+e.toString());
01953 }
01954
01955
01956
01957
01958
01959
01960 Expr
01961 TheoryCore::parseExprOp(const Expr& e) {
01962 TRACE("parser", "TheoryCore::parseExprOp(", e, ")");
01963
01964
01965 switch(e.getKind()) {
01966 case ID: {
01967 int kind = getEM()->getKind(e[0].getString());
01968 switch(kind) {
01969 case NULL_KIND: return e;
01970 case TRUE:
01971 case FALSE:
01972 case TYPE:
01973 case BOOLEAN: return getEM()->newLeafExpr(kind);
01974 default:
01975 DebugAssert(false, "Bad use of bare keyword: "+e.toString());
01976 return e;
01977 }
01978 }
01979 case RAW_LIST: break;
01980 default:
01981 return e;
01982 }
01983 DebugAssert(e.getKind()==RAW_LIST && e.arity() > 0 && e[0].getKind()==ID,
01984 "TheoryCore::parseExprOp:\n e = "+e.toString());
01985
01986
01987 const Expr& c1 = e[0][0];
01988 int kind = getEM()->getKind(c1.getString());
01989 TRACE("parser verbose", "building kind(", kind, ")");
01990 switch(kind) {
01991 case VARDECLS:
01992 case LETDECLS:
01993 case HELP:
01994 case DUMP_PROOF:
01995 case DUMP_ASSUMPTIONS:
01996 case DUMP_SIG:
01997 case DUMP_TCC:
01998 case DUMP_TCC_ASSUMPTIONS:
01999 case DUMP_TCC_PROOF:
02000 case DUMP_CLOSURE:
02001 case DUMP_CLOSURE_PROOF:
02002 case WHERE:
02003 case ASSERTIONS:
02004 case ASSUMPTIONS:
02005 case COUNTEREXAMPLE:
02006 case COUNTERMODEL:
02007 case ASSERT:
02008 case PRINT:
02009 case QUERY:
02010 case CHECKSAT:
02011 case CONTINUE:
02012 case RESTART:
02013 case TRACE:
02014 case ECHO:
02015 case UNTRACE:
02016 case VARLIST:
02017 case SUBTYPE:
02018 case FORGET:
02019 case GET_TYPE:
02020 case IFF:
02021 case IMPLIES:
02022 case TYPEDEF:
02023 case OPTION:
02024 case AND:
02025 case OR:
02026 case XOR:
02027 case NOT:
02028 case EQ:
02029 case CALL:
02030 case TRANSFORM:
02031 case CHECK_TYPE:
02032 case VARDECL:
02033 case GET_CHILD:
02034 case SUBSTITUTE:
02035 case SEQ:
02036 case CONSTDEF:
02037 case DBG:
02038 case PUSH:
02039 case POP:
02040 case POPTO:
02041 case PUSH_SCOPE:
02042 case POP_SCOPE:
02043 case POPTO_SCOPE:
02044 case LETDECL:
02045 case ELSE:
02046 case CONTEXT:{
02047 vector<Expr> k;
02048 Expr::iterator i = e.begin(), iend=e.end();
02049
02050
02051 ++i;
02052
02053 for(; i!=iend; ++i)
02054 k.push_back(parseExpr(*i));
02055 return Expr(kind, k, e.getEM());
02056 }
02057 case NEQ:
02058 if(e.arity()==3)
02059 return !(parseExpr(e[1]).eqExpr(parseExpr(e[2])));
02060 else
02061 throw ParserException("Disequality requires exactly two arguments: "
02062 +e.toString());
02063 break;
02064 case CONST: {
02065 if(e.arity()==3) {
02066 vector<Expr> names;
02067 const Expr& vars = e[1];
02068 if(vars.getKind() == RAW_LIST) {
02069 for(Expr::iterator i=vars.begin(), iend=vars.end(); i!=iend; ++i)
02070 names.push_back(*i);
02071 } else if(vars.getKind() == ID)
02072 names.push_back(vars);
02073 return Expr(CONST, Expr(RAW_LIST, names, getEM()),
02074 parseExpr(e[2]));
02075 }
02076 else if(e.arity() == 4 && e[1].getKind() == ID)
02077 return Expr(CONSTDEF, e[1],
02078 parseExpr(e[2]), parseExpr(e[3]));
02079 throw ParserException("Bad CONST declaration: "+e.toString());
02080 break;
02081 }
02082 case TYPE: {
02083 if(e.arity()==2) {
02084 const Expr& types = e[1];
02085 if(types.getKind() == RAW_LIST) {
02086 vector<Expr> names;
02087 for(Expr::iterator i=types.begin(), iend=types.end(); i!=iend; ++i)
02088 names.push_back(*i);
02089 return Expr(TYPEDECL, names, getEM());
02090 }
02091 }
02092 else if(e.arity() == 3 && e[1].getKind() == ID)
02093 return Expr(TYPEDEF, e[1], parseExpr(e[2]));
02094 throw ParserException("Bad TYPE declaration: "+e.toString());
02095 break;
02096 }
02097 case IF:
02098 if(e.arity() == 4) {
02099 Expr c(parseExpr(e[1]));
02100 Expr e1(parseExpr(e[2]));
02101 Expr e2(parseExpr(e[3]));
02102 return c.iteExpr(e1, e2);
02103 } else
02104 throw ParserException("Bad IF-THEN-ELSE expression: "
02105 +e.toString());
02106 case COND: {
02107 if(e.arity() >= 3)
02108 return processCond(e, 1);
02109 else
02110 throw ParserException("Bad COND expression: "+e.toString());
02111 break;
02112 }
02113 case LET: {
02114 if(!(e.arity() == 3 && e[1].getKind() == RAW_LIST && e[1].arity() > 0))
02115 throw ParserException("Bad LET expression: "+e.toString());
02116
02117
02118 for(Expr::iterator i=e[1].begin(), iend=e[1].end(); i!=iend; ++i) {
02119 const Expr& decl = *i;
02120 if(decl.getKind() != RAW_LIST
02121 || !(decl.arity() == 2 || decl.arity() == 3))
02122 throw ParserException("Bad variable declaration block in LET "
02123 "expression: "+decl.toString()+
02124 "\n e = "+e.toString());
02125 if(decl[0].getKind() != ID)
02126 throw ParserException("Variable must be an identifier in LET "
02127 "expression: "+decl[0].toString()+
02128 "\n e = "+e.toString());
02129 Type type;
02130 Expr def;
02131 if(decl.arity()==3) {
02132 type = Type(parseExpr(decl[1]));
02133 def = parseExpr(decl[2]);
02134 } else
02135 def = parseExpr(decl[1]);
02136 addBoundVar(decl[0][0].getString(), type, def);
02137 }
02138
02139 return parseExpr(e[2]);
02140 }
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153 case TRUE: { return e.getEM()->trueExpr(); }
02154 case FALSE: { return e.getEM()->falseExpr();}
02155 case BOOLEAN: { return e.getEM()->boolExpr(); }
02156 break;
02157 default:
02158 DebugAssert(false,
02159 "TheoryCore::parseExprOp: invalid command or expression: "
02160 + e.toString());
02161 break;
02162 }
02163 return e;
02164 }
02165
02166
02167
02168
02169
02170
02171 void TheoryCore::processFactQueue() {
02172 Theorem thm;
02173 int i;
02174 do {
02175 while (!d_queue.empty() && !d_inconsistent) {
02176 thm = d_queue.front();
02177 d_queue.pop();
02178 assertFactCore(thm);
02179 }
02180 if (d_inconsistent) {
02181 while(d_queue.size()) d_queue.pop();
02182 d_queueSE.clear();
02183 TRACE_MSG("facts addFact", "addFact[top level] => (inconsistent) }");
02184 return;
02185 }
02186 IF_DEBUG(debugger.counter("DP checkSAT calls")++);
02187 for(i=0; i<getNumTheories() && !d_inconsistent && d_queue.empty(); ++i) {
02188 TRACE("facts checkSat", "checkSat[", d_theories[i]->getName(), "]() {");
02189 d_theories[i]->checkSat(false);
02190 TRACE("facts checkSat", "checkSat[", d_theories[i]->getName(), "]() => }");
02191 }
02192
02193
02194 if(d_queue.empty()) {
02195 TRACE_MSG("facts addFact",
02196 "TheoryCore::processFactQueue(): flushing queueSE");
02197
02198
02199
02200 while(!d_queueSE.empty()) {
02201
02202
02203 Theorem thm(d_queueSE.back());
02204 d_queueSE.pop_back();
02205 d_coreSatAPI->addLemma(thm);
02206 }
02207 }
02208 } while (!d_queue.empty());
02209 }
02210
02211
02212 #ifdef DEBUG
02213 static void checkRewriteType(TheoryCore* core, const Theorem& thm) {
02214 Type t1(core->getBaseType(thm.getLHS()));
02215 Type t2(core->getBaseType(thm.getRHS()));
02216 DebugAssert(t1 == t2, "TheoryCore::rewriteCore: type-unsafe rewrite:\n"
02217 "type1 = "+t1.toString()+"\ntype2 = "+t2.toString()+"\n\n"
02218 +thm.toString());
02219 }
02220 #endif
02221
02222
02223
02224
02225
02226
02227
02228 void TheoryCore::setInconsistent(const Theorem& e) {
02229 TRACE("setInconsistent", "setInconsistent(", e, ") {");
02230 d_inconsistent = true; d_incThm = e;
02231 d_queueSE.clear();
02232
02233 for(int i=1; i<getNumTheories(); ++i) {
02234 TRACE("facts notifyInconsistent", "notifyInconsistent[", d_theories[i]->getName(), "]() {");
02235 d_theories[i]->notifyInconsistent(e);
02236 TRACE("facts notifyInconsistent", "notifyInconsistent[", d_theories[i]->getName(), "]() => }");
02237 }
02238 TRACE_MSG("setInconsistent", "setInconsistent => }");
02239 }
02240
02241
02242 void TheoryCore::enqueueFact(const Theorem& e) {
02243 TRACE("enqueueFact", "enqueueFact[Core](", e.getExpr(), ")");
02244
02245 DebugAssert(e.getScope() <= d_cm->scopeLevel(),
02246 "\n e.getScope()="+int2string(e.getScope())
02247 +"\n scopeLevel="+int2string(d_cm->scopeLevel())
02248 +"\n e = "+e.getExpr().toString());
02249 DebugAssert(d_inAddFact || d_inCheckSATCore || d_inRegisterAtom,
02250 "enqueueFact() is called outside of addFact()"
02251 " or checkSATCore() or registerAtom()");
02252
02253 if(inconsistent()) return;
02254
02255 IF_DEBUG(if(*d_dumpTrace != "")
02256 dumpTrace(e.getExpr(), "enqueueFact"));
02257
02258 DebugAssert(e.getScope() <= d_cm->scopeLevel(),
02259 "\n e.getScope()="+int2string(e.getScope())
02260 +"\n scopeLevel="+int2string(d_cm->scopeLevel())
02261 +"\n e = "+e.getExpr().toString());
02262 if(!e.isRewrite() && e.getExpr().isFalse()) {
02263 IF_DEBUG(debugger.counter("conflicts enqueued from DPs")++);
02264 setInconsistent(e);
02265 } else if(getResource()) {
02266 d_queue.push(e);
02267 } else {
02268
02269
02270 setIncomplete("Exhausted user-specified resource");
02271 }
02272 }
02273
02274
02275 void TheoryCore::addFact(const Theorem& e)
02276 {
02277 TRACE("facts addFact", "addFact[top level](", e, ") {");
02278 DebugAssert(!d_inAddFact, "Recursive call to addFact() is not allowed");
02279 DebugAssert(d_queue.empty(), "addFact[start]: Expected empty queue");
02280 DebugAssert(d_queueSE.empty(), "addFact[start]: Expected empty queue");
02281 DebugAssert(d_update_thms.empty() && d_update_data.empty(),
02282 "adFact[start]: Expected empty update list");
02283 IF_DEBUG(ScopeWatcher sw(&d_inAddFact));
02284 IF_DEBUG(if(*d_dumpTrace != "") dumpTrace(e.getExpr(), "addFact"));
02285
02286 if(!d_inconsistent) enqueueFact(e);
02287
02288 processFactQueue();
02289
02290 DebugAssert(d_queue.empty(), "addFact[end]: Expected empty queue");
02291 DebugAssert(d_queueSE.empty(), "addFact[end]: Expected empty queue");
02292
02293 TRACE_MSG("facts addFact", "addFact[top level] => }");
02294 }
02295
02296
02297 void TheoryCore::assertFactCore(const Theorem& e)
02298 {
02299 TRACE("facts assertFact", "assertFactCore(", e, ") {");
02300 const Expr& e2 = e.getExpr();
02301 Theorem equiv = simplify(e2);
02302
02303 Theorem estarThm(iffMP(e, equiv));
02304 Expr estar = estarThm.getExpr();
02305
02306 if(estar.isExists()) {
02307 Theorem sk(d_commonRules->skolemize(estarThm));
02308 enqueueFact(sk);
02309 TRACE("skolem", "assertFactCore: created Skolemized assumption:\n ",
02310 sk.getExpr(), "");
02311 }
02312
02313
02314 if(e2 != estar && !e2.isTrue() && e2.isAbsLiteral())
02315 setFindLiteral(e, true);
02316
02317 if(estar.isAnd()) {
02318 for(int i=0,iend=estar.arity(); i<iend; ++i)
02319 assertFactCore(d_commonRules->andElim(estarThm, i));
02320 TRACE_MSG("facts assertFact", "assertFactCore[AND] => }");
02321 return;
02322 }
02323
02324 if (estar.isAbsLiteral()) {
02325 if (estar.isEq()) {
02326
02327 enqueueSE(estarThm);
02328 Theorem solvedThm(solve(estarThm));
02329
02330 if(estar != solvedThm.getExpr()) setFindLiteral(estarThm, false);
02331 assertEqualities(solvedThm);
02332 }
02333 else if (estar.isFalse()) {
02334 IF_DEBUG(debugger.counter("conflicts from simplifier")++);
02335 setInconsistent(estarThm);
02336 }
02337 else if (!estar.isTrue()) {
02338 assertFormula(estarThm);
02339 processUpdates();
02340 }
02341 } else {
02342
02343 enqueueSE(estarThm);
02344 }
02345
02346 DebugAssert(!e2.isAbsLiteral() || e2.hasFind()
02347 || (e2.isNot() && e2[0].hasFind()),
02348 "assertFactCore: e2 = "+e2.toString());
02349 DebugAssert(!estar.isAbsLiteral() || estar.hasFind()
02350 || (estar.isNot() && estar[0].hasFind()),
02351 "assertFactCore: estar = "+estar.toString());
02352 TRACE_MSG("facts assertFact", "assertFactCore => }");
02353 }
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368 void TheoryCore::assertEqualities(const Theorem& e)
02369 {
02370 TRACE("facts eq", "assertEqualities(", e, ") {");
02371 DebugAssert(d_equalityQueue.empty(), "TheoryCore::assertEqualities()");
02372 enqueueEquality(e);
02373
02374 while(!d_equalityQueue.empty()) {
02375
02376
02377
02378
02379 ExprMap<Theorem> q;
02380 for(vector<Theorem>::iterator i=d_equalityQueue.begin(),
02381 iend=d_equalityQueue.end(); i!=iend; ++i) {
02382 if(processEquality(*i, q)) {
02383
02384 TRACE_MSG("facts eq", "assertEqualities[FALSE] => }");
02385 d_equalityQueue.clear();
02386 return;
02387 }
02388 }
02389 d_equalityQueue.clear();
02390
02391
02392 for(ExprMap<Theorem>::iterator i=q.begin(), iend=q.end(); i!=iend; ++i) {
02393 const Theorem& e = i->second;
02394 DebugAssert(e.isRewrite(), "");
02395 DebugAssert(e.getLHS().isTerm(), "term expected");
02396
02397 assertFormula(e);
02398 }
02399
02400
02401 for(ExprMap<Theorem>::iterator i=q.begin(), iend=q.end(); i!=iend; ++i) {
02402 const Theorem& e = i->second;
02403 DebugAssert(find(e.getLHS()).getRHS() == e.getLHS(),
02404 "find error: e = "+e.getExpr().toString()
02405 +"\n\n find(e.getLHS()) = "
02406 +find(e.getLHS()).getRHS().toString());
02407 DebugAssert(find(e.getRHS()).getRHS() == e.getRHS(),
02408 "find error: e = "+e.getExpr().toString()
02409 +"\n\n find(e.getRHS()) = "
02410 +find(e.getRHS()).getRHS().toString());
02411
02412
02413
02414 e.getLHS().setFind(e);
02415 }
02416
02417 d_em->invalidateSimpCache();
02418
02419
02420
02421 for(ExprMap<Theorem>::iterator i=q.begin(), iend=q.end(); i!=iend; ++i) {
02422 const Theorem& e = i->second;
02423 NotifyList *L = e.getLHS().getNotify();
02424 if (L) processNotify(e, L);
02425 }
02426 }
02427 processUpdates();
02428 TRACE_MSG("facts eq", "assertEqualities => }");
02429 }
02430
02431
02432 void TheoryCore::assertFormula(const Theorem& thm)
02433 {
02434 TRACE("facts assertFact", "assertFormula(", thm, ") {");
02435 const Expr& e = thm.getExpr();
02436 if (e.isAbsLiteral()) {
02437 Theory* i = theoryOf(e);
02438
02439
02440 Theory* i2(NULL);
02441
02442
02443 if(e.isNot() && e[0].isEq())
02444 setupTerm(e, this);
02445 else
02446 setupTerm(e,i);
02447
02448
02449
02450
02451 enqueueSE(thm);
02452 Theorem findThm;
02453 NotifyList* L;
02454 if (e.isNot()) {
02455 DebugAssert(!e[0].hasFind(), "already has find");
02456 if (e[0].isEq()) {
02457
02458 d_diseq.push_back(thm);
02459
02460 i2 = theoryOf(getBaseType(e[0][0]).getExpr());
02461
02462 if(e[0][0] < e[0][1]) {
02463 Expr e2 = e[0][1].eqExpr(e[0][0]);
02464 DebugAssert(!e2.hasFind(), "already has find");
02465 findThm = transitivityRule(d_commonRules->rewriteUsingSymmetry(e2),
02466 d_commonRules->notToIff(thm));
02467 e2.setFind(findThm);
02468 d_em->invalidateSimpCache();
02469 L = e2.getNotify();
02470 if (L) processNotify(findThm, L);
02471 }
02472 }
02473 findThm = d_commonRules->notToIff(thm);
02474 e[0].setFind(findThm);
02475 d_em->invalidateSimpCache();
02476 L = e[0].getNotify();
02477 if (L) processNotify(findThm, L);
02478 }
02479 else {
02480
02481
02482
02483
02484 if(e.hasFind()) {
02485
02486
02487
02488
02489 findThm = find(e);
02490 if(findThm.getExpr().isFalse()) {
02491 IF_DEBUG(debugger.counter("conflicts from find pointers")++);
02492 setInconsistent(d_commonRules->contradictionRule(thm,
02493 d_commonRules->iffFalseElim(find(e))));
02494 TRACE_MSG("facts assertFact", "assertFormula[contradiction] => }");
02495 return;
02496 }
02497 }
02498 else {
02499 findThm = d_commonRules->iffTrue(thm);
02500 e.setFind(findThm);
02501 d_em->invalidateSimpCache();
02502 L = e.getNotify();
02503 if (L) processNotify(findThm, L);
02504 }
02505
02506 if(e.isEq()) {
02507 if(e[0] < e[1]) {
02508 Expr e2 = e[1].eqExpr(e[0]);
02509 if(e2.hasFind()) {
02510
02511
02512 findThm = find(e2);
02513 if(findThm.getExpr().isFalse()) {
02514 IF_DEBUG(debugger.counter("conflicts from find pointers")++);
02515 setInconsistent(d_commonRules->contradictionRule(
02516 symmetryRule(thm),
02517 d_commonRules->iffFalseElim(find(e2))));
02518 TRACE_MSG("facts assertFact", "assertFormula[e[1]/=e[0]] => }");
02519 return;
02520 }
02521 } else {
02522 findThm = transitivityRule(d_commonRules->rewriteUsingSymmetry(e2),
02523 d_commonRules->iffTrue(thm));
02524 e2.setFind(findThm);
02525 d_em->invalidateSimpCache();
02526 L = e2.getNotify();
02527 if (L) processNotify(findThm, L);
02528 }
02529 }
02530 }
02531 }
02532 d_em->invalidateSimpCache();
02533
02534
02535 if(thm.getExpr().isExists())
02536 enqueueFact(d_commonRules->skolemize(thm));
02537 else {
02538 TRACE("facts assertFact", ("assertFact[->" + i->getName() + "]("), thm, ") {");
02539 i->assertFact(thm);
02540 TRACE("facts assertFact", "assertFact[->", i->getName(),"] => }");
02541 if(i2 != NULL && i != i2) {
02542 TRACE("facts assertFact", ("assertFact[->" + i2->getName() + "]("), thm, ") {");
02543 IF_DEBUG(debugger.counter("assertFact(diseq) by type")++);
02544 i2->assertFact(thm);
02545 TRACE("facts assertFact", "assertFact[->", i2->getName(),"] => }");
02546 }
02547 }
02548 }
02549 else {
02550 DebugAssert(false,"assertFormula: nonliteral asserted:\n "
02551 +thm.toString());
02552 }
02553 TRACE_MSG("facts assertFact", "assertFormula => }");
02554 }
02555
02556
02557 void TheoryCore::setupTerm(const Expr& t, Theory* i)
02558 {
02559 TRACE("facts setup", "setupTerm(", t, ", i="+i->getName()+") {");
02560
02561
02562 Theory* j = theoryOf(t);
02563 if(i != j && t.isTerm()) {
02564 TRACE("facts setup", "addSharedTerm[->"+j->getName()+"](", t, ") {");
02565 j->addSharedTerm(t);
02566 TRACE_MSG("facts setup", "addSharedTerm[->"+j->getName()+"] => }");
02567 TRACE("facts setup", "addSharedTerm[->"+i->getName()+"](", t, ") {");
02568 i->addSharedTerm(t);
02569 TRACE_MSG("facts setup", "addSharedTerm[->"+i->getName()+"] => }");
02570 d_sharedTerms.insert(t, j);
02571 }
02572
02573 int k;
02574
02575
02576
02577
02578 if (!t.isTerm()) {
02579 if(t.isAbsLiteral()) {
02580 for (k = 0; k < t.arity(); ++k) {
02581 setupTerm(t[k], i);
02582 }
02583 TRACE("facts setup", "setup[->"+j->getName()+"](", t, ") {");
02584 j->setup(t);
02585 TRACE("facts setup", "setup[->",j->getName(),"] => }");
02586 }
02587 TRACE_MSG("facts setup", "setupTerm[not term] => }");
02588 return;
02589 }
02590
02591
02592 if (t.hasFind()) {
02593 TRACE_MSG("facts setup", "setupTerm[has find] => }");
02594 return;
02595 }
02596
02597
02598
02599
02600 d_terms.push_back(t);
02601
02602 for (k = 0; k < t.arity(); ++k) {
02603 setupTerm(t[k],theoryOf(t));
02604 }
02605 Theorem thm = d_commonRules->reflexivityRule(t);
02606 t.setFind(thm);
02607 TRACE("facts setup", "setup[->"+j->getName()+"](", t, ") {");
02608 j->setup(t);
02609 TRACE("facts setup", "setup[->",j->getName(),"] => }");
02610
02611
02612 Theorem pred = d_rules->typePred(t);
02613
02614 const Expr& predExpr = pred.getExpr();
02615
02616 if(predExpr.isFalse()) {
02617 IF_DEBUG(debugger.counter("conflicts from type preficate")++);
02618 setInconsistent(pred);
02619 }
02620 else if(!predExpr.isTrue()) {
02621 Theory* k = theoryOf(t.getType().getExpr());
02622 TRACE("facts setup", "assertTypePred[->"+k->getName()+"]("
02623 +t.toString()+", ", pred, ") {");
02624 k->assertTypePred(t, pred);
02625 TRACE_MSG("facts setup", "assertTypePred[->"+k->getName()+"] => }");
02626 }
02627
02628 d_typePredAsserted[t] = true;
02629 TRACE_MSG("facts setup", "setupTerm => }");
02630 }
02631
02632
02633 Theorem TheoryCore::rewriteCore(const Expr& e)
02634 {
02635 TRACE("rewrite", "rewriteCore(", e, ") {");
02636 if (e.hasFind()) {
02637 TRACE("rewrite", "rewriteCore[hasFind] => ", find(e), " }");
02638 IF_DEBUG(checkRewriteType(this, find(e)));
02639 return find(e);
02640 }
02641 if (e.isRewriteNormal()) {
02642 IF_DEBUG(
02643
02644
02645 e.clearRewriteNormal();
02646 Expr rewritten(rewriteCore(e).getRHS());
02647 e.setRewriteNormal();
02648 DebugAssert(rewritten == e,
02649 "Expected no change: e = " + e.toString()
02650 +"\n rewriteCore(e) = "+rewritten.toString());
02651 )
02652 TRACE("rewrite", "rewriteCore[isRewriteNormal] => ", reflexivityRule(e), " }");
02653 return reflexivityRule(e);
02654 }
02655 Theorem thm;
02656 if (e.isNot() || e.isEq()) {
02657 TRACE("rewrite", "rewriteLitCore(", e, ") {");
02658 thm = rewriteLitCore(e);
02659 IF_DEBUG(checkRewriteType(this, thm));
02660 TRACE("rewrite", "rewriteLitCore => ", thm, "}");
02661 if(e != thm.getRHS()) {
02662 thm = rewriteCore(thm);
02663 TRACE("rewrite", "rewriteCore => ", thm, " }");
02664 return thm;
02665 }
02666 }
02667 TRACE("rewrite", ("rewrite["+theoryOf(e)->getName()+"]("), e, ") {");
02668 thm = theoryOf(e)->rewrite(e);
02669 TRACE("rewrite", ("rewrite["+theoryOf(e)->getName()+"] => "), thm, "}");
02670 IF_DEBUG(checkRewriteType(this, thm));
02671
02672 const Expr& e2 = thm.getRHS();
02673
02674
02675
02676 DebugAssert(!e2.isEq() || e2[0] >= e2[1],
02677 "theory-specific rewrites for equality should ensure lhs >= rhs");
02678
02679 if (e != e2) {
02680 thm = rewriteCore(thm);
02681 TRACE("rewrite", "rewriteCore => ", thm, " }");
02682 return thm;
02683 }
02684
02685 TRACE("rewrite", "rewriteCore[refl] => ", thm, " }");
02686 return thm;
02687 }
02688
02689
02690 bool TheoryCore::checkSATCore() {
02691 TRACE_MSG("facts checkSat", "checkSATCore() {");
02692 DebugAssert(d_queue.empty(), "checkSATCore[start]: Expected empty queue");
02693 DebugAssert(d_queueSE.empty(), "checkSATCore[start]: Expected empty queue");
02694 DebugAssert(!d_inCheckSATCore, "Recursive call to checkSATCore is not allowed!");
02695 IF_DEBUG(ScopeWatcher sw(&d_inCheckSATCore));
02696 IF_DEBUG(debugger.counter("DP checkSAT(fullEffort) calls")++);
02697 for(int i=0; i<getNumTheories() && !d_inconsistent && d_queue.empty(); ++i) {
02698 TRACE("facts checkSat", "checkSAT (full effort) [",
02699 d_theories[i]->getName(), "]() {");
02700 d_theories[i]->checkSat(true);
02701 TRACE("facts checkSat", "checkSAT (full effort) [",
02702 d_theories[i]->getName(), "]() }");
02703 }
02704
02705 if(d_queue.empty()) {
02706 DebugAssert(d_queueSE.empty(),
02707 "checkSATCore[start]: Expected empty queue");
02708 TRACE_MSG("facts checkSat", "checkSATCore[queue empty] => true }");
02709 return true;
02710 }
02711
02712
02713 processFactQueue();
02714
02715 TRACE("facts checkSat", "checkSATCore => ",
02716 d_inconsistent? "true" : "false", " }");
02717
02718 DebugAssert(d_queue.empty(), "checkSATCore[start]: Expected empty queue");
02719 DebugAssert(d_queueSE.empty(), "checkSATCore[start]: Expected empty queue");
02720
02721 return(d_inconsistent);
02722 }
02723
02724
02725 void TheoryCore::addToVarDB(const Expr& e)
02726 {
02727 TRACE("model", "TheoryCore::addToVarDB(", e, ")");
02728 d_vars.push_back(e);
02729 }
02730
02731
02732 void TheoryCore::refineCounterExample()
02733 {
02734
02735 for(int i = 1; i<getNumTheories(); i++) {
02736 if(d_theories[i] != this)
02737 d_theories[i]->refineCounterExample();
02738 if(inconsistent()) {
02739 vector<Expr> assump;
02740 inconsistentThm().getLeafAssumptions(assump);
02741 Expr a = Expr(RAW_LIST, assump, d_em);
02742 throw EvalException("Theory["+d_theories[i]->getName()
02743 +"]: Model Creation failed due "
02744 "to the following assumptions:\n\n"
02745 +a.toString()
02746 +"\n\nYou might be using an incomplete logical fragment.");
02747 }
02748 }
02749 }
02750
02751
02752 void TheoryCore::computeModelBasic(const vector<Expr>& v) {
02753 for(vector<Expr>::const_iterator i=v.begin(), iend=v.end(); i!=iend; ++i) {
02754 TRACE("model", "Model var "+i->toString()+" = ", find(*i).getRHS(), "");
02755 DebugAssert((*i).getType().isBool(), "TheoryCore::computeModel: *i = "
02756 +(*i).toString());
02757 Expr val = find(*i).getRHS();
02758 if(!val.isBoolConst()) val = d_em->trueExpr();
02759 assignValue(*i, val);
02760 }
02761 }
02762
02763
02764 void TheoryCore::collectBasicVars() {
02765 TRACE_MSG("model", "collectBasicVars() {");
02766
02767 d_varModelMap.clear();
02768 d_varAssignments.clear();
02769
02770 vector<Expr> stack(d_vars.begin(), d_vars.end());
02771 size_t lastSize(0);
02772 while(stack.size() > 0) {
02773 Expr var(stack.back());
02774 stack.pop_back();
02775 if(d_varModelMap.count(var) > 0) continue;
02776 Theorem findThm(find(var));
02777 if(findThm.getRHS()!=var) {
02778 d_simplifiedModelVars[var] = findThm;
02779 stack.push_back(findThm.getRHS());
02780 TRACE("model", "collectBasicVars: simplified var: ", findThm.getExpr(), "");
02781 continue;
02782 }
02783 lastSize = stack.size();
02784 TRACE("model", "getModelTerm(", var, ") {");
02785 getModelTerm(var, stack);
02786 TRACE("model", "getModelTerm => ",
02787 Expr(RAW_LIST, stack, getEM()), " }");
02788 if(stack.size() == lastSize) {
02789
02790 TRACE("model", "collectBasicVars: adding primitive var: ", var, "");
02791 d_basicModelVars.push_back(var);
02792 if(var.isTerm()) {
02793 Theory* t1 = theoryOf(var);
02794 Theory* t2 = theoryOf(getBaseType(var).getExpr().getKind());
02795 if(t1 != t2) {
02796 TRACE("model", "collectBasicVars: adding shared var: ", var, "");
02797 d_sharedTerms.insert(var, t1);
02798 t1->addSharedTerm(var);
02799 t2->addSharedTerm(var);
02800 }
02801 }
02802 } else {
02803 vector<Expr>& kids = d_varModelMap[var];
02804 for(size_t i=lastSize; i<stack.size(); ++i) {
02805 DebugAssert(stack[i] != var, "Primitive var was pushed on "
02806 "the stack in computeModelTerm(): "+var.toString());
02807 kids.push_back(stack[i]);
02808 }
02809 TRACE("model", "collectBasicVars: var="+var.toString()
02810 +" maps into vars=", Expr(RAW_LIST, kids, getEM()), "");
02811 }
02812 }
02813 TRACE_MSG("model", "collectBasicVars() => }");
02814 }
02815
02816
02817 void TheoryCore::buildModel(ExprMap<Expr>& m) {
02818 TRACE_MSG("model", "buildModel() {");
02819
02820 size_t numTheories = getNumTheories();
02821
02822 set<Expr> theoryExprs[numTheories+1];
02823
02824 for(size_t j = 0 ; j<d_basicModelVars.size() ; j++) {
02825 const Expr& var = d_basicModelVars[j];
02826 Theorem findThm(find(var));
02827 if(findThm.getRHS()!=var) {
02828 TRACE("model", "buildModel: replace var="+var.toString(),
02829 " with find(var)=", findThm.getRHS());
02830 d_simplifiedModelVars[var] = findThm;
02831 continue;
02832 }
02833
02834 Theory *th = theoryOf(getBaseType(var).getExpr().getKind());
02835 size_t i=0;
02836 for(; i<numTheories && d_theories[i] != th; ++i);
02837 DebugAssert(i<numTheories && d_theories[i] == th,
02838 "TheoryCore::buildModel: cannot find the theory ["
02839 +th->getName()+"] for the variable: "
02840 +var.toString());
02841 theoryExprs[i].insert(var);
02842 TRACE("model", "buildModel: adding ", var,
02843 " to theory "+d_theories[i]->getName());
02844 }
02845
02846 for(int i=0; i<getNumTheories(); i++) {
02847 if(theoryExprs[i].size() > 0) {
02848 TRACE("model", "computeModelBasic[", d_theories[i]->getName(), "] {");
02849
02850 vector<Expr> vars;
02851 vars.insert(vars.end(), theoryExprs[i].begin(), theoryExprs[i].end());
02852 d_theories[i]->computeModelBasic(vars);
02853 TRACE("model", "computeModelBasic[", d_theories[i]->getName(), "] => }");
02854 if(inconsistent()) {
02855 vector<Expr> assump;
02856 inconsistentThm().getLeafAssumptions(assump);
02857 Expr a = Expr(RAW_LIST, assump, d_em);
02858 throw EvalException
02859 ("Model Creation failed in Theory["
02860 +d_theories[i]->getName()
02861 +"] due to the following assumptions:\n\n"
02862 +a.toString()
02863 +"\n\nYou might be using an incomplete logical fragment.");
02864 }
02865 }
02866 }
02867
02868 ExprHashMap<Theorem>::iterator k, kend=d_simplifiedModelVars.end();
02869 for(CDList<Expr>::const_iterator i=d_vars.begin(), iend=d_vars.end(); i!=iend; ++i) {
02870 Expr var(*i);
02871 TRACE("model", "buildModel: recombining var=", var, "");
02872 k=d_simplifiedModelVars.find(var);
02873 Theorem simp;
02874 if(k!=kend) {
02875 simp = k->second;
02876 TRACE("model", "buildModel: simplified var="+var.toString()+" to ",
02877 simp.getRHS(), "");
02878 var = simp.getRHS();
02879 }
02880 collectModelValues(var, m);
02881 if(d_varAssignments.count(var) > 0) {
02882 if(!simp.isNull()) {
02883 Theorem thm(transitivityRule(simp, d_varAssignments[var]));
02884 assignValue(thm);
02885 DebugAssert(thm.getLHS() == *i, "");
02886 m[*i] = thm.getRHS();
02887 } else
02888 m[*i] = d_varAssignments[var].getRHS();
02889 }
02890
02891
02892
02893
02894 }
02895 TRACE_MSG("model", "buildModel => }");
02896 }
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908 void TheoryCore::collectModelValues(const Expr& e, ExprMap<Expr>& m) {
02909 TRACE("model", "collectModelValues(", e, ") {");
02910 if(d_varAssignments.count(e) > 0) {
02911 TRACE("model", "collectModelValues[cached] => ",
02912 d_varAssignments[e].getRHS(), " }");
02913 return;
02914 }
02915 ExprHashMap<Theorem>::iterator k, kend=d_simplifiedModelVars.end();
02916 k=d_simplifiedModelVars.find(e);
02917 if(k!=kend) {
02918 const Theorem& findThm = k->second;
02919 const Expr& ee = findThm.getRHS();
02920 collectModelValues(ee, m);
02921 if(d_varAssignments.count(ee) > 0) {
02922 Theorem thm = transitivityRule(findThm, d_varAssignments[ee]);
02923 assignValue(thm);
02924 }
02925 TRACE("model", "collectModelValues[simplified] => ",
02926 d_varAssignments[e].getRHS(), " }");
02927 return;
02928 }
02929 if(d_varModelMap.count(e) == 0) {
02930 assignValue(reflexivityRule(e));
02931 TRACE("model", "collectModelValues[e=e] => ", e, " }");
02932 return;
02933 }
02934
02935 const vector<Expr>& vars = d_varModelMap[e];
02936
02937 bool gotAll(true);
02938 for(vector<Expr>::const_iterator i=vars.begin(), iend=vars.end(); i!=iend; ++i) {
02939 Expr var(*i);
02940
02941
02942
02943
02944
02945
02946 collectModelValues(var, m);
02947 if(d_varAssignments.count(var) == 0) {
02948 gotAll = false;
02949 }
02950
02951
02952
02953
02954
02955 }
02956 IF_DEBUG(vector<Expr> res);
02957 if(gotAll) {
02958 vector<Expr> assigned;
02959 Theory* th = theoryOf(getBaseType(e).getExpr());
02960 TRACE("model", "computeModel["+th->getName()+"](", e, ") {");
02961 th->computeModel(e, assigned);
02962 TRACE("model", "computeModel["+th->getName()+"] => ",
02963 Expr(RAW_LIST, assigned, getEM()), " }");
02964
02965 if(!(assigned.size()==1 && assigned[0]==e)) {
02966
02967 for(vector<Expr>::iterator i=assigned.begin(), iend=assigned.end();
02968 i!=iend; ++i) {
02969 if(*i == e) continue;
02970 m[*i] = getModelValue(*i).getRHS();
02971 IF_DEBUG(res.push_back(getModelValue(*i).getExpr()));
02972 }
02973 } else {
02974 IF_DEBUG(res.push_back(getModelValue(e).getExpr()));
02975 }
02976 }
02977 TRACE("model", "collectModelValues => ",
02978 Expr(RAW_LIST, res, getEM()), " }");
02979 }
02980
02981
02982 void TheoryCore::enqueueEquality(const Theorem& e) {
02983 TRACE("enqueueEquality", "enqueueEquality["+getName()+"](",
02984 e.getExpr(), ")");
02985 IF_DEBUG(if(*d_dumpTrace != "")
02986 dumpTrace(e.getExpr(), "enqueueEquality"));
02987 IF_DEBUG(const Expr& expr = e.getExpr());
02988 IF_DEBUG(int kind = expr.getKind());
02989 DebugAssert(kind == EQ || kind == AND || kind == EXISTS || kind == FALSE,
02990 "enqueueEnquality: bad input: "+expr.toString());
02991
02992 DebugAssert(e.getScope() <= d_cm->scopeLevel(),
02993 "\n e.getScope()="+int2string(e.getScope())
02994 +"\n scopeLevel="+int2string(d_cm->scopeLevel())
02995 +"\n e = "+expr.toString());
02996
02997
02998 d_equalityQueue.push_back(e);
02999 }
03000
03001
03002
03003
03004
03005
03006
03007 bool TheoryCore::processEquality(const Theorem& thm, ExprMap<Theorem>& q) {
03008 const Expr& e = thm.getExpr();
03009 TRACE("facts eq", "processEquality(", e, ") {");
03010 bool res(false);
03011
03012 switch(e.getKind()) {
03013 case FALSE:
03014 IF_DEBUG(debugger.counter("conflicts from solver")++);
03015 setInconsistent(thm);
03016 res = true;
03017 break;
03018 case EXISTS:
03019
03020
03021 res = processEquality(d_commonRules->skolemize(thm), q);
03022 break;
03023 case AND:
03024 for(int i=0, iend=e.arity(); i!=iend; ++i)
03025 if(res = processEquality(d_commonRules->andElim(thm, i), q)) break;
03026 break;
03027 case EQ:
03028
03029 if(find(e[0]).getRHS() != e[1] && e[0] != find(e[1]).getRHS()) {
03030 DebugAssert(e[0] != e[1], "processEquality: e = "+e.toString());
03031 DebugAssert(!e[1].hasFind() || find(e[1]).getRHS() == e[1],
03032 "processEquality: e = "+e.toString()
03033 +"\nfind(e[1]) = "+find(e[1]).getRHS().toString());
03034
03035 q[e] = thm;
03036 TRACE("facts eq", " [new] ", e, ",\n");
03037 } else if(find(e).getRHS().isFalse()) {
03038 TRACE("facts eq", " [FALSE] ", e, "]");
03039 IF_DEBUG(debugger.counter("conflicts from find pointers")++);
03040 setInconsistent(d_commonRules->contradictionRule(thm,
03041 d_commonRules->iffFalseElim(find(e))));
03042 res = true;
03043 } else {
03044 TRACE("facts eq", " ", e, ",");
03045 }
03046 break;
03047 default:
03048 DebugAssert(false,
03049 "TheoryCore::processEquality(): bad input:\n "
03050 +thm.toString());
03051 }
03052 TRACE("facts eq", "processEquality => ", res? "true" : "false", " }");
03053 return res;
03054 }
03055
03056
03057 void TheoryCore::processNotify(const Theorem& e, NotifyList *L)
03058 {
03059 DebugAssert(L, "Expected non-NULL notify list");
03060
03061
03062
03063
03064
03065
03066 for(unsigned k = 0; k < L->size(); ++k) {
03067 TRACE("facts update", "update["+L->getTheory(k)->getName()+"]("
03068 +e.toString()+", ", L->getExpr(k), ") {");
03069 L->getTheory(k)->update(e, L->getExpr(k));
03070 TRACE("facts update", "update[", L->getTheory(k)->getName(), "] => }");
03071 }
03072 }
03073
03074
03075 void TheoryCore::setIncomplete(const string& reason) {
03076 d_incomplete.insert(reason, true);
03077 }
03078
03079
03080 void
03081 TheoryCore::setResourceLimit(unsigned limit) {
03082 d_resourceLimit = limit;
03083 }
03084
03085
03086 IF_DEBUG(static ExprMap<bool> simpStack);
03087
03088 Theorem TheoryCore::simplify(const Expr& e, bool forceRebuild)
03089 {
03090 TRACE("simplify", "simplify(", e, ") {");
03091 IF_DEBUG(ScopeWatcher sw(&d_inSimplify));
03092 Theorem (TheoryCore::*oldSimplifier)(const Expr&) = d_currentRecursiveSimplifier;
03093
03094 if (*d_simplifyInPlace) {
03095 if (!forceRebuild) {
03096 d_currentRecursiveSimplifier = &CVCL::TheoryCore::simplifyInPlaceRec;
03097 Theorem res(simplifyRec(e));
03098 d_currentRecursiveSimplifier = oldSimplifier;
03099 TRACE("simplify", "simplify[in place] => ", res.getRHS(), " }");
03100 return res;
03101 }
03102 else {
03103 d_currentRecursiveSimplifier = &CVCL::TheoryCore::simplifyFullRec;
03104 d_em->invalidateSimpCache();
03105 Theorem thm = simplifyRec(e);
03106 d_em->invalidateSimpCache();
03107 if (!e.isAbsLiteral() && e != thm.getRHS()) {
03108 e.setFind(thm);
03109 }
03110 d_currentRecursiveSimplifier = oldSimplifier;
03111 TRACE("simplify", "simplify[rebuild] => ", thm.getRHS(), " }");
03112 return thm;
03113 }
03114 }
03115 d_currentRecursiveSimplifier = &CVCL::TheoryCore::simplifyFullRec;
03116 Theorem res(simplifyRec(e));
03117 d_currentRecursiveSimplifier = oldSimplifier;
03118 TRACE("simplify", "simplify => ", res.getRHS(), " }");
03119 return res;
03120 }
03121
03122
03123 Theorem TheoryCore::simplifyRec(const Expr& e)
03124 {
03125 DebugAssert(d_currentRecursiveSimplifier, "unexpected call to simplifyRec");
03126 return (this->*d_currentRecursiveSimplifier)(e);
03127 }
03128
03129
03130 Theorem TheoryCore::simplifyFullRec(const Expr& e)
03131 {
03132 TRACE("simplifyRec", "simplifyRec(", e, ") {");
03133 DebugAssert(simpStack.count(e) == 0, "TheoryCore::simplifyRec: loop detected over e =\n"
03134 +e.toString());
03135 TRACE("simplify stack", "simpStack.size = ", simpStack.size(), "");
03136 DebugAssert(simpStack.size() < 10000,
03137 "TheoryCore::simplify: too deep recursion depth");
03138 IF_DEBUG(simpStack[e] = true);
03139 Theorem thm;
03140 if(e.hasFind()) {
03141 thm = find(e);
03142 const Expr& e2 = thm.getRHS();
03143 if (e2.hasFind()) {
03144 DebugAssert(e2.isTrue() || e2.isFalse() || e2.isTerm(),
03145 "Unexpected find pointer");
03146 TRACE_MSG("simplifyRec", "Using find");
03147 TRACE("simplifyRec", "simplify => ", thm, "}\n");
03148 IF_DEBUG(simpStack.erase(e));
03149 return thm;
03150 }
03151 else {
03152 DebugAssert(!e.isAbsLiteral(), "Expected non-literal: e = "+e.toString()
03153 +"\n e2 = "+e2.toString());
03154 DebugAssert(*d_simplifyInPlace, "Expected in-place flag: e = "
03155 +e.toString()+"\n e2 = "+e2.toString());
03156 Theorem thm2 = simplifyRec(e2);
03157 if (thm2.getLHS() != thm2.getRHS()) {
03158 e.setFind(transitivityRule(thm,thm2));
03159 TRACE_MSG("simplifyRec", "Using find 2");
03160 TRACE("simplifyRec", "simplify => ", e.getFind(), "}\n");
03161 IF_DEBUG(simpStack.erase(e));
03162 return e.getFind();
03163 }
03164 TRACE_MSG("simplifyRec", "Using find 3");
03165 TRACE("simplifyRec", "simplify => ", thm, "}\n");
03166 IF_DEBUG(simpStack.erase(e));
03167 return thm;
03168 }
03169 }
03170
03171 if(e.validSimpCache()) {
03172 TRACE_MSG("simplifyRec", "Using cached result");
03173 TRACE("simplifyRec", "simplify => ", e.getSimpCache(), "}\n");
03174 IF_DEBUG(simpStack.erase(e));
03175 return e.getSimpCache();
03176 }
03177
03178
03179 switch(e.getKind()) {
03180 case EQ:
03181 case IFF:
03182 if(e[0]==e[1]) {
03183 thm = d_commonRules->iffTrue(reflexivityRule(e[0]));
03184 IF_DEBUG(debugger.counter("simplified x=x")++);
03185 break;
03186 }
03187
03188 default:
03189 TRACE("simplifyRec", "simplifyOp["+theoryOf(e)->getName()+"](",
03190 e, ") {");
03191 thm = theoryOf(e)->simplifyOp(e);
03192 TRACE("simplifyRec", "simplifyOp["+theoryOf(e)->getName()+"] => ",
03193 thm.getRHS(), " }");
03194 thm = rewriteCore(thm);
03195 }
03196
03197 const Expr& e2 = thm.getRHS();
03198 #ifdef DEBUG
03199
03200 if(!getFlags()["ite-lift-unary"].getBool()) {
03201 if (!e2.isTerm() || !e2.hasFind()) {
03202
03203 for (int k=0; k<e2.arity(); ++k) {
03204 Expr simplified(simplifyRec(e2[k]).getRHS());
03205 DebugAssert(e2[k]==simplified,"Simplify Error 1:\n e2[k="+int2string(k)
03206 +"] = "
03207 +e2[k].toString() + "\nSimplified = "
03208 +simplified.toString()
03209 +"\ne2 = "+e2.toString());
03210
03211
03212
03213
03214 }
03215 }
03216 Expr rewritten(rewriteCore(e2).getRHS());
03217 DebugAssert(e2==rewritten,"Simplify Error 2: e2 = \n"
03218 +e2.toString() + "\nSimplified rewritten = \n"
03219 +rewritten.toString());
03220 }
03221 #endif
03222 e.setSimpCache(thm);
03223 if (e != e2) {
03224 e2.setSimpCache(reflexivityRule(e2));
03225 }
03226 TRACE("simplifyRec", "simplify => ", thm, "}\n");
03227 IF_DEBUG(simpStack.erase(e));
03228 return thm;
03229 }
03230
03231
03232
03233 Theorem TheoryCore::simplifyInPlaceRec(const Expr& e)
03234 {
03235 TRACE("simplifyRec", "simplifyInPlaceRec(", e, ") {");
03236 Theorem thm;
03237 if (e.hasFind()) {
03238 thm = find(e);
03239 const Expr& e2 = thm.getRHS();
03240 if (e2.hasFind()) {
03241 DebugAssert(e2.isTrue() || e2.isFalse() || e2.isTerm(),
03242 "Unexpected find pointer");
03243 TRACE_MSG("simplifyRec", "Using find");
03244 TRACE("simplifyRec", "simplifyInPlaceRec => ", thm, "}\n");
03245 return thm;
03246 }
03247 else {
03248 DebugAssert(!e.isAbsLiteral(), "huh?");
03249 Theorem thm2 = simplifyInPlaceRec(e2);
03250 if (thm2.getLHS() != thm2.getRHS()) {
03251 e.setFind(transitivityRule(thm,thm2));
03252 TRACE_MSG("simplifyRec", "Using find 2");
03253 TRACE("simplifyRec", "simplifyInPlaceRec => ", e.getFind(), "}\n");
03254 return e.getFind();
03255 }
03256 TRACE_MSG("simplifyRec", "Using find 3");
03257 TRACE("simplifyRec", "simplifyInPlaceRec => ", thm, "}\n");
03258 return thm;
03259 }
03260 }
03261
03262 if (e.validSimpCache()) {
03263 TRACE_MSG("simplifyRec", "Using cached result");
03264 TRACE("simplifyRec", "simplifyInPlaceRec => ", e.getSimpCache(), "}\n");
03265 return e.getSimpCache();
03266 }
03267
03268 int k, ar = e.arity();
03269 if (ar > 0) {
03270 vector<Theorem> newChildrenThm;
03271 vector<unsigned> changed;
03272 const vector<Expr>& kids = e.getKids();
03273 for(k = 0; k < ar; ++k) {
03274 thm = simplifyRec(kids[k]);
03275 if (thm.getLHS() != thm.getRHS()) {
03276 if ((e.getKind() == OR && thm.getRHS().isTrue()) ||
03277 (e.getKind() == AND && thm.getRHS().isFalse())) {
03278 newChildrenThm.clear();
03279 changed.clear();
03280 newChildrenThm.push_back(thm);
03281 changed.push_back(k);
03282 break;
03283 }
03284 else if (k == 0 && e.getKind() == ITE && (thm.getRHS().isBoolConst())) {
03285 newChildrenThm.push_back(thm);
03286 changed.push_back(k);
03287 if (thm.getRHS().isTrue()) k += 1;
03288 else k += 2;
03289 thm = simplifyRec(kids[k]);
03290 newChildrenThm.push_back(thm);
03291 changed.push_back(k);
03292 break;
03293 }
03294 else {
03295 newChildrenThm.push_back(thm);
03296 changed.push_back(k);
03297 }
03298 }
03299 }
03300 if (changed.size() == 0) thm = rewriteCore(e);
03301 else {
03302 thm = substitutivityRule(e, changed, newChildrenThm);
03303 Theorem thm2 = rewriteCore(thm.getRHS());
03304 const Expr& e2 = thm2.getLHS();
03305 if (e2 == thm2.getRHS()) {
03306 if (!e.isAbsLiteral() && !e2.isAtomic() && !e2.isAbsLiteral()) {
03307 e.setFind(thm);
03308 thm = reflexivityRule(e);
03309 }
03310 }
03311 else thm = transitivityRule(thm, thm2);
03312 }
03313 } else {
03314 thm = rewriteCore(e);
03315 }
03316 e.setSimpCache(thm);
03317 const Expr& e2 = thm.getRHS();
03318 if (e != e2) {
03319 e2.setSimpCache(reflexivityRule(e2));
03320 }
03321 TRACE("simplifyRec", "simplifyInPlaceRec => ", thm, "}\n");
03322 return thm;
03323 }
03324
03325
03326 bool TheoryCore::incomplete(vector<string>& reasons) {
03327 if(d_incomplete.size() > 0) {
03328 for(CDMap<string,bool>::iterator i=d_incomplete.begin(),
03329 iend=d_incomplete.end(); i!=iend; ++i)
03330 reasons.push_back((*i).first);
03331 return true;
03332 }
03333 else
03334 return false;
03335 }
03336
03337
03338 Theorem TheoryCore::rewriteCore(const Theorem& e) {
03339 DebugAssert(e.isRewrite(),
03340 "rewriteCore(thm): not equality or iff:\n " + e.toString());
03341 return transitivityRule(e, rewriteCore(e.getRHS()));
03342 }
03343
03344
03345 Theorem TheoryCore::rewriteLiteral(const Expr& e) {
03346 DebugAssert(e.isAbsLiteral(), "rewriteLiteral("+e.toString()
03347 +")\nExpected a literal.");
03348 Theorem res;
03349
03350 bool neg(e.isNot());
03351 const Expr a = neg? e[0] : e;
03352 Theory * i;
03353 if(a.isEq())
03354 i = theoryOf(getBaseType(a[0]).getExpr());
03355 else if (a.arity() > 1)
03356 i = theoryOf(getBaseType(a[0]).getExpr());
03357 else
03358 i = theoryOf(a);
03359 TRACE("rewrite", ("rewriteAtomic["+i->getName()+"]("), e, ") {");
03360 res = i->rewriteAtomic(a);
03361 TRACE("rewrite", ("rewriteAtomic["+i->getName()+"] => "), res, "}");
03362 if(neg) res = d_commonRules->iffContrapositive(res);
03363 return res;
03364 }
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382 Theorem TheoryCore::solve(const Theorem& eThm)
03383 {
03384 const Expr& e = eThm.getExpr();
03385 TRACE("facts solve", "solve[Core](", e, ") {");
03386 Theorem thm;
03387 Expr e2;
03388 if (d_solver) {
03389 TRACE("facts solve", "solve["+d_solver->getName()+"](", e,") {");
03390 thm = d_solver->solve(eThm);
03391 TRACE("facts solve", "solve["+d_solver->getName()+"] => ", thm.getExpr(), " }");
03392 e2 = thm.getExpr();
03393
03394
03395
03396
03397 if (!e2.isEq() || theoryOf(e2) == d_solver) {
03398 TRACE("facts solve", "solve[Core](non-eq) => ", thm, " }");
03399
03400 return thm;
03401 }
03402 }
03403 else {
03404 thm = eThm;
03405 e2 = e;
03406 }
03407 Theory* i = theoryOf(e2);
03408 TRACE("facts solve", "solve["+i->getName()+"](", e2,") {");
03409 Theorem thm2 = i->solve(thm);
03410 TRACE("facts solve", "solve["+i->getName()+"] => ", thm2.getExpr(), " }");
03411 IF_DEBUG(
03412
03413 if (d_solver) {
03414 e2 = thm2.getExpr();
03415 if(e2.isEq()) {
03416 Expr solved(d_solver->solve(thm2).getExpr());
03417 DebugAssert(solved == e2, "e2 = "+e2.toString()
03418 +"\nsolved = "+solved.toString());
03419 }
03420
03421 }
03422 );
03423 TRACE("facts solve", "solve[Core] => ", thm2, " }");
03424 return thm2;
03425 }
03426
03427
03428 Theorem TheoryCore::typePred(const Expr& e) {
03429 return d_rules->typePred(e);
03430 }
03431
03432
03433 Theorem TheoryCore::subtypePredicate(const Expr& e) {
03434 TRACE("tccs", "subtypePredicate(", e, ") {");
03435 Theorem pred(e.lookupSubtypePred());
03436 if(pred.isNull()) {
03437 vector<Theorem> thms;
03438 thms.push_back(d_rules->typePred(e));
03439 TRACE("tccs", "subtypePredicate: typePred(e) = ", thms[0].getExpr(), "");
03440 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
03441 thms.push_back(subtypePredicate(*i));
03442 pred = d_commonRules->andIntro(thms);
03443 pred = d_commonRules->rewriteAnd(pred);
03444 e.setSubtypePred(pred);
03445 }
03446 TRACE("tccs", "subtypePredicate => ", pred.getExpr(), " }");
03447 return pred;
03448 }
03449
03450
03451 IF_DEBUG(
03452 void TheoryCore::dumpTrace(const Expr& e, const string& title) {
03453 vector<StrPair> fields;
03454 fields.push_back(strPair("op", d_em->getKindName(e.getKind())));
03455 fields.push_back(strPair("theory", theoryOf(e)->getName()));
03456 debugger.dumpTrace(title, fields);
03457 }
03458 )
03459
03460
03461 void TheoryCore::setFindLiteral(const Theorem& thm, bool notifySAT) {
03462 const Expr& e = thm.getExpr();
03463 if (e.isNot()) {
03464 if (!e[0].hasFind()) {
03465 if(notifySAT) enqueueSE(thm);
03466 e[0].setFind(d_commonRules->notToIff(thm));
03467 d_em->invalidateSimpCache();
03468 }
03469 }
03470 else if (!e.hasFind()) {
03471 e.setFind(d_commonRules->iffTrue(thm));
03472 if(notifySAT) enqueueSE(thm);
03473 d_em->invalidateSimpCache();
03474 }
03475 }
03476
03477
03478 Theorem TheoryCore::rewriteIte(const Expr& e) {
03479 if (e[0].isTrue())
03480 return d_rules->rewriteIteTrue(e);
03481 if (e[0].isFalse())
03482 return d_rules->rewriteIteFalse(e);
03483 if (e[1] == e[2])
03484 return d_rules->rewriteIteSame(e);
03485
03486
03487
03488
03489 return reflexivityRule(e);
03490 }
03491
03492
03493
03494
03495
03496
03497 void TheoryCore::setupSubFormulas(const Expr& s, const Expr& e)
03498 {
03499 if (s.isAtomic()) {
03500 setupTerm(s, theoryOf(s));
03501 s.addToNotify(this, e);
03502 processFactQueue();
03503 }
03504 else if (s.isAbsAtomicFormula()) {
03505 setupTerm(s, theoryOf(s));
03506 for (int i = 0; i < s.arity(); ++i) {
03507 s[i].addToNotify(this, e);
03508 }
03509 s.addToNotify(this, e);
03510 processFactQueue();
03511 }
03512 else {
03513 for (int i = 0; i < s.arity(); ++i) {
03514 setupSubFormulas(s[i], e);
03515 }
03516 }
03517 }
03518
03519
03520 void TheoryCore::registerAtom(const Expr& e)
03521 {
03522
03523 DebugAssert(e.isAbsAtomicFormula(), "Expected atomic formula");
03524 IF_DEBUG(ScopeWatcher sw(&d_inRegisterAtom));
03525 Theorem thm = simplify(e);
03526 if (thm.getRHS().isTrue()) {
03527 if (e.isImpliedLiteral()) return;
03528 e.setImpliedLiteral();
03529 d_impliedLiterals.push_back(d_commonRules->iffTrueElim(thm));
03530 }
03531 else if (thm.getRHS().isFalse()) {
03532 Expr not_e = !e;
03533 if (not_e.isImpliedLiteral()) return;
03534 not_e.setImpliedLiteral();
03535 d_impliedLiterals.push_back(d_commonRules->iffFalseElim(thm));
03536 }
03537 else {
03538 setupSubFormulas(thm.getRHS(), e);
03539 }
03540 }
03541
03542
03543 Theorem TheoryCore::getImpliedLiteral(void)
03544 {
03545 Theorem res;
03546 if (d_impliedLiteralsIdx < d_impliedLiterals.size()) {
03547 res = d_impliedLiterals[d_impliedLiteralsIdx];
03548 d_impliedLiteralsIdx = d_impliedLiteralsIdx + 1;
03549 }
03550 return res;
03551 }
03552
03553
03554 Theorem TheoryCore::getImpliedLiteralByIndex(unsigned index)
03555 {
03556 DebugAssert(index < d_impliedLiterals.size(), "index out of bounds");
03557 return d_impliedLiterals[index];
03558 }
03559
03560
03561 void TheoryCore::assignValue(const Expr& t, const Expr& val) {
03562 DebugAssert(d_varAssignments.count(t) == 0
03563 || d_varAssignments[t].getRHS() == val,
03564 "TheoryCore::assignValue("+t.toString()+" := "+val.toString()
03565 +")\n variable already has a different value");
03566
03567 Theorem thm(find(t));
03568 const Expr& t2 = thm.getRHS();
03569
03570 if(t2!=val) {
03571 bool isBool(t2.getType().isBool());
03572 Expr assump = (isBool)? t2.iffExpr(val) : t2.eqExpr(val);
03573 Theorem assertThm = d_coreSatAPI->addAssumption(assump);
03574 addFact(assertThm);
03575 thm = transitivityRule(thm, assertThm);
03576 }
03577 d_varAssignments[t] = thm;
03578 }
03579
03580
03581 void TheoryCore::assignValue(const Theorem& thm) {
03582 DebugAssert(thm.isRewrite(), "TheoryCore::assignValue("+thm.toString()+")");
03583 const Expr& t = thm.getLHS();
03584 const Expr& val = thm.getRHS();
03585 DebugAssert(d_varAssignments.count(t) == 0
03586 || d_varAssignments[t].getRHS() == val,
03587 "TheoryCore::assignValue("+thm.getExpr().toString()
03588 +")\n variable already has a different value:\n "
03589 +d_varAssignments[t].getExpr().toString());
03590 d_varAssignments[t] = thm;
03591
03592 Theorem findThm(find(t));
03593 const Expr& t2 = findThm.getRHS();
03594
03595 if(t2!=val) {
03596 Theorem thm2 = transitivityRule(symmetryRule(findThm), thm);
03597 addFact(thm2);
03598 }
03599 }
03600
03601
03602 bool TheoryCore::getResource() {
03603
03604 if(d_resourceLimit == 0) return true;
03605
03606 if(d_resourceLimit > 1) {
03607 d_resourceLimit--;
03608 return true;
03609 }
03610 else
03611 return false;
03612 }
03613
03614
03615 Theorem3 TheoryCore::queryTCC(const Theorem& phi, const Theorem& D_phi)
03616 {
03617 return d_rules->queryTCC(phi, D_phi);
03618 }
03619
03620
03621 Theorem3 TheoryCore::implIntro3(const Theorem3& phi,
03622 const std::vector<Expr>& assump,
03623 const std::vector<Theorem>& tccs)
03624 {
03625 return d_rules->implIntro3(phi, assump, tccs);
03626 }