l3lab/ntp-mathlib huggingface dataset:
/-- For a ring homomorphism `f : R →+* S` and open sets `U` and `V` of the prime spectra of `R` and
`S` such that `V ⊆ (comap f) ⁻¹ U`, the induced ring homomorphism from the structure sheaf of `R`
at `U` to the structure sheaf of `S` at `V`.

Explicitly, this map is given as follows: For a point `p : V`, if the section `s` evaluates on `p`
to the fraction `a / b`, its image on `V` evaluates on `p` to the fraction `f(a) / f(b)`.
-/
def comap (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) (V : Opens (PrimeSpectrum.Top S))
    (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1) :
    (structureSheaf R).1.obj (op U) →+* (structureSheaf S).1.obj (op V) where
  toFun s := ⟨comapFun f U V hUV s.1, comapFunIsLocallyFraction f U V hUV s.1 s.2⟩
  map_one' :=
    Subtype.ext <|
      funext fun p => by
        dsimp
        rw [comapFun, (sectionsSubring R (op U)).coe_one, Pi.one_apply, RingHom.map_one]
        rfl
  map_zero' :=
    Subtype.ext <|
      funext fun p => by
        dsimp
        rw [comapFun, (sectionsSubring R (op U)).coe_zero, Pi.zero_apply, RingHom.map_zero]
        rfl
  map_add' s t :=
    Subtype.ext <|
      funext fun p => by
        dsimp
        rw [comapFun, (sectionsSubring R (op U)).coe_add, Pi.add_apply, RingHom.map_add]
        

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
f : R →+* S
U : Opens ↑(PrimeSpectrum.Top R)
V : Opens ↑(PrimeSpectrum.Top S)
hUV : V.carrier ⊆ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier
s t : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
⊢ (Localization.localRingHom ((PrimeSpectrum.comap f) ↑p).asIdeal (↑p).asIdeal f
          (_ : ((PrimeSpectrum.comap f) ↑p).asIdeal = ((PrimeSpectrum.comap f) ↑p).asIdeal))
        (↑s { val := (PrimeSpectrum.comap f) ↑p, property := (_ : ↑p ∈ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier) }) +
      (Localization.localRingHom ((PrimeSpectrum.comap f) ↑p).asIdeal (↑p).asIdeal f
          (_ : ((PrimeSpectrum.comap f) ↑p).asIdeal = ((PrimeSpectrum.comap f) ↑p).asIdeal))
        (↑t { val := (PrimeSpectrum.comap f) ↑p, property := (_ : ↑p ∈ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier) }) =
    ↑({ val := comapFun f U V hUV ↑s,
            property :=
              (_ : PrelocalPredicate.pred (isLocallyFraction S).toPrelocalPredicate (comapFun f U V hUV ↑s)) } +
          { val := comapFun f U V hUV ↑t,
            property :=
              (_ : PrelocalPredicate.pred (isLocallyFraction S).toPrelocalPredicate (comapFun f U V hUV ↑t)) })
      p

Next tactic:
rfl
theorem comap_const (f : R →+* S) (U : Opens (PrimeSpectrum.Top R))
    (V : Opens (PrimeSpectrum.Top S)) (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1) (a b : R)
    (hb : ∀ x : PrimeSpectrum R, x ∈ U → b ∈ x.asIdeal.primeCompl) :
    comap f U V hUV (const R a b U hb) =
      const S (f a) (f b) V fun p hpV => hb (PrimeSpectrum.comap f p) (hUV hpV) :=
  Subtype.eq <|
    funext fun p => by
      

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
f : R →+* S
U : Opens ↑(PrimeSpectrum.Top R)
V : Opens ↑(PrimeSpectrum.Top S)
hUV : V.carrier ⊆ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier
a b : R
hb : ∀ x ∈ U, b ∈ Ideal.primeCompl x.asIdeal
p : ↥(op V).unop
⊢ ↑((comap f U V hUV) (const R a b U hb)) p =
    ↑(const S (f a) (f b) V (_ : ∀ p ∈ V, b ∈ Ideal.primeCompl ((PrimeSpectrum.comap f) p).asIdeal)) p

