[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
⊢ g = 0
[PROOFSTEP]
let u := kernel.ι g ≫ i
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
⊢ g = 0
[PROOFSTEP]
haveI : Mono u := mono_comp _ _
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
⊢ g = 0
[PROOFSTEP]
haveI hu := normalMonoOfMono u
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
⊢ g = 0
[PROOFSTEP]
let h := hu.g
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
⊢ g = 0
[PROOFSTEP]
obtain ⟨t, ht⟩ := kernel.lift' g p hpg
[GOAL]
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
⊢ g = 0
[PROOFSTEP]
have fh : f ≫ h = 0
[GOAL]
case fh
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
⊢ f ≫ h = 0
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
⊢ g = 0
[PROOFSTEP]
calc
  f ≫ h = (p ≫ i) ≫ h := (Abelian.image.fac f).symm ▸ rfl
  _ = ((t ≫ kernel.ι g) ≫ i) ≫ h := (ht ▸ rfl)
  _ = t ≫ u ≫ h := by simp only [Category.assoc]
  _ = t ≫ 0 := (hu.w ▸ rfl)
  _ = 0 :=
    HasZeroMorphisms.comp_zero _
      _
        -- h factors through the cokernel of f via some l.
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
⊢ ((t ≫ kernel.ι g) ≫ i) ≫ h = t ≫ u ≫ h
[PROOFSTEP]
simp only [Category.assoc]
[GOAL]
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
⊢ g = 0
[PROOFSTEP]
obtain ⟨l, hl⟩ := cokernel.desc' f h fh
[GOAL]
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
⊢ g = 0
[PROOFSTEP]
have hih : i ≫ h = 0
[GOAL]
case hih
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
⊢ i ≫ h = 0
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
hih : i ≫ h = 0
⊢ g = 0
[PROOFSTEP]
calc
  i ≫ h = i ≫ cokernel.π f ≫ l := hl ▸ rfl
  _ = 0 ≫ l := by rw [← Category.assoc, kernel.condition]
  _ = 0 := zero_comp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
⊢ i ≫ cokernel.π f ≫ l = 0 ≫ l
[PROOFSTEP]
rw [← Category.assoc, kernel.condition]
[GOAL]
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
hih : i ≫ h = 0
⊢ g = 0
[PROOFSTEP]
obtain ⟨s, hs⟩ := NormalMono.lift' u i hih
[GOAL]
case mk.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
hih : i ≫ h = 0
s : kernel (cokernel.π f) ⟶ kernel g
hs : s ≫ u = i
⊢ g = 0
[PROOFSTEP]
have hs' : (s ≫ kernel.ι g) ≫ i = 𝟙 I ≫ i := by rw [Category.assoc, hs, Category.id_comp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
hih : i ≫ h = 0
s : kernel (cokernel.π f) ⟶ kernel g
hs : s ≫ u = i
⊢ (s ≫ kernel.ι g) ≫ i = 𝟙 I ≫ i
[PROOFSTEP]
rw [Category.assoc, hs, Category.id_comp]
[GOAL]
case mk.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
hih : i ≫ h = 0
s : kernel (cokernel.π f) ⟶ kernel g
hs : s ≫ u = i
hs' : (s ≫ kernel.ι g) ≫ i = 𝟙 I ≫ i
⊢ g = 0
[PROOFSTEP]
haveI : Epi (kernel.ι g) :=
  epi_of_epi_fac
    ((cancel_mono _).1 hs')
      -- ker g is an epimorphism, but ker g ≫ g = 0 = ker g ≫ 0, so g = 0 as required.
[GOAL]
case mk.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.image f
p : P ⟶ Abelian.image f := Abelian.factorThruImage f
i : kernel (cokernel.π f) ⟶ Q := kernel.ι (cokernel.π f)
R : C
g : I ⟶ R
hpg : p ≫ g = 0
u : kernel g ⟶ Q := kernel.ι g ≫ i
this✝ : Mono u
hu : NormalMono u
h : Q ⟶ NormalMono.Z u := NormalMono.g
t : P ⟶ kernel g
ht : t ≫ kernel.ι g = p
fh : f ≫ h = 0
l : cokernel f ⟶ NormalMono.Z u
hl : cokernel.π f ≫ l = h
hih : i ≫ h = 0
s : kernel (cokernel.π f) ⟶ kernel g
hs : s ≫ u = i
hs' : (s ≫ kernel.ι g) ≫ i = 𝟙 I ≫ i
this : Epi (kernel.ι g)
⊢ g = 0
[PROOFSTEP]
exact zero_of_epi_comp _ (kernel.condition g)
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
⊢ g = 0
[PROOFSTEP]
let u := p ≫ cokernel.π g
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
⊢ g = 0
[PROOFSTEP]
haveI : Epi u := epi_comp _ _
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
⊢ g = 0
[PROOFSTEP]
haveI hu := normalEpiOfEpi u
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
⊢ g = 0
[PROOFSTEP]
let h := hu.g
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
⊢ g = 0
[PROOFSTEP]
obtain ⟨t, ht⟩ := cokernel.desc' g i hgi
[GOAL]
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
⊢ g = 0
[PROOFSTEP]
have hf : h ≫ f = 0
[GOAL]
case hf
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
⊢ h ≫ f = 0
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
⊢ g = 0
[PROOFSTEP]
calc
  h ≫ f = h ≫ p ≫ i := (Abelian.coimage.fac f).symm ▸ rfl
  _ = h ≫ p ≫ cokernel.π g ≫ t := (ht ▸ rfl)
  _ = h ≫ u ≫ t := by simp only [Category.assoc]
  _ = 0 ≫ t := by rw [← Category.assoc, hu.w]
  _ = 0 := zero_comp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
⊢ h ≫ p ≫ cokernel.π g ≫ t = h ≫ u ≫ t
[PROOFSTEP]
simp only [Category.assoc]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
⊢ h ≫ u ≫ t = 0 ≫ t
[PROOFSTEP]
rw [← Category.assoc, hu.w]
[GOAL]
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
⊢ g = 0
[PROOFSTEP]
obtain ⟨l, hl⟩ := kernel.lift' f h hf
[GOAL]
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
⊢ g = 0
[PROOFSTEP]
have hhp : h ≫ p = 0
[GOAL]
case hhp
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
⊢ h ≫ p = 0
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
hhp : h ≫ p = 0
⊢ g = 0
[PROOFSTEP]
calc
  h ≫ p = (l ≫ kernel.ι f) ≫ p := hl ▸ rfl
  _ = l ≫ 0 := by rw [Category.assoc, cokernel.condition]
  _ = 0 := comp_zero
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
⊢ (l ≫ kernel.ι f) ≫ p = l ≫ 0
[PROOFSTEP]
rw [Category.assoc, cokernel.condition]
[GOAL]
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
hhp : h ≫ p = 0
⊢ g = 0
[PROOFSTEP]
obtain ⟨s, hs⟩ := NormalEpi.desc' u p hhp
[GOAL]
case mk.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
hhp : h ≫ p = 0
s : cokernel g ⟶ cokernel (kernel.ι f)
hs : u ≫ s = p
⊢ g = 0
[PROOFSTEP]
have hs' : p ≫ cokernel.π g ≫ s = p ≫ 𝟙 I := by rw [← Category.assoc, hs, Category.comp_id]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
hhp : h ≫ p = 0
s : cokernel g ⟶ cokernel (kernel.ι f)
hs : u ≫ s = p
⊢ p ≫ cokernel.π g ≫ s = p ≫ 𝟙 I
[PROOFSTEP]
rw [← Category.assoc, hs, Category.comp_id]
[GOAL]
case mk.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
hhp : h ≫ p = 0
s : cokernel g ⟶ cokernel (kernel.ι f)
hs : u ≫ s = p
hs' : p ≫ cokernel.π g ≫ s = p ≫ 𝟙 I
⊢ g = 0
[PROOFSTEP]
haveI : Mono (cokernel.π g) :=
  mono_of_mono_fac
    ((cancel_epi _).1 hs')
      -- coker g is a monomorphism, but g ≫ coker g = 0 = 0 ≫ coker g, so g = 0 as required.
[GOAL]
case mk.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
P Q : C
f : P ⟶ Q
I : C := Abelian.coimage f
i : Abelian.coimage f ⟶ Q := Abelian.factorThruCoimage f
p : P ⟶ cokernel (kernel.ι f) := cokernel.π (kernel.ι f)
R : C
g : R ⟶ I
hgi : g ≫ i = 0
u : P ⟶ cokernel g := p ≫ cokernel.π g
this✝ : Epi u
hu : NormalEpi u
h : NormalEpi.W u ⟶ P := NormalEpi.g
t : cokernel g ⟶ Q
ht : cokernel.π g ≫ t = i
hf : h ≫ f = 0
l : NormalEpi.W u ⟶ kernel f
hl : l ≫ kernel.ι f = h
hhp : h ≫ p = 0
s : cokernel g ⟶ cokernel (kernel.ι f)
hs : u ≫ s = p
hs' : p ≫ cokernel.π g ≫ s = p ≫ 𝟙 I
this : Mono (cokernel.π g)
⊢ g = 0
[PROOFSTEP]
exact zero_of_comp_mono _ (cokernel.condition g)
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
⊢ Mono (r A)
[PROOFSTEP]
let hl : IsLimit (KernelFork.ofι (diag A) (cokernel.condition (diag A))) :=
  monoIsKernelOfCokernel _ (colimit.isColimit _)
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
⊢ Mono (r A)
[PROOFSTEP]
apply NormalEpiCategory.mono_of_cancel_zero
[GOAL]
case hf
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
⊢ ∀ (Z : C) (g : Z ⟶ A), g ≫ r A = 0 → g = 0
[PROOFSTEP]
intro Z x hx
[GOAL]
case hf
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
⊢ x = 0
[PROOFSTEP]
have hxx : (x ≫ prod.lift (𝟙 A) (0 : A ⟶ A)) ≫ cokernel.π (diag A) = 0 := by rw [Category.assoc, hx]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
⊢ (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
[PROOFSTEP]
rw [Category.assoc, hx]
[GOAL]
case hf
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
hxx : (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
⊢ x = 0
[PROOFSTEP]
obtain ⟨y, hy⟩ := KernelFork.IsLimit.lift' hl _ hxx
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
hxx : (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
y : Z ⟶ (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)).pt
hy : y ≫ Fork.ι (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) = x ≫ prod.lift (𝟙 A) 0
⊢ x = 0
[PROOFSTEP]
rw [KernelFork.ι_ofι] at hy
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
hxx : (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
y : Z ⟶ (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)).pt
hy : y ≫ diag A = x ≫ prod.lift (𝟙 A) 0
⊢ x = 0
[PROOFSTEP]
have hyy : y = 0 := by
  erw [← Category.comp_id y, ← Limits.prod.lift_snd (𝟙 A) (𝟙 A), ← Category.assoc, hy, Category.assoc, prod.lift_snd,
    HasZeroMorphisms.comp_zero]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
hxx : (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
y : Z ⟶ (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)).pt
hy : y ≫ diag A = x ≫ prod.lift (𝟙 A) 0
⊢ y = 0
[PROOFSTEP]
erw [← Category.comp_id y, ← Limits.prod.lift_snd (𝟙 A) (𝟙 A), ← Category.assoc, hy, Category.assoc, prod.lift_snd,
  HasZeroMorphisms.comp_zero]
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
hxx : (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
y : Z ⟶ (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)).pt
hy : y ≫ diag A = x ≫ prod.lift (𝟙 A) 0
hyy : y = 0
⊢ x = 0
[PROOFSTEP]
haveI : Mono (prod.lift (𝟙 A) (0 : A ⟶ A)) := mono_of_mono_fac (prod.lift_fst _ _)
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
hxx : (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
y : Z ⟶ (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)).pt
hy : y ≫ diag A = x ≫ prod.lift (𝟙 A) 0
hyy : y = 0
this : Mono (prod.lift (𝟙 A) 0)
⊢ x = 0
[PROOFSTEP]
apply (cancel_mono (prod.lift (𝟙 A) (0 : A ⟶ A))).1
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hl : IsLimit (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)) :=
  monoIsKernelOfCokernel (colimit.cocone (parallelPair (diag A) 0)) (colimit.isColimit (parallelPair (diag A) 0))
Z : C
x : Z ⟶ A
hx : x ≫ r A = 0
hxx : (x ≫ prod.lift (𝟙 A) 0) ≫ cokernel.π (diag A) = 0
y : Z ⟶ (KernelFork.ofι (diag A) (_ : diag A ≫ cokernel.π (diag A) = 0)).pt
hy : y ≫ diag A = x ≫ prod.lift (𝟙 A) 0
hyy : y = 0
this : Mono (prod.lift (𝟙 A) 0)
⊢ x ≫ prod.lift (𝟙 A) 0 = 0 ≫ prod.lift (𝟙 A) 0
[PROOFSTEP]
rw [← hy, hyy, zero_comp, zero_comp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
⊢ Epi (r A)
[PROOFSTEP]
have hlp : prod.lift (𝟙 A) (0 : A ⟶ A) ≫ Limits.prod.snd = 0 := prod.lift_snd _ _
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
⊢ Epi (r A)
[PROOFSTEP]
let hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) (0 : A ⟶ A)) hlp) :=
  by
  refine' Fork.IsLimit.mk _ (fun s => Fork.ι s ≫ Limits.prod.fst) _ _
  · intro s
    apply prod.hom_ext <;> simp
  · intro s m h
    haveI : Mono (prod.lift (𝟙 A) (0 : A ⟶ A)) := mono_of_mono_fac (prod.lift_fst _ _)
    apply (cancel_mono (prod.lift (𝟙 A) (0 : A ⟶ A))).1
    convert h
    apply prod.hom_ext <;> simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
⊢ IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp)
[PROOFSTEP]
refine' Fork.IsLimit.mk _ (fun s => Fork.ι s ≫ Limits.prod.fst) _ _
[GOAL]
case refine'_1
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
⊢ ∀ (s : Fork prod.snd 0), (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
[PROOFSTEP]
intro s
[GOAL]
case refine'_1
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
⊢ (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
[PROOFSTEP]
apply prod.hom_ext
[GOAL]
case refine'_1.h₁
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
⊢ ((fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp)) ≫ prod.fst = Fork.ι s ≫ prod.fst
[PROOFSTEP]
simp
[GOAL]
case refine'_1.h₂
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
⊢ ((fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp)) ≫ prod.snd = Fork.ι s ≫ prod.snd
[PROOFSTEP]
simp
[GOAL]
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
⊢ ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
    m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s
[PROOFSTEP]
intro s m h
[GOAL]
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt
h : m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
⊢ m = (fun s => Fork.ι s ≫ prod.fst) s
[PROOFSTEP]
haveI : Mono (prod.lift (𝟙 A) (0 : A ⟶ A)) := mono_of_mono_fac (prod.lift_fst _ _)
[GOAL]
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt
h : m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
this : Mono (prod.lift (𝟙 A) 0)
⊢ m = (fun s => Fork.ι s ≫ prod.fst) s
[PROOFSTEP]
apply (cancel_mono (prod.lift (𝟙 A) (0 : A ⟶ A))).1
[GOAL]
case refine'_2
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt
h : m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
this : Mono (prod.lift (𝟙 A) 0)
⊢ m ≫ prod.lift (𝟙 A) 0 = (fun s => Fork.ι s ≫ prod.fst) s ≫ prod.lift (𝟙 A) 0
[PROOFSTEP]
convert h
[GOAL]
case h.e'_3.h
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt
h : m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
this : Mono (prod.lift (𝟙 A) 0)
e_1✝ : (s.pt ⟶ A ⨯ A) = (s.pt ⟶ (parallelPair prod.snd 0).obj WalkingParallelPair.zero)
⊢ (fun s => Fork.ι s ≫ prod.fst) s ≫ prod.lift (𝟙 A) 0 = Fork.ι s
[PROOFSTEP]
apply prod.hom_ext
[GOAL]
case h.e'_3.h.h₁
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt
h : m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
this : Mono (prod.lift (𝟙 A) 0)
e_1✝ : (s.pt ⟶ A ⨯ A) = (s.pt ⟶ (parallelPair prod.snd 0).obj WalkingParallelPair.zero)
⊢ ((fun s => Fork.ι s ≫ prod.fst) s ≫ prod.lift (𝟙 A) 0) ≫ prod.fst = Fork.ι s ≫ prod.fst
[PROOFSTEP]
simp
[GOAL]
case h.e'_3.h.h₂
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
s : Fork prod.snd 0
m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt
h : m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s
this : Mono (prod.lift (𝟙 A) 0)
e_1✝ : (s.pt ⟶ A ⨯ A) = (s.pt ⟶ (parallelPair prod.snd 0).obj WalkingParallelPair.zero)
⊢ ((fun s => Fork.ι s ≫ prod.fst) s ≫ prod.lift (𝟙 A) 0) ≫ prod.snd = Fork.ι s ≫ prod.snd
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
⊢ Epi (r A)
[PROOFSTEP]
let hp2 : IsColimit (CokernelCofork.ofπ (Limits.prod.snd : A ⨯ A ⟶ A) hlp) := epiIsCokernelOfKernel _ hp1
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
⊢ Epi (r A)
[PROOFSTEP]
apply NormalMonoCategory.epi_of_zero_cancel
[GOAL]
case hf
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
⊢ ∀ (Z : C) (g : cokernel (diag A) ⟶ Z), r A ≫ g = 0 → g = 0
[PROOFSTEP]
intro Z z hz
[GOAL]
case hf
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
⊢ z = 0
[PROOFSTEP]
have h : prod.lift (𝟙 A) (0 : A ⟶ A) ≫ cokernel.π (diag A) ≫ z = 0 := by rw [← Category.assoc, hz]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
⊢ prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
[PROOFSTEP]
rw [← Category.assoc, hz]
[GOAL]
case hf
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
⊢ z = 0
[PROOFSTEP]
obtain ⟨t, ht⟩ := CokernelCofork.IsColimit.desc' hp2 _ h
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
t : (CokernelCofork.ofπ prod.snd hlp).pt ⟶ Z
ht : Cofork.π (CokernelCofork.ofπ prod.snd hlp) ≫ t = cokernel.π (diag A) ≫ z
⊢ z = 0
[PROOFSTEP]
rw [CokernelCofork.π_ofπ] at ht
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
t : (CokernelCofork.ofπ prod.snd hlp).pt ⟶ Z
ht : prod.snd ≫ t = cokernel.π (diag A) ≫ z
⊢ z = 0
[PROOFSTEP]
have htt : t = 0 := by
  rw [← Category.id_comp t]
  change 𝟙 A ≫ t = 0
  rw [← Limits.prod.lift_snd (𝟙 A) (𝟙 A), Category.assoc, ht, ← Category.assoc, cokernel.condition, zero_comp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
t : (CokernelCofork.ofπ prod.snd hlp).pt ⟶ Z
ht : prod.snd ≫ t = cokernel.π (diag A) ≫ z
⊢ t = 0
[PROOFSTEP]
rw [← Category.id_comp t]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
t : (CokernelCofork.ofπ prod.snd hlp).pt ⟶ Z
ht : prod.snd ≫ t = cokernel.π (diag A) ≫ z
⊢ 𝟙 (CokernelCofork.ofπ prod.snd hlp).pt ≫ t = 0
[PROOFSTEP]
change 𝟙 A ≫ t = 0
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
t : (CokernelCofork.ofπ prod.snd hlp).pt ⟶ Z
ht : prod.snd ≫ t = cokernel.π (diag A) ≫ z
⊢ 𝟙 A ≫ t = 0
[PROOFSTEP]
rw [← Limits.prod.lift_snd (𝟙 A) (𝟙 A), Category.assoc, ht, ← Category.assoc, cokernel.condition, zero_comp]
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
t : (CokernelCofork.ofπ prod.snd hlp).pt ⟶ Z
ht : prod.snd ≫ t = cokernel.π (diag A) ≫ z
htt : t = 0
⊢ z = 0
[PROOFSTEP]
apply (cancel_epi (cokernel.π (diag A))).1
[GOAL]
case hf.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
A : C
hlp : prod.lift (𝟙 A) 0 ≫ prod.snd = 0
hp1 : IsLimit (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) :=
  Fork.IsLimit.mk (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) (fun s => Fork.ι s ≫ prod.fst)
    (_ :
      ∀ (s : Fork prod.snd 0),
        (fun s => Fork.ι s ≫ prod.fst) s ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s)
    (_ :
      ∀ (s : Fork prod.snd 0) (m : s.pt ⟶ (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp).pt),
        m ≫ Fork.ι (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) = Fork.ι s → m = (fun s => Fork.ι s ≫ prod.fst) s)
hp2 : IsColimit (CokernelCofork.ofπ prod.snd hlp) := epiIsCokernelOfKernel (KernelFork.ofι (prod.lift (𝟙 A) 0) hlp) hp1
Z : C
z : cokernel (diag A) ⟶ Z
hz : r A ≫ z = 0
h : prod.lift (𝟙 A) 0 ≫ cokernel.π (diag A) ≫ z = 0
t : (CokernelCofork.ofπ prod.snd hlp).pt ⟶ Z
ht : prod.snd ≫ t = cokernel.π (diag A) ≫ z
htt : t = 0
⊢ cokernel.π (diag A) ≫ z = cokernel.π (diag A) ≫ 0
[PROOFSTEP]
rw [← ht, htt, comp_zero, comp_zero]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X : C
⊢ diag X ≫ σ = 0
[PROOFSTEP]
rw [cokernel.condition_assoc, zero_comp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X : C
⊢ prod.lift (𝟙 X) 0 ≫ σ = 𝟙 X
[PROOFSTEP]
rw [← Category.assoc, IsIso.hom_inv_id]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
⊢ prod.lift (𝟙 X) 0 ≫ prod.map f f = f ≫ prod.lift (𝟙 Y) 0
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X : C
⊢ cokernel.π (diag X) ≫ (asIso (r X)).symm.hom = σ
[PROOFSTEP]
rw [Iso.symm_hom, asIso_inv]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
⊢ σ ≫ f = prod.map f f ≫ σ
[PROOFSTEP]
obtain ⟨g, hg⟩ :=
  CokernelCofork.IsColimit.desc' isColimitσ (Limits.prod.map f f ≫ σ) (by rw [prod.diag_map_assoc, diag_σ, comp_zero])
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
⊢ diag X ≫ prod.map f f ≫ σ = 0
[PROOFSTEP]
rw [prod.diag_map_assoc, diag_σ, comp_zero]
[GOAL]
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
g : (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)).pt ⟶ Y
hg : Cofork.π (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)) ≫ g = prod.map f f ≫ σ
⊢ σ ≫ f = prod.map f f ≫ σ
[PROOFSTEP]
suffices hfg : f = g
[GOAL]
case mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
g : (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)).pt ⟶ Y
hg : Cofork.π (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)) ≫ g = prod.map f f ≫ σ
hfg : f = g
⊢ σ ≫ f = prod.map f f ≫ σ
[PROOFSTEP]
rw [← hg, Cofork.π_ofπ, hfg]
[GOAL]
case hfg
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
g : (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)).pt ⟶ Y
hg : Cofork.π (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)) ≫ g = prod.map f f ≫ σ
⊢ f = g
[PROOFSTEP]
calc
  f = f ≫ prod.lift (𝟙 Y) 0 ≫ σ := by rw [lift_σ, Category.comp_id]
  _ = prod.lift (𝟙 X) 0 ≫ Limits.prod.map f f ≫ σ := by rw [lift_map_assoc]
  _ = prod.lift (𝟙 X) 0 ≫ σ ≫ g := by rw [← hg, CokernelCofork.π_ofπ]
  _ = g := by rw [← Category.assoc, lift_σ, Category.id_comp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
g : (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)).pt ⟶ Y
hg : Cofork.π (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)) ≫ g = prod.map f f ≫ σ
⊢ f = f ≫ prod.lift (𝟙 Y) 0 ≫ σ
[PROOFSTEP]
rw [lift_σ, Category.comp_id]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
g : (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)).pt ⟶ Y
hg : Cofork.π (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)) ≫ g = prod.map f f ≫ σ
⊢ f ≫ prod.lift (𝟙 Y) 0 ≫ σ = prod.lift (𝟙 X) 0 ≫ prod.map f f ≫ σ
[PROOFSTEP]
rw [lift_map_assoc]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
g : (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)).pt ⟶ Y
hg : Cofork.π (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)) ≫ g = prod.map f f ≫ σ
⊢ prod.lift (𝟙 X) 0 ≫ prod.map f f ≫ σ = prod.lift (𝟙 X) 0 ≫ σ ≫ g
[PROOFSTEP]
rw [← hg, CokernelCofork.π_ofπ]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
f : X ⟶ Y
g : (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)).pt ⟶ Y
hg : Cofork.π (CokernelCofork.ofπ σ (_ : diag X ≫ σ = 0)) ≫ g = prod.map f f ≫ σ
⊢ prod.lift (𝟙 X) 0 ≫ σ ≫ g = g
[PROOFSTEP]
rw [← Category.assoc, lift_σ, Category.id_comp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ a - 0 = a
[PROOFSTEP]
rw [sub_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ prod.lift a 0 ≫ σ = a
[PROOFSTEP]
conv_lhs =>
  congr; congr; rw [← Category.comp_id a]
  case a.g => rw [show 0 = a ≫ (0 : Y ⟶ Y) by simp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| prod.lift a 0 ≫ σ
[PROOFSTEP]
  congr; congr; rw [← Category.comp_id a]
  case a.g => rw [show 0 = a ≫ (0 : Y ⟶ Y) by simp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| prod.lift a 0 ≫ σ
[PROOFSTEP]
  congr; congr; rw [← Category.comp_id a]
  case a.g => rw [show 0 = a ≫ (0 : Y ⟶ Y) by simp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| prod.lift a 0 ≫ σ
[PROOFSTEP]
congr
[GOAL]
case a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| prod.lift a 0
case a C : Type u inst✝¹ : Category.{v, u} C inst✝ : NonPreadditiveAbelian C X Y : C a : X ⟶ Y | σ
[PROOFSTEP]
congr
[GOAL]
case a.f
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| a
case a.g
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0
case a C : Type u inst✝¹ : Category.{v, u} C inst✝ : NonPreadditiveAbelian C X Y : C a : X ⟶ Y | σ
[PROOFSTEP]
rw [← Category.comp_id a]
[GOAL]
case a.f
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| a ≫ 𝟙 Y
case a.g
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0
case a C : Type u inst✝¹ : Category.{v, u} C inst✝ : NonPreadditiveAbelian C X Y : C a : X ⟶ Y | σ
[PROOFSTEP]
case a.g => rw [show 0 = a ≫ (0 : Y ⟶ Y) by simp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0
[PROOFSTEP]
rw [show 0 = a ≫ (0 : Y ⟶ Y) by simp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0
[PROOFSTEP]
rw [show 0 = a ≫ (0 : Y ⟶ Y) by simp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0
[PROOFSTEP]
rw [show 0 = a ≫ (0 : Y ⟶ Y) by simp]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ 0 = a ≫ 0
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ prod.lift (a ≫ 𝟙 Y) (a ≫ 0) ≫ σ = a
[PROOFSTEP]
rw [← prod.comp_lift, Category.assoc, lift_σ, Category.comp_id]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ a - a = 0
[PROOFSTEP]
rw [sub_def, ← Category.comp_id a, ← prod.comp_lift, Category.assoc, diag_σ, comp_zero]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c d : X ⟶ Y
⊢ prod.lift a b - prod.lift c d = prod.lift (a - c) (b - d)
[PROOFSTEP]
simp only [sub_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c d : X ⟶ Y
⊢ prod.lift (prod.lift a b) (prod.lift c d) ≫ σ = prod.lift (prod.lift a c ≫ σ) (prod.lift b d ≫ σ)
[PROOFSTEP]
ext
[GOAL]
case h₁
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c d : X ⟶ Y
⊢ (prod.lift (prod.lift a b) (prod.lift c d) ≫ σ) ≫ prod.fst =
    prod.lift (prod.lift a c ≫ σ) (prod.lift b d ≫ σ) ≫ prod.fst
[PROOFSTEP]
rw [Category.assoc, σ_comp, prod.lift_map_assoc, prod.lift_fst, prod.lift_fst, prod.lift_fst]
[GOAL]
case h₂
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c d : X ⟶ Y
⊢ (prod.lift (prod.lift a b) (prod.lift c d) ≫ σ) ≫ prod.snd =
    prod.lift (prod.lift a c ≫ σ) (prod.lift b d ≫ σ) ≫ prod.snd
[PROOFSTEP]
rw [Category.assoc, σ_comp, prod.lift_map_assoc, prod.lift_snd, prod.lift_snd, prod.lift_snd]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c d : X ⟶ Y
⊢ a - c - (b - d) = a - b - (c - d)
[PROOFSTEP]
rw [sub_def, ← lift_sub_lift, sub_def, Category.assoc, σ_comp, prod.lift_map_assoc]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c d : X ⟶ Y
⊢ prod.lift (prod.lift a b ≫ σ) (prod.lift c d ≫ σ) ≫ σ = a - b - (c - d)
[PROOFSTEP]
rfl
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ -a - b = -b - a
[PROOFSTEP]
conv_lhs => rw [neg_def, ← sub_zero b, sub_sub_sub, sub_zero, ← neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| -a - b
[PROOFSTEP]
rw [neg_def, ← sub_zero b, sub_sub_sub, sub_zero, ← neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| -a - b
[PROOFSTEP]
rw [neg_def, ← sub_zero b, sub_sub_sub, sub_zero, ← neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| -a - b
[PROOFSTEP]
rw [neg_def, ← sub_zero b, sub_sub_sub, sub_zero, ← neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ - -a = a
[PROOFSTEP]
rw [neg_def, neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ 0 - (0 - a) = a
[PROOFSTEP]
conv_lhs => congr; rw [← sub_self a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0 - (0 - a)
[PROOFSTEP]
congr; rw [← sub_self a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0 - (0 - a)
[PROOFSTEP]
congr; rw [← sub_self a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0 - (0 - a)
[PROOFSTEP]
congr
[GOAL]
case a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
| 0
case a C : Type u inst✝¹ : Category.{v, u} C inst✝ : NonPreadditiveAbelian C X Y : C a : X ⟶ Y | 0 - a
[PROOFSTEP]
rw [← sub_self a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ a - a - (0 - a) = a
[PROOFSTEP]
rw [sub_sub_sub, sub_zero, sub_self, sub_zero]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ a + b = b + a
[PROOFSTEP]
rw [add_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ a - -b = b + a
[PROOFSTEP]
conv_lhs => rw [← neg_neg a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| a - -b
[PROOFSTEP]
rw [← neg_neg a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| a - -b
[PROOFSTEP]
rw [← neg_neg a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| a - -b
[PROOFSTEP]
rw [← neg_neg a]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ - -a - -b = b + a
[PROOFSTEP]
rw [neg_def, neg_def, neg_def, sub_sub_sub]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ 0 - 0 - (0 - a - b) = b + a
[PROOFSTEP]
conv_lhs =>
  congr
  next => skip
  rw [← neg_def, neg_sub]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - 0 - (0 - a - b)
[PROOFSTEP]
  congr
  next => skip
  rw [← neg_def, neg_sub]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - 0 - (0 - a - b)
[PROOFSTEP]
  congr
  next => skip
  rw [← neg_def, neg_sub]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - 0 - (0 - a - b)
[PROOFSTEP]
congr
[GOAL]
case a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - 0
case a C : Type u inst✝¹ : Category.{v, u} C inst✝ : NonPreadditiveAbelian C X Y : C a b : X ⟶ Y | 0 - a - b
[PROOFSTEP]
next => skip
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - 0
[PROOFSTEP]
skip
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - 0
[PROOFSTEP]
skip
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - 0
[PROOFSTEP]
skip
[GOAL]
case a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - a - b
[PROOFSTEP]
rw [← neg_def, neg_sub]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ 0 - 0 - (-b - a) = b + a
[PROOFSTEP]
rw [sub_sub_sub, add_def, ← neg_def, neg_neg b, neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ a + -b = a - b
[PROOFSTEP]
rw [add_def, neg_neg]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ a + -a = 0
[PROOFSTEP]
rw [add_neg, sub_self]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ -a + a = 0
[PROOFSTEP]
rw [add_comm, add_neg_self]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ -(a - b) = -a + b
[PROOFSTEP]
rw [neg_def, neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ 0 - (a - b) = 0 - a + b
[PROOFSTEP]
conv_lhs => rw [← sub_self (0 : X ⟶ Y)]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - (a - b)
[PROOFSTEP]
rw [← sub_self (0 : X ⟶ Y)]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - (a - b)
[PROOFSTEP]
rw [← sub_self (0 : X ⟶ Y)]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
| 0 - (a - b)
[PROOFSTEP]
rw [← sub_self (0 : X ⟶ Y)]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ 0 - 0 - (a - b) = 0 - a + b
[PROOFSTEP]
rw [sub_sub_sub, add_def, neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b : X ⟶ Y
⊢ -(a + b) = -a - b
[PROOFSTEP]
rw [add_def, neg_sub', add_neg]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c : X ⟶ Y
⊢ a - b + c = a - (b - c)
[PROOFSTEP]
rw [add_def, neg_def, sub_sub_sub, sub_zero]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c : X ⟶ Y
⊢ a + b + c = a + (b + c)
[PROOFSTEP]
conv_lhs => congr; rw [add_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c : X ⟶ Y
| a + b + c
[PROOFSTEP]
congr; rw [add_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c : X ⟶ Y
| a + b + c
[PROOFSTEP]
congr; rw [add_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c : X ⟶ Y
| a + b + c
[PROOFSTEP]
congr
[GOAL]
case a
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c : X ⟶ Y
| a + b
case a C : Type u inst✝¹ : Category.{v, u} C inst✝ : NonPreadditiveAbelian C X Y : C a b c : X ⟶ Y | c
[PROOFSTEP]
rw [add_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a b c : X ⟶ Y
⊢ a - -b + c = a + (b + c)
[PROOFSTEP]
rw [sub_add, ← add_neg, neg_sub', neg_neg]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y : C
a : X ⟶ Y
⊢ a + 0 = a
[PROOFSTEP]
rw [add_def, neg_def, sub_self, sub_zero]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y Z : C
f : X ⟶ Y
g h : Y ⟶ Z
⊢ f ≫ (g - h) = f ≫ g - f ≫ h
[PROOFSTEP]
rw [sub_def, ← Category.assoc, prod.comp_lift, sub_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ (f - g) ≫ h = f ≫ h - g ≫ h
[PROOFSTEP]
rw [sub_def, Category.assoc, σ_comp, ← Category.assoc, prod.lift_map, sub_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y Z : C
f : X ⟶ Y
g h : Y ⟶ Z
⊢ f ≫ (g + h) = f ≫ g + f ≫ h
[PROOFSTEP]
rw [add_def, comp_sub, neg_def, comp_sub, comp_zero, add_def, neg_def]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : NonPreadditiveAbelian C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ (f + g) ≫ h = f ≫ h + g ≫ h
[PROOFSTEP]
rw [add_def, sub_comp, neg_def, sub_comp, zero_comp, add_def, neg_def]


[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
⊢ EckmannHilton.IsUnital (fun x x_1 => leftAdd X Y x x_1) 0
[PROOFSTEP]
have hr : ∀ f : X ⟶ Y, biprod.lift (0 : X ⟶ Y) f = f ≫ biprod.inr :=
  by
  intro f
  ext
  · aesop_cat
  · simp [biprod.lift_fst, Category.assoc, biprod.inr_fst, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
⊢ ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
[PROOFSTEP]
intro f
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f : X ⟶ Y
⊢ biprod.lift 0 f = f ≫ biprod.inr
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f : X ⟶ Y
⊢ biprod.lift 0 f ≫ biprod.fst = (f ≫ biprod.inr) ≫ biprod.fst
[PROOFSTEP]
aesop_cat
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f : X ⟶ Y
⊢ biprod.lift 0 f ≫ biprod.snd = (f ≫ biprod.inr) ≫ biprod.snd
[PROOFSTEP]
simp [biprod.lift_fst, Category.assoc, biprod.inr_fst, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
⊢ EckmannHilton.IsUnital (fun x x_1 => leftAdd X Y x x_1) 0
[PROOFSTEP]
have hl : ∀ f : X ⟶ Y, biprod.lift f (0 : X ⟶ Y) = f ≫ biprod.inl :=
  by
  intro f
  ext
  · aesop_cat
  · simp [biprod.lift_snd, Category.assoc, biprod.inl_snd, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
⊢ ∀ (f : X ⟶ Y), biprod.lift f 0 = f ≫ biprod.inl
[PROOFSTEP]
intro f
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
f : X ⟶ Y
⊢ biprod.lift f 0 = f ≫ biprod.inl
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
f : X ⟶ Y
⊢ biprod.lift f 0 ≫ biprod.fst = (f ≫ biprod.inl) ≫ biprod.fst
[PROOFSTEP]
aesop_cat
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
f : X ⟶ Y
⊢ biprod.lift f 0 ≫ biprod.snd = (f ≫ biprod.inl) ≫ biprod.snd
[PROOFSTEP]
simp [biprod.lift_snd, Category.assoc, biprod.inl_snd, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
hl : ∀ (f : X ⟶ Y), biprod.lift f 0 = f ≫ biprod.inl
⊢ EckmannHilton.IsUnital (fun x x_1 => leftAdd X Y x x_1) 0
[PROOFSTEP]
exact
  ⟨⟨fun f => by simp [hr f, leftAdd, Category.assoc, Category.comp_id, biprod.inr_desc]⟩,
    ⟨fun f => by simp [hl f, leftAdd, Category.assoc, Category.comp_id, biprod.inl_desc]⟩⟩
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
hl : ∀ (f : X ⟶ Y), biprod.lift f 0 = f ≫ biprod.inl
f : X ⟶ Y
⊢ leftAdd X Y 0 f = f
[PROOFSTEP]
simp [hr f, leftAdd, Category.assoc, Category.comp_id, biprod.inr_desc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
hr : ∀ (f : X ⟶ Y), biprod.lift 0 f = f ≫ biprod.inr
hl : ∀ (f : X ⟶ Y), biprod.lift f 0 = f ≫ biprod.inl
f : X ⟶ Y
⊢ leftAdd X Y f 0 = f
[PROOFSTEP]
simp [hl f, leftAdd, Category.assoc, Category.comp_id, biprod.inl_desc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
⊢ EckmannHilton.IsUnital (fun x x_1 => rightAdd X Y x x_1) 0
[PROOFSTEP]
have h₂ : ∀ f : X ⟶ Y, biprod.desc (0 : X ⟶ Y) f = biprod.snd ≫ f :=
  by
  intro f
  ext
  · aesop_cat
  · simp only [biprod.inr_desc, BinaryBicone.inr_snd_assoc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
⊢ ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
[PROOFSTEP]
intro f
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f : X ⟶ Y
⊢ biprod.desc 0 f = biprod.snd ≫ f
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f : X ⟶ Y
⊢ biprod.inl ≫ biprod.desc 0 f = biprod.inl ≫ biprod.snd ≫ f
[PROOFSTEP]
aesop_cat
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f : X ⟶ Y
⊢ biprod.inr ≫ biprod.desc 0 f = biprod.inr ≫ biprod.snd ≫ f
[PROOFSTEP]
simp only [biprod.inr_desc, BinaryBicone.inr_snd_assoc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
⊢ EckmannHilton.IsUnital (fun x x_1 => rightAdd X Y x x_1) 0
[PROOFSTEP]
have h₁ : ∀ f : X ⟶ Y, biprod.desc f (0 : X ⟶ Y) = biprod.fst ≫ f :=
  by
  intro f
  ext
  · aesop_cat
  · simp only [biprod.inr_desc, BinaryBicone.inr_fst_assoc, zero_comp]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
⊢ ∀ (f : X ⟶ Y), biprod.desc f 0 = biprod.fst ≫ f
[PROOFSTEP]
intro f
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
f : X ⟶ Y
⊢ biprod.desc f 0 = biprod.fst ≫ f
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
f : X ⟶ Y
⊢ biprod.inl ≫ biprod.desc f 0 = biprod.inl ≫ biprod.fst ≫ f
[PROOFSTEP]
aesop_cat
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
f : X ⟶ Y
⊢ biprod.inr ≫ biprod.desc f 0 = biprod.inr ≫ biprod.fst ≫ f
[PROOFSTEP]
simp only [biprod.inr_desc, BinaryBicone.inr_fst_assoc, zero_comp]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
h₁ : ∀ (f : X ⟶ Y), biprod.desc f 0 = biprod.fst ≫ f
⊢ EckmannHilton.IsUnital (fun x x_1 => rightAdd X Y x x_1) 0
[PROOFSTEP]
exact
  ⟨⟨fun f => by simp [h₂ f, rightAdd, biprod.lift_snd_assoc, Category.id_comp]⟩,
    ⟨fun f => by simp [h₁ f, rightAdd, biprod.lift_fst_assoc, Category.id_comp]⟩⟩
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
h₁ : ∀ (f : X ⟶ Y), biprod.desc f 0 = biprod.fst ≫ f
f : X ⟶ Y
⊢ rightAdd X Y 0 f = f
[PROOFSTEP]
simp [h₂ f, rightAdd, biprod.lift_snd_assoc, Category.id_comp]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
h₂ : ∀ (f : X ⟶ Y), biprod.desc 0 f = biprod.snd ≫ f
h₁ : ∀ (f : X ⟶ Y), biprod.desc f 0 = biprod.fst ≫ f
f : X ⟶ Y
⊢ rightAdd X Y f 0 = f
[PROOFSTEP]
simp [h₁ f, rightAdd, biprod.lift_fst_assoc, Category.id_comp]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
⊢ leftAdd X Y (rightAdd X Y f g) (rightAdd X Y h k) = rightAdd X Y (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
let diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
⊢ leftAdd X Y (rightAdd X Y f g) (rightAdd X Y h k) = rightAdd X Y (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
have hd₁ : biprod.inl ≫ diag = biprod.lift f h := by ext <;> simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
⊢ biprod.inl ≫ diag = biprod.lift f h
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
⊢ (biprod.inl ≫ diag) ≫ biprod.fst = biprod.lift f h ≫ biprod.fst
[PROOFSTEP]
simp
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
⊢ (biprod.inl ≫ diag) ≫ biprod.snd = biprod.lift f h ≫ biprod.snd
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
⊢ leftAdd X Y (rightAdd X Y f g) (rightAdd X Y h k) = rightAdd X Y (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
have hd₂ : biprod.inr ≫ diag = biprod.lift g k := by ext <;> simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
⊢ biprod.inr ≫ diag = biprod.lift g k
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
⊢ (biprod.inr ≫ diag) ≫ biprod.fst = biprod.lift g k ≫ biprod.fst
[PROOFSTEP]
simp
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
⊢ (biprod.inr ≫ diag) ≫ biprod.snd = biprod.lift g k ≫ biprod.snd
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
⊢ leftAdd X Y (rightAdd X Y f g) (rightAdd X Y h k) = rightAdd X Y (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
have h₁ : biprod.lift (f +ᵣ g) (h +ᵣ k) = biprod.lift (𝟙 X) (𝟙 X) ≫ diag := by ext <;> aesop_cat
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
⊢ biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) = biprod.lift (𝟙 X) (𝟙 X) ≫ diag
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
⊢ biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) ≫ biprod.fst = (biprod.lift (𝟙 X) (𝟙 X) ≫ diag) ≫ biprod.fst
[PROOFSTEP]
aesop_cat
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
⊢ biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) ≫ biprod.snd = (biprod.lift (𝟙 X) (𝟙 X) ≫ diag) ≫ biprod.snd
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
h₁ : biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) = biprod.lift (𝟙 X) (𝟙 X) ≫ diag
⊢ leftAdd X Y (rightAdd X Y f g) (rightAdd X Y h k) = rightAdd X Y (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
have h₂ : diag ≫ biprod.desc (𝟙 Y) (𝟙 Y) = biprod.desc (f +ₗ h) (g +ₗ k) := by
  ext <;> simp [reassoc_of% hd₁, reassoc_of% hd₂]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
h₁ : biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) = biprod.lift (𝟙 X) (𝟙 X) ≫ diag
⊢ diag ≫ biprod.desc (𝟙 Y) (𝟙 Y) = biprod.desc (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
ext
[GOAL]
case h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
h₁ : biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) = biprod.lift (𝟙 X) (𝟙 X) ≫ diag
⊢ biprod.inl ≫ diag ≫ biprod.desc (𝟙 Y) (𝟙 Y) = biprod.inl ≫ biprod.desc (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
simp [reassoc_of% hd₁, reassoc_of% hd₂]
[GOAL]
case h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
h₁ : biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) = biprod.lift (𝟙 X) (𝟙 X) ≫ diag
⊢ biprod.inr ≫ diag ≫ biprod.desc (𝟙 Y) (𝟙 Y) = biprod.inr ≫ biprod.desc (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
simp [reassoc_of% hd₁, reassoc_of% hd₂]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y : C
f g h k : X ⟶ Y
diag : X ⊞ X ⟶ Y ⊞ Y := biprod.lift (biprod.desc f g) (biprod.desc h k)
hd₁ : biprod.inl ≫ diag = biprod.lift f h
hd₂ : biprod.inr ≫ diag = biprod.lift g k
h₁ : biprod.lift (rightAdd X Y f g) (rightAdd X Y h k) = biprod.lift (𝟙 X) (𝟙 X) ≫ diag
h₂ : diag ≫ biprod.desc (𝟙 Y) (𝟙 Y) = biprod.desc (leftAdd X Y f h) (leftAdd X Y g k)
⊢ leftAdd X Y (rightAdd X Y f g) (rightAdd X Y h k) = rightAdd X Y (leftAdd X Y f h) (leftAdd X Y g k)
[PROOFSTEP]
rw [leftAdd, h₁, Category.assoc, h₂, rightAdd]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ (f + g) ≫ h = f ≫ h + g ≫ h
[PROOFSTEP]
simp only [add_eq_right_addition, Category.assoc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ biprod.lift (𝟙 X) (𝟙 X) ≫ biprod.desc f g ≫ h = biprod.lift (𝟙 X) (𝟙 X) ≫ biprod.desc (f ≫ h) (g ≫ h)
[PROOFSTEP]
congr
[GOAL]
case e_a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ biprod.desc f g ≫ h = biprod.desc (f ≫ h) (g ≫ h)
[PROOFSTEP]
ext
[GOAL]
case e_a.h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ biprod.inl ≫ biprod.desc f g ≫ h = biprod.inl ≫ biprod.desc (f ≫ h) (g ≫ h)
[PROOFSTEP]
simp
[GOAL]
case e_a.h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f g : X ⟶ Y
h : Y ⟶ Z
⊢ biprod.inr ≫ biprod.desc f g ≫ h = biprod.inr ≫ biprod.desc (f ≫ h) (g ≫ h)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f : X ⟶ Y
g h : Y ⟶ Z
⊢ f ≫ (g + h) = f ≫ g + f ≫ h
[PROOFSTEP]
simp only [add_eq_left_addition, ← Category.assoc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f : X ⟶ Y
g h : Y ⟶ Z
⊢ (f ≫ biprod.lift g h) ≫ biprod.desc (𝟙 Z) (𝟙 Z) = biprod.lift (f ≫ g) (f ≫ h) ≫ biprod.desc (𝟙 Z) (𝟙 Z)
[PROOFSTEP]
congr
[GOAL]
case e_a
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f : X ⟶ Y
g h : Y ⟶ Z
⊢ f ≫ biprod.lift g h = biprod.lift (f ≫ g) (f ≫ h)
[PROOFSTEP]
ext
[GOAL]
case e_a.h₀
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f : X ⟶ Y
g h : Y ⟶ Z
⊢ (f ≫ biprod.lift g h) ≫ biprod.fst = biprod.lift (f ≫ g) (f ≫ h) ≫ biprod.fst
[PROOFSTEP]
simp
[GOAL]
case e_a.h₁
C : Type u
inst✝² : Category.{v, u} C
inst✝¹ : HasZeroMorphisms C
inst✝ : HasBinaryBiproducts C
X Y Z : C
f : X ⟶ Y
g h : Y ⟶ Z
⊢ (f ≫ biprod.lift g h) ≫ biprod.snd = biprod.lift (f ≫ g) (f ≫ h) ≫ biprod.snd
[PROOFSTEP]
simp


[GOAL]
α : Type u_1
X Y : Discrete α
⊢ Fintype (X ⟶ Y)
[PROOFSTEP]
apply ULift.fintype