l3lab/ntp-mathlib huggingface dataset:
theorem CauSeq.cauchySeq (f : CauSeq β norm) : CauchySeq f := by
  refine' cauchy_iff.2 ⟨by infer_instance, fun s hs => _⟩
  rcases mem_uniformity_dist.1 hs with ⟨ε, ⟨hε, hεs⟩⟩
  cases' CauSeq.cauchy₂ f hε with N hN
  exists { n | n ≥ N }.image f
  simp only [exists_prop, mem_atTop_sets, mem_map, mem_image, ge_iff_le, mem_setOf_eq]
  constructor
  · exists N
    intro b hb
    exists b
  · rintro ⟨a, b⟩ ⟨⟨a', ⟨ha'1, ha'2⟩⟩, ⟨b', ⟨hb'1, hb'2⟩⟩⟩
    dsimp at ha'1 ha'2 hb'1 hb'2
    rw [← ha'2, ← hb'2]
    

Proof state:
case intro.intro.intro.right.mk.intro.intro.intro.intro.intro
β : Type v
inst✝ : NormedField β
f : CauSeq β norm
s : Set (β × β)
hs : s ∈ uniformity β
ε : ℝ
hε : ε > 0
hεs : ∀ {a b : β}, dist a b < ε → (a, b) ∈ s
N : ℕ
hN : ∀ j ≥ N, ∀ k ≥ N, ‖↑f j - ↑f k‖ < ε
a b : β
a' : ℕ
ha'1 : N ≤ a'
ha'2 : ↑f a' = a
b' : ℕ
hb'1 : N ≤ b'
hb'2 : ↑f b' = b
⊢ (↑f a', ↑f b') ∈ s

Next tactic:
apply hεs
theorem CauSeq.cauchySeq (f : CauSeq β norm) : CauchySeq f := by
  refine' cauchy_iff.2 ⟨by infer_instance, fun s hs => _⟩
  rcases mem_uniformity_dist.1 hs with ⟨ε, ⟨hε, hεs⟩⟩
  cases' CauSeq.cauchy₂ f hε with N hN
  exists { n | n ≥ N }.image f
  simp only [exists_prop, mem_atTop_sets, mem_map, mem_image, ge_iff_le, mem_setOf_eq]
  constructor
  · exists N
    intro b hb
    exists b
  · rintro ⟨a, b⟩ ⟨⟨a', ⟨ha'1, ha'2⟩⟩, ⟨b', ⟨hb'1, hb'2⟩⟩⟩
    dsimp at ha'1 ha'2 hb'1 hb'2
    rw [← ha'2, ← hb'2]
    apply hεs
    

Proof state:
case intro.intro.intro.right.mk.intro.intro.intro.intro.intro.a
β : Type v
inst✝ : NormedField β
f : CauSeq β norm
s : Set (β × β)
hs : s ∈ uniformity β
ε : ℝ
hε : ε > 0
hεs : ∀ {a b : β}, dist a b < ε → (a, b) ∈ s
N : ℕ
hN : ∀ j ≥ N, ∀ k ≥ N, ‖↑f j - ↑f k‖ < ε
a b : β
a' : ℕ
ha'1 : N ≤ a'
ha'2 : ↑f a' = a
b' : ℕ
hb'1 : N ≤ b'
hb'2 : ↑f b' = b
⊢ dist (↑f a') (↑f b') < ε

Next tactic:
rw [dist_eq_norm]
theorem CauSeq.cauchySeq (f : CauSeq β norm) : CauchySeq f := by
  refine' cauchy_iff.2 ⟨by infer_instance, fun s hs => _⟩
  rcases mem_uniformity_dist.1 hs with ⟨ε, ⟨hε, hεs⟩⟩
  cases' CauSeq.cauchy₂ f hε with N hN
  exists { n | n ≥ N }.image f
  simp only [exists_prop, mem_atTop_sets, mem_map, mem_image, ge_iff_le, mem_setOf_eq]
  constructor
  · exists N
    intro b hb
    exists b
  · rintro ⟨a, b⟩ ⟨⟨a', ⟨ha'1, ha'2⟩⟩, ⟨b', ⟨hb'1, hb'2⟩⟩⟩
    dsimp at ha'1 ha'2 hb'1 hb'2
    rw [← ha'2, ← hb'2]
    apply hεs
    rw [dist_eq_norm]
    

