l3lab/ntp-mathlib huggingface dataset:
/-- To show that a statement `P` holds for all open subsets of all schemes, it suffices to show that
1. In any scheme `X`, if `P` holds for an open cover of `U`, then `P` holds for `U`.
2. For an open immerison `f : X ⟶ Y`, if `P` holds for the entire space of `X`, then `P` holds for
  the image of `f`.
3. `P` holds for the entire space of an affine scheme.
-/
theorem reduce_to_affine_global (P : ∀ (X : Scheme) (_ : Opens X.carrier), Prop)
    (h₁ : ∀ (X : Scheme) (U : Opens X.carrier),
      (∀ x : U, ∃ (V : _) (_ : x.1 ∈ V) (_ : V ⟶ U), P X V) → P X U)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [hf : IsOpenImmersion f],
      ∃ (U : Set X.carrier) (V : Set Y.carrier) (hU : U = ⊤) (hV : V = Set.range f.1.base),
        P X ⟨U, hU.symm ▸ isOpen_univ⟩ → P Y ⟨V, hV.symm ▸ hf.base_open.open_range⟩)
    (h₃ : ∀ R : CommRingCat, P (Scheme.Spec.obj <| op R) ⊤) :
    ∀ (X : Scheme) (U : Opens X.carrier), P X U := by
  intro X U
  apply h₁
  intro x
  obtain ⟨_, ⟨j, rfl⟩, hx, i⟩ :=
    X.affineBasisCover_is_basis.exists_subset_of_mem_open (SetLike.mem_coe.2 x.prop) U.isOpen
  let U' : Opens _ := ⟨_, (X.affineBasisCover.IsOpen j).base_open.open_range⟩
  let i' : U' ⟶ U := homOfLE i
  

Proof state:
case a.intro.intro.intro.intro
X✝ : Scheme
P : (X : Scheme) → Opens ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (X : Scheme) (U : Opens ↑↑X.toPresheafedSpace), (∀ (x : ↥U), ∃ V, ∃ (_ : ↑x ∈ V), ∃ x, P X V) → P X U
h₂ :
  ∀ {X Y : Scheme} (f : X ⟶ Y) [hf : IsOpenImmersion f],
    ∃ U V,
      ∃ (hU : U = ⊤) (hV : V = Set.range ⇑f.val.base),
        P X { carrier := U, is_open' := (_ : IsOpen U) } → P Y { carrier := V, is_open' := (_ : IsOpen V) }
h₃ : ∀ (R : CommRingCat), P (Scheme.Spec.obj (op R)) ⊤
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
x : ↥U
j : (Scheme.affineBasisCover X).J
hx : ↑x ∈ Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base
i : Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base ⊆ ↑U
U' : Opens ((forget TopCat).obj ↑X.toPresheafedSpace) :=
  { carrier := Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base,
    is_open' := (_ : IsOpen (Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base)) }
i' : U' ⟶ U := homOfLE i
⊢ ∃ V, ∃ (_ : ↑x ∈ V), ∃ x, P X V

Next tactic:
refine' ⟨U', hx, i', _⟩
/-- To show that a statement `P` holds for all open subsets of all schemes, it suffices to show that
1. In any scheme `X`, if `P` holds for an open cover of `U`, then `P` holds for `U`.
2. For an open immerison `f : X ⟶ Y`, if `P` holds for the entire space of `X`, then `P` holds for
  the image of `f`.
3. `P` holds for the entire space of an affine scheme.
-/
theorem reduce_to_affine_global (P : ∀ (X : Scheme) (_ : Opens X.carrier), Prop)
    (h₁ : ∀ (X : Scheme) (U : Opens X.carrier),
      (∀ x : U, ∃ (V : _) (_ : x.1 ∈ V) (_ : V ⟶ U), P X V) → P X U)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [hf : IsOpenImmersion f],
      ∃ (U : Set X.carrier) (V : Set Y.carrier) (hU : U = ⊤) (hV : V = Set.range f.1.base),
        P X ⟨U, hU.symm ▸ isOpen_univ⟩ → P Y ⟨V, hV.symm ▸ hf.base_open.open_range⟩)
    (h₃ : ∀ R : CommRingCat, P (Scheme.Spec.obj <| op R) ⊤) :
    ∀ (X : Scheme) (U : Opens X.carrier), P X U := by
  intro X U
  apply h₁
  intro x
  obtain ⟨_, ⟨j, rfl⟩, hx, i⟩ :=
    X.affineBasisCover_is_basis.exists_subset_of_mem_open (SetLike.mem_coe.2 x.prop) U.isOpen
  let U' : Opens _ := ⟨_, (X.affineBasisCover.IsOpen j).base_open.open_range⟩
  let i' : U' ⟶ U := homOfLE i
  refine' ⟨U', hx, i', _⟩
  

