l3lab/ntp-mathlib huggingface dataset:
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  

Proof state:
case mk
n m : ℕ
i : Fin n
p : ℕ
isLt✝ : p < n
⊢ (if h : castSucc { val := p, isLt := isLt✝ } < if ↑i < ↑{ val := p, isLt := isLt✝ } then castSucc i else succ i then
      pred (if ↑i < ↑{ val := p, isLt := isLt✝ } then castSucc i else succ i)
        (_ : (if ↑i < ↑{ val := p, isLt := isLt✝ } then castSucc i else succ i) ≠ 0)
    else
      castLT (if ↑i < ↑{ val := p, isLt := isLt✝ } then castSucc i else succ i)
        (_ : ↑(if ↑i < ↑{ val := p, isLt := isLt✝ } then castSucc i else succ i) < n)) =
    i

Next tactic:
rcases i with ⟨i, _⟩
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  

Proof state:
case mk.mk
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
⊢ (if h :
        castSucc { val := p, isLt := isLt✝¹ } <
          if ↑{ val := i, isLt := isLt✝ } < ↑{ val := p, isLt := isLt✝¹ } then castSucc { val := i, isLt := isLt✝ }
          else succ { val := i, isLt := isLt✝ } then
      pred
        (if ↑{ val := i, isLt := isLt✝ } < ↑{ val := p, isLt := isLt✝¹ } then castSucc { val := i, isLt := isLt✝ }
        else succ { val := i, isLt := isLt✝ })
        (_ :
          (if ↑{ val := i, isLt := isLt✝ } < ↑{ val := p, isLt := isLt✝¹ } then castSucc { val := i, isLt := isLt✝ }
            else succ { val := i, isLt := isLt✝ }) ≠
            0)
    else
      castLT
        (if ↑{ val := i, isLt := isLt✝ } < ↑{ val := p, isLt := isLt✝¹ } then castSucc { val := i, isLt := isLt✝ }
        else succ { val := i, isLt := isLt✝ })
        (_ :
          ↑(if ↑{ val := i, isLt := isLt✝ } < ↑{ val := p, isLt := isLt✝¹ } then castSucc { val := i, isLt := isLt✝ }
              else succ { val := i, isLt := isLt✝ }) <
            n)) =
    { val := i, isLt := isLt✝ }

Next tactic:
dsimp
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  dsimp
  

Proof state:
case mk.mk
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
⊢ (if h :
        { val := p, isLt := (_ : p < Nat.succ n) } <
          if i < p then { val := i, isLt := (_ : i < Nat.succ n) }
          else { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) } then
      pred
        (if i < p then { val := i, isLt := (_ : i < Nat.succ n) }
        else { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) })
        (_ :
          (if i < p then { val := i, isLt := (_ : i < Nat.succ n) }
            else { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }) ≠
            0)
    else
      castLT
        (if i < p then { val := i, isLt := (_ : i < Nat.succ n) }
        else { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) })
        (_ :
          ↑(if i < p then { val := i, isLt := (_ : i < Nat.succ n) }
              else { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }) <
            n)) =
    { val := i, isLt := isLt✝ }

Next tactic:
split_ifs with h₁ h₂ h₃
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  dsimp
  split_ifs with h₁ h₂ h₃
  · 

Proof state:
case pos
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
h₁ : i < p
h₂ : { val := p, isLt := (_ : p < Nat.succ n) } < { val := i, isLt := (_ : i < Nat.succ n) }
⊢ pred { val := i, isLt := (_ : i < Nat.succ n) } (_ : { val := i, isLt := (_ : i < Nat.succ n) } ≠ 0) =
    { val := i, isLt := isLt✝ }

Next tactic:
simp only [← val_fin_lt, not_lt] at h₁ h₂
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  dsimp
  split_ifs with h₁ h₂ h₃
  · simp only [← val_fin_lt, not_lt] at h₁ h₂
    

Proof state:
case pos
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
h₁ : i < p
h₂✝ : { val := p, isLt := (_ : p < Nat.succ n) } < { val := i, isLt := (_ : i < Nat.succ n) }
h₂ : p < i
⊢ pred { val := i, isLt := (_ : i < Nat.succ n) } (_ : { val := i, isLt := (_ : i < Nat.succ n) } ≠ 0) =
    { val := i, isLt := isLt✝ }

Next tactic:
exact (Nat.lt_le_asymm h₁ (le_of_lt h₂)).elim
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  dsimp
  split_ifs with h₁ h₂ h₃
  · simp only [← val_fin_lt, not_lt] at h₁ h₂
    exact (Nat.lt_le_asymm h₁ (le_of_lt h₂)).elim
  · 

