l3lab/ntp-mathlib huggingface dataset:
lemma map_id_eq_isoClosure (P : MorphismProperty C) :
    P.map (𝟭 _) = P.isoClosure := by
  apply subset_antisymm
  · 

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.101058, u_1} D
P : MorphismProperty C
⊢ map P (𝟭 C) ⊆ isoClosure P

Next tactic:
rw [map_subset_iff _ _ _ P.isoClosure_respectsIso]
lemma map_id_eq_isoClosure (P : MorphismProperty C) :
    P.map (𝟭 _) = P.isoClosure := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ P.isoClosure_respectsIso]
    

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.101058, u_1} D
P : MorphismProperty C
⊢ ∀ (X Y : C) (f : X ⟶ Y), P f → isoClosure P ((𝟭 C).map f)

Next tactic:
intro X Y f hf
lemma map_id_eq_isoClosure (P : MorphismProperty C) :
    P.map (𝟭 _) = P.isoClosure := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ P.isoClosure_respectsIso]
    intro X Y f hf
    

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.101058, u_1} D
P : MorphismProperty C
X Y : C
f : X ⟶ Y
hf : P f
⊢ isoClosure P ((𝟭 C).map f)

Next tactic:
exact P.subset_isoClosure _ hf
lemma map_id_eq_isoClosure (P : MorphismProperty C) :
    P.map (𝟭 _) = P.isoClosure := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ P.isoClosure_respectsIso]
    intro X Y f hf
    exact P.subset_isoClosure _ hf
  · 

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.101058, u_1} D
P : MorphismProperty C
⊢ isoClosure P ⊆ map P (𝟭 C)

Next tactic:
intro X Y f hf
lemma map_id_eq_isoClosure (P : MorphismProperty C) :
    P.map (𝟭 _) = P.isoClosure := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ P.isoClosure_respectsIso]
    intro X Y f hf
    exact P.subset_isoClosure _ hf
  · intro X Y f hf
    

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.101058, u_1} D
P : MorphismProperty C
X Y : C
f : X ⟶ Y
hf : isoClosure P f
⊢ map P (𝟭 C) f

Next tactic:
exact hf
lemma map_id (P : MorphismProperty C) (hP : RespectsIso P) :
    P.map (𝟭 _) = P := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.101672, u_1} D
P : MorphismProperty C
hP : RespectsIso P
⊢ map P (𝟭 C) = P

Next tactic:
rw [map_id_eq_isoClosure, hP.isoClosure_eq]
@[simp]
lemma map_map (P : MorphismProperty C) (F : C ⥤ D) {E : Type*} [Category E] (G : D ⥤ E) :
    (P.map F).map G = P.map (F ⋙ G) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_3, u_1} D
P : MorphismProperty C
F : C ⥤ D
E : Type u_2
inst✝ : Category.{u_4, u_2} E
G : D ⥤ E
⊢ map (map P F) G = map P (F ⋙ G)

Next tactic:
apply subset_antisymm
@[simp]
lemma map_map (P : MorphismProperty C) (F : C ⥤ D) {E : Type*} [Category E] (G : D ⥤ E) :
    (P.map F).map G = P.map (F ⋙ G) := by
  apply subset_antisymm
  · 

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_3, u_1} D
P : MorphismProperty C
F : C ⥤ D
E : Type u_2
inst✝ : Category.{u_4, u_2} E
G : D ⥤ E
⊢ map (map P F) G ⊆ map P (F ⋙ G)

Next tactic:
rw [map_subset_iff _ _ _ (map_respectsIso _ (F ⋙ G))]
@[simp]
lemma map_map (P : MorphismProperty C) (F : C ⥤ D) {E : Type*} [Category E] (G : D ⥤ E) :
    (P.map F).map G = P.map (F ⋙ G) := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (map_respectsIso _ (F ⋙ G))]
    

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_3, u_1} D
P : MorphismProperty C
F : C ⥤ D
E : Type u_2
inst✝ : Category.{u_4, u_2} E
G : D ⥤ E
⊢ ∀ (X Y : D) (f : X ⟶ Y), map P F f → map P (F ⋙ G) (G.map f)

