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  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 
00030 #ifndef _CVC_lite__expr_h_
00031 #define _CVC_lite__expr_h_
00032 
00033 #include <iostream>
00034 #include <functional>
00035 #include <iterator>
00036 
00037 #include "debug.h"
00038 #include "rational.h"
00039 #include "kinds.h"
00040 #include "cdo.h"
00041 #include "lang.h"
00042 
00043 class CInterface;
00044 
00045 namespace CVCL {
00046 
00047   class NotifyList;
00048   class Theory;
00049   class Op;
00050   class Type;
00051   class Theorem;
00052 
00053   template<class Data>
00054   class ExprHashMap;
00055 
00056   class ExprManager;
00057   // Internal data-holding classes
00058   class ExprValue;
00059   class ExprNode;
00060   // Printing
00061   class ExprStream;
00062 
00063   //! Type ID of each ExprValue subclass.
00064   /*! It is defined in expr.h, so that ExprManager can use it before loading
00065     expr_value.h */
00066   typedef enum {
00067     EXPR_VALUE,
00068     EXPR_NODE,
00069     EXPR_STRING,
00070     EXPR_RATIONAL,
00071     EXPR_SKOLEM,
00072     EXPR_UCONST,
00073     EXPR_BOUND_VAR,
00074     EXPR_CC, //!< Expression with sig and rep attributes for congruence closure
00075     EXPR_APPLY, //!< Application of functions and predicates
00076     EXPR_CLOSURE,
00077     EXPR_NAMED,
00078     EXPR_BOOL_VAR,
00079 //     EXPR_READ,
00080 //     EXPR_RECORD, //!< for record literals
00081 //     EXPR_FIELD, //!< for a record field access (select, update)
00082 //     EXPR_TUPLE_INDEX, //!< for a tuple element access (select, update)
00083     EXPR_VALUE_TYPE_LAST // The end of list; don't assign it to any subclass
00084   } ExprValueType;
00085 
00086   //! Expression index type
00087   typedef long long unsigned ExprIndex;
00088 
00089   /**************************************************************************/
00090   /*! \defgroup ExprPkg Expression Package
00091    * \ingroup BuildingBlocks
00092    */
00093   /**************************************************************************/
00094   /*! \defgroup Expr_SmartPointer Smart Pointer Functionality in Expr
00095    * \ingroup ExprPkg
00096    */
00097   /**************************************************************************/
00098 
00099   /**************************************************************************/
00100   //! Data structure of expressions in CVC Lite
00101   /*! \ingroup ExprPkg
00102    * Class: Expr <br>
00103    * Author: Clark Barrett <br>
00104    * Created: Mon Nov 25 15:29:37 2002
00105    *
00106    * This class is the main data structure for expressions that all
00107    * other components should use.  It is actually a <em>smart
00108    * pointer</em> to the actual data holding class ExprValue and its
00109    * subclasses.
00110    *
00111    * Expressions are represented as DAGs with maximal sharing of
00112    * subexpressions.  Therefore, testing for equality is a constant time
00113    * operation (simply compare the pointers).
00114    *
00115    * Unused expressions are automatically garbage-collected.  The use is
00116    * determined by a reference counting mechanism.  In particular, this
00117    * means that if there is a circular dependency among expressions
00118    * (e.g. an attribute points back to the expression itself), these
00119    * expressions will not be garbage-collected, even if no one else is
00120    * using them.
00121    *
00122    * The most frequently used operations are getKind() (determining the
00123    * kind of the top level node of the expression), arity() (how many
00124    * children an Expr has), operator[]() for accessing a child, and
00125    * various testers and methods for constructing new expressions.
00126    *
00127    * In addition, a total ordering operator<() is provided.  It is
00128    * guaranteed to remain the same for the lifetime of the expressions
00129    * (it may change, however, if the expression is garbage-collected and
00130    * reborn).
00131    */
00132   /**************************************************************************/
00133 class Expr {
00134   friend class ExprHasher;
00135   friend class ExprManager;
00136   friend class Op;
00137   friend class ExprValue;
00138   friend class ExprNode;
00139   friend class CInterface;
00140 
00141   /*! \addtogroup ExprPkg
00142    * @{
00143    */
00144   //! bit-masks for static flags
00145   typedef enum {
00146     //! Whether IS_ATOMIC flag is valid (initialized)
00147     VALID_IS_ATOMIC = 0x1,
00148     //! Whether the expression is an atomic term or formula
00149     IS_ATOMIC = 0x2,
00150     //! Expression is the result of a "normal" (idempotent) rewrite
00151     REWRITE_NORMAL = 0x4
00152   } StaticFlagsEnum;
00153 
00154   /////////////////////////////////////////////////////////////////////////////
00155   // Private Dynamic Data                                                    //
00156   /////////////////////////////////////////////////////////////////////////////
00157   //! The value.  This is the only data member in this class.
00158   ExprValue* d_expr;
00159 
00160   /////////////////////////////////////////////////////////////////////////////
00161   // Private methods                                                         //
00162   /////////////////////////////////////////////////////////////////////////////
00163 
00164   //! Private constructor, simply wraps around the pointer
00165   /*! It includes an extra dummy argument to distinguish it from a
00166    * public constructor uniquifies the pointer.
00167    */
00168   Expr(ExprValue* expr, int i);
00169   
00170 public:
00171   /////////////////////////////////////////////////////////////////////////////
00172   // Public Classes and Types                                                //
00173   /////////////////////////////////////////////////////////////////////////////
00174 
00175   /////////////////////////////////////////////////////////////////////////////
00176   /*!
00177    * Class: Expr::iterator
00178    * Author: Sergey Berezin
00179    * Created: Fri Dec  6 15:38:51 2002
00180    * Description: STL-like iterator API to the Expr's children.
00181    * IMPORTANT: the iterator will not be valid after the originating 
00182    * expression is destroyed.
00183   */
00184   /////////////////////////////////////////////////////////////////////////////
00185   class iterator
00186     : public std::iterator<std::input_iterator_tag,Expr,ptrdiff_t>
00187   {
00188     friend class Expr;
00189   private:
00190     std::vector<Expr>::const_iterator d_it;
00191     // Private constructors (used by Expr only)
00192     //
00193     //! Construct an iterator out of the vector's iterator
00194     iterator(std::vector<Expr>::const_iterator it): d_it(it) { }
00195     // Public methods
00196   public:
00197     //! Default constructor
00198     iterator() { }
00199     // Copy constructor and operator= are defined by C++, that's good enough
00200 
00201     //! Equality
00202     bool operator==(const iterator& i) const {
00203       return d_it == i.d_it;
00204     }
00205     //! Disequality
00206     bool operator!=(const iterator& i) const { return !(*this == i); }
00207     //! Dereference operator
00208     const Expr& operator*() const;
00209     //! Dereference and member access
00210     const Expr* operator->() const;
00211     //! Prefix increment
00212     iterator& operator++() {
00213       d_it++;
00214       return *this;
00215     }
00216     /*! @brief Postfix increment requires a Proxy object to hold the
00217      * intermediate value for dereferencing */
00218     class Proxy {
00219       const Expr* d_e;
00220     public:
00221       Proxy(const Expr& e) : d_e(&e) { }
00222       Expr operator*() { return *d_e; }
00223     };
00224     //! Postfix increment
00225     /*! \return Proxy with the old Expr.
00226      *
00227      * Now, an expression like *i++ will return the current *i, and
00228      * then advance the iterator.  However, don't try to use Proxy for
00229      * anything else. 
00230      */
00231     Proxy operator++(int) {
00232       Proxy e(*(*this));
00233       ++(*this);
00234       return e;
00235     }
00236   }; // end of class Expr::iterator
00237 
00238   /////////////////////////////////////////////////////////////////////////////
00239   // Constructors                                                            //
00240   /////////////////////////////////////////////////////////////////////////////
00241 
00242   //! Default constructor creates the Null Expr
00243   Expr(): d_expr(NULL) {}
00244 
00245   //! Constructor from generic ExprValue subclasses.
00246   Expr(ExprValue* expr);
00247   /*! @brief Copy constructor and assignment (copy the pointer and take care
00248     of the refcount) */
00249   Expr(const Expr& e);
00250   //! Assignment operator: take care of the refcounting and GC
00251   Expr& operator=(const Expr& e);
00252 
00253   // Create a new Expr with given ExprManager, operator and children.
00254   // If the children belong to another ExprManager, convert them to
00255   // use the given one.
00256   Expr(ExprManager *em, const Op& op);
00257   Expr(ExprManager *em, const Op& op, const Expr& child);
00258   Expr(ExprManager *em, const Op& op, const Expr& child0, const Expr& child1);
00259   Expr(ExprManager *em, const Op& op, const Expr& child0, const Expr& child1, const Expr& child2);
00260   Expr(ExprManager *em, const Op& op, const std::vector<Expr>& children);
00261 
00262   // Similar constructors, but from kinds rather than from an Op
00263   Expr(ExprManager *em, int kind);
00264   Expr(ExprManager *em, int kind, const Expr& child);
00265   Expr(ExprManager *em, int kind, const Expr& child0, const Expr& child1);
00266   Expr(ExprManager *em, int kind, const Expr& child0, const Expr& child1,
00267        const Expr& child2);
00268   Expr(ExprManager *em, int kind, const std::vector<Expr>& children);
00269   //! Closure Expr (quantifier, lambda, etc.)
00270 //   Expr(ExprManager *em, int kind, const std::vector<Expr>& vars,
00271 //        const Expr& body);
00272   /*
00273   //! Record literal
00274   Expr(ExprManager *em, int kind,
00275        const std::vector<std::string>& fields,
00276        const std::vector<Expr>& children);
00277   //! Record access (REC_SELECT, REC_UPDATE)
00278   Expr(ExprManager *em, int kind, const std::string& field,
00279        const std::vector<Expr>& children);
00280   //! Tuple access (TUPLE_SELECT, TUPLE_UPDATE)
00281   Expr(ExprManager *em, int kind, int index,
00282        const std::vector<Expr>& children);
00283   */
00284   // These constructors grab the ExprManager from the Op or the first
00285   // child.  The operator and all children must belong to the same
00286   // ExprManager.
00287   Expr(const Op& op);
00288   Expr(const Op& op, const Expr& child);
00289   Expr(const Op& op, const Expr& child0, const Expr& child1);
00290   Expr(const Op& op, const Expr& child0, const Expr& child1,
00291        const Expr& child2);
00292   Expr(const Op& op, const std::vector<Expr>& children);
00293 
00294   // Leaf expression constructors
00295 //   Expr(ExprManager *em, int kind, const std::string &s);
00296 
00297 //   Expr(ExprManager *em, const Rational &r);
00298   //! Constructor for BOUND_VAR
00299 //   Expr(ExprManager *em, const std::string& name, const std::string& uid);
00300 
00301   // Compound expression constructors
00302   Expr eqExpr(const Expr& right) const;
00303   Expr notExpr() const;
00304   Expr negate() const; // avoid double-negatives
00305   Expr andExpr(const Expr& right) const;
00306   friend Expr andExpr(const std::vector <Expr>& children);
00307   Expr orExpr(const Expr& right) const;
00308   friend Expr orExpr(const std::vector <Expr>& children);
00309   Expr iteExpr(const Expr& thenpart, const Expr& elsepart) const;
00310   Expr iffExpr(const Expr& right) const;
00311   Expr impExpr(const Expr& right) const;
00312   //! Create a Skolem constant for the i'th variable of an existential (*this)
00313   Expr skolemExpr(int i) const;
00314   //! Create a Boolean variable out of the expression
00315   Expr boolVarExpr() const;
00316   //! Rebuild Expr with a new ExprManager
00317   Expr rebuild(ExprManager* em) const;
00318 //    Expr newForall(const Expr& e);
00319 //    Expr newExists(const Expr& e);
00320 
00321   Expr operator!() const { return notExpr(); }
00322   Expr operator&&(const Expr& right) const { return andExpr(right); }
00323   Expr operator||(const Expr& right) const { return orExpr(right); }
00324 
00325   //! Destructor
00326   ~Expr();
00327 
00328   /////////////////////////////////////////////////////////////////////////////
00329   // Public Static Methods                                                   //
00330   /////////////////////////////////////////////////////////////////////////////
00331 
00332   static size_t hash(const Expr& e);
00333 
00334   // Creating new Expr's.  These methods are basically the same as
00335   // constructors, but return value and can be nested.
00336   friend Expr newExpr(ExprValue* ev);
00337   friend Expr newExpr(ExprManager *em, const Expr& e); // Rebuild with new em
00338   friend Expr newExpr(ExprManager *em, const Op& op);
00339   friend Expr newExpr(ExprManager *em, const Op& op, const Expr& child);
00340   friend Expr newExpr(ExprManager *em, const Op& op, const Expr& child0,
00341                       const Expr& child1);
00342   friend Expr newExpr(ExprManager *em, const Op& op, const Expr& child0,
00343                       const Expr& child1, const Expr& child2);
00344   friend Expr newExpr(ExprManager *em, const Op& op,
00345                       const std::vector<Expr>& children);
00346 
00347   friend Expr newExpr(ExprManager *em, int kind);
00348   friend Expr newExpr(ExprManager *em, int kind, const Expr& child);
00349   friend Expr newExpr(ExprManager *em, int kind, const Expr& child0,
00350                       const Expr& child1);
00351   friend Expr newExpr(ExprManager *em, int kind, const Expr& child0,
00352                       const Expr& child1, const Expr& child2);
00353   friend Expr newExpr(ExprManager *em, int kind,
00354                       const std::vector<Expr>& children);
00355   //! Closure Expr
00356   friend Expr newClosureExpr(ExprManager *em, int kind,
00357                              const std::vector<Expr>& vars, const Expr& body);
00358   //! Closure Expr
00359   friend Expr newClosureExpr(int kind, const std::vector<Expr>& vars,
00360                              const Expr& body);
00361   //! Boolean variable expr
00362   friend Expr newBoolVarExpr(const Expr& e);
00363   //! Application of uninterpreted function
00364   friend Expr newApplyExpr(ExprManager* em, const Expr& func,
00365                            const std::vector<Expr>& args);
00366   friend Expr newApplyExpr(const Expr& func, const std::vector<Expr>& args)
00367   { return newApplyExpr(func.getEM(), func, args); }
00368   friend Expr newApplyExpr(const Expr& func, const Expr& arg) {
00369     std::vector<Expr> args;
00370     args.push_back(arg);
00371     return newApplyExpr(func.getEM(), func, args);
00372   }
00373   friend Expr newApplyExpr(const Expr& func, const Expr& a1, const Expr& a2) {
00374     std::vector<Expr> args;
00375     args.push_back(a1);
00376     args.push_back(a2);
00377     return newApplyExpr(func.getEM(), func, args);
00378   }
00379   friend Expr newApplyExpr(const Expr& func, const Expr& a1, const Expr& a2,
00380                            const Expr& a3) {
00381     std::vector<Expr> args;
00382     args.push_back(a1);
00383     args.push_back(a2);
00384     args.push_back(a3);
00385     return newApplyExpr(func.getEM(), func, args);
00386   }
00387   //! Named expressions without kids
00388   friend Expr newNamedExpr(ExprManager* em, int kind, const std::string& name);
00389   //! Named expressions with kids
00390   friend Expr newNamedExpr(ExprManager* em, int kind, const std::string& name,
00391                            const std::vector<Expr>& kids);
00392   friend Expr newNamedExpr(int kind, const std::string& name,
00393                            const std::vector<Expr>& kids);
00394   friend Expr newNamedExpr(int kind, const std::string& name,
00395                            const Expr& child) {
00396     std::vector<Expr> kids;
00397     kids.push_back(child);
00398     return newNamedExpr(kind, name, kids);
00399   }
00400   friend Expr newNamedExpr(int kind, const std::string& name,
00401                            const Expr& child1, const Expr& child2) {
00402     std::vector<Expr> kids;
00403     kids.push_back(child1);
00404     kids.push_back(child2);
00405     return newNamedExpr(kind, name, kids);
00406   }
00407   friend Expr newNamedExpr(int kind, const std::string& name,
00408                            const Expr& child1, const Expr& child2,
00409                            const Expr& child3) {
00410     std::vector<Expr> kids;
00411     kids.push_back(child1);
00412     kids.push_back(child2);
00413     kids.push_back(child3);
00414     return newNamedExpr(kind, name, kids);
00415   }
00416   // ExprManager is taken from the op or the children
00417   friend Expr newExpr(const Op& op);
00418   friend Expr newExpr(const Op& op, const Expr& child);
00419   friend Expr newExpr(const Op& op, const Expr& child0, const Expr& child1);
00420   friend Expr newExpr(const Op& op, const Expr& child0, const Expr& child1,
00421                       const Expr& child2);
00422   friend Expr newExpr(const Op& op, const std::vector<Expr>& children);
00423 
00424   // Leaf nodes
00425   friend Expr newStringExpr(ExprManager *em, const std::string &s);
00426   friend Expr newVarExpr(ExprManager *em, const std::string &s);
00427   friend Expr newBoundVarExpr(ExprManager *em, const std::string &name, 
00428                               const std::string& uid);
00429   friend Expr newRatExpr(ExprManager *em, const Rational &r);
00430   //skolem constant
00431   friend Expr newSkolemExpr(const Expr& e, int index);
00432   friend const Expr& falseExpr(ExprManager *em);
00433   friend const Expr& trueExpr(ExprManager *em);
00434   
00435   friend Expr substExpr(const Expr& e,
00436                         const std::vector<Expr>& oldTerms,
00437                         const std::vector<Expr>& newTerms); 
00438   friend Expr substExpr(const Expr& e, const ExprHashMap<Expr>& oldToNew);
00439 
00440   /////////////////////////////////////////////////////////////////////////////
00441   // Read-only (const) methods                                               //
00442   /////////////////////////////////////////////////////////////////////////////
00443 
00444   size_t hash() const;
00445 
00446   // Core expression testers
00447 
00448   bool isFalse() const { return getKind() == FALSE; }
00449   bool isTrue() const { return getKind() == TRUE; }
00450   bool isBoolConst() const { return isFalse() || isTrue(); }
00451   bool isVar() const;
00452   bool isBoolVar() const;
00453   bool isString() const;
00454   bool isClosure() const;
00455   bool isQuantifier() const;
00456   bool isLambda() const;
00457   //! Expr is an application of a LAMBDA-term to arguments
00458   bool isApply() const;
00459   //! Expr represents a type
00460   bool isType() const;
00461   /*
00462   bool isRecord() const;
00463   bool isRecordAccess() const;
00464   bool isTupleAccess() const;
00465   */
00466   size_t isGeneric() const;
00467   bool isGeneric(size_t idx) const;
00468 
00469   bool isEq() const { return getKind() == EQ; }
00470   bool isNot() const { return getKind() == NOT; }
00471   bool isAnd() const { return getKind() == AND; }
00472   bool isOr() const { return getKind() == OR; }
00473   bool isITE() const { return getKind() == ITE; }
00474   bool isIff() const { return getKind() == IFF; }
00475   bool isImpl() const { return getKind() == IMPLIES; }
00476   bool isXor() const { return getKind() == XOR;}
00477 
00478   bool isForall() const { return getKind() == FORALL; }
00479   bool isExists() const { return getKind() == EXISTS; }
00480 
00481   // Arith testers
00482   bool isRational() const { return getKind() == RATIONAL_EXPR; }
00483   bool isSkolem() const { return getKind() == SKOLEM_VAR;}
00484   // Leaf accessors - these functions must only be called one expressions of
00485   // the appropriate kind.
00486 
00487   // For UCONST and BOUND_VAR Expr's
00488   const std::string& getName() const;
00489   //! For BOUND_VAR, get the UID
00490   const std::string& getUid() const;
00491 
00492   // For STRING_EXPR's
00493   const std::string& getString() const; 
00494   //! Get bound variables from a closure Expr
00495   const std::vector<Expr>& getVars() const;
00496   //! Get the operator from Boolean variable
00497   const Expr& getVar() const;
00498   //! Get the operator from function application
00499   const Expr& getFun() const;
00500   //! Get the existential axiom expression for skolem constant
00501   const Expr& getExistential() const;
00502   //! Get the index of the bound var that skolem constant comes from
00503   int getBoundIndex() const;
00504  
00505   //! Get the body of the closure Expr
00506   const Expr& getBody() const;
00507   //! Get the body of the quantifier Expr (for backward compatibility)
00508   const Expr& getQuantBody() const { return getBody(); }
00509   //! Get the list of fields from record literal
00510 //   const std::vector<std::string>& getRecordFields() const;
00511 //   //! Get the field from a record access Expr
00512 //   const std::string& getRecordField() const;
00513 //   //! Get the index from a tuple access Expr
00514 //   int getTupleIndex() const;
00515 //   //! Get the index of the fieldName in the vector of strings, -1 if not found.
00516 //   int getFieldIndex(const std::string & fieldName) const;
00517   //! Get the Rational value out of RATIONAL_EXPR
00518   const Rational& getRational() const; 
00519 
00520   /*! \name Generic Values
00521    * Methods for accessing an immutable reference to generic values in
00522    * DP-local subclasses and their sizes.  Unlike attributes, these
00523    * are considered as parts of the expression value.
00524    * @{
00525    */
00526   int getIntValue(int idx) const;
00527   const std::string& getStringValue(int idx) const;
00528   const Rational& getRatValue(int idx) const;
00529   const Expr& getExprValue(int idx) const;
00530   const Theorem& getTheoremValue(int idx) const;
00531   const CDO<int>& getCDIntValue(int idx) const;
00532   const CDO<Expr>& getCDExprValue(int idx) const;
00533   const CDO<Theorem>& getCDTheoremValue(int idx) const;
00534   //! Values of all other types (don't use it unless absolutely needed)
00535   const void* getOtherValue(int idx) const;
00536 
00537   size_t getIntValueSize() const;
00538   size_t getStringValueSize() const;
00539   size_t getRatValueSize() const;
00540   size_t getExprValueSize() const;
00541   size_t getTheoremValueSize() const;
00542   size_t getCDIntValueSize() const;
00543   size_t getCDExprValueSize() const;
00544   size_t getCDTheoremValueSize() const;
00545   size_t getOtherValueSize() const;
00546   /*!@}*/
00547   
00548   /*! \name Generic attributes 
00549    * Methods for accessing an assignable reference to generic
00550    * attributes in DP-local subclasses and their sizes
00551    * @{
00552    */
00553   int& getIntAttr(int idx) const;
00554   Expr& getExprAttr(int idx) const;
00555   Theorem& getTheoremAttr(int idx) const;
00556   CDO<int>& getCDIntAttr(int idx) const;
00557   CDO<Expr>& getCDExprAttr(int idx) const;
00558   CDO<Theorem>& getCDTheoremAttr(int idx) const;
00559   //! Attributes of all other types (don't use it unless absolutely needed)
00560   void* getOtherAttr(int idx) const;
00561 
00562   size_t getIntAttrSize() const;
00563   size_t getExprAttrSize() const;
00564   size_t getTheoremAttrSize() const;
00565   size_t getCDIntAttrSize() const;
00566   size_t getCDExprAttrSize() const;
00567   size_t getCDTheoremAttrSize() const;
00568   size_t getOtherAttrSize() const;
00569   /*!@}*/
00570   
00571   // Get the expression manager.  The expression must be non-null.
00572   ExprManager *getEM() const;
00573 
00574   // Return a ref to the vector of children.
00575   const std::vector<Expr>& getKids() const;
00576 
00577   // Get the kind of this expr.
00578   int getKind() const;
00579 
00580   // Get the index field
00581   ExprIndex getIndex() const;
00582 
00583   // True if this is the most recently created expression
00584   bool hasLastIndex() const;
00585 
00586   // Return the number of children.  Note, that an application of a
00587   // user-defined function has the arity of that function (the number
00588   // of arguments), and the function name itself is part of the
00589   // operator.
00590   int arity() const;
00591 
00592   // Return the ith child.  As with arity, it's also the ith argument
00593   // in function application.
00594   const Expr& operator[](int i) const;
00595 
00596   //! Begin iterator
00597   iterator begin() const;
00598   //! End iterator
00599   iterator end() const;
00600 
00601   // Check if Expr is Null
00602   bool isNull() const;
00603 
00604   // Check if Expr is not Null
00605   bool isInitialized() const { return d_expr != NULL; }
00606   //! Get the memory manager index (it uniquely identifies the subclass)
00607   size_t getMMIndex() const;
00608 
00609   // Attributes
00610 
00611   // True if the find attribute has been set to something other than NULL.
00612   bool hasFind() const;
00613 
00614   // Return the attached find attribute for the expr.  Note that this
00615   // must be called repeatedly to get the root of the union-find tree.
00616   // It may also return a Null theorem if the attribute is not set.
00617   // Return by value, since a reference to the attribute may become
00618   // invalid at any point.
00619   Theorem getFind() const;
00620 
00621   // Return the notify list
00622   NotifyList* getNotify() const;
00623 
00624   //! Get the cached type.
00625   /*! Note that this does not compute the type.  For that, use
00626       Theory::getType() */
00627   const Type& lookupType() const;
00628   //! Look up the cached TCC (may return Null)
00629   const Expr& lookupTCC() const;
00630   //! Look up the cached subtyping predicate (may return Null)
00631   const Theorem& lookupSubtypePred() const;
00632 
00633   /*! @brief Return true if there is a valid cached value for calling
00634       simplify on this Expr. */
00635   bool validSimpCache() const;
00636 
00637   // Get the cached Simplify of this Expr.
00638   const Theorem& getSimpCache() const;
00639 
00640   // True if there is a pointer to the in-place simplification of current Expr
00641   //  bool hasSimpInPlace() const;
00642 
00643   // Return attached in-place simplification of current Expr
00644   //  Theorem getSimpInPlace() const;
00645 
00646   // Return true if there is a valid flag for whether Expr is atomic
00647   bool validIsAtomicFlag() const;
00648 
00649   // Get the isAtomic flag
00650   bool getIsAtomicFlag() const;
00651 
00652   // Get the RewriteNormal flag
00653   bool isRewriteNormal() const;
00654 
00655   //! Check if the generic flag is set
00656   bool getFlag() const;
00657   //! Set the generic flag
00658   void setFlag() const;
00659   //! Clear the generic flag in all Exprs
00660   void clearFlags() const;
00661 
00662   // Printing functions
00663 
00664   //! Print the expression to a string
00665   std::string toString() const;
00666   //! Print the expression to a string using the given output language
00667   std::string toString(InputLanguage lang) const;
00668   //! Print the expression in the specified format
00669   void print(InputLanguage lang) const;
00670   //! Print the expression as AST (lisp-like format)
00671   void print() const { print(AST_LANG); }
00672   /*! @brief Print only the top node of the expression as AST, and
00673     submit children to the ExprStream for pretty-printing */
00674   ExprStream& print(ExprStream& os) const;
00675   //! Set initial indentation to n.
00676   /*! The indentation will be reset to default unless the second
00677     argument is true.
00678     \return reference to itself, so one can write `os << e.indent(5)'
00679   */
00680   Expr& indent(int n, bool permanent = false);
00681 
00682   /////////////////////////////////////////////////////////////////////////////
00683   // Other Public methods                                                    //
00684   /////////////////////////////////////////////////////////////////////////////
00685 
00686   // Attributes
00687 
00688   //! Set the find attribute to e
00689   void setFind(const Theorem& e) const;
00690 
00691   // Set the simpInPlace attribute to e
00692   //  void setSimpInPlace(const Theorem& e) const;
00693 
00694   //! Add (e,i) to the notify list of this expression
00695   void addToNotify(Theory* i, const Expr& e) const;
00696   //! Remove (e,i) from the notify list of this expression
00697   void removeFromNotify(Theory* i, const Expr& e) const;
00698 
00699   //! Set the cached type
00700   void setType(const Type& t) const;
00701   //! Set the cached TCC
00702   void setTCC(const Expr& tcc) const;
00703   //! Set the cached subtyping predicate
00704   void setSubtypePred(const Theorem& pred) const;
00705 
00706   // Cache the result of a call to Simplify on this Expr
00707   void setSimpCache(const Theorem& e) const;
00708 
00709   // Set the isAtomicFlag for this Expr
00710   void setIsAtomicFlag(bool value) const;
00711 
00712   // Set or clear the RewriteNormal flag
00713   void setRewriteNormal() const;
00714   void clearRewriteNormal() const;
00715 
00716   //! Check if the current Expr (*this) is a subexpression of e
00717   bool subExprOf(const Expr& e) const;
00718   // Returns the maximum number of Boolean expressions on a path from
00719   // this to a leaf, including this.
00720   inline int getHeight() const;
00721 
00722   // Returns the index of the highest kid.
00723   inline int getHighestKid() const;
00724 
00725   // Gets/sets an expression that this expression was simplified from
00726   // (see newRWTheorem). This is the equivalent of SVC's Sigx.
00727   inline bool hasSimpFrom() const;
00728   inline const Expr& getSimpFrom() const;
00729   inline void setSimpFrom(const Expr& simpFrom);
00730 
00731   // Attributes for uninterpreted function symbols.  It is an error to
00732   // use these attributes with anything else but UFUNC.
00733   bool hasSig() const;
00734   bool hasRep() const;
00735   const Theorem& getSig() const;
00736   const Theorem& getRep() const;
00737   void setSig(const Theorem& e) const;
00738   void setRep(const Theorem& e) const;
00739 
00740 
00741   
00742 
00743 
00744   /////////////////////////////////////////////////////////////////////////////
00745   // Friend methods                                                          //
00746   /////////////////////////////////////////////////////////////////////////////
00747 
00748   friend std::ostream& operator<<(std::ostream& os, const Expr& e);
00749 
00750   // The master method which defines some fixed total ordering on all
00751   // Exprs.  If e1 < e2, e1==e2, and e1 > e2, it returns -1, 0, 1
00752   // respectively.  A Null expr is always "smaller" than any other
00753   // expr, but is equal to itself.
00754   friend int compare(const Expr& e1, const Expr& e2);
00755 
00756   friend bool operator==(const Expr& e1, const Expr& e2);
00757   friend bool operator!=(const Expr& e1, const Expr& e2);
00758 
00759   friend bool operator<(const Expr& e1, const Expr& e2);
00760   friend bool operator<=(const Expr& e1, const Expr& e2);
00761   friend bool operator>(const Expr& e1, const Expr& e2);
00762   friend bool operator>=(const Expr& e1, const Expr& e2);
00763 
00764   /*!@}*/ // end of group Expr
00765 
00766 }; // end of class Expr
00767 
00768 //! Printing NotifyList class
00769 std::ostream& operator<<(std::ostream& os, const NotifyList& l); 
00770 
00771 } // end of namespace CVCL
00772 
00773 // Include expr_value.h here.  We cannot include it earlier, since it
00774 // needs the definition of class Expr.  See comments in expr_value.h.
00775 #ifndef DOXYGEN
00776 #include "expr_op.h"
00777 #include "expr_manager.h"
00778 #include "expr_value.h"
00779 #endif
00780 namespace CVCL {
00781 
00782  // Private constructor for use in ExprManager
00783  inline Expr::Expr(ExprValue* expr, int i): d_expr(expr) {
00784    d_expr->incRefcount();
00785  }
00786  
00787  inline Expr::Expr(ExprValue* expr) {
00788    DebugAssert(expr != NULL, "Expr::Expr(ExprValue* NULL, int)");
00789    d_expr = expr->d_em->newExprValue(expr);
00790    d_expr->incRefcount();
00791  }
00792  
00793  // Copy constructor and assignment (copy the pointer and take care
00794  // of the refcount)
00795  inline Expr::Expr(const Expr& e) : d_expr(e.d_expr) {
00796    if(d_expr != NULL)
00797      d_expr->incRefcount();
00798  }
00799  
00800  inline Expr& Expr::operator=(const Expr& e) {
00801    if(&e == this) return *this; // Self-assignment
00802    if(d_expr != NULL) {
00803      d_expr->decRefcount();
00804    }
00805    d_expr = e.d_expr;
00806    if(d_expr != NULL)
00807      d_expr->incRefcount();
00808    return *this;
00809  }
00810  
00811   // Similar constructors, but from kinds rather than from an Op
00812  inline Expr::Expr(ExprManager *em, int kind) {
00813    ExprValue ev(em, kind);
00814    d_expr = em->newExprValue(&ev);
00815    d_expr->incRefcount();
00816  }
00817 
00818  inline Expr::Expr(ExprManager *em, int kind, const Expr& child) {
00819    std::vector<Expr> kids;
00820    kids.push_back(child);
00821    ExprNode ev(em, kind, kids);
00822    d_expr = em->newExprValue(&ev);
00823    d_expr->incRefcount();
00824  }
00825 
00826  inline Expr::Expr(ExprManager *em, int kind, const Expr& child0,
00827                    const Expr& child1) {
00828    std::vector<Expr> kids;
00829    kids.push_back(child0);
00830    kids.push_back(child1);
00831    ExprNode ev(em, kind, kids);
00832    d_expr = em->newExprValue(&ev);
00833    d_expr->incRefcount();
00834  }
00835 
00836  inline Expr::Expr(ExprManager *em, int kind, const Expr& child0,
00837                    const Expr& child1, const Expr& child2) {
00838    std::vector<Expr> kids;
00839    kids.push_back(child0);
00840    kids.push_back(child1);
00841    kids.push_back(child2);
00842    ExprNode ev(em, kind, kids);
00843    d_expr = em->newExprValue(&ev);
00844    d_expr->incRefcount();
00845  }
00846 
00847  inline Expr::Expr(ExprManager *em, int kind,
00848                    const std::vector<Expr>& children) {
00849    ExprNode ev(em, kind, children);
00850    d_expr = em->newExprValue(&ev);
00851    d_expr->incRefcount();
00852  }
00853 
00854 
00855  inline Expr Expr::eqExpr(const Expr& right) const {
00856    return Expr(getEM(), EQ, *this, right);
00857  }
00858 
00859  inline Expr Expr::notExpr() const {
00860    return Expr(getEM(), NOT, *this);
00861  }
00862 
00863  inline Expr Expr::negate() const {
00864    return isNot() ? (*this)[0] : this->notExpr();
00865  }
00866 
00867  inline Expr Expr::andExpr(const Expr& right) const {
00868    return Expr(getEM(), AND, *this, right);
00869  }
00870 
00871  inline Expr andExpr(const std::vector <Expr>& children) {
00872    DebugAssert(children.size()>0 && !children[0].isNull(),
00873                "Expr::andExpr(kids)");
00874    return Expr(children[0].getEM(), AND, children);
00875  }
00876 
00877  inline Expr Expr::orExpr(const Expr& right) const {
00878    return Expr(getEM(), OR, *this, right);
00879  }
00880 
00881  inline Expr orExpr(const std::vector <Expr>& children) {
00882    DebugAssert(children.size()>0 && !children[0].isNull(),
00883                "Expr::andExpr(kids)");
00884    return Expr(children[0].getEM(), OR, children);
00885  }
00886 
00887  inline Expr Expr::iteExpr(const Expr& thenpart, const Expr& elsepart) const {
00888    return Expr(getEM(), ITE, *this, thenpart, elsepart);
00889  }
00890 
00891  inline Expr Expr::iffExpr(const Expr& right) const {
00892    return Expr(getEM(), IFF, *this, right);
00893  }
00894 
00895  inline Expr Expr::impExpr(const Expr& right) const {
00896    return Expr(getEM(), IMPLIES, *this, right);
00897  }
00898 
00899  inline Expr Expr::skolemExpr(int i) const {
00900    ExprSkolem ev(getEM(), i, *this);
00901    return newExpr(&ev);
00902  }
00903 
00904  inline Expr Expr::boolVarExpr() const {
00905    BoolVarExprValue ev(getEM(), *this);
00906    return newExpr(&ev);
00907  }
00908 
00909  inline Expr Expr::rebuild(ExprManager* em) const {
00910    return em->rebuild(*this);
00911  }
00912 
00913  inline Expr::~Expr() {
00914    if(d_expr != NULL && !getEM()->d_disableGC) {
00915      d_expr->decRefcount();
00916    }
00917  }
00918 
00919  inline size_t Expr::hash(const Expr& e) { return e.getEM()->hash(e); }
00920 
00921  // Creating new Expr's.  These methods are basically the same as
00922  // constructors, but return value and can be nested.
00923  inline Expr newExpr(ExprValue* ev) {
00924    return Expr(ev);
00925  }
00926 
00927  inline Expr newExpr(ExprManager *em, const Expr& e) {
00928    return e.rebuild(em);
00929  }
00930 
00931  inline Expr newExpr(ExprManager *em, const Op& op) {
00932    return Expr(em, op);
00933  }
00934  inline Expr newExpr(ExprManager *em, const Op& op, const Expr& child) {
00935    return Expr(em, op, child);
00936  }
00937  inline Expr newExpr(ExprManager *em, const Op& op, const Expr& child0,
00938                      const Expr& child1) {
00939    return Expr(em, op, child0, child1);
00940  }
00941  inline Expr newExpr(ExprManager *em, const Op& op, const Expr& child0,
00942                      const Expr& child1, const Expr& child2) {
00943    return Expr(em, op, child0, child1, child2);
00944  }
00945  inline Expr newExpr(ExprManager *em, const Op& op,
00946                      const std::vector<Expr>& children) {
00947    return Expr(em, op, children);
00948  }
00949 
00950  inline Expr newExpr(ExprManager *em, int kind) {
00951    return Expr(em, kind);
00952  }
00953  inline Expr newExpr(ExprManager *em, int kind, const Expr& child) {
00954    return Expr(em, kind, child);
00955  }
00956  inline Expr newExpr(ExprManager *em, int kind, const Expr& child0,
00957                      const Expr& child1) {
00958    return Expr(em, kind, child0, child1);
00959  }
00960  inline Expr newExpr(ExprManager *em, int kind, const Expr& child0,
00961                      const Expr& child1, const Expr& child2) {
00962    return Expr(em, kind, child0, child1, child2);
00963  }
00964  inline Expr newExpr(ExprManager *em, int kind,
00965                      const std::vector<Expr>& children) {
00966    return Expr(em, kind, children);
00967  }
00968 
00969  inline Expr newClosureExpr(ExprManager *em, int kind,
00970                             const std::vector<Expr>& vars, const Expr& body) {
00971    ExprClosure ev(em, kind, vars, body);
00972    return newExpr(&ev);
00973  }
00974 
00975  inline Expr newClosureExpr(int kind, const std::vector<Expr>& vars,
00976                      const Expr& body) {
00977    ExprClosure ev(body.getEM(), kind, vars, body);
00978    return newExpr(&ev);
00979  }
00980 
00981  inline Expr newApplyExpr(ExprManager* em, const Expr& func,
00982                           const std::vector<Expr>& args) {
00983    ExprApply ev(em, func, args);
00984    return newExpr(&ev);
00985  }
00986  inline Expr newNamedExpr(ExprManager* em, int kind, const std::string& name) {
00987    NamedExprValue ev(em, kind, name, std::vector<Expr>());
00988    return newExpr(&ev);
00989  }
00990  inline Expr newNamedExpr(ExprManager* em, int kind, const std::string& name,
00991                           const std::vector<Expr>& kids) {
00992    NamedExprValue ev(em, kind, name, kids);
00993    return newExpr(&ev);
00994  }
00995  inline Expr newNamedExpr(int kind, const std::string& name,
00996                           const std::vector<Expr>& kids) {
00997    DebugAssert(kids.size() > 0 && !kids[0].isNull(), "newNamedExpr()");
00998    NamedExprValue ev(kids[0].getEM(), kind, name, kids);
00999    return newExpr(&ev);
01000  }
01001    
01002  // ExprManager is taken from the op or children
01003  inline Expr newExpr(const Op& op) {
01004    return Expr(op);
01005  }
01006  inline Expr newExpr(const Op& op, const Expr& child) {
01007    return Expr(op, child);
01008  }
01009  
01010  inline Expr newExpr(const Op& op, const Expr& child0, const Expr& child1) {
01011    return Expr(op, child0, child1);
01012  }
01013  inline Expr newExpr(const Op& op, const Expr& child0, const Expr& child1,
01014                      const Expr& child2) {
01015    return Expr(op, child0, child1, child2);
01016  }
01017  inline Expr newExpr(const Op& op, const std::vector<Expr>& children) {
01018    return Expr(op, children);
01019  }
01020 
01021  // Leaf nodes
01022  inline Expr newStringExpr(ExprManager *em, const std::string &s) {
01023    ExprString ev(em, s);
01024    return newExpr(&ev);
01025  }
01026  inline Expr newVarExpr(ExprManager *em, const std::string &s) {
01027    ExprVar ev(em, s);
01028    return newExpr(&ev);
01029  }
01030  inline Expr newBoundVarExpr(ExprManager *em, const std::string &name,
01031                              const std::string& uid) {
01032    ExprBoundVar ev(em, name, uid);
01033    return newExpr(&ev);
01034  }
01035  inline Expr newRatExpr(ExprManager *em, const Rational &r) {
01036    ExprRational ev(em, r);
01037    return newExpr(&ev);
01038  }
01039 
01040  inline Expr newSkolemExpr(const Expr& e, int index) {
01041    return e.skolemExpr(index);
01042  }
01043 
01044  inline Expr newBoolVarExpr(const Expr& e) {
01045    return e.boolVarExpr();
01046  }
01047  inline const Expr& falseExpr(ExprManager *em) {
01048    return em->falseExpr();
01049  }
01050  inline const Expr& trueExpr(ExprManager *em) {
01051    return em->trueExpr();
01052  }
01053 
01054 
01055   /////////////////////////////////////////////////////////////////////////////
01056   // Read-only (const) methods                                               //
01057   /////////////////////////////////////////////////////////////////////////////
01058 
01059  inline size_t Expr::hash() const { return getEM()->hash(*this); }
01060 
01061  // Core Expression Testers
01062 
01063  inline bool Expr::isVar() const { return d_expr->isVar(); }
01064  inline bool Expr::isBoolVar() const { return d_expr->isBoolVar(); }
01065  inline bool Expr::isString() const { return d_expr->isString(); }
01066  inline bool Expr::isClosure() const { return d_expr->isClosure(); }
01067  inline bool Expr::isQuantifier() const {
01068    return (isClosure() && (getKind() == FORALL || getKind() == EXISTS));
01069  }
01070  inline bool Expr::isLambda() const {
01071    return (isClosure() && getKind() == LAMBDA);
01072  }
01073  inline bool Expr::isApply() const { return d_expr->isApply(); }
01074  inline bool Expr::isType() const { return getEM()->isTypeKind(getKind()); }
01075 //  inline bool Expr::isRecord() const { return d_expr->isRecord(); }
01076 //  inline bool Expr::isRecordAccess() const { return d_expr->isField(); }
01077 //  inline bool Expr::isTupleAccess() const { return d_expr->isTupleIndex(); }
01078  inline size_t Expr::isGeneric() const { return d_expr->isGeneric(); }
01079  inline bool Expr::isGeneric(size_t idx) const
01080    { return d_expr->isGeneric(idx); }
01081 
01082  inline int Expr::getHeight() const { return d_expr->getHeight(); }
01083  inline int Expr::getHighestKid() const { return d_expr->getHighestKid(); }
01084 
01085  inline bool Expr::hasSimpFrom() const
01086    { return !d_expr->getSimpFrom().isNull(); }
01087  inline const Expr& Expr::getSimpFrom() const
01088    { return hasSimpFrom() ? d_expr->getSimpFrom() : *this; }
01089  inline void Expr::setSimpFrom(const Expr& simpFrom)
01090    { d_expr->setSimpFrom(simpFrom); }
01091 
01092  // Leaf accessors
01093 
01094  inline const std::string& Expr::getName() const {
01095    DebugAssert(!isNull(), "Expr::getName() on Null expr");
01096    return d_expr->getName();
01097  }
01098 
01099  inline const std::string& Expr::getString() const {
01100     DebugAssert(isString(),
01101                 "CVCL::Expr::getString(): not a string Expr:\n  "
01102                 + toString(AST_LANG));
01103     return d_expr->getString();
01104  }
01105 
01106  inline const std::vector<Expr>& Expr::getVars() const {
01107     DebugAssert(isClosure(),
01108                 "CVCL::Expr::getVars(): not a closure Expr:\n  "
01109                 + toString(AST_LANG));
01110     return d_expr->getVars();
01111  }
01112 
01113  inline const Expr& Expr::getVar() const {
01114     DebugAssert(isBoolVar(),
01115                 "CVCL::Expr::getVar(): not a BoolVar Expr:\n  "
01116                 + toString(AST_LANG));
01117     return d_expr->getVar();
01118  }
01119 
01120  inline const Expr& Expr::getFun() const {
01121     DebugAssert(isApply(),
01122                 "CVCL::Expr::getFun(): not an Apply Expr:\n  "
01123                 + toString(AST_LANG));
01124     return d_expr->getFun();
01125  }
01126 
01127  inline const Expr& Expr::getBody() const {
01128     DebugAssert(isClosure(),
01129                 "CVCL::Expr::getBody(): not a closure Expr:\n  "
01130                 + toString(AST_LANG));
01131     return d_expr->getBody();
01132  }
01133 
01134 //  inline const std::vector<std::string>& Expr::getRecordFields() const {
01135 //    DebugAssert(isRecord(), "Expr::getRecordFields(): not a record Expr:\n  "
01136 //             + toString(AST_LANG));
01137 //    return d_expr->getFields();
01138 //  }
01139 
01140 //  inline const std::string& Expr::getRecordField() const {
01141 //    DebugAssert(isRecordAccess(),
01142 //             "Expr::getRecordField(): not a record access Expr:\n  "
01143 //             + toString(AST_LANG));
01144 //    return d_expr->getField();
01145 //  }
01146 
01147 //  inline int Expr::getFieldIndex(const std::string& fieldName) const
01148 //    {
01149 //      DebugAssert(isRecord(), "Expr::getFieldIndex : not a record");
01150 //      const std::vector<std::string>& fields = getRecordFields();
01151 //      DebugAssert(fields.size() == (unsigned int)arity(),
01152 //        "Expr::getFieldIndex: number of fields differs from number of values");
01153 //      for(int i=0; i<arity(); ++i)
01154 //        {
01155 //       if(fieldName == fields[i])
01156 //         return i;
01157 //        }
01158 //      return -1;
01159        
01160 //    }
01161 //  inline int Expr::getTupleIndex() const {
01162 //    DebugAssert(isTupleAccess(),
01163 //             "Expr::getTupleIndex(): not a tuple access Expr:\n  "
01164 //             + toString(AST_LANG));
01165 //    return d_expr->getTupleIndex();
01166 //  }
01167 
01168 
01169  inline const Expr& Expr::getExistential() const {
01170    DebugAssert(isSkolem(),
01171                "CVCL::Expr::getExistential() not a skolem variable");
01172    return d_expr->getExistential();
01173  }
01174  inline int Expr::getBoundIndex() const {
01175    DebugAssert(isSkolem(),
01176                "CVCL::Expr::getBoundIndex() not a skolem variable");
01177    return d_expr->getBoundIndex();
01178  }
01179 
01180 
01181  inline const Rational& Expr::getRational() const {
01182    DebugAssert(isRational(),
01183                 "CVCL::Expr::getRational(): not a rational Expr:\n  "
01184                 + toString(AST_LANG));
01185     return d_expr->getRational();
01186  }
01187 
01188  inline int Expr::getIntValue(int idx) const
01189    { return d_expr->getIntValue(idx); }
01190  inline const std::string& Expr::getStringValue(int idx) const
01191    { return d_expr->getStringValue(idx); }
01192  inline const Rational& Expr::getRatValue(int idx) const
01193    { return d_expr->getRatValue(idx); }
01194  inline const Expr& Expr::getExprValue(int idx) const
01195    { return d_expr->getExprValue(idx); }
01196  inline const Theorem& Expr::getTheoremValue(int idx) const
01197    { return d_expr->getTheoremValue(idx); }
01198  inline const CDO<int>& Expr::getCDIntValue(int idx) const
01199    { return d_expr->getCDIntValue(idx); }
01200  inline const CDO<Expr>& Expr::getCDExprValue(int idx) const
01201    { return d_expr->getCDExprValue(idx); }
01202  inline const CDO<Theorem>& Expr::getCDTheoremValue(int idx) const
01203    { return d_expr->getCDTheoremValue(idx); }
01204  inline const void* Expr::getOtherValue(int idx) const
01205    { return d_expr->getOtherValue(idx); }
01206 
01207  inline size_t Expr::getIntValueSize() const
01208    { return d_expr->getIntValueSize(); }
01209  inline size_t Expr::getStringValueSize() const
01210    { return d_expr->getStringValueSize(); }
01211  inline size_t Expr::getRatValueSize() const
01212    { return d_expr->getRatValueSize(); }
01213  inline size_t Expr::getExprValueSize() const
01214    { return d_expr->getExprValueSize(); }
01215  inline size_t Expr::getTheoremValueSize() const
01216    { return d_expr->getTheoremValueSize(); }
01217  inline size_t Expr::getCDIntValueSize() const
01218    { return d_expr->getCDIntValueSize(); }
01219  inline size_t Expr::getCDExprValueSize() const
01220    { return d_expr->getCDExprValueSize(); }
01221  inline size_t Expr::getCDTheoremValueSize() const
01222    {return d_expr->getCDTheoremValueSize();}
01223  inline size_t Expr::getOtherValueSize() const
01224    { return d_expr->getOtherValueSize(); }
01225 
01226  inline int& Expr::getIntAttr(int idx) const
01227    { return d_expr->getIntAttr(idx); }
01228  inline Expr& Expr::getExprAttr(int idx) const
01229    { return d_expr->getExprAttr(idx); }
01230  inline Theorem& Expr::getTheoremAttr(int idx) const
01231    { return d_expr->getTheoremAttr(idx); }
01232  inline CDO<int>& Expr::getCDIntAttr(int idx) const
01233    { return d_expr->getCDIntAttr(idx); }
01234  inline CDO<Expr>& Expr::getCDExprAttr(int idx) const
01235    { return d_expr->getCDExprAttr(idx); }
01236  inline CDO<Theorem>& Expr::getCDTheoremAttr(int idx) const
01237    { return d_expr->getCDTheoremAttr(idx); }
01238  inline void* Expr::getOtherAttr(int idx) const
01239    { return d_expr->getOtherAttr(idx); }
01240 
01241  inline size_t Expr::getIntAttrSize() const
01242    { return d_expr->getIntAttrSize(); }
01243  inline size_t Expr::getExprAttrSize() const
01244    { return d_expr->getExprAttrSize(); }
01245  inline size_t Expr::getTheoremAttrSize() const
01246    { return d_expr->getTheoremAttrSize(); }
01247  inline size_t Expr::getCDIntAttrSize() const
01248    { return d_expr->getCDIntAttrSize(); }
01249  inline size_t Expr::getCDExprAttrSize() const
01250    { return d_expr->getCDExprAttrSize(); }
01251  inline size_t Expr::getCDTheoremAttrSize() const
01252    {return d_expr->getCDTheoremAttrSize();}
01253  inline size_t Expr::getOtherAttrSize() const
01254    { return d_expr->getOtherAttrSize(); }
01255 
01256  inline const std::string& Expr::getUid() const {
01257     DebugAssert(getKind() == BOUND_VAR,
01258                 "CVCL::Expr::getUid(): not a BOUND_VAR Expr:\n  "
01259                 + toString(AST_LANG));
01260     return d_expr->getUid();
01261  }
01262 
01263  inline ExprManager* Expr::getEM() const {
01264    ASSERT_FATAL(d_expr != NULL,
01265                 "CVCL::Expr:getEM: on Null Expr (not initialized)");
01266    return d_expr->d_em;
01267  }
01268 
01269  inline const std::vector<Expr>& Expr::getKids() const {
01270    DebugAssert(d_expr != NULL, "Expr::getKids on Null Expr");
01271    if(isNull()) return getEM()->getEmptyVector();
01272    else return d_expr->getKids();
01273  }
01274 
01275  inline int Expr::getKind() const {
01276     if(d_expr == NULL) return NULL_KIND; // FIXME: invent a better Null kind
01277     return d_expr->d_kind;
01278   }
01279 
01280  // Get the index field
01281  inline ExprIndex Expr::getIndex() const { return d_expr->d_index; }
01282  inline bool Expr::hasLastIndex() const { return d_expr->d_em->lastIndex() == getIndex(); }
01283 
01284 //  inline bool Expr::hasOp() const {
01285 //    if(d_expr == NULL) return false;
01286 //    return d_expr->hasOp();
01287 //  }
01288 
01289 //  inline const Expr& Expr::getOpRef() const {
01290 //    DebugAssert(!isNull(), "Expr::getOpRef() on Null expr");
01291 //    return d_expr->getOpRef();
01292 //  }
01293 
01294 //  inline Expr Expr::getOp() const {
01295 //    DebugAssert(!isNull(), "Expr::getOp() on Null expr");
01296 //    return d_expr->getOp();
01297 //  }
01298 
01299  inline int Expr::arity() const {
01300    if(isNull()) return 0;
01301    else return d_expr->arity();
01302  }
01303 
01304  inline bool Expr::isNull() const {
01305    return (d_expr == NULL) || (d_expr->d_kind == NULL_KIND);
01306  }
01307 
01308  inline size_t Expr::getMMIndex() const {
01309    DebugAssert(!isNull(), "Expr::getMMIndex()");
01310    return d_expr->getMMIndex();
01311  }
01312 
01313  // Attributes
01314  inline bool Expr::hasFind() const {
01315    DebugAssert(!isNull(), "hasFind called on NULL Expr");
01316    return (d_expr->d_find && !(d_expr->d_find->get().isNull()));
01317  }
01318  
01319  inline Theorem Expr::getFind() const {
01320    DebugAssert(hasFind(), "Should only be called if find is valid");
01321    return d_expr->d_find->get();
01322  }
01323 
01324  inline NotifyList* Expr::getNotify() const {
01325    if(isNull()) return NULL;
01326    else return d_expr->d_notifyList;
01327  }
01328 
01329  inline const Type& Expr::lookupType() const {
01330    static Type null;
01331    if(isNull()) return null;
01332    else return d_expr->d_type;
01333  }
01334 
01335  inline const Expr& Expr::lookupTCC() const {
01336    static Expr null;
01337    if(isNull()) return null;
01338    else return d_expr->d_tcc;
01339  }
01340 
01341  inline const Theorem& Expr::lookupSubtypePred() const {
01342    static Theorem null;
01343    if(isNull()) return null;
01344    else return d_expr->d_subtypePred;
01345  }
01346 
01347  inline bool Expr::validSimpCache() const {
01348    return d_expr->d_simpCacheTag == getEM()->getSimpCacheTag();
01349  }
01350 
01351  inline const Theorem& Expr::getSimpCache() const {
01352    return d_expr->d_simpCache;
01353  }
01354 
01355  inline bool Expr::validIsAtomicFlag() const {
01356    return d_expr->d_staticFlags & VALID_IS_ATOMIC;
01357  }
01358 
01359  inline bool Expr::getIsAtomicFlag() const {
01360    return d_expr->d_staticFlags & IS_ATOMIC;
01361  }
01362 
01363  inline bool Expr::isRewriteNormal() const {
01364    return d_expr->d_staticFlags & REWRITE_NORMAL;
01365  }
01366 
01367  inline bool Expr::getFlag() const {
01368    DebugAssert(!isNull(), "Expr::getFlag() on Null Expr");
01369    return (d_expr->d_flag == getEM()->getFlag());
01370  }
01371 
01372  inline void Expr::setFlag() const {
01373    DebugAssert(!isNull(), "Expr::setFlag() on Null Expr");
01374    d_expr->d_flag = getEM()->getFlag();
01375  }
01376 
01377  inline void Expr::clearFlags() const {
01378    DebugAssert(!isNull(), "Expr::clearFlags() on Null Expr");
01379    getEM()->clearFlags();
01380  }
01381 
01382  inline void Expr::setFind(const Theorem& e) const {
01383    DebugAssert(!isNull(), "Expr::setFind() on Null expr");
01384    DebugAssert(e.getLHS() == *this, "bad call to setFind");
01385    if (d_expr->d_find) d_expr->d_find->set(e);
01386    else {
01387      CDO<Theorem>* tmp = new CDO<Theorem>(getEM()->getCurrentContext(), e);
01388      d_expr->d_find = tmp;
01389      IF_DEBUG(tmp->setName("CDO[Expr.find]"));
01390    }
01391  }
01392 
01393  inline void Expr::setType(const Type& t) const {
01394    DebugAssert(!isNull(), "Expr::setType() on Null expr");
01395    d_expr->d_type = t;
01396  }
01397 
01398  inline void Expr::setTCC(const Expr& tcc) const {
01399    DebugAssert(!isNull(), "Expr::setTCC() on Null expr");
01400    d_expr->d_tcc = tcc;
01401  }
01402 
01403  inline void Expr::setSubtypePred(const Theorem& pred) const {
01404    DebugAssert(!isNull(), "Expr::setSubtypePred() on Null expr");
01405    d_expr->d_subtypePred = pred;
01406  }
01407 
01408  inline void Expr::setSimpCache(const Theorem& e) const {
01409    DebugAssert(!isNull(), "Expr::setSimpCache() on Null expr");
01410    d_expr->d_simpCache = e;
01411    d_expr->d_simpCacheTag = getEM()->getSimpCacheTag();
01412  }
01413 
01414  inline void Expr::setIsAtomicFlag(bool value) const {
01415    DebugAssert(!isNull(), "Expr::setIsAtomicFlag() on Null expr");
01416    d_expr->d_staticFlags = d_expr->d_staticFlags | VALID_IS_ATOMIC;
01417    if (value) d_expr->d_staticFlags = d_expr->d_staticFlags | IS_ATOMIC;
01418    else d_expr->d_staticFlags = d_expr->d_staticFlags & ~IS_ATOMIC;
01419  }
01420 
01421  inline void Expr::setRewriteNormal() const {
01422    DebugAssert(!isNull(), "Expr::setRewriteNormal() on Null expr");
01423    TRACE("setRewriteNormal", "setRewriteNormal(", *this, ")");
01424    d_expr->d_staticFlags = d_expr->d_staticFlags | REWRITE_NORMAL;
01425  }
01426 
01427  inline void Expr::clearRewriteNormal() const {
01428    DebugAssert(!isNull(), "Expr::clearRewriteNormal() on Null expr");
01429    d_expr->d_staticFlags = d_expr->d_staticFlags & ~REWRITE_NORMAL;
01430  }
01431 
01432  inline bool Expr::hasSig() const {
01433    return (!isNull()
01434            && d_expr->getSig() != NULL 
01435            && !(d_expr->getSig()->get().isNull()));
01436  }
01437 
01438  inline bool Expr::hasRep() const {
01439    return (!isNull()
01440            && d_expr->getRep() != NULL 
01441            && !(d_expr->getRep()->get().isNull()));
01442  }
01443 
01444  inline const Theorem& Expr::getSig() const {
01445    static Theorem nullThm;   
01446    DebugAssert(!isNull(), "Expr::getSig() on Null expr");
01447    if(d_expr->getSig() != NULL)
01448      return d_expr->getSig()->get();
01449    else
01450      return nullThm;
01451  }
01452 
01453  inline const Theorem& Expr::getRep() const {
01454    static Theorem nullThm;
01455    DebugAssert(!isNull(), "Expr::getRep() on Null expr");
01456    if(d_expr->getRep() != NULL)
01457      return d_expr->getRep()->get();
01458    else
01459      return nullThm;
01460  }
01461 
01462  inline void Expr::setSig(const Theorem& e) const {
01463    DebugAssert(!isNull(), "Expr::setSig() on Null expr");
01464    CDO<Theorem>* sig = d_expr->getSig();
01465    if(sig != NULL) sig->set(e);
01466    else {
01467      CDO<Theorem>* tmp = new CDO<Theorem>(getEM()->getCurrentContext(), e);
01468      d_expr->setSig(tmp);
01469      IF_DEBUG(tmp->setName("CDO[Expr.sig] in "+toString()));
01470    }
01471  }
01472  
01473  inline void Expr::setRep(const Theorem& e) const {
01474    DebugAssert(!isNull(), "Expr::setRep() on Null expr");
01475    CDO<Theorem>* rep = d_expr->getRep();
01476    if(rep != NULL) rep->set(e);
01477    else {
01478      CDO<Theorem>* tmp = new CDO<Theorem>(getEM()->getCurrentContext(), e);
01479      d_expr->setRep(tmp);
01480      IF_DEBUG(tmp->setName("CDO[Expr.rep] in "+toString()));
01481    }
01482  }
01483  
01484   inline bool operator==(const Expr& e1, const Expr& e2) {
01485     // Comparing pointers (equal expressions are always shared)
01486     return e1.d_expr == e2.d_expr;
01487   }
01488 
01489   inline bool operator!=(const Expr& e1, const Expr& e2)
01490     { return !(e1 == e2); }
01491 
01492   // compare() is defined in expr.cpp
01493 
01494   inline bool operator<(const Expr& e1, const Expr& e2)
01495     { return compare(e1,e2) < 0; }
01496   inline bool operator<=(const Expr& e1, const Expr& e2)
01497     { return compare(e1,e2) <= 0; }
01498   inline bool operator>(const Expr& e1, const Expr& e2)
01499     { return compare(e1,e2) > 0; }
01500   inline bool operator>=(const Expr& e1, const Expr& e2)
01501     { return compare(e1,e2) >= 0; }
01502   
01503 
01504 } // end of namespace CVCL
01505 
01506 #endif

Generated on Fri May 20 13:13:52 2005 for CVC Lite by  doxygen 1.3.9.1