Next tactic:
rw [comap_apply, const_apply, const_apply]
theorem comap_const (f : R →+* S) (U : Opens (PrimeSpectrum.Top R))
    (V : Opens (PrimeSpectrum.Top S)) (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1) (a b : R)
    (hb : ∀ x : PrimeSpectrum R, x ∈ U → b ∈ x.asIdeal.primeCompl) :
    comap f U V hUV (const R a b U hb) =
      const S (f a) (f b) V fun p hpV => hb (PrimeSpectrum.comap f p) (hUV hpV) :=
  Subtype.eq <|
    funext fun p => by
      rw [comap_apply, const_apply, const_apply]
      

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
f : R →+* S
U : Opens ↑(PrimeSpectrum.Top R)
V : Opens ↑(PrimeSpectrum.Top S)
hUV : V.carrier ⊆ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier
a b : R
hb : ∀ x ∈ U, b ∈ Ideal.primeCompl x.asIdeal
p : ↥(op V).unop
⊢ (Localization.localRingHom ((PrimeSpectrum.comap f) ↑p).asIdeal (↑p).asIdeal f
        (_ : ((PrimeSpectrum.comap f) ↑p).asIdeal = ((PrimeSpectrum.comap f) ↑p).asIdeal))
      (IsLocalization.mk'
        (Localizations R
          ↑{ val := (PrimeSpectrum.comap f) ↑p, property := (_ : ↑p ∈ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier) })
        a
        { val := b,
          property :=
            (_ :
              b ∈
                Ideal.primeCompl
                  (↑{ val := (PrimeSpectrum.comap f) ↑p,
                        property := (_ : ↑p ∈ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier) }).asIdeal) }) =
    IsLocalization.mk' (Localizations S ↑p) (f a)
      { val := f b, property := (_ : b ∈ Ideal.primeCompl ((PrimeSpectrum.comap f) ↑p).asIdeal) }

