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