From 9a1e164811f1582a8ac9a2523d65ef9627c96857 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Jun 2025 11:21:00 +0200 Subject: [PATCH 01/70] Added global preorder instance for schemes --- Mathlib/AlgebraicGeometry/Scheme.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index 059ad173cb47f1..aa5f955117c359 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -10,7 +10,7 @@ import Mathlib.CategoryTheory.Elementwise /-! # The category of schemes -A scheme is a locally ringed space such that every point is contained in some open set +A scheme is a locally ringed space such that every ptat is contained in some open set where there is an isomorphism of presheaves between the restriction to that open set, and the structure sheaf of `Spec R`, for some commutative ring `R`. @@ -117,6 +117,8 @@ lemma Hom.continuous {X Y : Scheme} (f : X.Hom Y) : Continuous f.base := f.base. protected abbrev sheaf (X : Scheme) := X.toSheafedSpace.sheaf +instance instanceSchemePreord {X : Scheme} : Preorder X := specializationPreorder X + namespace Hom variable {X Y : Scheme.{u}} (f : Hom X Y) {U U' : Y.Opens} {V V' : X.Opens} From 2ec0d7c692489a335cb7b8e95ddea47343a7ae5a Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Jun 2025 11:27:35 +0200 Subject: [PATCH 02/70] FIxed small error --- Mathlib/AlgebraicGeometry/Scheme.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index aa5f955117c359..f1c43c21252b4d 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -10,7 +10,7 @@ import Mathlib.CategoryTheory.Elementwise /-! # The category of schemes -A scheme is a locally ringed space such that every ptat is contained in some open set +A scheme is a locally ringed space such that every point is contained in some open set where there is an isomorphism of presheaves between the restriction to that open set, and the structure sheaf of `Spec R`, for some commutative ring `R`. @@ -117,7 +117,7 @@ lemma Hom.continuous {X Y : Scheme} (f : X.Hom Y) : Continuous f.base := f.base. protected abbrev sheaf (X : Scheme) := X.toSheafedSpace.sheaf -instance instanceSchemePreord {X : Scheme} : Preorder X := specializationPreorder X +instance {X : Scheme} : Preorder X := specializationPreorder X namespace Hom From 56b345d99bb8aa1b3de4d77118271d1fc54b4bc2 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Jun 2025 16:49:30 +0200 Subject: [PATCH 03/70] Some minimal API for the ordering on schemes --- Mathlib/AlgebraicGeometry/Properties.lean | 5 +++++ Mathlib/AlgebraicGeometry/Scheme.lean | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/Mathlib/AlgebraicGeometry/Properties.lean b/Mathlib/AlgebraicGeometry/Properties.lean index bbf920420ae4fb..3262f983f2ebc1 100644 --- a/Mathlib/AlgebraicGeometry/Properties.lean +++ b/Mathlib/AlgebraicGeometry/Properties.lean @@ -296,4 +296,9 @@ theorem map_injective_of_isIntegral [IsIntegral X] {U V : X.Opens} (i : U ⟶ V) apply nonempty_preirreducible_inter U.isOpen (RingedSpace.basicOpen _ _).isOpen simpa using H +noncomputable +instance [IsIntegral X] : OrderTop X where + top := genericPoint X + le_top := fun a ↦ genericPoint_specializes a + end AlgebraicGeometry diff --git a/Mathlib/AlgebraicGeometry/Scheme.lean b/Mathlib/AlgebraicGeometry/Scheme.lean index f1c43c21252b4d..5faf0ac599c25d 100644 --- a/Mathlib/AlgebraicGeometry/Scheme.lean +++ b/Mathlib/AlgebraicGeometry/Scheme.lean @@ -119,6 +119,15 @@ protected abbrev sheaf (X : Scheme) := instance {X : Scheme} : Preorder X := specializationPreorder X +open Order in +lemma height_closed_point {X : Scheme} {x : X} (hx : IsClosed {x}) : height x = 0 := by + simp only [height_eq_zero] + intro b _ + by_cases h : b ≠ x + · have := IsClosed.not_specializes hx rfl h + contradiction + · aesop + namespace Hom variable {X Y : Scheme.{u}} (f : Hom X Y) {U U' : Y.Opens} {V V' : X.Opens} From fa9f6e5ee38da783a08b329d7cf640a807d64f5d Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Sat, 21 Jun 2025 20:37:01 +0200 Subject: [PATCH 04/70] Connecting up locally finite APIs --- Mathlib/Topology/LocallyFinsupp.lean | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 974235a538e417..692e3b2245437d 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -63,6 +63,42 @@ theorem supportDiscreteWithin_iff_locallyFiniteWithin [T1Space X] [Zero Y] {f : exact (h ·) rw [EventuallyEq, Filter.Eventually, codiscreteWithin_iff_locallyFiniteComplementWithin, this] +lemma supportDiscreteWithin_top_iff [Zero Y] (f : X → Y) : + (∀ z ∈ (⊤ : Set X), ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) ↔ + LocallyFinite (fun s : f.support ↦ ({s.val} : Set X)) := by + have lem {α : Type u_1} (s t : Set α) : (s ∩ t) = {i : s | ↑i ∈ t} := by aesop + constructor + · intro h z + obtain ⟨t, ht⟩ := h z (by aesop) + use t + refine ⟨ht.1, ?_⟩ + have ans := ht.2 + simp only [top_eq_univ, lem t f.support, mem_support, ne_eq, Subtype.coe_image, + mem_setOf_eq, exists_prop, singleton_inter_nonempty] at ans ⊢ + have : {x | x ∈ t ∧ ¬f x = 0} = + Subtype.val '' {i : { x // ¬f x = 0 } | ↑i ∈ t} := by aesop + rw[this] at ans + convert ans + apply Equiv.set_finite_iff + exact BijOn.equiv (Subtype.val) (InjOn.bijOn_image injOn_subtype_val) + · intro h z _ + obtain ⟨t, ht⟩ := h z + use t + refine ⟨ht.1, ?_⟩ + have ans := ht.2 + simp only [singleton_inter_nonempty] at ans ⊢ + have : {i : f.support | ↑i ∈ t} = t ∩ f.support := by aesop + rw[← this] + exact Finite.image Subtype.val ans + +lemma supportDiscreteWithin_top_inter_compact_finite {W : Set X} + [Zero Y] {f : X → Y} (hf : ∀ z ∈ (⊤ : Set X), ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) + (hW : IsCompact W) : (W ∩ f.support).Finite := by + have := LocallyFinite.finite_nonempty_inter_compact ((supportDiscreteWithin_top_iff f).mp hf) hW + have lem {α : Type u_1} (s t : Set α) : {i : s | ({↑i} ∩ t).Nonempty} = (t ∩ s) := by aesop + rw[← lem f.support W] + exact Finite.image Subtype.val this + namespace Function.locallyFinsuppWithin /-- From 860f3f8369ed65c312f1de9a90b6e22ededfed86 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Sat, 21 Jun 2025 20:45:08 +0200 Subject: [PATCH 05/70] Fixed naming issues --- Mathlib/Topology/LocallyFinsupp.lean | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 692e3b2245437d..f322b8c989d40b 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -63,7 +63,7 @@ theorem supportDiscreteWithin_iff_locallyFiniteWithin [T1Space X] [Zero Y] {f : exact (h ·) rw [EventuallyEq, Filter.Eventually, codiscreteWithin_iff_locallyFiniteComplementWithin, this] -lemma supportDiscreteWithin_top_iff [Zero Y] (f : X → Y) : +lemma supportLocallyFiniteWithin_top_iff [Zero Y] (f : X → Y) : (∀ z ∈ (⊤ : Set X), ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) ↔ LocallyFinite (fun s : f.support ↦ ({s.val} : Set X)) := by have lem {α : Type u_1} (s t : Set α) : (s ∩ t) = {i : s | ↑i ∈ t} := by aesop @@ -91,10 +91,11 @@ lemma supportDiscreteWithin_top_iff [Zero Y] (f : X → Y) : rw[← this] exact Finite.image Subtype.val ans -lemma supportDiscreteWithin_top_inter_compact_finite {W : Set X} +lemma supportLocallyFiniteWithin_top_inter_compact_finite {W : Set X} [Zero Y] {f : X → Y} (hf : ∀ z ∈ (⊤ : Set X), ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) (hW : IsCompact W) : (W ∩ f.support).Finite := by - have := LocallyFinite.finite_nonempty_inter_compact ((supportDiscreteWithin_top_iff f).mp hf) hW + have := LocallyFinite.finite_nonempty_inter_compact + ((supportLocallyFiniteWithin_top_iff f).mp hf) hW have lem {α : Type u_1} (s t : Set α) : {i : s | ({↑i} ∩ t).Nonempty} = (t ∩ s) := by aesop rw[← lem f.support W] exact Finite.image Subtype.val this From ffb80018b21b4d0b60ed5a977958ba92c577723f Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Sun, 22 Jun 2025 10:05:04 +0200 Subject: [PATCH 06/70] Added algebraic cycle file --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 Mathlib/AlgebraicGeometry/AlgebraicCycle.lean diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean new file mode 100644 index 00000000000000..97baa9a78c0989 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -0,0 +1,188 @@ +/- +Copyright (c) 2025 Raphael Douglas Giles. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Raphael Douglas Giles +-/ +import Mathlib + +open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace + CategoryTheory + +/-! +# Algebraic Cycles + +We define the category of `AffineScheme`s as the essential image of `Spec`. +We also define predicates about affine schemes and affine open sets. + +## Main definitions + +-/ + +universe u v +variable (R : Type*) + [CommRing R] + (i : ℕ) + {X Y : Scheme.{u}} + +abbrev AlgebraicCycle (X : Scheme) := Function.locallyFinsuppWithin (⊤ : Set X) ℤ + +structure HomogenousCycle (X : Scheme) (d : ℕ) where + cycle : AlgebraicCycle X + homogenous : ∀ x ∈ cycle.support, height x = d + +namespace AlgebraicCycle + +variable (f : X ⟶ Y) + (c : AlgebraicCycle X) + (x : X) + (z : Y) + +/-- +The cycle containing a single point with a chosen coefficient +-/ +noncomputable +def single (coeff : ℤ) : AlgebraicCycle X where + toFun := Set.indicator {x} (Function.const X coeff) + supportWithinDomain' := by simp + supportLocallyFiniteWithinDomain' z hz := + ⟨⊤, ⟨Filter.univ_mem' fun a ↦ trivial, by simp [← Function.const_def, toFinite]⟩⟩ + +/-- +Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage +of a point z : Y along a morphism f : X ⟶ Y. +-/ +def preimageSupport : Set X := + f.base ⁻¹' {z} ∩ c.support + +/-- +Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage +of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. +-/ +def preimageSupportFinite [qf : QuasiCompact f] : + (preimageSupport f c z).Finite := + supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' <| + QuasiCompact.isCompact_preimage_singleton f z + +noncomputable +def _root_.AlgebraicGeometry.LocallyRingedSpace.Hom.degree : ℕ := @Module.finrank + (IsLocalRing.ResidueField (Y.presheaf.stalk (f.base x))) + (IsLocalRing.ResidueField (X.presheaf.stalk x)) + (by infer_instance) + (by infer_instance) + (by have := + RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom);exact Algebra.toModule) + +open Classical in +noncomputable +def mapAux {Y : Scheme} (f : X ⟶ Y) (x : X) : ℤ := + if height x = height (f.base x) then Hom.degree f x else 0 + +lemma map_locally_finite {Y : Scheme} + (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : + ∀ z ∈ (⊤ : Set Y), ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ + ∑ x ∈ (preimageSupportFinite f c z).toFinset, (c x) * mapAux f x).Finite := by + intro y hy + have : ∃ W : Y.Opens, IsAffineOpen W ∧ y ∈ W := by sorry + obtain ⟨W, hW⟩ := this + have cpct : IsCompact (f.base ⁻¹' W) := qc.1 W.carrier W.is_open' <| + AlgebraicGeometry.IsAffineOpen.isCompact hW.1 + use W + refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ + + have pbfinite : (f.base ⁻¹' W ∩ Function.support c).Finite := + supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' cpct + + suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by + apply Finite.subset this + apply inter_subset_inter Set.Subset.rfl + intro x + simp + contrapose! + intro aux + rw [Finset.sum_eq_zero] + intro x hx + simp only [Finite.mem_toFinset, aux] at hx + simp only [mem_empty_iff_false] at hx + + have : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ + f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by + intro a ha + rw [@image_preimage_inter] + suffices a ∈ f.base '' c.support by + exact mem_inter ha this + have := ha.2.some_mem + simp[preimageSupport] at this + simp + use ha.2.some + constructor + · exact this.2 + · exact this.1 + + apply Finite.subset _ this + apply Finite.image + rw[preimage_inter] + have : f.base ⁻¹' W.carrier ∩ f.base ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ + f.base ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by + intro p hp + simp[preimageSupport] at hp ⊢ + constructor + · exact hp.1.1 + · exact hp.2 + + apply Finite.subset _ this + rw[inter_iUnion] + simp[preimageSupport] + suffices (⋃ i : Y, f.base ⁻¹' W.carrier ∩ c.support).Finite by + apply Finite.subset this + simp + intro y x hx + simp at hx ⊢ + constructor + · exact hx.1 + · constructor + · exact Nonempty.intro y + · exact hx.2.2 + + suffices (f.base ⁻¹' W.carrier ∩ c.support).Finite by + apply Finite.subset this + intro a ha + simp at ha ⊢ + constructor + · exact ha.1 + · exact ha.2.2 + exact pbfinite + +open Classical in +noncomputable +def map {Y : Scheme} + (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : AlgebraicCycle Y where + toFun z := (∑ x ∈ (preimageSupportFinite f c z).toFinset, (c x) * mapAux f x) + supportWithinDomain' := by simp + supportLocallyFiniteWithinDomain' := fun z a ↦ map_locally_finite f c z a + +@[simp] +lemma map_id (c : AlgebraicCycle X) : + map (𝟙 X) c = c := by + ext z + have : (c z ≠ 0 ∧ (preimageSupportFinite (𝟙 X) c z).toFinset = {z}) ∨ + (c z = 0 ∧ (preimageSupportFinite (𝟙 X) c z).toFinset = ∅) := by + simp[preimageSupportFinite, preimageSupport, Finite.toFinset] + by_cases o : c z = 0 + · exact Or.inr o + · apply Or.inl + refine ⟨o, ?_⟩ + ext a + simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, + Finset.mem_singleton, and_iff_left_iff_imp] + intro h + rw[h] + exact o + suffices (map (𝟙 X) c).toFun z = c.toFun z from this + obtain h | h := this + all_goals simp[map, mapAux] + rw[h.2] + simp [Hom.degree] + try rfl + try exact h.1.symm + +end AlgebraicCycle From 144a4e0245567eb74e71082d34ab0937ef611e86 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Sun, 22 Jun 2025 11:36:49 +0200 Subject: [PATCH 07/70] Some minor golfing --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 50 ++++++++----------- 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 97baa9a78c0989..bb4429241a2c9e 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -11,8 +11,8 @@ open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace /-! # Algebraic Cycles -We define the category of `AffineScheme`s as the essential image of `Spec`. -We also define predicates about affine schemes and affine open sets. +We define algebraic cycles on a scheme `X` to be functions `c : X → ℤ` whose support is +locally finite. ## Main definitions @@ -96,7 +96,7 @@ lemma map_locally_finite {Y : Scheme} apply Finite.subset this apply inter_subset_inter Set.Subset.rfl intro x - simp + simp only [top_eq_univ, Function.mem_support, ne_eq, mem_setOf_eq] contrapose! intro aux rw [Finset.sum_eq_zero] @@ -107,49 +107,37 @@ lemma map_locally_finite {Y : Scheme} have : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by intro a ha - rw [@image_preimage_inter] - suffices a ∈ f.base '' c.support by - exact mem_inter ha this + rw [image_preimage_inter] + suffices a ∈ f.base '' c.support from mem_inter ha this have := ha.2.some_mem - simp[preimageSupport] at this - simp - use ha.2.some - constructor - · exact this.2 - · exact this.1 + simp[preimageSupport] at this ⊢ + exact ⟨ha.2.some, this.symm⟩ - apply Finite.subset _ this - apply Finite.image + refine Finite.subset (Finite.image _ ?_) this rw[preimage_inter] have : f.base ⁻¹' W.carrier ∩ f.base ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ f.base ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by intro p hp simp[preimageSupport] at hp ⊢ - constructor - · exact hp.1.1 - · exact hp.2 + exact ⟨hp.1.1, hp.2⟩ apply Finite.subset _ this rw[inter_iUnion] simp[preimageSupport] suffices (⋃ i : Y, f.base ⁻¹' W.carrier ∩ c.support).Finite by apply Finite.subset this - simp + simp only [Opens.carrier_eq_coe, top_eq_univ, iUnion_subset_iff] intro y x hx simp at hx ⊢ - constructor - · exact hx.1 - · constructor - · exact Nonempty.intro y - · exact hx.2.2 + exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ suffices (f.base ⁻¹' W.carrier ∩ c.support).Finite by apply Finite.subset this intro a ha - simp at ha ⊢ - constructor - · exact ha.1 - · exact ha.2.2 + simp only [Opens.carrier_eq_coe, top_eq_univ, mem_iUnion, mem_inter_iff, mem_preimage, + SetLike.mem_coe, Function.mem_support, ne_eq, exists_and_left, exists_const_iff] at ha ⊢ + exact ⟨ha.1, ha.2.2⟩ + exact pbfinite open Classical in @@ -181,8 +169,10 @@ lemma map_id (c : AlgebraicCycle X) : obtain h | h := this all_goals simp[map, mapAux] rw[h.2] - simp [Hom.degree] - try rfl - try exact h.1.symm + simp only [Hom.degree, Scheme.id.base, TopCat.hom_id, ContinuousMap.id_apply, + Scheme.stalkMap_id, CommRingCat.hom_id, IsLocalRing.ResidueField.map_id, + Module.finrank_self, Nat.cast_one, mul_one, Finset.sum_singleton] + · rfl + · exact h.1.symm end AlgebraicCycle From c1afc37bf3e4cbf9ee357cd3568ed730d7d0d470 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Sun, 22 Jun 2025 17:04:30 +0200 Subject: [PATCH 08/70] Added affine open lemma --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index c7680e28662a38..f8feee3891babc 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -234,6 +234,12 @@ theorem isAffineOpen_top (X : Scheme) [IsAffine X] : IsAffineOpen (⊤ : X.Opens ext1 exact Set.range_id.symm +theorem exists_affineOpen_mem_and_subset {X : Scheme.{u}} {x : X} + {U : X.Opens} (hxU : x ∈ U) : ∃ W : X.Opens, IsAffineOpen W ∧ x ∈ W := by + obtain ⟨R, f, hf⟩ := AlgebraicGeometry.Scheme.exists_affine_mem_range_and_range_subset hxU + exact ⟨Scheme.Hom.opensRange f (H := hf.1), + ⟨AlgebraicGeometry.isAffineOpen_opensRange f (H := hf.1) , hf.2.1⟩⟩ + instance Scheme.isAffine_affineCover (X : Scheme) (i : X.affineCover.J) : IsAffine (X.affineCover.obj i) := isAffine_Spec _ From 6bae8b145e855c5f0f8025ac545c5ebd1926615d Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Sun, 22 Jun 2025 18:20:31 +0200 Subject: [PATCH 09/70] Fixed typo in lemma statement --- Mathlib/AlgebraicGeometry/AffineScheme.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AffineScheme.lean b/Mathlib/AlgebraicGeometry/AffineScheme.lean index f8feee3891babc..40c3d50243c763 100644 --- a/Mathlib/AlgebraicGeometry/AffineScheme.lean +++ b/Mathlib/AlgebraicGeometry/AffineScheme.lean @@ -234,11 +234,11 @@ theorem isAffineOpen_top (X : Scheme) [IsAffine X] : IsAffineOpen (⊤ : X.Opens ext1 exact Set.range_id.symm -theorem exists_affineOpen_mem_and_subset {X : Scheme.{u}} {x : X} - {U : X.Opens} (hxU : x ∈ U) : ∃ W : X.Opens, IsAffineOpen W ∧ x ∈ W := by +theorem exists_isAffineOpen_mem_and_subset {X : Scheme.{u}} {x : X} + {U : X.Opens} (hxU : x ∈ U) : ∃ W : X.Opens, IsAffineOpen W ∧ x ∈ W ∧ W.1 ⊆ U := by obtain ⟨R, f, hf⟩ := AlgebraicGeometry.Scheme.exists_affine_mem_range_and_range_subset hxU exact ⟨Scheme.Hom.opensRange f (H := hf.1), - ⟨AlgebraicGeometry.isAffineOpen_opensRange f (H := hf.1) , hf.2.1⟩⟩ + ⟨AlgebraicGeometry.isAffineOpen_opensRange f (H := hf.1), hf.2.1, hf.2.2⟩⟩ instance Scheme.isAffine_affineCover (X : Scheme) (i : X.affineCover.J) : IsAffine (X.affineCover.obj i) := From bdb9c9decc9d1416c00379bbcc7b9311955fa1c2 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 23 Jun 2025 15:48:11 +0200 Subject: [PATCH 10/70] Added some things about homogeneous cycles --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 143 ++++++++++++++---- 1 file changed, 113 insertions(+), 30 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index bb4429241a2c9e..37fcfbaae1c297 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -3,7 +3,13 @@ Copyright (c) 2025 Raphael Douglas Giles. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Raphael Douglas Giles -/ -import Mathlib +import Mathlib.AlgebraicGeometry.Fiber +import Mathlib.AlgebraicGeometry.Morphisms.Proper +import Mathlib.Analysis.Normed.Ring.Lemmas +import Mathlib.Combinatorics.Quiver.ReflQuiver +import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition +import Mathlib.RingTheory.Henselian +import Mathlib.Topology.LocallyFinsupp open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace CategoryTheory @@ -13,9 +19,6 @@ open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace We define algebraic cycles on a scheme `X` to be functions `c : X → ℤ` whose support is locally finite. - -## Main definitions - -/ universe u v @@ -24,14 +27,62 @@ variable (R : Type*) (i : ℕ) {X Y : Scheme.{u}} -abbrev AlgebraicCycle (X : Scheme) := Function.locallyFinsuppWithin (⊤ : Set X) ℤ - -structure HomogenousCycle (X : Scheme) (d : ℕ) where - cycle : AlgebraicCycle X - homogenous : ∀ x ∈ cycle.support, height x = d +abbrev AlgebraicCycle (X : Scheme.{u}) := Function.locallyFinsuppWithin (⊤ : Set X) ℤ namespace AlgebraicCycle +/-- +Proposition saying whether a cycle is of pure dimension `d`. +-/ +def IsHomogeneous (d : ℕ∞) (c : AlgebraicCycle X) : Prop := ∀ x ∈ c.support, height x = d + +/-- +Subgroup of cycles of pure dimension `d`. +-/ +def homogeneousAddSubgroup (X : Scheme) (d : ℕ∞) : AddSubgroup (AlgebraicCycle X) where + carrier := {c : AlgebraicCycle X | IsHomogeneous d c} + add_mem' c₁ c₂ := by + rename_i a b + simp_all only [IsHomogeneous, top_eq_univ, Function.mem_support, ne_eq, mem_setOf_eq, + Function.locallyFinsuppWithin.coe_add, Pi.add_apply] + intro x hx + specialize c₁ x + specialize c₂ x + have : ¬ a x = 0 ∨ ¬ b x = 0 := by omega + obtain h | h := this + · exact c₁ h + · exact c₂ h + zero_mem' := by simp [IsHomogeneous] + neg_mem' c := by simp_all [IsHomogeneous] + +/-- +Homogeneous part of dimension `d` of an algebraic cycle `c`. +-/ +noncomputable +def homogeneousProjection (c : AlgebraicCycle X) (d : ℕ∞) : homogeneousAddSubgroup X d where + val := { + toFun x := if height x = d then c x else 0 + supportWithinDomain' := by simp + supportLocallyFiniteWithinDomain' z hz := by + choose t ht using c.supportLocallyFiniteWithinDomain' z + use t hz + specialize ht hz + refine ⟨ht.1, ?_⟩ + have := ht.2 + apply Finite.subset this + refine inter_subset_inter (fun ⦃a⦄ a ↦ a) (Function.support_subset_iff'.mpr ?_) + intro x hx + simp only [top_eq_univ, Function.mem_support, ne_eq, Decidable.not_not, + ite_eq_right_iff] at hx ⊢ + exact fun _ ↦ hx + } + property := by + simp only [top_eq_univ, homogeneousAddSubgroup, IsHomogeneous, Function.mem_support, ne_eq, + AddSubgroup.mem_mk, mem_setOf_eq] + intro x hx + have : ¬ (if height x = d then c x else 0) = 0 := hx + aesop + variable (f : X ⟶ Y) (c : AlgebraicCycle X) (x : X) @@ -63,6 +114,11 @@ def preimageSupportFinite [qf : QuasiCompact f] : supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' <| QuasiCompact.isCompact_preimage_singleton f z +/-- +Degree of `f` at a point `x` is defined to be the degree of the associated field extension +from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is either infinite +or undefined. +-/ noncomputable def _root_.AlgebraicGeometry.LocallyRingedSpace.Hom.degree : ℕ := @Module.finrank (IsLocalRing.ResidueField (Y.presheaf.stalk (f.base x))) @@ -72,22 +128,39 @@ def _root_.AlgebraicGeometry.LocallyRingedSpace.Hom.degree : ℕ := @Module.finr (by have := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom);exact Algebra.toModule) + open Classical in +/-- +Implementation detail for pushforward: function used to define the coefficient of the pushforward +of a cycle `c` at a point `z = f x`, as in stacks 02R3. + +Note: I'm not entirely sure if the case distinction here (and hence this definition) is necessary, +since the degree alread has a default value of zero whenever the degree of the field extension is +not finite. +-/ noncomputable def mapAux {Y : Scheme} (f : X ⟶ Y) (x : X) : ℤ := if height x = height (f.base x) then Hom.degree f x else 0 +/-- +The pushforward of an algebraic cycle has locally finite support. + +Note that while this could be part of the definition of map, we experienced significant performance +issues when instead writing this definition in the `supportLocallyFiniteWithinDomain'` field of the +`map` definition. + +I feel the proof here is a bit too long, but I'm a little unsure of how I should shorten it. +-/ lemma map_locally_finite {Y : Scheme} (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : ∀ z ∈ (⊤ : Set Y), ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ ∑ x ∈ (preimageSupportFinite f c z).toFinset, (c x) * mapAux f x).Finite := by intro y hy - have : ∃ W : Y.Opens, IsAffineOpen W ∧ y ∈ W := by sorry - obtain ⟨W, hW⟩ := this + obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by aesop) have cpct : IsCompact (f.base ⁻¹' W) := qc.1 W.carrier W.is_open' <| AlgebraicGeometry.IsAffineOpen.isCompact hW.1 use W - refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ + refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2.1, ?_⟩ have pbfinite : (f.base ⁻¹' W ∩ Function.support c).Finite := supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' cpct @@ -101,8 +174,7 @@ lemma map_locally_finite {Y : Scheme} intro aux rw [Finset.sum_eq_zero] intro x hx - simp only [Finite.mem_toFinset, aux] at hx - simp only [mem_empty_iff_false] at hx + simp_all have : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by @@ -110,7 +182,8 @@ lemma map_locally_finite {Y : Scheme} rw [image_preimage_inter] suffices a ∈ f.base '' c.support from mem_inter ha this have := ha.2.some_mem - simp[preimageSupport] at this ⊢ + simp only [preimageSupport, top_eq_univ, mem_inter_iff, mem_preimage, mem_singleton_iff, + Function.mem_support, ne_eq, mem_image] at this ⊢ exact ⟨ha.2.some, this.symm⟩ refine Finite.subset (Finite.image _ ?_) this @@ -118,7 +191,9 @@ lemma map_locally_finite {Y : Scheme} have : f.base ⁻¹' W.carrier ∩ f.base ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ f.base ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by intro p hp - simp[preimageSupport] at hp ⊢ + simp only [Opens.carrier_eq_coe, preimageSupport, top_eq_univ, preimage_setOf_eq, mem_inter_iff, + mem_preimage, SetLike.mem_coe, mem_setOf_eq, Function.mem_support, ne_eq, mem_iUnion, + mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ exact ⟨hp.1.1, hp.2⟩ apply Finite.subset _ this @@ -128,7 +203,8 @@ lemma map_locally_finite {Y : Scheme} apply Finite.subset this simp only [Opens.carrier_eq_coe, top_eq_univ, iUnion_subset_iff] intro y x hx - simp at hx ⊢ + simp only [mem_inter_iff, mem_preimage, SetLike.mem_coe, mem_singleton_iff, + Function.mem_support, ne_eq, mem_iUnion, exists_and_left, exists_const_iff] at hx ⊢ exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ suffices (f.base ⁻¹' W.carrier ∩ c.support).Finite by @@ -141,13 +217,22 @@ lemma map_locally_finite {Y : Scheme} exact pbfinite open Classical in +/-- +The pushforward of an algebraic cycle by a quasicompact morphism. + +Note that usually the pushforward is only defined for proper morphisms, and indeed we will need +properness to prove that the pushforward preserves rational equivalence. +-/ noncomputable -def map {Y : Scheme} - (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : AlgebraicCycle Y where +def map {Y : Scheme} (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : AlgebraicCycle Y + where toFun z := (∑ x ∈ (preimageSupportFinite f c z).toFinset, (c x) * mapAux f x) supportWithinDomain' := by simp supportLocallyFiniteWithinDomain' := fun z a ↦ map_locally_finite f c z a +/-- +The pushforward of `c` along the identity morphism is `c`. +-/ @[simp] lemma map_id (c : AlgebraicCycle X) : map (𝟙 X) c = c := by @@ -155,19 +240,15 @@ lemma map_id (c : AlgebraicCycle X) : have : (c z ≠ 0 ∧ (preimageSupportFinite (𝟙 X) c z).toFinset = {z}) ∨ (c z = 0 ∧ (preimageSupportFinite (𝟙 X) c z).toFinset = ∅) := by simp[preimageSupportFinite, preimageSupport, Finite.toFinset] - by_cases o : c z = 0 - · exact Or.inr o - · apply Or.inl - refine ⟨o, ?_⟩ - ext a - simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, - Finset.mem_singleton, and_iff_left_iff_imp] - intro h - rw[h] - exact o + refine Or.elim (em (c z = 0)) (fun o ↦ Or.inr o) (fun o ↦ Or.inl ⟨o, Finset.ext (fun a ↦ ?_)⟩) + simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, + Finset.mem_singleton, and_iff_left_iff_imp] + rintro rfl + assumption suffices (map (𝟙 X) c).toFun z = c.toFun z from this obtain h | h := this - all_goals simp[map, mapAux] + all_goals simp only [top_eq_univ, map, mapAux, Scheme.id.base, TopCat.hom_id, + ContinuousMap.id_apply, ↓reduceIte] rw[h.2] simp only [Hom.degree, Scheme.id.base, TopCat.hom_id, ContinuousMap.id_apply, Scheme.stalkMap_id, CommRingCat.hom_id, IsLocalRing.ResidueField.map_id, @@ -175,4 +256,6 @@ lemma map_id (c : AlgebraicCycle X) : · rfl · exact h.1.symm + +#min_imports end AlgebraicCycle From 404ee0eaf49fab707be81176660c0d1782abc610 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 23 Jun 2025 16:15:34 +0200 Subject: [PATCH 11/70] Added lemma about pushforward acting on k cycles --- Mathlib.lean | 1 + Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 29 +++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Mathlib.lean b/Mathlib.lean index 2677c651b28a3b..6b42076e8ca720 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1121,6 +1121,7 @@ import Mathlib.Algebra.Vertex.VertexOperator import Mathlib.AlgebraicGeometry.AffineScheme import Mathlib.AlgebraicGeometry.AffineSpace import Mathlib.AlgebraicGeometry.AffineTransitionLimit +import Mathlib.AlgebraicGeometry.AlgebraicCycle import Mathlib.AlgebraicGeometry.Cover.MorphismProperty import Mathlib.AlgebraicGeometry.Cover.Open import Mathlib.AlgebraicGeometry.Cover.Over diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 37fcfbaae1c297..12ea0ce15fac1d 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -39,7 +39,7 @@ def IsHomogeneous (d : ℕ∞) (c : AlgebraicCycle X) : Prop := ∀ x ∈ c.supp /-- Subgroup of cycles of pure dimension `d`. -/ -def homogeneousAddSubgroup (X : Scheme) (d : ℕ∞) : AddSubgroup (AlgebraicCycle X) where +def HomogeneousAddSubgroup (X : Scheme) (d : ℕ∞) : AddSubgroup (AlgebraicCycle X) where carrier := {c : AlgebraicCycle X | IsHomogeneous d c} add_mem' c₁ c₂ := by rename_i a b @@ -59,7 +59,7 @@ def homogeneousAddSubgroup (X : Scheme) (d : ℕ∞) : AddSubgroup (AlgebraicCyc Homogeneous part of dimension `d` of an algebraic cycle `c`. -/ noncomputable -def homogeneousProjection (c : AlgebraicCycle X) (d : ℕ∞) : homogeneousAddSubgroup X d where +def homogeneousProjection (c : AlgebraicCycle X) (d : ℕ∞) : HomogeneousAddSubgroup X d where val := { toFun x := if height x = d then c x else 0 supportWithinDomain' := by simp @@ -77,7 +77,7 @@ def homogeneousProjection (c : AlgebraicCycle X) (d : ℕ∞) : homogeneousAddSu exact fun _ ↦ hx } property := by - simp only [top_eq_univ, homogeneousAddSubgroup, IsHomogeneous, Function.mem_support, ne_eq, + simp only [top_eq_univ, HomogeneousAddSubgroup, IsHomogeneous, Function.mem_support, ne_eq, AddSubgroup.mem_mk, mem_setOf_eq] intro x hx have : ¬ (if height x = d then c x else 0) = 0 := hx @@ -216,7 +216,6 @@ lemma map_locally_finite {Y : Scheme} exact pbfinite -open Classical in /-- The pushforward of an algebraic cycle by a quasicompact morphism. @@ -224,12 +223,31 @@ Note that usually the pushforward is only defined for proper morphisms, and inde properness to prove that the pushforward preserves rational equivalence. -/ noncomputable -def map {Y : Scheme} (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : AlgebraicCycle Y +def map {Y : Scheme.{u}} (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : AlgebraicCycle Y where toFun z := (∑ x ∈ (preimageSupportFinite f c z).toFinset, (c x) * mapAux f x) supportWithinDomain' := by simp supportLocallyFiniteWithinDomain' := fun z a ↦ map_locally_finite f c z a +/-- +Pushforward preserves cycles of pure dimension `d`. +-/ +noncomputable +def map_homogeneneous {Y : Scheme.{u}} {d : ℕ∞} (f : X ⟶ Y) [qc : QuasiCompact f] + (c : HomogeneousAddSubgroup X d) : HomogeneousAddSubgroup Y d where + val := map f c + property := by + simp[HomogeneousAddSubgroup, IsHomogeneous] + intro y hy + have : ¬ (map f c).toFun y = 0 := hy + simp only [top_eq_univ, map, preimageSupport, mapAux, mul_ite, mul_zero] at this + obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero this + simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, + Function.mem_support, ne_eq, ite_eq_right_iff, mul_eq_zero, Int.natCast_eq_zero, + Classical.not_imp, not_or] at hx + have : height x = d := c.2 x hx.1.2 + aesop + /-- The pushforward of `c` along the identity morphism is `c`. -/ @@ -257,5 +275,4 @@ lemma map_id (c : AlgebraicCycle X) : · exact h.1.symm -#min_imports end AlgebraicCycle From 16df43d4881ee4bd6be771c7a68e86ec1bafa1c6 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 23 Jun 2025 16:16:16 +0200 Subject: [PATCH 12/70] Removed redundant newline --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 12ea0ce15fac1d..5987e26e18901c 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -274,5 +274,4 @@ lemma map_id (c : AlgebraicCycle X) : · rfl · exact h.1.symm - end AlgebraicCycle From 4dde31e1d7bfb8d4fd2e802e3a9bfaa2f5dda8ac Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 23 Jun 2025 16:48:00 +0200 Subject: [PATCH 13/70] Fixed issues raised by CI --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 5987e26e18901c..72dde551b4a4d1 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -27,6 +27,12 @@ variable (R : Type*) (i : ℕ) {X Y : Scheme.{u}} +/-- +Algebraic cycle on a scheme X. + +Note I am not certain that this should be an abbrev. I'm also not sure if these definitions +should instead directly be about Function.locallyFinsuppWithin +-/ abbrev AlgebraicCycle (X : Scheme.{u}) := Function.locallyFinsuppWithin (⊤ : Set X) ℤ namespace AlgebraicCycle @@ -109,7 +115,7 @@ def preimageSupport : Set X := Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. -/ -def preimageSupportFinite [qf : QuasiCompact f] : +lemma preimageSupport_finite [qf : QuasiCompact f] : (preimageSupport f c z).Finite := supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' <| QuasiCompact.isCompact_preimage_singleton f z @@ -153,9 +159,9 @@ I feel the proof here is a bit too long, but I'm a little unsure of how I should -/ lemma map_locally_finite {Y : Scheme} (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : - ∀ z ∈ (⊤ : Set Y), ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ - ∑ x ∈ (preimageSupportFinite f c z).toFinset, (c x) * mapAux f x).Finite := by - intro y hy + ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ + ∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux f x).Finite := by + intro y obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by aesop) have cpct : IsCompact (f.base ⁻¹' W) := qc.1 W.carrier W.is_open' <| AlgebraicGeometry.IsAffineOpen.isCompact hW.1 @@ -225,9 +231,9 @@ properness to prove that the pushforward preserves rational equivalence. noncomputable def map {Y : Scheme.{u}} (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : AlgebraicCycle Y where - toFun z := (∑ x ∈ (preimageSupportFinite f c z).toFinset, (c x) * mapAux f x) + toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux f x) supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' := fun z a ↦ map_locally_finite f c z a + supportLocallyFiniteWithinDomain' := fun z a ↦ map_locally_finite f c z /-- Pushforward preserves cycles of pure dimension `d`. @@ -255,9 +261,9 @@ The pushforward of `c` along the identity morphism is `c`. lemma map_id (c : AlgebraicCycle X) : map (𝟙 X) c = c := by ext z - have : (c z ≠ 0 ∧ (preimageSupportFinite (𝟙 X) c z).toFinset = {z}) ∨ - (c z = 0 ∧ (preimageSupportFinite (𝟙 X) c z).toFinset = ∅) := by - simp[preimageSupportFinite, preimageSupport, Finite.toFinset] + have : (c z ≠ 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = {z}) ∨ + (c z = 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = ∅) := by + simp[preimageSupport_finite, preimageSupport, Finite.toFinset] refine Or.elim (em (c z = 0)) (fun o ↦ Or.inr o) (fun o ↦ Or.inl ⟨o, Finset.ext (fun a ↦ ?_)⟩) simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, Finset.mem_singleton, and_iff_left_iff_imp] From 21ced5fc38dd8ef11c13cd50dcdac98dcb763f6e Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 23 Jun 2025 17:00:18 +0200 Subject: [PATCH 14/70] Fixed some CI complaints --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 72dde551b4a4d1..1c102f1d4ca0e3 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -5,15 +5,11 @@ Authors: Raphael Douglas Giles -/ import Mathlib.AlgebraicGeometry.Fiber import Mathlib.AlgebraicGeometry.Morphisms.Proper -import Mathlib.Analysis.Normed.Ring.Lemmas import Mathlib.Combinatorics.Quiver.ReflQuiver import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition import Mathlib.RingTheory.Henselian import Mathlib.Topology.LocallyFinsupp -open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace - CategoryTheory - /-! # Algebraic Cycles @@ -21,6 +17,9 @@ We define algebraic cycles on a scheme `X` to be functions `c : X → ℤ` whose locally finite. -/ +open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace + CategoryTheory + universe u v variable (R : Type*) [CommRing R] From 6e994b2f32274f8dc982d0ad3a075733d5290d81 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 23 Jun 2025 17:42:47 +0200 Subject: [PATCH 15/70] Removed unnecessary import --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 1c102f1d4ca0e3..ab8f8f41f83877 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -7,7 +7,6 @@ import Mathlib.AlgebraicGeometry.Fiber import Mathlib.AlgebraicGeometry.Morphisms.Proper import Mathlib.Combinatorics.Quiver.ReflQuiver import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition -import Mathlib.RingTheory.Henselian import Mathlib.Topology.LocallyFinsupp /-! From 70304cbacd905a4eb7413e6d7f96eda9249b4c84 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 25 Sep 2025 11:02:10 +0200 Subject: [PATCH 16/70] Made some changes according to reviewer comments --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 188 +++++++++++------- Mathlib/Topology/LocallyFinsupp.lean | 74 +++++-- 2 files changed, 169 insertions(+), 93 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index ab8f8f41f83877..32d7516b78daa0 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -8,6 +8,8 @@ import Mathlib.AlgebraicGeometry.Morphisms.Proper import Mathlib.Combinatorics.Quiver.ReflQuiver import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition import Mathlib.Topology.LocallyFinsupp +import Mathlib.Algebra.GradedMonoid +import Mathlib.Algebra.DirectSum.Decomposition /-! # Algebraic Cycles @@ -24,6 +26,7 @@ variable (R : Type*) [CommRing R] (i : ℕ) {X Y : Scheme.{u}} + (Z : Type*) --[Zero Z] /-- Algebraic cycle on a scheme X. @@ -31,72 +34,67 @@ Algebraic cycle on a scheme X. Note I am not certain that this should be an abbrev. I'm also not sure if these definitions should instead directly be about Function.locallyFinsuppWithin -/ -abbrev AlgebraicCycle (X : Scheme.{u}) := Function.locallyFinsuppWithin (⊤ : Set X) ℤ +abbrev AlgebraicCycle (X : Scheme.{u}) (Z : Type*) [Zero Z] := + Function.locallyFinsuppWithin (⊤ : Set X) Z + namespace AlgebraicCycle -/-- -Proposition saying whether a cycle is of pure dimension `d`. +/- +I think this is the data we should take in whenever we want to talk about a grading. Since +everything should be mostly handled by typeclass inference, it should suffice to only explicitly +pass A around. -/ -def IsHomogeneous (d : ℕ∞) (c : AlgebraicCycle X) : Prop := ∀ x ∈ c.support, height x = d - +/-variable {S ι : Type*} [AddMonoid Z] [SetLike S (AlgebraicCycle X Z)] [AddMonoid ι] + [AddSubmonoidClass S (AlgebraicCycle X Z)] [DecidableEq ι] + (A : ι → S) (X)-/ +variable (X) /-- Subgroup of cycles of pure dimension `d`. -/ -def HomogeneousAddSubgroup (X : Scheme) (d : ℕ∞) : AddSubgroup (AlgebraicCycle X) where - carrier := {c : AlgebraicCycle X | IsHomogeneous d c} +def dimensionGrading [AddMonoid Z] (d : ℕ∞) : + AddSubmonoid (AlgebraicCycle X Z) where + carrier := {c : AlgebraicCycle X Z | ∀ x ∈ c.support, height x = d} add_mem' c₁ c₂ := by rename_i a b - simp_all only [IsHomogeneous, top_eq_univ, Function.mem_support, ne_eq, mem_setOf_eq, + simp_all only [top_eq_univ, Function.mem_support, ne_eq, mem_setOf_eq, Function.locallyFinsuppWithin.coe_add, Pi.add_apply] intro x hx - specialize c₁ x - specialize c₂ x - have : ¬ a x = 0 ∨ ¬ b x = 0 := by omega - obtain h | h := this - · exact c₁ h - · exact c₂ h - zero_mem' := by simp [IsHomogeneous] - neg_mem' c := by simp_all [IsHomogeneous] + have : ¬ a x = 0 ∨ ¬ b x = 0 := by + by_contra h + simp_all + exact Or.elim this (c₁ x) (c₂ x) + zero_mem' := by simp -/-- -Homogeneous part of dimension `d` of an algebraic cycle `c`. --/ -noncomputable -def homogeneousProjection (c : AlgebraicCycle X) (d : ℕ∞) : HomogeneousAddSubgroup X d where - val := { - toFun x := if height x = d then c x else 0 - supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' z hz := by - choose t ht using c.supportLocallyFiniteWithinDomain' z - use t hz - specialize ht hz - refine ⟨ht.1, ?_⟩ - have := ht.2 - apply Finite.subset this - refine inter_subset_inter (fun ⦃a⦄ a ↦ a) (Function.support_subset_iff'.mpr ?_) - intro x hx - simp only [top_eq_univ, Function.mem_support, ne_eq, Decidable.not_not, - ite_eq_right_iff] at hx ⊢ - exact fun _ ↦ hx - } - property := by - simp only [top_eq_univ, HomogeneousAddSubgroup, IsHomogeneous, Function.mem_support, ne_eq, - AddSubgroup.mem_mk, mem_setOf_eq] - intro x hx - have : ¬ (if height x = d then c x else 0) = 0 := hx - aesop + +def dimensionGrading' (Z : Type*) [AddCommGroup Z] (d : ℕ∞) : + AddSubgroup (AlgebraicCycle X Z) where + __ := dimensionGrading X Z d + neg_mem' c := by simp_all [dimensionGrading] + + + + +def codimensionGrading [AddCommGroup Z] (d : ℕ∞) := + {c : AlgebraicCycle X Z | ∀ x ∈ c.support, coheight x = d} + +variable {X Z} + +section Zero variable (f : X ⟶ Y) - (c : AlgebraicCycle X) + [Zero Z] + --[AddMonoid Z] + (c : AlgebraicCycle X Z) (x : X) (z : Y) + /-- The cycle containing a single point with a chosen coefficient -/ noncomputable -def single (coeff : ℤ) : AlgebraicCycle X where +def single (coeff : Z) : AlgebraicCycle X Z where toFun := Set.indicator {x} (Function.const X coeff) supportWithinDomain' := by simp supportLocallyFiniteWithinDomain' z hz := @@ -132,7 +130,7 @@ def _root_.AlgebraicGeometry.LocallyRingedSpace.Hom.degree : ℕ := @Module.finr (by have := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom);exact Algebra.toModule) - +end Zero open Classical in /-- Implementation detail for pushforward: function used to define the coefficient of the pushforward @@ -146,6 +144,28 @@ noncomputable def mapAux {Y : Scheme} (f : X ⟶ Y) (x : X) : ℤ := if height x = height (f.base x) then Hom.degree f x else 0 + + +class _root_.HasDegree (Z : Type*) [Semiring Z] where + degree : ∀ {X Y : Scheme.{u}}, (X ⟶ Y) → X → Z + degree_one {X : Scheme.{u}} (z : X) : degree (𝟙 X) z = 1 + + +open Classical in +noncomputable +def mapAux' [Semiring Z] {N : Type*} (h : {Y : Scheme.{u}} → Y → N) + [HasDegree Z] {Y : Scheme} (f : X ⟶ Y) (x : X) : Z := + if h x = h (f.base x) then HasDegree.degree f x else 0 + +/- +I think this is the kind of thing we might want for, say, gradings that only work on particular +kinds of scheme (I'm thinking in particular of gradings explicitly involving some dimension +function, in which case our m would check if the scheme is of finite type over (S, δ) or +something). +-/ +def h {Y : Scheme.{u}} (m : Scheme.{u} → Prop) (_ : m Y) (x : Y) : Z := sorry + + /-- The pushforward of an algebraic cycle has locally finite support. @@ -155,10 +175,11 @@ issues when instead writing this definition in the `supportLocallyFiniteWithinDo I feel the proof here is a bit too long, but I'm a little unsure of how I should shorten it. -/ -lemma map_locally_finite {Y : Scheme} - (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : - ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ - ∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux f x).Finite := by +lemma map_locally_finite {Z : Type*} {Y : Scheme} [Semiring Z] [HasDegree Z] + {N : Type*} (h : {Y : Scheme.{u}} → Y → N) + (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X Z) : + ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ + ∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux' h f x).Finite := by intro y obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by aesop) have cpct : IsCompact (f.base ⁻¹' W) := qc.1 W.carrier W.is_open' <| @@ -227,37 +248,64 @@ Note that usually the pushforward is only defined for proper morphisms, and inde properness to prove that the pushforward preserves rational equivalence. -/ noncomputable -def map {Y : Scheme.{u}} (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X) : AlgebraicCycle Y +def map {Z : Type*} {Y : Scheme.{u}} [Semiring Z] [HasDegree Z] + {N : Type*} (h : {Y : Scheme.{u}} → Y → N) (f : X ⟶ Y) [qc : QuasiCompact f] + (c : AlgebraicCycle X Z) : AlgebraicCycle Y Z where - toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux f x) + toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux' h f x) supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' := fun z a ↦ map_locally_finite f c z + supportLocallyFiniteWithinDomain' z _ := map_locally_finite h f c z + + + +/- +Here, instead of HomogeneousAddSubgroup, we want to have for a general grading A, that c ∈ A d. +I think this preservation property is not going to be true for an arbitrary grading (i.e. how could +it). It's certainly true for the dimension grading (as proven below), +and this being true should arguably be a condition of being a grading. The thing is, this will not +hold for codimension (since this is somehow a relative thing). Indeed, I think most of the reason +to favour the dimension grading is that there is this niceness w.r.t taking pushforwards (and +pullbacks). So if we want a common abstraction, this probably isn't the property to go for. + +It's unclear to me what common property we could even have. Of course, one could argue that +homogeneity in some sense should be preserved, i.e. you may get knocked from A X i to A Y (σ i), +but there is still some mapping here. + +I don't really know if we're going to need to have some equidimensionality assumption somewhere tbh. + +-/ + +#check dimensionGrading +#check (fun {X : Scheme} (x : X) ↦ height x) + + +noncomputable instance : HasDegree ℕ where + degree := Hom.degree + degree_one := by simp [Hom.degree] /-- Pushforward preserves cycles of pure dimension `d`. -/ noncomputable -def map_homogeneneous {Y : Scheme.{u}} {d : ℕ∞} (f : X ⟶ Y) [qc : QuasiCompact f] - (c : HomogeneousAddSubgroup X d) : HomogeneousAddSubgroup Y d where - val := map f c +def map_homogeneneous {Y : Scheme.{u}} [Semiring Z] [HasDegree Z] + {d : ℕ∞} (f : X ⟶ Y) [qc : QuasiCompact f] + (c : dimensionGrading X Z d) : dimensionGrading Y Z d where + val := map (fun {X : Scheme} (x : X) ↦ height x) f c property := by - simp[HomogeneousAddSubgroup, IsHomogeneous] + simp only [dimensionGrading] intro y hy - have : ¬ (map f c).toFun y = 0 := hy - simp only [top_eq_univ, map, preimageSupport, mapAux, mul_ite, mul_zero] at this - obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero this - simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, - Function.mem_support, ne_eq, ite_eq_right_iff, mul_eq_zero, Int.natCast_eq_zero, - Classical.not_imp, not_or] at hx + simp [map, preimageSupport, mapAux'] at hy + obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy + simp at hx have : height x = d := c.2 x hx.1.2 - aesop + simp_all /-- The pushforward of `c` along the identity morphism is `c`. -/ @[simp] -lemma map_id (c : AlgebraicCycle X) : - map (𝟙 X) c = c := by +lemma map_id {Z : Type*} [Semiring Z] [HasDegree Z] (c : AlgebraicCycle X Z) : + map (fun {X : Scheme} (x : X) ↦ height x) (𝟙 X) c = c := by ext z have : (c z ≠ 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = {z}) ∨ (c z = 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = ∅) := by @@ -267,14 +315,12 @@ lemma map_id (c : AlgebraicCycle X) : Finset.mem_singleton, and_iff_left_iff_imp] rintro rfl assumption - suffices (map (𝟙 X) c).toFun z = c.toFun z from this + suffices (map (fun {X : Scheme} (x : X) ↦ height x) (𝟙 X) c).toFun z = c.toFun z from this obtain h | h := this - all_goals simp only [top_eq_univ, map, mapAux, Scheme.id.base, TopCat.hom_id, + all_goals simp only [top_eq_univ, map, mapAux', Scheme.id.base, TopCat.hom_id, ContinuousMap.id_apply, ↓reduceIte] rw[h.2] - simp only [Hom.degree, Scheme.id.base, TopCat.hom_id, ContinuousMap.id_apply, - Scheme.stalkMap_id, CommRingCat.hom_id, IsLocalRing.ResidueField.map_id, - Module.finrank_self, Nat.cast_one, mul_one, Finset.sum_singleton] + simp only [HasDegree.degree_one, mul_one, Finset.sum_singleton, Finset.sum_empty] · rfl · exact h.1.symm diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index f322b8c989d40b..ebe455207c93e2 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -207,7 +207,7 @@ variable (U) in /-- Functions with locally finite support within `U` form an additive subgroup of functions X → Y. -/ -protected def addSubgroup [AddCommGroup Y] : AddSubgroup (X → Y) where +protected def addSubmonoid [AddMonoid Y] : AddSubmonoid (X → Y) where carrier := {f | f.support ⊆ U ∧ ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)} zero_mem' := by simp only [support_subset_iff, ne_eq, mem_setOf_eq, Pi.zero_apply, not_true_eq_false, @@ -230,10 +230,21 @@ protected def addSubgroup [AddCommGroup Y] : AddSubgroup (X → Y) where by_contra hCon push_neg at hCon simp_all - neg_mem' {f} hf := by - simp_all -protected lemma memAddSubgroup [AddCommGroup Y] (D : locallyFinsuppWithin U Y) : +protected lemma memAddSubmonoid [AddMonoid Y] (D : locallyFinsuppWithin U Y) : + (D : X → Y) ∈ locallyFinsuppWithin.addSubmonoid U := + ⟨D.supportWithinDomain, D.supportLocallyFiniteWithinDomain⟩ + +variable (U) in +/-- +Functions with locally finite support within `U` form an additive subgroup of functions X → Y. +-/ +protected def addSubgroup [AddGroup Y] : AddSubgroup (X → Y) where + carrier := {f | f.support ⊆ U ∧ ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)} + __ := locallyFinsuppWithin.addSubmonoid U + neg_mem' {f} hf := by simp_all + +protected lemma memAddSubgroup [AddGroup Y] (D : locallyFinsuppWithin U Y) : (D : X → Y) ∈ locallyFinsuppWithin.addSubgroup U := ⟨D.supportWithinDomain, D.supportLocallyFiniteWithinDomain⟩ @@ -241,40 +252,59 @@ protected lemma memAddSubgroup [AddCommGroup Y] (D : locallyFinsuppWithin U Y) Assign a function with locally finite support within `U` to a function in the subgroup. -/ @[simps] -def mk_of_mem [AddCommGroup Y] (f : X → Y) (hf : f ∈ locallyFinsuppWithin.addSubgroup U) : +def mk_of_mem [AddMonoid Y] (f : X → Y) (hf : f ∈ locallyFinsuppWithin.addSubmonoid U) : locallyFinsuppWithin U Y := ⟨f, hf.1, hf.2⟩ -instance [AddCommGroup Y] : Zero (locallyFinsuppWithin U Y) where +instance [AddMonoid Y] : Zero (locallyFinsuppWithin U Y) where zero := mk_of_mem 0 <| zero_mem _ -instance [AddCommGroup Y]: Add (locallyFinsuppWithin U Y) where - add D₁ D₂ := mk_of_mem (D₁ + D₂) <| add_mem D₁.memAddSubgroup D₂.memAddSubgroup +instance [AddMonoid Y]: Add (locallyFinsuppWithin U Y) where + add D₁ D₂ := mk_of_mem (D₁ + D₂) <| add_mem D₁.memAddSubmonoid D₂.memAddSubmonoid -instance [AddCommGroup Y] : Neg (locallyFinsuppWithin U Y) where - neg D := mk_of_mem (-D) <| neg_mem D.memAddSubgroup +instance [AddMonoid Y] : SMul ℕ (locallyFinsuppWithin U Y) where + smul n D := mk_of_mem (n • D) <| nsmul_mem D.memAddSubmonoid n -instance [AddCommGroup Y] : Sub (locallyFinsuppWithin U Y) where - sub D₁ D₂ := mk_of_mem (D₁ - D₂) <| sub_mem D₁.memAddSubgroup D₂.memAddSubgroup +/-- +Assign a function with locally finite support within `U` to a function in the subgroup. +-/ +@[simps] +def mk_of_mem' [AddGroup Y] (f : X → Y) (hf : f ∈ locallyFinsuppWithin.addSubgroup U) : + locallyFinsuppWithin U Y := ⟨f, hf.1, hf.2⟩ + +instance [AddGroup Y] : Neg (locallyFinsuppWithin U Y) where + neg D := mk_of_mem' (-D) <| neg_mem D.memAddSubgroup -instance [AddCommGroup Y] : SMul ℕ (locallyFinsuppWithin U Y) where - smul n D := mk_of_mem (n • D) <| nsmul_mem D.memAddSubgroup n +instance [AddGroup Y] : Sub (locallyFinsuppWithin U Y) where + sub D₁ D₂ := mk_of_mem' (D₁ - D₂) <| sub_mem D₁.memAddSubgroup D₂.memAddSubgroup -instance [AddCommGroup Y] : SMul ℤ (locallyFinsuppWithin U Y) where - smul n D := mk_of_mem (n • D) <| zsmul_mem D.memAddSubgroup n +instance [AddGroup Y] : SMul ℤ (locallyFinsuppWithin U Y) where + smul n D := mk_of_mem' (n • D) <| zsmul_mem D.memAddSubgroup n -@[simp] lemma coe_zero [AddCommGroup Y] : +@[simp] lemma coe_zero [AddMonoid Y] : ((0 : locallyFinsuppWithin U Y) : X → Y) = 0 := rfl -@[simp] lemma coe_add [AddCommGroup Y] (D₁ D₂ : locallyFinsuppWithin U Y) : +@[simp] lemma coe_add [AddMonoid Y] (D₁ D₂ : locallyFinsuppWithin U Y) : (↑(D₁ + D₂) : X → Y) = D₁ + D₂ := rfl -@[simp] lemma coe_neg [AddCommGroup Y] (D : locallyFinsuppWithin U Y) : +@[simp] lemma coe_neg [AddGroup Y] (D : locallyFinsuppWithin U Y) : (↑(-D) : X → Y) = -(D : X → Y) := rfl -@[simp] lemma coe_sub [AddCommGroup Y] (D₁ D₂ : locallyFinsuppWithin U Y) : +@[simp] lemma coe_sub [AddGroup Y] (D₁ D₂ : locallyFinsuppWithin U Y) : (↑(D₁ - D₂) : X → Y) = D₁ - D₂ := rfl -@[simp] lemma coe_nsmul [AddCommGroup Y] (D : locallyFinsuppWithin U Y) (n : ℕ) : +@[simp] lemma coe_nsmul [AddMonoid Y] (D : locallyFinsuppWithin U Y) (n : ℕ) : (↑(n • D) : X → Y) = n • (D : X → Y) := rfl -@[simp] lemma coe_zsmul [AddCommGroup Y] (D : locallyFinsuppWithin U Y) (n : ℤ) : +@[simp] lemma coe_zsmul [AddGroup Y] (D : locallyFinsuppWithin U Y) (n : ℤ) : (↑(n • D) : X → Y) = n • (D : X → Y) := rfl +instance [AddMonoid Y] : AddMonoid (locallyFinsuppWithin U Y) := + Injective.addMonoid (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) + _ coe_injective coe_zero coe_add coe_nsmul + +instance [AddCommMonoid Y] : AddCommMonoid (locallyFinsuppWithin U Y) := + Injective.addCommMonoid (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) + _ coe_injective coe_zero coe_add coe_nsmul + +instance [AddGroup Y] : AddGroup (locallyFinsuppWithin U Y) := + Injective.addGroup (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) + _ coe_injective coe_zero coe_add coe_neg coe_sub coe_nsmul coe_zsmul + instance [AddCommGroup Y] : AddCommGroup (locallyFinsuppWithin U Y) := Injective.addCommGroup (M₁ := locallyFinsuppWithin U Y) (M₂ := X → Y) _ coe_injective coe_zero coe_add coe_neg coe_sub coe_nsmul coe_zsmul From 909ec6005085dfacebe680724ffcb6bfec16aa47 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 19 Feb 2026 16:03:17 +0100 Subject: [PATCH 17/70] WIP --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 165 ++++++++++++++++-- 1 file changed, 148 insertions(+), 17 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 32d7516b78daa0..d36fff802b7a0e 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -40,6 +40,9 @@ abbrev AlgebraicCycle (X : Scheme.{u}) (Z : Type*) [Zero Z] := namespace AlgebraicCycle +lemma locallyFiniteSupport [Zero Z] (c : AlgebraicCycle X Z) : LocallyFiniteSupport c := + fun z ↦ c.supportLocallyFiniteWithinDomain' z (mem_of_subset_of_mem (fun _ a ↦ a) trivial) + /- I think this is the data we should take in whenever we want to talk about a grading. Since everything should be mostly handled by typeclass inference, it should suffice to only explicitly @@ -57,7 +60,7 @@ def dimensionGrading [AddMonoid Z] (d : ℕ∞) : carrier := {c : AlgebraicCycle X Z | ∀ x ∈ c.support, height x = d} add_mem' c₁ c₂ := by rename_i a b - simp_all only [top_eq_univ, Function.mem_support, ne_eq, mem_setOf_eq, + simp_all only [Function.mem_support, ne_eq, mem_setOf_eq, Function.locallyFinsuppWithin.coe_add, Pi.add_apply] intro x hx have : ¬ a x = 0 ∨ ¬ b x = 0 := by @@ -89,14 +92,13 @@ variable (f : X ⟶ Y) (x : X) (z : Y) - /-- The cycle containing a single point with a chosen coefficient -/ noncomputable def single (coeff : Z) : AlgebraicCycle X Z where toFun := Set.indicator {x} (Function.const X coeff) - supportWithinDomain' := by simp + supportWithinDomain' := by simp only [support_indicator]; exact LE.le.subset fun _ a_1 ↦ trivial supportLocallyFiniteWithinDomain' z hz := ⟨⊤, ⟨Filter.univ_mem' fun a ↦ trivial, by simp [← Function.const_def, toFinite]⟩⟩ @@ -112,10 +114,17 @@ Implementation detail for the pushforward; the support of a cycle on X intersect of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. -/ lemma preimageSupport_finite [qf : QuasiCompact f] : - (preimageSupport f c z).Finite := - supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' <| - QuasiCompact.isCompact_preimage_singleton f z + (preimageSupport f c z).Finite := LocallyFiniteSupport.finite_inter_support_of_isCompact + c.locallyFiniteSupport <| f.isCompact_preimage_singleton z + + --supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' <| + -- QuasiCompact.isCompact_preimage_singleton f z +noncomputable +instance (x : X) : Module (IsLocalRing.ResidueField ↑(Y.presheaf.stalk (f x))) + (IsLocalRing.ResidueField ↑(X.presheaf.stalk x)) := by + let a := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom) + exact Algebra.toModule /-- Degree of `f` at a point `x` is defined to be the degree of the associated field extension from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is either infinite @@ -127,8 +136,11 @@ def _root_.AlgebraicGeometry.LocallyRingedSpace.Hom.degree : ℕ := @Module.finr (IsLocalRing.ResidueField (X.presheaf.stalk x)) (by infer_instance) (by infer_instance) - (by have := - RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom);exact Algebra.toModule) + (by infer_instance) + --(by infer_instance) + + --(by let a := + -- RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom); exact Algebra.toModule) end Zero open Classical in @@ -145,11 +157,31 @@ def mapAux {Y : Scheme} (f : X ⟶ Y) (x : X) : ℤ := if height x = height (f.base x) then Hom.degree f x else 0 +/- +Is this really necessary? +I can't think of any application of this other than the obvious HasDegree ℤ and +HasDegree ℕ. Maybe there's a good one though, who knows. +-/ class _root_.HasDegree (Z : Type*) [Semiring Z] where degree : ∀ {X Y : Scheme.{u}}, (X ⟶ Y) → X → Z degree_one {X : Scheme.{u}} (z : X) : degree (𝟙 X) z = 1 +/- +I think it would be better +-/ +variable (X) (Z) in +structure Grading [AddMonoid Z] where + I : Type* + ι : I → AddSubmonoid (AlgebraicCycle X Z) + +/- +I think this is the superior way to do gradings +-/ +def dimensionGrading'' [AddMonoid Z] : Grading X Z where + I := ℕ∞ + ι := dimensionGrading X Z + open Classical in noncomputable @@ -163,7 +195,79 @@ kinds of scheme (I'm thinking in particular of gradings explicitly involving som function, in which case our m would check if the scheme is of finite type over (S, δ) or something). -/ -def h {Y : Scheme.{u}} (m : Scheme.{u} → Prop) (_ : m Y) (x : Y) : Z := sorry +--def h {Y : Scheme.{u}} (m : Scheme.{u} → Prop) (_ : m Y) (x : Y) : Z := sorry + + +/- +How do we want algebraic cycles to work? + +Probably want to be able to declare a cycle with coeffients in Z like we have above. + +I think it's probably most sensible to just have a notion of "grading" which is structure +Grading X Z: + I : Type* + ι : I → SubMonoid <| AlgebraicCycle X Z + +Maybe it's not necessary to have this there... + +-/ + + +section testing +variable {Z : Type*} [Semiring Z] {W : Y.Opens} (hW : IsAffineOpen W) + (f : X ⟶ Y) (c : AlgebraicCycle X Z) + + +lemma preimageSupport_inter_subset : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ + f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by + intro a ha + rw [image_preimage_inter] + suffices a ∈ f.base '' c.support from mem_inter ha this + have := ha.2.some_mem + simp only [preimageSupport, mem_inter_iff, mem_preimage, mem_singleton_iff, + Function.mem_support, ne_eq, mem_image] at this ⊢ + exact ⟨ha.2.some, this.symm⟩ + +lemma preimageSupport_preimage_inter_subset : f.base ⁻¹' W.carrier ∩ + f.base ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ + f.base ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by + intro p hp + simp only [Opens.carrier_eq_coe, preimageSupport, preimage_setOf_eq, mem_inter_iff, + mem_preimage, SetLike.mem_coe, mem_setOf_eq, Function.mem_support, ne_eq, mem_iUnion, + mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ + exact ⟨hp.1.1, hp.2⟩ + +variable [qc : QuasiCompact f] + +lemma preimage_inter_support_finite_of_isAffineOpen (hW : IsAffineOpen W) : + (f.base ⁻¹' W.carrier ∩ c.support).Finite := + LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| + qc.1 W.carrier W.is_open' <| AlgebraicGeometry.IsAffineOpen.isCompact hW + +lemma iUnion_preimage_inter_support_finite_of_isAffineOpen (hW : IsAffineOpen W) : + (⋃ _ : Y, f.base ⁻¹' W.carrier ∩ c.support).Finite := by + suffices (f.base ⁻¹' W.carrier ∩ c.support).Finite by + apply Finite.subset this + intro a ha + simp only [Opens.carrier_eq_coe, mem_iUnion, mem_inter_iff, mem_preimage, + SetLike.mem_coe, Function.mem_support, ne_eq, exists_and_left, exists_const_iff] at ha ⊢ + exact ⟨ha.1, ha.2.2⟩ + exact preimage_inter_support_finite_of_isAffineOpen f c hW + +lemma inter_nonempty_finite (hW : IsAffineOpen W) + : (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite := by + refine Finite.subset (Finite.image _ ?_) (preimageSupport_inter_subset f c) + rw[preimage_inter] + apply Finite.subset _ (preimageSupport_preimage_inter_subset f c) + rw[inter_iUnion] + suffices (⋃ i : Y, f.base ⁻¹' W.carrier ∩ c.support).Finite by + apply Finite.subset this + simp only [Opens.carrier_eq_coe, iUnion_subset_iff] + intro y x hx + simp only [mem_inter_iff, mem_preimage, SetLike.mem_coe, + Function.mem_support, ne_eq, mem_iUnion, exists_and_left, exists_const_iff] at hx ⊢ + exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ + exact iUnion_preimage_inter_support_finite_of_isAffineOpen f c hW /-- @@ -188,13 +292,20 @@ lemma map_locally_finite {Z : Type*} {Y : Scheme} [Semiring Z] [HasDegree Z] refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2.1, ?_⟩ have pbfinite : (f.base ⁻¹' W ∩ Function.support c).Finite := - supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' cpct + LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport cpct + --supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' cpct + + + /- + Should probably prove this suffices in a separate lemma, then show this lemma we're in using + the reasoning in the suffices block + -/ suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by apply Finite.subset this apply inter_subset_inter Set.Subset.rfl intro x - simp only [top_eq_univ, Function.mem_support, ne_eq, mem_setOf_eq] + simp only [Function.mem_support, ne_eq, mem_setOf_eq] contrapose! intro aux rw [Finset.sum_eq_zero] @@ -241,6 +352,8 @@ lemma map_locally_finite {Z : Type*} {Y : Scheme} [Semiring Z] [HasDegree Z] exact pbfinite + +end testing /-- The pushforward of an algebraic cycle by a quasicompact morphism. @@ -253,7 +366,7 @@ def map {Z : Type*} {Y : Scheme.{u}} [Semiring Z] [HasDegree Z] (c : AlgebraicCycle X Z) : AlgebraicCycle Y Z where toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux' h f x) - supportWithinDomain' := by simp + supportWithinDomain' := by simp; sorry supportLocallyFiniteWithinDomain' z _ := map_locally_finite h f c z @@ -278,10 +391,24 @@ I don't really know if we're going to need to have some equidimensionality assum #check dimensionGrading #check (fun {X : Scheme} (x : X) ↦ height x) +lemma fds (R : Type*) [CommSemiring R] : Semiring.toModule (R := R) = + Algebra.toModule (R := R) (A := R) := rfl +/- +This is absolutely insane and this proof should be by simp. +-/ noncomputable instance : HasDegree ℕ where degree := Hom.degree - degree_one := by simp [Hom.degree] + degree_one {M} x := by + dsimp [Hom.degree] + have := fds (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) + let k := Module.finrank_self (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) + convert k + rw [this] + simp [inferInstance, + instModuleResidueFieldCarrierStalkCommRingCatPresheafCoeContinuousMapCarrierCarrierHomTopCatBase] + congr + aesop /-- Pushforward preserves cycles of pure dimension `d`. @@ -294,9 +421,11 @@ def map_homogeneneous {Y : Scheme.{u}} [Semiring Z] [HasDegree Z] property := by simp only [dimensionGrading] intro y hy - simp [map, preimageSupport, mapAux'] at hy + simp only [map, preimageSupport, mapAux', mul_ite, mul_zero, Function.mem_support, + ne_eq] at hy obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy - simp at hx + simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, + Function.mem_support, ne_eq, ite_eq_right_iff, Classical.not_imp] at hx have : height x = d := c.2 x hx.1.2 simp_all @@ -309,7 +438,9 @@ lemma map_id {Z : Type*} [Semiring Z] [HasDegree Z] (c : AlgebraicCycle X Z) : ext z have : (c z ≠ 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = {z}) ∨ (c z = 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = ∅) := by - simp[preimageSupport_finite, preimageSupport, Finite.toFinset] + simp only [ne_eq, Finite.toFinset, preimageSupport, Scheme.Hom.id_base, TopCat.hom_id, + ContinuousMap.coe_id, preimage_id_eq, id_eq, toFinset_eq_empty, singleton_inter_eq_empty, + Function.mem_support, not_not, and_self] refine Or.elim (em (c z = 0)) (fun o ↦ Or.inr o) (fun o ↦ Or.inl ⟨o, Finset.ext (fun a ↦ ?_)⟩) simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, Finset.mem_singleton, and_iff_left_iff_imp] @@ -317,7 +448,7 @@ lemma map_id {Z : Type*} [Semiring Z] [HasDegree Z] (c : AlgebraicCycle X Z) : assumption suffices (map (fun {X : Scheme} (x : X) ↦ height x) (𝟙 X) c).toFun z = c.toFun z from this obtain h | h := this - all_goals simp only [top_eq_univ, map, mapAux', Scheme.id.base, TopCat.hom_id, + all_goals simp only [map, mapAux', Scheme.Hom.id_base, TopCat.hom_id, ContinuousMap.id_apply, ↓reduceIte] rw[h.2] simp only [HasDegree.degree_one, mul_one, Finset.sum_singleton, Finset.sum_empty] From 01f59122dc73544f8acbc08785c7d6532e15d919 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 12:02:11 +0100 Subject: [PATCH 18/70] Refactored a lot of the code and cleaned up the way gradings are defined --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 346 ++++++------------ Mathlib/Topology/LocallyFinsupp.lean | 4 + 2 files changed, 111 insertions(+), 239 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index d36fff802b7a0e..ed27bd8a3d93d6 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -14,8 +14,13 @@ import Mathlib.Algebra.DirectSum.Decomposition /-! # Algebraic Cycles -We define algebraic cycles on a scheme `X` to be functions `c : X → ℤ` whose support is -locally finite. +In this define algebraic cycles on a scheme `X` with coefficients in a type `Z` and provide some +basic API for working with them. We define an algebraic cycle on a scheme `X` with coefficients +in a type `Z` to be functions `c : X → Z` whose support is locally finite. + +Here we're making use of the equivalence between irreducible closed subsets of a scheme and their +generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly +nonstandard definition. -/ open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace @@ -25,37 +30,38 @@ universe u v variable (R : Type*) [CommRing R] (i : ℕ) - {X Y : Scheme.{u}} - (Z : Type*) --[Zero Z] + (X : Scheme.{u}) + {Y : Scheme.{u}} + (Z : Type*) /-- -Algebraic cycle on a scheme X. +Algebraic cycle on a scheme `X` with coefficients in a type `Z` is just a function from `X` to `Z` +with locally finite support. -Note I am not certain that this should be an abbrev. I'm also not sure if these definitions -should instead directly be about Function.locallyFinsuppWithin +Here we're making use of the equivalence between irreducible closed subsets of a scheme and their +generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly +nonstandard definition. -/ abbrev AlgebraicCycle (X : Scheme.{u}) (Z : Type*) [Zero Z] := - Function.locallyFinsuppWithin (⊤ : Set X) Z - + Function.locallyFinsupp X Z namespace AlgebraicCycle -lemma locallyFiniteSupport [Zero Z] (c : AlgebraicCycle X Z) : LocallyFiniteSupport c := - fun z ↦ c.supportLocallyFiniteWithinDomain' z (mem_of_subset_of_mem (fun _ a ↦ a) trivial) - /- -I think this is the data we should take in whenever we want to talk about a grading. Since -everything should be mostly handled by typeclass inference, it should suffice to only explicitly -pass A around. +In the context of algebraic cycles, gradings tend to be defined using functions on +the components of the cycles (mainly different notions of dimension and codimension). +Here we define a notion of grading defined by such a dimension/codimension function. -/ -/-variable {S ι : Type*} [AddMonoid Z] [SetLike S (AlgebraicCycle X Z)] [AddMonoid ι] - [AddSubmonoidClass S (AlgebraicCycle X Z)] [DecidableEq ι] - (A : ι → S) (X)-/ -variable (X) +structure Grading [AddMonoid Z] (N : Type*) where + f : X → N + mon (d : N) : AddSubmonoid (AlgebraicCycle X Z) + mon_carrier (d : N) : (mon d).carrier = + {c : AlgebraicCycle X Z | ∀ x ∈ c.support, f x = d} := by aesop + /-- Subgroup of cycles of pure dimension `d`. -/ -def dimensionGrading [AddMonoid Z] (d : ℕ∞) : +def dimensionGradingAddSubmonoid [AddMonoid Z] (d : ℕ∞) : AddSubmonoid (AlgebraicCycle X Z) where carrier := {c : AlgebraicCycle X Z | ∀ x ∈ c.support, height x = d} add_mem' c₁ c₂ := by @@ -69,17 +75,16 @@ def dimensionGrading [AddMonoid Z] (d : ℕ∞) : exact Or.elim this (c₁ x) (c₂ x) zero_mem' := by simp - -def dimensionGrading' (Z : Type*) [AddCommGroup Z] (d : ℕ∞) : - AddSubgroup (AlgebraicCycle X Z) where - __ := dimensionGrading X Z d - neg_mem' c := by simp_all [dimensionGrading] - - - - -def codimensionGrading [AddCommGroup Z] (d : ℕ∞) := - {c : AlgebraicCycle X Z | ∀ x ∈ c.support, coheight x = d} +/-- +Grading on `AlgebraicCycle X Z` by dimension, where dimension of a point is defined to be the +height in the specialization order. Note this notion of dimension falls apart a bit outside of +contexts where there are some equidimensionality hypotheses. In these contexts, the theory of +dimension functions is more appropriate to use. +-/ +noncomputable +def dimensionGrading [AddMonoid Z] : Grading X Z ℕ∞ where + f := Order.height + mon := dimensionGradingAddSubmonoid X Z variable {X Z} @@ -87,7 +92,6 @@ section Zero variable (f : X ⟶ Y) [Zero Z] - --[AddMonoid Z] (c : AlgebraicCycle X Z) (x : X) (z : Y) @@ -117,14 +121,12 @@ lemma preimageSupport_finite [qf : QuasiCompact f] : (preimageSupport f c z).Finite := LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| f.isCompact_preimage_singleton z - --supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' <| - -- QuasiCompact.isCompact_preimage_singleton f z - noncomputable -instance (x : X) : Module (IsLocalRing.ResidueField ↑(Y.presheaf.stalk (f x))) - (IsLocalRing.ResidueField ↑(X.presheaf.stalk x)) := by - let a := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom) - exact Algebra.toModule +instance moduleResidueFieldExtension (x : X) : + Module (IsLocalRing.ResidueField ↑(Y.presheaf.stalk (f x))) + (IsLocalRing.ResidueField ↑(X.presheaf.stalk x)) := + letI := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom) + Algebra.toModule /-- Degree of `f` at a point `x` is defined to be the degree of the associated field extension from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is either infinite @@ -133,91 +135,41 @@ or undefined. noncomputable def _root_.AlgebraicGeometry.LocallyRingedSpace.Hom.degree : ℕ := @Module.finrank (IsLocalRing.ResidueField (Y.presheaf.stalk (f.base x))) - (IsLocalRing.ResidueField (X.presheaf.stalk x)) - (by infer_instance) - (by infer_instance) - (by infer_instance) - --(by infer_instance) - - --(by let a := - -- RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom); exact Algebra.toModule) + (IsLocalRing.ResidueField (X.presheaf.stalk x)) _ _ _ end Zero -open Classical in -/-- -Implementation detail for pushforward: function used to define the coefficient of the pushforward -of a cycle `c` at a point `z = f x`, as in stacks 02R3. - -Note: I'm not entirely sure if the case distinction here (and hence this definition) is necessary, -since the degree alread has a default value of zero whenever the degree of the field extension is -not finite. --/ -noncomputable -def mapAux {Y : Scheme} (f : X ⟶ Y) (x : X) : ℤ := - if height x = height (f.base x) then Hom.degree f x else 0 +/-- +The usual degree function of a morphism of schemes `f : X ⟶ Y` at a point `x : X` +is defined to be the degree of the associated field extension from `κ(f x)` to `κ(x)`, and can be +viewed a kind of correction factor with respect to which one can define the pushforward of algebraic +cycles. -/- -Is this really necessary? - -I can't think of any application of this other than the obvious HasDegree ℤ and -HasDegree ℕ. Maybe there's a good one though, who knows. +The class `HasDegree Z` states the properties needed of such a degree function to define a sensible +notion of pushforward from `AlgebraicCycle X Z` to `AlgebraicCycle Y Z`. -/ -class _root_.HasDegree (Z : Type*) [Semiring Z] where +class HasDegree (Z : Type*) [Semiring Z] where degree : ∀ {X Y : Scheme.{u}}, (X ⟶ Y) → X → Z degree_one {X : Scheme.{u}} (z : X) : degree (𝟙 X) z = 1 -/- -I think it would be better --/ -variable (X) (Z) in -structure Grading [AddMonoid Z] where - I : Type* - ι : I → AddSubmonoid (AlgebraicCycle X Z) - -/- -I think this is the superior way to do gradings --/ -def dimensionGrading'' [AddMonoid Z] : Grading X Z where - I := ℕ∞ - ι := dimensionGrading X Z - open Classical in -noncomputable -def mapAux' [Semiring Z] {N : Type*} (h : {Y : Scheme.{u}} → Y → N) - [HasDegree Z] {Y : Scheme} (f : X ⟶ Y) (x : X) : Z := - if h x = h (f.base x) then HasDegree.degree f x else 0 - /- -I think this is the kind of thing we might want for, say, gradings that only work on particular -kinds of scheme (I'm thinking in particular of gradings explicitly involving some dimension -function, in which case our m would check if the scheme is of finite type over (S, δ) or -something). --/ ---def h {Y : Scheme.{u}} (m : Scheme.{u} → Prop) (_ : m Y) (x : Y) : Z := sorry - - -/- -How do we want algebraic cycles to work? - -Probably want to be able to declare a cycle with coeffients in Z like we have above. - -I think it's probably most sensible to just have a notion of "grading" which is structure -Grading X Z: - I : Type* - ι : I → SubMonoid <| AlgebraicCycle X Z - -Maybe it's not necessary to have this there... - +Implementation detail for pushforward: function used to define the coefficient of the pushforward +of a cycle `c` at a point `z = f x`, as in stacks `02R3`. -/ +noncomputable +def mapAux {N : Type*} [AddMonoid N] [Semiring Z] + [HasDegree Z] {Y : Scheme} + (gx : Grading X Z N) (gy : Grading Y Z N) + (f : X ⟶ Y) (x : X) : Z := + if gx.f x = gy.f (f.base x) then HasDegree.degree f x else 0 +section map -section testing variable {Z : Type*} [Semiring Z] {W : Y.Opens} (hW : IsAffineOpen W) (f : X ⟶ Y) (c : AlgebraicCycle X Z) - lemma preimageSupport_inter_subset : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by intro a ha @@ -269,38 +221,18 @@ lemma inter_nonempty_finite (hW : IsAffineOpen W) exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ exact iUnion_preimage_inter_support_finite_of_isAffineOpen f c hW +variable {N : Type*} [AddMonoid N] [HasDegree Z] /-- The pushforward of an algebraic cycle has locally finite support. - -Note that while this could be part of the definition of map, we experienced significant performance -issues when instead writing this definition in the `supportLocallyFiniteWithinDomain'` field of the -`map` definition. - -I feel the proof here is a bit too long, but I'm a little unsure of how I should shorten it. -/ -lemma map_locally_finite {Z : Type*} {Y : Scheme} [Semiring Z] [HasDegree Z] - {N : Type*} (h : {Y : Scheme.{u}} → Y → N) - (f : X ⟶ Y) [qc : QuasiCompact f] (c : AlgebraicCycle X Z) : +lemma map_locally_finite (gx : Grading X Z N) (gy : Grading Y Z N) : ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ - ∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux' h f x).Finite := by + ∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux gx gy f x).Finite := by intro y - obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by aesop) - have cpct : IsCompact (f.base ⁻¹' W) := qc.1 W.carrier W.is_open' <| - AlgebraicGeometry.IsAffineOpen.isCompact hW.1 + obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by simp) use W refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2.1, ?_⟩ - - have pbfinite : (f.base ⁻¹' W ∩ Function.support c).Finite := - LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport cpct - - --supportLocallyFiniteWithin_top_inter_compact_finite c.supportLocallyFiniteWithinDomain' cpct - - - /- - Should probably prove this suffices in a separate lemma, then show this lemma we're in using - the reasoning in the suffices block - -/ suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by apply Finite.subset this apply inter_subset_inter Set.Subset.rfl @@ -311,49 +243,8 @@ lemma map_locally_finite {Z : Type*} {Y : Scheme} [Semiring Z] [HasDegree Z] rw [Finset.sum_eq_zero] intro x hx simp_all + exact inter_nonempty_finite f c hW.1 - have : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ - f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by - intro a ha - rw [image_preimage_inter] - suffices a ∈ f.base '' c.support from mem_inter ha this - have := ha.2.some_mem - simp only [preimageSupport, top_eq_univ, mem_inter_iff, mem_preimage, mem_singleton_iff, - Function.mem_support, ne_eq, mem_image] at this ⊢ - exact ⟨ha.2.some, this.symm⟩ - - refine Finite.subset (Finite.image _ ?_) this - rw[preimage_inter] - have : f.base ⁻¹' W.carrier ∩ f.base ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ - f.base ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by - intro p hp - simp only [Opens.carrier_eq_coe, preimageSupport, top_eq_univ, preimage_setOf_eq, mem_inter_iff, - mem_preimage, SetLike.mem_coe, mem_setOf_eq, Function.mem_support, ne_eq, mem_iUnion, - mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ - exact ⟨hp.1.1, hp.2⟩ - - apply Finite.subset _ this - rw[inter_iUnion] - simp[preimageSupport] - suffices (⋃ i : Y, f.base ⁻¹' W.carrier ∩ c.support).Finite by - apply Finite.subset this - simp only [Opens.carrier_eq_coe, top_eq_univ, iUnion_subset_iff] - intro y x hx - simp only [mem_inter_iff, mem_preimage, SetLike.mem_coe, mem_singleton_iff, - Function.mem_support, ne_eq, mem_iUnion, exists_and_left, exists_const_iff] at hx ⊢ - exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ - - suffices (f.base ⁻¹' W.carrier ∩ c.support).Finite by - apply Finite.subset this - intro a ha - simp only [Opens.carrier_eq_coe, top_eq_univ, mem_iUnion, mem_inter_iff, mem_preimage, - SetLike.mem_coe, Function.mem_support, ne_eq, exists_and_left, exists_const_iff] at ha ⊢ - exact ⟨ha.1, ha.2.2⟩ - - exact pbfinite - - -end testing /-- The pushforward of an algebraic cycle by a quasicompact morphism. @@ -361,80 +252,33 @@ Note that usually the pushforward is only defined for proper morphisms, and inde properness to prove that the pushforward preserves rational equivalence. -/ noncomputable -def map {Z : Type*} {Y : Scheme.{u}} [Semiring Z] [HasDegree Z] - {N : Type*} (h : {Y : Scheme.{u}} → Y → N) (f : X ⟶ Y) [qc : QuasiCompact f] - (c : AlgebraicCycle X Z) : AlgebraicCycle Y Z +def map (gx : Grading X Z N) (gy : Grading Y Z N) : AlgebraicCycle Y Z where - toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux' h f x) - supportWithinDomain' := by simp; sorry - supportLocallyFiniteWithinDomain' z _ := map_locally_finite h f c z - - - -/- -Here, instead of HomogeneousAddSubgroup, we want to have for a general grading A, that c ∈ A d. -I think this preservation property is not going to be true for an arbitrary grading (i.e. how could -it). It's certainly true for the dimension grading (as proven below), -and this being true should arguably be a condition of being a grading. The thing is, this will not -hold for codimension (since this is somehow a relative thing). Indeed, I think most of the reason -to favour the dimension grading is that there is this niceness w.r.t taking pushforwards (and -pullbacks). So if we want a common abstraction, this probably isn't the property to go for. - -It's unclear to me what common property we could even have. Of course, one could argue that -homogeneity in some sense should be preserved, i.e. you may get knocked from A X i to A Y (σ i), -but there is still some mapping here. - -I don't really know if we're going to need to have some equidimensionality assumption somewhere tbh. - --/ - -#check dimensionGrading -#check (fun {X : Scheme} (x : X) ↦ height x) - -lemma fds (R : Type*) [CommSemiring R] : Semiring.toModule (R := R) = - Algebra.toModule (R := R) (A := R) := rfl - -/- -This is absolutely insane and this proof should be by simp. --/ -noncomputable instance : HasDegree ℕ where - degree := Hom.degree - degree_one {M} x := by - dsimp [Hom.degree] - have := fds (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) - let k := Module.finrank_self (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) - convert k - rw [this] - simp [inferInstance, - instModuleResidueFieldCarrierStalkCommRingCatPresheafCoeContinuousMapCarrierCarrierHomTopCatBase] - congr - aesop + toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux gx gy f x) + supportWithinDomain' := by simp + supportLocallyFiniteWithinDomain' z _ := map_locally_finite f c gx gy z /-- -Pushforward preserves cycles of pure dimension `d`. +Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ noncomputable -def map_homogeneneous {Y : Scheme.{u}} [Semiring Z] [HasDegree Z] - {d : ℕ∞} (f : X ⟶ Y) [qc : QuasiCompact f] - (c : dimensionGrading X Z d) : dimensionGrading Y Z d where - val := map (fun {X : Scheme} (x : X) ↦ height x) f c - property := by - simp only [dimensionGrading] - intro y hy - simp only [map, preimageSupport, mapAux', mul_ite, mul_zero, Function.mem_support, - ne_eq] at hy - obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy - simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, - Function.mem_support, ne_eq, ite_eq_right_iff, Classical.not_imp] at hx - have : height x = d := c.2 x hx.1.2 - simp_all +def map_homogeneneous {d : ℕ∞} (c : AlgebraicCycle X Z) (hc : c ∈ (dimensionGrading X Z).mon d) : + map f c (dimensionGrading X Z) (dimensionGrading Y Z) ∈ (dimensionGrading Y Z).mon d := by + simp only [dimensionGrading] + intro y hy + simp only [map, preimageSupport, mapAux, mul_ite, mul_zero, Function.mem_support, + ne_eq] at hy + obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy + simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, + Function.mem_support, ne_eq, ite_eq_right_iff, Classical.not_imp] at hx + have : height x = d := hc x hx.1.2 + simp_all /-- The pushforward of `c` along the identity morphism is `c`. -/ @[simp] -lemma map_id {Z : Type*} [Semiring Z] [HasDegree Z] (c : AlgebraicCycle X Z) : - map (fun {X : Scheme} (x : X) ↦ height x) (𝟙 X) c = c := by +lemma map_id (g : Grading X Z N) : map (𝟙 X) c g g = c := by ext z have : (c z ≠ 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = {z}) ∨ (c z = 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = ∅) := by @@ -446,13 +290,37 @@ lemma map_id {Z : Type*} [Semiring Z] [HasDegree Z] (c : AlgebraicCycle X Z) : Finset.mem_singleton, and_iff_left_iff_imp] rintro rfl assumption - suffices (map (fun {X : Scheme} (x : X) ↦ height x) (𝟙 X) c).toFun z = c.toFun z from this + suffices (map (𝟙 X) c g g).toFun z = c.toFun z from this obtain h | h := this - all_goals simp only [map, mapAux', Scheme.Hom.id_base, TopCat.hom_id, + all_goals simp only [map, mapAux, Scheme.Hom.id_base, TopCat.hom_id, ContinuousMap.id_apply, ↓reduceIte] rw[h.2] simp only [HasDegree.degree_one, mul_one, Finset.sum_singleton, Finset.sum_empty] · rfl · exact h.1.symm +end map + +noncomputable instance instHasDegreeNat : HasDegree ℕ where + degree := Hom.degree + degree_one {M} x := by + dsimp [Hom.degree] + have (R : Type*) [CommSemiring R] : Semiring.toModule (R := R) = + Algebra.toModule (R := R) (A := R) := rfl + have := this (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) + let k := Module.finrank_self (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) + convert k + rw [this] + simp [moduleResidueFieldExtension] + congr + aesop + +noncomputable instance : HasDegree ℤ where + degree f x := ↑(Hom.degree f x) + degree_one {M} x := by + have := instHasDegreeNat.degree_one x + dsimp [HasDegree.degree] at this + rw [this] + exact Int.ofNat_one + end AlgebraicCycle diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 0f8b9e2969c469..a98d1974549730 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -99,6 +99,10 @@ lemma LocallyFiniteSupport.finite_inter_support_of_isCompact {W : Set X} rw [← lem f.support W] exact Finite.image Subtype.val this +lemma Function.locallyFinsupp.locallyFiniteSupport [Zero Y] (f : locallyFinsupp X Y) : + LocallyFiniteSupport f.toFun := + fun z ↦ f.supportLocallyFiniteWithinDomain' z (mem_of_subset_of_mem (fun _ a ↦ a) trivial) + namespace Function.locallyFinsuppWithin /-- From b4f71c748ddf4892d8aa3ad16d325b8e89ac0df4 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 12:10:56 +0100 Subject: [PATCH 19/70] Updated import formatting --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index ed27bd8a3d93d6..d5b2704c9fbfcf 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -3,13 +3,15 @@ Copyright (c) 2025 Raphael Douglas Giles. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Raphael Douglas Giles -/ -import Mathlib.AlgebraicGeometry.Fiber -import Mathlib.AlgebraicGeometry.Morphisms.Proper -import Mathlib.Combinatorics.Quiver.ReflQuiver -import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition -import Mathlib.Topology.LocallyFinsupp -import Mathlib.Algebra.GradedMonoid -import Mathlib.Algebra.DirectSum.Decomposition +module + +public import Mathlib.AlgebraicGeometry.Fiber +public import Mathlib.AlgebraicGeometry.Morphisms.Proper +public import Mathlib.Combinatorics.Quiver.ReflQuiver +public import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition +public import Mathlib.Topology.LocallyFinsupp +public import Mathlib.Algebra.GradedMonoid +public import Mathlib.Algebra.DirectSum.Decomposition /-! # Algebraic Cycles @@ -23,6 +25,8 @@ generic points in order to reuse the API in Function.locallyFinsupp, hence the s nonstandard definition. -/ +@[expose] public section + open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace CategoryTheory From bee02e0aede8b40eca9aa5f1d4e1229aedecd3c1 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 12:38:13 +0100 Subject: [PATCH 20/70] Removed unnecessary assumption --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index d5b2704c9fbfcf..b4e17d56cfa4ad 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -131,6 +131,7 @@ instance moduleResidueFieldExtension (x : X) : (IsLocalRing.ResidueField ↑(X.presheaf.stalk x)) := letI := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom) Algebra.toModule + /-- Degree of `f` at a point `x` is defined to be the degree of the associated field extension from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is either infinite @@ -163,8 +164,7 @@ Implementation detail for pushforward: function used to define the coefficient o of a cycle `c` at a point `z = f x`, as in stacks `02R3`. -/ noncomputable -def mapAux {N : Type*} [AddMonoid N] [Semiring Z] - [HasDegree Z] {Y : Scheme} +def mapAux {N : Type*} [Semiring Z] [HasDegree Z] {Y : Scheme} (gx : Grading X Z N) (gy : Grading Y Z N) (f : X ⟶ Y) (x : X) : Z := if gx.f x = gy.f (f.base x) then HasDegree.degree f x else 0 @@ -225,7 +225,7 @@ lemma inter_nonempty_finite (hW : IsAffineOpen W) exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ exact iUnion_preimage_inter_support_finite_of_isAffineOpen f c hW -variable {N : Type*} [AddMonoid N] [HasDegree Z] +variable {N : Type*} [HasDegree Z] /-- The pushforward of an algebraic cycle has locally finite support. From 109f9c73d1e1c910fe19a7f660d6ad1619d00463 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 13:28:41 +0100 Subject: [PATCH 21/70] Added some docstrings --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index b4e17d56cfa4ad..215b793e0de4f0 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -51,16 +51,25 @@ abbrev AlgebraicCycle (X : Scheme.{u}) (Z : Type*) [Zero Z] := namespace AlgebraicCycle -/- +/-- In the context of algebraic cycles, gradings tend to be defined using functions on the components of the cycles (mainly different notions of dimension and codimension). Here we define a notion of grading defined by such a dimension/codimension function. -/ structure Grading [AddMonoid Z] (N : Type*) where - f : X → N - mon (d : N) : AddSubmonoid (AlgebraicCycle X Z) - mon_carrier (d : N) : (mon d).carrier = - {c : AlgebraicCycle X Z | ∀ x ∈ c.support, f x = d} := by aesop + /-- + The "dimension function" associated with the grading + -/ + dim : X → N + /-- + Given `d` in `N`, we have an additive submonoid of homogeneous cycles + -/ + homogeneousCycles (d : N) : AddSubmonoid (AlgebraicCycle X Z) + /-- + Proof that `mon` is the + -/ + homogeneousCycles_carrier (d : N) : (homogeneousCycles d).carrier = + {c : AlgebraicCycle X Z | ∀ x ∈ c.support, dim x = d} := by aesop /-- Subgroup of cycles of pure dimension `d`. @@ -87,8 +96,8 @@ dimension functions is more appropriate to use. -/ noncomputable def dimensionGrading [AddMonoid Z] : Grading X Z ℕ∞ where - f := Order.height - mon := dimensionGradingAddSubmonoid X Z + dim := Order.height + homogeneousCycles := dimensionGradingAddSubmonoid X Z variable {X Z} @@ -154,7 +163,13 @@ The class `HasDegree Z` states the properties needed of such a degree function t notion of pushforward from `AlgebraicCycle X Z` to `AlgebraicCycle Y Z`. -/ class HasDegree (Z : Type*) [Semiring Z] where + /-- + The degree of a morrphism at a point + -/ degree : ∀ {X Y : Scheme.{u}}, (X ⟶ Y) → X → Z + /-- + The degree of the identity at any point is `1`. + -/ degree_one {X : Scheme.{u}} (z : X) : degree (𝟙 X) z = 1 @@ -167,7 +182,7 @@ noncomputable def mapAux {N : Type*} [Semiring Z] [HasDegree Z] {Y : Scheme} (gx : Grading X Z N) (gy : Grading Y Z N) (f : X ⟶ Y) (x : X) : Z := - if gx.f x = gy.f (f.base x) then HasDegree.degree f x else 0 + if gx.dim x = gy.dim (f.base x) then HasDegree.degree f x else 0 section map @@ -265,9 +280,10 @@ def map (gx : Grading X Z N) (gy : Grading Y Z N) : AlgebraicCycle Y Z /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ -noncomputable -def map_homogeneneous {d : ℕ∞} (c : AlgebraicCycle X Z) (hc : c ∈ (dimensionGrading X Z).mon d) : - map f c (dimensionGrading X Z) (dimensionGrading Y Z) ∈ (dimensionGrading Y Z).mon d := by +lemma map_homogeneneous {d : ℕ∞} (c : AlgebraicCycle X Z) + (hc : c ∈ (dimensionGrading X Z).homogeneousCycles d) : + map f c (dimensionGrading X Z) (dimensionGrading Y Z) ∈ + (dimensionGrading Y Z).homogeneousCycles d := by simp only [dimensionGrading] intro y hy simp only [map, preimageSupport, mapAux, mul_ite, mul_zero, Function.mem_support, From 11fdd625acfed5803548a258502486866b05f341 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 13:36:36 +0100 Subject: [PATCH 22/70] Added more missing docstrings --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 215b793e0de4f0..dd3d7871bf2450 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -174,7 +174,7 @@ class HasDegree (Z : Type*) [Semiring Z] where open Classical in -/- +/-- Implementation detail for pushforward: function used to define the coefficient of the pushforward of a cycle `c` at a point `z = f x`, as in stacks `02R3`. -/ From e8d182ffe0a8edd735904add027a450db7b93d3a Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 13:36:56 +0100 Subject: [PATCH 23/70] Removed redundant whitespace --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index dd3d7871bf2450..9278852a2a3721 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -172,7 +172,6 @@ class HasDegree (Z : Type*) [Semiring Z] where -/ degree_one {X : Scheme.{u}} (z : X) : degree (𝟙 X) z = 1 - open Classical in /-- Implementation detail for pushforward: function used to define the coefficient of the pushforward From 59231531ddfe9016e7ffe3bdfa03d10202fa07ee Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 13:44:10 +0100 Subject: [PATCH 24/70] Removed whitespace and such from LocallyFinsupp.lean --- Mathlib/Topology/LocallyFinsupp.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index a98d1974549730..03916de3d2116a 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -232,7 +232,7 @@ protected def addSubmonoid [AddMonoid Y] : AddSubmonoid (X → Y) where by_contra! hCon simp_all -protected lemma memAddSubmonoid [AddMonoid Y] (D : locallyFinsuppWithin U Y) : +protected lemma memAddSubmonoid [AddMonoid Y] (D : locallyFinsuppWithin U Y) : (D : X → Y) ∈ locallyFinsuppWithin.addSubmonoid U := ⟨D.supportWithinDomain, D.supportLocallyFiniteWithinDomain⟩ @@ -245,7 +245,7 @@ protected def addSubgroup [AddGroup Y] : AddSubgroup (X → Y) where __ := locallyFinsuppWithin.addSubmonoid U neg_mem' {f} hf := by simp_all -protected lemma memAddSubgroup [AddGroup Y] (D : locallyFinsuppWithin U Y) : +protected lemma memAddSubgroup [AddGroup Y] (D : locallyFinsuppWithin U Y) : (D : X → Y) ∈ locallyFinsuppWithin.addSubgroup U := ⟨D.supportWithinDomain, D.supportLocallyFiniteWithinDomain⟩ @@ -259,7 +259,7 @@ def mk_of_mem [AddMonoid Y] (f : X → Y) (hf : f ∈ locallyFinsuppWithin.addSu instance [AddMonoid Y] : Zero (locallyFinsuppWithin U Y) where zero := mk_of_mem 0 <| zero_mem _ -instance [AddMonoid Y]: Add (locallyFinsuppWithin U Y) where +instance [AddMonoid Y] : Add (locallyFinsuppWithin U Y) where add D₁ D₂ := mk_of_mem (D₁ + D₂) <| add_mem D₁.memAddSubmonoid D₂.memAddSubmonoid instance [AddMonoid Y] : SMul ℕ (locallyFinsuppWithin U Y) where From c5bacb4c743d295b214a8548b0ae86e8c7703eb9 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 14:08:16 +0100 Subject: [PATCH 25/70] Added a codimension grading --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 9278852a2a3721..18d0e029efa613 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -72,7 +72,7 @@ structure Grading [AddMonoid Z] (N : Type*) where {c : AlgebraicCycle X Z | ∀ x ∈ c.support, dim x = d} := by aesop /-- -Subgroup of cycles of pure dimension `d`. +Submonoid of cycles of pure dimension `d`. -/ def dimensionGradingAddSubmonoid [AddMonoid Z] (d : ℕ∞) : AddSubmonoid (AlgebraicCycle X Z) where @@ -99,6 +99,34 @@ def dimensionGrading [AddMonoid Z] : Grading X Z ℕ∞ where dim := Order.height homogeneousCycles := dimensionGradingAddSubmonoid X Z +/-- +Submonoid of cycles of pure codimension `d`. +-/ +def codimensionGradingAddSubmonoid [AddMonoid Z] (d : ℕ∞) : + AddSubmonoid (AlgebraicCycle X Z) where + carrier := {c : AlgebraicCycle X Z | ∀ x ∈ c.support, coheight x = d} + add_mem' c₁ c₂ := by + rename_i a b + simp_all only [Function.mem_support, ne_eq, mem_setOf_eq, + Function.locallyFinsuppWithin.coe_add, Pi.add_apply] + intro x hx + have : ¬ a x = 0 ∨ ¬ b x = 0 := by + by_contra h + simp_all + exact Or.elim this (c₁ x) (c₂ x) + zero_mem' := by simp + +/-- +Grading on `AlgebraicCycle X Z` by codimension, where codimension of a point is defined to be the +coheight in the specialization order. Note this notion of codimension falls apart a bit outside of +contexts where there are some equidimensionality hypotheses. In these contexts, the theory of +dimension functions is more appropriate to use. +-/ +noncomputable +def codimensionGrading [AddMonoid Z] : Grading X Z ℕ∞ where + dim := Order.coheight + homogeneousCycles := codimensionGradingAddSubmonoid X Z + variable {X Z} section Zero From c39feedf8b6462599520fe36915b9b9a7221a959 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 20 Feb 2026 15:58:21 +0100 Subject: [PATCH 26/70] Updated some unfinished docstrings --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 18d0e029efa613..d551f3146aae57 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -58,15 +58,15 @@ Here we define a notion of grading defined by such a dimension/codimension funct -/ structure Grading [AddMonoid Z] (N : Type*) where /-- - The "dimension function" associated with the grading + The "dimension function" associated with the grading. -/ dim : X → N /-- - Given `d` in `N`, we have an additive submonoid of homogeneous cycles + Given `d` in `N`, we have an additive submonoid of `d`-homogeneous cycles. -/ homogeneousCycles (d : N) : AddSubmonoid (AlgebraicCycle X Z) /-- - Proof that `mon` is the + Proof that `homogeneousCycles d` is the set of `d`-homogeneous cycles. -/ homogeneousCycles_carrier (d : N) : (homogeneousCycles d).carrier = {c : AlgebraicCycle X Z | ∀ x ∈ c.support, dim x = d} := by aesop From 7f9ece447b855e9cb80de336cb63af03c7e9fa61 Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Wed, 25 Feb 2026 20:44:24 +1100 Subject: [PATCH 27/70] Update Mathlib/AlgebraicGeometry/AlgebraicCycle.lean Co-authored-by: Christian Merten --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index d551f3146aae57..289d0efe661438 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -16,7 +16,7 @@ public import Mathlib.Algebra.DirectSum.Decomposition /-! # Algebraic Cycles -In this define algebraic cycles on a scheme `X` with coefficients in a type `Z` and provide some +In this file we define algebraic cycles on a scheme `X` with coefficients in a type `Z` and provide some basic API for working with them. We define an algebraic cycle on a scheme `X` with coefficients in a type `Z` to be functions `c : X → Z` whose support is locally finite. From d86b4e7b558c00b7b62c1113c0fc5c5715477da4 Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Wed, 25 Feb 2026 20:44:37 +1100 Subject: [PATCH 28/70] Update Mathlib/AlgebraicGeometry/AlgebraicCycle.lean Co-authored-by: Christian Merten --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 289d0efe661438..5fd56e8128b2a7 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -31,12 +31,7 @@ open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace CategoryTheory universe u v -variable (R : Type*) - [CommRing R] - (i : ℕ) - (X : Scheme.{u}) - {Y : Scheme.{u}} - (Z : Type*) +variable (R : Type*) [CommRing R] (i : ℕ) (X : Scheme.{u}) {Y : Scheme.{u}} (Z : Type*) /-- Algebraic cycle on a scheme `X` with coefficients in a type `Z` is just a function from `X` to `Z` From 035c26fa7e03b18d516d3bd231873d8377d2cb99 Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Wed, 25 Feb 2026 20:51:02 +1100 Subject: [PATCH 29/70] Update Mathlib/AlgebraicGeometry/AlgebraicCycle.lean Co-authored-by: Christian Merten --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 5fd56e8128b2a7..aa978573c085cf 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -72,8 +72,7 @@ Submonoid of cycles of pure dimension `d`. def dimensionGradingAddSubmonoid [AddMonoid Z] (d : ℕ∞) : AddSubmonoid (AlgebraicCycle X Z) where carrier := {c : AlgebraicCycle X Z | ∀ x ∈ c.support, height x = d} - add_mem' c₁ c₂ := by - rename_i a b + add_mem' {a} b c₁ c₂ := by simp_all only [Function.mem_support, ne_eq, mem_setOf_eq, Function.locallyFinsuppWithin.coe_add, Pi.add_apply] intro x hx From 7cce42c4a11f6fadb89ccd21e04c9840050c4208 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 26 Feb 2026 13:24:50 +0100 Subject: [PATCH 30/70] Changed the name of the type of coefficients from Z to R --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 56 +++++++++---------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index aa978573c085cf..e3ea4001869633 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -16,9 +16,9 @@ public import Mathlib.Algebra.DirectSum.Decomposition /-! # Algebraic Cycles -In this file we define algebraic cycles on a scheme `X` with coefficients in a type `Z` and provide some -basic API for working with them. We define an algebraic cycle on a scheme `X` with coefficients -in a type `Z` to be functions `c : X → Z` whose support is locally finite. +In this file we define algebraic cycles on a scheme `X` with coefficients in a type `R` and provide +some basic API for working with them. We define an algebraic cycle on a scheme `X` with +coefficients in a type `R` to be functions `c : X → R` whose support is locally finite. Here we're making use of the equivalence between irreducible closed subsets of a scheme and their generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly @@ -31,7 +31,7 @@ open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace CategoryTheory universe u v -variable (R : Type*) [CommRing R] (i : ℕ) (X : Scheme.{u}) {Y : Scheme.{u}} (Z : Type*) +variable (X : Scheme.{u}) {Y : Scheme.{u}} (R : Type*) /-- Algebraic cycle on a scheme `X` with coefficients in a type `Z` is just a function from `X` to `Z` @@ -41,8 +41,8 @@ Here we're making use of the equivalence between irreducible closed subsets of a generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly nonstandard definition. -/ -abbrev AlgebraicCycle (X : Scheme.{u}) (Z : Type*) [Zero Z] := - Function.locallyFinsupp X Z +abbrev AlgebraicCycle (X : Scheme.{u}) (R : Type*) [Zero R] := + Function.locallyFinsupp X R namespace AlgebraicCycle @@ -51,7 +51,7 @@ In the context of algebraic cycles, gradings tend to be defined using functions the components of the cycles (mainly different notions of dimension and codimension). Here we define a notion of grading defined by such a dimension/codimension function. -/ -structure Grading [AddMonoid Z] (N : Type*) where +structure Grading [AddMonoid R] (N : Type*) where /-- The "dimension function" associated with the grading. -/ @@ -59,19 +59,19 @@ structure Grading [AddMonoid Z] (N : Type*) where /-- Given `d` in `N`, we have an additive submonoid of `d`-homogeneous cycles. -/ - homogeneousCycles (d : N) : AddSubmonoid (AlgebraicCycle X Z) + homogeneousCycles (d : N) : AddSubmonoid (AlgebraicCycle X R) /-- Proof that `homogeneousCycles d` is the set of `d`-homogeneous cycles. -/ homogeneousCycles_carrier (d : N) : (homogeneousCycles d).carrier = - {c : AlgebraicCycle X Z | ∀ x ∈ c.support, dim x = d} := by aesop + {c : AlgebraicCycle X R | ∀ x ∈ c.support, dim x = d} := by aesop /-- Submonoid of cycles of pure dimension `d`. -/ -def dimensionGradingAddSubmonoid [AddMonoid Z] (d : ℕ∞) : - AddSubmonoid (AlgebraicCycle X Z) where - carrier := {c : AlgebraicCycle X Z | ∀ x ∈ c.support, height x = d} +def dimensionGradingAddSubmonoid [AddMonoid R] (d : ℕ∞) : + AddSubmonoid (AlgebraicCycle X R) where + carrier := {c : AlgebraicCycle X R | ∀ x ∈ c.support, height x = d} add_mem' {a} b c₁ c₂ := by simp_all only [Function.mem_support, ne_eq, mem_setOf_eq, Function.locallyFinsuppWithin.coe_add, Pi.add_apply] @@ -89,16 +89,16 @@ contexts where there are some equidimensionality hypotheses. In these contexts, dimension functions is more appropriate to use. -/ noncomputable -def dimensionGrading [AddMonoid Z] : Grading X Z ℕ∞ where +def dimensionGrading [AddMonoid R] : Grading X R ℕ∞ where dim := Order.height - homogeneousCycles := dimensionGradingAddSubmonoid X Z + homogeneousCycles := dimensionGradingAddSubmonoid X R /-- Submonoid of cycles of pure codimension `d`. -/ -def codimensionGradingAddSubmonoid [AddMonoid Z] (d : ℕ∞) : - AddSubmonoid (AlgebraicCycle X Z) where - carrier := {c : AlgebraicCycle X Z | ∀ x ∈ c.support, coheight x = d} +def codimensionGradingAddSubmonoid [AddMonoid R] (d : ℕ∞) : + AddSubmonoid (AlgebraicCycle X R) where + carrier := {c : AlgebraicCycle X R | ∀ x ∈ c.support, coheight x = d} add_mem' c₁ c₂ := by rename_i a b simp_all only [Function.mem_support, ne_eq, mem_setOf_eq, @@ -117,25 +117,21 @@ contexts where there are some equidimensionality hypotheses. In these contexts, dimension functions is more appropriate to use. -/ noncomputable -def codimensionGrading [AddMonoid Z] : Grading X Z ℕ∞ where +def codimensionGrading [AddMonoid R] : Grading X R ℕ∞ where dim := Order.coheight - homogeneousCycles := codimensionGradingAddSubmonoid X Z + homogeneousCycles := codimensionGradingAddSubmonoid X R -variable {X Z} +variable {X R} section Zero -variable (f : X ⟶ Y) - [Zero Z] - (c : AlgebraicCycle X Z) - (x : X) - (z : Y) +variable (f : X ⟶ Y) [Zero R] (c : AlgebraicCycle X R) (x : X) (z : Y) /-- The cycle containing a single point with a chosen coefficient -/ noncomputable -def single (coeff : Z) : AlgebraicCycle X Z where +def single (coeff : R) : AlgebraicCycle X R where toFun := Set.indicator {x} (Function.const X coeff) supportWithinDomain' := by simp only [support_indicator]; exact LE.le.subset fun _ a_1 ↦ trivial supportLocallyFiniteWithinDomain' z hz := @@ -143,7 +139,7 @@ def single (coeff : Z) : AlgebraicCycle X Z where /-- Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage -of a point z : Y along a morphism f : X ⟶ Y. +of a point z : Y along a morphism `f : X ⟶ Y`. -/ def preimageSupport : Set X := f.base ⁻¹' {z} ∩ c.support @@ -200,9 +196,9 @@ Implementation detail for pushforward: function used to define the coefficient o of a cycle `c` at a point `z = f x`, as in stacks `02R3`. -/ noncomputable -def mapAux {N : Type*} [Semiring Z] [HasDegree Z] {Y : Scheme} - (gx : Grading X Z N) (gy : Grading Y Z N) - (f : X ⟶ Y) (x : X) : Z := +def mapAux {N : Type*} [Semiring R] [HasDegree R] {Y : Scheme} + (gx : Grading X R N) (gy : Grading Y R N) + (f : X ⟶ Y) (x : X) : R := if gx.dim x = gy.dim (f.base x) then HasDegree.degree f x else 0 section map From 87f665cec0af697386dc8a42837b0803dc659b71 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 26 Feb 2026 13:46:24 +0100 Subject: [PATCH 31/70] Changed gradings to just be functions without bundling anything --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 73 ++++++------------- 1 file changed, 24 insertions(+), 49 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index e3ea4001869633..9267b4c75d2e36 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -51,20 +51,16 @@ In the context of algebraic cycles, gradings tend to be defined using functions the components of the cycles (mainly different notions of dimension and codimension). Here we define a notion of grading defined by such a dimension/codimension function. -/ -structure Grading [AddMonoid R] (N : Type*) where - /-- - The "dimension function" associated with the grading. - -/ - dim : X → N - /-- - Given `d` in `N`, we have an additive submonoid of `d`-homogeneous cycles. - -/ - homogeneousCycles (d : N) : AddSubmonoid (AlgebraicCycle X R) - /-- - Proof that `homogeneousCycles d` is the set of `d`-homogeneous cycles. - -/ - homogeneousCycles_carrier (d : N) : (homogeneousCycles d).carrier = - {c : AlgebraicCycle X R | ∀ x ∈ c.support, dim x = d} := by aesop +def Grading (N : Type*) := X → N + +variable {X} in +def Grading.homogeneousCycles {N : Type*} (G : Grading X N) (R : Type*) [AddMonoid R] (d : N) : + AddSubmonoid (AlgebraicCycle X R) where + carrier := { c | ∀ x ∈ c.support, G x = d } + add_mem' {c₁} c₂ hc₁ hc₂ := by + simp at hc₁ hc₂ ⊢ + grind + zero_mem' := by simp /-- Submonoid of cycles of pure dimension `d`. @@ -89,26 +85,7 @@ contexts where there are some equidimensionality hypotheses. In these contexts, dimension functions is more appropriate to use. -/ noncomputable -def dimensionGrading [AddMonoid R] : Grading X R ℕ∞ where - dim := Order.height - homogeneousCycles := dimensionGradingAddSubmonoid X R - -/-- -Submonoid of cycles of pure codimension `d`. --/ -def codimensionGradingAddSubmonoid [AddMonoid R] (d : ℕ∞) : - AddSubmonoid (AlgebraicCycle X R) where - carrier := {c : AlgebraicCycle X R | ∀ x ∈ c.support, coheight x = d} - add_mem' c₁ c₂ := by - rename_i a b - simp_all only [Function.mem_support, ne_eq, mem_setOf_eq, - Function.locallyFinsuppWithin.coe_add, Pi.add_apply] - intro x hx - have : ¬ a x = 0 ∨ ¬ b x = 0 := by - by_contra h - simp_all - exact Or.elim this (c₁ x) (c₂ x) - zero_mem' := by simp +def dimensionGrading : Grading X ℕ∞ := Order.height /-- Grading on `AlgebraicCycle X Z` by codimension, where codimension of a point is defined to be the @@ -117,9 +94,7 @@ contexts where there are some equidimensionality hypotheses. In these contexts, dimension functions is more appropriate to use. -/ noncomputable -def codimensionGrading [AddMonoid R] : Grading X R ℕ∞ where - dim := Order.coheight - homogeneousCycles := codimensionGradingAddSubmonoid X R +def codimensionGrading : Grading X ℕ∞ := Order.coheight variable {X R} @@ -197,14 +172,14 @@ of a cycle `c` at a point `z = f x`, as in stacks `02R3`. -/ noncomputable def mapAux {N : Type*} [Semiring R] [HasDegree R] {Y : Scheme} - (gx : Grading X R N) (gy : Grading Y R N) + (gx : Grading X N) (gy : Grading Y N) (f : X ⟶ Y) (x : X) : R := - if gx.dim x = gy.dim (f.base x) then HasDegree.degree f x else 0 + if gx x = gy (f.base x) then HasDegree.degree f x else 0 section map -variable {Z : Type*} [Semiring Z] {W : Y.Opens} (hW : IsAffineOpen W) - (f : X ⟶ Y) (c : AlgebraicCycle X Z) +variable [Semiring R] {W : Y.Opens} (hW : IsAffineOpen W) + (f : X ⟶ Y) (c : AlgebraicCycle X R) lemma preimageSupport_inter_subset : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by @@ -257,12 +232,12 @@ lemma inter_nonempty_finite (hW : IsAffineOpen W) exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ exact iUnion_preimage_inter_support_finite_of_isAffineOpen f c hW -variable {N : Type*} [HasDegree Z] +variable {N : Type*} [HasDegree R] /-- The pushforward of an algebraic cycle has locally finite support. -/ -lemma map_locally_finite (gx : Grading X Z N) (gy : Grading Y Z N) : +lemma map_locally_finite (gx : Grading X N) (gy : Grading Y N) : ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ ∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux gx gy f x).Finite := by intro y @@ -288,7 +263,7 @@ Note that usually the pushforward is only defined for proper morphisms, and inde properness to prove that the pushforward preserves rational equivalence. -/ noncomputable -def map (gx : Grading X Z N) (gy : Grading Y Z N) : AlgebraicCycle Y Z +def map (gx : Grading X N) (gy : Grading Y N) : AlgebraicCycle Y R where toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux gx gy f x) supportWithinDomain' := by simp @@ -297,10 +272,10 @@ def map (gx : Grading X Z N) (gy : Grading Y Z N) : AlgebraicCycle Y Z /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ -lemma map_homogeneneous {d : ℕ∞} (c : AlgebraicCycle X Z) - (hc : c ∈ (dimensionGrading X Z).homogeneousCycles d) : - map f c (dimensionGrading X Z) (dimensionGrading Y Z) ∈ - (dimensionGrading Y Z).homogeneousCycles d := by +lemma map_homogeneneous {d : ℕ∞} (c : AlgebraicCycle X R) + (hc : c ∈ (dimensionGrading X).homogeneousCycles R d) : + map f c (dimensionGrading X) (dimensionGrading Y) ∈ + (dimensionGrading Y).homogeneousCycles R d := by simp only [dimensionGrading] intro y hy simp only [map, preimageSupport, mapAux, mul_ite, mul_zero, Function.mem_support, @@ -315,7 +290,7 @@ lemma map_homogeneneous {d : ℕ∞} (c : AlgebraicCycle X Z) The pushforward of `c` along the identity morphism is `c`. -/ @[simp] -lemma map_id (g : Grading X Z N) : map (𝟙 X) c g g = c := by +lemma map_id (g : Grading X N) : map (𝟙 X) c g g = c := by ext z have : (c z ≠ 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = {z}) ∨ (c z = 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = ∅) := by From 90607495142dd19fd030e738c3ba90f362e3e0f9 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 26 Feb 2026 14:23:28 +0100 Subject: [PATCH 32/70] Added in a docstring for gradings --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean index 9267b4c75d2e36..47c9484e99d050 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean @@ -54,9 +54,13 @@ Here we define a notion of grading defined by such a dimension/codimension funct def Grading (N : Type*) := X → N variable {X} in -def Grading.homogeneousCycles {N : Type*} (G : Grading X N) (R : Type*) [AddMonoid R] (d : N) : +/-- +Given an addivive monoid `R`, a grading function `G` from `X` to `N`, and `d` in `N`, +we have an additive submonoid of `d`-homogeneous cycles with coefficients in `R`. +-/ +def Grading.homogeneousCycles {N : Type*} (g : Grading X N) (R : Type*) [AddMonoid R] (d : N) : AddSubmonoid (AlgebraicCycle X R) where - carrier := { c | ∀ x ∈ c.support, G x = d } + carrier := { c | ∀ x ∈ c.support, g x = d } add_mem' {c₁} c₂ hc₁ hc₂ := by simp at hc₁ hc₂ ⊢ grind From 8687db795f0d7724935f5d1e768f23e1318eb703 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 19 Mar 2026 14:28:40 +0100 Subject: [PATCH 33/70] WIP --- .../AlgebraicGeometry/AlgebraicCycle'.lean | 215 ++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean new file mode 100644 index 00000000000000..446a80f7306205 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean @@ -0,0 +1,215 @@ +/- +Copyright (c) 2025 Raphael Douglas Giles. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Raphael Douglas Giles +-/ +module + +public import Mathlib.AlgebraicGeometry.Fiber +public import Mathlib.AlgebraicGeometry.Morphisms.Proper +public import Mathlib.Combinatorics.Quiver.ReflQuiver +public import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition +public import Mathlib.Topology.LocallyFinsupp +public import Mathlib.Algebra.GradedMonoid +public import Mathlib.Algebra.DirectSum.Decomposition + +/-! +# Algebraic Cycles + +In this file we define algebraic cycles on a scheme `X` with coefficients in a type `R` and provide +some basic API for working with them. We define an algebraic cycle on a scheme `X` with +coefficients in a type `R` to be functions `c : X → R` whose support is locally finite. + +Here we're making use of the equivalence between irreducible closed subsets of a scheme and their +generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly +nonstandard definition. +-/ + +@[expose] public section + +open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace + CategoryTheory + +universe u v +variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] [PrespectralSpace X] + [PrespectralSpace Y] [QuasiSober X] [QuasiSober Y] [T0Space X] [T0Space Y] + {f : X → Y} (hf : IsSpectralMap f) (w : X → R) + +namespace Function +namespace locallyFinsupp + +section Zero +variable [Zero R] +/-- +The cycle containing a single point with a chosen coefficient +-/ +noncomputable +def single (x : X) (coeff : R) : Function.locallyFinsupp X R where + toFun := Set.indicator {x} (Function.const X coeff) + supportWithinDomain' := by simp only [support_indicator]; exact LE.le.subset fun _ a_1 ↦ trivial + supportLocallyFiniteWithinDomain' z hz := + ⟨⊤, ⟨Filter.univ_mem' fun a ↦ trivial, by simp [← Function.const_def, toFinite]⟩⟩ + +variable (f) in +/-- +Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage +of a point z : Y along a morphism `f : X ⟶ Y`. +-/ +def preimageSupport (c : locallyFinsupp X R) (z : Y) : Set X := + f ⁻¹' {z} ∩ c.support + +/-- +Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage +of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. +-/ +lemma preimageSupport_finite (c : locallyFinsupp X R) (hf : IsSpectralMap f) (z : Y) : + (preimageSupport f c z).Finite := by + + sorry + + +end Zero + + +section map + +variable [Semiring R] {W : TopologicalSpace.Opens Y} (hW : IsCompact W.1) + (c : Function.locallyFinsupp X R) + +lemma preimageSupport_inter_subset : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ + f '' (f ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by + intro a ha + rw [image_preimage_inter] + suffices a ∈ f '' c.support from mem_inter ha this + have := ha.2.some_mem + simp only [preimageSupport, mem_inter_iff, mem_preimage, mem_singleton_iff, + Function.mem_support, ne_eq, mem_image] at this ⊢ + exact ⟨ha.2.some, this.symm⟩ + +lemma preimageSupport_preimage_inter_subset : f ⁻¹' W.carrier ∩ + f ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ + f ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by + intro p hp + simp only [Opens.carrier_eq_coe, preimageSupport, preimage_setOf_eq, mem_inter_iff, + mem_preimage, SetLike.mem_coe, mem_setOf_eq, Function.mem_support, ne_eq, mem_iUnion, + mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ + exact ⟨hp.1.1, hp.2⟩ + +--variable [qc : QuasiCompact f] + +lemma preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) (hW : IsCompact W.1) : + (f ⁻¹' W.carrier ∩ c.support).Finite := + LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| + hf.2 W.is_open' hW + +lemma iUnion_preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) (hW : IsCompact W.1) : + (⋃ _ : Y, f ⁻¹' W.carrier ∩ c.support).Finite := by + suffices (f ⁻¹' W.carrier ∩ c.support).Finite by + apply Finite.subset this + intro a ha + simp only [Opens.carrier_eq_coe, mem_iUnion, mem_inter_iff, mem_preimage, + SetLike.mem_coe, Function.mem_support, ne_eq, exists_and_left, exists_const_iff] at ha ⊢ + exact ⟨ha.1, ha.2.2⟩ + exact preimage_inter_support_finite_of_isAffineOpen c hf hW + +lemma inter_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) + : (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite := by + refine Finite.subset (Finite.image _ ?_) (preimageSupport_inter_subset c) + rw[preimage_inter] + apply Finite.subset _ (preimageSupport_preimage_inter_subset c) + rw[inter_iUnion] + suffices (⋃ i : Y, f ⁻¹' W.carrier ∩ c.support).Finite by + apply Finite.subset this + simp only [Opens.carrier_eq_coe, iUnion_subset_iff] + intro y x hx + simp only [mem_inter_iff, mem_preimage, SetLike.mem_coe, + Function.mem_support, ne_eq, mem_iUnion, exists_and_left, exists_const_iff] at hx ⊢ + exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ + exact iUnion_preimage_inter_support_finite_of_isAffineOpen c hf hW + +variable {N : Type*} + +/-- +The pushforward of an algebraic cycle has locally finite support. +-/ +lemma map_locally_finite : + ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ + ∑ x ∈ (preimageSupport_finite c hf z).toFinset, (c x) * w x).Finite := by + intro y + have : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := sorry + obtain ⟨W, hW⟩ := this + --obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by simp) + use W + refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ + suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by + apply Finite.subset this + apply inter_subset_inter Set.Subset.rfl + intro x + simp only [Function.mem_support, ne_eq, mem_setOf_eq] + contrapose! + intro aux + rw [Finset.sum_eq_zero] + intro x hx + simp_all + exact inter_nonempty_finite c hf hW.1 + +variable (f) in +/-- +The pushforward of an algebraic cycle by a quasicompact morphism. + +Note that usually the pushforward is only defined for proper morphisms, and indeed we will need +properness to prove that the pushforward preserves rational equivalence. +-/ +noncomputable +def map : Function.locallyFinsupp Y R + where + toFun z := (∑ x ∈ (preimageSupport_finite c hf z).toFinset, (c x) * w x) + supportWithinDomain' := by simp + supportLocallyFiniteWithinDomain' z _ := map_locally_finite hf w c z + +/-- +Pushforward preserves cycles of pure dimension `d` in the dimension grading. +-/ +lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) + (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : + (map f hf w c).support ⊆ t:= by + intro y hy + simp only [map, preimageSupport, Function.mem_support, + ne_eq] at hy + obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy + simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, + Function.mem_support, ne_eq] at hx + specialize h x (hc hx.1.2) + grind + + +/-- +The pushforward of `c` along the identity morphism is `c`. +-/ +@[simp] +lemma map_id (hw : ∀ z : X, w z = 1) : map id isSpectralMap_id w c = c := by + ext z + have : (c z ≠ 0 ∧ (preimageSupport_finite c isSpectralMap_id z).toFinset = {z}) ∨ + (c z = 0 ∧ (preimageSupport_finite c isSpectralMap_id z).toFinset = ∅) := by + simp only [ne_eq, Finite.toFinset, preimageSupport, preimage_id_eq, id_eq, toFinset_eq_empty, + singleton_inter_eq_empty, + Function.mem_support, not_not, and_self] + refine Or.elim (em (c z = 0)) (fun o ↦ Or.inr o) (fun o ↦ Or.inl ⟨o, Finset.ext (fun a ↦ ?_)⟩) + simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, + Finset.mem_singleton, and_iff_left_iff_imp] + rintro rfl + assumption + suffices (map id isSpectralMap_id w c).toFun z = c.toFun z from this + obtain h | h := this + all_goals simp only [map] + rw[h.2] + simp only [Finset.sum_singleton, Finset.sum_empty] + · specialize hw z + rw [hw] + exact MulOneClass.mul_one (c z) + · exact h.1.symm + +end map + +end locallyFinsupp +end Function From 12e77e5e6d68ef2ee72ba5c14a41d2c4b00d29f0 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Wed, 25 Mar 2026 16:18:57 +0100 Subject: [PATCH 34/70] Added in some stuff about Locally Spectral spaces, still very much WIP --- .claude/worktrees/trusting-mendeleev | 1 + Mathlib/AlgebraicGeometry/AITEST.lean | 262 ++++++++++++++++++ .../AlgebraicGeometry/AlgebraicCycle'.lean | 12 +- 3 files changed, 274 insertions(+), 1 deletion(-) create mode 160000 .claude/worktrees/trusting-mendeleev create mode 100644 Mathlib/AlgebraicGeometry/AITEST.lean diff --git a/.claude/worktrees/trusting-mendeleev b/.claude/worktrees/trusting-mendeleev new file mode 160000 index 00000000000000..6a41af9938d48f --- /dev/null +++ b/.claude/worktrees/trusting-mendeleev @@ -0,0 +1 @@ +Subproject commit 6a41af9938d48fb9dffefebd4f03584ce964384c diff --git a/Mathlib/AlgebraicGeometry/AITEST.lean b/Mathlib/AlgebraicGeometry/AITEST.lean new file mode 100644 index 00000000000000..0f3731700af6a0 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/AITEST.lean @@ -0,0 +1,262 @@ +import Mathlib.Topology.Spectral.ConstructibleTopology +import Mathlib.Topology.Order + +instance {X : Type*} [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] : + T2Space (WithConstructibleTopology X) where + t2 x y hxy := by + wlog h : ∃ U : Set X, IsOpen U ∧ x ∈ U ∧ y ∉ U + · obtain ⟨U, hUo, ⟨hxU, hyU⟩ | ⟨hyU, hxU⟩⟩ := exists_isOpen_xor'_mem (X := X) hxy + · exact this _ _ hxy ⟨U, hUo, hxU, hyU⟩ + · obtain ⟨u, v, h1, h2, h3, h4, h5⟩ := this y x hxy.symm ⟨U, hUo, hyU, hxU⟩ + exact ⟨v, u, h2, h1, h4, h3, h5.symm⟩ + obtain ⟨U, hUo, ⟨hxU, hyU⟩⟩ := h + obtain ⟨V, ⟨hVo, hVc⟩, hxV, hVU⟩ := + PrespectralSpace.isTopologicalBasis (X := X) |>.exists_subset_of_mem_open hxU hUo + exact ⟨V, Vᶜ, hVc.isOpen_constructibleTopology_of_isOpen hVo, + (compl_compl V ▸ hVc).isOpen_constructibleTopology_of_isClosed hVo.isClosed_compl, + hxV, fun hyV => hyU (hVU hyV), disjoint_compl_right⟩ + +namespace WithConstructibleTopology + +@[match_pattern] def toEquiv {α : Type*} [TopologicalSpace α] : α ≃ WithConstructibleTopology α := + Equiv.refl _ + +@[match_pattern] def ofEquiv {α : Type*} [TopologicalSpace α] : WithConstructibleTopology α ≃ α := + Equiv.refl _ + +lemma ofEquiv_continuous {X : Type*} [TopologicalSpace X] [a : PrespectralSpace X] : + Continuous (ofEquiv (α := X)) := by + have := a.1 + constructor + intro U hU + have := (TopologicalSpace.IsTopologicalBasis.isOpen_iff this).mp hU + let Ux (x : U) := Exists.choose (this x x.2) + let V := ⋃ (x : U), Ux x + have opV : IsOpen V := by + apply isOpen_iUnion + intro x + exact (Exists.choose_spec (this x x.2)).1.1 + have vu : V = U := by + apply le_antisymm + · exact Set.iUnion_subset fun x => (Exists.choose_spec (this x x.2)).2.2 + · intro z hz + exact Set.mem_iUnion.mpr ⟨⟨z, hz⟩, (Exists.choose_spec (this z hz)).2.1⟩ + rw [← vu] + dsimp [V] + simp only [Set.iUnion_coe_set, Set.preimage_iUnion] + apply isOpen_iUnion + intro x + apply isOpen_iUnion + intro hx + have := Exists.choose_spec (this x hx) + dsimp [Ux] + apply IsCompact.isOpen_constructibleTopology_of_isOpen this.1.2 this.1.1 + +def lift {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] (f : X → Y) : + WithConstructibleTopology X → WithConstructibleTopology Y := toEquiv.toFun ∘ f ∘ toEquiv.invFun + +lemma lift_continuous {X Y : Type*} + [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] + [TopologicalSpace Y] [T0Space Y] [QuasiSober Y] [PrespectralSpace Y] + (f : SpectralMap X Y) : Continuous (lift f) := by + erw [continuous_generateFrom_iff] + intro U hU + simp only [constructibleTopologySubbasis] at hU + obtain h | h := hU + · have a := f.2.2 h.1 h.2 + have b := f.2.1.1 U h.1 + have := IsCompact.isOpen_constructibleTopology_of_isOpen a b + convert this + · expose_names + have o : @IsOpen Y inst_4 (U)ᶜ := by simp_all + have a := f.2.2 o h.2 + have : IsClosed (f.toFun ⁻¹' U) := IsClosed.preimage f.2.1 h.1 + convert IsCompact.isOpen_constructibleTopology_of_isClosed a this using 1 + +lemma isCompact_of_preimage_singleton {X Y : Type*} + [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] + [CompactSpace X] [QuasiSeparatedSpace X] + [TopologicalSpace Y] [T0Space Y] [QuasiSober Y] [PrespectralSpace Y] + (f : X → Y) (hf : IsSpectralMap f) (y : Y) : + IsCompact (f ⁻¹' {y}) := by + convert + ((isClosed_singleton).preimage (lift_continuous ⟨f, hf⟩)).isCompact.image ofEquiv_continuous + aesop + +end WithConstructibleTopology + +class IsLocallySpectral (X : Type*) [TopologicalSpace X] [T0Space X] [QuasiSober X] + [PrespectralSpace X] : Prop where + exists_spectral_nhd' (x : X) : ∃ U : Set X, IsOpen U ∧ IsCompact U ∧ QuasiSeparatedSpace U ∧ x ∈ U + +variable {X : Type*} [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] + +lemma IsLocallySpectral.exists_spectral_nhd [q : IsLocallySpectral X] (x : X) : + ∃ U : Set X, IsOpen U ∧ IsCompact U ∧ QuasiSeparatedSpace U ∧ x ∈ U := q.exists_spectral_nhd' x + +variable {Y : Type*} [TopologicalSpace Y] [T0Space Y] [QuasiSober Y] [PrespectralSpace Y] + [IsLocallySpectral Y] + +/- +lemma zsjdhh {X : Type*} [TopologicalSpace X] (U V : Set X) + (hU : IsQuasiSeparated U) (hV : IsOpen V) (hV' : IsCompact V) : IsQuasiSeparated (U ∩ V) := by + + sorry-/ + +open Topology +lemma IsSpectralMap.of_openEmbedding {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] + [CompactSpace X] [QuasiSeparatedSpace Y] {f : X → Y} (hf : IsOpenEmbedding f) : + IsSpectralMap f := by + constructor + · exact hf.continuous + · intro U hU hU' + have : IsCompact (U ∩ (Set.range f)) := by + have : IsCompact (Set.range f) := by + convert CompactSpace.isCompact_univ.image hf.continuous + exact Set.image_univ.symm + /- + Suppose we only know that f '' ⊤ is quasiseparated. Then we wish to know if f '' ⊤ ∩ + -/ + apply IsCompact.inter_of_isOpen hU' this hU hf.isOpen_range + have := hf.isCompact_preimage' this (by simp) + convert this using 1 + exact Set.preimage_inter_range.symm +open Set + + +variable [IsLocallySpectral X] + +/-- +A finite union of quasi-separated compact opens is quasi-separated, provided the pairwise +intersections are compact (and compact opens form a topological basis). + +This is the topological analogue of Stacks Project Tag 01KS. The key step is showing that +if `W` is compact open with `W ⊆ ⋃ i, f i`, then `W ∩ f k` is compact. This uses the +`PrespectralSpace` hypothesis: we cover `W` by basis compact opens, each contained in some +`f j`, extract a finite subcover by compactness of `W`, and then each piece intersected +with `f k` is compact by quasi-separatedness of `f j`. +-/ +lemma testing {X : Type*} [TopologicalSpace X] [PrespectralSpace X] + {ι : Type*} {f : ι → Set X} [Finite ι] + (h : ∀ (i : ι), IsOpen (f i) ∧ IsQuasiSeparated (f i) ∧ IsCompact (f i)) + (hpair : ∀ i j, IsCompact (f i ∩ f j)) : + IsQuasiSeparated (⋃ i, f i) := by + intro U V hUsub hUo hUc hVsub hVo hVc + -- Key claim: for W compact open ⊆ ⋃ f i, W ∩ f k is compact + suffices key : ∀ (W : Set X), W ⊆ ⋃ i, f i → IsOpen W → IsCompact W → + ∀ k, IsCompact (W ∩ f k) by + -- Decompose U ∩ V = ⋃ i, (U ∩ f i) ∩ (V ∩ f i) + have cover : U ∩ V = ⋃ i, (U ∩ V ∩ f i) := by + rw [← Set.inter_iUnion, Set.inter_eq_left.mpr (inter_subset_left.trans hUsub)] + rw [cover] + apply isCompact_iUnion; intro i + have : U ∩ V ∩ f i = (U ∩ f i) ∩ (V ∩ f i) := by tauto_set + rw [this] + exact (h i).2.1 _ _ inter_subset_right (hUo.inter (h i).1) (key U hUsub hUo hUc i) + inter_subset_right (hVo.inter (h i).1) (key V hVsub hVo hVc i) + -- Prove the key claim + intro W hWsub hWo hWc k + have basis := PrespectralSpace.isTopologicalBasis (X := X) + -- For each x ∈ W, find j(x) and a basis compact open B(x) ⊆ W ∩ f(j(x)) + have hx_data : ∀ x : ↥W, ∃ j : ι, ∃ B : Set X, + IsOpen B ∧ IsCompact B ∧ x.1 ∈ B ∧ B ⊆ W ∧ B ⊆ f j := by + intro ⟨x, hxW⟩ + obtain ⟨j, hxfj⟩ := mem_iUnion.mp (hWsub hxW) + obtain ⟨B, ⟨hBo, hBc⟩, hxB, hBsub⟩ := + basis.exists_subset_of_mem_open (show x ∈ W ∩ f j from ⟨hxW, hxfj⟩) (hWo.inter (h j).1) + exact ⟨j, B, hBo, hBc, hxB, hBsub.trans inter_subset_left, hBsub.trans inter_subset_right⟩ + choose j B hBo hBc hxB hBW hBf using hx_data + -- Extract finite subcover from compactness of W + obtain ⟨t, ht⟩ := hWc.elim_finite_subcover B (fun x => hBo x) + (fun x hx => mem_iUnion.mpr ⟨⟨x, hx⟩, hxB ⟨x, hx⟩⟩) + -- W ∩ f k = ⋃ x ∈ t, (B x ∩ f k) since each B x ⊆ W + have eq : W ∩ f k = ⋃ x ∈ (t : Set ↥W), (B x ∩ f k) := by + ext z; simp only [mem_inter_iff, mem_iUnion, Finset.mem_coe]; constructor + · intro ⟨hzW, hzfk⟩ + obtain ⟨x, hxt, hzBx⟩ := mem_iUnion₂.mp (ht hzW) + exact ⟨x, hxt, hzBx, hzfk⟩ + · rintro ⟨x, _, hzBx, hzfk⟩ + exact ⟨hBW x hzBx, hzfk⟩ + rw [eq] + -- Finite union of compact sets is compact + exact t.finite_toSet.isCompact_biUnion fun x _ => by + -- B x ∩ f k is compact: use QS of f(j x) with B x and f k ∩ f(j x) + have h_qs := (h (j x)).2.1 (B x) (f k ∩ f (j x)) + (hBf x) (hBo x) (hBc x) + inter_subset_right ((h k).1.inter (h (j x)).1) (hpair k (j x)) + -- B x ∩ (f k ∩ f(j x)) = B x ∩ f k since B x ⊆ f(j x) + rwa [← Set.inter_assoc, inter_eq_left.mpr (inter_subset_left.trans (hBf x))] at h_qs + +lemma IsLocallySpectral.fiber (f : X → Y) (hf : IsSpectralMap f) (y : Y) : + f ⁻¹' {y} = ⋂ s ∈ {x ∈ 𝓝 y | IsOpen x ∧ IsCompact x}, f ⁻¹' s := sorry + +lemma IsLocallySpectral.isCompact_of_preimage_singleton (f : X → Y) (hf : IsSpectralMap f) (y : Y) : + IsCompact (f ⁻¹' {y}) := by + obtain ⟨U, hU⟩ := IsLocallySpectral.exists_spectral_nhd y + -- Step 1: Get a spectral neighborhood U of y in Y + obtain ⟨U, hUo, hUc, hUqs, hyU⟩ := IsLocallySpectral.exists_spectral_nhd y + -- Step 2: f⁻¹(U) is compact and open + have hfUc : IsCompact (f ⁻¹' U) := hf.isCompact_preimage_of_isOpen hUo hUc + have hfUo : IsOpen (f ⁻¹' U) := hUo.preimage hf.continuous + -- Step 3: Set up typeclass instances on f⁻¹(U) and U + have oe_fU := hfUo.isOpenEmbedding_subtypeVal + have oe_U := hUo.isOpenEmbedding_subtypeVal + haveI : CompactSpace ↥(f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc + haveI : T0Space ↥(f ⁻¹' U) := oe_fU.isEmbedding.t0Space + haveI : QuasiSober ↥(f ⁻¹' U) := oe_fU.quasiSober + haveI : PrespectralSpace ↥(f ⁻¹' U) := oe_fU.prespectralSpace + haveI : T0Space ↥U := oe_U.isEmbedding.t0Space + haveI : QuasiSober ↥U := oe_U.quasiSober + haveI : PrespectralSpace ↥U := oe_U.prespectralSpace + -- KEY SORRY: need f⁻¹(U) quasi-separated for compactSpace_withConstructibleTopology. + -- For schemes this follows from the morphism being quasi-separated. + haveI : QuasiSeparatedSpace ↥(f ⁻¹' U) := + /- + `f ⁻¹ U` is covered by spectral opens since it is locally spectral - we just take the cover + indexed by all the points in `f ⁻¹ U` + + Hence, we must have that `f ⁻¹ U` is covered by a finite number of quasiseparated sets, + and hence must itself be quasiseparated. + -/ + + + sorry + -- Step 4: Define the restriction g : f⁻¹(U) → U and show it is spectral + let g : ↥(f ⁻¹' U) → ↥U := fun x => ⟨f x.val, x.prop⟩ + have hgc : Continuous g := + Continuous.subtype_mk (hf.continuous.comp continuous_subtype_val) _ + have hg : IsSpectralMap g := by + refine ⟨hgc, fun S hSo hSc => ?_⟩ + -- S is a compact open of ↥U, hence corresponds to a compact open of Y contained in U + have hSo' : IsOpen (Subtype.val '' S : Set Y) := oe_U.isOpenMap _ hSo + have hSc' : IsCompact (Subtype.val '' S : Set Y) := hSc.image continuous_subtype_val + -- f⁻¹(S') is compact since f is spectral + have hK : IsCompact (f ⁻¹' (Subtype.val '' S)) := + hf.isCompact_preimage_of_isOpen hSo' hSc' + -- g⁻¹(S) = Subtype.val⁻¹(f⁻¹(S')) and f⁻¹(S') ⊆ f⁻¹(U) = range Subtype.val + have hKsub : f ⁻¹' (Subtype.val '' S) ⊆ Set.range (Subtype.val : ↥(f ⁻¹' U) → X) := by + rw [Subtype.range_coe] + exact Set.preimage_mono (Subtype.coe_image_subset U S) + suffices g ⁻¹' S = Subtype.val ⁻¹' (f ⁻¹' (Subtype.val '' S)) by + rw [this] + exact oe_fU.toIsInducing.isCompact_preimage' hK hKsub + ext ⟨x, hx⟩ + simp only [Set.mem_preimage, g] + constructor + · intro h + exact ⟨⟨f x, hx⟩, h, rfl⟩ + · rintro ⟨⟨v, hv⟩, hS, hye⟩ + have : v = f x := hye + subst this; exact hS + -- Step 5: Apply the compact + quasi-separated version to g + have key := WithConstructibleTopology.isCompact_of_preimage_singleton g hg ⟨y, hyU⟩ + -- Step 6: Transfer back via Subtype.val + have hsub : f ⁻¹' {y} ⊆ f ⁻¹' U := Set.preimage_mono (Set.singleton_subset_iff.mpr hyU) + convert key.image continuous_subtype_val using 1 + ext x; constructor + · intro hx + refine ⟨⟨x, hsub hx⟩, ?_, rfl⟩ + simp only [Set.mem_preimage, Set.mem_singleton_iff, g] + exact Subtype.ext (Set.mem_singleton_iff.mp hx) + · rintro ⟨⟨a, ha⟩, hga, rfl⟩ + simpa [g] using hga diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean index 446a80f7306205..cc1c11e1c852a9 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean @@ -12,6 +12,7 @@ public import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition public import Mathlib.Topology.LocallyFinsupp public import Mathlib.Algebra.GradedMonoid public import Mathlib.Algebra.DirectSum.Decomposition +public import Mathlib.Topology.Spectral.ConstructibleTopology /-! # Algebraic Cycles @@ -57,17 +58,26 @@ of a point z : Y along a morphism `f : X ⟶ Y`. -/ def preimageSupport (c : locallyFinsupp X R) (z : Y) : Set X := f ⁻¹' {z} ∩ c.support +#check T2Space +lemma test {X : Type*} [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] : + T2Space (WithConstructibleTopology X) := by sorry + +def WithConstructibleTopology.lift {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] + (f : X → Y) : WithConstructibleTopology X → WithConstructibleTopology Y := f /-- Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. -/ lemma preimageSupport_finite (c : locallyFinsupp X R) (hf : IsSpectralMap f) (z : Y) : (preimageSupport f c z).Finite := by - + have : @Continuous _ _ (constructibleTopology X) (constructibleTopology Y) f := by sorry + have : T2Space (WithConstructibleTopology X) := sorry + have : T2Space (WithConstructibleTopology Y) := sorry sorry + end Zero From 3add02ca1cc85f54b6e2b1bd59d01149de2ac5f7 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 27 Mar 2026 10:07:06 +0100 Subject: [PATCH 35/70] WIP --- Mathlib/AlgebraicGeometry/AITEST.lean | 26 ++++++++++------ .../AlgebraicGeometry/AlgebraicCycle'.lean | 30 ++++++++++--------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AITEST.lean b/Mathlib/AlgebraicGeometry/AITEST.lean index 0f3731700af6a0..12c3a3a29a51d6 100644 --- a/Mathlib/AlgebraicGeometry/AITEST.lean +++ b/Mathlib/AlgebraicGeometry/AITEST.lean @@ -190,6 +190,8 @@ lemma testing {X : Type*} [TopologicalSpace X] [PrespectralSpace X] lemma IsLocallySpectral.fiber (f : X → Y) (hf : IsSpectralMap f) (y : Y) : f ⁻¹' {y} = ⋂ s ∈ {x ∈ 𝓝 y | IsOpen x ∧ IsCompact x}, f ⁻¹' s := sorry + + lemma IsLocallySpectral.isCompact_of_preimage_singleton (f : X → Y) (hf : IsSpectralMap f) (y : Y) : IsCompact (f ⁻¹' {y}) := by obtain ⟨U, hU⟩ := IsLocallySpectral.exists_spectral_nhd y @@ -201,22 +203,28 @@ lemma IsLocallySpectral.isCompact_of_preimage_singleton (f : X → Y) (hf : IsSp -- Step 3: Set up typeclass instances on f⁻¹(U) and U have oe_fU := hfUo.isOpenEmbedding_subtypeVal have oe_U := hUo.isOpenEmbedding_subtypeVal - haveI : CompactSpace ↥(f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc - haveI : T0Space ↥(f ⁻¹' U) := oe_fU.isEmbedding.t0Space - haveI : QuasiSober ↥(f ⁻¹' U) := oe_fU.quasiSober - haveI : PrespectralSpace ↥(f ⁻¹' U) := oe_fU.prespectralSpace - haveI : T0Space ↥U := oe_U.isEmbedding.t0Space - haveI : QuasiSober ↥U := oe_U.quasiSober - haveI : PrespectralSpace ↥U := oe_U.prespectralSpace + have : CompactSpace ↥(f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc + have : T0Space ↥(f ⁻¹' U) := oe_fU.isEmbedding.t0Space + have : QuasiSober ↥(f ⁻¹' U) := oe_fU.quasiSober + have : PrespectralSpace ↥(f ⁻¹' U) := oe_fU.prespectralSpace + have : T0Space ↥U := oe_U.isEmbedding.t0Space + have : QuasiSober ↥U := oe_U.quasiSober + have : PrespectralSpace ↥U := oe_U.prespectralSpace -- KEY SORRY: need f⁻¹(U) quasi-separated for compactSpace_withConstructibleTopology. -- For schemes this follows from the morphism being quasi-separated. - haveI : QuasiSeparatedSpace ↥(f ⁻¹' U) := + have : QuasiSeparatedSpace ↥(f ⁻¹' U) := by + constructor + intro A B hA1 hA2 hB1 hB2 + /- `f ⁻¹ U` is covered by spectral opens since it is locally spectral - we just take the cover indexed by all the points in `f ⁻¹ U` Hence, we must have that `f ⁻¹ U` is covered by a finite number of quasiseparated sets, - and hence must itself be quasiseparated. + and hence must itself be quasiseparated? + + I don't think this is true. Indeed, a quasicompact morphism may not in general be + quasiseparated -/ diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean index cc1c11e1c852a9..88a706718a9f2d 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean @@ -65,16 +65,17 @@ lemma test {X : Type*} [TopologicalSpace X] [T0Space X] [QuasiSober X] [Prespect def WithConstructibleTopology.lift {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] (f : X → Y) : WithConstructibleTopology X → WithConstructibleTopology Y := f -/-- +/- Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. -/ -lemma preimageSupport_finite (c : locallyFinsupp X R) (hf : IsSpectralMap f) (z : Y) : - (preimageSupport f c z).Finite := by - have : @Continuous _ _ (constructibleTopology X) (constructibleTopology Y) f := by sorry - have : T2Space (WithConstructibleTopology X) := sorry - have : T2Space (WithConstructibleTopology Y) := sorry - sorry +--lemma preimageSupport_finite (c : locallyFinsupp X R) (hf : IsSpectralMap f) (z : Y) : + --(preimageSupport f c z).Finite := by + + --have : @Continuous _ _ (constructibleTopology X) (constructibleTopology Y) f := by sorry + --have : T2Space (WithConstructibleTopology X) := sorry + --have : T2Space (WithConstructibleTopology Y) := sorry + --sorry @@ -112,7 +113,8 @@ lemma preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) (hW : LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| hf.2 W.is_open' hW -lemma iUnion_preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) (hW : IsCompact W.1) : +lemma iUnion_preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) + (hW : IsCompact W.1) : (⋃ _ : Y, f ⁻¹' W.carrier ∩ c.support).Finite := by suffices (f ⁻¹' W.carrier ∩ c.support).Finite by apply Finite.subset this @@ -142,13 +144,12 @@ variable {N : Type*} /-- The pushforward of an algebraic cycle has locally finite support. -/ -lemma map_locally_finite : +lemma map_locally_finite (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c z).Finite) : ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ - ∑ x ∈ (preimageSupport_finite c hf z).toFinset, (c x) * w x).Finite := by + ∑ x ∈ (h z).toFinset, (c x) * w x).Finite := by intro y have : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := sorry obtain ⟨W, hW⟩ := this - --obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by simp) use W refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by @@ -171,11 +172,12 @@ Note that usually the pushforward is only defined for proper morphisms, and inde properness to prove that the pushforward preserves rational equivalence. -/ noncomputable -def map : Function.locallyFinsupp Y R +def map (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c z).Finite) : + Function.locallyFinsupp Y R where - toFun z := (∑ x ∈ (preimageSupport_finite c hf z).toFinset, (c x) * w x) + toFun z := (∑ x ∈ (h z).toFinset, (c x) * w x) supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' z _ := map_locally_finite hf w c z + supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf h z /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. From a1f06ec28b2281b9dc67bf983403205ee504e1fb Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Tue, 31 Mar 2026 16:15:28 +0200 Subject: [PATCH 36/70] WIP --- .../AlgebraicGeometry/AlgebraicCycle'.lean | 71 +++++++------------ 1 file changed, 26 insertions(+), 45 deletions(-) diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean index 88a706718a9f2d..499b0cbf67b9e6 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean @@ -5,8 +5,6 @@ Authors: Raphael Douglas Giles -/ module -public import Mathlib.AlgebraicGeometry.Fiber -public import Mathlib.AlgebraicGeometry.Morphisms.Proper public import Mathlib.Combinatorics.Quiver.ReflQuiver public import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition public import Mathlib.Topology.LocallyFinsupp @@ -28,12 +26,10 @@ nonstandard definition. @[expose] public section -open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace - CategoryTheory +open Set Order Topology TopologicalSpace CategoryTheory universe u v -variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] [PrespectralSpace X] - [PrespectralSpace Y] [QuasiSober X] [QuasiSober Y] [T0Space X] [T0Space Y] +variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] {f : X → Y} (hf : IsSpectralMap f) (w : X → R) namespace Function @@ -58,30 +54,9 @@ of a point z : Y along a morphism `f : X ⟶ Y`. -/ def preimageSupport (c : locallyFinsupp X R) (z : Y) : Set X := f ⁻¹' {z} ∩ c.support -#check T2Space - -lemma test {X : Type*} [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] : - T2Space (WithConstructibleTopology X) := by sorry - -def WithConstructibleTopology.lift {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] - (f : X → Y) : WithConstructibleTopology X → WithConstructibleTopology Y := f -/- -Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage -of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. --/ ---lemma preimageSupport_finite (c : locallyFinsupp X R) (hf : IsSpectralMap f) (z : Y) : - --(preimageSupport f c z).Finite := by - - --have : @Continuous _ _ (constructibleTopology X) (constructibleTopology Y) f := by sorry - --have : T2Space (WithConstructibleTopology X) := sorry - --have : T2Space (WithConstructibleTopology Y) := sorry - --sorry - - end Zero - section map variable [Semiring R] {W : TopologicalSpace.Opens Y} (hW : IsCompact W.1) @@ -106,8 +81,6 @@ lemma preimageSupport_preimage_inter_subset : f ⁻¹' W.carrier ∩ mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ exact ⟨hp.1.1, hp.2⟩ ---variable [qc : QuasiCompact f] - lemma preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) (hW : IsCompact W.1) : (f ⁻¹' W.carrier ∩ c.support).Finite := LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| @@ -139,16 +112,21 @@ lemma inter_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ exact iUnion_preimage_inter_support_finite_of_isAffineOpen c hf hW -variable {N : Type*} +variable {N : Type*} [PrespectralSpace Y] /-- The pushforward of an algebraic cycle has locally finite support. -/ -lemma map_locally_finite (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c z).Finite) : +lemma map_locally_finite (hf : IsSpectralMap f) + (h : ∀ z, (preimageSupport f c z).Finite) : ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ ∑ x ∈ (h z).toFinset, (c x) * w x).Finite := by intro y - have : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := sorry + have : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by + obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open + (by simp : y ∈ ⊤) (by simp) + use ⟨U, hU.1.1⟩ + exact ⟨hU.1.2, hU.2.1⟩ obtain ⟨W, hW⟩ := this use W refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ @@ -160,16 +138,19 @@ lemma map_locally_finite (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c contrapose! intro aux rw [Finset.sum_eq_zero] - intro x hx simp_all exact inter_nonempty_finite c hf hW.1 variable (f) in /-- -The pushforward of an algebraic cycle by a quasicompact morphism. +The pushforward by a spectral map with quasicompact fibers with respect to a weight function `w`. +This is mainly used when interpretting locally fin supp functions as algebraic cycles (in this case +the weight function corresponds to a dimension or codimension function). + -Note that usually the pushforward is only defined for proper morphisms, and indeed we will need -properness to prove that the pushforward preserves rational equivalence. + +NOTE: It is probably more sensible to define this for functions with compact fibers, rather than +simply functions whose fibers have nonempty intersection with c.support. Maybe this way is fine too -/ noncomputable def map (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c z).Finite) : @@ -183,8 +164,9 @@ def map (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c z).Finite) : Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) + (h1 : ∀ z, (preimageSupport f c z).Finite) (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : - (map f hf w c).support ⊆ t:= by + (map f w c hf h1).support ⊆ t:= by intro y hy simp only [map, preimageSupport, Function.mem_support, ne_eq] at hy @@ -194,15 +176,16 @@ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) specialize h x (hc hx.1.2) grind - /-- The pushforward of `c` along the identity morphism is `c`. -/ @[simp] -lemma map_id (hw : ∀ z : X, w z = 1) : map id isSpectralMap_id w c = c := by +lemma map_id [PrespectralSpace X] (h : ∀ z, (preimageSupport id c z).Finite) + (hw : ∀ z : X, w z = 1) : + map id w c isSpectralMap_id h = c := by ext z - have : (c z ≠ 0 ∧ (preimageSupport_finite c isSpectralMap_id z).toFinset = {z}) ∨ - (c z = 0 ∧ (preimageSupport_finite c isSpectralMap_id z).toFinset = ∅) := by + have : (c z ≠ 0 ∧ (h z).toFinset = {z}) ∨ + (c z = 0 ∧ (h z).toFinset = ∅) := by simp only [ne_eq, Finite.toFinset, preimageSupport, preimage_id_eq, id_eq, toFinset_eq_empty, singleton_inter_eq_empty, Function.mem_support, not_not, and_self] @@ -211,17 +194,15 @@ lemma map_id (hw : ∀ z : X, w z = 1) : map id isSpectralMap_id w c = c := by Finset.mem_singleton, and_iff_left_iff_imp] rintro rfl assumption - suffices (map id isSpectralMap_id w c).toFun z = c.toFun z from this + suffices (map id w c isSpectralMap_id h).toFun z = c.toFun z from this obtain h | h := this all_goals simp only [map] rw[h.2] simp only [Finset.sum_singleton, Finset.sum_empty] - · specialize hw z - rw [hw] + · rw [hw] exact MulOneClass.mul_one (c z) · exact h.1.symm end map - end locallyFinsupp end Function From d0e4bb47470b074931e9b88f3057651f33a2d310 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Wed, 1 Apr 2026 18:13:22 +0200 Subject: [PATCH 37/70] Clean up --- .claude/worktrees/trusting-mendeleev | 1 - Mathlib/AlgebraicGeometry/AITEST.lean | 270 ------------------ .../LocallyFinsupp/Pushforward.lean} | 71 +++-- 3 files changed, 32 insertions(+), 310 deletions(-) delete mode 160000 .claude/worktrees/trusting-mendeleev delete mode 100644 Mathlib/AlgebraicGeometry/AITEST.lean rename Mathlib/{AlgebraicGeometry/AlgebraicCycle'.lean => Topology/LocallyFinsupp/Pushforward.lean} (73%) diff --git a/.claude/worktrees/trusting-mendeleev b/.claude/worktrees/trusting-mendeleev deleted file mode 160000 index 6a41af9938d48f..00000000000000 --- a/.claude/worktrees/trusting-mendeleev +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6a41af9938d48fb9dffefebd4f03584ce964384c diff --git a/Mathlib/AlgebraicGeometry/AITEST.lean b/Mathlib/AlgebraicGeometry/AITEST.lean deleted file mode 100644 index 12c3a3a29a51d6..00000000000000 --- a/Mathlib/AlgebraicGeometry/AITEST.lean +++ /dev/null @@ -1,270 +0,0 @@ -import Mathlib.Topology.Spectral.ConstructibleTopology -import Mathlib.Topology.Order - -instance {X : Type*} [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] : - T2Space (WithConstructibleTopology X) where - t2 x y hxy := by - wlog h : ∃ U : Set X, IsOpen U ∧ x ∈ U ∧ y ∉ U - · obtain ⟨U, hUo, ⟨hxU, hyU⟩ | ⟨hyU, hxU⟩⟩ := exists_isOpen_xor'_mem (X := X) hxy - · exact this _ _ hxy ⟨U, hUo, hxU, hyU⟩ - · obtain ⟨u, v, h1, h2, h3, h4, h5⟩ := this y x hxy.symm ⟨U, hUo, hyU, hxU⟩ - exact ⟨v, u, h2, h1, h4, h3, h5.symm⟩ - obtain ⟨U, hUo, ⟨hxU, hyU⟩⟩ := h - obtain ⟨V, ⟨hVo, hVc⟩, hxV, hVU⟩ := - PrespectralSpace.isTopologicalBasis (X := X) |>.exists_subset_of_mem_open hxU hUo - exact ⟨V, Vᶜ, hVc.isOpen_constructibleTopology_of_isOpen hVo, - (compl_compl V ▸ hVc).isOpen_constructibleTopology_of_isClosed hVo.isClosed_compl, - hxV, fun hyV => hyU (hVU hyV), disjoint_compl_right⟩ - -namespace WithConstructibleTopology - -@[match_pattern] def toEquiv {α : Type*} [TopologicalSpace α] : α ≃ WithConstructibleTopology α := - Equiv.refl _ - -@[match_pattern] def ofEquiv {α : Type*} [TopologicalSpace α] : WithConstructibleTopology α ≃ α := - Equiv.refl _ - -lemma ofEquiv_continuous {X : Type*} [TopologicalSpace X] [a : PrespectralSpace X] : - Continuous (ofEquiv (α := X)) := by - have := a.1 - constructor - intro U hU - have := (TopologicalSpace.IsTopologicalBasis.isOpen_iff this).mp hU - let Ux (x : U) := Exists.choose (this x x.2) - let V := ⋃ (x : U), Ux x - have opV : IsOpen V := by - apply isOpen_iUnion - intro x - exact (Exists.choose_spec (this x x.2)).1.1 - have vu : V = U := by - apply le_antisymm - · exact Set.iUnion_subset fun x => (Exists.choose_spec (this x x.2)).2.2 - · intro z hz - exact Set.mem_iUnion.mpr ⟨⟨z, hz⟩, (Exists.choose_spec (this z hz)).2.1⟩ - rw [← vu] - dsimp [V] - simp only [Set.iUnion_coe_set, Set.preimage_iUnion] - apply isOpen_iUnion - intro x - apply isOpen_iUnion - intro hx - have := Exists.choose_spec (this x hx) - dsimp [Ux] - apply IsCompact.isOpen_constructibleTopology_of_isOpen this.1.2 this.1.1 - -def lift {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] (f : X → Y) : - WithConstructibleTopology X → WithConstructibleTopology Y := toEquiv.toFun ∘ f ∘ toEquiv.invFun - -lemma lift_continuous {X Y : Type*} - [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] - [TopologicalSpace Y] [T0Space Y] [QuasiSober Y] [PrespectralSpace Y] - (f : SpectralMap X Y) : Continuous (lift f) := by - erw [continuous_generateFrom_iff] - intro U hU - simp only [constructibleTopologySubbasis] at hU - obtain h | h := hU - · have a := f.2.2 h.1 h.2 - have b := f.2.1.1 U h.1 - have := IsCompact.isOpen_constructibleTopology_of_isOpen a b - convert this - · expose_names - have o : @IsOpen Y inst_4 (U)ᶜ := by simp_all - have a := f.2.2 o h.2 - have : IsClosed (f.toFun ⁻¹' U) := IsClosed.preimage f.2.1 h.1 - convert IsCompact.isOpen_constructibleTopology_of_isClosed a this using 1 - -lemma isCompact_of_preimage_singleton {X Y : Type*} - [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] - [CompactSpace X] [QuasiSeparatedSpace X] - [TopologicalSpace Y] [T0Space Y] [QuasiSober Y] [PrespectralSpace Y] - (f : X → Y) (hf : IsSpectralMap f) (y : Y) : - IsCompact (f ⁻¹' {y}) := by - convert - ((isClosed_singleton).preimage (lift_continuous ⟨f, hf⟩)).isCompact.image ofEquiv_continuous - aesop - -end WithConstructibleTopology - -class IsLocallySpectral (X : Type*) [TopologicalSpace X] [T0Space X] [QuasiSober X] - [PrespectralSpace X] : Prop where - exists_spectral_nhd' (x : X) : ∃ U : Set X, IsOpen U ∧ IsCompact U ∧ QuasiSeparatedSpace U ∧ x ∈ U - -variable {X : Type*} [TopologicalSpace X] [T0Space X] [QuasiSober X] [PrespectralSpace X] - -lemma IsLocallySpectral.exists_spectral_nhd [q : IsLocallySpectral X] (x : X) : - ∃ U : Set X, IsOpen U ∧ IsCompact U ∧ QuasiSeparatedSpace U ∧ x ∈ U := q.exists_spectral_nhd' x - -variable {Y : Type*} [TopologicalSpace Y] [T0Space Y] [QuasiSober Y] [PrespectralSpace Y] - [IsLocallySpectral Y] - -/- -lemma zsjdhh {X : Type*} [TopologicalSpace X] (U V : Set X) - (hU : IsQuasiSeparated U) (hV : IsOpen V) (hV' : IsCompact V) : IsQuasiSeparated (U ∩ V) := by - - sorry-/ - -open Topology -lemma IsSpectralMap.of_openEmbedding {X Y : Type*} [TopologicalSpace X] [TopologicalSpace Y] - [CompactSpace X] [QuasiSeparatedSpace Y] {f : X → Y} (hf : IsOpenEmbedding f) : - IsSpectralMap f := by - constructor - · exact hf.continuous - · intro U hU hU' - have : IsCompact (U ∩ (Set.range f)) := by - have : IsCompact (Set.range f) := by - convert CompactSpace.isCompact_univ.image hf.continuous - exact Set.image_univ.symm - /- - Suppose we only know that f '' ⊤ is quasiseparated. Then we wish to know if f '' ⊤ ∩ - -/ - apply IsCompact.inter_of_isOpen hU' this hU hf.isOpen_range - have := hf.isCompact_preimage' this (by simp) - convert this using 1 - exact Set.preimage_inter_range.symm -open Set - - -variable [IsLocallySpectral X] - -/-- -A finite union of quasi-separated compact opens is quasi-separated, provided the pairwise -intersections are compact (and compact opens form a topological basis). - -This is the topological analogue of Stacks Project Tag 01KS. The key step is showing that -if `W` is compact open with `W ⊆ ⋃ i, f i`, then `W ∩ f k` is compact. This uses the -`PrespectralSpace` hypothesis: we cover `W` by basis compact opens, each contained in some -`f j`, extract a finite subcover by compactness of `W`, and then each piece intersected -with `f k` is compact by quasi-separatedness of `f j`. --/ -lemma testing {X : Type*} [TopologicalSpace X] [PrespectralSpace X] - {ι : Type*} {f : ι → Set X} [Finite ι] - (h : ∀ (i : ι), IsOpen (f i) ∧ IsQuasiSeparated (f i) ∧ IsCompact (f i)) - (hpair : ∀ i j, IsCompact (f i ∩ f j)) : - IsQuasiSeparated (⋃ i, f i) := by - intro U V hUsub hUo hUc hVsub hVo hVc - -- Key claim: for W compact open ⊆ ⋃ f i, W ∩ f k is compact - suffices key : ∀ (W : Set X), W ⊆ ⋃ i, f i → IsOpen W → IsCompact W → - ∀ k, IsCompact (W ∩ f k) by - -- Decompose U ∩ V = ⋃ i, (U ∩ f i) ∩ (V ∩ f i) - have cover : U ∩ V = ⋃ i, (U ∩ V ∩ f i) := by - rw [← Set.inter_iUnion, Set.inter_eq_left.mpr (inter_subset_left.trans hUsub)] - rw [cover] - apply isCompact_iUnion; intro i - have : U ∩ V ∩ f i = (U ∩ f i) ∩ (V ∩ f i) := by tauto_set - rw [this] - exact (h i).2.1 _ _ inter_subset_right (hUo.inter (h i).1) (key U hUsub hUo hUc i) - inter_subset_right (hVo.inter (h i).1) (key V hVsub hVo hVc i) - -- Prove the key claim - intro W hWsub hWo hWc k - have basis := PrespectralSpace.isTopologicalBasis (X := X) - -- For each x ∈ W, find j(x) and a basis compact open B(x) ⊆ W ∩ f(j(x)) - have hx_data : ∀ x : ↥W, ∃ j : ι, ∃ B : Set X, - IsOpen B ∧ IsCompact B ∧ x.1 ∈ B ∧ B ⊆ W ∧ B ⊆ f j := by - intro ⟨x, hxW⟩ - obtain ⟨j, hxfj⟩ := mem_iUnion.mp (hWsub hxW) - obtain ⟨B, ⟨hBo, hBc⟩, hxB, hBsub⟩ := - basis.exists_subset_of_mem_open (show x ∈ W ∩ f j from ⟨hxW, hxfj⟩) (hWo.inter (h j).1) - exact ⟨j, B, hBo, hBc, hxB, hBsub.trans inter_subset_left, hBsub.trans inter_subset_right⟩ - choose j B hBo hBc hxB hBW hBf using hx_data - -- Extract finite subcover from compactness of W - obtain ⟨t, ht⟩ := hWc.elim_finite_subcover B (fun x => hBo x) - (fun x hx => mem_iUnion.mpr ⟨⟨x, hx⟩, hxB ⟨x, hx⟩⟩) - -- W ∩ f k = ⋃ x ∈ t, (B x ∩ f k) since each B x ⊆ W - have eq : W ∩ f k = ⋃ x ∈ (t : Set ↥W), (B x ∩ f k) := by - ext z; simp only [mem_inter_iff, mem_iUnion, Finset.mem_coe]; constructor - · intro ⟨hzW, hzfk⟩ - obtain ⟨x, hxt, hzBx⟩ := mem_iUnion₂.mp (ht hzW) - exact ⟨x, hxt, hzBx, hzfk⟩ - · rintro ⟨x, _, hzBx, hzfk⟩ - exact ⟨hBW x hzBx, hzfk⟩ - rw [eq] - -- Finite union of compact sets is compact - exact t.finite_toSet.isCompact_biUnion fun x _ => by - -- B x ∩ f k is compact: use QS of f(j x) with B x and f k ∩ f(j x) - have h_qs := (h (j x)).2.1 (B x) (f k ∩ f (j x)) - (hBf x) (hBo x) (hBc x) - inter_subset_right ((h k).1.inter (h (j x)).1) (hpair k (j x)) - -- B x ∩ (f k ∩ f(j x)) = B x ∩ f k since B x ⊆ f(j x) - rwa [← Set.inter_assoc, inter_eq_left.mpr (inter_subset_left.trans (hBf x))] at h_qs - -lemma IsLocallySpectral.fiber (f : X → Y) (hf : IsSpectralMap f) (y : Y) : - f ⁻¹' {y} = ⋂ s ∈ {x ∈ 𝓝 y | IsOpen x ∧ IsCompact x}, f ⁻¹' s := sorry - - - -lemma IsLocallySpectral.isCompact_of_preimage_singleton (f : X → Y) (hf : IsSpectralMap f) (y : Y) : - IsCompact (f ⁻¹' {y}) := by - obtain ⟨U, hU⟩ := IsLocallySpectral.exists_spectral_nhd y - -- Step 1: Get a spectral neighborhood U of y in Y - obtain ⟨U, hUo, hUc, hUqs, hyU⟩ := IsLocallySpectral.exists_spectral_nhd y - -- Step 2: f⁻¹(U) is compact and open - have hfUc : IsCompact (f ⁻¹' U) := hf.isCompact_preimage_of_isOpen hUo hUc - have hfUo : IsOpen (f ⁻¹' U) := hUo.preimage hf.continuous - -- Step 3: Set up typeclass instances on f⁻¹(U) and U - have oe_fU := hfUo.isOpenEmbedding_subtypeVal - have oe_U := hUo.isOpenEmbedding_subtypeVal - have : CompactSpace ↥(f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc - have : T0Space ↥(f ⁻¹' U) := oe_fU.isEmbedding.t0Space - have : QuasiSober ↥(f ⁻¹' U) := oe_fU.quasiSober - have : PrespectralSpace ↥(f ⁻¹' U) := oe_fU.prespectralSpace - have : T0Space ↥U := oe_U.isEmbedding.t0Space - have : QuasiSober ↥U := oe_U.quasiSober - have : PrespectralSpace ↥U := oe_U.prespectralSpace - -- KEY SORRY: need f⁻¹(U) quasi-separated for compactSpace_withConstructibleTopology. - -- For schemes this follows from the morphism being quasi-separated. - have : QuasiSeparatedSpace ↥(f ⁻¹' U) := by - constructor - intro A B hA1 hA2 hB1 hB2 - - /- - `f ⁻¹ U` is covered by spectral opens since it is locally spectral - we just take the cover - indexed by all the points in `f ⁻¹ U` - - Hence, we must have that `f ⁻¹ U` is covered by a finite number of quasiseparated sets, - and hence must itself be quasiseparated? - - I don't think this is true. Indeed, a quasicompact morphism may not in general be - quasiseparated - -/ - - - sorry - -- Step 4: Define the restriction g : f⁻¹(U) → U and show it is spectral - let g : ↥(f ⁻¹' U) → ↥U := fun x => ⟨f x.val, x.prop⟩ - have hgc : Continuous g := - Continuous.subtype_mk (hf.continuous.comp continuous_subtype_val) _ - have hg : IsSpectralMap g := by - refine ⟨hgc, fun S hSo hSc => ?_⟩ - -- S is a compact open of ↥U, hence corresponds to a compact open of Y contained in U - have hSo' : IsOpen (Subtype.val '' S : Set Y) := oe_U.isOpenMap _ hSo - have hSc' : IsCompact (Subtype.val '' S : Set Y) := hSc.image continuous_subtype_val - -- f⁻¹(S') is compact since f is spectral - have hK : IsCompact (f ⁻¹' (Subtype.val '' S)) := - hf.isCompact_preimage_of_isOpen hSo' hSc' - -- g⁻¹(S) = Subtype.val⁻¹(f⁻¹(S')) and f⁻¹(S') ⊆ f⁻¹(U) = range Subtype.val - have hKsub : f ⁻¹' (Subtype.val '' S) ⊆ Set.range (Subtype.val : ↥(f ⁻¹' U) → X) := by - rw [Subtype.range_coe] - exact Set.preimage_mono (Subtype.coe_image_subset U S) - suffices g ⁻¹' S = Subtype.val ⁻¹' (f ⁻¹' (Subtype.val '' S)) by - rw [this] - exact oe_fU.toIsInducing.isCompact_preimage' hK hKsub - ext ⟨x, hx⟩ - simp only [Set.mem_preimage, g] - constructor - · intro h - exact ⟨⟨f x, hx⟩, h, rfl⟩ - · rintro ⟨⟨v, hv⟩, hS, hye⟩ - have : v = f x := hye - subst this; exact hS - -- Step 5: Apply the compact + quasi-separated version to g - have key := WithConstructibleTopology.isCompact_of_preimage_singleton g hg ⟨y, hyU⟩ - -- Step 6: Transfer back via Subtype.val - have hsub : f ⁻¹' {y} ⊆ f ⁻¹' U := Set.preimage_mono (Set.singleton_subset_iff.mpr hyU) - convert key.image continuous_subtype_val using 1 - ext x; constructor - · intro hx - refine ⟨⟨x, hsub hx⟩, ?_, rfl⟩ - simp only [Set.mem_preimage, Set.mem_singleton_iff, g] - exact Subtype.ext (Set.mem_singleton_iff.mp hx) - · rintro ⟨⟨a, ha⟩, hga, rfl⟩ - simpa [g] using hga diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean similarity index 73% rename from Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean rename to Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 499b0cbf67b9e6..71b646dbf63baa 100644 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle'.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Raphael Douglas Giles. All rights reserved. +Copyright (c) 2026 Raphael Douglas Giles. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Raphael Douglas Giles -/ @@ -13,15 +13,13 @@ public import Mathlib.Algebra.DirectSum.Decomposition public import Mathlib.Topology.Spectral.ConstructibleTopology /-! -# Algebraic Cycles +# Pushforward of functions with locally finite support -In this file we define algebraic cycles on a scheme `X` with coefficients in a type `R` and provide -some basic API for working with them. We define an algebraic cycle on a scheme `X` with -coefficients in a type `R` to be functions `c : X → R` whose support is locally finite. - -Here we're making use of the equivalence between irreducible closed subsets of a scheme and their -generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly -nonstandard definition. +In this file we define the notion of the pushforward of a function with locally finite support +between prespectral spaces. This is a nonstandard notion that arises because of our choice in +mathlib to model algebraic cycles as functions with locally finite support. +This makes it so that standard notions in the theory of cycles can be defined in more generality +than usual. -/ @[expose] public section @@ -38,7 +36,8 @@ namespace locallyFinsupp section Zero variable [Zero R] /-- -The cycle containing a single point with a chosen coefficient +The function taking `x` to some value `coeff`, and every other value to `0` as a +function with locally finite support. -/ noncomputable def single (x : X) (coeff : R) : Function.locallyFinsupp X R where @@ -59,8 +58,7 @@ end Zero section map -variable [Semiring R] {W : TopologicalSpace.Opens Y} (hW : IsCompact W.1) - (c : Function.locallyFinsupp X R) +variable [Semiring R] {W : TopologicalSpace.Opens Y} (c : Function.locallyFinsupp X R) lemma preimageSupport_inter_subset : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ f '' (f ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by @@ -81,28 +79,23 @@ lemma preimageSupport_preimage_inter_subset : f ⁻¹' W.carrier ∩ mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ exact ⟨hp.1.1, hp.2⟩ -lemma preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) (hW : IsCompact W.1) : - (f ⁻¹' W.carrier ∩ c.support).Finite := - LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| - hf.2 W.is_open' hW - -lemma iUnion_preimage_inter_support_finite_of_isAffineOpen (hf : IsSpectralMap f) - (hW : IsCompact W.1) : - (⋃ _ : Y, f ⁻¹' W.carrier ∩ c.support).Finite := by +lemma iUnion_preimage_inter_support_finite_of_isCompact (hf : IsSpectralMap f) + (hW : IsCompact W.1) : (⋃ _ : Y, f ⁻¹' W.carrier ∩ c.support).Finite := by suffices (f ⁻¹' W.carrier ∩ c.support).Finite by apply Finite.subset this intro a ha simp only [Opens.carrier_eq_coe, mem_iUnion, mem_inter_iff, mem_preimage, SetLike.mem_coe, Function.mem_support, ne_eq, exists_and_left, exists_const_iff] at ha ⊢ exact ⟨ha.1, ha.2.2⟩ - exact preimage_inter_support_finite_of_isAffineOpen c hf hW + exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| + hf.2 W.is_open' hW -lemma inter_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) - : (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite := by +lemma inter_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) : + (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite := by refine Finite.subset (Finite.image _ ?_) (preimageSupport_inter_subset c) - rw[preimage_inter] + rw [preimage_inter] apply Finite.subset _ (preimageSupport_preimage_inter_subset c) - rw[inter_iUnion] + rw [inter_iUnion] suffices (⋃ i : Y, f ⁻¹' W.carrier ∩ c.support).Finite by apply Finite.subset this simp only [Opens.carrier_eq_coe, iUnion_subset_iff] @@ -110,7 +103,7 @@ lemma inter_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) simp only [mem_inter_iff, mem_preimage, SetLike.mem_coe, Function.mem_support, ne_eq, mem_iUnion, exists_and_left, exists_const_iff] at hx ⊢ exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ - exact iUnion_preimage_inter_support_finite_of_isAffineOpen c hf hW + exact iUnion_preimage_inter_support_finite_of_isCompact c hf hW variable {N : Type*} [PrespectralSpace Y] @@ -143,14 +136,11 @@ lemma map_locally_finite (hf : IsSpectralMap f) variable (f) in /-- -The pushforward by a spectral map with quasicompact fibers with respect to a weight function `w`. -This is mainly used when interpretting locally fin supp functions as algebraic cycles (in this case -the weight function corresponds to a dimension or codimension function). - - - -NOTE: It is probably more sensible to define this for functions with compact fibers, rather than -simply functions whose fibers have nonempty intersection with c.support. Maybe this way is fine too +The pushforward of a function `c` of locally finite support +by a spectral map whose fibers intersect `c` in finitely many places +with respect to a weight function `w`. This is mainly used when interpretting locally fin supp +functions as algebraic cycles (in this case the weight function corresponds to a dimension or +codimension function). -/ noncomputable def map (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c z).Finite) : @@ -176,16 +166,19 @@ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) specialize h x (hc hx.1.2) grind +lemma preimageSupport_id (z : X) : (preimageSupport id c z).Finite := by + simp [preimageSupport, toFinite ({z} ∩ locallyFinsuppWithin.support c)] + /-- The pushforward of `c` along the identity morphism is `c`. -/ @[simp] -lemma map_id [PrespectralSpace X] (h : ∀ z, (preimageSupport id c z).Finite) +lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : - map id w c isSpectralMap_id h = c := by + map id w c isSpectralMap_id (preimageSupport_id c) = c := by ext z - have : (c z ≠ 0 ∧ (h z).toFinset = {z}) ∨ - (c z = 0 ∧ (h z).toFinset = ∅) := by + have : (c z ≠ 0 ∧ (preimageSupport_id c z).toFinset = {z}) ∨ + (c z = 0 ∧ (preimageSupport_id c z).toFinset = ∅) := by simp only [ne_eq, Finite.toFinset, preimageSupport, preimage_id_eq, id_eq, toFinset_eq_empty, singleton_inter_eq_empty, Function.mem_support, not_not, and_self] @@ -194,7 +187,7 @@ lemma map_id [PrespectralSpace X] (h : ∀ z, (preimageSupport id c z).Finite) Finset.mem_singleton, and_iff_left_iff_imp] rintro rfl assumption - suffices (map id w c isSpectralMap_id h).toFun z = c.toFun z from this + suffices (map id w c isSpectralMap_id (preimageSupport_id c)).toFun z = c.toFun z from this obtain h | h := this all_goals simp only [map] rw[h.2] From 7149ddcca0e531a8a0a395307091e4f3dcb4b833 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Wed, 1 Apr 2026 18:14:42 +0200 Subject: [PATCH 38/70] Remove AlegebraicCycle.lean --- Mathlib/AlgebraicGeometry/AlgebraicCycle.lean | 342 ------------------ 1 file changed, 342 deletions(-) delete mode 100644 Mathlib/AlgebraicGeometry/AlgebraicCycle.lean diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean deleted file mode 100644 index 47c9484e99d050..00000000000000 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle.lean +++ /dev/null @@ -1,342 +0,0 @@ -/- -Copyright (c) 2025 Raphael Douglas Giles. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Raphael Douglas Giles --/ -module - -public import Mathlib.AlgebraicGeometry.Fiber -public import Mathlib.AlgebraicGeometry.Morphisms.Proper -public import Mathlib.Combinatorics.Quiver.ReflQuiver -public import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition -public import Mathlib.Topology.LocallyFinsupp -public import Mathlib.Algebra.GradedMonoid -public import Mathlib.Algebra.DirectSum.Decomposition - -/-! -# Algebraic Cycles - -In this file we define algebraic cycles on a scheme `X` with coefficients in a type `R` and provide -some basic API for working with them. We define an algebraic cycle on a scheme `X` with -coefficients in a type `R` to be functions `c : X → R` whose support is locally finite. - -Here we're making use of the equivalence between irreducible closed subsets of a scheme and their -generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly -nonstandard definition. --/ - -@[expose] public section - -open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace - CategoryTheory - -universe u v -variable (X : Scheme.{u}) {Y : Scheme.{u}} (R : Type*) - -/-- -Algebraic cycle on a scheme `X` with coefficients in a type `Z` is just a function from `X` to `Z` -with locally finite support. - -Here we're making use of the equivalence between irreducible closed subsets of a scheme and their -generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly -nonstandard definition. --/ -abbrev AlgebraicCycle (X : Scheme.{u}) (R : Type*) [Zero R] := - Function.locallyFinsupp X R - -namespace AlgebraicCycle - -/-- -In the context of algebraic cycles, gradings tend to be defined using functions on -the components of the cycles (mainly different notions of dimension and codimension). -Here we define a notion of grading defined by such a dimension/codimension function. --/ -def Grading (N : Type*) := X → N - -variable {X} in -/-- -Given an addivive monoid `R`, a grading function `G` from `X` to `N`, and `d` in `N`, -we have an additive submonoid of `d`-homogeneous cycles with coefficients in `R`. --/ -def Grading.homogeneousCycles {N : Type*} (g : Grading X N) (R : Type*) [AddMonoid R] (d : N) : - AddSubmonoid (AlgebraicCycle X R) where - carrier := { c | ∀ x ∈ c.support, g x = d } - add_mem' {c₁} c₂ hc₁ hc₂ := by - simp at hc₁ hc₂ ⊢ - grind - zero_mem' := by simp - -/-- -Submonoid of cycles of pure dimension `d`. --/ -def dimensionGradingAddSubmonoid [AddMonoid R] (d : ℕ∞) : - AddSubmonoid (AlgebraicCycle X R) where - carrier := {c : AlgebraicCycle X R | ∀ x ∈ c.support, height x = d} - add_mem' {a} b c₁ c₂ := by - simp_all only [Function.mem_support, ne_eq, mem_setOf_eq, - Function.locallyFinsuppWithin.coe_add, Pi.add_apply] - intro x hx - have : ¬ a x = 0 ∨ ¬ b x = 0 := by - by_contra h - simp_all - exact Or.elim this (c₁ x) (c₂ x) - zero_mem' := by simp - -/-- -Grading on `AlgebraicCycle X Z` by dimension, where dimension of a point is defined to be the -height in the specialization order. Note this notion of dimension falls apart a bit outside of -contexts where there are some equidimensionality hypotheses. In these contexts, the theory of -dimension functions is more appropriate to use. --/ -noncomputable -def dimensionGrading : Grading X ℕ∞ := Order.height - -/-- -Grading on `AlgebraicCycle X Z` by codimension, where codimension of a point is defined to be the -coheight in the specialization order. Note this notion of codimension falls apart a bit outside of -contexts where there are some equidimensionality hypotheses. In these contexts, the theory of -dimension functions is more appropriate to use. --/ -noncomputable -def codimensionGrading : Grading X ℕ∞ := Order.coheight - -variable {X R} - -section Zero - -variable (f : X ⟶ Y) [Zero R] (c : AlgebraicCycle X R) (x : X) (z : Y) - -/-- -The cycle containing a single point with a chosen coefficient --/ -noncomputable -def single (coeff : R) : AlgebraicCycle X R where - toFun := Set.indicator {x} (Function.const X coeff) - supportWithinDomain' := by simp only [support_indicator]; exact LE.le.subset fun _ a_1 ↦ trivial - supportLocallyFiniteWithinDomain' z hz := - ⟨⊤, ⟨Filter.univ_mem' fun a ↦ trivial, by simp [← Function.const_def, toFinite]⟩⟩ - -/-- -Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage -of a point z : Y along a morphism `f : X ⟶ Y`. --/ -def preimageSupport : Set X := - f.base ⁻¹' {z} ∩ c.support - -/-- -Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage -of a point z : Y along a quasicompact morphism f : X ⟶ Y is finite. --/ -lemma preimageSupport_finite [qf : QuasiCompact f] : - (preimageSupport f c z).Finite := LocallyFiniteSupport.finite_inter_support_of_isCompact - c.locallyFiniteSupport <| f.isCompact_preimage_singleton z - -noncomputable -instance moduleResidueFieldExtension (x : X) : - Module (IsLocalRing.ResidueField ↑(Y.presheaf.stalk (f x))) - (IsLocalRing.ResidueField ↑(X.presheaf.stalk x)) := - letI := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom) - Algebra.toModule - -/-- -Degree of `f` at a point `x` is defined to be the degree of the associated field extension -from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is either infinite -or undefined. --/ -noncomputable -def _root_.AlgebraicGeometry.LocallyRingedSpace.Hom.degree : ℕ := @Module.finrank - (IsLocalRing.ResidueField (Y.presheaf.stalk (f.base x))) - (IsLocalRing.ResidueField (X.presheaf.stalk x)) _ _ _ - -end Zero - -/-- -The usual degree function of a morphism of schemes `f : X ⟶ Y` at a point `x : X` -is defined to be the degree of the associated field extension from `κ(f x)` to `κ(x)`, and can be -viewed a kind of correction factor with respect to which one can define the pushforward of algebraic -cycles. - -The class `HasDegree Z` states the properties needed of such a degree function to define a sensible -notion of pushforward from `AlgebraicCycle X Z` to `AlgebraicCycle Y Z`. --/ -class HasDegree (Z : Type*) [Semiring Z] where - /-- - The degree of a morrphism at a point - -/ - degree : ∀ {X Y : Scheme.{u}}, (X ⟶ Y) → X → Z - /-- - The degree of the identity at any point is `1`. - -/ - degree_one {X : Scheme.{u}} (z : X) : degree (𝟙 X) z = 1 - -open Classical in -/-- -Implementation detail for pushforward: function used to define the coefficient of the pushforward -of a cycle `c` at a point `z = f x`, as in stacks `02R3`. --/ -noncomputable -def mapAux {N : Type*} [Semiring R] [HasDegree R] {Y : Scheme} - (gx : Grading X N) (gy : Grading Y N) - (f : X ⟶ Y) (x : X) : R := - if gx x = gy (f.base x) then HasDegree.degree f x else 0 - -section map - -variable [Semiring R] {W : Y.Opens} (hW : IsAffineOpen W) - (f : X ⟶ Y) (c : AlgebraicCycle X R) - -lemma preimageSupport_inter_subset : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ - f.base '' (f.base ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by - intro a ha - rw [image_preimage_inter] - suffices a ∈ f.base '' c.support from mem_inter ha this - have := ha.2.some_mem - simp only [preimageSupport, mem_inter_iff, mem_preimage, mem_singleton_iff, - Function.mem_support, ne_eq, mem_image] at this ⊢ - exact ⟨ha.2.some, this.symm⟩ - -lemma preimageSupport_preimage_inter_subset : f.base ⁻¹' W.carrier ∩ - f.base ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ - f.base ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by - intro p hp - simp only [Opens.carrier_eq_coe, preimageSupport, preimage_setOf_eq, mem_inter_iff, - mem_preimage, SetLike.mem_coe, mem_setOf_eq, Function.mem_support, ne_eq, mem_iUnion, - mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ - exact ⟨hp.1.1, hp.2⟩ - -variable [qc : QuasiCompact f] - -lemma preimage_inter_support_finite_of_isAffineOpen (hW : IsAffineOpen W) : - (f.base ⁻¹' W.carrier ∩ c.support).Finite := - LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| - qc.1 W.carrier W.is_open' <| AlgebraicGeometry.IsAffineOpen.isCompact hW - -lemma iUnion_preimage_inter_support_finite_of_isAffineOpen (hW : IsAffineOpen W) : - (⋃ _ : Y, f.base ⁻¹' W.carrier ∩ c.support).Finite := by - suffices (f.base ⁻¹' W.carrier ∩ c.support).Finite by - apply Finite.subset this - intro a ha - simp only [Opens.carrier_eq_coe, mem_iUnion, mem_inter_iff, mem_preimage, - SetLike.mem_coe, Function.mem_support, ne_eq, exists_and_left, exists_const_iff] at ha ⊢ - exact ⟨ha.1, ha.2.2⟩ - exact preimage_inter_support_finite_of_isAffineOpen f c hW - -lemma inter_nonempty_finite (hW : IsAffineOpen W) - : (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite := by - refine Finite.subset (Finite.image _ ?_) (preimageSupport_inter_subset f c) - rw[preimage_inter] - apply Finite.subset _ (preimageSupport_preimage_inter_subset f c) - rw[inter_iUnion] - suffices (⋃ i : Y, f.base ⁻¹' W.carrier ∩ c.support).Finite by - apply Finite.subset this - simp only [Opens.carrier_eq_coe, iUnion_subset_iff] - intro y x hx - simp only [mem_inter_iff, mem_preimage, SetLike.mem_coe, - Function.mem_support, ne_eq, mem_iUnion, exists_and_left, exists_const_iff] at hx ⊢ - exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ - exact iUnion_preimage_inter_support_finite_of_isAffineOpen f c hW - -variable {N : Type*} [HasDegree R] - -/-- -The pushforward of an algebraic cycle has locally finite support. --/ -lemma map_locally_finite (gx : Grading X N) (gy : Grading Y N) : - ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ - ∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux gx gy f x).Finite := by - intro y - obtain ⟨W, hW⟩ := exists_isAffineOpen_mem_and_subset (x := y) (U := ⊤) (by simp) - use W - refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2.1, ?_⟩ - suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by - apply Finite.subset this - apply inter_subset_inter Set.Subset.rfl - intro x - simp only [Function.mem_support, ne_eq, mem_setOf_eq] - contrapose! - intro aux - rw [Finset.sum_eq_zero] - intro x hx - simp_all - exact inter_nonempty_finite f c hW.1 - -/-- -The pushforward of an algebraic cycle by a quasicompact morphism. - -Note that usually the pushforward is only defined for proper morphisms, and indeed we will need -properness to prove that the pushforward preserves rational equivalence. --/ -noncomputable -def map (gx : Grading X N) (gy : Grading Y N) : AlgebraicCycle Y R - where - toFun z := (∑ x ∈ (preimageSupport_finite f c z).toFinset, (c x) * mapAux gx gy f x) - supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' z _ := map_locally_finite f c gx gy z - -/-- -Pushforward preserves cycles of pure dimension `d` in the dimension grading. --/ -lemma map_homogeneneous {d : ℕ∞} (c : AlgebraicCycle X R) - (hc : c ∈ (dimensionGrading X).homogeneousCycles R d) : - map f c (dimensionGrading X) (dimensionGrading Y) ∈ - (dimensionGrading Y).homogeneousCycles R d := by - simp only [dimensionGrading] - intro y hy - simp only [map, preimageSupport, mapAux, mul_ite, mul_zero, Function.mem_support, - ne_eq] at hy - obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy - simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, - Function.mem_support, ne_eq, ite_eq_right_iff, Classical.not_imp] at hx - have : height x = d := hc x hx.1.2 - simp_all - -/-- -The pushforward of `c` along the identity morphism is `c`. --/ -@[simp] -lemma map_id (g : Grading X N) : map (𝟙 X) c g g = c := by - ext z - have : (c z ≠ 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = {z}) ∨ - (c z = 0 ∧ (preimageSupport_finite (𝟙 X) c z).toFinset = ∅) := by - simp only [ne_eq, Finite.toFinset, preimageSupport, Scheme.Hom.id_base, TopCat.hom_id, - ContinuousMap.coe_id, preimage_id_eq, id_eq, toFinset_eq_empty, singleton_inter_eq_empty, - Function.mem_support, not_not, and_self] - refine Or.elim (em (c z = 0)) (fun o ↦ Or.inr o) (fun o ↦ Or.inl ⟨o, Finset.ext (fun a ↦ ?_)⟩) - simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, - Finset.mem_singleton, and_iff_left_iff_imp] - rintro rfl - assumption - suffices (map (𝟙 X) c g g).toFun z = c.toFun z from this - obtain h | h := this - all_goals simp only [map, mapAux, Scheme.Hom.id_base, TopCat.hom_id, - ContinuousMap.id_apply, ↓reduceIte] - rw[h.2] - simp only [HasDegree.degree_one, mul_one, Finset.sum_singleton, Finset.sum_empty] - · rfl - · exact h.1.symm - -end map - -noncomputable instance instHasDegreeNat : HasDegree ℕ where - degree := Hom.degree - degree_one {M} x := by - dsimp [Hom.degree] - have (R : Type*) [CommSemiring R] : Semiring.toModule (R := R) = - Algebra.toModule (R := R) (A := R) := rfl - have := this (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) - let k := Module.finrank_self (IsLocalRing.ResidueField ↑(M.presheaf.stalk x)) - convert k - rw [this] - simp [moduleResidueFieldExtension] - congr - aesop - -noncomputable instance : HasDegree ℤ where - degree f x := ↑(Hom.degree f x) - degree_one {M} x := by - have := instHasDegreeNat.degree_one x - dsimp [HasDegree.degree] at this - rw [this] - exact Int.ofNat_one - -end AlgebraicCycle From 01b9e614919da4629a61b2e9bac89a10fb17d4fb Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Wed, 1 Apr 2026 18:16:09 +0200 Subject: [PATCH 39/70] Generated new Mathlib.lean --- Mathlib.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib.lean b/Mathlib.lean index db08faf8347dfd..533bfc816a1b17 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -1294,7 +1294,6 @@ public import Mathlib.AlgebraicGeometry.AffineScheme public import Mathlib.AlgebraicGeometry.AffineSpace public import Mathlib.AlgebraicGeometry.AffineTransitionLimit public import Mathlib.AlgebraicGeometry.AlgClosed.Basic -public import Mathlib.AlgebraicGeometry.AlgebraicCycle public import Mathlib.AlgebraicGeometry.Artinian public import Mathlib.AlgebraicGeometry.ColimitsOver public import Mathlib.AlgebraicGeometry.Cover.Directed @@ -7549,6 +7548,7 @@ public import Mathlib.Topology.LocallyConstant.Algebra public import Mathlib.Topology.LocallyConstant.Basic public import Mathlib.Topology.LocallyFinite public import Mathlib.Topology.LocallyFinsupp +public import Mathlib.Topology.LocallyFinsupp.Pushforward public import Mathlib.Topology.Maps.Basic public import Mathlib.Topology.Maps.OpenQuotient public import Mathlib.Topology.Maps.Proper.Basic From c94348969ca0d600a23abdaba357c35f3a790b5d Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Wed, 8 Apr 2026 15:47:46 +0200 Subject: [PATCH 40/70] Some golfing --- .../Topology/LocallyFinsupp/Pushforward.lean | 145 +++++++----------- 1 file changed, 52 insertions(+), 93 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 71b646dbf63baa..81a5e2fedd9f3a 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -35,16 +35,6 @@ namespace locallyFinsupp section Zero variable [Zero R] -/-- -The function taking `x` to some value `coeff`, and every other value to `0` as a -function with locally finite support. --/ -noncomputable -def single (x : X) (coeff : R) : Function.locallyFinsupp X R where - toFun := Set.indicator {x} (Function.const X coeff) - supportWithinDomain' := by simp only [support_indicator]; exact LE.le.subset fun _ a_1 ↦ trivial - supportLocallyFiniteWithinDomain' z hz := - ⟨⊤, ⟨Filter.univ_mem' fun a ↦ trivial, by simp [← Function.const_def, toFinite]⟩⟩ variable (f) in /-- @@ -54,56 +44,42 @@ of a point z : Y along a morphism `f : X ⟶ Y`. def preimageSupport (c : locallyFinsupp X R) (z : Y) : Set X := f ⁻¹' {z} ∩ c.support +class PreimageSupportFinite (c : locallyFinsupp X R) (f : X → Y) : Prop where + preimageSupport_finite' (z : Y) : (preimageSupport f c z).Finite + +omit [TopologicalSpace Y] in +lemma PreimageSupportFinite.preimageSupport_finite (c : locallyFinsupp X R) (f : X → Y) + [h : PreimageSupportFinite c f] (z : Y) : (preimageSupport f c z).Finite := + h.preimageSupport_finite' z + +instance (c : locallyFinsupp X R) (f : X → Y) (hf : IsProperMap f) : + PreimageSupportFinite c f := by + constructor + intro z + exact LocallyFiniteSupport.finite_inter_support_of_isCompact + c.locallyFiniteSupport <| hf.isCompact_preimage isCompact_singleton + end Zero section map variable [Semiring R] {W : TopologicalSpace.Opens Y} (c : Function.locallyFinsupp X R) -lemma preimageSupport_inter_subset : W.carrier ∩ {z | (preimageSupport f c z).Nonempty} ⊆ - f '' (f ⁻¹' ((W.carrier ∩ {z | (preimageSupport f c z).Nonempty})) ∩ c.support) := by - intro a ha - rw [image_preimage_inter] - suffices a ∈ f '' c.support from mem_inter ha this - have := ha.2.some_mem - simp only [preimageSupport, mem_inter_iff, mem_preimage, mem_singleton_iff, - Function.mem_support, ne_eq, mem_image] at this ⊢ - exact ⟨ha.2.some, this.symm⟩ - -lemma preimageSupport_preimage_inter_subset : f ⁻¹' W.carrier ∩ - f ⁻¹' {z | (preimageSupport f c z).Nonempty} ∩ c.support ⊆ - f ⁻¹' W.carrier ∩ (⋃ z : Y, preimageSupport f c z) := by - intro p hp - simp only [Opens.carrier_eq_coe, preimageSupport, preimage_setOf_eq, mem_inter_iff, - mem_preimage, SetLike.mem_coe, mem_setOf_eq, Function.mem_support, ne_eq, mem_iUnion, - mem_singleton_iff, exists_and_right, exists_eq', true_and] at hp ⊢ - exact ⟨hp.1.1, hp.2⟩ - -lemma iUnion_preimage_inter_support_finite_of_isCompact (hf : IsSpectralMap f) - (hW : IsCompact W.1) : (⋃ _ : Y, f ⁻¹' W.carrier ∩ c.support).Finite := by - suffices (f ⁻¹' W.carrier ∩ c.support).Finite by - apply Finite.subset this - intro a ha - simp only [Opens.carrier_eq_coe, mem_iUnion, mem_inter_iff, mem_preimage, - SetLike.mem_coe, Function.mem_support, ne_eq, exists_and_left, exists_const_iff] at ha ⊢ - exact ⟨ha.1, ha.2.2⟩ - exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| - hf.2 W.is_open' hW - -lemma inter_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) : +lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) : (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite := by - refine Finite.subset (Finite.image _ ?_) (preimageSupport_inter_subset c) + suffices (f ⁻¹' (W.carrier ∩ {z | (preimageSupport f c z).Nonempty}) ∩ c.support).Finite from + (this.image f).subset (fun a ha ↦ by grind [preimageSupport, Set.Nonempty]) rw [preimage_inter] - apply Finite.subset _ (preimageSupport_preimage_inter_subset c) - rw [inter_iUnion] - suffices (⋃ i : Y, f ⁻¹' W.carrier ∩ c.support).Finite by + suffices (f ⁻¹' W ∩ ⋃ z, preimageSupport f c z).Finite by apply Finite.subset this - simp only [Opens.carrier_eq_coe, iUnion_subset_iff] - intro y x hx - simp only [mem_inter_iff, mem_preimage, SetLike.mem_coe, - Function.mem_support, ne_eq, mem_iUnion, exists_and_left, exists_const_iff] at hx ⊢ - exact ⟨hx.1, ⟨Nonempty.intro y, hx.2.2⟩⟩ - exact iUnion_preimage_inter_support_finite_of_isCompact c hf hW + rw [Set.inter_assoc] + exact Set.inter_subset_inter_right _ (fun p hp ↦ by simp_all [preimageSupport]) + rw [inter_iUnion] + suffices (f ⁻¹' W.carrier ∩ c.support).Finite by + grind [preimageSupport, Opens.carrier_eq_coe, iUnion_subset_iff, SetLike.mem_coe, + Function.mem_support, Finite.subset] + exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| + hf.2 W.is_open' hW variable {N : Type*} [PrespectralSpace Y] @@ -111,28 +87,23 @@ variable {N : Type*} [PrespectralSpace Y] The pushforward of an algebraic cycle has locally finite support. -/ lemma map_locally_finite (hf : IsSpectralMap f) - (h : ∀ z, (preimageSupport f c z).Finite) : - ∀ z : Y, ∃ t ∈ 𝓝 z, (t ∩ Function.support fun z ↦ - ∑ x ∈ (h z).toFinset, (c x) * w x).Finite := by - intro y - have : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by + [PreimageSupportFinite c f] (y : Y) : + ∃ t ∈ 𝓝 y, (t ∩ Function.support fun z ↦ + ∑ x ∈ (PreimageSupportFinite.preimageSupport_finite c f z).toFinset, (c x) * w x).Finite := by + obtain ⟨W, hW⟩ : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open (by simp : y ∈ ⊤) (by simp) use ⟨U, hU.1.1⟩ exact ⟨hU.1.2, hU.2.1⟩ - obtain ⟨W, hW⟩ := this use W refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by - apply Finite.subset this - apply inter_subset_inter Set.Subset.rfl - intro x - simp only [Function.mem_support, ne_eq, mem_setOf_eq] - contrapose! - intro aux - rw [Finset.sum_eq_zero] - simp_all - exact inter_nonempty_finite c hf hW.1 + apply Finite.subset this + apply inter_subset_inter_right + intro x + contrapose! + simp +contextual [Set.not_nonempty_iff_eq_empty] + exact inter_preimageSupport_nonempty_finite c hf hW.1 variable (f) in /-- @@ -142,24 +113,24 @@ with respect to a weight function `w`. This is mainly used when interpretting lo functions as algebraic cycles (in this case the weight function corresponds to a dimension or codimension function). -/ +@[simps] noncomputable -def map (hf : IsSpectralMap f) (h : ∀ z, (preimageSupport f c z).Finite) : +def map (hf : IsSpectralMap f) [PreimageSupportFinite c f] : Function.locallyFinsupp Y R where - toFun z := (∑ x ∈ (h z).toFinset, (c x) * w x) + toFun z := (∑ x ∈ (PreimageSupportFinite.preimageSupport_finite c f z).toFinset, (c x) * w x) supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf h z + supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf z /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) - (h1 : ∀ z, (preimageSupport f c z).Finite) + [PreimageSupportFinite c f] (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : - (map f w c hf h1).support ⊆ t:= by + (map f w c hf).support ⊆ t:= by intro y hy - simp only [map, preimageSupport, Function.mem_support, - ne_eq] at hy + simp only [map, preimageSupport, Function.mem_support, ne_eq] at hy obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, Function.mem_support, ne_eq] at hx @@ -169,32 +140,20 @@ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) lemma preimageSupport_id (z : X) : (preimageSupport id c z).Finite := by simp [preimageSupport, toFinite ({z} ∩ locallyFinsuppWithin.support c)] +instance : c.PreimageSupportFinite id := ⟨preimageSupport_id c⟩ + /-- The pushforward of `c` along the identity morphism is `c`. -/ @[simp] -lemma map_id [PrespectralSpace X] - (hw : ∀ z : X, w z = 1) : - map id w c isSpectralMap_id (preimageSupport_id c) = c := by +lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : + map id w c isSpectralMap_id = c := by ext z - have : (c z ≠ 0 ∧ (preimageSupport_id c z).toFinset = {z}) ∨ + obtain h | h : (c z ≠ 0 ∧ (preimageSupport_id c z).toFinset = {z}) ∨ (c z = 0 ∧ (preimageSupport_id c z).toFinset = ∅) := by - simp only [ne_eq, Finite.toFinset, preimageSupport, preimage_id_eq, id_eq, toFinset_eq_empty, - singleton_inter_eq_empty, - Function.mem_support, not_not, and_self] - refine Or.elim (em (c z = 0)) (fun o ↦ Or.inr o) (fun o ↦ Or.inl ⟨o, Finset.ext (fun a ↦ ?_)⟩) - simp only [mem_toFinset, mem_inter_iff, mem_singleton_iff, Function.mem_support, ne_eq, - Finset.mem_singleton, and_iff_left_iff_imp] - rintro rfl - assumption - suffices (map id w c isSpectralMap_id (preimageSupport_id c)).toFun z = c.toFun z from this - obtain h | h := this - all_goals simp only [map] - rw[h.2] - simp only [Finset.sum_singleton, Finset.sum_empty] - · rw [hw] - exact MulOneClass.mul_one (c z) - · exact h.1.symm + grind [Finite.toFinset, preimageSupport, Function.mem_support] + · simp_all + · simp_all end map end locallyFinsupp From 69afd421064b4d7eb390708f051a442ddbefb616 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 10 Apr 2026 11:26:02 +0200 Subject: [PATCH 41/70] Fixed some design flaws --- .../Topology/LocallyFinsupp/Pushforward.lean | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 81a5e2fedd9f3a..3a9d4c17a6ceda 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -41,20 +41,22 @@ variable (f) in Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage of a point z : Y along a morphism `f : X ⟶ Y`. -/ -def preimageSupport (c : locallyFinsupp X R) (z : Y) : Set X := +def preimageSupport (c : X → R) (z : Y) : Set X := f ⁻¹' {z} ∩ c.support -class PreimageSupportFinite (c : locallyFinsupp X R) (f : X → Y) : Prop where - preimageSupport_finite' (z : Y) : (preimageSupport f c z).Finite +/-- +A function `f` has finite preimage support with respect to a function `c : X → R` where `R` has a +zero element if its fibers all have finite intersection with the support of `c`. -omit [TopologicalSpace Y] in -lemma PreimageSupportFinite.preimageSupport_finite (c : locallyFinsupp X R) (f : X → Y) - [h : PreimageSupportFinite c f] (z : Y) : (preimageSupport f c z).Finite := - h.preimageSupport_finite' z +This is a nonstandard notion and is mainly here to define the pushforward of algebraic cycles. +In this case, we define the pushforward with respect to quasicompact morphisms which automatically +satisfy this property, so in practice this definition shouldn't be exposed to the user too much. +-/ +def PreimageSupportFinite (c : X → R) (f : X → Y) : Prop := + ∀ (z : Y), (preimageSupport f c z).Finite -instance (c : locallyFinsupp X R) (f : X → Y) (hf : IsProperMap f) : - PreimageSupportFinite c f := by - constructor +lemma _root_.IsProperMap.preimageSupportFinite (c : locallyFinsupp X R) + (f : X → Y) (hf : IsProperMap f) : PreimageSupportFinite c f := by intro z exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| hf.isCompact_preimage isCompact_singleton @@ -87,9 +89,9 @@ variable {N : Type*} [PrespectralSpace Y] The pushforward of an algebraic cycle has locally finite support. -/ lemma map_locally_finite (hf : IsSpectralMap f) - [PreimageSupportFinite c f] (y : Y) : + (hf' : PreimageSupportFinite c f) (y : Y) : ∃ t ∈ 𝓝 y, (t ∩ Function.support fun z ↦ - ∑ x ∈ (PreimageSupportFinite.preimageSupport_finite c f z).toFinset, (c x) * w x).Finite := by + ∑ x ∈ (hf' z).toFinset, (c x) * w x).Finite := by obtain ⟨W, hW⟩ : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open (by simp : y ∈ ⊤) (by simp) @@ -115,20 +117,20 @@ codimension function). -/ @[simps] noncomputable -def map (hf : IsSpectralMap f) [PreimageSupportFinite c f] : +def map (hf : IsSpectralMap f) (hf' : PreimageSupportFinite c f) : Function.locallyFinsupp Y R where - toFun z := (∑ x ∈ (PreimageSupportFinite.preimageSupport_finite c f z).toFinset, (c x) * w x) + toFun z := (∑ x ∈ (hf' z).toFinset, (c x) * w x) supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf z + supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf hf' z /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) - [PreimageSupportFinite c f] + (hf' : PreimageSupportFinite c f) (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : - (map f w c hf).support ⊆ t:= by + (map f w c hf hf').support ⊆ t:= by intro y hy simp only [map, preimageSupport, Function.mem_support, ne_eq] at hy obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy @@ -140,14 +142,16 @@ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) lemma preimageSupport_id (z : X) : (preimageSupport id c z).Finite := by simp [preimageSupport, toFinite ({z} ∩ locallyFinsuppWithin.support c)] -instance : c.PreimageSupportFinite id := ⟨preimageSupport_id c⟩ +lemma preimageSupportFinite_id : PreimageSupportFinite c id := by + intro z + simp [preimageSupport, toFinite ({z} ∩ locallyFinsuppWithin.support c)] /-- The pushforward of `c` along the identity morphism is `c`. -/ @[simp] lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : - map id w c isSpectralMap_id = c := by + map id w c isSpectralMap_id (preimageSupportFinite_id c) = c := by ext z obtain h | h : (c z ≠ 0 ∧ (preimageSupport_id c z).toFinset = {z}) ∨ (c z = 0 ∧ (preimageSupport_id c z).toFinset = ∅) := by From 866be859df5fde011272efc99c0519db82b9ea97 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 16 Apr 2026 14:36:18 +0200 Subject: [PATCH 42/70] Various minor fixes --- .../Topology/LocallyFinsupp/Pushforward.lean | 43 +++++++------------ 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 3a9d4c17a6ceda..3f2ae079796ea0 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -5,12 +5,9 @@ Authors: Raphael Douglas Giles -/ module -public import Mathlib.Combinatorics.Quiver.ReflQuiver -public import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition public import Mathlib.Topology.LocallyFinsupp -public import Mathlib.Algebra.GradedMonoid -public import Mathlib.Algebra.DirectSum.Decomposition -public import Mathlib.Topology.Spectral.ConstructibleTopology +public import Mathlib.Data.Finite.Defs +public import Mathlib.Topology.Spectral.Prespectral /-! # Pushforward of functions with locally finite support @@ -24,7 +21,7 @@ than usual. @[expose] public section -open Set Order Topology TopologicalSpace CategoryTheory +open Set Order Topology TopologicalSpace universe u v variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] @@ -38,8 +35,8 @@ variable [Zero R] variable (f) in /-- -Implementation detail for the pushforward; the support of a cycle on X intersected with the preimage -of a point z : Y along a morphism `f : X ⟶ Y`. +Implementation detail for the pushforward; the support of a locally finsupp function on `X` +intersected with the preimage of a point `z : Y` along a function `f : X ⟶ Y`. -/ def preimageSupport (c : X → R) (z : Y) : Set X := f ⁻¹' {z} ∩ c.support @@ -59,7 +56,7 @@ lemma _root_.IsProperMap.preimageSupportFinite (c : locallyFinsupp X R) (f : X → Y) (hf : IsProperMap f) : PreimageSupportFinite c f := by intro z exact LocallyFiniteSupport.finite_inter_support_of_isCompact - c.locallyFiniteSupport <| hf.isCompact_preimage isCompact_singleton + c.locallyFiniteSupport <| hf.isCompact_preimage isCompact_singleton end Zero @@ -85,9 +82,6 @@ lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompa variable {N : Type*} [PrespectralSpace Y] -/-- -The pushforward of an algebraic cycle has locally finite support. --/ lemma map_locally_finite (hf : IsSpectralMap f) (hf' : PreimageSupportFinite c f) (y : Y) : ∃ t ∈ 𝓝 y, (t ∩ Function.support fun z ↦ @@ -111,15 +105,13 @@ variable (f) in /-- The pushforward of a function `c` of locally finite support by a spectral map whose fibers intersect `c` in finitely many places -with respect to a weight function `w`. This is mainly used when interpretting locally fin supp +with respect to a weight function `w`. This is mainly used when interpreting locally finsupp functions as algebraic cycles (in this case the weight function corresponds to a dimension or codimension function). -/ @[simps] noncomputable -def map (hf : IsSpectralMap f) (hf' : PreimageSupportFinite c f) : - Function.locallyFinsupp Y R - where +def map (hf : IsSpectralMap f) (hf' : PreimageSupportFinite c f) : Function.locallyFinsupp Y R where toFun z := (∑ x ∈ (hf' z).toFinset, (c x) * w x) supportWithinDomain' := by simp supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf hf' z @@ -127,10 +119,10 @@ def map (hf : IsSpectralMap f) (hf' : PreimageSupportFinite c f) : /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ -lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) +lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) (hf' : PreimageSupportFinite c f) (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : - (map f w c hf hf').support ⊆ t:= by + (map f w c hf hf').support ⊆ t := by intro y hy simp only [map, preimageSupport, Function.mem_support, ne_eq] at hy obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy @@ -139,9 +131,6 @@ lemma map_homogeneneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) specialize h x (hc hx.1.2) grind -lemma preimageSupport_id (z : X) : (preimageSupport id c z).Finite := by - simp [preimageSupport, toFinite ({z} ∩ locallyFinsuppWithin.support c)] - lemma preimageSupportFinite_id : PreimageSupportFinite c id := by intro z simp [preimageSupport, toFinite ({z} ∩ locallyFinsuppWithin.support c)] @@ -152,12 +141,12 @@ The pushforward of `c` along the identity morphism is `c`. @[simp] lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : map id w c isSpectralMap_id (preimageSupportFinite_id c) = c := by - ext z - obtain h | h : (c z ≠ 0 ∧ (preimageSupport_id c z).toFinset = {z}) ∨ - (c z = 0 ∧ (preimageSupport_id c z).toFinset = ∅) := by - grind [Finite.toFinset, preimageSupport, Function.mem_support] - · simp_all - · simp_all + ext z + obtain h | h : (c z ≠ 0 ∧ (preimageSupportFinite_id c z).toFinset = {z}) ∨ + (c z = 0 ∧ (preimageSupportFinite_id c z).toFinset = ∅) := by + grind [Finite.toFinset, preimageSupport, Function.mem_support] + · simp_all + · simp_all end map end locallyFinsupp From bb5278fd1650c494e8d53a2b768512f7cf18713e Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Wed, 22 Apr 2026 17:43:05 +0200 Subject: [PATCH 43/70] WIP --- .../AlgebraicCycle/Basic.lean | 95 +++++++++++++++++++ Mathlib/Topology/LocallyFinsupp.lean | 21 ++-- .../Topology/LocallyFinsupp/Pushforward.lean | 8 +- 3 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean new file mode 100644 index 00000000000000..e1d9e9c96bdbf8 --- /dev/null +++ b/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean @@ -0,0 +1,95 @@ +/- +Copyright (c) 2026 Raphael Douglas Giles. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Raphael Douglas Giles +-/ +module + +public import Mathlib.AlgebraicGeometry.Scheme +public import Mathlib.Topology.LocallyFinsupp.Pushforward +public import Mathlib.AlgebraicGeometry.Properties +public import Mathlib.AlgebraicGeometry.Morphisms.QuasiCompact +public import Mathlib.AlgebraicGeometry.Fiber + +/-! +# Algebraic Cycles + +In this file we define algebraic cycles on a scheme `X` with coefficients in a type `R` and provide +some basic API for working with them. We define an algebraic cycle on a scheme `X` with +coefficients in a type `R` to be functions `c : X → R` whose support is locally finite. + +Here we're making use of the equivalence between irreducible closed subsets of a scheme and their +generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly +nonstandard definition. +-/ + +@[expose] public section + +open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace + CategoryTheory + +universe u v +variable {X Y : Scheme.{u}} {R : Type*} +#check Finsupp.supported +/-- +Algebraic cycle on a scheme `X` with coefficients in a type `Z` is just a function from `X` to `Z` +with locally finite support. + +Here we're making use of the equivalence between irreducible closed subsets of a scheme and their +generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly +nonstandard definition. +-/ +abbrev AlgebraicCycle (X : Scheme.{u}) (R : Type*) [Zero R] := + Function.locallyFinsupp X R + +variable (f : X ⟶ Y) [Semiring R] (c : AlgebraicCycle X R) (x : X) (z : Y) + +noncomputable +instance moduleResidueFieldExtension (x : X) : + Module (IsLocalRing.ResidueField ↑(Y.presheaf.stalk (f x))) + (IsLocalRing.ResidueField ↑(X.presheaf.stalk x)) := + letI := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom) + Algebra.toModule + +/-- +Degree of `f` at a point `x` is defined to be the degree of the associated field extension +from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is either infinite +or undefined. +-/ +noncomputable +def _root_.AlgebraicGeometry.Scheme.Hom.degree : ℕ := @Module.finrank + (IsLocalRing.ResidueField (Y.presheaf.stalk (f.base x))) + (IsLocalRing.ResidueField (X.presheaf.stalk x)) _ _ _ + +namespace AlgebraicCycle + +/-- +Implementation detail for pushforward: function used to define the coefficient of the pushforward +of a cycle `c` at a point `z = f x`, as in stacks `02R3`. +-/ +noncomputable +def mapAux {N : Type*} [DecidableEq N] {Y : Scheme} (f : X ⟶ Y) (wx : X → N) (wy : Y → N) (x : X) : + ℕ := if wx x = wy (f.base x) then f.degree x else 0 + +open Function locallyFinsupp +lemma _root_.AlgebraicGeometry.Scheme.Hom.preimageSupportFinite [QuasiCompact f] : + PreimageSupportFinite c f := + fun z ↦ LocallyFiniteSupport.finite_inter_support_of_isCompact c.Function.locallyFinsuppWithin.locallyFiniteSupportWithin <| + AlgebraicGeometry.Scheme.Hom.isCompact_preimage_singleton f z + +/-- +The pushforward of algebraic cycles with respect to a quasicompact morphism of schemes. The +arguments `wx` and `wy` are certain weight functions used to calculate how the weights of the +algebraic cycle should be adjusted to make the pushforward operation functorial. Typically in +applications these will be some notions of dimension or codimension. The most common notion of +dimension is `Order.height`, and the most common notion of codimension is `Order.coheight`, though +more sophisticated notions exist in the literature which are useful when sufficient +equidimensionality hypotheses cannot be assumed. +-/ +noncomputable +def pushforward [QuasiCompact f] {N : Type*} [DecidableEq N] (c : AlgebraicCycle X R) + (wx : X → N) (wy : Y → N) : AlgebraicCycle Y R := + Function.locallyFinsupp.map f (Nat.cast (R := R) <| mapAux f wx wy ·) c + f.isSpectralMap (f.preimageSupportFinite c) + +end AlgebraicCycle diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 80612fc9ca39a6..7e601feb383117 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -88,18 +88,23 @@ theorem supportDiscreteWithin_iff_locallyFiniteWithin [T1Space X] [Zero Y] {f : A function `f : X → Y` has locally finite support if for every `z : X`, there is a neighbourhood `t` around `z` such that `t ∩ f.support` is finite. -/ -def LocallyFiniteSupport [Zero Y] (f : X → Y) : Prop := - ∀ z : X, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support) +def LocallyFiniteSupportWithin (U : Set X) [Zero Y] (f : X → Y) : Prop := + ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support) + +abbrev LocallyFiniteSupport [Zero Y] (f : X → Y) : Prop := LocallyFiniteSupportWithin univ f lemma LocallyFiniteSupport.iff_locallyFinite_support [Zero Y] (f : X → Y) : LocallyFinite (fun s : f.support ↦ ({s.val} : Set X)) ↔ LocallyFiniteSupport f := by dsimp only [LocallyFinite] - peel with z t ht + peel with z + simp only [singleton_inter_nonempty, mem_univ, forall_const] + peel with t ht have aux1 : t ∩ f.support = {i : f.support | ↑i ∈ t} := by aesop have aux2 : InjOn Subtype.val {i : f.support | ↑i ∈ t} := by aesop - simp only [singleton_inter_nonempty, aux1, finite_image_iff aux2] + simp only [aux1, finite_image_iff aux2] -lemma LocallyFiniteSupport.locallyFinite_support [Zero Y] (f : X → Y) (h : LocallyFiniteSupport f) : +lemma LocallyFiniteSupport.locallyFinite_support [Zero Y] (f : X → Y) + (h : LocallyFiniteSupport f) : LocallyFinite (fun s : f.support ↦ ({s.val} : Set X)) := (LocallyFiniteSupport.iff_locallyFinite_support f).mpr h @@ -112,9 +117,9 @@ lemma LocallyFiniteSupport.finite_inter_support_of_isCompact {W : Set X} rw [← lem f.support W] exact Finite.image Subtype.val this -lemma Function.locallyFinsupp.locallyFiniteSupport [Zero Y] (f : locallyFinsupp X Y) : - LocallyFiniteSupport f.toFun := - (f.supportLocallyFiniteWithinDomain' · (by trivial)) +lemma Function.locallyFinsuppWithin.locallyFiniteSupportWithin [Zero Y] + (f : locallyFinsuppWithin U Y) : LocallyFiniteSupportWithin U f.toFun := + f.supportLocallyFiniteWithinDomain' namespace Function.locallyFinsuppWithin diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 3f2ae079796ea0..70f44cfcf762da 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -25,7 +25,7 @@ open Set Order Topology TopologicalSpace universe u v variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] - {f : X → Y} (hf : IsSpectralMap f) (w : X → R) + {f : X → Y} (hf : IsSpectralMap f) (w : X → R) {U : Set X} namespace Function namespace locallyFinsupp @@ -51,8 +51,8 @@ satisfy this property, so in practice this definition shouldn't be exposed to th -/ def PreimageSupportFinite (c : X → R) (f : X → Y) : Prop := ∀ (z : Y), (preimageSupport f c z).Finite - -lemma _root_.IsProperMap.preimageSupportFinite (c : locallyFinsupp X R) +#check Function.locallyFinsuppWithin +lemma _root_.IsProperMap.preimageSupportFinite (c : locallyFinsuppWithin U R) (f : X → Y) (hf : IsProperMap f) : PreimageSupportFinite c f := by intro z exact LocallyFiniteSupport.finite_inter_support_of_isCompact @@ -77,7 +77,7 @@ lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompa suffices (f ⁻¹' W.carrier ∩ c.support).Finite by grind [preimageSupport, Opens.carrier_eq_coe, iUnion_subset_iff, SetLike.mem_coe, Function.mem_support, Finite.subset] - exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| + exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.Function.locallyFinsuppWithin.locallyFiniteSupportWithin <| hf.2 W.is_open' hW variable {N : Type*} [PrespectralSpace Y] From 97ebd219ff6ba8bb239a414dcd6674ff2de9e382 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 23 Apr 2026 20:36:13 +0200 Subject: [PATCH 44/70] Revert "WIP" This reverts commit bb5278fd1650c494e8d53a2b768512f7cf18713e. --- .../AlgebraicCycle/Basic.lean | 95 ------------------- Mathlib/Topology/LocallyFinsupp.lean | 21 ++-- .../Topology/LocallyFinsupp/Pushforward.lean | 8 +- 3 files changed, 12 insertions(+), 112 deletions(-) delete mode 100644 Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean diff --git a/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean b/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean deleted file mode 100644 index e1d9e9c96bdbf8..00000000000000 --- a/Mathlib/AlgebraicGeometry/AlgebraicCycle/Basic.lean +++ /dev/null @@ -1,95 +0,0 @@ -/- -Copyright (c) 2026 Raphael Douglas Giles. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Raphael Douglas Giles --/ -module - -public import Mathlib.AlgebraicGeometry.Scheme -public import Mathlib.Topology.LocallyFinsupp.Pushforward -public import Mathlib.AlgebraicGeometry.Properties -public import Mathlib.AlgebraicGeometry.Morphisms.QuasiCompact -public import Mathlib.AlgebraicGeometry.Fiber - -/-! -# Algebraic Cycles - -In this file we define algebraic cycles on a scheme `X` with coefficients in a type `R` and provide -some basic API for working with them. We define an algebraic cycle on a scheme `X` with -coefficients in a type `R` to be functions `c : X → R` whose support is locally finite. - -Here we're making use of the equivalence between irreducible closed subsets of a scheme and their -generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly -nonstandard definition. --/ - -@[expose] public section - -open AlgebraicGeometry Set Order LocallyRingedSpace Topology TopologicalSpace - CategoryTheory - -universe u v -variable {X Y : Scheme.{u}} {R : Type*} -#check Finsupp.supported -/-- -Algebraic cycle on a scheme `X` with coefficients in a type `Z` is just a function from `X` to `Z` -with locally finite support. - -Here we're making use of the equivalence between irreducible closed subsets of a scheme and their -generic points in order to reuse the API in Function.locallyFinsupp, hence the slightly -nonstandard definition. --/ -abbrev AlgebraicCycle (X : Scheme.{u}) (R : Type*) [Zero R] := - Function.locallyFinsupp X R - -variable (f : X ⟶ Y) [Semiring R] (c : AlgebraicCycle X R) (x : X) (z : Y) - -noncomputable -instance moduleResidueFieldExtension (x : X) : - Module (IsLocalRing.ResidueField ↑(Y.presheaf.stalk (f x))) - (IsLocalRing.ResidueField ↑(X.presheaf.stalk x)) := - letI := RingHom.toAlgebra (IsLocalRing.ResidueField.map (f.stalkMap x).hom) - Algebra.toModule - -/-- -Degree of `f` at a point `x` is defined to be the degree of the associated field extension -from `κ(f x)` to `κ(x)`. We return a default value of zero when this degree is either infinite -or undefined. --/ -noncomputable -def _root_.AlgebraicGeometry.Scheme.Hom.degree : ℕ := @Module.finrank - (IsLocalRing.ResidueField (Y.presheaf.stalk (f.base x))) - (IsLocalRing.ResidueField (X.presheaf.stalk x)) _ _ _ - -namespace AlgebraicCycle - -/-- -Implementation detail for pushforward: function used to define the coefficient of the pushforward -of a cycle `c` at a point `z = f x`, as in stacks `02R3`. --/ -noncomputable -def mapAux {N : Type*} [DecidableEq N] {Y : Scheme} (f : X ⟶ Y) (wx : X → N) (wy : Y → N) (x : X) : - ℕ := if wx x = wy (f.base x) then f.degree x else 0 - -open Function locallyFinsupp -lemma _root_.AlgebraicGeometry.Scheme.Hom.preimageSupportFinite [QuasiCompact f] : - PreimageSupportFinite c f := - fun z ↦ LocallyFiniteSupport.finite_inter_support_of_isCompact c.Function.locallyFinsuppWithin.locallyFiniteSupportWithin <| - AlgebraicGeometry.Scheme.Hom.isCompact_preimage_singleton f z - -/-- -The pushforward of algebraic cycles with respect to a quasicompact morphism of schemes. The -arguments `wx` and `wy` are certain weight functions used to calculate how the weights of the -algebraic cycle should be adjusted to make the pushforward operation functorial. Typically in -applications these will be some notions of dimension or codimension. The most common notion of -dimension is `Order.height`, and the most common notion of codimension is `Order.coheight`, though -more sophisticated notions exist in the literature which are useful when sufficient -equidimensionality hypotheses cannot be assumed. --/ -noncomputable -def pushforward [QuasiCompact f] {N : Type*} [DecidableEq N] (c : AlgebraicCycle X R) - (wx : X → N) (wy : Y → N) : AlgebraicCycle Y R := - Function.locallyFinsupp.map f (Nat.cast (R := R) <| mapAux f wx wy ·) c - f.isSpectralMap (f.preimageSupportFinite c) - -end AlgebraicCycle diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 7e601feb383117..80612fc9ca39a6 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -88,23 +88,18 @@ theorem supportDiscreteWithin_iff_locallyFiniteWithin [T1Space X] [Zero Y] {f : A function `f : X → Y` has locally finite support if for every `z : X`, there is a neighbourhood `t` around `z` such that `t ∩ f.support` is finite. -/ -def LocallyFiniteSupportWithin (U : Set X) [Zero Y] (f : X → Y) : Prop := - ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support) - -abbrev LocallyFiniteSupport [Zero Y] (f : X → Y) : Prop := LocallyFiniteSupportWithin univ f +def LocallyFiniteSupport [Zero Y] (f : X → Y) : Prop := + ∀ z : X, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support) lemma LocallyFiniteSupport.iff_locallyFinite_support [Zero Y] (f : X → Y) : LocallyFinite (fun s : f.support ↦ ({s.val} : Set X)) ↔ LocallyFiniteSupport f := by dsimp only [LocallyFinite] - peel with z - simp only [singleton_inter_nonempty, mem_univ, forall_const] - peel with t ht + peel with z t ht have aux1 : t ∩ f.support = {i : f.support | ↑i ∈ t} := by aesop have aux2 : InjOn Subtype.val {i : f.support | ↑i ∈ t} := by aesop - simp only [aux1, finite_image_iff aux2] + simp only [singleton_inter_nonempty, aux1, finite_image_iff aux2] -lemma LocallyFiniteSupport.locallyFinite_support [Zero Y] (f : X → Y) - (h : LocallyFiniteSupport f) : +lemma LocallyFiniteSupport.locallyFinite_support [Zero Y] (f : X → Y) (h : LocallyFiniteSupport f) : LocallyFinite (fun s : f.support ↦ ({s.val} : Set X)) := (LocallyFiniteSupport.iff_locallyFinite_support f).mpr h @@ -117,9 +112,9 @@ lemma LocallyFiniteSupport.finite_inter_support_of_isCompact {W : Set X} rw [← lem f.support W] exact Finite.image Subtype.val this -lemma Function.locallyFinsuppWithin.locallyFiniteSupportWithin [Zero Y] - (f : locallyFinsuppWithin U Y) : LocallyFiniteSupportWithin U f.toFun := - f.supportLocallyFiniteWithinDomain' +lemma Function.locallyFinsupp.locallyFiniteSupport [Zero Y] (f : locallyFinsupp X Y) : + LocallyFiniteSupport f.toFun := + (f.supportLocallyFiniteWithinDomain' · (by trivial)) namespace Function.locallyFinsuppWithin diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 70f44cfcf762da..3f2ae079796ea0 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -25,7 +25,7 @@ open Set Order Topology TopologicalSpace universe u v variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] - {f : X → Y} (hf : IsSpectralMap f) (w : X → R) {U : Set X} + {f : X → Y} (hf : IsSpectralMap f) (w : X → R) namespace Function namespace locallyFinsupp @@ -51,8 +51,8 @@ satisfy this property, so in practice this definition shouldn't be exposed to th -/ def PreimageSupportFinite (c : X → R) (f : X → Y) : Prop := ∀ (z : Y), (preimageSupport f c z).Finite -#check Function.locallyFinsuppWithin -lemma _root_.IsProperMap.preimageSupportFinite (c : locallyFinsuppWithin U R) + +lemma _root_.IsProperMap.preimageSupportFinite (c : locallyFinsupp X R) (f : X → Y) (hf : IsProperMap f) : PreimageSupportFinite c f := by intro z exact LocallyFiniteSupport.finite_inter_support_of_isCompact @@ -77,7 +77,7 @@ lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompa suffices (f ⁻¹' W.carrier ∩ c.support).Finite by grind [preimageSupport, Opens.carrier_eq_coe, iUnion_subset_iff, SetLike.mem_coe, Function.mem_support, Finite.subset] - exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.Function.locallyFinsuppWithin.locallyFiniteSupportWithin <| + exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| hf.2 W.is_open' hW variable {N : Type*} [PrespectralSpace Y] From 532f9e207e65ca94bcd114ccae01e61dd8e78b09 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Tue, 28 Apr 2026 13:41:13 +0200 Subject: [PATCH 45/70] Expanded on comments --- .../Topology/LocallyFinsupp/Pushforward.lean | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 3f2ae079796ea0..7b86c4f5964086 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -6,8 +6,7 @@ Authors: Raphael Douglas Giles module public import Mathlib.Topology.LocallyFinsupp -public import Mathlib.Data.Finite.Defs -public import Mathlib.Topology.Spectral.Prespectral +public import Mathlib.Topology.Spectral.Basic /-! # Pushforward of functions with locally finite support @@ -17,6 +16,14 @@ between prespectral spaces. This is a nonstandard notion that arises because of mathlib to model algebraic cycles as functions with locally finite support. This makes it so that standard notions in the theory of cycles can be defined in more generality than usual. + +In the usual definition of the proper pushforward of algebraic cycles, one needs to adjust the +coefficients by scaling by the degree of the corresponding extension of residue fields (assuming +the dimensions are the same and hence that this is a finite extension), or in the case where the +dimensions of the points differ scaling by zero. This is described in more detail in stacks 02R4. +The exact values of this scaling function are not relevant for the mere construction of the +pushforward, so our definition of the pushforward of a cycle `c` on a scheme `X` with coefficients +in `R` is done with respect to some `w : X → R`, about which we do not assume anything. -/ @[expose] public section @@ -105,9 +112,10 @@ variable (f) in /-- The pushforward of a function `c` of locally finite support by a spectral map whose fibers intersect `c` in finitely many places -with respect to a weight function `w`. This is mainly used when interpreting locally finsupp -functions as algebraic cycles (in this case the weight function corresponds to a dimension or -codimension function). +with respect to a weight function `w`. This is mainly used when interpretting locally fin supp +functions as algebraic cycles (in this case the weight function would be as described in stacks +02R4, where the weight function is the degree of the corresponding extension of residue fields +if the dimensions of the points correspond, and is zero otherwise). -/ @[simps] noncomputable From de7d996103f47dcb06418da00a36d81a495405cd Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Fri, 1 May 2026 15:13:32 +0200 Subject: [PATCH 46/70] Removed the preimageSupport business --- .../Topology/LocallyFinsupp/Pushforward.lean | 79 ++++++------------- 1 file changed, 24 insertions(+), 55 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 7b86c4f5964086..f5f9f64f0b2a4d 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -37,62 +37,32 @@ variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] namespace Function namespace locallyFinsupp -section Zero -variable [Zero R] - -variable (f) in -/-- -Implementation detail for the pushforward; the support of a locally finsupp function on `X` -intersected with the preimage of a point `z : Y` along a function `f : X ⟶ Y`. --/ -def preimageSupport (c : X → R) (z : Y) : Set X := - f ⁻¹' {z} ∩ c.support - -/-- -A function `f` has finite preimage support with respect to a function `c : X → R` where `R` has a -zero element if its fibers all have finite intersection with the support of `c`. - -This is a nonstandard notion and is mainly here to define the pushforward of algebraic cycles. -In this case, we define the pushforward with respect to quasicompact morphisms which automatically -satisfy this property, so in practice this definition shouldn't be exposed to the user too much. --/ -def PreimageSupportFinite (c : X → R) (f : X → Y) : Prop := - ∀ (z : Y), (preimageSupport f c z).Finite - -lemma _root_.IsProperMap.preimageSupportFinite (c : locallyFinsupp X R) - (f : X → Y) (hf : IsProperMap f) : PreimageSupportFinite c f := by - intro z - exact LocallyFiniteSupport.finite_inter_support_of_isCompact - c.locallyFiniteSupport <| hf.isCompact_preimage isCompact_singleton - -end Zero - section map variable [Semiring R] {W : TopologicalSpace.Opens Y} (c : Function.locallyFinsupp X R) lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) : - (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite := by - suffices (f ⁻¹' (W.carrier ∩ {z | (preimageSupport f c z).Nonempty}) ∩ c.support).Finite from - (this.image f).subset (fun a ha ↦ by grind [preimageSupport, Set.Nonempty]) + (W.carrier ∩ {z : Y | (f ⁻¹' {z} ∩ c.support).Nonempty}).Finite := by + suffices (f ⁻¹' (W.carrier ∩ {z | (f ⁻¹' {z} ∩ c.support).Nonempty}) ∩ c.support).Finite from + (this.image f).subset (fun a ha ↦ by grind [Set.Nonempty]) rw [preimage_inter] - suffices (f ⁻¹' W ∩ ⋃ z, preimageSupport f c z).Finite by + suffices (f ⁻¹' W ∩ ⋃ z, f ⁻¹' {z} ∩ c.support).Finite by apply Finite.subset this rw [Set.inter_assoc] - exact Set.inter_subset_inter_right _ (fun p hp ↦ by simp_all [preimageSupport]) + exact Set.inter_subset_inter_right _ (fun p hp ↦ by simp_all) rw [inter_iUnion] suffices (f ⁻¹' W.carrier ∩ c.support).Finite by - grind [preimageSupport, Opens.carrier_eq_coe, iUnion_subset_iff, SetLike.mem_coe, + grind [Opens.carrier_eq_coe, iUnion_subset_iff, SetLike.mem_coe, Function.mem_support, Finite.subset] exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| hf.2 W.is_open' hW variable {N : Type*} [PrespectralSpace Y] -lemma map_locally_finite (hf : IsSpectralMap f) - (hf' : PreimageSupportFinite c f) (y : Y) : +lemma map_locally_finite (hf : IsSpectralMap f) (hf' : ∀ y : Y, IsCompact <| f ⁻¹' {y}) (y : Y) : ∃ t ∈ 𝓝 y, (t ∩ Function.support fun z ↦ - ∑ x ∈ (hf' z).toFinset, (c x) * w x).Finite := by + ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, + (c x) * w x).Finite := by obtain ⟨W, hW⟩ : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open (by simp : y ∈ ⊤) (by simp) @@ -100,12 +70,13 @@ lemma map_locally_finite (hf : IsSpectralMap f) exact ⟨hU.1.2, hU.2.1⟩ use W refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ - suffices (W.carrier ∩ {z : Y | (preimageSupport f c z).Nonempty}).Finite by + suffices (W.carrier ∩ {z : Y | (f ⁻¹' {z} ∩ support c.toFun).Nonempty}).Finite by apply Finite.subset this apply inter_subset_inter_right intro x contrapose! - simp +contextual [Set.not_nonempty_iff_eq_empty] + simp +contextual only [mem_setOf_eq, not_nonempty_iff_eq_empty, mem_support, toFinite_toFinset, + toFinset_empty, Finset.sum_empty, ne_eq, not_true_eq_false, not_false_eq_true, implies_true] exact inter_preimageSupport_nonempty_finite c hf hW.1 variable (f) in @@ -119,8 +90,10 @@ if the dimensions of the points correspond, and is zero otherwise). -/ @[simps] noncomputable -def map (hf : IsSpectralMap f) (hf' : PreimageSupportFinite c f) : Function.locallyFinsupp Y R where - toFun z := (∑ x ∈ (hf' z).toFinset, (c x) * w x) +def map (hf : IsSpectralMap f) (hf' : ∀ y : Y, IsCompact <| f ⁻¹' {y}) : + Function.locallyFinsupp Y R where + toFun z := ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, + (c x) * w x supportWithinDomain' := by simp supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf hf' z @@ -128,33 +101,29 @@ def map (hf : IsSpectralMap f) (hf' : PreimageSupportFinite c f) : Function.loca Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) - (hf' : PreimageSupportFinite c f) + (hf' : ∀ y : Y, IsCompact <| f ⁻¹' {y}) (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : (map f w c hf hf').support ⊆ t := by intro y hy - simp only [map, preimageSupport, Function.mem_support, ne_eq] at hy + simp only [map, Function.mem_support, ne_eq] at hy obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, Function.mem_support, ne_eq] at hx specialize h x (hc hx.1.2) grind -lemma preimageSupportFinite_id : PreimageSupportFinite c id := by - intro z - simp [preimageSupport, toFinite ({z} ∩ locallyFinsuppWithin.support c)] - /-- The pushforward of `c` along the identity morphism is `c`. -/ @[simp] lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : - map id w c isSpectralMap_id (preimageSupportFinite_id c) = c := by + map id w c isSpectralMap_id (by simp) = c := by + classical ext z - obtain h | h : (c z ≠ 0 ∧ (preimageSupportFinite_id c z).toFinset = {z}) ∨ - (c z = 0 ∧ (preimageSupportFinite_id c z).toFinset = ∅) := by - grind [Finite.toFinset, preimageSupport, Function.mem_support] - · simp_all - · simp_all + change ∑ x ∈ _, c x * w x = c z + rw [show (Set.Finite.toFinset _ : Finset X) = if c z = 0 then ∅ else {z} from by + ext; split_ifs <;> aesop] + split_ifs with h <;> simp [hw, h] end map end locallyFinsupp From 0e78821d7a7580badd8f202bffe49504ab3700d0 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 4 May 2026 10:19:57 +0200 Subject: [PATCH 47/70] WIP --- .../Spectral/ConstructibleTopology.lean | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 9f4d1e23436662..3eb5cb7d601cb0 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -154,3 +154,34 @@ instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] · rw [← Set.sInter_union] refine hB.prop.2.1 (_ ∪ F) ?_ <| (hA₁'.diff.union hA₂'.diff).union hF grind [Set.diff_singleton_subset_iff, Set.union_subset_iff] + +variable {Y : Type*} [TopologicalSpace Y] + +abbrev HasCompactFibers (f : X → Y) : Prop := ∀ y, IsCompact (f ⁻¹' {y}) + +lemma IsProperMap.hasCompactFibers {f : X → Y} (hf : IsProperMap f) : HasCompactFibers f := sorry + +lemma fdsujb [PrespectralSpace X] [T0Space X] [QuasiSober X] : + T2Space <| WithConstructibleTopology X := by + constructor + intro x y hxy + #check t0Space_iff_not_inseparable + --#check exists_isOpen_xor_mem + --have := exists_isOpen_xor_mem + sorry + +/-- +A spectral map between *quasi-separated* quasispectral, sober spaces has compact fibers. +Somewhat strangely, this is the strongest such statement we can figure out how to show. +This is a bit strange because compactness of fibers is a purely topological property, +and yet there is an analogous theorem in algebraic geometry saying that the fibers of a quasicompact +morphism are quasicompact. The underlying space of a scheme is precisely a topological space which +is locally a spectral space, which notably does not necessarily have any global quasi-separatedness +assumptions. However, the proof of this fact is very algebraic (utilizing the fact that +quasi-compactness of morphisms is closed under base change). So, we have that this purely +topological property of quasicompact morphisms of schemes seems to be entirely a consequence of +algebra. +-/ +lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSeparatedSpace X] + [PrespectralSpace Y] [T0Space Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf : IsSpectralMap f) : + HasCompactFibers f := sorry From f6c7ed9baac34592518aa012aa58107bfd29ebdc Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 4 May 2026 20:46:45 +0200 Subject: [PATCH 48/70] Added in HasCompactFibers and gave the example for why it is not automatic from topological assumptions --- Mathlib/Topology/Compactness/Compact.lean | 2 + .../Topology/LocallyFinsupp/Pushforward.lean | 9 +- Mathlib/Topology/Maps/Proper/Basic.lean | 3 + .../Spectral/ConstructibleTopology.lean | 104 +++++++++++++++--- 4 files changed, 100 insertions(+), 18 deletions(-) diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index d4ea8909a123de..ae75cb065249c3 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -1222,3 +1222,5 @@ theorem IsClosed.exists_minimal_nonempty_closed_subset [CompactSpace X] {S : Set rw [← this, compl_compl] end Compact + +abbrev HasCompactFibers (f : X → Y) : Prop := ∀ y, IsCompact (f ⁻¹' {y}) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index f5f9f64f0b2a4d..53c1ba7d3669d7 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -59,7 +59,7 @@ lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompa variable {N : Type*} [PrespectralSpace Y] -lemma map_locally_finite (hf : IsSpectralMap f) (hf' : ∀ y : Y, IsCompact <| f ⁻¹' {y}) (y : Y) : +lemma map_locally_finite (hf : IsSpectralMap f) (hf' : HasCompactFibers f) (y : Y) : ∃ t ∈ 𝓝 y, (t ∩ Function.support fun z ↦ ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, (c x) * w x).Finite := by @@ -90,7 +90,7 @@ if the dimensions of the points correspond, and is zero otherwise). -/ @[simps] noncomputable -def map (hf : IsSpectralMap f) (hf' : ∀ y : Y, IsCompact <| f ⁻¹' {y}) : +def map (hf : IsSpectralMap f) (hf' : HasCompactFibers f) : Function.locallyFinsupp Y R where toFun z := ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, (c x) * w x @@ -100,8 +100,7 @@ def map (hf : IsSpectralMap f) (hf' : ∀ y : Y, IsCompact <| f ⁻¹' {y}) : /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ -lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) - (hf' : ∀ y : Y, IsCompact <| f ⁻¹' {y}) +lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) (hf' : HasCompactFibers f) (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : (map f w c hf hf').support ⊆ t := by intro y hy @@ -117,7 +116,7 @@ The pushforward of `c` along the identity morphism is `c`. -/ @[simp] lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : - map id w c isSpectralMap_id (by simp) = c := by + map id w c isSpectralMap_id (by simp [HasCompactFibers]) = c := by classical ext z change ∑ x ∈ _, c x * w x = c z diff --git a/Mathlib/Topology/Maps/Proper/Basic.lean b/Mathlib/Topology/Maps/Proper/Basic.lean index 0e77b669944c3f..89637568f71f20 100644 --- a/Mathlib/Topology/Maps/Proper/Basic.lean +++ b/Mathlib/Topology/Maps/Proper/Basic.lean @@ -346,3 +346,6 @@ theorem IsProperMap.universally_closed (Z) [TopologicalSpace Z] (h : IsProperMap IsClosedMap (Prod.map f id : X × Z → Y × Z) := -- `f × id` is proper as a product of proper maps, hence closed. (h.prodMap isProperMap_id).isClosedMap + +lemma IsProperMap.hasCompactFibers {f : X → Y} (hf : IsProperMap f) : HasCompactFibers f := + (isProperMap_iff_isClosedMap_and_compact_fibers.mp hf).2.2 diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 3eb5cb7d601cb0..2ebc6130ea6276 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -8,6 +8,7 @@ module public import Mathlib.Topology.Spectral.Basic public import Mathlib.Topology.JacobsonSpace public import Mathlib.Data.Set.Card +public import Mathlib.Topology.Constructible /-! # Constructible topology @@ -157,23 +158,75 @@ instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] variable {Y : Type*} [TopologicalSpace Y] -abbrev HasCompactFibers (f : X → Y) : Prop := ∀ y, IsCompact (f ⁻¹' {y}) +instance [PrespectralSpace X] [T0Space X] [QuasiSober X] : + T2Space <| WithConstructibleTopology X where + t2 := by + intro x y hxy + obtain ⟨U, hU, (⟨hxU, hyU⟩ | ⟨hyU, hxU⟩)⟩ := exists_isOpen_xor_mem (X := X) hxy <;> + obtain ⟨V, ⟨hVo, hVc⟩, hV, hVU⟩ := + PrespectralSpace.isTopologicalBasis.mem_nhds_iff.mp (hU.mem_nhds ‹_›) + · exact ⟨V, Vᶜ, + TopologicalSpace.isOpen_generateFrom_of_mem (.inl ⟨hVo, hVc⟩), + TopologicalSpace.isOpen_generateFrom_of_mem + (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), + hV, Set.mem_compl (fun h ↦ hyU (hVU h)), disjoint_compl_right⟩ + · exact ⟨Vᶜ, V, + TopologicalSpace.isOpen_generateFrom_of_mem + (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), + TopologicalSpace.isOpen_generateFrom_of_mem (.inl ⟨hVo, hVc⟩), + Set.mem_compl (fun h ↦ hxU (hVU h)), hV, disjoint_compl_left⟩ -lemma IsProperMap.hasCompactFibers {f : X → Y} (hf : IsProperMap f) : HasCompactFibers f := sorry +/-- +Canoical map from a space `X` to `WithConstructibleTopology X` +-/ +def toConstructibleTopology (X) [TopologicalSpace X] : X ≃ WithConstructibleTopology X := + Equiv.refl _ + +/-- +Canoical map from a space `WithConstructibleTopology X` to `X` +-/ +def ofConstructibleTopology (X) [TopologicalSpace X] : WithConstructibleTopology X ≃ X := + Equiv.refl _ + +/-- +Induced map `lift f : WithConstructibleTopology X → WithConstructibleTopology Y` by a map +`f : X → Y` +-/ +def WithConstructibleTopology.lift (f : X → Y) : + WithConstructibleTopology X → WithConstructibleTopology Y := + toConstructibleTopology Y ∘ f ∘ ofConstructibleTopology X + +/-- +The map from `X` with the constructible topology to `X` is continuous if `X` is prespectral. +-/ +lemma ofConstructibleTopology_continuous [PrespectralSpace X] : + Continuous <| ofConstructibleTopology X := by + rw [TopologicalSpace.IsTopologicalBasis.continuous_iff (PrespectralSpace.isBasis_opens X)] + intro U ⟨hU1, hU2, hU3⟩ + convert hU2.isOpen_constructibleTopology_of_isOpen hU1.2 + simp [hU3, ofConstructibleTopology] + rfl + +lemma WithConstructibleTopology.lift_continuous {f : X → Y} (hf : IsSpectralMap f) : + Continuous <| WithConstructibleTopology.lift f := by + apply continuous_generateFrom_iff.mpr + intro s hs + obtain ⟨hso, hsc⟩ | ⟨hscl, hsc⟩ := hs + · exact (hf.isCompact_preimage_of_isOpen hso hsc).isOpen_constructibleTopology_of_isOpen + (hso.preimage hf.continuous) + · exact + (hf.isCompact_preimage_of_isOpen hscl.isOpen_compl hsc).isOpen_constructibleTopology_of_isClosed + (hscl.preimage hf.continuous) -lemma fdsujb [PrespectralSpace X] [T0Space X] [QuasiSober X] : - T2Space <| WithConstructibleTopology X := by - constructor - intro x y hxy - #check t0Space_iff_not_inseparable - --#check exists_isOpen_xor_mem - --have := exists_isOpen_xor_mem - sorry +lemma Topology.IsOpenEmbedding.isSpectralMap_of_compactSpace {f : X → Y} [CompactSpace X] + (hf : Topology.IsOpenEmbedding f) [QuasiSeparatedSpace Y] : + IsSpectralMap f := ⟨hf.continuous, fun _ hU hU' ↦ IsRetrocompact.isCompact <| + IsRetrocompact.preimage_of_isOpenEmbedding hf <| hU'.isRetrocompact hU⟩ /-- A spectral map between *quasi-separated* quasispectral, sober spaces has compact fibers. Somewhat strangely, this is the strongest such statement we can figure out how to show. -This is a bit strange because compactness of fibers is a purely topological property, +This is weird because compactness of fibers is a purely topological property, and yet there is an analogous theorem in algebraic geometry saying that the fibers of a quasicompact morphism are quasicompact. The underlying space of a scheme is precisely a topological space which is locally a spectral space, which notably does not necessarily have any global quasi-separatedness @@ -183,5 +236,30 @@ topological property of quasicompact morphisms of schemes seems to be entirely a algebra. -/ lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSeparatedSpace X] - [PrespectralSpace Y] [T0Space Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf : IsSpectralMap f) : - HasCompactFibers f := sorry + [QuasiSober X] [PrespectralSpace Y] [T0Space Y] [QuasiSeparatedSpace Y] [QuasiSober Y] + {f : X → Y} (hf : IsSpectralMap f) : HasCompactFibers f := by + intro y + -- Take a compact open neighbourhood U of y (exists since Y is prespectral) + obtain ⟨U, ⟨hUo, hUc⟩, hyU, -⟩ := + (PrespectralSpace.isTopologicalBasis (X := Y)).mem_nhds_iff.mp (isOpen_univ.mem_nhds trivial) + -- f ⁻¹' U is compact and open (spectral map + U compact open) + have hfUo : IsOpen (f ⁻¹' U) := hUo.preimage hf.continuous + have hfUc : IsCompact (f ⁻¹' U) := hf.isCompact_preimage_of_isOpen hUo hUc + -- f ⁻¹' U is an open subspace, inheriting all the needed instances + have hfU_oe : IsOpenEmbedding (Subtype.val : ↥(f ⁻¹' U) → X) := hfUo.isOpenEmbedding_subtypeVal + have : CompactSpace ↥(f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc + have : PrespectralSpace ↥(f ⁻¹' U) := hfU_oe.prespectralSpace + have : QuasiSeparatedSpace ↥(f ⁻¹' U) := hfU_oe.quasiSeparatedSpace + have : QuasiSober ↥(f ⁻¹' U) := hfU_oe.quasiSober + let g := f ∘ (Subtype.val : f ⁻¹' U → X) + have hg : IsSpectralMap g := + hf.comp hfUo.isOpenEmbedding_subtypeVal.isSpectralMap_of_compactSpace + suffices h : f ⁻¹' {y} = Subtype.val '' (g ⁻¹' {y}) by + rw [h] + exact + (isClosed_singleton.preimage (WithConstructibleTopology.lift_continuous hg)).isCompact.image + (continuous_subtype_val.comp ofConstructibleTopology_continuous) + ext x + simp only [Set.mem_preimage, Set.mem_singleton_iff, Set.mem_image, g, Function.comp, + Subtype.exists] + exact ⟨fun hfx => ⟨x, hfx ▸ hyU, hfx, rfl⟩, fun ⟨_, _, hfa, rfl⟩ => hfa⟩ From 2a094a248efcbd8c6678681140e0fe6f3c1ebe13 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 4 May 2026 20:55:55 +0200 Subject: [PATCH 49/70] Expanded on a dosctring --- Mathlib/Topology/LocallyFinsupp/Pushforward.lean | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 53c1ba7d3669d7..ab23b8b007a9c5 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -90,8 +90,7 @@ if the dimensions of the points correspond, and is zero otherwise). -/ @[simps] noncomputable -def map (hf : IsSpectralMap f) (hf' : HasCompactFibers f) : - Function.locallyFinsupp Y R where +def map (hf : IsSpectralMap f) (hf' : HasCompactFibers f) : Function.locallyFinsupp Y R where toFun z := ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, (c x) * w x supportWithinDomain' := by simp @@ -112,7 +111,9 @@ lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) (hf' : HasC grind /-- -The pushforward of `c` along the identity morphism is `c`. +The pushforward of `c` along the identity morphism is `c` as long as the weight function is `1` +everywhere. One should note that typically this weight function depends on the map, so this +condition that the weight function must be trivial here is less strange than it may appear at first. -/ @[simp] lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : From 700233cb57125b86e348ca55393e45dd20c534f8 Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 4 May 2026 22:00:44 +0200 Subject: [PATCH 50/70] Added a dostring for HasCompactFibers --- Mathlib/Topology/Compactness/Compact.lean | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index ae75cb065249c3..adf4501893f1c4 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -1223,4 +1223,7 @@ theorem IsClosed.exists_minimal_nonempty_closed_subset [CompactSpace X] {S : Set end Compact +/-- +A function satisfies `HasCompactFibers` if all the fibers are quasi-compact +-/ abbrev HasCompactFibers (f : X → Y) : Prop := ∀ y, IsCompact (f ⁻¹' {y}) From 281eec4f75ed7f2bb85b87ddf06e95a0e7e13b52 Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Fri, 8 May 2026 15:58:30 +0200 Subject: [PATCH 51/70] Update Mathlib/Topology/Compactness/Compact.lean Co-authored-by: Christian Merten --- Mathlib/Topology/Compactness/Compact.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index adf4501893f1c4..a0dbd44e6862e2 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -1224,6 +1224,6 @@ theorem IsClosed.exists_minimal_nonempty_closed_subset [CompactSpace X] {S : Set end Compact /-- -A function satisfies `HasCompactFibers` if all the fibers are quasi-compact +A function satisfies `HasCompactFibers` if all the fibers are compact -/ abbrev HasCompactFibers (f : X → Y) : Prop := ∀ y, IsCompact (f ⁻¹' {y}) From 50b971cacf3d653d76627e2f132cb2831f03a9aa Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Fri, 8 May 2026 15:59:53 +0200 Subject: [PATCH 52/70] Update Mathlib/Topology/LocallyFinsupp/Pushforward.lean Co-authored-by: Christian Merten --- Mathlib/Topology/LocallyFinsupp/Pushforward.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index ab23b8b007a9c5..4aae81256b1b8c 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -32,7 +32,7 @@ open Set Order Topology TopologicalSpace universe u v variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] - {f : X → Y} (hf : IsSpectralMap f) (w : X → R) + {f : X → Y} (hf : IsSpectralMap f) (w : X → R) namespace Function namespace locallyFinsupp From 346e6569c2769642be429e3569570735a893a34e Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Mon, 11 May 2026 10:27:51 +0200 Subject: [PATCH 53/70] Update Mathlib/Topology/Spectral/ConstructibleTopology.lean Co-authored-by: Christian Merten --- Mathlib/Topology/Spectral/ConstructibleTopology.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 2ebc6130ea6276..2156718632f8a4 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -199,7 +199,7 @@ def WithConstructibleTopology.lift (f : X → Y) : /-- The map from `X` with the constructible topology to `X` is continuous if `X` is prespectral. -/ -lemma ofConstructibleTopology_continuous [PrespectralSpace X] : +lemma WithConstructibleTopology.continuous_equiv_symm [PrespectralSpace X] : Continuous <| ofConstructibleTopology X := by rw [TopologicalSpace.IsTopologicalBasis.continuous_iff (PrespectralSpace.isBasis_opens X)] intro U ⟨hU1, hU2, hU3⟩ From 23004637bbd515dc637d8837a2d033e31191bdcf Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Mon, 11 May 2026 10:28:28 +0200 Subject: [PATCH 54/70] Update Mathlib/Topology/Spectral/ConstructibleTopology.lean Co-authored-by: Christian Merten --- Mathlib/Topology/Spectral/ConstructibleTopology.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 2156718632f8a4..1ca3f235e80ce3 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -185,7 +185,7 @@ def toConstructibleTopology (X) [TopologicalSpace X] : X ≃ WithConstructibleTo /-- Canoical map from a space `WithConstructibleTopology X` to `X` -/ -def ofConstructibleTopology (X) [TopologicalSpace X] : WithConstructibleTopology X ≃ X := +def WithConstructibleTopology.equiv (X) [TopologicalSpace X] : WithConstructibleTopology X ≃ X := Equiv.refl _ /-- From d0163c416298e438d9291936f97117504f03fa1c Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Mon, 11 May 2026 10:29:01 +0200 Subject: [PATCH 55/70] Update Mathlib/Topology/Spectral/ConstructibleTopology.lean Co-authored-by: Christian Merten --- Mathlib/Topology/Spectral/ConstructibleTopology.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 1ca3f235e80ce3..f0361c8cd67a0a 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -202,10 +202,10 @@ The map from `X` with the constructible topology to `X` is continuous if `X` is lemma WithConstructibleTopology.continuous_equiv_symm [PrespectralSpace X] : Continuous <| ofConstructibleTopology X := by rw [TopologicalSpace.IsTopologicalBasis.continuous_iff (PrespectralSpace.isBasis_opens X)] - intro U ⟨hU1, hU2, hU3⟩ - convert hU2.isOpen_constructibleTopology_of_isOpen hU1.2 - simp [hU3, ofConstructibleTopology] - rfl + simp only [Set.mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] + intro U hU + rw [isOpen_ofConstructibleTopology_preimage_iff] + exact hU.isOpen_constructibleTopology_of_isOpen U.2 lemma WithConstructibleTopology.lift_continuous {f : X → Y} (hf : IsSpectralMap f) : Continuous <| WithConstructibleTopology.lift f := by From 1b02f54070452cf305f76a912f69db7cba79a651 Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Mon, 11 May 2026 10:44:30 +0200 Subject: [PATCH 56/70] Apply suggestion from @chrisflav Co-authored-by: Christian Merten --- .../Spectral/ConstructibleTopology.lean | 42 ++++++------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index f0361c8cd67a0a..bf900885ce4b81 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -224,42 +224,26 @@ lemma Topology.IsOpenEmbedding.isSpectralMap_of_compactSpace {f : X → Y} [Comp IsRetrocompact.preimage_of_isOpenEmbedding hf <| hU'.isRetrocompact hU⟩ /-- -A spectral map between *quasi-separated* quasispectral, sober spaces has compact fibers. -Somewhat strangely, this is the strongest such statement we can figure out how to show. -This is weird because compactness of fibers is a purely topological property, -and yet there is an analogous theorem in algebraic geometry saying that the fibers of a quasicompact -morphism are quasicompact. The underlying space of a scheme is precisely a topological space which -is locally a spectral space, which notably does not necessarily have any global quasi-separatedness -assumptions. However, the proof of this fact is very algebraic (utilizing the fact that -quasi-compactness of morphisms is closed under base change). So, we have that this purely -topological property of quasicompact morphisms of schemes seems to be entirely a consequence of -algebra. +A spectral map between *quasi-separated* pre-spectral, sober spaces has compact fibers. +Note that any quasi-compact morphism of schemes has compact fibers, although the underlying +topological space of a schemes is not necessarily quasi-separated. -/ lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSeparatedSpace X] [QuasiSober X] [PrespectralSpace Y] [T0Space Y] [QuasiSeparatedSpace Y] [QuasiSober Y] {f : X → Y} (hf : IsSpectralMap f) : HasCompactFibers f := by intro y -- Take a compact open neighbourhood U of y (exists since Y is prespectral) - obtain ⟨U, ⟨hUo, hUc⟩, hyU, -⟩ := + obtain ⟨U, ⟨hUo, hUc⟩, (hyU : y ∈ U), -⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).mem_nhds_iff.mp (isOpen_univ.mem_nhds trivial) - -- f ⁻¹' U is compact and open (spectral map + U compact open) have hfUo : IsOpen (f ⁻¹' U) := hUo.preimage hf.continuous have hfUc : IsCompact (f ⁻¹' U) := hf.isCompact_preimage_of_isOpen hUo hUc - -- f ⁻¹' U is an open subspace, inheriting all the needed instances - have hfU_oe : IsOpenEmbedding (Subtype.val : ↥(f ⁻¹' U) → X) := hfUo.isOpenEmbedding_subtypeVal - have : CompactSpace ↥(f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc - have : PrespectralSpace ↥(f ⁻¹' U) := hfU_oe.prespectralSpace - have : QuasiSeparatedSpace ↥(f ⁻¹' U) := hfU_oe.quasiSeparatedSpace - have : QuasiSober ↥(f ⁻¹' U) := hfU_oe.quasiSober + have : CompactSpace (f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc + have : PrespectralSpace (f ⁻¹' U) := hfUo.isOpenEmbedding_subtypeVal.prespectralSpace + have : QuasiSeparatedSpace (f ⁻¹' U) := hfUo.isOpenEmbedding_subtypeVal.quasiSeparatedSpace + have : QuasiSober (f ⁻¹' U) := hfUo.isOpenEmbedding_subtypeVal.quasiSober let g := f ∘ (Subtype.val : f ⁻¹' U → X) - have hg : IsSpectralMap g := - hf.comp hfUo.isOpenEmbedding_subtypeVal.isSpectralMap_of_compactSpace - suffices h : f ⁻¹' {y} = Subtype.val '' (g ⁻¹' {y}) by - rw [h] - exact - (isClosed_singleton.preimage (WithConstructibleTopology.lift_continuous hg)).isCompact.image - (continuous_subtype_val.comp ofConstructibleTopology_continuous) - ext x - simp only [Set.mem_preimage, Set.mem_singleton_iff, Set.mem_image, g, Function.comp, - Subtype.exists] - exact ⟨fun hfx => ⟨x, hfx ▸ hyU, hfx, rfl⟩, fun ⟨_, _, hfa, rfl⟩ => hfa⟩ + have hg : IsSpectralMap g := hf.comp hfUo.isOpenEmbedding_subtypeVal.isSpectralMap_of_compactSpace + have heq : f ⁻¹' {y} = Subtype.val '' (g ⁻¹' {y}) := by grind [Subtype.exists] + rw [heq] + exact (isClosed_singleton.preimage (WithConstructibleTopology.lift_continuous hg)).isCompact.image + (continuous_subtype_val.comp ofConstructibleTopology_continuous) From 394b8c4506daa43de8332403f720718fb60a02cd Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 11 May 2026 10:44:58 +0200 Subject: [PATCH 57/70] Applied some review changes --- .../Spectral/ConstructibleTopology.lean | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index f0361c8cd67a0a..df4b4bb1ae63fc 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -192,15 +192,28 @@ def WithConstructibleTopology.equiv (X) [TopologicalSpace X] : WithConstructible Induced map `lift f : WithConstructibleTopology X → WithConstructibleTopology Y` by a map `f : X → Y` -/ -def WithConstructibleTopology.lift (f : X → Y) : +def WithConstructibleTopology.map (f : X → Y) : WithConstructibleTopology X → WithConstructibleTopology Y := - toConstructibleTopology Y ∘ f ∘ ofConstructibleTopology X + toConstructibleTopology Y ∘ f ∘ equiv X + +@[simp] +lemma WithConstructibleTopology.map_id (x : WithConstructibleTopology X) : + WithConstructibleTopology.map id x = x := rfl + +@[simp] +lemma WithConstructibleTopology.map_comp {Z : Type*} [TopologicalSpace Z] (f : X → Y) (g : Y → Z) : + WithConstructibleTopology.map (g ∘ f) = + WithConstructibleTopology.map g ∘ WithConstructibleTopology.map f := rfl + +lemma isOpen_ofConstructibleTopology_preimage_iff (s : Set X) : + IsOpen (WithConstructibleTopology.equiv X ⁻¹' s) ↔ IsOpen[constructibleTopology X] s := + .rfl /-- The map from `X` with the constructible topology to `X` is continuous if `X` is prespectral. -/ lemma WithConstructibleTopology.continuous_equiv_symm [PrespectralSpace X] : - Continuous <| ofConstructibleTopology X := by + Continuous <| equiv X := by rw [TopologicalSpace.IsTopologicalBasis.continuous_iff (PrespectralSpace.isBasis_opens X)] simp only [Set.mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] intro U hU @@ -208,7 +221,7 @@ lemma WithConstructibleTopology.continuous_equiv_symm [PrespectralSpace X] : exact hU.isOpen_constructibleTopology_of_isOpen U.2 lemma WithConstructibleTopology.lift_continuous {f : X → Y} (hf : IsSpectralMap f) : - Continuous <| WithConstructibleTopology.lift f := by + Continuous <| WithConstructibleTopology.map f := by apply continuous_generateFrom_iff.mpr intro s hs obtain ⟨hso, hsc⟩ | ⟨hscl, hsc⟩ := hs From 23c006b104e0d7f013df44ce06030930bf5a1b8a Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 11 May 2026 11:27:22 +0200 Subject: [PATCH 58/70] Made changes according to review + attempted to gold proof using wlog --- Mathlib/Topology/Constructible.lean | 6 +++ .../Spectral/ConstructibleTopology.lean | 50 +++++++++---------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Mathlib/Topology/Constructible.lean b/Mathlib/Topology/Constructible.lean index e8fe3c95171a0c..0037e1de036937 100644 --- a/Mathlib/Topology/Constructible.lean +++ b/Mathlib/Topology/Constructible.lean @@ -326,6 +326,12 @@ omit [CompactSpace X] in lemma _root_.IsCompact.isRetrocompact (hU' : IsCompact U) (hU : IsOpen U) : IsRetrocompact U := fun _ hV' hV ↦ hU'.inter_of_isOpen hV' hU hV +omit [QuasiSeparatedSpace X] in +lemma IsOpenEmbedding.isSpectralMap_of_compactSpace {f : X → Y} + (hf : Topology.IsOpenEmbedding f) [QuasiSeparatedSpace Y] : + IsSpectralMap f := ⟨hf.continuous, fun _ hU hU' ↦ IsRetrocompact.isCompact <| + IsRetrocompact.preimage_of_isOpenEmbedding hf <| hU'.isRetrocompact hU⟩ + omit [CompactSpace X] in lemma _root_.IsCompact.isConstructible (hU' : IsCompact U) (hU : IsOpen U) : IsConstructible U := (hU'.isRetrocompact hU).isConstructible hU diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index e8e95cd2a00e1a..2afbee3dba9cbc 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -156,45 +156,47 @@ instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] refine hB.prop.2.1 (_ ∪ F) ?_ <| (hA₁'.diff.union hA₂'.diff).union hF grind [Set.diff_singleton_subset_iff, Set.union_subset_iff] -variable {Y : Type*} [TopologicalSpace Y] - instance [PrespectralSpace X] [T0Space X] [QuasiSober X] : - T2Space <| WithConstructibleTopology X where - t2 := by + T2Space <| WithConstructibleTopology X := by + constructor intro x y hxy - obtain ⟨U, hU, (⟨hxU, hyU⟩ | ⟨hyU, hxU⟩)⟩ := exists_isOpen_xor_mem (X := X) hxy <;> - obtain ⟨V, ⟨hVo, hVc⟩, hV, hVU⟩ := - PrespectralSpace.isTopologicalBasis.mem_nhds_iff.mp (hU.mem_nhds ‹_›) + wlog h : ∃ (U : Set X), IsOpen U ∧ x ∈ U ∧ y ∉ U + · have o : ∃ (U : Set X), IsOpen U ∧ y ∈ U ∧ x ∉ U := by + obtain ⟨U, hU1, (o | o)⟩ := exists_isOpen_xor_mem (X := X) hxy <;> use U + · simp only [not_exists, not_and, not_not] at h + exact (o.2 (h U hU1 o.1)).elim + · exact ⟨hU1, o⟩ + obtain ⟨U, V, a, b, c, d, e⟩ := @this X _ _ _ _ y x hxy.symm o + exact ⟨V, U, b, a, d, c, e.symm⟩ + obtain ⟨U, hU1, hU2, hU3⟩ := h + obtain ⟨V, ⟨hVo, hVc⟩, hV, hVU⟩ := + PrespectralSpace.isTopologicalBasis.mem_nhds_iff.mp (hU1.mem_nhds ‹_›) · exact ⟨V, Vᶜ, TopologicalSpace.isOpen_generateFrom_of_mem (.inl ⟨hVo, hVc⟩), TopologicalSpace.isOpen_generateFrom_of_mem (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), - hV, Set.mem_compl (fun h ↦ hyU (hVU h)), disjoint_compl_right⟩ - · exact ⟨Vᶜ, V, - TopologicalSpace.isOpen_generateFrom_of_mem - (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), - TopologicalSpace.isOpen_generateFrom_of_mem (.inl ⟨hVo, hVc⟩), - Set.mem_compl (fun h ↦ hxU (hVU h)), hV, disjoint_compl_left⟩ + hV, Set.mem_compl (fun h ↦ hU3 (hVU h)), disjoint_compl_right⟩ /-- -Canoical map from a space `X` to `WithConstructibleTopology X` +Canonical map from a space `X` to `WithConstructibleTopology X` -/ def toConstructibleTopology (X) [TopologicalSpace X] : X ≃ WithConstructibleTopology X := Equiv.refl _ /-- -Canoical map from a space `WithConstructibleTopology X` to `X` +Canonical map from a space `WithConstructibleTopology X` to `X` -/ def WithConstructibleTopology.equiv (X) [TopologicalSpace X] : WithConstructibleTopology X ≃ X := Equiv.refl _ +variable {Y : Type*} [TopologicalSpace Y] /-- Induced map `lift f : WithConstructibleTopology X → WithConstructibleTopology Y` by a map `f : X → Y` -/ def WithConstructibleTopology.map (f : X → Y) : WithConstructibleTopology X → WithConstructibleTopology Y := - toConstructibleTopology Y ∘ f ∘ equiv X + (equiv Y).symm ∘ f ∘ equiv X @[simp] lemma WithConstructibleTopology.map_id (x : WithConstructibleTopology X) : @@ -206,13 +208,12 @@ lemma WithConstructibleTopology.map_comp {Z : Type*} [TopologicalSpace Z] (f : X WithConstructibleTopology.map g ∘ WithConstructibleTopology.map f := rfl lemma isOpen_ofConstructibleTopology_preimage_iff (s : Set X) : - IsOpen (WithConstructibleTopology.equiv X ⁻¹' s) ↔ IsOpen[constructibleTopology X] s := - .rfl + IsOpen (WithConstructibleTopology.equiv X ⁻¹' s) ↔ IsOpen[constructibleTopology X] s := .rfl /-- The map from `X` with the constructible topology to `X` is continuous if `X` is prespectral. -/ -lemma WithConstructibleTopology.continuous_equiv_symm [PrespectralSpace X] : +lemma WithConstructibleTopology.continuous_equiv [PrespectralSpace X] : Continuous <| equiv X := by rw [TopologicalSpace.IsTopologicalBasis.continuous_iff (PrespectralSpace.isBasis_opens X)] simp only [Set.mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] @@ -220,7 +221,7 @@ lemma WithConstructibleTopology.continuous_equiv_symm [PrespectralSpace X] : rw [isOpen_ofConstructibleTopology_preimage_iff] exact hU.isOpen_constructibleTopology_of_isOpen U.2 -lemma WithConstructibleTopology.lift_continuous {f : X → Y} (hf : IsSpectralMap f) : +lemma WithConstructibleTopology.map_continuous {f : X → Y} (hf : IsSpectralMap f) : Continuous <| WithConstructibleTopology.map f := by apply continuous_generateFrom_iff.mpr intro s hs @@ -231,11 +232,6 @@ lemma WithConstructibleTopology.lift_continuous {f : X → Y} (hf : IsSpectralMa (hf.isCompact_preimage_of_isOpen hscl.isOpen_compl hsc).isOpen_constructibleTopology_of_isClosed (hscl.preimage hf.continuous) -lemma Topology.IsOpenEmbedding.isSpectralMap_of_compactSpace {f : X → Y} [CompactSpace X] - (hf : Topology.IsOpenEmbedding f) [QuasiSeparatedSpace Y] : - IsSpectralMap f := ⟨hf.continuous, fun _ hU hU' ↦ IsRetrocompact.isCompact <| - IsRetrocompact.preimage_of_isOpenEmbedding hf <| hU'.isRetrocompact hU⟩ - /-- A spectral map between *quasi-separated* pre-spectral, sober spaces has compact fibers. Note that any quasi-compact morphism of schemes has compact fibers, although the underlying @@ -258,5 +254,5 @@ lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSepa have hg : IsSpectralMap g := hf.comp hfUo.isOpenEmbedding_subtypeVal.isSpectralMap_of_compactSpace have heq : f ⁻¹' {y} = Subtype.val '' (g ⁻¹' {y}) := by grind [Subtype.exists] rw [heq] - exact (isClosed_singleton.preimage (WithConstructibleTopology.lift_continuous hg)).isCompact.image - (continuous_subtype_val.comp ofConstructibleTopology_continuous) + exact (isClosed_singleton.preimage (WithConstructibleTopology.map_continuous hg)).isCompact.image + (continuous_subtype_val.comp WithConstructibleTopology.continuous_equiv) From 19c27f3f26f60d296f8571068bd5062d13fd204e Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Mon, 11 May 2026 11:38:53 +0200 Subject: [PATCH 59/70] Changed things in Pushforward.lean according to review comments --- .../Topology/LocallyFinsupp/Pushforward.lean | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 4aae81256b1b8c..1c8ba9820985f0 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -34,16 +34,15 @@ universe u v variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] {f : X → Y} (hf : IsSpectralMap f) (w : X → R) -namespace Function -namespace locallyFinsupp +namespace Function.locallyFinsupp section map -variable [Semiring R] {W : TopologicalSpace.Opens Y} (c : Function.locallyFinsupp X R) +variable [Semiring R] {W : Set Y} (hW : IsOpen W) (c : Function.locallyFinsupp X R) -lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompact W.1) : - (W.carrier ∩ {z : Y | (f ⁻¹' {z} ∩ c.support).Nonempty}).Finite := by - suffices (f ⁻¹' (W.carrier ∩ {z | (f ⁻¹' {z} ∩ c.support).Nonempty}) ∩ c.support).Finite from +lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsOpen W) + (hW' : IsCompact W) : (W ∩ {z : Y | (f ⁻¹' {z} ∩ c.support).Nonempty}).Finite := by + suffices (f ⁻¹' (W ∩ {z | (f ⁻¹' {z} ∩ c.support).Nonempty}) ∩ c.support).Finite from (this.image f).subset (fun a ha ↦ by grind [Set.Nonempty]) rw [preimage_inter] suffices (f ⁻¹' W ∩ ⋃ z, f ⁻¹' {z} ∩ c.support).Finite by @@ -51,33 +50,13 @@ lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsCompa rw [Set.inter_assoc] exact Set.inter_subset_inter_right _ (fun p hp ↦ by simp_all) rw [inter_iUnion] - suffices (f ⁻¹' W.carrier ∩ c.support).Finite by + suffices (f ⁻¹' W ∩ c.support).Finite by grind [Opens.carrier_eq_coe, iUnion_subset_iff, SetLike.mem_coe, Function.mem_support, Finite.subset] exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| - hf.2 W.is_open' hW - -variable {N : Type*} [PrespectralSpace Y] - -lemma map_locally_finite (hf : IsSpectralMap f) (hf' : HasCompactFibers f) (y : Y) : - ∃ t ∈ 𝓝 y, (t ∩ Function.support fun z ↦ - ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, - (c x) * w x).Finite := by - obtain ⟨W, hW⟩ : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by - obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open - (by simp : y ∈ ⊤) (by simp) - use ⟨U, hU.1.1⟩ - exact ⟨hU.1.2, hU.2.1⟩ - use W - refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ - suffices (W.carrier ∩ {z : Y | (f ⁻¹' {z} ∩ support c.toFun).Nonempty}).Finite by - apply Finite.subset this - apply inter_subset_inter_right - intro x - contrapose! - simp +contextual only [mem_setOf_eq, not_nonempty_iff_eq_empty, mem_support, toFinite_toFinset, - toFinset_empty, Finset.sum_empty, ne_eq, not_true_eq_false, not_false_eq_true, implies_true] - exact inter_preimageSupport_nonempty_finite c hf hW.1 + hf.2 hW hW' + +variable [PrespectralSpace Y] variable (f) in /-- @@ -90,18 +69,35 @@ if the dimensions of the points correspond, and is zero otherwise). -/ @[simps] noncomputable -def map (hf : IsSpectralMap f) (hf' : HasCompactFibers f) : Function.locallyFinsupp Y R where +def map (hf : IsSpectralMap f) (hf' : HasCompactFibers f) (c : locallyFinsupp X R) : + Function.locallyFinsupp Y R where toFun z := ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, (c x) * w x supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' z _ := map_locally_finite w c hf hf' z + supportLocallyFiniteWithinDomain' y _ := by + obtain ⟨W, hW⟩ : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by + obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open + (by simp : y ∈ ⊤) (by simp) + use ⟨U, hU.1.1⟩ + exact ⟨hU.1.2, hU.2.1⟩ + use W + refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ + suffices (W.carrier ∩ {z : Y | (f ⁻¹' {z} ∩ support c.toFun).Nonempty}).Finite by + apply Finite.subset this + apply inter_subset_inter_right + intro x + contrapose! + simp +contextual only [mem_setOf_eq, not_nonempty_iff_eq_empty, mem_support, + toFinite_toFinset, toFinset_empty, Finset.sum_empty, ne_eq, not_true_eq_false, + not_false_eq_true, implies_true] + exact inter_preimageSupport_nonempty_finite c hf W.2 hW.1 /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) (hf' : HasCompactFibers f) (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : - (map f w c hf hf').support ⊆ t := by + (map f w hf hf' c).support ⊆ t := by intro y hy simp only [map, Function.mem_support, ne_eq] at hy obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy @@ -117,7 +113,7 @@ condition that the weight function must be trivial here is less strange than it -/ @[simp] lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : - map id w c isSpectralMap_id (by simp [HasCompactFibers]) = c := by + map id w isSpectralMap_id (by simp [HasCompactFibers]) c = c := by classical ext z change ∑ x ∈ _, c x * w x = c z @@ -126,5 +122,4 @@ lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : split_ifs with h <;> simp [hw, h] end map -end locallyFinsupp -end Function +end Function.locallyFinsupp From d6276ae11453c8bf7e97903107204ce0b7063121 Mon Sep 17 00:00:00 2001 From: Raphael Douglas Giles <77658801+Raph-DG@users.noreply.github.com> Date: Thu, 21 May 2026 11:40:27 +0200 Subject: [PATCH 60/70] Update Mathlib/Topology/LocallyFinsupp/Pushforward.lean Co-authored-by: Christian Merten --- .../Topology/LocallyFinsupp/Pushforward.lean | 79 ++++++++++--------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index 1c8ba9820985f0..ee8dc2080270aa 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -58,6 +58,19 @@ lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsOpen variable [PrespectralSpace Y] +-- move to an earlier file +@[simp] +lemma Function.locallyFinsuppWithin_toFun_eq_coe {X : Type*} [TopologicalSpace X] {U : Set X} + (c : locallyFinsuppWithin U R) : c.toFun = ⇑c := by + rfl + +-- move to an earlier file +@[simp] +lemma Function.locallyFinsuppWithin_coe_mk {X Y : Type*} [TopologicalSpace X] [Zero Y] {U : Set X} + (f : X → Y) (h : f.support ⊆ U) (h' : ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) : + ⇑(Function.locallyFinsuppWithin.mk f h h') = f := by + rfl + variable (f) in /-- The pushforward of a function `c` of locally finite support @@ -67,44 +80,42 @@ functions as algebraic cycles (in this case the weight function would be as desc 02R4, where the weight function is the degree of the corresponding extension of residue fields if the dimensions of the points correspond, and is zero otherwise). -/ -@[simps] noncomputable -def map (hf : IsSpectralMap f) (hf' : HasCompactFibers f) (c : locallyFinsupp X R) : - Function.locallyFinsupp Y R where - toFun z := ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf' z).toFinset, - (c x) * w x +def map (hf : IsSpectralMap f) (c : locallyFinsupp X R) : Function.locallyFinsupp Y R where + toFun z := ∑ᶠ x ∈ f ⁻¹' {z}, c x * w x supportWithinDomain' := by simp supportLocallyFiniteWithinDomain' y _ := by - obtain ⟨W, hW⟩ : ∃ W : TopologicalSpace.Opens Y, IsCompact W.1 ∧ y ∈ W := by - obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open - (by simp : y ∈ ⊤) (by simp) - use ⟨U, hU.1.1⟩ - exact ⟨hU.1.2, hU.2.1⟩ - use W - refine ⟨IsOpen.mem_nhds (Opens.isOpen W) hW.2, ?_⟩ - suffices (W.carrier ∩ {z : Y | (f ⁻¹' {z} ∩ support c.toFun).Nonempty}).Finite by - apply Finite.subset this - apply inter_subset_inter_right - intro x - contrapose! - simp +contextual only [mem_setOf_eq, not_nonempty_iff_eq_empty, mem_support, - toFinite_toFinset, toFinset_empty, Finset.sum_empty, ne_eq, not_true_eq_false, - not_false_eq_true, implies_true] - exact inter_preimageSupport_nonempty_finite c hf W.2 hW.1 + obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open + (by simp : y ∈ ⊤) (by simp) + refine ⟨U, IsOpen.mem_nhds hU.1.1 hU.2.1, ?_⟩ + refine (inter_preimageSupport_nonempty_finite c (hf.2 hU.1.1 hU.1.2)).subset + (inter_subset_inter_right _ fun y hy ↦ ?_) + obtain ⟨x, (hx : f x = y), h'⟩ := exists_ne_zero_of_finsum_mem_ne_zero hy + use x + grind [mem_support] + +@[simp] +lemma map_apply (hf : IsSpectralMap f) (c : locallyFinsupp X R) (y : Y) : + map f w hf c y = ∑ᶠ x ∈ f ⁻¹' {y}, c x * w x := + rfl + +lemma eq_finsetSum_of_hasCompactFibers (hf' : HasCompactFibers f) (y : Y) : + map f w hf c y = + ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact (hf' y)).toFinset, + c x * w x := by + simp only [map_apply, mem_preimage, mem_singleton_iff, Function.locallyFinsuppWithin_toFun_eq_coe] + apply finsum_cond_eq_sum_of_cond_iff + grind [Finite.mem_toFinset, mem_support] /-- Pushforward preserves cycles of pure dimension `d` in the dimension grading. -/ -lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) (hf' : HasCompactFibers f) +lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : - (map f w hf hf' c).support ⊆ t := by + (map f w hf c).support ⊆ t := by intro y hy - simp only [map, Function.mem_support, ne_eq] at hy - obtain ⟨x, hx⟩ := Finset.exists_ne_zero_of_sum_ne_zero hy - simp only [Finite.mem_toFinset, mem_inter_iff, mem_preimage, mem_singleton_iff, - Function.mem_support, ne_eq] at hx - specialize h x (hc hx.1.2) - grind + obtain ⟨x, (rfl : f x = y), h'⟩ := exists_ne_zero_of_finsum_mem_ne_zero hy + grind [mem_support] /-- The pushforward of `c` along the identity morphism is `c` as long as the weight function is `1` @@ -113,13 +124,9 @@ condition that the weight function must be trivial here is less strange than it -/ @[simp] lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : - map id w isSpectralMap_id (by simp [HasCompactFibers]) c = c := by - classical - ext z - change ∑ x ∈ _, c x * w x = c z - rw [show (Set.Finite.toFinset _ : Finset X) = if c z = 0 then ∅ else {z} from by - ext; split_ifs <;> aesop] - split_ifs with h <;> simp [hw, h] + map id w isSpectralMap_id c = c := by + ext + simp [map, hw] end map end Function.locallyFinsupp From 07f0e5daa08e520ffb087f5d326ba385441e4d3a Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 21 May 2026 12:06:40 +0200 Subject: [PATCH 61/70] Applied simplifications suggested by reviews --- Mathlib/Topology/LocallyFinsupp.lean | 8 +++ .../Topology/LocallyFinsupp/Pushforward.lean | 65 +++++-------------- 2 files changed, 25 insertions(+), 48 deletions(-) diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 80612fc9ca39a6..50ce1abefbe599 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -126,6 +126,14 @@ instance [Zero Y] : FunLike (locallyFinsuppWithin U Y) X Y where coe D := D.toFun coe_injective' := fun ⟨_, _, _⟩ ⟨_, _, _⟩ ↦ by simp +@[simp] +lemma toFun_eq_coe [Zero Y] (c : locallyFinsuppWithin U Y) : c.toFun = ⇑c := rfl + +@[simp] +lemma coe_mk [Zero Y] (f : X → Y) (h : f.support ⊆ U) + (h' : ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) : + ⇑(Function.locallyFinsuppWithin.mk f h h') = f := rfl + /-- This allows writing `D.support` instead of `Function.support D` -/ abbrev support [Zero Y] (D : locallyFinsuppWithin U Y) := Function.support D diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean index ee8dc2080270aa..d6e3d20e58b3a1 100644 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean @@ -15,7 +15,7 @@ In this file we define the notion of the pushforward of a function with locally between prespectral spaces. This is a nonstandard notion that arises because of our choice in mathlib to model algebraic cycles as functions with locally finite support. This makes it so that standard notions in the theory of cycles can be defined in more generality -than usual. +than usual, and allows us to reuse a lot of API to develop the theory of cycles. In the usual definition of the proper pushforward of algebraic cycles, one needs to adjust the coefficients by scaling by the degree of the corresponding extension of residue fields (assuming @@ -40,45 +40,15 @@ section map variable [Semiring R] {W : Set Y} (hW : IsOpen W) (c : Function.locallyFinsupp X R) -lemma inter_preimageSupport_nonempty_finite (hf : IsSpectralMap f) (hW : IsOpen W) - (hW' : IsCompact W) : (W ∩ {z : Y | (f ⁻¹' {z} ∩ c.support).Nonempty}).Finite := by - suffices (f ⁻¹' (W ∩ {z | (f ⁻¹' {z} ∩ c.support).Nonempty}) ∩ c.support).Finite from - (this.image f).subset (fun a ha ↦ by grind [Set.Nonempty]) - rw [preimage_inter] - suffices (f ⁻¹' W ∩ ⋃ z, f ⁻¹' {z} ∩ c.support).Finite by - apply Finite.subset this - rw [Set.inter_assoc] - exact Set.inter_subset_inter_right _ (fun p hp ↦ by simp_all) - rw [inter_iUnion] - suffices (f ⁻¹' W ∩ c.support).Finite by - grind [Opens.carrier_eq_coe, iUnion_subset_iff, SetLike.mem_coe, - Function.mem_support, Finite.subset] - exact LocallyFiniteSupport.finite_inter_support_of_isCompact c.locallyFiniteSupport <| - hf.2 hW hW' - variable [PrespectralSpace Y] --- move to an earlier file -@[simp] -lemma Function.locallyFinsuppWithin_toFun_eq_coe {X : Type*} [TopologicalSpace X] {U : Set X} - (c : locallyFinsuppWithin U R) : c.toFun = ⇑c := by - rfl - --- move to an earlier file -@[simp] -lemma Function.locallyFinsuppWithin_coe_mk {X Y : Type*} [TopologicalSpace X] [Zero Y] {U : Set X} - (f : X → Y) (h : f.support ⊆ U) (h' : ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) : - ⇑(Function.locallyFinsuppWithin.mk f h h') = f := by - rfl - variable (f) in /-- The pushforward of a function `c` of locally finite support -by a spectral map whose fibers intersect `c` in finitely many places -with respect to a weight function `w`. This is mainly used when interpretting locally fin supp -functions as algebraic cycles (in this case the weight function would be as described in stacks -02R4, where the weight function is the degree of the corresponding extension of residue fields -if the dimensions of the points correspond, and is zero otherwise). +by a spectral map with respect to a weight function `w`. This is mainly used when interpretting +locally fin supp functions as algebraic cycles (in this case the weight function would be as +described in stacks 02R4, where the weight function is the degree of the corresponding extension of +residue fields if the dimensions of the points correspond, and is zero otherwise). -/ noncomputable def map (hf : IsSpectralMap f) (c : locallyFinsupp X R) : Function.locallyFinsupp Y R where @@ -88,31 +58,30 @@ def map (hf : IsSpectralMap f) (c : locallyFinsupp X R) : Function.locallyFinsup obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open (by simp : y ∈ ⊤) (by simp) refine ⟨U, IsOpen.mem_nhds hU.1.1 hU.2.1, ?_⟩ - refine (inter_preimageSupport_nonempty_finite c (hf.2 hU.1.1 hU.1.2)).subset - (inter_subset_inter_right _ fun y hy ↦ ?_) - obtain ⟨x, (hx : f x = y), h'⟩ := exists_ne_zero_of_finsum_mem_ne_zero hy - use x - grind [mem_support] + suffices h : (U ∩ {z | (f ⁻¹' {z} ∩ support ⇑c).Nonempty}).Finite by + refine h.subset (inter_subset_inter_right U fun y hy ↦ ?_) + obtain ⟨x, (hx : f x = y), h'⟩ := exists_ne_zero_of_finsum_mem_ne_zero hy + use x + grind [mem_support] + suffices (f ⁻¹' (U ∩ {z | (f ⁻¹' {z} ∩ c.support).Nonempty}) ∩ c.support).Finite from + (this.image f).subset (fun a ha ↦ by grind [Set.Nonempty]) + exact (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf.2 hU.1.1 hU.1.2).subset + (by simp; grind) @[simp] lemma map_apply (hf : IsSpectralMap f) (c : locallyFinsupp X R) (y : Y) : - map f w hf c y = ∑ᶠ x ∈ f ⁻¹' {y}, c x * w x := - rfl + map f w hf c y = ∑ᶠ x ∈ f ⁻¹' {y}, c x * w x := rfl lemma eq_finsetSum_of_hasCompactFibers (hf' : HasCompactFibers f) (y : Y) : map f w hf c y = ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact (hf' y)).toFinset, c x * w x := by - simp only [map_apply, mem_preimage, mem_singleton_iff, Function.locallyFinsuppWithin_toFun_eq_coe] + simp only [map_apply, mem_preimage, mem_singleton_iff, Function.locallyFinsuppWithin.toFun_eq_coe] apply finsum_cond_eq_sum_of_cond_iff grind [Finite.mem_toFinset, mem_support] -/-- -Pushforward preserves cycles of pure dimension `d` in the dimension grading. --/ lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) - (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : - (map f w hf c).support ⊆ t := by + (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : (map f w hf c).support ⊆ t := by intro y hy obtain ⟨x, (rfl : f x = y), h'⟩ := exists_ne_zero_of_finsum_mem_ne_zero hy grind [mem_support] From 025d5fb0a98caf9bb6f01d284a5c9c21c3b1dcfa Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 21 May 2026 12:21:09 +0200 Subject: [PATCH 62/70] Remove stuff that's irrelevant for this PR --- Mathlib/Topology/LocallyFinsupp.lean | 8 -- .../Topology/LocallyFinsupp/Pushforward.lean | 101 ------------------ 2 files changed, 109 deletions(-) delete mode 100644 Mathlib/Topology/LocallyFinsupp/Pushforward.lean diff --git a/Mathlib/Topology/LocallyFinsupp.lean b/Mathlib/Topology/LocallyFinsupp.lean index 50ce1abefbe599..80612fc9ca39a6 100644 --- a/Mathlib/Topology/LocallyFinsupp.lean +++ b/Mathlib/Topology/LocallyFinsupp.lean @@ -126,14 +126,6 @@ instance [Zero Y] : FunLike (locallyFinsuppWithin U Y) X Y where coe D := D.toFun coe_injective' := fun ⟨_, _, _⟩ ⟨_, _, _⟩ ↦ by simp -@[simp] -lemma toFun_eq_coe [Zero Y] (c : locallyFinsuppWithin U Y) : c.toFun = ⇑c := rfl - -@[simp] -lemma coe_mk [Zero Y] (f : X → Y) (h : f.support ⊆ U) - (h' : ∀ z ∈ U, ∃ t ∈ 𝓝 z, Set.Finite (t ∩ f.support)) : - ⇑(Function.locallyFinsuppWithin.mk f h h') = f := rfl - /-- This allows writing `D.support` instead of `Function.support D` -/ abbrev support [Zero Y] (D : locallyFinsuppWithin U Y) := Function.support D diff --git a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean b/Mathlib/Topology/LocallyFinsupp/Pushforward.lean deleted file mode 100644 index d6e3d20e58b3a1..00000000000000 --- a/Mathlib/Topology/LocallyFinsupp/Pushforward.lean +++ /dev/null @@ -1,101 +0,0 @@ -/- -Copyright (c) 2026 Raphael Douglas Giles. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Raphael Douglas Giles --/ -module - -public import Mathlib.Topology.LocallyFinsupp -public import Mathlib.Topology.Spectral.Basic - -/-! -# Pushforward of functions with locally finite support - -In this file we define the notion of the pushforward of a function with locally finite support -between prespectral spaces. This is a nonstandard notion that arises because of our choice in -mathlib to model algebraic cycles as functions with locally finite support. -This makes it so that standard notions in the theory of cycles can be defined in more generality -than usual, and allows us to reuse a lot of API to develop the theory of cycles. - -In the usual definition of the proper pushforward of algebraic cycles, one needs to adjust the -coefficients by scaling by the degree of the corresponding extension of residue fields (assuming -the dimensions are the same and hence that this is a finite extension), or in the case where the -dimensions of the points differ scaling by zero. This is described in more detail in stacks 02R4. -The exact values of this scaling function are not relevant for the mere construction of the -pushforward, so our definition of the pushforward of a cycle `c` on a scheme `X` with coefficients -in `R` is done with respect to some `w : X → R`, about which we do not assume anything. --/ - -@[expose] public section - -open Set Order Topology TopologicalSpace - -universe u v -variable {X Y R : Type*} [TopologicalSpace X] [TopologicalSpace Y] - {f : X → Y} (hf : IsSpectralMap f) (w : X → R) - -namespace Function.locallyFinsupp - -section map - -variable [Semiring R] {W : Set Y} (hW : IsOpen W) (c : Function.locallyFinsupp X R) - -variable [PrespectralSpace Y] - -variable (f) in -/-- -The pushforward of a function `c` of locally finite support -by a spectral map with respect to a weight function `w`. This is mainly used when interpretting -locally fin supp functions as algebraic cycles (in this case the weight function would be as -described in stacks 02R4, where the weight function is the degree of the corresponding extension of -residue fields if the dimensions of the points correspond, and is zero otherwise). --/ -noncomputable -def map (hf : IsSpectralMap f) (c : locallyFinsupp X R) : Function.locallyFinsupp Y R where - toFun z := ∑ᶠ x ∈ f ⁻¹' {z}, c x * w x - supportWithinDomain' := by simp - supportLocallyFiniteWithinDomain' y _ := by - obtain ⟨U, hU⟩ := (PrespectralSpace.isTopologicalBasis (X := Y)).exists_subset_of_mem_open - (by simp : y ∈ ⊤) (by simp) - refine ⟨U, IsOpen.mem_nhds hU.1.1 hU.2.1, ?_⟩ - suffices h : (U ∩ {z | (f ⁻¹' {z} ∩ support ⇑c).Nonempty}).Finite by - refine h.subset (inter_subset_inter_right U fun y hy ↦ ?_) - obtain ⟨x, (hx : f x = y), h'⟩ := exists_ne_zero_of_finsum_mem_ne_zero hy - use x - grind [mem_support] - suffices (f ⁻¹' (U ∩ {z | (f ⁻¹' {z} ∩ c.support).Nonempty}) ∩ c.support).Finite from - (this.image f).subset (fun a ha ↦ by grind [Set.Nonempty]) - exact (c.locallyFiniteSupport.finite_inter_support_of_isCompact <| hf.2 hU.1.1 hU.1.2).subset - (by simp; grind) - -@[simp] -lemma map_apply (hf : IsSpectralMap f) (c : locallyFinsupp X R) (y : Y) : - map f w hf c y = ∑ᶠ x ∈ f ⁻¹' {y}, c x * w x := rfl - -lemma eq_finsetSum_of_hasCompactFibers (hf' : HasCompactFibers f) (y : Y) : - map f w hf c y = - ∑ x ∈ (c.locallyFiniteSupport.finite_inter_support_of_isCompact (hf' y)).toFinset, - c x * w x := by - simp only [map_apply, mem_preimage, mem_singleton_iff, Function.locallyFinsuppWithin.toFun_eq_coe] - apply finsum_cond_eq_sum_of_cond_iff - grind [Finite.mem_toFinset, mem_support] - -lemma map_homogeneous (s : Set X) (t : Set Y) (hc : c.support ⊆ s) - (h : ∀ x : X, x ∈ s → w x ≠ 0 → f x ∈ t) : (map f w hf c).support ⊆ t := by - intro y hy - obtain ⟨x, (rfl : f x = y), h'⟩ := exists_ne_zero_of_finsum_mem_ne_zero hy - grind [mem_support] - -/-- -The pushforward of `c` along the identity morphism is `c` as long as the weight function is `1` -everywhere. One should note that typically this weight function depends on the map, so this -condition that the weight function must be trivial here is less strange than it may appear at first. --/ -@[simp] -lemma map_id [PrespectralSpace X] (hw : ∀ z : X, w z = 1) : - map id w isSpectralMap_id c = c := by - ext - simp [map, hw] - -end map -end Function.locallyFinsupp From b6865bbcda7ee81964fc868a262f33ba298c9d1a Mon Sep 17 00:00:00 2001 From: Raph-DG Date: Thu, 21 May 2026 20:47:01 +0200 Subject: [PATCH 63/70] Update Mathlib.lean --- Mathlib.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib.lean b/Mathlib.lean index 404da0425d0d17..10f6ad3a47470d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7731,7 +7731,6 @@ public import Mathlib.Topology.LocallyConstant.Algebra public import Mathlib.Topology.LocallyConstant.Basic public import Mathlib.Topology.LocallyFinite public import Mathlib.Topology.LocallyFinsupp -public import Mathlib.Topology.LocallyFinsupp.Pushforward public import Mathlib.Topology.Maps.Basic public import Mathlib.Topology.Maps.OpenQuotient public import Mathlib.Topology.Maps.Proper.Basic From 64e599f080943789ed823546c9c790ed6024a716 Mon Sep 17 00:00:00 2001 From: FMLJohn <128468682+FMLJohn@users.noreply.github.com> Date: Thu, 4 Jun 2026 21:53:16 +0100 Subject: [PATCH 64/70] map_properties --- Mathlib.lean | 1 + Mathlib/Topology/Compactness/Compact.lean | 7 + .../Spectral/ConstructibleTopology.lean | 7 + Mathlib/Topology/Spectral/Maps.lean | 147 ++++++++++++++++++ 4 files changed, 162 insertions(+) create mode 100644 Mathlib/Topology/Spectral/Maps.lean diff --git a/Mathlib.lean b/Mathlib.lean index 10f6ad3a47470d..ed252e74e1eedd 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7928,6 +7928,7 @@ public import Mathlib.Topology.Specialization public import Mathlib.Topology.Spectral.Basic public import Mathlib.Topology.Spectral.ConstructibleTopology public import Mathlib.Topology.Spectral.Hom +public import Mathlib.Topology.Spectral.Maps public import Mathlib.Topology.Spectral.Prespectral public import Mathlib.Topology.Subpath public import Mathlib.Topology.TietzeExtension diff --git a/Mathlib/Topology/Compactness/Compact.lean b/Mathlib/Topology/Compactness/Compact.lean index a0dbd44e6862e2..99f603a2e323eb 100644 --- a/Mathlib/Topology/Compactness/Compact.lean +++ b/Mathlib/Topology/Compactness/Compact.lean @@ -555,6 +555,13 @@ theorem isCompact_generateFrom' [T : TopologicalSpace X] have ⟨J, hJ, cover⟩ := h P (fun a ↦ ⟨a.1, hP a.2⟩) (sUnion_eq_iUnion ▸ hs) ⟨(·.1) '' J, ⟨by simp, hJ.image _, by aesop⟩⟩ +omit [TopologicalSpace X] in +lemma isCompact_of_le_of_isCompact {S T : TopologicalSpace X} + (hST : S ≤ T) {s : Set X} (hs : @IsCompact _ S s) : @IsCompact _ T s := by + refine isCompact_iff_finite_subcover.2 ?_ + intro ι U hιU hsU + exact (@isCompact_iff_finite_subcover X S s).1 hs U (fun i => hST (U i) (hιU i)) hsU + namespace Filter theorem hasBasis_cocompact : (cocompact X).HasBasis IsCompact compl := diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 2afbee3dba9cbc..58cd247bc53019 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -42,6 +42,13 @@ the open and compact sets of `X` and their complements. -/ def constructibleTopology (X : Type*) [TopologicalSpace X] : TopologicalSpace X := .generateFrom (constructibleTopologySubbasis X) +lemma constructibleTopology_le (X : Type*) [T : TopologicalSpace X] + [CompactSpace X] [QuasiSeparatedSpace X] [PrespectralSpace X] : + constructibleTopology X ≤ T := + PrespectralSpace.isTopologicalBasis (X := X).eq_generateFrom ▸ + le_generateFrom fun _ hs => TopologicalSpace.isOpen_generateFrom_of_mem <| + PrespectralSpace.isTopologicalBasis (X := X).eq_generateFrom ▸ Or.intro_left _ hs + /-- A type synonym for `X` that is equipped with the constructible topology of `X`. -/ @[nolint unusedArguments] def WithConstructibleTopology (X : Type*) [TopologicalSpace X] : Type _ := diff --git a/Mathlib/Topology/Spectral/Maps.lean b/Mathlib/Topology/Spectral/Maps.lean new file mode 100644 index 00000000000000..ccd3e02619531c --- /dev/null +++ b/Mathlib/Topology/Spectral/Maps.lean @@ -0,0 +1,147 @@ +/- +Copyright (c) 2026 Fangming Li. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Fangming Li +-/ +module + +public import Mathlib.Topology.Spectral.ConstructibleTopology +public import Mathlib.Topology.Spectral.Hom + +/-! +# Properties of maps between spectral spaces + +This file proves properties of maps between spectral spaces. The results are stated in terms of +individual typeclasses rather than for spectral spaces directly; they apply in particular to +spectral spaces, which satisfy all the required hypotheses. + +## Main declarations + +* `IsSpectralMap.constructibleTopology_eq_induced_of_isEmbedding`: For a spectral embedding + `f : X → Y`, the constructible topology on `X` is the same as the topology induced by the + constructible topology on `Y` via `f`. +* `isSpectralMap_iff_continuous_and_continuous_withConstructibleTopology`: A map `f : X → Y` is + spectral if and only if it is continuous with respect to both the original topologies and the + constructible topologies on `X` and `Y`. +* `IsEmbedding.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range`: For + an embedding `f : X → Y` whose range is closed in the constructible topology on `Y`, a subset + `s` of `X` is compact open if and only if it is the preimage of a compact open set in `Y`. +* `IsEmbedding.compactSpace_of_isClosed_withConstructibleTopology_range`: If `f : X → Y` is an + embedding whose range is closed in the constructible topology on `Y`, then `X` is compact. +* `IsEmbedding.quasiSeparatedSpace_of_isClosed_withConstructibleTopology_range`: If `f : X → Y` + is an embedding whose range is closed in the constructible topology on `Y`, then `X` is + quasi-separated. +-/ + +@[expose] public section + +variable {X Y : Type*} [TopologicalSpace X] [T : TopologicalSpace Y] + +open TopologicalSpace Topology + +lemma Topology.IsEmbedding.exists_of_isOpen_isCompact [PrespectralSpace Y] + {f : X → Y} (hf : IsEmbedding f) {s : Set X} (hs1 : IsOpen s) (hs2 : IsCompact s) : + ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := by + obtain ⟨S, hS⟩ := eq_sUnion_finset_of_isTopologicalBasis_of_isCompact_open _ (hf.eq_induced ▸ + IsTopologicalBasis.induced f (PrespectralSpace.isTopologicalBasis (X := Y))) s hs2 hs1 + have : ∀ s ∈ S, ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := + fun ⟨s, o, ⟨ho1, ho2⟩, hfos⟩ hsS => ⟨o, ho1, ho2, hfos.symm⟩ + choose! U hU1 hU2 hU3 using this + refine ⟨⋃ s ∈ S, U s, isOpen_biUnion hU1, Finset.isCompact_biUnion S hU2, ?_⟩ + · exact (Set.sUnion_image _ _ ▸ hS) ▸ Set.biUnion_eq_iUnion _ _ ▸ Set.biUnion_eq_iUnion _ _ ▸ + Set.preimage_iUnion.symm ▸ Set.iUnion_congr fun ⟨t, ht⟩ => hU3 t ht + +lemma IsSpectralMap.constructibleTopology_eq_induced_of_isEmbedding + [CompactSpace X] [QuasiSeparatedSpace X] [PrespectralSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] + {f : X → Y} (hf1 : IsEmbedding f) (hf2 : IsSpectralMap f) : + constructibleTopology X = induced f (constructibleTopology Y) := by + change generateFrom (_ ∪ _) = induced f (generateFrom (_ ∪ _)) + refine induced_generateFrom_eq ▸ eq_of_le_of_ge (le_generateFrom fun s ⟨t, ht, hts⟩ => ?_) + (le_generateFrom fun s hs => ?_) + · refine ht.elim (fun ⟨ht1, ht2⟩ => ?_) (fun ⟨ht1, ht2⟩ => ?_) + · exact hts ▸ (TopologicalSpace.le_def.1 <| constructibleTopology_le X) _ + (ht1.preimage hf1.continuous) + · exact hts ▸ (isOpen_generateFrom_of_mem <| + Or.intro_right _ ⟨ht1.preimage hf2.1, t.preimage_compl ▸ hf2.2 ht1.isOpen_compl ht2⟩) + · refine isOpen_generateFrom_of_mem <| hs.elim (fun ⟨hs1, hs2⟩ => ?_) (fun ⟨hs1, hs2⟩ => ?_) + · obtain ⟨o, ho1, ho2, hsfo⟩ := hf1.exists_of_isOpen_isCompact hs1 hs2 + exact ⟨o, Or.intro_left _ ⟨ho1, ho2⟩, hsfo.symm⟩ + · obtain ⟨t, ht1, ht2, hoft⟩ := hf1.exists_of_isOpen_isCompact hs1.isOpen_compl hs2 + exact ⟨tᶜ, Or.intro_right _ ⟨ht1.isClosed_compl, (compl_compl t).symm ▸ ht2⟩, + t.preimage_compl.symm ▸ hoft ▸ compl_compl s⟩ + +lemma IsSpectralMap.continuous_withConstructibleTopology [CompactSpace X] [QuasiSeparatedSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf : IsSpectralMap f) : + Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f := by + refine continuous_generateFrom_iff.2 fun s hs => + hs.elim (fun ⟨hs1, hs2⟩ => ?_) (fun ⟨hs1, hs2⟩ => ?_) + · exact isOpen_generateFrom_of_mem <| Or.intro_left _ ⟨hf.1.isOpen_preimage s hs1, hf.2 hs1 hs2⟩ + · exact isOpen_generateFrom_of_mem <| Or.intro_right _ + ⟨hs1.preimage hf.1, s.preimage_compl ▸ hf.2 hs1.isOpen_compl hs2⟩ + +lemma isCompact_preimage_withConstructibleTopology_of_continuous + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] + [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} + (hf : Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f) + {s : Set Y} (hs1 : IsOpen s) (hs2 : IsCompact s) : + IsCompact (X := WithConstructibleTopology X) (f ⁻¹' s) := + IsClosed.isCompact <| IsClosed.preimage hf <| + (@isOpen_compl_iff _ _ (generateFrom _)).1 <| isOpen_generateFrom_of_mem <| + Or.intro_right _ ⟨hs1.isClosed_compl, (compl_compl s).symm ▸ hs2⟩ + +lemma isSpectralMap_of_continuous_of_continuous_withConstructibleTopology + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf1 : Continuous f) + (hf2 : Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f) : + IsSpectralMap f := + ⟨hf1, fun _ hs1 hs2 => isCompact_of_le_of_isCompact (constructibleTopology_le X) <| + isCompact_preimage_withConstructibleTopology_of_continuous hf2 hs1 hs2⟩ + +lemma isSpectralMap_iff_continuous_and_continuous_withConstructibleTopology + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] (f : X → Y) : + IsSpectralMap f ↔ Continuous f ∧ + Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f := + ⟨fun hf => ⟨hf.toContinuous, hf.continuous_withConstructibleTopology⟩, + fun ⟨hf1, hf2⟩ => isSpectralMap_of_continuous_of_continuous_withConstructibleTopology hf1 hf2⟩ + +namespace Topology.IsEmbedding + +lemma isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range [CompactSpace Y] + [QuasiSober Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] {f : X → Y} (hf : IsEmbedding f) + (hfX : IsClosed (X := WithConstructibleTopology Y) (Set.range f)) (s : Set X) : + (IsOpen s ∧ IsCompact s) ↔ ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := by + refine ⟨fun ⟨hs1, hs2⟩ => hf.exists_of_isOpen_isCompact hs1 hs2, + fun ⟨o, ho1, ho2, hsfo⟩ => ⟨hsfo ▸ IsOpen.preimage hf.continuous ho1, ?_⟩⟩ + · have h1 : IsClosed (X := WithConstructibleTopology Y) o := + isOpen_compl_iff.1 <| isOpen_generateFrom_of_mem <| + Or.intro_right _ ⟨ho1.isClosed_compl, (compl_compl o).symm ▸ ho2⟩ + have h2 : IsCompact (f '' s) := + (hsfo ▸ Set.image_preimage_eq_range_inter.symm) ▸ + (isCompact_of_le_of_isCompact (constructibleTopology_le Y) (hfX.inter h1).isCompact) + exact (hf.isCompact_iff).2 h2 + +lemma compactSpace_of_isClosed_withConstructibleTopology_range [CompactSpace Y] [QuasiSober Y] + [QuasiSeparatedSpace Y] [PrespectralSpace Y] {f : X → Y} (hf : IsEmbedding f) + (hfX : IsClosed (X := WithConstructibleTopology Y) (Set.range f)) : CompactSpace X := + ⟨((hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range hfX Set.univ).2 + ⟨Set.univ, isOpen_univ, isCompact_univ, Set.preimage_univ.symm⟩).2⟩ + +lemma quasiSeparatedSpace_of_isClosed_withConstructibleTopology_range + [CompactSpace Y] [QuasiSober Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] {f : X → Y} + (hf : IsEmbedding f) (hfX : IsClosed (X := WithConstructibleTopology Y) (Set.range f)) : + QuasiSeparatedSpace X := by + refine ⟨fun s t hs1 hs2 ht1 ht2 => ?_⟩ + · obtain ⟨u, hu1, hu2, hsfu⟩ := + (hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range hfX s).1 + ⟨hs1, hs2⟩ + obtain ⟨v, hv1, hv2, htfv⟩ := + (hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range hfX t).1 + ⟨ht1, ht2⟩ + exact hsfu ▸ htfv ▸ Set.preimage_inter ▸ + ((hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range + hfX (f ⁻¹' (u ∩ v))).2 ⟨u ∩ v, IsOpen.inter hu1 hv1, + QuasiSeparatedSpace.inter_isCompact u v hu1 hu2 hv1 hv2, rfl⟩).2 + +end Topology.IsEmbedding From 6b1bce558bafb5c28bf75dabb17a60ce23a63dec Mon Sep 17 00:00:00 2001 From: FMLJohn <128468682+FMLJohn@users.noreply.github.com> Date: Sat, 6 Jun 2026 16:50:41 +0100 Subject: [PATCH 65/70] merge with #39663 --- Mathlib.lean | 1 - .../Spectral/ConstructibleTopology.lean | 31 +++- Mathlib/Topology/Spectral/Maps.lean | 147 ------------------ 3 files changed, 29 insertions(+), 150 deletions(-) delete mode 100644 Mathlib/Topology/Spectral/Maps.lean diff --git a/Mathlib.lean b/Mathlib.lean index ed252e74e1eedd..10f6ad3a47470d 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -7928,7 +7928,6 @@ public import Mathlib.Topology.Specialization public import Mathlib.Topology.Spectral.Basic public import Mathlib.Topology.Spectral.ConstructibleTopology public import Mathlib.Topology.Spectral.Hom -public import Mathlib.Topology.Spectral.Maps public import Mathlib.Topology.Spectral.Prespectral public import Mathlib.Topology.Subpath public import Mathlib.Topology.TietzeExtension diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 58cd247bc53019..d4530b61168f96 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -1,7 +1,7 @@ /- Copyright (c) 2025 Jiedong Jiang, Christian Merten. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Johan Commelin, Jiedong Jiang, Christian Merten +Authors: Johan Commelin, Jiedong Jiang, Fangming Li, Christian Merten -/ module @@ -57,7 +57,7 @@ def WithConstructibleTopology (X : Type*) [TopologicalSpace X] : Type _ := instance : TopologicalSpace (WithConstructibleTopology X) := fast_instance% constructibleTopology X -open Topology +open TopologicalSpace Topology lemma IsCompact.isOpen_constructibleTopology_of_isOpen {s : Set X} (hs : IsCompact s) (ho : IsOpen s) : IsOpen[constructibleTopology X] s := by @@ -239,6 +239,33 @@ lemma WithConstructibleTopology.map_continuous {f : X → Y} (hf : IsSpectralMap (hf.isCompact_preimage_of_isOpen hscl.isOpen_compl hsc).isOpen_constructibleTopology_of_isClosed (hscl.preimage hf.continuous) +lemma WithConstructibleTopology.isCompact_preimage_of_map_continuous + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] + [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] + {f : X → Y} (hf : Continuous <| WithConstructibleTopology.map f) + {s : Set Y} (hs1 : IsOpen s) (hs2 : IsCompact s) : + @IsCompact X (constructibleTopology X) (f ⁻¹' s) := + letI : @CompactSpace X (constructibleTopology X) := compactSpace_withConstructibleTopology + letI := constructibleTopology X + IsClosed.isCompact <| IsClosed.preimage hf <| + (@isOpen_compl_iff _ _ (generateFrom _)).1 <| isOpen_generateFrom_of_mem <| + Or.intro_right _ ⟨hs1.isClosed_compl, (compl_compl s).symm ▸ hs2⟩ + +lemma WithConstructibleTopology.isSpectralMap_of_continuous_of_map_continuous + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf1 : Continuous f) + (hf2 : Continuous <| WithConstructibleTopology.map f) : + IsSpectralMap f := + ⟨hf1, fun _ hs1 hs2 => isCompact_of_le_of_isCompact (constructibleTopology_le X) <| + isCompact_preimage_of_map_continuous hf2 hs1 hs2⟩ + +lemma WithConstructibleTopology.isSpectralMap_iff_continuous_and_map_continuous + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] (f : X → Y) : + IsSpectralMap f ↔ Continuous f ∧ (Continuous <| WithConstructibleTopology.map f) := + ⟨fun hf => ⟨hf.toContinuous, map_continuous hf⟩, + fun ⟨hf1, hf2⟩ => isSpectralMap_of_continuous_of_map_continuous hf1 hf2⟩ + /-- A spectral map between *quasi-separated* pre-spectral, sober spaces has compact fibers. Note that any quasi-compact morphism of schemes has compact fibers, although the underlying diff --git a/Mathlib/Topology/Spectral/Maps.lean b/Mathlib/Topology/Spectral/Maps.lean deleted file mode 100644 index ccd3e02619531c..00000000000000 --- a/Mathlib/Topology/Spectral/Maps.lean +++ /dev/null @@ -1,147 +0,0 @@ -/- -Copyright (c) 2026 Fangming Li. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Fangming Li --/ -module - -public import Mathlib.Topology.Spectral.ConstructibleTopology -public import Mathlib.Topology.Spectral.Hom - -/-! -# Properties of maps between spectral spaces - -This file proves properties of maps between spectral spaces. The results are stated in terms of -individual typeclasses rather than for spectral spaces directly; they apply in particular to -spectral spaces, which satisfy all the required hypotheses. - -## Main declarations - -* `IsSpectralMap.constructibleTopology_eq_induced_of_isEmbedding`: For a spectral embedding - `f : X → Y`, the constructible topology on `X` is the same as the topology induced by the - constructible topology on `Y` via `f`. -* `isSpectralMap_iff_continuous_and_continuous_withConstructibleTopology`: A map `f : X → Y` is - spectral if and only if it is continuous with respect to both the original topologies and the - constructible topologies on `X` and `Y`. -* `IsEmbedding.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range`: For - an embedding `f : X → Y` whose range is closed in the constructible topology on `Y`, a subset - `s` of `X` is compact open if and only if it is the preimage of a compact open set in `Y`. -* `IsEmbedding.compactSpace_of_isClosed_withConstructibleTopology_range`: If `f : X → Y` is an - embedding whose range is closed in the constructible topology on `Y`, then `X` is compact. -* `IsEmbedding.quasiSeparatedSpace_of_isClosed_withConstructibleTopology_range`: If `f : X → Y` - is an embedding whose range is closed in the constructible topology on `Y`, then `X` is - quasi-separated. --/ - -@[expose] public section - -variable {X Y : Type*} [TopologicalSpace X] [T : TopologicalSpace Y] - -open TopologicalSpace Topology - -lemma Topology.IsEmbedding.exists_of_isOpen_isCompact [PrespectralSpace Y] - {f : X → Y} (hf : IsEmbedding f) {s : Set X} (hs1 : IsOpen s) (hs2 : IsCompact s) : - ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := by - obtain ⟨S, hS⟩ := eq_sUnion_finset_of_isTopologicalBasis_of_isCompact_open _ (hf.eq_induced ▸ - IsTopologicalBasis.induced f (PrespectralSpace.isTopologicalBasis (X := Y))) s hs2 hs1 - have : ∀ s ∈ S, ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := - fun ⟨s, o, ⟨ho1, ho2⟩, hfos⟩ hsS => ⟨o, ho1, ho2, hfos.symm⟩ - choose! U hU1 hU2 hU3 using this - refine ⟨⋃ s ∈ S, U s, isOpen_biUnion hU1, Finset.isCompact_biUnion S hU2, ?_⟩ - · exact (Set.sUnion_image _ _ ▸ hS) ▸ Set.biUnion_eq_iUnion _ _ ▸ Set.biUnion_eq_iUnion _ _ ▸ - Set.preimage_iUnion.symm ▸ Set.iUnion_congr fun ⟨t, ht⟩ => hU3 t ht - -lemma IsSpectralMap.constructibleTopology_eq_induced_of_isEmbedding - [CompactSpace X] [QuasiSeparatedSpace X] [PrespectralSpace X] - [CompactSpace Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] - {f : X → Y} (hf1 : IsEmbedding f) (hf2 : IsSpectralMap f) : - constructibleTopology X = induced f (constructibleTopology Y) := by - change generateFrom (_ ∪ _) = induced f (generateFrom (_ ∪ _)) - refine induced_generateFrom_eq ▸ eq_of_le_of_ge (le_generateFrom fun s ⟨t, ht, hts⟩ => ?_) - (le_generateFrom fun s hs => ?_) - · refine ht.elim (fun ⟨ht1, ht2⟩ => ?_) (fun ⟨ht1, ht2⟩ => ?_) - · exact hts ▸ (TopologicalSpace.le_def.1 <| constructibleTopology_le X) _ - (ht1.preimage hf1.continuous) - · exact hts ▸ (isOpen_generateFrom_of_mem <| - Or.intro_right _ ⟨ht1.preimage hf2.1, t.preimage_compl ▸ hf2.2 ht1.isOpen_compl ht2⟩) - · refine isOpen_generateFrom_of_mem <| hs.elim (fun ⟨hs1, hs2⟩ => ?_) (fun ⟨hs1, hs2⟩ => ?_) - · obtain ⟨o, ho1, ho2, hsfo⟩ := hf1.exists_of_isOpen_isCompact hs1 hs2 - exact ⟨o, Or.intro_left _ ⟨ho1, ho2⟩, hsfo.symm⟩ - · obtain ⟨t, ht1, ht2, hoft⟩ := hf1.exists_of_isOpen_isCompact hs1.isOpen_compl hs2 - exact ⟨tᶜ, Or.intro_right _ ⟨ht1.isClosed_compl, (compl_compl t).symm ▸ ht2⟩, - t.preimage_compl.symm ▸ hoft ▸ compl_compl s⟩ - -lemma IsSpectralMap.continuous_withConstructibleTopology [CompactSpace X] [QuasiSeparatedSpace X] - [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf : IsSpectralMap f) : - Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f := by - refine continuous_generateFrom_iff.2 fun s hs => - hs.elim (fun ⟨hs1, hs2⟩ => ?_) (fun ⟨hs1, hs2⟩ => ?_) - · exact isOpen_generateFrom_of_mem <| Or.intro_left _ ⟨hf.1.isOpen_preimage s hs1, hf.2 hs1 hs2⟩ - · exact isOpen_generateFrom_of_mem <| Or.intro_right _ - ⟨hs1.preimage hf.1, s.preimage_compl ▸ hf.2 hs1.isOpen_compl hs2⟩ - -lemma isCompact_preimage_withConstructibleTopology_of_continuous - [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] - [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} - (hf : Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f) - {s : Set Y} (hs1 : IsOpen s) (hs2 : IsCompact s) : - IsCompact (X := WithConstructibleTopology X) (f ⁻¹' s) := - IsClosed.isCompact <| IsClosed.preimage hf <| - (@isOpen_compl_iff _ _ (generateFrom _)).1 <| isOpen_generateFrom_of_mem <| - Or.intro_right _ ⟨hs1.isClosed_compl, (compl_compl s).symm ▸ hs2⟩ - -lemma isSpectralMap_of_continuous_of_continuous_withConstructibleTopology - [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] - [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf1 : Continuous f) - (hf2 : Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f) : - IsSpectralMap f := - ⟨hf1, fun _ hs1 hs2 => isCompact_of_le_of_isCompact (constructibleTopology_le X) <| - isCompact_preimage_withConstructibleTopology_of_continuous hf2 hs1 hs2⟩ - -lemma isSpectralMap_iff_continuous_and_continuous_withConstructibleTopology - [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] - [CompactSpace Y] [QuasiSeparatedSpace Y] (f : X → Y) : - IsSpectralMap f ↔ Continuous f ∧ - Continuous (X := WithConstructibleTopology X) (Y := WithConstructibleTopology Y) f := - ⟨fun hf => ⟨hf.toContinuous, hf.continuous_withConstructibleTopology⟩, - fun ⟨hf1, hf2⟩ => isSpectralMap_of_continuous_of_continuous_withConstructibleTopology hf1 hf2⟩ - -namespace Topology.IsEmbedding - -lemma isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range [CompactSpace Y] - [QuasiSober Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] {f : X → Y} (hf : IsEmbedding f) - (hfX : IsClosed (X := WithConstructibleTopology Y) (Set.range f)) (s : Set X) : - (IsOpen s ∧ IsCompact s) ↔ ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := by - refine ⟨fun ⟨hs1, hs2⟩ => hf.exists_of_isOpen_isCompact hs1 hs2, - fun ⟨o, ho1, ho2, hsfo⟩ => ⟨hsfo ▸ IsOpen.preimage hf.continuous ho1, ?_⟩⟩ - · have h1 : IsClosed (X := WithConstructibleTopology Y) o := - isOpen_compl_iff.1 <| isOpen_generateFrom_of_mem <| - Or.intro_right _ ⟨ho1.isClosed_compl, (compl_compl o).symm ▸ ho2⟩ - have h2 : IsCompact (f '' s) := - (hsfo ▸ Set.image_preimage_eq_range_inter.symm) ▸ - (isCompact_of_le_of_isCompact (constructibleTopology_le Y) (hfX.inter h1).isCompact) - exact (hf.isCompact_iff).2 h2 - -lemma compactSpace_of_isClosed_withConstructibleTopology_range [CompactSpace Y] [QuasiSober Y] - [QuasiSeparatedSpace Y] [PrespectralSpace Y] {f : X → Y} (hf : IsEmbedding f) - (hfX : IsClosed (X := WithConstructibleTopology Y) (Set.range f)) : CompactSpace X := - ⟨((hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range hfX Set.univ).2 - ⟨Set.univ, isOpen_univ, isCompact_univ, Set.preimage_univ.symm⟩).2⟩ - -lemma quasiSeparatedSpace_of_isClosed_withConstructibleTopology_range - [CompactSpace Y] [QuasiSober Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] {f : X → Y} - (hf : IsEmbedding f) (hfX : IsClosed (X := WithConstructibleTopology Y) (Set.range f)) : - QuasiSeparatedSpace X := by - refine ⟨fun s t hs1 hs2 ht1 ht2 => ?_⟩ - · obtain ⟨u, hu1, hu2, hsfu⟩ := - (hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range hfX s).1 - ⟨hs1, hs2⟩ - obtain ⟨v, hv1, hv2, htfv⟩ := - (hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range hfX t).1 - ⟨ht1, ht2⟩ - exact hsfu ▸ htfv ▸ Set.preimage_inter ▸ - ((hf.isOpen_and_isCompact_iff_exists_of_isClosed_withConstructibleTopology_range - hfX (f ⁻¹' (u ∩ v))).2 ⟨u ∩ v, IsOpen.inter hu1 hv1, - QuasiSeparatedSpace.inter_isCompact u v hu1 hu2 hv1 hv2, rfl⟩).2 - -end Topology.IsEmbedding From 5c7a1b9d57aa284719d04793954e4e210210549f Mon Sep 17 00:00:00 2001 From: FMLJohn <128468682+FMLJohn@users.noreply.github.com> Date: Sun, 7 Jun 2026 00:54:27 +0100 Subject: [PATCH 66/70] refine definitions --- Mathlib/Topology/Defs/Induced.lean | 7 ++ .../Spectral/ConstructibleTopology.lean | 105 +++++++++++------- Mathlib/Topology/WithTopology.lean | 14 +++ 3 files changed, 88 insertions(+), 38 deletions(-) diff --git a/Mathlib/Topology/Defs/Induced.lean b/Mathlib/Topology/Defs/Induced.lean index c652bd260cf68d..549fda82c78a85 100644 --- a/Mathlib/Topology/Defs/Induced.lean +++ b/Mathlib/Topology/Defs/Induced.lean @@ -108,6 +108,13 @@ protected def equiv (X : Type*) (t : TopologicalSpace X) : WithTopology X t ≃ left_inv _ := rfl right_inv _ := rfl +/-- +Induced map `lift f : WithTopology X → WithTopology Y` by a map `f : X → Y`. +-/ +def map {X Y : Type*} (s : TopologicalSpace X) (t : TopologicalSpace Y) (f : X → Y) : + WithTopology X s → WithTopology Y t := + (WithTopology.equiv Y t).symm ∘ f ∘ WithTopology.equiv X s + end WithTopology namespace Topology diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index cb250c7d0a2d7b..8174e1a7683873 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -93,16 +93,12 @@ lemma isCompact_sInter_of_subset_constructibleTopologySubbasis [CompactSpace X] · apply (hs ht).imp <;> grind · exact isCompact_of_mem_constructibleTopologySubbasis (hs ht) -/-- If `X` is quasi-separated, quasi-sober, prespectral and quasi-compact, then `X` -is still quasi-compact in the constructible topology. This holds in particular for spectral -spaces. -/ +/-- If `X` is quasi-separated, quasi-sober, prespectral and quasi-compact, then `X` is still +quasi-compact in the constructible topology. This holds in particular for spectral spaces. -/ @[stacks 0901 "quasi-compactness"] -instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] - [PrespectralSpace X] [QuasiSeparatedSpace X] : - CompactSpace (WithConstructibleTopology X) := by - suffices h : @CompactSpace X (constructibleTopology X) from - @Function.Surjective.compactSpace _ _ (constructibleTopology X) _ _ - (WithTopology.continuous_toTopology _) _ (WithTopology.toTopology_surjective _) +instance compactSpace_constructibleTopology [CompactSpace X] + [QuasiSober X] [PrespectralSpace X] [QuasiSeparatedSpace X] : + @CompactSpace X (constructibleTopology X) := by let 𝔅 := constructibleTopologySubbasis X /- It suffices to check that any subset of `𝔅` for which every finite subset has non-empty intersection, has non-empty intersection. We argue by contradiction and by Zorn's @@ -172,38 +168,60 @@ instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] refine hB.prop.2.1 (_ ∪ F) ?_ <| (hA₁'.diff.union hA₂'.diff).union hF grind [Set.diff_singleton_subset_iff, Set.union_subset_iff] -instance [PrespectralSpace X] [T0Space X] [QuasiSober X] : - T2Space <| WithConstructibleTopology X := by - constructor - intro x y hxy - wlog h : ∃ (U : Set X), IsOpen U ∧ x ∈ U ∧ y ∉ U - · have o : ∃ (U : Set X), IsOpen U ∧ y ∈ U ∧ x ∉ U := by - obtain ⟨U, hU1, (o | o)⟩ := exists_isOpen_xor_mem (X := X) hxy <;> use U - · simp only [not_exists, not_and, not_not] at h - exact (o.2 (h U hU1 o.1)).elim - · exact ⟨hU1, o⟩ - obtain ⟨U, V, a, b, c, d, e⟩ := @this X _ _ _ _ y x hxy.symm o - exact ⟨V, U, b, a, d, c, e.symm⟩ - obtain ⟨U, hU1, hU2, hU3⟩ := h - obtain ⟨V, ⟨hVo, hVc⟩, hV, hVU⟩ := - PrespectralSpace.isTopologicalBasis.mem_nhds_iff.mp (hU1.mem_nhds ‹_›) - · exact ⟨V, Vᶜ, - TopologicalSpace.isOpen_generateFrom_of_mem (.inl ⟨hVo, hVc⟩), - TopologicalSpace.isOpen_generateFrom_of_mem - (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), - hV, Set.mem_compl (fun h ↦ hU3 (hVU h)), disjoint_compl_right⟩ +/-- If `X` is quasi-separated, quasi-sober, prespectral and quasi-compact, then `X` is still +quasi-compact in the constructible topology. This holds in particular for spectral spaces. -/ +@[stacks 0901 "quasi-compactness"] +instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] + [PrespectralSpace X] [QuasiSeparatedSpace X] : + CompactSpace (WithConstructibleTopology X) := + @Function.Surjective.compactSpace _ _ (constructibleTopology X) _ _ + (WithTopology.continuous_toTopology _) compactSpace_constructibleTopology + (WithTopology.toTopology_surjective _) + +/-- If `X` is prespectral, T0 and quasi-sober, then `X` is T2 in the +constructible topology. This holds in particular for spectral spaces. -/ +@[stacks 0901 "Hausdorffness"] +instance t2Space_constructibleTopology [PrespectralSpace X] [T0Space X] + [QuasiSober X] : @T2Space X (constructibleTopology X) := by + simp only [t2Space_iff] + intro x y hxy + wlog h : ∃ (U : Set X), IsOpen U ∧ x ∈ U ∧ y ∉ U + · have o : ∃ (U : Set X), IsOpen U ∧ y ∈ U ∧ x ∉ U := by + obtain ⟨U, hU1, (o | o)⟩ := exists_isOpen_xor_mem (X := X) hxy <;> use U + · simp only [not_exists, not_and, not_not] at h + exact (o.2 (h U hU1 o.1)).elim + obtain ⟨U, V, a, b, c, d, e⟩ := @this X _ _ _ _ y x hxy.symm o + exact ⟨V, U, b, a, d, c, e.symm⟩ + obtain ⟨U, hU1, hU2, hU3⟩ := h + obtain ⟨V, ⟨hVo, hVc⟩, hV, hVU⟩ := + PrespectralSpace.isTopologicalBasis.mem_nhds_iff.mp (hU1.mem_nhds ‹_›) + · exact ⟨V, Vᶜ, + TopologicalSpace.isOpen_generateFrom_of_mem (.inl ⟨hVo, hVc⟩), + TopologicalSpace.isOpen_generateFrom_of_mem + (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), + hV, Set.mem_compl (fun h ↦ hU3 (hVU h)), disjoint_compl_right⟩ + +/-- If `X` is prespectral, T0 and quasi-sober, then `X` is T2 in the +constructible topology. This holds in particular for spectral spaces. -/ +@[stacks 0901 "Hausdorffness"] +instance t2Space_withConstructibleTopology [PrespectralSpace X] [T0Space X] + [QuasiSober X] : T2Space <| WithConstructibleTopology X := + @T2Space.of_injective_continuous (WithConstructibleTopology X) X _ + (constructibleTopology X) t2Space_constructibleTopology WithTopology.ofTopology + (WithTopology.ofTopology_injective (constructibleTopology X)) + (WithTopology.continuous_ofTopology (constructibleTopology X)) /-- Canonical map from a space `X` to `WithConstructibleTopology X` -/ def toConstructibleTopology (X) [TopologicalSpace X] : X ≃ WithConstructibleTopology X := - Equiv.refl _ + (WithTopology.equiv X (constructibleTopology X)).symm /-- Canonical map from a space `WithConstructibleTopology X` to `X` -/ def WithConstructibleTopology.equiv (X) [TopologicalSpace X] : WithConstructibleTopology X ≃ X := - Equiv.refl _ + WithTopology.equiv X (constructibleTopology X) variable {Y : Type*} [TopologicalSpace Y] /-- @@ -214,6 +232,11 @@ def WithConstructibleTopology.map (f : X → Y) : WithConstructibleTopology X → WithConstructibleTopology Y := (equiv Y).symm ∘ f ∘ equiv X +lemma WithConstructibleTopology.map_eq_map (f : X → Y) : + WithConstructibleTopology.map f = + WithTopology.map (constructibleTopology X) (constructibleTopology Y) f := + rfl + @[simp] lemma WithConstructibleTopology.map_id (x : WithConstructibleTopology X) : WithConstructibleTopology.map id x = x := rfl @@ -237,8 +260,14 @@ lemma WithConstructibleTopology.continuous_equiv [PrespectralSpace X] : rw [isOpen_ofConstructibleTopology_preimage_iff] exact hU.isOpen_constructibleTopology_of_isOpen U.2 +lemma WithConstructibleTopology.map_continuous_iff (f : X → Y) : + Continuous (WithConstructibleTopology.map f) ↔ + @Continuous X Y (constructibleTopology X) (constructibleTopology Y) f := + WithTopology.map_continuous_iff (constructibleTopology X) (constructibleTopology Y) f + lemma WithConstructibleTopology.map_continuous {f : X → Y} (hf : IsSpectralMap f) : Continuous <| WithConstructibleTopology.map f := by + apply (WithTopology.map_continuous_iff ..).2 apply continuous_generateFrom_iff.mpr intro s hs obtain ⟨hso, hsc⟩ | ⟨hscl, hsc⟩ := hs @@ -253,12 +282,13 @@ lemma WithConstructibleTopology.isCompact_preimage_of_map_continuous [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf : Continuous <| WithConstructibleTopology.map f) {s : Set Y} (hs1 : IsOpen s) (hs2 : IsCompact s) : - @IsCompact X (constructibleTopology X) (f ⁻¹' s) := - letI : @CompactSpace X (constructibleTopology X) := compactSpace_withConstructibleTopology + @IsCompact X (constructibleTopology X) (f ⁻¹' s) := by + have hf' := (map_continuous_iff f).1 hf letI := constructibleTopology X - IsClosed.isCompact <| IsClosed.preimage hf <| - (@isOpen_compl_iff _ _ (generateFrom _)).1 <| isOpen_generateFrom_of_mem <| - Or.intro_right _ ⟨hs1.isClosed_compl, (compl_compl s).symm ▸ hs2⟩ + apply IsClosed.isCompact + apply @IsClosed.preimage X Y _ (constructibleTopology Y) f hf' + exact (@isOpen_compl_iff _ _ (generateFrom _)).1 <| isOpen_generateFrom_of_mem <| + Or.intro_right _ ⟨hs1.isClosed_compl, (compl_compl s).symm ▸ hs2⟩ lemma WithConstructibleTopology.isSpectralMap_of_continuous_of_map_continuous [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] @@ -297,5 +327,4 @@ lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSepa have hg : IsSpectralMap g := hf.comp hfUo.isOpenEmbedding_subtypeVal.isSpectralMap_of_compactSpace have heq : f ⁻¹' {y} = Subtype.val '' (g ⁻¹' {y}) := by grind [Subtype.exists] rw [heq] - exact (isClosed_singleton.preimage (WithConstructibleTopology.map_continuous hg)).isCompact.image - (continuous_subtype_val.comp WithConstructibleTopology.continuous_equiv) + sorry diff --git a/Mathlib/Topology/WithTopology.lean b/Mathlib/Topology/WithTopology.lean index 7dd7ce8d8cc117..2267651110e899 100644 --- a/Mathlib/Topology/WithTopology.lean +++ b/Mathlib/Topology/WithTopology.lean @@ -5,6 +5,7 @@ Authors: Yury Kudryashov, Gemini CLI -/ module +public import Mathlib.Topology.Continuous public import Mathlib.Topology.Defs.Induced /-! @@ -81,6 +82,19 @@ lemma continuous_toTopology : Continuous[t, _] (toTopology t) := lemma continuous_ofTopology : Continuous[_, t] (ofTopology (t := t)) := ⟨fun _ ↦ (·)⟩ +lemma ofTopology_comp_map_comp_toTopology + {Y : Type*} (s : TopologicalSpace Y) (f : X → Y) : + ofTopology ∘ map t s f ∘ toTopology t = f := by + ext + delta map + simp + +lemma map_continuous_iff {Y : Type*} (s : TopologicalSpace Y) (f : X → Y) : + (Continuous <| WithTopology.map t s f) ↔ @Continuous X Y t s f := + ⟨fun hf => ofTopology_comp_map_comp_toTopology t s f ▸ (continuous_ofTopology s).comp + (hf.comp (continuous_toTopology t)), fun hf => (continuous_toTopology s).comp + (hf.comp (continuous_ofTopology t))⟩ + /-! ### Set-theoretic lemmas -/ open Set From 733ca650796129244e3184e4c1860e42ef9d3c92 Mon Sep 17 00:00:00 2001 From: FMLJohn <128468682+FMLJohn@users.noreply.github.com> Date: Sun, 7 Jun 2026 14:57:57 +0100 Subject: [PATCH 67/70] fix `IsSpectralMap.hasCompactFibers` --- .../Topology/Spectral/ConstructibleTopology.lean | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 8174e1a7683873..d3d372e3595d69 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -260,6 +260,11 @@ lemma WithConstructibleTopology.continuous_equiv [PrespectralSpace X] : rw [isOpen_ofConstructibleTopology_preimage_iff] exact hU.isOpen_constructibleTopology_of_isOpen U.2 +lemma WithConstructibleTopology.continuous_constructibleTopology_id [PrespectralSpace X] : + @Continuous X X (constructibleTopology X) _ id := + @Continuous.comp X _ X (constructibleTopology X) _ + _ _ _ continuous_equiv (WithTopology.continuous_toTopology (constructibleTopology X)) + lemma WithConstructibleTopology.map_continuous_iff (f : X → Y) : Continuous (WithConstructibleTopology.map f) ↔ @Continuous X Y (constructibleTopology X) (constructibleTopology Y) f := @@ -267,7 +272,7 @@ lemma WithConstructibleTopology.map_continuous_iff (f : X → Y) : lemma WithConstructibleTopology.map_continuous {f : X → Y} (hf : IsSpectralMap f) : Continuous <| WithConstructibleTopology.map f := by - apply (WithTopology.map_continuous_iff ..).2 + apply (map_continuous_iff f).2 apply continuous_generateFrom_iff.mpr intro s hs obtain ⟨hso, hsc⟩ | ⟨hscl, hsc⟩ := hs @@ -327,4 +332,10 @@ lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSepa have hg : IsSpectralMap g := hf.comp hfUo.isOpenEmbedding_subtypeVal.isSpectralMap_of_compactSpace have heq : f ⁻¹' {y} = Subtype.val '' (g ⁻¹' {y}) := by grind [Subtype.exists] rw [heq] - sorry + have hg1 := (WithTopology.map_continuous_iff (constructibleTopology (f ⁻¹' U)) + (constructibleTopology Y) g).1 <| WithConstructibleTopology.map_continuous hg + have h := @Continuous.comp (f ⁻¹' U) _ X (constructibleTopology (f ⁻¹' U)) _ _ id _ + continuous_subtype_val WithConstructibleTopology.continuous_constructibleTopology_id + letI := constructibleTopology { x // x ∈ f ⁻¹' U } + letI := constructibleTopology Y + exact (isClosed_singleton.preimage hg1).isCompact.image h From c177a5b5ef958d053361d2e8413417cb68697444 Mon Sep 17 00:00:00 2001 From: FMLJohn <128468682+FMLJohn@users.noreply.github.com> Date: Sun, 7 Jun 2026 17:26:55 +0100 Subject: [PATCH 68/70] constructibleTopology_eq_induced --- .../Spectral/ConstructibleTopology.lean | 19 +++++++++++++++++++ Mathlib/Topology/Spectral/Prespectral.lean | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index d3d372e3595d69..2ef66fd6e4b16f 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -93,6 +93,25 @@ lemma isCompact_sInter_of_subset_constructibleTopologySubbasis [CompactSpace X] · apply (hs ht).imp <;> grind · exact isCompact_of_mem_constructibleTopologySubbasis (hs ht) +lemma IsSpectralMap.constructibleTopology_eq_induced_of_isEmbedding + {Y : Type*} [TopologicalSpace Y] [CompactSpace X] [QuasiSeparatedSpace X] + [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] + {f : X → Y} (hf1 : IsSpectralMap f) (hf2 : IsEmbedding f) : + constructibleTopology X = induced f (constructibleTopology Y) := by + refine induced_generateFrom_eq ▸ eq_of_le_of_ge (le_generateFrom fun s ⟨t, ht, hts⟩ => ?_) + (le_generateFrom fun s hs => ?_) + · refine ht.elim (fun ⟨ht1, ht2⟩ => ?_) (fun ⟨ht1, ht2⟩ => ?_) + · exact hts ▸ (TopologicalSpace.le_def.1 <| constructibleTopology_le X) _ + (ht1.preimage hf1.continuous) + · exact hts ▸ (isOpen_generateFrom_of_mem <| + Or.intro_right _ ⟨ht1.preimage hf1.1, t.preimage_compl ▸ hf1.2 ht1.isOpen_compl ht2⟩) + · refine isOpen_generateFrom_of_mem <| hs.elim (fun ⟨hs1, hs2⟩ => ?_) (fun ⟨hs1, hs2⟩ => ?_) + · obtain ⟨o, ho1, ho2, hsfo⟩ := hf2.exists_of_isOpen_isCompact hs1 hs2 + exact ⟨o, Or.intro_left _ ⟨ho1, ho2⟩, hsfo.symm⟩ + · obtain ⟨t, ht1, ht2, hoft⟩ := hf2.exists_of_isOpen_isCompact hs1.isOpen_compl hs2 + exact ⟨tᶜ, Or.intro_right _ ⟨ht1.isClosed_compl, (compl_compl t).symm ▸ ht2⟩, + t.preimage_compl.symm ▸ hoft ▸ compl_compl s⟩ + /-- If `X` is quasi-separated, quasi-sober, prespectral and quasi-compact, then `X` is still quasi-compact in the constructible topology. This holds in particular for spectral spaces. -/ @[stacks 0901 "quasi-compactness"] diff --git a/Mathlib/Topology/Spectral/Prespectral.lean b/Mathlib/Topology/Spectral/Prespectral.lean index c259887f6e8c49..46cdb4eff33d8d 100644 --- a/Mathlib/Topology/Spectral/Prespectral.lean +++ b/Mathlib/Topology/Spectral/Prespectral.lean @@ -161,6 +161,18 @@ lemma IsOpenMap.exists_opens_image_eq_of_prespectralSpace [PrespectralSpace X] { have := heq ▸ mem_sSup.mpr ⟨i.1, i.2, hx⟩ exact this +lemma Topology.IsEmbedding.exists_of_isOpen_isCompact [PrespectralSpace Y] + {f : X → Y} (hf : IsEmbedding f) {s : Set X} (hs1 : IsOpen s) (hs2 : IsCompact s) : + ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := by + obtain ⟨S, hS⟩ := eq_sUnion_finset_of_isTopologicalBasis_of_isCompact_open _ (hf.eq_induced ▸ + IsTopologicalBasis.induced f (PrespectralSpace.isTopologicalBasis (X := Y))) s hs2 hs1 + have : ∀ s ∈ S, ∃ o : Set Y, IsOpen o ∧ IsCompact o ∧ s = f ⁻¹' o := + fun ⟨s, o, ⟨ho1, ho2⟩, hfos⟩ hsS => ⟨o, ho1, ho2, hfos.symm⟩ + choose! U hU1 hU2 hU3 using this + refine ⟨⋃ s ∈ S, U s, isOpen_biUnion hU1, Finset.isCompact_biUnion S hU2, ?_⟩ + · exact (Set.sUnion_image _ _ ▸ hS) ▸ Set.biUnion_eq_iUnion _ _ ▸ Set.biUnion_eq_iUnion _ _ ▸ + Set.preimage_iUnion.symm ▸ Set.iUnion_congr fun ⟨t, ht⟩ => hU3 t ht + lemma PrespectralSpace.exists_isCompact_and_isOpen_between [PrespectralSpace X] {K U : Set X} (hK : IsCompact K) (hU : IsOpen U) (hKU : K ⊆ U) : ∃ (W : Set X), IsCompact W ∧ IsOpen W ∧ K ⊆ W ∧ W ⊆ U := by From 4b4dfd578a70d929fbb668e61894a14a7b6c1962 Mon Sep 17 00:00:00 2001 From: FMLJohn <128468682+FMLJohn@users.noreply.github.com> Date: Fri, 12 Jun 2026 21:48:47 +0100 Subject: [PATCH 69/70] recover --- .../Spectral/ConstructibleTopology.lean | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index 3ae28b6ae4e1b0..deff8dc5c043fb 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -186,3 +186,175 @@ instance compactSpace_constructibleTopology [CompactSpace X] · rw [← Set.sInter_union] refine hB.prop.2.1 (_ ∪ F) ?_ <| (hA₁'.sdiff.union hA₂'.sdiff).union hF grind [Set.sdiff_singleton_subset_iff, Set.union_subset_iff] + +/-- If `X` is quasi-separated, quasi-sober, prespectral and quasi-compact, then `X` is still +quasi-compact in the constructible topology. This holds in particular for spectral spaces. -/ +@[stacks 0901 "quasi-compactness"] +instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] + [PrespectralSpace X] [QuasiSeparatedSpace X] : + CompactSpace (WithConstructibleTopology X) := + @Function.Surjective.compactSpace _ _ (constructibleTopology X) _ _ + (WithTopology.continuous_toTopology _) compactSpace_constructibleTopology + (WithTopology.toTopology_surjective _) + +/-- If `X` is prespectral, T0 and quasi-sober, then `X` is T2 in the +constructible topology. This holds in particular for spectral spaces. -/ +@[stacks 0901 "Hausdorffness"] +instance t2Space_constructibleTopology [PrespectralSpace X] [T0Space X] + [QuasiSober X] : @T2Space X (constructibleTopology X) := by + simp only [t2Space_iff] + intro x y hxy + wlog h : ∃ (U : Set X), IsOpen U ∧ x ∈ U ∧ y ∉ U + · have o : ∃ (U : Set X), IsOpen U ∧ y ∈ U ∧ x ∉ U := by + obtain ⟨U, hU1, (o | o)⟩ := exists_isOpen_xor_mem (X := X) hxy <;> use U + · simp only [not_exists, not_and, not_not] at h + exact (o.2 (h U hU1 o.1)).elim + obtain ⟨U, V, a, b, c, d, e⟩ := @this X _ _ _ _ y x hxy.symm o + exact ⟨V, U, b, a, d, c, e.symm⟩ + obtain ⟨U, hU1, hU2, hU3⟩ := h + obtain ⟨V, ⟨hVo, hVc⟩, hV, hVU⟩ := + PrespectralSpace.isTopologicalBasis.mem_nhds_iff.mp (hU1.mem_nhds ‹_›) + · exact ⟨V, Vᶜ, + TopologicalSpace.isOpen_generateFrom_of_mem (.inl ⟨hVo, hVc⟩), + TopologicalSpace.isOpen_generateFrom_of_mem + (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), + hV, Set.mem_compl (fun h ↦ hU3 (hVU h)), disjoint_compl_right⟩ + +/-- If `X` is prespectral, T0 and quasi-sober, then `X` is T2 in the +constructible topology. This holds in particular for spectral spaces. -/ +@[stacks 0901 "Hausdorffness"] +instance t2Space_withConstructibleTopology [PrespectralSpace X] [T0Space X] + [QuasiSober X] : T2Space <| WithConstructibleTopology X := + @T2Space.of_injective_continuous (WithConstructibleTopology X) X _ + (constructibleTopology X) t2Space_constructibleTopology WithTopology.ofTopology + (WithTopology.ofTopology_injective (constructibleTopology X)) + (WithTopology.continuous_ofTopology (constructibleTopology X)) + +/-- +Canonical map from a space `X` to `WithConstructibleTopology X` +-/ +def toConstructibleTopology (X) [TopologicalSpace X] : X ≃ WithConstructibleTopology X := + (WithTopology.equiv X (constructibleTopology X)).symm + +/-- +Canonical map from a space `WithConstructibleTopology X` to `X` +-/ +def WithConstructibleTopology.equiv (X) [TopologicalSpace X] : WithConstructibleTopology X ≃ X := + WithTopology.equiv X (constructibleTopology X) + +variable {Y : Type*} [TopologicalSpace Y] +/-- +Induced map `lift f : WithConstructibleTopology X → WithConstructibleTopology Y` by a map +`f : X → Y` +-/ +def WithConstructibleTopology.map (f : X → Y) : + WithConstructibleTopology X → WithConstructibleTopology Y := + (equiv Y).symm ∘ f ∘ equiv X + +lemma WithConstructibleTopology.map_eq_map (f : X → Y) : + WithConstructibleTopology.map f = + WithTopology.map (constructibleTopology X) (constructibleTopology Y) f := + rfl + +@[simp] +lemma WithConstructibleTopology.map_id (x : WithConstructibleTopology X) : + WithConstructibleTopology.map id x = x := rfl + +@[simp] +lemma WithConstructibleTopology.map_comp {Z : Type*} [TopologicalSpace Z] (f : X → Y) (g : Y → Z) : + WithConstructibleTopology.map (g ∘ f) = + WithConstructibleTopology.map g ∘ WithConstructibleTopology.map f := rfl + +lemma isOpen_ofConstructibleTopology_preimage_iff (s : Set X) : + IsOpen (WithConstructibleTopology.equiv X ⁻¹' s) ↔ IsOpen[constructibleTopology X] s := .rfl + +/-- +The map from `X` with the constructible topology to `X` is continuous if `X` is prespectral. +-/ +lemma WithConstructibleTopology.continuous_equiv [PrespectralSpace X] : + Continuous <| equiv X := by + rw [TopologicalSpace.IsTopologicalBasis.continuous_iff (PrespectralSpace.isBasis_opens X)] + simp only [Set.mem_image, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂] + intro U hU + rw [isOpen_ofConstructibleTopology_preimage_iff] + exact hU.isOpen_constructibleTopology_of_isOpen U.2 + +lemma WithConstructibleTopology.continuous_constructibleTopology_id [PrespectralSpace X] : + @Continuous X X (constructibleTopology X) _ id := + @Continuous.comp X _ X (constructibleTopology X) _ + _ _ _ continuous_equiv (WithTopology.continuous_toTopology (constructibleTopology X)) + +lemma WithConstructibleTopology.map_continuous_iff (f : X → Y) : + Continuous (WithConstructibleTopology.map f) ↔ + @Continuous X Y (constructibleTopology X) (constructibleTopology Y) f := + WithTopology.map_continuous_iff (constructibleTopology X) (constructibleTopology Y) f + +lemma WithConstructibleTopology.map_continuous {f : X → Y} (hf : IsSpectralMap f) : + Continuous <| WithConstructibleTopology.map f := by + apply (map_continuous_iff f).2 + apply continuous_generateFrom_iff.mpr + intro s hs + obtain ⟨hso, hsc⟩ | ⟨hscl, hsc⟩ := hs + · exact (hf.isCompact_preimage_of_isOpen hso hsc).isOpen_constructibleTopology_of_isOpen + (hso.preimage hf.continuous) + · exact + (hf.isCompact_preimage_of_isOpen hscl.isOpen_compl hsc).isOpen_constructibleTopology_of_isClosed + (hscl.preimage hf.continuous) + +lemma WithConstructibleTopology.isCompact_preimage_of_map_continuous + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] + [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] + {f : X → Y} (hf : Continuous <| WithConstructibleTopology.map f) + {s : Set Y} (hs1 : IsOpen s) (hs2 : IsCompact s) : + @IsCompact X (constructibleTopology X) (f ⁻¹' s) := by + have hf' := (map_continuous_iff f).1 hf + letI := constructibleTopology X + apply IsClosed.isCompact + apply @IsClosed.preimage X Y _ (constructibleTopology Y) f hf' + exact (@isOpen_compl_iff _ _ (generateFrom _)).1 <| isOpen_generateFrom_of_mem <| + Or.intro_right _ ⟨hs1.isClosed_compl, (compl_compl s).symm ▸ hs2⟩ + +lemma WithConstructibleTopology.isSpectralMap_of_continuous_of_map_continuous + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf1 : Continuous f) + (hf2 : Continuous <| WithConstructibleTopology.map f) : + IsSpectralMap f := + ⟨hf1, fun _ hs1 hs2 => isCompact_of_le_of_isCompact (constructibleTopology_le X) <| + isCompact_preimage_of_map_continuous hf2 hs1 hs2⟩ + +lemma WithConstructibleTopology.isSpectralMap_iff_continuous_and_map_continuous + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] + [CompactSpace Y] [QuasiSeparatedSpace Y] (f : X → Y) : + IsSpectralMap f ↔ Continuous f ∧ (Continuous <| WithConstructibleTopology.map f) := + ⟨fun hf => ⟨hf.toContinuous, map_continuous hf⟩, + fun ⟨hf1, hf2⟩ => isSpectralMap_of_continuous_of_map_continuous hf1 hf2⟩ + +/-- +A spectral map between *quasi-separated* pre-spectral, sober spaces has compact fibers. +Note that any quasi-compact morphism of schemes has compact fibers, although the underlying +topological space of a schemes is not necessarily quasi-separated. +-/ +lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSeparatedSpace X] + [QuasiSober X] [PrespectralSpace Y] [T0Space Y] [QuasiSeparatedSpace Y] [QuasiSober Y] + {f : X → Y} (hf : IsSpectralMap f) : HasCompactFibers f := by + intro y + -- Take a compact open neighbourhood U of y (exists since Y is prespectral) + obtain ⟨U, ⟨hUo, hUc⟩, (hyU : y ∈ U), -⟩ := + (PrespectralSpace.isTopologicalBasis (X := Y)).mem_nhds_iff.mp (isOpen_univ.mem_nhds trivial) + have hfUo : IsOpen (f ⁻¹' U) := hUo.preimage hf.continuous + have hfUc : IsCompact (f ⁻¹' U) := hf.isCompact_preimage_of_isOpen hUo hUc + have : CompactSpace (f ⁻¹' U) := isCompact_iff_compactSpace.mp hfUc + have : PrespectralSpace (f ⁻¹' U) := hfUo.isOpenEmbedding_subtypeVal.prespectralSpace + have : QuasiSeparatedSpace (f ⁻¹' U) := hfUo.isOpenEmbedding_subtypeVal.quasiSeparatedSpace + have : QuasiSober (f ⁻¹' U) := hfUo.isOpenEmbedding_subtypeVal.quasiSober + let g := f ∘ (Subtype.val : f ⁻¹' U → X) + have hg : IsSpectralMap g := hf.comp hfUo.isOpenEmbedding_subtypeVal.isSpectralMap_of_compactSpace + have heq : f ⁻¹' {y} = Subtype.val '' (g ⁻¹' {y}) := by grind [Subtype.exists] + rw [heq] + have hg1 := (WithTopology.map_continuous_iff (constructibleTopology (f ⁻¹' U)) + (constructibleTopology Y) g).1 <| WithConstructibleTopology.map_continuous hg + have h := @Continuous.comp (f ⁻¹' U) _ X (constructibleTopology (f ⁻¹' U)) _ _ id _ + continuous_subtype_val WithConstructibleTopology.continuous_constructibleTopology_id + letI := constructibleTopology { x // x ∈ f ⁻¹' U } + letI := constructibleTopology Y + exact (isClosed_singleton.preimage hg1).isCompact.image h From b7c3df187cc8b138aba28dfa0def8b285b3ed35c Mon Sep 17 00:00:00 2001 From: FMLJohn <128468682+FMLJohn@users.noreply.github.com> Date: Wed, 8 Jul 2026 21:13:39 +0100 Subject: [PATCH 70/70] remove unused arguments --- .../Spectral/ConstructibleTopology.lean | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/Mathlib/Topology/Spectral/ConstructibleTopology.lean b/Mathlib/Topology/Spectral/ConstructibleTopology.lean index deff8dc5c043fb..72f6f9d920f95c 100644 --- a/Mathlib/Topology/Spectral/ConstructibleTopology.lean +++ b/Mathlib/Topology/Spectral/ConstructibleTopology.lean @@ -43,8 +43,7 @@ the open and compact sets of `X` and their complements. -/ def constructibleTopology (X : Type*) [TopologicalSpace X] : TopologicalSpace X := .generateFrom (constructibleTopologySubbasis X) -lemma constructibleTopology_le (X : Type*) [T : TopologicalSpace X] - [CompactSpace X] [QuasiSeparatedSpace X] [PrespectralSpace X] : +lemma constructibleTopology_le (X : Type*) [T : TopologicalSpace X] [PrespectralSpace X] : constructibleTopology X ≤ T := PrespectralSpace.isTopologicalBasis (X := X).eq_generateFrom ▸ le_generateFrom fun _ hs => TopologicalSpace.isOpen_generateFrom_of_mem <| @@ -94,8 +93,7 @@ lemma isCompact_sInter_of_subset_constructibleTopologySubbasis [CompactSpace X] · exact isCompact_of_mem_constructibleTopologySubbasis (hs ht) lemma IsSpectralMap.constructibleTopology_eq_induced_of_isEmbedding - {Y : Type*} [TopologicalSpace Y] [CompactSpace X] [QuasiSeparatedSpace X] - [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] [PrespectralSpace Y] + {Y : Type*} [TopologicalSpace Y] [PrespectralSpace X] [PrespectralSpace Y] {f : X → Y} (hf1 : IsSpectralMap f) (hf2 : IsEmbedding f) : constructibleTopology X = induced f (constructibleTopology Y) := by refine induced_generateFrom_eq ▸ eq_of_le_of_ge (le_generateFrom fun s ⟨t, ht, hts⟩ => ?_) @@ -197,11 +195,11 @@ instance compactSpace_withConstructibleTopology [CompactSpace X] [QuasiSober X] (WithTopology.continuous_toTopology _) compactSpace_constructibleTopology (WithTopology.toTopology_surjective _) -/-- If `X` is prespectral, T0 and quasi-sober, then `X` is T2 in the -constructible topology. This holds in particular for spectral spaces. -/ +/-- If `X` is prespectral and T0, then `X` is T2 in the constructible topology. This holds in +particular for spectral spaces. -/ @[stacks 0901 "Hausdorffness"] -instance t2Space_constructibleTopology [PrespectralSpace X] [T0Space X] - [QuasiSober X] : @T2Space X (constructibleTopology X) := by +instance t2Space_constructibleTopology [PrespectralSpace X] [T0Space X] : + @T2Space X (constructibleTopology X) := by simp only [t2Space_iff] intro x y hxy wlog h : ∃ (U : Set X), IsOpen U ∧ x ∈ U ∧ y ∉ U @@ -209,7 +207,7 @@ instance t2Space_constructibleTopology [PrespectralSpace X] [T0Space X] obtain ⟨U, hU1, (o | o)⟩ := exists_isOpen_xor_mem (X := X) hxy <;> use U · simp only [not_exists, not_and, not_not] at h exact (o.2 (h U hU1 o.1)).elim - obtain ⟨U, V, a, b, c, d, e⟩ := @this X _ _ _ _ y x hxy.symm o + obtain ⟨U, V, a, b, c, d, e⟩ := @this X _ _ _ y x hxy.symm o exact ⟨V, U, b, a, d, c, e.symm⟩ obtain ⟨U, hU1, hU2, hU3⟩ := h obtain ⟨V, ⟨hVo, hVc⟩, hV, hVU⟩ := @@ -220,11 +218,11 @@ instance t2Space_constructibleTopology [PrespectralSpace X] [T0Space X] (Or.inr ⟨hVo.isClosed_compl, (compl_compl V).symm ▸ hVc⟩), hV, Set.mem_compl (fun h ↦ hU3 (hVU h)), disjoint_compl_right⟩ -/-- If `X` is prespectral, T0 and quasi-sober, then `X` is T2 in the -constructible topology. This holds in particular for spectral spaces. -/ +/-- If `X` is prespectral and T0, then `X` is T2 in the constructible topology. This holds in +particular for spectral spaces. -/ @[stacks 0901 "Hausdorffness"] -instance t2Space_withConstructibleTopology [PrespectralSpace X] [T0Space X] - [QuasiSober X] : T2Space <| WithConstructibleTopology X := +instance t2Space_withConstructibleTopology [PrespectralSpace X] [T0Space X] : + T2Space <| WithConstructibleTopology X := @T2Space.of_injective_continuous (WithConstructibleTopology X) X _ (constructibleTopology X) t2Space_constructibleTopology WithTopology.ofTopology (WithTopology.ofTopology_injective (constructibleTopology X)) @@ -302,8 +300,7 @@ lemma WithConstructibleTopology.map_continuous {f : X → Y} (hf : IsSpectralMap (hscl.preimage hf.continuous) lemma WithConstructibleTopology.isCompact_preimage_of_map_continuous - [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] - [PrespectralSpace X] [CompactSpace Y] [QuasiSeparatedSpace Y] + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] {f : X → Y} (hf : Continuous <| WithConstructibleTopology.map f) {s : Set Y} (hs1 : IsOpen s) (hs2 : IsCompact s) : @IsCompact X (constructibleTopology X) (f ⁻¹' s) := by @@ -316,27 +313,26 @@ lemma WithConstructibleTopology.isCompact_preimage_of_map_continuous lemma WithConstructibleTopology.isSpectralMap_of_continuous_of_map_continuous [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] - [CompactSpace Y] [QuasiSeparatedSpace Y] {f : X → Y} (hf1 : Continuous f) - (hf2 : Continuous <| WithConstructibleTopology.map f) : + {f : X → Y} (hf1 : Continuous f) (hf2 : Continuous <| WithConstructibleTopology.map f) : IsSpectralMap f := ⟨hf1, fun _ hs1 hs2 => isCompact_of_le_of_isCompact (constructibleTopology_le X) <| isCompact_preimage_of_map_continuous hf2 hs1 hs2⟩ lemma WithConstructibleTopology.isSpectralMap_iff_continuous_and_map_continuous - [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] - [CompactSpace Y] [QuasiSeparatedSpace Y] (f : X → Y) : + [CompactSpace X] [QuasiSober X] [QuasiSeparatedSpace X] [PrespectralSpace X] (f : X → Y) : IsSpectralMap f ↔ Continuous f ∧ (Continuous <| WithConstructibleTopology.map f) := ⟨fun hf => ⟨hf.toContinuous, map_continuous hf⟩, fun ⟨hf1, hf2⟩ => isSpectralMap_of_continuous_of_map_continuous hf1 hf2⟩ /-- -A spectral map between *quasi-separated* pre-spectral, sober spaces has compact fibers. -Note that any quasi-compact morphism of schemes has compact fibers, although the underlying -topological space of a schemes is not necessarily quasi-separated. +If `f : X → Y` is a spectral map, where `X` is prespectral, quasi-separated and quasi-sober, and `Y` +is prespectral and T0, then `f` has compact fibers. Note that any quasi-compact morphism of schemes +has compact fibers, although the underlying topological space of a schemes is not necessarily +quasi-separated. -/ -lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [T0Space X] [QuasiSeparatedSpace X] - [QuasiSober X] [PrespectralSpace Y] [T0Space Y] [QuasiSeparatedSpace Y] [QuasiSober Y] - {f : X → Y} (hf : IsSpectralMap f) : HasCompactFibers f := by +lemma IsSpectralMap.hasCompactFibers [PrespectralSpace X] [QuasiSeparatedSpace X] + [QuasiSober X] [PrespectralSpace Y] [T0Space Y] {f : X → Y} (hf : IsSpectralMap f) : + HasCompactFibers f := by intro y -- Take a compact open neighbourhood U of y (exists since Y is prespectral) obtain ⟨U, ⟨hUo, hUc⟩, (hyU : y ∈ U), -⟩ :=