l3lab/ntp-mathlib huggingface dataset:
theorem repeat_succ {α : Type*} (a : Fin n → α) (m : ℕ) :
    Fin.repeat m.succ a =
      append a (Fin.repeat m a) ∘ cast ((Nat.succ_mul _ _).trans (add_comm _ _)) := by
  generalize_proofs h
  apply funext
  rw [(Fin.rightInverse_cast h.symm).surjective.forall]
  

Proof state:
case h
m✝ n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m : ℕ
h : Nat.succ m * n = n + m * n
⊢ ∀ (x : Fin (n + m * n)),
    repeat (Nat.succ m) a (cast (_ : n + m * n = Nat.succ m * n) x) =
      (append a (repeat m a) ∘ cast h) (cast (_ : n + m * n = Nat.succ m * n) x)

Next tactic:
refine' Fin.addCases (fun l => _) fun r => _
theorem repeat_succ {α : Type*} (a : Fin n → α) (m : ℕ) :
    Fin.repeat m.succ a =
      append a (Fin.repeat m a) ∘ cast ((Nat.succ_mul _ _).trans (add_comm _ _)) := by
  generalize_proofs h
  apply funext
  rw [(Fin.rightInverse_cast h.symm).surjective.forall]
  refine' Fin.addCases (fun l => _) fun r => _
  · 

Proof state:
case h.refine'_1
m✝ n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m : ℕ
h : Nat.succ m * n = n + m * n
l : Fin n
⊢ repeat (Nat.succ m) a (cast (_ : n + m * n = Nat.succ m * n) (castAdd (m * n) l)) =
    (append a (repeat m a) ∘ cast h) (cast (_ : n + m * n = Nat.succ m * n) (castAdd (m * n) l))

Next tactic:
simp [modNat, Nat.mod_eq_of_lt l.is_lt]
theorem repeat_succ {α : Type*} (a : Fin n → α) (m : ℕ) :
    Fin.repeat m.succ a =
      append a (Fin.repeat m a) ∘ cast ((Nat.succ_mul _ _).trans (add_comm _ _)) := by
  generalize_proofs h
  apply funext
  rw [(Fin.rightInverse_cast h.symm).surjective.forall]
  refine' Fin.addCases (fun l => _) fun r => _
  · simp [modNat, Nat.mod_eq_of_lt l.is_lt]
  · 

Proof state:
case h.refine'_2
m✝ n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m : ℕ
h : Nat.succ m * n = n + m * n
r : Fin (m * n)
⊢ repeat (Nat.succ m) a (cast (_ : n + m * n = Nat.succ m * n) (natAdd n r)) =
    (append a (repeat m a) ∘ cast h) (cast (_ : n + m * n = Nat.succ m * n) (natAdd n r))

Next tactic:
simp [modNat]
@[simp]
theorem repeat_add {α : Type*} (a : Fin n → α) (m₁ m₂ : ℕ) : Fin.repeat (m₁ + m₂) a =
    append (Fin.repeat m₁ a) (Fin.repeat m₂ a) ∘ cast (add_mul _ _ _) := by
  

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m₁ m₂ : ℕ
⊢ repeat (m₁ + m₂) a = append (repeat m₁ a) (repeat m₂ a) ∘ cast (_ : (m₁ + m₂) * n = m₁ * n + m₂ * n)

Next tactic:
generalize_proofs h
@[simp]
theorem repeat_add {α : Type*} (a : Fin n → α) (m₁ m₂ : ℕ) : Fin.repeat (m₁ + m₂) a =
    append (Fin.repeat m₁ a) (Fin.repeat m₂ a) ∘ cast (add_mul _ _ _) := by
  generalize_proofs h
  

Proof state:
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m₁ m₂ : ℕ
h : (m₁ + m₂) * n = m₁ * n + m₂ * n
⊢ repeat (m₁ + m₂) a = append (repeat m₁ a) (repeat m₂ a) ∘ cast h

Next tactic:
apply funext
@[simp]
theorem repeat_add {α : Type*} (a : Fin n → α) (m₁ m₂ : ℕ) : Fin.repeat (m₁ + m₂) a =
    append (Fin.repeat m₁ a) (Fin.repeat m₂ a) ∘ cast (add_mul _ _ _) := by
  generalize_proofs h
  apply funext
  

Proof state:
case h
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m₁ m₂ : ℕ
h : (m₁ + m₂) * n = m₁ * n + m₂ * n
⊢ ∀ (x : Fin ((m₁ + m₂) * n)), repeat (m₁ + m₂) a x = (append (repeat m₁ a) (repeat m₂ a) ∘ cast h) x

