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 |
8954 |
TheoryBVRewriter::TheoryBVRewriter() { initializeRewrites(); } |
34 |
|
|
35 |
1383576 |
RewriteResponse TheoryBVRewriter::preRewrite(TNode node) { |
36 |
1383576 |
RewriteResponse res = d_rewriteTable[node.getKind()](node, true); |
37 |
1383576 |
if (res.d_node != node) |
38 |
|
{ |
39 |
442029 |
Debug("bitvector-rewrite") << "TheoryBV::preRewrite " << node << std::endl; |
40 |
884058 |
Debug("bitvector-rewrite") |
41 |
442029 |
<< "TheoryBV::preRewrite to " << res.d_node << std::endl; |
42 |
|
} |
43 |
1383576 |
return res; |
44 |
|
} |
45 |
|
|
46 |
1685235 |
RewriteResponse TheoryBVRewriter::postRewrite(TNode node) { |
47 |
1685235 |
RewriteResponse res = d_rewriteTable[node.getKind()](node, false); |
48 |
1685235 |
if (res.d_node != node) |
49 |
|
{ |
50 |
282822 |
Debug("bitvector-rewrite") << "TheoryBV::postRewrite " << node << std::endl; |
51 |
565644 |
Debug("bitvector-rewrite") |
52 |
282822 |
<< "TheoryBV::postRewrite to " << res.d_node << std::endl; |
53 |
|
} |
54 |
1685235 |
return res; |
55 |
|
} |
56 |
|
|
57 |
313792 |
TrustNode TheoryBVRewriter::expandDefinition(Node node) |
58 |
|
{ |
59 |
627584 |
Debug("bitvector-expandDefinition") |
60 |
313792 |
<< "TheoryBV::expandDefinition(" << node << ")" << std::endl; |
61 |
627584 |
Node ret; |
62 |
313792 |
switch (node.getKind()) |
63 |
|
{ |
64 |
8 |
case kind::BITVECTOR_SDIV: |
65 |
|
case kind::BITVECTOR_SREM: |
66 |
8 |
case kind::BITVECTOR_SMOD: ret = eliminateBVSDiv(node); break; |
67 |
|
|
68 |
313784 |
default: break; |
69 |
|
} |
70 |
313792 |
if (!ret.isNull() && node != ret) |
71 |
|
{ |
72 |
8 |
return TrustNode::mkTrustRewrite(node, ret, nullptr); |
73 |
|
} |
74 |
313784 |
return TrustNode::null(); |
75 |
|
} |
76 |
|
|
77 |
606421 |
RewriteResponse TheoryBVRewriter::RewriteBitOf(TNode node, bool prerewrite) |
78 |
|
{ |
79 |
1212842 |
Node resultNode = LinearRewriteStrategy<RewriteRule<BitOfConst>>::apply(node); |
80 |
1212842 |
return RewriteResponse(REWRITE_DONE, resultNode); |
81 |
|
} |
82 |
|
|
83 |
117892 |
RewriteResponse TheoryBVRewriter::RewriteUlt(TNode node, bool prerewrite) { |
84 |
|
// reduce common subexpressions on both sides |
85 |
|
Node resultNode = LinearRewriteStrategy |
86 |
|
< RewriteRule<EvalUlt>, // if both arguments are constants evaluates |
87 |
|
RewriteRule<UltZero>, // a < 0 rewrites to false, |
88 |
|
RewriteRule<SignExtendUltConst>, |
89 |
|
RewriteRule<ZeroExtendUltConst> |
90 |
235784 |
>::apply(node); |
91 |
|
|
92 |
117892 |
return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL, |
93 |
353676 |
resultNode); |
94 |
|
} |
95 |
|
|
96 |
3379 |
RewriteResponse TheoryBVRewriter::RewriteUltBv(TNode node, bool prerewrite) { |
97 |
|
// reduce common subexpressions on both sides |
98 |
|
Node resultNode = LinearRewriteStrategy |
99 |
|
< RewriteRule<EvalUltBv> |
100 |
6758 |
>::apply(node); |
101 |
|
|
102 |
6758 |
return RewriteResponse(REWRITE_DONE, resultNode); |
103 |
|
} |
104 |
|
|
105 |
|
|
106 |
125331 |
RewriteResponse TheoryBVRewriter::RewriteSlt(TNode node, bool prerewrite){ |
107 |
|
Node resultNode = LinearRewriteStrategy |
108 |
|
< RewriteRule<EvalSlt>, |
109 |
|
RewriteRule<MultSltMult> |
110 |
250662 |
>::apply(node); |
111 |
|
|
112 |
250662 |
return RewriteResponse(REWRITE_DONE, resultNode); |
113 |
|
|
114 |
|
// Node resultNode = LinearRewriteStrategy |
115 |
|
// < RewriteRule < SltEliminate > |
116 |
|
// // a <_s b ==> a + 2^{n-1} <_u b + 2^{n-1} |
117 |
|
// >::apply(node); |
118 |
|
|
119 |
|
// return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
120 |
|
} |
121 |
|
|
122 |
6376 |
RewriteResponse TheoryBVRewriter::RewriteSltBv(TNode node, bool prerewrite){ |
123 |
|
Node resultNode = LinearRewriteStrategy |
124 |
|
< RewriteRule < EvalSltBv > |
125 |
12752 |
>::apply(node); |
126 |
|
|
127 |
12752 |
return RewriteResponse(REWRITE_DONE, resultNode); |
128 |
|
} |
129 |
|
|
130 |
7122 |
RewriteResponse TheoryBVRewriter::RewriteUle(TNode node, bool prerewrite){ |
131 |
|
Node resultNode = LinearRewriteStrategy |
132 |
|
< RewriteRule<EvalUle>, |
133 |
|
RewriteRule<UleMax>, |
134 |
|
RewriteRule<ZeroUle>, |
135 |
|
RewriteRule<UleZero>, |
136 |
|
RewriteRule<UleSelf>, |
137 |
|
RewriteRule<UleEliminate> |
138 |
14244 |
>::apply(node); |
139 |
14244 |
return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN, resultNode); |
140 |
|
} |
141 |
|
|
142 |
7345 |
RewriteResponse TheoryBVRewriter::RewriteSle(TNode node, bool prerewrite){ |
143 |
|
Node resultNode = LinearRewriteStrategy |
144 |
|
< RewriteRule <EvalSle>, |
145 |
|
RewriteRule <SleEliminate> |
146 |
14690 |
>::apply(node); |
147 |
14690 |
return RewriteResponse(resultNode == node? REWRITE_DONE : REWRITE_AGAIN, resultNode); |
148 |
|
} |
149 |
|
|
150 |
3800 |
RewriteResponse TheoryBVRewriter::RewriteUgt(TNode node, bool prerewrite){ |
151 |
|
Node resultNode = |
152 |
|
LinearRewriteStrategy<RewriteRule<UgtUrem>, |
153 |
7600 |
RewriteRule<UgtEliminate>>::apply(node); |
154 |
|
|
155 |
7600 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
156 |
|
} |
157 |
|
|
158 |
3867 |
RewriteResponse TheoryBVRewriter::RewriteSgt(TNode node, bool prerewrite){ |
159 |
|
Node resultNode = LinearRewriteStrategy |
160 |
|
< RewriteRule<SgtEliminate> |
161 |
|
//RewriteRule<SltEliminate> |
162 |
7734 |
>::apply(node); |
163 |
|
|
164 |
7734 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
165 |
|
} |
166 |
|
|
167 |
3550 |
RewriteResponse TheoryBVRewriter::RewriteUge(TNode node, bool prerewrite){ |
168 |
|
Node resultNode = LinearRewriteStrategy |
169 |
|
< RewriteRule<UgeEliminate> |
170 |
7100 |
>::apply(node); |
171 |
|
|
172 |
7100 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
173 |
|
} |
174 |
|
|
175 |
3617 |
RewriteResponse TheoryBVRewriter::RewriteSge(TNode node, bool prerewrite){ |
176 |
|
Node resultNode = LinearRewriteStrategy |
177 |
|
< RewriteRule<SgeEliminate> |
178 |
|
// RewriteRule<SleEliminate> |
179 |
7234 |
>::apply(node); |
180 |
|
|
181 |
7234 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
182 |
|
} |
183 |
|
|
184 |
24275 |
RewriteResponse TheoryBVRewriter::RewriteITEBv(TNode node, bool prerewrite) |
185 |
|
{ |
186 |
|
Node resultNode = |
187 |
|
LinearRewriteStrategy<RewriteRule<EvalITEBv>, |
188 |
|
RewriteRule<BvIteConstCond>, |
189 |
48550 |
RewriteRule<BvIteEqualChildren>>::apply(node); |
190 |
|
// If the node has been rewritten, we return here because we need to make |
191 |
|
// sure that `BvIteEqualChildren` has been applied until we reach a fixpoint |
192 |
|
// before applying `BvIteConstChildren`. Otherwise, `BvIteConstChildren` |
193 |
|
// potentially performs an unsound rewrite. Returning hands back the control |
194 |
|
// to the `Rewriter` which will then call this method again, ensuring that |
195 |
|
// the rewrites are applied in the correct order. |
196 |
24275 |
if (resultNode != node) |
197 |
|
{ |
198 |
1978 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
199 |
|
} |
200 |
|
|
201 |
22297 |
resultNode = LinearRewriteStrategy<RewriteRule<BvIteConstChildren>, |
202 |
44594 |
RewriteRule<BvIteEqualCond>>::apply(node); |
203 |
22297 |
if (resultNode != node) |
204 |
|
{ |
205 |
257 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
206 |
|
} |
207 |
|
|
208 |
22040 |
resultNode = |
209 |
|
LinearRewriteStrategy<RewriteRule<BvIteMergeThenIf>, |
210 |
|
RewriteRule<BvIteMergeElseIf>, |
211 |
|
RewriteRule<BvIteMergeThenElse>, |
212 |
44080 |
RewriteRule<BvIteMergeElseElse>>::apply(node); |
213 |
22040 |
return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL, |
214 |
44080 |
resultNode); |
215 |
|
} |
216 |
|
|
217 |
93921 |
RewriteResponse TheoryBVRewriter::RewriteNot(TNode node, bool prerewrite){ |
218 |
187842 |
Node resultNode = node; |
219 |
|
|
220 |
|
// // if(RewriteRule<NotXor>::applies(node)) { |
221 |
|
// // resultNode = RewriteRule<NotXor>::run<false>(node); |
222 |
|
// // return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
223 |
|
// // } |
224 |
93921 |
resultNode = LinearRewriteStrategy |
225 |
|
< RewriteRule<EvalNot>, |
226 |
|
RewriteRule<NotIdemp> |
227 |
187842 |
>::apply(node); |
228 |
|
|
229 |
187842 |
return RewriteResponse(REWRITE_DONE, resultNode); |
230 |
|
} |
231 |
|
|
232 |
150371 |
RewriteResponse TheoryBVRewriter::RewriteExtract(TNode node, bool prerewrite) { |
233 |
300742 |
Node resultNode = node; |
234 |
|
|
235 |
150371 |
if (RewriteRule<ExtractConcat>::applies(node)) { |
236 |
8911 |
resultNode = RewriteRule<ExtractConcat>::run<false>(node); |
237 |
8911 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
238 |
|
} |
239 |
|
|
240 |
141460 |
if (RewriteRule<ExtractSignExtend>::applies(node)) { |
241 |
662 |
resultNode = RewriteRule<ExtractSignExtend>::run<false>(node); |
242 |
662 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
243 |
|
} |
244 |
|
|
245 |
140798 |
if (RewriteRule<ExtractNot>::applies(node)) { |
246 |
1766 |
resultNode = RewriteRule<ExtractNot>::run<false>(node); |
247 |
1766 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
248 |
|
} |
249 |
|
|
250 |
278064 |
if (options::bvExtractArithRewrite()) { |
251 |
|
if (RewriteRule<ExtractArith>::applies(node)) { |
252 |
|
resultNode = RewriteRule<ExtractArith>::run<false>(node); |
253 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
254 |
|
} |
255 |
|
} |
256 |
|
|
257 |
|
|
258 |
139032 |
resultNode = LinearRewriteStrategy |
259 |
|
< RewriteRule<ExtractConstant>, |
260 |
|
RewriteRule<ExtractExtract>, |
261 |
|
// We could get another extract over extract |
262 |
|
RewriteRule<ExtractWhole>, |
263 |
|
// At this point only Extract-Whole could apply |
264 |
|
RewriteRule<ExtractMultLeadingBit> |
265 |
278064 |
>::apply(node); |
266 |
|
|
267 |
139032 |
return RewriteResponse(REWRITE_DONE, resultNode); |
268 |
|
} |
269 |
|
|
270 |
185495 |
RewriteResponse TheoryBVRewriter::RewriteConcat(TNode node, bool prerewrite) |
271 |
|
{ |
272 |
|
Node resultNode = LinearRewriteStrategy< |
273 |
|
RewriteRule<ConcatFlatten>, |
274 |
|
// Flatten the top level concatenations |
275 |
|
RewriteRule<ConcatExtractMerge>, |
276 |
|
// Merge the adjacent extracts on non-constants |
277 |
|
RewriteRule<ConcatConstantMerge>, |
278 |
|
// Merge the adjacent extracts on constants |
279 |
370990 |
ApplyRuleToChildren<kind::BITVECTOR_CONCAT, ExtractWhole>>::apply(node); |
280 |
370990 |
return RewriteResponse(REWRITE_DONE, resultNode); |
281 |
|
} |
282 |
|
|
283 |
117861 |
RewriteResponse TheoryBVRewriter::RewriteAnd(TNode node, bool prerewrite) |
284 |
|
{ |
285 |
235722 |
Node resultNode = node; |
286 |
117861 |
resultNode = |
287 |
|
LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>, |
288 |
|
RewriteRule<AndSimplify>, |
289 |
235722 |
RewriteRule<AndOrXorConcatPullUp>>::apply(node); |
290 |
117861 |
if (!prerewrite) |
291 |
|
{ |
292 |
57210 |
resultNode = |
293 |
114420 |
LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode); |
294 |
|
|
295 |
57210 |
if (resultNode.getKind() != node.getKind()) |
296 |
|
{ |
297 |
27021 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
298 |
|
} |
299 |
|
} |
300 |
|
|
301 |
90840 |
return RewriteResponse(REWRITE_DONE, resultNode); |
302 |
|
} |
303 |
|
|
304 |
148528 |
RewriteResponse TheoryBVRewriter::RewriteOr(TNode node, bool prerewrite) |
305 |
|
{ |
306 |
297056 |
Node resultNode = node; |
307 |
148528 |
resultNode = |
308 |
|
LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>, |
309 |
|
RewriteRule<OrSimplify>, |
310 |
297056 |
RewriteRule<AndOrXorConcatPullUp>>::apply(node); |
311 |
|
|
312 |
148528 |
if (!prerewrite) |
313 |
|
{ |
314 |
74581 |
resultNode = |
315 |
149162 |
LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode); |
316 |
|
|
317 |
74581 |
if (resultNode.getKind() != node.getKind()) |
318 |
|
{ |
319 |
32695 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
320 |
|
} |
321 |
|
} |
322 |
|
|
323 |
115833 |
return RewriteResponse(REWRITE_DONE, resultNode); |
324 |
|
} |
325 |
|
|
326 |
11181 |
RewriteResponse TheoryBVRewriter::RewriteXor(TNode node, bool prerewrite) |
327 |
|
{ |
328 |
22362 |
Node resultNode = node; |
329 |
11181 |
resultNode = LinearRewriteStrategy< |
330 |
|
RewriteRule<FlattenAssocCommut>, // flatten the expression |
331 |
|
RewriteRule<XorSimplify>, // simplify duplicates and constants |
332 |
|
RewriteRule<XorZero>, // checks if the constant part is zero and |
333 |
|
// eliminates it |
334 |
|
RewriteRule<AndOrXorConcatPullUp>, |
335 |
22362 |
RewriteRule<BitwiseSlicing>>::apply(node); |
336 |
|
|
337 |
11181 |
if (!prerewrite) |
338 |
|
{ |
339 |
6035 |
resultNode = |
340 |
|
LinearRewriteStrategy<RewriteRule<XorOne>, |
341 |
12070 |
RewriteRule<BitwiseSlicing>>::apply(resultNode); |
342 |
|
|
343 |
6035 |
if (resultNode.getKind() != node.getKind()) |
344 |
|
{ |
345 |
1616 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
346 |
|
} |
347 |
|
} |
348 |
|
|
349 |
9565 |
return RewriteResponse(REWRITE_DONE, resultNode); |
350 |
|
} |
351 |
|
|
352 |
1012 |
RewriteResponse TheoryBVRewriter::RewriteXnor(TNode node, bool prerewrite) { |
353 |
|
Node resultNode = LinearRewriteStrategy |
354 |
|
< RewriteRule<XnorEliminate> |
355 |
2024 |
>::apply(node); |
356 |
|
// need to rewrite two levels in |
357 |
2024 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
358 |
|
} |
359 |
|
|
360 |
715 |
RewriteResponse TheoryBVRewriter::RewriteNand(TNode node, bool prerewrite) { |
361 |
|
Node resultNode = LinearRewriteStrategy |
362 |
|
< RewriteRule<NandEliminate> |
363 |
1430 |
>::apply(node); |
364 |
|
|
365 |
1430 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
366 |
|
} |
367 |
|
|
368 |
917 |
RewriteResponse TheoryBVRewriter::RewriteNor(TNode node, bool prerewrite) { |
369 |
|
Node resultNode = LinearRewriteStrategy |
370 |
|
< RewriteRule<NorEliminate> |
371 |
1834 |
>::apply(node); |
372 |
|
|
373 |
1834 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
374 |
|
} |
375 |
|
|
376 |
169650 |
RewriteResponse TheoryBVRewriter::RewriteComp(TNode node, bool prerewrite) |
377 |
|
{ |
378 |
|
Node resultNode = |
379 |
|
LinearRewriteStrategy<RewriteRule<EvalComp>, RewriteRule<BvComp> >::apply( |
380 |
339300 |
node); |
381 |
|
|
382 |
339300 |
return RewriteResponse(REWRITE_DONE, resultNode); |
383 |
|
} |
384 |
|
|
385 |
537 |
RewriteResponse TheoryBVRewriter::RewriteEagerAtom(TNode node, bool prerewrite) |
386 |
|
{ |
387 |
|
Node resultNode = |
388 |
1074 |
LinearRewriteStrategy<RewriteRule<EvalEagerAtom>>::apply(node); |
389 |
|
|
390 |
1074 |
return RewriteResponse(REWRITE_DONE, resultNode); |
391 |
|
} |
392 |
|
|
393 |
235268 |
RewriteResponse TheoryBVRewriter::RewriteMult(TNode node, bool prerewrite) { |
394 |
470536 |
Node resultNode = node; |
395 |
235268 |
resultNode = LinearRewriteStrategy |
396 |
|
< RewriteRule<FlattenAssocCommut>, // flattens and sorts |
397 |
|
RewriteRule<MultSimplify>, // multiplies constant part and checks for 0 |
398 |
|
RewriteRule<MultPow2> // replaces multiplication by a power of 2 by a shift |
399 |
470536 |
>::apply(resultNode); |
400 |
|
|
401 |
|
// only apply if every subterm was already rewritten |
402 |
235268 |
if (!prerewrite) { |
403 |
89585 |
resultNode = LinearRewriteStrategy |
404 |
|
< RewriteRule<MultDistribConst> |
405 |
|
, RewriteRule<MultDistrib> |
406 |
179170 |
>::apply(resultNode); |
407 |
|
} |
408 |
|
|
409 |
235268 |
if(resultNode == node) { |
410 |
148485 |
return RewriteResponse(REWRITE_DONE, resultNode); |
411 |
|
} |
412 |
86783 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
413 |
|
} |
414 |
|
|
415 |
144167 |
RewriteResponse TheoryBVRewriter::RewriteAdd(TNode node, bool prerewrite) |
416 |
|
{ |
417 |
288334 |
Node resultNode = node; |
418 |
144167 |
if (prerewrite) { |
419 |
60900 |
resultNode = LinearRewriteStrategy |
420 |
|
< RewriteRule<FlattenAssocCommut> |
421 |
121800 |
>::apply(node); |
422 |
60900 |
return RewriteResponse(REWRITE_DONE, resultNode); |
423 |
|
} |
424 |
|
|
425 |
83267 |
resultNode = |
426 |
|
LinearRewriteStrategy<RewriteRule<FlattenAssocCommut>, |
427 |
166534 |
RewriteRule<AddCombineLikeTerms>>::apply(node); |
428 |
|
|
429 |
83267 |
if (node != resultNode) { |
430 |
37211 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
431 |
|
} |
432 |
|
|
433 |
46056 |
return RewriteResponse(REWRITE_DONE, resultNode); |
434 |
|
} |
435 |
|
|
436 |
2518 |
RewriteResponse TheoryBVRewriter::RewriteSub(TNode node, bool prerewrite){ |
437 |
|
// return RewriteResponse(REWRITE_DONE, node); |
438 |
|
Node resultNode = LinearRewriteStrategy |
439 |
|
< RewriteRule<SubEliminate> |
440 |
5036 |
>::apply(node); |
441 |
|
|
442 |
5036 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
443 |
|
} |
444 |
|
|
445 |
30312 |
RewriteResponse TheoryBVRewriter::RewriteNeg(TNode node, bool prerewrite) { |
446 |
60624 |
Node resultNode = node; |
447 |
|
|
448 |
30312 |
resultNode = LinearRewriteStrategy |
449 |
|
< RewriteRule<EvalNeg>, |
450 |
|
RewriteRule<NegIdemp>, |
451 |
|
RewriteRule<NegSub> |
452 |
60624 |
>::apply(node); |
453 |
|
|
454 |
30312 |
if (RewriteRule<NegAdd>::applies(node)) |
455 |
|
{ |
456 |
1243 |
resultNode = RewriteRule<NegAdd>::run<false>(node); |
457 |
1243 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
458 |
|
} |
459 |
|
|
460 |
29069 |
if(!prerewrite) { |
461 |
15921 |
if (RewriteRule<NegMult>::applies(node)) { |
462 |
|
resultNode = RewriteRule<NegMult>::run<false>(node); |
463 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
464 |
|
} |
465 |
|
} |
466 |
|
|
467 |
29069 |
return RewriteResponse(REWRITE_DONE, resultNode); |
468 |
|
} |
469 |
|
|
470 |
21874 |
RewriteResponse TheoryBVRewriter::RewriteUdiv(TNode node, bool prerewrite){ |
471 |
43748 |
Node resultNode = node; |
472 |
|
|
473 |
21874 |
if(RewriteRule<UdivPow2>::applies(node)) { |
474 |
1359 |
resultNode = RewriteRule<UdivPow2>::run <false> (node); |
475 |
1359 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
476 |
|
} |
477 |
|
|
478 |
20515 |
resultNode = |
479 |
|
LinearRewriteStrategy<RewriteRule<EvalUdiv>, RewriteRule<UdivZero>, |
480 |
41030 |
RewriteRule<UdivOne> >::apply(node); |
481 |
|
|
482 |
20515 |
return RewriteResponse(REWRITE_DONE, resultNode); |
483 |
|
} |
484 |
|
|
485 |
21066 |
RewriteResponse TheoryBVRewriter::RewriteUrem(TNode node, bool prerewrite) |
486 |
|
{ |
487 |
42132 |
Node resultNode = node; |
488 |
|
|
489 |
21066 |
if(RewriteRule<UremPow2>::applies(node)) { |
490 |
1201 |
resultNode = RewriteRule<UremPow2>::run <false> (node); |
491 |
1201 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
492 |
|
} |
493 |
|
|
494 |
19865 |
resultNode = LinearRewriteStrategy |
495 |
|
< RewriteRule<EvalUrem>, |
496 |
|
RewriteRule<UremOne>, |
497 |
|
RewriteRule<UremSelf> |
498 |
39730 |
>::apply(node); |
499 |
19865 |
return RewriteResponse(REWRITE_DONE, resultNode); |
500 |
|
} |
501 |
|
|
502 |
116 |
RewriteResponse TheoryBVRewriter::RewriteSmod(TNode node, bool prerewrite) { |
503 |
|
Node resultNode = LinearRewriteStrategy |
504 |
|
< RewriteRule<SmodEliminate> |
505 |
232 |
>::apply(node); |
506 |
|
|
507 |
232 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
508 |
|
} |
509 |
|
|
510 |
148 |
RewriteResponse TheoryBVRewriter::RewriteSdiv(TNode node, bool prerewrite) { |
511 |
|
Node resultNode = LinearRewriteStrategy |
512 |
|
< RewriteRule<SdivEliminate> |
513 |
296 |
>::apply(node); |
514 |
|
|
515 |
296 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
516 |
|
} |
517 |
|
|
518 |
71 |
RewriteResponse TheoryBVRewriter::RewriteSrem(TNode node, bool prerewrite) { |
519 |
|
Node resultNode = LinearRewriteStrategy |
520 |
|
< RewriteRule<SremEliminate> |
521 |
142 |
>::apply(node); |
522 |
142 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
523 |
|
} |
524 |
|
|
525 |
22962 |
RewriteResponse TheoryBVRewriter::RewriteShl(TNode node, bool prerewrite) { |
526 |
45924 |
Node resultNode = node; |
527 |
22962 |
if(RewriteRule<ShlByConst>::applies(node)) { |
528 |
13532 |
resultNode = RewriteRule<ShlByConst>::run <false> (node); |
529 |
13532 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
530 |
|
} |
531 |
|
|
532 |
9430 |
resultNode = LinearRewriteStrategy |
533 |
|
< RewriteRule<EvalShl>, |
534 |
|
RewriteRule<ShiftZero> |
535 |
18860 |
>::apply(node); |
536 |
|
|
537 |
9430 |
return RewriteResponse(REWRITE_DONE, resultNode); |
538 |
|
} |
539 |
|
|
540 |
27059 |
RewriteResponse TheoryBVRewriter::RewriteLshr(TNode node, bool prerewrite) { |
541 |
54118 |
Node resultNode = node; |
542 |
27059 |
if(RewriteRule<LshrByConst>::applies(node)) { |
543 |
14584 |
resultNode = RewriteRule<LshrByConst>::run <false> (node); |
544 |
14584 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
545 |
|
} |
546 |
|
|
547 |
12475 |
resultNode = LinearRewriteStrategy |
548 |
|
< RewriteRule<EvalLshr>, |
549 |
|
RewriteRule<ShiftZero> |
550 |
24950 |
>::apply(node); |
551 |
|
|
552 |
12475 |
return RewriteResponse(REWRITE_DONE, resultNode); |
553 |
|
} |
554 |
|
|
555 |
7488 |
RewriteResponse TheoryBVRewriter::RewriteAshr(TNode node, bool prerewrite) { |
556 |
14976 |
Node resultNode = node; |
557 |
7488 |
if(RewriteRule<AshrByConst>::applies(node)) { |
558 |
787 |
resultNode = RewriteRule<AshrByConst>::run <false> (node); |
559 |
787 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
560 |
|
} |
561 |
|
|
562 |
6701 |
resultNode = LinearRewriteStrategy |
563 |
|
< RewriteRule<EvalAshr>, |
564 |
|
RewriteRule<ShiftZero> |
565 |
13402 |
>::apply(node); |
566 |
|
|
567 |
6701 |
return RewriteResponse(REWRITE_DONE, resultNode); |
568 |
|
} |
569 |
|
|
570 |
|
|
571 |
883 |
RewriteResponse TheoryBVRewriter::RewriteRepeat(TNode node, bool prerewrite) { |
572 |
|
Node resultNode = LinearRewriteStrategy |
573 |
|
< RewriteRule<RepeatEliminate > |
574 |
1766 |
>::apply(node); |
575 |
|
|
576 |
1766 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
577 |
|
} |
578 |
|
|
579 |
11695 |
RewriteResponse TheoryBVRewriter::RewriteZeroExtend(TNode node, bool prerewrite){ |
580 |
|
Node resultNode = LinearRewriteStrategy |
581 |
|
< RewriteRule<ZeroExtendEliminate > |
582 |
23390 |
>::apply(node); |
583 |
|
|
584 |
23390 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
585 |
|
} |
586 |
|
|
587 |
71812 |
RewriteResponse TheoryBVRewriter::RewriteSignExtend(TNode node, bool prerewrite) { |
588 |
|
Node resultNode = LinearRewriteStrategy |
589 |
|
< RewriteRule<MergeSignExtend> |
590 |
|
, RewriteRule<EvalSignExtend> |
591 |
143624 |
>::apply(node); |
592 |
|
|
593 |
|
|
594 |
71812 |
if (resultNode != node) { |
595 |
2237 |
return RewriteResponse(REWRITE_AGAIN, resultNode); |
596 |
|
} |
597 |
69575 |
return RewriteResponse(REWRITE_DONE, resultNode); |
598 |
|
} |
599 |
|
|
600 |
|
|
601 |
856 |
RewriteResponse TheoryBVRewriter::RewriteRotateRight(TNode node, bool prerewrite) { |
602 |
|
Node resultNode = LinearRewriteStrategy |
603 |
|
< RewriteRule<RotateRightEliminate > |
604 |
1712 |
>::apply(node); |
605 |
|
|
606 |
1712 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
607 |
|
} |
608 |
|
|
609 |
762 |
RewriteResponse TheoryBVRewriter::RewriteRotateLeft(TNode node, bool prerewrite){ |
610 |
|
Node resultNode = LinearRewriteStrategy |
611 |
|
< RewriteRule<RotateLeftEliminate > |
612 |
1524 |
>::apply(node); |
613 |
|
|
614 |
1524 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
615 |
|
} |
616 |
|
|
617 |
|
RewriteResponse TheoryBVRewriter::RewriteRedor(TNode node, bool prerewrite){ |
618 |
|
Node resultNode = LinearRewriteStrategy |
619 |
|
< RewriteRule<RedorEliminate> |
620 |
|
>::apply(node); |
621 |
|
|
622 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
623 |
|
} |
624 |
|
|
625 |
|
RewriteResponse TheoryBVRewriter::RewriteRedand(TNode node, bool prerewrite){ |
626 |
|
Node resultNode = LinearRewriteStrategy |
627 |
|
< RewriteRule<RedandEliminate> |
628 |
|
>::apply(node); |
629 |
|
|
630 |
|
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
631 |
|
} |
632 |
|
|
633 |
808 |
RewriteResponse TheoryBVRewriter::RewriteBVToNat(TNode node, bool prerewrite) { |
634 |
|
//do not use lazy rewrite strategy if equality solver is disabled |
635 |
808 |
if( node[0].isConst() || !options::bvLazyRewriteExtf() ){ |
636 |
|
Node resultNode = LinearRewriteStrategy |
637 |
|
< RewriteRule<BVToNatEliminate> |
638 |
378 |
>::apply(node); |
639 |
189 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
640 |
|
}else{ |
641 |
619 |
return RewriteResponse(REWRITE_DONE, node); |
642 |
|
} |
643 |
|
} |
644 |
|
|
645 |
607 |
RewriteResponse TheoryBVRewriter::RewriteIntToBV(TNode node, bool prerewrite) { |
646 |
|
//do not use lazy rewrite strategy if equality solver is disabled |
647 |
607 |
if( node[0].isConst() || !options::bvLazyRewriteExtf() ){ |
648 |
|
Node resultNode = LinearRewriteStrategy |
649 |
|
< RewriteRule<IntToBVEliminate> |
650 |
530 |
>::apply(node); |
651 |
|
|
652 |
265 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
653 |
|
}else{ |
654 |
342 |
return RewriteResponse(REWRITE_DONE, node); |
655 |
|
} |
656 |
|
} |
657 |
|
|
658 |
461971 |
RewriteResponse TheoryBVRewriter::RewriteEqual(TNode node, bool prerewrite) { |
659 |
461971 |
if (prerewrite) { |
660 |
|
Node resultNode = LinearRewriteStrategy |
661 |
|
< RewriteRule<FailEq>, |
662 |
|
RewriteRule<SimplifyEq>, |
663 |
|
RewriteRule<ReflexivityEq> |
664 |
378236 |
>::apply(node); |
665 |
189118 |
return RewriteResponse(REWRITE_DONE, resultNode); |
666 |
|
} |
667 |
|
else { |
668 |
|
Node resultNode = LinearRewriteStrategy |
669 |
|
< RewriteRule<FailEq>, |
670 |
|
RewriteRule<SimplifyEq>, |
671 |
|
RewriteRule<ReflexivityEq> |
672 |
545706 |
>::apply(node); |
673 |
|
|
674 |
272853 |
if(RewriteRule<SolveEq>::applies(resultNode)) { |
675 |
147566 |
resultNode = RewriteRule<SolveEq>::run<false>(resultNode); |
676 |
147566 |
if (resultNode != node) { |
677 |
7356 |
return RewriteResponse(REWRITE_AGAIN_FULL, resultNode); |
678 |
|
} |
679 |
|
} |
680 |
265497 |
return RewriteResponse(REWRITE_DONE, resultNode); |
681 |
|
} |
682 |
|
} |
683 |
|
|
684 |
|
|
685 |
213205 |
RewriteResponse TheoryBVRewriter::IdentityRewrite(TNode node, bool prerewrite) { |
686 |
213205 |
return RewriteResponse(REWRITE_DONE, node); |
687 |
|
} |
688 |
|
|
689 |
|
RewriteResponse TheoryBVRewriter::UndefinedRewrite(TNode node, bool prerewrite) { |
690 |
|
Debug("bv-rewrite") << "TheoryBV::UndefinedRewrite for" << node; |
691 |
|
Unimplemented(); |
692 |
|
} |
693 |
|
|
694 |
|
|
695 |
|
|
696 |
8954 |
void TheoryBVRewriter::initializeRewrites() { |
697 |
|
|
698 |
2910050 |
for(unsigned i = 0; i < kind::LAST_KIND; ++i) { |
699 |
2901096 |
d_rewriteTable[i] = IdentityRewrite; //UndefinedRewrite; |
700 |
|
} |
701 |
|
|
702 |
8954 |
d_rewriteTable [ kind::EQUAL ] = RewriteEqual; |
703 |
8954 |
d_rewriteTable[kind::BITVECTOR_BITOF] = RewriteBitOf; |
704 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ULT ] = RewriteUlt; |
705 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SLT ] = RewriteSlt; |
706 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ULE ] = RewriteUle; |
707 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SLE ] = RewriteSle; |
708 |
8954 |
d_rewriteTable [ kind::BITVECTOR_UGT ] = RewriteUgt; |
709 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SGT ] = RewriteSgt; |
710 |
8954 |
d_rewriteTable [ kind::BITVECTOR_UGE ] = RewriteUge; |
711 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SGE ] = RewriteSge; |
712 |
8954 |
d_rewriteTable [ kind::BITVECTOR_NOT ] = RewriteNot; |
713 |
8954 |
d_rewriteTable [ kind::BITVECTOR_CONCAT ] = RewriteConcat; |
714 |
8954 |
d_rewriteTable [ kind::BITVECTOR_AND ] = RewriteAnd; |
715 |
8954 |
d_rewriteTable [ kind::BITVECTOR_OR ] = RewriteOr; |
716 |
8954 |
d_rewriteTable [ kind::BITVECTOR_XOR] = RewriteXor; |
717 |
8954 |
d_rewriteTable [ kind::BITVECTOR_XNOR ] = RewriteXnor; |
718 |
8954 |
d_rewriteTable [ kind::BITVECTOR_NAND ] = RewriteNand; |
719 |
8954 |
d_rewriteTable [ kind::BITVECTOR_NOR ] = RewriteNor; |
720 |
8954 |
d_rewriteTable [ kind::BITVECTOR_COMP ] = RewriteComp; |
721 |
8954 |
d_rewriteTable [ kind::BITVECTOR_MULT ] = RewriteMult; |
722 |
8954 |
d_rewriteTable[kind::BITVECTOR_ADD] = RewriteAdd; |
723 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SUB ] = RewriteSub; |
724 |
8954 |
d_rewriteTable [ kind::BITVECTOR_NEG ] = RewriteNeg; |
725 |
8954 |
d_rewriteTable [ kind::BITVECTOR_UDIV ] = RewriteUdiv; |
726 |
8954 |
d_rewriteTable [ kind::BITVECTOR_UREM ] = RewriteUrem; |
727 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SMOD ] = RewriteSmod; |
728 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SDIV ] = RewriteSdiv; |
729 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SREM ] = RewriteSrem; |
730 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SHL ] = RewriteShl; |
731 |
8954 |
d_rewriteTable [ kind::BITVECTOR_LSHR ] = RewriteLshr; |
732 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ASHR ] = RewriteAshr; |
733 |
8954 |
d_rewriteTable [ kind::BITVECTOR_EXTRACT ] = RewriteExtract; |
734 |
8954 |
d_rewriteTable [ kind::BITVECTOR_REPEAT ] = RewriteRepeat; |
735 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ZERO_EXTEND ] = RewriteZeroExtend; |
736 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SIGN_EXTEND ] = RewriteSignExtend; |
737 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ROTATE_RIGHT ] = RewriteRotateRight; |
738 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ROTATE_LEFT ] = RewriteRotateLeft; |
739 |
8954 |
d_rewriteTable [ kind::BITVECTOR_REDOR ] = RewriteRedor; |
740 |
8954 |
d_rewriteTable [ kind::BITVECTOR_REDAND ] = RewriteRedand; |
741 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ULTBV ] = RewriteUltBv; |
742 |
8954 |
d_rewriteTable [ kind::BITVECTOR_SLTBV ] = RewriteSltBv; |
743 |
8954 |
d_rewriteTable [ kind::BITVECTOR_ITE ] = RewriteITEBv; |
744 |
8954 |
d_rewriteTable[kind::BITVECTOR_EAGER_ATOM] = RewriteEagerAtom; |
745 |
|
|
746 |
8954 |
d_rewriteTable [ kind::BITVECTOR_TO_NAT ] = RewriteBVToNat; |
747 |
8954 |
d_rewriteTable [ kind::INT_TO_BITVECTOR ] = RewriteIntToBV; |
748 |
8954 |
} |
749 |
|
|
750 |
8 |
Node TheoryBVRewriter::eliminateBVSDiv(TNode node) { |
751 |
|
Node result = bv::LinearRewriteStrategy < |
752 |
|
bv::RewriteRule<bv::SremEliminate>, |
753 |
|
bv::RewriteRule<bv::SdivEliminate>, |
754 |
|
bv::RewriteRule<bv::SmodEliminate> |
755 |
8 |
>::apply(node); |
756 |
8 |
return result; |
757 |
166767 |
} |