l3lab/ntp-mathlib huggingface dataset:
/-- Let `P` be a polynomial over `R`. If `P` is a unit, then all its coefficients are nilpotent,
except its constant term which is a unit.

See also `Polynomial.isUnit_iff_coeff_isUnit_isNilpotent`. -/
theorem coeff_isUnit_isNilpotent_of_isUnit (hunit : IsUnit P) :
    IsUnit (P.coeff 0) ∧ (∀ i, i ≠ 0 → IsNilpotent (P.coeff i)) := by
  obtain ⟨Q, hQ⟩ := IsUnit.exists_right_inv hunit
  constructor
  · refine' isUnit_of_mul_eq_one _ (Q.coeff 0) _
    have h := (mul_coeff_zero P Q).symm
    rwa [hQ, coeff_one_zero] at h
  · intros n hn
    rw [nilpotent_iff_mem_prime]
    intros I hI
    let f := mapRingHom (Ideal.Quotient.mk I)
    have hPQ : degree (f P) = 0 ∧ degree (f Q) = 0 := by
      rw [← Nat.WithBot.add_eq_zero_iff, ← degree_mul, ← _root_.map_mul, hQ, map_one, degree_one]
    have hcoeff : (f P).coeff n = 0 := by
      refine' coeff_eq_zero_of_degree_lt _
      rw [hPQ.1]
      

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (f P) = 0 ∧ degree (f Q) = 0
⊢ 0 < ↑n

Next tactic:
exact (@WithBot.coe_pos _ _ _ n).2 (Ne.bot_lt hn)
/-- Let `P` be a polynomial over `R`. If `P` is a unit, then all its coefficients are nilpotent,
except its constant term which is a unit.

See also `Polynomial.isUnit_iff_coeff_isUnit_isNilpotent`. -/
theorem coeff_isUnit_isNilpotent_of_isUnit (hunit : IsUnit P) :
    IsUnit (P.coeff 0) ∧ (∀ i, i ≠ 0 → IsNilpotent (P.coeff i)) := by
  obtain ⟨Q, hQ⟩ := IsUnit.exists_right_inv hunit
  constructor
  · refine' isUnit_of_mul_eq_one _ (Q.coeff 0) _
    have h := (mul_coeff_zero P Q).symm
    rwa [hQ, coeff_one_zero] at h
  · intros n hn
    rw [nilpotent_iff_mem_prime]
    intros I hI
    let f := mapRingHom (Ideal.Quotient.mk I)
    have hPQ : degree (f P) = 0 ∧ degree (f Q) = 0 := by
      rw [← Nat.WithBot.add_eq_zero_iff, ← degree_mul, ← _root_.map_mul, hQ, map_one, degree_one]
    have hcoeff : (f P).coeff n = 0 := by
      refine' coeff_eq_zero_of_degree_lt _
      rw [hPQ.1]
      exact (@WithBot.coe_pos _ _ _ n).2 (Ne.bot_lt hn)
    

Proof state:
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (f P) = 0 ∧ degree (f Q) = 0
hcoeff : coeff (f P) n = 0
⊢ coeff P n ∈ I

Next tactic:
rw [coe_mapRingHom, coeff_map, ← RingHom.mem_ker, Ideal.mk_ker] at hcoeff
/-- Let `P` be a polynomial over `R`. If `P` is a unit, then all its coefficients are nilpotent,
except its constant term which is a unit.