Next tactic:
erw [Localization.localRingHom_mk']
theorem comap_const (f : R →+* S) (U : Opens (PrimeSpectrum.Top R))
    (V : Opens (PrimeSpectrum.Top S)) (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1) (a b : R)
    (hb : ∀ x : PrimeSpectrum R, x ∈ U → b ∈ x.asIdeal.primeCompl) :
    comap f U V hUV (const R a b U hb) =
      const S (f a) (f b) V fun p hpV => hb (PrimeSpectrum.comap f p) (hUV hpV) :=
  Subtype.eq <|
    funext fun p => by
      rw [comap_apply, const_apply, const_apply]
      erw [Localization.localRingHom_mk']
      

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
f : R →+* S
U : Opens ↑(PrimeSpectrum.Top R)
V : Opens ↑(PrimeSpectrum.Top S)
hUV : V.carrier ⊆ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier
a b : R
hb : ∀ x ∈ U, b ∈ Ideal.primeCompl x.asIdeal
p : ↥(op V).unop
⊢ IsLocalization.mk' (Localization.AtPrime (↑p).asIdeal) (f a)
      {
        val :=
          f
            ↑{ val := b,
                property :=
                  (_ :
                    b ∈
                      Ideal.primeCompl
                        (↑{ val := (PrimeSpectrum.comap f) ↑p,
                              property := (_ : ↑p ∈ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier) }).asIdeal) },
        property :=
          (_ :
            ↑{ val := b,
                  property :=
                    (_ :
                      b ∈
                        Ideal.primeCompl
                          (↑{ val := (PrimeSpectrum.comap f) ↑p,
                                property := (_ : ↑p ∈ ⇑(PrimeSpectrum.comap f) ⁻¹' U.carrier) }).asIdeal) } ∈
              Submonoid.comap f (Ideal.primeCompl (↑p).asIdeal)) } =
    IsLocalization.mk' (Localizations S ↑p) (f a)
      { val := f b, property := (_ : b ∈ Ideal.primeCompl ((PrimeSpectrum.comap f) ↑p).asIdeal) }

Next tactic:
rfl
/-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the
identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf.

This is a generalization of the fact that, for fixed `U`, the comap of the identity from OO_X(U)
to OO_X(U) is the identity.
-/
theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) :
    (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) =
      (structureSheaf R).1.map iVU.op :=
  RingHom.ext fun s => Subtype.eq <| funext fun p => by
    

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
iVU : V ⟶ U
s : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
⊢ ↑((comap (RingHom.id R) U V (_ : ∀ p ∈ V.carrier, p ∈ ↑U)) s) p = ↑(((structureSheaf R).val.map iVU.op) s) p

Next tactic:
rw [comap_apply]
/-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the
identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf.

This is a generalization of the fact that, for fixed `U`, the comap of the identity from OO_X(U)
to OO_X(U) is the identity.
-/
theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) :
    (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) =
      (structureSheaf R).1.map iVU.op :=
  RingHom.ext fun s => Subtype.eq <| funext fun p => by
    rw [comap_apply]
    -- Unfortunately, we cannot use `Localization.localRingHom_id` here, because
    -- `PrimeSpectrum.comap (RingHom.id R) p` is not *definitionally* equal to `p`. Instead, we use
    -- that we can write `s` as a fraction `a/b` in a small neighborhood around `p`. Since
    -- `PrimeSpectrum.comap (RingHom.id R) p` equals `p`, it is also contained in the same
    -- neighborhood, hence `s` equals `a/b` there too.
    

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
iVU : V ⟶ U
s : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
⊢ (Localization.localRingHom ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal (↑p).asIdeal (RingHom.id R)
        (_ : ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal = ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal))
      (↑s { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := (_ : ↑p ∈ ↑U) }) =
    ↑(((structureSheaf R).val.map iVU.op) s) p

Next tactic:
obtain ⟨W, hpW, iWU, h⟩ := s.2 (iVU p)
/-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the
identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf.

This is a generalization of the fact that, for fixed `U`, the comap of the identity from OO_X(U)
to OO_X(U) is the identity.
-/
theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) :
    (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) =
      (structureSheaf R).1.map iVU.op :=
  RingHom.ext fun s => Subtype.eq <| funext fun p => by
    rw [comap_apply]
    -- Unfortunately, we cannot use `Localization.localRingHom_id` here, because
    -- `PrimeSpectrum.comap (RingHom.id R) p` is not *definitionally* equal to `p`. Instead, we use
    -- that we can write `s` as a fraction `a/b` in a small neighborhood around `p`. Since
    -- `PrimeSpectrum.comap (RingHom.id R) p` equals `p`, it is also contained in the same
    -- neighborhood, hence `s` equals `a/b` there too.
    obtain ⟨W, hpW, iWU, h⟩ := s.2 (iVU p)
    

Proof state:
case intro.intro.intro
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
iVU : V ⟶ U
s : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
W : Opens ↑(PrimeSpectrum.Top R)
hpW : ↑((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑U) }) p) ∈ W
iWU : W ⟶ (op U).unop
h :
  PrelocalPredicate.pred (isFractionPrelocal R) fun x =>
    ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)
⊢ (Localization.localRingHom ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal (↑p).asIdeal (RingHom.id R)
        (_ : ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal = ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal))
      (↑s { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := (_ : ↑p ∈ ↑U) }) =
    ↑(((structureSheaf R).val.map iVU.op) s) p

Next tactic:
obtain ⟨a, b, h'⟩ := h.eq_mk'
/-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the
identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf.

This is a generalization of the fact that, for fixed `U`, the comap of the identity from OO_X(U)
to OO_X(U) is the identity.
-/
theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) :
    (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) =
      (structureSheaf R).1.map iVU.op :=
  RingHom.ext fun s => Subtype.eq <| funext fun p => by
    rw [comap_apply]
    -- Unfortunately, we cannot use `Localization.localRingHom_id` here, because
    -- `PrimeSpectrum.comap (RingHom.id R) p` is not *definitionally* equal to `p`. Instead, we use
    -- that we can write `s` as a fraction `a/b` in a small neighborhood around `p`. Since
    -- `PrimeSpectrum.comap (RingHom.id R) p` equals `p`, it is also contained in the same
    -- neighborhood, hence `s` equals `a/b` there too.
    obtain ⟨W, hpW, iWU, h⟩ := s.2 (iVU p)
    obtain ⟨a, b, h'⟩ := h.eq_mk'
    

