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