|
9 | 9 | // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
10 | 10 | // |
11 | 11 | //===----------------------------------------------------------------------===// |
| 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 | +//===----------------------------------------------------------------------===// |
12 | 58 |
|
13 | 59 | #include "swift/AST/Type.h" |
14 | 60 | #include "llvm/Support/raw_ostream.h" |
|
0 commit comments