l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : castSucc j < i
H₁ : ↑(succAbove i j) < n
k : Fin n
hk : castLT (succAbove i j) H₁ = k
⊢ ∀ (H₂ : succAbove i k = succAbove i j), H₂ ▸ p k = p j

Next tactic:
rw [castLT_succAbove hlt] at hk
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; 

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : castSucc j < i
H₁ : ↑(succAbove i j) < n
k : Fin n
hk : j = k
⊢ ∀ (H₂ : succAbove i k = succAbove i j), H₂ ▸ p k = p j

Next tactic:
cases hk
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    

Proof state:
case pos.refl
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : castSucc j < i
H₁ : ↑(succAbove i j) < n
⊢ ∀ (H₂ : succAbove i j = succAbove i j), H₂ ▸ p j = p j

Next tactic:
intro
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; 

Proof state:
case pos.refl
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : castSucc j < i
H₁ : ↑(succAbove i j) < n
H₂✝ : succAbove i j = succAbove i j
⊢ H₂✝ ▸ p j = p j

Next tactic:
rfl
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; rfl
  · 

Proof state:
case neg
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : ¬castSucc j < i
⊢ (_ : succAbove i (pred (succAbove i j) (_ : succAbove i j ≠ 0)) = succAbove i j) ▸
      p (pred (succAbove i j) (_ : succAbove i j ≠ 0)) =
    p j

Next tactic:
generalize_proofs H₁ H₂
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; rfl
  · generalize_proofs H₁ H₂; 

Proof state:
case neg
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : ¬castSucc j < i
H₁ : succAbove i j ≠ 0
H₂ : succAbove i (pred (succAbove i j) (_ : succAbove i j ≠ 0)) = succAbove i j
⊢ H₂ ▸ p (pred (succAbove i j) H₁) = p j

Next tactic:
revert H₂
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; rfl
  · generalize_proofs H₁ H₂; revert H₂
    

Proof state:
case neg
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : ¬castSucc j < i
H₁ : succAbove i j ≠ 0
⊢ ∀ (H₂ : succAbove i (pred (succAbove i j) (_ : succAbove i j ≠ 0)) = succAbove i j),
    H₂ ▸ p (pred (succAbove i j) H₁) = p j

Next tactic:
generalize hk : pred ((succAboveEmb i).toEmbedding j) H₁ = k
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; rfl
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : pred ((succAboveEmb i).toEmbedding j) H₁ = k
    

Proof state:
case neg
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : ¬castSucc j < i
H₁ : succAbove i j ≠ 0
k : Fin n
hk : pred ((succAboveEmb i).toEmbedding j) H₁ = k
⊢ ∀ (H₂ : succAbove i k = succAbove i j), H₂ ▸ p k = p j

Next tactic:
erw [pred_succAbove (le_of_not_lt hlt)] at hk
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; rfl
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : pred ((succAboveEmb i).toEmbedding j) H₁ = k
    erw [pred_succAbove (le_of_not_lt hlt)] at hk; 

Proof state:
case neg
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : ¬castSucc j < i
H₁ : succAbove i j ≠ 0
k : Fin n
hk : j = k
⊢ ∀ (H₂ : succAbove i k = succAbove i j), H₂ ▸ p k = p j

Next tactic:
cases hk
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; rfl
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : pred ((succAboveEmb i).toEmbedding j) H₁ = k
    erw [pred_succAbove (le_of_not_lt hlt)] at hk; cases hk
    

Proof state:
case neg.refl
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : ¬castSucc j < i
H₁ : succAbove i j ≠ 0
⊢ ∀ (H₂ : succAbove i j = succAbove i j), H₂ ▸ p j = p j

Next tactic:
intro
@[simp]
theorem insertNth_apply_succAbove (i : Fin (n + 1)) (x : α i) (p : ∀ j, α (i.succAbove j))
    (j : Fin n) : insertNth i x p (i.succAbove j) = p j := by
  simp only [insertNth, succAboveCases, dif_neg (succAbove_ne _ _), succAbove_lt_iff]
  split_ifs with hlt
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : castLT ((succAbove i) j) H₁ = k
    rw [castLT_succAbove hlt] at hk; cases hk
    intro; rfl
  · generalize_proofs H₁ H₂; revert H₂
    generalize hk : pred ((succAboveEmb i).toEmbedding j) H₁ = k
    erw [pred_succAbove (le_of_not_lt hlt)] at hk; cases hk
    intro; 

