Skip to content

Commit 3ad5185

Browse files
committed
feat(AlgebraicGeometry): universal property of relative normalization (leanprover-community#33476)
1 parent 5e280db commit 3ad5185

4 files changed

Lines changed: 154 additions & 12 deletions

File tree

Mathlib/AlgebraicGeometry/AffineScheme.lean

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,12 @@ lemma Scheme.Opens.toSpecΓ_naturality {X Y : Scheme} (f : X ⟶ Y) (U : Y.Opens
363363
eqToHom_op, Hom.app_eq_appLE, Category.assoc, ← Spec.map_comp, Hom.appLE_map,
364364
toSpecΓ_naturality_assoc, TopologicalSpace.Opens.map_top, morphismRestrict_appLE, Hom.map_appLE]
365365

366+
@[reassoc (attr := simp)]
367+
lemma Scheme.Opens.toSpecΓ_SpecMap_appLE
368+
{X Y : Scheme} (f : X ⟶ Y) (U : Y.Opens) (V : X.Opens) (hUV) :
369+
V.toSpecΓ ≫ Spec.map (f.appLE U V hUV) = f.resLE U V hUV ≫ U.toSpecΓ := by
370+
simp [Hom.appLE, Hom.resLE]
371+
366372
namespace IsAffineOpen
367373

368374
variable {X Y : Scheme.{u}} {U : X.Opens} (hU : IsAffineOpen U) (f : Γ(X, U))
@@ -998,6 +1004,22 @@ theorem of_affine_open_cover {X : Scheme} {P : X.affineOpens → Prop}
9981004
rw [iSup_range', SetLike.mem_coe, Opens.mem_iSup]
9991005
exact ⟨_, hf₁ ⟨x, hx⟩⟩
10001006

1007+
/-- If `φ` is a monomorphism in `CommRingCat`, it is not in general true that `Spec φ` is epi.
1008+
(`ℤ ⊆ ℤ[1/2]` but `Spec ℤ[1/2] ⟶ Spec ℤ` is not epi, since epi open immersions are isomorphisms)
1009+
But if the range of `f g : Spec R ⟶ X` are contained in an common affine open `U`, one can still
1010+
cancel `Spec.map φ ≫ f = Spec.map φ ≫ g` to get `f = g`. -/
1011+
lemma eq_of_SpecMap_comp_eq_of_isAffineOpen {R S : CommRingCat} {X : Scheme}
1012+
(φ : R ⟶ S) (hφ : Function.Injective φ)
1013+
{f g : Spec R ⟶ X} (U : X.Opens) (hU : IsAffineOpen U) (hUf : f ⁻¹ᵁ U = ⊤) (hUg : g ⁻¹ᵁ U = ⊤)
1014+
(H : Spec.map φ ≫ f = Spec.map φ ≫ g) : f = g := by
1015+
have : Mono φ := ConcreteCategory.mono_of_injective _ hφ
1016+
rw [← IsOpenImmersion.lift_fac U.ι f (by simpa [Set.range_subset_iff] using fun x hx ↦ hUf.ge hx),
1017+
← IsOpenImmersion.lift_fac U.ι g (by simpa [Set.range_subset_iff] using fun x hx ↦ hUg.ge hx)]
1018+
congr 1
1019+
rw [← cancel_mono hU.isoSpec.hom, ← Spec.homEquiv.injective.eq_iff,
1020+
← cancel_mono φ, ← Spec.map_injective.eq_iff]
1021+
simp [← cancel_mono U.ι, H]
1022+
10011023
section ZeroLocus
10021024

10031025
namespace Scheme

Mathlib/AlgebraicGeometry/Morphisms/QuasiCompact.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ theorem quasiCompact_iff_isSpectralMap : QuasiCompact f ↔ IsSpectralMap f :=
5252
theorem Scheme.Hom.isSpectralMap [QuasiCompact f] : IsSpectralMap f := by
5353
rwa [← quasiCompact_iff_isSpectralMap]
5454

55+
lemma Scheme.Hom.isCompact_preimage [QuasiCompact f] {U : Opens Y}
56+
(hU : IsCompact (U : Set Y)) : IsCompact (f ⁻¹ᵁ U : Set X) :=
57+
f.isSpectralMap.2 U.2 hU
58+
5559
@[deprecated (since := "2025-10-07")]
5660
alias quasiCompact_iff_spectral := quasiCompact_iff_isSpectralMap
5761

Mathlib/AlgebraicGeometry/Morphisms/QuasiSeparated.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ theorem quasiSeparatedSpace_of_quasiSeparated (f : X ⟶ Y)
159159
rw [← terminalIsTerminal.hom_ext (f ≫ terminal.from Y) (terminal.from X)]
160160
infer_instance
161161

162+
lemma Scheme.Hom.isQuasiSeparated_preimage [QuasiSeparated f] {U : Opens Y}
163+
(hU : IsQuasiSeparated (U : Set Y)) : IsQuasiSeparated (f ⁻¹ᵁ U : Set X) := by
164+
have : QuasiSeparatedSpace U := (isQuasiSeparated_iff_quasiSeparatedSpace _ U.2).mp hU
165+
exact (isQuasiSeparated_iff_quasiSeparatedSpace _ (f ⁻¹ᵁ U).2).mpr
166+
(quasiSeparatedSpace_of_quasiSeparated (f ∣_ U))
167+
162168
instance quasiSeparatedSpace_of_isAffine (X : Scheme) [IsAffine X] : QuasiSeparatedSpace X :=
163169
(quasiSeparatedSpace_congr X.isoSpec.hom.homeomorph).2 PrimeSpectrum.instQuasiSeparatedSpace
164170

Mathlib/AlgebraicGeometry/Normalization.lean

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ along with the maps that `f` factor into:
1717
- `f.toNormalization : X ⟶ f.normalization`: a dominant morphism
1818
- `f.fromNormalization : f.normalization ⟶ Y`: an integral morphism
1919
20-
## TODO
21-
- show the universal property of relative normalization
20+
It satisfies the universal property:
21+
For any factorization `X ⟶ T ⟶ Y` with `T ⟶ Y` integral,
22+
the map `X ⟶ T` factors through `f.normalization` uniquely.
23+
The factorization map is `AlgebraicGeometry.Scheme.Hom.normalizationDesc`, and the uniqueness result
24+
is `AlgebraicGeometry.Scheme.Hom.normalization.hom_ext`.
25+
2226
-/
2327

2428
@[expose] public noncomputable section
@@ -64,16 +68,6 @@ def normalizationDiagramMap : Y.presheaf ⟶ f.normalizationDiagram where
6468
CommRingCat.ofHom (algebraMap Γ(Y, U.unop) (integralClosure Γ(Y, U.unop) Γ(X, f ⁻¹ᵁ U.unop)))
6569
naturality {U V} i := by ext x; exact Subtype.ext congr($(f.naturality i) x)
6670

67-
lemma isCompact_preimage [QuasiCompact f] {U : Opens Y}
68-
(hU : IsCompact (U : Set Y)) : IsCompact (f ⁻¹ᵁ U : Set X) :=
69-
f.isSpectralMap.2 U.2 hU
70-
71-
lemma isQuasiSeparated_preimage [QuasiSeparated f] {U : Opens Y}
72-
(hU : IsQuasiSeparated (U : Set Y)) : IsQuasiSeparated (f ⁻¹ᵁ U : Set X) := by
73-
have : QuasiSeparatedSpace U := (isQuasiSeparated_iff_quasiSeparatedSpace _ U.2).mp hU
74-
exact (isQuasiSeparated_iff_quasiSeparatedSpace _ (f ⁻¹ᵁ U).2).mpr
75-
(quasiSeparatedSpace_of_quasiSeparated (f ∣_ U))
76-
7771
variable [QuasiCompact f] [QuasiSeparated f]
7872

7973
lemma preservesLocalization_normalizationDiagramMap :
@@ -312,4 +306,120 @@ instance [IsIntegral X] : IsIntegral f.normalization :=
312306
simpa using f.toNormalization.denseRange.closure_range.symm
313307
isIntegral_of_irreducibleSpace_of_isReduced _
314308

309+
section UniversalProperty
310+
311+
variable {T : Scheme.{u}} (f₁ : X ⟶ T) (f₂ : T ⟶ Y) [IsIntegralHom f₂]
312+
313+
/-- Given an qcqs morphism `f : X ⟶ Y`, which factors into `X ⟶ T ⟶ Y` with `T ⟶ Y` integral,
314+
the map `X ⟶ T` factors through `f.normalization` uniquely.
315+
(See `normalization.hom_ext` for the uniqueness result) -/
316+
noncomputable
317+
def normalizationDesc (H : f = f₁ ≫ f₂) : f.normalization ⟶ T := by
318+
refine colimit.desc _
319+
{ pt := _
320+
ι.app U := Spec.map (CommRingCat.ofHom ((f₁.appLE _ _ (by simp [H])).hom.codRestrict _
321+
fun x ↦ ?_)) ≫ (U.2.preimage f₂).fromSpec,
322+
ι.naturality := ?_ }
323+
· algebraize [(f.app U.1).hom, (f₂.app U.1).hom,
324+
(f₁.appLE (f₂ ⁻¹ᵁ U.1) (f ⁻¹ᵁ U.1) (by simp [H])).hom]
325+
have : IsScalarTower Γ(Y, U.1) Γ(T, f₂ ⁻¹ᵁ U.1) Γ(X, f ⁻¹ᵁ U.1) := .of_algebraMap_eq' <| by
326+
simp only [RingHom.algebraMap_toAlgebra, ← CommRingCat.hom_comp,
327+
Hom.app_eq_appLE, Hom.appLE_comp_appLE, ← H]
328+
exact .algebraMap (R := Γ(Y, U.1)) (B := Γ(X, f ⁻¹ᵁ U.1)) (f₂.isIntegral_app U.1 U.2 x)
329+
· intros U V i
330+
dsimp
331+
rw [Category.comp_id, ← Spec.map_comp_assoc, ← (V.2.preimage f₂).map_fromSpec (U.2.preimage f₂)
332+
(homOfLE (f₂.preimage_mono (Scheme.AffineZariskiSite.toOpens_mono i.le))).op,
333+
← Spec.map_comp_assoc]
334+
congr 2
335+
ext i
336+
apply Subtype.ext
337+
dsimp [normalizationDiagram]
338+
simp only [← CommRingCat.comp_apply, appLE_map, map_appLE]
339+
340+
@[reassoc (attr := simp)]
341+
lemma toNormalization_normalizationDesc (H : f = f₁ ≫ f₂) :
342+
f.toNormalization ≫ f.normalizationDesc f₁ f₂ H = f₁ := by
343+
refine Scheme.Cover.hom_ext (X.openCoverOfIsOpenCover _
344+
(.comap (iSup_affineOpens_eq_top Y) f.base.hom)) _ _ fun U ↦ ?_
345+
letI := (f.app U.1).hom.toAlgebra
346+
refine (Scheme.Hom.ι_toNormalization_assoc ..).trans ?_
347+
dsimp [normalizationOpenCover, normalizationDesc]
348+
simp only [colimit.ι_desc, ← Spec.map_comp_assoc]
349+
change (f ⁻¹ᵁ U.1).toSpecΓ ≫ Spec.map (f₁.appLE (f₂ ⁻¹ᵁ U.1) (f ⁻¹ᵁ U.1) (by simp [H])) ≫
350+
(U.2.preimage f₂).fromSpec = (f ⁻¹ᵁ U.1).ι ≫ f₁
351+
simp
352+
353+
@[reassoc (attr := simp)]
354+
lemma normalizationDesc_comp (H : f = f₁ ≫ f₂) :
355+
f.normalizationDesc f₁ f₂ H ≫ f₂ = f.fromNormalization := by
356+
refine colimit.hom_ext fun U ↦ ?_
357+
dsimp [normalizationDesc, fromNormalization]
358+
rw [colimit.ι_desc_assoc, colimit.ι_desc, Category.assoc,
359+
← IsAffineOpen.SpecMap_appLE_fromSpec _ U.2 _ le_rfl, ← Spec.map_comp_assoc]
360+
congr 2
361+
ext i
362+
dsimp [normalizationDiagram, normalizationDiagramMap, RingHom.algebraMap_toAlgebra]
363+
rw [← CommRingCat.comp_apply, Hom.appLE_comp_appLE, app_eq_appLE]
364+
simp_rw [H]
365+
366+
instance (H : f = f₁ ≫ f₂) : IsIntegralHom (f.normalizationDesc f₁ f₂ H) := by
367+
have : IsIntegralHom (f.normalizationDesc f₁ f₂ H ≫ f₂) := by
368+
rw [f.normalizationDesc_comp]; infer_instance
369+
exact .of_comp _ f₂
370+
371+
/-- The uniqueness part of the universal property for relative normalization.
372+
Suppose `f : X ⟶ Y` is qcqs and factors into `X ⟶ T ⟶ Y` with `T ⟶ Y` affine, then
373+
there is at most one map `f.normalization ⟶ T` that commutes with them. -/
374+
lemma normalization.hom_ext (f₁ f₂ : f.normalization ⟶ T) (g : T ⟶ Y) [IsAffineHom g]
375+
(H₁ : f.toNormalization ≫ f₁ = f.toNormalization ≫ f₂)
376+
(hf₁ : f₁ ≫ g = f.fromNormalization) (hf₂ : f₂ ≫ g = f.fromNormalization) : f₁ = f₂ := by
377+
apply f.normalizationOpenCover.hom_ext _ _ fun U ↦ ?_
378+
let := (f.app U.1).hom.toAlgebra
379+
have : IsAffineHom f₁ := have : IsAffineHom (f₁ ≫ g) := hf₁ ▸ inferInstance; .of_comp _ g
380+
have : IsAffineHom f₂ := have : IsAffineHom (f₂ ≫ g) := hf₂ ▸ inferInstance; .of_comp _ g
381+
let f₀ := toNormalization f ≫ f₁
382+
have hf₀ : f₀ = toNormalization f ≫ f₂ := H₁
383+
refine eq_of_SpecMap_comp_eq_of_isAffineOpen
384+
(CommRingCat.ofHom (integralClosure Γ(Y, U.1) Γ(X, f ⁻¹ᵁ U.1)).val.toRingHom)
385+
Subtype.val_injective _ (U.2.preimage g) ?_ ?_ ?_
386+
· simp only [← Scheme.Hom.comp_preimage, Category.assoc, hf₁, ι_fromNormalization]; simp
387+
· simp only [← Scheme.Hom.comp_preimage, Category.assoc, hf₂, ι_fromNormalization]; simp
388+
· have h₁ : f ⁻¹ᵁ U.1 ≤ f₀ ⁻¹ᵁ g ⁻¹ᵁ U.1 := by
389+
simp only [← Scheme.Hom.comp_preimage, f₀, Category.assoc,
390+
hf₁, toNormalization_fromNormalization]; rfl
391+
have h₁' : f ⁻¹ᵁ U.1 = toNormalization f ⁻¹ᵁ f₂ ⁻¹ᵁ g ⁻¹ᵁ U.1 := by
392+
simp only [← Scheme.Hom.comp_preimage, hf₂, toNormalization_fromNormalization]
393+
have h₂ : fromNormalization f ⁻¹ᵁ U.1 = f₁ ⁻¹ᵁ g ⁻¹ᵁ U.1 := by
394+
simp only [← Scheme.Hom.comp_preimage, hf₁]
395+
have h₂' : fromNormalization f ⁻¹ᵁ U.1 = f₂ ⁻¹ᵁ g ⁻¹ᵁ U.1 := by
396+
simp only [← Scheme.Hom.comp_preimage, hf₂]
397+
have h₃ : f ⁻¹ᵁ U.1 = toNormalization f ⁻¹ᵁ fromNormalization f ⁻¹ᵁ U.1 := by
398+
simp [← Scheme.Hom.comp_preimage]
399+
trans Spec.map (f₀.appLE _ _ h₁) ≫ (U.2.preimage g).fromSpec
400+
· simp only [AlgHom.toRingHom_eq_coe, comp_appLE, Spec.map_comp, Category.assoc, f₀,
401+
app_eq_appLE]
402+
rw [IsAffineOpen.SpecMap_appLE_fromSpec _ _ ((U.2.preimage _).preimage _)]
403+
have : (toNormalization f).appLE (f₁ ⁻¹ᵁ g ⁻¹ᵁ U.1) (f ⁻¹ᵁ U.1) h₁ =
404+
f.normalization.presheaf.map (eqToHom h₂).op ≫
405+
(toNormalization f).app (f.fromNormalization ⁻¹ᵁ U.1) ≫
406+
X.presheaf.map (eqToHom h₃).op := by
407+
simp [app_eq_appLE]
408+
rw [this, f.toNormalization_app_preimage U]
409+
simp [appIso_hom', IsAffineOpen.SpecMap_appLE_fromSpec_assoc _ _ (isAffineOpen_top (Spec _)),
410+
IsAffineOpen.fromSpec_top]
411+
· simp only [AlgHom.toRingHom_eq_coe, hf₀, comp_appLE, Spec.map_comp, Category.assoc,
412+
app_eq_appLE]
413+
rw [IsAffineOpen.SpecMap_appLE_fromSpec _ _ ((U.2.preimage _).preimage _)]
414+
have : (toNormalization f).appLE (f₂ ⁻¹ᵁ g ⁻¹ᵁ U.1) (f ⁻¹ᵁ U.1) h₁'.le =
415+
f.normalization.presheaf.map (eqToHom h₂').op ≫
416+
(toNormalization f).app (f.fromNormalization ⁻¹ᵁ U.1) ≫
417+
X.presheaf.map (eqToHom h₃).op := by
418+
simp [app_eq_appLE]
419+
rw [this, f.toNormalization_app_preimage U]
420+
simp [appIso_hom', IsAffineOpen.SpecMap_appLE_fromSpec_assoc _ _ (isAffineOpen_top (Spec _)),
421+
IsAffineOpen.fromSpec_top]
422+
423+
end UniversalProperty
424+
315425
end AlgebraicGeometry.Scheme.Hom

0 commit comments

Comments
 (0)