Skip to content

Commit 1057b56

Browse files
committed
RequirementMachine: Rename HomotopyGenerator to RewriteLoop
Also, stop talking about 2-cells and 3-cells.
1 parent c0154d4 commit 1057b56

13 files changed

+92
-90
lines changed

lib/AST/RequirementMachine/GeneratingConformances.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ using namespace rewriting;
7777
/// of the pair stores conformance rules that appear without context. The
7878
/// second element of the pair stores rules that appear with non-empty left
7979
/// context. For each such rule, the left prefix is also stored alongside.
80-
void HomotopyGenerator::findProtocolConformanceRules(
80+
void RewriteLoop::findProtocolConformanceRules(
8181
llvm::SmallDenseMap<const ProtocolDecl *,
8282
ProtocolConformanceRules, 2> &result,
8383
const RewriteSystem &system) const {
@@ -274,7 +274,7 @@ RewriteSystem::decomposeTermIntoConformanceRuleLeftHandSides(
274274
void RewriteSystem::computeCandidateConformancePaths(
275275
llvm::MapVector<unsigned,
276276
std::vector<SmallVector<unsigned, 2>>> &conformancePaths) const {
277-
for (const auto &loop : HomotopyGenerators) {
277+
for (const auto &loop : Loops) {
278278
if (loop.isDeleted())
279279
continue;
280280

lib/AST/RequirementMachine/HomotopyReduction.cpp

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
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'.
13+
// A confluent rewrite system together with a set of rewrite loops that generate
14+
// the homotopy relation on rewrite paths is known as a 'coherent presentation'.
1615
//
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
16+
// If a rewrite rule appears exactly once in a loop and without context, the
17+
// loop witnesses a redundancy; the rewrite rule is equivalent to traveling
1918
// 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
19+
// corresponding loop can be deleted from the coherent presentation via a
2120
// Tietze transformation.
2221
//
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
22+
// Any occurrence of the rule in the remaining loops is replaced with the
23+
// alternate definition obtained by splitting the loop that witnessed the
24+
// redundancy. After substitution, every loop is normalized to a cyclically
25+
// reduced left-canonical form. The loop witnessing the redundancy normalizes
2726
// to the empty loop and is deleted.
2827
//
2928
// Iterating this process eventually produces a minimal presentation.
@@ -32,7 +31,7 @@
3231
// Procedure with Applications to Coherence of Monoids",
3332
// https://hal.inria.fr/hal-00818253.
3433
//
35-
// The idea of computing a left-canonical form for 2-cells is from
34+
// The idea of computing a left-canonical form for rewrite loops is from
3635
// "Homotopy reduction systems for monoid presentations",
3736
// https://www.sciencedirect.com/science/article/pii/S0022404997000959
3837
//
@@ -43,7 +42,7 @@
4342
// rules to be deleted instead.
4443
//
4544
// 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;
45+
// condition is needed than appearing once in a loop and without context;
4746
// the rule must not be a _generating conformance_. The algorithm for computing
4847
// a minimal set of generating conformances is implemented in
4948
// GeneratingConformances.cpp.
@@ -94,7 +93,8 @@ MutableTerm &RewritePathEvaluator::getCurrentTerm() {
9493
return A.back();
9594
}
9695

97-
/// Invert a 2-cell.
96+
/// Invert a rewrite path, producing a path that rewrites the original path's
97+
/// destination back to the original path's source.
9898
void RewritePath::invert() {
9999
std::reverse(Steps.begin(), Steps.end());
100100

@@ -350,10 +350,10 @@ void RewriteStep::dump(llvm::raw_ostream &out,
350350
}
351351
}
352352

353-
/// A rewrite rule is redundant if it appears exactly once in a 3-cell
353+
/// A rewrite rule is redundant if it appears exactly once in a loop
354354
/// without context.
355355
llvm::SmallVector<unsigned, 1>
356-
HomotopyGenerator::findRulesAppearingOnceInEmptyContext(
356+
RewriteLoop::findRulesAppearingOnceInEmptyContext(
357357
const RewriteSystem &system) const {
358358
llvm::SmallDenseSet<unsigned, 2> rulesInEmptyContext;
359359
llvm::SmallDenseMap<unsigned, unsigned, 2> ruleMultiplicity;
@@ -391,10 +391,10 @@ HomotopyGenerator::findRulesAppearingOnceInEmptyContext(
391391
return result;
392392
}
393393

394-
/// Given a rewrite rule which appears exactly once in a 3-cell
394+
/// Given a rewrite rule which appears exactly once in a loop
395395
/// without context, return a new definition for this rewrite rule.
396396
/// The new definition is the path obtained by deleting the
397-
/// rewrite rule from the 3-cell.
397+
/// rewrite rule from the loop.
398398
RewritePath RewritePath::splitCycleAtRule(unsigned ruleID) const {
399399
// A cycle is a path from the basepoint to the basepoint.
400400
// Somewhere in this path, an application of \p ruleID
@@ -653,12 +653,12 @@ bool RewritePath::computeFreelyReducedPath() {
653653
/// pairs of terms from the ends that are inverses of each other, applying
654654
/// the corresponding translation to the basepoint.
655655
///
656-
/// For example, consider this 3-cell, forming a loop with basepoint 'X':
656+
/// For example, consider this loop with basepoint 'X':
657657
///
658658
/// (X => Y.A) * (Y.A => Y.B) * Y.(B => A) * (Y.A => X)
659659
///
660660
/// The first step is the inverse of the last step, so the cyclic
661-
/// reduction is the 3-cell (Y.A => Y.B) * Y.(B => A), with a new
661+
/// reduction is the loop (Y.A => Y.B) * Y.(B => A), with a new
662662
/// basepoint 'Y.A'.
663663
bool RewritePath::computeCyclicallyReducedLoop(MutableTerm &basepoint,
664664
const RewriteSystem &system) {
@@ -717,8 +717,8 @@ void RewritePath::dump(llvm::raw_ostream &out,
717717
}
718718
}
719719

720-
/// Compute cyclically-reduced left-canonical normal form of a 3-cell.
721-
void HomotopyGenerator::normalize(const RewriteSystem &system) {
720+
/// Compute cyclically-reduced left-canonical normal form of a loop.
721+
void RewriteLoop::normalize(const RewriteSystem &system) {
722722
// FIXME: This can be more efficient.
723723
bool changed;
724724
do {
@@ -729,8 +729,8 @@ void HomotopyGenerator::normalize(const RewriteSystem &system) {
729729
} while (changed);
730730
}
731731

732-
/// A 3-cell is "in context" if every rewrite step has a left or right whisker.
733-
bool HomotopyGenerator::isInContext(const RewriteSystem &system) const {
732+
/// A loop is "in context" if every rewrite step has a left or right whisker.
733+
bool RewriteLoop::isInContext(const RewriteSystem &system) const {
734734
RewritePathEvaluator evaluator(Basepoint);
735735

736736
unsigned minStartOffset = (unsigned) -1;
@@ -760,8 +760,8 @@ bool HomotopyGenerator::isInContext(const RewriteSystem &system) const {
760760
return (minStartOffset > 0 || minEndOffset > 0);
761761
}
762762

763-
void HomotopyGenerator::dump(llvm::raw_ostream &out,
764-
const RewriteSystem &system) const {
763+
void RewriteLoop::dump(llvm::raw_ostream &out,
764+
const RewriteSystem &system) const {
765765
out << Basepoint << ": ";
766766
Path.dump(out, Basepoint, system);
767767
if (isDeleted())
@@ -784,7 +784,7 @@ isCandidateForDeletion(unsigned ruleID,
784784
// Associated type introduction rules are 'permanent'. They're
785785
// not worth eliminating since they are re-added every time; it
786786
// is better to find other candidates to eliminate in the same
787-
// 3-cell instead.
787+
// loop instead.
788788
if (rule.isPermanent())
789789
return false;
790790

@@ -826,7 +826,7 @@ isCandidateForDeletion(unsigned ruleID,
826826
return true;
827827
}
828828

829-
/// Find a rule to delete by looking through all 3-cells for rewrite rules appearing
829+
/// Find a rule to delete by looking through all loops for rewrite rules appearing
830830
/// once in empty context. Returns a redundant rule to delete if one was found,
831831
/// otherwise returns None.
832832
///
@@ -850,8 +850,8 @@ findRuleToDelete(bool firstPass,
850850
assert(!firstPass || redundantConformances == nullptr);
851851

852852
SmallVector<std::pair<unsigned, unsigned>, 2> redundancyCandidates;
853-
for (unsigned loopID : indices(HomotopyGenerators)) {
854-
const auto &loop = HomotopyGenerators[loopID];
853+
for (unsigned loopID : indices(Loops)) {
854+
const auto &loop = Loops[loopID];
855855
if (loop.isDeleted())
856856
continue;
857857

@@ -887,7 +887,7 @@ findRuleToDelete(bool firstPass,
887887
unsigned ruleID = found->second;
888888
assert(replacementPath.empty());
889889

890-
auto &loop = HomotopyGenerators[loopID];
890+
auto &loop = Loops[loopID];
891891
replacementPath = loop.Path.splitCycleAtRule(ruleID);
892892

893893
loop.markDeleted();
@@ -897,7 +897,7 @@ findRuleToDelete(bool firstPass,
897897
}
898898

899899
/// Delete a rewrite rule that is known to be redundant, replacing all
900-
/// occurrences of the rule in all 3-cells with the replacement path.
900+
/// occurrences of the rule in all loops with the replacement path.
901901
void RewriteSystem::deleteRule(unsigned ruleID,
902902
const RewritePath &replacementPath) {
903903
if (Debug.contains(DebugFlags::HomotopyReduction)) {
@@ -912,8 +912,8 @@ void RewriteSystem::deleteRule(unsigned ruleID,
912912
}
913913

914914
// Replace all occurrences of the rule with the replacement path and
915-
// normalize all 3-cells.
916-
for (auto &loop : HomotopyGenerators) {
915+
// normalize all loops.
916+
for (auto &loop : Loops) {
917917
if (loop.isDeleted())
918918
continue;
919919

@@ -927,14 +927,14 @@ void RewriteSystem::deleteRule(unsigned ruleID,
927927

928928
if (Debug.contains(DebugFlags::HomotopyReduction)) {
929929
if (size != loop.Path.size()) {
930-
llvm::dbgs() << "** Note: 3-cell normalization eliminated "
930+
llvm::dbgs() << "** Note: loop normalization eliminated "
931931
<< (size - loop.Path.size()) << " steps\n";
932932
}
933933
}
934934

935935
if (loop.Path.empty()) {
936936
if (Debug.contains(DebugFlags::HomotopyReduction)) {
937-
llvm::dbgs() << "** Deleting trivial 3-cell at basepoint ";
937+
llvm::dbgs() << "** Deleting trivial loop at basepoint ";
938938
llvm::dbgs() << loop.Basepoint << "\n";
939939
}
940940

@@ -945,7 +945,7 @@ void RewriteSystem::deleteRule(unsigned ruleID,
945945
// FIXME: Is this correct?
946946
if (loop.isInContext(*this)) {
947947
if (Debug.contains(DebugFlags::HomotopyReduction)) {
948-
llvm::dbgs() << "** Deleting 3-cell in context: ";
948+
llvm::dbgs() << "** Deleting loop in context: ";
949949
loop.dump(llvm::dbgs(), *this);
950950
llvm::dbgs() << "\n";
951951
}
@@ -955,7 +955,7 @@ void RewriteSystem::deleteRule(unsigned ruleID,
955955
}
956956

957957
if (Debug.contains(DebugFlags::HomotopyReduction)) {
958-
llvm::dbgs() << "** Updated 3-cell: ";
958+
llvm::dbgs() << "** Updated loop: ";
959959
loop.dump(llvm::dbgs(), *this);
960960
llvm::dbgs() << "\n";
961961
}
@@ -979,8 +979,8 @@ void RewriteSystem::performHomotopyReduction(
979979
}
980980
}
981981

982-
/// Use the 3-cells to delete redundant rewrite rules via a series of Tietze
983-
/// transformations, updating and simplifying existing 3-cells as each rule
982+
/// Use the loops to delete redundant rewrite rules via a series of Tietze
983+
/// transformations, updating and simplifying existing loops as each rule
984984
/// is deleted.
985985
///
986986
/// Redundant rules are mutated to set their isRedundant() bit.
@@ -989,17 +989,17 @@ void RewriteSystem::minimizeRewriteSystem() {
989989
assert(!Minimized);
990990
Minimized = 1;
991991

992-
/// Begin by normalizing all 3-cells to cyclically-reduced left-canonical
992+
/// Begin by normalizing all loops to cyclically-reduced left-canonical
993993
/// form.
994-
for (auto &loop : HomotopyGenerators) {
994+
for (auto &loop : Loops) {
995995
if (loop.isDeleted())
996996
continue;
997997

998998
loop.normalize(*this);
999999
}
10001000

10011001
// Check invariants before homotopy reduction.
1002-
verifyHomotopyGenerators();
1002+
verifyRewriteLoops();
10031003

10041004
// First pass: Eliminate all redundant rules involving unresolved types.
10051005
performHomotopyReduction(/*firstPass=*/true,
@@ -1022,7 +1022,7 @@ void RewriteSystem::minimizeRewriteSystem() {
10221022
/*redundantConformances=*/&redundantConformances);
10231023

10241024
// Check invariants after homotopy reduction.
1025-
verifyHomotopyGenerators();
1025+
verifyRewriteLoops();
10261026
verifyRedundantConformances(redundantConformances);
10271027
verifyMinimizedRules();
10281028
}
@@ -1055,10 +1055,10 @@ RewriteSystem::getMinimizedRules(ArrayRef<const ProtocolDecl *> protos) {
10551055
return rules;
10561056
}
10571057

1058-
/// Verify that each 3-cell is a valid loop around its basepoint.
1059-
void RewriteSystem::verifyHomotopyGenerators() const {
1058+
/// Verify that each loop begins and ends at its basepoint.
1059+
void RewriteSystem::verifyRewriteLoops() const {
10601060
#ifndef NDEBUG
1061-
for (const auto &loop : HomotopyGenerators) {
1061+
for (const auto &loop : Loops) {
10621062
RewritePathEvaluator evaluator(loop.Basepoint);
10631063

10641064
for (const auto &step : loop.Path) {

lib/AST/RequirementMachine/RequirementMachine.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ void RequirementMachine::initWithGenericSignature(CanGenericSignature sig) {
458458

459459
// Add the initial set of rewrite rules to the rewrite system, also
460460
// providing the protocol graph to use for the linear order on terms.
461-
System.initialize(/*recordHomotopyGenerators=*/false,
461+
System.initialize(/*recordLoops=*/false,
462462
std::move(builder.AssociatedTypeRules),
463463
std::move(builder.RequirementRules));
464464

@@ -499,7 +499,7 @@ void RequirementMachine::initWithProtocols(ArrayRef<const ProtocolDecl *> protos
499499

500500
// Add the initial set of rewrite rules to the rewrite system, also
501501
// providing the protocol graph to use for the linear order on terms.
502-
System.initialize(/*recordHomotopyGenerators=*/true,
502+
System.initialize(/*recordLoops=*/true,
503503
std::move(builder.AssociatedTypeRules),
504504
std::move(builder.RequirementRules));
505505

lib/AST/RequirementMachine/RewriteSystem.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ RewriteSystem::RewriteSystem(RewriteContext &ctx)
112112
Initialized = 0;
113113
Complete = 0;
114114
Minimized = 0;
115-
RecordHomotopyGenerators = 0;
115+
RecordLoops = 0;
116116
}
117117

118118
RewriteSystem::~RewriteSystem() {
@@ -121,13 +121,13 @@ RewriteSystem::~RewriteSystem() {
121121
}
122122

123123
void RewriteSystem::initialize(
124-
bool recordHomotopyGenerators,
124+
bool recordLoops,
125125
std::vector<std::pair<MutableTerm, MutableTerm>> &&associatedTypeRules,
126126
std::vector<std::pair<MutableTerm, MutableTerm>> &&requirementRules) {
127127
assert(!Initialized);
128128
Initialized = 1;
129129

130-
RecordHomotopyGenerators = recordHomotopyGenerators;
130+
RecordLoops = recordLoops;
131131

132132
for (const auto &rule : associatedTypeRules) {
133133
bool added = addRule(rule.first, rule.second);
@@ -272,7 +272,7 @@ bool RewriteSystem::addRule(MutableTerm lhs, MutableTerm rhs,
272272
if (path) {
273273
// We already have a loop, since the simplified lhs is identical to the
274274
// simplified rhs.
275-
recordHomotopyGenerator(lhs, loop);
275+
recordRewriteLoop(lhs, loop);
276276

277277
if (Debug.contains(DebugFlags::Add)) {
278278
llvm::dbgs() << "## Recorded trivial loop at " << lhs << ": ";
@@ -308,7 +308,7 @@ bool RewriteSystem::addRule(MutableTerm lhs, MutableTerm rhs,
308308
// add a rewrite step applying the new rule in reverse to close the loop.
309309
loop.add(RewriteStep::forRewriteRule(/*startOffset=*/0, /*endOffset=*/0,
310310
newRuleID, /*inverse=*/true));
311-
recordHomotopyGenerator(lhs, loop);
311+
recordRewriteLoop(lhs, loop);
312312

313313
if (Debug.contains(DebugFlags::Add)) {
314314
llvm::dbgs() << "## Recorded non-trivial loop at " << lhs << ": ";
@@ -488,7 +488,7 @@ void RewriteSystem::simplifyRewriteSystem() {
488488
loop.dump(llvm::dbgs(), MutableTerm(lhs), *this);
489489
}
490490

491-
recordHomotopyGenerator(MutableTerm(lhs), loop);
491+
recordRewriteLoop(MutableTerm(lhs), loop);
492492
}
493493
}
494494

@@ -562,8 +562,8 @@ void RewriteSystem::dump(llvm::raw_ostream &out) const {
562562
out << "- " << rule << "\n";
563563
}
564564
out << "}\n";
565-
out << "Homotopy generators: {\n";
566-
for (const auto &loop : HomotopyGenerators) {
565+
out << "Rewrite loops: {\n";
566+
for (const auto &loop : Loops) {
567567
if (loop.isDeleted())
568568
continue;
569569

0 commit comments

Comments
 (0)