File: Mathlib/AlgebraicGeometry/StructureSheaf.lean

full_name: AlgebraicGeometry.PrimeSpectrum.Top
code: /-- The prime spectrum, just as a topological space.
-/
def PrimeSpectrum.Top : TopCat 
goal: TopCat

full_name: AlgebraicGeometry.StructureSheaf.Localizations
code: /-- The type family over `PrimeSpectrum R` consisting of the localization over each point.
-/
def Localizations (P : PrimeSpectrum.Top R) : Type u 
goal: Type u

full_name: AlgebraicGeometry.StructureSheaf.commRingLocalizations
code: instance commRingLocalizations (P : PrimeSpectrum.Top R) : CommRing <| Localizations R P 
goal: CommRing (AlgebraicGeometry.StructureSheaf.Localizations R P)

full_name: AlgebraicGeometry.StructureSheaf.localRingLocalizations
code: instance localRingLocalizations (P : PrimeSpectrum.Top R) : LocalRing <| Localizations R P 
goal: LocalRing (AlgebraicGeometry.StructureSheaf.Localizations R P)

full_name: AlgebraicGeometry.StructureSheaf.instInhabitedLocalizations
code: instance (P : PrimeSpectrum.Top R) : Inhabited (Localizations R P) 
goal: Inhabited (AlgebraicGeometry.StructureSheaf.Localizations R P)

full_name: AlgebraicGeometry.StructureSheaf.instAlgebraLocalizationsValαTopologicalSpaceTopMemSetCoeOpens
code: instance (U : Opens (PrimeSpectrum.Top R)) (x : U) : Algebra R (Localizations R x) 
goal: Algebra R (AlgebraicGeometry.StructureSheaf.Localizations R ↑x)

full_name: AlgebraicGeometry.StructureSheaf.instAtPrimeLocalizationsValαTopologicalSpaceTopMemSetCoeOpensAsIdeal
code: instance (U : Opens (PrimeSpectrum.Top R)) (x : U) :
    IsLocalization.AtPrime (Localizations R x) (x : PrimeSpectrum.Top R).asIdeal 
goal: IsLocalization.AtPrime (AlgebraicGeometry.StructureSheaf.Localizations R ↑x) (↑x).asIdeal

full_name: AlgebraicGeometry.StructureSheaf.IsFraction
code: /-- The predicate saying that a dependent function on an open `U` is realised as a fixed fraction
`r / s` in each of the stalks (which are localizations at various prime ideals).
-/
def IsFraction {U : Opens (PrimeSpectrum.Top R)} (f : ∀ x : U, Localizations R x) : Prop 
goal: Prop

full_name: AlgebraicGeometry.StructureSheaf.IsFraction.eq_mk'
code: theorem IsFraction.eq_mk' {U : Opens (PrimeSpectrum.Top R)} {f : ∀ x : U, Localizations R x}
    (hf : IsFraction f) :
    ∃ r s : R,
      ∀ x : U,
        ∃ hs : s ∉ x.1.asIdeal,
          f x =
            IsLocalization.mk' (Localization.AtPrime _) r
              (⟨s, hs⟩ : (x : PrimeSpectrum.Top R).asIdeal.primeCompl) 
goal: ∃ r s, ∀ (x : ↥U), ∃ (hs : s ∉ (↑x).asIdeal), f x = IsLocalization.mk' (Localization.AtPrime (↑x).asIdeal) r ⟨s, hs⟩

full_name: AlgebraicGeometry.StructureSheaf.isFractionPrelocal
code: /-- The predicate `IsFraction` is "prelocal",
in the sense that if it holds on `U` it holds on any open subset `V` of `U`.
-/
def isFractionPrelocal : PrelocalPredicate (Localizations R) 
goal: TopCat.PrelocalPredicate (AlgebraicGeometry.StructureSheaf.Localizations R)

full_name: AlgebraicGeometry.StructureSheaf.isLocallyFraction
code: /-- We will define the structure sheaf as
the subsheaf of all dependent functions in `Π x : U, Localizations R x`
consisting of those functions which can locally be expressed as a ratio of
(the images in the localization of) elements of `R`.

Quoting Hartshorne:

For an open set $U ⊆ Spec A$, we define $𝒪(U)$ to be the set of functions
$s : U → ⨆_{𝔭 ∈ U} A_𝔭$, such that $s(𝔭) ∈ A_𝔭$ for each $𝔭$,
and such that $s$ is locally a quotient of elements of $A$:
to be precise, we require that for each $𝔭 ∈ U$, there is a neighborhood $V$ of $𝔭$,
contained in $U$, and elements $a, f ∈ A$, such that for each $𝔮 ∈ V, f ∉ 𝔮$,
and $s(𝔮) = a/f$ in $A_𝔮$.

Now Hartshorne had the disadvantage of not knowing about dependent functions,
so we replace his circumlocution about functions into a disjoint union with
`Π x : U, Localizations x`.
-/
def isLocallyFraction : LocalPredicate (Localizations R) 
goal: TopCat.LocalPredicate (AlgebraicGeometry.StructureSheaf.Localizations R)

full_name: AlgebraicGeometry.StructureSheaf.isLocallyFraction_pred
code: @[simp]
theorem isLocallyFraction_pred {U : Opens (PrimeSpectrum.Top R)} (f : ∀ x : U, Localizations R x) :
    (isLocallyFraction R).pred f =
      ∀ x : U,
        ∃ (V : _) (_ : x.1 ∈ V) (i : V ⟶ U),
          ∃ r s : R,
            ∀ y : V, ¬s ∈ y.1.asIdeal ∧ f (i y : U) * algebraMap _ _ s = algebraMap _ _ r 
goal: (AlgebraicGeometry.StructureSheaf.isLocallyFraction R).pred f =
  ∀ (x : ↥U),
    ∃ V,
      ∃ (_ : ↑x ∈ V),
        ∃ i r s,
          ∀ (y : ↥V),
            s ∉ (↑y).asIdeal ∧
              f ((fun x => ⟨↑x, ⋯⟩) y) *
                  (algebraMap R (AlgebraicGeometry.StructureSheaf.Localizations R ↑((fun x => ⟨↑x, ⋯⟩) y))) s =
                (algebraMap R (AlgebraicGeometry.StructureSheaf.Localizations R ↑((fun x => ⟨↑x, ⋯⟩) y))) r

full_name: AlgebraicGeometry.StructureSheaf.sectionsSubring
code: /-- The functions satisfying `isLocallyFraction` form a subring.
-/
def sectionsSubring (U : (Opens (PrimeSpectrum.Top R))ᵒᵖ) :
    Subring (∀ x : U.unop, Localizations R x) 
goal: Subring ((x : ↥(Opposite.unop U)) → AlgebraicGeometry.StructureSheaf.Localizations R ↑x)

