Commit Graph

67 Commits

Author SHA1 Message Date
Slava Pestov
86c15ad5c1 RequirementMachine: Generating conformances can reason about concrete conformances now 2021-12-08 00:53:35 -05:00
Slava Pestov
26293c4695 RequirementMachine: Factor out Symbol::withConcreteSubstitutions() 2021-12-07 15:31:47 -05:00
Slava Pestov
d19b15b66c RequirementMachine: Introduce Symbol::Kind::ConcreteConformance 2021-12-06 23:04:46 -05:00
Slava Pestov
2dd14afc5e RequirementMachine: Minor comment fixes 2021-11-10 23:02:02 -05:00
Slava Pestov
ecce9d2405 RequirementMachine: Narrower definition of Rule::isProtocolRefinementRule()
With this change the RequirementMachine's minimization behavior with
protocol refinement rules matches the GenericSignatureBuilder.

See https://github.com/apple/swift/pull/37466 for a full explanation
of what's going on here.
2021-11-10 00:18:18 -05:00
Slava Pestov
a4e848f598 RequirementMachine: New way of modeling layout requirement implied by superclass requirement
A superclass requirement implies a layout requirement. We don't
want the layout requirement to be present in the minimal
signature, so instead of adding a pair of requirements:

    T.[superclass: C<X, Y>] => T
    T.[layout: _NativeClass] => T

Add this pair of requirements:

    T.[superclass: C<X, Y>] => T
    [superclass: C<X, Y>].[layout: _NativeClass] => [superclass: C<X, Y>] [permanent]

Completion then derives the rule as a consequence:

    T.[layout: _NativeClass] => T

Since this rule is a consequence of the other two rules, homotopy
reduction will mark it redundant.
2021-11-10 00:18:18 -05:00
Slava Pestov
ba0fe6d7ac RequirementMachine: Add Rule::isExplicit() bit
Eventually I might upgrade this to a SourceLoc, for redundancy
diagnostics.
2021-11-10 00:18:18 -05:00
Slava Pestov
b7711454a2 RequirementMachine: Rename RewriteSystemBuilder::AssociatedTypeRules => PermanentRules 2021-11-10 00:18:18 -05:00
Slava Pestov
5067bfefe4 RequirementMachine: Re-organize some methods in RewriteSystem.cpp 2021-10-27 01:28:24 -04:00
Slava Pestov
1057b56395 RequirementMachine: Rename HomotopyGenerator to RewriteLoop
Also, stop talking about 2-cells and 3-cells.
2021-10-27 01:28:24 -04:00
Slava Pestov
745acea7ce RequirementMachine: Introduce Rule::isIdentityConformanceRule() 2021-10-27 00:39:07 -04:00
Slava Pestov
6d89b42462 RequirementMachine: Simplify concrete substitutions when adding a new rule
Suppose we have these rules:

  (1) [P].[P] => [P]
  (2) [P].[P:X] => [P:X]
  (3) [P].[P:Y] => [P:Y]
  (4) [P:X].[concrete: G<τ_0_0> with <[P:Y]>]

Rule (2) and (4) overlap on the following term, which has had the concrete
type adjustment applied:

  [P].[P:X].[concrete: G<τ_0_0> with <[P].[P:Y]>]

The critical pair is obtained by applying rule (2) to both sides of the
branching is

  [P:X].[concrete: G<τ_0_0> with <[P].[P:Y]>] => [P:X]

Note that this is a distinct rule from (4), and again this new rule overlaps
with (2), producing another rule

  [P:X].[concrete: G<τ_0_0> with <[P].[P].[P:Y]>] => [P:X]

This process doesn't terminate. The root cause of this problem is the
existence of rule (1), which appears when there are multiple non-trivial
conformance paths witnessing the conformance Self : P. This occurs when a
same-type requirement is defined between Self and some other type conforming
to P.

