l3lab/ntp-mathlib huggingface dataset:
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := 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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
⊢ append (append a b) c = append a (append b c) ∘ cast (_ : m + n + p = m + (n + p))

Next tactic:
ext i
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  

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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
⊢ append (append a b) c i = (append a (append b c) ∘ cast (_ : m + n + p = m + (n + p))) i

Next tactic:
rw [Function.comp_apply]
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  

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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
⊢ append (append a b) c i = append a (append b c) (cast (_ : m + n + p = m + (n + p)) i)

Next tactic:
refine' Fin.addCases (fun l => _) (fun r => _) i
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · 

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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
l : Fin (m + n)
⊢ append (append a b) c (castAdd p l) = append a (append b c) (cast (_ : m + n + p = m + (n + p)) (castAdd p l))

Next tactic:
rw [append_left]
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · rw [append_left]
    

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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
l : Fin (m + n)
⊢ append a b l = append a (append b c) (cast (_ : m + n + p = m + (n + p)) (castAdd p l))

Next tactic:
refine' Fin.addCases (fun ll => _) (fun lr => _) l
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · rw [append_left]
    refine' Fin.addCases (fun ll => _) (fun lr => _) l
    · 

Proof state:
case h.refine'_1.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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
l : Fin (m + n)
ll : Fin m
⊢ append a b (castAdd n ll) = append a (append b c) (cast (_ : m + n + p = m + (n + p)) (castAdd p (castAdd n ll)))

Next tactic:
rw [append_left]
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · rw [append_left]
    refine' Fin.addCases (fun ll => _) (fun lr => _) l
    · rw [append_left]
      

Proof state:
case h.refine'_1.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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
l : Fin (m + n)
ll : Fin m
⊢ a ll = append a (append b c) (cast (_ : m + n + p = m + (n + p)) (castAdd p (castAdd n ll)))

Next tactic:
simp [castAdd_castAdd]
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · rw [append_left]
    refine' Fin.addCases (fun ll => _) (fun lr => _) l
    · rw [append_left]
      simp [castAdd_castAdd]
    · 

Proof state:
case h.refine'_1.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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
l : Fin (m + n)
lr : Fin n
⊢ append a b (natAdd m lr) = append a (append b c) (cast (_ : m + n + p = m + (n + p)) (castAdd p (natAdd m lr)))

Next tactic:
rw [append_right]
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · rw [append_left]
    refine' Fin.addCases (fun ll => _) (fun lr => _) l
    · rw [append_left]
      simp [castAdd_castAdd]
    · rw [append_right]
      

Proof state:
case h.refine'_1.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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
l : Fin (m + n)
lr : Fin n
⊢ b lr = append a (append b c) (cast (_ : m + n + p = m + (n + p)) (castAdd p (natAdd m lr)))

Next tactic:
simp [castAdd_natAdd]
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · rw [append_left]
    refine' Fin.addCases (fun ll => _) (fun lr => _) l
    · rw [append_left]
      simp [castAdd_castAdd]
    · rw [append_right]
      simp [castAdd_natAdd]
  · 

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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
r : Fin p
⊢ append (append a b) c (natAdd (m + n) r) =
    append a (append b c) (cast (_ : m + n + p = m + (n + p)) (natAdd (m + n) r))

Next tactic:
rw [append_right]
theorem append_assoc {p : ℕ} {α : Type*} (a : Fin m → α) (b : Fin n → α) (c : Fin p → α) :
    append (append a b) c = append a (append b c) ∘ Fin.cast (add_assoc _ _ _) := by
  ext i
  rw [Function.comp_apply]
  refine' Fin.addCases (fun l => _) (fun r => _) i
  · rw [append_left]
    refine' Fin.addCases (fun ll => _) (fun lr => _) l
    · rw [append_left]
      simp [castAdd_castAdd]
    · rw [append_right]
      simp [castAdd_natAdd]
  · rw [append_right]
    

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
p : ℕ
α : Type u_1
a : Fin m → α
b : Fin n → α
c : Fin p → α
i : Fin (m + n + p)
r : Fin p
⊢ c r = append a (append b c) (cast (_ : m + n + p = m + (n + p)) (natAdd (m + n) r))