See also `Polynomial.isUnit_iff_coeff_isUnit_isNilpotent`. -/
theorem coeff_isUnit_isNilpotent_of_isUnit (hunit : IsUnit P) :
    IsUnit (P.coeff 0) ∧ (∀ i, i ≠ 0 → IsNilpotent (P.coeff i)) := by
  obtain ⟨Q, hQ⟩ := IsUnit.exists_right_inv hunit
  constructor
  · refine' isUnit_of_mul_eq_one _ (Q.coeff 0) _
    have h := (mul_coeff_zero P Q).symm
    rwa [hQ, coeff_one_zero] at h
  · intros n hn
    rw [nilpotent_iff_mem_prime]
    intros I hI
    let f := mapRingHom (Ideal.Quotient.mk I)
    have hPQ : degree (f P) = 0 ∧ degree (f Q) = 0 := by
      rw [← Nat.WithBot.add_eq_zero_iff, ← degree_mul, ← _root_.map_mul, hQ, map_one, degree_one]
    have hcoeff : (f P).coeff n = 0 := by
      refine' coeff_eq_zero_of_degree_lt _
      rw [hPQ.1]
      exact (@WithBot.coe_pos _ _ _ n).2 (Ne.bot_lt hn)
    rw [coe_mapRingHom, coeff_map, ← RingHom.mem_ker, Ideal.mk_ker] at hcoeff
    

Proof state:
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (f P) = 0 ∧ degree (f Q) = 0
hcoeff : coeff P n ∈ I
⊢ coeff P n ∈ I

Next tactic:
exact hcoeff
@[simp] lemma isUnit_C_add_X_mul_iff :
    IsUnit (C r + X * P) ↔ IsUnit r ∧ IsNilpotent P := by
  

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsUnit (C r + X * P) ↔ IsUnit r ∧ IsNilpotent P

Next tactic:
have : ∀ i, coeff (C r + X * P) (i + 1) = coeff P i := by simp
@[simp] lemma isUnit_C_add_X_mul_iff :
    IsUnit (C r + X * P) ↔ IsUnit r ∧ IsNilpotent P := by
  have : ∀ i, coeff (C r + X * P) (i + 1) = coeff P i := by 

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ ∀ (i : ℕ), coeff (C r + X * P) (i + 1) = coeff P i

Next tactic:
simp
@[simp] lemma isUnit_C_add_X_mul_iff :
    IsUnit (C r + X * P) ↔ IsUnit r ∧ IsNilpotent P := by
  have : ∀ i, coeff (C r + X * P) (i + 1) = coeff P i := by simp
  

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : ∀ (i : ℕ), coeff (C r + X * P) (i + 1) = coeff P i
⊢ IsUnit (C r + X * P) ↔ IsUnit r ∧ IsNilpotent P

Next tactic:
simp_rw [isUnit_iff_coeff_isUnit_isNilpotent, Nat.forall_ne_zero_iff, this]
@[simp] lemma isUnit_C_add_X_mul_iff :
    IsUnit (C r + X * P) ↔ IsUnit r ∧ IsNilpotent P := by
  have : ∀ i, coeff (C r + X * P) (i + 1) = coeff P i := by simp
  simp_rw [isUnit_iff_coeff_isUnit_isNilpotent, Nat.forall_ne_zero_iff, this]
  

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : ∀ (i : ℕ), coeff (C r + X * P) (i + 1) = coeff P i
⊢ (IsUnit (coeff (C r + X * P) 0) ∧ ∀ (i : ℕ), IsNilpotent (coeff P i)) ↔ IsUnit r ∧ IsNilpotent P

Next tactic:
simp only [coeff_add, coeff_C_zero, mul_coeff_zero, coeff_X_zero, zero_mul, add_zero,
    and_congr_right_iff, ← Polynomial.isNilpotent_iff]
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)

Next tactic:
suffices P = C (eval 0 P) + X * (P /ₘ X) by
    conv_lhs => rw [this]; simp
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  suffices P = C (eval 0 P) + X * (P /ₘ X) by
    

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = C (eval 0 P) + X * (P /ₘ X)
⊢ IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)

Next tactic:
conv_lhs => rw [this]; simp
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  suffices P = C (eval 0 P) + X * (P /ₘ X) by
    conv_lhs => 

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = C (eval 0 P) + X * (P /ₘ X)
| IsUnit P

