GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/theory_bv_rewriter.cpp Lines: 315 329 95.7 %
Date: 2021-05-22 Branches: 475 934 50.9 %

Line Exec Source
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
9459
TheoryBVRewriter::TheoryBVRewriter() { initializeRewrites(); }
34
35
1394665
RewriteResponse TheoryBVRewriter::preRewrite(TNode node) {
36
1394665
  RewriteResponse res = d_rewriteTable[node.getKind()](node, true);
37
1394665
  if (res.d_node != node)
38
  {
39
443280
    Debug("bitvector-rewrite") << "TheoryBV::preRewrite    " << node << std::endl;
40
886560
    Debug("bitvector-rewrite")
41
443280
        << "TheoryBV::preRewrite to " << res.d_node << std::endl;
42
  }
43
1394665
  return res;
44
}
45
46
1704928
RewriteResponse TheoryBVRewriter::postRewrite(TNode node) {
47
1704928
  RewriteResponse res = d_rewriteTable[node.getKind()](node, false);
48
1704928
  if (res.d_node != node)
49
  {
50
282893
    Debug("bitvector-rewrite") << "TheoryBV::postRewrite    " << node << std::endl;
51
565786
    Debug("bitvector-rewrite")
52
282893
        << "TheoryBV::postRewrite to " << res.d_node << std::endl;
53
  }
54
1704928
  return res;
55
}
56
57
317798
TrustNode TheoryBVRewriter::expandDefinition(Node node)
58
{
59
635596
  Debug("bitvector-expandDefinition")
60
317798
      << "TheoryBV::expandDefinition(" << node << ")" << std::endl;
61
635596
  Node ret;
62
317798
  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
317790
    default: break;
69
  }
70
317798
  if (!ret.isNull() && node != ret)
71
  {
72
8
    return TrustNode::mkTrustRewrite(node, ret, nullptr);
73
  }
74
317790
  return TrustNode::null();
75
}
76
77
631074
RewriteResponse TheoryBVRewriter::RewriteBitOf(TNode node, bool prerewrite)
78
{
79
1262148
  Node resultNode = LinearRewriteStrategy<RewriteRule<BitOfConst>>::apply(node);
80
1262148
  return RewriteResponse(REWRITE_DONE, resultNode);
81
}
82
83
117996
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
235992
       >::apply(node);
91
92
117996
  return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL,
93
353988
                         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
