[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
⊢ (equalizerSubobjectIso f g).hom ≫ equalizer.ι f g = arrow (equalizerSubobject f g)
[PROOFSTEP]
simp [equalizerSubobjectIso]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
⊢ (equalizerSubobjectIso f g).inv ≫ arrow (equalizerSubobject f g) = equalizer.ι f g
[PROOFSTEP]
simp [equalizerSubobjectIso]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
⊢ arrow (equalizerSubobject f g) ≫ f = arrow (equalizerSubobject f g) ≫ g
[PROOFSTEP]
rw [← equalizerSubobject_arrow, Category.assoc, Category.assoc, equalizer.condition]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
W : C
h : W ⟶ X
w : h ≫ f = h ≫ g
⊢ equalizer.lift h w ≫ MonoOver.arrow (MonoOver.mk' (equalizer.ι f g)) = h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f g : X ⟶ Y
inst✝ : HasEqualizer f g
W : C
h : W ⟶ X
w : Factors (equalizerSubobject f g) h
⊢ h ≫ f = h ≫ g
[PROOFSTEP]
rw [← Subobject.factorThru_arrow _ _ w, Category.assoc, equalizerSubobject_arrow_comp, Category.assoc]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ (kernelSubobjectIso f).hom ≫ kernel.ι f = arrow (kernelSubobject f)
[PROOFSTEP]
simp [kernelSubobjectIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ (kernelSubobjectIso f).inv ≫ arrow (kernelSubobject f) = kernel.ι f
[PROOFSTEP]
simp [kernelSubobjectIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ arrow (kernelSubobject f) ≫ f = 0
[PROOFSTEP]
rw [← kernelSubobject_arrow]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
⊢ ((kernelSubobjectIso f).hom ≫ kernel.ι f) ≫ f = 0
[PROOFSTEP]
simp only [Category.assoc, kernel.condition, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ kernel.lift f h w ≫ MonoOver.arrow (MonoOver.mk' (kernel.ι f)) = h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : Factors (kernelSubobject f) h
⊢ h ≫ f = 0
[PROOFSTEP]
rw [← Subobject.factorThru_arrow _ _ w, Category.assoc, kernelSubobject_arrow_comp, comp_zero]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ factorThruKernelSubobject f h w ≫ arrow (kernelSubobject f) = h
[PROOFSTEP]
dsimp [factorThruKernelSubobject]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ factorThru (kernelSubobject f) h (_ : Factors (kernelSubobject f) h) ≫ arrow (kernelSubobject f) = h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
W : C
h : W ⟶ X
w : h ≫ f = 0
⊢ (factorThruKernelSubobject f h w ≫ (kernelSubobjectIso f).hom) ≫ kernel.ι f = kernel.lift f h w ≫ kernel.ι f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ (arrow (kernelSubobject f) ≫ sq.left) ≫ f' = 0
[PROOFSTEP]
simp [sq.w]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ kernelSubobjectMap sq ≫ arrow (kernelSubobject f') = arrow (kernelSubobject f) ≫ sq.left
[PROOFSTEP]
simp [kernelSubobjectMap]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
⊢ kernelSubobjectMap (𝟙 (Arrow.mk f)) = 𝟙 (underlying.obj (kernelSubobject f))
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
inst✝³ : HasZeroMorphisms C
f : X ⟶ Y
inst✝² : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝¹ : HasKernel f'
X'' Y'' : C
f'' : X'' ⟶ Y''
inst✝ : HasKernel f''
sq : Arrow.mk f ⟶ Arrow.mk f'
sq' : Arrow.mk f' ⟶ Arrow.mk f''
⊢ kernelSubobjectMap (sq ≫ sq') = kernelSubobjectMap sq ≫ kernelSubobjectMap sq'
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ kernel.map f f' sq.left sq.right (_ : (Arrow.mk f).hom ≫ (𝟭 C).map sq.right = (𝟭 C).map sq.left ≫ (Arrow.mk f').hom) ≫
      (kernelSubobjectIso f').inv =
    (kernelSubobjectIso f).inv ≫ kernelSubobjectMap sq
[PROOFSTEP]
aesop_cat
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
inst✝² : HasZeroMorphisms C
f : X ⟶ Y
inst✝¹ : HasKernel f
X' Y' : C
f' : X' ⟶ Y'
inst✝ : HasKernel f'
sq : Arrow.mk f ⟶ Arrow.mk f'
⊢ (kernelSubobjectIso f).hom ≫
      kernel.map f f' sq.left sq.right
        (_ : (Arrow.mk f).hom ≫ (𝟭 C).map sq.right = (𝟭 C).map sq.left ≫ (Arrow.mk f').hom) =
    kernelSubobjectMap sq ≫ (kernelSubobjectIso f').hom
[PROOFSTEP]
simp [← Iso.comp_inv_eq, kernel_map_comp_kernelSubobjectIso_inv]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
A B : C
⊢ IsIso (kernel.ι 0)
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
inst✝¹ : HasZeroMorphisms C
f : X ⟶ Y
inst✝ : HasKernel f
A : Subobject X
h : arrow A ≫ f = 0
⊢ kernel.lift f (arrow A) h ≫ kernel.ι f = arrow A
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
X' : C
f : X' ⟶ X
inst✝¹ : IsIso f
g : X ⟶ Y
inst✝ : HasKernel g
⊢ (kernelSubobjectIsoComp f g).hom ≫ arrow (kernelSubobject g) = arrow (kernelSubobject (f ≫ g)) ≫ f
[PROOFSTEP]
simp [kernelSubobjectIsoComp]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
X' : C
f : X' ⟶ X
inst✝¹ : IsIso f
g : X ⟶ Y
inst✝ : HasKernel g
⊢ (kernelSubobjectIsoComp f g).inv ≫ arrow (kernelSubobject (f ≫ g)) = arrow (kernelSubobject g) ≫ inv f
[PROOFSTEP]
simp [kernelSubobjectIsoComp]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : HasKernel (f ≫ h)
⊢ arrow (kernelSubobject f) ≫ f ≫ h = 0
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ (arrow (kernelSubobject (f ≫ h)) ≫ f) ≫ h = 0 ≫ h
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ IsIso (ofLE (kernelSubobject f) (kernelSubobject (f ≫ h)) (_ : kernelSubobject f ≤ kernelSubobject (f ≫ h)))
[PROOFSTEP]
rw [ofLE_mk_le_mk_of_comm (kernelCompMono f h).inv]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ IsIso ((underlyingIso (kernel.ι f)).hom ≫ (kernelCompMono f h).inv ≫ (underlyingIso (kernel.ι (f ≫ h))).inv)
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z✝ : C
inst✝³ : HasZeroMorphisms C
f✝ : X ⟶ Y
inst✝² : HasKernel f✝
f : X ⟶ Y
inst✝¹ : HasKernel f
Z : C
h : Y ⟶ Z
inst✝ : Mono h
⊢ (kernelCompMono f h).inv ≫ kernel.ι (f ≫ h) = kernel.ι f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X : C
⊢ ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [inst : Mono f] [inst_1 : Mono g] (i : A ≅ B),
    i.hom ≫ g = f →
      (fun A f x => Subobject.mk (cokernel.π f).op) A f inst = (fun A f x => Subobject.mk (cokernel.π f).op) B g inst_1
[PROOFSTEP]
rintro A B f g hf hg i rfl
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X A B : C
g : B ⟶ X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (fun A f x => Subobject.mk (cokernel.π f).op) A (i.hom ≫ g) hf = (fun A f x => Subobject.mk (cokernel.π f).op) B g hg
[PROOFSTEP]
refine' Subobject.mk_eq_mk_of_comm _ _ (Iso.op _) (Quiver.Hom.unop_inj _)
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X A B : C
g : B ⟶ X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ cokernel g ≅ cokernel (i.hom ≫ g)
[PROOFSTEP]
exact
  (IsColimit.coconePointUniqueUpToIso (colimit.isColimit _) (isCokernelEpiComp (colimit.isColimit _) i.hom rfl)).symm
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X A B : C
g : B ⟶ X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ ((Iso.op
            (IsColimit.coconePointUniqueUpToIso (colimit.isColimit (parallelPair (i.hom ≫ g) 0))
                (isCokernelEpiComp (colimit.isColimit (parallelPair g 0)) i.hom
                  (_ : i.hom ≫ g = i.hom ≫ g))).symm).hom ≫
        (cokernel.π g).op).unop =
    (cokernel.π (i.hom ≫ g)).op.unop
[PROOFSTEP]
simp only [Iso.comp_inv_eq, Iso.op_hom, Iso.symm_hom, unop_comp, Quiver.Hom.unop_op,
  colimit.comp_coconePointUniqueUpToIso_hom, Cofork.ofπ_ι_app, coequalizer.cofork_π]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasCokernels C
X : C
⊢ ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [inst : Mono f] [inst_1 : Mono g],
    Subobject.mk f ≤ Subobject.mk g →
      Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
          (_ :
            ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (cokernel.π f).op) A f hf =
                  (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
          (Subobject.mk f) ≤
        Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
          (_ :
            ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (cokernel.π f).op) A f hf =
                  (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
          (Subobject.mk g)
[PROOFSTEP]
intro A B f g hf hg h
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
      (_ :
        ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (cokernel.π f).op) A f hf = (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
      (Subobject.mk f) ≤
    Subobject.lift (fun A f x => Subobject.mk (cokernel.π f).op)
      (_ :
        ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (cokernel.π f).op) A f hf = (fun A f x => Subobject.mk (cokernel.π f).op) B g hg)
      (Subobject.mk g)
[PROOFSTEP]
dsimp only [Subobject.lift_mk]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.mk (cokernel.π f).op ≤ Subobject.mk (cokernel.π g).op
[PROOFSTEP]
refine' Subobject.mk_le_mk_of_comm (cokernel.desc f (cokernel.π g) _).op _
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ f ≫ cokernel.π g = 0
[PROOFSTEP]
rw [← Subobject.ofMkLEMk_comp h, Category.assoc, cokernel.condition, comp_zero]
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasCokernels C
X A B : C
f : A ⟶ X
g : B ⟶ X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ (cokernel.desc f (cokernel.π g) (_ : f ≫ cokernel.π g = 0)).op ≫ (cokernel.π f).op = (cokernel.π g).op
[PROOFSTEP]
exact Quiver.Hom.unop_inj (cokernel.π_desc _ _ _)
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
⊢ ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [inst : Mono f] [inst_1 : Mono g] (i : A ≅ B),
    i.hom ≫ g = f →
      (fun A f x => Subobject.mk (kernel.ι f.unop)) A f inst = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g inst_1
[PROOFSTEP]
rintro A B f g hf hg i rfl
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (fun A f x => Subobject.mk (kernel.ι f.unop)) A (i.hom ≫ g) hf = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg
[PROOFSTEP]
refine' Subobject.mk_eq_mk_of_comm _ _ _ _
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ kernel (i.hom ≫ g).unop ≅ kernel g.unop
[PROOFSTEP]
exact
  IsLimit.conePointUniqueUpToIso (limit.isLimit _)
    (isKernelCompMono (limit.isLimit (parallelPair g.unop 0)) i.unop.hom rfl)
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (IsLimit.conePointUniqueUpToIso (limit.isLimit (parallelPair (g.unop ≫ (Iso.unop i).hom) 0))
          (isKernelCompMono (limit.isLimit (parallelPair g.unop 0)) (Iso.unop i).hom
            (_ : g.unop ≫ (Iso.unop i).hom = g.unop ≫ (Iso.unop i).hom))).hom ≫
      kernel.ι g.unop =
    kernel.ι (i.hom ≫ g).unop
[PROOFSTEP]
dsimp
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
g : B ⟶ op X
hg : Mono g
i : A ≅ B
hf : Mono (i.hom ≫ g)
⊢ (IsLimit.conePointUniqueUpToIso (limit.isLimit (parallelPair (g.unop ≫ i.hom.unop) 0))
          (isKernelCompMono (limit.isLimit (parallelPair g.unop 0)) i.hom.unop
            (_ : g.unop ≫ i.hom.unop = g.unop ≫ i.hom.unop))).hom ≫
      kernel.ι g.unop =
    kernel.ι (g.unop ≫ i.hom.unop)
[PROOFSTEP]
simp only [← Iso.eq_inv_comp, limit.conePointUniqueUpToIso_inv_comp, Fork.ofι_π_app]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f : X✝ ⟶ Y
inst✝¹ : HasKernel f
inst✝ : HasKernels C
X : C
⊢ ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [inst : Mono f] [inst_1 : Mono g],
    Subobject.mk f ≤ Subobject.mk g →
      Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
          (_ :
            ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf =
                  (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
          (Subobject.mk f) ≤
        Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
          (_ :
            ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
              i.hom ≫ g = f →
                (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf =
                  (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
          (Subobject.mk g)
[PROOFSTEP]
intro A B f g hf hg h
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
      (_ :
        ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
      (Subobject.mk f) ≤
    Subobject.lift (fun A f x => Subobject.mk (kernel.ι f.unop))
      (_ :
        ∀ ⦃A B : Cᵒᵖ⦄ (f : A ⟶ op X) (g : B ⟶ op X) [hf : Mono f] [hg : Mono g] (i : A ≅ B),
          i.hom ≫ g = f →
            (fun A f x => Subobject.mk (kernel.ι f.unop)) A f hf = (fun A f x => Subobject.mk (kernel.ι f.unop)) B g hg)
      (Subobject.mk g)
[PROOFSTEP]
dsimp only [Subobject.lift_mk]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ Subobject.mk (kernel.ι f.unop) ≤ Subobject.mk (kernel.ι g.unop)
[PROOFSTEP]
refine' Subobject.mk_le_mk_of_comm (kernel.lift g.unop (kernel.ι f.unop) _) _
[GOAL]
case refine'_1
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ kernel.ι f.unop ≫ g.unop = 0
[PROOFSTEP]
rw [← Subobject.ofMkLEMk_comp h, unop_comp, kernel.condition_assoc, zero_comp]
[GOAL]
case refine'_2
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ kernel.lift g.unop (kernel.ι f.unop) (_ : kernel.ι f.unop ≫ g.unop = 0) ≫ kernel.ι g.unop = kernel.ι f.unop
[PROOFSTEP]
exact Quiver.Hom.op_inj (by simp)
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ (kernel.lift g.unop (kernel.ι f.unop) (_ : kernel.ι f.unop ≫ g.unop = 0) ≫ kernel.ι g.unop).op = (kernel.ι f.unop).op
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ (imageSubobjectIso f).hom ≫ image.ι f = arrow (imageSubobject f)
[PROOFSTEP]
simp [imageSubobjectIso]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ (imageSubobjectIso f).inv ≫ arrow (imageSubobject f) = image.ι f
[PROOFSTEP]
simp [imageSubobjectIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasEqualizers C
⊢ Epi (factorThruImageSubobject f)
[PROOFSTEP]
dsimp [factorThruImageSubobject]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasEqualizers C
⊢ Epi (factorThruImage f ≫ (imageSubobjectIso f).inv)
[PROOFSTEP]
apply epi_comp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ factorThruImageSubobject f ≫ arrow (imageSubobject f) = f
[PROOFSTEP]
simp [factorThruImageSubobject, imageSubobject_arrow]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
inst✝² : HasZeroMorphisms C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : HasImage f
inst✝ : Epi (factorThruImageSubobject f)
h : f ≫ g = 0
⊢ factorThruImageSubobject f ≫ arrow (imageSubobject f) ≫ g = 0
[PROOFSTEP]
simp [h]
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
⊢ (k ≫ factorThruImage f) ≫ MonoOver.arrow (MonoOver.mk' (image.ι f)) = k ≫ f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
h : Factors (imageSubobject f) (k ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ f) h = k ≫ factorThruImageSubobject f
[PROOFSTEP]
ext
[GOAL]
case h
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
h : Factors (imageSubobject f) (k ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ f) h ≫ arrow (imageSubobject f) =
    (k ≫ factorThruImageSubobject f) ≫ arrow (imageSubobject f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W W' : C
k : W ⟶ W'
k' : W' ⟶ X
h : Factors (imageSubobject f) (k ≫ k' ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ k' ≫ f) h = k ≫ k' ≫ factorThruImageSubobject f
[PROOFSTEP]
ext
[GOAL]
case h
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W W' : C
k : W ⟶ W'
k' : W' ⟶ X
h : Factors (imageSubobject f) (k ≫ k' ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ k' ≫ f) h ≫ arrow (imageSubobject f) =
    (k ≫ k' ≫ factorThruImageSubobject f) ≫ arrow (imageSubobject f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝² : HasImage f✝
X' : C
h : X' ⟶ X
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ image.preComp h f ≫ image.ι f = image.ι (h ≫ f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
⊢ arrow (imageSubobject 0) = 0
[PROOFSTEP]
rw [← imageSubobject_arrow]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
⊢ (imageSubobjectIso 0).hom ≫ image.ι 0 = 0
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
A B : C
⊢ (imageSubobjectIso 0 ≪≫ imageZero ≪≫ botCoeIsoZero.symm).hom ≫ arrow ⊥ = arrow (imageSubobject 0)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ Epi (ofLE (imageSubobject (h ≫ f)) (imageSubobject f) (_ : imageSubobject (h ≫ f) ≤ imageSubobject f))
[PROOFSTEP]
rw [ofLE_mk_le_mk_of_comm (image.preComp h f)]
[GOAL]
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ Epi ((underlyingIso (image.ι (h ≫ f))).hom ≫ image.preComp h f ≫ (underlyingIso (image.ι f)).inv)
[PROOFSTEP]
infer_instance
[GOAL]
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ image.preComp h f ≫ image.ι f = image.ι (h ≫ f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
f : X ⟶ Y
inst✝¹ : HasImage f
Y' : C
h : Y ⟶ Y'
inst✝ : IsIso h
⊢ (imageSubobjectCompIso f h).hom ≫ arrow (imageSubobject f) = arrow (imageSubobject (f ≫ h)) ≫ inv h
[PROOFSTEP]
simp [imageSubobjectCompIso]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
f : X ⟶ Y
inst✝¹ : HasImage f
Y' : C
h : Y ⟶ Y'
inst✝ : IsIso h
⊢ (imageSubobjectCompIso f h).inv ≫ arrow (imageSubobject (f ≫ h)) = arrow (imageSubobject f) ≫ h
[PROOFSTEP]
simp [imageSubobjectCompIso]
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝¹ : HasImage f✝
f : X ⟶ Y
inst✝ : Mono f
⊢ (imageSubobjectIso f ≪≫ imageMonoIsoSource f ≪≫ (underlyingIso f).symm).hom ≫ arrow (Subobject.mk f) =
    arrow (imageSubobject f)
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝¹ : IsIso h
f : X ⟶ Y
inst✝ : HasImage f
⊢ inv (image.preComp h f) ≫ image.ι (h ≫ f) = image.ι f
[PROOFSTEP]
simp
[GOAL]
C : Type u
inst✝² : Category.{v, u} C
X✝ Y Z : C
f✝ : X✝ ⟶ Y
inst✝¹ : HasImage f✝
A B : C
X : Subobject B
f : A ⟶ B
inst✝ : HasImage f
h : A ⟶ underlying.obj X
w : h ≫ arrow X = f
⊢ ((imageSubobjectIso f).hom ≫ image.lift (MonoFactorisation.mk (underlying.obj X) (arrow X) h)) ≫ arrow X =
    arrow (imageSubobject f)
[PROOFSTEP]
rw [assoc, image.lift_fac, imageSubobject_arrow]
[GOAL]
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
f✝ : X✝ ⟶ Y
inst✝² : HasImage f✝
A B X : C
g : X ⟶ B
inst✝¹ : Mono g
f : A ⟶ B
inst✝ : HasImage f
h : A ⟶ X
w : h ≫ g = f
⊢ (h ≫ (underlyingIso g).inv) ≫ arrow (Subobject.mk g) = f
[PROOFSTEP]
simp [w]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ imageSubobjectMap sq ≫ arrow (imageSubobject g) = arrow (imageSubobject f) ≫ sq.right
[PROOFSTEP]
simp only [imageSubobjectMap, Category.assoc, imageSubobject_arrow']
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (imageSubobjectIso f).hom ≫ image.map sq ≫ image.ι g = arrow (imageSubobject f) ≫ sq.right
[PROOFSTEP]
erw [image.map_ι, ← Category.assoc, imageSubobject_arrow]
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ image.map sq ≫ (imageSubobjectIso (Arrow.mk g).hom).inv = (imageSubobjectIso f).inv ≫ imageSubobjectMap sq
[PROOFSTEP]
ext
[GOAL]
case h
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (image.map sq ≫ (imageSubobjectIso (Arrow.mk g).hom).inv) ≫ arrow (imageSubobject (Arrow.mk g).hom) =
    ((imageSubobjectIso f).inv ≫ imageSubobjectMap sq) ≫ arrow (imageSubobject (Arrow.mk g).hom)
[PROOFSTEP]
simpa using image.map_ι sq
[GOAL]
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (imageSubobjectIso (Arrow.mk f).hom).hom ≫ image.map sq = imageSubobjectMap sq ≫ (imageSubobjectIso g).hom
[PROOFSTEP]
erw [← Iso.comp_inv_eq, Category.assoc, ← (imageSubobjectIso f).eq_inv_comp, image_map_comp_imageSubobjectIso_inv sq]
