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₂ ⊢; simp only [mul_assoc, hr₂] }
  -- Our claim now reduces to showing that `f` is contained in the radical of `I`
  suffices f ∈ I.radical by
    cases' this with n hn
    exact ⟨⟨f ^ n, n, rfl⟩, hn⟩
  rw [← PrimeSpectrum.vanishingIdeal_zeroLocus_eq_radical, PrimeSpectrum.mem_vanishingIdeal]
  intro p hfp
  contrapose hfp
  rw [PrimeSpectrum.mem_zeroLocus, Set.not_subset]
  have := congr_fun (congr_arg Subtype.val h_eq) ⟨p, hfp⟩
  dsimp at this
  -- Porting note : need to tell Lean what `S` is and need to change to `erw`
  -- https://github.com/leanprover-community/mathlib4/issues/5164
  erw [IsLocalization.eq (S := Localization.AtPrime p.asIdeal)] at this
  cases' this with r hr
  

Proof state:
case intro.intro.mk.intro.intro.mk.intro
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)
I : Ideal R :=
  {
    toAddSubmonoid :=
      {
        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)) },
    smul_mem' :=
      (_ :
        ∀ {r₁ r₂ : 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 →
            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) }
p : PrimeSpectrum R
hfp : f ∉ p.asIdeal
r : ↥(Ideal.primeCompl p.asIdeal)
hr :
  ↑r * (↑{ val := d, property := (_ : d ∈ Ideal.primeCompl p.asIdeal) } * a) =
    ↑r * (↑{ val := b, property := (_ : b ∈ Ideal.primeCompl p.asIdeal) } * c)
⊢ ∃ a ∈ ↑I, a ∉ ↑p.asIdeal

Next tactic:
exact ⟨r.1, hr, r.2⟩