full_name: AlgebraicGeometry.structureSheafInType
code: /-- The structure sheaf (valued in `Type`, not yet `CommRingCat`) is the subsheaf consisting of
functions satisfying `isLocallyFraction`.
-/
def structureSheafInType : Sheaf (Type u) (PrimeSpectrum.Top R) 
goal: TopCat.Sheaf (Type u) (AlgebraicGeometry.PrimeSpectrum.Top R)

full_name: AlgebraicGeometry.commRingStructureSheafInTypeObj
code: instance commRingStructureSheafInTypeObj (U : (Opens (PrimeSpectrum.Top R))ᵒᵖ) :
    CommRing ((structureSheafInType R).1.obj U) 
goal: CommRing ((AlgebraicGeometry.structureSheafInType R).val.obj U)

full_name: AlgebraicGeometry.structurePresheafInCommRing_map_apply
code: /-- The structure presheaf, valued in `CommRingCat`, constructed by dressing up the `Type` valued
structure presheaf.
-/
@[simps]
def structurePresheafInCommRing : Presheaf CommRingCat (PrimeSpectrum.Top R) 
goal: ∀ (a : (AlgebraicGeometry.structureSheafInType R).val.obj U),
  ((AlgebraicGeometry.structurePresheafInCommRing R).map i) a = (AlgebraicGeometry.structureSheafInType R).val.map i a

full_name: AlgebraicGeometry.structurePresheafInCommRing_obj
code: /-- The structure presheaf, valued in `CommRingCat`, constructed by dressing up the `Type` valued
structure presheaf.
-/
@[simps]
def structurePresheafInCommRing : Presheaf CommRingCat (PrimeSpectrum.Top R) 
goal: (AlgebraicGeometry.structurePresheafInCommRing R).obj U =
  CommRingCat.of ((AlgebraicGeometry.structureSheafInType R).val.obj U)

full_name: AlgebraicGeometry.structurePresheafInCommRing
code: /-- The structure presheaf, valued in `CommRingCat`, constructed by dressing up the `Type` valued
structure presheaf.
-/
@[simps]
def structurePresheafInCommRing : Presheaf CommRingCat (PrimeSpectrum.Top R) 
goal: TopCat.Presheaf CommRingCat (AlgebraicGeometry.PrimeSpectrum.Top R)

full_name: AlgebraicGeometry.structurePresheafCompForget
code: /-- Some glue, verifying that the structure presheaf valued in `CommRingCat` agrees
with the `Type` valued structure presheaf.
-/
def structurePresheafCompForget :
    structurePresheafInCommRing R ⋙ forget CommRingCat ≅ (structureSheafInType R).1 
goal: AlgebraicGeometry.structurePresheafInCommRing R ⋙ CategoryTheory.forget CommRingCat ≅
  (AlgebraicGeometry.structureSheafInType R).val

full_name: AlgebraicGeometry.Spec.structureSheaf
code: /-- The structure sheaf on $Spec R$, valued in `CommRingCat`.

This is provided as a bundled `SheafedSpace` as `Spec.SheafedSpace R` later.
-/
def Spec.structureSheaf : Sheaf CommRingCat (PrimeSpectrum.Top R) 
goal: TopCat.Sheaf CommRingCat (AlgebraicGeometry.PrimeSpectrum.Top R)

full_name: AlgebraicGeometry.StructureSheaf.res_apply
code: @[simp]
theorem res_apply (U V : Opens (PrimeSpectrum.Top R)) (i : V ⟶ U)
    (s : (structureSheaf R).1.obj (op U)) (x : V) :
    ((structureSheaf R).1.map i.op s).1 x = (s.1 (i x) : _) 
goal: ↑(((AlgebraicGeometry.Spec.structureSheaf R).val.map i.op) s) x = ↑s ((fun x => ⟨↑x, ⋯⟩) x)

full_name: AlgebraicGeometry.StructureSheaf.const
code: /-- The section of `structureSheaf R` on an open `U` sending each `x ∈ U` to the element
`f/g` in the localization of `R` at `x`. -/
def const (f g : R) (U : Opens (PrimeSpectrum.Top R))
    (hu : ∀ x ∈ U, g ∈ (x : PrimeSpectrum.Top R).asIdeal.primeCompl) :
    (structureSheaf R).1.obj (op U) 
goal: ↑((AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op U))

full_name: AlgebraicGeometry.StructureSheaf.const_apply
code: @[simp]
theorem const_apply (f g : R) (U : Opens (PrimeSpectrum.Top R))
    (hu : ∀ x ∈ U, g ∈ (x : PrimeSpectrum.Top R).asIdeal.primeCompl) (x : U) :
    (const R f g U hu).1 x = IsLocalization.mk' _ f ⟨g, hu x x.2⟩ 
goal: ↑(AlgebraicGeometry.StructureSheaf.const R f g U hu) x =
  IsLocalization.mk' (AlgebraicGeometry.StructureSheaf.Localizations R ↑x) f ⟨g, ⋯⟩

full_name: AlgebraicGeometry.StructureSheaf.const_apply'
code: theorem const_apply' (f g : R) (U : Opens (PrimeSpectrum.Top R))
    (hu : ∀ x ∈ U, g ∈ (x : PrimeSpectrum.Top R).asIdeal.primeCompl) (x : U)
    (hx : g ∈ (x : PrimeSpectrum.Top R).asIdeal.primeCompl) :
    (const R f g U hu).1 x = IsLocalization.mk' _ f ⟨g, hx⟩ 
goal: ↑(AlgebraicGeometry.StructureSheaf.const R f g U hu) x =
  IsLocalization.mk' (AlgebraicGeometry.StructureSheaf.Localizations R ↑x) f ⟨g, hx⟩

full_name: AlgebraicGeometry.StructureSheaf.exists_const
code: theorem exists_const (U) (s : (structureSheaf R).1.obj (op U)) (x : PrimeSpectrum.Top R)
    (hx : x ∈ U) :
    ∃ (V : Opens (PrimeSpectrum.Top R)) (_ : x ∈ V) (i : V ⟶ U) (f g : R) (hg : _),
      const R f g V hg = (structureSheaf R).1.map i.op s 
goal: ∃ V,
  ∃ (_ : x ∈ V),
    ∃ i f g,
      ∃ (hg : ∀ x ∈ V, g ∈ x.asIdeal.primeCompl),
        AlgebraicGeometry.StructureSheaf.const R f g V hg = ((AlgebraicGeometry.Spec.structureSheaf R).val.map i.op) s

full_name: AlgebraicGeometry.StructureSheaf.res_const
code: @[simp]
theorem res_const (f g : R) (U hu V hv i) :
    (structureSheaf R).1.map i (const R f g U hu) = const R f g V hv 
