File: Mathlib/CategoryTheory/Preadditive/Biproducts.lean

full_name: CategoryTheory.Limits.isBilimitOfTotal
code: /-- In a preadditive category, we can construct a biproduct for `f : J → C` from
any bicone `b` for `f` satisfying `total : ∑ j : J, b.π j ≫ b.ι j = 𝟙 b.X`.

(That is, such a bicone is a limit cone and a colimit cocone.)
-/
def isBilimitOfTotal {f : J → C} (b : Bicone f) (total : ∑ j : J, b.π j ≫ b.ι j = 𝟙 b.pt) :
    b.IsBilimit 
goal: b.IsBilimit

full_name: CategoryTheory.Limits.IsBilimit.total
code: theorem IsBilimit.total {f : J → C} {b : Bicone f} (i : b.IsBilimit) :
    ∑ j : J, b.π j ≫ b.ι j = 𝟙 b.pt 
goal: ∑ j : J, b.π j ≫ b.ι j = 𝟙 b.pt

full_name: CategoryTheory.Limits.hasBiproduct_of_total
code: /-- In a preadditive category, we can construct a biproduct for `f : J → C` from
any bicone `b` for `f` satisfying `total : ∑ j : J, b.π j ≫ b.ι j = 𝟙 b.X`.

(That is, such a bicone is a limit cone and a colimit cocone.)
-/
theorem hasBiproduct_of_total {f : J → C} (b : Bicone f)
    (total : ∑ j : J, b.π j ≫ b.ι j = 𝟙 b.pt) : HasBiproduct f 
goal: CategoryTheory.Limits.HasBiproduct f

full_name: CategoryTheory.Limits.isBilimitOfIsLimit
code: /-- In a preadditive category, any finite bicone which is a limit cone is in fact a bilimit
    bicone. -/
def isBilimitOfIsLimit {f : J → C} (t : Bicone f) (ht : IsLimit t.toCone) : t.IsBilimit 
goal: t.IsBilimit

full_name: CategoryTheory.Limits.biconeIsBilimitOfLimitConeOfIsLimit
code: /-- We can turn any limit cone over a pair into a bilimit bicone. -/
def biconeIsBilimitOfLimitConeOfIsLimit {f : J → C} {t : Cone (Discrete.functor f)}
    (ht : IsLimit t) : (Bicone.ofLimitCone ht).IsBilimit 
goal: (CategoryTheory.Limits.Bicone.ofLimitCone ht).IsBilimit

full_name: CategoryTheory.Limits.isBilimitOfIsColimit
code: /-- In a preadditive category, any finite bicone which is a colimit cocone is in fact a bilimit
    bicone. -/
def isBilimitOfIsColimit {f : J → C} (t : Bicone f) (ht : IsColimit t.toCocone) : t.IsBilimit 
goal: t.IsBilimit

full_name: CategoryTheory.Limits.biconeIsBilimitOfColimitCoconeOfIsColimit
code: /-- We can turn any limit cone over a pair into a bilimit bicone. -/
def biconeIsBilimitOfColimitCoconeOfIsColimit {f : J → C} {t : Cocone (Discrete.functor f)}
    (ht : IsColimit t) : (Bicone.ofColimitCocone ht).IsBilimit 
goal: (CategoryTheory.Limits.Bicone.ofColimitCocone ht).IsBilimit

full_name: CategoryTheory.Limits.HasBiproduct.of_hasProduct
code: /-- In a preadditive category, if the product over `f : J → C` exists,
    then the biproduct over `f` exists. -/
theorem HasBiproduct.of_hasProduct (f : J → C) [HasProduct f] : HasBiproduct f 
goal: CategoryTheory.Limits.HasBiproduct f

full_name: CategoryTheory.Limits.HasBiproduct.of_hasCoproduct
code: /-- In a preadditive category, if the coproduct over `f : J → C` exists,
    then the biproduct over `f` exists. -/
theorem HasBiproduct.of_hasCoproduct (f : J → C) [HasCoproduct f] : HasBiproduct f 
goal: CategoryTheory.Limits.HasBiproduct f

full_name: CategoryTheory.Limits.HasFiniteBiproducts.of_hasFiniteProducts
code: /-- A preadditive category with finite products has finite biproducts. -/
theorem HasFiniteBiproducts.of_hasFiniteProducts [HasFiniteProducts C] : HasFiniteBiproducts C 
goal: CategoryTheory.Limits.HasFiniteBiproducts C

full_name: CategoryTheory.Limits.HasFiniteBiproducts.of_hasFiniteCoproducts
code: /-- A preadditive category with finite coproducts has finite biproducts. -/
theorem HasFiniteBiproducts.of_hasFiniteCoproducts [HasFiniteCoproducts C] :
    HasFiniteBiproducts C 
goal: CategoryTheory.Limits.HasFiniteBiproducts C

full_name: CategoryTheory.Limits.biproduct.total
code: /-- In any preadditive category, any biproduct satsifies
`∑ j : J, biproduct.π f j ≫ biproduct.ι f j = 𝟙 (⨁ f)`
-/
@[simp]
theorem biproduct.total : ∑ j : J, biproduct.π f j ≫ biproduct.ι f j = 𝟙 (⨁ f) 
goal: ∑ j : J, CategoryTheory.Limits.biproduct.π f j ≫ CategoryTheory.Limits.biproduct.ι f j = 𝟙 (⨁ f)

full_name: CategoryTheory.Limits.biproduct.lift_eq
code: theorem biproduct.lift_eq {T : C} {g : ∀ j, T ⟶ f j} :
    biproduct.lift g = ∑ j, g j ≫ biproduct.ι f j 
goal: CategoryTheory.Limits.biproduct.lift g = ∑ j : J, g j ≫ CategoryTheory.Limits.biproduct.ι f j

full_name: CategoryTheory.Limits.biproduct.desc_eq
code: theorem biproduct.desc_eq {T : C} {g : ∀ j, f j ⟶ T} :
    biproduct.desc g = ∑ j, biproduct.π f j ≫ g j 
goal: CategoryTheory.Limits.biproduct.desc g = ∑ j : J, CategoryTheory.Limits.biproduct.π f j ≫ g j

full_name: CategoryTheory.Limits.biproduct.lift_desc
code: @[reassoc]
theorem biproduct.lift_desc {T U : C} {g : ∀ j, T ⟶ f j} {h : ∀ j, f j ⟶ U} :
    biproduct.lift g ≫ biproduct.desc h = ∑ j : J, g j ≫ h j 
goal: CategoryTheory.Limits.biproduct.lift g ≫ CategoryTheory.Limits.biproduct.desc h = ∑ j : J, g j ≫ h j

full_name: CategoryTheory.Limits.biproduct.map_eq
code: theorem biproduct.map_eq [HasFiniteBiproducts C] {f g : J → C} {h : ∀ j, f j ⟶ g j} :
    biproduct.map h = ∑ j : J, biproduct.π f j ≫ h j ≫ biproduct.ι g j 