Proof state:
case a.intro.intro.intro.intro
X✝ : Scheme
P : (X : Scheme) → Opens ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (X : Scheme) (U : Opens ↑↑X.toPresheafedSpace), (∀ (x : ↥U), ∃ V, ∃ (_ : ↑x ∈ V), ∃ x, P X V) → P X U
h₂ :
  ∀ {X Y : Scheme} (f : X ⟶ Y) [hf : IsOpenImmersion f],
    ∃ U V,
      ∃ (hU : U = ⊤) (hV : V = Set.range ⇑f.val.base),
        P X { carrier := U, is_open' := (_ : IsOpen U) } → P Y { carrier := V, is_open' := (_ : IsOpen V) }
h₃ : ∀ (R : CommRingCat), P (Scheme.Spec.obj (op R)) ⊤
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
x : ↥U
j : (Scheme.affineBasisCover X).J
hx : ↑x ∈ Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base
i : Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base ⊆ ↑U
U' : Opens ((forget TopCat).obj ↑X.toPresheafedSpace) :=
  { carrier := Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base,
    is_open' := (_ : IsOpen (Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base)) }
i' : U' ⟶ U := homOfLE i
⊢ P X U'

Next tactic:
obtain ⟨_, _, rfl, rfl, h₂'⟩ := h₂ (X.affineBasisCover.map j)
/-- To show that a statement `P` holds for all open subsets of all schemes, it suffices to show that
1. In any scheme `X`, if `P` holds for an open cover of `U`, then `P` holds for `U`.
2. For an open immerison `f : X ⟶ Y`, if `P` holds for the entire space of `X`, then `P` holds for
  the image of `f`.
3. `P` holds for the entire space of an affine scheme.
-/
theorem reduce_to_affine_global (P : ∀ (X : Scheme) (_ : Opens X.carrier), Prop)
    (h₁ : ∀ (X : Scheme) (U : Opens X.carrier),
      (∀ x : U, ∃ (V : _) (_ : x.1 ∈ V) (_ : V ⟶ U), P X V) → P X U)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [hf : IsOpenImmersion f],
      ∃ (U : Set X.carrier) (V : Set Y.carrier) (hU : U = ⊤) (hV : V = Set.range f.1.base),
        P X ⟨U, hU.symm ▸ isOpen_univ⟩ → P Y ⟨V, hV.symm ▸ hf.base_open.open_range⟩)
    (h₃ : ∀ R : CommRingCat, P (Scheme.Spec.obj <| op R) ⊤) :
    ∀ (X : Scheme) (U : Opens X.carrier), P X U := by
  intro X U
  apply h₁
  intro x
  obtain ⟨_, ⟨j, rfl⟩, hx, i⟩ :=
    X.affineBasisCover_is_basis.exists_subset_of_mem_open (SetLike.mem_coe.2 x.prop) U.isOpen
  let U' : Opens _ := ⟨_, (X.affineBasisCover.IsOpen j).base_open.open_range⟩
  let i' : U' ⟶ U := homOfLE i
  refine' ⟨U', hx, i', _⟩
  obtain ⟨_, _, rfl, rfl, h₂'⟩ := h₂ (X.affineBasisCover.map j)
  

