l3lab/ntp-mathlib huggingface dataset:
theorem covering_iff_covers_id (S : Sieve X) : S ∈ J X ↔ J.Covers S (𝟙 X) := by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R : Sieve X
J : GrothendieckTopology C
S : Sieve X
⊢ S ∈ sieves J X ↔ Covers J S (𝟙 X)

Next tactic:
simp [covers_iff]
/-- The maximality axiom in 'arrow' form: Any arrow `f` in `S` is covered by `S`. -/
theorem arrow_max (f : Y ⟶ X) (S : Sieve X) (hf : S f) : J.Covers S f := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S : Sieve X
hf : S.arrows f
⊢ Covers J S f

Next tactic:
rw [Covers, (Sieve.pullback_eq_top_iff_mem f).1 hf]
/-- The maximality axiom in 'arrow' form: Any arrow `f` in `S` is covered by `S`. -/
theorem arrow_max (f : Y ⟶ X) (S : Sieve X) (hf : S f) : J.Covers S f := by
  rw [Covers, (Sieve.pullback_eq_top_iff_mem f).1 hf]
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S : Sieve X
hf : S.arrows f
⊢ ⊤ ∈ sieves J Y

Next tactic:
apply J.top_mem
/-- The stability axiom in 'arrow' form: If `S` covers `f` then `S` covers `g ≫ f` for any `g`. -/
theorem arrow_stable (f : Y ⟶ X) (S : Sieve X) (h : J.Covers S f) {Z : C} (g : Z ⟶ Y) :
    J.Covers S (g ≫ f) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S : Sieve X
h : Covers J S f
Z : C
g : Z ⟶ Y
⊢ Covers J S (g ≫ f)

Next tactic:
rw [covers_iff] at h ⊢
/-- The stability axiom in 'arrow' form: If `S` covers `f` then `S` covers `g ≫ f` for any `g`. -/
theorem arrow_stable (f : Y ⟶ X) (S : Sieve X) (h : J.Covers S f) {Z : C} (g : Z ⟶ Y) :
    J.Covers S (g ≫ f) := by
  rw [covers_iff] at h ⊢
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S : Sieve X
h : Sieve.pullback f S ∈ sieves J Y
Z : C
g : Z ⟶ Y
⊢ Sieve.pullback (g ≫ f) S ∈ sieves J Z

Next tactic:
simp [h, Sieve.pullback_comp]
/-- The transitivity axiom in 'arrow' form: If `S` covers `f` and every arrow in `S` is covered by
`R`, then `R` covers `f`.
-/
theorem arrow_trans (f : Y ⟶ X) (S R : Sieve X) (h : J.Covers S f) :
    (∀ {Z : C} (g : Z ⟶ X), S g → J.Covers R g) → J.Covers R f := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R✝ : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S R : Sieve X
h : Covers J S f
⊢ (∀ {Z : C} (g : Z ⟶ X), S.arrows g → Covers J R g) → Covers J R f

Next tactic:
intro k
/-- The transitivity axiom in 'arrow' form: If `S` covers `f` and every arrow in `S` is covered by
`R`, then `R` covers `f`.
-/
theorem arrow_trans (f : Y ⟶ X) (S R : Sieve X) (h : J.Covers S f) :
    (∀ {Z : C} (g : Z ⟶ X), S g → J.Covers R g) → J.Covers R f := by
  intro k
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R✝ : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S R : Sieve X
h : Covers J S f
k : ∀ {Z : C} (g : Z ⟶ X), S.arrows g → Covers J R g
⊢ Covers J R f

Next tactic:
apply J.transitive h
/-- The transitivity axiom in 'arrow' form: If `S` covers `f` and every arrow in `S` is covered by
`R`, then `R` covers `f`.
-/
theorem arrow_trans (f : Y ⟶ X) (S R : Sieve X) (h : J.Covers S f) :
    (∀ {Z : C} (g : Z ⟶ X), S g → J.Covers R g) → J.Covers R f := by
  intro k
  apply J.transitive h
  

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R✝ : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S R : Sieve X
h : Covers J S f
k : ∀ {Z : C} (g : Z ⟶ X), S.arrows g → Covers J R g
⊢ ∀ ⦃Y_1 : C⦄ ⦃f_1 : Y_1 ⟶ Y⦄, (Sieve.pullback f S).arrows f_1 → Sieve.pullback f_1 (Sieve.pullback f R) ∈ sieves J Y_1