goal: CategoryTheory.Limits.biproduct.map h =
  ∑ j : J, CategoryTheory.Limits.biproduct.π f j ≫ h j ≫ CategoryTheory.Limits.biproduct.ι g j

full_name: CategoryTheory.Limits.biproduct.lift_matrix
code: @[reassoc]
theorem biproduct.lift_matrix {K : Type} [Finite K] [HasFiniteBiproducts C] {f : J → C} {g : K → C}
    {P} (x : ∀ j, P ⟶ f j) (m : ∀ j k, f j ⟶ g k) :
    biproduct.lift x ≫ biproduct.matrix m = biproduct.lift fun k => ∑ j, x j ≫ m j k 
goal: CategoryTheory.Limits.biproduct.lift x ≫ CategoryTheory.Limits.biproduct.matrix m =
  CategoryTheory.Limits.biproduct.lift fun k => ∑ j : J, x j ≫ m j k

full_name: CategoryTheory.Limits.biproduct.matrix_desc
code: @[reassoc]
theorem biproduct.matrix_desc [Fintype K] {f : J → C} {g : K → C}
    (m : ∀ j k, f j ⟶ g k) {P} (x : ∀ k, g k ⟶ P) :
    biproduct.matrix m ≫ biproduct.desc x = biproduct.desc fun j => ∑ k, m j k ≫ x k 
goal: CategoryTheory.Limits.biproduct.matrix m ≫ CategoryTheory.Limits.biproduct.desc x =
  CategoryTheory.Limits.biproduct.desc fun j => ∑ k : K, m j k ≫ x k

full_name: CategoryTheory.Limits.biproduct.matrix_map
code: @[reassoc]
theorem biproduct.matrix_map {f : J → C} {g : K → C} {h : K → C} (m : ∀ j k, f j ⟶ g k)
    (n : ∀ k, g k ⟶ h k) :
    biproduct.matrix m ≫ biproduct.map n = biproduct.matrix fun j k => m j k ≫ n k 
goal: CategoryTheory.Limits.biproduct.matrix m ≫ CategoryTheory.Limits.biproduct.map n =
  CategoryTheory.Limits.biproduct.matrix fun j k => m j k ≫ n k

full_name: CategoryTheory.Limits.biproduct.map_matrix
code: @[reassoc]
theorem biproduct.map_matrix {f : J → C} {g : J → C} {h : K → C} (m : ∀ k, f k ⟶ g k)
    (n : ∀ j k, g j ⟶ h k) :
    biproduct.map m ≫ biproduct.matrix n = biproduct.matrix fun j k => m j ≫ n j k 
goal: CategoryTheory.Limits.biproduct.map m ≫ CategoryTheory.Limits.biproduct.matrix n =
  CategoryTheory.Limits.biproduct.matrix fun j k => m j ≫ n j k

full_name: CategoryTheory.Limits.biproduct.reindex_hom
code: /-- Reindex a categorical biproduct via an equivalence of the index types. -/
@[simps]
def biproduct.reindex {β γ : Type} [Finite β] (ε : β ≃ γ)
    (f : γ → C) [HasBiproduct f] [HasBiproduct (f ∘ ε)] : ⨁ f ∘ ε ≅ ⨁ f 
goal: (CategoryTheory.Limits.biproduct.reindex ε f).hom =
  CategoryTheory.Limits.biproduct.desc fun b => CategoryTheory.Limits.biproduct.ι f (ε b)

full_name: CategoryTheory.Limits.biproduct.reindex_inv
code: /-- Reindex a categorical biproduct via an equivalence of the index types. -/
@[simps]
def biproduct.reindex {β γ : Type} [Finite β] (ε : β ≃ γ)
    (f : γ → C) [HasBiproduct f] [HasBiproduct (f ∘ ε)] : ⨁ f ∘ ε ≅ ⨁ f 
goal: (CategoryTheory.Limits.biproduct.reindex ε f).inv =
  CategoryTheory.Limits.biproduct.lift fun b => CategoryTheory.Limits.biproduct.π f (ε b)

full_name: CategoryTheory.Limits.biproduct.reindex
code: /-- Reindex a categorical biproduct via an equivalence of the index types. -/
@[simps]
def biproduct.reindex {β γ : Type} [Finite β] (ε : β ≃ γ)
    (f : γ → C) [HasBiproduct f] [HasBiproduct (f ∘ ε)] : ⨁ f ∘ ε ≅ ⨁ f 
goal: ⨁ f ∘ ⇑ε ≅ ⨁ f

full_name: CategoryTheory.Limits.isBinaryBilimitOfTotal
code: /-- In a preadditive category, we can construct a binary biproduct for `X Y : C` from
any binary bicone `b` satisfying `total : b.fst ≫ b.inl + b.snd ≫ b.inr = 𝟙 b.X`.

(That is, such a bicone is a limit cone and a colimit cocone.)
-/
def isBinaryBilimitOfTotal {X Y : C} (b : BinaryBicone X Y)
    (total : b.fst ≫ b.inl + b.snd ≫ b.inr = 𝟙 b.pt) : b.IsBilimit 
goal: b.IsBilimit

full_name: CategoryTheory.Limits.IsBilimit.binary_total
code: theorem IsBilimit.binary_total {X Y : C} {b : BinaryBicone X Y} (i : b.IsBilimit) :
    b.fst ≫ b.inl + b.snd ≫ b.inr = 𝟙 b.pt 
goal: b.fst ≫ b.inl + b.snd ≫ b.inr = 𝟙 b.pt

full_name: CategoryTheory.Limits.hasBinaryBiproduct_of_total
code: /-- In a preadditive category, we can construct a binary biproduct for `X Y : C` from
any binary bicone `b` satisfying `total : b.fst ≫ b.inl + b.snd ≫ b.inr = 𝟙 b.X`.

(That is, such a bicone is a limit cone and a colimit cocone.)
-/
theorem hasBinaryBiproduct_of_total {X Y : C} (b : BinaryBicone X Y)
    (total : b.fst ≫ b.inl + b.snd ≫ b.inr = 𝟙 b.pt) : HasBinaryBiproduct X Y 
goal: CategoryTheory.Limits.HasBinaryBiproduct X Y

full_name: CategoryTheory.Limits.BinaryBicone.ofLimitCone_inr
code: /-- We can turn any limit cone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofLimitCone {X Y : C} {t : Cone (pair X Y)} (ht : IsLimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofLimitCone ht).inr = ht.lift (CategoryTheory.Limits.BinaryFan.mk 0 (𝟙 Y))

full_name: CategoryTheory.Limits.BinaryBicone.ofLimitCone
code: /-- We can turn any limit cone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofLimitCone {X Y : C} {t : Cone (pair X Y)} (ht : IsLimit t) :
    BinaryBicone X Y 
goal: CategoryTheory.Limits.BinaryBicone X Y

full_name: CategoryTheory.Limits.BinaryBicone.ofLimitCone_fst
code: /-- We can turn any limit cone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofLimitCone {X Y : C} {t : Cone (pair X Y)} (ht : IsLimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofLimitCone ht).fst = t.π.app { as := CategoryTheory.Limits.WalkingPair.left }

