Skip to content

Commit a11151a

Browse files
committed
RequirementMachine: Fix up some comments
1 parent 3790bba commit a11151a

File tree

6 files changed

+89
-16
lines changed

6 files changed

+89
-16
lines changed

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
//
2222
// Redundant rules that are not part of the minimal set are redundant are
2323
// detected by analyzing the set of rewrite loops computed by the completion
24-
// procedure.
24+
// procedure. See RewriteLoop.cpp for a discussion of rewrite loops.
2525
//
2626
// If a rewrite rule appears exactly once in a loop and without context, the
2727
// loop witnesses a redundancy; the rewrite rule is equivalent to traveling

lib/AST/RequirementMachine/KnuthBendix.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
// pair to the other. This can introduce more overlaps with existing rules, and
2424
// the process iterates until fixed point.
2525
//
26+
// When completion records a new rewrite rule, it also constructs a rewrite loop
27+
// describing how this rule is derived from existing rules. See RewriteLoop.cpp
28+
// for a discussion of rewrite loops.
29+
//
2630
// This implementation also extends Knuth-Bendix to introduce new _generators_,
2731
// in addition to new relations as in the standard algorithm. See the comment at
2832
// the top of RewriteSystem::processMergedAssociatedTypes() for a description.

lib/AST/RequirementMachine/PropertyMap.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ PropertyMap::~PropertyMap() {
237237

238238
/// Look for a property bag corresponding to a suffix of the given range.
239239
///
240+
/// The symbol range must correspond to a term that has already been
241+
/// simplified.
242+
///
240243
/// Returns nullptr if no information is known about this key.
241244
PropertyBag *
242245
PropertyMap::lookUpProperties(std::reverse_iterator<const Symbol *> begin,
@@ -249,6 +252,8 @@ PropertyMap::lookUpProperties(std::reverse_iterator<const Symbol *> begin,
249252

250253
/// Look for a property bag corresponding to a suffix of the given key.
251254
///
255+
/// The term must have already been simplified.
256+
///
252257
/// Returns nullptr if no information is known about this key.
253258
PropertyBag *
254259
PropertyMap::lookUpProperties(const MutableTerm &key) const {

lib/AST/RequirementMachine/RewriteLoop.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,52 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines data types used for representing redundancies among
14+
// rewrite rules. The information encoded in these types is ultimately used
15+
// for generic signature minimization.
16+
//
17+
// A RewriteStep is a single primitive transformation; the canonical example is
18+
// the application of a rewrite rule, possibly to a subterm.
19+
//
20+
// A RewritePath is a composition of RewriteSteps describing the transformation
21+
// of a term into another term. One place where a RewritePath originates is
22+
// RewriteSystem::simplify(); that method takes an optional RewritePath argument
23+
// to which the series of RewriteSteps performed during simplification are
24+
// appended. If the term was already canonical, the resulting path is empty,
25+
// otherwise it will consist of at least one RewriteStep.
26+
//
27+
// Simplification always applies rules by replacing a subterm equal to the LHS
28+
// with the RHS where LHS > RHS, so the RewriteSteps constructed there always
29+
// make the term shorter. However, more generally, RewriteSteps can also
30+
// express the inverse rewrite, where RHS is replaced with LHS, making the term
31+
// longer.
32+
//
33+
// Inverted RewriteSteps are constructed in the Knuth-Bendix completion
34+
// algorithm. A simple example is where two rules (U.V => X) and (V.W => Y)
35+
// overlap on the term U.V.W. Then the induced rule (X.W => U.Y) (assuming that
36+
// X.W > U.Y) can be described by a RewritePath which begins at X.W, applies
37+
// the inverted rule (X => U.V) to the subterm X to obtain U.V.W, then applies
38+
// the rule (V.W => Y) to the subterm V.W to obtain U.Y.
39+
//
40+
// A RewriteLoop is a path that begins and ends at the same term. A RewriteLoop
41+
// describes a _redundancy_. For example, when completion adds a new rule to
42+
// resolve an overlap, it constructs a RewritePath describing this new rule in
43+
// terms of existing rules; by adding an additional rewrite step corresponding
44+
// to the new rule, we get a loop that begins and ends at the same point, or in
45+
// other words, a RewriteLoop.
46+
//
47+
// In the above example, we have a RewritePath from X.W to U.Y via the two
48+
// existing rewrite rules with the overlap term U.V.W in the middle. If we then
49+
// add a third rewrite step for the new rule inverted, (U.Y => X.W), we get a
50+
// loop that begins and ends at X.W. This loop encodes that the new rule
51+
// (X.W => U.Y) is redundant because it can be expresed in terms of other rules.
52+
//
53+
// The homotopy reduction algorithm in HomotopyReduction.cpp uses rewrite loops
54+
// to find a minimal set of rewrite rules, which are then used to construct a
55+
// minimal generic signature.
56+
//
57+
//===----------------------------------------------------------------------===//
1258

1359
#include "swift/AST/Type.h"
1460
#include "llvm/Support/raw_ostream.h"

lib/AST/RequirementMachine/RewriteLoop.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,24 @@ struct RewriteStep {
7373
Shift,
7474

7575
/// If not inverted: the top of the primary stack must be a term ending
76-
/// with a superclass or concrete type symbol. Each concrete substitution
77-
/// in the term is pushed onto the primary stack.
76+
/// with a superclass or concrete type symbol:
7877
///
79-
/// If inverted: pop concrete substitutions from the primary stack, which
80-
/// must follow a term ending with a superclass or concrete type symbol.
81-
/// The new substitutions replace the substitutions in that symbol.
78+
/// T.[concrete: C<...> with <X1, X2...>]
79+
///
80+
/// Each concrete substitution Xn is pushed onto the primary stack,
81+
/// producing:
82+
///
83+
/// T.[concrete: C<...> with <X1, X2...>] X1 X2...
84+
///
85+
/// If inverted: pop concrete substitutions Xn' from the primary stack,
86+
/// which must follow a term ending with a superclass or concrete type
87+
/// symbol:
88+
///
89+
/// T.[concrete: C<...> with <X1, X2...>] X1' X2'...
90+
///
91+
/// The new substitutions replace the substitutions in that symbol:
92+
///
93+
/// T.[concrete: C<...> with <X1', X2'...>]
8294
///
8395
/// The Arg field encodes the number of substitutions.
8496
Decompose,
@@ -301,7 +313,8 @@ struct AppliedRewriteStep {
301313

302314
/// A rewrite path is a list of instructions for a two-stack interpreter.
303315
///
304-
/// - Shift moves a term from A to B (if not inverted) or B to A (if inverted).
316+
/// - Shift moves a term from the primary stack to the secondary stack
317+
/// (if not inverted) or secondary to primary (if inverted).
305318
///
306319
/// - Decompose splits off the substitutions from a superclass or concrete type
307320
/// symbol at the top of the primary stack (if not inverted) or assembles a

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ bool RewriteSystem::simplifySubstitutions(Symbol &symbol,
263263
RewritePath *path) const {
264264
assert(symbol.hasSubstitutions());
265265

266+
// Fast path if the type is fully concrete.
266267
auto substitutions = symbol.getSubstitutions();
267268
if (substitutions.empty())
268269
return false;
@@ -272,10 +273,12 @@ bool RewriteSystem::simplifySubstitutions(Symbol &symbol,
272273
unsigned oldSize = (path ? path->size() : 0);
273274

274275
if (path) {
275-
// The term is on the A stack. Push all substitutions onto the A stack.
276-
path->add(RewriteStep::forDecompose(substitutions.size(), /*inverse=*/false));
276+
// The term is at the top of the primary stack. Push all substitutions onto
277+
// the primary stack.
278+
path->add(RewriteStep::forDecompose(substitutions.size(),
279+
/*inverse=*/false));
277280

278-
// Move all substitutions but the first one to the B stack.
281+
// Move all substitutions but the first one to the secondary stack.
279282
for (unsigned i = 1; i < substitutions.size(); ++i)
280283
path->add(RewriteStep::forShift(/*inverse=*/false));
281284
}
@@ -287,23 +290,25 @@ bool RewriteSystem::simplifySubstitutions(Symbol &symbol,
287290
bool first = true;
288291
bool anyChanged = false;
289292
for (auto substitution : substitutions) {
290-
// Move the next substitution from the B stack to the A stack.
293+
// Move the next substitution from the secondary stack to the primary stack.
291294
if (!first && path)
292295
path->add(RewriteStep::forShift(/*inverse=*/true));
293296
first = false;
294297

295-
// The current substitution is at the top of the A stack; simplify it.
298+
// The current substitution is at the top of the primary stack; simplify it.
296299
MutableTerm mutTerm(substitution);
297300
anyChanged |= simplify(mutTerm, path);
298301

299302
// Record the new substitution.
300303
newSubstitutions.push_back(Term::get(mutTerm, Context));
301304
}
302305

303-
// All simplified substitutions are now on the A stack. Collect them to
306+
// All simplified substitutions are now on the primary stack. Collect them to
304307
// produce the new term.
305-
if (path)
306-
path->add(RewriteStep::forDecompose(substitutions.size(), /*inverse=*/true));
308+
if (path) {
309+
path->add(RewriteStep::forDecompose(substitutions.size(),
310+
/*inverse=*/true));
311+
}
307312

308313
// If nothing changed, we don't have to rebuild the symbol.
309314
if (!anyChanged) {
@@ -566,7 +571,7 @@ void RewriteSystem::simplifyRightHandSides() {
566571
}
567572
}
568573

569-
/// Simplify substitutions in superclass, concrete type and concrete
574+
/// Simplify substitution terms in superclass, concrete type and concrete
570575
/// conformance symbols.
571576
void RewriteSystem::simplifyLeftHandSideSubstitutions() {
572577
for (unsigned ruleID = 0, e = Rules.size(); ruleID < e; ++ruleID) {

0 commit comments

Comments
 (0)