CVC3

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 
00045 int TheoryBitvector::BVSize(const Expr& e)
00046 {
00047   Type tp(getBaseType(e));
00048   DebugAssert(tp.getExpr().getOpKind() == BITVECTOR,
00049         "BVSize: e = "+e.toString());
00050   return getBitvectorTypeParam(tp);
00051 }
00052 
00053 
00054 //! Converts e into a BITVECTOR of length 'len'
00055 /*!
00056  * \param len is the desired length of the resulting bitvector
00057  * \param e is the original bitvector of arbitrary length
00058  */
00059 Expr TheoryBitvector::pad(int len, const Expr& e)
00060 {
00061   DebugAssert(len >=0,
00062         "TheoryBitvector::newBVPlusExpr:"
00063         "padding length must be a non-negative integer: "+
00064         int2string(len));
00065   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
00066         "TheoryBitvector::newBVPlusExpr:"
00067         "input must be a BITVECTOR: " + e.toString());
00068 
00069   int size = BVSize(e);
00070   Expr res;
00071   if(size == len)
00072     res = e;
00073   else if (len < size)
00074     res = newBVExtractExpr(e,len-1,0);
00075   else {
00076     // size < len
00077     Expr zero = newBVZeroString(len-size);
00078     res = newConcatExpr(zero,e);
00079   }
00080   return res;
00081 }
00082 
00083 
00084 // Bit-blasting methods
00085 
00086 
00087 //! accepts a bitvector equation t1 = t2.
00088 /*! \return a rewrite theorem which is a conjunction of equivalences
00089  * over the bits of t1,t2 respectively.
00090  */
00091 Theorem TheoryBitvector::bitBlastEqn(const Expr& e)
00092 {
00093   TRACE("bitvector", "bitBlastEqn(", e.toString(), ") {");
00094   d_bvBitBlastEq++;
00095 
00096   DebugAssert(e.isEq(),
00097         "TheoryBitvector::bitBlastEqn:"
00098         "expecting an equation" + e.toString());
00099   const Expr& leftBV = e[0];
00100   const Expr& rightBV = e[1];
00101   IF_DEBUG(const Type& leftType = getBaseType(leftBV);)
00102   IF_DEBUG(const Type& rightType = getBaseType(rightBV);)
00103   DebugAssert(BITVECTOR == leftType.getExpr().getOpKind() &&
00104         BITVECTOR == rightType.getExpr().getOpKind(),
00105         "TheoryBitvector::bitBlastEqn:"
00106         "lhs & rhs must be bitvectors");
00107   DebugAssert(BVSize(leftBV) == BVSize(rightBV),
00108         "TheoryBitvector::bitBlastEqn:\n e = "
00109         +e.toString());
00110 
00111   Theorem result = reflexivityRule(e);
00112   Theorem bitBlastLeftThm;
00113   Theorem bitBlastRightThm;
00114   std::vector<Theorem> substThms;
00115   std::vector<Theorem> leftBVrightBVThms;
00116   int bvLength = BVSize(leftBV);
00117   int bitPosition = 0;
00118   Theorem thm0;
00119 
00120   for(; bitPosition < bvLength; ++bitPosition) {
00121     //bitBlastLeftThm is the theorem 'leftBV[bitPosition] <==> phi'
00122     bitBlastLeftThm = bitBlastTerm(leftBV, bitPosition);
00123     //bitBlastRightThm is the theorem 'rightBV[bitPosition] <==> theta'
00124     bitBlastRightThm = bitBlastTerm(rightBV, bitPosition);
00125     //collect the two theorems created above in the vector
00126     //leftBVrightBVthms.
00127     leftBVrightBVThms.push_back(bitBlastLeftThm);
00128     leftBVrightBVThms.push_back(bitBlastRightThm);
00129     //construct (leftBV[bitPosition] <==> rightBV[bitPosition])
00130     //<====> phi <==> theta
00131     //and store in the vector substThms.
00132     Theorem thm = substitutivityRule(IFF, leftBVrightBVThms);
00133     thm = transitivityRule(thm, rewriteBoolean(thm.getRHS()));
00134     leftBVrightBVThms.clear();
00135     substThms.push_back(thm);
00136     //if phi <==> theta is false, then stop bitblasting. immediately
00137     //exit and return false.
00138     if(thm.getRHS().isFalse())
00139       return transitivityRule(result,
00140             d_rules->bitvectorFalseRule(thm));
00141   }
00142   // AND_0^bvLength(leftBV[bitPosition] <==> rightBV[bitPosition]) <====>
00143   // AND_0^bvLength(phi <==> theta)
00144   Theorem thm = substitutivityRule(AND, substThms);
00145   // AND_0^bvLength(leftBV[bitPosition] <==> rightBV[bitPosition]) <====>
00146   // rewriteBoolean(AND_0^bvLength(phi <==> theta))
00147   thm = transitivityRule(thm, rewriteBoolean(thm.getRHS()));
00148   //call trusted rule for bitblasting equations.
00149   result = d_rules->bitBlastEqnRule(e, thm.getLHS());
00150   result = transitivityRule(result, thm);
00151   TRACE("bitvector", "bitBlastEqn => ", result.toString(), " }");
00152   return result;
00153 }
00154 
00155 
00156 //! accepts a bitvector equation t1 != t2.
00157 /*! \return a rewrite theorem which is a conjunction of
00158  * (dis)-equivalences over the bits of t1,t2 respectively.
00159  *
00160  * A separate rule for disequations for efficiency sake. Obvious
00161  * implementation using rule for equations and rule for NOT, is not
00162  * efficient.
00163  */
00164 Theorem TheoryBitvector::bitBlastDisEqn(const Theorem& notE)
00165 {
00166   TRACE("bitvector", "bitBlastDisEqn(", notE, ") {");
00167   IF_DEBUG(debugger.counter("bit-blasted diseq")++);
00168   //stat counter
00169   d_bvBitBlastDiseq++;
00170 
00171   DebugAssert(notE.getExpr().isNot() && (notE.getExpr())[0].isEq(),
00172         "TheoryBitvector::bitBlastDisEqn:"
00173         "expecting an equation" + notE.getExpr().toString());
00174   //e is the equation
00175   const Expr& e = (notE.getExpr())[0];
00176   const Expr& leftBV = e[0];
00177   const Expr& rightBV = e[1];
00178   IF_DEBUG(Type leftType = leftBV.getType());
00179   IF_DEBUG(debugger.counter("bit-blasted diseq bits")+=
00180      BVSize(leftBV));
00181   IF_DEBUG(Type rightType = rightBV.getType());
00182   DebugAssert(BITVECTOR == leftType.getExpr().getOpKind() &&
00183         BITVECTOR == rightType.getExpr().getOpKind(),
00184         "TheoryBitvector::bitBlastDisEqn:"
00185         "lhs & rhs must be bitvectors");
00186   DebugAssert(BVSize(leftBV) == BVSize(rightBV),
00187         "TheoryBitvector::bitBlastDisEqn: e = "
00188         +e.toString());
00189   Theorem bitBlastLeftThm;
00190   Theorem bitBlastRightThm;
00191   std::vector<Theorem> substThms;
00192   std::vector<Theorem> leftBVrightBVThms;
00193   int bvLength = BVSize(leftBV);
00194   int bitPosition = 0;
00195   for(; bitPosition < bvLength; bitPosition = bitPosition+1) {
00196     //bitBlastLeftThm is the theorem '~leftBV[bitPosition] <==> ~phi'
00197     bitBlastLeftThm =
00198       getCommonRules()->iffContrapositive(bitBlastTerm(leftBV, bitPosition));
00199     //bitBlastRightThm is the theorem 'rightBV[bitPosition] <==> theta'
00200     bitBlastRightThm = bitBlastTerm(rightBV, bitPosition);
00201     //collect the two theorems created above in the vector leftBVrightBVthms.
00202     leftBVrightBVThms.push_back(bitBlastLeftThm);
00203     leftBVrightBVThms.push_back(bitBlastRightThm);
00204     //construct (~leftBV[bitPosition] <==> rightBV[bitPosition])
00205     //<====> ~phi <==> theta
00206     //and store in the vector substThms.
00207     //recall that (p <=/=> q) is same as (~p <==> q)
00208     Theorem thm = substitutivityRule(IFF, leftBVrightBVThms);
00209     thm = transitivityRule(thm, rewriteBoolean(thm.getRHS()));
00210     leftBVrightBVThms.clear();
00211     substThms.push_back(thm);
00212 
00213     //if phi <==> theta is the True theorem, then stop bitblasting. immediately
00214     //exit and return t1!=t2 <=> true.
00215     if(thm.getRHS().isTrue())
00216       return d_rules->bitvectorTrueRule(thm);
00217   }
00218 
00219   // OR_0^bvLength(~leftBV[bitPosition] <==> rightBV[bitPosition]) <====>
00220   // OR_0^bvLength(~phi <==> theta)
00221   Theorem thm1 = substitutivityRule(OR, substThms);
00222   // Call trusted rule for bitblasting disequations.
00223   Theorem result = d_rules->bitBlastDisEqnRule(notE, thm1.getLHS());
00224   Theorem thm2 = transitivityRule(thm1, rewriteBoolean(thm1.getRHS()));
00225   result = iffMP(result, thm2);
00226   TRACE("bitvector", "bitBlastDisEqn => ", result.toString(), " }");
00227   return result;
00228 }
00229 
00230 
00231 /*! \param e has the form e1 pred e2, where pred is < or <=.
00232  *
00233  *  if e1,e2 are constants, determine bv2int(e1) pred bv2int(e2).
00234  *
00235  *  most significant bit of ei is denoted by msb(ei)
00236  *
00237  *  \return \f$(msb(e1)\ pred\ msb(e2)) \vee
00238  *          (msb(e1)=msb(e2) \wedge e1[n-2:0]\ pred\ e2[n-2:0])\f$
00239  */
00240 Theorem TheoryBitvector::bitBlastIneqn(const Expr& e)
00241 {
00242   TRACE("bitvector", "bitBlastIneqn(", e.toString(), ") {");
00243 
00244   DebugAssert(BVLT == e.getOpKind() ||
00245         BVLE == e.getOpKind(),
00246         "TheoryBitvector::bitBlastIneqn: "
00247         "input e must be BVLT/BVLE: e = " + e.toString());
00248   DebugAssert(e.arity() == 2,
00249         "TheoryBitvector::bitBlastIneqn: "
00250         "arity of e must be 2: e = " + e.toString());
00251   Expr lhs = e[0];
00252   Expr rhs = e[1];
00253   int e0len = BVSize(lhs);
00254   DebugAssert(e0len == BVSize(rhs), "Expected sizes to match");
00255 
00256   int kind = e.getOpKind();
00257   Theorem res;
00258   if(lhs == rhs) {
00259     res = d_rules->lhsEqRhsIneqn(e, kind);
00260   }
00261   else if (lhs.getKind() == BVCONST && rhs.getKind() == BVCONST) {
00262     res = d_rules->bvConstIneqn(e, kind);
00263   } else {
00264     Theorem lhs_i = bitBlastTerm(lhs, e0len-1);
00265     Theorem rhs_i = bitBlastTerm(rhs, e0len-1);
00266     res = d_rules->generalIneqn(e, lhs_i, rhs_i, kind);
00267 
00268     //check if output is TRUE or FALSE theorem, and then simply return
00269     Theorem output = rewriteBoolean(res.getRHS());
00270     if (output.getRHS().isBoolConst()) {
00271       res = transitivityRule(res, output);
00272     }
00273     else if (e0len > 1) {
00274       // Copy by value, since 'res' will be changing
00275       Expr resRHS = res.getRHS();
00276       // resRHS is of the form (\alpha or (\beta and \gamma))
00277       // where \gamma is an inequality
00278       DebugAssert(resRHS.getKind() == OR && resRHS.arity() == 2 &&
00279                   resRHS[1].getKind() == AND && resRHS[1].arity() == 2,
00280                   "Unexpected structure");
00281 
00282       vector<unsigned> changed;
00283       vector<Theorem> thms;
00284 
00285       // \gamma <=> \gamma'
00286       Theorem thm = bitBlastIneqn(resRHS[1][1]);
00287 
00288       // (\beta and \gamma) <=> (\beta and \gamma')
00289       changed.push_back(1);
00290       thms.push_back(thm);
00291       thm = substitutivityRule(resRHS[1], changed, thms);
00292 
00293       // (\alpha or (\beta and \gamma)) <=> (\alpha or (\beta and \gamma'))
00294       // 'changed' is the same, only update thms[0]
00295       thms[0] = thm;
00296       thm = substitutivityRule(resRHS, changed, thms);
00297       res = transitivityRule(res, thm);
00298       /*
00299 
00300       //resRHS can be of the form (\beta and \gamma) or
00301       //resRHS can be of the form (\alpha or \gamma) or
00302       //resRHS can be of the form (\gamma)
00303       // Our mission is to bitblast \gamma and insert it back to the formula
00304       switch(resRHS.getOpKind()) {
00305         case OR:
00306           if(resRHS[1].isAnd()) { // (\alpha or (\beta and \gamma))
00307             break;
00308           }
00309           // (\alpha or \gamma) - fall through (same as the AND case)
00310         case AND: { // (\beta and \gamma)
00311           changed.push_back(1);
00312           gamma = resRHS[1];
00313           // \gamma <=> \gamma'
00314           gammaThm = rewriteBV(gamma,2);
00315           //\gamma' <=> \gamma"
00316           Theorem thm3 = bitBlastIneqn(gammaThm.getRHS());
00317           //Theorem thm3 = bitBlastIneqn(gamma);
00318           //\gamma <=> \gamma' <=> \gamma"
00319           thm3 = transitivityRule(gammaThm, thm3);
00320           thms.push_back(thm3);
00321           // (\beta and \gamma) <=> (\beta and \gamma")
00322           thm3 = substitutivityRule(resRHS,changed,thms);
00323           res = transitivityRule(res, thm3);
00324           break;
00325         }
00326         default: // (\gamma)
00327           IF_DEBUG(gamma = resRHS;)
00328           // \gamma <=> \gamma'
00329           gammaThm = rewriteBV(resRHS,2);
00330           //\gamma' <=> \gamma"
00331           Theorem thm3 = bitBlastIneqn(gammaThm.getRHS());
00332           //Theorem thm3 = bitBlastIneqn(gamma);
00333           //\gamma <=> \gamma' <=> \gamma"
00334           thm3 = transitivityRule(gammaThm, thm3);
00335           res = transitivityRule(res, thm3);
00336           break;
00337       }
00338 
00339       DebugAssert(kind == gamma.getOpKind(),
00340                   "TheoryBitvector::bitBlastIneqn: "
00341                   "gamma must be a BVLT/BVLE. gamma = " +
00342                   gamma.toString());
00343       */
00344     }
00345   }
00346   TRACE("bitvector", "bitBlastIneqn => ", res.toString(), " }");
00347   return res;
00348 }
00349 
00350 
00351 /*! The invariant maintained by this function is: accepts a bitvector
00352  * term, t,and a bitPosition, i. returns a formula over the set of
00353  * propositional variables defined using BOOLEXTRACT of bitvector
00354  * variables in t at the position i.
00355  *
00356  * \return Theorem(BOOLEXTRACT(t, bitPosition) <=> phi), where phi is
00357  * a Boolean formula over the individual bits of bit-vector variables.
00358  */
00359 Theorem TheoryBitvector::bitBlastTerm(const Expr& t, int bitPosition)
00360 {
00361   TRACE("bitvector", "bitBlastTerm(", t, ", " + int2string(bitPosition) + ") {");
00362 
00363   IF_DEBUG(Type type = t.getType();)
00364   DebugAssert(BITVECTOR == type.getExpr().getOpKind(), "TheoryBitvector::bitBlastTerm: The type of input to bitBlastTerm must be BITVECTOR.\n t = " +t.toString());
00365   DebugAssert(bitPosition >= 0, "TheoryBitvector::bitBlastTerm: illegal bitExtraction attempted.\n bitPosition = " + int2string(bitPosition));
00366 
00367   Theorem result;
00368 
00369   // Check the cache
00370   Expr t_i = newBoolExtractExpr(t, bitPosition);
00371   CDMap<Expr,Theorem>::iterator it = d_bitvecCache.find(t_i);
00372   if (it != d_bitvecCache.end()) {
00373     result = (*it).second;
00374     TRACE("bitvector", "bitBlastTerm[cached] => ", result, " }");
00375     DebugAssert(t_i == result.getLHS(), "TheoryBitvector::bitBlastTerm: created wrong theorem" + result.toString() + t_i.toString());
00376     return result;
00377   }
00378 
00379   // Construct the theorem t[bitPosition] <=> \theta_i and put it into
00380   // d_bitvecCache
00381   switch(t.getOpKind()) {
00382     case BVCONST:
00383       result = d_rules->bitExtractConstant(t, bitPosition);
00384       break;
00385     case CONCAT:
00386     {
00387       Theorem thm = d_rules->bitExtractConcatenation(t, bitPosition);
00388       const Expr& boolExtractTerm = thm.getRHS();
00389       DebugAssert(BOOLEXTRACT == boolExtractTerm.getOpKind(), "TheoryBitvector::bitBlastTerm: recursion: term must be bool_extract");
00390       const Expr& term = boolExtractTerm[0];
00391       int bitPos = getBoolExtractIndex(boolExtractTerm);
00392       TRACE("bitvector", "term for bitblastTerm recursion:(", term.toString(), ")");
00393       result = transitivityRule(thm, bitBlastTerm(term, bitPos));
00394       break;
00395     }
00396     case EXTRACT:
00397     {
00398       Theorem thm = d_rules->bitExtractExtraction(t, bitPosition);
00399       const Expr& boolExtractTerm = thm.getRHS();
00400       DebugAssert(BOOLEXTRACT == boolExtractTerm.getOpKind(), "TheoryBitvector::bitBlastTerm: recursion: term must be bool_extract");
00401       const Expr& term = boolExtractTerm[0];
00402       int bitPos = getBoolExtractIndex(boolExtractTerm);
00403       TRACE("bitvector", "term for bitblastTerm recursion:(", term, ")");
00404       result = transitivityRule(thm, bitBlastTerm(term, bitPos));
00405       break;
00406     }
00407     case CONST_WIDTH_LEFTSHIFT:
00408     {
00409       result = d_rules->bitExtractFixedLeftShift(t, bitPosition);
00410       const Expr& extractTerm = result.getRHS();
00411       if(BOOLEXTRACT == extractTerm.getOpKind())
00412         result = transitivityRule(result, bitBlastTerm(extractTerm[0], getBoolExtractIndex(extractTerm)));
00413       break;
00414     }
00415     case BVSHL:
00416     {
00417       // BOOLEXTRACT(bvshl(t,x),i) <=> ((x = 0) AND BOOLEXTRACT(t,i)) OR
00418       //                               ((x = 1) AND BOOLEXTRACT(t,i-1)) OR ...
00419       //                               ((x = i) AND BOOLEXTRACT(t,0))
00420       Theorem thm = d_rules->bitExtractBVSHL(t, bitPosition);
00421       // bitblast the equations and extractions
00422         vector<Theorem> thms, thms0;
00423       int bvsize = BVSize(t);
00424         for (int i = 0; i <= bitPosition; ++i) {
00425         thms0.push_back(bitBlastEqn(t[1].eqExpr(newBVConstExpr(i, bvsize))));
00426         thms0.push_back(bitBlastTerm(t[0], bitPosition-i));
00427           thms.push_back(substitutivityRule(AND, thms0));
00428         thms0.clear();
00429       }
00430       // Put it all together
00431       if (thms.size() == 1) {
00432         result = transitivityRule(thm, thms[0]);
00433       }
00434       else {
00435         Theorem thm2 = substitutivityRule(OR, thms);
00436         result = transitivityRule(thm, thm2);
00437       }
00438       break;
00439     }
00440     case BVLSHR:
00441     {
00442       // BOOLEXTRACT(bvlshr(t,x),i) <=> ((x = 0) AND BOOLEXTRACT(t,i)) OR
00443       //                                ((x = 1) AND BOOLEXTRACT(t,i+1)) OR ...
00444       //                                ((x = n-1-i) AND BOOLEXTRACT(t,n-1))
00445       Theorem thm = d_rules->bitExtractBVLSHR(t, bitPosition);
00446       // bitblast the equations and extractions
00447       vector<Theorem> thms, thms0;
00448       int bvsize = BVSize(t);
00449       for (int i = 0; i <= bvsize-1-bitPosition; ++i) {
00450         thms0.push_back(bitBlastEqn(t[1].eqExpr(newBVConstExpr(i, bvsize))));
00451         thms0.push_back(bitBlastTerm(t[0], bitPosition+i));
00452         thms.push_back(substitutivityRule(AND, thms0));
00453         thms0.clear();
00454       }
00455       // Put it all together
00456       if (thms.size() == 1) {
00457         result = transitivityRule(thm, thms[0]);
00458       }
00459       else {
00460         Theorem thm2 = substitutivityRule(OR, thms);
00461         result = transitivityRule(thm, thm2);
00462       }
00463       break;
00464     }
00465     case BVASHR:
00466     {
00467       // BOOLEXTRACT(bvlshr(t,x),i) <=> ((x = 0) AND BOOLEXTRACT(t,i)) OR
00468       //                                ((x = 1) AND BOOLEXTRACT(t,i+1)) OR ...
00469       //                                ((x >= n-1-i) AND BOOLEXTRACT(t,n-1))
00470       Theorem thm = d_rules->bitExtractBVASHR(t, bitPosition);
00471       // bitblast the equations and extractions
00472       vector<Theorem> thms, thms0;
00473       int bvsize = BVSize(t);
00474       int i = 0;
00475       for (; i < bvsize-1-bitPosition; ++i) {
00476         thms0.push_back(bitBlastEqn(t[1].eqExpr(newBVConstExpr(i, bvsize))));
00477         thms0.push_back(bitBlastTerm(t[0], bitPosition+i));
00478         thms.push_back(substitutivityRule(AND, thms0));
00479         thms0.clear();
00480       }
00481       Expr leExpr = newBVLEExpr(newBVConstExpr(i, bvsize), t[1]);
00482       thms0.push_back(bitBlastIneqn(leExpr));
00483       thms0.push_back(bitBlastTerm(t[0], bvsize-1));
00484       thms.push_back(substitutivityRule(AND, thms0));
00485       // Put it all together
00486       if (thms.size() == 1) {
00487         result = transitivityRule(thm, thms[0]);
00488       }
00489       else {
00490         Theorem thm2 = substitutivityRule(OR, thms);
00491         result = transitivityRule(thm, thm2);
00492       }
00493       break;
00494     }
00495     case BVOR:
00496     case BVAND:
00497     case BVXOR:
00498     {
00499       int kind = t.getOpKind();
00500       int resKind = (kind == BVOR) ? OR :
00501         kind == BVAND ? AND : XOR;
00502       Theorem thm = d_rules->bitExtractBitwise(t, bitPosition, kind);
00503       const Expr& phi = thm.getRHS();
00504       DebugAssert(phi.getOpKind() == resKind && phi.arity() == t.arity(), "TheoryBitvector::bitBlastTerm: recursion:\n phi = " + phi.toString() + "\n t = " + t.toString());
00505       vector<Theorem> substThms;
00506       for(Expr::iterator i=phi.begin(), iend=phi.end(); i!=iend; ++i) {
00507         DebugAssert(i->getOpKind() == BOOLEXTRACT, "Expected BOOLEXTRACT");
00508         substThms.push_back(bitBlastTerm((*i)[0], getBoolExtractIndex(*i)));
00509       }
00510       result = transitivityRule(thm, substitutivityRule(resKind, substThms));
00511       break;
00512     }
00513     case BVNEG:
00514     {
00515       Theorem thm = d_rules->bitExtractNot(t, bitPosition);
00516       const Expr& extractTerm = thm.getRHS();
00517       DebugAssert(NOT == extractTerm.getKind(), "TheoryBitvector::bitBlastTerm: recursion: term must be NOT");
00518       const Expr& term0 = extractTerm[0];
00519       DebugAssert(BOOLEXTRACT == term0.getOpKind(), "TheoryBitvector::bitBlastTerm: recursion:(terms must be BOOL-EXTRACT");
00520       int bitPos0 = getBoolExtractIndex(term0);
00521       std::vector<Theorem> res;
00522       res.push_back(bitBlastTerm(term0[0], bitPos0));
00523       result = transitivityRule(thm, substitutivityRule(NOT, res));
00524       break;
00525     }
00526     case BVPLUS:
00527     {
00528     Theorem thm_binary;
00529     if(t.arity() > 2) thm_binary = d_rules->bvPlusAssociativityRule(t);
00530     else thm_binary = reflexivityRule(t);
00531 
00532     Expr bvPlusTerm = thm_binary.getRHS();
00533 
00534       // Get the bits of the right multiplicand
00535       Expr b = bvPlusTerm[1];
00536       vector<Theorem> b_bits(bitPosition + 1);
00537       for (int bit = bitPosition; bit >= 0; -- bit)
00538           b_bits[bit] = bitBlastTerm(b, bit);
00539 
00540       // The output of the bit-blasting
00541       vector<Theorem> output_bits;
00542 
00543       // Get the bits of the left multiplicand
00544       Expr a = bvPlusTerm[0];
00545       vector<Theorem> a_bits(bitPosition + 1);
00546       for (int bit = bitPosition; bit >= 0; -- bit)
00547         a_bits[bit] = bitBlastTerm(a, bit);
00548 
00549       // Bit-blast them and get all the output bits (of this size)
00550       d_rules->bitblastBVPlus(a_bits, b_bits, bvPlusTerm, output_bits);
00551 
00552       // Simplify all the resulting bit expressions and add them to the bit-blasting cache
00553       Theorem thm;
00554       for (int bit = 0; bit <= bitPosition; bit ++)
00555       {
00556         thm = output_bits[bit];
00557 
00558         Expr original_boolextract = newBoolExtractExpr(t, bit);
00559         Expr boolextract = thm.getLHS();
00560         Expr bitblasted  = thm.getRHS();
00561 
00562         CDMap<Expr,Theorem>::iterator it = d_bitvecCache.find(boolextract);
00563         if (it != d_bitvecCache.end())
00564           continue;
00565 
00566         thm = d_bitvecCache[boolextract] = transitivityRule(thm, rewriteBoolean(thm.getRHS()));
00567         if (boolextract != original_boolextract)
00568           thm = d_bitvecCache[original_boolextract] = transitivityRule(substitutivityRule(original_boolextract, thm_binary), thm);
00569         }
00570 
00571       // We are returning the last theorem
00572       return thm;
00573 
00574       break;
00575     }
00576     case BVMULT: {
00577 
00578       Theorem thm;
00579 
00580       bool a_is_const = (BVCONST == t[0].getKind());
00581 
00582           // If a constant, rewrite using addition
00583       if (a_is_const) {
00584         thm = d_rules->bitExtractConstBVMult(t, bitPosition);
00585         const Expr& boolExtractTerm = thm.getRHS();
00586         const Expr& term = boolExtractTerm[0];
00587         result = transitivityRule(thm, bitBlastTerm(term, bitPosition));
00588         break;
00589       }
00590 
00591       // Get the bits ot the right multiplicant
00592       Expr b = t[1];
00593       vector<Theorem> b_bits(bitPosition + 1);
00594       for (int bit = bitPosition; bit >= 0; -- bit)
00595           b_bits[bit] = bitBlastTerm(b, bit);
00596 
00597       // The output of the bitblasting
00598       vector<Theorem> output_bits;
00599 
00600     // Get the bits of the left multiplicant
00601       Expr a = t[0];
00602       vector<Theorem> a_bits(bitPosition + 1);
00603       for (int bit = bitPosition; bit >= 0; -- bit)
00604         a_bits[bit] = bitBlastTerm(a, bit);
00605 
00606       // Bitblast them and get all the output bits (of this size)
00607       d_rules->bitblastBVMult(a_bits, b_bits, t, output_bits);
00608 
00609       // Simplify all the resulting bit expressions and add them to the bitblasting cache
00610       for (int bit = 0; bit <= bitPosition; bit ++)
00611       {
00612         thm = output_bits[bit];
00613 
00614         Expr boolextract = thm.getLHS();
00615         Expr bitblasted  = thm.getRHS();
00616 
00617         CDMap<Expr,Theorem>::iterator it = d_bitvecCache.find(boolextract);
00618         if (it != d_bitvecCache.end())
00619           continue;
00620 
00621         thm = d_bitvecCache[boolextract] = transitivityRule(thm, rewriteBoolean(thm.getRHS()));
00622                 // not allowed to use simplify in bitblasting
00623                 //theoryCore()->simplify(thm.getRHS()));
00624       }
00625 
00626       // We are returning the last theorem
00627       return thm;
00628 
00629       break;
00630     }
00631 //    case BVMULT: {
00632 //
00633 //      Theorem thm;
00634 //      if(BVCONST == t[0].getKind())
00635 //        thm = d_rules->bitExtractConstBVMult(t, bitPosition);
00636 //      else
00637 //  thm = d_rules->bitExtractBVMult(t, bitPosition);
00638 //        const Expr& boolExtractTerm = thm.getRHS();
00639 //      const Expr& term = boolExtractTerm[0];
00640 //      result = transitivityRule(thm, bitBlastTerm(term, bitPosition));
00641 //      break;
00642 //    }
00643     default:
00644     {
00645       FatalAssert(theoryOf(t.getOpKind()) != this, "Unexpected operator in bitBlastTerm:" + t.toString());
00646       //we have bitvector variable. check if the expr is indeed a BITVECTOR.
00647       IF_DEBUG(Type type = t.getType();)
00648       DebugAssert(BITVECTOR == (type.getExpr()).getOpKind(), "BitvectorTheoremProducer::bitBlastTerm: the type must be BITVECTOR");
00649       //check if 0<= i < length of BITVECTOR
00650       IF_DEBUG(int bvLength=BVSize(t);)
00651       DebugAssert(0 <= bitPosition && bitPosition < bvLength, "BitvectorTheoremProducer::bitBlastTerm: the bitextract position must be legal");
00652       TRACE("bitvector", "bitBlastTerm: blasting variables(", t, ")");
00653       const Expr bitExtract = newBoolExtractExpr(t, bitPosition);
00654       result = reflexivityRule(bitExtract);
00655       TRACE("bitvector", "bitBlastTerm: blasting variables(", t, ")");
00656       break;
00657     }
00658   }
00659   DebugAssert(!result.isNull(), "TheoryBitvector::bitBlastTerm()");
00660   Theorem simpThm = rewriteBoolean(result.getRHS());
00661   // not allowed to use simplify in bitblasting
00662   // theoryCore()->simplify(result.getRHS());
00663   result = transitivityRule(result, simpThm);
00664   d_bitvecCache[t_i] = result;
00665   DebugAssert(t_i == result.getLHS(),
00666               "TheoryBitvector::bitBlastTerm: "
00667               "created wrong theorem.\n result = "
00668               +result.toString()
00669               +"\n t_i = "+t_i.toString());
00670   TRACE("bitvector", "bitBlastTerm => ", result, " }");
00671   return result;
00672 }
00673 
00674 
00675 // Rewriting methods
00676 
00677 
00678 //! Check that all the kids of e are BVCONST
00679 static bool constantKids(const Expr& e) {
00680   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
00681     if(!i->isRational() && i->getKind() != BVCONST) return false;
00682   return true;
00683 }
00684 
00685 
00686 //! Search for all the BVCONST kids of e, and return their indices in idxs
00687 static void constantKids(const Expr& e, vector<int>& idxs) {
00688   for(int i=0, iend=e.arity(); i<iend; ++i)
00689     if(e[i].getKind() == BVCONST) idxs.push_back(i);
00690 }
00691 
00692 
00693 // Recursively descend into the expression e, keeping track of whether
00694 // we are under even or odd number of negations ('neg' == true means
00695 // odd, the context is "negative").
00696 // Produce a proof of e <==> e' or !e <==> e', depending on whether
00697 // neg is false or true, respectively.
00698 // This function must be called only from the pushNegation function
00699 Theorem TheoryBitvector::pushNegationRec(const Expr& e)
00700 {
00701   TRACE("pushNegation", "pushNegationRec(", e,") {");
00702   DebugAssert(e.getKind() == BVNEG, "Expected BVNEG in pushNegationRec");
00703   ExprMap<Theorem>::iterator i = d_pushNegCache.find(e);
00704   if(i != d_pushNegCache.end()) { // Found cached result
00705     TRACE("TheoryBitvector::pushNegation",
00706     "pushNegationRec [cached] => ", (*i).second, "}");
00707     return (*i).second;
00708   }
00709   Theorem res(reflexivityRule(e));
00710 
00711   switch(e[0].getOpKind()) {
00712     case BVCONST:
00713       res = d_rules->negConst(e);
00714       break;
00715     case BVNEG:{
00716       res = d_rules->negNeg(e);
00717       break;
00718     }
00719     case BVAND: {
00720       //demorgan's laws.
00721       Theorem thm0 = d_rules->negBVand(e);
00722       Expr ee = thm0.getRHS();
00723       if (ee.arity() == 0) res = thm0;
00724       else {
00725         //process each negated kid
00726         Op op = ee.getOp();
00727         vector<Theorem> thms;
00728         for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i)
00729           thms.push_back(pushNegationRec(*i));
00730         res = substitutivityRule(op, thms);
00731         res = transitivityRule(thm0, res);
00732       }
00733       break;
00734     }
00735     case BVOR: {
00736       //demorgan's laws.
00737       Theorem thm0 = d_rules->negBVor(e);
00738       Expr ee = thm0.getRHS();
00739       if (ee.arity() == 0) res = thm0;
00740       else {
00741         //process each negated kid
00742         Op op = ee.getOp();
00743         vector<Theorem> thms;
00744         for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i)
00745           thms.push_back(pushNegationRec(*i));
00746         res = substitutivityRule(op, thms);
00747         res = transitivityRule(thm0, res);
00748       }
00749       break;
00750     }
00751     case BVXOR: {
00752       res = d_rules->negBVxor(e);
00753       Expr ee = res.getRHS();
00754 
00755       // only the first child is negated
00756       Theorem thm0 = pushNegationRec(ee[0]);
00757       if (!thm0.isRefl()) {
00758         thm0 = substitutivityRule(ee, 0, thm0);
00759         res = transitivityRule(res, thm0);
00760       }
00761       break;
00762     }
00763     case BVXNOR: {
00764       res = d_rules->negBVxnor(e);
00765       break;
00766     }
00767     case CONCAT: {
00768       //demorgan's laws.
00769       Theorem thm0 = d_rules->negConcat(e);
00770       Expr ee = thm0.getRHS();
00771       if (ee.arity() == 0) res = thm0;
00772       else {
00773         //process each negated kid
00774         Op op = ee.getOp();
00775         vector<Theorem> thms;
00776         for(Expr::iterator i=ee.begin(), iend=ee.end(); i!=iend; ++i)
00777           thms.push_back(pushNegationRec(*i));
00778         res = substitutivityRule(op, thms);
00779         res = transitivityRule(thm0, res);
00780       }
00781       break;
00782     }
00783     case BVPLUS:
00784       // FIXME: Need to implement the following transformation:
00785       // ~(x+y) <=> ~x+~y+1
00786       // (because  ~(x+y)+1= -(x+y) = -x-y = ~x+1+~y+1)
00787     case BVMULT:
00788       // FIXME: Need to implement the following transformation:
00789       // ~(x*y) <=> (~x+1)*y-1
00790       // [ where we prefer x to be constant/AND/OR/NEG and then
00791       //   BVPLUS, and only then everything else].
00792       // (because  ~(x*y)+1= -(x+y) = (-x)*y = (~x+1)*y)
00793     default:
00794       res = reflexivityRule(e);
00795       break;
00796   }
00797   TRACE("TheoryBitvector::pushNegation", "pushNegationRec => ", res, "}");
00798   d_pushNegCache[e] = res;
00799   return res;
00800 }
00801 
00802 
00803 // We assume that the cache is initially empty
00804 Theorem TheoryBitvector::pushNegation(const Expr& e) {
00805   d_pushNegCache.clear();
00806   DebugAssert(BVNEG == e.getOpKind(), "Expected BVNEG");
00807   return pushNegationRec(e);
00808 }
00809 
00810 
00811 //! Top down simplifier
00812 Theorem TheoryBitvector::simplifyOp(const Expr& e) {
00813   if (e.arity() > 0) {
00814     Expr ee(e);
00815     Theorem thm0;
00816     switch(e.getOpKind()) {
00817     case BVNEG:
00818       thm0 = pushNegation(e);
00819       break;
00820     case EXTRACT:
00821       switch(e[0].getOpKind()) {
00822       case BVPLUS:
00823   thm0 = d_rules->extractBVPlus(e);
00824   break;
00825       case BVMULT:
00826   thm0 = d_rules->extractBVMult(e);
00827   break;
00828       default:
00829   thm0 = reflexivityRule(e);
00830   break;
00831       }
00832       break;
00833     case BVPLUS:
00834       break;
00835     case BVMULT:
00836       //      thm0 = d_rules->padBVMult(e);
00837       break;
00838     case CONCAT: // 0bin0_[k] @ BVPLUS(n, args) => BVPLUS(n+k, args)
00839 //       if(e.arity()==2 && e[0].getKind()==BVCONST && e[1].getOpKind()==BVPLUS
00840 //   && computeBVConst(e[0]) == 0) {
00841 //  thm0 = d_rules->bvplusZeroConcatRule(e);
00842 //       }
00843       break;
00844     case RIGHTSHIFT:
00845       thm0 = d_rules->rightShiftToConcat(e);
00846       break;
00847     case LEFTSHIFT:
00848       thm0 = d_rules->leftShiftToConcat(e);
00849       break;
00850     case CONST_WIDTH_LEFTSHIFT:
00851       thm0 = d_rules->constWidthLeftShiftToConcat(e);
00852       break;
00853     default:
00854       thm0 = reflexivityRule(e);
00855       break;
00856     }
00857     vector<Theorem> newChildrenThm;
00858     vector<unsigned> changed;
00859     if(thm0.isNull()) thm0 = reflexivityRule(e);
00860     ee = thm0.getRHS();
00861     int ar = ee.arity();
00862     for(int k = 0; k < ar; ++k) {
00863       // Recursively simplify the kids
00864       Theorem thm = simplify(ee[k]);
00865       if (thm.getLHS() != thm.getRHS()) {
00866   newChildrenThm.push_back(thm);
00867   changed.push_back(k);
00868       }
00869     }
00870     if(changed.size() > 0) {
00871       Theorem thm1 = substitutivityRule(ee, changed, newChildrenThm);
00872       return transitivityRule(thm0,thm1);
00873     } else
00874       return thm0;
00875   }
00876   return reflexivityRule(e);
00877 }
00878 
00879 
00880 // Theorem TheoryBitvector::rewriteConst(const Expr& e)
00881 // {
00882 //   Theorem result = reflexivityRule(e);
00883 //   return result;
00884 // }
00885 
00886 
00887 Theorem TheoryBitvector::rewriteBV(const Expr& e, ExprMap<Theorem>& cache, int n)
00888 {
00889   TRACE("bitvector rewrite", "TheoryBitvector::rewriteBV(", e, ") {");
00890 
00891   if (n <= 0) return reflexivityRule(e);
00892 
00893   Theorem res;
00894 
00895   if(n >= 2) {
00896     // rewrite children recursively
00897     Theorem thm;
00898     vector<Theorem> thms;
00899     vector<unsigned> changed;
00900     for(int i=0, iend=e.arity(); i<iend; ++i) {
00901       thm = rewriteBV(e[i], cache, n-1);
00902       if(thm.getLHS() != thm.getRHS()) {
00903         thms.push_back(thm);
00904         changed.push_back(i);
00905       }
00906     }
00907     if(changed.size() > 0) {
00908       thm = substitutivityRule(e, changed, thms);
00909       return transitivityRule(thm, rewriteBV(thm.getRHS(), cache));
00910     }
00911     // else fall through
00912   }
00913 
00914   // Check the cache
00915   ExprMap<Theorem>::iterator it = cache.find(e);
00916   if (it != cache.end()) {
00917     res = (*it).second;
00918     TRACE("bitvector rewrite", "TheoryBitvector::rewrite["+int2string(n)
00919           +"][cached] => ", res.getExpr(), " }");
00920     IF_DEBUG(debugger.counter("bv rewriteBV[n] cache hits")++;)
00921     return res;
00922   }
00923 
00924   // Main rewrites
00925   switch(e.getOpKind()) {
00926     case NOT:
00927       switch (e[0].getKind()) {
00928         case BVLT:
00929         case BVLE:
00930           res = d_rules->notBVLTRule(e);
00931           if (!res.isRefl()) {
00932             res = transitivityRule(res, simplify(res.getRHS()));
00933           }
00934           break;
00935         case EQ:
00936           if (BVSize(e[0][0]) == 1) {
00937             res = d_rules->notBVEQ1Rule(e);
00938             res = transitivityRule(res, simplify(res.getRHS()));
00939             break;
00940           }
00941           break;
00942       }
00943       break;
00944     case EQ:
00945     {
00946       // Canonise constant equations to true or false
00947       if (e[0].getKind() == BVCONST && e[1].getKind() == BVCONST) {
00948         res = d_rules->constEq(e);
00949       } else
00950       // If x_1 or x_2 = 0 then both have to be 0
00951       if (e[0].getKind() == BVOR && e[1].getKind() == BVCONST && computeBVConst(e[1]) == 0) {
00952         res = d_rules->zeroBVOR(e);
00953         res = transitivityRule(res, simplify(res.getRHS()));
00954       }
00955       // if x_1 and x_2 = 1 then both have to be 1
00956       else if (e[0].getKind() == BVAND && e[1].getKind() == BVCONST && computeBVConst(e[1]) == pow(BVSize(e[1]), (Unsigned)2) - 1) {
00957         res = d_rules->oneBVAND(e);
00958         res = transitivityRule(res, simplify(res.getRHS()));
00959       }
00960       // Solve
00961       else {
00962         res = d_rules->canonBVEQ(e);
00963         if (!res.isRefl()) {
00964           res = transitivityRule(res, simplify(res.getRHS()));
00965         }
00966         else e.setRewriteNormal();
00967       }
00968       break;
00969     }
00970     case BVCONST:
00971     {
00972       res = reflexivityRule(e);
00973       break;
00974     }
00975     case CONCAT: {
00976       // First, flatten concatenation
00977       res = d_rules->concatFlatten(e);
00978       TRACE("bitvector rewrite", "rewriteBV (CONCAT): flattened = ",
00979       res.getRHS(), "");
00980       // Search for adjacent constants and accumulate the vector of
00981       // nested concatenations (@ t1 ... (@ c1 ... ck) ... tn), and the
00982       // indices of constant concatenations in this new expression.
00983       // We'll connect this term to 'e' by inverse of flattenning, and
00984       // rewrite concatenations of constants into bitvector constants.
00985       vector<unsigned> idxs;
00986       vector<Expr> kids; // Kids of the new concatenation
00987       vector<Theorem> thms; // Rewrites of constant concatenations
00988       vector<Expr> nestedKids; // Kids of the current concatenation of constants
00989       // res will be overwritten, using const Expr& may be dangerous
00990       Expr e1 = res.getRHS();
00991       for(int i=0, iend=e1.arity(); i<iend; ++i) {
00992   TRACE("bitvector rewrite", "rewriteBV: e["+int2string(i)+"]=",
00993         e1[i], "");
00994   if(e1[i].getKind() == BVCONST) {
00995     // INVARIANT: if it is the first constant in a batch,
00996     // then nestedKids must be empty.
00997     nestedKids.push_back(e1[i]);
00998     TRACE("bitvector rewrite", "rewriteBV: queued up BVCONST: ",
00999     e1[i], "");
01000   } else { // e1[i] is not a BVCONST
01001     if(nestedKids.size() > 0) { // This is the end of a batch
01002       if(nestedKids.size() >= 2) { // Create a nested const concat
01003         Expr cc = newConcatExpr(nestedKids);
01004         idxs.push_back(kids.size());
01005         kids.push_back(cc);
01006         thms.push_back(d_rules->concatConst(cc));
01007         TRACE("bitvector rewrite", "rewriteBV: wrapping ", cc, "");
01008       } else { // A single constant, add it as it is
01009         TRACE("bitvector rewrite", "rewriteBV: single const ",
01010         nestedKids[0], "");
01011         kids.push_back(nestedKids[0]);
01012       }
01013       nestedKids.clear();
01014     }
01015     // Add the current non-constant BV
01016     kids.push_back(e1[i]);
01017   }
01018       }
01019       // Handle the last BVCONST
01020       if(nestedKids.size() > 0) {
01021   if(nestedKids.size() >= 2) { // Create a nested const concat
01022     Expr cc = newConcatExpr(nestedKids);
01023     idxs.push_back(kids.size());
01024     kids.push_back(cc);
01025     thms.push_back(d_rules->concatConst(cc));
01026     TRACE("bitvector rewrite", "rewriteBV: wrapping ", cc, "");
01027   } else { // A single constant, add it as it is
01028     kids.push_back(nestedKids[0]);
01029     TRACE("bitvector rewrite", "rewriteBV: single const ",
01030     nestedKids[0], "");
01031   }
01032   nestedKids.clear();
01033       }
01034       // If there are any constants to merge, do the merging
01035       if(idxs.size() > 0) {
01036   // CONCAT with constants groupped
01037   if(kids.size() == 1) { // Special case: all elements are constants
01038     DebugAssert(thms.size() == 1, "TheoryBitvector::rewriteBV:\n"
01039           "case CONCAT: all constants.  thms.size() == "
01040           +int2string(thms.size()));
01041     res = transitivityRule(res, thms[0]);
01042   } else {
01043     Expr ee = newConcatExpr(kids);
01044 
01045     Theorem constMerge = substitutivityRule(ee, idxs, thms);
01046     // The inverse flattening of ee
01047     Theorem unFlatten = symmetryRule(d_rules->concatFlatten(ee));
01048     // Putting it together: Theorem(e==e'), where e' has constants merged
01049     res = transitivityRule(res, unFlatten);
01050     res = transitivityRule(res, constMerge);
01051   }
01052       }
01053 
01054       // Now do a similar search for mergeable extractions
01055       idxs.clear();
01056       thms.clear();
01057       kids.clear();
01058       // nestedKids must already be empty
01059       DebugAssert(nestedKids.size() == 0,
01060       "rewriteBV() case CONCAT, end of const merge");
01061       Expr prevExpr; // Previous base of extraction (initially Null)
01062       // The first and the last bit in the batch of mergeable extractions
01063       int hi(-1), low(-1);
01064       // Refresh e1
01065       e1 = res.getRHS();
01066       for(int i=0, iend=e1.arity(); i<iend; ++i) {
01067   const Expr& ei = e1[i];
01068   if(ei.getOpKind() == EXTRACT) {
01069     if(nestedKids.size() > 0 && ei[0] == prevExpr
01070        && (low-1) == getExtractHi(ei)) {
01071       // Continue to accumulate the current batch
01072       nestedKids.push_back(ei);
01073       low = getExtractLow(ei);
01074     } else { // Start a new batch
01075       // First, check if there was a batch before that
01076       if(nestedKids.size() >= 2) { // Create a nested const concat
01077         Expr cc = newConcatExpr(nestedKids);
01078         idxs.push_back(kids.size());
01079         kids.push_back(cc);
01080         thms.push_back(d_rules->concatMergeExtract(cc));
01081         nestedKids.clear();
01082       } else if(nestedKids.size() == 1) {
01083         // A single extraction, add it as it is
01084         kids.push_back(nestedKids[0]);
01085         nestedKids.clear();
01086       }
01087       // Now, actually start a new batch
01088       nestedKids.push_back(ei);
01089       hi = getExtractHi(ei);
01090       low = getExtractLow(ei);
01091       prevExpr = ei[0];
01092     }
01093   } else { // e1[i] is not an EXTRACT
01094     if(nestedKids.size() >= 2) { // Create a nested const concat
01095       Expr cc = newConcatExpr(nestedKids);
01096       idxs.push_back(kids.size());
01097       kids.push_back(cc);
01098       thms.push_back(d_rules->concatMergeExtract(cc));
01099     } else if(nestedKids.size() == 1) {
01100       // A single extraction, add it as it is
01101       kids.push_back(nestedKids[0]);
01102     }
01103     nestedKids.clear();
01104     // Add the current non-EXTRACT BV
01105     kids.push_back(ei);
01106   }
01107       }
01108       // Handle the last batch of extractions
01109       if(nestedKids.size() >= 2) { // Create a nested const concat
01110   Expr cc = newConcatExpr(nestedKids);
01111   idxs.push_back(kids.size());
01112   kids.push_back(cc);
01113   // The extraction may include all the bits, we need to rewrite again
01114   thms.push_back(rewriteBV(d_rules->concatMergeExtract(cc), cache, 1));
01115       } else if(nestedKids.size() == 1) {
01116   // A single extraction, add it as it is
01117   kids.push_back(nestedKids[0]);
01118       }
01119       // If there are any extractions to merge, do the merging
01120       if(idxs.size() > 0) {
01121   // CONCAT with extractions groupped
01122   if(kids.size() == 1) { // Special case: all elements merge together
01123     DebugAssert(thms.size() == 1, "TheoryBitvector::rewriteBV:\n"
01124           "case CONCAT: all extracts merge.  thms.size() == "
01125           +int2string(thms.size()));
01126     res = thms[0];
01127   } else {
01128     Expr ee = newConcatExpr(kids);
01129     Theorem extractMerge = substitutivityRule(ee, idxs, thms);
01130     // The inverse flattening of ee
01131     Theorem unFlatten = symmetryRule(d_rules->concatFlatten(ee));
01132     // Putting it together: Theorem(e==e'), where e' has extractions merged
01133     res = transitivityRule(res, unFlatten);
01134     res = transitivityRule(res, extractMerge);
01135   }
01136       }
01137       // Check for 0bin00 @ BVPLUS(n, ...).  Most of the time, this
01138       // case will be handled during the top-down phase
01139       // (simplifyOp()), but not always.
01140 //       Expr ee = res.getRHS();
01141 //       if(ee.getOpKind()==CONCAT && ee.arity() == 2 && ee[0].getKind()==BVCONST
01142 //   && ee[1].getOpKind()==BVPLUS && computeBVConst(ee[0]) == 0) {
01143 //  // Push the concat down through BVPLUS
01144 //  Theorem thm = d_rules->bvplusZeroConcatRule(ee);
01145 //  if(thm.getLHS()!=thm.getRHS()) {
01146 //    thm = transitivityRule(thm, d_rules->padBVPlus(thm.getRHS()));
01147 //    // Kids may need to be rewritten again
01148 //    res = rewriteBV(transitivityRule(res, thm), cache, 2);
01149 //  }
01150 //       }
01151       // Since we may have pulled subexpressions from more than one
01152       // level deep, we cannot guarantee that all the new kids are
01153       // fully simplified, and have to call simplify explicitly again.
01154       // Since this is potentially an expensive operation, we try to
01155       // minimize the need for it:
01156 
01157       // * check if the result has a find pointer (then kids don't
01158       //   need to be simplified),
01159       // * check if any of the kids simplify (if not, don't bother).
01160       // If kids are already simplified, we'll hit the simplifier
01161       // cache.  It's only expensive when kids do indeed simplify.
01162       if(!res.isRefl() && (theoryCore()->inUpdate() || !res.getRHS().hasFind())) {
01163         res = transitivityRule(res, simplify(res.getRHS()));
01164       }
01165       break;
01166     }
01167     case EXTRACT: {
01168       DebugAssert(e.arity() == 1, "TheoryBitvector::rewriteBV: e = "
01169       +e.toString());
01170       if(getExtractLow(e) == 0 && getExtractHi(e) == BVSize(e[0])-1)
01171   res = d_rules->extractWhole(e);
01172       else {
01173   switch(e[0].getOpKind()) {
01174   case BVCONST:
01175     res = d_rules->extractConst(e);
01176     break;
01177   case EXTRACT:
01178     res = d_rules->extractExtract(e);
01179     break;
01180   case CONCAT:
01181     // Push extraction through concat, and rewrite the kids
01182     res = rewriteBV(d_rules->extractConcat(e), cache, 2);
01183     break;
01184   case BVNEG:
01185           res = rewriteBV(d_rules->extractNeg(e), cache, 2);
01186     break;
01187   case BVAND:
01188     res = rewriteBV(d_rules->extractAnd(e), cache, 2);
01189     break;
01190   case BVOR:
01191     res = rewriteBV(d_rules->extractOr(e), cache, 2);
01192     break;
01193   case BVXOR:
01194     res =
01195       rewriteBV(d_rules->extractBitwise(e, BVXOR, "extract_bvxor"), cache, 2);
01196     break;
01197   case BVMULT: {
01198     const Expr& bvmult = e[0];
01199     int hiBit = getExtractHi(e);
01200     int bvmultLen = BVSize(bvmult);
01201     // Applicable if it changes anything
01202     if(hiBit+1 < bvmultLen) {
01203       res = d_rules->extractBVMult(e);
01204             res = rewriteBV(res, cache, 3);
01205     } else
01206       res = reflexivityRule(e);
01207     break;
01208   }
01209   case BVPLUS: {
01210     const Expr& bvplus = e[0];
01211     int hiBit = getExtractHi(e);
01212     int bvplusLen = BVSize(bvplus);
01213     if(hiBit+1 < bvplusLen) {
01214       res = d_rules->extractBVPlus(e);
01215     } else res = reflexivityRule(e);
01216     break;
01217   }
01218   default:
01219     res = reflexivityRule(e);
01220     break;
01221   }
01222       }
01223       if (!res.isRefl()) {
01224         res = transitivityRule(res, simplify(res.getRHS()));
01225       }
01226       break;
01227     }
01228     case BOOLEXTRACT: {
01229       Expr t(e);
01230       // Normal form: t[0] for 1-bit t, collapse t[i:i][0] into t[i]
01231       if(BVSize(e[0]) > 1) { // transform t[i] to t[i:i][0] and rewrite
01232         res = rewriteBV(d_rules->bitExtractRewrite(e), cache, 2);
01233         t = res.getRHS();
01234       }
01235       if(t.getOpKind() == BOOLEXTRACT && t[0].getOpKind() == EXTRACT) {
01236         // Collapse t[i:i][0] to t[i]
01237         int low = getExtractLow(t[0]);
01238         if(getExtractHi(t[0]) == low) {
01239           Theorem thm(d_rules->bitExtractRewrite
01240                       (newBoolExtractExpr(t[0][0], low)));
01241           thm = symmetryRule(thm);
01242           res = (res.isNull())? thm : transitivityRule(res, thm);
01243           t = res.getRHS()[0];
01244           // Make sure t in the resulting t[i] is its own find pointer
01245           // (global invariant)
01246           if(t.hasFind()) {
01247             Theorem findThm = find(t);
01248             if(t != findThm.getRHS()) {
01249               vector<Theorem> thms;
01250               thms.push_back(findThm);
01251               thm = substitutivityRule(res.getRHS().getOp(), thms);
01252               res = transitivityRule(res, thm);
01253             }
01254           }
01255         }
01256       }
01257       if(!res.isNull()) t = res.getRHS();
01258       // Rewrite a constant extraction to TRUE or FALSE
01259       if(t.getOpKind() == BOOLEXTRACT && constantKids(t)) {
01260         Theorem thm = d_rules->bitExtractConstant(t[0], getBoolExtractIndex(t));
01261         res = (res.isNull())? thm : transitivityRule(res, thm);
01262       }
01263       break;
01264     }
01265     case LEFTSHIFT:
01266         if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) {
01267           res = d_rules->bvShiftZero(e);
01268         } else {
01269           res = d_rules->leftShiftToConcat(e);
01270           if (!res.isRefl()) {
01271             res = transitivityRule(res, simplify(res.getRHS()));
01272           }
01273         }
01274         break;
01275     case CONST_WIDTH_LEFTSHIFT:
01276         if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) {
01277           res = d_rules->bvShiftZero(e);
01278         } else {
01279           res = d_rules->constWidthLeftShiftToConcat(e);
01280           if (!res.isRefl()) {
01281             res = transitivityRule(res, simplify(res.getRHS()));
01282           }
01283         }
01284         break;
01285     case RIGHTSHIFT:
01286         if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) {
01287           res = d_rules->bvShiftZero(e);
01288         } else {
01289           res = d_rules->rightShiftToConcat(e);
01290           if (!res.isRefl()) {
01291             res = transitivityRule(res, simplify(res.getRHS()));
01292           }
01293         }
01294         break;
01295     case BVSHL:
01296       if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) {
01297         res = d_rules->bvShiftZero(e);
01298       } else
01299       if (e[1].getKind() == BVCONST) {
01300         res = d_rules->bvshlToConcat(e);
01301         res = transitivityRule(res, simplify(res.getRHS()));
01302       }
01303 //       else {
01304 //         res = d_rules->bvshlSplit(e);
01305 //         res = transitivityRule(res, simplify(res.getRHS()));
01306 //       }
01307       break;
01308     case BVLSHR:
01309       if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) {
01310         res = d_rules->bvShiftZero(e);
01311       } else
01312       if (e[1].getKind() == BVCONST) {
01313         res = d_rules->bvlshrToConcat(e);
01314         res = transitivityRule(res, simplify(res.getRHS()));
01315       }
01316       break;
01317     case BVASHR:
01318       if (e[0].getKind() == BVCONST && computeBVConst(e[0]) == 0) {
01319       res = d_rules->bvShiftZero(e);
01320       } else
01321         if (e[1].getKind() == BVCONST) {
01322             res = d_rules->bvashrToConcat(e);
01323             res = transitivityRule(res, simplify(res.getRHS()));
01324           }
01325       break;
01326     case SX: {
01327       res = d_rules->signExtendRule(e);
01328       res = transitivityRule(res, simplify(res.getRHS()));
01329       break;
01330     }
01331 
01332     case BVZEROEXTEND:
01333       res = d_rules->zeroExtendRule(e);
01334       res = transitivityRule(res, simplify(res.getRHS()));
01335       break;
01336 
01337     case BVREPEAT:
01338       res = d_rules->repeatRule(e);
01339       res = transitivityRule(res, simplify(res.getRHS()));
01340       break;
01341 
01342     case BVROTL:
01343       res = d_rules->rotlRule(e);
01344       res = transitivityRule(res, simplify(res.getRHS()));
01345       break;
01346 
01347     case BVROTR:
01348       res = d_rules->rotrRule(e);
01349       res = transitivityRule(res, simplify(res.getRHS()));
01350       break;
01351 
01352     case BVAND:
01353     case BVOR:
01354     case BVXOR:
01355     {
01356       int kind = e.getOpKind();
01357       // Flatten the bit-wise AND, eliminate duplicates, reorder terms
01358       res = d_rules->bitwiseFlatten(e, kind);
01359       Expr ee = res.getRHS();
01360       if (ee.getOpKind() != kind) break;
01361 
01362       // Search for constant bitvectors
01363       vector<int> idxs;
01364       constantKids(ee, idxs);
01365       int idx = -1;
01366 
01367       if(idxs.size() >= 2) {
01368         res = transitivityRule(res, d_rules->bitwiseConst(ee, idxs, kind));
01369         ee = res.getRHS();
01370         if (ee.getOpKind() != kind) break;
01371         idx = 0;
01372       }
01373       else if (idxs.size() == 1) {
01374         idx = idxs[0];
01375       }
01376 
01377       if (idx >= 0) {
01378         res = transitivityRule(res, d_rules->bitwiseConstElim(ee, idx, kind));
01379         ee = res.getRHS();
01380       }
01381       if (ee.getOpKind() == kind) {
01382         res = transitivityRule(res, d_rules->bitwiseConcat(ee, kind));
01383       }
01384       if (!res.isRefl()) {
01385         res = transitivityRule(res, simplify(res.getRHS()));
01386       }
01387       else {
01388         e.setRewriteNormal();
01389       }
01390       break;
01391     }
01392     case BVXNOR: {
01393       res = d_rules->rewriteXNOR(e);
01394       res = transitivityRule(res, simplify(res.getRHS()));
01395       break;
01396     }
01397     case BVNEG: {
01398       res = pushNegation(e);
01399       if (!res.isRefl()) {
01400         res = transitivityRule(res, simplify(res.getRHS()));
01401       }
01402       break;
01403     }
01404     case BVNAND: {
01405       res = d_rules->rewriteNAND(e);
01406       res = transitivityRule(res, simplify(res.getRHS()));
01407       break;
01408     }
01409     case BVNOR: {
01410       res = d_rules->rewriteNOR(e);
01411       res = transitivityRule(res, simplify(res.getRHS()));
01412       break;
01413     }
01414     case BVCOMP: {
01415       res = d_rules->rewriteBVCOMP(e);
01416       res = transitivityRule(res, simplify(res.getRHS()));
01417       break;
01418     }
01419     case BVUMINUS:
01420     {
01421       res = d_rules->canonBVUMinus( e );
01422       res = transitivityRule(res, simplify(res.getRHS()));
01423       break;
01424     }
01425     case BVPLUS:
01426     {
01427       res = d_rules->canonBVPlus(e );
01428       if (!res.isRefl()) {
01429         res = transitivityRule(res, simplify(res.getRHS()));
01430       }
01431       else e.setRewriteNormal();
01432       break;
01433     }
01434     case BVSUB: {
01435       res = d_rules->rewriteBVSub(e);
01436       res = transitivityRule(res, simplify(res.getRHS()));
01437       break;
01438     }
01439     case BVMULT:
01440     {
01441       res = d_rules->liftConcatBVMult(e);
01442       if (!res.isRefl()) {
01443         res = transitivityRule(res, simplify(res.getRHS()));
01444       }
01445       else {
01446         res =  d_rules->canonBVMult( e );
01447         if (!res.isRefl())
01448           res = transitivityRule(res, simplify(res.getRHS()));
01449         else e.setRewriteNormal();
01450       }
01451       break;
01452     }
01453 
01454     case BVUDIV:
01455     {
01456       Expr a = e[0];
01457       Expr b = e[1];
01458 
01459       // Constant division
01460       if (a.getOpKind() == BVCONST && b.getOpKind() == BVCONST) {
01461         res = d_rules->bvUDivConst(e);
01462         break;
01463       }
01464 
01465       if (theoryCore()->okToEnqueue())
01466       {
01467         // get the full theorem
01468         // e = x/y
01469         // \exists div, mod: e = div & (y != 0 -> ...)
01470         // result is the equality
01471         // assert the additional conjunct
01472         Theorem fullTheorem =  d_rules->bvUDivTheorem(e);
01473         // Skolemise the variables
01474         Theorem skolem_div = getCommonRules()->skolemize(fullTheorem);
01475         // Get the rewrite part
01476         res = getCommonRules()->andElim(skolem_div, 0);
01477         // Get the division part
01478         Theorem additionalConstraint = getCommonRules()->andElim(skolem_div, 1);
01479         // Enqueue the division part
01480         enqueueFact(additionalConstraint);
01481         res = transitivityRule(res, simplify(res.getRHS()));
01482       } else {
01483         res = reflexivityRule(e);
01484       }
01485       break;
01486     }
01487     case BVSDIV:
01488       res = d_rules->bvSDivRewrite(e);
01489       res = transitivityRule(res, simplify(res.getRHS()));
01490       break;
01491     case BVUREM:
01492     {
01493       Expr a = e[0];
01494       Expr b = e[1];
01495 
01496       // Constant division
01497       if (a.getOpKind() == BVCONST && b.getOpKind() == BVCONST) {
01498           res = d_rules->bvURemConst(e);
01499           break;
01500       }
01501 
01502         res = d_rules->bvURemRewrite(e);
01503         res = transitivityRule(res, theoryCore()->simplify(res.getRHS()));
01504 
01505       break;
01506     }
01507     case BVSREM:
01508       res = d_rules->bvSRemRewrite(e);
01509       res = transitivityRule(res, simplify(res.getRHS()));
01510       break;
01511     case BVSMOD:
01512       res = d_rules->bvSModRewrite(e);
01513       res = transitivityRule(res, simplify(res.getRHS()));
01514       break;
01515     case BVLT:
01516     case BVLE: {
01517       Expr lhs = e[0];
01518       Expr rhs = e[1];
01519       if (BVSize(lhs) != BVSize(rhs)) {
01520         res = d_rules->padBVLTRule(e, BVSize(lhs) > BVSize(rhs) ? BVSize(lhs) : BVSize(rhs));
01521         res = transitivityRule(res, simplify(res.getRHS()));
01522       }
01523       else {
01524         if(lhs == rhs)
01525           res = d_rules->lhsEqRhsIneqn(e, e.getOpKind());
01526         else if (BVCONST == lhs.getKind() && BVCONST == rhs.getKind())
01527           res = d_rules->bvConstIneqn(e, e.getOpKind());
01528         else if (e.getOpKind() == BVLE && BVCONST == lhs.getKind() && computeBVConst(lhs) == 0)
01529           res = d_rules->zeroLeq(e);
01530       }
01531       break;
01532     }
01533 
01534     case BVGT:
01535     case BVGE:
01536       FatalAssert(false, "Should be eliminated at parse-time");
01537       break;
01538 
01539     case BVSLT:
01540     case BVSLE:{
01541       /*! input: e0 <=(s) e1. output depends on whether the topbits(MSB) of
01542        *  e0 and e1 are constants. If they are constants then optimizations
01543        *  are done. In general, the following rule is implemented.
01544        * Step1:
01545        *                    e0 <=(s) e1
01546        *                       <==>
01547        *                 pad(e0) <=(s) pad(e1)
01548        * Step2:
01549        *                 pad(e0) <=(s) pad(e1)
01550        *                       <==>
01551        *             (e0[n-1] AND NOT e1[n-1]) OR
01552        *             (e0[n-1] = e1[n-1] AND e0[n-2:0] <= e1[n-2:0])
01553        */
01554       int e0len = BVSize(e[0]);
01555       int e1len = BVSize(e[1]);
01556       int bvlength = e0len>=e1len ? e0len : e1len;
01557       //e0 <=(s) e1 <=> signpad(e0) <=(s) signpad(e1)
01558 
01559       std::vector<Theorem> thms;
01560       std::vector<unsigned> changed;
01561 
01562       //e0 <= e1 <==> pad(e0) <= pad(e1)
01563       Theorem thm = d_rules->padBVSLTRule(e, bvlength);
01564       Expr paddedE = thm.getRHS();
01565 
01566       //the rest of the code simply normalizes pad(e0) and pad(e1)
01567       Theorem thm0 = d_rules->signExtendRule(paddedE[0]);
01568       Expr rhs0 = thm0.getRHS();
01569       thm0 = transitivityRule(thm0, rewriteBV(rhs0, cache));
01570       if(thm0.getLHS() != thm0.getRHS()) {
01571         thms.push_back(thm0);
01572         changed.push_back(0);
01573       }
01574 
01575       Theorem thm1 = d_rules->signExtendRule(paddedE[1]);
01576       Expr rhs1 = thm1.getRHS();
01577       thm1 = transitivityRule(thm1, rewriteBV(rhs1, cache));
01578       if(thm1.getLHS() != thm1.getRHS()) {
01579         thms.push_back(thm1);
01580         changed.push_back(1);
01581       }
01582 
01583       if(changed.size() > 0) {
01584         thm0 = substitutivityRule(paddedE,changed,thms);
01585         thm0 = transitivityRule(thm, thm0);
01586       }
01587       else
01588         thm0 = reflexivityRule(e);
01589 
01590       //signpad(e0) <= signpad(e1)
01591       Expr thm0RHS = thm0.getRHS();
01592       DebugAssert(thm0RHS.getOpKind() == BVSLT ||
01593                   thm0RHS.getOpKind() == BVSLE,
01594                   "TheoryBitvector::RewriteBV");
01595       //signpad(e0)[bvlength-1:bvlength-1]
01596       const Expr MSB0 = newBVExtractExpr(thm0RHS[0],bvlength-1,bvlength-1);
01597       //signpad(e1)[bvlength-1:bvlength-1]
01598       const Expr MSB1 = newBVExtractExpr(thm0RHS[1],bvlength-1,bvlength-1);
01599       //rewritten MSB0
01600       const Theorem topBit0 = rewriteBV(MSB0, cache, 2);
01601       //rewritten MSB1
01602       const Theorem topBit1 = rewriteBV(MSB1, cache, 2);
01603       //compute e0 <=(s) e1 <==> signpad(e0) <=(s) signpad(e1) <==>
01604       //output as given above
01605       thm1 = d_rules->signBVLTRule(thm0RHS, topBit0, topBit1);
01606       thm1 = transitivityRule(thm1,simplify(thm1.getRHS()));
01607       res = transitivityRule(thm0,thm1);
01608       break;
01609     }
01610     case BVSGT:
01611     case BVSGE:
01612       FatalAssert(false, "Should be eliminated at parse-time");
01613       break;
01614     default:
01615       res = reflexivityRule(e);
01616       break;
01617   }
01618 
01619   if (res.isNull()) res = reflexivityRule(e);
01620 
01621   // Update cache
01622   cache[e] = res;
01623 
01624   TRACE("bitvector rewrite", "TheoryBitvector::rewriteBV => ",
01625   res.getExpr(), " }");
01626 
01627   return res;
01628 }
01629 
01630 
01631 Theorem TheoryBitvector::rewriteBV(const Expr& e, int n)
01632 {
01633   ExprMap<Theorem> cache;
01634   return rewriteBV(e, cache, n);
01635 }
01636 
01637 
01638 Theorem TheoryBitvector::rewriteBoolean(const Expr& e)
01639 {
01640   Theorem thm;
01641   switch (e.getKind()) {
01642   case NOT:
01643     if (e[0].isTrue())
01644       thm = getCommonRules()->rewriteNotTrue(e);
01645     else if (e[0].isFalse())
01646       thm = getCommonRules()->rewriteNotFalse(e);
01647     else if (e[0].isNot())
01648       thm = getCommonRules()->rewriteNotNot(e);
01649     break;
01650   case IFF: {
01651     thm = getCommonRules()->rewriteIff(e);
01652     const Expr& rhs = thm.getRHS();
01653     // The only time we need to rewrite the result (rhs) is when
01654     // e==(FALSE<=>e1) or (e1<=>FALSE), so rhs==!e1.
01655     if (e != rhs && rhs.isNot())
01656       thm = transitivityRule(thm, rewriteBoolean(rhs));
01657     break;
01658   }
01659   case AND:{
01660     std::vector<Theorem> newK;
01661     std::vector<unsigned> changed;
01662     unsigned count(0);
01663     for(Expr::iterator ii=e.begin(),iiend=e.end();ii!=iiend;ii++,count++) {
01664       Theorem temp = rewriteBoolean(*ii);
01665       if(temp.getLHS() != temp.getRHS()) {
01666   newK.push_back(temp);
01667   changed.push_back(count);
01668       }
01669     }
01670     if(changed.size() > 0) {
01671       Theorem res = substitutivityRule(e,changed,newK);
01672       thm = transitivityRule(res, rewriteAnd(res.getRHS()));
01673     } else
01674       thm = rewriteAnd(e);
01675   }
01676     break;
01677   case OR:{
01678     std::vector<Theorem> newK;
01679     std::vector<unsigned> changed;
01680     unsigned count(0);
01681     for(Expr::iterator ii=e.begin(),iiend=e.end();ii!=iiend;ii++,count++) {
01682       Theorem temp = rewriteBoolean(*ii);
01683       if(temp.getLHS() != temp.getRHS()) {
01684   newK.push_back(temp);
01685   changed.push_back(count);
01686       }
01687     }
01688     if(changed.size() > 0) {
01689       Theorem res = substitutivityRule(e,changed,newK);
01690       thm = transitivityRule(res, rewriteOr(res.getRHS()));
01691     } else
01692       thm = rewriteOr(e);
01693   }
01694     break;
01695 
01696   default:
01697     break;
01698   }
01699   if(thm.isNull()) thm = reflexivityRule(e);
01700 
01701   return thm;
01702 }
01703 
01704 
01705 ///////////////////////////////////////////////////////////////////////////////
01706 // TheoryBitvector Public Methods                                            //
01707 ///////////////////////////////////////////////////////////////////////////////
01708 TheoryBitvector::TheoryBitvector(TheoryCore* core)
01709   : Theory(core, "Bitvector"),
01710     d_bvDelayEq(core->getStatistics().counter("bv delayed assert eqs")),
01711     d_bvAssertEq(core->getStatistics().counter("bv eager assert eqs")),
01712     d_bvDelayDiseq(core->getStatistics().counter("bv delayed assert diseqs")),
01713     d_bvAssertDiseq(core->getStatistics().counter("bv eager assert diseqs")),
01714     d_bvTypePreds(core->getStatistics().counter("bv type preds enqueued")),
01715     d_bvDelayTypePreds(core->getStatistics().counter("bv type preds delayed")),
01716     d_bvBitBlastEq(core->getStatistics().counter("bv bitblast eqs")),
01717     d_bvBitBlastDiseq(core->getStatistics().counter("bv bitblast diseqs")),
01718     d_bv32Flag(&(core->getFlags()["bv32-flag"].getBool())),
01719     d_bitvecCache(core->getCM()->getCurrentContext()),
01720     d_eq(core->getCM()->getCurrentContext()),
01721     d_eqPending(core->getCM()->getCurrentContext()),
01722     d_eq_index(core->getCM()->getCurrentContext(), 0, 0),
01723     d_bitblast(core->getCM()->getCurrentContext()),
01724     d_bb_index(core->getCM()->getCurrentContext(), 0, 0),
01725     d_sharedSubterms(core->getCM()->getCurrentContext()),
01726     d_sharedSubtermsList(core->getCM()->getCurrentContext()),
01727     d_maxLength(0),
01728     d_index1(core->getCM()->getCurrentContext(), 0, 0),
01729     d_index2(core->getCM()->getCurrentContext(), 0, 0)
01730     //    d_solvedEqSet(core->getCM()->getCurrentContext(), 0, 0)
01731 {
01732   getEM()->newKind(BITVECTOR, "_BITVECTOR", true);
01733   getEM()->newKind(BVCONST, "_BVCONST");
01734   getEM()->newKind(CONCAT, "_CONCAT");
01735   getEM()->newKind(EXTRACT, "_EXTRACT");
01736   getEM()->newKind(BOOLEXTRACT, "_BOOLEXTRACT");
01737   getEM()->newKind(LEFTSHIFT, "_LEFTSHIFT");
01738   getEM()->newKind(CONST_WIDTH_LEFTSHIFT, "_CONST_WIDTH_LEFTSHIFT");
01739   getEM()->newKind(RIGHTSHIFT, "_RIGHTSHIFT");
01740   getEM()->newKind(BVSHL, "_BVSHL");
01741   getEM()->newKind(BVLSHR, "_BVLSHR");
01742   getEM()->newKind(BVASHR, "_BVASHR");
01743   getEM()->newKind(SX,"_SX");
01744   getEM()->newKind(BVREPEAT,"_BVREPEAT");
01745   getEM()->newKind(BVZEROEXTEND,"_BVZEROEXTEND");
01746   getEM()->newKind(BVROTL,"_BVROTL");
01747   getEM()->newKind(BVROTR,"_BVROTR");
01748   getEM()->newKind(BVAND, "_BVAND");
01749   getEM()->newKind(BVOR, "_BVOR");
01750   getEM()->newKind(BVXOR, "_BVXOR");
01751   getEM()->newKind(BVXNOR, "_BVXNOR");
01752   getEM()->newKind(BVNEG, "_BVNEG");
01753   getEM()->newKind(BVNAND, "_BVNAND");
01754   getEM()->newKind(BVNOR, "_BVNOR");
01755   getEM()->newKind(BVCOMP, "_BVCOMP");
01756   getEM()->newKind(BVUMINUS, "_BVUMINUS");
01757   getEM()->newKind(BVPLUS, "_BVPLUS");
01758   getEM()->newKind(BVSUB, "_BVSUB");
01759   getEM()->newKind(BVMULT, "_BVMULT");
01760   getEM()->newKind(BVUDIV, "_BVUDIV");
01761   getEM()->newKind(BVSDIV, "_BVSDIV");
01762   getEM()->newKind(BVUREM, "_BVUREM");
01763   getEM()->newKind(BVSREM, "_BVSREM");
01764   getEM()->newKind(BVSMOD, "_BVSMOD");
01765   getEM()->newKind(BVLT, "_BVLT");
01766   getEM()->newKind(BVLE, "_BVLE");
01767   getEM()->newKind(BVGT, "_BVGT");
01768   getEM()->newKind(BVGE, "_BVGE");
01769   getEM()->newKind(BVSLT, "_BVSLT");
01770   getEM()->newKind(BVSLE, "_BVSLE");
01771   getEM()->newKind(BVSGT, "_BVSGT");
01772   getEM()->newKind(BVSGE, "_BVSGE");
01773   getEM()->newKind(INTTOBV, "_INTTOBV");
01774   getEM()->newKind(BVTOINT, "_BVTOINT");
01775   getEM()->newKind(BVTYPEPRED, "_BVTYPEPRED");
01776 
01777   std::vector<int> kinds;
01778   kinds.push_back(BITVECTOR);
01779   kinds.push_back(BVCONST);
01780   kinds.push_back(CONCAT);
01781   kinds.push_back(EXTRACT);
01782   kinds.push_back(BOOLEXTRACT);
01783   kinds.push_back(LEFTSHIFT);
01784   kinds.push_back(CONST_WIDTH_LEFTSHIFT);
01785   kinds.push_back(RIGHTSHIFT);
01786   kinds.push_back(BVSHL);
01787   kinds.push_back(BVLSHR);
01788   kinds.push_back(BVASHR);
01789   kinds.push_back(SX);
01790   kinds.push_back(BVREPEAT);
01791   kinds.push_back(BVZEROEXTEND);
01792   kinds.push_back(BVROTL);
01793   kinds.push_back(BVROTR);
01794   kinds.push_back(BVAND);
01795   kinds.push_back(BVOR);
01796   kinds.push_back(BVXOR);
01797   kinds.push_back(BVXNOR);
01798   kinds.push_back(BVNEG);
01799   kinds.push_back(BVNAND);
01800   kinds.push_back(BVNOR);
01801   kinds.push_back(BVCOMP);
01802   kinds.push_back(BVUMINUS);
01803   kinds.push_back(BVPLUS);
01804   kinds.push_back(BVSUB);
01805   kinds.push_back(BVMULT);
01806   kinds.push_back(BVUDIV);
01807   kinds.push_back(BVSDIV);
01808   kinds.push_back(BVUREM);
01809   kinds.push_back(BVSREM);
01810   kinds.push_back(BVSMOD);
01811   kinds.push_back(BVLT);
01812   kinds.push_back(BVLE);
01813   kinds.push_back(BVGT);
01814   kinds.push_back(BVGE);
01815   kinds.push_back(BVSLT);
01816   kinds.push_back(BVSLE);
01817   kinds.push_back(BVSGT);
01818   kinds.push_back(BVSGE);
01819   kinds.push_back(INTTOBV);
01820   kinds.push_back(BVTOINT);
01821   kinds.push_back(BVTYPEPRED);
01822 
01823   registerTheory(this, kinds);
01824 
01825   d_bvConstExprIndex = getEM()->registerSubclass(sizeof(BVConstExpr));
01826 
01827   // Cache constants 0bin0 and 0bin1
01828   vector<bool> bits(1);
01829   bits[0]=false;
01830   d_bvZero = newBVConstExpr(bits);
01831   bits[0]=true;
01832   d_bvOne = newBVConstExpr(bits);
01833 
01834   // Instantiate the rules after all expression creation is
01835   // registered, since the constructor creates some bit-vector
01836   // expressions.
01837   d_rules = createProofRules();
01838 }
01839 
01840 
01841 // Destructor: delete the proof rules class if it's present
01842 TheoryBitvector::~TheoryBitvector() {
01843   if(d_rules != NULL) delete d_rules;
01844 }
01845 
01846 
01847 // Main theory API
01848 
01849 
01850 void TheoryBitvector::addSharedTerm(const Expr& e)
01851 {
01852 }
01853 
01854 
01855 /*Modified by Lorenzo PLatania*/
01856 
01857 // solvable fact (e.g. solvable equations) are added to d_eq CDList,
01858 // all the others have to be in a different CDList. If the equation is
01859 // solvable it comes here already solved. Should distinguish between
01860 // solved and not solved eqs
01861 void TheoryBitvector::assertFact(const Theorem& e)
01862 {
01863   const Expr& expr = e.getExpr();
01864   TRACE("bvAssertFact", "TheoryBitvector::assertFact(", e.getExpr().toString(), ")");
01865   //  cout<<"TheoryBitvector::assertFact, expr: "<<expr.toString()<<endl;
01866   // every time a new fact is added to the list the whole set may be
01867   // not in a solved form
01868 
01869   switch (expr.getOpKind()) {
01870 
01871     case BVTYPEPRED:
01872       assertTypePred(expr[0], e);
01873       break;
01874 
01875     case BOOLEXTRACT:
01876       // facts form the SAT solver are just ignored
01877       return;
01878 
01879     case NOT:
01880       // facts form the SAT solver are just ignored
01881       if (expr[0].getOpKind() == BOOLEXTRACT) return;
01882 
01883       if (expr[0].getOpKind() == BVTYPEPRED) {
01884         Expr tpExpr = getTypePredExpr(expr[0]);
01885         Theorem tpThm = typePred(tpExpr);
01886         DebugAssert(tpThm.getExpr() == expr[0], "Expected BVTYPEPRED theorem");
01887         setInconsistent(getCommonRules()->contradictionRule(tpThm, e));
01888         return;
01889       }
01890 
01891       DebugAssert(expr[0].isEq(), "Unexpected negation");
01892 
01893       d_bitblast.push_back(e);
01894       break;
01895 
01896     case EQ:
01897       // Updates are also ignored:
01898       // Note: this can only be true if this fact was asserted as a result of
01899       // assertEqualities.  For BV theory, this should only be possible if
01900       // the update was made from our own theory, so we can ignore it.
01901       if (theoryCore()->inUpdate()) return;
01902 
01903       // If we have already started bitblasting, just store the eq in d_bitblast;
01904       // if we haven't yet bitblasted and expr is a solved linear equation then
01905       // we store it in d_eq CDList, otherwise we store it in d_eqPending
01906       if (d_bb_index != 0) {
01907         d_bitblast.push_back(e);
01908       }
01909       else if (isLeaf(expr[0]) && !isLeafIn(expr[0], expr[1])) {
01910         d_eq.push_back( e );
01911       }
01912       else {
01913         d_eqPending.push_back( e );
01914       }
01915       break;
01916 
01917     default:
01918       // if the fact is not an equation it will be bit-blasted
01919       d_bitblast.push_back( e );
01920       break;
01921   }
01922 }
01923 
01924 
01925 //TODO: can we get rid of this in exchange for a more general politeness-based sharing mechanism?
01926 void TheoryBitvector::assertTypePred(const Expr& e, const Theorem& pred) {
01927   // Ignore bitvector constants (they always satisfy type predicates)
01928   // and bitvector operators.  When rewrites and updates are enabled.
01929   // their type predicates will be implicitly derived from the type
01930   // predicates of the arguments.
01931 
01932   if (theoryOf(e) == this) return;
01933   TRACE("bvAssertTypePred", "TheoryBitvector::assertTypePred(", e.toString(PRESENTATION_LANG), ")");
01934   addSharedTerm(e);
01935 }
01936 
01937 
01938 /*Beginning of Lorenzo PLatania's methods*/
01939 
01940 // evaluates the gcd of two integers using
01941 // Euclid algorithm
01942 // int TheoryBitvector::gcd(int c1, int c2)
01943 // {
01944 //   if(c2==0)
01945 //     return c1;
01946 //   else
01947 //     return gcd( c2, c1%c2);
01948 // }
01949 
01950 void TheoryBitvector::extract_vars(const Expr& e, vector<Expr>& result)
01951 {
01952   if (e.getOpKind() == BVMULT ) {
01953     extract_vars(e[0], result);
01954     extract_vars(e[1], result);
01955   }
01956   else {
01957     DebugAssert(e.getOpKind() != BVCONST &&
01958                 e.getOpKind() != BVUMINUS &&
01959                 e.getOpKind() != BVPLUS, "Unexpected structure");
01960     result.push_back(e);
01961   }
01962 }
01963 
01964 
01965 Expr TheoryBitvector::multiply_coeff( Rational mult_inv, const Expr& e)
01966 {
01967 
01968   // nothing to be done
01969   if( mult_inv == 1)
01970     return e;
01971   if(e.isEq())
01972     {
01973       Expr lhs = e[0];
01974       Expr rhs = e[1];
01975       Expr new_lhs = multiply_coeff( mult_inv, lhs);
01976       Expr new_rhs = multiply_coeff( mult_inv, rhs);
01977       Expr res(EQ, new_lhs, new_rhs);
01978       return res;
01979     }
01980   else
01981     {
01982       int kind = e.getOpKind();
01983       int size = BVSize(e);
01984       if( kind == BVMULT )
01985   {
01986 
01987     //lhs is like 'a_0*x_0'
01988     Rational new_coeff = mult_inv * computeBVConst( e[0] );
01989     Expr new_expr_coeff = newBVConstExpr( new_coeff, size);
01990     Expr BV_one = newBVConstExpr(1,size);
01991       if( new_expr_coeff == BV_one )
01992       {
01993         return e[1];
01994       }
01995     else
01996       {
01997         return newBVMultExpr( size, new_expr_coeff, e[1]);
01998       }
01999   }
02000       else
02001   if( kind == BVPLUS)
02002     {
02003 
02004       int expr_arity= e.arity();
02005       std::vector<Expr> tmp_list;
02006       for( int i = 0; i < expr_arity; ++i)
02007         {
02008     tmp_list.push_back(multiply_coeff( mult_inv, e[i]));
02009         }
02010 //      Expr::iterator i = e.begin();
02011 //      int index;
02012 //      Expr::iterator end = e.end();
02013 //      std::vector<Expr> tmp_list;
02014 //      for( i = e.begin(), index=0; i!=end; ++i, ++index)
02015 //        {
02016 //    tmp_list.push_back(multiply_coeff( mult_inv, *i));
02017 //        }
02018       return newBVPlusExpr(size, tmp_list);
02019     }
02020   else
02021     if( kind == BVCONST )
02022       {
02023 
02024         Rational new_const = mult_inv * computeBVConst(e);
02025         Expr res = newBVConstExpr( new_const, size);
02026               //        cout<<res.toString()+"\n";
02027         return res;
02028       }
02029     else
02030       if( isLeaf( e ) )
02031         {
02032     //lhs is like 'x_0'
02033     // need to know the lenght of the var
02034     // L:: guess it is not correct, mult_inv * e
02035     Expr BV_mult_inv = newBVConstExpr( mult_inv, size);
02036     Expr new_var = newBVMultExpr( size, BV_mult_inv, e);
02037 
02038     return new_var;
02039         }
02040       else
02041         {
02042     return e;
02043         }
02044     }
02045 }
02046 
02047 // L::return the index of the minimum element returns -1 if the list
02048 // is empty assuming only non-negative elements to be sostituted with
02049 // some debug assertion. ***I guess n_bits can be just an integer, no
02050 // need to declare it as a Rational
02051 
02052 Rational TheoryBitvector::multiplicative_inverse(Rational r, int n_bits)
02053 {
02054 
02055   //  cout<<"TheoryBitvector::multiplicative_inverse: working on "<<r.toString()<<endl;
02056   Rational i=r;
02057   Rational max_val= pow( n_bits, (Rational) 2);
02058   while(r!=1)
02059     {
02060       r = ( r*r ) % max_val;
02061       i = ( i*r ) % max_val;
02062     }
02063   //  cout<<"TheoryBitvector::multiplicative_inverse: result is "<<i.toString()<<endl;
02064   return i;
02065 }
02066 
02067 // int TheoryBitvector::min(std::vector<Rational> list)
02068 // {
02069 //   int res = 0;
02070 //   int i;
02071 //   int size = list.size();
02072 //   for(i = 0; i < size; ++i)
02073 //     {
02074 //       cout<<"list["<<i<<"]: "<<list[i]<<endl;
02075 //     }
02076 //   for(i = 1; i < size; ++i)
02077 //     {
02078 //       if(list[res]>list[i])
02079 //  res=i;
02080 //       cout<<"res: "<<res<<endl;
02081 //       cout<<"min: "<<list[res]<<endl;
02082 //     }
02083 
02084 //   cout<<"min: "<<res<<endl;
02085 //   return res;
02086 // }
02087 
02088 //***************************
02089 // ecco come fare il delete!
02090 //***************************
02091 
02092 // int main ()
02093 // {
02094 //   unsigned int i;
02095 //   deque<unsigned int> mydeque;
02096 
02097 //   // set some values (from 1 to 10)
02098 //   for (i=1; i<=10; i++) mydeque.push_back(i);
02099 
02100 //   // erase the 6th element
02101 //   mydeque.erase (mydeque.begin()+5);
02102 
02103 //   // erase the first 3 elements:
02104 //   mydeque.erase (mydeque.begin(),mydeque.begin()+3);
02105 
02106 //   cout << "mydeque contains:";
02107 //   for (i=0; i<mydeque.size(); i++)
02108 //     cout << " " << mydeque[i];
02109 //   cout << endl;
02110 
02111 //   return 0;
02112 // }
02113 
02114 // use the method in rational.h
02115 // it uses std::vector<Rational> instead of std::deque<int>
02116 // int TheoryBitvector::gcd(std::deque<int> coeff_list)
02117 // {
02118 
02119 //   cout<<"TheoryBitvector::gcd: begin\n";
02120 //   for(unsigned int i=0; i<coeff_list.size(); ++i)
02121 //     {
02122 //       cout<<"coeff_list["<<i<<"]: "<<coeff_list[i]<<endl;
02123 //     }
02124 //   int gcd_list;
02125 //   int min_index = min(coeff_list);
02126 //   int min_coeff_1 = coeff_list[min_index];
02127 //   cout<<"erasing element: "<<coeff_list[min_index];
02128 //   coeff_list.erase( coeff_list.begin() + min_index );
02129 
02130 //   while(coeff_list.size()>0)
02131 //     {
02132 //       min_index = min(coeff_list);
02133 //       int min_coeff_2 = coeff_list[min_index];
02134 //       cout<<"erasing element: "<<coeff_list[min_index];
02135 //       coeff_list.erase( coeff_list.begin() + min_index );
02136 
02137 //       // save one recursion
02138 //       gcd_list = gcd( min_coeff_2, min_coeff_1);
02139 //       cout<<"TheoryBitvector::gcd: erased min1\n";
02140 //       min_coeff_1 = gcd_list;
02141 //     }
02142 //   cout<<"gcd_list: "<<gcd_list<<endl;
02143 //   return gcd_list;
02144 // }
02145 
02146 // int TheoryBitvector::bv2int(const Expr& e)
02147 // {
02148 //   int sum=0;
02149 //   if(e.arity()==0 && ! e.isVar())
02150 //     {
02151 //       std::string tmp = e.toString();
02152 //       int s_length = tmp.length();
02153 //       int bit;
02154 //       int exp;
02155 //       // first 4 cells contains the bv prefix 0bin
02156 //       // just discard them
02157 //       for(int i=3; i < s_length; ++i)
02158 //  {
02159 //    if(tmp[i]=='1')
02160 //      {
02161 //        sum += (int)std::pow((float) 2, s_length - 1 - i);
02162 //      }
02163 //  }
02164 //     }
02165 //   else
02166 //     {
02167 //       cerr<<"error: non-constant to be converted\n";
02168 //     }
02169 //   return sum;
02170 // }
02171 
02172 // returning the position of the first odd coefficient found;
02173 // moreover, it multiplies a variable which does not appear in other
02174 // subterms. It assumes that the input expression has already been
02175 // canonized, so the lhs is a flat BVPLUS expression and the rhs is a
02176 // zero BVCONST
02177 
02178 Rational TheoryBitvector::Odd_coeff( const Expr& e )
02179 {
02180   int bv_size =  BVSize(e[0]);
02181   Expr bv_zero( newBVZeroString(bv_size));
02182 
02183   DebugAssert(e.getOpKind()==EQ && e[1] == bv_zero,
02184         "TheoryBitvector::Odd_coeff: the input expression has a non valid form ");
02185 
02186   Expr lhs = e[0];
02187   if( lhs.getOpKind() == BVMULT )
02188     {
02189       if( lhs[0].getOpKind() == BVCONST && computeBVConst( lhs[0]) % 2 != 0)
02190   return computeBVConst( lhs[0] );
02191     }
02192   else
02193     if( isLeaf( lhs))
02194       return 1;
02195     else
02196       if( lhs.getOpKind() == BVPLUS )
02197   {
02198     int lhs_arity = lhs.arity();
02199     // scanning lhs in order to find a good odd coefficient
02200     for( int i = 0; i < lhs_arity; ++i)
02201       {
02202         // checking that the subterm is a leaf
02203         if( isLeaf( lhs[i] ) )
02204     {
02205       // checking that the current subterm does not appear in other
02206       // subterms
02207       for( int j = 0; j < lhs_arity; ++j)
02208         if( j != i && !isLeafIn( lhs[i], lhs[j] ))
02209           return 1;
02210     }
02211         else
02212     if( lhs[i].getOpKind() == BVMULT)
02213       {
02214         // the subterm is a BVMULT with a odd coefficient
02215         if( lhs[i][0].getOpKind() == BVCONST && computeBVConst( lhs[i][0]) % 2 != 0)
02216           {
02217       // checking that the current subterm does not appear in other
02218       // subterms
02219       int flag = 0;
02220       for( int j = 0; j < lhs_arity; ++j)
02221         {
02222           // as we can solve also for non-leaf terms we use
02223           // isTermIn instead of isLeafIn
02224           if( j != i && isTermIn( lhs[i][1], lhs[j] ))
02225             flag = 1;
02226         }
02227       // if the leaf is not a subterm of other terms in the
02228       // current expression then we can solve for it
02229       if( flag == 0)
02230         return computeBVConst( lhs[i][0] );
02231           }
02232       }
02233     else
02234       // the subterm is a non-linear one
02235       if ( lhs[i].getOpKind() != BVCONST )
02236         {
02237           // checking that the current subterm does not appear in other
02238           // subterms
02239           for( int j = 0; j < lhs_arity; ++j)
02240       if( j != i && !isLeafIn( lhs[i][1], lhs[j] ))
02241         return 1;
02242         }
02243       else
02244         ;
02245       }
02246   }
02247   // no leaf found to solve for
02248   return 0;
02249 }
02250 
02251 int TheoryBitvector::check_linear( const Expr &e )
02252 {
02253   TRACE("bv_check_linear", "TheoryBitvector::check_linear(", e.toString(PRESENTATION_LANG), ")");
02254   // recursively check if the expression is linear
02255   if( e.isVar() || e.getOpKind() == BVCONST )
02256     return 1;
02257   else
02258     if( e.getOpKind() == BVPLUS )
02259       {
02260   int e_arity= e.arity();
02261   int flag = 1;
02262   for( int i=0; i < e_arity && flag == 1; ++i)
02263     {
02264       flag = check_linear( e[i]);
02265     }
02266   return flag;
02267       }
02268     else
02269       if( e.getOpKind() == BVMULT)
02270   {
02271     if( e[0].getOpKind() == BVCONST && e[1].isVar() )
02272       return 1;
02273     else
02274       return 0;
02275   }
02276       else
02277   if( e.getOpKind() == BVUMINUS)
02278     return check_linear( e[0]);
02279   else
02280     if( e.getOpKind() == EQ )
02281       return ( check_linear( e[0] ) && check_linear( e[1] ));
02282     else
02283       // all other operators are non-linear
02284       return 0;
02285 }
02286 
02287 // please check it is right. It is the same as Theory::isLeafIn but it
02288 // does not require e1 to be a leaf. In this way we can check for e1
02289 // to be a subterm of other expressions even if it is not a leaf,
02290 // i.e. a non-linear term
02291 bool TheoryBitvector::isTermIn(const Expr& e1, const Expr& e2)
02292 {
02293   if (e1 == e2) return true;
02294   if (theoryOf(e2) != this) return false;
02295   for(Expr::iterator i=e2.begin(), iend=e2.end(); i != iend; ++i)
02296     if (isTermIn(e1, *i)) return true;
02297   return false;
02298 }
02299 
02300 // checks whether e can be solved in term
02301 bool TheoryBitvector::canSolveFor( const Expr& term, const Expr& e )
02302 {
02303   DebugAssert( e.getOpKind() == EQ, "TheoryBitvector::canSolveFor, input 'e' must be an equation");
02304 
02305   //  cout<<"TheoryBitvector::canSolveFor, term: "<<term.toString()<<endl;
02306   // the term has not a unary coefficient, so we did not multiply the
02307   // equation by its multiplicative inverse
02308   if( term.getOpKind() == BVMULT && term[0].getOpKind() == BVCONST)
02309     return 0;
02310   else
02311     if( isLeaf( term ) || !isLinearTerm( term))
02312       {
02313   int count = countTermIn( term, e);
02314         //  cout<<"TheoryBitvector::canSolveFor, count for "<<term.toString()<<" is: "<<count<<endl;
02315   if( count == 1)
02316     return true;
02317   else
02318     return false;
02319       }
02320     else
02321       {
02322   DebugAssert( false, "TheoryBitvector::canSolveFor, input 'term' of not treated kind");
02323   return false;
02324       }
02325 }
02326 
02327 int TheoryBitvector::countTermIn( const Expr& term, const Expr& e)
02328 {
02329   //  cout<<"TheoryBitvector::countTermIn, term: "<<term.toString()<<" e: "<<e.toString()<<endl;
02330   int e_arity = e.arity();
02331   int result = 0;
02332   // base cases recursion happen when e is a constant or a leaf
02333   if( e.getOpKind() == BVCONST )
02334     return 0;
02335   if( term ==  e )
02336     return 1;
02337 
02338   for( int i = 0; i < e_arity; ++i)
02339     {
02340       result += countTermIn( term, e[i]);
02341     }
02342   return result;
02343 }
02344 
02345 bool TheoryBitvector::isLinearTerm( const Expr& e )
02346 {
02347   if( isLeaf( e ) )
02348     return true;
02349   switch( e.getOpKind())
02350     {
02351     case BVPLUS:
02352       return true;
02353     case BVMULT:
02354       if( e[0].getOpKind() == BVCONST && isLinearTerm( e[1] ))
02355   return true;
02356       else
02357   return false;
02358       break;
02359     default:
02360       return false;
02361     }
02362 }
02363 
02364 
02365 // returns thm if no change
02366 Theorem TheoryBitvector::simplifyPendingEq(const Theorem& thm, int maxEffort)
02367 {
02368   Expr e = thm.getExpr();
02369   DebugAssert(e.getKind() == EQ, "Expected EQ");
02370   Expr lhs = e[0];
02371   Expr rhs = e[1];
02372 
02373   Theorem thm2 = thm;
02374   if (!isLeaf(lhs)) {
02375     // Carefully simplify lhs:
02376     // We can't take find(lhs) because find(lhs) = find(rhs) and this would result in a trivially true equation.
02377     // So, take the find of the children instead.
02378     int ar = lhs.arity();
02379     vector<Theorem> newChildrenThm;
02380     vector<unsigned> changed;
02381     Theorem thm0;
02382     for (int k = 0; k < ar; ++k) {
02383       thm0 = find(lhs[k]);
02384       if (thm0.getLHS() != thm0.getRHS()) {
02385         newChildrenThm.push_back(thm0);
02386         changed.push_back(k);
02387       }
02388     }
02389     if(changed.size() > 0) {
02390       // lhs = updated_lhs
02391       thm0 = substitutivityRule(lhs, changed, newChildrenThm);
02392       // lhs = updated_and_rewritten_lhs
02393       thm0 = transitivityRule(thm0, rewrite(thm0.getRHS()));
02394       // updated_and_rewritten_lhs = rhs
02395       thm2 = transitivityRule(symmetryRule(thm0), thm);
02396     }
02397   }
02398   // updated_and_rewritten_lhs = find(rhs)
02399   thm2 = transitivityRule(thm2, find(rhs));
02400   // canonized EQ
02401   thm2 = iffMP(thm2, d_rules->canonBVEQ(thm2.getExpr(), maxEffort));
02402   if (thm2.isRewrite() && thm2.getRHS() == lhs && thm2.getLHS() == rhs) {
02403     thm2 = thm;
02404   }
02405   return thm2;
02406 }
02407 
02408 
02409 Theorem TheoryBitvector::generalBitBlast( const Theorem& thm )
02410 {
02411   // cout<<"TheoryBitvector::generalBitBlast, thm: "<<thm.toString()<<" to expr(): "<<thm.getExpr().toString()<<endl;
02412   Expr e = thm.getExpr();
02413   switch (e.getOpKind()) {
02414     case EQ: {
02415       Theorem thm2 = simplifyPendingEq(thm, 6);
02416       const Expr& e2 = thm2.getExpr();
02417       switch (e2.getKind()) {
02418         case TRUE_EXPR:
02419         case FALSE_EXPR:
02420           return thm2;
02421         case EQ:
02422           return iffMP(thm2, bitBlastEqn(thm2.getExpr()));
02423         case AND: {
02424           DebugAssert(e2.arity() == 2 && e2[0].getKind() == EQ && e2[1].getKind() == EQ,
02425                       "Expected two equations");
02426           Theorem t1 = bitBlastEqn(e2[0]);
02427           Theorem t2 = bitBlastEqn(e2[1]);
02428           Theorem thm3 = substitutivityRule(e2, t1, t2);
02429           return iffMP(thm2, thm3);
02430         }
02431         default:
02432           FatalAssert(false, "Unexpected Expr");
02433           break;
02434       }
02435       break;
02436     }
02437     case BVLT:
02438     case BVLE: {
02439       // Carefully simplify
02440       int ar = e.arity();
02441       DebugAssert(ar == 2, "Expected arity 2");
02442       vector<Theorem> newChildrenThm;
02443       vector<unsigned> changed;
02444       Theorem thm0;
02445       for (int k = 0; k < ar; ++k) {
02446         thm0 = find(e[k]);
02447         if (thm0.getLHS() != thm0.getRHS()) {
02448           newChildrenThm.push_back(thm0);
02449           changed.push_back(k);
02450         }
02451       }
02452       if(changed.size() > 0) {
02453         // updated_e
02454         thm0 = iffMP(thm, substitutivityRule(e, changed, newChildrenThm));
02455         // updated_and_rewritten_e
02456         thm0 = iffMP(thm0, rewrite(thm0.getExpr()));
02457         if (thm0.getExpr().getOpKind() != e.getOpKind()) return thm0;
02458         return iffMP(thm0, bitBlastIneqn(thm0.getExpr()));
02459       }
02460       return iffMP(thm, bitBlastIneqn(e));
02461     }
02462     // a NOT should mean a disequality, as negation of inequalities
02463     // can be expressed as other inequalities.
02464     case NOT: {
02465       // Carefully simplify
02466       DebugAssert(e.arity() == 1, "Expected arity 1");
02467       DebugAssert(e[0].isEq(), "Expected disequality");
02468       DebugAssert(e[0].arity() == 2, "Expected arity 2");
02469       vector<Theorem> newChildrenThm;
02470       vector<unsigned> changed;
02471       Theorem thm0;
02472       for (int k = 0; k < 2; ++k) {
02473         thm0 = find(e[0][k]);
02474         if (thm0.getLHS() != thm0.getRHS()) {
02475           newChildrenThm.push_back(thm0);
02476           changed.push_back(k);
02477         }
02478       }
02479       if(changed.size() > 0) {
02480         // a = b <=> a' = b'
02481         thm0 = substitutivityRule(e[0], changed, newChildrenThm);
02482       }
02483       else thm0 = reflexivityRule(e[0]);
02484       // a = b <=> canonized EQ
02485       thm0 = transitivityRule(thm0, d_rules->canonBVEQ(thm0.getRHS(), 6));
02486       // NOT(canonized EQ)
02487       thm0 = iffMP(thm, substitutivityRule(e, thm0));
02488       if (thm0.getExpr()[0].isEq()) {
02489         return bitBlastDisEqn(thm0);
02490       }
02491       else return thm0;
02492     }
02493     default:
02494       FatalAssert(false, "TheoryBitvector::generalBitBlast: unknown expression kind");
02495       break;
02496   }
02497   return reflexivityRule( e );
02498 }
02499 /*End of Lorenzo PLatania's methods*/
02500 
02501 static Expr findAtom(const Expr& e)
02502 {
02503   if (e.isAbsAtomicFormula()) return e;
02504   for (int i = 0; i < e.arity(); ++i) {
02505     Expr e_i = findAtom(e[i]);
02506     if (!e_i.isNull()) return e_i;
02507   }
02508   return Expr();
02509 }
02510 
02511 
02512 bool TheoryBitvector::comparebv(const Expr& e1, const Expr& e2)
02513 {
02514   int size = BVSize(e1);
02515   FatalAssert(size == BVSize(e2), "expected same size");
02516   Theorem c1, c2;
02517   int idx1 = -1;
02518   vector<Theorem> thms1;
02519 
02520   if (d_bb_index == 0) {
02521     Expr splitter = e1.eqExpr(e2);
02522     Theorem thm = simplify(splitter);
02523     if (!thm.getRHS().isBoolConst()) {
02524       addSplitter(e1.eqExpr(e2));
02525       return true;
02526     }
02527     // Store a dummy theorem to indicate bitblasting has begun
02528     d_bb_index = 1;
02529     d_bitblast.push_back(getCommonRules()->trueTheorem());
02530   }
02531 
02532   for (int i = 0; i < size; ++i) {
02533     c1 = bitBlastTerm(e1, i);
02534     c1 = transitivityRule(c1, simplify(c1.getRHS()));
02535     c2 = bitBlastTerm(e2, i);
02536     c2 = transitivityRule(c2, simplify(c2.getRHS()));
02537     thms1.push_back(c1);
02538     if (!c1.getRHS().isBoolConst()) {
02539       if (idx1 == -1) idx1 = i;
02540       continue;
02541     }
02542     if (!c2.getRHS().isBoolConst()) {
02543       continue;
02544     }
02545     if (c1.getRHS() != c2.getRHS()) return false;
02546   }
02547   if (idx1 == -1) {
02548     // If e1 is known to be a constant, assert that
02549     DebugAssert(e1.getKind() != BVCONST, "Expected non-const");
02550     assertEqualities(d_rules->bitExtractAllToConstEq(thms1));
02551     addSplitter(e1.eqExpr(e2));
02552     //    enqueueFact(getCommonRules()->trueTheorem());
02553     return true;
02554   }
02555 
02556   Theorem thm = bitBlastEqn(e1.eqExpr(e2));
02557   thm = iffMP(thm, simplify(thm.getExpr()));
02558   if (!thm.getExpr().isTrue()) {
02559     enqueueFact(thm);
02560     return true;
02561   }
02562 
02563   // Nothing to assert from bitblasted equation.  Best way to resolve this
02564   // problem is to split until the term can be equated with a bitvector
02565   // constant.
02566   Expr e = findAtom(thms1[idx1].getRHS());
02567   DebugAssert(!e.isNull(), "Expected atom");
02568   addSplitter(e);
02569   return true;
02570 }
02571 
02572 static bool bvdump = false;
02573 
02574 void TheoryBitvector::checkSat(bool fullEffort)
02575 {
02576   if(fullEffort) {
02577 
02578   for (unsigned i = 0; i < additionalRewriteConstraints.size(); i ++)
02579     enqueueFact(additionalRewriteConstraints[i]);
02580   additionalRewriteConstraints.clear();
02581 
02582     if (bvdump) {
02583       CDList<Theorem>::const_iterator it_list=d_eq.begin();
02584       unsigned int i;
02585       for(i=0; i<d_eq.size(); ++i)
02586       {
02587         cout<<"d_eq [" << i << "]= "<< it_list[i].getExpr().toString() << endl;
02588       }
02589 
02590       it_list=d_eqPending.begin();
02591 
02592       for(i=0; i<d_eqPending.size(); ++i)
02593       {
02594         cout<<"d_eqPending [" << i << "]= "<< it_list[i].getExpr().toString() << endl;
02595       }
02596 
02597       it_list=d_bitblast.begin();
02598 
02599       for(i=0; i<d_bitblast.size(); ++i)
02600       {
02601         cout<<"d_bitblast [" << i << "]= "<< it_list[i].getExpr().toString() << endl;
02602       }
02603 
02604       if (d_eq.size() || d_eqPending.size() || d_bitblast.size()) cout << endl;
02605     }
02606 
02607     unsigned eq_list_size = d_eqPending.size();
02608     bool bitBlastEq = d_eq_index < eq_list_size;
02609     if (d_bb_index == 0 && bitBlastEq) {
02610       bitBlastEq = false;
02611       unsigned eqIdx = d_eq_index;
02612       for(; eqIdx < eq_list_size; ++eqIdx) {
02613         Expr eq = d_eqPending[eqIdx].getExpr();
02614         DebugAssert(eq[1] == newBVConstExpr(Rational(0), BVSize(eq[0])), "Expected 0 on rhs");
02615         Theorem thm = simplifyPendingEq(d_eqPending[eqIdx], 5);
02616         if (thm == d_eqPending[eqIdx]) {
02617           bitBlastEq = true;
02618           continue;
02619         }
02620         const Expr& e2 = thm.getExpr();
02621         switch (e2.getKind()) {
02622           case TRUE_EXPR:
02623             break;
02624           case FALSE_EXPR:
02625             enqueueFact(thm);
02626             return;
02627           case EQ:
02628           case AND:
02629             if (simplify(thm.getExpr()).getRHS() == trueExpr()) {
02630               bitBlastEq = true;
02631               break;
02632             }
02633             for (; d_eq_index < eqIdx; d_eq_index = d_eq_index + 1) {
02634               d_eqPending.push_back(d_eqPending[d_eq_index]);
02635             }
02636             d_eq_index = d_eq_index + 1;
02637             enqueueFact(thm);
02638             return;
02639           default:
02640             FatalAssert(false, "Unexpected expr");
02641             break;
02642         }
02643       }
02644     }
02645 
02646    // Bitblast any new formulas
02647     unsigned bb_list_size = d_bitblast.size();
02648     bool bbflag = d_bb_index < bb_list_size || bitBlastEq;
02649     if (bbflag) {
02650       for( ; d_bb_index < bb_list_size; d_bb_index = d_bb_index + 1) {
02651         Theorem bb_result = generalBitBlast( d_bitblast[ d_bb_index ]);
02652         enqueueFact( bb_result);
02653       }
02654       if (d_bb_index == 0) {
02655         // push dummy on the stack to indicate bitblasting has started
02656         d_bb_index = 1;
02657         d_bitblast.push_back(getCommonRules()->trueTheorem());
02658       }
02659       for( ; d_eq_index < eq_list_size; d_eq_index = d_eq_index + 1) {
02660         Theorem bb_result = generalBitBlast( d_eqPending[ d_eq_index ]);
02661         enqueueFact( bb_result);
02662       }
02663       // If newly bitblasted formulas, skip the shared term check
02664       return;
02665     }
02666   }
02667 }
02668 
02669 
02670 Theorem TheoryBitvector::rewrite(const Expr& e)
02671 {
02672   ExprMap<Theorem> cache;
02673   return rewriteBV(e, cache);
02674 }
02675 
02676 
02677 Theorem TheoryBitvector::rewriteAtomic(const Expr& e)
02678 {
02679   return reflexivityRule(e);
02680 }
02681 
02682 
02683 void TheoryBitvector::setup(const Expr& e)
02684 {
02685   int k(0), ar(e.arity());
02686   if( e.isTerm() ) {
02687     for ( ; k < ar; ++k) {
02688       e[k].addToNotify(this, e);
02689     }
02690   }
02691 }
02692 
02693 
02694 // Lorenzo's version
02695 void TheoryBitvector::update(const Theorem& e, const Expr& d) {
02696 
02697   if (inconsistent()) return;
02698   //  cout<<"TheoryBitvector::update, theorem e:"<<e.toString()<<" expression d: "<<d.toString()<<endl;
02699   // Updating shared terms informations, code inherited from the old
02700   // version of the bitvector theory
02701 
02702   // Constants should never change their find pointers to non-constant
02703   // expressions
02704   DebugAssert(e.getLHS().getOpKind()!=BVCONST,
02705         "TheoryBitvector::update(e="+e.getExpr().toString()
02706         +", d="+d.toString());
02707   if (d.isNull()) {
02708     Expr lhs = e.getLHS();
02709     Expr rhs = e.getRHS();
02710     DebugAssert(d_sharedSubterms.find(lhs) != d_sharedSubterms.end(),
02711                 "Expected lhs to be shared");
02712     CDMap<Expr,Expr>::iterator it = d_sharedSubterms.find(rhs);
02713     if (it == d_sharedSubterms.end()) {
02714       addSharedTerm(rhs);
02715     }
02716     return;
02717   }
02718 //  {
02719 //    // found an equality between shared subterms!
02720 //           bool changed = false;
02721 //    if ((*it).second != lhs) {
02722 //      lhs = (*it).second;
02723 //      it = d_sharedSubterms.find(lhs);
02724 //      DebugAssert(it != d_sharedSubterms.end() && (*it).second == lhs,
02725 //      "Invariant violated in TheoryBitvector::update");
02726 //             changed = true;
02727 //    }
02728 //    if ((*it2).second != rhs) {
02729 //             rhs = (*it2).second;
02730 //             it2 = d_sharedSubterms.find(rhs);
02731 //             DebugAssert(it2 != d_sharedSubterms.end() && (*it2).second == rhs,
02732 //                         "Invariant violated in TheoryBitvector::update");
02733 //             changed = true;
02734 //           }
02735 //    DebugAssert(findExpr(lhs) == e.getRHS() &&
02736 //          findExpr(rhs) == e.getRHS(), "Unexpected value for finds");
02737 //    // It may be needed to check whether the two terms are the
02738 //    // same, in that case don't do anything
02739 //           if (changed) {
02740 //             Theorem thm = transitivityRule(find(lhs),symmetryRule(find(rhs)));
02741 //             const Expr& expr = thm.getExpr();
02742 
02743 //             if (d_bb_index == 0 &&
02744 //                 isLeaf(expr[0]) && !isLeafIn(expr[0], expr[1])) {
02745 //               d_eq.push_back( thm );
02746 //             }
02747 //             else {
02748 //               d_bitblast.push_back( thm );
02749 //             }
02750 //           }
02751 
02752 
02753 //    // canonize and solve befor asserting it
02754 //    //    cout<<"TheoryBitvector::update, thm.getRHS(): "<<thm.getRHS()<<" thm.getLHS():"<<thm.getLHS()<<" thm.getExpr():"<<thm.getExpr()<<endl;
02755 //    Theorem rwt_thm = rewrite( thm.getExpr() );
02756 //    Theorem solved_thm = solve( rwt_thm);
02757 //    assertFact( solved_thm );
02758     //    assertFact( thm );
02759     //    enqueueFact(iffMP(thm, bitBlastEqn(thm.getExpr())));
02760 //  }
02761 //       else
02762 //  {
02763 //    d_sharedSubterms[rhs] = (*it).second;
02764 //  }
02765 //     }
02766   // Propagate the "find" information to all the terms in the notify
02767   // list of d
02768 
02769   // if d has no find there is nothing to be updated
02770   if (!d.hasFind()) return;
02771 
02772   if (find(d).getRHS() == d) {
02773 //     Theorem thm = updateSubterms(d);
02774 //     TRACE("bvupdate", "TheoryArithOld::update(): thm = ", thm, "");
02775 //     DebugAssert(leavesAreSimp(thm.getRHS()), "updateHelper error: "
02776 //      +thm.getExpr().toString());
02777     Theorem thm = simplify(d);
02778     if (thm.getRHS().isAtomic()) {
02779       assertEqualities(thm);
02780     }
02781     else {
02782       // Simplify could introduce case splits in the expression.  Handle this by renaminig
02783       Theorem renameTheorem = renameExpr(d);
02784       enqueueFact(transitivityRule(symmetryRule(renameTheorem), thm));
02785       assertEqualities(renameTheorem);
02786     }
02787   }
02788 }
02789 
02790 
02791 Theorem TheoryBitvector::updateSubterms( const Expr& e )
02792 {
02793   //  DebugAssert(canonRec(e).getRHS() == e, "canonSimp expects input to be canonized");
02794   int ar = e.arity();
02795   if (isLeaf(e)) return find(e);
02796   if (ar > 0) {
02797     vector<Theorem> newChildrenThm;
02798     vector<unsigned> changed;
02799     Theorem thm;
02800     for (int k = 0; k < ar; ++k) {
02801       thm = updateSubterms(e[k]);
02802       if (thm.getLHS() != thm.getRHS()) {
02803         newChildrenThm.push_back(thm);
02804         changed.push_back(k);
02805       }
02806     }
02807     if(changed.size() > 0) {
02808       thm = substitutivityRule(e, changed, newChildrenThm);
02809       thm = transitivityRule(thm, rewrite(thm.getRHS()));
02810       return transitivityRule(thm, find(thm.getRHS()));
02811     }
02812     else return find(e);
02813   }
02814   return find(e);
02815 }
02816 
02817 
02818 Theorem TheoryBitvector::solve(const Theorem& t)
02819 {
02820   DebugAssert(t.isRewrite() && t.getLHS().isTerm(), "");
02821   Expr e = t.getExpr();
02822 
02823   if (isLeaf(e[0]) && !isLeafIn(e[0], e[1])) {
02824     // already solved
02825     return t;
02826   }
02827   else if (isLeaf(e[1]) && !isLeafIn(e[1], e[0])) {
02828     return symmetryRule(t);
02829   }
02830   else if (e[0].getOpKind() == EXTRACT && isLeaf(e[0][0])) {
02831     bool solvedForm;
02832     Theorem thm;
02833     if (d_rules->solveExtractOverlapApplies(e))
02834     {
02835       thm = iffMP(t, d_rules->solveExtractOverlap(e));
02836       solvedForm = true;
02837     }
02838     else
02839       thm = d_rules->processExtract(t, solvedForm);
02840 
02841     thm = getCommonRules()->skolemize(thm);
02842 
02843     if (solvedForm) return thm;
02844     else {
02845       enqueueFact(getCommonRules()->andElim(thm, 1));
02846       return getCommonRules()->andElim(thm, 0);
02847     }
02848   }
02849   else if (e[1].getOpKind() == EXTRACT && isLeaf(e[1][0])) {
02850     bool solvedForm;
02851     Theorem thm = getCommonRules()->skolemize(d_rules->processExtract(symmetryRule(t), solvedForm));
02852     if (solvedForm) return thm;
02853     else {
02854       enqueueFact(getCommonRules()->andElim(thm, 1));
02855       return getCommonRules()->andElim(thm, 0);
02856     }
02857   }
02858 
02859   IF_DEBUG(
02860     Theorem t2 = iffMP(t, d_rules->canonBVEQ(e));
02861     if (e[0] < e[1]) {
02862       DebugAssert(e[1].getOpKind() == BVCONST,
02863                   "Should be only case when lhs < rhs");
02864       t2 = symmetryRule(t2);
02865     }
02866     DebugAssert(t2.getExpr() == e, "Expected no change");
02867   )
02868 
02869   if (e[0].getOpKind() == BVCONST) {
02870     DebugAssert(e[1].getOpKind() != BVCONST, "should not have const = const");
02871     return symmetryRule(t);
02872   }
02873   return t;
02874 }
02875 
02876 //   // solving just linear equations; for everything else I just return
02877 //   // the same expression
02878 //   if( ! e.isEq())
02879 //     {
02880 //       return reflexivityRule( e );
02881 //     }
02882 //   //the search for the odd coefficient should also check that the
02883 //   //multiplied term does not appear in other terms. The coefficient can
02884 //   //also multiply a non-linear term
02885 
02886 
02887 //   // L:: look for a odd coefficient, if one, then the eq is solvable
02888 //   // and we can find the mult-inverse using Barrett-Dill-Levitt
02889 //   Expr lhs = e[0];
02890 //   Expr::iterator it = lhs.begin(), iend = lhs.end();
02891 //   for (; it != iend; ++it) {
02892 //     switch ((*it).getOpKind()) {
02893 //       case BVCONST: continue;
02894 //       case BVMULT: {
02895 //         DebugAssert((*it).arity() == 2 &&
02896 //                     (*it)[0].getOpKind() == BVCONST &&
02897 //                     computeBVConst((*it)[0]) != 1, "Unexpected format");
02898 //         continue
02899 //   }
02900 
02901 //   coefficient = Odd_coeff( e );
02902 //   //  Rational odd_coeff = anyOdd( coeff );
02903 //   if( coefficient != 0)
02904 //     {
02905 //       // the equation is solvable
02906 //       cout<<"Odd coefficient found => the equation is solvable\n";
02907 //       if (coefficient != 1) {
02908 //         Rational mult_inv = multiplicative_inverse( coefficient, BVSize(e[0]));
02909 //         // multiply all the coefficients in the expression by the inverse
02910 //         //      Expr tmp_expr = e;
02911 //         e = multiply_coeff( mult_inv, e);
02912 //         //      Expr isolated_expr = isolate_var( new_expr);
02913 //       }
02914 
02915 //       Theorem solved_th = d_rules->isolate_var( t, e);
02916 //       cout<<"solved theorem: "<<solved_th.toString()<<endl;
02917 //       cout<<"solved theorem expr: "<<solved_th.getExpr().toString()<<endl;
02918 
02919 //       return iffMP( t, solved_th);
02920 //     }
02921 //   else
02922 //     {
02923 //       cout<<"Odd coefficient not found => the equation is not solvable\n";
02924 //       Theorem thm = d_rules->MarkNonSolvableEq( e );
02925 //       cout<<"TheoryBitvector::solve, input e: "<<e.toString()<<" thm: "<<thm.toString()<<endl;
02926 //       return iffMP( t, thm);
02927 //       //return reflexivityRule(e);
02928 //     }
02929 //}
02930 
02931 
02932 void TheoryBitvector::checkType(const Expr& e)
02933 {
02934   switch (e.getOpKind()) {
02935     case BITVECTOR:
02936       //TODO: check that this is a well-formed type
02937       break;
02938     default:
02939       FatalAssert(false, "Unexpected kind in TheoryBitvector::checkType"
02940                   +getEM()->getKindName(e.getOpKind()));
02941   }
02942 }
02943 
02944 
02945 Cardinality TheoryBitvector::finiteTypeInfo(Expr& e, Unsigned& n,
02946                                             bool enumerate, bool computeSize)
02947 {
02948   FatalAssert(e.getKind() == BITVECTOR,
02949               "Unexpected kind in TheoryBitvector::finiteTypeInfo");
02950   if (enumerate || computeSize) {
02951     int bitwidth = getBitvectorTypeParam(e);
02952     Rational max_val = pow( bitwidth, (Rational) 2);
02953 
02954     if (enumerate) {
02955       if (n < max_val.getUnsigned()) {
02956         e = newBVConstExpr(n, bitwidth);
02957       }
02958       else e = Expr();
02959     }
02960 
02961     if (computeSize) {
02962       n = max_val.getUnsignedMP();
02963     }
02964   }
02965   return CARD_FINITE;
02966 }
02967 
02968 
02969 void TheoryBitvector::computeType(const Expr& e)
02970 {
02971   if (e.isApply()) {
02972     switch(e.getOpKind()) {
02973       case BOOLEXTRACT: {
02974         if(!(1 == e.arity() &&
02975              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
02976           throw TypecheckException("Type Checking error:"\
02977                                    "attempted extraction from non-bitvector \n"+
02978                                    e.toString());
02979         int extractLength = getBoolExtractIndex(e);
02980         if(!(0 <= extractLength))
02981           throw TypecheckException("Type Checking error: \n"
02982                                    "attempted out of range extraction  \n"+
02983                                    e.toString());
02984         e.setType(boolType());
02985         break;
02986       }
02987       case BVMULT:{
02988         if(!(2 == e.arity() &&
02989              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() &&
02990              BITVECTOR == getBaseType(e[1]).getExpr().getOpKind()))
02991           throw TypecheckException
02992             ("Not a bit-vector expression in BVMULT:\n\n  "
02993              +e.toString());
02994         int bvLen = getBVMultParam(e);
02995         Type bvType = newBitvectorType(bvLen);
02996         e.setType(bvType);
02997         break;
02998       }
02999       case EXTRACT:{
03000         if(!(1 == e.arity() &&
03001              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03002           throw TypecheckException
03003             ("Not a bit-vector expression in bit-vector extraction:\n\n  "
03004              + e.toString());
03005         int bvLength = BVSize(e[0]);
03006         int leftExtract = getExtractHi(e);
03007         int rightExtract = getExtractLow(e);
03008         if(!(0 <= rightExtract &&
03009              rightExtract <= leftExtract && leftExtract < bvLength))
03010           throw TypecheckException
03011             ("Wrong bounds in bit-vector extract:\n\n  "+e.toString());
03012         int extractLength = leftExtract - rightExtract + 1;
03013         Type bvType = newBitvectorType(extractLength);
03014         e.setType(bvType);
03015         break;
03016       }
03017       case BVPLUS: {
03018         int bvPlusLength = getBVPlusParam(e);
03019         if(!(0 <= bvPlusLength))
03020           throw TypecheckException
03021             ("Bad bit-vector length specified in BVPLUS expression:\n\n  "
03022              + e.toString());
03023         for(Expr::iterator i=e.begin(), iend=e.end(); i != iend; ++i) {
03024           if(BITVECTOR != getBaseType(*i).getExpr().getOpKind())
03025             throw TypecheckException
03026               ("Not a bit-vector expression in BVPLUS:\n\n  "+e.toString());
03027         }
03028         Type bvType = newBitvectorType(bvPlusLength);
03029         e.setType(bvType);
03030         break;
03031       }
03032       case LEFTSHIFT: {
03033         if(!(1 == e.arity() &&
03034              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03035           throw TypecheckException
03036             ("Not a bit-vector expression in bit-vector shift:\n\n  "
03037              +e.toString());
03038         int bvLength = BVSize(e[0]);
03039         int shiftLength = getFixedLeftShiftParam(e);
03040         if(!(shiftLength >= 0))
03041           throw TypecheckException("Bad shift value in bit-vector shift:\n\n  "
03042                                    +e.toString());
03043         int newLength = bvLength + shiftLength;
03044         Type bvType = newBitvectorType(newLength);
03045         e.setType(bvType);
03046         break;
03047       }
03048       case CONST_WIDTH_LEFTSHIFT: {
03049         if(!(1 == e.arity() &&
03050              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03051           throw TypecheckException
03052             ("Not a bit-vector expression in bit-vector shift:\n\n  "
03053              +e.toString());
03054         int bvLength = BVSize(e[0]);
03055         int shiftLength = getFixedLeftShiftParam(e);
03056         if(!(shiftLength >= 0))
03057           throw TypecheckException("Bad shift value in bit-vector shift:\n\n  "
03058                                    +e.toString());
03059         Type bvType = newBitvectorType(bvLength);
03060         e.setType(bvType);
03061         break;
03062       }
03063       case RIGHTSHIFT: {
03064         if(!(1 == e.arity() &&
03065              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03066           throw TypecheckException
03067             ("Not a bit-vector expression in bit-vector shift:\n\n  "
03068              +e.toString());
03069         int bvLength = BVSize(e[0]);
03070         int shiftLength = getFixedRightShiftParam(e);
03071         if(!(shiftLength >= 0))
03072           throw TypecheckException("Bad shift value in bit-vector shift:\n\n  "
03073                                    +e.toString());
03074         //int newLength = bvLength + shiftLength;
03075         Type bvType = newBitvectorType(bvLength);
03076         e.setType(bvType);
03077         break;
03078       }
03079       case BVTYPEPRED:
03080         e.setType(boolType());
03081         break;
03082       case SX: {
03083         if(!(1 == e.arity() &&
03084              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03085           throw TypecheckException("Type Checking error:"\
03086                                    "non-bitvector \n"+ e.toString());
03087         int bvLength = getSXIndex(e);
03088         if(!(1 <= bvLength))
03089           throw TypecheckException("Type Checking error: \n"
03090                                    "out of range\n"+ e.toString());
03091         Type bvType = newBitvectorType(bvLength);
03092         e.setType(bvType);
03093         break;
03094       }
03095       case BVREPEAT: {
03096         if(!(1 == e.arity() &&
03097              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03098           throw TypecheckException("Type Checking error:"\
03099                                    "non-bitvector \n"+ e.toString());
03100         int bvLength = getBVIndex(e) * BVSize(e[0]);
03101         if(!(1 <= bvLength))
03102           throw TypecheckException("Type Checking error: \n"
03103                                    "out of range\n"+ e.toString());
03104         Type bvType = newBitvectorType(bvLength);
03105         e.setType(bvType);
03106         break;
03107       }
03108       case BVZEROEXTEND: {
03109         if(!(1 == e.arity() &&
03110              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03111           throw TypecheckException("Type Checking error:"\
03112                                    "non-bitvector \n"+ e.toString());
03113         int bvLength = getBVIndex(e) + BVSize(e[0]);
03114         if(!(1 <= bvLength))
03115           throw TypecheckException("Type Checking error: \n"
03116                                    "out of range\n"+ e.toString());
03117         Type bvType = newBitvectorType(bvLength);
03118         e.setType(bvType);
03119         break;
03120       }
03121       case BVROTL:
03122       case BVROTR: {
03123         if(!(1 == e.arity() &&
03124              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03125           throw TypecheckException("Type Checking error:"\
03126                                    "non-bitvector \n"+ e.toString());
03127         e.setType(getBaseType(e[0]));
03128         break;
03129       }
03130       default:
03131         FatalAssert(false,
03132                     "TheoryBitvector::computeType: unexpected kind in application" +
03133                     int2string(e.getOpKind()));
03134         break;
03135     }
03136   }
03137   else {
03138     switch(e.getKind()) {
03139       case BOOLEXTRACT:
03140       case BVMULT:
03141       case EXTRACT:
03142       case BVPLUS:
03143       case LEFTSHIFT:
03144       case CONST_WIDTH_LEFTSHIFT:
03145       case RIGHTSHIFT:
03146       case BVTYPEPRED:
03147       case SX:
03148       case BVREPEAT:
03149       case BVZEROEXTEND:
03150       case BVROTL:
03151       case BVROTR:
03152         // These operators are handled above when applied to arguments, here we
03153         // are dealing with the operators themselves which are polymorphic, so
03154         // don't assign them a specific type.
03155         e.setType(Type::anyType(getEM()));
03156         break;
03157       case BVCONST: {
03158         Type bvType = newBitvectorType(getBVConstSize(e));
03159         e.setType(bvType);
03160         break;
03161       }
03162       case CONCAT: {
03163         if(e.arity() < 2)
03164           throw TypecheckException
03165             ("Concatenation must have at least 2 bit-vectors:\n\n  "+e.toString());
03166 
03167         // Compute the total length of concatenation
03168         int bvLength(0);
03169         for(int i=0, iend=e.arity(); i<iend; ++i) {
03170           if(BITVECTOR != getBaseType(e[i]).getExpr().getOpKind())
03171             throw TypecheckException
03172               ("Not a bit-vector expression (child #"+int2string(i+1)
03173                +") in concatenation:\n\n  "+e[i].toString()
03174                +"\n\nIn the expression:\n\n  "+e.toString());
03175           bvLength += BVSize(e[i]);
03176         }
03177         Type bvType = newBitvectorType(bvLength);
03178         e.setType(bvType);
03179         break;
03180       }
03181       case BVAND:
03182       case BVOR:
03183       case BVXOR:
03184       case BVXNOR:
03185       {
03186         string kindStr((e.getOpKind()==BVAND)? "AND" :
03187                        ((e.getOpKind()==BVOR)? "OR" :
03188                         ((e.getOpKind()==BVXOR)? "BVXOR" : "BVXNOR")));
03189 
03190         if(e.arity() < 2)
03191           throw TypecheckException
03192             ("Bit-wise "+kindStr+" must have at least 2 bit-vectors:\n\n  "
03193              +e.toString());
03194 
03195         int bvLength(0);
03196         bool first(true);
03197         for(int i=0, iend=e.arity(); i<iend; ++i) {
03198           if(BITVECTOR != getBaseType(e[i]).getExpr().getOpKind())
03199             throw TypecheckException
03200               ("Not a bit-vector expression (child #"+int2string(i+1)
03201                +") in bit-wise "+kindStr+":\n\n  "+e[i].toString()
03202                +"\n\nIn the expression:\n\n  "+e.toString());
03203           if(first) {
03204             bvLength = BVSize(e[i]);
03205             first=false;
03206           } else { // Check that the size is the same for all subsequent BVs
03207             if(BVSize(e[i]) != bvLength)
03208               throw TypecheckException
03209                 ("Mismatched bit-vector size in bit-wise "+kindStr+" (child #"
03210                  +int2string(i)+").\nExpected type: "
03211                  +newBitvectorType(bvLength).toString()
03212                  +"\nFound: "+e[i].getType().toString()
03213                  +"\nIn the following expression:\n\n  "+e.toString());
03214           }
03215         }
03216         e.setType(newBitvectorType(bvLength));
03217         break;
03218       }
03219       case BVNEG:{
03220         if(!(1 == e.arity() &&
03221              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind()))
03222           throw TypecheckException
03223             ("Not a bit-vector expression in bit-wise negation:\n\n  "
03224              + e.toString());
03225         e.setType(e[0].getType());
03226         break;
03227       }
03228       case BVNAND:
03229       case BVNOR:
03230       case BVCOMP:
03231       case BVSUB:
03232       case BVUDIV:
03233       case BVSDIV:
03234       case BVUREM:
03235       case BVSREM:
03236       case BVSMOD:
03237       case BVSHL:
03238       case BVASHR:
03239       case BVLSHR:
03240         if(!(2 == e.arity() &&
03241              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() &&
03242              BITVECTOR == getBaseType(e[1]).getExpr().getOpKind()))
03243           throw TypecheckException
03244             ("Expressions must have arity=2, and"
03245              "each subterm must be a bitvector term:\n"
03246              "e = " +e.toString());
03247         if (BVSize(e[0]) != BVSize(e[1]))
03248           throw TypecheckException
03249             ("Expected args of same size:\n"
03250              "e = " +e.toString());
03251         if (e.getKind() == BVCOMP) {
03252           e.setType(newBitvectorTypeExpr(1));
03253         }
03254         else {
03255           e.setType(getBaseType(e[0]));
03256         }
03257         break;
03258       case BVUMINUS:{
03259         Type bvType(getBaseType(e[0]));
03260         if(!(1 == e.arity() &&
03261              BITVECTOR == bvType.getExpr().getOpKind()))
03262           throw TypecheckException
03263             ("Not a bit-vector expression in BVUMINUS:\n\n  "
03264              +e.toString());
03265         e.setType(bvType);
03266         break;
03267       }
03268       case BVLT:
03269       case BVLE:
03270       case BVGT:
03271       case BVGE:
03272       case BVSLT:
03273       case BVSLE:
03274       case BVSGT:
03275       case BVSGE:
03276         if(!(2 == e.arity() &&
03277              BITVECTOR == getBaseType(e[0]).getExpr().getOpKind() &&
03278              BITVECTOR == getBaseType(e[1]).getExpr().getOpKind()))
03279           throw TypecheckException
03280             ("BVLT/BVLE expressions must have arity=2, and"
03281              "each subterm must be a bitvector term:\n"
03282              "e = " +e.toString());
03283         e.setType(boolType());
03284         break;
03285       default:
03286         FatalAssert(false,
03287                     "TheoryBitvector::computeType: wrong input" +
03288                     int2string(e.getOpKind()));
03289         break;
03290     }
03291   }
03292   TRACE("bitvector", "TheoryBitvector::computeType => ", e.getType(), " }");
03293 }
03294 
03295 
03296 void TheoryBitvector::computeModelTerm(const Expr& e, std::vector<Expr>& v) {
03297   switch(e.getOpKind()) {
03298   case BVPLUS:
03299   case BVSUB:
03300   case BVUMINUS:
03301   case BVMULT:
03302   case LEFTSHIFT:
03303   case CONST_WIDTH_LEFTSHIFT:
03304   case RIGHTSHIFT:
03305   case BVOR:
03306   case BVAND:
03307   case BVXOR:
03308   case BVXNOR:
03309   case BVNAND:
03310   case BVNOR:
03311   case BVNEG:
03312   case CONCAT:
03313   case EXTRACT:
03314   case BVSLT:
03315   case BVSLE:
03316   case BVSGT:
03317   case BVSGE:
03318   case BVLT:
03319   case BVLE:
03320   case BVGT:
03321   case BVGE:
03322     for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
03323       // getModelTerm(*i, v);
03324       v.push_back(*i);
03325     return;
03326   case BVCONST: // No model variables here
03327     return;
03328   default: break; // It's a variable; continue processing
03329   }
03330 
03331   Type tp(e.getType());
03332   switch(tp.getExpr().getOpKind()) {
03333   case BITVECTOR: {
03334     int n = getBitvectorTypeParam(tp);
03335     for(int i=0; i<n; i = i+1)
03336       v.push_back(newBoolExtractExpr(e, i));
03337     break;
03338   }
03339   default:
03340     v.push_back(e);
03341   }
03342 }
03343 
03344 
03345 void TheoryBitvector::computeModel(const Expr& e, std::vector<Expr>& v) {
03346   switch(e.getOpKind()) {
03347   case BVPLUS:
03348   case BVSUB:
03349   case BVUMINUS:
03350   case BVMULT:
03351   case LEFTSHIFT:
03352   case CONST_WIDTH_LEFTSHIFT:
03353   case RIGHTSHIFT:
03354   case BVOR:
03355   case BVAND:
03356   case BVXOR:
03357   case BVXNOR:
03358   case BVNAND:
03359   case BVNOR:
03360   case BVNEG:
03361   case CONCAT:
03362   case EXTRACT:
03363   case SX:
03364   case BVSLT:
03365   case BVSLE:
03366   case BVSGT:
03367   case BVSGE:
03368   case BVLT:
03369   case BVLE:
03370   case BVGT:
03371   case BVGE: {
03372     // More primitive vars are kids, and they should have been
03373     // assigned concrete values
03374     assignValue(simplify(e));
03375     v.push_back(e);
03376     return;
03377   }
03378   case BVCONST: // No model variables here
03379     return;
03380   default: break; // It's a variable; continue processing
03381   }
03382 
03383   Type tp(e.getType());
03384   switch(tp.getExpr().getOpKind()) {
03385   case BITVECTOR: {
03386     const Rational& n = getBitvectorTypeParam(tp);
03387     vector<bool> bits;
03388     // FIXME: generate concrete assignment from bits using proof
03389     // rules. For now, just create a new assignment.
03390     for(int i=0; i<n; i++) {
03391       Theorem val(getModelValue(newBoolExtractExpr(e, i)));
03392       DebugAssert(val.getRHS().isBoolConst(),
03393       "TheoryBitvector::computeModel: unassigned bit: "
03394       +val.getExpr().toString());
03395       bits.push_back(val.getRHS().isTrue());
03396     }
03397     Expr c(newBVConstExpr(bits));
03398     assignValue(e, c);
03399     v.push_back(e);
03400     break;
03401   }
03402   default:
03403     FatalAssert(false, "TheoryBitvector::computeModel[not BITVECTOR type]("
03404     +e.toString()+")");
03405   }
03406 }
03407 
03408 
03409 // TODO: get rid of this - don't need type predicates for bv's, just need to share the right terms
03410 Expr
03411 TheoryBitvector::computeTypePred(const Type& t, const Expr& e) {
03412   DebugAssert(t.getExpr().getOpKind() == BITVECTOR,
03413         "TheoryBitvector::computeTypePred: t = "+t.toString());
03414 //   switch(e.getKind()) {
03415 //   case BVCONST:
03416 //     return getEM()->trueExpr();
03417 //   default:
03418   return e.getEM()->trueExpr();
03419 
03420   //    return newBitvectorTypePred(t, e);
03421     //  }
03422 }
03423 
03424 ///////////////////////////////////////////////////////////////////////////////
03425 // Pretty-printing                                                           //
03426 ///////////////////////////////////////////////////////////////////////////////
03427 
03428 ExprStream&
03429 TheoryBitvector::printSmtLibShared(ExprStream& os, const Expr& e) {
03430 
03431   d_theoryUsed = true;
03432   switch( e.getOpKind() ) {
03433 
03434   case CONCAT:
03435     if( e.arity() == 0 )
03436       throw SmtlibException("TheoryBitvector::print: CONCAT arity = 0");
03437     else if( e.arity() == 1 )
03438       os << e[0];
03439     else {
03440       int i;
03441       for( i = 0; i < e.arity(); ++i ) {
03442         if( (i + 1) == e.arity() ) {
03443           os << e[i];
03444         } else {
03445           os << "(concat" << space << push << e[i] << space << push;
03446         }
03447       }
03448       for( --i; i != 0; --i )
03449         os << push << ")";
03450     }
03451     break;
03452   case BVSHL:
03453     os << "(bvshl" << space << push << e[0] << space << push << e[1] << push
03454         << ")";
03455     break;
03456   case BVLSHR:
03457     os << "(bvlshr" << space << push << e[0] << space << push << e[1] << push
03458         << ")";
03459     break;
03460   case BVASHR:
03461     os << "(bvashr" << space << push << e[0] << space << push << e[1] << push
03462         << ")";
03463     break;
03464   case BVAND:
03465     if( e.arity() == 0 )
03466       throw SmtlibException("TheoryBitvector::print: BVAND arity = 0");
03467     else if( e.arity() == 1 )
03468       os << e[0];
03469     else {
03470       int i;
03471       for( i = 0; i < e.arity(); ++i ) {
03472         if( (i + 1) == e.arity() ) {
03473           os << e[i];
03474         } else {
03475           os << "(bvand" << space << push << e[i] << space << push;
03476         }
03477       }
03478       for( --i; i != 0; --i )
03479         os << push << ")";
03480     }
03481     break;
03482   case BVOR:
03483     if( e.arity() == 0 )
03484       throw SmtlibException("TheoryBitvector::print: BVAND arity = 0");
03485     else if( e.arity() == 1 )
03486       os << e[0];
03487     else {
03488       int i;
03489       for( i = 0; i < e.arity(); ++i ) {
03490         if( (i + 1) == e.arity() ) {
03491           os << e[i];
03492         } else {
03493           os << "(bvor" << space << push << e[i] << space << push;
03494         }
03495       }
03496       for( --i; i != 0; --i )
03497         os << push << ")";
03498     }
03499     break;
03500   case BVXOR:
03501     if( e.arity() == 0 )
03502       throw SmtlibException("TheoryBitvector::print: BVXOR arity = 0");
03503     else if( e.arity() == 1 )
03504       os << e[0];
03505     else {
03506       int i;
03507       for( i = 0; i < e.arity(); ++i ) {
03508         if( (i + 1) == e.arity() ) {
03509           os << e[i];
03510         } else {
03511           os << "(bvxor" << space << push << e[i] << space << push;
03512         }
03513       }
03514       for( --i; i != 0; --i )
03515         os << push << ")";
03516     }
03517     break;
03518   case BVXNOR:
03519     if( e.arity() == 0 )
03520       throw SmtlibException("TheoryBitvector::print: BVXNOR arity = 0");
03521     else if( e.arity() == 1 )
03522       os << e[0];
03523     else {
03524       int i;
03525       for( i = 0; i < e.arity(); ++i ) {
03526         if( (i + 1) == e.arity() ) {
03527           os << e[i];
03528         } else {
03529           os << "(bvxnor" << space << push << e[i] << space << push;
03530         }
03531       }
03532       for( --i; i != 0; --i )
03533         os << push << ")";
03534     }
03535     break;
03536   case BVNEG:
03537     os << "(bvnot" << space << push << e[0] << push << ")";
03538     break;
03539   case BVNAND:
03540     os << "(bvnand" << space << push << e[0] << space << push << e[1] << push
03541         << ")";
03542     break;
03543   case BVNOR:
03544     os << "(bvnor" << space << push << e[0] << space << push << e[1] << push
03545         << ")";
03546     break;
03547   case BVCOMP:
03548     os << "(bvcomp" << space << push << e[0] << space << push << e[1] << push
03549         << ")";
03550     break;
03551 
03552   case BVUMINUS:
03553     os << "(bvneg" << space << push << e[0] << push << ")";
03554     break;
03555   case BVPLUS: {
03556     DebugAssert(e.arity() > 0, "expected arity > 0 in BVPLUS");
03557     int length = getBVPlusParam(e);
03558     int i;
03559     for( i = 0; i < e.arity(); ++i ) {
03560       if( (i + 1) == e.arity() ) {
03561         os << pad(length, e[i]);
03562       } else {
03563         os << "(bvadd" << space << push << pad(length, e[i]) << space << push;
03564       }
03565     }
03566     for( --i; i != 0; --i )
03567       os << push << ")";
03568   }
03569     break;
03570   case BVSUB:
03571     os << "(bvsub" << space << push << e[0] << space << push << e[1] << push
03572         << ")";
03573     break;
03574   case BVMULT: {
03575     int length = getBVMultParam(e);
03576     os << "(bvmul" << space << push << pad(length, e[0]) << space << push
03577         << pad(length, e[1]) << push << ")";
03578     break;
03579   }
03580   case BVUDIV:
03581     os << "(bvudiv" << space << push << e[0] << space << push << e[1] << push
03582         << ")";
03583     break;
03584   case BVSDIV:
03585     os << "(bvsdiv" << space << push << e[0] << space << push << e[1] << push
03586         << ")";
03587     break;
03588   case BVUREM:
03589     os << "(bvurem" << space << push << e[0] << space << push << e[1] << push
03590         << ")";
03591     break;
03592   case BVSREM:
03593     os << "(bvsrem" << space << push << e[0] << space << push << e[1] << push
03594         << ")";
03595     break;
03596   case BVSMOD:
03597     os << "(bvsmod" << space << push << e[0] << space << push << e[1] << push
03598         << ")";
03599     break;
03600 
03601   case BVLT:
03602     os << "(bvult" << space << push << e[0] << space << push << e[1] << push
03603         << ")";
03604     break;
03605   case BVLE:
03606     os << "(bvule" << space << push << e[0] << space << push << e[1] << push
03607         << ")";
03608     break;
03609   case BVGT:
03610     os << "(bvugt" << space << push << e[0] << space << push << e[1] << push
03611         << ")";
03612     break;
03613   case BVGE:
03614     os << "(bvuge" << space << push << e[0] << space << push << e[1] << push
03615         << ")";
03616     break;
03617   case BVSLT:
03618     os << "(bvslt" << space << push << e[0] << space << push << e[1] << push
03619         << ")";
03620     break;
03621   case BVSLE:
03622     os << "(bvsle" << space << push << e[0] << space << push << e[1] << push
03623         << ")";
03624     break;
03625   case BVSGT:
03626     os << "(bvsgt" << space << push << e[0] << space << push << e[1] << push
03627         << ")";
03628     break;
03629   case BVSGE:
03630     os << "(bvsge" << space << push << e[0] << space << push << e[1] << push
03631         << ")";
03632     break;
03633 
03634   case INTTOBV:
03635     throw SmtlibException(
03636         "TheoryBitvector::print: INTTOBV, SMTLIB not supported");
03637     break;
03638   case BVTOINT:
03639     throw SmtlibException(
03640         "TheoryBitvector::print: BVTOINT, SMTLIB not supported");
03641     break;
03642 
03643   case BVTYPEPRED:
03644     throw SmtlibException(
03645         "TheoryBitvector::print: BVTYPEPRED, SMTLIB not supported");
03646     if( e.isApply() ) {
03647       os << "BVTYPEPRED[" << push << e.getOp().getExpr() << push << "," << pop
03648           << space << e[0] << push << "]";
03649     } else
03650       e.printAST(os);
03651     break;
03652 
03653   default:
03654     FatalAssert(false, "Unknown BV kind");
03655     e.printAST(os);
03656     break;
03657   }
03658   return os;
03659 }
03660 
03661 ExprStream&
03662 TheoryBitvector::print(ExprStream& os, const Expr& e) {
03663   switch(os.lang()) {
03664   case PRESENTATION_LANG:
03665     switch(e.getOpKind()) {
03666 
03667     case BITVECTOR: //printing type expression
03668       os << "BITVECTOR(" << push
03669    << getBitvectorTypeParam(e) << push << ")";
03670       break;
03671 
03672     case BVCONST: {
03673       std::ostringstream ss;
03674       ss << "0bin";
03675       for(int i=(int)getBVConstSize(e)-1; i>=0; --i)
03676   ss << (getBVConstValue(e, i) ? "1" : "0");
03677       os << ss.str();
03678       break;
03679     }
03680 
03681     case CONCAT:
03682       if(e.arity() <= 1) e.printAST(os);
03683       else {
03684   os << "(" << push;
03685   bool first(true);
03686   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03687     if(first) first=false;
03688     else os << space << "@" << space;
03689     os << (*i);
03690   }
03691   os << push << ")";
03692       }
03693       break;
03694     case EXTRACT:
03695       os << "(" << push << e[0] << push << ")" << pop << pop
03696    << "[" << push << getExtractHi(e) << ":";
03697       os << getExtractLow(e) << push << "]";
03698       break;
03699     case BOOLEXTRACT:
03700       os << "BOOLEXTRACT(" << push  << e[0] << ","
03701    << getBoolExtractIndex(e) << push << ")";
03702       break;
03703 
03704     case LEFTSHIFT:
03705       os <<  "(" << push << e[0] << space << "<<" << space
03706    << getFixedLeftShiftParam(e) << push << ")";
03707       break;
03708     case CONST_WIDTH_LEFTSHIFT:
03709       os <<  "(" << push << e[0] << space << "<<" << space
03710    << getFixedLeftShiftParam(e) << push << ")";
03711       os << "[" << push << BVSize(e)-1 << ":0]";
03712       break;
03713     case RIGHTSHIFT:
03714       os <<  "(" << push << e[0] << space << ">>" << space
03715    << getFixedRightShiftParam(e) << push << ")";
03716       break;
03717     case BVSHL:
03718       os << "BVSHL(" << push << e[0] << "," << e[1] << push << ")";
03719       break;
03720     case BVLSHR:
03721       os << "BVLSHR(" << push << e[0] << "," << e[1] << push << ")";
03722       break;
03723     case BVASHR:
03724       os << "BVASHR(" << push << e[0] << "," << e[1] << push << ")";
03725       break;
03726     case BVZEROEXTEND:
03727       os << "BVZEROEXTEND(" << push << e[0] << "," << getBVIndex(e) << push << ")";
03728       break;
03729     case BVREPEAT:
03730       os << "BVREPEAT(" << push << e[0] << "," << getBVIndex(e) << push << ")";
03731       break;
03732     case BVROTL:
03733       os << "BVROTL(" << push << e[0] << "," << getBVIndex(e) << push << ")";
03734       break;
03735     case BVROTR:
03736       os << "BVROTR(" << push << e[0] << "," << getBVIndex(e) << push << ")";
03737       break;
03738     case SX:
03739       os << "SX(" << push  << e[0] << ","
03740    << push <<  getSXIndex(e) << ")";
03741       break;
03742 
03743     case BVAND:
03744       if(e.arity() <= 1) e.printAST(os);
03745       else {
03746   os << "(" << push;
03747   bool first(true);
03748   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03749     if(first) first=false;
03750     else os << space << "&" << space;
03751     os << (*i);
03752   }
03753   os << push << ")";
03754       }
03755       break;
03756     case BVOR:
03757       if(e.arity() <= 1) e.printAST(os);
03758       else {
03759   os << "(" << push;
03760   bool first(true);
03761   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03762     if(first) first=false;
03763     else os << space << "|" << space;
03764     os << (*i);
03765   }
03766   os << push << ")";
03767       }
03768       break;
03769     case BVXOR:
03770       DebugAssert(e.arity() > 0, "TheoryBitvector::print: BVXOR arity <= 0");
03771       if (e.arity() == 1) os << e[0];
03772       else {
03773         int i;
03774   for(i = 0; i < e.arity(); ++i) {
03775           if ((i+1) == e.arity()) {
03776             os << e[i];
03777           }
03778           else {
03779             os << "BVXOR(" << push << e[i] << "," << push;
03780           }
03781   }
03782         for (--i; i != 0; --i) os << push << ")";
03783       }
03784       break;
03785     case BVXNOR:
03786       DebugAssert(e.arity() > 0, "TheoryBitvector::print: BVXNOR arity <= 0");
03787       if (e.arity() == 1) os << e[0];
03788       else {
03789         int i;
03790   for(i = 0; i < e.arity(); ++i) {
03791           if ((i+1) == e.arity()) {
03792             os << e[i];
03793           }
03794           else {
03795             os << "BVXNOR(" << push << e[i] << "," << push;
03796           }
03797   }
03798         for (--i; i != 0; --i) os << push << ")";
03799       }
03800       break;
03801     case BVNEG:
03802       os << "(~(" << push << e[0] << push << "))";
03803       break;
03804     case BVNAND:
03805       os << "BVNAND(" << push << e[0] << "," << e[1] << push << ")";
03806       break;
03807     case BVNOR:
03808       os << "BVNAND(" << push << e[0] << "," << e[1] << push << ")";
03809       break;
03810     case BVCOMP:
03811       os << "BVCOMP(" << push << e[0] << "," << e[1] << push << ")";
03812       break;
03813 
03814     case BVUMINUS:
03815       os << "BVUMINUS(" << push << e[0] << push << ")";
03816       break;
03817     case BVPLUS:
03818       os << "BVPLUS(" << push << getBVPlusParam(e);
03819       for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
03820   os << push << "," << pop << space << (*i);
03821       }
03822       os << push << ")";
03823       break;
03824     case BVSUB:
03825       os << "BVSUB(" << push << BVSize(e) << "," << e[0] << "," << e[1] << push << ")";
03826       break;
03827     case BVMULT:
03828       os << "BVMULT(" << push << getBVMultParam(e) << "," << e[0] << "," << e[1]<<push<<")";
03829       break;
03830     case BVUDIV:
03831         os << "BVUDIV(" << push << e[0] << "," << e[1]<<push<<")";
03832         break;
03833     case BVSDIV:
03834         os << "BVSDIV(" << push << e[0] << "," << e[1]<<push<<")";
03835         break;
03836     case BVUREM:
03837         os << "BVUREM(" << push << e[0] << "," << e[1]<<push<<")";
03838         break;
03839     case BVSREM:
03840         os << "BVSREM(" << push << e[0] << "," << e[1]<<push<<")";
03841         break;
03842     case BVSMOD:
03843         os << "BVSMOD(" << push << e[0] << "," << e[1]<<push<<")";
03844         break;
03845     case BVLT:
03846       os << "BVLT(" << push << e[0] << "," << e[1] << push << ")";
03847       break;
03848     case BVLE:
03849       os << "BVLE(" << push << e[0] << "," << e[1] << push << ")";
03850       break;
03851     case BVGT:
03852       os << "BVGT(" << push << e[0] << "," << e[1] << push << ")";
03853       break;
03854     case BVGE:
03855       os << "BVGE(" << push << e[0] << "," << e[1] << push << ")";
03856       break;
03857     case BVSLT:
03858       os << "BVSLT(" << push << e[0] << "," << e[1] << push << ")";
03859       break;
03860     case BVSLE:
03861       os << "BVSLE(" << push << e[0] << "," << e[1] << push << ")";
03862       break;
03863     case BVSGT:
03864       os << "BVSGT(" << push << e[0] << "," << e[1] << push << ")";
03865       break;
03866     case BVSGE:
03867       os << "BVSGE(" << push << e[0] << "," << e[1] << push << ")";
03868       break;
03869 
03870     case INTTOBV:
03871       FatalAssert(false, "INTTOBV not implemented yet");
03872       break;
03873     case BVTOINT:
03874       FatalAssert(false, "BVTOINT not implemented yet");
03875       break;
03876 
03877     case BVTYPEPRED:
03878       if(e.isApply()) {
03879   os << "BVTYPEPRED[" << push << e.getOp().getExpr()
03880      << push << "," << pop << space << e[0]
03881      << push << "]";
03882       } else
03883   e.printAST(os);
03884       break;
03885 
03886     default:
03887       FatalAssert(false, "Unknown BV kind");
03888       e.printAST(os);
03889       break;
03890     }
03891     break;
03892 
03893   case SMTLIB_LANG:
03894     switch(e.getOpKind()) {
03895     case BITVECTOR: //printing type expression
03896       os << push << "BitVec[" << getBitvectorTypeParam(e) << "]";
03897       break;
03898 
03899     case BVCONST: {
03900       Rational r = computeBVConst(e);
03901       DebugAssert(r.isInteger() && r >= 0, "Expected non-negative integer");
03902       os << push << "bv" << r << "[" << BVSize(e) << "]";
03903       break;
03904     }
03905 
03906     case EXTRACT:
03907       os << push << "(extract[" << getExtractHi(e) << ":" << getExtractLow(e)
03908          << "]";
03909       os << space << push << e[0] << push << ")";
03910       break;
03911     case BOOLEXTRACT:
03912       os << "(=" << space << push << "(extract[" << getBoolExtractIndex(e) << ":"
03913          << getBoolExtractIndex(e) << "]";
03914       os << space << push << e[0] << push << ")" << space << "bit1" << push
03915          << ")";
03916       break;
03917 
03918     case LEFTSHIFT: {
03919       int bvLength = getFixedLeftShiftParam(e);
03920       if( bvLength != 0 ) {
03921         os << "(concat" << space << push << e[0] << space;
03922         os << push << "bv0[" << bvLength << "]" << push << ")";
03923         break;
03924       }
03925       // else fall-through
03926     }
03927     case CONST_WIDTH_LEFTSHIFT:
03928       os << "(bvshl" << space << push << e[0] << space << push << "bv"
03929          << getFixedLeftShiftParam(e) << "[" << BVSize(e[0]) << "]" << push
03930          << ")";
03931       break;
03932     case RIGHTSHIFT:
03933       os << "(bvlshr" << space << push << e[0] << space << push << "bv"
03934          << getFixedRightShiftParam(e) << "[" << BVSize(e[0]) << "]" << push
03935          << ")";
03936       break;
03937   case SX: {
03938     int extend = getSXIndex(e) - BVSize(e[0]);
03939     if( extend == 0 )
03940       os << e[0];
03941     else if( extend < 0 )
03942       throw SmtlibException(
03943           "TheoryBitvector::print: SX: extension is shorter than argument");
03944     else
03945       os << "(sign_extend[" << extend << "]" << space << push << e[0] << push
03946           << ")";
03947     break;
03948   }
03949   case BVREPEAT:
03950     os << "(repeat[" << getBVIndex(e) << "]" << space << push << e[0] << push
03951         << ")";
03952     break;
03953   case BVZEROEXTEND: {
03954     int extend = getBVIndex(e);
03955     if( extend == 0 )
03956       os << e[0];
03957     else if( extend < 0 )
03958       throw SmtlibException(
03959           "TheoryBitvector::print: ZEROEXTEND: extension is less than zero");
03960     else
03961       os << "(zero_extend[" << extend << "]" << space << push << e[0] << push
03962           << ")";
03963     break;
03964   }
03965   case BVROTL:
03966     os << "(rotate_left[" << getBVIndex(e) << "]" << space << push << e[0]
03967         << push << ")";
03968     break;
03969   case BVROTR:
03970     os << "(rotate_right[" << getBVIndex(e) << "]" << space << push << e[0]
03971         << push << ")";
03972     break;
03973 
03974     default:
03975       printSmtLibShared(os,e);
03976     }
03977     break;
03978 
03979   case SMTLIB_V2_LANG:
03980     switch(e.getOpKind()) {
03981     case BITVECTOR: //printing type expression
03982       os << push << "(_" << space << "BitVec" << space << getBitvectorTypeParam(e) << ")" << pop;
03983       break;
03984 
03985     case BVCONST: {
03986       Rational r = computeBVConst(e);
03987       DebugAssert(r.isInteger() && r >= 0, "Expected non-negative integer");
03988       os << push << "(_ bv" << r << space << BVSize(e) << ")";
03989       break;
03990     }
03991 
03992     case EXTRACT:
03993       os << push << "((_ extract" << space << getExtractHi(e) << space << getExtractLow(e)
03994          << ")";
03995       os << space << push << e[0] << push << ")";
03996       break;
03997 
03998     case BOOLEXTRACT:
03999       os << "(=" << space << push << "((_ extract" << getBoolExtractIndex(e) << space
04000          << getBoolExtractIndex(e) << ")";
04001       os << space << push << e[0] << push << ")" << space << "#b1" << push
04002          << ")";
04003       break;
04004 
04005     case LEFTSHIFT: {
04006       int bvLength = getFixedLeftShiftParam(e);
04007       if( bvLength != 0 ) {
04008         os << "(concat" << space << push << e[0] << space;
04009         os << push << "#b";
04010         for (int i = 0; i < bvLength; ++i) os << "0";
04011         os << push << ")";
04012         break;
04013       }
04014       // else fall-through
04015     }
04016     case CONST_WIDTH_LEFTSHIFT:
04017       os << "(bvshl" << space << push << e[0] << space << push;
04018       os << newBVConstExpr(getFixedLeftShiftParam(e), BVSize(e[0])) << push  << ")";
04019       break;
04020     case RIGHTSHIFT:
04021       os << "(bvlshr" << space << push << e[0] << space << push;
04022       os << newBVConstExpr(getFixedRightShiftParam(e), BVSize(e[0])) << push << ")";
04023       break;
04024     case SX: {
04025       int extend = getSXIndex(e) - BVSize(e[0]);
04026       if( extend == 0 )
04027         os << e[0];
04028       else if( extend < 0 )
04029         throw SmtlibException(
04030           "TheoryBitvector::print: SX: extension is shorter than argument");
04031       else
04032         os << "((_ sign_extend" << space << extend << ")" << space << push << e[0] << push
04033            << ")";
04034       break;
04035   }
04036   case BVREPEAT:
04037     os << "((_ repeat" << space << getBVIndex(e) << ")" << space << push << e[0] << push
04038         << ")";
04039     break;
04040   case BVZEROEXTEND: {
04041     int extend = getBVIndex(e);
04042     if( extend == 0 )
04043       os << e[0];
04044     else if( extend < 0 )
04045       throw SmtlibException(
04046           "TheoryBitvector::print: ZEROEXTEND: extension is less than zero");
04047     else
04048       os << "((_ zero_extend" << space << extend << ")" << space << push << e[0] << push
04049           << ")";
04050     break;
04051   }
04052   case BVROTL:
04053     os << "((_ rotate_left" << space << getBVIndex(e) << ")" << space << push << e[0]
04054         << push << ")";
04055     break;
04056   case BVROTR:
04057     os << "((_ rotate_right" << space << getBVIndex(e) << ")" << space << push << e[0]
04058         << push << ")";
04059     break;
04060 
04061     default:
04062       printSmtLibShared(os,e);
04063     }
04064     break;
04065 
04066   default:
04067     switch(e.getOpKind()) {
04068     case BVCONST: {
04069       os << "0bin";
04070       for(int i=(int)getBVConstSize(e)-1; i>=0; --i)
04071   os << (getBVConstValue(e, i) ? "1" : "0");
04072       break;
04073     }
04074     default:
04075       e.printAST(os);
04076       break;
04077     }
04078   }
04079   return os;
04080 }
04081 
04082 
04083 ///////////////////////////////////////////////////////////////////////////////
04084 //parseExprOp:
04085 //translating special Exprs to regular EXPR??
04086 ///////////////////////////////////////////////////////////////////////////////
04087 Expr TheoryBitvector::parseExprOp(const Expr& e)
04088 {
04089   d_theoryUsed = true;
04090   TRACE("parser", "TheoryBitvector::parseExprOp(", e, ")");
04091 
04092   // If the expression is not a list, it must have been already
04093   // parsed, so just return it as is.
04094   if(RAW_LIST != e.getKind()) return e;
04095 
04096   if(!(e.arity() > 0))
04097     throw ParserException("TheoryBitvector::parseExprOp: wrong input:\n\n"
04098         +e.toString());
04099 
04100   const Expr& c1 = e[0][0];
04101   int kind = getEM()->getKind(c1.getString());
04102   switch(kind) {
04103 
04104   case BITVECTOR:
04105     if(!(e.arity() == 2))
04106       throw ParserException("TheoryBitvector::parseExprOp: BITVECTOR"
04107           "kind should have exactly 1 arg:\n\n"
04108           + e.toString());
04109     if(!(e[1].isRational() && e[1].getRational().isInteger()))
04110       throw ParserException("BITVECTOR TYPE must have an integer constant"
04111           "as its first argument:\n\n"
04112           +e.toString());
04113     if(!(e[1].getRational().getInt() >=0 ))
04114       throw ParserException("parameter must be an integer constant >= 0.\n"
04115           +e.toString());
04116     return newBitvectorTypeExpr(e[1].getRational().getInt());
04117     break;
04118 
04119   case BVCONST:
04120     if(!(e.arity() == 2 || e.arity() == 3))
04121       throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
04122           "kind should have 1 or 2 args:\n\n"
04123           + e.toString());
04124     if(!(e[1].isRational() || e[1].isString()))
04125       throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
04126           "kind should have arg of type Rational "
04127           "or String:\n\n" + e.toString());
04128     if(e[1].isRational()) { // ("BVCONST" value [bitwidth])
04129       if(e.arity()==3) {
04130   if(!e[2].isRational() || !e[2].getRational().isInteger())
04131     throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
04132         "2nd argument must be an integer:\n\n"
04133         +e.toString());
04134   return newBVConstExpr(e[1].getRational(), e[2].getRational().getInt());
04135       } else
04136   return newBVConstExpr(e[1].getRational());
04137     } else if(e[1].isString()) { // ("BVCONST" string [base])
04138       if(e.arity() == 3) {
04139   if(!e[2].isRational() || !e[2].getRational().isInteger())
04140     throw ParserException("TheoryBitvector::parseExprOp: BVCONST "
04141         "2nd argument must be an integer:\n\n"
04142         +e.toString());
04143   return newBVConstExpr(e[1].getString(), e[2].getRational().getInt());
04144       } else
04145   return newBVConstExpr(e[1].getString());
04146     }
04147     break;
04148 
04149   case CONCAT: {
04150     if(!(e.arity() >= 3))
04151       throw ParserException("TheoryBitvector::parseExprOp: CONCAT"
04152           "kind should have at least 2 args:\n\n"
04153           + e.toString());
04154     vector<Expr> kids;
04155     Expr::iterator i=e.begin(), iend=e.end();
04156     DebugAssert(i!=iend, "TheoryBitvector::parseExprOp("+e.toString()+")");
04157     ++i; // Skip the first element - the operator name
04158     for(; i!=iend; ++i)
04159       kids.push_back(parseExpr(*i));
04160     return newConcatExpr(kids);
04161     break;
04162   }
04163   case EXTRACT: {
04164     if(!(e.arity() == 4))
04165       throw ParserException("TheoryBitvector::parseExprOp: EXTRACT"
04166           "kind should have exactly 3 arg:\n\n"
04167           + e.toString());
04168     if(!e[1].isRational() || !e[1].getRational().isInteger())
04169       throw ParserException("EXTRACT must have an integer constant as its "
04170           "1st argument:\n\n"
04171           +e.toString());
04172     if(!e[2].isRational() || !e[2].getRational().isInteger())
04173       throw ParserException("EXTRACT must have an integer constant as its "
04174           "2nd argument:\n\n"
04175           +e.toString());
04176     int hi = e[1].getRational().getInt();
04177     int lo = e[2].getRational().getInt();
04178     if(!(hi >= lo && lo >=0))
04179       throw ParserException("parameter must be an integer constant >= 0.\n"
04180           +e.toString());
04181 
04182     // Check for extract of left shift
04183     Expr arg = e[3];
04184     if (lo == 0 && arg.getKind() == RAW_LIST && arg[0].getKind() == ID &&
04185         getEM()->getKind(arg[0][0].getString()) == LEFTSHIFT) {
04186       if(!(arg.arity() == 3))
04187         throw ParserException("TheoryBitvector::parseExprOp: LEFTSHIFT"
04188                               "kind should have exactly 2 arg:\n\n"
04189                               + arg.toString());
04190       if(!arg[2].isRational() || !arg[2].getRational().isInteger())
04191         throw ParserException("LEFTSHIFT must have an integer constant as its "
04192                               "2nd argument:\n\n"
04193                               +arg.toString());
04194       if(!(arg[2].getRational().getInt() >=0 ))
04195         throw ParserException("parameter must be an integer constant >= 0.\n"
04196                               +arg.toString());
04197       Expr ls_arg = parseExpr(arg[1]);
04198       if (BVSize(ls_arg) == hi + 1) {
04199         return newFixedConstWidthLeftShiftExpr(ls_arg, arg[2].getRational().getInt());
04200       }
04201     }
04202     return newBVExtractExpr(parseExpr(arg), hi, lo);
04203     break;
04204   }
04205   case BOOLEXTRACT:
04206     if(!(e.arity() == 3))
04207       throw ParserException("TheoryBitvector::parseExprOp: BOOLEXTRACT"
04208           "kind should have exactly 2 arg:\n\n"
04209           + e.toString());
04210     if(!e[2].isRational() || !e[2].getRational().isInteger())
04211       throw ParserException("BOOLEXTRACT must have an integer constant as its"
04212           " 2nd argument:\n\n"
04213           +e.toString());
04214     if(!(e[2].getRational().getInt() >=0 ))
04215       throw ParserException("parameter must be an integer constant >= 0.\n"
04216           +e.toString());
04217     return newBoolExtractExpr(parseExpr(e[1]), e[2].getRational().getInt());
04218     break;
04219 
04220   case LEFTSHIFT:
04221     if(!(e.arity() == 3))
04222       throw ParserException("TheoryBitvector::parseExprOp: LEFTSHIFT"
04223           "kind should have exactly 2 arg:\n\n"
04224           + e.toString());
04225     if(!e[2].isRational() || !e[2].getRational().isInteger())
04226       throw ParserException("LEFTSHIFT must have an integer constant as its "
04227           "2nd argument:\n\n"
04228           +e.toString());
04229     if(!(e[2].getRational().getInt() >=0 ))
04230       throw ParserException("parameter must be an integer constant >= 0.\n"
04231           +e.toString());
04232     return newFixedLeftShiftExpr(parseExpr(e[1]), e[2].getRational().getInt());
04233     break;
04234   case CONST_WIDTH_LEFTSHIFT:
04235     if(!(e.arity() == 3))
04236       throw ParserException("TheoryBitvector::parseExprOp: CONST_WIDTH_LEFTSHIFT"
04237           "kind should have exactly 2 arg:\n\n"
04238           + e.toString());
04239     if(!e[2].isRational() || !e[2].getRational().isInteger())
04240       throw ParserException("CONST_WIDTH_LEFTSHIFT must have an integer constant as its "
04241           "2nd argument:\n\n"
04242           +e.toString());
04243     if(!(e[2].getRational().getInt() >=0 ))
04244       throw ParserException("parameter must be an integer constant >= 0.\n"
04245           +e.toString());
04246     return newFixedConstWidthLeftShiftExpr(parseExpr(e[1]), e[2].getRational().getInt());
04247     break;
04248   case RIGHTSHIFT:
04249     if(!(e.arity() == 3))
04250       throw ParserException("TheoryBitvector::parseExprOp: RIGHTSHIFT"
04251           "kind should have exactly 2 arg:\n\n"
04252           + e.toString());
04253     if(!e[2].isRational() || !e[2].getRational().isInteger())
04254       throw ParserException("RIGHTSHIFT must have an integer constant as its "
04255           "2nd argument:\n\n"
04256           +e.toString());
04257     if(!(e[2].getRational().getInt() >=0 ))
04258       throw ParserException("parameter must be an integer constant >= 0.\n"
04259           +e.toString());
04260     return newFixedRightShiftExpr(parseExpr(e[1]), e[2].getRational().getInt());
04261     break;
04262   // BVSHL, BVLSHR, BVASHR handled with arith operators below
04263   case SX:
04264     // smtlib format interprets the integer argument as the number of bits to
04265     // extend, while CVC format interprets it as the new total size.
04266     // The smtlib parser inserts an extra argument "_smtlib" for this operator
04267     // so that we can distinguish the two cases here.
04268     if (e.arity() == 4 &&
04269         e[1].getKind() == ID &&
04270         e[1][0].getString() == "_smtlib") {
04271       if(!e[2].isRational() || !e[2].getRational().isInteger())
04272         throw ParserException("sign_extend must have an integer constant as its"
04273                               " 1st argument:\n\n"
04274                               +e.toString());
04275       if(!(e[2].getRational().getInt() >=0 ))
04276         throw ParserException("sign_extend must have an integer constant as its"
04277                               " 1st argument >= 0:\n\n"
04278                               +e.toString());
04279       Expr e3 = parseExpr(e[3]);
04280       return newSXExpr(e3, BVSize(e3) + e[2].getRational().getInt());
04281     }
04282     if(!(e.arity() == 3))
04283       throw ParserException("TheoryBitvector::parseExprOp: SX"
04284           "kind should have exactly 2 arg:\n\n"
04285           + e.toString());
04286     if(!e[2].isRational() || !e[2].getRational().isInteger())
04287       throw ParserException("SX must have an integer constant as its"
04288           " 2nd argument:\n\n"
04289           +e.toString());
04290     if(!(e[2].getRational().getInt() >=0 ))
04291       throw ParserException("SX must have an integer constant as its"
04292           " 2nd argument >= 0:\n\n"
04293           +e.toString());
04294     return newSXExpr(parseExpr(e[1]), e[2].getRational().getInt());
04295     break;
04296   case BVROTL:
04297   case BVROTR:
04298   case BVREPEAT:
04299   case BVZEROEXTEND:
04300     if(!(e.arity() == 3))
04301       throw ParserException("TheoryBitvector::parseExprOp:"
04302           "kind should have exactly 2 arg:\n\n"
04303           + e.toString());
04304     if(!e[1].isRational() || !e[1].getRational().isInteger())
04305       throw ParserException("BVIndexExpr must have an integer constant as its"
04306           " 1st argument:\n\n"
04307           +e.toString());
04308     if (kind == BVREPEAT && !(e[1].getRational().getInt() >0 ))
04309       throw ParserException("BVREPEAT must have an integer constant as its"
04310           " 1st argument > 0:\n\n"
04311           +e.toString());
04312     if(!(e[1].getRational().getInt() >=0 ))
04313       throw ParserException("BVIndexExpr must have an integer constant as its"
04314           " 1st argument >= 0:\n\n"
04315           +e.toString());
04316     return newBVIndexExpr(kind, parseExpr(e[2]), e[1].getRational().getInt());
04317     break;
04318 
04319   case BVAND: {
04320     if(!(e.arity() >= 3))
04321       throw ParserException("TheoryBitvector::parseExprOp: BVAND "
04322           "kind should have at least 2 arg:\n\n"
04323           + e.toString());
04324     vector<Expr> kids;
04325     for(int i=1, iend=e.arity(); i<iend; ++i)
04326       kids.push_back(parseExpr(e[i]));
04327     return newBVAndExpr(kids);
04328     break;
04329   }
04330   case BVOR: {
04331     if(!(e.arity() >= 3))
04332       throw ParserException("TheoryBitvector::parseExprOp: BVOR "
04333           "kind should have at least 2 arg:\n\n"
04334           + e.toString());
04335     vector<Expr> kids;
04336     for(int i=1, iend=e.arity(); i<iend; ++i)
04337       kids.push_back(parseExpr(e[i]));
04338     return newBVOrExpr(kids);
04339     break;
04340   }
04341   case BVXOR: {
04342     if(!(e.arity() == 3))
04343       throw ParserException("TheoryBitvector::parseExprOp: BVXOR "
04344           "kind should have exactly 2 arg:\n\n"
04345           + e.toString());
04346     return newBVXorExpr(parseExpr(e[1]), parseExpr(e[2]));
04347     break;
04348   }
04349   case BVXNOR: {
04350     if(!(e.arity() == 3))
04351       throw ParserException("TheoryBitvector::parseExprOp: BVXNOR"
04352           "kind should have exactly 2 arg:\n\n"
04353           + e.toString());
04354     return newBVXnorExpr(parseExpr(e[1]), parseExpr(e[2]));
04355     break;
04356   }
04357   case BVNEG:
04358     if(!(e.arity() == 2))
04359       throw ParserException("TheoryBitvector::parseExprOp: BVNEG"
04360           "kind should have exactly 1 arg:\n\n"
04361           + e.toString());
04362     return newBVNegExpr(parseExpr(e[1]));
04363     break;
04364   case BVNAND:
04365     if(!(e.arity() == 3))
04366       throw ParserException("TheoryBitvector::parseExprOp: BVNAND"
04367           "kind should have exactly 2 arg:\n\n"
04368           + e.toString());
04369     return newBVNandExpr(parseExpr(e[1]), parseExpr(e[2]));
04370     break;
04371   case BVNOR:
04372     if(!(e.arity() == 3))
04373       throw ParserException("TheoryBitvector::parseExprOp: BVNOR"
04374           "kind should have exactly 2 arg:\n\n"
04375           + e.toString());
04376     return newBVNorExpr(parseExpr(e[1]), parseExpr(e[2]));
04377     break;
04378   case BVCOMP: {
04379     if(!(e.arity() == 3))
04380       throw ParserException("TheoryBitvector::parseExprOp: BVXNOR"
04381           "kind should have exactly 2 arg:\n\n"
04382           + e.toString());
04383     return newBVCompExpr(parseExpr(e[1]), parseExpr(e[2]));
04384     break;
04385   }
04386 
04387   case BVUMINUS:
04388     if(!(e.arity() == 2))
04389       throw ParserException("TheoryBitvector::parseExprOp: BVUMINUS"
04390           "kind should have exactly 1 arg:\n\n"
04391           + e.toString());
04392     return newBVUminusExpr(parseExpr(e[1]));
04393     break;
04394   case BVPLUS: {
04395     vector<Expr> k;
04396     Expr::iterator i = e.begin(), iend=e.end();
04397     if (!e[1].isRational()) {
04398       int maxsize = 0;
04399       Expr child;
04400       // Parse the kids of e and push them into the vector 'k'
04401       for(++i; i!=iend; ++i) {
04402         child = parseExpr(*i);
04403         if (getBaseType(child).getExpr().getOpKind() != BITVECTOR) {
04404           throw ParserException("BVPLUS argument is not bitvector");
04405         }
04406         if (BVSize(child) > maxsize) maxsize = BVSize(child);
04407         k.push_back(child);
04408       }
04409       if (e.arity() == 1) return k[0];
04410       return newBVPlusPadExpr(maxsize, k);
04411     }
04412     else {
04413       if(!(e.arity() >= 4))
04414         throw ParserException("Expected at least 3 args in BVPLUS:\n\n"
04415                               +e.toString());
04416       if(!e[1].isRational() || !e[1].getRational().isInteger())
04417         throw ParserException
04418           ("Expected integer constant in BVPLUS:\n\n"
04419            +e.toString());
04420       if(!(e[1].getRational().getInt() > 0))
04421         throw ParserException("parameter must be an integer constant > 0.\n"
04422                               +e.toString());
04423       // Skip first two elements of the vector of kids in 'e'.
04424       // The first element is the kind, and the second is the
04425       // numOfBits of the bvplus operator.
04426       ++i;++i;
04427       Expr child;
04428       // Parse the kids of e and push them into the vector 'k'
04429       for(; i!=iend; ++i) {
04430         child = parseExpr(*i);
04431         if (getBaseType(child).getExpr().getOpKind() != BITVECTOR) {
04432           throw ParserException("BVPLUS argument is not bitvector");
04433         }
04434         k.push_back(child);
04435       }
04436       return newBVPlusPadExpr(e[1].getRational().getInt(), k);
04437     }
04438     break;
04439   }
04440   case BVSUB: {
04441     if (e.arity() == 3) {
04442       Expr summand1 = parseExpr(e[1]);
04443       Expr summand2 = parseExpr(e[2]);
04444       if (getBaseType(summand1).getExpr().getOpKind() != BITVECTOR
04445           || getBaseType(summand2).getExpr().getOpKind() != BITVECTOR) {
04446         throw ParserException("BVSUB argument is not bitvector");
04447       } 
04448       if (BVSize(summand1) != BVSize(summand2)) {
04449         throw ParserException("BVSUB: expected same sized arguments"
04450                               +e.toString());
04451       }
04452       return newBVSubExpr(summand1, summand2);
04453     }
04454     else if (e.arity() != 4)
04455       throw ParserException("BVSUB: wrong number of arguments:\n\n"
04456           +e.toString());
04457     if (!e[1].isRational() || !e[1].getRational().isInteger())
04458       throw ParserException("BVSUB: expected an integer constant as "
04459           "first argument:\n\n"
04460           +e.toString());
04461     if (!(e[1].getRational().getInt() > 0))
04462       throw ParserException("parameter must be an integer constant > 0.\n"
04463                             +e.toString());
04464     int bvsublength = e[1].getRational().getInt();
04465     Expr summand1 = parseExpr(e[2]);
04466     Expr summand2 = parseExpr(e[3]);
04467     if (getBaseType(summand1).getExpr().getOpKind() != BITVECTOR
04468         || getBaseType(summand2).getExpr().getOpKind() != BITVECTOR) {
04469       throw ParserException("BVSUB argument is not bitvector");
04470     } 
04471     summand1 = pad(bvsublength, summand1);
04472     summand2 = pad(bvsublength, summand2);
04473     return newBVSubExpr(summand1, summand2);
04474     break;
04475   }
04476   case BVMULT: {
04477     vector<Expr> k;
04478     Expr::iterator i = e.begin(), iend=e.end();
04479     if (!e[1].isRational()) {
04480       if (e.arity() != 3) {
04481         throw ParserException("TheoryBitvector::parseExprOp: BVMULT: "
04482                               "expected exactly 2 args:\n\n"
04483                               + e.toString());
04484       }
04485       int maxsize = 0;
04486       Expr child;
04487       // Parse the kids of e and push them into the vector 'k'
04488       for(++i; i!=iend; ++i) {
04489         child = parseExpr(*i);
04490         if (getBaseType(child).getExpr().getOpKind() != BITVECTOR) {
04491           throw ParserException("BVMULT argument is not bitvector");
04492         }
04493         if (BVSize(child) > maxsize) maxsize = BVSize(child);
04494         k.push_back(child);
04495       }
04496       if (e.arity() == 1) return k[0];
04497       return newBVMultPadExpr(maxsize, k[0], k[1]);
04498     }
04499     if(!(e.arity() == 4))
04500       throw ParserException("TheoryBitvector::parseExprOp: BVMULT: "
04501           "expected exactly 3 args:\n\n"
04502           + e.toString());
04503     if(!e[1].isRational() || !e[1].getRational().isInteger())
04504       throw ParserException("BVMULT: expected integer constant"
04505           "as first argument:\n\n"
04506           +e.toString());
04507     if(!(e[1].getRational().getInt() > 0))
04508       throw ParserException("parameter must be an integer constant > 0.\n"
04509           +e.toString());
04510     Expr a = parseExpr(e[2]);
04511     Expr b = parseExpr(e[3]);
04512     if (getBaseType(a).getExpr().getOpKind() != BITVECTOR
04513         || getBaseType(b).getExpr().getOpKind() != BITVECTOR) {
04514       throw ParserException("BVMULT argument is not bitvector");
04515     }    
04516     return newBVMultPadExpr(e[1].getRational().getInt(),a,b);
04517     break;
04518   }
04519   case BVUDIV:
04520   case BVSDIV:
04521   case BVUREM:
04522   case BVSREM:
04523   case BVSMOD:
04524   case BVSHL:
04525   case BVASHR:
04526   case BVLSHR: {
04527     if(!(e.arity() == 3))
04528       throw ParserException("TheoryBitvector::parseExprOp:"
04529           "kind should have exactly 2 args:\n\n"
04530           + e.toString());
04531     Expr e1 = parseExpr(e[1]);
04532     Expr e2 = parseExpr(e[2]);
04533     if (e1.getType().getExpr().getOpKind() != BITVECTOR ||
04534         e2.getType().getExpr().getOpKind() != BITVECTOR)
04535       throw ParserException("TheoryBitvector::parseExprOp:"
04536                             "Expected bitvector arguments:\n\n"
04537                             + e.toString());
04538     if (BVSize(e1) != BVSize(e2))
04539       throw ParserException("TheoryBitvector::parseExprOp:"
04540                             "Expected bitvectors of same size:\n\n"
04541                             + e.toString());
04542     if (kind == BVSHL) {
04543       if (e2.getKind() == BVCONST)
04544         return newFixedConstWidthLeftShiftExpr(e1,
04545                                                computeBVConst(e2).getInt());
04546     }
04547     else if (kind == BVLSHR) {
04548       if (e2.getKind() == BVCONST)
04549         return newFixedRightShiftExpr(e1, computeBVConst(e2).getInt());
04550     }
04551     return Expr(kind, e1, e2);
04552     break;
04553   }
04554 
04555   case BVLT:
04556     if(!(e.arity() == 3))
04557       throw ParserException("TheoryBitvector::parseExprOp: BVLT"
04558           "kind should have exactly 2 arg:\n\n"
04559           + e.toString());
04560     return newBVLTExpr(parseExpr(e[1]),parseExpr(e[2]));
04561     break;
04562   case BVLE:
04563     if(!(e.arity() == 3))
04564       throw ParserException("TheoryBitvector::parseExprOp: BVLE"
04565           "kind should have exactly 2 arg:\n\n"
04566           + e.toString());
04567     return newBVLEExpr(parseExpr(e[1]),parseExpr(e[2]));
04568     break;
04569   case BVGT:
04570     if(!(e.arity() == 3))
04571       throw ParserException("TheoryBitvector::parseExprOp: BVGT"
04572           "kind should have exactly 2 arg:\n\n"
04573           + e.toString());
04574     return newBVLTExpr(parseExpr(e[2]),parseExpr(e[1]));
04575     break;
04576   case BVGE:
04577     if(!(e.arity() == 3))
04578       throw ParserException("TheoryBitvector::parseExprOp: BVGE"
04579           "kind should have exactly 2 arg:\n\n"
04580           + e.toString());
04581     return newBVLEExpr(parseExpr(e[2]),parseExpr(e[1]));
04582     break;
04583   case BVSLT:
04584     if(!(e.arity() == 3))
04585       throw ParserException("TheoryBitvector::parseExprOp: BVLT"
04586           "kind should have exactly 2 arg:\n\n"
04587           + e.toString());
04588     return newBVSLTExpr(parseExpr(e[1]),parseExpr(e[2]));
04589     break;
04590   case BVSLE:
04591     if(!(e.arity() == 3))
04592       throw ParserException("TheoryBitvector::parseExprOp: BVLE"
04593           "kind should have exactly 2 arg:\n\n"
04594           + e.toString());
04595     return newBVSLEExpr(parseExpr(e[1]),parseExpr(e[2]));
04596     break;
04597   case BVSGT:
04598     if(!(e.arity() == 3))
04599       throw ParserException("TheoryBitvector::parseExprOp: BVGT"
04600           "kind should have exactly 2 arg:\n\n"
04601           + e.toString());
04602     return newBVSLTExpr(parseExpr(e[2]),parseExpr(e[1]));
04603     break;
04604   case BVSGE:
04605     if(!(e.arity() == 3))
04606       throw ParserException("TheoryBitvector::parseExprOp: BVGE"
04607           "kind should have exactly 2 arg:\n\n"
04608           + e.toString());
04609     return newBVSLEExpr(parseExpr(e[2]),parseExpr(e[1]));
04610     break;
04611 
04612   case INTTOBV:
04613     throw ParserException("INTTOBV not implemented");
04614     break;
04615   case BVTOINT:
04616     throw ParserException("BVTOINT not implemented");
04617     break;
04618 
04619   case BVTYPEPRED:
04620     throw ParserException("BVTYPEPRED is used internally");
04621     break;
04622 
04623   default:
04624     FatalAssert(false,
04625     "TheoryBitvector::parseExprOp: unrecognized input operator"
04626     +e.toString());
04627     break;
04628   }
04629   return e;
04630 }
04631 
04632 
04633 ///////////////////////////////////////////////////////////////////////////////
04634 //helper functions
04635 ///////////////////////////////////////////////////////////////////////////////
04636 
04637 
04638 Expr TheoryBitvector::newBitvectorTypeExpr(int bvLength)
04639 {
04640   DebugAssert(bvLength > 0,
04641         "TheoryBitvector::newBitvectorTypeExpr:\n"
04642         "len of a BV must be a positive integer:\n bvlength = "+
04643         int2string(bvLength));
04644   if (bvLength > d_maxLength)
04645     d_maxLength = bvLength;
04646   return Expr(BITVECTOR, getEM()->newRatExpr(bvLength));
04647 }
04648 
04649 
04650 Expr TheoryBitvector::newBitvectorTypePred(const Type& t, const Expr& e)
04651 {
04652   return Expr(Expr(BVTYPEPRED, t.getExpr()).mkOp(), e);
04653 }
04654 
04655 
04656 Expr TheoryBitvector::newBVAndExpr(const Expr& t1, const Expr& t2)
04657 {
04658   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04659         BITVECTOR == t2.getType().getExpr().getOpKind(),
04660         "TheoryBitvector::newBVAndExpr:"
04661         "inputs must have type BITVECTOR:\n t1 = " +
04662         t1.toString() + "\n t2 = " +t2.toString());
04663   DebugAssert(BVSize(t1) == BVSize(t2),
04664         "TheoryBitvector::bitwise operator"
04665         "inputs must have same length:\n t1 = " + t1.toString()
04666         + "\n t2 = " + t2.toString());
04667   return Expr(CVC3::BVAND, t1, t2);
04668 }
04669 
04670 
04671 Expr TheoryBitvector::newBVAndExpr(const vector<Expr>& kids)
04672 {
04673   DebugAssert(kids.size() >= 2,
04674         "TheoryBitvector::newBVAndExpr:"
04675         "# of subterms must be at least 2");
04676   for(unsigned int i=0; i<kids.size(); ++i) {
04677     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
04678     "TheoryBitvector::newBVAndExpr:"
04679     "inputs must have type BITVECTOR:\n t1 = " +
04680     kids[i].toString());
04681     if(i < kids.size()-1) {
04682       DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]),
04683       "TheoryBitvector::bitwise operator"
04684       "inputs must have same length:\n t1 = " + kids[i].toString()
04685       + "\n t2 = " + kids[i+1].toString());
04686     }
04687   }
04688   return Expr(CVC3::BVAND, kids, getEM());
04689 }
04690 
04691 
04692 Expr TheoryBitvector::newBVOrExpr(const Expr& t1, const Expr& t2)
04693 {
04694   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04695         BITVECTOR == t2.getType().getExpr().getOpKind(),
04696         "TheoryBitvector::newBVOrExpr: "
04697         "inputs must have type BITVECTOR:\n t1 = " +
04698         t1.toString() + "\n t2 = " +t2.toString());
04699   DebugAssert(BVSize(t1) == BVSize(t2),
04700         "TheoryBitvector::bitwise OR operator: "
04701         "inputs must have same length:\n t1 = " + t1.toString()
04702         + "\n t2 = " + t2.toString());
04703   return Expr(CVC3::BVOR, t1, t2);
04704 }
04705 
04706 
04707 Expr TheoryBitvector::newBVOrExpr(const vector<Expr>& kids)
04708 {
04709   DebugAssert(kids.size() >= 2,
04710         "TheoryBitvector::newBVOrExpr: "
04711         "# of subterms must be at least 2");
04712   for(unsigned int i=0; i<kids.size(); ++i) {
04713     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
04714     "TheoryBitvector::newBVOrExpr: "
04715     "inputs must have type BITVECTOR:\n t1 = " +
04716     kids[i].toString());
04717     if(i < kids.size()-1) {
04718       DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]),
04719       "TheoryBitvector::bitwise operator"
04720       "inputs must have same length:\n t1 = " + kids[i].toString()
04721       + "\n t2 = " + kids[i+1].toString());
04722     }
04723   }
04724   return Expr(CVC3::BVOR, kids, getEM());
04725 }
04726 
04727 
04728 Expr TheoryBitvector::newBVNandExpr(const Expr& t1, const Expr& t2)
04729 {
04730   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04731         BITVECTOR == t2.getType().getExpr().getOpKind(),
04732         "TheoryBitvector::newBVNandExpr:"
04733         "inputs must have type BITVECTOR:\n t1 = " +
04734         t1.toString() + "\n t2 = " +t2.toString());
04735   DebugAssert(BVSize(t1) == BVSize(t2),
04736         "TheoryBitvector::bitwise operator"
04737         "inputs must have same length:\n t1 = " + t1.toString()
04738         + "\n t2 = " + t2.toString());
04739   return Expr(CVC3::BVNAND, t1, t2);
04740 }
04741 
04742 
04743 Expr TheoryBitvector::newBVNorExpr(const Expr& t1, const Expr& t2)
04744 {
04745   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04746         BITVECTOR == t2.getType().getExpr().getOpKind(),
04747         "TheoryBitvector::newBVNorExpr:"
04748         "inputs must have type BITVECTOR:\n t1 = " +
04749         t1.toString() + "\n t2 = " +t2.toString());
04750   DebugAssert(BVSize(t1) == BVSize(t2),
04751         "TheoryBitvector::bitwise operator"
04752         "inputs must have same length:\n t1 = " + t1.toString()
04753         + "\n t2 = " + t2.toString());
04754   return Expr(CVC3::BVNOR, t1, t2);
04755 }
04756 
04757 
04758 Expr TheoryBitvector::newBVXorExpr(const Expr& t1, const Expr& t2)
04759 {
04760   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04761         BITVECTOR == t2.getType().getExpr().getOpKind(),
04762         "TheoryBitvector::newBVXorExpr:"
04763         "inputs must have type BITVECTOR:\n t1 = " +
04764         t1.toString() + "\n t2 = " +t2.toString());
04765   DebugAssert(BVSize(t1) == BVSize(t2),
04766         "TheoryBitvector::bitwise operator"
04767         "inputs must have same length:\n t1 = " + t1.toString()
04768         + "\n t2 = " + t2.toString());
04769   return Expr(CVC3::BVXOR, t1, t2);
04770 }
04771 
04772 
04773 Expr TheoryBitvector::newBVXorExpr(const vector<Expr>& kids)
04774 {
04775   DebugAssert(kids.size() >= 2,
04776         "TheoryBitvector::newBVXorExpr:"
04777         "# of subterms must be at least 2");
04778   for(unsigned int i=0; i<kids.size(); ++i) {
04779     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
04780     "TheoryBitvector::newBVXorExpr:"
04781     "inputs must have type BITVECTOR:\n t1 = " +
04782     kids[i].toString());
04783     if(i < kids.size()-1) {
04784       DebugAssert(BVSize(kids[i]) ==  BVSize(kids[i+1]),
04785       "TheoryBitvector::bitwise operator"
04786       "inputs must have same length:\n t1 = " + kids[i].toString()
04787       + "\n t2 = " + kids[i+1].toString());
04788     }
04789   }
04790   return Expr(CVC3::BVXOR, kids, getEM());
04791 }
04792 
04793 
04794 Expr TheoryBitvector::newBVXnorExpr(const Expr& t1, const Expr& t2)
04795 {
04796   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04797         BITVECTOR == t2.getType().getExpr().getOpKind(),
04798         "TheoryBitvector::newBVXnorExpr:"
04799         "inputs must have type BITVECTOR:\n t1 = " +
04800         t1.toString() + "\n t2 = " +t2.toString());
04801   DebugAssert(BVSize(t1) == BVSize(t2),
04802         "TheoryBitvector::bitwise operator"
04803         "inputs must have same length:\n t1 = " + t1.toString()
04804         + "\n t2 = " + t2.toString());
04805   return Expr(CVC3::BVXNOR, t1, t2);
04806 }
04807 
04808 
04809 Expr TheoryBitvector::newBVCompExpr(const Expr& t1, const Expr& t2)
04810 {
04811   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04812         BITVECTOR == t2.getType().getExpr().getOpKind(),
04813         "TheoryBitvector::newBVCompExpr:"
04814         "inputs must have type BITVECTOR:\n t1 = " +
04815         t1.toString() + "\n t2 = " +t2.toString());
04816   DebugAssert(BVSize(t1) == BVSize(t2),
04817         "TheoryBitvector::bitwise operator"
04818         "inputs must have same length:\n t1 = " + t1.toString()
04819         + "\n t2 = " + t2.toString());
04820   return Expr(CVC3::BVCOMP, t1, t2);
04821 }
04822 
04823 
04824 Expr TheoryBitvector::newBVXnorExpr(const vector<Expr>& kids)
04825 {
04826   DebugAssert(kids.size() >= 2,
04827         "TheoryBitvector::newBVXnorExpr:"
04828         "# of subterms must be at least 2");
04829   for(unsigned int i=0; i<kids.size(); ++i) {
04830     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
04831     "TheoryBitvector::newBVXnorExpr:"
04832     "inputs must have type BITVECTOR:\n t1 = " +
04833     kids[i].toString());
04834     if(i < kids.size()-1) {
04835       DebugAssert(BVSize(kids[i]) == BVSize(kids[i+1]),
04836       "TheoryBitvector::bitwise operator"
04837       "inputs must have same length:\n t1 = " + kids[i].toString()
04838       + "\n t2 = " + kids[i+1].toString());
04839     }
04840   }
04841   return Expr(CVC3::BVXNOR, kids, getEM());
04842 }
04843 
04844 
04845 Expr TheoryBitvector::newBVLTExpr(const Expr& t1, const Expr& t2)
04846 {
04847   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04848         BITVECTOR == t2.getType().getExpr().getOpKind(),
04849         "TheoryBitvector::newBVLTExpr:"
04850         "inputs must have type BITVECTOR:\n t1 = " +
04851         t1.toString() + "\n t2 = " +t2.toString());
04852   return Expr(CVC3::BVLT, t1, t2);
04853 }
04854 
04855 
04856 Expr TheoryBitvector::newBVLEExpr(const Expr& t1, const Expr& t2)
04857 {
04858   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04859         BITVECTOR == t2.getType().getExpr().getOpKind(),
04860         "TheoryBitvector::newBVLEExpr:"
04861         "inputs must have type BITVECTOR:\n t1 = " +
04862         t1.toString() + "\n t2 = " +t2.toString());
04863   return Expr(CVC3::BVLE, t1, t2);
04864 }
04865 
04866 
04867 Expr TheoryBitvector::newSXExpr(const Expr& t1, int len)
04868 {
04869   DebugAssert(len >=0,
04870         " TheoryBitvector::newSXExpr:"
04871         "SX index must be a non-negative integer"+
04872         int2string(len));
04873   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04874         "TheoryBitvector::newSXExpr:"
04875         "inputs must have type BITVECTOR:\n t1 = " +
04876         t1.toString());
04877   if(len==0) return t1;
04878   return Expr(Expr(SX, getEM()->newRatExpr(len)).mkOp(), t1);
04879 }
04880 
04881 
04882 Expr TheoryBitvector::newBVIndexExpr(int kind, const Expr& t1, int len)
04883 {
04884   DebugAssert(kind != BVREPEAT || len > 0,
04885               "repeat requires index > 0");
04886   DebugAssert(len >=0,
04887         "TheoryBitvector::newBVIndexExpr:"
04888         "index must be a non-negative integer"+
04889         int2string(len));
04890   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04891         "TheoryBitvector::newBVIndexExpr:"
04892         "inputs must have type BITVECTOR:\n t1 = " +
04893         t1.toString());
04894   return Expr(Expr(kind, getEM()->newRatExpr(len)).mkOp(), t1);
04895 }
04896 
04897 
04898 Expr TheoryBitvector::newBVSLTExpr(const Expr& t1, const Expr& t2)
04899 {
04900   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04901         BITVECTOR == t2.getType().getExpr().getOpKind(),
04902         "TheoryBitvector::newBVSLTExpr:"
04903         "inputs must have type BITVECTOR:\n t1 = " +
04904         t1.toString() + "\n t2 = " +t2.toString());
04905   return Expr(CVC3::BVSLT, t1, t2);
04906 }
04907 
04908 
04909 Expr TheoryBitvector::newBVSLEExpr(const Expr& t1, const Expr& t2)
04910 {
04911   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
04912         BITVECTOR == t2.getType().getExpr().getOpKind(),
04913         "TheoryBitvector::newBVSLEExpr:"
04914         "inputs must have type BITVECTOR:\n t1 = " +
04915         t1.toString() + "\n t2 = " +t2.toString());
04916   return Expr(CVC3::BVSLE, t1, t2);
04917 }
04918 
04919 
04920 Expr TheoryBitvector::newBVNegExpr(const Expr& t1)
04921 {
04922   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04923         "TheoryBitvector::newBVNegExpr:"
04924         "inputs must have type BITVECTOR:\n t1 = " +
04925         t1.toString());
04926   return Expr(CVC3::BVNEG, t1);
04927 }
04928 
04929 
04930 Expr TheoryBitvector::newBVUminusExpr(const Expr& t1)
04931 {
04932   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04933         "TheoryBitvector::newBVNegExpr:"
04934         "inputs must have type BITVECTOR:\n t1 = " +
04935         t1.toString());
04936   return Expr(CVC3::BVUMINUS, t1);
04937 }
04938 
04939 
04940 Expr TheoryBitvector::newBoolExtractExpr(const Expr& t1, int index)
04941 {
04942   DebugAssert(index >=0,
04943         " TheoryBitvector::newBoolExtractExpr:"
04944         "bool_extract index must be a non-negative integer"+
04945         int2string(index));
04946   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04947         "TheoryBitvector::newBVBoolExtractExpr:"
04948         "inputs must have type BITVECTOR:\n t1 = " +
04949         t1.toString());
04950   return Expr(Expr(BOOLEXTRACT, getEM()->newRatExpr(index)).mkOp(), t1);
04951 }
04952 
04953 
04954 Expr TheoryBitvector::newFixedLeftShiftExpr(const Expr& t1, int shiftLength)
04955 {
04956   DebugAssert(shiftLength >=0,
04957         " TheoryBitvector::newFixedleftshift:"
04958         "fixed_shift index must be a non-negative integer"+
04959         int2string(shiftLength));
04960   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04961         "TheoryBitvector::newBVFixedleftshiftExpr:"
04962         "inputs must have type BITVECTOR:\n t1 = " +
04963         t1.toString());
04964   return Expr(Expr(LEFTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1);
04965 }
04966 
04967 
04968 Expr TheoryBitvector::newFixedConstWidthLeftShiftExpr(const Expr& t1, int shiftLength)
04969 {
04970   DebugAssert(shiftLength >=0,
04971         " TheoryBitvector::newFixedConstWidthLeftShift:"
04972         "fixed_shift index must be a non-negative integer"+
04973         int2string(shiftLength));
04974   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04975         "TheoryBitvector::newBVFixedleftshiftExpr:"
04976         "inputs must have type BITVECTOR:\n t1 = " +
04977         t1.toString());
04978   return Expr(Expr(CONST_WIDTH_LEFTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1);
04979 }
04980 
04981 
04982 Expr TheoryBitvector::newFixedRightShiftExpr(const Expr& t1, int shiftLength)
04983 {
04984   DebugAssert(shiftLength >=0,
04985         " TheoryBitvector::newFixedRightShift:"
04986         "fixed_shift index must be a non-negative integer"+
04987         int2string(shiftLength));
04988   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind(),
04989         "TheoryBitvector::newBVFixedRightShiftExpr:"
04990         "inputs must have type BITVECTOR:\n t1 = " +
04991         t1.toString());
04992   if(shiftLength==0) return t1;
04993   return Expr(Expr(RIGHTSHIFT, getEM()->newRatExpr(shiftLength)).mkOp(), t1);
04994 }
04995 
04996 
04997 Expr TheoryBitvector::newConcatExpr(const Expr& t1, const Expr& t2)
04998 {
04999   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05000         BITVECTOR == t2.getType().getExpr().getOpKind(),
05001         "TheoryBitvector::newBVConcatExpr:"
05002         "inputs must have type BITVECTOR:\n t1 = " +
05003         t1.toString() + "\n t2 = " +t2.toString());
05004   return Expr(CONCAT, t1, t2);
05005 }
05006 
05007 
05008 Expr TheoryBitvector::newConcatExpr(const Expr& t1, const Expr& t2,
05009             const Expr& t3)
05010 {
05011   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05012         BITVECTOR == t2.getType().getExpr().getOpKind() &&
05013         BITVECTOR == t3.getType().getExpr().getOpKind(),
05014         "TheoryBitvector::newBVConcatExpr:"
05015         "inputs must have type BITVECTOR:\n t1 = " +
05016         t1.toString() +
05017         "\n t2 = " +t2.toString() +
05018         "\n t3 =" + t3.toString());
05019   return Expr(CONCAT, t1, t2, t3);
05020 }
05021 
05022 
05023 Expr TheoryBitvector::newConcatExpr(const vector<Expr>& kids)
05024 {
05025   DebugAssert(kids.size() >= 2,
05026         "TheoryBitvector::newBVConcatExpr:"
05027         "# of subterms must be at least 2");
05028   for(unsigned int i=0; i<kids.size(); ++i) {
05029     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
05030     "TheoryBitvector::newBVConcatExpr:"
05031     "inputs must have type BITVECTOR:\n t1 = " +
05032     kids[i].toString());
05033   }
05034   return Expr(CONCAT, kids, getEM());
05035 }
05036 
05037 
05038 Expr TheoryBitvector::newBVMultExpr(int bvLength,
05039             const Expr& t1, const Expr& t2)
05040 {
05041   DebugAssert(bvLength > 0,
05042         "TheoryBitvector::newBVmultExpr:"
05043         "bvLength must be an integer > 0: bvLength = " +
05044         int2string(bvLength));
05045   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05046         BITVECTOR == t2.getType().getExpr().getOpKind(),
05047         "TheoryBitvector::newBVmultExpr:"
05048         "inputs must have type BITVECTOR:\n t1 = " +
05049         t1.toString() + "\n t2 = " +t2.toString());
05050   DebugAssert(bvLength == BVSize(t1) &&
05051               bvLength == BVSize(t2), "Expected same length");
05052   return Expr(Expr(BVMULT, getEM()->newRatExpr(bvLength)).mkOp(), t1, t2);
05053 }
05054 
05055 
05056 Expr TheoryBitvector::newBVMultExpr(int bvLength, const vector<Expr>& kids)
05057 {
05058   DebugAssert(bvLength > 0,
05059         "TheoryBitvector::newBVmultExpr:"
05060         "bvLength must be an integer > 0: bvLength = " +
05061         int2string(bvLength));
05062   for(unsigned int i=0; i<kids.size(); ++i) {
05063     DebugAssert(BITVECTOR == kids[i].getType().getExpr().getOpKind(),
05064     "TheoryBitvector::newBVPlusExpr:"
05065     "inputs must have type BITVECTOR:\n t1 = " +
05066     kids[i].toString());
05067     DebugAssert(BVSize(kids[i]) == bvLength, "Expected matching sizes");
05068   }
05069   return Expr(Expr(BVMULT, getEM()->newRatExpr(bvLength)).mkOp(), kids);
05070 }
05071 
05072 
05073 Expr TheoryBitvector::newBVMultPadExpr(int bvLength, const vector<Expr>& kids)
05074 {
05075   vector<Expr> newKids;
05076   for (unsigned i = 0; i < kids.size(); ++i) {
05077     newKids.push_back(pad(bvLength, kids[i]));
05078   }
05079   return newBVMultExpr(bvLength, newKids);
05080 }
05081 
05082 
05083 Expr TheoryBitvector::newBVMultPadExpr(int bvLength,
05084                                        const Expr& t1, const Expr& t2)
05085 {
05086   return newBVMultExpr(bvLength, pad(bvLength, t1), pad(bvLength, t2));
05087 }
05088 
05089 Expr TheoryBitvector::newBVUDivExpr(const Expr& t1, const Expr& t2)
05090 {
05091     DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05092           BITVECTOR == t2.getType().getExpr().getOpKind(),
05093           "TheoryBitvector::newBVUDivExpr:"
05094           "inputs must have type BITVECTOR:\n t1 = " +
05095           t1.toString() + "\n t2 = " +t2.toString());
05096     DebugAssert(BVSize(t2) == BVSize(t1), "Expected same length");
05097     return Expr(BVUDIV, t1, t2);
05098 }
05099 
05100 Expr TheoryBitvector::newBVURemExpr(const Expr& t1, const Expr& t2)
05101 {
05102     DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05103           BITVECTOR == t2.getType().getExpr().getOpKind(),
05104           "TheoryBitvector::newBVURemExpr:"
05105           "inputs must have type BITVECTOR:\n t1 = " +
05106           t1.toString() + "\n t2 = " +t2.toString());
05107     DebugAssert(BVSize(t2) == BVSize(t1), "Expected same length");
05108     return Expr(BVUREM, t1, t2);
05109 }
05110 
05111 Expr TheoryBitvector::newBVSDivExpr(const Expr& t1, const Expr& t2)
05112 {
05113     DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05114           BITVECTOR == t2.getType().getExpr().getOpKind(),
05115           "TheoryBitvector::newBVSDivExpr:"
05116           "inputs must have type BITVECTOR:\n t1 = " +
05117           t1.toString() + "\n t2 = " +t2.toString());
05118     DebugAssert(BVSize(t1) == BVSize(t2), "Expected same length");
05119     return Expr(BVSDIV, t1, t2);
05120 }
05121 
05122 Expr TheoryBitvector::newBVSRemExpr(const Expr& t1, const Expr& t2)
05123 {
05124     DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05125           BITVECTOR == t2.getType().getExpr().getOpKind(),
05126           "TheoryBitvector::newBVSRemExpr:"
05127           "inputs must have type BITVECTOR:\n t1 = " +
05128           t1.toString() + "\n t2 = " +t2.toString());
05129     DebugAssert(BVSize(t1) == BVSize(t2), "Expected same length");
05130     return Expr(BVSREM, t1, t2);
05131 }
05132 
05133 Expr TheoryBitvector::newBVSModExpr(const Expr& t1, const Expr& t2)
05134 {
05135     DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05136           BITVECTOR == t2.getType().getExpr().getOpKind(),
05137           "TheoryBitvector::newBVSModExpr:"
05138           "inputs must have type BITVECTOR:\n t1 = " +
05139           t1.toString() + "\n t2 = " +t2.toString());
05140     DebugAssert(BVSize(t1) == BVSize(t2), "Expected same length");
05141     return Expr(BVSMOD, t1, t2);
05142 }
05143 
05144 //! produces a string of 0's of length bvLength
05145 Expr TheoryBitvector::newBVZeroString(int bvLength)
05146 {
05147   DebugAssert(bvLength > 0,
05148         "TheoryBitvector::newBVZeroString:must be >= 0: "
05149         + int2string(bvLength));
05150   std::vector<bool> bits;
05151   for(int count=0; count < bvLength; count++) {
05152     bits.push_back(false);
05153   }
05154   return newBVConstExpr(bits);
05155 }
05156 
05157 
05158 //! produces a string of 1's of length bvLength
05159 Expr TheoryBitvector::newBVOneString(int bvLength)
05160 {
05161   DebugAssert(bvLength > 0,
05162         "TheoryBitvector::newBVOneString:must be >= 0: "
05163         + int2string(bvLength));
05164   std::vector<bool> bits;
05165   for(int count=0; count < bvLength; count++) {
05166     bits.push_back(true);
05167   }
05168   return newBVConstExpr(bits);
05169 }
05170 
05171 
05172 Expr TheoryBitvector::newBVConstExpr(const vector<bool>& bits)
05173 {
05174   DebugAssert(bits.size() > 0,
05175         "TheoryBitvector::newBVConstExpr:"
05176         "size of bits should be > 0");
05177   BVConstExpr bv(getEM(), bits, d_bvConstExprIndex);
05178   return getEM()->newExpr(&bv);
05179 }
05180 
05181 
05182 Expr TheoryBitvector::newBVConstExpr(const Rational& r, int bvLength)
05183 {
05184   DebugAssert(r.isInteger(),
05185         "TheoryBitvector::newBVConstExpr: not an integer: "
05186         + r.toString());
05187   DebugAssert(bvLength > 0,
05188         "TheoryBitvector::newBVConstExpr: bvLength = "
05189         + int2string(bvLength));
05190   string s(r.toString(2));
05191   size_t strsize = s.size();
05192   size_t length = bvLength;
05193   Expr res;
05194   if(length > 0 && length != strsize) {
05195     //either (length > strsize) or (length < strsize)
05196     if(length < strsize) {
05197       s = s.substr((strsize-length), length);
05198     } else {
05199       string zeros("");
05200       for(size_t i=0, pad=length-strsize; i < pad; ++i)
05201   zeros += "0";
05202       s = zeros+s;
05203     }
05204 
05205     res = newBVConstExpr(s, 2);
05206   }
05207   else
05208     res = newBVConstExpr(s, 2);
05209 
05210   return res;
05211 }
05212 
05213 
05214 Expr TheoryBitvector::newBVConstExpr(const std::string& s, int base)
05215 {
05216   DebugAssert(s.size() > 0,
05217         "TheoryBitvector::newBVConstExpr:"
05218         "# of subterms must be at least 2");
05219   DebugAssert(base == 2 || base == 16,
05220         "TheoryBitvector::newBVConstExpr: base = "
05221         +int2string(base));
05222   //hexadecimal
05223   std::string str = s;
05224   if(16 == base) {
05225     Rational r(str, 16);
05226     return newBVConstExpr(r, str.size()*4);
05227   }
05228   else {
05229     BVConstExpr bv(getEM(), str, d_bvConstExprIndex);
05230     return getEM()->newExpr(&bv);
05231   }
05232 }
05233 
05234 
05235 Expr
05236 TheoryBitvector::
05237 newBVExtractExpr(const Expr& e, int hi, int low)
05238 {
05239   DebugAssert(low>=0 && hi>=low,
05240         " TheoryBitvector::newBVExtractExpr: "
05241         "bad bv_extract indices: hi = "
05242         + int2string(hi)
05243         + ", low = "
05244         + int2string(low));
05245   if (e.getOpKind() == LEFTSHIFT &&
05246       hi == BVSize(e[0])-1 &&
05247       low == 0) {
05248     return newFixedConstWidthLeftShiftExpr(e[0], getFixedLeftShiftParam(e));
05249   }
05250   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
05251         "TheoryBitvector::newBVExtractExpr:"
05252         "inputs must have type BITVECTOR:\n e = " +
05253         e.toString());
05254   return Expr(Expr(EXTRACT,
05255                    getEM()->newRatExpr(hi),
05256                    getEM()->newRatExpr(low)).mkOp(), e);
05257 }
05258 
05259 
05260 Expr TheoryBitvector::newBVSubExpr(const Expr& t1, const Expr& t2)
05261 {
05262   DebugAssert(BITVECTOR == t1.getType().getExpr().getOpKind() &&
05263         BITVECTOR == t2.getType().getExpr().getOpKind(),
05264         "TheoryBitvector::newBVSubExpr:"
05265         "inputs must have type BITVECTOR:\n t1 = " +
05266         t1.toString() + "\n t2 = " +t2.toString());
05267   DebugAssert(BVSize(t1) == BVSize(t2),
05268         "TheoryBitvector::newBVSubExpr"
05269         "inputs must have same length:\n t1 = " + t1.toString()
05270         + "\n t2 = " + t2.toString());
05271   return Expr(BVSUB, t1, t2);
05272 }
05273 
05274 
05275 Expr TheoryBitvector::newBVPlusExpr(int bvLength, const Expr& k1, const Expr& k2)
05276 {
05277   DebugAssert(bvLength > 0,
05278         " TheoryBitvector::newBVPlusExpr:"
05279         "bvplus length must be a positive integer: "+
05280         int2string(bvLength));
05281   DebugAssert(BITVECTOR == k1.getType().getExpr().getOpKind(),
05282               "TheoryBitvector::newBVPlusExpr:"
05283               "inputs must have type BITVECTOR:\n t1 = " +
05284               k1.toString());
05285   DebugAssert(BVSize(k1) == bvLength, "Expected matching sizes");
05286   DebugAssert(BITVECTOR == k2.getType().getExpr().getOpKind(),
05287               "TheoryBitvector::newBVPlusExpr:"
05288               "inputs must have type BITVECTOR:\n t1 = " +
05289               k2.toString());
05290   DebugAssert(BVSize(k2) == bvLength, "Expected matching sizes");
05291 
05292   return Expr(Expr(BVPLUS, getEM()->newRatExpr(bvLength)).mkOp(), k1, k2);
05293 }
05294 
05295 
05296 Expr TheoryBitvector::newBVPlusExpr(int bvLength,
05297             const vector<Expr>& k)
05298 {
05299   DebugAssert(bvLength > 0,
05300         " TheoryBitvector::newBVPlusExpr:"
05301         "bvplus length must be a positive integer: "+
05302         int2string(bvLength));
05303   DebugAssert(k.size() > 1,
05304         " TheoryBitvector::newBVPlusExpr:"
05305         " size of input vector must be greater than 0: ");
05306   for(unsigned int i=0; i<k.size(); ++i) {
05307     DebugAssert(BITVECTOR == k[i].getType().getExpr().getOpKind(),
05308     "TheoryBitvector::newBVPlusExpr:"
05309     "inputs must have type BITVECTOR:\n t1 = " +
05310     k[i].toString());
05311     DebugAssert(BVSize(k[i]) == bvLength, "Expected matching sizes");
05312   }
05313   return Expr(Expr(BVPLUS, getEM()->newRatExpr(bvLength)).mkOp(), k);
05314 }
05315 
05316 
05317 Expr TheoryBitvector::newBVPlusPadExpr(int bvLength,
05318                                        const vector<Expr>& k)
05319 {
05320   vector<Expr> newKids;
05321   for (unsigned i = 0; i < k.size(); ++i) {
05322     newKids.push_back(pad(bvLength, k[i]));
05323   }
05324   return newBVPlusExpr(bvLength, newKids);
05325 }
05326 
05327 
05328 // Accessors for expression parameters
05329 
05330 
05331 int TheoryBitvector::getBitvectorTypeParam(const Expr& e)
05332 {
05333   DebugAssert(BITVECTOR == e.getKind(),
05334         "TheoryBitvector::getBitvectorTypeParam: wrong kind: " +
05335         e.toString());
05336   return e[0].getRational().getInt();
05337 }
05338 
05339 
05340 Type TheoryBitvector::getTypePredType(const Expr& tp)
05341 {
05342   DebugAssert(tp.getOpKind()==BVTYPEPRED && tp.isApply(),
05343         "TheoryBitvector::getTypePredType:\n tp = "+tp.toString());
05344   return Type(tp.getOpExpr()[0]);
05345 }
05346 
05347 
05348 const Expr& TheoryBitvector::getTypePredExpr(const Expr& tp)
05349 {
05350   DebugAssert(tp.getOpKind()==BVTYPEPRED,
05351         "TheoryBitvector::getTypePredType:\n tp = "+tp.toString());
05352   return tp[0];
05353 }
05354 
05355 
05356 int TheoryBitvector::getBoolExtractIndex(const Expr& e)
05357 {
05358   DebugAssert(BOOLEXTRACT == e.getOpKind() && e.isApply(),
05359         "TheoryBitvector::getBoolExtractIndex: wrong kind" +
05360         e.toString());
05361   return e.getOpExpr()[0].getRational().getInt();
05362 }
05363 
05364 
05365 int TheoryBitvector::getSXIndex(const Expr& e)
05366 {
05367   DebugAssert(SX == e.getOpKind() && e.isApply(),
05368         "TheoryBitvector::getSXIndex: wrong kind\n"+e.toString());
05369   return e.getOpExpr()[0].getRational().getInt();
05370 }
05371 
05372 
05373 int TheoryBitvector::getBVIndex(const Expr& e)
05374 {
05375   DebugAssert(e.isApply() &&
05376               (e.getOpKind() == BVREPEAT ||
05377                e.getOpKind() == BVROTL ||
05378                e.getOpKind() == BVROTR ||
05379                e.getOpKind() == BVZEROEXTEND),
05380         "TheoryBitvector::getBVIndex: wrong kind\n"+e.toString());
05381   return e.getOpExpr()[0].getRational().getInt();
05382 }
05383 
05384 
05385 int TheoryBitvector::getFixedLeftShiftParam(const Expr& e)
05386 {
05387   DebugAssert(e.isApply() &&
05388               (LEFTSHIFT == e.getOpKind() ||
05389                CONST_WIDTH_LEFTSHIFT == e.getOpKind()),
05390         "TheoryBitvector::getFixedLeftShiftParam: wrong kind" +
05391         e.toString());
05392   return e.getOpExpr()[0].getRational().getInt();
05393 }
05394 
05395 
05396 int TheoryBitvector::getFixedRightShiftParam(const Expr& e)
05397 {
05398   DebugAssert(RIGHTSHIFT == e.getOpKind() && e.isApply(),
05399         "TheoryBitvector::getFixedRightShiftParam: wrong kind" +
05400         e.toString());
05401   return e.getOpExpr()[0].getRational().getInt();
05402 }
05403 
05404 
05405 int TheoryBitvector::getExtractLow(const Expr& e)
05406 {
05407   DebugAssert(EXTRACT == e.getOpKind() && e.isApply(),
05408         "TheoryBitvector::getExtractLow: wrong kind" +
05409         e.toString());
05410   return e.getOpExpr()[1].getRational().getInt();
05411 }
05412 
05413 
05414 int TheoryBitvector::getExtractHi(const Expr& e)
05415 {
05416   DebugAssert(EXTRACT == e.getOpKind() && e.isApply(),
05417         "TheoryBitvector::getExtractHi: wrong kind" +
05418         e.toString());
05419   return e.getOpExpr()[0].getRational().getInt();
05420 }
05421 
05422 
05423 int TheoryBitvector::getBVPlusParam(const Expr& e)
05424 {
05425   DebugAssert(BVPLUS == e.getOpKind() && e.isApply(),
05426         "TheoryBitvector::getBVPlusParam: wrong kind" +
05427         e.toString(AST_LANG));
05428   return e.getOpExpr()[0].getRational().getInt();
05429 }
05430 
05431 int TheoryBitvector::getBVMultParam(const Expr& e)
05432 {
05433   DebugAssert(BVMULT == e.getOpKind() && e.isApply(),
05434         "TheoryBitvector::getBVMultParam: wrong kind " +
05435         e.toString(AST_LANG));
05436   return e.getOpExpr()[0].getRational().getInt();
05437 }
05438 
05439 unsigned TheoryBitvector::getBVConstSize(const Expr& e)
05440 {
05441   DebugAssert(BVCONST == e.getKind(), "getBVConstSize called on non-bvconst");
05442   const BVConstExpr* bvc = dynamic_cast<const BVConstExpr*>(e.getExprValue());
05443   DebugAssert(bvc, "getBVConstSize: cast failed");
05444   return bvc->size();
05445 }
05446 
05447 
05448 bool TheoryBitvector::getBVConstValue(const Expr& e, int i)
05449 {
05450   DebugAssert(BVCONST == e.getKind(), "getBVConstSize called on non-bvconst");
05451   const BVConstExpr* bvc = dynamic_cast<const BVConstExpr*>(e.getExprValue());
05452   DebugAssert(bvc, "getBVConstSize: cast failed");
05453   return bvc->getValue(i);
05454 }
05455 
05456 
05457 // as newBVConstExpr can not give the BV expr of a negative rational,
05458 // I use this wrapper to do that
05459 Expr TheoryBitvector::signed_newBVConstExpr( Rational c, int bv_size)
05460 {
05461   if( c > 0)
05462     return newBVConstExpr( c, bv_size);
05463   else
05464     {
05465       c = -c;
05466       Expr tmp = newBVConstExpr( c, bv_size);
05467       Rational neg_tmp = computeNegBVConst( tmp );
05468       return newBVConstExpr( neg_tmp, bv_size );
05469     }
05470 }
05471 
05472 
05473 // Computes the integer value of a bitvector constant
05474 Rational TheoryBitvector::computeBVConst(const Expr& e)
05475 {
05476   DebugAssert(BVCONST == e.getKind(),
05477         "TheoryBitvector::computeBVConst:"
05478         "input must be a BITVECTOR CONST: " + e.toString());
05479   if(*d_bv32Flag) {
05480     int c(0);
05481     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
05482       c = 2*c + getBVConstValue(e, j) ? 1 : 0;
05483     Rational d(c);
05484     return d;
05485   } else {
05486     Rational c(0);
05487     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
05488       c = 2*c + (getBVConstValue(e, j) ? Rational(1) : Rational(0));
05489     return c;
05490   }
05491 }
05492 
05493 
05494 // Computes the integer value of ~c+1
05495 Rational TheoryBitvector::computeNegBVConst(const Expr& e)
05496 {
05497   DebugAssert(BVCONST == e.getKind(),
05498         "TheoryBitvector::computeBVConst:"
05499         "input must be a BITVECTOR CONST: " + e.toString());
05500   if(*d_bv32Flag) {
05501     int c(0);
05502     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
05503       c = 2*c + getBVConstValue(e, j) ? 0 : 1;
05504     Rational d(c+1);
05505     return d;
05506   } else {
05507     Rational c(0);
05508     for(int j=(int)getBVConstSize(e)-1; j>=0; j--)
05509       c = 2*c + (getBVConstValue(e, j) ? Rational(0) : Rational(1));
05510     return c+1;
05511   }
05512 }
05513 
05514 
05515 //////////////////////////////////////////////////////////////////////
05516 // class BVConstExpr methods
05517 /////////////////////////////////////////////////////////////////////
05518 
05519 
05520 //! Constructor
05521 BVConstExpr::BVConstExpr(ExprManager* em, std::string bvconst,
05522        size_t mmIndex, ExprIndex idx)
05523   : ExprValue(em, BVCONST, idx), d_MMIndex(mmIndex)
05524 {
05525   std::string::reverse_iterator i = bvconst.rbegin();
05526   std::string::reverse_iterator iend = bvconst.rend();
05527   DebugAssert(bvconst.size() > 0,
05528         "TheoryBitvector::newBVConstExpr:"
05529         "# of subterms must be at least 2");
05530 
05531   for(;i != iend; ++i) {
05532     TRACE("bitvector", "BVConstExpr: bit ", *i, "");
05533     if('0' == *i)
05534       d_bvconst.push_back(false);
05535     else {
05536       if('1' == *i)
05537   d_bvconst.push_back(true);
05538       else
05539   DebugAssert(false, "BVConstExpr: bad binary bit-vector: "
05540         + bvconst);
05541     }
05542   }
05543   TRACE("bitvector", "BVConstExpr: #bits ", d_bvconst.size(), "");
05544 }
05545 
05546 
05547 BVConstExpr::BVConstExpr(ExprManager* em, std::vector<bool> bvconst,
05548                          size_t mmIndex, ExprIndex idx)
05549   : ExprValue(em, BVCONST, idx), d_bvconst(bvconst), d_MMIndex(mmIndex)
05550 {
05551   TRACE("bitvector", "BVConstExpr(vector<bool>): arg. size = ", bvconst.size(),
05552   ", d_bvconst.size = "+int2string(d_bvconst.size()));
05553 }
05554 
05555 
05556 size_t BVConstExpr::computeHash() const
05557 {
05558   std::vector<bool>::const_iterator i = d_bvconst.begin();
05559   std::vector<bool>::const_iterator iend = d_bvconst.end();
05560   size_t hash_value = 0;
05561   hash_value = ExprValue::hash(BVCONST);
05562   for (;i != iend; i++)
05563     if(*i)
05564       hash_value = PRIME*hash_value + HASH_VALUE_ONE;
05565     else
05566       hash_value = PRIME*hash_value + HASH_VALUE_ZERO;
05567   return hash_value;
05568 }
05569 
05570 Expr TheoryBitvector::computeTCC(const Expr& e)
05571 {
05572   // inline recursive computation for deeply nested bitvector Exprs
05573 
05574   vector<Expr> operatorStack;
05575   vector<Expr> operandStack;
05576   vector<int> childStack;
05577   Expr e2, tcc;
05578 
05579   operatorStack.push_back(e);
05580   childStack.push_back(0);
05581 
05582   while (!operatorStack.empty()) {
05583     DebugAssert(operatorStack.size() == childStack.size(), "Invariant violated");
05584 
05585     if (childStack.back() < operatorStack.back().arity()) {
05586 
05587       e2 = operatorStack.back()[childStack.back()++];
05588 
05589       if (e2.isVar()) {
05590         operandStack.push_back(trueExpr());
05591       }
05592       else {
05593         ExprMap<Expr>::iterator itccCache = theoryCore()->tccCache().find(e2);
05594         if (itccCache != theoryCore()->tccCache().end()) {
05595           operandStack.push_back((*itccCache).second);
05596         }
05597         else if (theoryOf(e2) == this) {
05598           if (e2.arity() == 0) {
05599             operandStack.push_back(trueExpr());
05600           }
05601           else {
05602             operatorStack.push_back(e2);
05603             childStack.push_back(0);
05604           }
05605         }
05606         else {
05607           operandStack.push_back(getTCC(e2));
05608         }
05609       }
05610     }
05611     else {
05612       e2 = operatorStack.back();
05613       operatorStack.pop_back();
05614       childStack.pop_back();
05615       vector<Expr> children;
05616       vector<Expr>::iterator childStart = operandStack.end() - (e2.arity());
05617       children.insert(children.begin(), childStart, operandStack.end());
05618       operandStack.erase(childStart, operandStack.end());
05619       tcc = (children.size() == 0) ? trueExpr() :
05620         (children.size() == 1) ? children[0] :
05621         getCommonRules()->rewriteAnd(andExpr(children)).getRHS();
05622       switch(e2.getKind()) {
05623         case BVUDIV:
05624         case BVSDIV:
05625         case BVUREM:
05626         case BVSREM:
05627         case BVSMOD: {
05628           DebugAssert(e2.arity() == 2, "");
05629           int size = BVSize(e2);
05630           tcc = getCommonRules()->rewriteAnd(tcc.andExpr(!(e2[1].eqExpr(newBVZeroString(size))))).getRHS();
05631           break;
05632         }
05633         default:
05634           break;
05635       }
05636       operandStack.push_back(tcc);
05637       theoryCore()->tccCache()[e2] = tcc;
05638     }
05639   }
05640   DebugAssert(childStack.empty(), "Invariant violated");
05641   DebugAssert(operandStack.size() == 1, "Expected single operand left");
05642   return operandStack.back();
05643 }