l3lab/ntp-mathlib huggingface dataset:
/-- This is a helper construction that can be useful when verifying that a category has certain wide
    equalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (λ j, F.map (line j))`, and a trident on `λ j, F.map (line j)`, we get a cone
    on `F`.

    If you're thinking about using this, have a look at
    `hasWideEqualizers_of_hasLimit_parallelFamily`, which you may find to be an easier way of
    achieving your goal. -/
def Cone.ofTrident {F : WalkingParallelFamily J ⥤ C} (t : Trident fun j => F.map (line j)) : Cone F
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> aesop_cat)
      naturality := fun j j' g => by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Trident fun j => F.map (line j)
j j' : WalkingParallelFamily J
g : j ⟶ j'
⊢ ((Functor.const (WalkingParallelFamily J)).obj t.pt).map g ≫
      (fun X => t.π.app X ≫ eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X)) j' =
    (fun X => t.π.app X ≫ eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X)) j ≫ F.map g

Next tactic:
cases g
/-- This is a helper construction that can be useful when verifying that a category has certain wide
    equalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (λ j, F.map (line j))`, and a trident on `λ j, F.map (line j)`, we get a cone
    on `F`.

    If you're thinking about using this, have a look at
    `hasWideEqualizers_of_hasLimit_parallelFamily`, which you may find to be an easier way of
    achieving your goal. -/
def Cone.ofTrident {F : WalkingParallelFamily J ⥤ C} (t : Trident fun j => F.map (line j)) : Cone F
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> aesop_cat)
      naturality := fun j j' g => by cases g <;> 

Proof state:
case id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Trident fun j => F.map (line j)
j : WalkingParallelFamily J
⊢ ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (Hom.id j) ≫
      (fun X => t.π.app X ≫ eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X)) j =
    (fun X => t.π.app X ≫ eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X)) j ≫ F.map (Hom.id j)

Next tactic:
aesop_cat
/-- This is a helper construction that can be useful when verifying that a category has certain wide
    equalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (λ j, F.map (line j))`, and a trident on `λ j, F.map (line j)`, we get a cone
    on `F`.

    If you're thinking about using this, have a look at
    `hasWideEqualizers_of_hasLimit_parallelFamily`, which you may find to be an easier way of
    achieving your goal. -/
def Cone.ofTrident {F : WalkingParallelFamily J ⥤ C} (t : Trident fun j => F.map (line j)) : Cone F
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> aesop_cat)
      naturality := fun j j' g => by cases g <;> 

Proof state:
case line
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Trident fun j => F.map (line j)
x✝ : J
⊢ ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (line x✝) ≫
      (fun X => t.π.app X ≫ eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X)) one =
    (fun X => t.π.app X ≫ eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X)) zero ≫ F.map (line x✝)

Next tactic:
aesop_cat
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f : J → (X✝ ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
X : WalkingParallelFamily J
⊢ F.obj X = (parallelFamily fun j => F.map (line j)).obj X

Next tactic:
cases X
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> 

Proof state:
case zero
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
⊢ F.obj zero = (parallelFamily fun j => F.map (line j)).obj zero

Next tactic:
aesop_cat
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> 

Proof state:
case one
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
⊢ F.obj one = (parallelFamily fun j => F.map (line j)).obj one

Next tactic:
aesop_cat
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := fun j j' g => by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
j j' : WalkingParallelFamily J
g : j ⟶ j'
⊢ F.map g ≫ (fun X => eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X) ≫ t.ι.app X) j' =
    (fun X => eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X) ≫ t.ι.app X) j ≫
      ((Functor.const (WalkingParallelFamily J)).obj t.pt).map g

Next tactic:
cases g
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := fun j j' g => by cases g <;> 

Proof state:
case id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
j : WalkingParallelFamily J
⊢ F.map (Hom.id j) ≫ (fun X => eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X) ≫ t.ι.app X) j =
    (fun X => eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X) ≫ t.ι.app X) j ≫
      ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (Hom.id j)

Next tactic:
dsimp
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := fun j j' g => by cases g <;> 

Proof state:
case line
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
x✝ : J
⊢ F.map (line x✝) ≫ (fun X => eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X) ≫ t.ι.app X) one =
    (fun X => eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X) ≫ t.ι.app X) zero ≫
      ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (line x✝)

Next tactic:
dsimp
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := fun j j' g => by cases g <;> dsimp <;> 

Proof state:
case id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
j : WalkingParallelFamily J
⊢ F.map (𝟙 j) ≫ eqToHom (_ : F.obj j = (parallelFamily fun j => F.map (line j)).obj j) ≫ t.ι.app j =
    (eqToHom (_ : F.obj j = (parallelFamily fun j => F.map (line j)).obj j) ≫ t.ι.app j) ≫ 𝟙 t.pt

Next tactic:
simp [Cotrident.app_one t]
/-- This is a helper construction that can be useful when verifying that a category has all
    coequalizers. Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))`, and a cotrident on `fun j ↦ F.map (line j)` we get a
    cocone on `F`.

    If you're thinking about using this, have a look at
    `hasWideCoequalizers_of_hasColimit_parallelFamily`, which you may find to be an easier way
    of achieving your goal. -/