Proof state:
case intro.intro.intro.right.mk.intro.intro.intro.intro.intro.a
β : Type v
inst✝ : NormedField β
f : CauSeq β norm
s : Set (β × β)
hs : s ∈ uniformity β
ε : ℝ
hε : ε > 0
hεs : ∀ {a b : β}, dist a b < ε → (a, b) ∈ s
N : ℕ
hN : ∀ j ≥ N, ∀ k ≥ N, ‖↑f j - ↑f k‖ < ε
a b : β
a' : ℕ
ha'1 : N ≤ a'
ha'2 : ↑f a' = a
b' : ℕ
hb'1 : N ≤ b'
hb'2 : ↑f b' = b
⊢ ‖↑f a' - ↑f b'‖ < ε

Next tactic:
apply hN
theorem CauSeq.cauchySeq (f : CauSeq β norm) : CauchySeq f := by
  refine' cauchy_iff.2 ⟨by infer_instance, fun s hs => _⟩
  rcases mem_uniformity_dist.1 hs with ⟨ε, ⟨hε, hεs⟩⟩
  cases' CauSeq.cauchy₂ f hε with N hN
  exists { n | n ≥ N }.image f
  simp only [exists_prop, mem_atTop_sets, mem_map, mem_image, ge_iff_le, mem_setOf_eq]
  constructor
  · exists N
    intro b hb
    exists b
  · rintro ⟨a, b⟩ ⟨⟨a', ⟨ha'1, ha'2⟩⟩, ⟨b', ⟨hb'1, hb'2⟩⟩⟩
    dsimp at ha'1 ha'2 hb'1 hb'2
    rw [← ha'2, ← hb'2]
    apply hεs
    rw [dist_eq_norm]
    apply hN <;> 

Proof state:
case intro.intro.intro.right.mk.intro.intro.intro.intro.intro.a.a
β : Type v
inst✝ : NormedField β
f : CauSeq β norm
s : Set (β × β)
hs : s ∈ uniformity β
ε : ℝ
hε : ε > 0
hεs : ∀ {a b : β}, dist a b < ε → (a, b) ∈ s
N : ℕ
hN : ∀ j ≥ N, ∀ k ≥ N, ‖↑f j - ↑f k‖ < ε
a b : β
a' : ℕ
ha'1 : N ≤ a'
ha'2 : ↑f a' = a
b' : ℕ
hb'1 : N ≤ b'
hb'2 : ↑f b' = b
⊢ a' ≥ N

Next tactic:
assumption
theorem CauSeq.cauchySeq (f : CauSeq β norm) : CauchySeq f := by
  refine' cauchy_iff.2 ⟨by infer_instance, fun s hs => _⟩
  rcases mem_uniformity_dist.1 hs with ⟨ε, ⟨hε, hεs⟩⟩
  cases' CauSeq.cauchy₂ f hε with N hN
  exists { n | n ≥ N }.image f
  simp only [exists_prop, mem_atTop_sets, mem_map, mem_image, ge_iff_le, mem_setOf_eq]
  constructor
  · exists N
    intro b hb
    exists b
  · rintro ⟨a, b⟩ ⟨⟨a', ⟨ha'1, ha'2⟩⟩, ⟨b', ⟨hb'1, hb'2⟩⟩⟩
    dsimp at ha'1 ha'2 hb'1 hb'2
    rw [← ha'2, ← hb'2]
    apply hεs
    rw [dist_eq_norm]
    apply hN <;> 

Proof state:
case intro.intro.intro.right.mk.intro.intro.intro.intro.intro.a.a
β : Type v
inst✝ : NormedField β
f : CauSeq β norm
s : Set (β × β)
hs : s ∈ uniformity β
ε : ℝ
hε : ε > 0
hεs : ∀ {a b : β}, dist a b < ε → (a, b) ∈ s
N : ℕ
hN : ∀ j ≥ N, ∀ k ≥ N, ‖↑f j - ↑f k‖ < ε
a b : β
a' : ℕ
ha'1 : N ≤ a'
ha'2 : ↑f a' = a
b' : ℕ
hb'1 : N ≤ b'
hb'2 : ↑f b' = b
⊢ b' ≥ N

Next tactic:
assumption
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  

