GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/theory_bv_rewriter.cpp Lines: 324 338 95.9 %
Date: 2021-09-29 Branches: 481 936 51.4 %

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
6271
TheoryBVRewriter::TheoryBVRewriter() { initializeRewrites(); }
34
35
954238
RewriteResponse TheoryBVRewriter::preRewrite(TNode node) {
36
954238
  RewriteResponse res = d_rewriteTable[node.getKind()](node, true);
37
954238
  if (res.d_node != node)
38
  {
39
273141
    Debug("bitvector-rewrite") << "TheoryBV::preRewrite    " << node << std::endl;
40
546282
    Debug("bitvector-rewrite")
41
273141
        << "TheoryBV::preRewrite to " << res.d_node << std::endl;
42
  }
43
954238
  return res;
44
}
45
46
1166165
RewriteResponse TheoryBVRewriter::postRewrite(TNode node) {
47
1166165
  RewriteResponse res = d_rewriteTable[node.getKind()](node, false);
48
1166165
  if (res.d_node != node)
49
  {
50
231379
    Debug("bitvector-rewrite") << "TheoryBV::postRewrite    " << node << std::endl;
51
462758
    Debug("bitvector-rewrite")
52
231379
        << "TheoryBV::postRewrite to " << res.d_node << std::endl;
53
  }
54
1166165
  return res;
55
}
56
57
203035
TrustNode TheoryBVRewriter::expandDefinition(Node node)
58
{
59
406070
  Debug("bitvector-expandDefinition")
60
203035
      << "TheoryBV::expandDefinition(" << node << ")" << std::endl;
61
406070
  Node ret;
62
203035
  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
38
    case kind::BITVECTOR_TO_NAT:
68
69
38
        ret = utils::eliminateBv2Nat(node);
70
71
38
      break;
72
35
    case kind::INT_TO_BITVECTOR:
73
74
35
        ret = utils::eliminateInt2Bv(node);
75
76
35
      break;
77
202952
    default: break;
78
  }
79
203035
  if (!ret.isNull() && node != ret)
80
  {
81
83
    return TrustNode::mkTrustRewrite(node, ret, nullptr);
82
  }
83
202952
  return TrustNode::null();
84
}
85
86
451550
RewriteResponse TheoryBVRewriter::RewriteBitOf(TNode node, bool prerewrite)
87
{
88
903100
  Node resultNode = LinearRewriteStrategy<RewriteRule<BitOfConst>>::apply(node);
89
903100
  return RewriteResponse(REWRITE_DONE, resultNode);
90
}
91
92
41952
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
83904
       >::apply(node);
100
101
41952
  return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL,
102
125856
                         resultNode);
103
}
104
105
4282
RewriteResponse TheoryBVRewriter::RewriteUltBv(TNode node, bool prerewrite) {
106
  // reduce common subexpressions on both sides
107
  Node resultNode = LinearRewriteStrategy
108
    < RewriteRule<EvalUltBv>
109
8564
       >::apply(node);
110
111
8564
  return RewriteResponse(REWRITE_DONE, resultNode);
112
}
113
114
115
43944
RewriteResponse TheoryBVRewriter::RewriteSlt(TNode node, bool prerewrite){
116
  Node resultNode = LinearRewriteStrategy
117
    < RewriteRule<EvalSlt>,
118
      RewriteRule<MultSltMult>
119
87888
       >::apply(node);
120
121
87888
  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
5659
RewriteResponse TheoryBVRewriter::RewriteSltBv(TNode node, bool prerewrite){
132
  Node resultNode = LinearRewriteStrategy
133
    < RewriteRule < EvalSltBv >
134
11318
       >::apply(node);
135
136
11318
  return RewriteResponse(REWRITE_DONE, resultNode);
137
}
138
139
2410
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
4820
      >::apply(node);
148
4820
  return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN, resultNode);
