l3lab/ntp-mathlib huggingface dataset:
/-- Möbius inversion for functions to a `CommGroupWithZero`, where the equalities only hold on
a well-behaved set. -/
theorem prod_eq_iff_prod_pow_moebius_eq_on_of_nonzero [CommGroupWithZero R]
    (s : Set ℕ) (hs : ∀ m n, m ∣ n → n ∈ s → m ∈ s) {f g : ℕ → R}
    (hf : ∀ n > 0, f n ≠ 0) (hg : ∀ n > 0, g n ≠ 0):
    (∀ n > 0, n ∈ s → (∏ i in n.divisors, f i) = g n) ↔
      ∀ n > 0, n ∈ s → (∏ x : ℕ × ℕ in n.divisorsAntidiagonal, g x.snd ^ μ x.fst) = f n := by
  refine'
      Iff.trans
        (Iff.trans (forall_congr' fun n => _)
          (@prod_eq_iff_prod_pow_moebius_eq_on Rˣ _
            (fun n => if h : 0 < n then Units.mk0 (f n) (hf n h) else 1)
            (fun n => if h : 0 < n then Units.mk0 (g n) (hg n h) else 1)
            s hs) )
        (forall_congr' fun n => _) <;>
    refine' imp_congr_right fun hn => _
  · dsimp
    rw [dif_pos hn, ← Units.eq_iff, ← Units.coeHom_apply, map_prod, Units.val_mk0,
      prod_congr rfl _]
    intro x hx
    rw [dif_pos (Nat.pos_of_mem_divisors hx), Units.coeHom_apply, Units.val_mk0]
  · dsimp
    rw [dif_pos hn, ← Units.eq_iff, ← Units.coeHom_apply, map_prod, Units.val_mk0,
      prod_congr rfl _]
    

Proof state:
R : Type u_1
inst✝ : CommGroupWithZero R
s : Set ℕ
hs : ∀ (m n : ℕ), m ∣ n → n ∈ s → m ∈ s
f g : ℕ → R
hf : ∀ n > 0, f n ≠ 0
hg : ∀ n > 0, g n ≠ 0
n : ℕ
hn : n > 0
⊢ ∀ x ∈ divisorsAntidiagonal n,
    (Units.coeHom R) ((if h : 0 < x.2 then Units.mk0 (g x.2) (_ : g x.2 ≠ 0) else 1) ^ μ x.1) = g x.2 ^ μ x.1

Next tactic:
intro x hx
/-- Möbius inversion for functions to a `CommGroupWithZero`, where the equalities only hold on
a well-behaved set. -/
theorem prod_eq_iff_prod_pow_moebius_eq_on_of_nonzero [CommGroupWithZero R]
    (s : Set ℕ) (hs : ∀ m n, m ∣ n → n ∈ s → m ∈ s) {f g : ℕ → R}
    (hf : ∀ n > 0, f n ≠ 0) (hg : ∀ n > 0, g n ≠ 0):
    (∀ n > 0, n ∈ s → (∏ i in n.divisors, f i) = g n) ↔
      ∀ n > 0, n ∈ s → (∏ x : ℕ × ℕ in n.divisorsAntidiagonal, g x.snd ^ μ x.fst) = f n := by
  refine'
      Iff.trans
        (Iff.trans (forall_congr' fun n => _)
          (@prod_eq_iff_prod_pow_moebius_eq_on Rˣ _
            (fun n => if h : 0 < n then Units.mk0 (f n) (hf n h) else 1)
            (fun n => if h : 0 < n then Units.mk0 (g n) (hg n h) else 1)
            s hs) )
        (forall_congr' fun n => _) <;>
    refine' imp_congr_right fun hn => _
  · dsimp
    rw [dif_pos hn, ← Units.eq_iff, ← Units.coeHom_apply, map_prod, Units.val_mk0,
      prod_congr rfl _]
    intro x hx
    rw [dif_pos (Nat.pos_of_mem_divisors hx), Units.coeHom_apply, Units.val_mk0]
  · dsimp
    rw [dif_pos hn, ← Units.eq_iff, ← Units.coeHom_apply, map_prod, Units.val_mk0,
      prod_congr rfl _]
    intro x hx
    

Proof state:
R : Type u_1
inst✝ : CommGroupWithZero R
s : Set ℕ
hs : ∀ (m n : ℕ), m ∣ n → n ∈ s → m ∈ s
f g : ℕ → R
hf : ∀ n > 0, f n ≠ 0
hg : ∀ n > 0, g n ≠ 0
n : ℕ
hn : n > 0
x : ℕ × ℕ
hx : x ∈ divisorsAntidiagonal n
⊢ (Units.coeHom R) ((if h : 0 < x.2 then Units.mk0 (g x.2) (_ : g x.2 ≠ 0) else 1) ^ μ x.1) = g x.2 ^ μ x.1

Next tactic:
rw [dif_pos (Nat.pos_of_mem_divisors (Nat.snd_mem_divisors_of_mem_antidiagonal hx)),
      Units.coeHom_apply, Units.val_zpow_eq_zpow_val, Units.val_mk0]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_inv_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] :
    (P.isoLeftDerivedToHomotopyCategoryObj F).inv ≫ F.leftDerivedToHomotopyCategory.map f =
      (F.mapHomologicalComplex _ ⋙ HomotopyCategory.quotient _ _).map φ ≫
        (Q.isoLeftDerivedToHomotopyCategoryObj F).inv := by
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
⊢ (isoLeftDerivedToHomotopyCategoryObj P F).inv ≫ (Functor.leftDerivedToHomotopyCategory F).map f =
    (Functor.mapHomologicalComplex F (ComplexShape.down ℕ) ⋙ HomotopyCategory.quotient D (ComplexShape.down ℕ)).map φ ≫
      (isoLeftDerivedToHomotopyCategoryObj Q F).inv

Next tactic:
dsimp [Functor.leftDerivedToHomotopyCategory, isoLeftDerivedToHomotopyCategoryObj]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_inv_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] :
    (P.isoLeftDerivedToHomotopyCategoryObj F).inv ≫ F.leftDerivedToHomotopyCategory.map f =
      (F.mapHomologicalComplex _ ⋙ HomotopyCategory.quotient _ _).map φ ≫
        (Q.isoLeftDerivedToHomotopyCategoryObj F).inv := by
  dsimp [Functor.leftDerivedToHomotopyCategory, isoLeftDerivedToHomotopyCategoryObj]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
⊢ ((Functor.mapHomotopyCategoryFactors F (ComplexShape.down ℕ)).inv.app P.complex ≫
        (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map (iso P).inv) ≫
      (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map ((projectiveResolutions C).map f) =
    (HomotopyCategory.quotient D (ComplexShape.down ℕ)).map
        ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).map φ) ≫
      (Functor.mapHomotopyCategoryFactors F (ComplexShape.down ℕ)).inv.app Q.complex ≫
        (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map (iso Q).inv

Next tactic:
rw [assoc, ← Functor.map_comp, iso_inv_naturality f P Q φ comm, Functor.map_comp]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_inv_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] :
    (P.isoLeftDerivedToHomotopyCategoryObj F).inv ≫ F.leftDerivedToHomotopyCategory.map f =
      (F.mapHomologicalComplex _ ⋙ HomotopyCategory.quotient _ _).map φ ≫
        (Q.isoLeftDerivedToHomotopyCategoryObj F).inv := by
  dsimp [Functor.leftDerivedToHomotopyCategory, isoLeftDerivedToHomotopyCategoryObj]
  rw [assoc, ← Functor.map_comp, iso_inv_naturality f P Q φ comm, Functor.map_comp]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
⊢ (Functor.mapHomotopyCategoryFactors F (ComplexShape.down ℕ)).inv.app P.complex ≫
      (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map
          ((HomotopyCategory.quotient C (ComplexShape.down ℕ)).map φ) ≫
        (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map (iso Q).inv =
    (HomotopyCategory.quotient D (ComplexShape.down ℕ)).map
        ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).map φ) ≫
      (Functor.mapHomotopyCategoryFactors F (ComplexShape.down ℕ)).inv.app Q.complex ≫
        (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map (iso Q).inv

Next tactic:
erw [(F.mapHomotopyCategoryFactors (ComplexShape.down ℕ)).inv.naturality_assoc]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_inv_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] :
    (P.isoLeftDerivedToHomotopyCategoryObj F).inv ≫ F.leftDerivedToHomotopyCategory.map f =
      (F.mapHomologicalComplex _ ⋙ HomotopyCategory.quotient _ _).map φ ≫
        (Q.isoLeftDerivedToHomotopyCategoryObj F).inv := by
  dsimp [Functor.leftDerivedToHomotopyCategory, isoLeftDerivedToHomotopyCategoryObj]
  rw [assoc, ← Functor.map_comp, iso_inv_naturality f P Q φ comm, Functor.map_comp]
  erw [(F.mapHomotopyCategoryFactors (ComplexShape.down ℕ)).inv.naturality_assoc]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
⊢ (Functor.mapHomotopyCategoryFactors F (ComplexShape.down ℕ)).inv.app P.complex ≫
      (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map
          ((HomotopyCategory.quotient C (ComplexShape.down ℕ)).map φ) ≫
        (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map (iso Q).inv =
    (Functor.mapHomotopyCategoryFactors F (ComplexShape.down ℕ)).inv.app P.complex ≫
      (HomotopyCategory.quotient C (ComplexShape.down ℕ) ⋙ Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map φ ≫
        (Functor.mapHomotopyCategory F (ComplexShape.down ℕ)).map (iso Q).inv

Next tactic:
rfl
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_hom_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] :
    F.leftDerivedToHomotopyCategory.map f ≫ (Q.isoLeftDerivedToHomotopyCategoryObj F).hom =
      (P.isoLeftDerivedToHomotopyCategoryObj F).hom ≫
        (F.mapHomologicalComplex _ ⋙ HomotopyCategory.quotient _ _).map φ := by
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
⊢ (Functor.leftDerivedToHomotopyCategory F).map f ≫ (isoLeftDerivedToHomotopyCategoryObj Q F).hom =
    (isoLeftDerivedToHomotopyCategoryObj P F).hom ≫
      (Functor.mapHomologicalComplex F (ComplexShape.down ℕ) ⋙ HomotopyCategory.quotient D (ComplexShape.down ℕ)).map φ

Next tactic:
dsimp
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_hom_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] :
    F.leftDerivedToHomotopyCategory.map f ≫ (Q.isoLeftDerivedToHomotopyCategoryObj F).hom =
      (P.isoLeftDerivedToHomotopyCategoryObj F).hom ≫
        (F.mapHomologicalComplex _ ⋙ HomotopyCategory.quotient _ _).map φ := by
    dsimp
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
⊢ (Functor.leftDerivedToHomotopyCategory F).map f ≫ (isoLeftDerivedToHomotopyCategoryObj Q F).hom =
    (isoLeftDerivedToHomotopyCategoryObj P F).hom ≫
      (HomotopyCategory.quotient D (ComplexShape.down ℕ)).map
        ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).map φ)

Next tactic:
rw [← cancel_epi (P.isoLeftDerivedToHomotopyCategoryObj F).inv, Iso.inv_hom_id_assoc,
      isoLeftDerivedToHomotopyCategoryObj_inv_naturality_assoc f P Q φ comm F,
      Iso.inv_hom_id, comp_id]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedObj_hom_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] (n : ℕ) :
    (F.leftDerived n).map f ≫ (Q.isoLeftDerivedObj F n).hom =
      (P.isoLeftDerivedObj F n).hom ≫
        (F.mapHomologicalComplex _ ⋙ HomologicalComplex.homologyFunctor _ _ n).map φ := by
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
n : ℕ
⊢ (Functor.leftDerived F n).map f ≫ (isoLeftDerivedObj Q F n).hom =
    (isoLeftDerivedObj P F n).hom ≫
      (Functor.mapHomologicalComplex F (ComplexShape.down ℕ) ⋙
            HomologicalComplex.homologyFunctor D (ComplexShape.down ℕ) n).map
        φ

