Zulip Chat Archive
Stream: Is there code for X?
Topic: succAbove and predAbove lemmas
Wrenna Robson (Nov 21 2023 at 10:00):
In an application I am considering, I needed the following:
lemma nonsense {i k} {j : Fin (m + 3)} :
(j.succAbove i).succAbove ((i.predAbove j).succAbove k) = j.succAbove (i.succAbove k) := sorry
Now, experimenting with various test values seems to indicate that this is true. But I can't find a proof for it. Can anyone suggest a good approach, or lemmas that I am missing (or that we are missing) that makes it more straightforward?
I also had this, which I could prove, but not nicely.
lemma succAbove_succAbove_predAbove {i : Fin (m + 1)} {j : Fin (m + 2)} :
(j.succAbove i).succAbove (i.predAbove j) = j := by
by_cases h : Fin.castSucc i < j
· rw [Fin.succAbove_below _ _ h, Fin.succAbove_predAbove (ne_of_lt h).symm]
· rw [not_lt] at h
rw [Fin.succAbove_above _ _ h, Fin.predAbove_below _ _ h, Fin.succAbove_below] <;>
rw [Fin.castSucc_castPred (lt_of_le_of_lt h (Fin.castSucc_lt_last _))]
exact lt_of_le_of_lt h (Fin.castSucc_lt_succ _)
Eric Wieser (Nov 21 2023 at 10:34):
Proof by ugly case bash:
import Mathlib.Data.Fin.Basic
import Mathlib.Tactic
lemma nonsense {i k} {j : Fin (m + 3)} :
(j.succAbove i).succAbove ((i.predAbove j).succAbove k) = j.succAbove (i.succAbove k) := by
ext
simp [Fin.succAbove, Fin.predAbove, Fin.lt_def]
split_ifs <;> simp_all
· linarith
· have : (1 : ℕ) ≤ j := by linarith
rw [lt_tsub_iff_left_of_le this] at *
linarith
· linarith
· linarith
· linarith
· linarith
· linarith
· linarith
Eric Wieser (Nov 21 2023 at 10:34):
(the sorry is easy)
Wrenna Robson (Nov 21 2023 at 10:36):
Weird that one step needs that sorry to work
Eric Wieser (Nov 21 2023 at 10:37):
linarith
is bad at Nat
subtraction
Wrenna Robson (Nov 21 2023 at 10:38):
So am I so I can't complain too much
Wrenna Robson (Nov 22 2023 at 15:53):
-- FIN LEMMA
lemma succAbove_succAbove_predAbove_succAbove_eq_succAbove_succAbove {j : Fin (m + 2)} :
(j.succAbove i).succAbove ((i.predAbove j).succAbove k) = j.succAbove (i.succAbove k) := by
ext
dsimp [Fin.succAbove, Fin.predAbove]
rcases j.succAbove_lt_ge i with (h | h) <;>
[ simp only [h, dite_true, Fin.coe_pred, ge_iff_le, lt_tsub_iff_right, Fin.dite_val,
Fin.coe_castSucc, Fin.val_succ] ;
simp only [h.not_lt, dite_false, Fin.coe_castLT, Fin.dite_val, Fin.coe_castSucc, Fin.val_succ]] <;>
rcases i.succAbove_lt_ge k with (h₂ | h₂) <;>
simp only [Fin.lt_def, Fin.le_def, Fin.coe_castSucc] at h h₂
· simp only [h, ite_true, h₂]
by_cases h₃ : (k + 1 : ℕ) < (j : ℕ)
· simp only [Nat.lt_of_succ_lt, h₃, ite_true, h₂]
· exfalso
rw [not_lt] at h₃
exact (Nat.le_of_lt_succ (lt_of_lt_of_le h h₃)).not_lt h₂
· simp only [h, ite_true, ite_false, h₂.not_lt]
by_cases h₃ : (k + 1 : ℕ) < (j : ℕ) <;>
simp only [h₃, ite_true, ite_false, ite_eq_right_iff, self_eq_add_right]
· exact h₂.not_lt
· rw [not_lt] at h₃
exact (lt_of_lt_of_le h h₃).le.not_lt
· simp only [h₂, ite_true, ite_false, h.not_lt]
by_cases h₃ : (k : ℕ) < (j : ℕ) <;>
simp only [h₃, ite_true, ite_false, ite_eq_left_iff, not_lt, add_right_eq_self]
· exact h₂.le.not_lt
· rw [Nat.succ_le_succ_iff]
exact h₂.not_le
· simp only [h.not_lt, ite_false]
by_cases h₃ : (k : ℕ) < (j : ℕ) <;>
simp only [h₃, Nat.succ_lt_succ_iff, h₂.not_lt, ite_false, ite_true]
· exfalso
exact h₃.not_le (h.trans h₂)
· rw [not_lt] at h₃
simp only [(h₃.trans (Nat.le_succ _)).not_lt, ite_false]
Wrenna Robson (Nov 22 2023 at 15:54):
This is just the ugly case bash with extra steps. But it may be more fertile ground for golfing.
Last updated: Dec 20 2023 at 11:08 UTC