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