Next tactic:
dsimp [isoLeftDerivedObj, Functor.leftDerived]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedObj_hom_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] (n : ℕ) :
    (F.leftDerived n).map f ≫ (Q.isoLeftDerivedObj F n).hom =
      (P.isoLeftDerivedObj F n).hom ≫
        (F.mapHomologicalComplex _ ⋙ HomologicalComplex.homologyFunctor _ _ n).map φ := by
  dsimp [isoLeftDerivedObj, Functor.leftDerived]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
n : ℕ
⊢ (HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map ((Functor.leftDerivedToHomotopyCategory F).map f) ≫
      (HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map (isoLeftDerivedToHomotopyCategoryObj Q F).hom ≫
        (HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.app
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).obj Q.complex) =
    ((HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map (isoLeftDerivedToHomotopyCategoryObj P F).hom ≫
        (HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.app
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).obj P.complex)) ≫
      HomologicalComplex.homologyMap ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).map φ) n

Next tactic:
rw [assoc, ← Functor.map_comp_assoc,
    ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_hom_naturality f P Q φ comm F,
    Functor.map_comp, assoc]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedObj_hom_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] (n : ℕ) :
    (F.leftDerived n).map f ≫ (Q.isoLeftDerivedObj F n).hom =
      (P.isoLeftDerivedObj F n).hom ≫
        (F.mapHomologicalComplex _ ⋙ HomologicalComplex.homologyFunctor _ _ n).map φ := by
  dsimp [isoLeftDerivedObj, Functor.leftDerived]
  rw [assoc, ← Functor.map_comp_assoc,
    ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_hom_naturality f P Q φ comm F,
    Functor.map_comp, assoc]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
