GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/theory_bv_rewriter.cpp Lines: 324 338 95.9 %
Date: 2021-08-01 Branches: 483 944 51.2 %

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
9838
TheoryBVRewriter::TheoryBVRewriter() { initializeRewrites(); }
34
35
1347304
RewriteResponse TheoryBVRewriter::preRewrite(TNode node) {
36
1347304
  RewriteResponse res = d_rewriteTable[node.getKind()](node, true);
37
1347304
  if (res.d_node != node)
38
  {
39
435195
    Debug("bitvector-rewrite") << "TheoryBV::preRewrite    " << node << std::endl;
40
870390
    Debug("bitvector-rewrite")
41
435195
        << "TheoryBV::preRewrite to " << res.d_node << std::endl;
42
  }
43
1347304
  return res;
44
}
45
46
1608906
RewriteResponse TheoryBVRewriter::postRewrite(TNode node) {
47
1608906
  RewriteResponse res = d_rewriteTable[node.getKind()](node, false);
48
1608906
  if (res.d_node != node)
49
  {
50
283448
    Debug("bitvector-rewrite") << "TheoryBV::postRewrite    " << node << std::endl;
51
566896
    Debug("bitvector-rewrite")
52
283448
        << "TheoryBV::postRewrite to " << res.d_node << std::endl;
53
  }
54
1608906
  return res;
55
}
56
57
426237
TrustNode TheoryBVRewriter::expandDefinition(Node node)
58
{
59
852474
  Debug("bitvector-expandDefinition")
60
426237
      << "TheoryBV::expandDefinition(" << node << ")" << std::endl;
61
852474
  Node ret;
62
426237
  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
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
426133
    default: break;
78
  }
79
426237
  if (!ret.isNull() && node != ret)
80
  {
81
104
    return TrustNode::mkTrustRewrite(node, ret, nullptr);
82
  }
83
426133
  return TrustNode::null();
84
}
85
86
624439
RewriteResponse TheoryBVRewriter::RewriteBitOf(TNode node, bool prerewrite)
87
{
88
1248878
  Node resultNode = LinearRewriteStrategy<RewriteRule<BitOfConst>>::apply(node);
89
1248878
  return RewriteResponse(REWRITE_DONE, resultNode);
90
}
91
92
95637
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
191274
       >::apply(node);
100
101
95637
  return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL,
102
286911
                         resultNode);
103
}
104
105
3538
RewriteResponse TheoryBVRewriter::RewriteUltBv(TNode node, bool prerewrite) {
106
  // reduce common subexpressions on both sides
107
  Node resultNode = LinearRewriteStrategy
108
    < RewriteRule<EvalUltBv>
109
7076
       >::apply(node);
110
111
7076
  return RewriteResponse(REWRITE_DONE, resultNode);
112
}
113
114
115
103207
RewriteResponse TheoryBVRewriter::RewriteSlt(TNode node, bool prerewrite){
116
  Node resultNode = LinearRewriteStrategy
117
    < RewriteRule<EvalSlt>,
118
      RewriteRule<MultSltMult>
119
206414
       >::apply(node);
120
121
206414
  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
6789
RewriteResponse TheoryBVRewriter::RewriteSltBv(TNode node, bool prerewrite){
132
  Node resultNode = LinearRewriteStrategy
133
    < RewriteRule < EvalSltBv >
134
13578
       >::apply(node);
135
136
13578
  return RewriteResponse(REWRITE_DONE, resultNode);
137
}
138
139
6424
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
12848
      >::apply(node);
148
12848
  return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN, resultNode);