Proof state:
case a.intro.intro.intro.intro.intro.intro.intro.intro
X✝ : Scheme
P : (X : Scheme) → Opens ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (X : Scheme) (U : Opens ↑↑X.toPresheafedSpace), (∀ (x : ↥U), ∃ V, ∃ (_ : ↑x ∈ V), ∃ x, P X V) → P X U
h₂ :
  ∀ {X Y : Scheme} (f : X ⟶ Y) [hf : IsOpenImmersion f],
    ∃ U V,
      ∃ (hU : U = ⊤) (hV : V = Set.range ⇑f.val.base),
        P X { carrier := U, is_open' := (_ : IsOpen U) } → P Y { carrier := V, is_open' := (_ : IsOpen V) }
h₃ : ∀ (R : CommRingCat), P (Scheme.Spec.obj (op R)) ⊤
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
x : ↥U
j : (Scheme.affineBasisCover X).J
hx : ↑x ∈ Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base
i : Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base ⊆ ↑U
U' : Opens ((forget TopCat).obj ↑X.toPresheafedSpace) :=
  { carrier := Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base,
    is_open' := (_ : IsOpen (Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base)) }
i' : U' ⟶ U := homOfLE i
h₂' :
  P (Scheme.OpenCover.obj (Scheme.affineBasisCover X) j) { carrier := ⊤, is_open' := (_ : IsOpen ⊤) } →
    P X
      { carrier := Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base,
        is_open' := (_ : IsOpen (Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base)) }
⊢ P X U'

Next tactic:
apply h₂'
/-- To show that a statement `P` holds for all open subsets of all schemes, it suffices to show that
1. In any scheme `X`, if `P` holds for an open cover of `U`, then `P` holds for `U`.
2. For an open immerison `f : X ⟶ Y`, if `P` holds for the entire space of `X`, then `P` holds for
  the image of `f`.
3. `P` holds for the entire space of an affine scheme.
-/
theorem reduce_to_affine_global (P : ∀ (X : Scheme) (_ : Opens X.carrier), Prop)
    (h₁ : ∀ (X : Scheme) (U : Opens X.carrier),
      (∀ x : U, ∃ (V : _) (_ : x.1 ∈ V) (_ : V ⟶ U), P X V) → P X U)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [hf : IsOpenImmersion f],
      ∃ (U : Set X.carrier) (V : Set Y.carrier) (hU : U = ⊤) (hV : V = Set.range f.1.base),
        P X ⟨U, hU.symm ▸ isOpen_univ⟩ → P Y ⟨V, hV.symm ▸ hf.base_open.open_range⟩)
    (h₃ : ∀ R : CommRingCat, P (Scheme.Spec.obj <| op R) ⊤) :
    ∀ (X : Scheme) (U : Opens X.carrier), P X U := by
  intro X U
  apply h₁
  intro x
  obtain ⟨_, ⟨j, rfl⟩, hx, i⟩ :=
    X.affineBasisCover_is_basis.exists_subset_of_mem_open (SetLike.mem_coe.2 x.prop) U.isOpen
  let U' : Opens _ := ⟨_, (X.affineBasisCover.IsOpen j).base_open.open_range⟩
  let i' : U' ⟶ U := homOfLE i
  refine' ⟨U', hx, i', _⟩
  obtain ⟨_, _, rfl, rfl, h₂'⟩ := h₂ (X.affineBasisCover.map j)
  apply h₂'
  

Proof state:
case a.intro.intro.intro.intro.intro.intro.intro.intro
X✝ : Scheme
P : (X : Scheme) → Opens ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (X : Scheme) (U : Opens ↑↑X.toPresheafedSpace), (∀ (x : ↥U), ∃ V, ∃ (_ : ↑x ∈ V), ∃ x, P X V) → P X U
h₂ :
  ∀ {X Y : Scheme} (f : X ⟶ Y) [hf : IsOpenImmersion f],
    ∃ U V,
      ∃ (hU : U = ⊤) (hV : V = Set.range ⇑f.val.base),
        P X { carrier := U, is_open' := (_ : IsOpen U) } → P Y { carrier := V, is_open' := (_ : IsOpen V) }
h₃ : ∀ (R : CommRingCat), P (Scheme.Spec.obj (op R)) ⊤
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
x : ↥U
j : (Scheme.affineBasisCover X).J
hx : ↑x ∈ Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base
i : Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base ⊆ ↑U
U' : Opens ((forget TopCat).obj ↑X.toPresheafedSpace) :=
  { carrier := Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base,
    is_open' := (_ : IsOpen (Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base)) }
i' : U' ⟶ U := homOfLE i
h₂' :
  P (Scheme.OpenCover.obj (Scheme.affineBasisCover X) j) { carrier := ⊤, is_open' := (_ : IsOpen ⊤) } →
    P X
      { carrier := Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base,
        is_open' := (_ : IsOpen (Set.range ⇑(Scheme.OpenCover.map (Scheme.affineBasisCover X) j).val.base)) }
⊢ P (Scheme.OpenCover.obj (Scheme.affineBasisCover X) j) { carrier := ⊤, is_open' := (_ : IsOpen ⊤) }

Next tactic:
apply h₃
theorem reduce_to_affine_nbhd (P : ∀ (X : Scheme) (_ : X.carrier), Prop)
    (h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum R), P (Scheme.Spec.obj <| op R) x)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [IsOpenImmersion f] (x : X.carrier), P X x → P Y (f.1.base x)) :
    ∀ (X : Scheme) (x : X.carrier), P X x := by
  

Proof state:
X : Scheme
P : (X : Scheme) → ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum ↑R), P (Scheme.Spec.obj (op R)) x
h₂ : ∀ {X Y : Scheme} (f : X ⟶ Y) [inst : IsOpenImmersion f] (x : ↑↑X.toPresheafedSpace), P X x → P Y (f.val.base x)
⊢ ∀ (X : Scheme) (x : ↑↑X.toPresheafedSpace), P X x

Next tactic:
intro X x
theorem reduce_to_affine_nbhd (P : ∀ (X : Scheme) (_ : X.carrier), Prop)
    (h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum R), P (Scheme.Spec.obj <| op R) x)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [IsOpenImmersion f] (x : X.carrier), P X x → P Y (f.1.base x)) :
    ∀ (X : Scheme) (x : X.carrier), P X x := by
  intro X x
  

Proof state:
X✝ : Scheme
P : (X : Scheme) → ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum ↑R), P (Scheme.Spec.obj (op R)) x
h₂ : ∀ {X Y : Scheme} (f : X ⟶ Y) [inst : IsOpenImmersion f] (x : ↑↑X.toPresheafedSpace), P X x → P Y (f.val.base x)
X : Scheme
x : ↑↑X.toPresheafedSpace
⊢ P X x

