theory_bitvector.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file theory_bitvector.cpp
00004  * 
00005  * Author: Vijay Ganesh.
00006  * 
00007  * Created: Wed May  5 16:16:59 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 
00029 
00030 #include "theory_bitvector.h"
00031 #include "bitvector_proof_rules.h"
00032 #include "bitvector_exception.h"
00033 #include "typecheck_exception.h"
00034 #include "parser_exception.h"
00035 #include "smtlib_exception.h"
00036 #include "bitvector_expr_value.h"
00037 #include "command_line_flags.h"
00038 
00039 
00040 #define HASH_VALUE_ZERO 380
00041 #define HASH_VALUE_ONE  450
00042 
00043 
00044 using namespace std;
00045 using namespace CVCL;
00046 
00047 
00048 ///////////////////////////////////////////////////////////////////////////////
00049 // TheoryBitvector Private Methods                                           //
00050 ///////////////////////////////////////////////////////////////////////////////
00051 
00052 int
00053 TheoryBitvector::BVSize(const Expr& e) {
00054   Type tp(getBaseType(e));
00055   DebugAssert(tp.getExpr().getOpKind() == BITVECTOR,
00056               "BVSize: e = "+e.toString());
00057   return getBitvectorTypeParam(tp);
00058 }
00059 
00060 
00061 //! accepts a bitvector equation t1 = t2. 
00062 /*! \return a rewrite theorem which is a conjunction of equivalences
00063  * over the bits of t1,t2 respectively.
00064  */
00065 Theorem TheoryBitvector::bitBlastEqn(const Expr& e)
00066 {
00067   TRACE("bitvector", "bitBlastEqn(", e.toString(), ") {"); 
00068   IF_DEBUG(debugger.counter("bit-blasted eq")++);
00069   //stat counter
00070   d_bvBitBlastEq++;
00071 
00072   DebugAssert(e.isEq(),
00073               "TheoryBitvector::bitBlastEqn:"
00074               "expecting an equation" + e.toString());
00075   const Expr& leftBV = e[0];
00076   const Expr& rightBV = e[1];
00077 
00078   Theorem result = reflexivityRule(e);
00079   IF_DEBUG(const Type& leftType = getBaseType(leftBV));
00080   IF_DEBUG(const Type& rightType = getBaseType(rightBV));
00081   DebugAssert(BITVECTOR == leftType.getExpr().getOpKind() &&
00082               BITVECTOR == rightType.getExpr().getOpKind(),
00083               "TheoryBitvector::bitBlastEqn:"
00084               "lhs & rhs must be bitvectors");
00085   DebugAssert(BVSize(leftBV) == BVSize(rightBV),
00086               "TheoryBitvector::bitBlastEqn:\n e = "
00087               +e.toString());
00088   Theorem bitBlastLeftThm;
00089   Theorem bitBlastRightThm;
00090   std::vector<Theorem> substThms;
00091   std::vector<Theorem> leftBVrightBVThms;
00092   int bvLength = BVSize(leftBV);
00093   int bitPosition = 0;
00094   Theorem thm0;
00095 
00096   int leftFlag = 0;
00097   int rightFlag = 0;
00098   //if(BVPLUS == leftBV.getOpKind())  leftFlag = 1;
00099   //if(BVPLUS == rightBV.getOpKind()) rightFlag = 2;
00100   if(leftFlag == 1) d_bvPlusCarryCacheLeftBV.clear();
00101   if(rightFlag == 2) d_bvPlusCarryCacheRightBV.clear();
00102   for(; bitPosition < bvLength; bitPosition = bitPosition+1) {
00103     //bitBlastLeftThm is the theorem 'leftBV[bitPosition] <==> phi'
00104     bitBlastLeftThm = bitBlastTerm(leftBV, bitPosition,leftFlag);
00105     //bitBlastRightThm is the theorem 'rightBV[bitPosition] <==> theta'
00106     bitBlastRightThm = bitBlastTerm(rightBV, bitPosition,rightFlag);
00107     //collect the two theorems created above in the vector
00108     //leftBVrightBVthms.
00109     leftBVrightBVThms.push_back(bitBlastLeftThm); 
00110     leftBVrightBVThms.push_back(bitBlastRightThm);
00111     //construct (leftBV[bitPosition] <==> rightBV[bitPosition]) 
00112     //<====> phi <==> theta
00113     //and store in the vector substThms.
00114     Theorem thm = substitutivityRule(IFF, leftBVrightBVThms);
00115     thm = transitivityRule(thm, rewriteBoolean(thm.getRHS()));    
00116     leftBVrightBVThms.clear();
00117     substThms.push_back(thm); 
00118     //if phi <==> theta is false, then stop bitblasting. immediately
00119     //exit and return false.
00120     if(thm.getRHS().isFalse())
00121       return transitivityRule(result,
00122                               d_rules->bitvectorFalseRule(thm));
00123   }
00124   // AND_0^bvLength(leftBV[bitPosition] <==> rightBV[bitPosition]) <====>
00125   // AND_0^bvLength(phi <==> theta)
00126   Theorem thm = substitutivityRule(AND, substThms);
00127   // AND_0^bvLength(leftBV[bitPosition] <==> rightBV[bitPosition]) <====>
00128   // rewriteBoolean(AND_0^bvLength(phi <==> theta))
00129   thm = transitivityRule(thm, rewriteBoolean(thm.getRHS()));
00130   //call trusted rule for bitblasting equations.
00131   result = d_rules->bitBlastEqnRule(e, thm.getLHS());
00132   result = transitivityRule(result, thm);
00133   TRACE("bitvector", "bitBlastEqn => ", result.toString(), " }"); 
00134   return result;
00135 }
00136 
00137 //! accepts a bitvector equation t1 != t2. 
00138 /*! \return a rewrite theorem which is a conjunction of
00139  * (dis)-equivalences over the bits of t1,t2 respectively.
00140  * 
00141  * A separate rule for disequations for efficiency sake. Obvious
00142  * implementation using rule for equations and rule for NOT, is not
00143  * efficient.
00144  */
00145 Theorem TheoryBitvector::bitBlastDisEqn(const Theorem& notE)
00146 {
00147   TRACE("bitvector", "bitBlastDisEqn(", notE, ") {"); 
00148   IF_DEBUG(debugger.counter("bit-blasted diseq")++);
00149   //stat counter
00150   d_bvBitBlastDiseq++;
00151 
00152   DebugAssert(notE.getExpr().isNot() && (notE.getExpr())[0].isEq(),
00153               "TheoryBitvector::bitBlastDisEqn:"
00154               "expecting an equation" + notE.getExpr().toString());
00155   //e is the equation
00156   const Expr& e = (notE.getExpr())[0];
00157   const Expr& leftBV = e[0];
00158   const Expr& rightBV = e[1];
00159   IF_DEBUG(Type leftType = leftBV.getType());
00160   IF_DEBUG(debugger.counter("bit-blasted diseq bits")+=
00161            BVSize(leftBV));
00162   IF_DEBUG(Type rightType = rightBV.getType());
00163   DebugAssert(BITVECTOR == leftType.getExpr().getOpKind() &&
00164               BITVECTOR == rightType.getExpr().getOpKind(),
00165               "TheoryBitvector::bitBlastDisEqn:"
00166               "lhs & rhs must be bitvectors");
00167   DebugAssert(BVSize(leftBV) == BVSize(rightBV),
00168               "TheoryBitvector::bitBlastDisEqn: e = "
00169               +e.toString());
00170   Theorem bitBlastLeftThm;
00171   Theorem bitBlastRightThm;
00172   std::vector<Theorem> substThms;
00173   std::vector<Theorem> leftBVrightBVThms;
00174   int bvLength = BVSize(leftBV);
00175   int leftFlag = 0;
00176   int rightFlag = 0;
00177   //if(BVPLUS == leftBV.getOpKind())  leftFlag = 1;
00178   //if(BVPLUS == rightBV.getOpKind()) rightFlag = 2;
00179   if(leftFlag == 1) d_bvPlusCarryCacheLeftBV.clear();
00180   if(rightFlag == 2) d_bvPlusCarryCacheRightBV.clear();
00181   int bitPosition = 0;
00182   for(; bitPosition < bvLength; bitPosition = bitPosition+1) {
00183     //bitBlastLeftThm is the theorem '~leftBV[bitPosition] <==> ~phi'
00184     bitBlastLeftThm =
00185       getCommonRules()->iffContrapositive(bitBlastTerm(leftBV, bitPosition,
00186                                                        leftFlag));
00187     //bitBlastRightThm is the theorem 'rightBV[bitPosition] <==> theta'
00188     bitBlastRightThm = bitBlastTerm(rightBV, bitPosition,rightFlag);
00189     //collect the two theorems created above in the vector leftBVrightBVthms.
00190     leftBVrightBVThms.push_back(bitBlastLeftThm); 
00191     leftBVrightBVThms.push_back(bitBlastRightThm);
00192     //construct (~leftBV[bitPosition] <==> rightBV[bitPosition]) 
00193     //<====> ~phi <==> theta
00194     //and store in the vector substThms.
00195     //recall that (p <=/=> q) is same as (~p <==> q)
00196     Theorem thm = substitutivityRule(IFF, leftBVrightBVThms);
00197     thm = transitivityRule(thm, rewriteBoolean(thm.getRHS()));
00198     leftBVrightBVThms.clear();
00199     substThms.push_back(thm); 
00200     
00201     //if phi <==> theta is the True theorem, then stop bitblasting. immediately
00202     //exit and return t1!=t2 <=> true.
00203     if(thm.getRHS().isTrue())
00204       return d_rules->bitvectorTrueRule(thm);
00205   }
00206 
00207   // OR_0^bvLength(~leftBV[bitPosition] <==> rightBV[bitPosition]) <====>
00208   // OR_0^bvLength(~phi <==> theta)
00209   Theorem thm1 = substitutivityRule(OR, substThms);
00210   // Call trusted rule for bitblasting disequations.
00211   Theorem result = d_rules->bitBlastDisEqnRule(notE, thm1.getLHS());
00212   Theorem thm2 = transitivityRule(thm1, rewriteBoolean(thm1.getRHS()));
00213   result = iffMP(result, thm2);
00214   TRACE("bitvector", "bitBlastDisEqn => ", result.toString(), " }"); 
00215   return result;
00216 }
00217 
00218 /*! \param e1 pred e2, where pred is < or <=.  
00219  *
00220  *  if e1,e2 are constants, determine bv2int(e1) pred bv2int(e2). 
00221  *
00222  *  most significant bit of ei is denoted by msb(ei) 
00223  * 
00224  *  \return (msb(e1) pred msb(e2)) \vee 
00225  *          (msb(e1)=msb(e2) \wedge e1[n-2:0] pred e2[n-2:0])
00226  */
00227 Theorem TheoryBitvector::bitBlastIneqn(const Expr& e) {
00228   TRACE("bitvector", "bitBlastIneqn(", e.toString(), ") {"); 
00229 
00230   if(e.isBoolConst()) {
00231     Theorem res(reflexivityRule(e));
00232     TRACE("bitvector", "bitBlastIneqn => ", res.getExpr(), " }");
00233     return res;
00234   }
00235 
00236   DebugAssert(BVLT == e.getOpKind() ||
00237               BVLE == e.getOpKind(),
00238               "TheoryBitvector::bitBlastIneqn: "
00239               "input e must be BVLT/BVLE: e = " + e.toString());
00240   DebugAssert(e.arity() == 2,
00241               "TheoryBitvector::bitBlastIneqn: "
00242               "arity of e must be 2: e = " + e.toString());
00243   int e0len = BVSize(e[0]);
00244   int e1len = BVSize(e[1]);
00245   int bvLength = e0len >= e1len ? e0len : e1len;
00246   
00247   Expr newE=e;
00248   Expr lhs = e[0];
00249   Expr rhs = e[1];
00250   Theorem thm1 = reflexivityRule(e);
00251   if(e0len != e1len) {
00252     Theorem thm0 = d_rules->padBVLTRule(e, bvLength);
00253     thm1 = rewriteBV(thm0, 3, false);
00254     newE = thm1.getRHS();
00255     lhs = newE[0];
00256     rhs = newE[1];
00257   }
00258 
00259   int kind = e.getOpKind();
00260   Theorem res;
00261   if(lhs == rhs)
00262     res = 
00263       transitivityRule(thm1,d_rules->lhsEqRhsIneqn(newE, kind));
00264   else {
00265     if(BVCONST == lhs.getKind() && BVCONST == rhs.getKind())
00266       res = transitivityRule(thm1,d_rules->bvConstIneqn(newE, kind));
00267     else {
00268       Theorem lhs_i = bitBlastTerm(lhs,bvLength-1, 0);
00269       Theorem rhs_i = bitBlastTerm(rhs,bvLength-1, 0);
00270       Theorem thm2 = d_rules->generalIneqn(newE, lhs_i, rhs_i, kind);
00271       res = transitivityRule(thm1, thm2);      
00272       //check if output is TRUE or FALSE theorem, and then simply return
00273       Theorem output = rewriteBoolean(res.getRHS());
00274       if(output.getRHS().isBoolConst()) {
00275         res = transitivityRule(res, output);
00276         TRACE("bitvector", "bitBlastIneqn => ", res.getExpr(), " }"); 
00277         return res;
00278       }
00279 
00280       if(bvLength-1 > 0) {
00281         // Copy by value, since 'res' will be changing
00282         Expr resRHS = res.getRHS();
00283         //resRHS can be of the form (\alpha or (\beta and \gamma)) or
00284         //resRHS can be of the form (\beta and \gamma) or
00285         //resRHS can be of the form (\alpha or \gamma) or
00286         //resRHS can be of the form (\gamma)
00287         // Our mission is to bitblast \gamma and insert it back to the formula
00288         vector<unsigned> changed;
00289         vector<Theorem> thms;
00290         Expr gamma;
00291         Theorem gammaThm;
00292         switch(resRHS.getOpKind()) {
00293         case OR:
00294           if(resRHS[1].isAnd()) { // (\alpha or (\beta and \gamma))
00295             changed.push_back(1);
00296             gamma = resRHS[1][1];
00297             // \gamma <=> \gamma'
00298             gammaThm = rewriteBV(gamma,2,false);
00299             //\gamma' <=> \gamma"
00300             Theorem thm3 = bitBlastIneqn(gammaThm.getRHS());
00301             //Theorem thm3 = bitBlastIneqn(gamma);
00302             //\gamma <=> \gamma' <=> \gamma"
00303             thm3 = transitivityRule(gammaThm, thm3);
00304             thms.push_back(thm3);
00305             // (\beta and \gamma) <=> (\beta and \gamma")
00306             thm3 = substitutivityRule(resRHS[1],changed,thms);
00307             // Now substitute this into the OR.
00308             // 'changed' is the same, only update thms[0]
00309             thms[0] = thm3;
00310             // (a or (b and g)) <=> (a or (b and g"))
00311             thm3 = substitutivityRule(resRHS,changed,thms);
00312             res = transitivityRule(res, thm3);
00313             break;
00314           }
00315           // (\alpha or \gamma) - fall through (same as the AND case)
00316         case AND: { // (\beta and \gamma)
00317           changed.push_back(1);
00318           gamma = resRHS[1];
00319           // \gamma <=> \gamma'
00320           gammaThm = rewriteBV(gamma,2,false);
00321           //\gamma' <=> \gamma"
00322           Theorem thm3 = bitBlastIneqn(gammaThm.getRHS());
00323           //Theorem thm3 = bitBlastIneqn(gamma);
00324           //\gamma <=> \gamma' <=> \gamma"
00325           thm3 = transitivityRule(gammaThm, thm3);
00326           thms.push_back(thm3);
00327           // (\beta and \gamma) <=> (\beta and \gamma")
00328           thm3 = substitutivityRule(resRHS,changed,thms);
00329           res = transitivityRule(res, thm3);
00330           break;
00331         }
00332         default: // (\gamma)
00333           IF_DEBUG(gamma = resRHS);
00334           // \gamma <=> \gamma'
00335           gammaThm = rewriteBV(resRHS,2,false);
00336           //\gamma' <=> \gamma"
00337           Theorem thm3 = bitBlastIneqn(gammaThm.getRHS());
00338           //Theorem thm3 = bitBlastIneqn(gamma);
00339           //\gamma <=> \gamma' <=> \gamma"
00340           thm3 = transitivityRule(gammaThm, thm3);
00341           res = transitivityRule(res, thm3);
00342           break;
00343         }
00344         
00345         DebugAssert(kind == gamma.getOpKind(),
00346                     "TheoryBitvector::bitBlastIneqn: "
00347                     "gamma must be a BVLT/BVLE. gamma = " +
00348                     gamma.toString());
00349       }
00350     }
00351   }
00352   TRACE("bitvector", "bitBlastIneqn => ", res.toString(), " }"); 
00353   return res;
00354 }
00355 
00356 
00357 /*! The invariant maintained by this function is: accepts a bitvector
00358  * term, t,and a bitPosition, i. returns a formula over the set of
00359  * propositional variables defined using BOOLEXTRACT of bitvector
00360  * variables in t at the position i.
00361  *
00362  * \return Theorem(BOOLEXTRACT(t, bitPosition) <=> phi), where phi is
00363  * a Boolean formula over the individual bits of bit-vector variables.
00364  */
00365 Theorem TheoryBitvector::bitBlastTerm(const Expr& t, 
00366                                       int bitPosition, int preComputed)
00367 {
00368   TRACE("bitvector", 
00369         "bitBlastTerm(", t, ", " + int2string(bitPosition) + ") {"); 
00370   Theorem result;
00371   
00372   //check in cache for the theorem t[bitPosition] <=> \theta_i.
00373   //if yes return the theorem, else produce it.
00374   Expr t_i = newBoolExtractExpr(t, bitPosition);
00375   CDMap<Expr,Theorem>::iterator it = d_bitvecCache.find(t_i);
00376   if(it != d_bitvecCache.end()) {
00377     result = (*it).second;
00378     TRACE("bitvector", "bitBlastTerm[cached] => ", result, " }"); 
00379     DebugAssert(t_i == result.getLHS(),
00380                 "TheoryBitvector::bitBlastTerm:"
00381                 "created wrong theorem" + result.toString() + t_i.toString());
00382     return result;
00383   } else {
00384     //else construct the theorem t[bitPosition] <=> \theta_i. and put it into
00385     //d_bitvecCache
00386     IF_DEBUG(Type type = t.getType());
00387     DebugAssert(BITVECTOR == type.getExpr().getOpKind(),
00388                 "TheoryBitvector::bitBlastTerm: "
00389                 "The type of input to bitBlastTerm must be BITVECTOR.\n t = "
00390                 +t.toString());
00391     DebugAssert(bitPosition >= 0,
00392                 "TheoryBitvector::bitBlastTerm: "
00393                 "illegal bitExtraction attempted.\n bitPosition = "+
00394                 int2string(bitPosition));
00395     // First, rewrite t[i] into t[i:i][0], normalize t[i:i], and
00396     // bitblast the result.
00397     if(*d_rwBitBlastFlag)
00398       result = rewriteBV(t_i, false);
00399     else
00400       result = reflexivityRule(t_i);
00401 
00402     Expr t2_i = result.getRHS();
00403     if(t2_i.isBoolConst()) {
00404       // Record the original expression into the cache
00405       d_bitvecCache[t_i] = result;
00406       TRACE("bitvector", "bitBlastTerm[rewrite to const] => ", result, " }"); 
00407       return result;
00408     }
00409       
00410     DebugAssert(t2_i.getOpKind()==BOOLEXTRACT,
00411                 "bitBlastTerm: t2_i = "+t2_i.toString());
00412     // Check the cache again
00413     it = d_bitvecCache.find(t2_i);
00414     if(it != d_bitvecCache.end()) {
00415       result = transitivityRule(result, (*it).second);
00416       // Record the original expression into the cache
00417       d_bitvecCache[t_i] = result;
00418       TRACE("bitvector", "bitBlastTerm[cached2] => ", result, " }"); 
00419       return result;
00420     }
00421     // Bit-blast the rewritten version of the term.  We'll merge the
00422     // two at the end.
00423     Theorem resTmp(reflexivityRule(t2_i));
00424     const Expr& t2 = t2_i[0];
00425 
00426     int bitPos2 = getBoolExtractIndex(t2_i);
00427     // Required depth of simplification for the resulting formula (the
00428     // depth of the newly generated Boolean formula that needs to be
00429     // simplified).  For the moment, we distinguish between 1 and many
00430     // (>1).  Default is 1 (only top node needs simplification).
00431 //     int simplifyDepth(1);
00432     switch(t2.getOpKind()) {
00433     case BVCONST:
00434       //we have a bitvector constant
00435       resTmp = transitivityRule(resTmp, 
00436                                 d_rules->bitExtractConstant(t2, bitPos2));
00437       break;
00438     case BVMULT: {
00439       Theorem thm;
00440       if(BVCONST == t2[0].getKind())
00441         thm = d_rules->bitExtractConstBVMult(t2, bitPos2);
00442       else
00443         thm = d_rules->bitExtractBVMult(t2, bitPos2);
00444       const Expr& boolExtractTerm = thm.getRHS();
00445       const Expr& term = boolExtractTerm[0];
00446       const Theorem& bitblastThm = bitBlastTerm(term, bitPos2,preComputed);
00447       resTmp = transitivityRule(thm, bitblastThm); 
00448 //       simplifyDepth = 2;
00449     }
00450       break;
00451     case BVOR:
00452     case BVAND: {
00453       int resKind = (t2.getOpKind()==BVOR)? OR : AND;
00454       const Theorem& thm = (resKind==AND)?
00455         d_rules->bitExtractAnd(t2, bitPos2)
00456         : d_rules->bitExtractOr(t2, bitPos2);
00457       const Expr& phi = thm.getRHS();
00458       DebugAssert(phi.getOpKind() == resKind && phi.arity() == t2.arity(),
00459                   "TheoryBitvector::bitBlastTerm: recursion:"
00460                   "\n phi = "+phi.toString()
00461                   +"\n t2 = "+t2.toString());
00462       vector<Theorem> substThms;
00463       for(Expr::iterator i=phi.begin(), iend=phi.end(); i!=iend; ++i) {
00464         if(i->getOpKind() == BOOLEXTRACT)
00465           substThms.push_back(bitBlastTerm((*i)[0], getBoolExtractIndex(*i), preComputed));
00466         else
00467           substThms.push_back(reflexivityRule(*i));
00468       }
00469       resTmp = transitivityRule(resTmp, thm);
00470       resTmp = transitivityRule(resTmp, substitutivityRule(resKind,
00471                                                            substThms));
00472       break;
00473     }
00474     case BVNEG: {
00475       const Theorem& thm = d_rules->bitExtractNot(t2, bitPos2);
00476       const Expr& extractTerm = thm.getRHS();
00477       DebugAssert(NOT == extractTerm.getKind(),
00478                   "TheoryBitvector::bitBlastTerm:" 
00479                   "recursion: term must be NOT");
00480       const Expr& term0 = extractTerm[0];
00481       DebugAssert(BOOLEXTRACT == term0.getOpKind(), 
00482                   "TheoryBitvector::bitBlastTerm: recursion:("
00483                   "terms must be BOOL-EXTRACT");
00484       int bitPos0 = getBoolExtractIndex(term0);
00485       std::vector<Theorem> res;
00486       res.push_back(bitBlastTerm(term0[0], bitPos0, preComputed));
00487       resTmp = transitivityRule(resTmp, thm);
00488       resTmp = transitivityRule(resTmp,
00489                                 substitutivityRule(NOT, res));
00490       break; 
00491     }
00492     case BVSUB:
00493       DebugAssert(false, "control should not reach here. " 
00494                   "BVSUB/BVUMINUS have already been translated into BVPLUS");
00495       break;
00496     case BVUMINUS: {
00497       vector<Theorem> thms;
00498       vector<unsigned> changed;
00499       // -t = ~t+1
00500       Theorem thm = d_rules->bvuminusToBVPlus(t2);
00501       thms.push_back(thm);
00502       changed.push_back(0);
00503       // (-t)[i] = (~t+1)[i]
00504       resTmp = substitutivityRule(t2_i, changed, thms);
00505       // Bitblast (~t+1)[i]
00506       resTmp = transitivityRule(resTmp, bitBlastTerm(thm.getRHS(), bitPos2, preComputed));
00507 //       simplifyDepth = 2;
00508       break;
00509     }
00510     case BVPLUS: {
00511       Expr bvPlusTerm = t2;
00512       Theorem thm1;
00513       if(2 < t2.arity()) {
00514         //this rule makes t2 a binary add. binary add is more suitable
00515         //for bitblasting.
00516         const Theorem& thm = d_rules->bvPlusAssociativityRule(bvPlusTerm);
00517         std::vector<Theorem> thms;
00518         thms.push_back(thm);
00519         thm1 = substitutivityRule
00520           (newBoolExtractExpr(bvPlusTerm, bitPos2).getOp(), thms);
00521         bvPlusTerm = thm.getRHS();
00522         TRACE("bitvector", 
00523               "TheoryBitvector::bitBlastTerm:thm1(", thm1.getExpr(), ")");
00524       } else
00525         thm1 = reflexivityRule(newBoolExtractExpr(bvPlusTerm, bitPos2));
00526       //bitblast each bit of t[0] and t[1] from 0-bit to bitPos2 
00527       //and store in two separate vectors.
00528       const Expr& bvplust1 = bvPlusTerm[0];
00529       const Expr& bvplust2 = bvPlusTerm[1];
00530       int t1Length = BVSize(bvplust1);
00531       int t2Length = BVSize(bvplust2);
00532       if(0 == preComputed) {
00533         std::vector<Theorem> t1BitExtractThms;
00534         std::vector<Theorem> t2BitExtractThms;
00535         for(int i = 0; i <= bitPos2; i=i+1) {
00536           if(i < t1Length)
00537             t1BitExtractThms.push_back(bitBlastTerm(bvplust1, i, 0));
00538           else
00539             t1BitExtractThms.push_back(d_rules->zeroPaddingRule(bvplust1,i));
00540           if(i < t2Length)
00541             t2BitExtractThms.push_back(bitBlastTerm(bvplust2, i, 0));
00542           else
00543             t2BitExtractThms.push_back(d_rules->zeroPaddingRule(bvplust2,i));
00544         }
00545         Theorem thm2 = 
00546           d_rules->bitExtractBVPlus(t1BitExtractThms, 
00547                                     t2BitExtractThms, bvPlusTerm, bitPos2);
00548         resTmp = transitivityRule(resTmp, thm1);
00549         resTmp = transitivityRule(resTmp, thm2);
00550       } else {      
00551         Theorem t1_i;
00552         Theorem t2_i;
00553         if(bitPos2 < t1Length)
00554           t1_i = bitBlastTerm(bvplust1,bitPos2,preComputed);      
00555         else
00556           t1_i = d_rules->zeroPaddingRule(bvplust1,bitPos2);
00557 
00558         if(bitPos2 < t2Length)
00559           t2_i = bitBlastTerm(bvplust2,bitPos2,preComputed);
00560         else
00561           t2_i = d_rules->zeroPaddingRule(bvplust2,bitPos2);
00562 
00563         Theorem thm2 = 
00564           d_rules->bitExtractBVPlusPreComputed(t1_i,t2_i,
00565                                                bvPlusTerm,
00566                                                bitPos2, 
00567                                                preComputed);
00568         resTmp = transitivityRule(resTmp, thm1);
00569         resTmp = transitivityRule(resTmp, thm2);
00570       }
00571       break;
00572     }
00573     case CONCAT: {
00574       //we have a bitvector concatenation term
00575       Theorem thm = d_rules->bitExtractConcatenation(t2, bitPos2);
00576       const Expr& boolExtractTerm = thm.getRHS();
00577       DebugAssert(BOOLEXTRACT == boolExtractTerm.getOpKind(),
00578                   "TheoryBitvector::bitBlastTerm: recursion: term must be"
00579                   "bool_extract");
00580       const Expr& term = boolExtractTerm[0];
00581       int bitPos = getBoolExtractIndex(boolExtractTerm);
00582       TRACE("bitvector", 
00583             "term for bitblastTerm recursion:(", term.toString(), ")");
00584       resTmp = transitivityRule(thm, bitBlastTerm(term, bitPos, preComputed));
00585     }
00586       break;
00587     case EXTRACT:{
00588       // EXTRACT collapses under BOOLEXTRACT, no more of this case      
00589       //we have a bitvector extraction term
00590       Theorem thm = d_rules->bitExtractExtraction(t2, bitPos2);
00591       const Expr& boolExtractTerm = thm.getRHS();
00592       DebugAssert(BOOLEXTRACT == boolExtractTerm.getOpKind(),
00593                   "TheoryBitvector::bitBlastTerm: recursion: term must be"
00594                   "bool_extract");
00595       const Expr& term = boolExtractTerm[0];
00596       int bitPos = getBoolExtractIndex(boolExtractTerm);
00597       TRACE("bitvector", "term for bitblastTerm recursion:(", term, ")");
00598       resTmp = transitivityRule(thm, bitBlastTerm(term, bitPos,preComputed));
00599     }
00600       break;
00601     case LEFTSHIFT: {
00602       resTmp = d_rules->bitExtractFixedLeftShift(t2, bitPos2);
00603       const Expr& extractTerm = resTmp.getRHS();
00604       if(BOOLEXTRACT == extractTerm.getOpKind())
00605         resTmp = 
00606           transitivityRule(resTmp, 
00607                            bitBlastTerm(extractTerm[0],
00608                                         getBoolExtractIndex(extractTerm), preComputed));
00609     }
00610       break;
00611     case RIGHTSHIFT: {
00612       resTmp = d_rules->bitExtractFixedRightShift(t2, bitPos2);
00613       const Expr& extractTerm = resTmp.getRHS();
00614       if(CVCL::BOOLEXTRACT == extractTerm.getOpKind())
00615         resTmp = 
00616           transitivityRule(resTmp, 
00617                            bitBlastTerm(extractTerm[0],
00618                                         getBoolExtractIndex(extractTerm), preComputed));
00619     }
00620       break;
00621     case SX: {
00622       resTmp = d_rules->bitExtractSXRule(t2, bitPos2);
00623       Expr extractTerm = resTmp.getRHS();
00624       resTmp = 
00625         transitivityRule(resTmp, 
00626                          bitBlastTerm(extractTerm[0],
00627                                       getBoolExtractIndex(extractTerm), preComputed));      
00628       break;
00629     }
00630     default:
00631       //we have bitvector variable.
00632       //check if the expr is indeed a BITVECTOR.   
00633       IF_DEBUG(Type type = t2.getType());
00634       DebugAssert(BITVECTOR == (type.getExpr()).getOpKind(),
00635                   "BitvectorTheoremProducer::bitBlastTerm: "
00636                   "the type must be BITVECTOR");
00637       //check if 0<= i < length of BITVECTOR
00638       IF_DEBUG(int bvLength=BVSize(t2));
00639       DebugAssert(0 <= bitPos2 && bitPos2 < bvLength,
00640                   "BitvectorTheoremProducer::bitBlastTerm: "
00641                   "the bitextract position must be legal");
00642       TRACE("bitvector",
00643             "bitBlastTerm: blasting variables(", t2, ")");
00644       const Expr bitExtract = newBoolExtractExpr(t2, bitPos2);
00645       resTmp = transitivityRule(resTmp, reflexivityRule(bitExtract));
00646       TRACE("bitvector",
00647             "bitBlastTerm: blasting variables(", t, ")");
00648       break;
00649     }
00650     DebugAssert(!resTmp.isNull(), "TheoryBitvector::bitBlastTerm()");
00651     Theorem simpThm;
00652 //     if(simplifyDepth > 1)
00653 //       simpThm = simplifyThm(resTmp.getRHS());
00654 //     else
00655       simpThm = rewriteBoolean(resTmp.getRHS());
00656 
00657     resTmp = transitivityRule(resTmp, simpThm);
00658     result = transitivityRule(result, resTmp);
00659     d_bitvecCache[t_i] = result;
00660     d_bitvecCache[t2_i] = resTmp;
00661     DebugAssert(t_i == result.getLHS(),
00662                 "TheoryBitvector::bitBlastTerm: "
00663                 "created wrong theorem.\n result = "
00664                 +result.toString()
00665                 +"\n t_i = "+t_i.toString());
00666     TRACE("bitvector", "bitBlastTerm => ", result, " }"); 
00667     return result;
00668   }
00669 }
00670   
00671 
00672 //! Check that all the kids of e are BVCONST
00673 static bool constantKids(const Expr& e) {
00674   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
00675     if(!i->isRational() && i->getKind() != BVCONST) return false;
00676   return true;
00677 }
00678 
00679 
00680 //! Search for all the BVCONST kids of e, and return their indices in idxs
00681 static void constantKids(const Expr& e, vector<int>& idxs) {
00682   for(int i=0, iend=e.arity(); i<iend; ++i)
00683     if(e[i].getKind() == BVCONST) idxs.push_back(i);
00684 }
00685 
00686 Theorem
00687 TheoryBitvector::normalizeConcat(const Expr& e, bool useFind) {
00688   TRACE("bitvector rewrite", "normalizeConcat(", e, ") {");
00689   Theorem res;
00690   if(*d_concatRewriteFlag) {
00691     switch(e.getOpKind()) {
00692     case EXTRACT: {
00693       DebugAssert(e.arity() == 1, "TheoryBitvector::normalizeConcat: e = "
00694                   +e.toString());
00695       if(getExtractLow(e) == 0 && getExtractHi(e) == BVSize(e[0])-1)
00696         res = d_rules->extractWhole(e);
00697       else {
00698         switch(e[0].getOpKind()) {
00699         case BVCONST:
00700           res = d_rules->extractConst(e);
00701           break;
00702         case EXTRACT:
00703           res = d_rules->extractExtract(e);
00704           break;
00705         case CONCAT:
00706           // Push extraction through concat, and rewrite the kids
00707           res = rewriteBV(d_rules->extractConcat(e), 2, useFind);
00708           break;
00709         case BVNEG:
00710           res = rewriteBV(d_rules->extractNeg(e), 2, useFind);
00711           break;
00712         case BVAND:
00713           res = rewriteBV(d_rules->extractAnd(e), 2, useFind);
00714           break;
00715         case BVOR:
00716           res = rewriteBV(d_rules->extractOr(e), 2, useFind);     
00717           break;
00718         case BVXOR:
00719           res = 
00720             rewriteBV(d_rules->extractBitwise(e, BVXOR,"extract_bvxor"), 
00721                       2, useFind);
00722           break;
00723         case BVMULT: {
00724           const Expr& bvmult = e[0];
00725           int hiBit = getExtractHi(e);
00726           int bvmultLen = BVSize(bvmult);
00727           // Applicable if it changes anything
00728           if(hiBit+1 < bvmultLen) {
00729             res = d_rules->extractBVMult(e);
00730             // The extraction may be stripped off
00731             if(res.getRHS().getOpKind() == EXTRACT)
00732               res = rewriteBV(res, 2, useFind);
00733             else
00734               res = rewriteBV(res, 1, useFind);
00735           } else
00736             res = reflexivityRule(e);
00737           break;
00738         }
00739         case BVPLUS: {
00740           const Expr& bvplus = e[0];
00741           int hiBit = getExtractHi(e);
00742           int bvplusLen = BVSize(bvplus);
00743           if(hiBit+1 < bvplusLen) {
00744             res = d_rules->extractBVPlus(e);
00745             // The extraction may be stripped off
00746             if(res.getRHS().getOpKind() == EXTRACT)
00747               res = rewriteBV(res, 2, useFind);
00748             else
00749               res = rewriteBV(res, 1, useFind);
00750           } else
00751             res = reflexivityRule(e);
00752           break;
00753         }
00754           
00755           /*
00756         case ITE: {
00757           //ite(c,t1,t2)[i:j] <=> ite(c,t1[i:j],t2[i:j])
00758           res = simplify(e);
00759           vector<Theorem> thms;
00760           vector<unsigned> changed;
00761           const Expr& e1 = res.getRHS()[1];
00762           const Expr& e2 = res.getRHS()[2];
00763           Theorem t = rewriteBV(e1, useFind);
00764           if(e1 != t.getRHS()) {
00765             thms.push_back(t);
00766             changed.push_back(1);
00767           }
00768           t = rewriteBV(e2, useFind);
00769           if(e2 != t.getRHS()) {
00770             thms.push_back(t);
00771             changed.push_back(2);
00772           }
00773           if(changed.size()>0) {
00774             t = substitutivityRule(res.getRHS(), changed, thms);
00775             res = transitivityRule(res, t);
00776           }
00777           break;
00778         }
00779           */
00780         default:
00781           res = reflexivityRule(e);
00782           break;
00783         }
00784       }
00785       break;
00786     }
00787     case BVNEG: {
00788       switch(e[0].getOpKind()) {
00789       case BVCONST:
00790         res = d_rules->negConst(e);
00791         break;
00792       case CONCAT:
00793         // May need to propagate negation in the kids, rewrite 2 levels
00794         res = rewriteBV(d_rules->negConcat(e), 2, useFind);
00795       break;
00796       case BVNEG:
00797         res = d_rules->negNeg(e);
00798         break;
00799       default:
00800         res = reflexivityRule(e);
00801         break;
00802       }
00803       break;
00804     }
00805     case BVAND: {
00806       // Flatten the bit-wise AND, eliminate duplicates, reorder terms
00807       res = d_rules->andFlatten(e);
00808       Expr ee = res.getRHS();
00809       // Search for constant bitvectors
00810       vector<int> idxs;
00811       constantKids(ee, idxs);
00812       if(idxs.size() >= 2) {
00813       res = transitivityRule(res, d_rules->andConst(ee, idxs));
00814       }
00815       ee = res.getRHS();
00816       if(ee.getOpKind() == BVAND) {
00817         // Search for constants again
00818         idxs.clear();
00819         constantKids(ee, idxs);
00820         DebugAssert(idxs.size() <= 1, "TheoryBitvector::normalizeConcat(ee="
00821                     +ee.toString()+")");
00822         if(idxs.size() >= 1) {
00823           int idx(idxs[0]);
00824           // Check if ee[idx] is a bitvector of 0's or 1's
00825           bool isZero(true);
00826           bool isOne(true);
00827           const Expr& c = ee[idx];
00828           for(int i=0, iend=getBVConstSize(c);
00829               (isZero || isOne) && (i<iend); ++i) {
00830             isZero = (isZero && !getBVConstValue(c, i));
00831             isOne  = (isOne && getBVConstValue(c, i));
00832           }
00833           if(isZero)
00834             res = transitivityRule(res, d_rules->andZero(ee, idx));
00835           else if(isOne)
00836             res = transitivityRule(res, d_rules->andOne(ee, idxs));
00837         }
00838       }
00839       // Lift concatenation over bit-wise AND and rewrite again
00840       ee = res.getRHS();
00841       if(ee.getOpKind() == BVAND) {
00842         int i=0, iend=ee.arity();
00843         // Search for the first CONCAT child
00844         for(; (i<iend) && ee[i].getOpKind() != CONCAT; ++i);
00845         // If found, lift CONCAT over BVAND, and rewrite 3 levels
00846         // deep.  Reason: the result of andConcat is of the form:
00847         // (@ (& ... t_k[i:j] ...) ... ), and only t_k is known to be 
00848         // completely rewritten.  Hence the 3 levels of rewrites.
00849         if(i<iend)
00850           res = transitivityRule(res, rewriteBV(d_rules->andConcat(ee, i),
00851                                                 3, useFind));
00852       }
00853       break;
00854     }
00855     case BVOR: {
00856       // Flatten the bit-wise OR, eliminate duplicates, reorder terms
00857       res = d_rules->orFlatten(e);
00858       Expr ee = res.getRHS();
00859       // Search for constant bitvectors
00860       vector<int> idxs;
00861       constantKids(ee, idxs);
00862       if(idxs.size() >= 2) {
00863         res = transitivityRule(res, d_rules->orConst(ee, idxs));
00864       }
00865       ee = res.getRHS();
00866       if(ee.getOpKind() == BVOR) {
00867         // Search for constants again
00868         idxs.clear();
00869         constantKids(ee, idxs);
00870         DebugAssert(idxs.size() <= 1, "TheoryBitvector::normalizeConcat(ee="
00871                     +ee.toString()+")");
00872         if(idxs.size() >= 1) {
00873           int idx(idxs[0]);
00874           // Check if ee[idx] is a bitvector of 0's or 1's
00875           bool isZero(true);
00876           bool isOne(true);
00877           const Expr& c = ee[idx];
00878           for(int i=0, iend=getBVConstSize(c);
00879               (isZero || isOne) && (i<iend); ++i) {
00880             isZero = (isZero && !getBVConstValue(c, i));
00881             isOne  &= (isOne && getBVConstValue(c, i));
00882           }
00883           if(isOne)
00884             res = transitivityRule(res, d_rules->orOne(ee, idx));
00885           else if(isZero)
00886             res = transitivityRule(res, d_rules->orZero(ee, idxs));
00887           
00888         }
00889       }
00890       // Lift concatenation over bit-wise OR and rewrite again
00891       ee = res.getRHS();
00892       if(ee.getOpKind() == BVOR) {
00893         int i=0, iend=ee.arity();
00894         // Search for the first CONCAT child
00895         for(; (i<iend) && ee[i].getOpKind() != CONCAT; ++i);
00896         // If found, lift CONCAT over BVOR, and rewrite 3 levels
00897         // deep.  Reason: the result of orConcat is of the form:
00898         // (@ (| ... t_k[i:j] ...) ... ), and only t_k is known to be 
00899         // completely rewritten.  Hence the 3 levels of rewrites.
00900         if(i<iend)
00901           res = transitivityRule(res, rewriteBV(d_rules->orConcat(ee, i),
00902                                                 3, useFind));
00903       }
00904       break;
00905     }
00906 
00907 //     case BVXOR: {
00908 //       // Flatten the bit-wise OR, eliminate duplicates, reorder terms
00909 //       res = d_rules->orFlatten(e);
00910 //       Expr ee = res.getRHS();
00911 //       // Search for constant bitvectors
00912 //       vector<int> idxs;
00913 //       constantKids(ee, idxs);
00914 //       if(idxs.size() >= 2) {
00915 //      res = transitivityRule(res, d_rules->orConst(ee, idxs));
00916 //       }
00917 //       ee = res.getRHS();
00918 //       if(ee.getOpKind() == BVOR) {
00919 //      // Search for constants again
00920 //      idxs.clear();
00921 //      constantKids(ee, idxs);
00922 //      DebugAssert(idxs.size() <= 1, "TheoryBitvector::normalizeConcat(ee="
00923 //                  +ee.toString()+")");
00924 //      if(idxs.size() >= 1) {
00925 //        int idx(idxs[0]);
00926 //        // Check if ee[idx] is a bitvector of 0's or 1's
00927 //        bool isZero(true);
00928 //        bool isOne(true);
00929 //        const Expr& c = ee[idx];
00930 //        for(int i=0, iend=c.getIntValueSize();
00931 //            (isZero || isOne) && (i<iend); ++i) {
00932 //          isZero = (isZero && c.getIntValue(i) == 0);
00933 //          isOne  &= (isOne && c.getIntValue(i) == 1);
00934 //        }
00935 //        if(isOne)
00936 //          res = transitivityRule(res, d_rules->orOne(ee, idx));
00937 //        else if(isZero)
00938 //          res = transitivityRule(res, d_rules->orZero(ee, idxs));
00939           
00940 //      }
00941 //       }
00942 //       // Lift concatenation over bit-wise OR and rewrite again
00943 //       ee = res.getRHS();
00944 //       if(ee.getOpKind() == BVOR) {
00945 //      int i=0, iend=ee.arity();
00946 //      // Search for the first CONCAT child
00947 //      for(; (i<iend) && ee[i].getOpKind() != CONCAT; ++i);
00948 //      // If found, lift CONCAT over BVOR, and rewrite 3 levels
00949 //      // deep.  Reason: the result of orConcat is of the form:
00950 //      // (@ (| ... t_k[i:j] ...) ... ), and only t_k is known to be 
00951 //      // completely rewritten.  Hence the 3 levels of rewrites.
00952 //      if(i<iend)
00953 //        res = transitivityRule(res, rewriteBV(d_rules->orConcat(ee, i),
00954 //                                              3, useFind));
00955 //       }
00956 //       break;
00957 //     }
00958     case CONCAT: {
00959       // Congruence closure rewrite
00960       res = rewriteCC(e);
00961       // First, flatten concatenation
00962       res = transitivityRule(res, d_rules->concatFlatten(res.getRHS()));
00963       TRACE("bitvector rewrite", "normalizeConcat: flattened = ",
00964             res.getRHS(), "");
00965       // Search for adjacent constants and accumulate the vector of
00966       // nested concatenations (@ t1 ... (@ c1 ... ck) ... tn), and the
00967       // indices of constant concatenations in this new expression.
00968       // We'll connect this term to 'e' by inverse of flattenning, and
00969       // rewrite concatenations of constants into bitvector constants.
00970       vector<unsigned> idxs;
00971       vector<Expr> kids; // Kids of the new concatenation
00972       vector<Theorem> thms; // Rewrites of constant concatenations
00973       vector<Expr> nestedKids; // Kids of the current concatenation of constants
00974       // res will be overwritten, using const Expr& may be dangerous
00975       Expr e1 = res.getRHS();
00976       for(int i=0, iend=e1.arity(); i<iend; ++i) {
00977         TRACE("bitvector rewrite", "normalizeConcat: e["+int2string(i)+"]=",
00978               e1[i], "");
00979         if(e1[i].getKind() == BVCONST) {
00980           // INVARIANT: if it is the first constant in a batch,
00981           // then nestedKids must be empty.
00982           nestedKids.push_back(e1[i]);
00983           TRACE("bitvector rewrite", "normalizeConcat: queued up BVCONST: ",
00984                 e1[i], "");
00985         } else { // e1[i] is not a BVCONST
00986           if(nestedKids.size() > 0) { // This is the end of a batch
00987             if(nestedKids.size() >= 2) { // Create a nested const concat
00988               Expr cc = newConcatExpr(nestedKids);
00989               idxs.push_back(kids.size());
00990               kids.push_back(cc);
00991               thms.push_back(d_rules->concatConst(cc));
00992               TRACE("bitvector rewrite", "normalizeConcat: wrapping ", cc, "");
00993             } else { // A single constant, add it as it is
00994               TRACE("bitvector rewrite", "normalizeConcat: single const ",
00995                     nestedKids[0], "");
00996               kids.push_back(nestedKids[0]);
00997             }
00998             nestedKids.clear();
00999           }
01000           // Add the current non-constant BV
01001           kids.push_back(e1[i]);
01002         }
01003       }
01004       // Handle the last BVCONST
01005       if(nestedKids.size() > 0) {
01006         if(nestedKids.size() >= 2) { // Create a nested const concat
01007           Expr cc = newConcatExpr(nestedKids);
01008           idxs.push_back(kids.size());
01009           kids.push_back(cc);
01010           thms.push_back(d_rules->concatConst(cc));
01011           TRACE("bitvector rewrite", "normalizeConcat: wrapping ", cc, "");
01012         } else { // A single constant, add it as it is
01013           kids.push_back(nestedKids[0]);
01014           TRACE("bitvector rewrite", "normalizeConcat: single const ",
01015                 nestedKids[0], "");
01016         }
01017         nestedKids.clear();
01018       }
01019       // If there are any constants to merge, do the merging
01020       if(idxs.size() > 0) {
01021         // CONCAT with constants groupped
01022         if(kids.size() == 1) { // Special case: all elements are constants
01023           DebugAssert(thms.size() == 1, "TheoryBitvector::normalizeConcat:\n"
01024                       "case CONCAT: all constants.  thms.size() == "
01025                       +int2string(thms.size()));
01026           res = transitivityRule(res, thms[0]);
01027         } else {
01028           Expr ee = newConcatExpr(kids);
01029           
01030           Theorem constMerge = substitutivityRule(ee, idxs, thms);
01031           // The inverse flattening of ee
01032           Theorem unFlatten = symmetryRule(d_rules->concatFlatten(ee));
01033           // Putting it together: Theorem(e==e'), where e' has constants merged
01034           res = transitivityRule(res, unFlatten);
01035           res = transitivityRule(res, constMerge);
01036         }
01037       }
01038       
01039       // Now do a similar search for mergeable extractions
01040       idxs.clear();
01041       thms.clear();
01042       kids.clear();
01043       // nestedKids must already be empty
01044       DebugAssert(nestedKids.size() == 0,
01045                   "normalizeConcat() case CONCAT, end of const merge");
01046       Expr prevExpr; // Previous base of extraction (initially Null)
01047       // The first and the last bit in the batch of mergeable extractions
01048       int hi(-1), low(-1);
01049       // Refresh e1
01050       e1 = res.getRHS();
01051       for(int i=0, iend=e1.arity(); i<iend; ++i) {
01052         const Expr& ei = e1[i];
01053         if(ei.getOpKind() == EXTRACT) {
01054           if(nestedKids.size() > 0 && ei[0] == prevExpr
01055              && (low-1) == getExtractHi(ei)) {
01056             // Continue to accumulate the current batch
01057             nestedKids.push_back(ei);
01058             low = getExtractLow(ei);
01059           } else { // Start a new batch
01060             // First, check if there was a batch before that
01061             if(nestedKids.size() >= 2) { // Create a nested const concat
01062               Expr cc = newConcatExpr(nestedKids);
01063               idxs.push_back(kids.size());
01064               kids.push_back(cc);
01065               thms.push_back(d_rules->concatMergeExtract(cc));
01066               nestedKids.clear();
01067             } else if(nestedKids.size() == 1) {
01068               // A single extraction, add it as it is
01069               kids.push_back(nestedKids[0]);
01070               nestedKids.clear();
01071             }
01072             // Now, actually start a new batch
01073             nestedKids.push_back(ei);
01074             hi = getExtractHi(ei);
01075             low = getExtractLow(ei);
01076             prevExpr = ei[0];
01077           }
01078         } else { // e1[i] is not an EXTRACT
01079           if(nestedKids.size() >= 2) { // Create a nested const concat
01080             Expr cc = newConcatExpr(nestedKids);
01081             idxs.push_back(kids.size());
01082             kids.push_back(cc);
01083             thms.push_back(d_rules->concatMergeExtract(cc));
01084           } else if(nestedKids.size() == 1) {
01085             // A single extraction, add it as it is
01086             kids.push_back(nestedKids[0]);
01087           }
01088           nestedKids.clear();
01089           // Add the current non-EXTRACT BV
01090           kids.push_back(ei);
01091         }
01092       }
01093       // Handle the last batch of extractions
01094       if(nestedKids.size() >= 2) { // Create a nested const concat
01095         Expr cc = newConcatExpr(nestedKids);
01096         idxs.push_back(kids.size());
01097         kids.push_back(cc);
01098         // The extraction may include all the bits, we need to rewrite again
01099         thms.push_back(rewriteBV(d_rules->concatMergeExtract(cc), 1, useFind));
01100       } else if(nestedKids.size() == 1) {
01101         // A single extraction, add it as it is
01102         kids.push_back(nestedKids[0]);
01103       }
01104       // If there are any extractions to merge, do the merging
01105       if(idxs.size() > 0) {
01106         // CONCAT with extractions groupped
01107         if(kids.size() == 1) { // Special case: all elements merge together
01108           DebugAssert(thms.size() == 1, "TheoryBitvector::normalizeConcat:\n"
01109                       "case CONCAT: all extracts merge.  thms.size() == "
01110                       +int2string(thms.size()));
01111           res = thms[0];
01112         } else {
01113           Expr ee = newConcatExpr(kids);
01114           Theorem extractMerge = substitutivityRule(ee, idxs, thms);
01115           // The inverse flattening of ee
01116           Theorem unFlatten = symmetryRule(d_rules->concatFlatten(ee));
01117           // Putting it together: Theorem(e==e'), where e' has extractions merged
01118           res = transitivityRule(res, unFlatten);
01119           res = transitivityRule(res, extractMerge);
01120         }
01121       }
01122       // Check for 0bin00 @ BVPLUS(n, ...).  Most of the time, this
01123       // case will be handled during the top-down phase
01124       // (simplifyOp()), but not always.
01125       const Expr& ee = res.getRHS();
01126       if(ee.getOpKind()==CONCAT && ee[0].getKind()==BVCONST
01127          && ee[1].getOpKind()==BVPLUS && computeBVConst(ee[0]) == 0) {
01128         // Push the concat down through BVPLUS
01129         Theorem thm = d_rules->bvplusZeroConcatRule(ee);
01130         if(thm.getLHS()!=thm.getRHS()) {
01131           thm = transitivityRule(thm, padBVPlus(thm.getRHS()));
01132           // Kids may need to be rewritten again
01133           res = rewriteBV(transitivityRule(res, thm), 2, useFind);
01134         }
01135       }
01136       // Since we may have pulled subexpressions from more than one
01137       // level deep, we cannot guarantee that all the new kids are
01138       // fully simplified, and have to call simplify explicitly again.
01139       // Since this is potentially an expensive operation, we try to
01140       // minimize the need for it: 
01141 
01142       // * check if the result has a find pointer (then kids don't
01143       //   need to be simplified),
01144       // * check if any of the kids simplify (if not, don't bother).
01145       // If kids are already simplified, we'll hit the simplifier
01146       // cache.  It's only expensive when kids do indeed simplify.
01147       if(!res.getRHS().hasFind()) {
01148         const Expr& ee = res.getRHS();
01149         vector<Theorem> thms;
01150         vector<unsigned> changed;
01151         for(int i=0, iend=ee.arity(); i<iend; ++i) {
01152           Theorem thm = simplify(ee[i]);
01153           if(thm.getLHS()!=thm.getRHS()) {
01154             thms.push_back(thm);
01155             changed.push_back(i);
01156           }
01157         }
01158         if(changed.size()>0) {
01159           Theorem subst = substitutivityRule(ee, changed, thms);
01160           res = transitivityRule(res, rewriteBV(subst, 1, useFind));
01161         }
01162       }
01163       // Finally, do another congruence closure rewrite, to guarantee
01164       // that the kids are fully simplified
01165       if(res.getRHS().getOpKind()==CONCAT)
01166         res = transitivityRule(res, rewriteCC(res.getRHS()));
01167       break;
01168     }
01169     default:
01170       DebugAssert(false, "normalizeConcat: bad expr: "+e.toString());
01171       res = reflexivityRule(e);
01172       break;
01173     }
01174     DebugAssert(e == res.getLHS(), "normalizeConcat:\n e = "+e.toString()
01175                 +"\n res.getLHS() = "+res.getLHS().toString());
01176   }
01177   else
01178     res = reflexivityRule(e);
01179   TRACE("bitvector rewrite", "normalizeConcat => ", res.getExpr(), " }");
01180   return res;
01181 }
01182 
01183 
01184 /*! accepts an expression e, and returns a theorem e <==>
01185  *  BVPLUS_NORMAL_FORM(e) we always assume that kids of e are in
01186  *  bvplus normal form, and only the top-level needs normalization
01187  */
01188 Theorem
01189 TheoryBitvector::normalizeBVArith(const Expr& e, bool useFind) {
01190   TRACE("bitvector rewrite", "normalizeBVArith(", e, ") {");
01191   Theorem res;
01192   if(*d_bvplusRewriteFlag) {
01193     switch(e.getOpKind()) {
01194     case BVPLUS: {
01195       DebugAssert(e.arity()>=2,
01196                   "BVPLUS must have atleast 2 kids:\n e = " + e.toString());
01197       res = padBVPlus(e);
01198       const Expr& rhs = res.getRHS();
01199       if(e != rhs)
01200         return rewriteBV(res, 4, useFind);
01201       switch(rhs.getOpKind()) {
01202       case BVPLUS: {
01203         const Theorem thm0 = flattenBVPlus(rhs);
01204         res = transitivityRule(res, thm0);
01205         //res = transitivityRule(res, padBVPlus(res.getRHS()));
01206         res = transitivityRule(res, combineLikeTerms(res.getRHS()));
01207         break;
01208       }
01209       default:
01210         return res;
01211         break;
01212       }
01213     }
01214       break;
01215     case BVMULT: {
01216       DebugAssert(e.arity()==2,
01217                   "BVMULT must have exactly 2 kids: " + e.toString());
01218       DebugAssert(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
01219                   BITVECTOR==e[1].getType().getExpr().getOpKind(),
01220                   "For BVMULT terms e[0], e[1] must be a BV:\n e = "
01221                   +e.toString());
01222       if(BVCONST == e[0].getKind() || BVCONST == e[1].getKind()) {
01223         if(constantKids(e)) {
01224           res = d_rules->bvmultConst(e);
01225           TRACE("bitvector rewrite", "normalizeBVArith[const] => ",
01226                 res.getExpr(), " }");
01227           return res;
01228         }
01229         
01230         if(BVCONST == e[1].getKind()) {
01231           const Theorem thm = d_rules->flipBVMult(e);
01232           const Theorem thm1 = normalizeBVArith(thm.getRHS(), useFind);
01233           res = transitivityRule(thm, thm1);      
01234           TRACE("bitvector rewrite", "normalizeBVArith[flip] => ",
01235                 res.getExpr(), " }");
01236           return res;
01237         }
01238         const Rational coeff = computeBVConst(e[0]);
01239         if(0 == coeff) {
01240           res = d_rules->zeroCoeffBVMult(e);
01241           TRACE("bitvector rewrite", "normalizeBVArith[c=0] => ",
01242                 res.getExpr(), " }");
01243           return res;
01244         }
01245         else if(1 == coeff) {
01246           res = d_rules->oneCoeffBVMult(e); 
01247           TRACE("bitvector rewrite", "normalizeBVArith[c=1] => ",
01248                 res.getExpr(), " }");
01249           return res;
01250         }
01251         
01252         DebugAssert(coeff > 1,
01253                     "in BVMULT e[0] must be a rational: " + e.toString());
01254         const Theorem thm = d_rules->padBVMult(e);
01255         if(thm.getLHS() != thm.getRHS()) {
01256           const Theorem thm1 = rewriteBV(thm.getRHS(), 2, useFind);
01257           res = transitivityRule(thm, thm1);
01258           TRACE("bitvector rewrite", "normalizeBVArith[pad] => ",
01259                 res.getExpr(), " }");
01260           return res;
01261         }
01262         
01263         switch(e[1].getOpKind()) {
01264         case BVMULT: {
01265           //e is of the form a*(b*t); e cannot be of the form a*(t*b)
01266           //or a*(b*c) since the kids are always in normal form
01267           DebugAssert(BVCONST == e[1][0].getKind(),
01268                       "e[1][0] must be a BVCONST: " + 
01269                       e.toString());
01270           //e <==> (a*b)*t
01271           const Theorem thm2 = 
01272             d_rules->bvConstMultAssocRule(e);
01273           res = thm2;
01274           break;
01275         }
01276         case BVPLUS: {
01277           DebugAssert(BVCONST == e[0].getKind(),
01278                       "e[0] must be a BVCONST" + e.toString());
01279           //a*(t1+...+tn) <==> a*t1 + ... + a*tn
01280           const Theorem thm0 = d_rules->bvMultDistRule(e);
01281           res = rewriteBV(thm0, 2, useFind);
01282           break;
01283         }
01284         default:
01285           res = reflexivityRule(e);
01286           break;
01287         }
01288       }
01289       //nonlinear multiplication
01290       else
01291         if(e[1] < e[0])
01292           res = d_rules->flipBVMult(e);
01293         else
01294           res = reflexivityRule(e);
01295       //        //FIXME: fix this rule later
01296       //        rhs = res.getRHS();
01297       //        if(BVMULT == rhs[0].getOpKind() || BVMULT == rhs[1].getOpKind())
01298       //          res = d_rules->bvMultAssocRule(rhs);
01299       //       }
01300       break;
01301     }
01302     case BVUMINUS: {
01303       DebugAssert(e.arity() == 1,
01304                   "e can atmost have one kid" + e.toString());
01305       DebugAssert(e[0].getOpKind() != BVUMINUS,
01306                   "e[0] may not be BVUMINUS, it must be normalized:"+
01307                   e.toString());
01308       Theorem thm0 = d_rules->bvuminusToBVPlus(e);
01309       Theorem temp = pushNegation(thm0.getRHS()[0]);
01310       if (temp.getLHS() != temp.getRHS()) {
01311         vector<Theorem> thms;
01312         vector<unsigned> changed;
01313         thms.push_back(temp);
01314         changed.push_back(0);
01315         Theorem thm1 = substitutivityRule(thm0.getRHS(),changed,thms);
01316         thm0 = transitivityRule(thm0,thm1);
01317       }
01318       Theorem thm2 = rewriteBV(thm0.getRHS(), 2, useFind);
01319       res= transitivityRule(thm0,thm2);
01320     }
01321       break;
01322     default:
01323       res = reflexivityRule(e);
01324       break;
01325     }
01326   } 
01327   else
01328     res = reflexivityRule(e);
01329   TRACE("bitvector rewrite", "normalizeBVArith => ", res.getExpr(), " }");
01330   return res;
01331 }
01332 
01333 Theorem TheoryBitvector::combineLikeTerms(const Expr& e) {
01334   Theorem thm0 = d_rules->combineLikeTermsRule(e);
01335   return thm0;
01336 }
01337 
01338 Theorem TheoryBitvector::padBVPlus(const Expr& e) {
01339   TRACE("bv pad", "padBVPlus(", e, ") {");
01340   DebugAssert(BVPLUS == e.getOpKind(),
01341               "TheoryBitvector::padBVPlus:"
01342               "input must be a BVPLUS: " + e.toString());
01343 //   bool needPadding = false;
01344   
01345 //   //loop thru' the subterms to check if they need padding
01346 //   int bvlen = BVSize(e);
01347 //   for(Expr::iterator  i=e.begin(), iend=e.end();i!=iend;++i) {
01348 //     int monomlen = BVSize(*i);
01349 //     if(monomlen != bvlen) {
01350 //       needPadding = true;
01351 //       break;
01352 //     }
01353 //   }
01354   Theorem res;
01355 //   if(needPadding) {
01356   res = d_rules->padBVPlus(e);
01357 //   } else
01358 //     res = reflexivityRule(e);
01359   TRACE("bv pad", "padBVPlus => ", res.getExpr(), " }");
01360   return res;
01361 }
01362 
01363   
01364 Theorem TheoryBitvector::flattenBVPlus(const Expr& e) {
01365   DebugAssert(BVPLUS == e.getOpKind(),
01366               "TheoryBitvector::padBVPlus:"
01367               "input must be a BVPLUS: " + e.toString());
01368 
01369   bool needFlattening = false;  
01370   //loop thru' the subterms to check if they need flatten
01371   for(Expr::iterator  i=e.begin(), iend=e.end();i!=iend;++i) {
01372     if(BVPLUS == (*i).getOpKind()) {
01373       needFlattening = true;
01374       break;
01375     }
01376   }
01377   
01378   Theorem res;
01379   if(needFlattening)
01380     res = d_rules->flattenBVPlus(e);
01381   else
01382     res = reflexivityRule(e);
01383 
01384   return res;
01385 }
01386 
01387 //! signextend e0 <=(s) e1 appropriately, then normalize and return
01388 Theorem TheoryBitvector::signExtendBVLT(const Expr& e, int len, bool useFind) {
01389   DebugAssert(e.getOpKind()==SBVLT || e.getOpKind()==SBVLE,
01390               "TheoryBitvector::signExtendBVLT: input must be BVLT/BVLE"
01391               + e.toString());
01392   std::vector<Theorem> thms;
01393   std::vector<unsigned> changed;
01394 
01395   //e0 <= e1 <==> pad(e0) <= pad(e1)
01396   Theorem thm = d_rules->padSBVLTRule(e, len);
01397   Expr paddedE = thm.getRHS();
01398 
01399   //the rest of the code simply normalizes pad(e0) and pad(e1)
01400   Theorem thm0 = d_rules->signExtendRule(paddedE[0]);
01401   Expr rhs0 = thm0.getRHS();
01402   thm0 = transitivityRule(thm0, rewriteBV(rhs0, useFind));
01403   if(thm0.getLHS() != thm0.getRHS()) {
01404     thms.push_back(thm0);
01405     changed.push_back(0);
01406   }
01407   
01408   Theorem thm1 = d_rules->signExtendRule(paddedE[1]);
01409   Expr rhs1 = thm1.getRHS();
01410   thm1 = transitivityRule(thm1, rewriteBV(rhs1, useFind));
01411   if(thm1.getLHS() != thm1.getRHS()) {
01412     thms.push_back(thm1);
01413     changed.push_back(1);
01414   }
01415 
01416   Theorem result;
01417   if(changed.size() > 0) {
01418     result = substitutivityRule(paddedE,changed,thms);
01419     result = transitivityRule(thm, result);
01420   }
01421   else
01422     result = reflexivityRule(e);
01423   return result;
01424 }
01425 
01426 Theorem TheoryBitvector::rewriteConst(const Expr& e)
01427 {
01428   // Rewrite bitvector operators which have constant arguments
01429   switch(e.getOpKind()) {
01430   case EQ:
01431     if(constantKids(e))
01432       return d_rules->eqConst(e);
01433     break;
01434   case CONCAT:
01435     if(constantKids(e))
01436       return d_rules->concatConst(e);
01437     break;
01438   case BVAND: {
01439     vector<int> idxs;
01440     constantKids(e, idxs);
01441     if(idxs.size() >= 2)
01442       return d_rules->andConst(e, idxs);
01443     break;
01444   }
01445   case BVOR: {
01446     vector<int> idxs;
01447     constantKids(e, idxs);
01448     if(idxs.size() >= 2)
01449       return d_rules->orConst(e, idxs);
01450     break;
01451   }
01452   case BVNEG:
01453     if(constantKids(e))
01454       return d_rules->negConst(e);
01455     break;
01456   case BOOLEXTRACT:
01457     if(constantKids(e))
01458       return d_rules->bitExtractConstant(e[0], getBoolExtractIndex(e));
01459     break;
01460   case EXTRACT:
01461     if(constantKids(e))
01462       return d_rules->extractConst(e);
01463     break;
01464   case BVPLUS:
01465     if(constantKids(e))
01466       return d_rules->bvplusConst(e);
01467     break;
01468   case BVMULT:
01469     if(constantKids(e))
01470       return d_rules->bvmultConst(e);
01471     break;
01472   default:
01473     break;
01474   }
01475   return reflexivityRule(e);
01476 }
01477 
01478 Theorem TheoryBitvector::rewriteBV(const Expr& e, bool useFind) {
01479   ExprMap<Theorem> cache;
01480   return rewriteBV(e, cache, useFind);
01481 }
01482 
01483 
01484 Theorem TheoryBitvector::rewriteBV(const Expr& e, ExprMap<Theorem>& cache,
01485                                    bool useFind) {
01486   TRACE("bitvector rewrite", "TheoryBitvector::rewriteBV(", e, ") {");
01487 
01488   ExprMap<Theorem>::iterator it = cache.find(e);
01489   if(it!=cache.end()) {
01490     Theorem res = (*it).second;
01491     TRACE("bitvector rewrite", "TheoryBitvector::rewriteBV[cached] => ",
01492           res.getExpr(), " }");
01493     IF_DEBUG(debugger.counter("bv rewriteBV cache hits")++);
01494     return res;
01495   }
01496     
01497   Theorem res;
01498   switch(e.getOpKind()) {
01499   case EQ: {
01500     // Rewrite bitvector operators which have constant arguments
01501     if(constantKids(e)) {
01502       res = d_rules->eqConst(e);
01503       IF_DEBUG(debugger.counter("bv rewrite const eq")++);
01504     } 
01505     //if both e[0],e[1] are BVPLUS. I disregard other cases like
01506     //BVPLUS(x,y)=x
01507     else if (BVPLUS == e[0].getOpKind() && 
01508              BVPLUS == e[1].getOpKind() &&
01509              *d_lhsMinusRhsFlag) {
01510       // e[0]=e[1] <==> e[0]+(-e[1])=0
01511       res = d_rules->lhsMinusRhsRule(e);
01512       Theorem  thm0 = rewriteBV(res.getRHS(),2,useFind);
01513       res = transitivityRule(res,thm0);
01514     }   
01515     else
01516       res = reflexivityRule(e);
01517     break;
01518   }
01519   case BOOLEXTRACT: {
01520     Expr t(e);
01521     // Normal form: t[0] for 1-bit t, collapse t[i:i][0] into t[i]
01522     if(BVSize(e[0]) > 1) { // transform t[i] to t[i:i][0] and rewrite
01523       res = rewriteBV(d_rules->bitExtractRewrite(e), cache, 2, useFind);
01524       t = res.getRHS();
01525     }
01526     if(t.getOpKind() == BOOLEXTRACT && t[0].getOpKind() == EXTRACT) {
01527       // Collapse t[i:i][0] to t[i]
01528       int low = getExtractLow(t[0]);
01529       if(getExtractHi(t[0]) == low) {
01530         Theorem thm(d_rules->bitExtractRewrite
01531                     (newBoolExtractExpr(t[0][0], low)));
01532         thm = symmetryRule(thm);
01533         res = (res.isNull())? thm : transitivityRule(res, thm);
01534         t = res.getRHS()[0];
01535         // Make sure t in the resulting t[i] is its own find pointer
01536         // (global invariant)
01537         if(useFind && t.hasFind()) {
01538           Theorem findThm = find(t);
01539           if(t != findThm.getRHS()) {
01540             vector<Theorem> thms;
01541             thms.push_back(findThm);
01542             thm = substitutivityRule(res.getRHS().getOp(), thms);
01543             res = transitivityRule(res, thm);
01544           }
01545         }
01546       }
01547     }
01548     if(!res.isNull()) t = res.getRHS();
01549     // Rewrite a constant extraction to TRUE or FALSE
01550     if(t.getOpKind() == BOOLEXTRACT && constantKids(t)) {
01551       Theorem thm = d_rules->bitExtractConstant(t[0], getBoolExtractIndex(t));
01552       res = (res.isNull())? thm : transitivityRule(res, thm);
01553     }
01554     break;
01555   }
01556   case SBVLT:
01557   case SBVLE:{
01558     /*! input: e0 <=(s) e1. output depends on whether the topbits(MSB) of
01559      *  e0 and e1 are constants. If they are constants then optimizations
01560      *  are done. In general, the following rule is implemented.
01561      * Step1:
01562      *                    e0 <=(s) e1 
01563      *                       <==> 
01564      *                 pad(e0) <=(s) pad(e1)
01565      * Step2:
01566      *                 pad(e0) <=(s) pad(e1) 
01567      *                       <==> 
01568      *             (e0[n-1] AND NOT e1[n-1]) OR 
01569      *             (e0[n-1] AND e1[n-1] AND e1[n-2:0] <= e0[n-2:0]) OR 
01570      *             (NOT e0[n-1] AND NOT e1[n-1] AND e0[n-2:0] <= e1[n-2:0])
01571      */
01572     int e0len = BVSize(e[0]);
01573     int e1len = BVSize(e[1]);
01574     int bvlength = e0len>=e1len ? e0len : e1len;
01575     //e0 <=(s) e1 <=> signpad(e0) <=(s) signpad(e1)
01576     Theorem thm0 = signExtendBVLT(e, bvlength, useFind);
01577     //signpad(e0) <= signpad(e1)
01578     Expr thm0RHS = thm0.getRHS();
01579     DebugAssert(thm0RHS.getOpKind() == SBVLT || 
01580                 thm0RHS.getOpKind() == SBVLE,
01581                 "TheoryBitvector::RewriteBV");
01582     //signpad(e0)[bvlength-1:bvlength-1]
01583     const Expr MSB0 = newBVExtractExpr(thm0RHS[0],bvlength-1,bvlength-1);
01584     //signpad(e1)[bvlength-1:bvlength-1]
01585     const Expr MSB1 = newBVExtractExpr(thm0RHS[1],bvlength-1,bvlength-1);
01586     //rewritten MSB0
01587     const Theorem topBit0 = rewriteBV(MSB0, 2, useFind);
01588     //rewritten MSB1
01589     const Theorem topBit1 = rewriteBV(MSB1, 2, useFind);
01590     //compute e0 <=(s) e1 <==> signpad(e0) <=(s) signpad(e1) <==>
01591     //output as given above
01592     Theorem thm1 = d_rules->signBVLTRule(thm0RHS, topBit0, topBit1);
01593     thm1 = transitivityRule(thm1,simplify(thm1.getRHS()));
01594     res = transitivityRule(thm0,thm1);
01595     break;
01596   }
01597   case BVLT:
01598   case BVLE: {
01599     Expr lhs = e[0];
01600     Expr rhs = e[1];
01601     int e0len = BVSize(lhs);
01602     int e1len = BVSize(rhs);
01603     int bvlength = e0len>=e1len ? e0len : e1len;
01604     //e0 <= e1 <=> pad(e0) <= pad(e1)
01605     Theorem thm0 = d_rules->padBVLTRule(e, bvlength);
01606     //pad(e0) <= pad(e1)
01607     Expr thm0RHS = thm0.getRHS();
01608     DebugAssert(thm0RHS.getOpKind() == BVLT || 
01609                 thm0RHS.getOpKind() == BVLE,
01610                 "TheoryBitvector::RewriteBV");
01611     //pad(e0)
01612     Expr thm0RHS0 = thm0RHS[0];
01613     //pad(e1)
01614     Expr thm0RHS1 = thm0RHS[1];    
01615     //pad(e0) <=> pad(e0)'
01616     Theorem rhsThm0 = rewriteBV(thm0RHS0, 2, false);
01617     //pad(e1) <=> pad(e1)'
01618     Theorem rhsThm1 = rewriteBV(thm0RHS1, 2, false);
01619 
01620     std::vector<Theorem> thms;
01621     std::vector<unsigned> changed;
01622     if(rhsThm0.getLHS() != rhsThm0.getRHS()) {
01623       thms.push_back(rhsThm0);
01624       changed.push_back(0);
01625     }    
01626     if(rhsThm1.getLHS() != rhsThm1.getRHS()) {
01627       thms.push_back(rhsThm1);
01628       changed.push_back(1);
01629     }
01630 
01631     Theorem thm1;
01632     if(changed.size() > 0) {
01633       //pad(e0)<pad(e1) <=> pad(e0)' < pad(e1)'
01634       thm1 = substitutivityRule(thm0RHS, changed, thms);
01635       thm1 = transitivityRule(thm0,thm1);
01636     }
01637     else
01638       thm1 = thm0;
01639 
01640     lhs = thm1.getRHS()[0];
01641     rhs = thm1.getRHS()[1];
01642     Expr newE = thm1.getRHS();
01643 
01644     int kind = newE.getOpKind();
01645     if(lhs == rhs)
01646       res = transitivityRule(thm1,d_rules->lhsEqRhsIneqn(newE, kind));
01647     else if(BVCONST == lhs.getKind() && BVCONST == rhs.getKind())
01648       res = transitivityRule(thm1,d_rules->bvConstIneqn(newE, kind));
01649     else
01650       res = reflexivityRule(e);
01651     break;
01652   }
01653   case SX: {  
01654     res = d_rules->signExtendRule(e);
01655     Expr rhs = res.getRHS();
01656     res = transitivityRule(res, rewriteBV(rhs, useFind));
01657     break;
01658   }
01659   case RIGHTSHIFT:
01660     res = rewriteBV(d_rules->rightShiftToConcat(e), 1, useFind);
01661     break;
01662   case LEFTSHIFT:
01663     res = rewriteBV(d_rules->leftShiftToConcat(e), 1, useFind);
01664     break;
01665   case CONCAT:  
01666   case BVAND:
01667   case BVOR:
01668   case BVNEG:
01669   case EXTRACT:
01670     res = normalizeConcat(e, useFind);
01671     break;
01672   case BVPLUS:
01673   case BVUMINUS:
01674   case BVMULT:
01675     res = normalizeBVArith(e, useFind);
01676     break;
01677   default:
01678     break;
01679   }
01680   if(res.isNull()) res = reflexivityRule(e);
01681   // Ensure that the result is a find pointer of itself (if it has any)
01682   const Expr& rhs = res.getRHS();
01683   // Congruence Closure rewrites for CONCAT
01684   if(res.getRHS().getOpKind()==CONCAT) {
01685     res = transitivityRule(res, rewriteCC(res.getRHS()));
01686   }
01687   if(useFind && rhs.hasFind())
01688     res = transitivityRule(res, find(rhs));
01689   cache[e] = res;
01690   TRACE("bitvector rewrite", "TheoryBitvector::rewriteBV => ",
01691         res.getExpr(), " }");
01692   return res;
01693 }
01694 
01695 
01696 Theorem
01697 TheoryBitvector::rewriteBV(const Expr& e, int n, bool useFind) {
01698   ExprMap<Theorem> cache;
01699   return rewriteBV(e, cache, n, useFind);
01700 }
01701 
01702 Theorem
01703 TheoryBitvector::rewriteBV(const Expr& e, ExprMap<Theorem>& cache, int n,
01704                            bool useFind) {
01705   TRACE("bitvector rewrite",
01706         "TheoryBitvector::rewriteBV["+int2string(n)+"](", e, ") {");
01707   Theorem res;
01708 
01709   if(n > 0) {
01710     // First, check the cache
01711     ExprMap<Theorem>::iterator it = cache.find(e);
01712     if(it!=cache.end()) {
01713       res = (*it).second;
01714       TRACE("bitvector rewrite", "TheoryBitvector::rewrite["+int2string(n)
01715             +"][cached] => ", res.getExpr(), " }");
01716       IF_DEBUG(debugger.counter("bv rewriteBV[n] cache hits")++);
01717       return res;
01718     }
01719     
01720     if(n >= 2) {
01721       // rewrite children recursively
01722       vector<Theorem> thms;
01723       vector<unsigned> changed;
01724       for(int i=0, iend=e.arity(); i<iend; ++i) {
01725         Theorem thm = rewriteBV(e[i], cache, n-1, useFind);
01726         if(thm.getLHS() != thm.getRHS()) {
01727           thms.push_back(thm);
01728           changed.push_back(i);
01729         }
01730       }
01731       if(changed.size() > 0)
01732         res = substitutivityRule(e, changed, thms);
01733     }
01734     // Rewrite the top node
01735     if(res.isNull())
01736       res = rewriteBV(e, cache, useFind);
01737     else
01738       res = transitivityRule(res, rewriteBV(res.getRHS(), cache, useFind));
01739   } else
01740     res = reflexivityRule(e);
01741 
01742   DebugAssert(!res.isNull(), "TheoryBitvector::rewriteBV(e, cache, n)");
01743   TRACE("bitvector rewrite",
01744         "TheoryBitvector::rewriteBV["+int2string(n)+"] => ",
01745         res.getExpr(), " }");
01746   // The cache is not updated here, since it's used in rewriteBV(e, cache)
01747   return res;
01748 }
01749 
01750 // Recursively descend into the expression e, keeping track of whether
01751 // we are under even or odd number of negations ('neg' == true means
01752 // odd, the context is "negative").
01753 // Produce a proof of e <==> e' or !e <==> e', depending on whether
01754 // neg is false or true, respectively.
01755 // This function must be called only from the pushNegation function
01756 Theorem TheoryBitvector::pushNegationRec(const Expr& e, bool neg) {
01757   TRACE("pushNegation", "pushNegationRec(", e,
01758         ", neg=" + string(neg? "true":"false") + ") {");
01759   //DebugAssert(isTerm(e), 
01760   //      "TheoryBitvector::pushNegationRec: input must be a term. e = " + 
01761   //      e.toString());
01762   Expr NegExpr = newBVNegExpr(e);
01763   ExprMap<Theorem>::iterator i = d_pushNegCache.find(neg ? NegExpr : e);
01764   if(i != d_pushNegCache.end()) { // Found cached result
01765     TRACE("TheoryBitvector::pushNegation", 
01766           "pushNegationRec [cached] => ", (*i).second, "}");
01767     return (*i).second;
01768   }
01769   // By default, do not rewrite
01770   Theorem res(reflexivityRule((neg)? NegExpr : e));
01771   if(neg) {
01772     switch(e.getOpKind()) {
01773     case BVCONST: 
01774       res = d_rules->negConst(NegExpr); 
01775       break;
01776     case BVNEG:{
01777       Theorem thm0 = d_rules->negNeg(NegExpr);
01778       res = pushNegationRec(thm0.getRHS(), false);
01779       res = transitivityRule(thm0,res);
01780       break;
01781     }
01782     case BVAND: {
01783       //demorgan's laws. 
01784       Theorem thm0 = d_rules->negBVand(NegExpr);
01785       Expr ee = thm0.getRHS();
01786       if (ee.arity() == 0) res = thm0;
01787       else {
01788         //process each negated kid
01789         Op op = ee.getOp();
01790         vector<Theorem> thms;
01791         for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i)
01792           thms.push_back(pushNegationRec((*i)[0], true));
01793         res = substitutivityRule(op, thms);
01794         res = transitivityRule(thm0, res);
01795         res = transitivityRule(res, rewriteAux(res.getRHS()));
01796       }
01797       break;
01798     }
01799     case BVOR: {
01800       //demorgan's laws. 
01801       Theorem thm0 = d_rules->negBVor(NegExpr);
01802       Expr ee = thm0.getRHS();
01803       if (ee.arity() == 0) res = thm0;
01804       else {
01805         //process each negated kid
01806         Op op = ee.getOp();
01807         vector<Theorem> thms;
01808         for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i)
01809           thms.push_back(pushNegationRec((*i)[0], true));
01810         res = substitutivityRule(op, thms);
01811         res = transitivityRule(thm0, res);
01812         res = transitivityRule(res, rewriteAux(res.getRHS()));
01813       }
01814       break;
01815     }
01816     case CONCAT: {
01817       //demorgan's laws. 
01818       Theorem thm0 = d_rules->negConcat(NegExpr);
01819       Expr ee = thm0.getRHS();
01820       if (ee.arity() == 0) res = thm0;
01821       else {
01822         //process each negated kid
01823         Op op = ee.getOp();
01824         vector<Theorem> thms;
01825         for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i)
01826           thms.push_back(pushNegationRec((*i)[0], true));
01827         res = substitutivityRule(op, thms);
01828         res = transitivityRule(thm0, res);
01829       }
01830       break;
01831     }
01832     case BVPLUS:
01833       // FIXME: Need to implement the following transformation:
01834       // ~(x+y) <=> ~x+~y+1
01835       // (because  ~(x+y)+1= -(x+y) = -x-y = ~x+1+~y+1)
01836     case BVMULT:
01837       // FIXME: Need to implement the following transformation:
01838       // ~(x*y) <=> (~x+1)*y-1 
01839       // [ where we prefer x to be constant/AND/OR/NEG and then
01840       //   BVPLUS, and only then everything else].
01841       // (because  ~(x*y)+1= -(x+y) = (-x)*y = (~x+1)*y)
01842     default:
01843       res = reflexivityRule(NegExpr);
01844       break;
01845     }
01846   } else { // if(!neg)
01847     switch(e.getOpKind()) {
01848     case BVNEG: 
01849       res = pushNegationRec(e[0], true); 
01850       break;
01851     case CONCAT:
01852     case BVAND:
01853     case BVOR: {
01854       if (e.arity() == 0) res = reflexivityRule(e);
01855       else {
01856         Op op = e.getOp();
01857         vector<Theorem> thms;
01858         for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
01859           thms.push_back(pushNegationRec(*i, false));
01860         res = substitutivityRule(op, thms);
01861         res = transitivityRule(res, rewriteAux(res.getRHS()));
01862       }
01863       break;
01864     }
01865     default:
01866       res = reflexivityRule(e);
01867       break;
01868     } // end of switch(e.getOpKind())
01869   }
01870   TRACE("TheoryBitvector::pushNegation", "pushNegationRec => ", res, "}");
01871   d_pushNegCache[neg? NegExpr : e] = res;
01872   return res;
01873 }
01874 
01875 Theorem TheoryBitvector::pushNegationRec(const Theorem& thm, bool neg) {
01876   DebugAssert(thm.isRewrite(), 
01877               "TheoryBitvector::pushNegationRec(Theorem): bad theorem: "
01878               + thm.toString());
01879   Expr e(thm.getRHS());
01880   if(neg) {
01881     DebugAssert(e.isNot(), 
01882                 "TheoryBitvector::pushNegationRec(Theorem, neg = true): bad Theorem: "
01883                 + thm.toString());
01884     e = e[0];
01885   }
01886   return transitivityRule(thm, pushNegationRec(e, neg));
01887 }
01888 
01889 // We assume that the cache is initially empty
01890 Theorem TheoryBitvector::pushNegation(const Expr& e) {
01891   d_pushNegCache.clear();
01892   Theorem res;
01893   if(BVNEG == e.getOpKind())
01894     res = pushNegationRec(e[0], true);
01895   else if(BITVECTOR == e.getType().getExpr().getOpKind())
01896     res = pushNegationRec(e, false);
01897   else
01898     res = reflexivityRule(e);
01899   return res;
01900 }
01901 
01902 //! Top down simplifier
01903 Theorem TheoryBitvector::simplifyOp(const Expr& e) {
01904   if (e.arity() > 0) {
01905     Expr ee(e);
01906     Theorem thm0;
01907     switch(e.getOpKind()) {
01908     case BVNEG:
01909       if(*d_pushNegationFlag)
01910         thm0 = pushNegation(e);
01911       break;
01912     case EXTRACT:
01913       switch(e[0].getOpKind()) {
01914       case BVPLUS:
01915         thm0 = d_rules->extractBVPlus(e);
01916         break;
01917       case BVMULT:
01918         thm0 = d_rules->extractBVMult(e);
01919         break;
01920       default:
01921         thm0 = reflexivityRule(e);
01922         break;
01923       }
01924       break;
01925     case BVPLUS:
01926       thm0 = d_rules->padBVPlus(e);
01927       break;
01928     case BVMULT:
01929       thm0 = d_rules->padBVMult(e);
01930       break;
01931     case CONCAT: // 0bin0_[k] @ BVPLUS(n, args) => BVPLUS(n+k, args)
01932       if(e.arity()==2 && e[0].getKind()==BVCONST && e[1].getOpKind()==BVPLUS
01933          && computeBVConst(e[0]) == 0) {
01934         thm0 = d_rules->bvplusZeroConcatRule(e);
01935         if(thm0.getLHS()!=thm0.getRHS())
01936           thm0 = transitivityRule(thm0, padBVPlus(thm0.getRHS()));
01937       }
01938       break;
01939     case RIGHTSHIFT:
01940       thm0 = d_rules->rightShiftToConcat(e);
01941       break;
01942     case LEFTSHIFT:
01943       thm0 = d_rules->leftShiftToConcat(e);
01944       break;
01945     default:
01946       thm0 = reflexivityRule(e);
01947       break;
01948     }
01949     vector<Theorem> newChildrenThm;
01950     vector<unsigned> changed;
01951     if(thm0.isNull()) thm0 = reflexivityRule(e);
01952     ee = thm0.getRHS();
01953     int ar = ee.arity();
01954     for(int k = 0; k < ar; ++k) {
01955       // Recursively simplify the kids  
01956       Theorem thm = simplifyRec(ee[k]);
01957       if (thm.getLHS() != thm.getRHS()) {
01958         newChildrenThm.push_back(thm);
01959         changed.push_back(k);
01960       }
01961     }
01962     if(changed.size() > 0) {
01963       Theorem thm1 = substitutivityRule(ee, changed, newChildrenThm);
01964       return transitivityRule(thm0,thm1);
01965     } else
01966       return thm0;
01967   }
01968   return reflexivityRule(e);
01969 }
01970 
01971 ///////////////////////////////////////////////////////////////////////////////
01972 // TheoryBitvector Public Methods                                            //
01973 ///////////////////////////////////////////////////////////////////////////////
01974 TheoryBitvector::TheoryBitvector(TheoryCore* core)
01975   : Theory(core, "Bitvector"),
01976     d_bvDelayEq(core->getStatistics().counter("bv delayed assert eqs")),
01977     d_bvAssertEq(core->getStatistics().counter("bv eager assert eqs")),
01978     d_bvDelayDiseq(core->getStatistics().counter("bv delayed assert diseqs")),
01979     d_bvAssertDiseq(core->getStatistics().counter("bv eager assert diseqs")),
01980     d_bvTypePreds(core->getStatistics().counter("bv type preds enqueued")),
01981     d_bvDelayTypePreds(core->getStatistics().counter("bv type preds delayed")),
01982     d_bvBitBlastEq(core->getStatistics().counter("bv bitblast eqs")),
01983     d_bvBitBlastDiseq(core->getStatistics().counter("bv bitblast diseqs")),
01984     d_simplifyFlag(&(core->getFlags()["bv-simplify"].getBool())),
01985     d_booleanRWFlag(&(core->getFlags()["boolean-rewrite"].getBool())),
01986     //d_boolExtractCacheFlag(&(core->getFlags()["use-boolextract-cache"].getBool())),
01987     d_bv32Flag(&(core->getFlags()["bv32-flag"].getBool())),
01988     d_rewriteFlag(&(core->getFlags()["bv-rewrite"].getBool())),
01989     d_concatRewriteFlag(&(core->getFlags()["bv-concatnormal-rewrite"].getBool())),
01990     d_bvplusRewriteFlag(&(core->getFlags()["bv-plusnormal-rewrite"].getBool())),
01991     d_rwBitBlastFlag(&(core->getFlags()["bv-rw-bitblast"].getBool())),
01992     d_cnfBitBlastFlag(&(core->getFlags()["bv-cnf-bitblast"].getBool())),
01993     d_lhsMinusRhsFlag(&(core->getFlags()["bv-lhs-minus-rhs"].getBool())),
01994     d_updateFlag(&(core->getFlags()["bv-update"].getBool())),
01995     d_setupFlag(&(core->getFlags()["bv-setup"].getBool())),
01996     d_setupSharedFlag(&(core->getFlags()["bv-shared-setup"].getBool())),
01997     d_pushNegationFlag(&(core->getFlags()["bv-pushnegation"].getBool())),
01998     d_bitvecCache(core->getCM()->getCurrentContext()),
01999     d_eq(core->getCM()->getCurrentContext()),
02000     d_eqIdx(core->getCM()->getCurrentContext(), 0, 0),
02001     d_eqBlastIdx(core->getCM()->getCurrentContext(), 0, 0),
02002     d_diseq(core->getCM()->getCurrentContext()),
02003     d_diseqIdx(core->getCM()->getCurrentContext(), 0, 0),
02004     d_staleDB(core->getCM()->getCurrentContext()),
02005     d_tccs(core->getCM()->getCurrentContext()),
02006     d_tccsIdx(core->getCM()->getCurrentContext(), 0, 0),
02007     d_sharedSubterms(core->getCM()->getCurrentContext()),
02008     d_typePredsCache(core->getCM()->getCurrentContext())
02009 {
02010   getEM()->newKind(BITVECTOR, "BITVECTOR", true);
02011   getEM()->newKind(BVCONST, "BVCONST");
02012   getEM()->newKind(HEXBVCONST, "HEXBVCONST");
02013   getEM()->newKind(CONCAT, "CONCAT");
02014   getEM()->newKind(BVOR, "BVOR");
02015   getEM()->newKind(BVAND, "BVAND");
02016   getEM()->newKind(BVXOR, "BVXOR");
02017   getEM()->newKind(BVNAND, "BVNAND");
02018   getEM()->newKind(BVNOR, "BVNOR");
02019   getEM()->newKind(BVXNOR, "BVXNOR");
02020   getEM()->newKind(BVNEG, "BVNEG");
02021   getEM()->newKind(EXTRACT, "EXTRACT");
02022   getEM()->newKind(LEFTSHIFT, "LEFTSHIFT");
02023   getEM()->newKind(RIGHTSHIFT, "RIGHTSHIFT");
02024   getEM()->newKind(VARSHIFT, "VARSHIFT");
02025   getEM()->newKind(BVPLUS, "BVPLUS");
02026   getEM()->newKind(BVMULT, "BVMULT");
02027   getEM()->newKind(BVSUB, "BVSUB");
02028   getEM()->newKind(BVUMINUS, "BVUMINUS");
02029   getEM()->newKind(BOOLEXTRACT, "BOOLEXTRACT");
02030   getEM()->newKind(SX,"SX");
02031   getEM()->newKind(SBVLT, "SBVLT");
02032   getEM()->newKind(SBVLE, "SBVLE");
02033   getEM()->newKind(SBVGT, "SBVGT");
02034   getEM()->newKind(SBVGE, "SBVGE");
02035   getEM()->newKind(BVLT, "BVLT");
02036   getEM()->newKind(BVLE, "BVLE");
02037   getEM()->newKind(BVGT, "BVGT");
02038   getEM()->newKind(BVGE, "BVGE");
02039   getEM()->newKind(INTTOBV, "INTTOBV");
02040   getEM()->newKind(BVTOINT, "BVTOINT");
02041   getEM()->newKind(BVTYPEPRED, "BVTYPEPRED");
02042   getEM()->newKind(BVPARAMOP, "BVPARAMOP");
02043 
02044  
02045   std::vector<int> kinds;
02046   kinds.push_back(BITVECTOR);
02047   kinds.push_back(BVCONST);
02048   kinds.push_back(HEXBVCONST);
02049   kinds.push_back(CONCAT);
02050   kinds.push_back(BVOR);
02051   kinds.push_back(BVAND);
02052   kinds.push_back(BVXOR);
02053   kinds.push_back(BVXNOR);
02054   kinds.push_back(BVNAND);
02055   kinds.push_back(BVNOR);
02056   kinds.push_back(BVNEG);
02057   kinds.push_back(EXTRACT);
02058   kinds.push_back(LEFTSHIFT);
02059   kinds.push_back(RIGHTSHIFT);
02060   kinds.push_back(VARSHIFT);
02061   kinds.push_back(BVPLUS);
02062   kinds.push_back(BVMULT);
02063   kinds.push_back(BVSUB);
02064   kinds.push_back(BVUMINUS);
02065   kinds.push_back(BOOLEXTRACT);
02066   kinds.push_back(SX);
02067   kinds.push_back(SBVLT);
02068   kinds.push_back(SBVLE);
02069   kinds.push_back(SBVGT);
02070   kinds.push_back(SBVGE);
02071   kinds.push_back(BVLT);
02072   kinds.push_back(BVLE);
02073   kinds.push_back(BVGT);
02074   kinds.push_back(BVGE);
02075   kinds.push_back(INTTOBV);
02076   kinds.push_back(BVTOINT);
02077   kinds.push_back(BVTYPEPRED);
02078   kinds.push_back(BVPARAMOP);
02079 
02080   registerTheory(this, kinds);
02081  
02082   d_bvConstExprIndex = getEM()->registerSubclass(sizeof(BVConstExpr));
02083 
02084   // Cache constants 0bin0 and 0bin1
02085   vector<bool> bits(1);
02086   bits[0]=false;
02087   d_bvZero = newBVConstExpr(bits);
02088   bits[0]=true;
02089   d_bvOne = newBVConstExpr(bits);
02090 
02091   // Instantiate the rules after all expression creation is
02092   // registered, since the constructor creates some bit-vector
02093   // expressions.
02094   d_rules = createProofRules();
02095 }
02096 
02097 
02098 // Destructor: delete the proof rules class if it's present
02099 TheoryBitvector::~TheoryBitvector() {
02100   if(d_rules != NULL) delete d_rules;
02101 }
02102 
02103 
02104 void
02105 TheoryBitvector::collectSharedSubterms(const Expr& e) {
02106   TRACE("bitvector shared", "TheoryBitvector::collectSharedSubterms(", e.toString(), ")");
02107   if(d_sharedSubterms.count(e)>0) return;
02108   IF_DEBUG(debugger.counter("bv shared subterms")++);
02109   d_sharedSubterms[e]=true;
02110 
02111   if(d_typePredsCache.count(e) > 0) {
02112     Theorem pred = d_typePredsCache[e];
02113     if((pred.getExpr()).isFalse())
02114       setInconsistent(pred);
02115     else if(!(pred.getExpr()).isTrue())
02116       assertTypePred(e,pred);
02117   }
02118 
02119   if(!isLeaf(e)) {
02120     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
02121       collectSharedSubterms(*i);
02122   }
02123   setupExpr(e);
02124   if(d_sharedSubterms[e])
02125     TRACE("bitvector shared", "TheoryBitvector::collectSharedSubterms =>", "true" , ")");
02126   else
02127     TRACE("bitvector shared", "TheoryBitvector::collectSharedSubterms =>", "false" , ")");
02128 }
02129 
02130 void TheoryBitvector::addSharedTerm(const Expr& e) {
02131   IF_DEBUG(debugger.counter("bv shared terms")++);
02132   collectSharedSubterms(e);
02133 }
02134 
02135 
02136 void TheoryBitvector::assertFact(const Theorem& e) {
02137   TRACE("bitvector", "TheoryBitvector::assertFact(", e.getExpr(), ")");
02138   const Expr& expr = e.getExpr();
02139 
02140   //strategy
02141   Theorem result;
02142   switch(expr.getOpKind()) {
02143   case BVTYPEPRED:
02144     enqueueFact(d_rules->expandTypePred(e));
02145     IF_DEBUG(debugger.counter("bv expand type pred")++);
02146     break;
02147   case NOT: {
02148     const Expr& e0 = expr[0];
02149     switch(e0.getOpKind()) {
02150     case BOOLEXTRACT:
02151       // Assert e0[i:i] = 0bin0
02152       IF_DEBUG(debugger.counter("bv received NOT BOOLEXTRACT")++);
02153       if(theoryCore()->getFlags()["bv-assert"].getBool())
02154         enqueueFact(d_rules->bitExtractToExtract(e));
02155       break;
02156     case EQ:
02157       // enqueueFact(bitBlastDisEqn(e));
02158       IF_DEBUG(debugger.counter("bv received diseq")++);
02159       if(theoryCore()->getFlags()["bv-delay-diseq"].getBool()) {
02160         d_bvDelayDiseq++;
02161         d_diseq.push_back(e);
02162       }
02163       else {
02164         d_bvAssertDiseq++;
02165         result = bitBlastDisEqn(e);
02166       }
02167       break;
02168     case BVLT:
02169     case BVLE:
02170       result = d_rules->notBVLTRule(expr, expr[0].getOpKind());
02171       result = iffMP(e, result);
02172       result = iffMP(result, bitBlastIneqn(result.getExpr()));
02173       break;
02174     case BVTYPEPRED:
02175       enqueueFact(d_rules->expandTypePred(e));
02176       IF_DEBUG(debugger.counter("bv expand type pred")++);
02177       break;
02178     default: // Ignore other facts
02179       break;
02180     }
02181     break;
02182   }
02183   case BOOLEXTRACT:
02184     // Assert e0[i:i] = 0bin1
02185     if(theoryCore()->getFlags()["bv-assert"].getBool())
02186       enqueueFact(d_rules->bitExtractToExtract(e));
02187     IF_DEBUG(debugger.counter("bv received BOOLEXTRACT")++);
02188     break;
02189   case EQ:
02190     IF_DEBUG(debugger.counter("bv received eq")++);
02191     if(theoryCore()->getFlags()["bv-delay-eq"].getBool()) {
02192       d_bvDelayEq++;
02193       // d_eq.push_back(e);
02194       int size(BVSize(e.getLHS()));
02195       if(size >= 2 && theoryCore()->getFlags()["bv-bit-eq"].getBool()) {
02196         IF_DEBUG(debugger.counter("bv assert eq wide")++);
02197         // Enqueue equalities over individual bits
02198         Theorem thm = d_rules->eqToBits(e);
02199         for(int i=0; i<size; ++i) {
02200           IF_DEBUG(debugger.counter("bv delay eq 1-bit")++);
02201           Theorem ti(getCommonRules()->andElim(thm, i));
02202           ti = iffMP(ti, rewriteBV(ti.getExpr(), 2, true));
02203           // ti may simplify to TRUE or FALSE
02204           if(ti.isRewrite()) d_eq.push_back(ti);
02205           else enqueueFact(ti);
02206         }
02207       } else
02208         d_eq.push_back(e);
02209     } else {
02210       d_bvAssertEq++;
02211       result = iffMP(e, bitBlastEqn(e.getExpr()));
02212     }
02213     break;
02214   case BVLT:
02215   case BVLE:
02216     result = iffMP(e, bitBlastIneqn(e.getExpr()));
02217     break;
02218   default: // Ignore other facts
02219     break;
02220   }
02221 
02222   if(result.isNull()) return;
02223 
02224   // Simplifying bit-blasted expressions makes things easier for the
02225   // CNF converter
02226   if(*d_simplifyFlag)
02227     result = iffMP(result, simplify(result.getExpr()));
02228   else if (*d_booleanRWFlag)
02229     result = iffMP(result, rewriteBoolean(result.getExpr()));
02230   enqueueFact(result);
02231 }
02232 
02233 
02234 void
02235 TheoryBitvector::assertTypePred(const Expr& e, const Theorem& pred) {
02236   TRACE("bv asserttypepred", "TheoryBitvector::assertTypePred(", e.toString(), ")");
02237   // Ignore bitvector constants (they always satisfy type predicates)
02238   // and bitvector operators.  When rewrites and updates are enabled.
02239   // their type predicates will be implicitly derived from the type
02240   // predicates of the arguments.
02241   switch(e.getOpKind()) {
02242   case BVCONST:
02243     return;
02244   case CONCAT:
02245   case BVOR:
02246   case BVAND:
02247   case BVNEG:
02248   case EXTRACT:
02249   case LEFTSHIFT:
02250   case RIGHTSHIFT:
02251   case BVPLUS:
02252   case BVUMINUS:
02253   case BVSUB:
02254   case BVXOR:
02255   case BVXNOR:
02256   case BVNAND:
02257   case BVMULT:
02258   case BOOLEXTRACT:
02259   case SX:
02260   case SBVLT:
02261   case SBVLE:
02262   case SBVGT:
02263   case SBVGE:
02264   case BVLT:
02265   case BVLE:
02266   case BVGT:
02267   case BVGE:
02268 //   case VAR_SHIFT:
02269     if(*d_setupFlag && *d_updateFlag) return;
02270     break;
02271   default:
02272     break;
02273   }
02274   // If the variable is not a part of a shared term, don't bother
02275      if(d_sharedSubterms.count(e) == 0) {
02276        d_typePredsCache[e] = pred;
02277        return;
02278      }
02279   //The remaining type predicates are important
02280   if(!theoryCore()->getFlags()["bv-delay-typepred"].getBool()) {
02281     d_bvTypePreds++;
02282     enqueueFact(pred);
02283   }
02284   else {
02285     d_bvDelayTypePreds++;
02286     d_tccs.push_back(pred);
02287   }
02288 }
02289 
02290 
02291 void TheoryBitvector::checkSat(bool fullEffort) {
02292   if(fullEffort) {
02293     // Bit-blast equalities first
02294     if(d_eqIdx<d_eq.size()) {
02295       for(; d_eqIdx<d_eq.size(); d_eqIdx = d_eqIdx + 1) {
02296         IF_DEBUG(debugger.counter("bv enqueue eq 1-bit")++);
02297         enqueueFact(d_eq[d_eqIdx]);
02298       }
02299     } else if(d_eqBlastIdx<d_eq.size()) {
02300       for(; d_eqBlastIdx<d_eq.size(); d_eqBlastIdx = d_eqBlastIdx + 1) {
02301         Theorem result = iffMP(d_eq[d_eqBlastIdx], 
02302                                bitBlastEqn(d_eq[d_eqBlastIdx].getExpr()));
02303         if(*d_simplifyFlag)
02304           result = iffMP(result, simplify(result.getExpr()));
02305         else if (*d_booleanRWFlag)
02306           result = iffMP(result, rewriteBoolean(result.getExpr()));     
02307         enqueueFact(result);
02308       }
02309       // Only if there are no more equalities, deal with disequalities
02310     } else if(d_diseqIdx<d_diseq.size()) {
02311       // None of the disequalities is violated due to equal find
02312       // pointers, since otherwise TheoryCore would have detected that
02313       // already.  Therefore, we can only hope to simplify the
02314       // expressions.
02315       for(; d_diseqIdx<d_diseq.size(); d_diseqIdx = d_diseqIdx + 1) {
02316         Theorem diseq = d_diseq[d_diseqIdx];
02317         Expr diseqExpr = diseq.getExpr();
02318         const Expr& eqExpr = diseqExpr[0];
02319         const Theorem& thm0 = find(eqExpr[0]);
02320         const Theorem& thm1 = find(eqExpr[1]);
02321         vector<Theorem> thms;
02322         vector<unsigned> changed;
02323         if(thm0.getLHS() != thm0.getRHS()) {
02324           changed.push_back(0);
02325           thms.push_back(thm0);
02326         }
02327         if(thm1.getLHS() != thm1.getRHS()) {
02328           changed.push_back(1);
02329           thms.push_back(thm1);
02330         }
02331         if(changed.size() > 0) {
02332           IF_DEBUG(debugger.counter("bv simplified diseq")++);
02333           Theorem subst = substitutivityRule(eqExpr, changed, thms);
02334           thms.clear();
02335           thms.push_back(subst);
02336           diseq = iffMP(diseq, substitutivityRule(diseqExpr.getOp(), thms));
02337         }
02338         Theorem result = bitBlastDisEqn(diseq);
02339         if(*d_simplifyFlag)
02340           result = iffMP(result, simplify(result.getExpr()));
02341         else if (*d_booleanRWFlag)
02342           result = iffMP(result, rewriteBoolean(result.getExpr()));
02343         enqueueFact(result);
02344       }
02345     } else {
02346       // Finally, if there is nothing else to do, assert all the
02347       // remaining type predicates on the bits, for completeness
02348       for(; d_tccsIdx<d_tccs.size(); d_tccsIdx = d_tccsIdx + 1) {
02349         Theorem tcc(d_tccs[d_tccsIdx]);
02350         tcc = iffMP(tcc, simplify(tcc.getExpr()));
02351         if(!tcc.getExpr().isTrue()) {
02352           IF_DEBUG(debugger.counter("bv enqueue type pred")++);
02353           d_bvTypePreds++;
02354           enqueueFact(d_tccs[d_tccsIdx]);
02355         }
02356       }
02357     }
02358   }
02359 }
02360 
02361 
02362 Theorem TheoryBitvector::rewrite(const Expr& e) {
02363   return rewriteAux(e);
02364 }
02365 
02366 
02367 Theorem TheoryBitvector::rewriteAux(const Expr& e) {
02368   Theorem res;
02369   if(*d_rewriteFlag)
02370     res = rewriteBV(e, true);
02371   else {
02372     res = rewriteConst(e);
02373     IF_DEBUG(if(res.getRHS()!=res.getLHS())
02374              debugger.counter("bv rewrite const")++);
02375     // Ensure that the result is a find pointer of itself (if it has any)
02376     const Expr& rhs = res.getRHS();
02377     if(rhs.hasFind())
02378       res = transitivityRule(res, find(rhs));
02379   }
02380   return res;
02381 }
02382 
02383 Theorem TheoryBitvector::rewriteAtomic(const Expr& e) {
02384   TRACE("bv rewriteatomic", "rewriteAtomic(", e.toString(), ") {"); 
02385   
02386   Theorem res = reflexivityRule(e);
02387   if(*d_cnfBitBlastFlag && res.getRHS().isEq()) {
02388     //res = rewriteAux(e);
02389     res = transitivityRule(res, bitBlastEqn(res.getRHS()));
02390     res = transitivityRule(res, simplify(res.getRHS()));
02391   }
02392   else if(*d_cnfBitBlastFlag && 
02393           (BVLT== res.getRHS().getOpKind() || BVLE==res.getRHS().getOpKind())) {
02394     //res = rewriteAux(e);
02395     res = transitivityRule(res, bitBlastIneqn(res.getRHS()));
02396     res = transitivityRule(res, simplify(res.getRHS()));
02397   }
02398   TRACE("bv rewriteatomic", "rewriteAtomic => ", res.toString(), "}"); 
02399   return res;
02400 }
02401 
02402 // We set up only shared terms
02403 void TheoryBitvector::setup(const Expr& e) {
02404   if(!*d_setupSharedFlag) {
02405     if(e.getOpKind()==CONCAT) {
02406       setupCC(e);
02407     } else {      
02408       for (int k=0, ar=e.arity(); k < ar; ++k) {
02409         // Constants never change
02410         if(e[k].getKind() == BVCONST) continue;
02411         e[k].addToNotify(this, e);
02412         TRACE("bv setup", "e["+int2string(k)+"]="+e[k].toString()+": ",
02413               *(e[k].getNotify()), "");
02414       }
02415     }
02416   }
02417 }
02418 
02419 
02420 void TheoryBitvector::setupExpr(const Expr& e) {
02421   TRACE("bv setup", "setupExpr(", e, ") {");
02422   if(!(*d_setupFlag)) {
02423     TRACE_MSG("bv setup", "setupExpr[-bv-setup] => }");
02424     return;
02425   }
02426   // Process only terms.  If not a term, nothing to do.
02427   if(!e.isTerm()) {
02428     TRACE_MSG("bv setup", "setupExpr[not term] => }");
02429     return;
02430   }
02431   // Do not setup constants
02432   if(e.getKind()==BVCONST) {
02433     TRACE_MSG("bv setup", "setupExpr[const] => }");
02434     return;
02435   }
02436   // Only setup subterms of shared terms
02437 
02438   // First, set up notification for the kids (the usual stuff)
02439   if(*d_setupSharedFlag) {
02440     if(e.getOpKind()==CONCAT)
02441       setupCC(e); 
02442     else {      
02443       for (int k=0, ar=e.arity(); k < ar; ++k) {
02444         // Constants never change
02445         if(e[k].getKind() == BVCONST) continue;
02446         e[k].addToNotify(this, e);
02447         TRACE("bv setup", "e["+int2string(k)+"] = "+e[k].toString()+": ",
02448               *(e[k].getNotify()), "");
02449       }
02450     }
02451   }
02452   // Next, set up additional notifications for individual bits.  Skip
02453   // CONCAT expressions, since the bits of their kids have already
02454   // been setup.
02455   Type tp(getBaseType(e));
02456   if( e.getOpKind() != CONCAT  && 
02457       e.getOpKind() != BVCONST && 
02458       tp.getExpr().getOpKind() == BITVECTOR) {
02459     int size = BVSize(e);
02460     if(size >= 2) {
02461       IF_DEBUG(debugger.counter("setup long bitvectors")++);
02462       // Assert an equality e = e[n-1:n-1]@...@e[0:0] with individual
02463       // bits fully simplified
02464       vector<Expr> kids;
02465       vector<unsigned> changed; // for simplification
02466       vector<Theorem> thms; // simplification of kids
02467       for(int i=size-1; i>=0; i=i-1) {
02468         Expr k = newBVExtractExpr(e, i, i);
02469         Theorem thm = rewriteAux(k);
02470         if(thm.getLHS() != thm.getRHS()) {
02471           changed.push_back(kids.size());
02472           thms.push_back(thm);
02473         }
02474         kids.push_back(k);
02475       }
02476       Expr concat(newConcatExpr(kids));
02477       // Construct a Theorem(concat = e)
02478       Theorem thm = d_rules->concatMergeExtract(concat);
02479       thm = transitivityRule(thm, d_rules->extractWhole(thm.getRHS()));
02480       // If bits simplified, substitute the new bits
02481       if(changed.size() > 0) {
02482         thm = symmetryRule(thm);
02483         Theorem subst = substitutivityRule(thm.getRHS(), changed, thms);
02484         thm = transitivityRule(thm, subst);
02485         thm = symmetryRule(thm);
02486       }
02487       // Get the latest version of the concatenation of bits
02488       concat = thm.getLHS();
02489       // HACK ATTACK: we want 'concat' to be setup the way it is, but
02490       // we cannot use enqueueEquality() [since those are not
02491       // processed at this point] or enqueueFact() [since it will
02492       // simplify the equality to TRUE and ignore it].  Hence, we'll
02493       // do setup here.
02494       //
02495       // It involves: setting find pointers and calling setup() on the
02496       // bits and on the 'concat', unless they already have find
02497       // pointers.
02498       if(!concat.hasFind()) {
02499         theoryCore()->setupTerm(concat, this);
02500         // Set up notification for the bits
02501         if(*d_setupSharedFlag)
02502           setupCC(concat);       
02503         // Set the find pointer properly
02504         // if(concat > e)
02505         concat.setFind(thm);
02506         if(constantKids(concat)) {
02507           thm = symmetryRule(thm);
02508           Theorem t1 = d_rules->concatConst(thm.getRHS());
02509           thm = transitivityRule(thm,t1);
02510           enqueueFact(thm);
02511         }
02512         //else {
02513         //        concat.setFind(reflexivityRule(concat));
02514         //        e.setFind(symmetryRule(thm));
02515         //      }
02516       } 
02517       else 
02518         // Both e and concat have find pointers.  Just enqueue the equality.
02519         enqueueFact(thm);       
02520     }
02521   }
02522   TRACE_MSG("bv setup", "setupExpr => }");
02523 }
02524 
02525 
02526 void TheoryBitvector::update(const Theorem& e, const Expr& d) {
02527   // Constants should never change their find pointers to non-constant
02528   // expressions
02529   DebugAssert(e.getLHS().getOpKind()!=BVCONST || e.getRHS().getKind()==BVCONST,
02530               "TheoryBitvector::update(e="+e.getExpr().toString()
02531               +", d="+d.toString());
02532   if(!(*d_updateFlag)) return;
02533 
02534   IF_DEBUG(debugger.counter("bv update total")++);
02535   IF_DEBUG(if(d_sharedSubterms.count(d) > 0)
02536            debugger.counter("bv update shared")++);
02537   // Catch CONCAT updates: those are done using congruence closure
02538   if(d.getOpKind()==CONCAT) {
02539     updateCC(e, d);
02540     Theorem thm1 = updateHelper(d);
02541     if(constantKids(thm1.getRHS())){
02542       Theorem t1 = d_rules->concatConst(thm1.getRHS());
02543       t1 = transitivityRule(thm1,t1);
02544       Theorem t2 = find(d);
02545       t2 = symmetryRule(t2);
02546       t1 = transitivityRule(t2,t1);
02547       enqueueEquality(t1);
02548       //enqueueFact(t1);
02549     } 
02550     return;
02551   }
02552   Theorem thm = updateHelper(d);  // |- d = d'
02553   DebugAssert(thm.getRHS() != d,
02554               "TheoryBitvector::update(e,d):\n thm = "+thm.toString());
02555   // If find(d) == d, enqueue thm as a new equality directly.
02556   // Otherwise, enqueue thm as a fact (postpone its processing, and
02557   // process it later sequentially).  This is needed to guarantee the
02558   // internal invariants of assertEqualities().
02559   DebugAssert(d.hasFind(), "TheoryBitvector::update: d = "+d.toString());
02560   if(d.getFind().getRHS() == d) {
02561   // Rewrite the RHS to keep it fully simplified
02562     thm = transitivityRule(thm, rewriteAux(thm.getRHS()));
02563     TRACE("bv update", "TheoryBitvector::update[find(d)==d]: thm = ",
02564           thm.getExpr(), "");
02565     const Expr& rhs = thm.getRHS();
02566     if(d != rhs) {
02567       DebugAssert(find(rhs).getRHS() == rhs,
02568                   "TheoryBitvector::update(e,d):\n thm = "+thm.toString()
02569                   +"\n find(rhs) = "
02570                   +find(rhs).getRHS().toString()
02571                   +"\n e = "+e.getExpr().toString()
02572                   +"\n d = "+d.toString());
02573       // It may happen that in the same batch of equalities a
02574       // non-canonical d will simplify to the same rhs, in which case
02575       // we want to enqueue it as a fact rather than setting it up and
02576       // not reporting to the core.  To detect this situation, we
02577       // setup rhs immediately.
02578       if(!rhs.hasFind()) theoryCore()->setupTerm(rhs, this);
02579       enqueueEquality(thm);
02580       IF_DEBUG(debugger.counter("bv update equality")++);
02581     }
02582   } else if(d_staleDB.count(d) == 0) {
02583     if(constantKids(thm.getRHS()))
02584       thm = transitivityRule(thm, rewriteAux(thm.getRHS()));
02585     const Expr& rhs = thm.getRHS();
02586     TRACE("bv update", "TheoryBitvector::update[not stale]: thm = ",
02587           thm.getExpr(), "");
02588     if(rhs.hasFind() || rhs.getKind() == BVCONST) {
02589       IF_DEBUG(debugger.counter("bv update fact")++);
02590       enqueueFact(thm);
02591     } else {
02592       // Do not enqueue fact; instead, setup and assign the find
02593       // pointer "manually"
02594       Theorem rhsFindThm(transitivityRule(symmetryRule(thm), find(d)));
02595       TRACE("bv update", "TheoryBitvector::update[setup]:\n rhs find thm = ",
02596             rhsFindThm.getExpr(), "");
02597       IF_DEBUG(debugger.counter("bv update setup")++);
02598       theoryCore()->setupTerm(rhs, this);
02599       rhs.setFind(rhsFindThm);
02600     }
02601     d_staleDB[d] = true;
02602   } else {
02603     TRACE("bv update", "TheoryBitvector::update[stale] d = ", d, "");
02604     IF_DEBUG(debugger.counter("bv update stale")++);
02605   }
02606 }
02607 
02608 
02609 Theorem TheoryBitvector::solve(const Theorem& e)
02610 {
02611   const Expr& lhs = e.getLHS();
02612   const Expr& rhs = e.getRHS();
02613   bool constLHS(lhs.getKind()==BVCONST);
02614   bool constRHS(rhs.getKind()==BVCONST);
02615   if(lhs != rhs) {
02616     if(constLHS && constRHS)
02617       return iffMP(e, d_rules->eqConst(e.getExpr()));
02618     else if(constLHS) // Put a constant on the RHS
02619       return symmetryRule(e);
02620   }
02621   // Otherwise don't do anything
02622   return e;
02623 }
02624 
02625 
02626 void TheoryBitvector::checkType(const Expr& e)
02627 {
02628   switch (e.getOpKind()) {
02629     case BITVECTOR: 
02630       //TODO: check that this is a well-formed type
02631       break;
02632     default:
02633       DebugAssert(false, "Unexpected kind in TheoryBitvector::checkType"
02634                   +getEM()->getKindName(e.getOpKind()));
02635   }
02636 }
02637 
02638 
02639 void TheoryBitvector::computeType(const Expr& e)
02640 {
02641   TRACE("bitvector", "TheoryBitvector::computeType(", e.toString(), ") {"); 
02642   switch(e.getOpKind()) {
02643   case BOOLEXTRACT: {
02644     if(!(1 == e.arity() &&
02645          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
02646       throw TypecheckException("Type Checking error:"\
02647                                "attempted extraction from non-bitvector \n"+ 
02648                                e.toString());
02649     int extractLength = getBoolExtractIndex(e);
02650     if(!(0 <= extractLength))
02651       throw TypecheckException("Type Checking error: \n"
02652                                "attempted out of range extraction  \n"+ 
02653                                e.toString());
02654     e.setType(boolType());
02655   }
02656     break;
02657   case BVCONST: {
02658     Type bvType = newBitvectorType(getBVConstSize(e));
02659     e.setType(bvType);
02660   }
02661     break;
02662   case CONCAT: {
02663     if(e.arity() < 2) 
02664       throw TypecheckException
02665         ("Concatenation must have at least 2 bit-vectors:\n\n  "+e.toString());
02666 
02667     // Compute the total length of concatenation
02668     int bvLength(0);
02669     for(int i=0, iend=e.arity(); i<iend; ++i) {
02670       if(BITVECTOR != getBaseType(e[i]).getExpr().getOpKind())
02671         throw TypecheckException
02672           ("Not a bit-vector expression (child #"+int2string(i+1)
02673            +") in concatenation:\n\n  "+e[i].toString()
02674            +"\n\nIn the expression:\n\n  "+e.toString());
02675       bvLength += BVSize(e[i]);
02676     }
02677     Type bvType = newBitvectorType(bvLength);
02678     e.setType(bvType);
02679     break;
02680   }
02681    case BVMULT:{
02682     if(!(2 == e.arity() &&
02683          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() &&
02684          BITVECTOR == getBaseType(e[1]).getExpr().getOpKind()))
02685       throw TypecheckException
02686         ("Not a bit-vector expression in BVMULT:\n\n  "
02687          +e.toString());
02688     int bvLen = getBVMultParam(e);
02689     Type bvType = newBitvectorType(bvLen);
02690     e.setType(bvType);
02691   }
02692     break;
02693   case BVUMINUS:{
02694     Type bvType(getBaseType(e[0]));
02695     if(!(1 == e.arity() &&
02696          BITVECTOR == bvType.getExpr().getOpKind()))
02697       throw TypecheckException
02698         ("Not a bit-vector expression in BVUMINUS:\n\n  "
02699          +e.toString());
02700     e.setType(bvType);
02701   }
02702     break;
02703   case EXTRACT:{
02704     if(!(1 == e.arity() && 
02705          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
02706       throw TypecheckException
02707         ("Not a bit-vector expression in bit-vector extraction:\n\n  "
02708          + e.toString());
02709     int bvLength = BVSize(e[0]);
02710     int leftExtract = getExtractHi(e);
02711     int rightExtract = getExtractLow(e);
02712     if(!(0 <= rightExtract && 
02713          rightExtract <= leftExtract && leftExtract < bvLength))
02714       throw TypecheckException
02715         ("Wrong bounds in bit-vector extract:\n\n  "+e.toString());
02716     int extractLength = leftExtract - rightExtract + 1;
02717     Type bvType = newBitvectorType(extractLength);
02718     e.setType(bvType);
02719     break;
02720   }
02721   case BVNEG:{
02722     if(!(1 == e.arity() && 
02723          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
02724       throw TypecheckException
02725         ("Not a bit-vector expression in bit-wise negation:\n\n  "
02726          + e.toString());
02727     e.setType(e[0].getType());
02728     break; 
02729   }
02730   case BVAND:
02731   case BVOR: {
02732     string kindStr((e.getOpKind()==BVAND)? "AND" : "OR");
02733     if(e.arity() < 2) 
02734       throw TypecheckException
02735         ("Bit-wise "+kindStr+" must have at least 2 bit-vectors:\n\n  "
02736          +e.toString());
02737 
02738     int bvLength(0);
02739     bool first(true);
02740     for(int i=0, iend=e.arity(); i<iend; ++i) {
02741       if(BITVECTOR != getBaseType(e[i]).getExpr().getOpKind())
02742         throw TypecheckException
02743           ("Not a bit-vector expression (child #"+int2string(i+1)
02744            +") in bit-wise "+kindStr+":\n\n  "+e[i].toString()
02745            +"\n\nIn the expression:\n\n  "+e.toString());
02746       if(first) {
02747         bvLength = BVSize(e[i]);
02748         first=false;
02749       } else { // Check that the size is the same for all subsequent BVs
02750         if(BVSize(e[i]) != bvLength)
02751           throw TypecheckException
02752             ("Mismatched bit-vector size in bit-wise "+kindStr+" (child #"
02753              +int2string(i)+").\nExpected type: "
02754              +newBitvectorType(bvLength).toString()
02755              +"\nFound: "+e[i].getType().toString()
02756              +"\nIn the following expression:\n\n  "+e.toString());
02757       }
02758     }
02759     e.setType(newBitvectorType(bvLength));
02760     break; 
02761   }
02762   case BVPLUS: {
02763     int bvPlusLength = getBVPlusParam(e);
02764     if(!(0 <= bvPlusLength))
02765       throw TypecheckException
02766         ("Bad bit-vector length specified in BVPLUS expression:\n\n  "
02767          + e.toString());
02768     for(Expr::iterator i=e.begin(), iend=e.end(); i != iend; ++i) {
02769       if(BITVECTOR != getBaseType(*i).getExpr().getOpKind())
02770         throw TypecheckException
02771           ("Not a bit-vector expression in BVPLUS:\n\n  "+e.toString());
02772     }
02773     Type bvType = newBitvectorType(bvPlusLength);
02774     e.setType(bvType);
02775     break;
02776   }
02777   case LEFTSHIFT: {
02778     if(!(1 == e.arity() && 
02779          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
02780       throw TypecheckException
02781         ("Not a bit-vector expression in bit-vector shift:\n\n  "
02782          +e.toString());
02783     int bvLength = BVSize(e[0]);
02784     int shiftLength = getFixedLeftShiftParam(e);
02785     if(!(shiftLength >= 0))
02786       throw TypecheckException("Bad shift value in bit-vector shift:\n\n  "
02787                                +e.toString());
02788     int newLength = bvLength + shiftLength;
02789     Type bvType = newBitvectorType(newLength);
02790     e.setType(bvType);
02791   }
02792     break;
02793   case RIGHTSHIFT: {
02794     if(!(1 == e.arity() && 
02795          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
02796       throw TypecheckException
02797         ("Not a bit-vector expression in bit-vector shift:\n\n  "
02798          +e.toString());
02799     int bvLength = BVSize(e[0]);
02800     int shiftLength = getFixedRightShiftParam(e);
02801     if(!(shiftLength >= 0))
02802       throw TypecheckException("Bad shift value in bit-vector shift:\n\n  "
02803                                +e.toString());
02804     //int newLength = bvLength + shiftLength;
02805     Type bvType = newBitvectorType(bvLength);
02806     e.setType(bvType);
02807   }
02808     break;
02809   case BVTYPEPRED:    
02810     e.setType(boolType());
02811     break;
02812   case SX: {
02813     if(!(1 == e.arity() &&
02814          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
02815       throw TypecheckException("Type Checking error:"\
02816                                "non-bitvector \n"+ e.toString());
02817     int bvLength = getSXIndex(e);
02818     if(!(0 <= bvLength))
02819       throw TypecheckException("Type Checking error: \n"
02820                                "out of range\n"+ e.toString());
02821     Type bvType = newBitvectorType(bvLength);
02822     e.setType(bvType);
02823     break;
02824   }
02825   case SBVLT:
02826   case SBVLE:
02827   case BVLT:
02828   case BVLE:
02829     if(!(2 == e.arity() &&
02830          BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() &&
02831          BITVECTOR == getBaseType(e[1]).getExpr().getOpKind()))
02832       throw TypecheckException
02833         ("BVLT/BVLE expressions must have arity=2, and"
02834          "each subterm must be a bitvector term:\n"
02835          "e = " +e.toString());
02836     e.setType(boolType());
02837     break;
02838   default:
02839     DebugAssert(false,
02840                 "TheoryBitvector::computeType: wrong input" +
02841                 int2string(e.getOpKind()));
02842     break;
02843   }
02844   TRACE("bitvector", "TheoryBitvector::computeType => ", e.getType(), " }"); 
02845 }
02846 
02847 
02848 void TheoryBitvector::computeModelTerm(const Expr& e, std::vector<Expr>& v) {
02849   switch(e.getOpKind()) {
02850   case BVPLUS:
02851   case BVSUB:
02852   case BVUMINUS:
02853   case BVMULT:
02854   case LEFTSHIFT:
02855   case RIGHTSHIFT:
02856   case BVOR:
02857   case BVAND:
02858   case BVXOR:
02859   case BVXNOR:
02860   case BVNAND:
02861   case BVNOR:
02862   case BVNEG:
02863   case VARSHIFT:
02864   case CONCAT:
02865   case EXTRACT:
02866   case SBVLT:
02867   case SBVLE:
02868   case SBVGT:
02869   case SBVGE:
02870   case BVLT:
02871   case BVLE:
02872   case BVGT:
02873   case BVGE:
02874   case INTTOBV:
02875   case BVTOINT:
02876     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
02877       // getModelTerm(*i, v);
02878       v.push_back(*i);
02879     return;
02880   case HEXBVCONST:
02881   case BVCONST: // No model variables here
02882     return;
02883   default: break; // It's a variable; continue processing
02884   }
02885   
02886   Type tp(e.getType());
02887   switch(tp.getExpr().getOpKind()) {
02888   case BITVECTOR: {
02889     int n = getBitvectorTypeParam(tp);
02890     for(int i=0; i<n; i = i+1)
02891       v.push_back(newBoolExtractExpr(e, i));
02892     break;
02893   }
02894   default:
02895     v.push_back(e);
02896   }
02897 }
02898 
02899 
02900 void TheoryBitvector::computeModel(const Expr& e, std::vector<Expr>& v) {
02901   switch(e.getOpKind()) {
02902   case BVPLUS:
02903   case BVSUB:
02904   case BVUMINUS:
02905   case BVMULT:
02906   case LEFTSHIFT:
02907   case RIGHTSHIFT:
02908   case BVOR:
02909   case BVAND:
02910   case BVXOR:
02911   case BVXNOR:
02912   case BVNAND:
02913   case BVNOR:
02914   case BVNEG:
02915   case VARSHIFT:
02916   case CONCAT:
02917   case EXTRACT:
02918   case SX:
02919   case SBVLT:
02920   case SBVLE:
02921   case SBVGT:
02922   case SBVGE:
02923   case BVLT:
02924   case BVLE:
02925   case BVGT:
02926   case BVGE:
02927   case INTTOBV:
02928   case BVTOINT: {
02929     // More primitive vars are kids, and they should have been
02930     // assigned concrete values
02931     assignValue(simplify(e));
02932     v.push_back(e);
02933     return;
02934   }
02935   case HEXBVCONST:
02936   case BVCONST: // No model variables here
02937     return;
02938   default: break; // It's a variable; continue processing
02939   }
02940   
02941   Type tp(e.getType());
02942   switch(tp.getExpr().getOpKind()) {
02943   case BITVECTOR: {
02944     const Rational& n = getBitvectorTypeParam(tp);
02945     vector<bool> bits;
02946     // FIXME: generate concrete assignment from bits using proof
02947     // rules. For now, just create a new assignment.
02948     for(int i=0; i<n; i++) {
02949       Theorem val(getModelValue(newBoolExtractExpr(e, i)));
02950       DebugAssert(val.getRHS().isBoolConst(), 
02951                   "TheoryBitvector::computeModel: unassigned bit: "
02952                   +val.getExpr().toString());
02953       bits.push_back(val.getRHS().isTrue());
02954     }
02955     Expr c(newBVConstExpr(bits));
02956     assignValue(e, c);
02957     v.push_back(e);
02958     break;
02959   }
02960   default:
02961     DebugAssert(false, "TheoryBitvector::computeModel[not BITVECTOR type]("
02962                 +e.toString()+")");
02963   }
02964 }
02965 
02966 
02967 Expr
02968 TheoryBitvector::computeTypePred(const Type& t, const Expr& e) {
02969   DebugAssert(t.getExpr().getOpKind() == BITVECTOR,
02970               "TheoryBitvector::computeTypePred: t = "+t.toString());
02971 //   switch(e.getKind()) {
02972 //   case BVCONST:
02973 //     return getEM()->trueExpr();
02974 //   default:
02975     return newBitvectorTypePred(t, e);
02976     //  }
02977 }
02978 
02979 
02980 Expr
02981 TheoryBitvector::computeTCC(const Expr& e) {
02982   Expr tcc(Theory::computeTCC(e));
02983   switch(e.getOpKind()) {
02984   default:
02985     return tcc;
02986   }
02987 }
02988 
02989 ///////////////////////////////////////////////////////////////////////////////
02990 // Pretty-printing                                                           //
02991 ///////////////////////////////////////////////////////////////////////////////
02992 
02993 ExprStream&
02994 TheoryBitvector::print(ExprStream& os, const Expr& e) {
02995   switch(os.lang()) {
02996   case PRESENTATION_LANG:
02997     switch(e.getOpKind()) {
02998     case BVCONST: {
02999       std::ostringstream ss;
03000       ss << "0bin";
03001       for(int i=(int)getBVConstSize(e)-1; i>=0; --i)
03002         ss << (getBVConstValue(e, i) ? "1" : "0");
03003       os << ss.str();
03004       break;
03005     }
03006     case CONCAT:
03007       if(e.arity() <= 1) e.printAST(os);
03008       else {
03009         os << "(" << push;
03010         bool first(true);
03011         for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03012           if(first) first=false;
03013           else os << space << "@" << space;
03014           os << (*i);
03015         }
03016         os << push << ")";
03017       }
03018       break;
03019     case BVUMINUS:
03020       os << "BVUMINUS(" << push << e[0] << push << ")";
03021       break;
03022     case BVSUB:
03023       break;
03024     case BVMULT:
03025       os << "BVMULT(" << push
03026          << getBVMultParam(e) << "," << e[0] << "," << e[1]<<push<<")"; 
03027       break;
03028     case BVAND:
03029       if(e.arity() <= 1) e.printAST(os);
03030       else {
03031         os << "(" << push;
03032         bool first(true);
03033         for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03034           if(first) first=false;
03035           else os << space << "&" << space;
03036           os << (*i);
03037         }
03038         os << push << ")";
03039       }
03040       break;
03041     case BVOR:
03042       if(e.arity() <= 1) e.printAST(os);
03043       else {
03044         os << "(" << push;
03045         bool first(true);
03046         for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03047           if(first) first=false;
03048           else os << space << "|" << space;
03049           os << (*i);
03050         }
03051         os << push << ")";
03052       }
03053       break;
03054     case BVNEG:
03055       os << "(~(" << push << e[0] << push << "))";
03056       break;
03057     case BVLT:
03058       os << "BVLT(" << push << e[0] << "," << e[1] << push << ")";
03059       break;
03060     case BVLE:
03061       os << "BVLE(" << push << e[0] << "," << e[1] << push << ")";
03062       break;
03063     case SBVLT:
03064       os << "SBVLT(" << push << e[0] << "," << e[1] << push << ")";
03065       break;
03066     case SBVLE:
03067       os << "SBVLE(" << push << e[0] << "," << e[1] << push << ")";
03068       break;
03069     case EXTRACT:
03070       os << "(" << push << e[0] << push << ")" << pop << pop
03071          << "[" << push << getExtractHi(e) << ":";
03072       os << getExtractLow(e) << push << "]";
03073       break;
03074     case BOOLEXTRACT:
03075       os << "BOOLEXTRACT(" << push  << e[0] << "," 
03076          << getBoolExtractIndex(e) << push << ")";
03077       break;
03078     case SX:
03079       os << "SX(" << push  << e[0] << "," 
03080          << push <<  getSXIndex(e) << ")";
03081       break;
03082     case LEFTSHIFT:
03083       os <<  "(" << push << e[0] << space << "<<" << space
03084          << getFixedLeftShiftParam(e) << push << ")";
03085       break;
03086     case RIGHTSHIFT:
03087       os <<  "(" << push << e[0] << space << ">>" << space
03088          << getFixedRightShiftParam(e) << push << ")";
03089       break;
03090     case BITVECTOR: //printing type expression
03091       os << "BITVECTOR(" << push
03092          << getBitvectorTypeParam(e) << push << ")";
03093       break;
03094     case INTTOBV:
03095       break;
03096     case BVTOINT:
03097       break;
03098     case BVPLUS:
03099       os << "BVPLUS(" << push << getBVPlusParam(e);
03100       for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03101         os << push << "," << pop << space << (*i);
03102       }
03103       os << push << ")";
03104       break;
03105     case BVTYPEPRED:
03106       if(e.isApply()) {
03107         os << "BVTYPEPRED[" << push << e.getOp().getExpr()
03108            << push << "," << pop << space << e[0]
03109            << push << "]";
03110       } else
03111         e.printAST(os);
03112       break;
03113     default:
03114       e.printAST(os);
03115       break;
03116     }
03117     break;
03118   case SMTLIB_LANG:
03119     d_theoryUsed = true;
03120     throw SmtlibException("TheoryBitvector::print: SMTLIB not supported");
03121     break;
03122   default:
03123     switch(e.getOpKind()) {
03124     case BVCONST: {
03125       os << "0bin";
03126       for(int i=(int)getBVConstSize(e)-1; i>=0; --i)
03127         os << (getBVConstValue(e, i) ? "1" : "0");
03128       break;
03129     }
03130     default:
03131       e.printAST(os);
03132       break;
03133     }
03134   }
03135   return os;
03136 }
03137 
03138 
03139 ///////////////////////////////////////////////////////////////////////////////
03140 //parseExprOp:
03141 //translating special Exprs to regular EXPR??
03142 ///////////////////////////////////////////////////////////////////////////////
03143 Expr
03144 TheoryBitvector::parseExprOp(const Expr& e) {
03145   TRACE("parser", "TheoryBitvector::parseExprOp(", e, ")");
03146   
03147   // If the expression is not a list, it must have been already
03148   // parsed, so just return it as is.
03149   if(RAW_LIST != e.getKind()) return e;
03150 
03151   if(!(e.arity() > 0))      
03152     throw ParserException("TheoryBitvector::parseExprOp: wrong input:\n\n"
03153                           +e.toString());
03154   
03155   const Expr& c1 = e[0][0];
03156   int kind = getEM()->getKind(c1.getString());
03157   switch(kind) {
03158   case BITVECTOR:
03159     if(!(e.arity() == 2))
03160       throw ParserException("TheoryBitvector::parseExprOp: BITVECTOR" 
03161                             "kind should have exactly 1 arg:\n\n" 
03162                             + e.toString());    
03163     if(!(e[1].isRational() && e[1].getRational().isInteger()))
03164       throw ParserException("BITVECTOR TYPE must have an integer constant" 
03165                             "as its first argument:\n\n"
03166                             +e.toString());    
03167     if(!(e[1].getRational().getInt() >=0 ))
03168       throw ParserException("parameter must be an integer constant >= 0.\n"
03169                             +e.toString());    
03170     return newBitvectorTypeExpr(e[1].getRational().getInt());
03171     break;
03172   case CONCAT: {
03173     if(!(e.arity() >= 3))
03174       throw ParserException("TheoryBitvector::parseExprOp: CONCAT" 
03175                             "kind should have at least 2 args:\n\n" 
03176                             + e.toString());
03177     vector<Expr> kids;
03178     Expr::iterator i=e.begin(), iend=e.end();
03179     DebugAssert(i!=iend, "TheoryBitvector::parseExprOp("+e.toString()+")");
03180     ++i; // Skip the first element - the operator name
03181     for(; i!=iend; ++i)
03182       kids.push_back(parseExpr(*i));
03183     return newConcatExpr(kids);
03184     break;
03185   }
03186   case BVAND: {
03187     if(!(e.arity() >= 3))
03188       throw ParserException("TheoryBitvector::parseExprOp: BVAND " 
03189                             "kind should have at least 2 arg:\n\n" 
03190                             + e.toString());
03191     vector<Expr> kids;
03192     for(int i=1, iend=e.arity(); i<iend; ++i)
03193       kids.push_back(parseExpr(e[i]));
03194     return newBVAndExpr(kids);
03195     break;
03196   }
03197   case BVOR: {
03198     if(!(e.arity() >= 3))
03199       throw ParserException("TheoryBitvector::parseExprOp: BVOR " 
03200                             "kind should have at least 2 arg:\n\n" 
03201                             + e.toString());
03202     vector<Expr> kids;
03203     for(int i=1, iend=e.arity(); i<iend; ++i)
03204       kids.push_back(parseExpr(e[i]));
03205     return newBVOrExpr(kids);
03206     break;
03207   }
03208   case BVXOR: {
03209     if(!(e.arity() == 3))
03210       throw ParserException("TheoryBitvector::parseExprOp: BVXOR " 
03211                             "kind should have exactly 2 arg:\n\n" 
03212                             + e.toString());
03213 //     Expr e1 = parseExpr(e[1]);
03214 //     Expr e2 = parseExpr(e[2]);
03215 //     return newBVXorExpr(e1,e2);
03216     Expr or1 = 
03217       newBVAndExpr(newBVNegExpr(parseExpr(e[1])), parseExpr(e[2]));
03218     or1 = rewriteBV(or1,3).getRHS();
03219     Expr or2 = 
03220       newBVAndExpr(parseExpr(e[1]), newBVNegExpr(parseExpr(e[2])));
03221     or2 = rewriteBV(or2,3).getRHS();
03222     return rewrite(newBVOrExpr(or1, or2)).getRHS();
03223     break;
03224   }
03225   case BVXNOR: {
03226     if(!(e.arity() == 3))
03227       throw ParserException("TheoryBitvector::parseExprOp: BVXNOR" 
03228                             "kind should have exactly 2 arg:\n\n" 
03229                             + e.toString());    
03230 //     Expr e1 = parseExpr(e[1]);
03231 //     Expr e2 = parseExpr(e[2]);
03232 //     return newBVXorExpr(e1,e2).notExpr();
03233     Expr or1 = 
03234       newBVAndExpr(newBVNegExpr(parseExpr(e[1])), 
03235                    newBVNegExpr(parseExpr(e[2])));
03236     Expr or2 = newBVAndExpr(parseExpr(e[1]), parseExpr(e[2]));
03237     return newBVOrExpr(or1, or2);
03238     break;
03239   }
03240   case BVNAND:
03241     if(!(e.arity() == 3))
03242       throw ParserException("TheoryBitvector::parseExprOp: BVNAND" 
03243                             "kind should have exactly 2 arg:\n\n" 
03244                             + e.toString());    
03245     return newBVNegExpr(newBVAndExpr(parseExpr(e[1]),parseExpr(e[2])));
03246     break;
03247   case BVNOR:
03248     if(!(e.arity() == 3))
03249       throw ParserException("TheoryBitvector::parseExprOp: BVNOR" 
03250                             "kind should have exactly 2 arg:\n\n" 
03251                             + e.toString());
03252     return newBVNegExpr(newBVOrExpr(parseExpr(e[1]),parseExpr(e[2])));    
03253     break;
03254   case BVLT:
03255     if(!(e.arity() == 3))
03256       throw ParserException("TheoryBitvector::parseExprOp: BVLT" 
03257                             "kind should have exactly 2 arg:\n\n" 
03258                             + e.toString());
03259     return newBVLTExpr(parseExpr(e[1]),parseExpr(e[2]));    
03260     break;
03261   case BVLE:
03262     if(!(e.arity() == 3))
03263       throw ParserException("TheoryBitvector::parseExprOp: BVLE" 
03264                             "kind should have exactly 2 arg:\n\n" 
03265                             + e.toString());
03266     return newBVLEExpr(parseExpr(e[1]),parseExpr(e[2]));    
03267     break;
03268   case BVGT:
03269     if(!(e.arity() == 3))
03270       throw ParserException("TheoryBitvector::parseExprOp: BVGT" 
03271                             "kind should have exactly 2 arg:\n\n" 
03272                             + e.toString());
03273     return newBVLTExpr(parseExpr(e[2]),parseExpr(e[1]));    
03274     break;
03275   case BVGE:
03276     if(!(e.arity() == 3))
03277       throw ParserException("TheoryBitvector::parseExprOp: BVGE" 
03278                             "kind should have exactly 2 arg:\n\n" 
03279                             + e.toString());
03280     return newBVLEExpr(parseExpr(e[2]),parseExpr(e[1]));    
03281     break;
03282   case SX:
03283     if(!(e.arity() == 3))
03284       throw ParserException("TheoryBitvector::parseExprOp: SX" 
03285                             "kind should have exactly 2 arg:\n\n" 
03286                             + e.toString());    
03287     if(!e[2].isRational() || !e[2].getRational().isInteger())
03288       throw ParserException("SX must have an integer constant as its"
03289                             " 2nd argument:\n\n"
03290                             +e.toString());    
03291     if(!(e[2].getRational().getInt() >=0 ))
03292       throw ParserException("SX must have an integer constant as its"
03293                             " 2nd argument >= 0:\n\n"
03294                             +e.toString());    
03295     return newSXExpr(parseExpr(e[1]), e[2].getRational().getInt());
03296     break;
03297   case SBVLT:
03298     if(!(e.arity() == 3))
03299       throw ParserException("TheoryBitvector::parseExprOp: BVLT" 
03300                             "kind should have exactly 2 arg:\n\n" 
03301                             + e.toString());
03302     return newSBVLTExpr(parseExpr(e[1]),parseExpr(e[2]));    
03303     break;
03304   case SBVLE:
03305     if(!(e.arity() == 3))
03306       throw ParserException("TheoryBitvector::parseExprOp: BVLE" 
03307                             "kind should have exactly 2 arg:\n\n" 
03308                             + e.toString());
03309     return newSBVLEExpr(parseExpr(e[1]),parseExpr(e[2]));    
03310     break;
03311   case SBVGT:
03312     if(!(e.arity() == 3))
03313       throw ParserException("TheoryBitvector::parseExprOp: BVGT" 
03314                             "kind should have exactly 2 arg:\n\n" 
03315                             + e.toString());
03316     return newSBVLTExpr(parseExpr(e[2]),parseExpr(e[1]));    
03317     break;
03318   case SBVGE:
03319     if(!(e.arity() == 3))
03320       throw ParserException("TheoryBitvector::parseExprOp: BVGE" 
03321                             "kind should have exactly 2 arg:\n\n" 
03322                             + e.toString());
03323     return newSBVLEExpr(parseExpr(e[2]),parseExpr(e[1]));    
03324     break;
03325   case BVNEG:
03326     if(!(e.arity() == 2))
03327       throw ParserException("TheoryBitvector::parseExprOp: BVNEG" 
03328                             "kind should have exactly 1 arg:\n\n" 
03329                             + e.toString());    
03330     return newBVNegExpr(parseExpr(e[1]));
03331     break;
03332   case BVCONST:
03333     if(!(e.arity() == 2 || e.arity() == 3))
03334       throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
03335                             "kind should have 1 or 2 args:\n\n"
03336                             + e.toString());
03337     if(!(e[1].isRational() || e[1].isString()))
03338       throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
03339                             "kind should have arg of type Rational "
03340                             "or String:\n\n" + e.toString());
03341     if(e[1].isRational()) { // ("BVCONST" value [bitwidth])
03342       if(e.arity()==3) {
03343         if(!e[2].isRational() || !e[2].getRational().isInteger())
03344           throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
03345                                 "2nd argument must be an integer:\n\n"
03346                                 +e.toString());
03347         return newBVConstExpr(e[1].getRational(), e[2].getRational().getInt());
03348       } else
03349         return newBVConstExpr(e[1].getRational());
03350     } else if(e[1].isString()) { // ("BVCONST" string [base])
03351       if(e.arity() == 3) {
03352         if(!e[2].isRational() || !e[2].getRational().isInteger())
03353           throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
03354                                 "2nd argument must be an integer:\n\n"
03355                                 +e.toString());
03356         return newBVConstExpr(e[1].getString(), e[2].getRational().getInt());
03357       } else
03358         return newBVConstExpr(e[1].getString());
03359     }
03360     break;
03361   case HEXBVCONST:
03362     if(!(e.arity() == 2))
03363       throw ParserException("TheoryBitvector::parseExprOp: BVCONST" 
03364                             "kind should have exactly 1 arg:\n\n" 
03365                             + e.toString());    
03366     if(!(e[1].isRational() || e[1].isString()))
03367       throw ParserException("TheoryBitvector::parseExprOp: BVCONST" 
03368                             "kind should have arg of type Rational" 
03369                             "or String:\n\n" + e.toString());    
03370     if(e[1].isRational()) 
03371       return newBVConstExpr(e[1].getRational());
03372     if(e[1].isString())
03373       return newBVConstExpr(e[1].getString(),16);
03374     break;
03375   case LEFTSHIFT:
03376     if(!(e.arity() == 3))
03377       throw ParserException("TheoryBitvector::parseExprOp: LEFTSHIFT" 
03378                             "kind should have exactly 2 arg:\n\n" 
03379                             + e.toString());    
03380     if(!e[2].isRational() || !e[2].getRational().isInteger())
03381       throw ParserException("LEFTSHIFT must have an integer constant as its "
03382                             "2nd argument:\n\n"
03383                             +e.toString());    
03384     if(!(e[2].getRational().getInt() >=0 ))
03385       throw ParserException("parameter must be an integer constant >= 0.\n"
03386                             +e.toString());    
03387     return newFixedLeftShiftExpr(parseExpr(e[1]), e[2].getRational().getInt());
03388     break;
03389   case RIGHTSHIFT:
03390     if(!(e.arity() == 3))
03391       throw ParserException("TheoryBitvector::parseExprOp: RIGHTSHIFT" 
03392                             "kind should have exactly 2 arg:\n\n" 
03393                             + e.toString());    
03394     if(!e[2].isRational() || !e[2].getRational().isInteger())
03395       throw ParserException("RIGHTSHIFT must have an integer constant as its "
03396                             "2nd argument:\n\n"
03397                             +e.toString());    
03398     if(!(e[2].getRational().getInt() >=0 ))
03399       throw ParserException("parameter must be an integer constant >= 0.\n"
03400                             +e.toString());    
03401     return newFixedRightShiftExpr(parseExpr(e[1]), e[2].getRational().getInt());
03402     break;
03403   case BOOLEXTRACT:
03404     if(!(e.arity() == 3))
03405       throw ParserException("TheoryBitvector::parseExprOp: BOOLEXTRACT" 
03406                             "kind should have exactly 2 arg:\n\n" 
03407                             + e.toString());    
03408     if(!e[2].isRational() || !e[2].getRational().isInteger())
03409       throw ParserException("BOOLEXTRACT must have an integer constant as its"
03410                             " 2nd argument:\n\n"
03411                             +e.toString());    
03412     if(!(e[2].getRational().getInt() >=0 ))
03413       throw ParserException("parameter must be an integer constant >= 0.\n"
03414                             +e.toString());    
03415     return newBoolExtractExpr(parseExpr(e[1]), e[2].getRational().getInt());
03416     break;
03417   case EXTRACT:
03418     if(!(e.arity() == 4))
03419       throw ParserException("TheoryBitvector::parseExprOp: EXTRACT" 
03420                             "kind should have exactly 3 arg:\n\n" 
03421                             + e.toString());    
03422     if(!e[2].isRational() || !e[2].getRational().isInteger())
03423       throw ParserException("EXTRACT must have an integer constant as its "
03424                             "2nd argument:\n\n"
03425                             +e.toString());    
03426     if(!e[3].isRational() || !e[3].getRational().isInteger())
03427       throw ParserException("EXTRACT must have an integer constant as its "
03428                             "3nd argument:\n\n"
03429                             +e.toString());    
03430     if(!(e[2].getRational().getInt() >=0 && e[3].getRational().getInt() >=0))
03431       throw ParserException("parameter must be an integer constant >= 0.\n"
03432                             +e.toString());    
03433     return newBVExtractExpr(parseExpr(e[1]), 
03434                             e[2].getRational().getInt(), 
03435                             e[3].getRational().getInt());
03436     break;
03437   case BVSUB: {
03438     if(e.arity() != 4)
03439       throw ParserException("BVSUB must have 3 arguments:\n\n"
03440                             +e.toString());
03441     if(!e[1].isRational() || !e[1].getRational().isInteger())
03442       throw ParserException("BVSUB must have an integer constant as its "
03443                             "first argument:\n\n"
03444                             +e.toString());
03445     if(!(e[1].getRational().getInt() >=0))
03446       throw ParserException("parameter must be an integer constant >= 0.\n"
03447                             +e.toString());    
03448     int bvsublength = e[1].getRational().getInt();
03449     std::vector<Expr> k;
03450     Expr summand1 = parseExpr(e[2]);
03451     summand1 = pad(bvsublength, summand1);
03452     k.push_back(summand1);    
03453     Expr summand2 = parseExpr(e[3]);
03454     summand2 = pad(bvsublength, summand2);
03455     Expr bvuminus = newBVUminusExpr(summand2);
03456     k.push_back(bvuminus);
03457     return newBVPlusExpr(bvsublength, k);
03458   }
03459     break;
03460   case BVUMINUS:
03461     if(!(e.arity() == 2))
03462       throw ParserException("TheoryBitvector::parseExprOp: BVUMINUS" 
03463                             "kind should have exactly 1 arg:\n\n" 
03464                             + e.toString());    
03465     return newBVUminusExpr(parseExpr(e[1]));
03466     break;
03467   case BVPLUS: {
03468     vector<Expr> k;
03469     Expr::iterator i = e.begin(), iend=e.end();
03470     if(!(e.arity() >= 4))
03471       throw ParserException("BVPLUS must have at least 3 args:\n\n"
03472                             +e.toString());
03473     if(!e[1].isRational() || !e[1].getRational().isInteger())
03474       throw ParserException
03475         ("BVPLUS must have an integer constant as its first argument:\n\n"
03476          +e.toString());
03477     if(!(e[1].getRational().getInt() >=0))
03478       throw ParserException("parameter must be an integer constant >= 0.\n"
03479                             +e.toString());    
03480     // Skip first two elements of the vector of kids in 'e'.
03481     // The first element is the kind, and the second is the
03482     // numOfBits of the bvplus operator.
03483     ++i;++i; 
03484     // Parse the kids of e and push them into the vector 'k'
03485     for(; i!=iend; ++i) k.push_back(parseExpr(*i));
03486     return newBVPlusExpr(e[1].getRational().getInt(), k);
03487   }
03488     break;
03489   case BVMULT:
03490     if(!(e.arity() == 4))
03491       throw ParserException("TheoryBitvector::parseExprOp: BVMULT" 
03492                             "kind should have exactly 3 arg:\n\n" 
03493                             + e.toString());    
03494     if(!e[1].isRational() || !e[1].getRational().isInteger())
03495       throw ParserException("BVMULT must have an integer constant" 
03496                             "as its first argument:\n\n"
03497                             +e.toString());
03498     if(!(e[1].getRational().getInt() >=0))
03499       throw ParserException("parameter must be an integer constant >= 0.\n"
03500                             +e.toString());        
03501     return newBVMultExpr(e[1].getRational().getInt(), 
03502                          parseExpr(e[2]), parseExpr(e[3]));
03503     break;
03504   default:
03505     DebugAssert(false,
03506                 "TheoryBitvector::parseExprOp: input must be either"\
03507                 "not be a bitvector:" + int2string(e.getKind()));
03508     break;
03509   }
03510   return e;
03511 }
03512 
03513 
03514 ///////////////////////////////////////////////////////////////////////////////
03515 //helper functions
03516 ///////////////////////////////////////////////////////////////////////////////
03517 Expr TheoryBitvector::newBitvectorTypeExpr(int bvLength) {
03518   DebugAssert(bvLength > 0,
03519               "TheoryBitvector::newBitvectorTypeExpr:\n"
03520               "len of a BV must be a positive integer:\n bvlength = "+
03521               int2string(bvLength));
03522   return Expr(BITVECTOR, getEM()->newRatExpr(bvLength));
03523 }
03524 
03525 Expr TheoryBitvector::newBitvectorTypePred(const Type& t, const Expr& e) {
03526   return Expr(Expr(BVTYPEPRED, t.getExpr()).mkOp(), e);
03527 }
03528 
03529 
03530 Expr TheoryBitvector::newBVAndExpr(const Expr& t1, const Expr& t2) {
03531   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03532               BITVECTOR == t2.getType().getExpr().getOpKind(),
03533               "TheoryBitvector::newBVAndExpr:"
03534               "inputs must have type BITVECTOR:\n t1 = " +
03535               t1.toString() + "\n t2 = " +t2.toString());
03536   DebugAssert(BVSize(t1) == BVSize(t2),
03537               "TheoryBitvector::bitwise operator"
03538               "inputs must have same length:\n t1 = " + t1.toString()
03539               + "\n t2 = " + t2.toString());
03540   return Expr(CVCL::BVAND, t1, t2);
03541 }
03542 
03543 Expr TheoryBitvector::newBVAndExpr(const vector<Expr>& kids) {
03544   DebugAssert(kids.size() >= 2,
03545               "TheoryBitvector::newBVAndExpr:"
03546               "# of subterms must be at least 2");
03547   for(unsigned int i=0; i<kids.size(); ++i) {
03548     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
03549                 "TheoryBitvector::newBVAndExpr:"
03550                 "inputs must have type BITVECTOR:\n t1 = " +
03551                 kids[i].toString());
03552     if(i < kids.size()-1) {
03553       DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]),
03554                   "TheoryBitvector::bitwise operator"
03555                   "inputs must have same length:\n t1 = " + kids[i].toString()
03556                   + "\n t2 = " + kids[i+1].toString());
03557     }
03558   }
03559   return Expr(CVCL::BVAND, kids, getEM());
03560 }
03561 
03562 Expr TheoryBitvector::newBVOrExpr(const Expr& t1, const Expr& t2) {
03563   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03564               BITVECTOR == t2.getType().getExpr().getOpKind(),
03565               "TheoryBitvector::newBVOrExpr: "
03566               "inputs must have type BITVECTOR:\n t1 = " +
03567               t1.toString() + "\n t2 = " +t2.toString());
03568   DebugAssert(BVSize(t1) == BVSize(t2),
03569               "TheoryBitvector::bitwise OR operator: "
03570               "inputs must have same length:\n t1 = " + t1.toString()
03571               + "\n t2 = " + t2.toString());
03572   return Expr(CVCL::BVOR, t1, t2);
03573 }
03574 
03575 Expr TheoryBitvector::newBVOrExpr(const vector<Expr>& kids) {
03576   DebugAssert(kids.size() >= 2,
03577               "TheoryBitvector::newBVOrExpr: "
03578               "# of subterms must be at least 2");
03579   for(unsigned int i=0; i<kids.size(); ++i) {
03580     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
03581                 "TheoryBitvector::newBVOrExpr: "
03582                 "inputs must have type BITVECTOR:\n t1 = " +
03583                 kids[i].toString());
03584     if(i < kids.size()-1) {
03585       DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]),
03586                   "TheoryBitvector::bitwise operator"
03587                   "inputs must have same length:\n t1 = " + kids[i].toString()
03588                   + "\n t2 = " + kids[i+1].toString());
03589     }
03590   }
03591   return Expr(CVCL::BVOR, kids, getEM());
03592 }
03593 
03594 
03595 Expr TheoryBitvector::newBVNandExpr(const Expr& t1, const Expr& t2) {
03596   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03597               BITVECTOR == t2.getType().getExpr().getOpKind(),
03598               "TheoryBitvector::newBVNandExpr:"
03599               "inputs must have type BITVECTOR:\n t1 = " +
03600               t1.toString() + "\n t2 = " +t2.toString());
03601   DebugAssert(BVSize(t1) == BVSize(t2),
03602               "TheoryBitvector::bitwise operator"
03603               "inputs must have same length:\n t1 = " + t1.toString()
03604               + "\n t2 = " + t2.toString());
03605   return Expr(CVCL::BVNAND, t1, t2);
03606 }
03607 
03608 Expr TheoryBitvector::newBVNandExpr(const vector<Expr>& kids) {
03609   DebugAssert(kids.size() >= 2,
03610               "TheoryBitvector::newBVNandExpr:"
03611               "# of subterms must be at least 2");
03612   for(unsigned int i=0; i<kids.size(); ++i) {
03613     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
03614                 "TheoryBitvector::newBVNandExpr:"
03615                 "inputs must have type BITVECTOR:\n t1 = " +
03616                 kids[i].toString());
03617     if(i < kids.size()-1) {
03618       DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]),
03619                   "TheoryBitvector::bitwise operator"
03620                   "inputs must have same length:\n t1 = " + kids[i].toString()
03621                   + "\n t2 = " + kids[i+1].toString());
03622     }
03623   }
03624   return Expr(CVCL::BVNAND, kids, getEM());
03625 }
03626 
03627 Expr TheoryBitvector::newBVNorExpr(const Expr& t1, const Expr& t2) {
03628   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03629               BITVECTOR == t2.getType().getExpr().getOpKind(),
03630               "TheoryBitvector::newBVNorExpr:"
03631               "inputs must have type BITVECTOR:\n t1 = " +
03632               t1.toString() + "\n t2 = " +t2.toString());
03633   DebugAssert(BVSize(t1) == BVSize(t2),
03634               "TheoryBitvector::bitwise operator"
03635               "inputs must have same length:\n t1 = " + t1.toString()
03636               + "\n t2 = " + t2.toString());
03637   return Expr(CVCL::BVNOR, t1, t2);
03638 }
03639 
03640 Expr TheoryBitvector::newBVNorExpr(const vector<Expr>& kids) {
03641   DebugAssert(kids.size() >= 2,
03642               "TheoryBitvector::newBVNorExpr:"
03643               "# of subterms must be at least 2");
03644   for(unsigned int i=0; i<kids.size(); ++i) {
03645     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
03646                 "TheoryBitvector::newBVNorExpr:"
03647                 "inputs must have type BITVECTOR:\n t1 = " +
03648                 kids[i].toString());
03649     if(i < kids.size()-1) {
03650       DebugAssert( BVSize(kids[i]) ==  BVSize(kids[i+1]),
03651                   "TheoryBitvector::bitwise operator"
03652                   "inputs must have same length:\n t1 = " + kids[i].toString()
03653                   + "\n t2 = " + kids[i+1].toString());
03654     }
03655   }
03656   return Expr(CVCL::BVNOR, kids, getEM());
03657 }
03658 
03659 Expr TheoryBitvector::newBVXorExpr(const Expr& t1, const Expr& t2) {
03660   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03661               BITVECTOR == t2.getType().getExpr().getOpKind(),
03662               "TheoryBitvector::newBVXorExpr:"
03663               "inputs must have type BITVECTOR:\n t1 = " +
03664               t1.toString() + "\n t2 = " +t2.toString());
03665   DebugAssert(BVSize(t1) == BVSize(t2),
03666               "TheoryBitvector::bitwise operator"
03667               "inputs must have same length:\n t1 = " + t1.toString()
03668               + "\n t2 = " + t2.toString());
03669   return Expr(CVCL::BVXOR, t1, t2);
03670 }
03671 
03672 Expr TheoryBitvector::newBVXorExpr(const vector<Expr>& kids) {
03673   DebugAssert(kids.size() >= 2,
03674               "TheoryBitvector::newBVXorExpr:"
03675               "# of subterms must be at least 2");
03676   for(unsigned int i=0; i<kids.size(); ++i) {
03677     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
03678                 "TheoryBitvector::newBVXorExpr:"
03679                 "inputs must have type BITVECTOR:\n t1 = " +
03680                 kids[i].toString());
03681     if(i < kids.size()-1) {
03682       DebugAssert(BVSize(kids[i]) ==  BVSize(kids[i+1]),
03683                   "TheoryBitvector::bitwise operator"
03684                   "inputs must have same length:\n t1 = " + kids[i].toString()
03685                   + "\n t2 = " + kids[i+1].toString());
03686     }
03687   }
03688   return Expr(CVCL::BVXOR, kids, getEM());
03689 }
03690 
03691 Expr TheoryBitvector::newBVXnorExpr(const Expr& t1, const Expr& t2) {
03692   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03693               BITVECTOR == t2.getType().getExpr().getOpKind(),
03694               "TheoryBitvector::newBVXnorExpr:"
03695               "inputs must have type BITVECTOR:\n t1 = " +
03696               t1.toString() + "\n t2 = " +t2.toString());
03697   DebugAssert(BVSize(t1) == BVSize(t2),
03698               "TheoryBitvector::bitwise operator"
03699               "inputs must have same length:\n t1 = " + t1.toString()
03700               + "\n t2 = " + t2.toString());
03701   return Expr(CVCL::BVXNOR, t1, t2);
03702 }
03703  
03704 Expr TheoryBitvector::newBVXnorExpr(const vector<Expr>& kids) {
03705   DebugAssert(kids.size() >= 2,
03706               "TheoryBitvector::newBVXnorExpr:"
03707               "# of subterms must be at least 2");
03708   for(unsigned int i=0; i<kids.size(); ++i) {
03709     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
03710                 "TheoryBitvector::newBVXnorExpr:"
03711                 "inputs must have type BITVECTOR:\n t1 = " +
03712                 kids[i].toString());
03713     if(i < kids.size()-1) {
03714       DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]),
03715                   "TheoryBitvector::bitwise operator"
03716                   "inputs must have same length:\n t1 = " + kids[i].toString()
03717                   + "\n t2 = " + kids[i+1].toString());
03718     }
03719   }
03720   return Expr(CVCL::BVXNOR, kids, getEM());
03721 }
03722 
03723 Expr TheoryBitvector::newBVLTExpr(const Expr& t1, const Expr& t2) {
03724   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03725               BITVECTOR == t2.getType().getExpr().getOpKind(),
03726               "TheoryBitvector::newBVLTExpr:"
03727               "inputs must have type BITVECTOR:\n t1 = " +
03728               t1.toString() + "\n t2 = " +t2.toString());
03729   return Expr(CVCL::BVLT, t1, t2);
03730 }
03731 
03732 Expr TheoryBitvector::newBVLEExpr(const Expr& t1, const Expr& t2) {
03733   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03734               BITVECTOR == t2.getType().getExpr().getOpKind(),
03735               "TheoryBitvector::newBVLEExpr:"
03736               "inputs must have type BITVECTOR:\n t1 = " +
03737               t1.toString() + "\n t2 = " +t2.toString());
03738   return Expr(CVCL::BVLE, t1, t2);
03739 }
03740 
03741 Expr TheoryBitvector::newSXExpr(const Expr& t1, int len) {
03742   DebugAssert(len >=0,
03743               " TheoryBitvector::newSXExpr:" 
03744               "SX index must be a non-negative integer"+
03745               int2string(len));
03746   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
03747               "TheoryBitvector::newBVFixedleftshiftExpr:"
03748               "inputs must have type BITVECTOR:\n t1 = " +
03749               t1.toString());
03750   if(len==0) return t1;
03751   return Expr(Expr(SX, getEM()->newRatExpr(len)).mkOp(), t1);
03752 }
03753 
03754 Expr TheoryBitvector::newSBVLTExpr(const Expr& t1, const Expr& t2) {
03755   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03756               BITVECTOR == t2.getType().getExpr().getOpKind(),
03757               "TheoryBitvector::newSBVLTExpr:"
03758               "inputs must have type BITVECTOR:\n t1 = " +
03759               t1.toString() + "\n t2 = " +t2.toString());
03760   return Expr(CVCL::SBVLT, t1, t2);
03761 }
03762 
03763 Expr TheoryBitvector::newSBVLEExpr(const Expr& t1, const Expr& t2) {
03764   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03765               BITVECTOR == t2.getType().getExpr().getOpKind(),
03766               "TheoryBitvector::newSBVLEExpr:"
03767               "inputs must have type BITVECTOR:\n t1 = " +
03768               t1.toString() + "\n t2 = " +t2.toString());
03769   return Expr(CVCL::SBVLE, t1, t2);
03770 }
03771 
03772 Expr TheoryBitvector::newBVNegExpr(const Expr& t1) {
03773   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
03774               "TheoryBitvector::newBVNegExpr:"
03775               "inputs must have type BITVECTOR:\n t1 = " +
03776               t1.toString());
03777   return Expr(CVCL::BVNEG, t1);
03778 }
03779 
03780 
03781 Expr TheoryBitvector::newBVUminusExpr(const Expr& t1) {
03782   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
03783               "TheoryBitvector::newBVNegExpr:"
03784               "inputs must have type BITVECTOR:\n t1 = " +
03785               t1.toString());
03786   return Expr(CVCL::BVUMINUS, t1);
03787 }
03788 
03789 Expr TheoryBitvector::newBoolExtractExpr(const Expr& t1, int index) {
03790   DebugAssert(index >=0,
03791               " TheoryBitvector::newBoolExtractExpr:" 
03792               "bool_extract index must be a non-negative integer"+
03793               int2string(index));
03794   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
03795               "TheoryBitvector::newBVBoolExtractExpr:"
03796               "inputs must have type BITVECTOR:\n t1 = " +
03797               t1.toString());
03798 //   if(*d_boolExtractCacheFlag && isLeaf(t1)) {
03799 //     std::vector<Expr> bits = d_boolExtractCache[t1];
03800 //     int bitsSize = bits.size();
03801 //     if(bitsSize < index+1) {
03802 //       //if bits is empty then populate with empty Expr
03803 //       for(int i=bitsSize;i < index+1; ++i)
03804 //      bits.push_back(Expr());
03805 //       //now put boolextract(t1,index) in bits[index]
03806 //       BVParameterExpr 
03807 //      bv(getEM(), t1, index, d_bvParameterExprIndex, CVCL::BOOLEXTRACT);
03808 //       bits[index] = Expr(&bv);
03809 //     } else {
03810 //       if(bits[index].isNull()) {
03811 //      BVParameterExpr 
03812 //        bv(getEM(), t1, index, d_bvParameterExprIndex, CVCL::BOOLEXTRACT);
03813 //      bits[index] = Expr(&bv);
03814 //       } else {
03815 //      IF_DEBUG(const Expr e = bits[index]);
03816 //      DebugAssert(BOOLEXTRACT == e.getOpKind() &&
03817 //                  t1 == e[0] &&
03818 //                  index == getBoolExtractIndex(e),
03819 //                  "TheoryBitvector::newBoolExtractExpr:"
03820 //                  "the d_boolExtractCache has the wrong bool extract:\n"
03821 //                  "e = " + e.toString());
03822 //       }
03823 //     }
03824 //     return bits[index];
03825 //   } else {
03826   return Expr(Expr(BOOLEXTRACT, getEM()->newRatExpr(index)).mkOp(), t1);
03827 }
03828 
03829 Expr TheoryBitvector::newFixedLeftShiftExpr(const Expr& t1, int shiftLength) {
03830   DebugAssert(shiftLength >=0,
03831               " TheoryBitvector::newFixedleftshift:" 
03832               "fixed_shift index must be a non-negative integer"+
03833               int2string(shiftLength));
03834   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
03835               "TheoryBitvector::newBVFixedleftshiftExpr:"
03836               "inputs must have type BITVECTOR:\n t1 = " +
03837               t1.toString());
03838   if(shiftLength==0) return t1;
03839   return Expr(Expr(LEFTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1);
03840 }
03841 
03842 Expr TheoryBitvector::newFixedRightShiftExpr(const Expr& t1, int shiftLength) {
03843   DebugAssert(shiftLength >=0,
03844               " TheoryBitvector::newFixedleftshift:" 
03845               "fixed_shift index must be a non-negative integer"+
03846               int2string(shiftLength));
03847   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
03848               "TheoryBitvector::newBVFixedleftshiftExpr:"
03849               "inputs must have type BITVECTOR:\n t1 = " +
03850               t1.toString());
03851   if(shiftLength==0) return t1;
03852   return Expr(Expr(RIGHTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1);
03853 }
03854 
03855 Expr TheoryBitvector::newConcatExpr(const Expr& t1, const Expr& t2) {
03856   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03857               BITVECTOR == t2.getType().getExpr().getOpKind(),
03858               "TheoryBitvector::newBVConcatExpr:"
03859               "inputs must have type BITVECTOR:\n t1 = " +
03860               t1.toString() + "\n t2 = " +t2.toString());
03861   return Expr(CONCAT, t1, t2);
03862 }
03863 
03864 Expr TheoryBitvector::newConcatExpr(const Expr& t1, const Expr& t2,
03865                                     const Expr& t3) {
03866   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03867               BITVECTOR == t2.getType().getExpr().getOpKind() &&
03868               BITVECTOR == t3.getType().getExpr().getOpKind(),
03869               "TheoryBitvector::newBVConcatExpr:"
03870               "inputs must have type BITVECTOR:\n t1 = " +
03871               t1.toString() + 
03872               "\n t2 = " +t2.toString() + 
03873               "\n t3 =" + t3.toString());
03874   return Expr(CONCAT, t1, t2, t3);
03875 }
03876 
03877 Expr TheoryBitvector::newConcatExpr(const vector<Expr>& kids) {
03878   DebugAssert(kids.size() >= 2,
03879               "TheoryBitvector::newBVConcatExpr:"
03880               "# of subterms must be at least 2");
03881   for(unsigned int i=0; i<kids.size(); ++i) {
03882     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
03883                 "TheoryBitvector::newBVConcatExpr:"
03884                 "inputs must have type BITVECTOR:\n t1 = " +
03885                 kids[i].toString());
03886   }
03887   return Expr(CONCAT, kids, getEM());
03888 }
03889 
03890 Expr TheoryBitvector::newBVMultExpr(int bvLength,
03891                                     const Expr& t1, const Expr& t2) {
03892   DebugAssert(bvLength > 0,
03893               "TheoryBitvector::newBVmultExpr:"
03894               "bvLength must be an integer > 0: bvLength = " +
03895               int2string(bvLength));
03896   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
03897               BITVECTOR == t2.getType().getExpr().getOpKind(),
03898               "TheoryBitvector::newBVmultExpr:"
03899               "inputs must have type BITVECTOR:\n t1 = " +
03900               t1.toString() + "\n t2 = " +t2.toString());
03901   return Expr(Expr(BVMULT, getEM()->newRatExpr(bvLength)).mkOp(), t1, t2);
03902 }
03903 
03904 //! produces a string of 0's of length bvLength
03905 Expr TheoryBitvector::newBVZeroString(int bvLength) {
03906   DebugAssert(bvLength > 0,
03907               "TheoryBitvector::newZeroBVExpr:must be >= 0: "
03908               + int2string(bvLength));
03909   std::vector<bool> bits;
03910   for(int count=0; count < bvLength; count++) {
03911     bits.push_back(false);
03912   }
03913   return newBVConstExpr(bits);
03914 }
03915 
03916 //! produces a string of 1's of length bvLength
03917 Expr TheoryBitvector::newBVOneString(int bvLength) {
03918   DebugAssert(bvLength > 0,
03919               "TheoryBitvector::newOneBVExpr:must be >= 0: "
03920               + int2string(bvLength));
03921   std::vector<bool> bits;
03922   for(int count=0; count < bvLength; count++) {
03923     bits.push_back(true);
03924   }
03925   return newBVConstExpr(bits);
03926 }
03927 
03928 Expr TheoryBitvector::newBVConstExpr(const vector<bool>& bits) {
03929   DebugAssert(bits.size() > 0,
03930               "TheoryBitvector::newBVConstExpr:"
03931               "# of subterms must be at least 2");
03932   BVConstExpr bv(getEM(), bits, d_bvConstExprIndex);
03933   return getEM()->newExpr(&bv);
03934 }
03935 
03936 Expr TheoryBitvector::newBVConstExpr(const Rational& r, int bvLength) {
03937   DebugAssert(r.isInteger(),
03938               "TheoryBitvector::newBVConstExpr: not an integer: "
03939               + r.toString());
03940   DebugAssert(bvLength > 0,
03941               "TheoryBitvector::newBVConstExpr: bvLength = "
03942               + int2string(bvLength));
03943   string s(r.toString(2));
03944   size_t strsize = s.size();
03945   size_t length = bvLength;
03946   Expr res;
03947   if(length > 0 && length != strsize) {
03948     //either (length > strsize) or (length < strsize)
03949     if(length < strsize) {
03950       s = s.substr((strsize-length), length);
03951     } else {
03952       string zeros("");
03953       for(size_t i=0, pad=length-strsize; i < pad; ++i)
03954         zeros += "0";
03955       s = zeros+s;
03956     }
03957     res = newBVConstExpr(s, 2);
03958   } 
03959   else
03960     res = newBVConstExpr(s, 2);
03961   
03962   return res;
03963 }
03964 
03965 Expr TheoryBitvector::newBVConstExpr(const std::string& s, int base) {
03966   DebugAssert(s.size() > 0,
03967               "TheoryBitvector::newBVConstExpr:"
03968               "# of subterms must be at least 2");
03969   DebugAssert(base == 2 || base == 16, 
03970               "TheoryBitvector::newBVConstExpr: base = "
03971               +int2string(base));
03972   //hexadecimal
03973   std::string str = s;
03974   if(16 == base) {
03975     Rational r(str, 16);
03976     return newBVConstExpr(r, str.size()*4);
03977   } 
03978   else {
03979     BVConstExpr bv(getEM(), str, d_bvConstExprIndex);
03980     return getEM()->newExpr(&bv);
03981   }
03982 }
03983 
03984 Expr 
03985 TheoryBitvector::
03986 newBVExtractExpr(const Expr& e, int hi, int low){
03987   DebugAssert(low>=0 && hi>=low,
03988               " TheoryBitvector::newBVExtractExpr: " 
03989               "bad bv_extract indices: hi = " 
03990               + int2string(hi)
03991               + ", low = " 
03992               + int2string(low));
03993   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
03994               "TheoryBitvector::newBVExtractExpr:"
03995               "inputs must have type BITVECTOR:\n e = " +
03996               e.toString());
03997   return Expr(Expr(EXTRACT,
03998                    getEM()->newRatExpr(hi),
03999                    getEM()->newRatExpr(low)).mkOp(), e);
04000 }
04001 
04002 Expr TheoryBitvector::newBVPlusExpr(int bvLength, 
04003                                     const std::vector<Expr>& k) {
04004   DebugAssert(bvLength > 0,
04005               " TheoryBitvector::newBVPlusExpr:" 
04006               "bvplus length must be a positive integer: "+
04007               int2string(bvLength));
04008   DebugAssert(k.size() > 1,
04009               " TheoryBitvector::newBVPlusExpr:" 
04010               " size of input vector must be greater than 0: ");
04011   for(unsigned int i=0; i<k.size(); ++i) {
04012     DebugAssert(BITVECTOR == k[i].getType().getExpr().getOpKind(),
04013                 "TheoryBitvector::newBVPlusExpr:"
04014                 "inputs must have type BITVECTOR:\n t1 = " +
04015                 k[i].toString());
04016   }
04017   return Expr(Expr(BVPLUS, getEM()->newRatExpr(bvLength)).mkOp(), k);
04018 }
04019 
04020 //! Converts e into a BITVECTOR of length 'len'
04021 /*!
04022  * \param len is the desired length of the resulting bitvector
04023  * \param e is the original bitvector of arbitrary length
04024  */
04025 Expr 
04026 TheoryBitvector::pad(int len, const Expr& e) {
04027   DebugAssert(len >=0,
04028               "TheoryBitvector::newBVPlusExpr:" 
04029               "padding length must be a non-negative integer: "+
04030               int2string(len));
04031   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
04032               "TheoryBitvector::newBVPlusExpr:" 
04033               "input must be a BITVECTOR: " + e.toString());
04034               
04035   int size = BVSize(e);
04036   Expr res;
04037   if(size == len)
04038     res = e;
04039   else if (len < size)
04040     res = newBVExtractExpr(e,len-1,0);
04041   else {
04042     // size < len
04043     Expr zero = newBVZeroString(len-size);
04044     res = newConcatExpr(zero,e);
04045   }
04046   return res;
04047 }
04048 
04049 
04050 // Accessors for expression parameters
04051 int TheoryBitvector::getBitvectorTypeParam(const Expr& e) {
04052   DebugAssert(BITVECTOR == e.getKind(),
04053               "TheoryBitvector::getBitvectorTypeParam: wrong kind: " +
04054               e.toString());
04055   return e[0].getRational().getInt();
04056 }
04057 
04058 
04059 Type TheoryBitvector::getTypePredType(const Expr& tp) {
04060   DebugAssert(tp.getOpKind()==BVTYPEPRED && tp.isApply(),
04061               "TheoryBitvector::getTypePredType:\n tp = "+tp.toString());
04062   return Type(tp.getOpExpr()[0]);
04063 }
04064 
04065 
04066 const Expr& TheoryBitvector::getTypePredExpr(const Expr& tp) {
04067   DebugAssert(tp.getOpKind()==BVTYPEPRED,
04068               "TheoryBitvector::getTypePredType:\n tp = "+tp.toString());
04069   return tp[0];
04070 }
04071 
04072 int TheoryBitvector::getBoolExtractIndex(const Expr& e) {
04073   DebugAssert(BOOLEXTRACT == e.getOpKind() && e.isApply(),
04074               "TheoryBitvector::getBoolExtractIndex: wrong kind" +
04075               e.toString());
04076   return e.getOpExpr()[0].getRational().getInt();
04077 }
04078 
04079 int TheoryBitvector::getSXIndex(const Expr& e) {
04080   DebugAssert(SX == e.getOpKind() && e.isApply(),
04081               "TheoryBitvector::getSXIndex: wrong kind\n"+e.toString());
04082   return e.getOpExpr()[0].getRational().getInt();
04083 }
04084 
04085 int TheoryBitvector::getFixedLeftShiftParam(const Expr& e) {
04086   DebugAssert(LEFTSHIFT == e.getOpKind() && e.isApply(),
04087               "TheoryBitvector::getFixedLeftShiftParam: wrong kind" +
04088               e.toString());
04089   return e.getOpExpr()[0].getRational().getInt();
04090 }
04091 
04092 
04093 int TheoryBitvector::getFixedRightShiftParam(const Expr& e) {
04094   DebugAssert(RIGHTSHIFT == e.getOpKind() && e.isApply(),
04095               "TheoryBitvector::getFixedRightShiftParam: wrong kind" +
04096               e.toString());
04097   return e.getOpExpr()[0].getRational().getInt();
04098 }
04099 
04100 int TheoryBitvector::getExtractLow(const Expr& e) {
04101   DebugAssert(EXTRACT == e.getOpKind() && e.isApply(),
04102               "TheoryBitvector::getExtractLow: wrong kind" +
04103               e.toString());
04104   return e.getOpExpr()[1].getRational().getInt();
04105 }
04106 
04107 int TheoryBitvector::getExtractHi(const Expr& e) {
04108   DebugAssert(EXTRACT == e.getOpKind() && e.isApply(),
04109               "TheoryBitvector::getExtractHi: wrong kind" +
04110               e.toString());
04111   return e.getOpExpr()[0].getRational().getInt();
04112 }
04113 
04114 int TheoryBitvector::getBVPlusParam(const Expr& e) {
04115   DebugAssert(BVPLUS == e.getOpKind() && e.isApply(),
04116               "TheoryBitvector::getBVPlusParam: wrong kind" +
04117               e.toString());
04118   return e.getOpExpr()[0].getRational().getInt();
04119 }
04120 
04121 
04122 int TheoryBitvector::getBVMultParam(const Expr& e) {
04123   DebugAssert(BVMULT == e.getOpKind() && e.isApply(),
04124               "TheoryBitvector::getBVMultParam: wrong kind " +
04125               e.toString(AST_LANG));
04126   return e.getOpExpr()[0].getRational().getInt();
04127 }
04128 
04129 //////////////////////////////////////////////////////////////////////
04130 // class BVConstExpr methods
04131 /////////////////////////////////////////////////////////////////////
04132 //! Constructor
04133 BVConstExpr::BVConstExpr(ExprManager* em, std::string bvconst,
04134                          size_t mmIndex, ExprIndex idx)
04135   : ExprValue(em, BVCONST, idx), d_MMIndex(mmIndex) {
04136   std::string::reverse_iterator i = bvconst.rbegin();
04137   std::string::reverse_iterator iend = bvconst.rend();
04138   DebugAssert(bvconst.size() > 0,
04139               "TheoryBitvector::newBVConstExpr:"
04140               "# of subterms must be at least 2");
04141   
04142   for(;i != iend; ++i) {
04143     TRACE("bitvector", "BVConstExpr: bit ", *i, "");
04144     if('0' == *i)
04145       d_bvconst.push_back(false);
04146     else { 
04147       if('1' == *i)
04148         d_bvconst.push_back(true);
04149       else
04150         DebugAssert(false, "BVConstExpr: bad binary bit-vector: "
04151                     + bvconst);
04152     }
04153   }
04154   TRACE("bitvector", "BVConstExpr: #bits ", d_bvconst.size(), "");
04155 }
04156 
04157 BVConstExpr::BVConstExpr(ExprManager* em, std::vector<bool> bvconst,
04158                          size_t mmIndex, ExprIndex idx)
04159   : ExprValue(em, BVCONST, idx), d_bvconst(bvconst), d_MMIndex(mmIndex) {
04160   TRACE("bitvector", "BVConstExpr(vector<bool>): arg. size = ", bvconst.size(),
04161         ", d_bvconst.size = "+int2string(d_bvconst.size()));
04162 }
04163   
04164 size_t BVConstExpr::computeHash() const {
04165   std::vector<bool>::const_iterator i = d_bvconst.begin();
04166   std::vector<bool>::const_iterator iend = d_bvconst.end(); 
04167   size_t hash_value = 0;
04168   hash_value = ExprValue::hash(BVCONST);
04169   for (;i != iend; i++)
04170     if(*i)
04171       hash_value = PRIME*hash_value + HASH_VALUE_ONE;
04172     else 
04173       hash_value = PRIME*hash_value + HASH_VALUE_ZERO;
04174   return hash_value;
04175 }
04176 
04177 namespace CVCL {
04178 
04179 unsigned TheoryBitvector::getBVConstSize(const Expr& e)
04180 {
04181   DebugAssert(BVCONST == e.getKind(), "getBVConstSize called on non-bvconst");
04182   const BVConstExpr* bvc = dynamic_cast<const BVConstExpr*>(e.getExprValue());
04183   DebugAssert(bvc, "getBVConstSize: cast failed");
04184   return bvc->size();
04185 }
04186 
04187 bool TheoryBitvector::getBVConstValue(const Expr& e, int i)
04188 {
04189   DebugAssert(BVCONST == e.getKind(), "getBVConstSize called on non-bvconst");
04190   const BVConstExpr* bvc = dynamic_cast<const BVConstExpr*>(e.getExprValue());
04191   DebugAssert(bvc, "getBVConstSize: cast failed");
04192   return bvc->getValue(i);
04193 }
04194 
04195 // Computes the integer value of a bitvector constant
04196 Rational TheoryBitvector::computeBVConst(const Expr& e) {
04197 //   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
04198 //            "TheoryBitvector::computeBVConst:" 
04199 //            "input must be a BITVECTOR: " + e.toString());
04200   DebugAssert(BVCONST == e.getKind(),
04201               "TheoryBitvector::computeBVConst:" 
04202               "input must be a BITVECTOR CONST: " + e.toString());
04203   if(*d_bv32Flag) {
04204     int c(0);
04205     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
04206       c = 2*c + getBVConstValue(e, j) ? 1 : 0;
04207     Rational d(c);
04208     return d;
04209   } else {
04210     Rational c(0);
04211     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
04212       c = 2*c + (getBVConstValue(e, j) ? Rational(1) : Rational(0));
04213     return c;
04214   }
04215 }
04216 
04217 // Computes the integer value of ~c+1
04218 Rational TheoryBitvector::computeNegBVConst(const Expr& e) {
04219 //   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
04220 //            "TheoryBitvector::computeBVConst:" 
04221 //            "input must be a BITVECTOR: " + e.toString());
04222   DebugAssert(BVCONST == e.getKind(),
04223               "TheoryBitvector::computeBVConst:" 
04224               "input must be a BITVECTOR CONST: " + e.toString());
04225   if(*d_bv32Flag) {
04226     int c(0);
04227     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
04228       c = 2*c + getBVConstValue(e, j) ? 0 : 1;
04229     Rational d(c+1);
04230     return d;
04231   } else {
04232     Rational c(0);
04233     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
04234       c = 2*c + (getBVConstValue(e, j) ? Rational(0) : Rational(1));
04235     return c+1;
04236   }
04237 }
04238 
04239 // Computes the integer value of a bitvector constant
04240 Rational computeBVConst(const Expr& e) {
04241 //   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
04242 //            "TheoryBitvector::computeBVConst:" 
04243 //            "input must be a BITVECTOR: " + e.toString());
04244   DebugAssert(BVCONST == e.getKind(),
04245               "TheoryBitvector::computeBVConst:" 
04246               "input must be a BITVECTOR CONST: " + e.toString());
04247   Rational c(0);
04248 
04249   const BVConstExpr* bvc = dynamic_cast<const BVConstExpr*>(e.getExprValue());
04250   DebugAssert(bvc, "getBVConstSize: cast failed");
04251 
04252   for(int j=(int)bvc->size()-1; j>=0; j--)
04253     c = 2*c + (bvc->getValue(j) ? Rational(1) : Rational(0));
04254   return c;
04255 }
04256 
04257 Theorem
04258 TheoryBitvector::rewriteBoolean(const Expr& e) {
04259   if(!*d_booleanRWFlag)
04260     return reflexivityRule(e);
04261 
04262   Theorem thm;
04263   switch (e.getKind()) {
04264   case NOT:
04265     if (e[0].isTrue())
04266       thm = getCommonRules()->rewriteNotTrue(e);
04267     else if (e[0].isFalse())
04268       thm = getCommonRules()->rewriteNotFalse(e);
04269     else if (e[0].isNot())
04270       thm = getCommonRules()->rewriteNotNot(e);
04271     break;
04272   case IFF: {
04273     thm = getCommonRules()->rewriteIff(e);
04274     const Expr& rhs = thm.getRHS();
04275     // The only time we need to rewrite the result (rhs) is when
04276     // e==(FALSE<=>e1) or (e1<=>FALSE), so rhs==!e1.
04277     if (e != rhs && rhs.isNot())
04278       thm = transitivityRule(thm, rewriteBoolean(rhs));
04279     break;
04280   }
04281 //   case AND:
04282 //     thm = rewriteAnd(e);
04283 //     break;
04284 //   case OR:
04285 //     thm = rewriteOr(e);
04286 //     break;
04287   case AND:{
04288     std::vector<Theorem> newK;
04289     std::vector<unsigned> changed;
04290     unsigned count(0);
04291     for(Expr::iterator ii=e.begin(),iiend=e.end();ii!=iiend;ii++,count++) {
04292       Theorem temp = rewriteBoolean(*ii);
04293       if(temp.getLHS() != temp.getRHS()) {
04294         newK.push_back(temp);
04295         changed.push_back(count);
04296       }
04297     }
04298     if(changed.size() > 0) {
04299       Theorem res = substitutivityRule(e,changed,newK);
04300       thm = transitivityRule(res, rewriteAnd(res.getRHS()));
04301     } else
04302       thm = rewriteAnd(e);
04303   }
04304     break;
04305   case OR:{
04306     std::vector<Theorem> newK;
04307     std::vector<unsigned> changed;
04308     unsigned count(0);
04309     for(Expr::iterator ii=e.begin(),iiend=e.end();ii!=iiend;ii++,count++) {
04310       Theorem temp = rewriteBoolean(*ii);
04311       if(temp.getLHS() != temp.getRHS()) {
04312         newK.push_back(temp);
04313         changed.push_back(count);
04314       }
04315     }
04316     if(changed.size() > 0) {
04317       Theorem res = substitutivityRule(e,changed,newK);
04318       thm = transitivityRule(res, rewriteOr(res.getRHS()));
04319     } else
04320       thm = rewriteOr(e);
04321   }
04322     break;
04323 
04324   default:
04325     break;
04326   }
04327   if(thm.isNull()) thm = reflexivityRule(e);
04328   
04329   return thm;
04330 }
04331 
04332 } // end of namespace CVCL

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