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