Proof state:
case intro.intro.intro.intro.intro
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
iVU : V ⟶ U
s : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
W : Opens ↑(PrimeSpectrum.Top R)
hpW : ↑((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑U) }) p) ∈ W
iWU : W ⟶ (op U).unop
h :
  PrelocalPredicate.pred (isFractionPrelocal R) fun x =>
    ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)
a b : R
h' :
  ∀ (x : ↥W),
    ∃ (hs : b ∉ (↑x).asIdeal),
      (fun x => ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)) x =
        IsLocalization.mk' (Localization.AtPrime (↑x).asIdeal) a { val := b, property := hs }
⊢ (Localization.localRingHom ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal (↑p).asIdeal (RingHom.id R)
        (_ : ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal = ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal))
      (↑s { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := (_ : ↑p ∈ ↑U) }) =
    ↑(((structureSheaf R).val.map iVU.op) s) p

Next tactic:
obtain ⟨hb₁, s_eq₁⟩ := h' ⟨p, hpW⟩
/-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the
identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf.

This is a generalization of the fact that, for fixed `U`, the comap of the identity from OO_X(U)
to OO_X(U) is the identity.
-/
theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) :
    (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) =
      (structureSheaf R).1.map iVU.op :=
  RingHom.ext fun s => Subtype.eq <| funext fun p => by
    rw [comap_apply]
    -- Unfortunately, we cannot use `Localization.localRingHom_id` here, because
    -- `PrimeSpectrum.comap (RingHom.id R) p` is not *definitionally* equal to `p`. Instead, we use
    -- that we can write `s` as a fraction `a/b` in a small neighborhood around `p`. Since
    -- `PrimeSpectrum.comap (RingHom.id R) p` equals `p`, it is also contained in the same
    -- neighborhood, hence `s` equals `a/b` there too.
    obtain ⟨W, hpW, iWU, h⟩ := s.2 (iVU p)
    obtain ⟨a, b, h'⟩ := h.eq_mk'
    obtain ⟨hb₁, s_eq₁⟩ := h' ⟨p, hpW⟩
    

Proof state:
case intro.intro.intro.intro.intro.intro
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
iVU : V ⟶ U
s : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
W : Opens ↑(PrimeSpectrum.Top R)
hpW : ↑((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑U) }) p) ∈ W
iWU : W ⟶ (op U).unop
h :
  PrelocalPredicate.pred (isFractionPrelocal R) fun x =>
    ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)
a b : R
h' :
  ∀ (x : ↥W),
    ∃ (hs : b ∉ (↑x).asIdeal),
      (fun x => ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)) x =
        IsLocalization.mk' (Localization.AtPrime (↑x).asIdeal) a { val := b, property := hs }
hb₁ : b ∉ (↑{ val := ↑p, property := hpW }).asIdeal
s_eq₁ :
  (fun x => ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)) { val := ↑p, property := hpW } =
    IsLocalization.mk' (Localization.AtPrime (↑{ val := ↑p, property := hpW }).asIdeal) a { val := b, property := hb₁ }
⊢ (Localization.localRingHom ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal (↑p).asIdeal (RingHom.id R)
        (_ : ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal = ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal))
      (↑s { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := (_ : ↑p ∈ ↑U) }) =
    ↑(((structureSheaf R).val.map iVU.op) s) p

Next tactic:
obtain ⟨hb₂, s_eq₂⟩ :=
      h' ⟨PrimeSpectrum.comap (RingHom.id _) p.1, hpW⟩
/-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the
identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf.