Proof state:
case neg.refl
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
j : Fin n
hlt : ¬castSucc j < i
H₁ : succAbove i j ≠ 0
H₂✝ : succAbove i j = succAbove i j
⊢ H₂✝ ▸ p j = p j

Next tactic:
rfl
@[simp]
theorem insertNth_comp_succAbove (i : Fin (n + 1)) (x : β) (p : Fin n → β) :
    insertNth i x p ∘ i.succAbove = p :=
  funext (by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : β
p : Fin n → β
⊢ ∀ (x_1 : Fin n), (insertNth i x p ∘ succAbove i) x_1 = p x_1

Next tactic:
unfold comp
@[simp]
theorem insertNth_comp_succAbove (i : Fin (n + 1)) (x : β) (p : Fin n → β) :
    insertNth i x p ∘ i.succAbove = p :=
  funext (by unfold comp; 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : β
p : Fin n → β
⊢ ∀ (x_1 : Fin n), insertNth i x p (succAbove i x_1) = p x_1

Next tactic:
exact insertNth_apply_succAbove i _ _
theorem insertNth_eq_iff {i : Fin (n + 1)} {x : α i} {p : ∀ j, α (i.succAbove j)} {q : ∀ j, α j} :
    i.insertNth x p = q ↔ q i = x ∧ p = fun j ↦ q (i.succAbove j) := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
q : (j : Fin (n + 1)) → α j
⊢ insertNth i x p = q ↔ q i = x ∧ p = fun j => q (succAbove i j)

Next tactic:
simp [funext_iff, forall_iff_succAbove i, eq_comm]
theorem insertNth_apply_below {i j : Fin (n + 1)} (h : j < i) (x : α i)
    (p : ∀ k, α (i.succAbove k)) :
    i.insertNth x p j = @Eq.recOn _ _ (fun x _ ↦ α x) _ (succAbove_castLT h) (p <| j.castLT _) := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i j : Fin (n + 1)
h : j < i
x : α i
p : (k : Fin n) → α (succAbove i k)
⊢ insertNth i x p j = Eq.recOn (_ : succAbove i (castLT j (_ : ↑j < n)) = j) (p (castLT j (_ : ↑j < n)))

Next tactic:
rw [insertNth, succAboveCases, dif_neg h.ne, dif_pos h]
theorem insertNth_apply_above {i j : Fin (n + 1)} (h : i < j) (x : α i)
    (p : ∀ k, α (i.succAbove k)) :
    i.insertNth x p j = @Eq.recOn _ _ (fun x _ ↦ α x) _ (succAbove_pred h) (p <| j.pred _) := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
i j : Fin (n + 1)
h : i < j
x : α i
p : (k : Fin n) → α (succAbove i k)
⊢ insertNth i x p j = Eq.recOn (_ : succAbove i (pred j (_ : j ≠ 0)) = j) (p (pred j (_ : j ≠ 0)))

Next tactic:
rw [insertNth, succAboveCases, dif_neg h.ne', dif_neg h.not_lt]
theorem insertNth_zero (x : α 0) (p : ∀ j : Fin n, α (succAbove 0 j)) :
    insertNth 0 x p =
      cons x fun j ↦ _root_.cast (congr_arg α (congr_fun succAbove_zero j)) (p j) := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α 0
p : (j : Fin n) → α (succAbove 0 j)
⊢ insertNth 0 x p = cons x fun j => _root_.cast (_ : α (succAbove 0 j) = α (succ j)) (p j)

Next tactic:
refine' insertNth_eq_iff.2 ⟨by simp, _⟩
theorem insertNth_zero (x : α 0) (p : ∀ j : Fin n, α (succAbove 0 j)) :
    insertNth 0 x p =
      cons x fun j ↦ _root_.cast (congr_arg α (congr_fun succAbove_zero j)) (p j) := by
  refine' insertNth_eq_iff.2 ⟨by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α 0
p : (j : Fin n) → α (succAbove 0 j)
⊢ cons x (fun j => _root_.cast (_ : α (succAbove 0 j) = α (succ j)) (p j)) 0 = x

Next tactic:
simp
theorem insertNth_zero (x : α 0) (p : ∀ j : Fin n, α (succAbove 0 j)) :
    insertNth 0 x p =
      cons x fun j ↦ _root_.cast (congr_arg α (congr_fun succAbove_zero j)) (p j) := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α 0
p : (j : Fin n) → α (succAbove 0 j)
⊢ p = fun j => cons x (fun j => _root_.cast (_ : α (succAbove 0 j) = α (succ j)) (p j)) (succAbove 0 j)

Next tactic:
ext j
theorem insertNth_zero (x : α 0) (p : ∀ j : Fin n, α (succAbove 0 j)) :
    insertNth 0 x p =
      cons x fun j ↦ _root_.cast (congr_arg α (congr_fun succAbove_zero j)) (p j) := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  ext j
  

Proof state:
case h
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α 0
p : (j : Fin n) → α (succAbove 0 j)
j : Fin n
⊢ p j = cons x (fun j => _root_.cast (_ : α (succAbove 0 j) = α (succ j)) (p j)) (succAbove 0 j)

Next tactic:
convert (cons_succ x p j).symm
@[simp]
theorem insertNth_zero' (x : β) (p : Fin n → β) : @insertNth _ (fun _ ↦ β) 0 x p = cons x p := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : β
p : Fin n → β
⊢ insertNth 0 x p = cons x p

Next tactic:
simp [insertNth_zero]
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
⊢ insertNth (last n) x p = snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x

Next tactic:
refine' insertNth_eq_iff.2 ⟨by simp, _⟩
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
⊢ snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x (last n) = x

Next tactic:
simp
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
⊢ p = fun j =>
    snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x (succAbove (last n) j)

Next tactic:
ext j
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  ext j
  

Proof state:
case h
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
j : Fin n
⊢ p j = snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x (succAbove (last n) j)

Next tactic:
apply eq_of_heq
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  ext j
  apply eq_of_heq
  

Proof state:
case h.h
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
j : Fin n
⊢ HEq (p j) (snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x (succAbove (last n) j))

Next tactic:
trans snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x (castSucc j)
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  ext j
  apply eq_of_heq
  trans snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x (castSucc j)
  · 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
j : Fin n
⊢ HEq (p j) (snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x (castSucc j))

Next tactic:
rw [snoc_castSucc]
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  ext j
  apply eq_of_heq
  trans snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x (castSucc j)
  · rw [snoc_castSucc]
    

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
j : Fin n
⊢ HEq (p j) (_root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j))

Next tactic:
exact (cast_heq _ _).symm
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  ext j
  apply eq_of_heq
  trans snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x (castSucc j)
  · rw [snoc_castSucc]
    exact (cast_heq _ _).symm
  · 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
j : Fin n
⊢ HEq (snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x (castSucc j))
    (snoc (fun j => _root_.cast (_ : α (succAbove (last n) j) = α (castSucc j)) (p j)) x (succAbove (last n) j))

Next tactic:
apply congr_arg_heq
theorem insertNth_last (x : α (last n)) (p : ∀ j : Fin n, α ((last n).succAbove j)) :
    insertNth (last n) x p =
      snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x := by
  refine' insertNth_eq_iff.2 ⟨by simp, _⟩
  ext j
  apply eq_of_heq
  trans snoc (fun j ↦ _root_.cast (congr_arg α (succAbove_last_apply j)) (p j)) x (castSucc j)
  · rw [snoc_castSucc]
    exact (cast_heq _ _).symm
  · apply congr_arg_heq
    

Proof state:
case a
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : α (last n)
p : (j : Fin n) → α (succAbove (last n) j)
j : Fin n
⊢ castSucc j = succAbove (last n) j

Next tactic:
rw [succAbove_last]
@[simp]
theorem insertNth_last' (x : β) (p : Fin n → β) :
    @insertNth _ (fun _ ↦ β) (last n) x p = snoc p x := by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
x : β
p : Fin n → β
⊢ insertNth (last n) x p = snoc p x

Next tactic:
simp [insertNth_last]
@[simp]
theorem insertNth_zero_right [∀ j, Zero (α j)] (i : Fin (n + 1)) (x : α i) :
    i.insertNth x 0 = Pi.single i x :=
  insertNth_eq_iff.2 <| by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
inst✝ : (j : Fin (n + 1)) → Zero (α j)
i : Fin (n + 1)
x : α i
⊢ Pi.single i x i = x ∧ 0 = fun j => Pi.single i x (succAbove i j)

Next tactic:
simp [succAbove_ne, Pi.zero_def]
theorem insertNth_binop (op : ∀ j, α j → α j → α j) (i : Fin (n + 1)) (x y : α i)
    (p q : ∀ j, α (i.succAbove j)) :
    (i.insertNth (op i x y) fun j ↦ op _ (p j) (q j)) = fun j ↦
      op j (i.insertNth x p j) (i.insertNth y q j) :=
  insertNth_eq_iff.2 <| by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
op : (j : Fin (n + 1)) → α j → α j → α j
i : Fin (n + 1)
x y : α i
p q : (j : Fin n) → α (succAbove i j)
⊢ op i (insertNth i x p i) (insertNth i y q i) = op i x y ∧
    (fun j => op (succAbove i j) (p j) (q j)) = fun j =>
      op (succAbove i j) (insertNth i x p (succAbove i j)) (insertNth i y q (succAbove i j))

Next tactic:
simp
@[simp]
theorem insertNth_sub_same [∀ j, AddGroup (α j)] (i : Fin (n + 1)) (x y : α i)
    (p : ∀ j, α (i.succAbove j)) : i.insertNth x p - i.insertNth y p = Pi.single i (x - y) := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
inst✝ : (j : Fin (n + 1)) → AddGroup (α j)
i : Fin (n + 1)
x y : α i
p : (j : Fin n) → α (succAbove i j)
⊢ insertNth i x p - insertNth i y p = Pi.single i (x - y)

Next tactic:
simp_rw [← insertNth_sub, ← insertNth_zero_right, Pi.sub_def, sub_self, Pi.zero_def]
theorem insertNth_le_iff {i : Fin (n + 1)} {x : α i} {p : ∀ j, α (i.succAbove j)} {q : ∀ j, α j} :
    i.insertNth x p ≤ q ↔ x ≤ q i ∧ p ≤ fun j ↦ q (i.succAbove j) := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
inst✝ : (i : Fin (n + 1)) → Preorder (α i)
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
q : (j : Fin (n + 1)) → α j
⊢ insertNth i x p ≤ q ↔ x ≤ q i ∧ p ≤ fun j => q (succAbove i j)

Next tactic:
simp [Pi.le_def, forall_iff_succAbove i]
theorem le_insertNth_iff {i : Fin (n + 1)} {x : α i} {p : ∀ j, α (i.succAbove j)} {q : ∀ j, α j} :
    q ≤ i.insertNth x p ↔ q i ≤ x ∧ (fun j ↦ q (i.succAbove j)) ≤ p := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
inst✝ : (i : Fin (n + 1)) → Preorder (α i)
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
q : (j : Fin (n + 1)) → α j
⊢ q ≤ insertNth i x p ↔ q i ≤ x ∧ (fun j => q (succAbove i j)) ≤ p

Next tactic:
simp [Pi.le_def, forall_iff_succAbove i]
theorem insertNth_mem_Icc {i : Fin (n + 1)} {x : α i} {p : ∀ j, α (i.succAbove j)}
    {q₁ q₂ : ∀ j, α j} :
    i.insertNth x p ∈ Icc q₁ q₂ ↔
      x ∈ Icc (q₁ i) (q₂ i) ∧ p ∈ Icc (fun j ↦ q₁ (i.succAbove j)) fun j ↦ q₂ (i.succAbove j) := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
inst✝ : (i : Fin (n + 1)) → Preorder (α i)
i : Fin (n + 1)
x : α i
p : (j : Fin n) → α (succAbove i j)
q₁ q₂ : (j : Fin (n + 1)) → α j
⊢ insertNth i x p ∈ Icc q₁ q₂ ↔
    x ∈ Icc (q₁ i) (q₂ i) ∧ p ∈ Icc (fun j => q₁ (succAbove i j)) fun j => q₂ (succAbove i j)

Next tactic:
simp only [mem_Icc, insertNth_le_iff, le_insertNth_iff, and_assoc, @and_left_comm (x ≤ q₂ i)]
theorem preimage_insertNth_Icc_of_mem {i : Fin (n + 1)} {x : α i} {q₁ q₂ : ∀ j, α j}
    (hx : x ∈ Icc (q₁ i) (q₂ i)) :
    i.insertNth x ⁻¹' Icc q₁ q₂ = Icc (fun j ↦ q₁ (i.succAbove j)) fun j ↦ q₂ (i.succAbove j) :=
  Set.ext fun p ↦ by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
inst✝ : (i : Fin (n + 1)) → Preorder (α i)
i : Fin (n + 1)
x : α i
q₁ q₂ : (j : Fin (n + 1)) → α j
hx : x ∈ Icc (q₁ i) (q₂ i)
p : (j : Fin n) → α (succAbove i j)
⊢ p ∈ insertNth i x ⁻¹' Icc q₁ q₂ ↔ p ∈ Icc (fun j => q₁ (succAbove i j)) fun j => q₂ (succAbove i j)

Next tactic:
simp only [mem_preimage, insertNth_mem_Icc, hx, true_and_iff]
theorem preimage_insertNth_Icc_of_not_mem {i : Fin (n + 1)} {x : α i} {q₁ q₂ : ∀ j, α j}
    (hx : x ∉ Icc (q₁ i) (q₂ i)) : i.insertNth x ⁻¹' Icc q₁ q₂ = ∅ :=
  Set.ext fun p ↦ by
    

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
β : Type v
inst✝ : (i : Fin (n + 1)) → Preorder (α i)
i : Fin (n + 1)
x : α i
q₁ q₂ : (j : Fin (n + 1)) → α j
hx : x ∉ Icc (q₁ i) (q₂ i)
p : (j : Fin n) → α (succAbove i j)
⊢ p ∈ insertNth i x ⁻¹' Icc q₁ q₂ ↔ p ∈ ∅

Next tactic:
simp only [mem_preimage, insertNth_mem_Icc, hx, false_and_iff, mem_empty_iff_false]
/-- `find p` returns the first index `n` where `p n` is satisfied, and `none` if it is never
satisfied. -/
def find : ∀ {n : ℕ} (p : Fin n → Prop) [DecidablePred p], Option (Fin n)
  | 0, _p, _ => none
  | n + 1, p, _ => by
    

Proof state:
m n✝ n : ℕ
p : Fin (n + 1) → Prop
x✝ : DecidablePred p
⊢ Option (Fin (n + 1))

Next tactic:
exact
      Option.casesOn (@find n (fun i ↦ p (i.castLT (Nat.lt_succ_of_lt i.2))) _)
        (if _ : p (Fin.last n) then some (Fin.last n) else none) fun i ↦
        some (i.castLT (Nat.lt_succ_of_lt i.2))
/-- If `find p = some i`, then `p i` holds -/
theorem find_spec :
    ∀ {n : ℕ} (p : Fin n → Prop) [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p), p i
  | 0, p, I, i, hi => Option.noConfusion hi
  | n + 1, p, I, i, hi => by
    

Proof state:
m n✝ n : ℕ
p : Fin (n + 1) → Prop
I : DecidablePred p
i : Fin (n + 1)
hi : i ∈ find p
⊢ p i

Next tactic:
rw [find] at hi
/-- If `find p = some i`, then `p i` holds -/
theorem find_spec :
    ∀ {n : ℕ} (p : Fin n → Prop) [DecidablePred p] {i : Fin n} (_ : i ∈ Fin.find p), p i
  | 0, p, I, i, hi => Option.noConfusion hi
  | n + 1, p, I, i, hi => by
    rw [find] at hi
    

Proof state:
m n✝ n : ℕ
p : Fin (n + 1) → Prop
I : DecidablePred p
i : Fin (n + 1)
hi :
  i ∈
    Option.casesOn (find fun i => p (castLT i (_ : ↑i < Nat.succ n))) (if x : p (last n) then some (last n) else none)
      fun i => some (castLT i (_ : ↑i < Nat.succ n))
⊢ p i

Next tactic:
cases' h : find fun i : Fin n ↦ p (i.castLT (Nat.lt_succ_of_lt i.2)) with j