1 /*****************************************************************************/
2 /*!
3  * \file bitvector_theorem_producer.cpp
4  *
5  * Author: Vijay Ganesh
6  *
7  * Created: Wed May  5 16:19:49 PST 2004
8  *
9  * <hr>
10  *
11  * License to use, copy, modify, sell and/or distribute this software
12  * and its documentation for any purpose is hereby granted without
13  * royalty, subject to the terms and conditions defined in the \ref
14  * LICENSE file provided with this distribution.
15  *
16  * <hr>
17  *
18  */
19 /*****************************************************************************/
20 // CLASS: BitvectorProofRules
21 //
22 // AUTHOR: Vijay Ganesh,   05/30/2003
23 //
24 // Description: TRUSTED implementation of bitvector proof rules.
25 //
26 ///////////////////////////////////////////////////////////////////////////////
27 
28 // This code is trusted
29 #define _CVC3_TRUSTED_
30 
31 #include <cstdio>
32 #include "bitvector_theorem_producer.h"
33 #include "common_proof_rules.h"
34 #include "theory_core.h"
35 #include "theory_bitvector.h"
36 
37 using namespace std;
38 using namespace CVC3;
39 
40 
41 ///////////////////////////////////////////////////////////////////////
42 // TheoryBitvector:trusted method for creating BitvectorTheoremProducer
43 ///////////////////////////////////////////////////////////////////////
44 BitvectorProofRules*
createProofRules()45 TheoryBitvector::createProofRules() {
46   return new BitvectorTheoremProducer(this);
47 }
48 
49 
BitvectorTheoremProducer(TheoryBitvector * theoryBV)50 BitvectorTheoremProducer::BitvectorTheoremProducer(TheoryBitvector* theoryBV)
51   : TheoremProducer(theoryBV->theoryCore()->getTM()),
52     d_theoryBitvector(theoryBV) {
53   // Cache constants 0bin0 and 0bin1
54   vector<bool> bits(1);
55   bits[0]=false;
56   d_bvZero = d_theoryBitvector->newBVConstExpr(bits);
57   bits[0]=true;
58   d_bvOne = d_theoryBitvector->newBVConstExpr(bits);
59 }
60 
61 
62 ///////////////////////////////////////////////////////////////////////
63 // BitBlasting rules for equations
64 ///////////////////////////////////////////////////////////////////////
65 // |- (BOOLEXTRACT(a,i) <=> BOOLEXTRACT(b,i)) <=> False ==> |- a = b <=> False
bitvectorFalseRule(const Theorem & thm)66 Theorem BitvectorTheoremProducer::bitvectorFalseRule(const Theorem& thm) {
67   if(CHECK_PROOFS) {
68     const Expr e = thm.getExpr();
69     CHECK_SOUND(e.isIff() && e[0].isIff(),
70 		"TheoryBitvector::bitvectorFalseRule: "
71 		"premise must be a iff theorem:\n e = "
72 		+e.toString());
73     CHECK_SOUND(e[1].isFalse(),
74 		"TheoryBitvector::bitvectorFalseRule: "
75 		"premise must be iff Theorem, with False as the RHS:\n e = "
76 		+e.toString());
77     CHECK_SOUND(e[0][0].getOpKind() == BOOLEXTRACT &&
78 		e[0][1].getOpKind() == BOOLEXTRACT,
79 		"TheoryBitvector::bitvectorFalseRule: "
80 		"premise must be iff Theorem, with False as the RHS:\n e = "
81 		+e.toString());
82     CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(e[0][0]) ==
83 		d_theoryBitvector->getBoolExtractIndex(e[0][1]),
84 		"TheoryBitvector::bitvectorFalseRule: "
85 		"premise must be iff Theorem, with False as the RHS:\n e = "
86 		+e.toString());
87   }
88   const Expr& e = thm.getExpr();
89   const Expr& t1 = e[0][0][0];
90   const Expr& t2 = e[0][1][0];
91 
92   Proof pf;
93   if(withProof())
94     pf = newPf("bitvector_false_rule", e, thm.getProof());
95   return newRWTheorem(t1.eqExpr(t2), e[1], thm.getAssumptionsRef(), pf);
96 }
97 
98     /*! \param thm input theorem: (~e1[i]<=>e2[i])<=>true
99      *
100      *  \result (e1!=e2)<=>true
101      */
102 // |- (NOT (BOOLEXTRACT(a,i)) <=> BOOLEXTRACT(b,i)) <=> TRUE ==>
103 // |- NOT (a = b) <=> TRUE
bitvectorTrueRule(const Theorem & thm)104 Theorem BitvectorTheoremProducer::bitvectorTrueRule(const Theorem& thm) {
105   if(CHECK_PROOFS) {
106     const Expr e = thm.getExpr();
107     CHECK_SOUND(e.isIff() && e[0].isIff(),
108 		"TheoryBitvector::bitvectorFalseRule: "
109 		"premise must be a iff theorem:\n e = "
110 		+e.toString());
111     CHECK_SOUND(e[1].isTrue(),
112 		"TheoryBitvector::bitvectorFalseRule: "
113 		"premise must be iff Theorem, with False as the RHS:\n e = "
114 		+e.toString());
115     CHECK_SOUND(e[0][0].getKind() == NOT &&
116 		e[0][0][0].getOpKind() == BOOLEXTRACT &&
117 		e[0][1].getOpKind() == BOOLEXTRACT,
118 		"TheoryBitvector::bitvectorFalseRule: "
119 		"premise must be iff Theorem, with False as the RHS:\n e = "
120 		+e.toString());
121     CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(e[0][0][0]) ==
122 		d_theoryBitvector->getBoolExtractIndex(e[0][1]),
123 		"TheoryBitvector::bitvectorFalseRule: "
124 		"premise must be iff Theorem, with False as the RHS:\n e = "
125 		+e.toString());
126   }
127   const Expr& e = thm.getExpr();
128   //e is (~BE(t1,i)<=>BE(t2,i))<=>true. to extract t1 we have to go 4 level deep
129   //FIXME: later
130   const Expr& t1 = e[0][0][0][0];
131   const Expr& t2 = e[0][1][0];
132 
133   Proof pf;
134   if(withProof())
135     pf = newPf("bitvector_true_rule", e, thm.getProof());
136   return newRWTheorem(t1.eqExpr(t2).negate(), e[1], thm.getAssumptionsRef(), pf);
137 }
138 
139 // Input: e: a = b
140 //        f :AND_0^(bvLength-1)(a[bitPosition] <=> b[bitPosition])
141 // Output: |- e <=> f
bitBlastEqnRule(const Expr & e,const Expr & f)142 Theorem BitvectorTheoremProducer::bitBlastEqnRule(const Expr& e, const Expr& f)
143 {
144   if(CHECK_PROOFS) {
145     CHECK_SOUND(e.isEq(),
146 		"TheoryBitvector::bitBlastEqnRule: "
147 		"premise must be a rewrite theorem:\n e = "
148 		+e.toString());
149     const Expr& lhs = e[0];
150     const Expr& rhs = e[1];
151     const Type& leftType = lhs.getType();
152     const Type& rightType = rhs.getType();
153     CHECK_SOUND(BITVECTOR == leftType.getExpr().getOpKind() &&
154 		BITVECTOR == rightType.getExpr().getOpKind(),
155 		"TheoryBitvector::bitBlastEqnRule: "
156 		"lhs & rhs must be bitvectors:\n e ="
157 		+e.toString());
158     int lhsLength = d_theoryBitvector->BVSize(lhs);
159     int rhsLength = d_theoryBitvector->BVSize(rhs);
160     CHECK_SOUND(lhsLength == rhsLength,
161 		"TheoryBitvector::bitBlastEqnRule: "
162 		"lhs & rhs must be bitvectors of same bvLength.\n size(lhs) = "
163 		+ int2string(lhsLength)
164 		+"\n size(rhs) = "
165 		+ int2string(rhsLength)
166 		+"\n e = "+e.toString());
167     int bvLength = d_theoryBitvector->BVSize(leftType.getExpr());
168     CHECK_SOUND(f.isAnd(),
169 		"TheoryBitvector::bitBlastEqnRule: "
170 		"consequence of the rule must be an AND.\n f = "
171 		+f.toString());
172     CHECK_SOUND(bvLength == f.arity(),
173 		"TheoryBitvector::bitBlastEqnRule: "
174 		"the arity of the consequence AND must "
175 		"equal the bvLength of the bitvector:\n f = "
176 		+f.toString()+"\n bvLength = "+ int2string(bvLength));
177     for (int i=0; i < bvLength; ++i) {
178       const Expr& conjunct = f[i];
179       CHECK_SOUND(conjunct.isIff() && 2 == conjunct.arity(),
180 		  "TheoryBitvector::bitBlastEqnRule: "
181 		  "each conjunct in consequent must be an IFF.\n f = "
182 		  +f.toString());
183       const Expr& leftExtract = conjunct[0];
184       const Expr& rightExtract = conjunct[1];
185       CHECK_SOUND(BOOLEXTRACT == leftExtract.getOpKind(),
186 		  "TheoryBitvector::bitBlastEqnRule: "
187 		  "each conjunct in consequent must be boolextract.\n"
188 		  " f["+int2string(i)+"] = "+conjunct.toString());
189       CHECK_SOUND(BOOLEXTRACT == rightExtract.getOpKind(),
190 		  "TheoryBitvector::bitBlastEqnRule: "
191 		  "each conjunct in consequent must be boolextract.\n"
192 		  " f["+int2string(i)+"] = "+conjunct.toString());
193       const Expr& leftBV = leftExtract[0];
194       const Expr& rightBV = rightExtract[0];
195       CHECK_SOUND(leftBV == lhs && rightBV == rhs,
196 		  "TheoryBitvector::bitBlastEqnRule: each boolextract"
197 		  " must be applied to the correct bitvector.\n conjunct = "
198 		  +conjunct.toString()
199 		  +"\n leftBV = "+ leftBV.toString()
200 		  +"\n lhs = "+ lhs.toString()
201 		  +"\n rightBV = "+rightBV.toString()
202 		  +"\n rhs = "+rhs.toString());
203       int leftBitPosition =
204 	d_theoryBitvector->getBoolExtractIndex(leftExtract);
205       int rightBitPosition =
206 	d_theoryBitvector->getBoolExtractIndex(rightExtract);
207       CHECK_SOUND(leftBitPosition == i && rightBitPosition == i,
208 		  "TheoryBitvector::bitBlastEqnRule: "
209 		  "boolextract positions must match i= "+int2string(i)
210 		  +"\n conjunct = "+conjunct.toString());
211     }
212   }
213 
214   Proof pf;
215   if(withProof())
216     pf = newPf("bit_blast_equations", e, f);
217   return newRWTheorem(e, f, Assumptions::emptyAssump(), pf);
218 }
219 
220 
221 ///////////////////////////////////////////////////////////////////////
222 // BitBlasting rules for dis-equations: separate rule for disequations
223 // for efficiency sake
224 ///////////////////////////////////////////////////////////////////////
bitBlastDisEqnRule(const Theorem & notE,const Expr & f)225 Theorem BitvectorTheoremProducer::bitBlastDisEqnRule(const Theorem& notE,
226 						     const Expr& f){
227 
228   TRACE("bitvector", "input to bitBlastDisEqnRule(", notE.toString(), ")");
229   DebugAssert(notE.getExpr().isNot() && (notE.getExpr())[0].isEq(),
230 	      "TheoryBitvector::bitBlastDisEqnRule:"
231 	      "expecting an equation" + notE.getExpr().toString());
232   //e is the equation
233   const Expr& e = (notE.getExpr())[0];
234   if(CHECK_PROOFS) {
235     CHECK_SOUND(e.isEq(),
236 		"TheoryBitvector::bitBlastDisEqnRule:"
237 		"premise must be a rewrite theorem" + e.toString());
238     const Expr& lhs = e[0];
239     const Expr& rhs = e[1];
240     const Type& leftType = lhs.getType();
241     const Type& rightType = rhs.getType();
242     CHECK_SOUND(BITVECTOR == leftType.getExpr().getOpKind() &&
243 		BITVECTOR == rightType.getExpr().getOpKind(),
244 		"TheoryBitvector::bitBlastDisEqnRule:"
245 		"lhs & rhs must be bitvectors" + e.toString());
246     CHECK_SOUND(d_theoryBitvector->BVSize(leftType.getExpr()) ==
247 		d_theoryBitvector->BVSize(rightType.getExpr()),
248 		"TheoryBitvector::bitBlastDisEqnRule:"
249 		"lhs & rhs must be bitvectors of same bvLength");
250     int bvLength = d_theoryBitvector->BVSize(leftType.getExpr());
251     CHECK_SOUND(f.isOr(),
252 		"TheoryBitvector::bitBlastDisEqnRule:"
253 		"consequence of the rule must be an OR" + f.toString());
254     CHECK_SOUND(bvLength == f.arity(),
255 		"TheoryBitvector::bitBlastDisEqnRule:"
256 		"the arity of the consequence OR must be"
257 		"equal to the bvLength of the bitvector" +
258 		f.toString() + int2string(bvLength));
259     for(int i=0; i <bvLength; i++) {
260       const Expr& disjunct = f[i];
261       CHECK_SOUND(disjunct.isIff() &&
262 		  2 == disjunct.arity() && disjunct[0].isNot(),
263 		  "TheoryBitvector::bitBlastDisEqnRule:"
264 		  "each conjunct in consequent must be an Iff"+f.toString());
265       const Expr& leftExtract = (disjunct[0])[0];
266       const Expr& rightExtract = disjunct[1];
267       CHECK_SOUND(BOOLEXTRACT == leftExtract.getOpKind(),
268 		  "TheoryBitvector::bitBlastDisEqnRule:"
269 		  "each disjunct in consequent must be boolextract" +
270 		  disjunct.toString());
271       CHECK_SOUND(BOOLEXTRACT == rightExtract.getOpKind(),
272 		  "TheoryBitvector::bitBlastDisEqnRule:"
273 		  "each conjunct in consequent must be boolextract" +
274 		  disjunct.toString());
275       const Expr& leftBV = leftExtract[0];
276       const Expr& rightBV = rightExtract[0];
277       CHECK_SOUND(leftBV == lhs && rightBV == rhs,
278 		  "TheoryBitvector::bitBlastDisEqnRule:"
279 		  "each boolextract must be applied to the correct bitvector"+
280 		  disjunct.toString() + leftBV.toString() + lhs.toString() +
281 		  rightBV.toString() + rhs.toString());
282       int leftBitPosition =
283 	d_theoryBitvector->getBoolExtractIndex(leftExtract);
284       int rightBitPosition =
285 	d_theoryBitvector->getBoolExtractIndex(rightExtract);
286       CHECK_SOUND(leftBitPosition == i && rightBitPosition == i,
287 		  "TheoryBitvector::bitBlastDisEqnRule:"
288 		  "boolextract positions must match" + disjunct.toString());
289     }
290   }
291 
292   Proof pf;
293   if(withProof())
294     pf = newPf("bit_blast_disequations", notE.getExpr(), f, notE.getProof());
295   return newTheorem(f, notE.getAssumptionsRef(), pf);
296 }
297 
298 ///////////////////////////////////////////////////////////////////////
299 // Rules for Inequations
300 ///////////////////////////////////////////////////////////////////////
301 
302 
303 //! Pad the kids of BVLT/BVLE to make their bvLength equal
304 Theorem
padBVLTRule(const Expr & e,int len)305 BitvectorTheoremProducer::padBVLTRule(const Expr& e, int len) {
306   if(CHECK_PROOFS) {
307     CHECK_SOUND((BVLT == e.getOpKind() || BVLE == e.getOpKind()) &&
308 		e.arity()==2,
309 		"BitvectorTheoremProducer::padBVLTRule: "
310 		"input must e be a BVLT/BVLE: e = " + e.toString());
311     CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
312 		BITVECTOR==e[1].getType().getExpr().getOpKind(),
313 		"BitvectorTheoremProducer::padBVLTRule: "
314 		"for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
315     CHECK_SOUND(0<len,
316 		"BitvectorTheoremProducer::padBVLTRule: "
317 		"input len must be >=0 and an integer: len = " +
318 		int2string(len));
319   }
320   Expr e0 = pad(len, e[0]);
321   Expr e1 = pad(len, e[1]);
322   int kind = e.getOpKind();
323 
324   Expr output;
325   if(kind == BVLT)
326     output = d_theoryBitvector->newBVLTExpr(e0,e1);
327   else
328     output = d_theoryBitvector->newBVLEExpr(e0,e1);
329 
330   Proof pf;
331   if(withProof())
332     pf = newPf("pad_bvlt_rule", e);
333   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
334   return result;
335 }
336 
337 //! signExtendRule: pads the input e with topBit to length len
338 Theorem
signExtendRule(const Expr & e)339 BitvectorTheoremProducer::signExtendRule(const Expr& e) {
340   if(CHECK_PROOFS) {
341     CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(),
342 		"input must be a bitvector. \n e = " + e.toString());
343     CHECK_SOUND(SX == e.getOpKind(),
344 		"input must be SX(e).\n e = " + e.toString());
345     CHECK_SOUND(SX != e[0].getOpKind(),
346 		"input cannot have nested SX.\n e = " + e.toString());
347   }
348   Expr input0 = e[0];
349   //strip the top level SX applications
350   while(SX == input0.getOpKind())
351     input0 = input0[0];
352 
353   int bvLength = d_theoryBitvector->BVSize(e);
354   int bvLength0 = d_theoryBitvector->BVSize(input0);
355 
356   Expr output;
357   if(bvLength0 == bvLength) {
358     output = input0;
359   } else if(bvLength0 < bvLength) {
360     std::vector<Expr> k;
361     int c = bvLength - bvLength0;
362     Expr topBit =
363       d_theoryBitvector->newBVExtractExpr(input0,bvLength0-1,bvLength0-1);
364     while(c--)
365       k.push_back(topBit);
366     k.push_back(input0);
367     output = d_theoryBitvector->newConcatExpr(k);
368   } else
369     output = d_theoryBitvector->newBVExtractExpr(input0, bvLength-1, 0);
370 
371   Proof pf;
372   if(withProof())
373     pf = newPf("sign_extend_rule", e);
374   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
375   return result;
376 }
377 
378 //! bitExtractSXRule
379 Theorem
bitExtractSXRule(const Expr & e,int i)380 BitvectorTheoremProducer::bitExtractSXRule(const Expr& e, int i) {
381   //little bit of cheating here. calling a rule from inside a rule.
382   //just a shorthand
383   Theorem thm = signExtendRule(e);
384   Expr e_i = d_theoryBitvector->newBoolExtractExpr(e,i);
385   Expr newE_i = d_theoryBitvector->newBoolExtractExpr(thm.getRHS(),i);
386 
387   Proof pf;
388   if(withProof())
389     pf = newPf("bitExtract_SX_rule",e,rat(i));
390   Theorem result(newRWTheorem(e_i,newE_i,Assumptions::emptyAssump(),pf));
391   return result;
392 }
393 
394 
395 //! Pad the kids of SIGN BVLT/SIGN BVLE to make their bvLength equal
396 Theorem
padBVSLTRule(const Expr & e,int len)397 BitvectorTheoremProducer::padBVSLTRule(const Expr& e, int len) {
398   if(CHECK_PROOFS) {
399     CHECK_SOUND((BVSLT == e.getOpKind() || BVSLE == e.getOpKind()) &&
400 		e.arity()==2,
401 		"BitvectorTheoremProducer::padBVSLTRule: "
402 		"input must e be a BVSLT/BVSLE: e = " + e.toString());
403     CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
404 		BITVECTOR==e[1].getType().getExpr().getOpKind(),
405 		"BitvectorTheoremProducer::padBVSLTRule: "
406 		"for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
407     CHECK_SOUND(0<=len,
408 		"BitvectorTheoremProducer::padBVSLTRule: "
409 		"input len must be >=0 and an integer: len = " +
410 		int2string(len));
411   }
412   Expr e0 = d_theoryBitvector->newSXExpr(e[0], len);
413   Expr e1 = d_theoryBitvector->newSXExpr(e[1], len);
414   int kind = e.getOpKind();
415 
416   Expr output;
417   if(kind == BVSLT)
418     output = d_theoryBitvector->newBVSLTExpr(e0,e1);
419   else
420     output = d_theoryBitvector->newBVSLEExpr(e0,e1);
421 
422   Proof pf;
423   if(withProof())
424     pf = newPf("pad_bvslt_rule", e);
425   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
426   return result;
427 }
428 
429 /*! input: e0 <=(s) e1. output depends on whether the topbits(MSB) of
430  *  e0 and e1 are constants. If they are constants then optimizations
431  *  are done, otherwise the following rule is implemented.
432  *
433  *  e0 <=(s) e1 <==> (e0[n-1] AND NOT e1[n-1]) OR
434  *                   (e0[n-1] = e1[n-1] AND e0[n-2:0] <= e1[n-2:0])
435  */
436 Theorem
signBVLTRule(const Expr & e,const Theorem & topBit0,const Theorem & topBit1)437 BitvectorTheoremProducer::signBVLTRule(const Expr& e,
438 				       const Theorem& topBit0,
439 				       const Theorem& topBit1){
440   if(CHECK_PROOFS) {
441     CHECK_SOUND((BVSLT == e.getOpKind() || BVSLE == e.getOpKind()) &&
442 		e.arity()==2,
443 		"BitvectorTheoremProducer::signedBVLTRule: "
444 		"input must e be a BVSLT/BVSLE: e = " + e.toString());
445     CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
446 		BITVECTOR==e[1].getType().getExpr().getOpKind(),
447 		"BitvectorTheoremProducer::signedBVLTRule: "
448 		"for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
449   }
450   const Expr e0 = e[0];
451   const Expr e1 = e[1];
452   int e0len = d_theoryBitvector->BVSize(e0);
453   int e1len = d_theoryBitvector->BVSize(e1);
454 
455   if(CHECK_PROOFS) {
456     const Expr e0ext =
457       d_theoryBitvector->newBVExtractExpr(e0,e0len-1,e0len-1);
458     const Expr e1ext =
459       d_theoryBitvector->newBVExtractExpr(e1,e1len-1,e1len-1);
460     CHECK_SOUND(e0ext == topBit0.getLHS(),
461 		"BitvectorTheoremProducer::signedBVLTRule: "
462 		"topBit0.getLHS() is the un-rewritten form of MSB of e0\n"
463 		"topBit0 is screwed up: topBit0 = " +
464 		topBit0.getExpr().toString());
465     CHECK_SOUND(e1ext == topBit1.getLHS(),
466 		"BitvectorTheoremProducer::signedBVLTRule: "
467 		"topBit1.getLHS() is the un-rewritten form of MSB of e1\n"
468 		"topBit1 is screwed up: topBit1 = " +
469 		topBit1.getExpr().toString());
470     CHECK_SOUND(e0len == e1len,
471 		"BitvectorTheoremProducer::signedBVLTRule: "
472 		"both e[0] and e[1] must have the same length\n. e =" +
473 		e.toString());
474   }
475   const Expr MSB0 = topBit0.getRHS();
476   const Expr MSB1 = topBit1.getRHS();
477 
478   int eKind = e.getOpKind();
479   Expr output;
480 
481   //if both MSBs are constants, then we can optimize the output.  we
482   //know precisely the value of the signed comparison in cases where
483   //topbit of e0 and e1 are constants. e.g. |-1\@t0 < 0\@t1 is clearly
484   //|-TRUE.
485 
486   //-1 indicates that both topBits are not known to be BVCONSTS
487   Rational b0 = -1;
488   Rational b1 = -1;
489   if(MSB0.getKind() == BVCONST) b0 = d_theoryBitvector->computeBVConst(MSB0);
490   if(MSB1.getKind() == BVCONST) b1 = d_theoryBitvector->computeBVConst(MSB1);
491 
492   //useful expressions to be used below
493   const Expr tExpr = d_theoryBitvector->trueExpr();
494   const Expr fExpr = d_theoryBitvector->falseExpr();
495   const Expr MSB0isZero = MSB0.eqExpr(bvZero());
496   const Expr MSB0isOne  = MSB0.eqExpr(bvOne());
497   const Expr MSB1isZero = MSB1.eqExpr(bvZero());
498   const Expr MSB1isOne  = MSB1.eqExpr(bvOne());
499 
500   //handle single bit e0 <=(s) e1 in a special way. this is clumsy
501   //(i.e. extra and redundant code) but much more efficient and easy
502   //to read
503   if(e0len == 1) {
504     if(b0==0 && b1==0)
505       output = eKind==BVSLT ? fExpr      : tExpr;
506     else if(b0==0  && b1==1)
507       output = fExpr;
508     else if(b0==1  && b1==0)
509       output = tExpr;
510     else if(b0==1  && b1==1)
511       output = eKind==BVSLT ? fExpr      : tExpr;
512     else if(b0==0  && b1==-1)
513       output = eKind==BVSLT ? fExpr      : MSB1isZero;
514     else if(b0==1  && b1==-1)
515       output = eKind==BVSLT ? MSB1isZero : tExpr;
516     else if(b0==-1 && b1==0)
517       output = eKind==BVSLT ? MSB0isOne  : tExpr;
518     else if(b0==-1 && b1==1)
519       output = eKind==BVSLT ? fExpr      : MSB0isOne;
520     else
521       //both b0 and b1 are -1
522       output =
523 	eKind==BVSLT ?
524 	MSB0isOne.andExpr(MSB1isZero) :
525 	MSB0isOne.orExpr(MSB1isZero);
526   } else {
527     //useful expressions to be used below
528     Expr newE0 = d_theoryBitvector->newBVExtractExpr(e0,e0len-2,0);
529     Expr newE1 = d_theoryBitvector->newBVExtractExpr(e1,e1len-2,0);
530     Expr newBVLT =
531       eKind==BVSLT ?
532       d_theoryBitvector->newBVLTExpr(newE0,newE1):
533       d_theoryBitvector->newBVLEExpr(newE0,newE1);
534 //     Expr newBVLTreverse =
535 //       eKind==BVSLT ?
536 //       d_theoryBitvector->newBVLTExpr(newE1,newE0):
537 //       d_theoryBitvector->newBVLEExpr(newE1,newE0);
538 
539 
540     //both MSBs are simultaneously constants
541     if(-1 != b0 && -1 !=b1) {
542       //e0 is negative and e1 is positive
543       if(b0 == 1 && b1 == 0)
544 	output = tExpr;
545       //e0 is positive and e1 is negative
546       else if(b0 == 0 && b1 == 1)
547 	output = fExpr;
548       //e0 = e1, so result is determined by the rest of the bits
549       else {
550 	output = newBVLT;
551       }
552     }
553     else if(-1 != b0 && -1 == b1) {
554       //only b0 is a constant. Both topBits are not simultaneously constants.
555 
556       //if (b0==0)
557       //    e0 <=(s) e1 <==> NOT e1[n-1] AND e0[n-2:0] <= e1[n-2:0])
558       //else
559       //    e0 <=(s) e1 <==> NOT e1[n-1] OR (e1[n-1] AND e0[n-2:0] <= e1[n-2:0]))
560 
561       output =
562 	(b0==0) ?
563 	//means that b1 has to be 0 and e0[n-2:0] <= e1[n-2:0]
564 	MSB1isZero.andExpr(newBVLT) :
565 	//means that either b1 is 0 or (b1 is 1 and e0[n-2:0] <= e1[n-2:0])
566 	MSB1isZero.orExpr(MSB1isOne.andExpr(newBVLT));
567     }
568     else if(-1 == b0 && -1 != b1) {
569       //only b1 is a constant. Both topBits are not simultaneously constants.
570 
571       //if (b1==0)
572       //    e0 <=(s) e1 <==> e0[n-1] OR (NOT e0[n-1] AND e0[n-2:0] <= e1[n-2:0]))
573       //else
574       //    e0 <=(s) e1 <==> e0[n-1] AND e0[n-2:0] <= e1[n-2:0]))
575 
576       output =
577 	(b1==0) ?
578 	//means that either b0 must be 1 or (b0 = 0 and e0[n-2:0] <= e1[n-2:0])
579 	MSB0isOne.orExpr(MSB0isZero.andExpr(newBVLT)) :
580 	//means that b0 must be 1 and e0[n-2:0] <= e1[n-2:0]
581 	MSB0isOne.andExpr(newBVLT);
582     } else {
583       //both top bits are not constants.
584 
585       //(e0[n-1] AND NOT e1[n-1])
586       Expr k0 = MSB0isOne.andExpr(MSB1isZero);
587 
588       //(e0[n-1] = e1[n-1])
589       Expr k1 = MSB0.eqExpr(MSB1);
590 
591       //e0 <=(s) e1 <==> (e0[n-1] AND NOT e1[n-1]) OR
592       //                 (e0[n-1] = e1[n-1] AND e0[n-2:0] <= e1[n-2:0])
593       output = k0.orExpr(k1.andExpr(newBVLT));
594     }
595   }
596 
597   Proof pf;
598   if(withProof())
599     pf = newPf("sign_bvlt_rule", e);
600   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
601 }
602 
603 
604 /*! NOT(e[0][0] = e[0][1]) <==> e[0][0] = ~e[0][1]
605  */
notBVEQ1Rule(const Expr & e)606 Theorem BitvectorTheoremProducer::notBVEQ1Rule(const Expr& e)
607 {
608   if(CHECK_PROOFS) {
609     CHECK_SOUND(e.getKind() == NOT,
610 		"BitvectorTheoremProducer::notBVEQ1Rule: "
611 		"input kind must be a NOT:\n e = " + e.toString());
612     CHECK_SOUND(e[0].getOpKind() == EQ,
613 		"BitvectorTheoremProducer::notBVEQ1Rule: "
614 		"e[0] must be EQ: \n e = " + e.toString());
615     CHECK_SOUND(d_theoryBitvector->BVSize(e[0][0]) == 1,
616 		"BitvectorTheoremProducer::notBVEQ1Rule: "
617 		"BVSize(e[0][0]) must be 1: \n e = " + e.toString());
618   }
619   Expr output = e[0][0].eqExpr(d_theoryBitvector->newBVNegExpr(e[0][1]));
620 
621   Proof pf;
622   if(withProof())
623     pf = newPf("not_eq1_rule", e);
624   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
625 }
626 
627 
628 /*! NOT(e[0][0] < e[0][1]) <==> (e[0][1] <= e[0][0]),
629  *  NOT(e[0][0] <= e[0][1]) <==> (e[0][1] < e[0][0])
630  */
notBVLTRule(const Expr & e)631 Theorem BitvectorTheoremProducer::notBVLTRule(const Expr& e) {
632   if(CHECK_PROOFS) {
633     CHECK_SOUND(e.getKind() == NOT,
634 		"BitvectorTheoremProducer::notBVLTRule: "
635 		"input kind must be a NOT:\n e = " + e.toString());
636     CHECK_SOUND(e[0].getOpKind() == BVLT ||
637 		e[0].getOpKind() == BVLE,
638 		"BitvectorTheoremProducer::notBVLTRule: "
639 		"e[0] must be BVLT or BVLE: \n e = " + e.toString());
640   }
641   Expr output;
642 
643   const Expr& e00 = e[0][0];
644   const Expr& e01 = e[0][1];
645   if(BVLT == e[0].getOpKind())
646     output = d_theoryBitvector->newBVLEExpr(e01,e00);
647   else
648     output = d_theoryBitvector->newBVLTExpr(e01,e00);
649 
650   Proof pf;
651   if(withProof())
652     pf = newPf("not_bvlt_rule", e);
653   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
654 }
655 
656 
657 //! if(lhs==rhs) then we have (lhs < rhs <==> false),(lhs <= rhs <==> true)
lhsEqRhsIneqn(const Expr & e,int kind)658 Theorem BitvectorTheoremProducer::lhsEqRhsIneqn(const Expr& e, int kind) {
659   if(CHECK_PROOFS) {
660     CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(),
661 		"BitvectorTheoremProducer::lhsEqRhsIneqn: "
662 		"input kind must be BVLT or BVLE: e = " + e.toString());
663     CHECK_SOUND(kind == e.getOpKind(),
664 		"BitvectorTheoremProducer::lhsEqRhsIneqn: "
665 		"input kind must match e.getOpKind(): "
666 		"\n e = " + e.toString());
667     CHECK_SOUND((e.arity()==2) && (e[0]==e[1]),
668 		"BitvectorTheoremProducer::lhsEqRhsIneqn: "
669 		"input arity must be 2, and e[0] must be equal to e[1]: "
670 		"\ne = " + e.toString());
671   }
672   Expr output;
673   if(kind == BVLT)
674     output = d_theoryBitvector->falseExpr();
675   else
676     output = d_theoryBitvector->trueExpr();
677 
678   Proof pf;
679   if(withProof())
680     pf = newPf("lhs_eq_rhs_ineqn", e);
681   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
682 }
683 
684 
685 //! |= 0 <= foo <-> TRUE
zeroLeq(const Expr & e)686 Theorem BitvectorTheoremProducer::zeroLeq(const Expr& e) {
687   if(CHECK_PROOFS) {
688     CHECK_SOUND(BVLE == e.getOpKind(),
689 		"BitvectorTheoremProducer::zeroLeq: "
690 		"input kind must be BVLE: e = " + e.toString());
691     CHECK_SOUND(e.arity()==2 && e[0].getOpKind() == BVCONST &&
692                 d_theoryBitvector->computeBVConst(e[0]) == 0,
693 		"BitvectorTheoremProducer::zeroLeq: "
694 		"unexpected input: e = " + e.toString());
695   }
696   Proof pf;
697   if(withProof())
698     pf = newPf("zeroLeq", e);
699   return newRWTheorem(e, d_theoryBitvector->trueExpr(), Assumptions::emptyAssump(), pf);
700 }
701 
702 
703 //! if indeed e[0] < e[1] then (e<==>true) else (e<==>false)
bvConstIneqn(const Expr & e,int kind)704 Theorem BitvectorTheoremProducer::bvConstIneqn(const Expr& e, int kind) {
705   if(CHECK_PROOFS) {
706     CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(),
707 		"BitvectorTheoremProducer::bvConstIneqn: "
708 		"input kind must be BVLT or BVLE: e = " + e.toString());
709     CHECK_SOUND(kind == e.getOpKind(),
710 		"BitvectorTheoremProducer::bvConstIneqn: "
711 		"input kind must match e.getOpKind(): "
712 		"\n e = " + e.toString());
713     CHECK_SOUND((e.arity()==2),
714 		"BitvectorTheoremProducer::bvConstIneqn: "
715 		"input arity must be 2: \ne = " + e.toString());
716     CHECK_SOUND(BVCONST == e[0].getKind() && BVCONST == e[1].getKind(),
717 		"BitvectorTheoremProducer::bvConstIneqn: "
718 		"e[0] and e[1] must both be constants:\n e = " +
719 		e.toString());
720   }
721 
722   int e0len = d_theoryBitvector->BVSize(e[0]);
723   int e1len = d_theoryBitvector->BVSize(e[1]);
724   if(CHECK_PROOFS)
725     CHECK_SOUND(e0len == e1len,
726 		"BitvectorTheoremProducer::bvConstIneqn: "
727 		"e[0] and e[1] must have the same bvLength:\ne = " +
728 		e.toString());
729 
730   Rational lhsVal = d_theoryBitvector->computeBVConst(e[0]);
731   Rational rhsVal = d_theoryBitvector->computeBVConst(e[1]);
732   Expr output;
733 
734   if(BVLT == kind) {
735     if(lhsVal < rhsVal)
736       output = d_theoryBitvector->trueExpr();
737     else
738       output = d_theoryBitvector->falseExpr();
739   } else {
740     if(lhsVal <= rhsVal)
741       output = d_theoryBitvector->trueExpr();
742     else
743       output = d_theoryBitvector->falseExpr();
744   }
745 
746   Proof pf;
747   if(withProof())
748     pf = newPf("bv_const_ineqn", e);
749   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
750 }
751 
752 
753 // Input: e: a op b, where op is < or <=
754 //        lhs_i: BOOLEXTRACT(a,i) <=> b1
755 //        rhs_i: BOOLEXTRACT(b,i) <=> b2
756 //        kind: op
757 //        i = BVSize(a)-1 = BVSize(b)-1
758 // Output: for i > 0:
759 //           (lhs_i < rhs_i) OR (lhs_i = rhs_i AND a[i-1:0] op b[i-1:0])
760 //         for i = 0:
761 //           (lhs_i op rhs_i)
generalIneqn(const Expr & e,const Theorem & lhs_i,const Theorem & rhs_i,int kind)762 Theorem BitvectorTheoremProducer::generalIneqn(const Expr& e,
763 					       const Theorem& lhs_i,
764 					       const Theorem& rhs_i,
765 					       int kind) {
766   if(CHECK_PROOFS) {
767     CHECK_SOUND(BVLT == e.getOpKind() || BVLE == e.getOpKind(),
768 		"BitvectorTheoremProducer::generalIneqn: "
769 		"input kind must be BVLT or BVLE: e = " + e.toString());
770     CHECK_SOUND(kind == e.getOpKind(),
771 		"BitvectorTheoremProducer::generalIneqn: "
772 		"input kind must match e.getOpKind(): "
773 		"\n e = " + e.toString());
774     CHECK_SOUND((e.arity()==2),
775 		"BitvectorTheoremProducer::generalIneqn: "
776 		"input arity must be 2: \ne = " + e.toString());
777     CHECK_SOUND(lhs_i.isRewrite() && rhs_i.isRewrite(),
778 		"BitvectorTheoremProducer::generalIneqn: "
779 		"lhs_i and rhs_i must be rewrite theorems: "
780 		"\nlhs_i = " + lhs_i.toString() +
781 		"\nrhs_i = " + rhs_i.toString());
782   }
783 
784   int e0len = d_theoryBitvector->BVSize(e[0]);
785   int e1len = d_theoryBitvector->BVSize(e[1]);
786   const Expr& e0_iBit = lhs_i.getLHS();
787   const Expr& e1_iBit = rhs_i.getLHS();
788   if(CHECK_PROOFS) {
789     CHECK_SOUND(BOOLEXTRACT == e0_iBit.getOpKind() &&
790 		BOOLEXTRACT == e1_iBit.getOpKind(),
791 		"BitvectorTheoremProducer::generalIneqn: "
792 		"lhs_i.getRHS() and rhs_i.getRHS() must be BOOLEXTRACTs:"
793 		"\nlhs_i = " + lhs_i.toString() +
794 		"\nrhs_i = " + rhs_i.toString());
795     CHECK_SOUND(e[0] == e0_iBit[0],
796 		"BitvectorTheoremProducer::generalIneqn: "
797 		"e[0] must be equal to LHS of lhs_i: \nlhs_i = " +
798 		lhs_i.toString() + "\n e[0] = " + e[0].toString());
799     CHECK_SOUND(e[1] == e1_iBit[0],
800 		"BitvectorTheoremProducer::generalIneqn: "
801 		"e[1] must be equal to LHS of rhs_i: \nrhs_i = " +
802 		rhs_i.toString() + "\n e[1] = " + e[1].toString());
803     CHECK_SOUND(e0len == e1len,
804 		"BitvectorTheoremProducer::generalIneqn: "
805 		"e[0] and e[1] must have the same bvLength:\ne = " +
806 		e.toString());
807     int e0_iBitIndex =
808       d_theoryBitvector->getBoolExtractIndex(e0_iBit);
809     int e1_iBitIndex =
810       d_theoryBitvector->getBoolExtractIndex(e1_iBit);
811     CHECK_SOUND(e0_iBitIndex == e1_iBitIndex &&
812 		e0_iBitIndex == e0len-1,
813 		"BitvectorTheoremProducer::generalIneqn: "
814 		"e0_iBit & e1_iBit must have same extract index: "
815 		"\ne0_iBit = " + e0_iBit.toString() +
816 		"\ne1_iBit = " + e1_iBit.toString());
817   }
818 
819   const Expr& b1 = lhs_i.getRHS();
820   const Expr& b2 = rhs_i.getRHS();
821   const Expr& trueExpression = d_theoryBitvector->trueExpr();
822   const Expr& falseExpression = d_theoryBitvector->falseExpr();
823 
824   if(CHECK_PROOFS) {
825     CHECK_SOUND(b1.getType().isBool(),
826 		"BitvectorTheoremProducer::generalIneqn: "
827 		"b1 must be a boolean type: "
828 		"\n b1 = " + b1.toString());
829     CHECK_SOUND(b2.getType().isBool(),
830 		"BitvectorTheoremProducer::generalIneqn: "
831 		"b2 must be boolean type: "
832 		"\n b2 = " + b2.toString());
833   }
834 
835   Expr output;
836   // Check for the shortcuts
837   if (b1.isFalse() && b2.isTrue()) // b1 < b2
838     output = trueExpression;
839   else if (b1.isTrue() && b2.isFalse()) // b1 > b2
840     output = falseExpression;
841   else if (e0len==1) {
842     // If this is the last bit, and one of them is a constant
843     if (kind==BVLE && (b1.isFalse() || b2.isTrue())) // F <= x or x <= T
844       output = trueExpression;
845     else if (kind==BVLT && (b2.isFalse() || b1.isTrue())) // x < F or T < x
846       output = falseExpression;
847   }
848 
849   // No shortcuts found
850   if (output.isNull()) {
851 
852     // Process the top bits
853     if (kind == BVLT || e0len > 1) {
854       output = (!b1) && b2;
855     }
856     else {
857       output = (!b1) || b2;
858     }
859 
860     if(e0len > 1) {
861       //construct e0[n-2:0]
862       Expr e0_extract =
863 	d_theoryBitvector->newBVExtractExpr(e[0],e0len-2,0);
864       //construct e1[n-2:0]
865       Expr e1_extract =
866 	d_theoryBitvector->newBVExtractExpr(e[1],e1len-2,0);
867 
868       Expr a;
869       if(kind==BVLT)
870 	//construct e0[n-2:0] < e1[n-2:0]
871 	a = d_theoryBitvector->newBVLTExpr(e0_extract,e1_extract);
872       else
873 	//construct e0[n-2:0] <= e1[n-2:0]
874 	a = d_theoryBitvector->newBVLEExpr(e0_extract,e1_extract);
875 
876       //construct (b1=0 and/or b2=1) or (b1=b2 and a)
877       output = output || (b1.iffExpr(b2) && a);
878     }
879   }
880 
881   Proof pf;
882   if(withProof())
883     pf = newPf("general_ineqn", e);
884   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
885 }
886 
887 ///////////////////////////////////////////////////////////////////////
888 // BitExtracting rules for terms
889 ///////////////////////////////////////////////////////////////////////
890 
891 // Input: |- BOOLEXTRACT(a,0) <=> bc_0, ... BOOLEXTRACT(a,n-1) <=> bc_(n-1)
892 // where each bc_0 is TRUE or FALSE
893 // Output: |- a = c
894 // where c is an n-bit constant made from the values bc_0..bc_(n-1)
bitExtractAllToConstEq(vector<Theorem> & thms)895 Theorem BitvectorTheoremProducer::bitExtractAllToConstEq(vector<Theorem>& thms)
896 {
897   if (CHECK_PROOFS) {
898     CHECK_SOUND(thms.size() > 0, "Expected size > 0");
899     unsigned i;
900     for(i = 0; i < thms.size(); ++i) {
901       Expr e = thms[i].getExpr();
902       CHECK_SOUND(e.getKind() == IFF && e.arity() == 2 && e[1].isBoolConst(),
903                   "Unexpected structure");
904       CHECK_SOUND(e[0].getOpKind() == BOOLEXTRACT &&
905                   e[0].arity() == 1 &&
906                   e[0][0] == thms[0].getExpr()[0][0] &&
907                   unsigned(d_theoryBitvector->getBoolExtractIndex(e[0])) == i,
908                   "Unexpected structure");
909     }
910   }
911   Expr lhs = thms[0].getExpr()[0][0];
912   vector<bool> bits;
913   for (unsigned i = 0; i < thms.size(); ++i) {
914     bits.push_back(thms[i].getExpr()[1].isTrue() ? true : false);
915   }
916   Expr rhs = d_theoryBitvector->newBVConstExpr(bits);
917 
918   Assumptions a(thms);
919   Proof pf;
920   if (withProof())
921     pf = newPf("bit_extract_all_to_const_eq");
922   return newRWTheorem(lhs, rhs, a, pf);
923 }
924 
925 
926 //! t[i] ==> t[i:i] = 0bin1   or    NOT t[i] ==> t[i:i] = 0bin0
bitExtractToExtract(const Theorem & thm)927 Theorem BitvectorTheoremProducer::bitExtractToExtract(const Theorem& thm) {
928   const Expr& e = thm.getExpr();
929   if(CHECK_PROOFS) {
930     CHECK_SOUND((e.isNot() && e[0].getOpKind() == BOOLEXTRACT)
931 		|| (e.getOpKind() == BOOLEXTRACT),
932 		"BitvectorTheoremProducer::bitExtractToExtract:\n e = "
933 		+e.toString());
934   }
935   bool negative = e.isNot();
936   const Expr& boolExtract = negative? e[0] : e;
937   int i = d_theoryBitvector->getBoolExtractIndex(boolExtract);
938   Expr lhs = d_theoryBitvector->newBVExtractExpr(boolExtract[0], i, i);
939 
940   Proof pf;
941   if(withProof())
942     pf = newPf("bit_extract_to_extract", e, thm.getProof());
943   return newRWTheorem(lhs, negative? bvZero() : bvOne(), thm.getAssumptionsRef(), pf);
944 }
945 
946 
947 //! t[i] <=> t[i:i][0]   (to use rewriter for simplifying t[i:i])
bitExtractRewrite(const Expr & x)948 Theorem BitvectorTheoremProducer::bitExtractRewrite(const Expr& x) {
949   if(CHECK_PROOFS) {
950     CHECK_SOUND(x.getOpKind() == BOOLEXTRACT,
951 		"BitvectorTheoremProducer::bitExtractRewrite: x = "
952 		+x.toString());
953   }
954 
955   int i = d_theoryBitvector->getBoolExtractIndex(x);
956   const Expr& t = x[0];
957   int bvLength = d_theoryBitvector->BVSize(t);
958 
959   if(CHECK_PROOFS) {
960     CHECK_SOUND(0<=i && i<bvLength,
961 		"BitvectorTheoremProducer::bitExtractRewrite:"
962 		"\n bvLength = "
963 		+ int2string(bvLength)
964 		+"\n i = "+ int2string(i)
965 		+"\n x = "+ x.toString());
966   }
967   Proof pf;
968   if(withProof())
969     pf = newPf("bit_extract_rewrite", x);
970   Expr res = d_theoryBitvector->newBVExtractExpr(t, i, i);
971   res = d_theoryBitvector->newBoolExtractExpr(res, 0);
972   return newRWTheorem(x, res, Assumptions::emptyAssump(), pf);
973 }
974 
975 
976 // |- BOOLEXTRACT(x,i) <=> *Boolean value of x[i]*
bitExtractConstant(const Expr & x,int i)977 Theorem BitvectorTheoremProducer::bitExtractConstant(const Expr & x, int i)
978 {
979   TRACE("bitvector", "bitExtractConstant(", x, ", "+ int2string(i) +" ) {");
980   if(CHECK_PROOFS) {
981     //check if the expr is indeed a bitvector constant.
982     CHECK_SOUND(BVCONST == x.getKind(),
983 		"BitvectorTheoremProducer::bitExtractConstant:"
984 		"the bitvector must be a constant.");
985     //check if 0<= i < bvLength of bitvector constant
986     CHECK_SOUND(0 <= i && (unsigned)i < d_theoryBitvector->getBVConstSize(x),
987 		"BitvectorTheoremProducer::bitExtractConstant:"
988 		"illegal extraction attempted on the bitvector x = "
989 		+ x.toString()
990 		+ "\nat the position i = "
991 		+ int2string(i));
992   }
993   // bool-extract of the bitvector constant
994   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
995 
996   //extract the actual expr_value string, bitextract it at i and check
997   //if the value is 'false'. if so then return c[i] <==> false else
998   //return c[i] <==> true.
999   Expr output;
1000   if(!d_theoryBitvector->getBVConstValue(x, i))
1001     output = d_theoryBitvector->falseExpr();
1002   else
1003     output = d_theoryBitvector->trueExpr();
1004 
1005   Proof pf;
1006   if(withProof()) pf = newPf("bit_extract_constant", x, rat(i));
1007   Theorem result(newRWTheorem(bitExtract,output,Assumptions::emptyAssump(),pf));
1008   TRACE("bitvector", "bitExtractConstant => ", result, " }");
1009   return result;
1010 }
1011 
1012 
1013 // Input: x: a_0 \@ ... \@ a_n,
1014 //        i: bitposition
1015 // Output |- BOOLEXTRACT(a_0 \@ ... \@ a_n, i) <=> BOOLEXTRACT(a_j, k)
1016 //        where j and k are determined by structure of CONCAT
bitExtractConcatenation(const Expr & x,int i)1017 Theorem BitvectorTheoremProducer::bitExtractConcatenation(const Expr & x,
1018 							  int i)
1019 {
1020   TRACE("bitvector", "bitExtractConcatenation(",
1021 	x.toString(), ", "+ int2string(i) + " ) {");
1022   Type type = d_theoryBitvector->getBaseType(x);
1023   if(CHECK_PROOFS) {
1024     //check if the expr is indeed a bitvector term and a concat.
1025     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1026 		"BitvectorTheoremProducer::bitExtractConcatenation: "
1027 		"term must be bitvector:\n x = "+x.toString());
1028     CHECK_SOUND(CONCAT == x.getOpKind() && x.arity() >= 2,
1029 		"BitvectorTheoremProducer::bitExtractConcatenation: "
1030 		"the bitvector must be a concat:\n x = " + x.toString());
1031   }
1032 
1033   //check if 0<= i < bvLength of bitvector constant
1034   int bvLength = d_theoryBitvector->BVSize(x);
1035   if(CHECK_PROOFS) {
1036     CHECK_SOUND(0 <= i && i < bvLength,
1037 		"BitvectorTheoremProducer::bitExtractNot:"
1038 		"illegal boolean extraction was attempted at position i = "
1039 		+ int2string(i)
1040 		+ "\non bitvector x = " + x.toString()
1041 		+ "\nwhose bvLength is = " +
1042 		int2string(bvLength));
1043   }
1044 
1045   // bool-extract of the bitvector constant
1046   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1047 
1048   int numOfKids = x.arity();
1049   int lenOfKidsSeen = 0;
1050   Expr bitExtractKid;
1051   for(int count = numOfKids-1; count >= 0; --count) {
1052     int bvLengthOfKid = d_theoryBitvector->BVSize(x[count]);
1053     if(lenOfKidsSeen <= i && i < bvLengthOfKid + lenOfKidsSeen) {
1054       bitExtractKid =
1055 	d_theoryBitvector->newBoolExtractExpr(x[count], i - lenOfKidsSeen);
1056       break;
1057     }
1058     lenOfKidsSeen += bvLengthOfKid;
1059   }
1060   DebugAssert(!bitExtractKid.isNull(),
1061 	      "BitvectorTheoremProducer::bitExtractConcatenation: "
1062 	      "something's broken...");
1063 
1064   Proof pf;
1065   if(withProof())
1066     pf = newPf("bit_extract_concatenation", x, rat(i));
1067   Theorem result(newRWTheorem(bitExtract, bitExtractKid, Assumptions::emptyAssump(), pf));
1068   TRACE("bitvector", "bitExtractConcatenation => ", result, " }");
1069   return result;
1070 }
1071 
1072 
1073 // |- BOOLEXTRACT(BVMULT(c,t),i) <=> BOOLEXTRACT(t',i) where t' is not a BVMULT
bitExtractConstBVMult(const Expr & t,int i)1074 Theorem BitvectorTheoremProducer::bitExtractConstBVMult(const Expr& t, int i)
1075 {
1076   TRACE("bitvector", "input to bitExtractConstBVMult(", t.toString(), ")");
1077   TRACE("bitvector", "input to bitExtractConstBVMult(", int2string(i), ")");
1078 
1079   Type type = t.getType();
1080   int bvLength = d_theoryBitvector->BVSize(t);
1081   if(CHECK_PROOFS) {
1082     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1083 		"BitvectorTheoremProducer::bitExtractConstBVMult:"
1084 		"the term must be a bitvector: " + t.toString());
1085     CHECK_SOUND(BVMULT == t.getOpKind() && 2 == t.arity(),
1086 		"BitvectorTheoremProducer::bitExtractConstBVMult:"
1087 		"the term must be a MULT of arity 2: " + t.toString());
1088     CHECK_SOUND(d_theoryBitvector->BVSize(t[0]) == bvLength &&
1089                 d_theoryBitvector->BVSize(t[1]) == bvLength,
1090                 "BitvectorTheoremProducer::bitExtractConstBVMult:"
1091                 "Expected inputs of same length");
1092     CHECK_SOUND(0 <= i && i < bvLength,
1093 		"BitvectorTheoremProducer::bitExtractNot:"
1094 		"illegal boolean extraction was attempted at position i = "
1095 		+ int2string(i)
1096 		+ "\non bitvector x = " + t.toString()
1097 		+ "\nwhose bvLength is = " +
1098 		int2string(bvLength));
1099     CHECK_SOUND(BVCONST == t[0].getKind(),
1100 		"BitvectorTheoremProducer::bitExtractConstBVMult:"
1101 		"illegal BVMULT expression" + t.toString());
1102   }
1103 
1104 	  std::vector<Expr> k;
1105 	  for(int j=0; j < bvLength; ++j)
1106 		if (d_theoryBitvector->getBVConstValue(t[0], j)) {
1107 		  Expr leftshiftTerm =
1108 		d_theoryBitvector->newFixedConstWidthLeftShiftExpr(t[1], j);
1109 		  k.push_back(leftshiftTerm);
1110 		}
1111 
1112 	  Expr mult;
1113 	  //size of k will always be >= 0
1114 	  switch(k.size()) {
1115 	  case 0:
1116 		//the vector k will remain empty if all bits in coeff are 0's
1117 		mult = d_theoryBitvector->newBVZeroString(bvLength);
1118 		break;
1119 	  case 1:
1120 		mult = k[0];
1121 		break;
1122 	  default:
1123 		mult = d_theoryBitvector->newBVPlusExpr(bvLength, k);
1124 		break;
1125 	  }
1126   Expr output = d_theoryBitvector->newBoolExtractExpr(mult, i);
1127 
1128   // bool-extract of the bitvector term
1129   const Expr bitExtract =
1130     d_theoryBitvector->newBoolExtractExpr(t, i);
1131 
1132   Proof pf;
1133   if(withProof()) pf = newPf("bit_extract_const_bvmult", t, rat(i));
1134   const Theorem result = newRWTheorem(bitExtract,output,Assumptions::emptyAssump(),pf);
1135   TRACE("bitvector",
1136 	"output of bitExtract_const_bvmult(", result, ")");
1137   return result;
1138 }
1139 
1140 // |- BOOLEXTRACT(t,i) <=> BOOLEXTRACT(t',i) where t' is not BVMULT
bitExtractBVMult(const Expr & t,int i)1141 Theorem BitvectorTheoremProducer::bitExtractBVMult(const Expr& t, int i)
1142 {
1143   TRACE("bitvector", "input to bitExtractBVMult(", t.toString(), ")");
1144   TRACE("bitvector", "input to bitExtractBVMult(", int2string(i), ")");
1145 
1146   Type type = t.getType();
1147   int bvLength= d_theoryBitvector->BVSize(t);
1148   if(CHECK_PROOFS) {
1149     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1150 		"BitvectorTheoremProducer::bitExtractBVMult:"
1151 		"the term must be a bitvector" + t.toString());
1152     CHECK_SOUND(BVMULT == t.getOpKind() && 2 == t.arity(),
1153 		"BitvectorTheoremProducer::bitExtractBVMult:"
1154 		"the term must be a bitvector" + t.toString());
1155     CHECK_SOUND(d_theoryBitvector->BVSize(t[0]) == bvLength &&
1156                 d_theoryBitvector->BVSize(t[1]) == bvLength,
1157                 "BitvectorTheoremProducer::bitExtractConstBVMult:"
1158                 "Expected inputs of same length");
1159     CHECK_SOUND(0 <= i && i < bvLength,
1160 		"BitvectorTheoremProducer::bitExtractNot:"
1161 		"illegal boolean extraction was attempted at position i = "
1162 		+ int2string(i)
1163 		+ "\non bitvector t = " + t.toString()
1164 		+ "\nwhose Length is = " +
1165 		int2string(bvLength));
1166     CHECK_SOUND(BVCONST != t[0].getOpKind(),
1167 		"BitvectorTheoremProducer::bitExtractBVMult:"
1168 		"illegal BVMULT expression" + t.toString());
1169   }
1170   Expr trueExpression = d_theoryBitvector->trueExpr();
1171   std::vector<Expr> k;
1172   for(int j=bvLength-1; j >= 0; j--) {
1173     Expr ext = d_theoryBitvector->newBVExtractExpr(t[0],j,j);
1174     Expr cond = ext.eqExpr(d_theoryBitvector->newBVOneString(1));
1175     Expr leftshiftTerm = d_theoryBitvector->newFixedConstWidthLeftShiftExpr(t[1], j);
1176     Expr zeroString = d_theoryBitvector->newBVZeroString(bvLength);
1177     Expr iteTerm = cond.iteExpr(leftshiftTerm, zeroString);
1178     k.push_back(iteTerm);
1179   }
1180 
1181   if(CHECK_PROOFS)
1182     CHECK_SOUND(k.size() > 0,
1183 		"BitvectorTheoremProducer::bitExtractBVMult:"
1184 		"size of output vector must be > 0");
1185   Expr mult;
1186   if (k.size() > 1)
1187     mult = d_theoryBitvector->newBVPlusExpr(bvLength, k);
1188   else
1189     mult = k[0];
1190   Expr output = d_theoryBitvector->newBoolExtractExpr(mult, i);
1191 
1192   // bool-extract of the bitvector term
1193   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(t, i);
1194 
1195   Proof pf;
1196   if(withProof()) pf = newPf("bit_extract_bvmult", t, rat(i));
1197   const Theorem result = newRWTheorem(bitExtract,output,Assumptions::emptyAssump(),pf);
1198   TRACE("bitvector","output of bitExtract_bvmult(", result, ")");
1199   return result;
1200 }
1201 
1202 
1203 // Input x: a[hi:low]
1204 //       i: bitposition
1205 // Output: |- BOOLEXTRACT(a[hi:low], i) <=> BOOLEXTRACT(a, i+low)
bitExtractExtraction(const Expr & x,int i)1206 Theorem BitvectorTheoremProducer::bitExtractExtraction(const Expr & x, int i)
1207 {
1208   TRACE("bitvector", "input to bitExtractExtraction(", x.toString(), ")");
1209   TRACE("bitvector", "input to bitExtractExtraction(", int2string(i), ")");
1210 
1211   Type type = x.getType();
1212   if(CHECK_PROOFS) {
1213     //check if the expr is indeed a bitvector term and a concat.
1214     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1215 		"BitvectorTheoremProducer::bitExtract-Extraction:"
1216 		"term must be bitvector.");
1217     CHECK_SOUND(EXTRACT == x.getOpKind() && 1 == x.arity(),
1218 		"BitvectorTheoremProducer::bitExtract-Extraction:"
1219 		"the bitvector must be an extract." + x.toString());
1220     //check if 0<= i < bvLength of bitvector constant
1221     int bvLength= d_theoryBitvector->BVSize(type.getExpr());
1222     CHECK_SOUND(0 <= i && i < bvLength,
1223 		"BitvectorTheoremProducer::bitExtractNot:"
1224 		"illegal boolean extraction was attempted at position i = "
1225 		+ int2string(i)
1226 		+ "\non bitvector t = " + x.toString()
1227 		+ "\nwhose Length is = " +
1228 		int2string(bvLength));
1229     int extractLeft = d_theoryBitvector->getExtractHi(x);
1230     int extractRight = d_theoryBitvector->getExtractLow(x);
1231     CHECK_SOUND(extractLeft >= extractRight && extractLeft >= 0,
1232 		"BitvectorTheoremProducer::bitExtract-Extraction:"
1233 		"illegal boolean extraction was attempted." + int2string(i) +
1234 		int2string(extractLeft) + int2string(extractRight));
1235     CHECK_SOUND(0 <= i && i < extractLeft-extractRight+1,
1236     		"BitvectorTheoremProducer::bitExtract-Extraction:"
1237 		"illegal boolean extraction was attempted." + int2string(i) +
1238 		int2string(extractLeft) + int2string(extractRight));
1239   }
1240   // bool-extract of the bitvector constant
1241   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1242   const Expr bitExtractExtraction =
1243     d_theoryBitvector->newBoolExtractExpr(x[0], i +
1244 					  d_theoryBitvector->getExtractLow(x));
1245 
1246   Proof pf;
1247   if(withProof()) pf = newPf("bit_extract_extraction", x, rat(i));
1248   Theorem result(newRWTheorem(bitExtract, bitExtractExtraction, Assumptions::emptyAssump(), pf));
1249   TRACE("bitvector",
1250 	"output of bitExtractExtraction(", result, ")");
1251   return result;
1252 }
1253 
1254 Theorem
1255 BitvectorTheoremProducer::
bitExtractBVPlus(const std::vector<Theorem> & t1BitExtractThms,const std::vector<Theorem> & t2BitExtractThms,const Expr & bvPlusTerm,int bitPos)1256   bitExtractBVPlus(const std::vector<Theorem>& t1BitExtractThms,
1257                    const std::vector<Theorem>& t2BitExtractThms,
1258                    const Expr& bvPlusTerm, int bitPos)
1259 {
1260   TRACE("bitvector","input to bitExtractBVPlus(", bvPlusTerm.toString(), ")");
1261   TRACE("bitvector","input to bitExtractBVPlus(", int2string(bitPos), ")");
1262 
1263   if(CHECK_PROOFS) {
1264     CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind() && 2 == bvPlusTerm.arity(), "BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + bvPlusTerm.toString());
1265     CHECK_SOUND(d_theoryBitvector->getBVPlusParam(bvPlusTerm) >= 0,	"BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + bvPlusTerm.toString());
1266     CHECK_SOUND(bitPos+1 == (int)t1BitExtractThms.size() &&	bitPos+1 == (int)t2BitExtractThms.size(), "BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + int2string(bitPos));
1267     const Expr& t1 = bvPlusTerm[0];
1268     const Expr& t2 = bvPlusTerm[1];
1269     std::vector<Theorem>::const_iterator i = t1BitExtractThms.begin();
1270     std::vector<Theorem>::const_iterator iend = t1BitExtractThms.end();
1271     std::vector<Theorem>::const_iterator j = t2BitExtractThms.begin();
1272     for(; i !=iend; ++i, ++j) {
1273       const Expr& t1Expr = i->getLHS();
1274       const Expr& t2Expr = j->getLHS();
1275       CHECK_SOUND(t1Expr[0] == t1 && t2Expr[0] == t2, "BitvectorTheoremProducer::bitExtractBVPlus: illegal bitvector fed to the function." + t1Expr.toString() + " ==\n" + t1.toString() + "\n" + t2.toString() + " == \n" + t2Expr.toString());
1276     }
1277   }
1278   const Expr lhs = d_theoryBitvector->newBoolExtractExpr(bvPlusTerm, bitPos);
1279   Expr rhs;
1280   const Expr& t1_iBit = (t1BitExtractThms[bitPos]).getRHS();
1281   const Expr& t2_iBit = (t2BitExtractThms[bitPos]).getRHS();
1282   if(0 != bitPos) {
1283     const Expr carry_iBit = computeCarry(t1BitExtractThms, t2BitExtractThms, bitPos);
1284     //constructing an XOR of 3 exprs using equivalences.  Note that (x
1285     //\xor y \xor z) is the same as (x \iff y \iff z). but remember, x
1286     //\xor y is not the same as x \iff y, but is equal instead to x
1287     //\neg\iff y
1288     rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit);
1289     //cout << "the addition output is : " << rhs.toString() << "\n";
1290     //TRACE("bitvector",
1291     //  "output of bitExtractBVPlus(", carry_iBit.toString(), ")");
1292   } else
1293     //bitblasting the 0th bit. construct NOT(t1_iBit <=> t2_iBit)
1294     rhs = !(t1_iBit.iffExpr(t2_iBit));
1295 
1296   Proof pf;
1297   if(withProof())
1298     pf = newPf("bit_extract_BVPlus_rule",bvPlusTerm,rat(bitPos));
1299   Theorem result = newRWTheorem(lhs, rhs, Assumptions::emptyAssump(), pf);
1300   TRACE("bitvector","output of bitExtractBVPlus(", result, ")");
1301   return result;
1302 }
1303 
1304 Expr
computeCarry(const std::vector<Theorem> & t1BitExtractThms,const std::vector<Theorem> & t2BitExtractThms,int i)1305 BitvectorTheoremProducer::computeCarry(const std::vector<Theorem>& t1BitExtractThms,
1306 	                                   const std::vector<Theorem>& t2BitExtractThms,
1307 	                                   int i){
1308   vector<Expr> carry;
1309   int bitPos = i;
1310   DebugAssert(bitPos >= 0,
1311 	      "computeCarry: negative bitExtract_Pos is illegal");
1312   if(0 == bitPos) {
1313     const Expr& t1Thm = t1BitExtractThms[bitPos].getRHS();
1314     const Expr& t2Thm = t2BitExtractThms[bitPos].getRHS();
1315     carry.push_back(t1Thm.andExpr(t2Thm));
1316   }
1317   else {
1318     const Expr& t1Thm = t1BitExtractThms[bitPos-1].getRHS();
1319     const Expr& t2Thm = t2BitExtractThms[bitPos-1].getRHS();
1320     const Expr iMinusOneTerm = t1Thm.andExpr(t2Thm);
1321     carry.push_back(iMinusOneTerm);
1322 
1323     const Expr iMinusOneCarry =
1324       computeCarry(t1BitExtractThms,t2BitExtractThms,bitPos-1);
1325     const Expr secondTerm = t1Thm.andExpr(iMinusOneCarry);
1326     carry.push_back(secondTerm);
1327 
1328     const Expr thirdTerm  = t2Thm.andExpr(iMinusOneCarry);
1329 
1330     carry.push_back(thirdTerm);
1331   }
1332   return orExpr(carry);
1333 }
1334 
1335 Theorem
1336 BitvectorTheoremProducer::
bitExtractBVPlusPreComputed(const Theorem & t1_i,const Theorem & t2_i,const Expr & bvPlusTerm,int bitPos,int precomputedFlag)1337 bitExtractBVPlusPreComputed(const Theorem& t1_i,
1338 			    const Theorem& t2_i,
1339 			    const Expr& bvPlusTerm,
1340 			    int bitPos,
1341 			    int precomputedFlag)
1342 {
1343   DebugAssert(0 != precomputedFlag,
1344 	      "precomputedFlag cannot be 0");
1345   TRACE("bitvector","input to bitExtractBVPlus(", bvPlusTerm.toString(), ")");
1346   TRACE("bitvector","input to bitExtractBVPlus(", int2string(bitPos), ")");
1347 
1348   if(CHECK_PROOFS) {
1349     CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind() && 2 == bvPlusTerm.arity(),
1350 		"BitvectorTheoremProducer::bitExtractBVPlus:"
1351 		"illegal bitvector fed to the function." +
1352 		bvPlusTerm.toString());
1353     CHECK_SOUND(d_theoryBitvector->getBVPlusParam(bvPlusTerm) >= 0,
1354 		"BitvectorTheoremProducer::bitExtractBVPlus:"
1355 		"illegal bitvector fed to the function." +
1356 		bvPlusTerm.toString());
1357     const Expr& t1 = bvPlusTerm[0];
1358     const Expr& t2 = bvPlusTerm[1];
1359     CHECK_SOUND(t1_i.getLHS()[0] == t1 &&
1360 		t2_i.getLHS()[0] == t2,
1361 		"BitvectorTheoremProducer::bitExtractBVPlus:"
1362 		"illegal theorems fed to the function. Theorem1 = " +
1363 		t1_i.toString() + "\nTheorem2 = " + t2_i.toString());
1364     CHECK_SOUND(t1_i.getLHS().getOpKind() == BOOLEXTRACT &&
1365 		t2_i.getLHS().getOpKind() == BOOLEXTRACT,
1366 		"BitvectorTheoremProducer::bitExtractBVPlus:"
1367 		"illegal theorems fed to the function. Theorem1 = " +
1368 		t1_i.toString() + "\nTheorem2 = " + t2_i.toString());
1369     CHECK_SOUND(d_theoryBitvector->getBoolExtractIndex(t1_i.getLHS()) == bitPos &&
1370 		d_theoryBitvector->getBoolExtractIndex(t2_i.getLHS()) == bitPos,
1371 		"BitvectorTheoremProducer::bitExtractBVPlus:"
1372 		"illegal theorems fed to the function. Theorem1 = " +
1373 		t1_i.toString() + "\nTheorem2 = " + t2_i.toString());
1374   }
1375   const Expr lhs =
1376     d_theoryBitvector->newBoolExtractExpr(bvPlusTerm, bitPos);
1377   Expr rhs;
1378   const Expr& t1_iBit = t1_i.getRHS();
1379   const Expr& t2_iBit = t2_i.getRHS();
1380 
1381   const Expr carry_iBit = computeCarryPreComputed(t1_i, t2_i, bitPos, precomputedFlag);
1382 
1383   if(0 != bitPos) {
1384     //constructing an XOR of 3 exprs using equivalences.  Note that (x
1385     //\xor y \xor z) is the same as (x \iff y \iff z). but remember, x
1386     //\xor y is not the same as x \iff y, but is equal instead to x
1387     //\neg\iff y
1388     rhs = t1_iBit.iffExpr(t2_iBit).iffExpr(carry_iBit);
1389     //cout << "the addition output is : " << rhs.toString() << "\n";
1390   } else
1391     //bitblasting the 0th bit. construct NOT(t1_iBit <=> t2_iBit)
1392     rhs = !(t1_iBit.iffExpr(t2_iBit));
1393 
1394   Proof pf;
1395   if(withProof())
1396     pf = newPf("bit_extract_BVPlus_precomputed_rule",bvPlusTerm,rat(bitPos));
1397   Theorem result = newRWTheorem(lhs, rhs, Assumptions::emptyAssump(), pf);
1398   TRACE("bitvector","output of bitExtractBVPlus(", result, ")");
1399   return result;
1400 }
1401 
1402 //! compute carryout of the current bits and cache them, and return
1403 //carryin of the current bits
1404 Expr
1405 BitvectorTheoremProducer::
computeCarryPreComputed(const Theorem & t1_i,const Theorem & t2_i,int bitPos,int preComputed)1406 computeCarryPreComputed(const Theorem& t1_i,
1407 			const Theorem& t2_i,
1408 			int bitPos, int preComputed){
1409   DebugAssert(1 == preComputed ||
1410 	      2 == preComputed,
1411 	      "cannot happen");
1412   Expr carryout;
1413   Expr carryin;
1414   DebugAssert(bitPos >= 0,
1415 	      "computeCarry: negative bitExtract_Pos is illegal");
1416 
1417   const Expr& t1Thm = t1_i.getRHS();
1418   const Expr& t2Thm = t2_i.getRHS();
1419   Expr x = t1Thm.andExpr(t2Thm);
1420   const Expr& t1 = t1_i.getLHS()[0];
1421   const Expr& t2 = t2_i.getLHS()[0];
1422   Expr t1Andt2 = t1.andExpr(t2);
1423   Expr index = t1Andt2.andExpr(rat(bitPos));
1424 
1425   if(0 == bitPos) {
1426     if(1 == preComputed)
1427       d_theoryBitvector->d_bvPlusCarryCacheLeftBV.insert(index,x);
1428     else
1429       d_theoryBitvector->d_bvPlusCarryCacheRightBV.insert(index,x);
1430     carryout = x;
1431     //carry.push_back(x);
1432   }
1433   else {
1434     if(1 == preComputed) {
1435       Expr indexMinusOne = t1Andt2.andExpr(rat(bitPos-1));
1436       if(d_theoryBitvector->d_bvPlusCarryCacheLeftBV.find(indexMinusOne) ==
1437 	 d_theoryBitvector->d_bvPlusCarryCacheLeftBV.end())
1438 	DebugAssert(false,
1439 		    "this should not happen");
1440       carryin =
1441 	(d_theoryBitvector->d_bvPlusCarryCacheLeftBV).find(indexMinusOne)->second;
1442       Expr secondTerm = t1Thm.andExpr(carryin);
1443       Expr thirdTerm = t2Thm.andExpr(carryin);
1444 
1445       carryout = (x.orExpr(secondTerm)).orExpr(thirdTerm);
1446       d_theoryBitvector->d_bvPlusCarryCacheLeftBV.insert(index,carryout);
1447     }
1448     else {
1449       Expr indexMinusOne = t1Andt2.andExpr(rat(bitPos-1));
1450       if(d_theoryBitvector->d_bvPlusCarryCacheRightBV.find(indexMinusOne) ==
1451 	 d_theoryBitvector->d_bvPlusCarryCacheRightBV.end())
1452 	DebugAssert(false,
1453 		    "this should not happen");
1454       carryin =
1455 	(d_theoryBitvector->d_bvPlusCarryCacheRightBV).find(indexMinusOne)->second;
1456       //(*d_bvPlusCarryCacheRightBV.find(indexMinusOne)).second;
1457       Expr secondTerm = t1Thm.andExpr(carryin);
1458       Expr thirdTerm = t2Thm.andExpr(carryin);
1459 
1460       carryout = (x.orExpr(secondTerm)).orExpr(thirdTerm);
1461       d_theoryBitvector->d_bvPlusCarryCacheRightBV.insert(index,carryout);
1462     }
1463   }
1464   //cout << "the carry for" << index << " is : " << carryout << "\n";
1465   return carryin;
1466 }
1467 
1468 Theorem
1469 BitvectorTheoremProducer::
zeroPaddingRule(const Expr & e,int i)1470 zeroPaddingRule(const Expr& e, int i) {
1471   if(CHECK_PROOFS) {
1472     CHECK_SOUND(BITVECTOR == e.getType().getExpr().getOpKind(),
1473 		"BitvectorTheoremProducer::zeroPaddingRule:"
1474 		"Wrong Input: Input must be a bitvector. But the input is: " +
1475 		e.toString());
1476   }
1477 
1478   int bvLength =
1479     d_theoryBitvector->BVSize(d_theoryBitvector->getBaseType(e).getExpr());
1480 
1481   if(CHECK_PROOFS) {
1482     CHECK_SOUND(0 <= i &&  i >= bvLength,
1483 		"BitvectorTheoremProducer::zeroPaddingRule:"
1484 		"bitPosition of extraction must be greater than bvLength" +
1485 		int2string(i) + "bvLength:" + int2string(bvLength));
1486   }
1487   const Expr boolExtractExpr = d_theoryBitvector->newBoolExtractExpr(e, i);
1488 
1489   Proof pf;
1490   if(withProof())
1491     pf = newPf("zeropadding_rule", e, rat(i));
1492   return newRWTheorem(boolExtractExpr, d_theoryBitvector->falseExpr(), Assumptions::emptyAssump(), pf);
1493 }
1494 
1495 Theorem
1496 BitvectorTheoremProducer::
bvPlusAssociativityRule(const Expr & bvPlusTerm)1497 bvPlusAssociativityRule(const Expr& bvPlusTerm)
1498 {
1499   TRACE("bitvector",
1500 	"input to bvPlusAssociativityRule(", bvPlusTerm.toString(), ")");
1501 
1502   Type type = bvPlusTerm.getType();
1503   if(CHECK_PROOFS) {
1504     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1505 		"BitvectorTheoremProducer::bvPlusAssociativityRule:"
1506 		"term must be BITVECTOR type.");
1507     CHECK_SOUND(BVPLUS == bvPlusTerm.getOpKind(),
1508 		"BitvectorTheoremProducer::bvPlusAssociativityRule:"
1509 		"term must have the kind BVPLUS.");
1510     CHECK_SOUND(2 < bvPlusTerm.arity(),
1511 		"BitvectorTheoremProducer::bvPlusAssociativityRule:"
1512 		"term must have arity() greater than 2 for associativity.");
1513   }
1514   std::vector<Expr> BVPlusTerms0;
1515   std::vector<Expr>::const_iterator j = (bvPlusTerm.getKids()).begin();
1516   std::vector<Expr>::const_iterator jend = (bvPlusTerm.getKids()).end();
1517   //skip the first kid
1518   j++;
1519   BVPlusTerms0.insert(BVPlusTerms0.end(), j, jend);
1520   int bvLength = d_theoryBitvector->BVSize(bvPlusTerm);
1521   const Expr bvplus0 = d_theoryBitvector->newBVPlusExpr(bvLength,
1522 							BVPlusTerms0);
1523 
1524   std::vector<Expr> BVPlusTerms1;
1525   BVPlusTerms1.push_back(*((bvPlusTerm.getKids()).begin()));
1526   BVPlusTerms1.push_back(bvplus0);
1527   const Expr bvplusOutput = d_theoryBitvector->newBVPlusExpr(bvLength,
1528 							     BVPlusTerms1);
1529 
1530   Proof pf;
1531   if(withProof()) pf = newPf("bv_plus_associativityrule", bvPlusTerm);
1532   const Theorem result(newRWTheorem(bvPlusTerm, bvplusOutput, Assumptions::emptyAssump(), pf));
1533   TRACE("bitvector",
1534 	"output of bvPlusAssociativityRule(", result, ")");
1535   return result;
1536 }
1537 
1538 
bitExtractNot(const Expr & x,int i)1539 Theorem BitvectorTheoremProducer::bitExtractNot(const Expr & x,
1540 						int i) {
1541   TRACE("bitvector", "input to bitExtractNot(", x.toString(), ")");
1542   TRACE("bitvector", "input to bitExtractNot(", int2string(i), ")");
1543 
1544   Type type = x.getType();
1545   if(CHECK_PROOFS) {
1546     //check if the expr is indeed a bitvector term and a concat.
1547     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1548 		"BitvectorTheoremProducer::bitExtractNot:"
1549 		"term must be bitvector.");
1550     CHECK_SOUND(BVNEG == x.getOpKind() && 1 == x.arity(),
1551 		"BitvectorTheoremProducer::bitExtractNot:"
1552 		"the bitvector must be an bitwise negation." + x.toString());
1553     //check if 0<= i < Length of bitvector constant
1554     int bvLength= d_theoryBitvector->BVSize(type.getExpr());
1555     CHECK_SOUND(0 <= i && i < bvLength,
1556 		"BitvectorTheoremProducer::bitExtractNot:"
1557 		"illegal boolean extraction was attempted at position i = "
1558 		+ int2string(i)
1559 		+ "\non bitvector x = " + x.toString()
1560 		+ "\nwhose Length is = " +
1561 		int2string(bvLength));
1562   }
1563   // bool-extract of the bitvector constant
1564   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1565   const Expr bitNegTerm = d_theoryBitvector->newBoolExtractExpr(x[0], i);
1566 
1567   Proof pf;
1568   if(withProof()) pf = newPf("bit_extract_bitwiseneg", x, rat(i));
1569   const Theorem result(newRWTheorem(bitExtract,!bitNegTerm,Assumptions::emptyAssump(),pf));
1570   TRACE("bitvector","output of bitExtractNot(", result, ")");
1571   return result;
1572 }
1573 
1574 
bitExtractBitwise(const Expr & x,int i,int kind)1575 Theorem BitvectorTheoremProducer::bitExtractBitwise(const Expr & x,
1576                                                     int i, int kind)
1577 {
1578   TRACE("bitvector", "bitExtractBitwise(", x, ", "+ int2string(i)+") {");
1579   Type type = x.getType();
1580   if(CHECK_PROOFS) {
1581     CHECK_SOUND(kind == BVAND || kind == BVOR || kind == BVXOR,
1582 		"BitvectorTheoremProducer::bitExtractBitwise: kind = "
1583 		+d_theoryBitvector->getEM()->getKindName(kind));
1584     //check if the expr is indeed a bitvector term and a concat.
1585     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1586 		"BitvectorTheoremProducer::bitExtractBitwise: "
1587 		"term must be bitvector.\n x = "+x.toString()
1588 		+" : "+type.toString());
1589     CHECK_SOUND(x.getOpKind() == kind && 2 <= x.arity(),
1590 		"BitvectorTheoremProducer::bitExtractBitwise: "
1591 		"kind does not match.\n x = "
1592 		+ x.toString());
1593     //check if 0<= i < Length of bitvector constant
1594     int size = d_theoryBitvector->BVSize(x);
1595     CHECK_SOUND(0 <= i && i < size,
1596 		"BitvectorTheoremProducer::bitExtractBitwise: "
1597 		"illegal boolean extraction was attempted.\n i = "
1598 		+ int2string(i) + "\n size = "+ int2string(size));
1599   }
1600   // bool-extract of the bitvector constant
1601   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1602   vector<Expr> kids;
1603   for(Expr::iterator j=x.begin(), jend=x.end(); j!=jend; ++j) {
1604     kids.push_back(d_theoryBitvector->newBoolExtractExpr(*j, i));
1605   }
1606 
1607   int resKind = kind == BVAND ? AND :
1608     kind == BVOR ? OR : XOR;
1609   Expr rhs = Expr(resKind, kids);
1610 
1611   Proof pf;
1612   if(withProof()) pf = newPf("bit_extract_bitwise", x, rat(i));
1613   const Theorem result(newRWTheorem(bitExtract, rhs, Assumptions::emptyAssump(), pf));
1614   TRACE("bitvector", "bitExtractBitwise => ", result.toString(), " }");
1615   return result;
1616 }
1617 
1618 
bitExtractFixedLeftShift(const Expr & x,int i)1619 Theorem BitvectorTheoremProducer::bitExtractFixedLeftShift(const Expr & x,
1620 							   int i) {
1621   TRACE("bitvector", "input to bitExtractFixedleftshift(", x.toString(), ")");
1622   TRACE("bitvector", "input to bitExtractFixedleftshift(", int2string(i), ")");
1623 
1624   Type type = x.getType();
1625   if(CHECK_PROOFS) {
1626     //check if the expr is indeed a bitvector term and a left shift.
1627     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1628 		"BitvectorTheoremProducer::bitExtractFixedleftshift:"
1629 		"term must be bitvector.");
1630     CHECK_SOUND((x.getOpKind() == LEFTSHIFT ||
1631                 x.getOpKind() == CONST_WIDTH_LEFTSHIFT) && 1 == x.arity(),
1632 		"BitvectorTheoremProducer::bitExtractFixedleftshift:"
1633 		"the bitvector must be a bitwise LEFTSHIFT." +
1634 		x.toString());
1635     CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(x) >= 0,
1636 		"BitvectorTheoremProducer::bitExtractFixedleftshift:"
1637 		"the bitvector must be a bitwise LEFTSHIFT." +
1638 		x.toString());
1639     //check if 0<= i < bvLength of bitvector constant
1640     int bvLength= d_theoryBitvector->BVSize(type.getExpr());
1641     CHECK_SOUND(0 <= i && i < bvLength,
1642 		"BitvectorTheoremProducer::bitExtractNot:"
1643 		"illegal boolean extraction was attempted at position i = "
1644 		+ int2string(i)
1645 		+ "\non bitvector x = " + x.toString()
1646 		+ "\nwhose bvLength is = " +
1647 		int2string(bvLength));
1648   }
1649   // bool-extract of the bitvector constant
1650   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1651   int shiftLength = d_theoryBitvector->getFixedLeftShiftParam(x);
1652   Expr output;
1653   if(0 <= i && i < shiftLength)
1654     output = d_theoryBitvector->falseExpr();
1655   else
1656     output =
1657       d_theoryBitvector->newBoolExtractExpr(x[0], i-shiftLength);
1658 
1659   Proof pf;
1660   if(withProof())
1661     pf = newPf("bit_extract_bitwisefixedleftshift", x,rat(i));
1662   const Theorem result = newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf);
1663   TRACE("bitvector",
1664 	"output of bitExtractFixedleftshift(", result, ")");
1665   return result;
1666 }
1667 
bitExtractFixedRightShift(const Expr & x,int i)1668 Theorem BitvectorTheoremProducer::bitExtractFixedRightShift(const Expr & x,
1669 							    int i) {
1670   TRACE("bitvector", "input to bitExtractFixedRightShift(", x.toString(), ")");
1671   TRACE("bitvector", "input to bitExtractFixedRightShift(", int2string(i), ")");
1672 
1673   Type type = x.getType();
1674   if(CHECK_PROOFS) {
1675     //check if the expr is indeed a bitvector term and a concat.
1676     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1677 		"BitvectorTheoremProducer::bitExtractFixedRightShift:"
1678 		"term must be bitvector.");
1679     CHECK_SOUND(RIGHTSHIFT == x.getOpKind() && 1 == x.arity(),
1680 		"BitvectorTheoremProducer::bitExtractFixedRightShift:"
1681 		"the bitvector must be an bitwise RIGHTSHIFT." +
1682 		x.toString());
1683     CHECK_SOUND(d_theoryBitvector->getFixedRightShiftParam(x) >= 0,
1684 		"BitvectorTheoremProducer::bitExtractFixedRightShift:"
1685 		"the bitvector must be an bitwise RIGHTSHIFT." +
1686 		x.toString());
1687   }
1688   //check if 0<= i < bvLength of bitvector constant
1689   int bvLength = d_theoryBitvector->BVSize(x);
1690   if(CHECK_PROOFS)
1691     CHECK_SOUND(0 <= i && i < bvLength,
1692 		"BitvectorTheoremProducer::bitExtractNot:"
1693 		"illegal boolean extraction was attempted at position i = "
1694 		+ int2string(i)
1695 		+ "\non bitvector t = " + x.toString()
1696 		+ "\nwhose Length is = " +
1697 		int2string(bvLength));
1698 
1699   // bool-extract of the bitvector constant
1700   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1701   int shiftLength = d_theoryBitvector->getFixedRightShiftParam(x);
1702   Expr output;
1703   if(bvLength > i && i > bvLength-shiftLength-1)
1704     output = d_theoryBitvector->falseExpr();
1705   else
1706     output =
1707       d_theoryBitvector->newBoolExtractExpr(x[0], i);
1708 
1709   Proof pf;
1710   if(withProof())
1711     pf = newPf("bit_extract_bitwiseFixedRightShift", x,rat(i));
1712   const Theorem result = newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf);
1713   TRACE("bitvector",
1714 	"output of bitExtractFixedRightShift(", result, ")");
1715   return result;
1716 }
1717 
1718 // BOOLEXTRACT(bvshl(t,s),i) <=> ((s = 0) AND BOOLEXTRACT(t,i)) OR
1719 //                               ((s = 1) AND BOOLEXTRACT(t,i-1)) OR ...
1720 //                               ((s = i) AND BOOLEXTRACT(t,0))
bitExtractBVSHL(const Expr & x,int i)1721 Theorem BitvectorTheoremProducer::bitExtractBVSHL(const Expr & x, int i)
1722 {
1723   Type type = x.getType();
1724   int bvLength= d_theoryBitvector->BVSize(x);
1725   if(CHECK_PROOFS) {
1726     //check if the expr is indeed a bitvector term and a left shift.
1727     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1728 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1729 		"term must be bitvector.");
1730     CHECK_SOUND(x.getOpKind() == BVSHL && 2 == x.arity(),
1731 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1732 		"the bitvector must be a BVSHL." +
1733 		x.toString());
1734     //check if 0<= i < bvLength of bitvector constant
1735     CHECK_SOUND(0 <= i && i < bvLength,
1736 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1737 		"illegal boolean extraction was attempted at position i = "
1738 		+ int2string(i)
1739 		+ "\non bitvector x = " + x.toString()
1740 		+ "\nwhose bvLength is = " +
1741 		int2string(bvLength));
1742   }
1743   // bool-extract of the bitvector constant
1744   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1745 
1746   const Expr& term = x[0];
1747   const Expr& shift = x[1];
1748 
1749   vector<Expr> kids;
1750 
1751   for (int j = 0; j <= i; ++j) {
1752     Expr eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(j, bvLength));
1753     Expr ext = d_theoryBitvector->newBoolExtractExpr(term, i-j);
1754     kids.push_back(eq && ext);
1755   }
1756 
1757   Expr output;
1758   if (kids.size() == 1) {
1759     output = kids[0];
1760   }
1761   else {
1762     output = Expr(OR, kids);
1763   }
1764 
1765   Proof pf;
1766   if(withProof())
1767     pf = newPf("bit_extract_bvshl", x, rat(i));
1768   return newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf);
1769 }
1770 
1771 
1772 // BOOLEXTRACT(bvlshr(t,s),i) <=> ((s = 0) AND BOOLEXTRACT(t,i)) OR
1773 //                                ((s = 1) AND BOOLEXTRACT(t,i+1)) OR ...
1774 //                                ((s = n-1-i) AND BOOLEXTRACT(t,n-1))
bitExtractBVLSHR(const Expr & x,int i)1775 Theorem BitvectorTheoremProducer::bitExtractBVLSHR(const Expr & x, int i)
1776 {
1777   Type type = x.getType();
1778   int bvLength= d_theoryBitvector->BVSize(x);
1779   if(CHECK_PROOFS) {
1780     //check if the expr is indeed a bitvector term and a left shift.
1781     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1782 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1783 		"term must be bitvector.");
1784     CHECK_SOUND(x.getOpKind() == BVLSHR && 2 == x.arity(),
1785 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1786 		"the bitvector must be a BVSHL." +
1787 		x.toString());
1788     //check if 0<= i < bvLength of bitvector constant
1789     CHECK_SOUND(0 <= i && i < bvLength,
1790 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1791 		"illegal boolean extraction was attempted at position i = "
1792 		+ int2string(i)
1793 		+ "\non bitvector x = " + x.toString()
1794 		+ "\nwhose bvLength is = " +
1795 		int2string(bvLength));
1796   }
1797   // bool-extract of the bitvector constant
1798   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1799 
1800   const Expr& term = x[0];
1801   const Expr& shift = x[1];
1802 
1803   vector<Expr> kids;
1804 
1805   for (int j = 0; j <= bvLength-1-i; ++j) {
1806     Expr eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(j, bvLength));
1807     Expr ext = d_theoryBitvector->newBoolExtractExpr(term, i+j);
1808     kids.push_back(eq && ext);
1809   }
1810 
1811   Expr output;
1812   if (kids.size() == 1) {
1813     output = kids[0];
1814   }
1815   else {
1816     output = Expr(OR, kids);
1817   }
1818 
1819   Proof pf;
1820   if(withProof())
1821     pf = newPf("bit_extract_bvlshr", x, rat(i));
1822   return newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf);
1823 }
1824 
1825 
1826 // BOOLEXTRACT(bvashr(t,s),i) <=> ((s = 0) AND BOOLEXTRACT(t,i)) OR
1827 //                                ((s = 1) AND BOOLEXTRACT(t,i+1)) OR ...
1828 //                                ((s >= n-1-i) AND BOOLEXTRACT(t,n-1))
bitExtractBVASHR(const Expr & x,int i)1829 Theorem BitvectorTheoremProducer::bitExtractBVASHR(const Expr & x, int i)
1830 {
1831   Type type = x.getType();
1832   int bvLength= d_theoryBitvector->BVSize(x);
1833   if(CHECK_PROOFS) {
1834     //check if the expr is indeed a bitvector term and a left shift.
1835     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
1836 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1837 		"term must be bitvector.");
1838     CHECK_SOUND(x.getOpKind() == BVASHR && 2 == x.arity(),
1839 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1840 		"the bitvector must be a BVSHL." +
1841 		x.toString());
1842     //check if 0<= i < bvLength of bitvector constant
1843     CHECK_SOUND(0 <= i && i < bvLength,
1844 		"BitvectorTheoremProducer::bitExtractBVSHL:"
1845 		"illegal boolean extraction was attempted at position i = "
1846 		+ int2string(i)
1847 		+ "\non bitvector x = " + x.toString()
1848 		+ "\nwhose bvLength is = " +
1849 		int2string(bvLength));
1850   }
1851   // bool-extract of the bitvector constant
1852   const Expr bitExtract = d_theoryBitvector->newBoolExtractExpr(x, i);
1853 
1854   const Expr& term = x[0];
1855   const Expr& shift = x[1];
1856 
1857   vector<Expr> kids;
1858   int j = 0;
1859   for (; j < bvLength-1-i; ++j) {
1860     Expr eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(j, bvLength));
1861     Expr ext = d_theoryBitvector->newBoolExtractExpr(term, i+j);
1862     kids.push_back(eq && ext);
1863   }
1864   Expr tmp = d_theoryBitvector->newBVConstExpr(j, bvLength);
1865   tmp = d_theoryBitvector->newBVLEExpr(tmp, shift);
1866   Expr ext = d_theoryBitvector->newBoolExtractExpr(term, bvLength-1);
1867   kids.push_back(tmp && ext);
1868 
1869   Expr output;
1870   if (kids.size() == 1) {
1871     output = kids[0];
1872   }
1873   else {
1874     output = Expr(OR, kids);
1875   }
1876 
1877   Proof pf;
1878   if(withProof())
1879     pf = newPf("bit_extract_bvashr", x, rat(i));
1880   return newRWTheorem(bitExtract, output, Assumptions::emptyAssump(), pf);
1881 }
1882 
1883 
1884 //! Check that all the kids of e are BVCONST
constantKids(const Expr & e)1885 static bool constantKids(const Expr& e) {
1886   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i)
1887     if(i->getOpKind() != BVCONST) return false;
1888   return true;
1889 }
1890 
1891 
1892 //! c1=c2 <=> TRUE/FALSE (equality of constant bitvectors)
eqConst(const Expr & e)1893 Theorem BitvectorTheoremProducer::eqConst(const Expr& e) {
1894   if(CHECK_PROOFS) {
1895     // The kids must be constant expressions
1896     CHECK_SOUND(e.isEq(),
1897 		"BitvectorTheoremProducer::eqConst: e = "+e.toString());
1898     CHECK_SOUND(constantKids(e),
1899 		"BitvectorTheoremProducer::eqConst: e = "+e.toString());
1900   }
1901   Proof pf;
1902   if(withProof())
1903     pf = newPf("bitvector_eq_const", e);
1904   Expr res((e[0]==e[1])? d_theoryBitvector->trueExpr() :
1905                          d_theoryBitvector->falseExpr());
1906   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
1907 }
1908 
1909 
1910 //! |- c1=c2 ==> |- AND(c1[i:i] = c2[i:i]) - expanding equalities into bits
eqToBits(const Theorem & eq)1911 Theorem BitvectorTheoremProducer::eqToBits(const Theorem& eq) {
1912   if(CHECK_PROOFS) {
1913     CHECK_SOUND(eq.isRewrite(),
1914 		"BitvectorTheoremProducer::eqToBits: eq = "+eq.toString());
1915   }
1916 
1917   const Expr& lhs = eq.getLHS();
1918   const Expr& rhs = eq.getRHS();
1919 
1920   if(CHECK_PROOFS) {
1921     CHECK_SOUND(d_theoryBitvector->getBaseType(lhs).getExpr().getOpKind() == BITVECTOR,
1922 		"BitvectorTheoremProducer::eqToBits: eq = "+eq.toString());
1923     CHECK_SOUND(d_theoryBitvector->BVSize(lhs)
1924 		== d_theoryBitvector->BVSize(rhs),
1925 		"BitvectorTheoremProducer::eqToBits: eq = "+eq.toString());
1926   }
1927 
1928   int i=0, size=d_theoryBitvector->BVSize(lhs);
1929   vector<Expr> bitEqs;
1930   for(; i<size; i++) {
1931     Expr l = d_theoryBitvector->newBVExtractExpr(lhs, i, i);
1932     Expr r = d_theoryBitvector->newBVExtractExpr(rhs, i, i);
1933     bitEqs.push_back(l.eqExpr(r));
1934   }
1935   Expr res = andExpr(bitEqs);
1936   Proof pf;
1937   if(withProof())
1938     pf = newPf("eq_to_bits", eq.getExpr(), eq.getProof());
1939   return newTheorem(res, eq.getAssumptionsRef(), pf);
1940 }
1941 
1942 
1943 //! t<<n = c \@ 0bin00...00, takes e == (t<<n)
leftShiftToConcat(const Expr & e)1944 Theorem BitvectorTheoremProducer::leftShiftToConcat(const Expr& e) {
1945   if(CHECK_PROOFS) {
1946     // The kids must be constant expressions
1947     CHECK_SOUND(e.getOpKind() == LEFTSHIFT && e.arity() == 1,
1948 		"BitvectorTheoremProducer::leftShiftConst: e = "+e.toString());
1949     CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(e) >= 0,
1950 		"BitvectorTheoremProducer::leftShiftConst: e = "+e.toString());
1951   }
1952   const Expr& e0 = e[0];
1953   Expr res(e0);
1954   int shiftSize=d_theoryBitvector->getFixedLeftShiftParam(e);
1955 
1956   if (shiftSize != 0) {
1957     Expr padding = d_theoryBitvector->newBVConstExpr(Rational(0), shiftSize);
1958     res = d_theoryBitvector->newConcatExpr(e0, padding);
1959   }
1960 
1961   Proof pf;
1962   if(withProof())
1963     pf = newPf("leftshift_to_concat", e);
1964   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
1965 }
1966 
1967 //! t<<n = c \@ 0bin00...00, takes e == (t<<n)
constWidthLeftShiftToConcat(const Expr & e)1968 Theorem BitvectorTheoremProducer::constWidthLeftShiftToConcat(const Expr& e) {
1969   if(CHECK_PROOFS) {
1970     // The kids must be constant expressions
1971     CHECK_SOUND(e.getOpKind() == CONST_WIDTH_LEFTSHIFT && e.arity() == 1,
1972 		"BitvectorTheoremProducer::leftShiftConst: e = "+e.toString());
1973     CHECK_SOUND(d_theoryBitvector->getFixedLeftShiftParam(e) >= 0,
1974 		"BitvectorTheoremProducer::leftShiftConst: e = "+e.toString());
1975   }
1976   const Expr& e0 = e[0];
1977   Expr res;
1978 
1979   int shiftSize=d_theoryBitvector->getFixedLeftShiftParam(e);
1980   if (shiftSize == 0)
1981     res = e0;
1982   else {
1983     int bvLength = d_theoryBitvector->BVSize(e);
1984     if (shiftSize >= bvLength)
1985       res = d_theoryBitvector->newBVConstExpr(Rational(0), bvLength);
1986     else {
1987       Expr padding = d_theoryBitvector->newBVConstExpr(Rational(0), shiftSize);
1988       res = d_theoryBitvector->newBVExtractExpr(e0, bvLength-shiftSize-1, 0);
1989       res = d_theoryBitvector->newConcatExpr(res, padding);
1990     }
1991   }
1992 
1993   Proof pf;
1994   if(withProof())
1995     pf = newPf("constWidthLeftShift_to_concat", e);
1996   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
1997 }
1998 
1999 
2000 //! t>>m = 0bin00...00 \@ t[bvLength-1:m], takes e == (t>>n)
rightShiftToConcat(const Expr & e)2001 Theorem BitvectorTheoremProducer::rightShiftToConcat(const Expr& e) {
2002   if(CHECK_PROOFS) {
2003     CHECK_SOUND(e.getOpKind() == RIGHTSHIFT && e.arity() == 1,
2004 		"BitvectorTheoremProducer::rightShiftConst: e = "+e.toString());
2005     CHECK_SOUND(d_theoryBitvector->getFixedRightShiftParam(e) >= 0,
2006 		"BitvectorTheoremProducer::rightShiftConst: e = "+e.toString());
2007   }
2008   int bvLength = d_theoryBitvector->BVSize(e[0]);
2009 
2010   int shiftSize=d_theoryBitvector->getFixedRightShiftParam(e);
2011 
2012   Expr output;
2013   if (shiftSize == 0) output = e[0];
2014   if (shiftSize >= bvLength)
2015     output = d_theoryBitvector->newBVZeroString(bvLength);
2016   else {
2017 	  Expr padding = d_theoryBitvector->newBVZeroString(shiftSize);
2018 	  Expr out0 = d_theoryBitvector->newBVExtractExpr(e[0],bvLength-1,shiftSize);
2019 	  output = d_theoryBitvector->newConcatExpr(padding,out0);
2020   }
2021 
2022   DebugAssert(bvLength == d_theoryBitvector->BVSize(output),
2023 	      "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString());
2024 
2025   Proof pf;
2026   if(withProof())
2027     pf = newPf("rightshift_to_concat", e);
2028   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2029 }
2030 
2031 
2032 //! BVSHL(t,c) = t[n-c,0] \@ 0bin00...00
bvshlToConcat(const Expr & e)2033 Theorem BitvectorTheoremProducer::bvshlToConcat(const Expr& e) {
2034   if(CHECK_PROOFS) {
2035     // The second kid must be a constant expression
2036     CHECK_SOUND(e.getOpKind() == BVSHL && e.arity() == 2,
2037 		"BitvectorTheoremProducer::bvshlToConcat: e = "+e.toString());
2038     CHECK_SOUND(e[1].getOpKind() == BVCONST,
2039 		"BitvectorTheoremProducer::bvshlToConcat: e = "+e.toString());
2040   }
2041   const Expr& e0 = e[0];
2042   Expr res;
2043 
2044   Rational shiftSize=d_theoryBitvector->computeBVConst(e[1]);
2045   if (shiftSize == 0) res = e0;
2046   else {
2047     int bvLength = d_theoryBitvector->BVSize(e);
2048     if (shiftSize >= bvLength)
2049       res = d_theoryBitvector->newBVConstExpr(Rational(0), bvLength);
2050     else {
2051       Expr padding = d_theoryBitvector->newBVConstExpr(Rational(0), shiftSize.getInt());
2052       res = d_theoryBitvector->newBVExtractExpr(e0, bvLength-shiftSize.getInt()-1, 0);
2053       res = d_theoryBitvector->newConcatExpr(res, padding);
2054     }
2055   }
2056 
2057   Proof pf;
2058   if(withProof())
2059     pf = newPf("bvshl_to_concat");
2060   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2061 }
2062 
2063 
2064 // bvshl(t,s) = IF (s = 0) THEN t ELSE
2065 //              IF (s = 1) then t[n-2:0] @ 0 Else
2066 //              ...
2067 //              ELSE 0
bvshlSplit(const Expr & e)2068 Theorem BitvectorTheoremProducer::bvshlSplit(const Expr &e)
2069 {
2070   Type type = e.getType();
2071   int bvLength= d_theoryBitvector->BVSize(e);
2072   if(CHECK_PROOFS) {
2073     //check if the expr is indeed a bitvector term and a left shift.
2074     CHECK_SOUND(BITVECTOR == type.getExpr().getOpKind(),
2075 		"BitvectorTheoremProducer::bitExtractBVSHL:"
2076 		"term must be bitvector.");
2077     CHECK_SOUND(e.getOpKind() == BVSHL && 2 == e.arity(),
2078 		"BitvectorTheoremProducer::bitExtractBVSHL:"
2079 		"the bitvector must be a BVSHL." +
2080 		e.toString());
2081   }
2082 
2083   const Expr& term = e[0];
2084   const Expr& shift = e[1];
2085 
2086   Expr newExpr = d_theoryBitvector->newBVZeroString(bvLength);
2087   Expr eq, tmp;
2088 
2089   for (int i = bvLength-1; i > 0; --i) {
2090     eq = shift.eqExpr(d_theoryBitvector->newBVConstExpr(i, bvLength));
2091     tmp = d_theoryBitvector->newBVExtractExpr(term, bvLength-i-1, 0);
2092     tmp = d_theoryBitvector->newConcatExpr(tmp, d_theoryBitvector->newBVZeroString(i));
2093     newExpr = eq.iteExpr(tmp, newExpr);
2094   }
2095 
2096   eq = shift.eqExpr(d_theoryBitvector->newBVZeroString(bvLength));
2097   newExpr = eq.iteExpr(term, newExpr);
2098 
2099   Proof pf;
2100   if(withProof())
2101     pf = newPf("bvshl_split", e);
2102   return newRWTheorem(e, newExpr, Assumptions::emptyAssump(), pf);
2103 }
2104 
2105 
2106 //! BVLSHR(t,c) = 0bin00...00 \@ t[n-1,c]
bvlshrToConcat(const Expr & e)2107 Theorem BitvectorTheoremProducer::bvlshrToConcat(const Expr& e)
2108 {
2109   if(CHECK_PROOFS) {
2110     CHECK_SOUND(e.getOpKind() == BVLSHR && e.arity() == 2,
2111 		"BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString());
2112     CHECK_SOUND(e[1].getOpKind() == BVCONST,
2113 		"BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString());
2114   }
2115   int bvLength = d_theoryBitvector->BVSize(e);
2116 
2117   Rational shiftSize=d_theoryBitvector->computeBVConst(e[1]);
2118 
2119   Expr output;
2120   if (shiftSize == 0) output = e[0];
2121   else if(shiftSize >= bvLength)
2122     output = d_theoryBitvector->newBVZeroString(bvLength);
2123   else {
2124     Expr padding = d_theoryBitvector->newBVZeroString(shiftSize.getInt());
2125     Expr out0 = d_theoryBitvector->newBVExtractExpr(e[0],bvLength-1,shiftSize.getInt());
2126     output = d_theoryBitvector->newConcatExpr(padding,out0);
2127   }
2128 
2129   Proof pf;
2130   if(withProof())
2131     pf = newPf("bvlshr_to_concat", e);
2132   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2133 }
2134 
bvShiftZero(const Expr & e)2135 Theorem BitvectorTheoremProducer::bvShiftZero(const Expr& e)
2136 {
2137   if(CHECK_PROOFS) {
2138 	int kind = e.getOpKind();
2139 	CHECK_SOUND((kind == BVLSHR || kind == BVSHL || kind == BVASHR || kind == LEFTSHIFT || kind == CONST_WIDTH_LEFTSHIFT || kind == RIGHTSHIFT)
2140 				 && e.arity() == 2, "BitvectorTheoremProducer::bvShiftZero: e = "+e.toString());
2141 	CHECK_SOUND(e[0].getOpKind() == BVCONST && d_theoryBitvector->computeBVConst(e[0]) == 0, "BitvectorTheoremProducer::bvShiftZero: e = "+e.toString());
2142   }
2143 
2144   int bvLength = d_theoryBitvector->BVSize(e);
2145   Expr output = d_theoryBitvector->newBVZeroString(bvLength);
2146 
2147   Proof pf;
2148   if(withProof())
2149     pf = newPf("shift_zero", e);
2150 
2151   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2152 }
2153 
2154 //! BVASHR(t,c) = SX(t[n-1,c], n-1)
bvashrToConcat(const Expr & e)2155 Theorem BitvectorTheoremProducer::bvashrToConcat(const Expr& e)
2156 {
2157   if(CHECK_PROOFS) {
2158     CHECK_SOUND(e.getOpKind() == BVASHR && e.arity() == 2,
2159 		"BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString());
2160     CHECK_SOUND(e[1].getOpKind() == BVCONST,
2161 		"BitvectorTheoremProducer::bvlshrToConcat: e = "+e.toString());
2162   }
2163   int bvLength = d_theoryBitvector->BVSize(e);
2164 
2165   Rational shiftSize=d_theoryBitvector->computeBVConst(e[1]);
2166 
2167   Expr output;
2168   if (shiftSize > 0) {
2169 	  if (shiftSize >= bvLength) shiftSize = bvLength - 1;
2170 	  Expr out0 = d_theoryBitvector->newBVExtractExpr(e[0],bvLength-1,shiftSize.getInt());
2171 	  output = d_theoryBitvector->newSXExpr(out0, bvLength);
2172   } else output = e[0];
2173 
2174   Proof pf;
2175   if(withProof())
2176     pf = newPf("bvashr_to_concat", e);
2177   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2178 }
2179 
2180 
rewriteXNOR(const Expr & e)2181 Theorem BitvectorTheoremProducer::rewriteXNOR(const Expr& e)
2182 {
2183   if (CHECK_PROOFS) {
2184     CHECK_SOUND(e.getKind() == BVXNOR && e.arity() == 2,
2185                 "Bad call to rewriteXNOR");
2186   }
2187   Expr res = d_theoryBitvector->newBVNegExpr(e[0]);
2188   res = d_theoryBitvector->newBVXorExpr(res, e[1]);
2189   Proof pf;
2190   if (withProof())
2191     pf = newPf("rewriteXNOR", e);
2192   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2193 }
2194 
2195 
rewriteNAND(const Expr & e)2196 Theorem BitvectorTheoremProducer::rewriteNAND(const Expr& e)
2197 {
2198   if (CHECK_PROOFS) {
2199     CHECK_SOUND(e.getKind() == BVNAND && e.arity() == 2,
2200                 "Bad call to rewriteNAND");
2201   }
2202   Expr andExpr = d_theoryBitvector->newBVAndExpr(e[0], e[1]);
2203   Proof pf;
2204   if (withProof())
2205     pf = newPf("rewriteNAND", e);
2206   return newRWTheorem(e, d_theoryBitvector->newBVNegExpr(andExpr),
2207                       Assumptions::emptyAssump(), pf);
2208 }
2209 
2210 
rewriteNOR(const Expr & e)2211 Theorem BitvectorTheoremProducer::rewriteNOR(const Expr& e)
2212 {
2213   if (CHECK_PROOFS) {
2214     CHECK_SOUND(e.getKind() == BVNOR && e.arity() == 2,
2215                 "Bad call to rewriteNOR");
2216   }
2217   Expr orExpr = d_theoryBitvector->newBVOrExpr(e[0], e[1]);
2218   Proof pf;
2219   if (withProof())
2220     pf = newPf("rewriteNOR", e);
2221   return newRWTheorem(e, d_theoryBitvector->newBVNegExpr(orExpr),
2222                       Assumptions::emptyAssump(), pf);
2223 }
2224 
2225 
rewriteBVCOMP(const Expr & e)2226 Theorem BitvectorTheoremProducer::rewriteBVCOMP(const Expr& e)
2227 {
2228   if (CHECK_PROOFS) {
2229     CHECK_SOUND(e.getKind() == BVCOMP && e.arity() == 2,
2230                 "Bad call to rewriteBVCOMP");
2231   }
2232   Expr res = e[0].eqExpr(e[1]).iteExpr(d_theoryBitvector->newBVOneString(1),
2233                                        d_theoryBitvector->newBVZeroString(1));
2234   Proof pf;
2235   if (withProof())
2236     pf = newPf("rewriteBVCOMP");
2237   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2238 }
2239 
2240 
rewriteBVSub(const Expr & e)2241 Theorem BitvectorTheoremProducer::rewriteBVSub(const Expr& e)
2242 {
2243   if (CHECK_PROOFS) {
2244     CHECK_SOUND(e.getKind() == BVSUB && e.arity() == 2 &&
2245                 d_theoryBitvector->BVSize(e[0]) ==
2246                 d_theoryBitvector->BVSize(e[1]),
2247                 "Bad call to rewriteBVSub");
2248   }
2249   int bvsize = d_theoryBitvector->BVSize(e[0]);
2250   vector<Expr> k;
2251   k.push_back(e[0]);
2252   k.push_back(d_theoryBitvector->newBVUminusExpr(e[1]));
2253   Expr new_expr = d_theoryBitvector->newBVPlusExpr(bvsize, k);
2254 
2255   ExprMap<Rational> sumHashMap;
2256   Rational known_term;
2257   getPlusTerms(new_expr, known_term, sumHashMap);
2258   new_expr = buildPlusTerm(bvsize, known_term, sumHashMap);
2259 
2260 
2261   Proof pf;
2262   if (withProof())
2263     pf = newPf("rewriteBVSub", e);
2264   return newRWTheorem(e, new_expr, Assumptions::emptyAssump(), pf);
2265 }
2266 
2267 
2268 //! k*t = BVPLUS(n, <sum of shifts of t>) -- translation of k*t to BVPLUS
2269 /*! If k = 2^m, return k*t = t\@0...0 */
constMultToPlus(const Expr & e)2270 Theorem BitvectorTheoremProducer::constMultToPlus(const Expr& e) {
2271   DebugAssert(false,
2272 	      "BitvectorTheoremProducer::constMultToPlus: this rule does not work\n");
2273   if(CHECK_PROOFS) {
2274     CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2
2275 		&& e[0].isRational() && e[0].getRational().isInteger(),
2276 		"BitvectorTheoremProducer::constMultToPlus:\n e = "
2277 		+e.toString());
2278   }
2279 
2280   Rational k = e[0].getRational();
2281   const Expr& t = e[1];
2282   int resLength = d_theoryBitvector->BVSize(e);
2283   string coeffBinary = abs(k).toString(2);
2284   int len = coeffBinary.length();
2285   Expr res; // The resulting expression
2286   if(k == 0) {
2287     // Construct n-bit vector of 0's
2288     vector<bool> bits;
2289     int len = resLength;
2290     for(int i=0; i<len; ++i) bits.push_back(false);
2291     res = d_theoryBitvector->newBVConstExpr(bits);
2292   } else {
2293     // Construct the vector of shifts, the kids of the resulting BVPLUS
2294     vector<Expr> kids;
2295     for(int i=0; i<len; ++i) {
2296       if(coeffBinary[i] == '1')
2297 	kids.push_back(d_theoryBitvector->newFixedLeftShiftExpr(t, (len-1)-i));
2298     }
2299     res = (kids.size() == 1)? kids[0]
2300       : d_theoryBitvector->newBVPlusExpr(resLength, kids);
2301     // For negative k, compute (~res+1), the 2's complement
2302     if(k < 0) {
2303       vector<Expr> kk;
2304       kk.push_back(d_theoryBitvector->newBVNegExpr(res));
2305       kk.push_back(rat(1));
2306       res = d_theoryBitvector->newBVPlusExpr(resLength, kk);
2307     }
2308   }
2309 
2310   Proof pf;
2311   if(withProof())
2312     pf = newPf("const_mult_to_plus", e);
2313   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2314 }
2315 
2316 
2317 Theorem
bvplusZeroConcatRule(const Expr & e)2318 BitvectorTheoremProducer::bvplusZeroConcatRule(const Expr& e) {
2319   if(CHECK_PROOFS) {
2320     CHECK_SOUND(e.getOpKind()==CONCAT && e.arity()==2,
2321 		"BitvectorTheoremProducer::bvplusZeroConcatRule: e = "
2322 		+e.toString());
2323     CHECK_SOUND(e[0].getKind()==BVCONST && e[1].getOpKind()==BVPLUS
2324 		&& d_theoryBitvector->computeBVConst(e[0])==0,
2325 		"BitvectorTheoremProducer::bvplusZeroConcatRule: e = "
2326 		+e.toString());
2327   }
2328 
2329   int constSize = d_theoryBitvector->BVSize(e[0]);
2330   const Expr& bvplus = e[1];
2331   int bvplusSize = d_theoryBitvector->getBVPlusParam(bvplus);
2332 
2333   // Check if we can apply the rewrite rule
2334   int maxKidSize(0);
2335   for(Expr::iterator i=bvplus.begin(), iend=bvplus.end(); i!=iend; ++i) {
2336     int size(d_theoryBitvector->BVSize(*i));
2337     // if kid is 0bin0 @ ..., then we can shorten its effective size
2338     if(i->getOpKind()==CONCAT && i->arity()>=2
2339        && (*i)[0].getKind()==BVCONST && d_theoryBitvector->computeBVConst((*i)[0])==0)
2340       size -= d_theoryBitvector->BVSize((*i)[0]);
2341     if(size > maxKidSize) maxKidSize = size;
2342   }
2343   int numKids = bvplus.arity();
2344   // Compute ceiling of log2(numKids)
2345   int log2 = 0;
2346   for(int i=1; i < numKids; i *=2, log2++);
2347   if(log2+maxKidSize > bvplusSize) {
2348     // Skip the rewrite, it's potentially unsound
2349     TRACE("bv 0@+", "bvplusZeroConcatRule(", e, "): skipped");
2350     return d_theoryBitvector->reflexivityRule(e);
2351   }
2352 
2353   Expr res(d_theoryBitvector->newBVPlusExpr(bvplusSize+constSize,
2354 					    bvplus.getKids()));
2355 
2356   Proof pf;
2357   if(withProof())
2358     pf = newPf("bvplus_zero_concat", e);
2359   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2360 }
2361 
2362 
2363 
2364 //! c1[i:j] = c  (extraction from a constant bitvector)
extractConst(const Expr & e)2365 Theorem BitvectorTheoremProducer::extractConst(const Expr& e) {
2366   if(CHECK_PROOFS) {
2367     // The kids must be constant expressions
2368     CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
2369 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
2370     CHECK_SOUND(constantKids(e),
2371 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
2372   }
2373 
2374   int hi = d_theoryBitvector->getExtractHi(e);
2375   int low = d_theoryBitvector->getExtractLow(e);
2376   const Expr& e0 = e[0];
2377 
2378   if(CHECK_PROOFS) {
2379     CHECK_SOUND(0 <= low && low <= hi,
2380 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
2381     CHECK_SOUND((unsigned)hi < d_theoryBitvector->getBVConstSize(e0),
2382 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
2383   }
2384   vector<bool> res;
2385 
2386   for(int bit=low; bit <= hi; bit++)
2387     res.push_back(d_theoryBitvector->getBVConstValue(e0, bit));
2388 
2389   Proof pf;
2390   if(withProof())
2391     pf = newPf("extract_const", e);
2392   return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf);
2393 }
2394 
2395 // t[n-1:0] = t  for n-bit t
2396 Theorem
extractWhole(const Expr & e)2397 BitvectorTheoremProducer::extractWhole(const Expr& e) {
2398   if(CHECK_PROOFS) {
2399     CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
2400 		"BitvectorTheoremProducer::extractWhole: e = "+e.toString());
2401   }
2402 
2403   int hi = d_theoryBitvector->getExtractHi(e);
2404   int low = d_theoryBitvector->getExtractLow(e);
2405   const Expr& e0 = e[0];
2406 
2407   if(CHECK_PROOFS) {
2408     CHECK_SOUND(low ==0 && hi == d_theoryBitvector->BVSize(e0) - 1,
2409 		"BitvectorTheoremProducer::extractWhole: e = "+e.toString()
2410 		+"\n BVSize(e) = "+ int2string(d_theoryBitvector->BVSize(e0)));
2411   }
2412   Proof pf;
2413   if(withProof())
2414     pf = newPf("extract_whole", e);
2415   return newRWTheorem(e, e0, Assumptions::emptyAssump(), pf);
2416 }
2417 
2418 
2419 //! t[i:j][k:l] = t[k+j:l+j]  (eliminate double extraction)
2420 Theorem
extractExtract(const Expr & e)2421 BitvectorTheoremProducer::extractExtract(const Expr& e) {
2422   if(CHECK_PROOFS) {
2423     CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
2424 		"BitvectorTheoremProducer::extractExtract: e = "+e.toString());
2425   }
2426 
2427   int hi = d_theoryBitvector->getExtractHi(e);
2428   int low = d_theoryBitvector->getExtractLow(e);
2429   const Expr& e0 = e[0];
2430 
2431   if(CHECK_PROOFS) {
2432     // Check the bounds
2433     CHECK_SOUND(0 <= low && low <= hi,
2434 		"BitvectorTheoremProducer::extractExtract: e = "+e.toString());
2435     // The base expression must also be EXTRACT
2436     CHECK_SOUND(e0.getOpKind() == EXTRACT && e0.arity() == 1,
2437 		"BitvectorTheoremProducer::extractExtract: e0 = "
2438 		+e0.toString());
2439   }
2440 
2441   int hi0 = d_theoryBitvector->getExtractHi(e0);
2442   int low0 = d_theoryBitvector->getExtractLow(e0);
2443   const Expr& e00 = e0[0];
2444 
2445   if(CHECK_PROOFS) {
2446     // The extractions must be within the correct bounds
2447     CHECK_SOUND((0 <= low) && (low <= hi) && (hi <= hi0-low0),
2448 		"BitvectorTheoremProducer::extractExtract:\n"
2449 		" [hi:low][hi0:low0] = ["+ int2string(hi0)+":"+ int2string(low0)
2450 		+"]["+ int2string(hi) + ":" + int2string(low)
2451 		+"]\n e = "+e.toString());
2452   }
2453 
2454   Expr res = d_theoryBitvector->newBVExtractExpr(e00, hi+low0, low+low0);
2455 
2456   Proof pf;
2457   if(withProof())
2458     pf = newPf("extract_extract", e);
2459   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2460 }
2461 
2462 
2463 //! (t1 \@ t2)[i:j] = t1[...] \@ t2[...]  (push extraction through concat)
2464 Theorem
extractConcat(const Expr & e)2465 BitvectorTheoremProducer::extractConcat(const Expr& e) {
2466   TRACE("bitvector rules", "extractConcat(", e, ") {");
2467   if(CHECK_PROOFS) {
2468     CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
2469 		"BitvectorTheoremProducer::extractConcat: e = "+e.toString());
2470   }
2471 
2472   int hi = d_theoryBitvector->getExtractHi(e);
2473   int low = d_theoryBitvector->getExtractLow(e);
2474   const Expr& e0 = e[0];
2475 
2476   if(CHECK_PROOFS) {
2477     // Check the bounds
2478     CHECK_SOUND(0 <= low && low <= hi,
2479 		"BitvectorTheoremProducer::extractConcat: e = "+e.toString());
2480     CHECK_SOUND(hi < d_theoryBitvector->BVSize(e0),
2481 		"BitvectorTheoremProducer::extractConcat: e = "+e.toString()
2482 		+"\n BVSize(e0) = "+ int2string(d_theoryBitvector->BVSize(e0)));
2483     // The base expression  must be CONCAT
2484     CHECK_SOUND(e0.getOpKind() == CONCAT,
2485 		"BitvectorTheoremProducer::extractConcat: e0 = "
2486 		+e0.toString());
2487   }
2488   // Collect the relevant kids from concatenation
2489   vector<Expr> kids;
2490   int width(d_theoryBitvector->BVSize(e0));
2491   TRACE("bitvector rules", "extractConcat: width=", width, "");
2492   for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend && width>low; ++i) {
2493     TRACE("bitvector rules", "extractConcat: *i=", *i, "");
2494     int w(d_theoryBitvector->BVSize(*i));
2495     int newWidth = width-w;
2496     int l(0), h(0);
2497     TRACE("bitvector rules", "extractConcat: w=", w, "");
2498     TRACE("bitvector rules", "extractConcat: newWidth=", newWidth, "");
2499     if(width > hi) { // Previous kids were outside of extract window
2500       if(hi >= newWidth) { // The first relevant kid
2501 	h = hi-newWidth;
2502 	l = (newWidth <= low)? low-newWidth : 0;
2503 	TRACE("bitvector rules", "extractConcat[newWidth<=hi<width]: h=",
2504 	      h, ", l="+ int2string(l));
2505 	kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, h, l));
2506       }
2507     } else if(width > low) {
2508       // High end of the current kid is in the extract window
2509       h = w-1;
2510       l = (newWidth <= low)? low-newWidth : 0;
2511       TRACE("bitvector rules", "extractConcat[low<width<=hi]: h=",
2512 	    h, ", l="+ int2string(l));
2513       kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, h, l));
2514     } // The remaining kids are outside of extract window, skip them
2515     width=newWidth;
2516     TRACE("bitvector rules", "extractConcat: width=", width, "");
2517   }
2518   Expr res = (kids.size()==1)? kids[0]
2519     : d_theoryBitvector->newConcatExpr(kids);
2520   Proof pf;
2521   if(withProof())
2522     pf = newPf("extract_concat", e);
2523   Theorem thm(newRWTheorem(e, res, Assumptions::emptyAssump(), pf));
2524   TRACE("bitvector rules", "extractConcat => ", thm.getExpr(), " }");
2525   return thm;
2526 }
2527 
2528 
2529 // (t1 op t2)[i:j] = t1[i:j] op t2[i:j] -- push extraction through
2530 // bit-wise operator
2531 Theorem
extractBitwise(const Expr & e,int kind,const string & pfName)2532 BitvectorTheoremProducer::extractBitwise(const Expr& e, int kind,
2533 					 const string& pfName) {
2534   if(CHECK_PROOFS) {
2535     CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity() == 1,
2536 		"BitvectorTheoremProducer::"+pfName+": e = "+e.toString());
2537     CHECK_SOUND(kind == BVAND || kind == BVOR ||
2538 		kind == BVNEG || kind == BVXOR ||
2539 		kind == BVXNOR,
2540 		"BitvectorTheoremProducer::"+pfName+": kind = "
2541 		+d_theoryBitvector->getEM()->getKindName(kind));
2542   }
2543 
2544   int hi = d_theoryBitvector->getExtractHi(e);
2545   int low = d_theoryBitvector->getExtractLow(e);
2546   const Expr& e0 = e[0];
2547 
2548   if(CHECK_PROOFS) {
2549     // Check the bounds
2550     CHECK_SOUND(0 <= low && low <= hi,
2551 		"BitvectorTheoremProducer::"+pfName+": e = "+e.toString());
2552     // The base expression must also be EXTRACT
2553     CHECK_SOUND(e0.getOpKind() == kind,
2554 		"BitvectorTheoremProducer::"+pfName+": e0 = "
2555 		+e0.toString());
2556   }
2557 
2558   vector<Expr> kids;
2559   for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend; ++i) {
2560     kids.push_back(d_theoryBitvector->newBVExtractExpr(*i, hi, low));
2561   }
2562   Expr res = Expr(e0.getOp(), kids);
2563   Proof pf;
2564   if(withProof())
2565     pf = newPf(pfName, e);
2566   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2567 }
2568 
2569 //! (t1 & t2)[i:j] = t1[i:j] & t2[i:j]  (push extraction through OR)
2570 Theorem
extractAnd(const Expr & e)2571 BitvectorTheoremProducer::extractAnd(const Expr& e) {
2572   return extractBitwise(e, BVAND, "extract_and");
2573 }
2574 
2575 
2576 //! (t1 | t2)[i:j] = t1[i:j] | t2[i:j]  (push extraction through AND)
2577 Theorem
extractOr(const Expr & e)2578 BitvectorTheoremProducer::extractOr(const Expr& e) {
2579   return extractBitwise(e, BVOR, "extract_or");
2580 }
2581 
2582 
2583 //! (~t)[i:j] = ~(t[i:j]) (push extraction through NEG)
2584 Theorem
extractNeg(const Expr & e)2585 BitvectorTheoremProducer::extractNeg(const Expr& e) {
2586   return extractBitwise(e, BVNEG, "extract_neg");
2587 }
2588 
2589 //! ite(c,t1,t2)[i:j] <=> ite(c,t1[i:j],t2[i:j])
2590 Theorem
iteExtractRule(const Expr & e)2591 BitvectorTheoremProducer::iteExtractRule(const Expr& e) {
2592   if(CHECK_PROOFS) {
2593     CHECK_SOUND(e.getOpKind() == EXTRACT && e.arity()==1,
2594 		"BitvectorTheoremProducer::iteExtractRule: "
2595 		"input must be an bitvector EXTRACT expr:\n"+
2596 		e.toString());
2597   }
2598   int hi = d_theoryBitvector->getExtractHi(e);
2599   int low = d_theoryBitvector->getExtractLow(e);
2600 
2601   if(CHECK_PROOFS) {
2602     CHECK_SOUND(e[0].getKind() == ITE &&
2603 		e[0].arity()==3 &&
2604 		BITVECTOR == e[0].getType().getExpr().getOpKind(),
2605 		"BitvectorTheoremProducer::iteExtractRule: "
2606 		"input must be an bitvector EXTRACT expr over an ITE:\n" +
2607 		e.toString());
2608     CHECK_SOUND(hi >= low && d_theoryBitvector->BVSize(e[0]) >= hi-low,
2609 		"BitvectorTheoremProducer::iteExtractRule: "
2610 		"i should be greater than j in e[i:j] = "
2611 		+e.toString());
2612   }
2613   const Expr ite = e[0];
2614   Expr cond = ite[0];
2615   Expr e1 = d_theoryBitvector->newBVExtractExpr(ite[1],hi,low);
2616   Expr e2 = d_theoryBitvector->newBVExtractExpr(ite[2],hi,low);
2617   Expr output = Expr(CVC3::ITE,cond,e1,e2);
2618 
2619   Proof pf;
2620   if(withProof())
2621     pf = newPf("ite_extract_rule", e);
2622   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2623 }
2624 
2625 //! ~ite(c,t1,t2) <=> ite(c,~t1,~t2)
2626 Theorem
iteBVnegRule(const Expr & e)2627 BitvectorTheoremProducer::iteBVnegRule(const Expr& e) {
2628   if(CHECK_PROOFS) {
2629     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity()==1,
2630 		"BitvectorTheoremProducer::itebvnegrule: "
2631 		"input must be an bitvector EXTRACT expr:\n"+
2632 		e.toString());
2633   }
2634   if(CHECK_PROOFS) {
2635     CHECK_SOUND(e[0].getKind() == ITE &&
2636 		e[0].arity()==3 &&
2637 		BITVECTOR == e[0].getType().getExpr().getOpKind(),
2638 		"BitvectorTheoremProducer::itebvnegrule: "
2639 		"input must be an bitvector EXTRACT expr over an ITE:\n" +
2640 		e.toString());
2641   }
2642   const Expr ite = e[0];
2643   Expr cond = ite[0];
2644   Expr e1 = d_theoryBitvector->newBVNegExpr(ite[1]);
2645   Expr e2 = d_theoryBitvector->newBVNegExpr(ite[2]);
2646   Expr output = Expr(CVC3::ITE,cond,e1,e2);
2647 
2648   Proof pf;
2649   if(withProof())
2650     pf = newPf("ite_bvneg_rule", e);
2651   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2652 }
2653 
2654 //! ~c1 = c  (bit-wise negation of a constant bitvector)
negConst(const Expr & e)2655 Theorem BitvectorTheoremProducer::negConst(const Expr& e) {
2656   if(CHECK_PROOFS) {
2657     // The kids must be constant expressions
2658     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
2659 		"BitvectorTheoremProducer::negConst: e = "+e.toString());
2660     CHECK_SOUND(constantKids(e),
2661 		"BitvectorTheoremProducer::negConst: e = "+e.toString());
2662   }
2663   const Expr& e0 = e[0];
2664   vector<bool> res;
2665 
2666   for(int bit=0, size=d_theoryBitvector->getBVConstSize(e0); bit<size; bit++)
2667     res.push_back(!d_theoryBitvector->getBVConstValue(e0, bit));
2668 
2669   Proof pf;
2670   if(withProof())
2671     pf = newPf("bitneg_const", e);
2672   return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf);
2673 }
2674 
2675 
2676 //! ~(t1\@...\@tn) = (~t1)\@...\@(~tn) -- push negation through concat
2677 Theorem
negConcat(const Expr & e)2678 BitvectorTheoremProducer::negConcat(const Expr& e) {
2679   if(CHECK_PROOFS) {
2680     // The kids must be constant expressions
2681     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
2682 		"BitvectorTheoremProducer::negConcat: e = "+e.toString());
2683     CHECK_SOUND(e[0].getOpKind() == CONCAT,
2684 		"BitvectorTheoremProducer::negConcat: e = "+e.toString());
2685   }
2686 
2687   const Expr& e0 = e[0];
2688 
2689   vector<Expr> kids;
2690   for(Expr::iterator i=e0.begin(), iend=e0.end(); i!=iend; ++i)
2691     kids.push_back(d_theoryBitvector->newBVNegExpr(*i));
2692 
2693   Expr res = d_theoryBitvector->newConcatExpr(kids);
2694 
2695   Proof pf;
2696   if(withProof())
2697     pf = newPf("bitneg_concat", e);
2698   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2699 }
2700 
2701 //! ~(~t) = t  -- eliminate double negation
2702 Theorem
negNeg(const Expr & e)2703 BitvectorTheoremProducer::negNeg(const Expr& e) {
2704   if(CHECK_PROOFS) {
2705     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
2706 		"BitvectorTheoremProducer::negNeg: e = "+e.toString());
2707     CHECK_SOUND(e[0].getOpKind() == BVNEG && e[0].arity() == 1,
2708 		"BitvectorTheoremProducer::negNeg: e = "+e.toString());
2709   }
2710 
2711   Proof pf;
2712   if(withProof())
2713     pf = newPf("bitneg_neg", e);
2714   return newRWTheorem(e, e[0][0], Assumptions::emptyAssump(), pf);
2715 }
2716 
2717 
2718 //! ~t = -1*t + 1 -- eliminate negation
negElim(const Expr & e)2719 Theorem BitvectorTheoremProducer::negElim(const Expr& e)
2720 {
2721   if(CHECK_PROOFS) {
2722     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
2723 		"BitvectorTheoremProducer::negNeg: e = "+e.toString());
2724   }
2725 
2726   int bv_size =  d_theoryBitvector->BVSize(e[0]);
2727   Rational modulus = pow(Rational(bv_size), Rational(2));
2728   Expr minus_one = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size);
2729 
2730   vector<Expr> bvplusTerms;
2731   bvplusTerms.push_back(minus_one);
2732   bvplusTerms.push_back(d_theoryBitvector->newBVMultExpr(bv_size, minus_one, e[0]));
2733   Expr res = d_theoryBitvector->newBVPlusExpr(bv_size, bvplusTerms);
2734 
2735   Proof pf;
2736   if(withProof())
2737     pf = newPf("bitneg_elim", e);
2738   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2739 }
2740 
2741 
2742 //! ~(t1 & t2) = ~t1 | ~t2  -- DeMorgan's Laws
2743 Theorem
negBVand(const Expr & e)2744 BitvectorTheoremProducer::negBVand(const Expr& e) {
2745   if(CHECK_PROOFS) {
2746     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
2747 		"BitvectorTheoremProducer::negBVand: e = "+e.toString());
2748     CHECK_SOUND(e[0].getOpKind() == BVAND,
2749 		"BitvectorTheoremProducer::negBVand: e = "+e.toString());
2750   }
2751   Expr output;
2752   std::vector<Expr> negated;
2753   for(Expr::iterator i = e[0].begin(),iend=e[0].end();i!=iend;++i)
2754     negated.push_back(d_theoryBitvector->newBVNegExpr(*i));
2755   output = d_theoryBitvector->newBVOrExpr(negated);
2756 
2757   Proof pf;
2758   if(withProof())
2759     pf = newPf("bitneg_and", e);
2760   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2761 }
2762 
2763 
2764 //! ~(t1 | t2) = ~t1 & ~t2  -- DeMorgan's Laws
2765 Theorem
negBVor(const Expr & e)2766 BitvectorTheoremProducer::negBVor(const Expr& e) {
2767   if(CHECK_PROOFS) {
2768     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1,
2769 		"BitvectorTheoremProducer::negBVor: e = "+e.toString());
2770     CHECK_SOUND(e[0].getOpKind() == BVOR,
2771 		"BitvectorTheoremProducer::negBVor: e = "+e.toString());
2772   }
2773 
2774   Expr output;
2775   std::vector<Expr> negated;
2776   for(Expr::iterator i = e[0].begin(),iend=e[0].end();i!=iend;++i)
2777     negated.push_back(d_theoryBitvector->newBVNegExpr(*i));
2778   output = d_theoryBitvector->newBVAndExpr(negated);
2779 
2780   Proof pf;
2781   if(withProof())
2782     pf = newPf("bitneg_or", e);
2783   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2784 }
2785 
2786 
2787 //! ~(t1 xor t2) = ~t1 xor t2
2788 Theorem
negBVxor(const Expr & e)2789 BitvectorTheoremProducer::negBVxor(const Expr& e) {
2790   if(CHECK_PROOFS) {
2791     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1 && e[0].arity() > 0,
2792 		"BitvectorTheoremProducer::negBVxor: e = "+e.toString());
2793     CHECK_SOUND(e[0].getOpKind() == BVXOR,
2794 		"BitvectorTheoremProducer::negBVxor: e = "+e.toString());
2795   }
2796 
2797   Expr output;
2798   std::vector<Expr> children;
2799   Expr::iterator i = e[0].begin(), iend = e[0].end();
2800   children.push_back(d_theoryBitvector->newBVNegExpr(*i));
2801   ++i;
2802   for(; i!=iend; ++i)
2803     children.push_back(*i);
2804   output = d_theoryBitvector->newBVXorExpr(children);
2805 
2806   Proof pf;
2807   if(withProof())
2808     pf = newPf("bitneg_xor", e);
2809   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2810 }
2811 
2812 
2813 //! ~(t1 xnor t2) = t1 xor t2
2814 Theorem
negBVxnor(const Expr & e)2815 BitvectorTheoremProducer::negBVxnor(const Expr& e) {
2816   if(CHECK_PROOFS) {
2817     CHECK_SOUND(e.getOpKind() == BVNEG && e.arity() == 1 && e[0].arity() > 0,
2818 		"BitvectorTheoremProducer::negBVxor: e = "+e.toString());
2819     CHECK_SOUND(e[0].getOpKind() == BVXNOR,
2820 		"BitvectorTheoremProducer::negBVxor: e = "+e.toString());
2821   }
2822 
2823   Expr t2 = e[0][1];
2824   if (e[0].arity() > 2) {
2825     std::vector<Expr> children;
2826     Expr::iterator i = e[0].begin(), iend = e[0].end();
2827     ++i;
2828     for(; i!=iend; ++i)
2829       children.push_back(*i);
2830     t2 = d_theoryBitvector->newBVXnorExpr(children);
2831   }
2832   Expr output = d_theoryBitvector->newBVXorExpr(e[0][0], t2);
2833 
2834   Proof pf;
2835   if(withProof())
2836     pf = newPf("bitneg_xnor", e);
2837   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
2838 }
2839 
2840 
2841 //! c1 op c2 = c  -- bit-wise AND, OR, XOR of constant bitvectors
bitwiseConst(const Expr & e,const vector<int> & idxs,int kind)2842 Theorem BitvectorTheoremProducer::bitwiseConst(const Expr& e,
2843 					       const vector<int>& idxs,
2844 					       int kind)
2845 {
2846   if(CHECK_PROOFS) {
2847     // The kids must be constant expressions
2848     CHECK_SOUND(e.getOpKind() == kind,
2849 		"BitvectorTheoremProducer::bitwiseConst: e = "+e.toString());
2850     CHECK_SOUND(e.getOpKind() == BVAND ||
2851                 e.getOpKind() == BVOR ||
2852                 e.getOpKind() == BVXOR, "Expected AND, OR, or XOR");
2853     CHECK_SOUND(idxs.size() >= 2, "BitvectorTheoremProducer::bitwiseConst():\n e = "
2854                 +e.toString());
2855     for(size_t i=0; i<idxs.size(); ++i) {
2856       CHECK_SOUND(idxs[i] < e.arity(),
2857 		  "BitvectorTheoremProducer::bitwiseConst: idxs["
2858 		  +int2string(i)+"]="+int2string(idxs[i])
2859 		  +", e.arity() = "+int2string(e.arity())
2860 		  +"\n e = "+e.toString());
2861       CHECK_SOUND(e[idxs[i]].getKind() == BVCONST,
2862 		  "BitvectorTheoremProducer::bitwiseConst: e = "+e.toString());
2863     }
2864   }
2865   // Initialize 'bits' with all 1's or 0's, depending on kind
2866   vector<bool> bits;
2867   int size = d_theoryBitvector->BVSize(e);
2868   for(int bit=0; bit<size; bit++) {
2869     bits.push_back(kind == BVAND);
2870   }
2871 
2872   vector<Expr> kids(1); // Reserve the first element for the constant bitvector
2873   size_t ii(0); // The next index of idxs to match
2874   int idx(idxs[0]); // The index of the next constant (for efficiency)
2875   for(int i=0, iend=e.arity(); i<iend; ++i) {
2876     const Expr& ei = e[i];
2877     if(i == idx) {
2878       if(CHECK_PROOFS) {
2879 	CHECK_SOUND(ei.getKind() == BVCONST,
2880 		    "BitvectorTheoremProducer::bitwiseConst: e["
2881 		    +int2string(i)+"] = "+ei.toString());
2882 	CHECK_SOUND(d_theoryBitvector->getBVConstSize(ei) == (unsigned)size,
2883 		    "BitvectorTheoremProducer::bitwiseConst: e["
2884 		    +int2string(i)+"] = "+ei.toString());
2885       }
2886       // Incorporate the constant bitvector
2887       for(int bit=0; bit<size; bit++)
2888 	bits[bit] =
2889           kind == BVAND ? (bits[bit] && d_theoryBitvector->getBVConstValue(ei, bit)) :
2890 	  kind == BVOR ? (bits[bit] || d_theoryBitvector->getBVConstValue(ei, bit)) :
2891           bits[bit] != d_theoryBitvector->getBVConstValue(ei, bit);
2892       // Advance the index of idxs
2893       if (ii < idxs.size() - 1)
2894 	idx = idxs[++ii];
2895       else
2896 	idx = e.arity();
2897     }
2898     else // Not a constant, add to the list of kids
2899       kids.push_back(ei);
2900   }
2901   // Create the new constant bitvector and make it the first kid
2902   kids[0] = d_theoryBitvector->newBVConstExpr(bits);
2903   // Contruct the final expression.
2904   Expr res = (kids.size() == 1) ? kids[0] :
2905     kind == BVAND ? d_theoryBitvector->newBVAndExpr(kids) :
2906     kind == BVOR ? d_theoryBitvector->newBVOrExpr(kids) :
2907     d_theoryBitvector->newBVXorExpr(kids);
2908 
2909   Proof pf;
2910   if(withProof()) {
2911     // Construct a list of indices as a RAW_LIST Expr
2912     vector<Expr> indices;
2913     for(size_t i=0, iend=idxs.size(); i<iend; ++i)
2914       indices.push_back(rat(idxs[i]));
2915     pf = newPf("bitwise_const", e, Expr(RAW_LIST, indices));
2916   }
2917   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2918 }
2919 
2920 
2921 //! Lifts concatenation above bitwise operators.
bitwiseConcat(const Expr & e,int kind)2922 Theorem BitvectorTheoremProducer::bitwiseConcat(const Expr& e, int kind)
2923 {
2924   if(CHECK_PROOFS) {
2925     CHECK_SOUND(e.getOpKind() == kind,
2926 		"BitvectorTheoremProducer::bitwiseConcat: e = "+e.toString());
2927   }
2928 
2929   int arity = e.arity();
2930   int idx;
2931   for (idx = 0; idx < arity; ++idx) {
2932     if (e[idx].getOpKind() == CONCAT) break;
2933   }
2934   if (idx == arity)
2935     return d_theoryBitvector->reflexivityRule(e);
2936 
2937   const Expr& ei = e[idx];
2938 
2939   // Build the top-level concatenation
2940   vector<Expr> concatKids;
2941   // Current extraction window
2942   int hi=d_theoryBitvector->BVSize(e)-1;
2943   int low=hi-d_theoryBitvector->BVSize(ei[0])+1;
2944 
2945   for(int i=0, iend=ei.arity(); i<iend; ++i) {
2946     // Kids of the current BVAND / BVOR
2947     vector<Expr> kids;
2948     for(int j=0; j<arity; ++j) {
2949       if(j==idx)
2950 	kids.push_back(ei[i]);
2951       else
2952 	kids.push_back(d_theoryBitvector->newBVExtractExpr(e[j], hi, low));
2953     }
2954     concatKids.push_back(Expr(kind, kids));
2955     if(i+1<iend) {
2956       int newHi = low-1;
2957       low = low - d_theoryBitvector->BVSize(ei[i+1]);
2958       hi = newHi;
2959     }
2960   }
2961   Expr res = d_theoryBitvector->newConcatExpr(concatKids);
2962   Proof pf;
2963   if(withProof())
2964     pf = newPf("bitwise_concat", e, rat(idx));
2965   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2966 }
2967 
2968 
2969 //! Flatten bitwise operation
bitwiseFlatten(const Expr & e,int kind)2970 Theorem BitvectorTheoremProducer::bitwiseFlatten(const Expr& e, int kind)
2971 {
2972   if(CHECK_PROOFS) {
2973     CHECK_SOUND(e.getOpKind() == kind && e.arity()>=2,
2974 		"BitvectorTheoremProducer::bitwiseFlatten: e = "+e.toString());
2975     CHECK_SOUND(e.getOpKind() == BVAND ||
2976                 e.getOpKind() == BVOR ||
2977                 e.getOpKind() == BVXOR, "Expected AND, OR, or XOR");
2978   }
2979   int bvLength = d_theoryBitvector->BVSize(e);
2980 
2981   // flatten the nested ops
2982   vector<Expr> flattenkids;
2983   for(Expr::iterator i = e.begin(),iend=e.end();i!=iend; ++i) {
2984     if(i->getOpKind() == kind)
2985       flattenkids.insert(flattenkids.end(),
2986 			 i->getKids().begin(),i->getKids().end());
2987     else
2988       flattenkids.push_back(*i);
2989   }
2990 
2991   // drop duplicate subterms and detect conflicts like t, ~t
2992   Expr output;
2993   int flag;
2994   ExprMap<int> likeTerms;
2995   vector<Expr>::iterator j = flattenkids.begin();
2996   vector<Expr>::iterator jend = flattenkids.end();
2997   bool negate = false;
2998 
2999   for(; output.isNull() && j != flattenkids.end(); ++j) {
3000     Expr t = *j;
3001     if (kind == BVXOR && t.getOpKind() == BVNEG) {
3002       negate = !negate;
3003       t = t[0];
3004     }
3005     //check if *j is duplicated or its negation already occured
3006     flag = sameKidCheck(t, likeTerms);
3007     switch(flag) {
3008       case 0:
3009         //no duplicates
3010         break;
3011       case 1:
3012         //duplicate detected. ignore the duplicate for BVAND, BVOR
3013         if (kind == BVXOR) {
3014           // remove both for BVXOR
3015           likeTerms.erase(t);
3016         }
3017         break;
3018       case -1:
3019         //conflict detected
3020         if (kind == BVAND)
3021           output = d_theoryBitvector->newBVZeroString(bvLength);
3022         else if (kind == BVOR)
3023           output = d_theoryBitvector->newBVOneString(bvLength);
3024         else {
3025           DebugAssert(false, "Shouldn't be possible");
3026         }
3027         break;
3028       default:
3029         DebugAssert(false,
3030                     "control should not reach here");
3031         break;
3032     }
3033   }
3034 
3035   if (output.isNull()) {
3036     vector<Expr> outputkids;
3037     ExprMap<int>::iterator it = likeTerms.begin();
3038     for(; it != likeTerms.end(); ++it) {
3039       outputkids.push_back((*it).first);
3040     }
3041     if(CHECK_PROOFS) {
3042       CHECK_SOUND(kind == BVXOR || outputkids.size() > 0,
3043 		  "TheoryBitvector:bitwiseFlatten: fatal error");
3044     }
3045     if (outputkids.size() == 0) {
3046       outputkids.push_back(d_theoryBitvector->newBVZeroString(bvLength));
3047     }
3048     if (negate) {
3049       outputkids[0] = d_theoryBitvector->newBVNegExpr(outputkids[0]);
3050     }
3051     if (outputkids.size() == 1) {
3052       output = outputkids[0];
3053     }
3054     else {
3055       output = Expr(kind, outputkids);
3056     }
3057   }
3058 
3059   Proof pf;
3060   if(withProof())
3061     pf = newPf("bitwise_flatten", e);
3062   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
3063 }
3064 
3065 
3066 // Rewrite bitwise operation with constant using concatenation,
3067 // negation, and extraction
bitwiseConstElim(const Expr & e,int idx,int kind)3068 Theorem BitvectorTheoremProducer::bitwiseConstElim(const Expr& e,
3069                                                    int idx, int kind)
3070 {
3071   if(CHECK_PROOFS) {
3072     CHECK_SOUND(e.getOpKind() == kind,
3073 		"BitvectorTheoremProducer::bitwiseConstElim: e = "+e.toString());
3074     CHECK_SOUND(e.getOpKind() == BVAND ||
3075                 e.getOpKind() == BVOR ||
3076                 e.getOpKind() == BVXOR, "Expected AND, OR, or XOR");
3077     CHECK_SOUND(idx < e.arity() && e.arity() > 1,
3078 		"BitvectorTheoremProducer::bitwiseConstElim: e = "+e.toString()
3079 		+"\n idx = "+int2string(idx)
3080 		+"\n e.arity() = "+int2string(e.arity()));
3081     CHECK_SOUND(e[idx].getOpKind() == BVCONST,
3082 		"BitvectorTheoremProducer::bitwiseConstElim: e["+int2string(idx)
3083 		+"] = "+e[idx].toString());
3084   }
3085 
3086   int bvLength = d_theoryBitvector->BVSize(e);
3087   Expr output;
3088   vector<Expr> kids;
3089   for (int i = 0; i < e.arity(); ++i) {
3090     if (i == idx) continue;
3091     kids.push_back(e[i]);
3092   }
3093   if (kids.size() == 1) output = kids[0];
3094   else output = Expr(kind, kids);
3095 
3096   const Expr& c = e[idx];
3097   int i=d_theoryBitvector->getBVConstSize(c)-1;
3098   bool curVal = d_theoryBitvector->getBVConstValue(c, i);
3099   int hi = bvLength-1;
3100   Expr term;
3101   vector<Expr> concatTerms;
3102 
3103   for(--i; i >= 0; --i) {
3104     if (d_theoryBitvector->getBVConstValue(c,i) != curVal) {
3105       if (kind == BVAND && curVal == false) {
3106         term = d_theoryBitvector->newBVZeroString(hi-i);
3107       }
3108       else if (kind == BVOR && curVal == true) {
3109         term = d_theoryBitvector->newBVOneString(hi-i);
3110       }
3111       else {
3112         term = d_theoryBitvector->newBVExtractExpr(output, hi, i+1);
3113         if (kind == BVXOR && curVal == true) {
3114           term = d_theoryBitvector->newBVNegExpr(term);
3115         }
3116       }
3117       concatTerms.push_back(term);
3118       curVal = !curVal;
3119       hi = i;
3120     }
3121   }
3122 
3123   if (kind == BVAND && curVal == false) {
3124     term = d_theoryBitvector->newBVZeroString(hi+1);
3125   }
3126   else if (kind == BVOR && curVal == true) {
3127     term = d_theoryBitvector->newBVOneString(hi+1);
3128   }
3129   else {
3130     if (hi < bvLength-1) {
3131       term = d_theoryBitvector->newBVExtractExpr(output, hi, 0);
3132     }
3133     else term = output;
3134     if (kind == BVXOR && curVal == true) {
3135       term = d_theoryBitvector->newBVNegExpr(term);
3136     }
3137   }
3138   concatTerms.push_back(term);
3139   if (concatTerms.size() == 1) {
3140     output = concatTerms[0];
3141   }
3142   else {
3143     output = d_theoryBitvector->newConcatExpr(concatTerms);
3144   }
3145 
3146   Proof pf;
3147   if(withProof())
3148     pf = newPf("bitwise_zero", e, rat(idx));
3149   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
3150 }
3151 
3152 
3153 /*! checks if e is already present in likeTerms without conflicts.
3154  *  if yes return 1, else{ if conflict return -1 else return 0 }
3155  *  we have conflict if
3156  *          1. the kind of e is BVNEG,
3157  *                 and e[0] is already present in likeTerms
3158  *          2. ~e is present in likeTerms already
3159  */
sameKidCheck(const Expr & e,ExprMap<int> & likeTerms)3160 int BitvectorTheoremProducer::sameKidCheck(const Expr&  e,
3161 					   ExprMap<int>& likeTerms) {
3162   //initially flag = 0, i.e. we assume e is not in likeTerms
3163   int flag = 0;
3164 
3165   //look for e
3166   ExprMap<int>::iterator it = likeTerms.find(e);
3167 
3168   //no entry found for e
3169   if(it==likeTerms.end()) {
3170     switch(e.getOpKind()) {
3171      case BVNEG: {
3172        ExprMap<int>::iterator it0 = likeTerms.find(e[0]);
3173        if(it0!=likeTerms.end())
3174 	 flag = -1;
3175        break;
3176      }
3177      default: {
3178        Expr bvNeg = d_theoryBitvector->newBVNegExpr(e);
3179        ExprMap<int>::iterator negIt = likeTerms.find(bvNeg);
3180        if(negIt!=likeTerms.end())
3181 	 flag=-1;
3182        break;
3183      }
3184     }
3185     if (flag == 0) likeTerms[e] = 1;
3186     return flag;
3187   }
3188 
3189   //found an entry for e
3190   return 1;
3191 }
3192 
3193 
3194 //! c1\@c2\@...\@cn = c  (concatenation of constant bitvectors)
concatConst(const Expr & e)3195 Theorem BitvectorTheoremProducer::concatConst(const Expr& e) {
3196   if(CHECK_PROOFS) {
3197     // The kids must be constant expressions
3198     CHECK_SOUND(e.getOpKind() == CONCAT,
3199 		"BitvectorTheoremProducer::concatConst: e = "+e.toString());
3200     CHECK_SOUND(constantKids(e),
3201 		"BitvectorTheoremProducer::concatConst: e = "+e.toString());
3202   }
3203   vector<bool> res;
3204   for(int i=e.arity()-1; i >= 0; --i) {
3205     for(int bit=0, size=d_theoryBitvector->getBVConstSize(e[i]); bit < size; bit++)
3206       res.push_back(d_theoryBitvector->getBVConstValue(e[i], bit));
3207   }
3208   Proof pf;
3209   if(withProof())
3210     pf = newPf("concat_const", e);
3211   return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf);
3212 }
3213 
3214 
3215 //! Flatten one level of nested concatenation, e.g.: x\@(y\@z)\@w = x\@y\@z\@w
3216 Theorem
concatFlatten(const Expr & e)3217 BitvectorTheoremProducer::concatFlatten(const Expr& e) {
3218   if(CHECK_PROOFS) {
3219     CHECK_SOUND(e.getOpKind() == CONCAT && e.arity() >= 2,
3220 		"BitvectorTheoremProducer::concatFlatten: e = "+e.toString());
3221   }
3222   // Rebuild the expression: copy the kids and flatten the nested CONCATs
3223   vector<Expr> kids;
3224   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
3225     if(i->getOpKind() == CONCAT)
3226       kids.insert(kids.end(), i->getKids().begin(), i->getKids().end());
3227     else
3228       kids.push_back(*i);
3229   }
3230   Proof pf;
3231   if(withProof())
3232     pf = newPf("concat_flatten", e);
3233   return newRWTheorem(e, Expr(e.getOp(), kids), Assumptions::emptyAssump(), pf);
3234 }
3235 
3236 
3237 //! Merge n-ary concat. of adjacent extractions: x[15:8]\@x[7:0] = x[15:0]
3238 Theorem
concatMergeExtract(const Expr & e)3239 BitvectorTheoremProducer::concatMergeExtract(const Expr& e) {
3240   if(CHECK_PROOFS) {
3241     CHECK_SOUND(e.getOpKind() == CONCAT && e.arity() >= 2,
3242 		"BitvectorTheoremProducer::concatMergeExtract: e = "
3243 		+e.toString());
3244     CHECK_SOUND(e[0].getOpKind() == EXTRACT,
3245 		"BitvectorTheoremProducer::concatMergeExtract: e = "
3246 		+e.toString());
3247     CHECK_SOUND(d_theoryBitvector->getExtractHi(e[0]) >= d_theoryBitvector->getExtractLow(e[0]),
3248 		"BitvectorTheoremProducer::concatMergeExtract: e = "
3249 		+e.toString());
3250   }
3251 
3252   const Expr& base = e[0][0]; // The common base of all extractions
3253 
3254   if(CHECK_PROOFS) {
3255     // Check that all extractions have the same base and are contiguous
3256     int low = d_theoryBitvector->getExtractLow(e[0]);
3257     for(int i=1, iend=e.arity(); i<iend; ++i) {
3258       const Expr& ei = e[i];
3259       CHECK_SOUND(ei.getOpKind() == EXTRACT && ei[0] == base,
3260 		  "BitvectorTheoremProducer::concatMergeExtract: e["
3261 		  +int2string(i)+"] = "+ei.toString()
3262 		  +"\n base = "+base.toString());
3263       CHECK_SOUND(d_theoryBitvector->getExtractHi(ei) >= d_theoryBitvector->getExtractLow(ei),
3264 		  "BitvectorTheoremProducer::concatMergeExtract: e["
3265 		  +int2string(i)+"] = "+e.toString());
3266 
3267       int newHi = d_theoryBitvector->getExtractHi(ei);
3268 
3269       CHECK_SOUND(0 <= newHi && newHi == low-1,
3270 		  "BitvectorTheoremProducer::concatMergeExtract:\n e["
3271 		  +int2string(i-1)+"] = "+e[i-1].toString()
3272 		  +"\n e["+int2string(i)+"] = "+ei.toString());
3273       low = d_theoryBitvector->getExtractLow(ei);
3274     }
3275   }
3276 
3277   int hi = d_theoryBitvector->getExtractHi(e[0]);
3278   int low = d_theoryBitvector->getExtractLow(e[e.arity()-1]);
3279   Expr res = d_theoryBitvector->newBVExtractExpr(base, hi, low);
3280 
3281   Proof pf;
3282   if(withProof())
3283     pf = newPf("concat_merge_extract", e);
3284   return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
3285 }
3286 
3287 
3288 
3289 //! BVPLUS(n, c1,c2,...,cn) = c  (bit-vector plus of constant bitvectors)
bvplusConst(const Expr & e)3290 Theorem BitvectorTheoremProducer::bvplusConst(const Expr& e) {
3291   if(CHECK_PROOFS) {
3292     // The kids must be constant expressions
3293     CHECK_SOUND(e.getOpKind() == BVPLUS,
3294 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
3295     CHECK_SOUND(constantKids(e),
3296 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
3297     CHECK_SOUND(d_theoryBitvector->getBVPlusParam(e) > 0,
3298 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
3299   }
3300   // Transfer the values for each bitvector to a Rational, then add it
3301   // to the accumulator.
3302   Rational acc(0);
3303   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
3304     Rational x = d_theoryBitvector->computeBVConst(*i);
3305     TRACE("bitvector rewrite", "bvplusConst: x(", *i, ") = "+x.toString());
3306     acc += x;
3307     TRACE("bitvector rewrite", "bvplusConst: acc = ", acc, "");
3308   }
3309   // Extract the bits of 'acc' into the vector
3310   int resSize = d_theoryBitvector->getBVPlusParam(e);
3311   vector<bool> res(resSize);
3312   for(int i=0; i<resSize; i++) {
3313     res[i] = (mod(acc, 2) == 1);
3314     TRACE("bitvector rewrite", "bvplusConst: acc = ", acc, "");
3315     TRACE("bitvector rewrite", "bvplusConst: res["+int2string(i)+"] = ",
3316 	  res[i], "");
3317     acc = floor(acc/2);
3318   }
3319 
3320   Proof pf;
3321   if(withProof())
3322     pf = newPf("bvplus_const", e);
3323   return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf);
3324 }
3325 
3326 
3327 /*! @brief c0*c1 = c, multiplication of two BVCONST
3328  */
bvmultConst(const Expr & e)3329 Theorem BitvectorTheoremProducer::bvmultConst(const Expr& e) {
3330   if(CHECK_PROOFS) {
3331     // The kids must be constant expressions
3332     CHECK_SOUND(e.getOpKind() == BVMULT,
3333 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
3334     CHECK_SOUND(constantKids(e),
3335 		"BitvectorTheoremProducer::extractConst: e = "+e.toString());
3336   }
3337   Rational c = d_theoryBitvector->computeBVConst(e[0]);
3338   // Do the multiplication
3339   Rational x = d_theoryBitvector->computeBVConst(e[1]) * c;
3340 
3341   // Extract the bits of 'x' into the vector
3342   int resSize = d_theoryBitvector->BVSize(e.getType().getExpr());
3343   vector<bool> res(resSize);
3344   for(int i=0; i<resSize; i++) {
3345     res[i] = (mod(x, 2) == 1);
3346     x = floor(x/2);
3347   }
3348 
3349   Proof pf;
3350   if(withProof())
3351     pf = newPf("bvmult_const", e);
3352   return newRWTheorem(e, d_theoryBitvector->newBVConstExpr(res), Assumptions::emptyAssump(), pf);
3353 }
3354 
3355 Theorem
zeroCoeffBVMult(const Expr & e)3356 BitvectorTheoremProducer::zeroCoeffBVMult(const Expr& e) {
3357   if(CHECK_PROOFS) {
3358     CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2,
3359 		"BitvectorTheoremProducer::zeroCoeffBVMult: e = "+e.toString());
3360     CHECK_SOUND(BVCONST == e[0].getKind(),
3361 		"BitvectorTheoremProducer::zeroCoeffBVMult: e = "+e.toString());
3362     Rational c = d_theoryBitvector->computeBVConst(e[0]);
3363     CHECK_SOUND(0 == c,
3364 		"BitvectorTheoremProducer::zeroCoeffBVMult:"
3365 		"coeff must be zero:\n e = " +e.toString());
3366   }
3367   int size = d_theoryBitvector->BVSize(e);
3368   Expr output = d_theoryBitvector->newBVZeroString(size);
3369 
3370   Proof pf;
3371   if(withProof())
3372     pf = newPf("zerocoeff_bvmult", e);
3373   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3374   return result;
3375 }
3376 
3377 Theorem
oneCoeffBVMult(const Expr & e)3378 BitvectorTheoremProducer::oneCoeffBVMult(const Expr& e) {
3379   if(CHECK_PROOFS) {
3380     CHECK_SOUND(e.getOpKind() == BVMULT && e.arity() == 2,
3381 		"BitvectorTheoremProducer::oneCoeffBVMult: e = "
3382 		+e.toString());
3383     CHECK_SOUND(BVCONST == e[0].getKind(),
3384 		"BitvectorTheoremProducer::oneCoeffBVMult: e = "
3385 		+e.toString());
3386     Rational c = d_theoryBitvector->computeBVConst(e[0]);
3387     CHECK_SOUND(1 == c,
3388 		"BitvectorTheoremProducer::oneCoeffBVMult:"
3389 		"coeff must be one:\n e = " +e.toString());
3390   }
3391   int size = d_theoryBitvector->BVSize(e);
3392   Expr output = pad(size,e);
3393 
3394   Proof pf;
3395   if(withProof())
3396     pf = newPf("onecoeff_bvmult", e);
3397   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3398   return result;
3399 }
3400 
3401 //! t1*a <==> a*t1
3402 Theorem
flipBVMult(const Expr & e)3403 BitvectorTheoremProducer::flipBVMult(const Expr& e) {
3404   if(CHECK_PROOFS) {
3405     CHECK_SOUND(e.arity()==2 && BVMULT == e.getOpKind(),
3406 		"BVMULT must have exactly 2 kids: " + e.toString());
3407   }
3408   int len = d_theoryBitvector->BVSize(e);
3409   Expr output = d_theoryBitvector->newBVMultExpr(len,e[1],e[0]);
3410 
3411   Proof pf;
3412   if(withProof())
3413     pf = newPf("flip_bvmult", e);
3414   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3415   return result;
3416 }
3417 
3418 //! Converts e into a BVVECTOR of bvLength 'len'
3419 /*!
3420  * \param len is the desired bvLength of the resulting bitvector
3421  * \param e is the original bitvector of arbitrary bvLength
3422  */
3423 Expr
pad(int len,const Expr & e)3424 BitvectorTheoremProducer::pad(int len, const Expr& e) {
3425   DebugAssert(len > 0,
3426 	      "TheoryBitvector::pad:"
3427 	      "padding bvLength must be a non-negative integer: "+
3428 	      int2string(len));
3429   DebugAssert(BITVECTOR == e.getType().getExpr().getOpKind(),
3430 	      "TheoryBitvector::newBVPlusExpr:"
3431 	      "input must be a BITVECTOR: " + e.toString());
3432 
3433   int size = d_theoryBitvector->BVSize(e);
3434   Expr res;
3435   if(size == len)
3436     res = e;
3437   else if (len < size)
3438     res = d_theoryBitvector->newBVExtractExpr(e,len-1,0);
3439   else {
3440     // size < len
3441     Expr zero = d_theoryBitvector->newBVZeroString(len-size);
3442     res = d_theoryBitvector->newConcatExpr(zero,e);
3443   }
3444   return res;
3445 }
3446 
3447 //! Pad the kids of BVMULT to make their bvLength = # of output-bits
3448 Theorem
padBVPlus(const Expr & e)3449 BitvectorTheoremProducer::padBVPlus(const Expr& e) {
3450   if(CHECK_PROOFS) {
3451     CHECK_SOUND(BVPLUS == e.getOpKind() && e.arity()>1,
3452 		"BitvectorTheoremProducer::padBVPlus: "
3453 		"input must be a BVPLUS: " + e.toString());
3454   }
3455   int len = d_theoryBitvector->BVSize(e);
3456   vector<Expr> kids;
3457   for(Expr::iterator i=e.begin(), iend=e.end(); i!=iend; ++i) {
3458     if(i->getOpKind() == BVMULT) {
3459       Expr e0 = pad(len, (*i)[0]);
3460       Expr e1 = pad(len, (*i)[1]);
3461       Expr out = d_theoryBitvector->newBVMultExpr(len,e0,e1);
3462       kids.push_back(out);
3463     }
3464     else
3465       kids.push_back(pad(len, *i));
3466   }
3467 
3468   Expr output = d_theoryBitvector->newBVPlusExpr(len, kids);
3469 
3470   Proof pf;
3471   if(withProof())
3472     pf = newPf("pad_bvplus", e);
3473   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3474   return result;
3475 }
3476 
3477 //! Pad the kids of BVMULT to make their bvLength = # of output-bits
3478 Theorem
padBVMult(const Expr & e)3479 BitvectorTheoremProducer::padBVMult(const Expr& e) {
3480   if(CHECK_PROOFS) {
3481     CHECK_SOUND(BVMULT == e.getOpKind() && e.arity()==2,
3482 		"BitvectorTheoremProducer::padBVMult: "
3483 		"input must be a BVMULT: " + e.toString());
3484     CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind() &&
3485 		BITVECTOR==e[1].getType().getExpr().getOpKind(),
3486 		"for BVMULT terms e[0],e[1] must be a BV: " + e.toString());
3487   }
3488   int len = d_theoryBitvector->BVSize(e);
3489   Expr e0 = pad(len, e[0]);
3490   Expr e1 = pad(len, e[1]);
3491 
3492   Expr output = d_theoryBitvector->newBVMultExpr(len,e0,e1);
3493 
3494   Proof pf;
3495   if(withProof())
3496     pf = newPf("pad_bvmult", e);
3497   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3498   return result;
3499 }
3500 
3501 //! a*(b*t) <==> (a*b)*t, where a,b,t have same bvLength
3502 Theorem
bvConstMultAssocRule(const Expr & e)3503 BitvectorTheoremProducer::bvConstMultAssocRule(const Expr& e) {
3504   if(CHECK_PROOFS) {
3505     CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2,
3506 		"BitvectorTheoremProducer::bvConstMultAssocRule: "
3507 		"input must be a BVMULT: " + e.toString());
3508     CHECK_SOUND(BVMULT == e[1].getOpKind(),
3509 		"BitvectorTheoremProducer::bvConstMultAssocRule: "
3510 		"e[1] must be a BVMULT:\n e= " + e.toString());
3511     CHECK_SOUND(BVCONST == e[0].getKind() &&
3512 		BVCONST == e[1][0].getKind(),
3513 		"BitvectorTheoremProducer::bvConstMultAssocRule: "
3514 		"e[0] & e[1][0] must be a BVCONST:\n e = " + e.toString());
3515   }
3516   int len = d_theoryBitvector->BVSize(e);
3517   int len0 = d_theoryBitvector->BVSize(e[0]);
3518   int len10 = d_theoryBitvector->BVSize(e[1][0]);
3519   int len11 = d_theoryBitvector->BVSize(e[1][1]);
3520   if(CHECK_PROOFS) {
3521     CHECK_SOUND(len == len0 && len0 == len10 && len0 == len11,
3522 		"BitvectorTheoremProducer::bvConstMultAssocRule: "
3523 		"kids of BVMULT must be equibvLength: ");
3524   }
3525   Rational e0 = d_theoryBitvector->computeBVConst(e[0]);
3526   Rational e10 = d_theoryBitvector->computeBVConst(e[1][0]);
3527   Expr c = d_theoryBitvector->newBVConstExpr(e0*e10, len);
3528   Expr output = d_theoryBitvector->newBVMultExpr(len, c, e[1][1]);
3529 
3530   Proof pf;
3531   if(withProof())
3532     pf = newPf("bvconstmult_assoc_rule", e);
3533   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3534   return result;
3535 }
3536 
3537 
3538 //FIXME: make BVMULT n-ary
3539 //! (t1*t2)*t3 <==> t1*(t2*t3), where t1<t2<t3
3540 Theorem
bvMultAssocRule(const Expr & e)3541 BitvectorTheoremProducer::bvMultAssocRule(const Expr& e) {
3542   if(CHECK_PROOFS) {
3543     CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2,
3544 		"BitvectorTheoremProducer::bvMultAssocRule: "
3545 		"input must be a BVMULT: " + e.toString());
3546     CHECK_SOUND(BVMULT == e[0].getOpKind() ||
3547 		BVMULT == e[1].getOpKind(),
3548 		"BitvectorTheoremProducer::bvMultAssocRule: "
3549 		"e[0] or e[1] must be a BVMULT:\n e= " + e.toString());
3550     CHECK_SOUND(!(BVCONST == e[0].getOpKind() &&
3551 		  BVCONST == e[1][0].getOpKind()),
3552 		"BitvectorTheoremProducer::bvMultAssocRule: "
3553 		"e[0] & e[1][0] cannot be a BVCONST:\n e = " +
3554 		e.toString());
3555   }
3556   int len = d_theoryBitvector->BVSize(e);
3557   int len0 = d_theoryBitvector->BVSize(e[0]);
3558   int len1 = d_theoryBitvector->BVSize(e[1]);
3559   if(CHECK_PROOFS)
3560     CHECK_SOUND(len == len0 && len0 == len1,
3561 		"BitvectorTheoremProducer::bvMultAssocRule: "
3562 		"kids of BVMULT must be equibvLength: ");
3563   Expr e0, e1;
3564   e0 = e[0];
3565   e1 = e[1];
3566 
3567   std::vector<Expr> outputkids;
3568   if(BVMULT == e[0].getOpKind() && BVMULT != e[1].getOpKind()) {
3569     outputkids.push_back(e0[0]);
3570     outputkids.push_back(e0[1]);
3571     outputkids.push_back(e1);
3572 
3573   } else if(BVMULT != e[0].getOpKind() && BVMULT == e[1].getOpKind()) {
3574     outputkids.push_back(e1[0]);
3575     outputkids.push_back(e1[1]);
3576     outputkids.push_back(e0);
3577   } else {
3578     //both must be BVMULTs
3579     outputkids.push_back(e0[0]);
3580     outputkids.push_back(e0[1]);
3581     outputkids.push_back(e1[0]);
3582     outputkids.push_back(e1[1]);
3583   }
3584   sort(outputkids.begin(),outputkids.end());
3585 
3586   Expr output;
3587   switch(outputkids.size()) {
3588   case 3: {
3589     Expr out1 =
3590       d_theoryBitvector->newBVMultExpr(len, outputkids[1],outputkids[2]);
3591     output =
3592       d_theoryBitvector->newBVMultExpr(len, outputkids[0], out1);
3593     break;
3594   }
3595   case 4: {
3596     Expr out0 =
3597       d_theoryBitvector->newBVMultExpr(len, outputkids[0], outputkids[1]);
3598     Expr out1 =
3599       d_theoryBitvector->newBVMultExpr(len, outputkids[2], outputkids[3]);
3600     output =
3601       d_theoryBitvector->newBVMultExpr(len, out0, out1);
3602     break;
3603   }
3604   }
3605 
3606   Proof pf;
3607   if(withProof())
3608     pf = newPf("bvmult_assoc_rule", e);
3609   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3610   return result;
3611 }
3612 
3613 //! a*(t1+...+tn) <==> (a*t1+...+a*tn), where all kids are equibvLength
3614 Theorem
bvMultDistRule(const Expr & e)3615 BitvectorTheoremProducer::bvMultDistRule(const Expr& e) {
3616   if(CHECK_PROOFS) {
3617     CHECK_SOUND(BVMULT == e.getOpKind() && e.arity() == 2,
3618 		"BitvectorTheoremProducer::bvMultDistRule: "
3619 		"input must be a BVMULT: " + e.toString());
3620     CHECK_SOUND(BVPLUS == e[1].getOpKind(),
3621 		"BitvectorTheoremProducer::bvMultDistRule: "
3622 		"input must be of the form a*(t1+...+tn): " + e.toString());
3623   }
3624   int bvLength= d_theoryBitvector->BVSize(e);
3625   int e0len = d_theoryBitvector->BVSize(e[0]);
3626   int e1len = d_theoryBitvector->BVSize(e[1]);
3627   if(CHECK_PROOFS) {
3628     CHECK_SOUND(bvLength== e0len && e0len == e1len,
3629 		"BitvectorTheoremProducer::bvMultDistRule: "
3630 		"all subterms must of equal bvLength: " + e.toString());
3631   }
3632   const Expr& e0 = e[0];
3633   const Expr& e1 = e[1];
3634 
3635   std::vector<Expr> v;
3636   Expr::iterator i = e1.begin();
3637   Expr::iterator iend = e1.end();
3638   for(;i != iend; ++i) {
3639     Expr s = d_theoryBitvector->newBVMultExpr(bvLength, e0, *i);
3640     v.push_back(s);
3641   }
3642   Expr output = d_theoryBitvector->newBVPlusExpr(bvLength,v);
3643 
3644   Proof pf;
3645   if(withProof())
3646     pf = newPf("bvmult_distributivity_rule", e);
3647   Theorem result(newRWTheorem(e,output,Assumptions::emptyAssump(),pf));
3648   return result;
3649 }
3650 
3651 //! input BVPLUS expression e.output e <==> e', where e' has no BVPLUS
3652 //  kids. remember, the invariant is that kids are already in
3653 //  bvplus normal-form
3654 Theorem
flattenBVPlus(const Expr & e)3655 BitvectorTheoremProducer::flattenBVPlus(const Expr& e) {
3656   if(CHECK_PROOFS) {
3657     CHECK_SOUND(e.getOpKind() == BVPLUS && e.arity() >= 2,
3658 		"BitvectorTheoremProducer::flattenBVPlus: e = "+e.toString());
3659   }
3660   int bvLength= d_theoryBitvector->BVSize(e);
3661   const int numOfKids = e.arity();
3662 
3663   if(CHECK_PROOFS) {
3664     for(int i=0; i<numOfKids; ++i)
3665       CHECK_SOUND(d_theoryBitvector->BVSize(e[i]) == bvLength,
3666 		  "BitvectorTheoremProducer::flattenBVPlus: "
3667 		  "summands must be of the same bvLength as BVPLUS:\n e = "
3668 		  +e.toString());
3669   }
3670 
3671   //collect the kids of e in the vector v. if any kid is a BVPLUS,
3672   //then collect its kids into v. then construct a BVPLUS expr
3673   std::vector<Expr> v;
3674   for(int i = 0; i < numOfKids; ++i) {
3675     if(e[i].getOpKind() == BVPLUS) {
3676       const Expr& bvplusKid = e[i];
3677       const int bvplusArity = bvplusKid.arity();
3678       for(int j=0; j < bvplusArity; ++j)
3679 	v.push_back(bvplusKid[j]);
3680     } else
3681       v.push_back(e[i]);
3682   }
3683   Expr eprime = d_theoryBitvector->newBVPlusExpr(bvLength, v);
3684 
3685   Proof pf;
3686   if(withProof())
3687     pf = newPf("flatten_bvplus", e);
3688   return newRWTheorem(e, eprime, Assumptions::emptyAssump(), pf);
3689 }
3690 
3691 void
collectOneTermOfPlus(const Rational & coefficient,const Expr & term,ExprMap<Rational> & likeTerms,Rational & plusConstant)3692 BitvectorTheoremProducer::collectOneTermOfPlus(const Rational & coefficient,
3693 					       const Expr& term,
3694 					       ExprMap<Rational> & likeTerms,
3695 					       Rational & plusConstant)
3696 {
3697   ExprMap<Rational>::iterator it = likeTerms.find(term);
3698 
3699   if(it!=likeTerms.end())
3700     likeTerms[term] += coefficient;
3701   else {
3702     // Check if there is a negated form of this term already in likeTerms map.
3703     bool foundNegated= false;
3704     if (!likeTerms.empty()) {
3705       Expr negTerm = d_theoryBitvector->newBVNegExpr(term);
3706       negTerm = d_theoryBitvector->pushNegationRec(term).getRHS();
3707       it = likeTerms.find(negTerm);
3708       if (it!= likeTerms.end()) {
3709 	foundNegated = true;
3710 
3711 	// Use the rule that ~(c*x) = -c*x-1 (based on the fact: -x= ~x+1).
3712 	likeTerms[negTerm] += -coefficient;
3713 	plusConstant+= -1;
3714       }
3715     }
3716     if (!foundNegated)
3717       // Negated form was not found, need to register the new positive form.
3718       likeTerms[term] = coefficient;
3719   }
3720 }
3721 
3722 void
collectLikeTermsOfPlus(const Expr & e,ExprMap<Rational> & likeTerms,Rational & plusConstant)3723 BitvectorTheoremProducer::collectLikeTermsOfPlus(const Expr& e,
3724 						 ExprMap<Rational> & likeTerms,
3725 						 Rational & plusConstant) {
3726   likeTerms.clear();
3727   Expr::iterator i = e.begin();
3728   Expr::iterator iend = e.end();
3729   plusConstant= 0;
3730   //go thru' bvplus term, one monom at a time
3731   for(; i!=iend; ++i) {
3732     const Expr s = *i;
3733     switch(s.getOpKind()) {
3734     case BVMULT: {
3735       //if monom is BVMULT, collect like terms using ExprMap
3736       if (s[0].getKind() == BVCONST) {
3737         Rational coefficient= d_theoryBitvector->computeBVConst(s[0]);
3738         const Expr& var = s[1];
3739         collectOneTermOfPlus(coefficient, var, likeTerms, plusConstant);
3740       }
3741       else { // non-linear mult
3742         if(CHECK_PROOFS) {
3743           CHECK_SOUND(BVCONST != s[1].getKind(),
3744 		    "TheoryBitvector::combineLikeTerms: "
3745 		    "Unexpected MULT syntax:\n\n s = " + s.toString()
3746 		    +"\n\n in e = "+e.toString());
3747         }
3748         collectOneTermOfPlus(1, s, likeTerms, plusConstant);
3749       }
3750       break;
3751     }
3752     case BVUMINUS:
3753       collectOneTermOfPlus(-1, s[0], likeTerms, plusConstant);
3754       break;
3755     case BVCONST:
3756       plusConstant += d_theoryBitvector->computeBVConst(s);
3757       break;
3758     default:
3759       //we have just a variable; check if variable in ExprMap
3760       collectOneTermOfPlus(1, s, likeTerms, plusConstant);
3761       break;
3762     }
3763   }
3764 }
3765 
boundedModulo(const Rational & value,const Rational & modulo,const Rational & lowerBound)3766 static Rational boundedModulo(const Rational & value, const Rational & modulo,
3767 			      const Rational & lowerBound) {
3768     Rational ret = mod(value, modulo);
3769     if(ret == 0)
3770       return ret;
3771 
3772     if (ret< lowerBound)
3773       ret+= modulo;
3774     else {
3775       // end is one position beyond upper limit.
3776       Rational end= modulo+lowerBound;
3777       if (ret >= end)
3778 	ret-= modulo;
3779     }
3780     return ret;
3781 }
3782 
3783 void
3784 BitvectorTheoremProducer::
createNewPlusCollection(const Expr & e,const ExprMap<Rational> & likeTerms,Rational & plusConstant,std::vector<Expr> & result)3785 createNewPlusCollection(const Expr & e,
3786 			const ExprMap<Rational> & likeTerms,
3787 			Rational & plusConstant,
3788 			std::vector<Expr> & result) {
3789   int bvplusLength= d_theoryBitvector->BVSize(e);
3790   // Compute 2^n, to use as a modulus base
3791   Rational power2(1);
3792   for(int i=0; i<bvplusLength; i += 1) power2 *= 2;
3793 
3794   ExprMap<Rational>::const_iterator j = likeTerms.begin();
3795   ExprMap<Rational>::const_iterator jend = likeTerms.end();
3796   for(; j!=jend; ++j) {
3797     // The coefficient will be equivalent to j->second modulus of power2
3798     // and in the range [-power2/2+1, power2/2]
3799     // FIXME: Need to reconsider the "best" coefficient normalization scheme.
3800     Rational coefficient = boundedModulo(j->second, power2, -power2/2+1);
3801     if(coefficient == 0)
3802       continue;
3803     Expr multiplicand = j->first;
3804     Expr monomial;
3805     if (coefficient<0) {
3806       // Make the coefficient positive: c<0 ;
3807       // (c*x)= (-c)*(-x)= (-c)*(~x+1)=(-c)*(~x) -c
3808       multiplicand = d_theoryBitvector->newBVNegExpr(multiplicand);
3809       multiplicand = d_theoryBitvector->pushNegationRec(multiplicand).getRHS();
3810       coefficient= coefficient*-1;
3811       plusConstant +=coefficient;
3812     }
3813     if(coefficient == 1)
3814       monomial = multiplicand;
3815     else {
3816       Expr coeffExpr =
3817 	d_theoryBitvector->newBVConstExpr(coefficient, bvplusLength);
3818       monomial =
3819 	d_theoryBitvector->newBVMultExpr(bvplusLength, coeffExpr,multiplicand);
3820     }
3821     if(CHECK_PROOFS) {
3822       CHECK_SOUND(BITVECTOR==monomial.getType().getExpr().getOpKind(),
3823 		  "TheoryBitvector::combineLikeTerms:"
3824 		  "each monomial must be a bitvector:\n"
3825 		  "monomial = " + monomial.toString());
3826       CHECK_SOUND(bvplusLength == d_theoryBitvector->BVSize(monomial),
3827 		  "TheoryBitvector::combineLikeTerms:"
3828 		  "bvLength of each monomial must be the same as e:\n"
3829 		  "monomial = " + monomial.toString() + "\n e = " + e.toString());
3830     }
3831     result.push_back(monomial);
3832   }
3833   // Positive modulo of the constant
3834   plusConstant = boundedModulo(plusConstant, power2, 0);
3835 
3836   //make the constant a subterm of the BVPLUS expression
3837   if(plusConstant != 0) {
3838     const Expr c =
3839       d_theoryBitvector->newBVConstExpr(plusConstant, bvplusLength);
3840     result.push_back(c);
3841   }
3842 }
3843 
3844 Expr
sumNormalizedElements(int bvplusLength,const std::vector<Expr> & items)3845 BitvectorTheoremProducer::sumNormalizedElements(int bvplusLength,
3846 						const std::vector<Expr>&items){
3847   //construct a new BVPLUS term using the ExprMap.  if size of
3848   //likeTerms is less than 2, then do NOT construct BVPLUS
3849   switch(items.size()) {
3850   case 0:
3851     //items are empty. only constant 0 remains
3852     return d_theoryBitvector->newBVZeroString(bvplusLength);
3853 
3854   case 1:
3855     //items may contain a Expr of the form a*x or x or a
3856     return items[0];
3857 
3858   default:
3859     //items have 2 or more kids
3860     return d_theoryBitvector->newBVPlusExpr(bvplusLength, items);
3861   }
3862 }
3863 
3864 Theorem
combineLikeTermsRule(const Expr & e)3865 BitvectorTheoremProducer::combineLikeTermsRule(const Expr& e) {
3866   TRACE("bitvector rewrite", "combineLikeTermsRule(",e.toString(), ") {");
3867   if(CHECK_PROOFS) {
3868     CHECK_SOUND(BVPLUS == e.getOpKind() && e.arity()>=2,
3869 		"TheoryBitvector::combineLikeTerms: "
3870 		"input must be a BVPLUS term:\n e = " + e.toString());
3871     int bvplusLength = d_theoryBitvector->BVSize(e);
3872     Expr::iterator i = e.begin();
3873     Expr::iterator iend = e.end();
3874     for(;i!=iend;++i) {
3875       const Expr& s = *i;
3876       if(s.getOpKind() == BVPLUS) {
3877 	CHECK_SOUND(s.getOpKind() != BVPLUS,
3878 		    "TheoryBitvector::combineLikeTerms: "
3879 		    "BVPLUS must be flattened:\n e = " + e.toString());
3880       }
3881 
3882       int bvLength= d_theoryBitvector->BVSize(s);
3883       //bvLength checks for BVCONST and variables
3884       CHECK_SOUND(bvLength==bvplusLength,
3885 		  "TheoryBitvector::combineLikeTerms: "
3886 		  "BVPLUS must be padded:\n e = " + e.toString());
3887       //Length checks for BVMULTs
3888       if(s.getOpKind()==BVMULT) {
3889 	int s0len = d_theoryBitvector->BVSize(s[0]);
3890 	int s1len = d_theoryBitvector->BVSize(s[1]);
3891 	CHECK_SOUND(bvplusLength == s0len && s0len== s1len,
3892 		    "all monoms must have the samebvLength "
3893 		    "as the bvplus term: " + e.toString());
3894       }
3895     }
3896   }
3897   int bvplusLength = d_theoryBitvector->BVSize(e);
3898   ExprMap<Rational> likeTerms;
3899   Rational theConstant(0);
3900   collectLikeTermsOfPlus(e, likeTerms, theConstant);
3901 
3902   std::vector<Expr> collection;
3903   createNewPlusCollection(e, likeTerms, theConstant, collection);
3904 
3905   Expr output= sumNormalizedElements(bvplusLength, collection);
3906 
3907   TRACE("bitvector rewrite",
3908 	"combineLikeTermsRule =>",output.toString(), "}");
3909   Proof pf;
3910   if(withProof())
3911     pf=newPf("bvplus_combine_like_terms", e);
3912   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
3913 }
3914 
3915 Theorem
lhsMinusRhsRule(const Expr & e)3916 BitvectorTheoremProducer::lhsMinusRhsRule(const Expr& e) {
3917   if(CHECK_PROOFS) {
3918     CHECK_SOUND(EQ == e.getKind() && e.arity() == 2,
3919 		"BitvectorTheoremProducer::lhsMinusRhsRule: "
3920 		"input must be an EQ: e = " +e.toString());
3921     CHECK_SOUND(BVPLUS == e[0].getOpKind() ||
3922 		BVPLUS == e[1].getOpKind(),
3923 		"BitvectorTheoremProducer::lhsMinusRhsRule: "
3924 		"atleast one of the input subterms must be BVPLUS:"
3925 		"e = " +e.toString());
3926     int bvLength0 = d_theoryBitvector->BVSize(e[0]);
3927     int bvLength1 = d_theoryBitvector->BVSize(e[1]);
3928     CHECK_SOUND(bvLength0 == bvLength1,
3929 		"BitvectorTheoremProducer::lhsMinusRhsRule: "
3930 		"both sides of EQ must be same Length. e = " +e.toString());
3931     for(Expr::iterator i=e[0].begin(),iend=e[0].end();i!=iend;++i) {
3932       int bvLength= d_theoryBitvector->BVSize(*i);
3933       CHECK_SOUND(bvLength0 == bvLength,
3934 		  "BitvectorTheoremProducer::lhsMinusRhsRule: "
3935 		  "all subterms of e[0] must be of same Length."
3936 		  "e = " +e.toString());
3937     }
3938     for(Expr::iterator i=e[1].begin(),iend=e[1].end();i!=iend;++i) {
3939       int bvLength= d_theoryBitvector->BVSize(*i);
3940       CHECK_SOUND(bvLength1 == bvLength,
3941 		  "BitvectorTheoremProducer::lhsMinusRhsRule: "
3942 		  "all subterms of e[1] must be of same Length."
3943 		  "e = " +e.toString());
3944     }
3945   }
3946   Expr output;
3947   int bvLength = d_theoryBitvector->BVSize(e[0]);
3948   std::vector<Expr> k;
3949 
3950   //construct 0 of bvLength
3951   Expr zeroStr = d_theoryBitvector->newBVZeroString(bvLength);
3952 
3953   if(e[0] == e[1])
3954     output = Expr(EQ, zeroStr, zeroStr);
3955   else {
3956     //drop common subterms
3957     std::vector<Expr> e0K = e[0].getKids();
3958     std::vector<Expr> e1K = e[1].getKids();
3959     for(vector<Expr>::iterator i=e0K.begin(),iend=e0K.end();i!=iend;++i){
3960       for(vector<Expr>::iterator j=e1K.begin(),jend=e1K.end();j!=jend;++j){
3961 	if(*i == *j) {
3962 	  e0K.erase(i);
3963 	  e1K.erase(j);
3964 	  break;
3965 	}
3966       }
3967     }
3968     Expr newLhs = d_theoryBitvector->newBVPlusExpr(bvLength, e0K);
3969     k.push_back(newLhs);
3970     Expr newRhs = d_theoryBitvector->newBVPlusExpr(bvLength, e1K);
3971     //construct -rhs
3972     Expr uminus = d_theoryBitvector->newBVUminusExpr(newRhs);
3973     //push back -rhs
3974     k.push_back(uminus);
3975     //construct lhs-rhs
3976     Expr lhsMinusRhs = d_theoryBitvector->newBVPlusExpr(bvLength,k);
3977     //construct lhs-rhs=0
3978     output = Expr(EQ, lhsMinusRhs, zeroStr);
3979   }
3980 
3981   Proof pf;
3982   if(withProof())
3983     pf = newPf("lhs_minus_rhs_rule", e);
3984   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
3985 }
3986 
3987 //! generic rule used for bitblasting step. -e <==> ~e+1
3988 Theorem
bvuminusToBVPlus(const Expr & e)3989 BitvectorTheoremProducer::bvuminusToBVPlus(const Expr& e) {
3990   if(CHECK_PROOFS) {
3991     CHECK_SOUND(BVUMINUS == e.getOpKind(),
3992 		"BitvectorTheoremProducer::bvuminusBitBlastRule: "
3993 		"input must be bvuminus: e = " + e.toString());
3994   }
3995   int bvLength = d_theoryBitvector->BVSize(e);
3996   std::vector<Expr> k;
3997   Expr negE0 = d_theoryBitvector->newBVNegExpr(e[0]);
3998   k.push_back(negE0);
3999   Expr plusOne = d_theoryBitvector->newBVConstExpr(1, bvLength);
4000   k.push_back(plusOne);
4001 
4002   Expr output = d_theoryBitvector->newBVPlusExpr(bvLength, k);
4003   Proof pf;
4004   if(withProof())
4005     pf = newPf("bvuminus_bitblast_rule", e);
4006   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4007 }
4008 
4009 //! -0 <==> 0, -c <==> ~c+1
4010 Theorem
bvuminusBVConst(const Expr & e)4011 BitvectorTheoremProducer::bvuminusBVConst(const Expr& e) {
4012   if(CHECK_PROOFS) {
4013     CHECK_SOUND(BVUMINUS == e.getOpKind() &&
4014 		BVCONST == e[0].getKind(),
4015 		"BitvectorTheoremProducer::bvuminusBVConst: "
4016 		"e should be bvuminus, e[0] should be bvconst: e = " +
4017 		e.toString());
4018   }
4019   Expr output;
4020   int e0Length = d_theoryBitvector->BVSize(e[0]);
4021   // output == 0
4022   if(d_theoryBitvector->computeBVConst(e[0]) == 0)
4023     output = e[0];
4024   else {
4025     // Compute -c, which is ~c+1
4026     Rational x = d_theoryBitvector->computeNegBVConst(e[0]);
4027     output = d_theoryBitvector->newBVConstExpr(x, e0Length);
4028   }
4029 
4030   Proof pf;
4031   if(withProof())
4032     pf = newPf("bvuminus_bvconst_rule", e);
4033   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4034 }
4035 
4036 //! -(c*t)<=>(-c)*t; if -c==0 return e<=>0. if(-c==1) return e<=>t
4037 Theorem
bvuminusBVMult(const Expr & e)4038 BitvectorTheoremProducer::bvuminusBVMult(const Expr& e) {
4039   if(CHECK_PROOFS) {
4040     CHECK_SOUND(BVUMINUS == e.getOpKind(),
4041 		"BitvectorTheoremProducer::bvuminusBVMult: "
4042 		"e should be bvuminus: e =" + e.toString());
4043     CHECK_SOUND(BVMULT == e[0].getOpKind(),
4044 		"Bitvectortheoremproducer::bvuminusBVMult: "
4045 		"in input expression e = " + e.toString() +
4046 		"\ne[0] should be bvmult: e[0] = " + e[0].toString());
4047     CHECK_SOUND(BVCONST == e[0][0].getKind(),
4048 		"Bitvectortheoremproducer::bvuminusBVMult: "
4049 		"in input expression e = " + e.toString() +
4050 		"\ne[0][0] should be bvconst: e[0][0] = " + e[0][0].toString());
4051     int bvLength =  d_theoryBitvector->BVSize(e);
4052     int e0Length =  d_theoryBitvector->BVSize(e[0]);
4053     int e00Length =  d_theoryBitvector->BVSize(e[0][0]);
4054     CHECK_SOUND(bvLength == e0Length && e0Length == e00Length,
4055 		"Bitvectortheoremproducer::bvuminusBVMult: "
4056 		"in input expression e = " + e.toString() +
4057 		"\nLengths of all subexprs must be equal: e = " + e.toString());
4058   }
4059   //e is of the form -(c*t)
4060   Expr output;
4061   int e0Length = d_theoryBitvector->BVSize(e[0]);
4062   //compute ~c+1
4063   Rational coeff = d_theoryBitvector->computeNegBVConst(e[0][0]);
4064   if(0 == coeff)
4065     //if ~c+1 == 0
4066     output = d_theoryBitvector->newBVZeroString(e0Length);
4067   else if (1 == coeff)
4068     //if ~c+1 == 1
4069     output = e[0][1];
4070   else {
4071     //construct (~c+1)*t
4072     Expr newcoeff = d_theoryBitvector->newBVConstExpr(coeff, e0Length);
4073     output = d_theoryBitvector->newBVMultExpr(e0Length, newcoeff, e[0][1]);
4074   }
4075 
4076   Proof pf;
4077   if(withProof())
4078     pf = newPf("bvuminus_bvmult_rule", e);
4079   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4080 }
4081 
4082 //! -(-e) <==> e
4083 Theorem
bvuminusBVUminus(const Expr & e)4084 BitvectorTheoremProducer::bvuminusBVUminus(const Expr& e) {
4085   if(CHECK_PROOFS) {
4086     CHECK_SOUND(BVUMINUS == e.getOpKind(),
4087 		"BitvectorTheoremProducer::bvuminusBVUminus: "
4088 		"e should be bvuminus: e =" + e.toString());
4089     CHECK_SOUND(BVUMINUS == e[0].getOpKind(),
4090 		"Bitvectortheoremproducer::bvuminusBVUminus: "
4091 		"in input expression e = " + e.toString() +
4092 		"\ne[0] should be bvmult: e[0] = " + e[0].toString());
4093   }
4094   Expr output;
4095   // -(-e) <==> e
4096   output = e[0][0];
4097   Proof pf;
4098   if(withProof())
4099     pf = newPf("bvuminus_bvuminus_rule", e);
4100   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4101 }
4102 
4103 //! -v <==> -1*v
4104 Theorem
bvuminusVar(const Expr & e)4105 BitvectorTheoremProducer::bvuminusVar(const Expr& e) {
4106   if(CHECK_PROOFS) {
4107     CHECK_SOUND(BVUMINUS == e.getOpKind(),
4108 		"BitvectorTheoremProducer::bvuminusVar: "
4109 		"e should be bvuminus: e =" + e.toString());
4110   }
4111   Expr output;
4112   std::vector<bool> res;
4113   int e0Length = d_theoryBitvector->BVSize(e[0]);
4114   for(int i=0; i<e0Length; ++i) {
4115     res.push_back(true);
4116   }
4117   Expr coeff = d_theoryBitvector->newBVConstExpr(res);
4118   output = d_theoryBitvector->newBVMultExpr(e0Length, coeff, e[0]);
4119 
4120   Proof pf;
4121   if(withProof())
4122     pf = newPf("bvuminus_var_rule", e);
4123   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4124 }
4125 
4126 //! c*(-t) <==> (-c)*t
4127 Theorem
bvmultBVUminus(const Expr & e)4128 BitvectorTheoremProducer::bvmultBVUminus(const Expr& e) {
4129   if(CHECK_PROOFS) {
4130     CHECK_SOUND(BVUMINUS == e.getOpKind(),
4131 		"BitvectorTheoremProducer::bvmultBVUminus: "
4132 		"e should be bvuminus: e =" + e.toString());
4133     CHECK_SOUND(BVMULT == e[0].getOpKind() &&
4134 		BVCONST == e[0][0].getKind() &&
4135 		BVUMINUS == e[0][1].getOpKind(),
4136 		"Bitvectortheoremproducer::bvmultBVUminus: "
4137 		"in input expression e = " + e.toString() +
4138 		"\ne[0] has to be bvmult"
4139 		"e[0][1] must be bvuminus: e[0] = " + e[0].toString());
4140     int bvLength = d_theoryBitvector->BVSize(e);
4141     int e00Length = d_theoryBitvector->BVSize(e[0][0]);
4142     int e01Length = d_theoryBitvector->BVSize(e[0][1]);
4143     CHECK_SOUND(bvLength == e00Length && e00Length == e01Length,
4144 		"Bitvectortheoremproducer::bvmultBVUminus: "
4145 		"in input expression e = " + e.toString() +
4146 		"\nLengths of all subexprs must be equal.");
4147   }
4148   Expr output;
4149   int bvLength = d_theoryBitvector->BVSize(e);
4150   const Expr& coeff = e[0][0];
4151   Rational negatedcoeff = d_theoryBitvector->computeNegBVConst(coeff);
4152   const Expr& e010 = e[0][1][0];
4153 
4154   if(0 == negatedcoeff)
4155     //if ~c+1 == 0
4156     output = d_theoryBitvector->newBVZeroString(bvLength);
4157   else if (1 == negatedcoeff)
4158     //if ~c+1 == 1
4159     output = e010;
4160   else {
4161     //construct (~c+1)*t
4162     Expr newcoeff = d_theoryBitvector->newBVConstExpr(negatedcoeff, bvLength);
4163     output = d_theoryBitvector->newBVMultExpr(bvLength, newcoeff, e010);
4164   }
4165 
4166   Proof pf;
4167   if(withProof())
4168     pf = newPf("bvmult_bvuminus_rule", e);
4169   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4170 }
4171 
4172 //! -(c1*t1+...+cn*tn) <==> (-(c1*t1)+...+-(cn*tn))
4173 Theorem
bvuminusBVPlus(const Expr & e)4174 BitvectorTheoremProducer::bvuminusBVPlus(const Expr& e) {
4175 //   if(CHECK_PROOFS) {
4176 //     CHECK_SOUND(BVUMINUS == e.getOpKind(),
4177 // 		"BitvectorTheoremProducer::bvuminusBVPlus: "
4178 // 		"e should be bvuminus: e =" + e.toString());
4179 //     CHECK_SOUND(BVPLUS == e[0].getOpKind(),
4180 // 		"BitvectorTheoremProducer::bvuminusBVPlus: "
4181 // 		"e[0] should be bvplus: e[0] =" + e[0].toString());
4182 //   }
4183 //   int bvLength = d_theoryBitvector->BVSize(e);
4184 //   const Expr& e0 = e[0];
4185 //   Expr::iterator i = e0.begin();
4186 //   Expr::iterator iend = e0.end();
4187 //   std::vector<Expr> output;
4188 //   for(; i!=iend; ++i) {
4189 //     const Expr& s = *i;
4190 //     Expr t = d_theoryBitvector->newBVUminusExpr(s);
4191 //     output.push_back(t);
4192 //   }
4193 //   Expr outputPlus =
4194 //     d_theoryBitvector->newBVPlusExpr(bvLength, output);
4195 
4196 //   Assumptions a;
4197 //   Proof pf;
4198 //   if(withProof())
4199 //     pf = newPf("bvminus_bvplus_rule", e);
4200 //   return newRWTheorem(e, outputPlus, a, pf);
4201 
4202   Proof pf;
4203   if(withProof())
4204     pf = newPf("bvminus_bvplus_rule", e);
4205   return newRWTheorem(e, e, Assumptions::emptyAssump(), pf);
4206 }
4207 
4208 Theorem
extractBVMult(const Expr & e)4209 BitvectorTheoremProducer::extractBVMult(const Expr& e) {
4210   if(CHECK_PROOFS) {
4211     CHECK_SOUND(e.getOpKind() == EXTRACT &&
4212 		e[0].getOpKind() == BVMULT &&
4213 		e[0].arity() == 2,
4214 		"BitvectorTheoremProducer::extractBVMult: "
4215 		"input must be an EXTRACT over BVMULT:\n e = "+e.toString());
4216   }
4217   const Expr& bvmult = e[0];
4218   int bvmultLen = d_theoryBitvector->BVSize(bvmult);
4219   int extractHi = d_theoryBitvector->getExtractHi(e);
4220   int extractLow = d_theoryBitvector->getExtractLow(e);
4221 
4222   if(CHECK_PROOFS) {
4223     CHECK_SOUND(bvmultLen > extractHi,
4224 		"BitvectorTheoremProducer::extractBVMult: "
4225 		"bvmult Length must be greater than extract Length:\n e = "
4226 		+e.toString());
4227   }
4228 
4229   Expr output = d_theoryBitvector->newBVMultPadExpr(extractHi+1, bvmult[0],
4230                                                     bvmult[1]);
4231   if(extractLow > 0)
4232     output=d_theoryBitvector->newBVExtractExpr(output, extractHi, extractLow);
4233 
4234   Proof pf;
4235   if(withProof())
4236     pf = newPf("extract_bvmult_rule", e);
4237   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4238 }
4239 
4240 Theorem
extractBVPlus(const Expr & e)4241 BitvectorTheoremProducer::extractBVPlus(const Expr& e) {
4242   if(CHECK_PROOFS) {
4243     CHECK_SOUND(e.getOpKind() == EXTRACT && e[0].getOpKind() == BVPLUS,
4244 		"BitvectorTheoremProducer::extractBVPlus: "
4245 		"input must be an EXTRACT over BVPLUS:\n e = "+e.toString());
4246   }
4247   const Expr& bvplus = e[0];
4248   int bvplusLen = d_theoryBitvector->BVSize(bvplus);
4249   int extractHi = d_theoryBitvector->getExtractHi(e);
4250   int extractLow = d_theoryBitvector->getExtractLow(e);
4251 
4252   if(CHECK_PROOFS) {
4253     CHECK_SOUND(bvplusLen > extractHi,
4254 		"BitvectorTheoremProducer::extractBVPlus: "
4255 		"bvplus Length must be greater than extract bvLength:\n e = "
4256 		+e.toString());
4257   }
4258 
4259   // Shortcut
4260   if(bvplusLen == extractHi+1)
4261     return d_theoryBitvector->reflexivityRule(e);
4262 
4263   // Shorten the result width of the bvplus term
4264   Expr output(d_theoryBitvector->newBVPlusPadExpr(extractHi+1, bvplus.getKids()));
4265   if(extractLow > 0)
4266     output=d_theoryBitvector->newBVExtractExpr(output, extractHi, extractLow);
4267 
4268   Proof pf;
4269   if(withProof())
4270     pf = newPf("extract_bvplus_rule", e);
4271   return newRWTheorem(e, output, Assumptions::emptyAssump(), pf);
4272 }
4273 
4274 
4275 // |- t=0 OR t=1  for any 1-bit bitvector t
4276 Theorem
typePredBit(const Expr & e)4277 BitvectorTheoremProducer::typePredBit(const Expr& e) {
4278   if(CHECK_PROOFS) {
4279     CHECK_SOUND(d_theoryBitvector->getBaseType(e).getExpr().getOpKind() == BITVECTOR,
4280 		"BitvectorTheoremProducer::typePredBit: e = "+e.toString());
4281     CHECK_SOUND(d_theoryBitvector->BVSize(e) == 1,
4282 		"BitvectorTheoremProducer::typePredBit: e = "+e.toString());
4283   }
4284 
4285   Proof pf;
4286   if(withProof())
4287     pf=newPf("type_pred_bit", e);
4288   return newTheorem(e.eqExpr(bvZero()) || e.eqExpr(bvOne()), Assumptions::emptyAssump(), pf);
4289 }
4290 
4291 
4292 //! Expand the type predicate wrapper (compute the actual type predicate)
4293 Theorem
expandTypePred(const Theorem & tp)4294 BitvectorTheoremProducer::expandTypePred(const Theorem& tp) {
4295   Expr tpExpr = tp.getExpr();
4296   if(CHECK_PROOFS) {
4297     CHECK_SOUND(tpExpr.getOpKind() == BVTYPEPRED ||
4298 		(tpExpr.getKind() == NOT && tpExpr[0].getOpKind() == BVTYPEPRED),
4299 		"BitvectorTheoremProducer::expandTypePred: "
4300 		"Expected BV_TYPE_PRED wrapper:\n tp = "
4301 		+tpExpr.toString());
4302   }
4303   Expr res;
4304   if(tpExpr.getKind() == NOT)
4305     res = d_theoryBitvector->falseExpr();
4306   else {
4307     Type t(d_theoryBitvector->getTypePredType(tpExpr));
4308     const Expr& e(d_theoryBitvector->getTypePredExpr(tpExpr));
4309     int size(d_theoryBitvector->getBitvectorTypeParam(t));
4310     //   DebugAssert(BVSize(e)==size, "TheoryBitvector::computeTypePred: e="
4311     // 	      +e.toString()+", t="+t.toString());
4312     if(size >= 2) {
4313       vector<Expr> kids;
4314       for(int i=0; i<size; i++) {
4315 	Expr bit(d_theoryBitvector->newBVExtractExpr(e, i, i));
4316 	kids.push_back(bit.eqExpr(bvZero()) || bit.eqExpr(bvOne()));
4317       }
4318       res = andExpr(kids);
4319     } else {
4320       res = (e.eqExpr(bvZero()) || e.eqExpr(bvOne()));
4321     }
4322   }
4323   Proof pf;
4324   if(withProof())
4325     pf = newPf("expand_type_pred", tp.getExpr(), tp.getProof());
4326 
4327   return newTheorem(res, tp.getAssumptionsRef(), pf);
4328 }
4329 
4330 /*Beginning of Lorenzo PLatania's methods*/
4331 
4332 // Theorem BitvectorTheoremProducer::multiply_coeff( Rational mult_inv, const Expr& e)
4333 // {
4334 
4335 //   Expr rhs= d_theoryBitvector->multiply_coeff( mult_inv, e);
4336 //   Proof pf= newPf("multiply both sides for a constant");
4337 //   return newRWTheorem( e, rhs, Assumptions::emptyAssump(), pf);
4338 // }
4339 
4340 
4341 // rewrites the equation in the form 0 = Expr
4342 // this is needed for TheoryBitvector::solve
MarkNonSolvableEq(const Expr & e)4343 Theorem BitvectorTheoremProducer::MarkNonSolvableEq( const Expr& e)
4344 {
4345 
4346   int bv_size =  d_theoryBitvector->BVSize(e[0]);
4347   Expr bv_zero( d_theoryBitvector->newBVZeroString(bv_size));
4348 
4349   if (CHECK_PROOFS)
4350     CHECK_SOUND( e.isEq() &&
4351 		( e[0] == bv_zero || e[1] == bv_zero ),
4352 		"MarkNonSolvableEq: input must be a canonized equation" + e.toString());
4353   if( e[1] == bv_zero )
4354     {
4355       Expr expr_res= Expr(EQ, e[1], e[0]);
4356       Proof pf= newPf("mark non solvable eq");
4357       Theorem th_res= newRWTheorem( e, expr_res, Assumptions::emptyAssump(), pf);
4358       return th_res;
4359     }
4360   else
4361     {
4362       return d_theoryBitvector->reflexivityRule(e);
4363     }
4364 
4365 
4366 }
4367 
4368 // Given an expression t = 0, isolate a single leaf on the lhs if possible,
4369 // returning t = 0 <=> leaf = rest.
4370 // Otherwise, return e <=> e
isolate_var(const Expr & e)4371 Theorem BitvectorTheoremProducer::isolate_var(const Expr& e)
4372 {
4373   int bv_size = d_theoryBitvector->BVSize(e[0]);
4374   Expr bv_zero(d_theoryBitvector->newBVZeroString(bv_size));
4375 
4376   if (CHECK_PROOFS) {
4377     CHECK_SOUND(e.isEq() && e[1] == bv_zero && e[0].getOpKind() != BVCONST,
4378 		"isolate_var: input must be an equation with lhs non-cosnt and rhs must be zero" + e.toString());
4379   }
4380 
4381   //  cout<<"BitvectorTheoremProducer::isolate_var: "<<e.toString()<<endl;
4382 
4383   Rational modulus = pow(Rational(bv_size), Rational(2));
4384   Expr res_expr;
4385   Expr lhs = e[0];
4386 
4387   switch (lhs.getOpKind()) {
4388     case BVMULT:
4389       // linear BVMULT term
4390       if( lhs[0].getOpKind() == BVCONST )
4391       {
4392         DebugAssert(lhs[1].getOpKind() != BVCONST &&
4393                     lhs[1].getOpKind() != BVPLUS, "Should have been canonized");
4394         DebugAssert(d_theoryBitvector->computeBVConst(lhs[0]) % 2 == 0,
4395                     "Expected even coeff");
4396       }
4397       res_expr = e;
4398       break;
4399     case BVPLUS:
4400     {
4401       int e_kid_arity = lhs.arity();
4402       bool foundUnitCoeff = false;
4403       Expr new_lhs, new_rhs, new_coeff;
4404       vector<Expr> newKids;
4405       Rational tmp, const_term = 0;
4406       for( int i = 0; i < e_kid_arity; ++i)
4407       {
4408         // it can be a BVMULT, a var, or a const
4409         Expr e_sub_kid = lhs[i];
4410         switch (e_sub_kid.getOpKind()) {
4411           case BVCONST:
4412             DebugAssert(const_term == 0, "Expected only one constant");
4413             const_term = ((modulus-1) * d_theoryBitvector->computeBVConst(e_sub_kid)) % modulus;
4414             newKids.push_back(d_theoryBitvector->newBVConstExpr(const_term, bv_size));
4415             break;
4416           case BVMULT:
4417             if( e_sub_kid[0].getOpKind() == BVCONST )
4418             {
4419               DebugAssert(e_sub_kid.arity() == 2, "Expected arity 2 BVMULT");
4420               tmp = d_theoryBitvector->computeBVConst(e_sub_kid[0]);
4421               DebugAssert(tmp != 1, "Expected coeff other than 1");
4422               tmp = (tmp * (modulus-1)) % modulus;
4423               new_coeff = d_theoryBitvector->newBVConstExpr(tmp, bv_size);
4424               newKids.push_back(d_theoryBitvector->newBVMultExpr(bv_size, new_coeff, e_sub_kid[1]));
4425             }
4426             else {
4427               new_coeff = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size);
4428               newKids.push_back(d_theoryBitvector->newBVMultExpr(bv_size, new_coeff, e_sub_kid));
4429             }
4430             break;
4431           default:
4432             if (!foundUnitCoeff) {
4433               foundUnitCoeff = true;
4434               new_lhs = e_sub_kid;
4435             }
4436             else {
4437               new_coeff = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size);
4438               newKids.push_back(d_theoryBitvector->newBVMultExpr(bv_size, new_coeff, e_sub_kid));
4439             }
4440             break;
4441         }
4442       }
4443       if (foundUnitCoeff) {
4444         DebugAssert(newKids.size() > 0, "Expected non-empty kids");
4445         Expr new_rhs;
4446         if (newKids.size() == 1) {
4447           new_rhs = newKids[0];
4448         }
4449         else {
4450           new_rhs = d_theoryBitvector->newBVPlusExpr(bv_size, newKids);
4451         }
4452         res_expr = Expr(EQ, new_lhs, new_rhs);
4453       }
4454       else {
4455         res_expr = e;
4456       }
4457       break;
4458     }
4459     default:
4460       res_expr = e;
4461       break;
4462   }
4463   Proof pf= newPf("isolate var");
4464   //  cout<<"TheoryBitvector::isolate_var: result is: " <<res_expr.toString()<<endl;
4465 
4466   DebugAssert(e == res_expr || (res_expr.isEq() && d_theoryBitvector->isLeaf(res_expr[0]) &&
4467               !d_theoryBitvector->isLeafIn(res_expr[0], res_expr[1])),
4468               "Expected no change or solved form");
4469 
4470   return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf);
4471 }
4472 
4473 
4474 // Theorem BitvectorTheoremProducer::isolate_var( const Theorem& t, const Expr& e)
4475 // {
4476 //   int bv_size =  d_theoryBitvector->BVSize(e[0]);
4477 //   Expr bv_zero( d_theoryBitvector->newBVZeroString(bv_size));
4478 //   Expr BV_one = d_theoryBitvector->newBVConstExpr(1,bv_size);
4479 
4480 //   if (CHECK_PROOFS)
4481 //     // the RHS assumptio has to be removed
4482 //     CHECK_SOUND( e.isEq() &&
4483 // 		( e[0] == bv_zero || e[1] == bv_zero ),
4484 // 		"isolate_var: input must be an equation and one of the kids must be a zero" + e.toString());
4485 
4486 //   cout<<"BitvectorTheoremProducer::isolate_var: "<<e.toString()<<endl;
4487 
4488 //   Expr new_rhs;
4489 //   Expr lhs;
4490 //   Expr new_lhs;
4491 //   //  Expr rhs;
4492 //   lhs = e[0];
4493 
4494 //   int lhs_arity = lhs.arity();
4495 
4496 //   int found = 0;
4497 //   int index, solve_pos;
4498 
4499 //   // add the case for a*x = 0
4500 
4501 //   //  equation of just one variable, like x= c, nothing to be done
4502 //   if( lhs.isVar())
4503 //     {
4504 //       Proof pf= newPf("isolate var");
4505 //       return newRWTheorem( t.getExpr(), e, Assumptions::emptyAssump(), pf);
4506 //     }
4507 //   else
4508 //     {
4509 //       //      look for a variable we can solve for
4510 //       for( index=0; index < lhs_arity; ++index)
4511 // 	{
4512 // // 	  if( lhs[index].getOpKind() == BVMULT )
4513 // // 	    {
4514 // // 	      if( lhs[index][0] == BV_one)
4515 // 	  cout<<"BitvectorTheoremProducer::isolate_var, lhs[index]: "<<lhs[index]<<endl;
4516 // 	  if( d_theoryBitvector->canSolveFor( lhs[index], e))
4517 // 	    //	  if( d_theoryBitvector->isLeaf( lhs[index]) || (lhs[index].getOpKind() == BVMULT && lhs[index][0].isVar() && lhs[index][0].isVar()) )
4518 // 	    {
4519 // 	      found = 1;
4520 // 	      solve_pos = index;
4521 // 	      break;
4522 // 	    }
4523 // 	}
4524 // // 	  else
4525 // // 	    if( lhs[index].getOpKind() == BVCONST )
4526 // // 	      rhs = lhs[index];
4527 
4528 //     }
4529 //   DebugAssert(found,
4530 // 	      "BitvectorTheoremProducer::isolate_var: No variable with unary coefficient found");
4531 
4532 //   // L:: Index says which variable we are solving the equation for.
4533 //   // for all other variables we have to invert the sign of the
4534 //   // coefficient and put them in the rhs with the known term
4535 
4536 //   cout<<"we solve for the var in position "<<solve_pos<<endl;
4537 //   //L:: x= sum(list)
4538 //   std::vector<Expr> new_rhs_list;
4539 //   Rational known_term = 0;
4540 //   int scan;
4541 //   for( scan = 0; scan < lhs_arity; ++scan)
4542 //     {
4543 //       if( scan != solve_pos )
4544 // 	{
4545 // 	  // I think the first case is useless
4546 // 	  // the operand of the sum is just a var, but different from
4547 // 	  // the one we choose to solve the equation
4548 // // 	  if( lhs[scan].isVar())
4549 // // 	    {
4550 // // 	      new_rhs_list.push_back( d_theoryBitvector->newBVUminusExpr( lhs[scan]) );
4551 // // 	    }
4552 // // 	  else
4553 // 	    // we add the constant to the known term
4554 // 	    if( lhs[scan].getOpKind() == BVCONST )
4555 // 	      {
4556 // 		Rational tmp = d_theoryBitvector->computeNegBVConst( lhs[scan]);
4557 // 		Expr bv_tmp = d_theoryBitvector->signed_newBVConstExpr( tmp, bv_size );
4558 // 		new_rhs_list.push_back ( bv_tmp);
4559 // 		cout<<"input constant: "<<lhs[scan].toString()<<" rational constant: "<<tmp<<" bv constant: "<<bv_tmp<<endl;
4560 // 	      }
4561 // 	    else
4562 
4563 // 	    // the operand is a variable multiplied by a constant
4564 // 	    if( lhs[scan].getOpKind() == BVMULT )
4565 // 	    {
4566 // 	      if( lhs[scan][0].getOpKind() == BVCONST )
4567 // 		{
4568 // 		  Rational new_coeff = d_theoryBitvector->computeNegBVConst( lhs[scan][0] );
4569 // 		  Expr bv_new_coeff = d_theoryBitvector->signed_newBVConstExpr( new_coeff, bv_size );
4570 // 		  if( bv_new_coeff == BV_one)
4571 // 		    new_rhs_list.push_back( lhs[scan][1]);
4572 // 		  else
4573 // 		    {
4574 // 		      Expr bv_new_expr = d_theoryBitvector->newBVMultExpr( bv_size, bv_new_coeff, lhs[scan][1]);
4575 // 		      new_rhs_list.push_back( bv_new_expr );
4576 // 		    }
4577 // 		}
4578 // 	      else
4579 // 		{
4580 // 		  new_rhs_list.push_back( d_theoryBitvector->newBVUminusExpr( lhs[scan] ) );
4581 // 		}
4582 // 	    }
4583 // 	    else
4584 // 	      if( d_theoryBitvector->isLeaf( lhs[scan] ) )
4585 // 		new_rhs_list.push_back( lhs[scan] );
4586 // 	      else
4587 // 		DebugAssert(0,
4588 // 			    "BitvectorTheoremProducer::isolate_var: subterm of non implemented kind");
4589 
4590 // 	}
4591 //     }
4592 //   for(unsigned int i=0; i < new_rhs_list.size(); i++)
4593 //     cout<<"new_rhs_list["<<i<<"]: "<<new_rhs_list[i]<<endl;
4594 //   if( new_rhs_list.size() > 1)
4595 //     new_rhs =  d_theoryBitvector->newBVPlusExpr( bv_size, new_rhs_list);
4596 //   else
4597 //     new_rhs = new_rhs_list[0];
4598 
4599 //   Expr expr_res;
4600 
4601 // //   if( lhs[index] >= new_rhs)
4602 // //     expr_res= Expr(EQ, lhs[index], new_rhs);
4603 // //   else
4604 // //     expr_res= Expr(EQ, new_rhs, lhs[index]);
4605 
4606 // // L:: fix according to the new form for variables
4607 //   new_lhs = lhs[solve_pos];
4608 //   expr_res= Expr(EQ, new_lhs, new_rhs);
4609 //   Proof pf= newPf("isolate var");
4610 //   Theorem th_res= newRWTheorem( e, expr_res, Assumptions::emptyAssump(), pf);
4611 //   cout<<"TheoryBitvector::isolate_var: result is: "<<expr_res.toString()<<endl;
4612 
4613 
4614 //   return newRWTheorem( t.getExpr(), expr_res, Assumptions::emptyAssump(), pf);
4615 //   //return d_theoryBitvector->iffMP( e, expr_res);
4616 // }
4617 
4618 
BVMult_order_subterms(const Expr & e)4619 Theorem BitvectorTheoremProducer::BVMult_order_subterms( const Expr& e )
4620 {
4621   if (CHECK_PROOFS)
4622     CHECK_SOUND(e.getOpKind() == BVMULT,
4623 		"BitvectorTheoremProducer::BVMult_order_vars: input must be a BVMULT expression" + e.toString());
4624 
4625   //  cout<<"BitvectorTheoremProducer::BVMult_order_subterms, e: "<<e.toString()<<endl;
4626   int bv_size= d_theoryBitvector->BVSize(e);
4627   Expr new_expr;
4628   vector<Expr> vars;
4629 
4630   // as the term has already been processed by BVcanon, a constant can
4631   // be just at the beginning of the term
4632   bool hasConst = false;
4633   if (e[0].getOpKind() == BVCONST) {
4634     d_theoryBitvector->extract_vars(e[1], vars);
4635     hasConst = true;
4636   }
4637   else {
4638     d_theoryBitvector->extract_vars(e, vars);
4639   }
4640 
4641   int vars_size = vars.size();
4642   ExprMap<int> vars_map;
4643 
4644   for( int i=0; i < vars_size; ++i)
4645     {
4646       //      cout<<"vars["<<i<<"]: "<<vars[i].toString()<<endl;
4647       // L:: we count how many times we found a variable
4648       if( vars_map.count( vars[i] ) == 0)
4649 	vars_map[ vars[i] ] = 1;
4650       else
4651 	vars_map[ vars[i] ] = vars_map[ vars[i] ] + 1;
4652     }
4653   // retrieving the variables from the map; the order of the variables
4654   // is like BVMULT(size, a, BVMULT(size, b, ...))  todo:: be careful
4655   // about the order in which variables are retrieved
4656   ExprMap<int>::iterator j = vars_map.begin();
4657   new_expr = (*j).first;
4658   if ((*j).second != 1) {
4659     for(int k=1; k < (*j).second; ++k) {
4660       new_expr = d_theoryBitvector->newBVMultExpr( bv_size, (*j).first, new_expr);
4661     }
4662   }
4663 
4664   for( ++j; j != vars_map.end(); ++j) {
4665     new_expr = d_theoryBitvector->newBVMultExpr( bv_size, (*j).first, new_expr);
4666     if ((*j).second != 1) {
4667       for(int k=1; k < (*j).second; ++k) {
4668         new_expr = d_theoryBitvector->newBVMultExpr( bv_size, (*j).first, new_expr);
4669       }
4670     }
4671   }
4672 
4673   Proof pf;
4674   if (withProof()) pf = newPf("BVMult_order_subterms");
4675 
4676   if (hasConst) {
4677     new_expr = d_theoryBitvector->newBVMultExpr( bv_size, e[0], new_expr);
4678   }
4679 
4680   Theorem result = newRWTheorem( e, new_expr, Assumptions::emptyAssump(), pf);
4681   return result;
4682 }
4683 
4684 
4685 // BVMULT(N, a\@b, y) = BVPLUS(N, BVMULT(N,b,y), BVMULT(N-n,a,y) \@ n-bit-0-string)
4686 // where n = BVSize(b), a != 0, one of a or b is a constant
liftConcatBVMult(const Expr & e)4687 Theorem BitvectorTheoremProducer::liftConcatBVMult(const Expr& e)
4688 {
4689   if (CHECK_PROOFS) {
4690     CHECK_SOUND(e.getOpKind() == BVMULT,
4691 		"BitvectorTheoremProducer::liftConcatBVMult: input must be a BVMULT expression" + e.toString());
4692   }
4693   int bv_size = d_theoryBitvector->BVSize( e );
4694   vector<Expr> kids;
4695   int idx = -1;
4696   bool first = false;
4697   int i = 0;
4698   for (; i< e.arity(); ++i) {
4699     const Expr& kid = e[i];
4700     if (idx == -1 &&
4701         kid.getOpKind() == CONCAT) {
4702       if (kid[kid.arity()-1].getKind() == BVCONST) {
4703         idx = i;
4704       }
4705       else if (kid[0].getKind() == BVCONST &&
4706                d_theoryBitvector->computeBVConst(kid[0]) != 0) {
4707         idx = i;
4708         first = true;
4709       }
4710       else kids.push_back(kid);
4711     }
4712     else kids.push_back(kid);
4713   }
4714   if (idx == -1) return d_theoryBitvector->reflexivityRule(e);
4715 
4716   Expr concatHi, concatLo;
4717 
4718   if (first) {
4719     // Split concat at the first kid
4720     if (e[idx].arity() == 2) {
4721       concatLo = e[idx][1];
4722     }
4723     else {
4724       vector<Expr> concatKids;
4725       for (i = 1; i < e[idx].arity(); ++i) {
4726         concatKids.push_back(e[idx][i]);
4727       }
4728       concatLo = d_theoryBitvector->newConcatExpr(concatKids);
4729     }
4730     concatHi = e[idx][0];
4731   }
4732   else {
4733     // Split concat at the last kid
4734     vector<Expr> concatKids = e[idx].getKids();
4735     concatLo = concatKids.back();
4736     concatKids.pop_back();
4737     if (concatKids.size() == 1) {
4738       concatHi = concatKids[0];
4739     }
4740     else {
4741       concatHi = d_theoryBitvector->newConcatExpr(concatKids);
4742     }
4743   }
4744 
4745   int n = d_theoryBitvector->BVSize(concatLo);
4746   kids.push_back(concatLo);
4747   Expr bvMult1 = d_theoryBitvector->newBVMultPadExpr(bv_size, kids);
4748   kids.pop_back();
4749   kids.push_back(concatHi);
4750   Expr bvMult2 = d_theoryBitvector->newBVMultPadExpr(bv_size-n,kids);
4751   Expr newLowConcat = d_theoryBitvector->newBVZeroString(n);
4752   Expr newConcat = d_theoryBitvector->newConcatExpr(bvMult2, newLowConcat);
4753   Expr res_expr = d_theoryBitvector->newBVPlusExpr(bv_size, bvMult1, newConcat);
4754 
4755   Proof pf;
4756   if (withProof()) pf = newPf("liftConcatBVMult");
4757   return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf);
4758 }
4759 
4760 
4761 // Let c * \prod_1^n a_i be the flattened BVMult term where c is a constant and each a_i cannot be:
4762 //   a) const, b) bvuminus, c) bvplus, d) bvmult
4763 // The canonical form is:
4764 // 1. if c = 0, then 0
4765 // 2. if c = 1 and n = 1 then a_1
4766 // 3. else if c = 1 then \prod_1^n a_i
4767 // 4. else c * \prod_1^n a_i
4768 // Note that \prod should be ordered and made up of binary mult's
4769 
canonBVMult(const Expr & e)4770 Theorem BitvectorTheoremProducer::canonBVMult( const Expr& e )
4771 {
4772   TRACE("canonBVMult", "canonBVMult: {\n    ", e.toString(), " --");
4773   if (CHECK_PROOFS)
4774     CHECK_SOUND(e.getOpKind() == BVMULT,
4775 		"BitvectorTheoremProducer::canonBVMult: input must be a BVMULT expression" + e.toString());
4776 
4777   //  cout<<"BitvectorTheoremProducer::canonBVMult, e:"<<e.toString()<<endl;
4778   int expr_arity = e.arity();
4779   int bv_size= d_theoryBitvector->BVSize(e);
4780   Theorem result;
4781   std::vector<Expr> mult_vars;
4782   Rational temp_coeff = 1;
4783   Expr new_expr;
4784   Expr no_minus_kid;
4785   Expr new_prod;
4786   Rational modulus = pow(Rational(bv_size), Rational(2));
4787   // separating all the constants and variables in the
4788   // multiplications
4789 
4790   for( int i = 0; i < expr_arity; ++i) {
4791     if (e[i].getOpKind() == BVUMINUS)	{
4792       temp_coeff = (temp_coeff * (modulus-1)) % modulus;
4793       no_minus_kid = e[i][0];
4794     } else no_minus_kid = e[i];
4795 
4796     switch (no_minus_kid.getOpKind()) {
4797 
4798       case BVCONST: {
4799         // Collect constants
4800         temp_coeff *= d_theoryBitvector->computeBVConst( no_minus_kid );
4801         temp_coeff = temp_coeff % modulus;
4802         break;
4803       }
4804 
4805       case BVMULT: {
4806         if (no_minus_kid[0].getOpKind() == BVCONST) {
4807           // collect coefficient and the variable
4808           temp_coeff *= d_theoryBitvector->computeBVConst(no_minus_kid[0]);
4809           temp_coeff = temp_coeff % modulus;
4810           DebugAssert(no_minus_kid[1].getOpKind() != BVCONST &&
4811                       no_minus_kid[1].getOpKind() != BVPLUS &&
4812                       no_minus_kid[1].getOpKind() != BVUMINUS,
4813                       "Expected canonized subterm");
4814 
4815           if (!new_prod.isNull()) {
4816             // multiply the kid by the product so far
4817             new_prod = d_theoryBitvector->newBVMultExpr( bv_size, new_prod, no_minus_kid[1]);
4818           }
4819           else
4820           {
4821             new_prod = no_minus_kid[1];
4822           }
4823         }
4824         else {
4825           if (!new_prod.isNull()) {
4826             // multiply the kid by the product so far
4827             new_prod = d_theoryBitvector->newBVMultExpr( bv_size, new_prod, no_minus_kid);
4828           }
4829           else
4830           {
4831             new_prod = no_minus_kid;
4832           }
4833         }
4834         break;
4835       }
4836 
4837       case BVPLUS: {
4838         result = distributive_rule( e );
4839         TRACE("canonBVMult", "--> ", result.getRHS().toString(), "\n}");
4840         return result;
4841       }
4842 
4843       default:
4844         if (!new_prod.isNull()) {
4845           // multiply the kid by the product so far
4846           new_prod = d_theoryBitvector->newBVMultExpr( bv_size, new_prod, no_minus_kid);
4847         }
4848         else
4849         {
4850           new_prod = no_minus_kid;
4851         }
4852     }
4853   }
4854 
4855   // producing the result
4856   if (temp_coeff == 0 || new_prod.isNull()) {
4857     // the variables found don't matter
4858     new_expr = d_theoryBitvector->newBVConstExpr(temp_coeff, bv_size);
4859   }
4860   else {
4861     if (new_prod.getOpKind() == BVMULT) {
4862       new_prod = BVMult_order_subterms(new_prod).getRHS();
4863     }
4864     ExprMap<Rational> sumHashMap;
4865     Rational known_term;
4866     Expr coeff_expr = d_theoryBitvector->newBVConstExpr(temp_coeff, bv_size);
4867     new_expr = d_theoryBitvector->newBVMultExpr(bv_size, coeff_expr, new_prod);
4868     getPlusTerms(new_expr, known_term, sumHashMap);
4869     new_expr = buildPlusTerm(bv_size, known_term, sumHashMap);
4870   }
4871 
4872   Proof pf;
4873   if (withProof()) pf = newPf("canonBVMult");
4874   result = newRWTheorem(e, new_expr, Assumptions::emptyAssump(), pf);
4875   TRACE("canonBVMult", "--> ", new_expr.toString(), "\n}");
4876   //  cout<<"BitvectorTheoremProducer::canonBVMult, e: "<<e.toString()<<" result: "<<result.toString()<<endl;
4877   return result;
4878 }
4879 
4880 
4881 // BVMULT(a,b) = X where X is the result of applying distributivity of BVMULT over BVPLUS
distributive_rule(const Expr & e)4882 Theorem BitvectorTheoremProducer::distributive_rule( const Expr& e )
4883 {
4884   if (CHECK_PROOFS)
4885     CHECK_SOUND(e.getOpKind() == BVMULT,
4886 		"BitvectorTheoremProducer::distributive_rule: input must be a BVMULT expression" + e.toString());
4887 
4888   int bv_size= d_theoryBitvector->BVSize(e);
4889 
4890   // BVMULT terms have just two kids; at least one of the two must be
4891   // a BVPLUS
4892 
4893   vector<Expr> e0_kids, e1_kids, result_kids;
4894 
4895   if (e[0].getOpKind() == BVPLUS) {
4896     e0_kids = e[0].getKids();
4897   }
4898   else e0_kids.push_back(e[0]);
4899 
4900   if (e[1].getOpKind() == BVPLUS) {
4901     e1_kids = e[1].getKids();
4902   }
4903   else e1_kids.push_back(e[1]);
4904 
4905   unsigned e0_kids_size = e0_kids.size();
4906   unsigned e1_kids_size = e1_kids.size();
4907   for( unsigned i = 0; i < e0_kids_size; ++i) {
4908     for( unsigned j = 0; j < e1_kids_size; ++j) {
4909       Expr sum_term = d_theoryBitvector->newBVMultExpr ( bv_size, e0_kids[i], e1_kids[j] );
4910       result_kids.push_back( sum_term );
4911     }
4912   }
4913   Expr result_sum = d_theoryBitvector->newBVPlusExpr ( bv_size, result_kids);
4914   Proof pf;
4915   if (withProof()) pf = newPf("distributive rule");
4916   Theorem result = newRWTheorem( e, result_sum, Assumptions::emptyAssump(), pf);
4917   return result;
4918 }
4919 
4920 
4921 // BVPLUS(N, a0, ..., an) = BVPLUS(N-n,a0[N-1:n],...an[N-1:n])\@t
4922 // where n = BVSize(t), and the sum of the lowest n bits of a0..an is exactly
4923 // equal to t (i.e. no carry)
liftConcatBVPlus(const Expr & e)4924 Theorem BitvectorTheoremProducer::liftConcatBVPlus(const Expr& e)
4925 {
4926   if (CHECK_PROOFS) {
4927     CHECK_SOUND(e.getOpKind() == BVPLUS,
4928 		"BitvectorTheoremProducer::liftConcatBVPlus: input must be a BVPLUS expression" + e.toString());
4929   }
4930   int bv_size = d_theoryBitvector->BVSize( e );
4931   vector<Expr> kids;
4932   int i = 0;
4933   Rational c = 0;
4934 
4935   if (e[0].getOpKind() == BVCONST) {
4936     ++i;
4937     c = d_theoryBitvector->computeBVConst(e[0]);
4938   }
4939 
4940   int chopSize = bv_size;
4941 
4942   bool nonzero = false;
4943   bool nonconst = false;
4944   Expr term;
4945 
4946   for (; i< e.arity(); ++i) {
4947     const Expr& kid = e[i];
4948     if (kid.getOpKind() != CONCAT) {
4949       return d_theoryBitvector->reflexivityRule(e);
4950     }
4951     Expr last = kid[kid.arity()-1];
4952     int size = d_theoryBitvector->BVSize(last);
4953 
4954     // If the last concat kid is not a constant, then our only hope is to chop
4955     // it off exactly and hope that all other last concat kids are equal to
4956     // 0 and wider (in bits) than last
4957     if (last.getOpKind() != BVCONST) {
4958       if (nonzero || size > chopSize) {
4959         return d_theoryBitvector->reflexivityRule(e);
4960       }
4961       nonzero = true;
4962       nonconst = true;
4963       chopSize = size;
4964       term = last;
4965       continue;
4966     }
4967 
4968     // If last is a zero-string, then we are OK, as long as it's at least as
4969     // wide as any nonconst we have encountered.  If it's less wide than the
4970     // constants we have encountered so far, reduce chopSize accordingly
4971     if (d_theoryBitvector->computeBVConst(last) == 0) {
4972       if (size >= chopSize) continue;
4973       if (nonconst) return d_theoryBitvector->reflexivityRule(e);
4974       chopSize = size;
4975       continue;
4976     }
4977 
4978     // If last is a nonzero const, it's OK as long as it is the only nonzero
4979     // thing we encounter
4980     if (nonzero) return d_theoryBitvector->reflexivityRule(e);
4981     nonzero = true;
4982     if (size < chopSize) chopSize = size;
4983     term = last;
4984   }
4985 
4986   // if nonzero exists, check the constant
4987   if (nonzero) {
4988     if (c != 0) {
4989       Rational modulus = pow(Rational(chopSize), Rational(2));
4990       if ((c % modulus) != 0) {
4991         return d_theoryBitvector->reflexivityRule(e);
4992       }
4993     }
4994   }
4995   else if (c == 0) {
4996     term = d_theoryBitvector->newBVZeroString(chopSize);
4997   }
4998   else {
4999     term = d_theoryBitvector->newBVExtractExpr(e[0], chopSize-1, 0);
5000   }
5001 
5002   vector<Expr> newKids;
5003   for (i = 0; i < e.arity(); ++i) {
5004     newKids.push_back(d_theoryBitvector->newBVExtractExpr(e[i], bv_size-1, chopSize));
5005   }
5006 
5007   Expr bvPlus = d_theoryBitvector->newBVPlusExpr(bv_size-chopSize, newKids);
5008   if (d_theoryBitvector->BVSize(term) > chopSize) {
5009     term = d_theoryBitvector->newBVExtractExpr(term, chopSize-1, 0);
5010   }
5011 
5012   Expr res_expr = d_theoryBitvector->newConcatExpr(bvPlus, term);
5013 
5014   Proof pf;
5015   if (withProof()) pf = newPf("liftConcatBVPlus");
5016   return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf);
5017 }
5018 
5019 
getPlusTerms(const Expr & e,Rational & known_term,ExprMap<Rational> & sumHashMap)5020 void BitvectorTheoremProducer::getPlusTerms(const Expr& e, Rational& known_term,
5021                                             ExprMap<Rational>& sumHashMap)
5022 {
5023   int bv_size = d_theoryBitvector->BVSize( e );
5024   Rational modulus = pow(Rational(bv_size), Rational(2));
5025   unsigned i;
5026   vector<Expr> plusTerms;
5027   vector<Rational> coeffs;
5028 
5029   plusTerms.push_back(e);
5030   coeffs.push_back(1);
5031   known_term = 0;
5032 
5033   for(i = 0; i < plusTerms.size(); ++i) {
5034     Expr kid = plusTerms[i];
5035     int kidSize = d_theoryBitvector->BVSize(kid);
5036     DebugAssert(kidSize <= bv_size, "Expected kid no wider than bv_size");
5037     Rational coeff = coeffs[i];
5038     if (coeff == 0) continue;
5039 
5040     switch (kid.getOpKind()) {
5041 
5042       case BVCONST:
5043         known_term += coeff * d_theoryBitvector->computeBVConst( kid );
5044         known_term = known_term % modulus;
5045         break;
5046 
5047       case BVUMINUS:
5048         DebugAssert(kidSize == bv_size, "Unexpected size for uminus");
5049         plusTerms.push_back(plusTerms[i][0]);
5050         coeffs.push_back((coeff * (modulus - 1)) % modulus);
5051         break;
5052 
5053       case BVNEG:
5054         if (kidSize < bv_size) {
5055           Rational m2 = pow(Rational(kidSize), Rational(2));
5056           known_term += coeff * (m2-1);
5057         }
5058         else {
5059           known_term += coeff * (modulus-1);
5060         }
5061         known_term = known_term % modulus;
5062         plusTerms.push_back(plusTerms[i][0]);
5063         coeffs.push_back((coeff * (modulus-1)) % modulus);
5064         break;
5065 
5066       case BVMULT:
5067         if (kidSize < bv_size) {
5068           int shift = 0;
5069           Rational tcoeff = coeff;
5070           for (; tcoeff % 2 == 0; ++shift, tcoeff = tcoeff / 2);
5071           if (shift + kidSize < bv_size) {
5072             // can't combine different sizes--
5073             // just insert it as is
5074             sumHashMap[ kid ] = sumHashMap[ kid ] + coeff;
5075             break;
5076           }
5077         }
5078         // OK to combine sizes
5079         if( kid[0].getOpKind() == BVCONST )
5080         {
5081           DebugAssert(kid.arity() == 2, "Expected arity 2 BVMULT");
5082           plusTerms.push_back(kid[1]);
5083           coeffs.push_back((coeff * d_theoryBitvector->computeBVConst(kid[0])) % modulus);
5084         }
5085         else
5086         {
5087           sumHashMap[ kid ] = sumHashMap[ kid ] + coeff;
5088         }
5089         break;
5090 
5091       case BVPLUS: {
5092         if (kidSize < bv_size) {
5093           int shift = 0;
5094           Rational tcoeff = coeff;
5095           for (; tcoeff % 2 == 0; ++shift, tcoeff = tcoeff / 2);
5096           if (shift + kidSize < bv_size) {
5097             // can't combine BVPLUSes of different size--
5098             // just insert it as is
5099             sumHashMap[ kid ] = sumHashMap[ kid ] + coeff;
5100             break;
5101           }
5102         }
5103         // OK to combine BVPLUS terms
5104         int kid_arity = kid.arity();
5105         for(int j = 0; j < kid_arity; ++j) {
5106           plusTerms.push_back(kid[j]);
5107           coeffs.push_back(coeff);
5108         }
5109         break;
5110       }
5111 
5112       case CONCAT: {
5113         // Convert CONCAT to BVPLUS
5114         int n = d_theoryBitvector->BVSize(kid);
5115         Rational concatConst;
5116         for (int j = 0; j < kid.arity(); ++j) {
5117           const Expr& concatKid = kid[j];
5118           n -= d_theoryBitvector->BVSize(concatKid);
5119           concatConst = pow(Rational(n), Rational(2)) * coeff;
5120           plusTerms.push_back(concatKid);
5121           coeffs.push_back(concatConst % modulus);
5122         }
5123         break;
5124       }
5125 
5126       case EXTRACT: {
5127         // TODO: maybe re-enable this in some cases, but it leads to simplification loops
5128         if (false && kidSize < bv_size) {
5129           // If the top part of a term is cut off with an extract, try to put it back
5130           const Expr& ext_kid = kid[0];
5131           int size = d_theoryBitvector->BVSize(ext_kid);
5132           int extractLeft = d_theoryBitvector->getExtractHi(kid);
5133           if (extractLeft < size-1) {
5134             int shift = 0;
5135             Rational tcoeff = coeff;
5136             for (; tcoeff % 2 == 0; ++shift, tcoeff = tcoeff / 2);
5137             if (shift + kidSize >= bv_size) {
5138               int bitsToAdd = bv_size - kidSize;
5139               extractLeft += bitsToAdd;
5140               if (extractLeft > size - 1) extractLeft = size - 1;
5141               int extractRight = d_theoryBitvector->getExtractLow(kid);
5142               if (extractLeft == size-1 && extractRight == 0) {
5143                 plusTerms.push_back(ext_kid);
5144                 coeffs.push_back(coeff);
5145               }
5146               else {
5147                 plusTerms.push_back(d_theoryBitvector->newBVExtractExpr(ext_kid, extractLeft, extractRight));
5148                 coeffs.push_back(coeff);
5149               }
5150               break;
5151             }
5152           }
5153           else {
5154             DebugAssert(d_theoryBitvector->getExtractLow(kid) != 0,
5155                         "Unexpected extract bounds");
5156           }
5157         }
5158         // fall through
5159       }
5160 
5161       default:
5162         sumHashMap[ kid] = sumHashMap[ kid] + coeff;
5163         break;
5164     }
5165   }
5166 }
5167 
5168 
chopConcat(int bv_size,Rational c,vector<Expr> & concatKids)5169 Expr BitvectorTheoremProducer::chopConcat(int bv_size, Rational c,
5170                                           vector<Expr>& concatKids)
5171 {
5172   int chopSize = bv_size;
5173 
5174   bool nonzero = false;
5175   bool nonconst = false;
5176   Expr term, kid, last;
5177   int size;
5178   unsigned i;
5179 
5180   for (i = 0; i< concatKids.size(); ++i) {
5181     kid = concatKids[i];
5182     if (kid.getOpKind() != CONCAT) return Expr();
5183 
5184     last = kid[kid.arity()-1];
5185     size = d_theoryBitvector->BVSize(last);
5186 
5187     // If the last concat kid is not a constant, then our only hope is to chop
5188     // it off exactly and hope that all other last concat kids are equal to
5189     // 0 and wider (in bits) than last
5190     if (last.getOpKind() != BVCONST) {
5191       if (nonzero || size > chopSize) return Expr();
5192       nonzero = true;
5193       nonconst = true;
5194       chopSize = size;
5195       term = last;
5196       continue;
5197     }
5198 
5199     // If last is a zero-string, then we are OK, as long as it's at least as
5200     // wide as any nonconst we have encountered.  If it's less wide than the
5201     // constants we have encountered so far, reduce chopSize accordingly
5202     if (d_theoryBitvector->computeBVConst(last) == 0) {
5203       if (size >= chopSize) continue;
5204       if (nonconst) return Expr();
5205       chopSize = size;
5206       continue;
5207     }
5208 
5209     // If last is a nonzero const, it's OK as long as it is the only nonzero
5210     // thing we encounter
5211     if (nonzero) return Expr();
5212     nonzero = true;
5213     if (size < chopSize) chopSize = size;
5214     term = last;
5215   }
5216 
5217   Rational modulus = pow(Rational(chopSize), Rational(2));
5218 
5219   // if nonzero exists, check the constant
5220   if (nonzero) {
5221     if (c != 0) {
5222       if ((c % modulus) != 0) return Expr();
5223       c = c / modulus;
5224     }
5225   }
5226   else if (c == 0) {
5227     term = d_theoryBitvector->newBVZeroString(chopSize);
5228   }
5229   else {
5230     Rational value = c % modulus;
5231     term = d_theoryBitvector->newBVConstExpr(value, chopSize);
5232     c = c - value;
5233     c = c / modulus;
5234   }
5235 
5236   // Now chop them
5237   for (i = 0; i < concatKids.size(); ++i) {
5238     kid = concatKids[i];
5239     vector<Expr> kids = kid.getKids();
5240     last = kids.back();
5241     kids.pop_back();
5242     size = d_theoryBitvector->BVSize(last);
5243 
5244     if (size != chopSize) {
5245       DebugAssert(size > chopSize, "Expected last to be wider than chopSize");
5246       DebugAssert(last.getOpKind() == BVCONST, "Expected last kind = BVCONST");
5247       Rational value = d_theoryBitvector->computeBVConst(last);
5248       if (value != 0) {
5249         value = value - (value % modulus);
5250         value = value / modulus;
5251       }
5252       kids.push_back(d_theoryBitvector->newBVConstExpr(value, size - chopSize));
5253     }
5254     DebugAssert(kids.size() > 0, "Expected size > 0");
5255     if (kids.size() == 1) {
5256       concatKids[i] = kids[0];
5257     }
5258     else {
5259       concatKids[i] = d_theoryBitvector->newConcatExpr(kids);
5260     }
5261   }
5262 
5263   if (d_theoryBitvector->BVSize(term) > chopSize) {
5264     DebugAssert(term.getOpKind() == BVCONST, "Expected BVCONST");
5265     Rational value = d_theoryBitvector->computeBVConst(term);
5266     DebugAssert(value != 0, "Expected 0");
5267     value = value % modulus;
5268     term = d_theoryBitvector->newBVConstExpr(value, chopSize);
5269   }
5270 
5271   Expr bvPlus = chopConcat(bv_size-chopSize, c, concatKids);
5272   if (!bvPlus.isNull()) {
5273     DebugAssert(bvPlus.getOpKind() == CONCAT, "Expected CONCAT");
5274     vector<Expr> kids = bvPlus.getKids();
5275     kids.push_back(term);
5276     return d_theoryBitvector->newConcatExpr(kids);
5277   }
5278 
5279   vector<Expr> newKids;
5280   if (c != 0) {
5281     newKids.push_back(d_theoryBitvector->newBVConstExpr(c, bv_size - chopSize));
5282   }
5283   for (i = 0; i < concatKids.size(); ++i) {
5284     newKids.push_back(concatKids[i]);
5285   }
5286   DebugAssert(newKids.size() > 1, "Expected more than one kid");
5287   bvPlus = d_theoryBitvector->newBVPlusExpr(bv_size-chopSize, newKids);
5288 
5289   // Make sure bvPlus is canonized
5290   ExprMap<Rational> sumHashMap;
5291   Rational known_term;
5292   getPlusTerms(bvPlus, known_term, sumHashMap);
5293   bvPlus = buildPlusTerm(bv_size-chopSize, known_term, sumHashMap);
5294   return d_theoryBitvector->newConcatExpr(bvPlus, term);
5295 }
5296 
5297 
buildPlusTerm(int bv_size,Rational & known_term,ExprMap<Rational> & sumHashMap)5298 Expr BitvectorTheoremProducer::buildPlusTerm(int bv_size,
5299                                              Rational& known_term,
5300                                              ExprMap<Rational>& sumHashMap)
5301 {
5302   // Try to convert into CONCATs
5303   Rational modulus = pow(Rational(bv_size), Rational(2));
5304   Rational coeff, pos;
5305   Rational tmask, tcoeff, marked = 0;
5306   int nbits, lg;
5307   ExprMap<Rational>::iterator j = sumHashMap.begin();
5308   vector<Expr> multKids, concatKids;
5309   unsigned i;
5310   for(; j != sumHashMap.end(); ++j) {
5311     coeff = mod((*j).second, modulus);
5312     Expr term = (*j).first;
5313     nbits = d_theoryBitvector->BVSize(term);
5314 
5315     // Fast case: coeff is 1 and term takes up all the bits
5316     if (coeff == 1 && nbits == bv_size) {
5317       if (nbits == 1 && known_term == 1) {
5318         // rewrite 1-bit x + 1 as ~x
5319         multKids.push_back(d_theoryBitvector->newBVNegExpr(term));
5320         known_term = 0;
5321       }
5322       else {
5323         multKids.push_back(term);
5324       }
5325       continue;
5326     }
5327 
5328     while (coeff != 0) {
5329 
5330       for (pos = coeff, lg = 0; pos % 2 == 0; pos = pos / 2, ++lg);
5331       pos = pow(Rational(lg), Rational(2));          // Position of lsb containing a 1
5332 
5333       Expr concatTerm;
5334 
5335       // pos of first bit beyond term
5336       Rational tmodulus = modulus;
5337       if (nbits+lg < bv_size) tmodulus = pow(Rational(nbits+lg), Rational(2));
5338       Rational tcoeff = coeff % tmodulus;
5339 
5340       if (tcoeff == pos) {
5341         coeff -= tcoeff;
5342         concatTerm = term;
5343       }
5344       else if (((tcoeff + pos) % tmodulus) == 0) {
5345         coeff = (coeff + pos) % modulus;
5346         // rewrite as bvneg
5347         concatTerm = d_theoryBitvector->newBVNegExpr(term);
5348         known_term += pos;
5349         if (nbits + lg < bv_size) {
5350           known_term += (modulus - tmodulus);
5351         }
5352         if (pos == 1 && nbits == bv_size) {
5353           multKids.push_back(concatTerm);
5354           continue;
5355         }
5356       }
5357       else {
5358         // create a BVMULT
5359         if (nbits + lg > bv_size) {
5360           // term is too big: chop it off
5361           int diff = nbits + lg - bv_size;
5362           int high, low;
5363           if (term.getOpKind() == EXTRACT) {
5364             // Collapse extract of extract
5365             high = d_theoryBitvector->getExtractHi(term) - diff;
5366             low = d_theoryBitvector->getExtractLow(term);
5367             term = term[0];
5368           }
5369           else {
5370             high = nbits - 1 - diff;
5371             low = 0;
5372           }
5373           term = d_theoryBitvector->newBVExtractExpr(term, high, low);
5374         }
5375         nbits = bv_size - lg;
5376         coeff = coeff / pos;
5377         Expr new_coeff = d_theoryBitvector->newBVConstExpr(coeff, nbits);
5378         term = d_theoryBitvector->newBVMultPadExpr(nbits, new_coeff, term);
5379         coeff = 0;
5380         if (lg == 0) {
5381           multKids.push_back(term);
5382           continue;
5383         }
5384         concatTerm = term;
5385       }
5386 
5387       // Insert concatTerm at position lg into a CONCAT
5388       bool found = false;
5389       Expr t;
5390       vector<Expr> tmp;
5391       int bits, size, k, t_arity;
5392       for (i = 0; i < concatKids.size(); ++i) {
5393         t = concatKids[i];
5394         DebugAssert(t.getOpKind() == CONCAT, "Expected CONCAT");
5395         bits = bv_size;
5396         t_arity = t.arity();
5397         for (k = 0; k < t_arity; ++k) {
5398           if (k > 0 && bits < lg + nbits) break;
5399           size = d_theoryBitvector->BVSize(t[k]);
5400           if (bits - size <= lg) {
5401             if (t[k].getOpKind() == BVCONST) {
5402               found = true;
5403             }
5404             break;
5405           }
5406           else {
5407             tmp.push_back(t[k]);
5408             bits -= size;
5409           }
5410         }
5411         if (found) break;
5412         tmp.clear();
5413       }
5414       if (!found) {
5415         bits = bv_size;
5416         size = bv_size;
5417         k = t_arity = 0;
5418       }
5419       if (lg + nbits < bits) {
5420         tmp.push_back(d_theoryBitvector->newBVZeroString(bits-(lg+nbits)));
5421       }
5422       if (lg + nbits > bits) {
5423         bool negate = false;
5424         if (concatTerm.getOpKind() == BVNEG) {
5425           // Push extract inside negation
5426           negate = true;
5427           concatTerm = concatTerm[0];
5428         }
5429         DebugAssert(!found || k == 0,
5430                     "Too big only OK for first child");
5431         // If term is too big, chop it off
5432         int diff = lg + nbits - bits;
5433         int high, low;
5434         if (concatTerm.getOpKind() == EXTRACT) {
5435           // Collapse extract of extract
5436           high = d_theoryBitvector->getExtractHi(concatTerm) - diff;
5437           low = d_theoryBitvector->getExtractLow(concatTerm);
5438           concatTerm = concatTerm[0];
5439         }
5440         else {
5441           high = nbits - 1 - diff;
5442           low = 0;
5443         }
5444         concatTerm = d_theoryBitvector->newBVExtractExpr(concatTerm, high, low);
5445         if (negate) {
5446           concatTerm = d_theoryBitvector->newBVNegExpr(concatTerm);
5447         }
5448       }
5449       tmp.push_back(concatTerm);
5450       bits -= size;
5451       if (lg > bits) {
5452         tmp.push_back(d_theoryBitvector->newBVZeroString(lg-bits));
5453       }
5454       for (++k; k < t_arity; ++k) {
5455         tmp.push_back(t[k]);
5456       }
5457 
5458       if (tmp.size() == 1) {
5459         DebugAssert(!found, "Invariant violated");
5460         multKids.push_back(tmp[0]);
5461       }
5462       else if (found) {
5463         // replace existing concat term
5464         concatKids[i] = d_theoryBitvector->newConcatExpr(tmp);
5465       }
5466       else {
5467         // push back new concat term
5468         concatKids.push_back(d_theoryBitvector->newConcatExpr(tmp));
5469       }
5470     }
5471   }
5472 
5473   known_term = known_term % modulus;
5474 
5475   // See if we can merge constant in with CONCATs
5476   if (known_term != 0 && !concatKids.empty()) {
5477     vector<Expr> tmp;
5478     for (i = 0; i < concatKids.size(); ++i) {
5479       Expr t = concatKids[i];
5480       DebugAssert(t.getOpKind() == CONCAT, "Expected CONCAT");
5481       int bits = bv_size;
5482       int size;
5483       bool anyChanged = false;
5484       for (int k = 0; k < t.arity(); ++k) {
5485         size = d_theoryBitvector->BVSize(t[k]);
5486         bool changed = false;
5487         if (known_term != 0 && t[k].getOpKind() == BVCONST) {
5488           Rational high = pow(Rational(bits), Rational(2));
5489           Rational partConst = known_term % high;
5490           if (partConst != 0) {
5491             Rational low = pow(Rational(bits - size), Rational(2));
5492             partConst = partConst - (partConst % low);
5493             if (partConst != 0) {
5494               anyChanged = changed = true;
5495               tmp.push_back(d_theoryBitvector->newBVConstExpr(partConst / low, size));
5496               known_term -= partConst;
5497             }
5498           }
5499         }
5500         if (!changed) {
5501           tmp.push_back(t[k]);
5502         }
5503         bits -= size;
5504       }
5505       if (anyChanged) {
5506         concatKids[i] = d_theoryBitvector->newConcatExpr(tmp);
5507         if (known_term == 0) break;
5508       }
5509       tmp.clear();
5510     }
5511   }
5512 
5513   // reassembling terms into a unique BVPLUS expression
5514   Expr expr_result;
5515 
5516   // Check to see if we can chop off the bottom of the BVPLUS
5517   if (multKids.size() == 0 &&
5518       (concatKids.size() > 1 ||
5519        (concatKids.size() == 1 && known_term != 0))) {
5520     expr_result = chopConcat(bv_size, known_term, concatKids);
5521     if (!expr_result.isNull()) return expr_result;
5522   }
5523 
5524   if (known_term == 0) {
5525     for (i = 0; i < concatKids.size(); ++i) {
5526       multKids.push_back(concatKids[i]);
5527     }
5528     if (multKids.size() == 0) {
5529       expr_result = d_theoryBitvector->newBVConstExpr( Rational(0), bv_size);
5530     }
5531     else if (multKids.size() == 1) {
5532       expr_result = multKids[0];
5533     }
5534     else {
5535       expr_result = d_theoryBitvector->newBVPlusExpr( bv_size, multKids);
5536     }
5537   }
5538   else {
5539     vector<Expr> sumKids;
5540     sumKids.push_back( d_theoryBitvector->newBVConstExpr( known_term, bv_size));
5541     for (i = 0; i < multKids.size(); ++i) {
5542       sumKids.push_back(multKids[i]);
5543     }
5544     for (i = 0; i < concatKids.size(); ++i) {
5545       sumKids.push_back(concatKids[i]);
5546     }
5547     if (sumKids.size() == 1) {
5548       expr_result = sumKids[0];
5549     }
5550     else {
5551       expr_result = d_theoryBitvector->newBVPlusExpr( bv_size, sumKids);
5552     }
5553   }
5554   return expr_result;
5555 }
5556 
5557 
5558 // It assumes that all the kids have already been canonized
canonBVPlus(const Expr & e)5559 Theorem BitvectorTheoremProducer::canonBVPlus( const Expr& e )
5560 {
5561   TRACE("canonBVPlus", "canonBVPlus: {\n    ", e.toString(), " --");
5562 
5563   if (CHECK_PROOFS)
5564     CHECK_SOUND(e.getOpKind() == BVPLUS,
5565 		"BitvectorTheoremProducer::canonBVPlus: input must be a BVPLUS expression" + e.toString());
5566 
5567   //  cout<<"BitvectorTheoremProducer::canonBVPlus, e is: "<<e.toString()<<endl;
5568   //! L:: to store the sum of the coefficients for each var
5569   ExprMap<Rational> sumHashMap;
5570   int bv_size = d_theoryBitvector->BVSize( e );
5571   Rational known_term;
5572 
5573   // Get plus terms in a hash map
5574   getPlusTerms(e, known_term, sumHashMap);
5575 
5576   // Build the plus term from known_term, sumHashMap
5577   Expr expr_result = buildPlusTerm(bv_size, known_term, sumHashMap);
5578 
5579   Proof pf;
5580   if (withProof()) pf = newPf("canonBVPlus");
5581   Theorem result = newRWTheorem( e, expr_result, Assumptions::emptyAssump(), pf);
5582   TRACE("canonBVPlus", "--> ", expr_result.toString(), "\n}");
5583   return result;
5584 }
5585 
5586 
canonBVUMinus(const Expr & e)5587 Theorem BitvectorTheoremProducer::canonBVUMinus( const Expr& e )
5588 {
5589   if (CHECK_PROOFS)
5590     CHECK_SOUND(e.getOpKind() == BVUMINUS,
5591 		"BitvectorTheoremProducer::canonBVUMinus: input must be a BVUMINUS expression" + e.toString());
5592 
5593   int bv_size = d_theoryBitvector->BVSize(e);
5594   Rational modulus = pow(Rational(bv_size), Rational(2));
5595   Expr coeff = d_theoryBitvector->newBVConstExpr(modulus-1, bv_size);
5596   Expr res_expr = d_theoryBitvector->newBVMultExpr(bv_size, coeff, e[0]);
5597   Proof pf;
5598   if (withProof()) pf = newPf("canonBVUMinus");
5599   return newRWTheorem(e, res_expr, Assumptions::emptyAssump(), pf);
5600 }
5601 /*End of Lorenzo PLatania's methods*/
5602 
5603 
5604 // Input: t[hi:lo] = rhs
5605 // if t appears as leaf in rhs, then:
5606 //    t[hi:lo] = rhs |- Exists x,y,z. (t = x \@ y \@ z AND y = rhs), solvedForm = false
5607 // else
5608 //    t[hi:lo] = rhs |- Exists x,z. (t = x \@ rhs \@ z), solvedForm = true
processExtract(const Theorem & e,bool & solvedForm)5609 Theorem BitvectorTheoremProducer::processExtract(const Theorem& e, bool& solvedForm)
5610 {
5611   Expr expr = e.getExpr();
5612 
5613   if (CHECK_PROOFS) {
5614     CHECK_SOUND(expr.getOpKind() == EQ && expr[0].getOpKind() == EXTRACT,
5615                 "BitvectorTheoremProducer::processExtract: invalid input");
5616     CHECK_SOUND(d_theoryBitvector->BVSize(expr[0]) == d_theoryBitvector->BVSize(expr[1]),
5617                 "Expected same size");
5618   }
5619 
5620   Expr ext = expr[0];
5621   Expr lhs;
5622   Expr rhs = expr[1];
5623   Expr child = ext[0];
5624   int size = d_theoryBitvector->BVSize(child);
5625   int high = d_theoryBitvector->getExtractHi(ext);
5626   int low  = d_theoryBitvector->getExtractLow(ext);
5627 
5628   DebugAssert(d_theoryBitvector->isLeaf(child), "Expected leaf");
5629   solvedForm = !d_theoryBitvector->isLeafIn(child, rhs);
5630 
5631   vector<Expr> terms;
5632   vector<Expr> boundVars;
5633   if (high < size-1) {
5634     terms.push_back(d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(size-1-high)));
5635     boundVars.push_back(terms.back());
5636   }
5637   if (solvedForm) terms.push_back(rhs);
5638   else {
5639     lhs = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(high-low+1));
5640     terms.push_back(lhs);
5641     boundVars.push_back(lhs);
5642   }
5643   if (low > 0) {
5644     terms.push_back(d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(low)));
5645     boundVars.push_back(terms.back());
5646   }
5647   DebugAssert(terms.size() > 1, "Expected at least two terms");
5648   Expr result = child.eqExpr(d_theoryBitvector->newConcatExpr(terms));
5649   if (!solvedForm) result = result && lhs.eqExpr(rhs);
5650   result = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, result);
5651   Assumptions a(e);
5652   Proof pf;
5653   if (withProof()) pf = newPf("processExtract");
5654   return newTheorem(result, a, pf);
5655 }
5656 
okToSplit(const Expr & e)5657 bool BitvectorTheoremProducer::okToSplit(const Expr& e)
5658 {
5659   if (d_theoryBitvector->isLeaf(e)) return true;
5660   switch (e.getOpKind()) {
5661     case BVCONST:
5662     case EXTRACT:
5663     case BVAND:
5664     case BVOR:
5665     case BVXOR:
5666     case BVNEG:
5667       return true;
5668     case BVSHL:
5669     case BVLSHR:
5670     case BVASHR:
5671     case BVPLUS:
5672     case BVMULT:
5673     case BVUDIV:
5674     case BVSDIV:
5675     case BVUREM:
5676     case BVSREM:
5677     case BVSMOD:
5678       return false;
5679     default:
5680       FatalAssert(false, "unexpected kind in okToSplit");
5681       break;
5682   }
5683   return false;
5684 }
5685 
5686 
5687 // puts the equation in solved form if possible, otherwise in the form
5688 // \sum a_i*x_i +c = 0.
5689 // default maxEffort is 3: solves only when lhs can be isolated without splitting
5690 // maxEffort 5: solves when lhs can be isolated with splitting
5691 // maxEffort 6: solves even when result is not in solved form (good for bitblasting)
canonBVEQ(const Expr & e,int maxEffort)5692 Theorem BitvectorTheoremProducer::canonBVEQ( const Expr& e, int maxEffort )
5693 {
5694   TRACE("canonBVEQ", "canonBVEQ: {\n    ", e.toString(), " --");
5695   DebugAssert(maxEffort == 3 || maxEffort == 5 || maxEffort == 6,
5696               "Unexpected value for maxEffort");
5697   if(CHECK_PROOFS) {
5698     CHECK_SOUND( e.getOpKind() == EQ,
5699                  "BitvectorTheoremProducer::canonBVEQ: expression must be an equation");
5700     CHECK_SOUND(BITVECTOR==e[0].getType().getExpr().getOpKind(),
5701 		"input must be a bitvector eqn. \n e = " + e.toString());
5702   }
5703 
5704   Expr lhs = e[0];
5705   Expr rhs = e[1];
5706   int bv_size = d_theoryBitvector->BVSize( lhs );
5707 
5708   // Look for easy split of concats
5709   if (lhs.getOpKind() == CONCAT || rhs.getOpKind() == CONCAT) {
5710     Expr::iterator lit, rit;
5711     int lsize, rsize;
5712     if (lhs.getOpKind() == CONCAT) {
5713       lit = e[0].begin();
5714     }
5715     else {
5716       lit = e.begin();
5717     }
5718     if (rhs.getOpKind() == CONCAT) {
5719       rit = e[1].begin();
5720     }
5721     else {
5722       rit = e.begin();
5723       ++rit;
5724     }
5725     int splitSize;
5726     lsize = d_theoryBitvector->BVSize(*lit);
5727     rsize = d_theoryBitvector->BVSize(*rit);
5728     while (true) {
5729       DebugAssert(lsize <= bv_size && rsize <= bv_size, "invariant violated");
5730       if (lsize < rsize) {
5731         if (okToSplit(*rit)) {
5732           splitSize = lsize;
5733           break;
5734         }
5735         else {
5736           ++lit;
5737           lsize += d_theoryBitvector->BVSize(*lit);
5738         }
5739       }
5740       else if (lsize > rsize) {
5741         if (okToSplit(*lit)) {
5742           splitSize = rsize;
5743           break;
5744         }
5745         else {
5746           ++rit;
5747           rsize += d_theoryBitvector->BVSize(*rit);
5748         }
5749       }
5750       else {
5751         splitSize = lsize;
5752         break;
5753       }
5754     }
5755     if (splitSize != bv_size) {
5756       Proof pf;
5757       if (withProof()) pf = newPf("canonBVEQ");
5758       Expr tmp = d_theoryBitvector->newBVExtractExpr(lhs, bv_size-1, bv_size-splitSize);
5759       tmp = tmp.eqExpr(d_theoryBitvector->newBVExtractExpr(rhs, bv_size-1, bv_size-splitSize));
5760       Expr expr_result = d_theoryBitvector->newBVExtractExpr(lhs, bv_size-splitSize-1, 0);
5761       expr_result = expr_result.eqExpr(d_theoryBitvector->newBVExtractExpr(rhs, bv_size-splitSize-1, 0));
5762       expr_result = tmp && expr_result;
5763       TRACE("canonBVEQ", "--> ", expr_result.toString(), "\n}");
5764       return newRWTheorem( e, expr_result, Assumptions::emptyAssump(), pf);
5765     }
5766   }
5767 
5768   rhs = d_theoryBitvector->newBVUminusExpr(rhs);
5769   ExprMap<Rational> sumHashMap;
5770   Rational modulus = pow(Rational(bv_size), Rational(2));
5771   Rational known_term;
5772 
5773   getPlusTerms(d_theoryBitvector->newBVPlusExpr(bv_size, lhs, rhs), known_term, sumHashMap);
5774 
5775   // Loop through all terms and perform two tasks:
5776   // A. Truncate coefficients
5777   // B. Look for a something to solve for:
5778   //    1. first choice: full-sized leaf not occurring elsewhere
5779   //    2. second choice: full-sized leaf inside BVXOR not occurring elsewhere
5780   //    3. third choice: full-sized extract of a leaf or over-sized leaf or extract of leaf
5781   //    4. fourth choice: under-sized leaf not occurring elsewhere or extract of leaf
5782   //    5. fifth choice: even-coeff leaf not occurring elsewhere or extract of leaf
5783   //    6. sixth choice: first term with an odd coeff (even if not a leaf or occurring elsewhere)
5784   //    7. seventh choice: nothing to solve for and all coeffs are even
5785 
5786   // If choice > maxEffort (and not 7), put in form sum = 0 instead.
5787 
5788   Rational coeff, foundCoeff = 1;
5789   ExprMap<Rational>::iterator j = sumHashMap.begin();
5790   ExprMap<Rational>::iterator fixCoeff = j;
5791   Expr xor_leaf, leaf, foundterm;
5792   unsigned xor_idx=0, xor_size=0;
5793   int priority, size, foundpriority = 7;
5794   bool isExtract;
5795   for(; j != sumHashMap.end(); ++j) {
5796     Expr t = (*j).first;
5797     coeff = (*j).second;
5798     size = d_theoryBitvector->BVSize(t);
5799     if (j == fixCoeff) {
5800       coeff = (*j).second = mod(coeff, modulus);
5801       ++fixCoeff;
5802     }
5803     if (coeff == 0) continue;
5804 
5805     priority = 7;
5806     isExtract = false;
5807     if (coeff % 2 == 1) {
5808       if (d_theoryBitvector->isLeaf(t)) {
5809         if (size == bv_size) {
5810           leaf = t; priority = 1;
5811         } else if (size > bv_size) {
5812           isExtract = true;
5813           leaf = t; priority = 3;
5814         } else {
5815           leaf = t; priority = 4;
5816         }
5817       } else if (t.getOpKind() == EXTRACT &&
5818                  d_theoryBitvector->isLeaf(t[0])) {
5819         isExtract = true;
5820         if (size >= bv_size) {
5821           leaf = t[0]; priority = 3;
5822         } else {
5823           leaf = t[0]; priority = 4;
5824         }
5825       } else if (t.getOpKind() == BVXOR && size == bv_size) {
5826         if (foundpriority == 2) continue;
5827         xor_idx = 0;
5828         xor_size = t.arity();
5829         for (xor_idx = 0; xor_idx < xor_size; ++xor_idx) {
5830           if (!d_theoryBitvector->isLeaf(t[xor_idx])) {
5831             continue;
5832           }
5833           unsigned l = 0;
5834           for (; l < xor_size; ++l) {
5835             if (l == xor_idx) continue;
5836             if (d_theoryBitvector->isLeafIn(t[xor_idx], t[l])) break;
5837           }
5838           if (l < xor_size) continue;
5839           break;
5840         }
5841         if (xor_idx < xor_size) {
5842           leaf = t[xor_idx];
5843           xor_leaf = leaf;
5844           priority = 2;
5845         }
5846         else {
5847           leaf = t; priority = 6;
5848         }
5849       }
5850       else {
5851         leaf = t; priority = 6;
5852       }
5853     } else if (maxEffort >= 5) {
5854       if (d_theoryBitvector->isLeaf(t)) {
5855         leaf = t; priority = 5;
5856       } else if (t.getOpKind() == EXTRACT &&
5857                  d_theoryBitvector->isLeaf(t[0])) {
5858         isExtract = true;
5859         leaf = t[0]; priority = 5;
5860       }
5861     }
5862 
5863     if (priority < foundpriority) {
5864       if (priority < 6) {
5865         ExprMap<Rational>::iterator k = sumHashMap.begin();
5866         while (k != sumHashMap.end()) {
5867           if (j == k) {
5868             ++k; continue;
5869           }
5870           if (k == fixCoeff) {
5871             (*k).second = mod((*k).second, modulus);
5872             ++fixCoeff;
5873           }
5874           if ((*k).second == 0) {
5875             ++k; continue;
5876           }
5877           if (!isExtract && d_theoryBitvector->isLeafIn(leaf, (*k).first)) {
5878             if (priority == 2) {
5879               // Try to find another leaf in the BVXOR
5880               for (++xor_idx; xor_idx < xor_size; ++xor_idx) {
5881                 if (!d_theoryBitvector->isLeaf(t[xor_idx])) {
5882                   continue;
5883                 }
5884                 unsigned l = 0;
5885                 for (; l < xor_size; ++l) {
5886                   if (l == xor_idx) continue;
5887                   if (d_theoryBitvector->isLeafIn(t[xor_idx], t[l])) break;
5888                 }
5889                 if (l < xor_size) continue;
5890                 break;
5891               }
5892               if (xor_idx < xor_size) {
5893                 // found a leaf, continue checking it
5894                 leaf = t[xor_idx];
5895                 xor_leaf = leaf;
5896                 k = sumHashMap.begin();
5897                 continue;
5898               }
5899             }
5900             // this leaf cannot be solved for
5901             break;
5902           }
5903           ++k;
5904         }
5905         if (k == sumHashMap.end()) {
5906           foundpriority = priority;
5907           foundterm = t;
5908           if (coeff == 1 || priority == 5) foundCoeff = 1;
5909           else foundCoeff = d_theoryBitvector->multiplicative_inverse(coeff, bv_size);
5910           if (priority == 1) break;
5911         }
5912       }
5913       if (foundpriority > 6 && priority != 5) {
5914         foundpriority = 6;
5915         foundterm = t;
5916         if (coeff == 1) foundCoeff = 1;
5917         else foundCoeff = d_theoryBitvector->multiplicative_inverse(coeff, bv_size);
5918       }
5919     }
5920   }
5921 
5922   bool solving = (foundpriority <= maxEffort);
5923 
5924   if (foundpriority == 7) {
5925     // All coeffs are even
5926     if (known_term % 2 == 1) {
5927       Proof pf;
5928       if (withProof()) pf = newPf("canonBVEQ");
5929       TRACE("canonBVEQ", "--> ", d_theoryBitvector->falseExpr().toString(), "\n}");
5930       return newRWTheorem(e, d_theoryBitvector->falseExpr(), Assumptions::emptyAssump(), pf);
5931     }
5932     else foundCoeff = foundCoeff / Rational(2);
5933     if (bv_size > 1) {
5934       bv_size = bv_size - 1;
5935       modulus = pow(Rational(bv_size), Rational(2));
5936     }
5937   }
5938   else if (!solving && (e[1] == d_theoryBitvector->newBVZeroString(bv_size))) {
5939     // if we aren't solving, and rhs was already 0, then stop here: lhs already normalized by plus canonizer
5940     // further rewriting risks a simplification loop
5941     TRACE("canonBVEQ", "--> ", e, "\n}");
5942     return newReflTheorem(e);
5943   }
5944 
5945   Rational solveCoeff = 0;
5946   // Multiply through by foundCoeff if it is not 1
5947   // Also, multiply by -1 (i.e. subtract from modulus) if solving
5948   if (solving || foundCoeff != 1) {
5949     known_term = (known_term * foundCoeff) % modulus;
5950     if (solving && known_term != 0)
5951       known_term = modulus - known_term;
5952     for(j = sumHashMap.begin(); j != sumHashMap.end(); ++j) {
5953       coeff = (*j).second;
5954       if (coeff == 0) continue;
5955       (*j).second = (coeff * foundCoeff) % modulus;
5956       if (solving) {
5957         if ((*j).first == foundterm) {
5958           // remove the leaf being solved for
5959           solveCoeff = (*j).second;
5960           (*j).second = 0;
5961         }
5962         else {
5963           (*j).second = modulus - (*j).second;
5964         }
5965       }
5966     }
5967   }
5968 
5969   // Collect the terms for the new bitplus term
5970   Expr plusTerm = buildPlusTerm(bv_size, known_term, sumHashMap);
5971 
5972   Expr new_lhs, new_rhs, expr_result;
5973   // Solve the equation
5974   if (solving) {
5975     DebugAssert(solveCoeff != 0, "Expected solveCoeff != 0");
5976     if (foundpriority == 6 && d_theoryBitvector->BVSize(foundterm) < bv_size) {
5977       // zero-extend to get the right size
5978       foundterm = d_theoryBitvector->pad(bv_size, foundterm);
5979     }
5980     switch (foundpriority) {
5981       case 1:
5982         // 1. first choice: full-sized leaf
5983         // foundterm is full-sized leaf
5984       case 6:
5985         //  6. sixth choice: Not in solved form, but isolate first term
5986         //  with odd coeff on lhs anyway.
5987         DebugAssert(solveCoeff == 1, "Expected coeff = 1");
5988         new_lhs = foundterm;
5989         new_rhs = plusTerm;
5990         break;
5991       case 2: {
5992         // 2. second choice: leaf inside BVXOR
5993         DebugAssert(solveCoeff == 1, "Expected coeff = 1");
5994         vector<Expr> rhsTerms;
5995         rhsTerms.push_back(plusTerm);
5996         for (unsigned l = 0; l < xor_size; ++l) {
5997           if (l == xor_idx) continue;
5998           rhsTerms.push_back(foundterm[l]);
5999         }
6000         new_lhs = xor_leaf;
6001         new_rhs = d_theoryBitvector->newBVXorExpr(rhsTerms);
6002         break;
6003       }
6004       case 3:
6005         // 3. third choice: full-sized extract of a leaf or over-sized leaf or extract of leaf
6006         // foundterm is full-sized extract of leaf
6007         DebugAssert(solveCoeff == 1, "Expected coeff = 1");
6008         if (d_theoryBitvector->BVSize(foundterm) > bv_size) {
6009           if (foundterm.getOpKind() == EXTRACT) {
6010             int diff = d_theoryBitvector->BVSize(foundterm) - bv_size;
6011             int high = d_theoryBitvector->getExtractHi(foundterm);
6012             int low  = d_theoryBitvector->getExtractLow(foundterm);
6013             foundterm = d_theoryBitvector->newBVExtractExpr(foundterm[0], high - diff, low);
6014           }
6015           else {
6016             foundterm = d_theoryBitvector->newBVExtractExpr(foundterm, bv_size-1, 0);
6017           }
6018         }
6019         new_lhs = foundterm;
6020         new_rhs = plusTerm;
6021         break;
6022       case 4: {
6023         // 4. fourth choice: under-sized leaf or extract of leaf
6024         // foundterm is less than full-sized extract or leaf
6025         DebugAssert(solveCoeff == 1, "Expected coeff = 1");
6026         int foundtermsize = d_theoryBitvector->BVSize(foundterm);
6027         DebugAssert(foundtermsize < bv_size, "Expected undersized term");
6028         new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, foundtermsize-1, 0);
6029         expr_result = foundterm.eqExpr(new_rhs);
6030         new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, bv_size-1, foundtermsize);
6031         new_lhs = d_theoryBitvector->newBVZeroString(bv_size - foundtermsize);
6032         expr_result = expr_result && new_lhs.eqExpr(new_rhs);
6033         break;
6034       }
6035       case 5: {
6036         // 5. fifth choice: even-coeff leaf or extract of leaf
6037         // foundterm has even coeff
6038         int lg = 0;
6039         for (; solveCoeff % 2 == 0; solveCoeff = solveCoeff / 2, ++lg);
6040         new_lhs = d_theoryBitvector->newBVConstExpr(solveCoeff, bv_size-lg);
6041         new_lhs = d_theoryBitvector->newBVMultPadExpr(bv_size-lg, new_lhs, foundterm);
6042         new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, bv_size-1, lg);
6043         expr_result = new_lhs.eqExpr(new_rhs);
6044         new_lhs = d_theoryBitvector->newBVZeroString(lg);
6045         new_rhs = d_theoryBitvector->newBVExtractExpr(plusTerm, lg - 1, 0);
6046         expr_result = expr_result && new_lhs.eqExpr(new_rhs);
6047         break;
6048       }
6049       default:
6050         FatalAssert(false, "Expected priority < 7");
6051         break;
6052     }
6053   }
6054   else {
6055     new_lhs = plusTerm;
6056     new_rhs = d_theoryBitvector->newBVZeroString(bv_size);
6057   }
6058 
6059   if (expr_result.isNull()) {
6060     if ( new_lhs == new_rhs) {
6061       expr_result = d_theoryBitvector->trueExpr();
6062     }
6063     else if ( new_lhs >= new_rhs) {
6064       expr_result =  Expr(EQ, new_lhs, new_rhs);
6065     }
6066     else {
6067       expr_result =  Expr(EQ, new_rhs, new_lhs);
6068     }
6069   }
6070 
6071   Proof pf;
6072   if (withProof()) pf = newPf("canonBVEQ");
6073   TRACE("canonBVEQ", "--> ", expr_result.toString(), "\n}");
6074   Theorem result = newRWTheorem( e, expr_result, Assumptions::emptyAssump(), pf);
6075   return result;
6076 }
6077 
6078 
6079 //! BVZEROEXTEND(e, i) = zeroString \@ e
6080 // where zeroString is a string of i zeroes
zeroExtendRule(const Expr & e)6081 Theorem BitvectorTheoremProducer::zeroExtendRule(const Expr& e) {
6082   if(CHECK_PROOFS) {
6083     CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(),
6084 		"input must be a bitvector. \n e = " + e.toString());
6085     CHECK_SOUND(BVZEROEXTEND == e.getOpKind(),
6086 		"input must be BVZEROEXTEND(e).\n e = " + e.toString());
6087   }
6088 
6089   int extendLen = d_theoryBitvector->getBVIndex(e);
6090   Expr res;
6091   if (extendLen == 0) {
6092     res = e[0];
6093   }
6094   else {
6095     Expr extend = d_theoryBitvector->newBVZeroString(extendLen);
6096     res = d_theoryBitvector->newConcatExpr(extend, e[0]);
6097   }
6098 
6099   Proof pf;
6100   if(withProof())
6101     pf = newPf("zero_extend_rule");
6102   Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf));
6103   return result;
6104 }
6105 
6106 
6107 //! BVREPEAT(e, i) = e \@ e \@ ... \@ e
6108 // where e appears i times on the right
repeatRule(const Expr & e)6109 Theorem BitvectorTheoremProducer::repeatRule(const Expr& e) {
6110   if(CHECK_PROOFS) {
6111     CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(),
6112 		"input must be a bitvector. \n e = " + e.toString());
6113     CHECK_SOUND(BVREPEAT == e.getOpKind(),
6114 		"input must be BVREPEAT(e).\n e = " + e.toString());
6115     CHECK_SOUND(d_theoryBitvector->getBVIndex(e) > 0,
6116                 "Expected positive repeat value");
6117   }
6118 
6119   int repeatVal = d_theoryBitvector->getBVIndex(e);
6120   Expr res;
6121   if (repeatVal == 1) {
6122     res = e[0];
6123   }
6124   else {
6125     vector<Expr> kids;
6126     for (int i = 0; i < repeatVal; ++i) {
6127       kids.push_back(e[0]);
6128     }
6129     res = d_theoryBitvector->newConcatExpr(kids);
6130   }
6131 
6132   Proof pf;
6133   if(withProof())
6134     pf = newPf("repeat_rule");
6135   Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf));
6136   return result;
6137 }
6138 
6139 
6140 //! BVROTL(e, i) = a[n-i-1:0] \@ a[n-1:n-i]
6141 // where n is the size of e and i is less than n (otherwise i mod n is used)
rotlRule(const Expr & e)6142 Theorem BitvectorTheoremProducer::rotlRule(const Expr& e) {
6143   if(CHECK_PROOFS) {
6144     CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(),
6145 		"input must be a bitvector. \n e = " + e.toString());
6146     CHECK_SOUND(BVROTL == e.getOpKind(),
6147 		"input must be BVROTL(e).\n e = " + e.toString());
6148   }
6149 
6150   int bvsize = d_theoryBitvector->BVSize(e);
6151   int rotation = d_theoryBitvector->getBVIndex(e);
6152   rotation = rotation % bvsize;
6153   Expr res;
6154   if (rotation == 0) {
6155     res = e[0];
6156   }
6157   else {
6158     Expr hi = d_theoryBitvector->newBVExtractExpr(e[0],bvsize-1-rotation,0);
6159     Expr low = d_theoryBitvector->newBVExtractExpr(e[0],bvsize-1, bvsize-rotation);
6160     res = d_theoryBitvector->newConcatExpr(hi, low);
6161   }
6162 
6163   Proof pf;
6164   if(withProof())
6165     pf = newPf("rotl_rule");
6166   Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf));
6167   return result;
6168 }
6169 
6170 
6171 //! BVROTR(e, i) = a[i-1:0] \@ a[n-1:i]
6172 // where n is the size of e and i is less than n (otherwise i mod n is used)
rotrRule(const Expr & e)6173 Theorem BitvectorTheoremProducer::rotrRule(const Expr& e) {
6174   if(CHECK_PROOFS) {
6175     CHECK_SOUND(BITVECTOR==e.getType().getExpr().getOpKind(),
6176 		"input must be a bitvector. \n e = " + e.toString());
6177     CHECK_SOUND(BVROTR == e.getOpKind(),
6178 		"input must be BVROTR(e).\n e = " + e.toString());
6179   }
6180 
6181   int bvsize = d_theoryBitvector->BVSize(e);
6182   int rotation = d_theoryBitvector->getBVIndex(e);
6183   rotation = rotation % bvsize;
6184   Expr res;
6185   if (rotation == 0) {
6186     res = e[0];
6187   }
6188   else {
6189     Expr hi = d_theoryBitvector->newBVExtractExpr(e[0],rotation-1,0);
6190     Expr low = d_theoryBitvector->newBVExtractExpr(e[0],bvsize-1, rotation);
6191     res = d_theoryBitvector->newConcatExpr(hi, low);
6192   }
6193 
6194   Proof pf;
6195   if(withProof())
6196     pf = newPf("rotr_rule");
6197   Theorem result(newRWTheorem(e, res, Assumptions::emptyAssump(), pf));
6198   return result;
6199 }
6200 
bvURemConst(const Expr & remExpr)6201 Theorem BitvectorTheoremProducer::bvURemConst(const Expr& remExpr) {
6202 	const Expr& a = remExpr[0];
6203 	const Expr& b = remExpr[1];
6204 	int size = d_theoryBitvector->BVSize(remExpr);
6205 
6206 	Rational a_value = d_theoryBitvector->computeBVConst(a);
6207 	Rational b_value = d_theoryBitvector->computeBVConst(b);
6208 
6209 	Expr rem;
6210 
6211 	if (b_value != 0) {
6212 		Rational rem_value = a_value - floor(a_value / b_value)*b_value;
6213 		rem = d_theoryBitvector->newBVConstExpr(rem_value, size);
6214 	} else {
6215 		static int div_by_zero_count = 0;
6216 		div_by_zero_count ++;
6217 		char var_name[10000];
6218 		sprintf(var_name, "mod_by_zero_const_%d", div_by_zero_count);
6219 		rem = d_theoryBitvector->newVar(var_name, remExpr.getType());
6220 	}
6221 
6222 	Proof pf;
6223 	if (withProof())
6224 		pf = newPf("bvUDivConst");
6225 
6226 	return newRWTheorem(remExpr, rem, Assumptions::emptyAssump(), pf);
6227 }
6228 
bvURemRewrite(const Expr & remExpr)6229 Theorem BitvectorTheoremProducer::bvURemRewrite(const Expr& remExpr) {
6230 	Expr a = remExpr[0];
6231 	Expr b = remExpr[1];
6232 	int size = d_theoryBitvector->BVSize(remExpr);
6233 	Expr div = d_theoryBitvector->newBVUDivExpr(a, b);
6234 
6235 	Expr rem = d_theoryBitvector->newBVSubExpr(a, d_theoryBitvector->newBVMultExpr(size, div, b));
6236 	Proof pf;
6237 	if (withProof())
6238 		pf = newPf("bvURemRewrite", remExpr);
6239 	return newRWTheorem(remExpr, rem, Assumptions::emptyAssump(), pf);
6240 }
6241 
6242 
bvUDivConst(const Expr & divExpr)6243 Theorem BitvectorTheoremProducer::bvUDivConst(const Expr& divExpr)
6244 {
6245 	const Expr& a = divExpr[0];
6246 	const Expr& b = divExpr[1];
6247 	int size = d_theoryBitvector->BVSize(divExpr);
6248 
6249     Rational a_value = d_theoryBitvector->computeBVConst(a);
6250     Rational b_value = d_theoryBitvector->computeBVConst(b);
6251 
6252     Expr div;
6253 
6254     if (b_value != 0) {
6255     	Rational div_value = floor(a_value / b_value);
6256     	div = d_theoryBitvector->newBVConstExpr(div_value, size);
6257     } else {
6258     	static int div_by_zero_count = 0;
6259     	div_by_zero_count ++;
6260     	char var_name[10000];
6261     	sprintf(var_name, "div_by_zero_const_%d", div_by_zero_count);
6262     	div = d_theoryBitvector->newVar(var_name, divExpr.getType());
6263     }
6264 
6265 	Proof pf;
6266 	if (withProof())
6267 		pf = newPf("bvUDivConst");
6268 
6269 	return newRWTheorem(divExpr, div, Assumptions::emptyAssump(), pf);
6270 }
6271 
bvUDivTheorem(const Expr & divExpr)6272 Theorem BitvectorTheoremProducer::bvUDivTheorem(const Expr& divExpr)
6273 {
6274 	int size = d_theoryBitvector->BVSize(divExpr);
6275 
6276 	if(CHECK_PROOFS) {
6277 		CHECK_SOUND(BITVECTOR == divExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + divExpr.toString());
6278 		CHECK_SOUND(BVUDIV == divExpr.getOpKind(),"input must be BVUDIV(e).\n e = " + divExpr.toString());
6279 	}
6280 
6281 	const Expr a = divExpr[0];
6282 	const Expr b = divExpr[1];
6283 
6284 
6285 	Type type = divExpr.getType();
6286 	Expr div = d_theoryBitvector->getEM()->newBoundVarExpr(type);
6287 	Expr mod = d_theoryBitvector->getEM()->newBoundVarExpr(type);
6288 	vector<Expr> boundVars;
6289 	boundVars.push_back(div);
6290 	boundVars.push_back(mod);
6291 
6292 	vector<Expr> assertions;
6293 	Expr pad          = d_theoryBitvector->newBVConstExpr(Rational(0), size);
6294 	Expr a_expanded   = d_theoryBitvector->newConcatExpr(pad, a);
6295 	Expr b_expanded   = d_theoryBitvector->newConcatExpr(pad, b);
6296 	Expr div_expanded = d_theoryBitvector->newConcatExpr(pad, div);
6297 	Expr mod_expanded = d_theoryBitvector->newConcatExpr(pad, mod);
6298 	assertions.push_back(a_expanded.eqExpr(
6299 			d_theoryBitvector->newBVPlusExpr(2*size,
6300 					d_theoryBitvector->newBVMultExpr(2*size, b_expanded, div_expanded),
6301 					mod_expanded
6302 				)
6303 			)
6304 		);
6305 	assertions.push_back(d_theoryBitvector->newBVLTExpr(mod, b));
6306 
6307 	Expr non_zero_div = andExpr(assertions);
6308 	// b != 0 -> a = b*div + mod ...
6309 	Expr complete_div = (b.eqExpr(d_theoryBitvector->newBVConstExpr(Rational(0), size))).negate().impExpr(non_zero_div);
6310 	// x/y = div \wedge complete_div
6311 	complete_div = divExpr.eqExpr(div).andExpr(complete_div);
6312 	// Close the result
6313 	Expr result = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, complete_div);
6314 
6315 	// Make the proof
6316 	Proof pf;
6317 	if (withProof())
6318 		pf = newPf("bvUDiv");
6319 
6320 	// Return the theorem
6321 	return newTheorem(result, Assumptions::emptyAssump(), pf);
6322 }
6323 
bitblastBVMult(const std::vector<Theorem> & a_bits,const std::vector<Theorem> & b_bits,const Expr & a_times_b,std::vector<Theorem> & output_bits)6324 Theorem BitvectorTheoremProducer::bitblastBVMult(const std::vector<Theorem>& a_bits, const std::vector<Theorem>& b_bits,
6325     		                            const Expr& a_times_b, std::vector<Theorem>& output_bits)
6326 {
6327 	if(CHECK_PROOFS) {
6328 		CHECK_SOUND(a_times_b.arity() == 2, "must be a binary multiplication");
6329 		CHECK_SOUND(BITVECTOR == a_times_b.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + a_times_b.toString());
6330 		CHECK_SOUND(BVMULT == a_times_b.getOpKind(),"input must be BVMULT(e).\n e = " + a_times_b.toString());
6331 		CHECK_SOUND(a_bits.size() == b_bits.size(), "given bit expansions of different size");
6332 		CHECK_SOUND((int) a_bits.size() <= d_theoryBitvector->BVSize(a_times_b), "the expansion is bigger than the multiplier");
6333 	}
6334 
6335 	int size = a_bits.size();
6336 	Expr falseExpr = d_theoryBitvector->falseExpr();
6337 
6338 //  DISABLED FOR NOW, WE ARENT ENSURING THAT ALL TERMS THAT ENTER BITBLASTING
6339 //  ARE NON-ZERO
6340 //	if (CHECK_PROOFS) {
6341 //          bool all_zero = true;
6342 //          Expr a = a_times_b[0];
6343 //          for (int bit = 0; bit < size; bit++) {
6344 //            Theorem bit_i = a_bits[bit];
6345 //            Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(a, bit);
6346 //            CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems");
6347 //            if (bit_i.getRHS() != falseExpr) all_zero = false;
6348 //          }
6349 //          CHECK_SOUND(!all_zero, "expected non-zero inputs");
6350 //          all_zero = true;
6351 //          Expr b = a_times_b[1];
6352 //          for (int bit = 0; bit < size; bit++) {
6353 //            Theorem bit_i = b_bits[bit];
6354 //            Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(b, bit);
6355 //            CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems");
6356 //            if (bit_i.getRHS() != falseExpr) all_zero = false;
6357 //          }
6358 //          CHECK_SOUND(!all_zero, "expected non-zero inputs");
6359 //	}
6360 
6361 	vector<Expr> sum_bits;
6362 	vector<Expr> carry_bits;
6363 
6364 	// Find the first non-zero bits in a and b
6365 	int a_bit, b_bit;
6366 	for (a_bit = size - 1; a_bit >= 0 && a_bits[a_bit].getRHS() == falseExpr; a_bit --);
6367 	for (b_bit = size - 1; b_bit >= 0 && b_bits[b_bit].getRHS() == falseExpr; b_bit --);
6368 //  DISABLED, SAME AS ABOVE
6369 //	DebugAssert(a_bit >= 0 && b_bit >= 0, "Expected non-zero inputs");
6370 
6371 	int new_size = size;
6372     if (a_bit + b_bit + 2 < new_size) new_size = a_bit + b_bit + 2;
6373 
6374 	// Build the first row of the multiplier
6375 	for (int i = 0; i < new_size; i ++) {
6376 		sum_bits.push_back(a_bits[i].getRHS().andExpr(b_bits[0].getRHS()));
6377 		carry_bits.push_back(d_theoryBitvector->falseExpr());
6378 	}
6379 
6380 	// Now go down the rows
6381 	Expr carry = d_theoryBitvector->falseExpr();
6382 	for (int row = 1; row < new_size; row ++) {
6383 		for (int bit = new_size-1; bit >= row; bit --) {
6384 			Expr m = a_bits[bit-row].getRHS().andExpr(b_bits[row].getRHS());
6385 			Expr sum = sum_bits[bit].iffExpr(m).iffExpr(carry_bits[bit - 1]);
6386 			Expr carry = sum_bits[bit].andExpr(m).orExpr(carry_bits[bit - 1].andExpr(sum_bits[bit].orExpr(m)));
6387 			sum_bits[bit] = sum;
6388 			carry_bits[bit] = carry;
6389 		}
6390 		// The carry on the side of the multiplier
6391 		carry = carry.orExpr(carry_bits[new_size - 1]);
6392 	}
6393 
6394 	// Create all the theorems now
6395 	for (int bit = 0; bit < size; bit ++) {
6396 		Proof pf;
6397 		if (withProof()) {
6398 			pf = newPf("bitblastBVMult", a_times_b, rat(bit));
6399 		}
6400 		output_bits.push_back(newRWTheorem(d_theoryBitvector->newBoolExtractExpr(a_times_b, bit), bit < new_size ? sum_bits[bit] : falseExpr, Assumptions::emptyAssump(), pf));
6401 	}
6402 
6403 	Theorem carry_thm;
6404 	return carry_thm;
6405 }
6406 
bitblastBVPlus(const std::vector<Theorem> & a_bits,const std::vector<Theorem> & b_bits,const Expr & a_plus_b,std::vector<Theorem> & output_bits)6407 Theorem BitvectorTheoremProducer::bitblastBVPlus(const std::vector<Theorem>& a_bits, const std::vector<Theorem>& b_bits,
6408                                                  const Expr& a_plus_b, std::vector<Theorem>& output_bits)
6409 {
6410 	if(CHECK_PROOFS) {
6411 		CHECK_SOUND(a_plus_b.arity() == 2, "must be a binary addition");
6412 		CHECK_SOUND(BITVECTOR == a_plus_b.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + a_plus_b.toString());
6413 		CHECK_SOUND(BVPLUS == a_plus_b.getOpKind(),"input must be BVPLUS(e).\n e = " + a_plus_b.toString());
6414 		CHECK_SOUND(a_bits.size() == b_bits.size(), "given bit expansions of different size");
6415 		CHECK_SOUND((int) a_bits.size() <= d_theoryBitvector->BVSize(a_plus_b), "the expansion is bigger than the multiplier");
6416 	}
6417 
6418 	int size = a_bits.size();
6419 
6420 	if (CHECK_PROOFS) {
6421 		Expr a = a_plus_b[0];
6422 		for (int bit = 0; bit < size; bit++) {
6423 			Theorem bit_i = a_bits[bit];
6424 			Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(a, bit);
6425 			CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems");
6426 		}
6427 		Expr b = a_plus_b[1];
6428 		for (int bit = 0; bit < size; bit++) {
6429 			Theorem bit_i = b_bits[bit];
6430 			Expr bit_extract = d_theoryBitvector->newBoolExtractExpr(b, bit);
6431 			CHECK_SOUND(bit_extract == bit_i.getLHS(), "not the right bit theorems");
6432 		}
6433 	}
6434 
6435 	vector<Expr> sum_bits;
6436 
6437 	Expr carry = d_theoryBitvector->falseExpr();
6438 	for (int i = 0; i < size; i ++)
6439 	{
6440 		Expr a_i = a_bits[i].getRHS();
6441 		Expr b_i = b_bits[i].getRHS();
6442 		sum_bits.push_back(a_i.iffExpr(b_i).iffExpr(carry));
6443 		carry = a_i.andExpr(b_i).orExpr(carry.andExpr(a_i.orExpr(b_i)));
6444 	}
6445 
6446 	// Create all the theorems now
6447 	for (int bit = 0; bit < size; bit ++) {
6448 		Proof pf;
6449 		if (withProof()) {
6450 			pf = newPf("bitblastBVPlus", a_plus_b, rat(bit));
6451 		}
6452 		output_bits.push_back(newRWTheorem(d_theoryBitvector->newBoolExtractExpr(a_plus_b, bit), sum_bits[bit], Assumptions::emptyAssump(), pf));
6453 	}
6454 
6455 	Theorem carry_thm;
6456 	return carry_thm;
6457 }
6458 
6459 /**
6460  * Rewrite the signed divide in terms of the unsigned one.
6461  */
bvSDivRewrite(const Expr & sDivExpr)6462 Theorem BitvectorTheoremProducer::bvSDivRewrite(const Expr& sDivExpr)
6463 {
6464 	if(CHECK_PROOFS) {
6465 		CHECK_SOUND(BITVECTOR == sDivExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + sDivExpr.toString());
6466 		CHECK_SOUND(BVSDIV == sDivExpr.getOpKind(),"input must be BVSDIV(e).\n e = " + sDivExpr.toString());
6467 	}
6468 
6469 	int m      = d_theoryBitvector->BVSize(sDivExpr);
6470 
6471 	Proof pf;
6472 	if (withProof()) pf = newPf("bvSDivRewrite", sDivExpr);
6473 
6474 	//	(bvsdiv s t) abbreviates
6475 	//	      (let (?msb_s (extract[|m-1|:|m-1|] s))
6476 	//	      (let (?msb_t (extract[|m-1|:|m-1|] t))
6477 	//	      (ite (and (= ?msb_s bit0) (= ?msb_t bit0)) ---------> cond1
6478 	//	           (bvudiv s t)
6479 	//	      (ite (and (= ?msb_s bit1) (= ?msb_t bit0)) ---------> cond2
6480 	//	           (bvneg (bvudiv (bvneg s) t))
6481 	//	      (ite (and (= ?msb_s bit0) (= ?msb_t bit1)) ---------> cond3
6482 	//	           (bvneg (bvudiv s (bvneg t)))
6483 	//	           (bvudiv (bvneg s) (bvneg t)))))))
6484 
6485 	Expr s     = sDivExpr[0];
6486 	Expr t     = sDivExpr[1];
6487 
6488 	Expr s_neg = d_theoryBitvector->newBVUminusExpr(s);
6489 	Expr t_neg = d_theoryBitvector->newBVUminusExpr(t);
6490 
6491 	Expr msb_s = d_theoryBitvector->newBVExtractExpr(s, m-1, m-1);
6492 	Expr msb_t = d_theoryBitvector->newBVExtractExpr(t, m-1, m-1);
6493 
6494 	Expr bit0  = d_theoryBitvector->newBVConstExpr(Rational(0), 1);
6495 	Expr bit1  = d_theoryBitvector->newBVConstExpr(Rational(1), 1);
6496 
6497 	Expr cond1 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit0));
6498 	Expr cond2 = msb_s.eqExpr(bit1).andExpr(msb_t.eqExpr(bit0));
6499 	Expr cond3 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit1));
6500 
6501 	Expr result = cond1.iteExpr(
6502 				d_theoryBitvector->newBVUDivExpr(s, t),
6503 				cond2.iteExpr(
6504 						d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVUDivExpr(s_neg, t)),
6505 						cond3.iteExpr(
6506 								d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVUDivExpr(s, t_neg)),
6507 								d_theoryBitvector->newBVUDivExpr(s_neg, t_neg)
6508 								)
6509 						)
6510 			);
6511 
6512 	return newRWTheorem(sDivExpr, result, Assumptions::emptyAssump(), pf);
6513 }
6514 
6515 /**
6516  * Rewrite the signed remainder in terms of the unsigned one.
6517  */
bvSRemRewrite(const Expr & sRemExpr)6518 Theorem BitvectorTheoremProducer::bvSRemRewrite(const Expr& sRemExpr)
6519 {
6520 	if(CHECK_PROOFS) {
6521 		CHECK_SOUND(BITVECTOR == sRemExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + sRemExpr.toString());
6522 		CHECK_SOUND(BVSREM == sRemExpr.getOpKind(),"input must be BVSDIV(e).\n e = " + sRemExpr.toString());
6523 	}
6524 
6525 	int m      = d_theoryBitvector->BVSize(sRemExpr);
6526 
6527 	Proof pf;
6528 	if (withProof()) pf = newPf("bvSRemRewrite", sRemExpr);
6529 
6530 	//    (bvsrem s t) abbreviates
6531 	//	      (let (?msb_s (extract[|m-1|:|m-1|] s))
6532 	//	      (let (?msb_t (extract[|m-1|:|m-1|] t))
6533 	//	      (ite (and (= ?msb_s bit0) (= ?msb_t bit0))
6534 	//	           (bvurem s t)
6535 	//	      (ite (and (= ?msb_s bit1) (= ?msb_t bit0))
6536 	//	           (bvneg (bvurem (bvneg s) t))
6537 	//	      (ite (and (= ?msb_s bit0) (= ?msb_t bit1))
6538 	//	           (bvurem s (bvneg t))
6539 	//	           (bvneg (bvurem (bvneg s) (bvneg t))))))))
6540 
6541 	Expr s     = sRemExpr[0];
6542 	Expr t     = sRemExpr[1];
6543 
6544 	Expr s_neg = d_theoryBitvector->newBVUminusExpr(s);
6545 	Expr t_neg = d_theoryBitvector->newBVUminusExpr(t);
6546 
6547 	Expr msb_s = d_theoryBitvector->newBVExtractExpr(s, m-1, m-1);
6548 	Expr msb_t = d_theoryBitvector->newBVExtractExpr(t, m-1, m-1);
6549 
6550 	Expr bit0  = d_theoryBitvector->newBVConstExpr(Rational(0), 1);
6551 	Expr bit1  = d_theoryBitvector->newBVConstExpr(Rational(1), 1);
6552 
6553 	Expr cond1 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit0));
6554 	Expr cond2 = msb_s.eqExpr(bit1).andExpr(msb_t.eqExpr(bit0));
6555 	Expr cond3 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit1));
6556 
6557 	Expr result = cond1.iteExpr(
6558 				d_theoryBitvector->newBVURemExpr(s, t),
6559 				cond2.iteExpr(
6560 						d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVURemExpr(s_neg, t)),
6561 						cond3.iteExpr(
6562 								d_theoryBitvector->newBVURemExpr(s, t_neg),
6563 								d_theoryBitvector->newBVUminusExpr(d_theoryBitvector->newBVURemExpr(s_neg, t_neg))
6564 								)
6565 						)
6566 			);
6567 
6568 	return newRWTheorem(sRemExpr, result, Assumptions::emptyAssump(), pf);
6569 }
6570 
6571 /**
6572  * Rewrite the signed mod in terms of the unsigned one.
6573  */
bvSModRewrite(const Expr & sModExpr)6574 Theorem BitvectorTheoremProducer::bvSModRewrite(const Expr& sModExpr)
6575 {
6576 	if(CHECK_PROOFS) {
6577 		CHECK_SOUND(BITVECTOR == sModExpr.getType().getExpr().getOpKind(), "input must be a bitvector. \n e = " + sModExpr.toString());
6578 		CHECK_SOUND(BVSMOD == sModExpr.getOpKind(),"input must be BVSDIV(e).\n e = " + sModExpr.toString());
6579 	}
6580 
6581 	int m      = d_theoryBitvector->BVSize(sModExpr);
6582 
6583 	Proof pf;
6584 	if (withProof()) pf = newPf("bvSModRewrite", sModExpr);
6585 
6586         // (bvsmod s t) abbreviates
6587         //     (let ((?msb_s ((_ extract |m-1| |m-1|) s))
6588         //           (?msb_t ((_ extract |m-1| |m-1|) t)))
6589         //       (let ((abs_s (ite (= ?msb_s #b0) s (bvneg s)))
6590         //             (abs_t (ite (= ?msb_t #b0) t (bvneg t))))
6591         //         (let ((u (bvurem abs_s abs_t)))
6592         //           (ite (= u (_ bv0 m))
6593         //                u
6594         //           (ite (and (= ?msb_s #b0) (= ?msb_t #b0))
6595         //                u
6596         //           (ite (and (= ?msb_s #b1) (= ?msb_t #b0))
6597         //                (bvadd (bvneg u) t)
6598         //           (ite (and (= ?msb_s #b0) (= ?msb_t #b1))
6599         //                (bvadd u t)
6600         //                (bvneg u))))))))
6601 
6602 	Expr s     = sModExpr[0];
6603 	Expr t     = sModExpr[1];
6604 
6605 	Expr msb_s = d_theoryBitvector->newBVExtractExpr(s, m-1, m-1);
6606 	Expr msb_t = d_theoryBitvector->newBVExtractExpr(t, m-1, m-1);
6607 
6608 	Expr bit0  = d_theoryBitvector->newBVConstExpr(Rational(0), 1);
6609 	Expr bit1  = d_theoryBitvector->newBVConstExpr(Rational(1), 1);
6610 
6611 	Expr abs_s = msb_s.eqExpr(bit0).iteExpr(s, d_theoryBitvector->newBVUminusExpr(s));
6612 	Expr abs_t = msb_t.eqExpr(bit0).iteExpr(t, d_theoryBitvector->newBVUminusExpr(t));
6613 
6614         Expr u = d_theoryBitvector->newBVURemExpr(abs_s, abs_t);
6615 
6616 	Expr cond0 = u.eqExpr(d_theoryBitvector->newBVConstExpr(Rational(0), m));
6617 	Expr cond1 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit0));
6618 	Expr cond2 = msb_s.eqExpr(bit1).andExpr(msb_t.eqExpr(bit0));
6619 	Expr cond3 = msb_s.eqExpr(bit0).andExpr(msb_t.eqExpr(bit1));
6620 
6621         Expr result = cond0.iteExpr(u,
6622                       cond1.iteExpr(u,
6623                       cond2.iteExpr(
6624                                     d_theoryBitvector->newBVPlusExpr(m, d_theoryBitvector->newBVUminusExpr(u), t),
6625                       cond3.iteExpr(d_theoryBitvector->newBVPlusExpr(m, u, t),
6626                                     d_theoryBitvector->newBVUminusExpr(u)))));
6627 
6628 	return newRWTheorem(sModExpr, result, Assumptions::emptyAssump(), pf);
6629 }
6630 
zeroBVOR(const Expr & orEqZero)6631 Theorem BitvectorTheoremProducer::zeroBVOR(const Expr& orEqZero)
6632 {
6633 	if(CHECK_PROOFS) {
6634 		CHECK_SOUND(orEqZero.isEq(), "input must be an equality. \n e = " + orEqZero.toString());
6635 		CHECK_SOUND(orEqZero[0].getKind() == BVOR, "left-hand side must be a bitwise or. \n e = " + orEqZero.toString());
6636 		CHECK_SOUND(orEqZero[1].getKind() == BVCONST, "right-hand side must be a constant or. \n e = " + orEqZero.toString());
6637 		CHECK_SOUND(d_theoryBitvector->computeBVConst(orEqZero[1]) == 0, "right-hand side must be 0. \n e = " + orEqZero.toString());
6638 	}
6639 
6640 	vector<Expr> conjuncts;
6641 
6642 	for (int disjunct = 0; disjunct < orEqZero[0].arity(); disjunct ++)
6643 		conjuncts.push_back(orEqZero[0][disjunct].eqExpr(orEqZero[1]));
6644 
6645 	Expr result = andExpr(conjuncts);
6646 
6647 	Proof pf;
6648 	if (withProof()) pf = newPf("zeroBVOR", orEqZero);
6649 
6650 	return newRWTheorem(orEqZero, result, Assumptions::emptyAssump(), pf);
6651 }
6652 
oneBVAND(const Expr & andEqOne)6653 Theorem BitvectorTheoremProducer::oneBVAND(const Expr& andEqOne)
6654 {
6655 	if(CHECK_PROOFS) {
6656 		CHECK_SOUND(andEqOne.isEq(), "input must be an equality. \n e = " + andEqOne.toString());
6657 		CHECK_SOUND(andEqOne[0].getKind() == BVAND, "left-hand side must be a bitwise and. \n e = " + andEqOne.toString());
6658 		CHECK_SOUND(andEqOne[1].getKind() == BVCONST, "right-hand side must be a constant or. \n e = " + andEqOne.toString());
6659 		CHECK_SOUND(d_theoryBitvector->computeBVConst(andEqOne[1]) == pow(d_theoryBitvector->BVSize(andEqOne[1]), (Unsigned)2) - 1, "right-hand side must be 1^n. \n e = " + andEqOne.toString());
6660 	}
6661 
6662 	vector<Expr> conjuncts;
6663 
6664 	for (int conjunct = 0; conjunct < andEqOne[0].arity(); conjunct ++)
6665 		conjuncts.push_back(andEqOne[0][conjunct].eqExpr(andEqOne[1]));
6666 
6667 	Expr result = andExpr(conjuncts);
6668 
6669 	Proof pf;
6670 	if (withProof()) pf = newPf("oneBVAND", andEqOne);
6671 
6672 	return newRWTheorem(andEqOne, result, Assumptions::emptyAssump(), pf);
6673 }
6674 
constEq(const Expr & eq)6675 Theorem BitvectorTheoremProducer::constEq(const Expr& eq)
6676 {
6677 	if(CHECK_PROOFS) {
6678 		CHECK_SOUND(eq.isEq(), "input must be an equality. \n e = " + eq.toString());
6679 		CHECK_SOUND(eq[0].getKind() == BVCONST, "left-hand side must be a constant. \n e = " + eq.toString());
6680 		CHECK_SOUND(eq[1].getKind() == BVCONST, "right-hand side must be a constant. \n e = " + eq.toString());
6681 	}
6682 
6683 	Expr result = eq[0] == eq[1] ? d_theoryBitvector->trueExpr() : d_theoryBitvector->falseExpr();
6684 
6685 	Proof pf;
6686 	if (withProof()) pf = newPf("constEq", eq);
6687 
6688 	return newRWTheorem(eq, result, Assumptions::emptyAssump(), pf);
6689 }
6690 
solveExtractOverlapApplies(const Expr & eq)6691 bool BitvectorTheoremProducer::solveExtractOverlapApplies(const Expr& eq)
6692 {
6693   // Both sides should be an extract
6694   if (eq[0].getOpKind() != EXTRACT) return false;
6695   if (eq[1].getOpKind() != EXTRACT) return false;
6696   // Terms under extract should be identical
6697   if (eq[0][0] != eq[1][0]) return false;
6698   // We have x[i:j] == x[k:l]
6699   int i = d_theoryBitvector->getExtractHi(eq[0]);
6700   int j = d_theoryBitvector->getExtractLow(eq[0]);
6701   int k = d_theoryBitvector->getExtractHi(eq[1]);
6702   int l = d_theoryBitvector->getExtractLow(eq[1]);
6703   // They can't be equal, so we either have
6704   // i > k >= j > l or
6705   // k > i >= l > j
6706   if (i == k) return false;
6707   else if (i > k)
6708     return (k >= j && j > l);
6709   else
6710     return (i >= l && l > j);
6711 }
6712 
solveExtractOverlap(const Expr & eq)6713 Theorem BitvectorTheoremProducer::solveExtractOverlap(const Expr& eq)
6714 {
6715   Expr res;
6716 
6717   if (CHECK_PROOFS)
6718     CHECK_SOUND(solveExtractOverlapApplies(eq), "solveExtractOvelap does not apply to " + eq.toString());
6719 
6720   // Left and right side of the equation
6721   Expr lhs = eq[0];
6722   Expr rhs = eq[1];
6723 
6724   // We have x[i:j] == x[k:l]
6725   int i = d_theoryBitvector->getExtractHi(lhs);
6726   int j = d_theoryBitvector->getExtractLow(lhs);
6727   int k = d_theoryBitvector->getExtractHi(rhs);
6728   int l = d_theoryBitvector->getExtractLow(rhs);
6729 
6730   // We only do case where i > k
6731   if (i > k)
6732   {
6733     vector<Expr> terms;
6734     vector<Expr> boundVars;
6735 
6736     // Get the term
6737     Expr x = lhs[0];
6738     int x_size = d_theoryBitvector->BVSize(x);
6739 
6740     // If there is a initial part of x, put it in
6741     if (i < x_size - 1) {
6742       Expr x_begin = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(x_size - i - 1));
6743       terms.push_back(x_begin);
6744       boundVars.push_back(x_begin);
6745     }
6746 
6747     if (2*k + 1 <= i + j)
6748     {
6749       // Case when the overlap is smaller then the rest
6750       //     i                k   j                l
6751       // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6752       // xxxxAAAAABBBBBBBBBBBBAAAAABBBBBBBBBBBBAAAAAxxxxx
6753       //       a       b        c        d       e
6754       int o_size = k - j + 1; // Overlap size
6755       bool no_rest = (2*k + 1 == i + j);
6756 
6757       // Make The a = c = e expression
6758       Expr a = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(o_size));
6759       boundVars.push_back(a);
6760       terms.push_back(a);
6761 
6762       if (no_rest) {
6763         // c and e
6764         terms.push_back(a);
6765         terms.push_back(a);
6766       } else {
6767         // Make the b = d expression
6768         Expr b = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(i - k - o_size));
6769         boundVars.push_back(b);
6770         terms.push_back(b);
6771         terms.push_back(a);
6772         terms.push_back(b);
6773         terms.push_back(a);
6774       }
6775     }
6776     else
6777     {
6778       // Case when the overlap is bigger then the rest
6779       //     i  k                               j  l
6780       // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6781       // xxxxABCABCABCABCABCABCABCABCABCABCABCABCABCxxxxx
6782       int o_size = k - j + 1; // Overlap size
6783       int r_size = i - k;     // Rest szie
6784       // Smallest slice
6785       int d = gcd(Rational(o_size), Rational(r_size)).getInt();
6786       // Number of different pieces
6787       int different_pieces = r_size / d; // How many different slices will we get
6788       // Add all the initial different pieces
6789       for (int p = 0; p < different_pieces; p ++) {
6790         Expr piece = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(d));
6791         boundVars.push_back(piece);
6792         terms.push_back(piece);
6793       }
6794       // Add the rest of them cyclicly
6795       int other_pieces = (o_size + r_size) / d;
6796       for (int p = 0; p < other_pieces; p ++)
6797         terms.push_back(terms[terms.size() - different_pieces]);
6798     }
6799 
6800     // If there is a ending part of x, put it in
6801     if (l > 0) {
6802       Expr x_end = d_theoryBitvector->getEM()->newBoundVarExpr(d_theoryBitvector->newBitvectorType(l));
6803       terms.push_back(x_end);
6804       boundVars.push_back(x_end);
6805     }
6806 
6807     res = x.eqExpr(d_theoryBitvector->newConcatExpr(terms));
6808     res = d_theoryBitvector->getEM()->newClosureExpr(EXISTS, boundVars, res);
6809 
6810   } else
6811     // Other case by symmetry
6812     res = solveExtractOverlap(rhs.eqExpr(lhs)).getRHS();
6813 
6814   Proof pf;
6815   if (withProof()) pf = newPf("solveExtractOverlap", eq);
6816 
6817   return newTheorem(eq.iffExpr(res), Assumptions::emptyAssump(), pf);
6818 }
6819 
6820