/*****************************************************************************/ /*! * \file theory_arith.h * * Author: Clark Barrett * * Created: Fri Jan 17 18:34:55 2003 * *
* * License to use, copy, modify, sell and/or distribute this software * and its documentation for any purpose is hereby granted without * royalty, subject to the terms and conditions defined in the \ref * LICENSE file provided with this distribution. * *
* */ /*****************************************************************************/ #ifndef _cvc3__include__theory_arith_h_ #define _cvc3__include__theory_arith_h_ #include "theory.h" #include "cdmap.h" namespace CVC3 { class ArithProofRules; typedef enum { REAL = 3000, INT, SUBRANGE, UMINUS, PLUS, MINUS, MULT, DIVIDE, POW, INTDIV, MOD, LT, LE, GT, GE, IS_INTEGER, NEGINF, POSINF, DARK_SHADOW, GRAY_SHADOW, REAL_CONST // wrapper around constants to indicate that they should be real } ArithKinds; /*****************************************************************************/ /*! *\class TheoryArith *\ingroup Theories *\brief This theory handles basic linear arithmetic. * * Author: Clark Barrett * * Created: Sat Feb 8 14:44:32 2003 */ /*****************************************************************************/ class TheoryArith :public Theory { protected: Type d_realType; Type d_intType; protected: //! Canonize the expression e, assuming all children are canonical virtual Theorem canon(const Expr& e) = 0; //! Canonize the expression e recursively Theorem canonRec(const Expr& e); //! Print a rational in SMT-LIB format void printRational(ExprStream& os, const Rational& r, bool printAsReal = false); //! Whether any ite's appear in the arithmetic part of the term e bool isAtomicArithTerm(const Expr& e); //! simplify leaves and then canonize Theorem canonSimp(const Expr& e); //! helper for checkAssertEqInvariant bool recursiveCanonSimpCheck(const Expr& e); public: TheoryArith(TheoryCore* core, const std::string& name) : Theory(core, name) {} ~TheoryArith() {} // Used by translator //! Return whether e is syntactically identical to a rational constant bool isSyntacticRational(const Expr& e, Rational& r); //! Whether any ite's appear in the arithmetic part of the formula e bool isAtomicArithFormula(const Expr& e); //! Rewrite an atom to look like x - y op c if possible--for smtlib translation Expr rewriteToDiff(const Expr& e); /*! @brief Composition of canon(const Expr&) by transitivity: take e0 = e1, * canonize e1 to e2, return e0 = e2. */ Theorem canonThm(const Theorem& thm) { return transitivityRule(thm, canon(thm.getRHS())); } // ArithTheoremProducer needs this function, so make it public //! Separate monomial e = c*p1*...*pn into c and 1*p1*...*pn virtual void separateMonomial(const Expr& e, Expr& c, Expr& var) = 0; // Theory interface virtual void addSharedTerm(const Expr& e) = 0; virtual void assertFact(const Theorem& e) = 0; virtual void refineCounterExample() = 0; virtual void computeModelBasic(const std::vector& v) = 0; virtual void computeModel(const Expr& e, std::vector& vars) = 0; virtual void checkSat(bool fullEffort) = 0; virtual Theorem rewrite(const Expr& e) = 0; virtual void setup(const Expr& e) = 0; virtual void update(const Theorem& e, const Expr& d) = 0; virtual Theorem solve(const Theorem& e) = 0; virtual void checkAssertEqInvariant(const Theorem& e) = 0; virtual void checkType(const Expr& e) = 0; virtual void computeType(const Expr& e) = 0; virtual Type computeBaseType(const Type& t) = 0; virtual void computeModelTerm(const Expr& e, std::vector& v) = 0; virtual Expr computeTypePred(const Type& t, const Expr& e) = 0; virtual Expr computeTCC(const Expr& e) = 0; virtual ExprStream& print(ExprStream& os, const Expr& e) = 0; virtual Expr parseExprOp(const Expr& e) = 0; // Arith constructors Type realType() { return d_realType; } Type intType() { return d_intType;} Type subrangeType(const Expr& l, const Expr& r) { return Type(Expr(SUBRANGE, l, r)); } Expr rat(Rational r) { return getEM()->newRatExpr(r); } // Dark and Gray shadows (for internal use only) //! Construct the dark shadow expression representing lhs <= rhs Expr darkShadow(const Expr& lhs, const Expr& rhs) { return Expr(DARK_SHADOW, lhs, rhs); } //! Construct the gray shadow expression representing c1 <= v - e <= c2 /*! Alternatively, v = e + i for some i s.t. c1 <= i <= c2 */ Expr grayShadow(const Expr& v, const Expr& e, const Rational& c1, const Rational& c2) { return Expr(GRAY_SHADOW, v, e, rat(c1), rat(c2)); } }; // Arith testers inline bool isReal(Type t) { return t.getExpr().getKind() == REAL; } inline bool isInt(Type t) { return t.getExpr().getKind() == INT; } // Static arith testers inline bool isRational(const Expr& e) { return e.isRational(); } inline bool isIntegerConst(const Expr& e) { return e.isRational() && e.getRational().isInteger(); } inline bool isUMinus(const Expr& e) { return e.getKind() == UMINUS; } inline bool isPlus(const Expr& e) { return e.getKind() == PLUS; } inline bool isMinus(const Expr& e) { return e.getKind() == MINUS; } inline bool isMult(const Expr& e) { return e.getKind() == MULT; } inline bool isDivide(const Expr& e) { return e.getKind() == DIVIDE; } inline bool isPow(const Expr& e) { return e.getKind() == POW; } inline bool isLT(const Expr& e) { return e.getKind() == LT; } inline bool isLE(const Expr& e) { return e.getKind() == LE; } inline bool isGT(const Expr& e) { return e.getKind() == GT; } inline bool isGE(const Expr& e) { return e.getKind() == GE; } inline bool isDarkShadow(const Expr& e) { return e.getKind() == DARK_SHADOW;} inline bool isGrayShadow(const Expr& e) { return e.getKind() == GRAY_SHADOW;} inline bool isIneq(const Expr& e) { return isLT(e) || isLE(e) || isGT(e) || isGE(e); } inline bool isIntPred(const Expr& e) { return e.getKind() == IS_INTEGER; } // Static arith constructors inline Expr uminusExpr(const Expr& child) { return Expr(UMINUS, child); } inline Expr plusExpr(const Expr& left, const Expr& right) { return Expr(PLUS, left, right); } inline Expr plusExpr(const std::vector& children) { DebugAssert(children.size() > 0, "plusExpr()"); return Expr(PLUS, children); } inline Expr minusExpr(const Expr& left, const Expr& right) { return Expr(MINUS, left, right); } inline Expr multExpr(const Expr& left, const Expr& right) { return Expr(MULT, left, right); } // Begin Deepak: //! a Mult expr with two or more children inline Expr multExpr(const std::vector& children) { DebugAssert(children.size() > 0, "multExpr()"); return Expr(MULT, children); } //! Power (x^n, or base^{pow}) expressions inline Expr powExpr(const Expr& pow, const Expr & base) { return Expr(POW, pow, base);} // End Deepak inline Expr divideExpr(const Expr& left, const Expr& right) { return Expr(DIVIDE, left, right); } inline Expr ltExpr(const Expr& left, const Expr& right) { return Expr(LT, left, right); } inline Expr leExpr(const Expr& left, const Expr& right) { return Expr(LE, left, right); } inline Expr gtExpr(const Expr& left, const Expr& right) { return Expr(GT, left, right); } inline Expr geExpr(const Expr& left, const Expr& right) { return Expr(GE, left, right); } inline Expr operator-(const Expr& child) { return uminusExpr(child); } inline Expr operator+(const Expr& left, const Expr& right) { return plusExpr(left, right); } inline Expr operator-(const Expr& left, const Expr& right) { return minusExpr(left, right); } inline Expr operator*(const Expr& left, const Expr& right) { return multExpr(left, right); } inline Expr operator/(const Expr& left, const Expr& right) { return divideExpr(left, right); } } #endif