theory.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file theory.cpp
00004  * 
00005  * Author: Clark Barrett
00006  * 
00007  * Created: Thu Jan 30 15:11:55 2003
00008  *
00009  * <hr>
00010  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00011  * Junior University and by New York University. 
00012  *
00013  * License to use, copy, modify, sell and/or distribute this software
00014  * and its documentation for any purpose is hereby granted without
00015  * royalty, subject to the terms and conditions defined in the \ref
00016  * LICENSE file provided with this distribution.  In particular:
00017  *
00018  * - The above copyright notice and this permission notice must appear
00019  * in all copies of the software and related documentation.
00020  *
00021  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00022  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00023  * 
00024  * <hr>
00025  * 
00026  */
00027 /*****************************************************************************/
00028 
00029 
00030 #include "theory_core.h"
00031 #include "common_proof_rules.h"
00032 #include "typecheck_exception.h"
00033 #include "theorem_manager.h"
00034 
00035 
00036 using namespace CVCL;
00037 using namespace std;
00038 
00039 
00040 Theory::Theory(void) : d_theoryCore(NULL) { }
00041 
00042 
00043 Theory::Theory(TheoryCore* theoryCore, const string& name)
00044   : d_em(theoryCore->getEM()),
00045     d_theoryCore(theoryCore),
00046     d_commonRules(theoryCore->getTM()->getRules()),
00047     d_name(name), d_theoryUsed(false) {
00048 }
00049 
00050 
00051 Theory::~Theory(void) { }
00052 
00053 
00054 void Theory::computeModelTerm(const Expr& e, vector<Expr>& v) {
00055   TRACE("model", "Theory::computeModelTerm(", e, "): is a variable");
00056   //  v.push_back(e);
00057 }
00058 
00059 
00060 Theorem Theory::simplifyOp(const Expr& e) {
00061   int ar = e.arity();
00062   if (ar > 0) {
00063     vector<Theorem> newChildrenThm;
00064     vector<unsigned> changed;
00065     for(int k = 0; k < ar; ++k) {
00066       // Recursively simplify the kids
00067       Theorem thm = simplifyRec(e[k]);
00068       if (thm.getLHS() != thm.getRHS()) {
00069         newChildrenThm.push_back(thm);
00070         changed.push_back(k);
00071       }
00072     }
00073     if(changed.size() > 0)
00074       return d_commonRules->substitutivityRule(e, changed, newChildrenThm);
00075   }
00076   return reflexivityRule(e);
00077 }
00078 
00079 
00080 Expr Theory::computeTCC(const Expr& e) {
00081   vector<Expr> kids;
00082   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
00083     kids.push_back(getTCC(*i));
00084   return (kids.size()>0) ?
00085     d_commonRules->rewriteAnd(andExpr(kids)).getRHS() : trueExpr();
00086 }
00087 
00088 
00089 bool Theory::inconsistent()
00090 {
00091   return d_theoryCore->inconsistent();
00092 }
00093 
00094 
00095 void Theory::setInconsistent(const Theorem& e)
00096 {
00097   TRACE("facts assertFact", ("setInconsistent[" + getName() + "->]("), e, ")");
00098   TRACE("conflict", ("setInconsistent[" + getName() + "->]("), e, ")");
00099   IF_DEBUG(debugger.counter("conflicts from DPs")++);
00100   d_theoryCore->setInconsistent(e);
00101 }
00102 
00103 
00104 void Theory::setIncomplete(const string& reason)
00105 {
00106   TRACE("facts assertFact", "setIncomplete["+getName()+"](", reason, ")");
00107   d_theoryCore->setIncomplete(reason);
00108 }
00109 
00110 
00111 Theorem Theory::simplify(const Expr& e, bool forceRebuild)
00112 {
00113   TRACE("simplify", ("simplify[" + getName() + "->]("), e, ") {");
00114   Theorem res(d_theoryCore->simplify(e, forceRebuild));
00115   TRACE("simplify", "simplify[" + getName() + "] => ", res, "}");
00116   return res;
00117 }
00118 
00119 
00120 Theorem Theory::simplifyRec(const Expr& e)
00121 {
00122   TRACE("simplifyRec", ("simplifyRec[" + getName() + "->]("), e, ") {");
00123   Theorem res(d_theoryCore->simplifyRec(e));
00124   TRACE("simplifyRec", "simplifyRec[" + getName() + "] => ", res, "}");
00125   return res;
00126 }
00127 
00128 
00129 void Theory::enqueueFact(const Theorem& e)
00130 {
00131   TRACE("facts assertFact", ("enqueueFact[" + getName() + "->]("), e, ")");
00132   d_theoryCore->enqueueFact(e);
00133 }
00134 
00135 
00136 void Theory::enqueueEquality(const Theorem& e)
00137 {
00138   TRACE("facts assertFact", ("enqueueEquality[" + getName() + "->]("), e, ")");
00139   DebugAssert(e.isRewrite(), "Theory::enqueueEquality("+e.toString()+")");
00140 //   DebugAssert(leavesAreSimp(e.getRHS()),
00141 //            "Theory::enqueueEquality("+e.toString()+")");
00142   d_theoryCore->enqueueEquality(e);
00143 }
00144 
00145 
00146 void Theory::assertEqualities(const Theorem& e)
00147 {
00148   d_theoryCore->assertEqualities(e);
00149 }
00150 
00151 
00152 void Theory::addSplitter(const Expr& e, int priority) {
00153   TRACE("facts assertFact", "addSplitter[" + getName() + "->](", e,
00154         ", pri="+int2string(priority)+")");
00155   d_theoryCore->d_coreSatAPI->addSplitter(e, priority);
00156 }
00157 
00158 
00159 void Theory::assignValue(const Expr& t, const Expr& val) {
00160   TRACE("facts assertFact", "assignValue["+getName()+"](", t, ", "+
00161         val.toString()+") {");
00162   d_theoryCore->assignValue(t, val);
00163   TRACE("facts assertFact", "assignValue[", getName(), "] => }");
00164 }
00165 
00166 
00167 void Theory::assignValue(const Theorem& thm) {
00168   TRACE("facts assertFact", "assignValue["+getName()+"](", thm, ") {");
00169   d_theoryCore->assignValue(thm);
00170   TRACE("facts assertFact", "assignValue[", getName(), "] => }");
00171 }
00172 
00173 
00174 void Theory::registerKinds(Theory* theory, vector<int>& kinds)
00175 {
00176   vector<int>::const_iterator k;
00177   vector<int>::const_iterator kEnd;
00178   for (k = kinds.begin(), kEnd = kinds.end(); k != kEnd; ++k) {
00179     DebugAssert(d_theoryCore->d_theoryMap.count(*k) == 0,
00180                 "kind already registered: "+getEM()->getKindName(*k)
00181                 +" = "+int2string(*k));
00182     d_theoryCore->d_theoryMap[*k] = theory;
00183   }
00184 }
00185 
00186 
00187 void Theory::registerTheory(Theory* theory, vector<int>& kinds,
00188                             bool hasSolver)
00189 {
00190   registerKinds(theory, kinds);
00191   d_theoryCore->d_theories.push_back(theory);
00192   if (hasSolver) {
00193     DebugAssert(!d_theoryCore->d_solver,"Solver already registered");
00194     d_theoryCore->d_solver = theory;
00195   }
00196 }
00197 
00198 
00199 int Theory::getNumTheories()
00200 {
00201   return d_theoryCore->d_theories.size();
00202 }
00203 
00204 
00205 bool Theory::hasTheory(int kind) {
00206   return (d_theoryCore->d_theoryMap.count(kind) > 0);
00207 }
00208 
00209 
00210 Theory* Theory::theoryOf(int kind)
00211 {
00212   DebugAssert(d_theoryCore->d_theoryMap.count(kind) > 0,
00213               "Unknown operator: " + getEM()->getKindName(kind));
00214   return d_theoryCore->d_theoryMap[kind];
00215 }
00216 
00217 
00218 Theory* Theory::theoryOf(const Expr& e)
00219 {
00220   if (e.isNot() || e.isEq()) {
00221     return theoryOf(e[0]);
00222   }
00223   if (e.isApply()) {
00224     return theoryOf(e.getOpKind());
00225   }
00226   if (!e.isVar()) {
00227     return theoryOf(e.getKind());
00228   }
00229   // Theory of a var is determined by its *base* type, since SUBTYPE
00230   // may have different base types, but SUBTYPE itself belongs to
00231   // TheoryCore.
00232   const Expr& typeExpr = getBaseType(e).getExpr();
00233   DebugAssert(!typeExpr.isNull(),"Null type");
00234   int kind = typeExpr.getKind();
00235   if (typeExpr.isApply()) kind = typeExpr.getOpKind();
00236   DebugAssert(d_theoryCore->d_theoryMap.count(kind) > 0,
00237               "Unknown operator: " + getEM()->getKindName(kind));
00238   return d_theoryCore->d_theoryMap[kind];
00239 }
00240 
00241 
00242 Theorem Theory::find(const Expr& e)
00243 {
00244   Theorem thm1 = e.hasFind() ? e.getFind() : reflexivityRule(e);
00245   const Expr& e1 = thm1.getRHS();
00246   if (e1 == e || !e1.hasFind()) return thm1;
00247   Theorem thm2 = find(e1);
00248   DebugAssert(thm2.getLHS()==e1,"");
00249   if (thm2.getLHS() != thm2.getRHS()) {
00250     e.setFind(transitivityRule(thm1,thm2));
00251     return e.getFind();
00252   }
00253   return thm1;
00254 }
00255 
00256 
00257 Expr Theory::getTCC(const Expr& e)
00258 {
00259   const Expr& tccCached = e.lookupTCC();
00260   if (!tccCached.isNull()) return tccCached;
00261   if(e.isVar()) {
00262     e.setTCC(trueExpr());
00263     return trueExpr();
00264   }
00265   Theory* i = theoryOf(e.getKind());
00266   TRACE("tccs", "computeTCC["+i->getName()+"](", e, ") {");
00267   e.setTCC(i->computeTCC(e));
00268   TRACE("tccs", "computeTCC["+i->getName()+"] => ", e.lookupTCC(), " }");
00269   return e.lookupTCC();
00270 }
00271 
00272 
00273 Type Theory::getBaseType(const Expr& e)
00274 {
00275   return getBaseType(e.getType());
00276 }
00277 
00278 
00279 Type Theory::getBaseType(const Type& tp)
00280 {
00281   const Expr& e = tp.getExpr();
00282   DebugAssert(!e.isNull(), "Theory::getBaseType(Type(Null))");
00283   // See if we have it cached
00284   Type res(e.lookupType());
00285   if(!res.isNull()) return res;
00286 
00287   DebugAssert(theoryOf(e) != NULL,
00288               "Theory::getBaseType(): No theory for the type: "
00289               +tp.toString());
00290   TRACE("types", "getBaseType["+theoryOf(e)->getName()+"](", e, ") {");
00291   res= theoryOf(e)->computeBaseType(tp);
00292   TRACE("types", "getBaseType["+theoryOf(e)->getName()+"] => ", res, " }");
00293   e.setType(res);
00294   return res;
00295 }
00296 
00297 
00298 Expr Theory::getTypePred(const Type& t, const Expr& e)
00299 {
00300   Expr pred;
00301   Theory *i = theoryOf(t.getExpr().getKind());
00302   TRACE("typePred", "computeTypePred["+i->getName()+"]("+t.toString()+", ", e, ") {");
00303   pred = i->computeTypePred(t, e);
00304   TRACE("typePred", "computeTypePred["+i->getName()+"] => ", pred, " }");
00305   return pred;
00306 }
00307 
00308 
00309 Theorem Theory::updateHelper(const Expr& e)
00310 {
00311   vector<Theorem> newChildrenThm;
00312   vector<unsigned> changed;
00313   int k(0), ar(e.arity());
00314   Theorem thm;
00315   for (; k < ar; ++k) {
00316     thm = find(e[k]);
00317     if (thm.getLHS() != thm.getRHS()) {
00318       newChildrenThm.push_back(thm);
00319       changed.push_back(k);
00320     }
00321   }
00322   if (changed.size() == 0) thm = reflexivityRule(e);
00323   else thm = d_commonRules->substitutivityRule(e, changed, newChildrenThm);
00324   return thm;
00325 }
00326 
00327 
00328 //! Setup a term for congruence closure (must have sig and rep attributes)
00329 void Theory::setupCC(const Expr& e) {
00330   TRACE("facts setup", "setupCC["+getName()+"](", e, ") {");
00331   for (int k = 0; k < e.arity(); ++k) {
00332     e[k].addToNotify(this, e);
00333   }
00334   Theorem thm = reflexivityRule(e);
00335   e.setSig(thm);
00336   e.setRep(thm);
00337   TRACE_MSG("facts setup", "setupCC["+getName()+"]() => }");
00338 }
00339 
00340 
00341 //! Update a term w.r.t. congruence closure (must be setup with setupCC())
00342 void Theory::updateCC(const Theorem& e, const Expr& d) {
00343   TRACE("facts update", "updateCC["+getName()+"]("+e.getExpr().toString()+", ",
00344         d, ") {");
00345   int k, ar(d.arity());
00346   const Theorem& dEQdsig = d.getSig();
00347   if (!dEQdsig.isNull()) {
00348     const Expr& dsig = dEQdsig.getRHS();
00349     Theorem thm = updateHelper(d);
00350     const Expr& sigNew = thm.getRHS();
00351     if (sigNew == dsig) {
00352       TRACE_MSG("facts update", "updateCC["+getName()+"]() [no change] => }");
00353       return;
00354     }
00355     dsig.setRep(Theorem());
00356     const Theorem& repEQsigNew = sigNew.getRep();
00357     if (!repEQsigNew.isNull()) {
00358       d.setSig(Theorem());
00359       enqueueFact(transitivityRule(repEQsigNew, symmetryRule(thm)));
00360     }
00361     else {
00362       for (k = 0; k < ar; ++k) {
00363         if (sigNew[k] != dsig[k]) {
00364           sigNew[k].addToNotify(this, d);
00365         }
00366       }
00367       d.setSig(thm);
00368       sigNew.setRep(thm);
00369     }
00370   }
00371   TRACE_MSG("facts update", "updateCC["+getName()+"]() => }");
00372 }
00373 
00374 
00375 //! Rewrite a term w.r.t. congruence closure (must be setup with setupCC())
00376 Theorem Theory::rewriteCC(const Expr& e) {
00377   const Theorem& rep = e.getRep();
00378   if (rep.isNull()) return reflexivityRule(e);
00379   else return symmetryRule(rep);
00380 }
00381 
00382 
00383 Expr Theory::parseExpr(const Expr& e) {
00384   TRACE("facts parseExpr", "parseExpr(", e, ") {");
00385   Expr res(d_theoryCore->parseExpr(e));
00386   TRACE("facts parseExpr", "parseExpr => ", res, " }");
00387   return res;
00388 }
00389 
00390 
00391 void Theory::getModelTerm(const Expr& e, vector<Expr>& v)
00392 {
00393   Theory *i = theoryOf(getBaseType(e).getExpr());
00394   TRACE("model", "computeModelTerm["+i->getName()+"](", e, ") {");
00395   IF_DEBUG(unsigned size = v.size();)
00396   i->computeModelTerm(e, v);
00397   TRACE("model", "computeModelTerm[", i->getName(), "] => }");
00398   DebugAssert(v.size() <= size || v.back() != e, "Primitive var was pushed on "
00399               "the stack in computeModelTerm["+i->getName()
00400               +"]: "+e.toString());
00401   
00402 }
00403 
00404 
00405 Theorem Theory::getModelValue(const Expr& e) {
00406   return d_theoryCore->getModelValue(e);
00407 }
00408 
00409 
00410 bool Theory::isLeafIn(const Expr& e1, const Expr& e2)
00411 {
00412   DebugAssert(isLeaf(e1),"Expected leaf");
00413   if (e1 == e2) return true;
00414   if (theoryOf(e2) != this) return false;
00415   for(Expr::iterator i=e2.begin(), iend=e2.end(); i != iend; ++i)
00416     if (isLeafIn(e1, *i)) return true;
00417   return false;
00418 }
00419 
00420 
00421 bool Theory::leavesAreSimp(const Expr& e)
00422 {
00423   if (isLeaf(e)) {
00424     bool res(e.getFind().getRHS() == e);
00425     IF_DEBUG(if(!res) TRACE("facts leavesAreSimp", "leavesAreSimp(", e, 
00426                             " = "+e.getFind().getRHS().toString()
00427                             +") => false"));
00428     return res;
00429   }
00430   for (int k = 0; k < e.arity(); ++k) {
00431     if (!leavesAreSimp(e[k])) return false;
00432   }
00433   return true;
00434 }
00435 
00436 
00437 Expr Theory::newVar(const string& name, const Type& type)
00438 {
00439   DebugAssert(!type.isNull(), "Error: defining a variable of NULL type");
00440   Expr res = resolveID(name);
00441   Type t;
00442 //   Expr res = lookupVar(name, &t);
00443   if (!res.isNull()) {
00444     t = res.getType();
00445     if (t != type) {
00446       throw TypecheckException
00447         ("incompatible redefinition of variable "+name+":\n "
00448          "already defined with type: "+t.toString()
00449          +"\n the new type is: "+type.toString());
00450     }
00451     return res;
00452   }
00453   // Replace TYPEDEF with its definition
00454   t = type;
00455   while(t.getExpr().getKind() == TYPEDEF) {
00456     DebugAssert(t.arity() == 2, "Bad TYPEDEF: "+t.toString());
00457     t = t[1];
00458   }
00459   if (type.isBool()) res = d_em->newSymbolExpr(name, UCONST);
00460   else res = getEM()->newVarExpr(name);
00461 
00462   // Add the variable for constructing a concrete model
00463   d_theoryCore->addToVarDB(res);
00464   // Add the new global declaration
00465   installID(name, res);
00466   
00467   DebugAssert(type.getExpr().getKind() != ARROW,"");
00468   DebugAssert(res.lookupType().isNull(), 
00469               "newVarExpr: redefining a variable "
00470                + name);
00471   res.setType(type);
00472   return res;
00473 }
00474 
00475 
00476 Expr Theory::newVar(const string& name, const Type& type, const Expr& def)
00477 {
00478   DebugAssert(!type.isNull(), "Error: defining a variable of NULL type");
00479   Type t;
00480   Expr res = resolveID(name);
00481   if (!res.isNull()) {
00482     throw TypecheckException
00483       ("Redefinition of variable "+name+":\n "
00484        "This variable is already defined.");
00485   }
00486   Expr v;
00487   if (type.isBool()) v = getEM()->newSymbolExpr(name, UCONST);
00488   else v = getEM()->newVarExpr(name);
00489   res = Expr(CONSTDEF, v, def);
00490 
00491   // Replace TYPEDEF with its definition
00492   t = type;
00493   while(t.getExpr().getKind() == TYPEDEF) {
00494     DebugAssert(t.arity() == 2, "Bad TYPEDEF: "+t.toString());
00495     t = t[1];
00496   }
00497   v.setType(type);
00498 
00499   // Typecheck
00500   if(getBaseType(def) != getBaseType(v)) {
00501     throw TypecheckException("Type mismatch in constant definition:\n"
00502                              "Constant "+v.toString()+
00503                              " is declared with type:\n  "
00504                              +v.getType().toString()
00505                              +"\nBut the type of definition is\n  "
00506                              +def.getType().toString());
00507   }
00508   DebugAssert(type.getExpr().getKind() != ARROW,"");
00509   DebugAssert(res.lookupType().isNull(), 
00510               "newVarExpr: redefining a variable "
00511                + name);
00512 
00513   // Add the new global declaration
00514   installID(name, res);
00515   
00516   return res;
00517 }
00518 
00519 
00520 Op Theory::newFunction(const string& name, const Type& type,
00521                        bool computeTransClosure) {
00522   DebugAssert(!type.isNull(), "Error: defining a variable of NULL type");
00523   Expr res = resolveID(name);
00524   Type t;
00525   if (!res.isNull()) {
00526     t = res.getType();
00527     throw TypecheckException
00528       ("Redefinition of variable "+name+":\n "
00529        "already defined with type: "+t.toString()
00530        +"\n the new type is: "+type.toString());
00531   }
00532   res = getEM()->newSymbolExpr(name, UFUNC);
00533   // Replace TYPEDEF with its definition
00534   t = type;
00535   while(t.getExpr().getKind() == TYPEDEF) {
00536     DebugAssert(t.arity() == 2, "Bad TYPEDEF: "+t.toString());
00537     t = t[1];
00538   }
00539   res.setType(t);
00540   // Add it to the database of variables for concrete model generation
00541   d_theoryCore->addToVarDB(res);
00542   // Add the new global declaration
00543   installID(name, res);
00544   if (computeTransClosure &&
00545       t.isFunction() && t.arity() == 3 && t[2].isBool())
00546     res.setComputeTransClosure();
00547   return res.mkOp();
00548 }
00549 
00550 
00551 Op Theory::newFunction(const string& name, const Type& type,
00552                        const Expr& def) {
00553   DebugAssert(!type.isNull(), "Error: defining a variable of NULL type");
00554   Expr res = resolveID(name);
00555   Type t;
00556   if (!res.isNull()) {
00557     t = res.getType();
00558     throw TypecheckException
00559       ("Redefinition of variable "+name+":\n "
00560        "already defined with type: "+t.toString()
00561        +"\n the new type is: "+type.toString());
00562   }
00563   res = getEM()->newSymbolExpr(name, UFUNC);
00564   // Replace TYPEDEF with its definition
00565   t = type;
00566   while(t.getExpr().getKind() == TYPEDEF) {
00567     DebugAssert(t.arity() == 2, "Bad TYPEDEF: "+t.toString());
00568     t = t[1];
00569   }
00570   res.setType(t);
00571   // Add the new global declaration
00572   installID(name, res);
00573   return res.mkOp();
00574 }
00575 
00576 
00577 static int boundVarCount = 0;
00578 
00579 
00580 Expr Theory::addBoundVar(const string& name, const Type& type) {
00581   ostringstream ss;
00582   ss << boundVarCount++;
00583   Expr v(getEM()->newBoundVarExpr(name, ss.str(), type));
00584   d_theoryCore->d_boundVarStack.push_back(pair<string,Expr>(name,v));
00585   TRACE("vars", "addBoundVar("+name+", ", type, ") => "+v.toString());
00586   return v;
00587 }
00588 
00589 
00590 Expr Theory::addBoundVar(const string& name, const Type& type,
00591                          const Expr& def) {
00592   Expr res;
00593   // Without the type, just replace the bound variable with the definition
00594   if(type.isNull())
00595     res = def;
00596   else {
00597     // When type is given, construct (LETDECL var, def) for the typechecker
00598     ostringstream ss;
00599     ss << boundVarCount++;
00600     res = Expr(LETDECL,
00601                getEM()->newBoundVarExpr(name, ss.str(), type), def);
00602   }
00603   d_theoryCore->d_boundVarStack.push_back(pair<string,Expr>(name,res));
00604   TRACE("vars", "addBoundVar("+name+", "+type.toString()+", ", def,
00605         ") => "+res.toString());
00606   return res;
00607 }
00608 
00609 
00610 Expr Theory::lookupVar(const string& name, Type* type)
00611 {
00612   Expr e = getEM()->newVarExpr(name);
00613   *type = e.lookupType();
00614 //   if ((*type).isNull()) {
00615 //     e = newApplyExpr(Op(UFUNC, e));
00616 //     *type = e.lookupType();
00617     if ((*type).isNull()) return Expr();
00618 //   }
00619   return e;
00620 }
00621 
00622 
00623 // TODO: reconcile this with parser-driven new type expressions
00624 Type Theory::newTypeExpr(const string& name)
00625 {
00626   Expr res = resolveID(name);
00627   if (!res.isNull()) {
00628     throw TypecheckException
00629       ("Redefinition of type variable "+name+":\n "
00630        "This variable is already defined.");
00631   }
00632   res = Expr(TYPEDECL, getEM()->newStringExpr(name));
00633   // Add the new global declaration
00634   installID(name, res);
00635   return Type(res);
00636 }
00637 
00638 //! Create a new type abbreviation with the given name 
00639 Type Theory::newTypeExpr(const string& name, const Type& def)
00640 {
00641   Expr res = resolveID(name);
00642   if (!res.isNull()) {
00643     throw TypecheckException
00644       ("Redefinition of type variable "+name+":\n "
00645        "This variable is already defined.");
00646   }
00647   res = def.getExpr();
00648   // Add the new global declaration
00649   installID(name, res);
00650   return Type(res);
00651 }
00652 
00653 
00654 Expr Theory::resolveID(const string& name) {
00655   TRACE("vars", "resolveID(", name, ") {");
00656   Expr res; // Result is Null by default
00657   // First, look up the bound variable stack
00658   for(vector<pair<string, Expr> >::iterator
00659         i=d_theoryCore->d_boundVarStack.begin(),
00660         iend=d_theoryCore->d_boundVarStack.end();
00661       i!=iend && res.isNull(); ++i) {
00662     if(i->first == name)
00663       res = i->second;
00664   }
00665   if(res.isNull()) {
00666     // Next, check in the globals
00667     map<string,Expr>::iterator i=d_theoryCore->d_globals.find(name),
00668       iend=d_theoryCore->d_globals.end();
00669     if(i!=iend)
00670       res = i->second;
00671   }
00672   TRACE("vars", "resolveID => ", res, " }");
00673   return res;
00674 }
00675 
00676 
00677 void Theory::installID(const string& name, const Expr& e)
00678 {
00679   DebugAssert(resolveID(name).isNull(),
00680               "installID called on existing identifier");
00681   d_theoryCore->d_globals[name] = e;
00682 }
00683 
00684 
00685 Theorem Theory::typePred(const Expr& e) {
00686   return d_theoryCore->typePred(e);
00687 }
00688 
00689 
00690 Theorem Theory::subtypePredicate(const Expr& e) {
00691   return d_theoryCore->subtypePredicate(e);
00692 }

Generated on Thu Apr 13 16:57:33 2006 for CVC Lite by  doxygen 1.4.4