Skip to content

Commit cce5343

Browse files
feat(NumberTheory/Height/NumberField): Northcott property (leanprover-community#39744)
This PR finally adds a proof of the *Northcott property* for heights on number fields: ```lean theorem NumberField.finite_setOf_mulHeight₁_le (B : ℝ) : {x : K | mulHeight₁ x ≤ B}.Finite ``` Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 8f49886 commit cce5343

1 file changed

Lines changed: 222 additions & 2 deletions

File tree

Mathlib/NumberTheory/Height/NumberField.lean

Lines changed: 222 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ Authors: Michael Stoll, Ralf Stephan
55
-/
66
module
77

8-
public import Mathlib.NumberTheory.NumberField.ProductFormula
98
public import Mathlib.NumberTheory.Height.Basic
9+
public import Mathlib.NumberTheory.Height.Northcott
10+
public import Mathlib.NumberTheory.NumberField.ProductFormula
1011

1112
import Mathlib.Algebra.FiniteSupport.Basic
1213
import Mathlib.Algebra.Order.Hom.Lattice
@@ -19,6 +20,14 @@ import Mathlib.NumberTheory.NumberField.InfinitePlace.TotallyRealComplex
1920
We provide an instance of `Height.AdmissibleAbsValues` for algebraic number fields
2021
and set up some API.
2122
23+
## Main results
24+
25+
* Heights on number fields satisfy the **Northcott property**: If `K` is a number field,
26+
then the set of elements of `K` of bounded (multiplicative or logarithmic) height is finite;
27+
see `NumberField.finite_setOf_mulHeight₁_le` and `NumberField.finite_setOf_logHeight₁_le`.
28+
We also provide instances for `Northcott (mulHeight₁ (K := K))` (which automatically leads
29+
also to `Northcott (logHeight₁ (K := K))`).
30+
2231
## TODO
2332
2433
When this file gets long, split the material on heights over `ℚ` off into a file `Rat.lean`.
@@ -96,7 +105,6 @@ lemma sum_nonarchAbsVal_eq {M : Type*} [AddCommMonoid M] (f : AbsoluteValue K
96105
(∑ᶠ v : nonarchAbsVal, f v.val) = ∑ᶠ v : FinitePlace K, f v.val :=
97106
rfl
98107

99-
100108
/-- This is the familiar definition of the multiplicative height on a number field. -/
101109
lemma mulHeight₁_eq (x : K) :
102110
mulHeight₁ x =
@@ -184,6 +192,218 @@ lemma absNorm_mul_finprod_finitePlace_eq_one (hx : x ≠ 0) :
184192

185193
end NumberField
186194

195+
/-!
196+
### The Northcott property for heights on number fields
197+
198+
We show that a number field `K` has the **Northcott property** with respect to the multiplicative
199+
and with respect to the logarithmic height, i.e., for any `B : ℝ` the set of elements `x : K`
200+
such that `mulHeight₁ x ≤ B` (resp., `logHeight₁ x ≤ B`) is finite.
201+
See `NumberField.finite_setOf_mulHeight₁_le` and `NumberField.finite_setOf_logHeight₁_le`.
202+
203+
The main idea of the proof is as follows. We show that for every `x : K` there is `n : ℕ` such that
204+
`n * x` is an algebraic integer and `n ≤ mulHeight₁ x`; see `NumberField.exists_nat_le_mulHeight₁`.
205+
We also show that the set of `a : 𝓞 K` such that `mulHeight₁ (a / n)` is bounded is finite;
206+
see `NumberField.finite_setOf_prod_infinitePlace_iSup_le`. The result for the multiplicative height
207+
follows by combining these two ingredients, and the result for the logarithmic height follows
208+
from that for any field with a family of admissible absolute values
209+
(see `Mathlib.NumberTheory.Height.Northcott`).
210+
-/
211+
212+
section Northcott
213+
214+
namespace NumberField
215+
216+
variable {K : Type*} [Field K] [NumberField K]
217+
218+
section withIdeal
219+
220+
open Ideal
221+
222+
private lemma relIndex_span_span_nat_mul (m : ℕ) {n : ℕ} (hn : n ≠ 0) (a : 𝓞 K) :
223+
(span {(m : 𝓞 K)}).toAddSubgroup.relIndex (span {↑m, a}).toAddSubgroup =
224+
(span {(n * m : 𝓞 K)}).toAddSubgroup.relIndex (span {↑(n * m), n * a}).toAddSubgroup := by
225+
let f : 𝓞 K →ₗ[𝓞 K] 𝓞 K := .mulLeft _ n
226+
have hf : Function.Injective (f : 𝓞 K →+ 𝓞 K) :=
227+
(injective_iff_map_eq_zero f).mpr fun _ _ ↦ by simp_all [f]
228+
have H₁ : span {(n * m : 𝓞 K)} = Submodule.map f (span {↑m}) := by
229+
simp [LinearMap.map_span, f]
230+
have H₂ : span {↑(n * m), n * a} = Submodule.map f (span {↑m, a}) := by
231+
simp [LinearMap.map_span, f, Set.image_pair]
232+
rw [H₁, H₂]
233+
exact AddSubgroup.relIndex_map_map_of_injective _ _ hf |>.symm
234+
235+
private lemma relIndex_span_span_eq_relIndex_span_span {m n : ℕ} (hm : m ≠ 0) (hn : n ≠ 0)
236+
{a b : 𝓞 K} (h : n * a = m * b) :
237+
(span {(m : 𝓞 K)}).toAddSubgroup.relIndex (span {↑m, a}).toAddSubgroup =
238+
(span {(n : 𝓞 K)}).toAddSubgroup.relIndex (span {↑n, b}).toAddSubgroup := by
239+
refine (relIndex_span_span_nat_mul m hn a).trans ?_
240+
rw [mul_comm, mul_comm n, h]
241+
exact (relIndex_span_span_nat_mul n hm b).symm
242+
243+
open Module AddSubgroup LinearMap in
244+
lemma exists_nat_ne_zero_exists_integer_mul_eq_and_absNorm_span_eq_pow (x : K) :
245+
∃ n : ℕ, n ≠ 0 ∧ ∃ a : 𝓞 K, n * x = a ∧
246+
(span {(n : 𝓞 K), a}).absNorm = n ^ (Module.finrank ℚ K - 1) := by
247+
have hx : IsAlgebraic ℤ x := IsFractionRing.isAlgebraic_iff ℤ _ _ |>.mpr (.of_finite ℚ x)
248+
obtain ⟨m, r, hm, hmr⟩ := hx.exists_nsmul_eq (𝓞 K)
249+
rw [← RingOfIntegers.coe_eq_algebraMap r] at hmr
250+
set n := (span {(m : 𝓞 K)}).toAddSubgroup.relIndex (span {(m : 𝓞 K), r}).toAddSubgroup with hndef
251+
have hn : n ≠ 0 := isFiniteRelIndex (by simp [hm]) _ |>.relIndex_ne_zero
252+
obtain ⟨a, ha'⟩ : ∃ a, m * a = n * r := by
253+
have : n • r ∈ span {(m : 𝓞 K)} :=
254+
(span {(m : 𝓞 K)}).toAddSubgroup.nsmul_relIndex_mem <| Submodule.mem_span_of_mem <| by grind
255+
simpa [mem_span_singleton', mul_comm] using this
256+
have ha : n * x = a := by
257+
refine mul_left_cancel₀ (mod_cast hm : (m : K) ≠ 0) ?_
258+
rw [mul_left_comm, ← nsmul_eq_mul m, hmr]
259+
exact_mod_cast ha'.symm
260+
refine ⟨n, hn, a, ha, mul_left_cancel₀ hn ?_⟩
261+
nth_rewrite 1 [hndef]
262+
rw [absNorm_eq_index, mul_pow_sub_one finrank_pos.ne', ← RingOfIntegers.rank,
263+
← absNorm_span_natCast, absNorm_eq_index, ← relIndex_span_span_eq_relIndex_span_span hn hm ha']
264+
exact relIndex_mul_index <| Submodule.toAddSubgroup_mono <| span_mono <| by grind
265+
266+
open Height in
267+
private lemma one_le_pow_totalWeight_mul_finprod {n : ℕ} (hn : n ≠ 0) (a : 𝓞 K) :
268+
1 ≤ (n ^ totalWeight K : ℝ) * ∏ᶠ (v : FinitePlace K), ⨆ i, v (![↑a, ↑n] i) := by
269+
have Hw : (0 : ℝ) < n ^ totalWeight K := by positivity
270+
rw_mod_cast [totalWeight_eq_finrank, ← RingOfIntegers.rank, ← absNorm_span_natCast] at Hw ⊢
271+
rw [← absNorm_mul_finprod_finitePlace_eq_one (show ![a, n] ≠ 0 by simp [hn])]
272+
gcongr
273+
· exact finprod_nonneg fun _ ↦ Real.iSup_nonneg_of_nonnegHomClass ..
274+
· exact Nat.le_of_dvd Hw <| absNorm_dvd_absNorm_of_le <| span_mono <| by simp
275+
· apply le_of_eq; congr; ext; congr; ext i; fin_cases i <;> simp
276+
277+
end withIdeal
278+
279+
open Height
280+
281+
section withFinset
282+
283+
open Finset
284+
285+
/-- If `x : K` (for a number field `K`), then we can find a nonzero `n : ℕ` such that
286+
`n ≤ mulHeight₁ x` and `n * x` is integral. I.e., the denominator of `x` can be bounded by
287+
its multplicative height. -/
288+
-- TODO: Use this to show `natDenominator x ≤ mulHeight₁ x` once #39872 is merged.
289+
lemma exists_nat_le_mulHeight₁ (x : K) :
290+
∃ n : ℕ, n ≠ 0 ∧ n ≤ mulHeight₁ x ∧ IsIntegral ℤ (n * x) := by
291+
obtain ⟨n, hn, a, ha₁, ha₂⟩ := exists_nat_ne_zero_exists_integer_mul_eq_and_absNorm_span_eq_pow x
292+
refine ⟨n, hn, ?_, ha₁ ▸ a.isIntegral_coe⟩
293+
rw [← totalWeight_eq_finrank] at ha₂
294+
have hv (i : Fin 2) : (![a, n] i : K) = ![(a : K), n] i := by fin_cases i <;> rfl
295+
rw [← mul_div_cancel_left₀ x (mod_cast hn : (n : K) ≠ 0), ha₁, mulHeight₁_div_eq_mulHeight,
296+
mulHeight_eq (by simp [hn])]
297+
refine le_of_mul_le_mul_left ?_ (show (0 : ℝ) < n ^ (totalWeight K - 1) by positivity)
298+
have : n ^ (totalWeight K - 1) * ∏ᶠ (v : FinitePlace K), ⨆ i, v (![(a : K), n] i) = 1 := by
299+
simpa [ha₂, hv] using absNorm_mul_finprod_finitePlace_eq_one (show ![a, n] ≠ 0 by simp [hn])
300+
rw [pow_sub_one_mul (totalWeight_pos K).ne', mul_left_comm, this, mul_one,
301+
totalWeight_eq_sum_mult, ← prod_pow_eq_pow_sum univ]
302+
gcongr
303+
exact Finite.le_ciSup_of_le 1 <| by simp
304+
305+
private lemma pow_totalWeight_sub_one_eq [DecidableEq (InfinitePlace K)] {n : ℕ} (hn : n ≠ 0)
306+
(v : InfinitePlace K) :
307+
(n ^ (totalWeight K - 1) : ℝ) = (∏ w ∈ univ.erase v, (n ^ w.mult : ℝ)) * n ^ (v.mult - 1) := by
308+
refine mul_right_cancel₀ (b := (n : ℝ)) (mod_cast hn) ?_
309+
rw [pow_sub_one_mul (totalWeight_pos K).ne', totalWeight_eq_sum_mult, ← prod_pow_eq_pow_sum,
310+
← prod_erase_mul _ _ (mem_univ v), ← pow_sub_one_mul v.mult_ne_zero, ← mul_assoc]
311+
312+
private lemma infinitePlace_apply_le_of_prod_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) {x : 𝓞 K}
313+
(h : ∏ v : InfinitePlace K, (⨆ i, v (![(x : K), n] i)) ^ v.mult ≤ B) (v : InfinitePlace K) :
314+
v x ≤ B / n ^ (totalWeight K - 1) := by
315+
classical
316+
rw [le_div_iff₀' (by positivity)]
317+
calc
318+
_ ≤ n ^ (totalWeight K - 1) * ⨆ i, v (![(x : K), n] i) := by
319+
gcongr; exact Finite.le_ciSup_of_le 0 le_rfl
320+
_ ≤ (∏ v' ∈ univ.erase v, (⨆ i, v' (![↑x, ↑n] i)) ^ v'.mult) *
321+
(⨆ i, v (![↑x, ↑n] i)) ^ (v.mult - 1) * ⨆ i, v (![(x : K), n] i) := by
322+
rw [pow_totalWeight_sub_one_eq hn]
323+
gcongr
324+
· exact Real.iSup_nonneg_of_nonnegHomClass ..
325+
· exact prod_nonneg fun _ _ ↦ pow_nonneg (Real.iSup_nonneg_of_nonnegHomClass ..) _
326+
all_goals exact Finite.le_ciSup_of_le 1 <| by simp
327+
_ ≤ B := by
328+
rwa [mul_assoc, pow_sub_one_mul v.mult_ne_zero, prod_erase_mul _ _ (mem_univ v)]
329+
330+
end withFinset
331+
332+
lemma finite_setOf_prod_infinitePlace_iSup_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) :
333+
{x : 𝓞 K | ∏ v : InfinitePlace K, (⨆ i, v (![(x : K), n] i)) ^ v.mult ≤ B}.Finite := by
334+
set B' := B / n ^ (totalWeight K - 1)
335+
suffices Set.BijOn ((↑) : 𝓞 K → K) {x | ∀ (v : InfinitePlace K), v x ≤ B'}
336+
{x | IsIntegral ℤ x ∧ ∀ (φ : K →+* ℂ), ‖φ x‖ ≤ B'} from
337+
this.finite_iff_finite.mpr (Embeddings.finite_of_norm_le K ℂ B') |>.subset
338+
fun _ _ ↦ by grind [infinitePlace_apply_le_of_prod_le hn B]
339+
refine .mk (fun x hx ↦ ?_) (fun _ _ _ _ ↦ RingOfIntegers.ext) fun a ha ↦ ?_ <;>
340+
simp only [Set.mem_image, Set.mem_setOf_eq] at *
341+
· exact ⟨x.isIntegral_coe, fun φ ↦ hx <| .mk φ⟩
342+
· rw [← mem_integralClosure_iff ℤ K] at ha
343+
exact ⟨⟨a, ha.1⟩, fun v ↦ v.norm_embedding_eq a ▸ ha.2 v.embedding, rfl⟩
344+
345+
/-- The set of `a : 𝓞 K` such that `mulHeight₁ (a / n) = mulHeight ![a, n]` is bounded
346+
(for some given nonzero `n : ℕ`) is finite. -/
347+
lemma finite_setOf_mulHeight_nat_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) :
348+
{a : 𝓞 K | mulHeight ![(a : K), n] ≤ B}.Finite := by
349+
suffices {a : 𝓞 K | mulHeight ![(a : K), n] ≤ B} ⊆
350+
{a | ∏ v : InfinitePlace K, (⨆ i, v (![(a : K), n] i)) ^ v.mult ≤ n ^ totalWeight K * B} from
351+
(finite_setOf_prod_infinitePlace_iSup_le hn _).subset this
352+
refine Set.setOf_subset_setOf_of_imp fun a ha ↦ ?_
353+
rw [mulHeight_eq <| by simp [hn], mul_comm] at ha
354+
grw [← ha, ← mul_assoc, ← one_le_pow_totalWeight_mul_finprod hn, one_mul]
355+
-- nonnegativity side goal
356+
exact Finset.prod_nonneg fun _ _ ↦ pow_nonneg (Real.iSup_nonneg_of_nonnegHomClass ..) _
357+
358+
variable (K) in
359+
/- The set of `x : K` such that `mulHeight₁ x` is bounded and `n * x` is integral
360+
(for some given nonzero `n : ℕ`) is finite.
361+
This is a stepping stone for the proof of the next result, which is strictly stronger. -/
362+
private lemma finite_setOf_isIntegral_nat_mul_and_mulHeight₁_le {n : ℕ} (hn : n ≠ 0) (B : ℝ) :
363+
{x : K | IsIntegral ℤ (n * x) ∧ mulHeight₁ x ≤ B}.Finite := by
364+
have hn' : (n : K) ≠ 0 := mod_cast hn
365+
suffices Set.BijOn (fun a : 𝓞 K ↦ (a / n : K)) {a | mulHeight ![(a : K), n] ≤ B}
366+
{x | IsIntegral ℤ (n * x) ∧ mulHeight₁ x ≤ B} from
367+
this.finite_iff_finite.mp <| finite_setOf_mulHeight_nat_le hn B
368+
refine .mk (fun a ha ↦ ?_) (fun a _ b _ h ↦ ?_) fun x ⟨hx₁, hx₂⟩ ↦ ?_
369+
· simp only [Set.mem_setOf_eq] at ha ⊢
370+
rw [mul_div_cancel₀ (a : K) hn', mulHeight₁_div_eq_mulHeight]
371+
exact ⟨a.isIntegral_coe, ha⟩
372+
· rwa [div_left_inj' hn', RingOfIntegers.eq_iff] at h
373+
· simp only [Set.mem_setOf_eq, Set.mem_image]
374+
obtain ⟨a, ha⟩ : ∃ a : 𝓞 K, n * x = a := ⟨⟨_, hx₁⟩, rfl⟩
375+
refine ⟨a, ?_, (EuclideanDomain.eq_div_of_mul_eq_right hn' ha).symm⟩
376+
rwa [← ha, ← mulHeight₁_div_eq_mulHeight, mul_div_cancel_left₀ x hn']
377+
378+
variable (K) in
379+
/-- A number field `K` satisfies the **Northcott property**:
380+
The set of elements of bounded multiplicative height is finite. -/
381+
theorem finite_setOf_mulHeight₁_le (B : ℝ) : {x : K | mulHeight₁ x ≤ B}.Finite := by
382+
have H : {x : K | mulHeight₁ x ≤ B} =
383+
⋃ n : Fin ⌊B⌋₊, {x : K | IsIntegral ℤ ((n + 1) * x) ∧ mulHeight₁ x ≤ B} := by
384+
ext x : 1
385+
obtain ⟨n, hn₀, hn₁, hn⟩ := exists_nat_le_mulHeight₁ x
386+
simp only [Set.mem_setOf_eq, Set.mem_iUnion, exists_and_right, iff_and_self]
387+
refine fun h ↦ ⟨⟨n - 1, by grind [Nat.le_floor <| hn₁.trans h]⟩, ?_⟩
388+
rwa [← Nat.cast_add_one, Nat.sub_one_add_one hn₀]
389+
rw [H]
390+
exact Set.finite_iUnion fun n ↦
391+
mod_cast finite_setOf_isIntegral_nat_mul_and_mulHeight₁_le K (Nat.zero_ne_add_one n).symm B
392+
393+
instance : Northcott (mulHeight₁ (K := K)) where
394+
finite_le := finite_setOf_mulHeight₁_le K
395+
396+
variable (K) in
397+
/-- A number field `K` satisfies the **Northcott property**:
398+
The set of elements of bounded logarithmic height is finite. -/
399+
theorem finite_setOf_logHeight₁_le (B : ℝ) :
400+
{x : K | logHeight₁ x ≤ B}.Finite :=
401+
Northcott.finite_le B
402+
403+
end NumberField
404+
405+
end Northcott
406+
187407
/-!
188408
### Positivity extension for totalWeight on number fields
189409
-/

0 commit comments

Comments
 (0)