GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/theory_bv_rewrite_rules.h Lines: 74 244 30.3 %
Date: 2021-09-10 Branches: 4708 17542 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
  IsPowerOfTwo,
207
  MultSltMult,
208
  BitOfConst,
209
};
210
211
inline std::ostream& operator << (std::ostream& out, RewriteRuleId ruleId) {
212
  switch (ruleId) {
213
  case EmptyRule:           out << "EmptyRule";           return out;
214
  case ConcatFlatten:       out << "ConcatFlatten";       return out;
215
  case ConcatExtractMerge:  out << "ConcatExtractMerge";  return out;
216
  case ConcatConstantMerge: out << "ConcatConstantMerge"; return out;
217
  case AndOrXorConcatPullUp:out << "AndOrXorConcatPullUp";return out;
218
  case NegEliminate: out << "NegEliminate"; return out;
219
  case OrEliminate: out << "OrEliminate"; return out;
220
  case XorEliminate: out << "XorEliminate"; return out;
221
  case ExtractExtract:      out << "ExtractExtract";      return out;
222
  case ExtractWhole:        out << "ExtractWhole";        return out;
223
  case ExtractConcat:       out << "ExtractConcat";       return out;
224
  case ExtractConstant:     out << "ExtractConstant";     return out;
225
  case FailEq:              out << "FailEq";              return out;
226
  case SimplifyEq:          out << "SimplifyEq";          return out;
227
  case ReflexivityEq:       out << "ReflexivityEq";       return out;
228
  case UgtEliminate:        out << "UgtEliminate";        return out;
229
  case SgtEliminate:        out << "SgtEliminate";        return out;
230
  case UgeEliminate:        out << "UgeEliminate";        return out;
231
  case SgeEliminate:        out << "SgeEliminate";        return out;
232
  case RedorEliminate:      out << "RedorEliminate";      return out;
233
  case RedandEliminate:     out << "RedandEliminate";     return out;
234
  case RepeatEliminate:     out << "RepeatEliminate";     return out;
235
  case RotateLeftEliminate: out << "RotateLeftEliminate"; return out;
236
  case RotateRightEliminate:out << "RotateRightEliminate";return out;
237
  case BVToNatEliminate:    out << "BVToNatEliminate";    return out;
238
  case IntToBVEliminate:    out << "IntToBVEliminate";    return out;
239
  case NandEliminate:       out << "NandEliminate";       return out;
240
  case NorEliminate :       out << "NorEliminate";        return out;
241
  case SdivEliminate :      out << "SdivEliminate";       return out;
242
  case SdivEliminateFewerBitwiseOps:
243
    out << "SdivEliminateFewerBitwiseOps";
244
    return out;
245
  case SremEliminate :      out << "SremEliminate";       return out;
246
  case SremEliminateFewerBitwiseOps:
247
    out << "SremEliminateFewerBitwiseOps";
248
    return out;
249
  case SmodEliminate :      out << "SmodEliminate";       return out;
250
  case SmodEliminateFewerBitwiseOps:
251
    out << "SmodEliminateFewerBitwiseOps";
252
    return out;
253
  case ZeroExtendEliminate :out << "ZeroExtendEliminate"; return out;
254
  case EvalEquals :         out << "EvalEquals";          return out;
255
  case EvalConcat :         out << "EvalConcat";          return out;
256
  case EvalAnd :            out << "EvalAnd";             return out;
257
  case EvalOr :             out << "EvalOr";              return out;
258
  case EvalXor :            out << "EvalXor";             return out;
259
  case EvalNot :            out << "EvalNot";             return out;
260
  case EvalMult :           out << "EvalMult";            return out;
261
  case EvalAdd: out << "EvalAdd"; return out;
262
  case EvalUdiv :           out << "EvalUdiv";            return out;
263
  case EvalUrem :           out << "EvalUrem";            return out;
264
  case EvalShl :            out << "EvalShl";             return out;
265
  case EvalLshr :           out << "EvalLshr";            return out;
266
  case EvalAshr :           out << "EvalAshr";            return out;
267
  case EvalUlt :            out << "EvalUlt";             return out;
268
  case EvalUle :            out << "EvalUle";             return out;
269
  case EvalSlt :            out << "EvalSlt";             return out;
270
  case EvalSle :            out << "EvalSle";             return out;
271
  case EvalSltBv:           out << "EvalSltBv";           return out;
272
  case EvalITEBv:           out << "EvalITEBv";           return out;
273
  case EvalComp:            out << "EvalComp";            return out;
274
  case EvalEagerAtom: out << "EvalEagerAtom"; return out;
275
  case EvalExtract :        out << "EvalExtract";         return out;
276
  case EvalSignExtend :     out << "EvalSignExtend";      return out;
277
  case EvalRotateLeft :     out << "EvalRotateLeft";      return out;
278
  case EvalRotateRight :    out << "EvalRotateRight";     return out;
279
  case EvalNeg :            out << "EvalNeg";             return out;
280
  case BvIteConstCond :     out << "BvIteConstCond";      return out;
281
  case BvIteEqualChildren : out << "BvIteEqualChildren";  return out;
282
  case BvIteConstChildren : out << "BvIteConstChildren";  return out;
283
  case BvIteEqualCond :     out << "BvIteEqualCond";      return out;
284
  case BvIteMergeThenIf :   out << "BvIteMergeThenIf";    return out;
285
  case BvIteMergeElseIf :   out << "BvIteMergeElseIf";    return out;
286
  case BvIteMergeThenElse : out << "BvIteMergeThenElse";  return out;
287
  case BvIteMergeElseElse : out << "BvIteMergeElseElse";  return out;
288
  case BvComp :             out << "BvComp";              return out;
289
  case ShlByConst :         out << "ShlByConst";          return out;
290
  case LshrByConst :        out << "LshrByConst";         return out;
291
  case AshrByConst :        out << "AshrByConst";         return out;
292
  case ExtractBitwise :     out << "ExtractBitwise";      return out;
293
  case ExtractNot :         out << "ExtractNot";          return out;
294
  case ExtractArith :       out << "ExtractArith";        return out;
295
  case ExtractArith2 :      out << "ExtractArith2";       return out;
296
  case DoubleNeg :          out << "DoubleNeg";           return out;
297
  case NotConcat :          out << "NotConcat";           return out;
298
  case NotAnd :             out << "NotAnd";              return out;
299
  case NotOr :              out << "NotOr";               return out;
300
  case NotXor :             out << "NotXor";              return out;
301
  case BitwiseIdemp :       out << "BitwiseIdemp";        return out;
302
  case XorDuplicate :       out << "XorDuplicate";        return out;
303
  case BitwiseNotAnd :      out << "BitwiseNotAnd";       return out;
304
  case BitwiseNotOr :       out << "BitwiseNotOr";        return out;
305
  case XorNot :             out << "XorNot";              return out;
306
  case LtSelf :             out << "LtSelf";              return out;
307
  case LteSelf :            out << "LteSelf";             return out;
308
  case UltZero :            out << "UltZero";             return out;
309
  case UleZero :            out << "UleZero";             return out;
310
  case ZeroUle :            out << "ZeroUle";             return out;
311
  case NotUlt :             out << "NotUlt";              return out;
312
  case NotUle :             out << "NotUle";              return out;
313
  case UleMax :             out << "UleMax";              return out;
314
  case SltEliminate :       out << "SltEliminate";        return out;
315
  case SleEliminate :       out << "SleEliminate";        return out;
316
  case AndZero :       out << "AndZero";        return out;
317
  case AndOne :       out << "AndOne";        return out;
318
  case OrZero :       out << "OrZero";        return out;
319
  case OrOne :       out << "OrOne";        return out;
320
  case XorOne :       out << "XorOne";        return out;
321
  case XorZero :       out << "XorZero";        return out;
322
  case MultPow2 :            out << "MultPow2";             return out;
323
  case MultSlice :            out << "MultSlice";             return out;
324
  case ExtractMultLeadingBit :            out << "ExtractMultLeadingBit";             return out;
325
  case NegIdemp :            out << "NegIdemp";             return out;
326
  case UdivPow2 :            out << "UdivPow2";             return out;
327
  case UdivZero:
328
    out << "UdivZero";
329
    return out;
330
  case UdivOne :            out << "UdivOne";             return out;
331
  case UremPow2 :            out << "UremPow2";             return out;
332
  case UremOne :            out << "UremOne";             return out;
333
  case UremSelf :            out << "UremSelf";             return out;
334
  case ShiftZero :            out << "ShiftZero";             return out;
335
  case UgtUrem: out << "UgtUrem"; return out;
336
  case SubEliminate :            out << "SubEliminate";             return out;
337
  case CompEliminate :            out << "CompEliminate";             return out;
338
  case XnorEliminate :            out << "XnorEliminate";             return out;
339
  case SignExtendEliminate :            out << "SignExtendEliminate";             return out;
340
  case NotIdemp :                  out << "NotIdemp"; return out;
341
  case UleSelf:                    out << "UleSelf"; return out;
342
  case FlattenAssocCommut:     out << "FlattenAssocCommut"; return out;
343
  case FlattenAssocCommutNoDuplicates:
344
    out << "FlattenAssocCommutNoDuplicates";
345
    return out;
346
  case AddCombineLikeTerms: out << "AddCombineLikeTerms"; return out;
347
  case MultSimplify: out << "MultSimplify"; return out;
348
  case MultDistribConst: out << "MultDistribConst"; return out;
349
  case SolveEq : out << "SolveEq"; return out;
350
  case BitwiseEq : out << "BitwiseEq"; return out;
351
  case NegMult : out << "NegMult"; return out;
352
  case NegSub : out << "NegSub"; return out;
353
  case AndSimplify : out << "AndSimplify"; return out;
354
  case OrSimplify : out << "OrSimplify"; return out;
355
  case XorSimplify : out << "XorSimplify"; return out;
356
  case NegAdd: out << "NegAdd"; return out;
357
  case BBAddNeg: out << "BBAddNeg"; return out;
358
  case UltOne : out << "UltOne"; return out;
359
  case SltZero : out << "SltZero"; return out;
360
  case ZeroUlt : out << "ZeroUlt"; return out;
361
  case MergeSignExtend : out << "MergeSignExtend"; return out;
362
  case SignExtendEqConst: out << "SignExtendEqConst"; return out;
363
  case ZeroExtendEqConst: out << "ZeroExtendEqConst"; return out;
364
  case SignExtendUltConst: out << "SignExtendUltConst"; return out;
365
  case ZeroExtendUltConst: out << "ZeroExtendUltConst"; return out;
366
367
  case UleEliminate : out << "UleEliminate"; return out;
368
  case BitwiseSlicing : out << "BitwiseSlicing"; return out;
369
  case ExtractSignExtend : out << "ExtractSignExtend"; return out;
370
  case MultDistrib: out << "MultDistrib"; return out;
371
  case UltAddOne: out << "UltAddOne"; return out;
372
  case ConcatToMult: out << "ConcatToMult"; return out;
373
  case IsPowerOfTwo: out << "IsPowerOfTwo"; return out;
374
  case MultSltMult: out << "MultSltMult"; return out;
375
  case NormalizeEqAddNeg: out << "NormalizeEqAddNeg"; return out;
376
  case BitOfConst: out << "BitOfConst"; return out;
377
  default:
378
    Unreachable();
379
  }
380
};
381
382
template <RewriteRuleId rule>
383
class RewriteRule {
384
385
  // class RuleStatistics {
386
387
  //   /** The name of the rule prefixed with the prefix */
388
  //   static std::string getStatName(const char* prefix) {
389
  //     std::stringstream statName;
390
  //     statName << prefix << rule;
391
  //     return statName.str();
392
  //   }
393
394
  // public:
395
396
  //   /** Number of applications of this rule */
397
  //   IntStat d_ruleApplications;
398
399
  //   /** Constructor */
400
  //   RuleStatistics()
401
  //   : d_ruleApplications(getStatName("theory::bv::RewriteRules::count"), 0) {
402
  //     currentStatisticsRegistry()->registerStat(&d_ruleApplications);
403
  //   }
404
405
  //   /** Destructor */
406
  //   ~RuleStatistics() {
407
  //     StatisticsRegistry::unregisterStat(&d_ruleApplications);
408
  //   }
409
  // };
410
411
  // /* Statistics about the rule */
412
  // // NOTE: Cannot have static fields like this, or else you can't have
413
  // // two SmtEngines in the process (the second-to-be-destroyed will
414
  // // have a dangling pointer and segfault).  If this statistic is needed,
415
  // // fix the rewriter by making it an instance per-SmtEngine (instead of
416
  // // static).
417
  // static RuleStatistics* s_statistics;
418
419
  /** Actually apply the rewrite rule */
420
  static inline Node apply(TNode node) {
421
    Unreachable();
422
    SuppressWrongNoReturnWarning;
423
  }
424
425
public:
426
427
  RewriteRule() {
428
429
    // if (s_statistics == NULL) {
430
    //   s_statistics = new RuleStatistics();
431
    // }
432
433
  }
434
435
  ~RewriteRule() {
436
437
    // delete s_statistics;
438
    // s_statistics = NULL;
439
440
  }
441
442
  static inline bool applies(TNode node)
443
  {
444
    Unreachable();
445
    SuppressWrongNoReturnWarning;
446
  }
447
448
  template <bool checkApplies>
449
2153476
  static inline Node run(TNode node)
450
  {
451
488747
    if (!checkApplies || applies(node))
452
    {
453
5025813
      Debug("theory::bv::rewrite")
454
3350542
          << "RewriteRule<" << rule << ">(" << node << ")" << std::endl;
455
1675271
      Assert(checkApplies || applies(node));
456
3350542
      Node result = apply(node);
457
3350542
      Debug("theory::bv::rewrite") << "RewriteRule<" << rule << ">(" << node
458
1675271
                                   << ") => " << result << std::endl;
459
1675271
      return result;
460
    }
461
    else
462
    {
463
478205
      return node;
464
    }
465
  }
466
};
467
468
469
 // template<RewriteRuleId rule>