Next tactic:
rw [this]; simp
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  suffices P = C (eval 0 P) + X * (P /ₘ X) by
    conv_lhs => 

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = C (eval 0 P) + X * (P /ₘ X)
| IsUnit P

Next tactic:
rw [this]
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  suffices P = C (eval 0 P) + X * (P /ₘ X) by
    conv_lhs => rw [this]; 

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = C (eval 0 P) + X * (P /ₘ X)
| IsUnit (C (eval 0 P) + X * (P /ₘ X))

Next tactic:
simp
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  suffices P = C (eval 0 P) + X * (P /ₘ X) by
    conv_lhs => rw [this]; simp
  

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ P = C (eval 0 P) + X * (P /ₘ X)

Next tactic:
conv_lhs => rw [← modByMonic_add_div P monic_X]
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  suffices P = C (eval 0 P) + X * (P /ₘ X) by
    conv_lhs => rw [this]; simp
  conv_lhs => 

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
| P

Next tactic:
rw [← modByMonic_add_div P monic_X]
lemma isUnit_iff' :
    IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)  := by
  suffices P = C (eval 0 P) + X * (P /ₘ X) by
    conv_lhs => rw [this]; simp
  conv_lhs => rw [← modByMonic_add_div P monic_X]
  

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ P %ₘ X + X * (P /ₘ X) = C (eval 0 P) + X * (P /ₘ X)

Next tactic:
simp [modByMonic_X]
@[reassoc (attr := simp)]
lemma π₁Toπ₂_comp_π₂Toπ₃ : (π₁Toπ₂ : (_ : _ ⥤ C) ⟶ _) ≫ π₂Toπ₃ = 0 := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝² : Category.{u_3, u_1} C
inst✝¹ : Category.{?u.36967, u_2} D
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
⊢ π₁Toπ₂ ≫ π₂Toπ₃ = 0

Next tactic:
aesop_cat
/-- The short complex in `D` obtained by applying a functor `F : C ⥤ D` to a
short complex in `C`, assuming that `F` preserves zero morphisms. -/
@[simps]
def map (F : C ⥤ D) [F.PreservesZeroMorphisms] : ShortComplex D :=
  ShortComplex.mk (F.map S.f) (F.map S.g) (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.39893, u_1} C
inst✝³ : Category.{?u.39897, u_2} D
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasZeroMorphisms D
F : C ⥤ D
inst✝ : Functor.PreservesZeroMorphisms F
⊢ F.map S.f ≫ F.map S.g = 0

Next tactic:
rw [← F.map_comp, S.zero, F.map_zero]
/-- The functor `ShortComplex C ⥤ ShortComplex D` induced by a functor `C ⥤ D` which
preserves zero morphisms. -/
@[simps]
def _root_.CategoryTheory.Functor.mapShortComplex (F : C ⥤ D) [F.PreservesZeroMorphisms] :
    ShortComplex C ⥤ ShortComplex D where
  obj S := S.map F
  map φ :=
    { τ₁ := F.map φ.τ₁
      τ₂ := F.map φ.τ₂
      τ₃ := F.map φ.τ₃
      comm₁₂ := by
        

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.49139, u_1} C
inst✝³ : Category.{?u.49143, u_2} D
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasZeroMorphisms D
F : C ⥤ D
inst✝ : Functor.PreservesZeroMorphisms F
X✝ Y✝ : ShortComplex C
φ : X✝ ⟶ Y✝
⊢ F.map φ.τ₁ ≫ ((fun S => map S F) Y✝).f = ((fun S => map S F) X✝).f ≫ F.map φ.τ₂

