CVC3

bitvector_theorem_producer.cpp

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