To make this work, we need to simplify concrete substitutions when adding a
new rule in completion. Now that rewrite paths can represent this form of
simplification, this is easy to add.
2021-10-27 00:29:08 -04:00
Slava Pestov
97ed28ac4f RequirementMachine: simplify() supports appending to an existing rewrite path
This is for convenience with the subsequent change to addRule().
2021-10-27 00:28:49 -04:00
Slava Pestov
84f02eae49 RequirementMachine: Fix crash in simplifyRewriteSystem() with -debug-requirement-machine=completion
If we're not recording homotopy generators, we can't access
HomotopyGenerators.back() in the debug output.
2021-10-27 00:11:10 -04:00
Slava Pestov
bcf5e9794b RequirementMachine: Take concrete substitutions into account when checking completion depth limit
We didn't look at the length of terms appearing in concrete substitutions,
so runaway recursion there was only caught by the completion step limit
which takes much longer.
2021-10-27 00:10:40 -04:00
Slava Pestov
0571b65cb8 RequirementMachine: Move protocol linear order from ProtocolGraph to RewriteContext 2021-10-21 19:00:10 -04:00
Slava Pestov
f8fb412e77 RequirementMachine: Add Rule::compare() 2021-10-15 15:13:22 -04:00
Slava Pestov
a6cd78eeab RequirementMachine: Fix a typo in debug output and comment 2021-10-14 15:03:08 -04:00
Slava Pestov
286e91d447 RequirementMachine: Temporarily disable associated type merging when minimizing protocol signatures
Also while plumbing this through, don't record homotopy generators
unless we're minimizing a protocol signature, since they're not
used for anything else yet.
2021-10-09 19:11:14 -04:00
Slava Pestov
b47b2d3b03 RequirementMachine: Fix generating conformances 2021-10-08 14:28:27 -04:00
Slava Pestov
70233aceb7 RequirementMachine: Teach generating conformances to understand protocol refinement
For implementation reasons we want the requirement signature of a
protocol to directly include all protocol refinement relationships,
even if they can be derived via same-type requirements between Self
and some nested type.

Therefore, a protocol refinement rule [P].[Q] => [P] can only be
replaced with a generating conformance equation that consists
entirely of other conformance rules.

This exactly simulates the existing behavior of the GSB's redundant
requirements algorithm.
2021-10-08 14:28:27 -04:00
Slava Pestov
371366eb4b RequirementMachine: Assert that non-redundant rules are fully resolved 2021-10-08 14:28:27 -04:00
Slava Pestov
566971dbc2 RequirementMachine: Add some comments and assertions around state transitions 2021-10-08 14:28:27 -04:00
Slava Pestov
e7b0b1b35d RequirementMachine: Right-hand side simplification produces more aesthetically-pleasing 3-cells 2021-10-01 00:57:44 -04:00
Slava Pestov
2db676d41a RequirementMachine: Homotopy reduction deletes rules with unresolved name symbols first 2021-10-01 00:57:44 -04:00
Slava Pestov
916249ef73 RequirementMachine: Fix -debug-requirement-machine=simplify output 2021-10-01 00:56:50 -04:00
Slava Pestov
34592cb2fa RequirementMachine: Fix generating conformances algorithm for rules of the form [P].[P] => [P] 2021-10-01 00:56:50 -04:00
Slava Pestov
5f3d781ed3 RequirementMachine: Homotopy reduction tweaks
- Skip permanent rules (there's no point, we'll add them back next time)
- Skip conformance rules (these will be handled separately)
- Delete 3-cells that are entirely "in-context" (but don't quote me on
  this one, I'm not quite yet convinced it's correct, but it feels right)
