l3lab/ntp-mathlib huggingface dataset:
@[ext]
theorem hom_from_ext {W : A} (a b : homology' f g w ⟶ W)
    (h : π' f g w ≫ a = π' f g w ≫ b) : a = b := by
  dsimp [π'] at h
  apply_fun fun e => (homology'IsoCokernelLift f g w).inv ≫ e
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : homology' f g w ⟶ W
h :
  (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ a =
    (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ b
⊢ (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) a = (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) b
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : homology' f g w ⟶ W
h :
  (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ a =
    (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ b
⊢ Function.Injective fun e => (homology'IsoCokernelLift f g w).inv ≫ e

Next tactic:
swap
@[ext]
theorem hom_from_ext {W : A} (a b : homology' f g w ⟶ W)
    (h : π' f g w ≫ a = π' f g w ≫ b) : a = b := by
  dsimp [π'] at h
  apply_fun fun e => (homology'IsoCokernelLift f g w).inv ≫ e
  swap
  · 

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : homology' f g w ⟶ W
h :
  (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ a =
    (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ b
⊢ Function.Injective fun e => (homology'IsoCokernelLift f g w).inv ≫ e

Next tactic:
intro i j hh
@[ext]
theorem hom_from_ext {W : A} (a b : homology' f g w ⟶ W)
    (h : π' f g w ≫ a = π' f g w ≫ b) : a = b := by
  dsimp [π'] at h
  apply_fun fun e => (homology'IsoCokernelLift f g w).inv ≫ e
  swap
  · intro i j hh
    

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : homology' f g w ⟶ W
h :
  (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ a =
    (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ b
i j : homology' f g w ⟶ W
hh : (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) i = (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) j
⊢ i = j

Next tactic:
apply_fun fun e => (homology'IsoCokernelLift f g w).hom ≫ e at hh
@[ext]
theorem hom_from_ext {W : A} (a b : homology' f g w ⟶ W)
    (h : π' f g w ≫ a = π' f g w ≫ b) : a = b := by
  dsimp [π'] at h
  apply_fun fun e => (homology'IsoCokernelLift f g w).inv ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (homology'IsoCokernelLift f g w).hom ≫ e at hh
    

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : homology' f g w ⟶ W
h :
  (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ a =
    (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ b
i j : homology' f g w ⟶ W
hh :
  (homology'IsoCokernelLift f g w).hom ≫ (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) i =
    (homology'IsoCokernelLift f g w).hom ≫ (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) j
⊢ i = j

Next tactic:
simpa using hh
@[ext]
theorem hom_from_ext {W : A} (a b : homology' f g w ⟶ W)
    (h : π' f g w ≫ a = π' f g w ≫ b) : a = b := by
  dsimp [π'] at h
  apply_fun fun e => (homology'IsoCokernelLift f g w).inv ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (homology'IsoCokernelLift f g w).hom ≫ e at hh
    simpa using hh
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : homology' f g w ⟶ W
h :
  (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ a =
    (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫ b
⊢ (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) a = (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) b

Next tactic:
simp only [Category.assoc] at h
@[ext]
theorem hom_from_ext {W : A} (a b : homology' f g w ⟶ W)
    (h : π' f g w ≫ a = π' f g w ≫ b) : a = b := by
  dsimp [π'] at h
  apply_fun fun e => (homology'IsoCokernelLift f g w).inv ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (homology'IsoCokernelLift f g w).hom ≫ e at hh
    simpa using hh
  simp only [Category.assoc] at h
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : homology' f g w ⟶ W
h :
  cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv ≫ a =
    cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv ≫ b
⊢ (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) a = (fun e => (homology'IsoCokernelLift f g w).inv ≫ e) b

Next tactic:
exact coequalizer.hom_ext h
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h : a ≫ ι f g w = b ≫ ι f g w
⊢ a = b

Next tactic:
dsimp [ι] at h
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  dsimp [ι] at h
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  a ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w) =
    b ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w)
⊢ a = b

Next tactic:
apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).hom
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  dsimp [ι] at h
  apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).hom
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  a ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w) =
    b ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w)
⊢ (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) a = (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) b
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  a ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w) =
    b ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w)
⊢ Function.Injective fun e => e ≫ (homology'IsoKernelDesc f g w).hom

Next tactic:
swap
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  dsimp [ι] at h
  apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).hom
  swap
  · 

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  a ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w) =
    b ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w)
⊢ Function.Injective fun e => e ≫ (homology'IsoKernelDesc f g w).hom

Next tactic:
intro i j hh
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  dsimp [ι] at h
  apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).hom
  swap
  · intro i j hh
    

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  a ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w) =
    b ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w)
i j : W ⟶ homology' f g w
hh : (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) i = (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) j
⊢ i = j

Next tactic:
apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).inv at hh
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  dsimp [ι] at h
  apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).hom
  swap
  · intro i j hh
    apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).inv at hh
    

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  a ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w) =
    b ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w)
i j : W ⟶ homology' f g w
hh :
  (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) i ≫ (homology'IsoKernelDesc f g w).inv =
    (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) j ≫ (homology'IsoKernelDesc f g w).inv
⊢ i = j

Next tactic:
simpa using hh
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  dsimp [ι] at h
  apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).hom
  swap
  · intro i j hh
    apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).inv at hh
    simpa using hh
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  a ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w) =
    b ≫ (homology'IsoKernelDesc f g w).hom ≫ kernel.ι (cokernel.desc f g w)
⊢ (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) a = (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) b

Next tactic:
simp only [← Category.assoc] at h
@[ext]
theorem hom_to_ext {W : A} (a b : W ⟶ homology' f g w) (h : a ≫ ι f g w = b ≫ ι f g w) : a = b := by
  dsimp [ι] at h
  apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).hom
  swap
  · intro i j hh
    apply_fun fun e => e ≫ (homology'IsoKernelDesc f g w).inv at hh
    simpa using hh
  simp only [← Category.assoc] at h
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
W : A
a b : W ⟶ homology' f g w
h :
  (a ≫ (homology'IsoKernelDesc f g w).hom) ≫ kernel.ι (cokernel.desc f g w) =
    (b ≫ (homology'IsoKernelDesc f g w).hom) ≫ kernel.ι (cokernel.desc f g w)
⊢ (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) a = (fun e => e ≫ (homology'IsoKernelDesc f g w).hom) b

Next tactic:
exact equalizer.hom_ext h
@[reassoc (attr := simp)]
theorem π'_ι : π' f g w ≫ ι f g w = kernel.ι _ ≫ cokernel.π _ := by
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ π' f g w ≫ ι f g w = kernel.ι g ≫ cokernel.π f

Next tactic:
dsimp [π', ι, homology'IsoKernelDesc]
@[reassoc (attr := simp)]
theorem π'_ι : π' f g w ≫ ι f g w = kernel.ι _ ≫ cokernel.π _ := by
  dsimp [π', ι, homology'IsoKernelDesc]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ (cokernel.π (kernel.lift g f w) ≫ (homology'IsoCokernelLift f g w).inv) ≫
      ((homology'IsoCokernelLift f g w).hom ≫ Abelian.homologyCToK f g w) ≫ kernel.ι (cokernel.desc f g w) =
    kernel.ι g ≫ cokernel.π f

Next tactic:
simp
@[reassoc (attr := simp)]
theorem π'_eq_π : (kernelSubobjectIso _).hom ≫ π' f g w = π _ _ _ := by
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ (kernelSubobjectIso g).hom ≫ π' f g w = π f g w

Next tactic:
dsimp [π', homology'IsoCokernelLift]
@[reassoc (attr := simp)]
theorem π'_eq_π : (kernelSubobjectIso _).hom ≫ π' f g w = π _ _ _ := by
  dsimp [π', homology'IsoCokernelLift]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ (kernelSubobjectIso g).hom ≫
      cokernel.π (kernel.lift g f w) ≫
        ((cokernelIsoOfEq (_ : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w)).inv ≫
            cokernel.desc (factorThruImage f ≫ imageToKernel' f g w) (cokernel.π (imageToKernel' f g w))
              (_ : (factorThruImage f ≫ imageToKernel' f g w) ≫ cokernel.π (imageToKernel' f g w) = 0)) ≫
          (homology'IsoCokernelImageToKernel' f g w).inv =
    π f g w

Next tactic:
simp only [← Category.assoc]
@[reassoc (attr := simp)]
theorem π'_eq_π : (kernelSubobjectIso _).hom ≫ π' f g w = π _ _ _ := by
  dsimp [π', homology'IsoCokernelLift]
  simp only [← Category.assoc]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ ((((kernelSubobjectIso g).hom ≫ cokernel.π (kernel.lift g f w)) ≫
          (cokernelIsoOfEq (_ : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w)).inv) ≫
        cokernel.desc (factorThruImage f ≫ imageToKernel' f g w) (cokernel.π (imageToKernel' f g w))
          (_ : (factorThruImage f ≫ imageToKernel' f g w) ≫ cokernel.π (imageToKernel' f g w) = 0)) ≫
      (homology'IsoCokernelImageToKernel' f g w).inv =
    π f g w

Next tactic:
rw [Iso.comp_inv_eq]
@[reassoc (attr := simp)]
theorem π'_eq_π : (kernelSubobjectIso _).hom ≫ π' f g w = π _ _ _ := by
  dsimp [π', homology'IsoCokernelLift]
  simp only [← Category.assoc]
  rw [Iso.comp_inv_eq]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ (((kernelSubobjectIso g).hom ≫ cokernel.π (kernel.lift g f w)) ≫
        (cokernelIsoOfEq (_ : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w)).inv) ≫
      cokernel.desc (factorThruImage f ≫ imageToKernel' f g w) (cokernel.π (imageToKernel' f g w))
        (_ : (factorThruImage f ≫ imageToKernel' f g w) ≫ cokernel.π (imageToKernel' f g w) = 0) =
    π f g w ≫ (homology'IsoCokernelImageToKernel' f g w).hom

Next tactic:
dsimp [π, homology'IsoCokernelImageToKernel']
@[reassoc (attr := simp)]
theorem π'_eq_π : (kernelSubobjectIso _).hom ≫ π' f g w = π _ _ _ := by
  dsimp [π', homology'IsoCokernelLift]
  simp only [← Category.assoc]
  rw [Iso.comp_inv_eq]
  dsimp [π, homology'IsoCokernelImageToKernel']
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
⊢ (((kernelSubobjectIso g).hom ≫ cokernel.π (kernel.lift g f w)) ≫
        (cokernelIsoOfEq (_ : factorThruImage f ≫ imageToKernel' f g w = kernel.lift g f w)).inv) ≫
      cokernel.desc (factorThruImage f ≫ imageToKernel' f g w) (cokernel.π (imageToKernel' f g w))
        (_ : (factorThruImage f ≫ imageToKernel' f g w) ≫ cokernel.π (imageToKernel' f g w) = 0) =
    cokernel.π (imageToKernel f g w) ≫
      cokernel.map (imageToKernel f g w) (imageToKernel' f g w) (imageSubobjectIso f).hom (kernelSubobjectIso g).hom
        (_ : imageToKernel f g w ≫ (kernelSubobjectIso g).hom = (imageSubobjectIso f).hom ≫ imageToKernel' f g w)

Next tactic:
simp
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by 

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ g ≫ β.right = α.right ≫ g'

Next tactic:
simp [h, β.w.symm]
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ π' f g w ≫ map w w' α β h = kernel.map g g' α.right β.right (_ : g ≫ β.right = α.right ≫ g') ≫ π' f' g' w'

Next tactic:
apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ (fun e => (kernelSubobjectIso g).hom ≫ e) (π' f g w ≫ map w w' α β h) =
    (fun e => (kernelSubobjectIso g).hom ≫ e)
      (kernel.map g g' α.right β.right (_ : g ≫ β.right = α.right ≫ g') ≫ π' f' g' w')
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ Function.Injective fun e => (kernelSubobjectIso g).hom ≫ e

Next tactic:
swap
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · 

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ Function.Injective fun e => (kernelSubobjectIso g).hom ≫ e

Next tactic:
intro i j hh
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · intro i j hh
    

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
i j : kernel g ⟶ homology' f' g' w'
hh : (fun e => (kernelSubobjectIso g).hom ≫ e) i = (fun e => (kernelSubobjectIso g).hom ≫ e) j
⊢ i = j

Next tactic:
apply_fun fun e => (kernelSubobjectIso _).inv ≫ e at hh
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (kernelSubobjectIso _).inv ≫ e at hh
    

Proof state:
case inj
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
i j : kernel g ⟶ homology' f' g' w'
hh :
  (kernelSubobjectIso g).inv ≫ (fun e => (kernelSubobjectIso g).hom ≫ e) i =
    (kernelSubobjectIso g).inv ≫ (fun e => (kernelSubobjectIso g).hom ≫ e) j
⊢ i = j

Next tactic:
simpa using hh
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (kernelSubobjectIso _).inv ≫ e at hh
    simpa using hh
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ (fun e => (kernelSubobjectIso g).hom ≫ e) (π' f g w ≫ map w w' α β h) =
    (fun e => (kernelSubobjectIso g).hom ≫ e)
      (kernel.map g g' α.right β.right (_ : g ≫ β.right = α.right ≫ g') ≫ π' f' g' w')

Next tactic:
dsimp [map]
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (kernelSubobjectIso _).inv ≫ e at hh
    simpa using hh
  dsimp [map]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ (kernelSubobjectIso g).hom ≫
      π' f g w ≫
        cokernel.desc (imageToKernel f g w) (kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w'))
          (_ : imageToKernel f g w ≫ kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w') = 0) =
    (kernelSubobjectIso g).hom ≫ kernel.map g g' α.right β.right (_ : g ≫ β.right = α.right ≫ g') ≫ π' f' g' w'

Next tactic:
simp only [π'_eq_π_assoc]
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (kernelSubobjectIso _).inv ≫ e at hh
    simpa using hh
  dsimp [map]
  simp only [π'_eq_π_assoc]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ π f g w ≫
      cokernel.desc (imageToKernel f g w) (kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w'))
        (_ : imageToKernel f g w ≫ kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w') = 0) =
    (kernelSubobjectIso g).hom ≫ kernel.map g g' α.right β.right (_ : g ≫ β.right = α.right ≫ g') ≫ π' f' g' w'

Next tactic:
dsimp [π]
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (kernelSubobjectIso _).inv ≫ e at hh
    simpa using hh
  dsimp [map]
  simp only [π'_eq_π_assoc]
  dsimp [π]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ cokernel.π (imageToKernel f g w) ≫
      cokernel.desc (imageToKernel f g w) (kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w'))
        (_ : imageToKernel f g w ≫ kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w') = 0) =
    (kernelSubobjectIso g).hom ≫ kernel.map g g' α.right β.right (_ : g ≫ β.right = α.right ≫ g') ≫ π' f' g' w'

Next tactic:
simp only [cokernel.π_desc]
@[reassoc (attr := simp)]
theorem π'_map (α β h) : π' _ _ _ ≫ map w w' α β h =
    kernel.map _ _ α.right β.right (by simp [h, β.w.symm]) ≫ π' _ _ _ := by
  apply_fun fun e => (kernelSubobjectIso _).hom ≫ e
  swap
  · intro i j hh
    apply_fun fun e => (kernelSubobjectIso _).inv ≫ e at hh
    simpa using hh
  dsimp [map]
  simp only [π'_eq_π_assoc]
  dsimp [π]
  simp only [cokernel.π_desc]
  

Proof state:
A : Type u
inst✝¹ : Category.{v, u} A
inst✝ : Abelian A
X Y Z : A
f : X ⟶ Y
g : Y ⟶ Z
w : f ≫ g = 0
X' Y' Z' : A
f' : X' ⟶ Y'
g' : Y' ⟶ Z'
w' : f' ≫ g' = 0
α : Arrow.mk f ⟶ Arrow.mk f'
β : Arrow.mk g ⟶ Arrow.mk g'
h : α.right = β.left
⊢ kernelSubobjectMap β ≫ cokernel.π (imageToKernel f' g' w') =
    (kernelSubobjectIso g).hom ≫ kernel.map g g' α.right β.right (_ : g ≫ β.right = α.right ≫ g') ≫ π' f' g' w'

Next tactic:
rw [← Iso.inv_comp_eq, ← Category.assoc]