@@ -36,8 +36,11 @@ void RewritePath::invert() {
36
36
step.invert ();
37
37
}
38
38
39
- AppliedRewriteStep RewriteStep::apply (MutableTerm &term,
40
- const RewriteSystem &system) const {
39
+ AppliedRewriteStep
40
+ RewriteStep::applyRewriteRule (MutableTerm &term,
41
+ const RewriteSystem &system) const {
42
+ assert (Kind == ApplyRewriteRule);
43
+
41
44
const auto &rule = system.getRule (RuleID);
42
45
43
46
auto lhs = (Inverse ? rule.getRHS () : rule.getLHS ());
@@ -63,21 +66,69 @@ AppliedRewriteStep RewriteStep::apply(MutableTerm &term,
63
66
return {lhs, rhs, prefix, suffix};
64
67
}
65
68
69
+ MutableTerm RewriteStep::applyAdjustment (MutableTerm &term,
70
+ const RewriteSystem &system) const {
71
+ assert (Kind == AdjustConcreteType);
72
+
73
+ auto &ctx = system.getRewriteContext ();
74
+ MutableTerm prefix (term.begin (), term.begin () + Offset);
75
+
76
+ // We're either adding or removing the prefix to each concrete substitution.
77
+ term.back () = term.back ().transformConcreteSubstitutions (
78
+ [&](Term t) -> Term {
79
+ if (Inverse) {
80
+ if (!std::equal (t.begin (),
81
+ t.begin () + Offset,
82
+ prefix.begin ())) {
83
+ llvm::errs () << " Invalid rewrite path\n " ;
84
+ llvm::errs () << " - Term: " << term << " \n " ;
85
+ llvm::errs () << " - Offset: " << Offset << " \n " ;
86
+ llvm::errs () << " - Expected subterm: " << prefix << " \n " ;
87
+ abort ();
88
+ }
89
+
90
+ MutableTerm mutTerm (t.begin () + Offset, t.end ());
91
+ return Term::get (mutTerm, ctx);
92
+ } else {
93
+ MutableTerm mutTerm (prefix);
94
+ mutTerm.append (t);
95
+ return Term::get (mutTerm, ctx);
96
+ }
97
+ }, ctx);
98
+
99
+ return prefix;
100
+ }
101
+
66
102
// / Dumps the rewrite step that was applied to \p term. Mutates \p term to
67
103
// / reflect the application of the rule.
68
104
void RewriteStep::dump (llvm::raw_ostream &out,
69
105
MutableTerm &term,
70
106
const RewriteSystem &system) const {
71
- auto result = apply (term, system);
107
+ switch (Kind) {
108
+ case ApplyRewriteRule: {
109
+ auto result = applyRewriteRule (term, system);
72
110
73
- if (!result.prefix .empty ()) {
74
- out << result.prefix ;
75
- out << " ." ;
111
+ if (!result.prefix .empty ()) {
112
+ out << result.prefix ;
113
+ out << " ." ;
114
+ }
115
+ out << " (" << result.lhs << " => " << result.rhs << " )" ;
116
+ if (!result.suffix .empty ()) {
117
+ out << " ." ;
118
+ out << result.suffix ;
119
+ }
120
+
121
+ break ;
122
+ }
123
+ case AdjustConcreteType: {
124
+ auto result = applyAdjustment (term, system);
125
+
126
+ out << " (σ" ;
127
+ out << (Inverse ? " - " : " + " );
128
+ out << result << " )" ;
129
+
130
+ break ;
76
131
}
77
- out << " (" << result.lhs << " => " << result.rhs << " )" ;
78
- if (!result.suffix .empty ()) {
79
- out << " ." ;
80
- out << result.suffix ;
81
132
}
82
133
}
83
134
@@ -213,7 +264,7 @@ bool RewriteSystem::addRule(MutableTerm lhs, MutableTerm rhs,
213
264
if (path) {
214
265
// We have a rewrite path from the simplified lhs to the simplified rhs;
215
266
// add a rewrite step applying the new rule in reverse to close the loop.
216
- loop.add (RewriteStep (/* offset=*/ 0 , newRuleID, /* inverse=*/ true ));
267
+ loop.add (RewriteStep::forRewriteRule (/* offset=*/ 0 , newRuleID, /* inverse=*/ true ));
217
268
HomotopyGenerators.emplace_back (lhs, loop);
218
269
219
270
if (Debug.contains (DebugFlags::Add)) {
@@ -275,7 +326,8 @@ bool RewriteSystem::simplify(MutableTerm &term, RewritePath *path) const {
275
326
276
327
if (path) {
277
328
unsigned offset = (unsigned )(from - term.begin ());
278
- path->add (RewriteStep (offset, *ruleID, /* inverse=*/ false ));
329
+ path->add (RewriteStep::forRewriteRule (offset, *ruleID,
330
+ /* inverse=*/ false ));
279
331
}
280
332
281
333
changed = true ;
@@ -374,10 +426,12 @@ void RewriteSystem::simplifyRewriteSystem() {
374
426
375
427
// (2) Next, apply the original rule in reverse to produce the
376
428
// original lhs.
377
- loop.add (RewriteStep (/* offset=*/ 0 , ruleID, /* inverse=*/ true ));
429
+ loop.add (RewriteStep::forRewriteRule (/* offset=*/ 0 , ruleID,
430
+ /* inverse=*/ true ));
378
431
379
432
// (3) Finally, apply the new rule to produce the simplified rhs.
380
- loop.add (RewriteStep (/* offset=*/ 0 , newRuleID, /* inverse=*/ false ));
433
+ loop.add (RewriteStep::forRewriteRule (/* offset=*/ 0 , newRuleID,
434
+ /* inverse=*/ false ));
381
435
382
436
if (Debug.contains (DebugFlags::Completion)) {
383
437
llvm::dbgs () << " $ Right hand side simplification recorded a loop: " ;
@@ -456,7 +510,14 @@ void RewriteSystem::verifyHomotopyGenerators() const {
456
510
auto term = loop.first ;
457
511
458
512
for (const auto &step : loop.second ) {
459
- (void ) step.apply (term, *this );
513
+ switch (step.Kind ) {
514
+ case RewriteStep::ApplyRewriteRule:
515
+ (void ) step.applyRewriteRule (term, *this );
516
+ break ;
517
+ case RewriteStep::AdjustConcreteType:
518
+ (void ) step.applyAdjustment (term, *this );
519
+ break ;
520
+ }
460
521
}
461
522
462
523
if (term != loop.first ) {
0 commit comments