File: Mathlib/Data/TypeVec.lean

full_name: TypeVec
code: /-- n-tuples of types, as a category -/
@[pp_with_univ]
def TypeVec (n : ℕ) 
goal: Type (u_1 + 1)

full_name: instInhabitedTypeVec
code: instance {n} : Inhabited (TypeVec.{u} n) 
goal: Inhabited (TypeVec.{u} n)

full_name: TypeVec.Arrow
code: /-- arrow in the category of `TypeVec` -/
def Arrow (α β : TypeVec n) 
goal: Type (max u_1 u_2)

full_name: MvFunctor.«_aux_Mathlib_Data_TypeVec___macroRules_MvFunctor_term_⟹__1»
code: @[inherit_doc] scoped[MvFunctor] infixl:40 " ⟹ " => TypeVec.Arrow
goal: Lean.Macro

full_name: MvFunctor._aux_Mathlib_Data_TypeVec___unexpand_TypeVec_Arrow_1
code: @[inherit_doc] scoped[MvFunctor] infixl:40 " ⟹ " => TypeVec.Arrow
goal: Lean.PrettyPrinter.Unexpander

full_name: TypeVec.Arrow.ext
code: /-- Extensionality for arrows -/
@[ext]
theorem Arrow.ext {α β : TypeVec n} (f g : α ⟹ β) :
    (∀ i, f i = g i) → f = g 
goal: (∀ (i : Fin2 n), f i = g i) → f = g

full_name: TypeVec.Arrow.inhabited
code: instance Arrow.inhabited (α β : TypeVec n) [∀ i, Inhabited (β i)] : Inhabited (α ⟹ β) 
goal: Inhabited (α.Arrow β)

full_name: TypeVec.id
code: /-- identity of arrow composition -/
def id {α : TypeVec n} : α ⟹ α 
goal: α.Arrow α

full_name: TypeVec.comp
code: /-- arrow composition in the category of `TypeVec` -/
def comp {α β γ : TypeVec n} (g : β ⟹ γ) (f : α ⟹ β) : α ⟹ γ 
goal: α.Arrow γ

full_name: MvFunctor._aux_Mathlib_Data_TypeVec___unexpand_TypeVec_comp_1
code: @[inherit_doc] scoped[MvFunctor] infixr:80 " ⊚ " => TypeVec.comp
goal: Lean.PrettyPrinter.Unexpander

full_name: MvFunctor.«_aux_Mathlib_Data_TypeVec___macroRules_MvFunctor_term_⊚__1»
code: @[inherit_doc] scoped[MvFunctor] infixr:80 " ⊚ " => TypeVec.comp
goal: Lean.Macro

full_name: TypeVec.id_comp
code: @[simp]
theorem id_comp {α β : TypeVec n} (f : α ⟹ β) : id ⊚ f = f 
goal: TypeVec.comp TypeVec.id f = f

full_name: TypeVec.comp_id
code: @[simp]
theorem comp_id {α β : TypeVec n} (f : α ⟹ β) : f ⊚ id = f 
goal: TypeVec.comp f TypeVec.id = f

full_name: TypeVec.comp_assoc
code: theorem comp_assoc {α β γ δ : TypeVec n} (h : γ ⟹ δ) (g : β ⟹ γ) (f : α ⟹ β) :
    (h ⊚ g) ⊚ f = h ⊚ g ⊚ f 
goal: TypeVec.comp (TypeVec.comp h g) f = TypeVec.comp h (TypeVec.comp g f)

full_name: TypeVec.append1
code: /-- Support for extending a `TypeVec` by one element. -/
def append1 (α : TypeVec n) (β : Type*) : TypeVec (n + 1)
  
goal: TypeVec.{u_1} (n + 1)

full_name: TypeVec.«_aux_Mathlib_Data_TypeVec___macroRules_TypeVec_term_:::__1»
code: @[inherit_doc] infixl:67 " ::: " => append1
goal: Lean.Macro

full_name: TypeVec._aux_Mathlib_Data_TypeVec___unexpand_TypeVec_append1_1
code: @[inherit_doc] infixl:67 " ::: " => append1
goal: Lean.PrettyPrinter.Unexpander

full_name: TypeVec.drop
code: /-- retain only a `n-length` prefix of the argument -/
def drop (α : TypeVec.{u} (n + 1)) : TypeVec n 
goal: TypeVec.{u} n

full_name: TypeVec.last
code: /-- take the last value of a `(n+1)-length` vector -/
def last (α : TypeVec.{u} (n + 1)) : Type _ 
goal: Type u

full_name: TypeVec.last.inhabited
code: instance last.inhabited (α : TypeVec (n + 1)) [Inhabited (α Fin2.fz)] : Inhabited (last α) 
goal: Inhabited α.last

full_name: TypeVec.drop_append1
code: theorem drop_append1 {α : TypeVec n} {β : Type*} {i : Fin2 n} : drop (append1 α β) i = α i 
goal: (α ::: β).drop i = α i

full_name: TypeVec.drop_append1'
code: theorem drop_append1' {α : TypeVec n} {β : Type*} : drop (append1 α β) = α 
goal: (α ::: β).drop = α

full_name: TypeVec.last_append1
code: theorem last_append1 {α : TypeVec n} {β : Type*} : last (append1 α β) = β 
goal: (α ::: β).last = β