Proof state:
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
⊢ CompleteSpace β

Next tactic:
apply complete_of_cauchySeq_tendsto
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  

Proof state:
case a
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
⊢ ∀ (u : ℕ → β), CauchySeq u → ∃ a, Tendsto u atTop (𝓝 a)

Next tactic:
intro u hu
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  intro u hu
  

Proof state:
case a
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
u : ℕ → β
hu : CauchySeq u
⊢ ∃ a, Tendsto u atTop (𝓝 a)

Next tactic:
have C : IsCauSeq norm u := isCauSeq_iff_cauchySeq.2 hu
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  intro u hu
  have C : IsCauSeq norm u := isCauSeq_iff_cauchySeq.2 hu
  

Proof state:
case a
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
u : ℕ → β
hu : CauchySeq u
C : IsCauSeq norm u
⊢ ∃ a, Tendsto u atTop (𝓝 a)

Next tactic:
exists CauSeq.lim ⟨u, C⟩
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  intro u hu
  have C : IsCauSeq norm u := isCauSeq_iff_cauchySeq.2 hu
  exists CauSeq.lim ⟨u, C⟩
  

Proof state:
case a
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
u : ℕ → β
hu : CauchySeq u
C : IsCauSeq norm u
⊢ Tendsto u atTop (𝓝 (CauSeq.lim { val := u, property := C }))

Next tactic:
rw [Metric.tendsto_atTop]
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  intro u hu
  have C : IsCauSeq norm u := isCauSeq_iff_cauchySeq.2 hu
  exists CauSeq.lim ⟨u, C⟩
  rw [Metric.tendsto_atTop]
  

Proof state:
case a
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
u : ℕ → β
hu : CauchySeq u
C : IsCauSeq norm u
⊢ ∀ ε > 0, ∃ N, ∀ n ≥ N, dist (u n) (CauSeq.lim { val := u, property := C }) < ε

Next tactic:
intro ε εpos
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  intro u hu
  have C : IsCauSeq norm u := isCauSeq_iff_cauchySeq.2 hu
  exists CauSeq.lim ⟨u, C⟩
  rw [Metric.tendsto_atTop]
  intro ε εpos
  

Proof state:
case a
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
u : ℕ → β
hu : CauchySeq u
C : IsCauSeq norm u
ε : ℝ
εpos : ε > 0
⊢ ∃ N, ∀ n ≥ N, dist (u n) (CauSeq.lim { val := u, property := C }) < ε

Next tactic:
cases' (CauSeq.equiv_lim ⟨u, C⟩) _ εpos with N hN
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  intro u hu
  have C : IsCauSeq norm u := isCauSeq_iff_cauchySeq.2 hu
  exists CauSeq.lim ⟨u, C⟩
  rw [Metric.tendsto_atTop]
  intro ε εpos
  cases' (CauSeq.equiv_lim ⟨u, C⟩) _ εpos with N hN
  

Proof state:
case a.intro
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
u : ℕ → β
hu : CauchySeq u
C : IsCauSeq norm u
ε : ℝ
εpos : ε > 0
N : ℕ
hN : ∀ j ≥ N, ‖↑({ val := u, property := C } - CauSeq.const norm (CauSeq.lim { val := u, property := C })) j‖ < ε
⊢ ∃ N, ∀ n ≥ N, dist (u n) (CauSeq.lim { val := u, property := C }) < ε

Next tactic:
exists N
/-- A complete normed field is complete as a metric space, as Cauchy sequences converge by
assumption and this suffices to characterize completeness. -/
instance (priority := 100) completeSpace_of_cauSeq_isComplete [CauSeq.IsComplete β norm] :
    CompleteSpace β := by
  apply complete_of_cauchySeq_tendsto
  intro u hu
  have C : IsCauSeq norm u := isCauSeq_iff_cauchySeq.2 hu
  exists CauSeq.lim ⟨u, C⟩
  rw [Metric.tendsto_atTop]
  intro ε εpos
  cases' (CauSeq.equiv_lim ⟨u, C⟩) _ εpos with N hN
  exists N
  