def Cocone.ofCotrident {F : WalkingParallelFamily J ⥤ C} (t : Cotrident fun j => F.map (line j)) :
    Cocone F where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := fun j j' g => by cases g <;> dsimp <;> 

Proof state:
case line
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
x✝ : J
⊢ F.map (line x✝) ≫ 𝟙 (F.obj one) ≫ t.ι.app one = (𝟙 (F.obj zero) ≫ t.ι.app zero) ≫ 𝟙 t.pt

Next tactic:
simp [Cotrident.app_one t]
@[simp]
theorem Cone.ofTrident_π {F : WalkingParallelFamily J ⥤ C} (t : Trident fun j => F.map (line j))
    (j) : (Cone.ofTrident t).π.app j = t.π.app j ≫ eqToHom (by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Trident fun j => F.map (line j)
j : WalkingParallelFamily J
⊢ (parallelFamily fun j => F.map (line j)).obj j = F.obj j

Next tactic:
cases j
@[simp]
theorem Cone.ofTrident_π {F : WalkingParallelFamily J ⥤ C} (t : Trident fun j => F.map (line j))
    (j) : (Cone.ofTrident t).π.app j = t.π.app j ≫ eqToHom (by cases j <;> 

Proof state:
case zero
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Trident fun j => F.map (line j)
⊢ (parallelFamily fun j => F.map (line j)).obj zero = F.obj zero

Next tactic:
aesop_cat
@[simp]
theorem Cone.ofTrident_π {F : WalkingParallelFamily J ⥤ C} (t : Trident fun j => F.map (line j))
    (j) : (Cone.ofTrident t).π.app j = t.π.app j ≫ eqToHom (by cases j <;> 

Proof state:
case one
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Trident fun j => F.map (line j)
⊢ (parallelFamily fun j => F.map (line j)).obj one = F.obj one

Next tactic:
aesop_cat
@[simp]
theorem Cocone.ofCotrident_ι {F : WalkingParallelFamily J ⥤ C}
    (t : Cotrident fun j => F.map (line j)) (j) :
    (Cocone.ofCotrident t).ι.app j = eqToHom (by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
j : WalkingParallelFamily J
⊢ F.obj j = (parallelFamily fun j => F.map (line j)).obj j

Next tactic:
cases j
@[simp]
theorem Cocone.ofCotrident_ι {F : WalkingParallelFamily J ⥤ C}
    (t : Cotrident fun j => F.map (line j)) (j) :
    (Cocone.ofCotrident t).ι.app j = eqToHom (by cases j <;> 

Proof state:
case zero
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
⊢ F.obj zero = (parallelFamily fun j => F.map (line j)).obj zero

Next tactic:
aesop_cat
@[simp]
theorem Cocone.ofCotrident_ι {F : WalkingParallelFamily J ⥤ C}
    (t : Cotrident fun j => F.map (line j)) (j) :
    (Cocone.ofCotrident t).ι.app j = eqToHom (by cases j <;> 

Proof state:
case one
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cotrident fun j => F.map (line j)
⊢ F.obj one = (parallelFamily fun j => F.map (line j)).obj one

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))` and a cone on `F`, we get a trident on
    `fun j ↦ F.map (line j)`. -/
def Trident.ofCone {F : WalkingParallelFamily J ⥤ C} (t : Cone F) : Trident fun j => F.map (line j)
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f : J → (X✝ ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cone F
X : WalkingParallelFamily J
⊢ F.obj X = (parallelFamily fun j => F.map (line j)).obj X

Next tactic:
cases X
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))` and a cone on `F`, we get a trident on
    `fun j ↦ F.map (line j)`. -/
def Trident.ofCone {F : WalkingParallelFamily J ⥤ C} (t : Cone F) : Trident fun j => F.map (line j)
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> 

Proof state:
case zero
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cone F
⊢ F.obj zero = (parallelFamily fun j => F.map (line j)).obj zero

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))` and a cone on `F`, we get a trident on
    `fun j ↦ F.map (line j)`. -/
def Trident.ofCone {F : WalkingParallelFamily J ⥤ C} (t : Cone F) : Trident fun j => F.map (line j)
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> 

Proof state:
case one
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cone F
⊢ F.obj one = (parallelFamily fun j => F.map (line j)).obj one

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))` and a cone on `F`, we get a trident on
    `fun j ↦ F.map (line j)`. -/
def Trident.ofCone {F : WalkingParallelFamily J ⥤ C} (t : Cone F) : Trident fun j => F.map (line j)
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> aesop_cat)
      naturality := by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cone F
⊢ ∀ ⦃X Y : WalkingParallelFamily J⦄ (f : X ⟶ Y),
    ((Functor.const (WalkingParallelFamily J)).obj t.pt).map f ≫
        (fun X => t.π.app X ≫ eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X)) Y =
      (fun X => t.π.app X ≫ eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X)) X ≫
        (parallelFamily fun j => F.map (line j)).map f

