File: Mathlib/CategoryTheory/Preadditive/Basic.lean

full_name: CategoryTheory.Preadditive.homGroup
code: /-- A category is called preadditive if `P ⟶ Q` is an abelian group such that composition is
    linear in both variables. -/
class Preadditive where
  homGroup : ∀ P Q : C, AddCommGroup (P ⟶ Q) := by infer_instance
  add_comp : ∀ (P Q R : C) (f f' : P ⟶ Q) (g : Q ⟶ R), (f + f') ≫ g = f ≫ g + f' ≫ g := by
    aesop_cat
  comp_add : ∀ (P Q R : C) (f : P ⟶ Q) (g g' : Q ⟶ R), f ≫ (g + g') = f ≫ g + f ≫ g' := by
    aesop_cat
goal: AddCommGroup (P ⟶ Q)

full_name: CategoryTheory.Preadditive
code: /-- A category is called preadditive if `P ⟶ Q` is an abelian group such that composition is
    linear in both variables. -/
class Preadditive where
  homGroup : ∀ P Q : C, AddCommGroup (P ⟶ Q) := by infer_instance
  add_comp : ∀ (P Q R : C) (f f' : P ⟶ Q) (g : Q ⟶ R), (f + f') ≫ g = f ≫ g + f' ≫ g := by
    aesop_cat
  comp_add : ∀ (P Q R : C) (f : P ⟶ Q) (g g' : Q ⟶ R), f ≫ (g + g') = f ≫ g + f ≫ g' := by
    aesop_cat
goal: Type (max u v)

full_name: CategoryTheory.Preadditive.add_comp
code: /-- A category is called preadditive if `P ⟶ Q` is an abelian group such that composition is
    linear in both variables. -/
class Preadditive where
  homGroup : ∀ P Q : C, AddCommGroup (P ⟶ Q) := by infer_instance
  add_comp : ∀ (P Q R : C) (f f' : P ⟶ Q) (g : Q ⟶ R), (f + f') ≫ g = f ≫ g + f' ≫ g := by
    aesop_cat
  comp_add : ∀ (P Q R : C) (f : P ⟶ Q) (g g' : Q ⟶ R), f ≫ (g + g') = f ≫ g + f ≫ g' := by
    aesop_cat
