@@ -100,6 +100,11 @@ Fin.foldrM n f xₙ = do
100100
101101/-! ### foldlM -/
102102
103+ @[congr] theorem foldlM_congr [Monad m] {n k : Nat} (w : n = k) (f : α → Fin n → m α) :
104+ foldlM n f = foldlM k (fun x i => f x (i.cast w.symm)) := by
105+ subst w
106+ rfl
107+
103108theorem foldlM_loop_lt [Monad m] (f : α → Fin n → m α) (x) (h : i < n) :
104109 foldlM.loop n f x i = f x ⟨i, h⟩ >>= (foldlM.loop n f . (i+1 )) := by
105110 rw [foldlM.loop, dif_pos h]
@@ -120,14 +125,49 @@ theorem foldlM_loop [Monad m] (f : α → Fin (n+1) → m α) (x) (h : i < n+1)
120125 rw [foldlM_loop_eq, foldlM_loop_eq]
121126termination_by n - i
122127
123- @[simp] theorem foldlM_zero [Monad m] (f : α → Fin 0 → m α) (x) : foldlM 0 f x = pure x :=
124- foldlM_loop_eq ..
128+ @[simp] theorem foldlM_zero [Monad m] (f : α → Fin 0 → m α) : foldlM 0 f = pure := by
129+ funext x
130+ exact foldlM_loop_eq ..
131+
132+ theorem foldlM_succ [Monad m] (f : α → Fin (n+1 ) → m α) :
133+ foldlM (n+1 ) f = fun x => f x 0 >>= foldlM n (fun x j => f x j.succ) := by
134+ funext x
135+ exact foldlM_loop ..
125136
126- theorem foldlM_succ [Monad m] (f : α → Fin (n+1 ) → m α) (x) :
127- foldlM (n+1 ) f x = f x 0 >>= foldlM n (fun x j => f x j.succ) := foldlM_loop ..
137+ /-- Variant of `foldlM_succ` that splits off `Fin.last n` rather than `0`. -/
138+ theorem foldlM_succ_last [Monad m] [LawfulMonad m] (f : α → Fin (n+1 ) → m α) :
139+ foldlM (n+1 ) f = fun x => foldlM n (fun x j => f x j.castSucc) x >>= (f · (Fin.last n)) := by
140+ funext x
141+ induction n generalizing x with
142+ | zero =>
143+ simp [foldlM_succ]
144+ | succ n ih =>
145+ rw [foldlM_succ]
146+ conv => rhs; rw [foldlM_succ]
147+ simp only [castSucc_zero, castSucc_succ, bind_assoc]
148+ congr 1
149+ funext x
150+ rw [ih]
151+ simp
152+
153+ theorem foldlM_add [Monad m] [LawfulMonad m] (f : α → Fin (n + k) → m α) :
154+ foldlM (n + k) f =
155+ fun x => foldlM n (fun x i => f x (i.castLE (Nat.le_add_right n k))) x >>= foldlM k (fun x i => f x (i.natAdd n)) := by
156+ induction k with
157+ | zero =>
158+ funext x
159+ simp
160+ | succ k ih =>
161+ funext x
162+ simp [foldlM_succ_last, ← Nat.add_assoc, ih]
128163
129164/-! ### foldrM -/
130165
166+ @[congr] theorem foldrM_congr [Monad m] {n k : Nat} (w : n = k) (f : Fin n → α → m α) :
167+ foldrM n f = foldrM k (fun i => f (i.cast w.symm)) := by
168+ subst w
169+ rfl
170+
131171theorem foldrM_loop_zero [Monad m] (f : Fin n → α → m α) (x) :
132172 foldrM.loop n f ⟨0 , Nat.zero_le _⟩ x = pure x := by
133173 rw [foldrM.loop]
@@ -145,19 +185,46 @@ theorem foldrM_loop [Monad m] [LawfulMonad m] (f : Fin (n+1) → α → m α) (x
145185 conv => rhs; rw [←bind_pure (f 0 x)]
146186 congr
147187 funext
148- try simp only [foldrM.loop] -- the try makes this proof work with and without opaque wf rec
149188 | succ i ih =>
150189 rw [foldrM_loop_succ, foldrM_loop_succ, bind_assoc]
151190 congr; funext; exact ih ..
152191
153- @[simp] theorem foldrM_zero [Monad m] (f : Fin 0 → α → m α) (x) : foldrM 0 f x = pure x :=
154- foldrM_loop_zero ..
192+ @[simp] theorem foldrM_zero [Monad m] (f : Fin 0 → α → m α) : foldrM 0 f = pure := by
193+ funext x
194+ exact foldrM_loop_zero ..
155195
156- theorem foldrM_succ [Monad m] [LawfulMonad m] (f : Fin (n+1 ) → α → m α) (x) :
157- foldrM (n+1 ) f x = foldrM n (fun i => f i.succ) x >>= f 0 := foldrM_loop ..
196+ theorem foldrM_succ [Monad m] [LawfulMonad m] (f : Fin (n+1 ) → α → m α) :
197+ foldrM (n+1 ) f = fun x => foldrM n (fun i => f i.succ) x >>= f 0 := by
198+ funext x
199+ exact foldrM_loop ..
200+
201+ theorem foldrM_succ_last [Monad m] [LawfulMonad m] (f : Fin (n+1 ) → α → m α) :
202+ foldrM (n+1 ) f = fun x => f (Fin.last n) x >>= foldrM n (fun i => f i.castSucc) := by
203+ funext x
204+ induction n generalizing x with
205+ | zero => simp [foldrM_succ]
206+ | succ n ih =>
207+ rw [foldrM_succ]
208+ conv => rhs; rw [foldrM_succ]
209+ simp [ih]
210+
211+ theorem foldrM_add [Monad m] [LawfulMonad m] (f : Fin (n + k) → α → m α) :
212+ foldrM (n + k) f =
213+ fun x => foldrM k (fun i => f (i.natAdd n)) x >>= foldrM n (fun i => f (i.castLE (Nat.le_add_right n k))) := by
214+ induction k with
215+ | zero =>
216+ simp
217+ | succ k ih =>
218+ funext x
219+ simp [foldrM_succ_last, ← Nat.add_assoc, ih]
158220
159221/-! ### foldl -/
160222
223+ @[congr] theorem foldl_congr {n k : Nat} (w : n = k) (f : α → Fin n → α) :
224+ foldl n f = foldl k (fun x i => f x (i.cast w.symm)) := by
225+ subst w
226+ rfl
227+
161228theorem foldl_loop_lt (f : α → Fin n → α) (x) (h : i < n) :
162229 foldl.loop n f x i = foldl.loop n f (f x ⟨i, h⟩) (i+1 ) := by
163230 rw [foldl.loop, dif_pos h]
@@ -187,14 +254,28 @@ theorem foldl_succ_last (f : α → Fin (n+1) → α) (x) :
187254 rw [foldl_succ]
188255 induction n generalizing x with
189256 | zero => simp [foldl_succ, Fin.last]
190- | succ n ih => rw [foldl_succ, ih (f · ·.succ), foldl_succ]; simp [succ_castSucc]
257+ | succ n ih => rw [foldl_succ, ih (f · ·.succ), foldl_succ]; simp
258+
259+ theorem foldl_add (f : α → Fin (n + m) → α) (x) :
260+ foldl (n + m) f x =
261+ foldl m (fun x i => f x (i.natAdd n))
262+ (foldl n (fun x i => f x (i.castLE (Nat.le_add_right n m))) x):= by
263+ induction m with
264+ | zero => simp
265+ | succ m ih => simp [foldl_succ_last, ih, ← Nat.add_assoc]
266+
191267
192268theorem foldl_eq_foldlM (f : α → Fin n → α) (x) :
193269 foldl n f x = foldlM (m:=Id) n f x := by
194270 induction n generalizing x <;> simp [foldl_succ, foldlM_succ, *]
195271
196272/-! ### foldr -/
197273
274+ @[congr] theorem foldr_congr {n k : Nat} (w : n = k) (f : Fin n → α → α) :
275+ foldr n f = foldr k (fun i => f (i.cast w.symm)) := by
276+ subst w
277+ rfl
278+
198279theorem foldr_loop_zero (f : Fin n → α → α) (x) :
199280 foldr.loop n f 0 (Nat.zero_le _) x = x := by
200281 rw [foldr.loop]
@@ -220,7 +301,15 @@ theorem foldr_succ_last (f : Fin (n+1) → α → α) (x) :
220301 foldr (n+1 ) f x = foldr n (f ·.castSucc) (f (last n) x) := by
221302 induction n generalizing x with
222303 | zero => simp [foldr_succ, Fin.last]
223- | succ n ih => rw [foldr_succ, ih (f ·.succ), foldr_succ]; simp [succ_castSucc]
304+ | succ n ih => rw [foldr_succ, ih (f ·.succ), foldr_succ]; simp
305+
306+ theorem foldr_add (f : Fin (n + m) → α → α) (x) :
307+ foldr (n + m) f x =
308+ foldr n (fun i => f (i.castLE (Nat.le_add_right n m)))
309+ (foldr m (fun i => f (i.natAdd n)) x) := by
310+ induction m generalizing x with
311+ | zero => simp
312+ | succ m ih => simp [foldr_succ_last, ih, ← Nat.add_assoc]
224313
225314theorem foldr_eq_foldrM (f : Fin n → α → α) (x) :
226315 foldr n f x = foldrM (m:=Id) n f x := by
0 commit comments