CVC3
|
00001 /*****************************************************************************/ 00002 /*! 00003 * \file bitvector_theorem_producer.cpp 00004 * 00005 * Author: Vijay Ganesh 00006 * 00007 * Created: Wed May 5 16:19:49 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 // CLASS: BitvectorProofRules 00021 // 00022 // AUTHOR: Vijay Ganesh, 05/30/2003 00023 // 00024 // Description: TRUSTED implementation of bitvector proof rules. 00025 // 00026 /////////////////////////////////////////////////////////////////////////////// 00027 00028 // This code is trusted 00029 #define _CVC3_TRUSTED_ 00030 00031 #include <cstdio> 00032 #include "bitvector_theorem_producer.h" 00033 #include "common_proof_rules.h" 00034 #include "theory_core.h" 00035 #include "theory_bitvector.h" 00036 00037 using namespace std; 00038 using namespace CVC3; 00039 00040 00041 /////////////////////////////////////////////////////////////////////// 00042 // TheoryBitvector:trusted method for creating BitvectorTheoremProducer 00043 /////////////////////////////////////////////////////////////////////// 00044 BitvectorProofRules* 00045 TheoryBitvector::createProofRules() { 00046 return new BitvectorTheoremProducer(this); 00047 } 00048 00049 00050 BitvectorTheoremProducer::BitvectorTheoremProducer(TheoryBitvector* theoryBV) 00051 : TheoremProducer(theoryBV->theoryCore()->getTM()), 00052 d_theoryBitvector(theoryBV) { 00053 // Cache constants 0bin0 and 0bin1 00054 vector<bool> bits(1); 00055 bits[0]=false; 00056 d_bvZero = d_theoryBitvector->newBVConstExpr(bits); 00057 bits[0]=true; 00058 d_bvOne = d_theoryBitvector->newBVConstExpr(bits); 00059 } 00060 00061 00062 /////////////////////////////////////////////////////////////////////// 00063 // BitBlasting rules for equations 00064 /////////////////////////////////////////////////////////////////////// 00065 // |- (BOOLEXTRACT(a,i) <=> BOOLEXTRACT(b,i)) <=> False ==> |- a = b <=> False 00066 Theorem BitvectorTheoremProducer::bitvectorFalseRule(const Theorem& thm) { 00067 if(CHECK_PROOFS) { 00068 const Expr e = thm.getExpr(); 00069 CHECK_SOUND(e.isIff() && e[0].isIff(), 00070 "TheoryBitvector::bitvectorFalseRule: " 00071 "premise must be a iff theorem:\n e = " 00072 +e.toString()); 00073 CHECK_SOUND(e[1].isFalse(), 00074 "TheoryBitvector::bitvectorFalseRule: " 00075 "premise must be iff Theorem, with False as the RHS:\n e = " 00076 +e.toString()); 00077 CHECK_SOUND(e[0][0].getOpKind() == BOOLEXTRACT && 00078 e[0][1].getOpKind() == BOOLEXTRACT, 00079 "TheoryBitvector::bitvectorFalseRule: " 00080 "premise must be iff Theorem, with False as the RHS:\n e = " 00081 +e.toString()); 00082 CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(e[0][0]) == 00083 d_theoryBitvector->getBoolExtractIndex(e[0][1]), 00084 "TheoryBitvector::bitvectorFalseRule: " 00085 "premise must be iff Theorem, with False as the RHS:\n e = " 00086 +e.toString()); 00087 } 00088 const Expr& e = thm.getExpr(); 00089 const Expr& t1 = e[0][0][0]; 00090 const Expr& t2 = e[0][1][0]; 00091 00092 Proof pf; 00093 if(withProof()) 00094 pf = newPf("bitvector_false_rule", e, thm.getProof()); 00095 return newRWTheorem(t1.eqExpr(t2), e[1], thm.getAssumptionsRef(), pf); 00096 } 00097 00098 /*! \param thm input theorem: (~e1[i]<=>e2[i])<=>true 00099 * 00100 * \result (e1!=e2)<=>true 00101 */ 00102 // |- (NOT (BOOLEXTRACT(a,i)) <=> BOOLEXTRACT(b,i)) <=> TRUE ==> 00103 // |- NOT (a = b) <=> TRUE 00104 Theorem BitvectorTheoremProducer::bitvectorTrueRule(const Theorem& thm) { 00105 if(CHECK_PROOFS) { 00106 const Expr e = thm.getExpr(); 00107 CHECK_SOUND(e.isIff() && e[0].isIff(), 00108 "TheoryBitvector::bitvectorFalseRule: " 00109 "premise must be a iff theorem:\n e = " 00110 +e.toString()); 00111 CHECK_SOUND(e[1].isTrue(), 00112 "TheoryBitvector::bitvectorFalseRule: " 00113 "premise must be iff Theorem, with False as the RHS:\n e = " 00114 +e.toString()); 00115 CHECK_SOUND(e[0][0].getKind() == NOT && 00116 e[0][0][0].getOpKind() == BOOLEXTRACT && 00117 e[0][1].getOpKind() == BOOLEXTRACT, 00118 "TheoryBitvector::bitvectorFalseRule: " 00119 "premise must be iff Theorem, with False as the RHS:\n e = " 00120 +e.toString()); 00121 CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(e[0][0][0]) == 00122 d_theoryBitvector->getBoolExtractIndex(e[0][1]), 00123 "TheoryBitvector::bitvectorFalseRule: " 00124 "premise must be iff Theorem, with False as the RHS:\n e = " 00125 +e.toString()); 00126 } 00127 const Expr& e = thm.getExpr(); 00128 //e is (~BE(t1,i)<=>BE(t2,i))<=>true. to extract t1 we have to go 4 level deep 00129 //FIXME: later 00130 const Expr& t1 = e[0][0][0][0]; 00131 const Expr& t2 = e[0][1][0]; 00132 00133 Proof pf; 00134 if(withProof()) 00135 pf = newPf("bitvector_true_rule", e, thm.getProof()); 00136 return newRWTheorem(t1.eqExpr(t2).negate(), e[1], thm.getAssumptionsRef(), pf); 00137 } 00138 00139 // Input: e: a = b 00140 // f :AND_0^(bvLength-1)(a[bitPosition] <=> b[bitPosition]) 00141 // Output: |- e <=> f 00142 Theorem BitvectorTheoremProducer::bitBlastEqnRule(const Expr& e, const Expr& f) 00143 { 00144 if(CHECK_PROOFS) { 00145 CHECK_SOUND(e.isEq(), 00146 "TheoryBitvector::bitBlastEqnRule: " 00147 "premise must be a rewrite theorem:\n e = " 00148 +e.toString()); 00149 const Expr& lhs = e[0]; 00150 const Expr& rhs = e[1]; 00151 const Type& leftType = lhs.getType(); 00152 const Type& rightType = rhs.getType(); 00153 CHECK_SOUND(BITVECTOR == leftType.getExpr().getOpKind() && 00154 BITVECTOR == rightType.getExpr().getOpKind(), 00155 "TheoryBitvector::bitBlastEqnRule: " 00156 "lhs & rhs must be bitvectors:\n e =" 00157 +e.toString()); 00158 int lhsLength = d_theoryBitvector->BVSize(lhs); 00159 int rhsLength = d_theoryBitvector->BVSize(rhs); 00160 CHECK_SOUND(lhsLength == rhsLength, 00161 "TheoryBitvector::bitBlastEqnRule: " 00162 "lhs & rhs must be bitvectors of same bvLength.\n size(lhs) = " 00163 + int2string(lhsLength) 00164 +"\n size(rhs) = " 00165 + int2string(rhsLength) 00166 +"\n e = "+e.toString()); 00167 int bvLength = d_theoryBitvector->BVSize(leftType.getExpr()); 00168 CHECK_SOUND(f.isAnd(), 00169 "TheoryBitvector::bitBlastEqnRule: " 00170 "consequence of the rule must be an AND.\n f = " 00171 +f.toString()); 00172 CHECK_SOUND(bvLength == f.arity(), 00173 "TheoryBitvector::bitBlastEqnRule: " 00174 "the arity of the consequence AND must " 00175 "equal the bvLength of the bitvector:\n f = " 00176 +f.toString()+"\n bvLength = "+ int2string(bvLength)); 00177 for (int i=0; i < bvLength; ++i) { 00178 const Expr& conjunct = f[i]; 00179 CHECK_SOUND(conjunct.isIff() && 2 == conjunct.arity(), 00180 "TheoryBitvector::bitBlastEqnRule: " 00181 "each conjunct in consequent must be an IFF.\n f = " 00182 +f.toString()); 00183 const Expr& leftExtract = conjunct[0]; 00184 const Expr& rightExtract = conjunct[1]; 00185 CHECK_SOUND(BOOLEXTRACT == leftExtract.getOpKind(), 00186 "TheoryBitvector::bitBlastEqnRule: " 00187 "each conjunct in consequent must be boolextract.\n" 00188 " f["+int2string(i)+"] = "+conjunct.toString()); 00189 CHECK_SOUND(BOOLEXTRACT == rightExtract.getOpKind(), 00190 "TheoryBitvector::bitBlastEqnRule: " 00191 "each conjunct in consequent must be boolextract.\n" 00192 " f["+int2string(i)+"] = "+conjunct.toString()); 00193 const Expr& leftBV = leftExtract[0]; 00194 const Expr& rightBV = rightExtract[0]; 00195 CHECK_SOUND(leftBV == lhs && rightBV == rhs, 00196 "TheoryBitvector::bitBlastEqnRule: each boolextract" 00197 " must be applied to the correct bitvector.\n conjunct = " 00198 +conjunct.toString() 00199 +"\n leftBV = "+ leftBV.toString() 00200 +"\n lhs = "+ lhs.toString() 00201 +"\n rightBV = "+rightBV.toString() 00202 +"\n rhs = "+rhs.toString()); 00203 int leftBitPosition = 00204 d_theoryBitvector->getBoolExtractIndex(leftExtract); 00205 int rightBitPosition = 00206 d_theoryBitvector->getBoolExtractIndex(rightExtract); 00207 CHECK_SOUND(leftBitPosition == i && rightBitPosition == i, 00208 "TheoryBitvector::bitBlastEqnRule: " 00209 "boolextract positions must match i= "+int2string(i) 00210 +"\n conjunct = "+conjunct.toString()); 00211 } 00212 } 00213 00214 Proof pf; 00215 if(withProof()) 00216 pf = newPf("bit_blast_equations", e, f); 00217 return newRWTheorem(e, f, Assumptions::emptyAssump(), pf); 00218 } 00219 00220 00221 /////////////////////////////////////////////////////////////////////// 00222 // BitBlasting rules for dis-equations: separate rule for disequations 00223 // for efficiency sake 00224 /////////////////////////////////////////////////////////////////////// 00225 Theorem BitvectorTheoremProducer::bitBlastDisEqnRule(const Theorem& notE, 00226 const Expr& f){ 00227 00228 TRACE("bitvector", "input to bitBlastDisEqnRule(", notE.toString(), ")"); 00229 DebugAssert(notE.getExpr().isNot() && (notE.getExpr())[0].isEq(), 00230 "TheoryBitvector::bitBlastDisEqnRule:" 00231 "expecting an equation" + notE.getExpr().toString()); 00232 //e is the equation 00233 const Expr& e = (notE.getExpr())[0]; 00234 if(CHECK_PROOFS) { 00235 CHECK_SOUND(e.isEq(), 00236 "TheoryBitvector::bitBlastDisEqnRule:" 00237 "premise must be a rewrite theorem" + e.toString()); 00238 const Expr& lhs = e[0]; 00239 const Expr& rhs = e[1]; 00240 const Type& leftType = lhs.getType(); 00241 const Type& rightType = rhs.getType(); 00242 CHECK_SOUND(BITVECTOR == leftType.getExpr().getOpKind() && 00243 BITVECTOR == rightType.getExpr().getOpKind(), 00244 "TheoryBitvector::bitBlastDisEqnRule:" 00245 "lhs & rhs must be bitvectors" + e.toString()); 00246 CHECK_SOUND(d_theoryBitvector->BVSize(leftType.getExpr()) == 00247 d_theoryBitvector->BVSize(rightType.getExpr()), 00248 "TheoryBitvector::bitBlastDisEqnRule:" 00249 "lhs & rhs must be bitvectors of same bvLength"); 00250 int bvLength = d_theoryBitvector->BVSize(leftType.getExpr()); 00251 CHECK_SOUND(f.isOr(), 00252 "TheoryBitvector::bitBlastDisEqnRule:" 00253 "consequence of the rule must be an OR" + f.toString()); 00254 CHECK_SOUND(bvLength == f.arity(), 00255 "TheoryBitvector::bitBlastDisEqnRule:" 00256 "the arity of the consequence OR must be" 00257 "equal to the bvLength of the bitvector" + 00258 f.toString() + int2string(bvLength)); 00259 for(int i=0; i <bvLength; i++) { 00260 const Expr& disjunct = f[i]; 00261 CHECK_SOUND(disjunct.isIff() && 00262 2 == disjunct.arity() && disjunct[0].isNot(), 00263 "TheoryBitvector::bitBlastDisEqnRule:" 00264 "each conjunct in consequent must be an Iff"+f.toString()); 00265 const Expr& leftExtract = (disjunct[0])[0]; 00266 const Expr& rightExtract = disjunct[1]; 00267 CHECK_SOUND(BOOLEXTRACT == leftExtract.getOpKind(), 00268 "TheoryBitvector::bitBlastDisEqnRule:" 00269 "each disjunct in consequent must be boolextract" + 00270 disjunct.toString()); 00271 CHECK_SOUND(BOOLEXTRACT == rightExtract.getOpKind(), 00272 "TheoryBitvector::bitBlastDisEqnRule:" 00273 "each conjunct in consequent must be boolextract" + 00274 disjunct.toString()); 00275 const Expr& leftBV = leftExtract[0]; 00276 const Expr& rightBV = rightExtract[0]; 00277 CHECK_SOUND(leftBV == lhs && rightBV == rhs, 00278 "TheoryBitvector::bitBlastDisEqnRule:" 00279 "each boolextract must be applied to the correct bitvector"+ 00280 disjunct.toString() + leftBV.toString() + lhs.toString() + 00281 rightBV.toString() + rhs.toString()); 00282 int leftBitPosition = 00283 d_theoryBitvector->getBoolExtractIndex(leftExtract); 00284 int rightBitPosition = 00285 d_theoryBitvector->getBoolExtractIndex(rightExtract); 00286 CHECK_SOUND(leftBitPosition == i && rightBitPosition == i, 00287 "TheoryBitvector::bitBlastDisEqnRule:" 00288 "boolextract positions must match" + disjunct.toString()); 00289 } 00290 } 00291 00292 Proof pf; 00293 if(withProof()) 00294 pf = newPf("bit_blast_disequations", notE.getExpr(), f, notE.getProof()); 00295 return newTheorem(f, notE.getAssumptionsRef(), pf); 00296 } 00297 00298 /////////////////////////////////////////////////////////////////////// 00299 // Rules for Inequations 00300 /////////////////////////////////////////////////////////////////////// 00301 00302 00303 //! Pad the kids of BVLT/BVLE to make their bvLength equal 00304 Theorem 00305 BitvectorTheoremProducer::padBVLTRule(const Expr& e, int len) { 00306 if(CHECK_PROOFS) { 00307 CHECK_SOUND((BVLT == e.getOpKind() || BVLE == e.getOpKind()) && 00308 e.arity()==2, 00309 "BitvectorTheoremProducer::padBVLTRule: " 00310 "input must e be a BVLT/BVLE: e = " + e.toString()); 00311 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() && 00312 BITVECTOR==e[1].getType().getExpr().getOpKind(), 00313 "BitvectorTheoremProducer::padBVLTRule: " 00314 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString()); 00315 CHECK_SOUND(0<len, 00316 "BitvectorTheoremProducer::padBVLTRule: " 00317 "input len must be >=0 and an integer: len = " + 00318 int2string(len)); 00319 } 00320 Expr e0 = pad(len, e[0]); 00321 Expr e1 = pad(len, e[1]); 00322 int kind = e.getOpKind(); 00323 00324 Expr output; 00325 if(kind == BVLT) 00326 output = d_theoryBitvector->newBVLTExpr(e0,e1); 00327 else 00328 output = d_theoryBitvector->newBVLEExpr(e0,e1); 00329 00330 Proof pf; 00331 if(withProof()) 00332 pf = newPf("pad_bvlt_rule", e); 00333 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 00334 return result; 00335 } 00336 00337 //! signExtendRule: pads the input e with topBit to length len 00338 Theorem 00339 BitvectorTheoremProducer::signExtendRule(const Expr& e) { 00340 if(CHECK_PROOFS) { 00341 CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(), 00342 "input must be a bitvector. \n e = " + e.toString()); 00343 CHECK_SOUND(SX == e.getOpKind(), 00344 "input must be SX(e).\n e = " + e.toString()); 00345 CHECK_SOUND(SX != e[0].getOpKind(), 00346 "input cannot have nested SX.\n e = " + e.toString()); 00347 } 00348 Expr input0 = e[0]; 00349 //strip the top level SX applications 00350 while(SX == input0.getOpKind()) 00351 input0 = input0[0]; 00352 00353 int bvLength = d_theoryBitvector->BVSize(e); 00354 int bvLength0 = d_theoryBitvector->BVSize(input0); 00355 00356 Expr output; 00357 if(bvLength0 == bvLength) { 00358 output = input0; 00359 } else if(bvLength0 < bvLength) { 00360 std::vector<Expr> k; 00361 int c = bvLength - bvLength0; 00362 Expr topBit = 00363 d_theoryBitvector->newBVExtractExpr(input0,bvLength0-1,bvLength0-1); 00364 while(c--) 00365 k.push_back(topBit); 00366 k.push_back(input0); 00367 output = d_theoryBitvector->newConcatExpr(k); 00368 } else 00369 output = d_theoryBitvector->newBVExtractExpr(input0, bvLength-1, 0); 00370 00371 Proof pf; 00372 if(withProof()) 00373 pf = newPf("sign_extend_rule", e); 00374 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 00375 return result; 00376 } 00377 00378 //! bitExtractSXRule 00379 Theorem 00380 BitvectorTheoremProducer::bitExtractSXRule(const Expr& e, int i) { 00381 //little bit of cheating here. calling a rule from inside a rule. 00382 //just a shorthand 00383 Theorem thm = signExtendRule(e); 00384 Expr e_i = d_theoryBitvector->newBoolExtractExpr(e,i); 00385 Expr newE_i = d_theoryBitvector->newBoolExtractExpr(thm.getRHS(),i); 00386 00387 Proof pf; 00388 if(withProof()) 00389 pf = newPf("bitExtract_SX_rule",e,rat(i)); 00390 Theorem result(newRWTheorem(e_i,newE_i,Assumptions::emptyAssump(),pf)); 00391 return result; 00392 } 00393 00394 00395 //! Pad the kids of SIGN BVLT/SIGN BVLE to make their bvLength equal 00396 Theorem 00397 BitvectorTheoremProducer::padBVSLTRule(const Expr& e, int len) { 00398 if(CHECK_PROOFS) { 00399 CHECK_SOUND((BVSLT == e.getOpKind() || BVSLE == e.getOpKind()) && 00400 e.arity()==2, 00401 "BitvectorTheoremProducer::padBVSLTRule: " 00402 "input must e be a BVSLT/BVSLE: e = " + e.toString()); 00403 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() && 00404 BITVECTOR==e[1].getType().getExpr().getOpKind(), 00405 "BitvectorTheoremProducer::padBVSLTRule: " 00406 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString()); 00407 CHECK_SOUND(0<=len, 00408 "BitvectorTheoremProducer::padBVSLTRule: " 00409 "input len must be >=0 and an integer: len = " + 00410 int2string(len)); 00411 } 00412 Expr e0 = d_theoryBitvector->newSXExpr(e[0], len); 00413 Expr e1 = d_theoryBitvector->newSXExpr(e[1], len); 00414 int kind = e.getOpKind(); 00415 00416 Expr output; 00417 if(kind == BVSLT) 00418 output = d_theoryBitvector->newBVSLTExpr(e0,e1); 00419 else 00420 output = d_theoryBitvector->newBVSLEExpr(e0,e1); 00421 00422 Proof pf; 00423 if(withProof()) 00424 pf = newPf("pad_bvslt_rule", e); 00425 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 00426 return result; 00427 } 00428 00429 /*! input: e0 <=(s) e1. output depends on whether the topbits(MSB) of 00430 * e0 and e1 are constants. If they are constants then optimizations 00431 * are done, otherwise the following rule is implemented. 00432 * 00433 * e0 <=(s) e1 <==> (e0[n-1] AND NOT e1[n-1]) OR 00434 * (e0[n-1] = e1[n-1] AND e0[n-2:0] <= e1[n-2:0]) 00435 */ 00436 Theorem 00437 BitvectorTheoremProducer::signBVLTRule(const Expr& e, 00438 const Theorem& topBit0, 00439 const Theorem& topBit1){ 00440 if(CHECK_PROOFS) { 00441 CHECK_SOUND((BVSLT == e.getOpKind() || BVSLE == e.getOpKind()) && 00442 e.arity()==2, 00443 "BitvectorTheoremProducer::signedBVLTRule: " 00444 "input must e be a BVSLT/BVSLE: e = " + e.toString()); 00445 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() && 00446 BITVECTOR==e[1].getType().getExpr().getOpKind(), 00447 "BitvectorTheoremProducer::signedBVLTRule: " 00448 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString()); 00449 } 00450 const Expr e0 = e[0]; 00451 const Expr e1 = e[1]; 00452 int e0len = d_theoryBitvector->BVSize(e0); 00453 int e1len = d_theoryBitvector->BVSize(e1); 00454 00455 if(CHECK_PROOFS) { 00456 const Expr e0ext = 00457 d_theoryBitvector->newBVExtractExpr(e0,e0len-1,e0len-1); 00458 const Expr e1ext = 00459 d_theoryBitvector->newBVExtractExpr(e1,e1len-1,e1len-1); 00460 CHECK_SOUND(e0ext == topBit0.getLHS(), 00461 "BitvectorTheoremProducer::signedBVLTRule: " 00462 "topBit0.getLHS() is the un-rewritten form of MSB of e0\n" 00463 "topBit0 is screwed up: topBit0 = " + 00464 topBit0.getExpr().toString()); 00465 CHECK_SOUND(e1ext == topBit1.getLHS(), 00466 "BitvectorTheoremProducer::signedBVLTRule: " 00467 "topBit1.getLHS() is the un-rewritten form of MSB of e1\n" 00468 "topBit1 is screwed up: topBit1 = " + 00469 topBit1.getExpr().toString()); 00470 CHECK_SOUND(e0len == e1len, 00471 "BitvectorTheoremProducer::signedBVLTRule: " 00472 "both e[0] and e[1] must have the same length\n. e =" + 00473 e.toString()); 00474 } 00475 const Expr MSB0 = topBit0.getRHS(); 00476 const Expr MSB1 = topBit1.getRHS(); 00477 00478 int eKind = e.getOpKind(); 00479 Expr output; 00480 00481 //if both MSBs are constants, then we can optimize the output. we 00482 //know precisely the value of the signed comparison in cases where 00483 //topbit of e0 and e1 are constants. e.g. |-1\@t0 < 0\@t1 is clearly 00484 //|-TRUE. 00485 00486 //-1 indicates that both topBits are not known to be BVCONSTS 00487 Rational b0 = -1; 00488 Rational b1 = -1; 00489 if(MSB0.getKind() == BVCONST) b0 = d_theoryBitvector->computeBVConst(MSB0); 00490 if(MSB1.getKind() == BVCONST) b1 = d_theoryBitvector->computeBVConst(MSB1); 00491 00492 //useful expressions to be used below 00493 const Expr tExpr = d_theoryBitvector->trueExpr(); 00494 const Expr fExpr = d_theoryBitvector->falseExpr(); 00495 const Expr MSB0isZero = MSB0.eqExpr(bvZero()); 00496 const Expr MSB0isOne = MSB0.eqExpr(bvOne()); 00497 const Expr MSB1isZero = MSB1.eqExpr(bvZero()); 00498 const Expr MSB1isOne = MSB1.eqExpr(bvOne()); 00499 00500 //handle single bit e0 <=(s) e1 in a special way. this is clumsy 00501 //(i.e. extra and redundant code) but much more efficient and easy 00502 //to read 00503 if(e0len == 1) { 00504 if(b0==0 && b1==0) 00505 output = eKind==BVSLT ? fExpr : tExpr; 00506 else if(b0==0 && b1==1) 00507 output = fExpr; 00508 else if(b0==1 && b1==0) 00509 output = tExpr; 00510 else if(b0==1 && b1==1) 00511 output = eKind==BVSLT ? fExpr : tExpr; 00512 else if(b0==0 && b1==-1) 00513 output = eKind==BVSLT ? fExpr : MSB1isZero; 00514 else if(b0==1 && b1==-1) 00515 output = eKind==BVSLT ? MSB1isZero : tExpr; 00516 else if(b0==-1 && b1==0) 00517 output = eKind==BVSLT ? MSB0isOne : tExpr; 00518 else if(b0==-1 && b1==1) 00519 output = eKind==BVSLT ? fExpr : MSB0isOne; 00520 else 00521 //both b0 and b1 are -1 00522 output = 00523 eKind==BVSLT ? 00524 MSB0isOne.andExpr(MSB1isZero) : 00525 MSB0isOne.orExpr(MSB1isZero); 00526 } else { 00527 //useful expressions to be used below 00528 Expr newE0 = d_theoryBitvector->newBVExtractExpr(e0,e0len-2,0); 00529 Expr newE1 = d_theoryBitvector->newBVExtractExpr(e1,e1len-2,0); 00530 Expr newBVLT = 00531 eKind==BVSLT ? 00532 d_theoryBitvector->newBVLTExpr(newE0,newE1): 00533 d_theoryBitvector->newBVLEExpr(newE0,newE1); 00534 // Expr newBVLTreverse = 00535 // eKind==BVSLT ? 00536 // d_theoryBitvector->newBVLTExpr(newE1,newE0): 00537 // d_theoryBitvector->newBVLEExpr(newE1,newE0); 00538 00539 00540 //both MSBs are simultaneously constants 00541 if(-1 != b0 && -1 !=b1) { 00542 //e0 is negative and e1 is positive 00543 if(b0 == 1 && b1 == 0) 00544 output = tExpr; 00545 //e0 is positive and e1 is negative 00546 else if(b0 == 0 && b1 == 1) 00547 output = fExpr; 00548 //e0 = e1, so result is determined by the rest of the bits 00549 else { 00550 output = newBVLT; 00551 } 00552 } 00553 else if(-1 != b0 && -1 == b1) { 00554 //only b0 is a constant. Both topBits are not simultaneously constants. 00555 00556 //if (b0==0) 00557 // e0 <=(s) e1 <==> NOT e1[n-1] AND e0[n-2:0] <= e1[n-2:0]) 00558 //else 00559 // e0 <=(s) e1 <==> NOT e1[n-1] OR (e1[n-1] AND e0[n-2:0] <= e1[n-2:0])) 00560 00561 output = 00562 (b0==0) ? 00563 //means that b1 has to be 0 and e0[n-2:0] <= e1[n-2:0] 00564 MSB1isZero.andExpr(newBVLT) : 00565 //means that either b1 is 0 or (b1 is 1 and e0[n-2:0] <= e1[n-2:0]) 00566 MSB1isZero.orExpr(MSB1isOne.andExpr(newBVLT)); 00567 } 00568 else if(-1 == b0 && -1 != b1) { 00569 //only b1 is a constant. Both topBits are not simultaneously constants. 00570 00571 //if (b1==0) 00572 // e0 <=(s) e1 <==> e0[n-1] OR (NOT e0[n-1] AND e0[n-2:0] <= e1[n-2:0])) 00573 //else 00574 // e0 <=(s) e1 <==> e0[n-1] AND e0[n-2:0] <= e1[n-2:0])) 00575 00576 output = 00577 (b1==0) ? 00578 //means that either b0 must be 1 or (b0 = 0 and e0[n-2:0] <= e1[n-2:0]) 00579 MSB0isOne.orExpr(MSB0isZero.andExpr(newBVLT)) : 00580 //means that b0 must be 1 and e0[n-2:0] <= e1[n-2:0] 00581 MSB0isOne.andExpr(newBVLT); 00582 } else { 00583 //both top bits are not constants. 00584 00585 //(e0[n-1] AND NOT e1[n-1]) 00586 Expr k0 = MSB0isOne.andExpr(MSB1isZero); 00587 00588 //(e0[n-1] = e1[n-1]) 00589 Expr k1 = MSB0.eqExpr(MSB1); 00590 00591 //e0 <=(s) e1 <==> (e0[n-1] AND NOT e1[n-1]) OR 00592 // (e0[n-1] = e1[n-1] AND e0[n-2:0] <= e1[n-2:0]) 00593 output = k0.orExpr(k1.andExpr(newBVLT)); 00594 } 00595 } 00596 00597 Proof pf; 00598 if(withProof()) 00599 pf = newPf("sign_bvlt_rule", e); 00600 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 00601 } 00602 00603 00604 /*! NOT(e[0][0] = e[0][1]) <==> e[0][0] = ~e[0][1] 00605 */ 00606 Theorem BitvectorTheoremProducer::notBVEQ1Rule(const Expr& e) 00607 { 00608 if(CHECK_PROOFS) { 00609 CHECK_SOUND(e.getKind() == NOT, 00610 "BitvectorTheoremProducer::notBVEQ1Rule: " 00611 "input kind must be a NOT:\n e = " + e.toString()); 00612 CHECK_SOUND(e[0].getOpKind() == EQ, 00613 "BitvectorTheoremProducer::notBVEQ1Rule: " 00614 "e[0] must be EQ: \n e = " + e.toString()); 00615 CHECK_SOUND(d_theoryBitvector->BVSize(e[0][0]) == 1, 00616 "BitvectorTheoremProducer::notBVEQ1Rule: " 00617 "BVSize(e[0][0]) must be 1: \n e = " + e.toString()); 00618 } 00619 Expr output = e[0][0].eqExpr(d_theoryBitvector->newBVNegExpr(e[0][1])); 00620 00621 Proof pf; 00622 if(withProof()) 00623 pf = newPf("not_eq1_rule", e); 00624 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 00625 } 00626 00627 00628 /*! NOT(e[0][0] < e[0][1]) <==> (e[0][1] <= e[0][0]), 00629 * NOT(e[0][0] <= e[0][1]) <==> (e[0][1] < e[0][0]) 00630 */ 00631 Theorem BitvectorTheoremProducer::notBVLTRule(const Expr& e) { 00632 if(CHECK_PROOFS) { 00633 CHECK_SOUND(e.getKind() == NOT, 00634 "BitvectorTheoremProducer::notBVLTRule: " 00635 "input kind must be a NOT:\n e = " + e.toString()); 00636 CHECK_SOUND(e[0].getOpKind() == BVLT || 00637 e[0].getOpKind() == BVLE, 00638 "BitvectorTheoremProducer::notBVLTRule: " 00639 "e[0] must be BVLT or BVLE: \n e = " + e.toString()); 00640 } 00641 Expr output; 00642 00643 const Expr& e00 = e[0][0]; 00644 const Expr& e01 = e[0][1]; 00645 if(BVLT == e[0].getOpKind()) 00646 output = d_theoryBitvector->newBVLEExpr(e01,e00); 00647 else 00648 output = d_theoryBitvector->newBVLTExpr(e01,e00); 00649 00650 Proof pf; 00651 if(withProof()) 00652 pf = newPf("not_bvlt_rule", e); 00653 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 00654 } 00655 00656 00657 //! if(lhs==rhs) then we have (lhs < rhs <==> false),(lhs <= rhs <==> true) 00658 Theorem BitvectorTheoremProducer::lhsEqRhsIneqn(const Expr& e, int kind) { 00659 if(CHECK_PROOFS) { 00660 CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(), 00661 "BitvectorTheoremProducer::lhsEqRhsIneqn: " 00662 "input kind must be BVLT or BVLE: e = " + e.toString()); 00663 CHECK_SOUND(kind == e.getOpKind(), 00664 "BitvectorTheoremProducer::lhsEqRhsIneqn: " 00665 "input kind must match e.getOpKind(): " 00666 "\n e = " + e.toString()); 00667 CHECK_SOUND((e.arity()==2) && (e[0]==e[1]), 00668 "BitvectorTheoremProducer::lhsEqRhsIneqn: " 00669 "input arity must be 2, and e[0] must be equal to e[1]: " 00670 "\ne = " + e.toString()); 00671 } 00672 Expr output; 00673 if(kind == BVLT) 00674 output = d_theoryBitvector->falseExpr(); 00675 else 00676 output = d_theoryBitvector->trueExpr(); 00677 00678 Proof pf; 00679 if(withProof()) 00680 pf = newPf("lhs_eq_rhs_ineqn", e); 00681 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 00682 } 00683 00684 00685 //! |= 0 <= foo <-> TRUE 00686 Theorem BitvectorTheoremProducer::zeroLeq(const Expr& e) { 00687 if(CHECK_PROOFS) { 00688 CHECK_SOUND(BVLE == e.getOpKind(), 00689 "BitvectorTheoremProducer::zeroLeq: " 00690 "input kind must be BVLE: e = " + e.toString()); 00691 CHECK_SOUND(e.arity()==2 && e[0].getOpKind() == BVCONST && 00692 d_theoryBitvector->computeBVConst(e[0]) == 0, 00693 "BitvectorTheoremProducer::zeroLeq: " 00694 "unexpected input: e = " + e.toString()); 00695 } 00696 Proof pf; 00697 if(withProof()) 00698 pf = newPf("zeroLeq", e); 00699 return newRWTheorem(e, d_theoryBitvector->trueExpr(), Assumptions::emptyAssump(), pf); 00700 } 00701 00702 00703 //! if indeed e[0] < e[1] then (e<==>true) else (e<==>false) 00704 Theorem BitvectorTheoremProducer::bvConstIneqn(const Expr& e, int kind) { 00705 if(CHECK_PROOFS) { 00706 CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(), 00707 "BitvectorTheoremProducer::bvConstIneqn: " 00708 "input kind must be BVLT or BVLE: e = " + e.toString()); 00709 CHECK_SOUND(kind == e.getOpKind(), 00710 "BitvectorTheoremProducer::bvConstIneqn: " 00711 "input kind must match e.getOpKind(): " 00712 "\n e = " + e.toString()); 00713 CHECK_SOUND((e.arity()==2), 00714 "BitvectorTheoremProducer::bvConstIneqn: " 00715 "input arity must be 2: \ne = " + e.toString()); 00716 CHECK_SOUND(BVCONST == e[0].getKind() && BVCONST == e[1].getKind(), 00717 "BitvectorTheoremProducer::bvConstIneqn: " 00718 "e[0] and e[1] must both be constants:\n e = " + 00719 e.toString()); 00720 } 00721 00722 int e0len = d_theoryBitvector->BVSize(e[0]); 00723 int e1len = d_theoryBitvector->BVSize(e[1]); 00724 if(CHECK_PROOFS) 00725 CHECK_SOUND(e0len == e1len, 00726 "BitvectorTheoremProducer::bvConstIneqn: " 00727 "e[0] and e[1] must have the same bvLength:\ne = " + 00728 e.toString()); 00729 00730 Rational lhsVal = d_theoryBitvector->computeBVConst(e[0]); 00731 Rational rhsVal = d_theoryBitvector->computeBVConst(e[1]); 00732 Expr output; 00733 00734 if(BVLT == kind) { 00735 if(lhsVal < rhsVal) 00736 output = d_theoryBitvector->trueExpr(); 00737 else 00738 output = d_theoryBitvector->falseExpr(); 00739 } else { 00740 if(lhsVal <= rhsVal) 00741 output = d_theoryBitvector->trueExpr(); 00742 else 00743 output = d_theoryBitvector->falseExpr(); 00744 } 00745 00746 Proof pf; 00747 if(withProof()) 00748 pf = newPf("bv_const_ineqn", e); 00749 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 00750 } 00751 00752 00753 // Input: e: a op b, where op is < or <= 00754 // lhs_i: BOOLEXTRACT(a,i) <=> b1 00755 // rhs_i: BOOLEXTRACT(b,i) <=> b2 00756 // kind: op 00757 // i = BVSize(a)-1 = BVSize(b)-1 00758 // Output: for i > 0: 00759 // (lhs_i < rhs_i) OR (lhs_i = rhs_i AND a[i-1:0] op b[i-1:0]) 00760 // for i = 0: 00761 // (lhs_i op rhs_i) 00762 Theorem BitvectorTheoremProducer::generalIneqn(const Expr& e, 00763 const Theorem& lhs_i, 00764 const Theorem& rhs_i, 00765 int kind) { 00766 if(CHECK_PROOFS) { 00767 CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(), 00768 "BitvectorTheoremProducer::generalIneqn: " 00769 "input kind must be BVLT or BVLE: e = " + e.toString()); 00770 CHECK_SOUND(kind == e.getOpKind(), 00771 "BitvectorTheoremProducer::generalIneqn: " 00772 "input kind must match e.getOpKind(): " 00773 "\n e = " + e.toString()); 00774 CHECK_SOUND((e.arity()==2), 00775 "BitvectorTheoremProducer::generalIneqn: " 00776 "input arity must be 2: \ne = " + e.toString()); 00777 CHECK_SOUND(lhs_i.isRewrite() && rhs_i.isRewrite(), 00778 "BitvectorTheoremProducer::generalIneqn: " 00779 "lhs_i and rhs_i must be rewrite theorems: " 00780 "\nlhs_i = " + lhs_i.toString() + 00781 "\nrhs_i = " + rhs_i.toString()); 00782 } 00783 00784 int e0len = d_theoryBitvector->BVSize(e[0]); 00785 int e1len = d_theoryBitvector->BVSize(e[1]); 00786 const Expr& e0_iBit = lhs_i.getLHS(); 00787 const Expr& e1_iBit = rhs_i.getLHS(); 00788 if(CHECK_PROOFS) { 00789 CHECK_SOUND(BOOLEXTRACT == e0_iBit.getOpKind() && 00790 BOOLEXTRACT == e1_iBit.getOpKind(), 00791 "BitvectorTheoremProducer::generalIneqn: " 00792 "lhs_i.getRHS() and rhs_i.getRHS() must be BOOLEXTRACTs:" 00793 "\nlhs_i = " + lhs_i.toString() + 00794 "\nrhs_i = " + rhs_i.toString()); 00795 CHECK_SOUND(e[0] == e0_iBit[0], 00796 "BitvectorTheoremProducer::generalIneqn: " 00797 "e[0] must be equal to LHS of lhs_i: \nlhs_i = " + 00798 lhs_i.toString() + "\n e[0] = " + e[0].toString()); 00799 CHECK_SOUND(e[1] == e1_iBit[0], 00800 "BitvectorTheoremProducer::generalIneqn: " 00801 "e[1] must be equal to LHS of rhs_i: \nrhs_i = " + 00802 rhs_i.toString() + "\n e[1] = " + e[1].toString()); 00803 CHECK_SOUND(e0len == e1len, 00804 "BitvectorTheoremProducer::generalIneqn: " 00805 "e[0] and e[1] must have the same bvLength:\ne = " + 00806 e.toString()); 00807 int e0_iBitIndex = 00808 d_theoryBitvector->getBoolExtractIndex(e0_iBit); 00809 int e1_iBitIndex = 00810 d_theoryBitvector->getBoolExtractIndex(e1_iBit); 00811 CHECK_SOUND(e0_iBitIndex == e1_iBitIndex && 00812 e0_iBitIndex == e0len-1, 00813 "BitvectorTheoremProducer::generalIneqn: " 00814 "e0_iBit & e1_iBit must have same extract index: " 00815 "\ne0_iBit = " + e0_iBit.toString() + 00816 "\ne1_iBit = " + e1_iBit.toString()); 00817 } 00818 00819 const Expr& b1 = lhs_i.getRHS(); 00820 const Expr& b2 = rhs_i.getRHS(); 00821 const Expr& trueExpression = d_theoryBitvector->trueExpr(); 00822 const Expr& falseExpression = d_theoryBitvector->falseExpr(); 00823 00824 if(CHECK_PROOFS) { 00825 CHECK_SOUND(b1.getType().isBool(), 00826 "BitvectorTheoremProducer::generalIneqn: " 00827 "b1 must be a boolean type: " 00828 "\n b1 = " + b1.toString()); 00829 CHECK_SOUND(b2.getType().isBool(), 00830 "BitvectorTheoremProducer::generalIneqn: " 00831 "b2 must be boolean type: " 00832 "\n b2 = " + b2.toString()); 00833 } 00834 00835 Expr output; 00836 // Check for the shortcuts 00837 if (b1.isFalse() && b2.isTrue()) // b1 < b2 00838 output = trueExpression; 00839 else if (b1.isTrue() && b2.isFalse()) // b1 > b2 00840 output = falseExpression; 00841 else if (e0len==1) { 00842 // If this is the last bit, and one of them is a constant 00843 if (kind==BVLE && (b1.isFalse() || b2.isTrue())) // F <= x or x <= T 00844 output = trueExpression; 00845 else if (kind==BVLT && (b2.isFalse() || b1.isTrue())) // x < F or T < x 00846 output = falseExpression; 00847 } 00848 00849 // No shortcuts found 00850 if (output.isNull()) { 00851 00852 // Process the top bits 00853 if (kind == BVLT || e0len > 1) { 00854 output = (!b1) && b2; 00855 } 00856 else { 00857 output = (!b1) || b2; 00858 } 00859 00860 if(e0len > 1) { 00861 //construct e0[n-2:0] 00862 Expr e0_extract = 00863 d_theoryBitvector->newBVExtractExpr(e[0],e0len-2,0); 00864 //construct e1[n-2:0] 00865 Expr e1_extract = 00866 d_theoryBitvector->newBVExtractExpr(e[1],e1len-2,0); 00867 00868 Expr a; 00869 if(kind==BVLT) 00870 //construct e0[n-2:0] < e1[n-2:0] 00871 a = d_theoryBitvector->newBVLTExpr(e0_extract,e1_extract); 00872 else 00873 //construct e0[n-2:0] <= e1[n-2:0] 00874 a = d_theoryBitvector->newBVLEExpr(e0_extract,e1_extract); 00875 00876 //construct (b1=0 and/or b2=1) or (b1=b2 and a) 00877 output = output || (b1.iffExpr(b2) && a); 00878 } 00879 } 00880 00881 Proof pf; 00882 if(withProof()) 00883 pf = newPf("general_ineqn", e); 00884 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 00885 } 00886 00887 /////////////////////////////////////////////////////////////////////// 00888 // BitExtracting rules for terms 00889 /////////////////////////////////////////////////////////////////////// 00890 00891 // Input: |- BOOLEXTRACT(a,0) <=> bc_0, ... BOOLEXTRACT(a,n-1) <=> bc_(n-1) 00892 // where each bc_0 is TRUE or FALSE 00893 // Output: |- a = c 00894 // where c is an n-bit constant made from the values bc_0..bc_(n-1) 00895 Theorem BitvectorTheoremProducer::bitExtractAllToConstEq(vector<Theorem>& thms) 00896 { 00897 if (CHECK_PROOFS) { 00898 CHECK_SOUND(thms.size() > 0, "Expected size > 0"); 00899 unsigned i; 00900 for(i = 0; i < thms.size(); ++i) { 00901 Expr e = thms[i].getExpr(); 00902 CHECK_SOUND(e.getKind() == IFF && e.arity() == 2 && e[1].isBoolConst(), 00903 "Unexpected structure"); 00904 CHECK_SOUND(e[0].getOpKind() == BOOLEXTRACT && 00905 e[0].arity() == 1 && 00906 e[0][0] == thms[0].getExpr()[0][0] && 00907 unsigned(d_theoryBitvector->getBoolExtractIndex(e[0])) == i, 00908 "Unexpected structure"); 00909 } 00910 } 00911 Expr lhs = thms[0].getExpr()[0][0]; 00912 vector<bool> bits; 00913 for (unsigned i = 0; i < thms.size(); ++i) { 00914 bits.push_back(thms[i].getExpr()[1].isTrue() ? true : false); 00915 } 00916 Expr rhs = d_theoryBitvector->newBVConstExpr(bits); 00917 00918 Assumptions a(thms); 00919 Proof pf; 00920 if (withProof()) 00921 pf = newPf("bit_extract_all_to_const_eq"); 00922 return newRWTheorem(lhs, rhs, a, pf); 00923 } 00924 00925 00926 //! t[i] ==> t[i:i] = 0bin1 or NOT t[i] ==> t[i:i] = 0bin0 00927 Theorem BitvectorTheoremProducer::bitExtractToExtract(const Theorem& thm) { 00928 const Expr& e = thm.getExpr(); 00929 if(CHECK_PROOFS) { 00930 CHECK_SOUND((e.isNot() && e[0].getOpKind() == BOOLEXTRACT) 00931 || (e.getOpKind() == BOOLEXTRACT), 00932 "BitvectorTheoremProducer::bitExtractToExtract:\n e = " 00933 +e.toString()); 00934 } 00935 bool negative = e.isNot(); 00936 const Expr& boolExtract = negative? e[0] : e; 00937 int i = d_theoryBitvector->getBoolExtractIndex(boolExtract); 00938 Expr lhs = d_theoryBitvector->newBVExtractExpr(boolExtract[0], i, i); 00939 00940 Proof pf; 00941 if(withProof()) 00942 pf = newPf("bit_extract_to_extract", e, thm.getProof()); 00943 return newRWTheorem(lhs, negative? bvZero() : bvOne(), thm.getAssumptionsRef(), pf); 00944 } 00945 00946 00947 //! t[i] <=> t[i:i][0] (to use rewriter for simplifying t[i:i]) 00948 Theorem BitvectorTheoremProducer::bitExtractRewrite(const Expr& x) { 00949 if(CHECK_PROOFS) { 00950 CHECK_SOUND(x.getOpKind() == BOOLEXTRACT, 00951 "BitvectorTheoremProducer::bitExtractRewrite: x = " 00952 +x.toString()); 00953 } 00954 00955 int i = d_theoryBitvector->getBoolExtractIndex(x); 00956 const Expr& t = x[0]; 00957 int bvLength = d_theoryBitvector->BVSize(t); 00958 00959 if(CHECK_PROOFS) { 00960 CHECK_SOUND(0<=i && i<bvLength, 00961 "BitvectorTheoremProducer::bitExtractRewrite:" 00962 "\n bvLength = " 00963 + int2string(bvLength) 00964 +"\n i = "+ int2string(i) 00965 +"\n x = "+ x.toString()); 00966 } 00967 Proof pf; 00968 if(withProof()) 00969 pf = newPf("bit_extract_rewrite", x); 00970 Expr res = d_theoryBitvector->newBVExtractExpr(t, i, i); 00971 res = d_theoryBitvector->newBoolExtractExpr(res, 0); 00972 return newRWTheorem(x, res, Assumptions::emptyAssump(), pf); 00973 } 00974 00975 00976 // |- BOOLEXTRACT(x,i) <=> *Boolean value of x[i]* 00977 Theorem BitvectorTheoremProducer::bitExtractConstant(const Expr & x, int i) 00978 { 00979 TRACE("bitvector", "bitExtractConstant(", x, ", "+ int2string(i) +" ) {"); 00980 if(CHECK_PROOFS) { 00981 //check if the expr is indeed a bitvector constant. 00982 CHECK_SOUND(BVCONST == x.getKind(), 00983 "BitvectorTheoremProducer::bitExtractConstant:" 00984 "the bitvector must be a constant."); 00985 //check if 0<= i < bvLength of bitvector constant 00986 CHECK_SOUND(0 <= i && (unsigned)i < d_theoryBitvector->getBVConstSize(x), 00987 "BitvectorTheoremProducer::bitExtractConstant:" 00988 "illegal extraction attempted on the bitvector x = " 00989 + x.toString() 00990 + "\nat the position i = " 00991 + int2string(i)); 00992 } 00993 // bool-extract of the bitvector constant 00994 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 00995 00996 //extract the actual expr_value string, bitextract it at i and check 00997 //if the value is 'false'. if so then return c[i] <==> false else 00998 //return c[i] <==> true. 00999 Expr output; 01000 if(!d_theoryBitvector->getBVConstValue(x, i)) 01001 output = d_theoryBitvector->falseExpr(); 01002 else 01003 output = d_theoryBitvector->trueExpr(); 01004 01005 Proof pf; 01006 if(withProof()) pf = newPf("bit_extract_constant", x, rat(i)); 01007 Theorem result(newRWTheorem(bitExtract,output,Assumptions::emptyAssump(),pf)); 01008 TRACE("bitvector", "bitExtractConstant => ", result, " }"); 01009 return result; 01010 } 01011 01012 01013 // Input: x: a_0 \@ ... \@ a_n, 01014 // i: bitposition 01015 // Output |- BOOLEXTRACT(a_0 \@ ... \@ a_n, i) <=> BOOLEXTRACT(a_j, k) 01016 // where j and k are determined by structure of CONCAT 01017 Theorem BitvectorTheoremProducer::bitExtractConcatenation(const Expr & x, 01018 int i) 01019 { 01020 TRACE("bitvector", "bitExtractConcatenation(", 01021 x.toString(), ", "+ int2string(i) + " ) {"); 01022 Type type = d_theoryBitvector->getBaseType(x); 01023 if(CHECK_PROOFS) { 01024 //check if the expr is indeed a bitvector term and a concat. 01025 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01026 "BitvectorTheoremProducer::bitExtractConcatenation: " 01027 "term must be bitvector:\n x = "+x.toString()); 01028 CHECK_SOUND(CONCAT == x.getOpKind() && x.arity() >= 2, 01029 "BitvectorTheoremProducer::bitExtractConcatenation: " 01030 "the bitvector must be a concat:\n x = " + x.toString()); 01031 } 01032 01033 //check if 0<= i < bvLength of bitvector constant 01034 int bvLength = d_theoryBitvector->BVSize(x); 01035 if(CHECK_PROOFS) { 01036 CHECK_SOUND(0 <= i && i < bvLength, 01037 "BitvectorTheoremProducer::bitExtractNot:" 01038 "illegal boolean extraction was attempted at position i = " 01039 + int2string(i) 01040 + "\non bitvector x = " + x.toString() 01041 + "\nwhose bvLength is = " + 01042 int2string(bvLength)); 01043 } 01044 01045 // bool-extract of the bitvector constant 01046 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01047 01048 int numOfKids = x.arity(); 01049 int lenOfKidsSeen = 0; 01050 Expr bitExtractKid; 01051 for(int count = numOfKids-1; count >= 0; --count) { 01052 int bvLengthOfKid = d_theoryBitvector->BVSize(x[count]); 01053 if(lenOfKidsSeen <= i && i < bvLengthOfKid + lenOfKidsSeen) { 01054 bitExtractKid = 01055 d_theoryBitvector->newBoolExtractExpr(x[count], i - lenOfKidsSeen); 01056 break; 01057 } 01058 lenOfKidsSeen += bvLengthOfKid; 01059 } 01060 DebugAssert(!bitExtractKid.isNull(), 01061 "BitvectorTheoremProducer::bitExtractConcatenation: " 01062 "something's broken..."); 01063 01064 Proof pf; 01065 if(withProof()) 01066 pf = newPf("bit_extract_concatenation", x, rat(i)); 01067 Theorem result(newRWTheorem(bitExtract, bitExtractKid, Assumptions::emptyAssump(), pf)); 01068 TRACE("bitvector", "bitExtractConcatenation => ", result, " }"); 01069 return result; 01070 } 01071 01072 01073 // |- BOOLEXTRACT(BVMULT(c,t),i) <=> BOOLEXTRACT(t',i) where t' is not a BVMULT 01074 Theorem BitvectorTheoremProducer::bitExtractConstBVMult(const Expr& t, int i) 01075 { 01076 TRACE("bitvector", "input to bitExtractConstBVMult(", t.toString(), ")"); 01077 TRACE("bitvector", "input to bitExtractConstBVMult(", int2string(i), ")"); 01078 01079 Type type = t.getType(); 01080 int bvLength = d_theoryBitvector->BVSize(t); 01081 if(CHECK_PROOFS) { 01082 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01083 "BitvectorTheoremProducer::bitExtractConstBVMult:" 01084 "the term must be a bitvector: " + t.toString()); 01085 CHECK_SOUND(BVMULT == t.getOpKind() && 2 == t.arity(), 01086 "BitvectorTheoremProducer::bitExtractConstBVMult:" 01087 "the term must be a MULT of arity 2: " + t.toString()); 01088 CHECK_SOUND(d_theoryBitvector->BVSize(t[0]) == bvLength && 01089 d_theoryBitvector->BVSize(t[1]) == bvLength, 01090 "BitvectorTheoremProducer::bitExtractConstBVMult:" 01091 "Expected inputs of same length"); 01092 CHECK_SOUND(0 <= i && i < bvLength, 01093 "BitvectorTheoremProducer::bitExtractNot:" 01094 "illegal boolean extraction was attempted at position i = " 01095 + int2string(i) 01096 + "\non bitvector x = " + t.toString() 01097 + "\nwhose bvLength is = " + 01098 int2string(bvLength)); 01099 CHECK_SOUND(BVCONST == t[0].getKind(), 01100 "BitvectorTheoremProducer::bitExtractConstBVMult:" 01101 "illegal BVMULT expression" + t.toString()); 01102 } 01103 01104 std::vector<Expr> k; 01105 for(int j=0; j < bvLength; ++j) 01106 if (d_theoryBitvector->getBVConstValue(t[0], j)) { 01107 Expr leftshiftTerm = 01108 d_theoryBitvector->newFixedConstWidthLeftShiftExpr(t[1], j); 01109 k.push_back(leftshiftTerm); 01110 } 01111 01112 Expr mult; 01113 //size of k will always be >= 0 01114 switch(k.size()) { 01115 case 0: 01116 //the vector k will remain empty if all bits in coeff are 0's 01117 mult = d_theoryBitvector->newBVZeroString(bvLength); 01118 break; 01119 case 1: 01120 mult = k[0]; 01121 break; 01122 default: 01123 mult = d_theoryBitvector->newBVPlusExpr(bvLength, k); 01124 break; 01125 } 01126 Expr output = d_theoryBitvector->newBoolExtractExpr(mult, i); 01127 01128 // bool-extract of the bitvector term 01129 const Expr bitExtract = 01130 d_theoryBitvector->newBoolExtractExpr(t, i); 01131 01132 Proof pf; 01133 if(withProof()) pf = newPf("bit_extract_const_bvmult", t, rat(i)); 01134 const Theorem result = newRWTheorem(bitExtract,output,Assumptions::emptyAssump(),pf); 01135 TRACE("bitvector", 01136 "output of bitExtract_const_bvmult(", result, ")"); 01137 return result; 01138 } 01139 01140 // |- BOOLEXTRACT(t,i) <=> BOOLEXTRACT(t',i) where t' is not BVMULT 01141 Theorem BitvectorTheoremProducer::bitExtractBVMult(const Expr& t, int i) 01142 { 01143 TRACE("bitvector", "input to bitExtractBVMult(", t.toString(), ")"); 01144 TRACE("bitvector", "input to bitExtractBVMult(", int2string(i), ")"); 01145 01146 Type type = t.getType(); 01147 int bvLength= d_theoryBitvector->BVSize(t); 01148 if(CHECK_PROOFS) { 01149 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01150 "BitvectorTheoremProducer::bitExtractBVMult:" 01151 "the term must be a bitvector" + t.toString()); 01152 CHECK_SOUND(BVMULT == t.getOpKind() && 2 == t.arity(), 01153 "BitvectorTheoremProducer::bitExtractBVMult:" 01154 "the term must be a bitvector" + t.toString()); 01155 CHECK_SOUND(d_theoryBitvector->BVSize(t[0]) == bvLength && 01156 d_theoryBitvector->BVSize(t[1]) == bvLength, 01157 "BitvectorTheoremProducer::bitExtractConstBVMult:" 01158 "Expected inputs of same length"); 01159 CHECK_SOUND(0 <= i && i < bvLength, 01160 "BitvectorTheoremProducer::bitExtractNot:" 01161 "illegal boolean extraction was attempted at position i = " 01162 + int2string(i) 01163 + "\non bitvector t = " + t.toString() 01164 + "\nwhose Length is = " + 01165 int2string(bvLength)); 01166 CHECK_SOUND(BVCONST != t[0].getOpKind(), 01167 "BitvectorTheoremProducer::bitExtractBVMult:" 01168 "illegal BVMULT expression" + t.toString()); 01169 } 01170 Expr trueExpression = d_theoryBitvector->trueExpr(); 01171 std::vector<Expr> k; 01172 for(int j=bvLength-1; j >= 0; j--) { 01173 Expr ext = d_theoryBitvector->newBVExtractExpr(t[0],j,j); 01174 Expr cond = ext.eqExpr(d_theoryBitvector->newBVOneString(1)); 01175 Expr leftshiftTerm = d_theoryBitvector->newFixedConstWidthLeftShiftExpr(t[1], j); 01176 Expr zeroString = d_theoryBitvector->newBVZeroString(bvLength); 01177 Expr iteTerm = cond.iteExpr(leftshiftTerm, zeroString); 01178 k.push_back(iteTerm); 01179 } 01180 01181 if(CHECK_PROOFS) 01182 CHECK_SOUND(k.size() > 0, 01183 "BitvectorTheoremProducer::bitExtractBVMult:" 01184 "size of output vector must be > 0"); 01185 Expr mult; 01186 if (k.size() > 1) 01187 mult = d_theoryBitvector->newBVPlusExpr(bvLength, k); 01188 else 01189 mult = k[0]; 01190 Expr output = d_theoryBitvector->newBoolExtractExpr(mult, i); 01191 01192 // bool-extract of the bitvector term 01193 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(t, i); 01194 01195 Proof pf; 01196 if(withProof()) pf = newPf("bit_extract_bvmult", t, rat(i)); 01197 const Theorem result = newRWTheorem(bitExtract,output,Assumptions::emptyAssump(),pf); 01198 TRACE("bitvector","output of bitExtract_bvmult(", result, ")"); 01199 return result; 01200 } 01201 01202 01203 // Input x: a[hi:low] 01204 // i: bitposition 01205 // Output: |- BOOLEXTRACT(a[hi:low], i) <=> BOOLEXTRACT(a, i+low) 01206 Theorem BitvectorTheoremProducer::bitExtractExtraction(const Expr & x, int i) 01207 { 01208 TRACE("bitvector", "input to bitExtractExtraction(", x.toString(), ")"); 01209 TRACE("bitvector", "input to bitExtractExtraction(", int2string(i), ")"); 01210 01211 Type type = x.getType(); 01212 if(CHECK_PROOFS) { 01213 //check if the expr is indeed a bitvector term and a concat. 01214 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01215 "BitvectorTheoremProducer::bitExtract-Extraction:" 01216 "term must be bitvector."); 01217 CHECK_SOUND(EXTRACT == x.getOpKind() && 1 == x.arity(), 01218 "BitvectorTheoremProducer::bitExtract-Extraction:" 01219 "the bitvector must be an extract." + x.toString()); 01220 //check if 0<= i < bvLength of bitvector constant 01221 int bvLength= d_theoryBitvector->BVSize(type.getExpr()); 01222 CHECK_SOUND(0 <= i && i < bvLength, 01223 "BitvectorTheoremProducer::bitExtractNot:" 01224 "illegal boolean extraction was attempted at position i = " 01225 + int2string(i) 01226 + "\non bitvector t = " + x.toString() 01227 + "\nwhose Length is = " + 01228 int2string(bvLength)); 01229 int extractLeft = d_theoryBitvector->getExtractHi(x); 01230 int extractRight = d_theoryBitvector->getExtractLow(x); 01231 CHECK_SOUND(extractLeft >= extractRight && extractLeft >= 0, 01232 "BitvectorTheoremProducer::bitExtract-Extraction:" 01233 "illegal boolean extraction was attempted." + int2string(i) + 01234 int2string(extractLeft) + int2string(extractRight)); 01235 CHECK_SOUND(0 <= i && i < extractLeft-extractRight+1, 01236 "BitvectorTheoremProducer::bitExtract-Extraction:" 01237 "illegal boolean extraction was attempted." + int2string(i) + 01238 int2string(extractLeft) + int2string(extractRight)); 01239 } 01240 // bool-extract of the bitvector constant 01241 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01242 const Expr bitExtractExtraction = 01243 d_theoryBitvector->newBoolExtractExpr(x[0], i + 01244 d_theoryBitvector->getExtractLow(x)); 01245 01246 Proof pf; 01247 if(withProof()) pf = newPf("bit_extract_extraction", x, rat(i)); 01248 Theorem result(newRWTheorem(bitExtract, bitExtractExtraction, Assumptions::emptyAssump(), pf)); 01249 TRACE("bitvector", 01250 "output of bitExtractExtraction(", result, ")"); 01251 return result; 01252 } 01253 01254 Theorem 01255 BitvectorTheoremProducer:: 01256 bitExtractBVPlus(const std::vector<Theorem>& t1BitExtractThms, 01257 const std::vector<Theorem>& t2BitExtractThms, 01258 const Expr& bvPlusTerm, int bitPos) 01259 { 01260 TRACE("bitvector","input to bitExtractBVPlus(", bvPlusTerm.toString(), ")"); 01261 TRACE("bitvector","input to bitExtractBVPlus(", int2string(bitPos), ")"); 01262 01263 if(CHECK_PROOFS) { 01264 CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind() && 2 == bvPlusTerm.arity(), "BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + bvPlusTerm.toString()); 01265 CHECK_SOUND(d_theoryBitvector->getBVPlusParam(bvPlusTerm) >= 0, "BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + bvPlusTerm.toString()); 01266 CHECK_SOUND(bitPos+1 == (int)t1BitExtractThms.size() && bitPos+1 == (int)t2BitExtractThms.size(), "BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + int2string(bitPos)); 01267 const Expr& t1 = bvPlusTerm[0]; 01268 const Expr& t2 = bvPlusTerm[1]; 01269 std::vector<Theorem>::const_iterator i = t1BitExtractThms.begin(); 01270 std::vector<Theorem>::const_iterator iend = t1BitExtractThms.end(); 01271 std::vector<Theorem>::const_iterator j = t2BitExtractThms.begin(); 01272 for(; i !=iend; ++i, ++j) { 01273 const Expr& t1Expr = i->getLHS(); 01274 const Expr& t2Expr = j->getLHS(); 01275 CHECK_SOUND(t1Expr[0] == t1 && t2Expr[0] == t2, "BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + t1Expr.toString() + " ==\n" + t1.toString() + "\n" + t2.toString() + " == \n" + t2Expr.toString()); 01276 } 01277 } 01278 const Expr lhs = d_theoryBitvector->newBoolExtractExpr(bvPlusTerm, bitPos); 01279 Expr rhs; 01280 const Expr& t1_iBit = (t1BitExtractThms[bitPos]).getRHS(); 01281 const Expr& t2_iBit = (t2BitExtractThms[bitPos]).getRHS(); 01282 if(0 != bitPos) { 01283 const Expr carry_iBit = computeCarry(t1BitExtractThms, t2BitExtractThms, bitPos); 01284 //constructing an XOR of 3 exprs using equivalences. Note that (x 01285 //\xor y \xor z) is the same as (x \iff y \iff z). but remember, x 01286 //\xor y is not the same as x \iff y, but is equal instead to x 01287 //\neg\iff y 01288 rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit); 01289 //cout << "the addition output is : " << rhs.toString() << "\n"; 01290 //TRACE("bitvector", 01291 // "output of bitExtractBVPlus(", carry_iBit.toString(), ")"); 01292 } else 01293 //bitblasting the 0th bit. construct NOT(t1_iBit <=> t2_iBit) 01294 rhs = !(t1_iBit.iffExpr(t2_iBit)); 01295 01296 Proof pf; 01297 if(withProof()) 01298 pf = newPf("bit_extract_BVPlus_rule",bvPlusTerm,rat(bitPos)); 01299 Theorem result = newRWTheorem(lhs, rhs, Assumptions::emptyAssump(), pf); 01300 TRACE("bitvector","output of bitExtractBVPlus(", result, ")"); 01301 return result; 01302 } 01303 01304 Expr 01305 BitvectorTheoremProducer::computeCarry(const std::vector<Theorem>& t1BitExtractThms, 01306 const std::vector<Theorem>& t2BitExtractThms, 01307 int i){ 01308 vector<Expr> carry; 01309 int bitPos = i; 01310 DebugAssert(bitPos >= 0, 01311 "computeCarry: negative bitExtract_Pos is illegal"); 01312 if(0 == bitPos) { 01313 const Expr& t1Thm = t1BitExtractThms[bitPos].getRHS(); 01314 const Expr& t2Thm = t2BitExtractThms[bitPos].getRHS(); 01315 carry.push_back(t1Thm.andExpr(t2Thm)); 01316 } 01317 else { 01318 const Expr& t1Thm = t1BitExtractThms[bitPos-1].getRHS(); 01319 const Expr& t2Thm = t2BitExtractThms[bitPos-1].getRHS(); 01320 const Expr iMinusOneTerm = t1Thm.andExpr(t2Thm); 01321 carry.push_back(iMinusOneTerm); 01322 01323 const Expr iMinusOneCarry = 01324 computeCarry(t1BitExtractThms,t2BitExtractThms,bitPos-1); 01325 const Expr secondTerm = t1Thm.andExpr(iMinusOneCarry); 01326 carry.push_back(secondTerm); 01327 01328 const Expr thirdTerm = t2Thm.andExpr(iMinusOneCarry); 01329 01330 carry.push_back(thirdTerm); 01331 } 01332 return orExpr(carry); 01333 } 01334 01335 Theorem 01336 BitvectorTheoremProducer:: 01337 bitExtractBVPlusPreComputed(const Theorem& t1_i, 01338 const Theorem& t2_i, 01339 const Expr& bvPlusTerm, 01340 int bitPos, 01341 int precomputedFlag) 01342 { 01343 DebugAssert(0 != precomputedFlag, 01344 "precomputedFlag cannot be 0"); 01345 TRACE("bitvector","input to bitExtractBVPlus(", bvPlusTerm.toString(), ")"); 01346 TRACE("bitvector","input to bitExtractBVPlus(", int2string(bitPos), ")"); 01347 01348 if(CHECK_PROOFS) { 01349 CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind() && 2 == bvPlusTerm.arity(), 01350 "BitvectorTheoremProducer::bitExtractBVPlus:" 01351 "illegal bitvector fed to the function." + 01352 bvPlusTerm.toString()); 01353 CHECK_SOUND(d_theoryBitvector->getBVPlusParam(bvPlusTerm) >= 0, 01354 "BitvectorTheoremProducer::bitExtractBVPlus:" 01355 "illegal bitvector fed to the function." + 01356 bvPlusTerm.toString()); 01357 const Expr& t1 = bvPlusTerm[0]; 01358 const Expr& t2 = bvPlusTerm[1]; 01359 CHECK_SOUND(t1_i.getLHS()[0] == t1 && 01360 t2_i.getLHS()[0] == t2, 01361 "BitvectorTheoremProducer::bitExtractBVPlus:" 01362 "illegal theorems fed to the function. Theorem1 = " + 01363 t1_i.toString() + "\nTheorem2 = " + t2_i.toString()); 01364 CHECK_SOUND(t1_i.getLHS().getOpKind() == BOOLEXTRACT && 01365 t2_i.getLHS().getOpKind() == BOOLEXTRACT, 01366 "BitvectorTheoremProducer::bitExtractBVPlus:" 01367 "illegal theorems fed to the function. Theorem1 = " + 01368 t1_i.toString() + "\nTheorem2 = " + t2_i.toString()); 01369 CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(t1_i.getLHS()) == bitPos && 01370 d_theoryBitvector->getBoolExtractIndex(t2_i.getLHS()) == bitPos, 01371 "BitvectorTheoremProducer::bitExtractBVPlus:" 01372 "illegal theorems fed to the function. Theorem1 = " + 01373 t1_i.toString() + "\nTheorem2 = " + t2_i.toString()); 01374 } 01375 const Expr lhs = 01376 d_theoryBitvector->newBoolExtractExpr(bvPlusTerm, bitPos); 01377 Expr rhs; 01378 const Expr& t1_iBit = t1_i.getRHS(); 01379 const Expr& t2_iBit = t2_i.getRHS(); 01380 01381 const Expr carry_iBit = computeCarryPreComputed(t1_i, t2_i, bitPos, precomputedFlag); 01382 01383 if(0 != bitPos) { 01384 //constructing an XOR of 3 exprs using equivalences. Note that (x 01385 //\xor y \xor z) is the same as (x \iff y \iff z). but remember, x 01386 //\xor y is not the same as x \iff y, but is equal instead to x 01387 //\neg\iff y 01388 rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit); 01389 //cout << "the addition output is : " << rhs.toString() << "\n"; 01390 } else 01391 //bitblasting the 0th bit. construct NOT(t1_iBit <=> t2_iBit) 01392 rhs = !(t1_iBit.iffExpr(t2_iBit)); 01393 01394 Proof pf; 01395 if(withProof()) 01396 pf = newPf("bit_extract_BVPlus_precomputed_rule",bvPlusTerm,rat(bitPos)); 01397 Theorem result = newRWTheorem(lhs, rhs, Assumptions::emptyAssump(), pf); 01398 TRACE("bitvector","output of bitExtractBVPlus(", result, ")"); 01399 return result; 01400 } 01401 01402 //! compute carryout of the current bits and cache them, and return 01403 //carryin of the current bits 01404 Expr 01405 BitvectorTheoremProducer:: 01406 computeCarryPreComputed(const Theorem& t1_i, 01407 const Theorem& t2_i, 01408 int bitPos, int preComputed){ 01409 DebugAssert(1 == preComputed || 01410 2 == preComputed, 01411 "cannot happen"); 01412 Expr carryout; 01413 Expr carryin; 01414 DebugAssert(bitPos >= 0, 01415 "computeCarry: negative bitExtract_Pos is illegal"); 01416 01417 const Expr& t1Thm = t1_i.getRHS(); 01418 const Expr& t2Thm = t2_i.getRHS(); 01419 Expr x = t1Thm.andExpr(t2Thm); 01420 const Expr& t1 = t1_i.getLHS()[0]; 01421 const Expr& t2 = t2_i.getLHS()[0]; 01422 Expr t1Andt2 = t1.andExpr(t2); 01423 Expr index = t1Andt2.andExpr(rat(bitPos)); 01424 01425 if(0 == bitPos) { 01426 if(1 == preComputed) 01427 d_theoryBitvector->d_bvPlusCarryCacheLeftBV.insert(index,x); 01428 else 01429 d_theoryBitvector->d_bvPlusCarryCacheRightBV.insert(index,x); 01430 carryout = x; 01431 //carry.push_back(x); 01432 } 01433 else { 01434 if(1 == preComputed) { 01435 Expr indexMinusOne = t1Andt2.andExpr(rat(bitPos-1)); 01436 if(d_theoryBitvector->d_bvPlusCarryCacheLeftBV.find(indexMinusOne) == 01437 d_theoryBitvector->d_bvPlusCarryCacheLeftBV.end()) 01438 DebugAssert(false, 01439 "this should not happen"); 01440 carryin = 01441 (d_theoryBitvector->d_bvPlusCarryCacheLeftBV).find(indexMinusOne)->second; 01442 Expr secondTerm = t1Thm.andExpr(carryin); 01443 Expr thirdTerm = t2Thm.andExpr(carryin); 01444 01445 carryout = (x.orExpr(secondTerm)).orExpr(thirdTerm); 01446 d_theoryBitvector->d_bvPlusCarryCacheLeftBV.insert(index,carryout); 01447 } 01448 else { 01449 Expr indexMinusOne = t1Andt2.andExpr(rat(bitPos-1)); 01450 if(d_theoryBitvector->d_bvPlusCarryCacheRightBV.find(indexMinusOne) == 01451 d_theoryBitvector->d_bvPlusCarryCacheRightBV.end()) 01452 DebugAssert(false, 01453 "this should not happen"); 01454 carryin = 01455 (d_theoryBitvector->d_bvPlusCarryCacheRightBV).find(indexMinusOne)->second; 01456 //(*d_bvPlusCarryCacheRightBV.find(indexMinusOne)).second; 01457 Expr secondTerm = t1Thm.andExpr(carryin); 01458 Expr thirdTerm = t2Thm.andExpr(carryin); 01459 01460 carryout = (x.orExpr(secondTerm)).orExpr(thirdTerm); 01461 d_theoryBitvector->d_bvPlusCarryCacheRightBV.insert(index,carryout); 01462 } 01463 } 01464 //cout << "the carry for" << index << " is : " << carryout << "\n"; 01465 return carryin; 01466 } 01467 01468 Theorem 01469 BitvectorTheoremProducer:: 01470 zeroPaddingRule(const Expr& e, int i) { 01471 if(CHECK_PROOFS) { 01472 CHECK_SOUND(BITVECTOR == e.getType().getExpr().getOpKind(), 01473 "BitvectorTheoremProducer::zeroPaddingRule:" 01474 "Wrong Input: Input must be a bitvector. But the input is: " + 01475 e.toString()); 01476 } 01477 01478 int bvLength = 01479 d_theoryBitvector->BVSize(d_theoryBitvector->getBaseType(e).getExpr()); 01480 01481 if(CHECK_PROOFS) { 01482 CHECK_SOUND(0 <= i && i >= bvLength, 01483 "BitvectorTheoremProducer::zeroPaddingRule:" 01484 "bitPosition of extraction must be greater than bvLength" + 01485 int2string(i) + "bvLength:" + int2string(bvLength)); 01486 } 01487 const Expr boolExtractExpr = d_theoryBitvector->newBoolExtractExpr(e, i); 01488 01489 Proof pf; 01490 if(withProof()) 01491 pf = newPf("zeropadding_rule", e, rat(i)); 01492 return newRWTheorem(boolExtractExpr, d_theoryBitvector->falseExpr(), Assumptions::emptyAssump(), pf); 01493 } 01494 01495 Theorem 01496 BitvectorTheoremProducer:: 01497 bvPlusAssociativityRule(const Expr& bvPlusTerm) 01498 { 01499 TRACE("bitvector", 01500 "input to bvPlusAssociativityRule(", bvPlusTerm.toString(), ")"); 01501 01502 Type type = bvPlusTerm.getType(); 01503 if(CHECK_PROOFS) { 01504 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01505 "BitvectorTheoremProducer::bvPlusAssociativityRule:" 01506 "term must be BITVECTOR type."); 01507 CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind(), 01508 "BitvectorTheoremProducer::bvPlusAssociativityRule:" 01509 "term must have the kind BVPLUS."); 01510 CHECK_SOUND(2 < bvPlusTerm.arity(), 01511 "BitvectorTheoremProducer::bvPlusAssociativityRule:" 01512 "term must have arity() greater than 2 for associativity."); 01513 } 01514 std::vector<Expr> BVPlusTerms0; 01515 std::vector<Expr>::const_iterator j = (bvPlusTerm.getKids()).begin(); 01516 std::vector<Expr>::const_iterator jend = (bvPlusTerm.getKids()).end(); 01517 //skip the first kid 01518 j++; 01519 BVPlusTerms0.insert(BVPlusTerms0.end(), j, jend); 01520 int bvLength = d_theoryBitvector->BVSize(bvPlusTerm); 01521 const Expr bvplus0 = d_theoryBitvector->newBVPlusExpr(bvLength, 01522 BVPlusTerms0); 01523 01524 std::vector<Expr> BVPlusTerms1; 01525 BVPlusTerms1.push_back(*((bvPlusTerm.getKids()).begin())); 01526 BVPlusTerms1.push_back(bvplus0); 01527 const Expr bvplusOutput = d_theoryBitvector->newBVPlusExpr(bvLength, 01528 BVPlusTerms1); 01529 01530 Proof pf; 01531 if(withProof()) pf = newPf("bv_plus_associativityrule", bvPlusTerm); 01532 const Theorem result(newRWTheorem(bvPlusTerm, bvplusOutput, Assumptions::emptyAssump(), pf)); 01533 TRACE("bitvector", 01534 "output of bvPlusAssociativityRule(", result, ")"); 01535 return result; 01536 } 01537 01538 01539 Theorem BitvectorTheoremProducer::bitExtractNot(const Expr & x, 01540 int i) { 01541 TRACE("bitvector", "input to bitExtractNot(", x.toString(), ")"); 01542 TRACE("bitvector", "input to bitExtractNot(", int2string(i), ")"); 01543 01544 Type type = x.getType(); 01545 if(CHECK_PROOFS) { 01546 //check if the expr is indeed a bitvector term and a concat. 01547 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01548 "BitvectorTheoremProducer::bitExtractNot:" 01549 "term must be bitvector."); 01550 CHECK_SOUND(BVNEG == x.getOpKind() && 1 == x.arity(), 01551 "BitvectorTheoremProducer::bitExtractNot:" 01552 "the bitvector must be an bitwise negation." + x.toString()); 01553 //check if 0<= i < Length of bitvector constant 01554 int bvLength= d_theoryBitvector->BVSize(type.getExpr()); 01555 CHECK_SOUND(0 <= i && i < bvLength, 01556 "BitvectorTheoremProducer::bitExtractNot:" 01557 "illegal boolean extraction was attempted at position i = " 01558 + int2string(i) 01559 + "\non bitvector x = " + x.toString() 01560 + "\nwhose Length is = " + 01561 int2string(bvLength)); 01562 } 01563 // bool-extract of the bitvector constant 01564 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01565 const Expr bitNegTerm = d_theoryBitvector->newBoolExtractExpr(x[0], i); 01566 01567 Proof pf; 01568 if(withProof()) pf = newPf("bit_extract_bitwiseneg", x, rat(i)); 01569 const Theorem result(newRWTheorem(bitExtract,!bitNegTerm,Assumptions::emptyAssump(),pf)); 01570 TRACE("bitvector","output of bitExtractNot(", result, ")"); 01571 return result; 01572 } 01573 01574 01575 Theorem BitvectorTheoremProducer::bitExtractBitwise(const Expr & x, 01576 int i, int kind) 01577 { 01578 TRACE("bitvector", "bitExtractBitwise(", x, ", "+ int2string(i)+") {"); 01579 Type type = x.getType(); 01580 if(CHECK_PROOFS) { 01581 CHECK_SOUND(kind == BVAND || kind == BVOR || kind == BVXOR, 01582 "BitvectorTheoremProducer::bitExtractBitwise: kind = " 01583 +d_theoryBitvector->getEM()->getKindName(kind)); 01584 //check if the expr is indeed a bitvector term and a concat. 01585 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01586 "BitvectorTheoremProducer::bitExtractBitwise: " 01587 "term must be bitvector.\n x = "+x.toString() 01588 +" : "+type.toString()); 01589 CHECK_SOUND(x.getOpKind() == kind && 2 <= x.arity(), 01590 "BitvectorTheoremProducer::bitExtractBitwise: " 01591 "kind does not match.\n x = " 01592 + x.toString()); 01593 //check if 0<= i < Length of bitvector constant 01594 int size = d_theoryBitvector->BVSize(x); 01595 CHECK_SOUND(0 <= i && i < size, 01596 "BitvectorTheoremProducer::bitExtractBitwise: " 01597 "illegal boolean extraction was attempted.\n i = " 01598 + int2string(i) + "\n size = "+ int2string(size)); 01599 } 01600 // bool-extract of the bitvector constant 01601 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01602 vector<Expr> kids; 01603 for(Expr::iterator j=x.begin(), jend=x.end(); j!=jend; ++j) { 01604 kids.push_back(d_theoryBitvector->newBoolExtractExpr(*j, i)); 01605 } 01606 01607 int resKind = kind == BVAND ? AND : 01608 kind == BVOR ? OR : XOR; 01609 Expr rhs = Expr(resKind, kids); 01610 01611 Proof pf; 01612 if(withProof()) pf = newPf("bit_extract_bitwise", x, rat(i)); 01613 const Theorem result(newRWTheorem(bitExtract, rhs, Assumptions::emptyAssump(), pf)); 01614 TRACE("bitvector", "bitExtractBitwise => ", result.toString(), " }"); 01615 return result; 01616 } 01617 01618 01619 Theorem BitvectorTheoremProducer::bitExtractFixedLeftShift(const Expr & x, 01620 int i) { 01621 TRACE("bitvector", "input to bitExtractFixedleftshift(", x.toString(), ")"); 01622 TRACE("bitvector", "input to bitExtractFixedleftshift(", int2string(i), ")"); 01623 01624 Type type = x.getType(); 01625 if(CHECK_PROOFS) { 01626 //check if the expr is indeed a bitvector term and a left shift. 01627 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01628 "BitvectorTheoremProducer::bitExtractFixedleftshift:" 01629 "term must be bitvector."); 01630 CHECK_SOUND((x.getOpKind() == LEFTSHIFT || 01631 x.getOpKind() == CONST_WIDTH_LEFTSHIFT) && 1 == x.arity(), 01632 "BitvectorTheoremProducer::bitExtractFixedleftshift:" 01633 "the bitvector must be a bitwise LEFTSHIFT." + 01634 x.toString()); 01635 CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(x) >= 0, 01636 "BitvectorTheoremProducer::bitExtractFixedleftshift:" 01637 "the bitvector must be a bitwise LEFTSHIFT." + 01638 x.toString()); 01639 //check if 0<= i < bvLength of bitvector constant 01640 int bvLength= d_theoryBitvector->BVSize(type.getExpr()); 01641 CHECK_SOUND(0 <= i && i < bvLength, 01642 "BitvectorTheoremProducer::bitExtractNot:" 01643 "illegal boolean extraction was attempted at position i = " 01644 + int2string(i) 01645 + "\non bitvector x = " + x.toString() 01646 + "\nwhose bvLength is = " + 01647 int2string(bvLength)); 01648 } 01649 // bool-extract of the bitvector constant 01650 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01651 int shiftLength = d_theoryBitvector->getFixedLeftShiftParam(x); 01652 Expr output; 01653 if(0 <= i && i < shiftLength) 01654 output = d_theoryBitvector->falseExpr(); 01655 else 01656 output = 01657 d_theoryBitvector->newBoolExtractExpr(x[0], i-shiftLength); 01658 01659 Proof pf; 01660 if(withProof()) 01661 pf = newPf("bit_extract_bitwisefixedleftshift", x,rat(i)); 01662 const Theorem result = newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf); 01663 TRACE("bitvector", 01664 "output of bitExtractFixedleftshift(", result, ")"); 01665 return result; 01666 } 01667 01668 Theorem BitvectorTheoremProducer::bitExtractFixedRightShift(const Expr & x, 01669 int i) { 01670 TRACE("bitvector", "input to bitExtractFixedRightShift(", x.toString(), ")"); 01671 TRACE("bitvector", "input to bitExtractFixedRightShift(", int2string(i), ")"); 01672 01673 Type type = x.getType(); 01674 if(CHECK_PROOFS) { 01675 //check if the expr is indeed a bitvector term and a concat. 01676 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01677 "BitvectorTheoremProducer::bitExtractFixedRightShift:" 01678 "term must be bitvector."); 01679 CHECK_SOUND(RIGHTSHIFT == x.getOpKind() && 1 == x.arity(), 01680 "BitvectorTheoremProducer::bitExtractFixedRightShift:" 01681 "the bitvector must be an bitwise RIGHTSHIFT." + 01682 x.toString()); 01683 CHECK_SOUND(d_theoryBitvector->getFixedRightShiftParam(x) >= 0, 01684 "BitvectorTheoremProducer::bitExtractFixedRightShift:" 01685 "the bitvector must be an bitwise RIGHTSHIFT." + 01686 x.toString()); 01687 } 01688 //check if 0<= i < bvLength of bitvector constant 01689 int bvLength = d_theoryBitvector->BVSize(x); 01690 if(CHECK_PROOFS) 01691 CHECK_SOUND(0 <= i && i < bvLength, 01692 "BitvectorTheoremProducer::bitExtractNot:" 01693 "illegal boolean extraction was attempted at position i = " 01694 + int2string(i) 01695 + "\non bitvector t = " + x.toString() 01696 + "\nwhose Length is = " + 01697 int2string(bvLength)); 01698 01699 // bool-extract of the bitvector constant 01700 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01701 int shiftLength = d_theoryBitvector->getFixedRightShiftParam(x); 01702 Expr output; 01703 if(bvLength > i && i > bvLength-shiftLength-1) 01704 output = d_theoryBitvector->falseExpr(); 01705 else 01706 output = 01707 d_theoryBitvector->newBoolExtractExpr(x[0], i); 01708 01709 Proof pf; 01710 if(withProof()) 01711 pf = newPf("bit_extract_bitwiseFixedRightShift", x,rat(i)); 01712 const Theorem result = newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf); 01713 TRACE("bitvector", 01714 "output of bitExtractFixedRightShift(", result, ")"); 01715 return result; 01716 } 01717 01718 // BOOLEXTRACT(bvshl(t,s),i) <=> ((s = 0) AND BOOLEXTRACT(t,i)) OR 01719 // ((s = 1) AND BOOLEXTRACT(t,i-1)) OR ... 01720 // ((s = i) AND BOOLEXTRACT(t,0)) 01721 Theorem BitvectorTheoremProducer::bitExtractBVSHL(const Expr & x, int i) 01722 { 01723 Type type = x.getType(); 01724 int bvLength= d_theoryBitvector->BVSize(x); 01725 if(CHECK_PROOFS) { 01726 //check if the expr is indeed a bitvector term and a left shift. 01727 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01728 "BitvectorTheoremProducer::bitExtractBVSHL:" 01729 "term must be bitvector."); 01730 CHECK_SOUND(x.getOpKind() == BVSHL && 2 == x.arity(), 01731 "BitvectorTheoremProducer::bitExtractBVSHL:" 01732 "the bitvector must be a BVSHL." + 01733 x.toString()); 01734 //check if 0<= i < bvLength of bitvector constant 01735 CHECK_SOUND(0 <= i && i < bvLength, 01736 "BitvectorTheoremProducer::bitExtractBVSHL:" 01737 "illegal boolean extraction was attempted at position i = " 01738 + int2string(i) 01739 + "\non bitvector x = " + x.toString() 01740 + "\nwhose bvLength is = " + 01741 int2string(bvLength)); 01742 } 01743 // bool-extract of the bitvector constant 01744 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01745 01746 const Expr& term = x[0]; 01747 const Expr& shift = x[1]; 01748 01749 vector<Expr> kids; 01750 01751 for (int j = 0; j <= i; ++j) { 01752 Expr eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(j, bvLength)); 01753 Expr ext = d_theoryBitvector->newBoolExtractExpr(term, i-j); 01754 kids.push_back(eq && ext); 01755 } 01756 01757 Expr output; 01758 if (kids.size() == 1) { 01759 output = kids[0]; 01760 } 01761 else { 01762 output = Expr(OR, kids); 01763 } 01764 01765 Proof pf; 01766 if(withProof()) 01767 pf = newPf("bit_extract_bvshl", x, rat(i)); 01768 return newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf); 01769 } 01770 01771 01772 // BOOLEXTRACT(bvlshr(t,s),i) <=> ((s = 0) AND BOOLEXTRACT(t,i)) OR 01773 // ((s = 1) AND BOOLEXTRACT(t,i+1)) OR ... 01774 // ((s = n-1-i) AND BOOLEXTRACT(t,n-1)) 01775 Theorem BitvectorTheoremProducer::bitExtractBVLSHR(const Expr & x, int i) 01776 { 01777 Type type = x.getType(); 01778 int bvLength= d_theoryBitvector->BVSize(x); 01779 if(CHECK_PROOFS) { 01780 //check if the expr is indeed a bitvector term and a left shift. 01781 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01782 "BitvectorTheoremProducer::bitExtractBVSHL:" 01783 "term must be bitvector."); 01784 CHECK_SOUND(x.getOpKind() == BVLSHR && 2 == x.arity(), 01785 "BitvectorTheoremProducer::bitExtractBVSHL:" 01786 "the bitvector must be a BVSHL." + 01787 x.toString()); 01788 //check if 0<= i < bvLength of bitvector constant 01789 CHECK_SOUND(0 <= i && i < bvLength, 01790 "BitvectorTheoremProducer::bitExtractBVSHL:" 01791 "illegal boolean extraction was attempted at position i = " 01792 + int2string(i) 01793 + "\non bitvector x = " + x.toString() 01794 + "\nwhose bvLength is = " + 01795 int2string(bvLength)); 01796 } 01797 // bool-extract of the bitvector constant 01798 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01799 01800 const Expr& term = x[0]; 01801 const Expr& shift = x[1]; 01802 01803 vector<Expr> kids; 01804 01805 for (int j = 0; j <= bvLength-1-i; ++j) { 01806 Expr eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(j, bvLength)); 01807 Expr ext = d_theoryBitvector->newBoolExtractExpr(term, i+j); 01808 kids.push_back(eq && ext); 01809 } 01810 01811 Expr output; 01812 if (kids.size() == 1) { 01813 output = kids[0]; 01814 } 01815 else { 01816 output = Expr(OR, kids); 01817 } 01818 01819 Proof pf; 01820 if(withProof()) 01821 pf = newPf("bit_extract_bvlshr", x, rat(i)); 01822 return newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf); 01823 } 01824 01825 01826 // BOOLEXTRACT(bvashr(t,s),i) <=> ((s = 0) AND BOOLEXTRACT(t,i)) OR 01827 // ((s = 1) AND BOOLEXTRACT(t,i+1)) OR ... 01828 // ((s >= n-1-i) AND BOOLEXTRACT(t,n-1)) 01829 Theorem BitvectorTheoremProducer::bitExtractBVASHR(const Expr & x, int i) 01830 { 01831 Type type = x.getType(); 01832 int bvLength= d_theoryBitvector->BVSize(x); 01833 if(CHECK_PROOFS) { 01834 //check if the expr is indeed a bitvector term and a left shift. 01835 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 01836 "BitvectorTheoremProducer::bitExtractBVSHL:" 01837 "term must be bitvector."); 01838 CHECK_SOUND(x.getOpKind() == BVASHR && 2 == x.arity(), 01839 "BitvectorTheoremProducer::bitExtractBVSHL:" 01840 "the bitvector must be a BVSHL." + 01841 x.toString()); 01842 //check if 0<= i < bvLength of bitvector constant 01843 CHECK_SOUND(0 <= i && i < bvLength, 01844 "BitvectorTheoremProducer::bitExtractBVSHL:" 01845 "illegal boolean extraction was attempted at position i = " 01846 + int2string(i) 01847 + "\non bitvector x = " + x.toString() 01848 + "\nwhose bvLength is = " + 01849 int2string(bvLength)); 01850 } 01851 // bool-extract of the bitvector constant 01852 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i); 01853 01854 const Expr& term = x[0]; 01855 const Expr& shift = x[1]; 01856 01857 vector<Expr> kids; 01858 int j = 0; 01859 for (; j < bvLength-1-i; ++j) { 01860 Expr eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(j, bvLength)); 01861 Expr ext = d_theoryBitvector->newBoolExtractExpr(term, i+j); 01862 kids.push_back(eq && ext); 01863 } 01864 Expr tmp = d_theoryBitvector->newBVConstExpr(j, bvLength); 01865 tmp = d_theoryBitvector->newBVLEExpr(tmp, shift); 01866 Expr ext = d_theoryBitvector->newBoolExtractExpr(term, bvLength-1); 01867 kids.push_back(tmp && ext); 01868 01869 Expr output; 01870 if (kids.size() == 1) { 01871 output = kids[0]; 01872 } 01873 else { 01874 output = Expr(OR, kids); 01875 } 01876 01877 Proof pf; 01878 if(withProof()) 01879 pf = newPf("bit_extract_bvashr", x, rat(i)); 01880 return newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf); 01881 } 01882 01883 01884 //! Check that all the kids of e are BVCONST 01885 static bool constantKids(const Expr& e) { 01886 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) 01887 if(i->getOpKind() != BVCONST) return false; 01888 return true; 01889 } 01890 01891 01892 //! c1=c2 <=> TRUE/FALSE (equality of constant bitvectors) 01893 Theorem BitvectorTheoremProducer::eqConst(const Expr& e) { 01894 if(CHECK_PROOFS) { 01895 // The kids must be constant expressions 01896 CHECK_SOUND(e.isEq(), 01897 "BitvectorTheoremProducer::eqConst: e = "+e.toString()); 01898 CHECK_SOUND(constantKids(e), 01899 "BitvectorTheoremProducer::eqConst: e = "+e.toString()); 01900 } 01901 Proof pf; 01902 if(withProof()) 01903 pf = newPf("bitvector_eq_const", e); 01904 Expr res((e[0]==e[1])? d_theoryBitvector->trueExpr() : 01905 d_theoryBitvector->falseExpr()); 01906 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 01907 } 01908 01909 01910 //! |- c1=c2 ==> |- AND(c1[i:i] = c2[i:i]) - expanding equalities into bits 01911 Theorem BitvectorTheoremProducer::eqToBits(const Theorem& eq) { 01912 if(CHECK_PROOFS) { 01913 CHECK_SOUND(eq.isRewrite(), 01914 "BitvectorTheoremProducer::eqToBits: eq = "+eq.toString()); 01915 } 01916 01917 const Expr& lhs = eq.getLHS(); 01918 const Expr& rhs = eq.getRHS(); 01919 01920 if(CHECK_PROOFS) { 01921 CHECK_SOUND(d_theoryBitvector->getBaseType(lhs).getExpr().getOpKind() == BITVECTOR, 01922 "BitvectorTheoremProducer::eqToBits: eq = "+eq.toString()); 01923 CHECK_SOUND(d_theoryBitvector->BVSize(lhs) 01924 == d_theoryBitvector->BVSize(rhs), 01925 "BitvectorTheoremProducer::eqToBits: eq = "+eq.toString()); 01926 } 01927 01928 int i=0, size=d_theoryBitvector->BVSize(lhs); 01929 vector<Expr> bitEqs; 01930 for(; i<size; i++) { 01931 Expr l = d_theoryBitvector->newBVExtractExpr(lhs, i, i); 01932 Expr r = d_theoryBitvector->newBVExtractExpr(rhs, i, i); 01933 bitEqs.push_back(l.eqExpr(r)); 01934 } 01935 Expr res = andExpr(bitEqs); 01936 Proof pf; 01937 if(withProof()) 01938 pf = newPf("eq_to_bits", eq.getExpr(), eq.getProof()); 01939 return newTheorem(res, eq.getAssumptionsRef(), pf); 01940 } 01941 01942 01943 //! t<<n = c \@ 0bin00...00, takes e == (t<<n) 01944 Theorem BitvectorTheoremProducer::leftShiftToConcat(const Expr& e) { 01945 if(CHECK_PROOFS) { 01946 // The kids must be constant expressions 01947 CHECK_SOUND(e.getOpKind() == LEFTSHIFT && e.arity() == 1, 01948 "BitvectorTheoremProducer::leftShiftConst: e = "+e.toString()); 01949 CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(e) >= 0, 01950 "BitvectorTheoremProducer::leftShiftConst: e = "+e.toString()); 01951 } 01952 const Expr& e0 = e[0]; 01953 Expr res(e0); 01954 int shiftSize=d_theoryBitvector->getFixedLeftShiftParam(e); 01955 01956 if (shiftSize != 0) { 01957 Expr padding = d_theoryBitvector->newBVConstExpr(Rational(0), shiftSize); 01958 res = d_theoryBitvector->newConcatExpr(e0, padding); 01959 } 01960 01961 Proof pf; 01962 if(withProof()) 01963 pf = newPf("leftshift_to_concat", e); 01964 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 01965 } 01966 01967 //! t<<n = c \@ 0bin00...00, takes e == (t<<n) 01968 Theorem BitvectorTheoremProducer::constWidthLeftShiftToConcat(const Expr& e) { 01969 if(CHECK_PROOFS) { 01970 // The kids must be constant expressions 01971 CHECK_SOUND(e.getOpKind() == CONST_WIDTH_LEFTSHIFT && e.arity() == 1, 01972 "BitvectorTheoremProducer::leftShiftConst: e = "+e.toString()); 01973 CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(e) >= 0, 01974 "BitvectorTheoremProducer::leftShiftConst: e = "+e.toString()); 01975 } 01976 const Expr& e0 = e[0]; 01977 Expr res; 01978 01979 int shiftSize=d_theoryBitvector->getFixedLeftShiftParam(e); 01980 if (shiftSize == 0) 01981 res = e0; 01982 else { 01983 int bvLength = d_theoryBitvector->BVSize(e); 01984 if (shiftSize >= bvLength) 01985 res = d_theoryBitvector->newBVConstExpr(Rational(0), bvLength); 01986 else { 01987 Expr padding = d_theoryBitvector->newBVConstExpr(Rational(0), shiftSize); 01988 res = d_theoryBitvector->newBVExtractExpr(e0, bvLength-shiftSize-1, 0); 01989 res = d_theoryBitvector->newConcatExpr(res, padding); 01990 } 01991 } 01992 01993 Proof pf; 01994 if(withProof()) 01995 pf = newPf("constWidthLeftShift_to_concat", e); 01996 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 01997 } 01998 01999 02000 //! t>>m = 0bin00...00 \@ t[bvLength-1:m], takes e == (t>>n) 02001 Theorem BitvectorTheoremProducer::rightShiftToConcat(const Expr& e) { 02002 if(CHECK_PROOFS) { 02003 CHECK_SOUND(e.getOpKind() == RIGHTSHIFT && e.arity() == 1, 02004 "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString()); 02005 CHECK_SOUND(d_theoryBitvector->getFixedRightShiftParam(e) >= 0, 02006 "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString()); 02007 } 02008 int bvLength = d_theoryBitvector->BVSize(e[0]); 02009 02010 int shiftSize=d_theoryBitvector->getFixedRightShiftParam(e); 02011 02012 Expr output; 02013 if (shiftSize == 0) output = e[0]; 02014 if (shiftSize >= bvLength) 02015 output = d_theoryBitvector->newBVZeroString(bvLength); 02016 else { 02017 Expr padding = d_theoryBitvector->newBVZeroString(shiftSize); 02018 Expr out0 = d_theoryBitvector->newBVExtractExpr(e[0],bvLength-1,shiftSize); 02019 output = d_theoryBitvector->newConcatExpr(padding,out0); 02020 } 02021 02022 DebugAssert(bvLength == d_theoryBitvector->BVSize(output), 02023 "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString()); 02024 02025 Proof pf; 02026 if(withProof()) 02027 pf = newPf("rightshift_to_concat", e); 02028 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02029 } 02030 02031 02032 //! BVSHL(t,c) = t[n-c,0] \@ 0bin00...00 02033 Theorem BitvectorTheoremProducer::bvshlToConcat(const Expr& e) { 02034 if(CHECK_PROOFS) { 02035 // The second kid must be a constant expression 02036 CHECK_SOUND(e.getOpKind() == BVSHL && e.arity() == 2, 02037 "BitvectorTheoremProducer::bvshlToConcat: e = "+e.toString()); 02038 CHECK_SOUND(e[1].getOpKind() == BVCONST, 02039 "BitvectorTheoremProducer::bvshlToConcat: e = "+e.toString()); 02040 } 02041 const Expr& e0 = e[0]; 02042 Expr res; 02043 02044 Rational shiftSize=d_theoryBitvector->computeBVConst(e[1]); 02045 if (shiftSize == 0) res = e0; 02046 else { 02047 int bvLength = d_theoryBitvector->BVSize(e); 02048 if (shiftSize >= bvLength) 02049 res = d_theoryBitvector->newBVConstExpr(Rational(0), bvLength); 02050 else { 02051 Expr padding = d_theoryBitvector->newBVConstExpr(Rational(0), shiftSize.getInt()); 02052 res = d_theoryBitvector->newBVExtractExpr(e0, bvLength-shiftSize.getInt()-1, 0); 02053 res = d_theoryBitvector->newConcatExpr(res, padding); 02054 } 02055 } 02056 02057 Proof pf; 02058 if(withProof()) 02059 pf = newPf("bvshl_to_concat"); 02060 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02061 } 02062 02063 02064 // bvshl(t,s) = IF (s = 0) THEN t ELSE 02065 // IF (s = 1) then t[n-2:0] @ 0 Else 02066 // ... 02067 // ELSE 0 02068 Theorem BitvectorTheoremProducer::bvshlSplit(const Expr &e) 02069 { 02070 Type type = e.getType(); 02071 int bvLength= d_theoryBitvector->BVSize(e); 02072 if(CHECK_PROOFS) { 02073 //check if the expr is indeed a bitvector term and a left shift. 02074 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(), 02075 "BitvectorTheoremProducer::bitExtractBVSHL:" 02076 "term must be bitvector."); 02077 CHECK_SOUND(e.getOpKind() == BVSHL && 2 == e.arity(), 02078 "BitvectorTheoremProducer::bitExtractBVSHL:" 02079 "the bitvector must be a BVSHL." + 02080 e.toString()); 02081 } 02082 02083 const Expr& term = e[0]; 02084 const Expr& shift = e[1]; 02085 02086 Expr newExpr = d_theoryBitvector->newBVZeroString(bvLength); 02087 Expr eq, tmp; 02088 02089 for (int i = bvLength-1; i > 0; --i) { 02090 eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(i, bvLength)); 02091 tmp = d_theoryBitvector->newBVExtractExpr(term, bvLength-i-1, 0); 02092 tmp = d_theoryBitvector->newConcatExpr(tmp, d_theoryBitvector->newBVZeroString(i)); 02093 newExpr = eq.iteExpr(tmp, newExpr); 02094 } 02095 02096 eq = shift.eqExpr(d_theoryBitvector->newBVZeroString(bvLength)); 02097 newExpr = eq.iteExpr(term, newExpr); 02098 02099 Proof pf; 02100 if(withProof()) 02101 pf = newPf("bvshl_split", e); 02102 return newRWTheorem(e, newExpr, Assumptions::emptyAssump(), pf); 02103 } 02104 02105 02106 //! BVLSHR(t,c) = 0bin00...00 \@ t[n-1,c] 02107 Theorem BitvectorTheoremProducer::bvlshrToConcat(const Expr& e) 02108 { 02109 if(CHECK_PROOFS) { 02110 CHECK_SOUND(e.getOpKind() == BVLSHR && e.arity() == 2, 02111 "BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString()); 02112 CHECK_SOUND(e[1].getOpKind() == BVCONST, 02113 "BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString()); 02114 } 02115 int bvLength = d_theoryBitvector->BVSize(e); 02116 02117 Rational shiftSize=d_theoryBitvector->computeBVConst(e[1]); 02118 02119 Expr output; 02120 if (shiftSize == 0) output = e[0]; 02121 else if(shiftSize >= bvLength) 02122 output = d_theoryBitvector->newBVZeroString(bvLength); 02123 else { 02124 Expr padding = d_theoryBitvector->newBVZeroString(shiftSize.getInt()); 02125 Expr out0 = d_theoryBitvector->newBVExtractExpr(e[0],bvLength-1,shiftSize.getInt()); 02126 output = d_theoryBitvector->newConcatExpr(padding,out0); 02127 } 02128 02129 Proof pf; 02130 if(withProof()) 02131 pf = newPf("bvlshr_to_concat", e); 02132 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02133 } 02134 02135 Theorem BitvectorTheoremProducer::bvShiftZero(const Expr& e) 02136 { 02137 if(CHECK_PROOFS) { 02138 int kind = e.getOpKind(); 02139 CHECK_SOUND((kind == BVLSHR || kind == BVSHL || kind == BVASHR || kind == LEFTSHIFT || kind == CONST_WIDTH_LEFTSHIFT || kind == RIGHTSHIFT) 02140 && e.arity() == 2, "BitvectorTheoremProducer::bvShiftZero: e = "+e.toString()); 02141 CHECK_SOUND(e[0].getOpKind() == BVCONST && d_theoryBitvector->computeBVConst(e[0]) == 0, "BitvectorTheoremProducer::bvShiftZero: e = "+e.toString()); 02142 } 02143 02144 int bvLength = d_theoryBitvector->BVSize(e); 02145 Expr output = d_theoryBitvector->newBVZeroString(bvLength); 02146 02147 Proof pf; 02148 if(withProof()) 02149 pf = newPf("shift_zero", e); 02150 02151 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02152 } 02153 02154 //! BVASHR(t,c) = SX(t[n-1,c], n-1) 02155 Theorem BitvectorTheoremProducer::bvashrToConcat(const Expr& e) 02156 { 02157 if(CHECK_PROOFS) { 02158 CHECK_SOUND(e.getOpKind() == BVASHR && e.arity() == 2, 02159 "BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString()); 02160 CHECK_SOUND(e[1].getOpKind() == BVCONST, 02161 "BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString()); 02162 } 02163 int bvLength = d_theoryBitvector->BVSize(e); 02164 02165 Rational shiftSize=d_theoryBitvector->computeBVConst(e[1]); 02166 02167 Expr output; 02168 if (shiftSize > 0) { 02169 if (shiftSize >= bvLength) shiftSize = bvLength - 1; 02170 Expr out0 = d_theoryBitvector->newBVExtractExpr(e[0],bvLength-1,shiftSize.getInt()); 02171 output = d_theoryBitvector->newSXExpr(out0, bvLength); 02172 } else output = e[0]; 02173 02174 Proof pf; 02175 if(withProof()) 02176 pf = newPf("bvashr_to_concat", e); 02177 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02178 } 02179 02180 02181 Theorem BitvectorTheoremProducer::rewriteXNOR(const Expr& e) 02182 { 02183 if (CHECK_PROOFS) { 02184 CHECK_SOUND(e.getKind() == BVXNOR && e.arity() == 2, 02185 "Bad call to rewriteXNOR"); 02186 } 02187 Expr res = d_theoryBitvector->newBVNegExpr(e[0]); 02188 res = d_theoryBitvector->newBVXorExpr(res, e[1]); 02189 Proof pf; 02190 if (withProof()) 02191 pf = newPf("rewriteXNOR", e); 02192 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02193 } 02194 02195 02196 Theorem BitvectorTheoremProducer::rewriteNAND(const Expr& e) 02197 { 02198 if (CHECK_PROOFS) { 02199 CHECK_SOUND(e.getKind() == BVNAND && e.arity() == 2, 02200 "Bad call to rewriteNAND"); 02201 } 02202 Expr andExpr = d_theoryBitvector->newBVAndExpr(e[0], e[1]); 02203 Proof pf; 02204 if (withProof()) 02205 pf = newPf("rewriteNAND", e); 02206 return newRWTheorem(e, d_theoryBitvector->newBVNegExpr(andExpr), 02207 Assumptions::emptyAssump(), pf); 02208 } 02209 02210 02211 Theorem BitvectorTheoremProducer::rewriteNOR(const Expr& e) 02212 { 02213 if (CHECK_PROOFS) { 02214 CHECK_SOUND(e.getKind() == BVNOR && e.arity() == 2, 02215 "Bad call to rewriteNOR"); 02216 } 02217 Expr orExpr = d_theoryBitvector->newBVOrExpr(e[0], e[1]); 02218 Proof pf; 02219 if (withProof()) 02220 pf = newPf("rewriteNOR", e); 02221 return newRWTheorem(e, d_theoryBitvector->newBVNegExpr(orExpr), 02222 Assumptions::emptyAssump(), pf); 02223 } 02224 02225 02226 Theorem BitvectorTheoremProducer::rewriteBVCOMP(const Expr& e) 02227 { 02228 if (CHECK_PROOFS) { 02229 CHECK_SOUND(e.getKind() == BVCOMP && e.arity() == 2, 02230 "Bad call to rewriteBVCOMP"); 02231 } 02232 Expr res = e[0].eqExpr(e[1]).iteExpr(d_theoryBitvector->newBVOneString(1), 02233 d_theoryBitvector->newBVZeroString(1)); 02234 Proof pf; 02235 if (withProof()) 02236 pf = newPf("rewriteBVCOMP"); 02237 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02238 } 02239 02240 02241 Theorem BitvectorTheoremProducer::rewriteBVSub(const Expr& e) 02242 { 02243 if (CHECK_PROOFS) { 02244 CHECK_SOUND(e.getKind() == BVSUB && e.arity() == 2 && 02245 d_theoryBitvector->BVSize(e[0]) == 02246 d_theoryBitvector->BVSize(e[1]), 02247 "Bad call to rewriteBVSub"); 02248 } 02249 int bvsize = d_theoryBitvector->BVSize(e[0]); 02250 vector<Expr> k; 02251 k.push_back(e[0]); 02252 k.push_back(d_theoryBitvector->newBVUminusExpr(e[1])); 02253 Expr new_expr = d_theoryBitvector->newBVPlusExpr(bvsize, k); 02254 02255 ExprMap<Rational> sumHashMap; 02256 Rational known_term; 02257 getPlusTerms(new_expr, known_term, sumHashMap); 02258 new_expr = buildPlusTerm(bvsize, known_term, sumHashMap); 02259 02260 02261 Proof pf; 02262 if (withProof()) 02263 pf = newPf("rewriteBVSub", e); 02264 return newRWTheorem(e, new_expr, Assumptions::emptyAssump(), pf); 02265 } 02266 02267 02268 //! k*t = BVPLUS(n, <sum of shifts of t>) -- translation of k*t to BVPLUS 02269 /*! If k = 2^m, return k*t = t\@0...0 */ 02270 Theorem BitvectorTheoremProducer::constMultToPlus(const Expr& e) { 02271 DebugAssert(false, 02272 "BitvectorTheoremProducer::constMultToPlus: this rule does not work\n"); 02273 if(CHECK_PROOFS) { 02274 CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2 02275 && e[0].isRational() && e[0].getRational().isInteger(), 02276 "BitvectorTheoremProducer::constMultToPlus:\n e = " 02277 +e.toString()); 02278 } 02279 02280 Rational k = e[0].getRational(); 02281 const Expr& t = e[1]; 02282 int resLength = d_theoryBitvector->BVSize(e); 02283 string coeffBinary = abs(k).toString(2); 02284 int len = coeffBinary.length(); 02285 Expr res; // The resulting expression 02286 if(k == 0) { 02287 // Construct n-bit vector of 0's 02288 vector<bool> bits; 02289 int len = resLength; 02290 for(int i=0; i<len; ++i) bits.push_back(false); 02291 res = d_theoryBitvector->newBVConstExpr(bits); 02292 } else { 02293 // Construct the vector of shifts, the kids of the resulting BVPLUS 02294 vector<Expr> kids; 02295 for(int i=0; i<len; ++i) { 02296 if(coeffBinary[i] == '1') 02297 kids.push_back(d_theoryBitvector->newFixedLeftShiftExpr(t, (len-1)-i)); 02298 } 02299 res = (kids.size() == 1)? kids[0] 02300 : d_theoryBitvector->newBVPlusExpr(resLength, kids); 02301 // For negative k, compute (~res+1), the 2's complement 02302 if(k < 0) { 02303 vector<Expr> kk; 02304 kk.push_back(d_theoryBitvector->newBVNegExpr(res)); 02305 kk.push_back(rat(1)); 02306 res = d_theoryBitvector->newBVPlusExpr(resLength, kk); 02307 } 02308 } 02309 02310 Proof pf; 02311 if(withProof()) 02312 pf = newPf("const_mult_to_plus", e); 02313 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02314 } 02315 02316 02317 Theorem 02318 BitvectorTheoremProducer::bvplusZeroConcatRule(const Expr& e) { 02319 if(CHECK_PROOFS) { 02320 CHECK_SOUND(e.getOpKind()==CONCAT && e.arity()==2, 02321 "BitvectorTheoremProducer::bvplusZeroConcatRule: e = " 02322 +e.toString()); 02323 CHECK_SOUND(e[0].getKind()==BVCONST && e[1].getOpKind()==BVPLUS 02324 && d_theoryBitvector->computeBVConst(e[0])==0, 02325 "BitvectorTheoremProducer::bvplusZeroConcatRule: e = " 02326 +e.toString()); 02327 } 02328 02329 int constSize = d_theoryBitvector->BVSize(e[0]); 02330 const Expr& bvplus = e[1]; 02331 int bvplusSize = d_theoryBitvector->getBVPlusParam(bvplus); 02332 02333 // Check if we can apply the rewrite rule 02334 int maxKidSize(0); 02335 for(Expr::iterator i=bvplus.begin(), iend=bvplus.end(); i!=iend; ++i) { 02336 int size(d_theoryBitvector->BVSize(*i)); 02337 // if kid is 0bin0 @ ..., then we can shorten its effective size 02338 if(i->getOpKind()==CONCAT && i->arity()>=2 02339 && (*i)[0].getKind()==BVCONST && d_theoryBitvector->computeBVConst((*i)[0])==0) 02340 size -= d_theoryBitvector->BVSize((*i)[0]); 02341 if(size > maxKidSize) maxKidSize = size; 02342 } 02343 int numKids = bvplus.arity(); 02344 // Compute ceiling of log2(numKids) 02345 int log2 = 0; 02346 for(int i=1; i < numKids; i *=2, log2++); 02347 if(log2+maxKidSize > bvplusSize) { 02348 // Skip the rewrite, it's potentially unsound 02349 TRACE("bv 0@+", "bvplusZeroConcatRule(", e, "): skipped"); 02350 return d_theoryBitvector->reflexivityRule(e); 02351 } 02352 02353 Expr res(d_theoryBitvector->newBVPlusExpr(bvplusSize+constSize, 02354 bvplus.getKids())); 02355 02356 Proof pf; 02357 if(withProof()) 02358 pf = newPf("bvplus_zero_concat", e); 02359 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02360 } 02361 02362 02363 02364 //! c1[i:j] = c (extraction from a constant bitvector) 02365 Theorem BitvectorTheoremProducer::extractConst(const Expr& e) { 02366 if(CHECK_PROOFS) { 02367 // The kids must be constant expressions 02368 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1, 02369 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 02370 CHECK_SOUND(constantKids(e), 02371 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 02372 } 02373 02374 int hi = d_theoryBitvector->getExtractHi(e); 02375 int low = d_theoryBitvector->getExtractLow(e); 02376 const Expr& e0 = e[0]; 02377 02378 if(CHECK_PROOFS) { 02379 CHECK_SOUND(0 <= low && low <= hi, 02380 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 02381 CHECK_SOUND((unsigned)hi < d_theoryBitvector->getBVConstSize(e0), 02382 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 02383 } 02384 vector<bool> res; 02385 02386 for(int bit=low; bit <= hi; bit++) 02387 res.push_back(d_theoryBitvector->getBVConstValue(e0, bit)); 02388 02389 Proof pf; 02390 if(withProof()) 02391 pf = newPf("extract_const", e); 02392 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf); 02393 } 02394 02395 // t[n-1:0] = t for n-bit t 02396 Theorem 02397 BitvectorTheoremProducer::extractWhole(const Expr& e) { 02398 if(CHECK_PROOFS) { 02399 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1, 02400 "BitvectorTheoremProducer::extractWhole: e = "+e.toString()); 02401 } 02402 02403 int hi = d_theoryBitvector->getExtractHi(e); 02404 int low = d_theoryBitvector->getExtractLow(e); 02405 const Expr& e0 = e[0]; 02406 02407 if(CHECK_PROOFS) { 02408 CHECK_SOUND(low ==0 && hi == d_theoryBitvector->BVSize(e0) - 1, 02409 "BitvectorTheoremProducer::extractWhole: e = "+e.toString() 02410 +"\n BVSize(e) = "+ int2string(d_theoryBitvector->BVSize(e0))); 02411 } 02412 Proof pf; 02413 if(withProof()) 02414 pf = newPf("extract_whole", e); 02415 return newRWTheorem(e, e0, Assumptions::emptyAssump(), pf); 02416 } 02417 02418 02419 //! t[i:j][k:l] = t[k+j:l+j] (eliminate double extraction) 02420 Theorem 02421 BitvectorTheoremProducer::extractExtract(const Expr& e) { 02422 if(CHECK_PROOFS) { 02423 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1, 02424 "BitvectorTheoremProducer::extractExtract: e = "+e.toString()); 02425 } 02426 02427 int hi = d_theoryBitvector->getExtractHi(e); 02428 int low = d_theoryBitvector->getExtractLow(e); 02429 const Expr& e0 = e[0]; 02430 02431 if(CHECK_PROOFS) { 02432 // Check the bounds 02433 CHECK_SOUND(0 <= low && low <= hi, 02434 "BitvectorTheoremProducer::extractExtract: e = "+e.toString()); 02435 // The base expression must also be EXTRACT 02436 CHECK_SOUND(e0.getOpKind() == EXTRACT && e0.arity() == 1, 02437 "BitvectorTheoremProducer::extractExtract: e0 = " 02438 +e0.toString()); 02439 } 02440 02441 int hi0 = d_theoryBitvector->getExtractHi(e0); 02442 int low0 = d_theoryBitvector->getExtractLow(e0); 02443 const Expr& e00 = e0[0]; 02444 02445 if(CHECK_PROOFS) { 02446 // The extractions must be within the correct bounds 02447 CHECK_SOUND((0 <= low) && (low <= hi) && (hi <= hi0-low0), 02448 "BitvectorTheoremProducer::extractExtract:\n" 02449 " [hi:low][hi0:low0] = ["+ int2string(hi0)+":"+ int2string(low0) 02450 +"]["+ int2string(hi) + ":" + int2string(low) 02451 +"]\n e = "+e.toString()); 02452 } 02453 02454 Expr res = d_theoryBitvector->newBVExtractExpr(e00, hi+low0, low+low0); 02455 02456 Proof pf; 02457 if(withProof()) 02458 pf = newPf("extract_extract", e); 02459 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02460 } 02461 02462 02463 //! (t1 \@ t2)[i:j] = t1[...] \@ t2[...] (push extraction through concat) 02464 Theorem 02465 BitvectorTheoremProducer::extractConcat(const Expr& e) { 02466 TRACE("bitvector rules", "extractConcat(", e, ") {"); 02467 if(CHECK_PROOFS) { 02468 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1, 02469 "BitvectorTheoremProducer::extractConcat: e = "+e.toString()); 02470 } 02471 02472 int hi = d_theoryBitvector->getExtractHi(e); 02473 int low = d_theoryBitvector->getExtractLow(e); 02474 const Expr& e0 = e[0]; 02475 02476 if(CHECK_PROOFS) { 02477 // Check the bounds 02478 CHECK_SOUND(0 <= low && low <= hi, 02479 "BitvectorTheoremProducer::extractConcat: e = "+e.toString()); 02480 CHECK_SOUND(hi < d_theoryBitvector->BVSize(e0), 02481 "BitvectorTheoremProducer::extractConcat: e = "+e.toString() 02482 +"\n BVSize(e0) = "+ int2string(d_theoryBitvector->BVSize(e0))); 02483 // The base expression must be CONCAT 02484 CHECK_SOUND(e0.getOpKind() == CONCAT, 02485 "BitvectorTheoremProducer::extractConcat: e0 = " 02486 +e0.toString()); 02487 } 02488 // Collect the relevant kids from concatenation 02489 vector<Expr> kids; 02490 int width(d_theoryBitvector->BVSize(e0)); 02491 TRACE("bitvector rules", "extractConcat: width=", width, ""); 02492 for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend && width>low; ++i) { 02493 TRACE("bitvector rules", "extractConcat: *i=", *i, ""); 02494 int w(d_theoryBitvector->BVSize(*i)); 02495 int newWidth = width-w; 02496 int l(0), h(0); 02497 TRACE("bitvector rules", "extractConcat: w=", w, ""); 02498 TRACE("bitvector rules", "extractConcat: newWidth=", newWidth, ""); 02499 if(width > hi) { // Previous kids were outside of extract window 02500 if(hi >= newWidth) { // The first relevant kid 02501 h = hi-newWidth; 02502 l = (newWidth <= low)? low-newWidth : 0; 02503 TRACE("bitvector rules", "extractConcat[newWidth<=hi<width]: h=", 02504 h, ", l="+ int2string(l)); 02505 kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, h, l)); 02506 } 02507 } else if(width > low) { 02508 // High end of the current kid is in the extract window 02509 h = w-1; 02510 l = (newWidth <= low)? low-newWidth : 0; 02511 TRACE("bitvector rules", "extractConcat[low<width<=hi]: h=", 02512 h, ", l="+ int2string(l)); 02513 kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, h, l)); 02514 } // The remaining kids are outside of extract window, skip them 02515 width=newWidth; 02516 TRACE("bitvector rules", "extractConcat: width=", width, ""); 02517 } 02518 Expr res = (kids.size()==1)? kids[0] 02519 : d_theoryBitvector->newConcatExpr(kids); 02520 Proof pf; 02521 if(withProof()) 02522 pf = newPf("extract_concat", e); 02523 Theorem thm(newRWTheorem(e, res, Assumptions::emptyAssump(), pf)); 02524 TRACE("bitvector rules", "extractConcat => ", thm.getExpr(), " }"); 02525 return thm; 02526 } 02527 02528 02529 // (t1 op t2)[i:j] = t1[i:j] op t2[i:j] -- push extraction through 02530 // bit-wise operator 02531 Theorem 02532 BitvectorTheoremProducer::extractBitwise(const Expr& e, int kind, 02533 const string& pfName) { 02534 if(CHECK_PROOFS) { 02535 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1, 02536 "BitvectorTheoremProducer::"+pfName+": e = "+e.toString()); 02537 CHECK_SOUND(kind == BVAND || kind == BVOR || 02538 kind == BVNEG || kind == BVXOR || 02539 kind == BVXNOR, 02540 "BitvectorTheoremProducer::"+pfName+": kind = " 02541 +d_theoryBitvector->getEM()->getKindName(kind)); 02542 } 02543 02544 int hi = d_theoryBitvector->getExtractHi(e); 02545 int low = d_theoryBitvector->getExtractLow(e); 02546 const Expr& e0 = e[0]; 02547 02548 if(CHECK_PROOFS) { 02549 // Check the bounds 02550 CHECK_SOUND(0 <= low && low <= hi, 02551 "BitvectorTheoremProducer::"+pfName+": e = "+e.toString()); 02552 // The base expression must also be EXTRACT 02553 CHECK_SOUND(e0.getOpKind() == kind, 02554 "BitvectorTheoremProducer::"+pfName+": e0 = " 02555 +e0.toString()); 02556 } 02557 02558 vector<Expr> kids; 02559 for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend; ++i) { 02560 kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, hi, low)); 02561 } 02562 Expr res = Expr(e0.getOp(), kids); 02563 Proof pf; 02564 if(withProof()) 02565 pf = newPf(pfName, e); 02566 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02567 } 02568 02569 //! (t1 & t2)[i:j] = t1[i:j] & t2[i:j] (push extraction through OR) 02570 Theorem 02571 BitvectorTheoremProducer::extractAnd(const Expr& e) { 02572 return extractBitwise(e, BVAND, "extract_and"); 02573 } 02574 02575 02576 //! (t1 | t2)[i:j] = t1[i:j] | t2[i:j] (push extraction through AND) 02577 Theorem 02578 BitvectorTheoremProducer::extractOr(const Expr& e) { 02579 return extractBitwise(e, BVOR, "extract_or"); 02580 } 02581 02582 02583 //! (~t)[i:j] = ~(t[i:j]) (push extraction through NEG) 02584 Theorem 02585 BitvectorTheoremProducer::extractNeg(const Expr& e) { 02586 return extractBitwise(e, BVNEG, "extract_neg"); 02587 } 02588 02589 //! ite(c,t1,t2)[i:j] <=> ite(c,t1[i:j],t2[i:j]) 02590 Theorem 02591 BitvectorTheoremProducer::iteExtractRule(const Expr& e) { 02592 if(CHECK_PROOFS) { 02593 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity()==1, 02594 "BitvectorTheoremProducer::iteExtractRule: " 02595 "input must be an bitvector EXTRACT expr:\n"+ 02596 e.toString()); 02597 } 02598 int hi = d_theoryBitvector->getExtractHi(e); 02599 int low = d_theoryBitvector->getExtractLow(e); 02600 02601 if(CHECK_PROOFS) { 02602 CHECK_SOUND(e[0].getKind() == ITE && 02603 e[0].arity()==3 && 02604 BITVECTOR == e[0].getType().getExpr().getOpKind(), 02605 "BitvectorTheoremProducer::iteExtractRule: " 02606 "input must be an bitvector EXTRACT expr over an ITE:\n" + 02607 e.toString()); 02608 CHECK_SOUND(hi >= low && d_theoryBitvector->BVSize(e[0]) >= hi-low, 02609 "BitvectorTheoremProducer::iteExtractRule: " 02610 "i should be greater than j in e[i:j] = " 02611 +e.toString()); 02612 } 02613 const Expr ite = e[0]; 02614 Expr cond = ite[0]; 02615 Expr e1 = d_theoryBitvector->newBVExtractExpr(ite[1],hi,low); 02616 Expr e2 = d_theoryBitvector->newBVExtractExpr(ite[2],hi,low); 02617 Expr output = Expr(CVC3::ITE,cond,e1,e2); 02618 02619 Proof pf; 02620 if(withProof()) 02621 pf = newPf("ite_extract_rule", e); 02622 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02623 } 02624 02625 //! ~ite(c,t1,t2) <=> ite(c,~t1,~t2) 02626 Theorem 02627 BitvectorTheoremProducer::iteBVnegRule(const Expr& e) { 02628 if(CHECK_PROOFS) { 02629 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity()==1, 02630 "BitvectorTheoremProducer::itebvnegrule: " 02631 "input must be an bitvector EXTRACT expr:\n"+ 02632 e.toString()); 02633 } 02634 if(CHECK_PROOFS) { 02635 CHECK_SOUND(e[0].getKind() == ITE && 02636 e[0].arity()==3 && 02637 BITVECTOR == e[0].getType().getExpr().getOpKind(), 02638 "BitvectorTheoremProducer::itebvnegrule: " 02639 "input must be an bitvector EXTRACT expr over an ITE:\n" + 02640 e.toString()); 02641 } 02642 const Expr ite = e[0]; 02643 Expr cond = ite[0]; 02644 Expr e1 = d_theoryBitvector->newBVNegExpr(ite[1]); 02645 Expr e2 = d_theoryBitvector->newBVNegExpr(ite[2]); 02646 Expr output = Expr(CVC3::ITE,cond,e1,e2); 02647 02648 Proof pf; 02649 if(withProof()) 02650 pf = newPf("ite_bvneg_rule", e); 02651 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02652 } 02653 02654 //! ~c1 = c (bit-wise negation of a constant bitvector) 02655 Theorem BitvectorTheoremProducer::negConst(const Expr& e) { 02656 if(CHECK_PROOFS) { 02657 // The kids must be constant expressions 02658 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1, 02659 "BitvectorTheoremProducer::negConst: e = "+e.toString()); 02660 CHECK_SOUND(constantKids(e), 02661 "BitvectorTheoremProducer::negConst: e = "+e.toString()); 02662 } 02663 const Expr& e0 = e[0]; 02664 vector<bool> res; 02665 02666 for(int bit=0, size=d_theoryBitvector->getBVConstSize(e0); bit<size; bit++) 02667 res.push_back(!d_theoryBitvector->getBVConstValue(e0, bit)); 02668 02669 Proof pf; 02670 if(withProof()) 02671 pf = newPf("bitneg_const", e); 02672 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf); 02673 } 02674 02675 02676 //! ~(t1\@...\@tn) = (~t1)\@...\@(~tn) -- push negation through concat 02677 Theorem 02678 BitvectorTheoremProducer::negConcat(const Expr& e) { 02679 if(CHECK_PROOFS) { 02680 // The kids must be constant expressions 02681 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1, 02682 "BitvectorTheoremProducer::negConcat: e = "+e.toString()); 02683 CHECK_SOUND(e[0].getOpKind() == CONCAT, 02684 "BitvectorTheoremProducer::negConcat: e = "+e.toString()); 02685 } 02686 02687 const Expr& e0 = e[0]; 02688 02689 vector<Expr> kids; 02690 for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend; ++i) 02691 kids.push_back(d_theoryBitvector->newBVNegExpr(*i)); 02692 02693 Expr res = d_theoryBitvector->newConcatExpr(kids); 02694 02695 Proof pf; 02696 if(withProof()) 02697 pf = newPf("bitneg_concat", e); 02698 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02699 } 02700 02701 //! ~(~t) = t -- eliminate double negation 02702 Theorem 02703 BitvectorTheoremProducer::negNeg(const Expr& e) { 02704 if(CHECK_PROOFS) { 02705 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1, 02706 "BitvectorTheoremProducer::negNeg: e = "+e.toString()); 02707 CHECK_SOUND(e[0].getOpKind() == BVNEG && e[0].arity() == 1, 02708 "BitvectorTheoremProducer::negNeg: e = "+e.toString()); 02709 } 02710 02711 Proof pf; 02712 if(withProof()) 02713 pf = newPf("bitneg_neg", e); 02714 return newRWTheorem(e, e[0][0], Assumptions::emptyAssump(), pf); 02715 } 02716 02717 02718 //! ~t = -1*t + 1 -- eliminate negation 02719 Theorem BitvectorTheoremProducer::negElim(const Expr& e) 02720 { 02721 if(CHECK_PROOFS) { 02722 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1, 02723 "BitvectorTheoremProducer::negNeg: e = "+e.toString()); 02724 } 02725 02726 int bv_size = d_theoryBitvector->BVSize(e[0]); 02727 Rational modulus = pow(Rational(bv_size), Rational(2)); 02728 Expr minus_one = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size); 02729 02730 vector<Expr> bvplusTerms; 02731 bvplusTerms.push_back(minus_one); 02732 bvplusTerms.push_back(d_theoryBitvector->newBVMultExpr(bv_size, minus_one, e[0])); 02733 Expr res = d_theoryBitvector->newBVPlusExpr(bv_size, bvplusTerms); 02734 02735 Proof pf; 02736 if(withProof()) 02737 pf = newPf("bitneg_elim", e); 02738 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02739 } 02740 02741 02742 //! ~(t1 & t2) = ~t1 | ~t2 -- DeMorgan's Laws 02743 Theorem 02744 BitvectorTheoremProducer::negBVand(const Expr& e) { 02745 if(CHECK_PROOFS) { 02746 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1, 02747 "BitvectorTheoremProducer::negBVand: e = "+e.toString()); 02748 CHECK_SOUND(e[0].getOpKind() == BVAND, 02749 "BitvectorTheoremProducer::negBVand: e = "+e.toString()); 02750 } 02751 Expr output; 02752 std::vector<Expr> negated; 02753 for(Expr::iterator i = e[0].begin(),iend=e[0].end();i!=iend;++i) 02754 negated.push_back(d_theoryBitvector->newBVNegExpr(*i)); 02755 output = d_theoryBitvector->newBVOrExpr(negated); 02756 02757 Proof pf; 02758 if(withProof()) 02759 pf = newPf("bitneg_and", e); 02760 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02761 } 02762 02763 02764 //! ~(t1 | t2) = ~t1 & ~t2 -- DeMorgan's Laws 02765 Theorem 02766 BitvectorTheoremProducer::negBVor(const Expr& e) { 02767 if(CHECK_PROOFS) { 02768 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1, 02769 "BitvectorTheoremProducer::negBVor: e = "+e.toString()); 02770 CHECK_SOUND(e[0].getOpKind() == BVOR, 02771 "BitvectorTheoremProducer::negBVor: e = "+e.toString()); 02772 } 02773 02774 Expr output; 02775 std::vector<Expr> negated; 02776 for(Expr::iterator i = e[0].begin(),iend=e[0].end();i!=iend;++i) 02777 negated.push_back(d_theoryBitvector->newBVNegExpr(*i)); 02778 output = d_theoryBitvector->newBVAndExpr(negated); 02779 02780 Proof pf; 02781 if(withProof()) 02782 pf = newPf("bitneg_or", e); 02783 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02784 } 02785 02786 02787 //! ~(t1 xor t2) = ~t1 xor t2 02788 Theorem 02789 BitvectorTheoremProducer::negBVxor(const Expr& e) { 02790 if(CHECK_PROOFS) { 02791 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1 && e[0].arity() > 0, 02792 "BitvectorTheoremProducer::negBVxor: e = "+e.toString()); 02793 CHECK_SOUND(e[0].getOpKind() == BVXOR, 02794 "BitvectorTheoremProducer::negBVxor: e = "+e.toString()); 02795 } 02796 02797 Expr output; 02798 std::vector<Expr> children; 02799 Expr::iterator i = e[0].begin(), iend = e[0].end(); 02800 children.push_back(d_theoryBitvector->newBVNegExpr(*i)); 02801 ++i; 02802 for(; i!=iend; ++i) 02803 children.push_back(*i); 02804 output = d_theoryBitvector->newBVXorExpr(children); 02805 02806 Proof pf; 02807 if(withProof()) 02808 pf = newPf("bitneg_xor", e); 02809 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02810 } 02811 02812 02813 //! ~(t1 xnor t2) = t1 xor t2 02814 Theorem 02815 BitvectorTheoremProducer::negBVxnor(const Expr& e) { 02816 if(CHECK_PROOFS) { 02817 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1 && e[0].arity() > 0, 02818 "BitvectorTheoremProducer::negBVxor: e = "+e.toString()); 02819 CHECK_SOUND(e[0].getOpKind() == BVXNOR, 02820 "BitvectorTheoremProducer::negBVxor: e = "+e.toString()); 02821 } 02822 02823 Expr t2 = e[0][1]; 02824 if (e[0].arity() > 2) { 02825 std::vector<Expr> children; 02826 Expr::iterator i = e[0].begin(), iend = e[0].end(); 02827 ++i; 02828 for(; i!=iend; ++i) 02829 children.push_back(*i); 02830 t2 = d_theoryBitvector->newBVXnorExpr(children); 02831 } 02832 Expr output = d_theoryBitvector->newBVXorExpr(e[0][0], t2); 02833 02834 Proof pf; 02835 if(withProof()) 02836 pf = newPf("bitneg_xnor", e); 02837 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 02838 } 02839 02840 02841 //! c1 op c2 = c -- bit-wise AND, OR, XOR of constant bitvectors 02842 Theorem BitvectorTheoremProducer::bitwiseConst(const Expr& e, 02843 const vector<int>& idxs, 02844 int kind) 02845 { 02846 if(CHECK_PROOFS) { 02847 // The kids must be constant expressions 02848 CHECK_SOUND(e.getOpKind() == kind, 02849 "BitvectorTheoremProducer::bitwiseConst: e = "+e.toString()); 02850 CHECK_SOUND(e.getOpKind() == BVAND || 02851 e.getOpKind() == BVOR || 02852 e.getOpKind() == BVXOR, "Expected AND, OR, or XOR"); 02853 CHECK_SOUND(idxs.size() >= 2, "BitvectorTheoremProducer::bitwiseConst():\n e = " 02854 +e.toString()); 02855 for(size_t i=0; i<idxs.size(); ++i) { 02856 CHECK_SOUND(idxs[i] < e.arity(), 02857 "BitvectorTheoremProducer::bitwiseConst: idxs[" 02858 +int2string(i)+"]="+int2string(idxs[i]) 02859 +", e.arity() = "+int2string(e.arity()) 02860 +"\n e = "+e.toString()); 02861 CHECK_SOUND(e[idxs[i]].getKind() == BVCONST, 02862 "BitvectorTheoremProducer::bitwiseConst: e = "+e.toString()); 02863 } 02864 } 02865 // Initialize 'bits' with all 1's or 0's, depending on kind 02866 vector<bool> bits; 02867 int size = d_theoryBitvector->BVSize(e); 02868 for(int bit=0; bit<size; bit++) { 02869 bits.push_back(kind == BVAND); 02870 } 02871 02872 vector<Expr> kids(1); // Reserve the first element for the constant bitvector 02873 size_t ii(0); // The next index of idxs to match 02874 int idx(idxs[0]); // The index of the next constant (for efficiency) 02875 for(int i=0, iend=e.arity(); i<iend; ++i) { 02876 const Expr& ei = e[i]; 02877 if(i == idx) { 02878 if(CHECK_PROOFS) { 02879 CHECK_SOUND(ei.getKind() == BVCONST, 02880 "BitvectorTheoremProducer::bitwiseConst: e[" 02881 +int2string(i)+"] = "+ei.toString()); 02882 CHECK_SOUND(d_theoryBitvector->getBVConstSize(ei) == (unsigned)size, 02883 "BitvectorTheoremProducer::bitwiseConst: e[" 02884 +int2string(i)+"] = "+ei.toString()); 02885 } 02886 // Incorporate the constant bitvector 02887 for(int bit=0; bit<size; bit++) 02888 bits[bit] = 02889 kind == BVAND ? (bits[bit] && d_theoryBitvector->getBVConstValue(ei, bit)) : 02890 kind == BVOR ? (bits[bit] || d_theoryBitvector->getBVConstValue(ei, bit)) : 02891 bits[bit] != d_theoryBitvector->getBVConstValue(ei, bit); 02892 // Advance the index of idxs 02893 if (ii < idxs.size() - 1) 02894 idx = idxs[++ii]; 02895 else 02896 idx = e.arity(); 02897 } 02898 else // Not a constant, add to the list of kids 02899 kids.push_back(ei); 02900 } 02901 // Create the new constant bitvector and make it the first kid 02902 kids[0] = d_theoryBitvector->newBVConstExpr(bits); 02903 // Contruct the final expression. 02904 Expr res = (kids.size() == 1) ? kids[0] : 02905 kind == BVAND ? d_theoryBitvector->newBVAndExpr(kids) : 02906 kind == BVOR ? d_theoryBitvector->newBVOrExpr(kids) : 02907 d_theoryBitvector->newBVXorExpr(kids); 02908 02909 Proof pf; 02910 if(withProof()) { 02911 // Construct a list of indices as a RAW_LIST Expr 02912 vector<Expr> indices; 02913 for(size_t i=0, iend=idxs.size(); i<iend; ++i) 02914 indices.push_back(rat(idxs[i])); 02915 pf = newPf("bitwise_const", e, Expr(RAW_LIST, indices)); 02916 } 02917 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02918 } 02919 02920 02921 //! Lifts concatenation above bitwise operators. 02922 Theorem BitvectorTheoremProducer::bitwiseConcat(const Expr& e, int kind) 02923 { 02924 if(CHECK_PROOFS) { 02925 CHECK_SOUND(e.getOpKind() == kind, 02926 "BitvectorTheoremProducer::bitwiseConcat: e = "+e.toString()); 02927 } 02928 02929 int arity = e.arity(); 02930 int idx; 02931 for (idx = 0; idx < arity; ++idx) { 02932 if (e[idx].getOpKind() == CONCAT) break; 02933 } 02934 if (idx == arity) 02935 return d_theoryBitvector->reflexivityRule(e); 02936 02937 const Expr& ei = e[idx]; 02938 02939 // Build the top-level concatenation 02940 vector<Expr> concatKids; 02941 // Current extraction window 02942 int hi=d_theoryBitvector->BVSize(e)-1; 02943 int low=hi-d_theoryBitvector->BVSize(ei[0])+1; 02944 02945 for(int i=0, iend=ei.arity(); i<iend; ++i) { 02946 // Kids of the current BVAND / BVOR 02947 vector<Expr> kids; 02948 for(int j=0; j<arity; ++j) { 02949 if(j==idx) 02950 kids.push_back(ei[i]); 02951 else 02952 kids.push_back(d_theoryBitvector->newBVExtractExpr(e[j], hi, low)); 02953 } 02954 concatKids.push_back(Expr(kind, kids)); 02955 if(i+1<iend) { 02956 int newHi = low-1; 02957 low = low - d_theoryBitvector->BVSize(ei[i+1]); 02958 hi = newHi; 02959 } 02960 } 02961 Expr res = d_theoryBitvector->newConcatExpr(concatKids); 02962 Proof pf; 02963 if(withProof()) 02964 pf = newPf("bitwise_concat", e, rat(idx)); 02965 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 02966 } 02967 02968 02969 //! Flatten bitwise operation 02970 Theorem BitvectorTheoremProducer::bitwiseFlatten(const Expr& e, int kind) 02971 { 02972 if(CHECK_PROOFS) { 02973 CHECK_SOUND(e.getOpKind() == kind && e.arity()>=2, 02974 "BitvectorTheoremProducer::bitwiseFlatten: e = "+e.toString()); 02975 CHECK_SOUND(e.getOpKind() == BVAND || 02976 e.getOpKind() == BVOR || 02977 e.getOpKind() == BVXOR, "Expected AND, OR, or XOR"); 02978 } 02979 int bvLength = d_theoryBitvector->BVSize(e); 02980 02981 // flatten the nested ops 02982 vector<Expr> flattenkids; 02983 for(Expr::iterator i = e.begin(),iend=e.end();i!=iend; ++i) { 02984 if(i->getOpKind() == kind) 02985 flattenkids.insert(flattenkids.end(), 02986 i->getKids().begin(),i->getKids().end()); 02987 else 02988 flattenkids.push_back(*i); 02989 } 02990 02991 // drop duplicate subterms and detect conflicts like t, ~t 02992 Expr output; 02993 int flag; 02994 ExprMap<int> likeTerms; 02995 vector<Expr>::iterator j = flattenkids.begin(); 02996 vector<Expr>::iterator jend = flattenkids.end(); 02997 bool negate = false; 02998 02999 for(; output.isNull() && j != flattenkids.end(); ++j) { 03000 Expr t = *j; 03001 if (kind == BVXOR && t.getOpKind() == BVNEG) { 03002 negate = !negate; 03003 t = t[0]; 03004 } 03005 //check if *j is duplicated or its negation already occured 03006 flag = sameKidCheck(t, likeTerms); 03007 switch(flag) { 03008 case 0: 03009 //no duplicates 03010 break; 03011 case 1: 03012 //duplicate detected. ignore the duplicate for BVAND, BVOR 03013 if (kind == BVXOR) { 03014 // remove both for BVXOR 03015 likeTerms.erase(t); 03016 } 03017 break; 03018 case -1: 03019 //conflict detected 03020 if (kind == BVAND) 03021 output = d_theoryBitvector->newBVZeroString(bvLength); 03022 else if (kind == BVOR) 03023 output = d_theoryBitvector->newBVOneString(bvLength); 03024 else { 03025 DebugAssert(false, "Shouldn't be possible"); 03026 } 03027 break; 03028 default: 03029 DebugAssert(false, 03030 "control should not reach here"); 03031 break; 03032 } 03033 } 03034 03035 if (output.isNull()) { 03036 vector<Expr> outputkids; 03037 ExprMap<int>::iterator it = likeTerms.begin(); 03038 for(; it != likeTerms.end(); ++it) { 03039 outputkids.push_back((*it).first); 03040 } 03041 if(CHECK_PROOFS) { 03042 CHECK_SOUND(kind == BVXOR || outputkids.size() > 0, 03043 "TheoryBitvector:bitwiseFlatten: fatal error"); 03044 } 03045 if (outputkids.size() == 0) { 03046 outputkids.push_back(d_theoryBitvector->newBVZeroString(bvLength)); 03047 } 03048 if (negate) { 03049 outputkids[0] = d_theoryBitvector->newBVNegExpr(outputkids[0]); 03050 } 03051 if (outputkids.size() == 1) { 03052 output = outputkids[0]; 03053 } 03054 else { 03055 output = Expr(kind, outputkids); 03056 } 03057 } 03058 03059 Proof pf; 03060 if(withProof()) 03061 pf = newPf("bitwise_flatten", e); 03062 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 03063 } 03064 03065 03066 // Rewrite bitwise operation with constant using concatenation, 03067 // negation, and extraction 03068 Theorem BitvectorTheoremProducer::bitwiseConstElim(const Expr& e, 03069 int idx, int kind) 03070 { 03071 if(CHECK_PROOFS) { 03072 CHECK_SOUND(e.getOpKind() == kind, 03073 "BitvectorTheoremProducer::bitwiseConstElim: e = "+e.toString()); 03074 CHECK_SOUND(e.getOpKind() == BVAND || 03075 e.getOpKind() == BVOR || 03076 e.getOpKind() == BVXOR, "Expected AND, OR, or XOR"); 03077 CHECK_SOUND(idx < e.arity() && e.arity() > 1, 03078 "BitvectorTheoremProducer::bitwiseConstElim: e = "+e.toString() 03079 +"\n idx = "+int2string(idx) 03080 +"\n e.arity() = "+int2string(e.arity())); 03081 CHECK_SOUND(e[idx].getOpKind() == BVCONST, 03082 "BitvectorTheoremProducer::bitwiseConstElim: e["+int2string(idx) 03083 +"] = "+e[idx].toString()); 03084 } 03085 03086 int bvLength = d_theoryBitvector->BVSize(e); 03087 Expr output; 03088 vector<Expr> kids; 03089 for (int i = 0; i < e.arity(); ++i) { 03090 if (i == idx) continue; 03091 kids.push_back(e[i]); 03092 } 03093 if (kids.size() == 1) output = kids[0]; 03094 else output = Expr(kind, kids); 03095 03096 const Expr& c = e[idx]; 03097 int i=d_theoryBitvector->getBVConstSize(c)-1; 03098 bool curVal = d_theoryBitvector->getBVConstValue(c, i); 03099 int hi = bvLength-1; 03100 Expr term; 03101 vector<Expr> concatTerms; 03102 03103 for(--i; i >= 0; --i) { 03104 if (d_theoryBitvector->getBVConstValue(c,i) != curVal) { 03105 if (kind == BVAND && curVal == false) { 03106 term = d_theoryBitvector->newBVZeroString(hi-i); 03107 } 03108 else if (kind == BVOR && curVal == true) { 03109 term = d_theoryBitvector->newBVOneString(hi-i); 03110 } 03111 else { 03112 term = d_theoryBitvector->newBVExtractExpr(output, hi, i+1); 03113 if (kind == BVXOR && curVal == true) { 03114 term = d_theoryBitvector->newBVNegExpr(term); 03115 } 03116 } 03117 concatTerms.push_back(term); 03118 curVal = !curVal; 03119 hi = i; 03120 } 03121 } 03122 03123 if (kind == BVAND && curVal == false) { 03124 term = d_theoryBitvector->newBVZeroString(hi+1); 03125 } 03126 else if (kind == BVOR && curVal == true) { 03127 term = d_theoryBitvector->newBVOneString(hi+1); 03128 } 03129 else { 03130 if (hi < bvLength-1) { 03131 term = d_theoryBitvector->newBVExtractExpr(output, hi, 0); 03132 } 03133 else term = output; 03134 if (kind == BVXOR && curVal == true) { 03135 term = d_theoryBitvector->newBVNegExpr(term); 03136 } 03137 } 03138 concatTerms.push_back(term); 03139 if (concatTerms.size() == 1) { 03140 output = concatTerms[0]; 03141 } 03142 else { 03143 output = d_theoryBitvector->newConcatExpr(concatTerms); 03144 } 03145 03146 Proof pf; 03147 if(withProof()) 03148 pf = newPf("bitwise_zero", e, rat(idx)); 03149 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 03150 } 03151 03152 03153 /*! checks if e is already present in likeTerms without conflicts. 03154 * if yes return 1, else{ if conflict return -1 else return 0 } 03155 * we have conflict if 03156 * 1. the kind of e is BVNEG, 03157 * and e[0] is already present in likeTerms 03158 * 2. ~e is present in likeTerms already 03159 */ 03160 int BitvectorTheoremProducer::sameKidCheck(const Expr& e, 03161 ExprMap<int>& likeTerms) { 03162 //initially flag = 0, i.e. we assume e is not in likeTerms 03163 int flag = 0; 03164 03165 //look for e 03166 ExprMap<int>::iterator it = likeTerms.find(e); 03167 03168 //no entry found for e 03169 if(it==likeTerms.end()) { 03170 switch(e.getOpKind()) { 03171 case BVNEG: { 03172 ExprMap<int>::iterator it0 = likeTerms.find(e[0]); 03173 if(it0!=likeTerms.end()) 03174 flag = -1; 03175 break; 03176 } 03177 default: { 03178 Expr bvNeg = d_theoryBitvector->newBVNegExpr(e); 03179 ExprMap<int>::iterator negIt = likeTerms.find(bvNeg); 03180 if(negIt!=likeTerms.end()) 03181 flag=-1; 03182 break; 03183 } 03184 } 03185 if (flag == 0) likeTerms[e] = 1; 03186 return flag; 03187 } 03188 03189 //found an entry for e 03190 return 1; 03191 } 03192 03193 03194 //! c1\@c2\@...\@cn = c (concatenation of constant bitvectors) 03195 Theorem BitvectorTheoremProducer::concatConst(const Expr& e) { 03196 if(CHECK_PROOFS) { 03197 // The kids must be constant expressions 03198 CHECK_SOUND(e.getOpKind() == CONCAT, 03199 "BitvectorTheoremProducer::concatConst: e = "+e.toString()); 03200 CHECK_SOUND(constantKids(e), 03201 "BitvectorTheoremProducer::concatConst: e = "+e.toString()); 03202 } 03203 vector<bool> res; 03204 for(int i=e.arity()-1; i >= 0; --i) { 03205 for(int bit=0, size=d_theoryBitvector->getBVConstSize(e[i]); bit < size; bit++) 03206 res.push_back(d_theoryBitvector->getBVConstValue(e[i], bit)); 03207 } 03208 Proof pf; 03209 if(withProof()) 03210 pf = newPf("concat_const", e); 03211 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf); 03212 } 03213 03214 03215 //! Flatten one level of nested concatenation, e.g.: x\@(y\@z)\@w = x\@y\@z\@w 03216 Theorem 03217 BitvectorTheoremProducer::concatFlatten(const Expr& e) { 03218 if(CHECK_PROOFS) { 03219 CHECK_SOUND(e.getOpKind() == CONCAT && e.arity() >= 2, 03220 "BitvectorTheoremProducer::concatFlatten: e = "+e.toString()); 03221 } 03222 // Rebuild the expression: copy the kids and flatten the nested CONCATs 03223 vector<Expr> kids; 03224 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) { 03225 if(i->getOpKind() == CONCAT) 03226 kids.insert(kids.end(), i->getKids().begin(), i->getKids().end()); 03227 else 03228 kids.push_back(*i); 03229 } 03230 Proof pf; 03231 if(withProof()) 03232 pf = newPf("concat_flatten", e); 03233 return newRWTheorem(e, Expr(e.getOp(), kids), Assumptions::emptyAssump(), pf); 03234 } 03235 03236 03237 //! Merge n-ary concat. of adjacent extractions: x[15:8]\@x[7:0] = x[15:0] 03238 Theorem 03239 BitvectorTheoremProducer::concatMergeExtract(const Expr& e) { 03240 if(CHECK_PROOFS) { 03241 CHECK_SOUND(e.getOpKind() == CONCAT && e.arity() >= 2, 03242 "BitvectorTheoremProducer::concatMergeExtract: e = " 03243 +e.toString()); 03244 CHECK_SOUND(e[0].getOpKind() == EXTRACT, 03245 "BitvectorTheoremProducer::concatMergeExtract: e = " 03246 +e.toString()); 03247 CHECK_SOUND(d_theoryBitvector->getExtractHi(e[0]) >= d_theoryBitvector->getExtractLow(e[0]), 03248 "BitvectorTheoremProducer::concatMergeExtract: e = " 03249 +e.toString()); 03250 } 03251 03252 const Expr& base = e[0][0]; // The common base of all extractions 03253 03254 if(CHECK_PROOFS) { 03255 // Check that all extractions have the same base and are contiguous 03256 int low = d_theoryBitvector->getExtractLow(e[0]); 03257 for(int i=1, iend=e.arity(); i<iend; ++i) { 03258 const Expr& ei = e[i]; 03259 CHECK_SOUND(ei.getOpKind() == EXTRACT && ei[0] == base, 03260 "BitvectorTheoremProducer::concatMergeExtract: e[" 03261 +int2string(i)+"] = "+ei.toString() 03262 +"\n base = "+base.toString()); 03263 CHECK_SOUND(d_theoryBitvector->getExtractHi(ei) >= d_theoryBitvector->getExtractLow(ei), 03264 "BitvectorTheoremProducer::concatMergeExtract: e[" 03265 +int2string(i)+"] = "+e.toString()); 03266 03267 int newHi = d_theoryBitvector->getExtractHi(ei); 03268 03269 CHECK_SOUND(0 <= newHi && newHi == low-1, 03270 "BitvectorTheoremProducer::concatMergeExtract:\n e[" 03271 +int2string(i-1)+"] = "+e[i-1].toString() 03272 +"\n e["+int2string(i)+"] = "+ei.toString()); 03273 low = d_theoryBitvector->getExtractLow(ei); 03274 } 03275 } 03276 03277 int hi = d_theoryBitvector->getExtractHi(e[0]); 03278 int low = d_theoryBitvector->getExtractLow(e[e.arity()-1]); 03279 Expr res = d_theoryBitvector->newBVExtractExpr(base, hi, low); 03280 03281 Proof pf; 03282 if(withProof()) 03283 pf = newPf("concat_merge_extract", e); 03284 return newRWTheorem(e, res, Assumptions::emptyAssump(), pf); 03285 } 03286 03287 03288 03289 //! BVPLUS(n, c1,c2,...,cn) = c (bit-vector plus of constant bitvectors) 03290 Theorem BitvectorTheoremProducer::bvplusConst(const Expr& e) { 03291 if(CHECK_PROOFS) { 03292 // The kids must be constant expressions 03293 CHECK_SOUND(e.getOpKind() == BVPLUS, 03294 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 03295 CHECK_SOUND(constantKids(e), 03296 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 03297 CHECK_SOUND(d_theoryBitvector->getBVPlusParam(e) > 0, 03298 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 03299 } 03300 // Transfer the values for each bitvector to a Rational, then add it 03301 // to the accumulator. 03302 Rational acc(0); 03303 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) { 03304 Rational x = d_theoryBitvector->computeBVConst(*i); 03305 TRACE("bitvector rewrite", "bvplusConst: x(", *i, ") = "+x.toString()); 03306 acc += x; 03307 TRACE("bitvector rewrite", "bvplusConst: acc = ", acc, ""); 03308 } 03309 // Extract the bits of 'acc' into the vector 03310 int resSize = d_theoryBitvector->getBVPlusParam(e); 03311 vector<bool> res(resSize); 03312 for(int i=0; i<resSize; i++) { 03313 res[i] = (mod(acc, 2) == 1); 03314 TRACE("bitvector rewrite", "bvplusConst: acc = ", acc, ""); 03315 TRACE("bitvector rewrite", "bvplusConst: res["+int2string(i)+"] = ", 03316 res[i], ""); 03317 acc = floor(acc/2); 03318 } 03319 03320 Proof pf; 03321 if(withProof()) 03322 pf = newPf("bvplus_const", e); 03323 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf); 03324 } 03325 03326 03327 /*! @brief c0*c1 = c, multiplication of two BVCONST 03328 */ 03329 Theorem BitvectorTheoremProducer::bvmultConst(const Expr& e) { 03330 if(CHECK_PROOFS) { 03331 // The kids must be constant expressions 03332 CHECK_SOUND(e.getOpKind() == BVMULT, 03333 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 03334 CHECK_SOUND(constantKids(e), 03335 "BitvectorTheoremProducer::extractConst: e = "+e.toString()); 03336 } 03337 Rational c = d_theoryBitvector->computeBVConst(e[0]); 03338 // Do the multiplication 03339 Rational x = d_theoryBitvector->computeBVConst(e[1]) * c; 03340 03341 // Extract the bits of 'x' into the vector 03342 int resSize = d_theoryBitvector->BVSize(e.getType().getExpr()); 03343 vector<bool> res(resSize); 03344 for(int i=0; i<resSize; i++) { 03345 res[i] = (mod(x, 2) == 1); 03346 x = floor(x/2); 03347 } 03348 03349 Proof pf; 03350 if(withProof()) 03351 pf = newPf("bvmult_const", e); 03352 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf); 03353 } 03354 03355 Theorem 03356 BitvectorTheoremProducer::zeroCoeffBVMult(const Expr& e) { 03357 if(CHECK_PROOFS) { 03358 CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2, 03359 "BitvectorTheoremProducer::zeroCoeffBVMult: e = "+e.toString()); 03360 CHECK_SOUND(BVCONST == e[0].getKind(), 03361 "BitvectorTheoremProducer::zeroCoeffBVMult: e = "+e.toString()); 03362 Rational c = d_theoryBitvector->computeBVConst(e[0]); 03363 CHECK_SOUND(0 == c, 03364 "BitvectorTheoremProducer::zeroCoeffBVMult:" 03365 "coeff must be zero:\n e = " +e.toString()); 03366 } 03367 int size = d_theoryBitvector->BVSize(e); 03368 Expr output = d_theoryBitvector->newBVZeroString(size); 03369 03370 Proof pf; 03371 if(withProof()) 03372 pf = newPf("zerocoeff_bvmult", e); 03373 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03374 return result; 03375 } 03376 03377 Theorem 03378 BitvectorTheoremProducer::oneCoeffBVMult(const Expr& e) { 03379 if(CHECK_PROOFS) { 03380 CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2, 03381 "BitvectorTheoremProducer::oneCoeffBVMult: e = " 03382 +e.toString()); 03383 CHECK_SOUND(BVCONST == e[0].getKind(), 03384 "BitvectorTheoremProducer::oneCoeffBVMult: e = " 03385 +e.toString()); 03386 Rational c = d_theoryBitvector->computeBVConst(e[0]); 03387 CHECK_SOUND(1 == c, 03388 "BitvectorTheoremProducer::oneCoeffBVMult:" 03389 "coeff must be one:\n e = " +e.toString()); 03390 } 03391 int size = d_theoryBitvector->BVSize(e); 03392 Expr output = pad(size,e); 03393 03394 Proof pf; 03395 if(withProof()) 03396 pf = newPf("onecoeff_bvmult", e); 03397 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03398 return result; 03399 } 03400 03401 //! t1*a <==> a*t1 03402 Theorem 03403 BitvectorTheoremProducer::flipBVMult(const Expr& e) { 03404 if(CHECK_PROOFS) { 03405 CHECK_SOUND(e.arity()==2 && BVMULT == e.getOpKind(), 03406 "BVMULT must have exactly 2 kids: " + e.toString()); 03407 } 03408 int len = d_theoryBitvector->BVSize(e); 03409 Expr output = d_theoryBitvector->newBVMultExpr(len,e[1],e[0]); 03410 03411 Proof pf; 03412 if(withProof()) 03413 pf = newPf("flip_bvmult", e); 03414 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03415 return result; 03416 } 03417 03418 //! Converts e into a BVVECTOR of bvLength 'len' 03419 /*! 03420 * \param len is the desired bvLength of the resulting bitvector 03421 * \param e is the original bitvector of arbitrary bvLength 03422 */ 03423 Expr 03424 BitvectorTheoremProducer::pad(int len, const Expr& e) { 03425 DebugAssert(len > 0, 03426 "TheoryBitvector::pad:" 03427 "padding bvLength must be a non-negative integer: "+ 03428 int2string(len)); 03429 DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(), 03430 "TheoryBitvector::newBVPlusExpr:" 03431 "input must be a BITVECTOR: " + e.toString()); 03432 03433 int size = d_theoryBitvector->BVSize(e); 03434 Expr res; 03435 if(size == len) 03436 res = e; 03437 else if (len < size) 03438 res = d_theoryBitvector->newBVExtractExpr(e,len-1,0); 03439 else { 03440 // size < len 03441 Expr zero = d_theoryBitvector->newBVZeroString(len-size); 03442 res = d_theoryBitvector->newConcatExpr(zero,e); 03443 } 03444 return res; 03445 } 03446 03447 //! Pad the kids of BVMULT to make their bvLength = # of output-bits 03448 Theorem 03449 BitvectorTheoremProducer::padBVPlus(const Expr& e) { 03450 if(CHECK_PROOFS) { 03451 CHECK_SOUND(BVPLUS == e.getOpKind() && e.arity()>1, 03452 "BitvectorTheoremProducer::padBVPlus: " 03453 "input must be a BVPLUS: " + e.toString()); 03454 } 03455 int len = d_theoryBitvector->BVSize(e); 03456 vector<Expr> kids; 03457 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) { 03458 if(i->getOpKind() == BVMULT) { 03459 Expr e0 = pad(len, (*i)[0]); 03460 Expr e1 = pad(len, (*i)[1]); 03461 Expr out = d_theoryBitvector->newBVMultExpr(len,e0,e1); 03462 kids.push_back(out); 03463 } 03464 else 03465 kids.push_back(pad(len, *i)); 03466 } 03467 03468 Expr output = d_theoryBitvector->newBVPlusExpr(len, kids); 03469 03470 Proof pf; 03471 if(withProof()) 03472 pf = newPf("pad_bvplus", e); 03473 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03474 return result; 03475 } 03476 03477 //! Pad the kids of BVMULT to make their bvLength = # of output-bits 03478 Theorem 03479 BitvectorTheoremProducer::padBVMult(const Expr& e) { 03480 if(CHECK_PROOFS) { 03481 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity()==2, 03482 "BitvectorTheoremProducer::padBVMult: " 03483 "input must be a BVMULT: " + e.toString()); 03484 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() && 03485 BITVECTOR==e[1].getType().getExpr().getOpKind(), 03486 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString()); 03487 } 03488 int len = d_theoryBitvector->BVSize(e); 03489 Expr e0 = pad(len, e[0]); 03490 Expr e1 = pad(len, e[1]); 03491 03492 Expr output = d_theoryBitvector->newBVMultExpr(len,e0,e1); 03493 03494 Proof pf; 03495 if(withProof()) 03496 pf = newPf("pad_bvmult", e); 03497 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03498 return result; 03499 } 03500 03501 //! a*(b*t) <==> (a*b)*t, where a,b,t have same bvLength 03502 Theorem 03503 BitvectorTheoremProducer::bvConstMultAssocRule(const Expr& e) { 03504 if(CHECK_PROOFS) { 03505 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2, 03506 "BitvectorTheoremProducer::bvConstMultAssocRule: " 03507 "input must be a BVMULT: " + e.toString()); 03508 CHECK_SOUND(BVMULT == e[1].getOpKind(), 03509 "BitvectorTheoremProducer::bvConstMultAssocRule: " 03510 "e[1] must be a BVMULT:\n e= " + e.toString()); 03511 CHECK_SOUND(BVCONST == e[0].getKind() && 03512 BVCONST == e[1][0].getKind(), 03513 "BitvectorTheoremProducer::bvConstMultAssocRule: " 03514 "e[0] & e[1][0] must be a BVCONST:\n e = " + e.toString()); 03515 } 03516 int len = d_theoryBitvector->BVSize(e); 03517 int len0 = d_theoryBitvector->BVSize(e[0]); 03518 int len10 = d_theoryBitvector->BVSize(e[1][0]); 03519 int len11 = d_theoryBitvector->BVSize(e[1][1]); 03520 if(CHECK_PROOFS) { 03521 CHECK_SOUND(len == len0 && len0 == len10 && len0 == len11, 03522 "BitvectorTheoremProducer::bvConstMultAssocRule: " 03523 "kids of BVMULT must be equibvLength: "); 03524 } 03525 Rational e0 = d_theoryBitvector->computeBVConst(e[0]); 03526 Rational e10 = d_theoryBitvector->computeBVConst(e[1][0]); 03527 Expr c = d_theoryBitvector->newBVConstExpr(e0*e10, len); 03528 Expr output = d_theoryBitvector->newBVMultExpr(len, c, e[1][1]); 03529 03530 Proof pf; 03531 if(withProof()) 03532 pf = newPf("bvconstmult_assoc_rule", e); 03533 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03534 return result; 03535 } 03536 03537 03538 //FIXME: make BVMULT n-ary 03539 //! (t1*t2)*t3 <==> t1*(t2*t3), where t1<t2<t3 03540 Theorem 03541 BitvectorTheoremProducer::bvMultAssocRule(const Expr& e) { 03542 if(CHECK_PROOFS) { 03543 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2, 03544 "BitvectorTheoremProducer::bvMultAssocRule: " 03545 "input must be a BVMULT: " + e.toString()); 03546 CHECK_SOUND(BVMULT == e[0].getOpKind() || 03547 BVMULT == e[1].getOpKind(), 03548 "BitvectorTheoremProducer::bvMultAssocRule: " 03549 "e[0] or e[1] must be a BVMULT:\n e= " + e.toString()); 03550 CHECK_SOUND(!(BVCONST == e[0].getOpKind() && 03551 BVCONST == e[1][0].getOpKind()), 03552 "BitvectorTheoremProducer::bvMultAssocRule: " 03553 "e[0] & e[1][0] cannot be a BVCONST:\n e = " + 03554 e.toString()); 03555 } 03556 int len = d_theoryBitvector->BVSize(e); 03557 int len0 = d_theoryBitvector->BVSize(e[0]); 03558 int len1 = d_theoryBitvector->BVSize(e[1]); 03559 if(CHECK_PROOFS) 03560 CHECK_SOUND(len == len0 && len0 == len1, 03561 "BitvectorTheoremProducer::bvMultAssocRule: " 03562 "kids of BVMULT must be equibvLength: "); 03563 Expr e0, e1; 03564 e0 = e[0]; 03565 e1 = e[1]; 03566 03567 std::vector<Expr> outputkids; 03568 if(BVMULT == e[0].getOpKind() && BVMULT != e[1].getOpKind()) { 03569 outputkids.push_back(e0[0]); 03570 outputkids.push_back(e0[1]); 03571 outputkids.push_back(e1); 03572 03573 } else if(BVMULT != e[0].getOpKind() && BVMULT == e[1].getOpKind()) { 03574 outputkids.push_back(e1[0]); 03575 outputkids.push_back(e1[1]); 03576 outputkids.push_back(e0); 03577 } else { 03578 //both must be BVMULTs 03579 outputkids.push_back(e0[0]); 03580 outputkids.push_back(e0[1]); 03581 outputkids.push_back(e1[0]); 03582 outputkids.push_back(e1[1]); 03583 } 03584 sort(outputkids.begin(),outputkids.end()); 03585 03586 Expr output; 03587 switch(outputkids.size()) { 03588 case 3: { 03589 Expr out1 = 03590 d_theoryBitvector->newBVMultExpr(len, outputkids[1],outputkids[2]); 03591 output = 03592 d_theoryBitvector->newBVMultExpr(len, outputkids[0], out1); 03593 break; 03594 } 03595 case 4: { 03596 Expr out0 = 03597 d_theoryBitvector->newBVMultExpr(len, outputkids[0], outputkids[1]); 03598 Expr out1 = 03599 d_theoryBitvector->newBVMultExpr(len, outputkids[2], outputkids[3]); 03600 output = 03601 d_theoryBitvector->newBVMultExpr(len, out0, out1); 03602 break; 03603 } 03604 } 03605 03606 Proof pf; 03607 if(withProof()) 03608 pf = newPf("bvmult_assoc_rule", e); 03609 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03610 return result; 03611 } 03612 03613 //! a*(t1+...+tn) <==> (a*t1+...+a*tn), where all kids are equibvLength 03614 Theorem 03615 BitvectorTheoremProducer::bvMultDistRule(const Expr& e) { 03616 if(CHECK_PROOFS) { 03617 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2, 03618 "BitvectorTheoremProducer::bvMultDistRule: " 03619 "input must be a BVMULT: " + e.toString()); 03620 CHECK_SOUND(BVPLUS == e[1].getOpKind(), 03621 "BitvectorTheoremProducer::bvMultDistRule: " 03622 "input must be of the form a*(t1+...+tn): " + e.toString()); 03623 } 03624 int bvLength= d_theoryBitvector->BVSize(e); 03625 int e0len = d_theoryBitvector->BVSize(e[0]); 03626 int e1len = d_theoryBitvector->BVSize(e[1]); 03627 if(CHECK_PROOFS) { 03628 CHECK_SOUND(bvLength== e0len && e0len == e1len, 03629 "BitvectorTheoremProducer::bvMultDistRule: " 03630 "all subterms must of equal bvLength: " + e.toString()); 03631 } 03632 const Expr& e0 = e[0]; 03633 const Expr& e1 = e[1]; 03634 03635 std::vector<Expr> v; 03636 Expr::iterator i = e1.begin(); 03637 Expr::iterator iend = e1.end(); 03638 for(;i != iend; ++i) { 03639 Expr s = d_theoryBitvector->newBVMultExpr(bvLength, e0, *i); 03640 v.push_back(s); 03641 } 03642 Expr output = d_theoryBitvector->newBVPlusExpr(bvLength,v); 03643 03644 Proof pf; 03645 if(withProof()) 03646 pf = newPf("bvmult_distributivity_rule", e); 03647 Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf)); 03648 return result; 03649 } 03650 03651 //! input BVPLUS expression e.output e <==> e', where e' has no BVPLUS 03652 // kids. remember, the invariant is that kids are already in 03653 // bvplus normal-form 03654 Theorem 03655 BitvectorTheoremProducer::flattenBVPlus(const Expr& e) { 03656 if(CHECK_PROOFS) { 03657 CHECK_SOUND(e.getOpKind() == BVPLUS && e.arity() >= 2, 03658 "BitvectorTheoremProducer::flattenBVPlus: e = "+e.toString()); 03659 } 03660 int bvLength= d_theoryBitvector->BVSize(e); 03661 const int numOfKids = e.arity(); 03662 03663 if(CHECK_PROOFS) { 03664 for(int i=0; i<numOfKids; ++i) 03665 CHECK_SOUND(d_theoryBitvector->BVSize(e[i]) == bvLength, 03666 "BitvectorTheoremProducer::flattenBVPlus: " 03667 "summands must be of the same bvLength as BVPLUS:\n e = " 03668 +e.toString()); 03669 } 03670 03671 //collect the kids of e in the vector v. if any kid is a BVPLUS, 03672 //then collect its kids into v. then construct a BVPLUS expr 03673 std::vector<Expr> v; 03674 for(int i = 0; i < numOfKids; ++i) { 03675 if(e[i].getOpKind() == BVPLUS) { 03676 const Expr& bvplusKid = e[i]; 03677 const int bvplusArity = bvplusKid.arity(); 03678 for(int j=0; j < bvplusArity; ++j) 03679 v.push_back(bvplusKid[j]); 03680 } else 03681 v.push_back(e[i]); 03682 } 03683 Expr eprime = d_theoryBitvector->newBVPlusExpr(bvLength, v); 03684 03685 Proof pf; 03686 if(withProof()) 03687 pf = newPf("flatten_bvplus", e); 03688 return newRWTheorem(e, eprime, Assumptions::emptyAssump(), pf); 03689 } 03690 03691 void 03692 BitvectorTheoremProducer::collectOneTermOfPlus(const Rational & coefficient, 03693 const Expr& term, 03694 ExprMap<Rational> & likeTerms, 03695 Rational & plusConstant) 03696 { 03697 ExprMap<Rational>::iterator it = likeTerms.find(term); 03698 03699 if(it!=likeTerms.end()) 03700 likeTerms[term] += coefficient; 03701 else { 03702 // Check if there is a negated form of this term already in likeTerms map. 03703 bool foundNegated= false; 03704 if (!likeTerms.empty()) { 03705 Expr negTerm = d_theoryBitvector->newBVNegExpr(term); 03706 negTerm = d_theoryBitvector->pushNegationRec(term).getRHS(); 03707 it = likeTerms.find(negTerm); 03708 if (it!= likeTerms.end()) { 03709 foundNegated = true; 03710 03711 // Use the rule that ~(c*x) = -c*x-1 (based on the fact: -x= ~x+1). 03712 likeTerms[negTerm] += -coefficient; 03713 plusConstant+= -1; 03714 } 03715 } 03716 if (!foundNegated) 03717 // Negated form was not found, need to register the new positive form. 03718 likeTerms[term] = coefficient; 03719 } 03720 } 03721 03722 void 03723 BitvectorTheoremProducer::collectLikeTermsOfPlus(const Expr& e, 03724 ExprMap<Rational> & likeTerms, 03725 Rational & plusConstant) { 03726 likeTerms.clear(); 03727 Expr::iterator i = e.begin(); 03728 Expr::iterator iend = e.end(); 03729 plusConstant= 0; 03730 //go thru' bvplus term, one monom at a time 03731 for(; i!=iend; ++i) { 03732 const Expr s = *i; 03733 switch(s.getOpKind()) { 03734 case BVMULT: { 03735 //if monom is BVMULT, collect like terms using ExprMap 03736 if (s[0].getKind() == BVCONST) { 03737 Rational coefficient= d_theoryBitvector->computeBVConst(s[0]); 03738 const Expr& var = s[1]; 03739 collectOneTermOfPlus(coefficient, var, likeTerms, plusConstant); 03740 } 03741 else { // non-linear mult 03742 if(CHECK_PROOFS) { 03743 CHECK_SOUND(BVCONST != s[1].getKind(), 03744 "TheoryBitvector::combineLikeTerms: " 03745 "Unexpected MULT syntax:\n\n s = " + s.toString() 03746 +"\n\n in e = "+e.toString()); 03747 } 03748 collectOneTermOfPlus(1, s, likeTerms, plusConstant); 03749 } 03750 break; 03751 } 03752 case BVUMINUS: 03753 collectOneTermOfPlus(-1, s[0], likeTerms, plusConstant); 03754 break; 03755 case BVCONST: 03756 plusConstant += d_theoryBitvector->computeBVConst(s); 03757 break; 03758 default: 03759 //we have just a variable; check if variable in ExprMap 03760 collectOneTermOfPlus(1, s, likeTerms, plusConstant); 03761 break; 03762 } 03763 } 03764 } 03765 03766 static Rational boundedModulo(const Rational & value, const Rational & modulo, 03767 const Rational & lowerBound) { 03768 Rational ret = mod(value, modulo); 03769 if(ret == 0) 03770 return ret; 03771 03772 if (ret< lowerBound) 03773 ret+= modulo; 03774 else { 03775 // end is one position beyond upper limit. 03776 Rational end= modulo+lowerBound; 03777 if (ret >= end) 03778 ret-= modulo; 03779 } 03780 return ret; 03781 } 03782 03783 void 03784 BitvectorTheoremProducer:: 03785 createNewPlusCollection(const Expr & e, 03786 const ExprMap<Rational> & likeTerms, 03787 Rational & plusConstant, 03788 std::vector<Expr> & result) { 03789 int bvplusLength= d_theoryBitvector->BVSize(e); 03790 // Compute 2^n, to use as a modulus base 03791 Rational power2(1); 03792 for(int i=0; i<bvplusLength; i += 1) power2 *= 2; 03793 03794 ExprMap<Rational>::const_iterator j = likeTerms.begin(); 03795 ExprMap<Rational>::const_iterator jend = likeTerms.end(); 03796 for(; j!=jend; ++j) { 03797 // The coefficient will be equivalent to j->second modulus of power2 03798 // and in the range [-power2/2+1, power2/2] 03799 // FIXME: Need to reconsider the "best" coefficient normalization scheme. 03800 Rational coefficient = boundedModulo(j->second, power2, -power2/2+1); 03801 if(coefficient == 0) 03802 continue; 03803 Expr multiplicand = j->first; 03804 Expr monomial; 03805 if (coefficient<0) { 03806 // Make the coefficient positive: c<0 ; 03807 // (c*x)= (-c)*(-x)= (-c)*(~x+1)=(-c)*(~x) -c 03808 multiplicand = d_theoryBitvector->newBVNegExpr(multiplicand); 03809 multiplicand = d_theoryBitvector->pushNegationRec(multiplicand).getRHS(); 03810 coefficient= coefficient*-1; 03811 plusConstant +=coefficient; 03812 } 03813 if(coefficient == 1) 03814 monomial = multiplicand; 03815 else { 03816 Expr coeffExpr = 03817 d_theoryBitvector->newBVConstExpr(coefficient, bvplusLength); 03818 monomial = 03819 d_theoryBitvector->newBVMultExpr(bvplusLength, coeffExpr,multiplicand); 03820 } 03821 if(CHECK_PROOFS) { 03822 CHECK_SOUND(BITVECTOR==monomial.getType().getExpr().getOpKind(), 03823 "TheoryBitvector::combineLikeTerms:" 03824 "each monomial must be a bitvector:\n" 03825 "monomial = " + monomial.toString()); 03826 CHECK_SOUND(bvplusLength == d_theoryBitvector->BVSize(monomial), 03827 "TheoryBitvector::combineLikeTerms:" 03828 "bvLength of each monomial must be the same as e:\n" 03829 "monomial = " + monomial.toString() + "\n e = " + e.toString()); 03830 } 03831 result.push_back(monomial); 03832 } 03833 // Positive modulo of the constant 03834 plusConstant = boundedModulo(plusConstant, power2, 0); 03835 03836 //make the constant a subterm of the BVPLUS expression 03837 if(plusConstant != 0) { 03838 const Expr c = 03839 d_theoryBitvector->newBVConstExpr(plusConstant, bvplusLength); 03840 result.push_back(c); 03841 } 03842 } 03843 03844 Expr 03845 BitvectorTheoremProducer::sumNormalizedElements(int bvplusLength, 03846 const std::vector<Expr>&items){ 03847 //construct a new BVPLUS term using the ExprMap. if size of 03848 //likeTerms is less than 2, then do NOT construct BVPLUS 03849 switch(items.size()) { 03850 case 0: 03851 //items are empty. only constant 0 remains 03852 return d_theoryBitvector->newBVZeroString(bvplusLength); 03853 03854 case 1: 03855 //items may contain a Expr of the form a*x or x or a 03856 return items[0]; 03857 03858 default: 03859 //items have 2 or more kids 03860 return d_theoryBitvector->newBVPlusExpr(bvplusLength, items); 03861 } 03862 } 03863 03864 Theorem 03865 BitvectorTheoremProducer::combineLikeTermsRule(const Expr& e) { 03866 TRACE("bitvector rewrite", "combineLikeTermsRule(",e.toString(), ") {"); 03867 if(CHECK_PROOFS) { 03868 CHECK_SOUND(BVPLUS == e.getOpKind() && e.arity()>=2, 03869 "TheoryBitvector::combineLikeTerms: " 03870 "input must be a BVPLUS term:\n e = " + e.toString()); 03871 int bvplusLength = d_theoryBitvector->BVSize(e); 03872 Expr::iterator i = e.begin(); 03873 Expr::iterator iend = e.end(); 03874 for(;i!=iend;++i) { 03875 const Expr& s = *i; 03876 if(s.getOpKind() == BVPLUS) { 03877 CHECK_SOUND(s.getOpKind() != BVPLUS, 03878 "TheoryBitvector::combineLikeTerms: " 03879 "BVPLUS must be flattened:\n e = " + e.toString()); 03880 } 03881 03882 int bvLength= d_theoryBitvector->BVSize(s); 03883 //bvLength checks for BVCONST and variables 03884 CHECK_SOUND(bvLength==bvplusLength, 03885 "TheoryBitvector::combineLikeTerms: " 03886 "BVPLUS must be padded:\n e = " + e.toString()); 03887 //Length checks for BVMULTs 03888 if(s.getOpKind()==BVMULT) { 03889 int s0len = d_theoryBitvector->BVSize(s[0]); 03890 int s1len = d_theoryBitvector->BVSize(s[1]); 03891 CHECK_SOUND(bvplusLength == s0len && s0len== s1len, 03892 "all monoms must have the samebvLength " 03893 "as the bvplus term: " + e.toString()); 03894 } 03895 } 03896 } 03897 int bvplusLength = d_theoryBitvector->BVSize(e); 03898 ExprMap<Rational> likeTerms; 03899 Rational theConstant(0); 03900 collectLikeTermsOfPlus(e, likeTerms, theConstant); 03901 03902 std::vector<Expr> collection; 03903 createNewPlusCollection(e, likeTerms, theConstant, collection); 03904 03905 Expr output= sumNormalizedElements(bvplusLength, collection); 03906 03907 TRACE("bitvector rewrite", 03908 "combineLikeTermsRule =>",output.toString(), "}"); 03909 Proof pf; 03910 if(withProof()) 03911 pf=newPf("bvplus_combine_like_terms", e); 03912 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 03913 } 03914 03915 Theorem 03916 BitvectorTheoremProducer::lhsMinusRhsRule(const Expr& e) { 03917 if(CHECK_PROOFS) { 03918 CHECK_SOUND(EQ == e.getKind() && e.arity() == 2, 03919 "BitvectorTheoremProducer::lhsMinusRhsRule: " 03920 "input must be an EQ: e = " +e.toString()); 03921 CHECK_SOUND(BVPLUS == e[0].getOpKind() || 03922 BVPLUS == e[1].getOpKind(), 03923 "BitvectorTheoremProducer::lhsMinusRhsRule: " 03924 "atleast one of the input subterms must be BVPLUS:" 03925 "e = " +e.toString()); 03926 int bvLength0 = d_theoryBitvector->BVSize(e[0]); 03927 int bvLength1 = d_theoryBitvector->BVSize(e[1]); 03928 CHECK_SOUND(bvLength0 == bvLength1, 03929 "BitvectorTheoremProducer::lhsMinusRhsRule: " 03930 "both sides of EQ must be same Length. e = " +e.toString()); 03931 for(Expr::iterator i=e[0].begin(),iend=e[0].end();i!=iend;++i) { 03932 int bvLength= d_theoryBitvector->BVSize(*i); 03933 CHECK_SOUND(bvLength0 == bvLength, 03934 "BitvectorTheoremProducer::lhsMinusRhsRule: " 03935 "all subterms of e[0] must be of same Length." 03936 "e = " +e.toString()); 03937 } 03938 for(Expr::iterator i=e[1].begin(),iend=e[1].end();i!=iend;++i) { 03939 int bvLength= d_theoryBitvector->BVSize(*i); 03940 CHECK_SOUND(bvLength1 == bvLength, 03941 "BitvectorTheoremProducer::lhsMinusRhsRule: " 03942 "all subterms of e[1] must be of same Length." 03943 "e = " +e.toString()); 03944 } 03945 } 03946 Expr output; 03947 int bvLength = d_theoryBitvector->BVSize(e[0]); 03948 std::vector<Expr> k; 03949 03950 //construct 0 of bvLength 03951 Expr zeroStr = d_theoryBitvector->newBVZeroString(bvLength); 03952 03953 if(e[0] == e[1]) 03954 output = Expr(EQ, zeroStr, zeroStr); 03955 else { 03956 //drop common subterms 03957 std::vector<Expr> e0K = e[0].getKids(); 03958 std::vector<Expr> e1K = e[1].getKids(); 03959 for(vector<Expr>::iterator i=e0K.begin(),iend=e0K.end();i!=iend;++i){ 03960 for(vector<Expr>::iterator j=e1K.begin(),jend=e1K.end();j!=jend;++j){ 03961 if(*i == *j) { 03962 e0K.erase(i); 03963 e1K.erase(j); 03964 break; 03965 } 03966 } 03967 } 03968 Expr newLhs = d_theoryBitvector->newBVPlusExpr(bvLength, e0K); 03969 k.push_back(newLhs); 03970 Expr newRhs = d_theoryBitvector->newBVPlusExpr(bvLength, e1K); 03971 //construct -rhs 03972 Expr uminus = d_theoryBitvector->newBVUminusExpr(newRhs); 03973 //push back -rhs 03974 k.push_back(uminus); 03975 //construct lhs-rhs 03976 Expr lhsMinusRhs = d_theoryBitvector->newBVPlusExpr(bvLength,k); 03977 //construct lhs-rhs=0 03978 output = Expr(EQ, lhsMinusRhs, zeroStr); 03979 } 03980 03981 Proof pf; 03982 if(withProof()) 03983 pf = newPf("lhs_minus_rhs_rule", e); 03984 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 03985 } 03986 03987 //! generic rule used for bitblasting step. -e <==> ~e+1 03988 Theorem 03989 BitvectorTheoremProducer::bvuminusToBVPlus(const Expr& e) { 03990 if(CHECK_PROOFS) { 03991 CHECK_SOUND(BVUMINUS == e.getOpKind(), 03992 "BitvectorTheoremProducer::bvuminusBitBlastRule: " 03993 "input must be bvuminus: e = " + e.toString()); 03994 } 03995 int bvLength = d_theoryBitvector->BVSize(e); 03996 std::vector<Expr> k; 03997 Expr negE0 = d_theoryBitvector->newBVNegExpr(e[0]); 03998 k.push_back(negE0); 03999 Expr plusOne = d_theoryBitvector->newBVConstExpr(1, bvLength); 04000 k.push_back(plusOne); 04001 04002 Expr output = d_theoryBitvector->newBVPlusExpr(bvLength, k); 04003 Proof pf; 04004 if(withProof()) 04005 pf = newPf("bvuminus_bitblast_rule", e); 04006 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04007 } 04008 04009 //! -0 <==> 0, -c <==> ~c+1 04010 Theorem 04011 BitvectorTheoremProducer::bvuminusBVConst(const Expr& e) { 04012 if(CHECK_PROOFS) { 04013 CHECK_SOUND(BVUMINUS == e.getOpKind() && 04014 BVCONST == e[0].getKind(), 04015 "BitvectorTheoremProducer::bvuminusBVConst: " 04016 "e should be bvuminus, e[0] should be bvconst: e = " + 04017 e.toString()); 04018 } 04019 Expr output; 04020 int e0Length = d_theoryBitvector->BVSize(e[0]); 04021 // output == 0 04022 if(d_theoryBitvector->computeBVConst(e[0]) == 0) 04023 output = e[0]; 04024 else { 04025 // Compute -c, which is ~c+1 04026 Rational x = d_theoryBitvector->computeNegBVConst(e[0]); 04027 output = d_theoryBitvector->newBVConstExpr(x, e0Length); 04028 } 04029 04030 Proof pf; 04031 if(withProof()) 04032 pf = newPf("bvuminus_bvconst_rule", e); 04033 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04034 } 04035 04036 //! -(c*t)<=>(-c)*t; if -c==0 return e<=>0. if(-c==1) return e<=>t 04037 Theorem 04038 BitvectorTheoremProducer::bvuminusBVMult(const Expr& e) { 04039 if(CHECK_PROOFS) { 04040 CHECK_SOUND(BVUMINUS == e.getOpKind(), 04041 "BitvectorTheoremProducer::bvuminusBVMult: " 04042 "e should be bvuminus: e =" + e.toString()); 04043 CHECK_SOUND(BVMULT == e[0].getOpKind(), 04044 "Bitvectortheoremproducer::bvuminusBVMult: " 04045 "in input expression e = " + e.toString() + 04046 "\ne[0] should be bvmult: e[0] = " + e[0].toString()); 04047 CHECK_SOUND(BVCONST == e[0][0].getKind(), 04048 "Bitvectortheoremproducer::bvuminusBVMult: " 04049 "in input expression e = " + e.toString() + 04050 "\ne[0][0] should be bvconst: e[0][0] = " + e[0][0].toString()); 04051 int bvLength = d_theoryBitvector->BVSize(e); 04052 int e0Length = d_theoryBitvector->BVSize(e[0]); 04053 int e00Length = d_theoryBitvector->BVSize(e[0][0]); 04054 CHECK_SOUND(bvLength == e0Length && e0Length == e00Length, 04055 "Bitvectortheoremproducer::bvuminusBVMult: " 04056 "in input expression e = " + e.toString() + 04057 "\nLengths of all subexprs must be equal: e = " + e.toString()); 04058 } 04059 //e is of the form -(c*t) 04060 Expr output; 04061 int e0Length = d_theoryBitvector->BVSize(e[0]); 04062 //compute ~c+1 04063 Rational coeff = d_theoryBitvector->computeNegBVConst(e[0][0]); 04064 if(0 == coeff) 04065 //if ~c+1 == 0 04066 output = d_theoryBitvector->newBVZeroString(e0Length); 04067 else if (1 == coeff) 04068 //if ~c+1 == 1 04069 output = e[0][1]; 04070 else { 04071 //construct (~c+1)*t 04072 Expr newcoeff = d_theoryBitvector->newBVConstExpr(coeff, e0Length); 04073 output = d_theoryBitvector->newBVMultExpr(e0Length, newcoeff, e[0][1]); 04074 } 04075 04076 Proof pf; 04077 if(withProof()) 04078 pf = newPf("bvuminus_bvmult_rule", e); 04079 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04080 } 04081 04082 //! -(-e) <==> e 04083 Theorem 04084 BitvectorTheoremProducer::bvuminusBVUminus(const Expr& e) { 04085 if(CHECK_PROOFS) { 04086 CHECK_SOUND(BVUMINUS == e.getOpKind(), 04087 "BitvectorTheoremProducer::bvuminusBVUminus: " 04088 "e should be bvuminus: e =" + e.toString()); 04089 CHECK_SOUND(BVUMINUS == e[0].getOpKind(), 04090 "Bitvectortheoremproducer::bvuminusBVUminus: " 04091 "in input expression e = " + e.toString() + 04092 "\ne[0] should be bvmult: e[0] = " + e[0].toString()); 04093 } 04094 Expr output; 04095 // -(-e) <==> e 04096 output = e[0][0]; 04097 Proof pf; 04098 if(withProof()) 04099 pf = newPf("bvuminus_bvuminus_rule", e); 04100 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04101 } 04102 04103 //! -v <==> -1*v 04104 Theorem 04105 BitvectorTheoremProducer::bvuminusVar(const Expr& e) { 04106 if(CHECK_PROOFS) { 04107 CHECK_SOUND(BVUMINUS == e.getOpKind(), 04108 "BitvectorTheoremProducer::bvuminusVar: " 04109 "e should be bvuminus: e =" + e.toString()); 04110 } 04111 Expr output; 04112 std::vector<bool> res; 04113 int e0Length = d_theoryBitvector->BVSize(e[0]); 04114 for(int i=0; i<e0Length; ++i) { 04115 res.push_back(true); 04116 } 04117 Expr coeff = d_theoryBitvector->newBVConstExpr(res); 04118 output = d_theoryBitvector->newBVMultExpr(e0Length, coeff, e[0]); 04119 04120 Proof pf; 04121 if(withProof()) 04122 pf = newPf("bvuminus_var_rule", e); 04123 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04124 } 04125 04126 //! c*(-t) <==> (-c)*t 04127 Theorem 04128 BitvectorTheoremProducer::bvmultBVUminus(const Expr& e) { 04129 if(CHECK_PROOFS) { 04130 CHECK_SOUND(BVUMINUS == e.getOpKind(), 04131 "BitvectorTheoremProducer::bvmultBVUminus: " 04132 "e should be bvuminus: e =" + e.toString()); 04133 CHECK_SOUND(BVMULT == e[0].getOpKind() && 04134 BVCONST == e[0][0].getKind() && 04135 BVUMINUS == e[0][1].getOpKind(), 04136 "Bitvectortheoremproducer::bvmultBVUminus: " 04137 "in input expression e = " + e.toString() + 04138 "\ne[0] has to be bvmult" 04139 "e[0][1] must be bvuminus: e[0] = " + e[0].toString()); 04140 int bvLength = d_theoryBitvector->BVSize(e); 04141 int e00Length = d_theoryBitvector->BVSize(e[0][0]); 04142 int e01Length = d_theoryBitvector->BVSize(e[0][1]); 04143 CHECK_SOUND(bvLength == e00Length && e00Length == e01Length, 04144 "Bitvectortheoremproducer::bvmultBVUminus: " 04145 "in input expression e = " + e.toString() + 04146 "\nLengths of all subexprs must be equal."); 04147 } 04148 Expr output; 04149 int bvLength = d_theoryBitvector->BVSize(e); 04150 const Expr& coeff = e[0][0]; 04151 Rational negatedcoeff = d_theoryBitvector->computeNegBVConst(coeff); 04152 const Expr& e010 = e[0][1][0]; 04153 04154 if(0 == negatedcoeff) 04155 //if ~c+1 == 0 04156 output = d_theoryBitvector->newBVZeroString(bvLength); 04157 else if (1 == negatedcoeff) 04158 //if ~c+1 == 1 04159 output = e010; 04160 else { 04161 //construct (~c+1)*t 04162 Expr newcoeff = d_theoryBitvector->newBVConstExpr(negatedcoeff, bvLength); 04163 output = d_theoryBitvector->newBVMultExpr(bvLength, newcoeff, e010); 04164 } 04165 04166 Proof pf; 04167 if(withProof()) 04168 pf = newPf("bvmult_bvuminus_rule", e); 04169 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04170 } 04171 04172 //! -(c1*t1+...+cn*tn) <==> (-(c1*t1)+...+-(cn*tn)) 04173 Theorem 04174 BitvectorTheoremProducer::bvuminusBVPlus(const Expr& e) { 04175 // if(CHECK_PROOFS) { 04176 // CHECK_SOUND(BVUMINUS == e.getOpKind(), 04177 // "BitvectorTheoremProducer::bvuminusBVPlus: " 04178 // "e should be bvuminus: e =" + e.toString()); 04179 // CHECK_SOUND(BVPLUS == e[0].getOpKind(), 04180 // "BitvectorTheoremProducer::bvuminusBVPlus: " 04181 // "e[0] should be bvplus: e[0] =" + e[0].toString()); 04182 // } 04183 // int bvLength = d_theoryBitvector->BVSize(e); 04184 // const Expr& e0 = e[0]; 04185 // Expr::iterator i = e0.begin(); 04186 // Expr::iterator iend = e0.end(); 04187 // std::vector<Expr> output; 04188 // for(; i!=iend; ++i) { 04189 // const Expr& s = *i; 04190 // Expr t = d_theoryBitvector->newBVUminusExpr(s); 04191 // output.push_back(t); 04192 // } 04193 // Expr outputPlus = 04194 // d_theoryBitvector->newBVPlusExpr(bvLength, output); 04195 04196 // Assumptions a; 04197 // Proof pf; 04198 // if(withProof()) 04199 // pf = newPf("bvminus_bvplus_rule", e); 04200 // return newRWTheorem(e, outputPlus, a, pf); 04201 04202 Proof pf; 04203 if(withProof()) 04204 pf = newPf("bvminus_bvplus_rule", e); 04205 return newRWTheorem(e, e, Assumptions::emptyAssump(), pf); 04206 } 04207 04208 Theorem 04209 BitvectorTheoremProducer::extractBVMult(const Expr& e) { 04210 if(CHECK_PROOFS) { 04211 CHECK_SOUND(e.getOpKind() == EXTRACT && 04212 e[0].getOpKind() == BVMULT && 04213 e[0].arity() == 2, 04214 "BitvectorTheoremProducer::extractBVMult: " 04215 "input must be an EXTRACT over BVMULT:\n e = "+e.toString()); 04216 } 04217 const Expr& bvmult = e[0]; 04218 int bvmultLen = d_theoryBitvector->BVSize(bvmult); 04219 int extractHi = d_theoryBitvector->getExtractHi(e); 04220 int extractLow = d_theoryBitvector->getExtractLow(e); 04221 04222 if(CHECK_PROOFS) { 04223 CHECK_SOUND(bvmultLen > extractHi, 04224 "BitvectorTheoremProducer::extractBVMult: " 04225 "bvmult Length must be greater than extract Length:\n e = " 04226 +e.toString()); 04227 } 04228 04229 Expr output = d_theoryBitvector->newBVMultPadExpr(extractHi+1, bvmult[0], 04230 bvmult[1]); 04231 if(extractLow > 0) 04232 output=d_theoryBitvector->newBVExtractExpr(output, extractHi, extractLow); 04233 04234 Proof pf; 04235 if(withProof()) 04236 pf = newPf("extract_bvmult_rule", e); 04237 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04238 } 04239 04240 Theorem 04241 BitvectorTheoremProducer::extractBVPlus(const Expr& e) { 04242 if(CHECK_PROOFS) { 04243 CHECK_SOUND(e.getOpKind() == EXTRACT && e[0].getOpKind() == BVPLUS, 04244 "BitvectorTheoremProducer::extractBVPlus: " 04245 "input must be an EXTRACT over BVPLUS:\n e = "+e.toString()); 04246 } 04247 const Expr& bvplus = e[0]; 04248 int bvplusLen = d_theoryBitvector->BVSize(bvplus); 04249 int extractHi = d_theoryBitvector->getExtractHi(e); 04250 int extractLow = d_theoryBitvector->getExtractLow(e); 04251 04252 if(CHECK_PROOFS) { 04253 CHECK_SOUND(bvplusLen > extractHi, 04254 "BitvectorTheoremProducer::extractBVPlus: " 04255 "bvplus Length must be greater than extract bvLength:\n e = " 04256 +e.toString()); 04257 } 04258 04259 // Shortcut 04260 if(bvplusLen == extractHi+1) 04261 return d_theoryBitvector->reflexivityRule(e); 04262 04263 // Shorten the result width of the bvplus term 04264 Expr output(d_theoryBitvector->newBVPlusPadExpr(extractHi+1, bvplus.getKids())); 04265 if(extractLow > 0) 04266 output=d_theoryBitvector->newBVExtractExpr(output, extractHi, extractLow); 04267 04268 Proof pf; 04269 if(withProof()) 04270 pf = newPf("extract_bvplus_rule", e); 04271 return newRWTheorem(e, output, Assumptions::emptyAssump(), pf); 04272 } 04273 04274 04275 // |- t=0 OR t=1 for any 1-bit bitvector t 04276 Theorem 04277 BitvectorTheoremProducer::typePredBit(const Expr& e) { 04278 if(CHECK_PROOFS) { 04279 CHECK_SOUND(d_theoryBitvector->getBaseType(e).getExpr().getOpKind() == BITVECTOR, 04280 "BitvectorTheoremProducer::typePredBit: e = "+e.toString()); 04281 CHECK_SOUND(d_theoryBitvector->BVSize(e) == 1, 04282 "BitvectorTheoremProducer::typePredBit: e = "+e.toString()); 04283 } 04284 04285 Proof pf; 04286 if(withProof()) 04287 pf=newPf("type_pred_bit", e); 04288 return newTheorem(e.eqExpr(bvZero()) || e.eqExpr(bvOne()), Assumptions::emptyAssump(), pf); 04289 } 04290 04291 04292 //! Expand the type predicate wrapper (compute the actual type predicate) 04293 Theorem 04294 BitvectorTheoremProducer::expandTypePred(const Theorem& tp) { 04295 Expr tpExpr = tp.getExpr(); 04296 if(CHECK_PROOFS) { 04297 CHECK_SOUND(tpExpr.getOpKind() == BVTYPEPRED || 04298 (tpExpr.getKind() == NOT && tpExpr[0].getOpKind() == BVTYPEPRED), 04299 "BitvectorTheoremProducer::expandTypePred: " 04300 "Expected BV_TYPE_PRED wrapper:\n tp = " 04301 +tpExpr.toString()); 04302 } 04303 Expr res; 04304 if(tpExpr.getKind() == NOT) 04305 res = d_theoryBitvector->falseExpr(); 04306 else { 04307 Type t(d_theoryBitvector->getTypePredType(tpExpr)); 04308 const Expr& e(d_theoryBitvector->getTypePredExpr(tpExpr)); 04309 int size(d_theoryBitvector->getBitvectorTypeParam(t)); 04310 // DebugAssert(BVSize(e)==size, "TheoryBitvector::computeTypePred: e=" 04311 // +e.toString()+", t="+t.toString()); 04312 if(size >= 2) { 04313 vector<Expr> kids; 04314 for(int i=0; i<size; i++) { 04315 Expr bit(d_theoryBitvector->newBVExtractExpr(e, i, i)); 04316 kids.push_back(bit.eqExpr(bvZero()) || bit.eqExpr(bvOne())); 04317 } 04318 res = andExpr(kids); 04319 } else { 04320 res = (e.eqExpr(bvZero()) || e.eqExpr(bvOne())); 04321 } 04322 } 04323 Proof pf; 04324 if(withProof()) 04325 pf = newPf("expand_type_pred", tp.getExpr(), tp.getProof()); 04326 04327 return newTheorem(res, tp.getAssumptionsRef(), pf); 04328 } 04329 04330 /*Beginning of Lorenzo PLatania's methods*/ 04331 04332 // Theorem BitvectorTheoremProducer::multiply_coeff( Rational mult_inv, const Expr& e) 04333 // { 04334 04335 // Expr rhs= d_theoryBitvector->multiply_coeff( mult_inv, e); 04336 // Proof pf= newPf("multiply both sides for a constant"); 04337 // return newRWTheorem( e, rhs, Assumptions::emptyAssump(), pf); 04338 // } 04339 04340 04341 // rewrites the equation in the form 0 = Expr 04342 // this is needed for TheoryBitvector::solve 04343 Theorem BitvectorTheoremProducer::MarkNonSolvableEq( const Expr& e) 04344 { 04345 04346 int bv_size = d_theoryBitvector->BVSize(e[0]); 04347 Expr bv_zero( d_theoryBitvector->newBVZeroString(bv_size)); 04348 04349 if (CHECK_PROOFS) 04350 CHECK_SOUND( e.isEq() && 04351 ( e[0] == bv_zero || e[1] == bv_zero ), 04352 "MarkNonSolvableEq: input must be a canonized equation" + e.toString()); 04353 if( e[1] == bv_zero ) 04354 { 04355 Expr expr_res= Expr(EQ, e[1], e[0]); 04356 Proof pf= newPf("mark non solvable eq"); 04357 Theorem th_res= newRWTheorem( e, expr_res, Assumptions::emptyAssump(), pf); 04358 return th_res; 04359 } 04360 else 04361 { 04362 return d_theoryBitvector->reflexivityRule(e); 04363 } 04364 04365 04366 } 04367 04368 // Given an expression t = 0, isolate a single leaf on the lhs if possible, 04369 // returning t = 0 <=> leaf = rest. 04370 // Otherwise, return e <=> e 04371 Theorem BitvectorTheoremProducer::isolate_var(const Expr& e) 04372 { 04373 int bv_size = d_theoryBitvector->BVSize(e[0]); 04374 Expr bv_zero(d_theoryBitvector->newBVZeroString(bv_size)); 04375 04376 if (CHECK_PROOFS) { 04377 CHECK_SOUND(e.isEq() && e[1] == bv_zero && e[0].getOpKind() != BVCONST, 04378 "isolate_var: input must be an equation with lhs non-cosnt and rhs must be zero" + e.toString()); 04379 } 04380 04381 // cout<<"BitvectorTheoremProducer::isolate_var: "<<e.toString()<<endl; 04382 04383 Rational modulus = pow(Rational(bv_size), Rational(2)); 04384 Expr res_expr; 04385 Expr lhs = e[0]; 04386 04387 switch (lhs.getOpKind()) { 04388 case BVMULT: 04389 // linear BVMULT term 04390 if( lhs[0].getOpKind() == BVCONST ) 04391 { 04392 DebugAssert(lhs[1].getOpKind() != BVCONST && 04393 lhs[1].getOpKind() != BVPLUS, "Should have been canonized"); 04394 DebugAssert(d_theoryBitvector->computeBVConst(lhs[0]) % 2 == 0, 04395 "Expected even coeff"); 04396 } 04397 res_expr = e; 04398 break; 04399 case BVPLUS: 04400 { 04401 int e_kid_arity = lhs.arity(); 04402 bool foundUnitCoeff = false; 04403 Expr new_lhs, new_rhs, new_coeff; 04404 vector<Expr> newKids; 04405 Rational tmp, const_term = 0; 04406 for( int i = 0; i < e_kid_arity; ++i) 04407 { 04408 // it can be a BVMULT, a var, or a const 04409 Expr e_sub_kid = lhs[i]; 04410 switch (e_sub_kid.getOpKind()) { 04411 case BVCONST: 04412 DebugAssert(const_term == 0, "Expected only one constant"); 04413 const_term = ((modulus-1) * d_theoryBitvector->computeBVConst(e_sub_kid)) % modulus; 04414 newKids.push_back(d_theoryBitvector->newBVConstExpr(const_term, bv_size)); 04415 break; 04416 case BVMULT: 04417 if( e_sub_kid[0].getOpKind() == BVCONST ) 04418 { 04419 DebugAssert(e_sub_kid.arity() == 2, "Expected arity 2 BVMULT"); 04420 tmp = d_theoryBitvector->computeBVConst(e_sub_kid[0]); 04421 DebugAssert(tmp != 1, "Expected coeff other than 1"); 04422 tmp = (tmp * (modulus-1)) % modulus; 04423 new_coeff = d_theoryBitvector->newBVConstExpr(tmp, bv_size); 04424 newKids.push_back(d_theoryBitvector->newBVMultExpr(bv_size, new_coeff, e_sub_kid[1])); 04425 } 04426 else { 04427 new_coeff = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size); 04428 newKids.push_back(d_theoryBitvector->newBVMultExpr(bv_size, new_coeff, e_sub_kid)); 04429 } 04430 break; 04431 default: 04432 if (!foundUnitCoeff) { 04433 foundUnitCoeff = true; 04434 new_lhs = e_sub_kid; 04435 } 04436 else { 04437 new_coeff = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size); 04438 newKids.push_back(d_theoryBitvector->newBVMultExpr(bv_size, new_coeff, e_sub_kid)); 04439 } 04440 break; 04441 } 04442 } 04443 if (foundUnitCoeff) { 04444 DebugAssert(newKids.size() > 0, "Expected non-empty kids"); 04445 Expr new_rhs; 04446 if (newKids.size() == 1) { 04447 new_rhs = newKids[0]; 04448 } 04449 else { 04450 new_rhs = d_theoryBitvector->newBVPlusExpr(bv_size, newKids); 04451 } 04452 res_expr = Expr(EQ, new_lhs, new_rhs); 04453 } 04454 else { 04455 res_expr = e; 04456 } 04457 break; 04458 } 04459 default: 04460 res_expr = e; 04461 break; 04462 } 04463 Proof pf= newPf("isolate var"); 04464 // cout<<"TheoryBitvector::isolate_var: result is: " <<res_expr.toString()<<endl; 04465 04466 DebugAssert(e == res_expr || (res_expr.isEq() && d_theoryBitvector->isLeaf(res_expr[0]) && 04467 !d_theoryBitvector->isLeafIn(res_expr[0], res_expr[1])), 04468 "Expected no change or solved form"); 04469 04470 return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf); 04471 } 04472 04473 04474 // Theorem BitvectorTheoremProducer::isolate_var( const Theorem& t, const Expr& e) 04475 // { 04476 // int bv_size = d_theoryBitvector->BVSize(e[0]); 04477 // Expr bv_zero( d_theoryBitvector->newBVZeroString(bv_size)); 04478 // Expr BV_one = d_theoryBitvector->newBVConstExpr(1,bv_size); 04479 04480 // if (CHECK_PROOFS) 04481 // // the RHS assumptio has to be removed 04482 // CHECK_SOUND( e.isEq() && 04483 // ( e[0] == bv_zero || e[1] == bv_zero ), 04484 // "isolate_var: input must be an equation and one of the kids must be a zero" + e.toString()); 04485 04486 // cout<<"BitvectorTheoremProducer::isolate_var: "<<e.toString()<<endl; 04487 04488 // Expr new_rhs; 04489 // Expr lhs; 04490 // Expr new_lhs; 04491 // // Expr rhs; 04492 // lhs = e[0]; 04493 04494 // int lhs_arity = lhs.arity(); 04495 04496 // int found = 0; 04497 // int index, solve_pos; 04498 04499 // // add the case for a*x = 0 04500 04501 // // equation of just one variable, like x= c, nothing to be done 04502 // if( lhs.isVar()) 04503 // { 04504 // Proof pf= newPf("isolate var"); 04505 // return newRWTheorem( t.getExpr(), e, Assumptions::emptyAssump(), pf); 04506 // } 04507 // else 04508 // { 04509 // // look for a variable we can solve for 04510 // for( index=0; index < lhs_arity; ++index) 04511 // { 04512 // // if( lhs[index].getOpKind() == BVMULT ) 04513 // // { 04514 // // if( lhs[index][0] == BV_one) 04515 // cout<<"BitvectorTheoremProducer::isolate_var, lhs[index]: "<<lhs[index]<<endl; 04516 // if( d_theoryBitvector->canSolveFor( lhs[index], e)) 04517 // // if( d_theoryBitvector->isLeaf( lhs[index]) || (lhs[index].getOpKind() == BVMULT && lhs[index][0].isVar() && lhs[index][0].isVar()) ) 04518 // { 04519 // found = 1; 04520 // solve_pos = index; 04521 // break; 04522 // } 04523 // } 04524 // // else 04525 // // if( lhs[index].getOpKind() == BVCONST ) 04526 // // rhs = lhs[index]; 04527 04528 // } 04529 // DebugAssert(found, 04530 // "BitvectorTheoremProducer::isolate_var: No variable with unary coefficient found"); 04531 04532 // // L:: Index says which variable we are solving the equation for. 04533 // // for all other variables we have to invert the sign of the 04534 // // coefficient and put them in the rhs with the known term 04535 04536 // cout<<"we solve for the var in position "<<solve_pos<<endl; 04537 // //L:: x= sum(list) 04538 // std::vector<Expr> new_rhs_list; 04539 // Rational known_term = 0; 04540 // int scan; 04541 // for( scan = 0; scan < lhs_arity; ++scan) 04542 // { 04543 // if( scan != solve_pos ) 04544 // { 04545 // // I think the first case is useless 04546 // // the operand of the sum is just a var, but different from 04547 // // the one we choose to solve the equation 04548 // // if( lhs[scan].isVar()) 04549 // // { 04550 // // new_rhs_list.push_back( d_theoryBitvector->newBVUminusExpr( lhs[scan]) ); 04551 // // } 04552 // // else 04553 // // we add the constant to the known term 04554 // if( lhs[scan].getOpKind() == BVCONST ) 04555 // { 04556 // Rational tmp = d_theoryBitvector->computeNegBVConst( lhs[scan]); 04557 // Expr bv_tmp = d_theoryBitvector->signed_newBVConstExpr( tmp, bv_size ); 04558 // new_rhs_list.push_back ( bv_tmp); 04559 // cout<<"input constant: "<<lhs[scan].toString()<<" rational constant: "<<tmp<<" bv constant: "<<bv_tmp<<endl; 04560 // } 04561 // else 04562 04563 // // the operand is a variable multiplied by a constant 04564 // if( lhs[scan].getOpKind() == BVMULT ) 04565 // { 04566 // if( lhs[scan][0].getOpKind() == BVCONST ) 04567 // { 04568 // Rational new_coeff = d_theoryBitvector->computeNegBVConst( lhs[scan][0] ); 04569 // Expr bv_new_coeff = d_theoryBitvector->signed_newBVConstExpr( new_coeff, bv_size ); 04570 // if( bv_new_coeff == BV_one) 04571 // new_rhs_list.push_back( lhs[scan][1]); 04572 // else 04573 // { 04574 // Expr bv_new_expr = d_theoryBitvector->newBVMultExpr( bv_size, bv_new_coeff, lhs[scan][1]); 04575 // new_rhs_list.push_back( bv_new_expr ); 04576 // } 04577 // } 04578 // else 04579 // { 04580 // new_rhs_list.push_back( d_theoryBitvector->newBVUminusExpr( lhs[scan] ) ); 04581 // } 04582 // } 04583 // else 04584 // if( d_theoryBitvector->isLeaf( lhs[scan] ) ) 04585 // new_rhs_list.push_back( lhs[scan] ); 04586 // else 04587 // DebugAssert(0, 04588 // "BitvectorTheoremProducer::isolate_var: subterm of non implemented kind"); 04589 04590 // } 04591 // } 04592 // for(unsigned int i=0; i < new_rhs_list.size(); i++) 04593 // cout<<"new_rhs_list["<<i<<"]: "<<new_rhs_list[i]<<endl; 04594 // if( new_rhs_list.size() > 1) 04595 // new_rhs = d_theoryBitvector->newBVPlusExpr( bv_size, new_rhs_list); 04596 // else 04597 // new_rhs = new_rhs_list[0]; 04598 04599 // Expr expr_res; 04600 04601 // // if( lhs[index] >= new_rhs) 04602 // // expr_res= Expr(EQ, lhs[index], new_rhs); 04603 // // else 04604 // // expr_res= Expr(EQ, new_rhs, lhs[index]); 04605 04606 // // L:: fix according to the new form for variables 04607 // new_lhs = lhs[solve_pos]; 04608 // expr_res= Expr(EQ, new_lhs, new_rhs); 04609 // Proof pf= newPf("isolate var"); 04610 // Theorem th_res= newRWTheorem( e, expr_res, Assumptions::emptyAssump(), pf); 04611 // cout<<"TheoryBitvector::isolate_var: result is: "<<expr_res.toString()<<endl; 04612 04613 04614 // return newRWTheorem( t.getExpr(), expr_res, Assumptions::emptyAssump(), pf); 04615 // //return d_theoryBitvector->iffMP( e, expr_res); 04616 // } 04617 04618 04619 Theorem BitvectorTheoremProducer::BVMult_order_subterms( const Expr& e ) 04620 { 04621 if (CHECK_PROOFS) 04622 CHECK_SOUND(e.getOpKind() == BVMULT, 04623 "BitvectorTheoremProducer::BVMult_order_vars: input must be a BVMULT expression" + e.toString()); 04624 04625 // cout<<"BitvectorTheoremProducer::BVMult_order_subterms, e: "<<e.toString()<<endl; 04626 int bv_size= d_theoryBitvector->BVSize(e); 04627 Expr new_expr; 04628 vector<Expr> vars; 04629 04630 // as the term has already been processed by BVcanon, a constant can 04631 // be just at the beginning of the term 04632 bool hasConst = false; 04633 if (e[0].getOpKind() == BVCONST) { 04634 d_theoryBitvector->extract_vars(e[1], vars); 04635 hasConst = true; 04636 } 04637 else { 04638 d_theoryBitvector->extract_vars(e, vars); 04639 } 04640 04641 int vars_size = vars.size(); 04642 ExprMap<int> vars_map; 04643 04644 for( int i=0; i < vars_size; ++i) 04645 { 04646 // cout<<"vars["<<i<<"]: "<<vars[i].toString()<<endl; 04647 // L:: we count how many times we found a variable 04648 if( vars_map.count( vars[i] ) == 0) 04649 vars_map[ vars[i] ] = 1; 04650 else 04651 vars_map[ vars[i] ] = vars_map[ vars[i] ] + 1; 04652 } 04653 // retrieving the variables from the map; the order of the variables 04654 // is like BVMULT(size, a, BVMULT(size, b, ...)) todo:: be careful 04655 // about the order in which variables are retrieved 04656 ExprMap<int>::iterator j = vars_map.begin(); 04657 new_expr = (*j).first; 04658 if ((*j).second != 1) { 04659 for(int k=1; k < (*j).second; ++k) { 04660 new_expr = d_theoryBitvector->newBVMultExpr( bv_size, (*j).first, new_expr); 04661 } 04662 } 04663 04664 for( ++j; j != vars_map.end(); ++j) { 04665 new_expr = d_theoryBitvector->newBVMultExpr( bv_size, (*j).first, new_expr); 04666 if ((*j).second != 1) { 04667 for(int k=1; k < (*j).second; ++k) { 04668 new_expr = d_theoryBitvector->newBVMultExpr( bv_size, (*j).first, new_expr); 04669 } 04670 } 04671 } 04672 04673 Proof pf; 04674 if (withProof()) pf = newPf("BVMult_order_subterms"); 04675 04676 if (hasConst) { 04677 new_expr = d_theoryBitvector->newBVMultExpr( bv_size, e[0], new_expr); 04678 } 04679 04680 Theorem result = newRWTheorem( e, new_expr, Assumptions::emptyAssump(), pf); 04681 return result; 04682 } 04683 04684 04685 // BVMULT(N, a\@b, y) = BVPLUS(N, BVMULT(N,b,y), BVMULT(N-n,a,y) \@ n-bit-0-string) 04686 // where n = BVSize(b), a != 0, one of a or b is a constant 04687 Theorem BitvectorTheoremProducer::liftConcatBVMult(const Expr& e) 04688 { 04689 if (CHECK_PROOFS) { 04690 CHECK_SOUND(e.getOpKind() == BVMULT, 04691 "BitvectorTheoremProducer::liftConcatBVMult: input must be a BVMULT expression" + e.toString()); 04692 } 04693 int bv_size = d_theoryBitvector->BVSize( e ); 04694 vector<Expr> kids; 04695 int idx = -1; 04696 bool first = false; 04697 int i = 0; 04698 for (; i< e.arity(); ++i) { 04699 const Expr& kid = e[i]; 04700 if (idx == -1 && 04701 kid.getOpKind() == CONCAT) { 04702 if (kid[kid.arity()-1].getKind() == BVCONST) { 04703 idx = i; 04704 } 04705 else if (kid[0].getKind() == BVCONST && 04706 d_theoryBitvector->computeBVConst(kid[0]) != 0) { 04707 idx = i; 04708 first = true; 04709 } 04710 else kids.push_back(kid); 04711 } 04712 else kids.push_back(kid); 04713 } 04714 if (idx == -1) return d_theoryBitvector->reflexivityRule(e); 04715 04716 Expr concatHi, concatLo; 04717 04718 if (first) { 04719 // Split concat at the first kid 04720 if (e[idx].arity() == 2) { 04721 concatLo = e[idx][1]; 04722 } 04723 else { 04724 vector<Expr> concatKids; 04725 for (i = 1; i < e[idx].arity(); ++i) { 04726 concatKids.push_back(e[idx][i]); 04727 } 04728 concatLo = d_theoryBitvector->newConcatExpr(concatKids); 04729 } 04730 concatHi = e[idx][0]; 04731 } 04732 else { 04733 // Split concat at the last kid 04734 vector<Expr> concatKids = e[idx].getKids(); 04735 concatLo = concatKids.back(); 04736 concatKids.pop_back(); 04737 if (concatKids.size() == 1) { 04738 concatHi = concatKids[0]; 04739 } 04740 else { 04741 concatHi = d_theoryBitvector->newConcatExpr(concatKids); 04742 } 04743 } 04744 04745 int n = d_theoryBitvector->BVSize(concatLo); 04746 kids.push_back(concatLo); 04747 Expr bvMult1 = d_theoryBitvector->newBVMultPadExpr(bv_size, kids); 04748 kids.pop_back(); 04749 kids.push_back(concatHi); 04750 Expr bvMult2 = d_theoryBitvector->newBVMultPadExpr(bv_size-n,kids); 04751 Expr newLowConcat = d_theoryBitvector->newBVZeroString(n); 04752 Expr newConcat = d_theoryBitvector->newConcatExpr(bvMult2, newLowConcat); 04753 Expr res_expr = d_theoryBitvector->newBVPlusExpr(bv_size, bvMult1, newConcat); 04754 04755 Proof pf; 04756 if (withProof()) pf = newPf("liftConcatBVMult"); 04757 return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf); 04758 } 04759 04760 04761 // Let c * \prod_1^n a_i be the flattened BVMult term where c is a constant and each a_i cannot be: 04762 // a) const, b) bvuminus, c) bvplus, d) bvmult 04763 // The canonical form is: 04764 // 1. if c = 0, then 0 04765 // 2. if c = 1 and n = 1 then a_1 04766 // 3. else if c = 1 then \prod_1^n a_i 04767 // 4. else c * \prod_1^n a_i 04768 // Note that \prod should be ordered and made up of binary mult's 04769 04770 Theorem BitvectorTheoremProducer::canonBVMult( const Expr& e ) 04771 { 04772 TRACE("canonBVMult", "canonBVMult: {\n ", e.toString(), " --"); 04773 if (CHECK_PROOFS) 04774 CHECK_SOUND(e.getOpKind() == BVMULT, 04775 "BitvectorTheoremProducer::canonBVMult: input must be a BVMULT expression" + e.toString()); 04776 04777 // cout<<"BitvectorTheoremProducer::canonBVMult, e:"<<e.toString()<<endl; 04778 int expr_arity = e.arity(); 04779 int bv_size= d_theoryBitvector->BVSize(e); 04780 Theorem result; 04781 std::vector<Expr> mult_vars; 04782 Rational temp_coeff = 1; 04783 Expr new_expr; 04784 Expr no_minus_kid; 04785 Expr new_prod; 04786 Rational modulus = pow(Rational(bv_size), Rational(2)); 04787 // separating all the constants and variables in the 04788 // multiplications 04789 04790 for( int i = 0; i < expr_arity; ++i) { 04791 if (e[i].getOpKind() == BVUMINUS) { 04792 temp_coeff = (temp_coeff * (modulus-1)) % modulus; 04793 no_minus_kid = e[i][0]; 04794 } else no_minus_kid = e[i]; 04795 04796 switch (no_minus_kid.getOpKind()) { 04797 04798 case BVCONST: { 04799 // Collect constants 04800 temp_coeff *= d_theoryBitvector->computeBVConst( no_minus_kid ); 04801 temp_coeff = temp_coeff % modulus; 04802 break; 04803 } 04804 04805 case BVMULT: { 04806 if (no_minus_kid[0].getOpKind() == BVCONST) { 04807 // collect coefficient and the variable 04808 temp_coeff *= d_theoryBitvector->computeBVConst(no_minus_kid[0]); 04809 temp_coeff = temp_coeff % modulus; 04810 DebugAssert(no_minus_kid[1].getOpKind() != BVCONST && 04811 no_minus_kid[1].getOpKind() != BVPLUS && 04812 no_minus_kid[1].getOpKind() != BVUMINUS, 04813 "Expected canonized subterm"); 04814 04815 if (!new_prod.isNull()) { 04816 // multiply the kid by the product so far 04817 new_prod = d_theoryBitvector->newBVMultExpr( bv_size, new_prod, no_minus_kid[1]); 04818 } 04819 else 04820 { 04821 new_prod = no_minus_kid[1]; 04822 } 04823 } 04824 else { 04825 if (!new_prod.isNull()) { 04826 // multiply the kid by the product so far 04827 new_prod = d_theoryBitvector->newBVMultExpr( bv_size, new_prod, no_minus_kid); 04828 } 04829 else 04830 { 04831 new_prod = no_minus_kid; 04832 } 04833 } 04834 break; 04835 } 04836 04837 case BVPLUS: { 04838 result = distributive_rule( e ); 04839 TRACE("canonBVMult", "--> ", result.getRHS().toString(), "\n}"); 04840 return result; 04841 } 04842 04843 default: 04844 if (!new_prod.isNull()) { 04845 // multiply the kid by the product so far 04846 new_prod = d_theoryBitvector->newBVMultExpr( bv_size, new_prod, no_minus_kid); 04847 } 04848 else 04849 { 04850 new_prod = no_minus_kid; 04851 } 04852 } 04853 } 04854 04855 // producing the result 04856 if (temp_coeff == 0 || new_prod.isNull()) { 04857 // the variables found don't matter 04858 new_expr = d_theoryBitvector->newBVConstExpr(temp_coeff, bv_size); 04859 } 04860 else { 04861 if (new_prod.getOpKind() == BVMULT) { 04862 new_prod = BVMult_order_subterms(new_prod).getRHS(); 04863 } 04864 ExprMap<Rational> sumHashMap; 04865 Rational known_term; 04866 Expr coeff_expr = d_theoryBitvector->newBVConstExpr(temp_coeff, bv_size); 04867 new_expr = d_theoryBitvector->newBVMultExpr(bv_size, coeff_expr, new_prod); 04868 getPlusTerms(new_expr, known_term, sumHashMap); 04869 new_expr = buildPlusTerm(bv_size, known_term, sumHashMap); 04870 } 04871 04872 Proof pf; 04873 if (withProof()) pf = newPf("canonBVMult"); 04874 result = newRWTheorem(e, new_expr, Assumptions::emptyAssump(), pf); 04875 TRACE("canonBVMult", "--> ", new_expr.toString(), "\n}"); 04876 // cout<<"BitvectorTheoremProducer::canonBVMult, e: "<<e.toString()<<" result: "<<result.toString()<<endl; 04877 return result; 04878 } 04879 04880 04881 // BVMULT(a,b) = X where X is the result of applying distributivity of BVMULT over BVPLUS 04882 Theorem BitvectorTheoremProducer::distributive_rule( const Expr& e ) 04883 { 04884 if (CHECK_PROOFS) 04885 CHECK_SOUND(e.getOpKind() == BVMULT, 04886 "BitvectorTheoremProducer::distributive_rule: input must be a BVMULT expression" + e.toString()); 04887 04888 int bv_size= d_theoryBitvector->BVSize(e); 04889 04890 // BVMULT terms have just two kids; at least one of the two must be 04891 // a BVPLUS 04892 04893 vector<Expr> e0_kids, e1_kids, result_kids; 04894 04895 if (e[0].getOpKind() == BVPLUS) { 04896 e0_kids = e[0].getKids(); 04897 } 04898 else e0_kids.push_back(e[0]); 04899 04900 if (e[1].getOpKind() == BVPLUS) { 04901 e1_kids = e[1].getKids(); 04902 } 04903 else e1_kids.push_back(e[1]); 04904 04905 unsigned e0_kids_size = e0_kids.size(); 04906 unsigned e1_kids_size = e1_kids.size(); 04907 for( unsigned i = 0; i < e0_kids_size; ++i) { 04908 for( unsigned j = 0; j < e1_kids_size; ++j) { 04909 Expr sum_term = d_theoryBitvector->newBVMultExpr ( bv_size, e0_kids[i], e1_kids[j] ); 04910 result_kids.push_back( sum_term ); 04911 } 04912 } 04913 Expr result_sum = d_theoryBitvector->newBVPlusExpr ( bv_size, result_kids); 04914 Proof pf; 04915 if (withProof()) pf = newPf("distributive rule"); 04916 Theorem result = newRWTheorem( e, result_sum, Assumptions::emptyAssump(), pf); 04917 return result; 04918 } 04919 04920 04921 // BVPLUS(N, a0, ..., an) = BVPLUS(N-n,a0[N-1:n],...an[N-1:n])\@t 04922 // where n = BVSize(t), and the sum of the lowest n bits of a0..an is exactly 04923 // equal to t (i.e. no carry) 04924 Theorem BitvectorTheoremProducer::liftConcatBVPlus(const Expr& e) 04925 { 04926 if (CHECK_PROOFS) { 04927 CHECK_SOUND(e.getOpKind() == BVPLUS, 04928 "BitvectorTheoremProducer::liftConcatBVPlus: input must be a BVPLUS expression" + e.toString()); 04929 } 04930 int bv_size = d_theoryBitvector->BVSize( e ); 04931 vector<Expr> kids; 04932 int i = 0; 04933 Rational c = 0; 04934 04935 if (e[0].getOpKind() == BVCONST) { 04936 ++i; 04937 c = d_theoryBitvector->computeBVConst(e[0]); 04938 } 04939 04940 int chopSize = bv_size; 04941 04942 bool nonzero = false; 04943 bool nonconst = false; 04944 Expr term; 04945 04946 for (; i< e.arity(); ++i) { 04947 const Expr& kid = e[i]; 04948 if (kid.getOpKind() != CONCAT) { 04949 return d_theoryBitvector->reflexivityRule(e); 04950 } 04951 Expr last = kid[kid.arity()-1]; 04952 int size = d_theoryBitvector->BVSize(last); 04953 04954 // If the last concat kid is not a constant, then our only hope is to chop 04955 // it off exactly and hope that all other last concat kids are equal to 04956 // 0 and wider (in bits) than last 04957 if (last.getOpKind() != BVCONST) { 04958 if (nonzero || size > chopSize) { 04959 return d_theoryBitvector->reflexivityRule(e); 04960 } 04961 nonzero = true; 04962 nonconst = true; 04963 chopSize = size; 04964 term = last; 04965 continue; 04966 } 04967 04968 // If last is a zero-string, then we are OK, as long as it's at least as 04969 // wide as any nonconst we have encountered. If it's less wide than the 04970 // constants we have encountered so far, reduce chopSize accordingly 04971 if (d_theoryBitvector->computeBVConst(last) == 0) { 04972 if (size >= chopSize) continue; 04973 if (nonconst) return d_theoryBitvector->reflexivityRule(e); 04974 chopSize = size; 04975 continue; 04976 } 04977 04978 // If last is a nonzero const, it's OK as long as it is the only nonzero 04979 // thing we encounter 04980 if (nonzero) return d_theoryBitvector->reflexivityRule(e); 04981 nonzero = true; 04982 if (size < chopSize) chopSize = size; 04983 term = last; 04984 } 04985 04986 // if nonzero exists, check the constant 04987 if (nonzero) { 04988 if (c != 0) { 04989 Rational modulus = pow(Rational(chopSize), Rational(2)); 04990 if ((c % modulus) != 0) { 04991 return d_theoryBitvector->reflexivityRule(e); 04992 } 04993 } 04994 } 04995 else if (c == 0) { 04996 term = d_theoryBitvector->newBVZeroString(chopSize); 04997 } 04998 else { 04999 term = d_theoryBitvector->newBVExtractExpr(e[0], chopSize-1, 0); 05000 } 05001 05002 vector<Expr> newKids; 05003 for (i = 0; i < e.arity(); ++i) { 05004 newKids.push_back(d_theoryBitvector->newBVExtractExpr(e[i], bv_size-1, chopSize)); 05005 } 05006 05007 Expr bvPlus = d_theoryBitvector->newBVPlusExpr(bv_size-chopSize, newKids); 05008 if (d_theoryBitvector->BVSize(term) > chopSize) { 05009 term = d_theoryBitvector->newBVExtractExpr(term, chopSize-1, 0); 05010 } 05011 05012 Expr res_expr = d_theoryBitvector->newConcatExpr(bvPlus, term); 05013 05014 Proof pf; 05015 if (withProof()) pf = newPf("liftConcatBVPlus"); 05016 return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf); 05017 } 05018 05019 05020 void BitvectorTheoremProducer::getPlusTerms(const Expr& e, Rational& known_term, 05021 ExprMap<Rational>& sumHashMap) 05022 { 05023 int bv_size = d_theoryBitvector->BVSize( e ); 05024 Rational modulus = pow(Rational(bv_size), Rational(2)); 05025 unsigned i; 05026 vector<Expr> plusTerms; 05027 vector<Rational> coeffs; 05028 05029 plusTerms.push_back(e); 05030 coeffs.push_back(1); 05031 known_term = 0; 05032 05033 for(i = 0; i < plusTerms.size(); ++i) { 05034 Expr kid = plusTerms[i]; 05035 int kidSize = d_theoryBitvector->BVSize(kid); 05036 DebugAssert(kidSize <= bv_size, "Expected kid no wider than bv_size"); 05037 Rational coeff = coeffs[i]; 05038 if (coeff == 0) continue; 05039 05040 switch (kid.getOpKind()) { 05041 05042 case BVCONST: 05043 known_term += coeff * d_theoryBitvector->computeBVConst( kid ); 05044 known_term = known_term % modulus; 05045 break; 05046 05047 case BVUMINUS: 05048 DebugAssert(kidSize == bv_size, "Unexpected size for uminus"); 05049 plusTerms.push_back(plusTerms[i][0]); 05050 coeffs.push_back((coeff * (modulus - 1)) % modulus); 05051 break; 05052 05053 case BVNEG: 05054 if (kidSize < bv_size) { 05055 Rational m2 = pow(Rational(kidSize), Rational(2)); 05056 known_term += coeff * (m2-1); 05057 } 05058 else { 05059 known_term += coeff * (modulus-1); 05060 } 05061 known_term = known_term % modulus; 05062 plusTerms.push_back(plusTerms[i][0]); 05063 coeffs.push_back((coeff * (modulus-1)) % modulus); 05064 break; 05065 05066 case BVMULT: 05067 if (kidSize < bv_size) { 05068 int shift = 0; 05069 Rational tcoeff = coeff; 05070 for (; tcoeff % 2 == 0; ++shift, tcoeff = tcoeff / 2); 05071 if (shift + kidSize < bv_size) { 05072 // can't combine different sizes-- 05073 // just insert it as is 05074 sumHashMap[ kid ] = sumHashMap[ kid ] + coeff; 05075 break; 05076 } 05077 } 05078 // OK to combine sizes 05079 if( kid[0].getOpKind() == BVCONST ) 05080 { 05081 DebugAssert(kid.arity() == 2, "Expected arity 2 BVMULT"); 05082 plusTerms.push_back(kid[1]); 05083 coeffs.push_back((coeff * d_theoryBitvector->computeBVConst(kid[0])) % modulus); 05084 } 05085 else 05086 { 05087 sumHashMap[ kid ] = sumHashMap[ kid ] + coeff; 05088 } 05089 break; 05090 05091 case BVPLUS: { 05092 if (kidSize < bv_size) { 05093 int shift = 0; 05094 Rational tcoeff = coeff; 05095 for (; tcoeff % 2 == 0; ++shift, tcoeff = tcoeff / 2); 05096 if (shift + kidSize < bv_size) { 05097 // can't combine BVPLUSes of different size-- 05098 // just insert it as is 05099 sumHashMap[ kid ] = sumHashMap[ kid ] + coeff; 05100 break; 05101 } 05102 } 05103 // OK to combine BVPLUS terms 05104 int kid_arity = kid.arity(); 05105 for(int j = 0; j < kid_arity; ++j) { 05106 plusTerms.push_back(kid[j]); 05107 coeffs.push_back(coeff); 05108 } 05109 break; 05110 } 05111 05112 case CONCAT: { 05113 // Convert CONCAT to BVPLUS 05114 int n = d_theoryBitvector->BVSize(kid); 05115 Rational concatConst; 05116 for (int j = 0; j < kid.arity(); ++j) { 05117 const Expr& concatKid = kid[j]; 05118 n -= d_theoryBitvector->BVSize(concatKid); 05119 concatConst = pow(Rational(n), Rational(2)) * coeff; 05120 plusTerms.push_back(concatKid); 05121 coeffs.push_back(concatConst % modulus); 05122 } 05123 break; 05124 } 05125 05126 case EXTRACT: { 05127 // TODO: maybe re-enable this in some cases, but it leads to simplification loops 05128 if (false && kidSize < bv_size) { 05129 // If the top part of a term is cut off with an extract, try to put it back 05130 const Expr& ext_kid = kid[0]; 05131 int size = d_theoryBitvector->BVSize(ext_kid); 05132 int extractLeft = d_theoryBitvector->getExtractHi(kid); 05133 if (extractLeft < size-1) { 05134 int shift = 0; 05135 Rational tcoeff = coeff; 05136 for (; tcoeff % 2 == 0; ++shift, tcoeff = tcoeff / 2); 05137 if (shift + kidSize >= bv_size) { 05138 int bitsToAdd = bv_size - kidSize; 05139 extractLeft += bitsToAdd; 05140 if (extractLeft > size - 1) extractLeft = size - 1; 05141 int extractRight = d_theoryBitvector->getExtractLow(kid); 05142 if (extractLeft == size-1 && extractRight == 0) { 05143 plusTerms.push_back(ext_kid); 05144 coeffs.push_back(coeff); 05145 } 05146 else { 05147 plusTerms.push_back(d_theoryBitvector->newBVExtractExpr(ext_kid, extractLeft, extractRight)); 05148 coeffs.push_back(coeff); 05149 } 05150 break; 05151 } 05152 } 05153 else { 05154 DebugAssert(d_theoryBitvector->getExtractLow(kid) != 0, 05155 "Unexpected extract bounds"); 05156 } 05157 } 05158 // fall through 05159 } 05160 05161 default: 05162 sumHashMap[ kid] = sumHashMap[ kid] + coeff; 05163 break; 05164 } 05165 } 05166 } 05167 05168 05169 Expr BitvectorTheoremProducer::chopConcat(int bv_size, Rational c, 05170 vector<Expr>& concatKids) 05171 { 05172 int chopSize = bv_size; 05173 05174 bool nonzero = false; 05175 bool nonconst = false; 05176 Expr term, kid, last; 05177 int size; 05178 unsigned i; 05179 05180 for (i = 0; i< concatKids.size(); ++i) { 05181 kid = concatKids[i]; 05182 if (kid.getOpKind() != CONCAT) return Expr(); 05183 05184 last = kid[kid.arity()-1]; 05185 size = d_theoryBitvector->BVSize(last); 05186 05187 // If the last concat kid is not a constant, then our only hope is to chop 05188 // it off exactly and hope that all other last concat kids are equal to 05189 // 0 and wider (in bits) than last 05190 if (last.getOpKind() != BVCONST) { 05191 if (nonzero || size > chopSize) return Expr(); 05192 nonzero = true; 05193 nonconst = true; 05194 chopSize = size; 05195 term = last; 05196 continue; 05197 } 05198 05199 // If last is a zero-string, then we are OK, as long as it's at least as 05200 // wide as any nonconst we have encountered. If it's less wide than the 05201 // constants we have encountered so far, reduce chopSize accordingly 05202 if (d_theoryBitvector->computeBVConst(last) == 0) { 05203 if (size >= chopSize) continue; 05204 if (nonconst) return Expr(); 05205 chopSize = size; 05206 continue; 05207 } 05208 05209 // If last is a nonzero const, it's OK as long as it is the only nonzero 05210 // thing we encounter 05211 if (nonzero) return Expr(); 05212 nonzero = true; 05213 if (size < chopSize) chopSize = size; 05214 term = last; 05215 } 05216 05217 Rational modulus = pow(Rational(chopSize), Rational(2)); 05218 05219 // if nonzero exists, check the constant 05220 if (nonzero) { 05221 if (c != 0) { 05222 if ((c % modulus) != 0) return Expr(); 05223 c = c / modulus; 05224 } 05225 } 05226 else if (c == 0) { 05227 term = d_theoryBitvector->newBVZeroString(chopSize); 05228 } 05229 else { 05230 Rational value = c % modulus; 05231 term = d_theoryBitvector->newBVConstExpr(value, chopSize); 05232 c = c - value; 05233 c = c / modulus; 05234 } 05235 05236 // Now chop them 05237 for (i = 0; i < concatKids.size(); ++i) { 05238 kid = concatKids[i]; 05239 vector<Expr> kids = kid.getKids(); 05240 last = kids.back(); 05241 kids.pop_back(); 05242 size = d_theoryBitvector->BVSize(last); 05243 05244 if (size != chopSize) { 05245 DebugAssert(size > chopSize, "Expected last to be wider than chopSize"); 05246 DebugAssert(last.getOpKind() == BVCONST, "Expected last kind = BVCONST"); 05247 Rational value = d_theoryBitvector->computeBVConst(last); 05248 if (value != 0) { 05249 value = value - (value % modulus); 05250 value = value / modulus; 05251 } 05252 kids.push_back(d_theoryBitvector->newBVConstExpr(value, size - chopSize)); 05253 } 05254 DebugAssert(kids.size() > 0, "Expected size > 0"); 05255 if (kids.size() == 1) { 05256 concatKids[i] = kids[0]; 05257 } 05258 else { 05259 concatKids[i] = d_theoryBitvector->newConcatExpr(kids); 05260 } 05261 } 05262 05263 if (d_theoryBitvector->BVSize(term) > chopSize) { 05264 DebugAssert(term.getOpKind() == BVCONST, "Expected BVCONST"); 05265 Rational value = d_theoryBitvector->computeBVConst(term); 05266 DebugAssert(value != 0, "Expected 0"); 05267 value = value % modulus; 05268 term = d_theoryBitvector->newBVConstExpr(value, chopSize); 05269 } 05270 05271 Expr bvPlus = chopConcat(bv_size-chopSize, c, concatKids); 05272 if (!bvPlus.isNull()) { 05273 DebugAssert(bvPlus.getOpKind() == CONCAT, "Expected CONCAT"); 05274 vector<Expr> kids = bvPlus.getKids(); 05275 kids.push_back(term); 05276 return d_theoryBitvector->newConcatExpr(kids); 05277 } 05278 05279 vector<Expr> newKids; 05280 if (c != 0) { 05281 newKids.push_back(d_theoryBitvector->newBVConstExpr(c, bv_size - chopSize)); 05282 } 05283 for (i = 0; i < concatKids.size(); ++i) { 05284 newKids.push_back(concatKids[i]); 05285 } 05286 DebugAssert(newKids.size() > 1, "Expected more than one kid"); 05287 bvPlus = d_theoryBitvector->newBVPlusExpr(bv_size-chopSize, newKids); 05288 05289 // Make sure bvPlus is canonized 05290 ExprMap<Rational> sumHashMap; 05291 Rational known_term; 05292 getPlusTerms(bvPlus, known_term, sumHashMap); 05293 bvPlus = buildPlusTerm(bv_size-chopSize, known_term, sumHashMap); 05294 return d_theoryBitvector->newConcatExpr(bvPlus, term); 05295 } 05296 05297 05298 Expr BitvectorTheoremProducer::buildPlusTerm(int bv_size, 05299 Rational& known_term, 05300 ExprMap<Rational>& sumHashMap) 05301 { 05302 // Try to convert into CONCATs 05303 Rational modulus = pow(Rational(bv_size), Rational(2)); 05304 Rational coeff, pos; 05305 Rational tmask, tcoeff, marked = 0; 05306 int nbits, lg; 05307 ExprMap<Rational>::iterator j = sumHashMap.begin(); 05308 vector<Expr> multKids, concatKids; 05309 unsigned i; 05310 for(; j != sumHashMap.end(); ++j) { 05311 coeff = mod((*j).second, modulus); 05312 Expr term = (*j).first; 05313 nbits = d_theoryBitvector->BVSize(term); 05314 05315 // Fast case: coeff is 1 and term takes up all the bits 05316 if (coeff == 1 && nbits == bv_size) { 05317 if (nbits == 1 && known_term == 1) { 05318 // rewrite 1-bit x + 1 as ~x 05319 multKids.push_back(d_theoryBitvector->newBVNegExpr(term)); 05320 known_term = 0; 05321 } 05322 else { 05323 multKids.push_back(term); 05324 } 05325 continue; 05326 } 05327 05328 while (coeff != 0) { 05329 05330 for (pos = coeff, lg = 0; pos % 2 == 0; pos = pos / 2, ++lg); 05331 pos = pow(Rational(lg), Rational(2)); // Position of lsb containing a 1 05332 05333 Expr concatTerm; 05334 05335 // pos of first bit beyond term 05336 Rational tmodulus = modulus; 05337 if (nbits+lg < bv_size) tmodulus = pow(Rational(nbits+lg), Rational(2)); 05338 Rational tcoeff = coeff % tmodulus; 05339 05340 if (tcoeff == pos) { 05341 coeff -= tcoeff; 05342 concatTerm = term; 05343 } 05344 else if (((tcoeff + pos) % tmodulus) == 0) { 05345 coeff = (coeff + pos) % modulus; 05346 // rewrite as bvneg 05347 concatTerm = d_theoryBitvector->newBVNegExpr(term); 05348 known_term += pos; 05349 if (nbits + lg < bv_size) { 05350 known_term += (modulus - tmodulus); 05351 } 05352 if (pos == 1 && nbits == bv_size) { 05353 multKids.push_back(concatTerm); 05354 continue; 05355 } 05356 } 05357 else { 05358 // create a BVMULT 05359 if (nbits + lg > bv_size) { 05360 // term is too big: chop it off 05361 int diff = nbits + lg - bv_size; 05362 int high, low; 05363 if (term.getOpKind() == EXTRACT) { 05364 // Collapse extract of extract 05365 high = d_theoryBitvector->getExtractHi(term) - diff; 05366 low = d_theoryBitvector->getExtractLow(term); 05367 term = term[0]; 05368 } 05369 else { 05370 high = nbits - 1 - diff; 05371 low = 0; 05372 } 05373 term = d_theoryBitvector->newBVExtractExpr(term, high, low); 05374 } 05375 nbits = bv_size - lg; 05376 coeff = coeff / pos; 05377 Expr new_coeff = d_theoryBitvector->newBVConstExpr(coeff, nbits); 05378 term = d_theoryBitvector->newBVMultPadExpr(nbits, new_coeff, term); 05379 coeff = 0; 05380 if (lg == 0) { 05381 multKids.push_back(term); 05382 continue; 05383 } 05384 concatTerm = term; 05385 } 05386 05387 // Insert concatTerm at position lg into a CONCAT 05388 bool found = false; 05389 Expr t; 05390 vector<Expr> tmp; 05391 int bits, size, k, t_arity; 05392 for (i = 0; i < concatKids.size(); ++i) { 05393 t = concatKids[i]; 05394 DebugAssert(t.getOpKind() == CONCAT, "Expected CONCAT"); 05395 bits = bv_size; 05396 t_arity = t.arity(); 05397 for (k = 0; k < t_arity; ++k) { 05398 if (k > 0 && bits < lg + nbits) break; 05399 size = d_theoryBitvector->BVSize(t[k]); 05400 if (bits - size <= lg) { 05401 if (t[k].getOpKind() == BVCONST) { 05402 found = true; 05403 } 05404 break; 05405 } 05406 else { 05407 tmp.push_back(t[k]); 05408 bits -= size; 05409 } 05410 } 05411 if (found) break; 05412 tmp.clear(); 05413 } 05414 if (!found) { 05415 bits = bv_size; 05416 size = bv_size; 05417 k = t_arity = 0; 05418 } 05419 if (lg + nbits < bits) { 05420 tmp.push_back(d_theoryBitvector->newBVZeroString(bits-(lg+nbits))); 05421 } 05422 if (lg + nbits > bits) { 05423 bool negate = false; 05424 if (concatTerm.getOpKind() == BVNEG) { 05425 // Push extract inside negation 05426 negate = true; 05427 concatTerm = concatTerm[0]; 05428 } 05429 DebugAssert(!found || k == 0, 05430 "Too big only OK for first child"); 05431 // If term is too big, chop it off 05432 int diff = lg + nbits - bits; 05433 int high, low; 05434 if (concatTerm.getOpKind() == EXTRACT) { 05435 // Collapse extract of extract 05436 high = d_theoryBitvector->getExtractHi(concatTerm) - diff; 05437 low = d_theoryBitvector->getExtractLow(concatTerm); 05438 concatTerm = concatTerm[0]; 05439 } 05440 else { 05441 high = nbits - 1 - diff; 05442 low = 0; 05443 } 05444 concatTerm = d_theoryBitvector->newBVExtractExpr(concatTerm, high, low); 05445 if (negate) { 05446 concatTerm = d_theoryBitvector->newBVNegExpr(concatTerm); 05447 } 05448 } 05449 tmp.push_back(concatTerm); 05450 bits -= size; 05451 if (lg > bits) { 05452 tmp.push_back(d_theoryBitvector->newBVZeroString(lg-bits)); 05453 } 05454 for (++k; k < t_arity; ++k) { 05455 tmp.push_back(t[k]); 05456 } 05457 05458 if (tmp.size() == 1) { 05459 DebugAssert(!found, "Invariant violated"); 05460 multKids.push_back(tmp[0]); 05461 } 05462 else if (found) { 05463 // replace existing concat term 05464 concatKids[i] = d_theoryBitvector->newConcatExpr(tmp); 05465 } 05466 else { 05467 // push back new concat term 05468 concatKids.push_back(d_theoryBitvector->newConcatExpr(tmp)); 05469 } 05470 } 05471 } 05472 05473 known_term = known_term % modulus; 05474 05475 // See if we can merge constant in with CONCATs 05476 if (known_term != 0 && !concatKids.empty()) { 05477 vector<Expr> tmp; 05478 for (i = 0; i < concatKids.size(); ++i) { 05479 Expr t = concatKids[i]; 05480 DebugAssert(t.getOpKind() == CONCAT, "Expected CONCAT"); 05481 int bits = bv_size; 05482 int size; 05483 bool anyChanged = false; 05484 for (int k = 0; k < t.arity(); ++k) { 05485 size = d_theoryBitvector->BVSize(t[k]); 05486 bool changed = false; 05487 if (known_term != 0 && t[k].getOpKind() == BVCONST) { 05488 Rational high = pow(Rational(bits), Rational(2)); 05489 Rational partConst = known_term % high; 05490 if (partConst != 0) { 05491 Rational low = pow(Rational(bits - size), Rational(2)); 05492 partConst = partConst - (partConst % low); 05493 if (partConst != 0) { 05494 anyChanged = changed = true; 05495 tmp.push_back(d_theoryBitvector->newBVConstExpr(partConst / low, size)); 05496 known_term -= partConst; 05497 } 05498 } 05499 } 05500 if (!changed) { 05501 tmp.push_back(t[k]); 05502 } 05503 bits -= size; 05504 } 05505 if (anyChanged) { 05506 concatKids[i] = d_theoryBitvector->newConcatExpr(tmp); 05507 if (known_term == 0) break; 05508 } 05509 tmp.clear(); 05510 } 05511 } 05512 05513 // reassembling terms into a unique BVPLUS expression 05514 Expr expr_result; 05515 05516 // Check to see if we can chop off the bottom of the BVPLUS 05517 if (multKids.size() == 0 && 05518 (concatKids.size() > 1 || 05519 (concatKids.size() == 1 && known_term != 0))) { 05520 expr_result = chopConcat(bv_size, known_term, concatKids); 05521 if (!expr_result.isNull()) return expr_result; 05522 } 05523 05524 if (known_term == 0) { 05525 for (i = 0; i < concatKids.size(); ++i) { 05526 multKids.push_back(concatKids[i]); 05527 } 05528 if (multKids.size() == 0) { 05529 expr_result = d_theoryBitvector->newBVConstExpr( Rational(0), bv_size); 05530 } 05531 else if (multKids.size() == 1) { 05532 expr_result = multKids[0]; 05533 } 05534 else { 05535 expr_result = d_theoryBitvector->newBVPlusExpr( bv_size, multKids); 05536 } 05537 } 05538 else { 05539 vector<Expr> sumKids; 05540 sumKids.push_back( d_theoryBitvector->newBVConstExpr( known_term, bv_size)); 05541 for (i = 0; i < multKids.size(); ++i) { 05542 sumKids.push_back(multKids[i]); 05543 } 05544 for (i = 0; i < concatKids.size(); ++i) { 05545 sumKids.push_back(concatKids[i]); 05546 } 05547 if (sumKids.size() == 1) { 05548 expr_result = sumKids[0]; 05549 } 05550 else { 05551 expr_result = d_theoryBitvector->newBVPlusExpr( bv_size, sumKids); 05552 } 05553 } 05554 return expr_result; 05555 } 05556 05557 05558 // It assumes that all the kids have already been canonized 05559 Theorem BitvectorTheoremProducer::canonBVPlus( const Expr& e ) 05560 { 05561 TRACE("canonBVPlus", "canonBVPlus: {\n ", e.toString(), " --"); 05562 05563 if (CHECK_PROOFS) 05564 CHECK_SOUND(e.getOpKind() == BVPLUS, 05565 "BitvectorTheoremProducer::canonBVPlus: input must be a BVPLUS expression" + e.toString()); 05566 05567 // cout<<"BitvectorTheoremProducer::canonBVPlus, e is: "<<e.toString()<<endl; 05568 //! L:: to store the sum of the coefficients for each var 05569 ExprMap<Rational> sumHashMap; 05570 int bv_size = d_theoryBitvector->BVSize( e ); 05571 Rational known_term; 05572 05573 // Get plus terms in a hash map 05574 getPlusTerms(e, known_term, sumHashMap); 05575 05576 // Build the plus term from known_term, sumHashMap 05577 Expr expr_result = buildPlusTerm(bv_size, known_term, sumHashMap); 05578 05579 Proof pf; 05580 if (withProof()) pf = newPf("canonBVPlus"); 05581 Theorem result = newRWTheorem( e, expr_result, Assumptions::emptyAssump(), pf); 05582 TRACE("canonBVPlus", "--> ", expr_result.toString(), "\n}"); 05583 return result; 05584 } 05585 05586 05587 Theorem BitvectorTheoremProducer::canonBVUMinus( const Expr& e ) 05588 { 05589 if (CHECK_PROOFS) 05590 CHECK_SOUND(e.getOpKind() == BVUMINUS, 05591 "BitvectorTheoremProducer::canonBVUMinus: input must be a BVUMINUS expression" + e.toString()); 05592 05593 int bv_size = d_theoryBitvector->BVSize(e); 05594 Rational modulus = pow(Rational(bv_size), Rational(2)); 05595 Expr coeff = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size); 05596 Expr res_expr = d_theoryBitvector->newBVMultExpr(bv_size, coeff, e[0]); 05597 Proof pf; 05598 if (withProof()) pf = newPf("canonBVUMinus"); 05599 return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf); 05600 } 05601 /*End of Lorenzo PLatania's methods*/ 05602 05603 05604 // Input: t[hi:lo] = rhs 05605 // if t appears as leaf in rhs, then: 05606 // t[hi:lo] = rhs |- Exists x,y,z. (t = x \@ y \@ z AND y = rhs), solvedForm = false 05607 // else 05608 // t[hi:lo] = rhs |- Exists x,z. (t = x \@ rhs \@ z), solvedForm = true 05609 Theorem BitvectorTheoremProducer::processExtract(const Theorem& e, bool& solvedForm) 05610 { 05611 Expr expr = e.getExpr(); 05612 05613 if (CHECK_PROOFS) { 05614 CHECK_SOUND(expr.getOpKind() == EQ && expr[0].getOpKind() == EXTRACT, 05615 "BitvectorTheoremProducer::processExtract: invalid input"); 05616 CHECK_SOUND(d_theoryBitvector->BVSize(expr[0]) == d_theoryBitvector->BVSize(expr[1]), 05617 "Expected same size"); 05618 } 05619 05620 Expr ext = expr[0]; 05621 Expr lhs; 05622 Expr rhs = expr[1]; 05623 Expr child = ext[0]; 05624 int size = d_theoryBitvector->BVSize(child); 05625 int high = d_theoryBitvector->getExtractHi(ext); 05626 int low = d_theoryBitvector->getExtractLow(ext); 05627 05628 DebugAssert(d_theoryBitvector->isLeaf(child), "Expected leaf"); 05629 solvedForm = !d_theoryBitvector->isLeafIn(child, rhs); 05630 05631 vector<Expr> terms; 05632 vector<Expr> boundVars; 05633 if (high < size-1) { 05634 terms.push_back(d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(size-1-high))); 05635 boundVars.push_back(terms.back()); 05636 } 05637 if (solvedForm) terms.push_back(rhs); 05638 else { 05639 lhs = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(high-low+1)); 05640 terms.push_back(lhs); 05641 boundVars.push_back(lhs); 05642 } 05643 if (low > 0) { 05644 terms.push_back(d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(low))); 05645 boundVars.push_back(terms.back()); 05646 } 05647 DebugAssert(terms.size() > 1, "Expected at least two terms"); 05648 Expr result = child.eqExpr(d_theoryBitvector->newConcatExpr(terms)); 05649 if (!solvedForm) result = result && lhs.eqExpr(rhs); 05650 result = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, result); 05651 Assumptions a(e); 05652 Proof pf; 05653 if (withProof()) pf = newPf("processExtract"); 05654 return newTheorem(result, a, pf); 05655 } 05656 05657 bool BitvectorTheoremProducer::okToSplit(const Expr& e) 05658 { 05659 if (d_theoryBitvector->isLeaf(e)) return true; 05660 switch (e.getOpKind()) { 05661 case BVCONST: 05662 case EXTRACT: 05663 case BVAND: 05664 case BVOR: 05665 case BVXOR: 05666 case BVNEG: 05667 return true; 05668 case BVSHL: 05669 case BVLSHR: 05670 case BVASHR: 05671 case BVPLUS: 05672 case BVMULT: 05673 case BVUDIV: 05674 case BVSDIV: 05675 case BVUREM: 05676 case BVSREM: 05677 case BVSMOD: 05678 return false; 05679 default: 05680 FatalAssert(false, "unexpected kind in okToSplit"); 05681 break; 05682 } 05683 return false; 05684 } 05685 05686 05687 // puts the equation in solved form if possible, otherwise in the form 05688 // \sum a_i*x_i +c = 0. 05689 // default maxEffort is 3: solves only when lhs can be isolated without splitting 05690 // maxEffort 5: solves when lhs can be isolated with splitting 05691 // maxEffort 6: solves even when result is not in solved form (good for bitblasting) 05692 Theorem BitvectorTheoremProducer::canonBVEQ( const Expr& e, int maxEffort ) 05693 { 05694 TRACE("canonBVEQ", "canonBVEQ: {\n ", e.toString(), " --"); 05695 DebugAssert(maxEffort == 3 || maxEffort == 5 || maxEffort == 6, 05696 "Unexpected value for maxEffort"); 05697 if(CHECK_PROOFS) { 05698 CHECK_SOUND( e.getOpKind() == EQ, 05699 "BitvectorTheoremProducer::canonBVEQ: expression must be an equation"); 05700 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind(), 05701 "input must be a bitvector eqn. \n e = " + e.toString()); 05702 } 05703 05704 Expr lhs = e[0]; 05705 Expr rhs = e[1]; 05706 int bv_size = d_theoryBitvector->BVSize( lhs ); 05707 05708 // Look for easy split of concats 05709 if (lhs.getOpKind() == CONCAT || rhs.getOpKind() == CONCAT) { 05710 Expr::iterator lit, rit; 05711 int lsize, rsize; 05712 if (lhs.getOpKind() == CONCAT) { 05713 lit = e[0].begin(); 05714 } 05715 else { 05716 lit = e.begin(); 05717 } 05718 if (rhs.getOpKind() == CONCAT) { 05719 rit = e[1].begin(); 05720 } 05721 else { 05722 rit = e.begin(); 05723 ++rit; 05724 } 05725 int splitSize; 05726 lsize = d_theoryBitvector->BVSize(*lit); 05727 rsize = d_theoryBitvector->BVSize(*rit); 05728 while (true) { 05729 DebugAssert(lsize <= bv_size && rsize <= bv_size, "invariant violated"); 05730 if (lsize < rsize) { 05731 if (okToSplit(*rit)) { 05732 splitSize = lsize; 05733 break; 05734 } 05735 else { 05736 ++lit; 05737 lsize += d_theoryBitvector->BVSize(*lit); 05738 } 05739 } 05740 else if (lsize > rsize) { 05741 if (okToSplit(*lit)) { 05742 splitSize = rsize; 05743 break; 05744 } 05745 else { 05746 ++rit; 05747 rsize += d_theoryBitvector->BVSize(*rit); 05748 } 05749 } 05750 else { 05751 splitSize = lsize; 05752 break; 05753 } 05754 } 05755 if (splitSize != bv_size) { 05756 Proof pf; 05757 if (withProof()) pf = newPf("canonBVEQ"); 05758 Expr tmp = d_theoryBitvector->newBVExtractExpr(lhs, bv_size-1, bv_size-splitSize); 05759 tmp = tmp.eqExpr(d_theoryBitvector->newBVExtractExpr(rhs, bv_size-1, bv_size-splitSize)); 05760 Expr expr_result = d_theoryBitvector->newBVExtractExpr(lhs, bv_size-splitSize-1, 0); 05761 expr_result = expr_result.eqExpr(d_theoryBitvector->newBVExtractExpr(rhs, bv_size-splitSize-1, 0)); 05762 expr_result = tmp && expr_result; 05763 TRACE("canonBVEQ", "--> ", expr_result.toString(), "\n}"); 05764 return newRWTheorem( e, expr_result, Assumptions::emptyAssump(), pf); 05765 } 05766 } 05767 05768 rhs = d_theoryBitvector->newBVUminusExpr(rhs); 05769 ExprMap<Rational> sumHashMap; 05770 Rational modulus = pow(Rational(bv_size), Rational(2)); 05771 Rational known_term; 05772 05773 getPlusTerms(d_theoryBitvector->newBVPlusExpr(bv_size, lhs, rhs), known_term, sumHashMap); 05774 05775 // Loop through all terms and perform two tasks: 05776 // A. Truncate coefficients 05777 // B. Look for a something to solve for: 05778 // 1. first choice: full-sized leaf not occurring elsewhere 05779 // 2. second choice: full-sized leaf inside BVXOR not occurring elsewhere 05780 // 3. third choice: full-sized extract of a leaf or over-sized leaf or extract of leaf 05781 // 4. fourth choice: under-sized leaf not occurring elsewhere or extract of leaf 05782 // 5. fifth choice: even-coeff leaf not occurring elsewhere or extract of leaf 05783 // 6. sixth choice: first term with an odd coeff (even if not a leaf or occurring elsewhere) 05784 // 7. seventh choice: nothing to solve for and all coeffs are even 05785 05786 // If choice > maxEffort (and not 7), put in form sum = 0 instead. 05787 05788 Rational coeff, foundCoeff = 1; 05789 ExprMap<Rational>::iterator j = sumHashMap.begin(); 05790 ExprMap<Rational>::iterator fixCoeff = j; 05791 Expr xor_leaf, leaf, foundterm; 05792 unsigned xor_idx=0, xor_size=0; 05793 int priority, size, foundpriority = 7; 05794 bool isExtract; 05795 for(; j != sumHashMap.end(); ++j) { 05796 Expr t = (*j).first; 05797 coeff = (*j).second; 05798 size = d_theoryBitvector->BVSize(t); 05799 if (j == fixCoeff) { 05800 coeff = (*j).second = mod(coeff, modulus); 05801 ++fixCoeff; 05802 } 05803 if (coeff == 0) continue; 05804 05805 priority = 7; 05806 isExtract = false; 05807 if (coeff % 2 == 1) { 05808 if (d_theoryBitvector->isLeaf(t)) { 05809 if (size == bv_size) { 05810 leaf = t; priority = 1; 05811 } else if (size > bv_size) { 05812 isExtract = true; 05813 leaf = t; priority = 3; 05814 } else { 05815 leaf = t; priority = 4; 05816 } 05817 } else if (t.getOpKind() == EXTRACT && 05818 d_theoryBitvector->isLeaf(t[0])) { 05819 isExtract = true; 05820 if (size >= bv_size) { 05821 leaf = t[0]; priority = 3; 05822 } else { 05823 leaf = t[0]; priority = 4; 05824 } 05825 } else if (t.getOpKind() == BVXOR && size == bv_size) { 05826 if (foundpriority == 2) continue; 05827 xor_idx = 0; 05828 xor_size = t.arity(); 05829 for (xor_idx = 0; xor_idx < xor_size; ++xor_idx) { 05830 if (!d_theoryBitvector->isLeaf(t[xor_idx])) { 05831 continue; 05832 } 05833 unsigned l = 0; 05834 for (; l < xor_size; ++l) { 05835 if (l == xor_idx) continue; 05836 if (d_theoryBitvector->isLeafIn(t[xor_idx], t[l])) break; 05837 } 05838 if (l < xor_size) continue; 05839 break; 05840 } 05841 if (xor_idx < xor_size) { 05842 leaf = t[xor_idx]; 05843 xor_leaf = leaf; 05844 priority = 2; 05845 } 05846 else { 05847 leaf = t; priority = 6; 05848 } 05849 } 05850 else { 05851 leaf = t; priority = 6; 05852 } 05853 } else if (maxEffort >= 5) { 05854 if (d_theoryBitvector->isLeaf(t)) { 05855 leaf = t; priority = 5; 05856 } else if (t.getOpKind() == EXTRACT && 05857 d_theoryBitvector->isLeaf(t[0])) { 05858 isExtract = true; 05859 leaf = t[0]; priority = 5; 05860 } 05861 } 05862 05863 if (priority < foundpriority) { 05864 if (priority < 6) { 05865 ExprMap<Rational>::iterator k = sumHashMap.begin(); 05866 while (k != sumHashMap.end()) { 05867 if (j == k) { 05868 ++k; continue; 05869 } 05870 if (k == fixCoeff) { 05871 (*k).second = mod((*k).second, modulus); 05872 ++fixCoeff; 05873 } 05874 if ((*k).second == 0) { 05875 ++k; continue; 05876 } 05877 if (!isExtract && d_theoryBitvector->isLeafIn(leaf, (*k).first)) { 05878 if (priority == 2) { 05879 // Try to find another leaf in the BVXOR 05880 for (++xor_idx; xor_idx < xor_size; ++xor_idx) { 05881 if (!d_theoryBitvector->isLeaf(t[xor_idx])) { 05882 continue; 05883 } 05884 unsigned l = 0; 05885 for (; l < xor_size; ++l) { 05886 if (l == xor_idx) continue; 05887 if (d_theoryBitvector->isLeafIn(t[xor_idx], t[l])) break; 05888 } 05889 if (l < xor_size) continue; 05890 break; 05891 } 05892 if (xor_idx < xor_size) { 05893 // found a leaf, continue checking it 05894 leaf = t[xor_idx]; 05895 xor_leaf = leaf; 05896 k = sumHashMap.begin(); 05897 continue; 05898 } 05899 } 05900 // this leaf cannot be solved for 05901 break; 05902 } 05903 ++k; 05904 } 05905 if (k == sumHashMap.end()) { 05906 foundpriority = priority; 05907 foundterm = t; 05908 if (coeff == 1 || priority == 5) foundCoeff = 1; 05909 else foundCoeff = d_theoryBitvector->multiplicative_inverse(coeff, bv_size); 05910 if (priority == 1) break; 05911 } 05912 } 05913 if (foundpriority > 6 && priority != 5) { 05914 foundpriority = 6; 05915 foundterm = t; 05916 if (coeff == 1) foundCoeff = 1; 05917 else foundCoeff = d_theoryBitvector->multiplicative_inverse(coeff, bv_size); 05918 } 05919 } 05920 } 05921 05922 bool solving = (foundpriority <= maxEffort); 05923 05924 if (foundpriority == 7) { 05925 // All coeffs are even 05926 if (known_term % 2 == 1) { 05927 Proof pf; 05928 if (withProof()) pf = newPf("canonBVEQ"); 05929 TRACE("canonBVEQ", "--> ", d_theoryBitvector->falseExpr().toString(), "\n}"); 05930 return newRWTheorem(e, d_theoryBitvector->falseExpr(), Assumptions::emptyAssump(), pf); 05931 } 05932 else foundCoeff = foundCoeff / Rational(2); 05933 if (bv_size > 1) { 05934 bv_size = bv_size - 1; 05935 modulus = pow(Rational(bv_size), Rational(2)); 05936 } 05937 } 05938 else if (!solving && (e[1] == d_theoryBitvector->newBVZeroString(bv_size))) { 05939 // if we aren't solving, and rhs was already 0, then stop here: lhs already normalized by plus canonizer 05940 // further rewriting risks a simplification loop 05941 TRACE("canonBVEQ", "--> ", e, "\n}"); 05942 return newReflTheorem(e); 05943 } 05944 05945 Rational solveCoeff = 0; 05946 // Multiply through by foundCoeff if it is not 1 05947 // Also, multiply by -1 (i.e. subtract from modulus) if solving 05948 if (solving || foundCoeff != 1) { 05949 known_term = (known_term * foundCoeff) % modulus; 05950 if (solving && known_term != 0) 05951 known_term = modulus - known_term; 05952 for(j = sumHashMap.begin(); j != sumHashMap.end(); ++j) { 05953 coeff = (*j).second; 05954 if (coeff == 0) continue; 05955 (*j).second = (coeff * foundCoeff) % modulus; 05956 if (solving) { 05957 if ((*j).first == foundterm) { 05958 // remove the leaf being solved for 05959 solveCoeff = (*j).second; 05960 (*j).second = 0; 05961 } 05962 else { 05963 (*j).second = modulus - (*j).second; 05964 } 05965 } 05966 } 05967 } 05968 05969 // Collect the terms for the new bitplus term 05970 Expr plusTerm = buildPlusTerm(bv_size, known_term, sumHashMap); 05971 05972 Expr new_lhs, new_rhs, expr_result; 05973 // Solve the equation 05974 if (solving) { 05975 DebugAssert(solveCoeff != 0, "Expected solveCoeff != 0"); 05976 if (foundpriority == 6 && d_theoryBitvector->BVSize(foundterm) < bv_size) { 05977 // zero-extend to get the right size 05978 foundterm = d_theoryBitvector->pad(bv_size, foundterm); 05979 } 05980 switch (foundpriority) { 05981 case 1: 05982 // 1. first choice: full-sized leaf 05983 // foundterm is full-sized leaf 05984 case 6: 05985 // 6. sixth choice: Not in solved form, but isolate first term 05986 // with odd coeff on lhs anyway. 05987 DebugAssert(solveCoeff == 1, "Expected coeff = 1"); 05988 new_lhs = foundterm; 05989 new_rhs = plusTerm; 05990 break; 05991 case 2: { 05992 // 2. second choice: leaf inside BVXOR 05993 DebugAssert(solveCoeff == 1, "Expected coeff = 1"); 05994 vector<Expr> rhsTerms; 05995 rhsTerms.push_back(plusTerm); 05996 for (unsigned l = 0; l < xor_size; ++l) { 05997 if (l == xor_idx) continue; 05998 rhsTerms.push_back(foundterm[l]); 05999 } 06000 new_lhs = xor_leaf; 06001 new_rhs = d_theoryBitvector->newBVXorExpr(rhsTerms); 06002 break; 06003 } 06004 case 3: 06005 // 3. third choice: full-sized extract of a leaf or over-sized leaf or extract of leaf 06006 // foundterm is full-sized extract of leaf 06007 DebugAssert(solveCoeff == 1, "Expected coeff = 1"); 06008 if (d_theoryBitvector->BVSize(foundterm) > bv_size) { 06009 if (foundterm.getOpKind() == EXTRACT) { 06010 int diff = d_theoryBitvector->BVSize(foundterm) - bv_size; 06011 int high = d_theoryBitvector->getExtractHi(foundterm); 06012 int low = d_theoryBitvector->getExtractLow(foundterm); 06013 foundterm = d_theoryBitvector->newBVExtractExpr(foundterm[0], high - diff, low); 06014 } 06015 else { 06016 foundterm = d_theoryBitvector->newBVExtractExpr(foundterm, bv_size-1, 0); 06017 } 06018 } 06019 new_lhs = foundterm; 06020 new_rhs = plusTerm; 06021 break; 06022 case 4: { 06023 // 4. fourth choice: under-sized leaf or extract of leaf 06024 // foundterm is less than full-sized extract or leaf 06025 DebugAssert(solveCoeff == 1, "Expected coeff = 1"); 06026 int foundtermsize = d_theoryBitvector->BVSize(foundterm); 06027 DebugAssert(foundtermsize < bv_size, "Expected undersized term"); 06028 new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, foundtermsize-1, 0); 06029 expr_result = foundterm.eqExpr(new_rhs); 06030 new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, bv_size-1, foundtermsize); 06031 new_lhs = d_theoryBitvector->newBVZeroString(bv_size - foundtermsize); 06032 expr_result = expr_result && new_lhs.eqExpr(new_rhs); 06033 break; 06034 } 06035 case 5: { 06036 // 5. fifth choice: even-coeff leaf or extract of leaf 06037 // foundterm has even coeff 06038 int lg = 0; 06039 for (; solveCoeff % 2 == 0; solveCoeff = solveCoeff / 2, ++lg); 06040 new_lhs = d_theoryBitvector->newBVConstExpr(solveCoeff, bv_size-lg); 06041 new_lhs = d_theoryBitvector->newBVMultPadExpr(bv_size-lg, new_lhs, foundterm); 06042 new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, bv_size-1, lg); 06043 expr_result = new_lhs.eqExpr(new_rhs); 06044 new_lhs = d_theoryBitvector->newBVZeroString(lg); 06045 new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, lg - 1, 0); 06046 expr_result = expr_result && new_lhs.eqExpr(new_rhs); 06047 break; 06048 } 06049 default: 06050 FatalAssert(false, "Expected priority < 7"); 06051 break; 06052 } 06053 } 06054 else { 06055 new_lhs = plusTerm; 06056 new_rhs = d_theoryBitvector->newBVZeroString(bv_size); 06057 } 06058 06059 if (expr_result.isNull()) { 06060 if ( new_lhs == new_rhs) { 06061 expr_result = d_theoryBitvector->trueExpr(); 06062 } 06063 else if ( new_lhs >= new_rhs) { 06064 expr_result = Expr(EQ, new_lhs, new_rhs); 06065 } 06066 else { 06067 expr_result = Expr(EQ, new_rhs, new_lhs); 06068 } 06069 } 06070 06071 Proof pf; 06072 if (withProof()) pf = newPf("canonBVEQ"); 06073 TRACE("canonBVEQ", "--> ", expr_result.toString(), "\n}"); 06074 Theorem result = newRWTheorem( e, expr_result, Assumptions::emptyAssump(), pf); 06075 return result; 06076 } 06077 06078 06079 //! BVZEROEXTEND(e, i) = zeroString \@ e 06080 // where zeroString is a string of i zeroes 06081 Theorem BitvectorTheoremProducer::zeroExtendRule(const Expr& e) { 06082 if(CHECK_PROOFS) { 06083 CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(), 06084 "input must be a bitvector. \n e = " + e.toString()); 06085 CHECK_SOUND(BVZEROEXTEND == e.getOpKind(), 06086 "input must be BVZEROEXTEND(e).\n e = " + e.toString()); 06087 } 06088 06089 int extendLen = d_theoryBitvector->getBVIndex(e); 06090 Expr res; 06091 if (extendLen == 0) { 06092 res = e[0]; 06093 } 06094 else { 06095 Expr extend = d_theoryBitvector->newBVZeroString(extendLen); 06096 res = d_theoryBitvector->newConcatExpr(extend, e[0]); 06097 } 06098 06099 Proof pf; 06100 if(withProof()) 06101 pf = newPf("zero_extend_rule"); 06102 Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf)); 06103 return result; 06104 } 06105 06106 06107 //! BVREPEAT(e, i) = e \@ e \@ ... \@ e 06108 // where e appears i times on the right 06109 Theorem BitvectorTheoremProducer::repeatRule(const Expr& e) { 06110 if(CHECK_PROOFS) { 06111 CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(), 06112 "input must be a bitvector. \n e = " + e.toString()); 06113 CHECK_SOUND(BVREPEAT == e.getOpKind(), 06114 "input must be BVREPEAT(e).\n e = " + e.toString()); 06115 CHECK_SOUND(d_theoryBitvector->getBVIndex(e) > 0, 06116 "Expected positive repeat value"); 06117 } 06118 06119 int repeatVal = d_theoryBitvector->getBVIndex(e); 06120 Expr res; 06121 if (repeatVal == 1) { 06122 res = e[0]; 06123 } 06124 else { 06125 vector<Expr> kids; 06126 for (int i = 0; i < repeatVal; ++i) { 06127 kids.push_back(e[0]); 06128 } 06129 res = d_theoryBitvector->newConcatExpr(kids); 06130 } 06131 06132 Proof pf; 06133 if(withProof()) 06134 pf = newPf("repeat_rule"); 06135 Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf)); 06136 return result; 06137 } 06138 06139 06140 //! BVROTL(e, i) = a[n-i-1:0] \@ a[n-1:n-i] 06141 // where n is the size of e and i is less than n (otherwise i mod n is used) 06142 Theorem BitvectorTheoremProducer::rotlRule(const Expr& e) { 06143 if(CHECK_PROOFS) { 06144 CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(), 06145 "input must be a bitvector. \n e = " + e.toString()); 06146 CHECK_SOUND(BVROTL == e.getOpKind(), 06147 "input must be BVROTL(e).\n e = " + e.toString()); 06148 } 06149 06150 int bvsize = d_theoryBitvector->BVSize(e); 06151 int rotation = d_theoryBitvector->getBVIndex(e); 06152 rotation = rotation % bvsize; 06153 Expr res; 06154 if (rotation == 0) { 06155 res = e[0]; 06156 } 06157 else { 06158 Expr hi = d_theoryBitvector->newBVExtractExpr(e[0],bvsize-1-rotation,0); 06159 Expr low = d_theoryBitvector->newBVExtractExpr(e[0],bvsize-1, bvsize-rotation); 06160 res = d_theoryBitvector->newConcatExpr(hi, low); 06161 } 06162 06163 Proof pf; 06164 if(withProof()) 06165 pf = newPf("rotl_rule"); 06166 Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf)); 06167 return result; 06168 } 06169 06170 06171 //! BVROTR(e, i) = a[i-1:0] \@ a[n-1:i] 06172 // where n is the size of e and i is less than n (otherwise i mod n is used) 06173 Theorem BitvectorTheoremProducer::rotrRule(const Expr& e) { 06174 if(CHECK_PROOFS) { 06175 CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(), 06176 "input must be a bitvector. \n e = " + e.toString()); 06177 CHECK_SOUND(BVROTR == e.getOpKind(), 06178 "input must be BVROTR(e).\n e = " + e.toString()); 06179 } 06180 06181 int bvsize = d_theoryBitvector->BVSize(e); 06182 int rotation = d_theoryBitvector->getBVIndex(e); 06183 rotation = rotation % bvsize; 06184 Expr res; 06185 if (rotation == 0) { 06186 res = e[0]; 06187 } 06188 else { 06189 Expr hi = d_theoryBitvector->newBVExtractExpr(e[0],rotation-1,0); 06190 Expr low = d_theoryBitvector->newBVExtractExpr(e[0],bvsize-1, rotation); 06191 res = d_theoryBitvector->newConcatExpr(hi, low); 06192 } 06193 06194 Proof pf; 06195 if(withProof()) 06196 pf = newPf("rotr_rule"); 06197 Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf)); 06198 return result; 06199 } 06200 06201 Theorem BitvectorTheoremProducer::bvURemConst(const Expr& remExpr) { 06202 const Expr& a = remExpr[0]; 06203 const Expr& b = remExpr[1]; 06204 int size = d_theoryBitvector->BVSize(remExpr); 06205 06206 Rational a_value = d_theoryBitvector->computeBVConst(a); 06207 Rational b_value = d_theoryBitvector->computeBVConst(b); 06208 06209 Expr rem; 06210 06211 if (b_value != 0) { 06212 Rational rem_value = a_value - floor(a_value / b_value)*b_value; 06213 rem = d_theoryBitvector->newBVConstExpr(rem_value, size); 06214 } else { 06215 static int div_by_zero_count = 0; 06216 div_by_zero_count ++; 06217 char var_name[10000]; 06218 sprintf(var_name, "mod_by_zero_const_%d", div_by_zero_count); 06219 rem = d_theoryBitvector->newVar(var_name, remExpr.getType()); 06220 } 06221 06222 Proof pf; 06223 if (withProof()) 06224 pf = newPf("bvUDivConst"); 06225 06226 return newRWTheorem(remExpr, rem, Assumptions::emptyAssump(), pf); 06227 } 06228 06229 Theorem BitvectorTheoremProducer::bvURemRewrite(const Expr& remExpr) { 06230 Expr a = remExpr[0]; 06231 Expr b = remExpr[1]; 06232 int size = d_theoryBitvector->BVSize(remExpr); 06233 Expr div = d_theoryBitvector->newBVUDivExpr(a, b); 06234 06235 Expr rem = d_theoryBitvector->newBVSubExpr(a, d_theoryBitvector->newBVMultExpr(size, div, b)); 06236 Proof pf; 06237 if (withProof()) 06238 pf = newPf("bvURemRewrite", remExpr); 06239 return newRWTheorem(remExpr, rem, Assumptions::emptyAssump(), pf); 06240 } 06241 06242 06243 Theorem BitvectorTheoremProducer::bvUDivConst(const Expr& divExpr) 06244 { 06245 const Expr& a = divExpr[0]; 06246 const Expr& b = divExpr[1]; 06247 int size = d_theoryBitvector->BVSize(divExpr); 06248 06249 Rational a_value = d_theoryBitvector->computeBVConst(a); 06250 Rational b_value = d_theoryBitvector->computeBVConst(b); 06251 06252 Expr div; 06253 06254 if (b_value != 0) { 06255 Rational div_value = floor(a_value / b_value); 06256 div = d_theoryBitvector->newBVConstExpr(div_value, size); 06257 } else { 06258 static int div_by_zero_count = 0; 06259 div_by_zero_count ++; 06260 char var_name[10000]; 06261 sprintf(var_name, "div_by_zero_const_%d", div_by_zero_count); 06262 div = d_theoryBitvector->newVar(var_name, divExpr.getType()); 06263 } 06264 06265 Proof pf; 06266 if (withProof()) 06267 pf = newPf("bvUDivConst"); 06268 06269 return newRWTheorem(divExpr, div, Assumptions::emptyAssump(), pf); 06270 } 06271 06272 Theorem BitvectorTheoremProducer::bvUDivTheorem(const Expr& divExpr) 06273 { 06274 int size = d_theoryBitvector->BVSize(divExpr); 06275 06276 if(CHECK_PROOFS) { 06277 CHECK_SOUND(BITVECTOR == divExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + divExpr.toString()); 06278 CHECK_SOUND(BVUDIV == divExpr.getOpKind(),"input must be BVUDIV(e).\n e = " + divExpr.toString()); 06279 } 06280 06281 const Expr a = divExpr[0]; 06282 const Expr b = divExpr[1]; 06283 06284 06285 Type type = divExpr.getType(); 06286 Expr div = d_theoryBitvector->getEM()->newBoundVarExpr(type); 06287 Expr mod = d_theoryBitvector->getEM()->newBoundVarExpr(type); 06288 vector<Expr> boundVars; 06289 boundVars.push_back(div); 06290 boundVars.push_back(mod); 06291 06292 vector<Expr> assertions; 06293 Expr pad = d_theoryBitvector->newBVConstExpr(Rational(0), size); 06294 Expr a_expanded = d_theoryBitvector->newConcatExpr(pad, a); 06295 Expr b_expanded = d_theoryBitvector->newConcatExpr(pad, b); 06296 Expr div_expanded = d_theoryBitvector->newConcatExpr(pad, div); 06297 Expr mod_expanded = d_theoryBitvector->newConcatExpr(pad, mod); 06298 assertions.push_back(a_expanded.eqExpr( 06299 d_theoryBitvector->newBVPlusExpr(2*size, 06300 d_theoryBitvector->newBVMultExpr(2*size, b_expanded, div_expanded), 06301 mod_expanded 06302 ) 06303 ) 06304 ); 06305 assertions.push_back(d_theoryBitvector->newBVLTExpr(mod, b)); 06306 06307 Expr non_zero_div = andExpr(assertions); 06308 // b != 0 -> a = b*div + mod ... 06309 Expr complete_div = (b.eqExpr(d_theoryBitvector->newBVConstExpr(Rational(0), size))).negate().impExpr(non_zero_div); 06310 // x/y = div \wedge complete_div 06311 complete_div = divExpr.eqExpr(div).andExpr(complete_div); 06312 // Close the result 06313 Expr result = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, complete_div); 06314 06315 // Make the proof 06316 Proof pf; 06317 if (withProof()) 06318 pf = newPf("bvUDiv"); 06319 06320 // Return the theorem 06321 return newTheorem(result, Assumptions::emptyAssump(), pf); 06322 } 06323 06324 Theorem BitvectorTheoremProducer::bitblastBVMult(const std::vector<Theorem>& a_bits, const std::vector<Theorem>& b_bits, 06325 const Expr& a_times_b, std::vector<Theorem>& output_bits) 06326 { 06327 if(CHECK_PROOFS) { 06328 CHECK_SOUND(a_times_b.arity() == 2, "must be a binary multiplication"); 06329 CHECK_SOUND(BITVECTOR == a_times_b.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + a_times_b.toString()); 06330 CHECK_SOUND(BVMULT == a_times_b.getOpKind(),"input must be BVMULT(e).\n e = " + a_times_b.toString()); 06331 CHECK_SOUND(a_bits.size() == b_bits.size(), "given bit expansions of different size"); 06332 CHECK_SOUND((int) a_bits.size() <= d_theoryBitvector->BVSize(a_times_b), "the expansion is bigger than the multiplier"); 06333 } 06334 06335 int size = a_bits.size(); 06336 Expr falseExpr = d_theoryBitvector->falseExpr(); 06337 06338 // DISABLED FOR NOW, WE ARENT ENSURING THAT ALL TERMS THAT ENTER BITBLASTING 06339 // ARE NON-ZERO 06340 // if (CHECK_PROOFS) { 06341 // bool all_zero = true; 06342 // Expr a = a_times_b[0]; 06343 // for (int bit = 0; bit < size; bit++) { 06344 // Theorem bit_i = a_bits[bit]; 06345 // Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(a, bit); 06346 // CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems"); 06347 // if (bit_i.getRHS() != falseExpr) all_zero = false; 06348 // } 06349 // CHECK_SOUND(!all_zero, "expected non-zero inputs"); 06350 // all_zero = true; 06351 // Expr b = a_times_b[1]; 06352 // for (int bit = 0; bit < size; bit++) { 06353 // Theorem bit_i = b_bits[bit]; 06354 // Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(b, bit); 06355 // CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems"); 06356 // if (bit_i.getRHS() != falseExpr) all_zero = false; 06357 // } 06358 // CHECK_SOUND(!all_zero, "expected non-zero inputs"); 06359 // } 06360 06361 vector<Expr> sum_bits; 06362 vector<Expr> carry_bits; 06363 06364 // Find the first non-zero bits in a and b 06365 int a_bit, b_bit; 06366 for (a_bit = size - 1; a_bit >= 0 && a_bits[a_bit].getRHS() == falseExpr; a_bit --); 06367 for (b_bit = size - 1; b_bit >= 0 && b_bits[b_bit].getRHS() == falseExpr; b_bit --); 06368 // DISABLED, SAME AS ABOVE 06369 // DebugAssert(a_bit >= 0 && b_bit >= 0, "Expected non-zero inputs"); 06370 06371 int new_size = size; 06372 if (a_bit + b_bit + 2 < new_size) new_size = a_bit + b_bit + 2; 06373 06374 // Build the first row of the multiplier 06375 for (int i = 0; i < new_size; i ++) { 06376 sum_bits.push_back(a_bits[i].getRHS().andExpr(b_bits[0].getRHS())); 06377 carry_bits.push_back(d_theoryBitvector->falseExpr()); 06378 } 06379 06380 // Now go down the rows 06381 Expr carry = d_theoryBitvector->falseExpr(); 06382 for (int row = 1; row < new_size; row ++) { 06383 for (int bit = new_size-1; bit >= row; bit --) { 06384 Expr m = a_bits[bit-row].getRHS().andExpr(b_bits[row].getRHS()); 06385 Expr sum = sum_bits[bit].iffExpr(m).iffExpr(carry_bits[bit - 1]); 06386 Expr carry = sum_bits[bit].andExpr(m).orExpr(carry_bits[bit - 1].andExpr(sum_bits[bit].orExpr(m))); 06387 sum_bits[bit] = sum; 06388 carry_bits[bit] = carry; 06389 } 06390 // The carry on the side of the multiplier 06391 carry = carry.orExpr(carry_bits[new_size - 1]); 06392 } 06393 06394 // Create all the theorems now 06395 for (int bit = 0; bit < size; bit ++) { 06396 Proof pf; 06397 if (withProof()) { 06398 pf = newPf("bitblastBVMult", a_times_b, rat(bit)); 06399 } 06400 output_bits.push_back(newRWTheorem(d_theoryBitvector->newBoolExtractExpr(a_times_b, bit), bit < new_size ? sum_bits[bit] : falseExpr, Assumptions::emptyAssump(), pf)); 06401 } 06402 06403 Theorem carry_thm; 06404 return carry_thm; 06405 } 06406 06407 Theorem BitvectorTheoremProducer::bitblastBVPlus(const std::vector<Theorem>& a_bits, const std::vector<Theorem>& b_bits, 06408 const Expr& a_plus_b, std::vector<Theorem>& output_bits) 06409 { 06410 if(CHECK_PROOFS) { 06411 CHECK_SOUND(a_plus_b.arity() == 2, "must be a binary addition"); 06412 CHECK_SOUND(BITVECTOR == a_plus_b.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + a_plus_b.toString()); 06413 CHECK_SOUND(BVPLUS == a_plus_b.getOpKind(),"input must be BVPLUS(e).\n e = " + a_plus_b.toString()); 06414 CHECK_SOUND(a_bits.size() == b_bits.size(), "given bit expansions of different size"); 06415 CHECK_SOUND((int) a_bits.size() <= d_theoryBitvector->BVSize(a_plus_b), "the expansion is bigger than the multiplier"); 06416 } 06417 06418 int size = a_bits.size(); 06419 06420 if (CHECK_PROOFS) { 06421 Expr a = a_plus_b[0]; 06422 for (int bit = 0; bit < size; bit++) { 06423 Theorem bit_i = a_bits[bit]; 06424 Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(a, bit); 06425 CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems"); 06426 } 06427 Expr b = a_plus_b[1]; 06428 for (int bit = 0; bit < size; bit++) { 06429 Theorem bit_i = b_bits[bit]; 06430 Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(b, bit); 06431 CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems"); 06432 } 06433 } 06434 06435 vector<Expr> sum_bits; 06436 06437 Expr carry = d_theoryBitvector->falseExpr(); 06438 for (int i = 0; i < size; i ++) 06439 { 06440 Expr a_i = a_bits[i].getRHS(); 06441 Expr b_i = b_bits[i].getRHS(); 06442 sum_bits.push_back(a_i.iffExpr(b_i).iffExpr(carry)); 06443 carry = a_i.andExpr(b_i).orExpr(carry.andExpr(a_i.orExpr(b_i))); 06444 } 06445 06446 // Create all the theorems now 06447 for (int bit = 0; bit < size; bit ++) { 06448 Proof pf; 06449 if (withProof()) { 06450 pf = newPf("bitblastBVPlus", a_plus_b, rat(bit)); 06451 } 06452 output_bits.push_back(newRWTheorem(d_theoryBitvector->newBoolExtractExpr(a_plus_b, bit), sum_bits[bit], Assumptions::emptyAssump(), pf)); 06453 } 06454 06455 Theorem carry_thm; 06456 return carry_thm; 06457 } 06458 06459 /** 06460 * Rewrite the signed divide in terms of the unsigned one. 06461 */ 06462 Theorem BitvectorTheoremProducer::bvSDivRewrite(const Expr& sDivExpr) 06463 { 06464 if(CHECK_PROOFS) { 06465 CHECK_SOUND(BITVECTOR == sDivExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + sDivExpr.toString()); 06466 CHECK_SOUND(BVSDIV == sDivExpr.getOpKind(),"input must be BVSDIV(e).\n e = " + sDivExpr.toString()); 06467 } 06468 06469 int m = d_theoryBitvector->BVSize(sDivExpr); 06470 06471 Proof pf; 06472 if (withProof()) pf = newPf("bvSDivRewrite", sDivExpr); 06473 06474 // (bvsdiv s t) abbreviates 06475 // (let (?msb_s (extract[|m-1|:|m-1|] s)) 06476 // (let (?msb_t (extract[|m-1|:|m-1|] t)) 06477 // (ite (and (= ?msb_s bit0) (= ?msb_t bit0)) ---------> cond1 06478 // (bvudiv s t) 06479 // (ite (and (= ?msb_s bit1) (= ?msb_t bit0)) ---------> cond2 06480 // (bvneg (bvudiv (bvneg s) t)) 06481 // (ite (and (= ?msb_s bit0) (= ?msb_t bit1)) ---------> cond3 06482 // (bvneg (bvudiv s (bvneg t))) 06483 // (bvudiv (bvneg s) (bvneg t))))))) 06484 06485 Expr s = sDivExpr[0]; 06486 Expr t = sDivExpr[1]; 06487 06488 Expr s_neg = d_theoryBitvector->newBVUminusExpr(s); 06489 Expr t_neg = d_theoryBitvector->newBVUminusExpr(t); 06490 06491 Expr msb_s = d_theoryBitvector->newBVExtractExpr(s, m-1, m-1); 06492 Expr msb_t = d_theoryBitvector->newBVExtractExpr(t, m-1, m-1); 06493 06494 Expr bit0 = d_theoryBitvector->newBVConstExpr(Rational(0), 1); 06495 Expr bit1 = d_theoryBitvector->newBVConstExpr(Rational(1), 1); 06496 06497 Expr cond1 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit0)); 06498 Expr cond2 = msb_s.eqExpr(bit1).andExpr(msb_t.eqExpr(bit0)); 06499 Expr cond3 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit1)); 06500 06501 Expr result = cond1.iteExpr( 06502 d_theoryBitvector->newBVUDivExpr(s, t), 06503 cond2.iteExpr( 06504 d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVUDivExpr(s_neg, t)), 06505 cond3.iteExpr( 06506 d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVUDivExpr(s, t_neg)), 06507 d_theoryBitvector->newBVUDivExpr(s_neg, t_neg) 06508 ) 06509 ) 06510 ); 06511 06512 return newRWTheorem(sDivExpr, result, Assumptions::emptyAssump(), pf); 06513 } 06514 06515 /** 06516 * Rewrite the signed remainder in terms of the unsigned one. 06517 */ 06518 Theorem BitvectorTheoremProducer::bvSRemRewrite(const Expr& sRemExpr) 06519 { 06520 if(CHECK_PROOFS) { 06521 CHECK_SOUND(BITVECTOR == sRemExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + sRemExpr.toString()); 06522 CHECK_SOUND(BVSREM == sRemExpr.getOpKind(),"input must be BVSDIV(e).\n e = " + sRemExpr.toString()); 06523 } 06524 06525 int m = d_theoryBitvector->BVSize(sRemExpr); 06526 06527 Proof pf; 06528 if (withProof()) pf = newPf("bvSRemRewrite", sRemExpr); 06529 06530 // (bvsrem s t) abbreviates 06531 // (let (?msb_s (extract[|m-1|:|m-1|] s)) 06532 // (let (?msb_t (extract[|m-1|:|m-1|] t)) 06533 // (ite (and (= ?msb_s bit0) (= ?msb_t bit0)) 06534 // (bvurem s t) 06535 // (ite (and (= ?msb_s bit1) (= ?msb_t bit0)) 06536 // (bvneg (bvurem (bvneg s) t)) 06537 // (ite (and (= ?msb_s bit0) (= ?msb_t bit1)) 06538 // (bvurem s (bvneg t)) 06539 // (bvneg (bvurem (bvneg s) (bvneg t)))))))) 06540 06541 Expr s = sRemExpr[0]; 06542 Expr t = sRemExpr[1]; 06543 06544 Expr s_neg = d_theoryBitvector->newBVUminusExpr(s); 06545 Expr t_neg = d_theoryBitvector->newBVUminusExpr(t); 06546 06547 Expr msb_s = d_theoryBitvector->newBVExtractExpr(s, m-1, m-1); 06548 Expr msb_t = d_theoryBitvector->newBVExtractExpr(t, m-1, m-1); 06549 06550 Expr bit0 = d_theoryBitvector->newBVConstExpr(Rational(0), 1); 06551 Expr bit1 = d_theoryBitvector->newBVConstExpr(Rational(1), 1); 06552 06553 Expr cond1 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit0)); 06554 Expr cond2 = msb_s.eqExpr(bit1).andExpr(msb_t.eqExpr(bit0)); 06555 Expr cond3 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit1)); 06556 06557 Expr result = cond1.iteExpr( 06558 d_theoryBitvector->newBVURemExpr(s, t), 06559 cond2.iteExpr( 06560 d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVURemExpr(s_neg, t)), 06561 cond3.iteExpr( 06562 d_theoryBitvector->newBVURemExpr(s, t_neg), 06563 d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVURemExpr(s_neg, t_neg)) 06564 ) 06565 ) 06566 ); 06567 06568 return newRWTheorem(sRemExpr, result, Assumptions::emptyAssump(), pf); 06569 } 06570 06571 /** 06572 * Rewrite the signed mod in terms of the unsigned one. 06573 */ 06574 Theorem BitvectorTheoremProducer::bvSModRewrite(const Expr& sModExpr) 06575 { 06576 if(CHECK_PROOFS) { 06577 CHECK_SOUND(BITVECTOR == sModExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + sModExpr.toString()); 06578 CHECK_SOUND(BVSMOD == sModExpr.getOpKind(),"input must be BVSDIV(e).\n e = " + sModExpr.toString()); 06579 } 06580 06581 int m = d_theoryBitvector->BVSize(sModExpr); 06582 06583 Proof pf; 06584 if (withProof()) pf = newPf("bvSModRewrite", sModExpr); 06585 06586 // (bvsmod s t) abbreviates 06587 // (let ((?msb_s ((_ extract |m-1| |m-1|) s)) 06588 // (?msb_t ((_ extract |m-1| |m-1|) t))) 06589 // (let ((abs_s (ite (= ?msb_s #b0) s (bvneg s))) 06590 // (abs_t (ite (= ?msb_t #b0) t (bvneg t)))) 06591 // (let ((u (bvurem abs_s abs_t))) 06592 // (ite (= u (_ bv0 m)) 06593 // u 06594 // (ite (and (= ?msb_s #b0) (= ?msb_t #b0)) 06595 // u 06596 // (ite (and (= ?msb_s #b1) (= ?msb_t #b0)) 06597 // (bvadd (bvneg u) t) 06598 // (ite (and (= ?msb_s #b0) (= ?msb_t #b1)) 06599 // (bvadd u t) 06600 // (bvneg u)))))))) 06601 06602 Expr s = sModExpr[0]; 06603 Expr t = sModExpr[1]; 06604 06605 Expr msb_s = d_theoryBitvector->newBVExtractExpr(s, m-1, m-1); 06606 Expr msb_t = d_theoryBitvector->newBVExtractExpr(t, m-1, m-1); 06607 06608 Expr bit0 = d_theoryBitvector->newBVConstExpr(Rational(0), 1); 06609 Expr bit1 = d_theoryBitvector->newBVConstExpr(Rational(1), 1); 06610 06611 Expr abs_s = msb_s.eqExpr(bit0).iteExpr(s, d_theoryBitvector->newBVUminusExpr(s)); 06612 Expr abs_t = msb_t.eqExpr(bit0).iteExpr(t, d_theoryBitvector->newBVUminusExpr(t)); 06613 06614 Expr u = d_theoryBitvector->newBVURemExpr(abs_s, abs_t); 06615 06616 Expr cond0 = u.eqExpr(d_theoryBitvector->newBVConstExpr(Rational(0), m)); 06617 Expr cond1 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit0)); 06618 Expr cond2 = msb_s.eqExpr(bit1).andExpr(msb_t.eqExpr(bit0)); 06619 Expr cond3 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit1)); 06620 06621 Expr result = cond0.iteExpr(u, 06622 cond1.iteExpr(u, 06623 cond2.iteExpr( 06624 d_theoryBitvector->newBVPlusExpr(m, d_theoryBitvector->newBVUminusExpr(u), t), 06625 cond3.iteExpr(d_theoryBitvector->newBVPlusExpr(m, u, t), 06626 d_theoryBitvector->newBVUminusExpr(u))))); 06627 06628 return newRWTheorem(sModExpr, result, Assumptions::emptyAssump(), pf); 06629 } 06630 06631 Theorem BitvectorTheoremProducer::zeroBVOR(const Expr& orEqZero) 06632 { 06633 if(CHECK_PROOFS) { 06634 CHECK_SOUND(orEqZero.isEq(), "input must be an equality. \n e = " + orEqZero.toString()); 06635 CHECK_SOUND(orEqZero[0].getKind() == BVOR, "left-hand side must be a bitwise or. \n e = " + orEqZero.toString()); 06636 CHECK_SOUND(orEqZero[1].getKind() == BVCONST, "right-hand side must be a constant or. \n e = " + orEqZero.toString()); 06637 CHECK_SOUND(d_theoryBitvector->computeBVConst(orEqZero[1]) == 0, "right-hand side must be 0. \n e = " + orEqZero.toString()); 06638 } 06639 06640 vector<Expr> conjuncts; 06641 06642 for (int disjunct = 0; disjunct < orEqZero[0].arity(); disjunct ++) 06643 conjuncts.push_back(orEqZero[0][disjunct].eqExpr(orEqZero[1])); 06644 06645 Expr result = andExpr(conjuncts); 06646 06647 Proof pf; 06648 if (withProof()) pf = newPf("zeroBVOR", orEqZero); 06649 06650 return newRWTheorem(orEqZero, result, Assumptions::emptyAssump(), pf); 06651 } 06652 06653 Theorem BitvectorTheoremProducer::oneBVAND(const Expr& andEqOne) 06654 { 06655 if(CHECK_PROOFS) { 06656 CHECK_SOUND(andEqOne.isEq(), "input must be an equality. \n e = " + andEqOne.toString()); 06657 CHECK_SOUND(andEqOne[0].getKind() == BVAND, "left-hand side must be a bitwise and. \n e = " + andEqOne.toString()); 06658 CHECK_SOUND(andEqOne[1].getKind() == BVCONST, "right-hand side must be a constant or. \n e = " + andEqOne.toString()); 06659 CHECK_SOUND(d_theoryBitvector->computeBVConst(andEqOne[1]) == pow(d_theoryBitvector->BVSize(andEqOne[1]), (Unsigned)2) - 1, "right-hand side must be 1^n. \n e = " + andEqOne.toString()); 06660 } 06661 06662 vector<Expr> conjuncts; 06663 06664 for (int conjunct = 0; conjunct < andEqOne[0].arity(); conjunct ++) 06665 conjuncts.push_back(andEqOne[0][conjunct].eqExpr(andEqOne[1])); 06666 06667 Expr result = andExpr(conjuncts); 06668 06669 Proof pf; 06670 if (withProof()) pf = newPf("oneBVAND", andEqOne); 06671 06672 return newRWTheorem(andEqOne, result, Assumptions::emptyAssump(), pf); 06673 } 06674 06675 Theorem BitvectorTheoremProducer::constEq(const Expr& eq) 06676 { 06677 if(CHECK_PROOFS) { 06678 CHECK_SOUND(eq.isEq(), "input must be an equality. \n e = " + eq.toString()); 06679 CHECK_SOUND(eq[0].getKind() == BVCONST, "left-hand side must be a constant. \n e = " + eq.toString()); 06680 CHECK_SOUND(eq[1].getKind() == BVCONST, "right-hand side must be a constant. \n e = " + eq.toString()); 06681 } 06682 06683 Expr result = eq[0] == eq[1] ? d_theoryBitvector->trueExpr() : d_theoryBitvector->falseExpr(); 06684 06685 Proof pf; 06686 if (withProof()) pf = newPf("constEq", eq); 06687 06688 return newRWTheorem(eq, result, Assumptions::emptyAssump(), pf); 06689 } 06690 06691 bool BitvectorTheoremProducer::solveExtractOverlapApplies(const Expr& eq) 06692 { 06693 // Both sides should be an extract 06694 if (eq[0].getOpKind() != EXTRACT) return false; 06695 if (eq[1].getOpKind() != EXTRACT) return false; 06696 // Terms under extract should be identical 06697 if (eq[0][0] != eq[1][0]) return false; 06698 // We have x[i:j] == x[k:l] 06699 int i = d_theoryBitvector->getExtractHi(eq[0]); 06700 int j = d_theoryBitvector->getExtractLow(eq[0]); 06701 int k = d_theoryBitvector->getExtractHi(eq[1]); 06702 int l = d_theoryBitvector->getExtractLow(eq[1]); 06703 // They can't be equal, so we either have 06704 // i > k >= j > l or 06705 // k > i >= l > j 06706 if (i == k) return false; 06707 else if (i > k) 06708 return (k >= j && j > l); 06709 else 06710 return (i >= l && l > j); 06711 } 06712 06713 Theorem BitvectorTheoremProducer::solveExtractOverlap(const Expr& eq) 06714 { 06715 Expr res; 06716 06717 if (CHECK_PROOFS) 06718 CHECK_SOUND(solveExtractOverlapApplies(eq), "solveExtractOvelap does not apply to " + eq.toString()); 06719 06720 // Left and right side of the equation 06721 Expr lhs = eq[0]; 06722 Expr rhs = eq[1]; 06723 06724 // We have x[i:j] == x[k:l] 06725 int i = d_theoryBitvector->getExtractHi(lhs); 06726 int j = d_theoryBitvector->getExtractLow(lhs); 06727 int k = d_theoryBitvector->getExtractHi(rhs); 06728 int l = d_theoryBitvector->getExtractLow(rhs); 06729 06730 // We only do case where i > k 06731 if (i > k) 06732 { 06733 vector<Expr> terms; 06734 vector<Expr> boundVars; 06735 06736 // Get the term 06737 Expr x = lhs[0]; 06738 int x_size = d_theoryBitvector->BVSize(x); 06739 06740 // If there is a initial part of x, put it in 06741 if (i < x_size - 1) { 06742 Expr x_begin = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(x_size - i - 1)); 06743 terms.push_back(x_begin); 06744 boundVars.push_back(x_begin); 06745 } 06746 06747 if (2*k + 1 <= i + j) 06748 { 06749 // Case when the overlap is smaller then the rest 06750 // i k j l 06751 // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 06752 // xxxxAAAAABBBBBBBBBBBBAAAAABBBBBBBBBBBBAAAAAxxxxx 06753 // a b c d e 06754 int o_size = k - j + 1; // Overlap size 06755 bool no_rest = (2*k + 1 == i + j); 06756 06757 // Make The a = c = e expression 06758 Expr a = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(o_size)); 06759 boundVars.push_back(a); 06760 terms.push_back(a); 06761 06762 if (no_rest) { 06763 // c and e 06764 terms.push_back(a); 06765 terms.push_back(a); 06766 } else { 06767 // Make the b = d expression 06768 Expr b = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(i - k - o_size)); 06769 boundVars.push_back(b); 06770 terms.push_back(b); 06771 terms.push_back(a); 06772 terms.push_back(b); 06773 terms.push_back(a); 06774 } 06775 } 06776 else 06777 { 06778 // Case when the overlap is bigger then the rest 06779 // i k j l 06780 // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 06781 // xxxxABCABCABCABCABCABCABCABCABCABCABCABCABCxxxxx 06782 int o_size = k - j + 1; // Overlap size 06783 int r_size = i - k; // Rest szie 06784 // Smallest slice 06785 int d = gcd(Rational(o_size), Rational(r_size)).getInt(); 06786 // Number of different pieces 06787 int different_pieces = r_size / d; // How many different slices will we get 06788 // Add all the initial different pieces 06789 for (int p = 0; p < different_pieces; p ++) { 06790 Expr piece = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(d)); 06791 boundVars.push_back(piece); 06792 terms.push_back(piece); 06793 } 06794 // Add the rest of them cyclicly 06795 int other_pieces = (o_size + r_size) / d; 06796 for (int p = 0; p < other_pieces; p ++) 06797 terms.push_back(terms[terms.size() - different_pieces]); 06798 } 06799 06800 // If there is a ending part of x, put it in 06801 if (l > 0) { 06802 Expr x_end = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(l)); 06803 terms.push_back(x_end); 06804 boundVars.push_back(x_end); 06805 } 06806 06807 res = x.eqExpr(d_theoryBitvector->newConcatExpr(terms)); 06808 res = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, res); 06809 06810 } else 06811 // Other case by symmetry 06812 res = solveExtractOverlap(rhs.eqExpr(lhs)).getRHS(); 06813 06814 Proof pf; 06815 if (withProof()) pf = newPf("solveExtractOverlap", eq); 06816 06817 return newTheorem(eq.iffExpr(res), Assumptions::emptyAssump(), pf); 06818 } 06819