l3lab/ntp-mathlib huggingface dataset:
theorem StableUnderComposition.epimorphisms : StableUnderComposition (epimorphisms C) :=
  fun X Y Z f g hf hg => by
  rw [epimorphisms.iff] at hf hg ⊢
  haveI := hf
  haveI := hg
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.90118, u_1} D
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : Epi f
hg : Epi g
this✝ : Epi f
this : Epi g
⊢ Epi (f ≫ g)

Next tactic:
apply epi_comp
@[ext]
lemma FunctorsInverting.ext {W : MorphismProperty C} {F₁ F₂ : FunctorsInverting W D}
    (h : F₁.obj = F₂.obj) : F₁ = F₂ := 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
F₁ F₂ : FunctorsInverting W D
h : F₁.obj = F₂.obj
⊢ F₁ = F₂

Next tactic:
cases F₁
@[ext]
lemma FunctorsInverting.ext {W : MorphismProperty C} {F₁ F₂ : FunctorsInverting W D}
    (h : F₁.obj = F₂.obj) : F₁ = F₂ := by
  cases F₁
  

Proof state:
case mk
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F₂ : FunctorsInverting W D
obj✝ : C ⥤ D
property✝ : IsInvertedBy W obj✝
h : { obj := obj✝, property := property✝ }.obj = F₂.obj
⊢ { obj := obj✝, property := property✝ } = F₂

Next tactic:
cases F₂
@[ext]
lemma FunctorsInverting.ext {W : MorphismProperty C} {F₁ F₂ : FunctorsInverting W D}
    (h : F₁.obj = F₂.obj) : F₁ = F₂ := by
  cases F₁
  cases F₂
  

Proof state:
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
obj✝¹ : C ⥤ D
property✝¹ : IsInvertedBy W obj✝¹
obj✝ : C ⥤ D
property✝ : IsInvertedBy W obj✝
h : { obj := obj✝¹, property := property✝¹ }.obj = { obj := obj✝, property := property✝ }.obj
⊢ { obj := obj✝¹, property := property✝¹ } = { obj := obj✝, property := property✝ }

Next tactic:
subst h
@[ext]
lemma FunctorsInverting.ext {W : MorphismProperty C} {F₁ F₂ : FunctorsInverting W D}
    (h : F₁.obj = F₂.obj) : F₁ = F₂ := by
  cases F₁
  cases F₂
  subst h
  

Proof state:
case mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
obj✝ : C ⥤ D
property✝¹ : IsInvertedBy W obj✝
property✝ : IsInvertedBy W { obj := obj✝, property := property✝¹ }.obj
⊢ { obj := obj✝, property := property✝¹ } =
    { obj := { obj := obj✝, property := property✝¹ }.obj, property := property✝ }

Next tactic:
rfl
theorem IsInvertedBy.iff_of_iso (W : MorphismProperty C) {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) :
    W.IsInvertedBy F₁ ↔ W.IsInvertedBy F₂ := 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
F₁ F₂ : C ⥤ D
e : F₁ ≅ F₂
⊢ IsInvertedBy W F₁ ↔ IsInvertedBy W F₂

Next tactic:
dsimp [IsInvertedBy]
theorem IsInvertedBy.iff_of_iso (W : MorphismProperty C) {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) :
    W.IsInvertedBy F₁ ↔ W.IsInvertedBy F₂ := by
  dsimp [IsInvertedBy]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F₁ F₂ : C ⥤ D
e : F₁ ≅ F₂
⊢ (∀ ⦃X Y : C⦄ (f : X ⟶ Y), W f → IsIso (F₁.map f)) ↔ ∀ ⦃X Y : C⦄ (f : X ⟶ Y), W f → IsIso (F₂.map f)

Next tactic:
simp only [NatIso.isIso_map_iff e]
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := 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
F : C ⥤ D
⊢ IsInvertedBy (isoClosure W) F ↔ IsInvertedBy W F

Next tactic:
constructor
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
⊢ IsInvertedBy (isoClosure W) F → IsInvertedBy W F

Next tactic:
intro h X Y f hf
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    

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

Next tactic:
exact h _ (W.subset_isoClosure _ hf)
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    exact h _ (W.subset_isoClosure _ hf)
  · 

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
⊢ IsInvertedBy W F → IsInvertedBy (isoClosure W) F

Next tactic:
intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    exact h _ (W.subset_isoClosure _ hf)
  · intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    

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

