-- Mathlib/CategoryTheory/Sites/Closed.lean
theorem classifier_isSheaf : Presieve.IsSheaf J₁ (Functor.closedSieves J₁)

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
Z : C
g : Z ⟶ Opposite.unop (Opposite.op X)
⊢ M.arrows g ∧ S.arrows g ↔ N.arrows g ∧ S.arrows g

Tactic:
simp only [and_comm]

Result:
case h
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
Z : C
g : Z ⟶ Opposite.unop (Opposite.op X)
⊢ S.arrows g ∧ M.arrows g ↔ S.arrows g ∧ N.arrows g

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
Z : C
g : Z ⟶ Opposite.unop (Opposite.op X)
⊢ S.arrows g ∧ M.arrows g ↔ S.arrows g ∧ N.arrows g

Tactic:
apply and_congr_right

Result:
case h.h
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
Z : C
g : Z ⟶ Opposite.unop (Opposite.op X)
⊢ S.arrows g → (M.arrows g ↔ N.arrows g)

Proof state:
case refine_1.mk.mk.a.h.mp
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
MSNS : M ⊓ S = N ⊓ S
hf : J₁.Covers M f
⊢ Sieve.pullback f (N ⊓ ?m.12869) ∈ J₁ Y

C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
MSNS : M ⊓ S = N ⊓ S
hf : J₁.Covers M f
⊢ Sieve X

Tactic:
rw [← MSNS]

Result:
case refine_1.mk.mk.a.h.mp
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
MSNS : M ⊓ S = N ⊓ S
hf : J₁.Covers M f
⊢ Sieve.pullback f (M ⊓ S) ∈ J₁ Y

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
⊢ M ⊓ S = N ⊓ S

Tactic:
ext Z g

Result:
case h
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
q : ∀ ⦃Z : C⦄ (g : Z ⟶ X), S.arrows g → Sieve.pullback g M = Sieve.pullback g N
Z : C
g : Z ⟶ Opposite.unop (Opposite.op X)
⊢ (M ⊓ S).arrows g ↔ (N ⊓ S).arrows g

Proof state:
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
⊢ Presieve.IsSeparatedFor (Functor.closedSieves J₁) S.arrows ∧
    ∀ (x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows), x.Compatible → ∃ t, x.IsAmalgamation t

Tactic:
refine ⟨?_, ?_⟩

Result:
case refine_1
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
⊢ Presieve.IsSeparatedFor (Functor.closedSieves J₁) S.arrows

case refine_2
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
⊢ ∀ (x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows), x.Compatible → ∃ t, x.IsAmalgamation t

Proof state:
case refine_1.mk.mk.a.h
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
⊢ (↑⟨M, hM⟩).arrows f ↔ (↑⟨N, hN⟩).arrows f

Tactic:
dsimp only [Subtype.coe_mk]

Result:
case refine_1.mk.mk.a.h
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
M : Sieve (Opposite.unop (Opposite.op X))
hM : J₁.IsClosed M
N : Sieve (Opposite.unop (Opposite.op X))
hN : J₁.IsClosed N
hM₂ : x.IsAmalgamation ⟨M, hM⟩
hN₂ : x.IsAmalgamation ⟨N, hN⟩
Y : C
f : Y ⟶ X
⊢ M.arrows f ↔ N.arrows f

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
hx : x.SieveCompatible
M : Sieve X := Sieve.bind S.arrows fun Y f hf => ↑(x f hf)
Y : C
f : Y ⟶ X
hf : S.arrows f
⊢ Sieve.pullback f M ≤ ↑(x f hf)

Tactic:
rintro Z u ⟨W, g, f', hf', hg : (x f' hf').1 _, c⟩

Result:
case a.intro.intro.intro.intro.intro
C : Type u
inst✝ : Category.{v, u} C
J₁ : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ J₁ X
x : Presieve.FamilyOfElements (Functor.closedSieves J₁) S.arrows
hx : x.SieveCompatible
M : Sieve X := Sieve.bind S.arrows fun Y f hf => ↑(x f hf)
Y : C
f : Y ⟶ X
hf : S.arrows f
Z : C
u : Z ⟶ Y
W : C
g : Z ⟶ W
f' : W ⟶ X
hf' : S.arrows f'
hg : (↑(x f' hf')).arrows g
c : g ≫ f' = u ≫ f
⊢ (↑(x f hf)).arrows u