theory_core.cpp

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

Generated on Tue Jul 3 14:33:41 2007 for CVC3 by  doxygen 1.5.1