@@ -17,11 +17,24 @@ proofs about these definitions, those are contained in other files in `Mathlib.D
17
17
namespace List
18
18
19
19
/-- Split a list at an index.
20
- splitAt 2 [a, b, c] = ([a, b], [ c ] ) -/
20
+ ```
21
+ splitAt 2 [a, b, c] = ([a, b], [c])
22
+ ``` -/
21
23
def splitAt : ℕ → List α → List α × List α
22
24
| n+1 , x :: xs => let (l, r) := splitAt n xs; (x :: l, r)
23
25
| _, xs => ([], xs)
24
26
27
+ /-- Split a list at an index. Ensures the left list always has the specified length
28
+ by right padding with the provided default element.
29
+ ```
30
+ splitAtD 2 [a, b, c] x = ([a, b], [c])
31
+ splitAtD 4 [a, b, c] x = ([a, b, c, x], [])
32
+ ``` -/
33
+ def splitAtD : ℕ → List α → α → List α × List α
34
+ | 0 , xs, a => ([], xs)
35
+ | n+1 , [], a => let (l, r) := splitAtD n [] a; (a :: l, r)
36
+ | n+1 , x :: xs, a => let (l, r) := splitAtD n xs a; (x :: l, r)
37
+
25
38
/-- An auxiliary function for `splitOnP`. -/
26
39
def splitOnPAux {α : Type u} (P : α → Prop ) [DecidablePred P] : List α → (List α → List α) → List (List α)
27
40
| [], f => [f []]
@@ -32,13 +45,17 @@ def splitOnP {α : Type u} (P : α → Prop) [DecidablePred P] (l : List α) : L
32
45
splitOnPAux P l id
33
46
34
47
/-- Split a list at every occurrence of an element.
35
- [ 1,1,2,3,2,4,4 ] .split_on 2 = [ [1,1 ] ,[ 3 ] ,[ 4,4 ] ] -/
48
+ ```
49
+ [1,1,2,3,2,4,4].split_on 2 = [[1,1],[3],[4,4]]
50
+ ``` -/
36
51
def splitOn {α : Type u} [DecidableEq α] (a : α) (as : List α) : List (List α) :=
37
52
as.splitOnP (· = a)
38
53
39
54
/-- Apply a function to the nth tail of `l`. Returns the input without
40
55
using `f` if the index is larger than the length of the List.
41
- modifyNthTail f 2 [a, b, c] = [a, b] ++ f [ c ] -/
56
+ ```
57
+ modifyNthTail f 2 [a, b, c] = [a, b] ++ f [c]
58
+ ``` -/
42
59
@[simp]
43
60
def modifyNthTail (f : List α → List α) : ℕ → List α → List α
44
61
| 0 , l => f l
@@ -63,7 +80,9 @@ def modifyLast (f : α → α) : List α → List α
63
80
| x :: xs => x :: modifyLast f xs
64
81
65
82
/-- `insertNth n a l` inserts `a` into the list `l` after the first `n` elements of `l`
66
- `insertNth 2 1 [1, 2, 3, 4] = [1, 2, 1, 3, 4]`-/
83
+ ```
84
+ insertNth 2 1 [1, 2, 3, 4] = [1, 2, 1, 3, 4]
85
+ ``` -/
67
86
def insertNth (n : ℕ) (a : α) : List α → List α :=
68
87
modifyNthTail (cons a) n
69
88
@@ -75,7 +94,9 @@ def takeD : ∀ n : ℕ, List α → α → List α
75
94
76
95
/-- Fold a function `f` over the list from the left, returning the list
77
96
of partial results.
78
- scanl (+) 0 [1, 2, 3] = [0, 1, 3, 6] -/
97
+ ```
98
+ scanl (+) 0 [1, 2, 3] = [0, 1, 3, 6]
99
+ ``` -/
79
100
def scanl (f : α → β → α) : α → List β → List α
80
101
| a, [] => [a]
81
102
| a, b :: l => a :: scanl f (f a b) l
@@ -88,9 +109,10 @@ def scanrAux (f : α → β → β) (b : β) : List α → β × List β
88
109
let (b', l') := scanrAux f b l
89
110
(f a b', b' :: l')
90
111
91
- /-- Fold a function `f` over the list from the right, returning the list
92
- of partial results.
93
- scanr (+) 0 [1, 2, 3] = [6, 5, 3, 0] -/
112
+ /-- Fold a function `f` over the list from the right, returning the list of partial results.
113
+ ```
114
+ scanr (+) 0 [1, 2, 3] = [6, 5, 3, 0]
115
+ ``` -/
94
116
def scanr (f : α → β → β) (b : β) (l : List α) : List β :=
95
117
let (b', l') := scanrAux f b l
96
118
b' :: l'
@@ -142,10 +164,8 @@ def indexesValues (p : α → Prop) [DecidablePred p] (l : List α) : List (ℕ
142
164
foldrIdx (fun i a l => if p a then (i, a) :: l else l) [] l
143
165
144
166
/-- `indexesOf a l` is the list of all indexes of `a` in `l`. For example:
145
- ```
146
- indexesOf a [a, b, a, a] = [0, 2, 3]
147
- ```
148
- -/
167
+
168
+ indexesOf a [a, b, a, a] = [0, 2, 3] -/
149
169
def indexesOf [DecidableEq α] (a : α) : List α → List Nat :=
150
170
findIdxs (Eq a)
151
171
@@ -190,13 +210,17 @@ infixl:50 " <:+ " => isSuffix
190
210
infixl :50 " <:+: " => isInfix
191
211
192
212
/-- `inits l` is the list of initial segments of `l`.
193
- inits [1, 2, 3] = [ [ ] , [ 1 ] , [1, 2], [1, 2, 3]] -/
213
+ ```
214
+ inits [1, 2, 3] = [[], [1], [1, 2], [1, 2, 3]]
215
+ ``` -/
194
216
@[simp] def inits : List α → List (List α)
195
217
| [] => [[]]
196
218
| a :: l => [] :: map (fun t => a :: t) (inits l)
197
219
198
220
/-- `tails l` is the list of terminal segments of `l`.
199
- tails [1, 2, 3] = [[1, 2, 3], [2, 3], [ 3 ] , [ ] ] -/
221
+ ```
222
+ tails [1, 2, 3] = [[1, 2, 3], [2, 3], [3], []]
223
+ ``` -/
200
224
@[simp] def tails : List α → List (List α)
201
225
| [] => [[]]
202
226
| a :: l => (a :: l) :: tails l
@@ -209,7 +233,9 @@ def sublists'Aux : List α → (List α → List β) → List (List β) → List
209
233
It differs from `sublists` only in the order of appearance of the sublists;
210
234
`sublists'` uses the first element of the list as the MSB,
211
235
`sublists` uses the first element of the list as the LSB.
212
- sublists' [1, 2, 3] = [ [ ] , [ 3 ] , [ 2 ] , [2, 3], [ 1 ] , [1, 3], [1, 2], [1, 2, 3]] -/
236
+ ```
237
+ sublists' [1, 2, 3] = [[], [3], [2], [2, 3], [1], [1, 3], [1, 2], [1, 2, 3]]
238
+ ``` -/
213
239
def sublists' (l : List α) : List (List α) :=
214
240
sublists'Aux l id []
215
241
@@ -219,7 +245,9 @@ def sublistsAux : List α → (List α → List β → List β) → List β
219
245
220
246
/-- `sublists l` is the list of all (non-contiguous) sublists of `l`; cf. `sublists'`
221
247
for a different ordering.
222
- sublists [1, 2, 3] = [ [ ] , [ 1 ] , [ 2 ] , [1, 2], [ 3 ] , [1, 3], [2, 3], [1, 2, 3]] -/
248
+ ```
249
+ sublists [1, 2, 3] = [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
250
+ ``` -/
223
251
def sublists (l : List α) : List (List α) :=
224
252
[] :: sublistsAux l cons
225
253
@@ -252,7 +280,9 @@ def transposeAux : List α → List (List α) → List (List α)
252
280
| a :: i, l :: ls => (a :: l) :: transposeAux i ls
253
281
254
282
/-- transpose of a list of lists, treated as a matrix.
255
- transpose [[1, 2], [3, 4], [5, 6]] = [[1, 3, 5], [2, 4, 6]] -/
283
+ ```
284
+ transpose [[1, 2], [3, 4], [5, 6]] = [[1, 3, 5], [2, 4, 6]]
285
+ ``` -/
256
286
def transpose : List (List α) → List (List α)
257
287
| [] => []
258
288
| l :: ls => transposeAux l (transpose ls)
@@ -280,18 +310,23 @@ def extractp (p : α → Prop) [DecidablePred p] : List α → Option α × List
280
310
281
311
/-- `revzip l` returns a list of pairs of the elements of `l` paired
282
312
with the elements of `l` in reverse order.
283
- `revzip [1,2,3,4,5] = [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]`
284
- -/
313
+ ```
314
+ revzip [1,2,3,4,5] = [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]
315
+ ``` -/
285
316
def revzip (l : List α) : List (α × α) :=
286
317
zip l l.reverse
287
318
288
319
/-- `product l₁ l₂` is the list of pairs `(a, b)` where `a ∈ l₁` and `b ∈ l₂`.
289
- product [1, 2] [5, 6] = [(1, 5), (1, 6), (2, 5), (2, 6)] -/
320
+ ```
321
+ product [1, 2] [5, 6] = [(1, 5), (1, 6), (2, 5), (2, 6)]
322
+ ``` -/
290
323
def product (l₁ : List α) (l₂ : List β) : List (α × β) :=
291
324
l₁.bind $ fun a => l₂.map $ Prod.mk a
292
325
293
326
/-- `sigma l₁ l₂` is the list of dependent pairs `(a, b)` where `a ∈ l₁` and `b ∈ l₂ a`.
294
- sigma [1, 2] (λ_, [(5 : ℕ), 6]) = [(1, 5), (1, 6), (2, 5), (2, 6)] -/
327
+ ```
328
+ sigma [1, 2] (λ_, [(5 : ℕ), 6]) = [(1, 5), (1, 6), (2, 5), (2, 6)]
329
+ ``` -/
295
330
protected def sigma {σ : α → Type _} (l₁ : List α) (l₂ : ∀ a, List (σ a)) : List (Σ a, σ a) :=
296
331
l₁.bind $ fun a => (l₂ a).map $ Sigma.mk a
297
332
@@ -303,7 +338,9 @@ def ofFnAux {n} (f : Fin n → α) : ∀ m, m ≤ n → List α → List α
303
338
| m+1 , h, l => ofFnAux f m (Nat.le_of_lt h) (f ⟨m, h⟩ :: l)
304
339
305
340
/-- `ofFn f` with `f : fin n → α` returns the list whose ith element is `f i`
306
- `ofFn f = [f 0, f 1, ... , f(n - 1)]` -/
341
+ ```
342
+ ofFn f = [f 0, f 1, ... , f(n - 1)]
343
+ ``` -/
307
344
def ofFn {n} (f : Fin n → α) : List α :=
308
345
ofFnAux f n (Nat.le_refl _) []
309
346
@@ -347,13 +384,17 @@ section Chain
347
384
variable (R : α → α → Prop )
348
385
349
386
/-- `Chain R a l` means that `R` holds between adjacent elements of `a::l`.
350
- Chain R a [b, c, d] ↔ R a b ∧ R b c ∧ R c d -/
387
+ ```
388
+ Chain R a [b, c, d] ↔ R a b ∧ R b c ∧ R c d
389
+ ``` -/
351
390
inductive Chain : α → List α → Prop
352
391
| nil {a : α} : Chain a []
353
392
| cons : ∀ {a b : α} {l : List α}, R a b → Chain b l → Chain a (b :: l)
354
393
355
394
/-- `Chain' R l` means that `R` holds between adjacent elements of `l`.
356
- Chain' R [a, b, c, d] ↔ R a b ∧ R b c ∧ R c d -/
395
+ ```
396
+ Chain' R [a, b, c, d] ↔ R a b ∧ R b c ∧ R c d
397
+ ``` -/
357
398
def Chain' : List α → Prop
358
399
| [] => True
359
400
| a :: l => Chain R a l
@@ -367,7 +408,8 @@ def Nodup : List α → Prop :=
367
408
368
409
/-- `eraseDup l` removes duplicates from `l` (taking only the first occurrence).
369
410
Defined as `pwFilter (≠)`.
370
- eraseDup [1, 0, 2, 2, 1] = [0, 2, 1] -/
411
+
412
+ eraseDup [1, 0, 2, 2, 1] = [0, 2, 1] -/
371
413
def eraseDup [DecidableEq α] : List α → List α :=
372
414
pwFilter (· ≠ ·)
373
415
@@ -398,7 +440,9 @@ def last' {α} : List α → Option α
398
440
| b :: l => last' l
399
441
400
442
/-- `rotate l n` rotates the elements of `l` to the left by `n`
401
- rotate [0, 1, 2, 3, 4, 5] 2 = [2, 3, 4, 5, 0, 1] -/
443
+ ```
444
+ rotate [0, 1, 2, 3, 4, 5] 2 = [2, 3, 4, 5, 0, 1]
445
+ ``` -/
402
446
def rotate (l : List α) (n : ℕ) : List α :=
403
447
let (l₁, l₂) := List.splitAt (n % l.length) l
404
448
l₂ ++ l₁
@@ -431,9 +475,10 @@ def mmapFilter {m : Type → Type v} [Monad m] {α β} (f : α → m (Option β)
431
475
`mmapUpperTriangle f l` calls `f` on all elements in the upper triangular part of `l × l`.
432
476
That is, for each `e ∈ l`, it will run `f e e` and then `f e e'`
433
477
for each `e'` that appears after `e` in `l`.
434
- Example: suppose `l = [1, 2, 3]`. `mmapUpperTriangle f l` will produce the list
435
- `[f 1 1, f 1 2, f 1 3, f 2 2, f 2 3, f 3 3]`.
436
- -/
478
+ ```
479
+ mmapUpperTriangle f [1, 2, 3] =
480
+ return [← f 1 1, ← f 1 2, ← f 1 3, ← f 2 2, ← f 2 3, ← f 3 3]
481
+ ``` -/
437
482
def mmapUpperTriangle {m} [Monad m] {α β : Type u} (f : α → α → m β) : List α → m (List β)
438
483
| [] => pure []
439
484
| h :: t => return (← f h h) :: (← t.mmap (f h)) ++ (← t.mmapUpperTriangle f)
@@ -442,9 +487,9 @@ def mmapUpperTriangle {m} [Monad m] {α β : Type u} (f : α → α → m β) :
442
487
`mmap'Diag f l` calls `f` on all elements in the upper triangular part of `l × l`.
443
488
That is, for each `e ∈ l`, it will run `f e e` and then `f e e'`
444
489
for each `e'` that appears after `e` in `l`.
445
- Example: suppose `l = [1, 2, 3]`. `mmap'Diag f l` will evaluate, in this order,
446
- `f 1 1`, ` f 1 2`, ` f 1 3`, ` f 2 2`, ` f 2 3`, ` f 3 3`.
447
- -/
490
+ ```
491
+ mmap'Diag f [1, 2, 3] = do f 1 1; f 1 2; f 1 3; f 2 2; f 2 3; f 3 3
492
+ ``` -/
448
493
def mmap'Diag {m} [Monad m] {α} (f : α → α → m Unit) : List α → m Unit
449
494
| [] => return ()
450
495
| h :: t => do f h h; t.mmap' (f h); t.mmap'Diag f
0 commit comments