149
}
150
151
2532
RewriteResponse TheoryBVRewriter::RewriteSle(TNode node, bool prerewrite){
152
  Node resultNode = LinearRewriteStrategy
153
    < RewriteRule <EvalSle>,
154
      RewriteRule <SleEliminate>
155
5064
      >::apply(node);
156
5064
  return RewriteResponse(resultNode == node? REWRITE_DONE : REWRITE_AGAIN, resultNode);
157
}
158
159
1456
RewriteResponse TheoryBVRewriter::RewriteUgt(TNode node, bool prerewrite){
160
  Node resultNode =
161
      LinearRewriteStrategy<RewriteRule<UgtUrem>,
162
2912
                            RewriteRule<UgtEliminate>>::apply(node);
163
164
2912
  return RewriteResponse(REWRITE_AGAIN, resultNode);
165
}
166
167
1491
RewriteResponse TheoryBVRewriter::RewriteSgt(TNode node, bool prerewrite){
168
  Node resultNode = LinearRewriteStrategy
169
    < RewriteRule<SgtEliminate>
170
      //RewriteRule<SltEliminate>
171
2982
      >::apply(node);
172
173
2982
  return RewriteResponse(REWRITE_AGAIN, resultNode);
174
}
175
176
1247
RewriteResponse TheoryBVRewriter::RewriteUge(TNode node, bool prerewrite){
177
  Node resultNode = LinearRewriteStrategy
178
    < RewriteRule<UgeEliminate>
179
2494
    >::apply(node);
180
181
2494
  return RewriteResponse(REWRITE_AGAIN, resultNode);
182
}
183
184
1235
RewriteResponse TheoryBVRewriter::RewriteSge(TNode node, bool prerewrite){
185
  Node resultNode = LinearRewriteStrategy
186
    < RewriteRule<SgeEliminate>
187
      //      RewriteRule<SleEliminate>
188
2470
    >::apply(node);
189
190
2470
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
191
}
192
193
21636
RewriteResponse TheoryBVRewriter::RewriteITEBv(TNode node, bool prerewrite)
194
{
195
  Node resultNode =
196
      LinearRewriteStrategy<RewriteRule<EvalITEBv>,
197
                            RewriteRule<BvIteConstCond>,
198
43272
                            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
21636
  if (resultNode != node)
206
  {
207
1772
    return RewriteResponse(REWRITE_AGAIN, resultNode);
208
  }
209
210
19864
  resultNode = LinearRewriteStrategy<RewriteRule<BvIteConstChildren>,
211
39728
                                     RewriteRule<BvIteEqualCond>>::apply(node);
212
19864
  if (resultNode != node)
213
  {
214
215
    return RewriteResponse(REWRITE_AGAIN, resultNode);
215
  }
216
217
19649
  resultNode =
218
      LinearRewriteStrategy<RewriteRule<BvIteMergeThenIf>,
219
                            RewriteRule<BvIteMergeElseIf>,
220
                            RewriteRule<BvIteMergeThenElse>,
221
39298
                            RewriteRule<BvIteMergeElseElse>>::apply(node);
222
19649
  return RewriteResponse(resultNode == node ? REWRITE_DONE : REWRITE_AGAIN_FULL,
223
39298
                         resultNode);
224
}
225
226
74194
RewriteResponse TheoryBVRewriter::RewriteNot(TNode node, bool prerewrite){
227
148388
  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
74194
  resultNode = LinearRewriteStrategy
234
    < RewriteRule<EvalNot>,
235
      RewriteRule<NotIdemp>
236
148388
    >::apply(node);
237
238
148388
  return RewriteResponse(REWRITE_DONE, resultNode);
239
}
240
241
87880
RewriteResponse TheoryBVRewriter::RewriteExtract(TNode node, bool prerewrite) {
242
175760
  Node resultNode = node;
243
244
87880
  if (RewriteRule<ExtractConcat>::applies(node)) {
245
6908
    resultNode = RewriteRule<ExtractConcat>::run<false>(node);
246
6908
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
247
  }
248
249
80972
  if (RewriteRule<ExtractSignExtend>::applies(node)) {
250
280
    resultNode = RewriteRule<ExtractSignExtend>::run<false>(node);
251
280
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
252
  }
253
254
80692
  if (RewriteRule<ExtractNot>::applies(node)) {
255
1263
    resultNode = RewriteRule<ExtractNot>::run<false>(node);
256
1263
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
257
  }
258
259
79429
  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
79429
  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
158858
      >::apply(node);
275
276
79429
  return RewriteResponse(REWRITE_DONE, resultNode);
277
}
278
279
116157
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
232314
      ApplyRuleToChildren<kind::BITVECTOR_CONCAT, ExtractWhole>>::apply(node);