n : ℕ
⊢ (HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map (isoLeftDerivedToHomotopyCategoryObj P F).hom ≫
      (HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ) ⋙
                HomotopyCategory.quotient D (ComplexShape.down ℕ)).map
            φ) ≫
        (HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.app
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).obj Q.complex) =
    (HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map (isoLeftDerivedToHomotopyCategoryObj P F).hom ≫
      (HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.app
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).obj P.complex) ≫
        HomologicalComplex.homologyMap ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).map φ) n

Next tactic:
erw [(HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.naturality]
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedObj_hom_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] (n : ℕ) :
    (F.leftDerived n).map f ≫ (Q.isoLeftDerivedObj F n).hom =
      (P.isoLeftDerivedObj F n).hom ≫
        (F.mapHomologicalComplex _ ⋙ HomologicalComplex.homologyFunctor _ _ n).map φ := by
  dsimp [isoLeftDerivedObj, Functor.leftDerived]
  rw [assoc, ← Functor.map_comp_assoc,
    ProjectiveResolution.isoLeftDerivedToHomotopyCategoryObj_hom_naturality f P Q φ comm F,
    Functor.map_comp, assoc]
  erw [(HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.naturality]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
n : ℕ
⊢ (HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map (isoLeftDerivedToHomotopyCategoryObj P F).hom ≫
      (HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.app
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).obj P.complex) ≫
        (HomologicalComplex.homologyFunctor D (ComplexShape.down ℕ) n).map
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).map φ) =
    (HomotopyCategory.homologyFunctor D (ComplexShape.down ℕ) n).map (isoLeftDerivedToHomotopyCategoryObj P F).hom ≫
      (HomotopyCategory.homologyFunctorFactors D (ComplexShape.down ℕ) n).hom.app
          ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).obj P.complex) ≫
        HomologicalComplex.homologyMap ((Functor.mapHomologicalComplex F (ComplexShape.down ℕ)).map φ) n