Next tactic:
intro Z g hg
/-- The transitivity axiom in 'arrow' form: If `S` covers `f` and every arrow in `S` is covered by
`R`, then `R` covers `f`.
-/
theorem arrow_trans (f : Y ⟶ X) (S R : Sieve X) (h : J.Covers S f) :
    (∀ {Z : C} (g : Z ⟶ X), S g → J.Covers R g) → J.Covers R f := by
  intro k
  apply J.transitive h
  intro Z g hg
  

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R✝ : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S R : Sieve X
h : Covers J S f
k : ∀ {Z : C} (g : Z ⟶ X), S.arrows g → Covers J R g
Z : C
g : Z ⟶ Y
hg : (Sieve.pullback f S).arrows g
⊢ Sieve.pullback g (Sieve.pullback f R) ∈ sieves J Z

Next tactic:
rw [← Sieve.pullback_comp]
/-- The transitivity axiom in 'arrow' form: If `S` covers `f` and every arrow in `S` is covered by
`R`, then `R` covers `f`.
-/
theorem arrow_trans (f : Y ⟶ X) (S R : Sieve X) (h : J.Covers S f) :
    (∀ {Z : C} (g : Z ⟶ X), S g → J.Covers R g) → J.Covers R f := by
  intro k
  apply J.transitive h
  intro Z g hg
  rw [← Sieve.pullback_comp]
  

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R✝ : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S R : Sieve X
h : Covers J S f
k : ∀ {Z : C} (g : Z ⟶ X), S.arrows g → Covers J R g
Z : C
g : Z ⟶ Y
hg : (Sieve.pullback f S).arrows g
⊢ Sieve.pullback (g ≫ f) R ∈ sieves J Z

Next tactic:
apply k (g ≫ f) hg
theorem arrow_intersect (f : Y ⟶ X) (S R : Sieve X) (hS : J.Covers S f) (hR : J.Covers R f) :
    J.Covers (S ⊓ R) f := by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R✝ : Sieve X
J : GrothendieckTopology C
f : Y ⟶ X
S R : Sieve X
hS : Covers J S f
hR : Covers J R f
⊢ Covers J (S ⊓ R) f

Next tactic:
simpa [covers_iff] using And.intro hS hR
/-- The trivial Grothendieck topology, in which only the maximal sieve is covering. This topology is
also known as the indiscrete, coarse, or chaotic topology.

See [MM92] Chapter III, Section 2, example (a), or
https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies
-/
def trivial : GrothendieckTopology C where
  sieves X := {⊤}
  top_mem' X := rfl
  pullback_stable' X Y S f hf := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ : C
S✝ R : Sieve X✝
J : GrothendieckTopology C
X Y : C
S : Sieve X
f : Y ⟶ X
hf : S ∈ (fun X => {⊤}) X
⊢ Sieve.pullback f S ∈ (fun X => {⊤}) Y

Next tactic:
rw [Set.mem_singleton_iff] at hf ⊢
/-- The trivial Grothendieck topology, in which only the maximal sieve is covering. This topology is
also known as the indiscrete, coarse, or chaotic topology.

See [MM92] Chapter III, Section 2, example (a), or
https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies
-/
def trivial : GrothendieckTopology C where
  sieves X := {⊤}
  top_mem' X := rfl
  pullback_stable' X Y S f hf := by
    rw [Set.mem_singleton_iff] at hf ⊢
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ : C
S✝ R : Sieve X✝
J : GrothendieckTopology C
X Y : C
S : Sieve X
f : Y ⟶ X
hf : S = ⊤
⊢ Sieve.pullback f S = ⊤

Next tactic:
simp [hf]
/-- The trivial Grothendieck topology, in which only the maximal sieve is covering. This topology is
also known as the indiscrete, coarse, or chaotic topology.

