l3lab/ntp-mathlib huggingface dataset:
/-- An isomorphism between two three-term complexes induces an isomorphism on homology. -/
def homology'.mapIso (α : Arrow.mk f₁ ≅ Arrow.mk f₂) (β : Arrow.mk g₁ ≅ Arrow.mk g₂)
    (p : α.hom.right = β.hom.left) : homology' f₁ g₁ w₁ ≅ homology' f₂ g₂ w₂ where
  hom := homology'.map w₁ w₂ α.hom β.hom p
  inv :=
    homology'.map w₂ w₁ α.inv β.inv
      (by
        rw [← cancel_mono α.hom.right, ← Comma.comp_right, α.inv_hom_id, Comma.id_right, p, ←
          Comma.comp_left, β.inv_hom_id, Comma.id_left]
        rfl)
  hom_inv_id := by
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> simp only [Iso.hom_inv_id]
  inv_hom_id := by
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> 

Proof state:
case e_α
ι : 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₃)
α : Arrow.mk f₁ ≅ Arrow.mk f₂
β : Arrow.mk g₁ ≅ Arrow.mk g₂
p : α.hom.right = β.hom.left
⊢ α.inv ≫ α.hom = 𝟙 (Arrow.mk f₂)

Next tactic:
simp only [Iso.inv_hom_id]
/-- An isomorphism between two three-term complexes induces an isomorphism on homology. -/
def homology'.mapIso (α : Arrow.mk f₁ ≅ Arrow.mk f₂) (β : Arrow.mk g₁ ≅ Arrow.mk g₂)
    (p : α.hom.right = β.hom.left) : homology' f₁ g₁ w₁ ≅ homology' f₂ g₂ w₂ where
  hom := homology'.map w₁ w₂ α.hom β.hom p
  inv :=
    homology'.map w₂ w₁ α.inv β.inv
      (by
        rw [← cancel_mono α.hom.right, ← Comma.comp_right, α.inv_hom_id, Comma.id_right, p, ←
          Comma.comp_left, β.inv_hom_id, Comma.id_left]
        rfl)
  hom_inv_id := by
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> simp only [Iso.hom_inv_id]
  inv_hom_id := by
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> 

Proof state:
case e_β
ι : 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₃)
α : Arrow.mk f₁ ≅ Arrow.mk f₂
β : Arrow.mk g₁ ≅ Arrow.mk g₂
p : α.hom.right = β.hom.left
⊢ β.inv ≫ β.hom = 𝟙 (Arrow.mk g₂)

Next tactic:
simp only [Iso.inv_hom_id]
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w 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
g : B ⟶ C
w : f ≫ g = 0
f' : A ⟶ B
g' : B ⟶ C
w' : f' ≫ g' = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pf : f = f'
pg : g = g'
⊢ (𝟭 V).map (𝟙 (Arrow.mk f).left) ≫ (Arrow.mk f').hom = (Arrow.mk f).hom ≫ (𝟭 V).map (𝟙 (Arrow.mk f).right)

Next tactic:
aesop_cat
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, 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
w : f ≫ g = 0
f' : A ⟶ B
g' : B ⟶ C
w' : f' ≫ g' = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pf : f = f'
pg : g = g'
⊢ (𝟭 V).map (𝟙 (Arrow.mk g).left) ≫ (Arrow.mk g').hom = (Arrow.mk g).hom ≫ (𝟭 V).map (𝟙 (Arrow.mk g).right)

Next tactic:
aesop_cat
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' 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
g : B ⟶ C
w : f ≫ g = 0
f' : A ⟶ B
g' : B ⟶ C
w' : f' ≫ g' = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pf : f = f'
pg : g = g'
⊢ (𝟭 V).map (𝟙 (Arrow.mk f').left) ≫ (Arrow.mk f).hom = (Arrow.mk f').hom ≫ (𝟭 V).map (𝟙 (Arrow.mk f').right)

Next tactic:
aesop_cat
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, 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
w : f ≫ g = 0
f' : A ⟶ B
g' : B ⟶ C
w' : f' ≫ g' = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pf : f = f'
pg : g = g'
⊢ (𝟭 V).map (𝟙 (Arrow.mk g').left) ≫ (Arrow.mk g).hom = (Arrow.mk g').hom ≫ (𝟭 V).map (𝟙 (Arrow.mk g').right)

Next tactic:
aesop_cat
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := 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
w : f ≫ g = 0
f' : A ⟶ B
g' : B ⟶ C
w' : f' ≫ g' = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pf : f = f'
pg : g = g'
⊢ map w w' (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) ≫
      map w' w (CommaMorphism.mk (𝟙 (Arrow.mk f').left) (𝟙 (Arrow.mk f').right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g').left) (𝟙 (Arrow.mk g').right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f').left) (𝟙 (Arrow.mk f').right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f').left) (𝟙 (Arrow.mk f').right)).right) =
    𝟙 (homology' f g w)

Next tactic:
obtain rfl := pf
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    

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
w : f ≫ g = 0
g' : B ⟶ C
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pg : g = g'
w' : f ≫ g' = 0
⊢ map w w' (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) ≫
      map w' w (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g').left) (𝟙 (Arrow.mk g').right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) =
    𝟙 (homology' f g w)

Next tactic:
obtain rfl := pg
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    

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
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ map w w' (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) ≫
      map w' w (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) =
    𝟙 (homology' f g w)

Next tactic:
rw [homology'.map_comp, ← homology'.map_id]
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    

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
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ map w w
      (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) ≫
        CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
      (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) ≫
        CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
      (_ :
        (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) ≫
              CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
          (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) ≫
              CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right)).left) =
    map w w (𝟙 (Arrow.mk f)) (𝟙 (Arrow.mk g)) (_ : (𝟙 (Arrow.mk f)).right = (𝟙 (Arrow.mk f)).right)

Next tactic:
congr
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> 

Proof state:
case e_α
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) ≫
      CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) =
    𝟙 (Arrow.mk f)

Next tactic:
aesop_cat
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> 

Proof state:
case e_β
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) ≫
      CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) =
    𝟙 (Arrow.mk g)

Next tactic:
aesop_cat
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> aesop_cat
  inv_hom_id := 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
w : f ≫ g = 0
f' : A ⟶ B
g' : B ⟶ C
w' : f' ≫ g' = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pf : f = f'
pg : g = g'
⊢ map w' w (CommaMorphism.mk (𝟙 (Arrow.mk f').left) (𝟙 (Arrow.mk f').right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g').left) (𝟙 (Arrow.mk g').right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f').left) (𝟙 (Arrow.mk f').right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f').left) (𝟙 (Arrow.mk f').right)).right) ≫
      map w w' (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) =
    𝟙 (homology' f' g' w')

Next tactic:
obtain rfl := pf
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> aesop_cat
  inv_hom_id := by
    obtain rfl := pf
    

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
w : f ≫ g = 0
g' : B ⟶ C
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
pg : g = g'
w' : f ≫ g' = 0
⊢ map w' w (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g').left) (𝟙 (Arrow.mk g').right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) ≫
      map w w' (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) =
    𝟙 (homology' f g' w')

Next tactic:
obtain rfl := pg
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> aesop_cat
  inv_hom_id := by
    obtain rfl := pf
    obtain rfl := pg
    

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
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ map w' w (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) ≫
      map w w' (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
        (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
        (_ :
          (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
            (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right) =
    𝟙 (homology' f g w')

Next tactic:
rw [homology'.map_comp, ← homology'.map_id]
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> aesop_cat
  inv_hom_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    

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
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ map w' w'
      (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) ≫
        CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right))
      (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) ≫
        CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right))
      (_ :
        (CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) ≫
              CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right)).right =
          (CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) ≫
              CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right)).left) =
    map w' w' (𝟙 (Arrow.mk f)) (𝟙 (Arrow.mk g)) (_ : (𝟙 (Arrow.mk f)).right = (𝟙 (Arrow.mk f)).right)

Next tactic:
congr
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> aesop_cat
  inv_hom_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> 

Proof state:
case e_α
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) ≫
      CommaMorphism.mk (𝟙 (Arrow.mk f).left) (𝟙 (Arrow.mk f).right) =
    𝟙 (Arrow.mk f)

