l3lab/ntp-mathlib huggingface dataset:
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    

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
hf : universally P f
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (e.hom ≫ f)
⊢ P f'

Next tactic:
have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨by rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]⟩
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨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
X Y Z : C
e : X ≅ Y
f : Y ⟶ Z
hf : universally P f
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (e.hom ≫ f)
⊢ 𝟙 X' ≫ i₁ = (i₁ ≫ e.hom) ≫ e.inv

Next tactic:
rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨by rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]⟩
    

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
hf : universally P f
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (e.hom ≫ f)
this : IsPullback (𝟙 X') (i₁ ≫ e.hom) i₁ e.inv
⊢ P f'

Next tactic:
exact hf _ _ _
      (by simpa only [Iso.inv_hom_id_assoc, Category.id_comp] using this.paste_horiz H)
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨by rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]⟩
    exact hf _ _ _
      (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
X Y Z : C
e : X ≅ Y
f : Y ⟶ Z
hf : universally P f
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (e.hom ≫ f)
this : IsPullback (𝟙 X') (i₁ ≫ e.hom) i₁ e.inv
⊢ IsPullback f' ?m.135996 ?m.135997 f

Next tactic:
simpa only [Iso.inv_hom_id_assoc, Category.id_comp] using this.paste_horiz H
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨by rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]⟩
    exact hf _ _ _
      (by simpa only [Iso.inv_hom_id_assoc, Category.id_comp] using this.paste_horiz H)
  · 

Proof state:
case right
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 : Y ≅ Z) (f : X ⟶ Y), universally P f → universally P (f ≫ e.hom)

Next tactic:
intro X Y Z e f hf X' Z' i₁ i₂ f' H
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨by rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]⟩
    exact hf _ _ _
      (by simpa only [Iso.inv_hom_id_assoc, Category.id_comp] using this.paste_horiz H)
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    

Proof state:
case right
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 : Y ≅ Z
f : X ⟶ Y
hf : universally P f
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (f ≫ e.hom)
⊢ P f'

Next tactic:
have : IsPullback (𝟙 _) i₂ (i₂ ≫ e.inv) e.inv :=
      IsPullback.of_horiz_isIso ⟨Category.id_comp _⟩
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨by rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]⟩
    exact hf _ _ _
      (by simpa only [Iso.inv_hom_id_assoc, Category.id_comp] using this.paste_horiz H)
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) i₂ (i₂ ≫ e.inv) e.inv :=
      IsPullback.of_horiz_isIso ⟨Category.id_comp _⟩
    