Next tactic:
obtain ⟨y, e⟩ := X.affineCover.Covers x
theorem reduce_to_affine_nbhd (P : ∀ (X : Scheme) (_ : X.carrier), Prop)
    (h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum R), P (Scheme.Spec.obj <| op R) x)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [IsOpenImmersion f] (x : X.carrier), P X x → P Y (f.1.base x)) :
    ∀ (X : Scheme) (x : X.carrier), P X x := by
  intro X x
  obtain ⟨y, e⟩ := X.affineCover.Covers x
  

Proof state:
case intro
X✝ : Scheme
P : (X : Scheme) → ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum ↑R), P (Scheme.Spec.obj (op R)) x
h₂ : ∀ {X Y : Scheme} (f : X ⟶ Y) [inst : IsOpenImmersion f] (x : ↑↑X.toPresheafedSpace), P X x → P Y (f.val.base x)
X : Scheme
x : ↑↑X.toPresheafedSpace
y :
  (forget TopCat).obj
    ↑(Scheme.OpenCover.obj (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)).toPresheafedSpace
e : (Scheme.OpenCover.map (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)).val.base y = x
⊢ P X x

Next tactic:
convert h₂ (X.affineCover.map (X.affineCover.f x)) y _
theorem reduce_to_affine_nbhd (P : ∀ (X : Scheme) (_ : X.carrier), Prop)
    (h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum R), P (Scheme.Spec.obj <| op R) x)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [IsOpenImmersion f] (x : X.carrier), P X x → P Y (f.1.base x)) :
    ∀ (X : Scheme) (x : X.carrier), P X x := by
  intro X x
  obtain ⟨y, e⟩ := X.affineCover.Covers x
  convert h₂ (X.affineCover.map (X.affineCover.f x)) y _
  · 

