1 |
|
/****************************************************************************** |
2 |
|
* Top contributors (to current version): |
3 |
|
* Liana Hadarean, Aina Niemetz, Andrew Reynolds |
4 |
|
* |
5 |
|
* This file is part of the cvc5 project. |
6 |
|
* |
7 |
|
* Copyright (c) 2009-2021 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. |
11 |
|
* **************************************************************************** |
12 |
|
* |
13 |
|
* [[ Add one-line brief description here ]] |
14 |
|
* |
15 |
|
* [[ Add lengthier description here ]] |
16 |
|
* \todo document this file |
17 |
|
*/ |
18 |
|
|
19 |
|
#include "options/bv_options.h" |
20 |
|
#include "theory/bv/theory_bv_rewrite_rules.h" |
21 |
|
#include "theory/bv/theory_bv_rewrite_rules_constant_evaluation.h" |
22 |
|
#include "theory/bv/theory_bv_rewrite_rules_core.h" |
23 |
|
#include "theory/bv/theory_bv_rewrite_rules_normalization.h" |
24 |
|
#include "theory/bv/theory_bv_rewrite_rules_operator_elimination.h" |
25 |
|
#include "theory/bv/theory_bv_rewrite_rules_simplification.h" |
26 |
|
#include "theory/bv/theory_bv_rewriter.h" |
27 |
|
#include "theory/theory.h" |
28 |
|
|
29 |
|
using namespace cvc5; |
30 |
|
using namespace cvc5::theory; |
31 |
|
using namespace cvc5::theory::bv; |
32 |
|
|
33 |
9943 |
TheoryBVRewriter::TheoryBVRewriter() { initializeRewrites(); } |
34 |
|
|
35 |
1326347 |
RewriteResponse TheoryBVRewriter::preRewrite(TNode node) { |
36 |
1326347 |
RewriteResponse res = d_rewriteTable[node.getKind()](node, true); |
37 |
1326347 |
if (res.d_node != node) |
38 |
|
{ |
39 |
443845 |
Debug("bitvector-rewrite") << "TheoryBV::preRewrite " << node << std::endl; |
40 |
887690 |
Debug("bitvector-rewrite") |
41 |
443845 |
<< "TheoryBV::preRewrite to " << res.d_node << std::endl; |
42 |
|
} |
43 |
1326347 |
return res; |
44 |
|
} |
45 |
|
|
46 |
1567318 |
RewriteResponse TheoryBVRewriter::postRewrite(TNode node) { |
47 |
1567318 |
RewriteResponse res = d_rewriteTable[node.getKind()](node, false); |
48 |
1567318 |
if (res.d_node != node) |
49 |
|
{ |
50 |
248534 |
Debug("bitvector-rewrite") << "TheoryBV::postRewrite " << node << std::endl; |
51 |
497068 |
Debug("bitvector-rewrite") |
52 |
248534 |
<< "TheoryBV::postRewrite to " << res.d_node << std::endl; |
53 |
|
} |
54 |
1567318 |
return res; |
55 |
|
} |
56 |
|
|
57 |
414711 |
TrustNode TheoryBVRewriter::expandDefinition(Node node) |
58 |
|
{ |
59 |
829422 |
Debug("bitvector-expandDefinition") |
60 |
414711 |
<< "TheoryBV::expandDefinition(" << node << ")" << std::endl; |
61 |
829422 |
Node ret; |
62 |
414711 |
switch (node.getKind()) |
63 |
|
{ |
64 |
10 |
case kind::BITVECTOR_SDIV: |
65 |
|
case kind::BITVECTOR_SREM: |
66 |
10 |
case kind::BITVECTOR_SMOD: ret = eliminateBVSDiv(node); break; |
67 |
50 |
case kind::BITVECTOR_TO_NAT: |
68 |
|
|
69 |
50 |
ret = utils::eliminateBv2Nat(node); |
70 |
|
|
71 |
50 |
break; |
72 |
46 |
case kind::INT_TO_BITVECTOR: |
73 |
|
|
74 |
46 |
ret = utils::eliminateInt2Bv(node); |
75 |
|
|
76 |
46 |
break; |
77 |
414605 |
default: break; |
78 |
|
} |
79 |
414711 |
if (!ret.isNull() && node != ret) |
80 |
|
{ |
81 |
106 |
return TrustNode::mkTrustRewrite(node, ret, nullptr); |
82 |
|
} |
83 |
414605 |
return TrustNode::null(); |
84 |
|
} |
85 |
|
|
86 |
619917 |
RewriteResponse TheoryBVRewriter::RewriteBitOf(TNode node, bool prerewrite) |
87 |
|
{ |
88 |
1239834 |
Node resultNode = LinearRewriteStrategy<RewriteRule<BitOfConst>>::apply(node); |
89 |
1239834 |
return RewriteResponse(REWRITE_DONE, resultNode); |
90 |
|
} |
91 |
|
|
92 |
95561 |
RewriteResponse TheoryBVRewriter::RewriteUlt(TNode node, bool prerewrite) { |
93 |
|
// reduce common subexpressions on both sides |
94 |
|
Node resultNode = LinearRewriteStrategy |
95 |
|
< RewriteRule<EvalUlt>, // if both arguments are constants evaluates |
96 |
|
RewriteRule<UltZero>, // a < 0 rewrites to false, |
97 |
|
RewriteRule<SignExtendUltConst>, |
98 |
|
RewriteRule<ZeroExtendUltConst> |
99 |
191122 |
>::apply(node); |
100 |
|
|
101 |
95561 |
return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL, |
102 |
286683 |
resultNode); |
103 |
|
} |
104 |
|
|
105 |
4774 |
RewriteResponse TheoryBVRewriter::RewriteUltBv(TNode node, bool prerewrite) { |
106 |
|
// reduce common subexpressions on both sides |
107 |
|
Node resultNode = LinearRewriteStrategy |
108 |
|
< RewriteRule<EvalUltBv> |
109 |
9548 |
>::apply(node); |
110 |
|
|
111 |
9548 |
return RewriteResponse(REWRITE_DONE, resultNode); |
112 |
|
} |
113 |
|
|
114 |
|
|
115 |
103040 |
RewriteResponse TheoryBVRewriter::RewriteSlt(TNode node, bool prerewrite){ |
116 |
|
Node resultNode = LinearRewriteStrategy |
117 |
|
< RewriteRule<EvalSlt>, |
118 |
|
RewriteRule<MultSltMult> |
119 |
206080 |
>::apply(node); |
120 |
|
|
121 |
206080 |
return RewriteResponse(REWRITE_DONE, resultNode); |
122 |
|
|
123 |
|
// Node resultNode = LinearRewriteStrategy |
124 |
|
// < RewriteRule < SltEliminate > |
125 |
|
// // a <_s b ==> a + 2^{n-1} <_u b + 2^{n-1} |
126 |
|
// >::apply(node); |
127 |
|
|
128 |
|
// return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
129 |
|
} |
130 |
|
|
131 |
7571 |
RewriteResponse TheoryBVRewriter::RewriteSltBv(TNode node, bool prerewrite){ |
132 |
|
Node resultNode = LinearRewriteStrategy |
133 |
|
< RewriteRule < EvalSltBv > |
134 |
15142 |
>::apply(node); |
135 |
|
|
136 |
15142 |
return RewriteResponse(REWRITE_DONE, resultNode); |
137 |
|
} |
138 |
|
|
139 |
6428 |
RewriteResponse TheoryBVRewriter::RewriteUle(TNode node, bool prerewrite){ |
140 |
|
Node resultNode = LinearRewriteStrategy |
141 |
|
< RewriteRule<EvalUle>, |
142 |
|
RewriteRule<UleMax>, |
143 |
|
RewriteRule<ZeroUle>, |
144 |
|
RewriteRule<UleZero>, |
145 |
|
RewriteRule<UleSelf>, |
146 |
|
RewriteRule<UleEliminate> |
147 |
12856 |
>::apply(node); |
148 |
12856 |
return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN, resultNode); |
149 |
|
} |
150 |
|
|
151 |
6800 |
RewriteResponse TheoryBVRewriter::RewriteSle(TNode node, bool prerewrite){ |
152 |
|
Node resultNode = LinearRewriteStrategy |
153 |
|
< RewriteRule <EvalSle>, |
154 |
|
RewriteRule <SleEliminate> |
155 |
13600 |
>::apply(node); |
156 |
13600 |
return RewriteResponse(resultNode == node? REWRITE_DONE : REWRITE_AGAIN, resultNode); |
157 |
|
} |
158 |
|
|
159 |
3643 |
RewriteResponse TheoryBVRewriter::RewriteUgt(TNode node, bool prerewrite){ |
160 |
|
Node resultNode = |
161 |
|
LinearRewriteStrategy<RewriteRule<UgtUrem>, |
162 |
7286 |
RewriteRule<UgtEliminate>>::apply(node); |
163 |
|
|
164 |
7286 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
165 |
|
} |
166 |
|
|
167 |
3715 |
RewriteResponse TheoryBVRewriter::RewriteSgt(TNode node, bool prerewrite){ |
168 |
|
Node resultNode = LinearRewriteStrategy |
169 |
|
< RewriteRule<SgtEliminate> |
170 |
|
//RewriteRule<SltEliminate> |
171 |
7430 |
>::apply(node); |
172 |
|
|
173 |
7430 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
174 |
|
} |
175 |
|
|
176 |
3229 |
RewriteResponse TheoryBVRewriter::RewriteUge(TNode node, bool prerewrite){ |
177 |
|
Node resultNode = LinearRewriteStrategy |
178 |
|
< RewriteRule<UgeEliminate> |
179 |
6458 |
>::apply(node); |
180 |
|
|
181 |
6458 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
182 |
|
} |
183 |
|
|
184 |
3270 |
RewriteResponse TheoryBVRewriter::RewriteSge(TNode node, bool prerewrite){ |
185 |
|
Node resultNode = LinearRewriteStrategy |
186 |
|
< RewriteRule<SgeEliminate> |
187 |
|
// RewriteRule<SleEliminate> |
188 |
6540 |
>::apply(node); |
189 |
|
|
190 |
6540 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
191 |
|
} |
192 |
|
|
193 |
29571 |
RewriteResponse TheoryBVRewriter::RewriteITEBv(TNode node, bool prerewrite) |
194 |
|
{ |
195 |
|
Node resultNode = |
196 |
|
LinearRewriteStrategy<RewriteRule<EvalITEBv>, |
197 |
|
RewriteRule<BvIteConstCond>, |
198 |
59142 |
RewriteRule<BvIteEqualChildren>>::apply(node); |
199 |
|
// If the node has been rewritten, we return here because we need to make |
200 |
|
// sure that `BvIteEqualChildren` has been applied until we reach a fixpoint |
201 |
|
// before applying `BvIteConstChildren`. Otherwise, `BvIteConstChildren` |
202 |
|
// potentially performs an unsound rewrite. Returning hands back the control |
203 |
|
// to the `Rewriter` which will then call this method again, ensuring that |
204 |
|
// the rewrites are applied in the correct order. |
205 |
29571 |
if (resultNode != node) |
206 |
|
{ |
207 |
2522 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
208 |
|
} |
209 |
|
|
210 |
27049 |
resultNode = LinearRewriteStrategy<RewriteRule<BvIteConstChildren>, |
211 |
54098 |
RewriteRule<BvIteEqualCond>>::apply(node); |
212 |
27049 |
if (resultNode != node) |
213 |
|
{ |
214 |
307 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
215 |
|
} |
216 |
|
|
217 |
26742 |
resultNode = |
218 |
|
LinearRewriteStrategy<RewriteRule<BvIteMergeThenIf>, |
219 |
|
RewriteRule<BvIteMergeElseIf>, |
220 |
|
RewriteRule<BvIteMergeThenElse>, |
221 |
53484 |
RewriteRule<BvIteMergeElseElse>>::apply(node); |
222 |
26742 |
return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL, |
223 |
53484 |
resultNode); |
224 |
|
} |
225 |
|
|
226 |
93059 |
RewriteResponse TheoryBVRewriter::RewriteNot(TNode node, bool prerewrite){ |
227 |
186118 |
Node resultNode = node; |
228 |
|
|
229 |
|
// // if(RewriteRule<NotXor>::applies(node)) { |
230 |
|
// // resultNode = RewriteRule<NotXor>::run<false>(node); |
231 |
|
// // return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
232 |
|
// // } |
233 |
93059 |
resultNode = LinearRewriteStrategy |
234 |
|
< RewriteRule<EvalNot>, |
235 |
|
RewriteRule<NotIdemp> |
236 |
186118 |
>::apply(node); |
237 |
|
|
238 |
186118 |
return RewriteResponse(REWRITE_DONE, resultNode); |
239 |
|
} |
240 |
|
|
241 |
117530 |
RewriteResponse TheoryBVRewriter::RewriteExtract(TNode node, bool prerewrite) { |
242 |
235060 |
Node resultNode = node; |
243 |
|
|
244 |
117530 |
if (RewriteRule<ExtractConcat>::applies(node)) { |
245 |
11048 |
resultNode = RewriteRule<ExtractConcat>::run<false>(node); |
246 |
11048 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
247 |
|
} |
248 |
|
|
249 |
106482 |
if (RewriteRule<ExtractSignExtend>::applies(node)) { |
250 |
533 |
resultNode = RewriteRule<ExtractSignExtend>::run<false>(node); |
251 |
533 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
252 |
|
} |
253 |
|
|
254 |
105949 |
if (RewriteRule<ExtractNot>::applies(node)) { |
255 |
1682 |
resultNode = RewriteRule<ExtractNot>::run<false>(node); |
256 |
1682 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
257 |
|
} |
258 |
|
|
259 |
104267 |
if (options::bvExtractArithRewrite()) { |
260 |
|
if (RewriteRule<ExtractArith>::applies(node)) { |
261 |
|
resultNode = RewriteRule<ExtractArith>::run<false>(node); |
262 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
263 |
|
} |
264 |
|
} |
265 |
|
|
266 |
|
|
267 |
104267 |
resultNode = LinearRewriteStrategy |
268 |
|
< RewriteRule<ExtractConstant>, |
269 |
|
RewriteRule<ExtractExtract>, |
270 |
|
// We could get another extract over extract |
271 |
|
RewriteRule<ExtractWhole>, |
272 |
|
// At this point only Extract-Whole could apply |
273 |
|
RewriteRule<ExtractMultLeadingBit> |
274 |
208534 |
>::apply(node); |
275 |
|
|
276 |
104267 |
return RewriteResponse(REWRITE_DONE, resultNode); |
277 |
|
} |
278 |
|
|
279 |
169504 |
RewriteResponse TheoryBVRewriter::RewriteConcat(TNode node, bool prerewrite) |
280 |
|
{ |
281 |
|
Node resultNode = LinearRewriteStrategy< |
282 |
|
RewriteRule<ConcatFlatten>, |
283 |
|
// Flatten the top level concatenations |
284 |
|
RewriteRule<ConcatExtractMerge>, |
285 |
|
// Merge the adjacent extracts on non-constants |
286 |
|
RewriteRule<ConcatConstantMerge>, |
287 |
|
// Merge the adjacent extracts on constants |
288 |
339008 |
ApplyRuleToChildren<kind::BITVECTOR_CONCAT, ExtractWhole>>::apply(node); |
289 |
339008 |
return RewriteResponse(REWRITE_DONE, resultNode); |
290 |
|
} |
291 |
|
|
292 |
123413 |
RewriteResponse TheoryBVRewriter::RewriteAnd(TNode node, bool prerewrite) |
293 |
|
{ |
294 |
246826 |
Node resultNode = node; |
295 |
123413 |
resultNode = |
296 |
|
LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>, |
297 |
|
RewriteRule<AndSimplify>, |
298 |
246826 |
RewriteRule<AndOrXorConcatPullUp>>::apply(node); |
299 |
123413 |
if (!prerewrite) |
300 |
|
{ |
301 |
60521 |
resultNode = |
302 |
121042 |
LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode); |
303 |
|
|
304 |
60521 |
if (resultNode.getKind() != node.getKind()) |
305 |
|
{ |
306 |
27239 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
307 |
|
} |
308 |
|
} |
309 |
|
|
310 |
96174 |
return RewriteResponse(REWRITE_DONE, resultNode); |
311 |
|
} |
312 |
|
|
313 |
154764 |
RewriteResponse TheoryBVRewriter::RewriteOr(TNode node, bool prerewrite) |
314 |
|
{ |
315 |
309528 |
Node resultNode = node; |
316 |
154764 |
resultNode = |
317 |
|
LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>, |
318 |
|
RewriteRule<OrSimplify>, |
319 |
309528 |
RewriteRule<AndOrXorConcatPullUp>>::apply(node); |
320 |
|
|
321 |
154764 |
if (!prerewrite) |
322 |
|
{ |
323 |
80498 |
resultNode = |
324 |
160996 |
LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode); |
325 |
|
|
326 |
80498 |
if (resultNode.getKind() != node.getKind()) |
327 |
|
{ |
328 |
32235 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
329 |
|
} |
330 |
|
} |
331 |
|
|
332 |
122529 |
return RewriteResponse(REWRITE_DONE, resultNode); |
333 |
|
} |
334 |
|
|
335 |
9133 |
RewriteResponse TheoryBVRewriter::RewriteXor(TNode node, bool prerewrite) |
336 |
|
{ |
337 |
18266 |
Node resultNode = node; |
338 |
9133 |
resultNode = LinearRewriteStrategy< |
339 |
|
RewriteRule<FlattenAssocCommut>, // flatten the expression |
340 |
|
RewriteRule<XorSimplify>, // simplify duplicates and constants |
341 |
|
RewriteRule<XorZero>, // checks if the constant part is zero and |
342 |
|
// eliminates it |
343 |
|
RewriteRule<AndOrXorConcatPullUp>, |
344 |
18266 |
RewriteRule<BitwiseSlicing>>::apply(node); |
345 |
|
|
346 |
9133 |
if (!prerewrite) |
347 |
|
{ |
348 |
4822 |
resultNode = |
349 |
|
LinearRewriteStrategy<RewriteRule<XorOne>, |
350 |
9644 |
RewriteRule<BitwiseSlicing>>::apply(resultNode); |
351 |
|
|
352 |
4822 |
if (resultNode.getKind() != node.getKind()) |
353 |
|
{ |
354 |
1404 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
355 |
|
} |
356 |
|
} |
357 |
|
|
358 |
7729 |
return RewriteResponse(REWRITE_DONE, resultNode); |
359 |
|
} |
360 |
|
|
361 |
861 |
RewriteResponse TheoryBVRewriter::RewriteXnor(TNode node, bool prerewrite) { |
362 |
|
Node resultNode = LinearRewriteStrategy |
363 |
|
< RewriteRule<XnorEliminate> |
364 |
1722 |
>::apply(node); |
365 |
|
// need to rewrite two levels in |
366 |
1722 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
367 |
|
} |
368 |
|
|
369 |
591 |
RewriteResponse TheoryBVRewriter::RewriteNand(TNode node, bool prerewrite) { |
370 |
|
Node resultNode = LinearRewriteStrategy |
371 |
|
< RewriteRule<NandEliminate> |
372 |
1182 |
>::apply(node); |
373 |
|
|
374 |
1182 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
375 |
|
} |
376 |
|
|
377 |
742 |
RewriteResponse TheoryBVRewriter::RewriteNor(TNode node, bool prerewrite) { |
378 |
|
Node resultNode = LinearRewriteStrategy |
379 |
|
< RewriteRule<NorEliminate> |
380 |
1484 |
>::apply(node); |
381 |
|
|
382 |
1484 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
383 |
|
} |
384 |
|
|
385 |
178475 |
RewriteResponse TheoryBVRewriter::RewriteComp(TNode node, bool prerewrite) |
386 |
|
{ |
387 |
356950 |
Node resultNode = LinearRewriteStrategy<RewriteRule<EvalComp>>::apply(node); |
388 |
|
|
389 |
178475 |
if (node == resultNode && RewriteRule<BvComp>::applies(node)) |
390 |
|
{ |
391 |
1618 |
resultNode = RewriteRule<BvComp>::run<false>(node); |
392 |
1618 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
393 |
|
} |
394 |
|
|
395 |
176857 |
return RewriteResponse(REWRITE_DONE, resultNode); |
396 |
|
} |
397 |
|
|
398 |
496 |
RewriteResponse TheoryBVRewriter::RewriteEagerAtom(TNode node, bool prerewrite) |
399 |
|
{ |
400 |
|
Node resultNode = |
401 |
992 |
LinearRewriteStrategy<RewriteRule<EvalEagerAtom>>::apply(node); |
402 |
|
|
403 |
992 |
return RewriteResponse(REWRITE_DONE, resultNode); |
404 |
|
} |
405 |
|
|
406 |
234742 |
RewriteResponse TheoryBVRewriter::RewriteMult(TNode node, bool prerewrite) { |
407 |
469484 |
Node resultNode = node; |
408 |
234742 |
resultNode = LinearRewriteStrategy |
409 |
|
< RewriteRule<FlattenAssocCommut>, // flattens and sorts |
410 |
|
RewriteRule<MultSimplify>, // multiplies constant part and checks for 0 |
411 |
|
RewriteRule<MultPow2> // replaces multiplication by a power of 2 by a shift |
412 |
469484 |
>::apply(resultNode); |
413 |
|
|
414 |
|
// only apply if every subterm was already rewritten |
415 |
234742 |
if (!prerewrite) { |
416 |
89109 |
resultNode = LinearRewriteStrategy |
417 |
|
< RewriteRule<MultDistribConst> |
418 |
|
, RewriteRule<MultDistrib> |
419 |
178218 |
>::apply(resultNode); |
420 |
|
} |
421 |
|
|
422 |
234742 |
if(resultNode == node) { |
423 |
147649 |
return RewriteResponse(REWRITE_DONE, resultNode); |
424 |
|
} |
425 |
87093 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
426 |
|
} |
427 |
|
|
428 |
129040 |
RewriteResponse TheoryBVRewriter::RewriteAdd(TNode node, bool prerewrite) |
429 |
|
{ |
430 |
258080 |
Node resultNode = node; |
431 |
129040 |
if (prerewrite) { |
432 |
56154 |
resultNode = LinearRewriteStrategy |
433 |
|
< RewriteRule<FlattenAssocCommut> |
434 |
112308 |
>::apply(node); |
435 |
56154 |
return RewriteResponse(REWRITE_DONE, resultNode); |
436 |
|
} |
437 |
|
|
438 |
72886 |
resultNode = |
439 |
|
LinearRewriteStrategy<RewriteRule<FlattenAssocCommut>, |
440 |
145772 |
RewriteRule<AddCombineLikeTerms>>::apply(node); |
441 |
|
|
442 |
72886 |
if (node != resultNode) { |
443 |
38308 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
444 |
|
} |
445 |
|
|
446 |
34578 |
return RewriteResponse(REWRITE_DONE, resultNode); |
447 |
|
} |
448 |
|
|
449 |
2465 |
RewriteResponse TheoryBVRewriter::RewriteSub(TNode node, bool prerewrite){ |
450 |
|
// return RewriteResponse(REWRITE_DONE, node); |
451 |
|
Node resultNode = LinearRewriteStrategy |
452 |
|
< RewriteRule<SubEliminate> |
453 |
4930 |
>::apply(node); |
454 |
|
|
455 |
4930 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
456 |
|
} |
457 |
|
|
458 |
32666 |
RewriteResponse TheoryBVRewriter::RewriteNeg(TNode node, bool prerewrite) { |
459 |
65332 |
Node resultNode = node; |
460 |
|
|
461 |
32666 |
resultNode = LinearRewriteStrategy |
462 |
|
< RewriteRule<EvalNeg>, |
463 |
|
RewriteRule<NegIdemp>, |
464 |
|
RewriteRule<NegSub> |
465 |
65332 |
>::apply(node); |
466 |
|
|
467 |
32666 |
if (RewriteRule<NegAdd>::applies(node)) |
468 |
|
{ |
469 |
1250 |
resultNode = RewriteRule<NegAdd>::run<false>(node); |
470 |
1250 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
471 |
|
} |
472 |
|
|
473 |
31416 |
if(!prerewrite) { |
474 |
17192 |
if (RewriteRule<NegMult>::applies(node)) { |
475 |
|
resultNode = RewriteRule<NegMult>::run<false>(node); |
476 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
477 |
|
} |
478 |
|
} |
479 |
|
|
480 |
31416 |
return RewriteResponse(REWRITE_DONE, resultNode); |
481 |
|
} |
482 |
|
|
483 |
23893 |
RewriteResponse TheoryBVRewriter::RewriteUdiv(TNode node, bool prerewrite){ |
484 |
47786 |
Node resultNode = node; |
485 |
|
|
486 |
23893 |
if(RewriteRule<UdivPow2>::applies(node)) { |
487 |
1440 |
resultNode = RewriteRule<UdivPow2>::run <false> (node); |
488 |
1440 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
489 |
|
} |
490 |
|
|
491 |
22453 |
resultNode = |
492 |
|
LinearRewriteStrategy<RewriteRule<EvalUdiv>, RewriteRule<UdivZero>, |
493 |
44906 |
RewriteRule<UdivOne> >::apply(node); |
494 |
|
|
495 |
22453 |
return RewriteResponse(REWRITE_DONE, resultNode); |
496 |
|
} |
497 |
|
|
498 |
23721 |
RewriteResponse TheoryBVRewriter::RewriteUrem(TNode node, bool prerewrite) |
499 |
|
{ |
500 |
47442 |
Node resultNode = node; |
501 |
|
|
502 |
23721 |
if(RewriteRule<UremPow2>::applies(node)) { |
503 |
1183 |
resultNode = RewriteRule<UremPow2>::run <false> (node); |
504 |
1183 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
505 |
|
} |
506 |
|
|
507 |
22538 |
resultNode = LinearRewriteStrategy |
508 |
|
< RewriteRule<EvalUrem>, |
509 |
|
RewriteRule<UremOne>, |
510 |
|
RewriteRule<UremSelf> |
511 |
45076 |
>::apply(node); |
512 |
22538 |
return RewriteResponse(REWRITE_DONE, resultNode); |
513 |
|
} |
514 |
|
|
515 |
114 |
RewriteResponse TheoryBVRewriter::RewriteSmod(TNode node, bool prerewrite) { |
516 |
|
Node resultNode = LinearRewriteStrategy |
517 |
|
< RewriteRule<SmodEliminate> |
518 |
228 |
>::apply(node); |
519 |
|
|
520 |
228 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
521 |
|
} |
522 |
|
|
523 |
146 |
RewriteResponse TheoryBVRewriter::RewriteSdiv(TNode node, bool prerewrite) { |
524 |
|
Node resultNode = LinearRewriteStrategy |
525 |
|
< RewriteRule<SdivEliminate> |
526 |
292 |
>::apply(node); |
527 |
|
|
528 |
292 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
529 |
|
} |
530 |
|
|
531 |
68 |
RewriteResponse TheoryBVRewriter::RewriteSrem(TNode node, bool prerewrite) { |
532 |
|
Node resultNode = LinearRewriteStrategy |
533 |
|
< RewriteRule<SremEliminate> |
534 |
136 |
>::apply(node); |
535 |
136 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
536 |
|
} |
537 |
|
|
538 |
23715 |
RewriteResponse TheoryBVRewriter::RewriteShl(TNode node, bool prerewrite) { |
539 |
47430 |
Node resultNode = node; |
540 |
23715 |
if(RewriteRule<ShlByConst>::applies(node)) { |
541 |
15183 |
resultNode = RewriteRule<ShlByConst>::run <false> (node); |
542 |
15183 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
543 |
|
} |
544 |
|
|
545 |
8532 |
resultNode = LinearRewriteStrategy |
546 |
|
< RewriteRule<EvalShl>, |
547 |
|
RewriteRule<ShiftZero> |
548 |
17064 |
>::apply(node); |
549 |
|
|
550 |
8532 |
return RewriteResponse(REWRITE_DONE, resultNode); |
551 |
|
} |
552 |
|
|
553 |
27335 |
RewriteResponse TheoryBVRewriter::RewriteLshr(TNode node, bool prerewrite) { |
554 |
54670 |
Node resultNode = node; |
555 |
27335 |
if(RewriteRule<LshrByConst>::applies(node)) { |
556 |
15781 |
resultNode = RewriteRule<LshrByConst>::run <false> (node); |
557 |
15781 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
558 |
|
} |
559 |
|
|
560 |
11554 |
resultNode = LinearRewriteStrategy |
561 |
|
< RewriteRule<EvalLshr>, |
562 |
|
RewriteRule<ShiftZero> |
563 |
23108 |
>::apply(node); |
564 |
|
|
565 |
11554 |
return RewriteResponse(REWRITE_DONE, resultNode); |
566 |
|
} |
567 |
|
|
568 |
6205 |
RewriteResponse TheoryBVRewriter::RewriteAshr(TNode node, bool prerewrite) { |
569 |
12410 |
Node resultNode = node; |
570 |
6205 |
if(RewriteRule<AshrByConst>::applies(node)) { |
571 |
771 |
resultNode = RewriteRule<AshrByConst>::run <false> (node); |
572 |
771 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
573 |
|
} |
574 |
|
|
575 |
5434 |
resultNode = LinearRewriteStrategy |
576 |
|
< RewriteRule<EvalAshr>, |
577 |
|
RewriteRule<ShiftZero> |
578 |
10868 |
>::apply(node); |
579 |
|
|
580 |
5434 |
return RewriteResponse(REWRITE_DONE, resultNode); |
581 |
|
} |
582 |
|
|
583 |
|
|
584 |
734 |
RewriteResponse TheoryBVRewriter::RewriteRepeat(TNode node, bool prerewrite) { |
585 |
|
Node resultNode = LinearRewriteStrategy |
586 |
|
< RewriteRule<RepeatEliminate > |
587 |
1468 |
>::apply(node); |
588 |
|
|
589 |
1468 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
590 |
|
} |
591 |
|
|
592 |
10023 |
RewriteResponse TheoryBVRewriter::RewriteZeroExtend(TNode node, bool prerewrite){ |
593 |
|
Node resultNode = LinearRewriteStrategy |
594 |
|
< RewriteRule<ZeroExtendEliminate > |
595 |
20046 |
>::apply(node); |
596 |
|
|
597 |
20046 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
598 |
|
} |
599 |
|
|
600 |
54931 |
RewriteResponse TheoryBVRewriter::RewriteSignExtend(TNode node, bool prerewrite) { |
601 |
|
Node resultNode = LinearRewriteStrategy |
602 |
|
< RewriteRule<MergeSignExtend> |
603 |
|
, RewriteRule<EvalSignExtend> |
604 |
109862 |
>::apply(node); |
605 |
|
|
606 |
|
|
607 |
54931 |
if (resultNode != node) { |
608 |
2049 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
609 |
|
} |
610 |
52882 |
return RewriteResponse(REWRITE_DONE, resultNode); |
611 |
|
} |
612 |
|
|
613 |
|
|
614 |
767 |
RewriteResponse TheoryBVRewriter::RewriteRotateRight(TNode node, bool prerewrite) { |
615 |
|
Node resultNode = LinearRewriteStrategy |
616 |
|
< RewriteRule<RotateRightEliminate > |
617 |
1534 |
>::apply(node); |
618 |
|
|
619 |
1534 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
620 |
|
} |
621 |
|
|
622 |
629 |
RewriteResponse TheoryBVRewriter::RewriteRotateLeft(TNode node, bool prerewrite){ |
623 |
|
Node resultNode = LinearRewriteStrategy |
624 |
|
< RewriteRule<RotateLeftEliminate > |
625 |
1258 |
>::apply(node); |
626 |
|
|
627 |
1258 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
628 |
|
} |
629 |
|
|
630 |
|
RewriteResponse TheoryBVRewriter::RewriteRedor(TNode node, bool prerewrite){ |
631 |
|
Node resultNode = LinearRewriteStrategy |
632 |
|
< RewriteRule<RedorEliminate> |
633 |
|
>::apply(node); |
634 |
|
|
635 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
636 |
|
} |
637 |
|
|
638 |
|
RewriteResponse TheoryBVRewriter::RewriteRedand(TNode node, bool prerewrite){ |
639 |
|
Node resultNode = LinearRewriteStrategy |
640 |
|
< RewriteRule<RedandEliminate> |
641 |
|
>::apply(node); |
642 |
|
|
643 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
644 |
|
} |
645 |
|
|
646 |
1261 |
RewriteResponse TheoryBVRewriter::RewriteBVToNat(TNode node, bool prerewrite) { |
647 |
1261 |
if (node[0].isConst()) |
648 |
|
{ |
649 |
|
Node resultNode = LinearRewriteStrategy |
650 |
|
< RewriteRule<BVToNatEliminate> |
651 |
644 |
>::apply(node); |
652 |
322 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
653 |
|
}else{ |
654 |
939 |
return RewriteResponse(REWRITE_DONE, node); |
655 |
|
} |
656 |
|
} |
657 |
|
|
658 |
823 |
RewriteResponse TheoryBVRewriter::RewriteIntToBV(TNode node, bool prerewrite) { |
659 |
823 |
if (node[0].isConst()) |
660 |
|
{ |
661 |
|
Node resultNode = LinearRewriteStrategy |
662 |
|
< RewriteRule<IntToBVEliminate> |
663 |
628 |
>::apply(node); |
664 |
|
|
665 |
314 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
666 |
|
}else{ |
667 |
509 |
return RewriteResponse(REWRITE_DONE, node); |
668 |
|
} |
669 |
|
} |
670 |
|
|
671 |
392284 |
RewriteResponse TheoryBVRewriter::RewriteEqual(TNode node, bool prerewrite) { |
672 |
392284 |
if (prerewrite) { |
673 |
|
Node resultNode = LinearRewriteStrategy |
674 |
|
< RewriteRule<FailEq>, |
675 |
|
RewriteRule<SimplifyEq>, |
676 |
|
RewriteRule<ReflexivityEq> |
677 |
315298 |
>::apply(node); |
678 |
157649 |
return RewriteResponse(REWRITE_DONE, resultNode); |
679 |
|
} |
680 |
|
else { |
681 |
|
Node resultNode = LinearRewriteStrategy |
682 |
|
< RewriteRule<FailEq>, |
683 |
|
RewriteRule<SimplifyEq>, |
684 |
|
RewriteRule<ReflexivityEq> |
685 |
469270 |
>::apply(node); |
686 |
|
|
687 |
234635 |
if(RewriteRule<SolveEq>::applies(resultNode)) { |
688 |
135261 |
resultNode = RewriteRule<SolveEq>::run<false>(resultNode); |
689 |
135261 |
if (resultNode != node) { |
690 |
5783 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
691 |
|
} |
692 |
|
} |
693 |
228852 |
return RewriteResponse(REWRITE_DONE, resultNode); |
694 |
|
} |
695 |
|
} |
696 |
|
|
697 |
|
|
698 |
192016 |
RewriteResponse TheoryBVRewriter::IdentityRewrite(TNode node, bool prerewrite) { |
699 |
192016 |
return RewriteResponse(REWRITE_DONE, node); |
700 |
|
} |
701 |
|
|
702 |
|
RewriteResponse TheoryBVRewriter::UndefinedRewrite(TNode node, bool prerewrite) { |
703 |
|
Debug("bv-rewrite") << "TheoryBV::UndefinedRewrite for" << node; |
704 |
|
Unimplemented(); |
705 |
|
} |
706 |
|
|
707 |
|
|
708 |
|
|
709 |
9943 |
void TheoryBVRewriter::initializeRewrites() { |
710 |
|
|
711 |
3261304 |
for(unsigned i = 0; i < kind::LAST_KIND; ++i) { |
712 |
3251361 |
d_rewriteTable[i] = IdentityRewrite; //UndefinedRewrite; |
713 |
|
} |
714 |
|
|
715 |
9943 |
d_rewriteTable [ kind::EQUAL ] = RewriteEqual; |
716 |
9943 |
d_rewriteTable[kind::BITVECTOR_BITOF] = RewriteBitOf; |
717 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ULT ] = RewriteUlt; |
718 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SLT ] = RewriteSlt; |
719 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ULE ] = RewriteUle; |
720 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SLE ] = RewriteSle; |
721 |
9943 |
d_rewriteTable [ kind::BITVECTOR_UGT ] = RewriteUgt; |
722 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SGT ] = RewriteSgt; |
723 |
9943 |
d_rewriteTable [ kind::BITVECTOR_UGE ] = RewriteUge; |
724 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SGE ] = RewriteSge; |
725 |
9943 |
d_rewriteTable [ kind::BITVECTOR_NOT ] = RewriteNot; |
726 |
9943 |
d_rewriteTable [ kind::BITVECTOR_CONCAT ] = RewriteConcat; |
727 |
9943 |
d_rewriteTable [ kind::BITVECTOR_AND ] = RewriteAnd; |
728 |
9943 |
d_rewriteTable [ kind::BITVECTOR_OR ] = RewriteOr; |
729 |
9943 |
d_rewriteTable [ kind::BITVECTOR_XOR] = RewriteXor; |
730 |
9943 |
d_rewriteTable [ kind::BITVECTOR_XNOR ] = RewriteXnor; |
731 |
9943 |
d_rewriteTable [ kind::BITVECTOR_NAND ] = RewriteNand; |
732 |
9943 |
d_rewriteTable [ kind::BITVECTOR_NOR ] = RewriteNor; |
733 |
9943 |
d_rewriteTable [ kind::BITVECTOR_COMP ] = RewriteComp; |
734 |
9943 |
d_rewriteTable [ kind::BITVECTOR_MULT ] = RewriteMult; |
735 |
9943 |
d_rewriteTable[kind::BITVECTOR_ADD] = RewriteAdd; |
736 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SUB ] = RewriteSub; |
737 |
9943 |
d_rewriteTable [ kind::BITVECTOR_NEG ] = RewriteNeg; |
738 |
9943 |
d_rewriteTable [ kind::BITVECTOR_UDIV ] = RewriteUdiv; |
739 |
9943 |
d_rewriteTable [ kind::BITVECTOR_UREM ] = RewriteUrem; |
740 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SMOD ] = RewriteSmod; |
741 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SDIV ] = RewriteSdiv; |
742 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SREM ] = RewriteSrem; |
743 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SHL ] = RewriteShl; |
744 |
9943 |
d_rewriteTable [ kind::BITVECTOR_LSHR ] = RewriteLshr; |
745 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ASHR ] = RewriteAshr; |
746 |
9943 |
d_rewriteTable [ kind::BITVECTOR_EXTRACT ] = RewriteExtract; |
747 |
9943 |
d_rewriteTable [ kind::BITVECTOR_REPEAT ] = RewriteRepeat; |
748 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ZERO_EXTEND ] = RewriteZeroExtend; |
749 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SIGN_EXTEND ] = RewriteSignExtend; |
750 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ROTATE_RIGHT ] = RewriteRotateRight; |
751 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ROTATE_LEFT ] = RewriteRotateLeft; |
752 |
9943 |
d_rewriteTable [ kind::BITVECTOR_REDOR ] = RewriteRedor; |
753 |
9943 |
d_rewriteTable [ kind::BITVECTOR_REDAND ] = RewriteRedand; |
754 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ULTBV ] = RewriteUltBv; |
755 |
9943 |
d_rewriteTable [ kind::BITVECTOR_SLTBV ] = RewriteSltBv; |
756 |
9943 |
d_rewriteTable [ kind::BITVECTOR_ITE ] = RewriteITEBv; |
757 |
9943 |
d_rewriteTable[kind::BITVECTOR_EAGER_ATOM] = RewriteEagerAtom; |
758 |
|
|
759 |
9943 |
d_rewriteTable [ kind::BITVECTOR_TO_NAT ] = RewriteBVToNat; |
760 |
9943 |
d_rewriteTable [ kind::INT_TO_BITVECTOR ] = RewriteIntToBV; |
761 |
9943 |
} |
762 |
|
|
763 |
10 |
Node TheoryBVRewriter::eliminateBVSDiv(TNode node) { |
764 |
|
Node result = bv::LinearRewriteStrategy < |
765 |
|
bv::RewriteRule<bv::SremEliminate>, |
766 |
|
bv::RewriteRule<bv::SdivEliminate>, |
767 |
|
bv::RewriteRule<bv::SmodEliminate> |
768 |
10 |
>::apply(node); |
769 |
10 |
return result; |
770 |
29589 |
} |