149
}
150
151
6798
RewriteResponse TheoryBVRewriter::RewriteSle(TNode node, bool prerewrite){
152
  Node resultNode = LinearRewriteStrategy
153
    < RewriteRule <EvalSle>,
154
      RewriteRule <SleEliminate>
155
13596
      >::apply(node);
156
13596
  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
3225
RewriteResponse TheoryBVRewriter::RewriteUge(TNode node, bool prerewrite){
177
  Node resultNode = LinearRewriteStrategy
178
    < RewriteRule<UgeEliminate>
179
6450
    >::apply(node);
180
181
6450
  return RewriteResponse(REWRITE_AGAIN, resultNode);
182
}
183
184
3268
RewriteResponse TheoryBVRewriter::RewriteSge(TNode node, bool prerewrite){
185
  Node resultNode = LinearRewriteStrategy
186
    < RewriteRule<SgeEliminate>
187
      //      RewriteRule<SleEliminate>
188
6536
    >::apply(node);
189
190
6536
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
191
}
192
193
26088
RewriteResponse TheoryBVRewriter::RewriteITEBv(TNode node, bool prerewrite)
194
{
195
  Node resultNode =
196
      LinearRewriteStrategy<RewriteRule<EvalITEBv>,
197
                            RewriteRule<BvIteConstCond>,
198
52176
                            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
26088
  if (resultNode != node)
206
  {
207
2203
    return RewriteResponse(REWRITE_AGAIN, resultNode);
208
  }
209
210
23885
  resultNode = LinearRewriteStrategy<RewriteRule<BvIteConstChildren>,
211
47770
                                     RewriteRule<BvIteEqualCond>>::apply(node);
212
23885
  if (resultNode != node)
213
  {
214
299
    return RewriteResponse(REWRITE_AGAIN, resultNode);
215
  }
216
217
23586
  resultNode =
218
      LinearRewriteStrategy<RewriteRule<BvIteMergeThenIf>,
219
                            RewriteRule<BvIteMergeElseIf>,
220
                            RewriteRule<BvIteMergeThenElse>,
221
47172
                            RewriteRule<BvIteMergeElseElse>>::apply(node);
222
23586
  return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL,
223
47172
                         resultNode);
224
}
225
226
90367
RewriteResponse TheoryBVRewriter::RewriteNot(TNode node, bool prerewrite){
227
180734
  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
90367
  resultNode = LinearRewriteStrategy
234
    < RewriteRule<EvalNot>,
235
      RewriteRule<NotIdemp>
236
180734
    >::apply(node);
237
238
180734
  return RewriteResponse(REWRITE_DONE, resultNode);
239
}
240
241
152320
RewriteResponse TheoryBVRewriter::RewriteExtract(TNode node, bool prerewrite) {
242
304640
  Node resultNode = node;
243
244
152320
  if (RewriteRule<ExtractConcat>::applies(node)) {
245
10202
    resultNode = RewriteRule<ExtractConcat>::run<false>(node);
246
10202
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
247
  }
248
249
142118
  if (RewriteRule<ExtractSignExtend>::applies(node)) {
250
533
    resultNode = RewriteRule<ExtractSignExtend>::run<false>(node);
251
533
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
252
  }
253
254
141585
  if (RewriteRule<ExtractNot>::applies(node)) {
255
1658
    resultNode = RewriteRule<ExtractNot>::run<false>(node);
256
1658
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
257
  }
258
259
279854
  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
139927
  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
279854
      >::apply(node);
275
276
139927
  return RewriteResponse(REWRITE_DONE, resultNode);
277
}
278
279
166935
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
333870
      ApplyRuleToChildren<kind::BITVECTOR_CONCAT, ExtractWhole>>::apply(node);
289
333870
  return RewriteResponse(REWRITE_DONE, resultNode);
