00001 /*****************************************************************************/ 00002 /*! 00003 * \file bitvector_proof_rules.h 00004 * \brief Arithmetic proof rules 00005 * 00006 * Author: Vijay Ganesh. 00007 * 00008 * Created:Wed May 5 15:47:28 PST 2004 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__bitvector_proof_rules_h_ 00031 #define _CVC_lite__bitvector_proof_rules_h_ 00032 00033 #include <string> 00034 #include <vector> 00035 00036 namespace CVCL { 00037 00038 class Expr; 00039 class Theorem; 00040 00041 class BitvectorProofRules { 00042 public: 00043 // Destructor 00044 virtual ~BitvectorProofRules() { } 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Bitblasting rules for equations 00048 //////////////////////////////////////////////////////////////////// 00049 00050 /*! \param thm input theorem: (e1[i]<=>e2[i])<=>false 00051 * 00052 * \result (e1=e2)<=>false 00053 */ 00054 virtual Theorem bitvectorFalseRule(const Theorem& thm) = 0; 00055 00056 /*! \param thm input theorem: (~e1[i]<=>e2[i])<=>true 00057 * 00058 * \result (e1!=e2)<=>true 00059 */ 00060 virtual Theorem bitvectorTrueRule(const Theorem& thm) = 0; 00061 00062 00063 //! t1=t2 ==> AND_i(t1[i:i] = t2[i:i]) 00064 /*! 00065 * \param e is a Expr(t1=t2) 00066 * 00067 * \param f is the resulting expression AND_i(t1[i:i] = t2[i:i]) 00068 * is passed to the rule for efficiency. 00069 */ 00070 virtual Theorem bitBlastEqnRule(const Expr& e, const Expr& f) = 0; 00071 //! t1/=t2 ==> OR_i(NOT t1[i]<=>t2[i]) 00072 /*! 00073 * \param e is a Theorem(t1/=t2) 00074 * 00075 * \param f is the resulting expression OR_i(NOT t1[i]<=>t2[i]), 00076 * passed to the rule for efficiency. 00077 */ 00078 virtual Theorem bitBlastDisEqnRule(const Theorem& e, const Expr& f) = 0; 00079 00080 00081 //////////////////////////////////////////////////////////////////// 00082 // Bitblasting and rewrite rules for Inequations 00083 //////////////////////////////////////////////////////////////////// 00084 00085 //! sign extend the input SX(e) appropriately 00086 virtual Theorem signExtendRule(const Expr& e) = 0; 00087 00088 //! Pad the kids of BVLT/BVLE to make their length equal 00089 virtual Theorem padBVLTRule(const Expr& e, int len) = 0; 00090 00091 //! Sign Extend the kids of SBVLT/SBVLE to make their length equal 00092 virtual Theorem padSBVLTRule(const Expr& e, int len) = 0; 00093 00094 /*! input: e0 <=(s) e1. output depends on whether the topbits(MSB) of 00095 * e0 and e1 are constants. If they are constants then optimizations 00096 * are done, otherwise the following rule is implemented. 00097 * 00098 * e0 <=(s) e1 <==> (e0[n-1] AND NOT e1[n-1]) OR 00099 * (e0[n-1] AND e1[n-1] AND e1[n-2:0] <= e0[n-2:0]) OR 00100 * (NOT e0[n-1] AND NOT e1[n-1] AND e0[n-2:0] <= e1[n-2:0]) 00101 */ 00102 virtual Theorem signBVLTRule(const Expr& e, 00103 const Theorem& topBit0, 00104 const Theorem& topBit1) = 0; 00105 00106 /*! NOT(e[0][0] < e[0][1]) <==> (e[0][1] <= e[0][0]), 00107 * NOT(e[0][0] <= e[0][1]) <==> (e[0][1] < e[0][0]) 00108 */ 00109 virtual Theorem notBVLTRule(const Expr& e, int Kind) = 0; 00110 00111 //! if(lhs==rhs) then we have (lhs < rhs <==> false),(lhs <= rhs <==> true) 00112 virtual Theorem lhsEqRhsIneqn(const Expr& e, int kind) = 0; 00113 00114 00115 virtual Theorem bvConstIneqn(const Expr& e, int kind) = 0; 00116 00117 virtual Theorem generalIneqn(const Expr& e, 00118 const Theorem& e0, 00119 const Theorem& e1, int kind) = 0; 00120 00121 00122 //////////////////////////////////////////////////////////////////// 00123 // Bitblast rules for terms 00124 //////////////////////////////////////////////////////////////////// 00125 00126 //! t[i] ==> t[i:i] = 0bin1 or NOT t[i] ==> t[i:i] = 0bin0 00127 /*! \param thm is a Theorem(t[i]) or Theorem(NOT t[i]), where t[i] 00128 * is BOOLEXTRACT(t, i). 00129 */ 00130 virtual Theorem bitExtractToExtract(const Theorem& thm) = 0; 00131 00132 //! t[i] <=> t[i:i][0] (to use rewriter for simplifying t[i:i]) 00133 virtual Theorem bitExtractRewrite(const Expr& x) = 0; 00134 00135 /*! \param x is bitvector constant 00136 * \param i is extracted bitposition 00137 * 00138 * \result \f[ \frac{}{\mathrm{BOOLEXTRACT(x,i)} \iff 00139 * \mathrm{TRUE}} \f], if bitposition has a 1; \f[ 00140 * \frac{}{\mathrm{BOOLEXTRACT(x,i)} \iff \mathrm{FALSE}} \f], if 00141 * the bitposition has a 0 00142 */ 00143 virtual Theorem bitExtractConstant(const Expr & x, int i)= 0; 00144 00145 /*! \param x is bitvector binary concatenation 00146 * \param i is extracted bitposition 00147 * 00148 * \result \f[ \frac{}{(t_{[m]}@q_{[n]})[i] \iff (q_{[n]})[i]} 00149 * \f], where \f[ 0 \geq i \geq n-1 \f], another case of 00150 * boolextract over concatenation is: 00151 * \f[\frac{}{(t_{[m]}@q_{[n]})[i] \iff (t_{[m]})[i-n]} \f], 00152 * where \f[ n \geq i \geq m+n-1 \f] 00153 */ 00154 virtual Theorem bitExtractConcatenation(const Expr & x, 00155 int i)= 0; 00156 00157 /*! \param t is bitvector binary BVMULT. x[0] must be BVCONST 00158 * \param i is extracted bitposition 00159 * 00160 * \result bitblast of BVMULT 00161 */ 00162 virtual Theorem bitExtractConstBVMult(const Expr& t, int i)= 0; 00163 00164 /*! \param t : input1 is bitvector binary BVMULT. t[0] must not be BVCONST 00165 * \param i : input2 is extracted bitposition 00166 * 00167 * \result bitblast of BVMULT 00168 */ 00169 virtual Theorem bitExtractBVMult(const Expr& t, int i) = 0; 00170 00171 /*! \param x is bitvector extraction e[k:j] 00172 * \param i is extracted bitposition 00173 * 00174 * \result \f[ \frac{}{(t_{[n]}[k:j])[i] \iff (t_{[n]})[i+j]} 00175 * \f], where \f[ 0 \geq j \geq k < n, 0 \geq i < k-j \f] 00176 */ 00177 virtual Theorem bitExtractExtraction(const Expr & x, int i)= 0; 00178 00179 /*! \param t1 is vector of bitblasts of t, from bit i-1 to 0 00180 * \param t2 is vector of bitblasts of q, from bit i-1 to 0 00181 * \param bvPlusTerm is BVPLUS term: BVPLUS(n,t,q) 00182 * \param i is extracted bitposition 00183 * 00184 * \result The base case is: \f[ 00185 * \frac{}{(\mathrm{BVPLUS}(n,t,q))[0] \iff t[0] \oplus q[0]} 00186 * \f], when \f[ 0 < i \leq n-1 \f], we have \f[ 00187 * \frac{}{(\mathrm{BVPLUS}(n,t,q))[i] \iff t[i] \oplus q[i] 00188 * \oplus c(t,q,i)} \f], where c(t,q,i) is the carry generated 00189 * by the addition of bits from 0 to i-1 00190 */ 00191 virtual Theorem bitExtractBVPlus(const std::vector<Theorem>& t1, 00192 const std::vector<Theorem>& t2, 00193 const Expr& bvPlusTerm, int i) = 0; 00194 00195 00196 virtual Theorem bitExtractBVPlusPreComputed(const Theorem& t1_i, 00197 const Theorem& t2_i, 00198 const Expr& bvPlusTerm, 00199 int bitPos, 00200 int precomputed) = 0; 00201 00202 00203 /*! \param bvPlusTerm : input1 is bvPlusTerm, a BVPLUS term with 00204 * arity > 2 00205 * 00206 * \result : output is iff-Theorem: bvPlusTerm <==> outputTerm, 00207 * where outputTerm is an equivalent BINARY bvplus. 00208 */ 00209 virtual Theorem bvPlusAssociativityRule(const Expr& bvPlusTerm)= 0; 00210 00211 /*! \param x : input1 is bitwise NEGATION 00212 * \param i : input2 is extracted bitposition 00213 * 00214 * \result \f[ \frac{}{(\sim t_{[n]})[i] \iff \neg (t_{[n]}[i])} 00215 * \f] 00216 */ 00217 virtual Theorem bitExtractNot(const Expr & x, int i)= 0; 00218 00219 /*! \param x : input1 is bitwise AND 00220 * \param i : input2 is extracted bitposition 00221 * 00222 * \result \f[ \frac{}{(t_{[n]} \& q_{[n]})[i] \iff (t_{[n]}[i] 00223 * \wedge q_{[n]}[i])} \f] 00224 */ 00225 virtual Theorem bitExtractAnd(const Expr & x, int i)= 0; 00226 00227 /*! \param x : input1 is bitwise OR 00228 * \param i : input2 is extracted bitposition 00229 * 00230 * \result \f[ \frac{}{(t_{[n]} \mid q_{[n]})[i] \iff (t_{[n]}[i] 00231 * \vee q_{[n]}[i])} \f] 00232 */ 00233 virtual Theorem bitExtractOr(const Expr & x, int i)= 0; 00234 00235 /*! \param x : input1 is bitvector FIXED SHIFT \f[ e_{[n]} \ll k \f] 00236 * \param i : input2 is extracted bitposition 00237 * 00238 * \result \f[\frac{}{(e_{[n]} \ll k)[i] \iff \mathrm{FALSE}} 00239 * \f], if 0 <= i < k. however, if k <= i < n then, result is 00240 * \f[\frac{}{(e_{[n]} \ll k)[i] \iff e_{[n]}[i]} \f] 00241 */ 00242 virtual Theorem bitExtractFixedLeftShift(const Expr & x, 00243 int i)= 0; 00244 00245 virtual Theorem bitExtractFixedRightShift(const Expr & x, 00246 int i)= 0; 00247 00248 /*! \param e : input1 is bitvector term 00249 * \param r : input2 is extracted bitposition 00250 * 00251 * \result we check if r > bvlength(e). if yes, then return 00252 * BOOLEXTRACT(e,r) <==> FALSE; else raise soundness 00253 * exception. (Note: this rule is used in BVPLUS bitblast 00254 * function) 00255 */ 00256 virtual Theorem zeroPaddingRule(const Expr& e, int r)= 0; 00257 00258 00259 virtual Theorem bitExtractSXRule(const Expr& e, int i) = 0; 00260 00261 /////////////////////////////////////////////////////////////////// 00262 ///// Special case rewrite rules 00263 /////////////////////////////////////////////////////////////////// 00264 00265 //! c1=c2 <=> TRUE/FALSE (equality of constant bitvectors) 00266 virtual Theorem eqConst(const Expr& e) = 0; 00267 //! |- c1=c2 ==> |- AND(c1[i:i] = c2[i:i]) - expanding equalities into bits 00268 virtual Theorem eqToBits(const Theorem& eq) = 0; 00269 //! t<<n = c @ 0bin00...00, takes e == (t<<n) 00270 virtual Theorem leftShiftToConcat(const Expr& e) = 0; 00271 //! t>>m = 0bin00...00 @ t[bvlength-1:m], takes e == (t>>n) 00272 virtual Theorem rightShiftToConcat(const Expr& e) = 0; 00273 //! k*t = BVPLUS(n, <sum of shifts of t>) -- translation of k*t to BVPLUS 00274 /*! If k = 2^m, return k*t = t\@0...0 */ 00275 virtual Theorem constMultToPlus(const Expr& e) = 0; 00276 //! 0bin0...0 @ BVPLUS(n, args) = BVPLUS(n+k, args) 00277 /*! provided that m+ceil(log2(l)) <= n, where k is the size of the 00278 * 0bin0...0, m is the max. length of each argument, and l is the 00279 * number of arguments. 00280 */ 00281 virtual Theorem bvplusZeroConcatRule(const Expr& e) = 0; 00282 00283 00284 /////////////////////////////////////////////////////////////////// 00285 ///// Bvplus Normal Form rules 00286 /////////////////////////////////////////////////////////////////// 00287 virtual Theorem zeroCoeffBVMult(const Expr& e)=0; 00288 virtual Theorem oneCoeffBVMult(const Expr& e)=0; 00289 virtual Theorem flipBVMult(const Expr& e) = 0; 00290 //! Make args the same length as the result (zero-extend) 00291 virtual Theorem padBVPlus(const Expr& e) = 0; 00292 //! Make args the same length as the result (zero-extend) 00293 virtual Theorem padBVMult(const Expr& e) = 0; 00294 virtual Theorem bvConstMultAssocRule(const Expr& e) = 0; 00295 virtual Theorem bvMultAssocRule(const Expr& e) = 0; 00296 virtual Theorem bvMultDistRule(const Expr& e) = 0; 00297 virtual Theorem flattenBVPlus(const Expr& e) = 0; 00298 virtual Theorem combineLikeTermsRule(const Expr& e) = 0; 00299 virtual Theorem lhsMinusRhsRule(const Expr& e) = 0; 00300 //! (x *[n] y)[m:k] = (x *[m+1] y)[m:k], where m < n 00301 virtual Theorem extractBVMult(const Expr& e) = 0; 00302 //! (x +[n] y)[m:k] = (x +[m+1] y)[m:k], where m < n 00303 virtual Theorem extractBVPlus(const Expr& e) = 0; 00304 //! ite(c,t1,t2)[i:j] <=> ite(c,t1[i:j],t2[i:j]) 00305 virtual Theorem iteExtractRule(const Expr& e) = 0; 00306 //! ~ite(c,t1,t2) <=> ite(c,~t1,~t2) 00307 virtual Theorem iteBVnegRule(const Expr& e) = 0; 00308 00309 virtual Theorem bvuminusBVConst(const Expr& e) = 0; 00310 virtual Theorem bvuminusBVMult(const Expr& e) = 0; 00311 virtual Theorem bvuminusBVUminus(const Expr& e) = 0; 00312 virtual Theorem bvuminusVar(const Expr& e) = 0; 00313 virtual Theorem bvmultBVUminus(const Expr& e) = 0; 00314 //! -t <==> ~t+1 00315 virtual Theorem bvuminusToBVPlus(const Expr& e) = 0; 00316 //! -(c1*t1+...+cn*tn) <==> (-(c1*t1)+...+-(cn*tn)) 00317 virtual Theorem bvuminusBVPlus(const Expr& e) = 0; 00318 00319 00320 00321 /////////////////////////////////////////////////////////////////// 00322 ///// Concatenation Normal Form rules 00323 /////////////////////////////////////////////////////////////////// 00324 00325 // Extraction rules 00326 00327 //! c1[i:j] = c (extraction from a constant bitvector) 00328 virtual Theorem extractConst(const Expr& e) = 0; 00329 //! t[n-1:0] = t for n-bit t 00330 virtual Theorem extractWhole(const Expr& e) = 0; 00331 //! t[i:j][k:l] = t[k+j:l+j] (eliminate double extraction) 00332 virtual Theorem extractExtract(const Expr& e) = 0; 00333 //! (t1 @ t2)[i:j] = t1[...] @ t2[...] (push extraction through concat) 00334 virtual Theorem extractConcat(const Expr& e) = 0; 00335 //! (t1 & t2)[i:j] = t1[i:j] & t2[i:j] (push extraction through OR) 00336 virtual Theorem extractAnd(const Expr& e) = 0; 00337 //! (t1 | t2)[i:j] = t1[i:j] | t2[i:j] (push extraction through AND) 00338 virtual Theorem extractOr(const Expr& e) = 0; 00339 //! (~t)[i:j] = ~(t[i:j]) (push extraction through NEG) 00340 virtual Theorem extractNeg(const Expr& e) = 0; 00341 //! Auxiliary function: (t1 op t2)[i:j] = t1[i:j] op t2[i:j] 00342 virtual Theorem extractBitwise(const Expr& e, 00343 int kind, const std::string& name) = 0; 00344 00345 // Negation rules 00346 00347 //! ~c1 = c (bit-wise negation of a constant bitvector) 00348 virtual Theorem negConst(const Expr& e) = 0; 00349 //! ~(t1\@...\@tn) = (~t1)\@...\@(~tn) -- push negation through concat 00350 virtual Theorem negConcat(const Expr& e) = 0; 00351 //! ~(~t) = t -- eliminate double negation 00352 virtual Theorem negNeg(const Expr& e) = 0; 00353 //! ~(t1 & t2) <=> ~t1 | ~t2 -- DeMorgan's Laws 00354 virtual Theorem negBVand(const Expr& e) = 0; 00355 //! ~(t1 | t2) <=> ~t1 & ~t2 -- DeMorgan's Laws 00356 virtual Theorem negBVor(const Expr& e) = 0; 00357 00358 // Bit-wise AND rules 00359 //! c1&c2&t = c&t -- compute bit-wise AND of constant bitvector arguments 00360 /*!\param e is the bit-wise AND expression; 00361 * 00362 * \param idxs are the indices of the constant bitvectors. There 00363 * must be at least constant expressions in this rule. 00364 * 00365 * \return Theorem(e==e'), where e' is either a constant 00366 * bitvector, or is a bit-wise AND with a single constant 00367 * bitvector in e'[0]. 00368 */ 00369 virtual Theorem andConst(const Expr& e, const std::vector<int>& idxs) = 0; 00370 //! 0bin0...0 & t = 0bin0...0 -- bit-wise AND with zero bitvector 00371 /*! \param e is the bit-wise AND expr 00372 * \param idx is the index of the zero bitvector 00373 */ 00374 virtual Theorem andZero(const Expr& e, int idx) = 0; 00375 //! 0bin1...1 & t = t -- bit-wise AND with bitvector of 1's 00376 /*! \param e is the bit-wise AND expr 00377 * \param idxs is a vector of indices of the bitvectors of 1's 00378 * which will be dropped 00379 */ 00380 virtual Theorem andOne(const Expr& e, const std::vector<int> idxs) = 0; 00381 //! ... & (t1\@...\@tk) & ... = (...& t1 &...)\@...\@(...& tk &...) 00382 /*! 00383 * Lifts concatenation to the top of bit-wise AND. Takes the 00384 * bit-wise AND expression 'e' and the index 'i' of the 00385 * concatenation. 00386 */ 00387 virtual Theorem andConcat(const Expr& e, int idx) = 0; 00388 //! (t1 & (t2 & t3) & t4) = t1 & t2 & t3 & t4 -- flatten bit-wise AND 00389 /*! Also reorders the terms according to a fixed total ordering */ 00390 virtual Theorem andFlatten(const Expr& e) = 0; 00391 00392 // Bit-wise OR rules 00393 00394 //! c1|c2|t = c|t -- compute bit-wise OR of constant bitvector arguments 00395 /*!\param e is the bit-wise OR expression; 00396 * 00397 * \param idxs are the indices of the constant bitvectors. There 00398 * must be at least constant expressions in this rule. 00399 * 00400 * \return Theorem(e==e'), where e' is either a constant 00401 * bitvector, or is a bit-wise OR with a single constant 00402 * bitvector in e'[0]. 00403 */ 00404 virtual Theorem orConst(const Expr& e, const std::vector<int>& idxs) = 0; 00405 //! 0bin1...1 | t = 0bin1...1 -- bit-wise OR with bitvector of 1's 00406 /*! \param e is the bit-wise OR expr 00407 * \param idx is the index of the bitvector of 1's 00408 */ 00409 virtual Theorem orOne(const Expr& e, int idx) = 0; 00410 //! 0bin0...0 | t = t -- bit-wise OR with bitvector of 0's 00411 /*! \param e is the bit-wise OR expr 00412 * \param idxs is a vector of indices of the bitvectors of 0's 00413 * which will be dropped 00414 */ 00415 virtual Theorem orZero(const Expr& e, const std::vector<int> idxs) = 0; 00416 //! ... | (t1\@...\@tk) | ... = (...| t1 |...)\@...\@(...| tk |...) 00417 /*! 00418 * Lifts concatenation to the top of bit-wise OR. Takes the 00419 * bit-wise OR expression 'e' and the index 'i' of the 00420 * concatenation. 00421 */ 00422 virtual Theorem orConcat(const Expr& e, int idx) = 0; 00423 //! (t1 | (t2 | t3) | t4) = t1 | t2 | t3 | t4 -- flatten bit-wise OR 00424 /*! Also reorders the terms according to a fixed total ordering */ 00425 virtual Theorem orFlatten(const Expr& e) = 0; 00426 00427 // Concatenation rules 00428 00429 //! c1\@c2\@...\@cn = c (concatenation of constant bitvectors) 00430 virtual Theorem concatConst(const Expr& e) = 0; 00431 //! Flatten one level of nested concatenation, e.g.: x\@(y\@z)\@w = x\@y\@z\@w 00432 virtual Theorem concatFlatten(const Expr& e) = 0; 00433 //! Merge n-ary concat. of adjacent extractions: x[15:8]\@x[7:0] = x[15:0] 00434 virtual Theorem concatMergeExtract(const Expr& e) = 0; 00435 00436 /////////////////////////////////////////////////////////////////// 00437 ///// Modulo arithmetic rules 00438 /////////////////////////////////////////////////////////////////// 00439 00440 //! BVPLUS(n, c1,c2,...,cn) = c (bit-vector plus of constant bitvectors) 00441 virtual Theorem bvplusConst(const Expr& e) = 0; 00442 /*! @brief n*c1 = c, where n >= 0 (multiplication of a constant 00443 * bitvector by a non-negative constant) */ 00444 virtual Theorem bvmultConst(const Expr& e) = 0; 00445 00446 /////////////////////////////////////////////////////////////////// 00447 ///// Type predicate rules 00448 /////////////////////////////////////////////////////////////////// 00449 00450 //! |- t=0 OR t=1 for any 1-bit bitvector t 00451 virtual Theorem typePredBit(const Expr& e) = 0; 00452 //! Expand the type predicate wrapper (compute the actual type predicate) 00453 virtual Theorem expandTypePred(const Theorem& tp) = 0; 00454 00455 00456 }; // end of class BitvectorProofRules 00457 } // end of namespace CVCL 00458 00459 #endif