l3lab/ntp-mathlib huggingface dataset:
theorem snd_prod_mk {α α' β β' : TypeVec n} (f : α ⟹ β) (g : α' ⟹ β') :
    TypeVec.prod.snd ⊚ (f ⊗' g) = g ⊚ TypeVec.prod.snd := by
  funext i; induction i
  case fz => rfl
  case fs _ _ i_ih => 

Proof state:
n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α α' β β' : TypeVec.{u_1} n✝} (f : α ⟹ β) (g : α' ⟹ β'), (prod.snd ⊚ (f ⊗' g)) a✝ = (g ⊚ prod.snd) a✝
α α' β β' : TypeVec.{u_1} (succ n✝)
f : α ⟹ β
g : α' ⟹ β'
⊢ (prod.snd ⊚ (f ⊗' g)) (Fin2.fs a✝) = (g ⊚ prod.snd) (Fin2.fs a✝)

Next tactic:
apply i_ih
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} n
⊢ prod.fst ⊚ prod.diag = id

Next tactic:
funext i
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; 

Proof state:
case h
n : ℕ
α : TypeVec.{u_1} n
i : Fin2 n
⊢ (prod.fst ⊚ prod.diag) i = id i

Next tactic:
induction i
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  

Proof state:
case h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.fst ⊚ prod.diag) Fin2.fz = id Fin2.fz
case h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ : ∀ {α : TypeVec.{u_1} n✝}, (prod.fst ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.fst ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
case fz => rfl
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  

Proof state:
n n✝ : ℕ
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.fst ⊚ prod.diag) Fin2.fz = id Fin2.fz

Next tactic:
case fz => rfl
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => 

Proof state:
n n✝ : ℕ
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.fst ⊚ prod.diag) Fin2.fz = id Fin2.fz

Next tactic:
rfl
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => rfl
  

Proof state:
case h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ : ∀ {α : TypeVec.{u_1} n✝}, (prod.fst ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.fst ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
case fs _ _ i_ih => apply i_ih
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => rfl
  

Proof state:
n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u_1} n✝}, (prod.fst ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.fst ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
case fs _ _ i_ih => apply i_ih
theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => rfl
  case fs _ _ i_ih => 

Proof state:
n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u_1} n✝}, (prod.fst ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.fst ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
apply i_ih
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} n
⊢ prod.snd ⊚ prod.diag = id

Next tactic:
funext i
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; 

Proof state:
case h
n : ℕ
α : TypeVec.{u_1} n
i : Fin2 n
⊢ (prod.snd ⊚ prod.diag) i = id i

Next tactic:
induction i
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  

Proof state:
case h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.snd ⊚ prod.diag) Fin2.fz = id Fin2.fz
case h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ : ∀ {α : TypeVec.{u_1} n✝}, (prod.snd ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.snd ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
case fz => rfl
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  

Proof state:
n n✝ : ℕ
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.snd ⊚ prod.diag) Fin2.fz = id Fin2.fz

Next tactic:
case fz => rfl
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => 

Proof state:
n n✝ : ℕ
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.snd ⊚ prod.diag) Fin2.fz = id Fin2.fz

Next tactic:
rfl
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => rfl
  

Proof state:
case h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ : ∀ {α : TypeVec.{u_1} n✝}, (prod.snd ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.snd ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
case fs _ _ i_ih => apply i_ih
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => rfl
  

Proof state:
n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u_1} n✝}, (prod.snd ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.snd ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
case fs _ _ i_ih => apply i_ih
theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id := by
  funext i; induction i
  case fz => rfl
  case fs _ _ i_ih => 

Proof state:
n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u_1} n✝}, (prod.snd ⊚ prod.diag) a✝ = id a✝
α : TypeVec.{u_1} (succ n✝)
⊢ (prod.snd ⊚ prod.diag) (Fin2.fs a✝) = id (Fin2.fs a✝)

