40 lines
1.6 KiB
Text
40 lines
1.6 KiB
Text
example {α β : Type} {f : α × β → β → β} (h : ∀ p : α × β, f p p.2 = p.2)
|
||
(a : α) (b : β) : f (a, b) b = b := by
|
||
simp [h] -- should not fail
|
||
|
||
example {α β : Type} {f : α × β → β → β}
|
||
(a : α) (b : β) (h : f (a,b) (a,b).2 = (a,b).2) : f (a, b) b = b := by
|
||
simp [h] -- should not fail
|
||
|
||
def enumFromTR' (n : Nat) (l : List α) : List (Nat × α) :=
|
||
let arr := l.toArray
|
||
(arr.foldr (fun a (n, acc) => (n-1, (n-1, a) :: acc)) (n + arr.size, [])).2
|
||
|
||
def enumFrom : Nat → List α → List (Nat × α)
|
||
| _, [] => []
|
||
| n, x :: xs => (n, x) :: enumFrom (n + 1) xs
|
||
|
||
open List in
|
||
theorem enumFrom_eq_enumFromTR' : @enumFrom = @enumFromTR' := by
|
||
funext α n l; simp only [enumFromTR']
|
||
let f := fun (a : α) (n, acc) => (n-1, (n-1, a) :: acc)
|
||
let rec go : ∀ l n, l.foldr f (n + l.length, []) = (n, enumFrom n l)
|
||
| [], n => rfl
|
||
| a::as, n => by
|
||
rw [← show _ + as.length = n + (a::as).length from Nat.succ_add .., List.foldr, go as]
|
||
simp [enumFrom, f]
|
||
rw [←Array.foldr_toList]
|
||
simp [f] at go -- We must unfold `f` at `go`, or use `+zetaDelta`. See next theorem
|
||
simp [go]
|
||
|
||
open List in
|
||
theorem enumFrom_eq_enumFromTR'' : @enumFrom = @enumFromTR' := by
|
||
funext α n l; simp only [enumFromTR']
|
||
let f := fun (a : α) (n, acc) => (n-1, (n-1, a) :: acc)
|
||
let rec go : ∀ l n, l.foldr f (n + l.length, []) = (n, enumFrom n l)
|
||
| [], n => rfl
|
||
| a::as, n => by
|
||
rw [← show _ + as.length = n + (a::as).length from Nat.succ_add .., List.foldr, go as]
|
||
simp [enumFrom, f]
|
||
rw [←Array.foldr_toList]
|
||
simp +zetaDelta [go]
|