Skip to content

Commit edeff06

Browse files
authored
prove a bunch in sigma.lean
1 parent 646fb08 commit edeff06

1 file changed

Lines changed: 102 additions & 32 deletions

File tree

ArkLib/Data/Fin/Sigma.lean

Lines changed: 102 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,22 @@ theorem embedSum_succ_zero {n : Fin (m + 1) → ℕ} {j : Fin (n 0)} :
107107
theorem embedSum_succ_succ {n : Fin (m + 1) → ℕ} {i : Fin m} (j : Fin (n i.succ)) :
108108
embedSum (i.succ) j = Fin.natAdd _ (embedSum i j) := rfl
109109

110+
/-- The underlying value of `embedSum i j` is the sum of `n` over all indices before `i`,
111+
plus the value of `j`. -/
112+
theorem val_embedSum {m : ℕ} {n : Fin m → ℕ} (i : Fin m) (j : Fin (n i)) :
113+
(embedSum i j).val = (∑ i' : Fin i.val, n (castLE i.isLt.le i')) + j.val := by
114+
induction m with
115+
| zero => exact Fin.elim0 i
116+
| succ m ih =>
117+
induction i using Fin.cases with
118+
| zero => simp
119+
| succ i =>
120+
have key : (∑ i' : Fin i.succ.val, n (castLE i.succ.isLt.le i'))
121+
= n 0 + ∑ i' : Fin i.val, n ((castLE i.isLt.le i').succ) :=
122+
Fin.sum_univ_succ (fun i' : Fin (i.val + 1) => n (castLE i.succ.isLt.le i'))
123+
rw [embedSum_succ_succ, val_natAdd, ih (n := fun i => n i.succ) i j]
124+
omega
125+
110126
/-- Split a vector sum index `k : Fin (vsum n)` into nested indices `(i : Fin m) × Fin (n i)`.
111127
This converts from indexing into the vector sum back to nested indexing, inverse of `embedSum`. -/
112128
def splitSum {m : ℕ} {n : Fin m → ℕ} (k : Fin (vsum n)) : (i : Fin m) × Fin (n i) := match m with
@@ -253,16 +269,6 @@ theorem vflatten_one {n : Fin 1 → ℕ} {v : (i : Fin 1) → Fin (n i) → α}
253269
theorem vflatten_two_eq_append {n : Fin 2 → ℕ} {v : (i : Fin 2) → Fin (n i) → α} :
254270
vflatten v = vappend (v 0) (v 1) := rfl
255271

