10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
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'.
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'.
16
15
//
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
19
18
// 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
21
20
// Tietze transformation.
22
21
//
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
27
26
// to the empty loop and is deleted.
28
27
//
29
28
// Iterating this process eventually produces a minimal presentation.
32
31
// Procedure with Applications to Coherence of Monoids",
33
32
// https://hal.inria.fr/hal-00818253.
34
33
//
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
36
35
// "Homotopy reduction systems for monoid presentations",
37
36
// https://www.sciencedirect.com/science/article/pii/S0022404997000959
38
37
//
43
42
// rules to be deleted instead.
44
43
//
45
44
// 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;
47
46
// the rule must not be a _generating conformance_. The algorithm for computing
48
47
// a minimal set of generating conformances is implemented in
49
48
// GeneratingConformances.cpp.
@@ -94,7 +93,8 @@ MutableTerm &RewritePathEvaluator::getCurrentTerm() {
94
93
return A.back ();
95
94
}
96
95
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.
98
98
void RewritePath::invert () {
99
99
std::reverse (Steps.begin (), Steps.end ());
100
100
@@ -350,10 +350,10 @@ void RewriteStep::dump(llvm::raw_ostream &out,
350
350
}
351
351
}
352
352
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
354
354
// / without context.
355
355
llvm::SmallVector<unsigned , 1 >
356
- HomotopyGenerator ::findRulesAppearingOnceInEmptyContext (
356
+ RewriteLoop ::findRulesAppearingOnceInEmptyContext (
357
357
const RewriteSystem &system) const {
358
358
llvm::SmallDenseSet<unsigned , 2 > rulesInEmptyContext;
359
359
llvm::SmallDenseMap<unsigned , unsigned , 2 > ruleMultiplicity;
@@ -391,10 +391,10 @@ HomotopyGenerator::findRulesAppearingOnceInEmptyContext(
391
391
return result;
392
392
}
393
393
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
395
395
// / without context, return a new definition for this rewrite rule.
396
396
// / The new definition is the path obtained by deleting the
397
- // / rewrite rule from the 3-cell .
397
+ // / rewrite rule from the loop .
398
398
RewritePath RewritePath::splitCycleAtRule (unsigned ruleID) const {
399
399
// A cycle is a path from the basepoint to the basepoint.
400
400
// Somewhere in this path, an application of \p ruleID
@@ -653,12 +653,12 @@ bool RewritePath::computeFreelyReducedPath() {
653
653
// / pairs of terms from the ends that are inverses of each other, applying
654
654
// / the corresponding translation to the basepoint.
655
655
// /
656
- // / For example, consider this 3-cell, forming a loop with basepoint 'X':
656
+ // / For example, consider this loop with basepoint 'X':
657
657
// /
658
658
// / (X => Y.A) * (Y.A => Y.B) * Y.(B => A) * (Y.A => X)
659
659
// /
660
660
// / 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
662
662
// / basepoint 'Y.A'.
663
663
bool RewritePath::computeCyclicallyReducedLoop (MutableTerm &basepoint,
664
664
const RewriteSystem &system) {
@@ -717,8 +717,8 @@ void RewritePath::dump(llvm::raw_ostream &out,
717
717
}
718
718
}
719
719
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) {
722
722
// FIXME: This can be more efficient.
723
723
bool changed;
724
724
do {
@@ -729,8 +729,8 @@ void HomotopyGenerator::normalize(const RewriteSystem &system) {
729
729
} while (changed);
730
730
}
731
731
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 {
734
734
RewritePathEvaluator evaluator (Basepoint);
735
735
736
736
unsigned minStartOffset = (unsigned ) -1 ;
@@ -760,8 +760,8 @@ bool HomotopyGenerator::isInContext(const RewriteSystem &system) const {
760
760
return (minStartOffset > 0 || minEndOffset > 0 );
761
761
}
762
762
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 {
765
765
out << Basepoint << " : " ;
766
766
Path.dump (out, Basepoint, system);
767
767
if (isDeleted ())
@@ -784,7 +784,7 @@ isCandidateForDeletion(unsigned ruleID,
784
784
// Associated type introduction rules are 'permanent'. They're
785
785
// not worth eliminating since they are re-added every time; it
786
786
// is better to find other candidates to eliminate in the same
787
- // 3-cell instead.
787
+ // loop instead.
788
788
if (rule.isPermanent ())
789
789
return false ;
790
790
@@ -826,7 +826,7 @@ isCandidateForDeletion(unsigned ruleID,
826
826
return true ;
827
827
}
828
828
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
830
830
// / once in empty context. Returns a redundant rule to delete if one was found,
831
831
// / otherwise returns None.
832
832
// /
@@ -850,8 +850,8 @@ findRuleToDelete(bool firstPass,
850
850
assert (!firstPass || redundantConformances == nullptr );
851
851
852
852
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];
855
855
if (loop.isDeleted ())
856
856
continue ;
857
857
@@ -887,7 +887,7 @@ findRuleToDelete(bool firstPass,
887
887
unsigned ruleID = found->second ;
888
888
assert (replacementPath.empty ());
889
889
890
- auto &loop = HomotopyGenerators [loopID];
890
+ auto &loop = Loops [loopID];
891
891
replacementPath = loop.Path .splitCycleAtRule (ruleID);
892
892
893
893
loop.markDeleted ();
@@ -897,7 +897,7 @@ findRuleToDelete(bool firstPass,
897
897
}
898
898
899
899
// / 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.
901
901
void RewriteSystem::deleteRule (unsigned ruleID,
902
902
const RewritePath &replacementPath) {
903
903
if (Debug.contains (DebugFlags::HomotopyReduction)) {
@@ -912,8 +912,8 @@ void RewriteSystem::deleteRule(unsigned ruleID,
912
912
}
913
913
914
914
// 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 ) {
917
917
if (loop.isDeleted ())
918
918
continue ;
919
919
@@ -927,14 +927,14 @@ void RewriteSystem::deleteRule(unsigned ruleID,
927
927
928
928
if (Debug.contains (DebugFlags::HomotopyReduction)) {
929
929
if (size != loop.Path .size ()) {
930
- llvm::dbgs () << " ** Note: 3-cell normalization eliminated "
930
+ llvm::dbgs () << " ** Note: loop normalization eliminated "
931
931
<< (size - loop.Path .size ()) << " steps\n " ;
932
932
}
933
933
}
934
934
935
935
if (loop.Path .empty ()) {
936
936
if (Debug.contains (DebugFlags::HomotopyReduction)) {
937
- llvm::dbgs () << " ** Deleting trivial 3-cell at basepoint " ;
937
+ llvm::dbgs () << " ** Deleting trivial loop at basepoint " ;
938
938
llvm::dbgs () << loop.Basepoint << " \n " ;
939
939
}
940
940
@@ -945,7 +945,7 @@ void RewriteSystem::deleteRule(unsigned ruleID,
945
945
// FIXME: Is this correct?
946
946
if (loop.isInContext (*this )) {
947
947
if (Debug.contains (DebugFlags::HomotopyReduction)) {
948
- llvm::dbgs () << " ** Deleting 3-cell in context: " ;
948
+ llvm::dbgs () << " ** Deleting loop in context: " ;
949
949
loop.dump (llvm::dbgs (), *this );
950
950
llvm::dbgs () << " \n " ;
951
951
}
@@ -955,7 +955,7 @@ void RewriteSystem::deleteRule(unsigned ruleID,
955
955
}
956
956
957
957
if (Debug.contains (DebugFlags::HomotopyReduction)) {
958
- llvm::dbgs () << " ** Updated 3-cell : " ;
958
+ llvm::dbgs () << " ** Updated loop : " ;
959
959
loop.dump (llvm::dbgs (), *this );
960
960
llvm::dbgs () << " \n " ;
961
961
}
@@ -979,8 +979,8 @@ void RewriteSystem::performHomotopyReduction(
979
979
}
980
980
}
981
981
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
984
984
// / is deleted.
985
985
// /
986
986
// / Redundant rules are mutated to set their isRedundant() bit.
@@ -989,17 +989,17 @@ void RewriteSystem::minimizeRewriteSystem() {
989
989
assert (!Minimized);
990
990
Minimized = 1 ;
991
991
992
- // / Begin by normalizing all 3-cells to cyclically-reduced left-canonical
992
+ // / Begin by normalizing all loops to cyclically-reduced left-canonical
993
993
// / form.
994
- for (auto &loop : HomotopyGenerators ) {
994
+ for (auto &loop : Loops ) {
995
995
if (loop.isDeleted ())
996
996
continue ;
997
997
998
998
loop.normalize (*this );
999
999
}
1000
1000
1001
1001
// Check invariants before homotopy reduction.
1002
- verifyHomotopyGenerators ();
1002
+ verifyRewriteLoops ();
1003
1003
1004
1004
// First pass: Eliminate all redundant rules involving unresolved types.
1005
1005
performHomotopyReduction (/* firstPass=*/ true ,
@@ -1022,7 +1022,7 @@ void RewriteSystem::minimizeRewriteSystem() {
1022
1022
/* redundantConformances=*/ &redundantConformances);
1023
1023
1024
1024
// Check invariants after homotopy reduction.
1025
- verifyHomotopyGenerators ();
1025
+ verifyRewriteLoops ();
1026
1026
verifyRedundantConformances (redundantConformances);
1027
1027
verifyMinimizedRules ();
1028
1028
}
@@ -1055,10 +1055,10 @@ RewriteSystem::getMinimizedRules(ArrayRef<const ProtocolDecl *> protos) {
1055
1055
return rules;
1056
1056
}
1057
1057
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 {
1060
1060
#ifndef NDEBUG
1061
- for (const auto &loop : HomotopyGenerators ) {
1061
+ for (const auto &loop : Loops ) {
1062
1062
RewritePathEvaluator evaluator (loop.Basepoint );
1063
1063
1064
1064
for (const auto &step : loop.Path ) {
0 commit comments