l3lab/ntp-mathlib huggingface dataset:
/-- If `φ : S₁ ⟶ S₂` is a morphism of short complexes such that `φ.τ₁` is epi, `φ.τ₂` is an iso
and `φ.τ₃` is mono, then a left homology data for `S₂` induces a left homology data for `S₁` with
the same `K` and `H` fields. The inverse construction is `ofEpiOfIsIsoOfMono`. -/
@[simps]
noncomputable def ofEpiOfIsIsoOfMono' (φ : S₁ ⟶ S₂) (h : LeftHomologyData S₂)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] : LeftHomologyData S₁ := by
  let i : h.K ⟶ S₁.X₂ := h.i ≫ inv φ.τ₂
  have wi : i ≫ S₁.g = 0 := by
    rw [assoc, ← cancel_mono φ.τ₃, zero_comp, assoc, assoc, ← φ.comm₂₃,
      IsIso.inv_hom_id_assoc, h.wi]
  have hi : IsLimit (KernelFork.ofι i wi) := KernelFork.IsLimit.ofι _ _
    (fun x hx => h.liftK (x ≫ φ.τ₂)
      (by rw [assoc, φ.comm₂₃, reassoc_of% hx, zero_comp]))
    (fun x hx => by simp )
    (fun x hx b hb => by rw [← cancel_mono h.i, ← cancel_mono (inv φ.τ₂), assoc, assoc,
      hb, liftK_i_assoc, assoc, IsIso.hom_inv_id, comp_id])
  let f' := hi.lift (KernelFork.ofι S₁.f S₁.zero)
  have hf' : f' ≫ i = S₁.f := Fork.IsLimit.lift_ι _
  have hf'' : f' = φ.τ₁ ≫ h.f' := by
    rw [← cancel_mono h.i, ← cancel_mono (inv φ.τ₂), assoc, assoc, assoc, hf', f'_i_assoc,
      φ.comm₁₂_assoc, IsIso.hom_inv_id, comp_id]
  have wπ : f' ≫ h.π = 0 := by simp only [hf'', assoc, f'_π, comp_zero]
  have hπ : IsColimit (CokernelCofork.ofπ h.π wπ) := CokernelCofork.IsColimit.ofπ _ _
    (fun x hx => h.descH x (by rw [← cancel_epi φ.τ₁, ← reassoc_of% hf'', hx, comp_zero]))
    (fun x hx => π_descH _ _ _)
    (fun x hx b hx => by rw [← cancel_epi h.π, π_descH, hx])
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.177302, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
i : h.K ⟶ S₁.X₂ := h.i ≫ inv φ.τ₂
wi : i ≫ S₁.g = 0
hi : IsLimit (KernelFork.ofι i wi)
f' : (KernelFork.ofι S₁.f (_ : S₁.f ≫ S₁.g = 0)).pt ⟶ (KernelFork.ofι i wi).pt :=
  IsLimit.lift hi (KernelFork.ofι S₁.f (_ : S₁.f ≫ S₁.g = 0))
hf' : f' ≫ i = S₁.f
hf'' : f' = φ.τ₁ ≫ CategoryTheory.ShortComplex.LeftHomologyData.f' h
wπ : f' ≫ h.π = 0
hπ : IsColimit (CokernelCofork.ofπ h.π wπ)
⊢ LeftHomologyData S₁

