l3lab/ntp-mathlib huggingface dataset:
theorem predAbove_left_monotone (i : Fin (n + 1)) :
    Monotone fun p => predAbove p i := fun a b H => by
  dsimp [predAbove]
  split_ifs with ha hb hb
  · rfl
  · 

Proof state:
case neg
n m : ℕ
i : Fin (n + 1)
a b : Fin n
H : a ≤ b
ha : castSucc a < i
hb : ¬castSucc b < i
⊢ pred i (_ : i ≠ 0) ≤ castLT i (_ : ↑i < n)

Next tactic:
exact pred_le _
theorem predAbove_left_monotone (i : Fin (n + 1)) :
    Monotone fun p => predAbove p i := fun a b H => by
  dsimp [predAbove]
  split_ifs with ha hb hb
  · rfl
  · exact pred_le _
  · 

Proof state:
case pos
n m : ℕ
i : Fin (n + 1)
a b : Fin n
H : a ≤ b
ha : ¬castSucc a < i
hb : castSucc b < i
⊢ castLT i (_ : ↑i < n) ≤ pred i (_ : i ≠ 0)

Next tactic:
have : b < a := castSucc_lt_castSucc_iff.mpr (hb.trans_le (le_of_not_gt ha))
theorem predAbove_left_monotone (i : Fin (n + 1)) :
    Monotone fun p => predAbove p i := fun a b H => by
  dsimp [predAbove]
  split_ifs with ha hb hb
  · rfl
  · exact pred_le _
  · have : b < a := castSucc_lt_castSucc_iff.mpr (hb.trans_le (le_of_not_gt ha))
    

Proof state:
case pos
n m : ℕ
i : Fin (n + 1)
a b : Fin n
H : a ≤ b
ha : ¬castSucc a < i
hb : castSucc b < i
this : b < a
⊢ castLT i (_ : ↑i < n) ≤ pred i (_ : i ≠ 0)

Next tactic:
exact absurd H this.not_le
theorem predAbove_left_monotone (i : Fin (n + 1)) :
    Monotone fun p => predAbove p i := fun a b H => by
  dsimp [predAbove]
  split_ifs with ha hb hb
  · rfl
  · exact pred_le _
  · have : b < a := castSucc_lt_castSucc_iff.mpr (hb.trans_le (le_of_not_gt ha))
    exact absurd H this.not_le
  · 

Proof state:
case neg
n m : ℕ
i : Fin (n + 1)
a b : Fin n
H : a ≤ b
ha : ¬castSucc a < i
hb : ¬castSucc b < i
⊢ castLT i (_ : ↑i < n) ≤ castLT i (_ : ↑i < n)

Next tactic:
rfl
@[simp]
theorem castPred_one : castPred (1 : Fin (n + 2)) = 1 := by
  

Proof state:
n m : ℕ
⊢ castPred 1 = 1

Next tactic:
cases n
@[simp]
theorem castPred_one : castPred (1 : Fin (n + 2)) = 1 := by
  cases n
  · 

Proof state:
case zero
m : ℕ
⊢ castPred 1 = 1

Next tactic:
rfl
@[simp]
theorem castPred_one : castPred (1 : Fin (n + 2)) = 1 := by
  cases n
  · rfl
  · 

Proof state:
case succ
m n✝ : ℕ
⊢ castPred 1 = 1

Next tactic:
rfl
@[simp]
theorem predAbove_zero {i : Fin (n + 2)} (hi : i ≠ 0) : predAbove 0 i = i.pred hi := by
  

Proof state:
n m : ℕ
i : Fin (n + 2)
hi : i ≠ 0
⊢ predAbove 0 i = pred i hi

Next tactic:
dsimp [predAbove]
@[simp]
theorem predAbove_zero {i : Fin (n + 2)} (hi : i ≠ 0) : predAbove 0 i = i.pred hi := by
  dsimp [predAbove]
  

Proof state:
n m : ℕ
i : Fin (n + 2)
hi : i ≠ 0
⊢ (if h : 0 < i then pred i (_ : i ≠ 0) else castLT i (_ : ↑i < n + 1)) = pred i hi

Next tactic:
rw [dif_pos]
@[simp]
theorem predAbove_zero {i : Fin (n + 2)} (hi : i ≠ 0) : predAbove 0 i = i.pred hi := by
  dsimp [predAbove]
  rw [dif_pos]
  

