-
Notifications
You must be signed in to change notification settings - Fork 362
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
feat(AlgebraicGeometry): flat morphisms of schemes #19790
base: master
Are you sure you want to change the base?
Changes from all commits
0028510
cf13e4b
78fd2bc
48ad682
50b003e
c128fe4
ca7c721
b1e263f
ce3eea2
5c2203a
c57f166
a173e8b
68463ed
3a46e91
998147a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/- | ||
Copyright (c) 2024 Christian Merten. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Christian Merten | ||
-/ | ||
import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties | ||
import Mathlib.RingTheory.RingHom.Flat | ||
|
||
/-! | ||
# Flat morphisms | ||
|
||
A morphism of schemes `f : X ⟶ Y` is flat if for each affine `U ⊆ Y` and | ||
`V ⊆ f ⁻¹' U`, the induced map `Γ(Y, U) ⟶ Γ(X, V)` is flat. | ||
|
||
We show that this property is local, and are stable under compositions and base change. | ||
|
||
-/ | ||
|
||
noncomputable section | ||
|
||
open CategoryTheory CategoryTheory.Limits Opposite TopologicalSpace | ||
|
||
universe v u | ||
|
||
namespace AlgebraicGeometry | ||
|
||
variable {X Y : Scheme.{u}} (f : X ⟶ Y) | ||
|
||
/-- A morphism of schemes `f : X ⟶ Y` is flat if for each affine `U ⊆ Y` and | ||
`V ⊆ f ⁻¹' U`, the induced map `Γ(Y, U) ⟶ Γ(X, V)` is flat. | ||
-/ | ||
@[mk_iff] | ||
class Flat (f : X ⟶ Y) : Prop where | ||
flat_of_affine_subset : | ||
∀ (U : Y.affineOpens) (V : X.affineOpens) (e : V.1 ≤ f ⁻¹ᵁ U.1), (f.appLE U V e).hom.Flat | ||
|
||
namespace Flat | ||
|
||
instance : HasRingHomProperty @Flat RingHom.Flat where | ||
isLocal_ringHomProperty := RingHom.Flat.propertyIsLocal | ||
eq_affineLocally' := by | ||
ext X Y f | ||
rw [flat_iff, affineLocally_iff_affineOpens_le] | ||
|
||
instance (priority := 900) [IsOpenImmersion f] : Flat f := | ||
HasRingHomProperty.of_isOpenImmersion | ||
RingHom.Flat.containsIdentities | ||
|
||
instance : MorphismProperty.IsStableUnderComposition @Flat := | ||
HasRingHomProperty.stableUnderComposition RingHom.Flat.stableUnderComposition | ||
|
||
instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) | ||
[hf : Flat f] [hg : Flat g] : Flat (f ≫ g) := | ||
MorphismProperty.comp_mem _ f g hf hg | ||
|
||
instance : MorphismProperty.IsMultiplicative @Flat where | ||
id_mem _ := inferInstance | ||
|
||
instance isStableUnderBaseChange : MorphismProperty.IsStableUnderBaseChange @Flat := | ||
HasRingHomProperty.isStableUnderBaseChange RingHom.Flat.isStableUnderBaseChange | ||
|
||
lemma of_stalkMap (H : ∀ x, (f.stalkMap x).hom.Flat) : Flat f := | ||
HasRingHomProperty.of_stalkMap RingHom.Flat.ofLocalizationPrime H | ||
|
||
lemma stalkMap [Flat f] (x : X) : (f.stalkMap x).hom.Flat := | ||
HasRingHomProperty.stalkMap (P := @Flat) | ||
(fun f hf J hJ ↦ hf.localRingHom J (J.comap f) rfl) ‹_› x | ||
|
||
lemma iff_flat_stalkMap : Flat f ↔ ∀ x, (f.stalkMap x).hom.Flat := | ||
⟨fun _ ↦ stalkMap f, fun H ↦ of_stalkMap f H⟩ | ||
|
||
end Flat | ||
|
||
end AlgebraicGeometry |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -530,7 +530,8 @@ private lemma respects_isOpenImmersion_aux | |
let f' : (V s).toScheme ⟶ U.ι ⁻¹ᵁ s := f ∣_ U.ι ⁻¹ᵁ s | ||
have hf' : P f' := IsLocalAtTarget.restrict hf _ | ||
let e : (U.ι ⁻¹ᵁ s).toScheme ≅ s := IsOpenImmersion.isoOfRangeEq ((U.ι ⁻¹ᵁ s).ι ≫ U.ι) s.1.ι | ||
(by simpa [Set.range_comp, Set.image_preimage_eq_iff, heq] using le_sSup s.2) | ||
(by simpa only [Scheme.comp_coeBase, TopCat.coe_comp, Set.range_comp, Scheme.Opens.range_ι, | ||
Opens.map_coe, Set.image_preimage_eq_iff, heq, Opens.coe_sSup] using le_sSup s.2) | ||
have heq : (V s).ι ≫ f ≫ U.ι = f' ≫ e.hom ≫ s.1.ι := by | ||
simp only [V, IsOpenImmersion.isoOfRangeEq_hom_fac, f', e, morphismRestrict_ι_assoc] | ||
rw [heq, ← Category.assoc] | ||
|
@@ -633,6 +634,69 @@ lemma locally_of_iff (hQl : LocalizationAwayPreserves Q) | |
ext X Y f | ||
rw [h, iff_exists_appLE_locally (P := affineLocally (Locally Q)) hQa.left hQa.respectsIso] | ||
|
||
/-- If `Q` is a property of ring maps that can be checked on prime ideals, the | ||
associated property of scheme morphisms can be checked on stalks. -/ | ||
lemma of_stalkMap (hQ : OfLocalizationPrime Q) (H : ∀ x, Q (f.stalkMap x).hom) : P f := by | ||
chrisflav marked this conversation as resolved.
Show resolved
Hide resolved
|
||
have hQi := (HasRingHomProperty.isLocal_ringHomProperty P).respectsIso | ||
wlog hY : IsAffine Y generalizing X Y f | ||
· rw [IsLocalAtTarget.iff_of_iSup_eq_top (P := P) _ (iSup_affineOpens_eq_top _)] | ||
intro U | ||
refine this (fun x ↦ ?_) U.2 | ||
exact (hQi.arrow_mk_iso_iff (AlgebraicGeometry.morphismRestrictStalkMap f U x)).mpr (H x.val) | ||
wlog hX : IsAffine X generalizing X f | ||
· rw [IsLocalAtSource.iff_of_iSup_eq_top (P := P) _ (iSup_affineOpens_eq_top _)] | ||
intro U | ||
refine this ?_ U.2 | ||
intro x | ||
rw [Scheme.stalkMap_comp, CommRingCat.hom_comp, hQi.cancel_right_isIso] | ||
exact H x.val | ||
wlog hXY : ∃ R S, Y = Spec R ∧ X = Spec S generalizing X Y | ||
· rw [← P.cancel_right_of_respectsIso (g := Y.isoSpec.hom)] | ||
rw [← P.cancel_left_of_respectsIso (f := X.isoSpec.inv)] | ||
refine this inferInstance (fun x ↦ ?_) inferInstance ?_ | ||
· rw [Scheme.stalkMap_comp, Scheme.stalkMap_comp, CommRingCat.hom_comp, | ||
hQi.cancel_right_isIso, CommRingCat.hom_comp, hQi.cancel_left_isIso] | ||
apply H | ||
· use Γ(Y, ⊤), Γ(X, ⊤) | ||
obtain ⟨R, S, rfl, rfl⟩ := hXY | ||
obtain ⟨φ, rfl⟩ := Spec.map_surjective f | ||
rw [Spec_iff (P := P)] | ||
apply hQ | ||
intro P hP | ||
specialize H ⟨P, hP⟩ | ||
rwa [hQi.arrow_mk_iso_iff (Scheme.arrowStalkMapSpecIso φ _)] at H | ||
|
||
/-- Let `Q` be a property of ring maps that is stable under localization. | ||
Then if the associated property of scheme morphisms holds for `f`, `Q` holds on all stalks. -/ | ||
lemma stalkMap | ||
(hQ : ∀ {R S : Type u} [CommRing R] [CommRing S] (f : R →+* S) (_ : Q f) | ||
(J : Ideal S) (_ : J.IsPrime), Q (Localization.localRingHom _ J f rfl)) | ||
Comment on lines
+672
to
+673
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could give this a name (I don't think this follows from |
||
(hf : P f) (x : X) : Q (f.stalkMap x).hom := by | ||
have hQi := (HasRingHomProperty.isLocal_ringHomProperty P).respectsIso | ||
wlog h : IsAffine X ∧ IsAffine Y generalizing X Y f | ||
· obtain ⟨U, hU, hfx, _⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open Y) | ||
(Opens.mem_top <| f.base x) | ||
obtain ⟨V, hV, hx, e⟩ := Opens.isBasis_iff_nbhd.mp (isBasis_affine_open X) | ||
(show x ∈ f ⁻¹ᵁ U from hfx) | ||
rw [← hQi.arrow_mk_iso_iff (Scheme.Hom.resLEStalkMap f e ⟨x, hx⟩)] | ||
exact this (IsLocalAtSource.resLE _ hf) _ ⟨hV, hU⟩ | ||
obtain ⟨hX, hY⟩ := h | ||
wlog hXY : ∃ R S, Y = Spec R ∧ X = Spec S generalizing X Y | ||
· have : Q ((X.isoSpec.inv ≫ f ≫ Y.isoSpec.hom).stalkMap (X.isoSpec.hom.base x)).hom := by | ||
refine this ?_ (X.isoSpec.hom.base x) inferInstance inferInstance ?_ | ||
· rwa [P.cancel_left_of_respectsIso, P.cancel_right_of_respectsIso] | ||
· use Γ(Y, ⊤), Γ(X, ⊤) | ||
rw [Scheme.stalkMap_comp, Scheme.stalkMap_comp, CommRingCat.hom_comp, | ||
hQi.cancel_right_isIso, CommRingCat.hom_comp, hQi.cancel_left_isIso] at this | ||
have heq : (X.isoSpec.inv.base (X.isoSpec.hom.base x)) = x := by simp | ||
rwa [hQi.arrow_mk_iso_iff | ||
(Scheme.arrowStalkMapIsoOfInseparable f <| Inseparable.of_eq heq)] at this | ||
obtain ⟨R, S, rfl, rfl⟩ := hXY | ||
obtain ⟨φ, rfl⟩ := Spec.map_surjective f | ||
rw [hQi.arrow_mk_iso_iff (Scheme.arrowStalkMapSpecIso φ _)] | ||
rw [Spec_iff (P := P)] at hf | ||
apply hQ _ hf | ||
|
||
end HasRingHomProperty | ||
|
||
end AlgebraicGeometry |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -761,6 +761,14 @@ lemma stalkMap_germ_apply (U : Y.Opens) (x : X) (hx : f.base x ∈ U) (y) : | |
X.presheaf.germ (f ⁻¹ᵁ U) x hx (f.app U y) := | ||
PresheafedSpace.stalkMap_germ_apply f.toPshHom U x hx y | ||
|
||
/-- If `x` and `y` are inseparable, the stalk maps are isomorphic. -/ | ||
noncomputable def arrowStalkMapIsoOfInseparable {x y : X} | ||
(h : Inseparable x y) : Arrow.mk (f.stalkMap x) ≅ Arrow.mk (f.stalkMap y) := | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think using |
||
Arrow.isoMk (Y.presheaf.stalkCongr <| h.map f.continuous) (X.presheaf.stalkCongr h) <| by | ||
simp only [Arrow.mk_left, Arrow.mk_right, Functor.id_obj, TopCat.Presheaf.stalkCongr_hom, | ||
Arrow.mk_hom] | ||
rw [Scheme.stalkSpecializes_stalkMap] | ||
|
||
end Scheme | ||
|
||
end Stalks | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you point to
iff_flat_stalkMap
here, as that is the more common definition in the literature? (also in the module docstring)