full_name: CategoryTheory.Limits.BinaryBicone.ofLimitCone_pt
code: /-- We can turn any limit cone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofLimitCone {X Y : C} {t : Cone (pair X Y)} (ht : IsLimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofLimitCone ht).pt = t.pt

full_name: CategoryTheory.Limits.BinaryBicone.ofLimitCone_inl
code: /-- We can turn any limit cone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofLimitCone {X Y : C} {t : Cone (pair X Y)} (ht : IsLimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofLimitCone ht).inl = ht.lift (CategoryTheory.Limits.BinaryFan.mk (𝟙 X) 0)

full_name: CategoryTheory.Limits.BinaryBicone.ofLimitCone_snd
code: /-- We can turn any limit cone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofLimitCone {X Y : C} {t : Cone (pair X Y)} (ht : IsLimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofLimitCone ht).snd = t.π.app { as := CategoryTheory.Limits.WalkingPair.right }

full_name: CategoryTheory.Limits.inl_of_isLimit
code: theorem inl_of_isLimit {X Y : C} {t : BinaryBicone X Y} (ht : IsLimit t.toCone) :
    t.inl = ht.lift (BinaryFan.mk (𝟙 X) 0) 
goal: t.inl = ht.lift (CategoryTheory.Limits.BinaryFan.mk (𝟙 X) 0)

full_name: CategoryTheory.Limits.inr_of_isLimit
code: theorem inr_of_isLimit {X Y : C} {t : BinaryBicone X Y} (ht : IsLimit t.toCone) :
    t.inr = ht.lift (BinaryFan.mk 0 (𝟙 Y)) 
goal: t.inr = ht.lift (CategoryTheory.Limits.BinaryFan.mk 0 (𝟙 Y))

full_name: CategoryTheory.Limits.isBinaryBilimitOfIsLimit
code: /-- In a preadditive category, any binary bicone which is a limit cone is in fact a bilimit
    bicone. -/
def isBinaryBilimitOfIsLimit {X Y : C} (t : BinaryBicone X Y) (ht : IsLimit t.toCone) :
    t.IsBilimit 
goal: t.IsBilimit

full_name: CategoryTheory.Limits.binaryBiconeIsBilimitOfLimitConeOfIsLimit
code: /-- We can turn any limit cone over a pair into a bilimit bicone. -/
def binaryBiconeIsBilimitOfLimitConeOfIsLimit {X Y : C} {t : Cone (pair X Y)} (ht : IsLimit t) :
    (BinaryBicone.ofLimitCone ht).IsBilimit 
goal: (CategoryTheory.Limits.BinaryBicone.ofLimitCone ht).IsBilimit

full_name: CategoryTheory.Limits.HasBinaryBiproduct.of_hasBinaryProduct
code: /-- In a preadditive category, if the product of `X` and `Y` exists, then the
    binary biproduct of `X` and `Y` exists. -/
theorem HasBinaryBiproduct.of_hasBinaryProduct (X Y : C) [HasBinaryProduct X Y] :
    HasBinaryBiproduct X Y 
goal: CategoryTheory.Limits.HasBinaryBiproduct X Y

full_name: CategoryTheory.Limits.HasBinaryBiproducts.of_hasBinaryProducts
code: /-- In a preadditive category, if all binary products exist, then all binary biproducts exist. -/
theorem HasBinaryBiproducts.of_hasBinaryProducts [HasBinaryProducts C] : HasBinaryBiproducts C 
goal: CategoryTheory.Limits.HasBinaryBiproducts C

full_name: CategoryTheory.Limits.BinaryBicone.ofColimitCocone_pt
code: /-- We can turn any colimit cocone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofColimitCocone {X Y : C} {t : Cocone (pair X Y)} (ht : IsColimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofColimitCocone ht).pt = t.pt

full_name: CategoryTheory.Limits.BinaryBicone.ofColimitCocone_snd
code: /-- We can turn any colimit cocone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofColimitCocone {X Y : C} {t : Cocone (pair X Y)} (ht : IsColimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofColimitCocone ht).snd = ht.desc (CategoryTheory.Limits.BinaryCofan.mk 0 (𝟙 Y))

full_name: CategoryTheory.Limits.BinaryBicone.ofColimitCocone_inr
code: /-- We can turn any colimit cocone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofColimitCocone {X Y : C} {t : Cocone (pair X Y)} (ht : IsColimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofColimitCocone ht).inr = t.ι.app { as := CategoryTheory.Limits.WalkingPair.right }

full_name: CategoryTheory.Limits.BinaryBicone.ofColimitCocone_fst
code: /-- We can turn any colimit cocone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofColimitCocone {X Y : C} {t : Cocone (pair X Y)} (ht : IsColimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofColimitCocone ht).fst = ht.desc (CategoryTheory.Limits.BinaryCofan.mk (𝟙 X) 0)

full_name: CategoryTheory.Limits.BinaryBicone.ofColimitCocone_inl
code: /-- We can turn any colimit cocone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofColimitCocone {X Y : C} {t : Cocone (pair X Y)} (ht : IsColimit t) :
    BinaryBicone X Y 
goal: (CategoryTheory.Limits.BinaryBicone.ofColimitCocone ht).inl = t.ι.app { as := CategoryTheory.Limits.WalkingPair.left }

full_name: CategoryTheory.Limits.BinaryBicone.ofColimitCocone
code: /-- We can turn any colimit cocone over a pair into a bicone. -/
@[simps]
def BinaryBicone.ofColimitCocone {X Y : C} {t : Cocone (pair X Y)} (ht : IsColimit t) :
    BinaryBicone X Y 
goal: CategoryTheory.Limits.BinaryBicone X Y

full_name: CategoryTheory.Limits.fst_of_isColimit
code: theorem fst_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.fst = ht.desc (BinaryCofan.mk (𝟙 X) 0) 
goal: t.fst = ht.desc (CategoryTheory.Limits.BinaryCofan.mk (𝟙 X) 0)

full_name: CategoryTheory.Limits.snd_of_isColimit
code: theorem snd_of_isColimit {X Y : C} {t : BinaryBicone X Y} (ht : IsColimit t.toCocone) :
    t.snd = ht.desc (BinaryCofan.mk 0 (𝟙 Y)) 
goal: t.snd = ht.desc (CategoryTheory.Limits.BinaryCofan.mk 0 (𝟙 Y))

full_name: CategoryTheory.Limits.isBinaryBilimitOfIsColimit
code: /-- In a preadditive category, any binary bicone which is a colimit cocone is in fact a
    bilimit bicone. -/
def isBinaryBilimitOfIsColimit {X Y : C} (t : BinaryBicone X Y) (ht : IsColimit t.toCocone) :
    t.IsBilimit 
goal: t.IsBilimit