470
 //   typename RewriteRule<rule>::RuleStatistics* RewriteRule<rule>::s_statistics = NULL;
471
472
473
/** Have to list all the rewrite rules to get the statistics out */
474
struct AllRewriteRules {
475
  RewriteRule<EmptyRule>                      rule00;
476
  RewriteRule<ConcatFlatten>                  rule01;
477
  RewriteRule<ConcatExtractMerge>             rule02;
478
  RewriteRule<ConcatConstantMerge>            rule03;
479
  RewriteRule<ExtractExtract>                 rule04;
480
  RewriteRule<ExtractWhole>                   rule05;
481
  RewriteRule<ExtractConcat>                  rule06;
482
  RewriteRule<ExtractConstant>                rule07;
483
  RewriteRule<FailEq>                         rule08;
484
  RewriteRule<SimplifyEq>                     rule09;
485
  RewriteRule<ReflexivityEq>                  rule10;
486
  RewriteRule<UgtEliminate>                   rule11;
487
  RewriteRule<SgtEliminate>                   rule12;
488
  RewriteRule<UgeEliminate>                   rule13;
489
  RewriteRule<SgeEliminate>                   rule14;
490
  RewriteRule<NegMult>                        rule15;
491
  RewriteRule<NegSub>                         rule16;
492
  RewriteRule<RepeatEliminate>                rule17;
493
  RewriteRule<RotateLeftEliminate>            rule18;
494
  RewriteRule<RotateRightEliminate>           rule19;
495
  RewriteRule<NandEliminate>                  rule20;
496
  RewriteRule<NorEliminate>                   rule21;
497
  RewriteRule<SdivEliminate>                  rule22;
498
  RewriteRule<SremEliminate>                  rule23;
499
  RewriteRule<SmodEliminate>                  rule24;
500
  RewriteRule<EvalConcat>                     rule25;
501
  RewriteRule<EvalAnd>                        rule26;
502
  RewriteRule<EvalOr>                         rule27;
503
  RewriteRule<EvalXor>                        rule28;
504
  RewriteRule<EvalNot>                        rule29;
505
  RewriteRule<EvalSlt>                        rule30;
506
  RewriteRule<EvalMult>                       rule31;
507
  RewriteRule<EvalAdd> rule32;
508
  RewriteRule<XorSimplify>                    rule33;
509
  RewriteRule<EvalUdiv>                       rule34;
510
  RewriteRule<EvalUrem>                       rule35;
511
  RewriteRule<EvalShl>                        rule36;
512
  RewriteRule<EvalLshr>                       rule37;
513
  RewriteRule<EvalAshr>                       rule38;
514
  RewriteRule<EvalUlt>                        rule39;
515
  RewriteRule<EvalUle>                        rule40;
516
  RewriteRule<EvalSle>                        rule41;
517
  RewriteRule<EvalExtract>                    rule43;
518
  RewriteRule<EvalSignExtend>                 rule44;
519
  RewriteRule<EvalRotateLeft>                 rule45;
520
  RewriteRule<EvalRotateRight>                rule46;
521
  RewriteRule<EvalEquals>                     rule47;
522
  RewriteRule<EvalNeg>                        rule48;
523
  RewriteRule<ShlByConst>                     rule50;
524
  RewriteRule<LshrByConst>                    rule51;
525
  RewriteRule<AshrByConst>                    rule52;
526
  RewriteRule<ExtractBitwise>                 rule53;
527
  RewriteRule<ExtractNot>                     rule54;
528
  RewriteRule<ExtractArith>                   rule55;
529
  RewriteRule<DoubleNeg>                      rule56;
530
  RewriteRule<NotConcat>                      rule57;
531
  RewriteRule<NotAnd>                         rule58;
532
  RewriteRule<NotOr>                          rule59;
533
  RewriteRule<NotXor>                         rule60;
534
  RewriteRule<BitwiseIdemp>                   rule61;
535
  RewriteRule<XorDuplicate>                   rule62;
536
  RewriteRule<BitwiseNotAnd>                  rule63;
537
  RewriteRule<BitwiseNotOr>                   rule64;
538
  RewriteRule<XorNot>                         rule65;
539
  RewriteRule<LtSelf>                         rule66;
540
  RewriteRule<LtSelf>                         rule67;
541
  RewriteRule<UltZero>                        rule68;
542
  RewriteRule<UleZero>                        rule69;
543
  RewriteRule<ZeroUle>                        rule70;
544
  RewriteRule<NotUlt>                         rule71;
545
  RewriteRule<NotUle>                         rule72;
546
  RewriteRule<ZeroExtendEliminate>            rule73;
547
  RewriteRule<UleMax>                         rule74;
548
  RewriteRule<LteSelf>                        rule75;
549
  RewriteRule<SltEliminate>                   rule76;
550
  RewriteRule<SleEliminate>                   rule77;
551
  RewriteRule<AndZero>                        rule78;
552
  RewriteRule<AndOne>                         rule79;
553
  RewriteRule<OrZero>                         rule80;
554
  RewriteRule<OrOne>                          rule81;
555
  RewriteRule<SubEliminate>                   rule82;
556
  RewriteRule<XorOne>                         rule83;
557
  RewriteRule<XorZero>                        rule84;
558
  RewriteRule<MultSlice>                      rule85;
559
  RewriteRule<FlattenAssocCommutNoDuplicates> rule86;
560
  RewriteRule<MultPow2>                       rule87;
561
  RewriteRule<ExtractMultLeadingBit>          rule88;
562
  RewriteRule<NegIdemp>                       rule91;
563
  RewriteRule<UdivPow2>                       rule92;
564
  RewriteRule<UdivZero>                       rule93;
565
  RewriteRule<UdivOne>                        rule94;
566
  RewriteRule<UremPow2>                       rule95;
567
  RewriteRule<UremOne>                        rule96;
568
  RewriteRule<UremSelf>                       rule97;
569
  RewriteRule<ShiftZero>                      rule98;
570
  RewriteRule<CompEliminate>                  rule99;
571
  RewriteRule<XnorEliminate>                  rule100;
572
  RewriteRule<SignExtendEliminate>            rule101;
573
  RewriteRule<NotIdemp>                       rule102;
574
  RewriteRule<UleSelf>                        rule103;
575
  RewriteRule<FlattenAssocCommut>             rule104;
576
  RewriteRule<AddCombineLikeTerms> rule105;
577
  RewriteRule<MultSimplify>                   rule106;
578
  RewriteRule<MultDistribConst>               rule107;
579
  RewriteRule<AndSimplify>                    rule108;
580
  RewriteRule<OrSimplify>                     rule109;
581
  RewriteRule<NegAdd> rule110;
582
  RewriteRule<BBAddNeg> rule111;
583
  RewriteRule<SolveEq>                        rule112;
584
  RewriteRule<BitwiseEq>                      rule113;
585
  RewriteRule<UltOne>                         rule114;
586
  RewriteRule<SltZero>                        rule115;
587
  RewriteRule<BVToNatEliminate>               rule116;
588
  RewriteRule<IntToBVEliminate>               rule117;
589
  RewriteRule<MultDistrib>                    rule118;
590
  RewriteRule<UltAddOne> rule119;
591
  RewriteRule<ConcatToMult>                   rule120;
592
  RewriteRule<IsPowerOfTwo>                   rule121;
593
  RewriteRule<RedorEliminate>                 rule122;
594
  RewriteRule<RedandEliminate>                rule123;
595
  RewriteRule<SignExtendEqConst>              rule124;
596
  RewriteRule<ZeroExtendEqConst>              rule125;
597
  RewriteRule<SignExtendUltConst>             rule126;
598
  RewriteRule<ZeroExtendUltConst>             rule127;
599
  RewriteRule<MultSltMult>                    rule128;
600
  RewriteRule<NormalizeEqAddNeg> rule129;
601
  RewriteRule<BvComp>                         rule130;
602
  RewriteRule<BvIteConstCond>                 rule131;
603
  RewriteRule<BvIteEqualChildren>             rule132;
604
  RewriteRule<BvIteConstChildren>             rule133;
605
  RewriteRule<BvIteEqualCond>                 rule134;
606
  RewriteRule<BvIteMergeThenIf>               rule135;
607
  RewriteRule<BvIteMergeElseIf>               rule136;
608
  RewriteRule<BvIteMergeThenElse>             rule137;
609
  RewriteRule<BvIteMergeElseElse>             rule138;
610
  RewriteRule<AndOrXorConcatPullUp>           rule139;
611
  RewriteRule<NegEliminate> rule140;
612
  RewriteRule<OrEliminate> rule141;
613
  RewriteRule<XorEliminate> rule142;
614
  RewriteRule<SdivEliminate> rule143;
615
  RewriteRule<SremEliminate> rule144;
616
  RewriteRule<SmodEliminate> rule145;
617
  RewriteRule<UgtUrem> rule146;
618
};
619
620
template<> inline
621
51474609
bool RewriteRule<EmptyRule>::applies(TNode node) {
622
51474609
  return false;
623
}
624
625
template<> inline
626
Node RewriteRule<EmptyRule>::apply(TNode node) {
627
  Debug("bv-rewrite") << "RewriteRule<EmptyRule> for " << node.getKind() <<"\n";
628
  Unreachable();
629
  return node;
630
}
631
632
template<Kind kind, RewriteRuleId rule>
633
struct ApplyRuleToChildren {
634
635
141037
  static Node apply(TNode node) {
636
141037
    if (node.getKind() != kind) {
637
33
      return RewriteRule<rule>::template run<true>(node);
638
    }
639
282008
    NodeBuilder result(kind);
640
629534
    for (unsigned i = 0, end = node.getNumChildren(); i < end; ++ i) {
641
488530
      result << RewriteRule<rule>::template run<true>(node[i]);
642
    }
643
141004
    return result;
644
  }
645
646
168073
  static bool applies(TNode node) {
647
168073
    if (node.getKind() == kind) return true;
648
27069
    return RewriteRule<rule>::applies(node);
649
  }
650
651
  template <bool checkApplies>
652
141037
  static Node run(TNode node) {
653
    if (!checkApplies || applies(node)) {
654
141037
      return apply(node);
655
    } else {
656
      return node;
657
    }
658
  }
659
};
660
661
template <
662
  typename R1,