Next tactic:
simp [← natAdd_natAdd]
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := 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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
⊢ append x₀ x = cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)

Next tactic:
ext i
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
i : Fin (1 + n)
⊢ append x₀ x i = (cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)) i

Next tactic:
refine' Fin.addCases _ _ i
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> 

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
i : Fin (1 + n)
⊢ ∀ (i : Fin 1), append x₀ x (castAdd n i) = (cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)) (castAdd n i)

Next tactic:
clear i
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> 

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
i : Fin (1 + n)
⊢ ∀ (i : Fin n), append x₀ x (natAdd 1 i) = (cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)) (natAdd 1 i)

Next tactic:
clear i
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> clear i
  · 

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
⊢ ∀ (i : Fin 1), append x₀ x (castAdd n i) = (cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)) (castAdd n i)

Next tactic:
intro i
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> clear i
  · intro i
    

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
i : Fin 1
⊢ append x₀ x (castAdd n i) = (cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)) (castAdd n i)

Next tactic:
rw [Subsingleton.elim i 0, Fin.append_left, Function.comp_apply, eq_comm]
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> clear i
  · intro i
    rw [Subsingleton.elim i 0, Fin.append_left, Function.comp_apply, eq_comm]
    

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
i : Fin 1
⊢ cons (x₀ 0) x (cast (_ : 1 + n = n + 1) (castAdd n 0)) = x₀ 0

Next tactic:
exact Fin.cons_zero _ _
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> clear i
  · intro i
    rw [Subsingleton.elim i 0, Fin.append_left, Function.comp_apply, eq_comm]
    exact Fin.cons_zero _ _
  · 

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
⊢ ∀ (i : Fin n), append x₀ x (natAdd 1 i) = (cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)) (natAdd 1 i)

Next tactic:
intro i
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> clear i
  · intro i
    rw [Subsingleton.elim i 0, Fin.append_left, Function.comp_apply, eq_comm]
    exact Fin.cons_zero _ _
  · intro i
    

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
i : Fin n
⊢ append x₀ x (natAdd 1 i) = (cons (x₀ 0) x ∘ cast (_ : 1 + n = n + 1)) (natAdd 1 i)

Next tactic:
rw [Fin.append_right, Function.comp_apply, Fin.cast_natAdd, eq_comm, Fin.addNat_one]
/-- Appending a one-tuple to the left is the same as `Fin.cons`. -/
theorem append_left_eq_cons {α : Type*} {n : ℕ} (x₀ : Fin 1 → α) (x : Fin n → α) :
    Fin.append x₀ x = Fin.cons (x₀ 0) x ∘ Fin.cast (add_comm _ _) := by
  ext i
  refine' Fin.addCases _ _ i <;> clear i
  · intro i
    rw [Subsingleton.elim i 0, Fin.append_left, Function.comp_apply, eq_comm]
    exact Fin.cons_zero _ _
  · intro i
    rw [Fin.append_right, Function.comp_apply, Fin.cast_natAdd, eq_comm, Fin.addNat_one]
    

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
n : ℕ
x₀ : Fin 1 → α
x : Fin n → α
i : Fin n
⊢ cons (x₀ 0) x (succ i) = x i

Next tactic:
exact Fin.cons_succ _ _ _
/-- `Fin.cons` is the same as appending a one-tuple to the left. -/
theorem cons_eq_append {α : Type*} (x : α) (xs : Fin n → α) :
    cons x xs = append (cons x Fin.elim0) xs ∘ Fin.cast (add_comm ..) := 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