Next tactic:
have : f = e.inv.left ≫ f' ≫ e.hom.right := by
      erw [← e.hom.w, ← Arrow.comp_left_assoc, e.inv_hom_id, Category.id_comp]
      rfl
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    exact h _ (W.subset_isoClosure _ hf)
  · intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    have : f = e.inv.left ≫ f' ≫ e.hom.right := 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
F : C ⥤ D
h : IsInvertedBy W F
X Y : C
f : X ⟶ Y
X' Y' : C
f' : X' ⟶ Y'
hf' : W f'
e : Arrow.mk f' ≅ Arrow.mk f
⊢ f = e.inv.left ≫ f' ≫ e.hom.right

Next tactic:
erw [← e.hom.w, ← Arrow.comp_left_assoc, e.inv_hom_id, Category.id_comp]
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    exact h _ (W.subset_isoClosure _ hf)
  · intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    have : f = e.inv.left ≫ f' ≫ e.hom.right := by
      erw [← e.hom.w, ← Arrow.comp_left_assoc, e.inv_hom_id, Category.id_comp]
      

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

Next tactic:
rfl
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    exact h _ (W.subset_isoClosure _ hf)
  · intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    have : f = e.inv.left ≫ f' ≫ e.hom.right := by
      erw [← e.hom.w, ← Arrow.comp_left_assoc, e.inv_hom_id, Category.id_comp]
      rfl
    

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
h : IsInvertedBy W F
X Y : C
f : X ⟶ Y
X' Y' : C
f' : X' ⟶ Y'
hf' : W f'
e : Arrow.mk f' ≅ Arrow.mk f
this : f = e.inv.left ≫ f' ≫ e.hom.right
⊢ IsIso (F.map f)