663
  typename R2  = RewriteRule<EmptyRule>,
664
  typename R3  = RewriteRule<EmptyRule>,
665
  typename R4  = RewriteRule<EmptyRule>,
666
  typename R5  = RewriteRule<EmptyRule>,
667
  typename R6  = RewriteRule<EmptyRule>,
668
  typename R7  = RewriteRule<EmptyRule>,
669
  typename R8  = RewriteRule<EmptyRule>,
670
  typename R9  = RewriteRule<EmptyRule>,
671
  typename R10 = RewriteRule<EmptyRule>,
672
  typename R11 = RewriteRule<EmptyRule>,
673
  typename R12 = RewriteRule<EmptyRule>,
674
  typename R13 = RewriteRule<EmptyRule>,
675
  typename R14 = RewriteRule<EmptyRule>,
676
  typename R15 = RewriteRule<EmptyRule>,
677
  typename R16 = RewriteRule<EmptyRule>,
678
  typename R17 = RewriteRule<EmptyRule>,
679
  typename R18 = RewriteRule<EmptyRule>,
680
  typename R19 = RewriteRule<EmptyRule>,
681
  typename R20 = RewriteRule<EmptyRule>
682
  >
683
struct LinearRewriteStrategy {
684
2905268
  static Node apply(TNode node) {
685
2905268
    Node current = node;
686
2905268
    if (R1::applies(current)) current  = R1::template run<false>(current);
687
2905268
    if (R2::applies(current)) current  = R2::template run<false>(current);
688
2905268
    if (R3::applies(current)) current  = R3::template run<false>(current);
689
2905268
    if (R4::applies(current)) current  = R4::template run<false>(current);
690
2905268
    if (R5::applies(current)) current  = R5::template run<false>(current);
691
2905268
    if (R6::applies(current)) current  = R6::template run<false>(current);
692
2905268
    if (R7::applies(current)) current  = R7::template run<false>(current);
693
2905268
    if (R8::applies(current)) current  = R8::template run<false>(current);
694
2905268
    if (R9::applies(current)) current  = R9::template run<false>(current);
695
2905268
    if (R10::applies(current)) current = R10::template run<false>(current);
696
2905268
    if (R11::applies(current)) current = R11::template run<false>(current);
697
2905268
    if (R12::applies(current)) current = R12::template run<false>(current);
698
2905268
    if (R13::applies(current)) current = R13::template run<false>(current);
699
2905268
    if (R14::applies(current)) current = R14::template run<false>(current);
700
2905268
    if (R15::applies(current)) current = R15::template run<false>(current);
701
2905268
    if (R16::applies(current)) current = R16::template run<false>(current);
702
2905268
    if (R17::applies(current)) current = R17::template run<false>(current);
703
2905268
    if (R18::applies(current)) current = R18::template run<false>(current);
704
2905268
    if (R19::applies(current)) current = R19::template run<false>(current);
705
2905268
    if (R20::applies(current)) current = R20::template run<false>(current);
706
2905268
    return current;
707
  }
708
};
709
710
template <
711
  typename R1,
