GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/theory_bv_rewrite_rules.h Lines: 74 243 30.5 %
Date: 2021-09-29 Branches: 4708 17541 26.8 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Liana Hadarean, Dejan Jovanovic, Aina Niemetz
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 "cvc5_private.h"
20
21
#pragma once
22
23
#include <sstream>
24
25
#include "context/context.h"
26
#include "printer/printer.h"
27
#include "smt/dump.h"
28
#include "smt/smt_engine.h"
29
#include "smt/smt_engine_scope.h"
30
#include "theory/bv/theory_bv_utils.h"
31
#include "theory/theory.h"
32
#include "util/statistics_stats.h"
33
34
namespace cvc5 {
35
namespace theory {
36
namespace bv {
37
38
enum RewriteRuleId
39
{
40
41
  /// core normalization rules
42
  EmptyRule,
43
  ConcatFlatten,
44
  ConcatExtractMerge,
45
  ConcatConstantMerge,
46
  ExtractExtract,
47
  ExtractWhole,
48
  ExtractConcat,
49
  ExtractConstant,
50
  FailEq,
51
  SimplifyEq,
52
  ReflexivityEq,
53
54
  /// operator elimination rules
55
  UgtEliminate,
56
  UgeEliminate,
57
  SgeEliminate,
58
  SgtEliminate,
59
  RedorEliminate,
60
  RedandEliminate,
61
  SubEliminate,
62
  SltEliminate,
63
  SleEliminate,
64
  UleEliminate,
65
  CompEliminate,
66
  RepeatEliminate,
67
  RotateLeftEliminate,
68
  RotateRightEliminate,
69
  NandEliminate,
70
  NorEliminate,
71
  XnorEliminate,
72
  SdivEliminate,
73
  SdivEliminateFewerBitwiseOps,
74
  UdivEliminate,
75
  SmodEliminate,
76
  SmodEliminateFewerBitwiseOps,
77
  SremEliminate,
78
  SremEliminateFewerBitwiseOps,
79
  ZeroExtendEliminate,
80
  SignExtendEliminate,
81
  BVToNatEliminate,
82
  IntToBVEliminate,
83
84
  /// ground term evaluation
85
  EvalEquals,
86
  EvalConcat,
87
  EvalAnd,
88
  EvalOr,
89
  EvalXor,
90
  EvalNot,
91
  EvalMult,
92
  EvalAdd,
93
  EvalUdiv,
94
  EvalUrem,
95
  EvalShl,
96
  EvalLshr,
97
  EvalAshr,
98
  EvalUlt,
99
  EvalUltBv,
100
  EvalUle,
101
  EvalExtract,
102
  EvalSignExtend,
103
  EvalRotateLeft,
104
  EvalRotateRight,
105
  EvalNeg,
106
  EvalSlt,
107
  EvalSltBv,
108
  EvalSle,
109
  EvalITEBv,
110
  EvalComp,
111
  EvalEagerAtom,
112
113
  /// simplification rules
114
  /// all of these rules decrease formula size
115
  BvIteConstCond,
116
  BvIteEqualChildren,
117
  BvIteConstChildren,
118
  BvIteEqualCond,
119
  BvIteMergeThenIf,
120
  BvIteMergeElseIf,
121
  BvIteMergeThenElse,
122
  BvIteMergeElseElse,
123
  BvComp,
124
  ShlByConst,
125
  LshrByConst,
126
  AshrByConst,
127
  BitwiseIdemp,
128
  AndZero,
129
  AndOne,
130
  AndOrXorConcatPullUp,
131
  NegEliminate,
132
  OrEliminate,
133
  XorEliminate,
134
  OrZero,
135
  OrOne,
136
  XorDuplicate,
137
  XorOne,
138
  XorZero,
139
  BitwiseNotAnd,
140
  BitwiseNotOr,
141
  XorNot,
142
  NotIdemp,
143
  LtSelf,
144
  LteSelf,
145
  UltZero,
146
  UltSelf,
147
  UleZero,
148
  UleSelf,
149
  ZeroUle,
150
  UleMax,
151
  NotUlt,
152
  NotUle,
153
  MultPow2,
154
  MultSlice,
155
  ExtractMultLeadingBit,
156
  NegIdemp,
157
  UdivPow2,
158
  UdivZero,
159
  UdivOne,
160
  UremPow2,
161
  UremOne,
162
  UremSelf,
163
  ShiftZero,
164
  UgtUrem,
165
166
  UltOne,
167
  SltZero,
168
  ZeroUlt,
169
  MergeSignExtend,
170
  SignExtendEqConst,
171
  ZeroExtendEqConst,
172
  SignExtendUltConst,
173
  ZeroExtendUltConst,
174
175
  /// normalization rules
176
  ExtractBitwise,
177
  ExtractNot,
178
  ExtractArith,
179
  ExtractArith2,
180
  ExtractSignExtend,
181
  DoubleNeg,
182
  NegMult,
183
  NegSub,
184
  NegAdd,
185
  NotConcat,
186
  NotAnd,  // not sure why this would help (not done)
187
  NotOr,   // not sure why this would help (not done)
188
  NotXor,  // not sure why this would help (not done)
189
  FlattenAssocCommut,
190
  FlattenAssocCommutNoDuplicates,
191
  AddCombineLikeTerms,
192
  MultSimplify,
193
  MultDistribConst,
194
  MultDistrib,
195
  SolveEq,
196
  BitwiseEq,
197
  AndSimplify,
198
  OrSimplify,
199
  XorSimplify,
200
  BitwiseSlicing,
201
  NormalizeEqAddNeg,
202
  // rules to simplify bitblasting
203
  BBAddNeg,
204
  UltAddOne,
205
  ConcatToMult,
206
  MultSltMult,
207
  BitOfConst,
208
};
209
210
inline std::ostream& operator << (std::ostream& out, RewriteRuleId ruleId) {
211
  switch (ruleId) {
212
  case EmptyRule:           out << "EmptyRule";           return out;
213
  case ConcatFlatten:       out << "ConcatFlatten";       return out;
214
  case ConcatExtractMerge:  out << "ConcatExtractMerge";  return out;
215
  case ConcatConstantMerge: out << "ConcatConstantMerge"; return out;
216
  case AndOrXorConcatPullUp:out << "AndOrXorConcatPullUp";return out;
217
  case NegEliminate: out << "NegEliminate"; return out;
218
  case OrEliminate: out << "OrEliminate"; return out;
219
  case XorEliminate: out << "XorEliminate"; return out;
220
  case ExtractExtract:      out << "ExtractExtract";      return out;
221
  case ExtractWhole:        out << "ExtractWhole";        return out;
222
  case ExtractConcat:       out << "ExtractConcat";       return out;
223
  case ExtractConstant:     out << "ExtractConstant";     return out;
224
  case FailEq:              out << "FailEq";              return out;
225
  case SimplifyEq:          out << "SimplifyEq";          return out;
226
  case ReflexivityEq:       out << "ReflexivityEq";       return out;
227
  case UgtEliminate:        out << "UgtEliminate";        return out;
228
  case SgtEliminate:        out << "SgtEliminate";        return out;
229
  case UgeEliminate:        out << "UgeEliminate";        return out;
230
  case SgeEliminate:        out << "SgeEliminate";        return out;
231
  case RedorEliminate:      out << "RedorEliminate";      return out;
232
  case RedandEliminate:     out << "RedandEliminate";     return out;
233
  case RepeatEliminate:     out << "RepeatEliminate";     return out;
234
  case RotateLeftEliminate: out << "RotateLeftEliminate"; return out;
235
  case RotateRightEliminate:out << "RotateRightEliminate";return out;
236
  case BVToNatEliminate:    out << "BVToNatEliminate";    return out;
237
  case IntToBVEliminate:    out << "IntToBVEliminate";    return out;
238
  case NandEliminate:       out << "NandEliminate";       return out;
239
  case NorEliminate :       out << "NorEliminate";        return out;
240
  case SdivEliminate :      out << "SdivEliminate";       return out;
241
  case SdivEliminateFewerBitwiseOps:
242
    out << "SdivEliminateFewerBitwiseOps";
243
    return out;
244
  case SremEliminate :      out << "SremEliminate";       return out;
245
  case SremEliminateFewerBitwiseOps:
246
    out << "SremEliminateFewerBitwiseOps";
247
    return out;
248
  case SmodEliminate :      out << "SmodEliminate";       return out;
249
  case SmodEliminateFewerBitwiseOps:
250
    out << "SmodEliminateFewerBitwiseOps";
251
    return out;
252
  case ZeroExtendEliminate :out << "ZeroExtendEliminate"; return out;
253
  case EvalEquals :         out << "EvalEquals";          return out;
254
  case EvalConcat :         out << "EvalConcat";          return out;
255
  case EvalAnd :            out << "EvalAnd";             return out;
256
  case EvalOr :             out << "EvalOr";              return out;
257
  case EvalXor :            out << "EvalXor";             return out;
258
  case EvalNot :            out << "EvalNot";             return out;
259
  case EvalMult :           out << "EvalMult";            return out;
260
  case EvalAdd: out << "EvalAdd"; return out;
261
  case EvalUdiv :           out << "EvalUdiv";            return out;
262
  case EvalUrem :           out << "EvalUrem";            return out;
263
  case EvalShl :            out << "EvalShl";             return out;
264
  case EvalLshr :           out << "EvalLshr";            return out;
265
  case EvalAshr :           out << "EvalAshr";            return out;
266
  case EvalUlt :            out << "EvalUlt";             return out;
267
  case EvalUle :            out << "EvalUle";             return out;
268
  case EvalSlt :            out << "EvalSlt";             return out;
269
  case EvalSle :            out << "EvalSle";             return out;
270
  case EvalSltBv:           out << "EvalSltBv";           return out;
271
  case EvalITEBv:           out << "EvalITEBv";           return out;
272
  case EvalComp:            out << "EvalComp";            return out;
273
  case EvalEagerAtom: out << "EvalEagerAtom"; return out;
274
  case EvalExtract :        out << "EvalExtract";         return out;
275
  case EvalSignExtend :     out << "EvalSignExtend";      return out;
276
  case EvalRotateLeft :     out << "EvalRotateLeft";      return out;
277
  case EvalRotateRight :    out << "EvalRotateRight";     return out;
278
  case EvalNeg :            out << "EvalNeg";             return out;
279
  case BvIteConstCond :     out << "BvIteConstCond";      return out;
280
  case BvIteEqualChildren : out << "BvIteEqualChildren";  return out;
281
  case BvIteConstChildren : out << "BvIteConstChildren";  return out;
282
  case BvIteEqualCond :     out << "BvIteEqualCond";      return out;
283
  case BvIteMergeThenIf :   out << "BvIteMergeThenIf";    return out;
284
  case BvIteMergeElseIf :   out << "BvIteMergeElseIf";    return out;
285
  case BvIteMergeThenElse : out << "BvIteMergeThenElse";  return out;
286
  case BvIteMergeElseElse : out << "BvIteMergeElseElse";  return out;
287
  case BvComp :             out << "BvComp";              return out;
288
  case ShlByConst :         out << "ShlByConst";          return out;
289
  case LshrByConst :        out << "LshrByConst";         return out;
290
  case AshrByConst :        out << "AshrByConst";         return out;
291
  case ExtractBitwise :     out << "ExtractBitwise";      return out;
292
  case ExtractNot :         out << "ExtractNot";          return out;
293
  case ExtractArith :       out << "ExtractArith";        return out;
294
  case ExtractArith2 :      out << "ExtractArith2";       return out;
295
  case DoubleNeg :          out << "DoubleNeg";           return out;
296
  case NotConcat :          out << "NotConcat";           return out;
297
  case NotAnd :             out << "NotAnd";              return out;
298
  case NotOr :              out << "NotOr";               return out;
299
  case NotXor :             out << "NotXor";              return out;
300
  case BitwiseIdemp :       out << "BitwiseIdemp";        return out;
301
  case XorDuplicate :       out << "XorDuplicate";        return out;
302
  case BitwiseNotAnd :      out << "BitwiseNotAnd";       return out;
303
  case BitwiseNotOr :       out << "BitwiseNotOr";        return out;
304
  case XorNot :             out << "XorNot";              return out;
305
  case LtSelf :             out << "LtSelf";              return out;
306
  case LteSelf :            out << "LteSelf";             return out;
307
  case UltZero :            out << "UltZero";             return out;
308
  case UleZero :            out << "UleZero";             return out;
309
  case ZeroUle :            out << "ZeroUle";             return out;
310
  case NotUlt :             out << "NotUlt";              return out;
311
  case NotUle :             out << "NotUle";              return out;
312
  case UleMax :             out << "UleMax";              return out;
313
  case SltEliminate :       out << "SltEliminate";        return out;
314
  case SleEliminate :       out << "SleEliminate";        return out;
315
  case AndZero :       out << "AndZero";        return out;
316
  case AndOne :       out << "AndOne";        return out;
317
  case OrZero :       out << "OrZero";        return out;
318
  case OrOne :       out << "OrOne";        return out;
319
  case XorOne :       out << "XorOne";        return out;
320
  case XorZero :       out << "XorZero";        return out;
321
  case MultPow2 :            out << "MultPow2";             return out;
322
  case MultSlice :            out << "MultSlice";             return out;
323
  case ExtractMultLeadingBit :            out << "ExtractMultLeadingBit";             return out;
324
  case NegIdemp :            out << "NegIdemp";             return out;
325
  case UdivPow2 :            out << "UdivPow2";             return out;
326
  case UdivZero:
327
    out << "UdivZero";
328
    return out;
329
  case UdivOne :            out << "UdivOne";             return out;
330
  case UremPow2 :            out << "UremPow2";             return out;
331
  case UremOne :            out << "UremOne";             return out;
332
  case UremSelf :            out << "UremSelf";             return out;
333
  case ShiftZero :            out << "ShiftZero";             return out;
334
  case UgtUrem: out << "UgtUrem"; return out;
335
  case SubEliminate :            out << "SubEliminate";             return out;
336
  case CompEliminate :            out << "CompEliminate";             return out;
337
  case XnorEliminate :            out << "XnorEliminate";             return out;
338
  case SignExtendEliminate :            out << "SignExtendEliminate";             return out;
339
  case NotIdemp :                  out << "NotIdemp"; return out;
340
  case UleSelf:                    out << "UleSelf"; return out;
341
  case FlattenAssocCommut:     out << "FlattenAssocCommut"; return out;
342
  case FlattenAssocCommutNoDuplicates:
343
    out << "FlattenAssocCommutNoDuplicates";
344
    return out;
345
  case AddCombineLikeTerms: out << "AddCombineLikeTerms"; return out;
346
  case MultSimplify: out << "MultSimplify"; return out;
347
  case MultDistribConst: out << "MultDistribConst"; return out;
348
  case SolveEq : out << "SolveEq"; return out;
349
  case BitwiseEq : out << "BitwiseEq"; return out;
350
  case NegMult : out << "NegMult"; return out;
351
  case NegSub : out << "NegSub"; return out;
352
  case AndSimplify : out << "AndSimplify"; return out;
353
  case OrSimplify : out << "OrSimplify"; return out;
354
  case XorSimplify : out << "XorSimplify"; return out;
355
  case NegAdd: out << "NegAdd"; return out;
356
  case BBAddNeg: out << "BBAddNeg"; return out;
357
  case UltOne : out << "UltOne"; return out;
358
  case SltZero : out << "SltZero"; return out;
359
  case ZeroUlt : out << "ZeroUlt"; return out;
360
  case MergeSignExtend : out << "MergeSignExtend"; return out;
361
  case SignExtendEqConst: out << "SignExtendEqConst"; return out;
362
  case ZeroExtendEqConst: out << "ZeroExtendEqConst"; return out;
363
  case SignExtendUltConst: out << "SignExtendUltConst"; return out;
364
  case ZeroExtendUltConst: out << "ZeroExtendUltConst"; return out;
365
366
  case UleEliminate : out << "UleEliminate"; return out;
367
  case BitwiseSlicing : out << "BitwiseSlicing"; return out;
368
  case ExtractSignExtend : out << "ExtractSignExtend"; return out;
369
  case MultDistrib: out << "MultDistrib"; return out;
370
  case UltAddOne: out << "UltAddOne"; return out;
371
  case ConcatToMult: out << "ConcatToMult"; return out;
372
  case MultSltMult: out << "MultSltMult"; return out;
373
  case NormalizeEqAddNeg: out << "NormalizeEqAddNeg"; return out;
374
  case BitOfConst: out << "BitOfConst"; return out;
375
  default:
376
    Unreachable();
377
  }
378
};
379
380
template <RewriteRuleId rule>
381
class RewriteRule {
382
383
  // class RuleStatistics {
384
385
  //   /** The name of the rule prefixed with the prefix */
386
  //   static std::string getStatName(const char* prefix) {
387
  //     std::stringstream statName;
388
  //     statName << prefix << rule;
389
  //     return statName.str();
390
  //   }
391
392
  // public:
393
394
  //   /** Number of applications of this rule */
395
  //   IntStat d_ruleApplications;
396
397
  //   /** Constructor */
398
  //   RuleStatistics()
399
  //   : d_ruleApplications(getStatName("theory::bv::RewriteRules::count"), 0) {
400
  //     currentStatisticsRegistry()->registerStat(&d_ruleApplications);
401
  //   }
402
403
  //   /** Destructor */
404
  //   ~RuleStatistics() {
405
  //     StatisticsRegistry::unregisterStat(&d_ruleApplications);
406
  //   }
407
  // };
408
409
  // /* Statistics about the rule */
410
  // // NOTE: Cannot have static fields like this, or else you can't have
411
  // // two SmtEngines in the process (the second-to-be-destroyed will
412
  // // have a dangling pointer and segfault).  If this statistic is needed,
413
  // // fix the rewriter by making it an instance per-SmtEngine (instead of
414
  // // static).
415
  // static RuleStatistics* s_statistics;
416
417
  /** Actually apply the rewrite rule */
418
  static inline Node apply(TNode node) {
419
    Unreachable();
420
    SuppressWrongNoReturnWarning;
421
  }
422
423
public:
424
425
  RewriteRule() {
426
427
    // if (s_statistics == NULL) {
428
    //   s_statistics = new RuleStatistics();
429
    // }
430
431
  }
432
433
  ~RewriteRule() {
434
435
    // delete s_statistics;
436
    // s_statistics = NULL;
437
438
  }
439
440
  static inline bool applies(TNode node)
441
  {
442
    Unreachable();
443
    SuppressWrongNoReturnWarning;
444
  }
445
446
  template <bool checkApplies>
447
1563076
  static inline Node run(TNode node)
448
  {
449
297219
    if (!checkApplies || applies(node))
450
    {
451
3817743
      Debug("theory::bv::rewrite")
452
2545162
          << "RewriteRule<" << rule << ">(" << node << ")" << std::endl;
453
1272581
      Assert(checkApplies || applies(node));
454
2545162
      Node result = apply(node);
455
2545162
      Debug("theory::bv::rewrite") << "RewriteRule<" << rule << ">(" << node
456
1272581
                                   << ") => " << result << std::endl;
457
1272581
      return result;
458
    }
459
    else
460
    {
461
290495
      return node;
462
    }
463
  }
464
};
465
466
467
 // template<RewriteRuleId rule>
468
 //   typename RewriteRule<rule>::RuleStatistics* RewriteRule<rule>::s_statistics = NULL;
469
470
471
/** Have to list all the rewrite rules to get the statistics out */
472
struct AllRewriteRules {
473
  RewriteRule<EmptyRule>                      rule00;
474
  RewriteRule<ConcatFlatten>                  rule01;
475
  RewriteRule<ConcatExtractMerge>             rule02;
476
  RewriteRule<ConcatConstantMerge>            rule03;
477
  RewriteRule<ExtractExtract>                 rule04;
478
  RewriteRule<ExtractWhole>                   rule05;
479
  RewriteRule<ExtractConcat>                  rule06;
480
  RewriteRule<ExtractConstant>                rule07;
481
  RewriteRule<FailEq>                         rule08;
482
  RewriteRule<SimplifyEq>                     rule09;
483
  RewriteRule<ReflexivityEq>                  rule10;
484
  RewriteRule<UgtEliminate>                   rule11;
485
  RewriteRule<SgtEliminate>                   rule12;
486
  RewriteRule<UgeEliminate>                   rule13;
487
  RewriteRule<SgeEliminate>                   rule14;
488
  RewriteRule<NegMult>                        rule15;
489
  RewriteRule<NegSub>                         rule16;
490
  RewriteRule<RepeatEliminate>                rule17;
491
  RewriteRule<RotateLeftEliminate>            rule18;
492
  RewriteRule<RotateRightEliminate>           rule19;
493
  RewriteRule<NandEliminate>                  rule20;
494
  RewriteRule<NorEliminate>                   rule21;
495
  RewriteRule<SdivEliminate>                  rule22;
496
  RewriteRule<SremEliminate>                  rule23;
497
  RewriteRule<SmodEliminate>                  rule24;
498
  RewriteRule<EvalConcat>                     rule25;
499
  RewriteRule<EvalAnd>                        rule26;
500
  RewriteRule<EvalOr>                         rule27;
501
  RewriteRule<EvalXor>                        rule28;
502
  RewriteRule<EvalNot>                        rule29;
503
  RewriteRule<EvalSlt>                        rule30;
504
  RewriteRule<EvalMult>                       rule31;
505
  RewriteRule<EvalAdd> rule32;
506
  RewriteRule<XorSimplify>                    rule33;
507
  RewriteRule<EvalUdiv>                       rule34;
508
  RewriteRule<EvalUrem>                       rule35;
509
  RewriteRule<EvalShl>                        rule36;
510
  RewriteRule<EvalLshr>                       rule37;
511
  RewriteRule<EvalAshr>                       rule38;
512
  RewriteRule<EvalUlt>                        rule39;
513
  RewriteRule<EvalUle>                        rule40;
514
  RewriteRule<EvalSle>                        rule41;
515
  RewriteRule<EvalExtract>                    rule43;
516
  RewriteRule<EvalSignExtend>                 rule44;
517
  RewriteRule<EvalRotateLeft>                 rule45;
518
  RewriteRule<EvalRotateRight>                rule46;
519
  RewriteRule<EvalEquals>                     rule47;
520
  RewriteRule<EvalNeg>                        rule48;
521
  RewriteRule<ShlByConst>                     rule50;
522
  RewriteRule<LshrByConst>                    rule51;
523
  RewriteRule<AshrByConst>                    rule52;
524
  RewriteRule<ExtractBitwise>                 rule53;
525
  RewriteRule<ExtractNot>                     rule54;
526
  RewriteRule<ExtractArith>                   rule55;
527
  RewriteRule<DoubleNeg>                      rule56;
528
  RewriteRule<NotConcat>                      rule57;
529
  RewriteRule<NotAnd>                         rule58;
530
  RewriteRule<NotOr>                          rule59;
531
  RewriteRule<NotXor>                         rule60;
532
  RewriteRule<BitwiseIdemp>                   rule61;
533
  RewriteRule<XorDuplicate>                   rule62;
534
  RewriteRule<BitwiseNotAnd>                  rule63;
535
  RewriteRule<BitwiseNotOr>                   rule64;
536
  RewriteRule<XorNot>                         rule65;
537
  RewriteRule<LtSelf>                         rule66;
538
  RewriteRule<LtSelf>                         rule67;
539
  RewriteRule<UltZero>                        rule68;
540
  RewriteRule<UleZero>                        rule69;
541
  RewriteRule<ZeroUle>                        rule70;
542
  RewriteRule<NotUlt>                         rule71;
543
  RewriteRule<NotUle>                         rule72;
544
  RewriteRule<ZeroExtendEliminate>            rule73;
545
  RewriteRule<UleMax>                         rule74;
546
  RewriteRule<LteSelf>                        rule75;
547
  RewriteRule<SltEliminate>                   rule76;
548
  RewriteRule<SleEliminate>                   rule77;
549
  RewriteRule<AndZero>                        rule78;
550
  RewriteRule<AndOne>                         rule79;
551
  RewriteRule<OrZero>                         rule80;
552
  RewriteRule<OrOne>                          rule81;
553
  RewriteRule<SubEliminate>                   rule82;
554
  RewriteRule<XorOne>                         rule83;
555
  RewriteRule<XorZero>                        rule84;
556
  RewriteRule<MultSlice>                      rule85;
557
  RewriteRule<FlattenAssocCommutNoDuplicates> rule86;
558
  RewriteRule<MultPow2>                       rule87;
559
  RewriteRule<ExtractMultLeadingBit>          rule88;
560
  RewriteRule<NegIdemp>                       rule91;
561
  RewriteRule<UdivPow2>                       rule92;
562
  RewriteRule<UdivZero>                       rule93;
563
  RewriteRule<UdivOne>                        rule94;
564
  RewriteRule<UremPow2>                       rule95;
565
  RewriteRule<UremOne>                        rule96;
566
  RewriteRule<UremSelf>                       rule97;
567
  RewriteRule<ShiftZero>                      rule98;
568
  RewriteRule<CompEliminate>                  rule99;
569
  RewriteRule<XnorEliminate>                  rule100;
570
  RewriteRule<SignExtendEliminate>            rule101;
571
  RewriteRule<NotIdemp>                       rule102;
572
  RewriteRule<UleSelf>                        rule103;
573
  RewriteRule<FlattenAssocCommut>             rule104;
574
  RewriteRule<AddCombineLikeTerms> rule105;
575
  RewriteRule<MultSimplify>                   rule106;
576
  RewriteRule<MultDistribConst>               rule107;
577
  RewriteRule<AndSimplify>                    rule108;
578
  RewriteRule<OrSimplify>                     rule109;
579
  RewriteRule<NegAdd> rule110;
580
  RewriteRule<BBAddNeg> rule111;
581
  RewriteRule<SolveEq>                        rule112;
582
  RewriteRule<BitwiseEq>                      rule113;
583
  RewriteRule<UltOne>                         rule114;
584
  RewriteRule<SltZero>                        rule115;
585
  RewriteRule<BVToNatEliminate>               rule116;
586
  RewriteRule<IntToBVEliminate>               rule117;
587
  RewriteRule<MultDistrib>                    rule118;
588
  RewriteRule<UltAddOne> rule119;
589
  RewriteRule<ConcatToMult>                   rule120;
590
  RewriteRule<RedorEliminate>                 rule122;
591
  RewriteRule<RedandEliminate>                rule123;
592
  RewriteRule<SignExtendEqConst>              rule124;
593
  RewriteRule<ZeroExtendEqConst>              rule125;
594
  RewriteRule<SignExtendUltConst>             rule126;
595
  RewriteRule<ZeroExtendUltConst>             rule127;
596
  RewriteRule<MultSltMult>                    rule128;
597
  RewriteRule<NormalizeEqAddNeg> rule129;
598
  RewriteRule<BvComp>                         rule130;
599
  RewriteRule<BvIteConstCond>                 rule131;
600
  RewriteRule<BvIteEqualChildren>             rule132;
601
  RewriteRule<BvIteConstChildren>             rule133;
602
  RewriteRule<BvIteEqualCond>                 rule134;
603
  RewriteRule<BvIteMergeThenIf>               rule135;
604
  RewriteRule<BvIteMergeElseIf>               rule136;
605
  RewriteRule<BvIteMergeThenElse>             rule137;
606
  RewriteRule<BvIteMergeElseElse>             rule138;
607
  RewriteRule<AndOrXorConcatPullUp>           rule139;
608
  RewriteRule<NegEliminate> rule140;
609
  RewriteRule<OrEliminate> rule141;
610
  RewriteRule<XorEliminate> rule142;
611
  RewriteRule<SdivEliminate> rule143;
612
  RewriteRule<SremEliminate> rule144;
613
  RewriteRule<SmodEliminate> rule145;
614
  RewriteRule<UgtUrem> rule146;
615
};
616
617
template<> inline
618
38088515
bool RewriteRule<EmptyRule>::applies(TNode node) {
619
38088515
  return false;
620
}
621
622
template<> inline
623
Node RewriteRule<EmptyRule>::apply(TNode node) {
624
  Debug("bv-rewrite") << "RewriteRule<EmptyRule> for " << node.getKind() <<"\n";
625
  Unreachable();
626
  return node;
627
}
628
629
template<Kind kind, RewriteRuleId rule>
630
struct ApplyRuleToChildren {
631
632
91359
  static Node apply(TNode node) {
633
91359
    if (node.getKind() != kind) {
634
25
      return RewriteRule<rule>::template run<true>(node);
635
    }
636
182668
    NodeBuilder result(kind);
637
388344
    for (unsigned i = 0, end = node.getNumChildren(); i < end; ++ i) {
638
297010
      result << RewriteRule<rule>::template run<true>(node[i]);
639
    }
640
91334
    return result;
641
  }
642
643
116157
  static bool applies(TNode node) {
644
116157
    if (node.getKind() == kind) return true;
645
24823
    return RewriteRule<rule>::applies(node);
646
  }
647
648
  template <bool checkApplies>
649
91359
  static Node run(TNode node) {
650
    if (!checkApplies || applies(node)) {
651
91359
      return apply(node);
652
    } else {
653
      return node;
654
    }
655
  }
656
};
657
658
template <
659
  typename R1,
660
  typename R2  = RewriteRule<EmptyRule>,
661
  typename R3  = RewriteRule<EmptyRule>,
662
  typename R4  = RewriteRule<EmptyRule>,
663
  typename R5  = RewriteRule<EmptyRule>,
664
  typename R6  = RewriteRule<EmptyRule>,
665
  typename R7  = RewriteRule<EmptyRule>,
666
  typename R8  = RewriteRule<EmptyRule>,
667
  typename R9  = RewriteRule<EmptyRule>,
668
  typename R10 = RewriteRule<EmptyRule>,
669
  typename R11 = RewriteRule<EmptyRule>,
670
  typename R12 = RewriteRule<EmptyRule>,
671
  typename R13 = RewriteRule<EmptyRule>,
672
  typename R14 = RewriteRule<EmptyRule>,
673
  typename R15 = RewriteRule<EmptyRule>,
674
  typename R16 = RewriteRule<EmptyRule>,
675
  typename R17 = RewriteRule<EmptyRule>,
676
  typename R18 = RewriteRule<EmptyRule>,
677
  typename R19 = RewriteRule<EmptyRule>,
678
  typename R20 = RewriteRule<EmptyRule>
679
  >
680
struct LinearRewriteStrategy {
681
2153629
  static Node apply(TNode node) {
682
2153629
    Node current = node;
683
2153629
    if (R1::applies(current)) current  = R1::template run<false>(current);
684
2153629
    if (R2::applies(current)) current  = R2::template run<false>(current);
685
2153629
    if (R3::applies(current)) current  = R3::template run<false>(current);
686
2153629
    if (R4::applies(current)) current  = R4::template run<false>(current);
687
2153629
    if (R5::applies(current)) current  = R5::template run<false>(current);
688
2153629
    if (R6::applies(current)) current  = R6::template run<false>(current);
689
2153629
    if (R7::applies(current)) current  = R7::template run<false>(current);
690
2153629
    if (R8::applies(current)) current  = R8::template run<false>(current);
691
2153629
    if (R9::applies(current)) current  = R9::template run<false>(current);
692
2153629
    if (R10::applies(current)) current = R10::template run<false>(current);
693
2153629
    if (R11::applies(current)) current = R11::template run<false>(current);
694
2153629
    if (R12::applies(current)) current = R12::template run<false>(current);
695
2153629
    if (R13::applies(current)) current = R13::template run<false>(current);
696
2153629
    if (R14::applies(current)) current = R14::template run<false>(current);
697
2153629
    if (R15::applies(current)) current = R15::template run<false>(current);
698
2153629
    if (R16::applies(current)) current = R16::template run<false>(current);
699
2153629
    if (R17::applies(current)) current = R17::template run<false>(current);
700
2153629
    if (R18::applies(current)) current = R18::template run<false>(current);
701
2153629
    if (R19::applies(current)) current = R19::template run<false>(current);
702
2153629
    if (R20::applies(current)) current = R20::template run<false>(current);
703
2153629
    return current;
704
  }
705
};
706
707
template <
708
  typename R1,
709
  typename R2  = RewriteRule<EmptyRule>,
710
  typename R3  = RewriteRule<EmptyRule>,
711
  typename R4  = RewriteRule<EmptyRule>,
712
  typename R5  = RewriteRule<EmptyRule>,
713
  typename R6  = RewriteRule<EmptyRule>,
714
  typename R7  = RewriteRule<EmptyRule>,
715
  typename R8  = RewriteRule<EmptyRule>,
716
  typename R9  = RewriteRule<EmptyRule>,
717
  typename R10 = RewriteRule<EmptyRule>,
718
  typename R11 = RewriteRule<EmptyRule>,
719
  typename R12 = RewriteRule<EmptyRule>,
720
  typename R13 = RewriteRule<EmptyRule>,
721
  typename R14 = RewriteRule<EmptyRule>,
722
  typename R15 = RewriteRule<EmptyRule>,
723
  typename R16 = RewriteRule<EmptyRule>,
724
  typename R17 = RewriteRule<EmptyRule>,
725
  typename R18 = RewriteRule<EmptyRule>,
726
  typename R19 = RewriteRule<EmptyRule>,
727
  typename R20 = RewriteRule<EmptyRule>
728
  >
729
struct FixpointRewriteStrategy {
730
1074
  static Node apply(TNode node) {
731
2148
    Node previous = node;
732
1074
    Node current = node;
733
42
    do {
734
1116
      previous = current;
735
1116
      if (R1::applies(current)) current  = R1::template run<false>(current);
736
1116
      if (R2::applies(current)) current  = R2::template run<false>(current);
737
1116
      if (R3::applies(current)) current  = R3::template run<false>(current);
738
1116
      if (R4::applies(current)) current  = R4::template run<false>(current);
739
1116
      if (R5::applies(current)) current  = R5::template run<false>(current);
740
1116
      if (R6::applies(current)) current  = R6::template run<false>(current);
741
1116
      if (R7::applies(current)) current  = R7::template run<false>(current);
742
1116
      if (R8::applies(current)) current  = R8::template run<false>(current);
743
1116
      if (R9::applies(current)) current  = R9::template run<false>(current);
744
1116
      if (R10::applies(current)) current = R10::template run<false>(current);
745
1116
      if (R11::applies(current)) current = R11::template run<false>(current);
746
1116
      if (R12::applies(current)) current = R12::template run<false>(current);
747
1116
      if (R13::applies(current)) current = R13::template run<false>(current);
748
1116
      if (R14::applies(current)) current = R14::template run<false>(current);
749
1116
      if (R15::applies(current)) current = R15::template run<false>(current);
750
1116
      if (R16::applies(current)) current = R16::template run<false>(current);
751
1116
      if (R17::applies(current)) current = R17::template run<false>(current);
752
1116
      if (R18::applies(current)) current = R18::template run<false>(current);
753
1116
      if (R19::applies(current)) current = R19::template run<false>(current);
754
1116
      if (R20::applies(current)) current = R20::template run<false>(current);
755
1116
    } while (previous != current);
756
757
2148
    return current;
758
  }
759
};
760
761
762
} // End namespace bv
763
} // End namespace theory
764
}  // End namespace cvc5