full_name: CategoryTheory.Limits.binaryBiconeIsBilimitOfColimitCoconeOfIsColimit
code: /-- We can turn any colimit cocone over a pair into a bilimit bicone. -/
def binaryBiconeIsBilimitOfColimitCoconeOfIsColimit {X Y : C} {t : Cocone (pair X Y)}
    (ht : IsColimit t) : (BinaryBicone.ofColimitCocone ht).IsBilimit 
goal: (CategoryTheory.Limits.BinaryBicone.ofColimitCocone ht).IsBilimit

full_name: CategoryTheory.Limits.HasBinaryBiproduct.of_hasBinaryCoproduct
code: /-- In a preadditive category, if the coproduct of `X` and `Y` exists, then the
    binary biproduct of `X` and `Y` exists. -/
theorem HasBinaryBiproduct.of_hasBinaryCoproduct (X Y : C) [HasBinaryCoproduct X Y] :
    HasBinaryBiproduct X Y 
goal: CategoryTheory.Limits.HasBinaryBiproduct X Y

full_name: CategoryTheory.Limits.HasBinaryBiproducts.of_hasBinaryCoproducts
code: /-- In a preadditive category, if all binary coproducts exist, then all binary biproducts exist. -/
theorem HasBinaryBiproducts.of_hasBinaryCoproducts [HasBinaryCoproducts C] :
    HasBinaryBiproducts C 
goal: CategoryTheory.Limits.HasBinaryBiproducts C

full_name: CategoryTheory.Limits.biprod.total
code: /-- In any preadditive category, any binary biproduct satsifies
`biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y)`.
-/
@[simp]
theorem biprod.total : biprod.fst ≫ biprod.inl + biprod.snd ≫ biprod.inr = 𝟙 (X ⊞ Y) 
goal: CategoryTheory.Limits.biprod.fst ≫ CategoryTheory.Limits.biprod.inl +
    CategoryTheory.Limits.biprod.snd ≫ CategoryTheory.Limits.biprod.inr =
  𝟙 (X ⊞ Y)

full_name: CategoryTheory.Limits.biprod.lift_eq
code: theorem biprod.lift_eq {T : C} {f : T ⟶ X} {g : T ⟶ Y} :
    biprod.lift f g = f ≫ biprod.inl + g ≫ biprod.inr 
goal: CategoryTheory.Limits.biprod.lift f g = f ≫ CategoryTheory.Limits.biprod.inl + g ≫ CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.biprod.desc_eq
code: theorem biprod.desc_eq {T : C} {f : X ⟶ T} {g : Y ⟶ T} :
    biprod.desc f g = biprod.fst ≫ f + biprod.snd ≫ g 
goal: CategoryTheory.Limits.biprod.desc f g = CategoryTheory.Limits.biprod.fst ≫ f + CategoryTheory.Limits.biprod.snd ≫ g

full_name: CategoryTheory.Limits.biprod.lift_desc
code: @[reassoc (attr := simp)]
theorem biprod.lift_desc {T U : C} {f : T ⟶ X} {g : T ⟶ Y} {h : X ⟶ U} {i : Y ⟶ U} :
    biprod.lift f g ≫ biprod.desc h i = f ≫ h + g ≫ i 
goal: CategoryTheory.Limits.biprod.lift f g ≫ CategoryTheory.Limits.biprod.desc h i = f ≫ h + g ≫ i

full_name: CategoryTheory.Limits.biprod.map_eq
code: theorem biprod.map_eq [HasBinaryBiproducts C] {W X Y Z : C} {f : W ⟶ Y} {g : X ⟶ Z} :
    biprod.map f g = biprod.fst ≫ f ≫ biprod.inl + biprod.snd ≫ g ≫ biprod.inr 
goal: CategoryTheory.Limits.biprod.map f g =
  CategoryTheory.Limits.biprod.fst ≫ f ≫ CategoryTheory.Limits.biprod.inl +
    CategoryTheory.Limits.biprod.snd ≫ g ≫ CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel_pt
code: /-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel i).pt = Y

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel_fst
code: /-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel i).fst = CategoryTheory.retraction f

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel_inr
code: /-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel i).inr =
  let c' := CategoryTheory.Limits.CokernelCofork.ofπ (CategoryTheory.Limits.Cofork.π c) ⋯;
  let i' := CategoryTheory.Limits.isCokernelEpiComp i (CategoryTheory.retraction f) ⋯;
  let i'' := CategoryTheory.Preadditive.isColimitCoforkOfCokernelCofork i';
  (CategoryTheory.Limits.splitEpiOfIdempotentOfIsColimitCofork C ⋯ i'').section_

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel_snd
code: /-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel i).snd = CategoryTheory.Limits.Cofork.π c

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel
code: /-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt 
goal: CategoryTheory.Limits.BinaryBicone X c.pt

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel_inl
code: /-- Every split mono `f` with a cokernel induces a binary bicone with `f` as its `inl` and
the cokernel map as its `snd`.
We will show in `is_bilimit_binary_bicone_of_split_mono_of_cokernel` that this binary bicone is in
fact already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f] {c : CokernelCofork f}
    (i : IsColimit c) : BinaryBicone X c.pt 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel i).inl = f

full_name: CategoryTheory.Limits.isBilimitBinaryBiconeOfIsSplitMonoOfCokernel
code: /-- The bicone constructed in `binaryBiconeOfSplitMonoOfCokernel` is a bilimit.
This is a version of the splitting lemma that holds in all preadditive categories. -/
def isBilimitBinaryBiconeOfIsSplitMonoOfCokernel {X Y : C} {f : X ⟶ Y} [IsSplitMono f]
    {c : CokernelCofork f} (i : IsColimit c) : (binaryBiconeOfIsSplitMonoOfCokernel i).IsBilimit 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitMonoOfCokernel i).IsBilimit

full_name: CategoryTheory.Limits.BinaryBicone.isBilimitOfKernelInl
code: /-- If `b` is a binary bicone such that `b.inl` is a kernel of `b.snd`, then `b` is a bilimit
    bicone. -/
def BinaryBicone.isBilimitOfKernelInl {X Y : C} (b : BinaryBicone X Y)
    (hb : IsLimit b.sndKernelFork) : b.IsBilimit 
goal: b.IsBilimit

full_name: CategoryTheory.Limits.BinaryBicone.isBilimitOfKernelInr
code: /-- If `b` is a binary bicone such that `b.inr` is a kernel of `b.fst`, then `b` is a bilimit
    bicone. -/
def BinaryBicone.isBilimitOfKernelInr {X Y : C} (b : BinaryBicone X Y)
    (hb : IsLimit b.fstKernelFork) : b.IsBilimit 
goal: b.IsBilimit

full_name: CategoryTheory.Limits.BinaryBicone.isBilimitOfCokernelFst
code: /-- If `b` is a binary bicone such that `b.fst` is a cokernel of `b.inr`, then `b` is a bilimit
    bicone. -/
def BinaryBicone.isBilimitOfCokernelFst {X Y : C} (b : BinaryBicone X Y)
    (hb : IsColimit b.inrCokernelCofork) : b.IsBilimit 
