@@ -64,17 +64,19 @@ RewriteSystem::getRelation(unsigned index) const {
6464 return Relations[index];
6565}
6666
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,
7073 RewriteSystem &system,
7174 SmallVectorImpl<InducedRule> &inducedRules,
7275 bool debug) {
7376 const auto &lhsRule = system.getRule (lhsRuleID);
74- const auto &rhsRule = system.getRule (rhsRuleID);
75-
7677 auto lhsProperty = lhsRule.getLHS ().back ();
77- auto rhsProperty = rhsRule.getLHS ().back ();
78+
79+ assert (key.size () >= lhsRule.getRHS ().size ());
7880
7981 assert (lhsProperty.isProperty ());
8082 assert (rhsProperty.isProperty ());
@@ -89,35 +91,34 @@ static void recordRelation(unsigned lhsRuleID, unsigned rhsRuleID,
8991
9092 // / Build the following rewrite path:
9193 // /
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 ).
9395 // /
9496 RewritePath path;
9597
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 ));
101104
102- // / T .Relation([p1].[p2] => [p1]).
105+ // / U.V .Relation([p1].[p2] => [p1]).
103106 path.add (RewriteStep::forRelation (relationID, /* inverse=*/ false ));
104107
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 ));
110114
111115 // / 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);
121122}
122123
123124static void recordConflict (Term key,
@@ -446,15 +447,16 @@ void PropertyMap::addProperty(
446447 // the new layout requirement is redundant.
447448 if (mergedLayout == props->Layout ) {
448449 if (checkRulePairOnce (*props->LayoutRule , ruleID)) {
449- recordRelation (*props->LayoutRule , ruleID , System,
450+ recordRelation (key, *props->LayoutRule , property , System,
450451 inducedRules, debug);
451452 }
452453
453454 // If the intersection is equal to the new layout requirement, the
454455 // existing layout requirement is redundant.
455456 } 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,
458460 inducedRules, debug);
459461 }
460462
0 commit comments