Proof state:
case a.intro
β : Type v
inst✝¹ : NormedField β
inst✝ : CauSeq.IsComplete β norm
u : ℕ → β
hu : CauchySeq u
C : IsCauSeq norm u
ε : ℝ
εpos : ε > 0
N : ℕ
hN : ∀ j ≥ N, ‖↑({ val := u, property := C } - CauSeq.const norm (CauSeq.lim { val := u, property := C })) j‖ < ε
⊢ ∀ n ≥ N, dist (u n) (CauSeq.lim { val := u, property := C }) < ε

Next tactic:
simpa [dist_eq_norm] using hN
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
U : TopologicalSpace.Opens ↑X
s : Sieve U
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) U
⊢ Presieve.IsSheafFor (F ⋙ coyoneda.obj (op c)) s.arrows

Next tactic:
obtain rfl | hne := eq_or_ne U ⊥
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · 

Proof state:
case inl
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊥
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊥
⊢ Presieve.IsSheafFor (F ⋙ coyoneda.obj (op c)) s.arrows

Next tactic:
intro _ _
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    

Proof state:
case inl
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊥
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊥
x✝ : Presieve.FamilyOfElements (F ⋙ coyoneda.obj (op c)) s.arrows
a✝ : Presieve.FamilyOfElements.Compatible x✝
⊢ ∃! t, Presieve.FamilyOfElements.IsAmalgamation x✝ t

Next tactic:
rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · 

Proof state:
case inl
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊥
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊥
x✝ : Presieve.FamilyOfElements (F ⋙ coyoneda.obj (op c)) s.arrows
a✝ : Presieve.FamilyOfElements.Compatible x✝
⊢ ∃ x, Presieve.FamilyOfElements.IsAmalgamation x✝ x

Next tactic:
refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      

Proof state:
case inl
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊥
hs✝ : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊥
x✝ : Presieve.FamilyOfElements (F ⋙ coyoneda.obj (op c)) s.arrows
a✝ : Presieve.FamilyOfElements.Compatible x✝
U : TopologicalSpace.Opens ↑X
hU : U ⟶ ⊥
hs : s.arrows hU
⊢ IsTerminal (F.obj (op U))

Next tactic:
rwa [le_bot_iff.1 hU.le]
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊥
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊥
x✝ : Presieve.FamilyOfElements (F ⋙ coyoneda.obj (op c)) s.arrows
a✝ : Presieve.FamilyOfElements.Compatible x✝
⊢ ∀ (x x_1 : (F ⋙ coyoneda.obj (op c)).obj (op ⊥)), x = x_1

Next tactic:
apply it.hom_ext
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · 

Proof state:
case inr
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
U : TopologicalSpace.Opens ↑X
s : Sieve U
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) U
hne : U ≠ ⊥
⊢ Presieve.IsSheafFor (F ⋙ coyoneda.obj (op c)) s.arrows

Next tactic:
convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    

Proof state:
case h.e'_5.h.h.e'_4
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
U : TopologicalSpace.Opens ↑X
s : Sieve U
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) U
hne : U ≠ ⊥
⊢ s = ⊤

Next tactic:
rw [← Sieve.id_mem_iff_eq_top]
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    

Proof state:
case h.e'_5.h.h.e'_4
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
U : TopologicalSpace.Opens ↑X
s : Sieve U
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) U
hne : U ≠ ⊥
⊢ s.arrows (𝟙 U)

Next tactic:
have := (U.eq_bot_or_top hind).resolve_left hne
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    have := (U.eq_bot_or_top hind).resolve_left hne
    

Proof state:
case h.e'_5.h.h.e'_4
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
U : TopologicalSpace.Opens ↑X
s : Sieve U
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) U
hne : U ≠ ⊥
this : U = ⊤
⊢ s.arrows (𝟙 U)

Next tactic:
subst this
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    have := (U.eq_bot_or_top hind).resolve_left hne
    subst this
    

Proof state:
case h.e'_5.h.h.e'_4
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊤
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊤
hne : ⊤ ≠ ⊥
⊢ s.arrows (𝟙 ⊤)

Next tactic:
obtain he | ⟨⟨x⟩⟩ := isEmpty_or_nonempty X
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    have := (U.eq_bot_or_top hind).resolve_left hne
    subst this
    obtain he | ⟨⟨x⟩⟩ := isEmpty_or_nonempty X
    · 

Proof state:
case h.e'_5.h.h.e'_4.inl
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊤
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊤
hne : ⊤ ≠ ⊥
he : IsEmpty ↑X
⊢ s.arrows (𝟙 ⊤)