goal: (f + f') ≫ g = f ≫ g + f' ≫ g

full_name: CategoryTheory.Preadditive.comp_add
code: /-- A category is called preadditive if `P ⟶ Q` is an abelian group such that composition is
    linear in both variables. -/
class Preadditive where
  homGroup : ∀ P Q : C, AddCommGroup (P ⟶ Q) := by infer_instance
  add_comp : ∀ (P Q R : C) (f f' : P ⟶ Q) (g : Q ⟶ R), (f + f') ≫ g = f ≫ g + f' ≫ g := by
    aesop_cat
  comp_add : ∀ (P Q R : C) (f : P ⟶ Q) (g g' : Q ⟶ R), f ≫ (g + g') = f ≫ g + f ≫ g' := by
    aesop_cat
goal: f ≫ (g + g') = f ≫ g + f ≫ g'

full_name: CategoryTheory.Preadditive.inducedCategory
code: instance inducedCategory : Preadditive.{v} (InducedCategory C F) 
goal: CategoryTheory.Preadditive (CategoryTheory.InducedCategory C F)

full_name: CategoryTheory.Preadditive.fullSubcategory
code: instance fullSubcategory (Z : C → Prop) : Preadditive.{v} (FullSubcategory Z) 
goal: CategoryTheory.Preadditive (CategoryTheory.FullSubcategory Z)

full_name: CategoryTheory.Preadditive.instAddCommGroupEnd
code: instance (X : C) : AddCommGroup (End X) 
goal: AddCommGroup (CategoryTheory.End X)

full_name: CategoryTheory.Preadditive.leftComp
code: /-- Composition by a fixed left argument as a group homomorphism -/
def leftComp {P Q : C} (R : C) (f : P ⟶ Q) : (Q ⟶ R) →+ (P ⟶ R) 
goal: (Q ⟶ R) →+ (P ⟶ R)

full_name: CategoryTheory.Preadditive.rightComp
code: /-- Composition by a fixed right argument as a group homomorphism -/
def rightComp (P : C) {Q R : C} (g : Q ⟶ R) : (P ⟶ Q) →+ (P ⟶ R) 
goal: (P ⟶ Q) →+ (P ⟶ R)

full_name: CategoryTheory.Preadditive.compHom
code: /-- Composition as a bilinear group homomorphism -/
def compHom : (P ⟶ Q) →+ (Q ⟶ R) →+ (P ⟶ R) 
goal: (P ⟶ Q) →+ (Q ⟶ R) →+ (P ⟶ R)

full_name: CategoryTheory.Preadditive.sub_comp
code: @[reassoc, simp]
theorem sub_comp : (f - f') ≫ g = f ≫ g - f' ≫ g 
goal: (f - f') ≫ g = f ≫ g - f' ≫ g

full_name: CategoryTheory.Preadditive.comp_sub
code: @[reassoc, simp]
theorem comp_sub : f ≫ (g - g') = f ≫ g - f ≫ g' 
goal: f ≫ (g - g') = f ≫ g - f ≫ g'

full_name: CategoryTheory.Preadditive.neg_comp
code: @[reassoc, simp]
theorem neg_comp : (-f) ≫ g = -f ≫ g 
goal: (-f) ≫ g = -f ≫ g

full_name: CategoryTheory.Preadditive.comp_neg
code: @[reassoc, simp]
theorem comp_neg : f ≫ (-g) = -f ≫ g 
goal: f ≫ (-g) = -f ≫ g

full_name: CategoryTheory.Preadditive.neg_comp_neg
code: @[reassoc]
theorem neg_comp_neg : (-f) ≫ (-g) = f ≫ g 
goal: (-f) ≫ (-g) = f ≫ g

full_name: CategoryTheory.Preadditive.nsmul_comp
code: theorem nsmul_comp (n : ℕ) : (n • f) ≫ g = n • f ≫ g 
goal: (n • f) ≫ g = n • f ≫ g

full_name: CategoryTheory.Preadditive.comp_nsmul
code: theorem comp_nsmul (n : ℕ) : f ≫ (n • g) = n • f ≫ g 
goal: f ≫ (n • g) = n • f ≫ g

full_name: CategoryTheory.Preadditive.zsmul_comp
code: theorem zsmul_comp (n : ℤ) : (n • f) ≫ g = n • f ≫ g 
goal: (n • f) ≫ g = n • f ≫ g

full_name: CategoryTheory.Preadditive.comp_zsmul
code: theorem comp_zsmul (n : ℤ) : f ≫ (n • g) = n • f ≫ g 
goal: f ≫ (n • g) = n • f ≫ g

full_name: CategoryTheory.Preadditive.comp_sum
code: @[reassoc]
theorem comp_sum {P Q R : C} {J : Type*} (s : Finset J) (f : P ⟶ Q) (g : J → (Q ⟶ R)) :
    (f ≫ ∑ j ∈ s, g j) = ∑ j ∈ s, f ≫ g j 
goal: f ≫ ∑ j ∈ s, g j = ∑ j ∈ s, f ≫ g j

full_name: CategoryTheory.Preadditive.sum_comp
code: @[reassoc]
theorem sum_comp {P Q R : C} {J : Type*} (s : Finset J) (f : J → (P ⟶ Q)) (g : Q ⟶ R) :
    (∑ j ∈ s, f j) ≫ g = ∑ j ∈ s, f j ≫ g 
goal: (∑ j ∈ s, f j) ≫ g = ∑ j ∈ s, f j ≫ g

full_name: CategoryTheory.Preadditive.instEpiNegHom
code: instance {P Q : C} {f : P ⟶ Q} [Epi f] : Epi (-f) 
goal: CategoryTheory.Epi (-f)

full_name: CategoryTheory.Preadditive.instMonoNegHom
code: instance {P Q : C} {f : P ⟶ Q} [Mono f] : Mono (-f) 
goal: CategoryTheory.Mono (-f)

full_name: CategoryTheory.Preadditive.preadditiveHasZeroMorphisms
code: instance (priority := 100) preadditiveHasZeroMorphisms : HasZeroMorphisms C 
goal: CategoryTheory.Limits.HasZeroMorphisms C

full_name: CategoryTheory.Preadditive.instSemiringEnd
code: /-- Porting note: adding this before the ring instance allowed moduleEndRight to find
the correct Monoid structure on End. Moved both down after preadditiveHasZeroMorphisms
to make use of them -/
instance {X : C} : Semiring (End X) 
goal: Semiring (CategoryTheory.End X)

full_name: CategoryTheory.Preadditive.instRingEnd
code: /-- Porting note: It looks like Ring's parent classes changed in
Lean 4 so the previous instance needed modification. Was following my nose here. -/
instance {X : C} : Ring (End X) 
goal: Ring (CategoryTheory.End X)

full_name: CategoryTheory.Preadditive.moduleEndRight
code: instance moduleEndRight {X Y : C} : Module (End Y) (X ⟶ Y) 
goal: Module (CategoryTheory.End Y) (X ⟶ Y)

full_name: CategoryTheory.Preadditive.mono_of_cancel_zero
code: theorem mono_of_cancel_zero {Q R : C} (f : Q ⟶ R) (h : ∀ {P : C} (g : P ⟶ Q), g ≫ f = 0 → g = 0) :
    Mono f 
goal: CategoryTheory.Mono f

full_name: CategoryTheory.Preadditive.mono_iff_cancel_zero
code: theorem mono_iff_cancel_zero {Q R : C} (f : Q ⟶ R) :
    Mono f ↔ ∀ (P : C) (g : P ⟶ Q), g ≫ f = 0 → g = 0 
goal: CategoryTheory.Mono f ↔ ∀ (P : C) (g : P ⟶ Q), g ≫ f = 0 → g = 0

full_name: CategoryTheory.Preadditive.mono_of_kernel_zero
code: theorem mono_of_kernel_zero {X Y : C} {f : X ⟶ Y} [HasLimit (parallelPair f 0)]
    (w : kernel.ι f = 0) : Mono f 
goal: CategoryTheory.Mono f

full_name: CategoryTheory.Preadditive.mono_of_isZero_kernel'
code: lemma mono_of_isZero_kernel' {X Y : C} {f : X ⟶ Y} (c : KernelFork f) (hc : IsLimit c)
    (h : IsZero c.pt) : Mono f 
goal: CategoryTheory.Mono f

full_name: CategoryTheory.Preadditive.mono_of_isZero_kernel
code: lemma mono_of_isZero_kernel {X Y : C} (f : X ⟶ Y) [HasKernel f] (h : IsZero (kernel f)) :
    Mono f 
goal: CategoryTheory.Mono f

full_name: CategoryTheory.Preadditive.epi_of_cancel_zero
code: theorem epi_of_cancel_zero {P Q : C} (f : P ⟶ Q) (h : ∀ {R : C} (g : Q ⟶ R), f ≫ g = 0 → g = 0) :
    Epi f 
goal: CategoryTheory.Epi f

full_name: CategoryTheory.Preadditive.epi_iff_cancel_zero
code: theorem epi_iff_cancel_zero {P Q : C} (f : P ⟶ Q) :
    Epi f ↔ ∀ (R : C) (g : Q ⟶ R), f ≫ g = 0 → g = 0 
goal: CategoryTheory.Epi f ↔ ∀ (R : C) (g : Q ⟶ R), f ≫ g = 0 → g = 0

full_name: CategoryTheory.Preadditive.epi_of_cokernel_zero
code: theorem epi_of_cokernel_zero {X Y : C} {f : X ⟶ Y} [HasColimit (parallelPair f 0)]
    (w : cokernel.π f = 0) : Epi f 
goal: CategoryTheory.Epi f

full_name: CategoryTheory.Preadditive.epi_of_isZero_cokernel'
code: lemma epi_of_isZero_cokernel' {X Y : C} {f : X ⟶ Y} (c : CokernelCofork f) (hc : IsColimit c)
    (h : IsZero c.pt) : Epi f 
goal: CategoryTheory.Epi f

full_name: CategoryTheory.Preadditive.epi_of_isZero_cokernel
code: lemma epi_of_isZero_cokernel {X Y : C} (f : X ⟶ Y) [HasCokernel f] (h : IsZero (cokernel f)) :
    Epi f 
goal: CategoryTheory.Epi f

full_name: CategoryTheory.Preadditive.IsIso.comp_left_eq_zero
code: @[simp]
theorem comp_left_eq_zero [IsIso f] : f ≫ g = 0 ↔ g = 0 
goal: f ≫ g = 0 ↔ g = 0

full_name: CategoryTheory.Preadditive.IsIso.comp_right_eq_zero
code: @[simp]
theorem comp_right_eq_zero [IsIso g] : f ≫ g = 0 ↔ f = 0 
goal: f ≫ g = 0 ↔ f = 0

full_name: CategoryTheory.Preadditive.mono_of_kernel_iso_zero
code: theorem mono_of_kernel_iso_zero {X Y : C} {f : X ⟶ Y} [HasLimit (parallelPair f 0)]
    (w : kernel f ≅ 0) : Mono f 
goal: CategoryTheory.Mono f

full_name: CategoryTheory.Preadditive.epi_of_cokernel_iso_zero
code: theorem epi_of_cokernel_iso_zero {X Y : C} {f : X ⟶ Y} [HasColimit (parallelPair f 0)]
    (w : cokernel f ≅ 0) : Epi f 
goal: CategoryTheory.Epi f

full_name: CategoryTheory.Preadditive.forkOfKernelFork_pt
code: /-- Map a kernel cone on the difference of two morphisms to the equalizer fork. -/
@[simps! pt]
def forkOfKernelFork (c : KernelFork (f - g)) : Fork f g 
goal: (CategoryTheory.Preadditive.forkOfKernelFork c).pt = c.pt

full_name: CategoryTheory.Preadditive.forkOfKernelFork
code: /-- Map a kernel cone on the difference of two morphisms to the equalizer fork. -/
@[simps! pt]
def forkOfKernelFork (c : KernelFork (f - g)) : Fork f g 
goal: CategoryTheory.Limits.Fork f g

full_name: CategoryTheory.Preadditive.forkOfKernelFork_ι
code: @[simp]
theorem forkOfKernelFork_ι (c : KernelFork (f - g)) : (forkOfKernelFork c).ι = c.ι 
goal: (CategoryTheory.Preadditive.forkOfKernelFork c).ι = CategoryTheory.Limits.Fork.ι c

full_name: CategoryTheory.Preadditive.kernelForkOfFork
code: /-- Map any equalizer fork to a cone on the difference of the two morphisms. -/
def kernelForkOfFork (c : Fork f g) : KernelFork (f - g) 
goal: CategoryTheory.Limits.KernelFork (f - g)

full_name: CategoryTheory.Preadditive.kernelForkOfFork_ι
code: @[simp]
theorem kernelForkOfFork_ι (c : Fork f g) : (kernelForkOfFork c).ι = c.ι 
goal: CategoryTheory.Limits.Fork.ι (CategoryTheory.Preadditive.kernelForkOfFork c) = c.ι

full_name: CategoryTheory.Preadditive.kernelForkOfFork_ofι
code: @[simp]
theorem kernelForkOfFork_ofι {P : C} (ι : P ⟶ X) (w : ι ≫ f = ι ≫ g) :
    kernelForkOfFork (Fork.ofι ι w) = KernelFork.ofι ι (by simp [w]) 
goal: CategoryTheory.Preadditive.kernelForkOfFork (CategoryTheory.Limits.Fork.ofι ι w) =
  CategoryTheory.Limits.KernelFork.ofι ι ⋯

full_name: CategoryTheory.Preadditive.isLimitForkOfKernelFork
code: /-- A kernel of `f - g` is an equalizer of `f` and `g`. -/
def isLimitForkOfKernelFork {c : KernelFork (f - g)} (i : IsLimit c) :
    IsLimit (forkOfKernelFork c) 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Preadditive.forkOfKernelFork c)

full_name: CategoryTheory.Preadditive.isLimitForkOfKernelFork_lift
code: @[simp]
theorem isLimitForkOfKernelFork_lift {c : KernelFork (f - g)} (i : IsLimit c) (s : Fork f g) :
    (isLimitForkOfKernelFork i).lift s = i.lift (kernelForkOfFork s) 
goal: (CategoryTheory.Preadditive.isLimitForkOfKernelFork i).lift s = i.lift (CategoryTheory.Preadditive.kernelForkOfFork s)

full_name: CategoryTheory.Preadditive.isLimitKernelForkOfFork
code: /-- An equalizer of `f` and `g` is a kernel of `f - g`. -/
def isLimitKernelForkOfFork {c : Fork f g} (i : IsLimit c) : IsLimit (kernelForkOfFork c) 
goal: CategoryTheory.Limits.IsLimit (CategoryTheory.Preadditive.kernelForkOfFork c)

full_name: CategoryTheory.Preadditive.hasEqualizer_of_hasKernel
code: /-- A preadditive category has an equalizer for `f` and `g` if it has a kernel for `f - g`. -/
theorem hasEqualizer_of_hasKernel [HasKernel (f - g)] : HasEqualizer f g 
goal: CategoryTheory.Limits.HasEqualizer f g

full_name: CategoryTheory.Preadditive.hasKernel_of_hasEqualizer
code: /-- A preadditive category has a kernel for `f - g` if it has an equalizer for `f` and `g`. -/
theorem hasKernel_of_hasEqualizer [HasEqualizer f g] : HasKernel (f - g) 
goal: CategoryTheory.Limits.HasKernel (f - g)

full_name: CategoryTheory.Preadditive.coforkOfCokernelCofork
code: /-- Map a cokernel cocone on the difference of two morphisms to the coequalizer cofork. -/
@[simps! pt]
def coforkOfCokernelCofork (c : CokernelCofork (f - g)) : Cofork f g 
goal: CategoryTheory.Limits.Cofork f g

full_name: CategoryTheory.Preadditive.coforkOfCokernelCofork_pt
code: /-- Map a cokernel cocone on the difference of two morphisms to the coequalizer cofork. -/
@[simps! pt]
def coforkOfCokernelCofork (c : CokernelCofork (f - g)) : Cofork f g 
goal: (CategoryTheory.Preadditive.coforkOfCokernelCofork c).pt = c.pt

full_name: CategoryTheory.Preadditive.coforkOfCokernelCofork_π
code: @[simp]
theorem coforkOfCokernelCofork_π (c : CokernelCofork (f - g)) :
    (coforkOfCokernelCofork c).π = c.π 
goal: (CategoryTheory.Preadditive.coforkOfCokernelCofork c).π = CategoryTheory.Limits.Cofork.π c

full_name: CategoryTheory.Preadditive.cokernelCoforkOfCofork
code: /-- Map any coequalizer cofork to a cocone on the difference of the two morphisms. -/
def cokernelCoforkOfCofork (c : Cofork f g) : CokernelCofork (f - g) 
goal: CategoryTheory.Limits.CokernelCofork (f - g)

full_name: CategoryTheory.Preadditive.cokernelCoforkOfCofork_π
code: @[simp]
theorem cokernelCoforkOfCofork_π (c : Cofork f g) : (cokernelCoforkOfCofork c).π = c.π 
goal: CategoryTheory.Limits.Cofork.π (CategoryTheory.Preadditive.cokernelCoforkOfCofork c) = c.π

full_name: CategoryTheory.Preadditive.cokernelCoforkOfCofork_ofπ
code: @[simp]
theorem cokernelCoforkOfCofork_ofπ {P : C} (π : Y ⟶ P) (w : f ≫ π = g ≫ π) :
    cokernelCoforkOfCofork (Cofork.ofπ π w) = CokernelCofork.ofπ π (by simp [w]) 
goal: CategoryTheory.Preadditive.cokernelCoforkOfCofork (CategoryTheory.Limits.Cofork.ofπ π w) =
  CategoryTheory.Limits.CokernelCofork.ofπ π ⋯

full_name: CategoryTheory.Preadditive.isColimitCoforkOfCokernelCofork
code: /-- A cokernel of `f - g` is a coequalizer of `f` and `g`. -/
def isColimitCoforkOfCokernelCofork {c : CokernelCofork (f - g)} (i : IsColimit c) :
    IsColimit (coforkOfCokernelCofork c) 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Preadditive.coforkOfCokernelCofork c)

full_name: CategoryTheory.Preadditive.isColimitCoforkOfCokernelCofork_desc
code: @[simp]
theorem isColimitCoforkOfCokernelCofork_desc {c : CokernelCofork (f - g)} (i : IsColimit c)
    (s : Cofork f g) :
    (isColimitCoforkOfCokernelCofork i).desc s = i.desc (cokernelCoforkOfCofork s) 
goal: (CategoryTheory.Preadditive.isColimitCoforkOfCokernelCofork i).desc s =
  i.desc (CategoryTheory.Preadditive.cokernelCoforkOfCofork s)

full_name: CategoryTheory.Preadditive.isColimitCokernelCoforkOfCofork
code: /-- A coequalizer of `f` and `g` is a cokernel of `f - g`. -/
def isColimitCokernelCoforkOfCofork {c : Cofork f g} (i : IsColimit c) :
    IsColimit (cokernelCoforkOfCofork c) 
goal: CategoryTheory.Limits.IsColimit (CategoryTheory.Preadditive.cokernelCoforkOfCofork c)

full_name: CategoryTheory.Preadditive.hasCoequalizer_of_hasCokernel
code: /-- A preadditive category has a coequalizer for `f` and `g` if it has a cokernel for `f - g`. -/
theorem hasCoequalizer_of_hasCokernel [HasCokernel (f - g)] : HasCoequalizer f g 
goal: CategoryTheory.Limits.HasCoequalizer f g

full_name: CategoryTheory.Preadditive.hasCokernel_of_hasCoequalizer
code: /-- A preadditive category has a cokernel for `f - g` if it has a coequalizer for `f` and `g`. -/
theorem hasCokernel_of_hasCoequalizer [HasCoequalizer f g] : HasCokernel (f - g) 
goal: CategoryTheory.Limits.HasCokernel (f - g)

full_name: CategoryTheory.Preadditive.hasEqualizers_of_hasKernels
code: /-- If a preadditive category has all kernels, then it also has all equalizers. -/
theorem hasEqualizers_of_hasKernels [HasKernels C] : HasEqualizers C 
goal: CategoryTheory.Limits.HasEqualizers C

full_name: CategoryTheory.Preadditive.hasCoequalizers_of_hasCokernels
code: /-- If a preadditive category has all cokernels, then it also has all coequalizers. -/
theorem hasCoequalizers_of_hasCokernels [HasCokernels C] : HasCoequalizers C 
goal: CategoryTheory.Limits.HasCoequalizers C

full_name: CategoryTheory.Preadditive.instSMulUnitsIntIso
code: instance : SMul (Units ℤ) (X ≅ Y) 
goal: SMul ℤˣ (X ≅ Y)

full_name: CategoryTheory.Preadditive.smul_iso_hom
code: @[simp]
lemma smul_iso_hom (a : Units ℤ) (e : X ≅ Y) : (a • e).hom = a • e.hom 
goal: (a • e).hom = a • e.hom

full_name: CategoryTheory.Preadditive.smul_iso_inv
code: @[simp]
lemma smul_iso_inv (a : Units ℤ) (e : X ≅ Y) : (a • e).inv = a⁻¹ • e.inv 
goal: (a • e).inv = a⁻¹ • e.inv

full_name: CategoryTheory.Preadditive.instNegIso
code: instance : Neg (X ≅ Y) 
goal: Neg (X ≅ Y)

full_name: CategoryTheory.Preadditive.neg_iso_hom
code: @[simp]
lemma neg_iso_hom (e : X ≅ Y) : (-e).hom = -e.hom 
goal: (-e).hom = -e.hom

full_name: CategoryTheory.Preadditive.neg_iso_inv
code: @[simp]
lemma neg_iso_inv (e : X ≅ Y) : (-e).inv = -e.inv 
goal: (-e).inv = -e.inv