Next tactic:
rw [(Fin.rightInverse_cast h.symm).surjective.forall]
@[simp]
theorem repeat_add {α : Type*} (a : Fin n → α) (m₁ m₂ : ℕ) : Fin.repeat (m₁ + m₂) a =
    append (Fin.repeat m₁ a) (Fin.repeat m₂ a) ∘ cast (add_mul _ _ _) := by
  generalize_proofs h
  apply funext
  rw [(Fin.rightInverse_cast h.symm).surjective.forall]
  

Proof state:
case h
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m₁ m₂ : ℕ
h : (m₁ + m₂) * n = m₁ * n + m₂ * n
⊢ ∀ (x : Fin (m₁ * n + m₂ * n)),
    repeat (m₁ + m₂) a (cast (_ : m₁ * n + m₂ * n = (m₁ + m₂) * n) x) =
      (append (repeat m₁ a) (repeat m₂ a) ∘ cast h) (cast (_ : m₁ * n + m₂ * n = (m₁ + m₂) * n) x)

Next tactic:
refine' Fin.addCases (fun l => _) fun r => _
@[simp]
theorem repeat_add {α : Type*} (a : Fin n → α) (m₁ m₂ : ℕ) : Fin.repeat (m₁ + m₂) a =
    append (Fin.repeat m₁ a) (Fin.repeat m₂ a) ∘ cast (add_mul _ _ _) := by
  generalize_proofs h
  apply funext
  rw [(Fin.rightInverse_cast h.symm).surjective.forall]
  refine' Fin.addCases (fun l => _) fun r => _
  · 

Proof state:
case h.refine'_1
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m₁ m₂ : ℕ
h : (m₁ + m₂) * n = m₁ * n + m₂ * n
l : Fin (m₁ * n)
⊢ repeat (m₁ + m₂) a (cast (_ : m₁ * n + m₂ * n = (m₁ + m₂) * n) (castAdd (m₂ * n) l)) =
    (append (repeat m₁ a) (repeat m₂ a) ∘ cast h) (cast (_ : m₁ * n + m₂ * n = (m₁ + m₂) * n) (castAdd (m₂ * n) l))

Next tactic:
simp [modNat, Nat.mod_eq_of_lt l.is_lt]
@[simp]
theorem repeat_add {α : Type*} (a : Fin n → α) (m₁ m₂ : ℕ) : Fin.repeat (m₁ + m₂) a =
    append (Fin.repeat m₁ a) (Fin.repeat m₂ a) ∘ cast (add_mul _ _ _) := by
  generalize_proofs h
  apply funext
  rw [(Fin.rightInverse_cast h.symm).surjective.forall]
  refine' Fin.addCases (fun l => _) fun r => _
  · simp [modNat, Nat.mod_eq_of_lt l.is_lt]
  · 

Proof state:
case h.refine'_2
m n : ℕ
α✝ : Fin (n + 1) → Type u
x : α✝ 0
q : (i : Fin (n + 1)) → α✝ i
p : (i : Fin n) → α✝ (succ i)
i : Fin n
y : α✝ (succ i)
z : α✝ 0
α : Type u_1
a : Fin n → α
m₁ m₂ : ℕ
h : (m₁ + m₂) * n = m₁ * n + m₂ * n
r : Fin (m₂ * n)
⊢ repeat (m₁ + m₂) a (cast (_ : m₁ * n + m₂ * n = (m₁ + m₂) * n) (natAdd (m₁ * n) r)) =
    (append (repeat m₁ a) (repeat m₂ a) ∘ cast h) (cast (_ : m₁ * n + m₂ * n = (m₁ + m₂) * n) (natAdd (m₁ * n) r))