full_name: TypeVec.append1_drop_last
code: @[simp]
theorem append1_drop_last (α : TypeVec (n + 1)) : append1 (drop α) (last α) = α 
goal: α.drop ::: α.last = α

full_name: TypeVec.append1Cases
code: /-- cases on `(n+1)-length` vectors -/
@[elab_as_elim]
def append1Cases {C : TypeVec (n + 1) → Sort u} (H : ∀ α β, C (append1 α β)) (γ) : C γ 
goal: C γ

full_name: TypeVec.append1_cases_append1
code: @[simp]
theorem append1_cases_append1 {C : TypeVec (n + 1) → Sort u} (H : ∀ α β, C (append1 α β)) (α β) :
    @append1Cases _ C H (append1 α β) = H α β 
goal: TypeVec.append1Cases H (α ::: β) = H α β

full_name: TypeVec.splitFun
code: /-- append an arrow and a function for arbitrary source and target type vectors -/
def splitFun {α α' : TypeVec (n + 1)} (f : drop α ⟹ drop α') (g : last α → last α') : α ⟹ α'
  
goal: α.Arrow α'

full_name: TypeVec.appendFun
code: /-- append an arrow and a function as well as their respective source and target types / typevecs -/
def appendFun {α α' : TypeVec n} {β β' : Type*} (f : α ⟹ α') (g : β → β') :
    append1 α β ⟹ append1 α' β' 
goal: (α ::: β).Arrow (α' ::: β')

full_name: TypeVec.«_aux_Mathlib_Data_TypeVec___macroRules_TypeVec_term_:::__1_1»
code: @[inherit_doc] infixl:0 " ::: " => appendFun
goal: Lean.Macro

full_name: TypeVec._aux_Mathlib_Data_TypeVec___unexpand_TypeVec_appendFun_1
code: @[inherit_doc] infixl:0 " ::: " => appendFun
goal: Lean.PrettyPrinter.Unexpander

full_name: TypeVec.dropFun
code: /-- split off the prefix of an arrow -/
def dropFun {α β : TypeVec (n + 1)} (f : α ⟹ β) : drop α ⟹ drop β 
goal: α.drop.Arrow β.drop

full_name: TypeVec.lastFun
code: /-- split off the last function of an arrow -/
def lastFun {α β : TypeVec (n + 1)} (f : α ⟹ β) : last α → last β 
goal: α.last → β.last

full_name: TypeVec.nilFun
code: /-- arrow in the category of `0-length` vectors -/
def nilFun {α : TypeVec 0} {β : TypeVec 0} : α ⟹ β 
goal: α.Arrow β

full_name: TypeVec.eq_of_drop_last_eq
code: theorem eq_of_drop_last_eq {α β : TypeVec (n + 1)} {f g : α ⟹ β} (h₀ : dropFun f = dropFun g)
    (h₁ : lastFun f = lastFun g) : f = g 
goal: f = g

full_name: TypeVec.dropFun_splitFun
code: @[simp]
theorem dropFun_splitFun {α α' : TypeVec (n + 1)} (f : drop α ⟹ drop α') (g : last α → last α') :
    dropFun (splitFun f g) = f 
goal: TypeVec.dropFun (TypeVec.splitFun f g) = f

full_name: TypeVec.Arrow.mp
code: /-- turn an equality into an arrow -/
def Arrow.mp {α β : TypeVec n} (h : α = β) : α ⟹ β
  
goal: α.Arrow β

full_name: TypeVec.Arrow.mpr
code: /-- turn an equality into an arrow, with reverse direction -/
def Arrow.mpr {α β : TypeVec n} (h : α = β) : β ⟹ α
  
goal: β.Arrow α

full_name: TypeVec.toAppend1DropLast
code: /-- decompose a vector into its prefix appended with its last element -/
def toAppend1DropLast {α : TypeVec (n + 1)} : α ⟹ (drop α ::: last α) 
goal: α.Arrow (α.drop ::: α.last)

full_name: TypeVec.fromAppend1DropLast
code: /-- stitch two bits of a vector back together -/
def fromAppend1DropLast {α : TypeVec (n + 1)} : (drop α ::: last α) ⟹ α 
goal: (α.drop ::: α.last).Arrow α

full_name: TypeVec.lastFun_splitFun
code: @[simp]
theorem lastFun_splitFun {α α' : TypeVec (n + 1)} (f : drop α ⟹ drop α') (g : last α → last α') :
    lastFun (splitFun f g) = g 
goal: TypeVec.lastFun (TypeVec.splitFun f g) = g

full_name: TypeVec.dropFun_appendFun
code: @[simp]
theorem dropFun_appendFun {α α' : TypeVec n} {β β' : Type*} (f : α ⟹ α') (g : β → β') :
    dropFun (f ::: g) = f 
goal: TypeVec.dropFun (f ::: g) = f

full_name: TypeVec.lastFun_appendFun
code: @[simp]
theorem lastFun_appendFun {α α' : TypeVec n} {β β' : Type*} (f : α ⟹ α') (g : β → β') :
    lastFun (f ::: g) = g 
goal: TypeVec.lastFun (f ::: g) = g

full_name: TypeVec.split_dropFun_lastFun
code: theorem split_dropFun_lastFun {α α' : TypeVec (n + 1)} (f : α ⟹ α') :
    splitFun (dropFun f) (lastFun f) = f 
goal: TypeVec.splitFun (TypeVec.dropFun f) (TypeVec.lastFun f) = f

full_name: TypeVec.splitFun_inj
code: theorem splitFun_inj {α α' : TypeVec (n + 1)} {f f' : drop α ⟹ drop α'} {g g' : last α → last α'}
    (H : splitFun f g = splitFun f' g') : f = f' ∧ g = g' 
goal: f = f' ∧ g = g'

full_name: TypeVec.appendFun_inj
code: theorem appendFun_inj {α α' : TypeVec n} {β β' : Type*} {f f' : α ⟹ α'} {g g' : β → β'} :
    (f ::: g : (α ::: β) ⟹ _) = (f' ::: g' : (α ::: β) ⟹ _)
    → f = f' ∧ g = g' 
goal: (f ::: g) = (f' ::: g') → f = f' ∧ g = g'

full_name: TypeVec.splitFun_comp
code: theorem splitFun_comp {α₀ α₁ α₂ : TypeVec (n + 1)} (f₀ : drop α₀ ⟹ drop α₁)
    (f₁ : drop α₁ ⟹ drop α₂) (g₀ : last α₀ → last α₁) (g₁ : last α₁ → last α₂) :
    splitFun (f₁ ⊚ f₀) (g₁ ∘ g₀) = splitFun f₁ g₁ ⊚ splitFun f₀ g₀ 
goal: TypeVec.splitFun (TypeVec.comp f₁ f₀) (g₁ ∘ g₀) = TypeVec.comp (TypeVec.splitFun f₁ g₁) (TypeVec.splitFun f₀ g₀)

full_name: TypeVec.appendFun_comp_splitFun
code: theorem appendFun_comp_splitFun {α γ : TypeVec n} {β δ : Type*} {ε : TypeVec (n + 1)}
    (f₀ : drop ε ⟹ α) (f₁ : α ⟹ γ) (g₀ : last ε → β) (g₁ : β → δ) :
    appendFun f₁ g₁ ⊚ splitFun f₀ g₀ = splitFun (α' := γ.append1 δ) (f₁ ⊚ f₀) (g₁ ∘ g₀) 
goal: TypeVec.comp (f₁ ::: g₁) (TypeVec.splitFun f₀ g₀) = TypeVec.splitFun (TypeVec.comp f₁ f₀) (g₁ ∘ g₀)

full_name: TypeVec.appendFun_comp
code: theorem appendFun_comp  {α₀ α₁ α₂ : TypeVec n}
    {β₀ β₁ β₂ : Type*}
    (f₀ : α₀ ⟹ α₁) (f₁ : α₁ ⟹ α₂)
    (g₀ : β₀ → β₁) (g₁ : β₁ → β₂) :
    (f₁ ⊚ f₀ ::: g₁ ∘ g₀) = (f₁ ::: g₁) ⊚ (f₀ ::: g₀) 
goal: (TypeVec.comp f₁ f₀ ::: g₁ ∘ g₀) = TypeVec.comp (f₁ ::: g₁) (f₀ ::: g₀)

full_name: TypeVec.appendFun_comp'
code: theorem appendFun_comp' {α₀ α₁ α₂ : TypeVec n} {β₀ β₁ β₂ : Type*}
    (f₀ : α₀ ⟹ α₁) (f₁ : α₁ ⟹ α₂) (g₀ : β₀ → β₁) (g₁ : β₁ → β₂) :
    (f₁ ::: g₁) ⊚ (f₀ ::: g₀) = (f₁ ⊚ f₀ ::: g₁ ∘ g₀) 
goal: TypeVec.comp (f₁ ::: g₁) (f₀ ::: g₀) = (TypeVec.comp f₁ f₀ ::: g₁ ∘ g₀)

full_name: TypeVec.nilFun_comp
code: theorem nilFun_comp {α₀ : TypeVec 0} (f₀ : α₀ ⟹ Fin2.elim0) : nilFun ⊚ f₀ = f₀ 
goal: TypeVec.comp TypeVec.nilFun f₀ = f₀

full_name: TypeVec.appendFun_comp_id
code: theorem appendFun_comp_id {α : TypeVec n} {β₀ β₁ β₂ : Type u} (g₀ : β₀ → β₁) (g₁ : β₁ → β₂) :
    (@id _ α ::: g₁ ∘ g₀) = (id ::: g₁) ⊚ (id ::: g₀) 
goal: (TypeVec.id ::: g₁ ∘ g₀) = TypeVec.comp (TypeVec.id ::: g₁) (TypeVec.id ::: g₀)

full_name: TypeVec.dropFun_comp
code: @[simp]
theorem dropFun_comp {α₀ α₁ α₂ : TypeVec (n + 1)} (f₀ : α₀ ⟹ α₁) (f₁ : α₁ ⟹ α₂) :
    dropFun (f₁ ⊚ f₀) = dropFun f₁ ⊚ dropFun f₀ 
goal: TypeVec.dropFun (TypeVec.comp f₁ f₀) = TypeVec.comp (TypeVec.dropFun f₁) (TypeVec.dropFun f₀)

full_name: TypeVec.lastFun_comp
code: @[simp]
theorem lastFun_comp {α₀ α₁ α₂ : TypeVec (n + 1)} (f₀ : α₀ ⟹ α₁) (f₁ : α₁ ⟹ α₂) :
    lastFun (f₁ ⊚ f₀) = lastFun f₁ ∘ lastFun f₀ 
goal: TypeVec.lastFun (TypeVec.comp f₁ f₀) = TypeVec.lastFun f₁ ∘ TypeVec.lastFun f₀

full_name: TypeVec.appendFun_aux
code: theorem appendFun_aux {α α' : TypeVec n} {β β' : Type*} (f : (α ::: β) ⟹ (α' ::: β')) :
    (dropFun f ::: lastFun f) = f 
goal: (TypeVec.dropFun f ::: TypeVec.lastFun f) = f

full_name: TypeVec.appendFun_id_id
code: theorem appendFun_id_id {α : TypeVec n} {β : Type*} :
    (@TypeVec.id n α ::: @_root_.id β) = TypeVec.id 
goal: (TypeVec.id ::: id) = TypeVec.id

full_name: TypeVec.subsingleton0
code: instance subsingleton0 : Subsingleton (TypeVec 0) 
goal: Subsingleton (TypeVec.{u_1} 0)

full_name: TypeVec.casesNil
code: /-- cases distinction for 0-length type vector -/
protected def casesNil {β : TypeVec 0 → Sort*} (f : β Fin2.elim0) : ∀ v, β v 
goal: β v

full_name: TypeVec.casesCons
code: /-- cases distinction for (n+1)-length type vector -/
protected def casesCons (n : ℕ) {β : TypeVec (n + 1) → Sort*}
    (f : ∀ (t) (v : TypeVec n), β (v ::: t)) :
    ∀ v, β v 
goal: β v

full_name: TypeVec.casesNil_append1
code: protected theorem casesNil_append1 {β : TypeVec 0 → Sort*} (f : β Fin2.elim0) :
    TypeVec.casesNil f Fin2.elim0 = f 
goal: TypeVec.casesNil f Fin2.elim0 = f

full_name: TypeVec.casesCons_append1
code: protected theorem casesCons_append1 (n : ℕ) {β : TypeVec (n + 1) → Sort*}
    (f : ∀ (t) (v : TypeVec n), β (v ::: t)) (v : TypeVec n) (α) :
    TypeVec.casesCons n f (v ::: α) = f α v 
goal: TypeVec.casesCons n f (v ::: α) = f α v

full_name: TypeVec.typevecCasesNil₃
code: /-- cases distinction for an arrow in the category of 0-length type vectors -/
def typevecCasesNil₃ {β : ∀ v v' : TypeVec 0, v ⟹ v' → Sort*}
    (f : β Fin2.elim0 Fin2.elim0 nilFun) :
    ∀ v v' fs, β v v' fs 
goal: β v v' fs

full_name: TypeVec.typevecCasesCons₃
code: /-- cases distinction for an arrow in the category of (n+1)-length type vectors -/
def typevecCasesCons₃ (n : ℕ) {β : ∀ v v' : TypeVec (n + 1), v ⟹ v' → Sort*}
    (F : ∀ (t t') (f : t → t') (v v' : TypeVec n) (fs : v ⟹ v'),
    β (v ::: t) (v' ::: t') (fs ::: f)) :
    ∀ v v' fs, β v v' fs 
goal: β v v' fs

full_name: TypeVec.typevecCasesNil₂
code: /-- specialized cases distinction for an arrow in the category of 0-length type vectors -/
def typevecCasesNil₂ {β : Fin2.elim0 ⟹ Fin2.elim0 → Sort*} (f : β nilFun) : ∀ f, β f 
goal: (f : TypeVec.Arrow Fin2.elim0 Fin2.elim0) → β f

full_name: TypeVec.typevecCasesCons₂
code: /-- specialized cases distinction for an arrow in the category of (n+1)-length type vectors -/
def typevecCasesCons₂ (n : ℕ) (t t' : Type*) (v v' : TypeVec n)
    {β : (v ::: t) ⟹ (v' ::: t') → Sort*}
    (F : ∀ (f : t → t') (fs : v ⟹ v'), β (fs ::: f)) : ∀ fs, β fs 
goal: β fs

full_name: TypeVec.typevecCasesNil₂_appendFun
code: theorem typevecCasesNil₂_appendFun {β : Fin2.elim0 ⟹ Fin2.elim0 → Sort*} (f : β nilFun) :
    typevecCasesNil₂ f nilFun = f 
goal: TypeVec.typevecCasesNil₂ f TypeVec.nilFun = f

full_name: TypeVec.typevecCasesCons₂_appendFun
code: theorem typevecCasesCons₂_appendFun (n : ℕ) (t t' : Type*) (v v' : TypeVec n)
    {β : (v ::: t) ⟹ (v' ::: t') → Sort*}
    (F : ∀ (f : t → t') (fs : v ⟹ v'), β (fs ::: f))
    (f fs) :
    typevecCasesCons₂ n t t' v v' F (fs ::: f) = F f fs 
goal: TypeVec.typevecCasesCons₂ n t t' v v' F (fs ::: f) = F f fs

full_name: TypeVec.PredLast
code: /-- `PredLast α p x` predicates `p` of the last element of `x : α.append1 β`. -/
def PredLast (α : TypeVec n) {β : Type*} (p : β → Prop) : ∀ ⦃i⦄, (α.append1 β) i → Prop
  
goal: (α ::: β) i → Prop

full_name: TypeVec.RelLast
code: /-- `RelLast α r x y` says that `p` the last elements of `x y : α.append1 β` are related by `r` and
all the other elements are equal. -/
def RelLast (α : TypeVec n) {β γ : Type u} (r : β → γ → Prop) :
    ∀ ⦃i⦄, (α.append1 β) i → (α.append1 γ) i → Prop
  
goal: (α ::: β) i → (α ::: γ) i → Prop

full_name: TypeVec.repeat
code: /-- `repeat n t` is a `n-length` type vector that contains `n` occurrences of `t` -/
def «repeat» : ∀ (n : ℕ), Sort _ → TypeVec n
  
goal: Type u_1 → TypeVec.{u_1} n

full_name: TypeVec.prod
code: /-- `prod α β` is the pointwise product of the components of `α` and `β` -/
def prod : ∀ {n}, TypeVec.{u} n → TypeVec.{u} n → TypeVec n
  
goal: TypeVec.{u} n → TypeVec.{u} n → TypeVec.{u} n

full_name: MvFunctor._aux_Mathlib_Data_TypeVec___unexpand_TypeVec_prod_1
code: @[inherit_doc] scoped[MvFunctor] infixl:45 " ⊗ " => TypeVec.prod
goal: Lean.PrettyPrinter.Unexpander

full_name: MvFunctor.«_aux_Mathlib_Data_TypeVec___macroRules_MvFunctor_term_⊗__1»
code: @[inherit_doc] scoped[MvFunctor] infixl:45 " ⊗ " => TypeVec.prod
goal: Lean.Macro

full_name: TypeVec.const
code: /-- `const x α` is an arrow that ignores its source and constructs a `TypeVec` that
contains nothing but `x` -/
protected def const {β} (x : β) : ∀ {n} (α : TypeVec n), α ⟹ «repeat» _ β
  
goal: α.Arrow (TypeVec.repeat n β)

full_name: TypeVec.repeatEq
code: /-- vector of equality on a product of vectors -/
def repeatEq : ∀ {n} (α : TypeVec n), (α ⊗ α) ⟹ «repeat» _ Prop
  
goal: (α.prod α).Arrow (TypeVec.repeat n Prop)

full_name: TypeVec.const_append1
code: theorem const_append1 {β γ} (x : γ) {n} (α : TypeVec n) :
    TypeVec.const x (α ::: β) = appendFun (TypeVec.const x α) fun _ => x 
goal: TypeVec.const x (α ::: β) = (TypeVec.const x α ::: fun x_1 => x)

full_name: TypeVec.eq_nilFun
code: theorem eq_nilFun {α β : TypeVec 0} (f : α ⟹ β) : f = nilFun 
goal: f = TypeVec.nilFun

full_name: TypeVec.id_eq_nilFun
code: theorem id_eq_nilFun {α : TypeVec 0} : @id _ α = nilFun 
goal: TypeVec.id = TypeVec.nilFun

full_name: TypeVec.const_nil
code: theorem const_nil {β} (x : β) (α : TypeVec 0) : TypeVec.const x α = nilFun 
goal: TypeVec.const x α = TypeVec.nilFun

full_name: TypeVec.repeat_eq_append1
code: @[typevec]
theorem repeat_eq_append1 {β} {n} (α : TypeVec n) :
    repeatEq (α ::: β) = splitFun (α := (α ⊗ α) ::: _ )
    (α' := («repeat» n Prop) ::: _) (repeatEq α) (uncurry Eq) 
goal: (α ::: β).repeatEq = TypeVec.splitFun α.repeatEq (Function.uncurry Eq)

full_name: TypeVec.repeat_eq_nil
code: @[typevec]
theorem repeat_eq_nil (α : TypeVec 0) : repeatEq α = nilFun 
goal: α.repeatEq = TypeVec.nilFun

full_name: TypeVec.PredLast'
code: /-- predicate on a type vector to constrain only the last object -/
def PredLast' (α : TypeVec n) {β : Type*} (p : β → Prop) :
    (α ::: β) ⟹ «repeat» (n + 1) Prop 
goal: (α ::: β).Arrow (TypeVec.repeat (n + 1) Prop)

full_name: TypeVec.RelLast'
code: /-- predicate on the product of two type vectors to constrain only their last object -/
def RelLast' (α : TypeVec n) {β : Type*} (p : β → β → Prop) :
    (α ::: β) ⊗ (α ::: β) ⟹ «repeat» (n + 1) Prop 
goal: ((α ::: β).prod (α ::: β)).Arrow (TypeVec.repeat (n + 1) Prop)

full_name: TypeVec.Curry
code: /-- given `F : TypeVec.{u} (n+1) → Type u`, `curry F : Type u → TypeVec.{u} → Type u`,
i.e. its first argument can be fed in separately from the rest of the vector of arguments -/
def Curry (F : TypeVec.{u} (n + 1) → Type*) (α : Type u) (β : TypeVec.{u} n) : Type _ 
goal: Type u_1

full_name: TypeVec.Curry.inhabited
code: instance Curry.inhabited (F : TypeVec.{u} (n + 1) → Type*) (α : Type u) (β : TypeVec.{u} n)
    [I : Inhabited (F <| (β ::: α))] : Inhabited (Curry F α β) 
goal: Inhabited (TypeVec.Curry F α β)

full_name: TypeVec.dropRepeat
code: /-- arrow to remove one element of a `repeat` vector -/
def dropRepeat (α : Type*) : ∀ {n}, drop («repeat» (succ n) α) ⟹ «repeat» n α
  
goal: (TypeVec.repeat n.succ α).drop.Arrow (TypeVec.repeat n α)

full_name: TypeVec.ofRepeat
code: /-- projection for a repeat vector -/
def ofRepeat {α : Sort _} : ∀ {n i}, «repeat» n α i → α
  
goal: TypeVec.repeat n α i → α

full_name: TypeVec.const_iff_true
code: theorem const_iff_true {α : TypeVec n} {i x p} : ofRepeat (TypeVec.const p α i x) ↔ p 
goal: TypeVec.ofRepeat (TypeVec.const p α i x) ↔ p

full_name: TypeVec.prod.fst
code: /-- left projection of a `prod` vector -/
def prod.fst : ∀ {n} {α β : TypeVec.{u} n}, α ⊗ β ⟹ α
  
goal: (α.prod β).Arrow α

full_name: TypeVec.prod.snd
code: /-- right projection of a `prod` vector -/
def prod.snd : ∀ {n} {α β : TypeVec.{u} n}, α ⊗ β ⟹ β
  
goal: (α.prod β).Arrow β

full_name: TypeVec.prod.diag
code: /-- introduce a product where both components are the same -/
def prod.diag : ∀ {n} {α : TypeVec.{u} n}, α ⟹ α ⊗ α
  
goal: α.Arrow (α.prod α)

full_name: TypeVec.prod.mk
code: /-- constructor for `prod` -/
def prod.mk : ∀ {n} {α β : TypeVec.{u} n} (i : Fin2 n), α i → β i → (α ⊗ β) i
  
goal: α i → β i → α.prod β i

full_name: TypeVec.prod_fst_mk
code: @[simp]
theorem prod_fst_mk {α β : TypeVec n} (i : Fin2 n) (a : α i) (b : β i) :
    TypeVec.prod.fst i (prod.mk i a b) = a 
goal: TypeVec.prod.fst i (TypeVec.prod.mk i a b) = a

full_name: TypeVec.prod_snd_mk
code: @[simp]
theorem prod_snd_mk {α β : TypeVec n} (i : Fin2 n) (a : α i) (b : β i) :
    TypeVec.prod.snd i (prod.mk i a b) = b 
goal: TypeVec.prod.snd i (TypeVec.prod.mk i a b) = b

full_name: TypeVec.prod.map
code: /-- `prod` is functorial -/
protected def prod.map : ∀ {n} {α α' β β' : TypeVec.{u} n}, α ⟹ β → α' ⟹ β' → α ⊗ α' ⟹ β ⊗ β'
  
goal: α.Arrow β → α'.Arrow β' → (α.prod α').Arrow (β.prod β')

full_name: MvFunctor.«_aux_Mathlib_Data_TypeVec___macroRules_MvFunctor_term_⊗'__1»
code: @[inherit_doc] scoped[MvFunctor] infixl:45 " ⊗' " => TypeVec.prod.map
goal: Lean.Macro

full_name: MvFunctor._aux_Mathlib_Data_TypeVec___unexpand_TypeVec_prod_map_1
code: @[inherit_doc] scoped[MvFunctor] infixl:45 " ⊗' " => TypeVec.prod.map
goal: Lean.PrettyPrinter.Unexpander

full_name: TypeVec.fst_prod_mk
code: theorem fst_prod_mk {α α' β β' : TypeVec n} (f : α ⟹ β) (g : α' ⟹ β') :
    TypeVec.prod.fst ⊚ (f ⊗' g) = f ⊚ TypeVec.prod.fst 
goal: TypeVec.comp TypeVec.prod.fst (TypeVec.prod.map f g) = TypeVec.comp f TypeVec.prod.fst

full_name: TypeVec.snd_prod_mk
code: theorem snd_prod_mk {α α' β β' : TypeVec n} (f : α ⟹ β) (g : α' ⟹ β') :
    TypeVec.prod.snd ⊚ (f ⊗' g) = g ⊚ TypeVec.prod.snd 
goal: TypeVec.comp TypeVec.prod.snd (TypeVec.prod.map f g) = TypeVec.comp g TypeVec.prod.snd

full_name: TypeVec.fst_diag
code: theorem fst_diag {α : TypeVec n} : TypeVec.prod.fst ⊚ (prod.diag : α ⟹ _) = id 
goal: TypeVec.comp TypeVec.prod.fst TypeVec.prod.diag = TypeVec.id

full_name: TypeVec.snd_diag
code: theorem snd_diag {α : TypeVec n} : TypeVec.prod.snd ⊚ (prod.diag : α ⟹ _) = id 
goal: TypeVec.comp TypeVec.prod.snd TypeVec.prod.diag = TypeVec.id

full_name: TypeVec.repeatEq_iff_eq
code: theorem repeatEq_iff_eq {α : TypeVec n} {i x y} :
    ofRepeat (repeatEq α i (prod.mk _ x y)) ↔ x = y 
goal: TypeVec.ofRepeat (α.repeatEq i (TypeVec.prod.mk i x y)) ↔ x = y

full_name: TypeVec.Subtype_
code: /-- given a predicate vector `p` over vector `α`, `Subtype_ p` is the type of vectors
that contain an `α` that satisfies `p` -/
def Subtype_ : ∀ {n} {α : TypeVec.{u} n}, (α ⟹ «repeat» n Prop) → TypeVec n
  
goal: α.Arrow (TypeVec.repeat n Prop) → TypeVec.{u} n

full_name: TypeVec.subtypeVal
code: /-- projection on `Subtype_` -/
def subtypeVal : ∀ {n} {α : TypeVec.{u} n} (p : α ⟹ «repeat» n Prop), Subtype_ p ⟹ α
  
goal: (TypeVec.Subtype_ p).Arrow α

full_name: TypeVec.toSubtype
code: /-- arrow that rearranges the type of `Subtype_` to turn a subtype of vector into
a vector of subtypes -/
def toSubtype :
    ∀ {n} {α : TypeVec.{u} n} (p : α ⟹ «repeat» n Prop),
      (fun i : Fin2 n => { x // ofRepeat <| p i x }) ⟹ Subtype_ p
  
goal: TypeVec.Arrow (fun i => { x // TypeVec.ofRepeat (p i x) }) (TypeVec.Subtype_ p)

full_name: TypeVec.ofSubtype
code: /-- arrow that rearranges the type of `Subtype_` to turn a vector of subtypes
into a subtype of vector -/
def ofSubtype {n} {α : TypeVec.{u} n} (p : α ⟹ «repeat» n Prop) :
    Subtype_ p ⟹ fun i : Fin2 n => { x // ofRepeat <| p i x }
  
goal: (TypeVec.Subtype_ p).Arrow fun i => { x // TypeVec.ofRepeat (p i x) }

full_name: TypeVec.toSubtype'
code: /-- 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
  
goal: TypeVec.Arrow (fun i => { x // TypeVec.ofRepeat (p i (TypeVec.prod.mk i x.1 x.2)) }) (TypeVec.Subtype_ p)

full_name: TypeVec.ofSubtype'
code: /-- 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) }
  
goal: (TypeVec.Subtype_ p).Arrow fun i => { x // TypeVec.ofRepeat (p i (TypeVec.prod.mk i x.1 x.2)) }

full_name: TypeVec.diagSub
code: /-- similar to `diag` but the target vector is a `Subtype_`
guaranteeing the equality of the components -/
def diagSub {n} {α : TypeVec.{u} n} : α ⟹ Subtype_ (repeatEq α)
  
goal: α.Arrow (TypeVec.Subtype_ α.repeatEq)

full_name: TypeVec.subtypeVal_nil
code: theorem subtypeVal_nil {α : TypeVec.{u} 0} (ps : α ⟹ «repeat» 0 Prop) :
    TypeVec.subtypeVal ps = nilFun 
goal: TypeVec.subtypeVal ps = TypeVec.nilFun

full_name: TypeVec.diag_sub_val
code: theorem diag_sub_val {n} {α : TypeVec.{u} n} : subtypeVal (repeatEq α) ⊚ diagSub = prod.diag 
goal: TypeVec.comp (TypeVec.subtypeVal α.repeatEq) TypeVec.diagSub = TypeVec.prod.diag

full_name: TypeVec.prod_id
code: theorem prod_id : ∀ {n} {α β : TypeVec.{u} n}, (id ⊗' id) = (id : α ⊗ β ⟹ _) 
goal: TypeVec.prod.map TypeVec.id TypeVec.id = TypeVec.id

full_name: TypeVec.append_prod_appendFun
code: 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₁)) 
goal: (TypeVec.prod.map f₀ g₀ ::: Prod.map f₁ g₁) = TypeVec.prod.map (f₀ ::: f₁) (g₀ ::: g₁)

full_name: TypeVec.dropFun_diag
code: @[simp]
theorem dropFun_diag {α} : dropFun (@prod.diag (n + 1) α) = prod.diag 
goal: TypeVec.dropFun TypeVec.prod.diag = TypeVec.prod.diag

full_name: TypeVec.dropFun_subtypeVal
code: @[simp]
theorem dropFun_subtypeVal {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (subtypeVal p) = subtypeVal _ 
goal: TypeVec.dropFun (TypeVec.subtypeVal p) = TypeVec.subtypeVal (TypeVec.dropFun p)

full_name: TypeVec.lastFun_subtypeVal
code: @[simp]
theorem lastFun_subtypeVal {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (subtypeVal p) = Subtype.val 
goal: TypeVec.lastFun (TypeVec.subtypeVal p) = Subtype.val

full_name: TypeVec.dropFun_toSubtype
code: @[simp]
theorem dropFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (toSubtype p) = toSubtype _ 
goal: TypeVec.dropFun (TypeVec.toSubtype p) = TypeVec.toSubtype fun i => p i.fs

full_name: TypeVec.lastFun_toSubtype
code: @[simp]
theorem lastFun_toSubtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (toSubtype p) = _root_.id 
goal: TypeVec.lastFun (TypeVec.toSubtype p) = id

full_name: TypeVec.dropFun_of_subtype
code: @[simp]
theorem dropFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    dropFun (ofSubtype p) = ofSubtype _ 
goal: TypeVec.dropFun (TypeVec.ofSubtype p) = TypeVec.ofSubtype (TypeVec.dropFun p)

full_name: TypeVec.lastFun_of_subtype
code: @[simp]
theorem lastFun_of_subtype {α} (p : α ⟹ «repeat» (n + 1) Prop) :
    lastFun (ofSubtype p) = _root_.id 
goal: TypeVec.lastFun (TypeVec.ofSubtype p) = id

full_name: TypeVec.dropFun_RelLast'
code: @[simp]
theorem dropFun_RelLast' {α : TypeVec n} {β} (R : β → β → Prop) :
    dropFun (RelLast' α R) = repeatEq α 
goal: TypeVec.dropFun (α.RelLast' R) = α.repeatEq

full_name: TypeVec.dropFun_prod
code: @[simp]
theorem dropFun_prod {α α' β β' : TypeVec (n + 1)} (f : α ⟹ β) (f' : α' ⟹ β') :
    dropFun (f ⊗' f') = (dropFun f ⊗' dropFun f') 
goal: TypeVec.dropFun (TypeVec.prod.map f f') = TypeVec.prod.map (TypeVec.dropFun f) (TypeVec.dropFun f')

full_name: TypeVec.lastFun_prod
code: @[simp]
theorem lastFun_prod {α α' β β' : TypeVec (n + 1)} (f : α ⟹ β) (f' : α' ⟹ β') :
    lastFun (f ⊗' f') = Prod.map (lastFun f) (lastFun f') 
goal: TypeVec.lastFun (TypeVec.prod.map f f') = Prod.map (TypeVec.lastFun f) (TypeVec.lastFun f')

full_name: TypeVec.dropFun_from_append1_drop_last
code: @[simp]
theorem dropFun_from_append1_drop_last {α : TypeVec (n + 1)} :
    dropFun (@fromAppend1DropLast _ α) = id 
goal: TypeVec.dropFun TypeVec.fromAppend1DropLast = TypeVec.id

full_name: TypeVec.lastFun_from_append1_drop_last
code: @[simp]
theorem lastFun_from_append1_drop_last {α : TypeVec (n + 1)} :
    lastFun (@fromAppend1DropLast _ α) = _root_.id 
goal: TypeVec.lastFun TypeVec.fromAppend1DropLast = id

full_name: TypeVec.dropFun_id
code: @[simp]
theorem dropFun_id {α : TypeVec (n + 1)} : dropFun (@TypeVec.id _ α) = id 
goal: TypeVec.dropFun TypeVec.id = TypeVec.id

full_name: TypeVec.prod_map_id
code: @[simp]
theorem prod_map_id {α β : TypeVec n} : (@TypeVec.id _ α ⊗' @TypeVec.id _ β) = id 
goal: TypeVec.prod.map TypeVec.id TypeVec.id = TypeVec.id

full_name: TypeVec.subtypeVal_diagSub
code: @[simp]
theorem subtypeVal_diagSub {α : TypeVec n} : subtypeVal (repeatEq α) ⊚ diagSub = prod.diag 
goal: TypeVec.comp (TypeVec.subtypeVal α.repeatEq) TypeVec.diagSub = TypeVec.prod.diag

full_name: TypeVec.toSubtype_of_subtype
code: @[simp]
theorem toSubtype_of_subtype {α : TypeVec n} (p : α ⟹ «repeat» n Prop) :
    toSubtype p ⊚ ofSubtype p = id 
goal: TypeVec.comp (TypeVec.toSubtype p) (TypeVec.ofSubtype p) = TypeVec.id

full_name: TypeVec.subtypeVal_toSubtype
code: @[simp]
theorem subtypeVal_toSubtype {α : TypeVec n} (p : α ⟹ «repeat» n Prop) :
    subtypeVal p ⊚ toSubtype p = fun _ => Subtype.val 
goal: TypeVec.comp (TypeVec.subtypeVal p) (TypeVec.toSubtype p) = fun x => Subtype.val

full_name: TypeVec.toSubtype_of_subtype_assoc
code: @[simp]
theorem toSubtype_of_subtype_assoc
    {α β : TypeVec n} (p : α ⟹ «repeat» n Prop) (f : β ⟹ Subtype_ p) :
    @toSubtype n _ p ⊚ ofSubtype _ ⊚ f = f 
goal: TypeVec.comp (TypeVec.toSubtype p) (TypeVec.comp (TypeVec.ofSubtype p) f) = f

full_name: TypeVec.toSubtype'_of_subtype'
code: @[simp]
theorem toSubtype'_of_subtype' {α : TypeVec n} (r : α ⊗ α ⟹ «repeat» n Prop) :
    toSubtype' r ⊚ ofSubtype' r = id 
goal: TypeVec.comp (TypeVec.toSubtype' r) (TypeVec.ofSubtype' r) = TypeVec.id

full_name: TypeVec.subtypeVal_toSubtype'
code: theorem subtypeVal_toSubtype' {α : TypeVec n} (r : α ⊗ α ⟹ «repeat» n Prop) :
    subtypeVal r ⊚ toSubtype' r = fun i x => prod.mk i x.1.fst x.1.snd 
goal: TypeVec.comp (TypeVec.subtypeVal r) (TypeVec.toSubtype' r) = fun i x => TypeVec.prod.mk i (↑x).1 (↑x).2