File: Mathlib/CategoryTheory/Limits/Shapes/Biproducts.lean

full_name: CategoryTheory.Limits.Bicone.ι_π
code: /-- A `c : Bicone F` is:
* an object `c.pt` and
* morphisms `π j : pt ⟶ F j` and `ι j : F j ⟶ pt` for each `j`,
* such that `ι j ≫ π j'` is the identity when `j = j'` and zero otherwise.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Bicone (F : J → C) where
  pt : C
  π : ∀ j, pt ⟶ F j
  ι : ∀ j, F j ⟶ pt
  ι_π : ∀ j j', ι j ≫ π j' =
    if h : j = j' then eqToHom (congrArg F h) else 0 := by aesop
goal: self.ι j ≫ self.π j' = if h : j = j' then CategoryTheory.eqToHom ⋯ else 0

full_name: CategoryTheory.Limits.Bicone.ι
code: /-- A `c : Bicone F` is:
* an object `c.pt` and
* morphisms `π j : pt ⟶ F j` and `ι j : F j ⟶ pt` for each `j`,
* such that `ι j ≫ π j'` is the identity when `j = j'` and zero otherwise.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Bicone (F : J → C) where
  pt : C
  π : ∀ j, pt ⟶ F j
  ι : ∀ j, F j ⟶ pt
  ι_π : ∀ j j', ι j ≫ π j' =
    if h : j = j' then eqToHom (congrArg F h) else 0 := by aesop
goal: F j ⟶ self.pt

full_name: CategoryTheory.Limits.Bicone
code: /-- A `c : Bicone F` is:
* an object `c.pt` and
* morphisms `π j : pt ⟶ F j` and `ι j : F j ⟶ pt` for each `j`,
* such that `ι j ≫ π j'` is the identity when `j = j'` and zero otherwise.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Bicone (F : J → C) where
  pt : C
  π : ∀ j, pt ⟶ F j
  ι : ∀ j, F j ⟶ pt
  ι_π : ∀ j j', ι j ≫ π j' =
    if h : j = j' then eqToHom (congrArg F h) else 0 := by aesop
