Theorem: CategoryTheory.Presheaf.isLocallySurjective_of_isLocallySurjective_of_isLocallyInjective
File: Mathlib/CategoryTheory/Sites/LocallySurjective.lean

Proof steps:
state_before: C : Type u
inst✝⁴ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝³ : Category.{v', u'} A
inst✝² : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
inst✝¹ : IsLocallySurjective J (f₁ ≫ f₂)
inst✝ : IsLocallyInjective J f₂
X : C
x : (forget A).obj (F₂.obj (op X))
⊢ imageSieve f₁ x ∈ J.sieves X
state_after: C : Type u
inst✝⁴ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝³ : Category.{v', u'} A
inst✝² : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
inst✝¹ : IsLocallySurjective J (f₁ ≫ f₂)
inst✝ : IsLocallyInjective J f₂
X : C
x : (forget A).obj (F₂.obj (op X))
S : Sieve X := imageSieve (f₁ ≫ f₂) ((f₂.app (op X)) x)
⊢ imageSieve f₁ x ∈ J.sieves X
tactic: let S := imageSieve (f₁ ≫ f₂) (f₂.app _ x)
state_before: C : Type u
inst✝⁴ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝³ : Category.{v', u'} A
inst✝² : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
inst✝¹ : IsLocallySurjective J (f₁ ≫ f₂)
inst✝ : IsLocallyInjective J f₂
X : C
x : (forget A).obj (F₂.obj (op X))
S : Sieve X := imageSieve (f₁ ≫ f₂) ((f₂.app (op X)) x)
⊢ imageSieve f₁ x ∈ J.sieves X
state_after: C : Type u
inst✝⁴ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝³ : Category.{v', u'} A
inst✝² : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
inst✝¹ : IsLocallySurjective J (f₁ ≫ f₂)
inst✝ : IsLocallyInjective J f₂
X : C
x : (forget A).obj (F₂.obj (op X))
S : Sieve X := imageSieve (f₁ ≫ f₂) ((f₂.app (op X)) x)
T : ⦃Y : C⦄ → (f : Y ⟶ X) → S.arrows f → Sieve Y :=
  fun Y f hf => equalizerSieve ((f₁.app (op Y)) (localPreimage (f₁ ≫ f₂) ((f₂.app (op X)) x) f hf)) ((F₂.map f.op) x)
⊢ imageSieve f₁ x ∈ J.sieves X
tactic: let T : ∀ ⦃Y : C⦄ (f : Y ⟶ X) (_ : S f), Sieve Y := fun Y f hf =>
      equalizerSieve (f₁.app _ (localPreimage (f₁ ≫ f₂) (f₂.app _ x) f hf)) (F₂.map f.op x)
state_before: C : Type u
inst✝⁴ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝³ : Category.{v', u'} A
inst✝² : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
inst✝¹ : IsLocallySurjective J (f₁ ≫ f₂)
inst✝ : IsLocallyInjective J f₂
X : C
x : (forget A).obj (F₂.obj (op X))
S : Sieve X := imageSieve (f₁ ≫ f₂) ((f₂.app (op X)) x)
T : ⦃Y : C⦄ → (f : Y ⟶ X) → S.arrows f → Sieve Y :=
  fun Y f hf => equalizerSieve ((f₁.app (op Y)) (localPreimage (f₁ ≫ f₂) ((f₂.app (op X)) x) f hf)) ((F₂.map f.op) x)
⊢ imageSieve f₁ x ∈ J.sieves X
state_after: case refine_1
C : Type u
inst✝⁴ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝³ : Category.{v', u'} A
inst✝² : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
inst✝¹ : IsLocallySurjective J (f₁ ≫ f₂)
inst✝ : IsLocallyInjective J f₂
X : C
x : (forget A).obj (F₂.obj (op X))
S : Sieve X := imageSieve (f₁ ≫ f₂) ((f₂.app (op X)) x)
T : ⦃Y : C⦄ → (f : Y ⟶ X) → S.arrows f → Sieve Y :=
  fun Y f hf => equalizerSieve ((f₁.app (op Y)) (localPreimage (f₁ ≫ f₂) ((f₂.app (op X)) x) f hf)) ((F₂.map f.op) x)
⊢ Sieve.bind S.arrows T ≤ imageSieve f₁ x

case refine_2
C : Type u
inst✝⁴ : Category.{v, u} C
J : GrothendieckTopology C
A : Type u'
inst✝³ : Category.{v', u'} A
inst✝² : ConcreteCategory A
F₁ F₂ F₃ : Cᵒᵖ ⥤ A
f₁ : F₁ ⟶ F₂
f₂ : F₂ ⟶ F₃
inst✝¹ : IsLocallySurjective J (f₁ ≫ f₂)
inst✝ : IsLocallyInjective J f₂
X : C
x : (forget A).obj (F₂.obj (op X))
S : Sieve X := imageSieve (f₁ ≫ f₂) ((f₂.app (op X)) x)
T : ⦃Y : C⦄ → (f : Y ⟶ X) → S.arrows f → Sieve Y :=
  fun Y f hf => equalizerSieve ((f₁.app (op Y)) (localPreimage (f₁ ≫ f₂) ((f₂.app (op X)) x) f hf)) ((F₂.map f.op) x)
⊢ ∀ ⦃Y : C⦄ ⦃f : Y ⟶ unop (op X)⦄,
    (imageSieve (f₁ ≫ f₂) ((f₂.app (op X)) x)).arrows f → Sieve.pullback f (Sieve.bind S.arrows T) ∈ J.sieves Y
tactic: refine J.superset_covering ?_ (J.transitive (imageSieve_mem J (f₁ ≫ f₂) (f₂.app _ x))
      (Sieve.bind S.1 T) ?_)