290
}
291
292
117337
RewriteResponse TheoryBVRewriter::RewriteAnd(TNode node, bool prerewrite)
293
{
294
234674
  Node resultNode = node;
295
117337
  resultNode =
296
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
297
                            RewriteRule<AndSimplify>,
298
234674
                            RewriteRule<AndOrXorConcatPullUp>>::apply(node);
299
117337
  if (!prerewrite)
300
  {
301
56954
    resultNode =
302
113908
        LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
303
304
56954
    if (resultNode.getKind() != node.getKind())
305
    {
306
27164
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
307
    }
308
  }
309
310
90173
  return RewriteResponse(REWRITE_DONE, resultNode);
311
}
312
313
152984
RewriteResponse TheoryBVRewriter::RewriteOr(TNode node, bool prerewrite)
314
{
315
305968
  Node resultNode = node;
316
152984
  resultNode =
317
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
318
                            RewriteRule<OrSimplify>,
319
305968
                            RewriteRule<AndOrXorConcatPullUp>>::apply(node);
320
321
152984
  if (!prerewrite)
322
  {
323
77461
    resultNode =
324
154922
        LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
325
326
77461
    if (resultNode.getKind() != node.getKind())
327
    {
328
33171
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
329
    }
330
  }
331
332
119813
  return RewriteResponse(REWRITE_DONE, resultNode);
333
}
334
335
9113
RewriteResponse TheoryBVRewriter::RewriteXor(TNode node, bool prerewrite)
336
{
337
18226
  Node resultNode = node;
338
9113
  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
18226
      RewriteRule<BitwiseSlicing>>::apply(node);
345
346
9113
  if (!prerewrite)
347
  {
348
4831
    resultNode =
349
        LinearRewriteStrategy<RewriteRule<XorOne>,
350
9662
                              RewriteRule<BitwiseSlicing>>::apply(resultNode);
351
352
4831
    if (resultNode.getKind() != node.getKind())
353
    {
354
1422
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
355
    }
356
  }
357
358
7691
  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
173959
RewriteResponse TheoryBVRewriter::RewriteComp(TNode node, bool prerewrite)
386
{
387
347918
  Node resultNode = LinearRewriteStrategy<RewriteRule<EvalComp>>::apply(node);
388
389
173959
  if (node == resultNode && RewriteRule<BvComp>::applies(node))
390
  {
391
1483
    resultNode = RewriteRule<BvComp>::run<false>(node);
392
1483
    return RewriteResponse(REWRITE_AGAIN, resultNode);
393
  }
394
395
172476
  return RewriteResponse(REWRITE_DONE, resultNode);
396
}
397
398
487
RewriteResponse TheoryBVRewriter::RewriteEagerAtom(TNode node, bool prerewrite)
399
{
400
  Node resultNode =
401
974
      LinearRewriteStrategy<RewriteRule<EvalEagerAtom>>::apply(node);
402
403
974
  return RewriteResponse(REWRITE_DONE, resultNode);
404
}
405
406
234168
RewriteResponse TheoryBVRewriter::RewriteMult(TNode node, bool prerewrite) {
407
468336
  Node resultNode = node;
408
234168
  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
468336
    >::apply(resultNode);
413
414
  // only apply if every subterm was already rewritten
415
234168
  if (!prerewrite) {
416
89014
    resultNode = LinearRewriteStrategy
417
      <   RewriteRule<MultDistribConst>
418
        , RewriteRule<MultDistrib>
419
178028
        >::apply(resultNode);
420
  }
421
422
234168
  if(resultNode == node) {
423
147570
    return RewriteResponse(REWRITE_DONE, resultNode);
424
  }
425
86598
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
426
}
427
428
127712
RewriteResponse TheoryBVRewriter::RewriteAdd(TNode node, bool prerewrite)
429
{
430
255424
  Node resultNode = node;
431
127712
  if (prerewrite) {
432
55475
    resultNode = LinearRewriteStrategy
433
      < RewriteRule<FlattenAssocCommut>
434
110950
        >::apply(node);
435
55475
    return RewriteResponse(REWRITE_DONE, resultNode);
436
  }
437
438
72237
  resultNode =
439
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommut>,
440
144474
                            RewriteRule<AddCombineLikeTerms>>::apply(node);
441
442
72237
  if (node != resultNode) {
443
37627
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
444
  }
445
446
34610
  return RewriteResponse(REWRITE_DONE, resultNode);
447
}
448
449
2388
RewriteResponse TheoryBVRewriter::RewriteSub(TNode node, bool prerewrite){
450
  // return RewriteResponse(REWRITE_DONE, node);
451
  Node resultNode = LinearRewriteStrategy
452
    < RewriteRule<SubEliminate>
453
4776
    >::apply(node);
454
455
4776
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
456
}
457
458
32056
RewriteResponse TheoryBVRewriter::RewriteNeg(TNode node, bool prerewrite) {
459
64112
  Node resultNode = node;
460
461
32056
  resultNode = LinearRewriteStrategy
462
    < RewriteRule<EvalNeg>,
463
      RewriteRule<NegIdemp>,
464
      RewriteRule<NegSub>
465
64112
      >::apply(node);
466
467
32056
  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
30806
  if(!prerewrite) {
474
16808
    if (RewriteRule<NegMult>::applies(node)) {
475
      resultNode = RewriteRule<NegMult>::run<false>(node);
476
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
477
    }
478
  }
479
480
30806
  return RewriteResponse(REWRITE_DONE, resultNode);
481
}
482
483
25571
RewriteResponse TheoryBVRewriter::RewriteUdiv(TNode node, bool prerewrite){
484
51142
  Node resultNode = node;
485
486
25571
  if(RewriteRule<UdivPow2>::applies(node)) {
487
1441
    resultNode = RewriteRule<UdivPow2>::run <false> (node);
488
1441
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
489
  }
490
491
24130
  resultNode =
492
      LinearRewriteStrategy<RewriteRule<EvalUdiv>, RewriteRule<UdivZero>,
493
48260
                            RewriteRule<UdivOne> >::apply(node);
494
495
24130
  return RewriteResponse(REWRITE_DONE, resultNode);
496
}
497
498
25238
RewriteResponse TheoryBVRewriter::RewriteUrem(TNode node, bool prerewrite)
499
{
500
50476
  Node resultNode = node;
501
502
25238
  if(RewriteRule<UremPow2>::applies(node)) {
503
1183
    resultNode = RewriteRule<UremPow2>::run <false> (node);
504
1183
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
505
  }
506
507
24055
  resultNode = LinearRewriteStrategy
508
    < RewriteRule<EvalUrem>,
509
      RewriteRule<UremOne>,
510
      RewriteRule<UremSelf>
511
48110
      >::apply(node);
512
24055
  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
21993
RewriteResponse TheoryBVRewriter::RewriteShl(TNode node, bool prerewrite) {
539
43986
  Node resultNode = node;
540
21993
  if(RewriteRule<ShlByConst>::applies(node)) {
541
13667
    resultNode = RewriteRule<ShlByConst>::run <false> (node);
542
13667
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
543
  }
544
545
8326
  resultNode = LinearRewriteStrategy
546
    < RewriteRule<EvalShl>,
547
      RewriteRule<ShiftZero>
548
16652
      >::apply(node);
549
550
8326
  return RewriteResponse(REWRITE_DONE, resultNode);
551
}
552
553
26501
RewriteResponse TheoryBVRewriter::RewriteLshr(TNode node, bool prerewrite) {
554
53002
  Node resultNode = node;
555
26501
  if(RewriteRule<LshrByConst>::applies(node)) {
556
14794
    resultNode = RewriteRule<LshrByConst>::run <false> (node);
557
14794
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
558
  }
559
560
11707
  resultNode = LinearRewriteStrategy
561
    < RewriteRule<EvalLshr>,
562
      RewriteRule<ShiftZero>
563
23414
      >::apply(node);
564
565
11707
  return RewriteResponse(REWRITE_DONE, resultNode);
566
}
567
568
6215
RewriteResponse TheoryBVRewriter::RewriteAshr(TNode node, bool prerewrite) {
569
12430
  Node resultNode = node;
570
6215
  if(RewriteRule<AshrByConst>::applies(node)) {
571
791
    resultNode = RewriteRule<AshrByConst>::run <false> (node);
572
791
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
573
  }
574
575
5424
  resultNode = LinearRewriteStrategy
576
    < RewriteRule<EvalAshr>,
577
      RewriteRule<ShiftZero>
578
10848
        >::apply(node);
579
580
5424
  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
9974
RewriteResponse TheoryBVRewriter::RewriteZeroExtend(TNode node, bool prerewrite){
593
  Node resultNode = LinearRewriteStrategy
594
    < RewriteRule<ZeroExtendEliminate >
595
19948
    >::apply(node);
596
597
19948
  return RewriteResponse(REWRITE_AGAIN, resultNode);
598
}
599
600
54853
RewriteResponse TheoryBVRewriter::RewriteSignExtend(TNode node, bool prerewrite) {
601
  Node resultNode = LinearRewriteStrategy
602
    < RewriteRule<MergeSignExtend>
603
    , RewriteRule<EvalSignExtend>
604
109706
    >::apply(node);
605
606
607
54853
  if (resultNode != node) {
608
2016
    return RewriteResponse(REWRITE_AGAIN, resultNode);
609
  }
610
52837
  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
990
RewriteResponse TheoryBVRewriter::RewriteBVToNat(TNode node, bool prerewrite) {
647
990
  if (node[0].isConst())
648
  {
649
    Node resultNode = LinearRewriteStrategy
650
      < RewriteRule<BVToNatEliminate>
651
388
      >::apply(node);
652
194
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
653
  }else{
654
796
    return RewriteResponse(REWRITE_DONE, node);
655
  }
656
}
657
658
794
RewriteResponse TheoryBVRewriter::RewriteIntToBV(TNode node, bool prerewrite) {
659
794
  if (node[0].isConst())
660
  {
661
    Node resultNode = LinearRewriteStrategy
662
      < RewriteRule<IntToBVEliminate>
663
558
      >::apply(node);
664
665
279
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
666
  }else{
667
515
    return RewriteResponse(REWRITE_DONE, node);
668
  }
669
}
670
671
418705
RewriteResponse TheoryBVRewriter::RewriteEqual(TNode node, bool prerewrite) {
672
418705
  if (prerewrite) {
673
    Node resultNode = LinearRewriteStrategy
674
      < RewriteRule<FailEq>,
675
        RewriteRule<SimplifyEq>,
676
        RewriteRule<ReflexivityEq>
677
344078
        >::apply(node);
678
172039
    return RewriteResponse(REWRITE_DONE, resultNode);
679
  }
680
  else {
681
    Node resultNode = LinearRewriteStrategy
682
      < RewriteRule<FailEq>,
683
        RewriteRule<SimplifyEq>,
684
        RewriteRule<ReflexivityEq>
685
493332
        >::apply(node);
686
687
246666
    if(RewriteRule<SolveEq>::applies(resultNode)) {
688
131664
      resultNode = RewriteRule<SolveEq>::run<false>(resultNode);
689
131664
      if (resultNode != node) {
690
6012
        return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
691
      }
692
    }
693
240654
    return RewriteResponse(REWRITE_DONE, resultNode);
694
  }
695
}
696
697
698
214127
RewriteResponse TheoryBVRewriter::IdentityRewrite(TNode node, bool prerewrite) {
699
214127
  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
9838
void TheoryBVRewriter::initializeRewrites() {
710
711
3217026
  for(unsigned i = 0; i < kind::LAST_KIND; ++i) {
712
3207188
    d_rewriteTable[i] = IdentityRewrite; //UndefinedRewrite;
713
  }
714
715
9838
  d_rewriteTable [ kind::EQUAL ] = RewriteEqual;
716
9838
  d_rewriteTable[kind::BITVECTOR_BITOF] = RewriteBitOf;
717
9838
  d_rewriteTable [ kind::BITVECTOR_ULT ] = RewriteUlt;
718
9838
  d_rewriteTable [ kind::BITVECTOR_SLT ] = RewriteSlt;
719
9838
  d_rewriteTable [ kind::BITVECTOR_ULE ] = RewriteUle;
720
9838
  d_rewriteTable [ kind::BITVECTOR_SLE ] = RewriteSle;
721
9838
  d_rewriteTable [ kind::BITVECTOR_UGT ] = RewriteUgt;
722
9838
  d_rewriteTable [ kind::BITVECTOR_SGT ] = RewriteSgt;
723
9838
  d_rewriteTable [ kind::BITVECTOR_UGE ] = RewriteUge;
724
9838
  d_rewriteTable [ kind::BITVECTOR_SGE ] = RewriteSge;
725
9838
  d_rewriteTable [ kind::BITVECTOR_NOT ] = RewriteNot;
726
9838
  d_rewriteTable [ kind::BITVECTOR_CONCAT ] = RewriteConcat;
727
9838
  d_rewriteTable [ kind::BITVECTOR_AND ] = RewriteAnd;
728
9838
  d_rewriteTable [ kind::BITVECTOR_OR ] = RewriteOr;
729
9838
  d_rewriteTable [ kind::BITVECTOR_XOR] = RewriteXor;
730
9838
  d_rewriteTable [ kind::BITVECTOR_XNOR ] = RewriteXnor;
731
9838
  d_rewriteTable [ kind::BITVECTOR_NAND ] = RewriteNand;
732
9838
  d_rewriteTable [ kind::BITVECTOR_NOR ] = RewriteNor;
733
9838
  d_rewriteTable [ kind::BITVECTOR_COMP ] = RewriteComp;
734
9838
  d_rewriteTable [ kind::BITVECTOR_MULT ] = RewriteMult;
735
9838
  d_rewriteTable[kind::BITVECTOR_ADD] = RewriteAdd;
736
9838
  d_rewriteTable [ kind::BITVECTOR_SUB ] = RewriteSub;
737
9838
  d_rewriteTable [ kind::BITVECTOR_NEG ] = RewriteNeg;
738
9838
  d_rewriteTable [ kind::BITVECTOR_UDIV ] = RewriteUdiv;
739
9838
  d_rewriteTable [ kind::BITVECTOR_UREM ] = RewriteUrem;
740
9838
  d_rewriteTable [ kind::BITVECTOR_SMOD ] = RewriteSmod;
741
9838
  d_rewriteTable [ kind::BITVECTOR_SDIV ] = RewriteSdiv;
742
9838
  d_rewriteTable [ kind::BITVECTOR_SREM ] = RewriteSrem;
743
9838
  d_rewriteTable [ kind::BITVECTOR_SHL ] = RewriteShl;
744
9838
  d_rewriteTable [ kind::BITVECTOR_LSHR ] = RewriteLshr;
745
9838
  d_rewriteTable [ kind::BITVECTOR_ASHR ] = RewriteAshr;
746
9838
  d_rewriteTable [ kind::BITVECTOR_EXTRACT ] = RewriteExtract;
747
9838
  d_rewriteTable [ kind::BITVECTOR_REPEAT ] = RewriteRepeat;
748
9838
  d_rewriteTable [ kind::BITVECTOR_ZERO_EXTEND ] = RewriteZeroExtend;
749
9838
  d_rewriteTable [ kind::BITVECTOR_SIGN_EXTEND ] = RewriteSignExtend;
750
9838
  d_rewriteTable [ kind::BITVECTOR_ROTATE_RIGHT ] = RewriteRotateRight;
751
9838
  d_rewriteTable [ kind::BITVECTOR_ROTATE_LEFT ] = RewriteRotateLeft;
752
9838
  d_rewriteTable [ kind::BITVECTOR_REDOR ] = RewriteRedor;
753
9838
  d_rewriteTable [ kind::BITVECTOR_REDAND ] = RewriteRedand;
754
9838
  d_rewriteTable [ kind::BITVECTOR_ULTBV ] = RewriteUltBv;
755
9838
  d_rewriteTable [ kind::BITVECTOR_SLTBV ] = RewriteSltBv;
756
9838
  d_rewriteTable [ kind::BITVECTOR_ITE ] = RewriteITEBv;
757
9838
  d_rewriteTable[kind::BITVECTOR_EAGER_ATOM] = RewriteEagerAtom;
758
759
9838
  d_rewriteTable [ kind::BITVECTOR_TO_NAT ] = RewriteBVToNat;
760
9838
  d_rewriteTable [ kind::INT_TO_BITVECTOR ] = RewriteIntToBV;
761
9838
}
762
763
8
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
8
    >::apply(node);
769
8
  return result;
770
169207
}