Next tactic:
rintro _ _ (_|_)
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))` and a cone on `F`, we get a trident on
    `fun j ↦ F.map (line j)`. -/
def Trident.ofCone {F : WalkingParallelFamily J ⥤ C} (t : Cone F) : Trident fun j => F.map (line j)
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> aesop_cat)
      naturality := by rintro _ _ (_|_) <;> 

Proof state:
case id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cone F
X✝ : WalkingParallelFamily J
⊢ ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (Hom.id X✝) ≫
      (fun X => t.π.app X ≫ eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X)) X✝ =
    (fun X => t.π.app X ≫ eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X)) X✝ ≫
      (parallelFamily fun j => F.map (line j)).map (Hom.id X✝)

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (fun j ↦ F.map (line j))` and a cone on `F`, we get a trident on
    `fun j ↦ F.map (line j)`. -/
def Trident.ofCone {F : WalkingParallelFamily J ⥤ C} (t : Cone F) : Trident fun j => F.map (line j)
    where
  pt := t.pt
  π :=
    { app := fun X => t.π.app X ≫ eqToHom (by cases X <;> aesop_cat)
      naturality := by rintro _ _ (_|_) <;> 

Proof state:
case line
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cone F
x✝ : J
⊢ ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (line x✝) ≫
      (fun X => t.π.app X ≫ eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X)) one =
    (fun X => t.π.app X ≫ eqToHom (_ : F.obj X = (parallelFamily fun j => F.map (line j)).obj X)) zero ≫
      (parallelFamily fun j => F.map (line j)).map (line x✝)

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (F.map left) (F.map right)` and a cocone on `F`, we get a cotrident on
    `fun j ↦ F.map (line j)`. -/
def Cotrident.ofCocone {F : WalkingParallelFamily J ⥤ C} (t : Cocone F) :
    Cotrident fun j => F.map (line j) where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
f : J → (X✝ ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cocone F
X : WalkingParallelFamily J
⊢ (parallelFamily fun j => F.map (line j)).obj X = F.obj X

Next tactic:
cases X
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (F.map left) (F.map right)` and a cocone on `F`, we get a cotrident on
    `fun j ↦ F.map (line j)`. -/