goal: ((AlgebraicGeometry.Spec.structureSheaf R).val.map i) (AlgebraicGeometry.StructureSheaf.const R f g U hu) =
  AlgebraicGeometry.StructureSheaf.const R f g V hv

full_name: AlgebraicGeometry.StructureSheaf.res_const'
code: theorem res_const' (f g : R) (V hv) :
    (structureSheaf R).1.map (homOfLE hv).op (const R f g (PrimeSpectrum.basicOpen g) fun _ => id) =
      const R f g V hv 
goal: ((AlgebraicGeometry.Spec.structureSheaf R).val.map (CategoryTheory.homOfLE hv).op)
    (AlgebraicGeometry.StructureSheaf.const R f g (PrimeSpectrum.basicOpen g) ⋯) =
  AlgebraicGeometry.StructureSheaf.const R f g V hv

full_name: AlgebraicGeometry.StructureSheaf.const_zero
code: theorem const_zero (f : R) (U hu) : const R 0 f U hu = 0 
goal: AlgebraicGeometry.StructureSheaf.const R 0 f U hu = 0

full_name: AlgebraicGeometry.StructureSheaf.const_self
code: theorem const_self (f : R) (U hu) : const R f f U hu = 1 
goal: AlgebraicGeometry.StructureSheaf.const R f f U hu = 1

full_name: AlgebraicGeometry.StructureSheaf.const_one
code: theorem const_one (U) : (const R 1 1 U fun _ _ => Submonoid.one_mem _) = 1 
goal: AlgebraicGeometry.StructureSheaf.const R 1 1 U ⋯ = 1

full_name: AlgebraicGeometry.StructureSheaf.const_add
code: theorem const_add (f₁ f₂ g₁ g₂ : R) (U hu₁ hu₂) :
    const R f₁ g₁ U hu₁ + const R f₂ g₂ U hu₂ =
      const R (f₁ * g₂ + f₂ * g₁) (g₁ * g₂) U fun x hx =>
        Submonoid.mul_mem _ (hu₁ x hx) (hu₂ x hx) 
goal: AlgebraicGeometry.StructureSheaf.const R f₁ g₁ U hu₁ + AlgebraicGeometry.StructureSheaf.const R f₂ g₂ U hu₂ =
  AlgebraicGeometry.StructureSheaf.const R (f₁ * g₂ + f₂ * g₁) (g₁ * g₂) U ⋯

full_name: AlgebraicGeometry.StructureSheaf.const_mul
code: theorem const_mul (f₁ f₂ g₁ g₂ : R) (U hu₁ hu₂) :
    const R f₁ g₁ U hu₁ * const R f₂ g₂ U hu₂ =
      const R (f₁ * f₂) (g₁ * g₂) U fun x hx => Submonoid.mul_mem _ (hu₁ x hx) (hu₂ x hx) 
goal: AlgebraicGeometry.StructureSheaf.const R f₁ g₁ U hu₁ * AlgebraicGeometry.StructureSheaf.const R f₂ g₂ U hu₂ =
  AlgebraicGeometry.StructureSheaf.const R (f₁ * f₂) (g₁ * g₂) U ⋯

full_name: AlgebraicGeometry.StructureSheaf.const_ext
code: theorem const_ext {f₁ f₂ g₁ g₂ : R} {U hu₁ hu₂} (h : f₁ * g₂ = f₂ * g₁) :
    const R f₁ g₁ U hu₁ = const R f₂ g₂ U hu₂ 
goal: AlgebraicGeometry.StructureSheaf.const R f₁ g₁ U hu₁ = AlgebraicGeometry.StructureSheaf.const R f₂ g₂ U hu₂

full_name: AlgebraicGeometry.StructureSheaf.const_congr
code: theorem const_congr {f₁ f₂ g₁ g₂ : R} {U hu} (hf : f₁ = f₂) (hg : g₁ = g₂) :
    const R f₁ g₁ U hu = const R f₂ g₂ U (hg ▸ hu) 
goal: AlgebraicGeometry.StructureSheaf.const R f₁ g₁ U hu = AlgebraicGeometry.StructureSheaf.const R f₂ g₂ U ⋯

full_name: AlgebraicGeometry.StructureSheaf.const_mul_rev
code: theorem const_mul_rev (f g : R) (U hu₁ hu₂) : const R f g U hu₁ * const R g f U hu₂ = 1 
goal: AlgebraicGeometry.StructureSheaf.const R f g U hu₁ * AlgebraicGeometry.StructureSheaf.const R g f U hu₂ = 1

full_name: AlgebraicGeometry.StructureSheaf.const_mul_cancel
code: theorem const_mul_cancel (f g₁ g₂ : R) (U hu₁ hu₂) :
    const R f g₁ U hu₁ * const R g₁ g₂ U hu₂ = const R f g₂ U hu₂ 
goal: AlgebraicGeometry.StructureSheaf.const R f g₁ U hu₁ * AlgebraicGeometry.StructureSheaf.const R g₁ g₂ U hu₂ =
  AlgebraicGeometry.StructureSheaf.const R f g₂ U hu₂

full_name: AlgebraicGeometry.StructureSheaf.const_mul_cancel'
code: theorem const_mul_cancel' (f g₁ g₂ : R) (U hu₁ hu₂) :
    const R g₁ g₂ U hu₂ * const R f g₁ U hu₁ = const R f g₂ U hu₂ 
goal: AlgebraicGeometry.StructureSheaf.const R g₁ g₂ U hu₂ * AlgebraicGeometry.StructureSheaf.const R f g₁ U hu₁ =
  AlgebraicGeometry.StructureSheaf.const R f g₂ U hu₂

full_name: AlgebraicGeometry.StructureSheaf.toOpen
code: /-- The canonical ring homomorphism interpreting an element of `R` as
a section of the structure sheaf. -/
def toOpen (U : Opens (PrimeSpectrum.Top R)) :
    CommRingCat.of R ⟶ (structureSheaf R).1.obj (op U) 
goal: CommRingCat.of R ⟶ (AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op U)

full_name: AlgebraicGeometry.StructureSheaf.toOpen_res
code: @[simp]
theorem toOpen_res (U V : Opens (PrimeSpectrum.Top R)) (i : V ⟶ U) :
    toOpen R U ≫ (structureSheaf R).1.map i.op = toOpen R V 
goal: AlgebraicGeometry.StructureSheaf.toOpen R U ≫ (AlgebraicGeometry.Spec.structureSheaf R).val.map i.op =
  AlgebraicGeometry.StructureSheaf.toOpen R V

full_name: AlgebraicGeometry.StructureSheaf.toOpen_apply
code: @[simp]
theorem toOpen_apply (U : Opens (PrimeSpectrum.Top R)) (f : R) (x : U) :
    (toOpen R U f).1 x = algebraMap _ _ f 
goal: ↑((AlgebraicGeometry.StructureSheaf.toOpen R U) f) x =
  (algebraMap R (AlgebraicGeometry.StructureSheaf.Localizations R ↑x)) f