256-
theorem vflatten_eq_vappend_last {m : ℕ} {n : Fin (m + 1) → ℕ}
257-
{v : (i : Fin (m + 1)) → Fin (n i) → α} :
258-
vflatten v =
259-
vappend (vflatten (fun i => v i.castSucc)) (v (last _)) ∘ Fin.cast vsum_castSucc := by
260-
induction m with
261-
| zero => ext i; simp
262-
| succ m ih =>
263-
rw [vflatten_succ, ih, vflatten_succ]
264-
sorry
265-
266272
@[simp]
267273
theorem vflatten_splitSum {m : ℕ} {n : Fin m → ℕ} (v : (k : Fin (vsum n)) → α) (k : Fin (vsum n)) :
268274
vflatten (fun i j => v (embedSum i j)) k = v k :=
@@ -273,6 +279,33 @@ theorem vflatten_embedSum {m : ℕ} {n : Fin m → ℕ} (v : (i : Fin m) → Fin
273279
(j : Fin (n i)) : vflatten v (embedSum i j) = v i j :=
274280
dflatten_embedSum (motive := fun _ => α) v i j
275281

282+
theorem vflatten_eq_vappend_last {m : ℕ} {n : Fin (m + 1) → ℕ}
283+
{v : (i : Fin (m + 1)) → Fin (n i) → α} :
284+
vflatten v =
285+
vappend (vflatten (fun i => v i.castSucc)) (v (last _)) ∘ Fin.cast vsum_castSucc := by
286+
funext k
287+
have hk : embedSum (splitSum k).1 (splitSum k).2 = k := embedSum_splitSum k
288+
rcases hs : splitSum k with ⟨i, j⟩
289+
rw [hs] at hk
290+
clear hs
291+
subst hk
292+
dsimp only
293+
rw [vflatten_embedSum, Function.comp_apply]
294+
induction i using Fin.lastCases with
295+
| last =>
296+
refine (vappend_right (vflatten fun i => v i.castSucc) (v (last m)) j).symm.trans ?_
297+
congr 1
298+
apply Fin.ext
299+
simp only [Fin.val_natAdd, Fin.val_cast, val_embedSum, Fin.val_last, vsum_eq_univ_sum]
300+
rfl
301+
| cast i =>
302+
refine (vflatten_embedSum (fun i => v i.castSucc) i j).symm.trans ?_
303+
rw [← vappend_left (vflatten fun i => v i.castSucc) (v (last m)) (embedSum i j)]
304+
congr 1
305+
apply Fin.ext
306+
simp only [Fin.val_castAdd, Fin.val_cast, val_embedSum, Fin.val_castSucc]
307+
rfl
308+
276309
/-- Functorial flatten: flattens a nested heterogeneous tuple
277310
`(i : Fin m) → (j : Fin (n i)) → F (α i j)` into a single heterogeneous tuple with type
278311
`(k : Fin (vsum n)) → F (vflatten α k)` where `vflatten` operates on the vector of types `α`.
@@ -309,13 +342,6 @@ theorem fflatten_two_eq_append {A : Sort u} {F : A → Sort v} {n : Fin 2 →
309342
{v : (i : Fin 2) → (j : Fin (n i)) → F (α i j)} :
310343
fflatten v = fappend (F := F) (v 0) (v 1) := rfl
311344

312-
@[simp]
313-
theorem fflatten_splitSum {A : Sort u} {F : A → Sort v} {m : ℕ} {n : Fin m → ℕ}
314-
{α : (i : Fin (vsum n)) → A}
315-
(v : (k : Fin (vsum n)) → F (α k)) (k : Fin (vsum n)) :
316-
fflatten (fun i j => v (embedSum i j)) k = cast (by simp) (v k) := by
317-
sorry
318-
319345
@[simp]
320346
theorem fflatten_embedSum {A : Sort u} {F : A → Sort v} {m : ℕ} {n : Fin m → ℕ}
321347
{α : (i : Fin m) → (j : Fin (n i)) → A}
@@ -334,6 +360,18 @@ theorem fflatten_embedSum {A : Sort u} {F : A → Sort v} {m : ℕ} {n : Fin m
334360
erw [fappend_right, ih (fun i => v i.succ) i j, _root_.cast_cast]
335361
rfl
336362

363+
@[simp]
364+
theorem fflatten_splitSum {A : Sort u} {F : A → Sort v} {m : ℕ} {n : Fin m → ℕ}
365+
{α : (i : Fin (vsum n)) → A}
366+
(v : (k : Fin (vsum n)) → F (α k)) (k : Fin (vsum n)) :
367+
fflatten (fun i j => v (embedSum i j)) k = cast (by simp) (v k) := by
368+
have hk : embedSum (splitSum k).1 (splitSum k).2 = k := embedSum_splitSum k
369+
rcases hs : splitSum k with ⟨i, j⟩
370+
rw [hs] at hk
371+
clear hs
372+
subst hk
373+
exact fflatten_embedSum _ i j
374+
337375
/-- Functorial flatten with two arguments: flattens two nested heterogeneous tuple
338376
`(i : Fin m) → (j : Fin (n i)) → F (α i j)` into a single heterogeneous tuple with type
339377
`(k : Fin (vsum n)) → F (vflatten α k)` where `vflatten` operates on the vector of types `α`.
@@ -375,14 +413,6 @@ theorem fflatten₂_two_eq_append {A : Sort u} {B : Sort v} {F : A → B → Sor
375413
{v : (i : Fin 2) → (j : Fin (n i)) → F (α i j) (β i j)} :
376414
fflatten₂ v = fappend₂ (F := F) (v 0) (v 1) := rfl
377415

378-
@[simp]
379-
theorem fflatten₂_splitSum {A : Sort u} {B : Sort v} {F : A → B → Sort w} {m : ℕ} {n : Fin m → ℕ}
380-
{α : (i : Fin m) → (j : Fin (n i)) → A}
381-
{β : (i : Fin m) → (j : Fin (n i)) → B}
382-
(v : (k : Fin (vsum n)) → F (vflatten α k) (vflatten β k)) (k : Fin (vsum n)) :
383-
fflatten₂ (fun i j => v (embedSum i j)) k = cast (by simp) (v k) := by
384-
sorry
385-
386416
@[simp]
387417
theorem fflatten₂_embedSum {A : Sort u} {B : Sort v} {F : A → B → Sort w} {m : ℕ} {n : Fin m → ℕ}
388418
{α : (i : Fin m) → (j : Fin (n i)) → A}
@@ -402,6 +432,19 @@ theorem fflatten₂_embedSum {A : Sort u} {B : Sort v} {F : A → B → Sort w}
402432
erw [fappend₂_right, ih (fun i => v i.succ) i j, _root_.cast_cast]
403433
rfl
404434

435+
@[simp]
436+
theorem fflatten₂_splitSum {A : Sort u} {B : Sort v} {F : A → B → Sort w} {m : ℕ} {n : Fin m → ℕ}
437+
{α : (i : Fin m) → (j : Fin (n i)) → A}
438+
{β : (i : Fin m) → (j : Fin (n i)) → B}
439+
(v : (k : Fin (vsum n)) → F (vflatten α k) (vflatten β k)) (k : Fin (vsum n)) :
440+
fflatten₂ (fun i j => v (embedSum i j)) k = cast (by simp) (v k) := by
441+
have hk : embedSum (splitSum k).1 (splitSum k).2 = k := embedSum_splitSum k
442+
rcases hs : splitSum k with ⟨i, j⟩
443+
rw [hs] at hk
444+
clear hs
445+
subst hk
446+
exact fflatten₂_embedSum _ i j
447+
405448
/-- Heterogeneous flatten: flattens a nested heterogeneous tuple
406449
`(i : Fin m) → (j : Fin (n i)) → α i j` into a single heterogeneous tuple with type
407450
`(k : Fin (vsum n)) → vflatten α k` where `vflatten` operates on the vector of types `α`.
@@ -478,9 +521,30 @@ def ranges {n : ℕ} (a : Fin n → ℕ) : (i : Fin n) → Fin (a i) → ℕ :=
478521
def divSum? {m : ℕ} (n : Fin m → ℕ) (k : ℕ) : Option (Fin m) :=
479522
Fin.find? (fun i => k < ∑ j, n (castLE i.isLt j))
480523

524+
/-- The sum of `n` over the first `i + 1` indices is at most the total sum. -/
525+
theorem partialSum_le_sum {m : ℕ} (n : Fin m → ℕ) (i : Fin m) :
526+
∑ j : Fin (i.val + 1), n (castLE i.isLt j) ≤ ∑ j, n j := by
527+
have h : (i.val + 1) + (m - i.val - 1) = m := by omega
528+
conv_rhs => rw [← Fin.sum_congr' n h, Fin.sum_univ_add]
529+
refine le_of_eq_of_le (Finset.sum_congr rfl fun j _ => ?_) (Nat.le_add_right _ _)
530+
rfl
531+
481532
theorem divSum?_is_some_iff_lt_sum {m : ℕ} {n : Fin m → ℕ} {k : ℕ} :
482533
(divSum? n k).isSome ↔ k < ∑ i, n i := by
483-
sorry
534+
rw [divSum?, Fin.isSome_find?_iff]
535+
constructor
536+
· rintro ⟨i, hi⟩
537+
rw [decide_eq_true_eq] at hi
538+
exact lt_of_lt_of_le hi (partialSum_le_sum n i)
539+
· intro hk
540+
obtain ⟨m', rfl⟩ : ∃ m', m = m' + 1 := by
541+
cases m with
542+
| zero => simp at hk
543+
| succ m' => exact ⟨m', rfl⟩
544+
refine ⟨Fin.last m', ?_⟩
545+
rw [decide_eq_true_eq]
546+
refine lt_of_lt_of_le hk (le_of_eq (Finset.sum_congr rfl fun j _ => ?_))
547+
rfl
484548
-- constructor
485549
-- · intro h
486550
-- simp only [divSum?, Nat.succ_eq_add_one, castLE, isSome_find_iff] at h
@@ -505,20 +569,26 @@ theorem sum_le_of_divSum?_eq_some {m : ℕ} {n : Fin m → ℕ} {k : Fin (∑ j,
505569
by_cases hi' : 0 = i.val
506570
· rw [← Fin.sum_congr' _ hi']
507571
simp only [Finset.univ_eq_empty, Finset.sum_empty, _root_.zero_le]
508-
· have : (i.val - 1) + 1 = i.val := by omega
509-
rw [← Fin.sum_congr' _ this]
510-
sorry
572+
· have hone : (i.val - 1) + 1 = i.val := by omega
573+
rw [← Fin.sum_congr' _ hone]
574+
have hj : (decide (↑k < ∑ j, n (castLE (Fin.mk (i.val - 1) (by omega) : Fin m).isLt j)))
575+
= false :=
576+
Fin.eq_false_of_find?_eq_some_of_lt hi ⟨i.val - 1, by omega⟩ (by simp [Fin.lt_def]; omega)
577+
rw [decide_eq_false_iff_not, not_lt] at hj
578+
refine le_trans (le_of_eq (Finset.sum_congr rfl fun j _ => ?_)) hj
579+
rfl
511580
-- have := Fin.find_min (Option.mem_def.mp hi) (j := ⟨i.val - 1, by omega⟩) <| Fin.lt_def.mpr
512581
-- (by simp only; omega)
513582
-- exact not_lt.mp this
514583

515584
def modSum {m : ℕ} {n : Fin m → ℕ} (k : Fin (∑ j, n j)) : Fin (n (divSum k)) :=
516585
⟨k - ∑ j, n (Fin.castLE (divSum k).isLt.le j), by
517-
-- sorry
518586
have divSum_mem : divSum k ∈ divSum? n k := by
519587
simp only [divSum, divSum?, Option.mem_def, Option.some_get]
520-
have hk : k < ∑ j, n (Fin.castLE (divSum k).isLt j) := by
521-
sorry --Fin.find_spec _ divSum_mem
588+
have hk : (k : ℕ) < ∑ j, n (Fin.castLE (divSum k).isLt j) := by
589+
have := Fin.eq_true_of_find?_eq_some (p := fun i => decide ((k : ℕ) <
590+
∑ j, n (castLE i.isLt j))) divSum_mem
591+
simpa using this
522592
simp only [Fin.sum_univ_succAbove _ (Fin.last (divSum k)), succAbove_last] at hk
523593
rw [Nat.sub_lt_iff_lt_add' (sum_le_of_divSum?_eq_some divSum_mem)]
524594
rw [add_comm]

0 commit comments

Comments
 (0)