Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: adaptations for nightly-2024-11-12 #1040

Merged
merged 33 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4adcb48
bump toolchain
kim-em Nov 4, 2024
a65a608
remove upstreamed
kim-em Nov 4, 2024
6df8458
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 4, 2024
3fca5be
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 5, 2024
d9e997f
Update lean-toolchain for testing https://github.com/leanprover/lean4…
leanprover-community-mathlib4-bot Nov 7, 2024
a7da4ba
bump toolchain and remove upstreamed
kim-em Nov 7, 2024
cd5fdf2
chore: bump to nightly-2024-11-08
leanprover-community-mathlib4-bot Nov 8, 2024
774ecca
chore: bump to nightly-2024-11-10
leanprover-community-mathlib4-bot Nov 10, 2024
91cce7f
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 10, 2024
a134655
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 10, 2024
32e391e
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 10, 2024
a4deb1e
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 10, 2024
e426f06
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 11, 2024
4fbc598
fixes for leanprover/lean4#5988
kim-em Nov 11, 2024
8dfd1e4
Trigger CI for https://github.com/leanprover/lean4/pull/5988
leanprover-community-mathlib4-bot Nov 11, 2024
db9926e
Trigger CI for https://github.com/leanprover/lean4/pull/5988
leanprover-community-mathlib4-bot Nov 11, 2024
1189492
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 11, 2024
4334297
chore: bump to nightly-2024-11-11
leanprover-community-mathlib4-bot Nov 11, 2024
4a4f127
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 12, 2024
03b1b75
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 12, 2024
3cf3e5e
chore: bump to nightly-2024-11-12
leanprover-community-mathlib4-bot Nov 12, 2024
a481537
merge lean-pr-testing-5988
kim-em Nov 12, 2024
007f1b1
fixes
kim-em Nov 12, 2024
322fd44
comment out UnionFind so I can fix Mathlib
kim-em Nov 12, 2024
eedab89
.
kim-em Nov 12, 2024
9ba2e12
.
kim-em Nov 12, 2024
d69cd4d
fix test
kim-em Nov 12, 2024
6b3f877
fix long lines
kim-em Nov 12, 2024
cba57c9
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 12, 2024
1459344
uncomment UnionFind
digama0 Nov 12, 2024
72c9c10
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 12, 2024
1ef59a8
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 12, 2024
65594b6
Merge main into nightly-testing
leanprover-community-mathlib4-bot Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Batteries/Data/Array/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ considered.
protected def minD [ord : Ord α]
(xs : Array α) (d : α) (start := 0) (stop := xs.size) : α :=
if h: start < xs.size ∧ start < stop then
xs.minWith (xs.get ⟨start, h.left⟩) (start + 1) stop
xs.minWith xs[start] (start + 1) stop
else
d

Expand All @@ -60,7 +60,7 @@ considered.
protected def min? [ord : Ord α]
(xs : Array α) (start := 0) (stop := xs.size) : Option α :=
if h : start < xs.size ∧ start < stop then
some $ xs.minD (xs.get ⟨start, h.left⟩) start stop
some $ xs.minD xs[start] start stop
else
none

Expand Down Expand Up @@ -135,7 +135,7 @@ A proof by `get_elem_tactic` is provided as a default argument for `h`.
This will perform the update destructively provided that `a` has a reference count of 1 when called.
-/
abbrev setN (a : Array α) (i : Nat) (x : α) (h : i < a.size := by get_elem_tactic) : Array α :=
a.set ⟨i, h⟩ x
a.set i x