See [MM92] Chapter III, Section 2, example (a), or
https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies
-/
def trivial : GrothendieckTopology C where
  sieves X := {⊤}
  top_mem' X := rfl
  pullback_stable' X Y S f hf := by
    rw [Set.mem_singleton_iff] at hf ⊢
    simp [hf]
  transitive' X S hS R hR := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
S✝ R✝ : Sieve X✝
J : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ (fun X => {⊤}) X
R : Sieve X
hR : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Sieve.pullback f R ∈ (fun X => {⊤}) Y
⊢ R ∈ (fun X => {⊤}) X

Next tactic:
rw [Set.mem_singleton_iff, ← Sieve.id_mem_iff_eq_top] at hS
/-- The trivial Grothendieck topology, in which only the maximal sieve is covering. This topology is
also known as the indiscrete, coarse, or chaotic topology.

See [MM92] Chapter III, Section 2, example (a), or
https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies
-/
def trivial : GrothendieckTopology C where
  sieves X := {⊤}
  top_mem' X := rfl
  pullback_stable' X Y S f hf := by
    rw [Set.mem_singleton_iff] at hf ⊢
    simp [hf]
  transitive' X S hS R hR := by
    rw [Set.mem_singleton_iff, ← Sieve.id_mem_iff_eq_top] at hS
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
S✝ R✝ : Sieve X✝
J : GrothendieckTopology C
X : C
S : Sieve X
hS : S.arrows (𝟙 X)
R : Sieve X
hR : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Sieve.pullback f R ∈ (fun X => {⊤}) Y
⊢ R ∈ (fun X => {⊤}) X

Next tactic:
simpa using hR hS
/-- The discrete Grothendieck topology, in which every sieve is covering.

See https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies.
-/
def discrete : GrothendieckTopology C
    where
  sieves X := Set.univ
  top_mem' := by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ ∀ (X : C), ⊤ ∈ (fun X => Set.univ) X

Next tactic:
simp
/-- The discrete Grothendieck topology, in which every sieve is covering.

See https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies.
-/
def discrete : GrothendieckTopology C
    where
  sieves X := Set.univ
  top_mem' := by simp
  pullback_stable' X Y f := by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ : C
S R : Sieve X✝
J : GrothendieckTopology C
X Y : C
f : Sieve X
⊢ ∀ (f_1 : Y ⟶ X), f ∈ (fun X => Set.univ) X → Sieve.pullback f_1 f ∈ (fun X => Set.univ) Y

Next tactic:
simp
/-- The discrete Grothendieck topology, in which every sieve is covering.

See https://en.wikipedia.org/wiki/Grothendieck_topology#The_discrete_and_indiscrete_topologies.
-/
def discrete : GrothendieckTopology C
    where
  sieves X := Set.univ
  top_mem' := by simp
  pullback_stable' X Y f := by simp
  transitive' := by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ ∀ ⦃X : C⦄ ⦃S : Sieve X⦄,
    S ∈ (fun X => Set.univ) X →
      ∀ (R : Sieve X),
        (∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Sieve.pullback f R ∈ (fun X => Set.univ) Y) → R ∈ (fun X => Set.univ) X

