00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
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
00064
00065
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
00099
00100
00101
00102
00103
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
00129
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
00140
00141
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
00223
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
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
00300
00301
00302
00303
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
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
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
00379 Theorem
00380 BitvectorTheoremProducer::bitExtractSXRule(const Expr& e, int i) {
00381
00382
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
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
00430
00431
00432
00433
00434
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
00482
00483
00484
00485
00486
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
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
00501
00502
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
00522 output =
00523 eKind==BVSLT ?
00524 MSB0isOne.andExpr(MSB1isZero) :
00525 MSB0isOne.orExpr(MSB1isZero);
00526 } else {
00527
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
00535
00536
00537
00538
00539
00540
00541 if(-1 != b0 && -1 !=b1) {
00542
00543 if(b0 == 1 && b1 == 0)
00544 output = tExpr;
00545
00546 else if(b0 == 0 && b1 == 1)
00547 output = fExpr;
00548
00549 else {
00550 output = newBVLT;
00551 }
00552 }
00553 else if(-1 != b0 && -1 == b1) {
00554
00555
00556
00557
00558
00559
00560
00561 output =
00562 (b0==0) ?
00563
00564 MSB1isZero.andExpr(newBVLT) :
00565
00566 MSB1isZero.orExpr(MSB1isOne.andExpr(newBVLT));
00567 }
00568 else if(-1 == b0 && -1 != b1) {
00569
00570
00571
00572
00573
00574
00575
00576 output =
00577 (b1==0) ?
00578
00579 MSB0isOne.orExpr(MSB0isZero.andExpr(newBVLT)) :
00580
00581 MSB0isOne.andExpr(newBVLT);
00582 } else {
00583
00584
00585
00586 Expr k0 = MSB0isOne.andExpr(MSB1isZero);
00587
00588
00589 Expr k1 = MSB0.eqExpr(MSB1);
00590
00591
00592
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
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
00629
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
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
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
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
00754
00755
00756
00757
00758
00759
00760
00761
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
00837 if (b1.isFalse() && b2.isTrue())
00838 output = trueExpression;
00839 else if (b1.isTrue() && b2.isFalse())
00840 output = falseExpression;
00841 else if (e0len==1) {
00842
00843 if (kind==BVLE && (b1.isFalse() || b2.isTrue()))
00844 output = trueExpression;
00845 else if (kind==BVLT && (b2.isFalse() || b1.isTrue()))
00846 output = falseExpression;
00847 }
00848
00849
00850 if (output.isNull()) {
00851
00852
00853 if (kind == BVLT || e0len > 1) {
00854 output = (!b1) && b2;
00855 }
00856 else {
00857 output = (!b1) || b2;
00858 }
00859
00860 if(e0len > 1) {
00861
00862 Expr e0_extract =
00863 d_theoryBitvector->newBVExtractExpr(e[0],e0len-2,0);
00864
00865 Expr e1_extract =
00866 d_theoryBitvector->newBVExtractExpr(e[1],e1len-2,0);
00867
00868 Expr a;
00869 if(kind==BVLT)
00870
00871 a = d_theoryBitvector->newBVLTExpr(e0_extract,e1_extract);
00872 else
00873
00874 a = d_theoryBitvector->newBVLEExpr(e0_extract,e1_extract);
00875
00876
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
00889
00890
00891
00892
00893
00894
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
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
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
00977 Theorem BitvectorTheoremProducer::bitExtractConstant(const Expr & x, int i)
00978 {
00979 TRACE("bitvector", "bitExtractConstant(", x, ", "+ int2string(i) +" ) {");
00980 if(CHECK_PROOFS) {
00981
00982 CHECK_SOUND(BVCONST == x.getKind(),
00983 "BitvectorTheoremProducer::bitExtractConstant:"
00984 "the bitvector must be a constant.");
00985
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
00994 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
00995
00996
00997
00998
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
01014
01015
01016
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
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
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
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
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
01114 switch(k.size()) {
01115 case 0:
01116
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
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
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
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
01204
01205
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
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
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
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
01285
01286
01287
01288 rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit);
01289
01290
01291
01292 } else
01293
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
01385
01386
01387
01388 rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit);
01389
01390 } else
01391
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
01403
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
01719
01720
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
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
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
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
01773
01774
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
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
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
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
01827
01828
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
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
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
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
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
01893 Theorem BitvectorTheoremProducer::eqConst(const Expr& e) {
01894 if(CHECK_PROOFS) {
01895
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
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
01944 Theorem BitvectorTheoremProducer::leftShiftToConcat(const Expr& e) {
01945 if(CHECK_PROOFS) {
01946
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
01968 Theorem BitvectorTheoremProducer::constWidthLeftShiftToConcat(const Expr& e) {
01969 if(CHECK_PROOFS) {
01970
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
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
02033 Theorem BitvectorTheoremProducer::bvshlToConcat(const Expr& e) {
02034 if(CHECK_PROOFS) {
02035
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
02065
02066
02067
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
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
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
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
02269
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;
02286 if(k == 0) {
02287
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
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
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
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
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
02345 int log2 = 0;
02346 for(int i=1; i < numKids; i *=2, log2++);
02347 if(log2+maxKidSize > bvplusSize) {
02348
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
02365 Theorem BitvectorTheoremProducer::extractConst(const Expr& e) {
02366 if(CHECK_PROOFS) {
02367
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
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
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
02433 CHECK_SOUND(0 <= low && low <= hi,
02434 "BitvectorTheoremProducer::extractExtract: e = "+e.toString());
02435
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
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
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
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
02484 CHECK_SOUND(e0.getOpKind() == CONCAT,
02485 "BitvectorTheoremProducer::extractConcat: e0 = "
02486 +e0.toString());
02487 }
02488
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) {
02500 if(hi >= newWidth) {
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
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 }
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
02530
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
02550 CHECK_SOUND(0 <= low && low <= hi,
02551 "BitvectorTheoremProducer::"+pfName+": e = "+e.toString());
02552
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
02570 Theorem
02571 BitvectorTheoremProducer::extractAnd(const Expr& e) {
02572 return extractBitwise(e, BVAND, "extract_and");
02573 }
02574
02575
02576
02577 Theorem
02578 BitvectorTheoremProducer::extractOr(const Expr& e) {
02579 return extractBitwise(e, BVOR, "extract_or");
02580 }
02581
02582
02583
02584 Theorem
02585 BitvectorTheoremProducer::extractNeg(const Expr& e) {
02586 return extractBitwise(e, BVNEG, "extract_neg");
02587 }
02588
02589
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
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
02655 Theorem BitvectorTheoremProducer::negConst(const Expr& e) {
02656 if(CHECK_PROOFS) {
02657
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
02677 Theorem
02678 BitvectorTheoremProducer::negConcat(const Expr& e) {
02679 if(CHECK_PROOFS) {
02680
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
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
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
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
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
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
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
02842 Theorem BitvectorTheoremProducer::bitwiseConst(const Expr& e,
02843 const vector<int>& idxs,
02844 int kind)
02845 {
02846 if(CHECK_PROOFS) {
02847
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
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);
02873 size_t ii(0);
02874 int idx(idxs[0]);
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
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
02893 if (ii < idxs.size() - 1)
02894 idx = idxs[++ii];
02895 else
02896 idx = e.arity();
02897 }
02898 else
02899 kids.push_back(ei);
02900 }
02901
02902 kids[0] = d_theoryBitvector->newBVConstExpr(bits);
02903
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
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
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
02940 vector<Expr> concatKids;
02941
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
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
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
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
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
03006 flag = sameKidCheck(t, likeTerms);
03007 switch(flag) {
03008 case 0:
03009
03010 break;
03011 case 1:
03012
03013 if (kind == BVXOR) {
03014
03015 likeTerms.erase(t);
03016 }
03017 break;
03018 case -1:
03019
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
03067
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
03154
03155
03156
03157
03158
03159
03160 int BitvectorTheoremProducer::sameKidCheck(const Expr& e,
03161 ExprMap<int>& likeTerms) {
03162
03163 int flag = 0;
03164
03165
03166 ExprMap<int>::iterator it = likeTerms.find(e);
03167
03168
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
03190 return 1;
03191 }
03192
03193
03194
03195 Theorem BitvectorTheoremProducer::concatConst(const Expr& e) {
03196 if(CHECK_PROOFS) {
03197
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
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
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
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];
03253
03254 if(CHECK_PROOFS) {
03255
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
03290 Theorem BitvectorTheoremProducer::bvplusConst(const Expr& e) {
03291 if(CHECK_PROOFS) {
03292
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
03301
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
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
03328
03329 Theorem BitvectorTheoremProducer::bvmultConst(const Expr& e) {
03330 if(CHECK_PROOFS) {
03331
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
03339 Rational x = d_theoryBitvector->computeBVConst(e[1]) * c;
03340
03341
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
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
03419
03420
03421
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
03441 Expr zero = d_theoryBitvector->newBVZeroString(len-size);
03442 res = d_theoryBitvector->newConcatExpr(zero,e);
03443 }
03444 return res;
03445 }
03446
03447
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
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
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
03539
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
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
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
03652
03653
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
03672
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
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
03712 likeTerms[negTerm] += -coefficient;
03713 plusConstant+= -1;
03714 }
03715 }
03716 if (!foundNegated)
03717
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
03731 for(; i!=iend; ++i) {
03732 const Expr s = *i;
03733 switch(s.getOpKind()) {
03734 case BVMULT: {
03735
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 {
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
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
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
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
03798
03799
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
03807
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
03834 plusConstant = boundedModulo(plusConstant, power2, 0);
03835
03836
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
03848
03849 switch(items.size()) {
03850 case 0:
03851
03852 return d_theoryBitvector->newBVZeroString(bvplusLength);
03853
03854 case 1:
03855
03856 return items[0];
03857
03858 default:
03859
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
03884 CHECK_SOUND(bvLength==bvplusLength,
03885 "TheoryBitvector::combineLikeTerms: "
03886 "BVPLUS must be padded:\n e = " + e.toString());
03887
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
03951 Expr zeroStr = d_theoryBitvector->newBVZeroString(bvLength);
03952
03953 if(e[0] == e[1])
03954 output = Expr(EQ, zeroStr, zeroStr);
03955 else {
03956
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
03972 Expr uminus = d_theoryBitvector->newBVUminusExpr(newRhs);
03973
03974 k.push_back(uminus);
03975
03976 Expr lhsMinusRhs = d_theoryBitvector->newBVPlusExpr(bvLength,k);
03977
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
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
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
04022 if(d_theoryBitvector->computeBVConst(e[0]) == 0)
04023 output = e[0];
04024 else {
04025
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
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
04060 Expr output;
04061 int e0Length = d_theoryBitvector->BVSize(e[0]);
04062
04063 Rational coeff = d_theoryBitvector->computeNegBVConst(e[0][0]);
04064 if(0 == coeff)
04065
04066 output = d_theoryBitvector->newBVZeroString(e0Length);
04067 else if (1 == coeff)
04068
04069 output = e[0][1];
04070 else {
04071
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
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
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
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
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
04156 output = d_theoryBitvector->newBVZeroString(bvLength);
04157 else if (1 == negatedcoeff)
04158
04159 output = e010;
04160 else {
04161
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
04173 Theorem
04174 BitvectorTheoremProducer::bvuminusBVPlus(const Expr& e) {
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200
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
04260 if(bvplusLen == extractHi+1)
04261 return d_theoryBitvector->reflexivityRule(e);
04262
04263
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
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
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
04311
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
04331
04332
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
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
04369
04370
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
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
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
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
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
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501
04502
04503
04504
04505
04506
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
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
04626 int bv_size= d_theoryBitvector->BVSize(e);
04627 Expr new_expr;
04628 vector<Expr> vars;
04629
04630
04631
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
04647
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
04654
04655
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
04686
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
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
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
04762
04763
04764
04765
04766
04767
04768
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
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
04788
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
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
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
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
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
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
04856 if (temp_coeff == 0 || new_prod.isNull()) {
04857
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
04877 return result;
04878 }
04879
04880
04881
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
04891
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
04922
04923
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
04955
04956
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
04969
04970
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
04979
04980 if (nonzero) return d_theoryBitvector->reflexivityRule(e);
04981 nonzero = true;
04982 if (size < chopSize) chopSize = size;
04983 term = last;
04984 }
04985
04986
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
05073
05074 sumHashMap[ kid ] = sumHashMap[ kid ] + coeff;
05075 break;
05076 }
05077 }
05078
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
05098
05099 sumHashMap[ kid ] = sumHashMap[ kid ] + coeff;
05100 break;
05101 }
05102 }
05103
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
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
05128 if (false && kidSize < bv_size) {
05129
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
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
05188
05189
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
05200
05201
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
05210
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
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
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
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
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
05316 if (coeff == 1 && nbits == bv_size) {
05317 if (nbits == 1 && known_term == 1) {
05318
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));
05332
05333 Expr concatTerm;
05334
05335
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
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
05359 if (nbits + lg > bv_size) {
05360
05361 int diff = nbits + lg - bv_size;
05362 int high, low;
05363 if (term.getOpKind() == EXTRACT) {
05364
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
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
05426 negate = true;
05427 concatTerm = concatTerm[0];
05428 }
05429 DebugAssert(!found || k == 0,
05430 "Too big only OK for first child");
05431
05432 int diff = lg + nbits - bits;
05433 int high, low;
05434 if (concatTerm.getOpKind() == EXTRACT) {
05435
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
05464 concatKids[i] = d_theoryBitvector->newConcatExpr(tmp);
05465 }
05466 else {
05467
05468 concatKids.push_back(d_theoryBitvector->newConcatExpr(tmp));
05469 }
05470 }
05471 }
05472
05473 known_term = known_term % modulus;
05474
05475
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
05514 Expr expr_result;
05515
05516
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
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
05568
05569 ExprMap<Rational> sumHashMap;
05570 int bv_size = d_theoryBitvector->BVSize( e );
05571 Rational known_term;
05572
05573
05574 getPlusTerms(e, known_term, sumHashMap);
05575
05576
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
05602
05603
05604
05605
05606
05607
05608
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
05688
05689
05690
05691
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
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
05776
05777
05778
05779
05780
05781
05782
05783
05784
05785
05786
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
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
05894 leaf = t[xor_idx];
05895 xor_leaf = leaf;
05896 k = sumHashMap.begin();
05897 continue;
05898 }
05899 }
05900
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
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
05940
05941 TRACE("canonBVEQ", "--> ", e, "\n}");
05942 return newReflTheorem(e);
05943 }
05944
05945 Rational solveCoeff = 0;
05946
05947
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
05959 solveCoeff = (*j).second;
05960 (*j).second = 0;
05961 }
05962 else {
05963 (*j).second = modulus - (*j).second;
05964 }
05965 }
05966 }
05967 }
05968
05969
05970 Expr plusTerm = buildPlusTerm(bv_size, known_term, sumHashMap);
05971
05972 Expr new_lhs, new_rhs, expr_result;
05973
05974 if (solving) {
05975 DebugAssert(solveCoeff != 0, "Expected solveCoeff != 0");
05976 if (foundpriority == 6 && d_theoryBitvector->BVSize(foundterm) < bv_size) {
05977
05978 foundterm = d_theoryBitvector->pad(bv_size, foundterm);
05979 }
05980 switch (foundpriority) {
05981 case 1:
05982
05983
05984 case 6:
05985
05986
05987 DebugAssert(solveCoeff == 1, "Expected coeff = 1");
05988 new_lhs = foundterm;
05989 new_rhs = plusTerm;
05990 break;
05991 case 2: {
05992
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
06006
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
06024
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
06037
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
06080
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
06108
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
06141
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
06172
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
06309 Expr complete_div = (b.eqExpr(d_theoryBitvector->newBVConstExpr(Rational(0), size))).negate().impExpr(non_zero_div);
06310
06311 complete_div = divExpr.eqExpr(div).andExpr(complete_div);
06312
06313 Expr result = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, complete_div);
06314
06315
06316 Proof pf;
06317 if (withProof())
06318 pf = newPf("bvUDiv");
06319
06320
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
06339
06340
06341
06342
06343
06344
06345
06346
06347
06348
06349
06350
06351
06352
06353
06354
06355
06356
06357
06358
06359
06360
06361 vector<Expr> sum_bits;
06362 vector<Expr> carry_bits;
06363
06364
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
06369
06370
06371 int new_size = size;
06372 if (a_bit + b_bit + 2 < new_size) new_size = a_bit + b_bit + 2;
06373
06374
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
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
06391 carry = carry.orExpr(carry_bits[new_size - 1]);
06392 }
06393
06394
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
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
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
06475
06476
06477
06478
06479
06480
06481
06482
06483
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
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
06531
06532
06533
06534
06535
06536
06537
06538
06539
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
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
06587
06588
06589
06590
06591
06592
06593
06594
06595
06596
06597 Expr s = sModExpr[0];
06598 Expr t = sModExpr[1];
06599
06600 Expr s_neg = d_theoryBitvector->newBVUminusExpr(s);
06601 Expr t_neg = d_theoryBitvector->newBVUminusExpr(t);
06602
06603 Expr msb_s = d_theoryBitvector->newBVExtractExpr(s, m-1, m-1);
06604 Expr msb_t = d_theoryBitvector->newBVExtractExpr(t, m-1, m-1);
06605
06606 Expr bit0 = d_theoryBitvector->newBVConstExpr(Rational(0), 1);
06607 Expr bit1 = d_theoryBitvector->newBVConstExpr(Rational(1), 1);
06608
06609 Expr cond1 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit0));
06610 Expr cond2 = msb_s.eqExpr(bit1).andExpr(msb_t.eqExpr(bit0));
06611 Expr cond3 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit1));
06612
06613 Expr result = cond1.iteExpr(
06614 d_theoryBitvector->newBVURemExpr(s, t),
06615 cond2.iteExpr(
06616 d_theoryBitvector->newBVPlusExpr(m, d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVURemExpr(s_neg, t)), t),
06617 cond3.iteExpr(
06618 d_theoryBitvector->newBVPlusExpr(m, d_theoryBitvector->newBVURemExpr(s, t_neg), t),
06619 d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVURemExpr(s_neg, t_neg))
06620 )
06621 )
06622 );
06623
06624 return newRWTheorem(sModExpr, result, Assumptions::emptyAssump(), pf);
06625 }
06626
06627 Theorem BitvectorTheoremProducer::zeroBVOR(const Expr& orEqZero)
06628 {
06629 if(CHECK_PROOFS) {
06630 CHECK_SOUND(orEqZero.isEq(), "input must be an equality. \n e = " + orEqZero.toString());
06631 CHECK_SOUND(orEqZero[0].getKind() == BVOR, "left-hand side must be a bitwise or. \n e = " + orEqZero.toString());
06632 CHECK_SOUND(orEqZero[1].getKind() == BVCONST, "right-hand side must be a constant or. \n e = " + orEqZero.toString());
06633 CHECK_SOUND(d_theoryBitvector->computeBVConst(orEqZero[1]) == 0, "right-hand side must be 0. \n e = " + orEqZero.toString());
06634 }
06635
06636 vector<Expr> conjuncts;
06637
06638 for (int disjunct = 0; disjunct < orEqZero[0].arity(); disjunct ++)
06639 conjuncts.push_back(orEqZero[0][disjunct].eqExpr(orEqZero[1]));
06640
06641 Expr result = andExpr(conjuncts);
06642
06643 Proof pf;
06644 if (withProof()) pf = newPf("zeroBVOR", orEqZero);
06645
06646 return newRWTheorem(orEqZero, result, Assumptions::emptyAssump(), pf);
06647 }
06648
06649 Theorem BitvectorTheoremProducer::oneBVAND(const Expr& andEqOne)
06650 {
06651 if(CHECK_PROOFS) {
06652 CHECK_SOUND(andEqOne.isEq(), "input must be an equality. \n e = " + andEqOne.toString());
06653 CHECK_SOUND(andEqOne[0].getKind() == BVAND, "left-hand side must be a bitwise and. \n e = " + andEqOne.toString());
06654 CHECK_SOUND(andEqOne[1].getKind() == BVCONST, "right-hand side must be a constant or. \n e = " + andEqOne.toString());
06655 CHECK_SOUND(d_theoryBitvector->computeBVConst(andEqOne[1]) == pow(d_theoryBitvector->BVSize(andEqOne[1]), 2) - 1, "right-hand side must be 1^n. \n e = " + andEqOne.toString());
06656 }
06657
06658 vector<Expr> conjuncts;
06659
06660 for (int conjunct = 0; conjunct < andEqOne[0].arity(); conjunct ++)
06661 conjuncts.push_back(andEqOne[0][conjunct].eqExpr(andEqOne[1]));
06662
06663 Expr result = andExpr(conjuncts);
06664
06665 Proof pf;
06666 if (withProof()) pf = newPf("oneBVAND", andEqOne);
06667
06668 return newRWTheorem(andEqOne, result, Assumptions::emptyAssump(), pf);
06669 }
06670
06671 Theorem BitvectorTheoremProducer::constEq(const Expr& eq)
06672 {
06673 if(CHECK_PROOFS) {
06674 CHECK_SOUND(eq.isEq(), "input must be an equality. \n e = " + eq.toString());
06675 CHECK_SOUND(eq[0].getKind() == BVCONST, "left-hand side must be a constant. \n e = " + eq.toString());
06676 CHECK_SOUND(eq[1].getKind() == BVCONST, "right-hand side must be a constant. \n e = " + eq.toString());
06677 }
06678
06679 Expr result = eq[0] == eq[1] ? d_theoryBitvector->trueExpr() : d_theoryBitvector->falseExpr();
06680
06681 Proof pf;
06682 if (withProof()) pf = newPf("constEq", eq);
06683
06684 return newRWTheorem(eq, result, Assumptions::emptyAssump(), pf);
06685 }
06686
06687 bool BitvectorTheoremProducer::solveExtractOverlapApplies(const Expr& eq)
06688 {
06689
06690 if (eq[0].getOpKind() != EXTRACT) return false;
06691 if (eq[1].getOpKind() != EXTRACT) return false;
06692
06693 if (eq[0][0] != eq[1][0]) return false;
06694
06695 int i = d_theoryBitvector->getExtractHi(eq[0]);
06696 int j = d_theoryBitvector->getExtractLow(eq[0]);
06697 int k = d_theoryBitvector->getExtractHi(eq[1]);
06698 int l = d_theoryBitvector->getExtractLow(eq[1]);
06699
06700
06701
06702 if (i == k) return false;
06703 else if (i > k)
06704 return (k >= j && j > l);
06705 else
06706 return (i >= l && l > j);
06707 }
06708
06709 Theorem BitvectorTheoremProducer::solveExtractOverlap(const Expr& eq)
06710 {
06711 Expr res;
06712
06713 if (CHECK_PROOFS)
06714 CHECK_SOUND(solveExtractOverlapApplies(eq), "solveExtractOvelap does not apply to " + eq.toString());
06715
06716
06717 Expr lhs = eq[0];
06718 Expr rhs = eq[1];
06719
06720
06721 int i = d_theoryBitvector->getExtractHi(lhs);
06722 int j = d_theoryBitvector->getExtractLow(lhs);
06723 int k = d_theoryBitvector->getExtractHi(rhs);
06724 int l = d_theoryBitvector->getExtractLow(rhs);
06725
06726
06727 if (i > k)
06728 {
06729 vector<Expr> terms;
06730 vector<Expr> boundVars;
06731
06732
06733 Expr x = lhs[0];
06734 int x_size = d_theoryBitvector->BVSize(x);
06735
06736
06737 if (i < x_size - 1) {
06738 Expr x_begin = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(x_size - i - 1));
06739 terms.push_back(x_begin);
06740 boundVars.push_back(x_begin);
06741 }
06742
06743 if (2*k + 1 <= i + j)
06744 {
06745
06746
06747
06748
06749
06750 int o_size = k - j + 1;
06751 bool no_rest = (2*k + 1 == i + j);
06752
06753
06754 Expr a = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(o_size));
06755 boundVars.push_back(a);
06756 terms.push_back(a);
06757
06758 if (no_rest) {
06759
06760 terms.push_back(a);
06761 terms.push_back(a);
06762 } else {
06763
06764 Expr b = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(i - k - o_size));
06765 boundVars.push_back(b);
06766 terms.push_back(b);
06767 terms.push_back(a);
06768 terms.push_back(b);
06769 terms.push_back(a);
06770 }
06771 }
06772 else
06773 {
06774
06775
06776
06777
06778 int o_size = k - j + 1;
06779 int r_size = i - k;
06780
06781 int d = gcd(Rational(o_size), Rational(r_size)).getInt();
06782
06783 int different_pieces = r_size / d;
06784
06785 for (int p = 0; p < different_pieces; p ++) {
06786 Expr piece = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(d));
06787 boundVars.push_back(piece);
06788 terms.push_back(piece);
06789 }
06790
06791 int other_pieces = (o_size + r_size) / d;
06792 for (int p = 0; p < other_pieces; p ++)
06793 terms.push_back(terms[terms.size() - different_pieces]);
06794 }
06795
06796
06797 if (l > 0) {
06798 Expr x_end = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(l));
06799 terms.push_back(x_end);
06800 boundVars.push_back(x_end);
06801 }
06802
06803 res = x.eqExpr(d_theoryBitvector->newConcatExpr(terms));
06804 res = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, res);
06805
06806 } else
06807
06808 res = solveExtractOverlap(rhs.eqExpr(lhs)).getRHS();
06809
06810 Proof pf;
06811 if (withProof()) pf = newPf("solveExtractOverlap", eq);
06812
06813 return newTheorem(eq.iffExpr(res), Assumptions::emptyAssump(), pf);
06814 }
06815