Skip to content

Commit 86ee6c2

Browse files
committed
RequirementMachine: Add some comments
1 parent 916249e commit 86ee6c2

File tree

2 files changed

+75
-2
lines changed

2 files changed

+75
-2
lines changed

lib/AST/RequirementMachine/GeneratingConformances.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,24 @@
1616
// (Vi.[Pi]), where each Vi.[Pi] is a left hand side of a generating
1717
// conformance.
1818
//
19+
// A "conformance-valid" rewrite system is one where if we can write
20+
// T == U.V for arbitrary non-empty U and V, then U.[domain(V)] is joinable
21+
// with U.
22+
//
23+
// If this holds, then starting with a term T.[P] that is joinable with T, we
24+
// can reduce T to canonical form T', and find the unique rule (V.[P] => V) such
25+
// that T' == U.V. Then we repeat this process with U.[domain(V)], which is
26+
// known to be joinable with U, since T is conformance-valid.
27+
//
28+
// Iterating this process produces a decomposition of T.[P] as a product of
29+
// left hand sides of conformance rules. Some of those rules are not minimal;
30+
// they are added by completion, or they are redundant rules written by the
31+
// user.
32+
//
33+
// Using the 3-cells that generate the homotopy relation on rewrite paths,
34+
// decompositions can be found for all "derived" conformance rules, producing
35+
// a minimal set of generating conformances.
36+
//
1937
//===----------------------------------------------------------------------===//
2038

2139
#include "swift/Basic/Defer.h"
@@ -30,6 +48,9 @@
3048
using namespace swift;
3149
using namespace rewriting;
3250

51+
/// Finds all protocol conformance rules appearing in a 3-cell, both without
52+
/// context, and with a non-empty left context. Applications of rules with a
53+
/// non-empty right context are ignored.
3354
void HomotopyGenerator::findProtocolConformanceRules(
3455
SmallVectorImpl<unsigned> &notInContext,
3556
SmallVectorImpl<std::pair<MutableTerm, unsigned>> &inContext,
@@ -287,6 +308,14 @@ void RewriteSystem::computeCandidateConformancePaths(
287308
}
288309
}
289310

311+
/// Determines if \p path can be expressed without any of the conformance
312+
/// rules appearing in \p redundantConformances, by possibly substituting
313+
/// any occurrences of the redundant rules with alternate definitions
314+
/// appearing in \p conformancePaths.
315+
///
316+
/// The \p conformancePaths map sends conformance rules to a list of
317+
/// disjunctions, where each disjunction is a product of other conformance
318+
/// rules.
290319
bool RewriteSystem::isValidConformancePath(
291320
llvm::SmallDenseSet<unsigned, 4> &visited,
292321
llvm::DenseSet<unsigned> &redundantConformances,
@@ -325,6 +354,9 @@ bool RewriteSystem::isValidConformancePath(
325354
return true;
326355
}
327356

357+
/// Computes a minimal set of generating conformances, assuming that homotopy
358+
/// reduction has already eliminated all redundant rewrite rules that are not
359+
/// conformance rules.
328360
void RewriteSystem::computeGeneratingConformances(
329361
llvm::DenseSet<unsigned> &redundantConformances) {
330362
llvm::MapVector<unsigned, std::vector<SmallVector<unsigned, 2>>> conformancePaths;

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,46 @@
99
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12+
//
13+
// A confluent rewrite system together with a set of 3-cells that generate the
14+
// homotopy relation on 2-cells (rewrite paths) is known as a 'coherent
15+
// presentation'.
16+
//
17+
// If a rewrite rule appears exactly once in a 3-cell and without context, the
18+
// 3-cell witnesses a redundancy; the rewrite rule is equivalent to traveling
19+
// around the loop "in the other direction". This rewrite rule and the
20+
// corresponding 3-cell can be deleted from the coherent presentation via a
21+
// Tietze transformation.
22+
//
23+
// Any occurrence of the rule in the remaining 3-cells is replaced with the
24+
// alternate definition obtained by splitting the 3-cell that witnessed the
25+
// redundancy. After substitution, every 3-cell is normalized to a cyclically
26+
// reduced left-canonical form. The 3-cell witnessing the redundancy normalizes
27+
// to the empty loop and is deleted.
28+
//
29+
// Iterating this process eventually produces a minimal presentation.
30+
//
31+
// For a description of the general algorithm, see "A Homotopical Completion
32+
// Procedure with Applications to Coherence of Monoids",
33+
// https://hal.inria.fr/hal-00818253.
34+
//
35+
// The idea of computing a left-canonical form for 2-cells is from
36+
// "Homotopy reduction systems for monoid presentations",
37+
// https://www.sciencedirect.com/science/article/pii/S0022404997000959
38+
//
39+
// Note that in the world of Swift, rewrite rules for introducing associated
40+
// type symbols are marked 'permanent'; they are always re-added when a new
41+
// rewrite system is built from a minimal generic signature, so instead of
42+
// deleting them it is better to leave them in place in case it allows other
43+
// rules to be deleted instead.
44+
//
45+
// Also, for a conformance rule (V.[P] => V) to be redundant, a stronger
46+
// condition is needed than appearing once in a 3-cell and without context;
47+
// the rule must not be a _generating conformance_. The algorithm for computing
48+
// a minimal set of generating conformances is implemented in
49+
// GeneratingConformances.cpp.
50+
//
51+
//===----------------------------------------------------------------------===//
1252

1353
#include "swift/Basic/Range.h"
1454
#include "llvm/ADT/DenseMap.h"
@@ -655,8 +695,9 @@ void RewriteSystem::deleteRule(unsigned ruleID,
655695
}
656696
}
657697

658-
/// Use the 3-cells to delete rewrite rules, updating and simplifying existing
659-
/// 3-cells as each rule is deleted.
698+
/// Use the 3-cells to delete redundant rewrite rules via a series of Tietze
699+
/// transformations, updating and simplifying existing 3-cells as each rule
700+
/// is deleted.
660701
void RewriteSystem::minimizeRewriteSystem() {
661702
// First, eliminate all redundant rules that are not conformance rules.
662703
while (true) {

0 commit comments

Comments
 (0)