Next tactic:
apply i_ih
theorem repeatEq_iff_eq {α : TypeVec n} {i x y} :
    ofRepeat (repeatEq α i (prod.mk _ x y)) ↔ x = y := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} n
i : Fin2 n
x y : α i
⊢ ofRepeat (repeatEq α i (prod.mk i x y)) ↔ x = y

Next tactic:
induction' i with _ _ _ i_ih
theorem repeatEq_iff_eq {α : TypeVec n} {i x y} :
    ofRepeat (repeatEq α i (prod.mk _ x y)) ↔ x = y := by
  induction' i with _ _ _ i_ih
  

Proof state:
case fz
n n✝ : ℕ
α : TypeVec.{u_1} (succ n✝)
x y : α Fin2.fz
⊢ ofRepeat (repeatEq α Fin2.fz (prod.mk Fin2.fz x y)) ↔ x = y
case fs
n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u_1} n✝} {x y : α a✝}, ofRepeat (repeatEq α a✝ (prod.mk a✝ x y)) ↔ x = y
α : TypeVec.{u_1} (succ n✝)
x y : α (Fin2.fs a✝)
⊢ ofRepeat (repeatEq α (Fin2.fs a✝) (prod.mk (Fin2.fs a✝) x y)) ↔ x = y

Next tactic:
rfl
theorem repeatEq_iff_eq {α : TypeVec n} {i x y} :
    ofRepeat (repeatEq α i (prod.mk _ x y)) ↔ x = y := by
  induction' i with _ _ _ i_ih
  rfl
  

Proof state:
case fs
n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u_1} n✝} {x y : α a✝}, ofRepeat (repeatEq α a✝ (prod.mk a✝ x y)) ↔ x = y
α : TypeVec.{u_1} (succ n✝)
x y : α (Fin2.fs a✝)
⊢ ofRepeat (repeatEq α (Fin2.fs a✝) (prod.mk (Fin2.fs a✝) x y)) ↔ x = y

