/-- The function between the basic open set `D(f)` in `Proj` to the corresponding basic open set in
`Spec A⁰_f`. This is bundled into a continuous map in `TopComponent.forward`.
-/
def toFun (x : Proj.T| pbo f) : Spec.T A⁰_ f :=
  ⟨carrier x, carrier_ne_top x, fun {x1 x2} hx12 => by
    classical
    rw [mem_carrier_iff] at hx12
    let J := span ((algebraMap A (Away f) : A → (Away f)) '' x.val.asHomogeneousIdeal)
    suffices h : ∀ x y : Localization.Away f, x * y ∈ J → x ∈ J ∨ y ∈ J
    · rw [HomogeneousLocalization.mul_val] at hx12; exact h x1.val x2.val hx12
    clear x1 x2 hx12
    intro x1 x2 hx12
    induction' x1 using Localization.induction_on with data_x1
    induction' x2 using Localization.induction_on with data_x2
    rcases data_x1, data_x2 with ⟨⟨a1, _, ⟨n1, rfl⟩⟩, ⟨a2, _, ⟨n2, rfl⟩⟩⟩
    rcases MemCarrier.clear_denominator' x hx12 with ⟨c, N, acd, eq1⟩
    simp only [Algebra.smul_def] at eq1
    change Localization.mk (f ^ N) 1 * (Localization.mk _ _ * Localization.mk _ _)
      = Localization.mk _ _ at eq1
    simp only [Localization.mk_mul, one_mul] at eq1
    simp only [mk_eq_mk', IsLocalization.eq] at eq1
    rcases eq1 with ⟨⟨_, ⟨M, rfl⟩⟩, eq1⟩
    rw [Submonoid.coe_one, one_mul] at eq1
    

Proof state:
case h.H.H.mk.mk.intro.mk.mk.intro.intro.intro.intro.intro.mk.intro
R : Type u_1
A : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing A
inst✝¹ : Algebra R A
𝒜 : ℕ → Submodule R A
inst✝ : GradedAlgebra 𝒜
f : A
m : ℕ
f_deg : f ∈ 𝒜 m
x✝ : ↑(LocallyRingedSpace.toTopCat (LocallyRingedSpace.restrict Proj (_ : OpenEmbedding ⇑(Opens.inclusion (pbo f)))))
x : ↑↑(LocallyRingedSpace.restrict Proj (_ : OpenEmbedding ⇑(Opens.inclusion (pbo f)))).toSheafedSpace.toPresheafedSpace
J : Ideal (Away f) := span (⇑(algebraMap A (Away f)) '' ↑(↑x).asHomogeneousIdeal)
a1 : A
n1 : ℕ
a2 : A
n2 : ℕ
hx12 :
  Localization.mk
        (a1, { val := (fun x => f ^ x) n1, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n1) }).1
        (a1, { val := (fun x => f ^ x) n1, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n1) }).2 *
      Localization.mk
        (a2, { val := (fun x => f ^ x) n2, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n2) }).1
        (a2, { val := (fun x => f ^ x) n2, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n2) }).2 ∈
    J
c : ↑(⇑(algebraMap A (Away f)) '' ↑(↑x).asHomogeneousIdeal) →₀ Away f
N : ℕ
acd : (y : Away f) → y ∈ image (⇑c) c.support → A
M : ℕ
eq1 :
  ↑{ val := (fun x => f ^ x) M, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) M) } * (f ^ N * (a1 * a2)) =
    ↑{ val := (fun x => f ^ x) M, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) M) } *
      (↑({ val := f ^ n1, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n1) } *
            { val := f ^ n2, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n2) }) *
        (algebraMap A A)
          (∑ i in attach c.support,
            acd (c ↑i) (_ : c ↑i ∈ image (⇑c) c.support) *
              Exists.choose (_ : ↑↑i ∈ ⇑(algebraMap A (Away f)) '' ↑(↑x).asHomogeneousIdeal)))
⊢ Localization.mk
        (a1, { val := (fun x => f ^ x) n1, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n1) }).1
        (a1, { val := (fun x => f ^ x) n1, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n1) }).2 ∈
      J ∨
    Localization.mk
        (a2, { val := (fun x => f ^ x) n2, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n2) }).1
        (a2, { val := (fun x => f ^ x) n2, property := (_ : ∃ y, (fun x => f ^ x) y = (fun x => f ^ x) n2) }).2 ∈
      J

Next tactic:
change f ^ _ * (_ * _) = f ^ _ * (f ^ _ * f ^ _ * _) at eq1