l3lab/ntp-mathlib huggingface dataset:
/-- The ring isomorphism between the stalk of the structure sheaf of `R` at a point `p`
corresponding to a prime ideal in `R` and the localization of `R` at `p`. -/
@[simps]
def stalkIso (x : PrimeSpectrum.Top R) :
    (structureSheaf R).presheaf.stalk x ≅ CommRingCat.of (Localization.AtPrime x.asIdeal) where
  hom := stalkToFiberRingHom R x
  inv := localizationToStalk R x
  hom_inv_id := by
    ext U hxU s
    simp only [FunctorToTypes.map_comp_apply, CommRingCat.forget_map,
      CommRingCat.coe_of, Category.comp_id]
    rw [comp_apply, comp_apply, stalkToFiberRingHom_germ']
    obtain ⟨V, hxV, iVU, f, g, (hg : V ≤ PrimeSpectrum.basicOpen _), hs⟩ :=
      exists_const _ _ s x hxU
    erw [← res_apply R U V iVU s ⟨x, hxV⟩, ← hs, const_apply, localizationToStalk_mk']
    refine' (structureSheaf R).presheaf.germ_ext V hxV (homOfLE hg) iVU _
    dsimp
    erw [← hs, res_const']
  inv_hom_id :=
    @IsLocalization.ringHom_ext R _ x.asIdeal.primeCompl (Localization.AtPrime x.asIdeal) _ _
      (Localization.AtPrime x.asIdeal) _ _
      (RingHom.comp (stalkToFiberRingHom R x) (localizationToStalk R x))
      (RingHom.id (Localization.AtPrime _)) <| by
        

Proof state:
R : Type u
inst✝ : CommRing R
x : ↑(PrimeSpectrum.Top R)
⊢ RingHom.comp (RingHom.comp (stalkToFiberRingHom R x) (localizationToStalk R x))
      (algebraMap R (Localization.AtPrime x.asIdeal)) =
    RingHom.comp (RingHom.id (Localization.AtPrime x.asIdeal)) (algebraMap R (Localization.AtPrime x.asIdeal))

Next tactic:
ext f
/-- The ring isomorphism between the stalk of the structure sheaf of `R` at a point `p`
corresponding to a prime ideal in `R` and the localization of `R` at `p`. -/
@[simps]
def stalkIso (x : PrimeSpectrum.Top R) :
    (structureSheaf R).presheaf.stalk x ≅ CommRingCat.of (Localization.AtPrime x.asIdeal) where
  hom := stalkToFiberRingHom R x
  inv := localizationToStalk R x
  hom_inv_id := by
    ext U hxU s
    simp only [FunctorToTypes.map_comp_apply, CommRingCat.forget_map,
      CommRingCat.coe_of, Category.comp_id]
    rw [comp_apply, comp_apply, stalkToFiberRingHom_germ']
    obtain ⟨V, hxV, iVU, f, g, (hg : V ≤ PrimeSpectrum.basicOpen _), hs⟩ :=
      exists_const _ _ s x hxU
    erw [← res_apply R U V iVU s ⟨x, hxV⟩, ← hs, const_apply, localizationToStalk_mk']
    refine' (structureSheaf R).presheaf.germ_ext V hxV (homOfLE hg) iVU _
    dsimp
    erw [← hs, res_const']
  inv_hom_id :=
    @IsLocalization.ringHom_ext R _ x.asIdeal.primeCompl (Localization.AtPrime x.asIdeal) _ _
      (Localization.AtPrime x.asIdeal) _ _
      (RingHom.comp (stalkToFiberRingHom R x) (localizationToStalk R x))
      (RingHom.id (Localization.AtPrime _)) <| by
        ext f
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        

Proof state:
case a
R : Type u
inst✝ : CommRing R
x : ↑(PrimeSpectrum.Top R)
f : R
⊢ (RingHom.comp (RingHom.comp (stalkToFiberRingHom R x) (localizationToStalk R x))
        (algebraMap R (Localization.AtPrime x.asIdeal)))
      f =
    (RingHom.comp (RingHom.id (Localization.AtPrime x.asIdeal)) (algebraMap R (Localization.AtPrime x.asIdeal))) f

Next tactic:
rw [RingHom.comp_apply, RingHom.comp_apply]
/-- The ring isomorphism between the stalk of the structure sheaf of `R` at a point `p`
corresponding to a prime ideal in `R` and the localization of `R` at `p`. -/
@[simps]
def stalkIso (x : PrimeSpectrum.Top R) :
    (structureSheaf R).presheaf.stalk x ≅ CommRingCat.of (Localization.AtPrime x.asIdeal) where
  hom := stalkToFiberRingHom R x
  inv := localizationToStalk R x
  hom_inv_id := by
    ext U hxU s
    simp only [FunctorToTypes.map_comp_apply, CommRingCat.forget_map,
      CommRingCat.coe_of, Category.comp_id]
    rw [comp_apply, comp_apply, stalkToFiberRingHom_germ']
    obtain ⟨V, hxV, iVU, f, g, (hg : V ≤ PrimeSpectrum.basicOpen _), hs⟩ :=
      exists_const _ _ s x hxU
    erw [← res_apply R U V iVU s ⟨x, hxV⟩, ← hs, const_apply, localizationToStalk_mk']
    refine' (structureSheaf R).presheaf.germ_ext V hxV (homOfLE hg) iVU _
    dsimp
    erw [← hs, res_const']
  inv_hom_id :=
    @IsLocalization.ringHom_ext R _ x.asIdeal.primeCompl (Localization.AtPrime x.asIdeal) _ _
      (Localization.AtPrime x.asIdeal) _ _
      (RingHom.comp (stalkToFiberRingHom R x) (localizationToStalk R x))
      (RingHom.id (Localization.AtPrime _)) <| by
        ext f
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        rw [RingHom.comp_apply, RingHom.comp_apply]; 

Proof state:
case a
R : Type u
inst✝ : CommRing R
x : ↑(PrimeSpectrum.Top R)
f : R
⊢ (stalkToFiberRingHom R x) ((localizationToStalk R x) ((algebraMap R (Localization.AtPrime x.asIdeal)) f)) =
    (RingHom.comp (RingHom.id (Localization.AtPrime x.asIdeal)) (algebraMap R (Localization.AtPrime x.asIdeal))) f

Next tactic:
erw [localizationToStalk_of,
          stalkToFiberRingHom_toStalk]
/-- The ring isomorphism between the stalk of the structure sheaf of `R` at a point `p`
corresponding to a prime ideal in `R` and the localization of `R` at `p`. -/
@[simps]
def stalkIso (x : PrimeSpectrum.Top R) :
    (structureSheaf R).presheaf.stalk x ≅ CommRingCat.of (Localization.AtPrime x.asIdeal) where
  hom := stalkToFiberRingHom R x
  inv := localizationToStalk R x
  hom_inv_id := by
    ext U hxU s
    simp only [FunctorToTypes.map_comp_apply, CommRingCat.forget_map,
      CommRingCat.coe_of, Category.comp_id]
    rw [comp_apply, comp_apply, stalkToFiberRingHom_germ']
    obtain ⟨V, hxV, iVU, f, g, (hg : V ≤ PrimeSpectrum.basicOpen _), hs⟩ :=
      exists_const _ _ s x hxU
    erw [← res_apply R U V iVU s ⟨x, hxV⟩, ← hs, const_apply, localizationToStalk_mk']
    refine' (structureSheaf R).presheaf.germ_ext V hxV (homOfLE hg) iVU _
    dsimp
    erw [← hs, res_const']
  inv_hom_id :=
    @IsLocalization.ringHom_ext R _ x.asIdeal.primeCompl (Localization.AtPrime x.asIdeal) _ _
      (Localization.AtPrime x.asIdeal) _ _
      (RingHom.comp (stalkToFiberRingHom R x) (localizationToStalk R x))
      (RingHom.id (Localization.AtPrime _)) <| by
        ext f
        -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
        rw [RingHom.comp_apply, RingHom.comp_apply]; erw [localizationToStalk_of,
          stalkToFiberRingHom_toStalk]; 

Proof state:
case a
R : Type u
inst✝ : CommRing R
x : ↑(PrimeSpectrum.Top R)
f : R
⊢ (algebraMap R (Localization.AtPrime x.asIdeal)) f =
    (RingHom.comp (RingHom.id (Localization.AtPrime x.asIdeal)) (algebraMap R (Localization.AtPrime x.asIdeal))) f

Next tactic:
rw [RingHom.comp_apply, RingHom.id_apply]
@[simp]
theorem toBasicOpen_mk' (s f : R) (g : Submonoid.powers s) :
    toBasicOpen R s (IsLocalization.mk' (Localization.Away s) f g) =
      const R f g (PrimeSpectrum.basicOpen s) fun x hx => Submonoid.powers_le.2 hx g.2 :=
  (IsLocalization.lift_mk'_spec _ _ _ _).2 <| by
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    

Proof state:
R : Type u
inst✝ : CommRing R
s f : R
g : ↥(Submonoid.powers s)
⊢ (toOpen R (PrimeSpectrum.basicOpen s)) f =
    (toOpen R (PrimeSpectrum.basicOpen s)) ↑g *
      const R f (↑g) (PrimeSpectrum.basicOpen s) (_ : ∀ x ∈ PrimeSpectrum.basicOpen s, ↑g ∈ Ideal.primeCompl x.asIdeal)

Next tactic:
erw [toOpen_eq_const, toOpen_eq_const]
@[simp]
theorem toBasicOpen_mk' (s f : R) (g : Submonoid.powers s) :
    toBasicOpen R s (IsLocalization.mk' (Localization.Away s) f g) =
      const R f g (PrimeSpectrum.basicOpen s) fun x hx => Submonoid.powers_le.2 hx g.2 :=
  (IsLocalization.lift_mk'_spec _ _ _ _).2 <| by
    -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
    erw [toOpen_eq_const, toOpen_eq_const]; 

Proof state:
R : Type u
inst✝ : CommRing R
s f : R
g : ↥(Submonoid.powers s)
⊢ const R f 1 (PrimeSpectrum.basicOpen s) (_ : ∀ x ∈ PrimeSpectrum.basicOpen s, 1 ∉ x.asIdeal) =
    const R (↑g) 1 (PrimeSpectrum.basicOpen s) (_ : ∀ x ∈ PrimeSpectrum.basicOpen s, 1 ∉ x.asIdeal) *
      const R f (↑g) (PrimeSpectrum.basicOpen s) (_ : ∀ x ∈ PrimeSpectrum.basicOpen s, ↑g ∈ Ideal.primeCompl x.asIdeal)

Next tactic:
rw [const_mul_cancel']
@[simp]
theorem localization_toBasicOpen (f : R) :
    RingHom.comp (toBasicOpen R f) (algebraMap R (Localization.Away f)) =
    toOpen R (PrimeSpectrum.basicOpen f) :=
  RingHom.ext fun g => by
    

Proof state:
R : Type u
inst✝ : CommRing R
f g : R
⊢ (RingHom.comp (toBasicOpen R f) (algebraMap R (Localization.Away f))) g = (toOpen R (PrimeSpectrum.basicOpen f)) g

Next tactic:
rw [toBasicOpen, IsLocalization.Away.lift, RingHom.comp_apply, IsLocalization.lift_eq]
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  

Proof state:
R : Type u
inst✝ : CommRing R
f : R
⊢ Function.Injective ⇑(toBasicOpen R f)

Next tactic:
intro s t h_eq
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  

Proof state:
R : Type u
inst✝ : CommRing R
f : R
s t : Localization.Away f
h_eq : (toBasicOpen R f) s = (toBasicOpen R f) t
⊢ s = t

Next tactic:
obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  

Proof state:
case intro.intro.mk
R : Type u
inst✝ : CommRing R
f : R
t : Localization.Away f
a b : R
hb : b ∈ Submonoid.powers f
h_eq : (toBasicOpen R f) (IsLocalization.mk' (Localization.Away f) a { val := b, property := hb }) = (toBasicOpen R f) t
⊢ IsLocalization.mk' (Localization.Away f) a { val := b, property := hb } = t

Next tactic:
obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  

Proof state:
case intro.intro.mk.intro.intro.mk
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  (toBasicOpen R f) (IsLocalization.mk' (Localization.Away f) a { val := b, property := hb }) =
    (toBasicOpen R f) (IsLocalization.mk' (Localization.Away f) c { val := d, property := hd })
⊢ IsLocalization.mk' (Localization.Away f) a { val := b, property := hb } =
    IsLocalization.mk' (Localization.Away f) c { val := d, property := hd }

Next tactic:
simp only [toBasicOpen_mk'] at h_eq
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  simp only [toBasicOpen_mk'] at h_eq
  

Proof state:
case intro.intro.mk.intro.intro.mk
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  const R a b (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := b, property := hb } ∈ Ideal.primeCompl x.asIdeal) =
    const R c d (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := d, property := hd } ∈ Ideal.primeCompl x.asIdeal)
⊢ IsLocalization.mk' (Localization.Away f) a { val := b, property := hb } =
    IsLocalization.mk' (Localization.Away f) c { val := d, property := hd }

Next tactic:
rw [IsLocalization.eq]
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  simp only [toBasicOpen_mk'] at h_eq
  rw [IsLocalization.eq]
  -- We know that the fractions `a/b` and `c/d` are equal as sections of the structure sheaf on
  -- `basicOpen f`. We need to show that they agree as elements in the localization of `R` at `f`.
  -- This amounts showing that `r * (d * a) = r * (b * c)`, for some power `r = f ^ n` of `f`.
  -- We define `I` as the ideal of *all* elements `r` satisfying the above equation.
  

Proof state:
case intro.intro.mk.intro.intro.mk
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  const R a b (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := b, property := hb } ∈ Ideal.primeCompl x.asIdeal) =
    const R c d (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := d, property := hd } ∈ Ideal.primeCompl x.asIdeal)
⊢ ∃ c_1, ↑c_1 * (↑{ val := d, property := hd } * a) = ↑c_1 * (↑{ val := b, property := hb } * c)

Next tactic:
let I : Ideal R :=
    { carrier := { r : R | r * (d * a) = r * (b * c) }
      zero_mem' := by simp only [Set.mem_setOf_eq, zero_mul]
      add_mem' := fun {r₁ r₂} hr₁ hr₂ => by dsimp at hr₁ hr₂ ⊢; simp only [add_mul, hr₁, hr₂]
      smul_mem' := fun {r₁ r₂} hr₂ => by dsimp at hr₂ ⊢; simp only [mul_assoc, hr₂] }
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  simp only [toBasicOpen_mk'] at h_eq
  rw [IsLocalization.eq]
  -- We know that the fractions `a/b` and `c/d` are equal as sections of the structure sheaf on
  -- `basicOpen f`. We need to show that they agree as elements in the localization of `R` at `f`.
  -- This amounts showing that `r * (d * a) = r * (b * c)`, for some power `r = f ^ n` of `f`.
  -- We define `I` as the ideal of *all* elements `r` satisfying the above equation.
  let I : Ideal R :=
    { carrier := { r : R | r * (d * a) = r * (b * c) }
      zero_mem' := by simp only [Set.mem_setOf_eq, zero_mul]
      add_mem' := fun {r₁ r₂} hr₁ hr₂ => by 

Proof state:
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  const R a b (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := b, property := hb } ∈ Ideal.primeCompl x.asIdeal) =
    const R c d (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := d, property := hd } ∈ Ideal.primeCompl x.asIdeal)
r₁ r₂ : R
hr₁ : r₁ ∈ {r | r * (d * a) = r * (b * c)}
hr₂ : r₂ ∈ {r | r * (d * a) = r * (b * c)}
⊢ r₁ + r₂ ∈ {r | r * (d * a) = r * (b * c)}

Next tactic:
dsimp at hr₁ hr₂ ⊢
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  simp only [toBasicOpen_mk'] at h_eq
  rw [IsLocalization.eq]
  -- We know that the fractions `a/b` and `c/d` are equal as sections of the structure sheaf on
  -- `basicOpen f`. We need to show that they agree as elements in the localization of `R` at `f`.
  -- This amounts showing that `r * (d * a) = r * (b * c)`, for some power `r = f ^ n` of `f`.
  -- We define `I` as the ideal of *all* elements `r` satisfying the above equation.
  let I : Ideal R :=
    { carrier := { r : R | r * (d * a) = r * (b * c) }
      zero_mem' := by simp only [Set.mem_setOf_eq, zero_mul]
      add_mem' := fun {r₁ r₂} hr₁ hr₂ => by dsimp at hr₁ hr₂ ⊢; 

Proof state:
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  const R a b (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := b, property := hb } ∈ Ideal.primeCompl x.asIdeal) =
    const R c d (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := d, property := hd } ∈ Ideal.primeCompl x.asIdeal)
r₁ r₂ : R
hr₁ : r₁ * (d * a) = r₁ * (b * c)
hr₂ : r₂ * (d * a) = r₂ * (b * c)
⊢ (r₁ + r₂) * (d * a) = (r₁ + r₂) * (b * c)

Next tactic:
simp only [add_mul, hr₁, hr₂]
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  simp only [toBasicOpen_mk'] at h_eq
  rw [IsLocalization.eq]
  -- We know that the fractions `a/b` and `c/d` are equal as sections of the structure sheaf on
  -- `basicOpen f`. We need to show that they agree as elements in the localization of `R` at `f`.
  -- This amounts showing that `r * (d * a) = r * (b * c)`, for some power `r = f ^ n` of `f`.
  -- We define `I` as the ideal of *all* elements `r` satisfying the above equation.
  let I : Ideal R :=
    { carrier := { r : R | r * (d * a) = r * (b * c) }
      zero_mem' := by 

Proof state:
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  const R a b (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := b, property := hb } ∈ Ideal.primeCompl x.asIdeal) =
    const R c d (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := d, property := hd } ∈ Ideal.primeCompl x.asIdeal)
⊢ 0 ∈
    { carrier := {r | r * (d * a) = r * (b * c)},
        add_mem' :=
          (_ :
            ∀ {r₁ r₂ : R},
              r₁ ∈ {r | r * (d * a) = r * (b * c)} →
                r₂ ∈ {r | r * (d * a) = r * (b * c)} → r₁ + r₂ ∈ {r | r * (d * a) = r * (b * c)}) }.carrier

Next tactic:
simp only [Set.mem_setOf_eq, zero_mul]
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  simp only [toBasicOpen_mk'] at h_eq
  rw [IsLocalization.eq]
  -- We know that the fractions `a/b` and `c/d` are equal as sections of the structure sheaf on
  -- `basicOpen f`. We need to show that they agree as elements in the localization of `R` at `f`.
  -- This amounts showing that `r * (d * a) = r * (b * c)`, for some power `r = f ^ n` of `f`.
  -- We define `I` as the ideal of *all* elements `r` satisfying the above equation.
  let I : Ideal R :=
    { carrier := { r : R | r * (d * a) = r * (b * c) }
      zero_mem' := by simp only [Set.mem_setOf_eq, zero_mul]
      add_mem' := fun {r₁ r₂} hr₁ hr₂ => by dsimp at hr₁ hr₂ ⊢; simp only [add_mul, hr₁, hr₂]
      smul_mem' := fun {r₁ r₂} hr₂ => by 

Proof state:
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  const R a b (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := b, property := hb } ∈ Ideal.primeCompl x.asIdeal) =
    const R c d (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := d, property := hd } ∈ Ideal.primeCompl x.asIdeal)
r₁ r₂ : R
hr₂ :
  r₂ ∈
    {
          toAddSubsemigroup :=
            { carrier := {r | r * (d * a) = r * (b * c)},
              add_mem' :=
                (_ :
                  ∀ {r₁ r₂ : R},
                    r₁ ∈ {r | r * (d * a) = r * (b * c)} →
                      r₂ ∈ {r | r * (d * a) = r * (b * c)} → r₁ + r₂ ∈ {r | r * (d * a) = r * (b * c)}) },
          zero_mem' := (_ : 0 * (d * a) = 0 * (b * c)) }.toAddSubsemigroup.carrier
⊢ r₁ • r₂ ∈
    {
          toAddSubsemigroup :=
            { carrier := {r | r * (d * a) = r * (b * c)},
              add_mem' :=
                (_ :
                  ∀ {r₁ r₂ : R},
                    r₁ ∈ {r | r * (d * a) = r * (b * c)} →
                      r₂ ∈ {r | r * (d * a) = r * (b * c)} → r₁ + r₂ ∈ {r | r * (d * a) = r * (b * c)}) },
          zero_mem' := (_ : 0 * (d * a) = 0 * (b * c)) }.toAddSubsemigroup.carrier

Next tactic:
dsimp at hr₂ ⊢
theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) := by
  intro s t h_eq
  obtain ⟨a, ⟨b, hb⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) s
  obtain ⟨c, ⟨d, hd⟩, rfl⟩ := IsLocalization.mk'_surjective (Submonoid.powers f) t
  simp only [toBasicOpen_mk'] at h_eq
  rw [IsLocalization.eq]
  -- We know that the fractions `a/b` and `c/d` are equal as sections of the structure sheaf on
  -- `basicOpen f`. We need to show that they agree as elements in the localization of `R` at `f`.
  -- This amounts showing that `r * (d * a) = r * (b * c)`, for some power `r = f ^ n` of `f`.
  -- We define `I` as the ideal of *all* elements `r` satisfying the above equation.
  let I : Ideal R :=
    { carrier := { r : R | r * (d * a) = r * (b * c) }
      zero_mem' := by simp only [Set.mem_setOf_eq, zero_mul]
      add_mem' := fun {r₁ r₂} hr₁ hr₂ => by dsimp at hr₁ hr₂ ⊢; simp only [add_mul, hr₁, hr₂]
      smul_mem' := fun {r₁ r₂} hr₂ => by dsimp at hr₂ ⊢; 

Proof state:
R : Type u
inst✝ : CommRing R
f a b : R
hb : b ∈ Submonoid.powers f
c d : R
hd : d ∈ Submonoid.powers f
h_eq :
  const R a b (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := b, property := hb } ∈ Ideal.primeCompl x.asIdeal) =
    const R c d (PrimeSpectrum.basicOpen f)
      (_ : ∀ x ∈ PrimeSpectrum.basicOpen f, ↑{ val := d, property := hd } ∈ Ideal.primeCompl x.asIdeal)
r₁ r₂ : R
hr₂ : r₂ * (d * a) = r₂ * (b * c)
⊢ r₁ * r₂ * (d * a) = r₁ * r₂ * (b * c)

Next tactic:
simp only [mul_assoc, hr₂]
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  

Proof state:
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
⊢ ∃ f g i,
    ↑x ∈ PrimeSpectrum.basicOpen g ∧
      const R f g (PrimeSpectrum.basicOpen g) (_ : ∀ y ∈ PrimeSpectrum.basicOpen g, y ∈ PrimeSpectrum.basicOpen g) =
        ((structureSheaf R).val.map i.op) s

Next tactic:
obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
theorem locally_const_basicOpen (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) (x : U) :
    ∃ (f g : R) (i : PrimeSpectrum.basicOpen g ⟶ U), x.1 ∈ PrimeSpectrum.basicOpen g ∧
      (const R f g (PrimeSpectrum.basicOpen g) fun y hy => hy) =
      (structureSheaf R).1.map i.op s := by
  -- First, any section `s` can be represented as a fraction `f/g` on some open neighborhood of `x`
  -- and we may pass to a `basicOpen h`, since these form a basis
  obtain ⟨V, hxV : x.1 ∈ V.1, iVU, f, g, hVDg : V ≤ PrimeSpectrum.basicOpen g, s_eq⟩ :=
    exists_const R U s x.1 x.2
  

Proof state:
case intro.intro.intro.intro.intro.intro
R : Type u
inst✝ : CommRing R
U : Opens ↑(PrimeSpectrum.Top R)
s : ↑((structureSheaf R).val.obj (op U))
x : ↥U
V : Opens ↑(PrimeSpectrum.Top R)
hxV : ↑x ∈ V.carrier
iVU : V ⟶ U
f g : R
hVDg : V ≤ PrimeSpectrum.basicOpen g
s_eq : const R f g V hVDg = ((structureSheaf R).val.map iVU.op) s
⊢ ∃ f g i,
    ↑x ∈ PrimeSpectrum.basicOpen g ∧
      const R f g (PrimeSpectrum.basicOpen g) (_ : ∀ y ∈ PrimeSpectrum.basicOpen g, y ∈ PrimeSpectrum.basicOpen g) =
        ((structureSheaf R).val.map i.op) s

Next tactic:
obtain ⟨_, ⟨h, rfl⟩, hxDh, hDhV : PrimeSpectrum.basicOpen h ≤ V⟩ :=
    PrimeSpectrum.isTopologicalBasis_basic_opens.exists_subset_of_mem_open hxV V.2