Next tactic:
erw [repeatEq, i_ih]
/-- similar to `toSubtype` adapted to relations (i.e. predicate on product) -/
def toSubtype' {n} {α : TypeVec.{u} n} (p : α ⊗ α ⟹ «repeat» n Prop) :
    (fun i : Fin2 n => { x : α i × α i // ofRepeat <| p i (prod.mk _ x.1 x.2) }) ⟹ Subtype_ p
  | Fin2.fs i, x => toSubtype' (dropFun p) i x
  | Fin2.fz, x => ⟨x.val, cast (by 

Proof state:
n✝¹ n : ℕ
α✝ : TypeVec.{u} n
p✝ : α✝ ⊗ α✝ ⟹ repeat n Prop
n✝ : ℕ
α : TypeVec.{u} (succ n✝)
p : α ⊗ α ⟹ repeat (succ n✝) Prop
x : (fun i => { x // ofRepeat (p i (prod.mk i x.fst x.snd)) }) Fin2.fz
⊢ ofRepeat (p Fin2.fz (prod.mk Fin2.fz (↑x).fst (↑x).snd)) = p Fin2.fz ↑x

Next tactic:
congr
/-- similar to `of_subtype` adapted to relations (i.e. predicate on product) -/
def ofSubtype' {n} {α : TypeVec.{u} n} (p : α ⊗ α ⟹ «repeat» n Prop) :
    Subtype_ p ⟹ fun i : Fin2 n => { x : α i × α i // ofRepeat <| p i (prod.mk _ x.1 x.2) }
  | Fin2.fs i, x => ofSubtype' _ i x
  | Fin2.fz, x => ⟨x.val, cast (by 

Proof state:
n✝¹ n : ℕ
α✝ : TypeVec.{u} n
p✝ : α✝ ⊗ α✝ ⟹ repeat n Prop
n✝ : ℕ
α : TypeVec.{u} (succ n✝)
p : α ⊗ α ⟹ repeat (succ n✝) Prop
x : Subtype_ p Fin2.fz
⊢ p Fin2.fz ↑x = ofRepeat (p Fin2.fz (prod.mk Fin2.fz (↑x).fst (↑x).snd))

Next tactic:
congr
theorem subtypeVal_nil {α : TypeVec.{u} 0} (ps : α ⟹ «repeat» 0 Prop) :
    TypeVec.subtypeVal ps = nilFun :=
  funext <| by 

Proof state:
n : ℕ
α : TypeVec.{u} 0
ps : α ⟹ repeat 0 Prop
⊢ ∀ (x : Fin2 0), subtypeVal ps x = nilFun x

Next tactic:
rintro ⟨⟩
theorem diag_sub_val {n} {α : TypeVec.{u} n} : subtypeVal (repeatEq α) ⊚ diagSub = prod.diag := by
  

Proof state:
n✝ n : ℕ
α : TypeVec.{u} n
⊢ subtypeVal (repeatEq α) ⊚ diagSub = prod.diag

Next tactic:
ext i x
theorem diag_sub_val {n} {α : TypeVec.{u} n} : subtypeVal (repeatEq α) ⊚ diagSub = prod.diag := by
  ext i x
  

Proof state:
case a.h
n✝ n : ℕ
α : TypeVec.{u} n
i : Fin2 n
x : α i
⊢ (subtypeVal (repeatEq α) ⊚ diagSub) i x = prod.diag i x

Next tactic:
induction' i with _ _ _ i_ih
theorem diag_sub_val {n} {α : TypeVec.{u} n} : subtypeVal (repeatEq α) ⊚ diagSub = prod.diag := by
  ext i x
  induction' i with _ _ _ i_ih
  

Proof state:
case a.h.fz
n✝¹ n n✝ : ℕ
α : TypeVec.{u} (succ n✝)
x : α Fin2.fz
⊢ (subtypeVal (repeatEq α) ⊚ diagSub) Fin2.fz x = prod.diag Fin2.fz x
case a.h.fs
n✝¹ n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u} n✝} (x : α a✝), (subtypeVal (repeatEq α) ⊚ diagSub) a✝ x = prod.diag a✝ x
α : TypeVec.{u} (succ n✝)
x : α (Fin2.fs a✝)
⊢ (subtypeVal (repeatEq α) ⊚ diagSub) (Fin2.fs a✝) x = prod.diag (Fin2.fs a✝) x

Next tactic:
simp only [comp, subtypeVal, repeatEq._eq_2, diagSub, prod.diag]
theorem diag_sub_val {n} {α : TypeVec.{u} n} : subtypeVal (repeatEq α) ⊚ diagSub = prod.diag := by
  ext i x
  induction' i with _ _ _ i_ih
  simp only [comp, subtypeVal, repeatEq._eq_2, diagSub, prod.diag]
  

Proof state:
case a.h.fs
n✝¹ n n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α : TypeVec.{u} n✝} (x : α a✝), (subtypeVal (repeatEq α) ⊚ diagSub) a✝ x = prod.diag a✝ x
α : TypeVec.{u} (succ n✝)
x : α (Fin2.fs a✝)
⊢ (subtypeVal (repeatEq α) ⊚ diagSub) (Fin2.fs a✝) x = prod.diag (Fin2.fs a✝) x

Next tactic:
apply @i_ih (drop α)
theorem prod_id : ∀ {n} {α β : TypeVec.{u} n}, (id ⊗' id) = (id : α ⊗ β ⟹ _) := by
  

Proof state:
n : ℕ
⊢ ∀ {n : ℕ} {α β : TypeVec.{u} n}, (id ⊗' id) = id

Next tactic:
intros
theorem prod_id : ∀ {n} {α β : TypeVec.{u} n}, (id ⊗' id) = (id : α ⊗ β ⟹ _) := by
  intros
  

Proof state:
n n✝ : ℕ
α✝ β✝ : TypeVec.{u} n✝
⊢ (id ⊗' id) = id

Next tactic:
ext i a
theorem prod_id : ∀ {n} {α β : TypeVec.{u} n}, (id ⊗' id) = (id : α ⊗ β ⟹ _) := by
  intros
  ext i a
  

Proof state:
case a.h
n n✝ : ℕ
α✝ β✝ : TypeVec.{u} n✝
i : Fin2 n✝
a : (α✝ ⊗ β✝) i
⊢ (id ⊗' id) i a = id i a

Next tactic:
induction' i with _ _ _ i_ih
theorem prod_id : ∀ {n} {α β : TypeVec.{u} n}, (id ⊗' id) = (id : α ⊗ β ⟹ _) := by
  intros
  ext i a
  induction' i with _ _ _ i_ih
  · 

Proof state:
case a.h.fz
n n✝¹ n✝ : ℕ
α✝ β✝ : TypeVec.{u} (succ n✝)
a : (α✝ ⊗ β✝) Fin2.fz
⊢ (id ⊗' id) Fin2.fz a = id Fin2.fz a

Next tactic:
cases a
theorem prod_id : ∀ {n} {α β : TypeVec.{u} n}, (id ⊗' id) = (id : α ⊗ β ⟹ _) := by
  intros
  ext i a
  induction' i with _ _ _ i_ih
  · cases a
    

Proof state:
case a.h.fz.mk
n n✝¹ n✝ : ℕ
α✝ β✝ : TypeVec.{u} (succ n✝)
fst✝ : last α✝
snd✝ : last β✝
⊢ (id ⊗' id) Fin2.fz (fst✝, snd✝) = id Fin2.fz (fst✝, snd✝)

Next tactic:
rfl
theorem prod_id : ∀ {n} {α β : TypeVec.{u} n}, (id ⊗' id) = (id : α ⊗ β ⟹ _) := by
  intros
  ext i a
  induction' i with _ _ _ i_ih
  · cases a
    rfl
  · 

Proof state:
case a.h.fs
n n✝¹ n✝ : ℕ
a✝ : Fin2 n✝
i_ih : ∀ {α β : TypeVec.{u} n✝} (a : (α ⊗ β) a✝), (id ⊗' id) a✝ a = id a✝ a
α✝ β✝ : TypeVec.{u} (succ n✝)
a : (α✝ ⊗ β✝) (Fin2.fs a✝)
⊢ (id ⊗' id) (Fin2.fs a✝) a = id (Fin2.fs a✝) a

Next tactic:
apply i_ih
theorem append_prod_appendFun {n} {α α' β β' : TypeVec.{u} n} {φ φ' ψ ψ' : Type u}
    {f₀ : α ⟹ α'} {g₀ : β ⟹ β'} {f₁ : φ → φ'} {g₁ : ψ → ψ'} :
    ((f₀ ⊗' g₀) ::: (_root_.Prod.map f₁ g₁)) = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) := by
  

Proof state:
n✝ n : ℕ
α α' β β' : TypeVec.{u} n
φ φ' ψ ψ' : Type u
f₀ : α ⟹ α'
g₀ : β ⟹ β'
f₁ : φ → φ'
g₁ : ψ → ψ'
⊢ (f₀ ⊗' g₀ ::: Prod.map f₁ g₁) = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁))

Next tactic:
ext i a
theorem append_prod_appendFun {n} {α α' β β' : TypeVec.{u} n} {φ φ' ψ ψ' : Type u}
    {f₀ : α ⟹ α'} {g₀ : β ⟹ β'} {f₁ : φ → φ'} {g₁ : ψ → ψ'} :
    ((f₀ ⊗' g₀) ::: (_root_.Prod.map f₁ g₁)) = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) := by
  ext i a
  

Proof state:
case a.h
n✝ n : ℕ
α α' β β' : TypeVec.{u} n
φ φ' ψ ψ' : Type u
f₀ : α ⟹ α'
g₀ : β ⟹ β'
f₁ : φ → φ'
g₁ : ψ → ψ'
i : Fin2 (n + 1)
a : ((α ⊗ β) ::: (φ × ψ)) i
⊢ (f₀ ⊗' g₀ ::: Prod.map f₁ g₁) i a = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) i a

Next tactic:
cases i
theorem append_prod_appendFun {n} {α α' β β' : TypeVec.{u} n} {φ φ' ψ ψ' : Type u}
    {f₀ : α ⟹ α'} {g₀ : β ⟹ β'} {f₁ : φ → φ'} {g₁ : ψ → ψ'} :
    ((f₀ ⊗' g₀) ::: (_root_.Prod.map f₁ g₁)) = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) := by
  ext i a
  cases i
  · 

Proof state:
case a.h.fz
n✝ n : ℕ
α α' β β' : TypeVec.{u} n
φ φ' ψ ψ' : Type u
f₀ : α ⟹ α'
g₀ : β ⟹ β'
f₁ : φ → φ'
g₁ : ψ → ψ'
a : ((α ⊗ β) ::: (φ × ψ)) Fin2.fz
⊢ (f₀ ⊗' g₀ ::: Prod.map f₁ g₁) Fin2.fz a = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) Fin2.fz a

Next tactic:
cases a
theorem append_prod_appendFun {n} {α α' β β' : TypeVec.{u} n} {φ φ' ψ ψ' : Type u}
    {f₀ : α ⟹ α'} {g₀ : β ⟹ β'} {f₁ : φ → φ'} {g₁ : ψ → ψ'} :
    ((f₀ ⊗' g₀) ::: (_root_.Prod.map f₁ g₁)) = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) := by
  ext i a
  cases i
  · cases a
    

Proof state:
case a.h.fz.mk
n✝ n : ℕ
α α' β β' : TypeVec.{u} n
φ φ' ψ ψ' : Type u
f₀ : α ⟹ α'
g₀ : β ⟹ β'
f₁ : φ → φ'
g₁ : ψ → ψ'
fst✝ : φ
snd✝ : ψ
⊢ (f₀ ⊗' g₀ ::: Prod.map f₁ g₁) Fin2.fz (fst✝, snd✝) = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) Fin2.fz (fst✝, snd✝)

Next tactic:
rfl
theorem append_prod_appendFun {n} {α α' β β' : TypeVec.{u} n} {φ φ' ψ ψ' : Type u}
    {f₀ : α ⟹ α'} {g₀ : β ⟹ β'} {f₁ : φ → φ'} {g₁ : ψ → ψ'} :
    ((f₀ ⊗' g₀) ::: (_root_.Prod.map f₁ g₁)) = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) := by
  ext i a
  cases i
  · cases a
    rfl
  · 

Proof state:
case a.h.fs
n✝ n : ℕ
α α' β β' : TypeVec.{u} n
φ φ' ψ ψ' : Type u
f₀ : α ⟹ α'
g₀ : β ⟹ β'
f₁ : φ → φ'
g₁ : ψ → ψ'
a✝ : Fin2 (Nat.add n 0)
a : ((α ⊗ β) ::: (φ × ψ)) (Fin2.fs a✝)
⊢ (f₀ ⊗' g₀ ::: Prod.map f₁ g₁) (Fin2.fs a✝) a = ((f₀ ::: f₁) ⊗' (g₀ ::: g₁)) (Fin2.fs a✝) a

Next tactic:
rfl
@[simp]
theorem dropFun_diag {α} : dropFun (@prod.diag (n + 1) α) = prod.diag := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} (n + 1)
⊢ dropFun prod.diag = prod.diag

Next tactic:
ext i : 2
@[simp]
theorem dropFun_diag {α} : dropFun (@prod.diag (n + 1) α) = prod.diag := by
  ext i : 2
  

Proof state:
case a.h
n : ℕ
α : TypeVec.{u_1} (n + 1)
i : Fin2 n
x✝ : drop α i
⊢ dropFun prod.diag i x✝ = prod.diag i x✝

Next tactic:
induction i
@[simp]
theorem dropFun_diag {α} : dropFun (@prod.diag (n + 1) α) = prod.diag := by
  ext i : 2
  induction i <;> 

Proof state:
case a.h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
x✝ : drop α Fin2.fz
⊢ dropFun prod.diag Fin2.fz x✝ = prod.diag Fin2.fz x✝

Next tactic:
simp [dropFun, *]
@[simp]
theorem dropFun_diag {α} : dropFun (@prod.diag (n + 1) α) = prod.diag := by
  ext i : 2
  induction i <;> 

Proof state:
case a.h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ : ∀ {α : TypeVec.{u_1} (n✝ + 1)} (x : drop α a✝), dropFun prod.diag a✝ x = prod.diag a✝ x
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
x✝ : drop α (Fin2.fs a✝)
⊢ dropFun prod.diag (Fin2.fs a✝) x✝ = prod.diag (Fin2.fs a✝) x✝

Next tactic:
simp [dropFun, *]
@[simp]
theorem dropFun_diag {α} : dropFun (@prod.diag (n + 1) α) = prod.diag := by
  ext i : 2
  induction i <;> simp [dropFun, *] <;> 

Proof state:
case a.h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
x✝ : drop α Fin2.fz
⊢ prod.diag (Fin2.fs Fin2.fz) x✝ = prod.diag Fin2.fz x✝

Next tactic:
rfl
@[simp]
theorem dropFun_diag {α} : dropFun (@prod.diag (n + 1) α) = prod.diag := by
  ext i : 2
  induction i <;> simp [dropFun, *] <;> 

Proof state:
case a.h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ : ∀ {α : TypeVec.{u_1} (n✝ + 1)} (x : drop α a✝), dropFun prod.diag a✝ x = prod.diag a✝ x
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
x✝ : drop α (Fin2.fs a✝)
⊢ prod.diag (Fin2.fs (Fin2.fs a✝)) x✝ = prod.diag (Fin2.fs a✝) x✝

Next tactic:
rfl
@[simp]
theorem dropFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (toSubtype p) = toSubtype _ := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
⊢ dropFun (toSubtype p) = toSubtype fun i x => p (Fin2.fs i) x

Next tactic:
ext i
@[simp]
theorem dropFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (toSubtype p) = toSubtype _ := by
  ext i
  

Proof state:
case a.h
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
i : Fin2 n
x✝ : drop (fun i => { x // ofRepeat (p i x) }) i
⊢ dropFun (toSubtype p) i x✝ = toSubtype (fun i x => p (Fin2.fs i) x) i x✝

Next tactic:
induction i
@[simp]
theorem dropFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (toSubtype p) = toSubtype _ := by
  ext i
  induction i <;> 

Proof state:
case a.h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (fun i => { x // ofRepeat (p i x) }) Fin2.fz
⊢ dropFun (toSubtype p) Fin2.fz x✝ = toSubtype (fun i x => p (Fin2.fs i) x) Fin2.fz x✝

Next tactic:
simp [dropFun, *]
@[simp]
theorem dropFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (toSubtype p) = toSubtype _ := by
  ext i
  induction i <;> 

Proof state:
case a.h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ :
  ∀ {α : TypeVec.{u_1} (n✝ + 1)} (p : α ⟹ repeat (n✝ + 1) Prop) (x : drop (fun i => { x // ofRepeat (p i x) }) a✝),
    dropFun (toSubtype p) a✝ x = toSubtype (fun i x => p (Fin2.fs i) x) a✝ x
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (fun i => { x // ofRepeat (p i x) }) (Fin2.fs a✝)
⊢ dropFun (toSubtype p) (Fin2.fs a✝) x✝ = toSubtype (fun i x => p (Fin2.fs i) x) (Fin2.fs a✝) x✝

Next tactic:
simp [dropFun, *]
@[simp]
theorem dropFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (toSubtype p) = toSubtype _ := by
  ext i
  induction i <;> simp [dropFun, *] <;> 

Proof state:
case a.h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (fun i => { x // ofRepeat (p i x) }) Fin2.fz
⊢ toSubtype p (Fin2.fs Fin2.fz) x✝ = toSubtype (fun i x => p (Fin2.fs i) x) Fin2.fz x✝

Next tactic:
rfl
@[simp]
theorem dropFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (toSubtype p) = toSubtype _ := by
  ext i
  induction i <;> simp [dropFun, *] <;> 

Proof state:
case a.h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ :
  ∀ {α : TypeVec.{u_1} (n✝ + 1)} (p : α ⟹ repeat (n✝ + 1) Prop) (x : drop (fun i => { x // ofRepeat (p i x) }) a✝),
    dropFun (toSubtype p) a✝ x = toSubtype (fun i x => p (Fin2.fs i) x) a✝ x
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (fun i => { x // ofRepeat (p i x) }) (Fin2.fs a✝)
⊢ toSubtype p (Fin2.fs (Fin2.fs a✝)) x✝ = toSubtype (fun i x => p (Fin2.fs i) x) (Fin2.fs a✝) x✝

Next tactic:
rfl
@[simp]
theorem lastFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (toSubtype p) = _root_.id := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
⊢ lastFun (toSubtype p) = _root_.id

Next tactic:
ext i : 2
@[simp]
theorem lastFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (toSubtype p) = _root_.id := by
  ext i : 2
  

Proof state:
case h
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
i : last fun i => { x // ofRepeat (p i x) }
⊢ lastFun (toSubtype p) i = _root_.id i

Next tactic:
induction i
@[simp]
theorem lastFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (toSubtype p) = _root_.id := by
  ext i : 2
  induction i; 

Proof state:
case h.mk
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
val✝ : α Fin2.fz
property✝ : ofRepeat (p Fin2.fz val✝)
⊢ lastFun (toSubtype p) { val := val✝, property := property✝ } = _root_.id { val := val✝, property := property✝ }

Next tactic:
simp [dropFun, *]
@[simp]
theorem lastFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (toSubtype p) = _root_.id := by
  ext i : 2
  induction i; simp [dropFun, *]; 

Proof state:
case h.mk
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
val✝ : α Fin2.fz
property✝ : ofRepeat (p Fin2.fz val✝)
⊢ lastFun (toSubtype p) { val := val✝, property := property✝ } = { val := val✝, property := property✝ }

Next tactic:
rfl
@[simp]
theorem dropFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (ofSubtype p) = ofSubtype _ := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
⊢ dropFun (ofSubtype p) = ofSubtype (dropFun p)

Next tactic:
ext i : 2
@[simp]
theorem dropFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (ofSubtype p) = ofSubtype _ := by
  ext i : 2
  

Proof state:
case a.h
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
i : Fin2 n
x✝ : drop (Subtype_ p) i
⊢ dropFun (ofSubtype p) i x✝ = ofSubtype (dropFun p) i x✝

Next tactic:
induction i
@[simp]
theorem dropFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (ofSubtype p) = ofSubtype _ := by
  ext i : 2
  induction i <;> 

Proof state:
case a.h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (Subtype_ p) Fin2.fz
⊢ dropFun (ofSubtype p) Fin2.fz x✝ = ofSubtype (dropFun p) Fin2.fz x✝

Next tactic:
simp [dropFun, *]
@[simp]
theorem dropFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (ofSubtype p) = ofSubtype _ := by
  ext i : 2
  induction i <;> 

Proof state:
case a.h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ :
  ∀ {α : TypeVec.{u_1} (n✝ + 1)} (p : α ⟹ repeat (n✝ + 1) Prop) (x : drop (Subtype_ p) a✝),
    dropFun (ofSubtype p) a✝ x = ofSubtype (dropFun p) a✝ x
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (Subtype_ p) (Fin2.fs a✝)
⊢ dropFun (ofSubtype p) (Fin2.fs a✝) x✝ = ofSubtype (dropFun p) (Fin2.fs a✝) x✝

Next tactic:
simp [dropFun, *]
@[simp]
theorem dropFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (ofSubtype p) = ofSubtype _ := by
  ext i : 2
  induction i <;> simp [dropFun, *] <;> 

Proof state:
case a.h.fz
n n✝ : ℕ
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (Subtype_ p) Fin2.fz
⊢ ofSubtype p (Fin2.fs Fin2.fz) x✝ = ofSubtype (dropFun p) Fin2.fz x✝

Next tactic:
rfl
@[simp]
theorem dropFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (ofSubtype p) = ofSubtype _ := by
  ext i : 2
  induction i <;> simp [dropFun, *] <;> 

Proof state:
case a.h.fs
n n✝ : ℕ
a✝ : Fin2 n✝
a_ih✝ :
  ∀ {α : TypeVec.{u_1} (n✝ + 1)} (p : α ⟹ repeat (n✝ + 1) Prop) (x : drop (Subtype_ p) a✝),
    dropFun (ofSubtype p) a✝ x = ofSubtype (dropFun p) a✝ x
α : TypeVec.{u_1} (Nat.succ n✝ + 1)
p : α ⟹ repeat (Nat.succ n✝ + 1) Prop
x✝ : drop (Subtype_ p) (Fin2.fs a✝)
⊢ ofSubtype p (Fin2.fs (Fin2.fs a✝)) x✝ = ofSubtype (dropFun p) (Fin2.fs a✝) x✝

Next tactic:
rfl
@[simp]
theorem lastFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (ofSubtype p) = _root_.id := by
  

Proof state:
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
⊢ lastFun (ofSubtype p) = _root_.id

Next tactic:
ext i : 2
@[simp]
theorem lastFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (ofSubtype p) = _root_.id := by
  ext i : 2
  

Proof state:
case h
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
i : last (Subtype_ p)
⊢ lastFun (ofSubtype p) i = _root_.id i

Next tactic:
induction i
@[simp]
theorem lastFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (ofSubtype p) = _root_.id := by
  ext i : 2
  induction i; 

Proof state:
case h.mk
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
val✝ : α Fin2.fz
property✝ : p Fin2.fz val✝
⊢ lastFun (ofSubtype p) { val := val✝, property := property✝ } = _root_.id { val := val✝, property := property✝ }

Next tactic:
simp [dropFun, *]
@[simp]
theorem lastFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (ofSubtype p) = _root_.id := by
  ext i : 2
  induction i; simp [dropFun, *]; 

Proof state:
case h.mk
n : ℕ
α : TypeVec.{u_1} (n + 1)
p : α ⟹ repeat (n + 1) Prop
val✝ : α Fin2.fz
property✝ : p Fin2.fz val✝
⊢ lastFun (ofSubtype p) { val := val✝, property := property✝ } = { val := val✝, property := property✝ }

Next tactic:
rfl
@[simp]
theorem dropFun_prod {α α' β β' : TypeVec (n + 1)} (f : α ⟹ β) (f' : α' ⟹ β') :
    dropFun (f ⊗' f') = (dropFun f ⊗' dropFun f') := by
  

Proof state:
n : ℕ
α α' β β' : TypeVec.{u_1} (n + 1)
f : α ⟹ β
f' : α' ⟹ β'
⊢ dropFun (f ⊗' f') = (dropFun f ⊗' dropFun f')

Next tactic:
ext i : 2