Next tactic:
simp only [this, F.map_comp]
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    exact h _ (W.subset_isoClosure _ hf)
  · intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    have : f = e.inv.left ≫ f' ≫ e.hom.right := by
      erw [← e.hom.w, ← Arrow.comp_left_assoc, e.inv_hom_id, Category.id_comp]
      rfl
    simp only [this, F.map_comp]
    

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
h : IsInvertedBy W F
X Y : C
f : X ⟶ Y
X' Y' : C
f' : X' ⟶ Y'
hf' : W f'
e : Arrow.mk f' ≅ Arrow.mk f
this : f = e.inv.left ≫ f' ≫ e.hom.right
⊢ IsIso (F.map e.inv.left ≫ F.map f' ≫ F.map e.hom.right)

Next tactic:
have := h _ hf'
@[simp]
lemma IsInvertedBy.isoClosure_iff (W : MorphismProperty C) (F : C ⥤ D) :
    W.isoClosure.IsInvertedBy F ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    exact h _ (W.subset_isoClosure _ hf)
  · intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    have : f = e.inv.left ≫ f' ≫ e.hom.right := by
      erw [← e.hom.w, ← Arrow.comp_left_assoc, e.inv_hom_id, Category.id_comp]
      rfl
    simp only [this, F.map_comp]
    have := h _ hf'
    

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
h : IsInvertedBy W F
X Y : C
f : X ⟶ Y
X' Y' : C
f' : X' ⟶ Y'
hf' : W f'
e : Arrow.mk f' ≅ Arrow.mk f
this✝ : f = e.inv.left ≫ f' ≫ e.hom.right
this : IsIso (F.map f')
⊢ IsIso (F.map e.inv.left ≫ F.map f' ≫ F.map e.hom.right)

Next tactic:
infer_instance
@[simp]
lemma IsInvertedBy.iff_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (G : C₂ ⥤ C₃) [ReflectsIsomorphisms G] :
    W.IsInvertedBy (F ⋙ G) ↔ W.IsInvertedBy F := by
  

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

Next tactic:
constructor
@[simp]
lemma IsInvertedBy.iff_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (G : C₂ ⥤ C₃) [ReflectsIsomorphisms G] :
    W.IsInvertedBy (F ⋙ G) ↔ W.IsInvertedBy F := by
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{?u.95478, 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₃
inst✝ : ReflectsIsomorphisms G
⊢ IsInvertedBy W (F ⋙ G) → IsInvertedBy W F

Next tactic:
intro h X Y f hf
@[simp]
lemma IsInvertedBy.iff_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (G : C₂ ⥤ C₃) [ReflectsIsomorphisms G] :
    W.IsInvertedBy (F ⋙ G) ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    

Proof state:
case mp
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{?u.95478, 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₃
inst✝ : ReflectsIsomorphisms G
h : IsInvertedBy W (F ⋙ G)
X Y : C₁
f : X ⟶ Y
hf : W f
⊢ IsIso (F.map f)

Next tactic:
have : IsIso (G.map (F.map f)) := h _ hf
@[simp]
lemma IsInvertedBy.iff_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (G : C₂ ⥤ C₃) [ReflectsIsomorphisms G] :
    W.IsInvertedBy (F ⋙ G) ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    have : IsIso (G.map (F.map f)) := h _ hf
    

Proof state:
case mp
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{?u.95478, 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₃
inst✝ : ReflectsIsomorphisms G
h : IsInvertedBy W (F ⋙ G)
X Y : C₁
f : X ⟶ Y
hf : W f
this : IsIso (G.map (F.map f))
⊢ IsIso (F.map f)

Next tactic:
exact isIso_of_reflects_iso (F.map f) G
@[simp]
lemma IsInvertedBy.iff_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (G : C₂ ⥤ C₃) [ReflectsIsomorphisms G] :
    W.IsInvertedBy (F ⋙ G) ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    have : IsIso (G.map (F.map f)) := h _ hf
    exact isIso_of_reflects_iso (F.map f) G
  · 

Proof state:
case mpr
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{?u.95478, 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₃
inst✝ : ReflectsIsomorphisms G
⊢ IsInvertedBy W F → IsInvertedBy W (F ⋙ G)

Next tactic:
intro hF
@[simp]
lemma IsInvertedBy.iff_comp {C₁ C₂ C₃ : Type*} [Category C₁] [Category C₂] [Category C₃]
    (W : MorphismProperty C₁) (F : C₁ ⥤ C₂) (G : C₂ ⥤ C₃) [ReflectsIsomorphisms G] :
    W.IsInvertedBy (F ⋙ G) ↔ W.IsInvertedBy F := by
  constructor
  · intro h X Y f hf
    have : IsIso (G.map (F.map f)) := h _ hf
    exact isIso_of_reflects_iso (F.map f) G
  · intro hF
    

Proof state:
case mpr
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{?u.95478, 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₃
inst✝ : ReflectsIsomorphisms G
hF : IsInvertedBy W F
⊢ IsInvertedBy W (F ⋙ G)

Next tactic:
exact IsInvertedBy.of_comp W F hF G
lemma isoClosure_subset_iff (P Q : MorphismProperty C) (hQ : RespectsIso Q) :
    P.isoClosure ⊆ Q ↔ P ⊆ Q := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.97011, u_1} D
P Q : MorphismProperty C
hQ : RespectsIso Q
⊢ isoClosure P ⊆ Q ↔ P ⊆ Q

Next tactic:
constructor
lemma isoClosure_subset_iff (P Q : MorphismProperty C) (hQ : RespectsIso Q) :
    P.isoClosure ⊆ Q ↔ P ⊆ Q := by
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.97011, u_1} D
P Q : MorphismProperty C
hQ : RespectsIso Q
⊢ isoClosure P ⊆ Q → P ⊆ Q

Next tactic:
exact P.subset_isoClosure.trans
lemma isoClosure_subset_iff (P Q : MorphismProperty C) (hQ : RespectsIso Q) :
    P.isoClosure ⊆ Q ↔ P ⊆ Q := by
  constructor
  · exact P.subset_isoClosure.trans
  · 

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.97011, u_1} D
P Q : MorphismProperty C
hQ : RespectsIso Q
⊢ P ⊆ Q → isoClosure P ⊆ Q

Next tactic:
intro h
lemma isoClosure_subset_iff (P Q : MorphismProperty C) (hQ : RespectsIso Q) :
    P.isoClosure ⊆ Q ↔ P ⊆ Q := by
  constructor
  · exact P.subset_isoClosure.trans
  · intro h
    

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.97011, u_1} D
P Q : MorphismProperty C
hQ : RespectsIso Q
h : P ⊆ Q
⊢ isoClosure P ⊆ Q

Next tactic:
exact (monotone_isoClosure _ _ h).trans (by rw [hQ.isoClosure_eq])
lemma isoClosure_subset_iff (P Q : MorphismProperty C) (hQ : RespectsIso Q) :
    P.isoClosure ⊆ Q ↔ P ⊆ Q := by
  constructor
  · exact P.subset_isoClosure.trans
  · intro h
    exact (monotone_isoClosure _ _ h).trans (by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.97011, u_1} D
P Q : MorphismProperty C
hQ : RespectsIso Q
h : P ⊆ Q
⊢ isoClosure Q ⊆ Q

Next tactic:
rw [hQ.isoClosure_eq]
lemma map_respectsIso (P : MorphismProperty C) (F : C ⥤ D) :
    (P.map F).RespectsIso := 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 : C ⥤ D
⊢ RespectsIso (map P F)

Next tactic:
apply RespectsIso.of_respects_arrow_iso
lemma map_respectsIso (P : MorphismProperty C) (F : C ⥤ D) :
    (P.map F).RespectsIso := by
  apply RespectsIso.of_respects_arrow_iso
  

Proof state:
case hP
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
F : C ⥤ D
⊢ ∀ (f g : Arrow D), (f ≅ g) → map P F f.hom → map P F g.hom

Next tactic:
intro f g e ⟨X', Y', f', hf', ⟨e'⟩⟩
lemma map_respectsIso (P : MorphismProperty C) (F : C ⥤ D) :
    (P.map F).RespectsIso := by
  apply RespectsIso.of_respects_arrow_iso
  intro f g e ⟨X', Y', f', hf', ⟨e'⟩⟩
  

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

Next tactic:
exact ⟨X', Y', f', hf', ⟨e' ≪≫ e⟩⟩
lemma map_subset_iff (P : MorphismProperty C) (F : C ⥤ D)
    (Q : MorphismProperty D) (hQ : RespectsIso Q):
    P.map F ⊆ Q ↔ ∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f) := 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 : C ⥤ D
Q : MorphismProperty D
hQ : RespectsIso Q
⊢ map P F ⊆ Q ↔ ∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f)

Next tactic:
constructor
lemma map_subset_iff (P : MorphismProperty C) (F : C ⥤ D)
    (Q : MorphismProperty D) (hQ : RespectsIso Q):
    P.map F ⊆ Q ↔ ∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f) := by
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
F : C ⥤ D
Q : MorphismProperty D
hQ : RespectsIso Q
⊢ map P F ⊆ Q → ∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f)

