CVC3
|
00001 /*****************************************************************************/ 00002 /*! 00003 * \file arith_theorem_producer.h 00004 * \brief TRUSTED implementation of arithmetic proof rules 00005 * 00006 * Author: Vijay Ganesh, Sergey Berezin 00007 * 00008 * Created: Dec 13 02:09:04 GMT 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__arith_theorem_producer_h_ 00023 #define _cvc3__arith_theorem_producer_h_ 00024 00025 #include "arith_proof_rules.h" 00026 #include "theorem_producer.h" 00027 #include "theory_arith_new.h" 00028 00029 namespace CVC3 { 00030 class TheoryArithNew; 00031 00032 class ArithTheoremProducer: public ArithProofRules, public TheoremProducer { 00033 TheoryArithNew* d_theoryArith; 00034 private: 00035 /*! \name Auxiliary functions for eqElimIntRule() 00036 * Methods that compute the subterms used in eqElimIntRule() 00037 *@{ 00038 */ 00039 //! Compute the special modulus: i - m*floor(i/m+1/2) 00040 Rational modEq(const Rational& i, const Rational& m); 00041 //! Create the term 't'. See eqElimIntRule(). 00042 Expr create_t(const Expr& eqn); 00043 //! Create the term 't2'. See eqElimIntRule(). 00044 Expr create_t2(const Expr& lhs, const Expr& rhs, const Expr& t); 00045 //! Create the term 't3'. See eqElimIntRule(). 00046 Expr create_t3(const Expr& lhs, const Expr& rhs, const Expr& t); 00047 /*! @brief Takes sum = a_0 + a_1*x_1+...+a_n*x_n and returns the 00048 * vector of similar monomials (in 'summands') with coefficients 00049 * mod(a_i, m). If divide flag is true, the coefficients will be 00050 * mod(a_i,m)/m. 00051 */ 00052 void sumModM(std::vector<Expr>& summands, const Expr& sum, 00053 const Rational& m, const Rational& divisor); 00054 Expr monomialModM(const Expr& e, 00055 const Rational& m, const Rational& divisor); 00056 void sumMulF(std::vector<Expr>& summands, const Expr& sum, 00057 const Rational& m, const Rational& divisor); 00058 Expr monomialMulF(const Expr& e, 00059 const Rational& m, const Rational& divisor); 00060 //! Compute floor(i/m+1/2) + mod(i,m) 00061 Rational f(const Rational& i, const Rational& m); 00062 Expr substitute(const Expr& term, ExprMap<Expr>& eMap); 00063 00064 /*@}*/ 00065 public: 00066 //! Constructor 00067 ArithTheoremProducer(TheoremManager* tm, TheoryArithNew* theoryArith): 00068 TheoremProducer(tm), d_theoryArith(theoryArith) { } 00069 00070 //! Create Expr from Rational (for convenience) 00071 Expr rat(Rational r) { return d_em->newRatExpr(r); } 00072 Type realType() { return d_theoryArith->realType(); } 00073 Type intType() { return d_theoryArith->intType(); } 00074 //! Construct the dark shadow expression representing lhs <= rhs 00075 Expr darkShadow(const Expr& lhs, const Expr& rhs) { 00076 return d_theoryArith->darkShadow(lhs, rhs); 00077 } 00078 //! Construct the gray shadow expression representing c1 <= v - e <= c2 00079 /*! Alternatively, v = e + i for some i s.t. c1 <= i <= c2 00080 */ 00081 Expr grayShadow(const Expr& v, const Expr& e, 00082 const Rational& c1, const Rational& c2) { 00083 return d_theoryArith->grayShadow(v, e, c1, c2); 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Canonization rules 00088 //////////////////////////////////////////////////////////////////// 00089 00090 // ==> x = 1 * x 00091 virtual Theorem varToMult(const Expr& e); 00092 00093 // ==> -(e) = (-1) * e 00094 virtual Theorem uMinusToMult(const Expr& e); 00095 00096 // ==> x - y = x + (-1) * y 00097 virtual Theorem minusToPlus(const Expr& x, const Expr& y); 00098 00099 // Rule for unary minus: it just converts it to division by -1, 00100 virtual Theorem canonUMinusToDivide(const Expr& e); 00101 00102 // Rules for division by constant 'd' 00103 // (c) / d ==> (c/d), takes c and d 00104 virtual Theorem canonDivideConst(const Expr& c, const Expr& d); 00105 // (c * x) / d ==> (c/d) * x, takes (c*x) and d 00106 virtual Theorem canonDivideMult(const Expr& cx, const Expr& d); 00107 // (+ c ...)/d ==> push division to all the coefficients. 00108 // The result is not canonical, but canonizing the summands will 00109 // make it canonical. 00110 // Takes (+ c ...) and d 00111 virtual Theorem canonDividePlus(const Expr& e, const Expr& d); 00112 // x / d ==> (1/d) * x, takes x and d 00113 virtual Theorem canonDivideVar(const Expr& e1, const Expr& e2); 00114 00115 // Canon Rules for multiplication 00116 00117 // TODO Deepak: 00118 // t1 * t2 where t1 and t2 are canonized expressions, i.e. it can be a 00119 // 1) Rational constant 00120 // 2) Arithmetic Leaf (var or term from another theory) 00121 // 3) (POW rational leaf) 00122 // 4) (MULT rational mterm'_1 ...) where each mterm' is of type (2) or (3) 00123 // 5) (PLUS rational sterm_1 sterm_2 ...) where each sterm is of 00124 // type (2) or (3) or (4) 00125 00126 static bool greaterthan(const Expr &, const Expr &); 00127 virtual Expr simplifiedMultExpr(std::vector<Expr> & mulKids); 00128 virtual Expr canonMultConstMult(const Expr & c, const Expr & e); 00129 virtual Expr canonMultConstPlus(const Expr & e1, const Expr & e2); 00130 virtual Expr canonMultPowPow(const Expr & e1, const Expr & e2); 00131 virtual Expr canonMultPowLeaf(const Expr & e1, const Expr & e2); 00132 virtual Expr canonMultLeafLeaf(const Expr & e1, const Expr & e2); 00133 virtual Expr canonMultLeafOrPowMult(const Expr & e1, const Expr & e2); 00134 virtual Expr canonCombineLikeTerms(const std::vector<Expr> & sumExprs); 00135 virtual Expr 00136 canonMultLeafOrPowOrMultPlus(const Expr & e1, const Expr & e2); 00137 virtual Expr canonMultPlusPlus(const Expr & e1, const Expr & e2); 00138 virtual Theorem canonMultMtermMterm(const Expr& e); 00139 virtual Theorem canonPlus(const Expr & e); 00140 virtual Theorem canonInvertConst(const Expr & e); 00141 virtual Theorem canonInvertLeaf(const Expr & e); 00142 virtual Theorem canonInvertPow(const Expr & e); 00143 virtual Theorem canonInvertMult(const Expr & e); 00144 virtual Theorem canonInvert(const Expr & e); 00145 00146 /** 00147 * Transform e = (SUM r t1 ... tn) @ 0 into (SUM t1 ... tn) @ -r. The first 00148 * sum term (r) must be a rational and t1 ... tn terms must be canonised. 00149 * 00150 * @param e the expression to transform 00151 * @return rewrite theorem representing the transformation 00152 */ 00153 virtual Theorem moveSumConstantRight(const Expr& e); 00154 00155 /** e[0]/e[1] ==> e[0]*(e[1])^-1 */ 00156 virtual Theorem canonDivide(const Expr & e); 00157 00158 /** Multiply out the operands of the multiplication (each of them is expected to be canonised */ 00159 virtual Theorem canonMult(const Expr & e); 00160 00161 // t*c ==> c*t, takes constant c and term t 00162 virtual Theorem canonMultTermConst(const Expr& c, const Expr& t); 00163 // t1*t2 ==> Error, takes t1 and t2 where both are non-constants 00164 virtual Theorem canonMultTerm1Term2(const Expr& t1, const Expr& t2); 00165 // 0*t ==> 0, takes 0*t 00166 virtual Theorem canonMultZero(const Expr& e); 00167 // 1*t ==> t, takes 1*t 00168 virtual Theorem canonMultOne(const Expr& e); 00169 // c1*c2 ==> c', takes constant c1*c2 00170 virtual Theorem canonMultConstConst(const Expr& c1, const Expr& c2); 00171 // c1*(c2*t) ==> c'*t, takes c1 and c2 and t 00172 virtual Theorem 00173 canonMultConstTerm(const Expr& c1, const Expr& c2, const Expr&t); 00174 // c1*(+ c2 v1 ...) ==> (+ c' c1v1 ...), takes c1 and the sum 00175 virtual Theorem canonMultConstSum(const Expr& c1, const Expr& sum); 00176 // c^n = c' (compute the constant power expression) 00177 virtual Theorem canonPowConst(const Expr& pow); 00178 00179 // Rules for addition 00180 // flattens the input. accepts a PLUS expr 00181 virtual Theorem canonFlattenSum(const Expr& e); 00182 00183 // Rules for addition 00184 // combine like terms. accepts a flattened PLUS expr 00185 virtual Theorem canonComboLikeTerms(const Expr& e); 00186 00187 // 0 = (* e1 e2 ...) <=> 0 = e1 OR 0 = e2 OR ... 00188 virtual Theorem multEqZero(const Expr& expr); 00189 00190 // 0 = (^ c x) <=> false if c <=0 00191 // <=> 0 = x if c > 0 00192 virtual Theorem powEqZero(const Expr& expr); 00193 00194 // x^n = y^n <=> x = y (if n is odd) 00195 // x^n = y^n <=> x = y OR x = -y (if n is even) 00196 virtual Theorem elimPower(const Expr& expr); 00197 00198 // x^n = c <=> x = root (if n is odd and root^n = c) 00199 // x^n = c <=> x = root OR x = -root (if n is even and root^n = c) 00200 virtual Theorem elimPowerConst(const Expr& expr, const Rational& root); 00201 00202 // x^n = c <=> false (if n is even and c is negative) 00203 virtual Theorem evenPowerEqNegConst(const Expr& expr); 00204 00205 // x^n = c <=> false (if x is an integer and c is not a perfect n power) 00206 virtual Theorem intEqIrrational(const Expr& expr, const Theorem& isInt); 00207 00208 // e[0] kind e[1] <==> true when e[0] kind e[1], 00209 // false when e[0] !kind e[1], for constants only 00210 virtual Theorem constPredicate(const Expr& e); 00211 00212 // e[0] kind e[1] <==> 0 kind e[1] - e[0] 00213 virtual Theorem rightMinusLeft(const Expr& e); 00214 00215 // e[0] kind e[1] <==> e[0] - e[1] kind 0 00216 virtual Theorem leftMinusRight(const Expr& e); 00217 00218 // x kind y <==> x + z kind y + z 00219 virtual Theorem plusPredicate(const Expr& x, 00220 const Expr& y, 00221 const Expr& z, int kind); 00222 00223 // x = y <==> x * z = y * z 00224 virtual Theorem multEqn(const Expr& x, const Expr& y, const Expr& z); 00225 00226 // x = y <==> z=0 OR x * 1/z = y * 1/z 00227 virtual Theorem divideEqnNonConst(const Expr& x, const Expr& y, const Expr& z); 00228 00229 // if z is +ve, return e[0] LT|LE|GT|GE e[1] <==> e[0]*z LT|LE|GT|GE e[1]*z 00230 // if z is -ve, return e[0] LT|LE|GT|GE e[1] <==> e[1]*z LT|LE|GT|GE e[0]*z 00231 virtual Theorem multIneqn(const Expr& e, const Expr& z); 00232 00233 // x = y ==> x <= y and x >= y 00234 virtual Theorem eqToIneq(const Expr& e); 00235 00236 // "op1 GE|GT op2" <==> op2 LE|LT op1 00237 virtual Theorem flipInequality(const Expr& e); 00238 00239 // NOT (op1 LT op2) <==> (op1 GE op2) 00240 // NOT (op1 LE op2) <==> (op1 GT op2) 00241 // NOT (op1 GT op2) <==> (op1 LE op2) 00242 // NOT (op1 GE op2) <==> (op1 LT op2) 00243 Theorem negatedInequality(const Expr& e); 00244 00245 Theorem realShadow(const Theorem& alphaLTt, const Theorem& tLTbeta); 00246 Theorem realShadowEq(const Theorem& alphaLEt, const Theorem& tLEalpha); 00247 Theorem finiteInterval(const Theorem& aLEt, const Theorem& tLEac, 00248 const Theorem& isInta, const Theorem& isIntt); 00249 00250 Theorem darkGrayShadow2ab(const Theorem& betaLEbx, 00251 const Theorem& axLEalpha, 00252 const Theorem& isIntAlpha, 00253 const Theorem& isIntBeta, 00254 const Theorem& isIntx); 00255 00256 Theorem darkGrayShadow2ba(const Theorem& betaLEbx, 00257 const Theorem& axLEalpha, 00258 const Theorem& isIntAlpha, 00259 const Theorem& isIntBeta, 00260 const Theorem& isIntx); 00261 00262 Theorem expandDarkShadow(const Theorem& darkShadow); 00263 Theorem expandGrayShadow0(const Theorem& grayShadow); 00264 Theorem splitGrayShadow(const Theorem& grayShadow); 00265 Theorem splitGrayShadowSmall(const Theorem& grayShadow); 00266 Theorem expandGrayShadow(const Theorem& grayShadow); 00267 Theorem expandGrayShadowConst(const Theorem& grayShadow); 00268 Theorem grayShadowConst(const Theorem& g); 00269 00270 //! Implements j(c,b,a) 00271 /*! accepts 3 integers a,b,c and returns 00272 * (b > 0)? (c+b) mod a : (a - (c+b)) mod a 00273 */ 00274 Rational constRHSGrayShadow(const Rational& c, 00275 const Rational& b, 00276 const Rational& a); 00277 00278 Theorem lessThanToLE(const Theorem& less, const Theorem& isIntLHS, 00279 const Theorem& isIntRHS, bool changeRight); 00280 00281 Theorem lessThanToLERewrite(const Expr& ineq, const Theorem& isIntLHS, 00282 const Theorem& isIntRHS, bool changeRight); 00283 00284 Theorem intVarEqnConst(const Expr& eqn, const Theorem& isIntx); 00285 00286 Theorem IsIntegerElim(const Theorem& isIntx); 00287 Theorem eqElimIntRule(const Theorem& eqn, const Theorem& isIntx, 00288 const std::vector<Theorem>& isIntVars); 00289 00290 Theorem isIntConst(const Expr& e); 00291 00292 Theorem equalLeaves1(const Theorem& e); 00293 Theorem equalLeaves2(const Theorem& e); 00294 Theorem equalLeaves3(const Theorem& e); 00295 Theorem equalLeaves4(const Theorem& e); 00296 00297 Theorem diseqToIneq(const Theorem& diseq); 00298 00299 Theorem dummyTheorem(const Expr& e); 00300 00301 Theorem oneElimination(const Expr& x); 00302 00303 Theorem clashingBounds(const Theorem& lowerBound, const Theorem& upperBound); 00304 00305 Theorem addInequalities(const Theorem& thm1, const Theorem& thm2); 00306 Theorem addInequalities(const std::vector<Theorem>& thms); 00307 00308 Theorem implyWeakerInequality(const Expr& expr1, const Expr& expr2); 00309 00310 Theorem implyNegatedInequality(const Expr& expr1, const Expr& expr2); 00311 00312 Theorem integerSplit(const Expr& intVar, const Rational& intPoint); 00313 00314 Theorem trustedRewrite(const Expr& expr1, const Expr& expr2); 00315 00316 Theorem rafineStrictInteger(const Theorem& isIntConstrThm, const Expr& constr); 00317 00318 Theorem simpleIneqInt(const Expr& ineq, const Theorem& isIntRHS); 00319 00320 Theorem intEqualityRationalConstant(const Theorem& isIntConstrThm, const Expr& constr); 00321 00322 Theorem cycleConflict(const std::vector<Theorem>& inequalitites); 00323 00324 Theorem implyEqualities(const std::vector<Theorem>& inequalities); 00325 00326 Theorem implyWeakerInequalityDiffLogic(const std::vector<Theorem>& antecedentThms, const Expr& implied); 00327 00328 Theorem implyNegatedInequalityDiffLogic(const std::vector<Theorem>& antecedentThms, const Expr& implied); 00329 00330 Theorem expandGrayShadowRewrite(const Expr& theShadow); 00331 00332 Theorem compactNonLinearTerm(const Expr& nonLinear); 00333 00334 Theorem nonLinearIneqSignSplit(const Theorem& ineqThm); 00335 00336 Theorem implyDiffLogicBothBounds(const Expr& x, std::vector<Theorem>& c1_le_x, Rational c1, 00337 std::vector<Theorem>& x_le_c2, Rational c2); 00338 00339 Theorem powerOfOne(const Expr& e); 00340 00341 }; // end of class ArithTheoremProducer 00342 00343 } // end of namespace CVC3 00344 00345 #endif