Proof state:
case right
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 : Y ≅ Z
f : X ⟶ Y
hf : universally P f
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (f ≫ e.hom)
this : IsPullback (𝟙 Z') i₂ (i₂ ≫ e.inv) e.inv
⊢ P f'

Next tactic:
exact hf _ _ _ (by simpa only [Category.assoc, Iso.hom_inv_id,
      Category.comp_id, Category.comp_id] using H.paste_horiz this)
theorem universally_respectsIso (P : MorphismProperty C) : P.universally.RespectsIso := by
  constructor
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) (i₁ ≫ e.hom) i₁ e.inv :=
      IsPullback.of_horiz_isIso
        ⟨by rw [Category.id_comp, Category.assoc, e.hom_inv_id, Category.comp_id]⟩
    exact hf _ _ _
      (by simpa only [Iso.inv_hom_id_assoc, Category.id_comp] using this.paste_horiz H)
  · intro X Y Z e f hf X' Z' i₁ i₂ f' H
    have : IsPullback (𝟙 _) i₂ (i₂ ≫ e.inv) e.inv :=
      IsPullback.of_horiz_isIso ⟨Category.id_comp _⟩
    exact hf _ _ _ (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
X Y Z : C
e : Y ≅ Z
f : X ⟶ Y
hf : universally P f
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (f ≫ e.hom)
this : IsPullback (𝟙 Z') i₂ (i₂ ≫ e.inv) e.inv
⊢ IsPullback f' ?m.137549 ?m.137550 f

Next tactic:
simpa only [Category.assoc, Iso.hom_inv_id,
      Category.comp_id, Category.comp_id] using H.paste_horiz this
theorem StableUnderComposition.universally [HasPullbacks C] {P : MorphismProperty C}
    (hP : P.StableUnderComposition) : P.universally.StableUnderComposition := by
  

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

Next tactic:
intro X Y Z f g hf hg X' Z' i₁ i₂ f' H
theorem StableUnderComposition.universally [HasPullbacks C] {P : MorphismProperty C}
    (hP : P.StableUnderComposition) : P.universally.StableUnderComposition := by
  intro X Y Z f g hf hg X' Z' i₁ i₂ f' H
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.138015, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.universally P f
hg : MorphismProperty.universally P g
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (f ≫ g)
⊢ P f'

Next tactic:
have := pullback.lift_fst _ _ (H.w.trans (Category.assoc _ _ _).symm)
theorem StableUnderComposition.universally [HasPullbacks C] {P : MorphismProperty C}
    (hP : P.StableUnderComposition) : P.universally.StableUnderComposition := by
  intro X Y Z f g hf hg X' Z' i₁ i₂ f' H
  have := pullback.lift_fst _ _ (H.w.trans (Category.assoc _ _ _).symm)
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.138015, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.universally P f
hg : MorphismProperty.universally P g
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H : IsPullback f' i₁ i₂ (f ≫ g)
this : pullback.lift f' (i₁ ≫ f) (_ : f' ≫ i₂ = (i₁ ≫ f) ≫ g) ≫ pullback.fst = f'
⊢ P f'

Next tactic:
rw [← this] at H ⊢
theorem StableUnderComposition.universally [HasPullbacks C] {P : MorphismProperty C}
    (hP : P.StableUnderComposition) : P.universally.StableUnderComposition := by
  intro X Y Z f g hf hg X' Z' i₁ i₂ f' H
  have := pullback.lift_fst _ _ (H.w.trans (Category.assoc _ _ _).symm)
  rw [← this] at H ⊢
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.138015, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.universally P f
hg : MorphismProperty.universally P g
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H✝ : IsPullback f' i₁ i₂ (f ≫ g)
H : IsPullback (pullback.lift f' (i₁ ≫ f) (_ : f' ≫ i₂ = (i₁ ≫ f) ≫ g) ≫ pullback.fst) i₁ i₂ (f ≫ g)
this : pullback.lift f' (i₁ ≫ f) (_ : f' ≫ i₂ = (i₁ ≫ f) ≫ g) ≫ pullback.fst = f'
⊢ P (pullback.lift f' (i₁ ≫ f) (_ : f' ≫ i₂ = (i₁ ≫ f) ≫ g) ≫ pullback.fst)

Next tactic:
apply hP _ _ _ (hg _ _ _ <| IsPullback.of_hasPullback _ _)
theorem StableUnderComposition.universally [HasPullbacks C] {P : MorphismProperty C}
    (hP : P.StableUnderComposition) : P.universally.StableUnderComposition := by
  intro X Y Z f g hf hg X' Z' i₁ i₂ f' H
  have := pullback.lift_fst _ _ (H.w.trans (Category.assoc _ _ _).symm)
  rw [← this] at H ⊢
  apply hP _ _ _ (hg _ _ _ <| IsPullback.of_hasPullback _ _)
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.138015, u_1} D
inst✝ : HasPullbacks C
P : MorphismProperty C
hP : StableUnderComposition P
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.universally P f
hg : MorphismProperty.universally P g
X' Z' : C
i₁ : X' ⟶ X
i₂ : Z' ⟶ Z
f' : X' ⟶ Z'
H✝ : IsPullback f' i₁ i₂ (f ≫ g)
H : IsPullback (pullback.lift f' (i₁ ≫ f) (_ : f' ≫ i₂ = (i₁ ≫ f) ≫ g) ≫ pullback.fst) i₁ i₂ (f ≫ g)
this : pullback.lift f' (i₁ ≫ f) (_ : f' ≫ i₂ = (i₁ ≫ f) ≫ g) ≫ pullback.fst = f'
⊢ P (pullback.lift f' (i₁ ≫ f) (_ : f' ≫ i₂ = (i₁ ≫ f) ≫ g))

Next tactic:
exact hf _ _ _ (H.of_right (pullback.lift_snd _ _ _) (IsPullback.of_hasPullback i₂ g))
theorem universally_le (P : MorphismProperty C) : P.universally ≤ P := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.139717, u_1} D
P : MorphismProperty C
⊢ universally P ≤ P

Next tactic:
intro X Y f hf
theorem universally_le (P : MorphismProperty C) : P.universally ≤ P := by
  intro X Y f hf
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.139717, u_1} D
P : MorphismProperty C
X Y : C
f : X ⟶ Y
hf : universally P f
⊢ P f

