00001 /*****************************************************************************/ 00002 /*! 00003 * \file arith_proof_rules.h 00004 * \brief Arithmetic proof rules 00005 * 00006 * Author: Vijay Ganesh, Sergey Berezin 00007 * 00008 * Created: Dec 13 02:09:04 GMT 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__arith_proof_rules_h_ 00031 #define _CVC_lite__arith_proof_rules_h_ 00032 00033 #include <vector> 00034 00035 namespace CVCL { 00036 00037 class Theorem; 00038 class Expr; 00039 00040 class ArithProofRules { 00041 public: 00042 // Destructor 00043 virtual ~ArithProofRules() { } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Canonization rules 00047 //////////////////////////////////////////////////////////////////// 00048 00049 //! ==> -(e) = (-1) * e 00050 virtual Theorem uMinusToMult(const Expr& e) = 0; 00051 00052 //! ==> x - y = x + (-1) * y 00053 virtual Theorem minusToPlus(const Expr& x, const Expr& y) = 0; 00054 00055 //! -(e) ==> e / (-1); takes 'e' 00056 /*! Canon Rule for unary minus: it just converts it to division by 00057 * -1, the result is not yet canonical: 00058 */ 00059 virtual Theorem canonUMinusToDivide(const Expr& e) = 0; 00060 00061 //! (c) / d ==> (c/d), takes c and d 00062 /*! Canon Rules for division by constant 'd' */ 00063 virtual Theorem canonDivideConst(const Expr& c, const Expr& d) = 0; 00064 //! (c * x) / d ==> (c/d) * x, takes (c*x) and d 00065 virtual Theorem canonDivideMult(const Expr& cx, const Expr& d) = 0; 00066 //! (+ c ...)/d ==> push division to all the coefficients. 00067 /*! The result is not canonical, but canonizing the summands will 00068 * make it canonical. 00069 * Takes (+ c ...) and d 00070 */ 00071 virtual Theorem canonDividePlus(const Expr& e, const Expr& d) = 0; 00072 //! x / d ==> (1/d) * x, takes x and d 00073 virtual Theorem canonDivideVar(const Expr& e, const Expr& e) = 0; 00074 00075 // Canon Rules for multiplication 00076 00077 // TODO Deepak: 00078 // e == t1 * t2 where t1 and t2 are canonized expressions, i.e. it can be a 00079 // 1) Rational constant 00080 // 2) Arithmetic Leaf (var or term from another theory) 00081 // 3) (POW rational leaf) 00082 // 4) (MULT rational mterm'_1 ...) where each mterm' is of type (2) or (3) 00083 // 5) (PLUS rational sterm_1 sterm_2 ...) where each sterm is of 00084 // type (2) or (3) or (4) 00085 virtual Theorem canonMultMtermMterm(const Expr& e) = 0; 00086 //! Canonize (PLUS t1 ... tn) 00087 virtual Theorem canonPlus(const Expr & e) = 0; 00088 //! Canonize (MULT t1 ... tn) 00089 virtual Theorem canonMult(const Expr & e) = 0; 00090 //! ==> 1/e = e' where e' is canonical; takes e. 00091 virtual Theorem canonInvert(const Expr & e) = 0; 00092 //! Canonize t1/t2 00093 virtual Theorem canonDivide(const Expr & e) = 0; 00094 00095 //! t*c ==> c*t, takes constant c and term t 00096 virtual Theorem canonMultTermConst(const Expr& c, const Expr& t) = 0; 00097 //! t1*t2 ==> Error, takes t1 and t2 where both are non-constants 00098 virtual Theorem canonMultTerm1Term2(const Expr& t1, const Expr& t2) = 0; 00099 //! 0*t ==> 0, takes 0*t 00100 virtual Theorem canonMultZero(const Expr& e) = 0; 00101 //! 1*t ==> t, takes 1*t 00102 virtual Theorem canonMultOne(const Expr& e) = 0; 00103 //! c1*c2 ==> c', takes constant c1*c2 00104 virtual Theorem canonMultConstConst(const Expr& c1, const Expr& c2) = 0; 00105 //! c1*(c2*t) ==> c'*t, takes c1 and c2 and t 00106 virtual Theorem 00107 canonMultConstTerm(const Expr& c1, const Expr& c2, const Expr&t) = 0; 00108 //! c1*(+ c2 v1 ...) ==> (+ c' c1v1 ...), takes c1 and the sum 00109 virtual Theorem canonMultConstSum(const Expr& c1, const Expr& sum) = 0; 00110 //! c^n = c' (compute the constant power expression) 00111 virtual Theorem canonPowConst(const Expr& pow) = 0; 00112 00113 // Rules for addition 00114 //! flattens the input. accepts a PLUS expr 00115 virtual Theorem canonFlattenSum(const Expr& e) = 0; 00116 00117 //! combine like terms. accepts a flattened PLUS expr 00118 virtual Theorem canonComboLikeTerms(const Expr& e) = 0; 00119 00120 //! e0 \@ e1 <==> true | false, where \@ is {=,<,<=,>,>=} 00121 /*! \param e takes e is (e0\@e1) where e0 and e1 are constants 00122 */ 00123 virtual Theorem constPredicate(const Expr& e) = 0; 00124 00125 //! e[0] @ e[1] <==> 0 @ e[1] - e[0], where @ is {=,<,<=,>,>=} 00126 virtual Theorem rightMinusLeft(const Expr& e) = 0; 00127 00128 //! x @ y <==> x + z @ y + z, where @ is {=,<,<=,>,>=} (given as 'kind') 00129 virtual Theorem plusPredicate(const Expr& x, 00130 const Expr& y, const Expr& z, int kind) = 0; 00131 00132 //! x = y <==> x * z = y * z, where z is a non-zero constant 00133 virtual Theorem multEqn(const Expr& x, const Expr& y, const Expr& z) = 0; 00134 00135 //! Multiplying inequation by a non-zero constant 00136 /*! 00137 * z>0 ==> e[0] @ e[1] <==> e[0]*z @ e[1]*z 00138 * 00139 * z<0 ==> e[0] @ e[1] <==> e[1]*z @ e[0]*z 00140 * 00141 * for @ in {<,<=,>,>=}: 00142 */ 00143 virtual Theorem multIneqn(const Expr& e, const Expr& z) = 0; 00144 00145 //! "op1 GE|GT op2" <==> op2 LE|LT op1 00146 virtual Theorem flipInequality(const Expr& e) = 0; 00147 00148 //! Propagating negation over <,<=,>,>= 00149 /*! NOT (op1 < op2) <==> (op1 >= op2) 00150 * 00151 * NOT (op1 <= op2) <==> (op1 > op2) 00152 * 00153 * NOT (op1 > op2) <==> (op1 <= op2) 00154 * 00155 * NOT (op1 >= op2) <==> (op1 < op2) 00156 */ 00157 virtual Theorem negatedInequality(const Expr& e) = 0; 00158 00159 //! Real shadow: a <(=) t, t <(=) b ==> a <(=) b 00160 virtual Theorem realShadow(const Theorem& alphaLTt, 00161 const Theorem& tLTbeta) = 0; 00162 00163 //! Projecting a tight inequality: alpha <= t <= alpha ==> t = alpha 00164 virtual Theorem realShadowEq(const Theorem& alphaLEt, 00165 const Theorem& tLEalpha) = 0; 00166 00167 //! Finite interval for integers: a <= t <= a + c ==> G(t, a, 0, c) 00168 virtual Theorem finiteInterval(const Theorem& aLEt, 00169 const Theorem& tLEac, 00170 const Theorem& isInta, 00171 const Theorem& isIntt) = 0; 00172 00173 //! Dark & Gray shadows when a <= b 00174 /*! takes two integer ineqs (i.e. all vars are ints) 00175 * "|- beta <= b.x" and "|- a.x <= alpha" and checks if "1 <= a <= b" 00176 * and returns (D or G) and (!D or !G), where 00177 * D = Dark_Shadow(ab-1, b.alpha - a.beta), 00178 * G = Gray_Shadow(a.x, alpha, -(a-1), 0). 00179 */ 00180 virtual Theorem darkGrayShadow2ab(const Theorem& betaLEbx, 00181 const Theorem& axLEalpha, 00182 const Theorem& isIntAlpha, 00183 const Theorem& isIntBeta, 00184 const Theorem& isIntx)=0; 00185 00186 //! Dark & Gray shadows when b <= a 00187 /*! takes two integer ineqs (i.e. all vars are ints) 00188 * "|- beta <= b.x" and "|- a.x <= alpha" and checks if "1 <= b < a" 00189 * and returns (D or G) and (!D or !G), where 00190 * D = Dark_Shadow(ab-1, b.alpha - a.beta), 00191 * G = Gray_Shadow(b.x, beta, 0, b-1). 00192 */ 00193 virtual Theorem darkGrayShadow2ba(const Theorem& betaLEbx, 00194 const Theorem& axLEalpha, 00195 const Theorem& isIntAlpha, 00196 const Theorem& isIntBeta, 00197 const Theorem& isIntx)=0; 00198 00199 //! DARK_SHADOW(t1, t2) ==> t1 <= t2 00200 virtual Theorem expandDarkShadow(const Theorem& darkShadow)=0; 00201 00202 //! GRAY_SHADOW(v, e, c, c) ==> v=e+c. 00203 virtual Theorem expandGrayShadow0(const Theorem& g)=0; 00204 00205 // [used to be] GRAY_SHADOW(t1, t2, i) ==> t1 = t2+i OR 00206 // GRAY_SHADOW(t1, t2, i+/-1) 00207 00208 //! G(x, e, c1, c2) ==> (G1 or G2) and (!G1 or !G2) 00209 /*! Here G1 = G(x,e,c1,c), 00210 * G2 = G(x,e,c+1,c2), 00211 * and c = floor((c1+c2)/2). 00212 */ 00213 virtual Theorem splitGrayShadow(const Theorem& g)=0; 00214 //! G(x, e, c1, c2) ==> e+c1 <= x AND x <= e+c2 00215 virtual Theorem expandGrayShadow(const Theorem& g)=0; 00216 00217 //! Optimized rules: GRAY_SHADOW(a*x, c, c1, c2) ==> [expansion] 00218 /*! Implements three versions of the rule: 00219 * 00220 * \f[\frac{\mathrm{GRAY\_SHADOW}(ax,c,c1,c2)} 00221 * {ax = c + i - \mathrm{sign}(i)\cdot j(c,i,a) 00222 * \lor GRAY\_SHADOW(ax, c, i-\mathrm{sign}(i)\cdot (a+j(c,i,a)))}\f] 00223 * 00224 * where the conclusion may become FALSE or without the 00225 * GRAY_SHADOW part, depending on the values of a, c and i. 00226 */ 00227 virtual Theorem expandGrayShadowConst(const Theorem& g)=0; 00228 //! |- G(ax, c, c1, c2) ==> |- G(x, 0, ceil((c1+c)/a), floor((c2+c)/a)) 00229 /*! In the case the new c1 > c2, return |- FALSE */ 00230 virtual Theorem grayShadowConst(const Theorem& g)=0; 00231 00232 //! a,b: INT; a < b ==> a <= b-1 [or a+1 <= b] 00233 /*! Takes a Theorem(\\alpha < \\beta) and returns 00234 * Theorem(\\alpha < \\beta <==> \\alpha <= \\beta -1) 00235 * or Theorem(\\alpha < \\beta <==> \\alpha + 1 <= \\beta), 00236 * depending on which side must be changed (changeRight flag) 00237 */ 00238 virtual Theorem lessThanToLE(const Theorem& less, 00239 const Theorem& isIntLHS, 00240 const Theorem& isIntRHS, 00241 bool changeRight)=0; 00242 00243 /*! \param eqn is an equation 0 = a.x or 0 = c + a.x, where x is integer 00244 * \param isIntx is a proof of IS_INTEGER(x) 00245 * 00246 * \return the theorem 0 = c + a.x <==> x=-c/a if -c/a is int else 00247 * return the theorem 0 = c + a.x <==> false. 00248 * 00249 * It also handles the special case of 0 = a.x <==> x = 0 00250 */ 00251 virtual Theorem intVarEqnConst(const Expr& eqn, 00252 const Theorem& isIntx) = 0; 00253 /*! @brief Equality elimination rule for integers: 00254 * \f[\frac{\mathsf{int}(a\cdot x)\quad 00255 * \mathsf{int}(C+\sum_{i=1}^{n}a_{i}\cdot x_{i})} 00256 * {a\cdot x=C+\sum_{i=1}^{n}a_{i}\cdot x_{i} 00257 * \quad\equiv\quad x=t_{2}\wedge 0=t_{3}} 00258 * \f] 00259 * See the detailed description for explanations. 00260 * 00261 * This rule implements a step in the iterative algorithm for 00262 * eliminating integer equality. The terms in the rule are 00263 * defined as follows: 00264 * 00265 * \f[\begin{array}{rcl} 00266 * t_{2} & = & 00267 * -(C\ \mathbf{mod}\ m+\sum_{i=1}^{n}(a_{i}\ \mathbf{mod}\ m) 00268 * \cdot x_{i}-m\cdot\sigma(t))\\ & & \\ 00269 * t_{3} & = & 00270 * \mathbf{f}(C,m)+\sum_{i=1}^{n}\mathbf{f}(a_{i},m)\cdot x_{i} 00271 * -a\cdot\sigma(t)\\ & & \\ 00272 * t & = & 00273 * (C\ \mathbf{mod}\ m+\sum_{i=1}^{n}(a_{i}\ \mathbf{mod}\ m) 00274 * \cdot x_{i}+x)/m\\ & & \\ 00275 * m & = & a+1\\ & & \\ 00276 * \mathbf{f}(i,m) & = & \left\lfloor \frac{i}{m} 00277 * +\frac{1}{2}\right\rfloor +i\ \mathbf{mod}\ m\\ & & \\ 00278 * i\ \mathbf{mod}\ m & = & i-m\left\lfloor\frac{i}{m} 00279 * +\frac{1}{2}\right\rfloor 00280 * \end{array} 00281 * \f] 00282 * 00283 * All the variables and coefficients are integer, and a >= 2. 00284 * 00285 * \param eqn is the equation 00286 * \f[a\cdot x = C + \sum_{i=1}^n a_i\cdot x_i.\f] 00287 * 00288 */ 00289 00290 /* 00291 virtual Theorem eqElimIntRule(const Expr& eqn, 00292 const Theorem& isIntLHS, 00293 const Theorem& isIntRHS) = 0; 00294 //! a <=> b ==> c AND a <=> c AND b. Takes "a <=> b" and "c". 00295 virtual Theorem cANDaIffcANDb(const Theorem& thm, 00296 const Expr& solvedEq) = 0; 00297 virtual Theorem substSolvedFormRule(const Expr& e1, 00298 ExprMap<Expr>& eMap) = 0; 00299 virtual Theorem aANDcIffbANDc(const Theorem& thm, const Expr& newEq) = 0; 00300 */ 00301 00302 /////////////////////////////////////////////////////////////////////// 00303 // Alternative implementation of integer equality elimination 00304 /////////////////////////////////////////////////////////////////////// 00305 00306 /*! @brief 00307 * \f[\frac{\Gamma\models ax=t\quad 00308 * \Gamma'\models\mathsf{int}(x)\quad 00309 * \{\Gamma_i\models\mathsf{int}(x_i) | x_i\mbox{ is var in }t\}} 00310 * {\Gamma,\Gamma',\bigcup_i\Gamma_i\models 00311 * \exists (y:\mathrm{int}).\ x=t_2(y)\wedge 0=t_3(y)} 00312 * \f] 00313 * See detailed docs for more information. 00314 * 00315 * This rule implements a step in the iterative algorithm for 00316 * eliminating integer equality. The terms in the rule are 00317 * defined as follows: 00318 * 00319 * \f[\begin{array}{rcl} 00320 * t & = & C+\sum_{i=1}^na_{i}\cdot x_{i}\\ 00321 * t_{2}(y) & = & 00322 * -(C\ \mathbf{mod}\ m+\sum_{i=1}^{n}(a_{i}\ \mathbf{mod}\ m) 00323 * \cdot x_{i}-m\cdot y)\\ & & \\ 00324 * t_{3}(y) & = & 00325 * \mathbf{f}(C,m)+\sum_{i=1}^{n}\mathbf{f}(a_{i},m)\cdot x_{i} 00326 * -a\cdot y\\ & & \\ 00327 * m & = & a+1\\ & & \\ 00328 * \mathbf{f}(i,m) & = & \left\lfloor \frac{i}{m} 00329 * +\frac{1}{2}\right\rfloor +i\ \mathbf{mod}\ m\\ & & \\ 00330 * i\ \mathbf{mod}\ m & = & i-m\left\lfloor\frac{i}{m} 00331 * +\frac{1}{2}\right\rfloor 00332 * \end{array} 00333 * \f] 00334 * 00335 * All the variables and coefficients are integer, and a >= 2. 00336 * 00337 * \param eqn is the equation ax=t: 00338 * \f[a\cdot x = C + \sum_{i=1}^n a_i\cdot x_i.\f] 00339 * 00340 * \param isIntx is a Theorem deriving the integrality of the 00341 * LHS variable: IS_INTEGER(x) 00342 * 00343 * \param isIntVars is a vector of Theorems deriving the 00344 * integrality of all variables on the RHS 00345 */ 00346 virtual Theorem eqElimIntRule(const Theorem& eqn, 00347 const Theorem& isIntx, 00348 const std::vector<Theorem>& isIntVars) = 0; 00349 00350 /*! 00351 * @brief return e <=> TRUE/FALSE for e == IS_INTEGER(c), where c 00352 * is a constant 00353 * 00354 * \param e is a predicate IS_INTEGER(c) where c is a rational constant 00355 */ 00356 virtual Theorem isIntConst(const Expr& e) = 0; 00357 00358 virtual Theorem equalLeaves1(const Theorem& thm) = 0; 00359 virtual Theorem equalLeaves2(const Theorem& thm) = 0; 00360 virtual Theorem equalLeaves3(const Theorem& thm) = 0; 00361 virtual Theorem equalLeaves4(const Theorem& thm) = 0; 00362 00363 //! x /= y ==> (x < y) OR (x > y) 00364 /*! Used in concrete model generation */ 00365 virtual Theorem diseqToIneq(const Theorem& diseq) = 0; 00366 00367 }; // end of class ArithProofRules 00368 } // end of namespace CVCL 00369 00370 #endif