You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Manual/Quotients.lean
+49-3Lines changed: 49 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,9 @@ In particular, all functions from a quotient type must prove that they respect t
27
27
28
28
{docstring Quotient}
29
29
30
+
A proof that two elements of the underlying type are related by the equivalence relation is sufficient to prove that they are equal in the {name}`Quotient`.
31
+
However, {tech}[definitional equality] is unaffected by the use of {lean}`Quotient`: two elements in the quotient are definitionally equal if and only if they are definitionally equal in the underlying type.
32
+
30
33
:::paragraph
31
34
Quotient types are not widely used in programming.
32
35
However, they occur regularly in mathematics:
@@ -53,6 +56,7 @@ However, they occur regularly in mathematics:
53
56
54
57
:::
55
58
59
+
56
60
One alternative to quotient types would be to reason directly about the equivalence classes introduced by the relation.
57
61
The downside of this approach is that it does not allow _computation_: in addition to knowing _that_ there is an integer that is the sum of 5 and 8, it is useful for $`5 + 8 = 13` to not be a theoremthatrequiresproof.
@@ -62,10 +66,23 @@ Defining functions out of sets of equivalence classes relies on non-computationa
62
66
tag := "quotient-alternatives"
63
67
%%%
64
68
69
+
While {name}`Quotient` is a convenient way to form quotients with reasonable computational properties, it is often possible to define quotients in other ways.
70
+
71
+
In general, a type $`Q` is said to be the quotient of $`A` by an equivalence relation $`\sim` if it respects the universal property of quotients: there is a function $`q:A\to Q` with the property that $`q(a)=q(b)` if and only if $`a\sim b` for all $`a` and $`b` in $`A`.
72
+
73
+
Quotients formed with {name}`Quotient` have this property up to propositional equality: elements of $`A` that are related by $`\sim` are equal, so they cannot be distinguished.
74
+
But members of the same equivalence classarenotnecessarily {tech key:="definitional equality"}[definitionally equal] in the quotient.
75
+
76
+
Quotients may also be implemented by designating a single representative of each equivalence classin $`A`itself,andthendefining $`Q`aspairofelementsin $`A`with proofs that they are such a canonical representative.
77
+
Together with a function that maps each $`a` in $`A` to its canonical representative, $`Q` is a quotient of $`A`.
78
+
Due to {tech}[proof irrelevance], representatives in $`Q` of the same equivalence classare {tech key:="definitional equality"}[definitionally equal].
79
+
80
+
Such a manually implemented quotient $`Q` can be easier to work with than {name}`Quotient`.
81
+
In particular, because each equivalence classisrepresentedbyitssinglecanonicalrepresentative,there'snoneedtoprovethatfunctionsfromthequotientrespecttheequivalencerelation.
82
+
Itcanalsohavebettercomputationalpropertiesduetothefactthatthecomputationsgivenormalizedvalues (in contrast, elements of {name}`Quotient` can be represented in multiple ways).
83
+
Finally, because the manually implemented quotient is an {tech}[inductivetype],itcanbeusedincontextswhere other kinds of types cannot, such as when defining a {ref "nested-inductive-types"}[nested inductivetype].
84
+
However,notallquotientscanbemanuallyimplemented.
65
85
66
-
Quotient types are not the only way to implement quotients.
67
-
An alternative is to select a canonical representative for each equivalence classinducedbytheequivalencerelation,andthenpairanelementoftheunderlyingtypewith a proof that it is such a canonical representative.
68
-
These manually constructed quotients are often much easier to work with than full quotient types, but not all quotients can be implemented this way.
69
86
70
87
:::example"Manually Quotiented Integers"
71
88
When implemented as pairs of {lean}`Nat`s, each equivalence classaccordingtothedesiredequalityforintegershasacanonicalrepresentativeinwhichatleastoneofthe {lean}`Nat`s is zero.
@@ -138,9 +155,31 @@ instance : Add Z where
138
155
```
139
156
140
157
Because each equivalence classisuniquelyrepresented,there'snoneedtowriteaproofthatthesefunctionsfrom {lean}`Z` respect the equivalence relation.
158
+
However, in practice, the {ref "quotient-api"}[API for quotients] should be implemented for manually-constructed quotients and proved to respect the universal property.
141
159
142
160
:::
143
161
162
+
:::example"Built-In Integers as Quotients"
163
+
164
+
Lean's built-in integer type {lean}`Int` satisfies the universal property of quotients, and can thus be thought of as a quotient of pairs of {lean}`Nat`s.
165
+
The canonical representative of each equivalence classcanbecomputedviacomparisonandsubtraction:{margin}[This {lean}`toInt` function is called {name}`Int.subNatNat` in the standard library.]
166
+
```lean
167
+
deftoInt (n k : Nat) : Int :=
168
+
if n < k then - (k - n : Nat)
169
+
elseif n = k then0
170
+
else (n - k : Nat)
171
+
```
172
+
173
+
It satisfies the universal property.
174
+
Two pairs of {lean}`Nat`s are represent the same integer if and only if {lean}`toInt` computes the same {lean}`Int` for both pairs:
175
+
```lean
176
+
theoremtoInt_sound :
177
+
n + k' = k + n' ↔
178
+
toInt n k = toInt n' k' := by
179
+
simp only [toInt]
180
+
split <;> split <;> omega
181
+
```
182
+
:::
144
183
145
184
# Setoids
146
185
%%%
@@ -468,6 +507,13 @@ Stating that a dependent function respects the quotient's equivalence relation r
468
507
469
508
{docstring Quotient.hrecOn}
470
509
510
+
If two elements of a type are equal in a quotient, then they are related by the setoid's equivalence relation.
0 commit comments