Proof state:
case neg
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
h₁ : i < p
h₂ : ¬{ val := p, isLt := (_ : p < Nat.succ n) } < { val := i, isLt := (_ : i < Nat.succ n) }
⊢ castLT { val := i, isLt := (_ : i < Nat.succ n) } (_ : ↑{ val := i, isLt := (_ : i < Nat.succ n) } < n) =
    { val := i, isLt := isLt✝ }

Next tactic:
rfl
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  dsimp
  split_ifs with h₁ h₂ h₃
  · simp only [← val_fin_lt, not_lt] at h₁ h₂
    exact (Nat.lt_le_asymm h₁ (le_of_lt h₂)).elim
  · rfl
  · 

Proof state:
case pos
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
h₁ : ¬i < p
h₃ : { val := p, isLt := (_ : p < Nat.succ n) } < { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }
⊢ pred { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }
      (_ : { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) } ≠ 0) =
    { val := i, isLt := isLt✝ }

Next tactic:
rfl
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  dsimp
  split_ifs with h₁ h₂ h₃
  · simp only [← val_fin_lt, not_lt] at h₁ h₂
    exact (Nat.lt_le_asymm h₁ (le_of_lt h₂)).elim
  · rfl
  · rfl
  · 

Proof state:
case neg
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
h₁ : ¬i < p
h₃ : ¬{ val := p, isLt := (_ : p < Nat.succ n) } < { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }
⊢ castLT { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }
      (_ : ↑{ val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) } < n) =
    { val := i, isLt := isLt✝ }

Next tactic:
simp only [← val_fin_lt, not_lt] at h₁ h₃
/-- Sending `Fin n` into `Fin (n + 1)` with a gap at `p`
then back to `Fin n` by subtracting one from anything above `p` is the identity. -/
@[simp]
theorem predAbove_succAbove (p : Fin n) (i : Fin n) :
    p.predAbove ((castSucc p).succAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  dsimp
  split_ifs with h₁ h₂ h₃
  · simp only [← val_fin_lt, not_lt] at h₁ h₂
    exact (Nat.lt_le_asymm h₁ (le_of_lt h₂)).elim
  · rfl
  · rfl
  · simp only [← val_fin_lt, not_lt] at h₁ h₃
    

Proof state:
case neg
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n
h₁✝ : ¬i < p
h₃✝ : ¬{ val := p, isLt := (_ : p < Nat.succ n) } < { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }
h₁ : p ≤ i
h₃ : i + 1 ≤ p
⊢ castLT { val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) }
      (_ : ↑{ val := i + 1, isLt := (_ : Nat.succ i < Nat.succ n) } < n) =
    { val := i, isLt := isLt✝ }

