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
00030
00031
00032
00033
00034
00035
00036
00037 #define _CVCL_TRUSTED_
00038
00039 #include "bitvector_theorem_producer.h"
00040 #include "common_proof_rules.h"
00041 #include "theory_core.h"
00042 #include "theory_bitvector.h"
00043
00044 using namespace std;
00045 using namespace CVCL;
00046
00047
00048
00049
00050 BitvectorProofRules*
00051 TheoryBitvector::createProofRules() {
00052 return new BitvectorTheoremProducer(this);
00053 }
00054
00055
00056 BitvectorTheoremProducer::BitvectorTheoremProducer(TheoryBitvector* theoryBV)
00057 : TheoremProducer(theoryBV->theoryCore()->getTM()),
00058 d_theoryBitvector(theoryBV) {
00059
00060 vector<bool> bits(1);
00061 bits[0]=false;
00062 d_bvZero = d_theoryBitvector->newBVConstExpr(bits);
00063 bits[0]=true;
00064 d_bvOne = d_theoryBitvector->newBVConstExpr(bits);
00065 }
00066
00067
00068
00069
00070
00071 Theorem BitvectorTheoremProducer::bitvectorFalseRule(const Theorem& thm) {
00072 if(CHECK_PROOFS) {
00073 const Expr e = thm.getExpr();
00074 CHECK_SOUND(e.isIff() && e[0].isIff(),
00075 "TheoryBitvector::bitvectorFalseRule: "
00076 "premise must be a iff theorem:\n e = "
00077 +e.toString());
00078 CHECK_SOUND(e[1].isFalse(),
00079 "TheoryBitvector::bitvectorFalseRule: "
00080 "premise must be iff Theorem, with False as the RHS:\n e = "
00081 +e.toString());
00082 CHECK_SOUND(e[0][0].getOpKind() == BOOLEXTRACT &&
00083 e[0][1].getOpKind() == BOOLEXTRACT,
00084 "TheoryBitvector::bitvectorFalseRule: "
00085 "premise must be iff Theorem, with False as the RHS:\n e = "
00086 +e.toString());
00087 CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(e[0][0]) ==
00088 d_theoryBitvector->getBoolExtractIndex(e[0][1]),
00089 "TheoryBitvector::bitvectorFalseRule: "
00090 "premise must be iff Theorem, with False as the RHS:\n e = "
00091 +e.toString());
00092 }
00093 const Expr& e = thm.getExpr();
00094 const Expr& t1 = e[0][0][0];
00095 const Expr& t2 = e[0][1][0];
00096 Expr output = (t1.eqExpr(t2)).iffExpr(e[1]);
00097
00098 Assumptions a;
00099 Proof pf;
00100 if(withProof())
00101 pf = newPf("bitvector_false_rule", e);
00102 return newRWTheorem(t1.eqExpr(t2), e[1], a, pf);
00103 }
00104
00105 Theorem BitvectorTheoremProducer::bitvectorTrueRule(const Theorem& thm) {
00106 if(CHECK_PROOFS) {
00107 const Expr e = thm.getExpr();
00108 CHECK_SOUND(e.isIff() && e[0].isIff(),
00109 "TheoryBitvector::bitvectorFalseRule: "
00110 "premise must be a iff theorem:\n e = "
00111 +e.toString());
00112 CHECK_SOUND(e[1].isTrue(),
00113 "TheoryBitvector::bitvectorFalseRule: "
00114 "premise must be iff Theorem, with False as the RHS:\n e = "
00115 +e.toString());
00116 CHECK_SOUND(e[0][0].getKind() == NOT &&
00117 e[0][0][0].getOpKind() == BOOLEXTRACT &&
00118 e[0][1].getOpKind() == BOOLEXTRACT,
00119 "TheoryBitvector::bitvectorFalseRule: "
00120 "premise must be iff Theorem, with False as the RHS:\n e = "
00121 +e.toString());
00122 CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(e[0][0][0]) ==
00123 d_theoryBitvector->getBoolExtractIndex(e[0][1]),
00124 "TheoryBitvector::bitvectorFalseRule: "
00125 "premise must be iff Theorem, with False as the RHS:\n e = "
00126 +e.toString());
00127 }
00128 const Expr& e = thm.getExpr();
00129
00130
00131 const Expr& t1 = e[0][0][0][0];
00132 const Expr& t2 = e[0][1][0];
00133 Expr output = (t1.eqExpr(t2).negate()).iffExpr(e[1]);
00134
00135 Assumptions a;
00136 Proof pf;
00137 if(withAssumptions())
00138 a = thm.getAssumptionsCopy();
00139 if(withProof())
00140 pf = newPf("bitvector_true_rule", thm.getExpr(), output, thm.getProof());
00141 return newTheorem(output, a, pf);
00142 }
00143
00144 Theorem BitvectorTheoremProducer::bitBlastEqnRule(const Expr& e,
00145 const Expr& f) {
00146 if(CHECK_PROOFS) {
00147 CHECK_SOUND(e.isEq(),
00148 "TheoryBitvector::bitBlastEqnRule: "
00149 "premise must be a rewrite theorem:\n e = "
00150 +e.toString());
00151 const Expr& lhs = e[0];
00152 const Expr& rhs = e[1];
00153 const Type& leftType = lhs.getType();
00154 const Type& rightType = rhs.getType();
00155 CHECK_SOUND(BITVECTOR == leftType.getExpr().getOpKind() &&
00156 BITVECTOR == rightType.getExpr().getOpKind(),
00157 "TheoryBitvector::bitBlastEqnRule: "
00158 "lhs & rhs must be bitvectors:\n e ="
00159 +e.toString());
00160 int lhsLength = d_theoryBitvector->BVSize(lhs);
00161 int rhsLength = d_theoryBitvector->BVSize(rhs);
00162 CHECK_SOUND(lhsLength == rhsLength,
00163 "TheoryBitvector::bitBlastEqnRule: "
00164 "lhs & rhs must be bitvectors of same bvLength.\n size(lhs) = "
00165 + int2string(lhsLength)
00166 +"\n size(rhs) = "
00167 + int2string(rhsLength)
00168 +"\n e = "+e.toString());
00169 int bvLength = d_theoryBitvector->BVSize(leftType.getExpr());
00170 CHECK_SOUND(f.isAnd(),
00171 "TheoryBitvector::bitBlastEqnRule: "
00172 "consequence of the rule must be an AND.\n f = "
00173 +f.toString());
00174 CHECK_SOUND(bvLength == f.arity(),
00175 "TheoryBitvector::bitBlastEqnRule: "
00176 "the arity of the consequence AND must "
00177 "equal the bvLength of the bitvector:\n f = "
00178 +f.toString()+"\n bvLength = "+ int2string(bvLength));
00179 for(int i=0; i <bvLength; i++) {
00180 const Expr& conjunct = f[i];
00181 CHECK_SOUND(conjunct.isIff() && 2 == conjunct.arity(),
00182 "TheoryBitvector::bitBlastEqnRule: "
00183 "each conjunct in consequent must be an IFF.\n f = "
00184 +f.toString());
00185 const Expr& leftExtract = conjunct[0];
00186 const Expr& rightExtract = conjunct[1];
00187 CHECK_SOUND(BOOLEXTRACT == leftExtract.getOpKind(),
00188 "TheoryBitvector::bitBlastEqnRule: "
00189 "each conjunct in consequent must be boolextract.\n"
00190 " f["+int2string(i)+"] = "+conjunct.toString());
00191 CHECK_SOUND(BOOLEXTRACT == rightExtract.getOpKind(),
00192 "TheoryBitvector::bitBlastEqnRule: "
00193 "each conjunct in consequent must be boolextract.\n"
00194 " f["+int2string(i)+"] = "+conjunct.toString());
00195 const Expr& leftBV = leftExtract[0];
00196 const Expr& rightBV = rightExtract[0];
00197 CHECK_SOUND(leftBV == lhs && rightBV == rhs,
00198 "TheoryBitvector::bitBlastEqnRule: each boolextract"
00199 " must be applied to the correct bitvector.\n conjunct = "
00200 +conjunct.toString()
00201 +"\n leftBV = "+ leftBV.toString()
00202 +"\n lhs = "+ lhs.toString()
00203 +"\n rightBV = "+rightBV.toString()
00204 +"\n rhs = "+rhs.toString());
00205 int leftBitPosition =
00206 d_theoryBitvector->getBoolExtractIndex(leftExtract);
00207 int rightBitPosition =
00208 d_theoryBitvector->getBoolExtractIndex(rightExtract);
00209 CHECK_SOUND(leftBitPosition == i && rightBitPosition == i,
00210 "TheoryBitvector::bitBlastEqnRule: "
00211 "boolextract positions must match i= "+int2string(i)
00212 +"\n conjunct = "+conjunct.toString());
00213 }
00214 }
00215
00216 Assumptions a;
00217 Proof pf;
00218 if(withProof())
00219 pf = newPf("bit_blast_equations", e, f);
00220 return newRWTheorem(e, f, a, pf);
00221 }
00222
00223
00224
00225
00226
00227
00228 Theorem BitvectorTheoremProducer::bitBlastDisEqnRule(const Theorem& notE,
00229 const Expr& f){
00230
00231 TRACE("bitvector", "input to bitBlastDisEqnRule(", notE.toString(), ")");
00232 DebugAssert(notE.getExpr().isNot() && (notE.getExpr())[0].isEq(),
00233 "TheoryBitvector::bitBlastDisEqnRule:"
00234 "expecting an equation" + notE.getExpr().toString());
00235
00236 const Expr& e = (notE.getExpr())[0];
00237 if(CHECK_PROOFS) {
00238 CHECK_SOUND(e.isEq(),
00239 "TheoryBitvector::bitBlastDisEqnRule:"
00240 "premise must be a rewrite theorem" + e.toString());
00241 const Expr& lhs = e[0];
00242 const Expr& rhs = e[1];
00243 const Type& leftType = lhs.getType();
00244 const Type& rightType = rhs.getType();
00245 CHECK_SOUND(BITVECTOR == leftType.getExpr().getOpKind() &&
00246 BITVECTOR == rightType.getExpr().getOpKind(),
00247 "TheoryBitvector::bitBlastDisEqnRule:"
00248 "lhs & rhs must be bitvectors" + e.toString());
00249 CHECK_SOUND(d_theoryBitvector->BVSize(leftType.getExpr()) ==
00250 d_theoryBitvector->BVSize(rightType.getExpr()),
00251 "TheoryBitvector::bitBlastDisEqnRule:"
00252 "lhs & rhs must be bitvectors of same bvLength");
00253 int bvLength = d_theoryBitvector->BVSize(leftType.getExpr());
00254 CHECK_SOUND(f.isOr(),
00255 "TheoryBitvector::bitBlastDisEqnRule:"
00256 "consequence of the rule must be an OR" + f.toString());
00257 CHECK_SOUND(bvLength == f.arity(),
00258 "TheoryBitvector::bitBlastDisEqnRule:"
00259 "the arity of the consequence OR must be"
00260 "equal to the bvLength of the bitvector" +
00261 f.toString() + int2string(bvLength));
00262 for(int i=0; i <bvLength; i++) {
00263 const Expr& disjunct = f[i];
00264 CHECK_SOUND(disjunct.isIff() &&
00265 2 == disjunct.arity() && disjunct[0].isNot(),
00266 "TheoryBitvector::bitBlastDisEqnRule:"
00267 "each conjunct in consequent must be an Iff"+f.toString());
00268 const Expr& leftExtract = (disjunct[0])[0];
00269 const Expr& rightExtract = disjunct[1];
00270 CHECK_SOUND(BOOLEXTRACT == leftExtract.getOpKind(),
00271 "TheoryBitvector::bitBlastDisEqnRule:"
00272 "each disjunct in consequent must be boolextract" +
00273 disjunct.toString());
00274 CHECK_SOUND(BOOLEXTRACT == rightExtract.getOpKind(),
00275 "TheoryBitvector::bitBlastDisEqnRule:"
00276 "each conjunct in consequent must be boolextract" +
00277 disjunct.toString());
00278 const Expr& leftBV = leftExtract[0];
00279 const Expr& rightBV = rightExtract[0];
00280 CHECK_SOUND(leftBV == lhs && rightBV == rhs,
00281 "TheoryBitvector::bitBlastDisEqnRule:"
00282 "each boolextract must be applied to the correct bitvector"+
00283 disjunct.toString() + leftBV.toString() + lhs.toString() +
00284 rightBV.toString() + rhs.toString());
00285 int leftBitPosition =
00286 d_theoryBitvector->getBoolExtractIndex(leftExtract);
00287 int rightBitPosition =
00288 d_theoryBitvector->getBoolExtractIndex(rightExtract);
00289 CHECK_SOUND(leftBitPosition == i && rightBitPosition == i,
00290 "TheoryBitvector::bitBlastDisEqnRule:"
00291 "boolextract positions must match" + disjunct.toString());
00292 }
00293 }
00294
00295 Assumptions a;
00296 Proof pf;
00297 if(withAssumptions())
00298 a = notE.getAssumptionsCopy();
00299 if(withProof())
00300 pf = newPf("bit_blast_disequations", notE.getExpr(), f, notE.getProof());
00301 return newTheorem(f, a, pf);
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 Theorem
00311 BitvectorTheoremProducer::padBVLTRule(const Expr& e, int len) {
00312 if(CHECK_PROOFS) {
00313 CHECK_SOUND((BVLT == e.getOpKind() || BVLE == e.getOpKind()) &&
00314 e.arity()==2,
00315 "BitvectorTheoremProducer::padBVLTRule: "
00316 "input must e be a BVLT/BVLE: e = " + e.toString());
00317 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
00318 BITVECTOR==e[1].getType().getExpr().getOpKind(),
00319 "BitvectorTheoremProducer::padBVLTRule: "
00320 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
00321 CHECK_SOUND(0<=len,
00322 "BitvectorTheoremProducer::padBVLTRule: "
00323 "input len must be >=0 and an integer: len = " +
00324 int2string(len));
00325 }
00326 Expr e0 = pad(len, e[0]);
00327 Expr e1 = pad(len, e[1]);
00328 int kind = e.getOpKind();
00329
00330 Expr output;
00331 if(kind == BVLT)
00332 output = d_theoryBitvector->newBVLTExpr(e0,e1);
00333 else
00334 output = d_theoryBitvector->newBVLEExpr(e0,e1);
00335
00336 Assumptions a;
00337 Proof pf;
00338 if(withProof())
00339 pf = newPf("pad_bvlt_rule", e);
00340 Theorem result(newRWTheorem(e,output,a,pf));
00341 return result;
00342 }
00343
00344
00345 Theorem
00346 BitvectorTheoremProducer::signExtendRule(const Expr& e) {
00347 if(CHECK_PROOFS) {
00348 CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(),
00349 "input must be a bitvector. \n e = " + e.toString());
00350 CHECK_SOUND(SX == e.getOpKind(),
00351 "input must be SX(e).\n e = " + e.toString());
00352 CHECK_SOUND(SX != e[0].getOpKind(),
00353 "input cannot have nested SX.\n e = " + e.toString());
00354 }
00355 Expr input0 = e[0];
00356
00357 while(SX == input0.getOpKind())
00358 input0 = input0[0];
00359
00360 int bvLength = d_theoryBitvector->BVSize(e);
00361 int bvLength0 = d_theoryBitvector->BVSize(input0);
00362
00363 Expr output;
00364 if(bvLength0 == bvLength) {
00365 output = input0;
00366 } else if(bvLength0 < bvLength) {
00367 std::vector<Expr> k;
00368 int c = bvLength - bvLength0;
00369 Expr topBit =
00370 d_theoryBitvector->newBVExtractExpr(input0,bvLength0-1,bvLength0-1);
00371 while(c--)
00372 k.push_back(topBit);
00373 k.push_back(input0);
00374 output = d_theoryBitvector->newConcatExpr(k);
00375 } else
00376 output = d_theoryBitvector->newBVExtractExpr(input0, bvLength-1, 0);
00377
00378 Assumptions a;
00379 Proof pf;
00380 if(withProof())
00381 pf = newPf("sign_extend_rule", e);
00382 Theorem result(newRWTheorem(e,output,a,pf));
00383 return result;
00384 }
00385
00386
00387 Theorem
00388 BitvectorTheoremProducer::bitExtractSXRule(const Expr& e, int i) {
00389
00390
00391 Theorem thm = signExtendRule(e);
00392 Expr e_i = d_theoryBitvector->newBoolExtractExpr(e,i);
00393 Expr newE_i = d_theoryBitvector->newBoolExtractExpr(thm.getRHS(),i);
00394
00395 Assumptions a;
00396 Proof pf;
00397 if(withProof())
00398 pf = newPf("bitExtract_SX_rule",e,rat(i));
00399 Theorem result(newRWTheorem(e_i,newE_i,a,pf));
00400 return result;
00401 }
00402
00403
00404
00405 Theorem
00406 BitvectorTheoremProducer::padSBVLTRule(const Expr& e, int len) {
00407 if(CHECK_PROOFS) {
00408 CHECK_SOUND((SBVLT == e.getOpKind() || SBVLE == e.getOpKind()) &&
00409 e.arity()==2,
00410 "BitvectorTheoremProducer::padSBVLTRule: "
00411 "input must e be a SBVLT/SBVLE: e = " + e.toString());
00412 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
00413 BITVECTOR==e[1].getType().getExpr().getOpKind(),
00414 "BitvectorTheoremProducer::padSBVLTRule: "
00415 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
00416 CHECK_SOUND(0<=len,
00417 "BitvectorTheoremProducer::padSBVLTRule: "
00418 "input len must be >=0 and an integer: len = " +
00419 int2string(len));
00420 }
00421 Expr e0 = d_theoryBitvector->newSXExpr(e[0], len);
00422 Expr e1 = d_theoryBitvector->newSXExpr(e[1], len);
00423 int kind = e.getOpKind();
00424
00425 Expr output;
00426 if(kind == SBVLT)
00427 output = d_theoryBitvector->newSBVLTExpr(e0,e1);
00428 else
00429 output = d_theoryBitvector->newSBVLEExpr(e0,e1);
00430
00431 Assumptions a;
00432 Proof pf;
00433 if(withProof())
00434 pf = newPf("pad_sbvlt_rule", e);
00435 Theorem result(newRWTheorem(e,output,a,pf));
00436 return result;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 Theorem
00448 BitvectorTheoremProducer::signBVLTRule(const Expr& e,
00449 const Theorem& topBit0,
00450 const Theorem& topBit1){
00451 if(CHECK_PROOFS) {
00452 CHECK_SOUND((SBVLT == e.getOpKind() || SBVLE == e.getOpKind()) &&
00453 e.arity()==2,
00454 "BitvectorTheoremProducer::signedBVLTRule: "
00455 "input must e be a SBVLT/SBVLE: e = " + e.toString());
00456 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
00457 BITVECTOR==e[1].getType().getExpr().getOpKind(),
00458 "BitvectorTheoremProducer::signedBVLTRule: "
00459 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
00460 }
00461 const Expr e0 = e[0];
00462 const Expr e1 = e[1];
00463 int e0len = d_theoryBitvector->BVSize(e0);
00464 int e1len = d_theoryBitvector->BVSize(e1);
00465
00466 if(CHECK_PROOFS) {
00467 const Expr e0ext =
00468 d_theoryBitvector->newBVExtractExpr(e0,e0len-1,e0len-1);
00469 const Expr e1ext =
00470 d_theoryBitvector->newBVExtractExpr(e1,e1len-1,e1len-1);
00471 CHECK_SOUND(e0ext == topBit0.getLHS(),
00472 "BitvectorTheoremProducer::signedBVLTRule: "
00473 "topBit0.getLHS() is the un-rewritten form of MSB of e0\n"
00474 "topBit0 is screwed up: topBit0 = " +
00475 topBit0.getExpr().toString());
00476 CHECK_SOUND(e1ext == topBit1.getLHS(),
00477 "BitvectorTheoremProducer::signedBVLTRule: "
00478 "topBit1.getLHS() is the un-rewritten form of MSB of e1\n"
00479 "topBit1 is screwed up: topBit1 = " +
00480 topBit1.getExpr().toString());
00481 CHECK_SOUND(e0len == e1len,
00482 "BitvectorTheoremProducer::signedBVLTRule: "
00483 "both e[0] and e[1] must have the same length\n. e =" +
00484 e.toString());
00485 }
00486 const Expr MSB0 = topBit0.getRHS();
00487 const Expr MSB1 = topBit1.getRHS();
00488
00489 int eKind = e.getOpKind();
00490 Expr output;
00491
00492
00493
00494
00495
00496
00497
00498 Rational b0 = -1;
00499 Rational b1 = -1;
00500 if(MSB0.getKind() == BVCONST) b0 = d_theoryBitvector->computeBVConst(MSB0);
00501 if(MSB1.getKind() == BVCONST) b1 = d_theoryBitvector->computeBVConst(MSB1);
00502
00503
00504 const Expr tExpr = d_theoryBitvector->trueExpr();
00505 const Expr fExpr = d_theoryBitvector->falseExpr();
00506 const Expr MSB0isZero = MSB0.eqExpr(bvZero());
00507 const Expr MSB0isOne = MSB0.eqExpr(bvOne());
00508 const Expr MSB1isZero = MSB1.eqExpr(bvZero());
00509 const Expr MSB1isOne = MSB1.eqExpr(bvOne());
00510
00511
00512
00513
00514 if(e0len == 1) {
00515 if(b0==0 && b1==0)
00516 output = eKind==SBVLT ? fExpr : tExpr;
00517 else if(b0==0 && b1==1)
00518 output = fExpr;
00519 else if(b0==1 && b1==0)
00520 output = tExpr;
00521 else if(b0==1 && b1==1)
00522 output = eKind==SBVLT ? fExpr : tExpr;
00523 else if(b0==0 && b1==-1)
00524 output = eKind==SBVLT ? fExpr : MSB1isZero;
00525 else if(b0==1 && b1==-1)
00526 output = eKind==SBVLT ? MSB1isZero : tExpr;
00527 else if(b0==-1 && b1==0)
00528 output = eKind==SBVLT ? MSB0isOne : tExpr;
00529 else if(b0==-1 && b1==1)
00530 output = eKind==SBVLT ? fExpr : MSB0isOne;
00531 else
00532
00533 output =
00534 eKind==SBVLT ?
00535 MSB0isOne.andExpr(MSB1isZero) :
00536 MSB1isZero;
00537 } else {
00538
00539 Expr newE0 = d_theoryBitvector->newBVExtractExpr(e0,e0len-2,0);
00540 Expr newE1 = d_theoryBitvector->newBVExtractExpr(e1,e1len-2,0);
00541 Expr newBVLT =
00542 eKind==SBVLT ?
00543 d_theoryBitvector->newBVLTExpr(newE0,newE1):
00544 d_theoryBitvector->newBVLEExpr(newE0,newE1);
00545 Expr newBVLTreverse =
00546 eKind==SBVLT ?
00547 d_theoryBitvector->newBVLTExpr(newE1,newE0):
00548 d_theoryBitvector->newBVLEExpr(newE1,newE0);
00549
00550
00551
00552 if(-1 != b0 && -1 !=b1) {
00553
00554 if(b0 == 1 && b1 == 0)
00555 output = tExpr;
00556
00557 else if(b0 == 0 && b1 == 1)
00558 output = fExpr;
00559
00560 else if(b0 == 0 && b1 == 0)
00561 output = eKind==SBVLT ?
00562 d_theoryBitvector->newBVLTExpr(e0,e1):
00563 d_theoryBitvector->newBVLEExpr(e0,e1);
00564
00565 else
00566 output = newBVLT;
00567 }
00568 else if(-1 != b0 && -1 == b1) {
00569
00570
00571
00572
00573
00574
00575
00576 output =
00577 (b0==0) ?
00578
00579 MSB1isZero.andExpr(newBVLT) :
00580
00581 MSB1isZero.orExpr(MSB1isOne.andExpr(newBVLTreverse));
00582 }
00583 else if(-1 == b0 && -1 != b1) {
00584
00585
00586
00587
00588
00589
00590
00591 output =
00592 (b1==0) ?
00593
00594 MSB0isOne.orExpr(MSB0isZero.andExpr(newBVLT)) :
00595
00596 MSB0isOne.andExpr(newBVLTreverse);
00597 } else {
00598
00599
00600
00601 Expr k0 = MSB0isOne.andExpr(MSB1isZero);
00602
00603
00604 Expr k1 = MSB0isOne.andExpr(MSB1isOne.andExpr(newBVLTreverse));
00605
00606
00607 Expr k2 = MSB0isZero.andExpr(MSB1isZero.andExpr(newBVLT));
00608
00609
00610
00611
00612 output = k0.orExpr(k1.orExpr(k2));
00613 }
00614 }
00615
00616 Assumptions a;
00617 Proof pf;
00618 if(withProof())
00619 pf = newPf("sign_bvlt_rule", e);
00620 return newRWTheorem(e, output, a, pf);
00621 }
00622
00623
00624
00625
00626
00627 Theorem BitvectorTheoremProducer::notBVLTRule(const Expr& e, int kind) {
00628 if(CHECK_PROOFS) {
00629 CHECK_SOUND(e.getKind() == NOT,
00630 "BitvectorTheoremProducer::notBVLTRule: "
00631 "input kind must be a NOT:\n e = " + e.toString());
00632 CHECK_SOUND(e[0].getOpKind() == BVLT ||
00633 e[0].getOpKind() == BVLE,
00634 "BitvectorTheoremProducer::notBVLTRule: "
00635 "e[0] must be BVLT or BVLE: \n e = " + e.toString());
00636 CHECK_SOUND(kind == e[0].getOpKind(),
00637 "BitvectorTheoremProducer::notBVLTRule: "
00638 "input kind must be the correct one: e[0] = " +
00639 e[0].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 Assumptions a;
00651 Proof pf;
00652 if(withProof())
00653 pf = newPf("not_bvlt_rule", e);
00654 return newRWTheorem(e, output, a, pf);
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 Assumptions a;
00679 Proof pf;
00680 if(withProof())
00681 pf = newPf("lhs_eq_rhs_ineqn", e);
00682 return newRWTheorem(e, output, a, pf);
00683 }
00684
00685
00686 Theorem BitvectorTheoremProducer::bvConstIneqn(const Expr& e, int kind) {
00687 if(CHECK_PROOFS) {
00688 CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(),
00689 "BitvectorTheoremProducer::bvConstIneqn: "
00690 "input kind must be BVLT or BVLE: e = " + e.toString());
00691 CHECK_SOUND(kind == e.getOpKind(),
00692 "BitvectorTheoremProducer::bvConstIneqn: "
00693 "input kind must match e.getOpKind(): "
00694 "\n e = " + e.toString());
00695 CHECK_SOUND((e.arity()==2),
00696 "BitvectorTheoremProducer::bvConstIneqn: "
00697 "input arity must be 2: \ne = " + e.toString());
00698 CHECK_SOUND(BVCONST == e[0].getKind() && BVCONST == e[1].getKind(),
00699 "BitvectorTheoremProducer::bvConstIneqn: "
00700 "e[0] and e[1] must both be constants:\n e = " +
00701 e.toString());
00702 }
00703
00704 int e0len = d_theoryBitvector->BVSize(e[0]);
00705 int e1len = d_theoryBitvector->BVSize(e[1]);
00706 if(CHECK_PROOFS)
00707 CHECK_SOUND(e0len == e1len,
00708 "BitvectorTheoremProducer::bvConstIneqn: "
00709 "e[0] and e[1] must have the same bvLength:\ne = " +
00710 e.toString());
00711
00712 Rational lhsVal = d_theoryBitvector->computeBVConst(e[0]);
00713 Rational rhsVal = d_theoryBitvector->computeBVConst(e[1]);
00714 Expr output;
00715
00716 if(BVLT == kind) {
00717 if(lhsVal < rhsVal)
00718 output = d_theoryBitvector->trueExpr();
00719 else
00720 output = d_theoryBitvector->falseExpr();
00721 } else {
00722 if(lhsVal <= rhsVal)
00723 output = d_theoryBitvector->trueExpr();
00724 else
00725 output = d_theoryBitvector->falseExpr();
00726 }
00727
00728 Assumptions a;
00729 Proof pf;
00730 if(withProof())
00731 pf = newPf("bv_const_ineqn", e);
00732 return newRWTheorem(e, output, a, pf);
00733 }
00734
00735 Theorem BitvectorTheoremProducer::generalIneqn(const Expr& e,
00736 const Theorem& lhs_i,
00737 const Theorem& rhs_i,
00738 int kind) {
00739 if(CHECK_PROOFS) {
00740 CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(),
00741 "BitvectorTheoremProducer::generalIneqn: "
00742 "input kind must be BVLT or BVLE: e = " + e.toString());
00743 CHECK_SOUND(kind == e.getOpKind(),
00744 "BitvectorTheoremProducer::generalIneqn: "
00745 "input kind must match e.getOpKind(): "
00746 "\n e = " + e.toString());
00747 CHECK_SOUND((e.arity()==2),
00748 "BitvectorTheoremProducer::generalIneqn: "
00749 "input arity must be 2: \ne = " + e.toString());
00750 CHECK_SOUND(lhs_i.isRewrite() && rhs_i.isRewrite(),
00751 "BitvectorTheoremProducer::generalIneqn: "
00752 "lhs_i and rhs_i must be rewrite theorems: "
00753 "\nlhs_i = " + lhs_i.toString() +
00754 "\nrhs_i = " + rhs_i.toString());
00755 }
00756
00757 int e0len = d_theoryBitvector->BVSize(e[0]);
00758 int e1len = d_theoryBitvector->BVSize(e[1]);
00759 const Expr& e0_iBit = lhs_i.getLHS();
00760 const Expr& e1_iBit = rhs_i.getLHS();
00761 if(CHECK_PROOFS) {
00762 CHECK_SOUND(BOOLEXTRACT == e0_iBit.getOpKind() &&
00763 BOOLEXTRACT == e1_iBit.getOpKind(),
00764 "BitvectorTheoremProducer::generalIneqn: "
00765 "lhs_i.getRHS() and rhs_i.getRHS() must be BOOLEXTRACTs:"
00766 "\nlhs_i = " + lhs_i.toString() +
00767 "\nrhs_i = " + rhs_i.toString());
00768 CHECK_SOUND(e[0] == e0_iBit[0],
00769 "BitvectorTheoremProducer::generalIneqn: "
00770 "e[0] must be equal to LHS of lhs_i: \nlhs_i = " +
00771 lhs_i.toString() + "\n e[0] = " + e[0].toString());
00772 CHECK_SOUND(e[1] == e1_iBit[0],
00773 "BitvectorTheoremProducer::generalIneqn: "
00774 "e[1] must be equal to LHS of rhs_i: \nrhs_i = " +
00775 rhs_i.toString() + "\n e[1] = " + e[1].toString());
00776 CHECK_SOUND(e0len == e1len,
00777 "BitvectorTheoremProducer::generalIneqn: "
00778 "e[0] and e[1] must have the same bvLength:\ne = " +
00779 e.toString());
00780 int e0_iBitIndex =
00781 d_theoryBitvector->getBoolExtractIndex(e0_iBit);
00782 int e1_iBitIndex =
00783 d_theoryBitvector->getBoolExtractIndex(e1_iBit);
00784 CHECK_SOUND(e0_iBitIndex == e1_iBitIndex &&
00785 e0_iBitIndex == e0len-1,
00786 "BitvectorTheoremProducer::generalIneqn: "
00787 "e0_iBit & e1_iBit must have same extract index: "
00788 "\ne0_iBit = " + e0_iBit.toString() +
00789 "\ne1_iBit = " + e1_iBit.toString());
00790 }
00791
00792
00793
00794 const Expr& b1 = lhs_i.getRHS();
00795 const Expr& b2 = rhs_i.getRHS();
00796 const Expr& trueExpression = d_theoryBitvector->trueExpr();
00797 const Expr& falseExpression = d_theoryBitvector->falseExpr();
00798
00799 if(CHECK_PROOFS) {
00800 CHECK_SOUND(b1.getType().isBool(),
00801 "BitvectorTheoremProducer::generalIneqn: "
00802 "b1 must be a boolean type: "
00803 "\n b1 = " + b1.toString());
00804 CHECK_SOUND(b2.getType().isBool(),
00805 "BitvectorTheoremProducer::generalIneqn: "
00806 "b2 must be boolean type: "
00807 "\n b2 = " + b2.toString());
00808 }
00809
00810 Expr output;
00811
00812 if(b1.isFalse() && b2.isTrue())
00813 output = trueExpression;
00814 else if(b1.isTrue() && b2.isFalse())
00815 output = falseExpression;
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825 if(output.isNull()) {
00826
00827
00828 Expr b1_0 = b1.notExpr();
00829
00830
00831 Expr b2_1 = b2;
00832
00833 Expr b1_eq_b2 = b1.iffExpr(b2);
00834
00835
00836 output = (kind==BVLT) ?
00837 b1_0.andExpr(b2_1) :
00838 (e0len==1) ? b1_0.orExpr(b2_1) : b1_0.andExpr(b2_1);
00839
00840
00841
00842 if(e0len > 1) {
00843
00844 Expr e0_extract =
00845 d_theoryBitvector->newBVExtractExpr(e[0],e0len-2,0);
00846
00847 Expr e1_extract =
00848 d_theoryBitvector->newBVExtractExpr(e[1],e1len-2,0);
00849
00850 Expr a;
00851 if(kind==BVLT)
00852
00853 a = d_theoryBitvector->newBVLTExpr(e0_extract,e1_extract);
00854 else
00855
00856 a = d_theoryBitvector->newBVLEExpr(e0_extract,e1_extract);
00857
00858
00859 Expr b1_eq_b2_and_a = b1_eq_b2.andExpr(a);
00860
00861 output = output.orExpr(b1_eq_b2_and_a);
00862 }
00863 }
00864
00865 Assumptions a;
00866 Proof pf;
00867 if(withProof())
00868 pf = newPf("general_ineqn", e);
00869 return newRWTheorem(e, output, a, pf);
00870 }
00871
00872
00873
00874
00875
00876
00877 Theorem BitvectorTheoremProducer::bitExtractToExtract(const Theorem& thm) {
00878 const Expr& e = thm.getExpr();
00879 if(CHECK_PROOFS) {
00880 CHECK_SOUND((e.isNot() && e[0].getOpKind() == BOOLEXTRACT)
00881 || (e.getOpKind() == BOOLEXTRACT),
00882 "BitvectorTheoremProducer::bitExtractToExtract:\n e = "
00883 +e.toString());
00884 }
00885 bool negative = e.isNot();
00886 const Expr& boolExtract = negative? e[0] : e;
00887 int i = d_theoryBitvector->getBoolExtractIndex(boolExtract);
00888 Expr lhs = d_theoryBitvector->newBVExtractExpr(boolExtract[0], i, i);
00889
00890 Assumptions a;
00891 Proof pf;
00892 if(withAssumptions())
00893 a = thm.getAssumptionsCopy();
00894 if(withProof())
00895 pf = newPf("bit_extract_to_extract", e, thm.getProof());
00896 return newRWTheorem(lhs, negative? bvZero() : bvOne(), a, pf);
00897 }
00898
00899
00900
00901 Theorem BitvectorTheoremProducer::bitExtractRewrite(const Expr& x) {
00902 if(CHECK_PROOFS) {
00903 CHECK_SOUND(x.getOpKind() == BOOLEXTRACT,
00904 "BitvectorTheoremProducer::bitExtractRewrite: x = "
00905 +x.toString());
00906 }
00907
00908 int i = d_theoryBitvector->getBoolExtractIndex(x);
00909 const Expr& t = x[0];
00910 int bvLength = d_theoryBitvector->BVSize(t);
00911
00912 if(CHECK_PROOFS) {
00913 CHECK_SOUND(0<=i && i<bvLength,
00914 "BitvectorTheoremProducer::bitExtractRewrite:"
00915 "\n bvLength = "
00916 + int2string(bvLength)
00917 +"\n i = "+ int2string(i)
00918 +"\n x = "+ x.toString());
00919 }
00920 Assumptions a;
00921 Proof pf;
00922 if(withProof())
00923 pf = newPf("bit_extract_rewrite", x);
00924 Expr res = d_theoryBitvector->newBVExtractExpr(t, i, i);
00925 res = d_theoryBitvector->newBoolExtractExpr(res, 0);
00926 return newRWTheorem(x, res, a, pf);
00927 }
00928
00929
00930 Theorem BitvectorTheoremProducer::bitExtractConstant(const Expr & x,
00931 int i)
00932 {
00933 TRACE("bitvector", "bitExtractConstant(", x, ", "+ int2string(i) +" ) {");
00934 if(CHECK_PROOFS) {
00935
00936 CHECK_SOUND(BVCONST == x.getKind(),
00937 "BitvectorTheoremProducer::bitExtractConstant:"
00938 "the bitvector must be a constant.");
00939
00940 CHECK_SOUND(0 <= i && (unsigned)i < d_theoryBitvector->getBVConstSize(x),
00941 "BitvectorTheoremProducer::bitExtractConstant:"
00942 "illegal extraction attempted on the bitvector x = "
00943 + x.toString()
00944 + "\nat the position i = "
00945 + int2string(i));
00946 }
00947
00948 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
00949
00950
00951
00952
00953 Expr output;
00954 if(!d_theoryBitvector->getBVConstValue(x, i))
00955 output = d_theoryBitvector->falseExpr();
00956 else
00957 output = d_theoryBitvector->trueExpr();
00958
00959 Assumptions a;
00960 Proof pf;
00961 if(withProof()) pf = newPf("bit_extract_constant", x, rat(i));
00962 Theorem result(newRWTheorem(bitExtract,output,a,pf));
00963 TRACE("bitvector", "bitExtractConstant => ", result, " }");
00964 return result;
00965 }
00966
00967
00968 Theorem BitvectorTheoremProducer::bitExtractConcatenation(const Expr & x,
00969 int i) {
00970 TRACE("bitvector", "bitExtractConcatenation(",
00971 x.toString(), ", "+ int2string(i) + " ) {");
00972 Type type = d_theoryBitvector->getBaseType(x);
00973 if(CHECK_PROOFS) {
00974
00975 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
00976 "BitvectorTheoremProducer::bitExtractConcatenation: "
00977 "term must be bitvector:\n x = "+x.toString());
00978 CHECK_SOUND(CONCAT == x.getOpKind() && x.arity() >= 2,
00979 "BitvectorTheoremProducer::bitExtractConcatenation: "
00980 "the bitvector must be a concat:\n x = " + x.toString());
00981 }
00982
00983
00984 int bvLength = d_theoryBitvector->BVSize(x);
00985 if(CHECK_PROOFS) {
00986 CHECK_SOUND(0 <= i && i < bvLength,
00987 "BitvectorTheoremProducer::bitExtractNot:"
00988 "illegal boolean extraction was attempted at position i = "
00989 + int2string(i)
00990 + "\non bitvector x = " + x.toString()
00991 + "\nwhose bvLength is = " +
00992 int2string(bvLength));
00993 }
00994
00995
00996 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
00997
00998 int numOfKids = x.arity();
00999 int lenOfKidsSeen = 0;
01000 Expr bitExtractKid;
01001 for(int count = numOfKids-1; count >= 0; --count) {
01002 int bvLengthOfKid = d_theoryBitvector->BVSize(x[count]);
01003 if(lenOfKidsSeen <= i && i < bvLengthOfKid + lenOfKidsSeen) {
01004 bitExtractKid =
01005 d_theoryBitvector->newBoolExtractExpr(x[count], i - lenOfKidsSeen);
01006 break;
01007 }
01008 lenOfKidsSeen += bvLengthOfKid;
01009 }
01010 DebugAssert(!bitExtractKid.isNull(),
01011 "BitvectorTheoremProducer::bitExtractConcatenation: "
01012 "something's broken...");
01013
01014 Assumptions a;
01015 Proof pf;
01016 if(withProof())
01017 pf = newPf("bit_extract_concatenation", x, rat(i));
01018 Theorem result(newRWTheorem(bitExtract, bitExtractKid, a, pf));
01019 TRACE("bitvector", "bitExtractConcatenation => ", result, " }");
01020 return result;
01021 }
01022
01023 Theorem BitvectorTheoremProducer::bitExtractConstBVMult(const Expr& t,
01024 int i)
01025 {
01026 TRACE("bitvector", "input to bitExtractConstBVMult(", t.toString(), ")");
01027 TRACE("bitvector", "input to bitExtractConstBVMult(", int2string(i), ")");
01028
01029 Type type = t.getType();
01030 if(CHECK_PROOFS) {
01031 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01032 "BitvectorTheoremProducer::bitExtractConstBVMult:"
01033 "the term must be a bitvector" + t.toString());
01034 CHECK_SOUND(BVMULT == t.getOpKind() && 2 == t.arity(),
01035 "BitvectorTheoremProducer::bitExtractConstBVMult:"
01036 "the term must be a bitvector" + t.toString());
01037
01038 int bvLength= d_theoryBitvector->BVSize(t);
01039 CHECK_SOUND(0 <= i && i < bvLength,
01040 "BitvectorTheoremProducer::bitExtractNot:"
01041 "illegal boolean extraction was attempted at position i = "
01042 + int2string(i)
01043 + "\non bitvector x = " + t.toString()
01044 + "\nwhose bvLength is = " +
01045 int2string(bvLength));
01046 CHECK_SOUND(BVCONST == t[0].getKind(),
01047 "BitvectorTheoremProducer::bitExtractConstBVMult:"
01048 "illegal BVMULT expression" + t.toString());
01049 }
01050 int len = d_theoryBitvector->BVSize(t[0]);
01051 std::vector<Expr> k;
01052 for(int j=0; j < len; ++j)
01053 if (d_theoryBitvector->getBVConstValue(t[0], j)) {
01054 Expr fixedleftshiftTerm =
01055 d_theoryBitvector->newFixedLeftShiftExpr(t[1], j);
01056 k.push_back(fixedleftshiftTerm);
01057 }
01058 int bvLength = d_theoryBitvector->BVSize(t);
01059
01060 Expr mult;
01061
01062 switch(k.size()) {
01063 case 0:
01064
01065 mult = d_theoryBitvector->newBVZeroString(bvLength);
01066 break;
01067 case 1:
01068 mult = pad(bvLength, k[0]);
01069 break;
01070 default:
01071 mult = d_theoryBitvector->newBVPlusExpr(bvLength, k);
01072 break;
01073 }
01074 Expr output = d_theoryBitvector->newBoolExtractExpr(mult, i);
01075
01076
01077 const Expr bitExtract =
01078 d_theoryBitvector->newBoolExtractExpr(t, i);
01079
01080 Assumptions a;
01081 Proof pf;
01082 if(withProof()) pf = newPf("bit_extract_const_bvmult", t, rat(i));
01083 const Theorem result = newRWTheorem(bitExtract,output,a,pf);
01084 TRACE("bitvector",
01085 "output of bitExtract_const_bvmult(", result, ")");
01086 return result;
01087 }
01088
01089
01090 Theorem BitvectorTheoremProducer::bitExtractBVMult(const Expr& t,
01091 int i)
01092 {
01093 TRACE("bitvector", "input to bitExtractBVMult(", t.toString(), ")");
01094 TRACE("bitvector", "input to bitExtractBVMult(", int2string(i), ")");
01095
01096 Type type = t.getType();
01097 if(CHECK_PROOFS) {
01098 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01099 "BitvectorTheoremProducer::bitExtractBVMult:"
01100 "the term must be a bitvector" + t.toString());
01101 CHECK_SOUND(BVMULT == t.getOpKind() && 2 == t.arity(),
01102 "BitvectorTheoremProducer::bitExtractBVMult:"
01103 "the term must be a bitvector" + t.toString());
01104 int bvLength= d_theoryBitvector->BVSize(t);
01105 CHECK_SOUND(0 <= i && i < bvLength,
01106 "BitvectorTheoremProducer::bitExtractNot:"
01107 "illegal boolean extraction was attempted at position i = "
01108 + int2string(i)
01109 + "\non bitvector t = " + t.toString()
01110 + "\nwhose Length is = " +
01111 int2string(bvLength));
01112 CHECK_SOUND(BVCONST != t[0].getOpKind(),
01113 "BitvectorTheoremProducer::bitExtractBVMult:"
01114 "illegal BVMULT expression" + t.toString());
01115 }
01116 int len = d_theoryBitvector->BVSize(t[0]);
01117 Expr trueExpression = d_theoryBitvector->trueExpr();
01118 std::vector<Expr> k;
01119 for(int j=len-1; j >= 0; j--) {
01120 Expr boolExt = d_theoryBitvector->newBoolExtractExpr(t[0],j);
01121 Expr cond = trueExpression.iffExpr(boolExt);
01122 Expr lShiftTerm = d_theoryBitvector->newFixedLeftShiftExpr(t[1], j);
01123 int shiftLen = d_theoryBitvector->BVSize(lShiftTerm);
01124 Expr zeroString = d_theoryBitvector->newBVZeroString(shiftLen);
01125 Expr iteTerm = cond.iteExpr(lShiftTerm, zeroString);
01126 k.push_back(iteTerm);
01127 }
01128
01129 if(CHECK_PROOFS)
01130 CHECK_SOUND(k.size() > 0,
01131 "BitvectorTheoremProducer::bitExtractBVMult:"
01132 "size of output vector must be > 0");
01133
01134 int bvLength = d_theoryBitvector->BVSize(t);
01135 Expr mult;
01136 if(k.size() >= 2)
01137 mult = d_theoryBitvector->newBVPlusExpr(bvLength, k);
01138 else
01139 mult = k[0];
01140 Expr output = d_theoryBitvector->newBoolExtractExpr(mult, i);
01141
01142
01143 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(t, i);
01144
01145 Assumptions a;
01146 Proof pf;
01147 if(withProof()) pf = newPf("bit_extract_bvmult", t, rat(i));
01148 const Theorem result = newRWTheorem(bitExtract,output,a,pf);
01149 TRACE("bitvector","output of bitExtract_bvmult(", result, ")");
01150 return result;
01151 }
01152
01153 Theorem BitvectorTheoremProducer::bitExtractExtraction(const Expr & x,
01154 int i)
01155 {
01156 TRACE("bitvector", "input to bitExtractExtraction(", x.toString(), ")");
01157 TRACE("bitvector", "input to bitExtractExtraction(", int2string(i), ")");
01158
01159 Type type = x.getType();
01160 if(CHECK_PROOFS) {
01161
01162 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01163 "BitvectorTheoremProducer::bitExtract-Extraction:"
01164 "term must be bitvector.");
01165 CHECK_SOUND(EXTRACT == x.getOpKind() && 1 == x.arity(),
01166 "BitvectorTheoremProducer::bitExtract-Extraction:"
01167 "the bitvector must be an extract." + x.toString());
01168
01169 int bvLength= d_theoryBitvector->BVSize(type.getExpr());
01170 CHECK_SOUND(0 <= i && i < bvLength,
01171 "BitvectorTheoremProducer::bitExtractNot:"
01172 "illegal boolean extraction was attempted at position i = "
01173 + int2string(i)
01174 + "\non bitvector t = " + x.toString()
01175 + "\nwhose Length is = " +
01176 int2string(bvLength));
01177 int extractLeft = d_theoryBitvector->getExtractHi(x);
01178 int extractRight = d_theoryBitvector->getExtractLow(x);
01179 CHECK_SOUND(extractLeft >= extractRight && extractLeft >= 0,
01180 "BitvectorTheoremProducer::bitExtract-Extraction:"
01181 "illegal boolean extraction was attempted." + int2string(i) +
01182 int2string(extractLeft) + int2string(extractRight));
01183 CHECK_SOUND(0 <= i && i < extractLeft-extractRight+1,
01184 "BitvectorTheoremProducer::bitExtract-Extraction:"
01185 "illegal boolean extraction was attempted." + int2string(i) +
01186 int2string(extractLeft) + int2string(extractRight));
01187 }
01188
01189 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
01190 const Expr bitExtractExtraction =
01191 d_theoryBitvector->newBoolExtractExpr(x[0], i +
01192 d_theoryBitvector->getExtractLow(x));
01193
01194 Assumptions a;
01195 Proof pf;
01196 if(withProof()) pf = newPf("bit_extract_extraction", x, rat(i));
01197 Theorem result(newRWTheorem(bitExtract, bitExtractExtraction, a, pf));
01198 TRACE("bitvector",
01199 "output of bitExtractExtraction(", result, ")");
01200 return result;
01201 }
01202
01203 Theorem
01204 BitvectorTheoremProducer::
01205 bitExtractBVPlus(const std::vector<Theorem>& t1BitExtractThms,
01206 const std::vector<Theorem>& t2BitExtractThms,
01207 const Expr& bvPlusTerm, int bitPos)
01208 {
01209 TRACE("bitvector","input to bitExtractBVPlus(", bvPlusTerm.toString(), ")");
01210 TRACE("bitvector","input to bitExtractBVPlus(", int2string(bitPos), ")");
01211
01212 if(CHECK_PROOFS) {
01213 CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind() && 2 == bvPlusTerm.arity(),
01214 "BitvectorTheoremProducer::bitExtractBVPlus:"
01215 "illegal bitvector fed to the function." +
01216 bvPlusTerm.toString());
01217 CHECK_SOUND(d_theoryBitvector->getBVPlusParam(bvPlusTerm) >= 0,
01218 "BitvectorTheoremProducer::bitExtractBVPlus:"
01219 "illegal bitvector fed to the function." +
01220 bvPlusTerm.toString());
01221 CHECK_SOUND(bitPos+1 == (int)t1BitExtractThms.size() &&
01222 bitPos+1 == (int)t2BitExtractThms.size(),
01223 "BitvectorTheoremProducer::bitExtractBVPlus:"
01224 "illegal bitvector fed to the function." +
01225 int2string(bitPos));
01226 const Expr& t1 = bvPlusTerm[0];
01227 const Expr& t2 = bvPlusTerm[1];
01228 std::vector<Theorem>::const_iterator i = t1BitExtractThms.begin();
01229 std::vector<Theorem>::const_iterator iend = t1BitExtractThms.end();
01230 std::vector<Theorem>::const_iterator j = t2BitExtractThms.begin();
01231 for(; i !=iend; ++i, ++j) {
01232 const Expr& t1Expr = i->getLHS();
01233 const Expr& t2Expr = j->getLHS();
01234 CHECK_SOUND(t1Expr[0] == t1 && t2Expr[0] == t2,
01235 "BitvectorTheoremProducer::bitExtractBVPlus:"
01236 "illegal bitvector fed to the function." +
01237 t1Expr.toString() + " ==\n" +
01238 t1.toString() + "\n" +
01239 t2.toString() + " == \n" +
01240 t2Expr.toString());
01241 }
01242 }
01243 const Expr lhs =
01244 d_theoryBitvector->newBoolExtractExpr(bvPlusTerm, bitPos);
01245 Expr rhs;
01246 const Expr& t1_iBit = (t1BitExtractThms[bitPos]).getRHS();
01247 const Expr& t2_iBit = (t2BitExtractThms[bitPos]).getRHS();
01248 if(0 != bitPos) {
01249 const Expr carry_iBit =
01250 computeCarry(t1BitExtractThms, t2BitExtractThms, bitPos);
01251
01252
01253
01254
01255 rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit);
01256
01257
01258
01259 } else
01260
01261 rhs = !(t1_iBit.iffExpr(t2_iBit));
01262
01263 Assumptions a;
01264 Proof pf;
01265 if(withProof())
01266 pf = newPf("bit_extract_BVPlus_rule",bvPlusTerm,rat(bitPos));
01267 Theorem result = newRWTheorem(lhs, rhs, a, pf);
01268 TRACE("bitvector","output of bitExtractBVPlus(", result, ")");
01269 return result;
01270 }
01271
01272 Expr
01273 BitvectorTheoremProducer::
01274 computeCarry(const std::vector<Theorem>& t1BitExtractThms,
01275 const std::vector<Theorem>& t2BitExtractThms,
01276 int i){
01277 vector<Expr> carry;
01278 int bitPos = i;
01279 DebugAssert(bitPos >= 0,
01280 "computeCarry: negative bitExtract_Pos is illegal");
01281 if(0 == bitPos) {
01282 const Expr& t1Thm = t1BitExtractThms[bitPos].getRHS();
01283 const Expr& t2Thm = t2BitExtractThms[bitPos].getRHS();
01284 carry.push_back(t1Thm.andExpr(t2Thm));
01285 }
01286 else {
01287 const Expr& t1Thm = t1BitExtractThms[bitPos-1].getRHS();
01288 const Expr& t2Thm = t2BitExtractThms[bitPos-1].getRHS();
01289 const Expr iMinusOneTerm = t1Thm.andExpr(t2Thm);
01290 carry.push_back(iMinusOneTerm);
01291
01292 const Expr iMinusOneCarry =
01293 computeCarry(t1BitExtractThms,t2BitExtractThms,bitPos-1);
01294 const Expr secondTerm = t1Thm.andExpr(iMinusOneCarry);
01295 carry.push_back(secondTerm);
01296
01297 const Expr thirdTerm = t2Thm.andExpr(iMinusOneCarry);
01298
01299 carry.push_back(thirdTerm);
01300 }
01301 return orExpr(carry);
01302 }
01303
01304 Theorem
01305 BitvectorTheoremProducer::
01306 bitExtractBVPlusPreComputed(const Theorem& t1_i,
01307 const Theorem& t2_i,
01308 const Expr& bvPlusTerm,
01309 int bitPos,
01310 int precomputedFlag)
01311 {
01312 DebugAssert(0 != precomputedFlag,
01313 "precomputedFlag cannot be 0");
01314 TRACE("bitvector","input to bitExtractBVPlus(", bvPlusTerm.toString(), ")");
01315 TRACE("bitvector","input to bitExtractBVPlus(", int2string(bitPos), ")");
01316
01317 if(CHECK_PROOFS) {
01318 CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind() && 2 == bvPlusTerm.arity(),
01319 "BitvectorTheoremProducer::bitExtractBVPlus:"
01320 "illegal bitvector fed to the function." +
01321 bvPlusTerm.toString());
01322 CHECK_SOUND(d_theoryBitvector->getBVPlusParam(bvPlusTerm) >= 0,
01323 "BitvectorTheoremProducer::bitExtractBVPlus:"
01324 "illegal bitvector fed to the function." +
01325 bvPlusTerm.toString());
01326 const Expr& t1 = bvPlusTerm[0];
01327 const Expr& t2 = bvPlusTerm[1];
01328 CHECK_SOUND(t1_i.getLHS()[0] == t1 &&
01329 t2_i.getLHS()[0] == t2,
01330 "BitvectorTheoremProducer::bitExtractBVPlus:"
01331 "illegal theorems fed to the function. Theorem1 = " +
01332 t1_i.toString() + "\nTheorem2 = " + t2_i.toString());
01333 CHECK_SOUND(t1_i.getLHS().getOpKind() == BOOLEXTRACT &&
01334 t2_i.getLHS().getOpKind() == BOOLEXTRACT,
01335 "BitvectorTheoremProducer::bitExtractBVPlus:"
01336 "illegal theorems fed to the function. Theorem1 = " +
01337 t1_i.toString() + "\nTheorem2 = " + t2_i.toString());
01338 CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(t1_i.getLHS()) == bitPos &&
01339 d_theoryBitvector->getBoolExtractIndex(t2_i.getLHS()) == bitPos,
01340 "BitvectorTheoremProducer::bitExtractBVPlus:"
01341 "illegal theorems fed to the function. Theorem1 = " +
01342 t1_i.toString() + "\nTheorem2 = " + t2_i.toString());
01343 }
01344 const Expr lhs =
01345 d_theoryBitvector->newBoolExtractExpr(bvPlusTerm, bitPos);
01346 Expr rhs;
01347 const Expr& t1_iBit = t1_i.getRHS();
01348 const Expr& t2_iBit = t2_i.getRHS();
01349
01350 const Expr carry_iBit = computeCarryPreComputed(t1_i, t2_i, bitPos, precomputedFlag);
01351
01352 if(0 != bitPos) {
01353
01354
01355
01356
01357 rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit);
01358
01359 } else
01360
01361 rhs = !(t1_iBit.iffExpr(t2_iBit));
01362
01363 Assumptions a;
01364 Proof pf;
01365 if(withProof())
01366 pf = newPf("bit_extract_BVPlus_precomputed_rule",bvPlusTerm,rat(bitPos));
01367 Theorem result = newRWTheorem(lhs, rhs, a, pf);
01368 TRACE("bitvector","output of bitExtractBVPlus(", result, ")");
01369 return result;
01370 }
01371
01372
01373
01374 Expr
01375 BitvectorTheoremProducer::
01376 computeCarryPreComputed(const Theorem& t1_i,
01377 const Theorem& t2_i,
01378 int bitPos, int preComputed){
01379 DebugAssert(1 == preComputed ||
01380 2 == preComputed,
01381 "cannot happen");
01382 Expr carryout;
01383 Expr carryin;
01384 DebugAssert(bitPos >= 0,
01385 "computeCarry: negative bitExtract_Pos is illegal");
01386
01387 const Expr& t1Thm = t1_i.getRHS();
01388 const Expr& t2Thm = t2_i.getRHS();
01389 Expr x = t1Thm.andExpr(t2Thm);
01390 const Expr& t1 = t1_i.getLHS()[0];
01391 const Expr& t2 = t2_i.getLHS()[0];
01392 Expr t1Andt2 = t1.andExpr(t2);
01393 Expr index = t1Andt2.andExpr(rat(bitPos));
01394
01395 if(0 == bitPos) {
01396 if(1 == preComputed)
01397 d_theoryBitvector->d_bvPlusCarryCacheLeftBV.insert(index,x);
01398 else
01399 d_theoryBitvector->d_bvPlusCarryCacheRightBV.insert(index,x);
01400 carryout = x;
01401
01402 }
01403 else {
01404 if(1 == preComputed) {
01405 Expr indexMinusOne = t1Andt2.andExpr(rat(bitPos-1));
01406 if(d_theoryBitvector->d_bvPlusCarryCacheLeftBV.find(indexMinusOne) ==
01407 d_theoryBitvector->d_bvPlusCarryCacheLeftBV.end())
01408 DebugAssert(false,
01409 "this should not happen");
01410 carryin =
01411 (d_theoryBitvector->d_bvPlusCarryCacheLeftBV).find(indexMinusOne)->second;
01412 Expr secondTerm = t1Thm.andExpr(carryin);
01413 Expr thirdTerm = t2Thm.andExpr(carryin);
01414
01415 carryout = (x.orExpr(secondTerm)).orExpr(thirdTerm);
01416 d_theoryBitvector->d_bvPlusCarryCacheLeftBV.insert(index,carryout);
01417 }
01418 else {
01419 Expr indexMinusOne = t1Andt2.andExpr(rat(bitPos-1));
01420 if(d_theoryBitvector->d_bvPlusCarryCacheRightBV.find(indexMinusOne) ==
01421 d_theoryBitvector->d_bvPlusCarryCacheRightBV.end())
01422 DebugAssert(false,
01423 "this should not happen");
01424 carryin =
01425 (d_theoryBitvector->d_bvPlusCarryCacheRightBV).find(indexMinusOne)->second;
01426
01427 Expr secondTerm = t1Thm.andExpr(carryin);
01428 Expr thirdTerm = t2Thm.andExpr(carryin);
01429
01430 carryout = (x.orExpr(secondTerm)).orExpr(thirdTerm);
01431 d_theoryBitvector->d_bvPlusCarryCacheRightBV.insert(index,carryout);
01432 }
01433 }
01434
01435 return carryin;
01436 }
01437
01438 Theorem
01439 BitvectorTheoremProducer::
01440 zeroPaddingRule(const Expr& e, int i) {
01441 if(CHECK_PROOFS) {
01442 CHECK_SOUND(BITVECTOR == e.getType().getExpr().getOpKind(),
01443 "BitvectorTheoremProducer::zeroPaddingRule:"
01444 "Wrong Input: Input must be a bitvector. But the input is: " +
01445 e.toString());
01446 }
01447
01448 int bvLength =
01449 d_theoryBitvector->BVSize(d_theoryBitvector->getBaseType(e).getExpr());
01450
01451 if(CHECK_PROOFS) {
01452 CHECK_SOUND(0 <= i && i >= bvLength,
01453 "BitvectorTheoremProducer::zeroPaddingRule:"
01454 "bitPosition of extraction must be greater than bvLength" +
01455 int2string(i) + "bvLength:" + int2string(bvLength));
01456 }
01457 const Expr boolExtractExpr = d_theoryBitvector->newBoolExtractExpr(e, i);
01458
01459 Assumptions a;
01460 Proof pf;
01461 if(withProof())
01462 pf = newPf("zeropadding_rule", e, rat(i));
01463 return newRWTheorem(boolExtractExpr, d_theoryBitvector->falseExpr(), a, pf);
01464 }
01465
01466 Theorem
01467 BitvectorTheoremProducer::
01468 bvPlusAssociativityRule(const Expr& bvPlusTerm)
01469 {
01470 TRACE("bitvector",
01471 "input to bvPlusAssociativityRule(", bvPlusTerm.toString(), ")");
01472
01473 Type type = bvPlusTerm.getType();
01474 if(CHECK_PROOFS) {
01475 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01476 "BitvectorTheoremProducer::bvPlusAssociativityRule:"
01477 "term must be BITVECTOR type.");
01478 CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind(),
01479 "BitvectorTheoremProducer::bvPlusAssociativityRule:"
01480 "term must have the kind BVPLUS.");
01481 CHECK_SOUND(2 < bvPlusTerm.arity(),
01482 "BitvectorTheoremProducer::bvPlusAssociativityRule:"
01483 "term must have arity() greater than 2 for associativity.");
01484 }
01485 std::vector<Expr> BVPlusTerms0;
01486 std::vector<Expr>::const_iterator j = (bvPlusTerm.getKids()).begin();
01487 std::vector<Expr>::const_iterator jend = (bvPlusTerm.getKids()).end();
01488
01489 j++;
01490 BVPlusTerms0.insert(BVPlusTerms0.end(), j, jend);
01491 int bvLength = d_theoryBitvector->BVSize(bvPlusTerm);
01492 const Expr bvplus0 = d_theoryBitvector->newBVPlusExpr(bvLength,
01493 BVPlusTerms0);
01494
01495 std::vector<Expr> BVPlusTerms1;
01496 BVPlusTerms1.push_back(*((bvPlusTerm.getKids()).begin()));
01497 BVPlusTerms1.push_back(bvplus0);
01498 const Expr bvplusOutput = d_theoryBitvector->newBVPlusExpr(bvLength,
01499 BVPlusTerms1);
01500
01501 Assumptions a;
01502 Proof pf;
01503 if(withProof()) pf = newPf("bv_plus_associativityrule", bvPlusTerm);
01504 const Theorem result(newRWTheorem(bvPlusTerm, bvplusOutput, a, pf));
01505 TRACE("bitvector",
01506 "output of bvPlusAssociativityRule(", result, ")");
01507 return result;
01508 }
01509
01510
01511 Theorem BitvectorTheoremProducer::bitExtractNot(const Expr & x,
01512 int i) {
01513 TRACE("bitvector", "input to bitExtractNot(", x.toString(), ")");
01514 TRACE("bitvector", "input to bitExtractNot(", int2string(i), ")");
01515
01516 Type type = x.getType();
01517 if(CHECK_PROOFS) {
01518
01519 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01520 "BitvectorTheoremProducer::bitExtractNot:"
01521 "term must be bitvector.");
01522 CHECK_SOUND(BVNEG == x.getOpKind() && 1 == x.arity(),
01523 "BitvectorTheoremProducer::bitExtractNot:"
01524 "the bitvector must be an bitwise negation." + x.toString());
01525
01526 int bvLength= d_theoryBitvector->BVSize(type.getExpr());
01527 CHECK_SOUND(0 <= i && i < bvLength,
01528 "BitvectorTheoremProducer::bitExtractNot:"
01529 "illegal boolean extraction was attempted at position i = "
01530 + int2string(i)
01531 + "\non bitvector x = " + x.toString()
01532 + "\nwhose Length is = " +
01533 int2string(bvLength));
01534 }
01535
01536 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
01537 const Expr bitNegTerm = d_theoryBitvector->newBoolExtractExpr(x[0], i);
01538
01539 Assumptions a;
01540 Proof pf;
01541 if(withProof()) pf = newPf("bit_extract_bitwiseneg", x, rat(i));
01542 const Theorem result(newRWTheorem(bitExtract,!bitNegTerm,a,pf));
01543 TRACE("bitvector","output of bitExtractNot(", result, ")");
01544 return result;
01545 }
01546
01547 Theorem
01548 BitvectorTheoremProducer::bitExtractBitwise(const Expr & x,
01549 int i, int kind) {
01550 string funName = (kind==BVAND)? "bitExtractAnd" : "bitExtractOr";
01551 string pfName = (kind==BVAND)? "bit_extract_and" : "bit_extract_or";
01552 TRACE("bitvector", funName+"(", x, ", "+ int2string(i)+") {");
01553 Type type = x.getType();
01554 if(CHECK_PROOFS) {
01555 CHECK_SOUND(kind == BVAND || kind == BVOR,
01556 "BitvectorTheoremProducer::"+funName+": kind = "
01557 +d_theoryBitvector->getEM()->getKindName(kind));
01558
01559 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01560 "BitvectorTheoremProducer::"+funName+": "
01561 "term must be bitvector.\n x = "+x.toString()
01562 +" : "+type.toString());
01563 CHECK_SOUND(x.getOpKind() == kind && 2 <= x.arity(),
01564 "BitvectorTheoremProducer::"+funName+": "
01565 "the bitvector must be a bitwise AND.\n x = "
01566 + x.toString());
01567
01568 int size = d_theoryBitvector->BVSize(x);
01569 CHECK_SOUND(0 <= i && i < size,
01570 "BitvectorTheoremProducer::"+funName+": "
01571 "illegal boolean extraction was attempted.\n i = "
01572 + int2string(i) + "\n size = "+ int2string(size));
01573 }
01574
01575 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
01576 vector<Expr> kids;
01577 for(Expr::iterator j=x.begin(), jend=x.end(); j!=jend; ++j) {
01578 kids.push_back(d_theoryBitvector->newBoolExtractExpr(*j, i));
01579 }
01580
01581 Expr rhs = (kind==BVAND)? andExpr(kids) : orExpr(kids);
01582
01583 Assumptions a;
01584 Proof pf;
01585 if(withProof()) pf = newPf(pfName,x,rat(i));
01586 const Theorem result(newRWTheorem(bitExtract, rhs, a, pf));
01587 TRACE("bitvector", funName+" => ", result.toString(), " }");
01588 return result;
01589 }
01590
01591
01592 Theorem
01593 BitvectorTheoremProducer::bitExtractAnd(const Expr & x, int i) {
01594 return bitExtractBitwise(x, i, BVAND);
01595 }
01596
01597
01598 Theorem
01599 BitvectorTheoremProducer::bitExtractOr(const Expr & x, int i) {
01600 return bitExtractBitwise(x, i, BVOR);
01601 }
01602
01603
01604 Theorem BitvectorTheoremProducer::bitExtractFixedLeftShift(const Expr & x,
01605 int i) {
01606 TRACE("bitvector", "input to bitExtractFixedleftshift(", x.toString(), ")");
01607 TRACE("bitvector", "input to bitExtractFixedleftshift(", int2string(i), ")");
01608
01609 Type type = x.getType();
01610 if(CHECK_PROOFS) {
01611
01612 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01613 "BitvectorTheoremProducer::bitExtractFixedleftshift:"
01614 "term must be bitvector.");
01615 CHECK_SOUND(LEFTSHIFT == x.getOpKind() && 1 == x.arity(),
01616 "BitvectorTheoremProducer::bitExtractFixedleftshift:"
01617 "the bitvector must be an bitwise LEFTSHIFT." +
01618 x.toString());
01619 CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(x) >= 0,
01620 "BitvectorTheoremProducer::bitExtractFixedleftshift:"
01621 "the bitvector must be an bitwise LEFTSHIFT." +
01622 x.toString());
01623
01624 int bvLength= d_theoryBitvector->BVSize(type.getExpr());
01625 CHECK_SOUND(0 <= i && i < bvLength,
01626 "BitvectorTheoremProducer::bitExtractNot:"
01627 "illegal boolean extraction was attempted at position i = "
01628 + int2string(i)
01629 + "\non bitvector x = " + x.toString()
01630 + "\nwhose bvLength is = " +
01631 int2string(bvLength));
01632 }
01633
01634 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
01635 int shiftLength = d_theoryBitvector->getFixedLeftShiftParam(x);
01636 Expr output;
01637 if(0 <= i && i < shiftLength)
01638 output = d_theoryBitvector->falseExpr();
01639 else
01640 output =
01641 d_theoryBitvector->newBoolExtractExpr(x[0], i-shiftLength);
01642
01643 Assumptions a;
01644 Proof pf;
01645 if(withProof())
01646 pf = newPf("bit_extract_bitwisefixedleftshift", x,rat(i));
01647 const Theorem result = newRWTheorem(bitExtract, output, a, pf);
01648 TRACE("bitvector",
01649 "output of bitExtractFixedleftshift(", result, ")");
01650 return result;
01651 }
01652
01653 Theorem BitvectorTheoremProducer::bitExtractFixedRightShift(const Expr & x,
01654 int i) {
01655 TRACE("bitvector", "input to bitExtractFixedLeftShift(", x.toString(), ")");
01656 TRACE("bitvector", "input to bitExtractFixedLeftShift(", int2string(i), ")");
01657
01658 Type type = x.getType();
01659 if(CHECK_PROOFS) {
01660
01661 CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
01662 "BitvectorTheoremProducer::bitExtractFixedRightShift:"
01663 "term must be bitvector.");
01664 CHECK_SOUND(RIGHTSHIFT == x.getOpKind() && 1 == x.arity(),
01665 "BitvectorTheoremProducer::bitExtractFixedRightShift:"
01666 "the bitvector must be an bitwise RIGHTSHIFT." +
01667 x.toString());
01668 CHECK_SOUND(d_theoryBitvector->getFixedRightShiftParam(x) >= 0,
01669 "BitvectorTheoremProducer::bitExtractFixedRightShift:"
01670 "the bitvector must be an bitwise RIGHTSHIFT." +
01671 x.toString());
01672 }
01673
01674 int bvLength = d_theoryBitvector->BVSize(x);
01675 if(CHECK_PROOFS)
01676 CHECK_SOUND(0 <= i && i < bvLength,
01677 "BitvectorTheoremProducer::bitExtractNot:"
01678 "illegal boolean extraction was attempted at position i = "
01679 + int2string(i)
01680 + "\non bitvector t = " + x.toString()
01681 + "\nwhose Length is = " +
01682 int2string(bvLength));
01683
01684
01685 const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
01686 int shiftLength = d_theoryBitvector->getFixedRightShiftParam(x);
01687 Expr output;
01688 if(bvLength > i && i > bvLength-shiftLength-1)
01689 output = d_theoryBitvector->falseExpr();
01690 else
01691 output =
01692 d_theoryBitvector->newBoolExtractExpr(x[0], i);
01693
01694 Assumptions a;
01695 Proof pf;
01696 if(withProof())
01697 pf = newPf("bit_extract_bitwiseFixedRightShift", x,rat(i));
01698 const Theorem result = newRWTheorem(bitExtract, output, a, pf);
01699 TRACE("bitvector",
01700 "output of bitExtractFixedRightShift(", result, ")");
01701 return result;
01702 }
01703
01704
01705 static bool constantKids(const Expr& e) {
01706 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
01707 if(i->getOpKind() != BVCONST) return false;
01708 return true;
01709 }
01710
01711
01712
01713 Theorem BitvectorTheoremProducer::eqConst(const Expr& e) {
01714 if(CHECK_PROOFS) {
01715
01716 CHECK_SOUND(e.isEq(),
01717 "BitvectorTheoremProducer::eqConst: e = "+e.toString());
01718 CHECK_SOUND(constantKids(e),
01719 "BitvectorTheoremProducer::eqConst: e = "+e.toString());
01720 }
01721 Assumptions a;
01722 Proof pf;
01723 if(withProof())
01724 pf = newPf("bitvector_eq_const", e);
01725 Expr res((e[0]==e[1])? d_theoryBitvector->trueExpr() :
01726 d_theoryBitvector->falseExpr());
01727 return newRWTheorem(e, res, a, pf);
01728 }
01729
01730
01731
01732 Theorem BitvectorTheoremProducer::eqToBits(const Theorem& eq) {
01733 if(CHECK_PROOFS) {
01734 CHECK_SOUND(eq.isRewrite(),
01735 "BitvectorTheoremProducer::eqToBits: eq = "+eq.toString());
01736 }
01737
01738 const Expr& lhs = eq.getLHS();
01739 const Expr& rhs = eq.getRHS();
01740
01741 if(CHECK_PROOFS) {
01742 CHECK_SOUND(d_theoryBitvector->getBaseType(lhs).getExpr().getOpKind() == BITVECTOR,
01743 "BitvectorTheoremProducer::eqToBits: eq = "+eq.toString());
01744 CHECK_SOUND(d_theoryBitvector->BVSize(lhs)
01745 == d_theoryBitvector->BVSize(rhs),
01746 "BitvectorTheoremProducer::eqToBits: eq = "+eq.toString());
01747 }
01748
01749 int i=0, size=d_theoryBitvector->BVSize(lhs);
01750 vector<Expr> bitEqs;
01751 for(; i<size; i++) {
01752 Expr l = d_theoryBitvector->newBVExtractExpr(lhs, i, i);
01753 Expr r = d_theoryBitvector->newBVExtractExpr(rhs, i, i);
01754 bitEqs.push_back(l.eqExpr(r));
01755 }
01756 Expr res = andExpr(bitEqs);
01757 Assumptions a;
01758 Proof pf;
01759 if(withAssumptions())
01760 a = eq.getAssumptionsCopy();
01761 if(withProof())
01762 pf = newPf("eq_to_bits", eq.getExpr(), eq.getProof());
01763 return newTheorem(res, a, pf);
01764 }
01765
01766
01767
01768 Theorem BitvectorTheoremProducer::leftShiftToConcat(const Expr& e) {
01769 if(CHECK_PROOFS) {
01770
01771 CHECK_SOUND(e.getOpKind() == LEFTSHIFT && e.arity() == 1,
01772 "BitvectorTheoremProducer::leftShiftConst: e = "+e.toString());
01773 CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(e) >= 0,
01774 "BitvectorTheoremProducer::leftShiftConst: e = "+e.toString());
01775 }
01776 const Expr& e0 = e[0];
01777 vector<bool> bits;
01778
01779 int shiftSize=d_theoryBitvector->getFixedLeftShiftParam(e);
01780
01781 for(int i=0; i<shiftSize; ++i)
01782 bits.push_back(false);
01783
01784 Expr padding = d_theoryBitvector->newBVConstExpr(bits);
01785 Expr res = d_theoryBitvector->newConcatExpr(e0, padding);
01786
01787 Assumptions a;
01788 Proof pf;
01789 if(withProof())
01790 pf = newPf("leftshift_to_concat", e);
01791 return newRWTheorem(e, res, a, pf);
01792 }
01793
01794
01795 Theorem BitvectorTheoremProducer::rightShiftToConcat(const Expr& e) {
01796 if(CHECK_PROOFS) {
01797 CHECK_SOUND(e.getOpKind() == RIGHTSHIFT && e.arity() == 1,
01798 "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString());
01799 CHECK_SOUND(d_theoryBitvector->getFixedRightShiftParam(e) >= 0,
01800 "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString());
01801 }
01802 int bvLength = d_theoryBitvector->BVSize(e[0]);
01803
01804 int shiftSize=d_theoryBitvector->getFixedRightShiftParam(e);
01805 Expr padding = d_theoryBitvector->newBVZeroString(shiftSize);
01806
01807 Expr output;
01808 if(shiftSize >= bvLength)
01809 output = d_theoryBitvector->newBVZeroString(bvLength);
01810 else {
01811 Expr out0 =
01812 d_theoryBitvector->newBVExtractExpr(e[0],bvLength-1,shiftSize);
01813 output =
01814 d_theoryBitvector->newConcatExpr(padding,out0);
01815 }
01816
01817 DebugAssert(bvLength == d_theoryBitvector->BVSize(output),
01818 "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString());
01819
01820 Assumptions a;
01821 Proof pf;
01822 if(withProof())
01823 pf = newPf("rightshift_to_concat", e);
01824 return newRWTheorem(e, output, a, pf);
01825 }
01826
01827
01828
01829
01830 Theorem BitvectorTheoremProducer::constMultToPlus(const Expr& e) {
01831 DebugAssert(false,
01832 "BitvectorTheoremProducer::constMultToPlus: this rule does not work\n");
01833 if(CHECK_PROOFS) {
01834 CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2
01835 && e[0].isRational() && e[0].getRational().isInteger(),
01836 "BitvectorTheoremProducer::constMultToPlus:\n e = "
01837 +e.toString());
01838 }
01839
01840 Rational k = e[0].getRational();
01841 const Expr& t = e[1];
01842 int resLength = d_theoryBitvector->BVSize(e);
01843 string coeffBinary = abs(k).toString(2);
01844 int len = coeffBinary.length();
01845 Expr res;
01846 if(k == 0) {
01847
01848 vector<bool> bits;
01849 int len = resLength;
01850 for(int i=0; i<len; ++i) bits.push_back(false);
01851 res = d_theoryBitvector->newBVConstExpr(bits);
01852 } else {
01853
01854 vector<Expr> kids;
01855 for(int i=0; i<len; ++i) {
01856 if(coeffBinary[i] == '1')
01857 kids.push_back(d_theoryBitvector->newFixedLeftShiftExpr(t, (len-1)-i));
01858 }
01859 res = (kids.size() == 1)? kids[0]
01860 : d_theoryBitvector->newBVPlusExpr(resLength, kids);
01861
01862 if(k < 0) {
01863 vector<Expr> kk;
01864 kk.push_back(d_theoryBitvector->newBVNegExpr(res));
01865 kk.push_back(rat(1));
01866 res = d_theoryBitvector->newBVPlusExpr(resLength, kk);
01867 }
01868 }
01869
01870 Assumptions a;
01871 Proof pf;
01872 if(withProof())
01873 pf = newPf("const_mult_to_plus", e);
01874 return newRWTheorem(e, res, a, pf);
01875 }
01876
01877
01878 Theorem
01879 BitvectorTheoremProducer::bvplusZeroConcatRule(const Expr& e) {
01880 if(CHECK_PROOFS) {
01881 CHECK_SOUND(e.getOpKind()==CONCAT && e.arity()==2,
01882 "BitvectorTheoremProducer::bvplusZeroConcatRule: e = "
01883 +e.toString());
01884 CHECK_SOUND(e[0].getKind()==BVCONST && e[1].getOpKind()==BVPLUS
01885 && d_theoryBitvector->computeBVConst(e[0])==0,
01886 "BitvectorTheoremProducer::bvplusZeroConcatRule: e = "
01887 +e.toString());
01888 }
01889
01890 int constSize = d_theoryBitvector->BVSize(e[0]);
01891 const Expr& bvplus = e[1];
01892 int bvplusSize = d_theoryBitvector->getBVPlusParam(bvplus);
01893
01894
01895 int maxKidSize(0);
01896 for(Expr::iterator i=bvplus.begin(), iend=bvplus.end(); i!=iend; ++i) {
01897 int size(d_theoryBitvector->BVSize(*i));
01898
01899 if(i->getOpKind()==CONCAT && i->arity()>=2
01900 && (*i)[0].getKind()==BVCONST && d_theoryBitvector->computeBVConst((*i)[0])==0)
01901 size -= d_theoryBitvector->BVSize((*i)[0]);
01902 if(size > maxKidSize) maxKidSize = size;
01903 }
01904 int numKids = bvplus.arity();
01905
01906 int log2 = 0;
01907 for(int i=1; i < numKids; i *=2, log2++);
01908 if(log2+maxKidSize > bvplusSize) {
01909
01910 TRACE("bv 0@+", "bvplusZeroConcatRule(", e, "): skipped");
01911 return d_theoryBitvector->reflexivityRule(e);
01912 }
01913
01914 Expr res(d_theoryBitvector->newBVPlusExpr(bvplusSize+constSize,
01915 bvplus.getKids()));
01916 Assumptions a;
01917 Proof pf;
01918 if(withProof())
01919 pf = newPf("bvplus_zero_concat", e);
01920 return newRWTheorem(e, res, a, pf);
01921 }
01922
01923
01924
01925
01926 Theorem BitvectorTheoremProducer::extractConst(const Expr& e) {
01927 if(CHECK_PROOFS) {
01928
01929 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
01930 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
01931 CHECK_SOUND(constantKids(e),
01932 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
01933 }
01934
01935 int hi = d_theoryBitvector->getExtractHi(e);
01936 int low = d_theoryBitvector->getExtractLow(e);
01937 const Expr& e0 = e[0];
01938
01939 if(CHECK_PROOFS) {
01940 CHECK_SOUND(0 <= low && low <= hi,
01941 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
01942 CHECK_SOUND((unsigned)hi < d_theoryBitvector->getBVConstSize(e0),
01943 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
01944 }
01945 vector<bool> res;
01946
01947 for(int bit=low; bit <= hi; bit++)
01948 res.push_back(d_theoryBitvector->getBVConstValue(e0, bit));
01949
01950 Assumptions a;
01951 Proof pf;
01952 if(withProof())
01953 pf = newPf("extract_const", e);
01954 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), a, pf);
01955 }
01956
01957
01958 Theorem
01959 BitvectorTheoremProducer::extractWhole(const Expr& e) {
01960 if(CHECK_PROOFS) {
01961 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
01962 "BitvectorTheoremProducer::extractWhole: e = "+e.toString());
01963 }
01964
01965 int hi = d_theoryBitvector->getExtractHi(e);
01966 int low = d_theoryBitvector->getExtractLow(e);
01967 const Expr& e0 = e[0];
01968
01969 if(CHECK_PROOFS) {
01970 CHECK_SOUND(low ==0 && hi == d_theoryBitvector->BVSize(e0) - 1,
01971 "BitvectorTheoremProducer::extractWhole: e = "+e.toString()
01972 +"\n BVSize(e) = "+ int2string(d_theoryBitvector->BVSize(e0)));
01973 }
01974 Assumptions a;
01975 Proof pf;
01976 if(withProof())
01977 pf = newPf("extract_whole", e);
01978 return newRWTheorem(e, e0, a, pf);
01979 }
01980
01981
01982
01983 Theorem
01984 BitvectorTheoremProducer::extractExtract(const Expr& e) {
01985 if(CHECK_PROOFS) {
01986 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
01987 "BitvectorTheoremProducer::extractExtract: e = "+e.toString());
01988 }
01989
01990 int hi = d_theoryBitvector->getExtractHi(e);
01991 int low = d_theoryBitvector->getExtractLow(e);
01992 const Expr& e0 = e[0];
01993
01994 if(CHECK_PROOFS) {
01995
01996 CHECK_SOUND(0 <= low && low <= hi,
01997 "BitvectorTheoremProducer::extractExtract: e = "+e.toString());
01998
01999 CHECK_SOUND(e0.getOpKind() == EXTRACT && e0.arity() == 1,
02000 "BitvectorTheoremProducer::extractExtract: e0 = "
02001 +e0.toString());
02002 }
02003
02004 int hi0 = d_theoryBitvector->getExtractHi(e0);
02005 int low0 = d_theoryBitvector->getExtractLow(e0);
02006 const Expr& e00 = e0[0];
02007
02008 if(CHECK_PROOFS) {
02009
02010 CHECK_SOUND((0 <= low) && (low <= hi) && (hi <= hi0-low0),
02011 "BitvectorTheoremProducer::extractExtract:\n"
02012 " [hi:low][hi0:low0] = ["+ int2string(hi0)+":"+ int2string(low0)
02013 +"]["+ int2string(hi) + ":" + int2string(low)
02014 +"]\n e = "+e.toString());
02015 }
02016
02017 Expr res = d_theoryBitvector->newBVExtractExpr(e00, hi+low0, low+low0);
02018
02019 Assumptions a;
02020 Proof pf;
02021 if(withProof())
02022 pf = newPf("extract_extract", e);
02023 return newRWTheorem(e, res, a, pf);
02024 }
02025
02026
02027
02028 Theorem
02029 BitvectorTheoremProducer::extractConcat(const Expr& e) {
02030 TRACE("bitvector rules", "extractConcat(", e, ") {");
02031 if(CHECK_PROOFS) {
02032 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
02033 "BitvectorTheoremProducer::extractConcat: e = "+e.toString());
02034 }
02035
02036 int hi = d_theoryBitvector->getExtractHi(e);
02037 int low = d_theoryBitvector->getExtractLow(e);
02038 const Expr& e0 = e[0];
02039
02040 if(CHECK_PROOFS) {
02041
02042 CHECK_SOUND(0 <= low && low <= hi,
02043 "BitvectorTheoremProducer::extractConcat: e = "+e.toString());
02044 CHECK_SOUND(hi < d_theoryBitvector->BVSize(e0),
02045 "BitvectorTheoremProducer::extractConcat: e = "+e.toString()
02046 +"\n BVSize(e0) = "+ int2string(d_theoryBitvector->BVSize(e0)));
02047
02048 CHECK_SOUND(e0.getOpKind() == CONCAT,
02049 "BitvectorTheoremProducer::extractConcat: e0 = "
02050 +e0.toString());
02051 }
02052
02053 vector<Expr> kids;
02054 int width(d_theoryBitvector->BVSize(e0));
02055 TRACE("bitvector rules", "extractConcat: width=", width, "");
02056 for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend && width>low; ++i) {
02057 TRACE("bitvector rules", "extractConcat: *i=", *i, "");
02058 int w(d_theoryBitvector->BVSize(*i));
02059 int newWidth = width-w;
02060 int l(0), h(0);
02061 TRACE("bitvector rules", "extractConcat: w=", w, "");
02062 TRACE("bitvector rules", "extractConcat: newWidth=", newWidth, "");
02063 if(width > hi) {
02064 if(hi >= newWidth) {
02065 h = hi-newWidth;
02066 l = (newWidth <= low)? low-newWidth : 0;
02067 TRACE("bitvector rules", "extractConcat[newWidth<=hi<width]: h=",
02068 h, ", l="+ int2string(l));
02069 kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, h, l));
02070 }
02071 } else if(width > low) {
02072
02073 h = w-1;
02074 l = (newWidth <= low)? low-newWidth : 0;
02075 TRACE("bitvector rules", "extractConcat[low<width<=hi]: h=",
02076 h, ", l="+ int2string(l));
02077 kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, h, l));
02078 }
02079 width=newWidth;
02080 TRACE("bitvector rules", "extractConcat: width=", width, "");
02081 }
02082 Expr res = (kids.size()==1)? kids[0]
02083 : d_theoryBitvector->newConcatExpr(kids);
02084 Assumptions a;
02085 Proof pf;
02086 if(withProof())
02087 pf = newPf("extract_concat", e);
02088 Theorem thm(newRWTheorem(e, res, a, pf));
02089 TRACE("bitvector rules", "extractConcat => ", thm.getExpr(), " }");
02090 return thm;
02091 }
02092
02093
02094
02095
02096 Theorem
02097 BitvectorTheoremProducer::extractBitwise(const Expr& e, int kind,
02098 const string& pfName) {
02099 if(CHECK_PROOFS) {
02100 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
02101 "BitvectorTheoremProducer::"+pfName+": e = "+e.toString());
02102 CHECK_SOUND(kind == BVAND || kind == BVOR ||
02103 kind == BVNEG || kind == BVXOR ||
02104 kind == BVXNOR,
02105 "BitvectorTheoremProducer::"+pfName+": kind = "
02106 +d_theoryBitvector->getEM()->getKindName(kind));
02107 }
02108
02109 int hi = d_theoryBitvector->getExtractHi(e);
02110 int low = d_theoryBitvector->getExtractLow(e);
02111 const Expr& e0 = e[0];
02112
02113 if(CHECK_PROOFS) {
02114
02115 CHECK_SOUND(0 <= low && low <= hi,
02116 "BitvectorTheoremProducer::"+pfName+": e = "+e.toString());
02117
02118 CHECK_SOUND(e0.getOpKind() == kind,
02119 "BitvectorTheoremProducer::"+pfName+": e0 = "
02120 +e0.toString());
02121 }
02122
02123 vector<Expr> kids;
02124 for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend; ++i) {
02125 kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, hi, low));
02126 }
02127 Expr res = Expr(e0.getOp(), kids);
02128 Assumptions a;
02129 Proof pf;
02130 if(withProof())
02131 pf = newPf(pfName, e);
02132 return newRWTheorem(e, res, a, pf);
02133 }
02134
02135
02136 Theorem
02137 BitvectorTheoremProducer::extractAnd(const Expr& e) {
02138 return extractBitwise(e, BVAND, "extract_and");
02139 }
02140
02141
02142
02143 Theorem
02144 BitvectorTheoremProducer::extractOr(const Expr& e) {
02145 return extractBitwise(e, BVOR, "extract_or");
02146 }
02147
02148
02149
02150 Theorem
02151 BitvectorTheoremProducer::extractNeg(const Expr& e) {
02152 return extractBitwise(e, BVNEG, "extract_neg");
02153 }
02154
02155
02156 Theorem
02157 BitvectorTheoremProducer::iteExtractRule(const Expr& e) {
02158 if(CHECK_PROOFS) {
02159 CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity()==1,
02160 "BitvectorTheoremProducer::iteExtractRule: "
02161 "input must be an bitvector EXTRACT expr:\n"+
02162 e.toString());
02163 }
02164 int hi = d_theoryBitvector->getExtractHi(e);
02165 int low = d_theoryBitvector->getExtractLow(e);
02166
02167 if(CHECK_PROOFS) {
02168 CHECK_SOUND(e[0].getKind() == ITE &&
02169 e[0].arity()==3 &&
02170 BITVECTOR == e[0].getType().getExpr().getOpKind(),
02171 "BitvectorTheoremProducer::iteExtractRule: "
02172 "input must be an bitvector EXTRACT expr over an ITE:\n" +
02173 e.toString());
02174 CHECK_SOUND(hi >= low && d_theoryBitvector->BVSize(e[0]) >= hi-low,
02175 "BitvectorTheoremProducer::iteExtractRule: "
02176 "i should be greater than j in e[i:j] = "
02177 +e.toString());
02178 }
02179 const Expr ite = e[0];
02180 Expr cond = ite[0];
02181 Expr e1 = d_theoryBitvector->newBVExtractExpr(ite[1],hi,low);
02182 Expr e2 = d_theoryBitvector->newBVExtractExpr(ite[2],hi,low);
02183 Expr output = Expr(CVCL::ITE,cond,e1,e2);
02184
02185 Assumptions a;
02186 Proof pf;
02187 if(withProof())
02188 pf = newPf("ite_extract_rule", e);
02189 return newRWTheorem(e, output, a, pf);
02190 }
02191
02192
02193 Theorem
02194 BitvectorTheoremProducer::iteBVnegRule(const Expr& e) {
02195 if(CHECK_PROOFS) {
02196 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity()==1,
02197 "BitvectorTheoremProducer::itebvnegrule: "
02198 "input must be an bitvector EXTRACT expr:\n"+
02199 e.toString());
02200 }
02201 if(CHECK_PROOFS) {
02202 CHECK_SOUND(e[0].getKind() == ITE &&
02203 e[0].arity()==3 &&
02204 BITVECTOR == e[0].getType().getExpr().getOpKind(),
02205 "BitvectorTheoremProducer::itebvnegrule: "
02206 "input must be an bitvector EXTRACT expr over an ITE:\n" +
02207 e.toString());
02208 }
02209 const Expr ite = e[0];
02210 Expr cond = ite[0];
02211 Expr e1 = d_theoryBitvector->newBVNegExpr(ite[1]);
02212 Expr e2 = d_theoryBitvector->newBVNegExpr(ite[2]);
02213 Expr output = Expr(CVCL::ITE,cond,e1,e2);
02214
02215 Assumptions a;
02216 Proof pf;
02217 if(withProof())
02218 pf = newPf("ite_bvneg_rule", e);
02219 return newRWTheorem(e, output, a, pf);
02220 }
02221
02222
02223 Theorem BitvectorTheoremProducer::negConst(const Expr& e) {
02224 if(CHECK_PROOFS) {
02225
02226 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
02227 "BitvectorTheoremProducer::negConst: e = "+e.toString());
02228 CHECK_SOUND(constantKids(e),
02229 "BitvectorTheoremProducer::negConst: e = "+e.toString());
02230 }
02231 const Expr& e0 = e[0];
02232 vector<bool> res;
02233
02234 for(int bit=0, size=d_theoryBitvector->getBVConstSize(e0); bit<size; bit++)
02235 res.push_back(!d_theoryBitvector->getBVConstValue(e0, bit));
02236
02237 Assumptions a;
02238 Proof pf;
02239 if(withProof())
02240 pf = newPf("bitneg_const", e);
02241 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), a, pf);
02242 }
02243
02244
02245
02246 Theorem
02247 BitvectorTheoremProducer::negConcat(const Expr& e) {
02248 if(CHECK_PROOFS) {
02249
02250 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
02251 "BitvectorTheoremProducer::negConcat: e = "+e.toString());
02252 CHECK_SOUND(e[0].getOpKind() == CONCAT,
02253 "BitvectorTheoremProducer::negConcat: e = "+e.toString());
02254 }
02255
02256 const Expr& e0 = e[0];
02257
02258 vector<Expr> kids;
02259 for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend; ++i)
02260 kids.push_back(d_theoryBitvector->newBVNegExpr(*i));
02261
02262 Expr res = d_theoryBitvector->newConcatExpr(kids);
02263
02264 Assumptions a;
02265 Proof pf;
02266 if(withProof())
02267 pf = newPf("bitneg_concat", e);
02268 return newRWTheorem(e, res, a, pf);
02269 }
02270
02271
02272 Theorem
02273 BitvectorTheoremProducer::negNeg(const Expr& e) {
02274 if(CHECK_PROOFS) {
02275 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
02276 "BitvectorTheoremProducer::negNeg: e = "+e.toString());
02277 CHECK_SOUND(e[0].getOpKind() == BVNEG && e[0].arity() == 1,
02278 "BitvectorTheoremProducer::negNeg: e = "+e.toString());
02279 }
02280
02281 Assumptions a;
02282 Proof pf;
02283 if(withProof())
02284 pf = newPf("bitneg_neg", e);
02285 return newRWTheorem(e, e[0][0], a, pf);
02286 }
02287
02288
02289 Theorem
02290 BitvectorTheoremProducer::negBVand(const Expr& e) {
02291 if(CHECK_PROOFS) {
02292 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
02293 "BitvectorTheoremProducer::negBVand: e = "+e.toString());
02294 CHECK_SOUND(e[0].getOpKind() == BVAND,
02295 "BitvectorTheoremProducer::negBVand: e = "+e.toString());
02296 }
02297 Expr output;
02298 std::vector<Expr> negated;
02299 for(Expr::iterator i = e[0].begin(),iend=e[0].end();i!=iend;++i)
02300 negated.push_back(d_theoryBitvector->newBVNegExpr(*i));
02301 output = d_theoryBitvector->newBVOrExpr(negated);
02302
02303 Assumptions a;
02304 Proof pf;
02305 if(withProof())
02306 pf = newPf("bitneg_and", e);
02307 return newRWTheorem(e, output, a, pf);
02308 }
02309
02310
02311
02312 Theorem
02313 BitvectorTheoremProducer::negBVor(const Expr& e) {
02314 if(CHECK_PROOFS) {
02315 CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
02316 "BitvectorTheoremProducer::negBVor: e = "+e.toString());
02317 CHECK_SOUND(e[0].getOpKind() == BVOR,
02318 "BitvectorTheoremProducer::negBVor: e = "+e.toString());
02319 }
02320
02321 Expr output;
02322 std::vector<Expr> negated;
02323 for(Expr::iterator i = e[0].begin(),iend=e[0].end();i!=iend;++i)
02324 negated.push_back(d_theoryBitvector->newBVNegExpr(*i));
02325 output = d_theoryBitvector->newBVAndExpr(negated);
02326
02327 Assumptions a;
02328 Proof pf;
02329 if(withProof())
02330 pf = newPf("bitneg_or", e);
02331 return newRWTheorem(e, output, a, pf);
02332 }
02333
02334
02335
02336
02337 Theorem BitvectorTheoremProducer::bitwiseConst(const Expr& e,
02338 const std::vector<int>& idxs,
02339 bool isAnd) {
02340 string funName(isAnd? "andConst" : "orConst");
02341 if(CHECK_PROOFS) {
02342
02343 CHECK_SOUND(e.getOpKind() == isAnd? BVAND : BVOR,
02344 "BitvectorTheoremProducer::"+funName+": e = "+e.toString());
02345 CHECK_SOUND(idxs.size() >= 2, "BitvectorTheoremProducer::"+funName
02346 +"():\n e = "+e.toString());
02347 for(size_t i=0; i<idxs.size(); ++i) {
02348 CHECK_SOUND(idxs[i] < e.arity(),
02349 "BitvectorTheoremProducer::"+funName+": idxs["
02350 +int2string(i)+"]="+int2string(idxs[i])
02351 +", e.arity() = "+int2string(e.arity())
02352 +"\n e = "+e.toString());
02353 CHECK_SOUND(e[idxs[i]].getKind() == BVCONST,
02354 "BitvectorTheoremProducer::"+funName+": e = "+e.toString());
02355 }
02356 }
02357 vector<bool> bits;
02358
02359 int size = d_theoryBitvector->BVSize(e);
02360 for(int bit=0; bit<size; bit++)
02361 bits.push_back(isAnd);
02362
02363 vector<Expr> kids(1);
02364 size_t ii(0);
02365 int idx(idxs[0]);
02366 for(int i=0, iend=e.arity(); i<iend; ++i) {
02367 const Expr& ei = e[i];
02368 if(i == idx) {
02369 if(CHECK_PROOFS) {
02370 CHECK_SOUND(ei.getKind() == BVCONST,
02371 "BitvectorTheoremProducer::"+funName+": e["
02372 +int2string(i)+"] = "+ei.toString());
02373 CHECK_SOUND(d_theoryBitvector->getBVConstSize(ei) == (unsigned)size,
02374 "BitvectorTheoremProducer::"+funName+": e["
02375 +int2string(i)+"] = "+ei.toString());
02376 }
02377
02378 for(int bit=0; bit<size; bit++)
02379 bits[bit] = isAnd ?
02380 (bits[bit] && d_theoryBitvector->getBVConstValue(ei, bit))
02381 : (bits[bit] || d_theoryBitvector->getBVConstValue(ei, bit));
02382
02383 if(ii < idxs.size())
02384 idx = idxs[++ii];
02385 else
02386 idx = e.arity();
02387 }
02388 else
02389 kids.push_back(ei);
02390 }
02391
02392 kids[0] = d_theoryBitvector->newBVConstExpr(bits);
02393
02394 Expr res = (kids.size() == 1)? kids[0]
02395 : isAnd? d_theoryBitvector->newBVAndExpr(kids)
02396 : d_theoryBitvector->newBVOrExpr(kids);
02397
02398 Assumptions a;
02399 Proof pf;
02400 if(withProof()) {
02401
02402 vector<Expr> indices;
02403 for(size_t i=0, iend=idxs.size(); i<iend; ++i)
02404 indices.push_back(rat(idxs[i]));
02405 pf = newPf(isAnd? "bitand_const" : "bitor_const",
02406 e, Expr(RAW_LIST, indices));
02407 }
02408 return newRWTheorem(e, res, a, pf);
02409 }
02410
02411
02412
02413
02414
02415
02416
02417
02418 Theorem
02419 BitvectorTheoremProducer::bitwiseConcat(const Expr& e, int idx, bool isAnd) {
02420 string funName(isAnd? "andConcat" : "orConcat");
02421 if(CHECK_PROOFS) {
02422 CHECK_SOUND(e.getOpKind() == isAnd? BVAND : BVOR,
02423 "BitvectorTheoremProducer::"+funName+": e = "+e.toString());
02424 CHECK_SOUND(idx < e.arity(),
02425 "BitvectorTheoremProducer::"+funName+": e = "+e.toString()
02426 +"\n idx = "+int2string(idx)
02427 +"\n e.arity() = "+int2string(e.arity()));
02428 CHECK_SOUND(e[idx].getOpKind() == CONCAT && e[idx].arity() > 0,
02429 "BitvectorTheoremProducer::"+funName+": e["+int2string(idx)
02430 +"] = "+e[idx].toString());
02431 }
02432
02433 int arity = e.arity();
02434 const Expr& ei = e[idx];
02435
02436
02437 vector<Expr> concatKids;
02438
02439 int hi=d_theoryBitvector->BVSize(e)-1;
02440 int low=hi-d_theoryBitvector->BVSize(ei[0])+1;
02441
02442 for(int i=0, iend=ei.arity(); i<iend; ++i) {
02443
02444 vector<Expr> kids;
02445 for(int j=0; j<arity; ++j) {
02446 if(j==idx)
02447 kids.push_back(ei[i]);
02448 else
02449 kids.push_back(d_theoryBitvector->newBVExtractExpr(e[j], hi, low));
02450 }
02451 if(isAnd)
02452 concatKids.push_back(d_theoryBitvector->newBVAndExpr(kids));
02453 else
02454 concatKids.push_back(d_theoryBitvector->newBVOrExpr(kids));
02455 if(i+1<iend) {
02456 int newHi = low-1;
02457 low = low - d_theoryBitvector->BVSize(ei[i+1]);
02458 hi = newHi;
02459 }
02460 }
02461 Expr res = d_theoryBitvector->newConcatExpr(concatKids);
02462 Assumptions a;
02463 Proof pf;
02464 if(withProof())
02465 pf = newPf(isAnd? "bitand_concat" : "bitor_concat", e, rat(idx));
02466 return newRWTheorem(e, res, a, pf);
02467 }
02468
02469
02470 Theorem
02471 BitvectorTheoremProducer::bitwiseFlatten(const Expr& e, bool isAnd) {
02472 string funName(isAnd? "andFlatten" : "orFlatten");
02473 int kind = isAnd? BVAND : BVOR;
02474
02475 if(CHECK_PROOFS) {
02476 CHECK_SOUND(e.getOpKind() == kind && e.arity()>=2,
02477 "BitvectorTheoremProducer::"+funName+": e = "+e.toString());
02478 }
02479 int bvLength = d_theoryBitvector->BVSize(e);
02480 Expr output;
02481 int flag = 0;
02482
02483
02484 std::vector<Expr> flattenkids;
02485 for(Expr::iterator i = e.begin(),iend=e.end();i!=iend; ++i) {
02486 if(i->getOpKind() == kind)
02487 flattenkids.insert(flattenkids.end(),
02488 i->getKids().begin(),i->getKids().end());
02489 else
02490 flattenkids.push_back(*i);
02491 }
02492
02493
02494 std::vector<Expr> outputkids;
02495 ExprMap<int> likeTerms;
02496 std::vector<Expr>::iterator j = flattenkids.begin();
02497 std::vector<Expr>::iterator jend = flattenkids.end();
02498 for(;j!=jend; ++j) {
02499
02500 flag = sameKidCheck(*j, likeTerms);
02501 switch(flag) {
02502 case 0:
02503
02504 outputkids.push_back(*j);
02505 break;
02506 case 1:
02507
02508 break;
02509 case -1:{
02510
02511 if(isAnd)
02512 output = d_theoryBitvector->newBVZeroString(bvLength);
02513 else
02514 output = d_theoryBitvector->newBVOneString(bvLength);
02515 break;
02516 }
02517 default:
02518 DebugAssert(false,
02519 "control should not reach here");
02520 break;
02521 }
02522 if(-1 == flag)
02523 break;
02524 }
02525
02526 if(flag != -1) {
02527 DebugAssert(outputkids.size()>0,
02528 "TheoryBitvector::bitwiseFlatten: fatal error");
02529
02530 if(CHECK_PROOFS)
02531 CHECK_SOUND(outputkids.size() > 0,
02532 "TheoryBitvector:bitwiseFlatten: fatal error");
02533 sort(outputkids.begin(), outputkids.end());
02534 if(outputkids.size() >= 2)
02535 output = Expr(e.getOp(), outputkids);
02536 else
02537 output = *(outputkids.begin());
02538 }
02539
02540 Assumptions a;
02541 Proof pf;
02542 if(withProof())
02543 pf = newPf(isAnd? "bitand_flatten" : "bitor_flatten", e);
02544 return newRWTheorem(e, output, a, pf);
02545 }
02546
02547
02548 Theorem BitvectorTheoremProducer::andConst(const Expr& e,
02549 const std::vector<int>& idxs) {
02550 return bitwiseConst(e, idxs, true);
02551 }
02552
02553
02554
02555
02556
02557 Theorem
02558 BitvectorTheoremProducer::andZero(const Expr& e, int idx) {
02559 if(CHECK_PROOFS) {
02560 CHECK_SOUND(e.getOpKind() == BVAND,
02561 "BitvectorTheoremProducer::andZero: e = "+e.toString());
02562 CHECK_SOUND(idx < e.arity(),
02563 "BitvectorTheoremProducer::andZero: e = "+e.toString()
02564 +"\n idx = "+int2string(idx)
02565 +"\n e.arity() = "+int2string(e.arity()));
02566 CHECK_SOUND(e[idx].getKind() == BVCONST &&
02567 0 == d_theoryBitvector->computeBVConst(e[idx]),
02568 "BitvectorTheoremProducer::andZero: e["+int2string(idx)
02569 +"] = "+e[idx].toString());
02570 }
02571
02572 Assumptions a;
02573 Proof pf;
02574 if(withProof())
02575 pf = newPf("bitand_zero", e, rat(idx));
02576 return newRWTheorem(e, e[idx], a, pf);
02577 }
02578
02579
02580 Theorem
02581 BitvectorTheoremProducer::andOne(const Expr& e, const vector<int> idxs) {
02582 if(CHECK_PROOFS) {
02583 CHECK_SOUND(e.getOpKind() == BVAND,
02584 "BitvectorTheoremProducer::andOne: e = "+e.toString());
02585 CHECK_SOUND(idxs.size() > 0,
02586 "BitvectorTheoremProducer::andOne: e = "+e.toString());
02587 int lastIdx(-1);
02588 for(vector<int>::const_iterator i=idxs.begin(), iend=idxs.end();
02589 i!=iend; ++i) {
02590 CHECK_SOUND(lastIdx < (*i) && (*i) < e.arity(),
02591 "BitvectorTheoremProducer::andOne: e = "+e.toString()
02592 +"\n lastIdx = "+int2string(lastIdx)
02593 +"\n *i = "+int2string(*i)
02594 +"\n e.arity() = "+int2string(e.arity()));
02595 lastIdx=(*i);
02596 const Expr& ei = e[*i];
02597 CHECK_SOUND(ei.getKind() == BVCONST,
02598 "BitvectorTheoremProducer::andOne: e["+int2string(*i)
02599 +"] = "+ei.toString());
02600
02601 for(int j=0,jend=(int)d_theoryBitvector->getBVConstSize(ei); j<jend; ++j)
02602 CHECK_SOUND(d_theoryBitvector->getBVConstValue(ei, j),
02603 "BitvectorTheoremProducer::andOne: e["+int2string(j)
02604 +"] = "+ei.toString());
02605 }
02606 }
02607 Assumptions a;
02608 Proof pf;
02609 if(withProof()) {
02610 vector<Expr> es;
02611 es.push_back(e);
02612 for(vector<int>::const_iterator i=idxs.begin(), iend=idxs.end();
02613 i!=iend; ++i)
02614 es.push_back(rat(*i));
02615 pf=newPf("bitand_one", es);
02616 }
02617
02618 vector<Expr> kids;
02619 size_t idx(0);
02620 for(int i=0; i<e.arity(); ++i) {
02621 if(i == idxs[idx]) idx++;
02622 else kids.push_back(e[i]);
02623 }
02624 Expr res;
02625 if(kids.size()>=2) res = Expr(e.getOp(), kids);
02626 else if(kids.size()==1) res = kids[0];
02627 else res = e[0];
02628 return newRWTheorem(e, res, a, pf);
02629 }
02630
02631
02632
02633
02634
02635
02636
02637
02638 Theorem
02639 BitvectorTheoremProducer::andConcat(const Expr& e, int idx) {
02640 return bitwiseConcat(e, idx, true);
02641 }
02642
02643
02644
02645
02646 Theorem
02647 BitvectorTheoremProducer::andFlatten(const Expr& e) {
02648 return bitwiseFlatten(e, true);
02649 }
02650
02651
02652
02653
02654 Theorem BitvectorTheoremProducer::orConst(const Expr& e,
02655 const std::vector<int>& idxs) {
02656 return bitwiseConst(e, idxs, false);
02657 }
02658
02659
02660
02661
02662
02663
02664 Theorem
02665 BitvectorTheoremProducer::orOne(const Expr& e, int idx) {
02666 if(CHECK_PROOFS) {
02667 CHECK_SOUND(e.getOpKind() == BVOR,
02668 "BitvectorTheoremProducer::orOne: e = "+e.toString());
02669 CHECK_SOUND(idx < e.arity(),
02670 "BitvectorTheoremProducer::orOne: e = "+e.toString()
02671 +"\n idx = "+int2string(idx)
02672 +"\n e.arity() = "+int2string(e.arity()));
02673 CHECK_SOUND(e[idx].getKind() == BVCONST,
02674 "BitvectorTheoremProducer::orOne: e["+int2string(idx)
02675 +"] = "+e[idx].toString());
02676 }
02677
02678 const Expr& ei = e[idx];
02679
02680 if(CHECK_PROOFS) {
02681 for(int i=0, iend=d_theoryBitvector->getBVConstSize(ei); i<iend; ++i)
02682 CHECK_SOUND(d_theoryBitvector->getBVConstValue(ei,i),
02683 "BitvectorTheoremProducer::orOne: e["+int2string(idx)
02684 +"] = "+ei.toString());
02685 }
02686
02687 Assumptions a;
02688 Proof pf;
02689 if(withProof())
02690 pf = newPf("bitand_zero", e, rat(idx));
02691 return newRWTheorem(e, e[idx], a, pf);
02692 }
02693
02694
02695 Theorem
02696 BitvectorTheoremProducer::orZero(const Expr& e, const vector<int> idxs) {
02697 if(CHECK_PROOFS) {
02698 CHECK_SOUND(e.getOpKind() == BVOR,
02699 "BitvectorTheoremProducer::orZero: e = "+e.toString());
02700 CHECK_SOUND(idxs.size() > 0,
02701 "BitvectorTheoremProducer::orZero: e = "+e.toString());
02702 int lastIdx(-1);
02703 for(vector<int>::const_iterator i=idxs.begin(), iend=idxs.end();
02704 i!=iend; ++i) {
02705 CHECK_SOUND(lastIdx < (*i) && (*i) < e.arity(),
02706 "BitvectorTheoremProducer::orZero: e = "+e.toString()
02707 +"\n lastIdx = "+int2string(lastIdx)
02708 +"\n *i = "+int2string(*i)
02709 +"\n e.arity() = "+int2string(e.arity()));
02710 lastIdx=(*i);
02711 const Expr& ei = e[*i];
02712 CHECK_SOUND(ei.getKind() == BVCONST &&
02713 d_theoryBitvector->computeBVConst(ei)==0,
02714 "BitvectorTheoremProducer::orZero: e["+int2string(*i)
02715 +"] = "+ei.toString());
02716 }
02717 }
02718 Assumptions a;
02719 Proof pf;
02720 if(withProof()) {
02721 vector<Expr> es;
02722 es.push_back(e);
02723 for(vector<int>::const_iterator i=idxs.begin(), iend=idxs.end();
02724 i!=iend; ++i)
02725 es.push_back(rat(*i));
02726 pf=newPf("bitor_zero", es);
02727 }
02728
02729 vector<Expr> kids;
02730 size_t idx(0);
02731 for(int i=0; i<e.arity(); ++i) {
02732 if(i == idxs[idx]) idx++;
02733 else kids.push_back(e[i]);
02734 }
02735 Expr res;
02736 if(kids.size()>=2) res = Expr(e.getOp(), kids);
02737 else if(kids.size()==1) res = kids[0];
02738 else res = e[0];
02739 return newRWTheorem(e, res, a, pf);
02740 }
02741
02742
02743
02744
02745
02746
02747
02748
02749 int BitvectorTheoremProducer::sameKidCheck(const Expr& e,
02750 ExprMap<int>& likeTerms) {
02751
02752 int flag = 0;
02753
02754
02755 ExprMap<int>::iterator it = likeTerms.find(e);
02756
02757
02758 if(it==likeTerms.end()) {
02759 switch(e.getOpKind()) {
02760 case BVNEG: {
02761 likeTerms[e] = 1;
02762 ExprMap<int>::iterator it0 = likeTerms.find(e[0]);
02763 if(it0!=likeTerms.end())
02764 flag = -1;
02765 break;
02766 }
02767 default: {
02768 likeTerms[e] = 1;
02769 Expr bvNeg = d_theoryBitvector->newBVNegExpr(e);
02770 ExprMap<int>::iterator negIt = likeTerms.find(bvNeg);
02771 if(negIt!=likeTerms.end())
02772 flag=-1;
02773 break;
02774 }
02775 }
02776 return flag;
02777 }
02778
02779
02780 flag = 1;
02781 switch(e.getOpKind()) {
02782 case BVNEG: {
02783 ExprMap<int>::iterator it0 = likeTerms.find(e[0]);
02784 if(it0!=likeTerms.end())
02785 flag = -1;
02786 break;
02787 }
02788 default: {
02789 Expr bvNeg = d_theoryBitvector->newBVNegExpr(e);
02790 ExprMap<int>::iterator negIt = likeTerms.find(bvNeg);
02791 if(negIt!=likeTerms.end())
02792 flag=-1;
02793 break;
02794 }
02795 }
02796 return flag;
02797 }
02798
02799
02800
02801
02802
02803
02804
02805 Theorem
02806 BitvectorTheoremProducer::orConcat(const Expr& e, int idx) {
02807 return bitwiseConcat(e, idx, false);
02808 }
02809
02810
02811
02812
02813 Theorem
02814 BitvectorTheoremProducer::orFlatten(const Expr& e) {
02815 return bitwiseFlatten(e, false);
02816 }
02817
02818
02819
02820
02821 Theorem BitvectorTheoremProducer::concatConst(const Expr& e) {
02822 if(CHECK_PROOFS) {
02823
02824 CHECK_SOUND(e.getOpKind() == CONCAT,
02825 "BitvectorTheoremProducer::concatConst: e = "+e.toString());
02826 CHECK_SOUND(constantKids(e),
02827 "BitvectorTheoremProducer::concatConst: e = "+e.toString());
02828 }
02829 vector<bool> res;
02830 for(int i=e.arity()-1; i >= 0; --i) {
02831 for(int bit=0, size=d_theoryBitvector->getBVConstSize(e[i]); bit < size; bit++)
02832 res.push_back(d_theoryBitvector->getBVConstValue(e[i], bit));
02833 }
02834 Assumptions a;
02835 Proof pf;
02836 if(withProof())
02837 pf = newPf("concat_const", e);
02838 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), a, pf);
02839 }
02840
02841
02842
02843 Theorem
02844 BitvectorTheoremProducer::concatFlatten(const Expr& e) {
02845 if(CHECK_PROOFS) {
02846 CHECK_SOUND(e.getOpKind() == CONCAT && e.arity() >= 2,
02847 "BitvectorTheoremProducer::concatFlatten: e = "+e.toString());
02848 }
02849
02850 vector<Expr> kids;
02851 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
02852 if(i->getOpKind() == CONCAT)
02853 kids.insert(kids.end(), i->getKids().begin(), i->getKids().end());
02854 else
02855 kids.push_back(*i);
02856 }
02857 Assumptions a;
02858 Proof pf;
02859 if(withProof())
02860 pf = newPf("concat_flatten", e);
02861 return newRWTheorem(e, Expr(e.getOp(), kids), a, pf);
02862 }
02863
02864
02865
02866 Theorem
02867 BitvectorTheoremProducer::concatMergeExtract(const Expr& e) {
02868 if(CHECK_PROOFS) {
02869 CHECK_SOUND(e.getOpKind() == CONCAT && e.arity() >= 2,
02870 "BitvectorTheoremProducer::concatMergeExtract: e = "
02871 +e.toString());
02872 CHECK_SOUND(e[0].getOpKind() == EXTRACT,
02873 "BitvectorTheoremProducer::concatMergeExtract: e = "
02874 +e.toString());
02875 CHECK_SOUND(d_theoryBitvector->getExtractHi(e[0]) >= d_theoryBitvector->getExtractLow(e[0]),
02876 "BitvectorTheoremProducer::concatMergeExtract: e = "
02877 +e.toString());
02878 }
02879
02880 const Expr& base = e[0][0];
02881
02882 if(CHECK_PROOFS) {
02883
02884 int low = d_theoryBitvector->getExtractLow(e[0]);
02885 for(int i=1, iend=e.arity(); i<iend; ++i) {
02886 const Expr& ei = e[i];
02887 CHECK_SOUND(ei.getOpKind() == EXTRACT && ei[0] == base,
02888 "BitvectorTheoremProducer::concatMergeExtract: e["
02889 +int2string(i)+"] = "+ei.toString()
02890 +"\n base = "+base.toString());
02891 CHECK_SOUND(d_theoryBitvector->getExtractHi(ei) >= d_theoryBitvector->getExtractLow(ei),
02892 "BitvectorTheoremProducer::concatMergeExtract: e["
02893 +int2string(i)+"] = "+e.toString());
02894
02895 int newHi = d_theoryBitvector->getExtractHi(ei);
02896
02897 CHECK_SOUND(0 <= newHi && newHi == low-1,
02898 "BitvectorTheoremProducer::concatMergeExtract:\n e["
02899 +int2string(i-1)+"] = "+e[i-1].toString()
02900 +"\n e["+int2string(i)+"] = "+ei.toString());
02901 low = d_theoryBitvector->getExtractLow(ei);
02902 }
02903 }
02904
02905 int hi = d_theoryBitvector->getExtractHi(e[0]);
02906 int low = d_theoryBitvector->getExtractLow(e[e.arity()-1]);
02907 Expr res = d_theoryBitvector->newBVExtractExpr(base, hi, low);
02908
02909 Assumptions a;
02910 Proof pf;
02911 if(withProof())
02912 pf = newPf("concat_merge_extract", e);
02913 return newRWTheorem(e, res, a, pf);
02914 }
02915
02916
02917
02918
02919 Theorem BitvectorTheoremProducer::bvplusConst(const Expr& e) {
02920 if(CHECK_PROOFS) {
02921
02922 CHECK_SOUND(e.getOpKind() == BVPLUS,
02923 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
02924 CHECK_SOUND(constantKids(e),
02925 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
02926 CHECK_SOUND(d_theoryBitvector->getBVPlusParam(e) > 0,
02927 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
02928 }
02929
02930
02931 Rational acc(0);
02932 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
02933 Rational x = d_theoryBitvector->computeBVConst(*i);
02934 TRACE("bitvector rewrite", "bvplusConst: x(", *i, ") = "+x.toString());
02935 acc += x;
02936 TRACE("bitvector rewrite", "bvplusConst: acc = ", acc, "");
02937 }
02938
02939 int resSize = d_theoryBitvector->getBVPlusParam(e);
02940 vector<bool> res(resSize);
02941 for(int i=0; i<resSize; i++) {
02942 res[i] = (mod(acc, 2) == 1);
02943 TRACE("bitvector rewrite", "bvplusConst: acc = ", acc, "");
02944 TRACE("bitvector rewrite", "bvplusConst: res["+int2string(i)+"] = ",
02945 res[i], "");
02946 acc = floor(acc/2);
02947 }
02948
02949 Assumptions a;
02950 Proof pf;
02951 if(withProof())
02952 pf = newPf("bvplus_const", e);
02953 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), a, pf);
02954 }
02955
02956
02957
02958
02959 Theorem BitvectorTheoremProducer::bvmultConst(const Expr& e) {
02960 if(CHECK_PROOFS) {
02961
02962 CHECK_SOUND(e.getOpKind() == BVMULT,
02963 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
02964 CHECK_SOUND(constantKids(e),
02965 "BitvectorTheoremProducer::extractConst: e = "+e.toString());
02966 }
02967 Rational c = d_theoryBitvector->computeBVConst(e[0]);
02968
02969 Rational x = d_theoryBitvector->computeBVConst(e[1]) * c;
02970
02971
02972 int resSize = d_theoryBitvector->BVSize(e.getType().getExpr());
02973 vector<bool> res(resSize);
02974 for(int i=0; i<resSize; i++) {
02975 res[i] = (mod(x, 2) == 1);
02976 x = floor(x/2);
02977 }
02978
02979 Assumptions a;
02980 Proof pf;
02981 if(withProof())
02982 pf = newPf("bvmult_const", e);
02983 return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), a, pf);
02984 }
02985
02986 Theorem
02987 BitvectorTheoremProducer::zeroCoeffBVMult(const Expr& e) {
02988 if(CHECK_PROOFS) {
02989 CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2,
02990 "BitvectorTheoremProducer::zeroCoeffBVMult: e = "+e.toString());
02991 CHECK_SOUND(BVCONST == e[0].getKind(),
02992 "BitvectorTheoremProducer::zeroCoeffBVMult: e = "+e.toString());
02993 Rational c = d_theoryBitvector->computeBVConst(e[0]);
02994 CHECK_SOUND(0 == c,
02995 "BitvectorTheoremProducer::zeroCoeffBVMult:"
02996 "coeff must be zero:\n e = " +e.toString());
02997 }
02998 int size = d_theoryBitvector->BVSize(e);
02999 Expr output = d_theoryBitvector->newBVZeroString(size);
03000
03001 Assumptions a;
03002 Proof pf;
03003 if(withProof())
03004 pf = newPf("zerocoeff_bvmult", e);
03005 Theorem result(newRWTheorem(e,output,a,pf));
03006 return result;
03007 }
03008
03009 Theorem
03010 BitvectorTheoremProducer::oneCoeffBVMult(const Expr& e) {
03011 if(CHECK_PROOFS) {
03012 CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2,
03013 "BitvectorTheoremProducer::oneCoeffBVMult: e = "
03014 +e.toString());
03015 CHECK_SOUND(BVCONST == e[0].getKind(),
03016 "BitvectorTheoremProducer::oneCoeffBVMult: e = "
03017 +e.toString());
03018 Rational c = d_theoryBitvector->computeBVConst(e[0]);
03019 CHECK_SOUND(1 == c,
03020 "BitvectorTheoremProducer::oneCoeffBVMult:"
03021 "coeff must be one:\n e = " +e.toString());
03022 }
03023 int size = d_theoryBitvector->BVSize(e);
03024 Expr output = pad(size,e);
03025
03026 Assumptions a;
03027 Proof pf;
03028 if(withProof())
03029 pf = newPf("onecoeff_bvmult", e);
03030 Theorem result(newRWTheorem(e,output,a,pf));
03031 return result;
03032 }
03033
03034
03035 Theorem
03036 BitvectorTheoremProducer::flipBVMult(const Expr& e) {
03037 if(CHECK_PROOFS) {
03038 CHECK_SOUND(e.arity()==2 && BVMULT == e.getOpKind(),
03039 "BVMULT must have exactly 2 kids: " + e.toString());
03040 }
03041 int len = d_theoryBitvector->BVSize(e);
03042 Expr output = d_theoryBitvector->newBVMultExpr(len,e[1],e[0]);
03043
03044 Assumptions a;
03045 Proof pf;
03046 if(withProof())
03047 pf = newPf("flip_bvmult", e);
03048 Theorem result(newRWTheorem(e,output,a,pf));
03049 return result;
03050 }
03051
03052
03053
03054
03055
03056
03057 Expr
03058 BitvectorTheoremProducer::pad(int len, const Expr& e) {
03059 DebugAssert(len >=0,
03060 "TheoryBitvector::pad:"
03061 "padding bvLength must be a non-negative integer: "+
03062 int2string(len));
03063 DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
03064 "TheoryBitvector::newBVPlusExpr:"
03065 "input must be a BITVECTOR: " + e.toString());
03066
03067 int size = d_theoryBitvector->BVSize(e);
03068 Expr res;
03069 if(size == len)
03070 res = e;
03071 else if (len < size)
03072 res = d_theoryBitvector->newBVExtractExpr(e,len-1,0);
03073 else {
03074
03075 Expr zero = d_theoryBitvector->newBVZeroString(len-size);
03076 res = d_theoryBitvector->newConcatExpr(zero,e);
03077 }
03078 return res;
03079 }
03080
03081
03082 Theorem
03083 BitvectorTheoremProducer::padBVPlus(const Expr& e) {
03084 if(CHECK_PROOFS) {
03085 CHECK_SOUND(BVPLUS == e.getOpKind() && e.arity()>1,
03086 "BitvectorTheoremProducer::padBVPlus: "
03087 "input must be a BVPLUS: " + e.toString());
03088 }
03089 int len = d_theoryBitvector->BVSize(e);
03090 vector<Expr> kids;
03091 for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03092 if(i->getOpKind() == BVMULT) {
03093 Expr e0 = pad(len, (*i)[0]);
03094 Expr e1 = pad(len, (*i)[1]);
03095 Expr out = d_theoryBitvector->newBVMultExpr(len,e0,e1);
03096 kids.push_back(out);
03097 }
03098 else
03099 kids.push_back(pad(len, *i));
03100 }
03101
03102 Expr output = d_theoryBitvector->newBVPlusExpr(len, kids);
03103
03104 Assumptions a;
03105 Proof pf;
03106 if(withProof())
03107 pf = newPf("pad_bvplus", e);
03108 Theorem result(newRWTheorem(e,output,a,pf));
03109 return result;
03110 }
03111
03112
03113 Theorem
03114 BitvectorTheoremProducer::padBVMult(const Expr& e) {
03115 if(CHECK_PROOFS) {
03116 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity()==2,
03117 "BitvectorTheoremProducer::padBVMult: "
03118 "input must be a BVMULT: " + e.toString());
03119 CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
03120 BITVECTOR==e[1].getType().getExpr().getOpKind(),
03121 "for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
03122 }
03123 int len = d_theoryBitvector->BVSize(e);
03124 Expr e0 = pad(len, e[0]);
03125 Expr e1 = pad(len, e[1]);
03126
03127 Expr output = d_theoryBitvector->newBVMultExpr(len,e0,e1);
03128
03129 Assumptions a;
03130 Proof pf;
03131 if(withProof())
03132 pf = newPf("pad_bvmult", e);
03133 Theorem result(newRWTheorem(e,output,a,pf));
03134 return result;
03135 }
03136
03137
03138 Theorem
03139 BitvectorTheoremProducer::bvConstMultAssocRule(const Expr& e) {
03140 if(CHECK_PROOFS) {
03141 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2,
03142 "BitvectorTheoremProducer::bvConstMultAssocRule: "
03143 "input must be a BVMULT: " + e.toString());
03144 CHECK_SOUND(BVMULT == e[1].getOpKind(),
03145 "BitvectorTheoremProducer::bvConstMultAssocRule: "
03146 "e[1] must be a BVMULT:\n e= " + e.toString());
03147 CHECK_SOUND(BVCONST == e[0].getKind() &&
03148 BVCONST == e[1][0].getKind(),
03149 "BitvectorTheoremProducer::bvConstMultAssocRule: "
03150 "e[0] & e[1][0] must be a BVCONST:\n e = " + e.toString());
03151 }
03152 int len = d_theoryBitvector->BVSize(e);
03153 int len0 = d_theoryBitvector->BVSize(e[0]);
03154 int len10 = d_theoryBitvector->BVSize(e[1][0]);
03155 int len11 = d_theoryBitvector->BVSize(e[1][1]);
03156 if(CHECK_PROOFS) {
03157 CHECK_SOUND(len == len0 && len0 == len10 && len0 == len11,
03158 "BitvectorTheoremProducer::bvConstMultAssocRule: "
03159 "kids of BVMULT must be equibvLength: ");
03160 }
03161 Rational e0 = d_theoryBitvector->computeBVConst(e[0]);
03162 Rational e10 = d_theoryBitvector->computeBVConst(e[1][0]);
03163 Expr c = d_theoryBitvector->newBVConstExpr(e0*e10, len);
03164 Expr output = d_theoryBitvector->newBVMultExpr(len, c, e[1][1]);
03165
03166 Assumptions a;
03167 Proof pf;
03168 if(withProof())
03169 pf = newPf("bvconstmult_assoc_rule", e);
03170 Theorem result(newRWTheorem(e,output,a,pf));
03171 return result;
03172 }
03173
03174
03175
03176
03177 Theorem
03178 BitvectorTheoremProducer::bvMultAssocRule(const Expr& e) {
03179 if(CHECK_PROOFS) {
03180 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2,
03181 "BitvectorTheoremProducer::bvMultAssocRule: "
03182 "input must be a BVMULT: " + e.toString());
03183 CHECK_SOUND(BVMULT == e[0].getOpKind() ||
03184 BVMULT == e[1].getOpKind(),
03185 "BitvectorTheoremProducer::bvMultAssocRule: "
03186 "e[0] or e[1] must be a BVMULT:\n e= " + e.toString());
03187 CHECK_SOUND(!(BVCONST == e[0].getOpKind() &&
03188 BVCONST == e[1][0].getOpKind()),
03189 "BitvectorTheoremProducer::bvMultAssocRule: "
03190 "e[0] & e[1][0] cannot be a BVCONST:\n e = " +
03191 e.toString());
03192 }
03193 int len = d_theoryBitvector->BVSize(e);
03194 int len0 = d_theoryBitvector->BVSize(e[0]);
03195 int len1 = d_theoryBitvector->BVSize(e[1]);
03196 if(CHECK_PROOFS)
03197 CHECK_SOUND(len == len0 && len0 == len1,
03198 "BitvectorTheoremProducer::bvMultAssocRule: "
03199 "kids of BVMULT must be equibvLength: ");
03200 Expr e0, e1;
03201 e0 = e[0];
03202 e1 = e[1];
03203
03204 std::vector<Expr> outputkids;
03205 if(BVMULT == e[0].getOpKind() && BVMULT != e[1].getOpKind()) {
03206 outputkids.push_back(e0[0]);
03207 outputkids.push_back(e0[1]);
03208 outputkids.push_back(e1);
03209
03210 } else if(BVMULT != e[0].getOpKind() && BVMULT == e[1].getOpKind()) {
03211 outputkids.push_back(e1[0]);
03212 outputkids.push_back(e1[1]);
03213 outputkids.push_back(e0);
03214 } else {
03215
03216 outputkids.push_back(e0[0]);
03217 outputkids.push_back(e0[1]);
03218 outputkids.push_back(e1[0]);
03219 outputkids.push_back(e1[1]);
03220 }
03221 sort(outputkids.begin(),outputkids.end());
03222
03223 Expr output;
03224 switch(outputkids.size()) {
03225 case 3: {
03226 Expr out1 =
03227 d_theoryBitvector->newBVMultExpr(len, outputkids[1],outputkids[2]);
03228 output =
03229 d_theoryBitvector->newBVMultExpr(len, outputkids[0], out1);
03230 break;
03231 }
03232 case 4: {
03233 Expr out0 =
03234 d_theoryBitvector->newBVMultExpr(len, outputkids[0], outputkids[1]);
03235 Expr out1 =
03236 d_theoryBitvector->newBVMultExpr(len, outputkids[2], outputkids[3]);
03237 output =
03238 d_theoryBitvector->newBVMultExpr(len, out0, out1);
03239 break;
03240 }
03241 }
03242
03243 Assumptions a;
03244 Proof pf;
03245 if(withProof())
03246 pf = newPf("bvmult_assoc_rule", e);
03247 Theorem result(newRWTheorem(e,output,a,pf));
03248 return result;
03249 }
03250
03251
03252 Theorem
03253 BitvectorTheoremProducer::bvMultDistRule(const Expr& e) {
03254 if(CHECK_PROOFS) {
03255 CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2,
03256 "BitvectorTheoremProducer::bvMultDistRule: "
03257 "input must be a BVMULT: " + e.toString());
03258 CHECK_SOUND(BVPLUS == e[1].getOpKind(),
03259 "BitvectorTheoremProducer::bvMultDistRule: "
03260 "input must be of the form a*(t1+...+tn): " + e.toString());
03261 }
03262 int bvLength= d_theoryBitvector->BVSize(e);
03263 int e0len = d_theoryBitvector->BVSize(e[0]);
03264 int e1len = d_theoryBitvector->BVSize(e[1]);
03265 if(CHECK_PROOFS) {
03266 CHECK_SOUND(bvLength== e0len && e0len == e1len,
03267 "BitvectorTheoremProducer::bvMultDistRule: "
03268 "all subterms must of equal bvLength: " + e.toString());
03269 }
03270 const Expr& e0 = e[0];
03271 const Expr& e1 = e[1];
03272
03273 std::vector<Expr> v;
03274 Expr::iterator i = e1.begin();
03275 Expr::iterator iend = e1.end();
03276 for(;i != iend; ++i) {
03277 Expr s = d_theoryBitvector->newBVMultExpr(bvLength, e0, *i);
03278 v.push_back(s);
03279 }
03280 Expr output = d_theoryBitvector->newBVPlusExpr(bvLength,v);
03281
03282 Assumptions a;
03283 Proof pf;
03284 if(withProof())
03285 pf = newPf("bvmult_distributivity_rule", e);
03286 Theorem result(newRWTheorem(e,output,a,pf));
03287 return result;
03288 }
03289
03290
03291
03292
03293 Theorem
03294 BitvectorTheoremProducer::flattenBVPlus(const Expr& e) {
03295 if(CHECK_PROOFS) {
03296 CHECK_SOUND(e.getOpKind() == BVPLUS && e.arity() >= 2,
03297 "BitvectorTheoremProducer::flattenBVPlus: e = "+e.toString());
03298 }
03299 int bvLength= d_theoryBitvector->BVSize(e);
03300 const int numOfKids = e.arity();
03301
03302 if(CHECK_PROOFS) {
03303 for(int i=0; i<numOfKids; ++i)
03304 CHECK_SOUND(d_theoryBitvector->BVSize(e[i]) == bvLength,
03305 "BitvectorTheoremProducer::flattenBVPlus: "
03306 "summands must be of the same bvLength as BVPLUS:\n e = "
03307 +e.toString());
03308 }
03309
03310
03311
03312 std::vector<Expr> v;
03313 for(int i = 0; i < numOfKids; ++i) {
03314 if(e[i].getOpKind() == BVPLUS) {
03315 const Expr& bvplusKid = e[i];
03316 const int bvplusArity = bvplusKid.arity();
03317 for(int j=0; j < bvplusArity; ++j)
03318 v.push_back(bvplusKid[j]);
03319 } else
03320 v.push_back(e[i]);
03321 }
03322 Expr eprime = d_theoryBitvector->newBVPlusExpr(bvLength, v);
03323
03324 Assumptions a;
03325 Proof pf;
03326 if(withProof())
03327 pf = newPf("flatten_bvplus", e);
03328 return newRWTheorem(e, eprime, a, pf);
03329 }
03330
03331 void
03332 BitvectorTheoremProducer::collectOneTermOfPlus(const Rational & coefficient,
03333 const Expr& term,
03334 ExprMap<Rational> & likeTerms,
03335 Rational & plusConstant)
03336 {
03337 ExprMap<Rational>::iterator it = likeTerms.find(term);
03338
03339 if(it!=likeTerms.end())
03340 likeTerms[term] += coefficient;
03341 else {
03342
03343 bool foundNegated= false;
03344 if (!likeTerms.empty()) {
03345 Expr negTerm= d_theoryBitvector->pushNegationRec(term, true).getRHS();
03346 it = likeTerms.find(negTerm);
03347 if (it!= likeTerms.end()) {
03348 foundNegated = true;
03349
03350
03351 likeTerms[negTerm] += -coefficient;
03352 plusConstant+= -1;
03353 }
03354 }
03355 if (!foundNegated)
03356
03357 likeTerms[term] = coefficient;
03358 }
03359 }
03360
03361 void
03362 BitvectorTheoremProducer::collectLikeTermsOfPlus(const Expr& e,
03363 ExprMap<Rational> & likeTerms,
03364 Rational & plusConstant) {
03365 likeTerms.clear();
03366 Expr::iterator i = e.begin();
03367 Expr::iterator iend = e.end();
03368 plusConstant= 0;
03369
03370 for(; i!=iend; ++i) {
03371 const Expr s = *i;
03372 switch(s.getOpKind()) {
03373 case BVMULT: {
03374
03375 if (s[0].getKind() == BVCONST) {
03376 Rational coefficient= d_theoryBitvector->computeBVConst(s[0]);
03377 const Expr& var = s[1];
03378 collectOneTermOfPlus(coefficient, var, likeTerms, plusConstant);
03379 }
03380 else {
03381 if(CHECK_PROOFS) {
03382 CHECK_SOUND(BVCONST != s[1].getKind(),
03383 "TheoryBitvector::combineLikeTerms: "
03384 "Unexpected MULT syntax:\n\n s = " + s.toString()
03385 +"\n\n in e = "+e.toString());
03386 }
03387 collectOneTermOfPlus(1, s, likeTerms, plusConstant);
03388 }
03389 break;
03390 }
03391 case BVUMINUS:
03392 collectOneTermOfPlus(-1, s[0], likeTerms, plusConstant);
03393 break;
03394 case BVCONST:
03395 plusConstant += d_theoryBitvector->computeBVConst(s);
03396 break;
03397 default:
03398
03399 collectOneTermOfPlus(1, s, likeTerms, plusConstant);
03400 break;
03401 }
03402 }
03403 }
03404
03405 static Rational boundedModulo(const Rational & value, const Rational & modulo,
03406 const Rational & lowerBound) {
03407 Rational ret = mod(value, modulo);
03408 if(ret == 0)
03409 return ret;
03410
03411 if (ret< lowerBound)
03412 ret+= modulo;
03413 else {
03414
03415 Rational end= modulo+lowerBound;
03416 if (ret >= end)
03417 ret-= modulo;
03418 }
03419 return ret;
03420 }
03421
03422 void
03423 BitvectorTheoremProducer::
03424 createNewPlusCollection(const Expr & e,
03425 const ExprMap<Rational> & likeTerms,
03426 Rational & plusConstant,
03427 std::vector<Expr> & result) {
03428 int bvplusLength= d_theoryBitvector->BVSize(e);
03429
03430 Rational power2(1);
03431 for(int i=0; i<bvplusLength; i += 1) power2 *= 2;
03432
03433 ExprMap<Rational>::iterator j = likeTerms.begin();
03434 ExprMap<Rational>::iterator jend = likeTerms.end();
03435 for(; j!=jend; ++j) {
03436
03437
03438
03439 Rational coefficient = boundedModulo(j->second, power2, -power2/2+1);
03440 if(coefficient == 0)
03441 continue;
03442 Expr multiplicand = j->first;
03443 Expr monomial;
03444 if (coefficient<0) {
03445
03446
03447 multiplicand=
03448 d_theoryBitvector->pushNegationRec(multiplicand, true).getRHS();
03449 coefficient= coefficient*-1;
03450 plusConstant +=coefficient;
03451 }
03452 if(coefficient == 1)
03453 monomial = multiplicand;
03454 else {
03455 Expr coeffExpr =
03456 d_theoryBitvector->newBVConstExpr(coefficient, bvplusLength);
03457 monomial =
03458 d_theoryBitvector->newBVMultExpr(bvplusLength, coeffExpr,multiplicand);
03459 }
03460 if(CHECK_PROOFS) {
03461 CHECK_SOUND(BITVECTOR==monomial.getType().getExpr().getOpKind(),
03462 "TheoryBitvector::combineLikeTerms:"
03463 "each monomial must be a bitvector:\n"
03464 "monomial = " + monomial.toString());
03465 CHECK_SOUND(bvplusLength == d_theoryBitvector->BVSize(monomial),
03466 "TheoryBitvector::combineLikeTerms:"
03467 "bvLength of each monomial must be the same as e:\n"
03468 "monomial = " + monomial.toString() + "\n e = " + e.toString());
03469 }
03470 result.push_back(monomial);
03471 }
03472
03473 plusConstant = boundedModulo(plusConstant, power2, 0);
03474
03475
03476 if(plusConstant != 0) {
03477 const Expr c =
03478 d_theoryBitvector->newBVConstExpr(plusConstant, bvplusLength);
03479 result.push_back(c);
03480 }
03481 }
03482
03483 Expr
03484 BitvectorTheoremProducer::sumNormalizedElements(int bvplusLength,
03485 const std::vector<Expr>&items){
03486
03487
03488 switch(items.size()) {
03489 case 0:
03490
03491 return d_theoryBitvector->newBVZeroString(bvplusLength);
03492
03493 case 1:
03494
03495 return items[0];
03496
03497 default:
03498
03499 return d_theoryBitvector->newBVPlusExpr(bvplusLength, items);
03500 }
03501 }
03502
03503 Theorem
03504 BitvectorTheoremProducer::combineLikeTermsRule(const Expr& e) {
03505 TRACE("bitvector rewrite", "combineLikeTermsRule(",e.toString(), ") {");
03506 if(CHECK_PROOFS) {
03507 CHECK_SOUND(BVPLUS == e.getOpKind() && e.arity()>=2,
03508 "TheoryBitvector::combineLikeTerms: "
03509 "input must be a BVPLUS term:\n e = " + e.toString());
03510 int bvplusLength = d_theoryBitvector->BVSize(e);
03511 Expr::iterator i = e.begin();
03512 Expr::iterator iend = e.end();
03513 for(;i!=iend;++i) {
03514 const Expr& s = *i;
03515 if(s.getOpKind() == BVPLUS) {
03516 CHECK_SOUND(s.getOpKind() != BVPLUS,
03517 "TheoryBitvector::combineLikeTerms: "
03518 "BVPLUS must be flattened:\n e = " + e.toString());
03519 }
03520
03521 int bvLength= d_theoryBitvector->BVSize(s);
03522
03523 CHECK_SOUND(bvLength==bvplusLength,
03524 "TheoryBitvector::combineLikeTerms: "
03525 "BVPLUS must be padded:\n e = " + e.toString());
03526
03527 if(s.getOpKind()==BVMULT) {
03528 int s0len = d_theoryBitvector->BVSize(s[0]);
03529 int s1len = d_theoryBitvector->BVSize(s[1]);
03530 CHECK_SOUND(bvplusLength == s0len && s0len== s1len,
03531 "all monoms must have the samebvLength "
03532 "as the bvplus term: " + e.toString());
03533 }
03534 }
03535 }
03536 int bvplusLength = d_theoryBitvector->BVSize(e);
03537 ExprMap<Rational> likeTerms;
03538 Rational theConstant(0);
03539 collectLikeTermsOfPlus(e, likeTerms, theConstant);
03540
03541 std::vector<Expr> collection;
03542 createNewPlusCollection(e, likeTerms, theConstant, collection);
03543
03544 Expr output= sumNormalizedElements(bvplusLength, collection);
03545
03546 TRACE("bitvector rewrite",
03547 "combineLikeTermsRule =>",output.toString(), "}");
03548 Assumptions a;
03549 Proof pf;
03550 if(withProof())
03551 pf=newPf("bvplus_combine_like_terms", e);
03552 return newRWTheorem(e, output, a, pf);
03553 }
03554
03555 Theorem
03556 BitvectorTheoremProducer::lhsMinusRhsRule(const Expr& e) {
03557 if(CHECK_PROOFS) {
03558 CHECK_SOUND(EQ == e.getKind() && e.arity() == 2,
03559 "BitvectorTheoremProducer::lhsMinusRhsRule: "
03560 "input must be an EQ: e = " +e.toString());
03561 CHECK_SOUND(BVPLUS == e[0].getOpKind() ||
03562 BVPLUS == e[1].getOpKind(),
03563 "BitvectorTheoremProducer::lhsMinusRhsRule: "
03564 "atleast one of the input subterms must be BVPLUS:"
03565 "e = " +e.toString());
03566 int bvLength0 = d_theoryBitvector->BVSize(e[0]);
03567 int bvLength1 = d_theoryBitvector->BVSize(e[1]);
03568 CHECK_SOUND(bvLength0 == bvLength1,
03569 "BitvectorTheoremProducer::lhsMinusRhsRule: "
03570 "both sides of EQ must be same Length. e = " +e.toString());
03571 for(Expr::iterator i=e[0].begin(),iend=e[0].end();i!=iend;++i) {
03572 int bvLength= d_theoryBitvector->BVSize(*i);
03573 CHECK_SOUND(bvLength0 == bvLength,
03574 "BitvectorTheoremProducer::lhsMinusRhsRule: "
03575 "all subterms of e[0] must be of same Length."
03576 "e = " +e.toString());
03577 }
03578 for(Expr::iterator i=e[1].begin(),iend=e[1].end();i!=iend;++i) {
03579 int bvLength= d_theoryBitvector->BVSize(*i);
03580 CHECK_SOUND(bvLength1 == bvLength,
03581 "BitvectorTheoremProducer::lhsMinusRhsRule: "
03582 "all subterms of e[1] must be of same Length."
03583 "e = " +e.toString());
03584 }
03585 }
03586 Expr output;
03587 int bvLength = d_theoryBitvector->BVSize(e[0]);
03588 std::vector<Expr> k;
03589
03590
03591 Expr zeroStr = d_theoryBitvector->newBVZeroString(bvLength);
03592
03593 if(e[0] == e[1])
03594 output = Expr(EQ, zeroStr, zeroStr);
03595 else {
03596
03597 std::vector<Expr> e0K = e[0].getKids();
03598 std::vector<Expr> e1K = e[1].getKids();
03599 for(vector<Expr>::iterator i=e0K.begin(),iend=e0K.end();i!=iend;++i){
03600 for(vector<Expr>::iterator j=e1K.begin(),jend=e1K.end();j!=jend;++j){
03601 if(*i == *j) {
03602 e0K.erase(i);
03603 e1K.erase(j);
03604 break;
03605 }
03606 }
03607 }
03608 Expr newLhs = d_theoryBitvector->newBVPlusExpr(bvLength, e0K);
03609 k.push_back(newLhs);
03610 Expr newRhs = d_theoryBitvector->newBVPlusExpr(bvLength, e1K);
03611
03612 Expr uminus = d_theoryBitvector->newBVUminusExpr(newRhs);
03613
03614 k.push_back(uminus);
03615
03616 Expr lhsMinusRhs = d_theoryBitvector->newBVPlusExpr(bvLength,k);
03617
03618 output = Expr(EQ, lhsMinusRhs, zeroStr);
03619 }
03620
03621 Assumptions a;
03622 Proof pf;
03623 if(withProof())
03624 pf = newPf("lhs_minus_rhs_rule", e);
03625 return newRWTheorem(e, output, a, pf);
03626 }
03627
03628
03629 Theorem
03630 BitvectorTheoremProducer::bvuminusToBVPlus(const Expr& e) {
03631 if(CHECK_PROOFS) {
03632 CHECK_SOUND(BVUMINUS == e.getOpKind(),
03633 "BitvectorTheoremProducer::bvuminusBitBlastRule: "
03634 "input must be bvuminus: e = " + e.toString());
03635 }
03636 int bvLength = d_theoryBitvector->BVSize(e);
03637 std::vector<Expr> k;
03638 Expr negE0 = d_theoryBitvector->newBVNegExpr(e[0]);
03639 k.push_back(negE0);
03640 Expr plusOne = d_theoryBitvector->newBVConstExpr(1, bvLength);
03641 k.push_back(plusOne);
03642
03643 Expr output = d_theoryBitvector->newBVPlusExpr(bvLength, k);
03644 Assumptions a;
03645 Proof pf;
03646 if(withProof())
03647 pf = newPf("bvuminus_bitblast_rule", e);
03648 return newRWTheorem(e, output, a, pf);
03649 }
03650
03651
03652 Theorem
03653 BitvectorTheoremProducer::bvuminusBVConst(const Expr& e) {
03654 if(CHECK_PROOFS) {
03655 CHECK_SOUND(BVUMINUS == e.getOpKind() &&
03656 BVCONST == e[0].getKind(),
03657 "BitvectorTheoremProducer::bvuminusBVConst: "
03658 "e should be bvuminus, e[0] should be bvconst: e = " +
03659 e.toString());
03660 }
03661 Expr output;
03662 int e0Length = d_theoryBitvector->BVSize(e[0]);
03663
03664 if(d_theoryBitvector->computeBVConst(e[0]) == 0)
03665 output = e[0];
03666 else {
03667
03668 Rational x = d_theoryBitvector->computeNegBVConst(e[0]);
03669 output = d_theoryBitvector->newBVConstExpr(x, e0Length);
03670 }
03671
03672 Assumptions a;
03673 Proof pf;
03674 if(withProof())
03675 pf = newPf("bvuminus_bvconst_rule", e);
03676 return newRWTheorem(e, output, a, pf);
03677 }
03678
03679
03680 Theorem
03681 BitvectorTheoremProducer::bvuminusBVMult(const Expr& e) {
03682 if(CHECK_PROOFS) {
03683 CHECK_SOUND(BVUMINUS == e.getOpKind(),
03684 "BitvectorTheoremProducer::bvuminusBVMult: "
03685 "e should be bvuminus: e =" + e.toString());
03686 CHECK_SOUND(BVMULT == e[0].getOpKind(),
03687 "Bitvectortheoremproducer::bvuminusBVMult: "
03688 "in input expression e = " + e.toString() +
03689 "\ne[0] should be bvmult: e[0] = " + e[0].toString());
03690 CHECK_SOUND(BVCONST == e[0][0].getKind(),
03691 "Bitvectortheoremproducer::bvuminusBVMult: "
03692 "in input expression e = " + e.toString() +
03693 "\ne[0][0] should be bvconst: e[0][0] = " + e[0][0].toString());
03694 int bvLength = d_theoryBitvector->BVSize(e);
03695 int e0Length = d_theoryBitvector->BVSize(e[0]);
03696 int e00Length = d_theoryBitvector->BVSize(e[0][0]);
03697 CHECK_SOUND(bvLength == e0Length && e0Length == e00Length,
03698 "Bitvectortheoremproducer::bvuminusBVMult: "
03699 "in input expression e = " + e.toString() +
03700 "\nLengths of all subexprs must be equal: e = " + e.toString());
03701 }
03702
03703 Expr output;
03704 int e0Length = d_theoryBitvector->BVSize(e[0]);
03705
03706 Rational coeff = d_theoryBitvector->computeNegBVConst(e[0][0]);
03707 if(0 == coeff)
03708
03709 output = d_theoryBitvector->newBVZeroString(e0Length);
03710 else if (1 == coeff)
03711
03712 output = e[0][1];
03713 else {
03714
03715 Expr newcoeff = d_theoryBitvector->newBVConstExpr(coeff, e0Length);
03716 output = d_theoryBitvector->newBVMultExpr(e0Length, newcoeff, e[0][1]);
03717 }
03718
03719 Assumptions a;
03720 Proof pf;
03721 if(withProof())
03722 pf = newPf("bvuminus_bvmult_rule", e);
03723 return newRWTheorem(e, output, a, pf);
03724 }
03725
03726
03727 Theorem
03728 BitvectorTheoremProducer::bvuminusBVUminus(const Expr& e) {
03729 if(CHECK_PROOFS) {
03730 CHECK_SOUND(BVUMINUS == e.getOpKind(),
03731 "BitvectorTheoremProducer::bvuminusBVUminus: "
03732 "e should be bvuminus: e =" + e.toString());
03733 CHECK_SOUND(BVUMINUS == e[0].getOpKind(),
03734 "Bitvectortheoremproducer::bvuminusBVUminus: "
03735 "in input expression e = " + e.toString() +
03736 "\ne[0] should be bvmult: e[0] = " + e[0].toString());
03737 }
03738 Expr output;
03739
03740 output = e[0][0];
03741 Assumptions a;
03742 Proof pf;
03743 if(withProof())
03744 pf = newPf("bvuminus_bvuminus_rule", e);
03745 return newRWTheorem(e, output, a, pf);
03746 }
03747
03748
03749 Theorem
03750 BitvectorTheoremProducer::bvuminusVar(const Expr& e) {
03751 if(CHECK_PROOFS) {
03752 CHECK_SOUND(BVUMINUS == e.getOpKind(),
03753 "BitvectorTheoremProducer::bvuminusVar: "
03754 "e should be bvuminus: e =" + e.toString());
03755 }
03756 Expr output;
03757 std::vector<bool> res;
03758 int e0Length = d_theoryBitvector->BVSize(e[0]);
03759 for(int i=0; i<e0Length; ++i) {
03760 res.push_back(true);
03761 }
03762 Expr coeff = d_theoryBitvector->newBVConstExpr(res);
03763 output = d_theoryBitvector->newBVMultExpr(e0Length, coeff, e[0]);
03764
03765 Assumptions a;
03766 Proof pf;
03767 if(withProof())
03768 pf = newPf("bvuminus_var_rule", e);
03769 return newRWTheorem(e, output, a, pf);
03770 }
03771
03772
03773 Theorem
03774 BitvectorTheoremProducer::bvmultBVUminus(const Expr& e) {
03775 if(CHECK_PROOFS) {
03776 CHECK_SOUND(BVUMINUS == e.getOpKind(),
03777 "BitvectorTheoremProducer::bvmultBVUminus: "
03778 "e should be bvuminus: e =" + e.toString());
03779 CHECK_SOUND(BVMULT == e[0].getOpKind() &&
03780 BVCONST == e[0][0].getKind() &&
03781 BVUMINUS == e[0][1].getOpKind(),
03782 "Bitvectortheoremproducer::bvmultBVUminus: "
03783 "in input expression e = " + e.toString() +
03784 "\ne[0] has to be bvmult"
03785 "e[0][1] must be bvuminus: e[0] = " + e[0].toString());
03786 int bvLength = d_theoryBitvector->BVSize(e);
03787 int e00Length = d_theoryBitvector->BVSize(e[0][0]);
03788 int e01Length = d_theoryBitvector->BVSize(e[0][1]);
03789 CHECK_SOUND(bvLength == e00Length && e00Length == e01Length,
03790 "Bitvectortheoremproducer::bvmultBVUminus: "
03791 "in input expression e = " + e.toString() +
03792 "\nLengths of all subexprs must be equal.");
03793 }
03794 Expr output;
03795 int bvLength = d_theoryBitvector->BVSize(e);
03796 const Expr& coeff = e[0][0];
03797 Rational negatedcoeff = d_theoryBitvector->computeNegBVConst(coeff);
03798 const Expr& e010 = e[0][1][0];
03799
03800 if(0 == negatedcoeff)
03801
03802 output = d_theoryBitvector->newBVZeroString(bvLength);
03803 else if (1 == negatedcoeff)
03804
03805 output = e010;
03806 else {
03807
03808 Expr newcoeff = d_theoryBitvector->newBVConstExpr(negatedcoeff, bvLength);
03809 output = d_theoryBitvector->newBVMultExpr(bvLength, newcoeff, e010);
03810 }
03811
03812 Assumptions a;
03813 Proof pf;
03814 if(withProof())
03815 pf = newPf("bvmult_bvuminus_rule", e);
03816 return newRWTheorem(e, output, a, pf);
03817 }
03818
03819
03820 Theorem
03821 BitvectorTheoremProducer::bvuminusBVPlus(const Expr& e) {
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849 Assumptions a;
03850 Proof pf;
03851 if(withProof())
03852 pf = newPf("bvminus_bvplus_rule", e);
03853 return newRWTheorem(e, e, a, pf);
03854 }
03855
03856 Theorem
03857 BitvectorTheoremProducer::extractBVMult(const Expr& e) {
03858 if(CHECK_PROOFS) {
03859 CHECK_SOUND(e.getOpKind() == EXTRACT &&
03860 e[0].getOpKind() == BVMULT &&
03861 e[0].arity() == 2,
03862 "BitvectorTheoremProducer::extractBVMult: "
03863 "input must be an EXTRACT over BVMULT:\n e = "+e.toString());
03864 }
03865 const Expr& bvmult = e[0];
03866 int bvmultLen = d_theoryBitvector->BVSize(bvmult);
03867 int extractHi = d_theoryBitvector->getExtractHi(e);
03868 int extractLow = d_theoryBitvector->getExtractLow(e);
03869
03870 if(CHECK_PROOFS) {
03871 CHECK_SOUND(bvmultLen > extractHi,
03872 "BitvectorTheoremProducer::extractBVMult: "
03873 "bvmult Length must be greater than extract Length:\n e = "
03874 +e.toString());
03875 }
03876
03877 Expr output = d_theoryBitvector->newBVMultExpr(extractHi+1, bvmult[0],
03878 bvmult[1]);
03879 if(extractLow > 0)
03880 output=d_theoryBitvector->newBVExtractExpr(output, extractHi, extractLow);
03881
03882 Assumptions a;
03883 Proof pf;
03884 if(withProof())
03885 pf = newPf("extract_bvmult_rule", e);
03886 return newRWTheorem(e, output, a, pf);
03887 }
03888
03889 Theorem
03890 BitvectorTheoremProducer::extractBVPlus(const Expr& e) {
03891 if(CHECK_PROOFS) {
03892 CHECK_SOUND(e.getOpKind() == EXTRACT && e[0].getOpKind() == BVPLUS,
03893 "BitvectorTheoremProducer::extractBVPlus: "
03894 "input must be an EXTRACT over BVPLUS:\n e = "+e.toString());
03895 }
03896 const Expr& bvplus = e[0];
03897 int bvplusLen = d_theoryBitvector->BVSize(bvplus);
03898 int extractHi = d_theoryBitvector->getExtractHi(e);
03899 int extractLow = d_theoryBitvector->getExtractLow(e);
03900
03901 if(CHECK_PROOFS) {
03902 CHECK_SOUND(bvplusLen > extractHi,
03903 "BitvectorTheoremProducer::extractBVPlus: "
03904 "bvplus Length must be greater than extract bvLength:\n e = "
03905 +e.toString());
03906 }
03907
03908
03909 if(bvplusLen == extractHi+1)
03910 return d_theoryBitvector->reflexivityRule(e);
03911
03912
03913 Expr output(d_theoryBitvector->newBVPlusExpr(extractHi+1, bvplus.getKids()));
03914 if(extractLow > 0)
03915 output=d_theoryBitvector->newBVExtractExpr(output, extractHi, extractLow);
03916
03917 Assumptions a;
03918 Proof pf;
03919 if(withProof())
03920 pf = newPf("extract_bvplus_rule", e);
03921 return newRWTheorem(e, output, a, pf);
03922 }
03923
03924
03925
03926 Theorem
03927 BitvectorTheoremProducer::typePredBit(const Expr& e) {
03928 if(CHECK_PROOFS) {
03929 CHECK_SOUND(d_theoryBitvector->getBaseType(e).getExpr().getOpKind() == BITVECTOR,
03930 "BitvectorTheoremProducer::typePredBit: e = "+e.toString());
03931 CHECK_SOUND(d_theoryBitvector->BVSize(e) == 1,
03932 "BitvectorTheoremProducer::typePredBit: e = "+e.toString());
03933 }
03934
03935 Assumptions a;
03936 Proof pf;
03937 if(withProof())
03938 pf=newPf("type_pred_bit", e);
03939 return newTheorem(e.eqExpr(bvZero()) || e.eqExpr(bvOne()), a, pf);
03940 }
03941
03942
03943
03944 Theorem
03945 BitvectorTheoremProducer::expandTypePred(const Theorem& tp) {
03946 Expr tpExpr = tp.getExpr();
03947 if(CHECK_PROOFS) {
03948 CHECK_SOUND(tpExpr.getOpKind() == BVTYPEPRED ||
03949 (tpExpr.getKind() == NOT && tpExpr[0].getOpKind() == BVTYPEPRED),
03950 "BitvectorTheoremProducer::expandTypePred: "
03951 "Expected BV_TYPE_PRED wrapper:\n tp = "
03952 +tpExpr.toString());
03953 }
03954 Expr res;
03955 if(tpExpr.getKind() == NOT)
03956 res = d_theoryBitvector->falseExpr();
03957 else {
03958 Type t(d_theoryBitvector->getTypePredType(tpExpr));
03959 const Expr& e(d_theoryBitvector->getTypePredExpr(tpExpr));
03960 int size(d_theoryBitvector->getBitvectorTypeParam(t));
03961
03962
03963 if(size >= 2) {
03964 vector<Expr> kids;
03965 for(int i=0; i<size; i++) {
03966 Expr bit(d_theoryBitvector->newBVExtractExpr(e, i, i));
03967 kids.push_back(bit.eqExpr(bvZero()) || bit.eqExpr(bvOne()));
03968 }
03969 res = andExpr(kids);
03970 } else {
03971 res = (e.eqExpr(bvZero()) || e.eqExpr(bvOne()));
03972 }
03973 }
03974 Assumptions a;
03975 Proof pf;
03976 if(withAssumptions())
03977 a = tp.getAssumptionsCopy();
03978 if(withProof())
03979 pf = newPf("expand_type_pred", tp.getExpr(), tp.getProof());
03980
03981 return newTheorem(res, a, pf);
03982 }