full_name: AlgebraicGeometry.StructureSheaf.toOpen_eq_const
code: theorem toOpen_eq_const (U : Opens (PrimeSpectrum.Top R)) (f : R) :
    toOpen R U f = const R f 1 U fun x _ => (Ideal.ne_top_iff_one _).1 x.2.1 
goal: (AlgebraicGeometry.StructureSheaf.toOpen R U) f = AlgebraicGeometry.StructureSheaf.const R f 1 U ⋯

full_name: AlgebraicGeometry.StructureSheaf.toStalk
code: /-- The canonical ring homomorphism interpreting an element of `R` as an element of
the stalk of `structureSheaf R` at `x`. -/
def toStalk (x : PrimeSpectrum.Top R) : CommRingCat.of R ⟶ (structureSheaf R).presheaf.stalk x 
goal: CommRingCat.of R ⟶ (AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk x

full_name: AlgebraicGeometry.StructureSheaf.toOpen_germ
code: @[simp]
theorem toOpen_germ (U : Opens (PrimeSpectrum.Top R)) (x : U) :
    toOpen R U ≫ (structureSheaf R).presheaf.germ x = toStalk R x 
goal: AlgebraicGeometry.StructureSheaf.toOpen R U ≫ (AlgebraicGeometry.Spec.structureSheaf R).presheaf.germ x =
  AlgebraicGeometry.StructureSheaf.toStalk R ↑x

full_name: AlgebraicGeometry.StructureSheaf.germ_toOpen
code: @[simp]
theorem germ_toOpen (U : Opens (PrimeSpectrum.Top R)) (x : U) (f : R) :
    (structureSheaf R).presheaf.germ x (toOpen R U f) = toStalk R x f 
goal: ((AlgebraicGeometry.Spec.structureSheaf R).presheaf.germ x) ((AlgebraicGeometry.StructureSheaf.toOpen R U) f) =
  (AlgebraicGeometry.StructureSheaf.toStalk R ↑x) f

full_name: AlgebraicGeometry.StructureSheaf.germ_to_top
code: theorem germ_to_top (x : PrimeSpectrum.Top R) (f : R) :
    (structureSheaf R).presheaf.germ (⟨x, trivial⟩ : (⊤ : Opens (PrimeSpectrum.Top R)))
        (toOpen R ⊤ f) =
      toStalk R x f 
goal: ((AlgebraicGeometry.Spec.structureSheaf R).presheaf.germ ⟨x, trivial⟩)
    ((AlgebraicGeometry.StructureSheaf.toOpen R ⊤) f) =
  (AlgebraicGeometry.StructureSheaf.toStalk R x) f

full_name: AlgebraicGeometry.StructureSheaf.isUnit_to_basicOpen_self
code: theorem isUnit_to_basicOpen_self (f : R) : IsUnit (toOpen R (PrimeSpectrum.basicOpen f) f) 
goal: IsUnit ((AlgebraicGeometry.StructureSheaf.toOpen R (PrimeSpectrum.basicOpen f)) f)

full_name: AlgebraicGeometry.StructureSheaf.isUnit_toStalk
code: theorem isUnit_toStalk (x : PrimeSpectrum.Top R) (f : x.asIdeal.primeCompl) :
    IsUnit (toStalk R x (f : R)) 
goal: IsUnit ((AlgebraicGeometry.StructureSheaf.toStalk R x) ↑f)

full_name: AlgebraicGeometry.StructureSheaf.localizationToStalk
code: /-- The canonical ring homomorphism from the localization of `R` at `p` to the stalk
of the structure sheaf at the point `p`. -/
def localizationToStalk (x : PrimeSpectrum.Top R) :
    CommRingCat.of (Localization.AtPrime x.asIdeal) ⟶ (structureSheaf R).presheaf.stalk x 
goal: CommRingCat.of (Localization.AtPrime x.asIdeal) ⟶ (AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk x

full_name: AlgebraicGeometry.StructureSheaf.localizationToStalk_of
code: @[simp]
theorem localizationToStalk_of (x : PrimeSpectrum.Top R) (f : R) :
    localizationToStalk R x (algebraMap _ (Localization _) f) = toStalk R x f 
goal: (AlgebraicGeometry.StructureSheaf.localizationToStalk R x) ((algebraMap R (Localization x.asIdeal.primeCompl)) f) =
  (AlgebraicGeometry.StructureSheaf.toStalk R x) f

full_name: AlgebraicGeometry.StructureSheaf.localizationToStalk_mk'
code: @[simp]
theorem localizationToStalk_mk' (x : PrimeSpectrum.Top R) (f : R) (s : x.asIdeal.primeCompl) :
    localizationToStalk R x (IsLocalization.mk' (Localization.AtPrime x.asIdeal) f s) =
      (structureSheaf R).presheaf.germ (⟨x, s.2⟩ : PrimeSpectrum.basicOpen (s : R))
        (const R f s (PrimeSpectrum.basicOpen s) fun _ => id) 
goal: (AlgebraicGeometry.StructureSheaf.localizationToStalk R x) (IsLocalization.mk' (Localization.AtPrime x.asIdeal) f s) =
  ((AlgebraicGeometry.Spec.structureSheaf R).presheaf.germ ⟨x, ⋯⟩)
    (AlgebraicGeometry.StructureSheaf.const R f (↑s) (PrimeSpectrum.basicOpen ↑s) ⋯)

full_name: AlgebraicGeometry.StructureSheaf.openToLocalization
code: /-- The ring homomorphism that takes a section of the structure sheaf of `R` on the open set `U`,
implemented as a subtype of dependent functions to localizations at prime ideals, and evaluates
the section on the point corresponding to a given prime ideal. -/
def openToLocalization (U : Opens (PrimeSpectrum.Top R)) (x : PrimeSpectrum.Top R) (hx : x ∈ U) :
    (structureSheaf R).1.obj (op U) ⟶ CommRingCat.of (Localization.AtPrime x.asIdeal) 
goal: (AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op U) ⟶ CommRingCat.of (Localization.AtPrime x.asIdeal)

full_name: AlgebraicGeometry.StructureSheaf.coe_openToLocalization
code: @[simp]
theorem coe_openToLocalization (U : Opens (PrimeSpectrum.Top R)) (x : PrimeSpectrum.Top R)
    (hx : x ∈ U) :
    (openToLocalization R U x hx :
        (structureSheaf R).1.obj (op U) → Localization.AtPrime x.asIdeal) =
      fun s => (s.1 ⟨x, hx⟩ : _) 
goal: ⇑(AlgebraicGeometry.StructureSheaf.openToLocalization R U x hx) = fun s => ↑s ⟨x, hx⟩

full_name: AlgebraicGeometry.StructureSheaf.openToLocalization_apply
code: theorem openToLocalization_apply (U : Opens (PrimeSpectrum.Top R)) (x : PrimeSpectrum.Top R)
    (hx : x ∈ U) (s : (structureSheaf R).1.obj (op U)) :
    openToLocalization R U x hx s = (s.1 ⟨x, hx⟩ : _) 
goal: (AlgebraicGeometry.StructureSheaf.openToLocalization R U x hx) s = ↑s ⟨x, hx⟩

full_name: AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom
code: /-- The ring homomorphism from the stalk of the structure sheaf of `R` at a point corresponding to
a prime ideal `p` to the localization of `R` at `p`,
formed by gluing the `openToLocalization` maps. -/
def stalkToFiberRingHom (x : PrimeSpectrum.Top R) :
    (structureSheaf R).presheaf.stalk x ⟶ CommRingCat.of (Localization.AtPrime x.asIdeal) 
goal: (AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk x ⟶ CommRingCat.of (Localization.AtPrime x.asIdeal)

full_name: AlgebraicGeometry.StructureSheaf.germ_comp_stalkToFiberRingHom
code: @[simp]
theorem germ_comp_stalkToFiberRingHom (U : Opens (PrimeSpectrum.Top R)) (x : U) :
    (structureSheaf R).presheaf.germ x ≫ stalkToFiberRingHom R x = openToLocalization R U x x.2 
goal: (AlgebraicGeometry.Spec.structureSheaf R).presheaf.germ x ≫ AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R ↑x =
  AlgebraicGeometry.StructureSheaf.openToLocalization R U ↑x ⋯

full_name: AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom_germ'
code: @[simp]
theorem stalkToFiberRingHom_germ' (U : Opens (PrimeSpectrum.Top R)) (x : PrimeSpectrum.Top R)
    (hx : x ∈ U) (s : (structureSheaf R).1.obj (op U)) :
    stalkToFiberRingHom R x ((structureSheaf R).presheaf.germ ⟨x, hx⟩ s) = (s.1 ⟨x, hx⟩ : _) 
goal: (AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x)
    (((AlgebraicGeometry.Spec.structureSheaf R).presheaf.germ ⟨x, hx⟩) s) =
  ↑s ⟨x, hx⟩

full_name: AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom_germ
code: @[simp]
theorem stalkToFiberRingHom_germ (U : Opens (PrimeSpectrum.Top R)) (x : U)
    (s : (structureSheaf R).1.obj (op U)) :
    stalkToFiberRingHom R x ((structureSheaf R).presheaf.germ x s) = s.1 x 
goal: (AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R ↑x)
    (((AlgebraicGeometry.Spec.structureSheaf R).presheaf.germ x) s) =
  ↑s x

full_name: AlgebraicGeometry.StructureSheaf.toStalk_comp_stalkToFiberRingHom
code: @[simp]
theorem toStalk_comp_stalkToFiberRingHom (x : PrimeSpectrum.Top R) :
    -- Porting note: now `algebraMap _ _` needs to be explicitly typed
    toStalk R x ≫ stalkToFiberRingHom R x = algebraMap R (Localization.AtPrime x.asIdeal) 
goal: AlgebraicGeometry.StructureSheaf.toStalk R x ≫ AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x =
  algebraMap R (Localization.AtPrime x.asIdeal)

full_name: AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom_toStalk
code: @[simp]
theorem stalkToFiberRingHom_toStalk (x : PrimeSpectrum.Top R) (f : R) :
    -- Porting note: now `algebraMap _ _` needs to be explicitly typed
    stalkToFiberRingHom R x (toStalk R x f) = algebraMap R (Localization.AtPrime x.asIdeal) f 
goal: (AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x) ((AlgebraicGeometry.StructureSheaf.toStalk R x) f) =
  (algebraMap R (Localization.AtPrime x.asIdeal)) f

full_name: AlgebraicGeometry.StructureSheaf.stalkIso_hom
code: /-- 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) 
goal: (AlgebraicGeometry.StructureSheaf.stalkIso R x).hom = AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x

full_name: AlgebraicGeometry.StructureSheaf.stalkIso_inv
code: /-- 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) 
goal: (AlgebraicGeometry.StructureSheaf.stalkIso R x).inv = AlgebraicGeometry.StructureSheaf.localizationToStalk R x

full_name: AlgebraicGeometry.StructureSheaf.stalkIso
code: /-- 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) 
goal: (AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk x ≅ CommRingCat.of (Localization.AtPrime x.asIdeal)

full_name: AlgebraicGeometry.StructureSheaf.instIsIsoCommRingCatStalkToFiberRingHom
code: instance (x : PrimeSpectrum R) : IsIso (stalkToFiberRingHom R x) 
goal: CategoryTheory.IsIso (AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x)

full_name: AlgebraicGeometry.StructureSheaf.instIsIsoCommRingCatLocalizationToStalk
code: instance (x : PrimeSpectrum R) : IsIso (localizationToStalk R x) 
goal: CategoryTheory.IsIso (AlgebraicGeometry.StructureSheaf.localizationToStalk R x)

full_name: AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom_localizationToStalk
code: @[simp, reassoc]
theorem stalkToFiberRingHom_localizationToStalk (x : PrimeSpectrum.Top R) :
    stalkToFiberRingHom R x ≫ localizationToStalk R x = 𝟙 _ 
goal: AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x ≫ AlgebraicGeometry.StructureSheaf.localizationToStalk R x =
  𝟙 ((AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk x)

full_name: AlgebraicGeometry.StructureSheaf.localizationToStalk_stalkToFiberRingHom
code: @[simp, reassoc]
theorem localizationToStalk_stalkToFiberRingHom (x : PrimeSpectrum.Top R) :
    localizationToStalk R x ≫ stalkToFiberRingHom R x = 𝟙 _ 
goal: AlgebraicGeometry.StructureSheaf.localizationToStalk R x ≫ AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x =
  𝟙 (CommRingCat.of (Localization.AtPrime x.asIdeal))

full_name: AlgebraicGeometry.StructureSheaf.toBasicOpen
code: /-- The canonical ring homomorphism interpreting `s ∈ R_f` as a section of the structure sheaf
on the basic open defined by `f ∈ R`. -/
def toBasicOpen (f : R) :
    Localization.Away f →+* (structureSheaf R).1.obj (op <| PrimeSpectrum.basicOpen f) 
goal: Localization.Away f →+* ↑((AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)))

full_name: AlgebraicGeometry.StructureSheaf.toBasicOpen_mk'
code: @[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 
goal: (AlgebraicGeometry.StructureSheaf.toBasicOpen R s) (IsLocalization.mk' (Localization.Away s) f g) =
  AlgebraicGeometry.StructureSheaf.const R f (↑g) (PrimeSpectrum.basicOpen s) ⋯

full_name: AlgebraicGeometry.StructureSheaf.localization_toBasicOpen
code: @[simp]
theorem localization_toBasicOpen (f : R) :
    RingHom.comp (toBasicOpen R f) (algebraMap R (Localization.Away f)) =
    toOpen R (PrimeSpectrum.basicOpen f) 
goal: (AlgebraicGeometry.StructureSheaf.toBasicOpen R f).comp (algebraMap R (Localization.Away f)) =
  AlgebraicGeometry.StructureSheaf.toOpen R (PrimeSpectrum.basicOpen f)

full_name: AlgebraicGeometry.StructureSheaf.toBasicOpen_to_map
code: @[simp]
theorem toBasicOpen_to_map (s f : R) :
    toBasicOpen R s (algebraMap R (Localization.Away s) f) =
      const R f 1 (PrimeSpectrum.basicOpen s) fun _ _ => Submonoid.one_mem _ 
goal: (AlgebraicGeometry.StructureSheaf.toBasicOpen R s) ((algebraMap R (Localization.Away s)) f) =
  AlgebraicGeometry.StructureSheaf.const R f 1 (PrimeSpectrum.basicOpen s) ⋯

full_name: AlgebraicGeometry.StructureSheaf.toBasicOpen_injective
code: theorem toBasicOpen_injective (f : R) : Function.Injective (toBasicOpen R f) 
goal: Function.Injective ⇑(AlgebraicGeometry.StructureSheaf.toBasicOpen R f)

full_name: AlgebraicGeometry.StructureSheaf.locally_const_basicOpen
code: 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 
goal: ∃ f g i,
  ↑x ∈ PrimeSpectrum.basicOpen g ∧
    AlgebraicGeometry.StructureSheaf.const R f g (PrimeSpectrum.basicOpen g) ⋯ =
      ((AlgebraicGeometry.Spec.structureSheaf R).val.map i.op) s

full_name: AlgebraicGeometry.StructureSheaf.normalize_finite_fraction_representation
code: theorem normalize_finite_fraction_representation (U : Opens (PrimeSpectrum.Top R))
    (s : (structureSheaf R).1.obj (op U)) {ι : Type*} (t : Finset ι) (a h : ι → R)
    (iDh : ∀ i : ι, PrimeSpectrum.basicOpen (h i) ⟶ U)
    (h_cover : U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h i))
    (hs :
      ∀ i : ι,
        (const R (a i) (h i) (PrimeSpectrum.basicOpen (h i)) fun y hy => hy) =
          (structureSheaf R).1.map (iDh i).op s) :
    ∃ (a' h' : ι → R) (iDh' : ∀ i : ι, PrimeSpectrum.basicOpen (h' i) ⟶ U),
      (U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h' i)) ∧
        (∀ (i) (_ : i ∈ t) (j) (_ : j ∈ t), a' i * h' j = h' i * a' j) ∧
          ∀ i ∈ t,
            (structureSheaf R).1.map (iDh' i).op s =
              const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i)) fun y hy => hy 
goal: ∃ a' h' iDh',
  U ≤ ⨆ i ∈ t, PrimeSpectrum.basicOpen (h' i) ∧
    (∀ i ∈ t, ∀ j ∈ t, a' i * h' j = h' i * a' j) ∧
      ∀ i ∈ t,
        ((AlgebraicGeometry.Spec.structureSheaf R).val.map (iDh' i).op) s =
          AlgebraicGeometry.StructureSheaf.const R (a' i) (h' i) (PrimeSpectrum.basicOpen (h' i)) ⋯

full_name: AlgebraicGeometry.StructureSheaf.toBasicOpen_surjective
code: theorem toBasicOpen_surjective (f : R) : Function.Surjective (toBasicOpen R f) 
goal: Function.Surjective ⇑(AlgebraicGeometry.StructureSheaf.toBasicOpen R f)

full_name: AlgebraicGeometry.StructureSheaf.isIso_toBasicOpen
code: instance isIso_toBasicOpen (f : R) :
    IsIso (show CommRingCat.of (Localization.Away f) ⟶ _ from toBasicOpen R f) 
goal: CategoryTheory.IsIso
  (let_fun this := AlgebraicGeometry.StructureSheaf.toBasicOpen R f;
  this)

full_name: AlgebraicGeometry.StructureSheaf.basicOpenIso
code: /-- The ring isomorphism between the structure sheaf on `basicOpen f` and the localization of `R`
at the submonoid of powers of `f`. -/
def basicOpenIso (f : R) :
    (structureSheaf R).1.obj (op (PrimeSpectrum.basicOpen f)) ≅
    CommRingCat.of (Localization.Away f) 
goal: (AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op (PrimeSpectrum.basicOpen f)) ≅
  CommRingCat.of (Localization.Away f)

full_name: AlgebraicGeometry.StructureSheaf.stalkAlgebra
code: instance stalkAlgebra (p : PrimeSpectrum R) : Algebra R ((structureSheaf R).presheaf.stalk p) 
goal: Algebra R ↑((AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk p)

full_name: AlgebraicGeometry.StructureSheaf.stalkAlgebra_map
code: @[simp]
theorem stalkAlgebra_map (p : PrimeSpectrum R) (r : R) :
    algebraMap R ((structureSheaf R).presheaf.stalk p) r = toStalk R p r 
goal: (algebraMap R ↑((AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk p)) r =
  (AlgebraicGeometry.StructureSheaf.toStalk R p) r

full_name: AlgebraicGeometry.StructureSheaf.IsLocalization.to_stalk
code: /-- Stalk of the structure sheaf at a prime p as localization of R -/
instance IsLocalization.to_stalk (p : PrimeSpectrum R) :
    IsLocalization.AtPrime ((structureSheaf R).presheaf.stalk p) p.asIdeal 
goal: IsLocalization.AtPrime (↑((AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalk p)) p.asIdeal

full_name: AlgebraicGeometry.StructureSheaf.openAlgebra
code: instance openAlgebra (U : (Opens (PrimeSpectrum R))ᵒᵖ) : Algebra R ((structureSheaf R).val.obj U) 
goal: Algebra R ↑((AlgebraicGeometry.Spec.structureSheaf R).val.obj U)

full_name: AlgebraicGeometry.StructureSheaf.openAlgebra_map
code: @[simp]
theorem openAlgebra_map (U : (Opens (PrimeSpectrum R))ᵒᵖ) (r : R) :
    algebraMap R ((structureSheaf R).val.obj U) r = toOpen R (unop U) r 
goal: (algebraMap R ↑((AlgebraicGeometry.Spec.structureSheaf R).val.obj U)) r =
  (AlgebraicGeometry.StructureSheaf.toOpen R (Opposite.unop U)) r

full_name: AlgebraicGeometry.StructureSheaf.IsLocalization.to_basicOpen
code: /-- Sections of the structure sheaf of Spec R on a basic open as localization of R -/
instance IsLocalization.to_basicOpen (r : R) :
    IsLocalization.Away r ((structureSheaf R).val.obj (op <| PrimeSpectrum.basicOpen r)) 
goal: IsLocalization.Away r ↑((AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op (PrimeSpectrum.basicOpen r)))

full_name: AlgebraicGeometry.StructureSheaf.to_basicOpen_epi
code: instance to_basicOpen_epi (r : R) : Epi (toOpen R (PrimeSpectrum.basicOpen r)) 
goal: CategoryTheory.Epi (AlgebraicGeometry.StructureSheaf.toOpen R (PrimeSpectrum.basicOpen r))

full_name: AlgebraicGeometry.StructureSheaf.to_global_factors
code: @[elementwise]
theorem to_global_factors :
    toOpen R ⊤ =
      CommRingCat.ofHom (algebraMap R (Localization.Away (1 : R))) ≫
        toBasicOpen R (1 : R) ≫
        (structureSheaf R).1.map (eqToHom PrimeSpectrum.basicOpen_one.symm).op 
goal: AlgebraicGeometry.StructureSheaf.toOpen R ⊤ =
  CommRingCat.ofHom (algebraMap R (Localization.Away 1)) ≫
    AlgebraicGeometry.StructureSheaf.toBasicOpen R 1 ≫
      (AlgebraicGeometry.Spec.structureSheaf R).val.map (CategoryTheory.eqToHom ⋯).op

full_name: AlgebraicGeometry.StructureSheaf.isIso_to_global
code: instance isIso_to_global : IsIso (toOpen R ⊤) 
goal: CategoryTheory.IsIso (AlgebraicGeometry.StructureSheaf.toOpen R ⊤)

full_name: AlgebraicGeometry.StructureSheaf.globalSectionsIso
code: /-- The ring isomorphism between the ring `R` and the global sections `Γ(X, 𝒪ₓ)`. -/
-- Porting note: was @[simps (config := { rhsMd := Tactic.Transparency.semireducible })]
@[simps!]
def globalSectionsIso : CommRingCat.of R ≅ (structureSheaf R).1.obj (op ⊤) 
goal: CommRingCat.of R ≅ (AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op ⊤)

full_name: AlgebraicGeometry.StructureSheaf.globalSectionsIso_inv
code: /-- The ring isomorphism between the ring `R` and the global sections `Γ(X, 𝒪ₓ)`. -/
-- Porting note: was @[simps (config := { rhsMd := Tactic.Transparency.semireducible })]
@[simps!]
def globalSectionsIso : CommRingCat.of R ≅ (structureSheaf R).1.obj (op ⊤) 
goal: (AlgebraicGeometry.StructureSheaf.globalSectionsIso R).inv =
  CategoryTheory.inv (AlgebraicGeometry.StructureSheaf.toOpen R ⊤)

full_name: AlgebraicGeometry.StructureSheaf.globalSectionsIso_hom_apply_coe
code: /-- The ring isomorphism between the ring `R` and the global sections `Γ(X, 𝒪ₓ)`. -/
-- Porting note: was @[simps (config := { rhsMd := Tactic.Transparency.semireducible })]
@[simps!]
def globalSectionsIso : CommRingCat.of R ≅ (structureSheaf R).1.obj (op ⊤) 
goal: ↑((AlgebraicGeometry.StructureSheaf.globalSectionsIso R).hom f) x =
  (algebraMap R (AlgebraicGeometry.StructureSheaf.Localizations R ↑x)) f

full_name: AlgebraicGeometry.StructureSheaf.globalSectionsIso_hom
code: @[simp]
theorem globalSectionsIso_hom (R : CommRingCat) : (globalSectionsIso R).hom = toOpen R ⊤ 
goal: (AlgebraicGeometry.StructureSheaf.globalSectionsIso ↑R).hom = AlgebraicGeometry.StructureSheaf.toOpen ↑R ⊤

full_name: AlgebraicGeometry.StructureSheaf.toStalk_stalkSpecializes
code: @[simp, reassoc, elementwise]
theorem toStalk_stalkSpecializes {R : Type*} [CommRing R] {x y : PrimeSpectrum R} (h : x ⤳ y) :
    toStalk R y ≫ (structureSheaf R).presheaf.stalkSpecializes h = toStalk R x 
goal: AlgebraicGeometry.StructureSheaf.toStalk R y ≫ (AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalkSpecializes h =
  AlgebraicGeometry.StructureSheaf.toStalk R x

full_name: AlgebraicGeometry.StructureSheaf.localizationToStalk_stalkSpecializes
code: @[simp, reassoc, elementwise]
theorem localizationToStalk_stalkSpecializes {R : Type*} [CommRing R] {x y : PrimeSpectrum R}
    (h : x ⤳ y) :
    StructureSheaf.localizationToStalk R y ≫ (structureSheaf R).presheaf.stalkSpecializes h =
      CommRingCat.ofHom (PrimeSpectrum.localizationMapOfSpecializes h) ≫
        StructureSheaf.localizationToStalk R x 
goal: AlgebraicGeometry.StructureSheaf.localizationToStalk R y ≫
    (AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalkSpecializes h =
  CommRingCat.ofHom (PrimeSpectrum.localizationMapOfSpecializes h) ≫
    AlgebraicGeometry.StructureSheaf.localizationToStalk R x

full_name: AlgebraicGeometry.StructureSheaf.stalkSpecializes_stalk_to_fiber
code: @[simp, reassoc, elementwise]
theorem stalkSpecializes_stalk_to_fiber {R : Type*} [CommRing R] {x y : PrimeSpectrum R}
    (h : x ⤳ y) :
    (structureSheaf R).presheaf.stalkSpecializes h ≫ StructureSheaf.stalkToFiberRingHom R x =
      StructureSheaf.stalkToFiberRingHom R y ≫
      -- Porting note: `PrimeSpectrum.localizationMapOfSpecializes h` by itself is interpreted as a
      -- ring homomorphism, so it is changed in a way to force it being interpreted as categorical
      -- arrow.
      (show CommRingCat.of (Localization.AtPrime y.asIdeal) ⟶
        CommRingCat.of (Localization.AtPrime x.asIdeal)
        from PrimeSpectrum.localizationMapOfSpecializes h) 
goal: (AlgebraicGeometry.Spec.structureSheaf R).presheaf.stalkSpecializes h ≫
    AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R x =
  AlgebraicGeometry.StructureSheaf.stalkToFiberRingHom R y ≫
    let_fun this := PrimeSpectrum.localizationMapOfSpecializes h;
    this

full_name: AlgebraicGeometry.StructureSheaf.comapFun
code: /--
Given a ring homomorphism `f : R →+* S`, an open set `U` of the prime spectrum of `R` and an open
set `V` of the prime spectrum of `S`, such that `V ⊆ (comap f) ⁻¹' U`, we can push a section `s`
on `U` to a section on `V`, by composing with `Localization.localRingHom _ _ f` from the left and
`comap f` from the right. Explicitly, if `s` evaluates on `comap f p` to `a / b`, its image on `V`
evaluates on `p` to `f(a) / f(b)`.

At the moment, we work with arbitrary dependent functions `s : Π x : U, Localizations R x`. Below,
we prove the predicate `isLocallyFraction` is preserved by this map, hence it can be extended to
a morphism between the structure sheaves of `R` and `S`.
-/
def comapFun (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) (V : Opens (PrimeSpectrum.Top S))
    (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1) (s : ∀ x : U, Localizations R x) (y : V) :
    Localizations S y 
goal: AlgebraicGeometry.StructureSheaf.Localizations S ↑y

full_name: AlgebraicGeometry.StructureSheaf.comapFunIsLocallyFraction
code: theorem comapFunIsLocallyFraction (f : R →+* S) (U : Opens (PrimeSpectrum.Top R))
    (V : Opens (PrimeSpectrum.Top S)) (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1)
    (s : ∀ x : U, Localizations R x) (hs : (isLocallyFraction R).toPrelocalPredicate.pred s) :
    (isLocallyFraction S).toPrelocalPredicate.pred (comapFun f U V hUV s) 
goal: (AlgebraicGeometry.StructureSheaf.isLocallyFraction S).pred (AlgebraicGeometry.StructureSheaf.comapFun f U V hUV s)

full_name: AlgebraicGeometry.StructureSheaf.comap
code: /-- 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) 
goal: ↑((AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op U)) →+*
  ↑((AlgebraicGeometry.Spec.structureSheaf S).val.obj (Opposite.op V))

full_name: AlgebraicGeometry.StructureSheaf.comap_apply
code: @[simp]
theorem comap_apply (f : R →+* S) (U : Opens (PrimeSpectrum.Top R))
    (V : Opens (PrimeSpectrum.Top S)) (hUV : V.1 ⊆ PrimeSpectrum.comap f ⁻¹' U.1)
    (s : (structureSheaf R).1.obj (op U)) (p : V) :
    (comap f U V hUV s).1 p =
      Localization.localRingHom (PrimeSpectrum.comap f p.1).asIdeal _ f rfl
        (s.1 ⟨PrimeSpectrum.comap f p.1, hUV p.2⟩ : _) 
goal: ↑((AlgebraicGeometry.StructureSheaf.comap f U V hUV) s) p =
  (Localization.localRingHom ((PrimeSpectrum.comap f) ↑p).asIdeal (↑p).asIdeal f ⋯) (↑s ⟨(PrimeSpectrum.comap f) ↑p, ⋯⟩)

full_name: AlgebraicGeometry.StructureSheaf.comap_const
code: 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) 
goal: (AlgebraicGeometry.StructureSheaf.comap f U V hUV) (AlgebraicGeometry.StructureSheaf.const R a b U hb) =
  AlgebraicGeometry.StructureSheaf.const S (f a) (f b) V ⋯

full_name: AlgebraicGeometry.StructureSheaf.comap_id_eq_map
code: /-- 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 
goal: AlgebraicGeometry.StructureSheaf.comap (RingHom.id R) U V ⋯ = (AlgebraicGeometry.Spec.structureSheaf R).val.map iVU.op

full_name: AlgebraicGeometry.StructureSheaf.comap_id
code: /--
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 rw [hUV]) 
goal: AlgebraicGeometry.StructureSheaf.comap (RingHom.id R) U V ⋯ = CategoryTheory.eqToHom ⋯

full_name: AlgebraicGeometry.StructureSheaf.comap_id'
code: @[simp]
theorem comap_id' (U : Opens (PrimeSpectrum.Top R)) :
    (comap (RingHom.id R) U U fun p hpU => by rwa [PrimeSpectrum.comap_id]) = RingHom.id _ 
goal: AlgebraicGeometry.StructureSheaf.comap (RingHom.id R) U U ⋯ =
  RingHom.id ↑((AlgebraicGeometry.Spec.structureSheaf R).val.obj (Opposite.op U))

full_name: AlgebraicGeometry.StructureSheaf.comap_comp
code: theorem comap_comp (f : R →+* S) (g : S →+* P) (U : Opens (PrimeSpectrum.Top R))
    (V : Opens (PrimeSpectrum.Top S)) (W : Opens (PrimeSpectrum.Top P))
    (hUV : ∀ p ∈ V, PrimeSpectrum.comap f p ∈ U) (hVW : ∀ p ∈ W, PrimeSpectrum.comap g p ∈ V) :
    (comap (g.comp f) U W fun p hpW => hUV (PrimeSpectrum.comap g p) (hVW p hpW)) =
      (comap g V W hVW).comp (comap f U V hUV) 
goal: AlgebraicGeometry.StructureSheaf.comap (g.comp f) U W ⋯ =
  (AlgebraicGeometry.StructureSheaf.comap g V W hVW).comp (AlgebraicGeometry.StructureSheaf.comap f U V hUV)

full_name: AlgebraicGeometry.StructureSheaf.toOpen_comp_comap
code: @[elementwise, reassoc]
theorem toOpen_comp_comap (f : R →+* S) (U : Opens (PrimeSpectrum.Top R)) :
    (toOpen R U ≫ comap f U (Opens.comap (PrimeSpectrum.comap f) U) fun _ => id) =
      CommRingCat.ofHom f ≫ toOpen S _ 
goal: AlgebraicGeometry.StructureSheaf.toOpen R U ≫
    AlgebraicGeometry.StructureSheaf.comap f U ((TopologicalSpace.Opens.comap (PrimeSpectrum.comap f)) U) ⋯ =
  CommRingCat.ofHom f ≫
    AlgebraicGeometry.StructureSheaf.toOpen S ((TopologicalSpace.Opens.comap (PrimeSpectrum.comap f)) U)

full_name: AlgebraicGeometry.StructureSheaf.comap_basicOpen
code: lemma comap_basicOpen (f : R →+* S) (x : R) :
    comap f (PrimeSpectrum.basicOpen x) (PrimeSpectrum.basicOpen (f x))
        (PrimeSpectrum.comap_basicOpen f x).le =
      IsLocalization.map (M := .powers x) (T := .powers (f x)) _ f
        (Submonoid.powers_le.mpr (Submonoid.mem_powers _)) 
goal: AlgebraicGeometry.StructureSheaf.comap f (PrimeSpectrum.basicOpen x) (PrimeSpectrum.basicOpen (f x)) ⋯ =
  IsLocalization.map
    (↑((AlgebraicGeometry.Spec.structureSheaf S).val.obj (Opposite.op (PrimeSpectrum.basicOpen (f x))))) f ⋯