Next tactic:
simp [modNat, Nat.add_mod]
/-- Adding an element at the end of an `n`-tuple, to get an `n+1`-tuple. The name `snoc` comes from
`cons` (i.e., adding an element to the left of a tuple) read in reverse order. -/
def snoc (p : ∀ i : Fin n, α (castSucc i)) (x : α (last n)) (i : Fin (n + 1)) : α i :=
  if h : i.val < n then _root_.cast (by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x✝ : α (last n)
q : (i : Fin (n + 1)) → α i
p✝ : (i : Fin n) → α (castSucc i)
i✝ : Fin n
y : α (castSucc i✝)
z : α (last n)
p : (i : Fin n) → α (castSucc i)
x : α (last n)
i : Fin (n + 1)
h : ↑i < n
⊢ α (castSucc (castLT i h)) = α i

Next tactic:
rw [Fin.castSucc_castLT i h]
/-- Adding an element at the end of an `n`-tuple, to get an `n+1`-tuple. The name `snoc` comes from
`cons` (i.e., adding an element to the left of a tuple) read in reverse order. -/
def snoc (p : ∀ i : Fin n, α (castSucc i)) (x : α (last n)) (i : Fin (n + 1)) : α i :=
  if h : i.val < n then _root_.cast (by rw [Fin.castSucc_castLT i h]) (p (castLT i h))
  else _root_.cast (by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x✝ : α (last n)
q : (i : Fin (n + 1)) → α i
p✝ : (i : Fin n) → α (castSucc i)
i✝ : Fin n
y : α (castSucc i✝)
z : α (last n)
p : (i : Fin n) → α (castSucc i)
x : α (last n)
i : Fin (n + 1)
h : ¬↑i < n
⊢ α (last n) = α i

Next tactic:
rw [eq_last_of_not_lt h]
@[simp]
theorem init_snoc : init (snoc p x) = p := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
⊢ init (snoc p x) = p

Next tactic:
ext i
@[simp]
theorem init_snoc : init (snoc p x) = p := by
  ext i
  

Proof state:
case h
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i✝ : Fin n
y : α (castSucc i✝)
z : α (last n)
i : Fin n
⊢ init (snoc p x) i = p i

Next tactic:
simp only [init, snoc, coe_castSucc, is_lt, cast_eq, dite_true]
@[simp]
theorem init_snoc : init (snoc p x) = p := by
  ext i
  simp only [init, snoc, coe_castSucc, is_lt, cast_eq, dite_true]
  

Proof state:
case h
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i✝ : Fin n
y : α (castSucc i✝)
z : α (last n)
i : Fin n
⊢ p (castLT (castSucc i) (_ : ↑i < n)) = p i

Next tactic:
convert cast_eq rfl (p i)
@[simp]
theorem snoc_castSucc : snoc p x (castSucc i) = p i := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
⊢ snoc p x (castSucc i) = p i

Next tactic:
simp only [snoc, coe_castSucc, is_lt, cast_eq, dite_true]
@[simp]
theorem snoc_castSucc : snoc p x (castSucc i) = p i := by
  simp only [snoc, coe_castSucc, is_lt, cast_eq, dite_true]
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
⊢ p (castLT (castSucc i) (_ : ↑i < n)) = p i

Next tactic:
convert cast_eq rfl (p i)
@[simp]
theorem snoc_comp_castSucc {n : ℕ} {α : Sort _} {a : α} {f : Fin n → α} :
    (snoc f a : Fin (n + 1) → α) ∘ castSucc = f :=
  funext fun i ↦ by 

Proof state:
m n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i✝ : Fin n✝
y : α✝ (castSucc i✝)
z : α✝ (last n✝)
n : ℕ
α : Type u_1
a : α
f : Fin n → α
i : Fin n
⊢ (snoc f a ∘ castSucc) i = f i

Next tactic:
rw [Function.comp_apply, snoc_castSucc]
@[simp]
theorem snoc_last : snoc p x (last n) = x := by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
⊢ snoc p x (last n) = x

Next tactic:
simp [snoc]
@[simp]
theorem snoc_comp_nat_add {n m : ℕ} {α : Sort _} (f : Fin (m + n) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ (natAdd m : Fin (n + 1) → Fin (m + n + 1)) =
      snoc (f ∘ natAdd m) a := by
  

Proof state:
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i : Fin n✝
y : α✝ (castSucc i)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (m + n) → α
a : α
⊢ snoc f a ∘ natAdd m = snoc (f ∘ natAdd m) a

Next tactic:
ext i
@[simp]
theorem snoc_comp_nat_add {n m : ℕ} {α : Sort _} (f : Fin (m + n) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ (natAdd m : Fin (n + 1) → Fin (m + n + 1)) =
      snoc (f ∘ natAdd m) a := by
  ext i
  

Proof state:
case h
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i✝ : Fin n✝
y : α✝ (castSucc i✝)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (m + n) → α
a : α
i : Fin (n + 1)
⊢ (snoc f a ∘ natAdd m) i = snoc (f ∘ natAdd m) a i

Next tactic:
refine' Fin.lastCases _ (fun i ↦ _) i
@[simp]
theorem snoc_comp_nat_add {n m : ℕ} {α : Sort _} (f : Fin (m + n) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ (natAdd m : Fin (n + 1) → Fin (m + n + 1)) =
      snoc (f ∘ natAdd m) a := by
  ext i
  refine' Fin.lastCases _ (fun i ↦ _) i
  · 

Proof state:
case h.refine'_1
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i✝ : Fin n✝
y : α✝ (castSucc i✝)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (m + n) → α
a : α
i : Fin (n + 1)
⊢ (snoc f a ∘ natAdd m) (last n) = snoc (f ∘ natAdd m) a (last n)

Next tactic:
simp only [Function.comp_apply]
@[simp]
theorem snoc_comp_nat_add {n m : ℕ} {α : Sort _} (f : Fin (m + n) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ (natAdd m : Fin (n + 1) → Fin (m + n + 1)) =
      snoc (f ∘ natAdd m) a := by
  ext i
  refine' Fin.lastCases _ (fun i ↦ _) i
  · simp only [Function.comp_apply]
    

Proof state:
case h.refine'_1
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i✝ : Fin n✝
y : α✝ (castSucc i✝)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (m + n) → α
a : α
i : Fin (n + 1)
⊢ snoc f a (natAdd m (last n)) = snoc (f ∘ natAdd m) a (last n)

Next tactic:
rw [snoc_last, natAdd_last, snoc_last]
@[simp]
theorem snoc_comp_nat_add {n m : ℕ} {α : Sort _} (f : Fin (m + n) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ (natAdd m : Fin (n + 1) → Fin (m + n + 1)) =
      snoc (f ∘ natAdd m) a := by
  ext i
  refine' Fin.lastCases _ (fun i ↦ _) i
  · simp only [Function.comp_apply]
    rw [snoc_last, natAdd_last, snoc_last]
  · 

Proof state:
case h.refine'_2
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i✝¹ : Fin n✝
y : α✝ (castSucc i✝¹)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (m + n) → α
a : α
i✝ : Fin (n + 1)
i : Fin n
⊢ (snoc f a ∘ natAdd m) (castSucc i) = snoc (f ∘ natAdd m) a (castSucc i)

Next tactic:
simp only [comp_apply, snoc_castSucc]
@[simp]
theorem snoc_comp_nat_add {n m : ℕ} {α : Sort _} (f : Fin (m + n) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ (natAdd m : Fin (n + 1) → Fin (m + n + 1)) =
      snoc (f ∘ natAdd m) a := by
  ext i
  refine' Fin.lastCases _ (fun i ↦ _) i
  · simp only [Function.comp_apply]
    rw [snoc_last, natAdd_last, snoc_last]
  · simp only [comp_apply, snoc_castSucc]
    

Proof state:
case h.refine'_2
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i✝¹ : Fin n✝
y : α✝ (castSucc i✝¹)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (m + n) → α
a : α
i✝ : Fin (n + 1)
i : Fin n
⊢ snoc f a (natAdd m (castSucc i)) = f (natAdd m i)

Next tactic:
rw [natAdd_castSucc, snoc_castSucc]
@[simp]
theorem snoc_comp_cast_add {n m : ℕ} {α : Sort _} (f : Fin (n + m) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ castAdd (m + 1) = f ∘ castAdd m :=
  funext (by 

Proof state:
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i : Fin n✝
y : α✝ (castSucc i)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (n + m) → α
a : α
⊢ ∀ (x : Fin n), (snoc f a ∘ castAdd (m + 1)) x = (f ∘ castAdd m) x

Next tactic:
unfold comp
@[simp]
theorem snoc_comp_cast_add {n m : ℕ} {α : Sort _} (f : Fin (n + m) → α) (a : α) :
    (snoc f a : Fin _ → α) ∘ castAdd (m + 1) = f ∘ castAdd m :=
  funext (by unfold comp; 

Proof state:
m✝ n✝ : ℕ
α✝ : Fin (n✝ + 1) → Type u
x : α✝ (last n✝)
q : (i : Fin (n✝ + 1)) → α✝ i
p : (i : Fin n✝) → α✝ (castSucc i)
i : Fin n✝
y : α✝ (castSucc i)
z : α✝ (last n✝)
n m : ℕ
α : Type u_1
f : Fin (n + m) → α
a : α
⊢ ∀ (x : Fin n), snoc f a (castAdd (m + 1) x) = f (castAdd m x)

Next tactic:
exact snoc_cast_add _ _
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
⊢ snoc (update p i y) x = update (snoc p x) (castSucc i) y

Next tactic:
ext j
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  

Proof state:
case h
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
⊢ snoc (update p i y) x j = update (snoc p x) (castSucc i) y j

Next tactic:
by_cases h : j.val < n
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · 

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
⊢ snoc (update p i y) x j = update (snoc p x) (castSucc i) y j

Next tactic:
rw [snoc]
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
⊢ (if h : ↑j < n then _root_.cast (_ : α (castSucc (castLT j h)) = α j) (update p i y (castLT j h))
    else _root_.cast (_ : α (last n) = α j) x) =
    update (snoc p x) (castSucc i) y j

Next tactic:
simp only [h]
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
⊢ (if h_1 : True then
      _root_.cast (_ : α (castSucc (castLT j (_ : ↑j < n))) = α j) (update p i y (castLT j (_ : ↑j < n)))
    else _root_.cast (_ : α (last n) = α j) x) =
    update (snoc p x) (castSucc i) y j

Next tactic:
simp only [dif_pos]
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
⊢ _root_.cast (_ : α (castSucc (castLT j (_ : ↑j < n))) = α j) (update p i y (castLT j (_ : ↑j < n))) =
    update (snoc p x) (castSucc i) y j

Next tactic:
by_cases h' : j = castSucc i
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    by_cases h' : j = castSucc i
    · 

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
h' : j = castSucc i
⊢ _root_.cast (_ : α (castSucc (castLT j (_ : ↑j < n))) = α j) (update p i y (castLT j (_ : ↑j < n))) =
    update (snoc p x) (castSucc i) y j

Next tactic:
have C1 : α (castSucc i) = α j := by rw [h']
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    by_cases h' : j = castSucc i
    · have C1 : α (castSucc i) = α j := by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
h' : j = castSucc i
⊢ α (castSucc i) = α j

Next tactic:
rw [h']
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    by_cases h' : j = castSucc i
    · have C1 : α (castSucc i) = α j := by rw [h']
      

Proof state:
case pos
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
h' : j = castSucc i
C1 : α (castSucc i) = α j
⊢ _root_.cast (_ : α (castSucc (castLT j (_ : ↑j < n))) = α j) (update p i y (castLT j (_ : ↑j < n))) =
    update (snoc p x) (castSucc i) y j

Next tactic:
have E1 : update (snoc p x) (castSucc i) y j = _root_.cast C1 y := by
        have : update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y := by simp
        convert this
        · exact h'.symm
        · exact heq_of_cast_eq (congr_arg α (Eq.symm h')) rfl
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    by_cases h' : j = castSucc i
    · have C1 : α (castSucc i) = α j := by rw [h']
      have E1 : update (snoc p x) (castSucc i) y j = _root_.cast C1 y := by
        

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
h' : j = castSucc i
C1 : α (castSucc i) = α j
⊢ update (snoc p x) (castSucc i) y j = _root_.cast C1 y

Next tactic:
have : update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y := by simp
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    by_cases h' : j = castSucc i
    · have C1 : α (castSucc i) = α j := by rw [h']
      have E1 : update (snoc p x) (castSucc i) y j = _root_.cast C1 y := by
        have : update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y := by 

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
h' : j = castSucc i
C1 : α (castSucc i) = α j
⊢ update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y

Next tactic:
simp
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    by_cases h' : j = castSucc i
    · have C1 : α (castSucc i) = α j := by rw [h']
      have E1 : update (snoc p x) (castSucc i) y j = _root_.cast C1 y := by
        have : update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y := by simp
        

Proof state:
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
h' : j = castSucc i
C1 : α (castSucc i) = α j
this : update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y
⊢ update (snoc p x) (castSucc i) y j = _root_.cast C1 y

Next tactic:
convert this
/-- Updating a tuple and adding an element at the end commute. -/
@[simp]
theorem snoc_update : snoc (update p i y) x = update (snoc p x) (castSucc i) y := by
  ext j
  by_cases h : j.val < n
  · rw [snoc]
    simp only [h]
    simp only [dif_pos]
    by_cases h' : j = castSucc i
    · have C1 : α (castSucc i) = α j := by rw [h']
      have E1 : update (snoc p x) (castSucc i) y j = _root_.cast C1 y := by
        have : update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y := by simp
        convert this
        · 

Proof state:
case h.e'_2.h.e'_5
m n : ℕ
α : Fin (n + 1) → Type u
x : α (last n)
q : (i : Fin (n + 1)) → α i
p : (i : Fin n) → α (castSucc i)
i : Fin n
y : α (castSucc i)
z : α (last n)
j : Fin (n + 1)
h : ↑j < n
h' : j = castSucc i
C1 : α (castSucc i) = α j
this : update (snoc p x) j (_root_.cast C1 y) j = _root_.cast C1 y
⊢ castSucc i = j

Next tactic:
exact h'.symm