Proof state:
case hc
n m : ℕ
i : Fin (n + 2)
hi : i ≠ 0
⊢ 0 < i

Next tactic:
exact pos_iff_ne_zero.mpr hi
@[simp]
theorem castPred_last : castPred (last (n + 1)) = last n :=
  eq_of_veq (by 

Proof state:
n m : ℕ
⊢ ↑(castPred (last (n + 1))) = ↑(last n)

Next tactic:
simp [castPred, predAbove, castSucc_lt_last]
theorem castPred_mk (n i : ℕ) (h : i < n + 1) : castPred ⟨i, lt_succ_of_lt h⟩ = ⟨i, h⟩ := by
  

Proof state:
n✝ m n i : ℕ
h : i < n + 1
⊢ castPred { val := i, isLt := (_ : i < Nat.succ (n + 1)) } = { val := i, isLt := h }

Next tactic:
have : ¬castSucc (last n) < ⟨i, lt_succ_of_lt h⟩ := by
    simpa [lt_iff_val_lt_val] using le_of_lt_succ h
theorem castPred_mk (n i : ℕ) (h : i < n + 1) : castPred ⟨i, lt_succ_of_lt h⟩ = ⟨i, h⟩ := by
  have : ¬castSucc (last n) < ⟨i, lt_succ_of_lt h⟩ := by
    

Proof state:
n✝ m n i : ℕ
h : i < n + 1
⊢ ¬castSucc (last n) < { val := i, isLt := (_ : i < Nat.succ (n + 1)) }

Next tactic:
simpa [lt_iff_val_lt_val] using le_of_lt_succ h
theorem castPred_mk (n i : ℕ) (h : i < n + 1) : castPred ⟨i, lt_succ_of_lt h⟩ = ⟨i, h⟩ := by
  have : ¬castSucc (last n) < ⟨i, lt_succ_of_lt h⟩ := by
    simpa [lt_iff_val_lt_val] using le_of_lt_succ h
  

Proof state:
n✝ m n i : ℕ
h : i < n + 1
this : ¬castSucc (last n) < { val := i, isLt := (_ : i < Nat.succ (n + 1)) }
⊢ castPred { val := i, isLt := (_ : i < Nat.succ (n + 1)) } = { val := i, isLt := h }

Next tactic:
simp [castPred, predAbove, this]
theorem coe_castPred {n : ℕ} (a : Fin (n + 2)) (hx : a < Fin.last _) :
    (a.castPred : ℕ) = a := by
  

Proof state:
n✝ m n : ℕ
a : Fin (n + 2)
hx : a < last (n + 1)
⊢ ↑(castPred a) = ↑a

Next tactic:
rcases a with ⟨a, ha⟩
theorem coe_castPred {n : ℕ} (a : Fin (n + 2)) (hx : a < Fin.last _) :
    (a.castPred : ℕ) = a := by
  rcases a with ⟨a, ha⟩
  

Proof state:
case mk
n✝ m n a : ℕ
ha : a < n + 2
hx : { val := a, isLt := ha } < last (n + 1)
⊢ ↑(castPred { val := a, isLt := ha }) = ↑{ val := a, isLt := ha }

Next tactic:
rw [castPred_mk]
theorem coe_castPred {n : ℕ} (a : Fin (n + 2)) (hx : a < Fin.last _) :
    (a.castPred : ℕ) = a := by
  rcases a with ⟨a, ha⟩
  rw [castPred_mk]
  

Proof state:
case mk.h
n✝ m n a : ℕ
ha : a < n + 2
hx : { val := a, isLt := ha } < last (n + 1)
⊢ a < n + 1

Next tactic:
exact hx
theorem predAbove_below (p : Fin (n + 1)) (i : Fin (n + 2)) (h : i ≤ castSucc p) :
    p.predAbove i = i.castPred := by
  

Proof state:
n m : ℕ
p : Fin (n + 1)
i : Fin (n + 2)
h : i ≤ castSucc p
⊢ predAbove p i = castPred i

Next tactic:
have : i ≤ castSucc (last n) := h.trans p.le_last
theorem predAbove_below (p : Fin (n + 1)) (i : Fin (n + 2)) (h : i ≤ castSucc p) :
    p.predAbove i = i.castPred := by
  have : i ≤ castSucc (last n) := h.trans p.le_last
  

Proof state:
n m : ℕ
p : Fin (n + 1)
i : Fin (n + 2)
h : i ≤ castSucc p
this : i ≤ castSucc (last n)
⊢ predAbove p i = castPred i

Next tactic:
simp [predAbove, castPred, h.not_lt, this.not_lt]
theorem predAbove_last_apply (i : Fin n) : predAbove (Fin.last n) i = i.castPred := by
  

Proof state:
n m : ℕ
i : Fin n
⊢ predAbove (last n) ↑↑i = castPred ↑↑i

Next tactic:
rw [predAbove_last]
theorem predAbove_above (p : Fin n) (i : Fin (n + 1)) (h : castSucc p < i) :
    p.predAbove i = i.pred ((zero_le <| castSucc p).trans_lt h).ne.symm := by
  

Proof state:
n m : ℕ
p : Fin n
i : Fin (n + 1)
h : castSucc p < i
⊢ predAbove p i = pred i (_ : i ≠ 0)

Next tactic:
simp [predAbove, h]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  

Proof state:
n m : ℕ
p : Fin n
i : Fin (n + 1)
h : i ≠ castSucc p
⊢ succAbove (castSucc p) (predAbove p i) = i

Next tactic:
dsimp [predAbove, succAbove]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  

Proof state:
n m : ℕ
p : Fin n
i : Fin (n + 1)
h : i ≠ castSucc p
⊢ (if ↑(if h : castSucc p < i then pred i (_ : i ≠ 0) else castLT i (_ : ↑i < n)) < ↑p then
      castSucc (if h : castSucc p < i then pred i (_ : i ≠ 0) else castLT i (_ : ↑i < n))
    else succ (if h : castSucc p < i then pred i (_ : i ≠ 0) else castLT i (_ : ↑i < n))) =
    i

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

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

Next tactic:
rcases i with ⟨i, _⟩
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove 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 + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
⊢ (if
        ↑(if h : castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ } then
              pred { val := i, isLt := isLt✝ } (_ : { val := i, isLt := isLt✝ } ≠ 0)
            else castLT { val := i, isLt := isLt✝ } (_ : ↑{ val := i, isLt := isLt✝ } < n)) <
          ↑{ val := p, isLt := isLt✝¹ } then
      castSucc
        (if h : castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ } then
          pred { val := i, isLt := isLt✝ } (_ : { val := i, isLt := isLt✝ } ≠ 0)
        else castLT { val := i, isLt := isLt✝ } (_ : ↑{ val := i, isLt := isLt✝ } < n))
    else
      succ
        (if h : castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ } then
          pred { val := i, isLt := isLt✝ } (_ : { val := i, isLt := isLt✝ } ≠ 0)
        else castLT { val := i, isLt := isLt✝ } (_ : ↑{ val := i, isLt := isLt✝ } < n))) =
    { val := i, isLt := isLt✝ }

