Theorem: CategoryTheory.Presheaf.isLocallyInjective_iff_equalizerSieve_mem_imp
File: Mathlib/CategoryTheory/Sites/LocallyInjective.lean

tactic: constructor
state_before: C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
⊢ IsLocallyInjective J φ ↔
    ∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
      equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop
state_after: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
⊢ IsLocallyInjective J φ →
    ∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
      equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop

case mpr
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
⊢ (∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
      equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop) →
    IsLocallyInjective J φ

tactic: intro _ X x y h
state_before: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
⊢ IsLocallyInjective J φ →
    ∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
      equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop
state_after: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
⊢ equalizerSieve x y ∈ J.sieves X.unop

tactic: let S := equalizerSieve (φ.app _ x) (φ.app _ y)
state_before: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
⊢ equalizerSieve x y ∈ J.sieves X.unop
state_after: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
⊢ equalizerSieve x y ∈ J.sieves X.unop

tactic: let T : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X.unop⦄ (_ : S f), Sieve Y := fun Y f _ =>
  equalizerSieve (F₁.map f.op x) ((F₁.map f.op y))
state_before: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
⊢ equalizerSieve x y ∈ J.sieves X.unop
state_after: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
⊢ equalizerSieve x y ∈ J.sieves X.unop

tactic: refine J.superset_covering ?_ (J.transitive h (Sieve.bind S.1 T) ?_)
state_before: case mp
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
⊢ equalizerSieve x y ∈ J.sieves X.unop
state_after: case mp.refine_1
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
⊢ Sieve.bind S.arrows T ≤ equalizerSieve x y

case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X.unop⦄,
    (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f → Sieve.pullback f (Sieve.bind S.arrows T) ∈ J.sieves Y

tactic: rintro Y f ⟨Z, a, g, hg, ha, rfl⟩
state_before: case mp.refine_1
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
⊢ Sieve.bind S.arrows T ≤ equalizerSieve x y
state_after: case mp.refine_1.intro.intro.intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y Z : C
a : Y ⟶ Z
g : Z ⟶ X.unop
hg : S.arrows g
ha : (T hg).arrows a
⊢ (equalizerSieve x y).arrows (a ≫ g)

tactic: simpa using ha
state_before: case mp.refine_1.intro.intro.intro.intro.intro
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y Z : C
a : Y ⟶ Z
g : Z ⟶ X.unop
hg : S.arrows g
ha : (T hg).arrows a
⊢ (equalizerSieve x y).arrows (a ≫ g)
state_after: no goals

tactic: intro Y f hf
state_before: case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X.unop⦄,
    (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f → Sieve.pullback f (Sieve.bind S.arrows T) ∈ J.sieves Y
state_after: case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y : C
f : Y ⟶ X.unop
hf : (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f
⊢ Sieve.pullback f (Sieve.bind S.arrows T) ∈ J.sieves Y

tactic: refine J.superset_covering (Sieve.le_pullback_bind S.1 T _ hf)
  (equalizerSieve_mem J φ _ _ ?_)
state_before: case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y : C
f : Y ⟶ X.unop
hf : (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f
⊢ Sieve.pullback f (Sieve.bind S.arrows T) ∈ J.sieves Y
state_after: case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y : C
f : Y ⟶ X.unop
hf : (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f
⊢ (φ.app { unop := Y }) ((F₁.map f.op) x) = (φ.app { unop := Y }) ((F₁.map f.op) y)

tactic: erw [NatTrans.naturality_apply, NatTrans.naturality_apply]
state_before: case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y : C
f : Y ⟶ X.unop
hf : (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f
⊢ (φ.app { unop := Y }) ((F₁.map f.op) x) = (φ.app { unop := Y }) ((F₁.map f.op) y)
state_after: case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y : C
f : Y ⟶ X.unop
hf : (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f
⊢ (F₂.map f.op) ((φ.app { unop := X.unop }) x) = (F₂.map f.op) ((φ.app { unop := X.unop }) y)

tactic: exact hf
state_before: case mp.refine_2
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
a✝ : IsLocallyInjective J φ
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
S : Sieve X.unop := equalizerSieve ((φ.app X) x) ((φ.app X) y)
T : ⦃Y : C⦄ → ⦃f : Y ⟶ X.unop⦄ → S.arrows f → Sieve Y :=
  fun Y f x_1 => equalizerSieve ((F₁.map f.op) x) ((F₁.map f.op) y)
Y : C
f : Y ⟶ X.unop
hf : (equalizerSieve ((φ.app X) x) ((φ.app X) y)).arrows f
⊢ (F₂.map f.op) ((φ.app { unop := X.unop }) x) = (F₂.map f.op) ((φ.app { unop := X.unop }) y)
state_after: no goals

tactic: intro hφ
state_before: case mpr
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
⊢ (∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
      equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop) →
    IsLocallyInjective J φ
state_after: case mpr
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
hφ :
  ∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
    equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop
⊢ IsLocallyInjective J φ

tactic: exact ⟨fun {X} x y h => hφ x y (by simp [h])⟩
state_before: case mpr
C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
hφ :
  ∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
    equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop
⊢ IsLocallyInjective J φ
state_after: no goals

tactic: simp [h]
state_before: C : Type u
inst✝² : Category.{v, u} C
D : Type u'
inst✝¹ : Category.{v', u'} D
inst✝ : ConcreteCategory D
J : GrothendieckTopology C
F₁ F₂ F₃ : Cᵒᵖ ⥤ D
φ : F₁ ⟶ F₂
ψ : F₂ ⟶ F₃
hφ :
  ∀ ⦃X : Cᵒᵖ⦄ (x y : (forget D).obj (F₁.obj X)),
    equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop → equalizerSieve x y ∈ J.sieves X.unop
X : Cᵒᵖ
x y : (forget D).obj (F₁.obj X)
h : (φ.app X) x = (φ.app X) y
⊢ equalizerSieve ((φ.app X) x) ((φ.app X) y) ∈ J.sieves X.unop
state_after: no goals