def Cotrident.ofCocone {F : WalkingParallelFamily J ⥤ C} (t : Cocone F) :
    Cotrident fun j => F.map (line j) where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> 

Proof state:
case zero
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cocone F
⊢ (parallelFamily fun j => F.map (line j)).obj zero = F.obj zero

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (F.map left) (F.map right)` and a cocone on `F`, we get a cotrident on
    `fun j ↦ F.map (line j)`. -/
def Cotrident.ofCocone {F : WalkingParallelFamily J ⥤ C} (t : Cocone F) :
    Cotrident fun j => F.map (line j) where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> 

Proof state:
case one
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cocone F
⊢ (parallelFamily fun j => F.map (line j)).obj one = F.obj one

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (F.map left) (F.map right)` and a cocone on `F`, we get a cotrident on
    `fun j ↦ F.map (line j)`. -/
def Cotrident.ofCocone {F : WalkingParallelFamily J ⥤ C} (t : Cocone F) :
    Cotrident fun j => F.map (line j) where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := by 

Proof state:
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cocone F
⊢ ∀ ⦃X Y : WalkingParallelFamily J⦄ (f : X ⟶ Y),
    (parallelFamily fun j => F.map (line j)).map f ≫
        (fun X => eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X) ≫ t.ι.app X) Y =
      (fun X => eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X) ≫ t.ι.app X) X ≫
        ((Functor.const (WalkingParallelFamily J)).obj t.pt).map f

Next tactic:
rintro _ _ (_|_)
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (F.map left) (F.map right)` and a cocone on `F`, we get a cotrident on
    `fun j ↦ F.map (line j)`. -/
def Cotrident.ofCocone {F : WalkingParallelFamily J ⥤ C} (t : Cocone F) :
    Cotrident fun j => F.map (line j) where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := by rintro _ _ (_|_) <;> 

Proof state:
case id
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cocone F
X✝ : WalkingParallelFamily J
⊢ (parallelFamily fun j => F.map (line j)).map (Hom.id X✝) ≫
      (fun X => eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X) ≫ t.ι.app X) X✝ =
    (fun X => eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X) ≫ t.ι.app X) X✝ ≫
      ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (Hom.id X✝)

Next tactic:
aesop_cat
/-- Given `F : WalkingParallelFamily ⥤ C`, which is really the same as
    `parallelFamily (F.map left) (F.map right)` and a cocone on `F`, we get a cotrident on
    `fun j ↦ F.map (line j)`. -/
def Cotrident.ofCocone {F : WalkingParallelFamily J ⥤ C} (t : Cocone F) :
    Cotrident fun j => F.map (line j) where
  pt := t.pt
  ι :=
    { app := fun X => eqToHom (by cases X <;> aesop_cat) ≫ t.ι.app X
      naturality := by rintro _ _ (_|_) <;> 

Proof state:
case line
J : Type w
C : Type u
inst✝ : Category.{v, u} C
X Y : C
f : J → (X ⟶ Y)
F : WalkingParallelFamily J ⥤ C
t : Cocone F
x✝ : J
⊢ (parallelFamily fun j => F.map (line j)).map (line x✝) ≫
      (fun X => eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X) ≫ t.ι.app X) one =
    (fun X => eqToHom (_ : (parallelFamily fun j => F.map (line j)).obj X = F.obj X) ≫ t.ι.app X) zero ≫
      ((Functor.const (WalkingParallelFamily J)).obj t.pt).map (line x✝)

Next tactic:
aesop_cat