CVC3
|
00001 /*****************************************************************************/ 00002 /*! 00003 * \file theory_arith.h 00004 * 00005 * Author: Clark Barrett 00006 * 00007 * Created: Fri Jan 17 18:34:55 2003 00008 * 00009 * <hr> 00010 * 00011 * License to use, copy, modify, sell and/or distribute this software 00012 * and its documentation for any purpose is hereby granted without 00013 * royalty, subject to the terms and conditions defined in the \ref 00014 * LICENSE file provided with this distribution. 00015 * 00016 * <hr> 00017 * 00018 */ 00019 /*****************************************************************************/ 00020 00021 #ifndef _cvc3__include__theory_arith_h_ 00022 #define _cvc3__include__theory_arith_h_ 00023 00024 #include "theory.h" 00025 #include "cdmap.h" 00026 00027 namespace CVC3 { 00028 00029 class ArithProofRules; 00030 00031 typedef enum { 00032 // New constants 00033 REAL_CONST = 30, // wrapper around constants to indicate that they should be real 00034 NEGINF = 31, 00035 POSINF = 32, 00036 00037 REAL = 3000, 00038 INT, 00039 SUBRANGE, 00040 00041 UMINUS, 00042 PLUS, 00043 MINUS, 00044 MULT, 00045 DIVIDE, 00046 POW, 00047 INTDIV, 00048 MOD, 00049 LT, 00050 LE, 00051 GT, 00052 GE, 00053 IS_INTEGER, 00054 DARK_SHADOW, 00055 GRAY_SHADOW 00056 00057 } ArithKinds; 00058 00059 /*****************************************************************************/ 00060 /*! 00061 *\class TheoryArith 00062 *\ingroup Theories 00063 *\brief This theory handles basic linear arithmetic. 00064 * 00065 * Author: Clark Barrett 00066 * 00067 * Created: Sat Feb 8 14:44:32 2003 00068 */ 00069 /*****************************************************************************/ 00070 class TheoryArith :public Theory { 00071 protected: 00072 Type d_realType; 00073 Type d_intType; 00074 std::vector<int> d_kinds; 00075 00076 protected: 00077 00078 //! Canonize the expression e, assuming all children are canonical 00079 virtual Theorem canon(const Expr& e) = 0; 00080 00081 //! Canonize the expression e recursively 00082 Theorem canonRec(const Expr& e); 00083 00084 //! Print a rational in SMT-LIB format 00085 void printRational(ExprStream& os, const Rational& r, 00086 bool printAsReal = false); 00087 00088 //! Whether any ite's appear in the arithmetic part of the term e 00089 bool isAtomicArithTerm(const Expr& e); 00090 00091 //! simplify leaves and then canonize 00092 Theorem canonSimp(const Expr& e); 00093 00094 //! helper for checkAssertEqInvariant 00095 bool recursiveCanonSimpCheck(const Expr& e); 00096 00097 public: 00098 TheoryArith(TheoryCore* core, const std::string& name) 00099 : Theory(core, name) {} 00100 ~TheoryArith() {} 00101 00102 virtual void addMultiplicativeSignSplit(const Theorem& case_split_thm) {}; 00103 00104 /** 00105 * Record that smaller should be smaller than bigger in the variable order. 00106 * Should be implemented in decision procedures that support it. 00107 */ 00108 virtual bool addPairToArithOrder(const Expr& smaller, const Expr& bigger) { return true; }; 00109 00110 // Used by translator 00111 //! Return whether e is syntactically identical to a rational constant 00112 bool isSyntacticRational(const Expr& e, Rational& r); 00113 //! Whether any ite's appear in the arithmetic part of the formula e 00114 bool isAtomicArithFormula(const Expr& e); 00115 //! Rewrite an atom to look like x - y op c if possible--for smtlib translation 00116 Expr rewriteToDiff(const Expr& e); 00117 00118 /*! @brief Composition of canon(const Expr&) by transitivity: take e0 = e1, 00119 * canonize e1 to e2, return e0 = e2. */ 00120 Theorem canonThm(const Theorem& thm) { 00121 return transitivityRule(thm, canon(thm.getRHS())); 00122 } 00123 00124 // ArithTheoremProducer needs this function, so make it public 00125 //! Separate monomial e = c*p1*...*pn into c and 1*p1*...*pn 00126 virtual void separateMonomial(const Expr& e, Expr& c, Expr& var) = 0; 00127 00128 // Theory interface 00129 virtual void addSharedTerm(const Expr& e) = 0; 00130 virtual void assertFact(const Theorem& e) = 0; 00131 virtual void refineCounterExample() = 0; 00132 virtual void computeModelBasic(const std::vector<Expr>& v) = 0; 00133 virtual void computeModel(const Expr& e, std::vector<Expr>& vars) = 0; 00134 virtual void checkSat(bool fullEffort) = 0; 00135 virtual Theorem rewrite(const Expr& e) = 0; 00136 virtual void setup(const Expr& e) = 0; 00137 virtual void update(const Theorem& e, const Expr& d) = 0; 00138 virtual Theorem solve(const Theorem& e) = 0; 00139 virtual void checkAssertEqInvariant(const Theorem& e) = 0; 00140 virtual void checkType(const Expr& e) = 0; 00141 virtual Cardinality finiteTypeInfo(Expr& e, Unsigned& n, 00142 bool enumerate, bool computeSize) = 0; 00143 virtual void computeType(const Expr& e) = 0; 00144 virtual Type computeBaseType(const Type& t) = 0; 00145 virtual void computeModelTerm(const Expr& e, std::vector<Expr>& v) = 0; 00146 virtual Expr computeTypePred(const Type& t, const Expr& e) = 0; 00147 virtual Expr computeTCC(const Expr& e) = 0; 00148 virtual ExprStream& print(ExprStream& os, const Expr& e) = 0; 00149 virtual Expr parseExprOp(const Expr& e) = 0; 00150 00151 // Arith constructors 00152 Type realType() { return d_realType; } 00153 Type intType() { return d_intType;} 00154 Type subrangeType(const Expr& l, const Expr& r) 00155 { return Type(Expr(SUBRANGE, l, r)); } 00156 Expr rat(Rational r) { return getEM()->newRatExpr(r); } 00157 // Dark and Gray shadows (for internal use only) 00158 //! Construct the dark shadow expression representing lhs <= rhs 00159 Expr darkShadow(const Expr& lhs, const Expr& rhs) { 00160 return Expr(DARK_SHADOW, lhs, rhs); 00161 } 00162 //! Construct the gray shadow expression representing c1 <= v - e <= c2 00163 /*! Alternatively, v = e + i for some i s.t. c1 <= i <= c2 00164 */ 00165 Expr grayShadow(const Expr& v, const Expr& e, 00166 const Rational& c1, const Rational& c2) { 00167 return Expr(GRAY_SHADOW, v, e, rat(c1), rat(c2)); 00168 } 00169 bool leavesAreNumConst(const Expr& e); 00170 }; 00171 00172 // Arith testers 00173 inline bool isReal(Type t) { return t.getExpr().getKind() == REAL; } 00174 inline bool isInt(Type t) { return t.getExpr().getKind() == INT; } 00175 00176 // Static arith testers 00177 inline bool isRational(const Expr& e) { return e.isRational(); } 00178 inline bool isIntegerConst(const Expr& e) 00179 { return e.isRational() && e.getRational().isInteger(); } 00180 inline bool isUMinus(const Expr& e) { return e.getKind() == UMINUS; } 00181 inline bool isPlus(const Expr& e) { return e.getKind() == PLUS; } 00182 inline bool isMinus(const Expr& e) { return e.getKind() == MINUS; } 00183 inline bool isMult(const Expr& e) { return e.getKind() == MULT; } 00184 inline bool isDivide(const Expr& e) { return e.getKind() == DIVIDE; } 00185 inline bool isPow(const Expr& e) { return e.getKind() == POW; } 00186 inline bool isLT(const Expr& e) { return e.getKind() == LT; } 00187 inline bool isLE(const Expr& e) { return e.getKind() == LE; } 00188 inline bool isGT(const Expr& e) { return e.getKind() == GT; } 00189 inline bool isGE(const Expr& e) { return e.getKind() == GE; } 00190 inline bool isDarkShadow(const Expr& e) { return e.getKind() == DARK_SHADOW;} 00191 inline bool isGrayShadow(const Expr& e) { return e.getKind() == GRAY_SHADOW;} 00192 inline bool isIneq(const Expr& e) 00193 { return isLT(e) || isLE(e) || isGT(e) || isGE(e); } 00194 inline bool isIntPred(const Expr& e) { return e.getKind() == IS_INTEGER; } 00195 00196 // Static arith constructors 00197 inline Expr uminusExpr(const Expr& child) 00198 { return Expr(UMINUS, child); } 00199 inline Expr plusExpr(const Expr& left, const Expr& right) 00200 { return Expr(PLUS, left, right); } 00201 inline Expr plusExpr(const std::vector<Expr>& children) { 00202 DebugAssert(children.size() > 0, "plusExpr()"); 00203 return Expr(PLUS, children); 00204 } 00205 inline Expr minusExpr(const Expr& left, const Expr& right) 00206 { return Expr(MINUS, left, right); } 00207 inline Expr multExpr(const Expr& left, const Expr& right) 00208 { return Expr(MULT, left, right); } 00209 // Begin Deepak: 00210 //! a Mult expr with two or more children 00211 inline Expr multExpr(const std::vector<Expr>& children) { 00212 DebugAssert(children.size() > 0, "multExpr()"); 00213 return Expr(MULT, children); 00214 } 00215 //! Power (x^n, or base^{pow}) expressions 00216 inline Expr powExpr(const Expr& pow, const Expr & base) 00217 { return Expr(POW, pow, base);} 00218 // End Deepak 00219 inline Expr divideExpr(const Expr& left, const Expr& right) 00220 { return Expr(DIVIDE, left, right); } 00221 inline Expr ltExpr(const Expr& left, const Expr& right) 00222 { return Expr(LT, left, right); } 00223 inline Expr leExpr(const Expr& left, const Expr& right) 00224 { return Expr(LE, left, right); } 00225 inline Expr gtExpr(const Expr& left, const Expr& right) 00226 { return Expr(GT, left, right); } 00227 inline Expr geExpr(const Expr& left, const Expr& right) 00228 { return Expr(GE, left, right); } 00229 00230 inline Expr operator-(const Expr& child) 00231 { return uminusExpr(child); } 00232 inline Expr operator+(const Expr& left, const Expr& right) 00233 { return plusExpr(left, right); } 00234 inline Expr operator-(const Expr& left, const Expr& right) 00235 { return minusExpr(left, right); } 00236 inline Expr operator*(const Expr& left, const Expr& right) 00237 { return multExpr(left, right); } 00238 inline Expr operator/(const Expr& left, const Expr& right) 00239 { return divideExpr(left, right); } 00240 00241 } 00242 00243 #endif