Next tactic:
simp
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
instance : InfSet (GrothendieckTopology C) where
  sInf T :=
    { sieves := sInf (sieves '' T)
      top_mem' := by
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
T : Set (GrothendieckTopology C)
⊢ ∀ (X : C), ⊤ ∈ sInf (sieves '' T) X

Next tactic:
rintro X S ⟨⟨_, J, hJ, rfl⟩, rfl⟩
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
instance : InfSet (GrothendieckTopology C) where
  sInf T :=
    { sieves := sInf (sieves '' T)
      top_mem' := by
        rintro X S ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        

Proof state:
case intro.mk.intro.intro
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
S R : Sieve X✝
J✝ : GrothendieckTopology C
T : Set (GrothendieckTopology C)
X : C
J : GrothendieckTopology C
hJ : J ∈ T
⊢ ⊤ ∈ (fun f => ↑f X) { val := J.sieves, property := (_ : ∃ a ∈ T, a.sieves = J.sieves) }

Next tactic:
simp
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
instance : InfSet (GrothendieckTopology C) where
  sInf T :=
    { sieves := sInf (sieves '' T)
      top_mem' := by
        rintro X S ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        simp
      pullback_stable' := by
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
T : Set (GrothendieckTopology C)
⊢ ∀ ⦃X Y : C⦄ ⦃S : Sieve X⦄ (f : Y ⟶ X), S ∈ sInf (sieves '' T) X → Sieve.pullback f S ∈ sInf (sieves '' T) Y

Next tactic:
rintro X Y S hS f _ ⟨⟨_, J, hJ, rfl⟩, rfl⟩
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
instance : InfSet (GrothendieckTopology C) where
  sInf T :=
    { sieves := sInf (sieves '' T)
      top_mem' := by
        rintro X S ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        simp
      pullback_stable' := by
        rintro X Y S hS f _ ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        

Proof state:
case intro.mk.intro.intro
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ : C
S✝ R : Sieve X✝
J✝ : GrothendieckTopology C
T : Set (GrothendieckTopology C)
X Y : C
S : Sieve X
hS : Y ⟶ X
f : S ∈ sInf (sieves '' T) X
J : GrothendieckTopology C
hJ : J ∈ T
⊢ Sieve.pullback hS S ∈ (fun f => ↑f Y) { val := J.sieves, property := (_ : ∃ a ∈ T, a.sieves = J.sieves) }

Next tactic:
apply J.pullback_stable _ (f _ ⟨⟨_, _, hJ, rfl⟩, rfl⟩)
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
instance : InfSet (GrothendieckTopology C) where
  sInf T :=
    { sieves := sInf (sieves '' T)
      top_mem' := by
        rintro X S ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        simp
      pullback_stable' := by
        rintro X Y S hS f _ ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        apply J.pullback_stable _ (f _ ⟨⟨_, _, hJ, rfl⟩, rfl⟩)
      transitive' := by
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
T : Set (GrothendieckTopology C)
⊢ ∀ ⦃X : C⦄ ⦃S : Sieve X⦄,
    S ∈ sInf (sieves '' T) X →
      ∀ (R : Sieve X),
        (∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Sieve.pullback f R ∈ sInf (sieves '' T) Y) → R ∈ sInf (sieves '' T) X

Next tactic:
rintro X S hS R h _ ⟨⟨_, J, hJ, rfl⟩, rfl⟩
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
instance : InfSet (GrothendieckTopology C) where
  sInf T :=
    { sieves := sInf (sieves '' T)
      top_mem' := by
        rintro X S ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        simp
      pullback_stable' := by
        rintro X Y S hS f _ ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        apply J.pullback_stable _ (f _ ⟨⟨_, _, hJ, rfl⟩, rfl⟩)
      transitive' := by
        rintro X S hS R h _ ⟨⟨_, J, hJ, rfl⟩, rfl⟩
        

Proof state:
case intro.mk.intro.intro
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
S✝ R✝ : Sieve X✝
J✝ : GrothendieckTopology C
T : Set (GrothendieckTopology C)
X : C
S : Sieve X
hS : S ∈ sInf (sieves '' T) X
R : Sieve X
h : ∀ ⦃Y : C⦄ ⦃f : Y ⟶ X⦄, S.arrows f → Sieve.pullback f R ∈ sInf (sieves '' T) Y
J : GrothendieckTopology C
hJ : J ∈ T
⊢ R ∈ (fun f => ↑f X) { val := J.sieves, property := (_ : ∃ a ∈ T, a.sieves = J.sieves) }

Next tactic:
apply
          J.transitive (hS _ ⟨⟨_, _, hJ, rfl⟩, rfl⟩) _ fun Y f hf => h hf _ ⟨⟨_, _, hJ, rfl⟩, rfl⟩
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
theorem isGLB_sInf (s : Set (GrothendieckTopology C)) : IsGLB s (sInf s) := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
s : Set (GrothendieckTopology C)
⊢ IsGLB s (sInf s)

Next tactic:
refine' @IsGLB.of_image _ _ _ _ sieves _ _ _ _
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
theorem isGLB_sInf (s : Set (GrothendieckTopology C)) : IsGLB s (sInf s) := by
  refine' @IsGLB.of_image _ _ _ _ sieves _ _ _ _
  · 

Proof state:
case refine'_1
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
s : Set (GrothendieckTopology C)
⊢ ∀ {x y : GrothendieckTopology C}, x.sieves ≤ y.sieves ↔ x ≤ y

Next tactic:
intros
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
theorem isGLB_sInf (s : Set (GrothendieckTopology C)) : IsGLB s (sInf s) := by
  refine' @IsGLB.of_image _ _ _ _ sieves _ _ _ _
  · intros
    

Proof state:
case refine'_1
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
s : Set (GrothendieckTopology C)
x✝ y✝ : GrothendieckTopology C
⊢ x✝.sieves ≤ y✝.sieves ↔ x✝ ≤ y✝

Next tactic:
rfl
/-- See <https://stacks.math.columbia.edu/tag/00Z7> -/
theorem isGLB_sInf (s : Set (GrothendieckTopology C)) : IsGLB s (sInf s) := by
  refine' @IsGLB.of_image _ _ _ _ sieves _ _ _ _
  · intros
    rfl
  · 

Proof state:
case refine'_2
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
s : Set (GrothendieckTopology C)
⊢ IsGLB (sieves '' s) (sInf s).sieves

Next tactic:
exact _root_.isGLB_sInf _
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ discrete C = ⊤

Next tactic:
apply le_antisymm
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · 

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ discrete C ≤ ⊤

Next tactic:
exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
      · 

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ ⊤ ≤ discrete C

Next tactic:
intro X S _
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
      · intro X S _
        

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
S✝ R : Sieve X✝
J : GrothendieckTopology C
X : C
S : Sieve X
a✝ : S ∈ sieves ⊤ X
⊢ S ∈ sieves (discrete C) X

Next tactic:
apply Set.mem_univ
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
      · intro X S _
        apply Set.mem_univ)
    (trivial C)
    (by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ trivial C = ⊥

Next tactic:
apply le_antisymm
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
      · intro X S _
        apply Set.mem_univ)
    (trivial C)
    (by
      apply le_antisymm
      · 

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ trivial C ≤ ⊥

Next tactic:
intro X S hS
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
      · intro X S _
        apply Set.mem_univ)
    (trivial C)
    (by
      apply le_antisymm
      · intro X S hS
        

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
S✝ R : Sieve X✝
J : GrothendieckTopology C
X : C
S : Sieve X
hS : S ∈ sieves (trivial C) X
⊢ S ∈ sieves ⊥ X

Next tactic:
rw [trivial_covering] at hS
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
      · intro X S _
        apply Set.mem_univ)
    (trivial C)
    (by
      apply le_antisymm
      · intro X S hS
        rw [trivial_covering] at hS
        

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X✝ Y : C
S✝ R : Sieve X✝
J : GrothendieckTopology C
X : C
S : Sieve X
hS : S = ⊤
⊢ S ∈ sieves ⊥ X

Next tactic:
apply covering_of_eq_top _ hS
/-- Construct a complete lattice from the `Inf`, but make the trivial and discrete topologies
definitionally equal to the bottom and top respectively.
-/
instance : CompleteLattice (GrothendieckTopology C) :=
  CompleteLattice.copy (completeLatticeOfInf _ isGLB_sInf) _ rfl (discrete C)
    (by
      apply le_antisymm
      · exact @CompleteLattice.le_top _ (completeLatticeOfInf _ isGLB_sInf) (discrete C)
      · intro X S _
        apply Set.mem_univ)
    (trivial C)
    (by
      apply le_antisymm
      · intro X S hS
        rw [trivial_covering] at hS
        apply covering_of_eq_top _ hS
      · 

Proof state:
case a
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ ⊥ ≤ trivial C

Next tactic:
exact @CompleteLattice.bot_le _ (completeLatticeOfInf _ isGLB_sInf) (trivial C)
theorem bot_covers (S : Sieve X) (f : Y ⟶ X) : (⊥ : GrothendieckTopology C).Covers S f ↔ S f := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R : Sieve X
J : GrothendieckTopology C
S : Sieve X
f : Y ⟶ X
⊢ Covers ⊥ S f ↔ S.arrows f

Next tactic:
rw [covers_iff, bot_covering, ← Sieve.pullback_eq_top_iff_mem]
@[simp]
theorem top_covers (S : Sieve X) (f : Y ⟶ X) : (⊤ : GrothendieckTopology C).Covers S f := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S✝ R : Sieve X
J : GrothendieckTopology C
S : Sieve X
f : Y ⟶ X
⊢ Covers ⊤ S f

Next tactic:
simp [covers_iff]
/-- The dense Grothendieck topology.

See https://ncatlab.org/nlab/show/dense+topology, or [MM92] Chapter III, Section 2, example (e).
-/
def dense : GrothendieckTopology C
    where
  sieves X S := ∀ {Y : C} (f : Y ⟶ X), ∃ (Z : _) (g : Z ⟶ Y), S (g ≫ f)
  top_mem' X Y f := ⟨Y, 𝟙 Y, ⟨⟩⟩
  pullback_stable' := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X Y : C
S R : Sieve X
J : GrothendieckTopology C
⊢ ∀ ⦃X Y : C⦄ ⦃S : Sieve X⦄ (f : Y ⟶ X),
    S ∈ (fun X S => ∀ {Y : C} (f : Y ⟶ X), ∃ Z g, S.arrows (g ≫ f)) X →
      Sieve.pullback f S ∈ (fun X S => ∀ {Y : C} (f : Y ⟶ X), ∃ Z g, S.arrows (g ≫ f)) Y

Next tactic:
intro X Y S h H Z f
/-- The dense Grothendieck topology.

See https://ncatlab.org/nlab/show/dense+topology, or [MM92] Chapter III, Section 2, example (e).
-/
def dense : GrothendieckTopology C
    where
  sieves X S := ∀ {Y : C} (f : Y ⟶ X), ∃ (Z : _) (g : Z ⟶ Y), S (g ≫ f)
  top_mem' X Y f := ⟨Y, 𝟙 Y, ⟨⟩⟩
  pullback_stable' := by
    intro X Y S h H Z f
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ : C
S✝ R : Sieve X✝
J : GrothendieckTopology C
X Y : C
S : Sieve X
h : Y ⟶ X
H : S ∈ (fun X S => ∀ {Y : C} (f : Y ⟶ X), ∃ Z g, S.arrows (g ≫ f)) X
Z : C
f : Z ⟶ Y
⊢ ∃ Z_1 g, (Sieve.pullback h S).arrows (g ≫ f)

Next tactic:
rcases H (f ≫ h) with ⟨W, g, H'⟩
/-- The dense Grothendieck topology.

See https://ncatlab.org/nlab/show/dense+topology, or [MM92] Chapter III, Section 2, example (e).
-/
def dense : GrothendieckTopology C
    where
  sieves X S := ∀ {Y : C} (f : Y ⟶ X), ∃ (Z : _) (g : Z ⟶ Y), S (g ≫ f)
  top_mem' X Y f := ⟨Y, 𝟙 Y, ⟨⟩⟩
  pullback_stable' := by
    intro X Y S h H Z f
    rcases H (f ≫ h) with ⟨W, g, H'⟩
    

Proof state:
case intro.intro
C : Type u
inst✝ : Category.{v, u} C
X✝ Y✝ : C
S✝ R : Sieve X✝
J : GrothendieckTopology C
X Y : C
S : Sieve X
h : Y ⟶ X
H : S ∈ (fun X S => ∀ {Y : C} (f : Y ⟶ X), ∃ Z g, S.arrows (g ≫ f)) X
Z : C
f : Z ⟶ Y
W : C
g : W ⟶ Z
H' : S.arrows (g ≫ f ≫ h)
⊢ ∃ Z_1 g, (Sieve.pullback h S).arrows (g ≫ f)

Next tactic:
exact ⟨W, g, by simpa⟩