Next tactic:
intro h X Y f hf
lemma map_subset_iff (P : MorphismProperty C) (F : C ⥤ D)
    (Q : MorphismProperty D) (hQ : RespectsIso Q):
    P.map F ⊆ Q ↔ ∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f) := by
  constructor
  · intro h X Y f hf
    

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
F : C ⥤ D
Q : MorphismProperty D
hQ : RespectsIso Q
h : map P F ⊆ Q
X Y : C
f : X ⟶ Y
hf : P f
⊢ Q (F.map f)

Next tactic:
exact h (F.map f) (map_mem_map P F f hf)
lemma map_subset_iff (P : MorphismProperty C) (F : C ⥤ D)
    (Q : MorphismProperty D) (hQ : RespectsIso Q):
    P.map F ⊆ Q ↔ ∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f) := by
  constructor
  · intro h X Y f hf
    exact h (F.map f) (map_mem_map P F f hf)
  · 

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
P : MorphismProperty C
F : C ⥤ D
Q : MorphismProperty D
hQ : RespectsIso Q
⊢ (∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f)) → map P F ⊆ Q

Next tactic:
intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
lemma map_subset_iff (P : MorphismProperty C) (F : C ⥤ D)
    (Q : MorphismProperty D) (hQ : RespectsIso Q):
    P.map F ⊆ Q ↔ ∀ (X Y : C) (f : X ⟶ Y), P f → Q (F.map f) := by
  constructor
  · intro h X Y f hf
    exact h (F.map f) (map_mem_map P F f hf)
  · intro h X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    

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

