Lean4
/-- Given an ordered finpartition of `n+1`, with a leftmost atom different from `{0}`, remove `{0}`
from the atom that contains it, to form an ordered finpartition of `n`. -/
def eraseMiddle (c : OrderedFinpartition (n + 1)) (hc : range (c.emb 0) ≠ {0}) : OrderedFinpartition n
where
length := c.length
partSize := update c.partSize (c.index 0) (c.partSize (c.index 0) - 1)
partSize_pos
i := by
rcases eq_or_ne i (c.index 0) with rfl | hi
· simpa using c.one_lt_partSize_index_zero hc
· simp only [ne_eq, hi, not_false_eq_true, update_of_ne]
exact c.partSize_pos i
emb i
j := by
by_cases h : i = c.index 0
· refine Fin.pred (c.emb i (Fin.cast ?_ (succ j))) ?_
· rw [h]
simpa using Nat.sub_add_cancel (c.partSize_pos (c.index 0))
· have : 0 ≤ c.emb i 0 := Fin.zero_le _
exact (this.trans_lt (c.emb_strictMono _ (succ_pos _))).ne'
· refine Fin.pred (c.emb i (Fin.cast ?_ j)) ?_
· simp [h]
· conv_rhs => rw [← c.emb_invEmbedding 0]
exact c.emb_ne_emb_of_ne h
emb_strictMono i a b
hab := by
rcases eq_or_ne i (c.index 0) with rfl | hi
· simp only [↓reduceDIte, Nat.succ_eq_add_one, pred_lt_pred_iff]
exact (c.emb_strictMono _).comp (cast_strictMono _) (by simpa using hab)
· simp only [hi, ↓reduceDIte, pred_lt_pred_iff, Nat.succ_eq_add_one]
exact (c.emb_strictMono _).comp (cast_strictMono _) hab
parts_strictMono i j
hij := by
simp only [Fin.lt_iff_val_lt_val]
rw [← Nat.add_lt_add_iff_right (k := 1)]
convert Fin.lt_iff_val_lt_val.1 (c.parts_strictMono hij)
· rcases eq_or_ne i (c.index 0) with rfl | hi
· simp only [↓reduceDIte, update_self, succ_mk, cast_mk, coe_pred]
have A := c.one_lt_partSize_index_zero hc
rw [Nat.sub_add_cancel]
· congr; omega
· rw [Order.one_le_iff_pos]
conv_lhs => rw [show (0 : ℕ) = c.emb (c.index 0) 0 by simp [emb_zero]]
rw [← lt_iff_val_lt_val]
apply c.emb_strictMono
simp [lt_iff_val_lt_val]
· simp only [hi, ↓reduceDIte, ne_eq, not_false_eq_true, update_of_ne, cast_mk, coe_pred]
apply Nat.sub_add_cancel
have : c.emb i ⟨c.partSize i - 1, Nat.sub_one_lt_of_lt (c.partSize_pos i)⟩ ≠ c.emb (c.index 0) 0 :=
c.emb_ne_emb_of_ne hi
simp only [c.emb_zero, ne_eq, ← val_eq_val, val_zero] at this
omega
· rcases eq_or_ne j (c.index 0) with rfl | hj
· simp only [↓reduceDIte, update_self, succ_mk, cast_mk, coe_pred]
have A := c.one_lt_partSize_index_zero hc
rw [Nat.sub_add_cancel]
· congr; omega
· rw [Order.one_le_iff_pos]
conv_lhs => rw [show (0 : ℕ) = c.emb (c.index 0) 0 by simp [emb_zero]]
rw [← lt_iff_val_lt_val]
apply c.emb_strictMono
simp [lt_iff_val_lt_val]
· simp only [hj, ↓reduceDIte, ne_eq, not_false_eq_true, update_of_ne, cast_mk, coe_pred]
apply Nat.sub_add_cancel
have : c.emb j ⟨c.partSize j - 1, Nat.sub_one_lt_of_lt (c.partSize_pos j)⟩ ≠ c.emb (c.index 0) 0 :=
c.emb_ne_emb_of_ne hj
simp only [c.emb_zero, ne_eq, ← val_eq_val, val_zero] at this
omega
disjoint i _ j _
hij := by
wlog h : i ≠ c.index 0 generalizing i j
· apply Disjoint.symm (this j (mem_univ j) i (mem_univ i) hij.symm ?_)
simp only [ne_eq, Decidable.not_not] at h
simpa [h] using hij.symm
rcases eq_or_ne j (c.index 0) with rfl | hj
· simp only [onFun, hij, ↓reduceDIte]
apply Set.disjoint_iff_forall_ne.2
simp only [mem_range, ne_eq, forall_exists_index, forall_apply_eq_imp_iff, pred_inj]
intro a b
exact c.emb_ne_emb_of_ne hij
· simp only [onFun, h, ↓reduceDIte, hj]
apply Set.disjoint_iff_forall_ne.2
simp only [mem_range, ne_eq, forall_exists_index, forall_apply_eq_imp_iff, pred_inj]
intro a b
exact c.emb_ne_emb_of_ne hij
cover
x := by
simp only [mem_range]
obtain ⟨i, j, hij⟩ : ∃ (i : Fin c.length), ∃ (j : Fin (c.partSize i)), c.emb i j = succ x :=
⟨c.index (succ x), c.invEmbedding (succ x), by simp⟩
rcases eq_or_ne i (c.index 0) with rfl | hi
· refine ⟨c.index 0, ?_⟩
have j_ne : j ≠ 0 := by
rintro rfl
simp only [c.emb_zero] at hij
exact (Fin.succ_ne_zero _).symm hij
have je_ne' : (j : ℕ) ≠ 0 := by simpa
simp only [↓reduceDIte]
have A : c.partSize (c.index 0) - 1 + 1 = c.partSize (c.index 0) := Nat.sub_add_cancel (c.partSize_pos _)
have B : update c.partSize (c.index 0) (c.partSize (c.index 0) - 1) (c.index 0) = c.partSize (c.index 0) - 1 := by
simp
refine ⟨Fin.cast B.symm (pred (Fin.cast A.symm j) ?_), ?_⟩
· simpa using j_ne
· have : x = pred (succ x) (succ_ne_zero x) := rfl
rw [this]
simp only [pred_inj, ← hij]
congr 1
rw [← val_eq_val]
simp only [coe_cast, val_succ, coe_pred]
omega
· have A : update c.partSize (c.index 0) (c.partSize (c.index 0) - 1) i = c.partSize i := by simp [hi]
exact ⟨i, Fin.cast A.symm j, by simp [hi, hij]⟩