goal: b.IsBilimit

full_name: CategoryTheory.Limits.BinaryBicone.isBilimitOfCokernelSnd
code: /-- If `b` is a binary bicone such that `b.snd` is a cokernel of `b.inl`, then `b` is a bilimit
    bicone. -/
def BinaryBicone.isBilimitOfCokernelSnd {X Y : C} (b : BinaryBicone X Y)
    (hb : IsColimit b.inlCokernelCofork) : b.IsBilimit 
goal: b.IsBilimit

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel_pt
code: /-- Every split epi `f` with a kernel induces a binary bicone with `f` as its `snd` and
the kernel map as its `inl`.
We will show in `binary_bicone_of_is_split_mono_of_cokernel` that this binary bicone is in fact
already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f] {c : KernelFork f}
    (i : IsLimit c) : BinaryBicone c.pt Y 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel i).pt = X

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel_inr
code: /-- Every split epi `f` with a kernel induces a binary bicone with `f` as its `snd` and
the kernel map as its `inl`.
We will show in `binary_bicone_of_is_split_mono_of_cokernel` that this binary bicone is in fact
already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f] {c : KernelFork f}
    (i : IsLimit c) : BinaryBicone c.pt Y 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel i).inr = CategoryTheory.section_ f

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel
code: /-- Every split epi `f` with a kernel induces a binary bicone with `f` as its `snd` and
the kernel map as its `inl`.
We will show in `binary_bicone_of_is_split_mono_of_cokernel` that this binary bicone is in fact
already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f] {c : KernelFork f}
    (i : IsLimit c) : BinaryBicone c.pt Y 
goal: CategoryTheory.Limits.BinaryBicone c.pt Y

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel_snd
code: /-- Every split epi `f` with a kernel induces a binary bicone with `f` as its `snd` and
the kernel map as its `inl`.
We will show in `binary_bicone_of_is_split_mono_of_cokernel` that this binary bicone is in fact
already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f] {c : KernelFork f}
    (i : IsLimit c) : BinaryBicone c.pt Y 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel i).snd = f

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel_inl
code: /-- Every split epi `f` with a kernel induces a binary bicone with `f` as its `snd` and
the kernel map as its `inl`.
We will show in `binary_bicone_of_is_split_mono_of_cokernel` that this binary bicone is in fact
already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f] {c : KernelFork f}
    (i : IsLimit c) : BinaryBicone c.pt Y 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel i).inl = CategoryTheory.Limits.Fork.ι c

full_name: CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel_fst
code: /-- Every split epi `f` with a kernel induces a binary bicone with `f` as its `snd` and
the kernel map as its `inl`.
We will show in `binary_bicone_of_is_split_mono_of_cokernel` that this binary bicone is in fact
already a biproduct. -/
@[simps]
def binaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f] {c : KernelFork f}
    (i : IsLimit c) : BinaryBicone c.pt Y 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel i).fst =
  let c' := CategoryTheory.Limits.KernelFork.ofι (CategoryTheory.Limits.Fork.ι c) ⋯;
  let i' := CategoryTheory.Limits.isKernelCompMono i (CategoryTheory.section_ f) ⋯;
  let i'' := CategoryTheory.Preadditive.isLimitForkOfKernelFork i';
  (CategoryTheory.Limits.splitMonoOfIdempotentOfIsLimitFork C ⋯ i'').retraction

full_name: CategoryTheory.Limits.isBilimitBinaryBiconeOfIsSplitEpiOfKernel
code: /-- The bicone constructed in `binaryBiconeOfIsSplitEpiOfKernel` is a bilimit.
This is a version of the splitting lemma that holds in all preadditive categories. -/
def isBilimitBinaryBiconeOfIsSplitEpiOfKernel {X Y : C} {f : X ⟶ Y} [IsSplitEpi f]
    {c : KernelFork f} (i : IsLimit c) : (binaryBiconeOfIsSplitEpiOfKernel i).IsBilimit 
goal: (CategoryTheory.Limits.binaryBiconeOfIsSplitEpiOfKernel i).IsBilimit

full_name: CategoryTheory.Limits.biprod.add_eq_lift_id_desc
code: /-- The existence of binary biproducts implies that there is at most one preadditive structure. -/
theorem biprod.add_eq_lift_id_desc [HasBinaryBiproduct X X] :
    f + g = biprod.lift (𝟙 X) (𝟙 X) ≫ biprod.desc f g 
goal: f + g = CategoryTheory.Limits.biprod.lift (𝟙 X) (𝟙 X) ≫ CategoryTheory.Limits.biprod.desc f g

full_name: CategoryTheory.Limits.biprod.add_eq_lift_desc_id
code: /-- The existence of binary biproducts implies that there is at most one preadditive structure. -/
theorem biprod.add_eq_lift_desc_id [HasBinaryBiproduct Y Y] :
    f + g = biprod.lift f g ≫ biprod.desc (𝟙 Y) (𝟙 Y) 
goal: f + g = CategoryTheory.Limits.biprod.lift f g ≫ CategoryTheory.Limits.biprod.desc (𝟙 Y) (𝟙 Y)

full_name: CategoryTheory.subsingleton_preadditive_of_hasBinaryBiproducts
code: /-- The existence of binary biproducts implies that there is at most one preadditive structure. -/
instance subsingleton_preadditive_of_hasBinaryBiproducts {C : Type u} [Category.{v} C]
    [HasZeroMorphisms C] [HasBinaryBiproducts C] : Subsingleton (Preadditive C) 
goal: Subsingleton (CategoryTheory.Preadditive C)

full_name: CategoryTheory.Biprod.ofComponents
code: /-- The "matrix" morphism `X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂` with specified components.
-/
def Biprod.ofComponents : X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂ 
goal: X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂

full_name: CategoryTheory.Biprod.inl_ofComponents
code: @[simp]
theorem Biprod.inl_ofComponents :
    biprod.inl ≫ Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ = f₁₁ ≫ biprod.inl + f₁₂ ≫ biprod.inr 
goal: CategoryTheory.Limits.biprod.inl ≫ CategoryTheory.Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ =
  f₁₁ ≫ CategoryTheory.Limits.biprod.inl + f₁₂ ≫ CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Biprod.inr_ofComponents
code: @[simp]
theorem Biprod.inr_ofComponents :
    biprod.inr ≫ Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ = f₂₁ ≫ biprod.inl + f₂₂ ≫ biprod.inr 
goal: CategoryTheory.Limits.biprod.inr ≫ CategoryTheory.Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ =
  f₂₁ ≫ CategoryTheory.Limits.biprod.inl + f₂₂ ≫ CategoryTheory.Limits.biprod.inr

full_name: CategoryTheory.Biprod.ofComponents_fst
code: @[simp]
theorem Biprod.ofComponents_fst :
    Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ biprod.fst = biprod.fst ≫ f₁₁ + biprod.snd ≫ f₂₁ 
goal: CategoryTheory.Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ CategoryTheory.Limits.biprod.fst =
  CategoryTheory.Limits.biprod.fst ≫ f₁₁ + CategoryTheory.Limits.biprod.snd ≫ f₂₁