Next tactic:
dsimp
/-- The functor `ShortComplex C ⥤ ShortComplex D` induced by a functor `C ⥤ D` which
preserves zero morphisms. -/
@[simps]
def _root_.CategoryTheory.Functor.mapShortComplex (F : C ⥤ D) [F.PreservesZeroMorphisms] :
    ShortComplex C ⥤ ShortComplex D where
  obj S := S.map F
  map φ :=
    { τ₁ := F.map φ.τ₁
      τ₂ := F.map φ.τ₂
      τ₃ := F.map φ.τ₃
      comm₁₂ := by
        dsimp
        

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.49139, u_1} C
inst✝³ : Category.{?u.49143, u_2} D
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasZeroMorphisms D
F : C ⥤ D
inst✝ : Functor.PreservesZeroMorphisms F
X✝ Y✝ : ShortComplex C
φ : X✝ ⟶ Y✝
⊢ F.map φ.τ₁ ≫ F.map Y✝.f = F.map X✝.f ≫ F.map φ.τ₂

Next tactic:
simp only [← F.map_comp, φ.comm₁₂]
/-- The functor `ShortComplex C ⥤ ShortComplex D` induced by a functor `C ⥤ D` which
preserves zero morphisms. -/
@[simps]
def _root_.CategoryTheory.Functor.mapShortComplex (F : C ⥤ D) [F.PreservesZeroMorphisms] :
    ShortComplex C ⥤ ShortComplex D where
  obj S := S.map F
  map φ :=
    { τ₁ := F.map φ.τ₁
      τ₂ := F.map φ.τ₂
      τ₃ := F.map φ.τ₃
      comm₁₂ := by
        dsimp
        simp only [← F.map_comp, φ.comm₁₂]
      comm₂₃ := by
        

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.49139, u_1} C
inst✝³ : Category.{?u.49143, u_2} D
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasZeroMorphisms D
F : C ⥤ D
inst✝ : Functor.PreservesZeroMorphisms F
X✝ Y✝ : ShortComplex C
φ : X✝ ⟶ Y✝
⊢ F.map φ.τ₂ ≫ ((fun S => map S F) Y✝).g = ((fun S => map S F) X✝).g ≫ F.map φ.τ₃

Next tactic:
dsimp
/-- The functor `ShortComplex C ⥤ ShortComplex D` induced by a functor `C ⥤ D` which
preserves zero morphisms. -/
@[simps]
def _root_.CategoryTheory.Functor.mapShortComplex (F : C ⥤ D) [F.PreservesZeroMorphisms] :
    ShortComplex C ⥤ ShortComplex D where
  obj S := S.map F
  map φ :=
    { τ₁ := F.map φ.τ₁
      τ₂ := F.map φ.τ₂
      τ₃ := F.map φ.τ₃
      comm₁₂ := by
        dsimp
        simp only [← F.map_comp, φ.comm₁₂]
      comm₂₃ := by
        dsimp
        

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.49139, u_1} C
inst✝³ : Category.{?u.49143, u_2} D
inst✝² : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝¹ : HasZeroMorphisms D
F : C ⥤ D
inst✝ : Functor.PreservesZeroMorphisms F
X✝ Y✝ : ShortComplex C
φ : X✝ ⟶ Y✝
⊢ F.map φ.τ₂ ≫ F.map Y✝.g = F.map X✝.g ≫ F.map φ.τ₃

Next tactic:
simp only [← F.map_comp, φ.comm₂₃]
/-- A constructor for isomorphisms in the category `ShortComplex C`-/
@[simps]
def isoMk (e₁ : S₁.X₁ ≅ S₂.X₁) (e₂ : S₁.X₂ ≅ S₂.X₂) (e₃ : S₁.X₃ ≅ S₂.X₃)
    (comm₁₂ : e₁.hom ≫ S₂.f = S₁.f ≫ e₂.hom := by aesop_cat)
    (comm₂₃ : e₂.hom ≫ S₂.g = S₁.g ≫ e₃.hom := by aesop_cat) :
    S₁ ≅ S₂ where
  hom := ⟨e₁.hom, e₂.hom, e₃.hom, comm₁₂, comm₂₃⟩
  inv := homMk e₁.inv e₂.inv e₃.inv
    (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.56783, u_1} C