712
  typename R2  = RewriteRule<EmptyRule>,
713
  typename R3  = RewriteRule<EmptyRule>,
714
  typename R4  = RewriteRule<EmptyRule>,
715
  typename R5  = RewriteRule<EmptyRule>,
716
  typename R6  = RewriteRule<EmptyRule>,
717
  typename R7  = RewriteRule<EmptyRule>,
718
  typename R8  = RewriteRule<EmptyRule>,
719
  typename R9  = RewriteRule<EmptyRule>,
720
  typename R10 = RewriteRule<EmptyRule>,
721
  typename R11 = RewriteRule<EmptyRule>,
722
  typename R12 = RewriteRule<EmptyRule>,
723
  typename R13 = RewriteRule<EmptyRule>,
724
  typename R14 = RewriteRule<EmptyRule>,
725
  typename R15 = RewriteRule<EmptyRule>,
726
  typename R16 = RewriteRule<EmptyRule>,
727
  typename R17 = RewriteRule<EmptyRule>,
728
  typename R18 = RewriteRule<EmptyRule>,
729
  typename R19 = RewriteRule<EmptyRule>,
730
  typename R20 = RewriteRule<EmptyRule>
731
  >
732
struct FixpointRewriteStrategy {
733
2236
  static Node apply(TNode node) {
734
4472
    Node previous = node;
735
2236
    Node current = node;
736
65
    do {
737
2301
      previous = current;
738
2301
      if (R1::applies(current)) current  = R1::template run<false>(current);
739
2301
      if (R2::applies(current)) current  = R2::template run<false>(current);
740
2301
      if (R3::applies(current)) current  = R3::template run<false>(current);
741
2301
      if (R4::applies(current)) current  = R4::template run<false>(current);
742
2301
      if (R5::applies(current)) current  = R5::template run<false>(current);
743
2301
      if (R6::applies(current)) current  = R6::template run<false>(current);
744
2301
      if (R7::applies(current)) current  = R7::template run<false>(current);
745
2301
      if (R8::applies(current)) current  = R8::template run<false>(current);
746
2301
      if (R9::applies(current)) current  = R9::template run<false>(current);
747
2301
      if (R10::applies(current)) current = R10::template run<false>(current);
748
2301
      if (R11::applies(current)) current = R11::template run<false>(current);
749
2301
      if (R12::applies(current)) current = R12::template run<false>(current);
750
2301
      if (R13::applies(current)) current = R13::template run<false>(current);
751
2301
      if (R14::applies(current)) current = R14::template run<false>(current);
752
2301
      if (R15::applies(current)) current = R15::template run<false>(current);
753
2301
      if (R16::applies(current)) current = R16::template run<false>(current);
754
2301
      if (R17::applies(current)) current = R17::template run<false>(current);
755
2301
      if (R18::applies(current)) current = R18::template run<false>(current);
756
2301
      if (R19::applies(current)) current = R19::template run<false>(current);
757
2301
      if (R20::applies(current)) current = R20::template run<false>(current);
758
2301
    } while (previous != current);
759
760
4472
    return current;
761
  }
762
};
763
764
765
} // End namespace bv
766
} // End namespace theory
767
}  // End namespace cvc5