GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/bv/theory_bv_rewrite_rules.h Lines: 74 243 30.5 %
Date: 2021-11-07 Branches: 4711 17531 26.9 %

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