CVC3  2.4.1
bitvector_theorem_producer.cpp
Go to the documentation of this file.
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>
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 ///////////////////////////////////////////////////////////////////////
45 TheoryBitvector::createProofRules() {
46  return new BitvectorTheoremProducer(this);
47 }
48 
49 
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;
57  bits[0]=true;
59 }
60 
61 
62 ///////////////////////////////////////////////////////////////////////
63 // BitBlasting rules for equations
64 ///////////////////////////////////////////////////////////////////////
65 // |- (BOOLEXTRACT(a,i) <=> BOOLEXTRACT(b,i)) <=> False ==> |- a = b <=> False
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());
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
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());
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
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 =
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 ///////////////////////////////////////////////////////////////////////
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());
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 =
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
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
340  if(CHECK_PROOFS) {
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
381  //little bit of cheating here. calling a rule from inside a rule.
382  //just a shorthand
383  Theorem thm = signExtendRule(e);
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
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
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  */
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  */
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)
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
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);
700 }
701 
702 
703 //! if indeed e[0] < e[1] then (e<==>true) else (e<==>false)
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)
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 =
809  int e1_iBitIndex =
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)
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  }
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
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])
949  if(CHECK_PROOFS) {
951  "BitvectorTheoremProducer::bitExtractRewrite: x = "
952  +x.toString());
953  }
954 
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]*
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;
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
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
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 =
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 =
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
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)
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 =
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
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
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
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());
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
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)
1428  else
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) ==
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);
1447  }
1448  else {
1449  Expr indexMinusOne = t1Andt2.andExpr(rat(bitPos-1));
1450  if(d_theoryBitvector->d_bvPlusCarryCacheRightBV.find(indexMinusOne) ==
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);
1462  }
1463  }
1464  //cout << "the carry for" << index << " is : " << carryout << "\n";
1465  return carryin;
1466 }
1467 
1468 Theorem
1470 zeroPaddingRule(const Expr& e, int i) {
1471  if(CHECK_PROOFS) {
1473  "BitvectorTheoremProducer::zeroPaddingRule:"
1474  "Wrong Input: Input must be a bitvector. But the input is: " +
1475  e.toString());
1476  }
1477 
1478  int bvLength =
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
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 
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 
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 
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());
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 
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());
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 =
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))
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))
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))
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
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)
1894  if(CHECK_PROOFS) {
1895  // The kids must be constant expressions
1896  CHECK_SOUND(e.isEq(),
1897  "BitvectorTheoremProducer::eqConst: e = "+e.toString());
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() :
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
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) {
1922  "BitvectorTheoremProducer::eqToBits: eq = "+eq.toString());
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)
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());
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)
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());
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)
2002  if(CHECK_PROOFS) {
2003  CHECK_SOUND(e.getOpKind() == RIGHTSHIFT && e.arity() == 1,
2004  "BitvectorTheoremProducer::rightShiftConst: e = "+e.toString());
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
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
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);
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]
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 
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)
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 
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 
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 
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 
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),
2234  Proof pf;
2235  if (withProof())
2236  pf = newPf("rewriteBVCOMP");
2237  return newRWTheorem(e, res, Assumptions::emptyAssump(), pf);
2238 }
2239 
2240 
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 */
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
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");
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)
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());
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);
2393 }
2394 
2395 // t[n-1:0] = t for n-bit t
2396 Theorem
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
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
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]
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
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
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
2579  return extractBitwise(e, BVOR, "extract_or");
2580 }
2581 
2582 
2583 //! (~t)[i:j] = ~(t[i:j]) (push extraction through NEG)
2584 Theorem
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
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
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)
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());
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);
2673 }
2674 
2675 
2676 //! ~(t1\@...\@tn) = (~t1)\@...\@(~tn) -- push negation through concat
2677 Theorem
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
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
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
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
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
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
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
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) :
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.
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)
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
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
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  */
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)
3196  if(CHECK_PROOFS) {
3197  // The kids must be constant expressions
3198  CHECK_SOUND(e.getOpKind() == CONCAT,
3199  "BitvectorTheoremProducer::concatConst: e = "+e.toString());
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);
3212 }
3213 
3214 
3215 //! Flatten one level of nested concatenation, e.g.: x\@(y\@z)\@w = x\@y\@z\@w
3216 Theorem
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
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());
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());
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)
3291  if(CHECK_PROOFS) {
3292  // The kids must be constant expressions
3293  CHECK_SOUND(e.getOpKind() == BVPLUS,
3294  "BitvectorTheoremProducer::extractConst: e = "+e.toString());
3296  "BitvectorTheoremProducer::extractConst: e = "+e.toString());
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) {
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);
3324 }
3325 
3326 
3327 /*! @brief c0*c1 = c, multiplication of two BVCONST
3328  */
3330  if(CHECK_PROOFS) {
3331  // The kids must be constant expressions
3332  CHECK_SOUND(e.getOpKind() == BVMULT,
3333  "BitvectorTheoremProducer::extractConst: e = "+e.toString());
3335  "BitvectorTheoremProducer::extractConst: e = "+e.toString());
3336  }
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);
3353 }
3354 
3355 Theorem
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());
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
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());
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
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
3425  DebugAssert(len > 0,
3426  "TheoryBitvector::pad:"
3427  "padding bvLength must be a non-negative integer: "+
3428  int2string(len));
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
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
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
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  }
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
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
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
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
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
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 
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
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
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
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
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
3990  if(CHECK_PROOFS) {
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
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
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
4039  if(CHECK_PROOFS) {
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
4085  if(CHECK_PROOFS) {
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
4106  if(CHECK_PROOFS) {
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
4129  if(CHECK_PROOFS) {
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
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
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
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)
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
4278  if(CHECK_PROOFS) {
4280  "BitvectorTheoremProducer::typePredBit: e = "+e.toString());
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
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 {
4308  const Expr& e(d_theoryBitvector->getTypePredExpr(tpExpr));
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
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  {
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
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 
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
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 
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
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)
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) {
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) {
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) {
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 
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);
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 {
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 
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 
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
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 
5588 {
5589  if (CHECK_PROOFS)
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
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");
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 {
5640  terms.push_back(lhs);
5641  boundVars.push_back(lhs);
5642  }
5643  if (low > 0) {
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 
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)
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}");
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
6082  if(CHECK_PROOFS) {
6084  "input must be a bitvector. \n e = " + e.toString());
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
6110  if(CHECK_PROOFS) {
6112  "input must be a bitvector. \n e = " + e.toString());
6114  "input must be BVREPEAT(e).\n e = " + e.toString());
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)
6143  if(CHECK_PROOFS) {
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)
6174  if(CHECK_PROOFS) {
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 
6202  const Expr& a = remExpr[0];
6203  const Expr& b = remExpr[1];
6204  int size = d_theoryBitvector->BVSize(remExpr);
6205 
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 
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 
6236  Proof pf;
6237  if (withProof())
6238  pf = newPf("bvURemRewrite", remExpr);
6239  return newRWTheorem(remExpr, rem, Assumptions::emptyAssump(), pf);
6240 }
6241 
6242 
6244 {
6245  const Expr& a = divExpr[0];
6246  const Expr& b = divExpr[1];
6247  int size = d_theoryBitvector->BVSize(divExpr);
6248 
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 
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;
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(
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 
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 
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  */
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 
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 
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(
6503  cond2.iteExpr(
6505  cond3.iteExpr(
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  */
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 
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 
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(
6559  cond2.iteExpr(
6561  cond3.iteExpr(
6562  d_theoryBitvector->newBVURemExpr(s, 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  */
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 
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 
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(
6625  cond3.iteExpr(d_theoryBitvector->newBVPlusExpr(m, u, t),
6627 
6628  return newRWTheorem(sModExpr, result, Assumptions::emptyAssump(), pf);
6629 }
6630 
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 
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 
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 
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 
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) {
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
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
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 ++) {
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) {
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 
Theorem bitExtractBVSHL(const Expr &x, int i)
int arity() const
Definition: expr.h:1201
bool isIff() const
Definition: expr.h:424
bool isNull() const
Definition: expr.h:1223
Theorem bitExtractToExtract(const Theorem &thm)
t[i] ==> t[i:i] = 0bin1 or NOT t[i] ==> t[i:i] = 0bin0
iterator begin() const
Begin iterator.
Definition: expr.h:1211
bool isEq() const
Definition: expr.h:419
int getFixedRightShiftParam(const Expr &e)
Theorem expandTypePred(const Theorem &tp)
Expand the type predicate wrapper (compute the actual type predicate)
Expr newBVSLTExpr(const Expr &t1, const Expr &t2)
Expr sumNormalizedElements(int bvplusLength, const std::vector< Expr > &elements)
void clear()
Definition: expr_map.h:175
Data structure of expressions in CVC3.
Definition: expr.h:133
bool isLeafIn(const Expr &e1, const Expr &e2)
Test if e1 is an i-leaf in e2.
Definition: theory.cpp:546
virtual Theorem bvUDivTheorem(const Expr &divExpr)
Expr iteExpr(const Expr &thenpart, const Expr &elsepart) const
Definition: expr.h:961
const Expr & bvZero() const
Return cached constant 0bin0.
Theorem newTheorem(const Expr &thm, const Assumptions &assump, const Proof &pf)
Create a new theorem. See also newRWTheorem() and newReflTheorem()
bool isLeaf(const Expr &e)
Test if e is an i-leaf term for the current theory.
Definition: theory.h:556
Expr newBVXnorExpr(const Expr &t1, const Expr &t2)
Expr newBVExtractExpr(const Expr &e, int hi, int low)
hi and low are bit indices
Theorem extractExtract(const Expr &e)
t[i:j][k:l] = t[k+j:l+j] (eliminate double extraction)
bool isTrue() const
Definition: expr.h:356
bool isRational() const
Definition: expr.h:431
static Rational boundedModulo(const Rational &value, const Rational &modulo, const Rational &lowerBound)
Theorem bvMultDistRule(const Expr &e)
a*(t1+...+tn) <==> (a*t1+...+a*tn), where all kids are equibvLength
Theorem bitExtractBVLSHR(const Expr &x, int i)
Theorem bvshlToConcat(const Expr &e)
BVSHL(t,c) = t[n-c,0] @ 0bin00...00.
void insert(const Expr &e, const Data &d)
Definition: expr_map.h:177
Theorem bvshlSplit(const Expr &e)
BVSHL(t,c) = IF (c = 0) THEN t ELSE IF (c = 1) ...
Expr newBVUDivExpr(const Expr &t1, const Expr &t2)
Theorem bitExtractFixedLeftShift(const Expr &x, int i)
Expr computeCarryPreComputed(const Theorem &t1_i, const Theorem &t2_i, int bitPos, int precomputedFlag)
compute carryout of the current bits and cache them, and return
Theorem bitExtractRewrite(const Expr &x)
t[i] <=> t[i:i][0] (to use rewriter for simplifying t[i:i])
Theorem bitExtractNot(const Expr &x, int i)
const Rational & getRational() const
Get the Rational value out of RATIONAL_EXPR.
Definition: expr.h:1135
iterator find(const Expr &e)
Definition: expr_map.h:194
Theorem flattenBVPlus(const Expr &e)
input BVPLUS expression e.output e <==> e', where e' has no BVPLUS
const Expr & getTypePredExpr(const Expr &tp)
virtual Theorem bitblastBVMult(const std::vector< Theorem > &a_bits, const std::vector< Theorem > &b_bits, const Expr &a_times_b, std::vector< Theorem > &output_bits)
Theorem iteExtractRule(const Expr &e)
ite(c,t1,t2)[i:j] <=> ite(c,t1[i:j],t2[i:j])
Expr chopConcat(int bv_size, Rational c, std::vector< Expr > &concatKids)
int getExtractHi(const Expr &e)
Theorem bitExtractFixedRightShift(const Expr &x, int i)
Theorem newReflTheorem(const Expr &e)
Create a reflexivity theorem.
Expr newBVSLEExpr(const Expr &t1, const Expr &t2)
bool isFalse() const
Definition: expr.h:355
Theorem negBVxor(const Expr &e)
~(t1 xor t2) = ~t1 xor t2
void createNewPlusCollection(const Expr &e, const ExprMap< Rational > &likeTerms, Rational &plusConstant, std::vector< Expr > &result)
virtual Theorem BVMult_order_subterms(const Expr &e)
Theorem pushNegationRec(const Expr &e)
Theorem bitvectorFalseRule(const Theorem &thm)
MS C++ specific settings.
Definition: type.h:42
Theorem bitBlastDisEqnRule(const Theorem &e, const Expr &f)
virtual Theorem bvUDivConst(const Expr &divExpr)
Theorem bvmultBVUminus(const Expr &e)
c*(-t) <==> (-c)*t
Expr newBVOneString(int r)
produces a string of 1's of length bvLength
Expr newConcatExpr(const Expr &t1, const Expr &t2)
Theorem constMultToPlus(const Expr &e)
k*t = BVPLUS(n, ) – translation of k*t to BVPLUS
Definition: kinds.h:85
Type getTypePredType(const Expr &tp)
iterator begin()
Definition: expr_map.h:190
Theorem zeroLeq(const Expr &e)
|= 0 <= foo <-> TRUE
Theorem bvuminusBVUminus(const Expr &e)
-(-e) <==> e
Expr newSXExpr(const Expr &t1, int len)
Expr d_bvZero
Constant 1-bit bit-vector 0bin0.
Definition: kinds.h:66
bool withProof()
Testing whether to generate proofs.
int getBVPlusParam(const Expr &e)
Expr computeCarry(const std::vector< Theorem > &t1BitExtractThms, const std::vector< Theorem > &t2BitExtractThms, int bitPos)
Theorem bvmultConst(const Expr &e)
n*c1 = c, where n >= 0 (multiplication of a constant bitvector by a non-negative constant) ...
Expr eqExpr(const Expr &right) const
Definition: expr.h:929
Theorem bitExtractSXRule(const Expr &e, int i)
bitExtractSXRule
Theorem eqConst(const Expr &e)
c1=c2 <=> TRUE/FALSE (equality of constant bitvectors)
bool isBool() const
Definition: type.h:60
std::string toString(int base=10) const
virtual Theorem bvSRemRewrite(const Expr &sRemExpr)
Theorem padBVMult(const Expr &e)
Pad the kids of BVMULT to make their bvLength = # of output-bits.
Theorem typePredBit(const Expr &e)
|- t=0 OR t=1 for any 1-bit bitvector t
Theorem rewriteXNOR(const Expr &e)
a XNOR b <=> (~a & ~b) | (a & b)
Theorem bitvectorTrueRule(const Theorem &thm)
TRUSTED implementation of bitvector proof rules.
#define DebugAssert(cond, str)
Definition: debug.h:408
virtual Theorem bvSDivRewrite(const Expr &sDivExpr)
#define CHECK_SOUND(cond, msg)
Theorem lhsEqRhsIneqn(const Expr &e, int kind)
if(lhs==rhs) then we have (lhs < rhs <==> false),(lhs <= rhs <==> true)
Expr newClosureExpr(int kind, const Expr &var, const Expr &body)
Definition: expr_manager.h:506
Expr newFixedLeftShiftExpr(const Expr &t1, int r)
void getPlusTerms(const Expr &e, Rational &known_term, ExprMap< Rational > &sumHashMap)
Theorem bitExtractConcatenation(const Expr &x, int i)
#define CHECK_PROOFS
bool isOr() const
Definition: expr.h:422
Theorem bitwiseFlatten(const Expr &e, int kind)
Flatten bitwise operation.
const Expr & bvOne() const
Return cached constant 0bin1.
Theorem negConst(const Expr &e)
~c1 = c (bit-wise negation of a constant bitvector)
const std::vector< Expr > & getKids() const
Definition: expr.h:1162
Expr andExpr(const Expr &right) const
Definition: expr.h:941
virtual Theorem liftConcatBVPlus(const Expr &e)
virtual Theorem constEq(const Expr &eq)
virtual Theorem liftConcatBVMult(const Expr &e)
Theorem bvPlusAssociativityRule(const Expr &bvPlusTerm)
Expr newBVOrExpr(const Expr &t1, const Expr &t2)
Expr orExpr(const std::vector< Expr > &children)
Definition: expr.h:955
Theorem extractNeg(const Expr &e)
(~t)[i:j] = ~(t[i:j]) (push extraction through NEG)
Expr impExpr(const Expr &right) const
Definition: expr.h:969
Expr newBoundVarExpr(const std::string &name, const std::string &uid)
Definition: expr_manager.h:484
Expr newBVNegExpr(const Expr &t1)
virtual Theorem processExtract(const Theorem &e, bool &solvedForm)
Theorem bitBlastEqnRule(const Expr &e, const Expr &f)
Op getOp() const
Get operator from expression.
Definition: expr.h:1183
Theorem negBVand(const Expr &e)
~(t1 & t2) <=> ~t1 | ~t2 – DeMorgan's Laws
const Expr & getExpr() const
Definition: type.h:52
Theorem bitExtractBVMult(const Expr &t, int i)
Theorem bvlshrToConcat(const Expr &e)
BVLSHR(t,c) = 0bin00...00 @ t[n-1,c].
bool isNot() const
Definition: expr.h:420
Theorem bvuminusBVPlus(const Expr &e)
-(c1*t1+...+cn*tn) <==> (-(c1*t1)+...+-(cn*tn))
size_t count(const Expr &e) const
Definition: expr_map.h:173
Theorem negConcat(const Expr &e)
~(t1@...@tn) = (~t1)@...@(~tn) – push negation through concat
const std::string & getKindName(int kind)
Return the name associated with a kind. The kind must already be registered.
int getBitvectorTypeParam(const Expr &e)
Theorem eqToBits(const Theorem &eq)
|- c1=c2 ==> |- AND(c1[i:i] = c2[i:i]) - expanding equalities into bits
Theorem bvuminusBVConst(const Expr &e)
-0 <==> 0, -c <==> ~c+1
Theorem bitwiseConcat(const Expr &e, int kind)
Lifts concatenation above bitwise operators.
Theorem bvShiftZero(const Expr &e)
All shifts over a 0 constant = 0.
Expr newBVConstExpr(const std::string &s, int base=2)
Theorem bitExtractBitwise(const Expr &x, int i, int kind)
Extract from bitwise AND, OR, or XOR.
Definition: kinds.h:44
bool empty() const
Definition: expr_map.h:170
Expr newBVURemExpr(const Expr &t1, const Expr &t2)
virtual Theorem bitblastBVPlus(const std::vector< Theorem > &a_bits, const std::vector< Theorem > &b_bits, const Expr &a_plus_b, std::vector< Theorem > &output_bits)
virtual Theorem canonBVMult(const Expr &e)
canonize BVMult expressions in order to get one coefficient
Expr newBVMultExpr(int bvLength, const Expr &t1, const Expr &t2)
Expr newFixedConstWidthLeftShiftExpr(const Expr &t1, int r)
Theorem bitExtractExtraction(const Expr &x, int i)
#define FatalAssert(cond, msg)
If something goes horribly wrong, print a message and abort immediately with exit(1).
Definition: debug.h:37
Theorem rightShiftToConcat(const Expr &e)
t>>m = 0bin00...00 @ t[bvlength-1:m], takes e == (t>>n)
Expr newBVLEExpr(const Expr &t1, const Expr &t2)
bool isInteger() const
std::string toString() const
Definition: theorem.h:404
Theorem bvConstIneqn(const Expr &e, int kind)
if indeed e[0] < e[1] then (e<==>true) else (e<==>false)
Theorem constWidthLeftShiftToConcat(const Expr &e)
Expr pad(int rat, const Expr &e)
converts e to a bitvector of length rat
std::string toString() const
Print the expression to a string.
Definition: expr.cpp:344
Expr newVar(const std::string &name, const Type &type)
Create a new variable given its name and type.
Definition: theory.cpp:569
virtual Theorem bvURemRewrite(const Expr &remExpr)
Expr newBVLTExpr(const Expr &t1, const Expr &t2)
ExprMap< Expr > d_bvPlusCarryCacheRightBV
Rational multiplicative_inverse(Rational r, int n_bits)
int getOpKind() const
Get kind of operator (for APPLY Exprs only)
Definition: expr.h:1196
Expr iffExpr(const Expr &right) const
Definition: expr.h:965
virtual Theorem zeroExtendRule(const Expr &e)
BVZEROEXTEND(e, i) = zeroString @ e.
Expr newBVUminusExpr(const Expr &t1)
Theorem rewriteBVCOMP(const Expr &e)
BVCOMP(a,b) <=> ITE(a=b,0bin1,0bin0)
Theorem bvplusZeroConcatRule(const Expr &e)
0bin0...0 @ BVPLUS(n, args) = BVPLUS(n+k, args)
Theorem bitExtractConstBVMult(const Expr &t, int i)
Expr negate() const
Definition: expr.h:937
Definition: kinds.h:68
Expr newBVPlusPadExpr(int bvLength, const std::vector< Expr > &k)
pads children and then builds plus expr
bool isBoolConst() const
Definition: expr.h:357
int getKind() const
Definition: expr.h:1168
void collectLikeTermsOfPlus(const Expr &e, ExprMap< Rational > &likeTerms, Rational &plusConstant)
T abs(T t)
Definition: cvc_util.h:53
Theorem negBVxnor(const Expr &e)
~(t1 xnor t2) = t1 xor t2
Theorem bitExtractBVPlus(const std::vector< Theorem > &t1, const std::vector< Theorem > &t2, const Expr &bvPlusTerm, int i)
std::string int2string(int n)
Definition: cvc_util.h:46
int getBVIndex(const Expr &e)
Expr newBVSubExpr(const Expr &t1, const Expr &t2)
const Expr & getRHS() const
Definition: theorem.cpp:246
Theorem bvplusConst(const Expr &e)
BVPLUS(n, c1,c2,...,cn) = c (bit-vector plus of constant bitvectors)
std::string toString() const
Definition: type.h:80
Theorem negBVor(const Expr &e)
~(t1 | t2) <=> ~t1 & ~t2 – DeMorgan's Laws
Theorem extractConst(const Expr &e)
c1[i:j] = c (extraction from a constant bitvector)
const Expr & falseExpr()
Return FALSE Expr.
Definition: theory.h:579
Theorem bitwiseConst(const Expr &e, const std::vector< int > &idxs, int kind)
Combine constants in bitwise AND, OR, XOR.
Proof getProof() const
Definition: theorem.cpp:402
const Expr & trueExpr()
Return TRUE Expr.
Definition: theory.h:582
const Assumptions & getAssumptionsRef() const
Definition: theorem.cpp:385
virtual Theorem distributive_rule(const Expr &e)
apply the distributive rule on the BVMULT expression e
Theorem bitExtractBVASHR(const Expr &x, int i)
Expr newBVMultPadExpr(int bvLength, const Expr &t1, const Expr &t2)
Theorem extractAnd(const Expr &e)
(t1 & t2)[i:j] = t1[i:j] & t2[i:j] (push extraction through OR)
void collectOneTermOfPlus(const Rational &coefficient, const Expr &var, ExprMap< Rational > &likeTerms, Rational &plusConstant)
Expr getExpr() const
Definition: theorem.cpp:230
Theorem bvuminusBVMult(const Expr &e)
-(c*t)<=>(-c)*t; if -c==0 return e<=>0. if(-c==1) return e<=>t
Theorem flipBVMult(const Expr &e)
t1*a <==> a*t1
int getBoolExtractIndex(const Expr &e)
ExprManager * getEM()
Access to ExprManager.
Definition: theory.h:90
Expr orExpr(const Expr &right) const
Definition: expr.h:951
int getFixedLeftShiftParam(const Expr &e)
Theorem padBVPlus(const Expr &e)
Pad the kids of BVMULT to make their bvLength = # of output-bits.
Definition: kinds.h:69
Expr rat(const Rational &r)
Create Expr from Rational (for convenience)
Theorem leftShiftToConcat(const Expr &e)
Theorem rewriteNAND(const Expr &e)
a NAND b <=> ~(a & b)
Theorem bitExtractAllToConstEq(std::vector< Theorem > &thms)
ExprMap< Expr > d_bvPlusCarryCacheLeftBV
Theorem bvConstMultAssocRule(const Expr &e)
a*(b*t) <==> (a*b)*t, where a,b,t have same bvLength
int sameKidCheck(const Expr &e, ExprMap< int > &likeTerms)
bool getBVConstValue(const Expr &e, int i)
Theorem negElim(const Expr &e)
~t = -1*t + 1 – eliminate negation
virtual Theorem bvSModRewrite(const Expr &sModExpr)
Expr buildPlusTerm(int bv_size, Rational &known_term, ExprMap< Rational > &sumHashMap)
Expr newBVPlusExpr(int numbits, const Expr &k1, const Expr &k2)
'numbits' is the number of bits in the result
Type getBaseType(const Expr &e)
Compute (or look up in cache) the base type of e and return the result.
Definition: theory.cpp:383
Expr d_bvOne
Constant 1-bit bit-vector 0bin1.
Theorem newRWTheorem(const Expr &lhs, const Expr &rhs, const Assumptions &assump, const Proof &pf)
Create a rewrite theorem: lhs = rhs.
virtual Theorem canonBVEQ(const Expr &e, int maxEffort=3)
unsigned getBVConstSize(const Expr &e)
virtual Theorem MarkNonSolvableEq(const Expr &e)
Theorem extractBVPlus(const Expr &e)
(x +[n] y)[m:k] = (x +[m+1] y)[m:k], where m < n
Theorem extractBitwise(const Expr &e, int kind, const std::string &name)
Auxiliary function: (t1 op t2)[i:j] = t1[i:j] op t2[i:j].
Theorem negNeg(const Expr &e)
~(~t) = t – eliminate double negation
Theorem padBVLTRule(const Expr &e, int len)
Pad the kids of BVLT/BVLE to make their length equal.
Expr newBoolExtractExpr(const Expr &t1, int r)
Expr pad(int len, const Expr &e)
pads e to be of length len
virtual Theorem oneBVAND(const Expr &andEqOne)
virtual Theorem zeroBVOR(const Expr &orEqZero)
int BVSize(const Expr &e)
Return the number of bits in the bitvector expression.
const Expr & getLHS() const
Definition: theorem.cpp:240
Theorem bitwiseConstElim(const Expr &e, int idx, int kind)
Simplify bitwise operator containing a constant child.
virtual Theorem canonBVUMinus(const Expr &e)
canonize BVMinus expressions: push the minus to the leafs in
Definition: kinds.h:81
Theorem signExtendRule(const Expr &e)
sign extend the input SX(e) appropriately
Theorem extractConcat(const Expr &e)
(t1 @ t2)[i:j] = t1[...] @ t2[...] (push extraction through concat)
Theorem rewriteNOR(const Expr &e)
a NOR b <=> ~(a | b)
Theorem generalIneqn(const Expr &e, const Theorem &lhs_i, const Theorem &rhs_i, int kind)
virtual Theorem repeatRule(const Expr &e)
BVREPEAT(e, i) = e @ e @ ... @ e.
Proof newPf(const std::string &name)
virtual Theorem rotlRule(const Expr &e)
BVROTL(e, i) = a[n-i-1:0] @ a[n-1:n-i].
Definition: kinds.h:61
Theorem zeroPaddingRule(const Expr &e, int r)
Theorem extractOr(const Expr &e)
(t1 | t2)[i:j] = t1[i:j] | t2[i:j] (push extraction through AND)
Theorem reflexivityRule(const Expr &a)
==> a == a
Definition: theory.h:673
Theorem extractWhole(const Expr &e)
t[n-1:0] = t for n-bit t
Theory of bitvectors of known length \ (operations include: @,[i:j],[i],+,.,BVAND,BVNEG)
Theorem concatMergeExtract(const Expr &e)
Merge n-ary concat. of adjacent extractions: x[15:8]@x[7:0] = x[15:0].
Theorem rewriteBVSub(const Expr &e)
a - b <=> a + (-b)
Theorem concatFlatten(const Expr &e)
Flatten one level of nested concatenation, e.g.: x@(y@z)@w = x@y@z@w.
Theorem bvashrToConcat(const Expr &e)
BVASHR(t,c) = SX(t[n-1,c], n-1)
Rational pow(Rational pow, const Rational &base)
Raise 'base' into the power of 'pow' (pow must be an integer)
Definition: rational.h:159
Definition: kinds.h:99
This class implements proof rules for bitvector normalizers (concatenation normal form...
Theorem padBVSLTRule(const Expr &e, int len)
Sign Extend the kids of BVSLT/BVSLE to make their length equal.
Type getType() const
Get the type. Recursively compute if necessary.
Definition: expr.h:1259
void extract_vars(const Expr &e, std::vector< Expr > &vars)
bool isRewrite() const
Definition: theorem.cpp:224
Rational computeNegBVConst(const Expr &e)
computes the integer value of ~c+1 or BVUMINUS(c)
Expr newBVXorExpr(const Expr &t1, const Expr &t2)
Theorem bvuminusToBVPlus(const Expr &e)
-t <==> ~t+1
Expr newBVZeroString(int r)
produces a string of 0's of length bvLength
Theorem iteBVnegRule(const Expr &e)
~ite(c,t1,t2) <=> ite(c,~t1,~t2)
Theorem bitExtractBVPlusPreComputed(const Theorem &t1_i, const Theorem &t2_i, const Expr &bvPlusTerm, int bitPos, int precomputed)
static const Assumptions & emptyAssump()
Definition: assumptions.h:83
Expr andExpr(const std::vector< Expr > &children)
Definition: expr.h:945
iterator end()
Definition: expr_map.h:191
static bool constantKids(const Expr &e)
Check that all the kids of e are BVCONST.
Definition: kinds.h:67
Rational computeBVConst(const Expr &e)
computes the integer value of a bitvector constant
Theorem bvuminusVar(const Expr &e)
-v <==> -1*v
Theorem concatConst(const Expr &e)
c1@c2@...@cn = c (concatenation of constant bitvectors)
virtual Theorem canonBVPlus(const Expr &e)
canonize BVPlus expressions in order to get just one
Expr newBVAndExpr(const Expr &t1, const Expr &t2)
Theorem bitExtractConstant(const Expr &x, int i)
virtual Theorem bvURemConst(const Expr &remExpr)
void erase(const Expr &e)
Definition: expr_map.h:178
int getInt() const
Theorem bvMultAssocRule(const Expr &e)
(t1*t2)*t3 <==> t1*(t2*t3), where t1
Theorem extractBVMult(const Expr &e)
(x *[n] y)[m:k] = (x *[m+1] y)[m:k], where m < n
Theorem signBVLTRule(const Expr &e, const Theorem &topBit0, const Theorem &topBit1)
virtual Theorem isolate_var(const Expr &e)
isolate a variable with coefficient = 1 on the Lhs of an
Definition: kinds.h:70
int getExtractLow(const Expr &e)
virtual Theorem rotrRule(const Expr &e)
BVROTR(e, i) = a[i-1:0] @ a[n-1:i].
iterator end() const
End iterator.
Definition: expr.h:1217
bool isAnd() const
Definition: expr.h:421