full_name: CategoryTheory.Biprod.ofComponents_snd
code: @[simp]
theorem Biprod.ofComponents_snd :
    Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ biprod.snd = biprod.fst ≫ f₁₂ + biprod.snd ≫ f₂₂ 
goal: CategoryTheory.Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ CategoryTheory.Limits.biprod.snd =
  CategoryTheory.Limits.biprod.fst ≫ f₁₂ + CategoryTheory.Limits.biprod.snd ≫ f₂₂

full_name: CategoryTheory.Biprod.ofComponents_eq
code: @[simp]
theorem Biprod.ofComponents_eq (f : X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂) :
    Biprod.ofComponents (biprod.inl ≫ f ≫ biprod.fst) (biprod.inl ≫ f ≫ biprod.snd)
        (biprod.inr ≫ f ≫ biprod.fst) (biprod.inr ≫ f ≫ biprod.snd) =
      f 
goal: CategoryTheory.Biprod.ofComponents (CategoryTheory.Limits.biprod.inl ≫ f ≫ CategoryTheory.Limits.biprod.fst)
    (CategoryTheory.Limits.biprod.inl ≫ f ≫ CategoryTheory.Limits.biprod.snd)
    (CategoryTheory.Limits.biprod.inr ≫ f ≫ CategoryTheory.Limits.biprod.fst)
    (CategoryTheory.Limits.biprod.inr ≫ f ≫ CategoryTheory.Limits.biprod.snd) =
  f

full_name: CategoryTheory.Biprod.ofComponents_comp
code: @[simp]
theorem Biprod.ofComponents_comp {X₁ X₂ Y₁ Y₂ Z₁ Z₂ : C} (f₁₁ : X₁ ⟶ Y₁) (f₁₂ : X₁ ⟶ Y₂)
    (f₂₁ : X₂ ⟶ Y₁) (f₂₂ : X₂ ⟶ Y₂) (g₁₁ : Y₁ ⟶ Z₁) (g₁₂ : Y₁ ⟶ Z₂) (g₂₁ : Y₂ ⟶ Z₁)
    (g₂₂ : Y₂ ⟶ Z₂) :
    Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ Biprod.ofComponents g₁₁ g₁₂ g₂₁ g₂₂ =
      Biprod.ofComponents (f₁₁ ≫ g₁₁ + f₁₂ ≫ g₂₁) (f₁₁ ≫ g₁₂ + f₁₂ ≫ g₂₂) (f₂₁ ≫ g₁₁ + f₂₂ ≫ g₂₁)
        (f₂₁ ≫ g₁₂ + f₂₂ ≫ g₂₂) 
goal: CategoryTheory.Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ CategoryTheory.Biprod.ofComponents g₁₁ g₁₂ g₂₁ g₂₂ =
  CategoryTheory.Biprod.ofComponents (f₁₁ ≫ g₁₁ + f₁₂ ≫ g₂₁) (f₁₁ ≫ g₁₂ + f₁₂ ≫ g₂₂) (f₂₁ ≫ g₁₁ + f₂₂ ≫ g₂₁)
    (f₂₁ ≫ g₁₂ + f₂₂ ≫ g₂₂)

full_name: CategoryTheory.Biprod.unipotentUpper_inv
code: /-- The unipotent upper triangular matrix
```
(1 r)
(0 1)
```
as an isomorphism.
-/
@[simps]
def Biprod.unipotentUpper {X₁ X₂ : C} (r : X₁ ⟶ X₂) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ 
goal: (CategoryTheory.Biprod.unipotentUpper r).inv = CategoryTheory.Biprod.ofComponents (𝟙 X₁) (-r) 0 (𝟙 X₂)

full_name: CategoryTheory.Biprod.unipotentUpper_hom
code: /-- The unipotent upper triangular matrix
```
(1 r)
(0 1)
```
as an isomorphism.
-/
@[simps]
def Biprod.unipotentUpper {X₁ X₂ : C} (r : X₁ ⟶ X₂) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ 
goal: (CategoryTheory.Biprod.unipotentUpper r).hom = CategoryTheory.Biprod.ofComponents (𝟙 X₁) r 0 (𝟙 X₂)

full_name: CategoryTheory.Biprod.unipotentUpper
code: /-- The unipotent upper triangular matrix
```
(1 r)
(0 1)
```
as an isomorphism.
-/
@[simps]
def Biprod.unipotentUpper {X₁ X₂ : C} (r : X₁ ⟶ X₂) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ 
goal: X₁ ⊞ X₂ ≅ X₁ ⊞ X₂

full_name: CategoryTheory.Biprod.unipotentLower
code: /-- The unipotent lower triangular matrix
```
(1 0)
(r 1)
```
as an isomorphism.
-/
@[simps]
def Biprod.unipotentLower {X₁ X₂ : C} (r : X₂ ⟶ X₁) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ 
goal: X₁ ⊞ X₂ ≅ X₁ ⊞ X₂

full_name: CategoryTheory.Biprod.unipotentLower_inv
code: /-- The unipotent lower triangular matrix
```
(1 0)
(r 1)
```
as an isomorphism.
-/
@[simps]
def Biprod.unipotentLower {X₁ X₂ : C} (r : X₂ ⟶ X₁) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ 
goal: (CategoryTheory.Biprod.unipotentLower r).inv = CategoryTheory.Biprod.ofComponents (𝟙 X₁) 0 (-r) (𝟙 X₂)

full_name: CategoryTheory.Biprod.unipotentLower_hom
code: /-- The unipotent lower triangular matrix
```
(1 0)
(r 1)
```
as an isomorphism.
-/
@[simps]
def Biprod.unipotentLower {X₁ X₂ : C} (r : X₂ ⟶ X₁) : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂ 
goal: (CategoryTheory.Biprod.unipotentLower r).hom = CategoryTheory.Biprod.ofComponents (𝟙 X₁) 0 r (𝟙 X₂)

full_name: CategoryTheory.Biprod.gaussian'
code: /-- If `f` is a morphism `X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism,
then we can construct isomorphisms `L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂` and `R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂`
so that `L.hom ≫ g ≫ R.hom` is diagonal (with `X₁ ⟶ Y₁` component still `f`),
via Gaussian elimination.

(This is the version of `Biprod.gaussian` written in terms of components.)
-/
def Biprod.gaussian' [IsIso f₁₁] :
    Σ' (L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂) (R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂) (g₂₂ : X₂ ⟶ Y₂),
      L.hom ≫ Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ R.hom = biprod.map f₁₁ g₂₂ 
goal: (L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂) ×'
  (R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂) ×'
    (g₂₂ : X₂ ⟶ Y₂) ×'
      L.hom ≫ CategoryTheory.Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂ ≫ R.hom = CategoryTheory.Limits.biprod.map f₁₁ g₂₂

full_name: CategoryTheory.Biprod.gaussian
code: /-- If `f` is a morphism `X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism,
then we can construct isomorphisms `L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂` and `R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂`
so that `L.hom ≫ g ≫ R.hom` is diagonal (with `X₁ ⟶ Y₁` component still `f`),
via Gaussian elimination.
-/
def Biprod.gaussian (f : X₁ ⊞ X₂ ⟶ Y₁ ⊞ Y₂) [IsIso (biprod.inl ≫ f ≫ biprod.fst)] :
    Σ' (L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂) (R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂) (g₂₂ : X₂ ⟶ Y₂),
      L.hom ≫ f ≫ R.hom = biprod.map (biprod.inl ≫ f ≫ biprod.fst) g₂₂ 
