00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #ifndef _cvc3__expr_h_
00023 #define _cvc3__expr_h_
00024 
00025 #include <stdlib.h>
00026 #include <sstream>
00027 #include <set>
00028 #include <functional>
00029 #include <iterator>
00030 #include <map>
00031 
00032 #include "os.h"
00033 #include "compat_hash_map.h"
00034 #include "compat_hash_set.h"
00035 #include "rational.h"
00036 #include "kinds.h"
00037 #include "cdo.h"
00038 #include "cdflags.h"
00039 #include "lang.h"
00040 #include "memory_manager.h"
00041 
00042 class CInterface;
00043 
00044 namespace CVC3 {
00045 
00046   class NotifyList;
00047   class Theory;
00048   class Op;
00049   class Type;
00050   class Theorem;
00051 
00052   template<class Data>
00053   class ExprHashMap;
00054 
00055   class ExprManager;
00056   
00057   class ExprValue;
00058   class ExprNode;
00059   
00060   class ExprStream;
00061 
00062 
00063 
00064 
00065   typedef enum {
00066     EXPR_VALUE,
00067     EXPR_NODE,
00068     EXPR_APPLY, 
00069     EXPR_STRING,
00070     EXPR_RATIONAL,
00071     EXPR_SKOLEM,
00072     EXPR_UCONST,
00073     EXPR_SYMBOL,
00074     EXPR_BOUND_VAR,
00075     EXPR_CLOSURE,
00076     EXPR_THEOREM,
00077     EXPR_VALUE_TYPE_LAST 
00078   } ExprValueType;
00079 
00080 
00081   typedef long long unsigned ExprIndex;
00082 
00083   
00084 
00085 
00086 
00087   
00088 
00089 
00090 
00091   
00092 
00093   
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126   
00127 class CVC_DLL Expr {
00128   friend class ExprHasher;
00129   friend class ExprManager;
00130   friend class Op;
00131   friend class ExprValue;
00132   friend class ExprNode;
00133   friend class ::CInterface;
00134   friend class Theorem;
00135 
00136 
00137 
00138 
00139 
00140   typedef enum {
00141 
00142     VALID_TYPE = 0x1,
00143 
00144     VALID_IS_ATOMIC = 0x2,
00145 
00146     IS_ATOMIC = 0x4,
00147 
00148     REWRITE_NORMAL = 0x8,
00149 
00150     IS_FINITE = 0x400,
00151 
00152     WELL_FOUNDED = 0x800,
00153 
00154     COMPUTE_TRANS_CLOSURE = 0x1000,
00155 
00156     CONTAINS_BOUND_VAR = 0x00020000
00157   } StaticFlagsEnum;
00158 
00159 
00160   
00161   typedef enum {
00162 
00163     IMPLIED_LITERAL = 0x10,
00164     IS_USER_ASSUMPTION = 0x20,
00165     IS_INT_ASSUMPTION = 0x40,
00166     IS_JUSTIFIED = 0x80,
00167     IS_TRANSLATED = 0x100,
00168     IS_USER_REGISTERED_ATOM = 0x200,
00169     IS_SELECTED = 0x2000,
00170     IS_STORED_PREDICATE = 0x4000,
00171     IS_REGISTERED_ATOM = 0x8000,
00172     IN_USER_ASSUMPTION = 0x00010000
00173   } DynamicFlagsEnum;
00174 
00175 
00176   static Expr s_null;
00177 
00178 
00179   
00180 
00181 
00182   ExprValue* d_expr;
00183 
00184 
00185   
00186 
00187 
00188 
00189   Expr(ExprValue* expr);
00190 
00191   Expr recursiveSubst(const ExprHashMap<Expr>& subst,
00192                       ExprHashMap<Expr>& visited) const;
00193 public:
00194 
00195   
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208   class CVC_DLL iterator
00209     : public std::iterator<std::input_iterator_tag,Expr,ptrdiff_t>
00210   {
00211     friend class Expr;
00212   private:
00213     std::vector<Expr>::const_iterator d_it;
00214     
00215     
00216 
00217     iterator(std::vector<Expr>::const_iterator it): d_it(it) { }
00218     
00219   public:
00220 
00221     iterator() { }
00222     
00223 
00224 
00225     bool operator==(const iterator& i) const {
00226       return d_it == i.d_it;
00227     }
00228 
00229     bool operator!=(const iterator& i) const { return !(*this == i); }
00230 
00231     const Expr& operator*() const { return *d_it; }
00232 
00233     const Expr* operator->() const { return &(operator*()); }
00234 
00235     iterator& operator++() {
00236       d_it++;
00237       return *this;
00238     }
00239 
00240 
00241     class Proxy {
00242       const Expr* d_e;
00243     public:
00244       Proxy(const Expr& e) : d_e(&e) { }
00245       Expr operator*() { return *d_e; }
00246     };
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254     Proxy operator++(int) {
00255       Proxy e(*(*this));
00256       ++(*this);
00257       return e;
00258     }
00259   }; 
00260 
00261 
00262   
00263 
00264 
00265 
00266   Expr(): d_expr(NULL) {}
00267 
00268 
00269 
00270   Expr(const Expr& e);
00271 
00272   Expr& operator=(const Expr& e);
00273 
00274   
00275   
00276   
00277   Expr(const Op& op, const Expr& child);
00278   Expr(const Op& op, const Expr& child0, const Expr& child1);
00279   Expr(const Op& op, const Expr& child0, const Expr& child1,
00280        const Expr& child2);
00281   Expr(const Op& op, const Expr& child0, const Expr& child1,
00282        const Expr& child2, const Expr& child3);
00283   Expr(const Op& op, const std::vector<Expr>& children,
00284        ExprManager* em = NULL);
00285 
00286 
00287   ~Expr();
00288 
00289   
00290   Expr eqExpr(const Expr& right) const;
00291   Expr notExpr() const;
00292   Expr negate() const; 
00293   Expr andExpr(const Expr& right) const;
00294   Expr orExpr(const Expr& right) const;
00295   Expr iteExpr(const Expr& thenpart, const Expr& elsepart) const;
00296   Expr iffExpr(const Expr& right) const;
00297   Expr impExpr(const Expr& right) const;
00298 
00299   Expr skolemExpr(int i) const;
00300 
00301   
00302 
00303   Expr rebuild(ExprManager* em) const;
00304 
00305 
00306   Expr substExpr(const std::vector<Expr>& oldTerms,
00307                  const std::vector<Expr>& newTerms) const;
00308   Expr substExpr(const ExprHashMap<Expr>& oldToNew) const;
00309 
00310   Expr operator!() const { return notExpr(); }
00311   Expr operator&&(const Expr& right) const { return andExpr(right); }
00312   Expr operator||(const Expr& right) const { return orExpr(right); }
00313 
00314 
00315   
00316 
00317 
00318   static size_t hash(const Expr& e);
00319 
00320 
00321   
00322 
00323 
00324   size_t hash() const;
00325 
00326   
00327 
00328   bool isFalse() const { return getKind() == FALSE_EXPR; }
00329   bool isTrue() const { return getKind() == TRUE_EXPR; }
00330   bool isBoolConst() const { return isFalse() || isTrue(); }
00331   bool isVar() const;
00332   bool isBoundVar() const { return getKind() == BOUND_VAR; }
00333   bool isString() const;
00334   bool isClosure() const;
00335   bool isQuantifier() const;
00336   bool isLambda() const;
00337   bool isApply() const;
00338   bool isSymbol() const;
00339   bool isTheorem() const;
00340 
00341   bool isType() const;
00342   
00343 
00344 
00345 
00346 
00347 
00348   
00349 
00350   const ExprValue* getExprValue() const;
00351 
00352 
00353   bool isTerm() const;
00354 
00355 
00356 
00357 
00358   bool isAtomic() const;
00359 
00360 
00361 
00362 
00363 
00364   bool isAtomicFormula() const;
00365 
00366   bool isAbsAtomicFormula() const
00367     { return isQuantifier() || isAtomicFormula(); }
00368 
00369 
00370 
00371   bool isLiteral() const
00372   { return (isAtomicFormula() || (isNot() && (*this)[0].isAtomicFormula())); }
00373 
00374   bool isAbsLiteral() const
00375   { return (isAbsAtomicFormula() || (isNot() && (*this)[0].isAbsAtomicFormula())); }
00376 
00377   bool isBoolConnective() const;
00378 
00379   bool isPropAtom() const { return !isBoolConnective(); }
00380 
00381   bool isPropLiteral() const
00382     { return (isNot() && (*this)[0].isPropAtom()) || isPropAtom(); }
00383 
00384   bool isEq() const { return getKind() == EQ; }
00385   bool isNot() const { return getKind() == NOT; }
00386   bool isAnd() const { return getKind() == AND; }
00387   bool isOr() const { return getKind() == OR; }
00388   bool isITE() const { return getKind() == ITE; }
00389   bool isIff() const { return getKind() == IFF; }
00390   bool isImpl() const { return getKind() == IMPLIES; }
00391   bool isXor() const { return getKind() == XOR;}
00392 
00393   bool isForall() const { return getKind() == FORALL; }
00394   bool isExists() const { return getKind() == EXISTS; }
00395 
00396   bool isRational() const { return getKind() == RATIONAL_EXPR; }
00397   bool isSkolem() const { return getKind() == SKOLEM_VAR;}
00398 
00399   
00400   
00401 
00402   
00403   const std::string& getName() const;
00404 
00405   const std::string& getUid() const;
00406 
00407   
00408   const std::string& getString() const; 
00409 
00410   const std::vector<Expr>& getVars() const;
00411 
00412   const Expr& getExistential() const;
00413 
00414   int getBoundIndex() const;
00415  
00416 
00417   const Expr& getBody() const;
00418 
00419   const Rational& getRational() const; 
00420 
00421   const Theorem& getTheorem() const;
00422 
00423   
00424   ExprManager *getEM() const;
00425 
00426   
00427   const std::vector<Expr>& getKids() const;
00428 
00429   
00430   int getKind() const;
00431 
00432   
00433   ExprIndex getIndex() const;
00434 
00435   
00436   bool hasLastIndex() const;
00437 
00438 
00439   Op mkOp() const;
00440 
00441 
00442   Op getOp() const;
00443 
00444 
00445   Expr getOpExpr() const;
00446 
00447 
00448   int getOpKind() const;
00449 
00450   
00451   
00452   
00453   
00454   int arity() const;
00455 
00456   
00457   
00458   const Expr& operator[](int i) const;
00459 
00460 
00461   const Expr& unnegate() const { return isNot() ? (*this)[0] : *this; }
00462 
00463 
00464   iterator begin() const;
00465 
00466 
00467   iterator end() const;
00468 
00469   
00470   bool isNull() const;
00471 
00472   
00473   bool isInitialized() const { return d_expr != NULL; }
00474 
00475   size_t getMMIndex() const;
00476 
00477   
00478 
00479   
00480   bool hasFind() const;
00481 
00482   
00483   
00484   
00485   const Theorem& getFind() const;
00486 
00487   int getFindLevel() const;
00488 
00489   
00490   NotifyList* getNotify() const;
00491 
00492 
00493   const Type getType() const;
00494 
00495   const Type lookupType() const;
00496 
00497 
00498 
00499   bool validSimpCache() const;
00500 
00501   
00502   const Theorem& getSimpCache() const;
00503 
00504   
00505   bool isValidType() const;
00506 
00507   
00508   bool validIsAtomicFlag() const;
00509 
00510   
00511   bool getIsAtomicFlag() const;
00512 
00513   
00514   bool isRewriteNormal() const;
00515 
00516   
00517   bool isFinite() const;
00518 
00519   
00520   bool isWellFounded() const;
00521 
00522   
00523   bool computeTransClosure() const;
00524 
00525   
00526   bool containsBoundVar() const;
00527 
00528   
00529   bool isImpliedLiteral() const;
00530 
00531   
00532   bool isUserAssumption() const;
00533 
00534   
00535   bool inUserAssumption() const;
00536 
00537   
00538   bool isIntAssumption() const;
00539 
00540   
00541   bool isJustified() const;
00542 
00543   
00544   bool isTranslated() const;
00545 
00546   
00547   bool isUserRegisteredAtom() const;
00548 
00549   
00550   bool isRegisteredAtom() const;
00551 
00552   
00553   bool isSelected() const;
00554 
00555   
00556   bool isStoredPredicate() const;
00557 
00558 
00559   bool getFlag() const;
00560 
00561   void setFlag() const;
00562 
00563   void clearFlags() const;
00564 
00565   
00566 
00567 
00568   std::string toString() const;
00569 
00570   std::string toString(InputLanguage lang) const;
00571 
00572   void print(InputLanguage lang, bool dagify = true) const;
00573 
00574 
00575   void print() const { print(AST_LANG); }
00576 
00577   void printnodag() const;
00578 
00579 
00580   void pprint() const;
00581 
00582   void pprintnodag() const;
00583 
00584 
00585   
00586 
00587 
00588   ExprStream& print(ExprStream& os) const;
00589 
00590   
00591 
00592   ExprStream& printAST(ExprStream& os) const;
00593 
00594 
00595 
00596 
00597 
00598   Expr& indent(int n, bool permanent = false);
00599 
00600 
00601   
00602 
00603 
00604   
00605 
00606 
00607   void setFind(const Theorem& e) const;
00608 
00609 
00610   void addToNotify(Theory* i, const Expr& e) const;
00611 
00612 
00613   void setType(const Type& t) const;
00614 
00615   
00616   void setSimpCache(const Theorem& e) const;
00617 
00618   
00619   void setValidType() const;
00620 
00621   
00622   void setIsAtomicFlag(bool value) const;
00623 
00624   
00625   void setRewriteNormal() const;
00626   void clearRewriteNormal() const;
00627 
00628   
00629   void setFinite() const;
00630 
00631   
00632   void setWellFounded() const;
00633 
00634   
00635   void setComputeTransClosure() const;
00636 
00637   
00638   void setContainsBoundVar() const;
00639 
00640   
00641   void setImpliedLiteral() const;
00642 
00643   
00644   void setUserAssumption(int scope = -1) const;
00645 
00646   
00647   void setInUserAssumption(int scope = -1) const;
00648 
00649   
00650   void setIntAssumption() const;
00651 
00652   
00653   void setJustified() const;
00654 
00655 
00656   void setTranslated(int scope = -1) const;
00657 
00658 
00659   void setUserRegisteredAtom() const;
00660 
00661 
00662   void setRegisteredAtom() const;
00663 
00664 
00665   void setSelected() const;
00666 
00667 
00668   void setStoredPredicate() const;
00669 
00670 
00671   bool subExprOf(const Expr& e) const;
00672   
00673   
00674 
00675 
00676 
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
00685   
00686   bool hasSig() const;
00687   bool hasRep() const;
00688   const Theorem& getSig() const;
00689   const Theorem& getRep() const;
00690   void setSig(const Theorem& e) const;
00691   void setRep(const Theorem& e) const;
00692 
00693 
00694   
00695 
00696 
00697   friend CVC_DLL std::ostream& operator<<(std::ostream& os, const Expr& e);
00698 
00699   
00700   
00701   
00702   
00703   friend int compare(const Expr& e1, const Expr& e2);
00704 
00705   friend bool operator==(const Expr& e1, const Expr& e2);
00706   friend bool operator!=(const Expr& e1, const Expr& e2);
00707 
00708   friend bool operator<(const Expr& e1, const Expr& e2);
00709   friend bool operator<=(const Expr& e1, const Expr& e2);
00710   friend bool operator>(const Expr& e1, const Expr& e2);
00711   friend bool operator>=(const Expr& e1, const Expr& e2);
00712 
00713  
00714 
00715 }; 
00716 
00717 } 
00718 
00719 
00720 
00721 #ifndef DOXYGEN
00722 #include "expr_op.h"
00723 #include "expr_manager.h"
00724 #endif
00725 namespace CVC3 {
00726 
00727 inline Expr::Expr(ExprValue* expr) : d_expr(expr) { d_expr->incRefcount(); }
00728 
00729 inline Expr::Expr(const Expr& e) : d_expr(e.d_expr) {
00730   if (d_expr != NULL) d_expr->incRefcount();
00731 }
00732 
00733 inline Expr& Expr::operator=(const Expr& e) {
00734   if(&e == this) return *this; 
00735   ExprValue* tmp = e.d_expr;
00736   if (tmp == NULL) {
00737     if (d_expr == NULL) {
00738       return *this;
00739     }
00740     d_expr->decRefcount();
00741   }
00742   else {
00743     tmp->incRefcount();  
00744     if(d_expr != NULL) {
00745       d_expr->decRefcount();
00746     }
00747   }
00748   d_expr = tmp;
00749   return *this;
00750 }
00751 
00752 inline Expr::Expr(const Op& op, const Expr& child) {
00753   ExprManager* em = child.getEM();
00754   if (op.getExpr().isNull()) {
00755     ExprNode ev(em, op.getKind());
00756     std::vector<Expr>& kids = ev.getKids1();
00757     kids.push_back(child);
00758     d_expr = em->newExprValue(&ev);
00759   } else {
00760     ExprApply ev(em, op);
00761     std::vector<Expr>& kids = ev.getKids1();
00762     kids.push_back(child);
00763     d_expr = em->newExprValue(&ev);
00764   }
00765   d_expr->incRefcount();  
00766 }
00767  
00768 inline Expr::Expr(const Op& op, const Expr& child0, const Expr& child1) {
00769   ExprManager* em = child0.getEM();
00770   if (op.getExpr().isNull()) {
00771     ExprNode ev(em, op.getKind());
00772     std::vector<Expr>& kids = ev.getKids1();
00773     kids.push_back(child0);
00774     kids.push_back(child1);
00775     d_expr = em->newExprValue(&ev);
00776   } else {
00777     ExprApply ev(em, op);
00778     std::vector<Expr>& kids = ev.getKids1();
00779     kids.push_back(child0);
00780     kids.push_back(child1);
00781     d_expr = em->newExprValue(&ev);
00782   }
00783   d_expr->incRefcount();  
00784 }
00785 
00786 inline Expr::Expr(const Op& op, const Expr& child0, const Expr& child1,
00787                   const Expr& child2) {
00788   ExprManager* em = child0.getEM();
00789   if (op.getExpr().isNull()) {
00790     ExprNode ev(em, op.getKind());
00791     std::vector<Expr>& kids = ev.getKids1();
00792     kids.push_back(child0);
00793     kids.push_back(child1);
00794     kids.push_back(child2);
00795     d_expr = em->newExprValue(&ev);
00796   } else {
00797     ExprApply ev(em, op);
00798     std::vector<Expr>& kids = ev.getKids1();
00799     kids.push_back(child0);
00800     kids.push_back(child1);
00801     kids.push_back(child2);
00802     d_expr = em->newExprValue(&ev);
00803   }
00804   d_expr->incRefcount();  
00805 }
00806 
00807 inline Expr::Expr(const Op& op, const Expr& child0, const Expr& child1,
00808                   const Expr& child2, const Expr& child3) {
00809   ExprManager* em = child0.getEM();
00810   if (op.getExpr().isNull()) {
00811     ExprNode ev(em, op.getKind());
00812     std::vector<Expr>& kids = ev.getKids1();
00813     kids.push_back(child0);
00814     kids.push_back(child1);
00815     kids.push_back(child2);
00816     kids.push_back(child3);
00817     d_expr = em->newExprValue(&ev);
00818   } else {
00819     ExprApply ev(em, op);
00820     std::vector<Expr>& kids = ev.getKids1();
00821     kids.push_back(child0);
00822     kids.push_back(child1);
00823     kids.push_back(child2);
00824     kids.push_back(child3);
00825     d_expr = em->newExprValue(&ev);
00826   }
00827   d_expr->incRefcount();
00828 }
00829 
00830 inline Expr::Expr(const Op& op, const std::vector<Expr>& children,
00831                   ExprManager* em) {
00832   if (em == NULL) {
00833     if (!op.getExpr().isNull()) em = op.getExpr().getEM();
00834     else {
00835       DebugAssert(children.size() > 0,
00836                   "Expr::Expr(Op, children): op's EM is NULL and "
00837                   "no children given");
00838       em = children[0].getEM();
00839     }
00840   }
00841   if (op.getExpr().isNull()) {
00842     ExprNodeTmp ev(em, op.getKind(), children);
00843     d_expr = em->newExprValue(&ev);
00844   } else {
00845     ExprApplyTmp ev(em, op, children);
00846     d_expr = em->newExprValue(&ev);
00847   }
00848   d_expr->incRefcount();
00849 }
00850 
00851 inline Expr Expr::eqExpr(const Expr& right) const {
00852   return Expr(EQ, *this, right);
00853 }
00854 
00855 inline Expr Expr::notExpr() const {
00856   return Expr(NOT, *this);
00857 }
00858 
00859 inline Expr Expr::negate() const {
00860   return isNot() ? (*this)[0] : this->notExpr();
00861 }
00862 
00863 inline Expr Expr::andExpr(const Expr& right) const {
00864   return Expr(AND, *this, right);
00865 }
00866 
00867 inline Expr andExpr(const std::vector <Expr>& children) {
00868   DebugAssert(children.size()>0 && !children[0].isNull(),
00869               "Expr::andExpr(kids)");
00870   return Expr(AND, children);
00871 }
00872 
00873 inline Expr Expr::orExpr(const Expr& right) const {
00874   return Expr(OR, *this, right);
00875 }
00876 
00877 inline Expr orExpr(const std::vector <Expr>& children) {
00878   DebugAssert(children.size()>0 && !children[0].isNull(),
00879               "Expr::andExpr(kids)");
00880   return Expr(OR, children);
00881 }
00882 
00883 inline Expr Expr::iteExpr(const Expr& thenpart, const Expr& elsepart) const {
00884   return Expr(ITE, *this, thenpart, elsepart);
00885 }
00886 
00887 inline Expr Expr::iffExpr(const Expr& right) const {
00888   return Expr(IFF, *this, right);
00889 }
00890 
00891 inline Expr Expr::impExpr(const Expr& right) const {
00892   return Expr(IMPLIES, *this, right);
00893 }
00894 
00895 inline Expr Expr::skolemExpr(int i) const {
00896   return getEM()->newSkolemExpr(*this, i);
00897 }
00898 
00899 inline Expr Expr::rebuild(ExprManager* em) const {
00900   return em->rebuild(*this);
00901 }
00902 
00903 inline Expr::~Expr() {
00904   if(d_expr != NULL) {
00905     d_expr->decRefcount();
00906   }
00907 }
00908 
00909 inline size_t Expr::hash(const Expr& e) { return e.getEM()->hash(e); }
00910 
00911 
00912 
00913 
00914 
00915 inline size_t Expr::hash() const { return getEM()->hash(*this); }
00916 
00917 inline const ExprValue* Expr::getExprValue() const
00918   { return d_expr->getExprValue(); }
00919 
00920 
00921 
00922 inline bool Expr::isVar() const { return d_expr->isVar(); }
00923 inline bool Expr::isString() const { return d_expr->isString(); }
00924 inline bool Expr::isClosure() const { return d_expr->isClosure(); }
00925 inline bool Expr::isQuantifier() const {
00926   return (isClosure() && (getKind() == FORALL || getKind() == EXISTS));
00927 }
00928 inline bool Expr::isLambda() const {
00929   return (isClosure() && getKind() == LAMBDA);
00930 }
00931 inline bool Expr::isApply() const 
00932 { DebugAssert((getKind() != APPLY || d_expr->isApply()) &&
00933               (!d_expr->isApply() || getKind() == APPLY), "APPLY mismatch");
00934   return d_expr->isApply(); }
00935 inline bool Expr::isSymbol() const { return d_expr->isSymbol(); }
00936 inline bool Expr::isTheorem() const { return d_expr->isTheorem(); }
00937 inline bool Expr::isType() const { return getEM()->isTypeKind(getOpKind()); }
00938 inline bool Expr::isTerm() const { return !getType().isBool(); }
00939 inline bool Expr::isBoolConnective() const {
00940   if (!getType().isBool()) return false;
00941   switch (getKind()) {
00942     case NOT: case AND: case OR: case IMPLIES: case IFF: case XOR: case ITE:
00943       return true; }
00944   return false;
00945 }
00946 
00947   
00948   
00949 
00950   
00951 
00952 
00953 
00954 
00955 
00956 
00957 
00958 
00959 inline const std::string& Expr::getName() const {
00960   DebugAssert(!isNull(), "Expr::getName() on Null expr");
00961   return d_expr->getName();
00962 }
00963 
00964 inline const std::string& Expr::getString() const {
00965    DebugAssert(isString(),
00966         "CVC3::Expr::getString(): not a string Expr:\n  "
00967         + toString(AST_LANG));
00968    return d_expr->getString();
00969 }
00970 
00971 inline const std::vector<Expr>& Expr::getVars() const {
00972    DebugAssert(isClosure(),
00973         "CVC3::Expr::getVars(): not a closure Expr:\n  "
00974         + toString(AST_LANG));
00975    return d_expr->getVars();
00976 }
00977 
00978 inline const Expr& Expr::getBody() const {
00979    DebugAssert(isClosure(),
00980         "CVC3::Expr::getBody(): not a closure Expr:\n  "
00981         + toString(AST_LANG));
00982    return d_expr->getBody();
00983 }
00984 
00985 inline const Expr& Expr::getExistential() const {
00986   DebugAssert(isSkolem(),
00987               "CVC3::Expr::getExistential() not a skolem variable");
00988   return d_expr->getExistential();
00989 }
00990 inline int Expr::getBoundIndex() const {
00991   DebugAssert(isSkolem(),
00992               "CVC3::Expr::getBoundIndex() not a skolem variable");
00993   return d_expr->getBoundIndex();
00994 }
00995 
00996 
00997 inline const Rational& Expr::getRational() const {
00998   DebugAssert(isRational(),
00999         "CVC3::Expr::getRational(): not a rational Expr:\n  "
01000         + toString(AST_LANG));
01001    return d_expr->getRational();
01002 }
01003 
01004 inline const Theorem& Expr::getTheorem() const {
01005   DebugAssert(isTheorem(),
01006         "CVC3::Expr::getTheorem(): not a Theorem Expr:\n  "
01007         + toString(AST_LANG));
01008    return d_expr->getTheorem();
01009 }
01010 
01011 inline const std::string& Expr::getUid() const {
01012    DebugAssert(getKind() == BOUND_VAR,
01013         "CVC3::Expr::getUid(): not a BOUND_VAR Expr:\n  "
01014         + toString(AST_LANG));
01015    return d_expr->getUid();
01016 }
01017 
01018 inline ExprManager* Expr::getEM() const {
01019   DebugAssert(d_expr != NULL,
01020               "CVC3::Expr:getEM: on Null Expr (not initialized)");
01021   return d_expr->d_em;
01022 }
01023 
01024 inline const std::vector<Expr>& Expr::getKids() const {
01025   DebugAssert(d_expr != NULL, "Expr::getKids on Null Expr");
01026   if(isNull()) return getEM()->getEmptyVector();
01027   else return d_expr->getKids();
01028 }
01029 
01030 inline int Expr::getKind() const {
01031    if(d_expr == NULL) return NULL_KIND; 
01032    return d_expr->d_kind;
01033  }
01034 
01035 inline ExprIndex Expr::getIndex() const { return d_expr->d_index; }
01036 
01037 inline bool Expr::hasLastIndex() const
01038 { return d_expr->d_em->lastIndex() == getIndex(); }
01039 
01040 inline Op Expr::mkOp() const {
01041   DebugAssert(!isNull(), "Expr::mkOp() on Null expr");
01042   return Op(*this);
01043 }
01044 
01045 inline Op Expr::getOp() const {
01046   DebugAssert(!isNull(), "Expr::getOp() on Null expr");
01047   if (isApply()) return d_expr->getOp();
01048   DebugAssert(arity() > 0,
01049               "Expr::getOp() called on non-apply expr with no children");
01050   return Op(getKind());
01051 }
01052 
01053 inline Expr Expr::getOpExpr() const {
01054   DebugAssert(isApply(), "getOpExpr() called on non-apply");
01055   return getOp().getExpr();
01056 }
01057 
01058 inline int Expr::getOpKind() const {
01059   if (!isApply()) return getKind();
01060   return getOp().getExpr().getKind();
01061 }
01062 
01063 inline int Expr::arity() const {
01064   if(isNull()) return 0;
01065   else return d_expr->arity();
01066 }
01067 
01068 inline const Expr& Expr::operator[](int i) const {
01069   DebugAssert(i < arity(), "out of bounds access");
01070   return (d_expr->getKids())[i];
01071 }
01072 
01073 inline Expr::iterator Expr::begin() const {
01074   if (isNull() || d_expr->arity() == 0)
01075     return Expr::iterator(getEM()->getEmptyVector().begin());
01076   else return Expr::iterator(d_expr->getKids().begin());
01077 }
01078 
01079 inline Expr::iterator Expr::end() const {
01080   if (isNull() || d_expr->arity() == 0)
01081     return Expr::iterator(getEM()->getEmptyVector().end());
01082   else return Expr::iterator(d_expr->getKids().end());
01083 }
01084 
01085 inline bool Expr::isNull() const {
01086   return (d_expr == NULL) || (d_expr->d_kind == NULL_KIND);
01087 }
01088 
01089 inline size_t Expr::getMMIndex() const {
01090   DebugAssert(!isNull(), "Expr::getMMIndex()");
01091   return d_expr->getMMIndex();
01092 }
01093 
01094 inline bool Expr::hasFind() const {
01095   DebugAssert(!isNull(), "hasFind called on NULL Expr");
01096   return (d_expr->d_find && !(d_expr->d_find->get().isNull()));
01097 }
01098 
01099 inline const Theorem& Expr::getFind() const {
01100   DebugAssert(hasFind(), "Should only be called if find is valid");
01101   return d_expr->d_find->get();
01102 }
01103 
01104 inline int  Expr::getFindLevel() const {
01105   DebugAssert(hasFind(), "Should only be called if find is valid");
01106   return d_expr->d_find->level();
01107 }
01108 
01109 inline NotifyList* Expr::getNotify() const {
01110   if(isNull()) return NULL;
01111   else return d_expr->d_notifyList;
01112 }
01113 
01114 inline const Type Expr::getType() const {
01115   if (isNull()) return s_null;
01116   if(d_expr->d_type.isNull()) getEM()->computeType(*this);
01117   return d_expr->d_type;
01118 }
01119 
01120 inline const Type Expr::lookupType() const {
01121   if (isNull()) return s_null;
01122   return d_expr->d_type;
01123 }
01124 
01125 inline bool Expr::validSimpCache() const {
01126   return d_expr->d_simpCacheTag == getEM()->getSimpCacheTag();
01127 }
01128 
01129 inline const Theorem& Expr::getSimpCache() const {
01130   return d_expr->d_simpCache;
01131 }
01132 
01133 inline bool Expr::isValidType() const {
01134   return d_expr->d_dynamicFlags.get(VALID_TYPE);
01135 }
01136 
01137 inline bool Expr::validIsAtomicFlag() const {
01138   return d_expr->d_dynamicFlags.get(VALID_IS_ATOMIC);
01139 }
01140 
01141 inline bool Expr::getIsAtomicFlag() const {
01142   return d_expr->d_dynamicFlags.get(IS_ATOMIC);
01143 }
01144 
01145 inline bool Expr::isRewriteNormal() const {
01146   return d_expr->d_dynamicFlags.get(REWRITE_NORMAL);
01147 }
01148 
01149 inline bool Expr::isFinite() const {
01150   return d_expr->d_dynamicFlags.get(IS_FINITE);
01151 }
01152 
01153 inline bool Expr::isWellFounded() const {
01154   return d_expr->d_dynamicFlags.get(WELL_FOUNDED);
01155 }
01156 
01157 inline bool Expr::computeTransClosure() const {
01158   return d_expr->d_dynamicFlags.get(COMPUTE_TRANS_CLOSURE);
01159 }
01160 
01161 inline bool Expr::containsBoundVar() const {
01162   return d_expr->d_dynamicFlags.get(CONTAINS_BOUND_VAR);
01163 }
01164 
01165 inline bool Expr::isImpliedLiteral() const {
01166   return d_expr->d_dynamicFlags.get(IMPLIED_LITERAL);
01167 }
01168 
01169 inline bool Expr::isUserAssumption() const {
01170   return d_expr->d_dynamicFlags.get(IS_USER_ASSUMPTION);
01171 }
01172 
01173 inline bool Expr::inUserAssumption() const {
01174   return d_expr->d_dynamicFlags.get(IN_USER_ASSUMPTION);
01175 }
01176 
01177 inline bool Expr::isIntAssumption() const {
01178   return d_expr->d_dynamicFlags.get(IS_INT_ASSUMPTION);
01179 }
01180 
01181 inline bool Expr::isJustified() const {
01182   return d_expr->d_dynamicFlags.get(IS_JUSTIFIED);
01183 }
01184 
01185 inline bool Expr::isTranslated() const {
01186   return d_expr->d_dynamicFlags.get(IS_TRANSLATED);
01187 }
01188 
01189 inline bool Expr::isUserRegisteredAtom() const {
01190   return d_expr->d_dynamicFlags.get(IS_USER_REGISTERED_ATOM);
01191 }
01192 
01193 inline bool Expr::isRegisteredAtom() const {
01194   return d_expr->d_dynamicFlags.get(IS_REGISTERED_ATOM);
01195 }
01196 
01197 inline bool Expr::isSelected() const {
01198   return d_expr->d_dynamicFlags.get(IS_SELECTED);
01199 }
01200 
01201 inline bool Expr::isStoredPredicate() const {
01202   return d_expr->d_dynamicFlags.get(IS_STORED_PREDICATE);
01203 }
01204 
01205 inline bool Expr::getFlag() const {
01206   DebugAssert(!isNull(), "Expr::getFlag() on Null Expr");
01207   return (d_expr->d_flag == getEM()->getFlag());
01208 }
01209 
01210 inline void Expr::setFlag() const {
01211   DebugAssert(!isNull(), "Expr::setFlag() on Null Expr");
01212   d_expr->d_flag = getEM()->getFlag();
01213 }
01214 
01215 inline void Expr::clearFlags() const {
01216   DebugAssert(!isNull(), "Expr::clearFlags() on Null Expr");
01217   getEM()->clearFlags();
01218 }
01219 
01220 inline void Expr::setFind(const Theorem& e) const {
01221   DebugAssert(!isNull(), "Expr::setFind() on Null expr");
01222   DebugAssert(e.getLHS() == *this, "bad call to setFind");
01223   if (d_expr->d_find) d_expr->d_find->set(e);
01224   else {
01225     CDO<Theorem>* tmp = new(true) CDO<Theorem>(getEM()->getCurrentContext(), e);
01226     d_expr->d_find = tmp;
01227     IF_DEBUG(tmp->setName("CDO[Expr.find]"));
01228   }
01229 }
01230 
01231 inline void Expr::setType(const Type& t) const {
01232   DebugAssert(!isNull(), "Expr::setType() on Null expr");
01233   d_expr->d_type = t;
01234 }
01235 
01236 inline void Expr::setSimpCache(const Theorem& e) const {
01237   DebugAssert(!isNull(), "Expr::setSimpCache() on Null expr");
01238   d_expr->d_simpCache = e;
01239   d_expr->d_simpCacheTag = getEM()->getSimpCacheTag();
01240 }
01241 
01242 inline void Expr::setValidType() const {
01243   DebugAssert(!isNull(), "Expr::setValidType() on Null expr");
01244   d_expr->d_dynamicFlags.set(VALID_TYPE, 0);
01245 }
01246 
01247 inline void Expr::setIsAtomicFlag(bool value) const {
01248   DebugAssert(!isNull(), "Expr::setIsAtomicFlag() on Null expr");
01249   d_expr->d_dynamicFlags.set(VALID_IS_ATOMIC, 0);
01250   if (value) d_expr->d_dynamicFlags.set(IS_ATOMIC, 0);
01251   else d_expr->d_dynamicFlags.clear(IS_ATOMIC, 0);
01252 }
01253 
01254 inline void Expr::setRewriteNormal() const {
01255   DebugAssert(!isNull(), "Expr::setRewriteNormal() on Null expr");
01256   TRACE("setRewriteNormal", "setRewriteNormal(", *this, ")");
01257   d_expr->d_dynamicFlags.set(REWRITE_NORMAL, 0);
01258 }
01259 
01260 inline void Expr::setFinite() const {
01261   DebugAssert(!isNull(), "Expr::setFinite() on Null expr");
01262   d_expr->d_dynamicFlags.set(IS_FINITE, 0);
01263 }
01264 
01265 inline void Expr::setWellFounded() const {
01266   DebugAssert(!isNull(), "Expr::setWellFounded() on Null expr");
01267   d_expr->d_dynamicFlags.set(WELL_FOUNDED, 0);
01268 }
01269 
01270 inline void Expr::setComputeTransClosure() const {
01271   DebugAssert(!isNull(), "Expr::setComputeTransClosure() on Null expr");
01272   d_expr->d_dynamicFlags.set(COMPUTE_TRANS_CLOSURE, 0);
01273 }
01274 
01275 inline void Expr::setContainsBoundVar() const {
01276   DebugAssert(!isNull(), "Expr::setContainsBoundVar() on Null expr");
01277   d_expr->d_dynamicFlags.set(CONTAINS_BOUND_VAR, 0);
01278 }
01279 
01280 inline void Expr::setImpliedLiteral() const {
01281   DebugAssert(!isNull(), "Expr::setImpliedLiteral() on Null expr");
01282   d_expr->d_dynamicFlags.set(IMPLIED_LITERAL);
01283 }
01284 
01285 inline void Expr::setUserAssumption(int scope) const {
01286   DebugAssert(!isNull(), "Expr::setUserAssumption() on Null expr");
01287   d_expr->d_dynamicFlags.set(IS_USER_ASSUMPTION, scope);
01288 }
01289 
01290 inline void Expr::setInUserAssumption(int scope) const {
01291   DebugAssert(!isNull(), "Expr::setInUserAssumption() on Null expr");
01292   d_expr->d_dynamicFlags.set(IN_USER_ASSUMPTION, scope);
01293 }
01294 
01295 inline void Expr::setIntAssumption() const {
01296   DebugAssert(!isNull(), "Expr::setIntAssumption() on Null expr");
01297   d_expr->d_dynamicFlags.set(IS_INT_ASSUMPTION);
01298 }
01299 
01300 inline void Expr::setJustified() const {
01301   DebugAssert(!isNull(), "Expr::setJustified() on Null expr");
01302   d_expr->d_dynamicFlags.set(IS_JUSTIFIED);
01303 }
01304 
01305 inline void Expr::setTranslated(int scope) const {
01306   DebugAssert(!isNull(), "Expr::setTranslated() on Null expr");
01307   d_expr->d_dynamicFlags.set(IS_TRANSLATED, scope);
01308 }
01309 
01310 inline void Expr::setUserRegisteredAtom() const {
01311   DebugAssert(!isNull(), "Expr::setUserRegisteredAtom() on Null expr");
01312   d_expr->d_dynamicFlags.set(IS_USER_REGISTERED_ATOM);
01313 }
01314 
01315 inline void Expr::setRegisteredAtom() const {
01316   DebugAssert(!isNull(), "Expr::setUserRegisteredAtom() on Null expr");
01317   d_expr->d_dynamicFlags.set(IS_REGISTERED_ATOM);
01318 }
01319 
01320 inline void Expr::setSelected() const {
01321   DebugAssert(!isNull(), "Expr::setSelected() on Null expr");
01322   d_expr->d_dynamicFlags.set(IS_SELECTED);
01323 }
01324 
01325 inline void Expr::setStoredPredicate() const {
01326   DebugAssert(!isNull(), "Expr::setStoredPredicate() on Null expr");
01327   d_expr->d_dynamicFlags.set(IS_STORED_PREDICATE);
01328 }
01329 
01330 inline void Expr::clearRewriteNormal() const {
01331   DebugAssert(!isNull(), "Expr::clearRewriteNormal() on Null expr");
01332   d_expr->d_dynamicFlags.clear(REWRITE_NORMAL, 0);
01333 }
01334 
01335 inline bool Expr::hasSig() const {
01336   return (!isNull()
01337           && d_expr->getSig() != NULL 
01338           && !(d_expr->getSig()->get().isNull()));
01339 }
01340 
01341 inline bool Expr::hasRep() const {
01342   return (!isNull()
01343           && d_expr->getRep() != NULL 
01344           && !(d_expr->getRep()->get().isNull()));
01345 }
01346 
01347 inline const Theorem& Expr::getSig() const {
01348   static Theorem nullThm;   
01349   DebugAssert(!isNull(), "Expr::getSig() on Null expr");
01350   if(d_expr->getSig() != NULL)
01351     return d_expr->getSig()->get();
01352   else
01353     return nullThm;
01354 }
01355 
01356 inline const Theorem& Expr::getRep() const {
01357   static Theorem nullThm;
01358   DebugAssert(!isNull(), "Expr::getRep() on Null expr");
01359   if(d_expr->getRep() != NULL)
01360     return d_expr->getRep()->get();
01361   else
01362     return nullThm;
01363 }
01364 
01365 inline void Expr::setSig(const Theorem& e) const {
01366   DebugAssert(!isNull(), "Expr::setSig() on Null expr");
01367   CDO<Theorem>* sig = d_expr->getSig();
01368   if(sig != NULL) sig->set(e);
01369   else {
01370     CDO<Theorem>* tmp = new(true) CDO<Theorem>(getEM()->getCurrentContext(), e);
01371     d_expr->setSig(tmp);
01372     IF_DEBUG(tmp->setName("CDO[Expr.sig] in "+toString()));
01373   }
01374 }
01375 
01376 inline void Expr::setRep(const Theorem& e) const {
01377   DebugAssert(!isNull(), "Expr::setRep() on Null expr");
01378   CDO<Theorem>* rep = d_expr->getRep();
01379   if(rep != NULL) rep->set(e);
01380   else {
01381     CDO<Theorem>* tmp = new(true) CDO<Theorem>(getEM()->getCurrentContext(), e);
01382     d_expr->setRep(tmp);
01383     IF_DEBUG(tmp->setName("CDO[Expr.rep] in "+toString()));
01384   }
01385 }
01386  
01387 inline bool operator==(const Expr& e1, const Expr& e2) {
01388   
01389   return e1.d_expr == e2.d_expr;
01390 }
01391 
01392 inline bool operator!=(const Expr& e1, const Expr& e2)
01393   { return !(e1 == e2); }
01394 
01395 
01396 
01397 inline bool operator<(const Expr& e1, const Expr& e2)
01398   { return compare(e1,e2) < 0; }
01399 inline bool operator<=(const Expr& e1, const Expr& e2)
01400   { return compare(e1,e2) <= 0; }
01401 inline bool operator>(const Expr& e1, const Expr& e2)
01402   { return compare(e1,e2) > 0; }
01403 inline bool operator>=(const Expr& e1, const Expr& e2)
01404   { return compare(e1,e2) >= 0; }
01405 
01406 } 
01407 
01408 #endif