expr.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file expr.h
00004  * \brief Definition of the API to expression package.  See class Expr for details.
00005  * 
00006  * Author: Clark Barrett
00007  * 
00008  * Created: Tue Nov 26 00:27:40 2002
00009  *
00010  * <hr>
00011  *
00012  * License to use, copy, modify, sell and/or distribute this software
00013  * and its documentation for any purpose is hereby granted without
00014  * royalty, subject to the terms and conditions defined in the \ref
00015  * LICENSE file provided with this distribution.
00016  * 
00017  * <hr>
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   // Internal data-holding classes
00057   class ExprValue;
00058   class ExprNode;
00059   // Printing
00060   class ExprStream;
00061 
00062   //! Type ID of each ExprValue subclass.
00063   /*! It is defined in expr.h, so that ExprManager can use it before loading
00064     expr_value.h */
00065   typedef enum {
00066     EXPR_VALUE,
00067     EXPR_NODE,
00068     EXPR_APPLY, //!< Application of functions and predicates
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 // The end of list; don't assign it to any subclass
00078   } ExprValueType;
00079 
00080   //! Expression index type
00081   typedef long long unsigned ExprIndex;
00082 
00083   /**************************************************************************/
00084   /*! \defgroup ExprPkg Expression Package
00085    * \ingroup BuildingBlocks
00086    */
00087   /**************************************************************************/
00088   /*! \defgroup Expr_SmartPointer Smart Pointer Functionality in Expr
00089    * \ingroup ExprPkg
00090    */
00091   /**************************************************************************/
00092 
00093   /**************************************************************************/
00094   //! Data structure of expressions in CVC3
00095   /*! \ingroup ExprPkg
00096    * Class: Expr <br>
00097    * Author: Clark Barrett <br>
00098    * Created: Mon Nov 25 15:29:37 2002
00099    *
00100    * This class is the main data structure for expressions that all
00101    * other components should use.  It is actually a <em>smart
00102    * pointer</em> to the actual data holding class ExprValue and its
00103    * subclasses.
00104    *
00105    * Expressions are represented as DAGs with maximal sharing of
00106    * subexpressions.  Therefore, testing for equality is a constant time
00107    * operation (simply compare the pointers).
00108    *
00109    * Unused expressions are automatically garbage-collected.  The use is
00110    * determined by a reference counting mechanism.  In particular, this
00111    * means that if there is a circular dependency among expressions
00112    * (e.g. an attribute points back to the expression itself), these
00113    * expressions will not be garbage-collected, even if no one else is
00114    * using them.
00115    *
00116    * The most frequently used operations are getKind() (determining the
00117    * kind of the top level node of the expression), arity() (how many
00118    * children an Expr has), operator[]() for accessing a child, and
00119    * various testers and methods for constructing new expressions.
00120    *
00121    * In addition, a total ordering operator<() is provided.  It is
00122    * guaranteed to remain the same for the lifetime of the expressions
00123    * (it may change, however, if the expression is garbage-collected and
00124    * reborn).
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   /*! \addtogroup ExprPkg
00137    * @{
00138    */
00139   //! bit-masks for static flags
00140   typedef enum {
00141     //! Whether is valid TYPE expr
00142     VALID_TYPE = 0x1,
00143     //! Whether IS_ATOMIC flag is valid (initialized)
00144     VALID_IS_ATOMIC = 0x2,
00145     //! Whether the expression is an atomic term or formula
00146     IS_ATOMIC = 0x4,
00147     //! Expression is the result of a "normal" (idempotent) rewrite
00148     REWRITE_NORMAL = 0x8,
00149     //! Finite type
00150     IS_FINITE = 0x400,
00151     //! Well-founded (used in datatypes)
00152     WELL_FOUNDED = 0x800,
00153     //! Compute transitive closure (for binary uninterpreted predicates)
00154     COMPUTE_TRANS_CLOSURE = 0x1000,
00155     //! Whether expr contains a bounded variable (for quantifier instantiation)
00156     CONTAINS_BOUND_VAR = 0x00020000
00157   } StaticFlagsEnum;
00158 
00159   //! bit-masks for dynamic flags
00160   // TODO: Registered flags instead of hard-wired
00161   typedef enum {
00162     //! Whether expr has been added as an implied literal
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   //! Convenient null expr
00176   static Expr s_null;
00177 
00178   /////////////////////////////////////////////////////////////////////////////
00179   // Private Dynamic Data                                                    //
00180   /////////////////////////////////////////////////////////////////////////////
00181   //! The value.  This is the only data member in this class.
00182   ExprValue* d_expr;
00183 
00184   /////////////////////////////////////////////////////////////////////////////
00185   // Private methods                                                         //
00186   /////////////////////////////////////////////////////////////////////////////
00187 
00188   //! Private constructor, simply wraps around the pointer
00189   Expr(ExprValue* expr);
00190 
00191   Expr recursiveSubst(const ExprHashMap<Expr>& subst,
00192                       ExprHashMap<Expr>& visited) const;
00193 public:
00194   /////////////////////////////////////////////////////////////////////////////
00195   // Public Classes and Types                                                //
00196   /////////////////////////////////////////////////////////////////////////////
00197 
00198   /////////////////////////////////////////////////////////////////////////////
00199   /*!
00200    * Class: Expr::iterator
00201    * Author: Sergey Berezin
00202    * Created: Fri Dec  6 15:38:51 2002
00203    * Description: STL-like iterator API to the Expr's children.
00204    * IMPORTANT: the iterator will not be valid after the originating 
00205    * expression is destroyed.
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     // Private constructors (used by Expr only)
00215     //
00216     //! Construct an iterator out of the vector's iterator
00217     iterator(std::vector<Expr>::const_iterator it): d_it(it) { }
00218     // Public methods
00219   public:
00220     //! Default constructor
00221     iterator() { }
00222     // Copy constructor and operator= are defined by C++, that's good enough
00223 
00224     //! Equality
00225     bool operator==(const iterator& i) const {
00226       return d_it == i.d_it;
00227     }
00228     //! Disequality
00229     bool operator!=(const iterator& i) const { return !(*this == i); }
00230     //! Dereference operator
00231     const Expr& operator*() const { return *d_it; }
00232     //! Dereference and member access
00233     const Expr* operator->() const { return &(operator*()); }
00234     //! Prefix increment
00235     iterator& operator++() {
00236       d_it++;
00237       return *this;
00238     }
00239     /*! @brief Postfix increment requires a Proxy object to hold the
00240      * intermediate value for dereferencing */
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     //! Postfix increment
00248     /*! \return Proxy with the old Expr.
00249      *
00250      * Now, an expression like *i++ will return the current *i, and
00251      * then advance the iterator.  However, don't try to use Proxy for
00252      * anything else. 
00253      */
00254     Proxy operator++(int) {
00255       Proxy e(*(*this));
00256       ++(*this);
00257       return e;
00258     }
00259   }; // end of class Expr::iterator
00260 
00261   /////////////////////////////////////////////////////////////////////////////
00262   // Constructors                                                            //
00263   /////////////////////////////////////////////////////////////////////////////
00264 
00265   //! Default constructor creates the Null Expr
00266   Expr(): d_expr(NULL) {}
00267 
00268   /*! @brief Copy constructor and assignment (copy the pointer and take care
00269     of the refcount) */
00270   Expr(const Expr& e);
00271   //! Assignment operator: take care of the refcounting and GC
00272   Expr& operator=(const Expr& e);
00273 
00274   // These constructors grab the ExprManager from the Op or the first
00275   // child.  The operator and all children must belong to the same
00276   // ExprManager.
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   //! Destructor
00287   ~Expr();
00288 
00289   // Compound expression constructors
00290   Expr eqExpr(const Expr& right) const;
00291   Expr notExpr() const;
00292   Expr negate() const; // avoid double-negatives
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   //! Create a Skolem constant for the i'th variable of an existential (*this)
00299   Expr skolemExpr(int i) const;
00300   //! Create a Boolean variable out of the expression
00301   //  Expr boolVarExpr() const;
00302   //! Rebuild Expr with a new ExprManager
00303   Expr rebuild(ExprManager* em) const;
00304 //    Expr newForall(const Expr& e);
00305 //    Expr newExists(const Expr& e);
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   // Public Static Methods                                                   //
00316   /////////////////////////////////////////////////////////////////////////////
00317 
00318   static size_t hash(const Expr& e);
00319 
00320   /////////////////////////////////////////////////////////////////////////////
00321   // Read-only (const) methods                                               //
00322   /////////////////////////////////////////////////////////////////////////////
00323 
00324   size_t hash() const;
00325 
00326   // Core expression testers
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   //! Expr represents a type
00341   bool isType() const;
00342   /*
00343   bool isRecord() const;
00344   bool isRecordAccess() const;
00345   bool isTupleAccess() const;
00346   */
00347   //! Provide access to ExprValue for client subclasses of ExprValue *only*
00348   /*@ Calling getExprValue on an Expr with a built-in ExprValue class will
00349    * cause an error */
00350   const ExprValue* getExprValue() const;
00351 
00352   //! Test if e is a term (as opposed to a predicate/formula)
00353   bool isTerm() const;
00354   //! Test if e is atomic
00355   /*! An atomic expression is one that does not contain a formula (including
00356    *  not being a formula itself).
00357    *  \sa isAtomicFormula */
00358   bool isAtomic() const;
00359   //! Test if e is an atomic formula
00360   /*! An atomic formula is TRUE or FALSE or an application of a predicate
00361     (possibly 0-ary) which does not properly contain any formula.  For
00362     instance, the formula "x = IF f THEN y ELSE z ENDIF is not an atomic
00363     formula, since it contains the condition "f", which is a formula. */
00364   bool isAtomicFormula() const;
00365   //! An abstract atomic formua is an atomic formula or a quantified formula
00366   bool isAbsAtomicFormula() const
00367     { return isQuantifier() || isAtomicFormula(); }
00368   //! Test if e is a literal
00369   /*! A literal is an atomic formula, or its negation.  
00370     \sa isAtomicFormula */
00371   bool isLiteral() const
00372   { return (isAtomicFormula() || (isNot() && (*this)[0].isAtomicFormula())); }
00373   //! Test if e is an abstract literal
00374   bool isAbsLiteral() const
00375   { return (isAbsAtomicFormula() || (isNot() && (*this)[0].isAbsAtomicFormula())); }
00376   //! A Bool connective is one of NOT,AND,OR,IMPLIES,IFF,XOR,ITE (with type Bool)
00377   bool isBoolConnective() const;
00378   //! True iff expr is not a Bool connective
00379   bool isPropAtom() const { return !isBoolConnective(); }
00380   //! PropAtom or negation of PropAtom
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   // Leaf accessors - these functions must only be called one expressions of
00400   // the appropriate kind.
00401 
00402   // For UCONST and BOUND_VAR Expr's
00403   const std::string& getName() const;
00404   //! For BOUND_VAR, get the UID
00405   const std::string& getUid() const;
00406 
00407   // For STRING_EXPR's
00408   const std::string& getString() const; 
00409   //! Get bound variables from a closure Expr
00410   const std::vector<Expr>& getVars() const;
00411   //! Get the existential axiom expression for skolem constant
00412   const Expr& getExistential() const;
00413   //! Get the index of the bound var that skolem constant comes from
00414   int getBoundIndex() const;
00415  
00416   //! Get the body of the closure Expr
00417   const Expr& getBody() const;
00418   //! Get the Rational value out of RATIONAL_EXPR
00419   const Rational& getRational() const; 
00420   //! Get theorem from THEOREM_EXPR
00421   const Theorem& getTheorem() const;
00422 
00423   // Get the expression manager.  The expression must be non-null.
00424   ExprManager *getEM() const;
00425 
00426   // Return a ref to the vector of children.
00427   const std::vector<Expr>& getKids() const;
00428 
00429   // Get the kind of this expr.
00430   int getKind() const;
00431 
00432   // Get the index field
00433   ExprIndex getIndex() const;
00434 
00435   // True if this is the most recently created expression
00436   bool hasLastIndex() const;
00437 
00438   //! Make the expr into an operator
00439   Op mkOp() const;
00440 
00441   //! Get operator from expression
00442   Op getOp() const;
00443 
00444   //! Get expression of operator (for APPLY Exprs only)
00445   Expr getOpExpr() const;
00446 
00447   //! Get kind of operator (for APPLY Exprs only)
00448   int getOpKind() const;
00449 
00450   // Return the number of children.  Note, that an application of a
00451   // user-defined function has the arity of that function (the number
00452   // of arguments), and the function name itself is part of the
00453   // operator.
00454   int arity() const;
00455 
00456   // Return the ith child.  As with arity, it's also the ith argument
00457   // in function application.
00458   const Expr& operator[](int i) const;
00459 
00460   //! Remove leading NOT if any
00461   const Expr& unnegate() const { return isNot() ? (*this)[0] : *this; }
00462 
00463   //! Begin iterator
00464   iterator begin() const;
00465 
00466   //! End iterator
00467   iterator end() const;
00468 
00469   // Check if Expr is Null
00470   bool isNull() const;
00471 
00472   // Check if Expr is not Null
00473   bool isInitialized() const { return d_expr != NULL; }
00474   //! Get the memory manager index (it uniquely identifies the subclass)
00475   size_t getMMIndex() const;
00476 
00477   // Attributes
00478 
00479   // True if the find attribute has been set to something other than NULL.
00480   bool hasFind() const;
00481 
00482   // Return the attached find attribute for the expr.  Note that this
00483   // must be called repeatedly to get the root of the union-find tree.
00484   // Should only be called if hasFind is true.
00485   const Theorem& getFind() const;
00486 
00487   int getFindLevel() const;
00488 
00489   // Return the notify list
00490   NotifyList* getNotify() const;
00491 
00492   //! Get the type.  Recursively compute if necessary
00493   const Type getType() const;
00494   //! Look up the current type. Do not recursively compute (i.e. may be NULL)
00495   const Type lookupType() const;
00496 
00497   /*! @brief Return true if there is a valid cached value for calling
00498       simplify on this Expr. */
00499   bool validSimpCache() const;
00500 
00501   // Get the cached Simplify of this Expr.
00502   const Theorem& getSimpCache() const;
00503 
00504   // Return true if valid type flag is set for Expr
00505   bool isValidType() const;
00506 
00507   // Return true if there is a valid flag for whether Expr is atomic
00508   bool validIsAtomicFlag() const;
00509 
00510   // Get the isAtomic flag
00511   bool getIsAtomicFlag() const;
00512 
00513   // Get the RewriteNormal flag
00514   bool isRewriteNormal() const;
00515 
00516   // Get the isFinite flag
00517   bool isFinite() const;
00518 
00519   // Get the WellFounded flag
00520   bool isWellFounded() const;
00521 
00522   // Get the ComputeTransClosure flag
00523   bool computeTransClosure() const;
00524 
00525   // Get the ContainsBoundVar flag
00526   bool containsBoundVar() const;
00527 
00528   // Get the ImpliedLiteral flag
00529   bool isImpliedLiteral() const;
00530 
00531   // Get the UserAssumption flag
00532   bool isUserAssumption() const;
00533 
00534   // Get the inUserAssumption flag
00535   bool inUserAssumption() const;
00536 
00537   // Get the IntAssumption flag
00538   bool isIntAssumption() const;
00539 
00540   // Get the Justified flag
00541   bool isJustified() const;
00542 
00543   // Get the Translated flag
00544   bool isTranslated() const;
00545 
00546   // Get the UserRegisteredAtom flag
00547   bool isUserRegisteredAtom() const;
00548 
00549   // Get the RegisteredAtom flag
00550   bool isRegisteredAtom() const;
00551 
00552   // Get the Selected flag
00553   bool isSelected() const;
00554 
00555   // Get the Stored Predicate flag
00556   bool isStoredPredicate() const;
00557 
00558   //! Check if the generic flag is set
00559   bool getFlag() const;
00560   //! Set the generic flag
00561   void setFlag() const;
00562   //! Clear the generic flag in all Exprs
00563   void clearFlags() const;
00564 
00565   // Printing functions
00566 
00567   //! Print the expression to a string
00568   std::string toString() const;
00569   //! Print the expression to a string using the given output language
00570   std::string toString(InputLanguage lang) const;
00571   //! Print the expression in the specified format
00572   void print(InputLanguage lang, bool dagify = true) const;
00573 
00574   //! Print the expression as AST (lisp-like format)
00575   void print() const { print(AST_LANG); }
00576   //! Print the expression as AST without dagifying
00577   void printnodag() const;
00578 
00579   //! Pretty-print the expression
00580   void pprint() const;
00581   //! Pretty-print without dagifying
00582   void pprintnodag() const;
00583 
00584   //! Print a leaf node
00585   /*@ The top node is pretty-printed if it is a basic leaf type;
00586    * otherwise, just the kind is printed.  Should only be called on expressions
00587    * with no children. */
00588   ExprStream& print(ExprStream& os) const;
00589   //! Print the top node and then recurse through the children */
00590   /*@ The top node is printed as an AST with all the information, including
00591    * "hidden" Exprs that are part of the ExprValue */
00592   ExprStream& printAST(ExprStream& os) const;
00593   //! Set initial indentation to n.
00594   /*! The indentation will be reset to default unless the second
00595     argument is true.
00596     \return reference to itself, so one can write `os << e.indent(5)'
00597   */
00598   Expr& indent(int n, bool permanent = false);
00599 
00600   /////////////////////////////////////////////////////////////////////////////
00601   // Other Public methods                                                    //
00602   /////////////////////////////////////////////////////////////////////////////
00603 
00604   // Attributes
00605 
00606   //! Set the find attribute to e
00607   void setFind(const Theorem& e) const;
00608 
00609   //! Add (e,i) to the notify list of this expression
00610   void addToNotify(Theory* i, const Expr& e) const;
00611 
00612   //! Set the cached type
00613   void setType(const Type& t) const;
00614 
00615   // Cache the result of a call to Simplify on this Expr
00616   void setSimpCache(const Theorem& e) const;
00617 
00618   // Set the valid type flag for this Expr
00619   void setValidType() const;
00620 
00621   // Set the isAtomicFlag for this Expr
00622   void setIsAtomicFlag(bool value) const;
00623 
00624   // Set or clear the RewriteNormal flag
00625   void setRewriteNormal() const;
00626   void clearRewriteNormal() const;
00627 
00628   // Set the isFinite flag
00629   void setFinite() const;
00630 
00631   // Set the WellFounded flag
00632   void setWellFounded() const;
00633 
00634   // Set the ComputeTransClosure flag
00635   void setComputeTransClosure() const;
00636 
00637   // Set the ContainsBoundVar flag
00638   void setContainsBoundVar() const;
00639 
00640   // Set the impliedLiteral flag for this Expr
00641   void setImpliedLiteral() const;
00642 
00643   // Set the user assumption flag for this Expr
00644   void setUserAssumption(int scope = -1) const;
00645 
00646   // Set the in user assumption flag for this Expr
00647   void setInUserAssumption(int scope = -1) const;
00648 
00649   // Set the internal assumption flag for this Expr
00650   void setIntAssumption() const;
00651 
00652   // Set the justified flag for this Expr
00653   void setJustified() const;
00654 
00655   //! Set the translated flag for this Expr
00656   void setTranslated(int scope = -1) const;
00657 
00658   //! Set the UserRegisteredAtom flag for this Expr
00659   void setUserRegisteredAtom() const;
00660 
00661   //! Set the RegisteredAtom flag for this Expr
00662   void setRegisteredAtom() const;
00663 
00664   //! Set the Selected flag for this Expr
00665   void setSelected() const;
00666 
00667   //! Set the Stored Predicate flag for this Expr
00668   void setStoredPredicate() const;
00669 
00670   //! Check if the current Expr (*this) is a subexpression of e
00671   bool subExprOf(const Expr& e) const;
00672   // Returns the maximum number of Boolean expressions on a path from
00673   // this to a leaf, including this.
00674 //   inline int getHeight() const;
00675 
00676 //   // Returns the index of the highest kid.
00677 //   inline int getHighestKid() const;
00678 
00679 //   // Gets/sets an expression that this expression was simplified from
00680 //   // (see newRWTheorem). This is the equivalent of SVC's Sigx.
00681 //   inline bool hasSimpFrom() const;
00682 //   inline const Expr& getSimpFrom() const;
00683 //   inline void setSimpFrom(const Expr& simpFrom);
00684 
00685   // Attributes for uninterpreted function symbols.
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   // Friend methods                                                          //
00695   /////////////////////////////////////////////////////////////////////////////
00696 
00697   friend CVC_DLL std::ostream& operator<<(std::ostream& os, const Expr& e);
00698 
00699   // The master method which defines some fixed total ordering on all
00700   // Exprs.  If e1 < e2, e1==e2, and e1 > e2, it returns -1, 0, 1
00701   // respectively.  A Null expr is always "smaller" than any other
00702   // expr, but is equal to itself.
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   /*!@}*/ // end of group Expr
00714 
00715 }; // end of class Expr
00716 
00717 } // end of namespace CVC3
00718 
00719 // Include expr_value.h here.  We cannot include it earlier, since it
00720 // needs the definition of class Expr.  See comments in expr_value.h.
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; // Self-assignment
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 // Read-only (const) methods                                               //
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 // Core Expression Testers
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   //inline int Expr::getHeight() const { return d_expr->getHeight(); }
00948   //inline int Expr::getHighestKid() const { return d_expr->getHighestKid(); }
00949 
00950   //inline bool Expr::hasSimpFrom() const
00951 //   { return !d_expr->getSimpFrom().isNull(); }
00952 // inline const Expr& Expr::getSimpFrom() const
00953 //   { return hasSimpFrom() ? d_expr->getSimpFrom() : *this; }
00954 // inline void Expr::setSimpFrom(const Expr& simpFrom)
00955 //   { d_expr->setSimpFrom(simpFrom); }
00956 
00957 // Leaf accessors
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; // FIXME: invent a better 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   // Comparing pointers (equal expressions are always shared)
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 // compare() is defined in expr.cpp
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 } // end of namespace CVC3
01407 
01408 #endif

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