This is a generalization of the fact that, for fixed `U`, the comap of the identity from OO_X(U)
to OO_X(U) is the identity.
-/
theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) :
    (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) =
      (structureSheaf R).1.map iVU.op :=
  RingHom.ext fun s => Subtype.eq <| funext fun p => by
    rw [comap_apply]
    -- Unfortunately, we cannot use `Localization.localRingHom_id` here, because
    -- `PrimeSpectrum.comap (RingHom.id R) p` is not *definitionally* equal to `p`. Instead, we use
    -- that we can write `s` as a fraction `a/b` in a small neighborhood around `p`. Since
    -- `PrimeSpectrum.comap (RingHom.id R) p` equals `p`, it is also contained in the same
    -- neighborhood, hence `s` equals `a/b` there too.
    obtain ⟨W, hpW, iWU, h⟩ := s.2 (iVU p)
    obtain ⟨a, b, h'⟩ := h.eq_mk'
    obtain ⟨hb₁, s_eq₁⟩ := h' ⟨p, hpW⟩
    obtain ⟨hb₂, s_eq₂⟩ :=
      h' ⟨PrimeSpectrum.comap (RingHom.id _) p.1, hpW⟩
    

Proof state:
case intro.intro.intro.intro.intro.intro.intro
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
iVU : V ⟶ U
s : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
W : Opens ↑(PrimeSpectrum.Top R)
hpW : ↑((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑U) }) p) ∈ W
iWU : W ⟶ (op U).unop
h :
  PrelocalPredicate.pred (isFractionPrelocal R) fun x =>
    ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)
a b : R
h' :
  ∀ (x : ↥W),
    ∃ (hs : b ∉ (↑x).asIdeal),
      (fun x => ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)) x =
        IsLocalization.mk' (Localization.AtPrime (↑x).asIdeal) a { val := b, property := hs }
hb₁ : b ∉ (↑{ val := ↑p, property := hpW }).asIdeal
s_eq₁ :
  (fun x => ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)) { val := ↑p, property := hpW } =
    IsLocalization.mk' (Localization.AtPrime (↑{ val := ↑p, property := hpW }).asIdeal) a { val := b, property := hb₁ }
hb₂ : b ∉ (↑{ val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := hpW }).asIdeal
s_eq₂ :
  (fun x => ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x))
      { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := hpW } =
    IsLocalization.mk'
      (Localization.AtPrime (↑{ val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := hpW }).asIdeal) a
      { val := b, property := hb₂ }
⊢ (Localization.localRingHom ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal (↑p).asIdeal (RingHom.id R)
        (_ : ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal = ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal))
      (↑s { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := (_ : ↑p ∈ ↑U) }) =
    ↑(((structureSheaf R).val.map iVU.op) s) p

Next tactic:
dsimp only at s_eq₁ s_eq₂
/-- For an inclusion `i : V ⟶ U` between open sets of the prime spectrum of `R`, the comap of the
identity from OO_X(U) to OO_X(V) equals as the restriction map of the structure sheaf.

This is a generalization of the fact that, for fixed `U`, the comap of the identity from OO_X(U)
to OO_X(U) is the identity.
-/
theorem comap_id_eq_map (U V : Opens (PrimeSpectrum.Top R)) (iVU : V ⟶ U) :
    (comap (RingHom.id R) U V fun p hpV => leOfHom iVU <| hpV) =
      (structureSheaf R).1.map iVU.op :=
  RingHom.ext fun s => Subtype.eq <| funext fun p => by
    rw [comap_apply]
    -- Unfortunately, we cannot use `Localization.localRingHom_id` here, because
    -- `PrimeSpectrum.comap (RingHom.id R) p` is not *definitionally* equal to `p`. Instead, we use
    -- that we can write `s` as a fraction `a/b` in a small neighborhood around `p`. Since
    -- `PrimeSpectrum.comap (RingHom.id R) p` equals `p`, it is also contained in the same
    -- neighborhood, hence `s` equals `a/b` there too.
    obtain ⟨W, hpW, iWU, h⟩ := s.2 (iVU p)
    obtain ⟨a, b, h'⟩ := h.eq_mk'
    obtain ⟨hb₁, s_eq₁⟩ := h' ⟨p, hpW⟩
    obtain ⟨hb₂, s_eq₂⟩ :=
      h' ⟨PrimeSpectrum.comap (RingHom.id _) p.1, hpW⟩
    dsimp only at s_eq₁ s_eq₂
    