inst✝² : Category.{?u.56787, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
e₁ : S₁.X₁ ≅ S₂.X₁
e₂ : S₁.X₂ ≅ S₂.X₂
e₃ : S₁.X₃ ≅ S₂.X₃
comm₁₂ : autoParam (e₁.hom ≫ S₂.f = S₁.f ≫ e₂.hom) _auto✝
comm₂₃ : autoParam (e₂.hom ≫ S₂.g = S₁.g ≫ e₃.hom) _auto✝
⊢ e₁.inv ≫ S₁.f = S₂.f ≫ e₂.inv

Next tactic:
rw [← cancel_mono e₂.hom, assoc, assoc, e₂.inv_hom_id, comp_id,
          ← comm₁₂, e₁.inv_hom_id_assoc]
/-- A constructor for isomorphisms in the category `ShortComplex C`-/
@[simps]
def isoMk (e₁ : S₁.X₁ ≅ S₂.X₁) (e₂ : S₁.X₂ ≅ S₂.X₂) (e₃ : S₁.X₃ ≅ S₂.X₃)
    (comm₁₂ : e₁.hom ≫ S₂.f = S₁.f ≫ e₂.hom := by aesop_cat)
    (comm₂₃ : e₂.hom ≫ S₂.g = S₁.g ≫ e₃.hom := by aesop_cat) :
    S₁ ≅ S₂ where
  hom := ⟨e₁.hom, e₂.hom, e₃.hom, comm₁₂, comm₂₃⟩
  inv := homMk e₁.inv e₂.inv e₃.inv
    (by rw [← cancel_mono e₂.hom, assoc, assoc, e₂.inv_hom_id, comp_id,
          ← comm₁₂, e₁.inv_hom_id_assoc])
    (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.56783, u_1} C
inst✝² : Category.{?u.56787, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
e₁ : S₁.X₁ ≅ S₂.X₁
e₂ : S₁.X₂ ≅ S₂.X₂
e₃ : S₁.X₃ ≅ S₂.X₃
comm₁₂ : autoParam (e₁.hom ≫ S₂.f = S₁.f ≫ e₂.hom) _auto✝
comm₂₃ : autoParam (e₂.hom ≫ S₂.g = S₁.g ≫ e₃.hom) _auto✝
⊢ e₂.inv ≫ S₁.g = S₂.g ≫ e₃.inv

Next tactic:
rw [← cancel_mono e₃.hom, assoc, assoc, e₃.inv_hom_id, comp_id,
          ← comm₂₃, e₂.inv_hom_id_assoc]
/-- The opposite `ShortComplex` in `Cᵒᵖ` associated to a short complex in `C`. -/
@[simps]
def op : ShortComplex Cᵒᵖ :=
  mk S.g.op S.f.op (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.68483, u_1} C
inst✝² : Category.{?u.68487, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
⊢ S.g.op ≫ S.f.op = 0

Next tactic:
simp only [← op_comp, S.zero]
/-- The opposite `ShortComplex` in `Cᵒᵖ` associated to a short complex in `C`. -/
@[simps]
def op : ShortComplex Cᵒᵖ :=
  mk S.g.op S.f.op (by simp only [← op_comp, S.zero]; 

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.68483, u_1} C
inst✝² : Category.{?u.68487, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
⊢ 0.op = 0

Next tactic:
rfl
/-- The opposite morphism in `ShortComplex Cᵒᵖ` associated to a morphism in `ShortComplex C` -/
@[simps]
def opMap (φ : S₁ ⟶ S₂) : S₂.op ⟶ S₁.op where
  τ₁ := φ.τ₃.op
  τ₂ := φ.τ₂.op
  τ₃ := φ.τ₁.op
  comm₁₂ := by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.69186, u_1} C
inst✝² : Category.{?u.69190, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
φ : S₁ ⟶ S₂
⊢ φ.τ₃.op ≫ (op S₁).f = (op S₂).f ≫ φ.τ₂.op

Next tactic:
dsimp
/-- The opposite morphism in `ShortComplex Cᵒᵖ` associated to a morphism in `ShortComplex C` -/
@[simps]
def opMap (φ : S₁ ⟶ S₂) : S₂.op ⟶ S₁.op where
  τ₁ := φ.τ₃.op
  τ₂ := φ.τ₂.op
  τ₃ := φ.τ₁.op
  comm₁₂ := by
    dsimp
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.69186, u_1} C
inst✝² : Category.{?u.69190, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
φ : S₁ ⟶ S₂
⊢ φ.τ₃.op ≫ S₁.g.op = S₂.g.op ≫ φ.τ₂.op

Next tactic:
simp only [← op_comp, φ.comm₂₃]
/-- The opposite morphism in `ShortComplex Cᵒᵖ` associated to a morphism in `ShortComplex C` -/
@[simps]
def opMap (φ : S₁ ⟶ S₂) : S₂.op ⟶ S₁.op where
  τ₁ := φ.τ₃.op
  τ₂ := φ.τ₂.op
  τ₃ := φ.τ₁.op
  comm₁₂ := by
    dsimp
    simp only [← op_comp, φ.comm₂₃]
  comm₂₃ := by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.69186, u_1} C
inst✝² : Category.{?u.69190, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
φ : S₁ ⟶ S₂
⊢ φ.τ₂.op ≫ (op S₁).g = (op S₂).g ≫ φ.τ₁.op

Next tactic:
dsimp
/-- The opposite morphism in `ShortComplex Cᵒᵖ` associated to a morphism in `ShortComplex C` -/
@[simps]
def opMap (φ : S₁ ⟶ S₂) : S₂.op ⟶ S₁.op where
  τ₁ := φ.τ₃.op
  τ₂ := φ.τ₂.op
  τ₃ := φ.τ₁.op
  comm₁₂ := by
    dsimp
    simp only [← op_comp, φ.comm₂₃]
  comm₂₃ := by
    dsimp
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.69186, u_1} C
inst✝² : Category.{?u.69190, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
φ : S₁ ⟶ S₂
⊢ φ.τ₂.op ≫ S₁.f.op = S₂.f.op ≫ φ.τ₁.op

Next tactic:
simp only [← op_comp, φ.comm₁₂]
/-- The `ShortComplex` in `C` associated to a short complex in `Cᵒᵖ`. -/
@[simps]
def unop (S : ShortComplex Cᵒᵖ) : ShortComplex C :=
  mk S.g.unop S.f.unop (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.70602, u_1} C
inst✝² : Category.{?u.70606, u_2} D
inst✝¹ : HasZeroMorphisms C
S✝ S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
S : ShortComplex Cᵒᵖ
⊢ S.g.unop ≫ S.f.unop = 0

Next tactic:
simp only [← unop_comp, S.zero]
/-- The `ShortComplex` in `C` associated to a short complex in `Cᵒᵖ`. -/
@[simps]
def unop (S : ShortComplex Cᵒᵖ) : ShortComplex C :=
  mk S.g.unop S.f.unop (by simp only [← unop_comp, S.zero]; 

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.70602, u_1} C
inst✝² : Category.{?u.70606, u_2} D
inst✝¹ : HasZeroMorphisms C
S✝ S₁ S₂ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
S : ShortComplex Cᵒᵖ
⊢ 0.unop = 0

Next tactic:
rfl
/-- The morphism in `ShortComplex C` associated to a morphism in `ShortComplex Cᵒᵖ` -/
@[simps]
def unopMap {S₁ S₂ : ShortComplex Cᵒᵖ} (φ : S₁ ⟶ S₂) : S₂.unop ⟶ S₁.unop where
  τ₁ := φ.τ₃.unop
  τ₂ := φ.τ₂.unop
  τ₃ := φ.τ₁.unop
  comm₁₂ := by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.71370, u_1} C
inst✝² : Category.{?u.71374, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁✝ S₂✝ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
S₁ S₂ : ShortComplex Cᵒᵖ
φ : S₁ ⟶ S₂
⊢ φ.τ₃.unop ≫ (unop S₁).f = (unop S₂).f ≫ φ.τ₂.unop

Next tactic:
dsimp
/-- The morphism in `ShortComplex C` associated to a morphism in `ShortComplex Cᵒᵖ` -/
@[simps]
def unopMap {S₁ S₂ : ShortComplex Cᵒᵖ} (φ : S₁ ⟶ S₂) : S₂.unop ⟶ S₁.unop where
  τ₁ := φ.τ₃.unop
  τ₂ := φ.τ₂.unop
  τ₃ := φ.τ₁.unop
  comm₁₂ := by
    dsimp
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.71370, u_1} C
inst✝² : Category.{?u.71374, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁✝ S₂✝ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
S₁ S₂ : ShortComplex Cᵒᵖ
φ : S₁ ⟶ S₂
⊢ φ.τ₃.unop ≫ S₁.g.unop = S₂.g.unop ≫ φ.τ₂.unop

Next tactic:
simp only [← unop_comp, φ.comm₂₃]
/-- The morphism in `ShortComplex C` associated to a morphism in `ShortComplex Cᵒᵖ` -/
@[simps]
def unopMap {S₁ S₂ : ShortComplex Cᵒᵖ} (φ : S₁ ⟶ S₂) : S₂.unop ⟶ S₁.unop where
  τ₁ := φ.τ₃.unop
  τ₂ := φ.τ₂.unop
  τ₃ := φ.τ₁.unop
  comm₁₂ := by
    dsimp
    simp only [← unop_comp, φ.comm₂₃]
  comm₂₃ := by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.71370, u_1} C
inst✝² : Category.{?u.71374, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁✝ S₂✝ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
S₁ S₂ : ShortComplex Cᵒᵖ
φ : S₁ ⟶ S₂
⊢ φ.τ₂.unop ≫ (unop S₁).g = (unop S₂).g ≫ φ.τ₁.unop

Next tactic:
dsimp
/-- The morphism in `ShortComplex C` associated to a morphism in `ShortComplex Cᵒᵖ` -/
@[simps]
def unopMap {S₁ S₂ : ShortComplex Cᵒᵖ} (φ : S₁ ⟶ S₂) : S₂.unop ⟶ S₁.unop where
  τ₁ := φ.τ₃.unop
  τ₂ := φ.τ₂.unop
  τ₃ := φ.τ₁.unop
  comm₁₂ := by
    dsimp
    simp only [← unop_comp, φ.comm₂₃]
  comm₂₃ := by
    dsimp
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{?u.71370, u_1} C
inst✝² : Category.{?u.71374, u_2} D
inst✝¹ : HasZeroMorphisms C
S S₁✝ S₂✝ S₃ : ShortComplex C
inst✝ : HasZeroMorphisms D
S₁ S₂ : ShortComplex Cᵒᵖ
φ : S₁ ⟶ S₂
⊢ φ.τ₂.unop ≫ S₁.f.unop = S₂.f.unop ≫ φ.τ₁.unop

Next tactic:
simp only [← unop_comp, φ.comm₁₂]
instance preservesMonomorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesMonomorphisms F]
    [PreservesMonomorphisms G] : PreservesMonomorphisms (F ⋙ G) where
  preserves f h := by
    

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
G : D ⥤ E
inst✝¹ : PreservesMonomorphisms F
inst✝ : PreservesMonomorphisms G
X✝ Y✝ : C
f : X✝ ⟶ Y✝
h : Mono f
⊢ Mono ((F ⋙ G).map f)

Next tactic:
rw [comp_map]
instance preservesMonomorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesMonomorphisms F]
    [PreservesMonomorphisms G] : PreservesMonomorphisms (F ⋙ G) where
  preserves f h := by
    rw [comp_map]
    

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
G : D ⥤ E
inst✝¹ : PreservesMonomorphisms F
inst✝ : PreservesMonomorphisms G
X✝ Y✝ : C
f : X✝ ⟶ Y✝
h : Mono f
⊢ Mono (G.map (F.map f))

Next tactic:
exact inferInstance
instance preservesEpimorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesEpimorphisms F]
    [PreservesEpimorphisms G] : PreservesEpimorphisms (F ⋙ G) where
  preserves f h := by
    

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
G : D ⥤ E
inst✝¹ : PreservesEpimorphisms F
inst✝ : PreservesEpimorphisms G
X✝ Y✝ : C
f : X✝ ⟶ Y✝
h : Epi f
⊢ Epi ((F ⋙ G).map f)

Next tactic:
rw [comp_map]
instance preservesEpimorphisms_comp (F : C ⥤ D) (G : D ⥤ E) [PreservesEpimorphisms F]
    [PreservesEpimorphisms G] : PreservesEpimorphisms (F ⋙ G) where
  preserves f h := by
    rw [comp_map]
    

Proof state:
C : Type u₁
inst✝⁴ : Category.{v₁, u₁} C
D : Type u₂
inst✝³ : Category.{v₂, u₂} D
E : Type u₃
inst✝² : Category.{v₃, u₃} E
F : C ⥤ D
G : D ⥤ E
inst✝¹ : PreservesEpimorphisms F
inst✝ : PreservesEpimorphisms G
X✝ Y✝ : C
f : X✝ ⟶ Y✝
h : Epi f
⊢ Epi (G.map (F.map f))

Next tactic:
exact inferInstance
theorem preservesMonomorphisms.of_iso {F G : C ⥤ D} [PreservesMonomorphisms F] (α : F ≅ G) :
    PreservesMonomorphisms G :=
  { preserves := fun {X} {Y} f h => by
      

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
F G : C ⥤ D
inst✝ : PreservesMonomorphisms F
α : F ≅ G
X Y : C
f : X ⟶ Y
h : Mono f
⊢ Mono (G.map f)

Next tactic:
haveI : Mono (F.map f ≫ (α.app Y).hom) := mono_comp _ _
theorem preservesMonomorphisms.of_iso {F G : C ⥤ D} [PreservesMonomorphisms F] (α : F ≅ G) :
    PreservesMonomorphisms G :=
  { preserves := fun {X} {Y} f h => by
      haveI : Mono (F.map f ≫ (α.app Y).hom) := mono_comp _ _
      

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
F G : C ⥤ D
inst✝ : PreservesMonomorphisms F
α : F ≅ G
X Y : C
f : X ⟶ Y
h : Mono f
this : Mono (F.map f ≫ (α.app Y).hom)
⊢ Mono (G.map f)

Next tactic:
convert (mono_comp _ _ : Mono ((α.app X).inv ≫ F.map f ≫ (α.app Y).hom))
theorem preservesMonomorphisms.of_iso {F G : C ⥤ D} [PreservesMonomorphisms F] (α : F ≅ G) :
    PreservesMonomorphisms G :=
  { preserves := fun {X} {Y} f h => by
      haveI : Mono (F.map f ≫ (α.app Y).hom) := mono_comp _ _
      convert (mono_comp _ _ : Mono ((α.app X).inv ≫ F.map f ≫ (α.app Y).hom))
      

Proof state:
case h.e'_5
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
E : Type u₃
inst✝¹ : Category.{v₃, u₃} E
F G : C ⥤ D
inst✝ : PreservesMonomorphisms F
α : F ≅ G
X Y : C
f : X ⟶ Y
h : Mono f
this : Mono (F.map f ≫ (α.app Y).hom)
⊢ G.map f = (α.app X).inv ≫ F.map f ≫ (α.app Y).hom

Next tactic:
rw [Iso.eq_inv_comp, Iso.app_hom, Iso.app_hom, NatTrans.naturality]