goal: Type (max (max uC uC') w)

full_name: CategoryTheory.Limits.Bicone.pt
code: /-- A `c : Bicone F` is:
* an object `c.pt` and
* morphisms `π j : pt ⟶ F j` and `ι j : F j ⟶ pt` for each `j`,
* such that `ι j ≫ π j'` is the identity when `j = j'` and zero otherwise.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Bicone (F : J → C) where
  pt : C
  π : ∀ j, pt ⟶ F j
  ι : ∀ j, F j ⟶ pt
  ι_π : ∀ j j', ι j ≫ π j' =
    if h : j = j' then eqToHom (congrArg F h) else 0 := by aesop
goal: C

full_name: CategoryTheory.Limits.Bicone.π
code: /-- A `c : Bicone F` is:
* an object `c.pt` and
* morphisms `π j : pt ⟶ F j` and `ι j : F j ⟶ pt` for each `j`,
* such that `ι j ≫ π j'` is the identity when `j = j'` and zero otherwise.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure Bicone (F : J → C) where
  pt : C
  π : ∀ j, pt ⟶ F j
  ι : ∀ j, F j ⟶ pt
  ι_π : ∀ j j', ι j ≫ π j' =
    if h : j = j' then eqToHom (congrArg F h) else 0 := by aesop
goal: self.pt ⟶ F j

full_name: CategoryTheory.Limits.bicone_ι_π_self
code: @[reassoc (attr := simp)]
theorem bicone_ι_π_self {F : J → C} (B : Bicone F) (j : J) : B.ι j ≫ B.π j = 𝟙 (F j) 
goal: B.ι j ≫ B.π j = 𝟙 (F j)

full_name: CategoryTheory.Limits.bicone_ι_π_ne
code: @[reassoc (attr := simp)]
theorem bicone_ι_π_ne {F : J → C} (B : Bicone F) {j j' : J} (h : j ≠ j') : B.ι j ≫ B.π j' = 0 
goal: B.ι j ≫ B.π j' = 0

full_name: CategoryTheory.Limits.BiconeMorphism
code: /-- A bicone morphism between two bicones for the same diagram is a morphism of the bicone points
which commutes with the cone and cocone legs. -/
structure BiconeMorphism {F : J → C} (A B : Bicone F) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wπ : ∀ j : J, hom ≫ B.π j = A.π j := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wι : ∀ j : J, A.ι j ≫ hom = B.ι j := by aesop_cat
goal: Type uC'

full_name: CategoryTheory.Limits.BiconeMorphism.hom
code: /-- A bicone morphism between two bicones for the same diagram is a morphism of the bicone points
which commutes with the cone and cocone legs. -/
structure BiconeMorphism {F : J → C} (A B : Bicone F) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wπ : ∀ j : J, hom ≫ B.π j = A.π j := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wι : ∀ j : J, A.ι j ≫ hom = B.ι j := by aesop_cat
goal: A.pt ⟶ B.pt

full_name: CategoryTheory.Limits.BiconeMorphism.wι
code: /-- A bicone morphism between two bicones for the same diagram is a morphism of the bicone points
which commutes with the cone and cocone legs. -/
structure BiconeMorphism {F : J → C} (A B : Bicone F) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wπ : ∀ j : J, hom ≫ B.π j = A.π j := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wι : ∀ j : J, A.ι j ≫ hom = B.ι j := by aesop_cat
goal: A.ι j ≫ self.hom = B.ι j

full_name: CategoryTheory.Limits.BiconeMorphism.wπ
code: /-- A bicone morphism between two bicones for the same diagram is a morphism of the bicone points
which commutes with the cone and cocone legs. -/
structure BiconeMorphism {F : J → C} (A B : Bicone F) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wπ : ∀ j : J, hom ≫ B.π j = A.π j := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wι : ∀ j : J, A.ι j ≫ hom = B.ι j := by aesop_cat
goal: self.hom ≫ B.π j = A.π j

full_name: CategoryTheory.Limits.Bicone.category_id_hom
code: /-- The category of bicones on a given diagram. -/
@[simps]
instance Bicone.category : Category (Bicone F) 
goal: (𝟙 B).hom = 𝟙 B.pt

full_name: CategoryTheory.Limits.Bicone.category_comp_hom
code: /-- The category of bicones on a given diagram. -/
@[simps]
instance Bicone.category : Category (Bicone F) 
goal: ∀ {X Y Z : CategoryTheory.Limits.Bicone F} (f : X ⟶ Y) (g : Y ⟶ Z), (f ≫ g).hom = f.hom ≫ g.hom

full_name: CategoryTheory.Limits.Bicone.category
code: /-- The category of bicones on a given diagram. -/
@[simps]
instance Bicone.category : Category (Bicone F) 
goal: CategoryTheory.Category.{uC', max (max uC uC') w} (CategoryTheory.Limits.Bicone F)

full_name: CategoryTheory.Limits.BiconeMorphism.ext
code: @[ext]
theorem BiconeMorphism.ext {c c' : Bicone F} (f g : c ⟶ c') (w : f.hom = g.hom) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.Bicones.ext_inv_hom
code: /-- To give an isomorphism between cocones, it suffices to give an
  isomorphism between their vertices which commutes with the cocone
  maps. -/
-- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule
@[aesop apply safe (rule_sets := [CategoryTheory]), simps]
def ext {c c' : Bicone F} (φ : c.pt ≅ c'.pt)
    (wι : ∀ j, c.ι j ≫ φ.hom = c'.ι j := by aesop_cat)
    (wπ : ∀ j, φ.hom ≫ c'.π j = c.π j := by aesop_cat) : c ≅ c' 
goal: (CategoryTheory.Limits.Bicones.ext φ wι wπ).inv.hom = φ.inv

full_name: CategoryTheory.Limits.Bicones.ext_hom_hom
code: /-- To give an isomorphism between cocones, it suffices to give an
  isomorphism between their vertices which commutes with the cocone
  maps. -/
-- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule
@[aesop apply safe (rule_sets := [CategoryTheory]), simps]
def ext {c c' : Bicone F} (φ : c.pt ≅ c'.pt)
    (wι : ∀ j, c.ι j ≫ φ.hom = c'.ι j := by aesop_cat)
    (wπ : ∀ j, φ.hom ≫ c'.π j = c.π j := by aesop_cat) : c ≅ c' 
goal: (CategoryTheory.Limits.Bicones.ext φ wι wπ).hom.hom = φ.hom

full_name: CategoryTheory.Limits.Bicones.ext
code: /-- To give an isomorphism between cocones, it suffices to give an
  isomorphism between their vertices which commutes with the cocone
  maps. -/
-- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule
@[aesop apply safe (rule_sets := [CategoryTheory]), simps]
def ext {c c' : Bicone F} (φ : c.pt ≅ c'.pt)
    (wι : ∀ j, c.ι j ≫ φ.hom = c'.ι j := by aesop_cat)
    (wπ : ∀ j, φ.hom ≫ c'.π j = c.π j := by aesop_cat) : c ≅ c' 
goal: c ≅ c'

full_name: CategoryTheory.Limits.Bicones.functoriality_obj_π
code: /-- A functor `G : C ⥤ D` sends bicones over `F` to bicones over `G.obj ∘ F` functorially. -/
@[simps]
def functoriality (G : C ⥤ D) [Functor.PreservesZeroMorphisms G] :
    Bicone F ⥤ Bicone (G.obj ∘ F) 
goal: ((CategoryTheory.Limits.Bicones.functoriality F G).obj A).π j = G.map (A.π j)

full_name: CategoryTheory.Limits.Bicones.functoriality
code: /-- A functor `G : C ⥤ D` sends bicones over `F` to bicones over `G.obj ∘ F` functorially. -/
@[simps]
def functoriality (G : C ⥤ D) [Functor.PreservesZeroMorphisms G] :
    Bicone F ⥤ Bicone (G.obj ∘ F) 
goal: CategoryTheory.Limits.Bicone F ⥤ CategoryTheory.Limits.Bicone (G.obj ∘ F)

full_name: CategoryTheory.Limits.Bicones.functoriality_obj_ι
code: /-- A functor `G : C ⥤ D` sends bicones over `F` to bicones over `G.obj ∘ F` functorially. -/
@[simps]
def functoriality (G : C ⥤ D) [Functor.PreservesZeroMorphisms G] :
    Bicone F ⥤ Bicone (G.obj ∘ F) 
goal: ((CategoryTheory.Limits.Bicones.functoriality F G).obj A).ι j = G.map (A.ι j)

full_name: CategoryTheory.Limits.Bicones.functoriality_map_hom
code: /-- A functor `G : C ⥤ D` sends bicones over `F` to bicones over `G.obj ∘ F` functorially. -/
@[simps]
def functoriality (G : C ⥤ D) [Functor.PreservesZeroMorphisms G] :
    Bicone F ⥤ Bicone (G.obj ∘ F) 
goal: ∀ {X Y : CategoryTheory.Limits.Bicone F} (f : X ⟶ Y),
  ((CategoryTheory.Limits.Bicones.functoriality F G).map f).hom = G.map f.hom

full_name: CategoryTheory.Limits.Bicones.functoriality_obj_pt
code: /-- A functor `G : C ⥤ D` sends bicones over `F` to bicones over `G.obj ∘ F` functorially. -/
@[simps]
def functoriality (G : C ⥤ D) [Functor.PreservesZeroMorphisms G] :
    Bicone F ⥤ Bicone (G.obj ∘ F) 
goal: ((CategoryTheory.Limits.Bicones.functoriality F G).obj A).pt = G.obj A.pt

full_name: CategoryTheory.Limits.Bicones.functoriality_full
code: instance functoriality_full [G.PreservesZeroMorphisms] [G.Full] [G.Faithful] :
    (functoriality F G).Full 
goal: (CategoryTheory.Limits.Bicones.functoriality F G).Full

full_name: CategoryTheory.Limits.Bicones.functoriality_faithful
code: instance functoriality_faithful [G.PreservesZeroMorphisms] [G.Faithful] :
    (functoriality F G).Faithful 
goal: (CategoryTheory.Limits.Bicones.functoriality F G).Faithful

full_name: CategoryTheory.Limits.Bicone.toConeFunctor
code: /-- Extract the cone from a bicone. -/
def toConeFunctor : Bicone F ⥤ Cone (Discrete.functor F) 
goal: CategoryTheory.Limits.Bicone F ⥤ CategoryTheory.Limits.Cone (CategoryTheory.Discrete.functor F)

full_name: CategoryTheory.Limits.Bicone.toCone
code: /-- A shorthand for `toConeFunctor.obj` -/
abbrev toCone (B : Bicone F) : Cone (Discrete.functor F) 
goal: CategoryTheory.Limits.Cone (CategoryTheory.Discrete.functor F)

full_name: CategoryTheory.Limits.Bicone.toCone_pt
code: @[simp]
theorem toCone_pt (B : Bicone F) : B.toCone.pt = B.pt 
goal: B.toCone.pt = B.pt

full_name: CategoryTheory.Limits.Bicone.toCone_π_app
code: @[simp]
theorem toCone_π_app (B : Bicone F) (j : Discrete J) : B.toCone.π.app j = B.π j.as 
goal: B.toCone.π.app j = B.π j.as

full_name: CategoryTheory.Limits.Bicone.toCone_π_app_mk
code: theorem toCone_π_app_mk (B : Bicone F) (j : J) : B.toCone.π.app ⟨j⟩ = B.π j 
goal: B.toCone.π.app { as := j } = B.π j

full_name: CategoryTheory.Limits.Bicone.toCone_proj
code: @[simp]
theorem toCone_proj (B : Bicone F) (j : J) : Fan.proj B.toCone j = B.π j 
goal: CategoryTheory.Limits.Fan.proj B.toCone j = B.π j

full_name: CategoryTheory.Limits.Bicone.toCoconeFunctor
code: /-- Extract the cocone from a bicone. -/
def toCoconeFunctor : Bicone F ⥤ Cocone (Discrete.functor F) 
goal: CategoryTheory.Limits.Bicone F ⥤ CategoryTheory.Limits.Cocone (CategoryTheory.Discrete.functor F)

full_name: CategoryTheory.Limits.Bicone.toCocone
code: /-- A shorthand for `toCoconeFunctor.obj` -/
abbrev toCocone (B : Bicone F) : Cocone (Discrete.functor F) 
goal: CategoryTheory.Limits.Cocone (CategoryTheory.Discrete.functor F)

full_name: CategoryTheory.Limits.Bicone.toCocone_pt
code: @[simp]
theorem toCocone_pt (B : Bicone F) : B.toCocone.pt = B.pt 
goal: B.toCocone.pt = B.pt

full_name: CategoryTheory.Limits.Bicone.toCocone_ι_app
code: @[simp]
theorem toCocone_ι_app (B : Bicone F) (j : Discrete J) : B.toCocone.ι.app j = B.ι j.as 
goal: B.toCocone.ι.app j = B.ι j.as

full_name: CategoryTheory.Limits.Bicone.toCocone_inj
code: @[simp]
theorem toCocone_inj (B : Bicone F) (j : J) : Cofan.inj B.toCocone j = B.ι j 
goal: CategoryTheory.Limits.Cofan.inj B.toCocone j = B.ι j

full_name: CategoryTheory.Limits.Bicone.toCocone_ι_app_mk
code: theorem toCocone_ι_app_mk (B : Bicone F) (j : J) : B.toCocone.ι.app ⟨j⟩ = B.ι j 
goal: B.toCocone.ι.app { as := j } = B.ι j

full_name: CategoryTheory.Limits.Bicone.ofLimitCone_pt
code: /-- We can turn any limit cone over a discrete collection of objects into a bicone. -/
@[simps]
def ofLimitCone {f : J → C} {t : Cone (Discrete.functor f)} (ht : IsLimit t) : Bicone f 
goal: (CategoryTheory.Limits.Bicone.ofLimitCone ht).pt = t.pt

full_name: CategoryTheory.Limits.Bicone.ofLimitCone_ι
code: /-- We can turn any limit cone over a discrete collection of objects into a bicone. -/
@[simps]
def ofLimitCone {f : J → C} {t : Cone (Discrete.functor f)} (ht : IsLimit t) : Bicone f 
goal: (CategoryTheory.Limits.Bicone.ofLimitCone ht).ι j =
  ht.lift (CategoryTheory.Limits.Fan.mk (f j) fun j' => if h : j = j' then CategoryTheory.eqToHom ⋯ else 0)

full_name: CategoryTheory.Limits.Bicone.ofLimitCone_π
code: /-- We can turn any limit cone over a discrete collection of objects into a bicone. -/
@[simps]
def ofLimitCone {f : J → C} {t : Cone (Discrete.functor f)} (ht : IsLimit t) : Bicone f 
goal: (CategoryTheory.Limits.Bicone.ofLimitCone ht).π j = t.π.app { as := j }

full_name: CategoryTheory.Limits.Bicone.ofLimitCone
code: /-- We can turn any limit cone over a discrete collection of objects into a bicone. -/
@[simps]
def ofLimitCone {f : J → C} {t : Cone (Discrete.functor f)} (ht : IsLimit t) : Bicone f 
goal: CategoryTheory.Limits.Bicone f

full_name: CategoryTheory.Limits.Bicone.ι_of_isLimit
code: theorem ι_of_isLimit {f : J → C} {t : Bicone f} (ht : IsLimit t.toCone) (j : J) :
    t.ι j = ht.lift (Fan.mk _ fun j' => if h : j = j' then eqToHom (congr_arg f h) else 0) 
goal: t.ι j = ht.lift (CategoryTheory.Limits.Fan.mk (f j) fun j' => if h : j = j' then CategoryTheory.eqToHom ⋯ else 0)

full_name: CategoryTheory.Limits.Bicone.ofColimitCocone_ι
code: /-- We can turn any colimit cocone over a discrete collection of objects into a bicone. -/
@[simps]
def ofColimitCocone {f : J → C} {t : Cocone (Discrete.functor f)} (ht : IsColimit t) :
    Bicone f 
goal: (CategoryTheory.Limits.Bicone.ofColimitCocone ht).ι j = t.ι.app { as := j }

full_name: CategoryTheory.Limits.Bicone.ofColimitCocone
code: /-- We can turn any colimit cocone over a discrete collection of objects into a bicone. -/
@[simps]
def ofColimitCocone {f : J → C} {t : Cocone (Discrete.functor f)} (ht : IsColimit t) :
    Bicone f 
goal: CategoryTheory.Limits.Bicone f

full_name: CategoryTheory.Limits.Bicone.ofColimitCocone_π
code: /-- We can turn any colimit cocone over a discrete collection of objects into a bicone. -/
@[simps]
def ofColimitCocone {f : J → C} {t : Cocone (Discrete.functor f)} (ht : IsColimit t) :
    Bicone f 
goal: (CategoryTheory.Limits.Bicone.ofColimitCocone ht).π j =
  ht.desc (CategoryTheory.Limits.Cofan.mk (f j) fun j' => if h : j' = j then CategoryTheory.eqToHom ⋯ else 0)

full_name: CategoryTheory.Limits.Bicone.ofColimitCocone_pt
code: /-- We can turn any colimit cocone over a discrete collection of objects into a bicone. -/
@[simps]
def ofColimitCocone {f : J → C} {t : Cocone (Discrete.functor f)} (ht : IsColimit t) :
    Bicone f 
goal: (CategoryTheory.Limits.Bicone.ofColimitCocone ht).pt = t.pt

full_name: CategoryTheory.Limits.Bicone.π_of_isColimit
code: theorem π_of_isColimit {f : J → C} {t : Bicone f} (ht : IsColimit t.toCocone) (j : J) :
    t.π j = ht.desc (Cofan.mk _ fun j' => if h : j' = j then eqToHom (congr_arg f h) else 0) 
goal: t.π j = ht.desc (CategoryTheory.Limits.Cofan.mk (f j) fun j' => if h : j' = j then CategoryTheory.eqToHom ⋯ else 0)

full_name: CategoryTheory.Limits.Bicone.IsBilimit
code: /-- Structure witnessing that a bicone is both a limit cone and a colimit cocone. -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure IsBilimit {F : J → C} (B : Bicone F) where
  isLimit : IsLimit B.toCone
  isColimit : IsColimit B.toCocone
goal: Type (max (max uC uC') w)

full_name: CategoryTheory.Limits.Bicone.IsBilimit.isLimit
code: /-- Structure witnessing that a bicone is both a limit cone and a colimit cocone. -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure IsBilimit {F : J → C} (B : Bicone F) where
  isLimit : IsLimit B.toCone
  isColimit : IsColimit B.toCocone
goal: CategoryTheory.Limits.IsLimit B.toCone

full_name: CategoryTheory.Limits.Bicone.IsBilimit.isColimit
code: /-- Structure witnessing that a bicone is both a limit cone and a colimit cocone. -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure IsBilimit {F : J → C} (B : Bicone F) where
  isLimit : IsLimit B.toCone
  isColimit : IsColimit B.toCocone
goal: CategoryTheory.Limits.IsColimit B.toCocone

full_name: CategoryTheory.Limits.Bicone.subsingleton_isBilimit
code: instance subsingleton_isBilimit {f : J → C} {c : Bicone f} : Subsingleton c.IsBilimit 
goal: Subsingleton c.IsBilimit

full_name: CategoryTheory.Limits.Bicone.whisker_π
code: /-- Whisker a bicone with an equivalence between the indexing types. -/
@[simps]
def whisker {f : J → C} (c : Bicone f) (g : K ≃ J) : Bicone (f ∘ g) 
goal: (c.whisker g).π k = c.π (g k)

full_name: CategoryTheory.Limits.Bicone.whisker
code: /-- Whisker a bicone with an equivalence between the indexing types. -/
@[simps]
def whisker {f : J → C} (c : Bicone f) (g : K ≃ J) : Bicone (f ∘ g) 
goal: CategoryTheory.Limits.Bicone (f ∘ ⇑g)

full_name: CategoryTheory.Limits.Bicone.whisker_pt
code: /-- Whisker a bicone with an equivalence between the indexing types. -/
@[simps]
def whisker {f : J → C} (c : Bicone f) (g : K ≃ J) : Bicone (f ∘ g) 
goal: (c.whisker g).pt = c.pt

full_name: CategoryTheory.Limits.Bicone.whisker_ι
code: /-- Whisker a bicone with an equivalence between the indexing types. -/
@[simps]
def whisker {f : J → C} (c : Bicone f) (g : K ≃ J) : Bicone (f ∘ g) 
goal: (c.whisker g).ι k = c.ι (g k)

full_name: CategoryTheory.Limits.Bicone.whiskerToCone
code: /-- Taking the cone of a whiskered bicone results in a cone isomorphic to one gained
by whiskering the cone and postcomposing with a suitable isomorphism. -/
def whiskerToCone {f : J → C} (c : Bicone f) (g : K ≃ J) :
    (c.whisker g).toCone ≅
      (Cones.postcompose (Discrete.functorComp f g).inv).obj
        (c.toCone.whisker (Discrete.functor (Discrete.mk ∘ g))) 
goal: (c.whisker g).toCone ≅
  (CategoryTheory.Limits.Cones.postcompose (CategoryTheory.Discrete.functorComp f ⇑g).inv).obj
    (CategoryTheory.Limits.Cone.whisker (CategoryTheory.Discrete.functor (CategoryTheory.Discrete.mk ∘ ⇑g)) c.toCone)

full_name: CategoryTheory.Limits.Bicone.whiskerToCocone
code: /-- Taking the cocone of a whiskered bicone results in a cone isomorphic to one gained
by whiskering the cocone and precomposing with a suitable isomorphism. -/
def whiskerToCocone {f : J → C} (c : Bicone f) (g : K ≃ J) :
    (c.whisker g).toCocone ≅
      (Cocones.precompose (Discrete.functorComp f g).hom).obj
        (c.toCocone.whisker (Discrete.functor (Discrete.mk ∘ g))) 
goal: (c.whisker g).toCocone ≅
  (CategoryTheory.Limits.Cocones.precompose (CategoryTheory.Discrete.functorComp f ⇑g).hom).obj
    (CategoryTheory.Limits.Cocone.whisker (CategoryTheory.Discrete.functor (CategoryTheory.Discrete.mk ∘ ⇑g))
      c.toCocone)

full_name: CategoryTheory.Limits.Bicone.whiskerIsBilimitIff
code: /-- Whiskering a bicone with an equivalence between types preserves being a bilimit bicone. -/
def whiskerIsBilimitIff {f : J → C} (c : Bicone f) (g : K ≃ J) :
    (c.whisker g).IsBilimit ≃ c.IsBilimit 
goal: (c.whisker g).IsBilimit ≃ c.IsBilimit

full_name: CategoryTheory.Limits.LimitBicone.isBilimit
code: /-- A bicone over `F : J → C`, which is both a limit cone and a colimit cocone.
-/
-- @[nolint has_nonempty_instance] -- Porting note(#5171): removed; linter not ported yet
structure LimitBicone (F : J → C) where
  bicone : Bicone F
  isBilimit : bicone.IsBilimit
goal: self.bicone.IsBilimit

full_name: CategoryTheory.Limits.LimitBicone.bicone
code: /-- A bicone over `F : J → C`, which is both a limit cone and a colimit cocone.
-/
-- @[nolint has_nonempty_instance] -- Porting note(#5171): removed; linter not ported yet
structure LimitBicone (F : J → C) where
  bicone : Bicone F
  isBilimit : bicone.IsBilimit
goal: CategoryTheory.Limits.Bicone F

full_name: CategoryTheory.Limits.LimitBicone
code: /-- A bicone over `F : J → C`, which is both a limit cone and a colimit cocone.
-/
-- @[nolint has_nonempty_instance] -- Porting note(#5171): removed; linter not ported yet
structure LimitBicone (F : J → C) where
  bicone : Bicone F
  isBilimit : bicone.IsBilimit
goal: Type (max (max uC uC') w)

full_name: CategoryTheory.Limits.HasBiproduct.exists_biproduct
code: /-- `HasBiproduct F` expresses the mere existence of a bicone which is
simultaneously a limit and a colimit of the diagram `F`.
-/
class HasBiproduct (F : J → C) : Prop where mk' ::
  exists_biproduct : Nonempty (LimitBicone F)
goal: Nonempty (CategoryTheory.Limits.LimitBicone F)

full_name: CategoryTheory.Limits.HasBiproduct.mk'
code: /-- `HasBiproduct F` expresses the mere existence of a bicone which is
simultaneously a limit and a colimit of the diagram `F`.
-/
class HasBiproduct (F : J → C) : Prop where mk' ::
  exists_biproduct : Nonempty (LimitBicone F)
goal: CategoryTheory.Limits.HasBiproduct F

full_name: CategoryTheory.Limits.HasBiproduct
code: /-- `HasBiproduct F` expresses the mere existence of a bicone which is
simultaneously a limit and a colimit of the diagram `F`.
-/
class HasBiproduct (F : J → C) : Prop where mk' ::
  exists_biproduct : Nonempty (LimitBicone F)
goal: Prop

full_name: CategoryTheory.Limits.HasBiproduct.mk
code: theorem HasBiproduct.mk {F : J → C} (d : LimitBicone F) : HasBiproduct F 
goal: CategoryTheory.Limits.HasBiproduct F

full_name: CategoryTheory.Limits.getBiproductData
code: /-- Use the axiom of choice to extract explicit `BiproductData F` from `HasBiproduct F`. -/
def getBiproductData (F : J → C) [HasBiproduct F] : LimitBicone F 
goal: CategoryTheory.Limits.LimitBicone F

full_name: CategoryTheory.Limits.biproduct.bicone
code: /-- A bicone for `F` which is both a limit cone and a colimit cocone. -/
def biproduct.bicone (F : J → C) [HasBiproduct F] : Bicone F 
goal: CategoryTheory.Limits.Bicone F

full_name: CategoryTheory.Limits.biproduct.isBilimit
code: /-- `biproduct.bicone F` is a bilimit bicone. -/
def biproduct.isBilimit (F : J → C) [HasBiproduct F] : (biproduct.bicone F).IsBilimit 
goal: (CategoryTheory.Limits.biproduct.bicone F).IsBilimit

full_name: CategoryTheory.Limits.biproduct.isLimit
code: /-- `biproduct.bicone F` is a limit cone. -/
def biproduct.isLimit (F : J → C) [HasBiproduct F] : IsLimit (biproduct.bicone F).toCone 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Limits.biproduct.bicone F).toCone

full_name: CategoryTheory.Limits.biproduct.isColimit
code: /-- `biproduct.bicone F` is a colimit cocone. -/
def biproduct.isColimit (F : J → C) [HasBiproduct F] : IsColimit (biproduct.bicone F).toCocone 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Limits.biproduct.bicone F).toCocone

full_name: CategoryTheory.Limits.hasProduct_of_hasBiproduct
code: instance (priority := 100) hasProduct_of_hasBiproduct [HasBiproduct F] : HasProduct F 
goal: CategoryTheory.Limits.HasProduct F

full_name: CategoryTheory.Limits.hasCoproduct_of_hasBiproduct
code: instance (priority := 100) hasCoproduct_of_hasBiproduct [HasBiproduct F] : HasCoproduct F 
goal: CategoryTheory.Limits.HasCoproduct F

full_name: CategoryTheory.Limits.HasBiproductsOfShape
code: /-- `C` has biproducts of shape `J` if we have
a limit and a colimit, with the same cone points,
of every function `F : J → C`.
-/
class HasBiproductsOfShape : Prop where
  has_biproduct : ∀ F : J → C, HasBiproduct F
goal: Prop

full_name: CategoryTheory.Limits.HasBiproductsOfShape.has_biproduct
code: /-- `C` has biproducts of shape `J` if we have
a limit and a colimit, with the same cone points,
of every function `F : J → C`.
-/
class HasBiproductsOfShape : Prop where
  has_biproduct : ∀ F : J → C, HasBiproduct F
goal: CategoryTheory.Limits.HasBiproduct F

full_name: CategoryTheory.Limits.HasFiniteBiproducts
code: /-- `HasFiniteBiproducts C` represents a choice of biproduct for every family of objects in `C`
indexed by a finite type. -/
class HasFiniteBiproducts : Prop where
  out : ∀ n, HasBiproductsOfShape (Fin n) C
goal: Prop

full_name: CategoryTheory.Limits.HasFiniteBiproducts.out
code: /-- `HasFiniteBiproducts C` represents a choice of biproduct for every family of objects in `C`
indexed by a finite type. -/
class HasFiniteBiproducts : Prop where
  out : ∀ n, HasBiproductsOfShape (Fin n) C
goal: CategoryTheory.Limits.HasBiproductsOfShape (Fin n) C

full_name: CategoryTheory.Limits.hasBiproductsOfShape_of_equiv
code: theorem hasBiproductsOfShape_of_equiv {K : Type w'} [HasBiproductsOfShape K C] (e : J ≃ K) :
    HasBiproductsOfShape J C 
goal: CategoryTheory.Limits.HasBiproductsOfShape J C

full_name: CategoryTheory.Limits.hasBiproductsOfShape_finite
code: instance (priority := 100) hasBiproductsOfShape_finite [HasFiniteBiproducts C] [Finite J] :
    HasBiproductsOfShape J C 
goal: CategoryTheory.Limits.HasBiproductsOfShape J C

full_name: CategoryTheory.Limits.hasFiniteProducts_of_hasFiniteBiproducts
code: instance (priority := 100) hasFiniteProducts_of_hasFiniteBiproducts [HasFiniteBiproducts C] :
    HasFiniteProducts C 
goal: CategoryTheory.Limits.HasFiniteProducts C

full_name: CategoryTheory.Limits.hasFiniteCoproducts_of_hasFiniteBiproducts
code: instance (priority := 100) hasFiniteCoproducts_of_hasFiniteBiproducts [HasFiniteBiproducts C] :
    HasFiniteCoproducts C 
goal: CategoryTheory.Limits.HasFiniteCoproducts C

full_name: CategoryTheory.Limits.biproductIso
code: /-- The isomorphism between the specified limit and the specified colimit for
a functor with a bilimit.
-/
def biproductIso (F : J → C) [HasBiproduct F] : Limits.piObj F ≅ Limits.sigmaObj F 
goal: ∏ᶜ F ≅ ∐ F

full_name: CategoryTheory.Limits.biproduct
code: /-- `biproduct f` computes the biproduct of a family of elements `f`. (It is defined as an
   abbreviation for `limit (Discrete.functor f)`, so for most facts about `biproduct f`, you will
   just use general facts about limits and colimits.) -/
abbrev biproduct (f : J → C) [HasBiproduct f] : C 
goal: C

full_name: CategoryTheory.Limits.«_aux_Mathlib_CategoryTheory_Limits_Shapes_Biproducts___macroRules_CategoryTheory_Limits_term⨁__1»
code: @[inherit_doc biproduct]
notation "⨁ " f:20 => biproduct f
goal: Lean.Macro

full_name: CategoryTheory.Limits._aux_Mathlib_CategoryTheory_Limits_Shapes_Biproducts___unexpand_CategoryTheory_Limits_biproduct_1
code: @[inherit_doc biproduct]
notation "⨁ " f:20 => biproduct f
goal: Lean.PrettyPrinter.Unexpander

full_name: CategoryTheory.Limits.biproduct.π
code: /-- The projection onto a summand of a biproduct. -/
abbrev biproduct.π (f : J → C) [HasBiproduct f] (b : J) : ⨁ f ⟶ f b 
goal: ⨁ f ⟶ f b

full_name: CategoryTheory.Limits.biproduct.bicone_π
code: @[simp]
theorem biproduct.bicone_π (f : J → C) [HasBiproduct f] (b : J) :
    (biproduct.bicone f).π b = biproduct.π f b 
goal: (CategoryTheory.Limits.biproduct.bicone f).π b = CategoryTheory.Limits.biproduct.π f b

full_name: CategoryTheory.Limits.biproduct.ι
code: /-- The inclusion into a summand of a biproduct. -/
abbrev biproduct.ι (f : J → C) [HasBiproduct f] (b : J) : f b ⟶ ⨁ f 
goal: f b ⟶ ⨁ f

full_name: CategoryTheory.Limits.biproduct.bicone_ι
code: @[simp]
theorem biproduct.bicone_ι (f : J → C) [HasBiproduct f] (b : J) :
    (biproduct.bicone f).ι b = biproduct.ι f b 
goal: (CategoryTheory.Limits.biproduct.bicone f).ι b = CategoryTheory.Limits.biproduct.ι f b

full_name: CategoryTheory.Limits.biproduct.ι_π
code: /-- Note that as this lemma has an `if` in the statement, we include a `DecidableEq` argument.
This means you may not be able to `simp` using this lemma unless you `open scoped Classical`. -/
@[reassoc]
theorem biproduct.ι_π [DecidableEq J] (f : J → C) [HasBiproduct f] (j j' : J) :
    biproduct.ι f j ≫ biproduct.π f j' = if h : j = j' then eqToHom (congr_arg f h) else 0 
goal: CategoryTheory.Limits.biproduct.ι f j ≫ CategoryTheory.Limits.biproduct.π f j' =
  if h : j = j' then CategoryTheory.eqToHom ⋯ else 0

full_name: CategoryTheory.Limits.biproduct.ι_π_self
code: @[reassoc] -- Porting note: both versions proven by simp
theorem biproduct.ι_π_self (f : J → C) [HasBiproduct f] (j : J) :
    biproduct.ι f j ≫ biproduct.π f j = 𝟙 _ 
goal: CategoryTheory.Limits.biproduct.ι f j ≫ CategoryTheory.Limits.biproduct.π f j = 𝟙 (f j)

full_name: CategoryTheory.Limits.biproduct.ι_π_ne
code: @[reassoc (attr := simp)]
theorem biproduct.ι_π_ne (f : J → C) [HasBiproduct f] {j j' : J} (h : j ≠ j') :
    biproduct.ι f j ≫ biproduct.π f j' = 0 
goal: CategoryTheory.Limits.biproduct.ι f j ≫ CategoryTheory.Limits.biproduct.π f j' = 0

full_name: CategoryTheory.Limits.biproduct.eqToHom_comp_ι
code: @[reassoc (attr := simp, nolint simpNF)]
theorem biproduct.eqToHom_comp_ι (f : J → C) [HasBiproduct f] {j j' : J} (w : j = j') :
    eqToHom (by simp [w]) ≫ biproduct.ι f j' = biproduct.ι f j 
goal: CategoryTheory.eqToHom ⋯ ≫ CategoryTheory.Limits.biproduct.ι f j' = CategoryTheory.Limits.biproduct.ι f j

full_name: CategoryTheory.Limits.biproduct.π_comp_eqToHom
code: @[reassoc (attr := simp, nolint simpNF)]
theorem biproduct.π_comp_eqToHom (f : J → C) [HasBiproduct f] {j j' : J} (w : j = j') :
    biproduct.π f j ≫ eqToHom (by simp [w]) = biproduct.π f j' 
goal: CategoryTheory.Limits.biproduct.π f j ≫ CategoryTheory.eqToHom ⋯ = CategoryTheory.Limits.biproduct.π f j'

full_name: CategoryTheory.Limits.biproduct.lift
code: /-- Given a collection of maps into the summands, we obtain a map into the biproduct. -/
abbrev biproduct.lift {f : J → C} [HasBiproduct f] {P : C} (p : ∀ b, P ⟶ f b) : P ⟶ ⨁ f 
goal: P ⟶ ⨁ f

full_name: CategoryTheory.Limits.biproduct.desc
code: /-- Given a collection of maps out of the summands, we obtain a map out of the biproduct. -/
abbrev biproduct.desc {f : J → C} [HasBiproduct f] {P : C} (p : ∀ b, f b ⟶ P) : ⨁ f ⟶ P 
goal: ⨁ f ⟶ P

full_name: CategoryTheory.Limits.biproduct.lift_π
code: @[reassoc (attr := simp)]
theorem biproduct.lift_π {f : J → C} [HasBiproduct f] {P : C} (p : ∀ b, P ⟶ f b) (j : J) :
    biproduct.lift p ≫ biproduct.π f j = p j 
goal: CategoryTheory.Limits.biproduct.lift p ≫ CategoryTheory.Limits.biproduct.π f j = p j

full_name: CategoryTheory.Limits.biproduct.ι_desc
code: @[reassoc (attr := simp)]
theorem biproduct.ι_desc {f : J → C} [HasBiproduct f] {P : C} (p : ∀ b, f b ⟶ P) (j : J) :
    biproduct.ι f j ≫ biproduct.desc p = p j 
goal: CategoryTheory.Limits.biproduct.ι f j ≫ CategoryTheory.Limits.biproduct.desc p = p j

full_name: CategoryTheory.Limits.biproduct.map
code: /-- Given a collection of maps between corresponding summands of a pair of biproducts
indexed by the same type, we obtain a map between the biproducts. -/
abbrev biproduct.map {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ b, f b ⟶ g b) :
    ⨁ f ⟶ ⨁ g 
goal: ⨁ f ⟶ ⨁ g

full_name: CategoryTheory.Limits.biproduct.map'
code: /-- An alternative to `biproduct.map` constructed via colimits.
This construction only exists in order to show it is equal to `biproduct.map`. -/
abbrev biproduct.map' {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ b, f b ⟶ g b) :
    ⨁ f ⟶ ⨁ g 
goal: ⨁ f ⟶ ⨁ g

full_name: CategoryTheory.Limits.biproduct.hom_ext
code: @[ext 1001]
theorem biproduct.hom_ext {f : J → C} [HasBiproduct f] {Z : C} (g h : Z ⟶ ⨁ f)
    (w : ∀ j, g ≫ biproduct.π f j = h ≫ biproduct.π f j) : g = h 
goal: g = h

full_name: CategoryTheory.Limits.biproduct.hom_ext'
code: @[ext]
theorem biproduct.hom_ext' {f : J → C} [HasBiproduct f] {Z : C} (g h : ⨁ f ⟶ Z)
    (w : ∀ j, biproduct.ι f j ≫ g = biproduct.ι f j ≫ h) : g = h 
goal: g = h

full_name: CategoryTheory.Limits.biproduct.isoProduct
code: /-- The canonical isomorphism between the chosen biproduct and the chosen product. -/
def biproduct.isoProduct (f : J → C) [HasBiproduct f] : ⨁ f ≅ ∏ᶜ f 
goal: ⨁ f ≅ ∏ᶜ f

full_name: CategoryTheory.Limits.biproduct.isoProduct_hom
code: @[simp]
theorem biproduct.isoProduct_hom {f : J → C} [HasBiproduct f] :
    (biproduct.isoProduct f).hom = Pi.lift (biproduct.π f) 
goal: (CategoryTheory.Limits.biproduct.isoProduct f).hom = CategoryTheory.Limits.Pi.lift (CategoryTheory.Limits.biproduct.π f)

full_name: CategoryTheory.Limits.biproduct.isoProduct_inv
code: @[simp]
theorem biproduct.isoProduct_inv {f : J → C} [HasBiproduct f] :
    (biproduct.isoProduct f).inv = biproduct.lift (Pi.π f) 
goal: (CategoryTheory.Limits.biproduct.isoProduct f).inv = CategoryTheory.Limits.biproduct.lift (CategoryTheory.Limits.Pi.π f)

full_name: CategoryTheory.Limits.biproduct.isoCoproduct
code: /-- The canonical isomorphism between the chosen biproduct and the chosen coproduct. -/
def biproduct.isoCoproduct (f : J → C) [HasBiproduct f] : ⨁ f ≅ ∐ f 
goal: ⨁ f ≅ ∐ f

full_name: CategoryTheory.Limits.biproduct.isoCoproduct_inv
code: @[simp]
theorem biproduct.isoCoproduct_inv {f : J → C} [HasBiproduct f] :
    (biproduct.isoCoproduct f).inv = Sigma.desc (biproduct.ι f) 
goal: (CategoryTheory.Limits.biproduct.isoCoproduct f).inv =
  CategoryTheory.Limits.Sigma.desc (CategoryTheory.Limits.biproduct.ι f)

full_name: CategoryTheory.Limits.biproduct.isoCoproduct_hom
code: @[simp]
theorem biproduct.isoCoproduct_hom {f : J → C} [HasBiproduct f] :
    (biproduct.isoCoproduct f).hom = biproduct.desc (Sigma.ι f) 
goal: (CategoryTheory.Limits.biproduct.isoCoproduct f).hom =
  CategoryTheory.Limits.biproduct.desc (CategoryTheory.Limits.Sigma.ι f)

full_name: CategoryTheory.Limits.biproduct.map_eq_map'
code: theorem biproduct.map_eq_map' {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ b, f b ⟶ g b) :
    biproduct.map p = biproduct.map' p 
goal: CategoryTheory.Limits.biproduct.map p = CategoryTheory.Limits.biproduct.map' p

full_name: CategoryTheory.Limits.biproduct.map_π
code: @[reassoc (attr := simp)]
theorem biproduct.map_π {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ j, f j ⟶ g j)
    (j : J) : biproduct.map p ≫ biproduct.π g j = biproduct.π f j ≫ p j 
goal: CategoryTheory.Limits.biproduct.map p ≫ CategoryTheory.Limits.biproduct.π g j =
  CategoryTheory.Limits.biproduct.π f j ≫ p j

full_name: CategoryTheory.Limits.biproduct.ι_map
code: @[reassoc (attr := simp)]
theorem biproduct.ι_map {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ j, f j ⟶ g j)
    (j : J) : biproduct.ι f j ≫ biproduct.map p = p j ≫ biproduct.ι g j 
goal: CategoryTheory.Limits.biproduct.ι f j ≫ CategoryTheory.Limits.biproduct.map p =
  p j ≫ CategoryTheory.Limits.biproduct.ι g j

full_name: CategoryTheory.Limits.biproduct.map_desc
code: @[reassoc (attr := simp)]
theorem biproduct.map_desc {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ j, f j ⟶ g j)
    {P : C} (k : ∀ j, g j ⟶ P) :
    biproduct.map p ≫ biproduct.desc k = biproduct.desc fun j => p j ≫ k j 
goal: CategoryTheory.Limits.biproduct.map p ≫ CategoryTheory.Limits.biproduct.desc k =
  CategoryTheory.Limits.biproduct.desc fun j => p j ≫ k j

full_name: CategoryTheory.Limits.biproduct.lift_map
code: @[reassoc (attr := simp)]
theorem biproduct.lift_map {f g : J → C} [HasBiproduct f] [HasBiproduct g] {P : C}
    (k : ∀ j, P ⟶ f j) (p : ∀ j, f j ⟶ g j) :
    biproduct.lift k ≫ biproduct.map p = biproduct.lift fun j => k j ≫ p j 
goal: CategoryTheory.Limits.biproduct.lift k ≫ CategoryTheory.Limits.biproduct.map p =
  CategoryTheory.Limits.biproduct.lift fun j => k j ≫ p j

full_name: CategoryTheory.Limits.biproduct.mapIso_inv
code: /-- Given a collection of isomorphisms between corresponding summands of a pair of biproducts
indexed by the same type, we obtain an isomorphism between the biproducts. -/
@[simps]
def biproduct.mapIso {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ b, f b ≅ g b) :
    ⨁ f ≅ ⨁ g 
goal: (CategoryTheory.Limits.biproduct.mapIso p).inv = CategoryTheory.Limits.biproduct.map fun b => (p b).inv

full_name: CategoryTheory.Limits.biproduct.mapIso
code: /-- Given a collection of isomorphisms between corresponding summands of a pair of biproducts
indexed by the same type, we obtain an isomorphism between the biproducts. -/
@[simps]
def biproduct.mapIso {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ b, f b ≅ g b) :
    ⨁ f ≅ ⨁ g 
goal: ⨁ f ≅ ⨁ g

full_name: CategoryTheory.Limits.biproduct.mapIso_hom
code: /-- Given a collection of isomorphisms between corresponding summands of a pair of biproducts
indexed by the same type, we obtain an isomorphism between the biproducts. -/
@[simps]
def biproduct.mapIso {f g : J → C} [HasBiproduct f] [HasBiproduct g] (p : ∀ b, f b ≅ g b) :
    ⨁ f ≅ ⨁ g 
goal: (CategoryTheory.Limits.biproduct.mapIso p).hom = CategoryTheory.Limits.biproduct.map fun b => (p b).hom

full_name: CategoryTheory.Limits.biproduct.whiskerEquiv_hom
code: /-- Two biproducts which differ by an equivalence in the indexing type,
and up to isomorphism in the factors, are isomorphic.

Unfortunately there are two natural ways to define each direction of this isomorphism
(because it is true for both products and coproducts separately).
We give the alternative definitions as lemmas below.
-/
@[simps]
def biproduct.whiskerEquiv {f : J → C} {g : K → C} (e : J ≃ K) (w : ∀ j, g (e j) ≅ f j)
    [HasBiproduct f] [HasBiproduct g] : ⨁ f ≅ ⨁ g 
goal: (CategoryTheory.Limits.biproduct.whiskerEquiv e w).hom =
  CategoryTheory.Limits.biproduct.desc fun j => (w j).inv ≫ CategoryTheory.Limits.biproduct.ι g (e j)

full_name: CategoryTheory.Limits.biproduct.whiskerEquiv
code: /-- Two biproducts which differ by an equivalence in the indexing type,
and up to isomorphism in the factors, are isomorphic.

Unfortunately there are two natural ways to define each direction of this isomorphism
(because it is true for both products and coproducts separately).
We give the alternative definitions as lemmas below.
-/
@[simps]
def biproduct.whiskerEquiv {f : J → C} {g : K → C} (e : J ≃ K) (w : ∀ j, g (e j) ≅ f j)
    [HasBiproduct f] [HasBiproduct g] : ⨁ f ≅ ⨁ g 
goal: ⨁ f ≅ ⨁ g

full_name: CategoryTheory.Limits.biproduct.whiskerEquiv_inv
code: /-- Two biproducts which differ by an equivalence in the indexing type,
and up to isomorphism in the factors, are isomorphic.

Unfortunately there are two natural ways to define each direction of this isomorphism
(because it is true for both products and coproducts separately).
We give the alternative definitions as lemmas below.
-/
@[simps]
def biproduct.whiskerEquiv {f : J → C} {g : K → C} (e : J ≃ K) (w : ∀ j, g (e j) ≅ f j)
    [HasBiproduct f] [HasBiproduct g] : ⨁ f ≅ ⨁ g 
goal: (CategoryTheory.Limits.biproduct.whiskerEquiv e w).inv =
  CategoryTheory.Limits.biproduct.desc fun k =>
    CategoryTheory.eqToHom ⋯ ≫ (w (e.symm k)).hom ≫ CategoryTheory.Limits.biproduct.ι f (e.symm k)

full_name: CategoryTheory.Limits.biproduct.whiskerEquiv_hom_eq_lift
code: lemma biproduct.whiskerEquiv_hom_eq_lift {f : J → C} {g : K → C} (e : J ≃ K)
    (w : ∀ j, g (e j) ≅ f j) [HasBiproduct f] [HasBiproduct g] :
    (biproduct.whiskerEquiv e w).hom =
      biproduct.lift fun k => biproduct.π f (e.symm k) ≫ (w _).inv ≫ eqToHom (by simp) 
goal: (CategoryTheory.Limits.biproduct.whiskerEquiv e w).hom =
  CategoryTheory.Limits.biproduct.lift fun k =>
    CategoryTheory.Limits.biproduct.π f (e.symm k) ≫ (w (e.symm k)).inv ≫ CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.Limits.biproduct.whiskerEquiv_inv_eq_lift
code: lemma biproduct.whiskerEquiv_inv_eq_lift {f : J → C} {g : K → C} (e : J ≃ K)
    (w : ∀ j, g (e j) ≅ f j) [HasBiproduct f] [HasBiproduct g] :
    (biproduct.whiskerEquiv e w).inv =
      biproduct.lift fun j => biproduct.π g (e j) ≫ (w j).hom 
goal: (CategoryTheory.Limits.biproduct.whiskerEquiv e w).inv =
  CategoryTheory.Limits.biproduct.lift fun j => CategoryTheory.Limits.biproduct.π g (e j) ≫ (w j).hom

full_name: CategoryTheory.Limits.instHasBiproductSigmaFstSndOfBiproduct
code: instance {ι} (f : ι → Type*) (g : (i : ι) → (f i) → C)
    [∀ i, HasBiproduct (g i)] [HasBiproduct fun i => ⨁ g i] :
    HasBiproduct fun p : Σ i, f i => g p.1 p.2 
goal: CategoryTheory.Limits.HasBiproduct fun p => g p.fst p.snd

full_name: CategoryTheory.Limits.biproductBiproductIso_inv
code: /-- An iterated biproduct is a biproduct over a sigma type. -/
@[simps]
def biproductBiproductIso {ι} (f : ι → Type*) (g : (i : ι) → (f i) → C)
    [∀ i, HasBiproduct (g i)] [HasBiproduct fun i => ⨁ g i] :
    (⨁ fun i => ⨁ g i) ≅ (⨁ fun p : Σ i, f i => g p.1 p.2) 
goal: (CategoryTheory.Limits.biproductBiproductIso f g).inv =
  CategoryTheory.Limits.biproduct.lift fun i =>
    CategoryTheory.Limits.biproduct.lift fun x => CategoryTheory.Limits.biproduct.π (fun p => g p.fst p.snd) ⟨i, x⟩

full_name: CategoryTheory.Limits.biproductBiproductIso
code: /-- An iterated biproduct is a biproduct over a sigma type. -/
@[simps]
def biproductBiproductIso {ι} (f : ι → Type*) (g : (i : ι) → (f i) → C)
    [∀ i, HasBiproduct (g i)] [HasBiproduct fun i => ⨁ g i] :
    (⨁ fun i => ⨁ g i) ≅ (⨁ fun p : Σ i, f i => g p.1 p.2) 
goal: (⨁ fun i => ⨁ g i) ≅ ⨁ fun p => g p.fst p.snd

full_name: CategoryTheory.Limits.biproductBiproductIso_hom
code: /-- An iterated biproduct is a biproduct over a sigma type. -/
@[simps]
def biproductBiproductIso {ι} (f : ι → Type*) (g : (i : ι) → (f i) → C)
    [∀ i, HasBiproduct (g i)] [HasBiproduct fun i => ⨁ g i] :
    (⨁ fun i => ⨁ g i) ≅ (⨁ fun p : Σ i, f i => g p.1 p.2) 
goal: (CategoryTheory.Limits.biproductBiproductIso f g).hom =
  CategoryTheory.Limits.biproduct.lift fun x =>
    match x with
    | ⟨i, x⟩ => CategoryTheory.Limits.biproduct.π (fun i => ⨁ g i) i ≫ CategoryTheory.Limits.biproduct.π (g i) x

full_name: CategoryTheory.Limits.biproduct.fromSubtype
code: /-- The canonical morphism from the biproduct over a restricted index type to the biproduct of
the full index type. -/
def biproduct.fromSubtype : ⨁ Subtype.restrict p f ⟶ ⨁ f 
goal: ⨁ Subtype.restrict p f ⟶ ⨁ f

full_name: CategoryTheory.Limits.biproduct.toSubtype
code: /-- The canonical morphism from a biproduct to the biproduct over a restriction of its index
type. -/
def biproduct.toSubtype : ⨁ f ⟶ ⨁ Subtype.restrict p f 
goal: ⨁ f ⟶ ⨁ Subtype.restrict p f

full_name: CategoryTheory.Limits.biproduct.fromSubtype_π
code: @[reassoc (attr := simp)]
theorem biproduct.fromSubtype_π [DecidablePred p] (j : J) :
    biproduct.fromSubtype f p ≫ biproduct.π f j =
      if h : p j then biproduct.π (Subtype.restrict p f) ⟨j, h⟩ else 0 
goal: CategoryTheory.Limits.biproduct.fromSubtype f p ≫ CategoryTheory.Limits.biproduct.π f j =
  if h : p j then CategoryTheory.Limits.biproduct.π (Subtype.restrict p f) ⟨j, h⟩ else 0

full_name: CategoryTheory.Limits.biproduct.fromSubtype_eq_lift
code: theorem biproduct.fromSubtype_eq_lift [DecidablePred p] :
    biproduct.fromSubtype f p =
      biproduct.lift fun j => if h : p j then biproduct.π (Subtype.restrict p f) ⟨j, h⟩ else 0 
goal: CategoryTheory.Limits.biproduct.fromSubtype f p =
  CategoryTheory.Limits.biproduct.lift fun j =>
    if h : p j then CategoryTheory.Limits.biproduct.π (Subtype.restrict p f) ⟨j, h⟩ else 0

full_name: CategoryTheory.Limits.biproduct.fromSubtype_π_subtype
code: @[reassoc] -- Porting note: both version solved using simp
theorem biproduct.fromSubtype_π_subtype (j : Subtype p) :
    biproduct.fromSubtype f p ≫ biproduct.π f j = biproduct.π (Subtype.restrict p f) j 
goal: CategoryTheory.Limits.biproduct.fromSubtype f p ≫ CategoryTheory.Limits.biproduct.π f ↑j =
  CategoryTheory.Limits.biproduct.π (Subtype.restrict p f) j

full_name: CategoryTheory.Limits.biproduct.toSubtype_π
code: @[reassoc (attr := simp)]
theorem biproduct.toSubtype_π (j : Subtype p) :
    biproduct.toSubtype f p ≫ biproduct.π (Subtype.restrict p f) j = biproduct.π f j 
goal: CategoryTheory.Limits.biproduct.toSubtype f p ≫ CategoryTheory.Limits.biproduct.π (Subtype.restrict p f) j =
  CategoryTheory.Limits.biproduct.π f ↑j

full_name: CategoryTheory.Limits.biproduct.ι_toSubtype
code: @[reassoc (attr := simp)]
theorem biproduct.ι_toSubtype [DecidablePred p] (j : J) :
    biproduct.ι f j ≫ biproduct.toSubtype f p =
      if h : p j then biproduct.ι (Subtype.restrict p f) ⟨j, h⟩ else 0 
goal: CategoryTheory.Limits.biproduct.ι f j ≫ CategoryTheory.Limits.biproduct.toSubtype f p =
  if h : p j then CategoryTheory.Limits.biproduct.ι (Subtype.restrict p f) ⟨j, h⟩ else 0

full_name: CategoryTheory.Limits.biproduct.toSubtype_eq_desc
code: theorem biproduct.toSubtype_eq_desc [DecidablePred p] :
    biproduct.toSubtype f p =
      biproduct.desc fun j => if h : p j then biproduct.ι (Subtype.restrict p f) ⟨j, h⟩ else 0 
goal: CategoryTheory.Limits.biproduct.toSubtype f p =
  CategoryTheory.Limits.biproduct.desc fun j =>
    if h : p j then CategoryTheory.Limits.biproduct.ι (Subtype.restrict p f) ⟨j, h⟩ else 0

full_name: CategoryTheory.Limits.biproduct.ι_toSubtype_subtype
code: @[reassoc] -- Porting note (#10618): simp can prove both versions
theorem biproduct.ι_toSubtype_subtype (j : Subtype p) :
    biproduct.ι f j ≫ biproduct.toSubtype f p = biproduct.ι (Subtype.restrict p f) j 
goal: CategoryTheory.Limits.biproduct.ι f ↑j ≫ CategoryTheory.Limits.biproduct.toSubtype f p =
  CategoryTheory.Limits.biproduct.ι (Subtype.restrict p f) j

full_name: CategoryTheory.Limits.biproduct.ι_fromSubtype
code: @[reassoc (attr := simp)]
theorem biproduct.ι_fromSubtype (j : Subtype p) :
    biproduct.ι (Subtype.restrict p f) j ≫ biproduct.fromSubtype f p = biproduct.ι f j 
goal: CategoryTheory.Limits.biproduct.ι (Subtype.restrict p f) j ≫ CategoryTheory.Limits.biproduct.fromSubtype f p =
  CategoryTheory.Limits.biproduct.ι f ↑j

full_name: CategoryTheory.Limits.biproduct.fromSubtype_toSubtype
code: @[reassoc (attr := simp)]
theorem biproduct.fromSubtype_toSubtype :
    biproduct.fromSubtype f p ≫ biproduct.toSubtype f p = 𝟙 (⨁ Subtype.restrict p f) 
goal: CategoryTheory.Limits.biproduct.fromSubtype f p ≫ CategoryTheory.Limits.biproduct.toSubtype f p =
  𝟙 (⨁ Subtype.restrict p f)

full_name: CategoryTheory.Limits.biproduct.toSubtype_fromSubtype
code: @[reassoc (attr := simp)]
theorem biproduct.toSubtype_fromSubtype [DecidablePred p] :
    biproduct.toSubtype f p ≫ biproduct.fromSubtype f p =
      biproduct.map fun j => if p j then 𝟙 (f j) else 0 
goal: CategoryTheory.Limits.biproduct.toSubtype f p ≫ CategoryTheory.Limits.biproduct.fromSubtype f p =
  CategoryTheory.Limits.biproduct.map fun j => if p j then 𝟙 (f j) else 0

full_name: CategoryTheory.Limits.biproduct.isLimitFromSubtype
code: /-- The kernel of `biproduct.π f i` is the inclusion from the biproduct which omits `i`
from the index set `J` into the biproduct over `J`. -/
def biproduct.isLimitFromSubtype :
    IsLimit (KernelFork.ofι (biproduct.fromSubtype f fun j => j ≠ i) (by simp) :
    KernelFork (biproduct.π f i)) 
goal: CategoryTheory.Limits.IsLimit
  (CategoryTheory.Limits.KernelFork.ofι (CategoryTheory.Limits.biproduct.fromSubtype f fun j => j ≠ i) ⋯)

full_name: CategoryTheory.Limits.instHasKernelπ
code: instance : HasKernel (biproduct.π f i) 
goal: CategoryTheory.Limits.HasKernel (CategoryTheory.Limits.biproduct.π f i)

full_name: CategoryTheory.Limits.kernelBiproductπIso_hom
code: /-- The kernel of `biproduct.π f i` is `⨁ Subtype.restrict {i}ᶜ f`. -/
@[simps!]
def kernelBiproductπIso : kernel (biproduct.π f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f 
goal: (CategoryTheory.Limits.kernelBiproductπIso f i).hom =
  (CategoryTheory.Limits.biproduct.isLimitFromSubtype f i).lift
    (CategoryTheory.Limits.limit.cone (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.π f i) 0))

full_name: CategoryTheory.Limits.kernelBiproductπIso_inv
code: /-- The kernel of `biproduct.π f i` is `⨁ Subtype.restrict {i}ᶜ f`. -/
@[simps!]
def kernelBiproductπIso : kernel (biproduct.π f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f 
goal: (CategoryTheory.Limits.kernelBiproductπIso f i).inv =
  CategoryTheory.Limits.limit.lift (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.π f i) 0)
    (CategoryTheory.Limits.KernelFork.ofι (CategoryTheory.Limits.biproduct.fromSubtype f fun j => ¬j = i) ⋯)

full_name: CategoryTheory.Limits.kernelBiproductπIso
code: /-- The kernel of `biproduct.π f i` is `⨁ Subtype.restrict {i}ᶜ f`. -/
@[simps!]
def kernelBiproductπIso : kernel (biproduct.π f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f 
goal: CategoryTheory.Limits.kernel (CategoryTheory.Limits.biproduct.π f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f

full_name: CategoryTheory.Limits.biproduct.isColimitToSubtype
code: /-- The cokernel of `biproduct.ι f i` is the projection from the biproduct over the index set `J`
onto the biproduct omitting `i`. -/
def biproduct.isColimitToSubtype :
    IsColimit (CokernelCofork.ofπ (biproduct.toSubtype f fun j => j ≠ i) (by simp) :
    CokernelCofork (biproduct.ι f i)) 
goal: CategoryTheory.Limits.IsColimit
  (CategoryTheory.Limits.CokernelCofork.ofπ (CategoryTheory.Limits.biproduct.toSubtype f fun j => j ≠ i) ⋯)

full_name: CategoryTheory.Limits.instHasCokernelι
code: instance : HasCokernel (biproduct.ι f i) 
goal: CategoryTheory.Limits.HasCokernel (CategoryTheory.Limits.biproduct.ι f i)

full_name: CategoryTheory.Limits.cokernelBiproductιIso_inv
code: /-- The cokernel of `biproduct.ι f i` is `⨁ Subtype.restrict {i}ᶜ f`. -/
@[simps!]
def cokernelBiproductιIso : cokernel (biproduct.ι f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f 
goal: (CategoryTheory.Limits.cokernelBiproductιIso f i).inv =
  (CategoryTheory.Limits.biproduct.isColimitToSubtype f i).desc
    (CategoryTheory.Limits.colimit.cocone
      (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.ι f i) 0))

full_name: CategoryTheory.Limits.cokernelBiproductιIso
code: /-- The cokernel of `biproduct.ι f i` is `⨁ Subtype.restrict {i}ᶜ f`. -/
@[simps!]
def cokernelBiproductιIso : cokernel (biproduct.ι f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f 
goal: CategoryTheory.Limits.cokernel (CategoryTheory.Limits.biproduct.ι f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f

full_name: CategoryTheory.Limits.cokernelBiproductιIso_hom
code: /-- The cokernel of `biproduct.ι f i` is `⨁ Subtype.restrict {i}ᶜ f`. -/
@[simps!]
def cokernelBiproductιIso : cokernel (biproduct.ι f i) ≅ ⨁ Subtype.restrict (fun j => j ≠ i) f 
goal: (CategoryTheory.Limits.cokernelBiproductιIso f i).hom =
  CategoryTheory.Limits.colimit.desc (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.ι f i) 0)
    (CategoryTheory.Limits.CokernelCofork.ofπ (CategoryTheory.Limits.biproduct.toSubtype f fun j => ¬j = i) ⋯)

full_name: CategoryTheory.Limits.kernelForkBiproductToSubtype
code: /-- The limit cone exhibiting `⨁ Subtype.restrict pᶜ f` as the kernel of
`biproduct.toSubtype f p` -/
@[simps]
def kernelForkBiproductToSubtype (p : Set K) :
    LimitCone (parallelPair (biproduct.toSubtype f p) 0) 
goal: CategoryTheory.Limits.LimitCone (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.toSubtype f p) 0)

full_name: CategoryTheory.Limits.kernelForkBiproductToSubtype_isLimit
code: /-- The limit cone exhibiting `⨁ Subtype.restrict pᶜ f` as the kernel of
`biproduct.toSubtype f p` -/
@[simps]
def kernelForkBiproductToSubtype (p : Set K) :
    LimitCone (parallelPair (biproduct.toSubtype f p) 0) 
goal: (CategoryTheory.Limits.kernelForkBiproductToSubtype f p).isLimit =
  CategoryTheory.Limits.KernelFork.IsLimit.ofι (CategoryTheory.Limits.biproduct.fromSubtype f pᶜ) ⋯
    (fun {W} g x => g ≫ CategoryTheory.Limits.biproduct.toSubtype f pᶜ) ⋯ ⋯

full_name: CategoryTheory.Limits.kernelForkBiproductToSubtype_cone
code: /-- The limit cone exhibiting `⨁ Subtype.restrict pᶜ f` as the kernel of
`biproduct.toSubtype f p` -/
@[simps]
def kernelForkBiproductToSubtype (p : Set K) :
    LimitCone (parallelPair (biproduct.toSubtype f p) 0) 
goal: (CategoryTheory.Limits.kernelForkBiproductToSubtype f p).cone =
  CategoryTheory.Limits.KernelFork.ofι (CategoryTheory.Limits.biproduct.fromSubtype f pᶜ) ⋯

full_name: CategoryTheory.Limits.instHasKernelToSubtype
code: instance (p : Set K) : HasKernel (biproduct.toSubtype f p) 
goal: CategoryTheory.Limits.HasKernel (CategoryTheory.Limits.biproduct.toSubtype f p)

full_name: CategoryTheory.Limits.kernelBiproductToSubtypeIso_hom
code: /-- The kernel of `biproduct.toSubtype f p` is `⨁ Subtype.restrict pᶜ f`. -/
@[simps!]
def kernelBiproductToSubtypeIso (p : Set K) :
    kernel (biproduct.toSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f 
goal: (CategoryTheory.Limits.kernelBiproductToSubtypeIso f p).hom =
  (CategoryTheory.Limits.KernelFork.IsLimit.ofι (CategoryTheory.Limits.biproduct.fromSubtype f pᶜ) ⋯
        (fun {W} g x => g ≫ CategoryTheory.Limits.biproduct.toSubtype f pᶜ) ⋯ ⋯).lift
    (CategoryTheory.Limits.limit.cone
      (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.toSubtype f p) 0))

full_name: CategoryTheory.Limits.kernelBiproductToSubtypeIso_inv
code: /-- The kernel of `biproduct.toSubtype f p` is `⨁ Subtype.restrict pᶜ f`. -/
@[simps!]
def kernelBiproductToSubtypeIso (p : Set K) :
    kernel (biproduct.toSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f 
goal: (CategoryTheory.Limits.kernelBiproductToSubtypeIso f p).inv =
  CategoryTheory.Limits.limit.lift
    (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.toSubtype f p) 0)
    (CategoryTheory.Limits.KernelFork.ofι (CategoryTheory.Limits.biproduct.fromSubtype f pᶜ) ⋯)

full_name: CategoryTheory.Limits.kernelBiproductToSubtypeIso
code: /-- The kernel of `biproduct.toSubtype f p` is `⨁ Subtype.restrict pᶜ f`. -/
@[simps!]
def kernelBiproductToSubtypeIso (p : Set K) :
    kernel (biproduct.toSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f 
goal: CategoryTheory.Limits.kernel (CategoryTheory.Limits.biproduct.toSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f

full_name: CategoryTheory.Limits.cokernelCoforkBiproductFromSubtype
code: /-- The colimit cocone exhibiting `⨁ Subtype.restrict pᶜ f` as the cokernel of
`biproduct.fromSubtype f p` -/
@[simps]
def cokernelCoforkBiproductFromSubtype (p : Set K) :
    ColimitCocone (parallelPair (biproduct.fromSubtype f p) 0) 
goal: CategoryTheory.Limits.ColimitCocone
  (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.fromSubtype f p) 0)

full_name: CategoryTheory.Limits.cokernelCoforkBiproductFromSubtype_isColimit
code: /-- The colimit cocone exhibiting `⨁ Subtype.restrict pᶜ f` as the cokernel of
`biproduct.fromSubtype f p` -/
@[simps]
def cokernelCoforkBiproductFromSubtype (p : Set K) :
    ColimitCocone (parallelPair (biproduct.fromSubtype f p) 0) 
goal: (CategoryTheory.Limits.cokernelCoforkBiproductFromSubtype f p).isColimit =
  CategoryTheory.Limits.CokernelCofork.IsColimit.ofπ (CategoryTheory.Limits.biproduct.toSubtype f pᶜ) ⋯
    (fun {W} g x => CategoryTheory.Limits.biproduct.fromSubtype f pᶜ ≫ g) ⋯ ⋯

full_name: CategoryTheory.Limits.cokernelCoforkBiproductFromSubtype_cocone
code: /-- The colimit cocone exhibiting `⨁ Subtype.restrict pᶜ f` as the cokernel of
`biproduct.fromSubtype f p` -/
@[simps]
def cokernelCoforkBiproductFromSubtype (p : Set K) :
    ColimitCocone (parallelPair (biproduct.fromSubtype f p) 0) 
goal: (CategoryTheory.Limits.cokernelCoforkBiproductFromSubtype f p).cocone =
  CategoryTheory.Limits.CokernelCofork.ofπ (CategoryTheory.Limits.biproduct.toSubtype f pᶜ) ⋯

full_name: CategoryTheory.Limits.instHasCokernelFromSubtype
code: instance (p : Set K) : HasCokernel (biproduct.fromSubtype f p) 
goal: CategoryTheory.Limits.HasCokernel (CategoryTheory.Limits.biproduct.fromSubtype f p)

full_name: CategoryTheory.Limits.cokernelBiproductFromSubtypeIso_inv
code: /-- The cokernel of `biproduct.fromSubtype f p` is `⨁ Subtype.restrict pᶜ f`. -/
@[simps!]
def cokernelBiproductFromSubtypeIso (p : Set K) :
    cokernel (biproduct.fromSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f 
goal: (CategoryTheory.Limits.cokernelBiproductFromSubtypeIso f p).inv =
  (CategoryTheory.Limits.CokernelCofork.IsColimit.ofπ (CategoryTheory.Limits.biproduct.toSubtype f pᶜ) ⋯
        (fun {W} g x => CategoryTheory.Limits.biproduct.fromSubtype f pᶜ ≫ g) ⋯ ⋯).desc
    (CategoryTheory.Limits.colimit.cocone
      (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.fromSubtype f p) 0))

full_name: CategoryTheory.Limits.cokernelBiproductFromSubtypeIso_hom
code: /-- The cokernel of `biproduct.fromSubtype f p` is `⨁ Subtype.restrict pᶜ f`. -/
@[simps!]
def cokernelBiproductFromSubtypeIso (p : Set K) :
    cokernel (biproduct.fromSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f 
goal: (CategoryTheory.Limits.cokernelBiproductFromSubtypeIso f p).hom =
  CategoryTheory.Limits.colimit.desc
    (CategoryTheory.Limits.parallelPair (CategoryTheory.Limits.biproduct.fromSubtype f p) 0)
    (CategoryTheory.Limits.CokernelCofork.ofπ (CategoryTheory.Limits.biproduct.toSubtype f pᶜ) ⋯)

full_name: CategoryTheory.Limits.cokernelBiproductFromSubtypeIso
code: /-- The cokernel of `biproduct.fromSubtype f p` is `⨁ Subtype.restrict pᶜ f`. -/
@[simps!]
def cokernelBiproductFromSubtypeIso (p : Set K) :
    cokernel (biproduct.fromSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f 
goal: CategoryTheory.Limits.cokernel (CategoryTheory.Limits.biproduct.fromSubtype f p) ≅ ⨁ Subtype.restrict pᶜ f

full_name: CategoryTheory.Limits.biproduct.matrix
code: /-- Convert a (dependently typed) matrix to a morphism of biproducts.
-/
def biproduct.matrix (m : ∀ j k, f j ⟶ g k) : ⨁ f ⟶ ⨁ g 
goal: ⨁ f ⟶ ⨁ g

full_name: CategoryTheory.Limits.biproduct.matrix_π
code: @[reassoc (attr := simp)]
theorem biproduct.matrix_π (m : ∀ j k, f j ⟶ g k) (k : K) :
    biproduct.matrix m ≫ biproduct.π g k = biproduct.desc fun j => m j k 
goal: CategoryTheory.Limits.biproduct.matrix m ≫ CategoryTheory.Limits.biproduct.π g k =
  CategoryTheory.Limits.biproduct.desc fun j => m j k

full_name: CategoryTheory.Limits.biproduct.ι_matrix
code: @[reassoc (attr := simp)]
theorem biproduct.ι_matrix (m : ∀ j k, f j ⟶ g k) (j : J) :
    biproduct.ι f j ≫ biproduct.matrix m = biproduct.lift fun k => m j k 
goal: CategoryTheory.Limits.biproduct.ι f j ≫ CategoryTheory.Limits.biproduct.matrix m =
  CategoryTheory.Limits.biproduct.lift fun k => m j k

full_name: CategoryTheory.Limits.biproduct.components
code: /-- Extract the matrix components from a morphism of biproducts.
-/
def biproduct.components (m : ⨁ f ⟶ ⨁ g) (j : J) (k : K) : f j ⟶ g k 
goal: f j ⟶ g k

full_name: CategoryTheory.Limits.biproduct.matrix_components
code: @[simp]
theorem biproduct.matrix_components (m : ∀ j k, f j ⟶ g k) (j : J) (k : K) :
    biproduct.components (biproduct.matrix m) j k = m j k 
goal: CategoryTheory.Limits.biproduct.components (CategoryTheory.Limits.biproduct.matrix m) j k = m j k

full_name: CategoryTheory.Limits.biproduct.components_matrix
code: @[simp]
theorem biproduct.components_matrix (m : ⨁ f ⟶ ⨁ g) :
    (biproduct.matrix fun j k => biproduct.components m j k) = m 
goal: (CategoryTheory.Limits.biproduct.matrix fun j k => CategoryTheory.Limits.biproduct.components m j k) = m

full_name: CategoryTheory.Limits.biproduct.matrixEquiv_symm_apply
code: /-- Morphisms between direct sums are matrices. -/
@[simps]
def biproduct.matrixEquiv : (⨁ f ⟶ ⨁ g) ≃ ∀ j k, f j ⟶ g k 
goal: CategoryTheory.Limits.biproduct.matrixEquiv.symm m = CategoryTheory.Limits.biproduct.matrix m

full_name: CategoryTheory.Limits.biproduct.matrixEquiv
code: /-- Morphisms between direct sums are matrices. -/
@[simps]
def biproduct.matrixEquiv : (⨁ f ⟶ ⨁ g) ≃ ∀ j k, f j ⟶ g k 
goal: (⨁ f ⟶ ⨁ g) ≃ ((j : J) → (k : K) → f j ⟶ g k)

full_name: CategoryTheory.Limits.biproduct.matrixEquiv_apply
code: /-- Morphisms between direct sums are matrices. -/
@[simps]
def biproduct.matrixEquiv : (⨁ f ⟶ ⨁ g) ≃ ∀ j k, f j ⟶ g k 
goal: CategoryTheory.Limits.biproduct.matrixEquiv m j k = CategoryTheory.Limits.biproduct.components m j k

full_name: CategoryTheory.Limits.biproduct.ι_mono
code: instance biproduct.ι_mono (f : J → C) [HasBiproduct f] (b : J) : IsSplitMono (biproduct.ι f b) 
goal: CategoryTheory.IsSplitMono (CategoryTheory.Limits.biproduct.ι f b)

full_name: CategoryTheory.Limits.biproduct.π_epi
code: instance biproduct.π_epi (f : J → C) [HasBiproduct f] (b : J) : IsSplitEpi (biproduct.π f b) 
goal: CategoryTheory.IsSplitEpi (CategoryTheory.Limits.biproduct.π f b)

full_name: CategoryTheory.Limits.biproduct.conePointUniqueUpToIso_hom
code: /-- Auxiliary lemma for `biproduct.uniqueUpToIso`. -/
theorem biproduct.conePointUniqueUpToIso_hom (f : J → C) [HasBiproduct f] {b : Bicone f}
    (hb : b.IsBilimit) :
    (hb.isLimit.conePointUniqueUpToIso (biproduct.isLimit _)).hom = biproduct.lift b.π 
goal: (hb.isLimit.conePointUniqueUpToIso (CategoryTheory.Limits.biproduct.isLimit f)).hom =
  CategoryTheory.Limits.biproduct.lift b.π

full_name: CategoryTheory.Limits.biproduct.conePointUniqueUpToIso_inv
code: /-- Auxiliary lemma for `biproduct.uniqueUpToIso`. -/
theorem biproduct.conePointUniqueUpToIso_inv (f : J → C) [HasBiproduct f] {b : Bicone f}
    (hb : b.IsBilimit) :
    (hb.isLimit.conePointUniqueUpToIso (biproduct.isLimit _)).inv = biproduct.desc b.ι 
goal: (hb.isLimit.conePointUniqueUpToIso (CategoryTheory.Limits.biproduct.isLimit f)).inv =
  CategoryTheory.Limits.biproduct.desc b.ι

full_name: CategoryTheory.Limits.biproduct.uniqueUpToIso_hom
code: /-- Biproducts are unique up to isomorphism. This already follows because bilimits are limits,
    but in the case of biproducts we can give an isomorphism with particularly nice definitional
    properties, namely that `biproduct.lift b.π` and `biproduct.desc b.ι` are inverses of each
    other. -/
@[simps]
def biproduct.uniqueUpToIso (f : J → C) [HasBiproduct f] {b : Bicone f} (hb : b.IsBilimit) :
    b.pt ≅ ⨁ f 
goal: (CategoryTheory.Limits.biproduct.uniqueUpToIso f hb).hom = CategoryTheory.Limits.biproduct.lift b.π

full_name: CategoryTheory.Limits.biproduct.uniqueUpToIso_inv
code: /-- Biproducts are unique up to isomorphism. This already follows because bilimits are limits,
    but in the case of biproducts we can give an isomorphism with particularly nice definitional
    properties, namely that `biproduct.lift b.π` and `biproduct.desc b.ι` are inverses of each
    other. -/
@[simps]
def biproduct.uniqueUpToIso (f : J → C) [HasBiproduct f] {b : Bicone f} (hb : b.IsBilimit) :
    b.pt ≅ ⨁ f 
goal: (CategoryTheory.Limits.biproduct.uniqueUpToIso f hb).inv = CategoryTheory.Limits.biproduct.desc b.ι

full_name: CategoryTheory.Limits.biproduct.uniqueUpToIso
code: /-- Biproducts are unique up to isomorphism. This already follows because bilimits are limits,
    but in the case of biproducts we can give an isomorphism with particularly nice definitional
    properties, namely that `biproduct.lift b.π` and `biproduct.desc b.ι` are inverses of each
    other. -/
@[simps]
def biproduct.uniqueUpToIso (f : J → C) [HasBiproduct f] {b : Bicone f} (hb : b.IsBilimit) :
    b.pt ≅ ⨁ f 
goal: b.pt ≅ ⨁ f

full_name: CategoryTheory.Limits.hasZeroObject_of_hasFiniteBiproducts
code: /-- A category with finite biproducts has a zero object. -/
instance (priority := 100) hasZeroObject_of_hasFiniteBiproducts [HasFiniteBiproducts C] :
    HasZeroObject C 
goal: CategoryTheory.Limits.HasZeroObject C

full_name: CategoryTheory.Limits.limitBiconeOfUnique
code: /-- The limit bicone for the biproduct over an index type with exactly one term. -/
@[simps]
def limitBiconeOfUnique : LimitBicone f 
goal: CategoryTheory.Limits.LimitBicone f

full_name: CategoryTheory.Limits.limitBiconeOfUnique_bicone_π
code: /-- The limit bicone for the biproduct over an index type with exactly one term. -/
@[simps]
def limitBiconeOfUnique : LimitBicone f 
goal: (CategoryTheory.Limits.limitBiconeOfUnique f).bicone.π j = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.Limits.limitBiconeOfUnique_bicone_pt
code: /-- The limit bicone for the biproduct over an index type with exactly one term. -/
@[simps]
def limitBiconeOfUnique : LimitBicone f 
goal: (CategoryTheory.Limits.limitBiconeOfUnique f).bicone.pt = f default

full_name: CategoryTheory.Limits.limitBiconeOfUnique_isBilimit_isLimit
code: /-- The limit bicone for the biproduct over an index type with exactly one term. -/
@[simps]
def limitBiconeOfUnique : LimitBicone f 
goal: (CategoryTheory.Limits.limitBiconeOfUnique f).isBilimit.isLimit = (CategoryTheory.Limits.limitConeOfUnique f).isLimit

full_name: CategoryTheory.Limits.limitBiconeOfUnique_isBilimit_isColimit
code: /-- The limit bicone for the biproduct over an index type with exactly one term. -/
@[simps]
def limitBiconeOfUnique : LimitBicone f 
goal: (CategoryTheory.Limits.limitBiconeOfUnique f).isBilimit.isColimit =
  (CategoryTheory.Limits.colimitCoconeOfUnique f).isColimit

full_name: CategoryTheory.Limits.limitBiconeOfUnique_bicone_ι
code: /-- The limit bicone for the biproduct over an index type with exactly one term. -/
@[simps]
def limitBiconeOfUnique : LimitBicone f 
goal: (CategoryTheory.Limits.limitBiconeOfUnique f).bicone.ι j = CategoryTheory.eqToHom ⋯

full_name: CategoryTheory.Limits.hasBiproduct_unique
code: instance (priority := 100) hasBiproduct_unique : HasBiproduct f 
goal: CategoryTheory.Limits.HasBiproduct f

full_name: CategoryTheory.Limits.biproductUniqueIso
code: /-- A biproduct over an index type with exactly one term is just the object over that term. -/
@[simps!]
def biproductUniqueIso : ⨁ f ≅ f default 
goal: ⨁ f ≅ f default

full_name: CategoryTheory.Limits.biproductUniqueIso_hom
code: /-- A biproduct over an index type with exactly one term is just the object over that term. -/
@[simps!]
def biproductUniqueIso : ⨁ f ≅ f default 
goal: (CategoryTheory.Limits.biproductUniqueIso f).hom =
  CategoryTheory.Limits.biproduct.desc (CategoryTheory.Limits.limitBiconeOfUnique f).bicone.ι

full_name: CategoryTheory.Limits.biproductUniqueIso_inv
code: /-- A biproduct over an index type with exactly one term is just the object over that term. -/
@[simps!]
def biproductUniqueIso : ⨁ f ≅ f default 
goal: (CategoryTheory.Limits.biproductUniqueIso f).inv =
  CategoryTheory.Limits.biproduct.lift (CategoryTheory.Limits.limitBiconeOfUnique f).bicone.π

full_name: CategoryTheory.Limits.BinaryBicone.inr_snd
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: self.inr ≫ self.snd = 𝟙 Q

full_name: CategoryTheory.Limits.BinaryBicone.inr
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: Q ⟶ self.pt

full_name: CategoryTheory.Limits.BinaryBicone.inr_fst
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: self.inr ≫ self.fst = 0

full_name: CategoryTheory.Limits.BinaryBicone.inl_fst
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: self.inl ≫ self.fst = 𝟙 P

full_name: CategoryTheory.Limits.BinaryBicone
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: Type (max u v)

full_name: CategoryTheory.Limits.BinaryBicone.inl
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: P ⟶ self.pt

full_name: CategoryTheory.Limits.BinaryBicone.inl_snd
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: self.inl ≫ self.snd = 0

full_name: CategoryTheory.Limits.BinaryBicone.fst
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: self.pt ⟶ P

full_name: CategoryTheory.Limits.BinaryBicone.pt
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: C

full_name: CategoryTheory.Limits.BinaryBicone.snd
code: /-- A binary bicone for a pair of objects `P Q : C` consists of the cone point `X`,
maps from `X` to both `P` and `Q`, and maps from both `P` and `Q` to `X`,
so that `inl ≫ fst = 𝟙 P`, `inl ≫ snd = 0`, `inr ≫ fst = 0`, and `inr ≫ snd = 𝟙 Q`
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone (P Q : C) where
  pt : C
  fst : pt ⟶ P
  snd : pt ⟶ Q
  inl : P ⟶ pt
  inr : Q ⟶ pt
  inl_fst : inl ≫ fst = 𝟙 P := by aesop
  inl_snd : inl ≫ snd = 0 := by aesop
  inr_fst : inr ≫ fst = 0 := by aesop
  inr_snd : inr ≫ snd = 𝟙 Q := by aesop
goal: self.pt ⟶ Q

full_name: CategoryTheory.Limits.BinaryBiconeMorphism.hom
code: /-- A binary bicone morphism between two binary bicones for the same diagram is a morphism of the
binary bicone points which commutes with the cone and cocone legs. -/
structure BinaryBiconeMorphism {P Q : C} (A B : BinaryBicone P Q) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wfst : hom ≫ B.fst = A.fst := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wsnd : hom ≫ B.snd = A.snd := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winl : A.inl ≫ hom = B.inl := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winr : A.inr ≫ hom = B.inr := by aesop_cat
goal: A.pt ⟶ B.pt

full_name: CategoryTheory.Limits.BinaryBiconeMorphism.wfst
code: /-- A binary bicone morphism between two binary bicones for the same diagram is a morphism of the
binary bicone points which commutes with the cone and cocone legs. -/
structure BinaryBiconeMorphism {P Q : C} (A B : BinaryBicone P Q) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wfst : hom ≫ B.fst = A.fst := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wsnd : hom ≫ B.snd = A.snd := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winl : A.inl ≫ hom = B.inl := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winr : A.inr ≫ hom = B.inr := by aesop_cat
goal: self.hom ≫ B.fst = A.fst

full_name: CategoryTheory.Limits.BinaryBiconeMorphism.wsnd
code: /-- A binary bicone morphism between two binary bicones for the same diagram is a morphism of the
binary bicone points which commutes with the cone and cocone legs. -/
structure BinaryBiconeMorphism {P Q : C} (A B : BinaryBicone P Q) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wfst : hom ≫ B.fst = A.fst := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wsnd : hom ≫ B.snd = A.snd := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winl : A.inl ≫ hom = B.inl := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winr : A.inr ≫ hom = B.inr := by aesop_cat
goal: self.hom ≫ B.snd = A.snd

full_name: CategoryTheory.Limits.BinaryBiconeMorphism.winr
code: /-- A binary bicone morphism between two binary bicones for the same diagram is a morphism of the
binary bicone points which commutes with the cone and cocone legs. -/
structure BinaryBiconeMorphism {P Q : C} (A B : BinaryBicone P Q) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wfst : hom ≫ B.fst = A.fst := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wsnd : hom ≫ B.snd = A.snd := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winl : A.inl ≫ hom = B.inl := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winr : A.inr ≫ hom = B.inr := by aesop_cat
goal: A.inr ≫ self.hom = B.inr

full_name: CategoryTheory.Limits.BinaryBiconeMorphism.winl
code: /-- A binary bicone morphism between two binary bicones for the same diagram is a morphism of the
binary bicone points which commutes with the cone and cocone legs. -/
structure BinaryBiconeMorphism {P Q : C} (A B : BinaryBicone P Q) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wfst : hom ≫ B.fst = A.fst := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wsnd : hom ≫ B.snd = A.snd := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winl : A.inl ≫ hom = B.inl := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winr : A.inr ≫ hom = B.inr := by aesop_cat
goal: A.inl ≫ self.hom = B.inl

full_name: CategoryTheory.Limits.BinaryBiconeMorphism
code: /-- A binary bicone morphism between two binary bicones for the same diagram is a morphism of the
binary bicone points which commutes with the cone and cocone legs. -/
structure BinaryBiconeMorphism {P Q : C} (A B : BinaryBicone P Q) where
  /-- A morphism between the two vertex objects of the bicones -/
  hom : A.pt ⟶ B.pt
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wfst : hom ≫ B.fst = A.fst := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  wsnd : hom ≫ B.snd = A.snd := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winl : A.inl ≫ hom = B.inl := by aesop_cat
  /-- The triangle consisting of the two natural transformations and `hom` commutes -/
  winr : A.inr ≫ hom = B.inr := by aesop_cat
goal: Type v

full_name: CategoryTheory.Limits.BinaryBicone.category_comp_hom
code: /-- The category of binary bicones on a given diagram. -/
@[simps]
instance BinaryBicone.category {P Q : C} : Category (BinaryBicone P Q) 
goal: ∀ {X Y Z : CategoryTheory.Limits.BinaryBicone P Q} (f : X ⟶ Y) (g : Y ⟶ Z), (f ≫ g).hom = f.hom ≫ g.hom

full_name: CategoryTheory.Limits.BinaryBicone.category_id_hom
code: /-- The category of binary bicones on a given diagram. -/
@[simps]
instance BinaryBicone.category {P Q : C} : Category (BinaryBicone P Q) 
goal: (𝟙 B).hom = 𝟙 B.pt

full_name: CategoryTheory.Limits.BinaryBicone.category
code: /-- The category of binary bicones on a given diagram. -/
@[simps]
instance BinaryBicone.category {P Q : C} : Category (BinaryBicone P Q) 
goal: CategoryTheory.Category.{v, max u v} (CategoryTheory.Limits.BinaryBicone P Q)

full_name: CategoryTheory.Limits.BinaryBiconeMorphism.ext
code: @[ext]
theorem BinaryBiconeMorphism.ext {P Q : C} {c c' : BinaryBicone P Q}
    (f g : c ⟶ c') (w : f.hom = g.hom) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.BinaryBicones.ext
code: /-- To give an isomorphism between cocones, it suffices to give an
  isomorphism between their vertices which commutes with the cocone
  maps. -/
-- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule
@[aesop apply safe (rule_sets := [CategoryTheory]), simps]
def ext {P Q : C} {c c' : BinaryBicone P Q} (φ : c.pt ≅ c'.pt)
    (winl : c.inl ≫ φ.hom = c'.inl := by aesop_cat)
    (winr : c.inr ≫ φ.hom = c'.inr := by aesop_cat)
    (wfst : φ.hom ≫ c'.fst = c.fst := by aesop_cat)
    (wsnd : φ.hom ≫ c'.snd = c.snd := by aesop_cat) : c ≅ c' 
goal: c ≅ c'

full_name: CategoryTheory.Limits.BinaryBicones.ext_hom_hom
code: /-- To give an isomorphism between cocones, it suffices to give an
  isomorphism between their vertices which commutes with the cocone
  maps. -/
-- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule
@[aesop apply safe (rule_sets := [CategoryTheory]), simps]
def ext {P Q : C} {c c' : BinaryBicone P Q} (φ : c.pt ≅ c'.pt)
    (winl : c.inl ≫ φ.hom = c'.inl := by aesop_cat)
    (winr : c.inr ≫ φ.hom = c'.inr := by aesop_cat)
    (wfst : φ.hom ≫ c'.fst = c.fst := by aesop_cat)
    (wsnd : φ.hom ≫ c'.snd = c.snd := by aesop_cat) : c ≅ c' 
goal: (CategoryTheory.Limits.BinaryBicones.ext φ winl winr wfst wsnd).hom.hom = φ.hom

full_name: CategoryTheory.Limits.BinaryBicones.ext_inv_hom
code: /-- To give an isomorphism between cocones, it suffices to give an
  isomorphism between their vertices which commutes with the cocone
  maps. -/
-- Porting note: `@[ext]` used to accept lemmas like this. Now we add an aesop rule
@[aesop apply safe (rule_sets := [CategoryTheory]), simps]
def ext {P Q : C} {c c' : BinaryBicone P Q} (φ : c.pt ≅ c'.pt)
    (winl : c.inl ≫ φ.hom = c'.inl := by aesop_cat)
    (winr : c.inr ≫ φ.hom = c'.inr := by aesop_cat)
    (wfst : φ.hom ≫ c'.fst = c.fst := by aesop_cat)
    (wsnd : φ.hom ≫ c'.snd = c.snd := by aesop_cat) : c ≅ c' 
goal: (CategoryTheory.Limits.BinaryBicones.ext φ winl winr wfst wsnd).inv.hom = φ.inv

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_obj_fst
code: /-- A functor `F : C ⥤ D` sends binary bicones for `P` and `Q`
to binary bicones for `G.obj P` and `G.obj Q` functorially. -/
@[simps]
def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) 
goal: ((CategoryTheory.Limits.BinaryBicones.functoriality P Q F).obj A).fst = F.map A.fst

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_obj_snd
code: /-- A functor `F : C ⥤ D` sends binary bicones for `P` and `Q`
to binary bicones for `G.obj P` and `G.obj Q` functorially. -/
@[simps]
def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) 
goal: ((CategoryTheory.Limits.BinaryBicones.functoriality P Q F).obj A).snd = F.map A.snd

full_name: CategoryTheory.Limits.BinaryBicones.functoriality
code: /-- A functor `F : C ⥤ D` sends binary bicones for `P` and `Q`
to binary bicones for `G.obj P` and `G.obj Q` functorially. -/
@[simps]
def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) 
goal: CategoryTheory.Limits.BinaryBicone P Q ⥤ CategoryTheory.Limits.BinaryBicone (F.obj P) (F.obj Q)

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_map_hom
code: /-- A functor `F : C ⥤ D` sends binary bicones for `P` and `Q`
to binary bicones for `G.obj P` and `G.obj Q` functorially. -/
@[simps]
def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) 
goal: ∀ {X Y : CategoryTheory.Limits.BinaryBicone P Q} (f : X ⟶ Y),
  ((CategoryTheory.Limits.BinaryBicones.functoriality P Q F).map f).hom = F.map f.hom

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_obj_inr
code: /-- A functor `F : C ⥤ D` sends binary bicones for `P` and `Q`
to binary bicones for `G.obj P` and `G.obj Q` functorially. -/
@[simps]
def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) 
goal: ((CategoryTheory.Limits.BinaryBicones.functoriality P Q F).obj A).inr = F.map A.inr

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_obj_inl
code: /-- A functor `F : C ⥤ D` sends binary bicones for `P` and `Q`
to binary bicones for `G.obj P` and `G.obj Q` functorially. -/
@[simps]
def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) 
goal: ((CategoryTheory.Limits.BinaryBicones.functoriality P Q F).obj A).inl = F.map A.inl

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_obj_pt
code: /-- A functor `F : C ⥤ D` sends binary bicones for `P` and `Q`
to binary bicones for `G.obj P` and `G.obj Q` functorially. -/
@[simps]
def functoriality : BinaryBicone P Q ⥤ BinaryBicone (F.obj P) (F.obj Q) 
goal: ((CategoryTheory.Limits.BinaryBicones.functoriality P Q F).obj A).pt = F.obj A.pt

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_full
code: instance functoriality_full [F.Full] [F.Faithful] : (functoriality P Q F).Full 
goal: (CategoryTheory.Limits.BinaryBicones.functoriality P Q F).Full

full_name: CategoryTheory.Limits.BinaryBicones.functoriality_faithful
code: instance functoriality_faithful [F.Faithful] : (functoriality P Q F).Faithful 
goal: (CategoryTheory.Limits.BinaryBicones.functoriality P Q F).Faithful

full_name: CategoryTheory.Limits.BinaryBicone.toCone
code: /-- Extract the cone from a binary bicone. -/
def toCone (c : BinaryBicone P Q) : Cone (pair P Q) 
goal: CategoryTheory.Limits.Cone (CategoryTheory.Limits.pair P Q)

full_name: CategoryTheory.Limits.BinaryBicone.toCone_pt
code: @[simp]
theorem toCone_pt (c : BinaryBicone P Q) : c.toCone.pt = c.pt 
goal: c.toCone.pt = c.pt

full_name: CategoryTheory.Limits.BinaryBicone.toCone_π_app_left
code: @[simp]
theorem toCone_π_app_left (c : BinaryBicone P Q) : c.toCone.π.app ⟨WalkingPair.left⟩ = c.fst 
goal: c.toCone.π.app { as := CategoryTheory.Limits.WalkingPair.left } = c.fst

full_name: CategoryTheory.Limits.BinaryBicone.toCone_π_app_right
code: @[simp]
theorem toCone_π_app_right (c : BinaryBicone P Q) : c.toCone.π.app ⟨WalkingPair.right⟩ = c.snd 
goal: c.toCone.π.app { as := CategoryTheory.Limits.WalkingPair.right } = c.snd

full_name: CategoryTheory.Limits.BinaryBicone.binary_fan_fst_toCone
code: @[simp]
theorem binary_fan_fst_toCone (c : BinaryBicone P Q) : BinaryFan.fst c.toCone = c.fst 
goal: CategoryTheory.Limits.BinaryFan.fst c.toCone = c.fst

full_name: CategoryTheory.Limits.BinaryBicone.binary_fan_snd_toCone
code: @[simp]
theorem binary_fan_snd_toCone (c : BinaryBicone P Q) : BinaryFan.snd c.toCone = c.snd 
goal: CategoryTheory.Limits.BinaryFan.snd c.toCone = c.snd

full_name: CategoryTheory.Limits.BinaryBicone.toCocone
code: /-- Extract the cocone from a binary bicone. -/
def toCocone (c : BinaryBicone P Q) : Cocone (pair P Q) 
goal: CategoryTheory.Limits.Cocone (CategoryTheory.Limits.pair P Q)

full_name: CategoryTheory.Limits.BinaryBicone.toCocone_pt
code: @[simp]
theorem toCocone_pt (c : BinaryBicone P Q) : c.toCocone.pt = c.pt 
goal: c.toCocone.pt = c.pt

full_name: CategoryTheory.Limits.BinaryBicone.toCocone_ι_app_left
code: @[simp]
theorem toCocone_ι_app_left (c : BinaryBicone P Q) : c.toCocone.ι.app ⟨WalkingPair.left⟩ = c.inl 
goal: c.toCocone.ι.app { as := CategoryTheory.Limits.WalkingPair.left } = c.inl

full_name: CategoryTheory.Limits.BinaryBicone.toCocone_ι_app_right
code: @[simp]
theorem toCocone_ι_app_right (c : BinaryBicone P Q) :
    c.toCocone.ι.app ⟨WalkingPair.right⟩ = c.inr 
goal: c.toCocone.ι.app { as := CategoryTheory.Limits.WalkingPair.right } = c.inr

full_name: CategoryTheory.Limits.BinaryBicone.binary_cofan_inl_toCocone
code: @[simp]
theorem binary_cofan_inl_toCocone (c : BinaryBicone P Q) : BinaryCofan.inl c.toCocone = c.inl 
goal: CategoryTheory.Limits.BinaryCofan.inl c.toCocone = c.inl

full_name: CategoryTheory.Limits.BinaryBicone.binary_cofan_inr_toCocone
code: @[simp]
theorem binary_cofan_inr_toCocone (c : BinaryBicone P Q) : BinaryCofan.inr c.toCocone = c.inr 
goal: CategoryTheory.Limits.BinaryCofan.inr c.toCocone = c.inr

full_name: CategoryTheory.Limits.BinaryBicone.instIsSplitMonoInl
code: instance (c : BinaryBicone P Q) : IsSplitMono c.inl 
goal: CategoryTheory.IsSplitMono c.inl

full_name: CategoryTheory.Limits.BinaryBicone.instIsSplitMonoInr
code: instance (c : BinaryBicone P Q) : IsSplitMono c.inr 
goal: CategoryTheory.IsSplitMono c.inr

full_name: CategoryTheory.Limits.BinaryBicone.instIsSplitEpiFst
code: instance (c : BinaryBicone P Q) : IsSplitEpi c.fst 
goal: CategoryTheory.IsSplitEpi c.fst

full_name: CategoryTheory.Limits.BinaryBicone.instIsSplitEpiSnd
code: instance (c : BinaryBicone P Q) : IsSplitEpi c.snd 
goal: CategoryTheory.IsSplitEpi c.snd

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeFunctor_map_hom
code: /-- Convert a `BinaryBicone` into a `Bicone` over a pair. -/
@[simps]
def toBiconeFunctor {X Y : C} : BinaryBicone X Y ⥤ Bicone (pairFunction X Y) 
goal: ∀ {X_1 Y_1 : CategoryTheory.Limits.BinaryBicone X Y} (f : X_1 ⟶ Y_1),
  (CategoryTheory.Limits.BinaryBicone.toBiconeFunctor.map f).hom = f.hom

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeFunctor
code: /-- Convert a `BinaryBicone` into a `Bicone` over a pair. -/
@[simps]
def toBiconeFunctor {X Y : C} : BinaryBicone X Y ⥤ Bicone (pairFunction X Y) 
goal: CategoryTheory.Limits.BinaryBicone X Y ⥤ CategoryTheory.Limits.Bicone (CategoryTheory.Limits.pairFunction X Y)

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeFunctor_obj_ι
code: /-- Convert a `BinaryBicone` into a `Bicone` over a pair. -/
@[simps]
def toBiconeFunctor {X Y : C} : BinaryBicone X Y ⥤ Bicone (pairFunction X Y) 
goal: (CategoryTheory.Limits.BinaryBicone.toBiconeFunctor.obj b).ι j = CategoryTheory.Limits.WalkingPair.casesOn j b.inl b.inr

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeFunctor_obj_π
code: /-- Convert a `BinaryBicone` into a `Bicone` over a pair. -/
@[simps]
def toBiconeFunctor {X Y : C} : BinaryBicone X Y ⥤ Bicone (pairFunction X Y) 
goal: (CategoryTheory.Limits.BinaryBicone.toBiconeFunctor.obj b).π j = CategoryTheory.Limits.WalkingPair.casesOn j b.fst b.snd

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeFunctor_obj_pt
code: /-- Convert a `BinaryBicone` into a `Bicone` over a pair. -/
@[simps]
def toBiconeFunctor {X Y : C} : BinaryBicone X Y ⥤ Bicone (pairFunction X Y) 
goal: (CategoryTheory.Limits.BinaryBicone.toBiconeFunctor.obj b).pt = b.pt

full_name: CategoryTheory.Limits.BinaryBicone.toBicone
code: /-- A shorthand for `toBiconeFunctor.obj` -/
abbrev toBicone {X Y : C} (b : BinaryBicone X Y) : Bicone (pairFunction X Y) 
goal: CategoryTheory.Limits.Bicone (CategoryTheory.Limits.pairFunction X Y)

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeIsLimit
code: /-- A binary bicone is a limit cone if and only if the corresponding bicone is a limit cone. -/
def toBiconeIsLimit {X Y : C} (b : BinaryBicone X Y) :
    IsLimit b.toBicone.toCone ≃ IsLimit b.toCone 
goal: CategoryTheory.Limits.IsLimit b.toBicone.toCone ≃ CategoryTheory.Limits.IsLimit b.toCone

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeIsColimit
code: /-- A binary bicone is a colimit cocone if and only if the corresponding bicone is a colimit
    cocone. -/
def toBiconeIsColimit {X Y : C} (b : BinaryBicone X Y) :
    IsColimit b.toBicone.toCocone ≃ IsColimit b.toCocone 
goal: CategoryTheory.Limits.IsColimit b.toBicone.toCocone ≃ CategoryTheory.Limits.IsColimit b.toCocone

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor_obj_pt
code: /-- Convert a `Bicone` over a function on `WalkingPair` to a BinaryBicone. -/
@[simps]
def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone X Y 
goal: (CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor.obj b).pt = b.pt

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor
code: /-- Convert a `Bicone` over a function on `WalkingPair` to a BinaryBicone. -/
@[simps]
def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone X Y 
goal: CategoryTheory.Limits.Bicone (CategoryTheory.Limits.pairFunction X Y) ⥤ CategoryTheory.Limits.BinaryBicone X Y

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor_obj_inr
code: /-- Convert a `Bicone` over a function on `WalkingPair` to a BinaryBicone. -/
@[simps]
def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone X Y 
goal: (CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor.obj b).inr = b.ι CategoryTheory.Limits.WalkingPair.right

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor_obj_inl
code: /-- Convert a `Bicone` over a function on `WalkingPair` to a BinaryBicone. -/
@[simps]
def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone X Y 
goal: (CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor.obj b).inl = b.ι CategoryTheory.Limits.WalkingPair.left

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor_map_hom
code: /-- Convert a `Bicone` over a function on `WalkingPair` to a BinaryBicone. -/
@[simps]
def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone X Y 
goal: ∀ {X_1 Y_1 : CategoryTheory.Limits.Bicone (CategoryTheory.Limits.pairFunction X Y)} (f : X_1 ⟶ Y_1),
  (CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor.map f).hom = f.hom

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor_obj_snd
code: /-- Convert a `Bicone` over a function on `WalkingPair` to a BinaryBicone. -/
@[simps]
def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone X Y 
goal: (CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor.obj b).snd = b.π CategoryTheory.Limits.WalkingPair.right

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor_obj_fst
code: /-- Convert a `Bicone` over a function on `WalkingPair` to a BinaryBicone. -/
@[simps]
def toBinaryBiconeFunctor {X Y : C} : Bicone (pairFunction X Y) ⥤ BinaryBicone X Y 
goal: (CategoryTheory.Limits.Bicone.toBinaryBiconeFunctor.obj b).fst = b.π CategoryTheory.Limits.WalkingPair.left

full_name: CategoryTheory.Limits.Bicone.toBinaryBicone
code: /-- A shorthand for `toBinaryBiconeFunctor.obj` -/
abbrev toBinaryBicone {X Y : C} (b : Bicone (pairFunction X Y)) : BinaryBicone X Y 
goal: CategoryTheory.Limits.BinaryBicone X Y

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeIsLimit
code: /-- A bicone over a pair is a limit cone if and only if the corresponding binary bicone is a limit
    cone.  -/
def toBinaryBiconeIsLimit {X Y : C} (b : Bicone (pairFunction X Y)) :
    IsLimit b.toBinaryBicone.toCone ≃ IsLimit b.toCone 
goal: CategoryTheory.Limits.IsLimit b.toBinaryBicone.toCone ≃ CategoryTheory.Limits.IsLimit b.toCone

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeIsColimit
code: /-- A bicone over a pair is a colimit cocone if and only if the corresponding binary bicone is a
    colimit cocone. -/
def toBinaryBiconeIsColimit {X Y : C} (b : Bicone (pairFunction X Y)) :
    IsColimit b.toBinaryBicone.toCocone ≃ IsColimit b.toCocone 
goal: CategoryTheory.Limits.IsColimit b.toBinaryBicone.toCocone ≃ CategoryTheory.Limits.IsColimit b.toCocone

full_name: CategoryTheory.Limits.BinaryBicone.IsBilimit.isColimit
code: /-- Structure witnessing that a binary bicone is a limit cone and a limit cocone. -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone.IsBilimit {P Q : C} (b : BinaryBicone P Q) where
  isLimit : IsLimit b.toCone
  isColimit : IsColimit b.toCocone
goal: CategoryTheory.Limits.IsColimit b.toCocone

full_name: CategoryTheory.Limits.BinaryBicone.IsBilimit
code: /-- Structure witnessing that a binary bicone is a limit cone and a limit cocone. -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone.IsBilimit {P Q : C} (b : BinaryBicone P Q) where
  isLimit : IsLimit b.toCone
  isColimit : IsColimit b.toCocone
goal: Type (max u v)

full_name: CategoryTheory.Limits.BinaryBicone.IsBilimit.isLimit
code: /-- Structure witnessing that a binary bicone is a limit cone and a limit cocone. -/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBicone.IsBilimit {P Q : C} (b : BinaryBicone P Q) where
  isLimit : IsLimit b.toCone
  isColimit : IsColimit b.toCocone
goal: CategoryTheory.Limits.IsLimit b.toCone

full_name: CategoryTheory.Limits.BinaryBicone.toBiconeIsBilimit
code: /-- A binary bicone is a bilimit bicone if and only if the corresponding bicone is a bilimit. -/
def BinaryBicone.toBiconeIsBilimit {X Y : C} (b : BinaryBicone X Y) :
    b.toBicone.IsBilimit ≃ b.IsBilimit 
goal: b.toBicone.IsBilimit ≃ b.IsBilimit

full_name: CategoryTheory.Limits.Bicone.toBinaryBiconeIsBilimit
code: /-- A bicone over a pair is a bilimit bicone if and only if the corresponding binary bicone is a
    bilimit. -/
def Bicone.toBinaryBiconeIsBilimit {X Y : C} (b : Bicone (pairFunction X Y)) :
    b.toBinaryBicone.IsBilimit ≃ b.IsBilimit 
goal: b.toBinaryBicone.IsBilimit ≃ b.IsBilimit

full_name: CategoryTheory.Limits.BinaryBiproductData.bicone
code: /-- A bicone over `P Q : C`, which is both a limit cone and a colimit cocone.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBiproductData (P Q : C) where
  bicone : BinaryBicone P Q
  isBilimit : bicone.IsBilimit
goal: CategoryTheory.Limits.BinaryBicone P Q

full_name: CategoryTheory.Limits.BinaryBiproductData.isBilimit
code: /-- A bicone over `P Q : C`, which is both a limit cone and a colimit cocone.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBiproductData (P Q : C) where
  bicone : BinaryBicone P Q
  isBilimit : bicone.IsBilimit
goal: self.bicone.IsBilimit

full_name: CategoryTheory.Limits.BinaryBiproductData
code: /-- A bicone over `P Q : C`, which is both a limit cone and a colimit cocone.
-/
-- @[nolint has_nonempty_instance] Porting note (#5171): removed
structure BinaryBiproductData (P Q : C) where
  bicone : BinaryBicone P Q
  isBilimit : bicone.IsBilimit
goal: Type (max u v)

full_name: CategoryTheory.Limits.HasBinaryBiproduct.mk'
code: /-- `HasBinaryBiproduct P Q` expresses the mere existence of a bicone which is
simultaneously a limit and a colimit of the diagram `pair P Q`.
-/
class HasBinaryBiproduct (P Q : C) : Prop where mk' ::
  exists_binary_biproduct : Nonempty (BinaryBiproductData P Q)
goal: CategoryTheory.Limits.HasBinaryBiproduct P Q

full_name: CategoryTheory.Limits.HasBinaryBiproduct.exists_binary_biproduct
code: /-- `HasBinaryBiproduct P Q` expresses the mere existence of a bicone which is
simultaneously a limit and a colimit of the diagram `pair P Q`.
-/
class HasBinaryBiproduct (P Q : C) : Prop where mk' ::
  exists_binary_biproduct : Nonempty (BinaryBiproductData P Q)
goal: Nonempty (CategoryTheory.Limits.BinaryBiproductData P Q)

full_name: CategoryTheory.Limits.HasBinaryBiproduct
code: /-- `HasBinaryBiproduct P Q` expresses the mere existence of a bicone which is
simultaneously a limit and a colimit of the diagram `pair P Q`.
-/
class HasBinaryBiproduct (P Q : C) : Prop where mk' ::
  exists_binary_biproduct : Nonempty (BinaryBiproductData P Q)
goal: Prop

full_name: CategoryTheory.Limits.HasBinaryBiproduct.mk
code: theorem HasBinaryBiproduct.mk {P Q : C} (d : BinaryBiproductData P Q) : HasBinaryBiproduct P Q 
goal: CategoryTheory.Limits.HasBinaryBiproduct P Q

full_name: CategoryTheory.Limits.getBinaryBiproductData
code: /--
Use the axiom of choice to extract explicit `BinaryBiproductData F` from `HasBinaryBiproduct F`.
-/
def getBinaryBiproductData (P Q : C) [HasBinaryBiproduct P Q] : BinaryBiproductData P Q 
goal: CategoryTheory.Limits.BinaryBiproductData P Q

full_name: CategoryTheory.Limits.BinaryBiproduct.bicone
code: /-- A bicone for `P Q` which is both a limit cone and a colimit cocone. -/
def BinaryBiproduct.bicone (P Q : C) [HasBinaryBiproduct P Q] : BinaryBicone P Q 
goal: CategoryTheory.Limits.BinaryBicone P Q

full_name: CategoryTheory.Limits.BinaryBiproduct.isBilimit
code: /-- `BinaryBiproduct.bicone P Q` is a limit bicone. -/
def BinaryBiproduct.isBilimit (P Q : C) [HasBinaryBiproduct P Q] :
    (BinaryBiproduct.bicone P Q).IsBilimit 
goal: (CategoryTheory.Limits.BinaryBiproduct.bicone P Q).IsBilimit

full_name: CategoryTheory.Limits.BinaryBiproduct.isLimit
code: /-- `BinaryBiproduct.bicone P Q` is a limit cone. -/
def BinaryBiproduct.isLimit (P Q : C) [HasBinaryBiproduct P Q] :
    IsLimit (BinaryBiproduct.bicone P Q).toCone 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Limits.BinaryBiproduct.bicone P Q).toCone

full_name: CategoryTheory.Limits.BinaryBiproduct.isColimit
code: /-- `BinaryBiproduct.bicone P Q` is a colimit cocone. -/
def BinaryBiproduct.isColimit (P Q : C) [HasBinaryBiproduct P Q] :
    IsColimit (BinaryBiproduct.bicone P Q).toCocone 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Limits.BinaryBiproduct.bicone P Q).toCocone

full_name: CategoryTheory.Limits.HasBinaryBiproducts.has_binary_biproduct
code: /-- `HasBinaryBiproducts C` represents the existence of a bicone which is
simultaneously a limit and a colimit of the diagram `pair P Q`, for every `P Q : C`.
-/
class HasBinaryBiproducts : Prop where
  has_binary_biproduct : ∀ P Q : C, HasBinaryBiproduct P Q
goal: CategoryTheory.Limits.HasBinaryBiproduct P Q

full_name: CategoryTheory.Limits.HasBinaryBiproducts
code: /-- `HasBinaryBiproducts C` represents the existence of a bicone which is
simultaneously a limit and a colimit of the diagram `pair P Q`, for every `P Q : C`.
-/
class HasBinaryBiproducts : Prop where
  has_binary_biproduct : ∀ P Q : C, HasBinaryBiproduct P Q
goal: Prop

full_name: CategoryTheory.Limits.hasBinaryBiproducts_of_finite_biproducts
code: /-- A category with finite biproducts has binary biproducts.

This is not an instance as typically in concrete categories there will be
an alternative construction with nicer definitional properties.
-/
theorem hasBinaryBiproducts_of_finite_biproducts [HasFiniteBiproducts C] : HasBinaryBiproducts C 
goal: CategoryTheory.Limits.HasBinaryBiproducts C

full_name: CategoryTheory.Limits.HasBinaryBiproduct.hasLimit_pair
code: instance HasBinaryBiproduct.hasLimit_pair [HasBinaryBiproduct P Q] : HasLimit (pair P Q) 
goal: CategoryTheory.Limits.HasLimit (CategoryTheory.Limits.pair P Q)

full_name: CategoryTheory.Limits.HasBinaryBiproduct.hasColimit_pair
code: instance HasBinaryBiproduct.hasColimit_pair [HasBinaryBiproduct P Q] : HasColimit (pair P Q) 
goal: CategoryTheory.Limits.HasColimit (CategoryTheory.Limits.pair P Q)

full_name: CategoryTheory.Limits.hasBinaryProducts_of_hasBinaryBiproducts
code: instance (priority := 100) hasBinaryProducts_of_hasBinaryBiproducts [HasBinaryBiproducts C] :
    HasBinaryProducts C 
goal: CategoryTheory.Limits.HasBinaryProducts C

full_name: CategoryTheory.Limits.hasBinaryCoproducts_of_hasBinaryBiproducts
code: instance (priority := 100) hasBinaryCoproducts_of_hasBinaryBiproducts [HasBinaryBiproducts C] :
    HasBinaryCoproducts C 
goal: CategoryTheory.Limits.HasBinaryCoproducts C

full_name: CategoryTheory.Limits.biprodIso
code: /-- The isomorphism between the specified binary product and the specified binary coproduct for
a pair for a binary biproduct.
-/
def biprodIso (X Y : C) [HasBinaryBiproduct X Y] : Limits.prod X Y ≅ Limits.coprod X Y 
goal: X ⨯ Y ≅ X ⨿ Y

full_name: CategoryTheory.Limits.biprod
code: /-- An arbitrary choice of biproduct of a pair of objects. -/
abbrev biprod (X Y : C) [HasBinaryBiproduct X Y] 
goal: C

full_name: CategoryTheory.Limits.«_aux_Mathlib_CategoryTheory_Limits_Shapes_Biproducts___macroRules_CategoryTheory_Limits_term_⊞__1»
code: @[inherit_doc biprod]
notation:20 X " ⊞ " Y:20 => biprod X Y
goal: Lean.Macro

full_name: CategoryTheory.Limits._aux_Mathlib_CategoryTheory_Limits_Shapes_Biproducts___unexpand_CategoryTheory_Limits_biprod_1
code: @[inherit_doc biprod]
notation:20 X " ⊞ " Y:20 => biprod X Y
goal: Lean.PrettyPrinter.Unexpander

full_name: CategoryTheory.Limits.biprod.fst
code: /-- The projection onto the first summand of a binary biproduct. -/
abbrev biprod.fst {X Y : C} [HasBinaryBiproduct X Y] : X ⊞ Y ⟶ X 
goal: X ⊞ Y ⟶ X

full_name: CategoryTheory.Limits.biprod.snd
code: /-- The projection onto the second summand of a binary biproduct. -/
abbrev biprod.snd {X Y : C} [HasBinaryBiproduct X Y] : X ⊞ Y ⟶ Y 
goal: X ⊞ Y ⟶ Y

full_name: CategoryTheory.Limits.biprod.inl
code: /-- The inclusion into the first summand of a binary biproduct. -/
abbrev biprod.inl {X Y : C} [HasBinaryBiproduct X Y] : X ⟶ X ⊞ Y 
goal: X ⟶ X ⊞ Y

full_name: CategoryTheory.Limits.biprod.inr
code: /-- The inclusion into the second summand of a binary biproduct. -/
abbrev biprod.inr {X Y : C} [HasBinaryBiproduct X Y] : Y ⟶ X ⊞ Y 
goal: Y ⟶ X ⊞ Y

full_name: CategoryTheory.Limits.BinaryBiproduct.bicone_fst
code: @[simp]
theorem BinaryBiproduct.bicone_fst : (BinaryBiproduct.bicone X Y).fst = biprod.fst 
goal: (CategoryTheory.Limits.BinaryBiproduct.bicone X Y).fst = CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.BinaryBiproduct.bicone_snd
code: @[simp]
theorem BinaryBiproduct.bicone_snd : (BinaryBiproduct.bicone X Y).snd = biprod.snd 
goal: (CategoryTheory.Limits.BinaryBiproduct.bicone X Y).snd = CategoryTheory.Limits.biprod.snd

full_name: CategoryTheory.Limits.BinaryBiproduct.bicone_inl
code: @[simp]
theorem BinaryBiproduct.bicone_inl : (BinaryBiproduct.bicone X Y).inl = biprod.inl 
goal: (CategoryTheory.Limits.BinaryBiproduct.bicone X Y).inl = CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.BinaryBiproduct.bicone_inr
code: @[simp]
theorem BinaryBiproduct.bicone_inr : (BinaryBiproduct.bicone X Y).inr = biprod.inr 
goal: (CategoryTheory.Limits.BinaryBiproduct.bicone X Y).inr = CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod.inl_fst
code: @[reassoc] -- Porting note: simp can solve both versions
theorem biprod.inl_fst {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.inl : X ⟶ X ⊞ Y) ≫ (biprod.fst : X ⊞ Y ⟶ X) = 𝟙 X 
goal: CategoryTheory.Limits.biprod.inl ≫ CategoryTheory.Limits.biprod.fst = 𝟙 X

full_name: CategoryTheory.Limits.biprod.inl_snd
code: @[reassoc] -- Porting note: simp can solve both versions
theorem biprod.inl_snd {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.inl : X ⟶ X ⊞ Y) ≫ (biprod.snd : X ⊞ Y ⟶ Y) = 0 
goal: CategoryTheory.Limits.biprod.inl ≫ CategoryTheory.Limits.biprod.snd = 0

full_name: CategoryTheory.Limits.biprod.inr_fst
code: @[reassoc] -- Porting note: simp can solve both versions
theorem biprod.inr_fst {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.inr : Y ⟶ X ⊞ Y) ≫ (biprod.fst : X ⊞ Y ⟶ X) = 0 
goal: CategoryTheory.Limits.biprod.inr ≫ CategoryTheory.Limits.biprod.fst = 0

full_name: CategoryTheory.Limits.biprod.inr_snd
code: @[reassoc] -- Porting note: simp can solve both versions
theorem biprod.inr_snd {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.inr : Y ⟶ X ⊞ Y) ≫ (biprod.snd : X ⊞ Y ⟶ Y) = 𝟙 Y 
goal: CategoryTheory.Limits.biprod.inr ≫ CategoryTheory.Limits.biprod.snd = 𝟙 Y

full_name: CategoryTheory.Limits.biprod.lift
code: /-- Given a pair of maps into the summands of a binary biproduct,
we obtain a map into the binary biproduct. -/
abbrev biprod.lift {W X Y : C} [HasBinaryBiproduct X Y] (f : W ⟶ X) (g : W ⟶ Y) : W ⟶ X ⊞ Y 
goal: W ⟶ X ⊞ Y

full_name: CategoryTheory.Limits.biprod.desc
code: /-- Given a pair of maps out of the summands of a binary biproduct,
we obtain a map out of the binary biproduct. -/
abbrev biprod.desc {W X Y : C} [HasBinaryBiproduct X Y] (f : X ⟶ W) (g : Y ⟶ W) : X ⊞ Y ⟶ W 
goal: X ⊞ Y ⟶ W

full_name: CategoryTheory.Limits.biprod.lift_fst
code: @[reassoc (attr := simp)]
theorem biprod.lift_fst {W X Y : C} [HasBinaryBiproduct X Y] (f : W ⟶ X) (g : W ⟶ Y) :
    biprod.lift f g ≫ biprod.fst = f 
goal: CategoryTheory.Limits.biprod.lift f g ≫ CategoryTheory.Limits.biprod.fst = f

full_name: CategoryTheory.Limits.biprod.lift_snd
code: @[reassoc (attr := simp)]
theorem biprod.lift_snd {W X Y : C} [HasBinaryBiproduct X Y] (f : W ⟶ X) (g : W ⟶ Y) :
    biprod.lift f g ≫ biprod.snd = g 
goal: CategoryTheory.Limits.biprod.lift f g ≫ CategoryTheory.Limits.biprod.snd = g

full_name: CategoryTheory.Limits.biprod.inl_desc
code: @[reassoc (attr := simp)]
theorem biprod.inl_desc {W X Y : C} [HasBinaryBiproduct X Y] (f : X ⟶ W) (g : Y ⟶ W) :
    biprod.inl ≫ biprod.desc f g = f 
goal: CategoryTheory.Limits.biprod.inl ≫ CategoryTheory.Limits.biprod.desc f g = f

full_name: CategoryTheory.Limits.biprod.inr_desc
code: @[reassoc (attr := simp)]
theorem biprod.inr_desc {W X Y : C} [HasBinaryBiproduct X Y] (f : X ⟶ W) (g : Y ⟶ W) :
    biprod.inr ≫ biprod.desc f g = g 
goal: CategoryTheory.Limits.biprod.inr ≫ CategoryTheory.Limits.biprod.desc f g = g

full_name: CategoryTheory.Limits.biprod.mono_lift_of_mono_left
code: instance biprod.mono_lift_of_mono_left {W X Y : C} [HasBinaryBiproduct X Y] (f : W ⟶ X) (g : W ⟶ Y)
    [Mono f] : Mono (biprod.lift f g) 
goal: CategoryTheory.Mono (CategoryTheory.Limits.biprod.lift f g)

full_name: CategoryTheory.Limits.biprod.mono_lift_of_mono_right
code: instance biprod.mono_lift_of_mono_right {W X Y : C} [HasBinaryBiproduct X Y] (f : W ⟶ X) (g : W ⟶ Y)
    [Mono g] : Mono (biprod.lift f g) 
goal: CategoryTheory.Mono (CategoryTheory.Limits.biprod.lift f g)

full_name: CategoryTheory.Limits.biprod.epi_desc_of_epi_left
code: instance biprod.epi_desc_of_epi_left {W X Y : C} [HasBinaryBiproduct X Y] (f : X ⟶ W) (g : Y ⟶ W)
    [Epi f] : Epi (biprod.desc f g) 
goal: CategoryTheory.Epi (CategoryTheory.Limits.biprod.desc f g)

full_name: CategoryTheory.Limits.biprod.epi_desc_of_epi_right
code: instance biprod.epi_desc_of_epi_right {W X Y : C} [HasBinaryBiproduct X Y] (f : X ⟶ W) (g : Y ⟶ W)
    [Epi g] : Epi (biprod.desc f g) 
goal: CategoryTheory.Epi (CategoryTheory.Limits.biprod.desc f g)

full_name: CategoryTheory.Limits.biprod.map
code: /-- Given a pair of maps between the summands of a pair of binary biproducts,
we obtain a map between the binary biproducts. -/
abbrev biprod.map {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ⟶ Y)
    (g : X ⟶ Z) : W ⊞ X ⟶ Y ⊞ Z 
goal: W ⊞ X ⟶ Y ⊞ Z

full_name: CategoryTheory.Limits.biprod.map'
code: /-- An alternative to `biprod.map` constructed via colimits.
This construction only exists in order to show it is equal to `biprod.map`. -/
abbrev biprod.map' {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ⟶ Y)
    (g : X ⟶ Z) : W ⊞ X ⟶ Y ⊞ Z 
goal: W ⊞ X ⟶ Y ⊞ Z

full_name: CategoryTheory.Limits.biprod.hom_ext
code: @[ext]
theorem biprod.hom_ext {X Y Z : C} [HasBinaryBiproduct X Y] (f g : Z ⟶ X ⊞ Y)
    (h₀ : f ≫ biprod.fst = g ≫ biprod.fst) (h₁ : f ≫ biprod.snd = g ≫ biprod.snd) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.biprod.hom_ext'
code: @[ext]
theorem biprod.hom_ext' {X Y Z : C} [HasBinaryBiproduct X Y] (f g : X ⊞ Y ⟶ Z)
    (h₀ : biprod.inl ≫ f = biprod.inl ≫ g) (h₁ : biprod.inr ≫ f = biprod.inr ≫ g) : f = g 
goal: f = g

full_name: CategoryTheory.Limits.biprod.isoProd
code: /-- The canonical isomorphism between the chosen biproduct and the chosen product. -/
def biprod.isoProd (X Y : C) [HasBinaryBiproduct X Y] : X ⊞ Y ≅ X ⨯ Y 
goal: X ⊞ Y ≅ X ⨯ Y

full_name: CategoryTheory.Limits.biprod.isoProd_hom
code: @[simp]
theorem biprod.isoProd_hom {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.isoProd X Y).hom = prod.lift biprod.fst biprod.snd 
goal: (CategoryTheory.Limits.biprod.isoProd X Y).hom =
  CategoryTheory.Limits.prod.lift CategoryTheory.Limits.biprod.fst CategoryTheory.Limits.biprod.snd

full_name: CategoryTheory.Limits.biprod.isoProd_inv
code: @[simp]
theorem biprod.isoProd_inv {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.isoProd X Y).inv = biprod.lift prod.fst prod.snd 
goal: (CategoryTheory.Limits.biprod.isoProd X Y).inv =
  CategoryTheory.Limits.biprod.lift CategoryTheory.Limits.prod.fst CategoryTheory.Limits.prod.snd

full_name: CategoryTheory.Limits.biprod.isoCoprod
code: /-- The canonical isomorphism between the chosen biproduct and the chosen coproduct. -/
def biprod.isoCoprod (X Y : C) [HasBinaryBiproduct X Y] : X ⊞ Y ≅ X ⨿ Y 
goal: X ⊞ Y ≅ X ⨿ Y

full_name: CategoryTheory.Limits.biprod.isoCoprod_inv
code: @[simp]
theorem biprod.isoCoprod_inv {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.isoCoprod X Y).inv = coprod.desc biprod.inl biprod.inr 
goal: (CategoryTheory.Limits.biprod.isoCoprod X Y).inv =
  CategoryTheory.Limits.coprod.desc CategoryTheory.Limits.biprod.inl CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod_isoCoprod_hom
code: @[simp]
theorem biprod_isoCoprod_hom {X Y : C} [HasBinaryBiproduct X Y] :
    (biprod.isoCoprod X Y).hom = biprod.desc coprod.inl coprod.inr 
goal: (CategoryTheory.Limits.biprod.isoCoprod X Y).hom =
  CategoryTheory.Limits.biprod.desc CategoryTheory.Limits.coprod.inl CategoryTheory.Limits.coprod.inr

full_name: CategoryTheory.Limits.biprod.map_eq_map'
code: theorem biprod.map_eq_map' {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z]
    (f : W ⟶ Y) (g : X ⟶ Z) : biprod.map f g = biprod.map' f g 
goal: CategoryTheory.Limits.biprod.map f g = CategoryTheory.Limits.biprod.map' f g

full_name: CategoryTheory.Limits.biprod.inl_mono
code: instance biprod.inl_mono {X Y : C} [HasBinaryBiproduct X Y] :
    IsSplitMono (biprod.inl : X ⟶ X ⊞ Y) 
goal: CategoryTheory.IsSplitMono CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.biprod.inr_mono
code: instance biprod.inr_mono {X Y : C} [HasBinaryBiproduct X Y] :
    IsSplitMono (biprod.inr : Y ⟶ X ⊞ Y) 
goal: CategoryTheory.IsSplitMono CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod.fst_epi
code: instance biprod.fst_epi {X Y : C} [HasBinaryBiproduct X Y] : IsSplitEpi (biprod.fst : X ⊞ Y ⟶ X) 
goal: CategoryTheory.IsSplitEpi CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.biprod.snd_epi
code: instance biprod.snd_epi {X Y : C} [HasBinaryBiproduct X Y] : IsSplitEpi (biprod.snd : X ⊞ Y ⟶ Y) 
goal: CategoryTheory.IsSplitEpi CategoryTheory.Limits.biprod.snd

full_name: CategoryTheory.Limits.biprod.map_fst
code: @[reassoc (attr := simp)]
theorem biprod.map_fst {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ⟶ Y)
    (g : X ⟶ Z) : biprod.map f g ≫ biprod.fst = biprod.fst ≫ f 
goal: CategoryTheory.Limits.biprod.map f g ≫ CategoryTheory.Limits.biprod.fst = CategoryTheory.Limits.biprod.fst ≫ f

full_name: CategoryTheory.Limits.biprod.map_snd
code: @[reassoc (attr := simp)]
theorem biprod.map_snd {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ⟶ Y)
    (g : X ⟶ Z) : biprod.map f g ≫ biprod.snd = biprod.snd ≫ g 
goal: CategoryTheory.Limits.biprod.map f g ≫ CategoryTheory.Limits.biprod.snd = CategoryTheory.Limits.biprod.snd ≫ g

full_name: CategoryTheory.Limits.biprod.inl_map
code: @[reassoc (attr := simp)]
theorem biprod.inl_map {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ⟶ Y)
    (g : X ⟶ Z) : biprod.inl ≫ biprod.map f g = f ≫ biprod.inl 
goal: CategoryTheory.Limits.biprod.inl ≫ CategoryTheory.Limits.biprod.map f g = f ≫ CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.biprod.inr_map
code: @[reassoc (attr := simp)]
theorem biprod.inr_map {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ⟶ Y)
    (g : X ⟶ Z) : biprod.inr ≫ biprod.map f g = g ≫ biprod.inr 
goal: CategoryTheory.Limits.biprod.inr ≫ CategoryTheory.Limits.biprod.map f g = g ≫ CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod.mapIso
code: /-- Given a pair of isomorphisms between the summands of a pair of binary biproducts,
we obtain an isomorphism between the binary biproducts. -/
@[simps]
def biprod.mapIso {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ≅ Y)
    (g : X ≅ Z) : W ⊞ X ≅ Y ⊞ Z 
goal: W ⊞ X ≅ Y ⊞ Z

full_name: CategoryTheory.Limits.biprod.mapIso_inv
code: /-- Given a pair of isomorphisms between the summands of a pair of binary biproducts,
we obtain an isomorphism between the binary biproducts. -/
@[simps]
def biprod.mapIso {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ≅ Y)
    (g : X ≅ Z) : W ⊞ X ≅ Y ⊞ Z 
goal: (CategoryTheory.Limits.biprod.mapIso f g).inv = CategoryTheory.Limits.biprod.map f.inv g.inv

full_name: CategoryTheory.Limits.biprod.mapIso_hom
code: /-- Given a pair of isomorphisms between the summands of a pair of binary biproducts,
we obtain an isomorphism between the binary biproducts. -/
@[simps]
def biprod.mapIso {W X Y Z : C} [HasBinaryBiproduct W X] [HasBinaryBiproduct Y Z] (f : W ≅ Y)
    (g : X ≅ Z) : W ⊞ X ≅ Y ⊞ Z 
goal: (CategoryTheory.Limits.biprod.mapIso f g).hom = CategoryTheory.Limits.biprod.map f.hom g.hom

full_name: CategoryTheory.Limits.biprod.conePointUniqueUpToIso_hom
code: /-- Auxiliary lemma for `biprod.uniqueUpToIso`. -/
theorem biprod.conePointUniqueUpToIso_hom (X Y : C) [HasBinaryBiproduct X Y] {b : BinaryBicone X Y}
    (hb : b.IsBilimit) :
    (hb.isLimit.conePointUniqueUpToIso (BinaryBiproduct.isLimit _ _)).hom =
      biprod.lift b.fst b.snd 
goal: (hb.isLimit.conePointUniqueUpToIso (CategoryTheory.Limits.BinaryBiproduct.isLimit X Y)).hom =
  CategoryTheory.Limits.biprod.lift b.fst b.snd

full_name: CategoryTheory.Limits.biprod.conePointUniqueUpToIso_inv
code: /-- Auxiliary lemma for `biprod.uniqueUpToIso`. -/
theorem biprod.conePointUniqueUpToIso_inv (X Y : C) [HasBinaryBiproduct X Y] {b : BinaryBicone X Y}
    (hb : b.IsBilimit) :
    (hb.isLimit.conePointUniqueUpToIso (BinaryBiproduct.isLimit _ _)).inv =
      biprod.desc b.inl b.inr 
goal: (hb.isLimit.conePointUniqueUpToIso (CategoryTheory.Limits.BinaryBiproduct.isLimit X Y)).inv =
  CategoryTheory.Limits.biprod.desc b.inl b.inr

full_name: CategoryTheory.Limits.biprod.uniqueUpToIso
code: /-- Binary biproducts are unique up to isomorphism. This already follows because bilimits are
    limits, but in the case of biproducts we can give an isomorphism with particularly nice
    definitional properties, namely that `biprod.lift b.fst b.snd` and `biprod.desc b.inl b.inr`
    are inverses of each other. -/
@[simps]
def biprod.uniqueUpToIso (X Y : C) [HasBinaryBiproduct X Y] {b : BinaryBicone X Y}
    (hb : b.IsBilimit) : b.pt ≅ X ⊞ Y 
goal: b.pt ≅ X ⊞ Y

full_name: CategoryTheory.Limits.biprod.uniqueUpToIso_hom
code: /-- Binary biproducts are unique up to isomorphism. This already follows because bilimits are
    limits, but in the case of biproducts we can give an isomorphism with particularly nice
    definitional properties, namely that `biprod.lift b.fst b.snd` and `biprod.desc b.inl b.inr`
    are inverses of each other. -/
@[simps]
def biprod.uniqueUpToIso (X Y : C) [HasBinaryBiproduct X Y] {b : BinaryBicone X Y}
    (hb : b.IsBilimit) : b.pt ≅ X ⊞ Y 
goal: (CategoryTheory.Limits.biprod.uniqueUpToIso X Y hb).hom = CategoryTheory.Limits.biprod.lift b.fst b.snd

full_name: CategoryTheory.Limits.biprod.uniqueUpToIso_inv
code: /-- Binary biproducts are unique up to isomorphism. This already follows because bilimits are
    limits, but in the case of biproducts we can give an isomorphism with particularly nice
    definitional properties, namely that `biprod.lift b.fst b.snd` and `biprod.desc b.inl b.inr`
    are inverses of each other. -/
@[simps]
def biprod.uniqueUpToIso (X Y : C) [HasBinaryBiproduct X Y] {b : BinaryBicone X Y}
    (hb : b.IsBilimit) : b.pt ≅ X ⊞ Y 
goal: (CategoryTheory.Limits.biprod.uniqueUpToIso X Y hb).inv = CategoryTheory.Limits.biprod.desc b.inl b.inr

full_name: CategoryTheory.Limits.biprod.isIso_inl_iff_id_eq_fst_comp_inl
code: theorem biprod.isIso_inl_iff_id_eq_fst_comp_inl (X Y : C) [HasBinaryBiproduct X Y] :
    IsIso (biprod.inl : X ⟶ X ⊞ Y) ↔ 𝟙 (X ⊞ Y) = biprod.fst ≫ biprod.inl 
goal: CategoryTheory.IsIso CategoryTheory.Limits.biprod.inl ↔
  𝟙 (X ⊞ Y) = CategoryTheory.Limits.biprod.fst ≫ CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.BinaryBicone.fstKernelFork
code: /-- A kernel fork for the kernel of `BinaryBicone.fst`. It consists of the morphism
`BinaryBicone.inr`. -/
def BinaryBicone.fstKernelFork : KernelFork c.fst 
goal: CategoryTheory.Limits.KernelFork c.fst

full_name: CategoryTheory.Limits.BinaryBicone.fstKernelFork_ι
code: @[simp]
theorem BinaryBicone.fstKernelFork_ι : (BinaryBicone.fstKernelFork c).ι = c.inr 
goal: CategoryTheory.Limits.Fork.ι c.fstKernelFork = c.inr

full_name: CategoryTheory.Limits.BinaryBicone.sndKernelFork
code: /-- A kernel fork for the kernel of `BinaryBicone.snd`. It consists of the morphism
`BinaryBicone.inl`. -/
def BinaryBicone.sndKernelFork : KernelFork c.snd 
goal: CategoryTheory.Limits.KernelFork c.snd

full_name: CategoryTheory.Limits.BinaryBicone.sndKernelFork_ι
code: @[simp]
theorem BinaryBicone.sndKernelFork_ι : (BinaryBicone.sndKernelFork c).ι = c.inl 
goal: CategoryTheory.Limits.Fork.ι c.sndKernelFork = c.inl

full_name: CategoryTheory.Limits.BinaryBicone.inlCokernelCofork
code: /-- A cokernel cofork for the cokernel of `BinaryBicone.inl`. It consists of the morphism
`BinaryBicone.snd`. -/
def BinaryBicone.inlCokernelCofork : CokernelCofork c.inl 
goal: CategoryTheory.Limits.CokernelCofork c.inl

full_name: CategoryTheory.Limits.BinaryBicone.inlCokernelCofork_π
code: @[simp]
theorem BinaryBicone.inlCokernelCofork_π : (BinaryBicone.inlCokernelCofork c).π = c.snd 
goal: CategoryTheory.Limits.Cofork.π c.inlCokernelCofork = c.snd

full_name: CategoryTheory.Limits.BinaryBicone.inrCokernelCofork
code: /-- A cokernel cofork for the cokernel of `BinaryBicone.inr`. It consists of the morphism
`BinaryBicone.fst`. -/
def BinaryBicone.inrCokernelCofork : CokernelCofork c.inr 
goal: CategoryTheory.Limits.CokernelCofork c.inr

full_name: CategoryTheory.Limits.BinaryBicone.inrCokernelCofork_π
code: @[simp]
theorem BinaryBicone.inrCokernelCofork_π : (BinaryBicone.inrCokernelCofork c).π = c.fst 
goal: CategoryTheory.Limits.Cofork.π c.inrCokernelCofork = c.fst

full_name: CategoryTheory.Limits.BinaryBicone.isLimitFstKernelFork
code: /-- The fork defined in `BinaryBicone.fstKernelFork` is indeed a kernel. -/
def BinaryBicone.isLimitFstKernelFork (i : IsLimit c.toCone) : IsLimit c.fstKernelFork 
goal: CategoryTheory.Limits.IsLimit c.fstKernelFork

full_name: CategoryTheory.Limits.BinaryBicone.isLimitSndKernelFork
code: /-- The fork defined in `BinaryBicone.sndKernelFork` is indeed a kernel. -/
def BinaryBicone.isLimitSndKernelFork (i : IsLimit c.toCone) : IsLimit c.sndKernelFork 
goal: CategoryTheory.Limits.IsLimit c.sndKernelFork

full_name: CategoryTheory.Limits.BinaryBicone.isColimitInlCokernelCofork
code: /-- The cofork defined in `BinaryBicone.inlCokernelCofork` is indeed a cokernel. -/
def BinaryBicone.isColimitInlCokernelCofork (i : IsColimit c.toCocone) :
    IsColimit c.inlCokernelCofork 
goal: CategoryTheory.Limits.IsColimit c.inlCokernelCofork

full_name: CategoryTheory.Limits.BinaryBicone.isColimitInrCokernelCofork
code: /-- The cofork defined in `BinaryBicone.inrCokernelCofork` is indeed a cokernel. -/
def BinaryBicone.isColimitInrCokernelCofork (i : IsColimit c.toCocone) :
    IsColimit c.inrCokernelCofork 
goal: CategoryTheory.Limits.IsColimit c.inrCokernelCofork

full_name: CategoryTheory.Limits.biprod.fstKernelFork
code: /-- A kernel fork for the kernel of `biprod.fst`. It consists of the
morphism `biprod.inr`. -/
def biprod.fstKernelFork : KernelFork (biprod.fst : X ⊞ Y ⟶ X) 
goal: CategoryTheory.Limits.KernelFork CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.biprod.fstKernelFork_ι
code: @[simp]
theorem biprod.fstKernelFork_ι : Fork.ι (biprod.fstKernelFork X Y) = (biprod.inr : Y ⟶ X ⊞ Y) 
goal: CategoryTheory.Limits.Fork.ι (CategoryTheory.Limits.biprod.fstKernelFork X Y) = CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod.isKernelFstKernelFork
code: /-- The fork `biprod.fstKernelFork` is indeed a limit.  -/
def biprod.isKernelFstKernelFork : IsLimit (biprod.fstKernelFork X Y) 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Limits.biprod.fstKernelFork X Y)

full_name: CategoryTheory.Limits.biprod.sndKernelFork
code: /-- A kernel fork for the kernel of `biprod.snd`. It consists of the
morphism `biprod.inl`. -/
def biprod.sndKernelFork : KernelFork (biprod.snd : X ⊞ Y ⟶ Y) 
goal: CategoryTheory.Limits.KernelFork CategoryTheory.Limits.biprod.snd

full_name: CategoryTheory.Limits.biprod.sndKernelFork_ι
code: @[simp]
theorem biprod.sndKernelFork_ι : Fork.ι (biprod.sndKernelFork X Y) = (biprod.inl : X ⟶ X ⊞ Y) 
goal: CategoryTheory.Limits.Fork.ι (CategoryTheory.Limits.biprod.sndKernelFork X Y) = CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.biprod.isKernelSndKernelFork
code: /-- The fork `biprod.sndKernelFork` is indeed a limit.  -/
def biprod.isKernelSndKernelFork : IsLimit (biprod.sndKernelFork X Y) 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Limits.biprod.sndKernelFork X Y)

full_name: CategoryTheory.Limits.biprod.inlCokernelCofork
code: /-- A cokernel cofork for the cokernel of `biprod.inl`. It consists of the
morphism `biprod.snd`. -/
def biprod.inlCokernelCofork : CokernelCofork (biprod.inl : X ⟶ X ⊞ Y) 
goal: CategoryTheory.Limits.CokernelCofork CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.biprod.inlCokernelCofork_π
code: @[simp]
theorem biprod.inlCokernelCofork_π : Cofork.π (biprod.inlCokernelCofork X Y) = biprod.snd 
goal: CategoryTheory.Limits.Cofork.π (CategoryTheory.Limits.biprod.inlCokernelCofork X Y) = CategoryTheory.Limits.biprod.snd

full_name: CategoryTheory.Limits.biprod.isCokernelInlCokernelFork
code: /-- The cofork `biprod.inlCokernelFork` is indeed a colimit.  -/
def biprod.isCokernelInlCokernelFork : IsColimit (biprod.inlCokernelCofork X Y) 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Limits.biprod.inlCokernelCofork X Y)

full_name: CategoryTheory.Limits.biprod.inrCokernelCofork
code: /-- A cokernel cofork for the cokernel of `biprod.inr`. It consists of the
morphism `biprod.fst`. -/
def biprod.inrCokernelCofork : CokernelCofork (biprod.inr : Y ⟶ X ⊞ Y) 
goal: CategoryTheory.Limits.CokernelCofork CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod.inrCokernelCofork_π
code: @[simp]
theorem biprod.inrCokernelCofork_π : Cofork.π (biprod.inrCokernelCofork X Y) = biprod.fst 
goal: CategoryTheory.Limits.Cofork.π (CategoryTheory.Limits.biprod.inrCokernelCofork X Y) = CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.biprod.isCokernelInrCokernelFork
code: /-- The cofork `biprod.inrCokernelFork` is indeed a colimit.  -/
def biprod.isCokernelInrCokernelFork : IsColimit (biprod.inrCokernelCofork X Y) 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Limits.biprod.inrCokernelCofork X Y)

full_name: CategoryTheory.Limits.instHasKernelFst
code: instance : HasKernel (biprod.fst : X ⊞ Y ⟶ X) 
goal: CategoryTheory.Limits.HasKernel CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.kernelBiprodFstIso_inv
code: /-- The kernel of `biprod.fst : X ⊞ Y ⟶ X` is `Y`. -/
@[simps!]
def kernelBiprodFstIso : kernel (biprod.fst : X ⊞ Y ⟶ X) ≅ Y 
goal: CategoryTheory.Limits.kernelBiprodFstIso.inv =
  CategoryTheory.Limits.limit.lift (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.fst 0)
    (CategoryTheory.Limits.biprod.fstKernelFork X Y)

full_name: CategoryTheory.Limits.kernelBiprodFstIso
code: /-- The kernel of `biprod.fst : X ⊞ Y ⟶ X` is `Y`. -/
@[simps!]
def kernelBiprodFstIso : kernel (biprod.fst : X ⊞ Y ⟶ X) ≅ Y 
goal: CategoryTheory.Limits.kernel CategoryTheory.Limits.biprod.fst ≅ Y

full_name: CategoryTheory.Limits.kernelBiprodFstIso_hom
code: /-- The kernel of `biprod.fst : X ⊞ Y ⟶ X` is `Y`. -/
@[simps!]
def kernelBiprodFstIso : kernel (biprod.fst : X ⊞ Y ⟶ X) ≅ Y 
goal: CategoryTheory.Limits.kernelBiprodFstIso.hom =
  (CategoryTheory.Limits.biprod.isKernelFstKernelFork X Y).lift
    (CategoryTheory.Limits.limit.cone (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.fst 0))

full_name: CategoryTheory.Limits.instHasKernelSnd
code: instance : HasKernel (biprod.snd : X ⊞ Y ⟶ Y) 
goal: CategoryTheory.Limits.HasKernel CategoryTheory.Limits.biprod.snd

full_name: CategoryTheory.Limits.kernelBiprodSndIso
code: /-- The kernel of `biprod.snd : X ⊞ Y ⟶ Y` is `X`. -/
@[simps!]
def kernelBiprodSndIso : kernel (biprod.snd : X ⊞ Y ⟶ Y) ≅ X 
goal: CategoryTheory.Limits.kernel CategoryTheory.Limits.biprod.snd ≅ X

full_name: CategoryTheory.Limits.kernelBiprodSndIso_hom
code: /-- The kernel of `biprod.snd : X ⊞ Y ⟶ Y` is `X`. -/
@[simps!]
def kernelBiprodSndIso : kernel (biprod.snd : X ⊞ Y ⟶ Y) ≅ X 
goal: CategoryTheory.Limits.kernelBiprodSndIso.hom =
  (CategoryTheory.Limits.biprod.isKernelSndKernelFork X Y).lift
    (CategoryTheory.Limits.limit.cone (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.snd 0))

full_name: CategoryTheory.Limits.kernelBiprodSndIso_inv
code: /-- The kernel of `biprod.snd : X ⊞ Y ⟶ Y` is `X`. -/
@[simps!]
def kernelBiprodSndIso : kernel (biprod.snd : X ⊞ Y ⟶ Y) ≅ X 
goal: CategoryTheory.Limits.kernelBiprodSndIso.inv =
  CategoryTheory.Limits.limit.lift (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.snd 0)
    (CategoryTheory.Limits.biprod.sndKernelFork X Y)

full_name: CategoryTheory.Limits.instHasCokernelInl
code: instance : HasCokernel (biprod.inl : X ⟶ X ⊞ Y) 
goal: CategoryTheory.Limits.HasCokernel CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.cokernelBiprodInlIso_hom
code: /-- The cokernel of `biprod.inl : X ⟶ X ⊞ Y` is `Y`. -/
@[simps!]
def cokernelBiprodInlIso : cokernel (biprod.inl : X ⟶ X ⊞ Y) ≅ Y 
goal: CategoryTheory.Limits.cokernelBiprodInlIso.hom =
  CategoryTheory.Limits.colimit.desc (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.inl 0)
    (CategoryTheory.Limits.biprod.inlCokernelCofork X Y)

full_name: CategoryTheory.Limits.cokernelBiprodInlIso
code: /-- The cokernel of `biprod.inl : X ⟶ X ⊞ Y` is `Y`. -/
@[simps!]
def cokernelBiprodInlIso : cokernel (biprod.inl : X ⟶ X ⊞ Y) ≅ Y 
goal: CategoryTheory.Limits.cokernel CategoryTheory.Limits.biprod.inl ≅ Y

full_name: CategoryTheory.Limits.cokernelBiprodInlIso_inv
code: /-- The cokernel of `biprod.inl : X ⟶ X ⊞ Y` is `Y`. -/
@[simps!]
def cokernelBiprodInlIso : cokernel (biprod.inl : X ⟶ X ⊞ Y) ≅ Y 
goal: CategoryTheory.Limits.cokernelBiprodInlIso.inv =
  (CategoryTheory.Limits.biprod.isCokernelInlCokernelFork X Y).desc
    (CategoryTheory.Limits.colimit.cocone (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.inl 0))

full_name: CategoryTheory.Limits.instHasCokernelInr
code: instance : HasCokernel (biprod.inr : Y ⟶ X ⊞ Y) 
goal: CategoryTheory.Limits.HasCokernel CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.cokernelBiprodInrIso_inv
code: /-- The cokernel of `biprod.inr : Y ⟶ X ⊞ Y` is `X`. -/
@[simps!]
def cokernelBiprodInrIso : cokernel (biprod.inr : Y ⟶ X ⊞ Y) ≅ X 
goal: CategoryTheory.Limits.cokernelBiprodInrIso.inv =
  (CategoryTheory.Limits.biprod.isCokernelInrCokernelFork X Y).desc
    (CategoryTheory.Limits.colimit.cocone (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.inr 0))

full_name: CategoryTheory.Limits.cokernelBiprodInrIso_hom
code: /-- The cokernel of `biprod.inr : Y ⟶ X ⊞ Y` is `X`. -/
@[simps!]
def cokernelBiprodInrIso : cokernel (biprod.inr : Y ⟶ X ⊞ Y) ≅ X 
goal: CategoryTheory.Limits.cokernelBiprodInrIso.hom =
  CategoryTheory.Limits.colimit.desc (CategoryTheory.Limits.parallelPair CategoryTheory.Limits.biprod.inr 0)
    (CategoryTheory.Limits.biprod.inrCokernelCofork X Y)

full_name: CategoryTheory.Limits.cokernelBiprodInrIso
code: /-- The cokernel of `biprod.inr : Y ⟶ X ⊞ Y` is `X`. -/
@[simps!]
def cokernelBiprodInrIso : cokernel (biprod.inr : Y ⟶ X ⊞ Y) ≅ X 
goal: CategoryTheory.Limits.cokernel CategoryTheory.Limits.biprod.inr ≅ X

full_name: CategoryTheory.Limits.isoBiprodZero
code: /-- If `Y` is a zero object, `X ≅ X ⊞ Y` for any `X`. -/
@[simps!]
def isoBiprodZero {X Y : C} [HasBinaryBiproduct X Y] (hY : IsZero Y) : X ≅ X ⊞ Y 
goal: X ≅ X ⊞ Y

full_name: CategoryTheory.Limits.isoBiprodZero_hom
code: /-- If `Y` is a zero object, `X ≅ X ⊞ Y` for any `X`. -/
@[simps!]
def isoBiprodZero {X Y : C} [HasBinaryBiproduct X Y] (hY : IsZero Y) : X ≅ X ⊞ Y 
goal: (CategoryTheory.Limits.isoBiprodZero hY).hom = CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.isoBiprodZero_inv
code: /-- If `Y` is a zero object, `X ≅ X ⊞ Y` for any `X`. -/
@[simps!]
def isoBiprodZero {X Y : C} [HasBinaryBiproduct X Y] (hY : IsZero Y) : X ≅ X ⊞ Y 
goal: (CategoryTheory.Limits.isoBiprodZero hY).inv = CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.isoZeroBiprod_inv
code: /-- If `X` is a zero object, `Y ≅ X ⊞ Y` for any `Y`. -/
@[simps]
def isoZeroBiprod {X Y : C} [HasBinaryBiproduct X Y] (hY : IsZero X) : Y ≅ X ⊞ Y 
goal: (CategoryTheory.Limits.isoZeroBiprod hY).inv = CategoryTheory.Limits.biprod.snd

full_name: CategoryTheory.Limits.isoZeroBiprod
code: /-- If `X` is a zero object, `Y ≅ X ⊞ Y` for any `Y`. -/
@[simps]
def isoZeroBiprod {X Y : C} [HasBinaryBiproduct X Y] (hY : IsZero X) : Y ≅ X ⊞ Y 
goal: Y ≅ X ⊞ Y

full_name: CategoryTheory.Limits.isoZeroBiprod_hom
code: /-- If `X` is a zero object, `Y ≅ X ⊞ Y` for any `Y`. -/
@[simps]
def isoZeroBiprod {X Y : C} [HasBinaryBiproduct X Y] (hY : IsZero X) : Y ≅ X ⊞ Y 
goal: (CategoryTheory.Limits.isoZeroBiprod hY).hom = CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod_isZero_iff
code: @[simp]
lemma biprod_isZero_iff (A B : C) [HasBinaryBiproduct A B] :
    IsZero (biprod A B) ↔ IsZero A ∧ IsZero B 
goal: CategoryTheory.Limits.IsZero (A ⊞ B) ↔ CategoryTheory.Limits.IsZero A ∧ CategoryTheory.Limits.IsZero B

full_name: CategoryTheory.Limits.biprod.braiding
code: /-- The braiding isomorphism which swaps a binary biproduct. -/
@[simps]
def biprod.braiding (P Q : C) : P ⊞ Q ≅ Q ⊞ P 
goal: P ⊞ Q ≅ Q ⊞ P

full_name: CategoryTheory.Limits.biprod.braiding_inv
code: /-- The braiding isomorphism which swaps a binary biproduct. -/
@[simps]
def biprod.braiding (P Q : C) : P ⊞ Q ≅ Q ⊞ P 
goal: (CategoryTheory.Limits.biprod.braiding P Q).inv =
  CategoryTheory.Limits.biprod.lift CategoryTheory.Limits.biprod.snd CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.biprod.braiding_hom
code: /-- The braiding isomorphism which swaps a binary biproduct. -/
@[simps]
def biprod.braiding (P Q : C) : P ⊞ Q ≅ Q ⊞ P 
goal: (CategoryTheory.Limits.biprod.braiding P Q).hom =
  CategoryTheory.Limits.biprod.lift CategoryTheory.Limits.biprod.snd CategoryTheory.Limits.biprod.fst

full_name: CategoryTheory.Limits.biprod.braiding'
code: /-- An alternative formula for the braiding isomorphism which swaps a binary biproduct,
using the fact that the biproduct is a coproduct.
-/
@[simps]
def biprod.braiding' (P Q : C) : P ⊞ Q ≅ Q ⊞ P 
goal: P ⊞ Q ≅ Q ⊞ P

full_name: CategoryTheory.Limits.biprod.braiding'_hom
code: /-- An alternative formula for the braiding isomorphism which swaps a binary biproduct,
using the fact that the biproduct is a coproduct.
-/
@[simps]
def biprod.braiding' (P Q : C) : P ⊞ Q ≅ Q ⊞ P 
goal: (CategoryTheory.Limits.biprod.braiding' P Q).hom =
  CategoryTheory.Limits.biprod.desc CategoryTheory.Limits.biprod.inr CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.biprod.braiding'_inv
code: /-- An alternative formula for the braiding isomorphism which swaps a binary biproduct,
using the fact that the biproduct is a coproduct.
-/
@[simps]
def biprod.braiding' (P Q : C) : P ⊞ Q ≅ Q ⊞ P 
goal: (CategoryTheory.Limits.biprod.braiding' P Q).inv =
  CategoryTheory.Limits.biprod.desc CategoryTheory.Limits.biprod.inr CategoryTheory.Limits.biprod.inl

full_name: CategoryTheory.Limits.biprod.braiding'_eq_braiding
code: theorem biprod.braiding'_eq_braiding {P Q : C} : biprod.braiding' P Q = biprod.braiding P Q 
goal: CategoryTheory.Limits.biprod.braiding' P Q = CategoryTheory.Limits.biprod.braiding P Q

full_name: CategoryTheory.Limits.biprod.braid_natural
code: /-- The braiding isomorphism can be passed through a map by swapping the order. -/
@[reassoc]
theorem biprod.braid_natural {W X Y Z : C} (f : X ⟶ Y) (g : Z ⟶ W) :
    biprod.map f g ≫ (biprod.braiding _ _).hom = (biprod.braiding _ _).hom ≫ biprod.map g f 
goal: CategoryTheory.Limits.biprod.map f g ≫ (CategoryTheory.Limits.biprod.braiding Y W).hom =
  (CategoryTheory.Limits.biprod.braiding X Z).hom ≫ CategoryTheory.Limits.biprod.map g f

full_name: CategoryTheory.Limits.biprod.braiding_map_braiding
code: @[reassoc]
theorem biprod.braiding_map_braiding {W X Y Z : C} (f : W ⟶ Y) (g : X ⟶ Z) :
    (biprod.braiding X W).hom ≫ biprod.map f g ≫ (biprod.braiding Y Z).hom = biprod.map g f 
goal: (CategoryTheory.Limits.biprod.braiding X W).hom ≫
    CategoryTheory.Limits.biprod.map f g ≫ (CategoryTheory.Limits.biprod.braiding Y Z).hom =
  CategoryTheory.Limits.biprod.map g f

full_name: CategoryTheory.Limits.biprod.symmetry'
code: @[reassoc (attr := simp)]
theorem biprod.symmetry' (P Q : C) :
    biprod.lift biprod.snd biprod.fst ≫ biprod.lift biprod.snd biprod.fst = 𝟙 (P ⊞ Q) 
goal: CategoryTheory.Limits.biprod.lift CategoryTheory.Limits.biprod.snd CategoryTheory.Limits.biprod.fst ≫
    CategoryTheory.Limits.biprod.lift CategoryTheory.Limits.biprod.snd CategoryTheory.Limits.biprod.fst =
  𝟙 (P ⊞ Q)

full_name: CategoryTheory.Limits.biprod.symmetry
code: /-- The braiding isomorphism is symmetric. -/
@[reassoc]
theorem biprod.symmetry (P Q : C) :
    (biprod.braiding P Q).hom ≫ (biprod.braiding Q P).hom = 𝟙 _ 
goal: (CategoryTheory.Limits.biprod.braiding P Q).hom ≫ (CategoryTheory.Limits.biprod.braiding Q P).hom = 𝟙 (P ⊞ Q)

full_name: CategoryTheory.Limits.biprod.associator
code: /-- The associator isomorphism which associates a binary biproduct. -/
@[simps]
def biprod.associator (P Q R : C) : (P ⊞ Q) ⊞ R ≅ P ⊞ (Q ⊞ R) 
goal: (P ⊞ Q) ⊞ R ≅ P ⊞ Q ⊞ R

full_name: CategoryTheory.Limits.biprod.associator_hom
code: /-- The associator isomorphism which associates a binary biproduct. -/
@[simps]
def biprod.associator (P Q R : C) : (P ⊞ Q) ⊞ R ≅ P ⊞ (Q ⊞ R) 
goal: (CategoryTheory.Limits.biprod.associator P Q R).hom =
  CategoryTheory.Limits.biprod.lift (CategoryTheory.Limits.biprod.fst ≫ CategoryTheory.Limits.biprod.fst)
    (CategoryTheory.Limits.biprod.lift (CategoryTheory.Limits.biprod.fst ≫ CategoryTheory.Limits.biprod.snd)
      CategoryTheory.Limits.biprod.snd)

full_name: CategoryTheory.Limits.biprod.associator_inv
code: /-- The associator isomorphism which associates a binary biproduct. -/
@[simps]
def biprod.associator (P Q R : C) : (P ⊞ Q) ⊞ R ≅ P ⊞ (Q ⊞ R) 
goal: (CategoryTheory.Limits.biprod.associator P Q R).inv =
  CategoryTheory.Limits.biprod.lift
    (CategoryTheory.Limits.biprod.lift CategoryTheory.Limits.biprod.fst
      (CategoryTheory.Limits.biprod.snd ≫ CategoryTheory.Limits.biprod.fst))
    (CategoryTheory.Limits.biprod.snd ≫ CategoryTheory.Limits.biprod.snd)

full_name: CategoryTheory.Limits.biprod.associator_natural
code: /-- The associator isomorphism can be passed through a map by swapping the order. -/
@[reassoc]
theorem biprod.associator_natural {U V W X Y Z : C} (f : U ⟶ X) (g : V ⟶ Y) (h : W ⟶ Z) :
    biprod.map (biprod.map f g) h ≫ (biprod.associator _ _ _).hom
      = (biprod.associator _ _ _).hom ≫ biprod.map f (biprod.map g h) 
goal: CategoryTheory.Limits.biprod.map (CategoryTheory.Limits.biprod.map f g) h ≫
    (CategoryTheory.Limits.biprod.associator X Y Z).hom =
  (CategoryTheory.Limits.biprod.associator U V W).hom ≫
    CategoryTheory.Limits.biprod.map f (CategoryTheory.Limits.biprod.map g h)

full_name: CategoryTheory.Limits.biprod.associator_inv_natural
code: /-- The associator isomorphism can be passed through a map by swapping the order. -/
@[reassoc]
theorem biprod.associator_inv_natural {U V W X Y Z : C} (f : U ⟶ X) (g : V ⟶ Y) (h : W ⟶ Z) :
    biprod.map f (biprod.map g h) ≫ (biprod.associator _ _ _).inv
      = (biprod.associator _ _ _).inv ≫ biprod.map (biprod.map f g) h 
goal: CategoryTheory.Limits.biprod.map f (CategoryTheory.Limits.biprod.map g h) ≫
    (CategoryTheory.Limits.biprod.associator X Y Z).inv =
  (CategoryTheory.Limits.biprod.associator U V W).inv ≫
    CategoryTheory.Limits.biprod.map (CategoryTheory.Limits.biprod.map f g) h

full_name: CategoryTheory.Indecomposable
code: /-- An object is indecomposable if it cannot be written as the biproduct of two nonzero objects. -/
def Indecomposable (X : C) : Prop 
goal: Prop

full_name: CategoryTheory.isIso_left_of_isIso_biprod_map
code: /-- If
```
(f 0)
(0 g)
```
is invertible, then `f` is invertible.
-/
theorem isIso_left_of_isIso_biprod_map {W X Y Z : C} (f : W ⟶ Y) (g : X ⟶ Z)
    [IsIso (biprod.map f g)] : IsIso f 
goal: CategoryTheory.IsIso f

full_name: CategoryTheory.isIso_right_of_isIso_biprod_map
code: /-- If
```
(f 0)
(0 g)
```
is invertible, then `g` is invertible.
-/
theorem isIso_right_of_isIso_biprod_map {W X Y Z : C} (f : W ⟶ Y) (g : X ⟶ Z)
    [IsIso (biprod.map f g)] : IsIso g 
goal: CategoryTheory.IsIso g