/--
`swapN a i j hi hj` swaps two `Nat` indexed entries in an `Array α`.
Expand Down Expand Up @@ -201,7 +201,7 @@ subarray, or `none` if the subarray is empty.
def popHead? (as : Subarray α) : Option (α × Subarray α) :=
if h : as.start < as.stop
then
let head := as.array.get ⟨as.start, Nat.lt_of_lt_of_le h as.stop_le_array_size
let head := as.array[as.start]'(Nat.lt_of_lt_of_le h as.stop_le_array_size)
let tail :=
{ as with
start := as.start + 1
Expand Down
48 changes: 0 additions & 48 deletions Batteries/Data/Array/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -22,61 +22,13 @@ theorem forIn_eq_forIn_toList [Monad m]

/-! ### zipWith / zip -/

theorem toList_zipWith (f : α → β → γ) (as : Array α) (bs : Array β) :
(as.zipWith bs f).toList = as.toList.zipWith f bs.toList := by
let rec loop : ∀ (i : Nat) cs, i ≤ as.size → i ≤ bs.size →
(zipWithAux f as bs i cs).toList =
cs.toList ++ (as.toList.drop i).zipWith f (bs.toList.drop i) := by
intro i cs hia hib
unfold zipWithAux
by_cases h : i = as.size ∨ i = bs.size
case pos =>
have : ¬(i < as.size) ∨ ¬(i < bs.size) := by
cases h <;> simp_all only [Nat.not_lt, Nat.le_refl, true_or, or_true]
-- Cleaned up aesop output below
simp_all only [Nat.not_lt]
cases h <;> [(cases this); (cases this)]
· simp_all only [Nat.le_refl, Nat.lt_irrefl, dite_false, List.drop_length,
List.zipWith_nil_left, List.append_nil]
· simp_all only [Nat.le_refl, Nat.lt_irrefl, dite_false, List.drop_length,
List.zipWith_nil_left, List.append_nil]
· simp_all only [Nat.le_refl, Nat.lt_irrefl, dite_false, List.drop_length,
List.zipWith_nil_right, List.append_nil]
split <;> simp_all only [Nat.not_lt]
· simp_all only [Nat.le_refl, Nat.lt_irrefl, dite_false, List.drop_length,
List.zipWith_nil_right, List.append_nil]
split <;> simp_all only [Nat.not_lt]
case neg =>
rw [not_or] at h
have has : i < as.size := Nat.lt_of_le_of_ne hia h.1
have hbs : i < bs.size := Nat.lt_of_le_of_ne hib h.2
simp only [has, hbs, dite_true]
rw [loop (i+1) _ has hbs, Array.push_toList]
have h₁ : [f as[i] bs[i]] = List.zipWith f [as[i]] [bs[i]] := rfl
let i_as : Fin as.toList.length := ⟨i, has⟩
let i_bs : Fin bs.toList.length := ⟨i, hbs⟩
rw [h₁, List.append_assoc]
congr
rw [← List.zipWith_append (h := by simp), getElem_eq_getElem_toList,
getElem_eq_getElem_toList]
show List.zipWith f (as.toList[i_as] :: List.drop (i_as + 1) as.toList)
((List.get bs.toList i_bs) :: List.drop (i_bs + 1) bs.toList) =
List.zipWith f (List.drop i as.toList) (List.drop i bs.toList)
simp only [length_toList, Fin.getElem_fin, List.getElem_cons_drop, List.get_eq_getElem]
simp [zipWith, loop 0 #[] (by simp) (by simp)]
@[deprecated (since := "2024-09-09")] alias data_zipWith := toList_zipWith
@[deprecated (since := "2024-08-13")] alias zipWith_eq_zipWith_data := data_zipWith

@[simp] theorem size_zipWith (as : Array α) (bs : Array β) (f : α → β → γ) :
(as.zipWith bs f).size = min as.size bs.size := by
rw [size_eq_length_toList, toList_zipWith, List.length_zipWith]

theorem toList_zip (as : Array α) (bs : Array β) :
(as.zip bs).toList = as.toList.zip bs.toList :=
toList_zipWith Prod.mk as bs
@[deprecated (since := "2024-09-09")] alias data_zip := toList_zip
@[deprecated (since := "2024-08-13")] alias zip_eq_zip_data := data_zip

@[simp] theorem size_zip (as : Array α) (bs : Array β) :
(as.zip bs).size = min as.size bs.size :=
as.size_zipWith bs Prod.mk
Expand Down
2 changes: 1 addition & 1 deletion Batteries/Data/Array/Merge.lean
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ set_option linter.unusedVariables.funArgs false in
`f ⋯ (f (f x₁ x₂) x₃) ⋯ xₙ`.
-/
def mergeAdjacentDups [eq : BEq α] (f : α → α → α) (xs : Array α) : Array α :=
if h : 0 < xs.size then go (mkEmpty xs.size) 1 (xs.get ⟨0, h⟩) else xs
if h : 0 < xs.size then go (mkEmpty xs.size) 1 xs[0] else xs
where
/-- Auxiliary definition for `mergeAdjacentDups`. -/
go (acc : Array α) (i : Nat) (hd : α) :=
Expand Down
2 changes: 1 addition & 1 deletion Batteries/Data/Array/Monadic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ theorem SatisfiesM_mapIdxM [Monad m] [LawfulMonad m] (as : Array α) (f : Nat
(hs : ∀ i, motive i.1 → SatisfiesM (p i · ∧ motive (i + 1)) (f i as[i])) :
SatisfiesM
(fun arr => motive as.size ∧ ∃ eq : arr.size = as.size, ∀ i h, p ⟨i, h⟩ arr[i])
(Array.mapIdxM as f) :=
(as.mapIdxM f) :=
SatisfiesM_mapFinIdxM as (fun i => f i) motive h0 p hs

theorem size_modifyM [Monad m] [LawfulMonad m] (a : Array α) (i : Nat) (f : α → m α) :
Expand Down
4 changes: 0 additions & 4 deletions Batteries/Data/Array/OfFn.lean
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,4 @@ namespace Array

/-! ### ofFn -/

@[simp]
theorem toList_ofFn (f : Fin n → α) : (ofFn f).toList = List.ofFn f := by
apply ext_getElem <;> simp

end Array
2 changes: 1 addition & 1 deletion Batteries/Data/Array/Pairwise.lean
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ that `as` is strictly sorted and `as.Pairwise (· ≤ ·)` asserts that `as` is
def Pairwise (R : α → α → Prop) (as : Array α) : Prop := as.toList.Pairwise R

theorem pairwise_iff_get {as : Array α} : as.Pairwise R ↔
∀ (i j : Fin as.size), i < j → R (as.get i) (as.get j) := by
∀ (i j : Fin as.size), i < j → R (as.get i i.2) (as.get j j.2) := by
unfold Pairwise; simp [List.pairwise_iff_get, getElem_fin_eq_getElem_toList]

theorem pairwise_iff_getElem {as : Array α} : as.Pairwise R ↔
Expand Down
2 changes: 1 addition & 1 deletion Batteries/Data/BinaryHeap.lean
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def size (self : BinaryHeap α lt) : Nat := self.1.size
def vector (self : BinaryHeap α lt) : Vector α self.size := ⟨self.1, rfl⟩

/-- `O(1)`. Get an element in the heap by index. -/
def get (self : BinaryHeap α lt) (i : Fin self.size) : α := self.1.get i
def get (self : BinaryHeap α lt) (i : Fin self.size) : α := self.1[i]'(i.2)

/-- `O(log n)`. Insert an element into a `BinaryHeap`, preserving the max-heap property. -/
def insert (self : BinaryHeap α lt) (x : α) : BinaryHeap α lt where
Expand Down
8 changes: 4 additions & 4 deletions Batteries/Data/ByteArray.lean
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ theorem getElem_eq_data_getElem (a : ByteArray) (h : i < a.size) : a[i] = a.data
/-! ### uget/uset -/

@[simp] theorem uset_eq_set (a : ByteArray) {i : USize} (h : i.toNat < a.size) (v : UInt8) :
a.uset i v h = a.set i.toNat, h⟩ v := rfl
a.uset i v h = a.set i.toNat v := rfl

/-! ### empty -/

Expand Down Expand Up @@ -45,7 +45,7 @@ theorem get_push_lt (a : ByteArray) (x : UInt8) (i : Nat) (h : i < a.size) :
/-! ### set -/

@[simp] theorem data_set (a : ByteArray) (i : Fin a.size) (v : UInt8) :
(a.set i v).data = a.data.set i v := rfl
(a.set i v).data = a.data.set i v i.isLt := rfl
@[deprecated (since := "2024-08-13")] alias set_data := data_set

@[simp] theorem size_set (a : ByteArray) (i : Fin a.size) (v : UInt8) :
Expand All @@ -60,7 +60,7 @@ theorem get_set_ne (a : ByteArray) (i : Fin a.size) (v : UInt8) (hj : j < a.size
Array.get_set_ne (h:=h) ..

theorem set_set (a : ByteArray) (i : Fin a.size) (v v' : UInt8) :
(a.set i v).set ⟨i, by simp [i.2]⟩ v' = a.set i v' :=
(a.set i v).set i v' = a.set i v' :=
ByteArray.ext <| Array.set_set ..

/-! ### copySlice -/
Expand Down Expand Up @@ -132,7 +132,7 @@ def ofFn (f : Fin n → UInt8) : ByteArray where
simp [get, Fin.cast]

@[simp] theorem getElem_ofFn (f : Fin n → UInt8) (i) (h : i < (ofFn f).size) :
(ofFn f)[i] = f ⟨i, size_ofFn f ▸ h⟩ := get_ofFn ..
(ofFn f)[i] = f ⟨i, size_ofFn f ▸ h⟩ := get_ofFn f ⟨i, h⟩

private def ofFnAux (f : Fin n → UInt8) : ByteArray := go 0 (mkEmpty n) where
go (i : Nat) (acc : ByteArray) : ByteArray :=
Expand Down
54 changes: 0 additions & 54 deletions Batteries/Data/Fin/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,3 @@ def enum (n) : Array (Fin n) := Array.ofFn id

/-- `list n` is the list of all elements of `Fin n` in order -/
def list (n) : List (Fin n) := (enum n).toList

/--
Folds a monadic function over `Fin n` from left to right:
```
Fin.foldlM n f x₀ = do
let x₁ ← f x₀ 0
let x₂ ← f x₁ 1
...
let xₙ ← f xₙ₋₁ (n-1)
pure xₙ
```
-/
@[inline] def foldlM [Monad m] (n) (f : α → Fin n → m α) (init : α) : m α := loop init 0 where
/--
Inner loop for `Fin.foldlM`.
```
Fin.foldlM.loop n f xᵢ i = do
let xᵢ₊₁ ← f xᵢ i
...
let xₙ ← f xₙ₋₁ (n-1)
pure xₙ
```
-/
loop (x : α) (i : Nat) : m α := do
if h : i < n then f x ⟨i, h⟩ >>= (loop · (i+1)) else pure x
termination_by n - i

/--
Folds a monadic function over `Fin n` from right to left:
```
Fin.foldrM n f xₙ = do
let xₙ₋₁ ← f (n-1) xₙ
let xₙ₋₂ ← f (n-2) xₙ₋₁
...
let x₀ ← f 0 x₁
pure x₀
```
-/
@[inline] def foldrM [Monad m] (n) (f : Fin n → α → m α) (init : α) : m α :=
loop ⟨n, Nat.le_refl n⟩ init where
/--
Inner loop for `Fin.foldrM`.
```
Fin.foldrM.loop n f i xᵢ = do
let xᵢ₋₁ ← f (i-1) xᵢ
...
let x₁ ← f 1 x₂
let x₀ ← f 0 x₁
pure x₀
```
-/
loop : {i // i ≤ n} → α → m α
| ⟨0, _⟩, x => pure x
| ⟨i+1, h⟩, x => f ⟨i, h⟩ x >>= loop ⟨i, Nat.le_of_lt h⟩
128 changes: 0 additions & 128 deletions Batteries/Data/Fin/Lemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,6 @@ theorem list_reverse (n) : (list n).reverse = (list n).map rev := by

/-! ### foldlM -/

theorem foldlM_loop_lt [Monad m] (f : α → Fin n → m α) (x) (h : i < n) :
foldlM.loop n f x i = f x ⟨i, h⟩ >>= (foldlM.loop n f . (i+1)) := by
rw [foldlM.loop, dif_pos h]

theorem foldlM_loop_eq [Monad m] (f : α → Fin n → m α) (x) : foldlM.loop n f x n = pure x := by
rw [foldlM.loop, dif_neg (Nat.lt_irrefl _)]

theorem foldlM_loop [Monad m] (f : α → Fin (n+1) → m α) (x) (h : i < n+1) :
foldlM.loop (n+1) f x i = f x ⟨i, h⟩ >>= (foldlM.loop n (fun x j => f x j.succ) . i) := by
if h' : i < n then
rw [foldlM_loop_lt _ _ h]
congr; funext
rw [foldlM_loop_lt _ _ h', foldlM_loop]; rfl
else
cases Nat.le_antisymm (Nat.le_of_lt_succ h) (Nat.not_lt.1 h')
rw [foldlM_loop_lt]
congr; funext
rw [foldlM_loop_eq, foldlM_loop_eq]
termination_by n - i

@[simp] theorem foldlM_zero [Monad m] (f : α → Fin 0 → m α) (x) : foldlM 0 f x = pure x :=
foldlM_loop_eq ..

theorem foldlM_succ [Monad m] (f : α → Fin (n+1) → m α) (x) :
foldlM (n+1) f x = f x 0 >>= foldlM n (fun x j => f x j.succ) := foldlM_loop ..

theorem foldlM_eq_foldlM_list [Monad m] (f : α → Fin n → m α) (x) :
foldlM n f x = (list n).foldlM f x := by
induction n generalizing x with
Expand All @@ -93,32 +67,6 @@ theorem foldlM_eq_foldlM_list [Monad m] (f : α → Fin n → m α) (x) :

/-! ### foldrM -/

theorem foldrM_loop_zero [Monad m] (f : Fin n → α → m α) (x) :
foldrM.loop n f ⟨0, Nat.zero_le _⟩ x = pure x := by
rw [foldrM.loop]

theorem foldrM_loop_succ [Monad m] (f : Fin n → α → m α) (x) (h : i < n) :
foldrM.loop n f ⟨i+1, h⟩ x = f ⟨i, h⟩ x >>= foldrM.loop n f ⟨i, Nat.le_of_lt h⟩ := by
rw [foldrM.loop]

theorem foldrM_loop [Monad m] [LawfulMonad m] (f : Fin (n+1) → α → m α) (x) (h : i+1 ≤ n+1) :
foldrM.loop (n+1) f ⟨i+1, h⟩ x =
foldrM.loop n (fun j => f j.succ) ⟨i, Nat.le_of_succ_le_succ h⟩ x >>= f 0 := by
induction i generalizing x with
| zero =>
rw [foldrM_loop_zero, foldrM_loop_succ, pure_bind]
conv => rhs; rw [←bind_pure (f 0 x)]
congr; funext; exact foldrM_loop_zero ..
| succ i ih =>
rw [foldrM_loop_succ, foldrM_loop_succ, bind_assoc]
congr; funext; exact ih ..

@[simp] theorem foldrM_zero [Monad m] (f : Fin 0 → α → m α) (x) : foldrM 0 f x = pure x :=
foldrM_loop_zero ..

theorem foldrM_succ [Monad m] [LawfulMonad m] (f : Fin (n+1) → α → m α) (x) :
foldrM (n+1) f x = foldrM n (fun i => f i.succ) x >>= f 0 := foldrM_loop ..

theorem foldrM_eq_foldrM_list [Monad m] [LawfulMonad m] (f : Fin n → α → m α) (x) :
foldrM n f x = (list n).foldrM f x := by
induction n with
Expand All @@ -127,90 +75,14 @@ theorem foldrM_eq_foldrM_list [Monad m] [LawfulMonad m] (f : Fin n → α → m

/-! ### foldl -/

theorem foldl_loop_lt (f : α → Fin n → α) (x) (h : i < n) :
foldl.loop n f x i = foldl.loop n f (f x ⟨i, h⟩) (i+1) := by
rw [foldl.loop, dif_pos h]

theorem foldl_loop_eq (f : α → Fin n → α) (x) : foldl.loop n f x n = x := by
rw [foldl.loop, dif_neg (Nat.lt_irrefl _)]

theorem foldl_loop (f : α → Fin (n+1) → α) (x) (h : i < n+1) :
foldl.loop (n+1) f x i = foldl.loop n (fun x j => f x j.succ) (f x ⟨i, h⟩) i := by
if h' : i < n then
rw [foldl_loop_lt _ _ h]
rw [foldl_loop_lt _ _ h', foldl_loop]; rfl
else
cases Nat.le_antisymm (Nat.le_of_lt_succ h) (Nat.not_lt.1 h')
rw [foldl_loop_lt]
rw [foldl_loop_eq, foldl_loop_eq]

@[simp] theorem foldl_zero (f : α → Fin 0 → α) (x) : foldl 0 f x = x :=
foldl_loop_eq ..

theorem foldl_succ (f : α → Fin (n+1) → α) (x) :
foldl (n+1) f x = foldl n (fun x i => f x i.succ) (f x 0) :=
foldl_loop ..

theorem foldl_succ_last (f : α → Fin (n+1) → α) (x) :
foldl (n+1) f x = f (foldl n (f · ·.castSucc) x) (last n) := by
rw [foldl_succ]
induction n generalizing x with
| zero => simp [foldl_succ, Fin.last]
| succ n ih => rw [foldl_succ, ih (f · ·.succ), foldl_succ]; simp [succ_castSucc]

theorem foldl_eq_foldlM (f : α → Fin n → α) (x) :
foldl n f x = foldlM (m:=Id) n f x := by
induction n generalizing x <;> simp [foldl_succ, foldlM_succ, *]

theorem foldl_eq_foldl_list (f : α → Fin n → α) (x) : foldl n f x = (list n).foldl f x := by
induction n generalizing x with
| zero => rw [foldl_zero, list_zero, List.foldl_nil]
| succ n ih => rw [foldl_succ, ih, list_succ, List.foldl_cons, List.foldl_map]

/-! ### foldr -/

theorem foldr_loop_zero (f : Fin n → α → α) (x) :
foldr.loop n f ⟨0, Nat.zero_le _⟩ x = x := by
rw [foldr.loop]

theorem foldr_loop_succ (f : Fin n → α → α) (x) (h : i < n) :
foldr.loop n f ⟨i+1, h⟩ x = foldr.loop n f ⟨i, Nat.le_of_lt h⟩ (f ⟨i, h⟩ x) := by
rw [foldr.loop]

theorem foldr_loop (f : Fin (n+1) → α → α) (x) (h : i+1 ≤ n+1) :
foldr.loop (n+1) f ⟨i+1, h⟩ x =
f 0 (foldr.loop n (fun j => f j.succ) ⟨i, Nat.le_of_succ_le_succ h⟩ x) := by
induction i generalizing x <;> simp [foldr_loop_zero, foldr_loop_succ, *]

@[simp] theorem foldr_zero (f : Fin 0 → α → α) (x) : foldr 0 f x = x :=
foldr_loop_zero ..

theorem foldr_succ (f : Fin (n+1) → α → α) (x) :
foldr (n+1) f x = f 0 (foldr n (fun i => f i.succ) x) := foldr_loop ..

theorem foldr_succ_last (f : Fin (n+1) → α → α) (x) :
foldr (n+1) f x = foldr n (f ·.castSucc) (f (last n) x) := by
induction n generalizing x with
| zero => simp [foldr_succ, Fin.last]
| succ n ih => rw [foldr_succ, ih (f ·.succ), foldr_succ]; simp [succ_castSucc]

theorem foldr_eq_foldrM (f : Fin n → α → α) (x) :
foldr n f x = foldrM (m:=Id) n f x := by
induction n <;> simp [foldr_succ, foldrM_succ, *]

theorem foldr_eq_foldr_list (f : Fin n → α → α) (x) : foldr n f x = (list n).foldr f x := by
induction n with
| zero => rw [foldr_zero, list_zero, List.foldr_nil]
| succ n ih => rw [foldr_succ, ih, list_succ, List.foldr_cons, List.foldr_map]

theorem foldl_rev (f : Fin n → α → α) (x) :
foldl n (fun x i => f i.rev x) x = foldr n f x := by
induction n generalizing x with
| zero => simp
| succ n ih => rw [foldl_succ, foldr_succ_last, ← ih]; simp [rev_succ]

theorem foldr_rev (f : α → Fin n → α) (x) :
foldr n (fun i x => f x i.rev) x = foldl n f x := by
induction n generalizing x with
| zero => simp
| succ n ih => rw [foldl_succ_last, foldr_succ, ← ih]; simp [rev_succ]
Loading