289
232314
  return RewriteResponse(REWRITE_DONE, resultNode);
290
}
291
292
108709
RewriteResponse TheoryBVRewriter::RewriteAnd(TNode node, bool prerewrite)
293
{
294
217418
  Node resultNode = node;
295
108709
  resultNode =
296
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
297
                            RewriteRule<AndSimplify>,
298
217418
                            RewriteRule<AndOrXorConcatPullUp>>::apply(node);
299
108709
  if (!prerewrite)
300
  {
301
52172
    resultNode =
302
104344
        LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
303
304
52172
    if (resultNode.getKind() != node.getKind())
305
    {
306
26014
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
307
    }
308
  }
309
310
82695
  return RewriteResponse(REWRITE_DONE, resultNode);
311
}
312
313
133288
RewriteResponse TheoryBVRewriter::RewriteOr(TNode node, bool prerewrite)
314
{
315
266576
  Node resultNode = node;
316
133288
  resultNode =
317
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommutNoDuplicates>,
318
                            RewriteRule<OrSimplify>,
319
266576
                            RewriteRule<AndOrXorConcatPullUp>>::apply(node);
320
321
133288
  if (!prerewrite)
322
  {
323
66300
    resultNode =
324
132600
        LinearRewriteStrategy<RewriteRule<BitwiseSlicing>>::apply(resultNode);
325
326
66300
    if (resultNode.getKind() != node.getKind())
327
    {
328
31453
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
329
    }
330
  }
331
332
101835
  return RewriteResponse(REWRITE_DONE, resultNode);
333
}
334
335
4560
RewriteResponse TheoryBVRewriter::RewriteXor(TNode node, bool prerewrite)
336
{
337
9120
  Node resultNode = node;
338
4560
  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
9120
      RewriteRule<BitwiseSlicing>>::apply(node);
345
346
4560
  if (!prerewrite)
347
  {
348
2286
    resultNode =
349
        LinearRewriteStrategy<RewriteRule<XorOne>,
350
4572
                              RewriteRule<BitwiseSlicing>>::apply(resultNode);
351
352
2286
    if (resultNode.getKind() != node.getKind())
353
    {
354
853
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
355
    }
356
  }
357
358
3707
  return RewriteResponse(REWRITE_DONE, resultNode);
359
}
360
361
219
RewriteResponse TheoryBVRewriter::RewriteXnor(TNode node, bool prerewrite) {
362
  Node resultNode = LinearRewriteStrategy
363
    < RewriteRule<XnorEliminate>
364
438
    >::apply(node);
365
  // need to rewrite two levels in
366
438
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
367
}
368
369
145
RewriteResponse TheoryBVRewriter::RewriteNand(TNode node, bool prerewrite) {
370
  Node resultNode = LinearRewriteStrategy
371
    < RewriteRule<NandEliminate>
372
290
      >::apply(node);
373
374
290
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
375
}
376
377
184
RewriteResponse TheoryBVRewriter::RewriteNor(TNode node, bool prerewrite) {
378
  Node resultNode = LinearRewriteStrategy
379
    < RewriteRule<NorEliminate>
380
368
    >::apply(node);
381
382
368
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
383
}
384
385
61976
RewriteResponse TheoryBVRewriter::RewriteComp(TNode node, bool prerewrite)
386
{
387
123952
  Node resultNode = LinearRewriteStrategy<RewriteRule<EvalComp>>::apply(node);
388
389
61976
  if (node == resultNode && RewriteRule<BvComp>::applies(node))
390
  {
391
1137
    resultNode = RewriteRule<BvComp>::run<false>(node);
392
1137
    return RewriteResponse(REWRITE_AGAIN, resultNode);
393
  }
394
395
60839
  return RewriteResponse(REWRITE_DONE, resultNode);
396
}
397
398
70
RewriteResponse TheoryBVRewriter::RewriteEagerAtom(TNode node, bool prerewrite)
399
{
400
  Node resultNode =
401
140
      LinearRewriteStrategy<RewriteRule<EvalEagerAtom>>::apply(node);
402
403
140
  return RewriteResponse(REWRITE_DONE, resultNode);
404
}
405
406
230109
RewriteResponse TheoryBVRewriter::RewriteMult(TNode node, bool prerewrite) {
407
460218
  Node resultNode = node;
408
230109
  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
460218
    >::apply(resultNode);
413
414
  // only apply if every subterm was already rewritten
415
230109
  if (!prerewrite) {
416
87265
    resultNode = LinearRewriteStrategy
417
      <   RewriteRule<MultDistribConst>
418
        , RewriteRule<MultDistrib>
419
174530
        >::apply(resultNode);
420
  }
421
422
230109
  if(resultNode == node) {
423
144647
    return RewriteResponse(REWRITE_DONE, resultNode);
424
  }
425
85462
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
426
}
427
428
117486
RewriteResponse TheoryBVRewriter::RewriteAdd(TNode node, bool prerewrite)
429
{
430
234972
  Node resultNode = node;
431
117486
  if (prerewrite) {
432
51627
    resultNode = LinearRewriteStrategy
433
      < RewriteRule<FlattenAssocCommut>
434
103254
        >::apply(node);
435
51627
    return RewriteResponse(REWRITE_DONE, resultNode);
436
  }
437
438
65859
  resultNode =
439
      LinearRewriteStrategy<RewriteRule<FlattenAssocCommut>,
440
131718
                            RewriteRule<AddCombineLikeTerms>>::apply(node);
441
442
65859
  if (node != resultNode) {
443
37109
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
444
  }
445
446
28750
  return RewriteResponse(REWRITE_DONE, resultNode);
447
}
448
449
1494
RewriteResponse TheoryBVRewriter::RewriteSub(TNode node, bool prerewrite){
450
  // return RewriteResponse(REWRITE_DONE, node);
451
  Node resultNode = LinearRewriteStrategy
452
    < RewriteRule<SubEliminate>
453
2988
    >::apply(node);
454
455
2988
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
456
}
457
458
26804
RewriteResponse TheoryBVRewriter::RewriteNeg(TNode node, bool prerewrite) {
459
53608
  Node resultNode = node;
460
461
26804
  resultNode = LinearRewriteStrategy
462
    < RewriteRule<EvalNeg>,
463
      RewriteRule<NegIdemp>,
464
      RewriteRule<NegSub>
465
53608
      >::apply(node);
466
467
26804
  if (RewriteRule<NegAdd>::applies(node))
468
  {
469
1224
    resultNode = RewriteRule<NegAdd>::run<false>(node);
470
1224
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
471
  }
472
473
25580
  if(!prerewrite) {
474
13609
    if (RewriteRule<NegMult>::applies(node)) {
475
      resultNode = RewriteRule<NegMult>::run<false>(node);
476
      return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
477
    }
478
  }
479
480
25580
  return RewriteResponse(REWRITE_DONE, resultNode);
481
}
482
483
23381
RewriteResponse TheoryBVRewriter::RewriteUdiv(TNode node, bool prerewrite){
484
46762
  Node resultNode = node;
485
486
23381
  if(RewriteRule<UdivPow2>::applies(node)) {
487
1435
    resultNode = RewriteRule<UdivPow2>::run <false> (node);
488
1435
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
489
  }
490
491
21946
  resultNode =
492
      LinearRewriteStrategy<RewriteRule<EvalUdiv>, RewriteRule<UdivZero>,
493
43892
                            RewriteRule<UdivOne> >::apply(node);
494
495
21946
  return RewriteResponse(REWRITE_DONE, resultNode);
496
}
497
498
23225
RewriteResponse TheoryBVRewriter::RewriteUrem(TNode node, bool prerewrite)
499
{
500
46450
  Node resultNode = node;
501
502
23225
  if(RewriteRule<UremPow2>::applies(node)) {
503
1177
    resultNode = RewriteRule<UremPow2>::run <false> (node);
504
1177
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
505
  }
506
507
22048
  resultNode = LinearRewriteStrategy
508
    < RewriteRule<EvalUrem>,
509
      RewriteRule<UremOne>,
510
      RewriteRule<UremSelf>
511
44096
      >::apply(node);
512
22048
  return RewriteResponse(REWRITE_DONE, resultNode);
513
}
514
515
35
RewriteResponse TheoryBVRewriter::RewriteSmod(TNode node, bool prerewrite) {
516
  Node resultNode = LinearRewriteStrategy
517
    < RewriteRule<SmodEliminate>
518
70
      >::apply(node);
519
520
70
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
521
}
522
523
72
RewriteResponse TheoryBVRewriter::RewriteSdiv(TNode node, bool prerewrite) {
524
  Node resultNode = LinearRewriteStrategy
525
    < RewriteRule<SdivEliminate>
526
144
      >::apply(node);
527
528
144
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
529
}
530
531
18
RewriteResponse TheoryBVRewriter::RewriteSrem(TNode node, bool prerewrite) {
532
  Node resultNode = LinearRewriteStrategy
533
    < RewriteRule<SremEliminate>
534
36
       >::apply(node);
535
36
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
536
}
537
538
21082
RewriteResponse TheoryBVRewriter::RewriteShl(TNode node, bool prerewrite) {
539
42164
  Node resultNode = node;
540
21082
  if(RewriteRule<ShlByConst>::applies(node)) {
541
14859
    resultNode = RewriteRule<ShlByConst>::run <false> (node);
542
14859
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
543
  }
544
545
6223
  resultNode = LinearRewriteStrategy
546
    < RewriteRule<EvalShl>,
547
      RewriteRule<ShiftZero>
548
12446
      >::apply(node);
549
550
6223
  return RewriteResponse(REWRITE_DONE, resultNode);
551
}
552
553
24737
RewriteResponse TheoryBVRewriter::RewriteLshr(TNode node, bool prerewrite) {
554
49474
  Node resultNode = node;
555
24737
  if(RewriteRule<LshrByConst>::applies(node)) {
556
15573
    resultNode = RewriteRule<LshrByConst>::run <false> (node);
557
15573
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
558
  }
559
560
9164
  resultNode = LinearRewriteStrategy
561
    < RewriteRule<EvalLshr>,
562
      RewriteRule<ShiftZero>
563
18328
      >::apply(node);
564
565
9164
  return RewriteResponse(REWRITE_DONE, resultNode);
566
}
567
568
3314
RewriteResponse TheoryBVRewriter::RewriteAshr(TNode node, bool prerewrite) {
569
6628
  Node resultNode = node;
570
3314
  if(RewriteRule<AshrByConst>::applies(node)) {
571
532
    resultNode = RewriteRule<AshrByConst>::run <false> (node);
572
532
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
573
  }
574
575
2782
  resultNode = LinearRewriteStrategy
576
    < RewriteRule<EvalAshr>,
577
      RewriteRule<ShiftZero>
578
5564
        >::apply(node);
579
580
2782
  return RewriteResponse(REWRITE_DONE, resultNode);
581
}
582
583
584
175
RewriteResponse TheoryBVRewriter::RewriteRepeat(TNode node, bool prerewrite) {
585
  Node resultNode = LinearRewriteStrategy
586
    < RewriteRule<RepeatEliminate >
587
350
    >::apply(node);
588
589
350
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
590
}
591
592
4055
RewriteResponse TheoryBVRewriter::RewriteZeroExtend(TNode node, bool prerewrite){
593
  Node resultNode = LinearRewriteStrategy
594
    < RewriteRule<ZeroExtendEliminate >
595
8110
    >::apply(node);
596
597
8110
  return RewriteResponse(REWRITE_AGAIN, resultNode);
598
}
599
600
24112
RewriteResponse TheoryBVRewriter::RewriteSignExtend(TNode node, bool prerewrite) {
601
  Node resultNode = LinearRewriteStrategy
602
    < RewriteRule<MergeSignExtend>
603
    , RewriteRule<EvalSignExtend>
604
48224
    >::apply(node);
605
606
607
24112
  if (resultNode != node) {
608
1295
    return RewriteResponse(REWRITE_AGAIN, resultNode);
609
  }
610
22817
  return RewriteResponse(REWRITE_DONE, resultNode);
611
}
612
613
614
168
RewriteResponse TheoryBVRewriter::RewriteRotateRight(TNode node, bool prerewrite) {
615
  Node resultNode = LinearRewriteStrategy
616
    < RewriteRule<RotateRightEliminate >
617
336
    >::apply(node);
618
619
336
  return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
620
}
621
622
133
RewriteResponse TheoryBVRewriter::RewriteRotateLeft(TNode node, bool prerewrite){
623
  Node resultNode = LinearRewriteStrategy
624
    < RewriteRule<RotateLeftEliminate >
625
266
    >::apply(node);
626
627
266
  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
896
RewriteResponse TheoryBVRewriter::RewriteBVToNat(TNode node, bool prerewrite) {
647
896
  if (node[0].isConst())
648
  {
649
    Node resultNode = LinearRewriteStrategy
650
      < RewriteRule<BVToNatEliminate>
651
510
      >::apply(node);
652
255
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
653
  }else{
654
641
    return RewriteResponse(REWRITE_DONE, node);
655
  }
656
}
657
658
511
RewriteResponse TheoryBVRewriter::RewriteIntToBV(TNode node, bool prerewrite) {
659
511
  if (node[0].isConst())
660
  {
661
    Node resultNode = LinearRewriteStrategy
662
      < RewriteRule<IntToBVEliminate>
663
438
      >::apply(node);
664
665
219
    return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
666
  }else{
667
292
    return RewriteResponse(REWRITE_DONE, node);
668
  }
669
}
670
671
280460
RewriteResponse TheoryBVRewriter::RewriteEqual(TNode node, bool prerewrite) {
672
280460
  if (prerewrite) {
673
    Node resultNode = LinearRewriteStrategy
674
      < RewriteRule<FailEq>,
675
        RewriteRule<SimplifyEq>,
676
        RewriteRule<ReflexivityEq>
677
224390
        >::apply(node);
678
112195
    return RewriteResponse(REWRITE_DONE, resultNode);
679
  }
680
  else {
681
    Node resultNode = LinearRewriteStrategy
682
      < RewriteRule<FailEq>,
683
        RewriteRule<SimplifyEq>,
684
        RewriteRule<ReflexivityEq>
685
336530
        >::apply(node);
686
687
168265
    if(RewriteRule<SolveEq>::applies(resultNode)) {
688
103280
      resultNode = RewriteRule<SolveEq>::run<false>(resultNode);
689
103280
      if (resultNode != node) {
690
3526
        return RewriteResponse(REWRITE_AGAIN_FULL, resultNode);
691
      }
692
    }
693
164739
    return RewriteResponse(REWRITE_DONE, resultNode);
694
  }
695
}
696
697
698
171360
RewriteResponse TheoryBVRewriter::IdentityRewrite(TNode node, bool prerewrite) {
699
171360
  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
6271
void TheoryBVRewriter::initializeRewrites() {
710
711
2056888
  for(unsigned i = 0; i < kind::LAST_KIND; ++i) {
712
2050617
    d_rewriteTable[i] = IdentityRewrite; //UndefinedRewrite;
713
  }
714
715
6271
  d_rewriteTable [ kind::EQUAL ] = RewriteEqual;
716
6271
  d_rewriteTable[kind::BITVECTOR_BITOF] = RewriteBitOf;
717
6271
  d_rewriteTable [ kind::BITVECTOR_ULT ] = RewriteUlt;
718
6271
  d_rewriteTable [ kind::BITVECTOR_SLT ] = RewriteSlt;
719
6271
  d_rewriteTable [ kind::BITVECTOR_ULE ] = RewriteUle;
720
6271
  d_rewriteTable [ kind::BITVECTOR_SLE ] = RewriteSle;
721
6271
  d_rewriteTable [ kind::BITVECTOR_UGT ] = RewriteUgt;
722
6271
  d_rewriteTable [ kind::BITVECTOR_SGT ] = RewriteSgt;
723
6271
  d_rewriteTable [ kind::BITVECTOR_UGE ] = RewriteUge;
724
6271
  d_rewriteTable [ kind::BITVECTOR_SGE ] = RewriteSge;
725
6271
  d_rewriteTable [ kind::BITVECTOR_NOT ] = RewriteNot;
726
6271
  d_rewriteTable [ kind::BITVECTOR_CONCAT ] = RewriteConcat;
727
6271
  d_rewriteTable [ kind::BITVECTOR_AND ] = RewriteAnd;
728
6271
  d_rewriteTable [ kind::BITVECTOR_OR ] = RewriteOr;
729
6271
  d_rewriteTable [ kind::BITVECTOR_XOR] = RewriteXor;
730
6271
  d_rewriteTable [ kind::BITVECTOR_XNOR ] = RewriteXnor;
731
6271
  d_rewriteTable [ kind::BITVECTOR_NAND ] = RewriteNand;
732
6271
  d_rewriteTable [ kind::BITVECTOR_NOR ] = RewriteNor;
733
6271
  d_rewriteTable [ kind::BITVECTOR_COMP ] = RewriteComp;
734
6271
  d_rewriteTable [ kind::BITVECTOR_MULT ] = RewriteMult;
735
6271
  d_rewriteTable[kind::BITVECTOR_ADD] = RewriteAdd;
736
6271
  d_rewriteTable [ kind::BITVECTOR_SUB ] = RewriteSub;
737
6271
  d_rewriteTable [ kind::BITVECTOR_NEG ] = RewriteNeg;
738
6271
  d_rewriteTable [ kind::BITVECTOR_UDIV ] = RewriteUdiv;
739
6271
  d_rewriteTable [ kind::BITVECTOR_UREM ] = RewriteUrem;
740
6271
  d_rewriteTable [ kind::BITVECTOR_SMOD ] = RewriteSmod;
741
6271
  d_rewriteTable [ kind::BITVECTOR_SDIV ] = RewriteSdiv;
742
6271
  d_rewriteTable [ kind::BITVECTOR_SREM ] = RewriteSrem;
743
6271
  d_rewriteTable [ kind::BITVECTOR_SHL ] = RewriteShl;
744
6271
  d_rewriteTable [ kind::BITVECTOR_LSHR ] = RewriteLshr;
745
6271
  d_rewriteTable [ kind::BITVECTOR_ASHR ] = RewriteAshr;
746
6271
  d_rewriteTable [ kind::BITVECTOR_EXTRACT ] = RewriteExtract;
747
6271
  d_rewriteTable [ kind::BITVECTOR_REPEAT ] = RewriteRepeat;
748
6271
  d_rewriteTable [ kind::BITVECTOR_ZERO_EXTEND ] = RewriteZeroExtend;
749
6271
  d_rewriteTable [ kind::BITVECTOR_SIGN_EXTEND ] = RewriteSignExtend;
750
6271
  d_rewriteTable [ kind::BITVECTOR_ROTATE_RIGHT ] = RewriteRotateRight;
751
6271
  d_rewriteTable [ kind::BITVECTOR_ROTATE_LEFT ] = RewriteRotateLeft;
752
6271
  d_rewriteTable [ kind::BITVECTOR_REDOR ] = RewriteRedor;
753
6271
  d_rewriteTable [ kind::BITVECTOR_REDAND ] = RewriteRedand;
754
6271
  d_rewriteTable [ kind::BITVECTOR_ULTBV ] = RewriteUltBv;
755
6271
  d_rewriteTable [ kind::BITVECTOR_SLTBV ] = RewriteSltBv;
756
6271
  d_rewriteTable [ kind::BITVECTOR_ITE ] = RewriteITEBv;
757
6271
  d_rewriteTable[kind::BITVECTOR_EAGER_ATOM] = RewriteEagerAtom;
758
759
6271
  d_rewriteTable [ kind::BITVECTOR_TO_NAT ] = RewriteBVToNat;
760
6271
  d_rewriteTable [ kind::INT_TO_BITVECTOR ] = RewriteIntToBV;
761
6271
}
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
22746
}