-
Notifications
You must be signed in to change notification settings - Fork 67
Expand file tree
/
Copy pathBasicClasses.lean
More file actions
367 lines (230 loc) · 7.42 KB
/
Copy pathBasicClasses.lean
File metadata and controls
367 lines (230 loc) · 7.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/-
Copyright (c) 2024 Lean FRO LLC. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: David Thrane Christiansen
-/
import VersoManual
import Manual.Meta
open Manual
open Verso.Genre
open Verso.Genre.Manual
open Verso.Genre.Manual.InlineLean
set_option maxHeartbeats 250000
#doc (Manual) "Basic Classes" =>
%%%
tag := "basic-classes"
%%%
Many Lean type classes exist in order to allow built-in notations such as addition or array indexing to be overloaded.
# Boolean Equality Tests
The Boolean equality operator `==` is overloaded by defining instances of {name}`BEq`.
The companion class {name}`Hashable` specifies a hashing procedure for a type.
When a type has both {name}`BEq` and {name}`Hashable` instances, then the hashes computed should respect the {name}`BEq` instance: two values equated by {name}`BEq.beq` should always have the same hash.
{docstring BEq}
{docstring Hashable}
{docstring mixHash}
{docstring LawfulBEq}
{docstring ReflBEq}
{docstring EquivBEq}
{docstring LawfulHashable}
{docstring hash_eq}
# Ordering
There are two primary ways to order the values of a type:
* The {name}`Ord` type class provides a three-way comparison operator, {name}`compare`, which can indicate that one value is less than, equal to, or greater than another. It returns an {name}`Ordering`.
* The {name}`LT` and {name}`LE` classes provide canonical {lean}`Prop`-valued ordering relations for a type that do not need to be decidable. These relations are used to overload the `<` and `≤` operators.
{docstring Ord}
The {name}`compare` method is exported, so no explicit {name}`Ord` namespace is required to use it.
{docstring compareOn}
{docstring Ord.opposite}
{docstring Ordering}
{docstring Ordering.swap}
{docstring Ordering.then}
{docstring Ordering.isLT}
{docstring Ordering.isLE}
{docstring Ordering.isEq}
{docstring Ordering.isNe}
{docstring Ordering.isGE}
{docstring Ordering.isGT}
{docstring compareOfLessAndEq}
{docstring compareOfLessAndBEq}
{docstring compareLex}
:::syntax term (title := "Ordering Operators")
The less-than operator is overloaded in the {name}`LT` class:
```grammar
$_ < $_
```
The less-than-or-equal-to operator is overloaded in the {name}`LE` class:
```grammar
$_ ≤ $_
```
The greater-than and greater-than-or-equal-to operators are the reverse of the less-than and less-than-or-equal-to operators, and cannot be independently overloaded:
```grammar
$_ > $_
```
```grammar
$_ ≥ $_
```
:::
{docstring LT}
{docstring LE}
An {name}`Ord` can be used to construct {name}`BEq`, {name}`LT`, and {name}`LE` instances with the following helpers.
They are not automatically instances because many types are better served by custom relations.
{docstring ltOfOrd}
{docstring leOfOrd}
{docstring Ord.toBEq}
{docstring Ord.toLE}
{docstring Ord.toLT}
:::example "Using `Ord` Instances for `LT` and `LE` Instances"
Lean can automatically derive an {name}`Ord` instance.
In this case, the {inst}`Ord Vegetable` instance compares vegetables lexicographically:
```lean
structure Vegetable where
color : String
size : Fin 5
deriving Ord
```
```lean
def broccoli : Vegetable where
color := "green"
size := 2
def sweetPotato : Vegetable where
color := "orange"
size := 3
```
Using the helpers {name}`ltOfOrd` and {name}`leOfOrd`, {inst}`LT Vegetable` and {inst}`LE Vegetable` instances can be defined.
These instances compare the vegetables using {name}`compare` and logically assert that the result is as expected.
```lean
instance : LT Vegetable := ltOfOrd
instance : LE Vegetable := leOfOrd
```
The resulting relations are decidable because equality is decidable for {lean}`Ordering`:
```lean (name := brLtSw)
#eval broccoli < sweetPotato
```
```leanOutput brLtSw
true
```
```lean (name := brLeSw)
#eval broccoli ≤ sweetPotato
```
```leanOutput brLeSw
true
```
```lean (name := brLtBr)
#eval broccoli < broccoli
```
```leanOutput brLtBr
false
```
```lean (name := brLeBr)
#eval broccoli ≤ broccoli
```
```leanOutput brLeBr
true
```
:::
## Instance Construction
{docstring Ord.lex}
{docstring Ord.lex'}
{docstring Ord.on}
# Minimum and Maximum Values
The classes {name}`Max` and {name}`Min` provide overloaded operators for choosing the greater or lesser of two values.
These should be in agreement with {name}`Ord`, {name}`LT`, and {name}`LE` instances, if they exist, but there is no mechanism to enforce this.
{docstring Min}
{docstring Max}
:::leanSection
```lean -show
variable {α : Type u} [LE α]
```
Given an {inst}`LE α` instance for which {name}`LE.le` is decidable, the helpers {name}`minOfLe` and {name}`maxOfLe` can be used to create suitable {lean}`Min α` and {lean}`Max α` instances.
They can be used as the right-hand side of an {keywordOf Lean.Parser.Command.declaration}`instance` declaration.
{docstring minOfLe}
{docstring maxOfLe}
:::
# Decidability
%%%
tag := "decidable-propositions"
%%%
A proposition is {deftech}_decidable_ if it can be checked algorithmically.{index}[decidable]{index (subterm := "decidable")}[proposition]
The Law of the Excluded Middle means that every proposition is true or false, but it provides no way to check which of the two cases holds, which can often be useful.
By default, only algorithmic {lean}`Decidable` instances for which code can be generated are in scope; opening the {name}`Classical` namespace makes every proposition decidable.
{docstring Decidable}
{docstring DecidablePred}
{docstring DecidableRel}
{docstring DecidableEq}
{docstring DecidableLT}
{docstring DecidableLE}
{docstring Decidable.decide}
{docstring Decidable.byCases}
::::keepEnv
:::example "Excluded Middle and {lean}`Decidable`"
The equality of functions from {lean}`Nat` to {lean}`Nat` is not decidable:
```lean +error (name := NatFunNotDecEq)
example (f g : Nat → Nat) : Decidable (f = g) := inferInstance
```
```leanOutput NatFunNotDecEq
failed to synthesize instance of type class
Decidable (f = g)
Hint: Type class instance resolution failures can be inspected with the `set_option trace.Meta.synthInstance true` command.
```
Opening {name}`Classical` makes every proposition decidable; however, declarations and examples that use this fact must be marked {keywordOf Lean.Parser.Command.declaration}`noncomputable` to indicate that code should not be generated for them.
```lean
open Classical
noncomputable example (f g : Nat → Nat) : Decidable (f = g) :=
inferInstance
```
:::
::::
# Inhabited Types
{docstring Inhabited}
{docstring Nonempty}
# Subsingleton Types
{docstring Subsingleton}
{docstring Subsingleton.elim}
{docstring Subsingleton.helim}
# Visible Representations
%%%
draft := true
%%%
:::planned 135
* ToString
* xref to Repr section
* When to use {name}`Repr` vs {name}`ToString`
:::
{docstring ToString +allowMissing}
# Arithmetic and Bitwise Operators
{docstring Zero}
{docstring NeZero}
{docstring HAdd}
{docstring Add}
{docstring HSub}
{docstring Sub}
{docstring HMul}
{docstring SMul}
{docstring Mul}
{docstring HDiv}
{docstring Div}
{docstring Dvd}
{docstring HMod}
{docstring Mod}
{docstring HPow}
{docstring Pow}
{docstring NatPow}
{docstring HomogeneousPow}
{docstring HShiftLeft}
{docstring ShiftLeft}
{docstring HShiftRight}
{docstring ShiftRight}
{docstring Neg}
{docstring HAnd}
{docstring AndOp}
{docstring HOr}
{docstring OrOp}
{docstring HXor}
{docstring XorOp}
# Append
{docstring HAppend}
{docstring Append}
# Data Lookups
{docstring GetElem}
{docstring GetElem?}
{docstring LawfulGetElem}