Next tactic:
exact ⟨h.K, h.H, i, h.π, wi, hi, wπ, hπ⟩
@[simp]
lemma ofEpiOfIsIsoOfMono'_f' (φ : S₁ ⟶ S₂) (h : LeftHomologyData S₂)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] : (ofEpiOfIsIsoOfMono' φ h).f' = φ.τ₁ ≫ h.f' := by
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{u_2, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
⊢ f' (ofEpiOfIsIsoOfMono' φ h) = φ.τ₁ ≫ f' h

Next tactic:
rw [← cancel_mono (ofEpiOfIsIsoOfMono' φ h).i, f'_i, ofEpiOfIsIsoOfMono'_i,
    assoc, f'_i_assoc, φ.comm₁₂_assoc, IsIso.hom_inv_id, comp_id]
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
⊢ IsIso (leftHomologyMap' φ h₁ h₂)

Next tactic:
let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
⊢ IsIso (leftHomologyMap' φ h₁ h₂)

Next tactic:
have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
    dsimp
    infer_instance
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
⊢ IsIso (leftHomologyMap' φ h₁ h₂')

Next tactic:
rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
⊢ IsIso (LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).φH

Next tactic:
dsimp
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
    dsimp
    

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
⊢ IsIso (𝟙 h₁.H)

Next tactic:
infer_instance
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
    dsimp
    infer_instance
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
this : IsIso (leftHomologyMap' φ h₁ h₂')
⊢ IsIso (leftHomologyMap' φ h₁ h₂)

Next tactic:
have eq := leftHomologyMap'_comp φ (𝟙 S₂) h₁ h₂' h₂
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
    dsimp
    infer_instance
  have eq := leftHomologyMap'_comp φ (𝟙 S₂) h₁ h₂' h₂
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
this : IsIso (leftHomologyMap' φ h₁ h₂')
eq : leftHomologyMap' (φ ≫ 𝟙 S₂) h₁ h₂ = leftHomologyMap' φ h₁ h₂' ≫ leftHomologyMap' (𝟙 S₂) h₂' h₂
⊢ IsIso (leftHomologyMap' φ h₁ h₂)

Next tactic:
rw [comp_id] at eq
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
    dsimp
    infer_instance
  have eq := leftHomologyMap'_comp φ (𝟙 S₂) h₁ h₂' h₂
  rw [comp_id] at eq
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
this : IsIso (leftHomologyMap' φ h₁ h₂')
eq : leftHomologyMap' φ h₁ h₂ = leftHomologyMap' φ h₁ h₂' ≫ leftHomologyMap' (𝟙 S₂) h₂' h₂
⊢ IsIso (leftHomologyMap' φ h₁ h₂)

Next tactic:
rw [eq]
instance (φ : S₁ ⟶ S₂) (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData)
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap' φ h₁ h₂) := by
  let h₂' := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
  have : IsIso (leftHomologyMap' φ h₁ h₂') := by
    rw [(LeftHomologyMapData.ofEpiOfIsIsoOfMono φ h₁).leftHomologyMap'_eq]
    dsimp
    infer_instance
  have eq := leftHomologyMap'_comp φ (𝟙 S₂) h₁ h₂' h₂
  rw [comp_id] at eq
  rw [eq]
  

Proof state:
C : Type u_1
inst✝⁴ : Category.{?u.207691, u_1} C
inst✝³ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
h₂' : LeftHomologyData S₂ := LeftHomologyData.ofEpiOfIsIsoOfMono φ h₁
this : IsIso (leftHomologyMap' φ h₁ h₂')
eq : leftHomologyMap' φ h₁ h₂ = leftHomologyMap' φ h₁ h₂' ≫ leftHomologyMap' (𝟙 S₂) h₂' h₂
⊢ IsIso (leftHomologyMap' φ h₁ h₂' ≫ leftHomologyMap' (𝟙 S₂) h₂' h₂)

Next tactic:
infer_instance
/-- If a morphism of short complexes `φ : S₁ ⟶ S₂` is such that `φ.τ₁` is epi, `φ.τ₂` is an iso,
and `φ.τ₃` is mono, then the induced morphism on left homology is an isomorphism. -/
instance (φ : S₁ ⟶ S₂) [S₁.HasLeftHomology] [S₂.HasLeftHomology]
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap φ) := by
  

Proof state:
C : Type u_1
inst✝⁶ : Category.{?u.209581, u_1} C
inst✝⁵ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
inst✝⁴ : HasLeftHomology S₁
inst✝³ : HasLeftHomology S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
⊢ IsIso (leftHomologyMap φ)

Next tactic:
dsimp only [leftHomologyMap]
/-- If a morphism of short complexes `φ : S₁ ⟶ S₂` is such that `φ.τ₁` is epi, `φ.τ₂` is an iso,
and `φ.τ₃` is mono, then the induced morphism on left homology is an isomorphism. -/
instance (φ : S₁ ⟶ S₂) [S₁.HasLeftHomology] [S₂.HasLeftHomology]
    [Epi φ.τ₁] [IsIso φ.τ₂] [Mono φ.τ₃] :
    IsIso (leftHomologyMap φ) := by
  dsimp only [leftHomologyMap]
  

Proof state:
C : Type u_1
inst✝⁶ : Category.{?u.209581, u_1} C
inst✝⁵ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
inst✝⁴ : HasLeftHomology S₁
inst✝³ : HasLeftHomology S₂
inst✝² : Epi φ.τ₁
inst✝¹ : IsIso φ.τ₂
inst✝ : Mono φ.τ₃
⊢ IsIso (leftHomologyMap' φ (leftHomologyData S₁) (leftHomologyData S₂))

Next tactic:
infer_instance
@[reassoc]
lemma comp_liftCycles {A' : C} (α : A' ⟶ A) :
    α ≫ S.liftCycles k hk = S.liftCycles (α ≫ k) (by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.213913, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝ : HasLeftHomology S
A' : C
α : A' ⟶ A
⊢ (α ≫ k) ≫ S.g = 0

Next tactic:
rw [assoc, hk, comp_zero]
@[reassoc]
lemma comp_liftCycles {A' : C} (α : A' ⟶ A) :
    α ≫ S.liftCycles k hk = S.liftCycles (α ≫ k) (by rw [assoc, hk, comp_zero]) := by 

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝ : HasLeftHomology S
A' : C
α : A' ⟶ A
⊢ α ≫ liftCycles S k hk = liftCycles S (α ≫ k) (_ : (α ≫ k) ≫ S.g = 0)

Next tactic:
aesop_cat
/-- The canonical isomorphism `S.cycles ≅ kernel S.g`. -/
@[simps]
noncomputable def cyclesIsoKernel [HasKernel S.g] : S.cycles ≅ kernel S.g where
  hom := kernel.lift S.g S.iCycles (by 

Proof state:
C : Type u_1
inst✝³ : Category.{?u.217439, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
⊢ iCycles S ≫ S.g = 0

Next tactic:
simp
/-- The canonical isomorphism `S.cycles ≅ kernel S.g`. -/
@[simps]
noncomputable def cyclesIsoKernel [HasKernel S.g] : S.cycles ≅ kernel S.g where
  hom := kernel.lift S.g S.iCycles (by simp)
  inv := S.liftCycles (kernel.ι S.g) (by 

Proof state:
C : Type u_1
inst✝³ : Category.{?u.217439, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
⊢ kernel.ι S.g ≫ S.g = 0

Next tactic:
simp
@[reassoc]
lemma liftCycles_leftHomologyπ_eq_zero_of_boundary (x : A ⟶ S.X₁) (hx : k = x ≫ S.f) :
    S.liftCycles k (by 

Proof state:
C : Type u_1
inst✝² : Category.{?u.221749, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝ : HasLeftHomology S
x : A ⟶ S.X₁
hx : k = x ≫ S.f
⊢ k ≫ S.g = 0

Next tactic:
rw [hx, assoc, S.zero, comp_zero]
@[reassoc (attr := simp)]
lemma toCycles_comp_leftHomologyπ : S.toCycles ≫ S.leftHomologyπ = 0 :=
  S.liftCycles_leftHomologyπ_eq_zero_of_boundary S.f (𝟙 _) (by 

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝ : HasLeftHomology S
⊢ S.f = 𝟙 S.X₁ ≫ S.f

Next tactic:
rw [id_comp]
@[reassoc (attr := simp)]
lemma liftCycles_comp_cyclesMap (φ : S ⟶ S₁) [S₁.HasLeftHomology] :
    S.liftCycles k hk ≫ cyclesMap φ =
      S₁.liftCycles (k ≫ φ.τ₂) (by 

Proof state:
C : Type u_1
inst✝³ : Category.{?u.226069, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝¹ : HasLeftHomology S
φ : S ⟶ S₁
inst✝ : HasLeftHomology S₁
⊢ (k ≫ φ.τ₂) ≫ S₁.g = 0

Next tactic:
rw [assoc, φ.comm₂₃, reassoc_of% hk, zero_comp]
@[reassoc (attr := simp)]
lemma liftCycles_comp_cyclesMap (φ : S ⟶ S₁) [S₁.HasLeftHomology] :
    S.liftCycles k hk ≫ cyclesMap φ =
      S₁.liftCycles (k ≫ φ.τ₂) (by rw [assoc, φ.comm₂₃, reassoc_of% hk, zero_comp]) := by
  

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝¹ : HasLeftHomology S
φ : S ⟶ S₁
inst✝ : HasLeftHomology S₁
⊢ liftCycles S k hk ≫ cyclesMap φ = liftCycles S₁ (k ≫ φ.τ₂) (_ : (k ≫ φ.τ₂) ≫ S₁.g = 0)

Next tactic:
aesop_cat
@[reassoc (attr := simp)]
lemma LeftHomologyData.liftCycles_comp_cyclesIso_hom :
    S.liftCycles k hk ≫ h.cyclesIso.hom = h.liftK k hk := by
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝ : HasLeftHomology S
⊢ liftCycles S k hk ≫ (cyclesIso h).hom = liftK h k hk

Next tactic:
simp only [← cancel_mono h.i, assoc, LeftHomologyData.cyclesIso_hom_comp_i,
    liftCycles_i, LeftHomologyData.liftK_i]
@[reassoc (attr := simp)]
lemma LeftHomologyData.lift_K_comp_cyclesIso_inv :
    h.liftK k hk ≫ h.cyclesIso.inv = S.liftCycles k hk := by
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝ : HasLeftHomology S
⊢ liftK h k hk ≫ (cyclesIso h).inv = liftCycles S k hk

Next tactic:
rw [← h.liftCycles_comp_cyclesIso_hom, assoc, Iso.hom_inv_id, comp_id]
lemma hasCokernel [S.HasLeftHomology] [HasKernel S.g] :
    HasCokernel (kernel.lift S.g S.f S.zero) := by
  

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
⊢ HasCokernel (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))

Next tactic:
let h := S.leftHomologyData
lemma hasCokernel [S.HasLeftHomology] [HasKernel S.g] :
    HasCokernel (kernel.lift S.g S.f S.zero) := by
  let h := S.leftHomologyData
  

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
h : LeftHomologyData S := leftHomologyData S
⊢ HasCokernel (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))

Next tactic:
haveI : HasColimit (parallelPair h.f' 0) := ⟨⟨⟨_, h.hπ'⟩⟩⟩
lemma hasCokernel [S.HasLeftHomology] [HasKernel S.g] :
    HasCokernel (kernel.lift S.g S.f S.zero) := by
  let h := S.leftHomologyData
  haveI : HasColimit (parallelPair h.f' 0) := ⟨⟨⟨_, h.hπ'⟩⟩⟩
  

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
h : LeftHomologyData S := leftHomologyData S
this : HasColimit (parallelPair (LeftHomologyData.f' h) 0)
⊢ HasCokernel (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))

Next tactic:
let e : parallelPair (kernel.lift S.g S.f S.zero) 0 ≅ parallelPair h.f' 0 :=
    parallelPair.ext (Iso.refl _) (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi)
      (by aesop_cat) (by aesop_cat)
lemma hasCokernel [S.HasLeftHomology] [HasKernel S.g] :
    HasCokernel (kernel.lift S.g S.f S.zero) := by
  let h := S.leftHomologyData
  haveI : HasColimit (parallelPair h.f' 0) := ⟨⟨⟨_, h.hπ'⟩⟩⟩
  let e : parallelPair (kernel.lift S.g S.f S.zero) 0 ≅ parallelPair h.f' 0 :=
    parallelPair.ext (Iso.refl _) (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi)
      (by 

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
h : LeftHomologyData S := leftHomologyData S
this : HasColimit (parallelPair (LeftHomologyData.f' h) 0)
⊢ (parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0).map WalkingParallelPairHom.left ≫
      (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi).hom =
    (Iso.refl ((parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0).obj WalkingParallelPair.zero)).hom ≫
      (parallelPair (LeftHomologyData.f' h) 0).map WalkingParallelPairHom.left

Next tactic:
aesop_cat
lemma hasCokernel [S.HasLeftHomology] [HasKernel S.g] :
    HasCokernel (kernel.lift S.g S.f S.zero) := by
  let h := S.leftHomologyData
  haveI : HasColimit (parallelPair h.f' 0) := ⟨⟨⟨_, h.hπ'⟩⟩⟩
  let e : parallelPair (kernel.lift S.g S.f S.zero) 0 ≅ parallelPair h.f' 0 :=
    parallelPair.ext (Iso.refl _) (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi)
      (by aesop_cat) (by 

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
h : LeftHomologyData S := leftHomologyData S
this : HasColimit (parallelPair (LeftHomologyData.f' h) 0)
⊢ (parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0).map WalkingParallelPairHom.right ≫
      (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi).hom =
    (Iso.refl ((parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0).obj WalkingParallelPair.zero)).hom ≫
      (parallelPair (LeftHomologyData.f' h) 0).map WalkingParallelPairHom.right

Next tactic:
aesop_cat
lemma hasCokernel [S.HasLeftHomology] [HasKernel S.g] :
    HasCokernel (kernel.lift S.g S.f S.zero) := by
  let h := S.leftHomologyData
  haveI : HasColimit (parallelPair h.f' 0) := ⟨⟨⟨_, h.hπ'⟩⟩⟩
  let e : parallelPair (kernel.lift S.g S.f S.zero) 0 ≅ parallelPair h.f' 0 :=
    parallelPair.ext (Iso.refl _) (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi)
      (by aesop_cat) (by aesop_cat)
  

Proof state:
C : Type u_1
inst✝³ : Category.{u_2, u_1} C
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasLeftHomology S
inst✝ : HasKernel S.g
h : LeftHomologyData S := leftHomologyData S
this : HasColimit (parallelPair (LeftHomologyData.f' h) 0)
e : parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0 ≅ parallelPair (LeftHomologyData.f' h) 0 :=
  parallelPair.ext (Iso.refl ((parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0).obj WalkingParallelPair.zero))
    (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi)
    (_ :
      (parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0).map WalkingParallelPairHom.left ≫
          (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) h.hi).hom =
        (Iso.refl ((parallelPair (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0)) 0).obj WalkingParallelPair.zero)).hom ≫
          (parallelPair (LeftHomologyData.f' h) 0).map WalkingParallelPairHom.left)
    (_ : 0 ≫ (IsLimit.conePointUniqueUpToIso (kernelIsKernel S.g) (leftHomologyData S).hi).hom = 𝟙 S.X₁ ≫ 0)
⊢ HasCokernel (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))

Next tactic:
exact hasColimitOfIso e
lemma isIso_cyclesMap'_of_isIso_of_mono (φ : S₁ ⟶ S₂) (h₂ : IsIso φ.τ₂) (h₃ : Mono φ.τ₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) :
    IsIso (cyclesMap' φ h₁ h₂) := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₂✝ : IsIso φ.τ₂
h₃ : Mono φ.τ₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
⊢ IsIso (cyclesMap' φ h₁ h₂)

Next tactic:
refine' ⟨h₁.liftK (h₂.i ≫ inv φ.τ₂) _, _, _⟩
lemma isIso_cyclesMap'_of_isIso_of_mono (φ : S₁ ⟶ S₂) (h₂ : IsIso φ.τ₂) (h₃ : Mono φ.τ₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) :
    IsIso (cyclesMap' φ h₁ h₂) := by
  refine' ⟨h₁.liftK (h₂.i ≫ inv φ.τ₂) _, _, _⟩
  · 

Proof state:
case refine'_1
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₂✝ : IsIso φ.τ₂
h₃ : Mono φ.τ₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
⊢ (h₂.i ≫ inv φ.τ₂) ≫ S₁.g = 0

Next tactic:
simp only [assoc, ← cancel_mono φ.τ₃, zero_comp, ← φ.comm₂₃, IsIso.inv_hom_id_assoc, h₂.wi]
lemma isIso_cyclesMap'_of_isIso_of_mono (φ : S₁ ⟶ S₂) (h₂ : IsIso φ.τ₂) (h₃ : Mono φ.τ₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) :
    IsIso (cyclesMap' φ h₁ h₂) := by
  refine' ⟨h₁.liftK (h₂.i ≫ inv φ.τ₂) _, _, _⟩
  · simp only [assoc, ← cancel_mono φ.τ₃, zero_comp, ← φ.comm₂₃, IsIso.inv_hom_id_assoc, h₂.wi]
  · 

Proof state:
case refine'_2
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₂✝ : IsIso φ.τ₂
h₃ : Mono φ.τ₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
⊢ cyclesMap' φ h₁ h₂ ≫ LeftHomologyData.liftK h₁ (h₂.i ≫ inv φ.τ₂) (_ : (h₂.i ≫ inv φ.τ₂) ≫ S₁.g = 0) = 𝟙 h₁.K

Next tactic:
simp only [← cancel_mono h₁.i, assoc, h₁.liftK_i, cyclesMap'_i_assoc,
      IsIso.hom_inv_id, comp_id, id_comp]
lemma isIso_cyclesMap'_of_isIso_of_mono (φ : S₁ ⟶ S₂) (h₂ : IsIso φ.τ₂) (h₃ : Mono φ.τ₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) :
    IsIso (cyclesMap' φ h₁ h₂) := by
  refine' ⟨h₁.liftK (h₂.i ≫ inv φ.τ₂) _, _, _⟩
  · simp only [assoc, ← cancel_mono φ.τ₃, zero_comp, ← φ.comm₂₃, IsIso.inv_hom_id_assoc, h₂.wi]
  · simp only [← cancel_mono h₁.i, assoc, h₁.liftK_i, cyclesMap'_i_assoc,
      IsIso.hom_inv_id, comp_id, id_comp]
  · 

Proof state:
case refine'_3
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₂✝ : IsIso φ.τ₂
h₃ : Mono φ.τ₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
⊢ LeftHomologyData.liftK h₁ (h₂.i ≫ inv φ.τ₂) (_ : (h₂.i ≫ inv φ.τ₂) ≫ S₁.g = 0) ≫ cyclesMap' φ h₁ h₂ = 𝟙 h₂.K

Next tactic:
simp only [← cancel_mono h₂.i, assoc, cyclesMap'_i, h₁.liftK_i_assoc,
      IsIso.inv_hom_id, comp_id, id_comp]
theorem Coloring.card_colorClasses_le [Fintype α] [Fintype C.colorClasses] :
    Fintype.card C.colorClasses ≤ Fintype.card α := by
  

Proof state:
V : Type u
G : SimpleGraph V
α : Type v
C : Coloring G α
inst✝¹ : Fintype α
inst✝ : Fintype ↑(colorClasses C)
⊢ Fintype.card ↑(colorClasses C) ≤ Fintype.card α

Next tactic:
simp [colorClasses]