l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem imageToKernel_comp_mono {D : V} (h : C ⟶ D) [Mono h] (w) :
    imageToKernel f (g ≫ h) w =
      imageToKernel f g ((cancel_mono h).mp (by simpa using w : (f ≫ g) ≫ h = 0 ≫ h)) ≫
        (Subobject.isoOfEq _ _ (kernelSubobject_comp_mono g h)).inv := by
  ext
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝² : HasKernels V
inst✝¹ : HasImages V
D : V
h : C ⟶ D
inst✝ : Mono h
w : f ≫ g ≫ h = 0
⊢ imageToKernel f (g ≫ h) w ≫ Subobject.arrow (kernelSubobject (g ≫ h)) =
    (imageToKernel f g (_ : f ≫ g = 0) ≫
        (Subobject.isoOfEq (kernelSubobject (g ≫ h)) (kernelSubobject g)
            (_ : kernelSubobject (g ≫ h) = kernelSubobject g)).inv) ≫
      Subobject.arrow (kernelSubobject (g ≫ h))

Next tactic:
simp
@[simp]
theorem imageToKernel_epi_comp {Z : V} (h : Z ⟶ A) [Epi h] (w) :
    imageToKernel (h ≫ f) g w =
      Subobject.ofLE _ _ (imageSubobject_comp_le h f) ≫
        imageToKernel f g ((cancel_epi h).mp (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝² : HasKernels V
inst✝¹ : HasImages V
Z : V
h : Z ⟶ A
inst✝ : Epi h
w : (h ≫ f) ≫ g = 0
⊢ h ≫ f ≫ g = h ≫ 0

Next tactic:
simpa using w
@[simp]
theorem imageToKernel_epi_comp {Z : V} (h : Z ⟶ A) [Epi h] (w) :
    imageToKernel (h ≫ f) g w =
      Subobject.ofLE _ _ (imageSubobject_comp_le h f) ≫
        imageToKernel f g ((cancel_epi h).mp (by simpa using w : h ≫ f ≫ g = h ≫ 0)) := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝² : HasKernels V
inst✝¹ : HasImages V
Z : V
h : Z ⟶ A
inst✝ : Epi h
w : (h ≫ f) ≫ g = 0
⊢ imageToKernel (h ≫ f) g w =
    Subobject.ofLE (imageSubobject (h ≫ f)) (imageSubobject f) (_ : imageSubobject (h ≫ f) ≤ imageSubobject f) ≫
      imageToKernel f g (_ : f ≫ g = 0)

Next tactic:
ext
@[simp]
theorem imageToKernel_epi_comp {Z : V} (h : Z ⟶ A) [Epi h] (w) :
    imageToKernel (h ≫ f) g w =
      Subobject.ofLE _ _ (imageSubobject_comp_le h f) ≫
        imageToKernel f g ((cancel_epi h).mp (by simpa using w : h ≫ f ≫ g = h ≫ 0)) := by
  ext
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝² : HasKernels V
inst✝¹ : HasImages V
Z : V
h : Z ⟶ A
inst✝ : Epi h
w : (h ≫ f) ≫ g = 0
⊢ imageToKernel (h ≫ f) g w ≫ Subobject.arrow (kernelSubobject g) =
    (Subobject.ofLE (imageSubobject (h ≫ f)) (imageSubobject f) (_ : imageSubobject (h ≫ f) ≤ imageSubobject f) ≫
        imageToKernel f g (_ : f ≫ g = 0)) ≫
      Subobject.arrow (kernelSubobject g)

Next tactic:
simp
@[simp]
theorem imageToKernel_comp_hom_inv_comp [HasEqualizers V] [HasImages V] {Z : V} {i : B ≅ Z} (w) :
    imageToKernel (f ≫ i.hom) (i.inv ≫ g) w =
      (imageSubobjectCompIso _ _).hom ≫
        imageToKernel f g (by 

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasEqualizers V
inst✝ : HasImages V
Z : V
i : B ≅ Z
w : (f ≫ i.hom) ≫ i.inv ≫ g = 0
⊢ f ≫ g = 0

Next tactic:
simpa using w
@[simp]
theorem imageToKernel_comp_hom_inv_comp [HasEqualizers V] [HasImages V] {Z : V} {i : B ≅ Z} (w) :
    imageToKernel (f ≫ i.hom) (i.inv ≫ g) w =
      (imageSubobjectCompIso _ _).hom ≫
        imageToKernel f g (by simpa using w) ≫ (kernelSubobjectIsoComp i.inv g).inv := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasEqualizers V
inst✝ : HasImages V
Z : V
i : B ≅ Z
w : (f ≫ i.hom) ≫ i.inv ≫ g = 0
⊢ imageToKernel (f ≫ i.hom) (i.inv ≫ g) w =
    (imageSubobjectCompIso f i.hom).hom ≫ imageToKernel f g (_ : f ≫ g = 0) ≫ (kernelSubobjectIsoComp i.inv g).inv

Next tactic:
ext
@[simp]
theorem imageToKernel_comp_hom_inv_comp [HasEqualizers V] [HasImages V] {Z : V} {i : B ≅ Z} (w) :
    imageToKernel (f ≫ i.hom) (i.inv ≫ g) w =
      (imageSubobjectCompIso _ _).hom ≫
        imageToKernel f g (by simpa using w) ≫ (kernelSubobjectIsoComp i.inv g).inv := by
  ext
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasEqualizers V
inst✝ : HasImages V
Z : V
i : B ≅ Z
w : (f ≫ i.hom) ≫ i.inv ≫ g = 0
⊢ imageToKernel (f ≫ i.hom) (i.inv ≫ g) w ≫ Subobject.arrow (kernelSubobject (i.inv ≫ g)) =
    ((imageSubobjectCompIso f i.hom).hom ≫ imageToKernel f g (_ : f ≫ g = 0) ≫ (kernelSubobjectIsoComp i.inv g).inv) ≫
      Subobject.arrow (kernelSubobject (i.inv ≫ g))

Next tactic:
simp
/-- `imageToKernel` for `A --0--> B --g--> C`, where `g` is a mono is itself an epi
(i.e. the sequence is exact at `B`).
-/
instance imageToKernel_epi_of_zero_of_mono [HasKernels V] [HasZeroObject V] [Mono g] :
    Epi (imageToKernel (0 : A ⟶ B) g (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝² : HasKernels V
inst✝¹ : HasZeroObject V
inst✝ : Mono g
⊢ 0 ≫ g = 0

Next tactic:
simp
/-- `imageToKernel` for `A --f--> B --0--> C`, where `g` is an epi is itself an epi
(i.e. the sequence is exact at `B`).
-/
instance imageToKernel_epi_of_epi_of_zero [HasImages V] [Epi f] :
    Epi (imageToKernel f (0 : B ⟶ C) (by 

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasImages V
inst✝ : Epi f
⊢ f ≫ 0 = 0

Next tactic:
simp
/-- `imageToKernel` for `A --f--> B --0--> C`, where `g` is an epi is itself an epi
(i.e. the sequence is exact at `B`).
-/
instance imageToKernel_epi_of_epi_of_zero [HasImages V] [Epi f] :
    Epi (imageToKernel f (0 : B ⟶ C) (by simp)) := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasImages V
inst✝ : Epi f
⊢ Epi (imageToKernel f 0 (_ : f ≫ 0 = 0))

Next tactic:
simp only [imageToKernel_zero_right]
/-- `imageToKernel` for `A --f--> B --0--> C`, where `g` is an epi is itself an epi
(i.e. the sequence is exact at `B`).
-/
instance imageToKernel_epi_of_epi_of_zero [HasImages V] [Epi f] :
    Epi (imageToKernel f (0 : B ⟶ C) (by simp)) := by
  simp only [imageToKernel_zero_right]
  

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasImages V
inst✝ : Epi f
⊢ Epi (Subobject.arrow (imageSubobject f) ≫ inv (Subobject.arrow (kernelSubobject 0)))

Next tactic:
haveI := epi_image_of_epi f
/-- `imageToKernel` for `A --f--> B --0--> C`, where `g` is an epi is itself an epi
(i.e. the sequence is exact at `B`).
-/
instance imageToKernel_epi_of_epi_of_zero [HasImages V] [Epi f] :
    Epi (imageToKernel f (0 : B ⟶ C) (by simp)) := by
  simp only [imageToKernel_zero_right]
  haveI := epi_image_of_epi f
  

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasImages V
inst✝ : Epi f
this : Epi (image.ι f)
⊢ Epi (Subobject.arrow (imageSubobject f) ≫ inv (Subobject.arrow (kernelSubobject 0)))

Next tactic:
rw [← imageSubobject_arrow]
/-- `imageToKernel` for `A --f--> B --0--> C`, where `g` is an epi is itself an epi
(i.e. the sequence is exact at `B`).
-/
instance imageToKernel_epi_of_epi_of_zero [HasImages V] [Epi f] :
    Epi (imageToKernel f (0 : B ⟶ C) (by simp)) := by
  simp only [imageToKernel_zero_right]
  haveI := epi_image_of_epi f
  rw [← imageSubobject_arrow]
  

Proof state:
ι : Type u_1
V : Type u
inst✝³ : Category.{v, u} V
inst✝² : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
inst✝¹ : HasImages V
inst✝ : Epi f
this : Epi (image.ι f)
⊢ Epi (((imageSubobjectIso f).hom ≫ image.ι f) ≫ inv (Subobject.arrow (kernelSubobject 0)))

Next tactic:
refine' @epi_comp _ _ _ _ _ _ (epi_comp _ _) _ _
@[reassoc (attr := simp)]
theorem homology'.π_desc {D : V} (k : (kernelSubobject g : V) ⟶ D)
    (p : imageToKernel f g w ≫ k = 0) : homology'.π f g w ≫ homology'.desc f g w k p = k := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁴ : Category.{v, u} V
inst✝³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝² : HasImage f
g : B ⟶ C
inst✝¹ : HasKernel g
w : f ≫ g = 0
inst✝ : HasCokernel (imageToKernel f g w)
D : V
k : Subobject.underlying.obj (kernelSubobject g) ⟶ D
p : imageToKernel f g w ≫ k = 0
⊢ π f g w ≫ desc f g w k p = k

Next tactic:
simp [homology'.π, homology'.desc]
/-- The cokernel of the map `Im f ⟶ Ker 0` is isomorphic to the cokernel of `f.` -/
def homology'OfZeroRight [HasCokernel (imageToKernel f (0 : B ⟶ C) comp_zero)] [HasCokernel f]
    [HasCokernel (image.ι f)] [Epi (factorThruImage f)] :
    homology' f (0 : B ⟶ C) comp_zero ≅ cokernel f :=
  (cokernel.mapIso _ _ (imageSubobjectIso _) ((kernelSubobjectIso 0).trans kernelZeroIsoSource)
        (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁸ : Category.{v, u} V
inst✝⁷ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝⁶ : HasImage f
g : B ⟶ C
inst✝⁵ : HasKernel g
w : f ≫ g = 0
inst✝⁴ : HasCokernel (imageToKernel f g w)
inst✝³ : HasCokernel (imageToKernel f 0 (_ : f ≫ 0 = 0))
inst✝² : HasCokernel f
inst✝¹ : HasCokernel (image.ι f)
inst✝ : Epi (factorThruImage f)
⊢ imageToKernel f 0 (_ : f ≫ 0 = 0) ≫ (kernelSubobjectIso 0 ≪≫ kernelZeroIsoSource).hom =
    (imageSubobjectIso f).hom ≫ image.ι f

Next tactic:
simp
/-- `homology 0 0 _` is just the middle object. -/
@[simps]
def homology'ZeroZero [HasZeroObject V] [HasImage (0 : A ⟶ B)]
    [HasCokernel (imageToKernel (0 : A ⟶ B) (0 : B ⟶ C) zero_comp)] :
    homology' (0 : A ⟶ B) (0 : B ⟶ C) zero_comp ≅ B where
  hom := homology'.desc (0 : A ⟶ B) (0 : B ⟶ C) zero_comp (kernelSubobject 0).arrow (by 

Proof state:
ι : Type u_1
V : Type u
inst✝⁷ : Category.{v, u} V
inst✝⁶ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝⁵ : HasImage f
g : B ⟶ C
inst✝⁴ : HasKernel g
w : f ≫ g = 0
inst✝³ : HasCokernel (imageToKernel f g w)
inst✝² : HasZeroObject V
inst✝¹ : HasImage 0
inst✝ : HasCokernel (imageToKernel 0 0 (_ : 0 ≫ 0 = 0))
⊢ imageToKernel 0 0 (_ : 0 ≫ 0 = 0) ≫ Subobject.arrow (kernelSubobject 0) = 0

Next tactic:
simp
/-- Given compatible commutative squares between
a pair `f g` and a pair `f' g'` satisfying `f ≫ g = 0` and `f' ≫ g' = 0`,
the `imageToKernel` morphisms intertwine the induced map on kernels and the induced map on images.
-/
@[reassoc]
theorem imageSubobjectMap_comp_imageToKernel (p : α.right = β.left) :
    imageToKernel f g w ≫ kernelSubobjectMap β = imageSubobjectMap α ≫ imageToKernel f' g' w' := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝¹⁴ : Category.{v, u} V
inst✝¹³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹² : HasImage f
g : B ⟶ C
inst✝¹¹ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁰ : HasImage f'
g' : B' ⟶ C'
inst✝⁹ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝⁸ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝⁷ : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝⁶ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝⁵ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁴ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝³ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝² : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝¹ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
p : α.right = β.left
⊢ imageToKernel f g w ≫ kernelSubobjectMap β = imageSubobjectMap α ≫ imageToKernel f' g' w'

Next tactic:
ext
/-- Given compatible commutative squares between
a pair `f g` and a pair `f' g'` satisfying `f ≫ g = 0` and `f' ≫ g' = 0`,
the `imageToKernel` morphisms intertwine the induced map on kernels and the induced map on images.
-/
@[reassoc]
theorem imageSubobjectMap_comp_imageToKernel (p : α.right = β.left) :
    imageToKernel f g w ≫ kernelSubobjectMap β = imageSubobjectMap α ≫ imageToKernel f' g' w' := by
  ext
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝¹⁴ : Category.{v, u} V
inst✝¹³ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹² : HasImage f
g : B ⟶ C
inst✝¹¹ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁰ : HasImage f'
g' : B' ⟶ C'
inst✝⁹ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝⁸ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝⁷ : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝⁶ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝⁵ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁴ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝³ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝² : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝¹ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
p : α.right = β.left
⊢ (imageToKernel f g w ≫ kernelSubobjectMap β) ≫ Subobject.arrow (kernelSubobject g') =
    (imageSubobjectMap α ≫ imageToKernel f' g' w') ≫ Subobject.arrow (kernelSubobject g')

Next tactic:
simp [p]
/-- Given compatible commutative squares between
a pair `f g` and a pair `f' g'` satisfying `f ≫ g = 0` and `f' ≫ g' = 0`,
we get a morphism on homology.
-/
def homology'.map (p : α.right = β.left) : homology' f g w ⟶ homology' f' g' w' :=
  cokernel.desc _ (kernelSubobjectMap β ≫ cokernel.π _) <| by
    

Proof state:
ι : Type u_1
V : Type u
inst✝¹⁹ : Category.{v, u} V
inst✝¹⁸ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹⁷ : HasImage f
g : B ⟶ C
inst✝¹⁶ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁵ : HasImage f'
g' : B' ⟶ C'
inst✝¹⁴ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝¹³ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝¹² : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝¹¹ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝¹⁰ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁹ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝⁸ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝⁷ : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝⁶ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝⁵ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
inst✝⁴ : HasCokernel (imageToKernel f g w)
inst✝³ : HasCokernel (imageToKernel f' g' w')
inst✝² : HasCokernel (imageToKernel f₁ g₁ w₁)
inst✝¹ : HasCokernel (imageToKernel f₂ g₂ w₂)
inst✝ : HasCokernel (imageToKernel f₃ g₃ w₃)
p : α.right = β.left
⊢ imageToKernel f g w ≫ kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w') = 0

Next tactic:
rw [imageSubobjectMap_comp_imageToKernel_assoc w w' α β p]
/-- Given compatible commutative squares between
a pair `f g` and a pair `f' g'` satisfying `f ≫ g = 0` and `f' ≫ g' = 0`,
we get a morphism on homology.
-/
def homology'.map (p : α.right = β.left) : homology' f g w ⟶ homology' f' g' w' :=
  cokernel.desc _ (kernelSubobjectMap β ≫ cokernel.π _) <| by
    rw [imageSubobjectMap_comp_imageToKernel_assoc w w' α β p]
    

Proof state:
ι : Type u_1
V : Type u
inst✝¹⁹ : Category.{v, u} V
inst✝¹⁸ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹⁷ : HasImage f
g : B ⟶ C
inst✝¹⁶ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁵ : HasImage f'
g' : B' ⟶ C'
inst✝¹⁴ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝¹³ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝¹² : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝¹¹ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝¹⁰ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁹ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝⁸ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝⁷ : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝⁶ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝⁵ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
inst✝⁴ : HasCokernel (imageToKernel f g w)
inst✝³ : HasCokernel (imageToKernel f' g' w')
inst✝² : HasCokernel (imageToKernel f₁ g₁ w₁)
inst✝¹ : HasCokernel (imageToKernel f₂ g₂ w₂)
inst✝ : HasCokernel (imageToKernel f₃ g₃ w₃)
p : α.right = β.left
⊢ imageSubobjectMap α ≫ imageToKernel f' g' w' ≫ cokernel.π (imageToKernel f' g' w') = 0

Next tactic:
simp only [cokernel.condition, comp_zero]
@[reassoc (attr := simp)]
theorem homology'.π_map (p : α.right = β.left) :
    homology'.π f g w ≫ homology'.map w w' α β p =
      kernelSubobjectMap β ≫ homology'.π f' g' w' := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝¹⁹ : Category.{v, u} V
inst✝¹⁸ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹⁷ : HasImage f
g : B ⟶ C
inst✝¹⁶ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁵ : HasImage f'
g' : B' ⟶ C'
inst✝¹⁴ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝¹³ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝¹² : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝¹¹ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝¹⁰ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁹ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝⁸ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝⁷ : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝⁶ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝⁵ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
inst✝⁴ : HasCokernel (imageToKernel f g w)
inst✝³ : HasCokernel (imageToKernel f' g' w')
inst✝² : HasCokernel (imageToKernel f₁ g₁ w₁)
inst✝¹ : HasCokernel (imageToKernel f₂ g₂ w₂)
inst✝ : HasCokernel (imageToKernel f₃ g₃ w₃)
p : α.right = β.left
⊢ π f g w ≫ map w w' α β p = kernelSubobjectMap β ≫ π f' g' w'

Next tactic:
simp only [homology'.π, homology'.map, cokernel.π_desc]
@[simp]
lemma homology'.π_map_apply [ConcreteCategory.{w} V] (p : α.right = β.left)
    (x : (forget V).obj (Subobject.underlying.obj (kernelSubobject g))) :
    homology'.map w w' α β p (homology'.π f g w x) =
      homology'.π f' g' w' (kernelSubobjectMap β x) := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝²⁰ : Category.{v, u} V
inst✝¹⁹ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹⁸ : HasImage f
g : B ⟶ C
inst✝¹⁷ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁶ : HasImage f'
g' : B' ⟶ C'
inst✝¹⁵ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝¹⁴ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝¹³ : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝¹² : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝¹¹ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝¹⁰ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝⁹ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝⁸ : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝⁷ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝⁶ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
inst✝⁵ : HasCokernel (imageToKernel f g w)
inst✝⁴ : HasCokernel (imageToKernel f' g' w')
inst✝³ : HasCokernel (imageToKernel f₁ g₁ w₁)
inst✝² : HasCokernel (imageToKernel f₂ g₂ w₂)
inst✝¹ : HasCokernel (imageToKernel f₃ g₃ w₃)
inst✝ : ConcreteCategory V
p : α.right = β.left
x : (forget V).obj (Subobject.underlying.obj (kernelSubobject g))
⊢ (map w w' α β p) ((π f g w) x) = (π f' g' w') ((kernelSubobjectMap β) x)

Next tactic:
simp only [← comp_apply, homology'.π_map w w' α β p]
@[reassoc (attr := simp), elementwise (attr := simp)]
theorem homology'.map_desc (p : α.right = β.left) {D : V} (k : (kernelSubobject g' : V) ⟶ D)
    (z : imageToKernel f' g' w' ≫ k = 0) :
    homology'.map w w' α β p ≫ homology'.desc f' g' w' k z =
      homology'.desc f g w (kernelSubobjectMap β ≫ k)
        (by 

Proof state:
ι : Type u_1
V : Type u
inst✝¹⁹ : Category.{v, u} V
inst✝¹⁸ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹⁷ : HasImage f
g : B ⟶ C
inst✝¹⁶ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁵ : HasImage f'
g' : B' ⟶ C'
inst✝¹⁴ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝¹³ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝¹² : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝¹¹ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝¹⁰ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁹ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝⁸ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝⁷ : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝⁶ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝⁵ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
inst✝⁴ : HasCokernel (imageToKernel f g w)
inst✝³ : HasCokernel (imageToKernel f' g' w')
inst✝² : HasCokernel (imageToKernel f₁ g₁ w₁)
inst✝¹ : HasCokernel (imageToKernel f₂ g₂ w₂)
inst✝ : HasCokernel (imageToKernel f₃ g₃ w₃)
p : α.right = β.left
D : V
k : Subobject.underlying.obj (kernelSubobject g') ⟶ D
z : imageToKernel f' g' w' ≫ k = 0
⊢ imageToKernel f g w ≫ kernelSubobjectMap β ≫ k = 0

Next tactic:
simp only [imageSubobjectMap_comp_imageToKernel_assoc w w' α β p, z, comp_zero]
@[reassoc (attr := simp), elementwise (attr := simp)]
theorem homology'.map_desc (p : α.right = β.left) {D : V} (k : (kernelSubobject g' : V) ⟶ D)
    (z : imageToKernel f' g' w' ≫ k = 0) :
    homology'.map w w' α β p ≫ homology'.desc f' g' w' k z =
      homology'.desc f g w (kernelSubobjectMap β ≫ k)
        (by simp only [imageSubobjectMap_comp_imageToKernel_assoc w w' α β p, z, comp_zero]) := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝¹⁹ : Category.{v, u} V
inst✝¹⁸ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹⁷ : HasImage f
g : B ⟶ C
inst✝¹⁶ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁵ : HasImage f'
g' : B' ⟶ C'
inst✝¹⁴ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝¹³ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝¹² : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝¹¹ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝¹⁰ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁹ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝⁸ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝⁷ : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝⁶ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝⁵ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
inst✝⁴ : HasCokernel (imageToKernel f g w)
inst✝³ : HasCokernel (imageToKernel f' g' w')
inst✝² : HasCokernel (imageToKernel f₁ g₁ w₁)
inst✝¹ : HasCokernel (imageToKernel f₂ g₂ w₂)
inst✝ : HasCokernel (imageToKernel f₃ g₃ w₃)
p : α.right = β.left
D : V
k : Subobject.underlying.obj (kernelSubobject g') ⟶ D
z : imageToKernel f' g' w' ≫ k = 0
⊢ map w w' α β p ≫ desc f' g' w' k z =
    desc f g w (kernelSubobjectMap β ≫ k) (_ : imageToKernel f g w ≫ kernelSubobjectMap β ≫ k = 0)

Next tactic:
ext
@[reassoc (attr := simp), elementwise (attr := simp)]
theorem homology'.map_desc (p : α.right = β.left) {D : V} (k : (kernelSubobject g' : V) ⟶ D)
    (z : imageToKernel f' g' w' ≫ k = 0) :
    homology'.map w w' α β p ≫ homology'.desc f' g' w' k z =
      homology'.desc f g w (kernelSubobjectMap β ≫ k)
        (by simp only [imageSubobjectMap_comp_imageToKernel_assoc w w' α β p, z, comp_zero]) := by
  ext
  

Proof state:
case p
ι : Type u_1
V : Type u
inst✝¹⁹ : Category.{v, u} V
inst✝¹⁸ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
inst✝¹⁷ : HasImage f
g : B ⟶ C
inst✝¹⁶ : HasKernel g
w : f ≫ g = 0
A' B' C' : V
f' : A' ⟶ B'
inst✝¹⁵ : HasImage f'
g' : B' ⟶ C'
inst✝¹⁴ : HasKernel g'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
inst✝¹³ : HasImageMap α
β : Arrow.mk g ⟶ Arrow.mk g'
A₁ B₁ C₁ : V
f₁ : A₁ ⟶ B₁
inst✝¹² : HasImage f₁
g₁ : B₁ ⟶ C₁
inst✝¹¹ : HasKernel g₁
w₁ : f₁ ≫ g₁ = 0
A₂ B₂ C₂ : V
f₂ : A₂ ⟶ B₂
inst✝¹⁰ : HasImage f₂
g₂ : B₂ ⟶ C₂
inst✝⁹ : HasKernel g₂
w₂ : f₂ ≫ g₂ = 0
A₃ B₃ C₃ : V
f₃ : A₃ ⟶ B₃
inst✝⁸ : HasImage f₃
g₃ : B₃ ⟶ C₃
inst✝⁷ : HasKernel g₃
w₃ : f₃ ≫ g₃ = 0
α₁ : Arrow.mk f₁ ⟶ Arrow.mk f₂
inst✝⁶ : HasImageMap α₁
β₁ : Arrow.mk g₁ ⟶ Arrow.mk g₂
α₂ : Arrow.mk f₂ ⟶ Arrow.mk f₃
inst✝⁵ : HasImageMap α₂
β₂ : Arrow.mk g₂ ⟶ Arrow.mk g₃
inst✝⁴ : HasCokernel (imageToKernel f g w)
inst✝³ : HasCokernel (imageToKernel f' g' w')
inst✝² : HasCokernel (imageToKernel f₁ g₁ w₁)
inst✝¹ : HasCokernel (imageToKernel f₂ g₂ w₂)
inst✝ : HasCokernel (imageToKernel f₃ g₃ w₃)
p : α.right = β.left
D : V
k : Subobject.underlying.obj (kernelSubobject g') ⟶ D
z : imageToKernel f' g' w' ≫ k = 0
⊢ π f g w ≫ map w w' α β p ≫ desc f' g' w' k z =
    π f g w ≫ desc f g w (kernelSubobjectMap β ≫ k) (_ : imageToKernel f g w ≫ kernelSubobjectMap β ≫ k = 0)

Next tactic:
simp only [homology'.π_desc, homology'.π_map_assoc]