goal: (L : X₁ ⊞ X₂ ≅ X₁ ⊞ X₂) ×'
  (R : Y₁ ⊞ Y₂ ≅ Y₁ ⊞ Y₂) ×'
    (g₂₂ : X₂ ⟶ Y₂) ×'
      L.hom ≫ f ≫ R.hom =
        CategoryTheory.Limits.biprod.map (CategoryTheory.Limits.biprod.inl ≫ f ≫ CategoryTheory.Limits.biprod.fst) g₂₂

full_name: CategoryTheory.Biprod.isoElim'
code: /-- If `X₁ ⊞ X₂ ≅ Y₁ ⊞ Y₂` via a two-by-two matrix whose `X₁ ⟶ Y₁` entry is an isomorphism,
then we can construct an isomorphism `X₂ ≅ Y₂`, via Gaussian elimination.
-/
def Biprod.isoElim' [IsIso f₁₁] [IsIso (Biprod.ofComponents f₁₁ f₁₂ f₂₁ f₂₂)] : X₂ ≅ Y₂ 
goal: X₂ ≅ Y₂

full_name: CategoryTheory.Biprod.isoElim
code: /-- If `f` is an isomorphism `X₁ ⊞ X₂ ≅ Y₁ ⊞ Y₂` whose `X₁ ⟶ Y₁` entry is an isomorphism,
then we can construct an isomorphism `X₂ ≅ Y₂`, via Gaussian elimination.
-/
def Biprod.isoElim (f : X₁ ⊞ X₂ ≅ Y₁ ⊞ Y₂) [IsIso (biprod.inl ≫ f.hom ≫ biprod.fst)] : X₂ ≅ Y₂ 
goal: X₂ ≅ Y₂

full_name: CategoryTheory.Biprod.column_nonzero_of_iso
code: theorem Biprod.column_nonzero_of_iso {W X Y Z : C} (f : W ⊞ X ⟶ Y ⊞ Z) [IsIso f] :
    𝟙 W = 0 ∨ biprod.inl ≫ f ≫ biprod.fst ≠ 0 ∨ biprod.inl ≫ f ≫ biprod.snd ≠ 0 
goal: 𝟙 W = 0 ∨
  CategoryTheory.Limits.biprod.inl ≫ f ≫ CategoryTheory.Limits.biprod.fst ≠ 0 ∨
    CategoryTheory.Limits.biprod.inl ≫ f ≫ CategoryTheory.Limits.biprod.snd ≠ 0

full_name: CategoryTheory.Biproduct.column_nonzero_of_iso'
code: theorem Biproduct.column_nonzero_of_iso' {σ τ : Type} [Finite τ] {S : σ → C} [HasBiproduct S]
    {T : τ → C} [HasBiproduct T] (s : σ) (f : ⨁ S ⟶ ⨁ T) [IsIso f] :
    (∀ t : τ, biproduct.ι S s ≫ f ≫ biproduct.π T t = 0) → 𝟙 (S s) = 0 
goal: (∀ (t : τ), CategoryTheory.Limits.biproduct.ι S s ≫ f ≫ CategoryTheory.Limits.biproduct.π T t = 0) → 𝟙 (S s) = 0

