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

Generated on Tue Jul 3 14:33:40 2007 for CVC3 by  doxygen 1.5.1