Theorem: CategoryTheory.NormalEpiCategory.mono_of_zero_kernel
File: Mathlib/CategoryTheory/Limits/Shapes/NormalMono/Equalizers.lean

tactic: simp
state_before: C : Type ?u.174543
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
⊢ 0 ≫ f = 0

tactic: obtain ⟨W, w, hw, hl⟩ := normalEpiOfEpi (coequalizer.π u v)
state_before: C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
⊢ u = v

tactic: obtain ⟨m, hm⟩ := coequalizer.desc' f huv
state_before: case mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
⊢ u = v

tactic: have reassoced {W : C} (h : coequalizer u v ⟶  W) : w ≫ coequalizer.π u v ≫ h = 0 ≫ h := by
  rw [← Category.assoc, eq_whisker hw]
state_before: case mk.mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
⊢ u = v

tactic: have hwf : w ≫ f = 0 := by rw [← hm, reassoced, zero_comp]
state_before: case mk.mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
⊢ u = v

tactic: obtain ⟨n, hn⟩ := KernelFork.IsLimit.lift' l _ hwf
state_before: case mk.mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
hwf : w ≫ f = 0
⊢ u = v

tactic: rw [Fork.ι_ofι, HasZeroMorphisms.comp_zero] at hn
state_before: case mk.mk.mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
hwf : w ≫ f = 0
n : W ⟶ (KernelFork.ofι 0 (_ : 0 ≫ f = 0)).pt
hn : n ≫ Fork.ι (KernelFork.ofι 0 (_ : 0 ≫ f = 0)) = w
⊢ u = v

tactic: have : IsIso (coequalizer.π u v) := by
  apply isIso_colimit_cocone_parallelPair_of_eq hn.symm hl
state_before: case mk.mk.mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
hwf : w ≫ f = 0
n : W ⟶ (KernelFork.ofι 0 (_ : 0 ≫ f = 0)).pt
hn : 0 = w
⊢ u = v

tactic: apply (cancel_mono (coequalizer.π u v)).1
state_before: case mk.mk.mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
hwf : w ≫ f = 0
n : W ⟶ (KernelFork.ofι 0 (_ : 0 ≫ f = 0)).pt
hn : 0 = w
this : IsIso (coequalizer.π u v)
⊢ u = v

tactic: exact coequalizer.condition _ _
state_before: case mk.mk.mk
C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
hwf : w ≫ f = 0
n : W ⟶ (KernelFork.ofι 0 (_ : 0 ≫ f = 0)).pt
hn : 0 = w
this : IsIso (coequalizer.π u v)
⊢ u ≫ coequalizer.π u v = v ≫ coequalizer.π u v

tactic: rw [← Category.assoc, eq_whisker hw]
state_before: C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W✝ : C
w : W✝ ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
W : C
h : coequalizer u v ⟶ W
⊢ w ≫ coequalizer.π u v ≫ h = 0 ≫ h

tactic: rw [← hm, reassoced, zero_comp]
state_before: C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
⊢ w ≫ f = 0

tactic: apply isIso_colimit_cocone_parallelPair_of_eq hn.symm hl
state_before: C : Type u_2
inst✝⁴ : Category C
inst✝³ : HasZeroMorphisms C
inst✝² : HasFiniteCoproducts C
inst✝¹ : HasCokernels C
inst✝ : NormalEpiCategory C
X Y : C
f : X ⟶ Y
Z : C
l : IsLimit (KernelFork.ofι 0 (_ : 0 ≫ f = 0))
Z✝ : C
u v : Z✝ ⟶ X
huv : u ≫ f = v ≫ f
W : C
w : W ⟶ X
hw : w ≫ coequalizer.π u v = 0
hl : IsColimit (CokernelCofork.ofπ (coequalizer.π u v) hw)
m : coequalizer u v ⟶ Y
hm : coequalizer.π u v ≫ m = f
reassoced : ∀ {W_1 : C} (h : coequalizer u v ⟶ W_1), w ≫ coequalizer.π u v ≫ h = 0 ≫ h
hwf : w ≫ f = 0
n : W ⟶ (KernelFork.ofι 0 (_ : 0 ≫ f = 0)).pt
hn : 0 = w
⊢ IsIso (coequalizer.π u v)