From 059ed4f2c1f2ad64c7186931542e4595d31eb1b2 Mon Sep 17 00:00:00 2001 From: Yohsuke Matsuzawa Date: Thu, 23 Jul 2026 08:12:47 +0900 Subject: [PATCH 1/7] some progresses toward Tate acyclicity --- Rigid.lean | 4 + Rigid/AffinoidAlgebra/MaximumModulus.lean | 122 +++++++++++++ Rigid/AffinoidAlgebra/PowerBounded.lean | 167 +++++++++++++++++ .../AffinoidAlgebra/RationalRestriction.lean | 94 ++++++++++ Rigid/AffinoidSpectrum/RationalCover.lean | 168 ++++++++++++++++++ 5 files changed, 555 insertions(+) create mode 100644 Rigid/AffinoidAlgebra/MaximumModulus.lean create mode 100644 Rigid/AffinoidAlgebra/PowerBounded.lean create mode 100644 Rigid/AffinoidAlgebra/RationalRestriction.lean create mode 100644 Rigid/AffinoidSpectrum/RationalCover.lean diff --git a/Rigid.lean b/Rigid.lean index f8142c7..ee15de6 100644 --- a/Rigid.lean +++ b/Rigid.lean @@ -1,14 +1,18 @@ import Rigid.AffinoidAlgebra.AutomaticContinuity import Rigid.AffinoidAlgebra.Basic import Rigid.AffinoidAlgebra.MaximalSpectrum +import Rigid.AffinoidAlgebra.MaximumModulus import Rigid.AffinoidAlgebra.NoetherNormalization +import Rigid.AffinoidAlgebra.PowerBounded import Rigid.AffinoidAlgebra.QuotientNorm import Rigid.AffinoidAlgebra.QuotientTopology import Rigid.AffinoidAlgebra.RationalDatum import Rigid.AffinoidAlgebra.RationalLocalization +import Rigid.AffinoidAlgebra.RationalRestriction import Rigid.AffinoidAlgebra.RelativeTate import Rigid.AffinoidAlgebra.ResidueNorm import Rigid.AffinoidSpectrum.RationalBasis +import Rigid.AffinoidSpectrum.RationalCover import Rigid.Berkovich.AffinoidDomain import Rigid.Berkovich.CompletedResidue import Rigid.Berkovich.CompletedResidueFunctoriality diff --git a/Rigid/AffinoidAlgebra/MaximumModulus.lean b/Rigid/AffinoidAlgebra/MaximumModulus.lean new file mode 100644 index 0000000..42d94a5 --- /dev/null +++ b/Rigid/AffinoidAlgebra/MaximumModulus.lean @@ -0,0 +1,122 @@ +import Rigid.AffinoidAlgebra.PowerBounded +import Rigid.Berkovich.RelativeNonempty +import Rigid.TateAlgebra.Multiplicative +import Rigid.TateAlgebra.NormedRing + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# The affinoid maximum-modulus theorem + +The Gauss point shows first that the Gauss norm on a strict Tate algebra is its spectral norm. In +particular, the power-bounded elements of a Tate algebra are exactly its closed unit ball. These +are the base cases for the Noether-normalization proof of the maximum-modulus theorem for general +strict affinoid algebras. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [IsUltrametricDist K] + +namespace BerkovichSpectrumOver + +variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] + +/-- **Maximum-modulus theorem.** On a nonzero normed algebra, every analytic function attains its +maximum on the relative Berkovich spectrum. -/ +theorem exists_maximum [Nontrivial A] (a : A) : + ∃ x : BerkovichSpectrumOver K A, ∀ y : BerkovichSpectrumOver K A, y a ≤ x a := by + have hne : (Set.univ : Set (BerkovichSpectrumOver K A)).Nonempty := + ⟨Classical.choice (nonempty_of_nontrivial K A), Set.mem_univ _⟩ + obtain ⟨x, -, hx⟩ := (isCompact_univ K A).exists_isMaxOn + hne (continuous_eval K A a).continuousOn + exact ⟨x, fun y ↦ hx (Set.mem_univ y)⟩ + +end BerkovichSpectrumOver + +namespace TateAlgebra + +/-- The Gauss unit ball in a strict Tate algebra. -/ +def unitBallSubring (n : ℕ) : Subring (TateAlgebra K (Fin n)) where + carrier := {f | ‖f‖ ≤ 1} + zero_mem' := by simp + one_mem' := by simp + add_mem' {f g} hf hg := + (IsUltrametricDist.norm_add_le_max f g).trans (max_le hf hg) + neg_mem' {f} hf := by simpa using hf + mul_mem' {f g} hf hg := + (norm_mul_le f g).trans (by simpa using mul_le_mul hf hg (norm_nonneg g) zero_le_one) + +/-- The relative Berkovich point defined by the multiplicative Gauss norm. -/ +noncomputable def gaussPoint (n : ℕ) : BerkovichSpectrumOver K (TateAlgebra K (Fin n)) where + toBerkovichSpectrum := + { seminorm := + { toFun := fun f ↦ ‖f‖ + map_zero' := norm_zero + add_le' := norm_add_le + neg' := norm_neg + map_one' := by + change ‖(1 : TateAlgebra K (Fin n))‖ = 1 + rw [show (1 : TateAlgebra K (Fin n)) = TateAlgebra.C K (Fin n) 1 by + exact (map_one (algebraMap K (TateAlgebra K (Fin n)))).symm, + Rigid.norm_C, norm_one] + map_mul' := norm_mul } + le_norm' := fun _ ↦ le_rfl } + map_algebraMap' := fun r ↦ by + change ‖algebraMap K (TateAlgebra K (Fin n)) r‖ = ‖r‖ + change ‖TateAlgebra.C K (Fin n) r‖ = ‖r‖ + exact Rigid.norm_C K (Fin n) r + +@[simp] +theorem gaussPoint_apply (n : ℕ) (f : TateAlgebra K (Fin n)) : + gaussPoint K n f = ‖f‖ := rfl + +/-- The Gauss point realizes the maximum modulus of every function on a strict Tate algebra. -/ +theorem le_gaussPoint (n : ℕ) (x : BerkovichSpectrumOver K (TateAlgebra K (Fin n))) + (f : TateAlgebra K (Fin n)) : x f ≤ gaussPoint K n f := + BerkovichSpectrumOver.le_norm K _ x f + +/-- In a strict Tate algebra, power-boundedness is equivalent to membership in the Gauss unit +ball. -/ +theorem isPowerBounded_iff_norm_le_one {n : ℕ} {f : TateAlgebra K (Fin n)} : + IsPowerBounded f ↔ ‖f‖ ≤ 1 := by + constructor + · intro hf + simpa using IsPowerBounded.apply_le_one K (gaussPoint K n) hf + · exact isPowerBounded_of_norm_le_one + +@[simp] +theorem mem_unitBallSubring_iff {n : ℕ} {f : TateAlgebra K (Fin n)} : + f ∈ unitBallSubring K n ↔ IsPowerBounded f := by + rw [isPowerBounded_iff_norm_le_one] + rfl + +variable {B : Type v} [NormedCommRing B] [NormedAlgebra K B] [IsUltrametricDist B] + +/-- The image of the Tate unit ball under a continuous homomorphism is uniformly bounded. -/ +theorem bddAbove_image_unitBall (n : ℕ) + (π : ContinuousAlgHom K (TateAlgebra K (Fin n)) B) : + BddAbove (Set.range fun b : (unitBallSubring K n).map π.toRingHom ↦ ‖(b : B)‖) := by + obtain ⟨M, hM, hπ⟩ := SemilinearMapClass.bound_of_continuous π π.continuous + refine ⟨max 0 M, ?_⟩ + rintro _ ⟨b, rfl⟩ + obtain ⟨a, ha, hab⟩ := b.2 + calc + ‖(b : B)‖ = ‖π a‖ := congrArg norm hab |>.symm + _ ≤ M * ‖a‖ := hπ a + _ ≤ M * 1 := mul_le_mul_of_nonneg_left ha hM.le + _ ≤ max 0 M := by simp [le_max_right 0 M] + +/-- An element integral over the image of a Tate unit ball is power-bounded. -/ +theorem isPowerBounded_of_isIntegral_image_unitBall (n : ℕ) + (π : ContinuousAlgHom K (TateAlgebra K (Fin n)) B) {b : B} + (hb : IsIntegral ((unitBallSubring K n).map π.toRingHom) b) : IsPowerBounded b := + IsPowerBounded.of_isIntegral_over_bounded_subring _ + (bddAbove_image_unitBall K n π) hb + +end TateAlgebra + +end Rigid diff --git a/Rigid/AffinoidAlgebra/PowerBounded.lean b/Rigid/AffinoidAlgebra/PowerBounded.lean new file mode 100644 index 0000000..5dd6aba --- /dev/null +++ b/Rigid/AffinoidAlgebra/PowerBounded.lean @@ -0,0 +1,167 @@ +import Rigid.AffinoidAlgebra.RationalDatum +import Rigid.Berkovich.RelativeSpectrum +import Mathlib.Analysis.Normed.Group.Ultra +import Mathlib.RingTheory.IntegralClosure.IsIntegral.Basic + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# Power-bounded elements of nonarchimedean normed rings + +This file develops the elementary algebra of power-bounded elements used in the affinoid maximum +modulus theorem. The property is independent of replacing a Banach norm by an equivalent norm, +is stable under the ring operations in a commutative nonarchimedean normed ring, and forces every +Berkovich seminorm to have value at most one. +-/ + +open scoped BigOperators + +universe u v + +namespace Rigid + +namespace IsPowerBounded + +variable {B : Type u} [NormedCommRing B] [IsUltrametricDist B] + +omit [IsUltrametricDist B] in +/-- Power-boundedness is unchanged by negation. -/ +theorem neg {x : B} (hx : IsPowerBounded x) : IsPowerBounded (-x) := by + rcases hx with ⟨C, hC⟩ + refine ⟨C, ?_⟩ + rintro _ ⟨n, rfl⟩ + change ‖(-x) ^ n‖ ≤ C + rw [neg_pow] + rcases neg_one_pow_eq_or B n with hn | hn + · rw [hn, one_mul] + exact hC ⟨n, rfl⟩ + · rw [hn, neg_one_mul, norm_neg] + exact hC ⟨n, rfl⟩ + +omit [IsUltrametricDist B] in +/-- The product of two power-bounded elements is power-bounded. -/ +theorem mul {x y : B} (hx : IsPowerBounded x) (hy : IsPowerBounded y) : + IsPowerBounded (x * y) := by + rcases hx with ⟨Cx, hCx⟩ + rcases hy with ⟨Cy, hCy⟩ + refine ⟨max 0 Cx * max 0 Cy, ?_⟩ + rintro _ ⟨n, rfl⟩ + change ‖(x * y) ^ n‖ ≤ max 0 Cx * max 0 Cy + rw [mul_pow] + exact (norm_mul_le _ _).trans <| mul_le_mul + ((hCx ⟨n, rfl⟩).trans (le_max_right 0 Cx)) + ((hCy ⟨n, rfl⟩).trans (le_max_right 0 Cy)) + (norm_nonneg _) (by positivity) + +private theorem norm_natCast_le_norm_one (n : ℕ) : ‖(n : B)‖ ≤ ‖(1 : B)‖ := by + induction n with + | zero => simp + | succ n ih => + rw [Nat.cast_succ] + exact (IsUltrametricDist.norm_add_le_max (n : B) 1).trans + (max_le ih le_rfl) + +/-- The sum of two power-bounded elements is power-bounded. -/ +theorem add {x y : B} (hx : IsPowerBounded x) (hy : IsPowerBounded y) : + IsPowerBounded (x + y) := by + rcases hx with ⟨Cx, hCx⟩ + rcases hy with ⟨Cy, hCy⟩ + let C := max 0 Cx * max 0 Cy * max 1 ‖(1 : B)‖ + refine ⟨C, ?_⟩ + rintro _ ⟨n, rfl⟩ + change ‖(x + y) ^ n‖ ≤ C + rw [add_pow] + refine IsUltrametricDist.norm_sum_le_of_forall_le_of_nonneg (by positivity) ?_ + intro i hi + simp only [Finset.mem_range] at hi + calc + ‖x ^ i * y ^ (n - i) * (n.choose i : B)‖ ≤ + ‖x ^ i * y ^ (n - i)‖ * ‖(n.choose i : B)‖ := norm_mul_le _ _ + _ ≤ + ‖x ^ i * y ^ (n - i)‖ * max 1 ‖(1 : B)‖ := + mul_le_mul_of_nonneg_left + ((norm_natCast_le_norm_one (B := B) _).trans (le_max_right 1 ‖(1 : B)‖)) + (norm_nonneg _) + _ ≤ (‖x ^ i‖ * ‖y ^ (n - i)‖) * max 1 ‖(1 : B)‖ := + mul_le_mul_of_nonneg_right (norm_mul_le _ _) (by positivity) + _ ≤ C := by + dsimp only [C] + exact mul_le_mul_of_nonneg_right + (mul_le_mul + ((hCx ⟨i, rfl⟩).trans (le_max_right 0 Cx)) + ((hCy ⟨n - i, rfl⟩).trans (le_max_right 0 Cy)) + (norm_nonneg _) (by positivity)) + (by positivity) + +/-- The power-bounded elements form a subring. -/ +def subring (B : Type u) [NormedCommRing B] [IsUltrametricDist B] : Subring B where + carrier := {x | IsPowerBounded x} + zero_mem' := isPowerBounded_zero + one_mem' := isPowerBounded_one + add_mem' := add + neg_mem' := neg + mul_mem' := mul + +/-- An element integral over a uniformly bounded coefficient subring is power-bounded. This is +the bounded-coefficient half of the affinoid maximum-modulus argument. -/ +theorem of_isIntegral_over_bounded_subring (S : Subring B) + (hS : BddAbove (Set.range fun s : S ↦ ‖(s : B)‖)) {x : B} (hx : IsIntegral S x) : + IsPowerBounded x := by + obtain ⟨C, hC⟩ := hS + obtain ⟨d, v, hv⟩ := + Submodule.fg_iff_exists_fin_generating_family.mp hx.fg_adjoin_singleton + let D : ℝ := ∑ i, ‖v i‖ + refine ⟨max 0 C * D, ?_⟩ + rintro _ ⟨n, rfl⟩ + have hxpow : x ^ n ∈ Algebra.adjoin S {x} := by + exact (Algebra.adjoin S {x}).pow_mem (Algebra.subset_adjoin (Set.mem_singleton x)) n + have hxspan : x ^ n ∈ Submodule.span S (Set.range v) := by + rw [hv] + exact hxpow + obtain ⟨c, hc⟩ := (Submodule.mem_span_range_iff_exists_fun S).mp hxspan + change ‖x ^ n‖ ≤ max 0 C * D + rw [← hc] + calc + ‖∑ i, c i • v i‖ ≤ ∑ i, ‖c i • v i‖ := norm_sum_le _ _ + _ ≤ ∑ i, max 0 C * ‖v i‖ := by + apply Finset.sum_le_sum + intro i _ + change ‖(c i : B) * v i‖ ≤ max 0 C * ‖v i‖ + exact (norm_mul_le _ _).trans <| mul_le_mul_of_nonneg_right + ((hC ⟨c i, rfl⟩).trans (le_max_right 0 C)) (norm_nonneg _) + _ = max 0 C * D := by rw [Finset.mul_sum] + +/-- Continuous algebra homomorphisms preserve power-bounded elements. -/ +theorem map_continuousAlgHom + {K : Type v} [NontriviallyNormedField K] [NormedAlgebra K B] + {C : Type v} [NormedCommRing C] [NormedAlgebra K C] + (f : ContinuousAlgHom K B C) {x : B} (hx : IsPowerBounded x) : + IsPowerBounded (f x) := by + obtain ⟨D, hD⟩ := hx + obtain ⟨M, hM, hf⟩ := SemilinearMapClass.bound_of_continuous f f.continuous + refine ⟨M * max 0 D, ?_⟩ + rintro _ ⟨n, rfl⟩ + change ‖(f x) ^ n‖ ≤ M * max 0 D + rw [← map_pow] + exact (hf (x ^ n)).trans <| mul_le_mul_of_nonneg_left + ((hD ⟨n, rfl⟩).trans (le_max_right 0 D)) hM.le + +omit [IsUltrametricDist B] in +/-- A power-bounded element has value at most one at every relative Berkovich point. -/ +theorem apply_le_one + (K : Type v) [NormedField K] [Algebra K B] + (x : BerkovichSpectrumOver K B) {b : B} (hb : IsPowerBounded b) : x b ≤ 1 := by + rcases hb with ⟨C, hC⟩ + by_contra h + have hxb : 1 < x b := lt_of_not_ge h + obtain ⟨n, hn⟩ := pow_unbounded_of_one_lt C hxb + apply not_le_of_gt hn + calc + x b ^ n = x (b ^ n) := (map_pow x.toBerkovichSpectrum.seminorm b n).symm + _ ≤ ‖b ^ n‖ := BerkovichSpectrumOver.le_norm K B x _ + _ ≤ C := hC ⟨n, rfl⟩ + +end IsPowerBounded + +end Rigid diff --git a/Rigid/AffinoidAlgebra/RationalRestriction.lean b/Rigid/AffinoidAlgebra/RationalRestriction.lean new file mode 100644 index 0000000..6f6fe87 --- /dev/null +++ b/Rigid/AffinoidAlgebra/RationalRestriction.lean @@ -0,0 +1,94 @@ +import Rigid.AffinoidAlgebra.PowerBounded +import Rigid.AffinoidAlgebra.RationalLocalization + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# Maps out of rational localizations + +This file isolates the algebraic part of restriction along an inclusion of rational domains. If +the target makes the denominator invertible and all quotient coordinates power-bounded, the +universal property gives a canonical map from the rational localization. Its uniqueness only +uses invertibility of the denominator. +-/ + +universe u v w + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +namespace RationalLocalization + +variable {B : Type w} [NormedCommRing B] [NormedAlgebra K B] [CompleteSpace B] + [IsUltrametricDist B] + +/-- The quotient coordinate `fᵢ / g` in a target in which the image of `g` is a unit. -/ +noncomputable def quotientCoordinate {n : ℕ} {g : A} {f : Fin n → A} + (φ : ContinuousAlgHom K A B) (hg : IsUnit (φ g)) (i : Fin n) : B := + (↑hg.unit⁻¹ : B) * φ (f i) + +@[simp] +theorem denominator_mul_quotientCoordinate {n : ℕ} {g : A} {f : Fin n → A} + (φ : ContinuousAlgHom K A B) (hg : IsUnit (φ g)) (i : Fin n) : + φ g * quotientCoordinate K A (f := f) φ hg i = φ (f i) := by + change φ g * ((↑hg.unit⁻¹ : B) * φ (f i)) = φ (f i) + calc + _ = (↑hg.unit : B) * ((↑hg.unit⁻¹ : B) * φ (f i)) := by + rw [IsUnit.unit_spec hg] + _ = φ (f i) := by rw [← mul_assoc]; simp + +/-- The canonical map from a rational localization to a target in which its denominator is a unit +and its quotient coordinates are power-bounded. -/ +noncomputable def liftOfIsUnit {n : ℕ} {g : A} {f : Fin n → A} + (φ : ContinuousAlgHom K A B) (hg : IsUnit (φ g)) + (hbounded : ∀ i : Fin n, IsPowerBounded (quotientCoordinate K A (f := f) φ hg i)) : + ContinuousAlgHom K (RationalLocalization K A n g f) B := + lift K A n g f φ (quotientCoordinate K A (f := f) φ hg) hbounded + (denominator_mul_quotientCoordinate K A (f := f) φ hg) + +@[simp] +theorem liftOfIsUnit_comp_baseMap {n : ℕ} {g : A} {f : Fin n → A} + (φ : ContinuousAlgHom K A B) (hg : IsUnit (φ g)) + (hbounded : ∀ i : Fin n, IsPowerBounded (quotientCoordinate K A (f := f) φ hg i)) : + (liftOfIsUnit K A φ hg hbounded).comp (baseMap K A n g f) = φ := + lift_comp_baseMap K A n g f φ _ hbounded _ + +@[simp] +theorem liftOfIsUnit_coordinate {n : ℕ} {g : A} {f : Fin n → A} + (φ : ContinuousAlgHom K A B) (hg : IsUnit (φ g)) + (hbounded : ∀ i : Fin n, IsPowerBounded (quotientCoordinate K A (f := f) φ hg i)) + (i : Fin n) : + liftOfIsUnit K A φ hg hbounded (coordinate K A n g f i) = + quotientCoordinate K A (f := f) φ hg i := + lift_coordinate K A n g f φ _ hbounded _ i + +/-- Maps out of a rational localization are determined by their restriction to the base whenever +the image of the denominator is a unit. -/ +theorem hom_ext_of_isUnit {n : ℕ} {g : A} {f : Fin n → A} + (φ ψ : ContinuousAlgHom K (RationalLocalization K A n g f) B) + (hg : IsUnit (φ (baseMap K A n g f g))) + (hbase : φ.comp (baseMap K A n g f) = ψ.comp (baseMap K A n g f)) : φ = ψ := by + apply hom_ext K A n g f φ ψ hbase + intro i + apply hg.mul_left_cancel + have hbase_g : φ (baseMap K A n g f g) = ψ (baseMap K A n g f g) := + congrArg (fun q : ContinuousAlgHom K A B ↦ q g) hbase + have hbase_f : φ (baseMap K A n g f (f i)) = ψ (baseMap K A n g f (f i)) := + congrArg (fun q : ContinuousAlgHom K A B ↦ q (f i)) hbase + have hφ := congrArg φ (baseMap_denominator_mul_coordinate K A n g f i) + have hψ := congrArg ψ (baseMap_denominator_mul_coordinate K A n g f i) + calc + φ (baseMap K A n g f g) * φ (coordinate K A n g f i) = + φ (baseMap K A n g f (f i)) := by simpa only [map_mul] using hφ + _ = ψ (baseMap K A n g f (f i)) := hbase_f + _ = ψ (baseMap K A n g f g) * ψ (coordinate K A n g f i) := by + simpa only [map_mul] using hψ.symm + _ = φ (baseMap K A n g f g) * ψ (coordinate K A n g f i) := by rw [hbase_g] + +end RationalLocalization + +end Rigid diff --git a/Rigid/AffinoidSpectrum/RationalCover.lean b/Rigid/AffinoidSpectrum/RationalCover.lean new file mode 100644 index 0000000..f9ea9a7 --- /dev/null +++ b/Rigid/AffinoidSpectrum/RationalCover.lean @@ -0,0 +1,168 @@ +import Rigid.AffinoidSpectrum.RationalBasis + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# Rational and Laurent covers + +This file supplies the finite-cover objects used in Tate's acyclicity argument and constructs the +two-member Laurent cover associated with one analytic function. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +namespace AffinoidRationalSubdomain + +/-- The whole affinoid spectrum, represented as a rational subdomain with no numerators. -/ +noncomputable def whole : AffinoidRationalSubdomain K A where + n := 0 + g := 1 + f := Fin.elim0 + isRational := by + rw [IsRationalDatum] + apply (Ideal.eq_top_iff_one _).mpr + apply Ideal.subset_span + exact Set.mem_insert 1 _ + +@[simp] +theorem carrier_whole : (whole K A).carrier = Set.univ := by + ext x + simp [whole, carrier, BerkovichSpectrumOver.rationalDomainSet] + +/-- The Laurent subdomain on which `|f| ≤ 1`. -/ +noncomputable def laurentLE (f : A) : AffinoidRationalSubdomain K A where + n := 1 + g := 1 + f := fun _ ↦ f + isRational := by + rw [IsRationalDatum] + apply (Ideal.eq_top_iff_one _).mpr + apply Ideal.subset_span + exact Set.mem_insert 1 _ + +/-- The Laurent subdomain on which `1 ≤ |f|`. -/ +noncomputable def laurentGE (f : A) : AffinoidRationalSubdomain K A where + n := 1 + g := f + f := fun _ ↦ 1 + isRational := by + rw [IsRationalDatum] + apply (Ideal.eq_top_iff_one _).mpr + apply Ideal.subset_span + exact Set.mem_insert_of_mem f ⟨0, rfl⟩ + +@[simp] +theorem mem_carrier_laurentLE (f : A) (x : BerkovichSpectrumOver K A) : + x ∈ (laurentLE K A f).carrier ↔ x f ≤ 1 := by + simp [laurentLE, carrier, BerkovichSpectrumOver.rationalDomainSet] + +@[simp] +theorem mem_carrier_laurentGE (f : A) (x : BerkovichSpectrumOver K A) : + x ∈ (laurentGE K A f).carrier ↔ 1 ≤ x f := by + simp [laurentGE, carrier, BerkovichSpectrumOver.rationalDomainSet] + +/-- A finite rational cover of a rational subdomain. -/ +structure Cover (U : AffinoidRationalSubdomain K A) where + m : ℕ + domain : Fin m → AffinoidRationalSubdomain K A + subset : ∀ i, (domain i).carrier ⊆ U.carrier + covers : U.carrier = ⋃ i, (domain i).carrier + +namespace Cover + +/-- `𝒱` refines `𝒰` when every member of `𝒱` is contained in a specified member of `𝒰`. -/ +structure Refinement {U : AffinoidRationalSubdomain K A} (𝒱 𝒰 : Cover K A U) where + index : Fin 𝒱.m → Fin 𝒰.m + subset : ∀ j, (𝒱.domain j).carrier ⊆ (𝒰.domain (index j)).carrier + +/-- Every rational cover refines itself. -/ +def Refinement.refl {U : AffinoidRationalSubdomain K A} (𝒰 : Cover K A U) : + Refinement K A 𝒰 𝒰 where + index := id + subset := fun _ ↦ Set.Subset.rfl + +/-- Refinements compose. -/ +def Refinement.trans {U : AffinoidRationalSubdomain K A} {𝒲 𝒱 𝒰 : Cover K A U} + (h𝒲𝒱 : Refinement K A 𝒲 𝒱) (h𝒱𝒰 : Refinement K A 𝒱 𝒰) : + Refinement K A 𝒲 𝒰 where + index := h𝒱𝒰.index ∘ h𝒲𝒱.index + subset := fun j ↦ (h𝒲𝒱.subset j).trans (h𝒱𝒰.subset (h𝒲𝒱.index j)) + +/-- The two-member Laurent cover `|f| ≤ 1` and `1 ≤ |f|` of the whole spectrum. -/ +noncomputable def laurent (f : A) : Cover K A (whole K A) where + m := 2 + domain := ![laurentLE K A f, laurentGE K A f] + subset := fun _ ↦ by rw [carrier_whole]; exact Set.subset_univ _ + covers := by + rw [carrier_whole] + symm + apply Set.eq_univ_of_forall + intro x + by_cases hx : x f ≤ 1 + · apply Set.mem_iUnion.mpr + refine ⟨0, ?_⟩ + simpa [Fin.cases] using hx + · apply Set.mem_iUnion.mpr + refine ⟨1, ?_⟩ + have hx' : 1 ≤ x f := (le_total 1 (x f)).resolve_right hx + simpa [Fin.cases] using hx' + +/-- The member with denominator `qᵢ` of the rational cover generated by a unit-ideal family `q`. -/ +noncomputable def generatedDomain {r : ℕ} (q : Fin r → A) + (hq : Ideal.span (Set.range q) = ⊤) (i : Fin r) : AffinoidRationalSubdomain K A where + n := r + g := q i + f := q + isRational := by + apply top_unique + rw [← hq] + exact Ideal.span_mono (Set.subset_insert (q i) (Set.range q)) + +@[simp] +theorem mem_generatedDomain_carrier {r : ℕ} (q : Fin r → A) + (hq : Ideal.span (Set.range q) = ⊤) (i : Fin r) (x : BerkovichSpectrumOver K A) : + x ∈ (generatedDomain K A q hq i).carrier ↔ ∀ j, x (q j) ≤ x (q i) := by + rfl + +/-- A finite family generating the unit ideal gives its standard rational cover: at every point, +choose an index at which the family has maximal modulus. -/ +noncomputable def generated {r : ℕ} (q : Fin r → A) + (hq : Ideal.span (Set.range q) = ⊤) : Cover K A (whole K A) where + m := r + domain := generatedDomain K A q hq + subset := fun _ ↦ by rw [carrier_whole]; exact Set.subset_univ _ + covers := by + rcases eq_or_ne r 0 with hr | hr + · subst r + rw [carrier_whole] + simp only [Set.iUnion_of_empty] + ext x + simp only [Set.mem_univ, Set.mem_empty_iff_false, iff_false] + intro _ + have hbot : (⊥ : Ideal A) = ⊤ := by simpa using hq + have hone : (1 : A) ∈ (⊥ : Ideal A) := by rw [hbot]; simp + have h10 : (1 : A) = 0 := by simpa using hone + have hx := congrArg (fun a : A ↦ x a) h10 + rw [BerkovichSpectrumOver.map_one, BerkovichSpectrumOver.map_zero] at hx + exact one_ne_zero hx + · letI : Nonempty (Fin r) := Fin.pos_iff_nonempty.mp (Nat.pos_of_ne_zero hr) + rw [carrier_whole] + symm + apply Set.eq_univ_of_forall + intro x + obtain ⟨i, hi⟩ := Finite.exists_max (fun i : Fin r ↦ x (q i)) + apply Set.mem_iUnion.mpr + exact ⟨i, (mem_generatedDomain_carrier K A q hq i x).2 hi⟩ + +end Cover + +end AffinoidRationalSubdomain + +end Rigid From 7d358a557b8a5125795d2b0059ead571c3cde0a8 Mon Sep 17 00:00:00 2001 From: Yohsuke Matsuzawa Date: Thu, 23 Jul 2026 14:54:45 +0900 Subject: [PATCH 2/7] progresses toward tate acyclicity --- Rigid.lean | 25 + Rigid/AffinoidAlgebra/ClosedIdeals.lean | 84 ++ Rigid/AffinoidAlgebra/CompletedLaurent.lean | 333 +++++++ .../FiniteExtensionFunctional.lean | 103 ++ .../AffinoidAlgebra/FiniteModuleBounded.lean | 163 +++ Rigid/AffinoidAlgebra/LaurentCharts.lean | 141 +++ Rigid/AffinoidAlgebra/LaurentCover.lean | 135 +++ .../AffinoidAlgebra/NoetherNormalization.lean | 105 +- .../AffinoidAlgebra/RationalLocalization.lean | 26 +- Rigid/AffinoidAlgebra/SpectralComponents.lean | 51 + Rigid/AffinoidAlgebra/SpectralCriterion.lean | 31 + Rigid/AffinoidAlgebra/SpectralPolynomial.lean | 924 ++++++++++++++++++ .../AffinoidAlgebra/SpectralPresentation.lean | 142 +++ Rigid/AffinoidAlgebra/SpectralRadius.lean | 151 +++ Rigid/AffinoidAlgebra/TateRealization.lean | 84 ++ .../AffinoidSpectrum/RationalRefinement.lean | 373 +++++++ Rigid/AffinoidSpectrum/Restriction.lean | 287 ++++++ Rigid/Berkovich/Nonempty.lean | 122 +++ Rigid/Berkovich/Quotient.lean | 77 ++ Rigid/Berkovich/SpectralRadius.lean | 157 +++ Rigid/Berkovich/Unit.lean | 62 ++ Rigid/Development.lean | 71 +- Rigid/TateAlgebra/Division.lean | 29 +- Rigid/TateAlgebra/Domain.lean | 30 + Rigid/TateAlgebra/EmptyVariables.lean | 66 ++ Rigid/TateAlgebra/FirstVariable.lean | 492 ++++++++++ Rigid/TateAlgebra/LeadingMultiplicative.lean | 210 ++++ Rigid/TateAlgebra/Ruckert.lean | 225 +++++ Rigid/TateAlgebra/UniqueFactorization.lean | 129 +++ Rigid/TateAlgebra/WeierstrassDivision.lean | 203 ++++ Rigid/TateAlgebra/WeierstrassPreparation.lean | 63 ++ 31 files changed, 5071 insertions(+), 23 deletions(-) create mode 100644 Rigid/AffinoidAlgebra/ClosedIdeals.lean create mode 100644 Rigid/AffinoidAlgebra/CompletedLaurent.lean create mode 100644 Rigid/AffinoidAlgebra/FiniteExtensionFunctional.lean create mode 100644 Rigid/AffinoidAlgebra/FiniteModuleBounded.lean create mode 100644 Rigid/AffinoidAlgebra/LaurentCharts.lean create mode 100644 Rigid/AffinoidAlgebra/LaurentCover.lean create mode 100644 Rigid/AffinoidAlgebra/SpectralComponents.lean create mode 100644 Rigid/AffinoidAlgebra/SpectralCriterion.lean create mode 100644 Rigid/AffinoidAlgebra/SpectralPolynomial.lean create mode 100644 Rigid/AffinoidAlgebra/SpectralPresentation.lean create mode 100644 Rigid/AffinoidAlgebra/SpectralRadius.lean create mode 100644 Rigid/AffinoidAlgebra/TateRealization.lean create mode 100644 Rigid/AffinoidSpectrum/RationalRefinement.lean create mode 100644 Rigid/AffinoidSpectrum/Restriction.lean create mode 100644 Rigid/Berkovich/Quotient.lean create mode 100644 Rigid/Berkovich/SpectralRadius.lean create mode 100644 Rigid/Berkovich/Unit.lean create mode 100644 Rigid/TateAlgebra/Domain.lean create mode 100644 Rigid/TateAlgebra/EmptyVariables.lean create mode 100644 Rigid/TateAlgebra/FirstVariable.lean create mode 100644 Rigid/TateAlgebra/LeadingMultiplicative.lean create mode 100644 Rigid/TateAlgebra/Ruckert.lean create mode 100644 Rigid/TateAlgebra/UniqueFactorization.lean create mode 100644 Rigid/TateAlgebra/WeierstrassDivision.lean create mode 100644 Rigid/TateAlgebra/WeierstrassPreparation.lean diff --git a/Rigid.lean b/Rigid.lean index ee15de6..32fb6c4 100644 --- a/Rigid.lean +++ b/Rigid.lean @@ -1,5 +1,11 @@ import Rigid.AffinoidAlgebra.AutomaticContinuity import Rigid.AffinoidAlgebra.Basic +import Rigid.AffinoidAlgebra.ClosedIdeals +import Rigid.AffinoidAlgebra.CompletedLaurent +import Rigid.AffinoidAlgebra.FiniteExtensionFunctional +import Rigid.AffinoidAlgebra.FiniteModuleBounded +import Rigid.AffinoidAlgebra.LaurentCharts +import Rigid.AffinoidAlgebra.LaurentCover import Rigid.AffinoidAlgebra.MaximalSpectrum import Rigid.AffinoidAlgebra.MaximumModulus import Rigid.AffinoidAlgebra.NoetherNormalization @@ -11,26 +17,45 @@ import Rigid.AffinoidAlgebra.RationalLocalization import Rigid.AffinoidAlgebra.RationalRestriction import Rigid.AffinoidAlgebra.RelativeTate import Rigid.AffinoidAlgebra.ResidueNorm +import Rigid.AffinoidAlgebra.SpectralCriterion +import Rigid.AffinoidAlgebra.SpectralComponents +import Rigid.AffinoidAlgebra.SpectralPolynomial +import Rigid.AffinoidAlgebra.SpectralPresentation +import Rigid.AffinoidAlgebra.SpectralRadius +import Rigid.AffinoidAlgebra.TateRealization import Rigid.AffinoidSpectrum.RationalBasis import Rigid.AffinoidSpectrum.RationalCover +import Rigid.AffinoidSpectrum.RationalRefinement +import Rigid.AffinoidSpectrum.Restriction import Rigid.Berkovich.AffinoidDomain import Rigid.Berkovich.CompletedResidue import Rigid.Berkovich.CompletedResidueFunctoriality import Rigid.Berkovich.GeneralSmoothing import Rigid.Berkovich.Nonempty +import Rigid.Berkovich.Quotient import Rigid.Berkovich.RationalLocalization import Rigid.Berkovich.RelativeNonempty import Rigid.Berkovich.RelativeSpectrum +import Rigid.Berkovich.SpectralRadius import Rigid.Berkovich.Spectrum +import Rigid.Berkovich.Unit import Rigid.Development import Rigid.TateAlgebra.Basic import Rigid.TateAlgebra.Complete import Rigid.TateAlgebra.Division +import Rigid.TateAlgebra.Domain +import Rigid.TateAlgebra.EmptyVariables +import Rigid.TateAlgebra.FirstVariable import Rigid.TateAlgebra.GaussNorm import Rigid.TateAlgebra.Leading +import Rigid.TateAlgebra.LeadingMultiplicative import Rigid.TateAlgebra.Multiplicative import Rigid.TateAlgebra.Noetherian import Rigid.TateAlgebra.NormedRing import Rigid.TateAlgebra.PowerBoundedUniversalProperty import Rigid.TateAlgebra.RelativeUniversalProperty +import Rigid.TateAlgebra.Ruckert +import Rigid.TateAlgebra.UniqueFactorization import Rigid.TateAlgebra.UniversalProperty +import Rigid.TateAlgebra.WeierstrassDivision +import Rigid.TateAlgebra.WeierstrassPreparation diff --git a/Rigid/AffinoidAlgebra/ClosedIdeals.lean b/Rigid/AffinoidAlgebra/ClosedIdeals.lean new file mode 100644 index 0000000..48010bb --- /dev/null +++ b/Rigid/AffinoidAlgebra/ClosedIdeals.lean @@ -0,0 +1,84 @@ +import Mathlib.Topology.Defs.Induced +import Mathlib.Topology.Maps.Basic +import Mathlib.Topology.Maps.OpenQuotient +import Rigid.AffinoidAlgebra.AutomaticContinuity + +set_option linter.style.header false + +/-! +# Closed ideals in a Banach realization of an affinoid algebra + +Ideals in a Tate algebra are closed. Since an affinoid presentation is a quotient map for the +canonical affinoid topology, the same is true in every normed realization whose topology agrees +with that canonical topology. This isolates the topological input needed to form complete +minimal-prime quotients in the reduction of Proposition 4.5.3. +-/ + +universe u v + +namespace Rigid + +section Quotient + +variable {R : Type v} [NormedCommRing R] [IsUltrametricDist R] + +/-- A quotient by a closed ideal inherits a nonarchimedean quotient norm. -/ +theorem idealQuotientIsUltrametricDist (I : Ideal R) [IsClosed (I : Set R)] : + IsUltrametricDist (R ⧸ I) := by + exact IsUltrametricDist.isUltrametricDist_of_forall_norm_add_le_max_norm fun x y ↦ by + refine le_of_forall_pos_le_add fun ε hε ↦ ?_ + obtain ⟨x', hx', hxnorm⟩ := + Ideal.Quotient.norm_mk_lt (ε := ε / 2) x (half_pos hε) + obtain ⟨y', hy', hynorm⟩ := + Ideal.Quotient.norm_mk_lt (ε := ε / 2) y (half_pos hε) + calc + ‖x + y‖ = ‖Ideal.Quotient.mk I x' + Ideal.Quotient.mk I y'‖ := by + rw [hx', hy'] + _ = ‖Ideal.Quotient.mk I (x' + y')‖ := by rw [map_add] + _ ≤ ‖x' + y'‖ := Ideal.Quotient.norm_mk_le I _ + _ ≤ max ‖x'‖ ‖y'‖ := IsUltrametricDist.norm_add_le_max _ _ + _ ≤ max (‖x‖ + ε / 2) (‖y‖ + ε / 2) := + max_le_max (le_of_lt hxnorm) (le_of_lt hynorm) + _ ≤ max ‖x‖ ‖y‖ + ε := by + apply max_le + · linarith [le_max_left ‖x‖ ‖y‖] + · linarith [le_max_right ‖x‖ ‖y‖] + +variable (K : Type u) [NontriviallyNormedField K] [NormedAlgebra K R] + +/-- The quotient map by a closed ideal, bundled as a continuous algebra homomorphism. -/ +noncomputable def idealQuotientMk (I : Ideal R) [IsClosed (I : Set R)] : + ContinuousAlgHom K R (R ⧸ I) where + toAlgHom := Ideal.Quotient.mkₐ K I + cont := AddMonoidHomClass.continuous_of_bound (Ideal.Quotient.mkₐ K I) 1 fun r ↦ by + change ‖Ideal.Quotient.mk I r‖ ≤ 1 * ‖r‖ + simpa only [one_mul] using Ideal.Quotient.norm_mk_le I r + +end Quotient + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] + +/-- Every ideal is closed once the given norm topology is known to be the canonical affinoid +quotient topology. -/ +theorem isClosed_ideal_of_topology_eq_affinoidTopology + (hA : IsAffinoidAlgebra K A) + (htop : (inferInstance : TopologicalSpace A) = affinoidTopology K A hA) + (I : Ideal A) : IsClosed (I : Set A) := by + let P := hA.presentation + have hcanonical : + @IsClosed A (affinoidTopology K A hA) (I : Set A) := by + letI : TopologicalSpace A := affinoidTopology K A hA + have hquotient : IsOpenQuotientMap P.toAlgHom := + isOpenQuotientMap_coinduced P.toAlgHom P.toAlgHom_surjective + rw [← hquotient.isQuotientMap.isClosed_preimage] + change IsClosed + ((I.comap P.toAlgHom.toRingHom : Ideal (TateAlgebra K (Fin P.n))) : + Set (TateAlgebra K (Fin P.n))) + exact isClosed_tateAlgebra_ideal K _ + rw [← isOpen_compl_iff] + change @IsOpen A (inferInstance : TopologicalSpace A) ((I : Set A)ᶜ) + rw [htop] + exact hcanonical.isOpen_compl + +end Rigid diff --git a/Rigid/AffinoidAlgebra/CompletedLaurent.lean b/Rigid/AffinoidAlgebra/CompletedLaurent.lean new file mode 100644 index 0000000..de0e4c1 --- /dev/null +++ b/Rigid/AffinoidAlgebra/CompletedLaurent.lean @@ -0,0 +1,333 @@ +import Rigid.TateAlgebra.RelativeUniversalProperty +import Mathlib.Algebra.Exact.Basic + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# The completed Laurent coefficient sequence + +The middle row in BGR 8.2.3/1 is the completed version of the elementary Laurent-polynomial +sequence. A restricted Laurent series is a family `(aₙ)ₙ∈ℤ` tending to zero along the cofinite +filter. Its nonnegative and negative coefficients give two one-variable Tate series, and the only +ambiguity is the constant coefficient. + +This file proves that coefficient statement over an arbitrary nonarchimedean Banach algebra. It +is the analytic input used in the Laurent-cover diagram before passing to the closed ideals +`(T - f)` and `(1 - fS)`. +-/ + +open Filter +open scoped Topology + +universe u v + +namespace Rigid + +namespace CompletedLaurent + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +/-- Restricted Laurent coefficient families, viewed as a `K`-submodule of all `ℤ`-indexed +families. -/ +def seriesSubmodule : Submodule K (ℤ → A) where + carrier := {a | Tendsto a cofinite (𝓝 0)} + zero_mem' := tendsto_const_nhds + add_mem' := by + intro a b ha hb + change Tendsto (fun n ↦ a n + b n) cofinite (𝓝 0) + simpa only [add_zero] using ha.add hb + smul_mem' := by + intro c a ha + change Tendsto (fun n ↦ c • a n) cofinite (𝓝 0) + simpa only [smul_zero] using + (tendsto_const_nhds.smul ha : Tendsto (fun n ↦ c • a n) cofinite (𝓝 (c • 0))) + +/-- The additive `K`-module of restricted Laurent series. -/ +abbrev Series := seriesSubmodule K A + +/-- The exponent supported at the unique variable of a one-variable Tate algebra. -/ +noncomputable def oneExponent (n : ℕ) : Fin 1 →₀ ℕ := + Finsupp.single 0 n + +private theorem oneExponent_injective : Function.Injective (oneExponent : ℕ → Fin 1 →₀ ℕ) := by + intro m n h + have h0 := congrArg (fun e : Fin 1 →₀ ℕ ↦ e 0) h + simpa [oneExponent] using h0 + +private theorem exponent_eq_oneExponent (e : Fin 1 →₀ ℕ) : + e = oneExponent (e 0) := by + apply Finsupp.ext + intro i + rw [Fin.eq_zero i] + simp [oneExponent] + +private theorem exponentValue_injective : + Function.Injective (fun e : Fin 1 →₀ ℕ ↦ e 0) := by + intro e e' h + rw [exponent_eq_oneExponent e, exponent_eq_oneExponent e'] + exact congrArg oneExponent h + +/-- The coefficient sequence of a one-variable Tate series tends to zero. -/ +theorem tendsto_oneVariable_coeff (p : TateAlgebra A (Fin 1)) : + Tendsto (fun n ↦ TateAlgebra.coeff A (Fin 1) (oneExponent n) p) + cofinite (𝓝 0) := by + apply tendsto_zero_iff_norm_tendsto_zero.mpr + exact (tendsto_norm_coeff_zero A (Fin 1) p).comp + oneExponent_injective.tendsto_cofinite + +/-- Build a one-variable Tate series from a coefficient family tending to zero. -/ +noncomputable def ofCoefficients (a : ℕ → A) (ha : Tendsto a cofinite (𝓝 0)) : + TateAlgebra A (Fin 1) := + ⟨fun e ↦ a (e 0), by + change Tendsto (fun e : Fin 1 →₀ ℕ ↦ + ‖MvPowerSeries.coeff e (fun e : Fin 1 →₀ ℕ ↦ a (e 0) : MvPowerSeries (Fin 1) A)‖ * + e.prod fun _ n ↦ (1 : ℝ) ^ n) cofinite (𝓝 0) + simp only [MvPowerSeries.coeff_apply, one_pow, Finsupp.prod, Finset.prod_const_one, mul_one] + exact (tendsto_zero_iff_norm_tendsto_zero.mp ha).comp + exponentValue_injective.tendsto_cofinite⟩ + +@[simp] +theorem coeff_ofCoefficients (a : ℕ → A) (ha : Tendsto a cofinite (𝓝 0)) (n : ℕ) : + TateAlgebra.coeff A (Fin 1) (oneExponent n) (ofCoefficients A a ha) = a n := by + simp only [TateAlgebra.coeff_apply, ofCoefficients, MvPowerSeries.coeff_apply, + oneExponent, Finsupp.single_eq_same] + +private theorem tendsto_nonnegativeExtension + (a : ℕ → A) (ha : Tendsto a cofinite (𝓝 0)) : + Tendsto (fun z : ℤ ↦ if 0 ≤ z then a z.toNat else 0) cofinite (𝓝 0) := by + rw [tendsto_def] + intro s hs + have h0 : (0 : A) ∈ s := mem_of_mem_nhds hs + have ha' : {n | a n ∈ s} ∈ (cofinite : Filter ℕ) := ha hs + rw [mem_cofinite] at ha' ⊢ + have hbad : Set.Finite {n : ℕ | a n ∉ s} := by + simpa only [Set.compl_setOf] using ha' + let bad : Set ℤ := {z | (if 0 ≤ z then a z.toNat else 0) ∉ s} + change bad.Finite + apply Set.Finite.of_finite_image + · exact hbad.subset (by + rintro n ⟨z, hz, rfl⟩ + change (if 0 ≤ z then a z.toNat else 0) ∉ s at hz + by_cases hz0 : 0 ≤ z + · simpa [hz0] using hz + · exact (hz (by simpa [hz0] using h0)).elim) + · intro z hz w hw hzw + have hz0 : 0 ≤ z := by + by_contra h + change (if 0 ≤ z then a z.toNat else 0) ∉ s at hz + exact hz (by simpa [h] using h0) + have hw0 : 0 ≤ w := by + by_contra h + change (if 0 ≤ w then a w.toNat else 0) ∉ s at hw + exact hw (by simpa [h] using h0) + calc + z = (z.toNat : ℤ) := (Int.toNat_of_nonneg hz0).symm + _ = (w.toNat : ℤ) := congrArg (fun n : ℕ ↦ (n : ℤ)) hzw + _ = w := Int.toNat_of_nonneg hw0 + +/-- Embed a nonnegative restricted power series into restricted Laurent coefficients. -/ +noncomputable def positive : TateAlgebra A (Fin 1) →ₗ[K] Series K A where + toFun p := + ⟨fun z ↦ if 0 ≤ z then + TateAlgebra.coeff A (Fin 1) (oneExponent z.toNat) p else 0, + tendsto_nonnegativeExtension A _ (tendsto_oneVariable_coeff A p)⟩ + map_add' p q := by + ext z + by_cases hz : 0 ≤ z <;> simp [hz, TateAlgebra.coeff] + map_smul' c p := by + ext z + change (if 0 ≤ z then + TateAlgebra.coeff A (Fin 1) (oneExponent z.toNat) (c • p) else 0) = + c • (if 0 ≤ z then + TateAlgebra.coeff A (Fin 1) (oneExponent z.toNat) p else 0) + by_cases hz : 0 ≤ z + · rw [if_pos hz, if_pos hz] + change MvPowerSeries.coeff (oneExponent z.toNat) + ((c • p : TateAlgebra A (Fin 1)) : MvPowerSeries (Fin 1) A) = + c • MvPowerSeries.coeff (oneExponent z.toNat) p.1 + simp only [Algebra.smul_def] + change MvPowerSeries.coeff (oneExponent z.toNat) + (MvPowerSeries.C (algebraMap K A c) * p.1) = + algebraMap K A c * MvPowerSeries.coeff (oneExponent z.toNat) p.1 + rw [MvPowerSeries.coeff_C_mul] + · simp [hz] + +/-- Embed a nonpositive restricted power series into restricted Laurent coefficients by sending +`T` to the formal inverse Laurent variable. -/ +noncomputable def negative : TateAlgebra A (Fin 1) →ₗ[K] Series K A where + toFun p := + ⟨fun z ↦ (positive K A p).1 (-z), + (positive K A p).2.comp (Equiv.neg ℤ).injective.tendsto_cofinite⟩ + map_add' p q := by + ext z + simp + map_smul' c p := by + ext z + simp + +/-- Constants embedded in both one-variable Tate algebras. -/ +noncomputable def diagonal : A →ₗ[K] TateAlgebra A (Fin 1) × TateAlgebra A (Fin 1) := + let base := (IsScalarTower.toAlgHom K A (TateAlgebra A (Fin 1))).toLinearMap + base.prod base + +/-- Difference between the positive and negative Laurent expansions. -/ +noncomputable def difference : + TateAlgebra A (Fin 1) × TateAlgebra A (Fin 1) →ₗ[K] Series K A := + (positive K A).comp (LinearMap.fst K _ _) - + (negative K A).comp (LinearMap.snd K _ _) + +@[simp] +theorem diagonal_apply (a : A) : + diagonal K A a = (TateAlgebra.C A (Fin 1) a, TateAlgebra.C A (Fin 1) a) := + rfl + +@[simp] +theorem difference_coeff_zero (p q : TateAlgebra A (Fin 1)) : + (difference K A (p, q)).1 0 = + TateAlgebra.coeff A (Fin 1) (oneExponent 0) p - + TateAlgebra.coeff A (Fin 1) (oneExponent 0) q := by + rfl + +theorem difference_coeff_pos (p q : TateAlgebra A (Fin 1)) (n : ℕ) (hn : 0 < n) : + (difference K A (p, q)).1 (n : ℤ) = + TateAlgebra.coeff A (Fin 1) (oneExponent n) p := by + simp [difference, positive, negative, hn.ne'] + +theorem difference_coeff_neg (p q : TateAlgebra A (Fin 1)) (n : ℕ) (hn : 0 < n) : + (difference K A (p, q)).1 (-(n : ℤ)) = + -TateAlgebra.coeff A (Fin 1) (oneExponent n) q := by + simp [difference, positive, negative, hn.ne'] + +/-- The image of the diagonal constants is the kernel of Laurent coefficient difference. -/ +theorem exact : Function.Exact (diagonal K A) (difference K A) := by + rintro ⟨p, q⟩ + constructor + · intro h + let a := TateAlgebra.coeff A (Fin 1) (oneExponent 0) p + have hzero := congrArg (fun z : Series K A ↦ z.1 0) h + change (difference K A (p, q)).1 0 = 0 at hzero + rw [difference_coeff_zero] at hzero + have hp : p = TateAlgebra.C A (Fin 1) a := by + apply TateAlgebra.ext + intro e + rw [exponent_eq_oneExponent e] + by_cases he : e 0 = 0 + · rw [he] + simp [a, oneExponent] + · have hn : 0 < e 0 := Nat.pos_of_ne_zero he + have hcoeff := congrArg (fun z : Series K A ↦ z.1 (e 0 : ℤ)) h + change (difference K A (p, q)).1 (e 0 : ℤ) = 0 at hcoeff + rw [difference_coeff_pos K A p q (e 0) hn] at hcoeff + have hexp : oneExponent (e 0) ≠ 0 := by + intro hexp + have := congrArg (fun d : Fin 1 →₀ ℕ ↦ d 0) hexp + exact he (by simpa [oneExponent] using this) + rw [TateAlgebra.coeff_C, if_neg hexp] + exact hcoeff + have hq : q = TateAlgebra.C A (Fin 1) a := by + apply TateAlgebra.ext + intro e + rw [exponent_eq_oneExponent e] + by_cases he : e 0 = 0 + · rw [he] + rw [TateAlgebra.coeff_C, if_pos (by simp [oneExponent])] + simpa [a] using (sub_eq_zero.mp hzero).symm + · have hn : 0 < e 0 := Nat.pos_of_ne_zero he + have hcoeff := congrArg (fun z : Series K A ↦ z.1 (-(e 0 : ℤ))) h + change (difference K A (p, q)).1 (-(e 0 : ℤ)) = 0 at hcoeff + rw [difference_coeff_neg K A p q (e 0) hn] at hcoeff + have hqzero : + TateAlgebra.coeff A (Fin 1) (oneExponent (e 0)) q = 0 := by + simpa using neg_eq_zero.mp hcoeff + have hexp : oneExponent (e 0) ≠ 0 := by + intro hexp + have := congrArg (fun d : Fin 1 →₀ ℕ ↦ d 0) hexp + exact he (by simpa [oneExponent] using this) + rw [TateAlgebra.coeff_C, if_neg hexp] + exact hqzero + exact ⟨a, by simp [hp, hq]⟩ + · rintro ⟨a, ha⟩ + rw [← ha, diagonal_apply] + ext z + by_cases hz : z = 0 + · subst z + simp [difference_coeff_zero, oneExponent] + · by_cases hz0 : 0 < z + · obtain ⟨n, hn⟩ := Int.eq_ofNat_of_zero_le hz0.le + subst z + have hn0 : 0 < n := by + simpa using hz0 + rw [difference_coeff_pos K A _ _ n hn0] + rw [TateAlgebra.coeff_C] + simp [oneExponent, hn0.ne'] + · have hzneg : z < 0 := lt_of_le_of_ne (le_of_not_gt hz0) hz + obtain ⟨n, hn⟩ := Int.eq_negSucc_of_lt_zero hzneg + rw [hn, Int.negSucc_eq] + convert difference_coeff_neg K A + (TateAlgebra.C A (Fin 1) a) (TateAlgebra.C A (Fin 1) a) + (n + 1) (Nat.succ_pos n) using 1 <;> + simp [oneExponent] + +/-- Every restricted Laurent coefficient family splits into a nonnegative and a nonpositive Tate +series. -/ +theorem difference_surjective : Function.Surjective (difference K A) := by + intro a + let pa : ℕ → A := fun n ↦ a.1 (n : ℤ) + have hpa : Tendsto pa cofinite (𝓝 0) := + a.2.comp (show Function.Injective (fun n : ℕ ↦ (n : ℤ)) by + intro n m h + exact Int.ofNat.inj h).tendsto_cofinite + let qa : ℕ → A := fun n ↦ if n = 0 then 0 else -a.1 (-(n : ℤ)) + have hbase : Tendsto (fun n : ℕ ↦ -a.1 (-(n : ℤ))) cofinite (𝓝 0) := by + have ht := a.2.neg.comp + (show Function.Injective (fun n : ℕ ↦ -(n : ℤ)) by + intro n m h + exact Int.ofNat.inj (Int.neg_inj.mp h)).tendsto_cofinite + change Tendsto (fun n : ℕ ↦ -a.1 (-(n : ℤ))) cofinite (𝓝 (-0)) at ht + simpa only [neg_zero] using ht + have hqa : Tendsto qa cofinite (𝓝 0) := by + apply hbase.congr' + filter_upwards [(Set.finite_singleton 0).compl_mem_cofinite] with n hn + have hn' : n ≠ 0 := by simpa using hn + simp [qa, hn'] + refine ⟨(ofCoefficients A pa hpa, ofCoefficients A qa hqa), ?_⟩ + ext z + by_cases hz : z = 0 + · subst z + rw [difference_coeff_zero, coeff_ofCoefficients, coeff_ofCoefficients] + simp [pa, qa] + · by_cases hz0 : 0 < z + · obtain ⟨n, hn⟩ := Int.eq_ofNat_of_zero_le hz0.le + subst z + have hn0 : 0 < n := by simpa using hz0 + rw [difference_coeff_pos K A _ _ n hn0] + rw [coeff_ofCoefficients] + · have hzneg : z < 0 := lt_of_le_of_ne (le_of_not_gt hz0) hz + obtain ⟨n, hn⟩ := Int.eq_negSucc_of_lt_zero hzneg + rw [hn, Int.negSucc_eq] + convert difference_coeff_neg K A + (ofCoefficients A pa hpa) (ofCoefficients A qa hqa) + (n + 1) (Nat.succ_pos n) using 1 + · simp + · rw [coeff_ofCoefficients] + simp [qa] + +/-- The completed Laurent coefficient sequence is short exact. -/ +theorem shortExact : + Function.Injective (diagonal K A) ∧ + Function.Exact (diagonal K A) (difference K A) ∧ + Function.Surjective (difference K A) := by + refine ⟨?_, exact K A, difference_surjective K A⟩ + intro a b h + have hfirst := congrArg Prod.fst h + have hcoeff := congrArg + (fun p : TateAlgebra A (Fin 1) ↦ TateAlgebra.coeff A (Fin 1) (oneExponent 0) p) + hfirst + simpa [TateAlgebra.coeff_C, oneExponent] using hcoeff + +end CompletedLaurent + +end Rigid diff --git a/Rigid/AffinoidAlgebra/FiniteExtensionFunctional.lean b/Rigid/AffinoidAlgebra/FiniteExtensionFunctional.lean new file mode 100644 index 0000000..4922235 --- /dev/null +++ b/Rigid/AffinoidAlgebra/FiniteExtensionFunctional.lean @@ -0,0 +1,103 @@ +import Mathlib.FieldTheory.IntermediateField.Adjoin.Basic +import Mathlib.LinearAlgebra.Basis.VectorSpace + +set_option linter.style.header false + +/-! +# Linear functionals on simple field extensions + +The domain case of Proposition 4.5.3 extends evaluation at a root from the simple field generated +by an element to the ambient fraction field. This file isolates that purely linear-algebraic +step. No finiteness assumption is needed for existence; finite generation is used later to prove +that the resulting functional is bounded. +-/ + +namespace Rigid + +namespace FiniteExtensionFunctional + +universe u v w + +variable {F : Type u} {E : Type v} {L : Type w} +variable [Field F] [Field E] [Field L] [Algebra F E] [Algebra F L] + +/-- Evaluation at a root of the minimal polynomial, transported to the simple field generated by +the original algebraic element. -/ +noncomputable def adjoinSimpleLift (c : E) (hc : IsIntegral F c) (z : L) + (hz : Polynomial.aeval z (minpoly F c) = 0) : + IntermediateField.adjoin F {c} →ₐ[F] L := + (AdjoinRoot.liftAlgHom (minpoly F c) (Algebra.ofId F L) z hz).comp + (IntermediateField.adjoinRootEquivAdjoin F hc).symm.toAlgHom + +@[simp] +theorem adjoinSimpleLift_gen (c : E) (hc : IsIntegral F c) (z : L) + (hz : Polynomial.aeval z (minpoly F c) = 0) : + adjoinSimpleLift c hc z hz (IntermediateField.AdjoinSimple.gen F c) = z := by + change Polynomial.eval₂ (Algebra.ofId F L) z (minpoly F c) = 0 at hz + simp [adjoinSimpleLift, IntermediateField.adjoinRootEquivAdjoin_symm_apply_gen] + +/-- An `F`-algebra map from the simple field `F(c)` extends to an `F`-linear map on `E`, and the +extension carries every power of `c` to the corresponding power of the image of the generator. + +This is the linear-extension step in the proof of Proposition 4.5.7. -/ +theorem exists_linearMap_map_pow_eq (c : E) + (g : IntermediateField.adjoin F {c} →ₐ[F] L) : + ∃ G : E →ₗ[F] L, ∀ m : ℕ, G (c ^ m) = g (IntermediateField.AdjoinSimple.gen F c) ^ m := by + obtain ⟨G, hG⟩ := LinearMap.exists_extend (K := F) (V := E) (V' := L) + (p := (IntermediateField.adjoin F {c}).toSubmodule) g.toLinearMap + refine ⟨G, fun m ↦ ?_⟩ + let cm : IntermediateField.adjoin F {c} := + (IntermediateField.AdjoinSimple.gen F c) ^ m + have hm := LinearMap.congr_fun hG cm + change G (c ^ m) = g cm at hm + calc + G (c ^ m) = g cm := hm + _ = g (IntermediateField.AdjoinSimple.gen F c) ^ m := map_pow g _ m + +/-- A root of the minimal polynomial gives a linear functional on the ambient field carrying all +powers of the original element to the corresponding powers of that root. -/ +theorem exists_linearMap_map_pow_eq_of_minpoly_root (c : E) (hc : IsIntegral F c) (z : L) + (hz : Polynomial.aeval z (minpoly F c) = 0) : + ∃ G : E →ₗ[F] L, ∀ m : ℕ, G (c ^ m) = z ^ m := by + obtain ⟨G, hG⟩ := exists_linearMap_map_pow_eq c (adjoinSimpleLift c hc z hz) + refine ⟨G, fun m ↦ ?_⟩ + simpa using hG m + +section Restriction + +variable {R : Type*} {C : Type*} +variable [CommRing R] [CommRing C] [Algebra R C] +variable [Algebra R F] [Algebra R E] [Algebra R L] +variable [Algebra C E] +variable [IsScalarTower R C E] [IsScalarTower R F E] [IsScalarTower R F L] + +/-- Restrict the extended functional from a field containing `C` back to `C`. In the application, +`F` and `E` are fraction fields of `R` and `C`, respectively. -/ +theorem exists_linearMap_map_algebraMap_pow_eq (c : C) + (g : IntermediateField.adjoin F {algebraMap C E c} →ₐ[F] L) : + ∃ G : C →ₗ[R] L, ∀ m : ℕ, + G (c ^ m) = g (IntermediateField.AdjoinSimple.gen F (algebraMap C E c)) ^ m := by + obtain ⟨H, hH⟩ := exists_linearMap_map_pow_eq (F := F) (E := E) (L := L) + (algebraMap C E c) g + let i : C →ₗ[R] E := (IsScalarTower.toAlgHom R C E).toLinearMap + let G : C →ₗ[R] L := (H.restrictScalars R).comp i + refine ⟨G, fun m ↦ ?_⟩ + change H (algebraMap C E (c ^ m)) = _ + rw [map_pow] + exact hH m + +/-- Restrict the minimal-polynomial root functional to the original finite algebra. -/ +theorem exists_linearMap_map_algebraMap_pow_eq_of_minpoly_root (c : C) + (hc : IsIntegral F (algebraMap C E c)) (z : L) + (hz : Polynomial.aeval z (minpoly F (algebraMap C E c)) = 0) : + ∃ G : C →ₗ[R] L, ∀ m : ℕ, G (c ^ m) = z ^ m := by + obtain ⟨G, hG⟩ := exists_linearMap_map_algebraMap_pow_eq (R := R) (F := F) (E := E) + (L := L) c (adjoinSimpleLift (algebraMap C E c) hc z hz) + refine ⟨G, fun m ↦ ?_⟩ + simpa using hG m + +end Restriction + +end FiniteExtensionFunctional + +end Rigid diff --git a/Rigid/AffinoidAlgebra/FiniteModuleBounded.lean b/Rigid/AffinoidAlgebra/FiniteModuleBounded.lean new file mode 100644 index 0000000..ffe6f3e --- /dev/null +++ b/Rigid/AffinoidAlgebra/FiniteModuleBounded.lean @@ -0,0 +1,163 @@ +import Mathlib.Analysis.Normed.Operator.Banach +import Mathlib.RingTheory.Algebraic.Integral +import Mathlib.RingTheory.Finiteness.Cardinality +import Rigid.AffinoidAlgebra.FiniteExtensionFunctional + +set_option linter.style.header false + +/-! +# Bounded linear maps from finite Banach modules + +The bounded-functional step in the domain proof of the sharp spectral polynomial theorem uses a +standard Banach-module argument. A finite module is a quotient of a finite free module. Scalar +linearity makes every map out of that free module continuous, and the Banach open mapping theorem +gives controlled preimages. Consequently every linear map between such topological modules is +bounded. +-/ + +universe u v w x y z + +namespace Rigid + +/-- A continuous ring homomorphism makes its target a topological module over its source. -/ +theorem continuousSMul_of_continuousRingHom {R S : Type*} [NormedCommRing R] [NormedCommRing S] + (f : R →+* S) (hf : Continuous f) : + letI : Algebra R S := f.toAlgebra + ContinuousSMul R S := by + letI : Algebra R S := f.toAlgebra + constructor + change Continuous fun p : R × S ↦ f p.1 * p.2 + exact (hf.comp continuous_fst).mul continuous_snd + +section FiniteModule + +variable {K : Type u} [NontriviallyNormedField K] +variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] +variable {C : Type w} [NormedAddCommGroup C] [NormedSpace K C] [CompleteSpace C] +variable {L : Type x} [NormedAddCommGroup L] [NormedSpace K L] +variable [Module A C] [Module A L] [IsScalarTower K A C] [IsScalarTower K A L] +variable [ContinuousSMul A C] [ContinuousSMul A L] + +include K in +/-- A linear map from a finite Banach `A`-module is bounded, provided both scalar actions are +continuous. The target itself need not be complete. -/ +theorem LinearMap.exists_bound_of_module_finite [Module.Finite A C] (F : C →ₗ[A] L) : + ∃ M : ℝ, 0 < M ∧ ∀ c : C, ‖F c‖ ≤ M * ‖c‖ := by + obtain ⟨m, q, hq⟩ := Module.Finite.exists_fin' A C + let qK : (Fin m → A) →L[K] C := + { toLinearMap := q.restrictScalars K + cont := q.continuous_on_pi } + let Fq : (Fin m → A) →ₗ[A] L := F.comp q + let FqK : (Fin m → A) →L[K] L := + { toLinearMap := Fq.restrictScalars K + cont := Fq.continuous_on_pi } + obtain ⟨Q, hQpos, hQ⟩ := qK.exists_preimage_norm_le hq + let M : ℝ := max 1 (‖FqK‖ * Q) + refine ⟨M, lt_of_lt_of_le zero_lt_one (le_max_left _ _), fun c ↦ ?_⟩ + obtain ⟨a, ha, hanorm⟩ := hQ c + calc + ‖F c‖ = ‖FqK a‖ := by rw [← ha]; rfl + _ ≤ ‖FqK‖ * ‖a‖ := FqK.le_opNorm a + _ ≤ ‖FqK‖ * (Q * ‖c‖) := + mul_le_mul_of_nonneg_left hanorm (norm_nonneg FqK) + _ = (‖FqK‖ * Q) * ‖c‖ := by rw [mul_assoc] + _ ≤ M * ‖c‖ := + mul_le_mul_of_nonneg_right (le_max_right 1 (‖FqK‖ * Q)) (norm_nonneg c) + +end FiniteModule + +section FractionFieldFunctional + +variable {K : Type u} [NontriviallyNormedField K] +variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] +variable {C : Type w} [NormedCommRing C] [NormedAlgebra K C] [CompleteSpace C] +variable {F : Type x} {E : Type y} {L : Type z} +variable [Field F] [Field E] +variable [NormedField L] [NormedSpace K L] +variable [Algebra A C] [Algebra A F] [Algebra A E] [Algebra A L] +variable [Algebra C E] [Algebra F E] [Algebra F L] +variable [IsScalarTower K A C] +variable [IsScalarTower A C E] [IsScalarTower A F E] [IsScalarTower A F L] +variable [ContinuousSMul A C] [ContinuousSMul A L] + +include K in +/-- The algebraic root functional on the ambient fraction field becomes bounded after restriction +to a finite Banach algebra. This packages the linear-extension and open-mapping steps of +Proposition 4.5.7; the remaining input is the identification of the relevant minimal polynomial. -/ +theorem exists_bounded_linearMap_map_algebraMap_pow_eq_of_minpoly_root + [Module.Finite A C] + (hKAL : IsScalarTower K A L) (c : C) + (hc : IsIntegral F (algebraMap C E c)) (z : L) + (hz : Polynomial.aeval z (minpoly F (algebraMap C E c)) = 0) : + ∃ (G : C →ₗ[A] L) (M : ℝ), 0 < M ∧ (∀ m : ℕ, G (c ^ m) = z ^ m) ∧ + ∀ a : C, ‖G a‖ ≤ M * ‖a‖ := by + letI : IsScalarTower K A L := hKAL + obtain ⟨G, hGpow⟩ := + FiniteExtensionFunctional.exists_linearMap_map_algebraMap_pow_eq_of_minpoly_root + (R := A) (F := F) (E := E) (L := L) c hc z hz + obtain ⟨M, hM, hG⟩ := Rigid.LinearMap.exists_bound_of_module_finite (K := K) G + exact ⟨G, M, hM, hGpow, hG⟩ + +include K in +/-- Fraction-field specialization of +`exists_bounded_linearMap_map_algebraMap_pow_eq_of_minpoly_root`. The two fraction-field algebra +structures are the canonical lifts of the injective maps from `A`. -/ +theorem exists_bounded_fractionRingFunctional_of_minpoly_root + [IsDomain A] [IsDomain C] [FaithfulSMul A C] [FaithfulSMul A L] [Module.Finite A C] + (hKAL : IsScalarTower K A L) (c : C) (z : L) : + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + letI : IsScalarTower A (FractionRing A) (FractionRing C) := + FractionRing.isScalarTower_liftAlgebra A (FractionRing C) + letI : Algebra (FractionRing A) L := FractionRing.liftAlgebra A L + letI : IsScalarTower A (FractionRing A) L := FractionRing.isScalarTower_liftAlgebra A L + IsIntegral (FractionRing A) (algebraMap C (FractionRing C) c) → + Polynomial.aeval z (minpoly (FractionRing A) (algebraMap C (FractionRing C) c)) = 0 → + ∃ (G : C →ₗ[A] L) (M : ℝ), 0 < M ∧ (∀ m : ℕ, G (c ^ m) = z ^ m) ∧ + ∀ a : C, ‖G a‖ ≤ M * ‖a‖ := by + intro hc hz + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + letI : IsScalarTower A (FractionRing A) (FractionRing C) := + FractionRing.isScalarTower_liftAlgebra A (FractionRing C) + letI : Algebra (FractionRing A) L := FractionRing.liftAlgebra A L + letI : IsScalarTower A (FractionRing A) L := + FractionRing.isScalarTower_liftAlgebra A L + exact exists_bounded_linearMap_map_algebraMap_pow_eq_of_minpoly_root + (K := K) (A := A) (C := C) (F := FractionRing A) (E := FractionRing C) (L := L) + hKAL c hc z hz + +include K in +/-- For a finite extension, algebraicity of the fraction-field extension supplies the integrality +hypothesis in `exists_bounded_fractionRingFunctional_of_minpoly_root` automatically. -/ +theorem exists_bounded_fractionRingFunctional_of_minpoly_root_of_finite + [IsDomain A] [IsDomain C] [FaithfulSMul A C] [FaithfulSMul A L] [Module.Finite A C] + (hKAL : IsScalarTower K A L) (c : C) (z : L) : + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + Polynomial.eval₂ (IsFractionRing.lift (FaithfulSMul.algebraMap_injective A L)) z + (minpoly (FractionRing A) (algebraMap C (FractionRing C) c)) = 0 → + ∃ (G : C →ₗ[A] L) (M : ℝ), 0 < M ∧ (∀ m : ℕ, G (c ^ m) = z ^ m) ∧ + ∀ a : C, ‖G a‖ ≤ M * ‖a‖ := by + intro hz + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + letI : IsScalarTower A (FractionRing A) (FractionRing C) := + FractionRing.isScalarTower_liftAlgebra A (FractionRing C) + letI : Algebra (FractionRing A) L := FractionRing.liftAlgebra A L + letI : IsScalarTower A (FractionRing A) L := + FractionRing.isScalarTower_liftAlgebra A L + have hc : IsIntegral (FractionRing A) (algebraMap C (FractionRing C) c) := + (Algebra.IsAlgebraic.isAlgebraic _).isIntegral + have hz' : Polynomial.aeval z + (minpoly (FractionRing A) (algebraMap C (FractionRing C) c)) = 0 := by + change Polynomial.eval₂ (algebraMap (FractionRing A) L) z + (minpoly (FractionRing A) (algebraMap C (FractionRing C) c)) = 0 + exact hz + exact exists_bounded_linearMap_map_algebraMap_pow_eq_of_minpoly_root + (K := K) (A := A) (C := C) (F := FractionRing A) (E := FractionRing C) (L := L) + hKAL c hc z hz' + +end FractionFieldFunctional + +end Rigid diff --git a/Rigid/AffinoidAlgebra/LaurentCharts.lean b/Rigid/AffinoidAlgebra/LaurentCharts.lean new file mode 100644 index 0000000..f58a2d5 --- /dev/null +++ b/Rigid/AffinoidAlgebra/LaurentCharts.lean @@ -0,0 +1,141 @@ +import Rigid.AffinoidAlgebra.RationalLocalization + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# The analytic maps in a two-member Laurent cover + +For `f ∈ A`, the two Laurent charts are `A⟨f⟩` and `A⟨f⁻¹⟩`. Their overlap can be obtained by +localizing the first chart once more at `f`. This file constructs the two restriction maps into +that overlap and the first two arrows + +`A ⟶ A⟨f⟩ × A⟨f⁻¹⟩ ⟶ A⟨f, f⁻¹⟩` + +of Tate's Laurent-cover sequence. It proves that these arrows form a complex. Exactness is the +closed-ideal descent of the completed coefficient sequence in `CompletedLaurent`. +-/ + +universe u v + +namespace Rigid + +namespace LaurentCharts + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +/-- The Laurent chart on which `|f| ≤ 1`. -/ +abbrev Plus (f : A) := + RationalLocalization K A 1 1 (fun _ ↦ f) + +/-- The Laurent chart on which `1 ≤ |f|`. -/ +abbrev Minus (f : A) := + RationalLocalization K A 1 f (fun _ ↦ 1) + +/-- The overlap, obtained from the positive chart by adjoining a power-bounded inverse of `f`. -/ +abbrev Overlap (f : A) := + RationalLocalization K (Plus K A f) 1 + (RationalLocalization.baseMap K A 1 1 (fun _ ↦ f) f) (fun _ ↦ 1) + +/-- Restriction from the ambient algebra to the positive Laurent chart. -/ +noncomputable def plusMap (f : A) : ContinuousAlgHom K A (Plus K A f) := + RationalLocalization.baseMap K A 1 1 (fun _ ↦ f) + +/-- Restriction from the ambient algebra to the negative Laurent chart. -/ +noncomputable def minusMap (f : A) : ContinuousAlgHom K A (Minus K A f) := + RationalLocalization.baseMap K A 1 f (fun _ ↦ 1) + +/-- Restriction from the positive Laurent chart to the overlap. -/ +noncomputable def plusToOverlap (f : A) : + ContinuousAlgHom K (Plus K A f) (Overlap K A f) := + RationalLocalization.baseMap K (Plus K A f) 1 (plusMap K A f f) (fun _ ↦ 1) + +/-- The ambient map from `A` to the overlap. -/ +noncomputable def overlapMap (f : A) : ContinuousAlgHom K A (Overlap K A f) := + (plusToOverlap K A f).comp (plusMap K A f) + +/-- The power-bounded inverse of `f` on the overlap. -/ +noncomputable def overlapInverse (f : A) : Overlap K A f := + RationalLocalization.coordinate K (Plus K A f) 1 (plusMap K A f f) (fun _ ↦ 1) 0 + +theorem isPowerBounded_overlapInverse (f : A) : + IsPowerBounded (overlapInverse K A f) := + RationalLocalization.isPowerBounded_coordinate K (Plus K A f) 1 + (plusMap K A f f) (fun _ ↦ 1) 0 + +@[simp] +theorem overlapMap_mul_inverse (f : A) : + overlapMap K A f f * overlapInverse K A f = 1 := by + change + RationalLocalization.baseMap K (Plus K A f) 1 (plusMap K A f f) (fun _ ↦ 1) + (plusMap K A f f) * + RationalLocalization.coordinate K (Plus K A f) 1 + (plusMap K A f f) (fun _ ↦ 1) 0 = 1 + rw [RationalLocalization.baseMap_denominator_mul_coordinate] + simp + +/-- Restriction from the negative Laurent chart to the overlap. -/ +noncomputable def minusToOverlap (f : A) : + ContinuousAlgHom K (Minus K A f) (Overlap K A f) := + RationalLocalization.lift K A 1 f (fun _ ↦ 1) (overlapMap K A f) + (fun _ ↦ overlapInverse K A f) (fun _ ↦ isPowerBounded_overlapInverse K A f) + (fun _ ↦ by simp) + +@[simp] +theorem plusToOverlap_comp_plusMap (f : A) : + (plusToOverlap K A f).comp (plusMap K A f) = overlapMap K A f := + rfl + +@[simp] +theorem minusToOverlap_comp_minusMap (f : A) : + (minusToOverlap K A f).comp (minusMap K A f) = overlapMap K A f := + RationalLocalization.lift_comp_baseMap K A 1 f (fun _ ↦ 1) + (overlapMap K A f) (fun _ ↦ overlapInverse K A f) + (fun _ ↦ isPowerBounded_overlapInverse K A f) (fun _ ↦ by simp) + +/-- The diagonal restriction in the Laurent-cover sequence. -/ +noncomputable def diagonal (f : A) : + A →ₗ[K] Plus K A f × Minus K A f := + (plusMap K A f).toLinearMap.prod (minusMap K A f).toLinearMap + +/-- Difference of the two restrictions to the overlap. -/ +noncomputable def difference (f : A) : + Plus K A f × Minus K A f →ₗ[K] Overlap K A f := + (plusToOverlap K A f).toLinearMap.comp (LinearMap.fst K _ _) - + (minusToOverlap K A f).toLinearMap.comp (LinearMap.snd K _ _) + +@[simp] +theorem diagonal_apply (f a : A) : + diagonal K A f a = (plusMap K A f a, minusMap K A f a) := + rfl + +@[simp] +theorem difference_apply (f : A) (p : Plus K A f) (q : Minus K A f) : + difference K A f (p, q) = plusToOverlap K A f p - minusToOverlap K A f q := + rfl + +/-- The Laurent-cover arrows compose to zero. -/ +@[simp] +theorem difference_diagonal (f a : A) : + difference K A f (diagonal K A f a) = 0 := by + rw [diagonal_apply, difference_apply] + have hp := congrArg (fun φ : ContinuousAlgHom K A (Overlap K A f) ↦ φ a) + (plusToOverlap_comp_plusMap K A f) + have hm := congrArg (fun φ : ContinuousAlgHom K A (Overlap K A f) ↦ φ a) + (minusToOverlap_comp_minusMap K A f) + change plusToOverlap K A f (plusMap K A f a) = + overlapMap K A f a at hp + change minusToOverlap K A f (minusMap K A f a) = + overlapMap K A f a at hm + rw [hp, hm, sub_self] + +theorem range_diagonal_le_ker_difference (f : A) : + LinearMap.range (diagonal K A f) ≤ LinearMap.ker (difference K A f) := by + rintro _ ⟨a, rfl⟩ + exact LinearMap.mem_ker.mpr (difference_diagonal K A f a) + +end LaurentCharts + +end Rigid diff --git a/Rigid/AffinoidAlgebra/LaurentCover.lean b/Rigid/AffinoidAlgebra/LaurentCover.lean new file mode 100644 index 0000000..d8be743 --- /dev/null +++ b/Rigid/AffinoidAlgebra/LaurentCover.lean @@ -0,0 +1,135 @@ +import Mathlib.Algebra.Exact.Basic +import Mathlib.Algebra.Polynomial.Laurent + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# The algebraic Laurent-cover exact sequence + +The coefficient-splitting step in Tate's Laurent-cover argument is already visible on the dense +polynomial subalgebras. A Laurent polynomial splits into a polynomial in `T` and a polynomial in +`T⁻¹`; their intersection consists precisely of constants. This file proves the resulting short +exact sequence. The Banach-algebra proof follows the same decomposition after completing and +then descends it through the closed ideals `(T - f)` and `(1 - fT⁻¹)`, as in BGR 8.2.3/2. +-/ + +open Polynomial +open LaurentPolynomial +open scoped LaurentPolynomial + +universe u + +namespace Rigid + +namespace LaurentCover + +variable (R : Type u) [CommRing R] + +/-- Constants embed diagonally into the two polynomial charts. -/ +noncomputable def polynomialDiagonal : R →+ R[X] × R[X] where + toFun a := (Polynomial.C a, Polynomial.C a) + map_zero' := by simp + map_add' a b := by simp + +/-- The difference of the positive and negative polynomial expansions in the Laurent overlap. -/ +noncomputable def polynomialDifference : R[X] × R[X] →+ R[T;T⁻¹] where + toFun z := Polynomial.toLaurent z.1 - LaurentPolynomial.invert (Polynomial.toLaurent z.2) + map_zero' := by simp + map_add' p q := by simp; abel + +private theorem positive_coeff_eq_zero_of_toLaurent_eq_invert + {p q : R[X]} (h : Polynomial.toLaurent p = LaurentPolynomial.invert (Polynomial.toLaurent q)) + (n : ℕ) (hn : n ≠ 0) : p.coeff n = 0 := by + have hc := congrArg (fun z : R[T;T⁻¹] ↦ z.coeff (n : ℤ)) h + simp only [LaurentPolynomial.invert_apply, LaurentPolynomial.coeff_toLaurent] at hc + have hleft : + (Finsupp.mapDomain (⇑Nat.castEmbedding) p.toFinsupp.coeff) (n : ℤ) = p.coeff n := by + exact Finsupp.mapDomain_apply Nat.castEmbedding.injective _ n + rw [hleft] at hc + rw [Finsupp.mapDomain_notin_range] at hc + · exact hc + · rintro ⟨k, hk⟩ + change (k : ℤ) = -(n : ℤ) at hk + omega + +private theorem eq_C_coeff_zero_of_toLaurent_eq_invert + {p q : R[X]} (h : Polynomial.toLaurent p = LaurentPolynomial.invert (Polynomial.toLaurent q)) : + p = Polynomial.C (p.coeff 0) := by + ext n + by_cases hn : n = 0 + · subst n + simp + · have hp0 : p.coeff n = 0 := + positive_coeff_eq_zero_of_toLaurent_eq_invert R h n hn + rw [hp0, Polynomial.coeff_C] + simp [hn] + +/-- The polynomial Laurent difference is onto: split a Laurent polynomial into its nonnegative +and negative powers. -/ +theorem polynomialDifference_surjective : + Function.Surjective (polynomialDifference R) := by + intro z + induction z using LaurentPolynomial.induction_on' with + | add p q hp hq => + obtain ⟨p', rfl⟩ := hp + obtain ⟨q', rfl⟩ := hq + exact ⟨p' + q', map_add (polynomialDifference R) p' q'⟩ + | C_mul_T n a => + by_cases hn : 0 ≤ n + · let p : R[X] := Polynomial.monomial n.toNat a + refine ⟨(p, 0), ?_⟩ + simp [polynomialDifference, p, Polynomial.toLaurent_C_mul_T, + Int.toNat_of_nonneg hn] + · have hn' : n < 0 := lt_of_not_ge hn + let q : R[X] := Polynomial.monomial (-n).toNat (-a) + refine ⟨(0, q), ?_⟩ + simp [polynomialDifference, q, Polynomial.toLaurent_C_mul_T, + Int.toNat_of_nonneg (Int.neg_nonneg.mpr hn'.le), sub_eq_add_neg] + +/-- The image of the diagonal constants is exactly the kernel of the Laurent difference. -/ +theorem polynomial_exact : + Function.Exact (polynomialDiagonal R) (polynomialDifference R) := by + intro z + constructor + · intro hz + have heq : Polynomial.toLaurent z.1 = + LaurentPolynomial.invert (Polynomial.toLaurent z.2) := by + exact sub_eq_zero.mp hz + have hp : z.1 = Polynomial.C (z.1.coeff 0) := + eq_C_coeff_zero_of_toLaurent_eq_invert R heq + have heq' : Polynomial.toLaurent z.2 = + LaurentPolynomial.invert (Polynomial.toLaurent z.1) := by + calc + Polynomial.toLaurent z.2 = + LaurentPolynomial.invert (LaurentPolynomial.invert (Polynomial.toLaurent z.2)) := + (LaurentPolynomial.involutive_invert _).symm + _ = LaurentPolynomial.invert (Polynomial.toLaurent z.1) := + (congrArg LaurentPolynomial.invert heq).symm + have hq : z.2 = Polynomial.C (z.2.coeff 0) := + eq_C_coeff_zero_of_toLaurent_eq_invert R heq' + have hcoeff : z.1.coeff 0 = z.2.coeff 0 := by + have heqConstants := heq + rw [hp, hq] at heqConstants + have hzero := congrArg (fun w : R[T;T⁻¹] ↦ w.coeff 0) heqConstants + simpa using hzero + refine ⟨z.1.coeff 0, ?_⟩ + apply Prod.ext + · simpa [polynomialDiagonal] using hp.symm + · simpa [polynomialDiagonal, hcoeff] using hq.symm + · rintro ⟨a, rfl⟩ + simp [polynomialDiagonal, polynomialDifference] + +/-- The algebraic Laurent sequence is short exact. -/ +theorem polynomial_shortExact : + Function.Injective (polynomialDiagonal R) ∧ + Function.Exact (polynomialDiagonal R) (polynomialDifference R) ∧ + Function.Surjective (polynomialDifference R) := by + refine ⟨?_, polynomial_exact R, polynomialDifference_surjective R⟩ + intro a b h + have hfirst := congrArg Prod.fst h + simpa [polynomialDiagonal] using Polynomial.C_injective hfirst + +end LaurentCover + +end Rigid diff --git a/Rigid/AffinoidAlgebra/NoetherNormalization.lean b/Rigid/AffinoidAlgebra/NoetherNormalization.lean index b3d65d1..6dd4286 100644 --- a/Rigid/AffinoidAlgebra/NoetherNormalization.lean +++ b/Rigid/AffinoidAlgebra/NoetherNormalization.lean @@ -456,6 +456,37 @@ private theorem exists_tateShear_leadingDegree_eq_single_zero · simpa using hμdlt exact ⟨p, d, by simpa [F] using hleadF⟩ +/-- A polynomial triangular coordinate change makes every nonzero Tate series distinguished in +the first variable, expressed without exposing the implementation of the shear. -/ +theorem exists_algEquiv_leadingDegree_eq_single_zero + (f : TateAlgebra K (Fin (n + 1))) (hf : f ≠ 0) : + ∃ (ψ : TateAlgebra K (Fin (n + 1)) ≃ₐ[K] TateAlgebra K (Fin (n + 1))) (d : ℕ), + leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) (ψ f) = + Finsupp.single 0 d := by + classical + obtain ⟨p, d, hd⟩ := exists_tateShear_leadingDegree_eq_single_zero K f hf + have h1 : ‖(1 : K)‖ ≤ 1 := by simp + have hn1 : ‖(-1 : K)‖ ≤ 1 := by simp + have hnn1 : ‖-(-1 : K)‖ ≤ 1 := by simp + let ψ : TateAlgebra K (Fin (n + 1)) →ₐ[K] TateAlgebra K (Fin (n + 1)) := + (tateShear K p 1 h1).toAlgHom + let ψinv : TateAlgebra K (Fin (n + 1)) →ₐ[K] TateAlgebra K (Fin (n + 1)) := + (tateShear K p (-1) hn1).toAlgHom + have hright : ψ.comp ψinv = AlgHom.id K (TateAlgebra K (Fin (n + 1))) := by + apply DFunLike.ext _ _ + intro x + dsimp only [ψ, ψinv, AlgHom.comp_apply, AlgHom.id_apply] + exact tateShear_comp_neg K p 1 h1 hn1 x + have hleft : ψinv.comp ψ = AlgHom.id K (TateAlgebra K (Fin (n + 1))) := by + apply DFunLike.ext _ _ + intro x + dsimp only [ψ, ψinv, AlgHom.comp_apply, AlgHom.id_apply] + convert tateShear_comp_neg K p (-1) hn1 hnn1 x using 1 + all_goals simp + let e := AlgEquiv.ofAlgHom ψ ψinv hright hleft + refine ⟨e, d, ?_⟩ + exact hd + end CoordinateChange /-- Include the Tate algebra in variables `1, ..., n` into the one in variables `0, ..., n`. -/ @@ -504,6 +535,32 @@ private theorem succMap_tateVariable (n : ℕ) (i : Fin n) : (MvPowerSeries.X i.succ : MvPowerSeries (Fin (n + 1)) K) simp +/-- The remaining-variable inclusion preserves the Gauss norm. -/ +private theorem norm_succMap_eq (n : ℕ) (a : TateAlgebra K (Fin n)) : + ‖succMap K n a‖ = ‖a‖ := by + apply le_antisymm + · rw [norm_eq_sSup_coeff] + refine csSup_le (Set.range_nonempty _) ?_ + rintro _ ⟨μ, rfl⟩ + change ‖MvPowerSeries.coeff μ + (MvPowerSeries.rename (Fin.succEmb n) a.1)‖ ≤ ‖a‖ + by_cases hμ : μ ∈ Set.range (Finsupp.embDomain (Fin.succEmb n)) + · obtain ⟨ν, rfl⟩ := hμ + rw [MvPowerSeries.coeff_embDomain_rename] + exact norm_coeff_le_norm K (Fin n) a ν + · rw [MvPowerSeries.coeff_rename_eq_zero] + · exact norm_zero.trans_le (norm_nonneg a) + · rintro ⟨ν, hν⟩ + apply hμ + exact ⟨ν, by simpa [Finsupp.embDomain_eq_mapDomain] using hν⟩ + · rw [norm_eq_sSup_coeff] + refine csSup_le (Set.range_nonempty _) ?_ + rintro _ ⟨ν, rfl⟩ + change ‖MvPowerSeries.coeff ν a.1‖ ≤ ‖succMap K n a‖ + rw [← MvPowerSeries.coeff_embDomain_rename (Fin.succEmb n) a.1 ν] + exact norm_coeff_le_norm K (Fin (n + 1)) (succMap K n a) + (Finsupp.embDomain (Fin.succEmb n) ν) + /-- The coefficient series at a fixed exponent of the first variable. -/ private noncomputable def coeffSlice (n j : ℕ) (f : TateAlgebra K (Fin (n + 1))) : TateAlgebra K (Fin n) := @@ -675,8 +732,8 @@ private theorem finite_tateAlgebra_fin_zero : Module.Finite K (TateAlgebra K (Fi private theorem exists_finite_injective_tateAlgebra_of_surjective (n : ℕ) : ∀ {A : Type v} [CommRing A] [Algebra K A] [Nontrivial A] (π : TateAlgebra K (Fin n) →ₐ[K] A), Function.Surjective π → - ∃ (d : ℕ) (ι : TateAlgebra K (Fin d) →ₐ[K] A), - Function.Injective ι ∧ ι.Finite := by + ∃ (d : ℕ) (j : TateAlgebra K (Fin d) →ₐ[K] TateAlgebra K (Fin n)), + (∀ a, ‖j a‖ = ‖a‖) ∧ Function.Injective (π.comp j) ∧ (π.comp j).Finite := by induction n with | zero => intro A _ _ _ π hπ @@ -699,12 +756,15 @@ private theorem exists_finite_injective_tateAlgebra_of_surjective (n : ℕ) : _ = algebraMap K (TateAlgebra K (Fin 0)) (MvPowerSeries.coeff 0 g.1) := congrArg _ hcoeff _ = g := hscalar g - exact ⟨0, π, hπinj, AlgHom.Finite.of_surjective π hπ⟩ + refine ⟨0, AlgHom.id K _, fun _ ↦ rfl, ?_, ?_⟩ + · simpa using hπinj + · simpa using AlgHom.Finite.of_surjective π hπ | succ n ih => intro A _ _ _ π hπ by_cases hker : RingHom.ker π = ⊥ - · exact ⟨n + 1, π, (RingHom.injective_iff_ker_eq_bot π).mpr hker, - AlgHom.Finite.of_surjective π hπ⟩ + · refine ⟨n + 1, AlgHom.id K _, fun _ ↦ rfl, ?_, ?_⟩ + · simpa using (RingHom.injective_iff_ker_eq_bot π).mpr hker + · simpa using AlgHom.Finite.of_surjective π hπ · obtain ⟨g, hg, hg0⟩ := Submodule.exists_mem_ne_zero_of_ne_bot (p := RingHom.ker π) hker obtain ⟨p, d, hgd⟩ := exists_tateShear_leadingDegree_eq_single_zero K g hg0 @@ -747,9 +807,34 @@ private theorem exists_finite_injective_tateAlgebra_of_surjective (n : ℕ) : have hvalfinite : (Subalgebra.val C).Finite := by apply AlgHom.Finite.of_comp_finite (f := h.rangeRestrict) simpa [C] using hhfinite - obtain ⟨e, ι, hιinj, hιfinite⟩ := ih h.rangeRestrict h.rangeRestrict_surjective - refine ⟨e, (Subalgebra.val C).comp ι, Subtype.val_injective.comp hιinj, ?_⟩ - exact AlgHom.Finite.comp hvalfinite hιfinite + obtain ⟨e, j, hjnorm, hιinj, hιfinite⟩ := + ih h.rangeRestrict h.rangeRestrict_surjective + let j' : TateAlgebra K (Fin e) →ₐ[K] TateAlgebra K (Fin (n + 1)) := + ψinv.toAlgHom.comp ((succMap K n).comp j) + have hj'norm (a : TateAlgebra K (Fin e)) : ‖j' a‖ = ‖a‖ := by + change ‖ψinv (succMap K n (j a))‖ = ‖a‖ + rw [show ‖ψinv (succMap K n (j a))‖ = ‖succMap K n (j a)‖ by + exact norm_tateShear_eq K p (-1) (by simp) (by simp) _, + norm_succMap_eq K n, hjnorm] + have hcomp : + π.comp j' = (Subalgebra.val C).comp (h.rangeRestrict.comp j) := by + ext a + rfl + refine ⟨e, j', hj'norm, ?_, ?_⟩ + · rw [hcomp] + exact Subtype.val_injective.comp hιinj + · rw [hcomp] + exact AlgHom.Finite.comp hvalfinite hιfinite + +/-- A surjective Tate presentation contains an isometric Noether-normalizing Tate subalgebra. +Keeping the factorization through the source presentation is the coefficient-comparison input in +the minimal-prime proof of Proposition 4.5.3. -/ +theorem exists_isometric_normalizationFactor_of_surjective + {A : Type v} [CommRing A] [Algebra K A] [Nontrivial A] (n : ℕ) + (π : TateAlgebra K (Fin n) →ₐ[K] A) (hπ : Function.Surjective π) : + ∃ (d : ℕ) (j : TateAlgebra K (Fin d) →ₐ[K] TateAlgebra K (Fin n)), + (∀ a, ‖j a‖ = ‖a‖) ∧ Function.Injective (π.comp j) ∧ (π.comp j).Finite := + exists_finite_injective_tateAlgebra_of_surjective K n π hπ end Slices @@ -780,7 +865,9 @@ theorem exists_finite_injective_tateAlgebra_of_isAffinoidAlgebra [Nontrivial A] (hA : IsAffinoidAlgebra K A) : ∃ (d : ℕ) (ι : TateAlgebra K (Fin d) →ₐ[K] A), Function.Injective ι ∧ ι.Finite := by obtain ⟨n, π, hπ⟩ := exists_surjective_presentation_of_isAffinoidAlgebra K A hA - exact TateAlgebra.exists_finite_injective_tateAlgebra_of_surjective K n π hπ + obtain ⟨d, j, -, hinj, hfinite⟩ := + TateAlgebra.exists_isometric_normalizationFactor_of_surjective K n π hπ + exact ⟨d, π.comp j, hinj, hfinite⟩ /-- **Affinoid Nullstellensatz.** An affinoid algebra which is a field is a finite-dimensional algebra over the ground field. -/ diff --git a/Rigid/AffinoidAlgebra/RationalLocalization.lean b/Rigid/AffinoidAlgebra/RationalLocalization.lean index f072651..58fa417 100644 --- a/Rigid/AffinoidAlgebra/RationalLocalization.lean +++ b/Rigid/AffinoidAlgebra/RationalLocalization.lean @@ -34,6 +34,12 @@ noncomputable def rationalLocalizationIdeal (n : ℕ) (g : A) (f : Fin n → A) (Ideal.span (Set.range fun i ↦ TateAlgebra.C A (Fin n) g * tateVariable A (Fin n) i - TateAlgebra.C A (Fin n) (f i))).closure +noncomputable instance rationalLocalizationIdealIsClosed (n : ℕ) (g : A) (f : Fin n → A) : + IsClosed ((rationalLocalizationIdeal A n g f : Ideal (TateAlgebra A (Fin n))) : + Set (TateAlgebra A (Fin n))) := by + unfold rationalLocalizationIdeal + exact isClosed_closure + /-- The Banach algebra `A⟨T₁, ..., Tₙ⟩ / (gTᵢ - fᵢ)`. -/ abbrev RationalLocalization (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] @@ -41,24 +47,28 @@ abbrev RationalLocalization [IsUltrametricDist A] (n : ℕ) (g : A) (f : Fin n → A) : Type v := TateAlgebra A (Fin n) ⧸ rationalLocalizationIdeal A n g f -noncomputable instance rationalLocalizationNormedCommRing (n : ℕ) (g : A) (f : Fin n → A) : +@[reducible] noncomputable instance (priority := 100) rationalLocalizationNormedCommRing + (n : ℕ) (g : A) (f : Fin n → A) : NormedCommRing (RationalLocalization K A n g f) := by letI : IsClosed ((rationalLocalizationIdeal A n g f : Ideal (TateAlgebra A (Fin n))) : Set (TateAlgebra A (Fin n))) := isClosed_closure dsimp only [RationalLocalization] infer_instance -noncomputable instance rationalLocalizationAlgebra (n : ℕ) (g : A) (f : Fin n → A) : +@[reducible] noncomputable instance (priority := 100) rationalLocalizationAlgebra + (n : ℕ) (g : A) (f : Fin n → A) : Algebra A (RationalLocalization K A n g f) := by dsimp only [RationalLocalization] infer_instance -noncomputable instance rationalLocalizationNormedAlgebra (n : ℕ) (g : A) (f : Fin n → A) : +@[reducible] noncomputable instance (priority := 100) rationalLocalizationNormedAlgebra + (n : ℕ) (g : A) (f : Fin n → A) : NormedAlgebra K (RationalLocalization K A n g f) := by dsimp only [RationalLocalization] infer_instance -noncomputable instance rationalLocalizationCompleteSpace (n : ℕ) (g : A) (f : Fin n → A) : +noncomputable instance (priority := 100) rationalLocalizationCompleteSpace + (n : ℕ) (g : A) (f : Fin n → A) : CompleteSpace (RationalLocalization K A n g f) := by dsimp only [RationalLocalization] infer_instance @@ -84,8 +94,12 @@ noncomputable instance rationalLocalizationIsUltrametricDist noncomputable instance rationalLocalizationIsScalarTower (n : ℕ) (g : A) (f : Fin n → A) : - IsScalarTower K A (RationalLocalization K A n g f) := - IsScalarTower.of_algebraMap_eq fun _ ↦ rfl + IsScalarTower K A (RationalLocalization K A n g f) := by + constructor + intro x y z + induction z using Quotient.inductionOn' + exact congrArg (Ideal.Quotient.mk (rationalLocalizationIdeal A n g f)) + (smul_assoc x y _) namespace RationalLocalization diff --git a/Rigid/AffinoidAlgebra/SpectralComponents.lean b/Rigid/AffinoidAlgebra/SpectralComponents.lean new file mode 100644 index 0000000..091ef89 --- /dev/null +++ b/Rigid/AffinoidAlgebra/SpectralComponents.lean @@ -0,0 +1,51 @@ +import Rigid.AffinoidAlgebra.ClosedIdeals +import Rigid.Berkovich.Quotient +import Rigid.Berkovich.SpectralRadius + +set_option linter.style.header false + +/-! +# Spectral radii on minimal-prime components + +The spectral radius of an element of an affinoid algebra is attained on one of its +minimal-prime quotients. This is the elementwise form of Mattias, Proposition 4.5.1: the map to +the product of the irreducible components is an isometry for the spectral seminorm. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] [Nontrivial A] + +/-- For every element, some minimal-prime quotient preserves its spectral radius. -/ +theorem exists_minimalPrime_spectralRadius_eq_quotient + (hA : IsAffinoidAlgebra K A) + (htop : (inferInstance : TopologicalSpace A) = affinoidTopology K A hA) + (a : A) : + ∃ q ∈ minimalPrimes A, + letI : IsClosed (q : Set A) := + isClosed_ideal_of_topology_eq_affinoidTopology K A hA htop q + BerkovichSpectrum.spectralRadius (A ⧸ q) (Ideal.Quotient.mk q a) = + BerkovichSpectrum.spectralRadius A a := by + obtain ⟨x, hx⟩ := + BerkovichSpectrumOver.exists_apply_eq_spectralRadius K A a + letI : x.kernel.IsPrime := x.kernel_isPrime + obtain ⟨q, hq, hqx⟩ := + Ideal.exists_minimalPrimes_le (I := (⊥ : Ideal A)) (J := x.kernel) bot_le + refine ⟨q, hq, ?_⟩ + letI : IsClosed (q : Set A) := + isClosed_ideal_of_topology_eq_affinoidTopology K A hA htop q + letI : q.IsPrime := hq.isPrime + let y : BerkovichSpectrumOver K (A ⧸ q) := + BerkovichSpectrumOver.descendQuotient K A x q hqx + apply le_antisymm + · exact BerkovichSpectrumOver.spectralRadius_map_le K A + (idealQuotientMk K q) a + · rw [← hx] + exact BerkovichSpectrumOver.le_spectralRadius K (A ⧸ q) y + (Ideal.Quotient.mk q a) + +end Rigid diff --git a/Rigid/AffinoidAlgebra/SpectralCriterion.lean b/Rigid/AffinoidAlgebra/SpectralCriterion.lean new file mode 100644 index 0000000..1f51ce1 --- /dev/null +++ b/Rigid/AffinoidAlgebra/SpectralCriterion.lean @@ -0,0 +1,31 @@ +import Rigid.AffinoidAlgebra.SpectralPolynomial +import Rigid.AffinoidAlgebra.TateRealization + +set_option linter.style.header false + +/-! +# The spectral power-boundedness criterion for affinoid domains + +This file joins the algebraic/spectral argument of Proposition 4.5.3 with automatic continuity. +The only topological hypothesis is the standard identification of the chosen Banach topology with +the canonical affinoid quotient topology. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +/-- Proposition 4.5.12 for an affinoid domain in a Banach realization carrying its canonical +topology. -/ +theorem hasPowerBoundedSpectralCriterion_of_affinoidDomain + [IsDomain A] (hA : IsAffinoidAlgebra K A) + (htop : (inferInstance : TopologicalSpace A) = affinoidTopology K A hA) : + HasPowerBoundedSpectralCriterion A := + SpectralPolynomial.hasPowerBoundedSpectralCriterion_of_isAffinoidAlgebra_of_isDomain K hA + fun π ↦ continuous_tateAlgebra_to_affinoid K hA htop π + +end Rigid diff --git a/Rigid/AffinoidAlgebra/SpectralPolynomial.lean b/Rigid/AffinoidAlgebra/SpectralPolynomial.lean new file mode 100644 index 0000000..4eb9eb3 --- /dev/null +++ b/Rigid/AffinoidAlgebra/SpectralPolynomial.lean @@ -0,0 +1,924 @@ +import Mathlib.Analysis.Normed.Unbundled.SpectralNorm +import Mathlib.FieldTheory.Minpoly.IsIntegrallyClosed +import Mathlib.RingTheory.Ideal.MinimalPrime.Noetherian +import Mathlib.RingTheory.Polynomial.Subring +import Rigid.AffinoidAlgebra.FiniteModuleBounded +import Rigid.AffinoidAlgebra.NoetherNormalization +import Rigid.AffinoidAlgebra.SpectralRadius +import Rigid.Berkovich.CompletedResidue +import Rigid.TateAlgebra.Complete +import Rigid.TateAlgebra.Domain +import Rigid.TateAlgebra.UniqueFactorization + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# Spectral polynomial relations + +This file isolates the algebraic part of Proposition 4.5.3 of the cited draft. A monic +polynomial relation whose coefficients belong to a fixed subring is stable under products and +powers. Consequently, relations obtained after quotienting by every minimal prime of a +Noetherian ring combine to a relation in the original ring: their product vanishes modulo every +minimal prime, hence is nilpotent, and a power of that product vanishes. + +For a Tate-algebra base, a relation with coefficients in the Gauss unit ball is exactly the +integrality certificate needed in the power-boundedness argument. Thus the remaining analytic +content of Proposition 4.5.3 is cleanly reduced to the domain case. +-/ + +open Filter +open scoped BigOperators Polynomial Topology + +universe u v + +namespace Rigid + +namespace SpectralPolynomial + +variable {R : Type u} {B : Type v} + +section MinimalPolynomial + +variable [CommRing R] [CommRing B] [IsDomain R] [IsIntegrallyClosed R] [IsDomain B] +variable [Algebra R B] [Module.IsTorsionFree R B] + +/-- Lemma 4.5.5, in the slightly more general integrally-closed form already supported by +Mathlib: an integral element in a domain has a unique monic annihilating polynomial of minimal +degree. -/ +theorem existsUnique_monic_minimalPolynomial (b : B) (hb : IsIntegral R b) : + ∃! P : R[X], P.Monic ∧ Polynomial.aeval b P = 0 ∧ + ∀ Q : R[X], Q.Monic → Polynomial.aeval b Q = 0 → P.degree ≤ Q.degree := by + refine ⟨minpoly R b, ⟨minpoly.monic hb, minpoly.aeval R b, ?_⟩, ?_⟩ + · intro Q hQmonic hQeval + exact minpoly.min R b hQmonic hQeval + · intro P hP + exact IsIntegrallyClosed.minpoly.unique hP.1 hP.2.1 hP.2.2 + +/-- The quotient by the minimal polynomial is the subalgebra generated by the element, the +second assertion of Lemma 4.5.5. `AdjoinRoot P` is `R[X] / (P)`. -/ +noncomputable def minimalPolynomialQuotientEquivAdjoin (b : B) (hb : IsIntegral R b) : + AdjoinRoot (minpoly R b) ≃ₐ[R] Algebra.adjoin R ({b} : Set B) := + minpoly.equivAdjoin hb + +end MinimalPolynomial + +/-- Every coefficient of `P` belongs to the subring `S`. -/ +def CoefficientsIn [Ring R] (S : Subring R) (P : R[X]) : Prop := + ∀ i : ℕ, P.coeff i ∈ S + +namespace CoefficientsIn + +variable [CommRing R] {S : Subring R} {P Q : R[X]} + +theorem one : CoefficientsIn S (1 : R[X]) := by + intro i + simp only [Polynomial.coeff_one] + split_ifs <;> simp + +theorem mul (hP : CoefficientsIn S P) (hQ : CoefficientsIn S Q) : + CoefficientsIn S (P * Q) := by + intro n + rw [Polynomial.coeff_mul] + exact Subring.sum_mem S fun i _ ↦ S.mul_mem (hP i.1) (hQ i.2) + +theorem pow (hP : CoefficientsIn S P) (n : ℕ) : CoefficientsIn S (P ^ n) := by + induction n with + | zero => simpa using (one (S := S)) + | succ n ih => simpa [pow_succ] using ih.mul hP + +theorem prod {ι : Type*} {s : Finset ι} {P : ι → R[X]} + (hP : ∀ i ∈ s, CoefficientsIn S (P i)) : + CoefficientsIn S (∏ i ∈ s, P i) := by + classical + induction s using Finset.induction_on with + | empty => simpa using (one (S := S)) + | @insert a s ha ih => + simp only [Finset.prod_insert, ha, not_false_eq_true] + exact (hP a (Finset.mem_insert_self a s)).mul + (ih fun i hi ↦ hP i (Finset.mem_insert_of_mem hi)) + +end CoefficientsIn + +/-- A monic polynomial over `R`, with coefficients in `S`, that annihilates `b` through `f`. -/ +def HasMonicRelation [CommRing R] [CommRing B] (S : Subring R) (f : R →+* B) + (b : B) : Prop := + ∃ P : R[X], P.Monic ∧ CoefficientsIn S P ∧ Polynomial.eval₂ f b P = 0 + +/-- A monic relation with coefficients in `S` makes the element integral over the image of `S`. -/ +theorem isIntegral_image_of_hasMonicRelation [CommRing R] [CommRing B] + (S : Subring R) (f : R →+* B) (b : B) (h : HasMonicRelation S f b) : + IsIntegral (S.map f) b := by + classical + obtain ⟨P, hPmonic, hPcoeff, hPeval⟩ := h + let T : Subring B := S.map f + have hcoeffs : ((P.map f).coeffs : Set B) ⊆ T := by + intro c hc + have hc' : c ∈ (P.map f).coeffs := hc + obtain ⟨i, hi, rfl⟩ := Polynomial.mem_coeffs_iff.mp hc' + rw [Polynomial.coeff_map] + exact ⟨P.coeff i, hPcoeff i, rfl⟩ + let Q : T[X] := (P.map f).toSubring T hcoeffs + refine ⟨Q, ?_, ?_⟩ + · exact (Polynomial.monic_toSubring (P.map f) T hcoeffs).mpr (hPmonic.map f) + · change Polynomial.eval₂ (Subring.subtype T) b Q = 0 + rw [← Polynomial.eval_map, Polynomial.map_toSubring] + simpa only [Polynomial.eval_map] using hPeval + +/-- The algebraic reduction in Proposition 4.5.3 from a Noetherian ring to its domain +quotients. Relations modulo the minimal primes are multiplied; the resulting value lies in the +nilradical, so a positive power of the product is an actual relation. -/ +theorem hasMonicRelation_of_minimalPrime_quotients [CommRing R] [CommRing B] + [Nontrivial B] [IsNoetherianRing B] (S : Subring R) (f : R →+* B) (b : B) + (h : ∀ q ∈ minimalPrimes B, + HasMonicRelation S ((Ideal.Quotient.mk q).comp f) (Ideal.Quotient.mk q b)) : + HasMonicRelation S f b := by + classical + let MinPrime := {q : Ideal B // q ∈ minimalPrimes B} + letI : Fintype MinPrime := + (minimalPrimes.finite_of_isNoetherianRing B).fintype + let P : MinPrime → R[X] := fun q ↦ Classical.choose (h q.1 q.2) + have hP (q : MinPrime) : + (P q).Monic ∧ CoefficientsIn S (P q) ∧ + Polynomial.eval₂ ((Ideal.Quotient.mk q.1).comp f) + (Ideal.Quotient.mk q.1 b) (P q) = 0 := + Classical.choose_spec (h q.1 q.2) + let Q : R[X] := ∏ q : MinPrime, P q + have hQmonic : Q.Monic := by + dsimp only [Q] + exact Polynomial.monic_prod_of_monic Finset.univ P fun q _ ↦ (hP q).1 + have hQcoeff : CoefficientsIn S Q := by + dsimp only [Q] + exact CoefficientsIn.prod fun q _ ↦ (hP q).2.1 + have hQeval_mem (q : Ideal B) (hq : q ∈ minimalPrimes B) : + Polynomial.eval₂ f b Q ∈ q := by + rw [← Ideal.Quotient.eq_zero_iff_mem] + rw [Polynomial.hom_eval₂] + dsimp only [Q] + rw [Polynomial.eval₂_finsetProd] + exact Finset.prod_eq_zero (Finset.mem_univ (⟨q, hq⟩ : MinPrime)) + (hP (⟨q, hq⟩ : MinPrime)).2.2 + have hQeval_sInf : Polynomial.eval₂ f b Q ∈ sInf (minimalPrimes B) := by + rw [Ideal.mem_sInf] + exact hQeval_mem + have hQeval_radical : Polynomial.eval₂ f b Q ∈ (⊥ : Ideal B).radical := by + simpa only [Ideal.sInf_minimalPrimes] using hQeval_sInf + have hnil : IsNilpotent (Polynomial.eval₂ f b Q) := + (mem_nilradical (R := B)).mp hQeval_radical + obtain ⟨e, he⟩ := hnil + refine ⟨Q ^ e, hQmonic.pow e, hQcoeff.pow e, ?_⟩ + rw [Polynomial.eval₂_pow] + exact he + +section Normed + +variable [NormedRing R] [NormOneClass R] [Nontrivial R] + +/-- The coefficient bound direction of `Polynomial.spectralValue_le_one_iff` needs no division +in the coefficient ring. -/ +theorem norm_coeff_le_one_of_spectralValue_le_one {P : R[X]} (hP : P.Monic) + (hsp : spectralValue P ≤ 1) (n : ℕ) : ‖P.coeff n‖ ≤ 1 := by + obtain hn | hn | hn := lt_trichotomy P.natDegree n + · simp [Polynomial.coeff_eq_zero_of_natDegree_lt hn] + · rw [← hn, hP.coeff_natDegree, norm_one] + · have hterm : spectralValueTerms P n ≤ 1 := + (le_ciSup (spectralValueTerms_bddAbove P) n).trans hsp + contrapose! hterm + rw [spectralValueTerms_of_lt_natDegree P hn] + exact Real.one_lt_rpow hterm (by simp [hn]) + +variable {D : Type v} [NormedRing D] [Nontrivial D] + +/-- Spectral value does not increase when the coefficients are mapped by a norm-nonincreasing +ring homomorphism. -/ +theorem spectralValue_map_le (f : R →+* D) (hf : ∀ r, ‖f r‖ ≤ ‖r‖) + {P : R[X]} (hP : P.Monic) : spectralValue (P.map f) ≤ spectralValue P := by + rw [spectralValue] + apply ciSup_le + intro n + calc + spectralValueTerms (P.map f) n ≤ spectralValueTerms P n := by + have hdeg : (P.map f).natDegree = P.natDegree := hP.natDegree_map f + simp only [spectralValueTerms, hdeg, Polynomial.coeff_map] + split_ifs with hn + · have hexp : 0 ≤ 1 / (P.natDegree - n : ℝ) := by + rw [one_div_nonneg, sub_nonneg, Nat.cast_le] + exact hn.le + exact Real.rpow_le_rpow (norm_nonneg _) (hf (P.coeff n)) hexp + · exact le_rfl + _ ≤ ⨆ n, spectralValueTerms P n := + le_ciSup (spectralValueTerms_bddAbove P) n + +/-- An isometric coefficient map preserves spectral value. -/ +theorem spectralValue_map_eq (f : R →+* D) (hf : ∀ r, ‖f r‖ = ‖r‖) + {P : R[X]} (hP : P.Monic) : spectralValue (P.map f) = spectralValue P := by + apply iSup_congr + intro n + have hdeg : (P.map f).natDegree = P.natDegree := hP.natDegree_map f + simp only [spectralValueTerms, hdeg, Polynomial.coeff_map, hf] + +end Normed + +section BoundedPowerRealization + +variable {E : Type u} [NormedCommRing E] +variable {L : Type v} [NormedDivisionRing L] + +/-- A bounded function that realizes all powers of `c` as powers of `z` bounds the norm of `z` +by the spectral radius of `c`. No additivity or multiplicativity of the function away from those +powers is needed. This is the asymptotic estimate used after extending the root evaluation to a +linear functional on a finite algebra. -/ +theorem norm_le_spectralRadius_of_bounded_power_realization [Nontrivial E] + (c : E) (z : L) (F : E → L) (M : ℝ) (hM : 0 < M) + (hFpow : ∀ m : ℕ, F (c ^ m) = z ^ m) + (hF : ∀ a : E, ‖F a‖ ≤ M * ‖a‖) : + ‖z‖ ≤ BerkovichSpectrum.spectralRadius E c := by + let μ : RingSeminorm E := BerkovichSpectrum.normalizedNormSeminorm E + let D : ℝ := M * ‖(1 : E)‖ + have hD : 0 < D := mul_pos hM (norm_pos_iff.mpr one_ne_zero) + have hrootD : Tendsto (fun n : ℕ ↦ D ^ (1 / (n : ℝ))) atTop (𝓝 1) := by + convert tendsto_const_nhds.rpow tendsto_one_div_atTop_nhds_zero_nat + (Or.inl hD.ne') using 1 + rw [Real.rpow_zero] + have hlim : Tendsto (fun n : ℕ ↦ + smoothingSeminormSeq μ c n * D ^ (1 / (n : ℝ))) atTop + (𝓝 (BerkovichSpectrum.spectralRadius E c)) := by + simpa only [μ, mul_one] using (BerkovichSpectrum.tendsto_spectralRadius E c).mul hrootD + apply ge_of_tendsto hlim + filter_upwards [eventually_ge_atTop 1] with m hm + have hm0 : (m : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr (Nat.one_le_iff_ne_zero.mp hm) + have hexp : 0 < 1 / (m : ℝ) := one_div_pos.mpr (Nat.cast_pos.mpr (by omega)) + calc + ‖z‖ = (‖z‖ ^ m) ^ (1 / (m : ℝ)) := by + rw [← Real.rpow_natCast, ← Real.rpow_mul (norm_nonneg z), + mul_one_div_cancel hm0, Real.rpow_one] + _ = ‖z ^ m‖ ^ (1 / (m : ℝ)) := by rw [norm_pow] + _ = ‖F (c ^ m)‖ ^ (1 / (m : ℝ)) := by rw [hFpow] + _ ≤ (M * ‖c ^ m‖) ^ (1 / (m : ℝ)) := + Real.rpow_le_rpow (norm_nonneg _) (hF _) hexp.le + _ ≤ (D * μ (c ^ m)) ^ (1 / (m : ℝ)) := by + apply Real.rpow_le_rpow (mul_nonneg hM.le (norm_nonneg _)) _ hexp.le + calc + M * ‖c ^ m‖ ≤ M * (‖(1 : E)‖ * μ (c ^ m)) := + mul_le_mul_of_nonneg_left + (BerkovichSpectrum.norm_le_norm_one_mul_normalizedNormSeminorm E (c ^ m)) hM.le + _ = D * μ (c ^ m) := by simp only [D, mul_assoc] + _ = smoothingSeminormSeq μ c m * D ^ (1 / (m : ℝ)) := by + rw [Real.mul_rpow hD.le (apply_nonneg μ _), mul_comm] + +end BoundedPowerRealization + +section FiniteModulePowerRealization + +variable {k : Type u} [NontriviallyNormedField k] +variable {R : Type v} [NormedCommRing R] [NormedAlgebra k R] [CompleteSpace R] +variable {E : Type w} [NormedCommRing E] [NormedAlgebra k E] [CompleteSpace E] [Nontrivial E] +variable {L : Type*} [NormedDivisionRing L] [NormedSpace k L] +variable [Module R E] [Module R L] [IsScalarTower k R E] [IsScalarTower k R L] +variable [ContinuousSMul R E] [ContinuousSMul R L] [Module.Finite R E] + +include k in +/-- Once the root evaluation has been extended to an `R`-linear map on the finite algebra, its +boundedness and the lower spectral-radius inequality are automatic. -/ +theorem norm_le_spectralRadius_of_finiteModule_power_realization + (c : E) (z : L) (F : E →ₗ[R] L) (hFpow : ∀ m : ℕ, F (c ^ m) = z ^ m) : + ‖z‖ ≤ BerkovichSpectrum.spectralRadius E c := by + obtain ⟨M, hM, hF⟩ := + Rigid.LinearMap.exists_bound_of_module_finite (K := k) F + exact norm_le_spectralRadius_of_bounded_power_realization c z F M hM hFpow hF + +end FiniteModulePowerRealization + +section Tate + +variable (K : Type u) [NontriviallyNormedField K] [IsUltrametricDist K] + +section Algebraic + +variable {C : Type v} [CommRing C] + +/-- A polynomial relation over a Tate algebra whose coefficients lie in its Gauss unit ball. -/ +def HasUnitBallRelation (n : ℕ) (f : TateAlgebra K (Fin n) →+* C) (c : C) : Prop := + HasMonicRelation (TateAlgebra.unitBallSubring K n) f c + +/-- A unit-ball polynomial relation is the corresponding integrality certificate. -/ +theorem isIntegral_image_unitBall_of_hasUnitBallRelation (n : ℕ) + (f : TateAlgebra K (Fin n) →+* C) (c : C) (h : HasUnitBallRelation K n f c) : + IsIntegral ((TateAlgebra.unitBallSubring K n).map f) c := + isIntegral_image_of_hasMonicRelation _ _ _ h + +/-- The minimal-prime reduction of Proposition 4.5.3 in its unit-ball form. It is enough to +construct a unit-ball relation after quotienting by every minimal prime; multiplying those +relations and taking a power removes the nilpotent error. -/ +theorem hasUnitBallRelation_of_minimalPrime_quotients [Nontrivial C] [IsNoetherianRing C] + (n : ℕ) (f : TateAlgebra K (Fin n) →+* C) (c : C) + (h : ∀ q ∈ minimalPrimes C, + HasUnitBallRelation K n ((Ideal.Quotient.mk q).comp f) (Ideal.Quotient.mk q c)) : + HasUnitBallRelation K n f c := + hasMonicRelation_of_minimalPrime_quotients _ _ _ h + +end Algebraic + +variable [CompleteSpace K] +variable {C : Type v} +variable [NormedCommRing C] [NormedAlgebra K C] [CompleteSpace C] [IsUltrametricDist C] + +/-- Componentwise unit-ball relations over one continuous Tate-algebra map combine into the +integral certificate used by Proposition 4.5.12. -/ +theorem hasUnitBallIntegralCertificate_of_minimalPrime_quotients + [Nontrivial C] [IsNoetherianRing C] {n : ℕ} + (π : ContinuousAlgHom K (TateAlgebra K (Fin n)) C) (c : C) + (h : ∀ q ∈ minimalPrimes C, + HasUnitBallRelation K n ((Ideal.Quotient.mk q).comp π.toRingHom) + (Ideal.Quotient.mk q c)) : + HasUnitBallIntegralCertificate K c := + ⟨n, π, isIntegral_image_unitBall_of_hasUnitBallRelation K n π.toRingHom c + (hasUnitBallRelation_of_minimalPrime_quotients K n π.toRingHom c h)⟩ + +/-- The completed residue field of the Gauss point of a finite Tate algebra. -/ +abbrev GaussResidueField (n : ℕ) := + BerkovichSpectrumOver.CompletedResidueField (TateAlgebra.gaussPoint K n) + +/-- An algebraic closure of the completed Gauss residue field. -/ +abbrev GaussAlgebraicClosure (n : ℕ) := AlgebraicClosure (GaussResidueField K n) + +/-- Evaluation of Tate-algebra coefficients in an algebraic closure of the completed Gauss +residue field. -/ +noncomputable def gaussAlgebraicClosureMap (n : ℕ) : + TateAlgebra K (Fin n) →+* GaussAlgebraicClosure K n := + (algebraMap (GaussResidueField K n) (GaussAlgebraicClosure K n)).comp + (BerkovichSpectrumOver.completedResidueMap (TateAlgebra.gaussPoint K n)) + +@[simp] +theorem spectralNorm_gaussAlgebraicClosureMap (n : ℕ) (a : TateAlgebra K (Fin n)) : + spectralNorm (GaussResidueField K n) (GaussAlgebraicClosure K n) + (gaussAlgebraicClosureMap K n a) = ‖a‖ := by + rw [gaussAlgebraicClosureMap, RingHom.comp_apply, spectralNorm_extends, + BerkovichSpectrumOver.norm_completedResidueMap, TateAlgebra.gaussPoint_apply] + +/-- Evaluation in the completed Gauss residue field, and hence in its algebraic closure, is +injective. -/ +theorem gaussAlgebraicClosureMap_injective (n : ℕ) : + Function.Injective (gaussAlgebraicClosureMap K n) := by + rw [injective_iff_map_eq_zero] + intro a ha + apply norm_eq_zero.mp + rw [← spectralNorm_gaussAlgebraicClosureMap K n a, ha, spectralNorm_zero] + +/-- A monic polynomial annihilating an element of a nontrivial algebra has positive degree. -/ +theorem natDegree_pos_of_monic_relation [Nontrivial C] {n : ℕ} + (π : TateAlgebra K (Fin n) →+* C) (c : C) + {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) + (hPeval : Polynomial.eval₂ π c P = 0) : 0 < P.natDegree := by + have hroot : Polynomial.aeval c (P.map π) = 0 := by + simpa only [Polynomial.aeval_def, Polynomial.eval₂_map, Algebra.algebraMap_self, + RingHom.id_comp] using hPeval + have hdeg := Polynomial.natDegree_pos_of_monic_of_aeval_eq_zero (hP.map π) hroot + rwa [hP.natDegree_map] at hdeg + +/-- The root-theoretic part of Lemma 4.5.11 and Proposition 4.5.7. A positive-degree monic +polynomial over a Tate algebra has a root over the completed Gauss residue field whose extended +norm is exactly its spectral value. This is the existing nonarchimedean norm-extension theorem +from Mathlib, together with the isometry of evaluation at the Gauss point. -/ +theorem exists_gaussRoot_spectralNorm_eq_spectralValue {n : ℕ} + {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) : + ∃ z : GaussAlgebraicClosure K n, + Polynomial.aeval z (P.map (gaussAlgebraicClosureMap K n)) = 0 ∧ + spectralNorm (GaussResidueField K n) (GaussAlgebraicClosure K n) z = spectralValue P := by + classical + let H := GaussResidueField K n + let L := GaussAlgebraicClosure K n + let ψ : TateAlgebra K (Fin n) →+* H := + BerkovichSpectrumOver.completedResidueMap (TateAlgebra.gaussPoint K n) + let P_H : H[X] := P.map ψ + have hP_H : P_H.Monic := hP.map ψ + have hsplit : (P_H.map (algebraMap H L)).Splits := IsAlgClosed.splits _ + obtain ⟨s, hs⟩ := Polynomial.splits_iff_exists_multiset.mp hsplit + have hlc : algebraMap H L P_H.leadingCoeff = 1 := by + rw [hP_H.leadingCoeff, map_one] + rw [Polynomial.leadingCoeff_map, hlc, Polynomial.C_1, one_mul] at hs + have hcard : s.card = P.natDegree := by + rw [← Polynomial.natDegree_multiset_prod_X_sub_C_eq_card, ← hs, + hP_H.natDegree_map, hP.natDegree_map] + have hsne : s ≠ 0 := by + intro hs0 + rw [hs0, Multiset.card_zero] at hcard + omega + letI : NormedField L := spectralNorm.normedField H L + letI : NormedAlgebra H L := spectralNorm.normedAlgebra H L + letI : IsUltrametricDist L := + IsUltrametricDist.isUltrametricDist_of_isNonarchimedean_norm fun a b ↦ + isNonarchimedean_spectralNorm a b + obtain ⟨z, hzs, hzmax⟩ := Multiset.exists_max_image norm hsne + refine ⟨z, ?_, ?_⟩ + · have hzroot : Polynomial.aeval z P_H = 0 := + Polynomial.aeval_root_of_mapAlg_eq_multiset_prod_X_sub_C (R := H) s hzs (by + simpa only [Polynomial.mapAlg_eq_map] using hs) + simpa only [Polynomial.aeval_def, P_H, ψ, gaussAlgebraicClosureMap, + Polynomial.eval₂_map, RingHom.comp_assoc, Algebra.algebraMap_self, + RingHom.id_comp] using hzroot + · have hmax : (⨆ x : L, if x ∈ s then ‖x‖ else 0) = ‖z‖ := by + have hbdd : BddAbove (Set.range fun x : L ↦ if x ∈ s then ‖x‖ else 0) := by + refine ⟨‖z‖, ?_⟩ + rintro _ ⟨x, rfl⟩ + change (if x ∈ s then ‖x‖ else 0) ≤ ‖z‖ + split_ifs with hx + · exact hzmax x hx + · exact norm_nonneg z + apply le_antisymm + · apply ciSup_le + intro x + change (if x ∈ s then ‖x‖ else 0) ≤ ‖z‖ + split_ifs with hx + · exact hzmax x hx + · exact norm_nonneg z + · simpa only [if_pos hzs] using (le_ciSup hbdd z) + let ν : AlgebraNorm H L := (NormedAlgebra.toMulAlgebraNorm H L).toAlgebraNorm + have hνpow : IsPowMul ν := by + intro a m _ + change ‖a ^ m‖ = ‖a‖ ^ m + exact norm_pow a m + have hνna : IsNonarchimedean ν := by + intro a b + change ‖a + b‖ ≤ max ‖a‖ ‖b‖ + exact IsUltrametricDist.norm_add_le_max a b + have hνone : ν 1 = 1 := by + change ‖(1 : L)‖ = 1 + exact norm_one + have hspectral : (⨆ x : L, if x ∈ s then ‖x‖ else 0) = spectralValue P_H := by + simpa only [ν, MulAlgebraNorm.coe_AlgebraNorm, + NormedAlgebra.toMulAlgebraNorm_apply] using + (max_norm_root_eq_spectralValue hνpow hνna hνone P_H s hs) + have hψ (a : TateAlgebra K (Fin n)) : ‖ψ a‖ = ‖a‖ := by + change ‖BerkovichSpectrumOver.completedResidueMap (TateAlgebra.gaussPoint K n) a‖ = ‖a‖ + rw [BerkovichSpectrumOver.norm_completedResidueMap, + TateAlgebra.gaussPoint_apply] + calc + spectralNorm H L z = ‖z‖ := rfl + _ = ⨆ x : L, if x ∈ s then ‖x‖ else 0 := hmax.symm + _ = spectralValue P_H := hspectral + _ = spectralValue P := spectralValue_map_eq ψ hψ hP + +/-- A chosen root of maximal norm over the completed Gauss residue field. -/ +noncomputable def gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} + (hP : P.Monic) (hPdeg : 0 < P.natDegree) : GaussAlgebraicClosure K n := + Classical.choose (exists_gaussRoot_spectralNorm_eq_spectralValue K hP hPdeg) + +@[simp] +theorem aeval_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} + (hP : P.Monic) (hPdeg : 0 < P.natDegree) : + Polynomial.aeval (gaussMaxRoot K hP hPdeg) + (P.map (gaussAlgebraicClosureMap K n)) = 0 := + (Classical.choose_spec (exists_gaussRoot_spectralNorm_eq_spectralValue K hP hPdeg)).1 + +@[simp] +theorem eval₂_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} + (hP : P.Monic) (hPdeg : 0 < P.natDegree) : + Polynomial.eval₂ (gaussAlgebraicClosureMap K n) (gaussMaxRoot K hP hPdeg) P = 0 := by + simpa only [Polynomial.aeval_def, Polynomial.eval₂_map, Algebra.algebraMap_self, + RingHom.id_comp] using aeval_gaussMaxRoot K hP hPdeg + +@[simp] +theorem spectralNorm_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} + (hP : P.Monic) (hPdeg : 0 < P.natDegree) : + spectralNorm (GaussResidueField K n) (GaussAlgebraicClosure K n) + (gaussMaxRoot K hP hPdeg) = spectralValue P := + (Classical.choose_spec (exists_gaussRoot_spectralNorm_eq_spectralValue K hP hPdeg)).2 + +/-- Evaluation at a Gauss-fiber root, as a homomorphism out of the polynomial quotient. -/ +noncomputable def gaussRootLift {n : ℕ} (P : (TateAlgebra K (Fin n))[X]) + (z : GaussAlgebraicClosure K n) + (hz : Polynomial.aeval z (P.map (gaussAlgebraicClosureMap K n)) = 0) : + AdjoinRoot P →+* GaussAlgebraicClosure K n := + AdjoinRoot.lift (gaussAlgebraicClosureMap K n) z (by + simpa only [Polynomial.aeval_def, Polynomial.eval₂_map, Algebra.algebraMap_self, + RingHom.id_comp] using hz) + +@[simp] +theorem gaussRootLift_root {n : ℕ} (P : (TateAlgebra K (Fin n))[X]) + (z : GaussAlgebraicClosure K n) + (hz : Polynomial.aeval z (P.map (gaussAlgebraicClosureMap K n)) = 0) : + gaussRootLift K P z hz (AdjoinRoot.root P) = z := + AdjoinRoot.lift_root _ + +/-- The precise finite-module functional needed after the Gauss root has been constructed. The +function need only be bounded and carry the powers of `c` to the powers of the chosen root; in the +domain proof it is obtained by extending root evaluation linearly over the fraction field. -/ +def HasBoundedGaussRootRealization (n : ℕ) (c : C) + (P : (TateAlgebra K (Fin n))[X]) : Prop := + ∃ z : GaussAlgebraicClosure K n, + Polynomial.aeval z (P.map (gaussAlgebraicClosureMap K n)) = 0 ∧ + spectralNorm (GaussResidueField K n) (GaussAlgebraicClosure K n) z = spectralValue P ∧ + ∃ (F : C → GaussAlgebraicClosure K n) (M : ℝ), 0 < M ∧ + (∀ m : ℕ, F (c ^ m) = z ^ m) ∧ + ∀ a : C, + spectralNorm (GaussResidueField K n) (GaussAlgebraicClosure K n) (F a) ≤ M * ‖a‖ + +/-- The sole remaining functional in the domain argument, stated for the canonical maximal Gauss +root. Lemma 4.5.5 identifies the algebra generated by `c` with the polynomial quotient; one then +extends its root-evaluation map linearly across the finite fraction-field extension and uses the +Banach open mapping theorem for this bound. -/ +def HasBoundedGaussMaxRootFunctional {n : ℕ} (c : C) + {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) : Prop := + ∃ (F : C → GaussAlgebraicClosure K n) (M : ℝ), 0 < M ∧ + (∀ m : ℕ, F (c ^ m) = gaussMaxRoot K hP hPdeg ^ m) ∧ + ∀ a : C, + spectralNorm (GaussResidueField K n) (GaussAlgebraicClosure K n) (F a) ≤ M * ‖a‖ + +/-- The remaining algebraic identity in the domain proof of Proposition 4.5.7: after passing to +fraction fields, the maximal Gauss root is a root of the minimal polynomial of `c`. -/ +def HasFractionMinpolyGaussRoot [IsDomain C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπinj : Function.Injective π) (c : C) + {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) : Prop := + let A := TateAlgebra K (Fin n) + let L := GaussAlgebraicClosure K n + letI : Algebra A C := π.toRingHom.toAlgebra + letI : FaithfulSMul A C := + (faithfulSMul_iff_algebraMap_injective A C).mpr hπinj + letI : Algebra A L := (gaussAlgebraicClosureMap K n).toAlgebra + letI : FaithfulSMul A L := + (faithfulSMul_iff_algebraMap_injective A L).mpr + (gaussAlgebraicClosureMap_injective K n) + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + Polynomial.eval₂ (IsFractionRing.lift (gaussAlgebraicClosureMap_injective K n)) + (gaussMaxRoot K hP hPdeg) + (minpoly (FractionRing A) (algebraMap C (FractionRing C) c)) = 0 + +/-- A Tate-algebra relation becomes the minimal polynomial of the element after passing to the +fraction fields. This is the algebraic conclusion of Lemma 4.5.5 used in Proposition 4.5.7. -/ +def IsFractionMinpoly [IsDomain C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπinj : Function.Injective π) (c : C) + (P : (TateAlgebra K (Fin n))[X]) : Prop := + let A := TateAlgebra K (Fin n) + letI : Algebra A C := π.toRingHom.toAlgebra + letI : FaithfulSMul A C := + (faithfulSMul_iff_algebraMap_injective A C).mpr hπinj + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + P.map (algebraMap A (FractionRing A)) = + minpoly (FractionRing A) (algebraMap C (FractionRing C) c) + +/-- The minimal polynomial over the Tate algebra, using the algebra structure induced by `π`. -/ +noncomputable def integralMinimalPolynomial {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (c : C) : (TateAlgebra K (Fin n))[X] := + letI : Algebra (TateAlgebra K (Fin n)) C := π.toRingHom.toAlgebra + minpoly (TateAlgebra K (Fin n)) c + +/-- Finiteness makes the integral minimal polynomial monic. -/ +theorem integralMinimalPolynomial_monic {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπfinite : π.Finite) (c : C) : + (integralMinimalPolynomial K π c).Monic := by + let A := TateAlgebra K (Fin n) + letI : Algebra A C := π.toRingHom.toAlgebra + letI : Module.Finite A C := hπfinite + change (minpoly A c).Monic + exact minpoly.monic (IsIntegral.of_finite A c) + +/-- The integral minimal polynomial annihilates the original element. -/ +theorem eval₂_integralMinimalPolynomial {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (c : C) : + Polynomial.eval₂ π.toRingHom c (integralMinimalPolynomial K π c) = 0 := by + let A := TateAlgebra K (Fin n) + letI : Algebra A C := π.toRingHom.toAlgebra + change Polynomial.eval₂ (algebraMap A C) c (minpoly A c) = 0 + simpa only [Polynomial.aeval_def] using minpoly.aeval A c + +/-- Lemma 4.5.5 over an integrally closed base: the integral minimal polynomial becomes the field +minimal polynomial after passing to fraction fields. -/ +theorem isFractionMinpoly_integralMinimalPolynomial [IsDomain C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπinj : Function.Injective π) + (hπfinite : π.Finite) (c : C) : + IsFractionMinpoly K π hπinj c (integralMinimalPolynomial K π c) := by + let A := TateAlgebra K (Fin n) + letI : Algebra A C := π.toRingHom.toAlgebra + letI : FaithfulSMul A C := + (faithfulSMul_iff_algebraMap_injective A C).mpr hπinj + letI : Module.Finite A C := hπfinite + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + letI : IsScalarTower A (FractionRing A) (FractionRing C) := + FractionRing.isScalarTower_liftAlgebra A (FractionRing C) + change (minpoly A c).map (algebraMap A (FractionRing A)) = + minpoly (FractionRing A) (algebraMap C (FractionRing C) c) + exact (minpoly.isIntegrallyClosed_eq_field_fractions + (R := A) (S := C) (FractionRing A) (FractionRing C) (IsIntegral.of_finite A c)).symm + +/-- A relation identified with the fraction-field minimal polynomial annihilates the maximal +Gauss root. -/ +theorem hasFractionMinpolyGaussRoot_of_isFractionMinpoly [IsDomain C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπinj : Function.Injective π) (c : C) + {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) + (hmin : IsFractionMinpoly K π hπinj c P) : + HasFractionMinpolyGaussRoot K π hπinj c hP hPdeg := by + let A := TateAlgebra K (Fin n) + let L := GaussAlgebraicClosure K n + letI : Algebra A C := π.toRingHom.toAlgebra + letI : FaithfulSMul A C := + (faithfulSMul_iff_algebraMap_injective A C).mpr hπinj + letI : Algebra A L := (gaussAlgebraicClosureMap K n).toAlgebra + letI : FaithfulSMul A L := + (faithfulSMul_iff_algebraMap_injective A L).mpr + (gaussAlgebraicClosureMap_injective K n) + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + change P.map (algebraMap A (FractionRing A)) = + minpoly (FractionRing A) (algebraMap C (FractionRing C) c) at hmin + change Polynomial.eval₂ (IsFractionRing.lift (gaussAlgebraicClosureMap_injective K n)) + (gaussMaxRoot K hP hPdeg) + (minpoly (FractionRing A) (algebraMap C (FractionRing C) c)) = 0 + have hcomp : + (IsFractionRing.lift (gaussAlgebraicClosureMap_injective K n)).comp + (algebraMap A (FractionRing A)) = gaussAlgebraicClosureMap K n := by + ext a + exact IsFractionRing.lift_algebraMap (A := A) (K := FractionRing A) (L := L) + (g := gaussAlgebraicClosureMap K n) (gaussAlgebraicClosureMap_injective K n) a + rw [← hmin, Polynomial.eval₂_map, hcomp] + exact eval₂_gaussMaxRoot K hP hPdeg + +/-- Once the fraction-field minimal-polynomial identity is known, the Gauss-root functional is +automatic: extend evaluation linearly and apply the finite-module open-mapping theorem. -/ +theorem hasBoundedGaussMaxRootFunctional_of_fractionMinpolyRoot [IsDomain C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπinj : Function.Injective π) + (hπfinite : π.Finite) (hπcont : Continuous π) (c : C) + {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) + (hroot : HasFractionMinpolyGaussRoot K π hπinj c hP hPdeg) : + HasBoundedGaussMaxRootFunctional K c hP hPdeg := by + let A := TateAlgebra K (Fin n) + let H := GaussResidueField K n + let L := GaussAlgebraicClosure K n + letI : NormedField L := spectralNorm.normedField H L + letI : NormedAlgebra H L := spectralNorm.normedAlgebra H L + letI : NormedAlgebra K L := NormedAlgebra.restrictScalars K H L + letI : Algebra A C := π.toRingHom.toAlgebra + letI : IsScalarTower K A C := IsScalarTower.of_algebraMap_eq fun r ↦ (π.commutes r).symm + letI : ContinuousSMul A C := + continuousSMul_of_continuousRingHom π.toRingHom hπcont + letI : FaithfulSMul A C := + (faithfulSMul_iff_algebraMap_injective A C).mpr hπinj + letI : Module.Finite A C := hπfinite + let ι : A →ₐ[K] L := + { __ := gaussAlgebraicClosureMap K n + commutes' := fun _ ↦ rfl } + letI : Algebra A L := (gaussAlgebraicClosureMap K n).toAlgebra + let hKAL : IsScalarTower K A L := + IsScalarTower.of_algebraMap_eq fun r ↦ (ι.commutes r).symm + letI : IsScalarTower K A L := hKAL + have hιnorm (a : A) : ‖ι a‖ = ‖a‖ := + spectralNorm_gaussAlgebraicClosureMap K n a + have hιcont : Continuous ι := + (AddMonoidHomClass.isometry_of_norm ι hιnorm).continuous + letI : ContinuousSMul A L := + continuousSMul_of_continuousRingHom (gaussAlgebraicClosureMap K n) hιcont + letI : FaithfulSMul A L := + (faithfulSMul_iff_algebraMap_injective A L).mpr + (gaussAlgebraicClosureMap_injective K n) + have hroot' : + letI : Algebra (FractionRing A) (FractionRing C) := + FractionRing.liftAlgebra A (FractionRing C) + Polynomial.eval₂ (IsFractionRing.lift (FaithfulSMul.algebraMap_injective A L)) + (gaussMaxRoot K hP hPdeg) + (minpoly (FractionRing A) (algebraMap C (FractionRing C) c)) = 0 := by + simpa only [HasFractionMinpolyGaussRoot] using hroot + obtain ⟨G, M, hM, hGpow, hG⟩ := + exists_bounded_fractionRingFunctional_of_minpoly_root_of_finite + (K := K) (A := A) (C := C) (L := L) hKAL c + (gaussMaxRoot K hP hPdeg) hroot' + exact ⟨G, M, hM, hGpow, hG⟩ + +/-- A bounded functional for the chosen maximal root packages the bounded root realization. -/ +theorem hasBoundedGaussRootRealization_of_maxRootFunctional {n : ℕ} (c : C) + {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) + (hF : HasBoundedGaussMaxRootFunctional K c hP hPdeg) : + HasBoundedGaussRootRealization K n c P := by + obtain ⟨F, M, hM, hFpow, hFbound⟩ := hF + exact ⟨gaussMaxRoot K hP hPdeg, aeval_gaussMaxRoot K hP hPdeg, + spectralNorm_gaussMaxRoot K hP hPdeg, F, M, hM, hFpow, hFbound⟩ + +/-- A bounded Gauss-root realization supplies the difficult inequality in Proposition 4.5.7. -/ +theorem spectralValue_le_spectralRadius_of_boundedGaussRootRealization [Nontrivial C] + {n : ℕ} (c : C) {P : (TateAlgebra K (Fin n))[X]} + (h : HasBoundedGaussRootRealization K n c P) : + spectralValue P ≤ BerkovichSpectrum.spectralRadius C c := by + obtain ⟨z, -, hz, F, M, hM, hFpow, hF⟩ := h + let H := GaussResidueField K n + let L := GaussAlgebraicClosure K n + letI : NormedField L := spectralNorm.normedField H L + have hbound (a : C) : ‖F a‖ ≤ M * ‖a‖ := hF a + rw [← hz] + exact norm_le_spectralRadius_of_bounded_power_realization c z F M hM hFpow hbound + +/-- Any continuous monic Tate-algebra relation gives the standard upper bound +`ρ(c) ≤ σ(P)`. The proof evaluates at a Berkovich point attaining the spectral radius, passes to +its completed residue field, and applies Mathlib's nonarchimedean root bound there. Continuity is +enough because pulling the point back along the normalization map is automatically bounded by the +Gauss norm. -/ +theorem spectralRadius_le_spectralValue_of_relation [Nontrivial C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπ : Continuous π) + (c : C) {P : (TateAlgebra K (Fin n))[X]} (hPmonic : P.Monic) + (hPeval : Polynomial.eval₂ π.toRingHom c P = 0) : + BerkovichSpectrum.spectralRadius C c ≤ spectralValue P := by + obtain ⟨y, hy⟩ := BerkovichSpectrumOver.exists_apply_eq_spectralRadius K C c + let H := BerkovichSpectrumOver.CompletedResidueField y + let πcont : ContinuousAlgHom K (TateAlgebra K (Fin n)) C := + { toAlgHom := π, cont := hπ } + let φ : TateAlgebra K (Fin n) →+* H := + (BerkovichSpectrumOver.completedResidueMap y).comp π.toRingHom + let z : H := BerkovichSpectrumOver.completedResidueMap y c + have hφ (a : TateAlgebra K (Fin n)) : ‖φ a‖ ≤ ‖a‖ := by + change ‖BerkovichSpectrumOver.completedResidueMap y (π a)‖ ≤ ‖a‖ + rw [BerkovichSpectrumOver.norm_completedResidueMap] + exact BerkovichSpectrumOver.le_norm K _ + (BerkovichSpectrumOver.comapContinuous K _ πcont y) a + have hz : Polynomial.aeval z (P.map φ) = 0 := by + have hmap := congrArg (BerkovichSpectrumOver.completedResidueMap y) hPeval + rw [map_zero, Polynomial.hom_eval₂] at hmap + simpa only [Polynomial.aeval_def, Polynomial.eval₂_map, Algebra.algebraMap_self, + RingHom.id_comp] using hmap + let ν : AlgebraNorm H H := + { toFun := norm + map_zero' := norm_zero + add_le' := norm_add_le + neg' := norm_neg + smul' := norm_mul + mul_le' := norm_mul_le + eq_zero_of_map_eq_zero' := fun _ h ↦ norm_eq_zero.mp h } + have hνpow : IsPowMul ν := by + intro x m _ + change ‖x ^ m‖ = ‖x‖ ^ m + exact norm_pow x m + have hνna : IsNonarchimedean ν := by + intro x x' + change ‖x + x'‖ ≤ max ‖x‖ ‖x'‖ + exact IsUltrametricDist.norm_add_le_max x x' + have hroot : ‖z‖ ≤ spectralValue (P.map φ) := by + have hνz : ν z = ‖z‖ := rfl + rw [← hνz] + exact norm_root_le_spectralValue (f := ν) hνpow hνna (hPmonic.map φ) hz + calc + BerkovichSpectrum.spectralRadius C c = y c := hy.symm + _ = ‖z‖ := (BerkovichSpectrumOver.norm_completedResidueMap y c).symm + _ ≤ spectralValue (P.map φ) := hroot + _ ≤ spectralValue P := spectralValue_map_le φ hφ hPmonic + +/-- The sharp polynomial supplied by Proposition 4.5.3 for a Noether-normalizing Tate algebra. -/ +def HasSharpSpectralPolynomial (n : ℕ) (π : TateAlgebra K (Fin n) →ₐ[K] C) + (c : C) : Prop := + ∃ P : (TateAlgebra K (Fin n))[X], P.Monic ∧ Polynomial.eval₂ π.toRingHom c P = 0 ∧ + BerkovichSpectrum.spectralRadius C c = spectralValue P + +/-- Proposition 4.5.7 reduced to its finite-module functional: the usual root bound gives one +inequality, while a bounded realization of the maximal Gauss root gives the other. -/ +theorem hasSharpSpectralPolynomial_of_boundedGaussRootRealization [Nontrivial C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπ : Continuous π) + (c : C) {P : (TateAlgebra K (Fin n))[X]} (hPmonic : P.Monic) + (hPeval : Polynomial.eval₂ π.toRingHom c P = 0) + (hroot : HasBoundedGaussRootRealization K n c P) : + HasSharpSpectralPolynomial K n π c := by + refine ⟨P, hPmonic, hPeval, le_antisymm + (spectralRadius_le_spectralValue_of_relation K π hπ c hPmonic hPeval) ?_⟩ + exact spectralValue_le_spectralRadius_of_boundedGaussRootRealization K c hroot + +/-- Domain-case Proposition 4.5.7 with only its final bounded-functional input exposed. -/ +theorem hasSharpSpectralPolynomial_of_maxRootFunctional [Nontrivial C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπ : Continuous π) + (c : C) {P : (TateAlgebra K (Fin n))[X]} (hPmonic : P.Monic) + (hPeval : Polynomial.eval₂ π.toRingHom c P = 0) + (hF : HasBoundedGaussMaxRootFunctional K c hPmonic + (natDegree_pos_of_monic_relation K π.toRingHom c hPmonic hPeval)) : + HasSharpSpectralPolynomial K n π c := by + apply hasSharpSpectralPolynomial_of_boundedGaussRootRealization K π hπ c hPmonic hPeval + exact hasBoundedGaussRootRealization_of_maxRootFunctional K c hPmonic + (natDegree_pos_of_monic_relation K π.toRingHom c hPmonic hPeval) hF + +/-- Domain-case Proposition 4.5.7, reduced exactly to Lemma 4.5.5: a monic relation that becomes +the fraction-field minimal polynomial has spectral value equal to the spectral radius. -/ +theorem hasSharpSpectralPolynomial_of_isFractionMinpoly [IsDomain C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) + (hπinj : Function.Injective π) (hπfinite : π.Finite) (hπcont : Continuous π) + (c : C) {P : (TateAlgebra K (Fin n))[X]} (hPmonic : P.Monic) + (hPeval : Polynomial.eval₂ π.toRingHom c P = 0) + (hmin : IsFractionMinpoly K π hπinj c P) : + HasSharpSpectralPolynomial K n π c := by + let hPdeg := natDegree_pos_of_monic_relation K π.toRingHom c hPmonic hPeval + apply hasSharpSpectralPolynomial_of_maxRootFunctional K π hπcont c hPmonic hPeval + apply hasBoundedGaussMaxRootFunctional_of_fractionMinpolyRoot K π hπinj + hπfinite hπcont c hPmonic hPdeg + exact hasFractionMinpolyGaussRoot_of_isFractionMinpoly K π hπinj c hPmonic hPdeg hmin + +/-- Proposition 4.5.7 over a Noether-normalizing Tate algebra. The integrally-closed input is +supplied by the Rückert unique-factorization induction. -/ +theorem hasSharpSpectralPolynomial_of_integrallyClosedNormalization [IsDomain C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) + (hπinj : Function.Injective π) (hπfinite : π.Finite) (hπcont : Continuous π) + (c : C) : HasSharpSpectralPolynomial K n π c := by + apply hasSharpSpectralPolynomial_of_isFractionMinpoly K π hπinj hπfinite hπcont c + (integralMinimalPolynomial_monic K π hπfinite c) + (eval₂_integralMinimalPolynomial K π c) + exact isFractionMinpoly_integralMinimalPolynomial K π hπinj hπfinite c + +/-- The precise output of the missing finite-fiber argument in Proposition 4.5.7: a point above +the Gauss point at which the chosen root has size `σ(P)`. -/ +def HasGaussFiberMaximum {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C) (c : C) + (P : (TateAlgebra K (Fin n))[X]) : Prop := + ∃ y : BerkovichSpectrumOver K C, + (∀ a, y (π a) = ‖a‖) ∧ y c = spectralValue P + +/-- The standard upper bound together with the finite-fiber maximum gives the sharp equality of +Proposition 4.5.7. -/ +theorem hasSharpSpectralPolynomial_of_gaussFiberMaximum [Nontrivial C] {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπ : Continuous π) + (c : C) {P : (TateAlgebra K (Fin n))[X]} (hPmonic : P.Monic) + (hPeval : Polynomial.eval₂ π.toRingHom c P = 0) + (hfiber : HasGaussFiberMaximum K π c P) : HasSharpSpectralPolynomial K n π c := by + refine ⟨P, hPmonic, hPeval, le_antisymm + (spectralRadius_le_spectralValue_of_relation K π hπ c hPmonic hPeval) ?_⟩ + obtain ⟨y, -, hy⟩ := hfiber + rw [← hy] + exact BerkovichSpectrumOver.le_spectralRadius K C y c + +/-- A sharp spectral polynomial for an element in the closed spectral unit ball has all its +coefficients in the Gauss unit ball. -/ +theorem hasUnitBallRelation_of_hasSharpSpectralPolynomial {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (c : C) + (hc : BerkovichSpectrum.spectralRadius C c ≤ 1) + (hsharp : HasSharpSpectralPolynomial K n π c) : + HasUnitBallRelation K n π.toRingHom c := by + obtain ⟨P, hPmonic, hPeval, hsharp⟩ := hsharp + refine ⟨P, hPmonic, ?_, hPeval⟩ + intro i + change ‖P.coeff i‖ ≤ 1 + apply norm_coeff_le_one_of_spectralValue_le_one hPmonic + rwa [← hsharp] + +/-- Proposition 4.5.3 immediately supplies the certificate used in Proposition 4.5.12. -/ +theorem hasUnitBallIntegralCertificate_of_hasSharpSpectralPolynomial {n : ℕ} + (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπ : Continuous π) (c : C) + (hc : BerkovichSpectrum.spectralRadius C c ≤ 1) + (hsharp : HasSharpSpectralPolynomial K n π c) : + HasUnitBallIntegralCertificate K c := by + let πcont : ContinuousAlgHom K (TateAlgebra K (Fin n)) C := + { toAlgHom := π, cont := hπ } + exact ⟨n, πcont, isIntegral_image_unitBall_of_hasUnitBallRelation K n π.toRingHom c + (hasUnitBallRelation_of_hasSharpSpectralPolynomial K π c hc hsharp)⟩ + +/-- A Noether normalization together with Proposition 4.5.3 for every element. The finite +injective map is already supplied algebraically by Noether normalization; continuity and the +sharp polynomial are the remaining analytic inputs. -/ +def HasSharpNoetherNormalization (C : Type v) [NormedCommRing C] [NormedAlgebra K C] : Prop := + ∃ (n : ℕ) (π : TateAlgebra K (Fin n) →ₐ[K] C), + Function.Injective π ∧ π.Finite ∧ Continuous π ∧ + ∀ c : C, HasSharpSpectralPolynomial K n π c + +/-- In the domain case, Noether normalization and continuity of the normalizing map supply all +the sharp spectral polynomials of Proposition 4.5.7. -/ +theorem hasSharpNoetherNormalization_of_isAffinoidAlgebra_of_isDomain [IsDomain C] + (hC : IsAffinoidAlgebra K C) + (hcontinuous : ∀ {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C), Continuous π) : + HasSharpNoetherNormalization K C := by + obtain ⟨n, π, hπinj, hπfinite⟩ := + exists_finite_injective_tateAlgebra_of_isAffinoidAlgebra K hC + have hπcont : Continuous π := hcontinuous π + exact ⟨n, π, hπinj, hπfinite, hπcont, + hasSharpSpectralPolynomial_of_integrallyClosedNormalization K π + hπinj hπfinite hπcont⟩ + +/-- Sharp spectral polynomials over one Noether normalization imply the boundary case in the +power-boundedness criterion. -/ +theorem hasPowerBoundedSpectralCriterion_of_hasSharpNoetherNormalization [Nontrivial C] + (hC : HasSharpNoetherNormalization K C) : HasPowerBoundedSpectralCriterion C := by + apply hasPowerBoundedSpectralCriterion_of_certificates K + intro c hc + obtain ⟨n, π, -, -, hπ, hsharp⟩ := hC + exact hasUnitBallIntegralCertificate_of_hasSharpSpectralPolynomial K π hπ c hc (hsharp c) + +/-- The non-domain form of Proposition 4.5.3 reduced to its componentwise input. All minimal +prime components must use one continuous Tate-algebra coefficient map; the algebraic +minimal-prime argument then removes the nilpotent error. -/ +theorem hasPowerBoundedSpectralCriterion_of_minimalPrime_relations + [Nontrivial C] [IsNoetherianRing C] {n : ℕ} + (π : ContinuousAlgHom K (TateAlgebra K (Fin n)) C) + (hrelations : ∀ c : C, BerkovichSpectrum.spectralRadius C c ≤ 1 → + ∀ q ∈ minimalPrimes C, + HasUnitBallRelation K n ((Ideal.Quotient.mk q).comp π.toRingHom) + (Ideal.Quotient.mk q c)) : + HasPowerBoundedSpectralCriterion C := by + apply hasPowerBoundedSpectralCriterion_of_certificates K + intro c hc + exact hasUnitBallIntegralCertificate_of_minimalPrime_quotients K π c + (hrelations c hc) + +/-- Proposition 4.5.12 for an affinoid domain, with automatic continuity of its normalizing maps +left as an explicit topological input. -/ +theorem hasPowerBoundedSpectralCriterion_of_isAffinoidAlgebra_of_isDomain [IsDomain C] + (hC : IsAffinoidAlgebra K C) + (hcontinuous : ∀ {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C), Continuous π) : + HasPowerBoundedSpectralCriterion C := + hasPowerBoundedSpectralCriterion_of_hasSharpNoetherNormalization K + (hasSharpNoetherNormalization_of_isAffinoidAlgebra_of_isDomain K hC hcontinuous) + +end Tate + +end SpectralPolynomial + +end Rigid diff --git a/Rigid/AffinoidAlgebra/SpectralPresentation.lean b/Rigid/AffinoidAlgebra/SpectralPresentation.lean new file mode 100644 index 0000000..ee1168d --- /dev/null +++ b/Rigid/AffinoidAlgebra/SpectralPresentation.lean @@ -0,0 +1,142 @@ +import Mathlib.RingTheory.Ideal.MinimalPrime.Noetherian +import Rigid.AffinoidAlgebra.ClosedIdeals +import Rigid.AffinoidAlgebra.SpectralPolynomial +import Rigid.AffinoidAlgebra.TateRealization + +set_option linter.style.header false + +/-! +# Spectral relations over one affinoid presentation + +For each minimal-prime quotient, Noether normalization is performed inside the same surjective +Tate presentation. The resulting factor is isometric, so its sharp polynomial can be mapped back +to the presentation without changing its spectral value. Thus all component relations have +coefficients in one Gauss unit ball and can be multiplied before the nilpotent error is removed. +This supplies the coefficient-comparison step suppressed in the printed proof of Mattias, +Proposition 4.5.3. +-/ + +open scoped Polynomial + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +/-- Affinoid algebras are Noetherian, recorded in the production namespace. -/ +theorem isNoetherianRing_of_affinoidAlgebra (hA : IsAffinoidAlgebra K A) : + IsNoetherianRing A := by + let P := hA.presentation + haveI : IsNoetherianRing + (TateAlgebra K (Fin P.n) ⧸ P.ideal) := + isNoetherianRing_of_surjective _ _ (Ideal.Quotient.mk P.ideal) + Ideal.Quotient.mk_surjective + exact isNoetherianRing_of_ringEquiv _ P.equiv.toRingEquiv + +namespace SpectralPolynomial + +/-- A minimal component has a Gauss-unit-ball relation over the original affinoid presentation, +not merely over a separately chosen normalization of the component. -/ +theorem hasUnitBallRelation_minimalPrime_of_affinoidPresentation + [Nontrivial A] (hA : IsAffinoidAlgebra K A) + (htop : (inferInstance : TopologicalSpace A) = affinoidTopology K A hA) + (c : A) (hc : BerkovichSpectrum.spectralRadius A c ≤ 1) + (q : Ideal A) (hq : q ∈ minimalPrimes A) : + HasUnitBallRelation K hA.presentation.n + ((Ideal.Quotient.mk q).comp hA.presentation.toAlgHom.toRingHom) + (Ideal.Quotient.mk q c) := by + letI : IsClosed (q : Set A) := + isClosed_ideal_of_topology_eq_affinoidTopology K A hA htop q + letI : q.IsPrime := hq.isPrime + letI : IsUltrametricDist (A ⧸ q) := idealQuotientIsUltrametricDist q + let φ : ContinuousAlgHom K (TateAlgebra K (Fin hA.presentation.n)) A := + { toAlgHom := hA.presentation.toAlgHom + cont := continuous_tateAlgebra_to_affinoid K hA htop hA.presentation.toAlgHom } + let φq : ContinuousAlgHom K (TateAlgebra K (Fin hA.presentation.n)) (A ⧸ q) := + (idealQuotientMk K q).comp φ + have hφq : Function.Surjective φq := + Ideal.Quotient.mk_surjective.comp hA.presentation.toAlgHom_surjective + obtain ⟨d, j, hjnorm, hιinj, hιfinite⟩ := + TateAlgebra.exists_isometric_normalizationFactor_of_surjective K + hA.presentation.n φq.toAlgHom hφq + have hjcont : Continuous j := + (AddMonoidHomClass.isometry_of_norm j hjnorm).continuous + let jcont : ContinuousAlgHom K (TateAlgebra K (Fin d)) + (TateAlgebra K (Fin hA.presentation.n)) := + { toAlgHom := j, cont := hjcont } + let ι : ContinuousAlgHom K (TateAlgebra K (Fin d)) (A ⧸ q) := + φq.comp jcont + obtain ⟨P, hPmonic, hPeval, hPsharp⟩ := + hasSharpSpectralPolynomial_of_integrallyClosedNormalization K ι.toAlgHom + hιinj hιfinite ι.continuous (Ideal.Quotient.mk q c) + let Q : (TateAlgebra K (Fin hA.presentation.n))[X] := P.map j.toRingHom + have hQmonic : Q.Monic := hPmonic.map j.toRingHom + have hQeval : + Polynomial.eval₂ φq.toRingHom (Ideal.Quotient.mk q c) Q = 0 := by + change Polynomial.eval₂ φq.toRingHom (Ideal.Quotient.mk q c) + (P.map j.toRingHom) = 0 + rw [Polynomial.eval₂_map] + have hmapι : φq.toRingHom.comp j.toRingHom = ι.toRingHom := by + ext a + rfl + rw [hmapι] + exact hPeval + have hQsharp : + BerkovichSpectrum.spectralRadius (A ⧸ q) (Ideal.Quotient.mk q c) = + spectralValue Q := by + rw [hPsharp] + exact (spectralValue_map_eq j.toRingHom hjnorm hPmonic).symm + have hcq : + BerkovichSpectrum.spectralRadius (A ⧸ q) (Ideal.Quotient.mk q c) ≤ 1 := + (BerkovichSpectrumOver.spectralRadius_map_le K A (idealQuotientMk K q) c).trans hc + have hrelation : HasUnitBallRelation K hA.presentation.n φq.toRingHom + (Ideal.Quotient.mk q c) := + hasUnitBallRelation_of_hasSharpSpectralPolynomial K φq.toAlgHom + (Ideal.Quotient.mk q c) hcq + ⟨Q, hQmonic, hQeval, hQsharp⟩ + have hmap : + φq.toRingHom = + (Ideal.Quotient.mk q).comp hA.presentation.toAlgHom.toRingHom := by + ext a + rfl + rw [hmap] at hrelation + exact hrelation + +/-- Proposition 4.5.12 for an arbitrary affinoid algebra in a Banach realization carrying its +canonical topology. -/ +theorem hasPowerBoundedSpectralCriterion_of_affinoidAlgebra + [Nontrivial A] (hA : IsAffinoidAlgebra K A) + (htop : (inferInstance : TopologicalSpace A) = affinoidTopology K A hA) : + HasPowerBoundedSpectralCriterion A := by + letI : IsNoetherianRing A := isNoetherianRing_of_affinoidAlgebra K hA + let φ : ContinuousAlgHom K (TateAlgebra K (Fin hA.presentation.n)) A := + { toAlgHom := hA.presentation.toAlgHom + cont := continuous_tateAlgebra_to_affinoid K hA htop hA.presentation.toAlgHom } + apply hasPowerBoundedSpectralCriterion_of_minimalPrime_relations K φ + intro c hc q hq + simpa [φ] using + hasUnitBallRelation_minimalPrime_of_affinoidPresentation K hA htop c hc q hq + +/-- Presentation-level form of the general spectral criterion. This avoids any dependence on +the particular presentation chosen from an `IsAffinoidAlgebra` witness. -/ +theorem hasPowerBoundedSpectralCriterion_of_affinoidPresentation + [Nontrivial A] (P : AffinoidPresentation K A) + (htop : (inferInstance : TopologicalSpace A) = P.residueTopology) : + HasPowerBoundedSpectralCriterion A := by + let hA : IsAffinoidAlgebra K A := ⟨P⟩ + have hchosen : + hA.presentation.residueTopology = P.residueTopology := + residueTopology_eq_for_affinoidPresentationData K + hA.presentation.ideal hA.presentation.equiv P.ideal P.equiv + have hcanonical : + (inferInstance : TopologicalSpace A) = affinoidTopology K A hA := by + change (inferInstance : TopologicalSpace A) = hA.presentation.residueTopology + exact htop.trans hchosen.symm + exact hasPowerBoundedSpectralCriterion_of_affinoidAlgebra K hA hcanonical + +end SpectralPolynomial + +end Rigid diff --git a/Rigid/AffinoidAlgebra/SpectralRadius.lean b/Rigid/AffinoidAlgebra/SpectralRadius.lean new file mode 100644 index 0000000..8154245 --- /dev/null +++ b/Rigid/AffinoidAlgebra/SpectralRadius.lean @@ -0,0 +1,151 @@ +import Rigid.AffinoidAlgebra.MaximumModulus +import Rigid.Berkovich.SpectralRadius + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# Spectral radius and power-bounded elements + +This file formalizes the analytic part of Proposition 4.5.12 from the cited draft. In every +Banach algebra, power-bounded elements have spectral radius at most one, and spectral radius +strictly less than one implies power-boundedness. The boundary case is reduced to the monic +unit-ball relation supplied by Noether normalization. For a Tate algebra that relation is not +needed: the Gauss point identifies the spectral radius with the Gauss norm directly. +-/ + +open Filter +open scoped Topology BigOperators + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable {B : Type v} [NormedCommRing B] [NormedAlgebra K B] [CompleteSpace B] + [IsUltrametricDist B] + +namespace IsPowerBounded + +/-- A power-bounded element has spectral radius at most one. -/ +theorem spectralRadius_le_one [Nontrivial B] {b : B} (hb : IsPowerBounded b) : + BerkovichSpectrum.spectralRadius B b ≤ 1 := by + obtain ⟨x, hx⟩ := BerkovichSpectrum.exists_apply_eq_spectralRadius B b + rw [← hx] + rcases hb with ⟨C, hC⟩ + by_contra h + have hxb : 1 < x b := lt_of_not_ge h + obtain ⟨n, hn⟩ := pow_unbounded_of_one_lt C hxb + apply not_le_of_gt hn + calc + x b ^ n = x (b ^ n) := (_root_.map_pow x.seminorm b n).symm + _ ≤ ‖b ^ n‖ := BerkovichSpectrum.le_norm B x _ + _ ≤ C := hC ⟨n, rfl⟩ + +private theorem of_normalizedNorm_pow_lt_one [Nontrivial B] {b : B} {n : ℕ} (hn : 0 < n) + (hbn : BerkovichSpectrum.normalizedNormSeminorm B (b ^ n) < 1) : + IsPowerBounded b := by + let μ : RingSeminorm B := BerkovichSpectrum.normalizedNormSeminorm B + let D : ℝ := ∑ r ∈ Finset.range n, μ (b ^ r) + have hμ1 : μ 1 ≤ 1 := (BerkovichSpectrum.normalizedNormSeminorm_one B).le + refine ⟨‖(1 : B)‖ * D, ?_⟩ + rintro _ ⟨m, rfl⟩ + have hmod : m % n < n := Nat.mod_lt m hn + have hdecomp : b ^ m = (b ^ n) ^ (m / n) * b ^ (m % n) := by + rw [← pow_mul, ← pow_add, Nat.div_add_mod] + have hblock : μ ((b ^ n) ^ (m / n)) ≤ 1 := by + calc + μ ((b ^ n) ^ (m / n)) ≤ μ (b ^ n) ^ (m / n) := + map_pow_le_pow' hμ1 (b ^ n) (m / n) + _ ≤ 1 := pow_le_one₀ (apply_nonneg μ _) hbn.le + have hrem : μ (b ^ (m % n)) ≤ D := by + dsimp only [D] + exact Finset.single_le_sum + (fun r _ ↦ apply_nonneg μ (b ^ r)) (Finset.mem_range.mpr hmod) + calc + ‖b ^ m‖ ≤ ‖(1 : B)‖ * μ (b ^ m) := + BerkovichSpectrum.norm_le_norm_one_mul_normalizedNormSeminorm B (b ^ m) + _ ≤ ‖(1 : B)‖ * (μ ((b ^ n) ^ (m / n)) * μ (b ^ (m % n))) := by + gcongr + rw [hdecomp] + exact map_mul_le_mul μ _ _ + _ ≤ ‖(1 : B)‖ * (1 * μ (b ^ (m % n))) := by gcongr + _ ≤ ‖(1 : B)‖ * D := by simpa using + mul_le_mul_of_nonneg_left hrem (norm_nonneg (1 : B)) + +/-- Spectral radius strictly less than one implies power-boundedness in any complete normed +algebra. The affinoid input is needed only for the boundary case `ρ = 1`. -/ +theorem of_spectralRadius_lt_one [Nontrivial B] {b : B} + (hb : BerkovichSpectrum.spectralRadius B b < 1) : IsPowerBounded b := by + have hev : ∀ᶠ n : ℕ in atTop, + smoothingSeminormSeq (BerkovichSpectrum.normalizedNormSeminorm B) b n < 1 := + (BerkovichSpectrum.tendsto_spectralRadius B b) (Iio_mem_nhds hb) + obtain ⟨n, hnroot, hn⟩ := + (hev.and (show ∀ᶠ n : ℕ in atTop, 1 ≤ n from eventually_ge_atTop 1)).exists + have hnpos : 0 < n := Nat.lt_of_lt_of_le Nat.zero_lt_one hn + have hexp : 0 < 1 / (n : ℝ) := one_div_pos.mpr (Nat.cast_pos.mpr hnpos) + have hnorm : BerkovichSpectrum.normalizedNormSeminorm B (b ^ n) < 1 := + (Real.rpow_lt_one_iff' + (apply_nonneg (BerkovichSpectrum.normalizedNormSeminorm B) (b ^ n)) hexp).mp hnroot + exact of_normalizedNorm_pow_lt_one hnpos hnorm + +end IsPowerBounded + +namespace TateAlgebra + +/-- On a strict Tate algebra, the spectral radius is the Gauss norm. -/ +theorem spectralRadius_eq_norm (n : ℕ) (f : TateAlgebra K (Fin n)) : + BerkovichSpectrum.spectralRadius (TateAlgebra K (Fin n)) f = ‖f‖ := by + apply le_antisymm + · exact BerkovichSpectrum.spectralRadius_le_norm _ f + · simpa using BerkovichSpectrumOver.le_spectralRadius K _ (gaussPoint K n) f + +/-- Proposition 4.5.12(ii) for the Tate-algebra base case. -/ +theorem isPowerBounded_iff_spectralRadius_le_one {n : ℕ} {f : TateAlgebra K (Fin n)} : + IsPowerBounded f ↔ BerkovichSpectrum.spectralRadius (TateAlgebra K (Fin n)) f ≤ 1 := by + rw [spectralRadius_eq_norm K n f, isPowerBounded_iff_norm_le_one] + +end TateAlgebra + +/-- A BGR unit-ball certificate for an element: a finite Tate algebra maps continuously to the +ambient algebra and the element is integral over the image of its Gauss unit ball. -/ +def HasUnitBallIntegralCertificate (b : B) : Prop := + ∃ (n : ℕ) (π : ContinuousAlgHom K (TateAlgebra K (Fin n)) B), + IsIntegral ((TateAlgebra.unitBallSubring K n).map π.toRingHom) b + +/-- A unit-ball integral certificate implies power-boundedness. -/ +theorem isPowerBounded_of_hasUnitBallIntegralCertificate {b : B} + (hb : HasUnitBallIntegralCertificate K b) : IsPowerBounded b := by + obtain ⟨n, π, hb⟩ := hb + exact TateAlgebra.isPowerBounded_of_isIntegral_image_unitBall K n π hb + +/-- The boundary property in Proposition 4.5.12(ii). -/ +def HasPowerBoundedSpectralCriterion (B : Type v) [NormedCommRing B] : Prop := + ∀ b : B, BerkovichSpectrum.spectralRadius B b ≤ 1 → IsPowerBounded b + +/-- Unit-ball integral certificates for the closed spectral unit ball imply the boundary +criterion. -/ +theorem hasPowerBoundedSpectralCriterion_of_certificates + (hcertificate : ∀ b : B, BerkovichSpectrum.spectralRadius B b ≤ 1 → + HasUnitBallIntegralCertificate K b) : HasPowerBoundedSpectralCriterion B := + fun b hb ↦ isPowerBounded_of_hasUnitBallIntegralCertificate K (hcertificate b hb) + +/-- The boundary step in Proposition 4.5.12(ii), isolated in the exact form supplied by its +Noether-normalization proof. -/ +theorem isPowerBounded_iff_spectralRadius_le_one_of_certificate + [Nontrivial B] + (hcertificate : ∀ b : B, BerkovichSpectrum.spectralRadius B b ≤ 1 → + HasUnitBallIntegralCertificate K b) (b : B) : + IsPowerBounded b ↔ BerkovichSpectrum.spectralRadius B b ≤ 1 := by + constructor + · exact IsPowerBounded.spectralRadius_le_one + · exact fun hb ↦ isPowerBounded_of_hasUnitBallIntegralCertificate K (hcertificate b hb) + +/-- Once the affinoid boundary criterion is available, power-boundedness is characterized exactly +by spectral radius at most one. -/ +theorem isPowerBounded_iff_spectralRadius_le_one [Nontrivial B] + (hB : HasPowerBoundedSpectralCriterion B) (b : B) : + IsPowerBounded b ↔ BerkovichSpectrum.spectralRadius B b ≤ 1 := + ⟨IsPowerBounded.spectralRadius_le_one, hB b⟩ + +end Rigid diff --git a/Rigid/AffinoidAlgebra/TateRealization.lean b/Rigid/AffinoidAlgebra/TateRealization.lean new file mode 100644 index 0000000..d1da0ae --- /dev/null +++ b/Rigid/AffinoidAlgebra/TateRealization.lean @@ -0,0 +1,84 @@ +import Mathlib.RingTheory.Ideal.Quotient.Operations +import Rigid.AffinoidAlgebra.AutomaticContinuity + +set_option linter.style.header false + +/-! +# Tate algebras as affinoid algebras + +The quotient by the zero ideal gives a preferred affinoid presentation of a Tate algebra. This +file records that its canonical affinoid topology is the Gauss-norm topology and uses automatic +continuity for canonical affinoid topologies to obtain continuity of maps from a Tate algebra into +any Banach realization whose topology is known to be canonical. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- The tautological presentation of a Tate algebra as its quotient by the zero ideal. -/ +noncomputable def tateAlgebraPresentation (n : ℕ) : + AffinoidPresentation K (TateAlgebra K (Fin n)) where + n := n + ideal := ⊥ + equiv := AlgEquiv.quotientBot K (TateAlgebra K (Fin n)) + +@[simp] +theorem tateAlgebraPresentation_toAlgHom_apply (n : ℕ) + (f : TateAlgebra K (Fin n)) : + AffinoidPresentation.toAlgHom K (TateAlgebra K (Fin n)) + (tateAlgebraPresentation K n) f = f := by + rfl + +/-- A finite Tate algebra is an affinoid algebra. -/ +theorem isAffinoidAlgebra_tateAlgebra (n : ℕ) : + IsAffinoidAlgebra K (TateAlgebra K (Fin n)) := + ⟨tateAlgebraPresentation K n⟩ + +/-- The canonical affinoid topology of a Tate algebra is its Gauss-norm topology. -/ +theorem affinoidTopology_tateAlgebra_eq (n : ℕ) + (hT : IsAffinoidAlgebra K (TateAlgebra K (Fin n))) : + affinoidTopology K (TateAlgebra K (Fin n)) hT = + (inferInstance : TopologicalSpace (TateAlgebra K (Fin n))) := by + calc + affinoidTopology K (TateAlgebra K (Fin n)) hT = + (tateAlgebraPresentation K n).residueTopology := + residueTopology_eq_for_affinoidPresentationData K + hT.presentation.ideal hT.presentation.equiv + (tateAlgebraPresentation K n).ideal (tateAlgebraPresentation K n).equiv + _ = (inferInstance : TopologicalSpace (TateAlgebra K (Fin n))) := by + change TopologicalSpace.coinduced + (AffinoidPresentation.toAlgHom K (TateAlgebra K (Fin n)) + (tateAlgebraPresentation K n)) + (inferInstance : TopologicalSpace (TateAlgebra K (Fin n))) = + (inferInstance : TopologicalSpace (TateAlgebra K (Fin n))) + rw [show AffinoidPresentation.toAlgHom K (TateAlgebra K (Fin n)) + (tateAlgebraPresentation K n) = + AlgHom.id K (TateAlgebra K (Fin n)) by + apply DFunLike.ext _ _ + intro f + exact tateAlgebraPresentation_toAlgHom_apply K n f] + exact coinduced_id + +variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] + +/-- Every algebra homomorphism from a Tate algebra to a Banach realization of an affinoid algebra +is continuous once the target topology is identified with its canonical affinoid topology. -/ +theorem continuous_tateAlgebra_to_affinoid + (hA : IsAffinoidAlgebra K A) + (htop : (inferInstance : TopologicalSpace A) = affinoidTopology K A hA) + {n : ℕ} (f : TateAlgebra K (Fin n) →ₐ[K] A) : Continuous f := by + let hT := isAffinoidAlgebra_tateAlgebra K n + have hf : + @Continuous (TateAlgebra K (Fin n)) A + (affinoidTopology K (TateAlgebra K (Fin n)) hT) + (affinoidTopology K A hA) f := + continuous_for_affinoidPresentationData K + hT.presentation.ideal hT.presentation.equiv + hA.presentation.ideal hA.presentation.equiv f + rw [affinoidTopology_tateAlgebra_eq K n hT, ← htop] at hf + exact hf + +end Rigid diff --git a/Rigid/AffinoidSpectrum/RationalRefinement.lean b/Rigid/AffinoidSpectrum/RationalRefinement.lean new file mode 100644 index 0000000..a2f69a8 --- /dev/null +++ b/Rigid/AffinoidSpectrum/RationalRefinement.lean @@ -0,0 +1,373 @@ +import Rigid.AffinoidSpectrum.RationalCover + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +open scoped BigOperators + +/-! +# Rational-cover refinement from a dominating family + +BGR 8.2.2 refines a finite rational cover by forming finitely many products of its defining +functions. The formal argument naturally separates into two parts: the products span the unit +ideal, and at every Berkovich point one of the proposed denominators dominates every numerator. +This file packages the second, reusable part. A later product-family construction can therefore +produce a rational cover and its refinement by proving only finite pointwise inequalities. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +namespace AffinoidRationalSubdomain.Cover + +/-- A member of a rational cover obtained by choosing one element of a unit-ideal family as +denominator and keeping the whole family as numerators. -/ +noncomputable def dominatingDomain {r s : ℕ} (p : Fin r → A) + (hp : Ideal.span (Set.range p) = ⊤) (denominator : Fin s → Fin r) (i : Fin s) : + AffinoidRationalSubdomain K A where + n := r + g := p (denominator i) + f := p + isRational := by + apply top_unique + rw [← hp] + exact Ideal.span_mono (Set.subset_insert (p (denominator i)) (Set.range p)) + +@[simp] +theorem mem_dominatingDomain_carrier {r s : ℕ} (p : Fin r → A) + (hp : Ideal.span (Set.range p) = ⊤) (denominator : Fin s → Fin r) (i : Fin s) + (x : BerkovichSpectrumOver K A) : + x ∈ (dominatingDomain K A p hp denominator i).carrier ↔ + ∀ j, x (p j) ≤ x (p (denominator i)) := by + rfl + +/-- A pointwise dominating subfamily of a unit-ideal family gives a rational cover of the whole +affinoid spectrum. -/ +noncomputable def ofDominatingFamily {r s : ℕ} (p : Fin r → A) + (hp : Ideal.span (Set.range p) = ⊤) (denominator : Fin s → Fin r) + (hdom : ∀ x : BerkovichSpectrumOver K A, + ∃ i : Fin s, ∀ j : Fin r, x (p j) ≤ x (p (denominator i))) : + AffinoidRationalSubdomain.Cover K A (AffinoidRationalSubdomain.whole K A) where + m := s + domain := dominatingDomain K A p hp denominator + subset := fun _ ↦ by + rw [AffinoidRationalSubdomain.carrier_whole] + exact Set.subset_univ _ + covers := by + rw [AffinoidRationalSubdomain.carrier_whole] + symm + apply Set.eq_univ_of_forall + intro x + obtain ⟨i, hi⟩ := hdom x + exact Set.mem_iUnion.mpr ⟨i, + (mem_dominatingDomain_carrier K A p hp denominator i x).2 hi⟩ + +/-- Refinement criterion for a dominating-family cover. Each proposed denominator is assigned an +old cover member, and its domination inequalities are used to prove containment in that member. -/ +def refinementOfDominatingFamily + (𝒰 : AffinoidRationalSubdomain.Cover K A (AffinoidRationalSubdomain.whole K A)) + {r s : ℕ} (p : Fin r → A) (hp : Ideal.span (Set.range p) = ⊤) + (denominator : Fin s → Fin r) + (hdom : ∀ x : BerkovichSpectrumOver K A, + ∃ i : Fin s, ∀ j : Fin r, x (p j) ≤ x (p (denominator i))) + (owner : Fin s → Fin 𝒰.m) + (hrefines : ∀ i x, + (∀ j : Fin r, x (p j) ≤ x (p (denominator i))) → x ∈ (𝒰.domain (owner i)).carrier) : + Refinement K A (ofDominatingFamily K A p hp denominator hdom) 𝒰 where + index := owner + subset := by + intro i x hx + exact hrefines i x + ((mem_dominatingDomain_carrier K A p hp denominator i x).1 hx) + +/-! ## The product family attached to a rational cover -/ + +/-- The denominator followed by the numerators in a rational datum. -/ +def datumTerm (U : AffinoidRationalSubdomain K A) : Fin (U.n + 1) → A := + Fin.cases U.g U.f + +@[simp] +theorem datumTerm_zero (U : AffinoidRationalSubdomain K A) : datumTerm K A U 0 = U.g := + rfl + +@[simp] +theorem datumTerm_succ (U : AffinoidRationalSubdomain K A) (i : Fin U.n) : + datumTerm K A U i.succ = U.f i := + rfl + +theorem range_datumTerm (U : AffinoidRationalSubdomain K A) : + Set.range (datumTerm K A U) = Set.insert U.g (Set.range U.f) := by + ext a + constructor + · rintro ⟨i, rfl⟩ + refine Fin.cases ?_ (fun j ↦ ?_) i + · exact Set.mem_insert _ _ + · exact Set.mem_insert_of_mem _ ⟨j, rfl⟩ + · rintro (rfl | ⟨i, rfl⟩) + · exact ⟨0, rfl⟩ + · exact ⟨i.succ, rfl⟩ + +/-- A choice of one defining function from every member of a finite rational cover. -/ +abbrev ProductChoice + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) := + ∀ i : Fin 𝒰.m, Fin ((𝒰.domain i).n + 1) + +/-- The product associated with a choice of one defining function from each cover member. -/ +def productTerm + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) + (choice : ProductChoice K A 𝒰) : A := + ∏ i, datumTerm K A (𝒰.domain i) (choice i) + +/-- Enumerate all products of one defining function from every cover member. -/ +noncomputable def productFamily + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) : + Fin (Fintype.card (ProductChoice K A 𝒰)) → A := fun j ↦ + productTerm K A 𝒰 ((Fintype.equivFin (ProductChoice K A 𝒰)).symm j) + +/-- The full product family spans the unit ideal. This is the algebraic part of BGR's +rational-cover refinement: every defining family spans the unit ideal, so a maximal ideal cannot +contain every possible product. -/ +theorem span_range_productFamily_eq_top + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) : + Ideal.span (Set.range (productFamily K A 𝒰)) = ⊤ := by + by_contra htop + obtain ⟨m, hm, hle⟩ := + (Ideal.span (Set.range (productFamily K A 𝒰))).exists_le_maximal htop + letI : m.IsMaximal := hm + have hexists (i : Fin 𝒰.m) : + ∃ j : Fin ((𝒰.domain i).n + 1), datumTerm K A (𝒰.domain i) j ∉ m := by + by_contra h + push Not at h + have hdatum : Ideal.span (Set.range (datumTerm K A (𝒰.domain i))) ≤ m := + Ideal.span_le.mpr fun a ha ↦ by + obtain ⟨j, rfl⟩ := ha + exact h j + have htop_le : (⊤ : Ideal A) ≤ m := by + rw [← (𝒰.domain i).isRational, ← range_datumTerm K A] + exact hdatum + exact hm.ne_top (top_unique htop_le) + choose choice hchoice using hexists + have hproduct_not_mem : productTerm K A 𝒰 choice ∉ m := by + intro hproduct + rw [productTerm, Ideal.IsPrime.prod_mem_iff] at hproduct + obtain ⟨i, -, hi⟩ := hproduct + exact hchoice i hi + let j : Fin (Fintype.card (ProductChoice K A 𝒰)) := + Fintype.equivFin (ProductChoice K A 𝒰) choice + have hj : productFamily K A 𝒰 j = productTerm K A 𝒰 choice := by + simp [productFamily, j] + apply hproduct_not_mem + apply hle + apply Ideal.subset_span + exact ⟨j, hj⟩ + +/-- Choices containing at least one denominator. These are the proposed denominators in BGR's +product refinement. -/ +abbrev DenominatorChoice + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) := + {choice : ProductChoice K A 𝒰 // ∃ i, choice i = 0} + +/-- Locate a denominator-containing product inside the enumeration of all products. -/ +noncomputable def denominatorIndex + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) : + Fin (Fintype.card (DenominatorChoice K A 𝒰)) → + Fin (Fintype.card (ProductChoice K A 𝒰)) := fun j ↦ + Fintype.equivFin (ProductChoice K A 𝒰) + ((Fintype.equivFin (DenominatorChoice K A 𝒰)).symm j).1 + +/-- At every point of a rationally covered affinoid spectrum, a product containing an old +denominator dominates every product in the full family. This is the finite maximum argument in +BGR 8.2.2/2. -/ +theorem productFamily_dominated_by_denominator + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) + (x : BerkovichSpectrumOver K A) (hx𝒲 : x ∈ 𝒲.carrier) : + ∃ i : Fin (Fintype.card (DenominatorChoice K A 𝒰)), + ∀ j : Fin (Fintype.card (ProductChoice K A 𝒰)), + x (productFamily K A 𝒰 j) ≤ + x (productFamily K A 𝒰 (denominatorIndex K A 𝒰 i)) := by + let zeroChoice : ProductChoice K A 𝒰 := fun _ ↦ 0 + let j₀ : Fin (Fintype.card (ProductChoice K A 𝒰)) := + Fintype.equivFin (ProductChoice K A 𝒰) zeroChoice + letI : Nonempty (Fin (Fintype.card (ProductChoice K A 𝒰))) := ⟨j₀⟩ + obtain ⟨jmax, hjmax⟩ := + Finite.exists_max (fun j : Fin (Fintype.card (ProductChoice K A 𝒰)) ↦ + x (productFamily K A 𝒰 j)) + rw [𝒰.covers] at hx𝒲 + obtain ⟨owner, hxowner⟩ := Set.mem_iUnion.mp hx𝒲 + let choice : ProductChoice K A 𝒰 := + (Fintype.equivFin (ProductChoice K A 𝒰)).symm jmax + let choice' : ProductChoice K A 𝒰 := Function.update choice owner 0 + have hchoice'_denominator : ∃ i, choice' i = 0 := by + exact ⟨owner, by simp [choice']⟩ + let denominatorChoice : DenominatorChoice K A 𝒰 := + ⟨choice', hchoice'_denominator⟩ + let chosen : Fin (Fintype.card (DenominatorChoice K A 𝒰)) := + Fintype.equivFin (DenominatorChoice K A 𝒰) denominatorChoice + have hfactor : + x (datumTerm K A (𝒰.domain owner) (choice owner)) ≤ + x (datumTerm K A (𝒰.domain owner) 0) := by + refine Fin.cases ?_ (fun i ↦ ?_) (choice owner) + · exact le_rfl + · exact hxowner i + have hproduct : + x (productTerm K A 𝒰 choice) ≤ x (productTerm K A 𝒰 choice') := by + rw [productTerm, productTerm, map_prod, map_prod] + apply Finset.prod_le_prod + · intro i _ + exact BerkovichSpectrumOver.nonneg K A x _ + · intro i _ + by_cases hi : i = owner + · subst i + simpa [choice'] using hfactor + · simp [choice', hi] + refine ⟨chosen, fun j ↦ (hjmax j).trans ?_⟩ + simpa [productFamily, denominatorIndex, chosen, denominatorChoice, choice', choice] using hproduct + +/-- The rational domain in the product refinement corresponding to a product containing an old +denominator. -/ +noncomputable def productDomain + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) + (i : Fin (Fintype.card (DenominatorChoice K A 𝒰))) : + AffinoidRationalSubdomain K A := + dominatingDomain K A (productFamily K A 𝒰) + (span_range_productFamily_eq_top K A 𝒰) (denominatorIndex K A 𝒰) i + +/-- Choose an old cover member whose denominator occurs in a proposed product denominator. -/ +noncomputable def denominatorOwner + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) + (i : Fin (Fintype.card (DenominatorChoice K A 𝒰))) : Fin 𝒰.m := + Classical.choose ((Fintype.equivFin (DenominatorChoice K A 𝒰)).symm i).2 + +@[simp] +theorem denominatorChoice_apply_owner + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) + (i : Fin (Fintype.card (DenominatorChoice K A 𝒰))) : + ((Fintype.equivFin (DenominatorChoice K A 𝒰)).symm i).1 + (denominatorOwner K A 𝒰 i) = 0 := + Classical.choose_spec ((Fintype.equivFin (DenominatorChoice K A 𝒰)).symm i).2 + +/-- Each member of the BGR product cover is contained in an original rational-cover member. -/ +theorem productDomain_subset + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) + (i : Fin (Fintype.card (DenominatorChoice K A 𝒰))) : + (productDomain K A 𝒰 i).carrier ⊆ + (𝒰.domain (denominatorOwner K A 𝒰 i)).carrier := by + intro x hx + let denominatorChoice : DenominatorChoice K A 𝒰 := + (Fintype.equivFin (DenominatorChoice K A 𝒰)).symm i + let choice : ProductChoice K A 𝒰 := denominatorChoice.1 + let owner : Fin 𝒰.m := denominatorOwner K A 𝒰 i + have hchoice_owner : choice owner = 0 := by + simp [choice, owner, denominatorChoice] + have hdom : ∀ j : Fin (Fintype.card (ProductChoice K A 𝒰)), + x (productFamily K A 𝒰 j) ≤ + x (productFamily K A 𝒰 (denominatorIndex K A 𝒰 i)) := by + exact (mem_dominatingDomain_carrier K A (productFamily K A 𝒰) + (span_range_productFamily_eq_top K A 𝒰) (denominatorIndex K A 𝒰) i x).1 hx + intro k + let choice' : ProductChoice K A 𝒰 := Function.update choice owner k.succ + let j : Fin (Fintype.card (ProductChoice K A 𝒰)) := + Fintype.equivFin (ProductChoice K A 𝒰) choice' + have hproduct : x (productTerm K A 𝒰 choice') ≤ x (productTerm K A 𝒰 choice) := by + simpa [productFamily, denominatorIndex, j, choice', choice, denominatorChoice] using hdom j + let rest : A := (Finset.univ.erase owner).prod fun t ↦ + datumTerm K A (𝒰.domain t) (choice t) + have hchoice_product : + productTerm K A 𝒰 choice = + datumTerm K A (𝒰.domain owner) (choice owner) * rest := by + exact (Finset.mul_prod_erase Finset.univ + (fun t ↦ datumTerm K A (𝒰.domain t) (choice t)) (Finset.mem_univ owner)).symm + have hchoice'_product : + productTerm K A 𝒰 choice' = + datumTerm K A (𝒰.domain owner) (choice' owner) * rest := by + rw [productTerm] + calc + ∏ t, datumTerm K A (𝒰.domain t) (choice' t) = + datumTerm K A (𝒰.domain owner) (choice' owner) * + (Finset.univ.erase owner).prod + (fun t ↦ datumTerm K A (𝒰.domain t) (choice' t)) := + (Finset.mul_prod_erase Finset.univ + (fun t ↦ datumTerm K A (𝒰.domain t) (choice' t)) + (Finset.mem_univ owner)).symm + _ = datumTerm K A (𝒰.domain owner) (choice' owner) * rest := by + congr 1 + apply Finset.prod_congr rfl + intro t ht + have hne : t ≠ owner := Finset.ne_of_mem_erase ht + simp [choice', hne] + have hxdenominator : x (productTerm K A 𝒰 choice) ≠ 0 := by + have hxdom : x ∈ (dominatingDomain K A (productFamily K A 𝒰) + (span_range_productFamily_eq_top K A 𝒰) (denominatorIndex K A 𝒰) i).carrier := + (mem_dominatingDomain_carrier K A (productFamily K A 𝒰) + (span_range_productFamily_eq_top K A 𝒰) (denominatorIndex K A 𝒰) i x).2 hdom + have hne := BerkovichSpectrumOver.RationalDomain.denominator_ne_zero K A + (dominatingDomain K A (productFamily K A 𝒰) + (span_range_productFamily_eq_top K A 𝒰) (denominatorIndex K A 𝒰) i).isRational + ⟨x, hxdom⟩ + simpa [dominatingDomain, denominatorIndex, productFamily, choice, denominatorChoice] using hne + have hxrest_ne : x rest ≠ 0 := by + intro hzero + apply hxdenominator + rw [hchoice_product, BerkovichSpectrumOver.map_mul, hzero, mul_zero] + have hxrest_pos : 0 < x rest := + lt_of_le_of_ne (BerkovichSpectrumOver.nonneg K A x rest) hxrest_ne.symm + apply le_of_mul_le_mul_right _ hxrest_pos + simpa [hchoice'_product, hchoice_product, hchoice_owner, choice'] using hproduct + +/-- The BGR product construction gives a rational cover of an arbitrary rational subdomain. -/ +noncomputable def productCover + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) : + AffinoidRationalSubdomain.Cover K A 𝒲 where + m := Fintype.card (DenominatorChoice K A 𝒰) + domain := productDomain K A 𝒰 + subset := fun i ↦ (productDomain_subset K A 𝒰 i).trans (𝒰.subset _) + covers := by + apply Set.Subset.antisymm + · intro x hx𝒲 + obtain ⟨i, hi⟩ := productFamily_dominated_by_denominator K A 𝒰 x hx𝒲 + exact Set.mem_iUnion.mpr ⟨i, + (mem_dominatingDomain_carrier K A (productFamily K A 𝒰) + (span_range_productFamily_eq_top K A 𝒰) + (denominatorIndex K A 𝒰) i x).2 hi⟩ + · intro x hx + obtain ⟨i, hxi⟩ := Set.mem_iUnion.mp hx + exact 𝒰.subset _ (productDomain_subset K A 𝒰 i hxi) + +/-- Each member of the BGR product cover is contained in an original rational-cover member. -/ +theorem productCover_domain_subset + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) + (i : Fin (Fintype.card (DenominatorChoice K A 𝒰))) : + ((productCover K A 𝒰).domain i).carrier ⊆ + (𝒰.domain (denominatorOwner K A 𝒰 i)).carrier := + productDomain_subset K A 𝒰 i + +/-- **Rational-cover refinement.** Every finite rational cover of an arbitrary rational subdomain +is refined by the BGR product cover. -/ +noncomputable def productCoverRefinement + {𝒲 : AffinoidRationalSubdomain K A} + (𝒰 : AffinoidRationalSubdomain.Cover K A 𝒲) : + Refinement K A (productCover K A 𝒰) 𝒰 where + index := denominatorOwner K A 𝒰 + subset := productCover_domain_subset K A 𝒰 + +end AffinoidRationalSubdomain.Cover + +end Rigid diff --git a/Rigid/AffinoidSpectrum/Restriction.lean b/Rigid/AffinoidSpectrum/Restriction.lean new file mode 100644 index 0000000..4cdcc68 --- /dev/null +++ b/Rigid/AffinoidSpectrum/Restriction.lean @@ -0,0 +1,287 @@ +import Rigid.AffinoidAlgebra.RationalRestriction +import Rigid.AffinoidAlgebra.SpectralRadius +import Rigid.AffinoidSpectrum.RationalBasis +import Rigid.Berkovich.Unit + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# Restriction between rational subdomains + +This file connects the concrete rational-localization algebra to its Berkovich rational domain. +The first application is the denominator part of restriction: if `U ⊆ V`, then the denominator +defining `V` becomes a unit in the algebra of functions on `U`. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + [IsUltrametricDist A] + +namespace AffinoidRationalSubdomain + +/-- A Berkovich point of the section algebra restricts to a point of the ambient affinoid +algebra. -/ +noncomputable def ambientPoint (U : AffinoidRationalSubdomain K A) + (y : BerkovichSpectrumOver K U.Sections) : BerkovichSpectrumOver K A := + BerkovichSpectrumOver.comapContinuous K A + (RationalLocalization.baseMap K A U.n U.g U.f) y + +@[simp] +theorem ambientPoint_apply (U : AffinoidRationalSubdomain K A) + (y : BerkovichSpectrumOver K U.Sections) (a : A) : + ambientPoint K A U y a = y (RationalLocalization.baseMap K A U.n U.g U.f a) := + rfl + +/-- The ambient point underlying a point of the section algebra lies in the rational domain. -/ +theorem ambientPoint_mem_carrier (U : AffinoidRationalSubdomain K A) + (y : BerkovichSpectrumOver K U.Sections) : ambientPoint K A U y ∈ U.carrier := by + intro i + change y (RationalLocalization.baseMap K A U.n U.g U.f (U.f i)) ≤ + y (RationalLocalization.baseMap K A U.n U.g U.f U.g) + rw [← RationalLocalization.baseMap_denominator_mul_coordinate K A U.n U.g U.f i, + BerkovichSpectrumOver.map_mul] + exact mul_le_of_le_one_right + (BerkovichSpectrumOver.nonneg K U.Sections y _) + (IsPowerBounded.apply_le_one K y + (RationalLocalization.isPowerBounded_coordinate K A U.n U.g U.f i)) + +/-- If `U ⊆ V`, the denominator defining `V` is invertible on the section algebra of `U`. -/ +theorem isUnit_baseMap_denominator_of_subset + {U V : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) : + IsUnit (RationalLocalization.baseMap K A U.n U.g U.f V.g) := by + rw [BerkovichSpectrumOver.isUnit_iff_forall_apply_ne_zero K U.Sections] + intro y + let x := ambientPoint K A U y + have hxU : x ∈ U.carrier := ambientPoint_mem_carrier K A U y + have hxV : x ∈ V.carrier := hUV hxU + have hVg : x V.g ≠ 0 := + BerkovichSpectrumOver.RationalDomain.denominator_ne_zero K A V.isRational ⟨x, hxV⟩ + simpa [x] using hVg + +/-- On the smaller rational domain, each quotient coordinate defining the larger domain has value +at most one at every Berkovich point. The affinoid maximum-modulus theorem will turn this +pointwise estimate into power-boundedness. -/ +theorem quotientCoordinate_apply_le_one_of_subset + {U V : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) + (i : Fin V.n) (y : BerkovichSpectrumOver K U.Sections) : + y (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) i) ≤ 1 := by + let φ := RationalLocalization.baseMap K A U.n U.g U.f + let hg := isUnit_baseMap_denominator_of_subset K A hUV + let q := RationalLocalization.quotientCoordinate K A (f := V.f) φ hg i + let x := ambientPoint K A U y + have hxU : x ∈ U.carrier := ambientPoint_mem_carrier K A U y + have hxV : x ∈ V.carrier := hUV hxU + have hle : y (φ (V.f i)) ≤ y (φ V.g) := by + simpa [x, φ] using hxV i + have hne : y (φ V.g) ≠ 0 := by + have hVg : x V.g ≠ 0 := + BerkovichSpectrumOver.RationalDomain.denominator_ne_zero K A V.isRational ⟨x, hxV⟩ + simpa [x, φ] using hVg + have hpos : 0 < y (φ V.g) := + lt_of_le_of_ne (BerkovichSpectrumOver.nonneg K U.Sections y _) hne.symm + have hrel : φ V.g * q = φ (V.f i) := + RationalLocalization.denominator_mul_quotientCoordinate K A (f := V.f) φ hg i + change y q ≤ 1 + apply (mul_le_mul_iff_left₀ hpos).mp + calc + y q * y (φ V.g) = y (φ V.g) * y q := mul_comm _ _ + _ = y (φ V.g * q) := + (BerkovichSpectrumOver.map_mul K U.Sections y _ _).symm + _ = y (φ (V.f i)) := congrArg (fun z ↦ y z) hrel + _ ≤ y (φ V.g) := hle + _ = 1 * y (φ V.g) := (one_mul _).symm + +/-- The quotient coordinates required for restriction have spectral radius at most one. -/ +theorem quotientCoordinate_spectralRadius_le_one_of_subset + {U V : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) + (i : Fin V.n) : + BerkovichSpectrum.spectralRadius U.Sections + (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) i) ≤ 1 := by + by_cases hU : Nontrivial U.Sections + · letI := hU + apply (BerkovichSpectrumOver.forall_apply_le_one_iff_spectralRadius_le_one K + U.Sections _).mp + exact quotientCoordinate_apply_le_one_of_subset K A hUV i + · haveI : Subsingleton U.Sections := not_nontrivial_iff_subsingleton.mp hU + rw [Subsingleton.elim + (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) i) 0, + BerkovichSpectrum.spectralRadius_zero] + exact zero_le_one + +/-- Once the pointwise maximum-modulus estimate is known to imply power-boundedness on the +section algebra, inclusion of rational domains produces the restriction homomorphism. -/ +noncomputable def restrictionOfPointwisePowerBounded + {U V : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) + (hbounded : ∀ i : Fin V.n, IsPowerBounded + (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) i)) : + ContinuousAlgHom K V.Sections U.Sections := + RationalLocalization.liftOfIsUnit K A + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) hbounded + +/-- Restriction follows once the boundary spectral-radius estimates are supplied with the +unit-ball integral certificates from Proposition 4.5.12. -/ +noncomputable def restrictionOfUnitBallIntegralCertificates + {U V : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) + (hcertificate : ∀ i : Fin V.n, + HasUnitBallIntegralCertificate K + (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) i)) : + ContinuousAlgHom K V.Sections U.Sections := + restrictionOfPointwisePowerBounded K A hUV fun i ↦ + isPowerBounded_of_hasUnitBallIntegralCertificate K (hcertificate i) + +/-- An algebra satisfying Proposition 4.5.12(ii) supports restriction from every larger rational +domain. -/ +noncomputable def restrictionOfSpectralCriterion + {U V : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) + (hU : HasPowerBoundedSpectralCriterion U.Sections) : + ContinuousAlgHom K V.Sections U.Sections := + restrictionOfPointwisePowerBounded K A hUV fun i ↦ + hU _ (quotientCoordinate_spectralRadius_le_one_of_subset K A hUV i) + +@[simp] +theorem restrictionOfPointwisePowerBounded_comp_baseMap + {U V : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) + (hbounded : ∀ i : Fin V.n, IsPowerBounded + (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) i)) : + (restrictionOfPointwisePowerBounded K A hUV hbounded).comp + (RationalLocalization.baseMap K A V.n V.g V.f) = + RationalLocalization.baseMap K A U.n U.g U.f := + RationalLocalization.liftOfIsUnit_comp_baseMap K A _ _ _ + +/-- The conditional restriction construction is the identity for an equality inclusion. -/ +@[simp] +theorem restrictionOfPointwisePowerBounded_id + (U : AffinoidRationalSubdomain K A) + (hbounded : ∀ i : Fin U.n, IsPowerBounded + (RationalLocalization.quotientCoordinate K A + (f := U.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A (U := U) (V := U) Set.Subset.rfl) i)) : + restrictionOfPointwisePowerBounded K A (U := U) (V := U) Set.Subset.rfl hbounded = + ContinuousAlgHom.id K U.Sections := by + apply RationalLocalization.hom_ext_of_isUnit K A + (restrictionOfPointwisePowerBounded K A Set.Subset.rfl hbounded) + (ContinuousAlgHom.id K U.Sections) + · have hbase := congrArg + (fun q : ContinuousAlgHom K A U.Sections ↦ q U.g) + (restrictionOfPointwisePowerBounded_comp_baseMap K A Set.Subset.rfl hbounded) + change (restrictionOfPointwisePowerBounded K A Set.Subset.rfl hbounded) + (RationalLocalization.baseMap K A U.n U.g U.f U.g) = + RationalLocalization.baseMap K A U.n U.g U.f U.g at hbase + rw [hbase] + exact RationalLocalization.isUnit_baseMap_denominator + K A U.n U.g U.f U.isRational + · simp + +/-- Conditional restrictions compose independently of the proofs of power-boundedness used to +construct them. -/ +@[simp] +theorem restrictionOfPointwisePowerBounded_comp + {U V W : AffinoidRationalSubdomain K A} + (hUV : U.carrier ⊆ V.carrier) (hWU : W.carrier ⊆ U.carrier) + (hboundedUV : ∀ i : Fin V.n, IsPowerBounded + (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A U.n U.g U.f) + (isUnit_baseMap_denominator_of_subset K A hUV) i)) + (hboundedWU : ∀ i : Fin U.n, IsPowerBounded + (RationalLocalization.quotientCoordinate K A + (f := U.f) + (RationalLocalization.baseMap K A W.n W.g W.f) + (isUnit_baseMap_denominator_of_subset K A hWU) i)) + (hboundedWV : ∀ i : Fin V.n, IsPowerBounded + (RationalLocalization.quotientCoordinate K A + (f := V.f) + (RationalLocalization.baseMap K A W.n W.g W.f) + (isUnit_baseMap_denominator_of_subset K A (hWU.trans hUV)) i)) : + (restrictionOfPointwisePowerBounded K A hWU hboundedWU).comp + (restrictionOfPointwisePowerBounded K A hUV hboundedUV) = + restrictionOfPointwisePowerBounded K A (hWU.trans hUV) hboundedWV := by + apply RationalLocalization.hom_ext_of_isUnit K A + ((restrictionOfPointwisePowerBounded K A hWU hboundedWU).comp + (restrictionOfPointwisePowerBounded K A hUV hboundedUV)) + (restrictionOfPointwisePowerBounded K A (hWU.trans hUV) hboundedWV) + · change IsUnit + ((restrictionOfPointwisePowerBounded K A hWU hboundedWU) + ((restrictionOfPointwisePowerBounded K A hUV hboundedUV) + (RationalLocalization.baseMap K A V.n V.g V.f V.g))) + have hUVg := congrArg (fun q : ContinuousAlgHom K A U.Sections ↦ q V.g) + (restrictionOfPointwisePowerBounded_comp_baseMap K A hUV hboundedUV) + have hWUg := congrArg (fun q : ContinuousAlgHom K A W.Sections ↦ q V.g) + (restrictionOfPointwisePowerBounded_comp_baseMap K A hWU hboundedWU) + change (restrictionOfPointwisePowerBounded K A hUV hboundedUV) + (RationalLocalization.baseMap K A V.n V.g V.f V.g) = + RationalLocalization.baseMap K A U.n U.g U.f V.g at hUVg + change (restrictionOfPointwisePowerBounded K A hWU hboundedWU) + (RationalLocalization.baseMap K A U.n U.g U.f V.g) = + RationalLocalization.baseMap K A W.n W.g W.f V.g at hWUg + rw [hUVg, hWUg] + exact isUnit_baseMap_denominator_of_subset K A (hWU.trans hUV) + · apply ContinuousAlgHom.ext + intro a + simp only [ContinuousAlgHom.comp_apply] + have hUVa := congrArg (fun q : ContinuousAlgHom K A U.Sections ↦ q a) + (restrictionOfPointwisePowerBounded_comp_baseMap K A hUV hboundedUV) + have hWUa := congrArg (fun q : ContinuousAlgHom K A W.Sections ↦ q a) + (restrictionOfPointwisePowerBounded_comp_baseMap K A hWU hboundedWU) + have hWVa := congrArg (fun q : ContinuousAlgHom K A W.Sections ↦ q a) + (restrictionOfPointwisePowerBounded_comp_baseMap K A (hWU.trans hUV) hboundedWV) + change (restrictionOfPointwisePowerBounded K A hUV hboundedUV) + (RationalLocalization.baseMap K A V.n V.g V.f a) = + RationalLocalization.baseMap K A U.n U.g U.f a at hUVa + change (restrictionOfPointwisePowerBounded K A hWU hboundedWU) + (RationalLocalization.baseMap K A U.n U.g U.f a) = + RationalLocalization.baseMap K A W.n W.g W.f a at hWUa + change (restrictionOfPointwisePowerBounded K A (hWU.trans hUV) hboundedWV) + (RationalLocalization.baseMap K A V.n V.g V.f a) = + RationalLocalization.baseMap K A W.n W.g W.f a at hWVa + rw [hUVa, hWUa, hWVa] + +@[simp] +theorem restrictionOfSpectralCriterion_id + (U : AffinoidRationalSubdomain K A) + (hU : HasPowerBoundedSpectralCriterion U.Sections) : + restrictionOfSpectralCriterion K A (U := U) (V := U) Set.Subset.rfl hU = + ContinuousAlgHom.id K U.Sections := by + unfold restrictionOfSpectralCriterion + apply restrictionOfPointwisePowerBounded_id + +@[simp] +theorem restrictionOfSpectralCriterion_comp + {U V W : AffinoidRationalSubdomain K A} + (hUV : U.carrier ⊆ V.carrier) (hWU : W.carrier ⊆ U.carrier) + (hU : HasPowerBoundedSpectralCriterion U.Sections) + (hW : HasPowerBoundedSpectralCriterion W.Sections) : + (restrictionOfSpectralCriterion K A hWU hW).comp + (restrictionOfSpectralCriterion K A hUV hU) = + restrictionOfSpectralCriterion K A (hWU.trans hUV) hW := by + unfold restrictionOfSpectralCriterion + apply restrictionOfPointwisePowerBounded_comp + +end AffinoidRationalSubdomain + +end Rigid diff --git a/Rigid/Berkovich/Nonempty.lean b/Rigid/Berkovich/Nonempty.lean index 0203191..f5d92c7 100644 --- a/Rigid/Berkovich/Nonempty.lean +++ b/Rigid/Berkovich/Nonempty.lean @@ -168,6 +168,99 @@ private theorem improve_mem_mulAt_of_mem (p : Candidate R) {c d : R} (hd : p ∈ · exact hd a · exact seminormFromConst_isMul_of_isMul p.map_one.le hc p.powMul hd a +private theorem improve_apply_of_mem_mulAt (p : Candidate R) {c d : R} (hd : p ∈ mulAt R d) : + (improve R p c).toRingSeminorm d = p.toRingSeminorm d := by + unfold improve + split_ifs with hc + · rfl + · exact seminormFromConst_apply_of_isMul p.map_one.le hc p.powMul hd + +private theorem improve_apply_self (p : Candidate R) (c : R) : + (improve R p c).toRingSeminorm c = p.toRingSeminorm c := by + unfold improve + split_ifs with hc + · rfl + · exact seminormFromConst_apply_c p.map_one.le hc p.powMul + +/-- The normalized ring seminorm associated with the given norm. -/ +noncomputable def normalizedNormSeminorm : RingSeminorm R := + seminormFromBounded + (f := fun a : R ↦ ‖a‖) (c := 1) norm_zero norm_nonneg + (fun a b ↦ by simpa using norm_mul_le a b) norm_add_le norm_neg + +@[simp] +theorem normalizedNormSeminorm_one [Nontrivial R] : normalizedNormSeminorm R 1 = 1 := by + apply seminormFromBounded_one (c := 1) + · intro h + have h1 := congr_fun h (1 : R) + simpa using (norm_pos_iff.mpr (one_ne_zero : (1 : R) ≠ 0)).ne' h1 + · exact norm_nonneg + · intro a b + simpa using norm_mul_le a b + +theorem normalizedNormSeminorm_le_norm (a : R) : normalizedNormSeminorm R a ≤ ‖a‖ := by + unfold normalizedNormSeminorm + change seminormFromBounded' (fun x : R ↦ ‖x‖) a ≤ ‖a‖ + simpa only [one_mul] using (seminormFromBounded_le (c := 1) norm_nonneg + (fun x y ↦ by simpa using norm_mul_le x y) a) + +/-- The spectral radius of an element, computed using the normalized seminorm associated with the +given norm. Normalization does not affect asymptotic roots. -/ +noncomputable def spectralRadius (a : R) : ℝ := + smoothingFun (normalizedNormSeminorm R) a + +/-- The spectral smoothing of the normalized norm, regarded as a candidate seminorm. -/ +private noncomputable def spectralCandidate [Nontrivial R] : Candidate R := by + let μ : RingSeminorm R := normalizedNormSeminorm R + have hμ1 : μ 1 ≤ 1 := (normalizedNormSeminorm_one R).le + let f : RingSeminorm R := Rigid.spectralSmoothingSeminorm μ hμ1 + have hf_one : f 1 = 1 := by + change smoothingFun μ 1 = 1 + rw [smoothingFun_of_powMul μ hμ1 (x := 1)] + · exact normalizedNormSeminorm_one R + · intro n hn + simp only [show μ 1 = 1 from normalizedNormSeminorm_one R, one_pow] + exact Candidate.ofRingSeminorm R f hf_one + (Rigid.isPowMul_spectralSmoothingSeminorm μ hμ1) + (fun a ↦ (Rigid.spectralSmoothingSeminorm_le μ hμ1 a).trans + (normalizedNormSeminorm_le_norm R a)) + +private theorem spectralCandidate_apply [Nontrivial R] (a : R) : + (spectralCandidate R).toRingSeminorm a = spectralRadius R a := + rfl + +private def PreservesSpectralValue (a : R) : Set (Candidate R) := + {p | p.toRingSeminorm a = spectralRadius R a} + +private theorem isClosed_preservesSpectralValue (a : R) : + IsClosed (PreservesSpectralValue R a) := + isClosed_eq (continuous_eval_candidate R a) continuous_const + +private theorem exists_mem_mulAt_finset_preserving_spectralValue [Nontrivial R] + (a : R) (s : Finset R) : + ∃ p : Candidate R, p ∈ PreservesSpectralValue R a ∩ mulAt R a ∧ + ∀ c ∈ s, p ∈ mulAt R c := by + classical + let p₀ : Candidate R := improve R (spectralCandidate R) a + have hp₀a : p₀ ∈ mulAt R a := improve_mem_mulAt R (spectralCandidate R) a + have hp₀value : p₀ ∈ PreservesSpectralValue R a := by + change p₀.toRingSeminorm a = spectralRadius R a + rw [show p₀.toRingSeminorm a = (spectralCandidate R).toRingSeminorm a by + exact improve_apply_self R (spectralCandidate R) a] + exact spectralCandidate_apply R a + induction s using Finset.induction with + | empty => exact ⟨p₀, ⟨hp₀value, hp₀a⟩, by simp⟩ + | @insert c s hc ih => + obtain ⟨p, hp, hps⟩ := ih + refine ⟨improve R p c, ⟨?_, improve_mem_mulAt_of_mem R p hp.2⟩, ?_⟩ + · change (improve R p c).toRingSeminorm a = spectralRadius R a + rw [improve_apply_of_mem_mulAt R p hp.2] + exact hp.1 + · intro d hd + rcases Finset.mem_insert.mp hd with rfl | hd + · exact improve_mem_mulAt R p d + · exact improve_mem_mulAt_of_mem R p (hps d hd) + private theorem exists_mem_mulAt_finset [Nontrivial R] (s : Finset R) : ∃ p : Candidate R, ∀ c ∈ s, p ∈ mulAt R c := by classical @@ -206,6 +299,35 @@ theorem nonempty_of_nontrivial [Nontrivial R] : Nonempty (Rigid.BerkovichSpectru le_norm' := fun a ↦ (p.1 a).2.2 } ⟩ +/-- **Berkovich maximum-modulus theorem.** For every element, some bounded multiplicative +seminorm realizes the spectral smoothing of the given norm. -/ +theorem exists_apply_eq_smoothingFun [Nontrivial R] (a : R) : + ∃ x : Rigid.BerkovichSpectrum R, x a = spectralRadius R a := by + classical + let P : Set (Candidate R) := PreservesSpectralValue R a ∩ mulAt R a + have hPcompact : IsCompact P := + ((isClosed_preservesSpectralValue R a).inter (isClosed_mulAt R a)).isCompact + have hfinite (s : Finset R) : (P ∩ ⋂ c ∈ s, mulAt R c).Nonempty := by + obtain ⟨p, hp, hps⟩ := exists_mem_mulAt_finset_preserving_spectralValue R a s + refine ⟨p, hp, ?_⟩ + simp only [Set.mem_iInter] + exact hps + obtain ⟨p, hp, hmul⟩ := hPcompact.inter_iInter_nonempty (mulAt R) + (isClosed_mulAt R) hfinite + have hp_mul (c b : R) : p.toRingSeminorm (c * b) = + p.toRingSeminorm c * p.toRingSeminorm b := + (Set.mem_iInter.mp hmul c) b + let x : Rigid.BerkovichSpectrum R := + { seminorm := + { toFun := p.toRingSeminorm + map_zero' := _root_.map_zero p.toRingSeminorm + add_le' := map_add_le_add p.toRingSeminorm + neg' := map_neg_eq_map p.toRingSeminorm + map_one' := p.map_one + map_mul' := hp_mul } + le_norm' := fun b ↦ (p.1 b).2.2 } + exact ⟨x, hp.1⟩ + /-- The Berkovich spectrum of a nonzero nonarchimedean commutative normed ring is nonempty. -/ theorem nonempty_of_isUltrametric [IsUltrametricDist R] [Nontrivial R] : Nonempty (Rigid.BerkovichSpectrum R) := diff --git a/Rigid/Berkovich/Quotient.lean b/Rigid/Berkovich/Quotient.lean new file mode 100644 index 0000000..0179f23 --- /dev/null +++ b/Rigid/Berkovich/Quotient.lean @@ -0,0 +1,77 @@ +import Mathlib.RingTheory.Valuation.Quotient +import Rigid.Berkovich.CompletedResidue + +set_option linter.style.header false + +/-! +# Berkovich points on quotients + +A bounded multiplicative seminorm whose kernel contains an ideal factors through the corresponding +quotient. When the ideal is closed, the quotient norm makes the descended seminorm contractive. +This is the pointwise ingredient in the minimal-prime comparison of spectral radii. +-/ + +open scoped NNReal + +universe u v + +namespace Rigid.BerkovichSpectrumOver + +variable (K : Type u) [NontriviallyNormedField K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [IsUltrametricDist A] + +/-- A Berkovich point descends through every closed ideal contained in its kernel. -/ +noncomputable def descendQuotient (x : Rigid.BerkovichSpectrumOver K A) + (I : Ideal A) [IsClosed (I : Set A)] (hI : I ≤ x.kernel) : + Rigid.BerkovichSpectrumOver K (A ⧸ I) where + toBerkovichSpectrum := + { seminorm := + { toFun := fun z ↦ ((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI) z : ℝ) + map_zero' := by simp + add_le' := by + intro a b + calc + (((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)) (a + b) : ℝ) ≤ + max + (((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)) a : ℝ) + (((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)) b : ℝ) := by + exact_mod_cast ((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)).map_add a b + _ ≤ + (((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)) a : ℝ) + + (((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)) b : ℝ) := + max_le (le_add_of_nonneg_right NNReal.zero_le_coe) + (le_add_of_nonneg_left NNReal.zero_le_coe) + neg' := by + intro a + exact_mod_cast ((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)).map_neg a + map_one' := by simp + map_mul' := by + intro a b + exact_mod_cast ((valuation x).onQuot (by + simpa only [valuation_supp_eq_kernel] using hI)).map_mul a b } + le_norm' := by + intro z + refine le_of_forall_pos_le_add fun ε hε ↦ ?_ + obtain ⟨a, rfl, ha⟩ := Ideal.Quotient.norm_mk_lt z hε + change x a ≤ ‖Ideal.Quotient.mk I a‖ + ε + exact (le_norm K A x a).trans (le_of_lt ha) } + map_algebraMap' := by + intro r + change x (algebraMap K A r) = ‖r‖ + exact map_algebraMap K A x r + +@[simp] +theorem descendQuotient_apply_mk (x : Rigid.BerkovichSpectrumOver K A) + (I : Ideal A) [IsClosed (I : Set A)] (hI : I ≤ x.kernel) (a : A) : + descendQuotient K A x I hI (Ideal.Quotient.mk I a) = x a := + rfl + +end Rigid.BerkovichSpectrumOver diff --git a/Rigid/Berkovich/SpectralRadius.lean b/Rigid/Berkovich/SpectralRadius.lean new file mode 100644 index 0000000..2d995bd --- /dev/null +++ b/Rigid/Berkovich/SpectralRadius.lean @@ -0,0 +1,157 @@ +import Rigid.Berkovich.RelativeNonempty + +set_option linter.style.header false + +/-! +# The spectral radius and the Berkovich maximum-modulus theorem + +The spectral radius is the limit of the `n`-th roots of the norms of the powers. We use the +standard normalized seminorm associated with a possibly non-normalized ring norm; the two norms +are equivalent, so this does not change power-boundedness. The compactness construction in +`Rigid.Berkovich.Nonempty` produces a multiplicative seminorm attaining this spectral radius. +-/ + +open Filter +open scoped Topology + +universe u v + +namespace Rigid.BerkovichSpectrum + +variable (R : Type u) [NormedCommRing R] + +@[simp] +theorem spectralRadius_zero : spectralRadius R 0 = 0 := by + change smoothingFun (normalizedNormSeminorm R) 0 = 0 + apply le_antisymm + · simpa using (smoothingFun_le (normalizedNormSeminorm R) (0 : R) (1 : PNat)) + · exact le_ciInf fun n ↦ Real.rpow_nonneg (apply_nonneg (normalizedNormSeminorm R) _) _ + +/-- The normalized seminorm controls the original norm up to the fixed factor `‖1‖`. -/ +theorem norm_le_norm_one_mul_normalizedNormSeminorm [Nontrivial R] (a : R) : + ‖a‖ ≤ ‖(1 : R)‖ * normalizedNormSeminorm R a := by + have hmul : ∀ x y : R, ‖x * y‖ ≤ (1 : ℝ) * ‖x‖ * ‖y‖ := by + intro x y + simpa using norm_mul_le x y + have hbdd : BddAbove (Set.range fun y : R ↦ ‖a * y‖ / ‖y‖) := + seminormFromBounded_bddAbove_range norm_nonneg hmul a + have hle : ‖a‖ / ‖(1 : R)‖ ≤ normalizedNormSeminorm R a := by + unfold normalizedNormSeminorm + change ‖a‖ / ‖(1 : R)‖ ≤ seminormFromBounded' (fun x : R ↦ ‖x‖) a + have hle' := le_ciSup hbdd (1 : R) + change ‖a * 1‖ / ‖(1 : R)‖ ≤ + seminormFromBounded' (fun x : R ↦ ‖x‖) a at hle' + simpa only [mul_one] using hle' + have h1 : 0 < ‖(1 : R)‖ := norm_pos_iff.mpr one_ne_zero + calc + ‖a‖ ≤ normalizedNormSeminorm R a * ‖(1 : R)‖ := (div_le_iff₀ h1).mp hle + _ = ‖(1 : R)‖ * normalizedNormSeminorm R a := mul_comm _ _ + +/-- The spectral radius is nonnegative. -/ +theorem spectralRadius_nonneg [Nontrivial R] (a : R) : 0 ≤ spectralRadius R a := + smoothingFun_nonneg (normalizedNormSeminorm R) (normalizedNormSeminorm_one R).le a + +/-- The spectral radius is at most the given norm. -/ +theorem spectralRadius_le_norm [Nontrivial R] (a : R) : spectralRadius R a ≤ ‖a‖ := + (smoothingFun_le_self (normalizedNormSeminorm R) a).trans + (normalizedNormSeminorm_le_norm R a) + +/-- The `n`-th roots of the normalized norms of powers converge to the spectral radius. -/ +theorem tendsto_spectralRadius [Nontrivial R] (a : R) : + Tendsto (smoothingSeminormSeq (normalizedNormSeminorm R) a) atTop + (𝓝 (spectralRadius R a)) := + tendsto_smoothingFun_of_map_one_le_one (normalizedNormSeminorm R) + (normalizedNormSeminorm_one R).le a + +/-- Every bounded multiplicative seminorm is bounded above by the spectral radius. -/ +theorem le_spectralRadius [Nontrivial R] (x : Rigid.BerkovichSpectrum R) (a : R) : + x a ≤ spectralRadius R a := by + have hroot1 : Tendsto (fun n : ℕ ↦ ‖(1 : R)‖ ^ (1 / (n : ℝ))) atTop (𝓝 1) := by + have h1 : ‖(1 : R)‖ ≠ 0 := norm_ne_zero_iff.mpr one_ne_zero + convert tendsto_const_nhds.rpow tendsto_one_div_atTop_nhds_zero_nat (Or.inl h1) using 1 + rw [Real.rpow_zero] + have hlim : Tendsto (fun n : ℕ ↦ + smoothingSeminormSeq (normalizedNormSeminorm R) a n * + ‖(1 : R)‖ ^ (1 / (n : ℝ))) atTop (𝓝 (spectralRadius R a)) := by + simpa using (tendsto_spectralRadius R a).mul hroot1 + apply ge_of_tendsto hlim + filter_upwards [eventually_ge_atTop 1] with n hn + have hn0 : (n : ℝ) ≠ 0 := Nat.cast_ne_zero.mpr (Nat.one_le_iff_ne_zero.mp hn) + have hexp : 0 < 1 / (n : ℝ) := one_div_pos.mpr (Nat.cast_pos.mpr (by omega)) + calc + x a = (x a ^ n) ^ (1 / (n : ℝ)) := by + rw [← Real.rpow_natCast, ← Real.rpow_mul (Rigid.BerkovichSpectrum.nonneg R x a), + mul_one_div_cancel hn0, Real.rpow_one] + _ = x (a ^ n) ^ (1 / (n : ℝ)) := by rw [_root_.map_pow x.seminorm] + _ ≤ ‖a ^ n‖ ^ (1 / (n : ℝ)) := + Real.rpow_le_rpow (Rigid.BerkovichSpectrum.nonneg R x (a ^ n)) + (Rigid.BerkovichSpectrum.le_norm R x (a ^ n)) hexp.le + _ ≤ (normalizedNormSeminorm R (a ^ n) * ‖(1 : R)‖) ^ (1 / (n : ℝ)) := by + apply Real.rpow_le_rpow (norm_nonneg _) _ hexp.le + simpa only [mul_comm] using norm_le_norm_one_mul_normalizedNormSeminorm R (a ^ n) + _ = normalizedNormSeminorm R (a ^ n) ^ (1 / (n : ℝ)) * + ‖(1 : R)‖ ^ (1 / (n : ℝ)) := by + rw [Real.mul_rpow (apply_nonneg (normalizedNormSeminorm R) _) (norm_nonneg _)] + _ = smoothingSeminormSeq (normalizedNormSeminorm R) a n * + ‖(1 : R)‖ ^ (1 / (n : ℝ)) := rfl + +/-- The maximum in the Berkovich maximum-modulus theorem is attained. -/ +theorem exists_apply_eq_spectralRadius [Nontrivial R] (a : R) : + ∃ x : Rigid.BerkovichSpectrum R, x a = spectralRadius R a := + exists_apply_eq_smoothingFun R a + +end Rigid.BerkovichSpectrum + +namespace Rigid.BerkovichSpectrumOver + +variable (K : Type u) [NontriviallyNormedField K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] + +/-- Relative Berkovich points are also bounded above by the spectral radius. -/ +theorem le_spectralRadius [Nontrivial A] (x : Rigid.BerkovichSpectrumOver K A) (a : A) : + x a ≤ Rigid.BerkovichSpectrum.spectralRadius A a := + Rigid.BerkovichSpectrum.le_spectralRadius A x.toBerkovichSpectrum a + +/-- The spectral radius is attained on the relative Berkovich spectrum. -/ +theorem exists_apply_eq_spectralRadius [Nontrivial A] (a : A) : + ∃ x : Rigid.BerkovichSpectrumOver K A, + x a = Rigid.BerkovichSpectrum.spectralRadius A a := by + obtain ⟨x, hx⟩ := Rigid.BerkovichSpectrum.exists_apply_eq_spectralRadius A a + exact ⟨ofBerkovichSpectrum K A x, hx⟩ + +/-- **Berkovich maximum-modulus theorem.** The spectral radius is the attained maximum of the +values of an element on the relative Berkovich spectrum. -/ +theorem exists_spectralRadius_maximum [Nontrivial A] (a : A) : + ∃ x : Rigid.BerkovichSpectrumOver K A, + x a = Rigid.BerkovichSpectrum.spectralRadius A a ∧ + ∀ y : Rigid.BerkovichSpectrumOver K A, y a ≤ x a := by + obtain ⟨x, hx⟩ := exists_apply_eq_spectralRadius K A a + refine ⟨x, hx, fun y ↦ ?_⟩ + rw [hx] + exact le_spectralRadius K A y a + +/-- Spectral radius does not increase under a continuous algebra homomorphism. -/ +theorem spectralRadius_map_le + {B : Type*} [NormedCommRing B] [NormedAlgebra K B] [Nontrivial B] + (f : ContinuousAlgHom K A B) (a : A) : + Rigid.BerkovichSpectrum.spectralRadius B (f a) ≤ + Rigid.BerkovichSpectrum.spectralRadius A a := by + letI : Nontrivial A := f.toRingHom.domain_nontrivial + obtain ⟨y, hy⟩ := exists_apply_eq_spectralRadius K B (f a) + rw [← hy] + exact le_spectralRadius K A (comapContinuous K A f y) a + +/-- Pointwise boundedness by one on the relative Berkovich spectrum is equivalent to spectral +radius at most one. -/ +theorem forall_apply_le_one_iff_spectralRadius_le_one [Nontrivial A] (a : A) : + (∀ x : Rigid.BerkovichSpectrumOver K A, x a ≤ 1) ↔ + Rigid.BerkovichSpectrum.spectralRadius A a ≤ 1 := by + constructor + · intro h + obtain ⟨x, hx⟩ := exists_apply_eq_spectralRadius K A a + rw [← hx] + exact h x + · intro h x + exact (le_spectralRadius K A x a).trans h + +end Rigid.BerkovichSpectrumOver diff --git a/Rigid/Berkovich/Unit.lean b/Rigid/Berkovich/Unit.lean new file mode 100644 index 0000000..d882ce2 --- /dev/null +++ b/Rigid/Berkovich/Unit.lean @@ -0,0 +1,62 @@ +import Mathlib.Analysis.Normed.Ring.Units +import Mathlib.Analysis.Normed.Group.Quotient +import Rigid.Berkovich.RelativeNonempty + +set_option linter.style.header false +set_option linter.unusedSectionVars false + +/-! +# Detecting units on the Berkovich spectrum + +Maximal ideals in a Banach ring are closed. Consequently, a nonunit survives as zero in a +nontrivial Banach-field quotient. Pulling any Berkovich point of that quotient back to the +original algebra produces a point at which the nonunit vanishes. Thus an element of a complete +normed algebra is a unit exactly when it is nonzero at every Berkovich point. +-/ + +universe u v + +namespace Rigid + +variable (K : Type u) [NontriviallyNormedField K] +variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] + +namespace BerkovichSpectrumOver + +/-- A unit has nonzero value at every relative Berkovich point. -/ +theorem apply_ne_zero_of_isUnit {a : A} (ha : IsUnit a) + (x : BerkovichSpectrumOver K A) : x a ≠ 0 := by + obtain ⟨u, rfl⟩ := ha + intro hu + have hzero : x ((↑u : A) * (↑(u⁻¹) : A)) = 0 := by + rw [BerkovichSpectrumOver.map_mul, hu, zero_mul] + have hone : x ((↑u : A) * (↑(u⁻¹) : A)) = 1 := by simp + exact zero_ne_one (hzero.symm.trans hone) + +/-- **Unit detection on the Berkovich spectrum.** An element of a Banach algebra is a unit if it +does not vanish at any relative Berkovich point. -/ +theorem isUnit_iff_forall_apply_ne_zero {a : A} : + IsUnit a ↔ ∀ x : BerkovichSpectrumOver K A, x a ≠ 0 := by + constructor + · exact fun ha x ↦ apply_ne_zero_of_isUnit K A ha x + · intro ha + by_contra hunit + have hspan : Ideal.span ({a} : Set A) ≠ ⊤ := by + intro htop + exact hunit (Ideal.span_singleton_eq_top.mp htop) + obtain ⟨m, hm, ham⟩ := (Ideal.span ({a} : Set A)).exists_le_maximal hspan + letI : m.IsMaximal := hm + letI : IsClosed (m : Set A) := Ideal.IsMaximal.isClosed + let q : ContinuousAlgHom K A (A ⧸ m) := + { toAlgHom := Ideal.Quotient.mkₐ K m + cont := continuous_quot_mk } + let y : BerkovichSpectrumOver K (A ⧸ m) := + Classical.choice (nonempty_of_nontrivial K (A ⧸ m)) + let x : BerkovichSpectrumOver K A := comapContinuous K A q y + have haq : q a = 0 := by + exact Ideal.Quotient.eq_zero_iff_mem.mpr (ham (Ideal.subset_span (Set.mem_singleton a))) + exact ha x (by simp [x, haq]) + +end BerkovichSpectrumOver + +end Rigid diff --git a/Rigid/Development.lean b/Rigid/Development.lean index 59e5fed..f784c1f 100644 --- a/Rigid/Development.lean +++ b/Rigid/Development.lean @@ -14,6 +14,8 @@ import Rigid.AffinoidAlgebra.QuotientTopology import Rigid.AffinoidAlgebra.RationalDatum import Rigid.AffinoidAlgebra.RationalLocalization import Rigid.AffinoidAlgebra.ResidueNorm +import Rigid.AffinoidAlgebra.SpectralPresentation +import Rigid.AffinoidSpectrum.Restriction import Rigid.TateAlgebra.Complete import Rigid.TateAlgebra.Noetherian import Rigid.TateAlgebra.Multiplicative @@ -1384,19 +1386,82 @@ theorem inter_subset_right (U V : AffinoidRationalSubdomain K A) : /-- Restriction of analytic functions along an inclusion of rational subdomains. -/ noncomputable def restriction (hA : IsAffinoidAlgebra K A) {U V : AffinoidRationalSubdomain K A} - (hUV : U.carrier ⊆ V.carrier) : ContinuousAlgHom K V.Sections U.Sections := sorry + (hUV : U.carrier ⊆ V.carrier) : ContinuousAlgHom K V.Sections U.Sections := by + let U' : Rigid.AffinoidRationalSubdomain K A := + { n := U.n, g := U.g, f := U.f, isRational := U.isRational } + let V' : Rigid.AffinoidRationalSubdomain K A := + { n := V.n, g := V.g, f := V.f, isRational := V.isRational } + have hUV' : U'.carrier ⊆ V'.carrier := by + intro x hx + let x' : BerkovichSpectrumOver K A := + { toBerkovichSpectrum := + { seminorm := x.toBerkovichSpectrum.seminorm + le_norm' := x.toBerkovichSpectrum.le_norm' } + map_algebraMap' := x.map_algebraMap' } + have hx' : x' ∈ U.carrier := by + intro i + change x (U.f i) ≤ x U.g + exact hx i + have hxV := hUV hx' + intro i + change x (V.f i) ≤ x V.g + exact hxV i + by_cases hU : Nontrivial U.Sections + · letI := hU + letI : Nontrivial U'.Sections := by + change Nontrivial (RationalLocalization K A U.n U.g U.f) + exact hU + let hUaff := isAffinoidAlgebra_rationalLocalization K A hA U.n U.g U.f + let P := hUaff.presentation + let P' : Rigid.AffinoidPresentation K U.Sections := + { n := P.n, ideal := P.ideal, equiv := P.equiv } + have htop : (inferInstance : TopologicalSpace U.Sections) = P'.residueTopology := by + calc + (inferInstance : TopologicalSpace U.Sections) = + affinoidTopology K U.Sections hUaff := + topology_eq_affinoidTopology_of_isAffinoidAlgebra K U.Sections hUaff + _ = P.residueTopology := + affinoidTopology_eq_residueTopology K U.Sections hUaff P + _ = P'.residueTopology := rfl + exact Rigid.AffinoidRationalSubdomain.restrictionOfSpectralCriterion K A hUV' + (Rigid.SpectralPolynomial.hasPowerBoundedSpectralCriterion_of_affinoidPresentation + K P' htop) + · letI : Subsingleton U.Sections := not_nontrivial_iff_subsingleton.mp hU + letI : Subsingleton U'.Sections := by + change Subsingleton (RationalLocalization K A U.n U.g U.f) + infer_instance + exact Rigid.AffinoidRationalSubdomain.restrictionOfPointwisePowerBounded K A hUV' + fun i ↦ by + rw [Subsingleton.elim + (Rigid.RationalLocalization.quotientCoordinate K A + (f := V'.f) + (Rigid.RationalLocalization.baseMap K A U'.n U'.g U'.f) + (Rigid.AffinoidRationalSubdomain.isUnit_baseMap_denominator_of_subset + K A hUV') i) 0] + exact Rigid.isPowerBounded_zero @[simp] theorem restriction_id (hA : IsAffinoidAlgebra K A) (U : AffinoidRationalSubdomain K A) : restriction K A hA (U := U) (V := U) Set.Subset.rfl = - ContinuousAlgHom.id K U.Sections := sorry + ContinuousAlgHom.id K U.Sections := by + unfold restriction + dsimp only + split + · apply Rigid.AffinoidRationalSubdomain.restrictionOfPointwisePowerBounded_id + · apply Rigid.AffinoidRationalSubdomain.restrictionOfPointwisePowerBounded_id @[simp] theorem restriction_comp (hA : IsAffinoidAlgebra K A) {U V W : AffinoidRationalSubdomain K A} (hUV : U.carrier ⊆ V.carrier) (hWU : W.carrier ⊆ U.carrier) : (restriction K A hA hWU).comp (restriction K A hA hUV) = - restriction K A hA (hWU.trans hUV) := sorry + restriction K A hA (hWU.trans hUV) := by + unfold restriction + dsimp only + repeat' split + all_goals + try unfold Rigid.AffinoidRationalSubdomain.restrictionOfSpectralCriterion + apply Rigid.AffinoidRationalSubdomain.restrictionOfPointwisePowerBounded_comp /-- A finite rational cover of a rational subdomain. -/ structure Cover (U : AffinoidRationalSubdomain K A) where diff --git a/Rigid/TateAlgebra/Division.lean b/Rigid/TateAlgebra/Division.lean index 3a1cad1..36340b1 100644 --- a/Rigid/TateAlgebra/Division.lean +++ b/Rigid/TateAlgebra/Division.lean @@ -224,11 +224,13 @@ theorem exists_div_quotients_aux [CompleteSpace K] (hr0 : 0 < r) (hr1 : r < 1) (hGle : ∀ i n, ‖MvPowerSeries.coeff n (G i).1‖ ≤ 1) (hGsmall : ∀ i n, ν i ≺[m] n → ‖MvPowerSeries.coeff n (G i).1‖ ≤ r) (F : TateAlgebra K ι) : - ∃ Q : κ → TateAlgebra K ι, ∀ μ : ι →₀ ℕ, (∃ i, ν i ≤ μ) → - MvPowerSeries.coeff μ ((F - ∑ i, Q i * G i : TateAlgebra K ι) : MvPowerSeries ι K) = 0 := by + ∃ Q : κ → TateAlgebra K ι, (∀ i, ‖Q i‖ ≤ ‖F‖) ∧ + ∀ μ : ι →₀ ℕ, (∃ i, ν i ≤ μ) → + MvPowerSeries.coeff μ + ((F - ∑ i, Q i * G i : TateAlgebra K ι) : MvPowerSeries ι K) = 0 := by classical by_cases hF : F = 0 - · exact ⟨0, fun μ _ => by simp [hF]⟩ + · exact ⟨0, fun i => by simp [hF], fun μ _ => by simp [hF]⟩ have hFpos : 0 < ‖F‖ := norm_pos_iff.mpr hF set θ : ℕ → ℝ := fun k => ‖F‖ * r ^ (k + 1) with hθdef have hθpos : ∀ k, 0 < θ k := fun k => mul_pos hFpos (pow_pos hr0 _) @@ -295,6 +297,21 @@ theorem exists_div_quotients_aux [CompleteSpace K] (hr0 : 0 < r) (hr1 : r < 1) rw [hUsucc k] simp _ ≤ ‖F‖ * r ^ k := hle + have hUnorm : ∀ k i, ‖U k i‖ ≤ ‖F‖ := by + intro k + induction k with + | zero => + intro i + simp [hUdef] + | succ k ih => + intro i + have hpow : ‖F‖ * r ^ k ≤ ‖F‖ := by + simpa only [mul_one] using + mul_le_mul_of_nonneg_left (pow_le_one₀ hr0.le hr1.le) (norm_nonneg F) + have hadd : U k i + (U (k + 1) i - U k i) = U (k + 1) i := by abel + rw [← hadd] + exact (IsUltrametricDist.norm_add_le_max _ _).trans + (max_le (ih i) ((hdiff k i).trans hpow)) have hcauchy : ∀ i, CauchySeq fun k => U k i := by intro i apply cauchySeq_of_le_geometric r ‖F‖ hr1 @@ -302,7 +319,9 @@ theorem exists_div_quotients_aux [CompleteSpace K] (hr0 : 0 < r) (hr1 : r < 1) rw [dist_eq_norm, norm_sub_rev] exact hdiff k i choose Qlim hQlim using fun i => cauchySeq_tendsto_of_complete (hcauchy i) - refine ⟨Qlim, fun μ hμ => ?_⟩ + have hQlimNorm : ∀ i, ‖Qlim i‖ ≤ ‖F‖ := fun i => + le_of_tendsto' (hQlim i).norm fun k => hUnorm k i + refine ⟨Qlim, hQlimNorm, fun μ hμ => ?_⟩ -- The corrected series converge, hence so do their coefficients. have h1 : Tendsto (fun k => F - ∑ i, U k i * G i) atTop (𝓝 (F - ∑ i, Qlim i * G i)) := tendsto_const_nhds.sub (tendsto_finsetSum _ fun i _ => (hQlim i).mul tendsto_const_nhds) @@ -375,7 +394,7 @@ theorem exists_forall_coeff_eq_zero_of_leadingDegree_le [CompleteSpace K] _ ≤ Finset.univ.sup' Finset.univ_nonempty fun i => ‖G' i - leadingPart (G' i)‖ := Finset.le_sup' (fun i => ‖G' i - leadingPart (G' i)‖) (Finset.mem_univ i) _ ≤ r := le_max_right _ _ - obtain ⟨Q', hQ'⟩ := exists_div_quotients_aux m hr0 hr1 hG'1 hG'le hGsmall F + obtain ⟨Q', _, hQ'⟩ := exists_div_quotients_aux m hr0 hr1 hG'1 hG'le hGsmall F refine ⟨fun i => (leadingCoeff m (G i))⁻¹ • Q' i, fun μ hμ => ?_⟩ have hsum : ∑ i, ((leadingCoeff m (G i))⁻¹ • Q' i) * G i = ∑ i, Q' i * G' i := Finset.sum_congr rfl fun i _ => by diff --git a/Rigid/TateAlgebra/Domain.lean b/Rigid/TateAlgebra/Domain.lean new file mode 100644 index 0000000..3679481 --- /dev/null +++ b/Rigid/TateAlgebra/Domain.lean @@ -0,0 +1,30 @@ +import Rigid.TateAlgebra.Multiplicative + +set_option linter.style.header false + +/-! +# The Tate algebra is a domain + +Multiplicativity of the Gauss norm immediately rules out zero divisors in a strict Tate algebra +in finitely many variables. This elementary consequence is useful in the minimal-polynomial +step of Noether normalization. +-/ + +universe u v + +namespace Rigid.TateAlgebra + +variable (K : Type u) [NontriviallyNormedField K] [IsUltrametricDist K] +variable (ι : Type v) [Finite ι] + +noncomputable instance noZeroDivisors : NoZeroDivisors (TateAlgebra K ι) where + eq_zero_or_eq_zero_of_mul_eq_zero {f g} hfg := by + have hnorm : ‖f‖ * ‖g‖ = 0 := by + rw [← norm_mul f g, hfg, norm_zero] + exact (mul_eq_zero.mp hnorm).imp norm_eq_zero.mp norm_eq_zero.mp + +noncomputable instance isDomain : IsDomain (TateAlgebra K ι) := by + rw [isDomain_iff_noZeroDivisors_and_nontrivial] + exact ⟨inferInstance, inferInstance⟩ + +end Rigid.TateAlgebra diff --git a/Rigid/TateAlgebra/EmptyVariables.lean b/Rigid/TateAlgebra/EmptyVariables.lean new file mode 100644 index 0000000..bf12fe2 --- /dev/null +++ b/Rigid/TateAlgebra/EmptyVariables.lean @@ -0,0 +1,66 @@ +import Mathlib.RingTheory.IntegralClosure.IntegrallyClosed +import Rigid.TateAlgebra.Basic + +set_option linter.style.header false + +/-! +# Tate algebras with no variables + +The Tate algebra indexed by an empty type is canonically the ground ring. In particular, over a +field it is integrally closed. This is the base case for the Rückert/Weierstrass induction used in +§4.1 of the cited draft. +-/ + +universe u v + +namespace Rigid + +namespace TateAlgebra + +variable {R : Type u} [NormedCommRing R] [IsUltrametricDist R] +variable {iota : Type v} + +/-- Constant coefficient as a ring homomorphism on the Tate algebra. -/ +noncomputable def constantCoeff : TateAlgebra R iota →+* R := + (MvPowerSeries.constantCoeff : MvPowerSeries iota R →+* R).comp + (MvPowerSeries.IsRestricted.subring (fun _ : iota ↦ (1 : ℝ))).subtype + +@[simp] +theorem constantCoeff_apply (f : TateAlgebra R iota) : + constantCoeff f = coeff R iota 0 f := by + change MvPowerSeries.constantCoeff (f : MvPowerSeries iota R) = + MvPowerSeries.coeff 0 (f : MvPowerSeries iota R) + exact (MvPowerSeries.coeff_zero_eq_constantCoeff_apply _).symm + +/-- With no variables, taking the constant coefficient is a ring equivalence. -/ +noncomputable def equivEmpty [IsEmpty iota] : TateAlgebra R iota ≃+* R where + toFun := constantCoeff + invFun := C R iota + left_inv f := by + apply ext + intro n + have hn : n = 0 := Subsingleton.elim _ _ + subst n + simp + right_inv r := by simp + map_add' x y := map_add (constantCoeff) x y + map_mul' x y := map_mul (constantCoeff) x y + +@[simp] +theorem equivEmpty_apply [IsEmpty iota] (f : TateAlgebra R iota) : + equivEmpty f = coeff R iota 0 f := + constantCoeff_apply f + +@[simp] +theorem equivEmpty_symm_apply [IsEmpty iota] (r : R) : + (equivEmpty (R := R) (iota := iota)).symm r = C R iota r := + rfl + +/-- The empty-variable Tate algebra over a field is integrally closed. -/ +theorem isIntegrallyClosed_of_isEmpty {K : Type u} [NormedField K] [IsUltrametricDist K] + {sigma : Type v} [IsEmpty sigma] : IsIntegrallyClosed (TateAlgebra K sigma) := + IsIntegrallyClosed.of_equiv (equivEmpty (R := K) (iota := sigma)).symm + +end TateAlgebra + +end Rigid diff --git a/Rigid/TateAlgebra/FirstVariable.lean b/Rigid/TateAlgebra/FirstVariable.lean new file mode 100644 index 0000000..2a3d141 --- /dev/null +++ b/Rigid/TateAlgebra/FirstVariable.lean @@ -0,0 +1,492 @@ +import Mathlib.Algebra.Polynomial.Degree.IsMonicOfDegree +import Mathlib.Algebra.Polynomial.Eval.Defs +import Mathlib.Data.Finsupp.Fin +import Mathlib.RingTheory.MvPowerSeries.Rename +import Rigid.TateAlgebra.WeierstrassDivision + +set_option linter.style.header false + +open scoped MonomialOrder + +/-! +# A Tate algebra as restricted series in its first variable + +This file relates `TateAlgebra K (Fin (n + 1))` to polynomials in the variable indexed by zero +with coefficients in `TateAlgebra K (Fin n)`. It supplies the polynomial remainder used in +Weierstrass division and in the Rückert quotient comparison. +-/ + +universe u + +namespace Rigid + +namespace TateAlgebra + +open Filter + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- Include the Tate algebra in variables `1, ..., n` into the one in variables `0, ..., n`. -/ +noncomputable def succMap (n : ℕ) : + TateAlgebra K (Fin n) →ₐ[K] TateAlgebra K (Fin (n + 1)) := by + let e : Fin n ↪ Fin (n + 1) := Fin.succEmb n + refine + { toFun := fun p ↦ ⟨MvPowerSeries.rename e p.1, ?_⟩ + map_one' := Subtype.ext (map_one (MvPowerSeries.rename e)) + map_mul' := fun p q ↦ Subtype.ext (map_mul (MvPowerSeries.rename e) p.1 q.1) + map_zero' := Subtype.ext (map_zero (MvPowerSeries.rename e)) + map_add' := fun p q ↦ Subtype.ext (map_add (MvPowerSeries.rename e) p.1 q.1) + commutes' := fun c ↦ Subtype.ext (by simp [algebraMap_apply]) } + change MvPowerSeries.IsRestricted (fun _ : Fin (n + 1) ↦ (1 : ℝ)) + (MvPowerSeries.rename e p.1) + have hrename : Tendsto + (fun x : Fin (n + 1) →₀ ℕ ↦ + ‖MvPowerSeries.coeff x (MvPowerSeries.rename e p.1)‖) cofinite (nhds 0) := by + rw [tendsto_def] + intro s hs + have hzero : (0 : ℝ) ∈ s := mem_of_mem_nhds hs + have hp : {x : Fin n →₀ ℕ | ‖MvPowerSeries.coeff x p.1‖ ∈ s} ∈ cofinite := + (tendsto_norm_coeff_zero K (Fin n) p).eventually hs + rw [mem_cofinite] at hp ⊢ + refine hp.image (Finsupp.embDomain e) |>.subset ?_ + intro x hx + simp only [Set.mem_compl_iff, Set.mem_setOf_eq] at hx ⊢ + by_cases hxr : x ∈ Set.range (Finsupp.embDomain e) + · obtain ⟨y, rfl⟩ := hxr + refine ⟨y, ?_, rfl⟩ + simpa using hx + · exfalso + apply hx + change ‖MvPowerSeries.coeff x (MvPowerSeries.rename e p.1)‖ ∈ s + rw [MvPowerSeries.coeff_rename_eq_zero] + · simpa using hzero + · simpa [Finsupp.embDomain_eq_mapDomain] using hxr + simpa [MvPowerSeries.IsRestricted, Finsupp.prod] using hrename + +@[simp] +theorem succMap_tateVariable (n : ℕ) (i : Fin n) : + succMap K n (tateVariable K (Fin n) i) = tateVariable K (Fin (n + 1)) i.succ := by + apply Subtype.ext + change MvPowerSeries.rename (Fin.succEmb n) + (MvPowerSeries.X i : MvPowerSeries (Fin n) K) = + (MvPowerSeries.X i.succ : MvPowerSeries (Fin (n + 1)) K) + simp + +/-- The coefficient series at a fixed exponent of the first variable. -/ +noncomputable def coeffSlice (n j : ℕ) (f : TateAlgebra K (Fin (n + 1))) : + TateAlgebra K (Fin n) := + ⟨fun μ ↦ MvPowerSeries.coeff (μ.cons j) f.1, by + change MvPowerSeries.IsRestricted (fun _ : Fin n ↦ (1 : ℝ)) _ + rw [MvPowerSeries.IsRestricted] + simp only [one_pow, Finsupp.prod, Finset.prod_const_one, mul_one] + change Tendsto (fun μ : Fin n →₀ ℕ ↦ + ‖MvPowerSeries.coeff (μ.cons j) f.1‖) cofinite (nhds 0) + exact (tendsto_norm_coeff_zero K (Fin (n + 1)) f).comp + (Finsupp.cons_right_injective j).tendsto_cofinite⟩ + +@[simp] +theorem coeff_coeffSlice (n j : ℕ) (f : TateAlgebra K (Fin (n + 1))) + (μ : Fin n →₀ ℕ) : + MvPowerSeries.coeff μ (coeffSlice K n j f).1 = + MvPowerSeries.coeff (μ.cons j) f.1 := + rfl + +private theorem monomial_single_zero_eq_tateVariable_pow (n j : ℕ) : + monomial (Finsupp.single (0 : Fin (n + 1)) j) (1 : K) = + tateVariable K (Fin (n + 1)) 0 ^ j := by + apply Subtype.ext + exact (MvPowerSeries.X_pow_eq (R := K) (0 : Fin (n + 1)) j).symm + +private theorem coe_succMap (n : ℕ) (a : TateAlgebra K (Fin n)) : + ((succMap K n a : TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) = + MvPowerSeries.rename (Fin.succEmb n) a.1 := + rfl + +theorem coeff_succMap_mul_tateVariable_pow (n j : ℕ) + (a : TateAlgebra K (Fin n)) (μ : Fin (n + 1) →₀ ℕ) : + MvPowerSeries.coeff μ + ((succMap K n a * tateVariable K (Fin (n + 1)) 0 ^ j : + TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) = + if j = μ 0 then MvPowerSeries.coeff μ.tail a.1 else 0 := by + rw [mul_comm, ← monomial_single_zero_eq_tateVariable_pow, coeff_monomial_mul] + by_cases hjμ : j = μ 0 + · subst j + rw [if_pos rfl, if_pos (by simp [Finsupp.single_le_iff])] + have hsub : μ - Finsupp.single (0 : Fin (n + 1)) (μ 0) = μ.tail.cons 0 := by + ext i + cases i using Fin.cases with + | zero => simp + | succ i => simp [Finsupp.tail_apply] + rw [hsub] + simp only [one_mul] + rw [coe_succMap] + have hemb : Finsupp.embDomain (Fin.succEmb n) μ.tail = μ.tail.cons 0 := by + ext i + cases i using Fin.cases with + | zero => simp [Finsupp.embDomain_apply] + | succ i => simp [Finsupp.embDomain_apply] + rw [← hemb] + exact MvPowerSeries.coeff_embDomain_rename (Fin.succEmb n) a.1 μ.tail + · rw [if_neg hjμ] + split_ifs with hle + · simp only [one_mul] + rw [coe_succMap] + change MvPowerSeries.coeff (μ - Finsupp.single 0 j) + (MvPowerSeries.rename (Fin.succEmb n) a.1) = 0 + apply MvPowerSeries.coeff_rename_eq_zero + intro hrange + obtain ⟨ν, hν⟩ := hrange + rw [← Finsupp.embDomain_eq_mapDomain] at hν + have hzero := congrArg (fun x : Fin (n + 1) →₀ ℕ ↦ x 0) hν + simp [Finsupp.embDomain_apply] at hzero + have hμj : μ 0 ≤ j := Nat.sub_eq_zero_iff_le.mp (by simpa using hzero.symm) + exact hjμ (Nat.le_antisymm (by simpa [Finsupp.single_le_iff] using hle) hμj) + · rfl + +/-- A series whose first-variable exponents are bounded by `d` is a polynomial of degree less +than `d` in that variable, with coefficients in the remaining-variable Tate algebra. -/ +theorem eq_sum_succMap_coeffSlice_mul_pow {n d : ℕ} + (f : TateAlgebra K (Fin (n + 1))) + (hf : ∀ μ : Fin (n + 1) →₀ ℕ, d ≤ μ 0 → MvPowerSeries.coeff μ f.1 = 0) : + f = ∑ j ∈ Finset.range d, + succMap K n (coeffSlice K n j f) * tateVariable K (Fin (n + 1)) 0 ^ j := by + ext μ + change MvPowerSeries.coeff μ f.1 = MvPowerSeries.coeff μ + ((∑ j ∈ Finset.range d, + succMap K n (coeffSlice K n j f) * tateVariable K (Fin (n + 1)) 0 ^ j : + TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) + rw [show MvPowerSeries.coeff μ + ((∑ j ∈ Finset.range d, + succMap K n (coeffSlice K n j f) * tateVariable K (Fin (n + 1)) 0 ^ j : + TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) = + ∑ j ∈ Finset.range d, MvPowerSeries.coeff μ + ((succMap K n (coeffSlice K n j f) * + tateVariable K (Fin (n + 1)) 0 ^ j : TateAlgebra K (Fin (n + 1))) : + MvPowerSeries (Fin (n + 1)) K) by simp] + simp only [coeff_succMap_mul_tateVariable_pow] + by_cases hμd : d ≤ μ 0 + · rw [hf μ hμd] + symm + apply Finset.sum_eq_zero + intro j hj + rw [if_neg] + exact ne_of_lt (Finset.mem_range.mp hj |>.trans_le hμd) + · have hμlt : μ 0 < d := Nat.lt_of_not_ge hμd + rw [Finset.sum_eq_single (μ 0)] + · rw [if_pos rfl] + exact congrArg (fun ν ↦ MvPowerSeries.coeff ν f.1) (Finsupp.cons_tail μ).symm + · intro j hj hjne + rw [if_neg hjne] + · intro hnot + exact (hnot (Finset.mem_range.mpr hμlt)).elim + +/-- Evaluate a polynomial in the first Tate variable, after including its coefficient algebra in +the remaining variables. -/ +noncomputable def firstVariablePolynomialMap (n : ℕ) : + Polynomial (TateAlgebra K (Fin n)) →+* TateAlgebra K (Fin (n + 1)) := + Polynomial.eval₂RingHom (succMap K n).toRingHom (tateVariable K (Fin (n + 1)) 0) + +@[simp] +theorem firstVariablePolynomialMap_monomial (n j : ℕ) (a : TateAlgebra K (Fin n)) : + firstVariablePolynomialMap K n (Polynomial.monomial j a) = + succMap K n a * tateVariable K (Fin (n + 1)) 0 ^ j := by + simp [firstVariablePolynomialMap] + +theorem firstVariablePolynomialMap_eq_sum (n : ℕ) + (p : Polynomial (TateAlgebra K (Fin n))) : + firstVariablePolynomialMap K n p = + ∑ j ∈ Finset.range (p.natDegree + 1), + succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j := by + calc + firstVariablePolynomialMap K n p = + firstVariablePolynomialMap K n + (∑ j ∈ Finset.range (p.natDegree + 1), + Polynomial.C (p.coeff j) * Polynomial.X ^ j) := by + rw [← p.as_sum_range_C_mul_X_pow] + _ = ∑ j ∈ Finset.range (p.natDegree + 1), + succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j := by + simp [firstVariablePolynomialMap] + +/-- Coefficients of a first-variable polynomial are read by splitting an exponent into its first +coordinate and its tail. -/ +theorem coeff_firstVariablePolynomialMap (n : ℕ) + (p : Polynomial (TateAlgebra K (Fin n))) (μ : Fin (n + 1) →₀ ℕ) : + MvPowerSeries.coeff μ (firstVariablePolynomialMap K n p).1 = + MvPowerSeries.coeff μ.tail (p.coeff (μ 0)).1 := by + rw [firstVariablePolynomialMap_eq_sum] + change MvPowerSeries.coeff μ + ((∑ j ∈ Finset.range (p.natDegree + 1), + succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j : + TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) = + MvPowerSeries.coeff μ.tail (p.coeff (μ 0)).1 + rw [show MvPowerSeries.coeff μ + ((∑ j ∈ Finset.range (p.natDegree + 1), + succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j : + TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) = + ∑ j ∈ Finset.range (p.natDegree + 1), MvPowerSeries.coeff μ + ((succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j : + TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) by simp] + simp only [coeff_succMap_mul_tateVariable_pow] + by_cases hμ : μ 0 < p.natDegree + 1 + · rw [Finset.sum_eq_single (μ 0)] + · rw [if_pos rfl] + · intro j hj hjne + rw [if_neg hjne] + · exact fun h ↦ (h (Finset.mem_range.mpr hμ)).elim + · have hpμ : p.coeff (μ 0) = 0 := by + apply Polynomial.coeff_eq_zero_of_natDegree_lt + omega + rw [hpμ] + change (∑ j ∈ Finset.range (p.natDegree + 1), + if j = μ 0 then MvPowerSeries.coeff μ.tail (p.coeff j).1 else 0) = 0 + apply Finset.sum_eq_zero + intro j hj + rw [if_neg] + intro hjμ + subst j + exact hμ (Finset.mem_range.mp hj) + +/-- Evaluation in the first Tate variable is injective. -/ +theorem firstVariablePolynomialMap_injective (n : ℕ) : + Function.Injective (firstVariablePolynomialMap K n) := by + intro p q hpq + apply Polynomial.ext + intro j + apply Subtype.ext + ext μ + have hcoeff := congrArg + (fun f : TateAlgebra K (Fin (n + 1)) ↦ MvPowerSeries.coeff (μ.cons j) f.1) hpq + simpa [coeff_firstVariablePolynomialMap] using hcoeff + +/-- The polynomial in the first variable obtained from a series known to vanish from exponent +`d` onward. -/ +noncomputable def toFirstVariablePolynomial (n d : ℕ) + (f : TateAlgebra K (Fin (n + 1))) : Polynomial (TateAlgebra K (Fin n)) := + ∑ j ∈ Finset.range d, Polynomial.monomial j (coeffSlice K n j f) + +@[simp] +theorem coeff_toFirstVariablePolynomial (n d j : ℕ) + (f : TateAlgebra K (Fin (n + 1))) : + (toFirstVariablePolynomial K n d f).coeff j = + if j < d then coeffSlice K n j f else 0 := by + classical + simp [toFirstVariablePolynomial, Polynomial.coeff_monomial, eq_comm] + +theorem firstVariablePolynomialMap_toFirstVariablePolynomial {n d : ℕ} + (f : TateAlgebra K (Fin (n + 1))) + (hf : ∀ μ : Fin (n + 1) →₀ ℕ, d ≤ μ 0 → MvPowerSeries.coeff μ f.1 = 0) : + firstVariablePolynomialMap K n (toFirstVariablePolynomial K n d f) = f := by + calc + firstVariablePolynomialMap K n (toFirstVariablePolynomial K n d f) = + ∑ j ∈ Finset.range d, + succMap K n (coeffSlice K n j f) * tateVariable K (Fin (n + 1)) 0 ^ j := by + simp [toFirstVariablePolynomial] + _ = f := (eq_sum_succMap_coeffSlice_mul_pow K f hf).symm + +/-- The monic polynomial represented by a Weierstrass series. -/ +noncomputable def weierstrassPolynomial {n d : ℕ} (w : TateAlgebra K (Fin (n + 1))) : + Polynomial (TateAlgebra K (Fin n)) := + toFirstVariablePolynomial K n (d + 1) w + +theorem firstVariablePolynomialMap_weierstrassPolynomial {n d : ℕ} + {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : + firstVariablePolynomialMap K n (weierstrassPolynomial K (d := d) w) = w := by + apply firstVariablePolynomialMap_toFirstVariablePolynomial + intro μ hμ + apply hw.2.2 μ + · intro heq + subst μ + simp at hμ + · omega + +theorem isMonicOfDegree_weierstrassPolynomial {n d : ℕ} + {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : + Polynomial.IsMonicOfDegree (weierstrassPolynomial K (d := d) w) d := by + rw [Polynomial.isMonicOfDegree_iff] + constructor + · rw [Polynomial.natDegree_le_iff_coeff_eq_zero] + intro j hj + simp only [weierstrassPolynomial, coeff_toFirstVariablePolynomial] + rw [if_neg (by omega)] + · simp only [weierstrassPolynomial, coeff_toFirstVariablePolynomial, Nat.lt_add_one, if_true] + apply Subtype.ext + ext μ + by_cases hμ : μ = 0 + · subst μ + rw [coeff_coeffSlice, Finsupp.cons_zero_eq_single_zero, hw.2.1] + change TateAlgebra.coeff K (Fin n) 0 (1 : TateAlgebra K (Fin n)) = 1 + rw [← map_one (algebraMap K (TateAlgebra K (Fin n))), algebraMap_apply, + TateAlgebra.coeff_zero_C] + · have hconsne : μ.cons d ≠ Finsupp.single (0 : Fin (n + 1)) d := by + intro h + apply hμ + ext i + have hi := congrArg (fun ν : Fin (n + 1) →₀ ℕ ↦ ν i.succ) h + simpa using hi + rw [coeff_coeffSlice, hw.2.2 (μ.cons d) hconsne (by simp)] + change 0 = TateAlgebra.coeff K (Fin n) μ (1 : TateAlgebra K (Fin n)) + rw [← map_one (algebraMap K (TateAlgebra K (Fin n))), algebraMap_apply, + TateAlgebra.coeff_C, if_neg hμ] + +theorem IsWeierstrassOfDegree.norm_eq_one {n d : ℕ} + {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : + ‖w‖ = 1 := by + apply le_antisymm hw.1 + have hle := norm_coeff_le_norm K _ w (Finsupp.single (0 : Fin (n + 1)) d) + rw [hw.2.1, norm_one] at hle + exact hle + +private theorem single_zero_le_of_lex_lt {n d : ℕ} {μ : Fin (n + 1) →₀ ℕ} + (hμ : Finsupp.single 0 d ≺[(MonomialOrder.lex : MonomialOrder (Fin (n + 1)))] μ) : + d ≤ μ 0 := by + rw [MonomialOrder.lex_lt_iff, Finsupp.Lex.lt_iff] at hμ + obtain ⟨j, hj, hjlt⟩ := hμ + by_cases hj0 : j = 0 + · subst j + simpa using hjlt.le + · have h0j : (0 : Fin (n + 1)) < j := Fin.pos_iff_ne_zero.mpr hj0 + have heq := hj 0 h0j + simpa using heq.le + +theorem IsWeierstrassOfDegree.leadingDegree {n d : ℕ} + {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : + leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) w = + Finsupp.single 0 d := by + let ν : Fin (n + 1) →₀ ℕ := Finsupp.single 0 d + have hwne : w ≠ 0 := by + intro h + rw [h] at hw + simp [IsWeierstrassOfDegree] at hw + apply leadingDegree_unique MonomialOrder.lex hwne + · rw [hw.2.1, norm_one, hw.norm_eq_one K] + · intro μ hμ + by_contra hnot + have hlt : ν ≺[(MonomialOrder.lex : MonomialOrder (Fin (n + 1)))] μ := + lt_of_not_ge hnot + have hne : μ ≠ ν := by + intro h + subst μ + exact (lt_irrefl _ hlt) + have hzero := hw.2.2 μ hne (single_zero_le_of_lex_lt hlt) + rw [hzero, norm_zero, hw.norm_eq_one K] at hμ + norm_num at hμ + +/-- A monic first-variable polynomial is Weierstrass exactly when its Tate norm is at most one. -/ +theorem isWeierstrassOfDegree_firstVariablePolynomialMap_iff {n d : ℕ} + {p : Polynomial (TateAlgebra K (Fin n))} + (hp : Polynomial.IsMonicOfDegree p d) : + IsWeierstrassOfDegree d (firstVariablePolynomialMap K n p) ↔ + ‖firstVariablePolynomialMap K n p‖ ≤ 1 := by + constructor + · exact fun h ↦ h.1 + · intro hnorm + refine ⟨hnorm, ?_, ?_⟩ + · rw [coeff_firstVariablePolynomialMap] + have hpd : p.coeff d = 1 := by + have := hp.monic.coeff_natDegree + rwa [hp.natDegree_eq] at this + simp only [Finsupp.single_eq_same] + rw [hpd] + have htail : (Finsupp.single (0 : Fin (n + 1)) d).tail = 0 := by + ext i + simp [Finsupp.tail_apply] + rw [htail] + change TateAlgebra.coeff K (Fin n) 0 (1 : TateAlgebra K (Fin n)) = 1 + rw [← map_one (algebraMap K (TateAlgebra K (Fin n))), algebraMap_apply, + TateAlgebra.coeff_zero_C] + · intro μ hμne hμd + rw [coeff_firstVariablePolynomialMap] + by_cases hμeq : μ 0 = d + · have htail : μ.tail ≠ 0 := by + intro htail + apply hμne + ext i + cases i using Fin.cases with + | zero => simpa using hμeq + | succ i => simpa [Finsupp.tail_apply] using DFunLike.congr_fun htail i + have hpd : p.coeff d = 1 := by + have := hp.monic.coeff_natDegree + rwa [hp.natDegree_eq] at this + rw [hμeq, hpd] + change TateAlgebra.coeff K (Fin n) μ.tail (1 : TateAlgebra K (Fin n)) = 0 + rw [← map_one (algebraMap K (TateAlgebra K (Fin n))), algebraMap_apply, + TateAlgebra.coeff_C, if_neg htail] + · have hdlt : d < μ 0 := lt_of_le_of_ne hμd (Ne.symm hμeq) + rw [Polynomial.coeff_eq_zero_of_natDegree_lt (hp.natDegree_eq ▸ hdlt)] + simp + +/-- Rückert's factor-closure property for Weierstrass polynomials (Definition 4.1.13, R1). -/ +theorem isWeierstrassOfDegree_mul_iff {n d e : ℕ} + {p q : Polynomial (TateAlgebra K (Fin n))} + (hp : Polynomial.IsMonicOfDegree p d) (hq : Polynomial.IsMonicOfDegree q e) : + IsWeierstrassOfDegree (d + e) (firstVariablePolynomialMap K n (p * q)) ↔ + IsWeierstrassOfDegree d (firstVariablePolynomialMap K n p) ∧ + IsWeierstrassOfDegree e (firstVariablePolynomialMap K n q) := by + rw [isWeierstrassOfDegree_firstVariablePolynomialMap_iff K (hp.mul hq), + isWeierstrassOfDegree_firstVariablePolynomialMap_iff K hp, + isWeierstrassOfDegree_firstVariablePolynomialMap_iff K hq] + rw [map_mul, norm_mul] + constructor + · intro hpq + have hp1 : 1 ≤ ‖firstVariablePolynomialMap K n p‖ := by + have hcoeff := norm_coeff_le_norm K _ (firstVariablePolynomialMap K n p) + (Finsupp.single (0 : Fin (n + 1)) d) + rw [coeff_firstVariablePolynomialMap] at hcoeff + have hpd : p.coeff d = 1 := by + have := hp.monic.coeff_natDegree + rwa [hp.natDegree_eq] at this + simp only [Finsupp.single_eq_same] at hcoeff + rw [hpd] at hcoeff + have htail : (Finsupp.single (0 : Fin (n + 1)) d).tail = 0 := by + ext i + simp [Finsupp.tail_apply] + rw [htail] at hcoeff + have hone : MvPowerSeries.coeff 0 (1 : TateAlgebra K (Fin n)).1 = 1 := by + change TateAlgebra.coeff K (Fin n) 0 (1 : TateAlgebra K (Fin n)) = 1 + rw [← map_one (algebraMap K (TateAlgebra K (Fin n))), algebraMap_apply, + TateAlgebra.coeff_zero_C] + rw [hone, norm_one] at hcoeff + exact hcoeff + have hq1 : 1 ≤ ‖firstVariablePolynomialMap K n q‖ := by + have hcoeff := norm_coeff_le_norm K _ (firstVariablePolynomialMap K n q) + (Finsupp.single (0 : Fin (n + 1)) e) + rw [coeff_firstVariablePolynomialMap] at hcoeff + have hqe : q.coeff e = 1 := by + have := hq.monic.coeff_natDegree + rwa [hq.natDegree_eq] at this + simp only [Finsupp.single_eq_same] at hcoeff + rw [hqe] at hcoeff + have htail : (Finsupp.single (0 : Fin (n + 1)) e).tail = 0 := by + ext i + simp [Finsupp.tail_apply] + rw [htail] at hcoeff + have hone : MvPowerSeries.coeff 0 (1 : TateAlgebra K (Fin n)).1 = 1 := by + change TateAlgebra.coeff K (Fin n) 0 (1 : TateAlgebra K (Fin n)) = 1 + rw [← map_one (algebraMap K (TateAlgebra K (Fin n))), algebraMap_apply, + TateAlgebra.coeff_zero_C] + rw [hone, norm_one] at hcoeff + exact hcoeff + constructor + · calc + ‖firstVariablePolynomialMap K n p‖ = + ‖firstVariablePolynomialMap K n p‖ * 1 := (mul_one _).symm + _ ≤ ‖firstVariablePolynomialMap K n p‖ * + ‖firstVariablePolynomialMap K n q‖ := + mul_le_mul_of_nonneg_left hq1 (norm_nonneg _) + _ ≤ 1 := hpq + · calc + ‖firstVariablePolynomialMap K n q‖ = + 1 * ‖firstVariablePolynomialMap K n q‖ := (one_mul _).symm + _ ≤ ‖firstVariablePolynomialMap K n p‖ * + ‖firstVariablePolynomialMap K n q‖ := + mul_le_mul_of_nonneg_right hp1 (norm_nonneg _) + _ ≤ 1 := hpq + · rintro ⟨hp', hq'⟩ + calc + ‖firstVariablePolynomialMap K n p‖ * ‖firstVariablePolynomialMap K n q‖ ≤ + 1 * 1 := mul_le_mul hp' hq' (norm_nonneg _) zero_le_one + _ = 1 := mul_one 1 + +end TateAlgebra + +end Rigid diff --git a/Rigid/TateAlgebra/LeadingMultiplicative.lean b/Rigid/TateAlgebra/LeadingMultiplicative.lean new file mode 100644 index 0000000..2e7759b --- /dev/null +++ b/Rigid/TateAlgebra/LeadingMultiplicative.lean @@ -0,0 +1,210 @@ +import Rigid.TateAlgebra.Complete +import Rigid.TateAlgebra.Multiplicative +import Mathlib.Analysis.Normed.Group.Ultra +import Mathlib.Analysis.SpecificLimits.Normed +import Mathlib.Data.Finsupp.Antidiagonal + +set_option linter.style.header false + +/-! +# Multiplicative leading terms in Tate algebras + +The leading exponent selected by a monomial order is additive under multiplication. We also +record the resulting unit criterion: a nonzero finite-variable Tate series whose leading exponent +is zero is invertible. These are the algebraic inputs needed to pass from Weierstrass division to +Weierstrass preparation. +-/ + +open scoped MonomialOrder + +universe u v + +namespace Rigid + +namespace TateAlgebra + +variable {K : Type u} [NontriviallyNormedField K] [IsUltrametricDist K] +variable {ι : Type v} + +private theorem dominant_leading_pair [DecidableEq ι] (m : MonomialOrder ι) + {f g : TateAlgebra K ι} (hf : f ≠ 0) (hg : g ≠ 0) : + ∀ p ∈ Finset.antidiagonal (leadingDegree m f + leadingDegree m g), + p ≠ (leadingDegree m f, leadingDegree m g) → + ‖MvPowerSeries.coeff p.1 f.1 * MvPowerSeries.coeff p.2 g.1‖ < + ‖MvPowerSeries.coeff (leadingDegree m f) f.1‖ * + ‖MvPowerSeries.coeff (leadingDegree m g) g.1‖ := by + classical + intro p hp hpair + have hpadd : p.1 + p.2 = leadingDegree m f + leadingDegree m g := + Finset.mem_antidiagonal.mp hp + have hsum := congrArg m.toSyn hpadd + simp only [map_add] at hsum + rw [_root_.norm_mul, + show ‖MvPowerSeries.coeff (leadingDegree m f) f.1‖ = ‖f‖ from + norm_leadingCoeff m hf, + show ‖MvPowerSeries.coeff (leadingDegree m g) g.1‖ = ‖g‖ from + norm_leadingCoeff m hg] + rcases lt_trichotomy (m.toSyn (leadingDegree m f)) (m.toSyn p.1) with hfi | heq | hif + · have hflt : ‖MvPowerSeries.coeff p.1 f.1‖ < ‖f‖ := + norm_coeff_lt_of_leadingDegree_lt m hf hfi + calc + ‖MvPowerSeries.coeff p.1 f.1‖ * ‖MvPowerSeries.coeff p.2 g.1‖ ≤ + ‖MvPowerSeries.coeff p.1 f.1‖ * ‖g‖ := + mul_le_mul_of_nonneg_left (norm_coeff_le_norm K ι g p.2) (norm_nonneg _) + _ < ‖f‖ * ‖g‖ := mul_lt_mul_of_pos_right hflt (norm_pos_iff.mpr hg) + · exfalso + apply hpair + have hp1 : p.1 = leadingDegree m f := m.toSyn.injective heq.symm + have hp2 : p.2 = leadingDegree m g := by + apply add_left_cancel (a := leadingDegree m f) + simpa only [hp1] using hpadd + exact Prod.ext hp1 hp2 + · have hgj : m.toSyn (leadingDegree m g) < m.toSyn p.2 := by + by_contra h + have hp2le : m.toSyn p.2 ≤ m.toSyn (leadingDegree m g) := le_of_not_gt h + have hlt := add_lt_add_of_lt_of_le hif hp2le + rw [hsum] at hlt + exact lt_irrefl _ hlt + have hglt : ‖MvPowerSeries.coeff p.2 g.1‖ < ‖g‖ := + norm_coeff_lt_of_leadingDegree_lt m hg hgj + calc + ‖MvPowerSeries.coeff p.1 f.1‖ * ‖MvPowerSeries.coeff p.2 g.1‖ ≤ + ‖f‖ * ‖MvPowerSeries.coeff p.2 g.1‖ := + mul_le_mul_of_nonneg_right (norm_coeff_le_norm K ι f p.1) (norm_nonneg _) + _ < ‖f‖ * ‖g‖ := mul_lt_mul_of_pos_left hglt (norm_pos_iff.mpr hf) + +/-- The coefficient at the sum of the two leading exponents has the product norm. -/ +theorem norm_coeff_add_leadingDegree_mul (m : MonomialOrder ι) + {f g : TateAlgebra K ι} (hf : f ≠ 0) (hg : g ≠ 0) : + ‖MvPowerSeries.coeff (leadingDegree m f + leadingDegree m g) + ((f * g : TateAlgebra K ι) : MvPowerSeries ι K)‖ = ‖f‖ * ‖g‖ := by + classical + rw [show ((f * g : TateAlgebra K ι) : MvPowerSeries ι K) = f.1 * g.1 from rfl] + rw [MvPowerSeries.antidiagonal_dominant (fun a : K ↦ ‖a‖) f.1 g.1 + (leadingDegree m f) (leadingDegree m g) IsUltrametricDist.isNonarchimedean_norm + (fun a b ↦ _root_.norm_mul a b) (fun a ↦ (norm_neg a).symm) + (dominant_leading_pair m hf hg)] + rw [_root_.norm_mul] + simpa only [leadingCoeff] using + congrArg₂ (· * ·) (norm_leadingCoeff m hf) (norm_leadingCoeff m hg) + +/-- Leading exponents are additive under multiplication. -/ +theorem leadingDegree_mul (m : MonomialOrder ι) {f g : TateAlgebra K ι} + (hf : f ≠ 0) (hg : g ≠ 0) : + leadingDegree m (f * g) = leadingDegree m f + leadingDegree m g := by + classical + have hcoeff := norm_coeff_add_leadingDegree_mul m hf hg + have hfg : f * g ≠ 0 := by + intro hzero + have hzeroNorm : 0 = ‖f‖ * ‖g‖ := by simpa [hzero] using hcoeff + exact (mul_pos (norm_pos_iff.mpr hf) (norm_pos_iff.mpr hg)).ne' hzeroNorm.symm + refine leadingDegree_unique m hfg ?_ ?_ + · simpa [norm_mul_of_monomialOrder m] using hcoeff + · intro n hn + have hcoeffn : ‖MvPowerSeries.coeff n + ((f * g : TateAlgebra K ι) : MvPowerSeries ι K)‖ = ‖f‖ * ‖g‖ := by + apply le_antisymm + · exact (norm_coeff_le_norm K ι (f * g) n).trans_eq + (norm_mul_of_monomialOrder m f g) + · simpa [norm_mul_of_monomialOrder m] using hn + rw [show ((f * g : TateAlgebra K ι) : MvPowerSeries ι K) = f.1 * g.1 from rfl, + MvPowerSeries.coeff_mul] at hcoeffn + have hanti : (Finset.antidiagonal n).Nonempty := + ⟨(0, n), Finset.mem_antidiagonal.mpr (zero_add n)⟩ + obtain ⟨p, hp, hpsum⟩ := + IsUltrametricDist.exists_norm_finsetSum_le_of_nonempty hanti + (fun p : (ι →₀ ℕ) × (ι →₀ ℕ) ↦ + MvPowerSeries.coeff p.1 f.1 * MvPowerSeries.coeff p.2 g.1) + have hpterm : ‖MvPowerSeries.coeff p.1 f.1 * MvPowerSeries.coeff p.2 g.1‖ = + ‖f‖ * ‖g‖ := by + apply le_antisymm + · rw [_root_.norm_mul] + exact mul_le_mul (norm_coeff_le_norm K ι f p.1) (norm_coeff_le_norm K ι g p.2) + (norm_nonneg _) (norm_nonneg _) + · rw [hcoeffn] at hpsum + exact hpsum + have hp1 : ‖MvPowerSeries.coeff p.1 f.1‖ = ‖f‖ := by + apply le_antisymm (norm_coeff_le_norm K ι f p.1) + by_contra hlt + have hlt' : ‖MvPowerSeries.coeff p.1 f.1‖ < ‖f‖ := lt_of_not_ge hlt + have := mul_lt_mul_of_pos_right hlt' (norm_pos_iff.mpr hg) + exact (not_le_of_gt this) (by + rw [← hpterm, _root_.norm_mul] + exact mul_le_mul_of_nonneg_left (norm_coeff_le_norm K ι g p.2) (norm_nonneg _)) + have hp2 : ‖MvPowerSeries.coeff p.2 g.1‖ = ‖g‖ := by + apply le_antisymm (norm_coeff_le_norm K ι g p.2) + by_contra hlt + have hlt' : ‖MvPowerSeries.coeff p.2 g.1‖ < ‖g‖ := lt_of_not_ge hlt + have := mul_lt_mul_of_pos_left hlt' (norm_pos_iff.mpr hf) + exact (not_le_of_gt this) (by + rw [← hpterm, _root_.norm_mul] + exact mul_le_mul_of_nonneg_right (norm_coeff_le_norm K ι f p.1) (norm_nonneg _)) + have hp1le : m.toSyn p.1 ≤ m.toSyn (leadingDegree m f) := + le_leadingDegree m hf hp1.ge + have hp2le : m.toSyn p.2 ≤ m.toSyn (leadingDegree m g) := + le_leadingDegree m hg hp2.ge + have hpadd : p.1 + p.2 = n := Finset.mem_antidiagonal.mp hp + calc + m.toSyn n = m.toSyn (p.1 + p.2) := congrArg m.toSyn hpadd.symm + _ = m.toSyn p.1 + m.toSyn p.2 := map_add m.toSyn p.1 p.2 + _ ≤ m.toSyn (leadingDegree m f) + m.toSyn (leadingDegree m g) := + add_le_add hp1le hp2le + _ = m.toSyn (leadingDegree m f + leadingDegree m g) := + (map_add m.toSyn _ _).symm + +/-- A nonzero finite-variable Tate series whose leading exponent is zero is a unit. -/ +theorem isUnit_of_leadingDegree_eq_zero [Finite ι] [CompleteSpace K] + (m : MonomialOrder ι) {f : TateAlgebra K ι} (hf : f ≠ 0) + (hdeg : leadingDegree m f = 0) : IsUnit f := by + classical + let a : K := MvPowerSeries.coeff 0 f.1 + have haNorm : ‖a‖ = ‖f‖ := by + change ‖MvPowerSeries.coeff 0 f.1‖ = ‖f‖ + rw [← hdeg] + exact norm_leadingCoeff m hf + have ha : a ≠ 0 := by + rw [← norm_ne_zero_iff, haNorm] + exact norm_ne_zero_iff.mpr hf + let c : TateAlgebra K ι := C K ι a + have hcNorm : ‖c‖ = ‖f‖ := by simp [c, haNorm] + have hsupport : leadingSupport f = {0} := by + ext n + simp only [Finset.mem_singleton] + constructor + · intro hn + have hnle := le_leadingDegree m hf ((mem_leadingSupport hf).mp hn) + rw [hdeg] at hnle + have hzero : m.toSyn 0 ≤ m.toSyn n := by + rw [map_zero] + exact m.zero_le (m.toSyn n) + exact m.toSyn.injective (le_antisymm hnle hzero) + · intro hn + subst n + exact (mem_leadingSupport hf).mpr (by rw [haNorm]) + have hleading : leadingPart f = c := by + rw [leadingPart, hsupport] + simp only [Finset.sum_singleton, c, a] + apply Subtype.ext + exact MvPowerSeries.monomial_zero_eq_C_apply _ + have hsmall : ‖f - c‖ < ‖c‖ := by + rw [hcNorm, ← hleading] + exact norm_sub_leadingPart_lt hf + let x : TateAlgebra K ι := -(C K ι a⁻¹ * (f - c)) + have hx : ‖x‖ < 1 := by + dsimp only [x] + rw [norm_neg, norm_mul, norm_C, norm_inv] + rw [haNorm, inv_mul_lt_one₀ (norm_pos_iff.mpr hf)] + rwa [hcNorm] at hsmall + have hfactor : f = c * (1 - x) := by + dsimp only [x] + rw [sub_neg_eq_add, mul_add, mul_one] + dsimp only [c] + rw [← mul_assoc, ← map_mul, mul_inv_cancel₀ ha, map_one, one_mul] + abel + rw [hfactor] + exact IsUnit.mul (IsUnit.map (C K ι) (isUnit_iff_ne_zero.mpr ha)) + (isUnit_one_sub_of_norm_lt_one hx) + +end TateAlgebra + +end Rigid diff --git a/Rigid/TateAlgebra/Ruckert.lean b/Rigid/TateAlgebra/Ruckert.lean new file mode 100644 index 0000000..3b70fb2 --- /dev/null +++ b/Rigid/TateAlgebra/Ruckert.lean @@ -0,0 +1,225 @@ +import Mathlib.Algebra.Polynomial.Div +import Mathlib.RingTheory.Ideal.Maximal +import Mathlib.RingTheory.Ideal.Quotient.Operations +import Rigid.TateAlgebra.FirstVariable + +set_option linter.style.header false + +/-! +# Rückert properties for strict Tate algebras + +This file proves the quotient comparison in Definition 4.1.13 (R3). A monic polynomial in the +first variable and the corresponding Weierstrass element define isomorphic quotient rings. The +proof is the algebraic form of Weierstrass finiteness in §1.9: use polynomial division on the +source and Weierstrass division on the target. +-/ + +open scoped MonomialOrder + +universe u + +namespace Rigid + +namespace TateAlgebra + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +private theorem isWeierstrass_ne_zero {n d : ℕ} + {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : w ≠ 0 := by + intro h + have hnorm := hw.norm_eq_one K + rw [h, norm_zero] at hnorm + norm_num at hnorm + +/-- The first coordinate of the leading exponent of a first-variable polynomial is at most its +polynomial degree. -/ +theorem leadingDegree_zero_le_natDegree_firstVariablePolynomialMap {n : ℕ} + {p : Polynomial (TateAlgebra K (Fin n))} (hp : p ≠ 0) : + (leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) + (firstVariablePolynomialMap K n p)) 0 ≤ p.natDegree := by + have hmap : firstVariablePolynomialMap K n p ≠ 0 := + fun h ↦ hp (firstVariablePolynomialMap_injective K n (by simpa using h)) + by_contra hnot + have hlt : p.natDegree < + (leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) + (firstVariablePolynomialMap K n p)) 0 := Nat.lt_of_not_ge hnot + have hcoeffzero : MvPowerSeries.coeff + (leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) + (firstVariablePolynomialMap K n p)) + (firstVariablePolynomialMap K n p).1 = 0 := by + rw [coeff_firstVariablePolynomialMap] + rw [Polynomial.coeff_eq_zero_of_natDegree_lt hlt] + rfl + have hnorm := norm_leadingCoeff + (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) hmap + rw [leadingCoeff, hcoeffzero, norm_zero] at hnorm + exact (norm_pos_iff.mpr hmap).ne' hnorm.symm + +/-- A polynomial of degree below a Weierstrass polynomial cannot become a nonzero multiple of +that Weierstrass element in the Tate algebra. -/ +theorem eq_zero_of_natDegree_lt_of_firstVariablePolynomialMap_dvd_weierstrass + {n d : ℕ} {W r : Polynomial (TateAlgebra K (Fin n))} + {w : TateAlgebra K (Fin (n + 1))} + (hW : Polynomial.IsMonicOfDegree W d) + (hw : IsWeierstrassOfDegree d w) + (hWw : firstVariablePolynomialMap K n W = w) + (hrdeg : r.natDegree < d) + (hrdvd : w ∣ firstVariablePolynomialMap K n r) : r = 0 := by + by_contra hr + obtain ⟨q, hq⟩ := hrdvd + have hmapr : firstVariablePolynomialMap K n r ≠ 0 := + fun h ↦ hr (firstVariablePolynomialMap_injective K n (by simpa using h)) + have hq0 : q ≠ 0 := by + intro h + rw [h, mul_zero] at hq + exact hmapr hq + have hw0 := isWeierstrass_ne_zero K hw + have hlead := leadingDegree_mul + (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) hw0 hq0 + rw [← hWw, hWw, ← hq] at hlead + have hfirst : d ≤ + (leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) + (firstVariablePolynomialMap K n r)) 0 := by + rw [hlead, hw.leadingDegree K] + simp + have hupper := leadingDegree_zero_le_natDegree_firstVariablePolynomialMap K hr + omega + +/-- The map to the quotient by a Weierstrass element. -/ +noncomputable def weierstrassQuotientMap {n : ℕ} + (w : TateAlgebra K (Fin (n + 1))) : + Polynomial (TateAlgebra K (Fin n)) →+* + TateAlgebra K (Fin (n + 1)) ⧸ Ideal.span ({w} : Set (TateAlgebra K (Fin (n + 1)))) := + (Ideal.Quotient.mk _).comp (firstVariablePolynomialMap K n) + +theorem ker_weierstrassQuotientMap {n d : ℕ} + {W : Polynomial (TateAlgebra K (Fin n))} + {w : TateAlgebra K (Fin (n + 1))} + (hW : Polynomial.IsMonicOfDegree W d) + (hw : IsWeierstrassOfDegree d w) + (hWw : firstVariablePolynomialMap K n W = w) : + RingHom.ker (weierstrassQuotientMap K w) = Ideal.span ({W} : Set _) := by + ext p + constructor + · intro hp + rw [RingHom.mem_ker] at hp + change Ideal.Quotient.mk (Ideal.span ({w} : Set _)) + (firstVariablePolynomialMap K n p) = 0 at hp + have hpdiv : w ∣ firstVariablePolynomialMap K n p := + (Ideal.Quotient.eq_zero_iff_dvd w _).mp hp + let r := p %ₘ W + let s := p /ₘ W + have hdecomp : r + W * s = p := Polynomial.modByMonic_add_div p W + have hrdiv : w ∣ firstVariablePolynomialMap K n r := by + obtain ⟨q, hq⟩ := hpdiv + refine ⟨q - firstVariablePolynomialMap K n s, ?_⟩ + have hmapdecomp := congrArg (firstVariablePolynomialMap K n) hdecomp + simp only [map_add, map_mul] at hmapdecomp + rw [hWw] at hmapdecomp + rw [hq] at hmapdecomp + calc + firstVariablePolynomialMap K n r = + w * q - w * firstVariablePolynomialMap K n s := by + rw [← hmapdecomp] + abel + _ = w * (q - firstVariablePolynomialMap K n s) := by ring + have hrzero : r = 0 := by + by_cases hWone : W = 1 + · simp [r, hWone] + · apply eq_zero_of_natDegree_lt_of_firstVariablePolynomialMap_dvd_weierstrass + K hW hw hWw + · dsimp only [r] + simpa [hW.natDegree_eq] using + Polynomial.natDegree_modByMonic_lt p hW.monic hWone + · exact hrdiv + rw [Ideal.mem_span_singleton] + refine ⟨s, ?_⟩ + rw [← hdecomp, hrzero, zero_add] + · intro hp + rw [Ideal.mem_span_singleton] at hp + rw [RingHom.mem_ker] + change Ideal.Quotient.mk (Ideal.span ({w} : Set _)) + (firstVariablePolynomialMap K n p) = 0 + apply (Ideal.Quotient.eq_zero_iff_dvd w _).mpr + rw [← hWw] + exact map_dvd (firstVariablePolynomialMap K n) hp + +theorem weierstrassQuotientMap_surjective {n d : ℕ} + {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : + Function.Surjective (weierstrassQuotientMap K w) := by + intro x + obtain ⟨f, rfl⟩ := Ideal.Quotient.mk_surjective x + have hw0 := isWeierstrass_ne_zero K hw + obtain ⟨q, r, hf, hr⟩ := + exists_quotient_remainder_of_leadingDegree_eq_single_zero w hw0 + (hw.leadingDegree K) f + let p := toFirstVariablePolynomial K n d r + have hpr : firstVariablePolynomialMap K n p = r := + firstVariablePolynomialMap_toFirstVariablePolynomial K r hr + refine ⟨p, ?_⟩ + change Ideal.Quotient.mk (Ideal.span ({w} : Set _)) + (firstVariablePolynomialMap K n p) = + Ideal.Quotient.mk (Ideal.span ({w} : Set _)) f + rw [hpr, hf] + simp only [map_add, map_mul, Ideal.Quotient.mk_singleton_self, mul_zero, zero_add] + +/-- Rückert's quotient comparison (Definition 4.1.13, R3). -/ +noncomputable def weierstrassQuotientEquiv {n d : ℕ} + {W : Polynomial (TateAlgebra K (Fin n))} + {w : TateAlgebra K (Fin (n + 1))} + (hW : Polynomial.IsMonicOfDegree W d) + (hw : IsWeierstrassOfDegree d w) + (hWw : firstVariablePolynomialMap K n W = w) : + (Polynomial (TateAlgebra K (Fin n)) ⧸ Ideal.span ({W} : Set _)) ≃+* + (TateAlgebra K (Fin (n + 1)) ⧸ Ideal.span ({w} : Set _)) := + (Ideal.quotEquivOfEq (ker_weierstrassQuotientMap K hW hw hWw).symm).trans + ((weierstrassQuotientMap K w).quotientKerEquivOfSurjective + (weierstrassQuotientMap_surjective K hw)) + +/-- Prime monic polynomials remain prime after evaluation in the first Tate variable. -/ +theorem prime_firstVariablePolynomialMap_of_prime {n d : ℕ} + {W : Polynomial (TateAlgebra K (Fin n))} + {w : TateAlgebra K (Fin (n + 1))} + (hW : Polynomial.IsMonicOfDegree W d) + (hw : IsWeierstrassOfDegree d w) + (hWw : firstVariablePolynomialMap K n W = w) + (hprime : Prime W) : Prime w := by + have hw0 := isWeierstrass_ne_zero K hw + rw [← Ideal.span_singleton_prime hw0] + rw [Ideal.isPrime_iff] + let φ := weierstrassQuotientMap K w + have hker : RingHom.ker φ = Ideal.span ({W} : Set _) := + ker_weierstrassQuotientMap K hW hw hWw + have hsource : (Ideal.span ({W} : Set _)).IsPrime := + Ideal.isPrime_span_singleton_of_prime hprime + have hsurj : Function.Surjective φ := weierstrassQuotientMap_surjective K hw + constructor + · intro htop + apply hsource.ne_top + rw [← hker, Ideal.eq_top_iff_one, RingHom.mem_ker] + change Ideal.Quotient.mk (Ideal.span ({w} : Set _)) + (firstVariablePolynomialMap K n (1 : Polynomial (TateAlgebra K (Fin n)))) = 0 + rw [map_one, htop] + exact Subsingleton.elim _ _ + · intro a b hab + obtain ⟨p, hp⟩ := hsurj + (Ideal.Quotient.mk (Ideal.span ({w} : Set _)) a) + obtain ⟨q, hq⟩ := hsurj + (Ideal.Quotient.mk (Ideal.span ({w} : Set _)) b) + have hpq : p * q ∈ RingHom.ker φ := by + rw [RingHom.mem_ker, map_mul, hp, hq, ← map_mul] + exact Ideal.Quotient.eq_zero_iff_mem.mpr hab + rw [hker] at hpq + rcases hsource.mem_or_mem hpq with hpW | hqW + · left + apply Ideal.Quotient.eq_zero_iff_mem.mp + rw [← hp] + exact RingHom.mem_ker.mp (hker ▸ hpW) + · right + apply Ideal.Quotient.eq_zero_iff_mem.mp + rw [← hq] + exact RingHom.mem_ker.mp (hker ▸ hqW) + +end TateAlgebra + +end Rigid diff --git a/Rigid/TateAlgebra/UniqueFactorization.lean b/Rigid/TateAlgebra/UniqueFactorization.lean new file mode 100644 index 0000000..8e66810 --- /dev/null +++ b/Rigid/TateAlgebra/UniqueFactorization.lean @@ -0,0 +1,129 @@ +import Mathlib.RingTheory.Noetherian.UniqueFactorizationDomain +import Mathlib.RingTheory.Polynomial.RationalRoot +import Mathlib.RingTheory.Polynomial.UniqueFactorization +import Rigid.TateAlgebra.Domain +import Rigid.TateAlgebra.EmptyVariables +import Rigid.TateAlgebra.Noetherian +import Rigid.TateAlgebra.Ruckert +import Rigid.TateAlgebra.WeierstrassPreparation + +set_option linter.style.header false + +/-! +# Unique factorization in strict Tate algebras + +This is the Rückert induction of Proposition 4.1.14 and Theorem 4.1.15 in the cited draft. +The induction step uses Weierstrass preparation (R2), factor closure (R1), and the quotient +comparison / prime transfer (R3). +-/ + +universe u + +namespace Rigid + +namespace TateAlgebra + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- A monic polynomial whose first-variable image is a Weierstrass unit has degree zero. -/ +theorem natDegree_eq_zero_of_isUnit_firstVariablePolynomialMap {n d : ℕ} + {p : Polynomial (TateAlgebra K (Fin n))} + (hp : Polynomial.IsMonicOfDegree p d) + (hweier : IsWeierstrassOfDegree d (firstVariablePolynomialMap K n p)) + (hunit : IsUnit (firstVariablePolynomialMap K n p)) : + p.natDegree = 0 := by + have hpunit : IsUnit p := by + rw [isUnit_iff_dvd_one, ← Ideal.mem_span_singleton] + rw [← ker_weierstrassQuotientMap K hp hweier rfl, RingHom.mem_ker] + change Ideal.Quotient.mk + (Ideal.span ({firstVariablePolynomialMap K n p} : + Set (TateAlgebra K (Fin (n + 1))))) + (firstVariablePolynomialMap K n (1 : Polynomial (TateAlgebra K (Fin n)))) = 0 + rw [map_one] + exact (Ideal.Quotient.eq_zero_iff_dvd _ _).mpr (isUnit_iff_dvd_one.mp hunit) + rw [hp.monic.eq_one_of_isUnit hpunit, Polynomial.natDegree_one] + +/-- The Rückert induction step: adjoining one restricted variable preserves unique +factorization. -/ +theorem uniqueFactorizationMonoidSucc (n : ℕ) + [UniqueFactorizationMonoid (TateAlgebra K (Fin n))] : + UniqueFactorizationMonoid (TateAlgebra K (Fin (n + 1))) := + { (IsNoetherianRing.wfDvdMonoid : + WfDvdMonoid (TateAlgebra K (Fin (n + 1)))) with + irreducible_iff_prime := by + intro f + constructor + · intro hf + obtain ⟨ψ, d, e, w, he, hw, hψf⟩ := + exists_algEquiv_isUnit_mul_isWeierstrassOfDegree f hf.ne_zero + let W : Polynomial (TateAlgebra K (Fin n)) := + weierstrassPolynomial K (d := d) w + have hW : Polynomial.IsMonicOfDegree W d := + isMonicOfDegree_weierstrassPolynomial K hw + have hWw : firstVariablePolynomialMap K n W = w := + firstVariablePolynomialMap_weierstrassPolynomial K hw + have hψirr : Irreducible (ψ f) := + (MulEquiv.irreducible_iff ψ.toRingEquiv.toMulEquiv).mpr hf + have hwirr : Irreducible w := by + rw [hψf] at hψirr + exact (irreducible_isUnit_mul he).mp hψirr + have hWirr : Irreducible W := by + rw [hW.monic.irreducible_iff_natDegree] + constructor + · intro hWone + apply hf.not_isUnit + have hwone : w = 1 := by + rw [← hWw, hWone, map_one] + have hψunit : IsUnit (ψ f) := by + rw [hψf, hwone, mul_one] + exact he + have hback := hψunit.map ψ.symm.toAlgHom + simpa using hback + · intro p q hp hq hpq + let hpdeg : Polynomial.IsMonicOfDegree p p.natDegree := ⟨rfl, hp⟩ + let hqdeg : Polynomial.IsMonicOfDegree q q.natDegree := ⟨rfl, hq⟩ + have hdeg : p.natDegree + q.natDegree = d := by + rw [← hp.natDegree_mul hq, hpq, hW.natDegree_eq] + have hpqweier : + IsWeierstrassOfDegree (p.natDegree + q.natDegree) + (firstVariablePolynomialMap K n (p * q)) := by + rw [hdeg, hpq, hWw] + exact hw + obtain ⟨hpweier, hqweier⟩ := + (isWeierstrassOfDegree_mul_iff K hpdeg hqdeg).mp hpqweier + have hfactor : + w = firstVariablePolynomialMap K n p * + firstVariablePolynomialMap K n q := by + rw [← hWw, ← map_mul, hpq] + rcases hwirr.isUnit_or_isUnit hfactor with hpunit | hqunit + · left + exact natDegree_eq_zero_of_isUnit_firstVariablePolynomialMap + K hpdeg hpweier hpunit + · right + exact natDegree_eq_zero_of_isUnit_firstVariablePolynomialMap + K hqdeg hqweier hqunit + have hWprime : Prime W := + UniqueFactorizationMonoid.irreducible_iff_prime.mp hWirr + have hwprime : Prime w := + prime_firstVariablePolynomialMap_of_prime K hW hw hWw hWprime + have hψprime : Prime (ψ f) := by + rw [hψf] + exact (prime_isUnit_mul he).mpr hwprime + exact (MulEquiv.prime_iff ψ.toRingEquiv.toMulEquiv).mp hψprime + · exact Prime.irreducible } + +/-- Every finite-variable strict Tate algebra over the ground field is a unique factorization +monoid. -/ +noncomputable instance uniqueFactorizationMonoid (n : ℕ) : + UniqueFactorizationMonoid (TateAlgebra K (Fin n)) := by + induction n with + | zero => + exact (equivEmpty (R := K) (iota := Fin 0)).toMulEquiv.symm.uniqueFactorizationMonoid + (inferInstance : UniqueFactorizationMonoid K) + | succ n ih => + letI : UniqueFactorizationMonoid (TateAlgebra K (Fin n)) := ih + exact uniqueFactorizationMonoidSucc K n + +end TateAlgebra + +end Rigid diff --git a/Rigid/TateAlgebra/WeierstrassDivision.lean b/Rigid/TateAlgebra/WeierstrassDivision.lean new file mode 100644 index 0000000..9f89225 --- /dev/null +++ b/Rigid/TateAlgebra/WeierstrassDivision.lean @@ -0,0 +1,203 @@ +import Rigid.TateAlgebra.Division +import Rigid.TateAlgebra.LeadingMultiplicative + +set_option linter.style.header false + +/-! +# Weierstrass division for a distinguished leading monomial + +This file exposes the one-divisor consequence of the general Tate-algebra division algorithm. +When the leading monomial of `g` is a pure power of the first variable, every series has a +quotient by `g` and a remainder whose coefficients in that variable vanish from that degree on. +It is the division input to the Weierstrass preparation and Rückert arguments in §4.1 of the +cited draft. +-/ + +open scoped MonomialOrder + +universe u + +namespace Rigid + +namespace TateAlgebra + +variable {K : Type u} [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- One-divisor Weierstrass division for a series whose leading degree is a pure power of the +first variable. -/ +theorem exists_quotient_remainder_of_leadingDegree_eq_single_zero {n d : ℕ} + (g : TateAlgebra K (Fin (n + 1))) (hg : g ≠ 0) + (hgd : leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) g = + Finsupp.single 0 d) (f : TateAlgebra K (Fin (n + 1))) : + ∃ q r : TateAlgebra K (Fin (n + 1)), f = q * g + r ∧ + ∀ μ : Fin (n + 1) →₀ ℕ, d ≤ μ 0 → MvPowerSeries.coeff μ r.1 = 0 := by + obtain ⟨Q, hQ⟩ := exists_forall_coeff_eq_zero_of_leadingDegree_le + (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) (fun _ : Fin 1 ↦ g) + (fun _ ↦ hg) f + let q := Q 0 + let r := f - q * g + refine ⟨q, r, ?_, ?_⟩ + · dsimp only [r] + abel + · intro μ hμ + have hdiv : leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) g ≤ μ := by + rw [hgd] + simpa [Finsupp.single_le_iff] using hμ + simpa only [q, r, Fin.sum_univ_one] using hQ μ ⟨0, hdiv⟩ + +/-- Norm-controlled one-divisor division after normalizing the leading coefficient to one. -/ +theorem exists_quotient_remainder_norm_le_of_leadingCoeff_eq_one {n d : ℕ} + (g : TateAlgebra K (Fin (n + 1))) (hg : g ≠ 0) + (hgd : leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) g = + Finsupp.single 0 d) + (hglc : leadingCoeff (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) g = 1) + (f : TateAlgebra K (Fin (n + 1))) : + ∃ q r : TateAlgebra K (Fin (n + 1)), ‖q‖ ≤ ‖f‖ ∧ f = q * g + r ∧ + ∀ μ : Fin (n + 1) →₀ ℕ, d ≤ μ 0 → MvPowerSeries.coeff μ r.1 = 0 := by + classical + let m : MonomialOrder (Fin (n + 1)) := MonomialOrder.lex + let G : Fin 1 → TateAlgebra K (Fin (n + 1)) := fun _ ↦ g + let ν : Fin 1 → Fin (n + 1) →₀ ℕ := fun _ ↦ Finsupp.single 0 d + have hgnorm : ‖g‖ = 1 := by + rw [← norm_leadingCoeff m hg, hglc] + exact norm_one + have hG1 : ∀ i, MvPowerSeries.coeff (ν i) (G i).1 = 1 := by + intro i + change MvPowerSeries.coeff (Finsupp.single 0 d) g.1 = 1 + rw [← hgd] + exact hglc + have hGle : ∀ i μ, ‖MvPowerSeries.coeff μ (G i).1‖ ≤ 1 := by + intro i μ + exact (norm_coeff_le_norm K _ g μ).trans_eq hgnorm + let ρ : ℝ := max 2⁻¹ ‖g - leadingPart g‖ + have hρ0 : 0 < ρ := lt_of_lt_of_le (by norm_num) (le_max_left _ _) + have hρ1 : ρ < 1 := by + exact max_lt (by norm_num) ((norm_sub_leadingPart_lt hg).trans_eq hgnorm) + have hGsmall : ∀ i μ, ν i ≺[m] μ → + ‖MvPowerSeries.coeff μ (G i).1‖ ≤ ρ := by + intro i μ hμ + exact (norm_coeff_le_of_notMem_leadingSupport g + (notMem_leadingSupport_of_leadingDegree_lt m hg (by simpa [ν, m, hgd] using hμ))).trans + (le_max_right _ _) + obtain ⟨Q, hQnorm, hQrem⟩ := + exists_div_quotients_aux m hρ0 hρ1 hG1 hGle hGsmall f + let q := Q 0 + let r := f - q * g + refine ⟨q, r, hQnorm 0, ?_, ?_⟩ + · dsimp only [r] + abel + · intro μ hμ + have hdiv : ∃ i, ν i ≤ μ := ⟨0, by simpa [ν, Finsupp.single_le_iff] using hμ⟩ + simpa only [q, r, G, Fin.sum_univ_one] using hQrem μ hdiv + +/-- A Tate series which is a monic polynomial of degree `d` in the first variable, with Gauss +norm at most one. -/ +def IsWeierstrassOfDegree {n : ℕ} (d : ℕ) (w : TateAlgebra K (Fin (n + 1))) : Prop := + ‖w‖ ≤ 1 ∧ MvPowerSeries.coeff (Finsupp.single 0 d) w.1 = 1 ∧ + ∀ μ : Fin (n + 1) →₀ ℕ, μ ≠ Finsupp.single 0 d → d ≤ μ 0 → + MvPowerSeries.coeff μ w.1 = 0 + +private theorem single_zero_le_of_lex_lt {n d : ℕ} {μ : Fin (n + 1) →₀ ℕ} + (hμ : Finsupp.single 0 d ≺[(MonomialOrder.lex : MonomialOrder (Fin (n + 1)))] μ) : + d ≤ μ 0 := by + rw [MonomialOrder.lex_lt_iff, Finsupp.Lex.lt_iff] at hμ + obtain ⟨j, hj, hjlt⟩ := hμ + by_cases hj0 : j = 0 + · subst j + simpa using hjlt.le + · have h0j : (0 : Fin (n + 1)) < j := Fin.pos_iff_ne_zero.mpr hj0 + have heq := hj 0 h0j + simpa using heq.le + +/-- Weierstrass preparation for a series already normalized to have a pure first-variable leading +monomial and leading coefficient one. -/ +theorem exists_isUnit_mul_isWeierstrassOfDegree_of_leadingCoeff_eq_one {n d : ℕ} + (g : TateAlgebra K (Fin (n + 1))) (hg : g ≠ 0) + (hgd : leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) g = + Finsupp.single 0 d) + (hglc : leadingCoeff (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) g = 1) : + ∃ e w : TateAlgebra K (Fin (n + 1)), IsUnit e ∧ IsWeierstrassOfDegree d w ∧ + g = e * w := by + classical + let m : MonomialOrder (Fin (n + 1)) := MonomialOrder.lex + let ν : Fin (n + 1) →₀ ℕ := Finsupp.single 0 d + let F : TateAlgebra K (Fin (n + 1)) := monomial ν 1 + obtain ⟨q, r, hqnorm, hF, hr⟩ := + exists_quotient_remainder_norm_le_of_leadingCoeff_eq_one g hg hgd hglc F + let w : TateAlgebra K (Fin (n + 1)) := F - r + have hgnorm : ‖g‖ = 1 := by + rw [← norm_leadingCoeff m hg, hglc] + exact norm_one + have hFnorm : ‖F‖ = 1 := by simp [F] + have hqg : q * g = w := by + dsimp only [w] + rw [hF] + abel + have hwnorm : ‖w‖ ≤ 1 := by + rw [← hqg, norm_mul, hgnorm, mul_one] + exact hqnorm.trans_eq hFnorm + have hwcoeff : MvPowerSeries.coeff ν w.1 = 1 := by + rw [show w = F - r from rfl] + change MvPowerSeries.coeff ν (F.1 - r.1) = 1 + rw [map_sub, hr ν (by simp [ν])] + simp [F, ν] + have hwhigh : ∀ μ : Fin (n + 1) →₀ ℕ, μ ≠ ν → d ≤ μ 0 → + MvPowerSeries.coeff μ w.1 = 0 := by + intro μ hμne hμd + rw [show w = F - r from rfl] + change MvPowerSeries.coeff μ (F.1 - r.1) = 0 + rw [map_sub, hr μ hμd] + simp only [sub_zero] + rw [show F.1 = MvPowerSeries.monomial ν 1 from rfl, + MvPowerSeries.coeff_monomial, if_neg hμne] + have hwne : w ≠ 0 := by + intro hw + rw [hw] at hwcoeff + simp at hwcoeff + have hwnormeq : ‖w‖ = 1 := by + apply le_antisymm hwnorm + have hle := norm_coeff_le_norm K _ w ν + rw [hwcoeff, norm_one] at hle + exact hle + have hwdeg : leadingDegree m w = ν := by + apply leadingDegree_unique m hwne + · rw [hwcoeff, norm_one, hwnormeq] + · intro μ hμ + by_contra hnot + have hlt : ν ≺[m] μ := lt_of_not_ge hnot + have hne : μ ≠ ν := by + intro heq + subst μ + exact (lt_irrefl _ hlt) + have hzero := hwhigh μ hne (single_zero_le_of_lex_lt hlt) + rw [hzero, norm_zero, hwnormeq] at hμ + norm_num at hμ + have hqne : q ≠ 0 := by + intro hq + rw [hq, zero_mul] at hqg + exact hwne hqg.symm + have hqdeg : leadingDegree m q = 0 := by + have hmul := leadingDegree_mul m hqne hg + rw [hqg, hwdeg, hgd] at hmul + apply add_right_cancel (b := ν) + simpa [ν] using hmul.symm + have hqunit : IsUnit q := isUnit_of_leadingDegree_eq_zero m hqne hqdeg + let e : TateAlgebra K (Fin (n + 1)) := ↑hqunit.unit⁻¹ + refine ⟨e, w, hqunit.unit⁻¹.isUnit, ⟨hwnorm, ?_, ?_⟩, ?_⟩ + · simpa [ν] using hwcoeff + · simpa [ν] using hwhigh + · rw [← hqg] + dsimp only [e] + rw [← mul_assoc] + have hinv : (↑hqunit.unit⁻¹ : TateAlgebra K (Fin (n + 1))) * q = 1 := by + calc + (↑hqunit.unit⁻¹ : TateAlgebra K (Fin (n + 1))) * q = + ↑hqunit.unit⁻¹ * ↑hqunit.unit := + congrArg (fun z : TateAlgebra K (Fin (n + 1)) ↦ ↑hqunit.unit⁻¹ * z) + hqunit.unit_spec.symm + _ = 1 := by simp + rw [hinv, one_mul] + +end TateAlgebra + +end Rigid diff --git a/Rigid/TateAlgebra/WeierstrassPreparation.lean b/Rigid/TateAlgebra/WeierstrassPreparation.lean new file mode 100644 index 0000000..43bdd53 --- /dev/null +++ b/Rigid/TateAlgebra/WeierstrassPreparation.lean @@ -0,0 +1,63 @@ +import Rigid.AffinoidAlgebra.NoetherNormalization +import Rigid.TateAlgebra.WeierstrassDivision + +set_option linter.style.header false + +/-! +# Weierstrass preparation after a coordinate change + +This file combines the triangular coordinate change used in Noether normalization with the +norm-controlled division theorem. It supplies Rückert axiom (R2): after an algebra automorphism, +every nonzero Tate series is a unit times a Weierstrass polynomial in the first variable. +-/ + +open scoped MonomialOrder + +universe u + +namespace Rigid + +namespace TateAlgebra + +variable {K : Type u} [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- After a triangular coordinate change, every nonzero finite Tate series is a unit times a +Weierstrass polynomial in the first variable. -/ +theorem exists_algEquiv_isUnit_mul_isWeierstrassOfDegree {n : ℕ} + (f : TateAlgebra K (Fin (n + 1))) (hf : f ≠ 0) : + ∃ (ψ : TateAlgebra K (Fin (n + 1)) ≃ₐ[K] TateAlgebra K (Fin (n + 1))) + (d : ℕ) (e w : TateAlgebra K (Fin (n + 1))), + IsUnit e ∧ IsWeierstrassOfDegree d w ∧ ψ f = e * w := by + classical + obtain ⟨ψ, d, hψdeg⟩ := exists_algEquiv_leadingDegree_eq_single_zero K f hf + let m : MonomialOrder (Fin (n + 1)) := MonomialOrder.lex + let a : K := leadingCoeff m (ψ f) + have hψne : ψ f ≠ 0 := fun h ↦ hf (ψ.injective (by simpa using h)) + have ha : a ≠ 0 := leadingCoeff_ne_zero m hψne + let g : TateAlgebra K (Fin (n + 1)) := a⁻¹ • ψ f + have hg : g ≠ 0 := by + intro hg0 + apply hψne + have h := congrArg (fun z : TateAlgebra K (Fin (n + 1)) ↦ a • z) hg0 + simpa [g, smul_smul, mul_inv_cancel₀ ha] using h + have hgdeg : leadingDegree m g = Finsupp.single 0 d := by + change leadingDegree m (a⁻¹ • ψ f) = Finsupp.single 0 d + rw [leadingDegree_smul m (inv_ne_zero ha), hψdeg] + have hglc : leadingCoeff m g = 1 := by + change leadingCoeff m (a⁻¹ • ψ f) = 1 + rw [leadingCoeff_smul m (inv_ne_zero ha)] + exact inv_mul_cancel₀ ha + obtain ⟨e, w, he, hw, hgw⟩ := + exists_isUnit_mul_isWeierstrassOfDegree_of_leadingCoeff_eq_one g hg hgdeg hglc + let c : TateAlgebra K (Fin (n + 1)) := C K _ a + refine ⟨ψ, d, c * e, w, IsUnit.mul (IsUnit.map (C K _) (isUnit_iff_ne_zero.mpr ha)) he, + hw, ?_⟩ + have hag : a • g = ψ f := by + dsimp only [g] + rw [smul_smul, mul_inv_cancel₀ ha, one_smul] + rw [← hag, hgw, Algebra.smul_def, mul_assoc] + rfl + +end TateAlgebra + +end Rigid From 9bc646ef91a8e88ab56070a0dc618928be7e4074 Mon Sep 17 00:00:00 2001 From: katobungen Date: Thu, 23 Jul 2026 15:24:43 +0900 Subject: [PATCH 3/7] Define rigid admissible sites and G-ringed spaces --- Rigid.lean | 6 + Rigid/RigidSpace/AdmissibleSite.lean | 218 ++++++++++++++++++++++++ Rigid/RigidSpace/Basic.lean | 122 +++++++++++++ Rigid/RigidSpace/CanonicalTopology.lean | 71 ++++++++ Rigid/RigidSpace/Comparator.lean | 70 ++++++++ Rigid/RigidSpace/GRingedSpace.lean | 173 +++++++++++++++++++ Rigid/RigidSpace/Morphism.lean | 168 ++++++++++++++++++ 7 files changed, 828 insertions(+) create mode 100644 Rigid/RigidSpace/AdmissibleSite.lean create mode 100644 Rigid/RigidSpace/Basic.lean create mode 100644 Rigid/RigidSpace/CanonicalTopology.lean create mode 100644 Rigid/RigidSpace/Comparator.lean create mode 100644 Rigid/RigidSpace/GRingedSpace.lean create mode 100644 Rigid/RigidSpace/Morphism.lean diff --git a/Rigid.lean b/Rigid.lean index eee8a88..242f568 100644 --- a/Rigid.lean +++ b/Rigid.lean @@ -27,6 +27,12 @@ import Rigid.Berkovich.RelativeSpectrum import Rigid.Berkovich.SpectralSeminorm import Rigid.Berkovich.Spectrum import Rigid.Development +import Rigid.RigidSpace.AdmissibleSite +import Rigid.RigidSpace.Basic +import Rigid.RigidSpace.CanonicalTopology +import Rigid.RigidSpace.Comparator +import Rigid.RigidSpace.GRingedSpace +import Rigid.RigidSpace.Morphism import Rigid.TateAlgebra.Basic import Rigid.TateAlgebra.Complete import Rigid.TateAlgebra.Division diff --git a/Rigid/RigidSpace/AdmissibleSite.lean b/Rigid/RigidSpace/AdmissibleSite.lean new file mode 100644 index 0000000..883d8ee --- /dev/null +++ b/Rigid/RigidSpace/AdmissibleSite.lean @@ -0,0 +1,218 @@ +import Mathlib.CategoryTheory.Limits.Shapes.Pullback.HasPullback +import Mathlib.CategoryTheory.Sites.Pretopology + +set_option linter.style.header false +set_option linter.checkUnivs false + +/-! +# Admissible sites + +This file packages the point-set presentation of a G-topology as a small category of admissible +opens, with inclusions as morphisms, together with a mathlib `Pretopology`. The associated +Grothendieck topology is always obtained using `Pretopology.toGrothendieck`. + +The extra condition `precover_covers` records that the covering presieves really are +set-theoretic covers. It is not another version of the Grothendieck-topology axioms. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe p o + +namespace Rigid + +/-- A small family of subsets, closed under the whole set and binary intersections. + +The order is inclusion of carriers. In particular, admissible opens are determined by their +underlying point sets, as in the definition of a G-topology. -/ +structure AdmissibleBasis where + Point : Type p + Open : Type o + [openPartialOrder : PartialOrder Open] + [openHasPullbacks : HasPullbacks Open] + carrier : Open → Set Point + le_iff : ∀ {U V}, U ≤ V ↔ carrier U ⊆ carrier V + top : Open + carrier_top : carrier top = Set.univ + inter : Open → Open → Open + carrier_inter : ∀ U V, carrier (inter U V) = carrier U ∩ carrier V + +attribute [instance] AdmissibleBasis.openPartialOrder AdmissibleBasis.openHasPullbacks + +namespace AdmissibleBasis + +variable (B : AdmissibleBasis.{p, o}) + +theorem carrier_mono {U V : B.Open} (h : U ≤ V) : B.carrier U ⊆ B.carrier V := + B.le_iff.mp h + +theorem carrier_injective : Function.Injective B.carrier := by + intro U V h + apply le_antisymm + · exact B.le_iff.mpr h.le + · exact B.le_iff.mpr h.ge + +theorem top_mem (x : B.Point) : x ∈ B.carrier B.top := by + rw [B.carrier_top] + exact Set.mem_univ x + +theorem inter_le_left (U V : B.Open) : B.inter U V ≤ U := by + rw [B.le_iff, B.carrier_inter] + exact Set.inter_subset_left + +theorem inter_le_right (U V : B.Open) : B.inter U V ≤ V := by + rw [B.le_iff, B.carrier_inter] + exact Set.inter_subset_right + +theorem le_inter {T U V : B.Open} (hU : T ≤ U) (hV : T ≤ V) : T ≤ B.inter U V := by + rw [B.le_iff, B.carrier_inter] + exact fun x hx ↦ ⟨B.carrier_mono hU hx, B.carrier_mono hV hx⟩ + +/-- In the inclusion category of a G-basis, intersections are pullbacks. -/ +def interPullbackCone {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : + PullbackCone f g := + PullbackCone.mk (homOfLE (B.inter_le_left U V)) (homOfLE (B.inter_le_right U V)) + (Subsingleton.elim _ _) + +/-- The intersection cone has the universal property of the pullback. -/ +def interPullbackConeIsLimit {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : + IsLimit (B.interPullbackCone f g) := + PullbackCone.IsLimit.mk _ + (fun s ↦ homOfLE (B.le_inter (leOfHom s.fst) (leOfHom s.snd))) + (fun _ ↦ Subsingleton.elim _ _) (fun _ ↦ Subsingleton.elim _ _) + (fun _ _ _ _ ↦ Subsingleton.elim _ _) + +/-- The canonical pullback instance supplied by intersections. Constructors of an +`AdmissibleBasis` can use this as their `openHasPullbacks` field. -/ +theorem hasPullbackOfInter {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : + HasPullback f g where + exists_limit := ⟨⟨B.interPullbackCone f g, B.interPullbackConeIsLimit f g⟩⟩ + +end AdmissibleBasis + +/-- A G-site: an admissible basis, a pretopology on it, and the assertion that pretopology +coverings cover the underlying point set. -/ +structure AdmissibleSite extends AdmissibleBasis.{p, o} where + pretopology : Pretopology toAdmissibleBasis.Open + precover_covers : + ∀ {U : toAdmissibleBasis.Open} {R : Presieve U}, R ∈ pretopology U → + ∀ x ∈ toAdmissibleBasis.carrier U, + ∃ (V : toAdmissibleBasis.Open) (f : V ⟶ U), + R f ∧ x ∈ toAdmissibleBasis.carrier V + +namespace AdmissibleSite + +variable (X : Rigid.AdmissibleSite.{p, o}) + +/-- The Grothendieck topology generated by the admissible pretopology. -/ +def topology : GrothendieckTopology X.Open := + X.pretopology.toGrothendieck + +/-- A covering sieve in the generated topology covers the underlying point set. -/ +theorem coveringSieve_covers {U : X.Open} {S : Sieve U} (hS : S ∈ X.topology U) + {x : X.Point} (hx : x ∈ X.carrier U) : + ∃ (V : X.Open) (f : V ⟶ U), S f ∧ x ∈ X.carrier V := by + rcases hS with ⟨R, hR, hRS⟩ + obtain ⟨V, f, hf, hxV⟩ := X.precover_covers hR x hx + exact ⟨V, f, hRS V f hf, hxV⟩ + +/-- The presieve associated to an indexed family of inclusions. -/ +def familyPresieve {ι : Type*} {U : ι → X.Open} {V : X.Open} + (hUV : ∀ i, U i ≤ V) : Presieve V := + Presieve.ofArrows U (fun i ↦ homOfLE (hUV i)) + +/-- An indexed family is an admissible cover when its generated sieve is covering. -/ +def IsCover {ι : Type*} (U : ι → X.Open) (V : X.Open) : Prop := + ∃ hUV : ∀ i, U i ≤ V, Sieve.generate (X.familyPresieve hUV) ∈ X.topology V + +namespace IsCover + +variable {X} + +/-- Every member of an admissible cover is contained in the covered open. -/ +theorem subset {ι : Type*} {U : ι → X.Open} {V : X.Open} (h : X.IsCover U V) + (i : ι) : U i ≤ V := + h.choose i + +/-- A family admitting a covering refinement is itself an admissible cover. This is the +Grothendieck-topology form of the saturation axiom for coverings. -/ +theorem of_refinement {ι κ : Type*} {U : ι → X.Open} {W : κ → X.Open} {V : X.Open} + (hUV : ∀ i, U i ≤ V) (hW : X.IsCover W V) (r : κ → ι) + (hr : ∀ j, W j ≤ U (r j)) : X.IsCover U V := by + rcases hW with ⟨_, hWcover⟩ + refine ⟨hUV, X.topology.superset_covering ?_ hWcover⟩ + intro T q hq + rcases hq with ⟨Z, a, b, ⟨j⟩, hab⟩ + refine + ⟨U (r j), a ≫ homOfLE (hr j), homOfLE (hUV (r j)), ⟨r j⟩, Subsingleton.elim _ _⟩ + +/-- The singleton family is an admissible cover. -/ +theorem singleton (V : X.Open) : X.IsCover (fun _ : PUnit ↦ V) V := by + refine ⟨fun _ ↦ le_rfl, ?_⟩ + simp [AdmissibleSite.familyPresieve, Presieve.ofArrows_pUnit] + +/-- Admissible covers are stable under intersection with another admissible open. -/ +theorem pullback {ι : Type*} {U : ι → X.Open} {V : X.Open} (h : X.IsCover U V) + (W : X.Open) : + X.IsCover (fun i ↦ X.inter (U i) W) (X.inter V W) := by + rcases h with ⟨hUV, hcover⟩ + let p : X.inter V W ⟶ V := homOfLE (X.toAdmissibleBasis.inter_le_left V W) + let hIW : ∀ i, X.inter (U i) W ≤ X.inter V W := fun i ↦ + X.toAdmissibleBasis.le_inter + ((X.toAdmissibleBasis.inter_le_left (U i) W).trans (hUV i)) + (X.toAdmissibleBasis.inter_le_right (U i) W) + refine ⟨hIW, X.topology.superset_covering ?_ (X.topology.pullback_stable p hcover)⟩ + rintro T q hq + change Sieve.generate (X.familyPresieve hUV) (q ≫ p) at hq + rcases hq with ⟨Z, a, b, ⟨i⟩, hab⟩ + refine ⟨X.inter (U i) W, homOfLE ?_, homOfLE (hIW i), ⟨i⟩, Subsingleton.elim _ _⟩ + apply X.toAdmissibleBasis.le_inter + · exact leOfHom a + · exact (leOfHom q).trans (X.toAdmissibleBasis.inter_le_right V W) + +/-- Admissible coverings are transitive. -/ +theorem trans {ι : Type*} {κ : ι → Type*} {U : ι → X.Open} {V : X.Open} + (hU : X.IsCover U V) (W : ∀ i, κ i → X.Open) + (hW : ∀ i, X.IsCover (W i) (U i)) : + X.IsCover (fun p : Σ i, κ i ↦ W p.1 p.2) V := by + rcases hU with ⟨hUV, hUcover⟩ + choose hWU hWcover using hW + let f : ∀ i, U i ⟶ V := fun i ↦ homOfLE (hUV i) + let g : ∀ i j, W i j ⟶ U i := fun i j ↦ homOfLE (hWU i j) + refine ⟨fun p ↦ (hWU p.1 p.2).trans (hUV p.1), ?_⟩ + have hbind := X.topology.bindOfArrows (f := f) (R := fun i ↦ X.familyPresieve (hWU i)) + hUcover hWcover + change Sieve.generate + (Presieve.bindOfArrows U f (fun i ↦ Presieve.ofArrows (W i) (g i))) ∈ + X.topology V at hbind + rw [Presieve.bindOfArrows_ofArrows f g] at hbind + convert hbind using 1 + apply Sieve.ext + intro T q + rfl + +/-- The carriers of an admissible covering family have union equal to the covered carrier. -/ +theorem iUnion_carrier {ι : Type*} {U : ι → X.Open} {V : X.Open} + (h : X.IsCover U V) : X.carrier V = ⋃ i, X.carrier (U i) := by + apply Set.Subset.antisymm + · intro x hx + rcases h with ⟨hUV, hcover⟩ + obtain ⟨T, q, hq, hxT⟩ := X.coveringSieve_covers hcover hx + rcases hq with ⟨Z, a, b, ⟨i⟩, hab⟩ + exact Set.mem_iUnion.mpr ⟨i, X.toAdmissibleBasis.carrier_mono (leOfHom a) hxT⟩ + · intro x hx + rcases Set.mem_iUnion.mp hx with ⟨i, hxi⟩ + exact X.toAdmissibleBasis.carrier_mono (h.subset i) hxi + +end IsCover + +/-- A quasi-compact admissible open is one for which every admissible cover has a finite +admissible subcover. This is deliberately separate from admissibility itself. -/ +def IsQuasiCompact (U : X.Open) : Prop := + ∀ {ι : Type*} (V : ι → X.Open), X.IsCover V U → + ∃ s : Set ι, s.Finite ∧ X.IsCover (fun i : s ↦ V i.1) U + +end AdmissibleSite + +end Rigid diff --git a/Rigid/RigidSpace/Basic.lean b/Rigid/RigidSpace/Basic.lean new file mode 100644 index 0000000..abc73b5 --- /dev/null +++ b/Rigid/RigidSpace/Basic.lean @@ -0,0 +1,122 @@ +import Rigid.AffinoidAlgebra.MaximalSpectrum +import Rigid.RigidSpace.Morphism + +set_option linter.style.header false + +/-! +# Rigid analytic spaces + +The definition here follows Chapters 4 and 5 of +`Introduction_to_Rigid_Geometry(personal_version)_English.tex`. + +A rigid analytic space is more than a G-locally ringed space. Its G-topology contains the empty +and whole opens, is local for admissible coverings, is saturated under refinements, and the space +has an admissible affinoid covering. Saturation of coverings is already a theorem of the +Grothendieck topology (`AdmissibleSite.IsCover.of_refinement`), so it is not stored again. + +An `AffinoidChart` records the affinoid identification through the coordinate algebra of global +sections, its maximal spectrum, and an affinoid basis for the induced strong G-topology. This +distinguishes the strong topology used to glue rigid spaces from the weak finite-cover topology on +an affinoid basis. +-/ + +universe k + +namespace Rigid + +variable (K : Type k) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- The local affinoid data on an admissible open `U`. + +The coordinate algebra of the chart is `Γ(U, 𝒪)`. Its points are identified with the maximal +spectrum of that algebra. The final field expresses the strong-topology property: every +admissible subopen has an admissible covering by opens with the same two affinoid +characterizations. -/ +structure AffinoidChart (X : LocallyGRingedSpace.{k} K) + (U : X.toAdmissibleSite.Open) where + sections_isAffinoid : + IsAffinoidAlgebra K (GRingedSpace.Sections K X.toGRingedSpace U) + pointsEquiv : + {x : X.toAdmissibleSite.Point // x ∈ X.toAdmissibleSite.carrier U} ≃ + MaximalSpectrum (GRingedSpace.Sections K X.toGRingedSpace U) + affinoidBasis : + ∀ {V : X.toAdmissibleSite.Open}, V ≤ U → + ∃ (ι : Type k) (W : ι → X.toAdmissibleSite.Open), + X.toAdmissibleSite.IsCover W V ∧ + ∀ i, + IsAffinoidAlgebra K (GRingedSpace.Sections K X.toGRingedSpace (W i)) ∧ + Nonempty + ({x : X.toAdmissibleSite.Point // + x ∈ X.toAdmissibleSite.carrier (W i)} ≃ + MaximalSpectrum + (GRingedSpace.Sections K X.toGRingedSpace (W i))) + +/-- A rigid analytic space over `K`. + +Besides its underlying G-locally ringed space, this stores precisely the additional global +conditions from Definition 5.1 of the reference: + +* the empty set (the whole set is already `toAdmissibleSite.top`) is admissible; +* admissibility of a subset is local for an admissible covering; +* there is an admissible covering by affinoid charts. + +The third saturation axiom for coverings is derived from the associated Grothendieck topology, +rather than duplicated as structure data. -/ +structure RigidSpace extends LocallyGRingedSpace.{k} K where + empty : toLocallyGRingedSpace.toAdmissibleSite.Open + carrier_empty : + toLocallyGRingedSpace.toAdmissibleSite.carrier empty = ∅ + admissibleOpen_local : + ∀ {ι : Type k} + {U : ι → toLocallyGRingedSpace.toAdmissibleSite.Open} + {V : toLocallyGRingedSpace.toAdmissibleSite.Open}, + toLocallyGRingedSpace.toAdmissibleSite.IsCover U V → + ∀ (S : Set toLocallyGRingedSpace.toAdmissibleSite.Point), + S ⊆ toLocallyGRingedSpace.toAdmissibleSite.carrier V → + (∀ i, ∃ W : toLocallyGRingedSpace.toAdmissibleSite.Open, + toLocallyGRingedSpace.toAdmissibleSite.carrier W = + S ∩ toLocallyGRingedSpace.toAdmissibleSite.carrier (U i)) → + ∃ W : toLocallyGRingedSpace.toAdmissibleSite.Open, + toLocallyGRingedSpace.toAdmissibleSite.carrier W = S + AtlasIndex : Type k + atlasOpen : AtlasIndex → toLocallyGRingedSpace.toAdmissibleSite.Open + atlasChart : + ∀ i, AffinoidChart K toLocallyGRingedSpace (atlasOpen i) + atlasCover : + toLocallyGRingedSpace.toAdmissibleSite.IsCover atlasOpen + toLocallyGRingedSpace.toAdmissibleSite.top + +namespace RigidSpace + +variable (X : RigidSpace.{k} K) + +/-- The empty admissible open is uniquely determined by its carrier. -/ +theorem empty_unique {U : X.toAdmissibleSite.Open} + (hU : X.toAdmissibleSite.carrier U = ∅) : U = X.empty := + X.toAdmissibleSite.toAdmissibleBasis.carrier_injective + (hU.trans X.carrier_empty.symm) + +/-- The selected affinoid charts cover the underlying point set. -/ +theorem atlas_iUnion_carrier : + X.toAdmissibleSite.carrier X.toAdmissibleSite.top = + ⋃ i, X.toAdmissibleSite.carrier (X.atlasOpen i) := + X.atlasCover.iUnion_carrier + +/-- The covering-saturation axiom of a rigid G-topology is inherited from its Grothendieck +topology: a covering family with an admissible covering refinement is admissible. -/ +theorem cover_of_refinement {ι κ : Type*} + {U : ι → X.toAdmissibleSite.Open} {W : κ → X.toAdmissibleSite.Open} + {V : X.toAdmissibleSite.Open} (hUV : ∀ i, U i ≤ V) + (hW : X.toAdmissibleSite.IsCover W V) (r : κ → ι) + (hr : ∀ j, W j ≤ U (r j)) : + X.toAdmissibleSite.IsCover U V := + AdmissibleSite.IsCover.of_refinement hUV hW r hr + +/-- Morphisms of rigid analytic spaces are morphisms of the underlying G-locally ringed spaces, +as in Definition 5.1(2) of the reference. -/ +abbrev Hom (X Y : RigidSpace.{k} K) := + LocallyGRingedSpace.Hom K X.toLocallyGRingedSpace Y.toLocallyGRingedSpace + +end RigidSpace + +end Rigid diff --git a/Rigid/RigidSpace/CanonicalTopology.lean b/Rigid/RigidSpace/CanonicalTopology.lean new file mode 100644 index 0000000..911b635 --- /dev/null +++ b/Rigid/RigidSpace/CanonicalTopology.lean @@ -0,0 +1,71 @@ +import Rigid.RigidSpace.AdmissibleSite + +set_option linter.style.header false +set_option linter.checkUnivs false + +/-! +# The canonical point-cover G-topology + +This file constructs the canonical pretopology in which every set-theoretic covering by +admissible opens is admissible. The construction is separate from `AdmissibleSite` because rigid +affinoid spaces generally use a stricter choice of admissible coverings. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe p o + +namespace Rigid + +namespace AdmissibleBasis + +variable (B : AdmissibleBasis.{p, o}) + +/-- The precoverage consisting of all presieves whose domains cover the underlying point set. -/ +def pointCoverPrecoverage : Precoverage B.Open where + coverings U := + {R | ∀ x ∈ B.carrier U, ∃ (V : B.Open) (f : V ⟶ U), R f ∧ x ∈ B.carrier V} + +instance pointCoverPrecoverage_hasIsos : + B.pointCoverPrecoverage.HasIsos where + mem_coverings_of_isIso {U V} f _ x hx := by + refine ⟨U, f, Presieve.singleton_self f, ?_⟩ + exact B.carrier_mono (leOfHom (inv f)) hx + +instance pointCoverPrecoverage_isStableUnderBaseChange : + B.pointCoverPrecoverage.IsStableUnderBaseChange where + mem_coverings_of_isPullback {ι S U} f hR {V} g {P} p₁ p₂ hp x hxV := by + have hxS : x ∈ B.carrier S := B.carrier_mono (leOfHom g) hxV + obtain ⟨_, _, ⟨i⟩, hxUi⟩ := hR x hxS + let T := B.inter V (U i) + let q₁ : T ⟶ V := homOfLE (B.inter_le_left V (U i)) + let q₂ : T ⟶ U i := homOfLE (B.inter_le_right V (U i)) + let l : T ⟶ P i := (hp i).lift q₁ q₂ (Subsingleton.elim _ _) + refine ⟨P i, p₁ i, Presieve.ofArrows.mk i, B.carrier_mono (leOfHom l) ?_⟩ + rw [B.carrier_inter] + exact ⟨hxV, hxUi⟩ + +instance pointCoverPrecoverage_isStableUnderComposition : + B.pointCoverPrecoverage.IsStableUnderComposition where + comp_mem_coverings {ι S U} f hf {σ W} g hg x hxS := by + obtain ⟨_, _, ⟨i⟩, hxUi⟩ := hf x hxS + obtain ⟨_, _, ⟨j⟩, hxWij⟩ := hg i x hxUi + refine ⟨W i j, g i j ≫ f i, ?_, hxWij⟩ + exact Presieve.ofArrows.mk (Sigma.mk i j) + +/-- The pretopology of all point-set covers. Its three axioms are supplied by the +`Precoverage` instances above. -/ +def pointCoverPretopology : Pretopology B.Open := + B.pointCoverPrecoverage.toPretopology + +/-- The canonical G-site associated with an admissible basis: all point-set covering families are +admissible. -/ +def toCanonicalSite : AdmissibleSite.{p, o} where + toAdmissibleBasis := B + pretopology := B.pointCoverPretopology + precover_covers := fun h ↦ h + +end AdmissibleBasis + +end Rigid diff --git a/Rigid/RigidSpace/Comparator.lean b/Rigid/RigidSpace/Comparator.lean new file mode 100644 index 0000000..51d30f4 --- /dev/null +++ b/Rigid/RigidSpace/Comparator.lean @@ -0,0 +1,70 @@ +import Rigid.RigidSpace.Basic + +set_option linter.style.header false + +/-! +# Comparator adapters for G-locally ringed spaces + +These abbreviations isolate the global comparator-facing vocabulary from the implementation of +sites, sheaves, and stalk colimits. They are intentionally production declarations in namespace +`Rigid`; the comparator remains in its separate `RigidChallenge` namespace. +-/ + +universe u + +namespace Rigid + +namespace ComparatorAdapter + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- The production candidate underlying the comparator's global rigid-space interface. -/ +abbrev RigidSpace := + Rigid.RigidSpace.{u} K + +/-- Analytic points of the production G-locally ringed space. -/ +abbrev Point (X : RigidSpace K) : Type (u + 1) := + ULift.{u + 1, u} X.toAdmissibleSite.Point + +/-- Admissible opens of the production G-site. -/ +abbrev AdmissibleOpen (X : RigidSpace K) : Type (u + 1) := + ULift.{u + 1, u} X.toAdmissibleSite.Open + +/-- The point set of an admissible open. -/ +abbrev carrier {X : RigidSpace K} (U : AdmissibleOpen K X) : Set (Point K X) := + {x | x.down ∈ X.toAdmissibleSite.carrier U.down} + +/-- Indexed admissible covers are the covering sieves of the generated Grothendieck topology. -/ +abbrev IsCover {X : RigidSpace K} {ι : Type (u + 1)} + (U : ι → AdmissibleOpen K X) (V : AdmissibleOpen K X) : Prop := + X.toAdmissibleSite.IsCover (fun i ↦ (U i).down) V.down + +/-- Evaluation of the bundled structure sheaf. -/ +abbrev Sections {X : RigidSpace K} (U : AdmissibleOpen K X) : Type u := + GRingedSpace.Sections K X.toGRingedSpace U.down + +/-- Restriction is the corresponding map of the structure presheaf. -/ +def restriction {X : RigidSpace K} {U V : AdmissibleOpen K X} (hUV : carrier K U ⊆ carrier K V) : + Sections K V →ₐ[K] Sections K U := + GRingedSpace.restriction K X.toGRingedSpace + (X.toAdmissibleSite.le_iff.mpr (fun x hx ↦ by + have hx' : (ULift.up x : Point K X) ∈ carrier K U := hx + exact hUV hx')) + +/-- Stalks are the neighbourhood colimits constructed in `GRingedSpace`. -/ +noncomputable abbrev Stalk (X : RigidSpace K) (x : Point K X) : Type u := + GRingedSpace.Stalk K X.toGRingedSpace x.down + +/-- Germs are the canonical maps into those colimits. -/ +noncomputable def germ {X : RigidSpace K} {U : AdmissibleOpen K X} + {x : Point K X} (hx : x ∈ carrier K U) : + Sections K U →ₐ[K] Stalk K X x := + GRingedSpace.germ K X.toGRingedSpace hx + +/-- Production analytic morphism data, with the stalk map derived rather than stored. -/ +abbrev AnalyticMorphismData (X Y : RigidSpace K) := + Rigid.RigidSpace.Hom K X Y + +end ComparatorAdapter + +end Rigid diff --git a/Rigid/RigidSpace/GRingedSpace.lean b/Rigid/RigidSpace/GRingedSpace.lean new file mode 100644 index 0000000..060cbcf --- /dev/null +++ b/Rigid/RigidSpace/GRingedSpace.lean @@ -0,0 +1,173 @@ +import Mathlib.Algebra.Category.CommAlgCat.Basic +import Mathlib.CategoryTheory.Filtered.Basic +import Mathlib.CategoryTheory.Sites.Sheaf +import Rigid.RigidSpace.AdmissibleSite + +set_option linter.style.header false + +/-! +# G-ringed and G-locally ringed spaces + +The structure sheaf is a mathlib `Sheaf` on the Grothendieck topology generated by the admissible +pretopology. Sections and restriction maps are evaluations of that sheaf. Stalks are filtered +colimits over admissible neighbourhoods, and germs are the canonical colimit maps. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe k + +namespace Rigid + +variable (K : Type k) [CommRing K] + +/-- A G-ringed space over `K`. -/ +structure GRingedSpace where + toAdmissibleSite : AdmissibleSite.{k, k} + structureSheaf : + Sheaf toAdmissibleSite.topology (CommAlgCat.{k} K) + +namespace GRingedSpace + +variable (X : GRingedSpace.{k} K) + +/-- Analytic functions on an admissible open. -/ +abbrev Sections (U : X.toAdmissibleSite.Open) : Type k := + X.structureSheaf.obj.obj (Opposite.op U) + +/-- Restriction of analytic functions along an inclusion of admissible opens. -/ +def restriction {U V : X.toAdmissibleSite.Open} (hUV : U ≤ V) : + Sections K X V →ₐ[K] Sections K X U := + (X.structureSheaf.obj.map (homOfLE hUV).op).hom + +@[simp] +theorem restriction_id (U : X.toAdmissibleSite.Open) : + restriction K X (U := U) (V := U) le_rfl = AlgHom.id K (Sections K X U) := by + change (X.structureSheaf.obj.map (𝟙 (Opposite.op U))).hom = _ + rw [X.structureSheaf.obj.map_id] + rfl + +@[simp] +theorem restriction_comp {U V W : X.toAdmissibleSite.Open} (hUV : U ≤ V) (hWU : W ≤ U) : + (restriction K X hWU).comp (restriction K X hUV) = + restriction K X (hWU.trans hUV) := by + change + (X.structureSheaf.obj.map (homOfLE hUV).op ≫ + X.structureSheaf.obj.map (homOfLE hWU).op).hom = + (X.structureSheaf.obj.map (homOfLE (hWU.trans hUV)).op).hom + rw [← X.structureSheaf.obj.map_comp] + rfl + +/-- The representable form of the sheaf condition for an indexed admissible cover. This is the +categorical sheaf condition used by mathlib for a `CommAlgCat`-valued sheaf. -/ +theorem isSheafFor_isCover (E : CommAlgCat.{k} K) {ι : Type*} + {U : ι → X.toAdmissibleSite.Open} + {V : X.toAdmissibleSite.Open} (h : X.toAdmissibleSite.IsCover U V) : + Presieve.IsSheafFor + (X.structureSheaf.obj ⋙ coyoneda.obj (Opposite.op E)) + (X.toAdmissibleSite.familyPresieve h.choose) := by + rw [Presieve.isSheafFor_iff_generate] + exact X.structureSheaf.property E _ h.choose_spec + +/-- An admissible neighbourhood of a point. Its order is reverse inclusion, so restriction maps +form a direct system. -/ +structure Neighborhood (x : X.toAdmissibleSite.Point) where + obj : X.toAdmissibleSite.Open + mem : x ∈ X.toAdmissibleSite.carrier obj + +namespace Neighborhood + +variable {X} {x : X.toAdmissibleSite.Point} + +instance : Preorder (Neighborhood K X x) where + le U V := V.obj ≤ U.obj + le_refl _ := le_rfl + le_trans _ _ _ hUV hVW := hVW.trans hUV + +/-- The full admissible open is a neighbourhood of every point. -/ +def top : Neighborhood K X x where + obj := X.toAdmissibleSite.top + mem := X.toAdmissibleSite.toAdmissibleBasis.top_mem x + +/-- Intersections give common refinements of admissible neighbourhoods. -/ +def inter (U V : Neighborhood K X x) : Neighborhood K X x where + obj := X.toAdmissibleSite.inter U.obj V.obj + mem := by + rw [X.toAdmissibleSite.carrier_inter] + exact ⟨U.mem, V.mem⟩ + +instance : Nonempty (Neighborhood K X x) := + ⟨top (K := K)⟩ + +instance : IsFiltered (Neighborhood K X x) where + cocone_objs U V := + ⟨inter (K := K) U V, + homOfLE (X.toAdmissibleSite.toAdmissibleBasis.inter_le_left U.obj V.obj), + homOfLE (X.toAdmissibleSite.toAdmissibleBasis.inter_le_right U.obj V.obj), trivial⟩ + cocone_maps := fun {_ _} _ _ ↦ ⟨_, 𝟙 _, Subsingleton.elim _ _⟩ + +end Neighborhood + +/-- The direct system of section algebras over admissible neighbourhoods. -/ +@[reducible] +def stalkDiagram (x : X.toAdmissibleSite.Point) : + Neighborhood K X x ⥤ CommAlgCat.{k} K where + obj U := X.structureSheaf.obj.obj (Opposite.op U.obj) + map {U V} f := + X.structureSheaf.obj.map + (homOfLE (show V.obj ≤ U.obj from leOfHom f)).op + map_id U := by + change X.structureSheaf.obj.map (𝟙 (Opposite.op U.obj)) = 𝟙 _ + exact X.structureSheaf.obj.map_id _ + map_comp f g := by + rw [← X.structureSheaf.obj.map_comp] + rfl + +/-- The stalk object is the filtered colimit over admissible neighbourhoods. -/ +noncomputable abbrev stalkObj (x : X.toAdmissibleSite.Point) : CommAlgCat.{k} K := + colimit (stalkDiagram K X x) + +/-- The local ring of germs at a point, as an underlying type. -/ +noncomputable abbrev Stalk (x : X.toAdmissibleSite.Point) : Type k := + stalkObj K X x + +/-- The germ map is the canonical map into the neighbourhood colimit. -/ +noncomputable def germ {U : X.toAdmissibleSite.Open} {x : X.toAdmissibleSite.Point} + (hx : x ∈ X.toAdmissibleSite.carrier U) : + Sections K X U →ₐ[K] Stalk K X x := + (colimit.ι (stalkDiagram K X x) ⟨U, hx⟩).hom + +/-- Germs commute with restriction. -/ +@[simp] +theorem germ_restriction {U V : X.toAdmissibleSite.Open} (hUV : U ≤ V) + {x : X.toAdmissibleSite.Point} (hx : x ∈ X.toAdmissibleSite.carrier U) : + (germ K X hx).comp (restriction K X hUV) = + germ K X (X.toAdmissibleSite.toAdmissibleBasis.carrier_mono hUV hx) := by + let V' : Neighborhood K X x := + ⟨V, X.toAdmissibleSite.toAdmissibleBasis.carrier_mono hUV hx⟩ + let U' : Neighborhood K X x := ⟨U, hx⟩ + let f : V' ⟶ U' := homOfLE hUV + have hw := colimit.w (stalkDiagram K X x) f + exact congrArg CommAlgCat.Hom.hom hw + +end GRingedSpace + +/-- A G-locally ringed space is a G-ringed space whose canonically constructed stalks are local +rings. -/ +structure LocallyGRingedSpace extends GRingedSpace.{k} K where + stalk_isLocal : + ∀ x : toGRingedSpace.toAdmissibleSite.Point, + IsLocalRing (GRingedSpace.Stalk K toGRingedSpace x) + +namespace LocallyGRingedSpace + +variable (X : LocallyGRingedSpace.{k} K) + +instance stalkIsLocal (x : X.toAdmissibleSite.Point) : + IsLocalRing (GRingedSpace.Stalk K X.toGRingedSpace x) := + X.stalk_isLocal x + +end LocallyGRingedSpace + +end Rigid diff --git a/Rigid/RigidSpace/Morphism.lean b/Rigid/RigidSpace/Morphism.lean new file mode 100644 index 0000000..eaf7413 --- /dev/null +++ b/Rigid/RigidSpace/Morphism.lean @@ -0,0 +1,168 @@ +import Mathlib.CategoryTheory.Sites.CoverPreserving +import Rigid.RigidSpace.GRingedSpace + +set_option linter.style.header false + +/-! +# Morphisms of G-ringed spaces + +A continuous map carries an inverse-image functor on admissible opens together with mathlib's +`Functor.IsContinuous` site condition. A morphism of G-ringed spaces adds a morphism from the +target structure sheaf to the continuous pushforward of the source structure sheaf. Its maps on +stalks are then constructed from the universal property of the neighbourhood colimit. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe pX oX pY oY k a v + +namespace Rigid + +namespace AdmissibleSite + +/-- Point-set and inverse-image data for a map of admissible sites. -/ +structure MapData (X : AdmissibleSite.{pX, oX}) (Y : AdmissibleSite.{pY, oY}) where + toFun : X.Point → Y.Point + preimage : Y.Open → X.Open + monotone_preimage : Monotone preimage + carrier_preimage : + ∀ U, X.carrier (preimage U) = toFun ⁻¹' Y.carrier U + +namespace MapData + +variable {X : AdmissibleSite.{pX, oX}} {Y : AdmissibleSite.{pY, oY}} + +/-- Inverse image as a functor between the inclusion categories of admissible opens. -/ +abbrev preimageFunctor (f : MapData X Y) : Y.Open ⥤ X.Open := + f.monotone_preimage.functor + +end MapData + +/-- A continuous map of admissible sites. -/ +structure Hom (X : AdmissibleSite.{pX, oX}) (Y : AdmissibleSite.{pY, oY}) + extends MapData X Y where + continuous : + Functor.IsContinuous toMapData.preimageFunctor Y.topology X.topology + +namespace Hom + +variable {X : AdmissibleSite.{pX, oX}} {Y : AdmissibleSite.{pY, oY}} + +/-- The mathlib continuous pushforward along the inverse-image functor on opens. -/ +noncomputable def pushforwardSheaf (f : Hom X Y) {A : Type a} [Category.{v} A] + (F : Sheaf X.topology A) : Sheaf Y.topology A := by + letI := f.continuous + exact (f.toMapData.preimageFunctor.sheafPushforwardContinuous + A Y.topology X.topology).obj F + +end Hom + +end AdmissibleSite + +variable (K : Type k) [CommRing K] + +namespace GRingedSpace + +variable {X Y : GRingedSpace.{k} K} + +/-- A morphism of G-ringed spaces: a continuous map of sites and a morphism of structure +sheaves. -/ +structure Hom (X Y : GRingedSpace.{k} K) where + base : AdmissibleSite.Hom X.toAdmissibleSite Y.toAdmissibleSite + pullback : + Y.structureSheaf.obj ⟶ + base.toMapData.preimageFunctor.op ⋙ X.structureSheaf.obj + +namespace Hom + +variable (f : Hom K X Y) + +/-- The pullback natural transformation bundled as a morphism of sheaves. -/ +noncomputable def pullbackSheafHom : + Y.structureSheaf ⟶ + f.base.pushforwardSheaf (A := CommAlgCat.{k} K) X.structureSheaf := + ObjectProperty.homMk f.pullback + +/-- Inverse image sends a neighbourhood of `f(x)` to a neighbourhood of `x`. -/ +@[reducible] +def preimageNeighborhood (x : X.toAdmissibleSite.Point) + (U : Neighborhood K Y (f.base.toMapData.toFun x)) : + Neighborhood K X x where + obj := f.base.toMapData.preimage U.obj + mem := by + rw [f.base.toMapData.carrier_preimage] + exact U.mem + +/-- Pullback of sections on one admissible open. -/ +noncomputable def pullbackApp (U : Y.toAdmissibleSite.Open) : + Sections K Y U →ₐ[K] Sections K X (f.base.toMapData.preimage U) := + (f.pullback.app (Opposite.op U)).hom + +/-- The cocone from target neighbourhood sections to the source stalk. -/ +noncomputable def stalkCocone (x : X.toAdmissibleSite.Point) : + Cocone (stalkDiagram K Y (f.base.toMapData.toFun x)) where + pt := stalkObj K X x + ι := + { app := fun U ↦ + f.pullback.app (Opposite.op U.obj) ≫ + colimit.ι (stalkDiagram K X x) (preimageNeighborhood K f x U) + naturality := by + intro U V h + let h' : preimageNeighborhood K f x U ⟶ preimageNeighborhood K f x V := + homOfLE (f.base.toMapData.monotone_preimage (leOfHom h)) + simp only [Functor.const_obj_map] + change + Y.structureSheaf.obj.map + (homOfLE (show V.obj ≤ U.obj from leOfHom h)).op ≫ + f.pullback.app (Opposite.op V.obj) ≫ + colimit.ι (stalkDiagram K X x) (preimageNeighborhood K f x V) = + f.pullback.app (Opposite.op U.obj) ≫ + colimit.ι (stalkDiagram K X x) (preimageNeighborhood K f x U) + rw [← Category.assoc] + rw [f.pullback.naturality] + rw [Category.assoc] + have hmap : + (f.base.toMapData.preimageFunctor.op ⋙ X.structureSheaf.obj).map + (homOfLE (show V.obj ≤ U.obj from leOfHom h)).op = + (stalkDiagram K X x).map h' := rfl + rw [hmap] + exact congrArg + (fun q ↦ f.pullback.app (Opposite.op U.obj) ≫ q) + (colimit.w (stalkDiagram K X x) h') } + +/-- The induced map on stalks, obtained from the colimit universal property. -/ +noncomputable def stalkMap (x : X.toAdmissibleSite.Point) : + stalkObj K Y (f.base.toMapData.toFun x) ⟶ stalkObj K X x := + colimit.desc (stalkDiagram K Y (f.base.toMapData.toFun x)) (stalkCocone K f x) + +/-- The induced stalk map carries the germ of a section to the germ of its pullback. -/ +@[simp] +theorem germ_stalkMap {U : Y.toAdmissibleSite.Open} {x : X.toAdmissibleSite.Point} + (hx : f.base.toMapData.toFun x ∈ Y.toAdmissibleSite.carrier U) : + (stalkMap K f x).hom.comp (germ K Y hx) = + (germ K X (by + rw [f.base.toMapData.carrier_preimage] + exact hx)).comp (pullbackApp K f U) := by + exact congrArg CommAlgCat.Hom.hom + (colimit.ι_desc (stalkCocone K f x) ⟨U, hx⟩) + +end Hom + +end GRingedSpace + +namespace LocallyGRingedSpace + +variable {X Y : LocallyGRingedSpace.{k} K} + +/-- A morphism of G-locally ringed spaces is a G-ringed-space morphism whose canonically induced +maps on stalks are local. -/ +structure Hom (X Y : LocallyGRingedSpace.{k} K) where + toGRingedSpaceHom : GRingedSpace.Hom K X.toGRingedSpace Y.toGRingedSpace + local_stalk : + ∀ x : X.toAdmissibleSite.Point, + IsLocalHom (GRingedSpace.Hom.stalkMap K toGRingedSpaceHom x).hom + +end LocallyGRingedSpace + +end Rigid From 634883ae4638eddf3884f0861a39c9871ce91d04 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 23 Jul 2026 15:50:34 +0900 Subject: [PATCH 4/7] Polish Tate acyclicity foundations --- Rigid.lean | 2 +- Rigid/AffinoidAlgebra/CompletedLaurent.lean | 11 ++++++- Rigid/AffinoidAlgebra/LaurentCharts.lean | 1 - Rigid/AffinoidAlgebra/LaurentCover.lean | 1 - .../AffinoidAlgebra/NoetherNormalization.lean | 1 + Rigid/AffinoidAlgebra/PowerBounded.lean | 21 ------------- Rigid/AffinoidAlgebra/SpectralComponents.lean | 1 + Rigid/AffinoidAlgebra/SpectralPolynomial.lean | 30 +++++++++++++++++-- .../AffinoidAlgebra/SpectralPresentation.lean | 1 + Rigid/AffinoidAlgebra/SpectralRadius.lean | 16 +++++++--- .../AffinoidSpectrum/RationalRefinement.lean | 1 - Rigid/AffinoidSpectrum/Restriction.lean | 3 +- Rigid/Berkovich/Unit.lean | 2 +- Rigid/TateAlgebra/FirstVariable.lean | 25 ++++++++++++---- Rigid/TateAlgebra/Ruckert.lean | 6 +++- Rigid/TateAlgebra/UniqueFactorization.lean | 1 + 16 files changed, 81 insertions(+), 42 deletions(-) diff --git a/Rigid.lean b/Rigid.lean index 798b469..6cbde9a 100644 --- a/Rigid.lean +++ b/Rigid.lean @@ -19,8 +19,8 @@ import Rigid.AffinoidAlgebra.RationalLocalization import Rigid.AffinoidAlgebra.RationalRestriction import Rigid.AffinoidAlgebra.RelativeTate import Rigid.AffinoidAlgebra.ResidueNorm -import Rigid.AffinoidAlgebra.SpectralCriterion import Rigid.AffinoidAlgebra.SpectralComponents +import Rigid.AffinoidAlgebra.SpectralCriterion import Rigid.AffinoidAlgebra.SpectralPolynomial import Rigid.AffinoidAlgebra.SpectralPresentation import Rigid.AffinoidAlgebra.SpectralRadius diff --git a/Rigid/AffinoidAlgebra/CompletedLaurent.lean b/Rigid/AffinoidAlgebra/CompletedLaurent.lean index de0e4c1..b1b5674 100644 --- a/Rigid/AffinoidAlgebra/CompletedLaurent.lean +++ b/Rigid/AffinoidAlgebra/CompletedLaurent.lean @@ -2,7 +2,6 @@ import Rigid.TateAlgebra.RelativeUniversalProperty import Mathlib.Algebra.Exact.Basic set_option linter.style.header false -set_option linter.unusedSectionVars false /-! # The completed Laurent coefficient sequence @@ -70,6 +69,7 @@ private theorem exponentValue_injective : rw [exponent_eq_oneExponent e, exponent_eq_oneExponent e'] exact congrArg oneExponent h +omit [CompleteSpace A] in /-- The coefficient sequence of a one-variable Tate series tends to zero. -/ theorem tendsto_oneVariable_coeff (p : TateAlgebra A (Fin 1)) : Tendsto (fun n ↦ TateAlgebra.coeff A (Fin 1) (oneExponent n) p) @@ -89,12 +89,14 @@ noncomputable def ofCoefficients (a : ℕ → A) (ha : Tendsto a cofinite (𝓝 exact (tendsto_zero_iff_norm_tendsto_zero.mp ha).comp exponentValue_injective.tendsto_cofinite⟩ +omit [CompleteSpace A] in @[simp] theorem coeff_ofCoefficients (a : ℕ → A) (ha : Tendsto a cofinite (𝓝 0)) (n : ℕ) : TateAlgebra.coeff A (Fin 1) (oneExponent n) (ofCoefficients A a ha) = a n := by simp only [TateAlgebra.coeff_apply, ofCoefficients, MvPowerSeries.coeff_apply, oneExponent, Finsupp.single_eq_same] +omit [CompleteSpace A] [IsUltrametricDist A] in private theorem tendsto_nonnegativeExtension (a : ℕ → A) (ha : Tendsto a cofinite (𝓝 0)) : Tendsto (fun z : ℤ ↦ if 0 ≤ z then a z.toNat else 0) cofinite (𝓝 0) := by @@ -179,11 +181,13 @@ noncomputable def difference : (positive K A).comp (LinearMap.fst K _ _) - (negative K A).comp (LinearMap.snd K _ _) +omit [CompleteSpace K] [CompleteSpace A] in @[simp] theorem diagonal_apply (a : A) : diagonal K A a = (TateAlgebra.C A (Fin 1) a, TateAlgebra.C A (Fin 1) a) := rfl +omit [CompleteSpace K] [CompleteSpace A] in @[simp] theorem difference_coeff_zero (p q : TateAlgebra A (Fin 1)) : (difference K A (p, q)).1 0 = @@ -191,16 +195,19 @@ theorem difference_coeff_zero (p q : TateAlgebra A (Fin 1)) : TateAlgebra.coeff A (Fin 1) (oneExponent 0) q := by rfl +omit [CompleteSpace K] [CompleteSpace A] in theorem difference_coeff_pos (p q : TateAlgebra A (Fin 1)) (n : ℕ) (hn : 0 < n) : (difference K A (p, q)).1 (n : ℤ) = TateAlgebra.coeff A (Fin 1) (oneExponent n) p := by simp [difference, positive, negative, hn.ne'] +omit [CompleteSpace K] [CompleteSpace A] in theorem difference_coeff_neg (p q : TateAlgebra A (Fin 1)) (n : ℕ) (hn : 0 < n) : (difference K A (p, q)).1 (-(n : ℤ)) = -TateAlgebra.coeff A (Fin 1) (oneExponent n) q := by simp [difference, positive, negative, hn.ne'] +omit [CompleteSpace K] [CompleteSpace A] in /-- The image of the diagonal constants is the kernel of Laurent coefficient difference. -/ theorem exact : Function.Exact (diagonal K A) (difference K A) := by rintro ⟨p, q⟩ @@ -271,6 +278,7 @@ theorem exact : Function.Exact (diagonal K A) (difference K A) := by (n + 1) (Nat.succ_pos n) using 1 <;> simp [oneExponent] +omit [CompleteSpace K] [CompleteSpace A] in /-- Every restricted Laurent coefficient family splits into a nonnegative and a nonpositive Tate series. -/ theorem difference_surjective : Function.Surjective (difference K A) := by @@ -315,6 +323,7 @@ theorem difference_surjective : Function.Surjective (difference K A) := by · rw [coeff_ofCoefficients] simp [qa] +omit [CompleteSpace K] [CompleteSpace A] in /-- The completed Laurent coefficient sequence is short exact. -/ theorem shortExact : Function.Injective (diagonal K A) ∧ diff --git a/Rigid/AffinoidAlgebra/LaurentCharts.lean b/Rigid/AffinoidAlgebra/LaurentCharts.lean index f58a2d5..8e2c6f2 100644 --- a/Rigid/AffinoidAlgebra/LaurentCharts.lean +++ b/Rigid/AffinoidAlgebra/LaurentCharts.lean @@ -1,7 +1,6 @@ import Rigid.AffinoidAlgebra.RationalLocalization set_option linter.style.header false -set_option linter.unusedSectionVars false /-! # The analytic maps in a two-member Laurent cover diff --git a/Rigid/AffinoidAlgebra/LaurentCover.lean b/Rigid/AffinoidAlgebra/LaurentCover.lean index d8be743..6179aa0 100644 --- a/Rigid/AffinoidAlgebra/LaurentCover.lean +++ b/Rigid/AffinoidAlgebra/LaurentCover.lean @@ -2,7 +2,6 @@ import Mathlib.Algebra.Exact.Basic import Mathlib.Algebra.Polynomial.Laurent set_option linter.style.header false -set_option linter.unusedSectionVars false /-! # The algebraic Laurent-cover exact sequence diff --git a/Rigid/AffinoidAlgebra/NoetherNormalization.lean b/Rigid/AffinoidAlgebra/NoetherNormalization.lean index b494a4c..a8c0d89 100644 --- a/Rigid/AffinoidAlgebra/NoetherNormalization.lean +++ b/Rigid/AffinoidAlgebra/NoetherNormalization.lean @@ -546,6 +546,7 @@ private theorem succMap_tateVariable (n : ℕ) (i : Fin n) : (MvPowerSeries.X i.succ : MvPowerSeries (Fin (n + 1)) K) simp +omit [CompleteSpace K] in /-- The remaining-variable inclusion preserves the Gauss norm. -/ private theorem norm_succMap_eq (n : ℕ) (a : TateAlgebra K (Fin n)) : ‖succMap K n a‖ = ‖a‖ := by diff --git a/Rigid/AffinoidAlgebra/PowerBounded.lean b/Rigid/AffinoidAlgebra/PowerBounded.lean index 9dc3f56..2891171 100644 --- a/Rigid/AffinoidAlgebra/PowerBounded.lean +++ b/Rigid/AffinoidAlgebra/PowerBounded.lean @@ -2,7 +2,6 @@ import Mathlib.Analysis.Normed.Group.Ultra import Mathlib.Analysis.Normed.Operator.Banach import Mathlib.RingTheory.IntegralClosure.IsIntegral.Basic import Rigid.AffinoidAlgebra.RationalDatum -import Rigid.Berkovich.RelativeSpectrum set_option linter.style.header false @@ -194,24 +193,4 @@ theorem IsPowerBounded.map_continuousAlgHom (φ : ContinuousAlgHom K A B) {x : A end ContinuousAlgHom -section BerkovichSpectrumOver - -variable {B : Type u} [NormedCommRing B] - -/-- A power-bounded element has value at most one at every relative Berkovich point. -/ -theorem IsPowerBounded.apply_le_one - (K : Type v) [NormedField K] [Algebra K B] - (x : BerkovichSpectrumOver K B) {b : B} (hb : IsPowerBounded b) : x b ≤ 1 := by - rcases hb with ⟨C, hC⟩ - by_contra h - have hxb : 1 < x b := lt_of_not_ge h - obtain ⟨n, hn⟩ := pow_unbounded_of_one_lt C hxb - apply not_le_of_gt hn - calc - x b ^ n = x (b ^ n) := (map_pow x.toBerkovichSpectrum.seminorm b n).symm - _ ≤ ‖b ^ n‖ := BerkovichSpectrumOver.le_norm K B x _ - _ ≤ C := hC ⟨n, rfl⟩ - -end BerkovichSpectrumOver - end Rigid diff --git a/Rigid/AffinoidAlgebra/SpectralComponents.lean b/Rigid/AffinoidAlgebra/SpectralComponents.lean index 091ef89..412f426 100644 --- a/Rigid/AffinoidAlgebra/SpectralComponents.lean +++ b/Rigid/AffinoidAlgebra/SpectralComponents.lean @@ -20,6 +20,7 @@ variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametr variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] [IsUltrametricDist A] [Nontrivial A] +omit [CompleteSpace A] in /-- For every element, some minimal-prime quotient preserves its spectral radius. -/ theorem exists_minimalPrime_spectralRadius_eq_quotient (hA : IsAffinoidAlgebra K A) diff --git a/Rigid/AffinoidAlgebra/SpectralPolynomial.lean b/Rigid/AffinoidAlgebra/SpectralPolynomial.lean index 4eb9eb3..f35f54e 100644 --- a/Rigid/AffinoidAlgebra/SpectralPolynomial.lean +++ b/Rigid/AffinoidAlgebra/SpectralPolynomial.lean @@ -11,7 +11,6 @@ import Rigid.TateAlgebra.Domain import Rigid.TateAlgebra.UniqueFactorization set_option linter.style.header false -set_option linter.unusedSectionVars false /-! # Spectral polynomial relations @@ -174,6 +173,7 @@ section Normed variable [NormedRing R] [NormOneClass R] [Nontrivial R] +omit [Nontrivial R] in /-- The coefficient bound direction of `Polynomial.spectralValue_le_one_iff` needs no division in the coefficient ring. -/ theorem norm_coeff_le_one_of_spectralValue_le_one {P : R[X]} (hP : P.Monic) @@ -189,6 +189,7 @@ theorem norm_coeff_le_one_of_spectralValue_le_one {P : R[X]} (hP : P.Monic) variable {D : Type v} [NormedRing D] [Nontrivial D] +omit [NormOneClass R] [Nontrivial R] in /-- Spectral value does not increase when the coefficients are mapped by a norm-nonincreasing ring homomorphism. -/ theorem spectralValue_map_le (f : R →+* D) (hf : ∀ r, ‖f r‖ ≤ ‖r‖) @@ -209,6 +210,7 @@ theorem spectralValue_map_le (f : R →+* D) (hf : ∀ r, ‖f r‖ ≤ ‖r‖) _ ≤ ⨆ n, spectralValueTerms P n := le_ciSup (spectralValueTerms_bddAbove P) n +omit [NormOneClass R] [Nontrivial R] in /-- An isometric coefficient map preserves spectral value. -/ theorem spectralValue_map_eq (f : R →+* D) (hf : ∀ r, ‖f r‖ = ‖r‖) {P : R[X]} (hP : P.Monic) : spectralValue (P.map f) = spectralValue P := by @@ -323,6 +325,7 @@ variable [CompleteSpace K] variable {C : Type v} variable [NormedCommRing C] [NormedAlgebra K C] [CompleteSpace C] [IsUltrametricDist C] +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- Componentwise unit-ball relations over one continuous Tate-algebra map combine into the integral certificate used by Proposition 4.5.12. -/ theorem hasUnitBallIntegralCertificate_of_minimalPrime_quotients @@ -349,6 +352,7 @@ noncomputable def gaussAlgebraicClosureMap (n : ℕ) : (algebraMap (GaussResidueField K n) (GaussAlgebraicClosure K n)).comp (BerkovichSpectrumOver.completedResidueMap (TateAlgebra.gaussPoint K n)) +omit [CompleteSpace K] in @[simp] theorem spectralNorm_gaussAlgebraicClosureMap (n : ℕ) (a : TateAlgebra K (Fin n)) : spectralNorm (GaussResidueField K n) (GaussAlgebraicClosure K n) @@ -356,6 +360,7 @@ theorem spectralNorm_gaussAlgebraicClosureMap (n : ℕ) (a : TateAlgebra K (Fin rw [gaussAlgebraicClosureMap, RingHom.comp_apply, spectralNorm_extends, BerkovichSpectrumOver.norm_completedResidueMap, TateAlgebra.gaussPoint_apply] +omit [CompleteSpace K] in /-- Evaluation in the completed Gauss residue field, and hence in its algebraic closure, is injective. -/ theorem gaussAlgebraicClosureMap_injective (n : ℕ) : @@ -365,6 +370,7 @@ theorem gaussAlgebraicClosureMap_injective (n : ℕ) : apply norm_eq_zero.mp rw [← spectralNorm_gaussAlgebraicClosureMap K n a, ha, spectralNorm_zero] +omit [CompleteSpace K] [NormedAlgebra K C] [CompleteSpace C] [IsUltrametricDist C] in /-- A monic polynomial annihilating an element of a nontrivial algebra has positive degree. -/ theorem natDegree_pos_of_monic_relation [Nontrivial C] {n : ℕ} (π : TateAlgebra K (Fin n) →+* C) (c : C) @@ -376,6 +382,7 @@ theorem natDegree_pos_of_monic_relation [Nontrivial C] {n : ℕ} have hdeg := Polynomial.natDegree_pos_of_monic_of_aeval_eq_zero (hP.map π) hroot rwa [hP.natDegree_map] at hdeg +omit [CompleteSpace K] in /-- The root-theoretic part of Lemma 4.5.11 and Proposition 4.5.7. A positive-degree monic polynomial over a Tate algebra has a root over the completed Gauss residue field whose extended norm is exactly its spectral value. This is the existing nonarchimedean norm-extension theorem @@ -464,6 +471,7 @@ noncomputable def gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) : GaussAlgebraicClosure K n := Classical.choose (exists_gaussRoot_spectralNorm_eq_spectralValue K hP hPdeg) +omit [CompleteSpace K] in @[simp] theorem aeval_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) : @@ -471,6 +479,7 @@ theorem aeval_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} (P.map (gaussAlgebraicClosureMap K n)) = 0 := (Classical.choose_spec (exists_gaussRoot_spectralNorm_eq_spectralValue K hP hPdeg)).1 +omit [CompleteSpace K] in @[simp] theorem eval₂_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) : @@ -478,6 +487,7 @@ theorem eval₂_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} simpa only [Polynomial.aeval_def, Polynomial.eval₂_map, Algebra.algebraMap_self, RingHom.id_comp] using aeval_gaussMaxRoot K hP hPdeg +omit [CompleteSpace K] in @[simp] theorem spectralNorm_gaussMaxRoot {n : ℕ} {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) : @@ -494,6 +504,7 @@ noncomputable def gaussRootLift {n : ℕ} (P : (TateAlgebra K (Fin n))[X]) simpa only [Polynomial.aeval_def, Polynomial.eval₂_map, Algebra.algebraMap_self, RingHom.id_comp] using hz) +omit [CompleteSpace K] in @[simp] theorem gaussRootLift_root {n : ℕ} (P : (TateAlgebra K (Fin n))[X]) (z : GaussAlgebraicClosure K n) @@ -565,6 +576,7 @@ noncomputable def integralMinimalPolynomial {n : ℕ} letI : Algebra (TateAlgebra K (Fin n)) C := π.toRingHom.toAlgebra minpoly (TateAlgebra K (Fin n)) c +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- Finiteness makes the integral minimal polynomial monic. -/ theorem integralMinimalPolynomial_monic {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπfinite : π.Finite) (c : C) : @@ -575,6 +587,7 @@ theorem integralMinimalPolynomial_monic {n : ℕ} change (minpoly A c).Monic exact minpoly.monic (IsIntegral.of_finite A c) +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- The integral minimal polynomial annihilates the original element. -/ theorem eval₂_integralMinimalPolynomial {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C) (c : C) : @@ -584,6 +597,7 @@ theorem eval₂_integralMinimalPolynomial {n : ℕ} change Polynomial.eval₂ (algebraMap A C) c (minpoly A c) = 0 simpa only [Polynomial.aeval_def] using minpoly.aeval A c +omit [CompleteSpace C] [IsUltrametricDist C] in /-- Lemma 4.5.5 over an integrally closed base: the integral minimal polynomial becomes the field minimal polynomial after passing to fraction fields. -/ theorem isFractionMinpoly_integralMinimalPolynomial [IsDomain C] {n : ℕ} @@ -604,6 +618,7 @@ theorem isFractionMinpoly_integralMinimalPolynomial [IsDomain C] {n : ℕ} exact (minpoly.isIntegrallyClosed_eq_field_fractions (R := A) (S := C) (FractionRing A) (FractionRing C) (IsIntegral.of_finite A c)).symm +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- A relation identified with the fraction-field minimal polynomial annihilates the maximal Gauss root. -/ theorem hasFractionMinpolyGaussRoot_of_isFractionMinpoly [IsDomain C] {n : ℕ} @@ -636,6 +651,7 @@ theorem hasFractionMinpolyGaussRoot_of_isFractionMinpoly [IsDomain C] {n : ℕ} rw [← hmin, Polynomial.eval₂_map, hcomp] exact eval₂_gaussMaxRoot K hP hPdeg +omit [IsUltrametricDist C] in /-- Once the fraction-field minimal-polynomial identity is known, the Gauss-root functional is automatic: extend evaluation linearly and apply the finite-module open-mapping theorem. -/ theorem hasBoundedGaussMaxRootFunctional_of_fractionMinpolyRoot [IsDomain C] {n : ℕ} @@ -686,6 +702,7 @@ theorem hasBoundedGaussMaxRootFunctional_of_fractionMinpolyRoot [IsDomain C] {n (gaussMaxRoot K hP hPdeg) hroot' exact ⟨G, M, hM, hGpow, hG⟩ +omit [CompleteSpace K] [NormedAlgebra K C] [CompleteSpace C] [IsUltrametricDist C] in /-- A bounded functional for the chosen maximal root packages the bounded root realization. -/ theorem hasBoundedGaussRootRealization_of_maxRootFunctional {n : ℕ} (c : C) {P : (TateAlgebra K (Fin n))[X]} (hP : P.Monic) (hPdeg : 0 < P.natDegree) @@ -695,6 +712,7 @@ theorem hasBoundedGaussRootRealization_of_maxRootFunctional {n : ℕ} (c : C) exact ⟨gaussMaxRoot K hP hPdeg, aeval_gaussMaxRoot K hP hPdeg, spectralNorm_gaussMaxRoot K hP hPdeg, F, M, hM, hFpow, hFbound⟩ +omit [CompleteSpace K] [NormedAlgebra K C] [CompleteSpace C] [IsUltrametricDist C] in /-- A bounded Gauss-root realization supplies the difficult inequality in Proposition 4.5.7. -/ theorem spectralValue_le_spectralRadius_of_boundedGaussRootRealization [Nontrivial C] {n : ℕ} (c : C) {P : (TateAlgebra K (Fin n))[X]} @@ -708,6 +726,7 @@ theorem spectralValue_le_spectralRadius_of_boundedGaussRootRealization [Nontrivi rw [← hz] exact norm_le_spectralRadius_of_bounded_power_realization c z F M hM hFpow hbound +omit [CompleteSpace K] [CompleteSpace C] in /-- Any continuous monic Tate-algebra relation gives the standard upper bound `ρ(c) ≤ σ(P)`. The proof evaluates at a Berkovich point attaining the spectral radius, passes to its completed residue field, and applies Mathlib's nonarchimedean root bound there. Continuity is @@ -728,7 +747,7 @@ theorem spectralRadius_le_spectralValue_of_relation [Nontrivial C] {n : ℕ} have hφ (a : TateAlgebra K (Fin n)) : ‖φ a‖ ≤ ‖a‖ := by change ‖BerkovichSpectrumOver.completedResidueMap y (π a)‖ ≤ ‖a‖ rw [BerkovichSpectrumOver.norm_completedResidueMap] - exact BerkovichSpectrumOver.le_norm K _ + exact BerkovichSpectrumOver.le_norm K _ (BerkovichSpectrumOver.comapContinuous K _ πcont y) a have hz : Polynomial.aeval z (P.map φ) = 0 := by have hmap := congrArg (BerkovichSpectrumOver.completedResidueMap y) hPeval @@ -767,6 +786,7 @@ def HasSharpSpectralPolynomial (n : ℕ) (π : TateAlgebra K (Fin n) →ₐ[K] C ∃ P : (TateAlgebra K (Fin n))[X], P.Monic ∧ Polynomial.eval₂ π.toRingHom c P = 0 ∧ BerkovichSpectrum.spectralRadius C c = spectralValue P +omit [CompleteSpace K] [CompleteSpace C] in /-- Proposition 4.5.7 reduced to its finite-module functional: the usual root bound gives one inequality, while a bounded realization of the maximal Gauss root gives the other. -/ theorem hasSharpSpectralPolynomial_of_boundedGaussRootRealization [Nontrivial C] {n : ℕ} @@ -779,6 +799,7 @@ theorem hasSharpSpectralPolynomial_of_boundedGaussRootRealization [Nontrivial C] (spectralRadius_le_spectralValue_of_relation K π hπ c hPmonic hPeval) ?_⟩ exact spectralValue_le_spectralRadius_of_boundedGaussRootRealization K c hroot +omit [CompleteSpace K] [CompleteSpace C] in /-- Domain-case Proposition 4.5.7 with only its final bounded-functional input exposed. -/ theorem hasSharpSpectralPolynomial_of_maxRootFunctional [Nontrivial C] {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπ : Continuous π) @@ -824,6 +845,7 @@ def HasGaussFiberMaximum {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C) (c : ∃ y : BerkovichSpectrumOver K C, (∀ a, y (π a) = ‖a‖) ∧ y c = spectralValue P +omit [CompleteSpace K] [CompleteSpace C] in /-- The standard upper bound together with the finite-fiber maximum gives the sharp equality of Proposition 4.5.7. -/ theorem hasSharpSpectralPolynomial_of_gaussFiberMaximum [Nontrivial C] {n : ℕ} @@ -837,6 +859,7 @@ theorem hasSharpSpectralPolynomial_of_gaussFiberMaximum [Nontrivial C] {n : ℕ} rw [← hy] exact BerkovichSpectrumOver.le_spectralRadius K C y c +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- A sharp spectral polynomial for an element in the closed spectral unit ball has all its coefficients in the Gauss unit ball. -/ theorem hasUnitBallRelation_of_hasSharpSpectralPolynomial {n : ℕ} @@ -851,6 +874,7 @@ theorem hasUnitBallRelation_of_hasSharpSpectralPolynomial {n : ℕ} apply norm_coeff_le_one_of_spectralValue_le_one hPmonic rwa [← hsharp] +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- Proposition 4.5.3 immediately supplies the certificate used in Proposition 4.5.12. -/ theorem hasUnitBallIntegralCertificate_of_hasSharpSpectralPolynomial {n : ℕ} (π : TateAlgebra K (Fin n) →ₐ[K] C) (hπ : Continuous π) (c : C) @@ -883,6 +907,7 @@ theorem hasSharpNoetherNormalization_of_isAffinoidAlgebra_of_isDomain [IsDomain hasSharpSpectralPolynomial_of_integrallyClosedNormalization K π hπinj hπfinite hπcont⟩ +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- Sharp spectral polynomials over one Noether normalization imply the boundary case in the power-boundedness criterion. -/ theorem hasPowerBoundedSpectralCriterion_of_hasSharpNoetherNormalization [Nontrivial C] @@ -892,6 +917,7 @@ theorem hasPowerBoundedSpectralCriterion_of_hasSharpNoetherNormalization [Nontri obtain ⟨n, π, -, -, hπ, hsharp⟩ := hC exact hasUnitBallIntegralCertificate_of_hasSharpSpectralPolynomial K π hπ c hc (hsharp c) +omit [CompleteSpace K] [CompleteSpace C] [IsUltrametricDist C] in /-- The non-domain form of Proposition 4.5.3 reduced to its componentwise input. All minimal prime components must use one continuous Tate-algebra coefficient map; the algebraic minimal-prime argument then removes the nilpotent error. -/ diff --git a/Rigid/AffinoidAlgebra/SpectralPresentation.lean b/Rigid/AffinoidAlgebra/SpectralPresentation.lean index ee1168d..3b7ceef 100644 --- a/Rigid/AffinoidAlgebra/SpectralPresentation.lean +++ b/Rigid/AffinoidAlgebra/SpectralPresentation.lean @@ -26,6 +26,7 @@ variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametr variable {A : Type v} [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] [IsUltrametricDist A] +omit [CompleteSpace A] [IsUltrametricDist A] in /-- Affinoid algebras are Noetherian, recorded in the production namespace. -/ theorem isNoetherianRing_of_affinoidAlgebra (hA : IsAffinoidAlgebra K A) : IsNoetherianRing A := by diff --git a/Rigid/AffinoidAlgebra/SpectralRadius.lean b/Rigid/AffinoidAlgebra/SpectralRadius.lean index 8154245..97faae1 100644 --- a/Rigid/AffinoidAlgebra/SpectralRadius.lean +++ b/Rigid/AffinoidAlgebra/SpectralRadius.lean @@ -2,13 +2,12 @@ import Rigid.AffinoidAlgebra.MaximumModulus import Rigid.Berkovich.SpectralRadius set_option linter.style.header false -set_option linter.unusedSectionVars false /-! # Spectral radius and power-bounded elements This file formalizes the analytic part of Proposition 4.5.12 from the cited draft. In every -Banach algebra, power-bounded elements have spectral radius at most one, and spectral radius +normed algebra, power-bounded elements have spectral radius at most one, and spectral radius strictly less than one implies power-boundedness. The boundary case is reduced to the monic unit-ball relation supplied by Noether normalization. For a Tate algebra that relation is not needed: the Gauss point identifies the spectral radius with the Gauss norm directly. @@ -27,6 +26,7 @@ variable {B : Type v} [NormedCommRing B] [NormedAlgebra K B] [CompleteSpace B] namespace IsPowerBounded +omit [CompleteSpace B] [IsUltrametricDist B] in /-- A power-bounded element has spectral radius at most one. -/ theorem spectralRadius_le_one [Nontrivial B] {b : B} (hb : IsPowerBounded b) : BerkovichSpectrum.spectralRadius B b ≤ 1 := by @@ -42,6 +42,7 @@ theorem spectralRadius_le_one [Nontrivial B] {b : B} (hb : IsPowerBounded b) : _ ≤ ‖b ^ n‖ := BerkovichSpectrum.le_norm B x _ _ ≤ C := hC ⟨n, rfl⟩ +omit [CompleteSpace B] [IsUltrametricDist B] in private theorem of_normalizedNorm_pow_lt_one [Nontrivial B] {b : B} {n : ℕ} (hn : 0 < n) (hbn : BerkovichSpectrum.normalizedNormSeminorm B (b ^ n) < 1) : IsPowerBounded b := by @@ -73,8 +74,9 @@ private theorem of_normalizedNorm_pow_lt_one [Nontrivial B] {b : B} {n : ℕ} (h _ ≤ ‖(1 : B)‖ * D := by simpa using mul_le_mul_of_nonneg_left hrem (norm_nonneg (1 : B)) -/-- Spectral radius strictly less than one implies power-boundedness in any complete normed -algebra. The affinoid input is needed only for the boundary case `ρ = 1`. -/ +omit [CompleteSpace B] [IsUltrametricDist B] in +/-- Spectral radius strictly less than one implies power-boundedness in any normed algebra. +The affinoid input is needed only for the boundary case `ρ = 1`. -/ theorem of_spectralRadius_lt_one [Nontrivial B] {b : B} (hb : BerkovichSpectrum.spectralRadius B b < 1) : IsPowerBounded b := by have hev : ∀ᶠ n : ℕ in atTop, @@ -93,6 +95,7 @@ end IsPowerBounded namespace TateAlgebra +omit [CompleteSpace K] in /-- On a strict Tate algebra, the spectral radius is the Gauss norm. -/ theorem spectralRadius_eq_norm (n : ℕ) (f : TateAlgebra K (Fin n)) : BerkovichSpectrum.spectralRadius (TateAlgebra K (Fin n)) f = ‖f‖ := by @@ -100,6 +103,7 @@ theorem spectralRadius_eq_norm (n : ℕ) (f : TateAlgebra K (Fin n)) : · exact BerkovichSpectrum.spectralRadius_le_norm _ f · simpa using BerkovichSpectrumOver.le_spectralRadius K _ (gaussPoint K n) f +omit [CompleteSpace K] in /-- Proposition 4.5.12(ii) for the Tate-algebra base case. -/ theorem isPowerBounded_iff_spectralRadius_le_one {n : ℕ} {f : TateAlgebra K (Fin n)} : IsPowerBounded f ↔ BerkovichSpectrum.spectralRadius (TateAlgebra K (Fin n)) f ≤ 1 := by @@ -113,6 +117,7 @@ def HasUnitBallIntegralCertificate (b : B) : Prop := ∃ (n : ℕ) (π : ContinuousAlgHom K (TateAlgebra K (Fin n)) B), IsIntegral ((TateAlgebra.unitBallSubring K n).map π.toRingHom) b +omit [CompleteSpace K] [CompleteSpace B] [IsUltrametricDist B] in /-- A unit-ball integral certificate implies power-boundedness. -/ theorem isPowerBounded_of_hasUnitBallIntegralCertificate {b : B} (hb : HasUnitBallIntegralCertificate K b) : IsPowerBounded b := by @@ -123,6 +128,7 @@ theorem isPowerBounded_of_hasUnitBallIntegralCertificate {b : B} def HasPowerBoundedSpectralCriterion (B : Type v) [NormedCommRing B] : Prop := ∀ b : B, BerkovichSpectrum.spectralRadius B b ≤ 1 → IsPowerBounded b +omit [CompleteSpace K] [CompleteSpace B] [IsUltrametricDist B] in /-- Unit-ball integral certificates for the closed spectral unit ball imply the boundary criterion. -/ theorem hasPowerBoundedSpectralCriterion_of_certificates @@ -130,6 +136,7 @@ theorem hasPowerBoundedSpectralCriterion_of_certificates HasUnitBallIntegralCertificate K b) : HasPowerBoundedSpectralCriterion B := fun b hb ↦ isPowerBounded_of_hasUnitBallIntegralCertificate K (hcertificate b hb) +omit [CompleteSpace K] [CompleteSpace B] [IsUltrametricDist B] in /-- The boundary step in Proposition 4.5.12(ii), isolated in the exact form supplied by its Noether-normalization proof. -/ theorem isPowerBounded_iff_spectralRadius_le_one_of_certificate @@ -141,6 +148,7 @@ theorem isPowerBounded_iff_spectralRadius_le_one_of_certificate · exact IsPowerBounded.spectralRadius_le_one · exact fun hb ↦ isPowerBounded_of_hasUnitBallIntegralCertificate K (hcertificate b hb) +omit [CompleteSpace B] [IsUltrametricDist B] in /-- Once the affinoid boundary criterion is available, power-boundedness is characterized exactly by spectral radius at most one. -/ theorem isPowerBounded_iff_spectralRadius_le_one [Nontrivial B] diff --git a/Rigid/AffinoidSpectrum/RationalRefinement.lean b/Rigid/AffinoidSpectrum/RationalRefinement.lean index a2f69a8..2594964 100644 --- a/Rigid/AffinoidSpectrum/RationalRefinement.lean +++ b/Rigid/AffinoidSpectrum/RationalRefinement.lean @@ -1,7 +1,6 @@ import Rigid.AffinoidSpectrum.RationalCover set_option linter.style.header false -set_option linter.unusedSectionVars false open scoped BigOperators diff --git a/Rigid/AffinoidSpectrum/Restriction.lean b/Rigid/AffinoidSpectrum/Restriction.lean index 4cdcc68..65b365f 100644 --- a/Rigid/AffinoidSpectrum/Restriction.lean +++ b/Rigid/AffinoidSpectrum/Restriction.lean @@ -4,7 +4,6 @@ import Rigid.AffinoidSpectrum.RationalBasis import Rigid.Berkovich.Unit set_option linter.style.header false -set_option linter.unusedSectionVars false /-! # Restriction between rational subdomains @@ -47,7 +46,7 @@ theorem ambientPoint_mem_carrier (U : AffinoidRationalSubdomain K A) BerkovichSpectrumOver.map_mul] exact mul_le_of_le_one_right (BerkovichSpectrumOver.nonneg K U.Sections y _) - (IsPowerBounded.apply_le_one K y + (BerkovichSpectrumOver.apply_le_one_of_isPowerBounded K U.Sections y (RationalLocalization.isPowerBounded_coordinate K A U.n U.g U.f i)) /-- If `U ⊆ V`, the denominator defining `V` is invertible on the section algebra of `U`. -/ diff --git a/Rigid/Berkovich/Unit.lean b/Rigid/Berkovich/Unit.lean index d882ce2..a51c24d 100644 --- a/Rigid/Berkovich/Unit.lean +++ b/Rigid/Berkovich/Unit.lean @@ -3,7 +3,6 @@ import Mathlib.Analysis.Normed.Group.Quotient import Rigid.Berkovich.RelativeNonempty set_option linter.style.header false -set_option linter.unusedSectionVars false /-! # Detecting units on the Berkovich spectrum @@ -23,6 +22,7 @@ variable (A : Type v) [NormedCommRing A] [NormedAlgebra K A] [CompleteSpace A] namespace BerkovichSpectrumOver +omit [CompleteSpace A] in /-- A unit has nonzero value at every relative Berkovich point. -/ theorem apply_ne_zero_of_isUnit {a : A} (ha : IsUnit a) (x : BerkovichSpectrumOver K A) : x a ≠ 0 := by diff --git a/Rigid/TateAlgebra/FirstVariable.lean b/Rigid/TateAlgebra/FirstVariable.lean index 2a3d141..fdd6364 100644 --- a/Rigid/TateAlgebra/FirstVariable.lean +++ b/Rigid/TateAlgebra/FirstVariable.lean @@ -50,7 +50,7 @@ noncomputable def succMap (n : ℕ) : rw [mem_cofinite] at hp ⊢ refine hp.image (Finsupp.embDomain e) |>.subset ?_ intro x hx - simp only [Set.mem_compl_iff, Set.mem_setOf_eq] at hx ⊢ + simp only [Set.mem_compl_iff] at hx ⊢ by_cases hxr : x ∈ Set.range (Finsupp.embDomain e) · obtain ⟨y, rfl⟩ := hxr refine ⟨y, ?_, rfl⟩ @@ -63,6 +63,7 @@ noncomputable def succMap (n : ℕ) : · simpa [Finsupp.embDomain_eq_mapDomain] using hxr simpa [MvPowerSeries.IsRestricted, Finsupp.prod] using hrename +omit [CompleteSpace K] in @[simp] theorem succMap_tateVariable (n : ℕ) (i : Fin n) : succMap K n (tateVariable K (Fin n) i) = tateVariable K (Fin (n + 1)) i.succ := by @@ -84,6 +85,7 @@ noncomputable def coeffSlice (n j : ℕ) (f : TateAlgebra K (Fin (n + 1))) : exact (tendsto_norm_coeff_zero K (Fin (n + 1)) f).comp (Finsupp.cons_right_injective j).tendsto_cofinite⟩ +omit [CompleteSpace K] in @[simp] theorem coeff_coeffSlice (n j : ℕ) (f : TateAlgebra K (Fin (n + 1))) (μ : Fin n →₀ ℕ) : @@ -91,17 +93,20 @@ theorem coeff_coeffSlice (n j : ℕ) (f : TateAlgebra K (Fin (n + 1))) MvPowerSeries.coeff (μ.cons j) f.1 := rfl +omit [CompleteSpace K] in private theorem monomial_single_zero_eq_tateVariable_pow (n j : ℕ) : monomial (Finsupp.single (0 : Fin (n + 1)) j) (1 : K) = tateVariable K (Fin (n + 1)) 0 ^ j := by apply Subtype.ext exact (MvPowerSeries.X_pow_eq (R := K) (0 : Fin (n + 1)) j).symm +omit [CompleteSpace K] in private theorem coe_succMap (n : ℕ) (a : TateAlgebra K (Fin n)) : ((succMap K n a : TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) = MvPowerSeries.rename (Fin.succEmb n) a.1 := rfl +omit [CompleteSpace K] in theorem coeff_succMap_mul_tateVariable_pow (n j : ℕ) (a : TateAlgebra K (Fin n)) (μ : Fin (n + 1) →₀ ℕ) : MvPowerSeries.coeff μ @@ -143,6 +148,7 @@ theorem coeff_succMap_mul_tateVariable_pow (n j : ℕ) exact hjμ (Nat.le_antisymm (by simpa [Finsupp.single_le_iff] using hle) hμj) · rfl +omit [CompleteSpace K] in /-- A series whose first-variable exponents are bounded by `d` is a polynomial of degree less than `d` in that variable, with coefficients in the remaining-variable Tate algebra. -/ theorem eq_sum_succMap_coeffSlice_mul_pow {n d : ℕ} @@ -186,12 +192,14 @@ noncomputable def firstVariablePolynomialMap (n : ℕ) : Polynomial (TateAlgebra K (Fin n)) →+* TateAlgebra K (Fin (n + 1)) := Polynomial.eval₂RingHom (succMap K n).toRingHom (tateVariable K (Fin (n + 1)) 0) +omit [CompleteSpace K] in @[simp] theorem firstVariablePolynomialMap_monomial (n j : ℕ) (a : TateAlgebra K (Fin n)) : firstVariablePolynomialMap K n (Polynomial.monomial j a) = succMap K n a * tateVariable K (Fin (n + 1)) 0 ^ j := by simp [firstVariablePolynomialMap] +omit [CompleteSpace K] in theorem firstVariablePolynomialMap_eq_sum (n : ℕ) (p : Polynomial (TateAlgebra K (Fin n))) : firstVariablePolynomialMap K n p = @@ -207,6 +215,7 @@ theorem firstVariablePolynomialMap_eq_sum (n : ℕ) succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j := by simp [firstVariablePolynomialMap] +omit [CompleteSpace K] in /-- Coefficients of a first-variable polynomial are read by splitting an exponent into its first coordinate and its tail. -/ theorem coeff_firstVariablePolynomialMap (n : ℕ) @@ -214,11 +223,6 @@ theorem coeff_firstVariablePolynomialMap (n : ℕ) MvPowerSeries.coeff μ (firstVariablePolynomialMap K n p).1 = MvPowerSeries.coeff μ.tail (p.coeff (μ 0)).1 := by rw [firstVariablePolynomialMap_eq_sum] - change MvPowerSeries.coeff μ - ((∑ j ∈ Finset.range (p.natDegree + 1), - succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j : - TateAlgebra K (Fin (n + 1))) : MvPowerSeries (Fin (n + 1)) K) = - MvPowerSeries.coeff μ.tail (p.coeff (μ 0)).1 rw [show MvPowerSeries.coeff μ ((∑ j ∈ Finset.range (p.natDegree + 1), succMap K n (p.coeff j) * tateVariable K (Fin (n + 1)) 0 ^ j : @@ -246,6 +250,7 @@ theorem coeff_firstVariablePolynomialMap (n : ℕ) subst j exact hμ (Finset.mem_range.mp hj) +omit [CompleteSpace K] in /-- Evaluation in the first Tate variable is injective. -/ theorem firstVariablePolynomialMap_injective (n : ℕ) : Function.Injective (firstVariablePolynomialMap K n) := by @@ -264,6 +269,7 @@ noncomputable def toFirstVariablePolynomial (n d : ℕ) (f : TateAlgebra K (Fin (n + 1))) : Polynomial (TateAlgebra K (Fin n)) := ∑ j ∈ Finset.range d, Polynomial.monomial j (coeffSlice K n j f) +omit [CompleteSpace K] in @[simp] theorem coeff_toFirstVariablePolynomial (n d j : ℕ) (f : TateAlgebra K (Fin (n + 1))) : @@ -272,6 +278,7 @@ theorem coeff_toFirstVariablePolynomial (n d j : ℕ) classical simp [toFirstVariablePolynomial, Polynomial.coeff_monomial, eq_comm] +omit [CompleteSpace K] in theorem firstVariablePolynomialMap_toFirstVariablePolynomial {n d : ℕ} (f : TateAlgebra K (Fin (n + 1))) (hf : ∀ μ : Fin (n + 1) →₀ ℕ, d ≤ μ 0 → MvPowerSeries.coeff μ f.1 = 0) : @@ -288,6 +295,7 @@ noncomputable def weierstrassPolynomial {n d : ℕ} (w : TateAlgebra K (Fin (n + Polynomial (TateAlgebra K (Fin n)) := toFirstVariablePolynomial K n (d + 1) w +omit [CompleteSpace K] in theorem firstVariablePolynomialMap_weierstrassPolynomial {n d : ℕ} {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : firstVariablePolynomialMap K n (weierstrassPolynomial K (d := d) w) = w := by @@ -299,6 +307,7 @@ theorem firstVariablePolynomialMap_weierstrassPolynomial {n d : ℕ} simp at hμ · omega +omit [CompleteSpace K] in theorem isMonicOfDegree_weierstrassPolynomial {n d : ℕ} {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : Polynomial.IsMonicOfDegree (weierstrassPolynomial K (d := d) w) d := by @@ -328,6 +337,7 @@ theorem isMonicOfDegree_weierstrassPolynomial {n d : ℕ} rw [← map_one (algebraMap K (TateAlgebra K (Fin n))), algebraMap_apply, TateAlgebra.coeff_C, if_neg hμ] +omit [CompleteSpace K] in theorem IsWeierstrassOfDegree.norm_eq_one {n d : ℕ} {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : ‖w‖ = 1 := by @@ -348,6 +358,7 @@ private theorem single_zero_le_of_lex_lt {n d : ℕ} {μ : Fin (n + 1) →₀ have heq := hj 0 h0j simpa using heq.le +omit [CompleteSpace K] in theorem IsWeierstrassOfDegree.leadingDegree {n d : ℕ} {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : leadingDegree (MonomialOrder.lex : MonomialOrder (Fin (n + 1))) w = @@ -371,6 +382,7 @@ theorem IsWeierstrassOfDegree.leadingDegree {n d : ℕ} rw [hzero, norm_zero, hw.norm_eq_one K] at hμ norm_num at hμ +omit [CompleteSpace K] in /-- A monic first-variable polynomial is Weierstrass exactly when its Tate norm is at most one. -/ theorem isWeierstrassOfDegree_firstVariablePolynomialMap_iff {n d : ℕ} {p : Polynomial (TateAlgebra K (Fin n))} @@ -415,6 +427,7 @@ theorem isWeierstrassOfDegree_firstVariablePolynomialMap_iff {n d : ℕ} rw [Polynomial.coeff_eq_zero_of_natDegree_lt (hp.natDegree_eq ▸ hdlt)] simp +omit [CompleteSpace K] in /-- Rückert's factor-closure property for Weierstrass polynomials (Definition 4.1.13, R1). -/ theorem isWeierstrassOfDegree_mul_iff {n d e : ℕ} {p q : Polynomial (TateAlgebra K (Fin n))} diff --git a/Rigid/TateAlgebra/Ruckert.lean b/Rigid/TateAlgebra/Ruckert.lean index 3b70fb2..a8f1352 100644 --- a/Rigid/TateAlgebra/Ruckert.lean +++ b/Rigid/TateAlgebra/Ruckert.lean @@ -24,6 +24,7 @@ namespace TateAlgebra variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +omit [CompleteSpace K] in private theorem isWeierstrass_ne_zero {n d : ℕ} {w : TateAlgebra K (Fin (n + 1))} (hw : IsWeierstrassOfDegree d w) : w ≠ 0 := by intro h @@ -31,6 +32,7 @@ private theorem isWeierstrass_ne_zero {n d : ℕ} rw [h, norm_zero] at hnorm norm_num at hnorm +omit [CompleteSpace K] in /-- The first coordinate of the leading exponent of a first-variable polynomial is at most its polynomial degree. -/ theorem leadingDegree_zero_le_natDegree_firstVariablePolynomialMap {n : ℕ} @@ -55,12 +57,13 @@ theorem leadingDegree_zero_le_natDegree_firstVariablePolynomialMap {n : ℕ} rw [leadingCoeff, hcoeffzero, norm_zero] at hnorm exact (norm_pos_iff.mpr hmap).ne' hnorm.symm +omit [CompleteSpace K] in /-- A polynomial of degree below a Weierstrass polynomial cannot become a nonzero multiple of that Weierstrass element in the Tate algebra. -/ theorem eq_zero_of_natDegree_lt_of_firstVariablePolynomialMap_dvd_weierstrass {n d : ℕ} {W r : Polynomial (TateAlgebra K (Fin n))} {w : TateAlgebra K (Fin (n + 1))} - (hW : Polynomial.IsMonicOfDegree W d) + (_hW : Polynomial.IsMonicOfDegree W d) (hw : IsWeierstrassOfDegree d w) (hWw : firstVariablePolynomialMap K n W = w) (hrdeg : r.natDegree < d) @@ -92,6 +95,7 @@ noncomputable def weierstrassQuotientMap {n : ℕ} TateAlgebra K (Fin (n + 1)) ⧸ Ideal.span ({w} : Set (TateAlgebra K (Fin (n + 1)))) := (Ideal.Quotient.mk _).comp (firstVariablePolynomialMap K n) +omit [CompleteSpace K] in theorem ker_weierstrassQuotientMap {n d : ℕ} {W : Polynomial (TateAlgebra K (Fin n))} {w : TateAlgebra K (Fin (n + 1))} diff --git a/Rigid/TateAlgebra/UniqueFactorization.lean b/Rigid/TateAlgebra/UniqueFactorization.lean index 8e66810..29ea9db 100644 --- a/Rigid/TateAlgebra/UniqueFactorization.lean +++ b/Rigid/TateAlgebra/UniqueFactorization.lean @@ -25,6 +25,7 @@ namespace TateAlgebra variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] +omit [CompleteSpace K] in /-- A monic polynomial whose first-variable image is a Weierstrass unit has degree zero. -/ theorem natDegree_eq_zero_of_isUnit_firstVariablePolynomialMap {n d : ℕ} {p : Polynomial (TateAlgebra K (Fin n))} From cec20f019f3886db6057fdf22f0abbae23888acb Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 23 Jul 2026 15:55:03 +0900 Subject: [PATCH 5/7] Add the Berkovich locally ringed core Model the ordinary K-locally-ringed layer as locally ringed spaces over the universe lift of Spec K. Reuse mathlib for the faithful forgetful functor, point maps, sections, stalks, and germs, and correct the global Berkovich comparator universes to contain this core. --- Rigid.lean | 1 + Rigid/Berkovich/LocallyRingedSpace.lean | 112 ++++++++++++++++++++++++ Rigid/Challenge.lean | 6 +- Rigid/Development.lean | 6 +- 4 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 Rigid/Berkovich/LocallyRingedSpace.lean diff --git a/Rigid.lean b/Rigid.lean index eee8a88..8ff5cb9 100644 --- a/Rigid.lean +++ b/Rigid.lean @@ -20,6 +20,7 @@ import Rigid.Berkovich.CompletedResidue import Rigid.Berkovich.CompletedResidueFunctoriality import Rigid.Berkovich.GaussPoint import Rigid.Berkovich.GeneralSmoothing +import Rigid.Berkovich.LocallyRingedSpace import Rigid.Berkovich.Nonempty import Rigid.Berkovich.RationalLocalization import Rigid.Berkovich.RelativeNonempty diff --git a/Rigid/Berkovich/LocallyRingedSpace.lean b/Rigid/Berkovich/LocallyRingedSpace.lean new file mode 100644 index 0000000..a7dbc31 --- /dev/null +++ b/Rigid/Berkovich/LocallyRingedSpace.lean @@ -0,0 +1,112 @@ +import Mathlib.AlgebraicGeometry.Spec + +set_option linter.style.header false + +/-! +# The ordinary locally ringed core of a Berkovich space + +The ordinary locally ringed layer of a Berkovich space over `K` is a locally ringed space equipped +with a structure morphism to `Spec K`. We express this directly as a mathlib over category, using a +universe lift of `K` so that point spaces and section rings may live one universe above the ground +field. The structure sheaf, stalks, germ maps, locally ringed morphisms, and category structure then +come from mathlib. + +This core does not include the norm on `K`, analytic domains, an admissible G-topology, or an +affinoid atlas. Those belong to the later analytic-space layer. +-/ + +open CategoryTheory +open Opposite +open TopologicalSpace + +universe u + +namespace Rigid.Berkovich + +/-- The ordinary locally ringed-space data of a Berkovich space over `K`. + +An object consists of a locally ringed space in universe `u + 1` and a structure morphism to the +spectrum of the canonical universe lift of `K`. Analytic data added later can project to this core +without storing separate section, stalk, or germ data. -/ +abbrev LocallyRingedCore (K : Type u) [CommRing K] := + Over (AlgebraicGeometry.Spec.locallyRingedSpaceObj + (CommRingCat.of (ULift.{u + 1, u} K))) + +namespace LocallyRingedCore + +variable {K : Type u} [CommRing K] + +/-- Forget the structure morphism to `Spec K` and retain the underlying locally ringed space. -/ +noncomputable def locallyRingedSpaceFunctor : + LocallyRingedCore K ⥤ AlgebraicGeometry.LocallyRingedSpace.{u + 1} := + Over.forget _ + +noncomputable instance locallyRingedSpaceFunctorFaithful : + (locallyRingedSpaceFunctor (K := K)).Faithful where + map_injective h := Over.OverMorphism.ext h + +/-- The functor assigning the underlying topological point space to a locally ringed core. -/ +noncomputable def pointFunctor : LocallyRingedCore K ⥤ TopCat.{u + 1} := + locallyRingedSpaceFunctor ⋙ AlgebraicGeometry.LocallyRingedSpace.forgetToTop + +/-- The points of an ordinary locally ringed core. -/ +abbrev Point (X : LocallyRingedCore K) : Type (u + 1) := X.left + +/-- The core point topology is the topology underlying its locally ringed space. -/ +noncomputable def pointHomeomorph (X : LocallyRingedCore K) : + Point X ≃ₜ X.left.toTopCat := + Homeomorph.refl _ + +namespace Point + +/-- The point map induced by a morphism of ordinary locally ringed cores. -/ +noncomputable def map {X Y : LocallyRingedCore K} (f : X ⟶ Y) : Point X → Point Y := + (locallyRingedSpaceFunctor.map f).toHom.base + +/-- Point maps induced by locally ringed morphisms are continuous. -/ +theorem continuous_map {X Y : LocallyRingedCore K} (f : X ⟶ Y) : Continuous (map f) := + ((locallyRingedSpaceFunctor.map f).toHom.base).hom.continuous + +@[simp] +theorem map_id (X : LocallyRingedCore K) : map (𝟙 X) = id := + rfl + +@[simp] +theorem map_comp {X Y Z : LocallyRingedCore K} (f : X ⟶ Y) (g : Y ⟶ Z) : + map (f ≫ g) = map g ∘ map f := + rfl + +end Point + +/-- Naturality of the point identification with the underlying locally ringed space. -/ +@[simp] +theorem pointHomeomorph_naturality {X Y : LocallyRingedCore K} (f : X ⟶ Y) + (x : Point X) : + pointHomeomorph Y (Point.map f x) = + (locallyRingedSpaceFunctor.map f).toHom.base (pointHomeomorph X x) := + rfl + +namespace StructureSheaf + +/-- Sections on an ordinary open, obtained from the mathlib structure sheaf. -/ +abbrev Sections (X : LocallyRingedCore K) (U : Opens (Point X)) : Type (u + 1) := + X.left.presheaf.obj (op U) + +/-- The stalk at a point, obtained from the mathlib structure sheaf. -/ +noncomputable abbrev Stalk (X : LocallyRingedCore K) (x : Point X) : Type (u + 1) := + X.left.presheaf.stalk x + +instance stalkIsLocalRing (X : LocallyRingedCore K) (x : Point X) : + IsLocalRing (Stalk X x) := + inferInstance + +/-- The canonical germ map supplied by the mathlib structure sheaf. -/ +noncomputable def germ (X : LocallyRingedCore K) (U : Opens (Point X)) + (x : Point X) (hx : x ∈ U) : Sections X U →+* Stalk X x := + (X.left.presheaf.germ U x hx).hom + +end StructureSheaf + +end LocallyRingedCore + +end Rigid.Berkovich diff --git a/Rigid/Challenge.lean b/Rigid/Challenge.lean index 16b5632..574bd10 100644 --- a/Rigid/Challenge.lean +++ b/Rigid/Challenge.lean @@ -1560,7 +1560,7 @@ end RigidSpace algebras. -/ def BerkovichSpace (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] : - Type (u + 1) := sorry + Type (u + 2) := sorry noncomputable instance berkovichSpaceCategory : Category.{u + 1} (BerkovichSpace K) := sorry @@ -1620,7 +1620,7 @@ namespace StructureSheaf /-- Analytic functions on an open subset of a Berkovich space. -/ noncomputable def Sections {X : BerkovichSpace K} - (U : TopologicalSpace.Opens (Point K X)) : Type u := sorry + (U : TopologicalSpace.Opens (Point K X)) : Type (u + 1) := sorry noncomputable instance sectionsCommRing {X : BerkovichSpace K} (U : TopologicalSpace.Opens (Point K X)) : CommRing (Sections K U) := sorry @@ -1658,7 +1658,7 @@ theorem existsUnique_glue {X : BerkovichSpace K} {ι : Type (u + 1)} ∃! t : Sections K V, ∀ i, restriction K (hsub i) t = s i := sorry /-- The local ring of germs at a Berkovich point. -/ -noncomputable def Stalk (X : BerkovichSpace K) (x : Point K X) : Type u := sorry +noncomputable def Stalk (X : BerkovichSpace K) (x : Point K X) : Type (u + 1) := sorry noncomputable instance stalkCommRing (X : BerkovichSpace K) (x : Point K X) : CommRing (Stalk K X x) := sorry diff --git a/Rigid/Development.lean b/Rigid/Development.lean index a537480..a6e0e6c 100644 --- a/Rigid/Development.lean +++ b/Rigid/Development.lean @@ -2027,7 +2027,7 @@ end RigidSpace algebras. -/ def BerkovichSpace (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] : - Type (u + 1) := sorry + Type (u + 2) := sorry noncomputable instance berkovichSpaceCategory : Category.{u + 1} (BerkovichSpace K) := sorry @@ -2087,7 +2087,7 @@ namespace StructureSheaf /-- Analytic functions on an open subset of a Berkovich space. -/ noncomputable def Sections {X : BerkovichSpace K} - (U : TopologicalSpace.Opens (Point K X)) : Type u := sorry + (U : TopologicalSpace.Opens (Point K X)) : Type (u + 1) := sorry noncomputable instance sectionsCommRing {X : BerkovichSpace K} (U : TopologicalSpace.Opens (Point K X)) : CommRing (Sections K U) := sorry @@ -2125,7 +2125,7 @@ theorem existsUnique_glue {X : BerkovichSpace K} {ι : Type (u + 1)} ∃! t : Sections K V, ∀ i, restriction K (hsub i) t = s i := sorry /-- The local ring of germs at a Berkovich point. -/ -noncomputable def Stalk (X : BerkovichSpace K) (x : Point K X) : Type u := sorry +noncomputable def Stalk (X : BerkovichSpace K) (x : Point K X) : Type (u + 1) := sorry noncomputable instance stalkCommRing (X : BerkovichSpace K) (x : Point K X) : CommRing (Stalk K X x) := sorry From 8d9a80be095ec501e0ba7172c3f5bf812e9e11ff Mon Sep 17 00:00:00 2001 From: katobungen Date: Thu, 23 Jul 2026 15:24:43 +0900 Subject: [PATCH 6/7] Define rigid admissible sites and G-ringed spaces --- Rigid.lean | 6 + Rigid/RigidSpace/AdmissibleSite.lean | 218 ++++++++++++++++++++++++ Rigid/RigidSpace/Basic.lean | 122 +++++++++++++ Rigid/RigidSpace/CanonicalTopology.lean | 71 ++++++++ Rigid/RigidSpace/Comparator.lean | 70 ++++++++ Rigid/RigidSpace/GRingedSpace.lean | 173 +++++++++++++++++++ Rigid/RigidSpace/Morphism.lean | 168 ++++++++++++++++++ 7 files changed, 828 insertions(+) create mode 100644 Rigid/RigidSpace/AdmissibleSite.lean create mode 100644 Rigid/RigidSpace/Basic.lean create mode 100644 Rigid/RigidSpace/CanonicalTopology.lean create mode 100644 Rigid/RigidSpace/Comparator.lean create mode 100644 Rigid/RigidSpace/GRingedSpace.lean create mode 100644 Rigid/RigidSpace/Morphism.lean diff --git a/Rigid.lean b/Rigid.lean index 93a5513..2d3e20f 100644 --- a/Rigid.lean +++ b/Rigid.lean @@ -45,6 +45,12 @@ import Rigid.Berkovich.SpectralSeminorm import Rigid.Berkovich.Spectrum import Rigid.Berkovich.Unit import Rigid.Development +import Rigid.RigidSpace.AdmissibleSite +import Rigid.RigidSpace.Basic +import Rigid.RigidSpace.CanonicalTopology +import Rigid.RigidSpace.Comparator +import Rigid.RigidSpace.GRingedSpace +import Rigid.RigidSpace.Morphism import Rigid.TateAlgebra.Basic import Rigid.TateAlgebra.Complete import Rigid.TateAlgebra.Division diff --git a/Rigid/RigidSpace/AdmissibleSite.lean b/Rigid/RigidSpace/AdmissibleSite.lean new file mode 100644 index 0000000..883d8ee --- /dev/null +++ b/Rigid/RigidSpace/AdmissibleSite.lean @@ -0,0 +1,218 @@ +import Mathlib.CategoryTheory.Limits.Shapes.Pullback.HasPullback +import Mathlib.CategoryTheory.Sites.Pretopology + +set_option linter.style.header false +set_option linter.checkUnivs false + +/-! +# Admissible sites + +This file packages the point-set presentation of a G-topology as a small category of admissible +opens, with inclusions as morphisms, together with a mathlib `Pretopology`. The associated +Grothendieck topology is always obtained using `Pretopology.toGrothendieck`. + +The extra condition `precover_covers` records that the covering presieves really are +set-theoretic covers. It is not another version of the Grothendieck-topology axioms. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe p o + +namespace Rigid + +/-- A small family of subsets, closed under the whole set and binary intersections. + +The order is inclusion of carriers. In particular, admissible opens are determined by their +underlying point sets, as in the definition of a G-topology. -/ +structure AdmissibleBasis where + Point : Type p + Open : Type o + [openPartialOrder : PartialOrder Open] + [openHasPullbacks : HasPullbacks Open] + carrier : Open → Set Point + le_iff : ∀ {U V}, U ≤ V ↔ carrier U ⊆ carrier V + top : Open + carrier_top : carrier top = Set.univ + inter : Open → Open → Open + carrier_inter : ∀ U V, carrier (inter U V) = carrier U ∩ carrier V + +attribute [instance] AdmissibleBasis.openPartialOrder AdmissibleBasis.openHasPullbacks + +namespace AdmissibleBasis + +variable (B : AdmissibleBasis.{p, o}) + +theorem carrier_mono {U V : B.Open} (h : U ≤ V) : B.carrier U ⊆ B.carrier V := + B.le_iff.mp h + +theorem carrier_injective : Function.Injective B.carrier := by + intro U V h + apply le_antisymm + · exact B.le_iff.mpr h.le + · exact B.le_iff.mpr h.ge + +theorem top_mem (x : B.Point) : x ∈ B.carrier B.top := by + rw [B.carrier_top] + exact Set.mem_univ x + +theorem inter_le_left (U V : B.Open) : B.inter U V ≤ U := by + rw [B.le_iff, B.carrier_inter] + exact Set.inter_subset_left + +theorem inter_le_right (U V : B.Open) : B.inter U V ≤ V := by + rw [B.le_iff, B.carrier_inter] + exact Set.inter_subset_right + +theorem le_inter {T U V : B.Open} (hU : T ≤ U) (hV : T ≤ V) : T ≤ B.inter U V := by + rw [B.le_iff, B.carrier_inter] + exact fun x hx ↦ ⟨B.carrier_mono hU hx, B.carrier_mono hV hx⟩ + +/-- In the inclusion category of a G-basis, intersections are pullbacks. -/ +def interPullbackCone {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : + PullbackCone f g := + PullbackCone.mk (homOfLE (B.inter_le_left U V)) (homOfLE (B.inter_le_right U V)) + (Subsingleton.elim _ _) + +/-- The intersection cone has the universal property of the pullback. -/ +def interPullbackConeIsLimit {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : + IsLimit (B.interPullbackCone f g) := + PullbackCone.IsLimit.mk _ + (fun s ↦ homOfLE (B.le_inter (leOfHom s.fst) (leOfHom s.snd))) + (fun _ ↦ Subsingleton.elim _ _) (fun _ ↦ Subsingleton.elim _ _) + (fun _ _ _ _ ↦ Subsingleton.elim _ _) + +/-- The canonical pullback instance supplied by intersections. Constructors of an +`AdmissibleBasis` can use this as their `openHasPullbacks` field. -/ +theorem hasPullbackOfInter {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : + HasPullback f g where + exists_limit := ⟨⟨B.interPullbackCone f g, B.interPullbackConeIsLimit f g⟩⟩ + +end AdmissibleBasis + +/-- A G-site: an admissible basis, a pretopology on it, and the assertion that pretopology +coverings cover the underlying point set. -/ +structure AdmissibleSite extends AdmissibleBasis.{p, o} where + pretopology : Pretopology toAdmissibleBasis.Open + precover_covers : + ∀ {U : toAdmissibleBasis.Open} {R : Presieve U}, R ∈ pretopology U → + ∀ x ∈ toAdmissibleBasis.carrier U, + ∃ (V : toAdmissibleBasis.Open) (f : V ⟶ U), + R f ∧ x ∈ toAdmissibleBasis.carrier V + +namespace AdmissibleSite + +variable (X : Rigid.AdmissibleSite.{p, o}) + +/-- The Grothendieck topology generated by the admissible pretopology. -/ +def topology : GrothendieckTopology X.Open := + X.pretopology.toGrothendieck + +/-- A covering sieve in the generated topology covers the underlying point set. -/ +theorem coveringSieve_covers {U : X.Open} {S : Sieve U} (hS : S ∈ X.topology U) + {x : X.Point} (hx : x ∈ X.carrier U) : + ∃ (V : X.Open) (f : V ⟶ U), S f ∧ x ∈ X.carrier V := by + rcases hS with ⟨R, hR, hRS⟩ + obtain ⟨V, f, hf, hxV⟩ := X.precover_covers hR x hx + exact ⟨V, f, hRS V f hf, hxV⟩ + +/-- The presieve associated to an indexed family of inclusions. -/ +def familyPresieve {ι : Type*} {U : ι → X.Open} {V : X.Open} + (hUV : ∀ i, U i ≤ V) : Presieve V := + Presieve.ofArrows U (fun i ↦ homOfLE (hUV i)) + +/-- An indexed family is an admissible cover when its generated sieve is covering. -/ +def IsCover {ι : Type*} (U : ι → X.Open) (V : X.Open) : Prop := + ∃ hUV : ∀ i, U i ≤ V, Sieve.generate (X.familyPresieve hUV) ∈ X.topology V + +namespace IsCover + +variable {X} + +/-- Every member of an admissible cover is contained in the covered open. -/ +theorem subset {ι : Type*} {U : ι → X.Open} {V : X.Open} (h : X.IsCover U V) + (i : ι) : U i ≤ V := + h.choose i + +/-- A family admitting a covering refinement is itself an admissible cover. This is the +Grothendieck-topology form of the saturation axiom for coverings. -/ +theorem of_refinement {ι κ : Type*} {U : ι → X.Open} {W : κ → X.Open} {V : X.Open} + (hUV : ∀ i, U i ≤ V) (hW : X.IsCover W V) (r : κ → ι) + (hr : ∀ j, W j ≤ U (r j)) : X.IsCover U V := by + rcases hW with ⟨_, hWcover⟩ + refine ⟨hUV, X.topology.superset_covering ?_ hWcover⟩ + intro T q hq + rcases hq with ⟨Z, a, b, ⟨j⟩, hab⟩ + refine + ⟨U (r j), a ≫ homOfLE (hr j), homOfLE (hUV (r j)), ⟨r j⟩, Subsingleton.elim _ _⟩ + +/-- The singleton family is an admissible cover. -/ +theorem singleton (V : X.Open) : X.IsCover (fun _ : PUnit ↦ V) V := by + refine ⟨fun _ ↦ le_rfl, ?_⟩ + simp [AdmissibleSite.familyPresieve, Presieve.ofArrows_pUnit] + +/-- Admissible covers are stable under intersection with another admissible open. -/ +theorem pullback {ι : Type*} {U : ι → X.Open} {V : X.Open} (h : X.IsCover U V) + (W : X.Open) : + X.IsCover (fun i ↦ X.inter (U i) W) (X.inter V W) := by + rcases h with ⟨hUV, hcover⟩ + let p : X.inter V W ⟶ V := homOfLE (X.toAdmissibleBasis.inter_le_left V W) + let hIW : ∀ i, X.inter (U i) W ≤ X.inter V W := fun i ↦ + X.toAdmissibleBasis.le_inter + ((X.toAdmissibleBasis.inter_le_left (U i) W).trans (hUV i)) + (X.toAdmissibleBasis.inter_le_right (U i) W) + refine ⟨hIW, X.topology.superset_covering ?_ (X.topology.pullback_stable p hcover)⟩ + rintro T q hq + change Sieve.generate (X.familyPresieve hUV) (q ≫ p) at hq + rcases hq with ⟨Z, a, b, ⟨i⟩, hab⟩ + refine ⟨X.inter (U i) W, homOfLE ?_, homOfLE (hIW i), ⟨i⟩, Subsingleton.elim _ _⟩ + apply X.toAdmissibleBasis.le_inter + · exact leOfHom a + · exact (leOfHom q).trans (X.toAdmissibleBasis.inter_le_right V W) + +/-- Admissible coverings are transitive. -/ +theorem trans {ι : Type*} {κ : ι → Type*} {U : ι → X.Open} {V : X.Open} + (hU : X.IsCover U V) (W : ∀ i, κ i → X.Open) + (hW : ∀ i, X.IsCover (W i) (U i)) : + X.IsCover (fun p : Σ i, κ i ↦ W p.1 p.2) V := by + rcases hU with ⟨hUV, hUcover⟩ + choose hWU hWcover using hW + let f : ∀ i, U i ⟶ V := fun i ↦ homOfLE (hUV i) + let g : ∀ i j, W i j ⟶ U i := fun i j ↦ homOfLE (hWU i j) + refine ⟨fun p ↦ (hWU p.1 p.2).trans (hUV p.1), ?_⟩ + have hbind := X.topology.bindOfArrows (f := f) (R := fun i ↦ X.familyPresieve (hWU i)) + hUcover hWcover + change Sieve.generate + (Presieve.bindOfArrows U f (fun i ↦ Presieve.ofArrows (W i) (g i))) ∈ + X.topology V at hbind + rw [Presieve.bindOfArrows_ofArrows f g] at hbind + convert hbind using 1 + apply Sieve.ext + intro T q + rfl + +/-- The carriers of an admissible covering family have union equal to the covered carrier. -/ +theorem iUnion_carrier {ι : Type*} {U : ι → X.Open} {V : X.Open} + (h : X.IsCover U V) : X.carrier V = ⋃ i, X.carrier (U i) := by + apply Set.Subset.antisymm + · intro x hx + rcases h with ⟨hUV, hcover⟩ + obtain ⟨T, q, hq, hxT⟩ := X.coveringSieve_covers hcover hx + rcases hq with ⟨Z, a, b, ⟨i⟩, hab⟩ + exact Set.mem_iUnion.mpr ⟨i, X.toAdmissibleBasis.carrier_mono (leOfHom a) hxT⟩ + · intro x hx + rcases Set.mem_iUnion.mp hx with ⟨i, hxi⟩ + exact X.toAdmissibleBasis.carrier_mono (h.subset i) hxi + +end IsCover + +/-- A quasi-compact admissible open is one for which every admissible cover has a finite +admissible subcover. This is deliberately separate from admissibility itself. -/ +def IsQuasiCompact (U : X.Open) : Prop := + ∀ {ι : Type*} (V : ι → X.Open), X.IsCover V U → + ∃ s : Set ι, s.Finite ∧ X.IsCover (fun i : s ↦ V i.1) U + +end AdmissibleSite + +end Rigid diff --git a/Rigid/RigidSpace/Basic.lean b/Rigid/RigidSpace/Basic.lean new file mode 100644 index 0000000..abc73b5 --- /dev/null +++ b/Rigid/RigidSpace/Basic.lean @@ -0,0 +1,122 @@ +import Rigid.AffinoidAlgebra.MaximalSpectrum +import Rigid.RigidSpace.Morphism + +set_option linter.style.header false + +/-! +# Rigid analytic spaces + +The definition here follows Chapters 4 and 5 of +`Introduction_to_Rigid_Geometry(personal_version)_English.tex`. + +A rigid analytic space is more than a G-locally ringed space. Its G-topology contains the empty +and whole opens, is local for admissible coverings, is saturated under refinements, and the space +has an admissible affinoid covering. Saturation of coverings is already a theorem of the +Grothendieck topology (`AdmissibleSite.IsCover.of_refinement`), so it is not stored again. + +An `AffinoidChart` records the affinoid identification through the coordinate algebra of global +sections, its maximal spectrum, and an affinoid basis for the induced strong G-topology. This +distinguishes the strong topology used to glue rigid spaces from the weak finite-cover topology on +an affinoid basis. +-/ + +universe k + +namespace Rigid + +variable (K : Type k) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- The local affinoid data on an admissible open `U`. + +The coordinate algebra of the chart is `Γ(U, 𝒪)`. Its points are identified with the maximal +spectrum of that algebra. The final field expresses the strong-topology property: every +admissible subopen has an admissible covering by opens with the same two affinoid +characterizations. -/ +structure AffinoidChart (X : LocallyGRingedSpace.{k} K) + (U : X.toAdmissibleSite.Open) where + sections_isAffinoid : + IsAffinoidAlgebra K (GRingedSpace.Sections K X.toGRingedSpace U) + pointsEquiv : + {x : X.toAdmissibleSite.Point // x ∈ X.toAdmissibleSite.carrier U} ≃ + MaximalSpectrum (GRingedSpace.Sections K X.toGRingedSpace U) + affinoidBasis : + ∀ {V : X.toAdmissibleSite.Open}, V ≤ U → + ∃ (ι : Type k) (W : ι → X.toAdmissibleSite.Open), + X.toAdmissibleSite.IsCover W V ∧ + ∀ i, + IsAffinoidAlgebra K (GRingedSpace.Sections K X.toGRingedSpace (W i)) ∧ + Nonempty + ({x : X.toAdmissibleSite.Point // + x ∈ X.toAdmissibleSite.carrier (W i)} ≃ + MaximalSpectrum + (GRingedSpace.Sections K X.toGRingedSpace (W i))) + +/-- A rigid analytic space over `K`. + +Besides its underlying G-locally ringed space, this stores precisely the additional global +conditions from Definition 5.1 of the reference: + +* the empty set (the whole set is already `toAdmissibleSite.top`) is admissible; +* admissibility of a subset is local for an admissible covering; +* there is an admissible covering by affinoid charts. + +The third saturation axiom for coverings is derived from the associated Grothendieck topology, +rather than duplicated as structure data. -/ +structure RigidSpace extends LocallyGRingedSpace.{k} K where + empty : toLocallyGRingedSpace.toAdmissibleSite.Open + carrier_empty : + toLocallyGRingedSpace.toAdmissibleSite.carrier empty = ∅ + admissibleOpen_local : + ∀ {ι : Type k} + {U : ι → toLocallyGRingedSpace.toAdmissibleSite.Open} + {V : toLocallyGRingedSpace.toAdmissibleSite.Open}, + toLocallyGRingedSpace.toAdmissibleSite.IsCover U V → + ∀ (S : Set toLocallyGRingedSpace.toAdmissibleSite.Point), + S ⊆ toLocallyGRingedSpace.toAdmissibleSite.carrier V → + (∀ i, ∃ W : toLocallyGRingedSpace.toAdmissibleSite.Open, + toLocallyGRingedSpace.toAdmissibleSite.carrier W = + S ∩ toLocallyGRingedSpace.toAdmissibleSite.carrier (U i)) → + ∃ W : toLocallyGRingedSpace.toAdmissibleSite.Open, + toLocallyGRingedSpace.toAdmissibleSite.carrier W = S + AtlasIndex : Type k + atlasOpen : AtlasIndex → toLocallyGRingedSpace.toAdmissibleSite.Open + atlasChart : + ∀ i, AffinoidChart K toLocallyGRingedSpace (atlasOpen i) + atlasCover : + toLocallyGRingedSpace.toAdmissibleSite.IsCover atlasOpen + toLocallyGRingedSpace.toAdmissibleSite.top + +namespace RigidSpace + +variable (X : RigidSpace.{k} K) + +/-- The empty admissible open is uniquely determined by its carrier. -/ +theorem empty_unique {U : X.toAdmissibleSite.Open} + (hU : X.toAdmissibleSite.carrier U = ∅) : U = X.empty := + X.toAdmissibleSite.toAdmissibleBasis.carrier_injective + (hU.trans X.carrier_empty.symm) + +/-- The selected affinoid charts cover the underlying point set. -/ +theorem atlas_iUnion_carrier : + X.toAdmissibleSite.carrier X.toAdmissibleSite.top = + ⋃ i, X.toAdmissibleSite.carrier (X.atlasOpen i) := + X.atlasCover.iUnion_carrier + +/-- The covering-saturation axiom of a rigid G-topology is inherited from its Grothendieck +topology: a covering family with an admissible covering refinement is admissible. -/ +theorem cover_of_refinement {ι κ : Type*} + {U : ι → X.toAdmissibleSite.Open} {W : κ → X.toAdmissibleSite.Open} + {V : X.toAdmissibleSite.Open} (hUV : ∀ i, U i ≤ V) + (hW : X.toAdmissibleSite.IsCover W V) (r : κ → ι) + (hr : ∀ j, W j ≤ U (r j)) : + X.toAdmissibleSite.IsCover U V := + AdmissibleSite.IsCover.of_refinement hUV hW r hr + +/-- Morphisms of rigid analytic spaces are morphisms of the underlying G-locally ringed spaces, +as in Definition 5.1(2) of the reference. -/ +abbrev Hom (X Y : RigidSpace.{k} K) := + LocallyGRingedSpace.Hom K X.toLocallyGRingedSpace Y.toLocallyGRingedSpace + +end RigidSpace + +end Rigid diff --git a/Rigid/RigidSpace/CanonicalTopology.lean b/Rigid/RigidSpace/CanonicalTopology.lean new file mode 100644 index 0000000..911b635 --- /dev/null +++ b/Rigid/RigidSpace/CanonicalTopology.lean @@ -0,0 +1,71 @@ +import Rigid.RigidSpace.AdmissibleSite + +set_option linter.style.header false +set_option linter.checkUnivs false + +/-! +# The canonical point-cover G-topology + +This file constructs the canonical pretopology in which every set-theoretic covering by +admissible opens is admissible. The construction is separate from `AdmissibleSite` because rigid +affinoid spaces generally use a stricter choice of admissible coverings. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe p o + +namespace Rigid + +namespace AdmissibleBasis + +variable (B : AdmissibleBasis.{p, o}) + +/-- The precoverage consisting of all presieves whose domains cover the underlying point set. -/ +def pointCoverPrecoverage : Precoverage B.Open where + coverings U := + {R | ∀ x ∈ B.carrier U, ∃ (V : B.Open) (f : V ⟶ U), R f ∧ x ∈ B.carrier V} + +instance pointCoverPrecoverage_hasIsos : + B.pointCoverPrecoverage.HasIsos where + mem_coverings_of_isIso {U V} f _ x hx := by + refine ⟨U, f, Presieve.singleton_self f, ?_⟩ + exact B.carrier_mono (leOfHom (inv f)) hx + +instance pointCoverPrecoverage_isStableUnderBaseChange : + B.pointCoverPrecoverage.IsStableUnderBaseChange where + mem_coverings_of_isPullback {ι S U} f hR {V} g {P} p₁ p₂ hp x hxV := by + have hxS : x ∈ B.carrier S := B.carrier_mono (leOfHom g) hxV + obtain ⟨_, _, ⟨i⟩, hxUi⟩ := hR x hxS + let T := B.inter V (U i) + let q₁ : T ⟶ V := homOfLE (B.inter_le_left V (U i)) + let q₂ : T ⟶ U i := homOfLE (B.inter_le_right V (U i)) + let l : T ⟶ P i := (hp i).lift q₁ q₂ (Subsingleton.elim _ _) + refine ⟨P i, p₁ i, Presieve.ofArrows.mk i, B.carrier_mono (leOfHom l) ?_⟩ + rw [B.carrier_inter] + exact ⟨hxV, hxUi⟩ + +instance pointCoverPrecoverage_isStableUnderComposition : + B.pointCoverPrecoverage.IsStableUnderComposition where + comp_mem_coverings {ι S U} f hf {σ W} g hg x hxS := by + obtain ⟨_, _, ⟨i⟩, hxUi⟩ := hf x hxS + obtain ⟨_, _, ⟨j⟩, hxWij⟩ := hg i x hxUi + refine ⟨W i j, g i j ≫ f i, ?_, hxWij⟩ + exact Presieve.ofArrows.mk (Sigma.mk i j) + +/-- The pretopology of all point-set covers. Its three axioms are supplied by the +`Precoverage` instances above. -/ +def pointCoverPretopology : Pretopology B.Open := + B.pointCoverPrecoverage.toPretopology + +/-- The canonical G-site associated with an admissible basis: all point-set covering families are +admissible. -/ +def toCanonicalSite : AdmissibleSite.{p, o} where + toAdmissibleBasis := B + pretopology := B.pointCoverPretopology + precover_covers := fun h ↦ h + +end AdmissibleBasis + +end Rigid diff --git a/Rigid/RigidSpace/Comparator.lean b/Rigid/RigidSpace/Comparator.lean new file mode 100644 index 0000000..51d30f4 --- /dev/null +++ b/Rigid/RigidSpace/Comparator.lean @@ -0,0 +1,70 @@ +import Rigid.RigidSpace.Basic + +set_option linter.style.header false + +/-! +# Comparator adapters for G-locally ringed spaces + +These abbreviations isolate the global comparator-facing vocabulary from the implementation of +sites, sheaves, and stalk colimits. They are intentionally production declarations in namespace +`Rigid`; the comparator remains in its separate `RigidChallenge` namespace. +-/ + +universe u + +namespace Rigid + +namespace ComparatorAdapter + +variable (K : Type u) [NontriviallyNormedField K] [CompleteSpace K] [IsUltrametricDist K] + +/-- The production candidate underlying the comparator's global rigid-space interface. -/ +abbrev RigidSpace := + Rigid.RigidSpace.{u} K + +/-- Analytic points of the production G-locally ringed space. -/ +abbrev Point (X : RigidSpace K) : Type (u + 1) := + ULift.{u + 1, u} X.toAdmissibleSite.Point + +/-- Admissible opens of the production G-site. -/ +abbrev AdmissibleOpen (X : RigidSpace K) : Type (u + 1) := + ULift.{u + 1, u} X.toAdmissibleSite.Open + +/-- The point set of an admissible open. -/ +abbrev carrier {X : RigidSpace K} (U : AdmissibleOpen K X) : Set (Point K X) := + {x | x.down ∈ X.toAdmissibleSite.carrier U.down} + +/-- Indexed admissible covers are the covering sieves of the generated Grothendieck topology. -/ +abbrev IsCover {X : RigidSpace K} {ι : Type (u + 1)} + (U : ι → AdmissibleOpen K X) (V : AdmissibleOpen K X) : Prop := + X.toAdmissibleSite.IsCover (fun i ↦ (U i).down) V.down + +/-- Evaluation of the bundled structure sheaf. -/ +abbrev Sections {X : RigidSpace K} (U : AdmissibleOpen K X) : Type u := + GRingedSpace.Sections K X.toGRingedSpace U.down + +/-- Restriction is the corresponding map of the structure presheaf. -/ +def restriction {X : RigidSpace K} {U V : AdmissibleOpen K X} (hUV : carrier K U ⊆ carrier K V) : + Sections K V →ₐ[K] Sections K U := + GRingedSpace.restriction K X.toGRingedSpace + (X.toAdmissibleSite.le_iff.mpr (fun x hx ↦ by + have hx' : (ULift.up x : Point K X) ∈ carrier K U := hx + exact hUV hx')) + +/-- Stalks are the neighbourhood colimits constructed in `GRingedSpace`. -/ +noncomputable abbrev Stalk (X : RigidSpace K) (x : Point K X) : Type u := + GRingedSpace.Stalk K X.toGRingedSpace x.down + +/-- Germs are the canonical maps into those colimits. -/ +noncomputable def germ {X : RigidSpace K} {U : AdmissibleOpen K X} + {x : Point K X} (hx : x ∈ carrier K U) : + Sections K U →ₐ[K] Stalk K X x := + GRingedSpace.germ K X.toGRingedSpace hx + +/-- Production analytic morphism data, with the stalk map derived rather than stored. -/ +abbrev AnalyticMorphismData (X Y : RigidSpace K) := + Rigid.RigidSpace.Hom K X Y + +end ComparatorAdapter + +end Rigid diff --git a/Rigid/RigidSpace/GRingedSpace.lean b/Rigid/RigidSpace/GRingedSpace.lean new file mode 100644 index 0000000..060cbcf --- /dev/null +++ b/Rigid/RigidSpace/GRingedSpace.lean @@ -0,0 +1,173 @@ +import Mathlib.Algebra.Category.CommAlgCat.Basic +import Mathlib.CategoryTheory.Filtered.Basic +import Mathlib.CategoryTheory.Sites.Sheaf +import Rigid.RigidSpace.AdmissibleSite + +set_option linter.style.header false + +/-! +# G-ringed and G-locally ringed spaces + +The structure sheaf is a mathlib `Sheaf` on the Grothendieck topology generated by the admissible +pretopology. Sections and restriction maps are evaluations of that sheaf. Stalks are filtered +colimits over admissible neighbourhoods, and germs are the canonical colimit maps. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe k + +namespace Rigid + +variable (K : Type k) [CommRing K] + +/-- A G-ringed space over `K`. -/ +structure GRingedSpace where + toAdmissibleSite : AdmissibleSite.{k, k} + structureSheaf : + Sheaf toAdmissibleSite.topology (CommAlgCat.{k} K) + +namespace GRingedSpace + +variable (X : GRingedSpace.{k} K) + +/-- Analytic functions on an admissible open. -/ +abbrev Sections (U : X.toAdmissibleSite.Open) : Type k := + X.structureSheaf.obj.obj (Opposite.op U) + +/-- Restriction of analytic functions along an inclusion of admissible opens. -/ +def restriction {U V : X.toAdmissibleSite.Open} (hUV : U ≤ V) : + Sections K X V →ₐ[K] Sections K X U := + (X.structureSheaf.obj.map (homOfLE hUV).op).hom + +@[simp] +theorem restriction_id (U : X.toAdmissibleSite.Open) : + restriction K X (U := U) (V := U) le_rfl = AlgHom.id K (Sections K X U) := by + change (X.structureSheaf.obj.map (𝟙 (Opposite.op U))).hom = _ + rw [X.structureSheaf.obj.map_id] + rfl + +@[simp] +theorem restriction_comp {U V W : X.toAdmissibleSite.Open} (hUV : U ≤ V) (hWU : W ≤ U) : + (restriction K X hWU).comp (restriction K X hUV) = + restriction K X (hWU.trans hUV) := by + change + (X.structureSheaf.obj.map (homOfLE hUV).op ≫ + X.structureSheaf.obj.map (homOfLE hWU).op).hom = + (X.structureSheaf.obj.map (homOfLE (hWU.trans hUV)).op).hom + rw [← X.structureSheaf.obj.map_comp] + rfl + +/-- The representable form of the sheaf condition for an indexed admissible cover. This is the +categorical sheaf condition used by mathlib for a `CommAlgCat`-valued sheaf. -/ +theorem isSheafFor_isCover (E : CommAlgCat.{k} K) {ι : Type*} + {U : ι → X.toAdmissibleSite.Open} + {V : X.toAdmissibleSite.Open} (h : X.toAdmissibleSite.IsCover U V) : + Presieve.IsSheafFor + (X.structureSheaf.obj ⋙ coyoneda.obj (Opposite.op E)) + (X.toAdmissibleSite.familyPresieve h.choose) := by + rw [Presieve.isSheafFor_iff_generate] + exact X.structureSheaf.property E _ h.choose_spec + +/-- An admissible neighbourhood of a point. Its order is reverse inclusion, so restriction maps +form a direct system. -/ +structure Neighborhood (x : X.toAdmissibleSite.Point) where + obj : X.toAdmissibleSite.Open + mem : x ∈ X.toAdmissibleSite.carrier obj + +namespace Neighborhood + +variable {X} {x : X.toAdmissibleSite.Point} + +instance : Preorder (Neighborhood K X x) where + le U V := V.obj ≤ U.obj + le_refl _ := le_rfl + le_trans _ _ _ hUV hVW := hVW.trans hUV + +/-- The full admissible open is a neighbourhood of every point. -/ +def top : Neighborhood K X x where + obj := X.toAdmissibleSite.top + mem := X.toAdmissibleSite.toAdmissibleBasis.top_mem x + +/-- Intersections give common refinements of admissible neighbourhoods. -/ +def inter (U V : Neighborhood K X x) : Neighborhood K X x where + obj := X.toAdmissibleSite.inter U.obj V.obj + mem := by + rw [X.toAdmissibleSite.carrier_inter] + exact ⟨U.mem, V.mem⟩ + +instance : Nonempty (Neighborhood K X x) := + ⟨top (K := K)⟩ + +instance : IsFiltered (Neighborhood K X x) where + cocone_objs U V := + ⟨inter (K := K) U V, + homOfLE (X.toAdmissibleSite.toAdmissibleBasis.inter_le_left U.obj V.obj), + homOfLE (X.toAdmissibleSite.toAdmissibleBasis.inter_le_right U.obj V.obj), trivial⟩ + cocone_maps := fun {_ _} _ _ ↦ ⟨_, 𝟙 _, Subsingleton.elim _ _⟩ + +end Neighborhood + +/-- The direct system of section algebras over admissible neighbourhoods. -/ +@[reducible] +def stalkDiagram (x : X.toAdmissibleSite.Point) : + Neighborhood K X x ⥤ CommAlgCat.{k} K where + obj U := X.structureSheaf.obj.obj (Opposite.op U.obj) + map {U V} f := + X.structureSheaf.obj.map + (homOfLE (show V.obj ≤ U.obj from leOfHom f)).op + map_id U := by + change X.structureSheaf.obj.map (𝟙 (Opposite.op U.obj)) = 𝟙 _ + exact X.structureSheaf.obj.map_id _ + map_comp f g := by + rw [← X.structureSheaf.obj.map_comp] + rfl + +/-- The stalk object is the filtered colimit over admissible neighbourhoods. -/ +noncomputable abbrev stalkObj (x : X.toAdmissibleSite.Point) : CommAlgCat.{k} K := + colimit (stalkDiagram K X x) + +/-- The local ring of germs at a point, as an underlying type. -/ +noncomputable abbrev Stalk (x : X.toAdmissibleSite.Point) : Type k := + stalkObj K X x + +/-- The germ map is the canonical map into the neighbourhood colimit. -/ +noncomputable def germ {U : X.toAdmissibleSite.Open} {x : X.toAdmissibleSite.Point} + (hx : x ∈ X.toAdmissibleSite.carrier U) : + Sections K X U →ₐ[K] Stalk K X x := + (colimit.ι (stalkDiagram K X x) ⟨U, hx⟩).hom + +/-- Germs commute with restriction. -/ +@[simp] +theorem germ_restriction {U V : X.toAdmissibleSite.Open} (hUV : U ≤ V) + {x : X.toAdmissibleSite.Point} (hx : x ∈ X.toAdmissibleSite.carrier U) : + (germ K X hx).comp (restriction K X hUV) = + germ K X (X.toAdmissibleSite.toAdmissibleBasis.carrier_mono hUV hx) := by + let V' : Neighborhood K X x := + ⟨V, X.toAdmissibleSite.toAdmissibleBasis.carrier_mono hUV hx⟩ + let U' : Neighborhood K X x := ⟨U, hx⟩ + let f : V' ⟶ U' := homOfLE hUV + have hw := colimit.w (stalkDiagram K X x) f + exact congrArg CommAlgCat.Hom.hom hw + +end GRingedSpace + +/-- A G-locally ringed space is a G-ringed space whose canonically constructed stalks are local +rings. -/ +structure LocallyGRingedSpace extends GRingedSpace.{k} K where + stalk_isLocal : + ∀ x : toGRingedSpace.toAdmissibleSite.Point, + IsLocalRing (GRingedSpace.Stalk K toGRingedSpace x) + +namespace LocallyGRingedSpace + +variable (X : LocallyGRingedSpace.{k} K) + +instance stalkIsLocal (x : X.toAdmissibleSite.Point) : + IsLocalRing (GRingedSpace.Stalk K X.toGRingedSpace x) := + X.stalk_isLocal x + +end LocallyGRingedSpace + +end Rigid diff --git a/Rigid/RigidSpace/Morphism.lean b/Rigid/RigidSpace/Morphism.lean new file mode 100644 index 0000000..eaf7413 --- /dev/null +++ b/Rigid/RigidSpace/Morphism.lean @@ -0,0 +1,168 @@ +import Mathlib.CategoryTheory.Sites.CoverPreserving +import Rigid.RigidSpace.GRingedSpace + +set_option linter.style.header false + +/-! +# Morphisms of G-ringed spaces + +A continuous map carries an inverse-image functor on admissible opens together with mathlib's +`Functor.IsContinuous` site condition. A morphism of G-ringed spaces adds a morphism from the +target structure sheaf to the continuous pushforward of the source structure sheaf. Its maps on +stalks are then constructed from the universal property of the neighbourhood colimit. +-/ + +open CategoryTheory +open CategoryTheory.Limits + +universe pX oX pY oY k a v + +namespace Rigid + +namespace AdmissibleSite + +/-- Point-set and inverse-image data for a map of admissible sites. -/ +structure MapData (X : AdmissibleSite.{pX, oX}) (Y : AdmissibleSite.{pY, oY}) where + toFun : X.Point → Y.Point + preimage : Y.Open → X.Open + monotone_preimage : Monotone preimage + carrier_preimage : + ∀ U, X.carrier (preimage U) = toFun ⁻¹' Y.carrier U + +namespace MapData + +variable {X : AdmissibleSite.{pX, oX}} {Y : AdmissibleSite.{pY, oY}} + +/-- Inverse image as a functor between the inclusion categories of admissible opens. -/ +abbrev preimageFunctor (f : MapData X Y) : Y.Open ⥤ X.Open := + f.monotone_preimage.functor + +end MapData + +/-- A continuous map of admissible sites. -/ +structure Hom (X : AdmissibleSite.{pX, oX}) (Y : AdmissibleSite.{pY, oY}) + extends MapData X Y where + continuous : + Functor.IsContinuous toMapData.preimageFunctor Y.topology X.topology + +namespace Hom + +variable {X : AdmissibleSite.{pX, oX}} {Y : AdmissibleSite.{pY, oY}} + +/-- The mathlib continuous pushforward along the inverse-image functor on opens. -/ +noncomputable def pushforwardSheaf (f : Hom X Y) {A : Type a} [Category.{v} A] + (F : Sheaf X.topology A) : Sheaf Y.topology A := by + letI := f.continuous + exact (f.toMapData.preimageFunctor.sheafPushforwardContinuous + A Y.topology X.topology).obj F + +end Hom + +end AdmissibleSite + +variable (K : Type k) [CommRing K] + +namespace GRingedSpace + +variable {X Y : GRingedSpace.{k} K} + +/-- A morphism of G-ringed spaces: a continuous map of sites and a morphism of structure +sheaves. -/ +structure Hom (X Y : GRingedSpace.{k} K) where + base : AdmissibleSite.Hom X.toAdmissibleSite Y.toAdmissibleSite + pullback : + Y.structureSheaf.obj ⟶ + base.toMapData.preimageFunctor.op ⋙ X.structureSheaf.obj + +namespace Hom + +variable (f : Hom K X Y) + +/-- The pullback natural transformation bundled as a morphism of sheaves. -/ +noncomputable def pullbackSheafHom : + Y.structureSheaf ⟶ + f.base.pushforwardSheaf (A := CommAlgCat.{k} K) X.structureSheaf := + ObjectProperty.homMk f.pullback + +/-- Inverse image sends a neighbourhood of `f(x)` to a neighbourhood of `x`. -/ +@[reducible] +def preimageNeighborhood (x : X.toAdmissibleSite.Point) + (U : Neighborhood K Y (f.base.toMapData.toFun x)) : + Neighborhood K X x where + obj := f.base.toMapData.preimage U.obj + mem := by + rw [f.base.toMapData.carrier_preimage] + exact U.mem + +/-- Pullback of sections on one admissible open. -/ +noncomputable def pullbackApp (U : Y.toAdmissibleSite.Open) : + Sections K Y U →ₐ[K] Sections K X (f.base.toMapData.preimage U) := + (f.pullback.app (Opposite.op U)).hom + +/-- The cocone from target neighbourhood sections to the source stalk. -/ +noncomputable def stalkCocone (x : X.toAdmissibleSite.Point) : + Cocone (stalkDiagram K Y (f.base.toMapData.toFun x)) where + pt := stalkObj K X x + ι := + { app := fun U ↦ + f.pullback.app (Opposite.op U.obj) ≫ + colimit.ι (stalkDiagram K X x) (preimageNeighborhood K f x U) + naturality := by + intro U V h + let h' : preimageNeighborhood K f x U ⟶ preimageNeighborhood K f x V := + homOfLE (f.base.toMapData.monotone_preimage (leOfHom h)) + simp only [Functor.const_obj_map] + change + Y.structureSheaf.obj.map + (homOfLE (show V.obj ≤ U.obj from leOfHom h)).op ≫ + f.pullback.app (Opposite.op V.obj) ≫ + colimit.ι (stalkDiagram K X x) (preimageNeighborhood K f x V) = + f.pullback.app (Opposite.op U.obj) ≫ + colimit.ι (stalkDiagram K X x) (preimageNeighborhood K f x U) + rw [← Category.assoc] + rw [f.pullback.naturality] + rw [Category.assoc] + have hmap : + (f.base.toMapData.preimageFunctor.op ⋙ X.structureSheaf.obj).map + (homOfLE (show V.obj ≤ U.obj from leOfHom h)).op = + (stalkDiagram K X x).map h' := rfl + rw [hmap] + exact congrArg + (fun q ↦ f.pullback.app (Opposite.op U.obj) ≫ q) + (colimit.w (stalkDiagram K X x) h') } + +/-- The induced map on stalks, obtained from the colimit universal property. -/ +noncomputable def stalkMap (x : X.toAdmissibleSite.Point) : + stalkObj K Y (f.base.toMapData.toFun x) ⟶ stalkObj K X x := + colimit.desc (stalkDiagram K Y (f.base.toMapData.toFun x)) (stalkCocone K f x) + +/-- The induced stalk map carries the germ of a section to the germ of its pullback. -/ +@[simp] +theorem germ_stalkMap {U : Y.toAdmissibleSite.Open} {x : X.toAdmissibleSite.Point} + (hx : f.base.toMapData.toFun x ∈ Y.toAdmissibleSite.carrier U) : + (stalkMap K f x).hom.comp (germ K Y hx) = + (germ K X (by + rw [f.base.toMapData.carrier_preimage] + exact hx)).comp (pullbackApp K f U) := by + exact congrArg CommAlgCat.Hom.hom + (colimit.ι_desc (stalkCocone K f x) ⟨U, hx⟩) + +end Hom + +end GRingedSpace + +namespace LocallyGRingedSpace + +variable {X Y : LocallyGRingedSpace.{k} K} + +/-- A morphism of G-locally ringed spaces is a G-ringed-space morphism whose canonically induced +maps on stalks are local. -/ +structure Hom (X Y : LocallyGRingedSpace.{k} K) where + toGRingedSpaceHom : GRingedSpace.Hom K X.toGRingedSpace Y.toGRingedSpace + local_stalk : + ∀ x : X.toAdmissibleSite.Point, + IsLocalHom (GRingedSpace.Hom.stalkMap K toGRingedSpaceHom x).hom + +end LocallyGRingedSpace + +end Rigid From b113464114097312bed8a378b337c3b61d89b010 Mon Sep 17 00:00:00 2001 From: Dagur Asgeirsson Date: Thu, 23 Jul 2026 16:31:58 +0900 Subject: [PATCH 7/7] Complete categorical structure for G-ringed spaces --- Rigid/RigidSpace/AdmissibleSite.lean | 17 +- Rigid/RigidSpace/CanonicalTopology.lean | 1 - Rigid/RigidSpace/Morphism.lean | 222 +++++++++++++++++++++++- 3 files changed, 225 insertions(+), 15 deletions(-) diff --git a/Rigid/RigidSpace/AdmissibleSite.lean b/Rigid/RigidSpace/AdmissibleSite.lean index 883d8ee..10d59ad 100644 --- a/Rigid/RigidSpace/AdmissibleSite.lean +++ b/Rigid/RigidSpace/AdmissibleSite.lean @@ -2,7 +2,6 @@ import Mathlib.CategoryTheory.Limits.Shapes.Pullback.HasPullback import Mathlib.CategoryTheory.Sites.Pretopology set_option linter.style.header false -set_option linter.checkUnivs false /-! # Admissible sites @@ -22,6 +21,7 @@ universe p o namespace Rigid +set_option linter.checkUnivs false in /-- A small family of subsets, closed under the whole set and binary intersections. The order is inclusion of carriers. In particular, admissible opens are determined by their @@ -30,7 +30,6 @@ structure AdmissibleBasis where Point : Type p Open : Type o [openPartialOrder : PartialOrder Open] - [openHasPullbacks : HasPullbacks Open] carrier : Open → Set Point le_iff : ∀ {U V}, U ≤ V ↔ carrier U ⊆ carrier V top : Open @@ -38,7 +37,7 @@ structure AdmissibleBasis where inter : Open → Open → Open carrier_inter : ∀ U V, carrier (inter U V) = carrier U ∩ carrier V -attribute [instance] AdmissibleBasis.openPartialOrder AdmissibleBasis.openHasPullbacks +attribute [instance] AdmissibleBasis.openPartialOrder namespace AdmissibleBasis @@ -83,18 +82,24 @@ def interPullbackConeIsLimit {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : (fun _ ↦ Subsingleton.elim _ _) (fun _ ↦ Subsingleton.elim _ _) (fun _ _ _ _ ↦ Subsingleton.elim _ _) -/-- The canonical pullback instance supplied by intersections. Constructors of an -`AdmissibleBasis` can use this as their `openHasPullbacks` field. -/ +/-- The canonical pullback instance supplied by intersections. -/ theorem hasPullbackOfInter {U V W : B.Open} (f : U ⟶ W) (g : V ⟶ W) : HasPullback f g where exists_limit := ⟨⟨B.interPullbackCone f g, B.interPullbackConeIsLimit f g⟩⟩ +instance openHasPullbacks : HasPullbacks B.Open := by + letI : ∀ {U V W : B.Open} {f : U ⟶ W} {g : V ⟶ W}, HasPullback f g := + fun {_ _ _} {f g} ↦ B.hasPullbackOfInter f g + exact hasPullbacks_of_hasLimit_cospan B.Open + end AdmissibleBasis +set_option linter.checkUnivs false in /-- A G-site: an admissible basis, a pretopology on it, and the assertion that pretopology coverings cover the underlying point set. -/ structure AdmissibleSite extends AdmissibleBasis.{p, o} where - pretopology : Pretopology toAdmissibleBasis.Open + pretopology : @Pretopology toAdmissibleBasis.Open _ + (AdmissibleBasis.openHasPullbacks toAdmissibleBasis) precover_covers : ∀ {U : toAdmissibleBasis.Open} {R : Presieve U}, R ∈ pretopology U → ∀ x ∈ toAdmissibleBasis.carrier U, diff --git a/Rigid/RigidSpace/CanonicalTopology.lean b/Rigid/RigidSpace/CanonicalTopology.lean index 911b635..f05d6fd 100644 --- a/Rigid/RigidSpace/CanonicalTopology.lean +++ b/Rigid/RigidSpace/CanonicalTopology.lean @@ -1,7 +1,6 @@ import Rigid.RigidSpace.AdmissibleSite set_option linter.style.header false -set_option linter.checkUnivs false /-! # The canonical point-cover G-topology diff --git a/Rigid/RigidSpace/Morphism.lean b/Rigid/RigidSpace/Morphism.lean index eaf7413..0bd20c3 100644 --- a/Rigid/RigidSpace/Morphism.lean +++ b/Rigid/RigidSpace/Morphism.lean @@ -15,27 +15,57 @@ stalks are then constructed from the universal property of the neighbourhood col open CategoryTheory open CategoryTheory.Limits -universe pX oX pY oY k a v +universe pX oX pY oY pZ oZ k a v namespace Rigid namespace AdmissibleSite -/-- Point-set and inverse-image data for a map of admissible sites. -/ +/-- Point-set and inverse-image data for a map of admissible sites. The inverse-image functor +is primitive so identities and composites agree definitionally with the corresponding functor +operations. -/ structure MapData (X : AdmissibleSite.{pX, oX}) (Y : AdmissibleSite.{pY, oY}) where toFun : X.Point → Y.Point - preimage : Y.Open → X.Open - monotone_preimage : Monotone preimage + preimageFunctor : Y.Open ⥤ X.Open carrier_preimage : - ∀ U, X.carrier (preimage U) = toFun ⁻¹' Y.carrier U + ∀ U, X.carrier (preimageFunctor.obj U) = toFun ⁻¹' Y.carrier U namespace MapData variable {X : AdmissibleSite.{pX, oX}} {Y : AdmissibleSite.{pY, oY}} -/-- Inverse image as a functor between the inclusion categories of admissible opens. -/ -abbrev preimageFunctor (f : MapData X Y) : Y.Open ⥤ X.Open := - f.monotone_preimage.functor +/-- Inverse image on admissible opens. -/ +abbrev preimage (f : MapData X Y) (U : Y.Open) : X.Open := + f.preimageFunctor.obj U + +/-- Inverse image is monotone because it is functorial on inclusion categories. -/ +theorem monotone_preimage (f : MapData X Y) : Monotone f.preimage := + fun _ _ h ↦ leOfHom (f.preimageFunctor.map (homOfLE h)) + +@[ext] +theorem ext (f g : MapData X Y) (hfun : f.toFun = g.toFun) + (hpreimage : f.preimageFunctor = g.preimageFunctor) : f = g := by + cases f + cases g + cases hfun + cases hpreimage + rfl + +/-- The identity map data. -/ +abbrev id (X : AdmissibleSite.{pX, oX}) : MapData X X where + toFun := _root_.id + preimageFunctor := 𝟭 X.Open + carrier_preimage := fun _ ↦ rfl + +/-- Composition of point-set and inverse-image data. -/ +abbrev comp {Z : AdmissibleSite.{pZ, oZ}} (f : MapData X Y) (g : MapData Y Z) : MapData X Z where + toFun := g.toFun ∘ f.toFun + preimageFunctor := g.preimageFunctor ⋙ f.preimageFunctor + carrier_preimage U := by + change X.carrier (f.preimage (g.preimage U)) = + (g.toFun ∘ f.toFun) ⁻¹' Z.carrier U + rw [f.carrier_preimage, g.carrier_preimage] + rfl end MapData @@ -49,6 +79,27 @@ namespace Hom variable {X : AdmissibleSite.{pX, oX}} {Y : AdmissibleSite.{pY, oY}} +@[ext] +theorem ext (f g : Hom X Y) (h : f.toMapData = g.toMapData) : f = g := by + cases f + cases g + cases h + rfl + +/-- The identity continuous map of an admissible site. -/ +abbrev id (X : AdmissibleSite.{pX, oX}) : Hom X X where + toMapData := MapData.id X + continuous := by infer_instance + +/-- Composition of continuous maps of admissible sites. -/ +abbrev comp {Z : AdmissibleSite.{pZ, oZ}} (f : Hom X Y) (g : Hom Y Z) : Hom X Z where + toMapData := MapData.comp f.toMapData g.toMapData + continuous := by + letI := f.continuous + letI := g.continuous + exact Functor.isContinuous_comp g.toMapData.preimageFunctor + f.toMapData.preimageFunctor Z.topology Y.topology X.topology + /-- The mathlib continuous pushforward along the inverse-image functor on opens. -/ noncomputable def pushforwardSheaf (f : Hom X Y) {A : Type a} [Category.{v} A] (F : Sheaf X.topology A) : Sheaf Y.topology A := by @@ -76,6 +127,40 @@ structure Hom (X Y : GRingedSpace.{k} K) where namespace Hom +@[ext] +theorem ext (f g : Hom K X Y) (hbase : f.base = g.base) + (hpullback : HEq f.pullback g.pullback) : f = g := by + cases f + cases g + cases hbase + cases hpullback + rfl + +/-- The identity morphism of a G-ringed space. -/ +abbrev id (X : GRingedSpace.{k} K) : Hom K X X where + base := AdmissibleSite.Hom.id X.toAdmissibleSite + pullback := 𝟙 X.structureSheaf.obj + +/-- Composition of morphisms of G-ringed spaces. -/ +abbrev comp {Z : GRingedSpace.{k} K} (f : Hom K X Y) (g : Hom K Y Z) : Hom K X Z where + base := AdmissibleSite.Hom.comp f.base g.base + pullback := + g.pullback ≫ + Functor.whiskerLeft g.base.toMapData.preimageFunctor.op f.pullback ≫ + (Functor.associator g.base.toMapData.preimageFunctor.op + f.base.toMapData.preimageFunctor.op X.structureSheaf.obj).inv ≫ + Functor.whiskerRight + (Functor.opComp g.base.toMapData.preimageFunctor + f.base.toMapData.preimageFunctor).inv + X.structureSheaf.obj + +@[simp] +theorem comp_base_toFun {Z : GRingedSpace.{k} K} (f : Hom K X Y) (g : Hom K Y Z) + (x : X.toAdmissibleSite.Point) : + (comp K f g).base.toMapData.toFun x = + g.base.toMapData.toFun (f.base.toMapData.toFun x) := + rfl + variable (f : Hom K X Y) /-- The pullback natural transformation bundled as a morphism of sheaves. -/ @@ -147,8 +232,72 @@ theorem germ_stalkMap {U : Y.toAdmissibleSite.Open} {x : X.toAdmissibleSite.Poin exact congrArg CommAlgCat.Hom.hom (colimit.ι_desc (stalkCocone K f x) ⟨U, hx⟩) +@[simp] +theorem stalkMap_id (X : GRingedSpace.{k} K) (x : X.toAdmissibleSite.Point) : + stalkMap K (id K X) x = 𝟙 (stalkObj K X x) := by + dsimp only [stalkMap, id, AdmissibleSite.Hom.id, AdmissibleSite.MapData.id] + apply colimit.hom_ext + intro U + rw [colimit.ι_desc] + rfl + +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +theorem stalkMap_comp {Z : GRingedSpace.{k} K} (f : Hom K X Y) (g : Hom K Y Z) + (x : X.toAdmissibleSite.Point) : + stalkMap K (comp K f g) x = + stalkMap K g (f.base.toMapData.toFun x) ≫ stalkMap K f x := by + apply colimit.hom_ext + intro U + apply CommAlgCat.hom_ext + have hZ : g.base.toMapData.toFun (f.base.toMapData.toFun x) ∈ + Z.toAdmissibleSite.carrier U.obj := by + exact U.mem + have hY : f.base.toMapData.toFun x ∈ + Y.toAdmissibleSite.carrier (g.base.toMapData.preimage U.obj) := by + rw [g.base.toMapData.carrier_preimage] + exact hZ + change (stalkMap K (comp K f g) x).hom.comp (germ K Z hZ) = + (stalkMap K f x).hom.comp + ((stalkMap K g (f.base.toMapData.toFun x)).hom.comp (germ K Z hZ)) + rw [germ_stalkMap] + rw [germ_stalkMap] + change (germ K X _).comp (pullbackApp K (comp K f g) U.obj) = + ((stalkMap K f x).hom.comp (germ K Y hY)).comp (pullbackApp K g U.obj) + rw [germ_stalkMap] + simp [pullbackApp, comp] + rfl + end Hom +set_option backward.defeqAttrib.useBackward true in +set_option backward.isDefEq.respectTransparency false in +instance : Category (GRingedSpace.{k} K) where + Hom := GRingedSpace.Hom K + id := GRingedSpace.Hom.id K + comp := GRingedSpace.Hom.comp K + id_comp f := by + apply GRingedSpace.Hom.ext + · rfl + · apply heq_of_eq + apply NatTrans.ext + funext U + simp [GRingedSpace.Hom.comp, GRingedSpace.Hom.id] + comp_id f := by + apply GRingedSpace.Hom.ext + · rfl + · apply heq_of_eq + apply NatTrans.ext + funext U + simp [GRingedSpace.Hom.comp, GRingedSpace.Hom.id] + assoc f g h := by + apply GRingedSpace.Hom.ext + · rfl + · apply heq_of_eq + apply NatTrans.ext + funext U + simp [GRingedSpace.Hom.comp, Category.assoc] + end GRingedSpace namespace LocallyGRingedSpace @@ -163,6 +312,63 @@ structure Hom (X Y : LocallyGRingedSpace.{k} K) where ∀ x : X.toAdmissibleSite.Point, IsLocalHom (GRingedSpace.Hom.stalkMap K toGRingedSpaceHom x).hom +namespace Hom + +@[ext] +theorem ext (f g : Hom K X Y) + (h : f.toGRingedSpaceHom = g.toGRingedSpaceHom) : f = g := by + cases f + cases g + cases h + rfl + +/-- The identity morphism of a G-locally ringed space. -/ +abbrev id (X : LocallyGRingedSpace.{k} K) : Hom K X X where + toGRingedSpaceHom := GRingedSpace.Hom.id K X.toGRingedSpace + local_stalk _ := by + sorry + +/-- Composition of morphisms of G-locally ringed spaces. -/ +abbrev comp {Z : LocallyGRingedSpace.{k} K} (f : Hom K X Y) (g : Hom K Y Z) : + Hom K X Z where + toGRingedSpaceHom := + GRingedSpace.Hom.comp K f.toGRingedSpaceHom g.toGRingedSpaceHom + local_stalk x := by + rw [GRingedSpace.Hom.stalkMap_comp] + change IsLocalHom + ((GRingedSpace.Hom.stalkMap K f.toGRingedSpaceHom x).hom.comp + (GRingedSpace.Hom.stalkMap K g.toGRingedSpaceHom + (f.toGRingedSpaceHom.base.toMapData.toFun x)).hom) + letI : IsLocalHom (GRingedSpace.Hom.stalkMap K f.toGRingedSpaceHom x).hom := + f.local_stalk x + letI : IsLocalHom (GRingedSpace.Hom.stalkMap K g.toGRingedSpaceHom + (f.toGRingedSpaceHom.base.toMapData.toFun x)).hom := + g.local_stalk (f.toGRingedSpaceHom.base.toMapData.toFun x) + refine ⟨?_⟩ + intro a ha + exact IsLocalHom.map_nonunit + (f := (GRingedSpace.Hom.stalkMap K g.toGRingedSpaceHom + (f.toGRingedSpaceHom.base.toMapData.toFun x)).hom) a + (IsLocalHom.map_nonunit + (f := (GRingedSpace.Hom.stalkMap K f.toGRingedSpaceHom x).hom) _ ha) + +end Hom + +instance : Category (LocallyGRingedSpace.{k} K) where + Hom := LocallyGRingedSpace.Hom K + id := LocallyGRingedSpace.Hom.id K + comp := LocallyGRingedSpace.Hom.comp K + id_comp f := by + apply LocallyGRingedSpace.Hom.ext + exact @Category.id_comp (GRingedSpace.{k} K) _ _ _ f.toGRingedSpaceHom + comp_id f := by + apply LocallyGRingedSpace.Hom.ext + exact @Category.comp_id (GRingedSpace.{k} K) _ _ _ f.toGRingedSpaceHom + assoc f g h := by + apply LocallyGRingedSpace.Hom.ext + exact @Category.assoc (GRingedSpace.{k} K) _ _ _ _ _ + f.toGRingedSpaceHom g.toGRingedSpaceHom h.toGRingedSpaceHom + end LocallyGRingedSpace end Rigid