Next tactic:
exact (hne <| SetLike.ext'_iff.2 <| Set.univ_eq_empty_iff.2 he).elim
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    have := (U.eq_bot_or_top hind).resolve_left hne
    subst this
    obtain he | ⟨⟨x⟩⟩ := isEmpty_or_nonempty X
    · exact (hne <| SetLike.ext'_iff.2 <| Set.univ_eq_empty_iff.2 he).elim
    

Proof state:
case h.e'_5.h.h.e'_4.inr.intro
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊤
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊤
hne : ⊤ ≠ ⊥
x : ↑X
⊢ s.arrows (𝟙 ⊤)

Next tactic:
obtain ⟨U, f, hf, hm⟩ := hs x _root_.trivial
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    have := (U.eq_bot_or_top hind).resolve_left hne
    subst this
    obtain he | ⟨⟨x⟩⟩ := isEmpty_or_nonempty X
    · exact (hne <| SetLike.ext'_iff.2 <| Set.univ_eq_empty_iff.2 he).elim
    obtain ⟨U, f, hf, hm⟩ := hs x _root_.trivial
    

Proof state:
case h.e'_5.h.h.e'_4.inr.intro.intro.intro.intro
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊤
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊤
hne : ⊤ ≠ ⊥
x : ↑X
U : TopologicalSpace.Opens ↑X
f : U ⟶ ⊤
hf : s.arrows f
hm : x ∈ U
⊢ s.arrows (𝟙 ⊤)

Next tactic:
obtain rfl | rfl := U.eq_bot_or_top hind
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    have := (U.eq_bot_or_top hind).resolve_left hne
    subst this
    obtain he | ⟨⟨x⟩⟩ := isEmpty_or_nonempty X
    · exact (hne <| SetLike.ext'_iff.2 <| Set.univ_eq_empty_iff.2 he).elim
    obtain ⟨U, f, hf, hm⟩ := hs x _root_.trivial
    obtain rfl | rfl := U.eq_bot_or_top hind
    · 

Proof state:
case h.e'_5.h.h.e'_4.inr.intro.intro.intro.intro.inl
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊤
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊤
hne : ⊤ ≠ ⊥
x : ↑X
f : ⊥ ⟶ ⊤
hf : s.arrows f
hm : x ∈ ⊥
⊢ s.arrows (𝟙 ⊤)

Next tactic:
cases hm
theorem isSheaf_of_isTerminal_of_indiscrete {X : TopCat.{w}} (hind : X.str = ⊤) (F : Presheaf C X)
    (it : IsTerminal <| F.obj <| op ⊥) : F.IsSheaf := fun c U s hs => by
  obtain rfl | hne := eq_or_ne U ⊥
  · intro _ _
    rw [@exists_unique_iff_exists _ ⟨fun _ _ => _⟩]
    · refine' ⟨it.from _, fun U hU hs => IsTerminal.hom_ext _ _ _⟩
      rwa [le_bot_iff.1 hU.le]
    · apply it.hom_ext
  · convert Presieve.isSheafFor_top_sieve (F ⋙ coyoneda.obj (@op C c))
    rw [← Sieve.id_mem_iff_eq_top]
    have := (U.eq_bot_or_top hind).resolve_left hne
    subst this
    obtain he | ⟨⟨x⟩⟩ := isEmpty_or_nonempty X
    · exact (hne <| SetLike.ext'_iff.2 <| Set.univ_eq_empty_iff.2 he).elim
    obtain ⟨U, f, hf, hm⟩ := hs x _root_.trivial
    obtain rfl | rfl := U.eq_bot_or_top hind
    · cases hm
    · 

Proof state:
case h.e'_5.h.h.e'_4.inr.intro.intro.intro.intro.inr
C : Type u
inst✝ : Category.{v, u} C
X : TopCat
hind : X.str = ⊤
F : Presheaf C X
it : IsTerminal (F.obj (op ⊥))
c : C
s : Sieve ⊤
hs : s ∈ GrothendieckTopology.sieves (Opens.grothendieckTopology ↑X) ⊤
hne : ⊤ ≠ ⊥
x : ↑X
f : ⊤ ⟶ ⊤
hf : s.arrows f
hm : x ∈ ⊤
⊢ s.arrows (𝟙 ⊤)

Next tactic:
convert hf