Proof state:
case h.e'_2
X✝ : Scheme
P : (X : Scheme) → ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum ↑R), P (Scheme.Spec.obj (op R)) x
h₂ : ∀ {X Y : Scheme} (f : X ⟶ Y) [inst : IsOpenImmersion f] (x : ↑↑X.toPresheafedSpace), P X x → P Y (f.val.base x)
X : Scheme
x : ↑↑X.toPresheafedSpace
y :
  (forget TopCat).obj
    ↑(Scheme.OpenCover.obj (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)).toPresheafedSpace
e : (Scheme.OpenCover.map (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)).val.base y = x
⊢ x = (Scheme.OpenCover.map (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)).val.base y

Next tactic:
rw [e]
theorem reduce_to_affine_nbhd (P : ∀ (X : Scheme) (_ : X.carrier), Prop)
    (h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum R), P (Scheme.Spec.obj <| op R) x)
    (h₂ : ∀ {X Y} (f : X ⟶ Y) [IsOpenImmersion f] (x : X.carrier), P X x → P Y (f.1.base x)) :
    ∀ (X : Scheme) (x : X.carrier), P X x := by
  intro X x
  obtain ⟨y, e⟩ := X.affineCover.Covers x
  convert h₂ (X.affineCover.map (X.affineCover.f x)) y _
  · rw [e]
  

Proof state:
case intro
X✝ : Scheme
P : (X : Scheme) → ↑↑X.toPresheafedSpace → Prop
h₁ : ∀ (R : CommRingCat) (x : PrimeSpectrum ↑R), P (Scheme.Spec.obj (op R)) x
h₂ : ∀ {X Y : Scheme} (f : X ⟶ Y) [inst : IsOpenImmersion f] (x : ↑↑X.toPresheafedSpace), P X x → P Y (f.val.base x)
X : Scheme
x : ↑↑X.toPresheafedSpace
y :
  (forget TopCat).obj
    ↑(Scheme.OpenCover.obj (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)).toPresheafedSpace
e : (Scheme.OpenCover.map (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)).val.base y = x
⊢ P (Scheme.OpenCover.obj (Scheme.affineCover X) (Scheme.OpenCover.f (Scheme.affineCover X) x)) y

Next tactic:
apply h₁
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  

Proof state:
X✝ : Scheme
X : Scheme
hX : IsReduced X
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
⊢ s = 0

Next tactic:
apply TopCat.Presheaf.section_ext X.sheaf U
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  

Proof state:
case h
X✝ : Scheme
X : Scheme
hX : IsReduced X
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
⊢ ∀ (x : ↥U),
    (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) 0

Next tactic:
conv => intro x; rw [RingHom.map_zero]
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => 

Proof state:
X✝ : Scheme
X : Scheme
hX : IsReduced X
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
| ∀ (x : ↥U),
    (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) 0

Next tactic:
intro x; rw [RingHom.map_zero]
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => 

Proof state:
X✝ : Scheme
X : Scheme
hX : IsReduced X
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
| ∀ (x : ↥U),
    (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) 0

Next tactic:
intro x
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => intro x; 

Proof state:
X✝ : Scheme
X : Scheme
hX : IsReduced X
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
x : ↥U
| (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) 0

Next tactic:
rw [RingHom.map_zero]
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => intro x; rw [RingHom.map_zero]
  

Proof state:
case h
X✝ : Scheme
X : Scheme
hX : IsReduced X
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
⊢ ∀ (x : ↥U), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0