125423
RewriteResponse TheoryBVRewriter::RewriteSlt(TNode node, bool prerewrite){
107
  Node resultNode = LinearRewriteStrategy
108
    < RewriteRule<EvalSlt>,
109
      RewriteRule<MultSltMult>
110
250846
       >::apply(node);
111
112
250846
  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
7357
RewriteResponse TheoryBVRewriter::RewriteSle(TNode node, bool prerewrite){
143
  Node resultNode = LinearRewriteStrategy
144
    < RewriteRule <EvalSle>,
145
      RewriteRule <SleEliminate>
146
14714
      >::apply(node);
147
14714
  return RewriteResponse(resultNode == node? REWRITE_DONE : REWRITE_AGAIN, resultNode);
148
}
149
150
3811
RewriteResponse TheoryBVRewriter::RewriteUgt(TNode node, bool prerewrite){
151
  Node resultNode =
152
      LinearRewriteStrategy<RewriteRule<UgtUrem>,
153
7622
                            RewriteRule<UgtEliminate>>::apply(node);
154
155
7622
  return RewriteResponse(REWRITE_AGAIN, resultNode);
156
}
157
158
3871
RewriteResponse TheoryBVRewriter::RewriteSgt(TNode node, bool prerewrite){
159
  Node resultNode = LinearRewriteStrategy
160
    < RewriteRule<SgtEliminate>
161
      //RewriteRule<SltEliminate>
162
7742
      >::apply(node);
163
164
7742
  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
3629
RewriteResponse TheoryBVRewriter::RewriteSge(TNode node, bool prerewrite){
176
  Node resultNode = LinearRewriteStrategy
177
    < RewriteRule<SgeEliminate>
178
      //      RewriteRule<SleEliminate>
179
7258
    >::apply(node);
180
181
7258
  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
151075
RewriteResponse TheoryBVRewriter::RewriteExtract(TNode node, bool prerewrite) {
233
302150
  Node resultNode = node;
234
235
151075
  if (RewriteRule<ExtractConcat>::applies(node)) {
236
8912
    resultNode = RewriteRule<ExtractConcat>::run<false>(node);
237
8912
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
238
  }
239
240
142163
  if (RewriteRule<ExtractSignExtend>::applies(node)) {
241
662
    resultNode = RewriteRule<ExtractSignExtend>::run<false>(node);
242
662
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
243
  }
244
245
141501
  if (RewriteRule<ExtractNot>::applies(node)) {
246
1766
    resultNode = RewriteRule<ExtractNot>::run<false>(node);
247
1766
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
248
  }
249
250
279470
  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
139735
  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
279470
      >::apply(node);
266
267
139735
  return RewriteResponse(REWRITE_DONE, resultNode);
268
}
269
270
185864
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
371728
      ApplyRuleToChildren<kind::BITVECTOR_CONCAT, ExtractWhole>>::apply(node);
280
371728
  return RewriteResponse(REWRITE_DONE, resultNode);
281
}
282
283
117938
RewriteResponse TheoryBVRewriter::RewriteAnd(TNode node, bool prerewrite)
284
{
285
235876
  Node resultNode = node;
286
117938
  resultNode =
287
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
288
                            RewriteRule<AndSimplify>,
289
235876
                            RewriteRule<AndOrXorConcatPullUp>>::apply(node);
290
117938
  if (!prerewrite)
291
  {
292
57249
    resultNode =
293
114498
        LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
294
295
57249
    if (resultNode.getKind() != node.getKind())
296
    {
297
27024
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
298
    }
299
  }
300
301
90914
  return RewriteResponse(REWRITE_DONE, resultNode);
302
}
303
304
148590
RewriteResponse TheoryBVRewriter::RewriteOr(TNode node, bool prerewrite)
305
{
306
297180
  Node resultNode = node;
307
148590
  resultNode =
308
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
309
                            RewriteRule<OrSimplify>,
310
297180
                            RewriteRule<AndOrXorConcatPullUp>>::apply(node);
311
312
148590
  if (!prerewrite)
313
  {
314
74615
    resultNode =
315
149230
        LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
316
317
74615
    if (resultNode.getKind() != node.getKind())
318
    {
319
32705
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
320
    }
321
  }
322
323
115885
  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
624
RewriteResponse TheoryBVRewriter::RewriteEagerAtom(TNode node, bool prerewrite)
386
{
387
  Node resultNode =
388
1248
      LinearRewriteStrategy<RewriteRule<EvalEagerAtom>>::apply(node);
389
390
1248
  return RewriteResponse(REWRITE_DONE, resultNode);
391
}
392
393
235396
RewriteResponse TheoryBVRewriter::RewriteMult(TNode node, bool prerewrite) {
394
470792
  Node resultNode = node;
395
235396
  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
470792
    >::apply(resultNode);
400
401
  // only apply if every subterm was already rewritten
402
235396
  if (!prerewrite) {
403
89644
    resultNode = LinearRewriteStrategy
404
      <   RewriteRule<MultDistribConst>
405
        , RewriteRule<MultDistrib>
406
179288
        >::apply(resultNode);
407
  }
408
409
235396
  if(resultNode == node) {
410
148585
    return RewriteResponse(REWRITE_DONE, resultNode);
411
  }
412
86811
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
413
}
414
415
144304
RewriteResponse TheoryBVRewriter::RewriteAdd(TNode node, bool prerewrite)
416
{
417
288608
  Node resultNode = node;
418
144304
  if (prerewrite) {
419
60946
    resultNode = LinearRewriteStrategy
420
      < RewriteRule<FlattenAssocCommut>
421
121892
        >::apply(node);
422
60946
    return RewriteResponse(REWRITE_DONE, resultNode);
423
  }
424
425
83358
  resultNode =
426
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommut>,
427
166716
                            RewriteRule<AddCombineLikeTerms>>::apply(node);
428
429
83358
  if (node != resultNode) {
430
37212
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
431
  }
432
433
46146
  return RewriteResponse(REWRITE_DONE, resultNode);
434
}
435
436
2519
RewriteResponse TheoryBVRewriter::RewriteSub(TNode node, bool prerewrite){
437
  // return RewriteResponse(REWRITE_DONE, node);
438
  Node resultNode = LinearRewriteStrategy
439
    < RewriteRule<SubEliminate>
440
5038
    >::apply(node);
441
442
5038
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
443
}
444
445
30322
RewriteResponse TheoryBVRewriter::RewriteNeg(TNode node, bool prerewrite) {
446
60644
  Node resultNode = node;
447
448
30322
  resultNode = LinearRewriteStrategy
449
    < RewriteRule<EvalNeg>,
450
      RewriteRule<NegIdemp>,
451
      RewriteRule<NegSub>
452
60644
      >::apply(node);
453
454
30322
  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
29079
  if(!prerewrite) {
461
15927
    if (RewriteRule<NegMult>::applies(node)) {
462
      resultNode = RewriteRule<NegMult>::run<false>(node);
463
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
464
    }
465
  }
466
467
29079
  return RewriteResponse(REWRITE_DONE, resultNode);
468
}
469
470
21876
RewriteResponse TheoryBVRewriter::RewriteUdiv(TNode node, bool prerewrite){
471
43752
  Node resultNode = node;
472
473
21876
  if(RewriteRule<UdivPow2>::applies(node)) {
474
1360
    resultNode = RewriteRule<UdivPow2>::run <false> (node);
475
1360
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
476
  }
477
478
20516
  resultNode =
479
      LinearRewriteStrategy<RewriteRule<EvalUdiv>, RewriteRule<UdivZero>,
480
41032
                            RewriteRule<UdivOne> >::apply(node);
481
482
20516
  return RewriteResponse(REWRITE_DONE, resultNode);
483
}
484
485
21060
RewriteResponse TheoryBVRewriter::RewriteUrem(TNode node, bool prerewrite)
486
{
487
42120
  Node resultNode = node;
488
489
21060
  if(RewriteRule<UremPow2>::applies(node)) {
490
1201
    resultNode = RewriteRule<UremPow2>::run <false> (node);
491
1201
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
492
  }
493
494
19859
  resultNode = LinearRewriteStrategy
495
    < RewriteRule<EvalUrem>,
496
      RewriteRule<UremOne>,
497
      RewriteRule<UremSelf>
498
39718
      >::apply(node);
499
19859
  return RewriteResponse(REWRITE_DONE, resultNode);
500
}
501
502
114
RewriteResponse TheoryBVRewriter::RewriteSmod(TNode node, bool prerewrite) {
503
  Node resultNode = LinearRewriteStrategy
504
    < RewriteRule<SmodEliminate>
505
228
      >::apply(node);
506
507
228
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
508
}
509
510
149
RewriteResponse TheoryBVRewriter::RewriteSdiv(TNode node, bool prerewrite) {
511
  Node resultNode = LinearRewriteStrategy
512
    < RewriteRule<SdivEliminate>
513
298
      >::apply(node);
514
515
298
  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
27137
RewriteResponse TheoryBVRewriter::RewriteLshr(TNode node, bool prerewrite) {
541
54274
  Node resultNode = node;
542
27137
  if(RewriteRule<LshrByConst>::applies(node)) {
543
14584
    resultNode = RewriteRule<LshrByConst>::run <false> (node);
544
14584
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
545
  }
546
547
12553
  resultNode = LinearRewriteStrategy
548
    < RewriteRule<EvalLshr>,
549
      RewriteRule<ShiftZero>
550
25106
      >::apply(node);
551
552
12553
  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
884
RewriteResponse TheoryBVRewriter::RewriteRepeat(TNode node, bool prerewrite) {
572
  Node resultNode = LinearRewriteStrategy
573
    < RewriteRule<RepeatEliminate >
574
1768
    >::apply(node);
575
576
1768
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
577
}
578
579
11696
RewriteResponse TheoryBVRewriter::RewriteZeroExtend(TNode node, bool prerewrite){
580
  Node resultNode = LinearRewriteStrategy
581
    < RewriteRule<ZeroExtendEliminate >
582
23392
    >::apply(node);
583
584
23392
  return RewriteResponse(REWRITE_AGAIN, resultNode);
585
}
586
587
71813
RewriteResponse TheoryBVRewriter::RewriteSignExtend(TNode node, bool prerewrite) {
588
  Node resultNode = LinearRewriteStrategy
589
    < RewriteRule<MergeSignExtend>
590
    , RewriteRule<EvalSignExtend>
591
143626
    >::apply(node);
592
593
594
71813
  if (resultNode != node) {
595
2238
    return RewriteResponse(REWRITE_AGAIN, resultNode);
596
  }
597
69575
  return RewriteResponse(REWRITE_DONE, resultNode);
598
}
599
600
601
857
RewriteResponse TheoryBVRewriter::RewriteRotateRight(TNode node, bool prerewrite) {
602
  Node resultNode = LinearRewriteStrategy
603
    < RewriteRule<RotateRightEliminate >
604
1714
    >::apply(node);
605
606
1714
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
607
}
608
609
763
RewriteResponse TheoryBVRewriter::RewriteRotateLeft(TNode node, bool prerewrite){
610
  Node resultNode = LinearRewriteStrategy
611
    < RewriteRule<RotateLeftEliminate >
612
1526
    >::apply(node);
613
614
1526
  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
959
RewriteResponse TheoryBVRewriter::RewriteBVToNat(TNode node, bool prerewrite) {
634
  //do not use lazy rewrite strategy if equality solver is disabled
635
959
  if( node[0].isConst() || !options::bvLazyRewriteExtf() ){
636
    Node resultNode = LinearRewriteStrategy
637
      < RewriteRule<BVToNatEliminate>
638
394
      >::apply(node);
639
197
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
640
  }else{
641
762
    return RewriteResponse(REWRITE_DONE, node);
642
  }
643
}
644
645
707
RewriteResponse TheoryBVRewriter::RewriteIntToBV(TNode node, bool prerewrite) {
646
  //do not use lazy rewrite strategy if equality solver is disabled
647
707
  if( node[0].isConst() || !options::bvLazyRewriteExtf() ){
648
    Node resultNode = LinearRewriteStrategy
649
      < RewriteRule<IntToBVEliminate>
650
550
      >::apply(node);
651
652
275
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
653
  }else{
654
432
    return RewriteResponse(REWRITE_DONE, node);
655
  }
656
}
657
658
465567
RewriteResponse TheoryBVRewriter::RewriteEqual(TNode node, bool prerewrite) {
659
465567
  if (prerewrite) {
660
    Node resultNode = LinearRewriteStrategy
661
      < RewriteRule<FailEq>,
662
        RewriteRule<SimplifyEq>,
663
        RewriteRule<ReflexivityEq>
664
381172
        >::apply(node);
665
190586
    return RewriteResponse(REWRITE_DONE, resultNode);
666
  }
667
  else {
668
    Node resultNode = LinearRewriteStrategy
669
      < RewriteRule<FailEq>,
670
        RewriteRule<SimplifyEq>,
671
        RewriteRule<ReflexivityEq>
672
549962
        >::apply(node);
673
674
274981
    if(RewriteRule<SolveEq>::applies(resultNode)) {
675
147996
      resultNode = RewriteRule<SolveEq>::run<false>(resultNode);
676
147996
      if (resultNode != node) {
677
7356
        return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
678
      }
679
    }
680
267625
    return RewriteResponse(REWRITE_DONE, resultNode);
681
  }
682
}
683
684
685
213599
RewriteResponse TheoryBVRewriter::IdentityRewrite(TNode node, bool prerewrite) {
686
213599
  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
9459
void TheoryBVRewriter::initializeRewrites() {
697
698
3074175
  for(unsigned i = 0; i < kind::LAST_KIND; ++i) {
699
3064716
    d_rewriteTable[i] = IdentityRewrite; //UndefinedRewrite;
700
  }
701
702
9459
  d_rewriteTable [ kind::EQUAL ] = RewriteEqual;
703
9459
  d_rewriteTable[kind::BITVECTOR_BITOF] = RewriteBitOf;
704
9459
  d_rewriteTable [ kind::BITVECTOR_ULT ] = RewriteUlt;
705
9459
  d_rewriteTable [ kind::BITVECTOR_SLT ] = RewriteSlt;
706
9459
  d_rewriteTable [ kind::BITVECTOR_ULE ] = RewriteUle;
707
9459
  d_rewriteTable [ kind::BITVECTOR_SLE ] = RewriteSle;
708
9459
  d_rewriteTable [ kind::BITVECTOR_UGT ] = RewriteUgt;
709
9459
  d_rewriteTable [ kind::BITVECTOR_SGT ] = RewriteSgt;
710
9459
  d_rewriteTable [ kind::BITVECTOR_UGE ] = RewriteUge;
711
9459
  d_rewriteTable [ kind::BITVECTOR_SGE ] = RewriteSge;
712
9459
  d_rewriteTable [ kind::BITVECTOR_NOT ] = RewriteNot;
713
9459
  d_rewriteTable [ kind::BITVECTOR_CONCAT ] = RewriteConcat;
714
9459
  d_rewriteTable [ kind::BITVECTOR_AND ] = RewriteAnd;
715
9459
  d_rewriteTable [ kind::BITVECTOR_OR ] = RewriteOr;
716
9459
  d_rewriteTable [ kind::BITVECTOR_XOR] = RewriteXor;
717
9459
  d_rewriteTable [ kind::BITVECTOR_XNOR ] = RewriteXnor;
718
9459
  d_rewriteTable [ kind::BITVECTOR_NAND ] = RewriteNand;
719
9459
  d_rewriteTable [ kind::BITVECTOR_NOR ] = RewriteNor;
720
9459
  d_rewriteTable [ kind::BITVECTOR_COMP ] = RewriteComp;
721
9459
  d_rewriteTable [ kind::BITVECTOR_MULT ] = RewriteMult;
722
9459
  d_rewriteTable[kind::BITVECTOR_ADD] = RewriteAdd;
723
9459
  d_rewriteTable [ kind::BITVECTOR_SUB ] = RewriteSub;
724
9459
  d_rewriteTable [ kind::BITVECTOR_NEG ] = RewriteNeg;
725
9459
  d_rewriteTable [ kind::BITVECTOR_UDIV ] = RewriteUdiv;
726
9459
  d_rewriteTable [ kind::BITVECTOR_UREM ] = RewriteUrem;
727
9459
  d_rewriteTable [ kind::BITVECTOR_SMOD ] = RewriteSmod;
728
9459
  d_rewriteTable [ kind::BITVECTOR_SDIV ] = RewriteSdiv;
729
9459
  d_rewriteTable [ kind::BITVECTOR_SREM ] = RewriteSrem;
730
9459
  d_rewriteTable [ kind::BITVECTOR_SHL ] = RewriteShl;
731
9459
  d_rewriteTable [ kind::BITVECTOR_LSHR ] = RewriteLshr;
732
9459
  d_rewriteTable [ kind::BITVECTOR_ASHR ] = RewriteAshr;
733
9459
  d_rewriteTable [ kind::BITVECTOR_EXTRACT ] = RewriteExtract;
734
9459
  d_rewriteTable [ kind::BITVECTOR_REPEAT ] = RewriteRepeat;
735
9459
  d_rewriteTable [ kind::BITVECTOR_ZERO_EXTEND ] = RewriteZeroExtend;
736
9459
  d_rewriteTable [ kind::BITVECTOR_SIGN_EXTEND ] = RewriteSignExtend;
737
9459
  d_rewriteTable [ kind::BITVECTOR_ROTATE_RIGHT ] = RewriteRotateRight;
738
9459
  d_rewriteTable [ kind::BITVECTOR_ROTATE_LEFT ] = RewriteRotateLeft;
739
9459
  d_rewriteTable [ kind::BITVECTOR_REDOR ] = RewriteRedor;
740
9459
  d_rewriteTable [ kind::BITVECTOR_REDAND ] = RewriteRedand;
741
9459
  d_rewriteTable [ kind::BITVECTOR_ULTBV ] = RewriteUltBv;
742
9459
  d_rewriteTable [ kind::BITVECTOR_SLTBV ] = RewriteSltBv;
743
9459
  d_rewriteTable [ kind::BITVECTOR_ITE ] = RewriteITEBv;
744
9459
  d_rewriteTable[kind::BITVECTOR_EAGER_ATOM] = RewriteEagerAtom;
745
746
9459
  d_rewriteTable [ kind::BITVECTOR_TO_NAT ] = RewriteBVToNat;
747
9459
  d_rewriteTable [ kind::INT_TO_BITVECTOR ] = RewriteIntToBV;
748
9459
}
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
167926
}