Next tactic:
contradiction
theorem castSucc_pred_eq_pred_castSucc {a : Fin (n + 1)} (ha : a ≠ 0)
    (ha' := a.castSucc_ne_zero_iff.mpr ha) :
    castSucc (a.pred ha) = (castSucc a).pred ha' := by
  

Proof state:
n m : ℕ
a : Fin (n + 1)
ha : a ≠ 0
ha' : optParam (castSucc a ≠ 0) (_ : castSucc a ≠ 0)
⊢ castSucc (pred a ha) = pred (castSucc a) ha'

Next tactic:
cases a
theorem castSucc_pred_eq_pred_castSucc {a : Fin (n + 1)} (ha : a ≠ 0)
    (ha' := a.castSucc_ne_zero_iff.mpr ha) :
    castSucc (a.pred ha) = (castSucc a).pred ha' := by
  cases a
  

Proof state:
case mk
n m val✝ : ℕ
isLt✝ : val✝ < n + 1
ha : { val := val✝, isLt := isLt✝ } ≠ 0
ha' : optParam (castSucc { val := val✝, isLt := isLt✝ } ≠ 0) (_ : castSucc { val := val✝, isLt := isLt✝ } ≠ 0)
⊢ castSucc (pred { val := val✝, isLt := isLt✝ } ha) = pred (castSucc { val := val✝, isLt := isLt✝ }) ha'

Next tactic:
rfl
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  

Proof state:
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
⊢ succAbove (pred a ha) (pred b hb) = pred (succAbove a b) hk

Next tactic:
obtain hbelow | habove := lt_or_le (castSucc b) a
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · 

Proof state:
case inl
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
hbelow : castSucc b < a
⊢ succAbove (pred a ha) (pred b hb) = pred (succAbove a b) hk

Next tactic:
rw [Fin.succAbove_below]
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · rw [Fin.succAbove_below]
    · 

Proof state:
case inl
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
hbelow : castSucc b < a
⊢ castSucc (pred b hb) = pred (succAbove a b) hk

Next tactic:
rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_inj, Fin.succAbove_below]
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · rw [Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_inj, Fin.succAbove_below]
    · 

Proof state:
case inl.h
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
hbelow : castSucc b < a
⊢ castSucc (pred b hb) < pred a ha

Next tactic:
rwa [castSucc_pred_eq_pred_castSucc, pred_lt_pred_iff]
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · rw [Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_inj, Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, pred_lt_pred_iff]
  · 

Proof state:
case inr
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
habove : a ≤ castSucc b
⊢ succAbove (pred a ha) (pred b hb) = pred (succAbove a b) hk

Next tactic:
rw [Fin.succAbove_above]
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · rw [Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_inj, Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, pred_lt_pred_iff]
  · rw [Fin.succAbove_above]
    

Proof state:
case inr
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
habove : a ≤ castSucc b
⊢ succ (pred b hb) = pred (succAbove a b) hk
case inr.h
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
habove : a ≤ castSucc b
⊢ pred a ha ≤ castSucc (pred b hb)

Next tactic:
have : (b.pred hb).succ = b.succ.pred (succ_ne_zero _) := by rw [succ_pred, pred_succ]
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · rw [Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_inj, Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, pred_lt_pred_iff]
  · rw [Fin.succAbove_above]
    have : (b.pred hb).succ = b.succ.pred (succ_ne_zero _) := by 

Proof state:
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
habove : a ≤ castSucc b
⊢ succ (pred b hb) = pred (succ b) (_ : succ b ≠ 0)

Next tactic:
rw [succ_pred, pred_succ]
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · rw [Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_inj, Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, pred_lt_pred_iff]
  · rw [Fin.succAbove_above]
    have : (b.pred hb).succ = b.succ.pred (succ_ne_zero _) := by rw [succ_pred, pred_succ]
    · 

Proof state:
case inr
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
habove : a ≤ castSucc b
this : succ (pred b hb) = pred (succ b) (_ : succ b ≠ 0)
⊢ succ (pred b hb) = pred (succAbove a b) hk

Next tactic:
rwa [this, Fin.pred_inj, Fin.succAbove_above]
/-- `pred` commutes with `succAbove`. -/
theorem pred_succAbove_pred {a : Fin (n + 2)} {b : Fin (n + 1)} (ha : a ≠ 0) (hb : b ≠ 0)
    (hk := succAbove_ne_zero ha hb) :
    (a.pred ha).succAbove (b.pred hb) = (a.succAbove b).pred hk := by
  obtain hbelow | habove := lt_or_le (castSucc b) a
  -- `rwa` uses them
  · rw [Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_inj, Fin.succAbove_below]
    · rwa [castSucc_pred_eq_pred_castSucc, pred_lt_pred_iff]
  · rw [Fin.succAbove_above]
    have : (b.pred hb).succ = b.succ.pred (succ_ne_zero _) := by rw [succ_pred, pred_succ]
    · rwa [this, Fin.pred_inj, Fin.succAbove_above]
    · 

Proof state:
case inr.h
n m : ℕ
a : Fin (n + 2)
b : Fin (n + 1)
ha : a ≠ 0
hb : b ≠ 0
hk : optParam (succAbove a b ≠ 0) (_ : succAbove a b ≠ 0)
habove : a ≤ castSucc b
⊢ pred a ha ≤ castSucc (pred b hb)

Next tactic:
rwa [castSucc_pred_eq_pred_castSucc, Fin.pred_le_pred_iff]
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  

Proof state:
n✝ m n : ℕ
a : Fin n
b : Fin (n + 1)
⊢ predAbove (succ a) (succ b) = succ (predAbove a b)

Next tactic:
obtain h₁ | h₂ := lt_or_le (castSucc a) b
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · 

Proof state:
case inl
n✝ m n : ℕ
a : Fin n
b : Fin (n + 1)
h₁ : castSucc a < b
⊢ predAbove (succ a) (succ b) = succ (predAbove a b)

Next tactic:
rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    

Proof state:
case inl.h
n✝ m n : ℕ
a : Fin n
b : Fin (n + 1)
h₁ : castSucc a < b
⊢ castSucc (succ a) < succ b
case inl.h n✝ m n : ℕ a : Fin n b : Fin (n + 1) h₁ : castSucc a < b ⊢ castSucc (succ a) < succ b

Next tactic:
simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · 

Proof state:
case inr
n✝ m n : ℕ
a : Fin n
b : Fin (n + 1)
h₂ : b ≤ castSucc a
⊢ predAbove (succ a) (succ b) = succ (predAbove a b)

Next tactic:
cases' n with n
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · cases' n with n
    · 

Proof state:
case inr.zero
n m : ℕ
a : Fin zero
b : Fin (zero + 1)
h₂ : b ≤ castSucc a
⊢ predAbove (succ a) (succ b) = succ (predAbove a b)

Next tactic:
exfalso
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · cases' n with n
    · exfalso
      

Proof state:
case inr.zero.h
n m : ℕ
a : Fin zero
b : Fin (zero + 1)
h₂ : b ≤ castSucc a
⊢ False

Next tactic:
exact not_lt_zero' a.is_lt
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · cases' n with n
    · exfalso
      exact not_lt_zero' a.is_lt
    · 

Proof state:
case inr.succ
n✝ m n : ℕ
a : Fin (Nat.succ n)
b : Fin (Nat.succ n + 1)
h₂ : b ≤ castSucc a
⊢ predAbove (succ a) (succ b) = succ (predAbove a b)

Next tactic:
rw [Fin.predAbove_below a b h₂,
        Fin.predAbove_below a.succ b.succ
          (by
            simpa only [le_iff_val_le_val, val_succ, coe_castSucc, add_le_add_iff_right]
              using h₂)]
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · cases' n with n
    · exfalso
      exact not_lt_zero' a.is_lt
    · rw [Fin.predAbove_below a b h₂,
        Fin.predAbove_below a.succ b.succ
          (by
            

Proof state:
n✝ m n : ℕ
a : Fin (Nat.succ n)
b : Fin (Nat.succ n + 1)
h₂ : b ≤ castSucc a
⊢ succ b ≤ castSucc (succ a)

Next tactic:
simpa only [le_iff_val_le_val, val_succ, coe_castSucc, add_le_add_iff_right]
              using h₂
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · cases' n with n
    · exfalso
      exact not_lt_zero' a.is_lt
    · rw [Fin.predAbove_below a b h₂,
        Fin.predAbove_below a.succ b.succ
          (by
            simpa only [le_iff_val_le_val, val_succ, coe_castSucc, add_le_add_iff_right]
              using h₂)]
      

Proof state:
case inr.succ
n✝ m n : ℕ
a : Fin (Nat.succ n)
b : Fin (Nat.succ n + 1)
h₂ : b ≤ castSucc a
⊢ castPred (succ b) = succ (castPred b)

Next tactic:
ext
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · cases' n with n
    · exfalso
      exact not_lt_zero' a.is_lt
    · rw [Fin.predAbove_below a b h₂,
        Fin.predAbove_below a.succ b.succ
          (by
            simpa only [le_iff_val_le_val, val_succ, coe_castSucc, add_le_add_iff_right]
              using h₂)]
      ext
      

Proof state:
case inr.succ.h
n✝ m n : ℕ
a : Fin (Nat.succ n)
b : Fin (Nat.succ n + 1)
h₂ : b ≤ castSucc a
⊢ ↑(castPred (succ b)) = ↑(succ (castPred b))

Next tactic:
have h₀ : (b : ℕ) < n + 1 := by
        simp only [le_iff_val_le_val, coe_castSucc] at h₂
        simpa only [lt_succ_iff] using h₂.trans a.is_le
/-- `succ` commutes with `predAbove`. -/
@[simp]
theorem succ_predAbove_succ {n : ℕ} (a : Fin n) (b : Fin (n + 1)) :
    a.succ.predAbove b.succ = (a.predAbove b).succ := by
  obtain h₁ | h₂ := lt_or_le (castSucc a) b
  · rw [Fin.predAbove_above _ _ h₁, Fin.succ_pred, Fin.predAbove_above, Fin.pred_succ]
    simpa only [lt_iff_val_lt_val, coe_castSucc, val_succ, add_lt_add_iff_right] using
      h₁
  · cases' n with n
    · exfalso
      exact not_lt_zero' a.is_lt
    · rw [Fin.predAbove_below a b h₂,
        Fin.predAbove_below a.succ b.succ
          (by
            simpa only [le_iff_val_le_val, val_succ, coe_castSucc, add_le_add_iff_right]
              using h₂)]
      ext
      have h₀ : (b : ℕ) < n + 1 := by
        

Proof state:
n✝ m n : ℕ
a : Fin (Nat.succ n)
b : Fin (Nat.succ n + 1)
h₂ : b ≤ castSucc a
⊢ ↑b < n + 1

Next tactic:
simp only [le_iff_val_le_val, coe_castSucc] at h₂