Next tactic:
refine' (@reduce_to_affine_global (fun X U =>
     ∀ [IsReduced X] (s : X.presheaf.obj (op U)),
       X.basicOpen s = ⊥ → ∀ x, (X.sheaf.presheaf.germ x) s = 0) _ _ _) X U s hs
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => intro x; rw [RingHom.map_zero]
  refine' (@reduce_to_affine_global (fun X U =>
     ∀ [IsReduced X] (s : X.presheaf.obj (op U)),
       X.basicOpen s = ⊥ → ∀ x, (X.sheaf.presheaf.germ x) s = 0) _ _ _) X U s hs
  · 

Proof state:
case h.refine'_1
X✝ : Scheme
X : Scheme
hX : IsReduced X
U : Opens ↑↑X.toPresheafedSpace
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
⊢ ∀ (X : Scheme) (U : Opens ↑↑X.toPresheafedSpace),
    (∀ (x : ↥U),
        ∃ V,
          ∃ (_ : ↑x ∈ V),
            ∃ x,
              (fun X U =>
                  ∀ [inst : IsReduced X] (s : ↑(X.presheaf.obj (op U))),
                    X.basicOpen s = ⊥ → ∀ (x : ↥U), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0)
                X V) →
      (fun X U =>
          ∀ [inst : IsReduced X] (s : ↑(X.presheaf.obj (op U))),
            X.basicOpen s = ⊥ → ∀ (x : ↥U), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0)
        X U

Next tactic:
intro X U hx hX s hs x
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => intro x; rw [RingHom.map_zero]
  refine' (@reduce_to_affine_global (fun X U =>
     ∀ [IsReduced X] (s : X.presheaf.obj (op U)),
       X.basicOpen s = ⊥ → ∀ x, (X.sheaf.presheaf.germ x) s = 0) _ _ _) X U s hs
  · intro X U hx hX s hs x
    

Proof state:
case h.refine'_1
X✝¹ : Scheme
X✝ : Scheme
hX✝ : IsReduced X✝
U✝ : Opens ↑↑X✝.toPresheafedSpace
s✝ : ↑(X✝.presheaf.obj (op U✝))
hs✝ : X✝.basicOpen s✝ = ⊥
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
hx :
  ∀ (x : ↥U),
    ∃ V,
      ∃ (_ : ↑x ∈ V),
        ∃ x,
          (fun X U =>
              ∀ [inst : IsReduced X] (s : ↑(X.presheaf.obj (op U))),
                X.basicOpen s = ⊥ → ∀ (x : ↥U), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0)
            X V
hX : IsReduced X
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
x : ↥U
⊢ (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0

Next tactic:
obtain ⟨V, hx, i, H⟩ := hx x
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => intro x; rw [RingHom.map_zero]
  refine' (@reduce_to_affine_global (fun X U =>
     ∀ [IsReduced X] (s : X.presheaf.obj (op U)),
       X.basicOpen s = ⊥ → ∀ x, (X.sheaf.presheaf.germ x) s = 0) _ _ _) X U s hs
  · intro X U hx hX s hs x
    obtain ⟨V, hx, i, H⟩ := hx x
    

Proof state:
case h.refine'_1.intro.intro.intro
X✝¹ : Scheme
X✝ : Scheme
hX✝ : IsReduced X✝
U✝ : Opens ↑↑X✝.toPresheafedSpace
s✝ : ↑(X✝.presheaf.obj (op U✝))
hs✝ : X✝.basicOpen s✝ = ⊥
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
hx✝ :
  ∀ (x : ↥U),
    ∃ V,
      ∃ (_ : ↑x ∈ V),
        ∃ x,
          (fun X U =>
              ∀ [inst : IsReduced X] (s : ↑(X.presheaf.obj (op U))),
                X.basicOpen s = ⊥ → ∀ (x : ↥U), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0)
            X V
hX : IsReduced X
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
x : ↥U
V : Opens ↑↑X.toPresheafedSpace
hx : ↑x ∈ V
i : V ⟶ U
H :
  ∀ [inst : IsReduced X] (s : ↑(X.presheaf.obj (op V))),
    X.basicOpen s = ⊥ → ∀ (x : ↥V), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0