full_name: CategoryTheory.Biproduct.columnNonzeroOfIso
code: /-- If `f : ⨁ S ⟶ ⨁ T` is an isomorphism, and `s` is a non-trivial summand of the source,
then there is some `t` in the target so that the `s, t` matrix entry of `f` is nonzero.
-/
def Biproduct.columnNonzeroOfIso {σ τ : Type} [Fintype τ] {S : σ → C} [HasBiproduct S] {T : τ → C}
    [HasBiproduct T] (s : σ) (nz : 𝟙 (S s) ≠ 0) (f : ⨁ S ⟶ ⨁ T) [IsIso f] :
    Trunc (Σ't : τ, biproduct.ι S s ≫ f ≫ biproduct.π T t ≠ 0) 
goal: Trunc ((t : τ) ×' CategoryTheory.Limits.biproduct.ι S s ≫ f ≫ CategoryTheory.Limits.biproduct.π T t ≠ 0)

full_name: CategoryTheory.Limits.preservesProductOfPreservesBiproduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite biproducts
    preserves finite products. -/
def preservesProductOfPreservesBiproduct {f : J → C} [PreservesBiproduct f F] :
    PreservesLimit (Discrete.functor f) F 
goal: CategoryTheory.Limits.PreservesLimit (CategoryTheory.Discrete.functor f) F

full_name: CategoryTheory.Limits.preservesProductsOfShapeOfPreservesBiproductsOfShape
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite biproducts
    preserves finite products. -/
def preservesProductsOfShapeOfPreservesBiproductsOfShape [PreservesBiproductsOfShape J F] :
    PreservesLimitsOfShape (Discrete J) F 
goal: CategoryTheory.Limits.PreservesLimitsOfShape (CategoryTheory.Discrete J) F

full_name: CategoryTheory.Limits.preservesBiproductOfPreservesProduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite products
    preserves finite biproducts. -/
def preservesBiproductOfPreservesProduct {f : J → C} [PreservesLimit (Discrete.functor f) F] :
    PreservesBiproduct f F 
goal: CategoryTheory.Limits.PreservesBiproduct f F

full_name: CategoryTheory.Limits.preservesBiproductOfMonoBiproductComparison
code: /-- If the (product-like) biproduct comparison for `F` and `f` is a monomorphism, then `F`
    preserves the biproduct of `f`. For the converse, see `mapBiproduct`. -/
def preservesBiproductOfMonoBiproductComparison {f : J → C} [HasBiproduct f]
    [HasBiproduct (F.obj ∘ f)] [Mono (biproductComparison F f)] : PreservesBiproduct f F 
goal: CategoryTheory.Limits.PreservesBiproduct f F

full_name: CategoryTheory.Limits.preservesBiproductOfEpiBiproductComparison'
code: /-- If the (coproduct-like) biproduct comparison for `F` and `f` is an epimorphism, then `F`
    preserves the biproduct of `F` and `f`. For the converse, see `mapBiproduct`. -/
def preservesBiproductOfEpiBiproductComparison' {f : J → C} [HasBiproduct f]
    [HasBiproduct (F.obj ∘ f)] [Epi (biproductComparison' F f)] : PreservesBiproduct f F 
goal: CategoryTheory.Limits.PreservesBiproduct f F

full_name: CategoryTheory.Limits.preservesBiproductsOfShapeOfPreservesProductsOfShape
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite products
    preserves finite biproducts. -/
def preservesBiproductsOfShapeOfPreservesProductsOfShape [PreservesLimitsOfShape (Discrete J) F] :
    PreservesBiproductsOfShape J F 
goal: CategoryTheory.Limits.PreservesBiproductsOfShape J F

full_name: CategoryTheory.Limits.preservesCoproductOfPreservesBiproduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite biproducts
    preserves finite coproducts. -/
def preservesCoproductOfPreservesBiproduct {f : J → C} [PreservesBiproduct f F] :
    PreservesColimit (Discrete.functor f) F 
goal: CategoryTheory.Limits.PreservesColimit (CategoryTheory.Discrete.functor f) F

full_name: CategoryTheory.Limits.preservesCoproductsOfShapeOfPreservesBiproductsOfShape
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite biproducts
    preserves finite coproducts. -/
def preservesCoproductsOfShapeOfPreservesBiproductsOfShape [PreservesBiproductsOfShape J F] :
    PreservesColimitsOfShape (Discrete J) F 
goal: CategoryTheory.Limits.PreservesColimitsOfShape (CategoryTheory.Discrete J) F

full_name: CategoryTheory.Limits.preservesBiproductOfPreservesCoproduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite coproducts
    preserves finite biproducts. -/
def preservesBiproductOfPreservesCoproduct {f : J → C} [PreservesColimit (Discrete.functor f) F] :
    PreservesBiproduct f F 
goal: CategoryTheory.Limits.PreservesBiproduct f F

full_name: CategoryTheory.Limits.preservesBiproductsOfShapeOfPreservesCoproductsOfShape
code: /-- A functor between preadditive categories that preserves (zero morphisms and) finite coproducts
    preserves finite biproducts. -/
def preservesBiproductsOfShapeOfPreservesCoproductsOfShape
    [PreservesColimitsOfShape (Discrete J) F] : PreservesBiproductsOfShape J F 
goal: CategoryTheory.Limits.PreservesBiproductsOfShape J F

full_name: CategoryTheory.Limits.preservesBinaryProductOfPreservesBinaryBiproduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary biproducts
    preserves binary products. -/
def preservesBinaryProductOfPreservesBinaryBiproduct {X Y : C} [PreservesBinaryBiproduct X Y F] :
    PreservesLimit (pair X Y) F 
goal: CategoryTheory.Limits.PreservesLimit (CategoryTheory.Limits.pair X Y) F

full_name: CategoryTheory.Limits.preservesBinaryProductsOfPreservesBinaryBiproducts
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary biproducts
    preserves binary products. -/
def preservesBinaryProductsOfPreservesBinaryBiproducts [PreservesBinaryBiproducts F] :
    PreservesLimitsOfShape (Discrete WalkingPair) F 
goal: CategoryTheory.Limits.PreservesLimitsOfShape (CategoryTheory.Discrete CategoryTheory.Limits.WalkingPair) F

full_name: CategoryTheory.Limits.preservesBinaryBiproductOfPreservesBinaryProduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary products
    preserves binary biproducts. -/
def preservesBinaryBiproductOfPreservesBinaryProduct {X Y : C} [PreservesLimit (pair X Y) F] :
    PreservesBinaryBiproduct X Y F 
goal: CategoryTheory.Limits.PreservesBinaryBiproduct X Y F

full_name: CategoryTheory.Limits.preservesBinaryBiproductOfMonoBiprodComparison
code: /-- If the (product-like) biproduct comparison for `F`, `X` and `Y` is a monomorphism, then
    `F` preserves the biproduct of `X` and `Y`. For the converse, see `map_biprod`. -/
def preservesBinaryBiproductOfMonoBiprodComparison {X Y : C} [HasBinaryBiproduct X Y]
    [HasBinaryBiproduct (F.obj X) (F.obj Y)] [Mono (biprodComparison F X Y)] :
    PreservesBinaryBiproduct X Y F 
goal: CategoryTheory.Limits.PreservesBinaryBiproduct X Y F

full_name: CategoryTheory.Limits.preservesBinaryBiproductOfEpiBiprodComparison'
code: /-- If the (coproduct-like) biproduct comparison for `F`, `X` and `Y` is an epimorphism, then
    `F` preserves the biproduct of `X` and `Y`. For the converse, see `mapBiprod`. -/
def preservesBinaryBiproductOfEpiBiprodComparison' {X Y : C} [HasBinaryBiproduct X Y]
    [HasBinaryBiproduct (F.obj X) (F.obj Y)] [Epi (biprodComparison' F X Y)] :
    PreservesBinaryBiproduct X Y F 
goal: CategoryTheory.Limits.PreservesBinaryBiproduct X Y F

full_name: CategoryTheory.Limits.preservesBinaryBiproductsOfPreservesBinaryProducts
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary products
    preserves binary biproducts. -/
def preservesBinaryBiproductsOfPreservesBinaryProducts
    [PreservesLimitsOfShape (Discrete WalkingPair) F] : PreservesBinaryBiproducts F 
goal: CategoryTheory.Limits.PreservesBinaryBiproducts F

full_name: CategoryTheory.Limits.preservesBinaryCoproductOfPreservesBinaryBiproduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary biproducts
    preserves binary coproducts. -/
def preservesBinaryCoproductOfPreservesBinaryBiproduct {X Y : C} [PreservesBinaryBiproduct X Y F] :
    PreservesColimit (pair X Y) F 
goal: CategoryTheory.Limits.PreservesColimit (CategoryTheory.Limits.pair X Y) F

full_name: CategoryTheory.Limits.preservesBinaryCoproductsOfPreservesBinaryBiproducts
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary biproducts
    preserves binary coproducts. -/
def preservesBinaryCoproductsOfPreservesBinaryBiproducts [PreservesBinaryBiproducts F] :
    PreservesColimitsOfShape (Discrete WalkingPair) F 
goal: CategoryTheory.Limits.PreservesColimitsOfShape (CategoryTheory.Discrete CategoryTheory.Limits.WalkingPair) F

full_name: CategoryTheory.Limits.preservesBinaryBiproductOfPreservesBinaryCoproduct
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary coproducts
    preserves binary biproducts. -/
def preservesBinaryBiproductOfPreservesBinaryCoproduct {X Y : C} [PreservesColimit (pair X Y) F] :
    PreservesBinaryBiproduct X Y F 
goal: CategoryTheory.Limits.PreservesBinaryBiproduct X Y F

full_name: CategoryTheory.Limits.preservesBinaryBiproductsOfPreservesBinaryCoproducts
code: /-- A functor between preadditive categories that preserves (zero morphisms and) binary coproducts
    preserves binary biproducts. -/
def preservesBinaryBiproductsOfPreservesBinaryCoproducts
    [PreservesColimitsOfShape (Discrete WalkingPair) F] : PreservesBinaryBiproducts F 
goal: CategoryTheory.Limits.PreservesBinaryBiproducts F