1 /********************* */
2 /*! \file theory_bv_rewriter.cpp
3 ** \verbatim
4 ** Top contributors (to current version):
5 ** Liana Hadarean, Aina Niemetz, Dejan Jovanovic
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
8 ** in the top-level source directory) and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
11 **
12 ** \brief [[ Add one-line brief description here ]]
13 **
14 ** [[ Add lengthier description here ]]
15 ** \todo document this file
16 **/
17
18 #include "options/bv_options.h"
19 #include "theory/bv/theory_bv_rewrite_rules.h"
20 #include "theory/bv/theory_bv_rewrite_rules_constant_evaluation.h"
21 #include "theory/bv/theory_bv_rewrite_rules_core.h"
22 #include "theory/bv/theory_bv_rewrite_rules_normalization.h"
23 #include "theory/bv/theory_bv_rewrite_rules_operator_elimination.h"
24 #include "theory/bv/theory_bv_rewrite_rules_simplification.h"
25 #include "theory/bv/theory_bv_rewriter.h"
26 #include "theory/theory.h"
27
28 using namespace CVC4;
29 using namespace CVC4::theory;
30 using namespace CVC4::theory::bv;
31
32
33 // thread_local AllRewriteRules* TheoryBVRewriter::s_allRules = NULL;
34 // thread_local TimerStat* TheoryBVRewriter::d_rewriteTimer = NULL;
35 RewriteFunction TheoryBVRewriter::d_rewriteTable[kind::LAST_KIND];
init()36 void TheoryBVRewriter::init() {
37 // s_allRules = new AllRewriteRules;
38 // d_rewriteTimer = new TimerStat("theory::bv::rewriteTimer");
39 // smtStatisticsRegistry()->registerStat(d_rewriteTimer);
40 initializeRewrites();
41
42 }
43
shutdown()44 void TheoryBVRewriter::shutdown() {
45 // delete s_allRules;
46 // smtStatisticsRegistry()->unregisterStat(d_rewriteTimer);
47 //delete d_rewriteTimer;
48 }
49
preRewrite(TNode node)50 RewriteResponse TheoryBVRewriter::preRewrite(TNode node) {
51 RewriteResponse res = d_rewriteTable[node.getKind()](node, true);
52 if(res.node != node) {
53 Debug("bitvector-rewrite") << "TheoryBV::preRewrite " << node << std::endl;
54 Debug("bitvector-rewrite") << "TheoryBV::preRewrite to " << res.node << std::endl;
55 }
56 return res;
57 }
58
postRewrite(TNode node)59 RewriteResponse TheoryBVRewriter::postRewrite(TNode node) {
60 RewriteResponse res = d_rewriteTable[node.getKind()](node, false);
61 if(res.node!= node) {
62 Debug("bitvector-rewrite") << "TheoryBV::postRewrite " << node << std::endl;
63 Debug("bitvector-rewrite") << "TheoryBV::postRewrite to " << res.node << std::endl;
64 }
65 return res;
66 }
67
RewriteUlt(TNode node,bool prerewrite)68 RewriteResponse TheoryBVRewriter::RewriteUlt(TNode node, bool prerewrite) {
69 // reduce common subexpressions on both sides
70 Node resultNode = LinearRewriteStrategy
71 < RewriteRule<EvalUlt>, // if both arguments are constants evaluates
72 RewriteRule<UltZero>, // a < 0 rewrites to false,
73 RewriteRule<SignExtendUltConst>,
74 RewriteRule<ZeroExtendUltConst>
75 >::apply(node);
76
77 return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL,
78 resultNode);
79 }
80
RewriteUltBv(TNode node,bool prerewrite)81 RewriteResponse TheoryBVRewriter::RewriteUltBv(TNode node, bool prerewrite) {
82 // reduce common subexpressions on both sides
83 Node resultNode = LinearRewriteStrategy
84 < RewriteRule<EvalUltBv>
85 >::apply(node);
86
87 return RewriteResponse(REWRITE_DONE, resultNode);
88 }
89
90
RewriteSlt(TNode node,bool prerewrite)91 RewriteResponse TheoryBVRewriter::RewriteSlt(TNode node, bool prerewrite){
92 Node resultNode = LinearRewriteStrategy
93 < RewriteRule<EvalSlt>,
94 RewriteRule<MultSltMult>
95 >::apply(node);
96
97 return RewriteResponse(REWRITE_DONE, resultNode);
98
99 // Node resultNode = LinearRewriteStrategy
100 // < RewriteRule < SltEliminate >
101 // // a <_s b ==> a + 2^{n-1} <_u b + 2^{n-1}
102 // >::apply(node);
103
104 // return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
105 }
106
RewriteSltBv(TNode node,bool prerewrite)107 RewriteResponse TheoryBVRewriter::RewriteSltBv(TNode node, bool prerewrite){
108 Node resultNode = LinearRewriteStrategy
109 < RewriteRule < EvalSltBv >
110 >::apply(node);
111
112 return RewriteResponse(REWRITE_DONE, resultNode);
113 }
114
RewriteUle(TNode node,bool prerewrite)115 RewriteResponse TheoryBVRewriter::RewriteUle(TNode node, bool prerewrite){
116 Node resultNode = LinearRewriteStrategy
117 < RewriteRule<EvalUle>,
118 RewriteRule<UleMax>,
119 RewriteRule<ZeroUle>,
120 RewriteRule<UleZero>,
121 RewriteRule<UleSelf>,
122 RewriteRule<UleEliminate>
123 >::apply(node);
124 return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN, resultNode);
125 }
126
RewriteSle(TNode node,bool prerewrite)127 RewriteResponse TheoryBVRewriter::RewriteSle(TNode node, bool prerewrite){
128 Node resultNode = LinearRewriteStrategy
129 < RewriteRule <EvalSle>,
130 RewriteRule <SleEliminate>
131 >::apply(node);
132 return RewriteResponse(resultNode == node? REWRITE_DONE : REWRITE_AGAIN, resultNode);
133 }
134
RewriteUgt(TNode node,bool prerewrite)135 RewriteResponse TheoryBVRewriter::RewriteUgt(TNode node, bool prerewrite){
136 Node resultNode = LinearRewriteStrategy
137 < RewriteRule<UgtEliminate>
138 >::apply(node);
139
140 return RewriteResponse(REWRITE_AGAIN, resultNode);
141 }
142
RewriteSgt(TNode node,bool prerewrite)143 RewriteResponse TheoryBVRewriter::RewriteSgt(TNode node, bool prerewrite){
144 Node resultNode = LinearRewriteStrategy
145 < RewriteRule<SgtEliminate>
146 //RewriteRule<SltEliminate>
147 >::apply(node);
148
149 return RewriteResponse(REWRITE_AGAIN, resultNode);
150 }
151
RewriteUge(TNode node,bool prerewrite)152 RewriteResponse TheoryBVRewriter::RewriteUge(TNode node, bool prerewrite){
153 Node resultNode = LinearRewriteStrategy
154 < RewriteRule<UgeEliminate>
155 >::apply(node);
156
157 return RewriteResponse(REWRITE_AGAIN, resultNode);
158 }
159
RewriteSge(TNode node,bool prerewrite)160 RewriteResponse TheoryBVRewriter::RewriteSge(TNode node, bool prerewrite){
161 Node resultNode = LinearRewriteStrategy
162 < RewriteRule<SgeEliminate>
163 // RewriteRule<SleEliminate>
164 >::apply(node);
165
166 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
167 }
168
RewriteITEBv(TNode node,bool prerewrite)169 RewriteResponse TheoryBVRewriter::RewriteITEBv(TNode node, bool prerewrite)
170 {
171 Node resultNode =
172 LinearRewriteStrategy<RewriteRule<EvalITEBv>,
173 RewriteRule<BvIteConstCond>,
174 RewriteRule<BvIteEqualChildren>,
175 RewriteRule<BvIteConstChildren>,
176 RewriteRule<BvIteEqualCond>>::apply(node);
177 if (resultNode != node)
178 {
179 return RewriteResponse(REWRITE_AGAIN, resultNode);
180 }
181
182 resultNode =
183 LinearRewriteStrategy<RewriteRule<BvIteMergeThenIf>,
184 RewriteRule<BvIteMergeElseIf>,
185 RewriteRule<BvIteMergeThenElse>,
186 RewriteRule<BvIteMergeElseElse>>::apply(node);
187 return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL,
188 resultNode);
189 }
190
RewriteNot(TNode node,bool prerewrite)191 RewriteResponse TheoryBVRewriter::RewriteNot(TNode node, bool prerewrite){
192 Node resultNode = node;
193
194 // // if(RewriteRule<NotXor>::applies(node)) {
195 // // resultNode = RewriteRule<NotXor>::run<false>(node);
196 // // return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
197 // // }
198 resultNode = LinearRewriteStrategy
199 < RewriteRule<EvalNot>,
200 RewriteRule<NotIdemp>
201 >::apply(node);
202
203 return RewriteResponse(REWRITE_DONE, resultNode);
204 }
205
RewriteExtract(TNode node,bool prerewrite)206 RewriteResponse TheoryBVRewriter::RewriteExtract(TNode node, bool prerewrite) {
207 Node resultNode = node;
208
209 if (RewriteRule<ExtractConcat>::applies(node)) {
210 resultNode = RewriteRule<ExtractConcat>::run<false>(node);
211 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
212 }
213
214 if (RewriteRule<ExtractSignExtend>::applies(node)) {
215 resultNode = RewriteRule<ExtractSignExtend>::run<false>(node);
216 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
217 }
218
219 if (RewriteRule<ExtractNot>::applies(node)) {
220 resultNode = RewriteRule<ExtractNot>::run<false>(node);
221 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
222 }
223
224 if (options::bvExtractArithRewrite()) {
225 if (RewriteRule<ExtractArith>::applies(node)) {
226 resultNode = RewriteRule<ExtractArith>::run<false>(node);
227 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
228 }
229 }
230
231
232 resultNode = LinearRewriteStrategy
233 < RewriteRule<ExtractConstant>,
234 RewriteRule<ExtractExtract>,
235 // We could get another extract over extract
236 RewriteRule<ExtractWhole>,
237 // At this point only Extract-Whole could apply
238 RewriteRule<ExtractMultLeadingBit>
239 >::apply(node);
240
241 return RewriteResponse(REWRITE_DONE, resultNode);
242 }
243
RewriteConcat(TNode node,bool prerewrite)244 RewriteResponse TheoryBVRewriter::RewriteConcat(TNode node, bool prerewrite)
245 {
246 Node resultNode = LinearRewriteStrategy<
247 RewriteRule<ConcatFlatten>,
248 // Flatten the top level concatenations
249 RewriteRule<ConcatExtractMerge>,
250 // Merge the adjacent extracts on non-constants
251 RewriteRule<ConcatConstantMerge>,
252 // Merge the adjacent extracts on constants
253 ApplyRuleToChildren<kind::BITVECTOR_CONCAT, ExtractWhole>>::apply(node);
254 return RewriteResponse(REWRITE_DONE, resultNode);
255 }
256
RewriteAnd(TNode node,bool prerewrite)257 RewriteResponse TheoryBVRewriter::RewriteAnd(TNode node, bool prerewrite)
258 {
259 Node resultNode = node;
260 resultNode =
261 LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
262 RewriteRule<AndSimplify>,
263 RewriteRule<AndOrXorConcatPullUp>>::apply(node);
264 if (!prerewrite)
265 {
266 resultNode =
267 LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
268
269 if (resultNode.getKind() != node.getKind())
270 {
271 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
272 }
273 }
274
275 return RewriteResponse(REWRITE_DONE, resultNode);
276 }
277
RewriteOr(TNode node,bool prerewrite)278 RewriteResponse TheoryBVRewriter::RewriteOr(TNode node, bool prerewrite)
279 {
280 Node resultNode = node;
281 resultNode =
282 LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
283 RewriteRule<OrSimplify>,
284 RewriteRule<AndOrXorConcatPullUp>>::apply(node);
285
286 if (!prerewrite)
287 {
288 resultNode =
289 LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
290
291 if (resultNode.getKind() != node.getKind())
292 {
293 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
294 }
295 }
296
297 return RewriteResponse(REWRITE_DONE, resultNode);
298 }
299
RewriteXor(TNode node,bool prerewrite)300 RewriteResponse TheoryBVRewriter::RewriteXor(TNode node, bool prerewrite)
301 {
302 Node resultNode = node;
303 resultNode = LinearRewriteStrategy<
304 RewriteRule<FlattenAssocCommut>, // flatten the expression
305 RewriteRule<XorSimplify>, // simplify duplicates and constants
306 RewriteRule<XorZero>, // checks if the constant part is zero and
307 // eliminates it
308 RewriteRule<AndOrXorConcatPullUp>,
309 RewriteRule<BitwiseSlicing>>::apply(node);
310
311 if (!prerewrite)
312 {
313 resultNode =
314 LinearRewriteStrategy<RewriteRule<XorOne>,
315 RewriteRule<BitwiseSlicing>>::apply(resultNode);
316
317 if (resultNode.getKind() != node.getKind())
318 {
319 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
320 }
321 }
322
323 return RewriteResponse(REWRITE_DONE, resultNode);
324 }
325
RewriteXnor(TNode node,bool prerewrite)326 RewriteResponse TheoryBVRewriter::RewriteXnor(TNode node, bool prerewrite) {
327 Node resultNode = LinearRewriteStrategy
328 < RewriteRule<XnorEliminate>
329 >::apply(node);
330 // need to rewrite two levels in
331 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
332 }
333
RewriteNand(TNode node,bool prerewrite)334 RewriteResponse TheoryBVRewriter::RewriteNand(TNode node, bool prerewrite) {
335 Node resultNode = LinearRewriteStrategy
336 < RewriteRule<NandEliminate>
337 >::apply(node);
338
339 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
340 }
341
RewriteNor(TNode node,bool prerewrite)342 RewriteResponse TheoryBVRewriter::RewriteNor(TNode node, bool prerewrite) {
343 Node resultNode = LinearRewriteStrategy
344 < RewriteRule<NorEliminate>
345 >::apply(node);
346
347 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
348 }
349
RewriteComp(TNode node,bool prerewrite)350 RewriteResponse TheoryBVRewriter::RewriteComp(TNode node, bool prerewrite)
351 {
352 Node resultNode =
353 LinearRewriteStrategy<RewriteRule<EvalComp>, RewriteRule<BvComp> >::apply(
354 node);
355
356 return RewriteResponse(REWRITE_DONE, resultNode);
357 }
358
RewriteMult(TNode node,bool prerewrite)359 RewriteResponse TheoryBVRewriter::RewriteMult(TNode node, bool prerewrite) {
360 Node resultNode = node;
361 resultNode = LinearRewriteStrategy
362 < RewriteRule<FlattenAssocCommut>, // flattens and sorts
363 RewriteRule<MultSimplify>, // multiplies constant part and checks for 0
364 RewriteRule<MultPow2> // replaces multiplication by a power of 2 by a shift
365 >::apply(resultNode);
366
367 // only apply if every subterm was already rewritten
368 if (!prerewrite) {
369 resultNode = LinearRewriteStrategy
370 < RewriteRule<MultDistribConst>
371 , RewriteRule<MultDistrib>
372 >::apply(resultNode);
373 }
374
375 if(resultNode == node) {
376 return RewriteResponse(REWRITE_DONE, resultNode);
377 }
378 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
379 }
380
RewritePlus(TNode node,bool prerewrite)381 RewriteResponse TheoryBVRewriter::RewritePlus(TNode node, bool prerewrite) {
382 Node resultNode = node;
383 if (prerewrite) {
384 resultNode = LinearRewriteStrategy
385 < RewriteRule<FlattenAssocCommut>
386 >::apply(node);
387 return RewriteResponse(REWRITE_DONE, resultNode);
388 }
389
390 resultNode = LinearRewriteStrategy
391 < RewriteRule<FlattenAssocCommut>,
392 RewriteRule<PlusCombineLikeTerms>
393 >::apply(node);
394
395 if (node != resultNode) {
396 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
397 }
398
399 return RewriteResponse(REWRITE_DONE, resultNode);
400 }
401
RewriteSub(TNode node,bool prerewrite)402 RewriteResponse TheoryBVRewriter::RewriteSub(TNode node, bool prerewrite){
403 // return RewriteResponse(REWRITE_DONE, node);
404 Node resultNode = LinearRewriteStrategy
405 < RewriteRule<SubEliminate>
406 >::apply(node);
407
408 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
409 }
410
RewriteNeg(TNode node,bool prerewrite)411 RewriteResponse TheoryBVRewriter::RewriteNeg(TNode node, bool prerewrite) {
412 Node resultNode = node;
413
414 resultNode = LinearRewriteStrategy
415 < RewriteRule<EvalNeg>,
416 RewriteRule<NegIdemp>,
417 RewriteRule<NegSub>
418 >::apply(node);
419
420 if (RewriteRule<NegPlus>::applies(node)) {
421 resultNode = RewriteRule<NegPlus>::run<false>(node);
422 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
423 }
424
425 if(!prerewrite) {
426 if (RewriteRule<NegMult>::applies(node)) {
427 resultNode = RewriteRule<NegMult>::run<false>(node);
428 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
429 }
430 }
431
432 return RewriteResponse(REWRITE_DONE, resultNode);
433 }
434
RewriteUdiv(TNode node,bool prerewrite)435 RewriteResponse TheoryBVRewriter::RewriteUdiv(TNode node, bool prerewrite){
436 Node resultNode = node;
437
438 if(node[1].isConst() && node[1].getConst<BitVector>().getValue() != 0) {
439 return RewriteUdivTotal(node, prerewrite);
440 }
441
442 return RewriteResponse(REWRITE_DONE, resultNode);
443 }
444
RewriteUrem(TNode node,bool prerewrite)445 RewriteResponse TheoryBVRewriter::RewriteUrem(TNode node, bool prerewrite){
446 Node resultNode = node;
447
448 if(node[1].isConst() && node[1].getConst<BitVector>().getValue() != 0) {
449 return RewriteUremTotal(node, prerewrite);
450 }
451
452 return RewriteResponse(REWRITE_DONE, resultNode);
453 }
454
RewriteUdivTotal(TNode node,bool prerewrite)455 RewriteResponse TheoryBVRewriter::RewriteUdivTotal(TNode node, bool prerewrite){
456 Node resultNode = node;
457
458 if(RewriteRule<UdivPow2>::applies(node)) {
459 resultNode = RewriteRule<UdivPow2>::run <false> (node);
460 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
461 }
462
463 resultNode =
464 LinearRewriteStrategy<RewriteRule<EvalUdiv>, RewriteRule<UdivZero>,
465 RewriteRule<UdivOne> >::apply(node);
466
467 return RewriteResponse(REWRITE_DONE, resultNode);
468 }
469
RewriteUremTotal(TNode node,bool prerewrite)470 RewriteResponse TheoryBVRewriter::RewriteUremTotal(TNode node, bool prerewrite) {
471 Node resultNode = node;
472
473 if(RewriteRule<UremPow2>::applies(node)) {
474 resultNode = RewriteRule<UremPow2>::run <false> (node);
475 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
476 }
477
478 resultNode = LinearRewriteStrategy
479 < RewriteRule<EvalUrem>,
480 RewriteRule<UremOne>,
481 RewriteRule<UremSelf>
482 >::apply(node);
483 return RewriteResponse(REWRITE_DONE, resultNode);
484 }
485
RewriteSmod(TNode node,bool prerewrite)486 RewriteResponse TheoryBVRewriter::RewriteSmod(TNode node, bool prerewrite) {
487 Node resultNode = LinearRewriteStrategy
488 < RewriteRule<SmodEliminate>
489 >::apply(node);
490
491 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
492 }
493
RewriteSdiv(TNode node,bool prerewrite)494 RewriteResponse TheoryBVRewriter::RewriteSdiv(TNode node, bool prerewrite) {
495 Node resultNode = LinearRewriteStrategy
496 < RewriteRule<SdivEliminate>
497 >::apply(node);
498
499 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
500 }
501
RewriteSrem(TNode node,bool prerewrite)502 RewriteResponse TheoryBVRewriter::RewriteSrem(TNode node, bool prerewrite) {
503 Node resultNode = LinearRewriteStrategy
504 < RewriteRule<SremEliminate>
505 >::apply(node);
506 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
507 }
508
RewriteShl(TNode node,bool prerewrite)509 RewriteResponse TheoryBVRewriter::RewriteShl(TNode node, bool prerewrite) {
510 Node resultNode = node;
511 if(RewriteRule<ShlByConst>::applies(node)) {
512 resultNode = RewriteRule<ShlByConst>::run <false> (node);
513 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
514 }
515
516 resultNode = LinearRewriteStrategy
517 < RewriteRule<EvalShl>,
518 RewriteRule<ShiftZero>
519 >::apply(node);
520
521 return RewriteResponse(REWRITE_DONE, resultNode);
522 }
523
RewriteLshr(TNode node,bool prerewrite)524 RewriteResponse TheoryBVRewriter::RewriteLshr(TNode node, bool prerewrite) {
525 Node resultNode = node;
526 if(RewriteRule<LshrByConst>::applies(node)) {
527 resultNode = RewriteRule<LshrByConst>::run <false> (node);
528 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
529 }
530
531 resultNode = LinearRewriteStrategy
532 < RewriteRule<EvalLshr>,
533 RewriteRule<ShiftZero>
534 >::apply(node);
535
536 return RewriteResponse(REWRITE_DONE, resultNode);
537 }
538
RewriteAshr(TNode node,bool prerewrite)539 RewriteResponse TheoryBVRewriter::RewriteAshr(TNode node, bool prerewrite) {
540 Node resultNode = node;
541 if(RewriteRule<AshrByConst>::applies(node)) {
542 resultNode = RewriteRule<AshrByConst>::run <false> (node);
543 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
544 }
545
546 resultNode = LinearRewriteStrategy
547 < RewriteRule<EvalAshr>,
548 RewriteRule<ShiftZero>
549 >::apply(node);
550
551 return RewriteResponse(REWRITE_DONE, resultNode);
552 }
553
554
RewriteRepeat(TNode node,bool prerewrite)555 RewriteResponse TheoryBVRewriter::RewriteRepeat(TNode node, bool prerewrite) {
556 Node resultNode = LinearRewriteStrategy
557 < RewriteRule<RepeatEliminate >
558 >::apply(node);
559
560 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
561 }
562
RewriteZeroExtend(TNode node,bool prerewrite)563 RewriteResponse TheoryBVRewriter::RewriteZeroExtend(TNode node, bool prerewrite){
564 Node resultNode = LinearRewriteStrategy
565 < RewriteRule<ZeroExtendEliminate >
566 >::apply(node);
567
568 return RewriteResponse(REWRITE_AGAIN, resultNode);
569 }
570
RewriteSignExtend(TNode node,bool prerewrite)571 RewriteResponse TheoryBVRewriter::RewriteSignExtend(TNode node, bool prerewrite) {
572 Node resultNode = LinearRewriteStrategy
573 < RewriteRule<MergeSignExtend>
574 , RewriteRule<EvalSignExtend>
575 >::apply(node);
576
577
578 if (resultNode != node) {
579 return RewriteResponse(REWRITE_AGAIN, resultNode);
580 }
581 return RewriteResponse(REWRITE_DONE, resultNode);
582 }
583
584
RewriteRotateRight(TNode node,bool prerewrite)585 RewriteResponse TheoryBVRewriter::RewriteRotateRight(TNode node, bool prerewrite) {
586 Node resultNode = LinearRewriteStrategy
587 < RewriteRule<RotateRightEliminate >
588 >::apply(node);
589
590 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
591 }
592
RewriteRotateLeft(TNode node,bool prerewrite)593 RewriteResponse TheoryBVRewriter::RewriteRotateLeft(TNode node, bool prerewrite){
594 Node resultNode = LinearRewriteStrategy
595 < RewriteRule<RotateLeftEliminate >
596 >::apply(node);
597
598 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
599 }
600
RewriteRedor(TNode node,bool prerewrite)601 RewriteResponse TheoryBVRewriter::RewriteRedor(TNode node, bool prerewrite){
602 Node resultNode = LinearRewriteStrategy
603 < RewriteRule<RedorEliminate>
604 >::apply(node);
605
606 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
607 }
608
RewriteRedand(TNode node,bool prerewrite)609 RewriteResponse TheoryBVRewriter::RewriteRedand(TNode node, bool prerewrite){
610 Node resultNode = LinearRewriteStrategy
611 < RewriteRule<RedandEliminate>
612 >::apply(node);
613
614 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
615 }
616
RewriteBVToNat(TNode node,bool prerewrite)617 RewriteResponse TheoryBVRewriter::RewriteBVToNat(TNode node, bool prerewrite) {
618 //do not use lazy rewrite strategy if equality solver is disabled
619 if( node[0].isConst() || !options::bvLazyRewriteExtf() ){
620 Node resultNode = LinearRewriteStrategy
621 < RewriteRule<BVToNatEliminate>
622 >::apply(node);
623 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
624 }else{
625 return RewriteResponse(REWRITE_DONE, node);
626 }
627 }
628
RewriteIntToBV(TNode node,bool prerewrite)629 RewriteResponse TheoryBVRewriter::RewriteIntToBV(TNode node, bool prerewrite) {
630 //do not use lazy rewrite strategy if equality solver is disabled
631 if( node[0].isConst() || !options::bvLazyRewriteExtf() ){
632 Node resultNode = LinearRewriteStrategy
633 < RewriteRule<IntToBVEliminate>
634 >::apply(node);
635
636 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
637 }else{
638 return RewriteResponse(REWRITE_DONE, node);
639 }
640 }
641
RewriteEqual(TNode node,bool prerewrite)642 RewriteResponse TheoryBVRewriter::RewriteEqual(TNode node, bool prerewrite) {
643 if (prerewrite) {
644 Node resultNode = LinearRewriteStrategy
645 < RewriteRule<FailEq>,
646 RewriteRule<SimplifyEq>,
647 RewriteRule<ReflexivityEq>
648 >::apply(node);
649 return RewriteResponse(REWRITE_DONE, resultNode);
650 }
651 else {
652 Node resultNode = LinearRewriteStrategy
653 < RewriteRule<FailEq>,
654 RewriteRule<SimplifyEq>,
655 RewriteRule<ReflexivityEq>
656 >::apply(node);
657
658 if(RewriteRule<SolveEq>::applies(resultNode)) {
659 resultNode = RewriteRule<SolveEq>::run<false>(resultNode);
660 if (resultNode != node) {
661 return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
662 }
663 }
664 return RewriteResponse(REWRITE_DONE, resultNode);
665 }
666 }
667
668
IdentityRewrite(TNode node,bool prerewrite)669 RewriteResponse TheoryBVRewriter::IdentityRewrite(TNode node, bool prerewrite) {
670 return RewriteResponse(REWRITE_DONE, node);
671 }
672
UndefinedRewrite(TNode node,bool prerewrite)673 RewriteResponse TheoryBVRewriter::UndefinedRewrite(TNode node, bool prerewrite) {
674 Debug("bv-rewrite") << "TheoryBV::UndefinedRewrite for" << node;
675 Unimplemented();
676 }
677
678
679
initializeRewrites()680 void TheoryBVRewriter::initializeRewrites() {
681
682 for(unsigned i = 0; i < kind::LAST_KIND; ++i) {
683 d_rewriteTable[i] = IdentityRewrite; //UndefinedRewrite;
684 }
685
686 d_rewriteTable [ kind::EQUAL ] = RewriteEqual;
687 d_rewriteTable [ kind::BITVECTOR_ULT ] = RewriteUlt;
688 d_rewriteTable [ kind::BITVECTOR_SLT ] = RewriteSlt;
689 d_rewriteTable [ kind::BITVECTOR_ULE ] = RewriteUle;
690 d_rewriteTable [ kind::BITVECTOR_SLE ] = RewriteSle;
691 d_rewriteTable [ kind::BITVECTOR_UGT ] = RewriteUgt;
692 d_rewriteTable [ kind::BITVECTOR_SGT ] = RewriteSgt;
693 d_rewriteTable [ kind::BITVECTOR_UGE ] = RewriteUge;
694 d_rewriteTable [ kind::BITVECTOR_SGE ] = RewriteSge;
695 d_rewriteTable [ kind::BITVECTOR_NOT ] = RewriteNot;
696 d_rewriteTable [ kind::BITVECTOR_CONCAT ] = RewriteConcat;
697 d_rewriteTable [ kind::BITVECTOR_AND ] = RewriteAnd;
698 d_rewriteTable [ kind::BITVECTOR_OR ] = RewriteOr;
699 d_rewriteTable [ kind::BITVECTOR_XOR] = RewriteXor;
700 d_rewriteTable [ kind::BITVECTOR_XNOR ] = RewriteXnor;
701 d_rewriteTable [ kind::BITVECTOR_NAND ] = RewriteNand;
702 d_rewriteTable [ kind::BITVECTOR_NOR ] = RewriteNor;
703 d_rewriteTable [ kind::BITVECTOR_COMP ] = RewriteComp;
704 d_rewriteTable [ kind::BITVECTOR_MULT ] = RewriteMult;
705 d_rewriteTable [ kind::BITVECTOR_PLUS ] = RewritePlus;
706 d_rewriteTable [ kind::BITVECTOR_SUB ] = RewriteSub;
707 d_rewriteTable [ kind::BITVECTOR_NEG ] = RewriteNeg;
708 d_rewriteTable [ kind::BITVECTOR_UDIV ] = RewriteUdiv;
709 d_rewriteTable [ kind::BITVECTOR_UREM ] = RewriteUrem;
710 d_rewriteTable [ kind::BITVECTOR_UDIV_TOTAL ] = RewriteUdivTotal;
711 d_rewriteTable [ kind::BITVECTOR_UREM_TOTAL ] = RewriteUremTotal;
712 d_rewriteTable [ kind::BITVECTOR_SMOD ] = RewriteSmod;
713 d_rewriteTable [ kind::BITVECTOR_SDIV ] = RewriteSdiv;
714 d_rewriteTable [ kind::BITVECTOR_SREM ] = RewriteSrem;
715 d_rewriteTable [ kind::BITVECTOR_SHL ] = RewriteShl;
716 d_rewriteTable [ kind::BITVECTOR_LSHR ] = RewriteLshr;
717 d_rewriteTable [ kind::BITVECTOR_ASHR ] = RewriteAshr;
718 d_rewriteTable [ kind::BITVECTOR_EXTRACT ] = RewriteExtract;
719 d_rewriteTable [ kind::BITVECTOR_REPEAT ] = RewriteRepeat;
720 d_rewriteTable [ kind::BITVECTOR_ZERO_EXTEND ] = RewriteZeroExtend;
721 d_rewriteTable [ kind::BITVECTOR_SIGN_EXTEND ] = RewriteSignExtend;
722 d_rewriteTable [ kind::BITVECTOR_ROTATE_RIGHT ] = RewriteRotateRight;
723 d_rewriteTable [ kind::BITVECTOR_ROTATE_LEFT ] = RewriteRotateLeft;
724 d_rewriteTable [ kind::BITVECTOR_REDOR ] = RewriteRedor;
725 d_rewriteTable [ kind::BITVECTOR_REDAND ] = RewriteRedand;
726 d_rewriteTable [ kind::BITVECTOR_ULTBV ] = RewriteUltBv;
727 d_rewriteTable [ kind::BITVECTOR_SLTBV ] = RewriteSltBv;
728 d_rewriteTable [ kind::BITVECTOR_ITE ] = RewriteITEBv;
729
730 d_rewriteTable [ kind::BITVECTOR_TO_NAT ] = RewriteBVToNat;
731 d_rewriteTable [ kind::INT_TO_BITVECTOR ] = RewriteIntToBV;
732 }
733
eliminateBVSDiv(TNode node)734 Node TheoryBVRewriter::eliminateBVSDiv(TNode node) {
735 Node result = bv::LinearRewriteStrategy <
736 bv::RewriteRule<bv::SremEliminate>,
737 bv::RewriteRule<bv::SdivEliminate>,
738 bv::RewriteRule<bv::SmodEliminate>
739 >::apply(node);
740 return result;
741 }
742