⊢ (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0

Next tactic:
specialize H (X.presheaf.map i.op s)
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => intro x; rw [RingHom.map_zero]
  refine' (@reduce_to_affine_global (fun X U =>
     ∀ [IsReduced X] (s : X.presheaf.obj (op U)),
       X.basicOpen s = ⊥ → ∀ x, (X.sheaf.presheaf.germ x) s = 0) _ _ _) X U s hs
  · intro X U hx hX s hs x
    obtain ⟨V, hx, i, H⟩ := hx x
    specialize H (X.presheaf.map i.op s)
    

Proof state:
case h.refine'_1.intro.intro.intro
X✝¹ : Scheme
X✝ : Scheme
hX✝ : IsReduced X✝
U✝ : Opens ↑↑X✝.toPresheafedSpace
s✝ : ↑(X✝.presheaf.obj (op U✝))
hs✝ : X✝.basicOpen s✝ = ⊥
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
hx✝ :
  ∀ (x : ↥U),
    ∃ V,
      ∃ (_ : ↑x ∈ V),
        ∃ x,
          (fun X U =>
              ∀ [inst : IsReduced X] (s : ↑(X.presheaf.obj (op U))),
                X.basicOpen s = ⊥ → ∀ (x : ↥U), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0)
            X V
hX : IsReduced X
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
x : ↥U
V : Opens ↑↑X.toPresheafedSpace
hx : ↑x ∈ V
i : V ⟶ U
H :
  X.basicOpen ((X.presheaf.map i.op) s) = ⊥ →
    ∀ (x : ↥V), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) ((X.presheaf.map i.op) s) = 0
⊢ (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0

Next tactic:
erw [Scheme.basicOpen_res] at H
theorem eq_zero_of_basicOpen_eq_bot {X : Scheme} [hX : IsReduced X] {U : Opens X.carrier}
    (s : X.presheaf.obj (op U)) (hs : X.basicOpen s = ⊥) : s = 0 := by
  apply TopCat.Presheaf.section_ext X.sheaf U
  conv => intro x; rw [RingHom.map_zero]
  refine' (@reduce_to_affine_global (fun X U =>
     ∀ [IsReduced X] (s : X.presheaf.obj (op U)),
       X.basicOpen s = ⊥ → ∀ x, (X.sheaf.presheaf.germ x) s = 0) _ _ _) X U s hs
  · intro X U hx hX s hs x
    obtain ⟨V, hx, i, H⟩ := hx x
    specialize H (X.presheaf.map i.op s)
    erw [Scheme.basicOpen_res] at H
    

Proof state:
case h.refine'_1.intro.intro.intro
X✝¹ : Scheme
X✝ : Scheme
hX✝ : IsReduced X✝
U✝ : Opens ↑↑X✝.toPresheafedSpace
s✝ : ↑(X✝.presheaf.obj (op U✝))
hs✝ : X✝.basicOpen s✝ = ⊥
X : Scheme
U : Opens ↑↑X.toPresheafedSpace
hx✝ :
  ∀ (x : ↥U),
    ∃ V,
      ∃ (_ : ↑x ∈ V),
        ∃ x,
          (fun X U =>
              ∀ [inst : IsReduced X] (s : ↑(X.presheaf.obj (op U))),
                X.basicOpen s = ⊥ → ∀ (x : ↥U), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0)
            X V
hX : IsReduced X
s : ↑(X.presheaf.obj (op U))
hs : X.basicOpen s = ⊥
x : ↥U
V : Opens ↑↑X.toPresheafedSpace
hx : ↑x ∈ V
i : V ⟶ U
H :
  V ⊓ X.basicOpen s = ⊥ → ∀ (x : ↥V), (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) ((X.presheaf.map i.op) s) = 0
⊢ (Presheaf.germ (Sheaf.presheaf (Scheme.sheaf X)) x) s = 0

Next tactic:
rw [hs] at H