Proof state:
case intro.intro.intro.intro.intro.intro.intro
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
iVU : V ⟶ U
s : ↑((structureSheaf R).val.obj (op U))
p : ↥(op V).unop
W : Opens ↑(PrimeSpectrum.Top R)
hpW : ↑((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑U) }) p) ∈ W
iWU : W ⟶ (op U).unop
h :
  PrelocalPredicate.pred (isFractionPrelocal R) fun x =>
    ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)
a b : R
h' :
  ∀ (x : ↥W),
    ∃ (hs : b ∉ (↑x).asIdeal),
      (fun x => ↑s ((fun x => { val := ↑x, property := (_ : ↑x ∈ ↑(op U).unop) }) x)) x =
        IsLocalization.mk' (Localization.AtPrime (↑x).asIdeal) a { val := b, property := hs }
hb₁ : b ∉ (↑{ val := ↑p, property := hpW }).asIdeal
s_eq₁ :
  ↑s { val := ↑p, property := (_ : ↑{ val := ↑p, property := hpW } ∈ ↑(op U).unop) } =
    IsLocalization.mk' (Localization.AtPrime (↑p).asIdeal) a { val := b, property := hb₁ }
hb₂ : b ∉ (↑{ val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := hpW }).asIdeal
s_eq₂ :
  ↑s
      { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p,
        property := (_ : ↑{ val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := hpW } ∈ ↑(op U).unop) } =
    IsLocalization.mk' (Localization.AtPrime ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal) a
      { val := b, property := hb₂ }
⊢ (Localization.localRingHom ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal (↑p).asIdeal (RingHom.id R)
        (_ : ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal = ((PrimeSpectrum.comap (RingHom.id R)) ↑p).asIdeal))
      (↑s { val := (PrimeSpectrum.comap (RingHom.id R)) ↑p, property := (_ : ↑p ∈ ↑U) }) =
    ↑(((structureSheaf R).val.map iVU.op) s) p

Next tactic:
erw [s_eq₂, Localization.localRingHom_mk', ← s_eq₁, ← res_apply _ _ _ iVU]
/--
The comap of the identity is the identity. In this variant of the lemma, two open subsets `U` and
`V` are given as arguments, together with a proof that `U = V`. This is useful when `U` and `V`
are not definitionally equal.
-/
theorem comap_id (U V : Opens (PrimeSpectrum.Top R)) (hUV : U = V) :
    (comap (RingHom.id R) U V fun p hpV => by 

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
hUV : U = V
p : ↑(PrimeSpectrum.Top R)
hpV : p ∈ V.carrier
⊢ p ∈ ⇑(PrimeSpectrum.comap (RingHom.id R)) ⁻¹' U.carrier

Next tactic:
rwa [hUV, PrimeSpectrum.comap_id]
/--
The comap of the identity is the identity. In this variant of the lemma, two open subsets `U` and
`V` are given as arguments, together with a proof that `U = V`. This is useful when `U` and `V`
are not definitionally equal.
-/
theorem comap_id (U V : Opens (PrimeSpectrum.Top R)) (hUV : U = V) :
    (comap (RingHom.id R) U V fun p hpV => by rwa [hUV, PrimeSpectrum.comap_id]) =
      eqToHom (show (structureSheaf R).1.obj (op U) = _ by 

Proof state:
R : Type u
inst✝² : CommRing R
S : Type u
inst✝¹ : CommRing S
P : Type u
inst✝ : CommRing P
U V : Opens ↑(PrimeSpectrum.Top R)
hUV : U = V
⊢ (structureSheaf R).val.obj (op U) = (structureSheaf R).val.obj (op V)

Next tactic:
rw [hUV]