Next tactic:
exact hf (𝟙 _) (𝟙 _) _ (IsPullback.of_vert_isIso ⟨by rw [Category.comp_id, Category.id_comp]⟩)
theorem universally_le (P : MorphismProperty C) : P.universally ≤ P := by
  intro X Y f hf
  exact hf (𝟙 _) (𝟙 _) _ (IsPullback.of_vert_isIso ⟨by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
D : Type u_1
inst✝ : Category.{?u.139717, u_1} D
P : MorphismProperty C
X Y : C
f : X ⟶ Y
hf : universally P f
⊢ f ≫ 𝟙 Y = 𝟙 X ≫ f

Next tactic:
rw [Category.comp_id, Category.id_comp]
theorem injective_stableUnderComposition : (MorphismProperty.injective C).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.142432, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.injective C f
hg : MorphismProperty.injective C g
⊢ MorphismProperty.injective C (f ≫ g)

Next tactic:
delta MorphismProperty.injective
theorem injective_stableUnderComposition : (MorphismProperty.injective C).StableUnderComposition :=
  fun X Y Z f g hf hg => by
  delta MorphismProperty.injective
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.142432, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.injective C f
hg : MorphismProperty.injective C g
⊢ Injective ⇑(f ≫ g)

Next tactic:
rw [coe_comp]
theorem injective_stableUnderComposition : (MorphismProperty.injective C).StableUnderComposition :=
  fun X Y Z f g hf hg => by
  delta MorphismProperty.injective
  rw [coe_comp]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.142432, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.injective C f
hg : MorphismProperty.injective C g
⊢ Injective (⇑g ∘ ⇑f)

Next tactic:
exact hg.comp hf
theorem surjective_stableUnderComposition :
    (MorphismProperty.surjective C).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.142899, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.surjective C f
hg : MorphismProperty.surjective C g
⊢ MorphismProperty.surjective C (f ≫ g)

Next tactic:
delta MorphismProperty.surjective
theorem surjective_stableUnderComposition :
    (MorphismProperty.surjective C).StableUnderComposition := fun X Y Z f g hf hg => by
  delta MorphismProperty.surjective
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.142899, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.surjective C f
hg : MorphismProperty.surjective C g
⊢ Surjective ⇑(f ≫ g)

Next tactic:
rw [coe_comp]
theorem surjective_stableUnderComposition :
    (MorphismProperty.surjective C).StableUnderComposition := fun X Y Z f g hf hg => by
  delta MorphismProperty.surjective
  rw [coe_comp]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.142899, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.surjective C f
hg : MorphismProperty.surjective C g
⊢ Surjective (⇑g ∘ ⇑f)

Next tactic:
exact hg.comp hf
theorem bijective_stableUnderComposition : (MorphismProperty.bijective C).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.143364, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.bijective C f
hg : MorphismProperty.bijective C g
⊢ MorphismProperty.bijective C (f ≫ g)

Next tactic:
delta MorphismProperty.bijective
theorem bijective_stableUnderComposition : (MorphismProperty.bijective C).StableUnderComposition :=
  fun X Y Z f g hf hg => by
  delta MorphismProperty.bijective
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.143364, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.bijective C f
hg : MorphismProperty.bijective C g
⊢ Bijective ⇑(f ≫ g)

Next tactic:
rw [coe_comp]
theorem bijective_stableUnderComposition : (MorphismProperty.bijective C).StableUnderComposition :=
  fun X Y Z f g hf hg => by
  delta MorphismProperty.bijective
  rw [coe_comp]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
D : Type u_1
inst✝¹ : Category.{?u.143364, u_1} D
inst✝ : ConcreteCategory C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
hf : MorphismProperty.bijective C f
hg : MorphismProperty.bijective C g
⊢ Bijective (⇑g ∘ ⇑f)

Next tactic:
exact hg.comp hf
lemma IsInvertedBy.prod {W₁ : MorphismProperty C₁} {W₂ : MorphismProperty C₂}
    {E₁ E₂ : Type*} [Category E₁] [Category E₂] {F₁ : C₁ ⥤ E₁} {F₂ : C₂ ⥤ E₂}
    (h₁ : W₁.IsInvertedBy F₁) (h₂ : W₂.IsInvertedBy F₂) :
    (W₁.prod W₂).IsInvertedBy (F₁.prod F₂) := fun _ _ f hf => by
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{?u.149030, u_1} D
C₁ : Type u_2
C₂ : Type u_3
inst✝³ : Category.{u_6, u_2} C₁
inst✝² : Category.{u_7, u_3} C₂
W₁ : MorphismProperty C₁
W₂ : MorphismProperty C₂
E₁ : Type u_4
E₂ : Type u_5
inst✝¹ : Category.{u_8, u_4} E₁
inst✝ : Category.{u_9, u_5} E₂
F₁ : C₁ ⥤ E₁
F₂ : C₂ ⥤ E₂
h₁ : IsInvertedBy W₁ F₁
h₂ : IsInvertedBy W₂ F₂
x✝¹ x✝ : C₁ × C₂
f : x✝¹ ⟶ x✝
hf : MorphismProperty.prod W₁ W₂ f
⊢ IsIso ((Functor.prod F₁ F₂).map f)

Next tactic:
rw [isIso_prod_iff]
lemma IsInvertedBy.prod {W₁ : MorphismProperty C₁} {W₂ : MorphismProperty C₂}
    {E₁ E₂ : Type*} [Category E₁] [Category E₂] {F₁ : C₁ ⥤ E₁} {F₂ : C₂ ⥤ E₂}
    (h₁ : W₁.IsInvertedBy F₁) (h₂ : W₂.IsInvertedBy F₂) :
    (W₁.prod W₂).IsInvertedBy (F₁.prod F₂) := fun _ _ f hf => by
  rw [isIso_prod_iff]
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
D : Type u_1
inst✝⁴ : Category.{?u.149030, u_1} D
C₁ : Type u_2
C₂ : Type u_3
inst✝³ : Category.{u_6, u_2} C₁
inst✝² : Category.{u_7, u_3} C₂
W₁ : MorphismProperty C₁
W₂ : MorphismProperty C₂
E₁ : Type u_4
E₂ : Type u_5
inst✝¹ : Category.{u_8, u_4} E₁
inst✝ : Category.{u_9, u_5} E₂
F₁ : C₁ ⥤ E₁
F₂ : C₂ ⥤ E₂
h₁ : IsInvertedBy W₁ F₁
h₂ : IsInvertedBy W₂ F₂
x✝¹ x✝ : C₁ × C₂
f : x✝¹ ⟶ x✝
hf : MorphismProperty.prod W₁ W₂ f
⊢ IsIso ((Functor.prod F₁ F₂).map f).1 ∧ IsIso ((Functor.prod F₁ F₂).map f).2

Next tactic:
exact ⟨h₁ _ hf.1, h₂ _ hf.2⟩
lemma IsInvertedBy.pi (F : ∀ j, C j ⥤ D j) (hF : ∀ j, (W j).IsInvertedBy (F j)) :
    (MorphismProperty.pi W).IsInvertedBy (Functor.pi F) := by
  

Proof state:
C✝ : Type u
inst✝³ : Category.{v, u} C✝
D✝ : Type u_1
inst✝² : Category.{?u.151090, u_1} D✝
J : Type w
C : J → Type u
D : J → Type u'
inst✝¹ : (j : J) → Category.{v, u} (C j)
inst✝ : (j : J) → Category.{v', u'} (D j)
W : (j : J) → MorphismProperty (C j)
F : (j : J) → C j ⥤ D j
hF : ∀ (j : J), IsInvertedBy (W j) (F j)
⊢ IsInvertedBy (MorphismProperty.pi W) (Functor.pi F)

Next tactic:
intro _ _ f hf
lemma IsInvertedBy.pi (F : ∀ j, C j ⥤ D j) (hF : ∀ j, (W j).IsInvertedBy (F j)) :
    (MorphismProperty.pi W).IsInvertedBy (Functor.pi F) := by
  intro _ _ f hf
  

Proof state:
C✝ : Type u
inst✝³ : Category.{v, u} C✝
D✝ : Type u_1
inst✝² : Category.{?u.151090, u_1} D✝
J : Type w
C : J → Type u
D : J → Type u'
inst✝¹ : (j : J) → Category.{v, u} (C j)
inst✝ : (j : J) → Category.{v', u'} (D j)
W : (j : J) → MorphismProperty (C j)
F : (j : J) → C j ⥤ D j
hF : ∀ (j : J), IsInvertedBy (W j) (F j)
X✝ Y✝ : (j : J) → C j
f : X✝ ⟶ Y✝
hf : MorphismProperty.pi W f
⊢ IsIso ((Functor.pi F).map f)

Next tactic:
rw [isIso_pi_iff]
lemma IsInvertedBy.pi (F : ∀ j, C j ⥤ D j) (hF : ∀ j, (W j).IsInvertedBy (F j)) :
    (MorphismProperty.pi W).IsInvertedBy (Functor.pi F) := by
  intro _ _ f hf
  rw [isIso_pi_iff]
  

Proof state:
C✝ : Type u
inst✝³ : Category.{v, u} C✝
D✝ : Type u_1
inst✝² : Category.{?u.151090, u_1} D✝
J : Type w
C : J → Type u
D : J → Type u'
inst✝¹ : (j : J) → Category.{v, u} (C j)
inst✝ : (j : J) → Category.{v', u'} (D j)
W : (j : J) → MorphismProperty (C j)
F : (j : J) → C j ⥤ D j
hF : ∀ (j : J), IsInvertedBy (W j) (F j)
X✝ Y✝ : (j : J) → C j
f : X✝ ⟶ Y✝
hf : MorphismProperty.pi W f
⊢ ∀ (i : J), IsIso ((Functor.pi F).map f i)

Next tactic:
intro j
lemma IsInvertedBy.pi (F : ∀ j, C j ⥤ D j) (hF : ∀ j, (W j).IsInvertedBy (F j)) :
    (MorphismProperty.pi W).IsInvertedBy (Functor.pi F) := by
  intro _ _ f hf
  rw [isIso_pi_iff]
  intro j
  

Proof state:
C✝ : Type u
inst✝³ : Category.{v, u} C✝
D✝ : Type u_1
inst✝² : Category.{?u.151090, u_1} D✝
J : Type w
C : J → Type u
D : J → Type u'
inst✝¹ : (j : J) → Category.{v, u} (C j)
inst✝ : (j : J) → Category.{v', u'} (D j)
W : (j : J) → MorphismProperty (C j)
F : (j : J) → C j ⥤ D j
hF : ∀ (j : J), IsInvertedBy (W j) (F j)
X✝ Y✝ : (j : J) → C j
f : X✝ ⟶ Y✝
hf : MorphismProperty.pi W f
j : J
⊢ IsIso ((Functor.pi F).map f j)

Next tactic:
exact hF j _ (hf j)
@[ext]
lemma ext {P Q : Presheaf C X} {f g : P ⟶ Q} (w : ∀ U : Opens X, f.app (op U) = g.app (op U)) :
    f = g := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
P Q : Presheaf C X
f g : P ⟶ Q
w : ∀ (U : Opens ↑X), f.app (op U) = g.app (op U)
⊢ f = g

Next tactic:
apply NatTrans.ext
@[ext]
lemma ext {P Q : Presheaf C X} {f g : P ⟶ Q} (w : ∀ U : Opens X, f.app (op U) = g.app (op U)) :
    f = g := by
  apply NatTrans.ext
  

Proof state:
case app
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
P Q : Presheaf C X
f g : P ⟶ Q
w : ∀ (U : Opens ↑X), f.app (op U) = g.app (op U)
⊢ f.app = g.app

Next tactic:
ext U
@[ext]
lemma ext {P Q : Presheaf C X} {f g : P ⟶ Q} (w : ∀ U : Opens X, f.app (op U) = g.app (op U)) :
    f = g := by
  apply NatTrans.ext
  ext U
  

Proof state:
case app.h
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
P Q : Presheaf C X
f g : P ⟶ Q
w : ∀ (U : Opens ↑X), f.app (op U) = g.app (op U)
U : (Opens ↑X)ᵒᵖ
⊢ f.app U = g.app U

Next tactic:
induction U with | _ U => ?_
@[ext]
lemma ext {P Q : Presheaf C X} {f g : P ⟶ Q} (w : ∀ U : Opens X, f.app (op U) = g.app (op U)) :
    f = g := by
  apply NatTrans.ext
  ext U
  induction U with | _ U => ?_
  

Proof state:
case app.h.h
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
P Q : Presheaf C X
f g : P ⟶ Q
w : ∀ (U : Opens ↑X), f.app (op U) = g.app (op U)
U : Opens ↑X
⊢ f.app (op U) = g.app (op U)

Next tactic:
apply w
example {X} [CompleteLattice X] (v : Nat → X) (w x y z : X) (e : v 0 = v 1) (_ : v 1 = v 2)
    (h₀ : v 1 ≤ x) (_ : x ≤ z ⊓ w) (h₂ : x ≤ y ⊓ z) : v 0 ≤ y :=
  by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X : Type ?u.14461
inst✝ : CompleteLattice X
v : ℕ → X
w x y z : X
e : v 0 = v 1
x✝¹ : v 1 = v 2
h₀ : v 1 ≤ x
x✝ : x ≤ z ⊓ w
h₂ : x ≤ y ⊓ z
⊢ v 0 ≤ y

Next tactic:
restrict_tac
theorem restrict_restrict {X : TopCat} {C : Type*} [Category C] [ConcreteCategory C]
    {F : X.Presheaf C} {U V W : Opens X} (e₁ : U ≤ V) (e₂ : V ≤ W) (x : F.obj (op W)) :
    x |_ V |_ U = x |_ U := by
  

Proof state:
C✝ : Type u
inst✝² : Category.{v, u} C✝
X : TopCat
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
inst✝ : ConcreteCategory C
F : Presheaf C X
U V W : Opens ↑X
e₁ : U ≤ V
e₂ : V ≤ W
x : (forget C).obj (F.obj (op W))
⊢ x |_ V |_ U = x |_ U

Next tactic:
delta restrictOpen restrict
theorem restrict_restrict {X : TopCat} {C : Type*} [Category C] [ConcreteCategory C]
    {F : X.Presheaf C} {U V W : Opens X} (e₁ : U ≤ V) (e₂ : V ≤ W) (x : F.obj (op W)) :
    x |_ V |_ U = x |_ U := by
  delta restrictOpen restrict
  

Proof state:
C✝ : Type u
inst✝² : Category.{v, u} C✝
X : TopCat
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
inst✝ : ConcreteCategory C
F : Presheaf C X
U V W : Opens ↑X
e₁ : U ≤ V
e₂ : V ≤ W
x : (forget C).obj (F.obj (op W))
⊢ (F.map (homOfLE e₁).op) ((F.map (homOfLE e₂).op) x) = (F.map (homOfLE (_ : U ≤ W)).op) x

Next tactic:
rw [← comp_apply, ← Functor.map_comp]
theorem restrict_restrict {X : TopCat} {C : Type*} [Category C] [ConcreteCategory C]
    {F : X.Presheaf C} {U V W : Opens X} (e₁ : U ≤ V) (e₂ : V ≤ W) (x : F.obj (op W)) :
    x |_ V |_ U = x |_ U := by
  delta restrictOpen restrict
  rw [← comp_apply, ← Functor.map_comp]
  

Proof state:
C✝ : Type u
inst✝² : Category.{v, u} C✝
X : TopCat
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
inst✝ : ConcreteCategory C
F : Presheaf C X
U V W : Opens ↑X
e₁ : U ≤ V
e₂ : V ≤ W
x : (forget C).obj (F.obj (op W))
⊢ (F.map ((homOfLE e₂).op ≫ (homOfLE e₁).op)) x = (F.map (homOfLE (_ : U ≤ W)).op) x

Next tactic:
rfl
theorem map_restrict {X : TopCat} {C : Type*} [Category C] [ConcreteCategory C]
    {F G : X.Presheaf C} (e : F ⟶ G) {U V : Opens X} (h : U ≤ V) (x : F.obj (op V)) :
    e.app _ (x |_ U) = e.app _ x |_ U := by
  

Proof state:
C✝ : Type u
inst✝² : Category.{v, u} C✝
X : TopCat
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
inst✝ : ConcreteCategory C
F G : Presheaf C X
e : F ⟶ G
U V : Opens ↑X
h : U ≤ V
x : (forget C).obj (F.obj (op V))
⊢ (e.app (op U)) (x |_ U) = (e.app (op V)) x |_ U

Next tactic:
delta restrictOpen restrict
theorem map_restrict {X : TopCat} {C : Type*} [Category C] [ConcreteCategory C]
    {F G : X.Presheaf C} (e : F ⟶ G) {U V : Opens X} (h : U ≤ V) (x : F.obj (op V)) :
    e.app _ (x |_ U) = e.app _ x |_ U := by
  delta restrictOpen restrict
  

Proof state:
C✝ : Type u
inst✝² : Category.{v, u} C✝
X : TopCat
C : Type u_1
inst✝¹ : Category.{u_3, u_1} C
inst✝ : ConcreteCategory C
F G : Presheaf C X
e : F ⟶ G
U V : Opens ↑X
h : U ≤ V
x : (forget C).obj (F.obj (op V))
⊢ (e.app (op U)) ((F.map (homOfLE h).op) x) = (G.map (homOfLE h).op) ((e.app (op V)) x)

Next tactic:
rw [← comp_apply, NatTrans.naturality, comp_apply]