2021-09-27 19:03:34 -04:00
Slava Pestov
2923a334f5 RequirementMachine: Remove unused method 2021-09-27 19:03:30 -04:00
Slava Pestov
7ad0c3cc79 RequirementMachine: Add a mode allowing unresolved name symbols in rewrite rules 2021-09-27 19:03:26 -04:00
Slava Pestov
2b068b3c48 RequirementMachine: Encapsulate 3-cells in a new HomotopyGenerator data type 2021-09-24 08:59:51 -04:00
Slava Pestov
99dab70840 RequirementMachine: Mark associated type introduction rules permanent 2021-09-24 08:59:51 -04:00
Slava Pestov
8fbe93c469 RequirementMachine: Rename Rule::isDeleted() => isSimplified(), and add isPermanent(), isRedundant() bits 2021-09-24 08:59:51 -04:00
Slava Pestov
1fa36c70c6 RequirementMachine: Factor out Rule::isPropertyRule() from the property map 2021-09-24 08:59:51 -04:00
Slava Pestov
5f03c737d2 RequirementMachine: Preliminary implementation of homotopy reduction 2021-09-24 08:59:50 -04:00
Slava Pestov
c6403e65e1 RequirementMachine: RewriteStep stores both whiskers 2021-09-24 08:59:50 -04:00
Slava Pestov
5cbfbae536 RequirementMachine: Represent concrete type adjustment in a rewrite path 2021-09-24 08:59:50 -04:00
Slava Pestov
b317a5c5ee RequirementMachine: Verify homotopy generators 2021-09-24 08:59:50 -04:00
Slava Pestov
a75327e6b1 RequirementMachine: Record homotopy generators when adding new rules during completion 2021-09-24 08:59:50 -04:00
Slava Pestov
866a04905b RequirementMachine: When simplifying right hand sides, add new rules instead of mutating
We need to keep the original rules around for homotopy generators.
2021-09-24 08:59:50 -04:00
Slava Pestov
b2a21b3117 RequirementMachine: Preliminary plumbing for computing homotopy generators 2021-09-24 08:59:50 -04:00
Slava Pestov
e4f6128990 RequirementMachine: Don't simplify terms inside concrete substitutions when adding a rule
The effect of doing this is difficult to represent with homotopy generators,
so let's just not bother.
2021-09-24 08:59:50 -04:00
Slava Pestov
9fac25d65b RequirementMachine: Clean up merged associated type algorithm some more
The left and right hand side of a merged associated type candidate rule
have a common prefix except for the associated type symbol at the end.

Instead of passing two MutableTerms, we can pass a single uniqued
Term and a Symbol.

Also, we can compute the merged symbol before pushing the candidate
onto the vector. This avoids unnecessary work if the merged symbol
is equal to the right hand side's symbol.
2021-09-02 23:02:52 -04:00
Slava Pestov
6ec2aad857 RequirementMachine: Don't add unnecessary rule in merged associated types step
If we have a rewrite rule of the form

    X.[P:A] => X.[Q:A]

We introduce a pair of rules

    X.[P:A] => X.[P&Q:A]
    X.[Q:A] => X.[P&Q:A]

But in reality only the second one is necessary. The first one is redundant
because you obtain the same result by applying the original rule followed by
the second rule.
2021-08-20 01:29:22 -04:00
Slava Pestov
7de1d9b9a4 RequirementMachine: Better debug output 2021-08-20 01:29:22 -04:00
Slava Pestov
399a600e32 RequirementMachine: Add -debug-requirement-machine= flag to control debug output 2021-08-20 01:29:22 -04:00
Slava Pestov
af05377afa RequirementMachine: Use trie to find overlapping rules 2021-08-13 16:34:27 -04:00
Slava Pestov
2fc6ec551b RequirementMachine: Use trie for left hand side simplification
In a confluent rewrite system, if the left hand side of a rule
X => Y can be reduced by some other rule X' => Y', then it is
permissible to delete the original rule X => Y altogether.

Confluence means that rewrite rules can be applied in any
order, so it is always valid to apply X' => Y' first, thus
X => Y is obsolete.

This was previously done in the completion procedure via a
quadratic algorithm that attempted to reduce each existing
rule via the newly-added rule obtained by resolving a critical
pair. Instead, we can do this in the post-processing pass
where we reduce right hand sides using a trie to speed up
the lookup.

This increases the amount of work performed by the
completion procedure, but eliminates the quadratic algorithm,
saving time overall.
2021-08-07 01:51:31 -04:00
Slava Pestov
776a0889b7 RequirementMachine: Parametrize Trie by value type and add support for longest-suffix match
The PropertyMap wants to use a try to map to PropertyBags, and it
needs longest-suffix rather than shortest-prefix matching.

Implement both by making Trie into a template class with two
parameters; the ValueType, and the MatchKind.

Note that while the MatchKind encodes the longest vs shortest
match part, matching on the prefix vs suffix of a term is up
to the caller, since the find() and insert() methods of Trie
take a pair of iterators, so simply passing in begin()/end() vs
rbegin()/rend() selects the direction.
2021-08-06 14:17:20 -04:00
Slava Pestov
156fa2cc04 RequirementMachine: Speed up term simplification with a prefix trie
Previously RewriteSystem::simplify() would attempt to apply every
rewrite rule at every position in the original term, which was
obviously a source of overhead.

The trie itself is somewhat unoptimized; for example, with a bit of
effort it could merge a node with its only child, if nodes stored
a range of elements to compare rather than a single element.
2021-08-05 21:42:50 -04:00