-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[Merged by Bors] - feat(AlgebraicGeometry/Birational): Birationality and rationality of schemes #39122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
justus-springer
wants to merge
34
commits into
leanprover-community:master
from
justus-springer:justus/birational
Closed
[Merged by Bors] - feat(AlgebraicGeometry/Birational): Birationality and rationality of schemes #39122
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
96897a5
Birational
justus-springer 1c89905
fix docstring
justus-springer 8b05123
change universes of IsRationalOver
justus-springer b537f06
add section on dense opens
justus-springer c34e1e8
use `Type u` in `IsRationalOver`
justus-springer 3d96bdc
don't use OverClass
justus-springer 3096630
fixes
justus-springer ec600b7
add section on open immersions
justus-springer 0b3fc8f
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] 2620135
simps! everything
justus-springer 872c51f
update docstring, change some names
justus-springer 02ee8ef
small changes
justus-springer 30c536d
Merge branch 'justus/birational' of https://github.com/justus-springe…
justus-springer ab94069
Merge branch 'master' into justus/birational
justus-springer 0b95068
Merge branch 'master' into justus/birational
justus-springer 3490c74
Merge branch 'master' into justus/birational
justus-springer 1df80ce
fix
justus-springer ce004c1
Merge branch 'master' into justus/birational
justus-springer 08dfcc1
Merge branch 'master' into justus/birational
justus-springer a508980
fix
justus-springer eafbf8f
Merge branch 'master' into justus/birational
justus-springer 6b98083
add backward options
justus-springer d0fd850
Apply suggestions from code review
justus-springer 484df0b
Merge branch 'justus/birational' of https://github.com/justus-springe…
justus-springer ff96612
fixes
justus-springer a1c377b
add PartialIso.IsOver
justus-springer 515dabd
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] d653fe2
Apply suggestions from code review
justus-springer 1ee7969
fix
justus-springer bf1494e
Merge branch 'master' into justus/birational
justus-springer b9c8309
Merge branch 'master' into justus/birational
justus-springer 898916c
Merge branch 'master' into justus/birational
justus-springer 95fecc7
add comment
justus-springer 8367f15
Merge branch 'master' into justus/birational
justus-springer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,292 @@ | ||
| /- | ||
| Copyright (c) 2026 Justus Springer. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Justus Springer | ||
| -/ | ||
| module | ||
|
|
||
| public import Mathlib.AlgebraicGeometry.AffineSpace | ||
| public import Mathlib.AlgebraicGeometry.Birational.RationalMap | ||
|
|
||
| /-! | ||
| # Birationality and Rationality of schemes. | ||
|
|
||
| This file defines partial isomorphisms between schemes and uses them to formalize | ||
| birationality and rationality. | ||
|
|
||
| ## Main definitions | ||
|
|
||
| - `Scheme.PartialIso X Y`: an isomorphism between a dense open subscheme of `X` and a | ||
| dense open subscheme of `Y`. | ||
| - `Scheme.Birational X Y`: `X` and `Y` are birational, i.e. there exists a `PartialIso X Y`. | ||
| - `Scheme.BirationalOver sX sY`: `X` and `Y` are birational over `S` via structure maps | ||
| `sX : X ⟶ S` and `sY : Y ⟶ S`. | ||
| - `Scheme.IsRationalOver sX`: `X` is rational over `S` via structure map `sX : X ⟶ S`, | ||
| i.e. birational over `S` to some affine space `𝔸(n; S)`. | ||
|
|
||
| -/ | ||
|
|
||
| @[expose] public section | ||
|
|
||
| universe u | ||
|
|
||
| open CategoryTheory | ||
|
|
||
| namespace AlgebraicGeometry.Scheme | ||
|
|
||
| /-- A partial isomorphism from `X` to `Y` is an isomorphism between dense open subschemes | ||
| of `X` and `Y`. -/ | ||
| structure PartialIso (X Y : Scheme.{u}) where | ||
| /-- The source open subscheme of a partial isomorphism. -/ | ||
| source : X.Opens | ||
| dense_source : Dense (source : Set X) | ||
| /-- The target open subscheme of a partial isomorphism. -/ | ||
| target : Y.Opens | ||
| dense_target : Dense (target : Set Y) | ||
| /-- The underlying isomorphism of a partial isomorphism. -/ | ||
| iso : source.toScheme ≅ target.toScheme | ||
|
chrisflav marked this conversation as resolved.
|
||
|
|
||
| namespace PartialIso | ||
|
|
||
| variable {X Y Z S : Scheme.{u}} {sX : X ⟶ S} {sY : Y ⟶ S} {sZ : Z ⟶ S} | ||
|
|
||
| variable (sX sY) in | ||
| /-- A partial iso is an `S`-map if the underlying morphism is. -/ | ||
| abbrev IsOver (f : X.PartialIso Y) : Prop := | ||
| f.iso.hom ≫ f.target.ι ≫ sY = f.source.ι ≫ sX | ||
|
|
||
| lemma ext_iff (f g : X.PartialIso Y) : | ||
| f = g ↔ ∃ (e : f.source = g.source) (e' : g.target = f.target), | ||
| f.iso = X.isoOfEq e ≪≫ g.iso ≪≫ Y.isoOfEq e' := by | ||
| constructor | ||
| · rintro rfl | ||
| simp | ||
| · obtain ⟨U₁, hU₁, U₂, hU₂, f⟩ := f | ||
| obtain ⟨V₁, hV₁, V₂, hU₂, g⟩ := g | ||
| simp only [forall_exists_index] | ||
| rintro rfl rfl e | ||
| simpa using e | ||
|
|
||
| @[ext] | ||
| lemma ext (f g : X.PartialIso Y) (e : f.source = g.source) (e' : g.target = f.target) | ||
| (H : f.iso = X.isoOfEq e ≪≫ g.iso ≪≫ Y.isoOfEq e') : f = g := by | ||
| rw [ext_iff] | ||
| exact ⟨e, e', H⟩ | ||
|
|
||
| variable (X) in | ||
| /-- The identity partial isomorphism on `X`, defined on all of `X`. -/ | ||
| @[refl, simps] | ||
| def refl : X.PartialIso X where | ||
| source := ⊤ | ||
| dense_source := dense_univ | ||
| target := ⊤ | ||
| dense_target := dense_univ | ||
| iso := Iso.refl _ | ||
|
|
||
| /-- The inverse of a partial isomorphism. -/ | ||
| @[symm, simps] | ||
| def symm (f : X.PartialIso Y) : Y.PartialIso X where | ||
| source := f.target | ||
| dense_source := f.dense_target | ||
| target := f.source | ||
| dense_target := f.dense_source | ||
| iso := f.iso.symm | ||
|
|
||
| set_option backward.defeqAttrib.useBackward true in | ||
| lemma IsOver.symm {f : X.PartialIso Y} (hf : f.IsOver sX sY) : f.symm.IsOver sY sX := by | ||
| simpa [IsOver, ← cancel_epi f.iso.hom] using Eq.symm hf | ||
|
|
||
| /-- Compose two partial isomorphisms along a proof that the target of `f` equals the source | ||
| of `g`. See `trans` for the version that does not require this. -/ | ||
| @[simps] | ||
| noncomputable def trans' (f : X.PartialIso Y) (g : Y.PartialIso Z) (e : f.target = g.source) : | ||
| X.PartialIso Z where | ||
| source := f.source | ||
| dense_source := f.dense_source | ||
| target := g.target | ||
| dense_target := g.dense_target | ||
| iso := f.iso ≪≫ Y.isoOfEq e ≪≫ g.iso | ||
|
|
||
| set_option backward.defeqAttrib.useBackward true in | ||
| lemma IsOver.trans' {f : X.PartialIso Y} {g : Y.PartialIso Z} {e : f.target = g.source} | ||
| (hf : f.IsOver sX sY) (hg : g.IsOver sY sZ) : (trans' f g e).IsOver sX sZ := by | ||
| simp [IsOver, ← hf, hg] | ||
|
|
||
| /-- Restrict the source of a partial isomorphism to a smaller dense open. -/ | ||
| @[simps] | ||
| noncomputable def restrictSource (f : X.PartialIso Y) (U : Opens X) (hU : Dense (U : Set X)) | ||
| (hU' : U ≤ f.source) : X.PartialIso Y where | ||
| source := U | ||
| dense_source := hU | ||
| target := f.target.ι ''ᵁ f.iso.hom ''ᵁ f.source.ι ⁻¹ᵁ U | ||
| dense_target := | ||
| have := Opens.isDominant_ι f.dense_target | ||
| f.target.ι.denseRange.dense_image f.target.ι.continuous <| | ||
| f.iso.hom.denseRange.dense_image f.iso.hom.continuous <| | ||
| hU.preimage f.source.ι.isOpenEmbedding.isOpenMap | ||
| iso := (Opens.isoOfLE hU').symm ≪≫ | ||
| (f.iso.hom.isoImage (f.source.ι ⁻¹ᵁ U)) ≪≫ | ||
| (f.target.ι.isoImage (f.iso.hom ''ᵁ f.source.ι ⁻¹ᵁ U)) | ||
|
|
||
| set_option backward.defeqAttrib.useBackward true in | ||
| lemma IsOver.restrictSource {f : X.PartialIso Y} (hf : f.IsOver sX sY) (U : Opens X) | ||
| (hU : Dense (U : Set X)) (hU' : U ≤ f.source) : | ||
| (f.restrictSource U hU hU').IsOver sX sY := by | ||
| simp [IsOver, hf] | ||
|
|
||
| /-- Restrict the target of a partial isomorphism to a smaller dense open. -/ | ||
| @[simps! source target iso] | ||
| noncomputable def restrictTarget (f : X.PartialIso Y) (U : Opens Y) (hU : Dense (U : Set Y)) | ||
| (hU' : U ≤ f.target) : X.PartialIso Y := | ||
| (f.symm.restrictSource U hU hU').symm | ||
|
|
||
| lemma IsOver.restrictTarget {f : X.PartialIso Y} (hf : f.IsOver sX sY) (U : Opens Y) | ||
| (hU : Dense (U : Set Y)) (hU' : U ≤ f.target) : | ||
| (f.restrictTarget U hU hU').IsOver sX sY := | ||
| (hf.symm.restrictSource U hU hU').symm | ||
|
|
||
| /-- Compose two partial isomorphisms, restricting to the intersection of the intermediate opens. -/ | ||
| @[trans, simps! source target iso] | ||
| noncomputable def trans (f : X.PartialIso Y) (g : Y.PartialIso Z) : X.PartialIso Z := | ||
| have := f.dense_target.inter_of_isOpen_right g.dense_source g.source.2 | ||
| (f.restrictTarget _ this inf_le_left).trans' (g.restrictSource _ this inf_le_right) rfl | ||
|
|
||
| lemma IsOver.trans {f : X.PartialIso Y} {g : Y.PartialIso Z} (hf : f.IsOver sX sY) | ||
| (hg : g.IsOver sY sZ) : (f.trans g).IsOver sX sZ := | ||
| (hf.restrictTarget _ _ _).trans' (hg.restrictSource _ _ _) | ||
|
|
||
| /-- The underlying partial map of a partial isomorphism. -/ | ||
| @[simps] | ||
| def toPartialMap (f : X.PartialIso Y) : X.PartialMap Y where | ||
| domain := f.source | ||
| dense_domain := f.dense_source | ||
| hom := f.iso.hom ≫ f.target.ι | ||
|
|
||
| /-- The underlying rational map of a partial isomorphism. -/ | ||
| abbrev toRationalMap (f : X.PartialIso Y) : X ⤏ Y := f.toPartialMap.toRationalMap | ||
|
|
||
| /-- A scheme isomorphism viewed as a partial isomorphism defined on all of `X` and `Y`. -/ | ||
| @[simps] | ||
| noncomputable def ofIso (f : X ≅ Y) : X.PartialIso Y where | ||
| source := ⊤ | ||
| dense_source := dense_univ | ||
| target := ⊤ | ||
| dense_target := dense_univ | ||
| iso := X.topIso ≪≫ f ≪≫ Y.topIso.symm | ||
|
|
||
| end PartialIso | ||
|
|
||
| /-- `X` and `Y` are birational if there exists a partial isomorphism between them. -/ | ||
| @[stacks 0A20 "(1)"] | ||
| def Birational (X Y : Scheme.{u}) : Prop := Nonempty (PartialIso X Y) | ||
|
justus-springer marked this conversation as resolved.
|
||
|
|
||
| /-- Choose a partial isomorphism witnessing that `X` and `Y` are birational. -/ | ||
| noncomputable def Birational.partialIso {X Y : Scheme.{u}} (h : Birational X Y) : | ||
| PartialIso X Y := | ||
| Classical.choice h | ||
|
|
||
| @[refl] | ||
| lemma Birational.refl (X : Scheme.{u}) : Birational X X := | ||
| ⟨.refl X⟩ | ||
|
|
||
| @[symm] | ||
| lemma Birational.symm {X Y : Scheme.{u}} (h : Birational X Y) : Birational Y X := | ||
| ⟨h.partialIso.symm⟩ | ||
|
|
||
| @[trans] | ||
| lemma Birational.trans {X Y Z : Scheme.{u}} (h₁ : Birational X Y) (h₂ : Birational Y Z) : | ||
| Birational X Z := | ||
| ⟨h₁.partialIso.trans h₂.partialIso⟩ | ||
|
|
||
| /-- `X` and `Y` are birational over `S` if there exists a partial isomorphism between them | ||
| that is compatible with the structure maps to `S`. -/ | ||
| def BirationalOver {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) : Prop := | ||
| ∃ f : PartialIso X Y, f.IsOver sX sY | ||
|
|
||
| /-- Choose a partial isomorphism witnessing that `X` and `Y` are birational over `S`. -/ | ||
| noncomputable def BirationalOver.partialIso {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) | ||
| (h : BirationalOver sX sY) := | ||
| h.choose | ||
|
|
||
| lemma BirationalOver.partialIso_isOver {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) | ||
| (h : BirationalOver sX sY) : h.partialIso.IsOver sX sY := | ||
| h.choose_spec | ||
|
|
||
| set_option backward.defeqAttrib.useBackward true in | ||
| lemma BirationalOver.refl {S X : Scheme.{u}} (sX : X ⟶ S) : BirationalOver sX sX := | ||
| ⟨.refl X, by simp [PartialIso.IsOver]⟩ | ||
|
|
||
| lemma BirationalOver.symm {S X Y : Scheme.{u}} {sX : X ⟶ S} {sY : Y ⟶ S} | ||
| (h : BirationalOver sX sY) : BirationalOver sY sX := | ||
| ⟨h.partialIso.symm, h.partialIso_isOver.symm⟩ | ||
|
|
||
| lemma BirationalOver.trans {S X Y Z : Scheme.{u}} {sX : X ⟶ S} {sY : Y ⟶ S} {sZ : Z ⟶ S} | ||
| (h₁ : BirationalOver sX sY) (h₂ : BirationalOver sY sZ) : | ||
| BirationalOver sX sZ := | ||
| ⟨h₁.partialIso.trans h₂.partialIso, h₁.partialIso_isOver.trans h₂.partialIso_isOver⟩ | ||
|
|
||
| /-- `X` is rational over `S` (or `S`-rational) if it is birational over `S` to some | ||
| affine space `𝔸(n; S)`. Note that we do not require `n` to be finite here. -/ | ||
| @[mk_iff] | ||
| class IsRationalOver {S X : Scheme.{u}} (sX : X ⟶ S) : Prop where | ||
| exists_birationalOver_affineSpace (sX) : ∃ (n : Type u), BirationalOver sX (𝔸(n; S) ↘ S) | ||
|
|
||
| instance (S : Scheme.{u}) (n : Type u) : IsRationalOver (𝔸(n; S) ↘ S) where | ||
| exists_birationalOver_affineSpace := ⟨n, .refl _⟩ | ||
|
|
||
| /-- If a scheme `X` is `S`-birational to an `S`-rational scheme `Y`, then `X` is `S`-rational. -/ | ||
| lemma BirationalOver.isRationalOver {S X Y : Scheme.{u}} (sX : X ⟶ S) (sY : Y ⟶ S) | ||
| [IsRationalOver sY] (h : BirationalOver sX sY) : IsRationalOver sX := by | ||
| obtain ⟨n, hn⟩ := IsRationalOver.exists_birationalOver_affineSpace sY | ||
| exact ⟨n, h.trans hn⟩ | ||
|
|
||
| section DenseOpen | ||
|
|
||
| variable {X S : Scheme.{u}} (U : Opens X) (sX : X ⟶ S) | ||
|
|
||
| /-- A dense open set `U : Opens X` induces a partial isomorphism between `U` and `X`. -/ | ||
| @[simps] | ||
| def Opens.partialIsoOfDense (hU : Dense (U : Set X)) : PartialIso U X where | ||
| source := ⊤ | ||
| dense_source := dense_univ | ||
| target := U | ||
| dense_target := hU | ||
| iso := U.toScheme.topIso | ||
|
|
||
| /-- A dense open set `U : Opens X` is birational to `X`. -/ | ||
| lemma Opens.birational_of_dense (hU : Dense (U : Set X)) : Birational U X := | ||
| ⟨U.partialIsoOfDense hU⟩ | ||
|
|
||
| set_option backward.defeqAttrib.useBackward true in | ||
| /-- A dense open set `U : Opens X` of a scheme `X` over `S` is `S`-birational to `X`. -/ | ||
| lemma Opens.birationalOver_of_dense (hU : Dense (U : Set X)) : BirationalOver (U.ι ≫ sX) sX := | ||
| ⟨U.partialIsoOfDense hU, by simp [PartialIso.IsOver]⟩ | ||
|
|
||
| /-- A dense open set `U : Opens X` of a `S`-rational scheme `X` is `S`-rational. -/ | ||
| lemma Opens.isRationalOver_of_dense (hU : Dense (U : Set X)) [IsRationalOver sX] : | ||
| IsRationalOver (U.ι ≫ sX) := by | ||
| obtain ⟨n, hn⟩ := IsRationalOver.exists_birationalOver_affineSpace sX | ||
| exact ⟨n, (U.birationalOver_of_dense sX hU).trans hn⟩ | ||
|
|
||
| end DenseOpen | ||
|
|
||
| section OpenImmersion | ||
|
|
||
| variable {X U S : Scheme.{u}} | ||
|
|
||
| /-- A dominant open immersion `f : U ⟶ X` induces a partial isomorphism between `U` and `X`. -/ | ||
| @[simps! source target iso] | ||
| noncomputable def Hom.partialIso (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] : U.PartialIso X := | ||
| (PartialIso.ofIso f.isoOpensRange).trans' (f.opensRange.partialIsoOfDense f.denseRange) rfl | ||
|
|
||
| lemma Hom.birational (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] : Birational U X := | ||
| ⟨f.partialIso⟩ | ||
|
|
||
| set_option backward.defeqAttrib.useBackward true in | ||
| lemma Hom.birationalOver (f : U ⟶ X) [IsOpenImmersion f] [IsDominant f] (sX : X ⟶ S) (sU : U ⟶ S) | ||
| (hf : f ≫ sX = sU) : BirationalOver sU sX := | ||
| ⟨f.partialIso, by simp [PartialIso.IsOver, hf]⟩ | ||
|
|
||
| end OpenImmersion | ||
|
|
||
| end AlgebraicGeometry.Scheme | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.