Next tactic:
rfl
@[reassoc]
lemma ProjectiveResolution.isoLeftDerivedObj_inv_naturality
    {X Y : C} (f : X ⟶ Y) (P : ProjectiveResolution X) (Q : ProjectiveResolution Y)
    (φ : P.complex ⟶ Q.complex) (comm : φ.f 0 ≫ Q.π.f 0 = P.π.f 0 ≫ f)
    (F : C ⥤ D) [F.Additive] (n : ℕ) :
    (P.isoLeftDerivedObj F n).inv ≫ (F.leftDerived n).map f =
        (F.mapHomologicalComplex _ ⋙ HomologicalComplex.homologyFunctor _ _ n).map φ ≫
          (Q.isoLeftDerivedObj F n).inv := by
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{u_2, u_1} D
inst✝³ : Abelian C
inst✝² : HasProjectiveResolutions C
inst✝¹ : Abelian D
X Y : C
f : X ⟶ Y
P : ProjectiveResolution X
Q : ProjectiveResolution Y
φ : P.complex ⟶ Q.complex
comm : HomologicalComplex.Hom.f φ 0 ≫ HomologicalComplex.Hom.f Q.π 0 = HomologicalComplex.Hom.f P.π 0 ≫ f
F : C ⥤ D
inst✝ : Functor.Additive F
n : ℕ
⊢ (isoLeftDerivedObj P F n).inv ≫ (Functor.leftDerived F n).map f =
    (Functor.mapHomologicalComplex F (ComplexShape.down ℕ) ⋙
            HomologicalComplex.homologyFunctor D (ComplexShape.down ℕ) n).map
        φ ≫
      (isoLeftDerivedObj Q F n).inv

