CVC3
|
00001 /*****************************************************************************/ 00002 /*! 00003 * \file theory_bitvector.cpp 00004 * 00005 * Author: Vijay Ganesh. 00006 * 00007 * Created: Wed May 5 16:16:59 PST 2004 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 00022 #include "theory_bitvector.h" 00023 #include "bitvector_proof_rules.h" 00024 #include "bitvector_exception.h" 00025 #include "typecheck_exception.h" 00026 #include "parser_exception.h" 00027 #include "smtlib_exception.h" 00028 #include "bitvector_expr_value.h" 00029 #include "command_line_flags.h" 00030 00031 00032 #define HASH_VALUE_ZERO 380 00033 #define HASH_VALUE_ONE 450 00034 00035 00036 using namespace std; 00037 using namespace CVC3; 00038 00039 00040 /////////////////////////////////////////////////////////////////////////////// 00041 // TheoryBitvector Private Methods // 00042 /////////////////////////////////////////////////////////////////////////////// 00043 00044 00045 int TheoryBitvector::BVSize(const Expr& e) 00046 { 00047 Type tp(getBaseType(e)); 00048 DebugAssert(tp.getExpr().getOpKind() == BITVECTOR, 00049 "BVSize: e = "+e.toString()); 00050 return getBitvectorTypeParam(tp); 00051 } 00052 00053 00054 //! Converts e into a BITVECTOR of length 'len' 00055 /*! 00056 * \param len is the desired length of the resulting bitvector 00057 * \param e is the original bitvector of arbitrary length 00058 */ 00059 Expr TheoryBitvector::pad(int len, const Expr& e) 00060 { 00061 DebugAssert(len >=0, 00062 "TheoryBitvector::newBVPlusExpr:" 00063 "padding length must be a non-negative integer: "+ 00064 int2string(len)); 00065 DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(), 00066 "TheoryBitvector::newBVPlusExpr:" 00067 "input must be a BITVECTOR: " + e.toString()); 00068 00069 int size = BVSize(e); 00070 Expr res; 00071 if(size == len) 00072 res = e; 00073 else if (len < size) 00074 res = newBVExtractExpr(e,len-1,0); 00075 else { 00076 // size < len 00077 Expr zero = newBVZeroString(len-size); 00078 res = newConcatExpr(zero,e); 00079 } 00080 return res; 00081 } 00082 00083 00084 // Bit-blasting methods 00085 00086 00087 //! accepts a bitvector equation t1 = t2. 00088 /*! \return a rewrite theorem which is a conjunction of equivalences 00089 * over the bits of t1,t2 respectively. 00090 */ 00091 Theorem TheoryBitvector::bitBlastEqn(const Expr& e) 00092 { 00093 TRACE("bitvector", "bitBlastEqn(", e.toString(), ") {"); 00094 d_bvBitBlastEq++; 00095 00096 DebugAssert(e.isEq(), 00097 "TheoryBitvector::bitBlastEqn:" 00098 "expecting an equation" + e.toString()); 00099 const Expr& leftBV = e[0]; 00100 const Expr& rightBV = e[1]; 00101 IF_DEBUG(const Type& leftType = getBaseType(leftBV);) 00102 IF_DEBUG(const Type& rightType = getBaseType(rightBV);) 00103 DebugAssert(BITVECTOR == leftType.getExpr().getOpKind() && 00104 BITVECTOR == rightType.getExpr().getOpKind(), 00105 "TheoryBitvector::bitBlastEqn:" 00106 "lhs & rhs must be bitvectors"); 00107 DebugAssert(BVSize(leftBV) == BVSize(rightBV), 00108 "TheoryBitvector::bitBlastEqn:\n e = " 00109 +e.toString()); 00110 00111 Theorem result = reflexivityRule(e); 00112 Theorem bitBlastLeftThm; 00113 Theorem bitBlastRightThm; 00114 std::vector<Theorem> substThms; 00115 std::vector<Theorem> leftBVrightBVThms; 00116 int bvLength = BVSize(leftBV); 00117 int bitPosition = 0; 00118 Theorem thm0; 00119 00120 for(; bitPosition < bvLength; ++bitPosition) { 00121 //bitBlastLeftThm is the theorem 'leftBV[bitPosition] <==> phi' 00122 bitBlastLeftThm = bitBlastTerm(leftBV, bitPosition); 00123 //bitBlastRightThm is the theorem 'rightBV[bitPosition] <==> theta' 00124 bitBlastRightThm = bitBlastTerm(rightBV, bitPosition); 00125 //collect the two theorems created above in the vector 00126 //leftBVrightBVthms. 00127 leftBVrightBVThms.push_back(bitBlastLeftThm); 00128 leftBVrightBVThms.push_back(bitBlastRightThm); 00129 //construct (leftBV[bitPosition] <==> rightBV[bitPosition]) 00130 //<====> phi <==> theta 00131 //and store in the vector substThms. 00132 Theorem thm = substitutivityRule(IFF, leftBVrightBVThms); 00133 thm = transitivityRule(thm, rewriteBoolean(thm.getRHS())); 00134 leftBVrightBVThms.clear(); 00135 substThms.push_back(thm); 00136 //if phi <==> theta is false, then stop bitblasting. immediately 00137 //exit and return false. 00138 if(thm.getRHS().isFalse()) 00139 return transitivityRule(result, 00140 d_rules->bitvectorFalseRule(thm)); 00141 } 00142 // AND_0^bvLength(leftBV[bitPosition] <==> rightBV[bitPosition]) <====> 00143 // AND_0^bvLength(phi <==> theta) 00144 Theorem thm = substitutivityRule(AND, substThms); 00145 // AND_0^bvLength(leftBV[bitPosition] <==> rightBV[bitPosition]) <====> 00146 // rewriteBoolean(AND_0^bvLength(phi <==> theta)) 00147 thm = transitivityRule(thm, rewriteBoolean(thm.getRHS())); 00148 //call trusted rule for bitblasting equations. 00149 result = d_rules->bitBlastEqnRule(e, thm.getLHS()); 00150 result = transitivityRule(result, thm); 00151 TRACE("bitvector", "bitBlastEqn => ", result.toString(), " }"); 00152 return result; 00153 } 00154 00155 00156 //! accepts a bitvector equation t1 != t2. 00157 /*! \return a rewrite theorem which is a conjunction of 00158 * (dis)-equivalences over the bits of t1,t2 respectively. 00159 * 00160 * A separate rule for disequations for efficiency sake. Obvious 00161 * implementation using rule for equations and rule for NOT, is not 00162 * efficient. 00163 */ 00164 Theorem TheoryBitvector::bitBlastDisEqn(const Theorem& notE) 00165 { 00166 TRACE("bitvector", "bitBlastDisEqn(", notE, ") {"); 00167 IF_DEBUG(debugger.counter("bit-blasted diseq")++); 00168 //stat counter 00169 d_bvBitBlastDiseq++; 00170 00171 DebugAssert(notE.getExpr().isNot() && (notE.getExpr())[0].isEq(), 00172 "TheoryBitvector::bitBlastDisEqn:" 00173 "expecting an equation" + notE.getExpr().toString()); 00174 //e is the equation 00175 const Expr& e = (notE.getExpr())[0]; 00176 const Expr& leftBV = e[0]; 00177 const Expr& rightBV = e[1]; 00178 IF_DEBUG(Type leftType = leftBV.getType()); 00179 IF_DEBUG(debugger.counter("bit-blasted diseq bits")+= 00180 BVSize(leftBV)); 00181 IF_DEBUG(Type rightType = rightBV.getType()); 00182 DebugAssert(BITVECTOR == leftType.getExpr().getOpKind() && 00183 BITVECTOR == rightType.getExpr().getOpKind(), 00184 "TheoryBitvector::bitBlastDisEqn:" 00185 "lhs & rhs must be bitvectors"); 00186 DebugAssert(BVSize(leftBV) == BVSize(rightBV), 00187 "TheoryBitvector::bitBlastDisEqn: e = " 00188 +e.toString()); 00189 Theorem bitBlastLeftThm; 00190 Theorem bitBlastRightThm; 00191 std::vector<Theorem> substThms; 00192 std::vector<Theorem> leftBVrightBVThms; 00193 int bvLength = BVSize(leftBV); 00194 int bitPosition = 0; 00195 for(; bitPosition < bvLength; bitPosition = bitPosition+1) { 00196 //bitBlastLeftThm is the theorem '~leftBV[bitPosition] <==> ~phi' 00197 bitBlastLeftThm = 00198 getCommonRules()->iffContrapositive(bitBlastTerm(leftBV, bitPosition)); 00199 //bitBlastRightThm is the theorem 'rightBV[bitPosition] <==> theta' 00200 bitBlastRightThm = bitBlastTerm(rightBV, bitPosition); 00201 //collect the two theorems created above in the vector leftBVrightBVthms. 00202 leftBVrightBVThms.push_back(bitBlastLeftThm); 00203 leftBVrightBVThms.push_back(bitBlastRightThm); 00204 //construct (~leftBV[bitPosition] <==> rightBV[bitPosition]) 00205 //<====> ~phi <==> theta 00206 //and store in the vector substThms. 00207 //recall that (p <=/=> q) is same as (~p <==> q) 00208 Theorem thm = substitutivityRule(IFF, leftBVrightBVThms); 00209 thm = transitivityRule(thm, rewriteBoolean(thm.getRHS())); 00210 leftBVrightBVThms.clear(); 00211 substThms.push_back(thm); 00212 00213 //if phi <==> theta is the True theorem, then stop bitblasting. immediately 00214 //exit and return t1!=t2 <=> true. 00215 if(thm.getRHS().isTrue()) 00216 return d_rules->bitvectorTrueRule(thm); 00217 } 00218 00219 // OR_0^bvLength(~leftBV[bitPosition] <==> rightBV[bitPosition]) <====> 00220 // OR_0^bvLength(~phi <==> theta) 00221 Theorem thm1 = substitutivityRule(OR, substThms); 00222 // Call trusted rule for bitblasting disequations. 00223 Theorem result = d_rules->bitBlastDisEqnRule(notE, thm1.getLHS()); 00224 Theorem thm2 = transitivityRule(thm1, rewriteBoolean(thm1.getRHS())); 00225 result = iffMP(result, thm2); 00226 TRACE("bitvector", "bitBlastDisEqn => ", result.toString(), " }"); 00227 return result; 00228 } 00229 00230 00231 /*! \param e has the form e1 pred e2, where pred is < or <=. 00232 * 00233 * if e1,e2 are constants, determine bv2int(e1) pred bv2int(e2). 00234 * 00235 * most significant bit of ei is denoted by msb(ei) 00236 * 00237 * \return \f$(msb(e1)\ pred\ msb(e2)) \vee 00238 * (msb(e1)=msb(e2) \wedge e1[n-2:0]\ pred\ e2[n-2:0])\f$ 00239 */ 00240 Theorem TheoryBitvector::bitBlastIneqn(const Expr& e) 00241 { 00242 TRACE("bitvector", "bitBlastIneqn(", e.toString(), ") {"); 00243 00244 DebugAssert(BVLT == e.getOpKind() || 00245 BVLE == e.getOpKind(), 00246 "TheoryBitvector::bitBlastIneqn: " 00247 "input e must be BVLT/BVLE: e = " + e.toString()); 00248 DebugAssert(e.arity() == 2, 00249 "TheoryBitvector::bitBlastIneqn: " 00250 "arity of e must be 2: e = " + e.toString()); 00251 Expr lhs = e[0]; 00252 Expr rhs = e[1]; 00253 int e0len = BVSize(lhs); 00254 DebugAssert(e0len == BVSize(rhs), "Expected sizes to match"); 00255 00256 int kind = e.getOpKind(); 00257 Theorem res; 00258 if(lhs == rhs) { 00259 res = d_rules->lhsEqRhsIneqn(e, kind); 00260 } 00261 else if (lhs.getKind() == BVCONST && rhs.getKind() == BVCONST) { 00262 res = d_rules->bvConstIneqn(e, kind); 00263 } else { 00264 Theorem lhs_i = bitBlastTerm(lhs, e0len-1); 00265 Theorem rhs_i = bitBlastTerm(rhs, e0len-1); 00266 res = d_rules->generalIneqn(e, lhs_i, rhs_i, kind); 00267 00268 //check if output is TRUE or FALSE theorem, and then simply return 00269 Theorem output = rewriteBoolean(res.getRHS()); 00270 if (output.getRHS().isBoolConst()) { 00271 res = transitivityRule(res, output); 00272 } 00273 else if (e0len > 1) { 00274 // Copy by value, since 'res' will be changing 00275 Expr resRHS = res.getRHS(); 00276 // resRHS is of the form (\alpha or (\beta and \gamma)) 00277 // where \gamma is an inequality 00278 DebugAssert(resRHS.getKind() == OR && resRHS.arity() == 2 && 00279 resRHS[1].getKind() == AND && resRHS[1].arity() == 2, 00280 "Unexpected structure"); 00281 00282 vector<unsigned> changed; 00283 vector<Theorem> thms; 00284 00285 // \gamma <=> \gamma' 00286 Theorem thm = bitBlastIneqn(resRHS[1][1]); 00287 00288 // (\beta and \gamma) <=> (\beta and \gamma') 00289 changed.push_back(1); 00290 thms.push_back(thm); 00291 thm = substitutivityRule(resRHS[1], changed, thms); 00292 00293 // (\alpha or (\beta and \gamma)) <=> (\alpha or (\beta and \gamma')) 00294 // 'changed' is the same, only update thms[0] 00295 thms[0] = thm; 00296 thm = substitutivityRule(resRHS, changed, thms); 00297 res = transitivityRule(res, thm); 00298 /* 00299 00300 //resRHS can be of the form (\beta and \gamma) or 00301 //resRHS can be of the form (\alpha or \gamma) or 00302 //resRHS can be of the form (\gamma) 00303 // Our mission is to bitblast \gamma and insert it back to the formula 00304 switch(resRHS.getOpKind()) { 00305 case OR: 00306 if(resRHS[1].isAnd()) { // (\alpha or (\beta and \gamma)) 00307 break; 00308 } 00309 // (\alpha or \gamma) - fall through (same as the AND case) 00310 case AND: { // (\beta and \gamma) 00311 changed.push_back(1); 00312 gamma = resRHS[1]; 00313 // \gamma <=> \gamma' 00314 gammaThm = rewriteBV(gamma,2); 00315 //\gamma' <=> \gamma" 00316 Theorem thm3 = bitBlastIneqn(gammaThm.getRHS()); 00317 //Theorem thm3 = bitBlastIneqn(gamma); 00318 //\gamma <=> \gamma' <=> \gamma" 00319 thm3 = transitivityRule(gammaThm, thm3); 00320 thms.push_back(thm3); 00321 // (\beta and \gamma) <=> (\beta and \gamma") 00322 thm3 = substitutivityRule(resRHS,changed,thms); 00323 res = transitivityRule(res, thm3); 00324 break; 00325 } 00326 default: // (\gamma) 00327 IF_DEBUG(gamma = resRHS;) 00328 // \gamma <=> \gamma' 00329 gammaThm = rewriteBV(resRHS,2); 00330 //\gamma' <=> \gamma" 00331 Theorem thm3 = bitBlastIneqn(gammaThm.getRHS()); 00332 //Theorem thm3 = bitBlastIneqn(gamma); 00333 //\gamma <=> \gamma' <=> \gamma" 00334 thm3 = transitivityRule(gammaThm, thm3); 00335 res = transitivityRule(res, thm3); 00336 break; 00337 } 00338 00339 DebugAssert(kind == gamma.getOpKind(), 00340 "TheoryBitvector::bitBlastIneqn: " 00341 "gamma must be a BVLT/BVLE. gamma = " + 00342 gamma.toString()); 00343 */ 00344 } 00345 } 00346 TRACE("bitvector", "bitBlastIneqn => ", res.toString(), " }"); 00347 return res; 00348 } 00349 00350 00351 /*! The invariant maintained by this function is: accepts a bitvector 00352 * term, t,and a bitPosition, i. returns a formula over the set of 00353 * propositional variables defined using BOOLEXTRACT of bitvector 00354 * variables in t at the position i. 00355 * 00356 * \return Theorem(BOOLEXTRACT(t, bitPosition) <=> phi), where phi is 00357 * a Boolean formula over the individual bits of bit-vector variables. 00358 */ 00359 Theorem TheoryBitvector::bitBlastTerm(const Expr& t, int bitPosition) 00360 { 00361 TRACE("bitvector", "bitBlastTerm(", t, ", " + int2string(bitPosition) + ") {"); 00362 00363 IF_DEBUG(Type type = t.getType();) 00364 DebugAssert(BITVECTOR == type.getExpr().getOpKind(), "TheoryBitvector::bitBlastTerm: The type of input to bitBlastTerm must be BITVECTOR.\n t = " +t.toString()); 00365 DebugAssert(bitPosition >= 0, "TheoryBitvector::bitBlastTerm: illegal bitExtraction attempted.\n bitPosition = " + int2string(bitPosition)); 00366 00367 Theorem result; 00368 00369 // Check the cache 00370 Expr t_i = newBoolExtractExpr(t, bitPosition); 00371 CDMap<Expr,Theorem>::iterator it = d_bitvecCache.find(t_i); 00372 if (it != d_bitvecCache.end()) { 00373 result = (*it).second; 00374 TRACE("bitvector", "bitBlastTerm[cached] => ", result, " }"); 00375 DebugAssert(t_i == result.getLHS(), "TheoryBitvector::bitBlastTerm: created wrong theorem" + result.toString() + t_i.toString()); 00376 return result; 00377 } 00378 00379 // Construct the theorem t[bitPosition] <=> \theta_i and put it into 00380 // d_bitvecCache 00381 switch(t.getOpKind()) { 00382 case BVCONST: 00383 result = d_rules->bitExtractConstant(t, bitPosition); 00384 break; 00385 case CONCAT: 00386 { 00387 Theorem thm = d_rules->bitExtractConcatenation(t, bitPosition); 00388 const Expr& boolExtractTerm = thm.getRHS(); 00389 DebugAssert(BOOLEXTRACT == boolExtractTerm.getOpKind(), "TheoryBitvector::bitBlastTerm: recursion: term must be bool_extract"); 00390 const Expr& term = boolExtractTerm[0]; 00391 int bitPos = getBoolExtractIndex(boolExtractTerm); 00392 TRACE("bitvector", "term for bitblastTerm recursion:(", term.toString(), ")"); 00393 result = transitivityRule(thm, bitBlastTerm(term, bitPos)); 00394 break; 00395 } 00396 case EXTRACT: 00397 { 00398 Theorem thm = d_rules->bitExtractExtraction(t, bitPosition); 00399 const Expr& boolExtractTerm = thm.getRHS(); 00400 DebugAssert(BOOLEXTRACT == boolExtractTerm.getOpKind(), "TheoryBitvector::bitBlastTerm: recursion: term must be bool_extract"); 00401 const Expr& term = boolExtractTerm[0]; 00402 int bitPos = getBoolExtractIndex(boolExtractTerm); 00403 TRACE("bitvector", "term for bitblastTerm recursion:(", term, ")"); 00404 result = transitivityRule(thm, bitBlastTerm(term, bitPos)); 00405 break; 00406 } 00407 case CONST_WIDTH_LEFTSHIFT: 00408 { 00409 result = d_rules->bitExtractFixedLeftShift(t, bitPosition); 00410 const Expr& extractTerm = result.getRHS(); 00411 if(BOOLEXTRACT == extractTerm.getOpKind()) 00412 result = transitivityRule(result, bitBlastTerm(extractTerm[0], getBoolExtractIndex(extractTerm))); 00413 break; 00414 } 00415 case BVSHL: 00416 { 00417 // BOOLEXTRACT(bvshl(t,x),i) <=> ((x = 0) AND BOOLEXTRACT(t,i)) OR 00418 // ((x = 1) AND BOOLEXTRACT(t,i-1)) OR ... 00419 // ((x = i) AND BOOLEXTRACT(t,0)) 00420 Theorem thm = d_rules->bitExtractBVSHL(t, bitPosition); 00421 // bitblast the equations and extractions 00422 vector<Theorem> thms, thms0; 00423 int bvsize = BVSize(t); 00424 for (int i = 0; i <= bitPosition; ++i) { 00425 thms0.push_back(bitBlastEqn(t[1].eqExpr(newBVConstExpr(i, bvsize)))); 00426 thms0.push_back(bitBlastTerm(t[0], bitPosition-i)); 00427 thms.push_back(substitutivityRule(AND, thms0)); 00428 thms0.clear(); 00429 } 00430 // Put it all together 00431 if (thms.size() == 1) { 00432 result = transitivityRule(thm, thms[0]); 00433 } 00434 else { 00435 Theorem thm2 = substitutivityRule(OR, thms); 00436 result = transitivityRule(thm, thm2); 00437 } 00438 break; 00439 } 00440 case BVLSHR: 00441 { 00442 // BOOLEXTRACT(bvlshr(t,x),i) <=> ((x = 0) AND BOOLEXTRACT(t,i)) OR 00443 // ((x = 1) AND BOOLEXTRACT(t,i+1)) OR ... 00444 // ((x = n-1-i) AND BOOLEXTRACT(t,n-1)) 00445 Theorem thm = d_rules->bitExtractBVLSHR(t, bitPosition); 00446 // bitblast the equations and extractions 00447 vector<Theorem> thms, thms0; 00448 int bvsize = BVSize(t); 00449 for (int i = 0; i <= bvsize-1-bitPosition; ++i) { 00450 thms0.push_back(bitBlastEqn(t[1].eqExpr(newBVConstExpr(i, bvsize)))); 00451 thms0.push_back(bitBlastTerm(t[0], bitPosition+i)); 00452 thms.push_back(substitutivityRule(AND, thms0)); 00453 thms0.clear(); 00454 } 00455 // Put it all together 00456 if (thms.size() == 1) { 00457 result = transitivityRule(thm, thms[0]); 00458 } 00459 else { 00460 Theorem thm2 = substitutivityRule(OR, thms); 00461 result = transitivityRule(thm, thm2); 00462 } 00463 break; 00464 } 00465 case BVASHR: 00466 { 00467 // BOOLEXTRACT(bvlshr(t,x),i) <=> ((x = 0) AND BOOLEXTRACT(t,i)) OR 00468 // ((x = 1) AND BOOLEXTRACT(t,i+1)) OR ... 00469 // ((x >= n-1-i) AND BOOLEXTRACT(t,n-1)) 00470 Theorem thm = d_rules->bitExtractBVASHR(t, bitPosition); 00471 // bitblast the equations and extractions 00472 vector<Theorem> thms, thms0; 00473 int bvsize = BVSize(t); 00474 int i = 0; 00475 for (; i < bvsize-1-bitPosition; ++i) { 00476 thms0.push_back(bitBlastEqn(t[1].eqExpr(newBVConstExpr(i, bvsize)))); 00477 thms0.push_back(bitBlastTerm(t[0], bitPosition+i)); 00478 thms.push_back(substitutivityRule(AND, thms0)); 00479 thms0.clear(); 00480 } 00481 Expr leExpr = newBVLEExpr(newBVConstExpr(i, bvsize), t[1]); 00482 thms0.push_back(bitBlastIneqn(leExpr)); 00483 thms0.push_back(bitBlastTerm(t[0], bvsize-1)); 00484 thms.push_back(substitutivityRule(AND, thms0)); 00485 // Put it all together 00486 if (thms.size() == 1) { 00487 result = transitivityRule(thm, thms[0]); 00488 } 00489 else { 00490 Theorem thm2 = substitutivityRule(OR, thms); 00491 result = transitivityRule(thm, thm2); 00492 } 00493 break; 00494 } 00495 case BVOR: 00496 case BVAND: 00497 case BVXOR: 00498 { 00499 int kind = t.getOpKind(); 00500 int resKind = (kind == BVOR) ? OR : 00501 kind == BVAND ? AND : XOR; 00502 Theorem thm = d_rules->bitExtractBitwise(t, bitPosition, kind); 00503 const Expr& phi = thm.getRHS(); 00504 DebugAssert(phi.getOpKind() == resKind && phi.arity() == t.arity(), "TheoryBitvector::bitBlastTerm: recursion:\n phi = " + phi.toString() + "\n t = " + t.toString()); 00505 vector<Theorem> substThms; 00506 for(Expr::iterator i=phi.begin(), iend=phi.end(); i!=iend; ++i) { 00507 DebugAssert(i->getOpKind() == BOOLEXTRACT, "Expected BOOLEXTRACT"); 00508 substThms.push_back(bitBlastTerm((*i)[0], getBoolExtractIndex(*i))); 00509 } 00510 result = transitivityRule(thm, substitutivityRule(resKind, substThms)); 00511 break; 00512 } 00513 case BVNEG: 00514 { 00515 Theorem thm = d_rules->bitExtractNot(t, bitPosition); 00516 const Expr& extractTerm = thm.getRHS(); 00517 DebugAssert(NOT == extractTerm.getKind(), "TheoryBitvector::bitBlastTerm: recursion: term must be NOT"); 00518 const Expr& term0 = extractTerm[0]; 00519 DebugAssert(BOOLEXTRACT == term0.getOpKind(), "TheoryBitvector::bitBlastTerm: recursion:(terms must be BOOL-EXTRACT"); 00520 int bitPos0 = getBoolExtractIndex(term0); 00521 std::vector<Theorem> res; 00522 res.push_back(bitBlastTerm(term0[0], bitPos0)); 00523 result = transitivityRule(thm, substitutivityRule(NOT, res)); 00524 break; 00525 } 00526 case BVPLUS: 00527 { 00528 Theorem thm_binary; 00529 if(t.arity() > 2) thm_binary = d_rules->bvPlusAssociativityRule(t); 00530 else thm_binary = reflexivityRule(t); 00531 00532 Expr bvPlusTerm = thm_binary.getRHS(); 00533 00534 // Get the bits of the right multiplicand 00535 Expr b = bvPlusTerm[1]; 00536 vector<Theorem> b_bits(bitPosition + 1); 00537 for (int bit = bitPosition; bit >= 0; -- bit) 00538 b_bits[bit] = bitBlastTerm(b, bit); 00539 00540 // The output of the bit-blasting 00541 vector<Theorem> output_bits; 00542 00543 // Get the bits of the left multiplicand 00544 Expr a = bvPlusTerm[0]; 00545 vector<Theorem> a_bits(bitPosition + 1); 00546 for (int bit = bitPosition; bit >= 0; -- bit) 00547 a_bits[bit] = bitBlastTerm(a, bit); 00548 00549 // Bit-blast them and get all the output bits (of this size) 00550 d_rules->bitblastBVPlus(a_bits, b_bits, bvPlusTerm, output_bits); 00551 00552 // Simplify all the resulting bit expressions and add them to the bit-blasting cache 00553 Theorem thm; 00554 for (int bit = 0; bit <= bitPosition; bit ++) 00555 { 00556 thm = output_bits[bit]; 00557 00558 Expr original_boolextract = newBoolExtractExpr(t, bit); 00559 Expr boolextract = thm.getLHS(); 00560 Expr bitblasted = thm.getRHS(); 00561 00562 CDMap<Expr,Theorem>::iterator it = d_bitvecCache.find(boolextract); 00563 if (it != d_bitvecCache.end()) 00564 continue; 00565 00566 thm = d_bitvecCache[boolextract] = transitivityRule(thm, rewriteBoolean(thm.getRHS())); 00567 if (boolextract != original_boolextract) 00568 thm = d_bitvecCache[original_boolextract] = transitivityRule(substitutivityRule(original_boolextract, thm_binary), thm); 00569 } 00570 00571 // We are returning the last theorem 00572 return thm; 00573 00574 break; 00575 } 00576 case BVMULT: { 00577 00578 Theorem thm; 00579 00580 bool a_is_const = (BVCONST == t[0].getKind()); 00581 00582 // If a constant, rewrite using addition 00583 if (a_is_const) { 00584 thm = d_rules->bitExtractConstBVMult(t, bitPosition); 00585 const Expr& boolExtractTerm = thm.getRHS(); 00586 const Expr& term = boolExtractTerm[0]; 00587 result = transitivityRule(thm, bitBlastTerm(term, bitPosition)); 00588 break; 00589 } 00590 00591 // Get the bits ot the right multiplicant 00592 Expr b = t[1]; 00593 vector<Theorem> b_bits(bitPosition + 1); 00594 for (int bit = bitPosition; bit >= 0; -- bit) 00595 b_bits[bit] = bitBlastTerm(b, bit); 00596 00597 // The output of the bitblasting 00598 vector<Theorem> output_bits; 00599 00600 // Get the bits of the left multiplicant 00601 Expr a = t[0]; 00602 vector<Theorem> a_bits(bitPosition + 1); 00603 for (int bit = bitPosition; bit >= 0; -- bit) 00604 a_bits[bit] = bitBlastTerm(a, bit); 00605 00606 // Bitblast them and get all the output bits (of this size) 00607 d_rules->bitblastBVMult(a_bits, b_bits, t, output_bits); 00608 00609 // Simplify all the resulting bit expressions and add them to the bitblasting cache 00610 for (int bit = 0; bit <= bitPosition; bit ++) 00611 { 00612 thm = output_bits[bit]; 00613 00614 Expr boolextract = thm.getLHS(); 00615 Expr bitblasted = thm.getRHS(); 00616 00617 CDMap<Expr,Theorem>::iterator it = d_bitvecCache.find(boolextract); 00618 if (it != d_bitvecCache.end()) 00619 continue; 00620 00621 thm = d_bitvecCache[boolextract] = transitivityRule(thm, rewriteBoolean(thm.getRHS())); 00622 // not allowed to use simplify in bitblasting 00623 //theoryCore()->simplify(thm.getRHS())); 00624 } 00625 00626 // We are returning the last theorem 00627 return thm; 00628 00629 break; 00630 } 00631 // case BVMULT: { 00632 // 00633 // Theorem thm; 00634 // if(BVCONST == t[0].getKind()) 00635 // thm = d_rules->bitExtractConstBVMult(t, bitPosition); 00636 // else 00637 // thm = d_rules->bitExtractBVMult(t, bitPosition); 00638 // const Expr& boolExtractTerm = thm.getRHS(); 00639 // const Expr& term = boolExtractTerm[0]; 00640 // result = transitivityRule(thm, bitBlastTerm(term, bitPosition)); 00641 // break; 00642 // } 00643 default: 00644 { 00645 FatalAssert(theoryOf(t.getOpKind()) != this, "Unexpected operator in bitBlastTerm:" + t.toString()); 00646 //we have bitvector variable. check if the expr is indeed a BITVECTOR. 00647 IF_DEBUG(Type type = t.getType();) 00648 DebugAssert(BITVECTOR == (type.getExpr()).getOpKind(), "BitvectorTheoremProducer::bitBlastTerm: the type must be BITVECTOR"); 00649 //check if 0<= i < length of BITVECTOR 00650 IF_DEBUG(int bvLength=BVSize(t);) 00651 DebugAssert(0 <= bitPosition && bitPosition < bvLength, "BitvectorTheoremProducer::bitBlastTerm: the bitextract position must be legal"); 00652 TRACE("bitvector", "bitBlastTerm: blasting variables(", t, ")"); 00653 const Expr bitExtract = newBoolExtractExpr(t, bitPosition); 00654 result = reflexivityRule(bitExtract); 00655 TRACE("bitvector", "bitBlastTerm: blasting variables(", t, ")"); 00656 break; 00657 } 00658 } 00659 DebugAssert(!result.isNull(), "TheoryBitvector::bitBlastTerm()"); 00660 Theorem simpThm = rewriteBoolean(result.getRHS()); 00661 // not allowed to use simplify in bitblasting 00662 // theoryCore()->simplify(result.getRHS()); 00663 result = transitivityRule(result, simpThm); 00664 d_bitvecCache[t_i] = result; 00665 DebugAssert(t_i == result.getLHS(), 00666 "TheoryBitvector::bitBlastTerm: " 00667 "created wrong theorem.\n result = " 00668 +result.toString() 00669 +"\n t_i = "+t_i.toString()); 00670 TRACE("bitvector", "bitBlastTerm => ", result, " }"); 00671 return result; 00672 } 00673 00674 00675 // Rewriting methods 00676 00677 00678 //! Check that all the kids of e are BVCONST 00679 static bool constantKids(const Expr& e) { 00680 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) 00681 if(!i->isRational() && i->getKind() != BVCONST) return false; 00682 return true; 00683 } 00684 00685 00686 //! Search for all the BVCONST kids of e, and return their indices in idxs 00687 static void constantKids(const Expr& e, vector<int>& idxs) { 00688 for(int i=0, iend=e.arity(); i<iend; ++i) 00689 if(e[i].getKind() == BVCONST) idxs.push_back(i); 00690 } 00691 00692 00693 // Recursively descend into the expression e, keeping track of whether 00694 // we are under even or odd number of negations ('neg' == true means 00695 // odd, the context is "negative"). 00696 // Produce a proof of e <==> e' or !e <==> e', depending on whether 00697 // neg is false or true, respectively. 00698 // This function must be called only from the pushNegation function 00699 Theorem TheoryBitvector::pushNegationRec(const Expr& e) 00700 { 00701 TRACE("pushNegation", "pushNegationRec(", e,") {"); 00702 DebugAssert(e.getKind() == BVNEG, "Expected BVNEG in pushNegationRec"); 00703 ExprMap<Theorem>::iterator i = d_pushNegCache.find(e); 00704 if(i != d_pushNegCache.end()) { // Found cached result 00705 TRACE("TheoryBitvector::pushNegation", 00706 "pushNegationRec [cached] => ", (*i).second, "}"); 00707 return (*i).second; 00708 } 00709 Theorem res(reflexivityRule(e)); 00710 00711 switch(e[0].getOpKind()) { 00712 case BVCONST: 00713 res = d_rules->negConst(e); 00714 break; 00715 case BVNEG:{ 00716 res = d_rules->negNeg(e); 00717 break; 00718 } 00719 case BVAND: { 00720 //demorgan's laws. 00721 Theorem thm0 = d_rules->negBVand(e); 00722 Expr ee = thm0.getRHS(); 00723 if (ee.arity() == 0) res = thm0; 00724 else { 00725 //process each negated kid 00726 Op op = ee.getOp(); 00727 vector<Theorem> thms; 00728 for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i) 00729 thms.push_back(pushNegationRec(*i)); 00730 res = substitutivityRule(op, thms); 00731 res = transitivityRule(thm0, res); 00732 } 00733 break; 00734 } 00735 case BVOR: { 00736 //demorgan's laws. 00737 Theorem thm0 = d_rules->negBVor(e); 00738 Expr ee = thm0.getRHS(); 00739 if (ee.arity() == 0) res = thm0; 00740 else { 00741 //process each negated kid 00742 Op op = ee.getOp(); 00743 vector<Theorem> thms; 00744 for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i) 00745 thms.push_back(pushNegationRec(*i)); 00746 res = substitutivityRule(op, thms); 00747 res = transitivityRule(thm0, res); 00748 } 00749 break; 00750 } 00751 case BVXOR: { 00752 res = d_rules->negBVxor(e); 00753 Expr ee = res.getRHS(); 00754 00755 // only the first child is negated 00756 Theorem thm0 = pushNegationRec(ee[0]); 00757 if (!thm0.isRefl()) { 00758 thm0 = substitutivityRule(ee, 0, thm0); 00759 res = transitivityRule(res, thm0); 00760 } 00761 break; 00762 } 00763 case BVXNOR: { 00764 res = d_rules->negBVxnor(e); 00765 break; 00766 } 00767 case CONCAT: { 00768 //demorgan's laws. 00769 Theorem thm0 = d_rules->negConcat(e); 00770 Expr ee = thm0.getRHS(); 00771 if (ee.arity() == 0) res = thm0; 00772 else { 00773 //process each negated kid 00774 Op op = ee.getOp(); 00775 vector<Theorem> thms; 00776 for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i) 00777 thms.push_back(pushNegationRec(*i)); 00778 res = substitutivityRule(op, thms); 00779 res = transitivityRule(thm0, res); 00780 } 00781 break; 00782 } 00783 case BVPLUS: 00784 // FIXME: Need to implement the following transformation: 00785 // ~(x+y) <=> ~x+~y+1 00786 // (because ~(x+y)+1= -(x+y) = -x-y = ~x+1+~y+1) 00787 case BVMULT: 00788 // FIXME: Need to implement the following transformation: 00789 // ~(x*y) <=> (~x+1)*y-1 00790 // [ where we prefer x to be constant/AND/OR/NEG and then 00791 // BVPLUS, and only then everything else]. 00792 // (because ~(x*y)+1= -(x+y) = (-x)*y = (~x+1)*y) 00793 default: 00794 res = reflexivityRule(e); 00795 break; 00796 } 00797 TRACE("TheoryBitvector::pushNegation", "pushNegationRec => ", res, "}"); 00798 d_pushNegCache[e] = res; 00799 return res; 00800 } 00801 00802 00803 // We assume that the cache is initially empty 00804 Theorem TheoryBitvector::pushNegation(const Expr& e) { 00805 d_pushNegCache.clear(); 00806 DebugAssert(BVNEG == e.getOpKind(), "Expected BVNEG"); 00807 return pushNegationRec(e); 00808 } 00809 00810 00811 //! Top down simplifier 00812 Theorem TheoryBitvector::simplifyOp(const Expr& e) { 00813 if (e.arity() > 0) { 00814 Expr ee(e); 00815 Theorem thm0; 00816 switch(e.getOpKind()) { 00817 case BVNEG: 00818 thm0 = pushNegation(e); 00819 break; 00820 case EXTRACT: 00821 switch(e[0].getOpKind()) { 00822 case BVPLUS: 00823 thm0 = d_rules->extractBVPlus(e); 00824 break; 00825 case BVMULT: 00826 thm0 = d_rules->extractBVMult(e); 00827 break; 00828 default: 00829 thm0 = reflexivityRule(e); 00830 break; 00831 } 00832 break; 00833 case BVPLUS: 00834 break; 00835 case BVMULT: 00836 // thm0 = d_rules->padBVMult(e); 00837 break; 00838 case CONCAT: // 0bin0_[k] @ BVPLUS(n, args) => BVPLUS(n+k, args) 00839 // if(e.arity()==2 && e[0].getKind()==BVCONST && e[1].getOpKind()==BVPLUS 00840 // && computeBVConst(e[0]) == 0) { 00841 // thm0 = d_rules->bvplusZeroConcatRule(e); 00842 // } 00843 break; 00844 case RIGHTSHIFT: 00845 thm0 = d_rules->rightShiftToConcat(e); 00846 break; 00847 case LEFTSHIFT: 00848 thm0 = d_rules->leftShiftToConcat(e); 00849 break; 00850 case CONST_WIDTH_LEFTSHIFT: 00851 thm0 = d_rules->constWidthLeftShiftToConcat(e); 00852 break; 00853 default: 00854 thm0 = reflexivityRule(e); 00855 break; 00856 } 00857 vector<Theorem> newChildrenThm; 00858 vector<unsigned> changed; 00859 if(thm0.isNull()) thm0 = reflexivityRule(e); 00860 ee = thm0.getRHS(); 00861 int ar = ee.arity(); 00862 for(int k = 0; k < ar; ++k) { 00863 // Recursively simplify the kids 00864 Theorem thm = simplify(ee[k]); 00865 if (thm.getLHS() != thm.getRHS()) { 00866 newChildrenThm.push_back(thm); 00867 changed.push_back(k); 00868 } 00869 } 00870 if(changed.size() > 0) { 00871 Theorem thm1 = substitutivityRule(ee, changed, newChildrenThm); 00872 return transitivityRule(thm0,thm1); 00873 } else 00874 return thm0; 00875 } 00876 return reflexivityRule(e); 00877 } 00878 00879 00880 // Theorem TheoryBitvector::rewriteConst(const Expr& e) 00881 // { 00882 // Theorem result = reflexivityRule(e); 00883 // return result; 00884 // } 00885 00886 00887 Theorem TheoryBitvector::rewriteBV(const Expr& e, ExprMap<Theorem>& cache, int n) 00888 { 00889 TRACE("bitvector rewrite", "TheoryBitvector::rewriteBV(", e, ") {"); 00890 00891 if (n <= 0) return reflexivityRule(e); 00892 00893 Theorem res; 00894 00895 if(n >= 2) { 00896 // rewrite children recursively 00897 Theorem thm; 00898 vector<Theorem> thms; 00899 vector<unsigned> changed; 00900 for(int i=0, iend=e.arity(); i<iend; ++i) { 00901 thm = rewriteBV(e[i], cache, n-1); 00902 if(thm.getLHS() != thm.getRHS()) { 00903 thms.push_back(thm); 00904 changed.push_back(i); 00905 } 00906 } 00907 if(changed.size() > 0) { 00908 thm = substitutivityRule(e, changed, thms); 00909 return transitivityRule(thm, rewriteBV(thm.getRHS(), cache)); 00910 } 00911 // else fall through 00912 } 00913 00914 // Check the cache 00915 ExprMap<Theorem>::iterator it = cache.find(e); 00916 if (it != cache.end()) { 00917 res = (*it).second; 00918 TRACE("bitvector rewrite", "TheoryBitvector::rewrite["+int2string(n) 00919 +"][cached] => ", res.getExpr(), " }"); 00920 IF_DEBUG(debugger.counter("bv rewriteBV[n] cache hits")++;) 00921 return res; 00922 } 00923 00924 // Main rewrites 00925 switch(e.getOpKind()) { 00926 case NOT: 00927 switch (e[0].getKind()) { 00928 case BVLT: 00929 case BVLE: 00930 res = d_rules->notBVLTRule(e); 00931 if (!res.isRefl()) { 00932 res = transitivityRule(res, simplify(res.getRHS())); 00933 } 00934 break; 00935 case EQ: 00936 if (BVSize(e[0][0]) == 1) { 00937 res = d_rules->notBVEQ1Rule(e); 00938 res = transitivityRule(res, simplify(res.getRHS())); 00939 break; 00940 } 00941 break; 00942 } 00943 break; 00944 case EQ: 00945 { 00946 // Canonise constant equations to true or false 00947 if (e[0].getKind() == BVCONST && e[1].getKind() == BVCONST) { 00948 res = d_rules->constEq(e); 00949 } else 00950 // If x_1 or x_2 = 0 then both have to be 0 00951 if (e[0].getKind() == BVOR && e[1].getKind() == BVCONST && computeBVConst(e[1]) == 0) { 00952 res = d_rules->zeroBVOR(e); 00953 res = transitivityRule(res, simplify(res.getRHS())); 00954 } 00955 // if x_1 and x_2 = 1 then both have to be 1 00956 else if (e[0].getKind() == BVAND && e[1].getKind() == BVCONST && computeBVConst(e[1]) == pow(BVSize(e[1]), (Unsigned)2) - 1) { 00957 res = d_rules->oneBVAND(e); 00958 res = transitivityRule(res, simplify(res.getRHS())); 00959 } 00960 // Solve 00961 else { 00962 res = d_rules->canonBVEQ(e); 00963 if (!res.isRefl()) { 00964 res = transitivityRule(res, simplify(res.getRHS())); 00965 } 00966 else e.setRewriteNormal(); 00967 } 00968 break; 00969 } 00970 case BVCONST: 00971 { 00972 res = reflexivityRule(e); 00973 break; 00974 } 00975 case CONCAT: { 00976 // First, flatten concatenation 00977 res = d_rules->concatFlatten(e); 00978 TRACE("bitvector rewrite", "rewriteBV (CONCAT): flattened = ", 00979 res.getRHS(), ""); 00980 // Search for adjacent constants and accumulate the vector of 00981 // nested concatenations (@ t1 ... (@ c1 ... ck) ... tn), and the 00982 // indices of constant concatenations in this new expression. 00983 // We'll connect this term to 'e' by inverse of flattenning, and 00984 // rewrite concatenations of constants into bitvector constants. 00985 vector<unsigned> idxs; 00986 vector<Expr> kids; // Kids of the new concatenation 00987 vector<Theorem> thms; // Rewrites of constant concatenations 00988 vector<Expr> nestedKids; // Kids of the current concatenation of constants 00989 // res will be overwritten, using const Expr& may be dangerous 00990 Expr e1 = res.getRHS(); 00991 for(int i=0, iend=e1.arity(); i<iend; ++i) { 00992 TRACE("bitvector rewrite", "rewriteBV: e["+int2string(i)+"]=", 00993 e1[i], ""); 00994 if(e1[i].getKind() == BVCONST) { 00995 // INVARIANT: if it is the first constant in a batch, 00996 // then nestedKids must be empty. 00997 nestedKids.push_back(e1[i]); 00998 TRACE("bitvector rewrite", "rewriteBV: queued up BVCONST: ", 00999 e1[i], ""); 01000 } else { // e1[i] is not a BVCONST 01001 if(nestedKids.size() > 0) { // This is the end of a batch 01002 if(nestedKids.size() >= 2) { // Create a nested const concat 01003 Expr cc = newConcatExpr(nestedKids); 01004 idxs.push_back(kids.size()); 01005 kids.push_back(cc); 01006 thms.push_back(d_rules->concatConst(cc)); 01007 TRACE("bitvector rewrite", "rewriteBV: wrapping ", cc, ""); 01008 } else { // A single constant, add it as it is 01009 TRACE("bitvector rewrite", "rewriteBV: single const ", 01010 nestedKids[0], ""); 01011 kids.push_back(nestedKids[0]); 01012 } 01013 nestedKids.clear(); 01014 } 01015 // Add the current non-constant BV 01016 kids.push_back(e1[i]); 01017 } 01018 } 01019 // Handle the last BVCONST 01020 if(nestedKids.size() > 0) { 01021 if(nestedKids.size() >= 2) { // Create a nested const concat 01022 Expr cc = newConcatExpr(nestedKids); 01023 idxs.push_back(kids.size()); 01024 kids.push_back(cc); 01025 thms.push_back(d_rules->concatConst(cc)); 01026 TRACE("bitvector rewrite", "rewriteBV: wrapping ", cc, ""); 01027 } else { // A single constant, add it as it is 01028 kids.push_back(nestedKids[0]); 01029 TRACE("bitvector rewrite", "rewriteBV: single const ", 01030 nestedKids[0], ""); 01031 } 01032 nestedKids.clear(); 01033 } 01034 // If there are any constants to merge, do the merging 01035 if(idxs.size() > 0) { 01036 // CONCAT with constants groupped 01037 if(kids.size() == 1) { // Special case: all elements are constants 01038 DebugAssert(thms.size() == 1, "TheoryBitvector::rewriteBV:\n" 01039 "case CONCAT: all constants. thms.size() == " 01040 +int2string(thms.size())); 01041 res = transitivityRule(res, thms[0]); 01042 } else { 01043 Expr ee = newConcatExpr(kids); 01044 01045 Theorem constMerge = substitutivityRule(ee, idxs, thms); 01046 // The inverse flattening of ee 01047 Theorem unFlatten = symmetryRule(d_rules->concatFlatten(ee)); 01048 // Putting it together: Theorem(e==e'), where e' has constants merged 01049 res = transitivityRule(res, unFlatten); 01050 res = transitivityRule(res, constMerge); 01051 } 01052 } 01053 01054 // Now do a similar search for mergeable extractions 01055 idxs.clear(); 01056 thms.clear(); 01057 kids.clear(); 01058 // nestedKids must already be empty 01059 DebugAssert(nestedKids.size() == 0, 01060 "rewriteBV() case CONCAT, end of const merge"); 01061 Expr prevExpr; // Previous base of extraction (initially Null) 01062 // The first and the last bit in the batch of mergeable extractions 01063 int hi(-1), low(-1); 01064 // Refresh e1 01065 e1 = res.getRHS(); 01066 for(int i=0, iend=e1.arity(); i<iend; ++i) { 01067 const Expr& ei = e1[i]; 01068 if(ei.getOpKind() == EXTRACT) { 01069 if(nestedKids.size() > 0 && ei[0] == prevExpr 01070 && (low-1) == getExtractHi(ei)) { 01071 // Continue to accumulate the current batch 01072 nestedKids.push_back(ei); 01073 low = getExtractLow(ei); 01074 } else { // Start a new batch 01075 // First, check if there was a batch before that 01076 if(nestedKids.size() >= 2) { // Create a nested const concat 01077 Expr cc = newConcatExpr(nestedKids); 01078 idxs.push_back(kids.size()); 01079 kids.push_back(cc); 01080 thms.push_back(d_rules->concatMergeExtract(cc)); 01081 nestedKids.clear(); 01082 } else if(nestedKids.size() == 1) { 01083 // A single extraction, add it as it is 01084 kids.push_back(nestedKids[0]); 01085 nestedKids.clear(); 01086 } 01087 // Now, actually start a new batch 01088 nestedKids.push_back(ei); 01089 hi = getExtractHi(ei); 01090 low = getExtractLow(ei); 01091 prevExpr = ei[0]; 01092 } 01093 } else { // e1[i] is not an EXTRACT 01094 if(nestedKids.size() >= 2) { // Create a nested const concat 01095 Expr cc = newConcatExpr(nestedKids); 01096 idxs.push_back(kids.size()); 01097 kids.push_back(cc); 01098 thms.push_back(d_rules->concatMergeExtract(cc)); 01099 } else if(nestedKids.size() == 1) { 01100 // A single extraction, add it as it is 01101 kids.push_back(nestedKids[0]); 01102 } 01103 nestedKids.clear(); 01104 // Add the current non-EXTRACT BV 01105 kids.push_back(ei); 01106 } 01107 } 01108 // Handle the last batch of extractions 01109 if(nestedKids.size() >= 2) { // Create a nested const concat 01110 Expr cc = newConcatExpr(nestedKids); 01111 idxs.push_back(kids.size()); 01112 kids.push_back(cc); 01113 // The extraction may include all the bits, we need to rewrite again 01114 thms.push_back(rewriteBV(d_rules->concatMergeExtract(cc), cache, 1)); 01115 } else if(nestedKids.size() == 1) { 01116 // A single extraction, add it as it is 01117 kids.push_back(nestedKids[0]); 01118 } 01119 // If there are any extractions to merge, do the merging 01120 if(idxs.size() > 0) { 01121 // CONCAT with extractions groupped 01122 if(kids.size() == 1) { // Special case: all elements merge together 01123 DebugAssert(thms.size() == 1, "TheoryBitvector::rewriteBV:\n" 01124 "case CONCAT: all extracts merge. thms.size() == " 01125 +int2string(thms.size())); 01126 res = thms[0]; 01127 } else { 01128 Expr ee = newConcatExpr(kids); 01129 Theorem extractMerge = substitutivityRule(ee, idxs, thms); 01130 // The inverse flattening of ee 01131 Theorem unFlatten = symmetryRule(d_rules->concatFlatten(ee)); 01132 // Putting it together: Theorem(e==e'), where e' has extractions merged 01133 res = transitivityRule(res, unFlatten); 01134 res = transitivityRule(res, extractMerge); 01135 } 01136 } 01137 // Check for 0bin00 @ BVPLUS(n, ...). Most of the time, this 01138 // case will be handled during the top-down phase 01139 // (simplifyOp()), but not always. 01140 // Expr ee = res.getRHS(); 01141 // if(ee.getOpKind()==CONCAT && ee.arity() == 2 && ee[0].getKind()==BVCONST 01142 // && ee[1].getOpKind()==BVPLUS && computeBVConst(ee[0]) == 0) { 01143 // // Push the concat down through BVPLUS 01144 // Theorem thm = d_rules->bvplusZeroConcatRule(ee); 01145 // if(thm.getLHS()!=thm.getRHS()) { 01146 // thm = transitivityRule(thm, d_rules->padBVPlus(thm.getRHS())); 01147 // // Kids may need to be rewritten again 01148 // res = rewriteBV(transitivityRule(res, thm), cache, 2); 01149 // } 01150 // } 01151 // Since we may have pulled subexpressions from more than one 01152 // level deep, we cannot guarantee that all the new kids are 01153 // fully simplified, and have to call simplify explicitly again. 01154 // Since this is potentially an expensive operation, we try to 01155 // minimize the need for it: 01156 01157 // * check if the result has a find pointer (then kids don't 01158 // need to be simplified), 01159 // * check if any of the kids simplify (if not, don't bother). 01160 // If kids are already simplified, we'll hit the simplifier 01161 // cache. It's only expensive when kids do indeed simplify. 01162 if(!res.isRefl() && (theoryCore()->inUpdate() || !res.getRHS().hasFind())) { 01163 res = transitivityRule(res, simplify(res.getRHS())); 01164 } 01165 break; 01166 } 01167 case EXTRACT: { 01168 DebugAssert(e.arity() == 1, "TheoryBitvector::rewriteBV: e = " 01169 +e.toString()); 01170 if(getExtractLow(e) == 0 && getExtractHi(e) == BVSize(e[0])-1) 01171 res = d_rules->extractWhole(e); 01172 else { 01173 switch(e[0].getOpKind()) { 01174 case BVCONST: 01175 res = d_rules->extractConst(e); 01176 break; 01177 case EXTRACT: 01178 res = d_rules->extractExtract(e); 01179 break; 01180 case CONCAT: 01181 // Push extraction through concat, and rewrite the kids 01182 res = rewriteBV(d_rules->extractConcat(e), cache, 2); 01183 break; 01184 case BVNEG: 01185 res = rewriteBV(d_rules->extractNeg(e), cache, 2); 01186 break; 01187 case BVAND: 01188 res = rewriteBV(d_rules->extractAnd(e), cache, 2); 01189 break; 01190 case BVOR: 01191 res = rewriteBV(d_rules->extractOr(e), cache, 2); 01192 break; 01193 case BVXOR: 01194 res = 01195 rewriteBV(d_rules->extractBitwise(e, BVXOR, "extract_bvxor"), cache, 2); 01196 break; 01197 case BVMULT: { 01198 const Expr& bvmult = e[0]; 01199 int hiBit = getExtractHi(e); 01200 int bvmultLen = BVSize(bvmult); 01201 // Applicable if it changes anything 01202 if(hiBit+1 < bvmultLen) { 01203 res = d_rules->extractBVMult(e); 01204 res = rewriteBV(res, cache, 3); 01205 } else 01206 res = reflexivityRule(e); 01207 break; 01208 } 01209 case BVPLUS: { 01210 const Expr& bvplus = e[0]; 01211 int hiBit = getExtractHi(e); 01212 int bvplusLen = BVSize(bvplus); 01213 if(hiBit+1 < bvplusLen) { 01214 res = d_rules->extractBVPlus(e); 01215 } else res = reflexivityRule(e); 01216 break; 01217 } 01218 default: 01219 res = reflexivityRule(e); 01220 break; 01221 } 01222 } 01223 if (!res.isRefl()) { 01224 res = transitivityRule(res, simplify(res.getRHS())); 01225 } 01226 break; 01227 } 01228 case BOOLEXTRACT: { 01229 Expr t(e); 01230 // Normal form: t[0] for 1-bit t, collapse t[i:i][0] into t[i] 01231 if(BVSize(e[0]) > 1) { // transform t[i] to t[i:i][0] and rewrite 01232 res = rewriteBV(d_rules->bitExtractRewrite(e), cache, 2); 01233 t = res.getRHS(); 01234 } 01235 if(t.getOpKind() == BOOLEXTRACT && t[0].getOpKind() == EXTRACT) { 01236 // Collapse t[i:i][0] to t[i] 01237 int low = getExtractLow(t[0]); 01238 if(getExtractHi(t[0]) == low) { 01239 Theorem thm(d_rules->bitExtractRewrite 01240 (newBoolExtractExpr(t[0][0], low))); 01241 thm = symmetryRule(thm); 01242 res = (res.isNull())? thm : transitivityRule(res, thm); 01243 t = res.getRHS()[0]; 01244 // Make sure t in the resulting t[i] is its own find pointer 01245 // (global invariant) 01246 if(t.hasFind()) { 01247 Theorem findThm = find(t); 01248 if(t != findThm.getRHS()) { 01249 vector<Theorem> thms; 01250 thms.push_back(findThm); 01251 thm = substitutivityRule(res.getRHS().getOp(), thms); 01252 res = transitivityRule(res, thm); 01253 } 01254 } 01255 } 01256 } 01257 if(!res.isNull()) t = res.getRHS(); 01258 // Rewrite a constant extraction to TRUE or FALSE 01259 if(t.getOpKind() == BOOLEXTRACT && constantKids(t)) { 01260 Theorem thm = d_rules->bitExtractConstant(t[0], getBoolExtractIndex(t)); 01261 res = (res.isNull())? thm : transitivityRule(res, thm); 01262 } 01263 break; 01264 } 01265 case LEFTSHIFT: 01266 if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) { 01267 res = d_rules->bvShiftZero(e); 01268 } else { 01269 res = d_rules->leftShiftToConcat(e); 01270 if (!res.isRefl()) { 01271 res = transitivityRule(res, simplify(res.getRHS())); 01272 } 01273 } 01274 break; 01275 case CONST_WIDTH_LEFTSHIFT: 01276 if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) { 01277 res = d_rules->bvShiftZero(e); 01278 } else { 01279 res = d_rules->constWidthLeftShiftToConcat(e); 01280 if (!res.isRefl()) { 01281 res = transitivityRule(res, simplify(res.getRHS())); 01282 } 01283 } 01284 break; 01285 case RIGHTSHIFT: 01286 if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) { 01287 res = d_rules->bvShiftZero(e); 01288 } else { 01289 res = d_rules->rightShiftToConcat(e); 01290 if (!res.isRefl()) { 01291 res = transitivityRule(res, simplify(res.getRHS())); 01292 } 01293 } 01294 break; 01295 case BVSHL: 01296 if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) { 01297 res = d_rules->bvShiftZero(e); 01298 } else 01299 if (e[1].getKind() == BVCONST) { 01300 res = d_rules->bvshlToConcat(e); 01301 res = transitivityRule(res, simplify(res.getRHS())); 01302 } 01303 // else { 01304 // res = d_rules->bvshlSplit(e); 01305 // res = transitivityRule(res, simplify(res.getRHS())); 01306 // } 01307 break; 01308 case BVLSHR: 01309 if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) { 01310 res = d_rules->bvShiftZero(e); 01311 } else 01312 if (e[1].getKind() == BVCONST) { 01313 res = d_rules->bvlshrToConcat(e); 01314 res = transitivityRule(res, simplify(res.getRHS())); 01315 } 01316 break; 01317 case BVASHR: 01318 if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) { 01319 res = d_rules->bvShiftZero(e); 01320 } else 01321 if (e[1].getKind() == BVCONST) { 01322 res = d_rules->bvashrToConcat(e); 01323 res = transitivityRule(res, simplify(res.getRHS())); 01324 } 01325 break; 01326 case SX: { 01327 res = d_rules->signExtendRule(e); 01328 res = transitivityRule(res, simplify(res.getRHS())); 01329 break; 01330 } 01331 01332 case BVZEROEXTEND: 01333 res = d_rules->zeroExtendRule(e); 01334 res = transitivityRule(res, simplify(res.getRHS())); 01335 break; 01336 01337 case BVREPEAT: 01338 res = d_rules->repeatRule(e); 01339 res = transitivityRule(res, simplify(res.getRHS())); 01340 break; 01341 01342 case BVROTL: 01343 res = d_rules->rotlRule(e); 01344 res = transitivityRule(res, simplify(res.getRHS())); 01345 break; 01346 01347 case BVROTR: 01348 res = d_rules->rotrRule(e); 01349 res = transitivityRule(res, simplify(res.getRHS())); 01350 break; 01351 01352 case BVAND: 01353 case BVOR: 01354 case BVXOR: 01355 { 01356 int kind = e.getOpKind(); 01357 // Flatten the bit-wise AND, eliminate duplicates, reorder terms 01358 res = d_rules->bitwiseFlatten(e, kind); 01359 Expr ee = res.getRHS(); 01360 if (ee.getOpKind() != kind) break; 01361 01362 // Search for constant bitvectors 01363 vector<int> idxs; 01364 constantKids(ee, idxs); 01365 int idx = -1; 01366 01367 if(idxs.size() >= 2) { 01368 res = transitivityRule(res, d_rules->bitwiseConst(ee, idxs, kind)); 01369 ee = res.getRHS(); 01370 if (ee.getOpKind() != kind) break; 01371 idx = 0; 01372 } 01373 else if (idxs.size() == 1) { 01374 idx = idxs[0]; 01375 } 01376 01377 if (idx >= 0) { 01378 res = transitivityRule(res, d_rules->bitwiseConstElim(ee, idx, kind)); 01379 ee = res.getRHS(); 01380 } 01381 if (ee.getOpKind() == kind) { 01382 res = transitivityRule(res, d_rules->bitwiseConcat(ee, kind)); 01383 } 01384 if (!res.isRefl()) { 01385 res = transitivityRule(res, simplify(res.getRHS())); 01386 } 01387 else { 01388 e.setRewriteNormal(); 01389 } 01390 break; 01391 } 01392 case BVXNOR: { 01393 res = d_rules->rewriteXNOR(e); 01394 res = transitivityRule(res, simplify(res.getRHS())); 01395 break; 01396 } 01397 case BVNEG: { 01398 res = pushNegation(e); 01399 if (!res.isRefl()) { 01400 res = transitivityRule(res, simplify(res.getRHS())); 01401 } 01402 break; 01403 } 01404 case BVNAND: { 01405 res = d_rules->rewriteNAND(e); 01406 res = transitivityRule(res, simplify(res.getRHS())); 01407 break; 01408 } 01409 case BVNOR: { 01410 res = d_rules->rewriteNOR(e); 01411 res = transitivityRule(res, simplify(res.getRHS())); 01412 break; 01413 } 01414 case BVCOMP: { 01415 res = d_rules->rewriteBVCOMP(e); 01416 res = transitivityRule(res, simplify(res.getRHS())); 01417 break; 01418 } 01419 case BVUMINUS: 01420 { 01421 res = d_rules->canonBVUMinus( e ); 01422 res = transitivityRule(res, simplify(res.getRHS())); 01423 break; 01424 } 01425 case BVPLUS: 01426 { 01427 res = d_rules->canonBVPlus(e ); 01428 if (!res.isRefl()) { 01429 res = transitivityRule(res, simplify(res.getRHS())); 01430 } 01431 else e.setRewriteNormal(); 01432 break; 01433 } 01434 case BVSUB: { 01435 res = d_rules->rewriteBVSub(e); 01436 res = transitivityRule(res, simplify(res.getRHS())); 01437 break; 01438 } 01439 case BVMULT: 01440 { 01441 res = d_rules->liftConcatBVMult(e); 01442 if (!res.isRefl()) { 01443 res = transitivityRule(res, simplify(res.getRHS())); 01444 } 01445 else { 01446 res = d_rules->canonBVMult( e ); 01447 if (!res.isRefl()) 01448 res = transitivityRule(res, simplify(res.getRHS())); 01449 else e.setRewriteNormal(); 01450 } 01451 break; 01452 } 01453 01454 case BVUDIV: 01455 { 01456 Expr a = e[0]; 01457 Expr b = e[1]; 01458 01459 // Constant division 01460 if (a.getOpKind() == BVCONST && b.getOpKind() == BVCONST) { 01461 res = d_rules->bvUDivConst(e); 01462 break; 01463 } 01464 01465 if (theoryCore()->okToEnqueue()) 01466 { 01467 // get the full theorem 01468 // e = x/y 01469 // \exists div, mod: e = div & (y != 0 -> ...) 01470 // result is the equality 01471 // assert the additional conjunct 01472 Theorem fullTheorem = d_rules->bvUDivTheorem(e); 01473 // Skolemise the variables 01474 Theorem skolem_div = getCommonRules()->skolemize(fullTheorem); 01475 // Get the rewrite part 01476 res = getCommonRules()->andElim(skolem_div, 0); 01477 // Get the division part 01478 Theorem additionalConstraint = getCommonRules()->andElim(skolem_div, 1); 01479 // Enqueue the division part 01480 enqueueFact(additionalConstraint); 01481 res = transitivityRule(res, simplify(res.getRHS())); 01482 } else { 01483 res = reflexivityRule(e); 01484 } 01485 break; 01486 } 01487 case BVSDIV: 01488 res = d_rules->bvSDivRewrite(e); 01489 res = transitivityRule(res, simplify(res.getRHS())); 01490 break; 01491 case BVUREM: 01492 { 01493 Expr a = e[0]; 01494 Expr b = e[1]; 01495 01496 // Constant division 01497 if (a.getOpKind() == BVCONST && b.getOpKind() == BVCONST) { 01498 res = d_rules->bvURemConst(e); 01499 break; 01500 } 01501 01502 res = d_rules->bvURemRewrite(e); 01503 res = transitivityRule(res, theoryCore()->simplify(res.getRHS())); 01504 01505 break; 01506 } 01507 case BVSREM: 01508 res = d_rules->bvSRemRewrite(e); 01509 res = transitivityRule(res, simplify(res.getRHS())); 01510 break; 01511 case BVSMOD: 01512 res = d_rules->bvSModRewrite(e); 01513 res = transitivityRule(res, simplify(res.getRHS())); 01514 break; 01515 case BVLT: 01516 case BVLE: { 01517 Expr lhs = e[0]; 01518 Expr rhs = e[1]; 01519 if (BVSize(lhs) != BVSize(rhs)) { 01520 res = d_rules->padBVLTRule(e, BVSize(lhs) > BVSize(rhs) ? BVSize(lhs) : BVSize(rhs)); 01521 res = transitivityRule(res, simplify(res.getRHS())); 01522 } 01523 else { 01524 if(lhs == rhs) 01525 res = d_rules->lhsEqRhsIneqn(e, e.getOpKind()); 01526 else if (BVCONST == lhs.getKind() && BVCONST == rhs.getKind()) 01527 res = d_rules->bvConstIneqn(e, e.getOpKind()); 01528 else if (e.getOpKind() == BVLE && BVCONST == lhs.getKind() && computeBVConst(lhs) == 0) 01529 res = d_rules->zeroLeq(e); 01530 } 01531 break; 01532 } 01533 01534 case BVGT: 01535 case BVGE: 01536 FatalAssert(false, "Should be eliminated at parse-time"); 01537 break; 01538 01539 case BVSLT: 01540 case BVSLE:{ 01541 /*! input: e0 <=(s) e1. output depends on whether the topbits(MSB) of 01542 * e0 and e1 are constants. If they are constants then optimizations 01543 * are done. In general, the following rule is implemented. 01544 * Step1: 01545 * e0 <=(s) e1 01546 * <==> 01547 * pad(e0) <=(s) pad(e1) 01548 * Step2: 01549 * pad(e0) <=(s) pad(e1) 01550 * <==> 01551 * (e0[n-1] AND NOT e1[n-1]) OR 01552 * (e0[n-1] = e1[n-1] AND e0[n-2:0] <= e1[n-2:0]) 01553 */ 01554 int e0len = BVSize(e[0]); 01555 int e1len = BVSize(e[1]); 01556 int bvlength = e0len>=e1len ? e0len : e1len; 01557 //e0 <=(s) e1 <=> signpad(e0) <=(s) signpad(e1) 01558 01559 std::vector<Theorem> thms; 01560 std::vector<unsigned> changed; 01561 01562 //e0 <= e1 <==> pad(e0) <= pad(e1) 01563 Theorem thm = d_rules->padBVSLTRule(e, bvlength); 01564 Expr paddedE = thm.getRHS(); 01565 01566 //the rest of the code simply normalizes pad(e0) and pad(e1) 01567 Theorem thm0 = d_rules->signExtendRule(paddedE[0]); 01568 Expr rhs0 = thm0.getRHS(); 01569 thm0 = transitivityRule(thm0, rewriteBV(rhs0, cache)); 01570 if(thm0.getLHS() != thm0.getRHS()) { 01571 thms.push_back(thm0); 01572 changed.push_back(0); 01573 } 01574 01575 Theorem thm1 = d_rules->signExtendRule(paddedE[1]); 01576 Expr rhs1 = thm1.getRHS(); 01577 thm1 = transitivityRule(thm1, rewriteBV(rhs1, cache)); 01578 if(thm1.getLHS() != thm1.getRHS()) { 01579 thms.push_back(thm1); 01580 changed.push_back(1); 01581 } 01582 01583 if(changed.size() > 0) { 01584 thm0 = substitutivityRule(paddedE,changed,thms); 01585 thm0 = transitivityRule(thm, thm0); 01586 } 01587 else 01588 thm0 = reflexivityRule(e); 01589 01590 //signpad(e0) <= signpad(e1) 01591 Expr thm0RHS = thm0.getRHS(); 01592 DebugAssert(thm0RHS.getOpKind() == BVSLT || 01593 thm0RHS.getOpKind() == BVSLE, 01594 "TheoryBitvector::RewriteBV"); 01595 //signpad(e0)[bvlength-1:bvlength-1] 01596 const Expr MSB0 = newBVExtractExpr(thm0RHS[0],bvlength-1,bvlength-1); 01597 //signpad(e1)[bvlength-1:bvlength-1] 01598 const Expr MSB1 = newBVExtractExpr(thm0RHS[1],bvlength-1,bvlength-1); 01599 //rewritten MSB0 01600 const Theorem topBit0 = rewriteBV(MSB0, cache, 2); 01601 //rewritten MSB1 01602 const Theorem topBit1 = rewriteBV(MSB1, cache, 2); 01603 //compute e0 <=(s) e1 <==> signpad(e0) <=(s) signpad(e1) <==> 01604 //output as given above 01605 thm1 = d_rules->signBVLTRule(thm0RHS, topBit0, topBit1); 01606 thm1 = transitivityRule(thm1,simplify(thm1.getRHS())); 01607 res = transitivityRule(thm0,thm1); 01608 break; 01609 } 01610 case BVSGT: 01611 case BVSGE: 01612 FatalAssert(false, "Should be eliminated at parse-time"); 01613 break; 01614 default: 01615 res = reflexivityRule(e); 01616 break; 01617 } 01618 01619 if (res.isNull()) res = reflexivityRule(e); 01620 01621 // Update cache 01622 cache[e] = res; 01623 01624 TRACE("bitvector rewrite", "TheoryBitvector::rewriteBV => ", 01625 res.getExpr(), " }"); 01626 01627 return res; 01628 } 01629 01630 01631 Theorem TheoryBitvector::rewriteBV(const Expr& e, int n) 01632 { 01633 ExprMap<Theorem> cache; 01634 return rewriteBV(e, cache, n); 01635 } 01636 01637 01638 Theorem TheoryBitvector::rewriteBoolean(const Expr& e) 01639 { 01640 Theorem thm; 01641 switch (e.getKind()) { 01642 case NOT: 01643 if (e[0].isTrue()) 01644 thm = getCommonRules()->rewriteNotTrue(e); 01645 else if (e[0].isFalse()) 01646 thm = getCommonRules()->rewriteNotFalse(e); 01647 else if (e[0].isNot()) 01648 thm = getCommonRules()->rewriteNotNot(e); 01649 break; 01650 case IFF: { 01651 thm = getCommonRules()->rewriteIff(e); 01652 const Expr& rhs = thm.getRHS(); 01653 // The only time we need to rewrite the result (rhs) is when 01654 // e==(FALSE<=>e1) or (e1<=>FALSE), so rhs==!e1. 01655 if (e != rhs && rhs.isNot()) 01656 thm = transitivityRule(thm, rewriteBoolean(rhs)); 01657 break; 01658 } 01659 case AND:{ 01660 std::vector<Theorem> newK; 01661 std::vector<unsigned> changed; 01662 unsigned count(0); 01663 for(Expr::iterator ii=e.begin(),iiend=e.end();ii!=iiend;ii++,count++) { 01664 Theorem temp = rewriteBoolean(*ii); 01665 if(temp.getLHS() != temp.getRHS()) { 01666 newK.push_back(temp); 01667 changed.push_back(count); 01668 } 01669 } 01670 if(changed.size() > 0) { 01671 Theorem res = substitutivityRule(e,changed,newK); 01672 thm = transitivityRule(res, rewriteAnd(res.getRHS())); 01673 } else 01674 thm = rewriteAnd(e); 01675 } 01676 break; 01677 case OR:{ 01678 std::vector<Theorem> newK; 01679 std::vector<unsigned> changed; 01680 unsigned count(0); 01681 for(Expr::iterator ii=e.begin(),iiend=e.end();ii!=iiend;ii++,count++) { 01682 Theorem temp = rewriteBoolean(*ii); 01683 if(temp.getLHS() != temp.getRHS()) { 01684 newK.push_back(temp); 01685 changed.push_back(count); 01686 } 01687 } 01688 if(changed.size() > 0) { 01689 Theorem res = substitutivityRule(e,changed,newK); 01690 thm = transitivityRule(res, rewriteOr(res.getRHS())); 01691 } else 01692 thm = rewriteOr(e); 01693 } 01694 break; 01695 01696 default: 01697 break; 01698 } 01699 if(thm.isNull()) thm = reflexivityRule(e); 01700 01701 return thm; 01702 } 01703 01704 01705 /////////////////////////////////////////////////////////////////////////////// 01706 // TheoryBitvector Public Methods // 01707 /////////////////////////////////////////////////////////////////////////////// 01708 TheoryBitvector::TheoryBitvector(TheoryCore* core) 01709 : Theory(core, "Bitvector"), 01710 d_bvDelayEq(core->getStatistics().counter("bv delayed assert eqs")), 01711 d_bvAssertEq(core->getStatistics().counter("bv eager assert eqs")), 01712 d_bvDelayDiseq(core->getStatistics().counter("bv delayed assert diseqs")), 01713 d_bvAssertDiseq(core->getStatistics().counter("bv eager assert diseqs")), 01714 d_bvTypePreds(core->getStatistics().counter("bv type preds enqueued")), 01715 d_bvDelayTypePreds(core->getStatistics().counter("bv type preds delayed")), 01716 d_bvBitBlastEq(core->getStatistics().counter("bv bitblast eqs")), 01717 d_bvBitBlastDiseq(core->getStatistics().counter("bv bitblast diseqs")), 01718 d_bv32Flag(&(core->getFlags()["bv32-flag"].getBool())), 01719 d_bitvecCache(core->getCM()->getCurrentContext()), 01720 d_eq(core->getCM()->getCurrentContext()), 01721 d_eqPending(core->getCM()->getCurrentContext()), 01722 d_eq_index(core->getCM()->getCurrentContext(), 0, 0), 01723 d_bitblast(core->getCM()->getCurrentContext()), 01724 d_bb_index(core->getCM()->getCurrentContext(), 0, 0), 01725 d_sharedSubterms(core->getCM()->getCurrentContext()), 01726 d_sharedSubtermsList(core->getCM()->getCurrentContext()), 01727 d_maxLength(0), 01728 d_index1(core->getCM()->getCurrentContext(), 0, 0), 01729 d_index2(core->getCM()->getCurrentContext(), 0, 0) 01730 // d_solvedEqSet(core->getCM()->getCurrentContext(), 0, 0) 01731 { 01732 getEM()->newKind(BITVECTOR, "_BITVECTOR", true); 01733 getEM()->newKind(BVCONST, "_BVCONST"); 01734 getEM()->newKind(CONCAT, "_CONCAT"); 01735 getEM()->newKind(EXTRACT, "_EXTRACT"); 01736 getEM()->newKind(BOOLEXTRACT, "_BOOLEXTRACT"); 01737 getEM()->newKind(LEFTSHIFT, "_LEFTSHIFT"); 01738 getEM()->newKind(CONST_WIDTH_LEFTSHIFT, "_CONST_WIDTH_LEFTSHIFT"); 01739 getEM()->newKind(RIGHTSHIFT, "_RIGHTSHIFT"); 01740 getEM()->newKind(BVSHL, "_BVSHL"); 01741 getEM()->newKind(BVLSHR, "_BVLSHR"); 01742 getEM()->newKind(BVASHR, "_BVASHR"); 01743 getEM()->newKind(SX,"_SX"); 01744 getEM()->newKind(BVREPEAT,"_BVREPEAT"); 01745 getEM()->newKind(BVZEROEXTEND,"_BVZEROEXTEND"); 01746 getEM()->newKind(BVROTL,"_BVROTL"); 01747 getEM()->newKind(BVROTR,"_BVROTR"); 01748 getEM()->newKind(BVAND, "_BVAND"); 01749 getEM()->newKind(BVOR, "_BVOR"); 01750 getEM()->newKind(BVXOR, "_BVXOR"); 01751 getEM()->newKind(BVXNOR, "_BVXNOR"); 01752 getEM()->newKind(BVNEG, "_BVNEG"); 01753 getEM()->newKind(BVNAND, "_BVNAND"); 01754 getEM()->newKind(BVNOR, "_BVNOR"); 01755 getEM()->newKind(BVCOMP, "_BVCOMP"); 01756 getEM()->newKind(BVUMINUS, "_BVUMINUS"); 01757 getEM()->newKind(BVPLUS, "_BVPLUS"); 01758 getEM()->newKind(BVSUB, "_BVSUB"); 01759 getEM()->newKind(BVMULT, "_BVMULT"); 01760 getEM()->newKind(BVUDIV, "_BVUDIV"); 01761 getEM()->newKind(BVSDIV, "_BVSDIV"); 01762 getEM()->newKind(BVUREM, "_BVUREM"); 01763 getEM()->newKind(BVSREM, "_BVSREM"); 01764 getEM()->newKind(BVSMOD, "_BVSMOD"); 01765 getEM()->newKind(BVLT, "_BVLT"); 01766 getEM()->newKind(BVLE, "_BVLE"); 01767 getEM()->newKind(BVGT, "_BVGT"); 01768 getEM()->newKind(BVGE, "_BVGE"); 01769 getEM()->newKind(BVSLT, "_BVSLT"); 01770 getEM()->newKind(BVSLE, "_BVSLE"); 01771 getEM()->newKind(BVSGT, "_BVSGT"); 01772 getEM()->newKind(BVSGE, "_BVSGE"); 01773 getEM()->newKind(INTTOBV, "_INTTOBV"); 01774 getEM()->newKind(BVTOINT, "_BVTOINT"); 01775 getEM()->newKind(BVTYPEPRED, "_BVTYPEPRED"); 01776 01777 std::vector<int> kinds; 01778 kinds.push_back(BITVECTOR); 01779 kinds.push_back(BVCONST); 01780 kinds.push_back(CONCAT); 01781 kinds.push_back(EXTRACT); 01782 kinds.push_back(BOOLEXTRACT); 01783 kinds.push_back(LEFTSHIFT); 01784 kinds.push_back(CONST_WIDTH_LEFTSHIFT); 01785 kinds.push_back(RIGHTSHIFT); 01786 kinds.push_back(BVSHL); 01787 kinds.push_back(BVLSHR); 01788 kinds.push_back(BVASHR); 01789 kinds.push_back(SX); 01790 kinds.push_back(BVREPEAT); 01791 kinds.push_back(BVZEROEXTEND); 01792 kinds.push_back(BVROTL); 01793 kinds.push_back(BVROTR); 01794 kinds.push_back(BVAND); 01795 kinds.push_back(BVOR); 01796 kinds.push_back(BVXOR); 01797 kinds.push_back(BVXNOR); 01798 kinds.push_back(BVNEG); 01799 kinds.push_back(BVNAND); 01800 kinds.push_back(BVNOR); 01801 kinds.push_back(BVCOMP); 01802 kinds.push_back(BVUMINUS); 01803 kinds.push_back(BVPLUS); 01804 kinds.push_back(BVSUB); 01805 kinds.push_back(BVMULT); 01806 kinds.push_back(BVUDIV); 01807 kinds.push_back(BVSDIV); 01808 kinds.push_back(BVUREM); 01809 kinds.push_back(BVSREM); 01810 kinds.push_back(BVSMOD); 01811 kinds.push_back(BVLT); 01812 kinds.push_back(BVLE); 01813 kinds.push_back(BVGT); 01814 kinds.push_back(BVGE); 01815 kinds.push_back(BVSLT); 01816 kinds.push_back(BVSLE); 01817 kinds.push_back(BVSGT); 01818 kinds.push_back(BVSGE); 01819 kinds.push_back(INTTOBV); 01820 kinds.push_back(BVTOINT); 01821 kinds.push_back(BVTYPEPRED); 01822 01823 registerTheory(this, kinds); 01824 01825 d_bvConstExprIndex = getEM()->registerSubclass(sizeof(BVConstExpr)); 01826 01827 // Cache constants 0bin0 and 0bin1 01828 vector<bool> bits(1); 01829 bits[0]=false; 01830 d_bvZero = newBVConstExpr(bits); 01831 bits[0]=true; 01832 d_bvOne = newBVConstExpr(bits); 01833 01834 // Instantiate the rules after all expression creation is 01835 // registered, since the constructor creates some bit-vector 01836 // expressions. 01837 d_rules = createProofRules(); 01838 } 01839 01840 01841 // Destructor: delete the proof rules class if it's present 01842 TheoryBitvector::~TheoryBitvector() { 01843 if(d_rules != NULL) delete d_rules; 01844 } 01845 01846 01847 // Main theory API 01848 01849 01850 void TheoryBitvector::addSharedTerm(const Expr& e) 01851 { 01852 } 01853 01854 01855 /*Modified by Lorenzo PLatania*/ 01856 01857 // solvable fact (e.g. solvable equations) are added to d_eq CDList, 01858 // all the others have to be in a different CDList. If the equation is 01859 // solvable it comes here already solved. Should distinguish between 01860 // solved and not solved eqs 01861 void TheoryBitvector::assertFact(const Theorem& e) 01862 { 01863 const Expr& expr = e.getExpr(); 01864 TRACE("bvAssertFact", "TheoryBitvector::assertFact(", e.getExpr().toString(), ")"); 01865 // cout<<"TheoryBitvector::assertFact, expr: "<<expr.toString()<<endl; 01866 // every time a new fact is added to the list the whole set may be 01867 // not in a solved form 01868 01869 switch (expr.getOpKind()) { 01870 01871 case BVTYPEPRED: 01872 assertTypePred(expr[0], e); 01873 break; 01874 01875 case BOOLEXTRACT: 01876 // facts form the SAT solver are just ignored 01877 return; 01878 01879 case NOT: 01880 // facts form the SAT solver are just ignored 01881 if (expr[0].getOpKind() == BOOLEXTRACT) return; 01882 01883 if (expr[0].getOpKind() == BVTYPEPRED) { 01884 Expr tpExpr = getTypePredExpr(expr[0]); 01885 Theorem tpThm = typePred(tpExpr); 01886 DebugAssert(tpThm.getExpr() == expr[0], "Expected BVTYPEPRED theorem"); 01887 setInconsistent(getCommonRules()->contradictionRule(tpThm, e)); 01888 return; 01889 } 01890 01891 DebugAssert(expr[0].isEq(), "Unexpected negation"); 01892 01893 d_bitblast.push_back(e); 01894 break; 01895 01896 case EQ: 01897 // Updates are also ignored: 01898 // Note: this can only be true if this fact was asserted as a result of 01899 // assertEqualities. For BV theory, this should only be possible if 01900 // the update was made from our own theory, so we can ignore it. 01901 if (theoryCore()->inUpdate()) return; 01902 01903 // If we have already started bitblasting, just store the eq in d_bitblast; 01904 // if we haven't yet bitblasted and expr is a solved linear equation then 01905 // we store it in d_eq CDList, otherwise we store it in d_eqPending 01906 if (d_bb_index != 0) { 01907 d_bitblast.push_back(e); 01908 } 01909 else if (isLeaf(expr[0]) && !isLeafIn(expr[0], expr[1])) { 01910 d_eq.push_back( e ); 01911 } 01912 else { 01913 d_eqPending.push_back( e ); 01914 } 01915 break; 01916 01917 default: 01918 // if the fact is not an equation it will be bit-blasted 01919 d_bitblast.push_back( e ); 01920 break; 01921 } 01922 } 01923 01924 01925 //TODO: can we get rid of this in exchange for a more general politeness-based sharing mechanism? 01926 void TheoryBitvector::assertTypePred(const Expr& e, const Theorem& pred) { 01927 // Ignore bitvector constants (they always satisfy type predicates) 01928 // and bitvector operators. When rewrites and updates are enabled. 01929 // their type predicates will be implicitly derived from the type 01930 // predicates of the arguments. 01931 01932 if (theoryOf(e) == this) return; 01933 TRACE("bvAssertTypePred", "TheoryBitvector::assertTypePred(", e.toString(PRESENTATION_LANG), ")"); 01934 addSharedTerm(e); 01935 } 01936 01937 01938 /*Beginning of Lorenzo PLatania's methods*/ 01939 01940 // evaluates the gcd of two integers using 01941 // Euclid algorithm 01942 // int TheoryBitvector::gcd(int c1, int c2) 01943 // { 01944 // if(c2==0) 01945 // return c1; 01946 // else 01947 // return gcd( c2, c1%c2); 01948 // } 01949 01950 void TheoryBitvector::extract_vars(const Expr& e, vector<Expr>& result) 01951 { 01952 if (e.getOpKind() == BVMULT ) { 01953 extract_vars(e[0], result); 01954 extract_vars(e[1], result); 01955 } 01956 else { 01957 DebugAssert(e.getOpKind() != BVCONST && 01958 e.getOpKind() != BVUMINUS && 01959 e.getOpKind() != BVPLUS, "Unexpected structure"); 01960 result.push_back(e); 01961 } 01962 } 01963 01964 01965 Expr TheoryBitvector::multiply_coeff( Rational mult_inv, const Expr& e) 01966 { 01967 01968 // nothing to be done 01969 if( mult_inv == 1) 01970 return e; 01971 if(e.isEq()) 01972 { 01973 Expr lhs = e[0]; 01974 Expr rhs = e[1]; 01975 Expr new_lhs = multiply_coeff( mult_inv, lhs); 01976 Expr new_rhs = multiply_coeff( mult_inv, rhs); 01977 Expr res(EQ, new_lhs, new_rhs); 01978 return res; 01979 } 01980 else 01981 { 01982 int kind = e.getOpKind(); 01983 int size = BVSize(e); 01984 if( kind == BVMULT ) 01985 { 01986 01987 //lhs is like 'a_0*x_0' 01988 Rational new_coeff = mult_inv * computeBVConst( e[0] ); 01989 Expr new_expr_coeff = newBVConstExpr( new_coeff, size); 01990 Expr BV_one = newBVConstExpr(1,size); 01991 if( new_expr_coeff == BV_one ) 01992 { 01993 return e[1]; 01994 } 01995 else 01996 { 01997 return newBVMultExpr( size, new_expr_coeff, e[1]); 01998 } 01999 } 02000 else 02001 if( kind == BVPLUS) 02002 { 02003 02004 int expr_arity= e.arity(); 02005 std::vector<Expr> tmp_list; 02006 for( int i = 0; i < expr_arity; ++i) 02007 { 02008 tmp_list.push_back(multiply_coeff( mult_inv, e[i])); 02009 } 02010 // Expr::iterator i = e.begin(); 02011 // int index; 02012 // Expr::iterator end = e.end(); 02013 // std::vector<Expr> tmp_list; 02014 // for( i = e.begin(), index=0; i!=end; ++i, ++index) 02015 // { 02016 // tmp_list.push_back(multiply_coeff( mult_inv, *i)); 02017 // } 02018 return newBVPlusExpr(size, tmp_list); 02019 } 02020 else 02021 if( kind == BVCONST ) 02022 { 02023 02024 Rational new_const = mult_inv * computeBVConst(e); 02025 Expr res = newBVConstExpr( new_const, size); 02026 // cout<<res.toString()+"\n"; 02027 return res; 02028 } 02029 else 02030 if( isLeaf( e ) ) 02031 { 02032 //lhs is like 'x_0' 02033 // need to know the lenght of the var 02034 // L:: guess it is not correct, mult_inv * e 02035 Expr BV_mult_inv = newBVConstExpr( mult_inv, size); 02036 Expr new_var = newBVMultExpr( size, BV_mult_inv, e); 02037 02038 return new_var; 02039 } 02040 else 02041 { 02042 return e; 02043 } 02044 } 02045 } 02046 02047 // L::return the index of the minimum element returns -1 if the list 02048 // is empty assuming only non-negative elements to be sostituted with 02049 // some debug assertion. ***I guess n_bits can be just an integer, no 02050 // need to declare it as a Rational 02051 02052 Rational TheoryBitvector::multiplicative_inverse(Rational r, int n_bits) 02053 { 02054 02055 // cout<<"TheoryBitvector::multiplicative_inverse: working on "<<r.toString()<<endl; 02056 Rational i=r; 02057 Rational max_val= pow( n_bits, (Rational) 2); 02058 while(r!=1) 02059 { 02060 r = ( r*r ) % max_val; 02061 i = ( i*r ) % max_val; 02062 } 02063 // cout<<"TheoryBitvector::multiplicative_inverse: result is "<<i.toString()<<endl; 02064 return i; 02065 } 02066 02067 // int TheoryBitvector::min(std::vector<Rational> list) 02068 // { 02069 // int res = 0; 02070 // int i; 02071 // int size = list.size(); 02072 // for(i = 0; i < size; ++i) 02073 // { 02074 // cout<<"list["<<i<<"]: "<<list[i]<<endl; 02075 // } 02076 // for(i = 1; i < size; ++i) 02077 // { 02078 // if(list[res]>list[i]) 02079 // res=i; 02080 // cout<<"res: "<<res<<endl; 02081 // cout<<"min: "<<list[res]<<endl; 02082 // } 02083 02084 // cout<<"min: "<<res<<endl; 02085 // return res; 02086 // } 02087 02088 //*************************** 02089 // ecco come fare il delete! 02090 //*************************** 02091 02092 // int main () 02093 // { 02094 // unsigned int i; 02095 // deque<unsigned int> mydeque; 02096 02097 // // set some values (from 1 to 10) 02098 // for (i=1; i<=10; i++) mydeque.push_back(i); 02099 02100 // // erase the 6th element 02101 // mydeque.erase (mydeque.begin()+5); 02102 02103 // // erase the first 3 elements: 02104 // mydeque.erase (mydeque.begin(),mydeque.begin()+3); 02105 02106 // cout << "mydeque contains:"; 02107 // for (i=0; i<mydeque.size(); i++) 02108 // cout << " " << mydeque[i]; 02109 // cout << endl; 02110 02111 // return 0; 02112 // } 02113 02114 // use the method in rational.h 02115 // it uses std::vector<Rational> instead of std::deque<int> 02116 // int TheoryBitvector::gcd(std::deque<int> coeff_list) 02117 // { 02118 02119 // cout<<"TheoryBitvector::gcd: begin\n"; 02120 // for(unsigned int i=0; i<coeff_list.size(); ++i) 02121 // { 02122 // cout<<"coeff_list["<<i<<"]: "<<coeff_list[i]<<endl; 02123 // } 02124 // int gcd_list; 02125 // int min_index = min(coeff_list); 02126 // int min_coeff_1 = coeff_list[min_index]; 02127 // cout<<"erasing element: "<<coeff_list[min_index]; 02128 // coeff_list.erase( coeff_list.begin() + min_index ); 02129 02130 // while(coeff_list.size()>0) 02131 // { 02132 // min_index = min(coeff_list); 02133 // int min_coeff_2 = coeff_list[min_index]; 02134 // cout<<"erasing element: "<<coeff_list[min_index]; 02135 // coeff_list.erase( coeff_list.begin() + min_index ); 02136 02137 // // save one recursion 02138 // gcd_list = gcd( min_coeff_2, min_coeff_1); 02139 // cout<<"TheoryBitvector::gcd: erased min1\n"; 02140 // min_coeff_1 = gcd_list; 02141 // } 02142 // cout<<"gcd_list: "<<gcd_list<<endl; 02143 // return gcd_list; 02144 // } 02145 02146 // int TheoryBitvector::bv2int(const Expr& e) 02147 // { 02148 // int sum=0; 02149 // if(e.arity()==0 && ! e.isVar()) 02150 // { 02151 // std::string tmp = e.toString(); 02152 // int s_length = tmp.length(); 02153 // int bit; 02154 // int exp; 02155 // // first 4 cells contains the bv prefix 0bin 02156 // // just discard them 02157 // for(int i=3; i < s_length; ++i) 02158 // { 02159 // if(tmp[i]=='1') 02160 // { 02161 // sum += (int)std::pow((float) 2, s_length - 1 - i); 02162 // } 02163 // } 02164 // } 02165 // else 02166 // { 02167 // cerr<<"error: non-constant to be converted\n"; 02168 // } 02169 // return sum; 02170 // } 02171 02172 // returning the position of the first odd coefficient found; 02173 // moreover, it multiplies a variable which does not appear in other 02174 // subterms. It assumes that the input expression has already been 02175 // canonized, so the lhs is a flat BVPLUS expression and the rhs is a 02176 // zero BVCONST 02177 02178 Rational TheoryBitvector::Odd_coeff( const Expr& e ) 02179 { 02180 int bv_size = BVSize(e[0]); 02181 Expr bv_zero( newBVZeroString(bv_size)); 02182 02183 DebugAssert(e.getOpKind()==EQ && e[1] == bv_zero, 02184 "TheoryBitvector::Odd_coeff: the input expression has a non valid form "); 02185 02186 Expr lhs = e[0]; 02187 if( lhs.getOpKind() == BVMULT ) 02188 { 02189 if( lhs[0].getOpKind() == BVCONST && computeBVConst( lhs[0]) % 2 != 0) 02190 return computeBVConst( lhs[0] ); 02191 } 02192 else 02193 if( isLeaf( lhs)) 02194 return 1; 02195 else 02196 if( lhs.getOpKind() == BVPLUS ) 02197 { 02198 int lhs_arity = lhs.arity(); 02199 // scanning lhs in order to find a good odd coefficient 02200 for( int i = 0; i < lhs_arity; ++i) 02201 { 02202 // checking that the subterm is a leaf 02203 if( isLeaf( lhs[i] ) ) 02204 { 02205 // checking that the current subterm does not appear in other 02206 // subterms 02207 for( int j = 0; j < lhs_arity; ++j) 02208 if( j != i && !isLeafIn( lhs[i], lhs[j] )) 02209 return 1; 02210 } 02211 else 02212 if( lhs[i].getOpKind() == BVMULT) 02213 { 02214 // the subterm is a BVMULT with a odd coefficient 02215 if( lhs[i][0].getOpKind() == BVCONST && computeBVConst( lhs[i][0]) % 2 != 0) 02216 { 02217 // checking that the current subterm does not appear in other 02218 // subterms 02219 int flag = 0; 02220 for( int j = 0; j < lhs_arity; ++j) 02221 { 02222 // as we can solve also for non-leaf terms we use 02223 // isTermIn instead of isLeafIn 02224 if( j != i && isTermIn( lhs[i][1], lhs[j] )) 02225 flag = 1; 02226 } 02227 // if the leaf is not a subterm of other terms in the 02228 // current expression then we can solve for it 02229 if( flag == 0) 02230 return computeBVConst( lhs[i][0] ); 02231 } 02232 } 02233 else 02234 // the subterm is a non-linear one 02235 if ( lhs[i].getOpKind() != BVCONST ) 02236 { 02237 // checking that the current subterm does not appear in other 02238 // subterms 02239 for( int j = 0; j < lhs_arity; ++j) 02240 if( j != i && !isLeafIn( lhs[i][1], lhs[j] )) 02241 return 1; 02242 } 02243 else 02244 ; 02245 } 02246 } 02247 // no leaf found to solve for 02248 return 0; 02249 } 02250 02251 int TheoryBitvector::check_linear( const Expr &e ) 02252 { 02253 TRACE("bv_check_linear", "TheoryBitvector::check_linear(", e.toString(PRESENTATION_LANG), ")"); 02254 // recursively check if the expression is linear 02255 if( e.isVar() || e.getOpKind() == BVCONST ) 02256 return 1; 02257 else 02258 if( e.getOpKind() == BVPLUS ) 02259 { 02260 int e_arity= e.arity(); 02261 int flag = 1; 02262 for( int i=0; i < e_arity && flag == 1; ++i) 02263 { 02264 flag = check_linear( e[i]); 02265 } 02266 return flag; 02267 } 02268 else 02269 if( e.getOpKind() == BVMULT) 02270 { 02271 if( e[0].getOpKind() == BVCONST && e[1].isVar() ) 02272 return 1; 02273 else 02274 return 0; 02275 } 02276 else 02277 if( e.getOpKind() == BVUMINUS) 02278 return check_linear( e[0]); 02279 else 02280 if( e.getOpKind() == EQ ) 02281 return ( check_linear( e[0] ) && check_linear( e[1] )); 02282 else 02283 // all other operators are non-linear 02284 return 0; 02285 } 02286 02287 // please check it is right. It is the same as Theory::isLeafIn but it 02288 // does not require e1 to be a leaf. In this way we can check for e1 02289 // to be a subterm of other expressions even if it is not a leaf, 02290 // i.e. a non-linear term 02291 bool TheoryBitvector::isTermIn(const Expr& e1, const Expr& e2) 02292 { 02293 if (e1 == e2) return true; 02294 if (theoryOf(e2) != this) return false; 02295 for(Expr::iterator i=e2.begin(), iend=e2.end(); i != iend; ++i) 02296 if (isTermIn(e1, *i)) return true; 02297 return false; 02298 } 02299 02300 // checks whether e can be solved in term 02301 bool TheoryBitvector::canSolveFor( const Expr& term, const Expr& e ) 02302 { 02303 DebugAssert( e.getOpKind() == EQ, "TheoryBitvector::canSolveFor, input 'e' must be an equation"); 02304 02305 // cout<<"TheoryBitvector::canSolveFor, term: "<<term.toString()<<endl; 02306 // the term has not a unary coefficient, so we did not multiply the 02307 // equation by its multiplicative inverse 02308 if( term.getOpKind() == BVMULT && term[0].getOpKind() == BVCONST) 02309 return 0; 02310 else 02311 if( isLeaf( term ) || !isLinearTerm( term)) 02312 { 02313 int count = countTermIn( term, e); 02314 // cout<<"TheoryBitvector::canSolveFor, count for "<<term.toString()<<" is: "<<count<<endl; 02315 if( count == 1) 02316 return true; 02317 else 02318 return false; 02319 } 02320 else 02321 { 02322 DebugAssert( false, "TheoryBitvector::canSolveFor, input 'term' of not treated kind"); 02323 return false; 02324 } 02325 } 02326 02327 int TheoryBitvector::countTermIn( const Expr& term, const Expr& e) 02328 { 02329 // cout<<"TheoryBitvector::countTermIn, term: "<<term.toString()<<" e: "<<e.toString()<<endl; 02330 int e_arity = e.arity(); 02331 int result = 0; 02332 // base cases recursion happen when e is a constant or a leaf 02333 if( e.getOpKind() == BVCONST ) 02334 return 0; 02335 if( term == e ) 02336 return 1; 02337 02338 for( int i = 0; i < e_arity; ++i) 02339 { 02340 result += countTermIn( term, e[i]); 02341 } 02342 return result; 02343 } 02344 02345 bool TheoryBitvector::isLinearTerm( const Expr& e ) 02346 { 02347 if( isLeaf( e ) ) 02348 return true; 02349 switch( e.getOpKind()) 02350 { 02351 case BVPLUS: 02352 return true; 02353 case BVMULT: 02354 if( e[0].getOpKind() == BVCONST && isLinearTerm( e[1] )) 02355 return true; 02356 else 02357 return false; 02358 break; 02359 default: 02360 return false; 02361 } 02362 } 02363 02364 02365 // returns thm if no change 02366 Theorem TheoryBitvector::simplifyPendingEq(const Theorem& thm, int maxEffort) 02367 { 02368 Expr e = thm.getExpr(); 02369 DebugAssert(e.getKind() == EQ, "Expected EQ"); 02370 Expr lhs = e[0]; 02371 Expr rhs = e[1]; 02372 02373 Theorem thm2 = thm; 02374 if (!isLeaf(lhs)) { 02375 // Carefully simplify lhs: 02376 // We can't take find(lhs) because find(lhs) = find(rhs) and this would result in a trivially true equation. 02377 // So, take the find of the children instead. 02378 int ar = lhs.arity(); 02379 vector<Theorem> newChildrenThm; 02380 vector<unsigned> changed; 02381 Theorem thm0; 02382 for (int k = 0; k < ar; ++k) { 02383 thm0 = find(lhs[k]); 02384 if (thm0.getLHS() != thm0.getRHS()) { 02385 newChildrenThm.push_back(thm0); 02386 changed.push_back(k); 02387 } 02388 } 02389 if(changed.size() > 0) { 02390 // lhs = updated_lhs 02391 thm0 = substitutivityRule(lhs, changed, newChildrenThm); 02392 // lhs = updated_and_rewritten_lhs 02393 thm0 = transitivityRule(thm0, rewrite(thm0.getRHS())); 02394 // updated_and_rewritten_lhs = rhs 02395 thm2 = transitivityRule(symmetryRule(thm0), thm); 02396 } 02397 } 02398 // updated_and_rewritten_lhs = find(rhs) 02399 thm2 = transitivityRule(thm2, find(rhs)); 02400 // canonized EQ 02401 thm2 = iffMP(thm2, d_rules->canonBVEQ(thm2.getExpr(), maxEffort)); 02402 if (thm2.isRewrite() && thm2.getRHS() == lhs && thm2.getLHS() == rhs) { 02403 thm2 = thm; 02404 } 02405 return thm2; 02406 } 02407 02408 02409 Theorem TheoryBitvector::generalBitBlast( const Theorem& thm ) 02410 { 02411 // cout<<"TheoryBitvector::generalBitBlast, thm: "<<thm.toString()<<" to expr(): "<<thm.getExpr().toString()<<endl; 02412 Expr e = thm.getExpr(); 02413 switch (e.getOpKind()) { 02414 case EQ: { 02415 Theorem thm2 = simplifyPendingEq(thm, 6); 02416 const Expr& e2 = thm2.getExpr(); 02417 switch (e2.getKind()) { 02418 case TRUE_EXPR: 02419 case FALSE_EXPR: 02420 return thm2; 02421 case EQ: 02422 return iffMP(thm2, bitBlastEqn(thm2.getExpr())); 02423 case AND: { 02424 DebugAssert(e2.arity() == 2 && e2[0].getKind() == EQ && e2[1].getKind() == EQ, 02425 "Expected two equations"); 02426 Theorem t1 = bitBlastEqn(e2[0]); 02427 Theorem t2 = bitBlastEqn(e2[1]); 02428 Theorem thm3 = substitutivityRule(e2, t1, t2); 02429 return iffMP(thm2, thm3); 02430 } 02431 default: 02432 FatalAssert(false, "Unexpected Expr"); 02433 break; 02434 } 02435 break; 02436 } 02437 case BVLT: 02438 case BVLE: { 02439 // Carefully simplify 02440 int ar = e.arity(); 02441 DebugAssert(ar == 2, "Expected arity 2"); 02442 vector<Theorem> newChildrenThm; 02443 vector<unsigned> changed; 02444 Theorem thm0; 02445 for (int k = 0; k < ar; ++k) { 02446 thm0 = find(e[k]); 02447 if (thm0.getLHS() != thm0.getRHS()) { 02448 newChildrenThm.push_back(thm0); 02449 changed.push_back(k); 02450 } 02451 } 02452 if(changed.size() > 0) { 02453 // updated_e 02454 thm0 = iffMP(thm, substitutivityRule(e, changed, newChildrenThm)); 02455 // updated_and_rewritten_e 02456 thm0 = iffMP(thm0, rewrite(thm0.getExpr())); 02457 if (thm0.getExpr().getOpKind() != e.getOpKind()) return thm0; 02458 return iffMP(thm0, bitBlastIneqn(thm0.getExpr())); 02459 } 02460 return iffMP(thm, bitBlastIneqn(e)); 02461 } 02462 // a NOT should mean a disequality, as negation of inequalities 02463 // can be expressed as other inequalities. 02464 case NOT: { 02465 // Carefully simplify 02466 DebugAssert(e.arity() == 1, "Expected arity 1"); 02467 DebugAssert(e[0].isEq(), "Expected disequality"); 02468 DebugAssert(e[0].arity() == 2, "Expected arity 2"); 02469 vector<Theorem> newChildrenThm; 02470 vector<unsigned> changed; 02471 Theorem thm0; 02472 for (int k = 0; k < 2; ++k) { 02473 thm0 = find(e[0][k]); 02474 if (thm0.getLHS() != thm0.getRHS()) { 02475 newChildrenThm.push_back(thm0); 02476 changed.push_back(k); 02477 } 02478 } 02479 if(changed.size() > 0) { 02480 // a = b <=> a' = b' 02481 thm0 = substitutivityRule(e[0], changed, newChildrenThm); 02482 } 02483 else thm0 = reflexivityRule(e[0]); 02484 // a = b <=> canonized EQ 02485 thm0 = transitivityRule(thm0, d_rules->canonBVEQ(thm0.getRHS(), 6)); 02486 // NOT(canonized EQ) 02487 thm0 = iffMP(thm, substitutivityRule(e, thm0)); 02488 if (thm0.getExpr()[0].isEq()) { 02489 return bitBlastDisEqn(thm0); 02490 } 02491 else return thm0; 02492 } 02493 default: 02494 FatalAssert(false, "TheoryBitvector::generalBitBlast: unknown expression kind"); 02495 break; 02496 } 02497 return reflexivityRule( e ); 02498 } 02499 /*End of Lorenzo PLatania's methods*/ 02500 02501 static Expr findAtom(const Expr& e) 02502 { 02503 if (e.isAbsAtomicFormula()) return e; 02504 for (int i = 0; i < e.arity(); ++i) { 02505 Expr e_i = findAtom(e[i]); 02506 if (!e_i.isNull()) return e_i; 02507 } 02508 return Expr(); 02509 } 02510 02511 02512 bool TheoryBitvector::comparebv(const Expr& e1, const Expr& e2) 02513 { 02514 int size = BVSize(e1); 02515 FatalAssert(size == BVSize(e2), "expected same size"); 02516 Theorem c1, c2; 02517 int idx1 = -1; 02518 vector<Theorem> thms1; 02519 02520 if (d_bb_index == 0) { 02521 Expr splitter = e1.eqExpr(e2); 02522 Theorem thm = simplify(splitter); 02523 if (!thm.getRHS().isBoolConst()) { 02524 addSplitter(e1.eqExpr(e2)); 02525 return true; 02526 } 02527 // Store a dummy theorem to indicate bitblasting has begun 02528 d_bb_index = 1; 02529 d_bitblast.push_back(getCommonRules()->trueTheorem()); 02530 } 02531 02532 for (int i = 0; i < size; ++i) { 02533 c1 = bitBlastTerm(e1, i); 02534 c1 = transitivityRule(c1, simplify(c1.getRHS())); 02535 c2 = bitBlastTerm(e2, i); 02536 c2 = transitivityRule(c2, simplify(c2.getRHS())); 02537 thms1.push_back(c1); 02538 if (!c1.getRHS().isBoolConst()) { 02539 if (idx1 == -1) idx1 = i; 02540 continue; 02541 } 02542 if (!c2.getRHS().isBoolConst()) { 02543 continue; 02544 } 02545 if (c1.getRHS() != c2.getRHS()) return false; 02546 } 02547 if (idx1 == -1) { 02548 // If e1 is known to be a constant, assert that 02549 DebugAssert(e1.getKind() != BVCONST, "Expected non-const"); 02550 assertEqualities(d_rules->bitExtractAllToConstEq(thms1)); 02551 addSplitter(e1.eqExpr(e2)); 02552 // enqueueFact(getCommonRules()->trueTheorem()); 02553 return true; 02554 } 02555 02556 Theorem thm = bitBlastEqn(e1.eqExpr(e2)); 02557 thm = iffMP(thm, simplify(thm.getExpr())); 02558 if (!thm.getExpr().isTrue()) { 02559 enqueueFact(thm); 02560 return true; 02561 } 02562 02563 // Nothing to assert from bitblasted equation. Best way to resolve this 02564 // problem is to split until the term can be equated with a bitvector 02565 // constant. 02566 Expr e = findAtom(thms1[idx1].getRHS()); 02567 DebugAssert(!e.isNull(), "Expected atom"); 02568 addSplitter(e); 02569 return true; 02570 } 02571 02572 static bool bvdump = false; 02573 02574 void TheoryBitvector::checkSat(bool fullEffort) 02575 { 02576 if(fullEffort) { 02577 02578 for (unsigned i = 0; i < additionalRewriteConstraints.size(); i ++) 02579 enqueueFact(additionalRewriteConstraints[i]); 02580 additionalRewriteConstraints.clear(); 02581 02582 if (bvdump) { 02583 CDList<Theorem>::const_iterator it_list=d_eq.begin(); 02584 unsigned int i; 02585 for(i=0; i<d_eq.size(); ++i) 02586 { 02587 cout<<"d_eq [" << i << "]= "<< it_list[i].getExpr().toString() << endl; 02588 } 02589 02590 it_list=d_eqPending.begin(); 02591 02592 for(i=0; i<d_eqPending.size(); ++i) 02593 { 02594 cout<<"d_eqPending [" << i << "]= "<< it_list[i].getExpr().toString() << endl; 02595 } 02596 02597 it_list=d_bitblast.begin(); 02598 02599 for(i=0; i<d_bitblast.size(); ++i) 02600 { 02601 cout<<"d_bitblast [" << i << "]= "<< it_list[i].getExpr().toString() << endl; 02602 } 02603 02604 if (d_eq.size() || d_eqPending.size() || d_bitblast.size()) cout << endl; 02605 } 02606 02607 unsigned eq_list_size = d_eqPending.size(); 02608 bool bitBlastEq = d_eq_index < eq_list_size; 02609 if (d_bb_index == 0 && bitBlastEq) { 02610 bitBlastEq = false; 02611 unsigned eqIdx = d_eq_index; 02612 for(; eqIdx < eq_list_size; ++eqIdx) { 02613 Expr eq = d_eqPending[eqIdx].getExpr(); 02614 DebugAssert(eq[1] == newBVConstExpr(Rational(0), BVSize(eq[0])), "Expected 0 on rhs"); 02615 Theorem thm = simplifyPendingEq(d_eqPending[eqIdx], 5); 02616 if (thm == d_eqPending[eqIdx]) { 02617 bitBlastEq = true; 02618 continue; 02619 } 02620 const Expr& e2 = thm.getExpr(); 02621 switch (e2.getKind()) { 02622 case TRUE_EXPR: 02623 break; 02624 case FALSE_EXPR: 02625 enqueueFact(thm); 02626 return; 02627 case EQ: 02628 case AND: 02629 if (simplify(thm.getExpr()).getRHS() == trueExpr()) { 02630 bitBlastEq = true; 02631 break; 02632 } 02633 for (; d_eq_index < eqIdx; d_eq_index = d_eq_index + 1) { 02634 d_eqPending.push_back(d_eqPending[d_eq_index]); 02635 } 02636 d_eq_index = d_eq_index + 1; 02637 enqueueFact(thm); 02638 return; 02639 default: 02640 FatalAssert(false, "Unexpected expr"); 02641 break; 02642 } 02643 } 02644 } 02645 02646 // Bitblast any new formulas 02647 unsigned bb_list_size = d_bitblast.size(); 02648 bool bbflag = d_bb_index < bb_list_size || bitBlastEq; 02649 if (bbflag) { 02650 for( ; d_bb_index < bb_list_size; d_bb_index = d_bb_index + 1) { 02651 Theorem bb_result = generalBitBlast( d_bitblast[ d_bb_index ]); 02652 enqueueFact( bb_result); 02653 } 02654 if (d_bb_index == 0) { 02655 // push dummy on the stack to indicate bitblasting has started 02656 d_bb_index = 1; 02657 d_bitblast.push_back(getCommonRules()->trueTheorem()); 02658 } 02659 for( ; d_eq_index < eq_list_size; d_eq_index = d_eq_index + 1) { 02660 Theorem bb_result = generalBitBlast( d_eqPending[ d_eq_index ]); 02661 enqueueFact( bb_result); 02662 } 02663 // If newly bitblasted formulas, skip the shared term check 02664 return; 02665 } 02666 } 02667 } 02668 02669 02670 Theorem TheoryBitvector::rewrite(const Expr& e) 02671 { 02672 ExprMap<Theorem> cache; 02673 return rewriteBV(e, cache); 02674 } 02675 02676 02677 Theorem TheoryBitvector::rewriteAtomic(const Expr& e) 02678 { 02679 return reflexivityRule(e); 02680 } 02681 02682 02683 void TheoryBitvector::setup(const Expr& e) 02684 { 02685 int k(0), ar(e.arity()); 02686 if( e.isTerm() ) { 02687 for ( ; k < ar; ++k) { 02688 e[k].addToNotify(this, e); 02689 } 02690 } 02691 } 02692 02693 02694 // Lorenzo's version 02695 void TheoryBitvector::update(const Theorem& e, const Expr& d) { 02696 02697 if (inconsistent()) return; 02698 // cout<<"TheoryBitvector::update, theorem e:"<<e.toString()<<" expression d: "<<d.toString()<<endl; 02699 // Updating shared terms informations, code inherited from the old 02700 // version of the bitvector theory 02701 02702 // Constants should never change their find pointers to non-constant 02703 // expressions 02704 DebugAssert(e.getLHS().getOpKind()!=BVCONST, 02705 "TheoryBitvector::update(e="+e.getExpr().toString() 02706 +", d="+d.toString()); 02707 if (d.isNull()) { 02708 Expr lhs = e.getLHS(); 02709 Expr rhs = e.getRHS(); 02710 DebugAssert(d_sharedSubterms.find(lhs) != d_sharedSubterms.end(), 02711 "Expected lhs to be shared"); 02712 CDMap<Expr,Expr>::iterator it = d_sharedSubterms.find(rhs); 02713 if (it == d_sharedSubterms.end()) { 02714 addSharedTerm(rhs); 02715 } 02716 return; 02717 } 02718 // { 02719 // // found an equality between shared subterms! 02720 // bool changed = false; 02721 // if ((*it).second != lhs) { 02722 // lhs = (*it).second; 02723 // it = d_sharedSubterms.find(lhs); 02724 // DebugAssert(it != d_sharedSubterms.end() && (*it).second == lhs, 02725 // "Invariant violated in TheoryBitvector::update"); 02726 // changed = true; 02727 // } 02728 // if ((*it2).second != rhs) { 02729 // rhs = (*it2).second; 02730 // it2 = d_sharedSubterms.find(rhs); 02731 // DebugAssert(it2 != d_sharedSubterms.end() && (*it2).second == rhs, 02732 // "Invariant violated in TheoryBitvector::update"); 02733 // changed = true; 02734 // } 02735 // DebugAssert(findExpr(lhs) == e.getRHS() && 02736 // findExpr(rhs) == e.getRHS(), "Unexpected value for finds"); 02737 // // It may be needed to check whether the two terms are the 02738 // // same, in that case don't do anything 02739 // if (changed) { 02740 // Theorem thm = transitivityRule(find(lhs),symmetryRule(find(rhs))); 02741 // const Expr& expr = thm.getExpr(); 02742 02743 // if (d_bb_index == 0 && 02744 // isLeaf(expr[0]) && !isLeafIn(expr[0], expr[1])) { 02745 // d_eq.push_back( thm ); 02746 // } 02747 // else { 02748 // d_bitblast.push_back( thm ); 02749 // } 02750 // } 02751 02752 02753 // // canonize and solve befor asserting it 02754 // // cout<<"TheoryBitvector::update, thm.getRHS(): "<<thm.getRHS()<<" thm.getLHS():"<<thm.getLHS()<<" thm.getExpr():"<<thm.getExpr()<<endl; 02755 // Theorem rwt_thm = rewrite( thm.getExpr() ); 02756 // Theorem solved_thm = solve( rwt_thm); 02757 // assertFact( solved_thm ); 02758 // assertFact( thm ); 02759 // enqueueFact(iffMP(thm, bitBlastEqn(thm.getExpr()))); 02760 // } 02761 // else 02762 // { 02763 // d_sharedSubterms[rhs] = (*it).second; 02764 // } 02765 // } 02766 // Propagate the "find" information to all the terms in the notify 02767 // list of d 02768 02769 // if d has no find there is nothing to be updated 02770 if (!d.hasFind()) return; 02771 02772 if (find(d).getRHS() == d) { 02773 // Theorem thm = updateSubterms(d); 02774 // TRACE("bvupdate", "TheoryArithOld::update(): thm = ", thm, ""); 02775 // DebugAssert(leavesAreSimp(thm.getRHS()), "updateHelper error: " 02776 // +thm.getExpr().toString()); 02777 Theorem thm = simplify(d); 02778 if (thm.getRHS().isAtomic()) { 02779 assertEqualities(thm); 02780 } 02781 else { 02782 // Simplify could introduce case splits in the expression. Handle this by renaminig 02783 Theorem renameTheorem = renameExpr(d); 02784 enqueueFact(transitivityRule(symmetryRule(renameTheorem), thm)); 02785 assertEqualities(renameTheorem); 02786 } 02787 } 02788 } 02789 02790 02791 Theorem TheoryBitvector::updateSubterms( const Expr& e ) 02792 { 02793 // DebugAssert(canonRec(e).getRHS() == e, "canonSimp expects input to be canonized"); 02794 int ar = e.arity(); 02795 if (isLeaf(e)) return find(e); 02796 if (ar > 0) { 02797 vector<Theorem> newChildrenThm; 02798 vector<unsigned> changed; 02799 Theorem thm; 02800 for (int k = 0; k < ar; ++k) { 02801 thm = updateSubterms(e[k]); 02802 if (thm.getLHS() != thm.getRHS()) { 02803 newChildrenThm.push_back(thm); 02804 changed.push_back(k); 02805 } 02806 } 02807 if(changed.size() > 0) { 02808 thm = substitutivityRule(e, changed, newChildrenThm); 02809 thm = transitivityRule(thm, rewrite(thm.getRHS())); 02810 return transitivityRule(thm, find(thm.getRHS())); 02811 } 02812 else return find(e); 02813 } 02814 return find(e); 02815 } 02816 02817 02818 Theorem TheoryBitvector::solve(const Theorem& t) 02819 { 02820 DebugAssert(t.isRewrite() && t.getLHS().isTerm(), ""); 02821 Expr e = t.getExpr(); 02822 02823 if (isLeaf(e[0]) && !isLeafIn(e[0], e[1])) { 02824 // already solved 02825 return t; 02826 } 02827 else if (isLeaf(e[1]) && !isLeafIn(e[1], e[0])) { 02828 return symmetryRule(t); 02829 } 02830 else if (e[0].getOpKind() == EXTRACT && isLeaf(e[0][0])) { 02831 bool solvedForm; 02832 Theorem thm; 02833 if (d_rules->solveExtractOverlapApplies(e)) 02834 { 02835 thm = iffMP(t, d_rules->solveExtractOverlap(e)); 02836 solvedForm = true; 02837 } 02838 else 02839 thm = d_rules->processExtract(t, solvedForm); 02840 02841 thm = getCommonRules()->skolemize(thm); 02842 02843 if (solvedForm) return thm; 02844 else { 02845 enqueueFact(getCommonRules()->andElim(thm, 1)); 02846 return getCommonRules()->andElim(thm, 0); 02847 } 02848 } 02849 else if (e[1].getOpKind() == EXTRACT && isLeaf(e[1][0])) { 02850 bool solvedForm; 02851 Theorem thm = getCommonRules()->skolemize(d_rules->processExtract(symmetryRule(t), solvedForm)); 02852 if (solvedForm) return thm; 02853 else { 02854 enqueueFact(getCommonRules()->andElim(thm, 1)); 02855 return getCommonRules()->andElim(thm, 0); 02856 } 02857 } 02858 02859 IF_DEBUG( 02860 Theorem t2 = iffMP(t, d_rules->canonBVEQ(e)); 02861 if (e[0] < e[1]) { 02862 DebugAssert(e[1].getOpKind() == BVCONST, 02863 "Should be only case when lhs < rhs"); 02864 t2 = symmetryRule(t2); 02865 } 02866 DebugAssert(t2.getExpr() == e, "Expected no change"); 02867 ) 02868 02869 if (e[0].getOpKind() == BVCONST) { 02870 DebugAssert(e[1].getOpKind() != BVCONST, "should not have const = const"); 02871 return symmetryRule(t); 02872 } 02873 return t; 02874 } 02875 02876 // // solving just linear equations; for everything else I just return 02877 // // the same expression 02878 // if( ! e.isEq()) 02879 // { 02880 // return reflexivityRule( e ); 02881 // } 02882 // //the search for the odd coefficient should also check that the 02883 // //multiplied term does not appear in other terms. The coefficient can 02884 // //also multiply a non-linear term 02885 02886 02887 // // L:: look for a odd coefficient, if one, then the eq is solvable 02888 // // and we can find the mult-inverse using Barrett-Dill-Levitt 02889 // Expr lhs = e[0]; 02890 // Expr::iterator it = lhs.begin(), iend = lhs.end(); 02891 // for (; it != iend; ++it) { 02892 // switch ((*it).getOpKind()) { 02893 // case BVCONST: continue; 02894 // case BVMULT: { 02895 // DebugAssert((*it).arity() == 2 && 02896 // (*it)[0].getOpKind() == BVCONST && 02897 // computeBVConst((*it)[0]) != 1, "Unexpected format"); 02898 // continue 02899 // } 02900 02901 // coefficient = Odd_coeff( e ); 02902 // // Rational odd_coeff = anyOdd( coeff ); 02903 // if( coefficient != 0) 02904 // { 02905 // // the equation is solvable 02906 // cout<<"Odd coefficient found => the equation is solvable\n"; 02907 // if (coefficient != 1) { 02908 // Rational mult_inv = multiplicative_inverse( coefficient, BVSize(e[0])); 02909 // // multiply all the coefficients in the expression by the inverse 02910 // // Expr tmp_expr = e; 02911 // e = multiply_coeff( mult_inv, e); 02912 // // Expr isolated_expr = isolate_var( new_expr); 02913 // } 02914 02915 // Theorem solved_th = d_rules->isolate_var( t, e); 02916 // cout<<"solved theorem: "<<solved_th.toString()<<endl; 02917 // cout<<"solved theorem expr: "<<solved_th.getExpr().toString()<<endl; 02918 02919 // return iffMP( t, solved_th); 02920 // } 02921 // else 02922 // { 02923 // cout<<"Odd coefficient not found => the equation is not solvable\n"; 02924 // Theorem thm = d_rules->MarkNonSolvableEq( e ); 02925 // cout<<"TheoryBitvector::solve, input e: "<<e.toString()<<" thm: "<<thm.toString()<<endl; 02926 // return iffMP( t, thm); 02927 // //return reflexivityRule(e); 02928 // } 02929 //} 02930 02931 02932 void TheoryBitvector::checkType(const Expr& e) 02933 { 02934 switch (e.getOpKind()) { 02935 case BITVECTOR: 02936 //TODO: check that this is a well-formed type 02937 break; 02938 default: 02939 FatalAssert(false, "Unexpected kind in TheoryBitvector::checkType" 02940 +getEM()->getKindName(e.getOpKind())); 02941 } 02942 } 02943 02944 02945 Cardinality TheoryBitvector::finiteTypeInfo(Expr& e, Unsigned& n, 02946 bool enumerate, bool computeSize) 02947 { 02948 FatalAssert(e.getKind() == BITVECTOR, 02949 "Unexpected kind in TheoryBitvector::finiteTypeInfo"); 02950 if (enumerate || computeSize) { 02951 int bitwidth = getBitvectorTypeParam(e); 02952 Rational max_val = pow( bitwidth, (Rational) 2); 02953 02954 if (enumerate) { 02955 if (n < max_val.getUnsigned()) { 02956 e = newBVConstExpr(n, bitwidth); 02957 } 02958 else e = Expr(); 02959 } 02960 02961 if (computeSize) { 02962 n = max_val.getUnsignedMP(); 02963 } 02964 } 02965 return CARD_FINITE; 02966 } 02967 02968 02969 void TheoryBitvector::computeType(const Expr& e) 02970 { 02971 if (e.isApply()) { 02972 switch(e.getOpKind()) { 02973 case BOOLEXTRACT: { 02974 if(!(1 == e.arity() && 02975 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 02976 throw TypecheckException("Type Checking error:"\ 02977 "attempted extraction from non-bitvector \n"+ 02978 e.toString()); 02979 int extractLength = getBoolExtractIndex(e); 02980 if(!(0 <= extractLength)) 02981 throw TypecheckException("Type Checking error: \n" 02982 "attempted out of range extraction \n"+ 02983 e.toString()); 02984 e.setType(boolType()); 02985 break; 02986 } 02987 case BVMULT:{ 02988 if(!(2 == e.arity() && 02989 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() && 02990 BITVECTOR == getBaseType(e[1]).getExpr().getOpKind())) 02991 throw TypecheckException 02992 ("Not a bit-vector expression in BVMULT:\n\n " 02993 +e.toString()); 02994 int bvLen = getBVMultParam(e); 02995 Type bvType = newBitvectorType(bvLen); 02996 e.setType(bvType); 02997 break; 02998 } 02999 case EXTRACT:{ 03000 if(!(1 == e.arity() && 03001 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03002 throw TypecheckException 03003 ("Not a bit-vector expression in bit-vector extraction:\n\n " 03004 + e.toString()); 03005 int bvLength = BVSize(e[0]); 03006 int leftExtract = getExtractHi(e); 03007 int rightExtract = getExtractLow(e); 03008 if(!(0 <= rightExtract && 03009 rightExtract <= leftExtract && leftExtract < bvLength)) 03010 throw TypecheckException 03011 ("Wrong bounds in bit-vector extract:\n\n "+e.toString()); 03012 int extractLength = leftExtract - rightExtract + 1; 03013 Type bvType = newBitvectorType(extractLength); 03014 e.setType(bvType); 03015 break; 03016 } 03017 case BVPLUS: { 03018 int bvPlusLength = getBVPlusParam(e); 03019 if(!(0 <= bvPlusLength)) 03020 throw TypecheckException 03021 ("Bad bit-vector length specified in BVPLUS expression:\n\n " 03022 + e.toString()); 03023 for(Expr::iterator i=e.begin(), iend=e.end(); i != iend; ++i) { 03024 if(BITVECTOR != getBaseType(*i).getExpr().getOpKind()) 03025 throw TypecheckException 03026 ("Not a bit-vector expression in BVPLUS:\n\n "+e.toString()); 03027 } 03028 Type bvType = newBitvectorType(bvPlusLength); 03029 e.setType(bvType); 03030 break; 03031 } 03032 case LEFTSHIFT: { 03033 if(!(1 == e.arity() && 03034 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03035 throw TypecheckException 03036 ("Not a bit-vector expression in bit-vector shift:\n\n " 03037 +e.toString()); 03038 int bvLength = BVSize(e[0]); 03039 int shiftLength = getFixedLeftShiftParam(e); 03040 if(!(shiftLength >= 0)) 03041 throw TypecheckException("Bad shift value in bit-vector shift:\n\n " 03042 +e.toString()); 03043 int newLength = bvLength + shiftLength; 03044 Type bvType = newBitvectorType(newLength); 03045 e.setType(bvType); 03046 break; 03047 } 03048 case CONST_WIDTH_LEFTSHIFT: { 03049 if(!(1 == e.arity() && 03050 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03051 throw TypecheckException 03052 ("Not a bit-vector expression in bit-vector shift:\n\n " 03053 +e.toString()); 03054 int bvLength = BVSize(e[0]); 03055 int shiftLength = getFixedLeftShiftParam(e); 03056 if(!(shiftLength >= 0)) 03057 throw TypecheckException("Bad shift value in bit-vector shift:\n\n " 03058 +e.toString()); 03059 Type bvType = newBitvectorType(bvLength); 03060 e.setType(bvType); 03061 break; 03062 } 03063 case RIGHTSHIFT: { 03064 if(!(1 == e.arity() && 03065 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03066 throw TypecheckException 03067 ("Not a bit-vector expression in bit-vector shift:\n\n " 03068 +e.toString()); 03069 int bvLength = BVSize(e[0]); 03070 int shiftLength = getFixedRightShiftParam(e); 03071 if(!(shiftLength >= 0)) 03072 throw TypecheckException("Bad shift value in bit-vector shift:\n\n " 03073 +e.toString()); 03074 //int newLength = bvLength + shiftLength; 03075 Type bvType = newBitvectorType(bvLength); 03076 e.setType(bvType); 03077 break; 03078 } 03079 case BVTYPEPRED: 03080 e.setType(boolType()); 03081 break; 03082 case SX: { 03083 if(!(1 == e.arity() && 03084 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03085 throw TypecheckException("Type Checking error:"\ 03086 "non-bitvector \n"+ e.toString()); 03087 int bvLength = getSXIndex(e); 03088 if(!(1 <= bvLength)) 03089 throw TypecheckException("Type Checking error: \n" 03090 "out of range\n"+ e.toString()); 03091 Type bvType = newBitvectorType(bvLength); 03092 e.setType(bvType); 03093 break; 03094 } 03095 case BVREPEAT: { 03096 if(!(1 == e.arity() && 03097 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03098 throw TypecheckException("Type Checking error:"\ 03099 "non-bitvector \n"+ e.toString()); 03100 int bvLength = getBVIndex(e) * BVSize(e[0]); 03101 if(!(1 <= bvLength)) 03102 throw TypecheckException("Type Checking error: \n" 03103 "out of range\n"+ e.toString()); 03104 Type bvType = newBitvectorType(bvLength); 03105 e.setType(bvType); 03106 break; 03107 } 03108 case BVZEROEXTEND: { 03109 if(!(1 == e.arity() && 03110 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03111 throw TypecheckException("Type Checking error:"\ 03112 "non-bitvector \n"+ e.toString()); 03113 int bvLength = getBVIndex(e) + BVSize(e[0]); 03114 if(!(1 <= bvLength)) 03115 throw TypecheckException("Type Checking error: \n" 03116 "out of range\n"+ e.toString()); 03117 Type bvType = newBitvectorType(bvLength); 03118 e.setType(bvType); 03119 break; 03120 } 03121 case BVROTL: 03122 case BVROTR: { 03123 if(!(1 == e.arity() && 03124 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03125 throw TypecheckException("Type Checking error:"\ 03126 "non-bitvector \n"+ e.toString()); 03127 e.setType(getBaseType(e[0])); 03128 break; 03129 } 03130 default: 03131 FatalAssert(false, 03132 "TheoryBitvector::computeType: unexpected kind in application" + 03133 int2string(e.getOpKind())); 03134 break; 03135 } 03136 } 03137 else { 03138 switch(e.getKind()) { 03139 case BOOLEXTRACT: 03140 case BVMULT: 03141 case EXTRACT: 03142 case BVPLUS: 03143 case LEFTSHIFT: 03144 case CONST_WIDTH_LEFTSHIFT: 03145 case RIGHTSHIFT: 03146 case BVTYPEPRED: 03147 case SX: 03148 case BVREPEAT: 03149 case BVZEROEXTEND: 03150 case BVROTL: 03151 case BVROTR: 03152 // These operators are handled above when applied to arguments, here we 03153 // are dealing with the operators themselves which are polymorphic, so 03154 // don't assign them a specific type. 03155 e.setType(Type::anyType(getEM())); 03156 break; 03157 case BVCONST: { 03158 Type bvType = newBitvectorType(getBVConstSize(e)); 03159 e.setType(bvType); 03160 break; 03161 } 03162 case CONCAT: { 03163 if(e.arity() < 2) 03164 throw TypecheckException 03165 ("Concatenation must have at least 2 bit-vectors:\n\n "+e.toString()); 03166 03167 // Compute the total length of concatenation 03168 int bvLength(0); 03169 for(int i=0, iend=e.arity(); i<iend; ++i) { 03170 if(BITVECTOR != getBaseType(e[i]).getExpr().getOpKind()) 03171 throw TypecheckException 03172 ("Not a bit-vector expression (child #"+int2string(i+1) 03173 +") in concatenation:\n\n "+e[i].toString() 03174 +"\n\nIn the expression:\n\n "+e.toString()); 03175 bvLength += BVSize(e[i]); 03176 } 03177 Type bvType = newBitvectorType(bvLength); 03178 e.setType(bvType); 03179 break; 03180 } 03181 case BVAND: 03182 case BVOR: 03183 case BVXOR: 03184 case BVXNOR: 03185 { 03186 string kindStr((e.getOpKind()==BVAND)? "AND" : 03187 ((e.getOpKind()==BVOR)? "OR" : 03188 ((e.getOpKind()==BVXOR)? "BVXOR" : "BVXNOR"))); 03189 03190 if(e.arity() < 2) 03191 throw TypecheckException 03192 ("Bit-wise "+kindStr+" must have at least 2 bit-vectors:\n\n " 03193 +e.toString()); 03194 03195 int bvLength(0); 03196 bool first(true); 03197 for(int i=0, iend=e.arity(); i<iend; ++i) { 03198 if(BITVECTOR != getBaseType(e[i]).getExpr().getOpKind()) 03199 throw TypecheckException 03200 ("Not a bit-vector expression (child #"+int2string(i+1) 03201 +") in bit-wise "+kindStr+":\n\n "+e[i].toString() 03202 +"\n\nIn the expression:\n\n "+e.toString()); 03203 if(first) { 03204 bvLength = BVSize(e[i]); 03205 first=false; 03206 } else { // Check that the size is the same for all subsequent BVs 03207 if(BVSize(e[i]) != bvLength) 03208 throw TypecheckException 03209 ("Mismatched bit-vector size in bit-wise "+kindStr+" (child #" 03210 +int2string(i)+").\nExpected type: " 03211 +newBitvectorType(bvLength).toString() 03212 +"\nFound: "+e[i].getType().toString() 03213 +"\nIn the following expression:\n\n "+e.toString()); 03214 } 03215 } 03216 e.setType(newBitvectorType(bvLength)); 03217 break; 03218 } 03219 case BVNEG:{ 03220 if(!(1 == e.arity() && 03221 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind())) 03222 throw TypecheckException 03223 ("Not a bit-vector expression in bit-wise negation:\n\n " 03224 + e.toString()); 03225 e.setType(e[0].getType()); 03226 break; 03227 } 03228 case BVNAND: 03229 case BVNOR: 03230 case BVCOMP: 03231 case BVSUB: 03232 case BVUDIV: 03233 case BVSDIV: 03234 case BVUREM: 03235 case BVSREM: 03236 case BVSMOD: 03237 case BVSHL: 03238 case BVASHR: 03239 case BVLSHR: 03240 if(!(2 == e.arity() && 03241 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() && 03242 BITVECTOR == getBaseType(e[1]).getExpr().getOpKind())) 03243 throw TypecheckException 03244 ("Expressions must have arity=2, and" 03245 "each subterm must be a bitvector term:\n" 03246 "e = " +e.toString()); 03247 if (BVSize(e[0]) != BVSize(e[1])) 03248 throw TypecheckException 03249 ("Expected args of same size:\n" 03250 "e = " +e.toString()); 03251 if (e.getKind() == BVCOMP) { 03252 e.setType(newBitvectorTypeExpr(1)); 03253 } 03254 else { 03255 e.setType(getBaseType(e[0])); 03256 } 03257 break; 03258 case BVUMINUS:{ 03259 Type bvType(getBaseType(e[0])); 03260 if(!(1 == e.arity() && 03261 BITVECTOR == bvType.getExpr().getOpKind())) 03262 throw TypecheckException 03263 ("Not a bit-vector expression in BVUMINUS:\n\n " 03264 +e.toString()); 03265 e.setType(bvType); 03266 break; 03267 } 03268 case BVLT: 03269 case BVLE: 03270 case BVGT: 03271 case BVGE: 03272 case BVSLT: 03273 case BVSLE: 03274 case BVSGT: 03275 case BVSGE: 03276 if(!(2 == e.arity() && 03277 BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() && 03278 BITVECTOR == getBaseType(e[1]).getExpr().getOpKind())) 03279 throw TypecheckException 03280 ("BVLT/BVLE expressions must have arity=2, and" 03281 "each subterm must be a bitvector term:\n" 03282 "e = " +e.toString()); 03283 e.setType(boolType()); 03284 break; 03285 default: 03286 FatalAssert(false, 03287 "TheoryBitvector::computeType: wrong input" + 03288 int2string(e.getOpKind())); 03289 break; 03290 } 03291 } 03292 TRACE("bitvector", "TheoryBitvector::computeType => ", e.getType(), " }"); 03293 } 03294 03295 03296 void TheoryBitvector::computeModelTerm(const Expr& e, std::vector<Expr>& v) { 03297 switch(e.getOpKind()) { 03298 case BVPLUS: 03299 case BVSUB: 03300 case BVUMINUS: 03301 case BVMULT: 03302 case LEFTSHIFT: 03303 case CONST_WIDTH_LEFTSHIFT: 03304 case RIGHTSHIFT: 03305 case BVOR: 03306 case BVAND: 03307 case BVXOR: 03308 case BVXNOR: 03309 case BVNAND: 03310 case BVNOR: 03311 case BVNEG: 03312 case CONCAT: 03313 case EXTRACT: 03314 case BVSLT: 03315 case BVSLE: 03316 case BVSGT: 03317 case BVSGE: 03318 case BVLT: 03319 case BVLE: 03320 case BVGT: 03321 case BVGE: 03322 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) 03323 // getModelTerm(*i, v); 03324 v.push_back(*i); 03325 return; 03326 case BVCONST: // No model variables here 03327 return; 03328 default: break; // It's a variable; continue processing 03329 } 03330 03331 Type tp(e.getType()); 03332 switch(tp.getExpr().getOpKind()) { 03333 case BITVECTOR: { 03334 int n = getBitvectorTypeParam(tp); 03335 for(int i=0; i<n; i = i+1) 03336 v.push_back(newBoolExtractExpr(e, i)); 03337 break; 03338 } 03339 default: 03340 v.push_back(e); 03341 } 03342 } 03343 03344 03345 void TheoryBitvector::computeModel(const Expr& e, std::vector<Expr>& v) { 03346 switch(e.getOpKind()) { 03347 case BVPLUS: 03348 case BVSUB: 03349 case BVUMINUS: 03350 case BVMULT: 03351 case LEFTSHIFT: 03352 case CONST_WIDTH_LEFTSHIFT: 03353 case RIGHTSHIFT: 03354 case BVOR: 03355 case BVAND: 03356 case BVXOR: 03357 case BVXNOR: 03358 case BVNAND: 03359 case BVNOR: 03360 case BVNEG: 03361 case CONCAT: 03362 case EXTRACT: 03363 case SX: 03364 case BVSLT: 03365 case BVSLE: 03366 case BVSGT: 03367 case BVSGE: 03368 case BVLT: 03369 case BVLE: 03370 case BVGT: 03371 case BVGE: { 03372 // More primitive vars are kids, and they should have been 03373 // assigned concrete values 03374 assignValue(simplify(e)); 03375 v.push_back(e); 03376 return; 03377 } 03378 case BVCONST: // No model variables here 03379 return; 03380 default: break; // It's a variable; continue processing 03381 } 03382 03383 Type tp(e.getType()); 03384 switch(tp.getExpr().getOpKind()) { 03385 case BITVECTOR: { 03386 const Rational& n = getBitvectorTypeParam(tp); 03387 vector<bool> bits; 03388 // FIXME: generate concrete assignment from bits using proof 03389 // rules. For now, just create a new assignment. 03390 for(int i=0; i<n; i++) { 03391 Theorem val(getModelValue(newBoolExtractExpr(e, i))); 03392 DebugAssert(val.getRHS().isBoolConst(), 03393 "TheoryBitvector::computeModel: unassigned bit: " 03394 +val.getExpr().toString()); 03395 bits.push_back(val.getRHS().isTrue()); 03396 } 03397 Expr c(newBVConstExpr(bits)); 03398 assignValue(e, c); 03399 v.push_back(e); 03400 break; 03401 } 03402 default: 03403 FatalAssert(false, "TheoryBitvector::computeModel[not BITVECTOR type](" 03404 +e.toString()+")"); 03405 } 03406 } 03407 03408 03409 // TODO: get rid of this - don't need type predicates for bv's, just need to share the right terms 03410 Expr 03411 TheoryBitvector::computeTypePred(const Type& t, const Expr& e) { 03412 DebugAssert(t.getExpr().getOpKind() == BITVECTOR, 03413 "TheoryBitvector::computeTypePred: t = "+t.toString()); 03414 // switch(e.getKind()) { 03415 // case BVCONST: 03416 // return getEM()->trueExpr(); 03417 // default: 03418 return e.getEM()->trueExpr(); 03419 03420 // return newBitvectorTypePred(t, e); 03421 // } 03422 } 03423 03424 /////////////////////////////////////////////////////////////////////////////// 03425 // Pretty-printing // 03426 /////////////////////////////////////////////////////////////////////////////// 03427 03428 ExprStream& 03429 TheoryBitvector::printSmtLibShared(ExprStream& os, const Expr& e) { 03430 03431 d_theoryUsed = true; 03432 switch( e.getOpKind() ) { 03433 03434 case CONCAT: 03435 if( e.arity() == 0 ) 03436 throw SmtlibException("TheoryBitvector::print: CONCAT arity = 0"); 03437 else if( e.arity() == 1 ) 03438 os << e[0]; 03439 else { 03440 int i; 03441 for( i = 0; i < e.arity(); ++i ) { 03442 if( (i + 1) == e.arity() ) { 03443 os << e[i]; 03444 } else { 03445 os << "(concat" << space << push << e[i] << space << push; 03446 } 03447 } 03448 for( --i; i != 0; --i ) 03449 os << push << ")"; 03450 } 03451 break; 03452 case BVSHL: 03453 os << "(bvshl" << space << push << e[0] << space << push << e[1] << push 03454 << ")"; 03455 break; 03456 case BVLSHR: 03457 os << "(bvlshr" << space << push << e[0] << space << push << e[1] << push 03458 << ")"; 03459 break; 03460 case BVASHR: 03461 os << "(bvashr" << space << push << e[0] << space << push << e[1] << push 03462 << ")"; 03463 break; 03464 case BVAND: 03465 if( e.arity() == 0 ) 03466 throw SmtlibException("TheoryBitvector::print: BVAND arity = 0"); 03467 else if( e.arity() == 1 ) 03468 os << e[0]; 03469 else { 03470 int i; 03471 for( i = 0; i < e.arity(); ++i ) { 03472 if( (i + 1) == e.arity() ) { 03473 os << e[i]; 03474 } else { 03475 os << "(bvand" << space << push << e[i] << space << push; 03476 } 03477 } 03478 for( --i; i != 0; --i ) 03479 os << push << ")"; 03480 } 03481 break; 03482 case BVOR: 03483 if( e.arity() == 0 ) 03484 throw SmtlibException("TheoryBitvector::print: BVAND arity = 0"); 03485 else if( e.arity() == 1 ) 03486 os << e[0]; 03487 else { 03488 int i; 03489 for( i = 0; i < e.arity(); ++i ) { 03490 if( (i + 1) == e.arity() ) { 03491 os << e[i]; 03492 } else { 03493 os << "(bvor" << space << push << e[i] << space << push; 03494 } 03495 } 03496 for( --i; i != 0; --i ) 03497 os << push << ")"; 03498 } 03499 break; 03500 case BVXOR: 03501 if( e.arity() == 0 ) 03502 throw SmtlibException("TheoryBitvector::print: BVXOR arity = 0"); 03503 else if( e.arity() == 1 ) 03504 os << e[0]; 03505 else { 03506 int i; 03507 for( i = 0; i < e.arity(); ++i ) { 03508 if( (i + 1) == e.arity() ) { 03509 os << e[i]; 03510 } else { 03511 os << "(bvxor" << space << push << e[i] << space << push; 03512 } 03513 } 03514 for( --i; i != 0; --i ) 03515 os << push << ")"; 03516 } 03517 break; 03518 case BVXNOR: 03519 if( e.arity() == 0 ) 03520 throw SmtlibException("TheoryBitvector::print: BVXNOR arity = 0"); 03521 else if( e.arity() == 1 ) 03522 os << e[0]; 03523 else { 03524 int i; 03525 for( i = 0; i < e.arity(); ++i ) { 03526 if( (i + 1) == e.arity() ) { 03527 os << e[i]; 03528 } else { 03529 os << "(bvxnor" << space << push << e[i] << space << push; 03530 } 03531 } 03532 for( --i; i != 0; --i ) 03533 os << push << ")"; 03534 } 03535 break; 03536 case BVNEG: 03537 os << "(bvnot" << space << push << e[0] << push << ")"; 03538 break; 03539 case BVNAND: 03540 os << "(bvnand" << space << push << e[0] << space << push << e[1] << push 03541 << ")"; 03542 break; 03543 case BVNOR: 03544 os << "(bvnor" << space << push << e[0] << space << push << e[1] << push 03545 << ")"; 03546 break; 03547 case BVCOMP: 03548 os << "(bvcomp" << space << push << e[0] << space << push << e[1] << push 03549 << ")"; 03550 break; 03551 03552 case BVUMINUS: 03553 os << "(bvneg" << space << push << e[0] << push << ")"; 03554 break; 03555 case BVPLUS: { 03556 DebugAssert(e.arity() > 0, "expected arity > 0 in BVPLUS"); 03557 int length = getBVPlusParam(e); 03558 int i; 03559 for( i = 0; i < e.arity(); ++i ) { 03560 if( (i + 1) == e.arity() ) { 03561 os << pad(length, e[i]); 03562 } else { 03563 os << "(bvadd" << space << push << pad(length, e[i]) << space << push; 03564 } 03565 } 03566 for( --i; i != 0; --i ) 03567 os << push << ")"; 03568 } 03569 break; 03570 case BVSUB: 03571 os << "(bvsub" << space << push << e[0] << space << push << e[1] << push 03572 << ")"; 03573 break; 03574 case BVMULT: { 03575 int length = getBVMultParam(e); 03576 os << "(bvmul" << space << push << pad(length, e[0]) << space << push 03577 << pad(length, e[1]) << push << ")"; 03578 break; 03579 } 03580 case BVUDIV: 03581 os << "(bvudiv" << space << push << e[0] << space << push << e[1] << push 03582 << ")"; 03583 break; 03584 case BVSDIV: 03585 os << "(bvsdiv" << space << push << e[0] << space << push << e[1] << push 03586 << ")"; 03587 break; 03588 case BVUREM: 03589 os << "(bvurem" << space << push << e[0] << space << push << e[1] << push 03590 << ")"; 03591 break; 03592 case BVSREM: 03593 os << "(bvsrem" << space << push << e[0] << space << push << e[1] << push 03594 << ")"; 03595 break; 03596 case BVSMOD: 03597 os << "(bvsmod" << space << push << e[0] << space << push << e[1] << push 03598 << ")"; 03599 break; 03600 03601 case BVLT: 03602 os << "(bvult" << space << push << e[0] << space << push << e[1] << push 03603 << ")"; 03604 break; 03605 case BVLE: 03606 os << "(bvule" << space << push << e[0] << space << push << e[1] << push 03607 << ")"; 03608 break; 03609 case BVGT: 03610 os << "(bvugt" << space << push << e[0] << space << push << e[1] << push 03611 << ")"; 03612 break; 03613 case BVGE: 03614 os << "(bvuge" << space << push << e[0] << space << push << e[1] << push 03615 << ")"; 03616 break; 03617 case BVSLT: 03618 os << "(bvslt" << space << push << e[0] << space << push << e[1] << push 03619 << ")"; 03620 break; 03621 case BVSLE: 03622 os << "(bvsle" << space << push << e[0] << space << push << e[1] << push 03623 << ")"; 03624 break; 03625 case BVSGT: 03626 os << "(bvsgt" << space << push << e[0] << space << push << e[1] << push 03627 << ")"; 03628 break; 03629 case BVSGE: 03630 os << "(bvsge" << space << push << e[0] << space << push << e[1] << push 03631 << ")"; 03632 break; 03633 03634 case INTTOBV: 03635 throw SmtlibException( 03636 "TheoryBitvector::print: INTTOBV, SMTLIB not supported"); 03637 break; 03638 case BVTOINT: 03639 throw SmtlibException( 03640 "TheoryBitvector::print: BVTOINT, SMTLIB not supported"); 03641 break; 03642 03643 case BVTYPEPRED: 03644 throw SmtlibException( 03645 "TheoryBitvector::print: BVTYPEPRED, SMTLIB not supported"); 03646 if( e.isApply() ) { 03647 os << "BVTYPEPRED[" << push << e.getOp().getExpr() << push << "," << pop 03648 << space << e[0] << push << "]"; 03649 } else 03650 e.printAST(os); 03651 break; 03652 03653 default: 03654 FatalAssert(false, "Unknown BV kind"); 03655 e.printAST(os); 03656 break; 03657 } 03658 return os; 03659 } 03660 03661 ExprStream& 03662 TheoryBitvector::print(ExprStream& os, const Expr& e) { 03663 switch(os.lang()) { 03664 case PRESENTATION_LANG: 03665 switch(e.getOpKind()) { 03666 03667 case BITVECTOR: //printing type expression 03668 os << "BITVECTOR(" << push 03669 << getBitvectorTypeParam(e) << push << ")"; 03670 break; 03671 03672 case BVCONST: { 03673 std::ostringstream ss; 03674 ss << "0bin"; 03675 for(int i=(int)getBVConstSize(e)-1; i>=0; --i) 03676 ss << (getBVConstValue(e, i) ? "1" : "0"); 03677 os << ss.str(); 03678 break; 03679 } 03680 03681 case CONCAT: 03682 if(e.arity() <= 1) e.printAST(os); 03683 else { 03684 os << "(" << push; 03685 bool first(true); 03686 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) { 03687 if(first) first=false; 03688 else os << space << "@" << space; 03689 os << (*i); 03690 } 03691 os << push << ")"; 03692 } 03693 break; 03694 case EXTRACT: 03695 os << "(" << push << e[0] << push << ")" << pop << pop 03696 << "[" << push << getExtractHi(e) << ":"; 03697 os << getExtractLow(e) << push << "]"; 03698 break; 03699 case BOOLEXTRACT: 03700 os << "BOOLEXTRACT(" << push << e[0] << "," 03701 << getBoolExtractIndex(e) << push << ")"; 03702 break; 03703 03704 case LEFTSHIFT: 03705 os << "(" << push << e[0] << space << "<<" << space 03706 << getFixedLeftShiftParam(e) << push << ")"; 03707 break; 03708 case CONST_WIDTH_LEFTSHIFT: 03709 os << "(" << push << e[0] << space << "<<" << space 03710 << getFixedLeftShiftParam(e) << push << ")"; 03711 os << "[" << push << BVSize(e)-1 << ":0]"; 03712 break; 03713 case RIGHTSHIFT: 03714 os << "(" << push << e[0] << space << ">>" << space 03715 << getFixedRightShiftParam(e) << push << ")"; 03716 break; 03717 case BVSHL: 03718 os << "BVSHL(" << push << e[0] << "," << e[1] << push << ")"; 03719 break; 03720 case BVLSHR: 03721 os << "BVLSHR(" << push << e[0] << "," << e[1] << push << ")"; 03722 break; 03723 case BVASHR: 03724 os << "BVASHR(" << push << e[0] << "," << e[1] << push << ")"; 03725 break; 03726 case BVZEROEXTEND: 03727 os << "BVZEROEXTEND(" << push << e[0] << "," << getBVIndex(e) << push << ")"; 03728 break; 03729 case BVREPEAT: 03730 os << "BVREPEAT(" << push << e[0] << "," << getBVIndex(e) << push << ")"; 03731 break; 03732 case BVROTL: 03733 os << "BVROTL(" << push << e[0] << "," << getBVIndex(e) << push << ")"; 03734 break; 03735 case BVROTR: 03736 os << "BVROTR(" << push << e[0] << "," << getBVIndex(e) << push << ")"; 03737 break; 03738 case SX: 03739 os << "SX(" << push << e[0] << "," 03740 << push << getSXIndex(e) << ")"; 03741 break; 03742 03743 case BVAND: 03744 if(e.arity() <= 1) e.printAST(os); 03745 else { 03746 os << "(" << push; 03747 bool first(true); 03748 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) { 03749 if(first) first=false; 03750 else os << space << "&" << space; 03751 os << (*i); 03752 } 03753 os << push << ")"; 03754 } 03755 break; 03756 case BVOR: 03757 if(e.arity() <= 1) e.printAST(os); 03758 else { 03759 os << "(" << push; 03760 bool first(true); 03761 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) { 03762 if(first) first=false; 03763 else os << space << "|" << space; 03764 os << (*i); 03765 } 03766 os << push << ")"; 03767 } 03768 break; 03769 case BVXOR: 03770 DebugAssert(e.arity() > 0, "TheoryBitvector::print: BVXOR arity <= 0"); 03771 if (e.arity() == 1) os << e[0]; 03772 else { 03773 int i; 03774 for(i = 0; i < e.arity(); ++i) { 03775 if ((i+1) == e.arity()) { 03776 os << e[i]; 03777 } 03778 else { 03779 os << "BVXOR(" << push << e[i] << "," << push; 03780 } 03781 } 03782 for (--i; i != 0; --i) os << push << ")"; 03783 } 03784 break; 03785 case BVXNOR: 03786 DebugAssert(e.arity() > 0, "TheoryBitvector::print: BVXNOR arity <= 0"); 03787 if (e.arity() == 1) os << e[0]; 03788 else { 03789 int i; 03790 for(i = 0; i < e.arity(); ++i) { 03791 if ((i+1) == e.arity()) { 03792 os << e[i]; 03793 } 03794 else { 03795 os << "BVXNOR(" << push << e[i] << "," << push; 03796 } 03797 } 03798 for (--i; i != 0; --i) os << push << ")"; 03799 } 03800 break; 03801 case BVNEG: 03802 os << "(~(" << push << e[0] << push << "))"; 03803 break; 03804 case BVNAND: 03805 os << "BVNAND(" << push << e[0] << "," << e[1] << push << ")"; 03806 break; 03807 case BVNOR: 03808 os << "BVNAND(" << push << e[0] << "," << e[1] << push << ")"; 03809 break; 03810 case BVCOMP: 03811 os << "BVCOMP(" << push << e[0] << "," << e[1] << push << ")"; 03812 break; 03813 03814 case BVUMINUS: 03815 os << "BVUMINUS(" << push << e[0] << push << ")"; 03816 break; 03817 case BVPLUS: 03818 os << "BVPLUS(" << push << getBVPlusParam(e); 03819 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) { 03820 os << push << "," << pop << space << (*i); 03821 } 03822 os << push << ")"; 03823 break; 03824 case BVSUB: 03825 os << "BVSUB(" << push << BVSize(e) << "," << e[0] << "," << e[1] << push << ")"; 03826 break; 03827 case BVMULT: 03828 os << "BVMULT(" << push << getBVMultParam(e) << "," << e[0] << "," << e[1]<<push<<")"; 03829 break; 03830 case BVUDIV: 03831 os << "BVUDIV(" << push << e[0] << "," << e[1]<<push<<")"; 03832 break; 03833 case BVSDIV: 03834 os << "BVSDIV(" << push << e[0] << "," << e[1]<<push<<")"; 03835 break; 03836 case BVUREM: 03837 os << "BVUREM(" << push << e[0] << "," << e[1]<<push<<")"; 03838 break; 03839 case BVSREM: 03840 os << "BVSREM(" << push << e[0] << "," << e[1]<<push<<")"; 03841 break; 03842 case BVSMOD: 03843 os << "BVSMOD(" << push << e[0] << "," << e[1]<<push<<")"; 03844 break; 03845 case BVLT: 03846 os << "BVLT(" << push << e[0] << "," << e[1] << push << ")"; 03847 break; 03848 case BVLE: 03849 os << "BVLE(" << push << e[0] << "," << e[1] << push << ")"; 03850 break; 03851 case BVGT: 03852 os << "BVGT(" << push << e[0] << "," << e[1] << push << ")"; 03853 break; 03854 case BVGE: 03855 os << "BVGE(" << push << e[0] << "," << e[1] << push << ")"; 03856 break; 03857 case BVSLT: 03858 os << "BVSLT(" << push << e[0] << "," << e[1] << push << ")"; 03859 break; 03860 case BVSLE: 03861 os << "BVSLE(" << push << e[0] << "," << e[1] << push << ")"; 03862 break; 03863 case BVSGT: 03864 os << "BVSGT(" << push << e[0] << "," << e[1] << push << ")"; 03865 break; 03866 case BVSGE: 03867 os << "BVSGE(" << push << e[0] << "," << e[1] << push << ")"; 03868 break; 03869 03870 case INTTOBV: 03871 FatalAssert(false, "INTTOBV not implemented yet"); 03872 break; 03873 case BVTOINT: 03874 FatalAssert(false, "BVTOINT not implemented yet"); 03875 break; 03876 03877 case BVTYPEPRED: 03878 if(e.isApply()) { 03879 os << "BVTYPEPRED[" << push << e.getOp().getExpr() 03880 << push << "," << pop << space << e[0] 03881 << push << "]"; 03882 } else 03883 e.printAST(os); 03884 break; 03885 03886 default: 03887 FatalAssert(false, "Unknown BV kind"); 03888 e.printAST(os); 03889 break; 03890 } 03891 break; 03892 03893 case SMTLIB_LANG: 03894 switch(e.getOpKind()) { 03895 case BITVECTOR: //printing type expression 03896 os << push << "BitVec[" << getBitvectorTypeParam(e) << "]"; 03897 break; 03898 03899 case BVCONST: { 03900 Rational r = computeBVConst(e); 03901 DebugAssert(r.isInteger() && r >= 0, "Expected non-negative integer"); 03902 os << push << "bv" << r << "[" << BVSize(e) << "]"; 03903 break; 03904 } 03905 03906 case EXTRACT: 03907 os << push << "(extract[" << getExtractHi(e) << ":" << getExtractLow(e) 03908 << "]"; 03909 os << space << push << e[0] << push << ")"; 03910 break; 03911 case BOOLEXTRACT: 03912 os << "(=" << space << push << "(extract[" << getBoolExtractIndex(e) << ":" 03913 << getBoolExtractIndex(e) << "]"; 03914 os << space << push << e[0] << push << ")" << space << "bit1" << push 03915 << ")"; 03916 break; 03917 03918 case LEFTSHIFT: { 03919 int bvLength = getFixedLeftShiftParam(e); 03920 if( bvLength != 0 ) { 03921 os << "(concat" << space << push << e[0] << space; 03922 os << push << "bv0[" << bvLength << "]" << push << ")"; 03923 break; 03924 } 03925 // else fall-through 03926 } 03927 case CONST_WIDTH_LEFTSHIFT: 03928 os << "(bvshl" << space << push << e[0] << space << push << "bv" 03929 << getFixedLeftShiftParam(e) << "[" << BVSize(e[0]) << "]" << push 03930 << ")"; 03931 break; 03932 case RIGHTSHIFT: 03933 os << "(bvlshr" << space << push << e[0] << space << push << "bv" 03934 << getFixedRightShiftParam(e) << "[" << BVSize(e[0]) << "]" << push 03935 << ")"; 03936 break; 03937 case SX: { 03938 int extend = getSXIndex(e) - BVSize(e[0]); 03939 if( extend == 0 ) 03940 os << e[0]; 03941 else if( extend < 0 ) 03942 throw SmtlibException( 03943 "TheoryBitvector::print: SX: extension is shorter than argument"); 03944 else 03945 os << "(sign_extend[" << extend << "]" << space << push << e[0] << push 03946 << ")"; 03947 break; 03948 } 03949 case BVREPEAT: 03950 os << "(repeat[" << getBVIndex(e) << "]" << space << push << e[0] << push 03951 << ")"; 03952 break; 03953 case BVZEROEXTEND: { 03954 int extend = getBVIndex(e); 03955 if( extend == 0 ) 03956 os << e[0]; 03957 else if( extend < 0 ) 03958 throw SmtlibException( 03959 "TheoryBitvector::print: ZEROEXTEND: extension is less than zero"); 03960 else 03961 os << "(zero_extend[" << extend << "]" << space << push << e[0] << push 03962 << ")"; 03963 break; 03964 } 03965 case BVROTL: 03966 os << "(rotate_left[" << getBVIndex(e) << "]" << space << push << e[0] 03967 << push << ")"; 03968 break; 03969 case BVROTR: 03970 os << "(rotate_right[" << getBVIndex(e) << "]" << space << push << e[0] 03971 << push << ")"; 03972 break; 03973 03974 default: 03975 printSmtLibShared(os,e); 03976 } 03977 break; 03978 03979 case SMTLIB_V2_LANG: 03980 switch(e.getOpKind()) { 03981 case BITVECTOR: //printing type expression 03982 os << push << "(_" << space << "BitVec" << space << getBitvectorTypeParam(e) << ")" << pop; 03983 break; 03984 03985 case BVCONST: { 03986 Rational r = computeBVConst(e); 03987 DebugAssert(r.isInteger() && r >= 0, "Expected non-negative integer"); 03988 os << push << "(_ bv" << r << space << BVSize(e) << ")"; 03989 break; 03990 } 03991 03992 case EXTRACT: 03993 os << push << "((_ extract" << space << getExtractHi(e) << space << getExtractLow(e) 03994 << ")"; 03995 os << space << push << e[0] << push << ")"; 03996 break; 03997 03998 case BOOLEXTRACT: 03999 os << "(=" << space << push << "((_ extract" << getBoolExtractIndex(e) << space 04000 << getBoolExtractIndex(e) << ")"; 04001 os << space << push << e[0] << push << ")" << space << "#b1" << push 04002 << ")"; 04003 break; 04004 04005 case LEFTSHIFT: { 04006 int bvLength = getFixedLeftShiftParam(e); 04007 if( bvLength != 0 ) { 04008 os << "(concat" << space << push << e[0] << space; 04009 os << push << "#b"; 04010 for (int i = 0; i < bvLength; ++i) os << "0"; 04011 os << push << ")"; 04012 break; 04013 } 04014 // else fall-through 04015 } 04016 case CONST_WIDTH_LEFTSHIFT: 04017 os << "(bvshl" << space << push << e[0] << space << push; 04018 os << newBVConstExpr(getFixedLeftShiftParam(e), BVSize(e[0])) << push << ")"; 04019 break; 04020 case RIGHTSHIFT: 04021 os << "(bvlshr" << space << push << e[0] << space << push; 04022 os << newBVConstExpr(getFixedRightShiftParam(e), BVSize(e[0])) << push << ")"; 04023 break; 04024 case SX: { 04025 int extend = getSXIndex(e) - BVSize(e[0]); 04026 if( extend == 0 ) 04027 os << e[0]; 04028 else if( extend < 0 ) 04029 throw SmtlibException( 04030 "TheoryBitvector::print: SX: extension is shorter than argument"); 04031 else 04032 os << "((_ sign_extend" << space << extend << ")" << space << push << e[0] << push 04033 << ")"; 04034 break; 04035 } 04036 case BVREPEAT: 04037 os << "((_ repeat" << space << getBVIndex(e) << ")" << space << push << e[0] << push 04038 << ")"; 04039 break; 04040 case BVZEROEXTEND: { 04041 int extend = getBVIndex(e); 04042 if( extend == 0 ) 04043 os << e[0]; 04044 else if( extend < 0 ) 04045 throw SmtlibException( 04046 "TheoryBitvector::print: ZEROEXTEND: extension is less than zero"); 04047 else 04048 os << "((_ zero_extend" << space << extend << ")" << space << push << e[0] << push 04049 << ")"; 04050 break; 04051 } 04052 case BVROTL: 04053 os << "((_ rotate_left" << space << getBVIndex(e) << ")" << space << push << e[0] 04054 << push << ")"; 04055 break; 04056 case BVROTR: 04057 os << "((_ rotate_right" << space << getBVIndex(e) << ")" << space << push << e[0] 04058 << push << ")"; 04059 break; 04060 04061 default: 04062 printSmtLibShared(os,e); 04063 } 04064 break; 04065 04066 default: 04067 switch(e.getOpKind()) { 04068 case BVCONST: { 04069 os << "0bin"; 04070 for(int i=(int)getBVConstSize(e)-1; i>=0; --i) 04071 os << (getBVConstValue(e, i) ? "1" : "0"); 04072 break; 04073 } 04074 default: 04075 e.printAST(os); 04076 break; 04077 } 04078 } 04079 return os; 04080 } 04081 04082 04083 /////////////////////////////////////////////////////////////////////////////// 04084 //parseExprOp: 04085 //translating special Exprs to regular EXPR?? 04086 /////////////////////////////////////////////////////////////////////////////// 04087 Expr TheoryBitvector::parseExprOp(const Expr& e) 04088 { 04089 d_theoryUsed = true; 04090 TRACE("parser", "TheoryBitvector::parseExprOp(", e, ")"); 04091 04092 // If the expression is not a list, it must have been already 04093 // parsed, so just return it as is. 04094 if(RAW_LIST != e.getKind()) return e; 04095 04096 if(!(e.arity() > 0)) 04097 throw ParserException("TheoryBitvector::parseExprOp: wrong input:\n\n" 04098 +e.toString()); 04099 04100 const Expr& c1 = e[0][0]; 04101 int kind = getEM()->getKind(c1.getString()); 04102 switch(kind) { 04103 04104 case BITVECTOR: 04105 if(!(e.arity() == 2)) 04106 throw ParserException("TheoryBitvector::parseExprOp: BITVECTOR" 04107 "kind should have exactly 1 arg:\n\n" 04108 + e.toString()); 04109 if(!(e[1].isRational() && e[1].getRational().isInteger())) 04110 throw ParserException("BITVECTOR TYPE must have an integer constant" 04111 "as its first argument:\n\n" 04112 +e.toString()); 04113 if(!(e[1].getRational().getInt() >=0 )) 04114 throw ParserException("parameter must be an integer constant >= 0.\n" 04115 +e.toString()); 04116 return newBitvectorTypeExpr(e[1].getRational().getInt()); 04117 break; 04118 04119 case BVCONST: 04120 if(!(e.arity() == 2 || e.arity() == 3)) 04121 throw ParserException("TheoryBitvector::parseExprOp: BVCONST " 04122 "kind should have 1 or 2 args:\n\n" 04123 + e.toString()); 04124 if(!(e[1].isRational() || e[1].isString())) 04125 throw ParserException("TheoryBitvector::parseExprOp: BVCONST " 04126 "kind should have arg of type Rational " 04127 "or String:\n\n" + e.toString()); 04128 if(e[1].isRational()) { // ("BVCONST" value [bitwidth]) 04129 if(e.arity()==3) { 04130 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04131 throw ParserException("TheoryBitvector::parseExprOp: BVCONST " 04132 "2nd argument must be an integer:\n\n" 04133 +e.toString()); 04134 return newBVConstExpr(e[1].getRational(), e[2].getRational().getInt()); 04135 } else 04136 return newBVConstExpr(e[1].getRational()); 04137 } else if(e[1].isString()) { // ("BVCONST" string [base]) 04138 if(e.arity() == 3) { 04139 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04140 throw ParserException("TheoryBitvector::parseExprOp: BVCONST " 04141 "2nd argument must be an integer:\n\n" 04142 +e.toString()); 04143 return newBVConstExpr(e[1].getString(), e[2].getRational().getInt()); 04144 } else 04145 return newBVConstExpr(e[1].getString()); 04146 } 04147 break; 04148 04149 case CONCAT: { 04150 if(!(e.arity() >= 3)) 04151 throw ParserException("TheoryBitvector::parseExprOp: CONCAT" 04152 "kind should have at least 2 args:\n\n" 04153 + e.toString()); 04154 vector<Expr> kids; 04155 Expr::iterator i=e.begin(), iend=e.end(); 04156 DebugAssert(i!=iend, "TheoryBitvector::parseExprOp("+e.toString()+")"); 04157 ++i; // Skip the first element - the operator name 04158 for(; i!=iend; ++i) 04159 kids.push_back(parseExpr(*i)); 04160 return newConcatExpr(kids); 04161 break; 04162 } 04163 case EXTRACT: { 04164 if(!(e.arity() == 4)) 04165 throw ParserException("TheoryBitvector::parseExprOp: EXTRACT" 04166 "kind should have exactly 3 arg:\n\n" 04167 + e.toString()); 04168 if(!e[1].isRational() || !e[1].getRational().isInteger()) 04169 throw ParserException("EXTRACT must have an integer constant as its " 04170 "1st argument:\n\n" 04171 +e.toString()); 04172 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04173 throw ParserException("EXTRACT must have an integer constant as its " 04174 "2nd argument:\n\n" 04175 +e.toString()); 04176 int hi = e[1].getRational().getInt(); 04177 int lo = e[2].getRational().getInt(); 04178 if(!(hi >= lo && lo >=0)) 04179 throw ParserException("parameter must be an integer constant >= 0.\n" 04180 +e.toString()); 04181 04182 // Check for extract of left shift 04183 Expr arg = e[3]; 04184 if (lo == 0 && arg.getKind() == RAW_LIST && arg[0].getKind() == ID && 04185 getEM()->getKind(arg[0][0].getString()) == LEFTSHIFT) { 04186 if(!(arg.arity() == 3)) 04187 throw ParserException("TheoryBitvector::parseExprOp: LEFTSHIFT" 04188 "kind should have exactly 2 arg:\n\n" 04189 + arg.toString()); 04190 if(!arg[2].isRational() || !arg[2].getRational().isInteger()) 04191 throw ParserException("LEFTSHIFT must have an integer constant as its " 04192 "2nd argument:\n\n" 04193 +arg.toString()); 04194 if(!(arg[2].getRational().getInt() >=0 )) 04195 throw ParserException("parameter must be an integer constant >= 0.\n" 04196 +arg.toString()); 04197 Expr ls_arg = parseExpr(arg[1]); 04198 if (BVSize(ls_arg) == hi + 1) { 04199 return newFixedConstWidthLeftShiftExpr(ls_arg, arg[2].getRational().getInt()); 04200 } 04201 } 04202 return newBVExtractExpr(parseExpr(arg), hi, lo); 04203 break; 04204 } 04205 case BOOLEXTRACT: 04206 if(!(e.arity() == 3)) 04207 throw ParserException("TheoryBitvector::parseExprOp: BOOLEXTRACT" 04208 "kind should have exactly 2 arg:\n\n" 04209 + e.toString()); 04210 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04211 throw ParserException("BOOLEXTRACT must have an integer constant as its" 04212 " 2nd argument:\n\n" 04213 +e.toString()); 04214 if(!(e[2].getRational().getInt() >=0 )) 04215 throw ParserException("parameter must be an integer constant >= 0.\n" 04216 +e.toString()); 04217 return newBoolExtractExpr(parseExpr(e[1]), e[2].getRational().getInt()); 04218 break; 04219 04220 case LEFTSHIFT: 04221 if(!(e.arity() == 3)) 04222 throw ParserException("TheoryBitvector::parseExprOp: LEFTSHIFT" 04223 "kind should have exactly 2 arg:\n\n" 04224 + e.toString()); 04225 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04226 throw ParserException("LEFTSHIFT must have an integer constant as its " 04227 "2nd argument:\n\n" 04228 +e.toString()); 04229 if(!(e[2].getRational().getInt() >=0 )) 04230 throw ParserException("parameter must be an integer constant >= 0.\n" 04231 +e.toString()); 04232 return newFixedLeftShiftExpr(parseExpr(e[1]), e[2].getRational().getInt()); 04233 break; 04234 case CONST_WIDTH_LEFTSHIFT: 04235 if(!(e.arity() == 3)) 04236 throw ParserException("TheoryBitvector::parseExprOp: CONST_WIDTH_LEFTSHIFT" 04237 "kind should have exactly 2 arg:\n\n" 04238 + e.toString()); 04239 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04240 throw ParserException("CONST_WIDTH_LEFTSHIFT must have an integer constant as its " 04241 "2nd argument:\n\n" 04242 +e.toString()); 04243 if(!(e[2].getRational().getInt() >=0 )) 04244 throw ParserException("parameter must be an integer constant >= 0.\n" 04245 +e.toString()); 04246 return newFixedConstWidthLeftShiftExpr(parseExpr(e[1]), e[2].getRational().getInt()); 04247 break; 04248 case RIGHTSHIFT: 04249 if(!(e.arity() == 3)) 04250 throw ParserException("TheoryBitvector::parseExprOp: RIGHTSHIFT" 04251 "kind should have exactly 2 arg:\n\n" 04252 + e.toString()); 04253 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04254 throw ParserException("RIGHTSHIFT must have an integer constant as its " 04255 "2nd argument:\n\n" 04256 +e.toString()); 04257 if(!(e[2].getRational().getInt() >=0 )) 04258 throw ParserException("parameter must be an integer constant >= 0.\n" 04259 +e.toString()); 04260 return newFixedRightShiftExpr(parseExpr(e[1]), e[2].getRational().getInt()); 04261 break; 04262 // BVSHL, BVLSHR, BVASHR handled with arith operators below 04263 case SX: 04264 // smtlib format interprets the integer argument as the number of bits to 04265 // extend, while CVC format interprets it as the new total size. 04266 // The smtlib parser inserts an extra argument "_smtlib" for this operator 04267 // so that we can distinguish the two cases here. 04268 if (e.arity() == 4 && 04269 e[1].getKind() == ID && 04270 e[1][0].getString() == "_smtlib") { 04271 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04272 throw ParserException("sign_extend must have an integer constant as its" 04273 " 1st argument:\n\n" 04274 +e.toString()); 04275 if(!(e[2].getRational().getInt() >=0 )) 04276 throw ParserException("sign_extend must have an integer constant as its" 04277 " 1st argument >= 0:\n\n" 04278 +e.toString()); 04279 Expr e3 = parseExpr(e[3]); 04280 return newSXExpr(e3, BVSize(e3) + e[2].getRational().getInt()); 04281 } 04282 if(!(e.arity() == 3)) 04283 throw ParserException("TheoryBitvector::parseExprOp: SX" 04284 "kind should have exactly 2 arg:\n\n" 04285 + e.toString()); 04286 if(!e[2].isRational() || !e[2].getRational().isInteger()) 04287 throw ParserException("SX must have an integer constant as its" 04288 " 2nd argument:\n\n" 04289 +e.toString()); 04290 if(!(e[2].getRational().getInt() >=0 )) 04291 throw ParserException("SX must have an integer constant as its" 04292 " 2nd argument >= 0:\n\n" 04293 +e.toString()); 04294 return newSXExpr(parseExpr(e[1]), e[2].getRational().getInt()); 04295 break; 04296 case BVROTL: 04297 case BVROTR: 04298 case BVREPEAT: 04299 case BVZEROEXTEND: 04300 if(!(e.arity() == 3)) 04301 throw ParserException("TheoryBitvector::parseExprOp:" 04302 "kind should have exactly 2 arg:\n\n" 04303 + e.toString()); 04304 if(!e[1].isRational() || !e[1].getRational().isInteger()) 04305 throw ParserException("BVIndexExpr must have an integer constant as its" 04306 " 1st argument:\n\n" 04307 +e.toString()); 04308 if (kind == BVREPEAT && !(e[1].getRational().getInt() >0 )) 04309 throw ParserException("BVREPEAT must have an integer constant as its" 04310 " 1st argument > 0:\n\n" 04311 +e.toString()); 04312 if(!(e[1].getRational().getInt() >=0 )) 04313 throw ParserException("BVIndexExpr must have an integer constant as its" 04314 " 1st argument >= 0:\n\n" 04315 +e.toString()); 04316 return newBVIndexExpr(kind, parseExpr(e[2]), e[1].getRational().getInt()); 04317 break; 04318 04319 case BVAND: { 04320 if(!(e.arity() >= 3)) 04321 throw ParserException("TheoryBitvector::parseExprOp: BVAND " 04322 "kind should have at least 2 arg:\n\n" 04323 + e.toString()); 04324 vector<Expr> kids; 04325 for(int i=1, iend=e.arity(); i<iend; ++i) 04326 kids.push_back(parseExpr(e[i])); 04327 return newBVAndExpr(kids); 04328 break; 04329 } 04330 case BVOR: { 04331 if(!(e.arity() >= 3)) 04332 throw ParserException("TheoryBitvector::parseExprOp: BVOR " 04333 "kind should have at least 2 arg:\n\n" 04334 + e.toString()); 04335 vector<Expr> kids; 04336 for(int i=1, iend=e.arity(); i<iend; ++i) 04337 kids.push_back(parseExpr(e[i])); 04338 return newBVOrExpr(kids); 04339 break; 04340 } 04341 case BVXOR: { 04342 if(!(e.arity() == 3)) 04343 throw ParserException("TheoryBitvector::parseExprOp: BVXOR " 04344 "kind should have exactly 2 arg:\n\n" 04345 + e.toString()); 04346 return newBVXorExpr(parseExpr(e[1]), parseExpr(e[2])); 04347 break; 04348 } 04349 case BVXNOR: { 04350 if(!(e.arity() == 3)) 04351 throw ParserException("TheoryBitvector::parseExprOp: BVXNOR" 04352 "kind should have exactly 2 arg:\n\n" 04353 + e.toString()); 04354 return newBVXnorExpr(parseExpr(e[1]), parseExpr(e[2])); 04355 break; 04356 } 04357 case BVNEG: 04358 if(!(e.arity() == 2)) 04359 throw ParserException("TheoryBitvector::parseExprOp: BVNEG" 04360 "kind should have exactly 1 arg:\n\n" 04361 + e.toString()); 04362 return newBVNegExpr(parseExpr(e[1])); 04363 break; 04364 case BVNAND: 04365 if(!(e.arity() == 3)) 04366 throw ParserException("TheoryBitvector::parseExprOp: BVNAND" 04367 "kind should have exactly 2 arg:\n\n" 04368 + e.toString()); 04369 return newBVNandExpr(parseExpr(e[1]), parseExpr(e[2])); 04370 break; 04371 case BVNOR: 04372 if(!(e.arity() == 3)) 04373 throw ParserException("TheoryBitvector::parseExprOp: BVNOR" 04374 "kind should have exactly 2 arg:\n\n" 04375 + e.toString()); 04376 return newBVNorExpr(parseExpr(e[1]), parseExpr(e[2])); 04377 break; 04378 case BVCOMP: { 04379 if(!(e.arity() == 3)) 04380 throw ParserException("TheoryBitvector::parseExprOp: BVXNOR" 04381 "kind should have exactly 2 arg:\n\n" 04382 + e.toString()); 04383 return newBVCompExpr(parseExpr(e[1]), parseExpr(e[2])); 04384 break; 04385 } 04386 04387 case BVUMINUS: 04388 if(!(e.arity() == 2)) 04389 throw ParserException("TheoryBitvector::parseExprOp: BVUMINUS" 04390 "kind should have exactly 1 arg:\n\n" 04391 + e.toString()); 04392 return newBVUminusExpr(parseExpr(e[1])); 04393 break; 04394 case BVPLUS: { 04395 vector<Expr> k; 04396 Expr::iterator i = e.begin(), iend=e.end(); 04397 if (!e[1].isRational()) { 04398 int maxsize = 0; 04399 Expr child; 04400 // Parse the kids of e and push them into the vector 'k' 04401 for(++i; i!=iend; ++i) { 04402 child = parseExpr(*i); 04403 if (getBaseType(child).getExpr().getOpKind() != BITVECTOR) { 04404 throw ParserException("BVPLUS argument is not bitvector"); 04405 } 04406 if (BVSize(child) > maxsize) maxsize = BVSize(child); 04407 k.push_back(child); 04408 } 04409 if (e.arity() == 1) return k[0]; 04410 return newBVPlusPadExpr(maxsize, k); 04411 } 04412 else { 04413 if(!(e.arity() >= 4)) 04414 throw ParserException("Expected at least 3 args in BVPLUS:\n\n" 04415 +e.toString()); 04416 if(!e[1].isRational() || !e[1].getRational().isInteger()) 04417 throw ParserException 04418 ("Expected integer constant in BVPLUS:\n\n" 04419 +e.toString()); 04420 if(!(e[1].getRational().getInt() > 0)) 04421 throw ParserException("parameter must be an integer constant > 0.\n" 04422 +e.toString()); 04423 // Skip first two elements of the vector of kids in 'e'. 04424 // The first element is the kind, and the second is the 04425 // numOfBits of the bvplus operator. 04426 ++i;++i; 04427 Expr child; 04428 // Parse the kids of e and push them into the vector 'k' 04429 for(; i!=iend; ++i) { 04430 child = parseExpr(*i); 04431 if (getBaseType(child).getExpr().getOpKind() != BITVECTOR) { 04432 throw ParserException("BVPLUS argument is not bitvector"); 04433 } 04434 k.push_back(child); 04435 } 04436 return newBVPlusPadExpr(e[1].getRational().getInt(), k); 04437 } 04438 break; 04439 } 04440 case BVSUB: { 04441 if (e.arity() == 3) { 04442 Expr summand1 = parseExpr(e[1]); 04443 Expr summand2 = parseExpr(e[2]); 04444 if (getBaseType(summand1).getExpr().getOpKind() != BITVECTOR 04445 || getBaseType(summand2).getExpr().getOpKind() != BITVECTOR) { 04446 throw ParserException("BVSUB argument is not bitvector"); 04447 } 04448 if (BVSize(summand1) != BVSize(summand2)) { 04449 throw ParserException("BVSUB: expected same sized arguments" 04450 +e.toString()); 04451 } 04452 return newBVSubExpr(summand1, summand2); 04453 } 04454 else if (e.arity() != 4) 04455 throw ParserException("BVSUB: wrong number of arguments:\n\n" 04456 +e.toString()); 04457 if (!e[1].isRational() || !e[1].getRational().isInteger()) 04458 throw ParserException("BVSUB: expected an integer constant as " 04459 "first argument:\n\n" 04460 +e.toString()); 04461 if (!(e[1].getRational().getInt() > 0)) 04462 throw ParserException("parameter must be an integer constant > 0.\n" 04463 +e.toString()); 04464 int bvsublength = e[1].getRational().getInt(); 04465 Expr summand1 = parseExpr(e[2]); 04466 Expr summand2 = parseExpr(e[3]); 04467 if (getBaseType(summand1).getExpr().getOpKind() != BITVECTOR 04468 || getBaseType(summand2).getExpr().getOpKind() != BITVECTOR) { 04469 throw ParserException("BVSUB argument is not bitvector"); 04470 } 04471 summand1 = pad(bvsublength, summand1); 04472 summand2 = pad(bvsublength, summand2); 04473 return newBVSubExpr(summand1, summand2); 04474 break; 04475 } 04476 case BVMULT: { 04477 vector<Expr> k; 04478 Expr::iterator i = e.begin(), iend=e.end(); 04479 if (!e[1].isRational()) { 04480 if (e.arity() != 3) { 04481 throw ParserException("TheoryBitvector::parseExprOp: BVMULT: " 04482 "expected exactly 2 args:\n\n" 04483 + e.toString()); 04484 } 04485 int maxsize = 0; 04486 Expr child; 04487 // Parse the kids of e and push them into the vector 'k' 04488 for(++i; i!=iend; ++i) { 04489 child = parseExpr(*i); 04490 if (getBaseType(child).getExpr().getOpKind() != BITVECTOR) { 04491 throw ParserException("BVMULT argument is not bitvector"); 04492 } 04493 if (BVSize(child) > maxsize) maxsize = BVSize(child); 04494 k.push_back(child); 04495 } 04496 if (e.arity() == 1) return k[0]; 04497 return newBVMultPadExpr(maxsize, k[0], k[1]); 04498 } 04499 if(!(e.arity() == 4)) 04500 throw ParserException("TheoryBitvector::parseExprOp: BVMULT: " 04501 "expected exactly 3 args:\n\n" 04502 + e.toString()); 04503 if(!e[1].isRational() || !e[1].getRational().isInteger()) 04504 throw ParserException("BVMULT: expected integer constant" 04505 "as first argument:\n\n" 04506 +e.toString()); 04507 if(!(e[1].getRational().getInt() > 0)) 04508 throw ParserException("parameter must be an integer constant > 0.\n" 04509 +e.toString()); 04510 Expr a = parseExpr(e[2]); 04511 Expr b = parseExpr(e[3]); 04512 if (getBaseType(a).getExpr().getOpKind() != BITVECTOR 04513 || getBaseType(b).getExpr().getOpKind() != BITVECTOR) { 04514 throw ParserException("BVMULT argument is not bitvector"); 04515 } 04516 return newBVMultPadExpr(e[1].getRational().getInt(),a,b); 04517 break; 04518 } 04519 case BVUDIV: 04520 case BVSDIV: 04521 case BVUREM: 04522 case BVSREM: 04523 case BVSMOD: 04524 case BVSHL: 04525 case BVASHR: 04526 case BVLSHR: { 04527 if(!(e.arity() == 3)) 04528 throw ParserException("TheoryBitvector::parseExprOp:" 04529 "kind should have exactly 2 args:\n\n" 04530 + e.toString()); 04531 Expr e1 = parseExpr(e[1]); 04532 Expr e2 = parseExpr(e[2]); 04533 if (e1.getType().getExpr().getOpKind() != BITVECTOR || 04534 e2.getType().getExpr().getOpKind() != BITVECTOR) 04535 throw ParserException("TheoryBitvector::parseExprOp:" 04536 "Expected bitvector arguments:\n\n" 04537 + e.toString()); 04538 if (BVSize(e1) != BVSize(e2)) 04539 throw ParserException("TheoryBitvector::parseExprOp:" 04540 "Expected bitvectors of same size:\n\n" 04541 + e.toString()); 04542 if (kind == BVSHL) { 04543 if (e2.getKind() == BVCONST) 04544 return newFixedConstWidthLeftShiftExpr(e1, 04545 computeBVConst(e2).getInt()); 04546 } 04547 else if (kind == BVLSHR) { 04548 if (e2.getKind() == BVCONST) 04549 return newFixedRightShiftExpr(e1, computeBVConst(e2).getInt()); 04550 } 04551 return Expr(kind, e1, e2); 04552 break; 04553 } 04554 04555 case BVLT: 04556 if(!(e.arity() == 3)) 04557 throw ParserException("TheoryBitvector::parseExprOp: BVLT" 04558 "kind should have exactly 2 arg:\n\n" 04559 + e.toString()); 04560 return newBVLTExpr(parseExpr(e[1]),parseExpr(e[2])); 04561 break; 04562 case BVLE: 04563 if(!(e.arity() == 3)) 04564 throw ParserException("TheoryBitvector::parseExprOp: BVLE" 04565 "kind should have exactly 2 arg:\n\n" 04566 + e.toString()); 04567 return newBVLEExpr(parseExpr(e[1]),parseExpr(e[2])); 04568 break; 04569 case BVGT: 04570 if(!(e.arity() == 3)) 04571 throw ParserException("TheoryBitvector::parseExprOp: BVGT" 04572 "kind should have exactly 2 arg:\n\n" 04573 + e.toString()); 04574 return newBVLTExpr(parseExpr(e[2]),parseExpr(e[1])); 04575 break; 04576 case BVGE: 04577 if(!(e.arity() == 3)) 04578 throw ParserException("TheoryBitvector::parseExprOp: BVGE" 04579 "kind should have exactly 2 arg:\n\n" 04580 + e.toString()); 04581 return newBVLEExpr(parseExpr(e[2]),parseExpr(e[1])); 04582 break; 04583 case BVSLT: 04584 if(!(e.arity() == 3)) 04585 throw ParserException("TheoryBitvector::parseExprOp: BVLT" 04586 "kind should have exactly 2 arg:\n\n" 04587 + e.toString()); 04588 return newBVSLTExpr(parseExpr(e[1]),parseExpr(e[2])); 04589 break; 04590 case BVSLE: 04591 if(!(e.arity() == 3)) 04592 throw ParserException("TheoryBitvector::parseExprOp: BVLE" 04593 "kind should have exactly 2 arg:\n\n" 04594 + e.toString()); 04595 return newBVSLEExpr(parseExpr(e[1]),parseExpr(e[2])); 04596 break; 04597 case BVSGT: 04598 if(!(e.arity() == 3)) 04599 throw ParserException("TheoryBitvector::parseExprOp: BVGT" 04600 "kind should have exactly 2 arg:\n\n" 04601 + e.toString()); 04602 return newBVSLTExpr(parseExpr(e[2]),parseExpr(e[1])); 04603 break; 04604 case BVSGE: 04605 if(!(e.arity() == 3)) 04606 throw ParserException("TheoryBitvector::parseExprOp: BVGE" 04607 "kind should have exactly 2 arg:\n\n" 04608 + e.toString()); 04609 return newBVSLEExpr(parseExpr(e[2]),parseExpr(e[1])); 04610 break; 04611 04612 case INTTOBV: 04613 throw ParserException("INTTOBV not implemented"); 04614 break; 04615 case BVTOINT: 04616 throw ParserException("BVTOINT not implemented"); 04617 break; 04618 04619 case BVTYPEPRED: 04620 throw ParserException("BVTYPEPRED is used internally"); 04621 break; 04622 04623 default: 04624 FatalAssert(false, 04625 "TheoryBitvector::parseExprOp: unrecognized input operator" 04626 +e.toString()); 04627 break; 04628 } 04629 return e; 04630 } 04631 04632 04633 /////////////////////////////////////////////////////////////////////////////// 04634 //helper functions 04635 /////////////////////////////////////////////////////////////////////////////// 04636 04637 04638 Expr TheoryBitvector::newBitvectorTypeExpr(int bvLength) 04639 { 04640 DebugAssert(bvLength > 0, 04641 "TheoryBitvector::newBitvectorTypeExpr:\n" 04642 "len of a BV must be a positive integer:\n bvlength = "+ 04643 int2string(bvLength)); 04644 if (bvLength > d_maxLength) 04645 d_maxLength = bvLength; 04646 return Expr(BITVECTOR, getEM()->newRatExpr(bvLength)); 04647 } 04648 04649 04650 Expr TheoryBitvector::newBitvectorTypePred(const Type& t, const Expr& e) 04651 { 04652 return Expr(Expr(BVTYPEPRED, t.getExpr()).mkOp(), e); 04653 } 04654 04655 04656 Expr TheoryBitvector::newBVAndExpr(const Expr& t1, const Expr& t2) 04657 { 04658 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04659 BITVECTOR == t2.getType().getExpr().getOpKind(), 04660 "TheoryBitvector::newBVAndExpr:" 04661 "inputs must have type BITVECTOR:\n t1 = " + 04662 t1.toString() + "\n t2 = " +t2.toString()); 04663 DebugAssert(BVSize(t1) == BVSize(t2), 04664 "TheoryBitvector::bitwise operator" 04665 "inputs must have same length:\n t1 = " + t1.toString() 04666 + "\n t2 = " + t2.toString()); 04667 return Expr(CVC3::BVAND, t1, t2); 04668 } 04669 04670 04671 Expr TheoryBitvector::newBVAndExpr(const vector<Expr>& kids) 04672 { 04673 DebugAssert(kids.size() >= 2, 04674 "TheoryBitvector::newBVAndExpr:" 04675 "# of subterms must be at least 2"); 04676 for(unsigned int i=0; i<kids.size(); ++i) { 04677 DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(), 04678 "TheoryBitvector::newBVAndExpr:" 04679 "inputs must have type BITVECTOR:\n t1 = " + 04680 kids[i].toString()); 04681 if(i < kids.size()-1) { 04682 DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]), 04683 "TheoryBitvector::bitwise operator" 04684 "inputs must have same length:\n t1 = " + kids[i].toString() 04685 + "\n t2 = " + kids[i+1].toString()); 04686 } 04687 } 04688 return Expr(CVC3::BVAND, kids, getEM()); 04689 } 04690 04691 04692 Expr TheoryBitvector::newBVOrExpr(const Expr& t1, const Expr& t2) 04693 { 04694 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04695 BITVECTOR == t2.getType().getExpr().getOpKind(), 04696 "TheoryBitvector::newBVOrExpr: " 04697 "inputs must have type BITVECTOR:\n t1 = " + 04698 t1.toString() + "\n t2 = " +t2.toString()); 04699 DebugAssert(BVSize(t1) == BVSize(t2), 04700 "TheoryBitvector::bitwise OR operator: " 04701 "inputs must have same length:\n t1 = " + t1.toString() 04702 + "\n t2 = " + t2.toString()); 04703 return Expr(CVC3::BVOR, t1, t2); 04704 } 04705 04706 04707 Expr TheoryBitvector::newBVOrExpr(const vector<Expr>& kids) 04708 { 04709 DebugAssert(kids.size() >= 2, 04710 "TheoryBitvector::newBVOrExpr: " 04711 "# of subterms must be at least 2"); 04712 for(unsigned int i=0; i<kids.size(); ++i) { 04713 DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(), 04714 "TheoryBitvector::newBVOrExpr: " 04715 "inputs must have type BITVECTOR:\n t1 = " + 04716 kids[i].toString()); 04717 if(i < kids.size()-1) { 04718 DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]), 04719 "TheoryBitvector::bitwise operator" 04720 "inputs must have same length:\n t1 = " + kids[i].toString() 04721 + "\n t2 = " + kids[i+1].toString()); 04722 } 04723 } 04724 return Expr(CVC3::BVOR, kids, getEM()); 04725 } 04726 04727 04728 Expr TheoryBitvector::newBVNandExpr(const Expr& t1, const Expr& t2) 04729 { 04730 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04731 BITVECTOR == t2.getType().getExpr().getOpKind(), 04732 "TheoryBitvector::newBVNandExpr:" 04733 "inputs must have type BITVECTOR:\n t1 = " + 04734 t1.toString() + "\n t2 = " +t2.toString()); 04735 DebugAssert(BVSize(t1) == BVSize(t2), 04736 "TheoryBitvector::bitwise operator" 04737 "inputs must have same length:\n t1 = " + t1.toString() 04738 + "\n t2 = " + t2.toString()); 04739 return Expr(CVC3::BVNAND, t1, t2); 04740 } 04741 04742 04743 Expr TheoryBitvector::newBVNorExpr(const Expr& t1, const Expr& t2) 04744 { 04745 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04746 BITVECTOR == t2.getType().getExpr().getOpKind(), 04747 "TheoryBitvector::newBVNorExpr:" 04748 "inputs must have type BITVECTOR:\n t1 = " + 04749 t1.toString() + "\n t2 = " +t2.toString()); 04750 DebugAssert(BVSize(t1) == BVSize(t2), 04751 "TheoryBitvector::bitwise operator" 04752 "inputs must have same length:\n t1 = " + t1.toString() 04753 + "\n t2 = " + t2.toString()); 04754 return Expr(CVC3::BVNOR, t1, t2); 04755 } 04756 04757 04758 Expr TheoryBitvector::newBVXorExpr(const Expr& t1, const Expr& t2) 04759 { 04760 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04761 BITVECTOR == t2.getType().getExpr().getOpKind(), 04762 "TheoryBitvector::newBVXorExpr:" 04763 "inputs must have type BITVECTOR:\n t1 = " + 04764 t1.toString() + "\n t2 = " +t2.toString()); 04765 DebugAssert(BVSize(t1) == BVSize(t2), 04766 "TheoryBitvector::bitwise operator" 04767 "inputs must have same length:\n t1 = " + t1.toString() 04768 + "\n t2 = " + t2.toString()); 04769 return Expr(CVC3::BVXOR, t1, t2); 04770 } 04771 04772 04773 Expr TheoryBitvector::newBVXorExpr(const vector<Expr>& kids) 04774 { 04775 DebugAssert(kids.size() >= 2, 04776 "TheoryBitvector::newBVXorExpr:" 04777 "# of subterms must be at least 2"); 04778 for(unsigned int i=0; i<kids.size(); ++i) { 04779 DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(), 04780 "TheoryBitvector::newBVXorExpr:" 04781 "inputs must have type BITVECTOR:\n t1 = " + 04782 kids[i].toString()); 04783 if(i < kids.size()-1) { 04784 DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]), 04785 "TheoryBitvector::bitwise operator" 04786 "inputs must have same length:\n t1 = " + kids[i].toString() 04787 + "\n t2 = " + kids[i+1].toString()); 04788 } 04789 } 04790 return Expr(CVC3::BVXOR, kids, getEM()); 04791 } 04792 04793 04794 Expr TheoryBitvector::newBVXnorExpr(const Expr& t1, const Expr& t2) 04795 { 04796 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04797 BITVECTOR == t2.getType().getExpr().getOpKind(), 04798 "TheoryBitvector::newBVXnorExpr:" 04799 "inputs must have type BITVECTOR:\n t1 = " + 04800 t1.toString() + "\n t2 = " +t2.toString()); 04801 DebugAssert(BVSize(t1) == BVSize(t2), 04802 "TheoryBitvector::bitwise operator" 04803 "inputs must have same length:\n t1 = " + t1.toString() 04804 + "\n t2 = " + t2.toString()); 04805 return Expr(CVC3::BVXNOR, t1, t2); 04806 } 04807 04808 04809 Expr TheoryBitvector::newBVCompExpr(const Expr& t1, const Expr& t2) 04810 { 04811 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04812 BITVECTOR == t2.getType().getExpr().getOpKind(), 04813 "TheoryBitvector::newBVCompExpr:" 04814 "inputs must have type BITVECTOR:\n t1 = " + 04815 t1.toString() + "\n t2 = " +t2.toString()); 04816 DebugAssert(BVSize(t1) == BVSize(t2), 04817 "TheoryBitvector::bitwise operator" 04818 "inputs must have same length:\n t1 = " + t1.toString() 04819 + "\n t2 = " + t2.toString()); 04820 return Expr(CVC3::BVCOMP, t1, t2); 04821 } 04822 04823 04824 Expr TheoryBitvector::newBVXnorExpr(const vector<Expr>& kids) 04825 { 04826 DebugAssert(kids.size() >= 2, 04827 "TheoryBitvector::newBVXnorExpr:" 04828 "# of subterms must be at least 2"); 04829 for(unsigned int i=0; i<kids.size(); ++i) { 04830 DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(), 04831 "TheoryBitvector::newBVXnorExpr:" 04832 "inputs must have type BITVECTOR:\n t1 = " + 04833 kids[i].toString()); 04834 if(i < kids.size()-1) { 04835 DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]), 04836 "TheoryBitvector::bitwise operator" 04837 "inputs must have same length:\n t1 = " + kids[i].toString() 04838 + "\n t2 = " + kids[i+1].toString()); 04839 } 04840 } 04841 return Expr(CVC3::BVXNOR, kids, getEM()); 04842 } 04843 04844 04845 Expr TheoryBitvector::newBVLTExpr(const Expr& t1, const Expr& t2) 04846 { 04847 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04848 BITVECTOR == t2.getType().getExpr().getOpKind(), 04849 "TheoryBitvector::newBVLTExpr:" 04850 "inputs must have type BITVECTOR:\n t1 = " + 04851 t1.toString() + "\n t2 = " +t2.toString()); 04852 return Expr(CVC3::BVLT, t1, t2); 04853 } 04854 04855 04856 Expr TheoryBitvector::newBVLEExpr(const Expr& t1, const Expr& t2) 04857 { 04858 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04859 BITVECTOR == t2.getType().getExpr().getOpKind(), 04860 "TheoryBitvector::newBVLEExpr:" 04861 "inputs must have type BITVECTOR:\n t1 = " + 04862 t1.toString() + "\n t2 = " +t2.toString()); 04863 return Expr(CVC3::BVLE, t1, t2); 04864 } 04865 04866 04867 Expr TheoryBitvector::newSXExpr(const Expr& t1, int len) 04868 { 04869 DebugAssert(len >=0, 04870 " TheoryBitvector::newSXExpr:" 04871 "SX index must be a non-negative integer"+ 04872 int2string(len)); 04873 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04874 "TheoryBitvector::newSXExpr:" 04875 "inputs must have type BITVECTOR:\n t1 = " + 04876 t1.toString()); 04877 if(len==0) return t1; 04878 return Expr(Expr(SX, getEM()->newRatExpr(len)).mkOp(), t1); 04879 } 04880 04881 04882 Expr TheoryBitvector::newBVIndexExpr(int kind, const Expr& t1, int len) 04883 { 04884 DebugAssert(kind != BVREPEAT || len > 0, 04885 "repeat requires index > 0"); 04886 DebugAssert(len >=0, 04887 "TheoryBitvector::newBVIndexExpr:" 04888 "index must be a non-negative integer"+ 04889 int2string(len)); 04890 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04891 "TheoryBitvector::newBVIndexExpr:" 04892 "inputs must have type BITVECTOR:\n t1 = " + 04893 t1.toString()); 04894 return Expr(Expr(kind, getEM()->newRatExpr(len)).mkOp(), t1); 04895 } 04896 04897 04898 Expr TheoryBitvector::newBVSLTExpr(const Expr& t1, const Expr& t2) 04899 { 04900 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04901 BITVECTOR == t2.getType().getExpr().getOpKind(), 04902 "TheoryBitvector::newBVSLTExpr:" 04903 "inputs must have type BITVECTOR:\n t1 = " + 04904 t1.toString() + "\n t2 = " +t2.toString()); 04905 return Expr(CVC3::BVSLT, t1, t2); 04906 } 04907 04908 04909 Expr TheoryBitvector::newBVSLEExpr(const Expr& t1, const Expr& t2) 04910 { 04911 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 04912 BITVECTOR == t2.getType().getExpr().getOpKind(), 04913 "TheoryBitvector::newBVSLEExpr:" 04914 "inputs must have type BITVECTOR:\n t1 = " + 04915 t1.toString() + "\n t2 = " +t2.toString()); 04916 return Expr(CVC3::BVSLE, t1, t2); 04917 } 04918 04919 04920 Expr TheoryBitvector::newBVNegExpr(const Expr& t1) 04921 { 04922 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04923 "TheoryBitvector::newBVNegExpr:" 04924 "inputs must have type BITVECTOR:\n t1 = " + 04925 t1.toString()); 04926 return Expr(CVC3::BVNEG, t1); 04927 } 04928 04929 04930 Expr TheoryBitvector::newBVUminusExpr(const Expr& t1) 04931 { 04932 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04933 "TheoryBitvector::newBVNegExpr:" 04934 "inputs must have type BITVECTOR:\n t1 = " + 04935 t1.toString()); 04936 return Expr(CVC3::BVUMINUS, t1); 04937 } 04938 04939 04940 Expr TheoryBitvector::newBoolExtractExpr(const Expr& t1, int index) 04941 { 04942 DebugAssert(index >=0, 04943 " TheoryBitvector::newBoolExtractExpr:" 04944 "bool_extract index must be a non-negative integer"+ 04945 int2string(index)); 04946 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04947 "TheoryBitvector::newBVBoolExtractExpr:" 04948 "inputs must have type BITVECTOR:\n t1 = " + 04949 t1.toString()); 04950 return Expr(Expr(BOOLEXTRACT, getEM()->newRatExpr(index)).mkOp(), t1); 04951 } 04952 04953 04954 Expr TheoryBitvector::newFixedLeftShiftExpr(const Expr& t1, int shiftLength) 04955 { 04956 DebugAssert(shiftLength >=0, 04957 " TheoryBitvector::newFixedleftshift:" 04958 "fixed_shift index must be a non-negative integer"+ 04959 int2string(shiftLength)); 04960 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04961 "TheoryBitvector::newBVFixedleftshiftExpr:" 04962 "inputs must have type BITVECTOR:\n t1 = " + 04963 t1.toString()); 04964 return Expr(Expr(LEFTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1); 04965 } 04966 04967 04968 Expr TheoryBitvector::newFixedConstWidthLeftShiftExpr(const Expr& t1, int shiftLength) 04969 { 04970 DebugAssert(shiftLength >=0, 04971 " TheoryBitvector::newFixedConstWidthLeftShift:" 04972 "fixed_shift index must be a non-negative integer"+ 04973 int2string(shiftLength)); 04974 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04975 "TheoryBitvector::newBVFixedleftshiftExpr:" 04976 "inputs must have type BITVECTOR:\n t1 = " + 04977 t1.toString()); 04978 return Expr(Expr(CONST_WIDTH_LEFTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1); 04979 } 04980 04981 04982 Expr TheoryBitvector::newFixedRightShiftExpr(const Expr& t1, int shiftLength) 04983 { 04984 DebugAssert(shiftLength >=0, 04985 " TheoryBitvector::newFixedRightShift:" 04986 "fixed_shift index must be a non-negative integer"+ 04987 int2string(shiftLength)); 04988 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(), 04989 "TheoryBitvector::newBVFixedRightShiftExpr:" 04990 "inputs must have type BITVECTOR:\n t1 = " + 04991 t1.toString()); 04992 if(shiftLength==0) return t1; 04993 return Expr(Expr(RIGHTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1); 04994 } 04995 04996 04997 Expr TheoryBitvector::newConcatExpr(const Expr& t1, const Expr& t2) 04998 { 04999 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05000 BITVECTOR == t2.getType().getExpr().getOpKind(), 05001 "TheoryBitvector::newBVConcatExpr:" 05002 "inputs must have type BITVECTOR:\n t1 = " + 05003 t1.toString() + "\n t2 = " +t2.toString()); 05004 return Expr(CONCAT, t1, t2); 05005 } 05006 05007 05008 Expr TheoryBitvector::newConcatExpr(const Expr& t1, const Expr& t2, 05009 const Expr& t3) 05010 { 05011 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05012 BITVECTOR == t2.getType().getExpr().getOpKind() && 05013 BITVECTOR == t3.getType().getExpr().getOpKind(), 05014 "TheoryBitvector::newBVConcatExpr:" 05015 "inputs must have type BITVECTOR:\n t1 = " + 05016 t1.toString() + 05017 "\n t2 = " +t2.toString() + 05018 "\n t3 =" + t3.toString()); 05019 return Expr(CONCAT, t1, t2, t3); 05020 } 05021 05022 05023 Expr TheoryBitvector::newConcatExpr(const vector<Expr>& kids) 05024 { 05025 DebugAssert(kids.size() >= 2, 05026 "TheoryBitvector::newBVConcatExpr:" 05027 "# of subterms must be at least 2"); 05028 for(unsigned int i=0; i<kids.size(); ++i) { 05029 DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(), 05030 "TheoryBitvector::newBVConcatExpr:" 05031 "inputs must have type BITVECTOR:\n t1 = " + 05032 kids[i].toString()); 05033 } 05034 return Expr(CONCAT, kids, getEM()); 05035 } 05036 05037 05038 Expr TheoryBitvector::newBVMultExpr(int bvLength, 05039 const Expr& t1, const Expr& t2) 05040 { 05041 DebugAssert(bvLength > 0, 05042 "TheoryBitvector::newBVmultExpr:" 05043 "bvLength must be an integer > 0: bvLength = " + 05044 int2string(bvLength)); 05045 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05046 BITVECTOR == t2.getType().getExpr().getOpKind(), 05047 "TheoryBitvector::newBVmultExpr:" 05048 "inputs must have type BITVECTOR:\n t1 = " + 05049 t1.toString() + "\n t2 = " +t2.toString()); 05050 DebugAssert(bvLength == BVSize(t1) && 05051 bvLength == BVSize(t2), "Expected same length"); 05052 return Expr(Expr(BVMULT, getEM()->newRatExpr(bvLength)).mkOp(), t1, t2); 05053 } 05054 05055 05056 Expr TheoryBitvector::newBVMultExpr(int bvLength, const vector<Expr>& kids) 05057 { 05058 DebugAssert(bvLength > 0, 05059 "TheoryBitvector::newBVmultExpr:" 05060 "bvLength must be an integer > 0: bvLength = " + 05061 int2string(bvLength)); 05062 for(unsigned int i=0; i<kids.size(); ++i) { 05063 DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(), 05064 "TheoryBitvector::newBVPlusExpr:" 05065 "inputs must have type BITVECTOR:\n t1 = " + 05066 kids[i].toString()); 05067 DebugAssert(BVSize(kids[i]) == bvLength, "Expected matching sizes"); 05068 } 05069 return Expr(Expr(BVMULT, getEM()->newRatExpr(bvLength)).mkOp(), kids); 05070 } 05071 05072 05073 Expr TheoryBitvector::newBVMultPadExpr(int bvLength, const vector<Expr>& kids) 05074 { 05075 vector<Expr> newKids; 05076 for (unsigned i = 0; i < kids.size(); ++i) { 05077 newKids.push_back(pad(bvLength, kids[i])); 05078 } 05079 return newBVMultExpr(bvLength, newKids); 05080 } 05081 05082 05083 Expr TheoryBitvector::newBVMultPadExpr(int bvLength, 05084 const Expr& t1, const Expr& t2) 05085 { 05086 return newBVMultExpr(bvLength, pad(bvLength, t1), pad(bvLength, t2)); 05087 } 05088 05089 Expr TheoryBitvector::newBVUDivExpr(const Expr& t1, const Expr& t2) 05090 { 05091 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05092 BITVECTOR == t2.getType().getExpr().getOpKind(), 05093 "TheoryBitvector::newBVUDivExpr:" 05094 "inputs must have type BITVECTOR:\n t1 = " + 05095 t1.toString() + "\n t2 = " +t2.toString()); 05096 DebugAssert(BVSize(t2) == BVSize(t1), "Expected same length"); 05097 return Expr(BVUDIV, t1, t2); 05098 } 05099 05100 Expr TheoryBitvector::newBVURemExpr(const Expr& t1, const Expr& t2) 05101 { 05102 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05103 BITVECTOR == t2.getType().getExpr().getOpKind(), 05104 "TheoryBitvector::newBVURemExpr:" 05105 "inputs must have type BITVECTOR:\n t1 = " + 05106 t1.toString() + "\n t2 = " +t2.toString()); 05107 DebugAssert(BVSize(t2) == BVSize(t1), "Expected same length"); 05108 return Expr(BVUREM, t1, t2); 05109 } 05110 05111 Expr TheoryBitvector::newBVSDivExpr(const Expr& t1, const Expr& t2) 05112 { 05113 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05114 BITVECTOR == t2.getType().getExpr().getOpKind(), 05115 "TheoryBitvector::newBVSDivExpr:" 05116 "inputs must have type BITVECTOR:\n t1 = " + 05117 t1.toString() + "\n t2 = " +t2.toString()); 05118 DebugAssert(BVSize(t1) == BVSize(t2), "Expected same length"); 05119 return Expr(BVSDIV, t1, t2); 05120 } 05121 05122 Expr TheoryBitvector::newBVSRemExpr(const Expr& t1, const Expr& t2) 05123 { 05124 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05125 BITVECTOR == t2.getType().getExpr().getOpKind(), 05126 "TheoryBitvector::newBVSRemExpr:" 05127 "inputs must have type BITVECTOR:\n t1 = " + 05128 t1.toString() + "\n t2 = " +t2.toString()); 05129 DebugAssert(BVSize(t1) == BVSize(t2), "Expected same length"); 05130 return Expr(BVSREM, t1, t2); 05131 } 05132 05133 Expr TheoryBitvector::newBVSModExpr(const Expr& t1, const Expr& t2) 05134 { 05135 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05136 BITVECTOR == t2.getType().getExpr().getOpKind(), 05137 "TheoryBitvector::newBVSModExpr:" 05138 "inputs must have type BITVECTOR:\n t1 = " + 05139 t1.toString() + "\n t2 = " +t2.toString()); 05140 DebugAssert(BVSize(t1) == BVSize(t2), "Expected same length"); 05141 return Expr(BVSMOD, t1, t2); 05142 } 05143 05144 //! produces a string of 0's of length bvLength 05145 Expr TheoryBitvector::newBVZeroString(int bvLength) 05146 { 05147 DebugAssert(bvLength > 0, 05148 "TheoryBitvector::newBVZeroString:must be >= 0: " 05149 + int2string(bvLength)); 05150 std::vector<bool> bits; 05151 for(int count=0; count < bvLength; count++) { 05152 bits.push_back(false); 05153 } 05154 return newBVConstExpr(bits); 05155 } 05156 05157 05158 //! produces a string of 1's of length bvLength 05159 Expr TheoryBitvector::newBVOneString(int bvLength) 05160 { 05161 DebugAssert(bvLength > 0, 05162 "TheoryBitvector::newBVOneString:must be >= 0: " 05163 + int2string(bvLength)); 05164 std::vector<bool> bits; 05165 for(int count=0; count < bvLength; count++) { 05166 bits.push_back(true); 05167 } 05168 return newBVConstExpr(bits); 05169 } 05170 05171 05172 Expr TheoryBitvector::newBVConstExpr(const vector<bool>& bits) 05173 { 05174 DebugAssert(bits.size() > 0, 05175 "TheoryBitvector::newBVConstExpr:" 05176 "size of bits should be > 0"); 05177 BVConstExpr bv(getEM(), bits, d_bvConstExprIndex); 05178 return getEM()->newExpr(&bv); 05179 } 05180 05181 05182 Expr TheoryBitvector::newBVConstExpr(const Rational& r, int bvLength) 05183 { 05184 DebugAssert(r.isInteger(), 05185 "TheoryBitvector::newBVConstExpr: not an integer: " 05186 + r.toString()); 05187 DebugAssert(bvLength > 0, 05188 "TheoryBitvector::newBVConstExpr: bvLength = " 05189 + int2string(bvLength)); 05190 string s(r.toString(2)); 05191 size_t strsize = s.size(); 05192 size_t length = bvLength; 05193 Expr res; 05194 if(length > 0 && length != strsize) { 05195 //either (length > strsize) or (length < strsize) 05196 if(length < strsize) { 05197 s = s.substr((strsize-length), length); 05198 } else { 05199 string zeros(""); 05200 for(size_t i=0, pad=length-strsize; i < pad; ++i) 05201 zeros += "0"; 05202 s = zeros+s; 05203 } 05204 05205 res = newBVConstExpr(s, 2); 05206 } 05207 else 05208 res = newBVConstExpr(s, 2); 05209 05210 return res; 05211 } 05212 05213 05214 Expr TheoryBitvector::newBVConstExpr(const std::string& s, int base) 05215 { 05216 DebugAssert(s.size() > 0, 05217 "TheoryBitvector::newBVConstExpr:" 05218 "# of subterms must be at least 2"); 05219 DebugAssert(base == 2 || base == 16, 05220 "TheoryBitvector::newBVConstExpr: base = " 05221 +int2string(base)); 05222 //hexadecimal 05223 std::string str = s; 05224 if(16 == base) { 05225 Rational r(str, 16); 05226 return newBVConstExpr(r, str.size()*4); 05227 } 05228 else { 05229 BVConstExpr bv(getEM(), str, d_bvConstExprIndex); 05230 return getEM()->newExpr(&bv); 05231 } 05232 } 05233 05234 05235 Expr 05236 TheoryBitvector:: 05237 newBVExtractExpr(const Expr& e, int hi, int low) 05238 { 05239 DebugAssert(low>=0 && hi>=low, 05240 " TheoryBitvector::newBVExtractExpr: " 05241 "bad bv_extract indices: hi = " 05242 + int2string(hi) 05243 + ", low = " 05244 + int2string(low)); 05245 if (e.getOpKind() == LEFTSHIFT && 05246 hi == BVSize(e[0])-1 && 05247 low == 0) { 05248 return newFixedConstWidthLeftShiftExpr(e[0], getFixedLeftShiftParam(e)); 05249 } 05250 DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(), 05251 "TheoryBitvector::newBVExtractExpr:" 05252 "inputs must have type BITVECTOR:\n e = " + 05253 e.toString()); 05254 return Expr(Expr(EXTRACT, 05255 getEM()->newRatExpr(hi), 05256 getEM()->newRatExpr(low)).mkOp(), e); 05257 } 05258 05259 05260 Expr TheoryBitvector::newBVSubExpr(const Expr& t1, const Expr& t2) 05261 { 05262 DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() && 05263 BITVECTOR == t2.getType().getExpr().getOpKind(), 05264 "TheoryBitvector::newBVSubExpr:" 05265 "inputs must have type BITVECTOR:\n t1 = " + 05266 t1.toString() + "\n t2 = " +t2.toString()); 05267 DebugAssert(BVSize(t1) == BVSize(t2), 05268 "TheoryBitvector::newBVSubExpr" 05269 "inputs must have same length:\n t1 = " + t1.toString() 05270 + "\n t2 = " + t2.toString()); 05271 return Expr(BVSUB, t1, t2); 05272 } 05273 05274 05275 Expr TheoryBitvector::newBVPlusExpr(int bvLength, const Expr& k1, const Expr& k2) 05276 { 05277 DebugAssert(bvLength > 0, 05278 " TheoryBitvector::newBVPlusExpr:" 05279 "bvplus length must be a positive integer: "+ 05280 int2string(bvLength)); 05281 DebugAssert(BITVECTOR == k1.getType().getExpr().getOpKind(), 05282 "TheoryBitvector::newBVPlusExpr:" 05283 "inputs must have type BITVECTOR:\n t1 = " + 05284 k1.toString()); 05285 DebugAssert(BVSize(k1) == bvLength, "Expected matching sizes"); 05286 DebugAssert(BITVECTOR == k2.getType().getExpr().getOpKind(), 05287 "TheoryBitvector::newBVPlusExpr:" 05288 "inputs must have type BITVECTOR:\n t1 = " + 05289 k2.toString()); 05290 DebugAssert(BVSize(k2) == bvLength, "Expected matching sizes"); 05291 05292 return Expr(Expr(BVPLUS, getEM()->newRatExpr(bvLength)).mkOp(), k1, k2); 05293 } 05294 05295 05296 Expr TheoryBitvector::newBVPlusExpr(int bvLength, 05297 const vector<Expr>& k) 05298 { 05299 DebugAssert(bvLength > 0, 05300 " TheoryBitvector::newBVPlusExpr:" 05301 "bvplus length must be a positive integer: "+ 05302 int2string(bvLength)); 05303 DebugAssert(k.size() > 1, 05304 " TheoryBitvector::newBVPlusExpr:" 05305 " size of input vector must be greater than 0: "); 05306 for(unsigned int i=0; i<k.size(); ++i) { 05307 DebugAssert(BITVECTOR == k[i].getType().getExpr().getOpKind(), 05308 "TheoryBitvector::newBVPlusExpr:" 05309 "inputs must have type BITVECTOR:\n t1 = " + 05310 k[i].toString()); 05311 DebugAssert(BVSize(k[i]) == bvLength, "Expected matching sizes"); 05312 } 05313 return Expr(Expr(BVPLUS, getEM()->newRatExpr(bvLength)).mkOp(), k); 05314 } 05315 05316 05317 Expr TheoryBitvector::newBVPlusPadExpr(int bvLength, 05318 const vector<Expr>& k) 05319 { 05320 vector<Expr> newKids; 05321 for (unsigned i = 0; i < k.size(); ++i) { 05322 newKids.push_back(pad(bvLength, k[i])); 05323 } 05324 return newBVPlusExpr(bvLength, newKids); 05325 } 05326 05327 05328 // Accessors for expression parameters 05329 05330 05331 int TheoryBitvector::getBitvectorTypeParam(const Expr& e) 05332 { 05333 DebugAssert(BITVECTOR == e.getKind(), 05334 "TheoryBitvector::getBitvectorTypeParam: wrong kind: " + 05335 e.toString()); 05336 return e[0].getRational().getInt(); 05337 } 05338 05339 05340 Type TheoryBitvector::getTypePredType(const Expr& tp) 05341 { 05342 DebugAssert(tp.getOpKind()==BVTYPEPRED && tp.isApply(), 05343 "TheoryBitvector::getTypePredType:\n tp = "+tp.toString()); 05344 return Type(tp.getOpExpr()[0]); 05345 } 05346 05347 05348 const Expr& TheoryBitvector::getTypePredExpr(const Expr& tp) 05349 { 05350 DebugAssert(tp.getOpKind()==BVTYPEPRED, 05351 "TheoryBitvector::getTypePredType:\n tp = "+tp.toString()); 05352 return tp[0]; 05353 } 05354 05355 05356 int TheoryBitvector::getBoolExtractIndex(const Expr& e) 05357 { 05358 DebugAssert(BOOLEXTRACT == e.getOpKind() && e.isApply(), 05359 "TheoryBitvector::getBoolExtractIndex: wrong kind" + 05360 e.toString()); 05361 return e.getOpExpr()[0].getRational().getInt(); 05362 } 05363 05364 05365 int TheoryBitvector::getSXIndex(const Expr& e) 05366 { 05367 DebugAssert(SX == e.getOpKind() && e.isApply(), 05368 "TheoryBitvector::getSXIndex: wrong kind\n"+e.toString()); 05369 return e.getOpExpr()[0].getRational().getInt(); 05370 } 05371 05372 05373 int TheoryBitvector::getBVIndex(const Expr& e) 05374 { 05375 DebugAssert(e.isApply() && 05376 (e.getOpKind() == BVREPEAT || 05377 e.getOpKind() == BVROTL || 05378 e.getOpKind() == BVROTR || 05379 e.getOpKind() == BVZEROEXTEND), 05380 "TheoryBitvector::getBVIndex: wrong kind\n"+e.toString()); 05381 return e.getOpExpr()[0].getRational().getInt(); 05382 } 05383 05384 05385 int TheoryBitvector::getFixedLeftShiftParam(const Expr& e) 05386 { 05387 DebugAssert(e.isApply() && 05388 (LEFTSHIFT == e.getOpKind() || 05389 CONST_WIDTH_LEFTSHIFT == e.getOpKind()), 05390 "TheoryBitvector::getFixedLeftShiftParam: wrong kind" + 05391 e.toString()); 05392 return e.getOpExpr()[0].getRational().getInt(); 05393 } 05394 05395 05396 int TheoryBitvector::getFixedRightShiftParam(const Expr& e) 05397 { 05398 DebugAssert(RIGHTSHIFT == e.getOpKind() && e.isApply(), 05399 "TheoryBitvector::getFixedRightShiftParam: wrong kind" + 05400 e.toString()); 05401 return e.getOpExpr()[0].getRational().getInt(); 05402 } 05403 05404 05405 int TheoryBitvector::getExtractLow(const Expr& e) 05406 { 05407 DebugAssert(EXTRACT == e.getOpKind() && e.isApply(), 05408 "TheoryBitvector::getExtractLow: wrong kind" + 05409 e.toString()); 05410 return e.getOpExpr()[1].getRational().getInt(); 05411 } 05412 05413 05414 int TheoryBitvector::getExtractHi(const Expr& e) 05415 { 05416 DebugAssert(EXTRACT == e.getOpKind() && e.isApply(), 05417 "TheoryBitvector::getExtractHi: wrong kind" + 05418 e.toString()); 05419 return e.getOpExpr()[0].getRational().getInt(); 05420 } 05421 05422 05423 int TheoryBitvector::getBVPlusParam(const Expr& e) 05424 { 05425 DebugAssert(BVPLUS == e.getOpKind() && e.isApply(), 05426 "TheoryBitvector::getBVPlusParam: wrong kind" + 05427 e.toString(AST_LANG)); 05428 return e.getOpExpr()[0].getRational().getInt(); 05429 } 05430 05431 int TheoryBitvector::getBVMultParam(const Expr& e) 05432 { 05433 DebugAssert(BVMULT == e.getOpKind() && e.isApply(), 05434 "TheoryBitvector::getBVMultParam: wrong kind " + 05435 e.toString(AST_LANG)); 05436 return e.getOpExpr()[0].getRational().getInt(); 05437 } 05438 05439 unsigned TheoryBitvector::getBVConstSize(const Expr& e) 05440 { 05441 DebugAssert(BVCONST == e.getKind(), "getBVConstSize called on non-bvconst"); 05442 const BVConstExpr* bvc = dynamic_cast<const BVConstExpr*>(e.getExprValue()); 05443 DebugAssert(bvc, "getBVConstSize: cast failed"); 05444 return bvc->size(); 05445 } 05446 05447 05448 bool TheoryBitvector::getBVConstValue(const Expr& e, int i) 05449 { 05450 DebugAssert(BVCONST == e.getKind(), "getBVConstSize called on non-bvconst"); 05451 const BVConstExpr* bvc = dynamic_cast<const BVConstExpr*>(e.getExprValue()); 05452 DebugAssert(bvc, "getBVConstSize: cast failed"); 05453 return bvc->getValue(i); 05454 } 05455 05456 05457 // as newBVConstExpr can not give the BV expr of a negative rational, 05458 // I use this wrapper to do that 05459 Expr TheoryBitvector::signed_newBVConstExpr( Rational c, int bv_size) 05460 { 05461 if( c > 0) 05462 return newBVConstExpr( c, bv_size); 05463 else 05464 { 05465 c = -c; 05466 Expr tmp = newBVConstExpr( c, bv_size); 05467 Rational neg_tmp = computeNegBVConst( tmp ); 05468 return newBVConstExpr( neg_tmp, bv_size ); 05469 } 05470 } 05471 05472 05473 // Computes the integer value of a bitvector constant 05474 Rational TheoryBitvector::computeBVConst(const Expr& e) 05475 { 05476 DebugAssert(BVCONST == e.getKind(), 05477 "TheoryBitvector::computeBVConst:" 05478 "input must be a BITVECTOR CONST: " + e.toString()); 05479 if(*d_bv32Flag) { 05480 int c(0); 05481 for(int j=(int)getBVConstSize(e)-1; j>=0; j--) 05482 c = 2*c + getBVConstValue(e, j) ? 1 : 0; 05483 Rational d(c); 05484 return d; 05485 } else { 05486 Rational c(0); 05487 for(int j=(int)getBVConstSize(e)-1; j>=0; j--) 05488 c = 2*c + (getBVConstValue(e, j) ? Rational(1) : Rational(0)); 05489 return c; 05490 } 05491 } 05492 05493 05494 // Computes the integer value of ~c+1 05495 Rational TheoryBitvector::computeNegBVConst(const Expr& e) 05496 { 05497 DebugAssert(BVCONST == e.getKind(), 05498 "TheoryBitvector::computeBVConst:" 05499 "input must be a BITVECTOR CONST: " + e.toString()); 05500 if(*d_bv32Flag) { 05501 int c(0); 05502 for(int j=(int)getBVConstSize(e)-1; j>=0; j--) 05503 c = 2*c + getBVConstValue(e, j) ? 0 : 1; 05504 Rational d(c+1); 05505 return d; 05506 } else { 05507 Rational c(0); 05508 for(int j=(int)getBVConstSize(e)-1; j>=0; j--) 05509 c = 2*c + (getBVConstValue(e, j) ? Rational(0) : Rational(1)); 05510 return c+1; 05511 } 05512 } 05513 05514 05515 ////////////////////////////////////////////////////////////////////// 05516 // class BVConstExpr methods 05517 ///////////////////////////////////////////////////////////////////// 05518 05519 05520 //! Constructor 05521 BVConstExpr::BVConstExpr(ExprManager* em, std::string bvconst, 05522 size_t mmIndex, ExprIndex idx) 05523 : ExprValue(em, BVCONST, idx), d_MMIndex(mmIndex) 05524 { 05525 std::string::reverse_iterator i = bvconst.rbegin(); 05526 std::string::reverse_iterator iend = bvconst.rend(); 05527 DebugAssert(bvconst.size() > 0, 05528 "TheoryBitvector::newBVConstExpr:" 05529 "# of subterms must be at least 2"); 05530 05531 for(;i != iend; ++i) { 05532 TRACE("bitvector", "BVConstExpr: bit ", *i, ""); 05533 if('0' == *i) 05534 d_bvconst.push_back(false); 05535 else { 05536 if('1' == *i) 05537 d_bvconst.push_back(true); 05538 else 05539 DebugAssert(false, "BVConstExpr: bad binary bit-vector: " 05540 + bvconst); 05541 } 05542 } 05543 TRACE("bitvector", "BVConstExpr: #bits ", d_bvconst.size(), ""); 05544 } 05545 05546 05547 BVConstExpr::BVConstExpr(ExprManager* em, std::vector<bool> bvconst, 05548 size_t mmIndex, ExprIndex idx) 05549 : ExprValue(em, BVCONST, idx), d_bvconst(bvconst), d_MMIndex(mmIndex) 05550 { 05551 TRACE("bitvector", "BVConstExpr(vector<bool>): arg. size = ", bvconst.size(), 05552 ", d_bvconst.size = "+int2string(d_bvconst.size())); 05553 } 05554 05555 05556 size_t BVConstExpr::computeHash() const 05557 { 05558 std::vector<bool>::const_iterator i = d_bvconst.begin(); 05559 std::vector<bool>::const_iterator iend = d_bvconst.end(); 05560 size_t hash_value = 0; 05561 hash_value = ExprValue::hash(BVCONST); 05562 for (;i != iend; i++) 05563 if(*i) 05564 hash_value = PRIME*hash_value + HASH_VALUE_ONE; 05565 else 05566 hash_value = PRIME*hash_value + HASH_VALUE_ZERO; 05567 return hash_value; 05568 } 05569 05570 Expr TheoryBitvector::computeTCC(const Expr& e) 05571 { 05572 // inline recursive computation for deeply nested bitvector Exprs 05573 05574 vector<Expr> operatorStack; 05575 vector<Expr> operandStack; 05576 vector<int> childStack; 05577 Expr e2, tcc; 05578 05579 operatorStack.push_back(e); 05580 childStack.push_back(0); 05581 05582 while (!operatorStack.empty()) { 05583 DebugAssert(operatorStack.size() == childStack.size(), "Invariant violated"); 05584 05585 if (childStack.back() < operatorStack.back().arity()) { 05586 05587 e2 = operatorStack.back()[childStack.back()++]; 05588 05589 if (e2.isVar()) { 05590 operandStack.push_back(trueExpr()); 05591 } 05592 else { 05593 ExprMap<Expr>::iterator itccCache = theoryCore()->tccCache().find(e2); 05594 if (itccCache != theoryCore()->tccCache().end()) { 05595 operandStack.push_back((*itccCache).second); 05596 } 05597 else if (theoryOf(e2) == this) { 05598 if (e2.arity() == 0) { 05599 operandStack.push_back(trueExpr()); 05600 } 05601 else { 05602 operatorStack.push_back(e2); 05603 childStack.push_back(0); 05604 } 05605 } 05606 else { 05607 operandStack.push_back(getTCC(e2)); 05608 } 05609 } 05610 } 05611 else { 05612 e2 = operatorStack.back(); 05613 operatorStack.pop_back(); 05614 childStack.pop_back(); 05615 vector<Expr> children; 05616 vector<Expr>::iterator childStart = operandStack.end() - (e2.arity()); 05617 children.insert(children.begin(), childStart, operandStack.end()); 05618 operandStack.erase(childStart, operandStack.end()); 05619 tcc = (children.size() == 0) ? trueExpr() : 05620 (children.size() == 1) ? children[0] : 05621 getCommonRules()->rewriteAnd(andExpr(children)).getRHS(); 05622 switch(e2.getKind()) { 05623 case BVUDIV: 05624 case BVSDIV: 05625 case BVUREM: 05626 case BVSREM: 05627 case BVSMOD: { 05628 DebugAssert(e2.arity() == 2, ""); 05629 int size = BVSize(e2); 05630 tcc = getCommonRules()->rewriteAnd(tcc.andExpr(!(e2[1].eqExpr(newBVZeroString(size))))).getRHS(); 05631 break; 05632 } 05633 default: 05634 break; 05635 } 05636 operandStack.push_back(tcc); 05637 theoryCore()->tccCache()[e2] = tcc; 05638 } 05639 } 05640 DebugAssert(childStack.empty(), "Invariant violated"); 05641 DebugAssert(operandStack.size() == 1, "Expected single operand left"); 05642 return operandStack.back(); 05643 }