x : α
xs : Fin n → α
⊢ cons x xs = append (cons x elim0) xs ∘ cast (_ : n + (0 + 1) = 0 + 1 + n)

Next tactic:
funext i
/-- `Fin.cons` is the same as appending a one-tuple to the left. -/
theorem cons_eq_append {α : Type*} (x : α) (xs : Fin n → α) :
    cons x xs = append (cons x Fin.elim0) xs ∘ Fin.cast (add_comm ..) := by
  funext i; 

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
x : α
xs : Fin n → α
i : Fin (n + 1)
⊢ cons x xs i = (append (cons x elim0) xs ∘ cast (_ : n + (0 + 1) = 0 + 1 + n)) i

Next tactic:
simp [append_left_eq_cons]
@[simp] lemma append_cast_left {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (n' : ℕ)
    (h : n' = n) :
    Fin.append (xs ∘ Fin.cast h) ys = Fin.append xs ys ∘ (Fin.cast <| 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
n m : ℕ
α : Type u_1
xs : Fin n → α
ys : Fin m → α
n' : ℕ
h : n' = n
⊢ n' + m = n + m

Next tactic:
rw [h]
@[simp] lemma append_cast_left {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (n' : ℕ)
    (h : n' = n) :
    Fin.append (xs ∘ Fin.cast h) ys = Fin.append xs ys ∘ (Fin.cast <| by rw [h]) := 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
n m : ℕ
α : Type u_1
xs : Fin n → α
ys : Fin m → α
n' : ℕ
h : n' = n
⊢ append (xs ∘ cast h) ys = append xs ys ∘ cast (_ : n' + m = n + m)

Next tactic:
subst h
@[simp] lemma append_cast_left {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (n' : ℕ)
    (h : n' = n) :
    Fin.append (xs ∘ Fin.cast h) ys = Fin.append xs ys ∘ (Fin.cast <| by rw [h]) := by
  subst 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
m : ℕ
α : Type u_1
ys : Fin m → α
n' : ℕ
xs : Fin n' → α
⊢ append (xs ∘ cast (_ : n' = n')) ys = append xs ys ∘ cast (_ : n' + m = n' + m)

Next tactic:
funext i
@[simp] lemma append_cast_left {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (n' : ℕ)
    (h : n' = n) :
    Fin.append (xs ∘ Fin.cast h) ys = Fin.append xs ys ∘ (Fin.cast <| by rw [h]) := by
  subst h
  funext i
  

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
m : ℕ
α : Type u_1
ys : Fin m → α
n' : ℕ
xs : Fin n' → α
i : Fin (n' + m)
⊢ append (xs ∘ cast (_ : n' = n')) ys i = (append xs ys ∘ cast (_ : n' + m = n' + m)) i

Next tactic:
simp (config := {unfoldPartialApp := true}) only [Fin.append, Fin.addCases, comp_def, Fin.cast,
    Fin.coe_castLT, Fin.subNat_mk, Fin.natAdd_mk, ge_iff_le, eq_rec_constant, Fin.eta, Eq.ndrec,
    id_eq, eq_mpr_eq_cast, cast_eq]
@[simp] lemma append_cast_right {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (m' : ℕ)
    (h : m' = m) :
    Fin.append xs (ys ∘ Fin.cast h) = Fin.append xs ys ∘ (Fin.cast <| 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
n m : ℕ
α : Type u_1
xs : Fin n → α
ys : Fin m → α
m' : ℕ
h : m' = m
⊢ n + m' = n + m

Next tactic:
rw [h]
@[simp] lemma append_cast_right {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (m' : ℕ)
    (h : m' = m) :
    Fin.append xs (ys ∘ Fin.cast h) = Fin.append xs ys ∘ (Fin.cast <| by rw [h]) := 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
n m : ℕ
α : Type u_1
xs : Fin n → α
ys : Fin m → α
m' : ℕ
h : m' = m
⊢ append xs (ys ∘ cast h) = append xs ys ∘ cast (_ : n + m' = n + m)

Next tactic:
subst h
@[simp] lemma append_cast_right {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (m' : ℕ)
    (h : m' = m) :
    Fin.append xs (ys ∘ Fin.cast h) = Fin.append xs ys ∘ (Fin.cast <| by rw [h]) := by
  subst 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
n : ℕ
α : Type u_1
xs : Fin n → α
m' : ℕ
ys : Fin m' → α
⊢ append xs (ys ∘ cast (_ : m' = m')) = append xs ys ∘ cast (_ : n + m' = n + m')

Next tactic:
funext i
@[simp] lemma append_cast_right {n m} {α : Type*} (xs : Fin n → α) (ys : Fin m → α) (m' : ℕ)
    (h : m' = m) :
    Fin.append xs (ys ∘ Fin.cast h) = Fin.append xs ys ∘ (Fin.cast <| by rw [h]) := by
  subst h
  funext i
  

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
n : ℕ
α : Type u_1
xs : Fin n → α
m' : ℕ
ys : Fin m' → α
i : Fin (n + m')
⊢ append xs (ys ∘ cast (_ : m' = m')) i = (append xs ys ∘ cast (_ : n + m' = n + m')) i

Next tactic:
simp only [append, addCases, cast, subNat_mk, natAdd_mk, Fin.eta, ge_iff_le, comp_apply,
    eq_rec_constant]
@[simp]
theorem repeat_one {α : Type*} (a : Fin n → α) : Fin.repeat 1 a = a ∘ cast (one_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 → α
⊢ repeat 1 a = a ∘ cast (_ : 1 * n = n)

Next tactic:
generalize_proofs h
@[simp]
theorem repeat_one {α : Type*} (a : Fin n → α) : Fin.repeat 1 a = a ∘ cast (one_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 → α
h : 1 * n = n
⊢ repeat 1 a = a ∘ cast h

Next tactic:
apply funext
@[simp]
theorem repeat_one {α : Type*} (a : Fin n → α) : Fin.repeat 1 a = a ∘ cast (one_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 → α
h : 1 * n = n
⊢ ∀ (x : Fin (1 * n)), repeat 1 a x = (a ∘ cast h) x

Next tactic:
rw [(Fin.rightInverse_cast h.symm).surjective.forall]
@[simp]
theorem repeat_one {α : Type*} (a : Fin n → α) : Fin.repeat 1 a = a ∘ cast (one_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 → α
h : 1 * n = n
⊢ ∀ (x : Fin n), repeat 1 a (cast (_ : n = 1 * n) x) = (a ∘ cast h) (cast (_ : n = 1 * n) x)

Next tactic:
intro i
@[simp]
theorem repeat_one {α : Type*} (a : Fin n → α) : Fin.repeat 1 a = a ∘ cast (one_mul _) := by
  generalize_proofs h
  apply funext
  rw [(Fin.rightInverse_cast h.symm).surjective.forall]
  intro i
  

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 → α
h : 1 * n = n
i : Fin n
⊢ repeat 1 a (cast (_ : n = 1 * n) i) = (a ∘ cast h) (cast (_ : n = 1 * n) i)

Next tactic:
simp [modNat, Nat.mod_eq_of_lt i.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
  

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 : ℕ
⊢ repeat (Nat.succ m) a = append a (repeat m a) ∘ cast (_ : Nat.succ m * n = n + m * n)

Next tactic:
generalize_proofs h
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
  

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 : ℕ
h : Nat.succ m * n = n + m * n
⊢ repeat (Nat.succ m) a = append a (repeat m a) ∘ cast h

Next tactic:
apply funext
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
  

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 (Nat.succ m * n)), repeat (Nat.succ m) a x = (append a (repeat m a) ∘ cast h) x

Next tactic:
rw [(Fin.rightInverse_cast h.symm).surjective.forall]