Skip to content

Commit c326498

Browse files
feat(NumberTheory/Height/Basic): add {mul|log}Height_comp_le, {mul|log}Height_fun_mul_eq (leanprover-community#35408)
This adds * two missing `logHeight` lemmas (their `mulHeight` versions are already there) * `{mul|log}Height_comp_le`: the height of `x ∘ f` is bounded by the height of `x` * `{mul|log}Height_fun_mul_eq`: the height of the "multiplication table" `fun (i, j) ↦ x i * y j` is the {product|sum} of the heights of `x` and of `y` * `{mul|log}Height_fun_prod_eq`: the analogous result for products with arbitrarily many factors * plus some API lemmas needed for these.
1 parent 9a59085 commit c326498

File tree

5 files changed

+224
-6
lines changed

5 files changed

+224
-6
lines changed

Mathlib/Analysis/Normed/Ring/Basic.lean

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ public import Mathlib.Analysis.Normed.Group.Real
1111
public import Mathlib.Analysis.Normed.Group.Subgroup
1212
public import Mathlib.Analysis.Normed.Group.Submodule
1313

14+
import Mathlib.Data.Fintype.Order
15+
1416
/-!
1517
# Normed rings
1618
@@ -923,3 +925,61 @@ noncomputable def toNormedRing {R : Type*} [Ring R] (v : AbsoluteValue R ℝ) :
923925
exact hxy.symm
924926

925927
end AbsoluteValue
928+
929+
namespace Real
930+
931+
/-
932+
Note: We cannot easily generalize this to targets other than `ℝ`, because we need
933+
the fact that `⨆ i, f i = 0` when the indexing type is empty (`Real.iSup_of_isEmpty`).
934+
-/
935+
936+
section mul
937+
938+
variable {R ι ι' : Type*} [Semiring R] [Finite ι] [Finite ι']
939+
940+
lemma iSup_fun_mul_eq_iSup_mul_iSup_of_nonneg {F : Type*} [FunLike F R ℝ]
941+
[NonnegHomClass F R ℝ] [MulHomClass F R ℝ] (v : F) (x : ι → R) (y : ι' → R) :
942+
⨆ a : ι × ι', v (x a.1 * y a.2) = (⨆ i, v (x i)) * ⨆ j, v (y j) := by
943+
rcases isEmpty_or_nonempty ι
944+
· simp
945+
rcases isEmpty_or_nonempty ι'
946+
· simp
947+
simp_rw [Real.iSup_mul_of_nonneg (iSup_nonneg fun i ↦ apply_nonneg v (y i)),
948+
Real.mul_iSup_of_nonneg (apply_nonneg v _), map_mul, Finite.ciSup_prod]
949+
950+
end mul
951+
952+
/-
953+
Note: We cannot easily generalize this to targets other than `ℝ`, because we need
954+
the fact that `⨆ i, f i = 0` when the indexing type is empty (`Real.iSup_of_isEmpty`).
955+
-/
956+
957+
section prod
958+
959+
universe u v
960+
961+
variable {α R : Type*} [Fintype α] {ι : α → Type u} [∀ a, Finite (ι a)]
962+
963+
lemma iSup_prod_eq_prod_iSup_of_nonneg {f : (a : α) → ι a → ℝ} (hf₀ : ∀ a i, 0 ≤ f a i) :
964+
⨆ (i : (a : α) → ι a), ∏ a, f a (i a) = ∏ a, ⨆ i, f a i := by
965+
rcases isEmpty_or_nonempty ((a : α) → ι a) with h | h
966+
· rw [iSup_of_isEmpty, eq_comm, Finset.prod_eq_zero_iff]
967+
obtain ⟨a, ha⟩ := isEmpty_pi.mp h
968+
exact ⟨a, by simp⟩
969+
refine le_antisymm ?_ ?_
970+
· exact ciSup_le fun i ↦ Finset.prod_le_prod (by simp [hf₀])
971+
fun a ha ↦ Finite.le_ciSup_of_le _ le_rfl
972+
· rw [Classical.nonempty_pi] at h
973+
have H a : ∃ i : ι a, f a i = ⨆ i, f a i := exists_eq_ciSup_of_finite
974+
choose i hi using H
975+
simp only [← hi]
976+
exact Finite.le_ciSup_of_le i le_rfl
977+
978+
lemma iSup_prod_eq_prod_iSup_of_nonnegHomClass {F : Type*} [FunLike F R ℝ]
979+
[NonnegHomClass F R ℝ] (v : F) {x : (a : α) → ι a → R} :
980+
⨆ (i : (a : α) → ι a), ∏ a, v (x a (i a)) = ∏ a, ⨆ i, v (x a i) :=
981+
Real.iSup_prod_eq_prod_iSup_of_nonneg (f := fun a i ↦ v (x a i)) (fun _ _ ↦ apply_nonneg v _)
982+
983+
end prod
984+
985+
end Real

Mathlib/Data/Fintype/Order.lean

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public import Mathlib.Data.Set.Finite.Basic
1111
public import Mathlib.Data.Set.Finite.Range
1212
public import Mathlib.Order.Atoms
1313

14+
import Mathlib.Data.Finite.Prod
1415
import Mathlib.Order.ConditionallyCompleteLattice.Finset
1516

1617
/-!
@@ -242,7 +243,7 @@ namespace Finite
242243

243244
section CCL
244245

245-
variable {α ι : Type*} [Finite ι] [ConditionallyCompleteLattice α]
246+
variable {α ι ι' : Type*} [Finite ι] [Finite ι'] [ConditionallyCompleteLattice α]
246247

247248
lemma le_ciSup_of_le {a : α} {f : ι → α} (c : ι) (h : a ≤ f c) : a ≤ iSup f :=
248249
_root_.le_ciSup_of_le (bddAbove_range f) c h
@@ -272,6 +273,14 @@ lemma ciInf_inf [Nonempty ι] {f : ι → α} {a : α} :
272273
(⨅ i, f i) ⊓ a = ⨅ i, f i ⊓ a :=
273274
ciSup_sup (α := αᵒᵈ) ..
274275

276+
lemma ciSup_prod (f : ι × ι' → α) :
277+
⨆ a, f a = ⨆ i, ⨆ i', f (i, i') :=
278+
_root_.ciSup_prod (bddAbove_range f)
279+
280+
lemma ciInf_prod (f : ι × ι' → α) :
281+
⨅ a, f a = ⨅ i, ⨅ i', f (i, i') :=
282+
ciSup_prod (α := αᵒᵈ) f
283+
275284
end CCL
276285

277286
section CCLO

Mathlib/Data/Real/Archimedean.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ lemma sSup_nonneg (hs : ∀ x ∈ s, 0 ≤ x) : 0 ≤ sSup s := by
299299
it suffices to show that all values of `f` are nonnegative to show that `0 ≤ ⨆ i, f i`. -/
300300
lemma iSup_nonneg (hf : ∀ i, 0 ≤ f i) : 0 ≤ ⨆ i, f i := sSup_nonneg <| Set.forall_mem_range.2 hf
301301

302+
lemma iSup_nonneg_of_nonnegHomClass {ι F α : Type*} [FunLike F α ℝ] [NonnegHomClass F α ℝ] (f : F)
303+
(g : ι → α) :
304+
0 ≤ ⨆ i, f (g i) :=
305+
iSup_nonneg (fun i ↦ apply_nonneg f (g i))
306+
302307
/-- As `sInf s = 0` when `s` is a set of reals that's either empty or unbounded below,
303308
it suffices to show that all elements of `s` are nonpositive to show that `sInf s ≤ 0`. -/
304309
lemma sInf_nonpos (hs : ∀ x ∈ s, x ≤ 0) : sInf s ≤ 0 := by

Mathlib/NumberTheory/Height/Basic.lean

Lines changed: 124 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ namespace Height
225225

226226
open AdmissibleAbsValues Real Function
227227

228-
variable {K : Type*} [Field K] [AdmissibleAbsValues K] {ι : Type*}
228+
variable {K : Type*} [Field K] [AdmissibleAbsValues K] {ι ι' : Type*}
229229

230230
/-- The multiplicative height of a tuple of elements of `K`.
231231
For the zero tuple we take the junk value `1`. -/
@@ -252,7 +252,7 @@ lemma mulHeight_one : mulHeight (1 : ι → K) = 1 := by
252252
simp [mulHeight_eq hx]
253253

254254
/-- The multiplicative height does not change under re-indexing. -/
255-
lemma mulHeight_comp_equiv {ι' : Type*} (e : ι ≃ ι') (x : ι' → K) :
255+
lemma mulHeight_comp_equiv (e : ι ≃ ι') (x : ι' → K) :
256256
mulHeight (x ∘ e) = mulHeight x := by
257257
have H (v : AbsoluteValue K ℝ) : ⨆ i, v (x (e i)) = ⨆ i, v (x i) := e.iSup_congr (congrFun rfl)
258258
rcases eq_or_ne x 0 with rfl | hx
@@ -273,13 +273,20 @@ def logHeight (x : ι → K) : ℝ := log (mulHeight x)
273273
lemma logHeight_eq_log_mulHeight (x : ι → K) : logHeight x = log (mulHeight x) := rfl
274274

275275
@[to_fun (attr := simp)]
276-
lemma logHeight_zero {ι : Type*} : logHeight (0 : ι → K) = 0 := by
276+
lemma logHeight_zero : logHeight (0 : ι → K) = 0 := by
277277
simp [logHeight_eq_log_mulHeight]
278278

279279
@[to_fun (attr := simp)]
280-
lemma logHeight_one {ι : Type*} : logHeight (1 : ι → K) = 0 := by
280+
lemma logHeight_one : logHeight (1 : ι → K) = 0 := by
281281
simp [logHeight_eq_log_mulHeight]
282282

283+
lemma logHeight_comp_equiv (e : ι ≃ ι') (x : ι' → K) :
284+
logHeight (x ∘ ⇑e) = logHeight x := by
285+
simp only [logHeight_eq_log_mulHeight, mulHeight_comp_equiv]
286+
287+
lemma logHeight_swap (x y : K) : logHeight ![x, y] = logHeight ![y, x] := by
288+
simp only [logHeight_eq_log_mulHeight, mulHeight_swap]
289+
283290
variable {α : Type*}
284291

285292
/-- The multiplicative height of a finitely supported function. -/
@@ -300,7 +307,7 @@ private lemma max_eq_iSup {α : Type*} [ConditionallyCompleteLattice α] (a b :
300307
max a b = iSup ![a, b] :=
301308
eq_of_forall_ge_iff <| by simp [ciSup_le_iff, Fin.forall_fin_two]
302309

303-
variable [Finite ι]
310+
variable [Finite ι] [Finite ι']
304311

305312
@[fun_prop]
306313
private lemma mulSupport_iSup_nonarchAbsVal_finite {x : ι → K} (hx : x ≠ 0) :
@@ -358,6 +365,31 @@ lemma mulHeight_ne_zero (x : ι → K) : mulHeight x ≠ 0 :=
358365
lemma logHeight_nonneg (x : ι → K) : 0 ≤ logHeight x :=
359366
log_nonneg <| one_le_mulHeight x
360367

368+
open Function in
369+
lemma mulHeight_comp_le (f : ι → ι') (x : ι' → K) :
370+
mulHeight (x ∘ f) ≤ mulHeight x := by
371+
rcases eq_or_ne (x ∘ f) 0 with h₀ | h₀
372+
· simpa [h₀] using one_le_mulHeight _
373+
rcases eq_or_ne x 0 with rfl | hx
374+
· simp
375+
have : Nonempty ι := .intro (ne_iff.mp h₀).choose
376+
rw [mulHeight_eq h₀, mulHeight_eq hx]
377+
have H (v : AbsoluteValue K ℝ) : ⨆ i, v ((x ∘ f) i) ≤ ⨆ i, v (x i) :=
378+
ciSup_le fun i ↦ Finite.le_ciSup_of_le (f i) le_rfl
379+
gcongr
380+
· exact finprod_nonneg fun v ↦ Real.iSup_nonneg_of_nonnegHomClass v.val _
381+
· exact Multiset.prod_map_nonneg fun v _ ↦ Real.iSup_nonneg_of_nonnegHomClass v _
382+
· exact Multiset.prod_map_le_prod_map₀ _ _ (fun v _ ↦ Real.iSup_nonneg_of_nonnegHomClass v _)
383+
fun v _ ↦ H v
384+
· exact finprod_le_finprod (mulSupport_iSup_nonarchAbsVal_finite h₀)
385+
(fun v ↦ Real.iSup_nonneg_of_nonnegHomClass v.val _) (mulSupport_iSup_nonarchAbsVal_finite hx)
386+
fun v ↦ H v.val
387+
388+
open Real in
389+
lemma logHeight_comp_le (f : ι → ι') (x : ι' → K) :
390+
logHeight (x ∘ f) ≤ logHeight x := by
391+
simpa [logHeight_eq_log_mulHeight] using log_le_log (mulHeight_pos _) <| mulHeight_comp_le ..
392+
361393
end Height
362394

363395
/-!
@@ -503,6 +535,93 @@ lemma logHeight₁_zpow (x : K) (n : ℤ) : logHeight₁ (x ^ n) = n.natAbs * lo
503535

504536
end Height
505537

538+
/-!
539+
### Heights and "Segre embedding"
540+
541+
We show that the multiplicative height of `fun (i, j) ↦ x i * y j` is the product of the
542+
multiplicative heights of `x` and `y` (and the analogous statement for logarithmic heights).
543+
544+
We also show the corresponding statements for product with arbitrarily many factors.
545+
-/
546+
547+
namespace Height
548+
549+
open Height.AdmissibleAbsValues Function
550+
551+
variable {K : Type*} [Field K] [AdmissibleAbsValues K]
552+
553+
section many
554+
555+
universe u v
556+
557+
variable {α : Type u} [Fintype α] {ι : α → Type v} [∀ a, Finite (ι a)]
558+
559+
open Finset in
560+
/-- Consider a finite family `x : (a : α) → ι a → K` of tuples. Then the multiplicative height
561+
of the "multiplication table" `fun (I : (a : α) → ι a ↦ ∏ a, x a (I a))` is the product
562+
of the multiplicative heights of all the `x a`. -/
563+
lemma mulHeight_fun_prod_eq {x : (a : α) → ι a → K} (hx : ∀ a, x a ≠ 0) :
564+
mulHeight (fun I : (a : α) → ι a ↦ ∏ a, x a (I a)) = ∏ a, mulHeight (x a) := by
565+
rw [mulHeight_eq ?h₁]
566+
case h₁ =>
567+
simp_rw [ne_iff, Pi.zero_def] at hx ⊢
568+
choose f hf using hx
569+
exact ⟨f, prod_ne_zero_iff.mpr fun a _ ↦ hf a⟩
570+
simp_rw [map_prod, Real.iSup_prod_eq_prod_iSup_of_nonnegHomClass]
571+
rw [Multiset.prod_map_prod,
572+
finprod_prod_comm _ _ fun b _ ↦ mulSupport_iSup_nonarchAbsVal_finite (hx b), ← prod_mul_distrib]
573+
exact prod_congr rfl fun a _ ↦ by rw [mulHeight_eq (hx a)]
574+
575+
open Real in
576+
/-- Consider a finite family `x : (a : α) → ι a → K` of tuples. Then the logarithmic height
577+
of the "multiplication table" `fun (I : (a : α) → ι a ↦ ∏ a, x a (I a))` is the sum
578+
of the logarithmic heights of all the `x a`. -/
579+
lemma logHeight_fun_prod_eq {x : (a : α) → ι a → K} (hx : ∀ a, x a ≠ 0) :
580+
logHeight (fun I : (a : α) → ι a ↦ ∏ a, x a (I a)) = ∑ a, logHeight (x a) := by
581+
simp only [logHeight_eq_log_mulHeight]
582+
rw [← log_prod fun a _ ↦ mulHeight_ne_zero _]
583+
exact congrArg log <| mulHeight_fun_prod_eq hx
584+
585+
end many
586+
587+
section two
588+
589+
/-
590+
Note: One could try to deduce the binary case from the general case above,
591+
but this leads into dependent type shenanigans (because `ι` and `ι'` can live in different
592+
universes) that would likely obfuscate the proofs more than simplify them.
593+
-/
594+
595+
variable {ι ι' : Type*} [Finite ι] [Finite ι']
596+
597+
/-- The multiplicative height of the "multiplication table" `fun (i, j) ↦ x i * y j`
598+
is the product of the multiplicative heights of `x` and `y`. -/
599+
lemma mulHeight_fun_mul_eq {x : ι → K} (hx : x ≠ 0) {y : ι' → K} (hy : y ≠ 0) :
600+
mulHeight (fun a : ι × ι' ↦ x a.1 * y a.2) = mulHeight x * mulHeight y := by
601+
have hxy : (fun a : ι × ι' ↦ x a.1 * y a.2) ≠ 0 := by
602+
obtain ⟨i, hi⟩ := ne_iff.mp hx
603+
obtain ⟨j, hj⟩ := ne_iff.mp hy
604+
exact ne_iff.mpr ⟨⟨i, j⟩, mul_ne_zero hi hj⟩
605+
rw [mulHeight_eq hx, mulHeight_eq hy, mulHeight_eq hxy, mul_mul_mul_comm, ← Multiset.prod_map_mul,
606+
← finprod_mul_distrib
607+
(mulSupport_iSup_nonarchAbsVal_finite hx) (mulSupport_iSup_nonarchAbsVal_finite hy)]
608+
congr <;> ext1 v
609+
· exact Real.iSup_fun_mul_eq_iSup_mul_iSup_of_nonneg v x y
610+
· exact Real.iSup_fun_mul_eq_iSup_mul_iSup_of_nonneg v.val x y
611+
612+
open Real in
613+
/-- The logarithmic height of the "multiplication table" `fun (i, j) ↦ x i * y j`
614+
is the sum of the logarithmic heights of `x` and `y`. -/
615+
lemma logHeight_fun_mul_eq {x : ι → K} (hx : x ≠ 0) {y : ι' → K} (hy : y ≠ 0) :
616+
logHeight (fun a : ι × ι' ↦ x a.1 * y a.2) = logHeight x + logHeight y := by
617+
simp only [logHeight_eq_log_mulHeight]
618+
pull (disch := positivity) log
619+
rw [mulHeight_fun_mul_eq hx hy]
620+
621+
end two
622+
623+
end Height
624+
506625
/-!
507626
### Bounds for the height of sums of field elements
508627

Mathlib/Order/ConditionallyCompleteLattice/Indexed.lean

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,31 @@ lemma ciInf_le_ciSup [Nonempty ι] {f : ι → α} (hf : BddBelow (range f)) (hf
182182
⨅ i, f i ≤ ⨆ i, f i :=
183183
(ciInf_le hf (Classical.arbitrary _)).trans <| le_ciSup hf' (Classical.arbitrary _)
184184

185+
lemma ciSup_prod {f : β × γ → α} (hf : BddAbove (Set.range f)) :
186+
⨆ p, f p = ⨆ b, ⨆ c, f (b, c) := by
187+
rcases isEmpty_or_nonempty β
188+
· simp [iSup_of_empty']
189+
rcases isEmpty_or_nonempty γ
190+
· simp [iSup_of_empty']
191+
have h₁ : BddAbove (Set.range fun b ↦ ⨆ c, f (b, c)) := by
192+
rw [bddAbove_def] at hf ⊢
193+
obtain ⟨B, hB⟩ := hf
194+
refine ⟨B, fun y hy ↦ ?_⟩
195+
obtain ⟨z, rfl⟩ := Set.mem_range.mp hy
196+
exact ciSup_le fun c ↦ by grind
197+
have h₂ b : BddAbove (Set.range fun c ↦ f (b, c)) := by
198+
rw [bddAbove_def] at hf ⊢
199+
obtain ⟨B, hB⟩ := hf
200+
exact ⟨B, by grind⟩
201+
refine eq_of_forall_ge_iff fun c ↦ ?_
202+
rw [ciSup_le_iff (bddAbove_iff_subset_Iic.mpr hf), ciSup_le_iff h₁]
203+
conv_rhs => enter [b]; rw [ciSup_le_iff (h₂ b)]
204+
simp [Prod.forall]
205+
206+
lemma ciInf_prod {f : β × γ → α} (hf : BddBelow (Set.range f)) :
207+
⨅ p, f p = ⨅ b, ⨅ c, f (b, c) :=
208+
ciSup_prod (α := αᵒᵈ) hf
209+
185210
/-- Introduction rule to prove that `b` is the supremum of `f`: it suffices to check that `b`
186211
is larger than `f i` for all `i`, and that this is not the case of any `w<b`.
187212
See `iSup_eq_of_forall_le_of_forall_lt_exists_gt` for a version in complete lattices. -/

0 commit comments

Comments
 (0)