Next tactic:
rw [← cancel_mono (Q.isoLeftDerivedObj F n).hom, assoc, assoc,
    ProjectiveResolution.isoLeftDerivedObj_hom_naturality f P Q φ comm F n,
    Iso.inv_hom_id_assoc, Iso.inv_hom_id, comp_id]
/-- The higher derived functors vanish on projective objects. -/
lemma Functor.isZero_leftDerived_obj_projective_succ
    (F : C ⥤ D) [F.Additive] (n : ℕ) (X : C) [Projective X] :
    IsZero ((F.leftDerived (n + 1)).obj X) := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
D : Type u_1
inst✝⁵ : Category.{u_2, u_1} D
inst✝⁴ : Abelian C
inst✝³ : HasProjectiveResolutions C
inst✝² : Abelian D
F : C ⥤ D
inst✝¹ : Additive F
n : ℕ
X : C
inst✝ : Projective X
⊢ IsZero ((leftDerived F (n + 1)).obj X)

Next tactic:
refine IsZero.of_iso ?_ ((ProjectiveResolution.self X).isoLeftDerivedObj F (n + 1))
/-- The higher derived functors vanish on projective objects. -/
lemma Functor.isZero_leftDerived_obj_projective_succ
    (F : C ⥤ D) [F.Additive] (n : ℕ) (X : C) [Projective X] :
    IsZero ((F.leftDerived (n + 1)).obj X) := by
  refine IsZero.of_iso ?_ ((ProjectiveResolution.self X).isoLeftDerivedObj F (n + 1))
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
D : Type u_1
inst✝⁵ : Category.{u_2, u_1} D
inst✝⁴ : Abelian C
inst✝³ : HasProjectiveResolutions C
inst✝² : Abelian D
F : C ⥤ D
inst✝¹ : Additive F
n : ℕ
X : C
inst✝ : Projective X
⊢ IsZero
    ((HomologicalComplex.homologyFunctor D (ComplexShape.down ℕ) (n + 1)).obj
      ((mapHomologicalComplex F (ComplexShape.down ℕ)).obj (ProjectiveResolution.self X).complex))

Next tactic:
erw [← HomologicalComplex.exactAt_iff_isZero_homology]
/-- The higher derived functors vanish on projective objects. -/
lemma Functor.isZero_leftDerived_obj_projective_succ
    (F : C ⥤ D) [F.Additive] (n : ℕ) (X : C) [Projective X] :
    IsZero ((F.leftDerived (n + 1)).obj X) := by
  refine IsZero.of_iso ?_ ((ProjectiveResolution.self X).isoLeftDerivedObj F (n + 1))
  erw [← HomologicalComplex.exactAt_iff_isZero_homology]
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
D : Type u_1
inst✝⁵ : Category.{u_2, u_1} D
inst✝⁴ : Abelian C
inst✝³ : HasProjectiveResolutions C
inst✝² : Abelian D
F : C ⥤ D
inst✝¹ : Additive F
n : ℕ
X : C
inst✝ : Projective X
⊢ HomologicalComplex.ExactAt ((mapHomologicalComplex F (ComplexShape.down ℕ)).obj (ProjectiveResolution.self X).complex)
    (n + 1)

Next tactic:
exact ShortComplex.exact_of_isZero_X₂ _ (F.map_isZero (by apply isZero_zero))
/-- The higher derived functors vanish on projective objects. -/
lemma Functor.isZero_leftDerived_obj_projective_succ
    (F : C ⥤ D) [F.Additive] (n : ℕ) (X : C) [Projective X] :
    IsZero ((F.leftDerived (n + 1)).obj X) := by
  refine IsZero.of_iso ?_ ((ProjectiveResolution.self X).isoLeftDerivedObj F (n + 1))
  erw [← HomologicalComplex.exactAt_iff_isZero_homology]
  exact ShortComplex.exact_of_isZero_X₂ _ (F.map_isZero (by 

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
D : Type u_1
inst✝⁵ : Category.{u_2, u_1} D
inst✝⁴ : Abelian C
inst✝³ : HasProjectiveResolutions C
inst✝² : Abelian D
F : C ⥤ D
inst✝¹ : Additive F
n : ℕ
X : C
inst✝ : Projective X
⊢ IsZero (HomologicalComplex.X (ProjectiveResolution.self X).complex (n + 1))

Next tactic:
apply isZero_zero