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

Generated on Thu Apr 13 16:57:29 2006 for CVC Lite by  doxygen 1.4.4