l3lab/ntp-mathlib huggingface dataset:
theorem StableUnderBaseChange.pullback_map [HasPullbacks C] {P : MorphismProperty C}
    (hP : StableUnderBaseChange P) (hP' : StableUnderComposition P) {S X X' Y Y' : C} {f : X ⟶ S}
    {g : Y ⟶ S} {f' : X' ⟶ S} {g' : Y' ⟶ S} {i₁ : X ⟶ X'} {i₂ : Y ⟶ Y'} (h₁ : P i₁) (h₂ : P i₂)
    (e₁ : f = i₁ ≫ f') (e₂ : g = i₂ ≫ g') :
    P (pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂)) := by
  have :
    pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂) =
      ((pullbackSymmetry _ _).hom ≫
          ((baseChange _).map (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g')).left) ≫
        (pullbackSymmetry _ _).hom ≫
          ((baseChange g').map (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f')).left :=
    by ext <;> dsimp <;> 

Proof state:
case h₀
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
⊢ pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') ≫ pullback.fst =
    (((pullbackSymmetry f g).hom ≫
          pullback.map g f g' f i₂ (𝟙 X) (𝟙 S) (_ : (Over.mk g).hom ≫ 𝟙 S = (Over.homMk i₂).left ≫ (Over.mk g').hom)
            (_ : f ≫ 𝟙 S = 𝟙 X ≫ f)) ≫
        (pullbackSymmetry g' f).hom ≫
          pullback.map f g' f' g' i₁ (𝟙 Y') (𝟙 S) (_ : (Over.mk f).hom ≫ 𝟙 S = (Over.homMk i₁).left ≫ (Over.mk f').hom)
            (_ : g' ≫ 𝟙 S = 𝟙 Y' ≫ g')) ≫
      pullback.fst

Next tactic:
simp
theorem StableUnderBaseChange.pullback_map [HasPullbacks C] {P : MorphismProperty C}
    (hP : StableUnderBaseChange P) (hP' : StableUnderComposition P) {S X X' Y Y' : C} {f : X ⟶ S}
    {g : Y ⟶ S} {f' : X' ⟶ S} {g' : Y' ⟶ S} {i₁ : X ⟶ X'} {i₂ : Y ⟶ Y'} (h₁ : P i₁) (h₂ : P i₂)
    (e₁ : f = i₁ ≫ f') (e₂ : g = i₂ ≫ g') :
    P (pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂)) := by
  have :
    pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂) =
      ((pullbackSymmetry _ _).hom ≫
          ((baseChange _).map (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g')).left) ≫
        (pullbackSymmetry _ _).hom ≫
          ((baseChange g').map (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f')).left :=
    by ext <;> dsimp <;> 

Proof state:
case h₁
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
⊢ pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') ≫ pullback.snd =
    (((pullbackSymmetry f g).hom ≫
          pullback.map g f g' f i₂ (𝟙 X) (𝟙 S) (_ : (Over.mk g).hom ≫ 𝟙 S = (Over.homMk i₂).left ≫ (Over.mk g').hom)
            (_ : f ≫ 𝟙 S = 𝟙 X ≫ f)) ≫
        (pullbackSymmetry g' f).hom ≫
          pullback.map f g' f' g' i₁ (𝟙 Y') (𝟙 S) (_ : (Over.mk f).hom ≫ 𝟙 S = (Over.homMk i₁).left ≫ (Over.mk f').hom)
            (_ : g' ≫ 𝟙 S = 𝟙 Y' ≫ g')) ≫
      pullback.snd

Next tactic:
simp
theorem StableUnderBaseChange.pullback_map [HasPullbacks C] {P : MorphismProperty C}
    (hP : StableUnderBaseChange P) (hP' : StableUnderComposition P) {S X X' Y Y' : C} {f : X ⟶ S}
    {g : Y ⟶ S} {f' : X' ⟶ S} {g' : Y' ⟶ S} {i₁ : X ⟶ X'} {i₂ : Y ⟶ Y'} (h₁ : P i₁) (h₂ : P i₂)
    (e₁ : f = i₁ ≫ f') (e₂ : g = i₂ ≫ g') :
    P (pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂)) := by
  have :
    pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂) =
      ((pullbackSymmetry _ _).hom ≫
          ((baseChange _).map (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g')).left) ≫
        (pullbackSymmetry _ _).hom ≫
          ((baseChange g').map (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f')).left :=
    by ext <;> dsimp <;> simp
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
this :
  pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') =
    ((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫ ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left) ≫
      (pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left
⊢ P (pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g'))

Next tactic:
rw [this]
theorem StableUnderBaseChange.pullback_map [HasPullbacks C] {P : MorphismProperty C}
    (hP : StableUnderBaseChange P) (hP' : StableUnderComposition P) {S X X' Y Y' : C} {f : X ⟶ S}
    {g : Y ⟶ S} {f' : X' ⟶ S} {g' : Y' ⟶ S} {i₁ : X ⟶ X'} {i₂ : Y ⟶ Y'} (h₁ : P i₁) (h₂ : P i₂)
    (e₁ : f = i₁ ≫ f') (e₂ : g = i₂ ≫ g') :
    P (pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂)) := by
  have :
    pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂) =
      ((pullbackSymmetry _ _).hom ≫
          ((baseChange _).map (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g')).left) ≫
        (pullbackSymmetry _ _).hom ≫
          ((baseChange g').map (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f')).left :=
    by ext <;> dsimp <;> simp
  rw [this]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
this :
  pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') =
    ((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫ ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left) ≫
      (pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left
⊢ P
    (((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫
        ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left) ≫
      (pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left)

Next tactic:
apply hP'
theorem StableUnderBaseChange.pullback_map [HasPullbacks C] {P : MorphismProperty C}
    (hP : StableUnderBaseChange P) (hP' : StableUnderComposition P) {S X X' Y Y' : C} {f : X ⟶ S}
    {g : Y ⟶ S} {f' : X' ⟶ S} {g' : Y' ⟶ S} {i₁ : X ⟶ X'} {i₂ : Y ⟶ Y'} (h₁ : P i₁) (h₂ : P i₂)
    (e₁ : f = i₁ ≫ f') (e₂ : g = i₂ ≫ g') :
    P (pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂)) := by
  have :
    pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂) =
      ((pullbackSymmetry _ _).hom ≫
          ((baseChange _).map (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g')).left) ≫
        (pullbackSymmetry _ _).hom ≫
          ((baseChange g').map (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f')).left :=
    by ext <;> dsimp <;> simp
  rw [this]
  apply hP' <;> 

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
this :
  pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') =
    ((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫ ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left) ≫
      (pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left
⊢ P ((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫ ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left)

Next tactic:
rw [hP.respectsIso.cancel_left_isIso]
theorem StableUnderBaseChange.pullback_map [HasPullbacks C] {P : MorphismProperty C}
    (hP : StableUnderBaseChange P) (hP' : StableUnderComposition P) {S X X' Y Y' : C} {f : X ⟶ S}
    {g : Y ⟶ S} {f' : X' ⟶ S} {g' : Y' ⟶ S} {i₁ : X ⟶ X'} {i₂ : Y ⟶ Y'} (h₁ : P i₁) (h₂ : P i₂)
    (e₁ : f = i₁ ≫ f') (e₂ : g = i₂ ≫ g') :
    P (pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂)) := by
  have :
    pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂) =
      ((pullbackSymmetry _ _).hom ≫
          ((baseChange _).map (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g')).left) ≫
        (pullbackSymmetry _ _).hom ≫
          ((baseChange g').map (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f')).left :=
    by ext <;> dsimp <;> simp
  rw [this]
  apply hP' <;> 

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
this :
  pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') =
    ((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫ ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left) ≫
      (pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left
⊢ P ((pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left)

Next tactic:
rw [hP.respectsIso.cancel_left_isIso]
theorem StableUnderBaseChange.pullback_map [HasPullbacks C] {P : MorphismProperty C}
    (hP : StableUnderBaseChange P) (hP' : StableUnderComposition P) {S X X' Y Y' : C} {f : X ⟶ S}
    {g : Y ⟶ S} {f' : X' ⟶ S} {g' : Y' ⟶ S} {i₁ : X ⟶ X'} {i₂ : Y ⟶ Y'} (h₁ : P i₁) (h₂ : P i₂)
    (e₁ : f = i₁ ≫ f') (e₂ : g = i₂ ≫ g') :
    P (pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂)) := by
  have :
    pullback.map f g f' g' i₁ i₂ (𝟙 _) ((Category.comp_id _).trans e₁)
        ((Category.comp_id _).trans e₂) =
      ((pullbackSymmetry _ _).hom ≫
          ((baseChange _).map (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g')).left) ≫
        (pullbackSymmetry _ _).hom ≫
          ((baseChange g').map (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f')).left :=
    by ext <;> dsimp <;> simp
  rw [this]
  apply hP' <;> rw [hP.respectsIso.cancel_left_isIso]
  

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
this :
  pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') =
    ((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫ ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left) ≫
      (pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left
⊢ P ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.51933, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : StableUnderComposition P
S X X' Y Y' : C
f : X ⟶ S
g : Y ⟶ S
f' : X' ⟶ S
g' : Y' ⟶ S
i₁ : X ⟶ X'
i₂ : Y ⟶ Y'
h₁ : P i₁
h₂ : P i₂
e₁ : f = i₁ ≫ f'
e₂ : g = i₂ ≫ g'
this :
  pullback.map f g f' g' i₁ i₂ (𝟙 S) (_ : f ≫ 𝟙 S = i₁ ≫ f') (_ : g ≫ 𝟙 S = i₂ ≫ g') =
    ((pullbackSymmetry (Over.mk f).hom (Over.mk g).hom).hom ≫ ((baseChange (Over.mk f).hom).map (Over.homMk i₂)).left) ≫
      (pullbackSymmetry (Over.mk g').hom (Over.mk f).hom).hom ≫ ((baseChange g').map (Over.homMk i₁)).left
⊢ P ((baseChange g').map (Over.homMk i₁)).left

Next tactic:
exacts [hP.baseChange_map _ (Over.homMk _ e₂.symm : Over.mk g ⟶ Over.mk g') h₂,
    hP.baseChange_map _ (Over.homMk _ e₁.symm : Over.mk f ⟶ Over.mk f') h₁]
theorem StableUnderCobaseChange.mk {P : MorphismProperty C} [HasPushouts C] (hP₁ : RespectsIso P)
    (hP₂ : ∀ (A B A' : C) (f : A ⟶ A') (g : A ⟶ B) (_ : P f), P (pushout.inr : B ⟶ pushout f g)) :
    StableUnderCobaseChange P := fun A A' B B' f g f' g' sq hf => by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.64557, u_1} D
P : MorphismProperty C
inst✝ : HasPushouts C
hP₁ : RespectsIso P
hP₂ : ∀ (A B A' : C) (f : A ⟶ A') (g : A ⟶ B), P f → P pushout.inr
A A' B B' : C
f : A ⟶ A'
g : A ⟶ B
f' : B ⟶ B'
g' : A' ⟶ B'
sq : IsPushout g f f' g'
hf : P f
⊢ P f'

Next tactic:
let e := sq.flip.isoPushout
theorem StableUnderCobaseChange.mk {P : MorphismProperty C} [HasPushouts C] (hP₁ : RespectsIso P)
    (hP₂ : ∀ (A B A' : C) (f : A ⟶ A') (g : A ⟶ B) (_ : P f), P (pushout.inr : B ⟶ pushout f g)) :
    StableUnderCobaseChange P := fun A A' B B' f g f' g' sq hf => by
  let e := sq.flip.isoPushout
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.64557, u_1} D
P : MorphismProperty C
inst✝ : HasPushouts C
hP₁ : RespectsIso P
hP₂ : ∀ (A B A' : C) (f : A ⟶ A') (g : A ⟶ B), P f → P pushout.inr
A A' B B' : C
f : A ⟶ A'
g : A ⟶ B
f' : B ⟶ B'
g' : A' ⟶ B'
sq : IsPushout g f f' g'
hf : P f
e : B' ≅ pushout f g := IsPushout.isoPushout (_ : IsPushout f g g' f')
⊢ P f'

Next tactic:
rw [← hP₁.cancel_right_isIso _ e.hom, sq.flip.inr_isoPushout_hom]
theorem StableUnderCobaseChange.mk {P : MorphismProperty C} [HasPushouts C] (hP₁ : RespectsIso P)
    (hP₂ : ∀ (A B A' : C) (f : A ⟶ A') (g : A ⟶ B) (_ : P f), P (pushout.inr : B ⟶ pushout f g)) :
    StableUnderCobaseChange P := fun A A' B B' f g f' g' sq hf => by
  let e := sq.flip.isoPushout
  rw [← hP₁.cancel_right_isIso _ e.hom, sq.flip.inr_isoPushout_hom]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.64557, u_1} D
P : MorphismProperty C
inst✝ : HasPushouts C
hP₁ : RespectsIso P
hP₂ : ∀ (A B A' : C) (f : A ⟶ A') (g : A ⟶ B), P f → P pushout.inr
A A' B B' : C
f : A ⟶ A'
g : A ⟶ B
f' : B ⟶ B'
g' : A' ⟶ B'
sq : IsPushout g f f' g'
hf : P f
e : B' ≅ pushout f g := IsPushout.isoPushout (_ : IsPushout f g g' f')
⊢ P pushout.inr

Next tactic:
exact hP₂ _ _ _ f g hf
theorem of_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (hF : W.IsInvertedBy F) (G : C₂ ⥤ C₃) :
    W.IsInvertedBy (F ⋙ G) := fun X Y f hf => by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u_1
inst✝³ : Category.{?u.72530, u_1} D
C₁ : Type u_2
C₂ : Type u_3
C₃ : Type u_4
inst✝² : Category.{u_5, u_2} C₁
inst✝¹ : Category.{u_6, u_3} C₂
inst✝ : Category.{u_7, u_4} C₃
W : MorphismProperty C₁
F : C₁ ⥤ C₂
hF : IsInvertedBy W F
G : C₂ ⥤ C₃
X Y : C₁
f : X ⟶ Y
hf : W f
⊢ IsIso ((F ⋙ G).map f)

Next tactic:
haveI := hF f hf
theorem of_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (hF : W.IsInvertedBy F) (G : C₂ ⥤ C₃) :
    W.IsInvertedBy (F ⋙ G) := fun X Y f hf => by
  haveI := hF f hf
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u_1
inst✝³ : Category.{?u.72530, u_1} D
C₁ : Type u_2
C₂ : Type u_3
C₃ : Type u_4
inst✝² : Category.{u_5, u_2} C₁
inst✝¹ : Category.{u_6, u_3} C₂
inst✝ : Category.{u_7, u_4} C₃
W : MorphismProperty C₁
F : C₁ ⥤ C₂
hF : IsInvertedBy W F
G : C₂ ⥤ C₃
X Y : C₁
f : X ⟶ Y
hf : W f
this : IsIso (F.map f)
⊢ IsIso ((F ⋙ G).map f)

Next tactic:
dsimp
theorem of_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (hF : W.IsInvertedBy F) (G : C₂ ⥤ C₃) :
    W.IsInvertedBy (F ⋙ G) := fun X Y f hf => by
  haveI := hF f hf
  dsimp
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u_1
inst✝³ : Category.{?u.72530, u_1} D
C₁ : Type u_2
C₂ : Type u_3
C₃ : Type u_4
inst✝² : Category.{u_5, u_2} C₁
inst✝¹ : Category.{u_6, u_3} C₂
inst✝ : Category.{u_7, u_4} C₃
W : MorphismProperty C₁
F : C₁ ⥤ C₂
hF : IsInvertedBy W F
G : C₂ ⥤ C₃
X Y : C₁
f : X ⟶ Y
hf : W f
this : IsIso (F.map f)
⊢ IsIso (G.map (F.map f))

Next tactic:
infer_instance
theorem op {W : MorphismProperty C} {L : C ⥤ D} (h : W.IsInvertedBy L) : W.op.IsInvertedBy L.op :=
  fun X Y f hf => by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : C ⥤ D
h : IsInvertedBy W L
X Y : Cᵒᵖ
f : X ⟶ Y
hf : MorphismProperty.op W f
⊢ IsIso (L.op.map f)

Next tactic:
haveI := h f.unop hf
theorem op {W : MorphismProperty C} {L : C ⥤ D} (h : W.IsInvertedBy L) : W.op.IsInvertedBy L.op :=
  fun X Y f hf => by
  haveI := h f.unop hf
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : C ⥤ D
h : IsInvertedBy W L
X Y : Cᵒᵖ
f : X ⟶ Y
hf : MorphismProperty.op W f
this : IsIso (L.map f.unop)
⊢ IsIso (L.op.map f)

Next tactic:
dsimp
theorem op {W : MorphismProperty C} {L : C ⥤ D} (h : W.IsInvertedBy L) : W.op.IsInvertedBy L.op :=
  fun X Y f hf => by
  haveI := h f.unop hf
  dsimp
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : C ⥤ D
h : IsInvertedBy W L
X Y : Cᵒᵖ
f : X ⟶ Y
hf : MorphismProperty.op W f
this : IsIso (L.map f.unop)
⊢ IsIso (L.map f.unop).op

Next tactic:
infer_instance
theorem rightOp {W : MorphismProperty C} {L : Cᵒᵖ ⥤ D} (h : W.op.IsInvertedBy L) :
    W.IsInvertedBy L.rightOp := fun X Y f hf => by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : Cᵒᵖ ⥤ D
h : IsInvertedBy (MorphismProperty.op W) L
X Y : C
f : X ⟶ Y
hf : W f
⊢ IsIso (L.rightOp.map f)

Next tactic:
haveI := h f.op hf
theorem rightOp {W : MorphismProperty C} {L : Cᵒᵖ ⥤ D} (h : W.op.IsInvertedBy L) :
    W.IsInvertedBy L.rightOp := fun X Y f hf => by
  haveI := h f.op hf
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : Cᵒᵖ ⥤ D
h : IsInvertedBy (MorphismProperty.op W) L
X Y : C
f : X ⟶ Y
hf : W f
this : IsIso (L.map f.op)
⊢ IsIso (L.rightOp.map f)

Next tactic:
dsimp
theorem rightOp {W : MorphismProperty C} {L : Cᵒᵖ ⥤ D} (h : W.op.IsInvertedBy L) :
    W.IsInvertedBy L.rightOp := fun X Y f hf => by
  haveI := h f.op hf
  dsimp
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : Cᵒᵖ ⥤ D
h : IsInvertedBy (MorphismProperty.op W) L
X Y : C
f : X ⟶ Y
hf : W f
this : IsIso (L.map f.op)
⊢ IsIso (L.map f.op).op

Next tactic:
infer_instance
theorem leftOp {W : MorphismProperty C} {L : C ⥤ Dᵒᵖ} (h : W.IsInvertedBy L) :
    W.op.IsInvertedBy L.leftOp := fun X Y f hf => by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : C ⥤ Dᵒᵖ
h : IsInvertedBy W L
X Y : Cᵒᵖ
f : X ⟶ Y
hf : MorphismProperty.op W f
⊢ IsIso (L.leftOp.map f)

Next tactic:
haveI := h f.unop hf
theorem leftOp {W : MorphismProperty C} {L : C ⥤ Dᵒᵖ} (h : W.IsInvertedBy L) :
    W.op.IsInvertedBy L.leftOp := fun X Y f hf => by
  haveI := h f.unop hf
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : C ⥤ Dᵒᵖ
h : IsInvertedBy W L
X Y : Cᵒᵖ
f : X ⟶ Y
hf : MorphismProperty.op W f
this : IsIso (L.map f.unop)
⊢ IsIso (L.leftOp.map f)

Next tactic:
dsimp
theorem leftOp {W : MorphismProperty C} {L : C ⥤ Dᵒᵖ} (h : W.IsInvertedBy L) :
    W.op.IsInvertedBy L.leftOp := fun X Y f hf => by
  haveI := h f.unop hf
  dsimp
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : C ⥤ Dᵒᵖ
h : IsInvertedBy W L
X Y : Cᵒᵖ
f : X ⟶ Y
hf : MorphismProperty.op W f
this : IsIso (L.map f.unop)
⊢ IsIso (L.map f.unop).unop

Next tactic:
infer_instance
theorem unop {W : MorphismProperty C} {L : Cᵒᵖ ⥤ Dᵒᵖ} (h : W.op.IsInvertedBy L) :
    W.IsInvertedBy L.unop := fun X Y f hf => by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : Cᵒᵖ ⥤ Dᵒᵖ
h : IsInvertedBy (MorphismProperty.op W) L
X Y : C
f : X ⟶ Y
hf : W f
⊢ IsIso ((Functor.unop L).map f)

Next tactic:
haveI := h f.op hf
theorem unop {W : MorphismProperty C} {L : Cᵒᵖ ⥤ Dᵒᵖ} (h : W.op.IsInvertedBy L) :
    W.IsInvertedBy L.unop := fun X Y f hf => by
  haveI := h f.op hf
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : Cᵒᵖ ⥤ Dᵒᵖ
h : IsInvertedBy (MorphismProperty.op W) L
X Y : C
f : X ⟶ Y
hf : W f
this : IsIso (L.map f.op)
⊢ IsIso ((Functor.unop L).map f)

Next tactic:
dsimp
theorem unop {W : MorphismProperty C} {L : Cᵒᵖ ⥤ Dᵒᵖ} (h : W.op.IsInvertedBy L) :
    W.IsInvertedBy L.unop := fun X Y f hf => by
  haveI := h f.op hf
  dsimp
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
L : Cᵒᵖ ⥤ Dᵒᵖ
h : IsInvertedBy (MorphismProperty.op W) L
X Y : C
f : X ⟶ Y
hf : W f
this : IsIso (L.map f.op)
⊢ IsIso (L.map f.op).unop

Next tactic:
infer_instance
theorem stableUnderComposition {F₁ F₂ : C ⥤ D} (app : ∀ X, F₁.obj X ⟶ F₂.obj X) :
    (naturalityProperty app).StableUnderComposition := fun X Y Z f g hf hg => by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
F₁ F₂ : C ⥤ D
app : (X : C) → F₁.obj X ⟶ F₂.obj X
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : naturalityProperty app f
hg : naturalityProperty app g
⊢ naturalityProperty app (f ≫ g)

Next tactic:
simp only [naturalityProperty] at hf hg ⊢
theorem stableUnderComposition {F₁ F₂ : C ⥤ D} (app : ∀ X, F₁.obj X ⟶ F₂.obj X) :
    (naturalityProperty app).StableUnderComposition := fun X Y Z f g hf hg => by
  simp only [naturalityProperty] at hf hg ⊢
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
F₁ F₂ : C ⥤ D
app : (X : C) → F₁.obj X ⟶ F₂.obj X
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : F₁.map f ≫ app Y = app X ≫ F₂.map f
hg : F₁.map g ≫ app Z = app Y ≫ F₂.map g
⊢ F₁.map (f ≫ g) ≫ app Z = app X ≫ F₂.map (f ≫ g)

Next tactic:
simp only [Functor.map_comp, Category.assoc, hg]
theorem stableUnderComposition {F₁ F₂ : C ⥤ D} (app : ∀ X, F₁.obj X ⟶ F₂.obj X) :
    (naturalityProperty app).StableUnderComposition := fun X Y Z f g hf hg => by
  simp only [naturalityProperty] at hf hg ⊢
  simp only [Functor.map_comp, Category.assoc, hg]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
F₁ F₂ : C ⥤ D
app : (X : C) → F₁.obj X ⟶ F₂.obj X
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : F₁.map f ≫ app Y = app X ≫ F₂.map f
hg : F₁.map g ≫ app Z = app Y ≫ F₂.map g
⊢ F₁.map f ≫ app Y ≫ F₂.map g = app X ≫ F₂.map f ≫ F₂.map g

Next tactic:
slice_lhs 1 2 => rw [hf]