Next tactic:
cases' lt_or_le i p with H H
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · 

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

Next tactic:
rw [dif_neg]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    

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

Next tactic:
rw [if_pos]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    

Proof state:
case mk.mk.inl
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ castSucc (castLT { val := i, isLt := isLt✝ } (_ : ↑{ val := i, isLt := isLt✝ } < n)) = { val := i, isLt := isLt✝ }
case mk.mk.inl.hc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ↑(castLT { val := i, isLt := isLt✝ } (_ : ↑{ val := i, isLt := isLt✝ } < n)) < ↑{ val := p, isLt := isLt✝¹ }
case mk.mk.inl.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ¬castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ }
case mk.mk.inl.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ¬castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ }

Next tactic:
rfl
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    

Proof state:
case mk.mk.inl.hc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ↑(castLT { val := i, isLt := isLt✝ } (_ : ↑{ val := i, isLt := isLt✝ } < n)) < ↑{ val := p, isLt := isLt✝¹ }
case mk.mk.inl.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ¬castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ }
case mk.mk.inl.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ¬castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ }

Next tactic:
exact H
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    

Proof state:
case mk.mk.inl.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ¬castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ }
case mk.mk.inl.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ ¬castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ }

Next tactic:
simp only [castSucc_mk, mk_lt_mk, not_lt]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    simp only [castSucc_mk, mk_lt_mk, not_lt]
    