Next tactic:
exact (hQ.arrow_mk_iso_iff e).1 (h _ _ _ hf')
lemma IsInvertedBy.iff_map_subset_isomorphisms (W : MorphismProperty C) (F : C ⥤ D) :
    W.IsInvertedBy F ↔ W.map F ⊆ isomorphisms D := 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
F : C ⥤ D
⊢ IsInvertedBy W F ↔ map W F ⊆ isomorphisms D

Next tactic:
rw [map_subset_iff _ _ _ (RespectsIso.isomorphisms D)]
lemma IsInvertedBy.iff_map_subset_isomorphisms (W : MorphismProperty C) (F : C ⥤ D) :
    W.IsInvertedBy F ↔ W.map F ⊆ isomorphisms D := by
  rw [map_subset_iff _ _ _ (RespectsIso.isomorphisms D)]
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
⊢ IsInvertedBy W F ↔ ∀ (X Y : C) (f : X ⟶ Y), W f → isomorphisms D (F.map f)

Next tactic:
constructor
lemma IsInvertedBy.iff_map_subset_isomorphisms (W : MorphismProperty C) (F : C ⥤ D) :
    W.IsInvertedBy F ↔ W.map F ⊆ isomorphisms D := by
  rw [map_subset_iff _ _ _ (RespectsIso.isomorphisms D)]
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
⊢ IsInvertedBy W F → ∀ (X Y : C) (f : X ⟶ Y), W f → isomorphisms D (F.map f)

Next tactic:
intro h X Y f hf
lemma IsInvertedBy.iff_map_subset_isomorphisms (W : MorphismProperty C) (F : C ⥤ D) :
    W.IsInvertedBy F ↔ W.map F ⊆ isomorphisms D := by
  rw [map_subset_iff _ _ _ (RespectsIso.isomorphisms D)]
  constructor
  · intro h X Y f hf
    

Proof state:
case mp
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
h : IsInvertedBy W F
X Y : C
f : X ⟶ Y
hf : W f
⊢ isomorphisms D (F.map f)

Next tactic:
exact h f hf
lemma IsInvertedBy.iff_map_subset_isomorphisms (W : MorphismProperty C) (F : C ⥤ D) :
    W.IsInvertedBy F ↔ W.map F ⊆ isomorphisms D := by
  rw [map_subset_iff _ _ _ (RespectsIso.isomorphisms D)]
  constructor
  · intro h X Y f hf
    exact h f hf
  · 

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
⊢ (∀ (X Y : C) (f : X ⟶ Y), W f → isomorphisms D (F.map f)) → IsInvertedBy W F

Next tactic:
intro h X Y f hf
lemma IsInvertedBy.iff_map_subset_isomorphisms (W : MorphismProperty C) (F : C ⥤ D) :
    W.IsInvertedBy F ↔ W.map F ⊆ isomorphisms D := by
  rw [map_subset_iff _ _ _ (RespectsIso.isomorphisms D)]
  constructor
  · intro h X Y f hf
    exact h f hf
  · intro h X Y f hf
    

Proof state:
case mpr
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{u_2, u_1} D
W : MorphismProperty C
F : C ⥤ D
h : ∀ (X Y : C) (f : X ⟶ Y), W f → isomorphisms D (F.map f)
X Y : C
f : X ⟶ Y
hf : W f
⊢ IsIso (F.map f)

Next tactic:
exact h X Y f hf
@[simp]
lemma map_isoClosure (P : MorphismProperty C) (F : C ⥤ D) :
    P.isoClosure.map F = P.map F := 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 : C ⥤ D
⊢ map (isoClosure P) F = map P F

Next tactic:
apply subset_antisymm
@[simp]
lemma map_isoClosure (P : MorphismProperty C) (F : C ⥤ D) :
    P.isoClosure.map F = P.map F := 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 C
F : C ⥤ D
⊢ map (isoClosure P) F ⊆ map P F

Next tactic:
rw [map_subset_iff _ _ _ (P.map_respectsIso F)]
@[simp]
lemma map_isoClosure (P : MorphismProperty C) (F : C ⥤ D) :
    P.isoClosure.map F = P.map F := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (P.map_respectsIso 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 C
F : C ⥤ D
⊢ ∀ (X Y : C) (f : X ⟶ Y), isoClosure P f → map P F (F.map f)

Next tactic:
intro X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
@[simp]
lemma map_isoClosure (P : MorphismProperty C) (F : C ⥤ D) :
    P.isoClosure.map F = P.map F := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (P.map_respectsIso F)]
    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_2, u_1} D
P : MorphismProperty C
F : C ⥤ D
X Y : C
f : X ⟶ Y
X' Y' : C
f' : X' ⟶ Y'
hf' : P f'
e : Arrow.mk f' ≅ Arrow.mk f
⊢ map P F (F.map f)

Next tactic:
exact ⟨_, _, f', hf', ⟨F.mapArrow.mapIso e⟩⟩
@[simp]
lemma map_isoClosure (P : MorphismProperty C) (F : C ⥤ D) :
    P.isoClosure.map F = P.map F := by
  apply subset_antisymm
  · rw [map_subset_iff _ _ _ (P.map_respectsIso F)]
    intro X Y f ⟨X', Y', f', hf', ⟨e⟩⟩
    exact ⟨_, _, f', hf', ⟨F.mapArrow.mapIso e⟩⟩
  · 

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 C
F : C ⥤ D
⊢ map P F ⊆ map (isoClosure P) F

Next tactic:
exact monotone_map _ _ _ (subset_isoClosure P)
lemma map_id_eq_isoClosure (P : MorphismProperty C) :
    P.map (𝟭 _) = P.isoClosure := by
  

Proof state:
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:
apply subset_antisymm