Skip to content

Commit 9f348bf

Browse files
committed
Fix the line break
1 parent 4a83abe commit 9f348bf

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

cc-compare.md

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Capture Set Comparison
2+
3+
## Capture reference definition
4+
5+
All references in capture sets are `CaptureRef`s.
6+
7+
Valid `CaptureRef`s can be categorized into two kinds:
8+
9+
1. Value references, representing some singleton values in the set:
10+
11+
* A singleton reference `SingletonCaptureRef`, e.g. `x`, `x.y`, `this`
12+
- Stable `TermRef`
13+
- `TermParamRef`
14+
- `ThisType`
15+
16+
The info of a value reference can be:
17+
18+
* `CapturingType(parent, refs)`, a type with capture set: `x: A^{a, b}`;
19+
20+
* a value reference: `x: (y.type & A)`. In this case, `x` and `y` should be treated as the same reference during comparison.
21+
22+
* A union `|` of two value references, e.g. `x | y | z.a`
23+
24+
* An intersection `&` containing at least one value reference, e.g. `x & y & A`
25+
26+
* `MaybeCapability(x)` or `ReachCapability(x)` where `x` is a value reference.
27+
28+
2. Capture variable references, representing capture set polymorphism.
29+
All capture variable references are bounded by `CapSet`.
30+
A capture variable should not have any value instance, e.g. `val x: CapSet^{a}`
31+
32+
* A type reference, e.g. `C` in `{x, C}`
33+
34+
- `TypeRef`
35+
36+
- `TypeParamRef`
37+
38+
The info of a capture variable reference can be:
39+
40+
* a `TypeBounds(lo, hi)` where `lo` and `hi` are both capture variable references.
41+
If the type is an alias, both `lo` and `hi` are the same type.
42+
43+
* a `CapturingType(parent, refs)`, where `parent` is a capture variable reference.
44+
45+
* A union or intersection of two capture variable references, e.g. `C | CapSet^{x, y}`
46+
47+
## Comparison
48+
49+
Capture set comparison starts at:
50+
51+
```scala
52+
class CaptureSet:
53+
final def subCaptures(that: CaptureSet, frozen: Boolean)(using Context): CompareResult
54+
```
55+
56+
Later, `def subsumes(y: CaptureRef)` is called to compare two capture references: `{y} <:< {this}`.
57+
58+
There are three cases when comparing two capture references:
59+
60+
1. Both are value references: the comparison should be done in the `subsumes`.
61+
62+
2. Both are capture variable references: the subtyping should be used to compare the two types.
63+
The existing subtyping algorithm is able to check all possible type relations.
64+
65+
3. One is a value reference and the other is a capture variable reference.
66+
This is the most tricky case.
67+
The value reference should be converted to a capture variable with the reference in the capture set.
68+
69+
For example, when comparing `{x} <:< {C}`, where `C` is defined as `cap C >: {x} <: C2`,
70+
the comparison becomes `CapSet^{x} <:< C`.
71+
By the subtyping algorithm, `CapSet^{x}` will be compared with the lower bound of `C`, which is `{x}`.
72+
Then the comparison is reduced to `{x} <:< {x}`, which is true.
73+
74+
The tricky part is the info of `this`: for example, `x: IO^{io}` and `y: IO^{io}`, `{x} <:< {y}` should be false, as `x` and `y` can be two different instances both capturing `io`.
75+
76+
## Detailed comparison rules
77+
78+
### Subsuming `{y} <:< {x}`
79+
80+
Union and intersection types are treated specially in the rules,
81+
as they are not allowed directly in the capture set, for example, `A^{(x.type | y.type), z}`.
82+
Therefore, a value reference must be a singleton type, `SingletonCaptureRef`.
83+
Note the `||` and `&&` in the cases, because we only consider **equivalent references**.
84+
85+
Assuming both `x` and `y` are valid `CaptureRef`s, `x.subsumes(y)`:
86+
87+
TODO: `subsumesExistentially` should be considered.
88+
89+
1. If `x` and `y` are the same reference, `x eq y`.
90+
2. If `x` is a root capability.
91+
3. If `y` is a singleton type and not a root capability,
92+
1. If `x` is also a singleton type, and `x =:= y`.
93+
2. If `y` is a selection `ypre.f`, and `x.subsumes(ypre)`.
94+
3. By the info of `y`,
95+
* If `y.info` is a singleton type, `x.subsumes(y.info)`.
96+
* If `y =:= y1 | y2` and `y1` and `y2` are both singleton types, `x.subsumes(y1) && x.subsumes(y2)`.
97+
* If `y =:= y1 & y2`, `x.subsumes(y1) || x.subsumes(y2)`.
98+
4. If `x` is bounded by `CapSet` and `CapSet^{y} <:< x`.
99+
4. If `y` is a `MaybeCapability(y1)` and `x` is a `MaybeCapability(x1)`, `x1.subsumes(y1)`.
100+
5. If `x` is a `ReachCapability(x1)` and `y` is a `ReachCapability(y1)`, `x1.subsumes(y1)`.
101+
6. If `x` is a singleton type,
102+
1. By the info of `x`,
103+
* If `x.info` is a singleton type, `x.info.subsumes(y)`.
104+
* If `x =:= x1 | x2`, `x1.subsumes(y) && x2.subsumes(y)`.
105+
* If `x =:= x1 & x2`, `x1.subsumes(y) || x2.subsumes(y)`.
106+
2. If `y` is bounded by `CapSet` and `y <:< CapSet^{x}`.
107+
7. If `x` and `y` are both bounded by `CapSet`, `y <:< x`.
108+
8. If `x` is bounded by `CapSet` and `y` is assumed to be contained in `x`.
109+
110+
111+
### Subtyping `T1 <:< T2`
112+
113+
`T1 <:< T2`:
114+
115+
TODO: we are still not sure about the rules for union and intersection types.
116+
For example, should `C2^{x}` be a subtype of `C1^{x} | C2^{y}` given `x` and `y` are different references?

0 commit comments

Comments
 (0)