@@ -64,17 +64,19 @@ RewriteSystem::getRelation(unsigned index) const {
64
64
return Relations[index];
65
65
}
66
66
67
- // / Given two property rules (T.[p1] => T) and (T.[p2] => T) where [p1] < [p2],
68
- // / record a rewrite loop that makes the second rule redundant from the first.
69
- static void recordRelation (unsigned lhsRuleID, unsigned rhsRuleID,
67
+ // / Given a key T, a rule (V.[p1] => V) where T == U.V, and a property [p2]
68
+ // / where [p1] < [p2], record a rule (T.[p2] => T) that is implied by
69
+ // / the original rule (V.[p1] => V).
70
+ static void recordRelation (Term key,
71
+ unsigned lhsRuleID,
72
+ Symbol rhsProperty,
70
73
RewriteSystem &system,
71
74
SmallVectorImpl<InducedRule> &inducedRules,
72
75
bool debug) {
73
76
const auto &lhsRule = system.getRule (lhsRuleID);
74
- const auto &rhsRule = system.getRule (rhsRuleID);
75
-
76
77
auto lhsProperty = lhsRule.getLHS ().back ();
77
- auto rhsProperty = rhsRule.getLHS ().back ();
78
+
79
+ assert (key.size () >= lhsRule.getRHS ().size ());
78
80
79
81
assert (lhsProperty.isProperty ());
80
82
assert (rhsProperty.isProperty ());
@@ -89,35 +91,34 @@ static void recordRelation(unsigned lhsRuleID, unsigned rhsRuleID,
89
91
90
92
// / Build the following rewrite path:
91
93
// /
92
- // / (T => T .[p1]).[p2] ⊗ T. Relation([p1].[p2] => [p1]) ⊗ (T .[p1] => T ).
94
+ // / U.(V => V .[p1]).[p2] ⊗ U.V. Relation([p1].[p2] => [p1]) ⊗ U.(V .[p1] => V ).
93
95
// /
94
96
RewritePath path;
95
97
96
- // / Starting from T.[p2], the LHS rule in reverse to get T.[p1].[p2].
97
- path.add (RewriteStep::forRewriteRule (/* startOffset=*/ 0 ,
98
- /* endOffset=*/ 1 ,
99
- /* ruleID=*/ lhsRuleID,
100
- /* inverse=*/ true ));
98
+ // / Starting from U.V.[p2], apply the rule in reverse to get U.V.[p1].[p2].
99
+ path.add (RewriteStep::forRewriteRule (
100
+ /* startOffset=*/ key.size () - lhsRule.getRHS ().size (),
101
+ /* endOffset=*/ 1 ,
102
+ /* ruleID=*/ lhsRuleID,
103
+ /* inverse=*/ true ));
101
104
102
- // / T .Relation([p1].[p2] => [p1]).
105
+ // / U.V .Relation([p1].[p2] => [p1]).
103
106
path.add (RewriteStep::forRelation (relationID, /* inverse=*/ false ));
104
107
105
- // / (T.[p1] => T).
106
- path.add (RewriteStep::forRewriteRule (/* startOffset=*/ 0 ,
107
- /* endOffset=*/ 0 ,
108
- /* ruleID=*/ lhsRuleID,
109
- /* inverse=*/ false ));
108
+ // / U.(V.[p1] => V).
109
+ path.add (RewriteStep::forRewriteRule (
110
+ /* startOffset=*/ key.size () - lhsRule.getRHS ().size (),
111
+ /* endOffset=*/ 0 ,
112
+ /* ruleID=*/ lhsRuleID,
113
+ /* inverse=*/ false ));
110
114
111
115
// / Add the rule (T.[p2] => T) with the above rewrite path.
112
- // /
113
- // / Since a rule (T.[p2] => T) *already exists*, both sides of the new
114
- // / rule will simplify down to T, and the rewrite path will become a loop.
115
- // /
116
- // / This loop encodes the fact that (T.[p1] => T) makes (T.[p2] => T)
117
- // / redundant.
118
- inducedRules.emplace_back (MutableTerm (rhsRule.getLHS ()),
119
- MutableTerm (rhsRule.getRHS ()),
120
- path);
116
+ MutableTerm lhs (key);
117
+ lhs.add (rhsProperty);
118
+
119
+ MutableTerm rhs (key);
120
+
121
+ inducedRules.emplace_back (lhs, rhs, path);
121
122
}
122
123
123
124
static void recordConflict (Term key,
@@ -446,15 +447,16 @@ void PropertyMap::addProperty(
446
447
// the new layout requirement is redundant.
447
448
if (mergedLayout == props->Layout ) {
448
449
if (checkRulePairOnce (*props->LayoutRule , ruleID)) {
449
- recordRelation (*props->LayoutRule , ruleID , System,
450
+ recordRelation (key, *props->LayoutRule , property , System,
450
451
inducedRules, debug);
451
452
}
452
453
453
454
// If the intersection is equal to the new layout requirement, the
454
455
// existing layout requirement is redundant.
455
456
} else if (mergedLayout == newLayout) {
456
- if (checkRulePairOnce (*props->LayoutRule , ruleID)) {
457
- recordRelation (ruleID, *props->LayoutRule , System,
457
+ if (checkRulePairOnce (ruleID, *props->LayoutRule )) {
458
+ auto oldProperty = System.getRule (*props->LayoutRule ).getLHS ().back ();
459
+ recordRelation (key, ruleID, oldProperty, System,
458
460
inducedRules, debug);
459
461
}
460
462
0 commit comments