Proof state:
case mk.mk.inl.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : i < p
⊢ i ≤ p

Next tactic:
apply le_of_lt H
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    simp only [castSucc_mk, mk_lt_mk, not_lt]
    apply le_of_lt H
  · 

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

Next tactic:
rw [dif_pos]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    simp only [castSucc_mk, mk_lt_mk, not_lt]
    apply le_of_lt H
  · rw [dif_pos]
    

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

Next tactic:
rw [if_neg]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    simp only [castSucc_mk, mk_lt_mk, not_lt]
    apply le_of_lt H
  · rw [dif_pos]
    rw [if_neg]
    · 

Proof state:
case mk.mk.inr
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : p ≤ i
⊢ succ (pred { val := i, isLt := isLt✝ } (_ : { val := i, isLt := isLt✝ } ≠ 0)) = { val := i, isLt := isLt✝ }

Next tactic:
simp
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    simp only [castSucc_mk, mk_lt_mk, not_lt]
    apply le_of_lt H
  · rw [dif_pos]
    rw [if_neg]
    · simp
    · 

Proof state:
case mk.mk.inr.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : p ≤ i
⊢ ¬↑(pred { val := i, isLt := isLt✝ } (_ : { val := i, isLt := isLt✝ } ≠ 0)) < ↑{ val := p, isLt := isLt✝¹ }

Next tactic:
simp only [pred, Fin.mk_lt_mk, not_lt]
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    simp only [castSucc_mk, mk_lt_mk, not_lt]
    apply le_of_lt H
  · rw [dif_pos]
    rw [if_neg]
    · simp
    · simp only [pred, Fin.mk_lt_mk, not_lt]
      

Proof state:
case mk.mk.inr.hnc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : p ≤ i
⊢ p ≤ ↑(subNat 1 { val := i, isLt := isLt✝ } (_ : 0 < ↑{ val := i, isLt := isLt✝ }))

Next tactic:
exact Nat.le_sub_one_of_lt (h.symm.lt_of_le H)
/-- Sending `Fin (n+1)` to `Fin n` by subtracting one from anything above `p`
then back to `Fin (n+1)` with a gap around `p` is the identity away from `p`. -/
@[simp]
theorem succAbove_predAbove {p : Fin n} {i : Fin (n + 1)} (h : i ≠ castSucc p) :
    p.castSucc.succAbove (p.predAbove i) = i := by
  dsimp [predAbove, succAbove]
  rcases p with ⟨p, _⟩
  rcases i with ⟨i, _⟩
  cases' lt_or_le i p with H H
  · rw [dif_neg]
    rw [if_pos]
    rfl
    exact H
    simp only [castSucc_mk, mk_lt_mk, not_lt]
    apply le_of_lt H
  · rw [dif_pos]
    rw [if_neg]
    · simp
    · simp only [pred, Fin.mk_lt_mk, not_lt]
      exact Nat.le_sub_one_of_lt (h.symm.lt_of_le H)
    · 

Proof state:
case mk.mk.inr.hc
n m p : ℕ
isLt✝¹ : p < n
i : ℕ
isLt✝ : i < n + 1
h : { val := i, isLt := isLt✝ } ≠ castSucc { val := p, isLt := isLt✝¹ }
H : p ≤ i
⊢ castSucc { val := p, isLt := isLt✝¹ } < { val := i, isLt := isLt✝ }

Next tactic:
exact lt_of_le_of_ne H h.symm
/-- 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
  

Proof state:
n m : ℕ
p i : Fin n
⊢ predAbove p (succAbove (castSucc p) i) = i

Next tactic:
dsimp [predAbove, succAbove]
/-- 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]
  

Proof state:
n m : ℕ
p i : Fin n
⊢ (if h : castSucc p < if ↑i < ↑p then castSucc i else succ i then
      pred (if ↑i < ↑p then castSucc i else succ i) (_ : (if ↑i < ↑p then castSucc i else succ i) ≠ 0)
    else castLT (if ↑i < ↑p then castSucc i else succ i) (_ : ↑(if ↑i < ↑p then castSucc i else succ i) < n)) =
    i

Next tactic:
rcases p with ⟨p, _⟩