Next tactic:
intro X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
@[simp]
lemma map_map (P : MorphismProperty C) (F : C ⥤ D) {E : Type*} [Category E] (G : D ⥤ E) :
    (P.map F).map G = P.map (F ⋙ G) := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (map_respectsIso _ (F ⋙ G))]
    intro X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_3, u_1} D
P : MorphismProperty C
F : C ⥤ D
E : Type u_2
inst✝ : Category.{u_4, u_2} E
G : D ⥤ E
X Y : D
f : X ⟶ Y
X' Y' : C
f' : X' ⟶ Y'
hf' : P f'
e : Arrow.mk (F.map f') ≅ Arrow.mk f
⊢ map P (F ⋙ G) (G.map f)

Next tactic:
exact ⟨X', Y', f', hf', ⟨G.mapArrow.mapIso e⟩⟩
@[simp]
lemma map_map (P : MorphismProperty C) (F : C ⥤ D) {E : Type*} [Category E] (G : D ⥤ E) :
    (P.map F).map G = P.map (F ⋙ G) := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (map_respectsIso _ (F ⋙ G))]
    intro X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    exact ⟨X', Y', f', hf', ⟨G.mapArrow.mapIso e⟩⟩
  · 

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_3, u_1} D
P : MorphismProperty C
F : C ⥤ D
E : Type u_2
inst✝ : Category.{u_4, u_2} E
G : D ⥤ E
⊢ map P (F ⋙ G) ⊆ map (map P F) G

Next tactic:
rw [map_subset_iff _ _ _ (map_respectsIso _ G)]
@[simp]
lemma map_map (P : MorphismProperty C) (F : C ⥤ D) {E : Type*} [Category E] (G : D ⥤ E) :
    (P.map F).map G = P.map (F ⋙ G) := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (map_respectsIso _ (F ⋙ G))]
    intro X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    exact ⟨X', Y', f', hf', ⟨G.mapArrow.mapIso e⟩⟩
  · rw [map_subset_iff _ _ _ (map_respectsIso _ G)]
    

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_3, u_1} D
P : MorphismProperty C
F : C ⥤ D
E : Type u_2
inst✝ : Category.{u_4, u_2} E
G : D ⥤ E
⊢ ∀ (X Y : C) (f : X ⟶ Y), P f → map (map P F) G ((F ⋙ G).map f)

Next tactic:
intro X Y f hf
@[simp]
lemma map_map (P : MorphismProperty C) (F : C ⥤ D) {E : Type*} [Category E] (G : D ⥤ E) :
    (P.map F).map G = P.map (F ⋙ G) := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (map_respectsIso _ (F ⋙ G))]
    intro X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    exact ⟨X', Y', f', hf', ⟨G.mapArrow.mapIso e⟩⟩
  · rw [map_subset_iff _ _ _ (map_respectsIso _ G)]
    intro X Y f hf
    

Proof state:
case a
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_3, u_1} D
P : MorphismProperty C
F : C ⥤ D
E : Type u_2
inst✝ : Category.{u_4, u_2} E
G : D ⥤ E
X Y : C
f : X ⟶ Y
hf : P f
⊢ map (map P F) G ((F ⋙ G).map f)