Next tactic:
aesop_cat
/-- `homology f g w ≅ homology f' g' w'` if `f = f'` and `g = g'`.
(Note the objects are not changing here.)
-/
@[simps]
def homology'.congr (pf : f = f') (pg : g = g') : homology' f g w ≅ homology' f' g' w' where
  hom := homology'.map w w' ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  inv := homology'.map w' w ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ ⟨𝟙 _, 𝟙 _, by aesop_cat⟩ rfl
  hom_inv_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> aesop_cat
  inv_hom_id := by
    obtain rfl := pf
    obtain rfl := pg
    rw [homology'.map_comp, ← homology'.map_id]
    congr <;> 

Proof state:
case e_β
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : HasZeroMorphisms V
A B C : V
f : A ⟶ B
g : B ⟶ C
w : f ≫ g = 0
inst✝³ : HasKernels V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
w' : f ≫ g = 0
⊢ CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) ≫
      CommaMorphism.mk (𝟙 (Arrow.mk g).left) (𝟙 (Arrow.mk g).right) =
    𝟙 (Arrow.mk g)

Next tactic:
aesop_cat
/-- While `imageToKernel f g w` provides a morphism
`imageSubobject f ⟶ kernelSubobject g`
in terms of the subobject API,
this variant provides a morphism
`image f ⟶ kernel g`,
which is sometimes more convenient.
-/
def imageToKernel' (w : f ≫ g = 0) : image f ⟶ kernel g :=
  kernel.lift g (image.ι f) <| 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
w✝ : f ≫ g = 0
inst✝¹ : HasKernels V
inst✝ : HasImages V
w : f ≫ g = 0
⊢ image.ι f ≫ g = 0

Next tactic:
ext
/-- While `imageToKernel f g w` provides a morphism
`imageSubobject f ⟶ kernelSubobject g`
in terms of the subobject API,
this variant provides a morphism
`image f ⟶ kernel g`,
which is sometimes more convenient.
-/
def imageToKernel' (w : f ≫ g = 0) : image f ⟶ kernel g :=
  kernel.lift g (image.ι f) <| by
    ext
    

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

Next tactic:
simpa using w
@[simp]
theorem imageSubobjectIso_imageToKernel' (w : f ≫ g = 0) :
    (imageSubobjectIso f).hom ≫ imageToKernel' f g w =
      imageToKernel f g w ≫ (kernelSubobjectIso g).hom := 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
w✝ : f ≫ g = 0
inst✝¹ : HasKernels V
inst✝ : HasImages V
w : f ≫ g = 0
⊢ (imageSubobjectIso f).hom ≫ imageToKernel' f g w = imageToKernel f g w ≫ (kernelSubobjectIso g).hom

Next tactic:
ext