Next tactic:
exact map_mem_map _ _ _ (map_mem_map _ _ _ hf)
lemma IsInvertedBy.map_iff {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (G : C₂ ⥤ C₃) :
    (W.map F).IsInvertedBy G ↔ W.IsInvertedBy (F ⋙ G) := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
D : Type u_1
inst✝³ : Category.{?u.104927, 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₂
G : C₂ ⥤ C₃
⊢ IsInvertedBy (map W F) G ↔ IsInvertedBy W (F ⋙ G)

Next tactic:
simp only [IsInvertedBy.iff_map_subset_isomorphisms, map_map]
lemma map_eq_of_iso (P : MorphismProperty C) {F G : C ⥤ D} (e : F ≅ G) :
    P.map F = P.map G := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
F G : C ⥤ D
e : F ≅ G
⊢ map P F = map P G

Next tactic:
revert F G e
lemma map_eq_of_iso (P : MorphismProperty C) {F G : C ⥤ D} (e : F ≅ G) :
    P.map F = P.map G := by
  revert F G e
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
⊢ ∀ {F G : C ⥤ D}, (F ≅ G) → map P F = map P G

Next tactic:
suffices ∀ {F G : C ⥤ D} (_ : F ≅ G), P.map F ⊆ P.map G from
    fun F G e => le_antisymm (this e) (this e.symm)
lemma map_eq_of_iso (P : MorphismProperty C) {F G : C ⥤ D} (e : F ≅ G) :
    P.map F = P.map G := by
  revert F G e
  suffices ∀ {F G : C ⥤ D} (_ : F ≅ G), P.map F ⊆ P.map G from
    fun F G e => le_antisymm (this e) (this e.symm)
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
⊢ ∀ {F G : C ⥤ D}, (F ≅ G) → map P F ⊆ map P G

Next tactic:
intro F G e X Y f ⟨X', Y', f', hf', ⟨e'⟩⟩
lemma map_eq_of_iso (P : MorphismProperty C) {F G : C ⥤ D} (e : F ≅ G) :
    P.map F = P.map G := by
  revert F G e
  suffices ∀ {F G : C ⥤ D} (_ : F ≅ G), P.map F ⊆ P.map G from
    fun F G e => le_antisymm (this e) (this e.symm)
  intro F G e X Y f ⟨X', Y', f', hf', ⟨e'⟩⟩
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
F G : C ⥤ D
e : F ≅ G
X Y : D
f : X ⟶ Y
X' Y' : C
f' : X' ⟶ Y'
hf' : P f'
e' : Arrow.mk (F.map f') ≅ Arrow.mk f
⊢ map P G f

Next tactic:
exact ⟨X', Y', f', hf', ⟨((Functor.mapArrowFunctor _ _).mapIso e.symm).app (Arrow.mk f') ≪≫ e'⟩⟩
lemma inverseImage_equivalence_inverse_eq_map_functor
    (P : MorphismProperty D) (hP : RespectsIso P) (E : C ≌ D) :
    P.inverseImage E.functor = P.map E.inverse := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
E : C ≌ D
⊢ inverseImage P E.functor = map P E.inverse

Next tactic:
apply subset_antisymm
lemma inverseImage_equivalence_inverse_eq_map_functor
    (P : MorphismProperty D) (hP : RespectsIso P) (E : C ≌ D) :
    P.inverseImage E.functor = P.map E.inverse := by
  apply subset_antisymm
  · 

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
E : C ≌ D
⊢ inverseImage P E.functor ⊆ map P E.inverse

Next tactic:
intro X Y f hf
lemma inverseImage_equivalence_inverse_eq_map_functor
    (P : MorphismProperty D) (hP : RespectsIso P) (E : C ≌ D) :
    P.inverseImage E.functor = P.map E.inverse := by
  apply subset_antisymm
  · intro X Y f hf
    

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
E : C ≌ D
X Y : C
f : X ⟶ Y
hf : inverseImage P E.functor f
⊢ map P E.inverse f

Next tactic:
refine' ⟨_, _, _, hf, ⟨_⟩⟩
lemma inverseImage_equivalence_inverse_eq_map_functor
    (P : MorphismProperty D) (hP : RespectsIso P) (E : C ≌ D) :
    P.inverseImage E.functor = P.map E.inverse := by
  apply subset_antisymm
  · intro X Y f hf
    refine' ⟨_, _, _, hf, ⟨_⟩⟩
    

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
E : C ≌ D
X Y : C
f : X ⟶ Y
hf : inverseImage P E.functor f
⊢ Arrow.mk (E.inverse.map (E.functor.map f)) ≅ Arrow.mk f

Next tactic:
exact ((Functor.mapArrowFunctor _ _).mapIso E.unitIso.symm).app (Arrow.mk f)
lemma inverseImage_equivalence_inverse_eq_map_functor
    (P : MorphismProperty D) (hP : RespectsIso P) (E : C ≌ D) :
    P.inverseImage E.functor = P.map E.inverse := by
  apply subset_antisymm
  · intro X Y f hf
    refine' ⟨_, _, _, hf, ⟨_⟩⟩
    exact ((Functor.mapArrowFunctor _ _).mapIso E.unitIso.symm).app (Arrow.mk f)
  · 

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
E : C ≌ D
⊢ map P E.inverse ⊆ inverseImage P E.functor

Next tactic:
rw [map_subset_iff _ _ _ (hP.inverseImage E.functor)]
lemma inverseImage_equivalence_inverse_eq_map_functor
    (P : MorphismProperty D) (hP : RespectsIso P) (E : C ≌ D) :
    P.inverseImage E.functor = P.map E.inverse := by
  apply subset_antisymm
  · intro X Y f hf
    refine' ⟨_, _, _, hf, ⟨_⟩⟩
    exact ((Functor.mapArrowFunctor _ _).mapIso E.unitIso.symm).app (Arrow.mk f)
  · rw [map_subset_iff _ _ _ (hP.inverseImage E.functor)]
    

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
E : C ≌ D
⊢ ∀ (X Y : D) (f : X ⟶ Y), P f → inverseImage P E.functor (E.inverse.map f)

Next tactic:
intro X Y f hf
lemma inverseImage_equivalence_inverse_eq_map_functor
    (P : MorphismProperty D) (hP : RespectsIso P) (E : C ≌ D) :
    P.inverseImage E.functor = P.map E.inverse := by
  apply subset_antisymm
  · intro X Y f hf
    refine' ⟨_, _, _, hf, ⟨_⟩⟩
    exact ((Functor.mapArrowFunctor _ _).mapIso E.unitIso.symm).app (Arrow.mk f)
  · rw [map_subset_iff _ _ _ (hP.inverseImage E.functor)]
    intro X Y f hf
    

Proof state:
case a
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
E : C ≌ D
X Y : D
f : X ⟶ Y
hf : P f
⊢ inverseImage P E.functor (E.inverse.map f)

Next tactic:
exact (hP.arrow_mk_iso_iff
      (((Functor.mapArrowFunctor _ _).mapIso E.counitIso).app (Arrow.mk f))).2 hf
lemma map_inverseImage_eq_of_isEquivalence
    (P : MorphismProperty D) (hP : P.RespectsIso) (F : C ⥤ D) [IsEquivalence F] :
    (P.inverseImage F).map F = P := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_2, u_1} D
P : MorphismProperty D
hP : RespectsIso P
F : C ⥤ D
inst✝ : IsEquivalence F
⊢ map (inverseImage P F) F = P

Next tactic:
erw [P.inverseImage_equivalence_inverse_eq_map_functor hP F.asEquivalence, map_map,
    P.map_eq_of_iso F.asEquivalence.counitIso, map_id _ hP]
lemma inverseImage_map_eq_of_isEquivalence
    (P : MorphismProperty C) (hP : P.RespectsIso) (F : C ⥤ D) [IsEquivalence F] :
    (P.map F).inverseImage F = P := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{u_2, u_1} D
P : MorphismProperty C
hP : RespectsIso P
F : C ⥤ D
inst✝ : IsEquivalence F
⊢ inverseImage (map P F) F = P

Next tactic:
erw [((P.map F).inverseImage_equivalence_inverse_eq_map_functor
    (P.map_respectsIso F) (F.asEquivalence)), map_map,
    P.map_eq_of_iso F.asEquivalence.unitIso.symm, map_id _ hP]
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
⊢ RespectsIso (MorphismProperty.diagonal P)

Next tactic:
constructor
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  constructor
  · 

Proof state:
case left
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
⊢ ∀ {X Y Z : C} (e : X ≅ Y) (f : Y ⟶ Z), MorphismProperty.diagonal P f → MorphismProperty.diagonal P (e.hom ≫ f)

Next tactic:
introv H
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  constructor
  · introv H
    

Proof state:
case left
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
X Y Z : C
e : X ≅ Y
f : Y ⟶ Z
H : MorphismProperty.diagonal P f
⊢ MorphismProperty.diagonal P (e.hom ≫ f)

Next tactic:
rwa [diagonal_iff, pullback.diagonal_comp, hP.cancel_left_isIso, hP.cancel_left_isIso,
      ← hP.cancel_right_isIso _
        (pullback.map (e.hom ≫ f) (e.hom ≫ f) f f e.hom e.hom (𝟙 Z) (by simp) (by simp)),
      ← pullback.condition, hP.cancel_left_isIso]
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  constructor
  · introv H
    rwa [diagonal_iff, pullback.diagonal_comp, hP.cancel_left_isIso, hP.cancel_left_isIso,
      ← hP.cancel_right_isIso _
        (pullback.map (e.hom ≫ f) (e.hom ≫ f) f f e.hom e.hom (𝟙 Z) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
X Y Z : C
e : X ≅ Y
f : Y ⟶ Z
H : MorphismProperty.diagonal P f
⊢ (e.hom ≫ f) ≫ 𝟙 Z = e.hom ≫ f

Next tactic:
simp
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  constructor
  · introv H
    rwa [diagonal_iff, pullback.diagonal_comp, hP.cancel_left_isIso, hP.cancel_left_isIso,
      ← hP.cancel_right_isIso _
        (pullback.map (e.hom ≫ f) (e.hom ≫ f) f f e.hom e.hom (𝟙 Z) (by simp) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
X Y Z : C
e : X ≅ Y
f : Y ⟶ Z
H : MorphismProperty.diagonal P f
⊢ (e.hom ≫ f) ≫ 𝟙 Z = e.hom ≫ f

Next tactic:
simp
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  constructor
  · introv H
    rwa [diagonal_iff, pullback.diagonal_comp, hP.cancel_left_isIso, hP.cancel_left_isIso,
      ← hP.cancel_right_isIso _
        (pullback.map (e.hom ≫ f) (e.hom ≫ f) f f e.hom e.hom (𝟙 Z) (by simp) (by simp)),
      ← pullback.condition, hP.cancel_left_isIso]
  · 

Proof state:
case right
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
⊢ ∀ {X Y Z : C} (e : Y ≅ Z) (f : X ⟶ Y), MorphismProperty.diagonal P f → MorphismProperty.diagonal P (f ≫ e.hom)

Next tactic:
introv H
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  constructor
  · introv H
    rwa [diagonal_iff, pullback.diagonal_comp, hP.cancel_left_isIso, hP.cancel_left_isIso,
      ← hP.cancel_right_isIso _
        (pullback.map (e.hom ≫ f) (e.hom ≫ f) f f e.hom e.hom (𝟙 Z) (by simp) (by simp)),
      ← pullback.condition, hP.cancel_left_isIso]
  · introv H
    

Proof state:
case right
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
X Y Z : C
e : Y ≅ Z
f : X ⟶ Y
H : MorphismProperty.diagonal P f
⊢ MorphismProperty.diagonal P (f ≫ e.hom)

Next tactic:
delta diagonal
theorem RespectsIso.diagonal (hP : P.RespectsIso) : P.diagonal.RespectsIso := by
  constructor
  · introv H
    rwa [diagonal_iff, pullback.diagonal_comp, hP.cancel_left_isIso, hP.cancel_left_isIso,
      ← hP.cancel_right_isIso _
        (pullback.map (e.hom ≫ f) (e.hom ≫ f) f f e.hom e.hom (𝟙 Z) (by simp) (by simp)),
      ← pullback.condition, hP.cancel_left_isIso]
  · introv H
    delta diagonal
    

Proof state:
case right
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.115605, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : RespectsIso P
X Y Z : C
e : Y ≅ Z
f : X ⟶ Y
H : MorphismProperty.diagonal P f
⊢ P (pullback.diagonal (f ≫ e.hom))

Next tactic:
rwa [pullback.diagonal_comp, hP.cancel_right_isIso]
theorem StableUnderComposition.diagonal (hP : StableUnderComposition P) (hP' : RespectsIso P)
    (hP'' : StableUnderBaseChange P) : P.diagonal.StableUnderComposition := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.126984, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
hP' : RespectsIso P
hP'' : StableUnderBaseChange P
⊢ StableUnderComposition (MorphismProperty.diagonal P)

Next tactic:
introv X h₁ h₂
theorem StableUnderComposition.diagonal (hP : StableUnderComposition P) (hP' : RespectsIso P)
    (hP'' : StableUnderBaseChange P) : P.diagonal.StableUnderComposition := by
  introv X h₁ h₂
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.126984, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
hP' : RespectsIso P
hP'' : StableUnderBaseChange P
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h₁ : MorphismProperty.diagonal P f
h₂ : MorphismProperty.diagonal P g
⊢ MorphismProperty.diagonal P (f ≫ g)

Next tactic:
rw [diagonal_iff, pullback.diagonal_comp]
theorem StableUnderComposition.diagonal (hP : StableUnderComposition P) (hP' : RespectsIso P)
    (hP'' : StableUnderBaseChange P) : P.diagonal.StableUnderComposition := by
  introv X h₁ h₂
  rw [diagonal_iff, pullback.diagonal_comp]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.126984, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
hP' : RespectsIso P
hP'' : StableUnderBaseChange P
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h₁ : MorphismProperty.diagonal P f
h₂ : MorphismProperty.diagonal P g
⊢ P (pullback.diagonal f ≫ (pullbackDiagonalMapIdIso f f g).inv ≫ pullback.snd)

Next tactic:
exact hP _ _ h₁ (by simpa [hP'.cancel_left_isIso] using hP''.snd _ _ h₂)
theorem StableUnderComposition.diagonal (hP : StableUnderComposition P) (hP' : RespectsIso P)
    (hP'' : StableUnderBaseChange P) : P.diagonal.StableUnderComposition := by
  introv X h₁ h₂
  rw [diagonal_iff, pullback.diagonal_comp]
  exact hP _ _ h₁ (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.126984, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
hP' : RespectsIso P
hP'' : StableUnderBaseChange P
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
h₁ : MorphismProperty.diagonal P f
h₂ : MorphismProperty.diagonal P g
⊢ P ((pullbackDiagonalMapIdIso f f g).inv ≫ pullback.snd)

Next tactic:
simpa [hP'.cancel_left_isIso] using hP''.snd _ _ h₂
theorem StableUnderBaseChange.diagonal (hP : StableUnderBaseChange P) (hP' : RespectsIso P) :
    P.diagonal.StableUnderBaseChange :=
  StableUnderBaseChange.mk hP'.diagonal
    (by
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.131675, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : RespectsIso P
⊢ ∀ (X Y S : C) (f : X ⟶ S) (g : Y ⟶ S), MorphismProperty.diagonal P g → MorphismProperty.diagonal P pullback.fst

Next tactic:
introv h
theorem StableUnderBaseChange.diagonal (hP : StableUnderBaseChange P) (hP' : RespectsIso P) :
    P.diagonal.StableUnderBaseChange :=
  StableUnderBaseChange.mk hP'.diagonal
    (by
      introv h
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.131675, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : RespectsIso P
X Y S : C
f : X ⟶ S
g : Y ⟶ S
h : MorphismProperty.diagonal P g
⊢ MorphismProperty.diagonal P pullback.fst

Next tactic:
rw [diagonal_iff, diagonal_pullback_fst, hP'.cancel_left_isIso, hP'.cancel_right_isIso]
theorem StableUnderBaseChange.diagonal (hP : StableUnderBaseChange P) (hP' : RespectsIso P) :
    P.diagonal.StableUnderBaseChange :=
  StableUnderBaseChange.mk hP'.diagonal
    (by
      introv h
      rw [diagonal_iff, diagonal_pullback_fst, hP'.cancel_left_isIso, hP'.cancel_right_isIso]
      

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.131675, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : RespectsIso P
X Y S : C
f : X ⟶ S
g : Y ⟶ S
h : MorphismProperty.diagonal P g
⊢ P ((baseChange f).map (Over.homMk (pullback.diagonal g))).left

Next tactic:
exact hP.baseChange_map f _ (by simpa)
theorem StableUnderBaseChange.diagonal (hP : StableUnderBaseChange P) (hP' : RespectsIso P) :
    P.diagonal.StableUnderBaseChange :=
  StableUnderBaseChange.mk hP'.diagonal
    (by
      introv h
      rw [diagonal_iff, diagonal_pullback_fst, hP'.cancel_left_isIso, hP'.cancel_right_isIso]
      exact hP.baseChange_map f _ (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.131675, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderBaseChange P
hP' : RespectsIso P
X Y S : C
f : X ⟶ S
g : Y ⟶ S
h : MorphismProperty.diagonal P g
⊢ P (Over.homMk (pullback.diagonal g)).left

Next tactic:
simpa
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.133755, u_1} D
P : MorphismProperty C
⊢ RespectsIso (universally P)

Next tactic:
constructor
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · 

Proof state:
case left
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.133755, u_1} D
P : MorphismProperty C
⊢ ∀ {X Y Z : C} (e : X ≅ Y) (f : Y ⟶ Z), universally P f → universally P (e.hom ≫ f)

Next tactic:
intro X Y Z e f hf X' Z' i₁ i₂ f' H