number_theory.number_field.canonical_embeddingMathlib.NumberTheory.NumberField.CanonicalEmbedding

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -159,7 +159,7 @@ def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
       map_smul' := fun c x => by simpa only [zsmul_eq_mul, map_mul, map_intCast] }
     (by
       refine' ⟨fun _ _ h => _, fun ⟨_, _, ⟨a, rfl⟩, rfl⟩ => ⟨a, rfl⟩⟩
-      rw [LinearMap.coe_mk, Subtype.mk_eq_mk] at h 
+      rw [LinearMap.coe_mk, Subtype.mk_eq_mk] at h
       exact IsFractionRing.injective (𝓞 K) K (canonical_embedding_injective K h))
 #align number_field.canonical_embedding.equiv_integer_lattice NumberField.canonicalEmbedding.equivIntegerLattice
 
Diff
@@ -163,7 +163,6 @@ def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
       exact IsFractionRing.injective (𝓞 K) K (canonical_embedding_injective K h))
 #align number_field.canonical_embedding.equiv_integer_lattice NumberField.canonicalEmbedding.equivIntegerLattice
 
-#print NumberField.canonicalEmbedding.integerLattice.inter_ball_finite /-
 theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
     ((integerLattice K : Set E) ∩ closedBall 0 r).Finite :=
   by
@@ -179,8 +178,7 @@ theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
     exact ⟨x, ⟨SetLike.coe_mem x, (HEq x).mp hx2⟩, rfl⟩
   · rintro ⟨x, ⟨hx1, hx2⟩, rfl⟩
     exact ⟨⟨x, ⟨⟨x, hx1⟩, rfl⟩, rfl⟩, (HEq x).mpr hx2⟩
-#align number_field.canonical_embedding.integer_lattice.inter_ball_finite NumberField.canonicalEmbedding.integerLattice.inter_ball_finite
--/
+#align number_field.canonical_embedding.integer_lattice.inter_ball_finite NumberField.canonicalEmbedding.integerLattice.inter_ball_finiteₓ
 
 instance [NumberField K] : Countable (integerLattice K) :=
   by
Diff
@@ -3,7 +3,7 @@ Copyright (c) 2022 Xavier Roblot. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 -/
-import Mathbin.NumberTheory.NumberField.Embeddings
+import NumberTheory.NumberField.Embeddings
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"fdc286cc6967a012f41b87f76dcd2797b53152af"
 
Diff
@@ -45,7 +45,6 @@ scoped[CanonicalEmbedding]
   notation "E" =>
     ({ w : InfinitePlace K // IsReal w } → ℝ) × ({ w : InfinitePlace K // IsComplex w } → ℂ)
 
-#print NumberField.canonicalEmbedding.space_rank /-
 theorem space_rank [NumberField K] : finrank ℝ E = finrank ℚ K :=
   by
   haveI : Module.Free ℝ ℂ := inferInstance
@@ -53,11 +52,9 @@ theorem space_rank [NumberField K] : finrank ℝ E = finrank ℚ K :=
     Finset.card_univ, ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm, ←
     card_complex_embeddings, ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
     Nat.add_sub_of_le (Fintype.card_subtype_le _)]
-#align number_field.canonical_embedding.space_rank NumberField.canonicalEmbedding.space_rank
--/
+#align number_field.canonical_embedding.space_rank NumberField.CanonicalEmbedding.space_rank
 
-#print NumberField.canonicalEmbedding.nontrivial_space /-
-theorem nontrivial_space [NumberField K] : Nontrivial E :=
+theorem non_trivial_space [NumberField K] : Nontrivial E :=
   by
   obtain ⟨w⟩ := infinite_place.nonempty K
   obtain hw | hw := w.is_real_or_is_complex
@@ -65,8 +62,7 @@ theorem nontrivial_space [NumberField K] : Nontrivial E :=
     exact nontrivial_prod_left
   · haveI : Nonempty { w : infinite_place K // is_complex w } := ⟨⟨w, hw⟩⟩
     exact nontrivial_prod_right
-#align number_field.canonical_embedding.non_trivial_space NumberField.canonicalEmbedding.nontrivial_space
--/
+#align number_field.canonical_embedding.non_trivial_space NumberField.CanonicalEmbedding.non_trivial_space
 
 #print NumberField.canonicalEmbedding /-
 /-- The canonical embedding of a number field `K` of signature `(r₁, r₂)` into `ℝ^r₁ × ℂ^r₂`. -/
@@ -78,7 +74,7 @@ def NumberField.canonicalEmbedding : K →+* E :=
 #print NumberField.canonicalEmbedding_injective /-
 theorem NumberField.canonicalEmbedding_injective [NumberField K] :
     Injective (NumberField.canonicalEmbedding K) :=
-  @RingHom.injective _ _ _ _ (nontrivial_space K) _
+  @RingHom.injective _ _ _ _ (non_trivial_space K) _
 #align number_field.canonical_embedding_injective NumberField.canonicalEmbedding_injective
 -/
 
@@ -86,21 +82,17 @@ open NumberField
 
 variable {K}
 
-#print NumberField.canonicalEmbedding.apply_at_real_infinitePlace /-
 @[simp]
 theorem apply_at_real_infinitePlace (w : { w : InfinitePlace K // IsReal w }) (x : K) :
     (NumberField.canonicalEmbedding K x).1 w = w.Prop.Embedding x := by
   simp only [canonical_embedding, RingHom.prod_apply, Pi.ringHom_apply]
 #align number_field.canonical_embedding.apply_at_real_infinite_place NumberField.canonicalEmbedding.apply_at_real_infinitePlace
--/
 
-#print NumberField.canonicalEmbedding.apply_at_complex_infinitePlace /-
 @[simp]
 theorem apply_at_complex_infinitePlace (w : { w : InfinitePlace K // IsComplex w }) (x : K) :
     (NumberField.canonicalEmbedding K x).2 w = Embedding w.val x := by
   simp only [canonical_embedding, RingHom.prod_apply, Pi.ringHom_apply]
 #align number_field.canonical_embedding.apply_at_complex_infinite_place NumberField.canonicalEmbedding.apply_at_complex_infinitePlace
--/
 
 #print NumberField.canonicalEmbedding.nnnorm_eq /-
 theorem nnnorm_eq [NumberField K] (x : K) :
@@ -157,7 +149,6 @@ def integerLattice : Subring E :=
 #align number_field.canonical_embedding.integer_lattice NumberField.canonicalEmbedding.integerLattice
 -/
 
-#print NumberField.canonicalEmbedding.equivIntegerLattice /-
 /-- The linear equiv between `𝓞 K` and the integer lattice. -/
 def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
   LinearEquiv.ofBijective
@@ -171,7 +162,6 @@ def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
       rw [LinearMap.coe_mk, Subtype.mk_eq_mk] at h 
       exact IsFractionRing.injective (𝓞 K) K (canonical_embedding_injective K h))
 #align number_field.canonical_embedding.equiv_integer_lattice NumberField.canonicalEmbedding.equivIntegerLattice
--/
 
 #print NumberField.canonicalEmbedding.integerLattice.inter_ball_finite /-
 theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
Diff
@@ -2,14 +2,11 @@
 Copyright (c) 2022 Xavier Roblot. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
-
-! This file was ported from Lean 3 source module number_theory.number_field.canonical_embedding
-! leanprover-community/mathlib commit fdc286cc6967a012f41b87f76dcd2797b53152af
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.NumberTheory.NumberField.Embeddings
 
+#align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"fdc286cc6967a012f41b87f76dcd2797b53152af"
+
 /-!
 # Canonical embedding of a number field
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 
 ! This file was ported from Lean 3 source module number_theory.number_field.canonical_embedding
-! leanprover-community/mathlib commit 60da01b41bbe4206f05d34fd70c8dd7498717a30
+! leanprover-community/mathlib commit fdc286cc6967a012f41b87f76dcd2797b53152af
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -13,6 +13,9 @@ import Mathbin.NumberTheory.NumberField.Embeddings
 /-!
 # Canonical embedding of a number field
 
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
 The canonical embedding of a number field `K` of signature `(r₁, r₂)` is the ring homomorphism
 `K →+* ℝ^r₁ × ℂ^r₂` that sends `x ∈ K` to `(φ_₁(x),...,φ_r₁(x)) × (ψ_₁(x),..., ψ_r₂(x))` where
 `φ_₁,...,φ_r₁` are its real embeddings and `ψ_₁,..., ψ_r₂` are its complex embeddings (up to
Diff
@@ -45,6 +45,7 @@ scoped[CanonicalEmbedding]
   notation "E" =>
     ({ w : InfinitePlace K // IsReal w } → ℝ) × ({ w : InfinitePlace K // IsComplex w } → ℂ)
 
+#print NumberField.canonicalEmbedding.space_rank /-
 theorem space_rank [NumberField K] : finrank ℝ E = finrank ℚ K :=
   by
   haveI : Module.Free ℝ ℂ := inferInstance
@@ -52,9 +53,11 @@ theorem space_rank [NumberField K] : finrank ℝ E = finrank ℚ K :=
     Finset.card_univ, ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm, ←
     card_complex_embeddings, ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
     Nat.add_sub_of_le (Fintype.card_subtype_le _)]
-#align number_field.canonical_embedding.space_rank NumberField.CanonicalEmbedding.space_rank
+#align number_field.canonical_embedding.space_rank NumberField.canonicalEmbedding.space_rank
+-/
 
-theorem non_trivial_space [NumberField K] : Nontrivial E :=
+#print NumberField.canonicalEmbedding.nontrivial_space /-
+theorem nontrivial_space [NumberField K] : Nontrivial E :=
   by
   obtain ⟨w⟩ := infinite_place.nonempty K
   obtain hw | hw := w.is_real_or_is_complex
@@ -62,34 +65,44 @@ theorem non_trivial_space [NumberField K] : Nontrivial E :=
     exact nontrivial_prod_left
   · haveI : Nonempty { w : infinite_place K // is_complex w } := ⟨⟨w, hw⟩⟩
     exact nontrivial_prod_right
-#align number_field.canonical_embedding.non_trivial_space NumberField.CanonicalEmbedding.non_trivial_space
+#align number_field.canonical_embedding.non_trivial_space NumberField.canonicalEmbedding.nontrivial_space
+-/
 
+#print NumberField.canonicalEmbedding /-
 /-- The canonical embedding of a number field `K` of signature `(r₁, r₂)` into `ℝ^r₁ × ℂ^r₂`. -/
 def NumberField.canonicalEmbedding : K →+* E :=
   RingHom.prod (Pi.ringHom fun w => w.Prop.Embedding) (Pi.ringHom fun w => w.val.Embedding)
 #align number_field.canonical_embedding NumberField.canonicalEmbedding
+-/
 
+#print NumberField.canonicalEmbedding_injective /-
 theorem NumberField.canonicalEmbedding_injective [NumberField K] :
     Injective (NumberField.canonicalEmbedding K) :=
-  @RingHom.injective _ _ _ _ (non_trivial_space K) _
+  @RingHom.injective _ _ _ _ (nontrivial_space K) _
 #align number_field.canonical_embedding_injective NumberField.canonicalEmbedding_injective
+-/
 
 open NumberField
 
 variable {K}
 
+#print NumberField.canonicalEmbedding.apply_at_real_infinitePlace /-
 @[simp]
 theorem apply_at_real_infinitePlace (w : { w : InfinitePlace K // IsReal w }) (x : K) :
     (NumberField.canonicalEmbedding K x).1 w = w.Prop.Embedding x := by
   simp only [canonical_embedding, RingHom.prod_apply, Pi.ringHom_apply]
 #align number_field.canonical_embedding.apply_at_real_infinite_place NumberField.canonicalEmbedding.apply_at_real_infinitePlace
+-/
 
+#print NumberField.canonicalEmbedding.apply_at_complex_infinitePlace /-
 @[simp]
 theorem apply_at_complex_infinitePlace (w : { w : InfinitePlace K // IsComplex w }) (x : K) :
     (NumberField.canonicalEmbedding K x).2 w = Embedding w.val x := by
   simp only [canonical_embedding, RingHom.prod_apply, Pi.ringHom_apply]
 #align number_field.canonical_embedding.apply_at_complex_infinite_place NumberField.canonicalEmbedding.apply_at_complex_infinitePlace
+-/
 
+#print NumberField.canonicalEmbedding.nnnorm_eq /-
 theorem nnnorm_eq [NumberField K] (x : K) :
     ‖canonicalEmbedding K x‖₊ = Finset.univ.sup fun w : InfinitePlace K => ⟨w x, map_nonneg w x⟩ :=
   by
@@ -118,7 +131,9 @@ theorem nnnorm_eq [NumberField K] (x : K) :
     simp only [w.is_real_or_is_complex, Set.mem_setOf_eq, Finset.mem_union, Set.mem_toFinset,
       Finset.mem_univ]
 #align number_field.canonical_embedding.nnnorm_eq NumberField.canonicalEmbedding.nnnorm_eq
+-/
 
+#print NumberField.canonicalEmbedding.norm_le_iff /-
 theorem norm_le_iff [NumberField K] (x : K) (r : ℝ) :
     ‖canonicalEmbedding K x‖ ≤ r ↔ ∀ w : InfinitePlace K, w x ≤ r :=
   by
@@ -131,14 +146,18 @@ theorem norm_le_iff [NumberField K] (x : K) (r : ℝ) :
     simp_rw [← coe_nnnorm, nnnorm_eq, NNReal.coe_le_coe, Finset.sup_le_iff, Finset.mem_univ,
       forall_true_left, ← NNReal.coe_le_coe, Subtype.coe_mk]
 #align number_field.canonical_embedding.norm_le_iff NumberField.canonicalEmbedding.norm_le_iff
+-/
 
 variable (K)
 
+#print NumberField.canonicalEmbedding.integerLattice /-
 /-- The image of `𝓞 K` as a subring of `ℝ^r₁ × ℂ^r₂`. -/
 def integerLattice : Subring E :=
   (RingHom.range (algebraMap (𝓞 K) K)).map (canonicalEmbedding K)
 #align number_field.canonical_embedding.integer_lattice NumberField.canonicalEmbedding.integerLattice
+-/
 
+#print NumberField.canonicalEmbedding.equivIntegerLattice /-
 /-- The linear equiv between `𝓞 K` and the integer lattice. -/
 def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
   LinearEquiv.ofBijective
@@ -152,7 +171,9 @@ def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
       rw [LinearMap.coe_mk, Subtype.mk_eq_mk] at h 
       exact IsFractionRing.injective (𝓞 K) K (canonical_embedding_injective K h))
 #align number_field.canonical_embedding.equiv_integer_lattice NumberField.canonicalEmbedding.equivIntegerLattice
+-/
 
+#print NumberField.canonicalEmbedding.integerLattice.inter_ball_finite /-
 theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
     ((integerLattice K : Set E) ∩ closedBall 0 r).Finite :=
   by
@@ -169,6 +190,7 @@ theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
   · rintro ⟨x, ⟨hx1, hx2⟩, rfl⟩
     exact ⟨⟨x, ⟨⟨x, hx1⟩, rfl⟩, rfl⟩, (HEq x).mpr hx2⟩
 #align number_field.canonical_embedding.integer_lattice.inter_ball_finite NumberField.canonicalEmbedding.integerLattice.inter_ball_finite
+-/
 
 instance [NumberField K] : Countable (integerLattice K) :=
   by
Diff
@@ -40,7 +40,6 @@ variable (K : Type _) [Field K]
 
 namespace NumberField.canonicalEmbedding
 
--- mathport name: exprE
 -- The ambient space `ℝ^r₁ × ℂ^r₂` with `(r₁, r₂)` the signature of `K`.
 scoped[CanonicalEmbedding]
   notation "E" =>
Diff
@@ -97,18 +97,21 @@ theorem nnnorm_eq [NumberField K] (x : K) :
   rw [Prod.nnnorm_def', Pi.nnnorm_def, Pi.nnnorm_def]
   rw [(_ :
       Finset.univ =
-        { w : infinite_place K | is_real w }.toFinset ∪
-          { w : infinite_place K | is_complex w }.toFinset)]
+        {w : infinite_place K | is_real w}.toFinset ∪
+          {w : infinite_place K | is_complex w}.toFinset)]
   · rw [Finset.sup_union, sup_eq_max]
     refine' congr_arg₂ _ _ _
-    · convert(finset.univ.sup_map (Function.Embedding.subtype fun w : infinite_place K => is_real w)
-            fun w => (⟨w x, map_nonneg w x⟩ : NNReal)).symm using 2
+    · convert
+        (finset.univ.sup_map (Function.Embedding.subtype fun w : infinite_place K => is_real w)
+            fun w => (⟨w x, map_nonneg w x⟩ : NNReal)).symm using
+        2
       ext w
       simp only [apply_at_real_infinite_place, coe_nnnorm, Real.norm_eq_abs,
         Function.Embedding.coe_subtype, Subtype.coe_mk, is_real.abs_embedding_apply]
-    · convert(finset.univ.sup_map
-            (Function.Embedding.subtype fun w : infinite_place K => is_complex w) fun w =>
-            (⟨w x, map_nonneg w x⟩ : NNReal)).symm using 2
+    · convert
+        (finset.univ.sup_map (Function.Embedding.subtype fun w : infinite_place K => is_complex w)
+            fun w => (⟨w x, map_nonneg w x⟩ : NNReal)).symm using
+        2
       ext w
       simp only [apply_at_complex_infinite_place, Subtype.val_eq_coe, coe_nnnorm,
         Complex.norm_eq_abs, Function.Embedding.coe_subtype, Subtype.coe_mk, abs_embedding]
@@ -160,7 +163,7 @@ theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
     by
     simp only [← place_apply, ← infinite_place.coe_mk, mem_closedBall_zero_iff, norm_le_iff]
     exact fun x => le_iff_le x r
-  convert(embeddings.finite_of_norm_le K ℂ r).image (canonical_embedding K)
+  convert (embeddings.finite_of_norm_le K ℂ r).image (canonical_embedding K)
   ext; constructor
   · rintro ⟨⟨_, ⟨x, rfl⟩, rfl⟩, hx2⟩
     exact ⟨x, ⟨SetLike.coe_mem x, (HEq x).mp hx2⟩, rfl⟩
Diff
@@ -147,7 +147,7 @@ def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
       map_smul' := fun c x => by simpa only [zsmul_eq_mul, map_mul, map_intCast] }
     (by
       refine' ⟨fun _ _ h => _, fun ⟨_, _, ⟨a, rfl⟩, rfl⟩ => ⟨a, rfl⟩⟩
-      rw [LinearMap.coe_mk, Subtype.mk_eq_mk] at h
+      rw [LinearMap.coe_mk, Subtype.mk_eq_mk] at h 
       exact IsFractionRing.injective (𝓞 K) K (canonical_embedding_injective K h))
 #align number_field.canonical_embedding.equiv_integer_lattice NumberField.canonicalEmbedding.equivIntegerLattice
 
Diff
@@ -34,7 +34,7 @@ noncomputable section
 
 open Function FiniteDimensional Finset Fintype NumberField NumberField.InfinitePlace Metric Module
 
-open Classical NumberField
+open scoped Classical NumberField
 
 variable (K : Type _) [Field K]
 
Diff
@@ -161,8 +161,7 @@ theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
     simp only [← place_apply, ← infinite_place.coe_mk, mem_closedBall_zero_iff, norm_le_iff]
     exact fun x => le_iff_le x r
   convert(embeddings.finite_of_norm_le K ℂ r).image (canonical_embedding K)
-  ext
-  constructor
+  ext; constructor
   · rintro ⟨⟨_, ⟨x, rfl⟩, rfl⟩, hx2⟩
     exact ⟨x, ⟨SetLike.coe_mem x, (HEq x).mp hx2⟩, rfl⟩
   · rintro ⟨x, ⟨hx1, hx2⟩, rfl⟩
Diff
@@ -172,10 +172,10 @@ theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
 instance [NumberField K] : Countable (integerLattice K) :=
   by
   have : (⋃ n : ℕ, (integer_lattice K : Set E) ∩ closed_ball 0 n).Countable :=
-    Set.countable_unionᵢ fun n => (integer_lattice.inter_ball_finite K n).Countable
+    Set.countable_iUnion fun n => (integer_lattice.inter_ball_finite K n).Countable
   refine' (this.mono _).to_subtype
   rintro _ ⟨x, hx, rfl⟩
-  rw [Set.mem_unionᵢ]
+  rw [Set.mem_iUnion]
   exact ⟨⌈‖canonical_embedding K x‖⌉₊, ⟨x, hx, rfl⟩, mem_closedBall_zero_iff.2 (Nat.le_ceil _)⟩
 
 end NumberField.canonicalEmbedding

Changes in mathlib4

mathlib3
mathlib4
chore: adapt to multiple goal linter 1 (#12338)

A PR accompanying #12339.

Zulip discussion

Diff
@@ -88,7 +88,7 @@ instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasur
 instance : NoAtoms (volume : Measure (E K)) := by
   obtain ⟨w⟩ := (inferInstance : Nonempty (InfinitePlace K))
   by_cases hw : IsReal w
-  exact @prod.instNoAtoms_fst _ _ _ _ volume volume _ (pi_noAtoms ⟨w, hw⟩)
+  · exact @prod.instNoAtoms_fst _ _ _ _ volume volume _ (pi_noAtoms ⟨w, hw⟩)
   · exact @prod.instNoAtoms_snd _ _ _ _ volume volume _
       (pi_noAtoms ⟨w, not_isReal_iff_isComplex.mp hw⟩)
 
@@ -223,16 +223,16 @@ theorem convexBodyLT'_volume :
   have vol_box : ∀ B : ℝ≥0, volume {x : ℂ | |x.re| < 1 ∧ |x.im| < B^2} = 4*B^2 := by
     intro B
     rw [← (Complex.volume_preserving_equiv_real_prod.symm).measure_preimage]
-    simp_rw [Set.preimage_setOf_eq, Complex.measurableEquivRealProd_symm_apply]
-    rw [show {a : ℝ × ℝ | |a.1| < 1 ∧ |a.2| < B ^ 2} =
-      Set.Ioo (-1:ℝ) (1:ℝ) ×ˢ Set.Ioo (- (B:ℝ) ^ 2) ((B:ℝ) ^ 2) by
-        ext; simp_rw [Set.mem_setOf_eq, Set.mem_prod, Set.mem_Ioo, abs_lt]]
-    simp_rw [volume_eq_prod, prod_prod, Real.volume_Ioo, sub_neg_eq_add, one_add_one_eq_two,
-      ← two_mul, ofReal_mul zero_le_two, ofReal_pow (coe_nonneg B), ofReal_ofNat,
-      ofReal_coe_nnreal, ← mul_assoc, show (2:ℝ≥0∞) * 2 = 4 by norm_num]
-    refine MeasurableSet.inter ?_ ?_
-    · exact measurableSet_lt (measurable_norm.comp Complex.measurable_re) measurable_const
-    · exact measurableSet_lt (measurable_norm.comp Complex.measurable_im) measurable_const
+    · simp_rw [Set.preimage_setOf_eq, Complex.measurableEquivRealProd_symm_apply]
+      rw [show {a : ℝ × ℝ | |a.1| < 1 ∧ |a.2| < B ^ 2} =
+        Set.Ioo (-1:ℝ) (1:ℝ) ×ˢ Set.Ioo (- (B:ℝ) ^ 2) ((B:ℝ) ^ 2) by
+          ext; simp_rw [Set.mem_setOf_eq, Set.mem_prod, Set.mem_Ioo, abs_lt]]
+      simp_rw [volume_eq_prod, prod_prod, Real.volume_Ioo, sub_neg_eq_add, one_add_one_eq_two,
+        ← two_mul, ofReal_mul zero_le_two, ofReal_pow (coe_nonneg B), ofReal_ofNat,
+        ofReal_coe_nnreal, ← mul_assoc, show (2:ℝ≥0∞) * 2 = 4 by norm_num]
+    · refine MeasurableSet.inter ?_ ?_
+      · exact measurableSet_lt (measurable_norm.comp Complex.measurable_re) measurable_const
+      · exact measurableSet_lt (measurable_norm.comp Complex.measurable_im) measurable_const
   calc
     _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
           ((∏ x in Finset.univ.erase  w₀, ENNReal.ofReal (f x.val) ^ 2 * pi) *
@@ -384,8 +384,8 @@ theorem convexBodySum_convex : Convex ℝ (convexBodySum K B) := by
 theorem convexBodySum_isBounded : Bornology.IsBounded (convexBodySum K B) := by
   refine Metric.isBounded_iff.mpr ⟨B + B, fun x hx y hy => ?_⟩
   refine le_trans (norm_sub_le x y) (add_le_add ?_ ?_)
-  exact le_trans (norm_le_convexBodySumFun x) hx
-  exact le_trans (norm_le_convexBodySumFun y) hy
+  · exact le_trans (norm_le_convexBodySumFun x) hx
+  · exact le_trans (norm_le_convexBodySumFun y) hy
 
 theorem convexBodySum_compact : IsCompact (convexBodySum K B) := by
   rw [Metric.isCompact_iff_isClosed_bounded]
@@ -486,10 +486,10 @@ theorem volume_fundamentalDomain_fractionalIdealLatticeBasis :
       fractionalIdeal_rank]
   rw [← fundamentalDomain_reindex (fractionalIdealLatticeBasis K I) e,
     measure_fundamentalDomain ((fractionalIdealLatticeBasis K I).reindex e)]
-  rw [show (fractionalIdealLatticeBasis K I).reindex e = (mixedEmbedding K) ∘
-      (basisOfFractionalIdeal K I) ∘ e.symm by
-    ext1; simp only [Basis.coe_reindex, Function.comp_apply, fractionalIdealLatticeBasis_apply]]
-  rw [mixedEmbedding.det_basisOfFractionalIdeal_eq_norm]
+  · rw [show (fractionalIdealLatticeBasis K I).reindex e = (mixedEmbedding K) ∘
+        (basisOfFractionalIdeal K I) ∘ e.symm by
+      ext1; simp only [Basis.coe_reindex, Function.comp_apply, fractionalIdealLatticeBasis_apply]]
+    rw [mixedEmbedding.det_basisOfFractionalIdeal_eq_norm]
 
 theorem minkowskiBound_lt_top : minkowskiBound K I < ⊤ := by
   refine ENNReal.mul_lt_top ?_ ?_
chore: adapt to multiple goal linter 1 (#12338)

A PR accompanying #12339.

Zulip discussion

Diff
@@ -78,8 +78,8 @@ theorem norm_le_iff [NumberField K] (x : K) (r : ℝ) :
   obtain hr | hr := lt_or_le r 0
   · obtain ⟨φ⟩ := (inferInstance : Nonempty (K →+* ℂ))
     refine iff_of_false ?_ ?_
-    exact (hr.trans_le (norm_nonneg _)).not_le
-    exact fun h => hr.not_le (le_trans (norm_nonneg _) (h φ))
+    · exact (hr.trans_le (norm_nonneg _)).not_le
+    · exact fun h => hr.not_le (le_trans (norm_nonneg _) (h φ))
   · lift r to NNReal using hr
     simp_rw [← coe_nnnorm, nnnorm_eq, NNReal.coe_le_coe, Finset.sup_le_iff, Finset.mem_univ,
       forall_true_left]
feat: Add mixedEmbedding.norm (#12249)

Define a norm of the mixed space ℝ^r₁ × ℂ^r₂ associated to a number field K of signature (r₁, r₂). The norm is defined such that the norm of mixedEmbedding K a for a : K is equal to the absolute value of the norm of a over .

This norm will be used in a future PR about the quotient of the mixed space by the action of the units of K.

Co-authored-by: Xavier Roblot <46200072+xroblot@users.noreply.github.com>

Diff
@@ -241,9 +241,76 @@ theorem disjoint_span_commMap_ker [NumberField K] :
 
 end commMap
 
+noncomputable section norm
+
+open scoped Classical
+
+open BigOperators
+
+variable [NumberField K] {K}
+
+/-- The norm of `x` is `∏ w real, ‖x‖_w * ∏ w complex, ‖x‖_w ^ 2`. It is defined such that
+the norm of `mixedEmbedding K a` for `a : K` is equal to the absolute value of the norm of `a`
+over `ℚ`, see `norm_eq_norm`. -/
+protected def norm  : (E K) →*₀ ℝ where
+  toFun := fun x ↦ (∏ w, ‖x.1 w‖) * ∏ w, ‖x.2 w‖ ^ 2
+  map_one' := by simp only [Prod.fst_one, Pi.one_apply, norm_one, Finset.prod_const_one,
+    Prod.snd_one, one_pow, mul_one]
+  map_zero' := by
+    simp_rw [Prod.fst_zero, Prod.snd_zero, Pi.zero_apply, norm_zero, zero_pow (two_ne_zero),
+      mul_eq_zero, Finset.prod_const, pow_eq_zero_iff', true_and, Finset.card_univ]
+    by_contra!
+    have : finrank ℚ K = 0 := by
+      rw [← card_add_two_mul_card_eq_rank, NrRealPlaces, NrComplexPlaces, this.1, this.2]
+    exact ne_of_gt finrank_pos this
+  map_mul' _ _ := by simp only [Prod.fst_mul, Pi.mul_apply, norm_mul, Real.norm_eq_abs,
+      Finset.prod_mul_distrib, Prod.snd_mul, Complex.norm_eq_abs, mul_pow]; ring
+
+protected theorem norm_eq_zero_iff {x : E K} :
+    mixedEmbedding.norm x = 0 ↔ (∃ w, x.1 w = 0) ∨ (∃ w, x.2 w = 0) := by
+  simp_rw [mixedEmbedding.norm, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk, mul_eq_zero,
+    Finset.prod_eq_zero_iff, Finset.mem_univ, true_and, pow_eq_zero_iff two_ne_zero, norm_eq_zero]
+
+protected theorem norm_ne_zero_iff {x : E K} :
+    mixedEmbedding.norm x ≠ 0 ↔ (∀ w, x.1 w ≠ 0) ∧ (∀ w, x.2 w ≠ 0) := by
+  rw [← not_iff_not]
+  simp_rw [ne_eq, mixedEmbedding.norm_eq_zero_iff, not_and_or, not_forall, not_not]
+
+theorem norm_real (c : ℝ) :
+    mixedEmbedding.norm ((fun _ ↦ c, fun _ ↦ c) : (E K)) = |c| ^ finrank ℚ K := by
+  simp_rw [mixedEmbedding.norm, MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk, Real.norm_eq_abs,
+    Complex.norm_eq_abs, Complex.abs_ofReal, Finset.prod_const, ← pow_mul,
+    ← card_add_two_mul_card_eq_rank, Finset.card_univ, pow_add]
+
+theorem norm_smul (c : ℝ) (x : E K) :
+    mixedEmbedding.norm (c • x) = |c| ^ finrank ℚ K * (mixedEmbedding.norm x) := by
+  rw [show c • x = ((fun _ ↦ c, fun _ ↦ c) : (E K)) * x by rfl, map_mul, norm_real]
+
+@[simp]
+theorem norm_eq_norm (x : K) :
+    mixedEmbedding.norm (mixedEmbedding K x) = |Algebra.norm ℚ x| := by
+  simp_rw [← prod_eq_abs_norm, mixedEmbedding.norm, mixedEmbedding, RingHom.prod_apply,
+    MonoidWithZeroHom.coe_mk, ZeroHom.coe_mk, Pi.ringHom_apply, norm_embedding_eq,
+    norm_embedding_of_isReal]
+  rw [← Fintype.prod_subtype_mul_prod_subtype (fun w : InfinitePlace K ↦ IsReal w)]
+  congr 1
+  · exact Finset.prod_congr rfl (fun w _ ↦ by rw [mult, if_pos w.prop, pow_one])
+  · refine (Fintype.prod_equiv (Equiv.subtypeEquivRight ?_) _ _ (fun w ↦ ?_)).symm
+    · exact fun _ ↦ not_isReal_iff_isComplex
+    · rw [Equiv.subtypeEquivRight_apply_coe, mult, if_neg w.prop]
+
+theorem norm_eq_zero_iff' {x : E K} (hx : x ∈ Set.range (mixedEmbedding K)) :
+    mixedEmbedding.norm x = 0 ↔ x = 0 := by
+  obtain ⟨a, rfl⟩ := hx
+  rw [norm_eq_norm, Rat.cast_abs, abs_eq_zero, Rat.cast_eq_zero, Algebra.norm_eq_zero_iff,
+    map_eq_zero]
+
+end norm
+
 noncomputable section stdBasis
 
 open scoped Classical
+
 open Complex MeasureTheory MeasureTheory.Measure Zspan Matrix BigOperators
   ComplexConjugate
 
chore: tidy various files (#12213)
Diff
@@ -293,12 +293,12 @@ theorem convexBodySumFun_neg (x : E K) :
 theorem convexBodySumFun_add_le (x y : E K) :
     convexBodySumFun (x + y) ≤ convexBodySumFun x + convexBodySumFun y := by
   simp_rw [convexBodySumFun, Prod.fst_add, Pi.add_apply, Prod.snd_add]
-  refine le_trans (add_le_add
+  refine (add_le_add
     (Finset.sum_le_sum (fun w _ => norm_add_le (x.1 w) (y.1 w)))
     (mul_le_mul_of_nonneg_left
-      (Finset.sum_le_sum (fun w _ => norm_add_le (x.2 w) (y.2 w))) (by norm_num))) ?_
+      (Finset.sum_le_sum (fun w _ => norm_add_le (x.2 w) (y.2 w))) (by norm_num))).trans_eq ?_
   simp_rw [Finset.sum_add_distrib, mul_add]
-  exact le_of_eq (by ring)
+  ring
 
 theorem convexBodySumFun_smul (c : ℝ) (x : E K) :
     convexBodySumFun (c • x) = |c| * convexBodySumFun x := by
chore: Rename nat_cast/int_cast/rat_cast to natCast/intCast/ratCast (#11486)

Now that I am defining NNRat.cast, I want a definitive answer to this naming issue. Plenty of lemmas in mathlib already use natCast/intCast/ratCast over nat_cast/int_cast/rat_cast, and this matches with the general expectation that underscore-separated name parts correspond to a single declaration.

Diff
@@ -141,7 +141,7 @@ theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁
   · exact fun w hw => Function.update_noteq hw _ f
   · rw [← Finset.mul_prod_erase Finset.univ _ (Finset.mem_univ w₁), Function.update_same,
       Finset.prod_congr rfl fun w hw => by rw [Function.update_noteq (Finset.ne_of_mem_erase hw)],
-      ← NNReal.rpow_nat_cast, ← NNReal.rpow_mul, inv_mul_cancel, NNReal.rpow_one, mul_assoc,
+      ← NNReal.rpow_natCast, ← NNReal.rpow_mul, inv_mul_cancel, NNReal.rpow_one, mul_assoc,
       inv_mul_cancel, mul_one]
     · rw [Finset.prod_ne_zero_iff]
       exact fun w hw => pow_ne_zero _ (hf w (Finset.ne_of_mem_erase hw))
@@ -622,14 +622,14 @@ theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
   rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
   refine ⟨a, ha, by simpa using h_nz, ?_⟩
-  rw [← rpow_nat_cast, ← rpow_le_rpow_iff (by simp only [Rat.cast_abs, abs_nonneg])
+  rw [← rpow_natCast, ← rpow_le_rpow_iff (by simp only [Rat.cast_abs, abs_nonneg])
       (rpow_nonneg h2 _) h1, ← rpow_mul h2,  mul_inv_cancel (Nat.cast_ne_zero.mpr
       (ne_of_gt finrank_pos)), rpow_one, le_div_iff' (Nat.cast_pos.mpr finrank_pos)]
   refine le_trans ?_ ((convexBodySum_mem K B).mp h_mem)
   rw [← le_div_iff' (Nat.cast_pos.mpr finrank_pos), ← sum_mult_eq, Nat.cast_sum]
   refine le_trans ?_ (geom_mean_le_arith_mean Finset.univ _ _ (fun _ _ => Nat.cast_nonneg _)
     ?_ (fun _ _ => AbsoluteValue.nonneg _ _))
-  · simp_rw [← prod_eq_abs_norm, rpow_nat_cast]
+  · simp_rw [← prod_eq_abs_norm, rpow_natCast]
     exact le_of_eq rfl
   · rw [← Nat.cast_sum, sum_mult_eq, Nat.cast_pos]
     exact finrank_pos
feat: Define the covolume of a ZLattice (#11327)

This PR defines the covolume of a Zlattice as the (finite) volume of any of its fundamental domain and proves some results about it, mainly: it's nonzero, it does not depend of the choice of the fundamental domain and it is equal to the absolute value of the determinant of any basis of the lattice.

This PR also creates a directory Zlattice (with the original file becoming Zlattice/Basic.lean) and a new file Zlattice/Covolume.lean.

Co-authored-by: Xavier Roblot <roblot@Algorithmi.local> Co-authored-by: Xavier Roblot <roblot@math.univ-lyon1.fr>

Diff
@@ -3,7 +3,7 @@ Copyright (c) 2022 Xavier Roblot. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 -/
-import Mathlib.Algebra.Module.Zlattice
+import Mathlib.Algebra.Module.Zlattice.Basic
 import Mathlib.NumberTheory.NumberField.Embeddings
 import Mathlib.NumberTheory.NumberField.FractionalIdeal
 
chore: remove more bex and ball from lemma names (#11615)

Follow-up to #10816.

Remaining places containing such lemmas are

  • Option.bex_ne_none and Option.ball_ne_none: defined in Lean core
  • Nat.decidableBallLT and Nat.decidableBallLE: defined in Lean core
  • bef_def is still used in a number of places and could be renamed
  • BAll.imp_{left,right}, BEx.imp_{left,right}, BEx.intro and BEx.elim

I only audited the first ~150 lemmas mentioning "ball"; too many lemmas named after Metric.ball/openBall/closedBall.

Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>

Diff
@@ -64,7 +64,7 @@ theorem convexBodyLT_mem {x : K} :
     mixedEmbedding K x ∈ (convexBodyLT K f) ↔ ∀ w : InfinitePlace K, w x < f w := by
   simp_rw [mixedEmbedding, RingHom.prod_apply, Set.mem_prod, Set.mem_pi, Set.mem_univ,
     forall_true_left, mem_ball_zero_iff, Pi.ringHom_apply, ← Complex.norm_real,
-    embedding_of_isReal_apply, Subtype.forall, ← ball_or_left, ← not_isReal_iff_isComplex, em,
+    embedding_of_isReal_apply, Subtype.forall, ← forall₂_or_left, ← not_isReal_iff_isComplex, em,
     forall_true_left, norm_embedding_eq]
 
 theorem convexBodyLT_neg_mem (x : E K) (hx : x ∈ (convexBodyLT K f)) :
chore: Rename coe_nat/coe_int/coe_rat to natCast/intCast/ratCast (#11499)

This is less exhaustive than its sibling #11486 because edge cases are harder to classify. No fundamental difficulty, just me being a bit fast and lazy.

Reduce the diff of #11203

Diff
@@ -429,14 +429,14 @@ theorem convexBodySum_volume :
       (fun hx => (convexBodySumFun_eq_zero_iff _).mp hx)
       (fun r x => le_of_eq (convexBodySumFun_smul r x)) zero_lt_one]
     simp_rw [mixedEmbedding.finrank, div_one, Gamma_nat_eq_factorial, ofReal_div_of_pos
-      (Nat.cast_pos.mpr (Nat.factorial_pos _)), Real.rpow_one, ofReal_coe_nat]
+      (Nat.cast_pos.mpr (Nat.factorial_pos _)), Real.rpow_one, ofReal_natCast]
     suffices ∫ x : E K, exp (-convexBodySumFun x) =
         (2:ℝ) ^ NrRealPlaces K * (π / 2) ^ NrComplexPlaces K by
       rw [this, convexBodySumFactor, ofReal_mul (by positivity), ofReal_pow zero_le_two,
         ofReal_pow (by positivity), ofReal_div_of_pos zero_lt_two, ofReal_ofNat,
         ← NNReal.coe_real_pi, ofReal_coe_nnreal, coe_div (Nat.cast_ne_zero.mpr
         (Nat.factorial_ne_zero _)), coe_mul, coe_pow, coe_pow, coe_ofNat, coe_div two_ne_zero,
-        coe_ofNat, coe_nat]
+        coe_ofNat, coe_natCast]
     calc
       _ = (∫ x : {w : InfinitePlace K // IsReal w} → ℝ, ∏ w, exp (- ‖x w‖)) *
               (∫ x : {w : InfinitePlace K // IsComplex w} → ℂ, ∏ w, exp (- 2 * ‖x w‖)) := by
chore: Slightly modify the split of CanonicalEmbedding (#11917)

Create a new directory for the split of CanonicalEmbedding since more material is coming.

Also add some docstrings.

Diff
@@ -5,20 +5,33 @@ Authors: Xavier Roblot
 -/
 import Mathlib.MeasureTheory.Group.GeometryOfNumbers
 import Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls
-import Mathlib.NumberTheory.NumberField.CanonicalEmbedding
+import Mathlib.NumberTheory.NumberField.CanonicalEmbedding.Basic
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
 
 /-!
 # Convex Bodies
 
-This file contains theorems about convex bodies on infinite places of a number field.
+The file contains the definitions of several convex bodies lying in the space `ℝ^r₁ × ℂ^r₂`
+associated to a number field of signature `K` and proves several existence theorems by applying
+*Minkowski Convex Body Theorem* to those.
 
 ## Main definitions and results
 
-* `NumberField.mixedEmbedding.exists_ne_zero_mem_ringOfIntegers_lt`: let
-`f : InfinitePlace K → ℝ≥0`, if the product `∏ w, f w` is large enough, then there exists a
-nonzero algebraic integer `a` in `K` such that `w a < f w` for all infinite places `w`.
+* `NumberField.mixedEmbedding.convexBodyLT`: The set of points `x` such that `‖x w‖ < f w` for all
+infinite places `w` with `f : InfinitePlace K → ℝ≥0`.
+
+* `NumberField.mixedEmbedding.convexBodySum`: The set of points `x` such that
+`∑ w real, ‖x w‖ + 2 * ∑ w complex, ‖x w‖ ≤ B`
+
+* `NumberField.mixedEmbedding.exists_ne_zero_mem_ideal_lt`: Let `I` be a fractional ideal of `K`.
+Assume that `f` is such that `minkowskiBound K I < volume (convexBodyLT K f)`, then there exists a
+nonzero algebraic number `a` in `I` such that `w a < f w` for all infinite places `w`.
+
+* `NumberField.mixedEmbedding.exists_ne_zero_mem_ideal_of_norm_le`: Let `I` be a fractional ideal
+of `K`. Assume that `B` is such that `minkowskiBound K I < volume (convexBodySum K B)` (see
+`convexBodySum_volume` for the computation of this volume), then there exists a nonzero algebraic
+number `a` in `I` such that `|Norm a| < (B / d) ^ d` where `d` is the degree of `K`.
 
 ## Tags
 
@@ -31,6 +44,7 @@ namespace NumberField.mixedEmbedding
 
 open NumberField NumberField.InfinitePlace FiniteDimensional
 
+/-- The space `ℝ^r₁ × ℂ^r₂` with `(r₁, r₂)` the signature of `K`. -/
 local notation "E" K =>
   ({w : InfinitePlace K // IsReal w} → ℝ) × ({w : InfinitePlace K // IsComplex w} → ℂ)
 
@@ -582,6 +596,11 @@ theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀
       rw [NNReal.coe_one, Real.le_sqrt' zero_lt_one, one_pow]
       set_option tactic.skipAssignedInstances false in norm_num
 
+/-- Let `I` be a fractional ideal of `K`. Assume that `B : ℝ` is such that
+`minkowskiBound K I < volume (convexBodySum K B)` where `convexBodySum K B` is the set of points
+`x` such that `∑ w real, ‖x w‖ + 2 * ∑ w complex, ‖x w‖ ≤ B` (see `convexBodySum_volume` for
+the computation of this volume), then there exists a nonzero algebraic number `a` in `I` such
+that `|Norm a| < (B / d) ^ d` where `d` is the degree of `K`. -/
 theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
     (h : (minkowskiBound K I) ≤ volume (convexBodySum K B)) :
     ∃ a ∈ (I : FractionalIdeal (𝓞 K)⁰ K), a ≠ 0 ∧
@@ -623,3 +642,5 @@ theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
   exact ⟨a, ha, h_nz, h_bd⟩
 
 end minkowski
+
+end NumberField.mixedEmbedding
chore: split NumberTheory.NumberField.CanonicalEmbedding (#11873)

#8361 indicates that this is the most compute-intensive file on the longest pole for compiling Mathlib. It's bottlenecked dependency is Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls, and this import isn't used until the second half of the file, in the sections regarding convex bodies. I am therefore splitting the file at that point, from the context of the file it seems to me that this is a sensible split anyway.

chore: split NumberTheory.NumberField.CanonicalEmbedding (#11873)

#8361 indicates that this is the most compute-intensive file on the longest pole for compiling Mathlib. It's bottlenecked dependency is Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls, and this import isn't used until the second half of the file, in the sections regarding convex bodies. I am therefore splitting the file at that point, from the context of the file it seems to me that this is a sensible split anyway.

Diff
@@ -4,8 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 -/
 import Mathlib.Algebra.Module.Zlattice
-import Mathlib.MeasureTheory.Group.GeometryOfNumbers
-import Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls
 import Mathlib.NumberTheory.NumberField.Embeddings
 import Mathlib.NumberTheory.NumberField.FractionalIdeal
 
@@ -34,10 +32,6 @@ associated to the infinite place `w`. In particular, if `w` is real then `φ_w :
 `w` is complex, `φ_w` is an arbitrary choice between the two complex embeddings defining the place
 `w`.
 
-* `NumberField.mixedEmbedding.exists_ne_zero_mem_ringOfIntegers_lt`: let
-`f : InfinitePlace K → ℝ≥0`, if the product `∏ w, f w` is large enough, then there exists a
-nonzero algebraic integer `a` in `K` such that `w a < f w` for all infinite places `w`.
-
 ## Tags
 
 number field, infinite places
@@ -514,594 +508,4 @@ theorem mem_span_fractionalIdealLatticeBasis (x : (E K)) :
 
 end integerLattice
 
-section convexBodyLT
-
-open Metric NNReal
-
-variable (f : InfinitePlace K → ℝ≥0)
-
-/-- The convex body defined by `f`: the set of points `x : E` such that `‖x w‖ < f w` for all
-infinite places `w`. -/
-abbrev convexBodyLT : Set (E K) :=
-  (Set.univ.pi (fun w : { w : InfinitePlace K // IsReal w } => ball 0 (f w))) ×ˢ
-  (Set.univ.pi (fun w : { w : InfinitePlace K // IsComplex w } => ball 0 (f w)))
-
-theorem convexBodyLT_mem {x : K} :
-    mixedEmbedding K x ∈ (convexBodyLT K f) ↔ ∀ w : InfinitePlace K, w x < f w := by
-  simp_rw [mixedEmbedding, RingHom.prod_apply, Set.mem_prod, Set.mem_pi, Set.mem_univ,
-    forall_true_left, mem_ball_zero_iff, Pi.ringHom_apply, ← Complex.norm_real,
-    embedding_of_isReal_apply, Subtype.forall, ← ball_or_left, ← not_isReal_iff_isComplex, em,
-    forall_true_left, norm_embedding_eq]
-
-theorem convexBodyLT_neg_mem (x : E K) (hx : x ∈ (convexBodyLT K f)) :
-    -x ∈ (convexBodyLT K f) := by
-  simp only [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
-    mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
-    Prod.snd_neg, Complex.norm_eq_abs] at hx ⊢
-  exact hx
-
-theorem convexBodyLT_convex : Convex ℝ (convexBodyLT K f) :=
-  Convex.prod (convex_pi (fun _ _ => convex_ball _ _)) (convex_pi (fun _ _ => convex_ball _ _))
-
-open Fintype MeasureTheory MeasureTheory.Measure ENNReal
-
-open scoped Classical BigOperators
-
-variable [NumberField K]
-
-instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasure volume volume
-
-instance : NoAtoms (volume : Measure (E K)) := by
-  obtain ⟨w⟩ := (inferInstance : Nonempty (InfinitePlace K))
-  by_cases hw : IsReal w
-  exact @prod.instNoAtoms_fst _ _ _ _ volume volume _ (pi_noAtoms ⟨w, hw⟩)
-  · exact @prod.instNoAtoms_snd _ _ _ _ volume volume _
-      (pi_noAtoms ⟨w, not_isReal_iff_isComplex.mp hw⟩)
-
-/-- The fudge factor that appears in the formula for the volume of `convexBodyLT`. -/
-noncomputable abbrev convexBodyLTFactor : ℝ≥0 :=
-  (2 : ℝ≥0) ^ NrRealPlaces K * NNReal.pi ^ NrComplexPlaces K
-
-theorem convexBodyLTFactor_ne_zero : convexBodyLTFactor K ≠ 0 :=
-  mul_ne_zero (pow_ne_zero _ two_ne_zero) (pow_ne_zero _ pi_ne_zero)
-
-theorem one_le_convexBodyLTFactor : 1 ≤ convexBodyLTFactor K :=
-  one_le_mul₀ (one_le_pow_of_one_le one_le_two _)
-    (one_le_pow_of_one_le (le_trans one_le_two Real.two_le_pi) _)
-
-/-- The volume of `(ConvexBodyLt K f)` where `convexBodyLT K f` is the set of points `x`
-such that `‖x w‖ < f w` for all infinite places `w`. -/
-theorem convexBodyLT_volume :
-    volume (convexBodyLT K f) = (convexBodyLTFactor K) * ∏ w, (f w) ^ (mult w) := by
-  calc
-    _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
-          ∏ x : {w // InfinitePlace.IsComplex w}, ENNReal.ofReal (f x.val) ^ 2 * pi := by
-      simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball, Complex.volume_ball]
-    _ = ((2:ℝ≥0) ^ NrRealPlaces K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)))
-          * ((∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) *
-            NNReal.pi ^ NrComplexPlaces K) := by
-      simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
-        Finset.card_univ, ofReal_ofNat, ofReal_coe_nnreal, coe_ofNat]
-    _ = (convexBodyLTFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, .ofReal (f x.val)) *
-        (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by
-      simp_rw [convexBodyLTFactor, coe_mul, ENNReal.coe_pow]
-      ring
-    _ = (convexBodyLTFactor K) * ∏ w, (f w) ^ (mult w) := by
-      simp_rw [mult, pow_ite, pow_one, Finset.prod_ite, ofReal_coe_nnreal, not_isReal_iff_isComplex,
-        coe_mul, coe_finset_prod, ENNReal.coe_pow]
-      congr 2
-      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞))).symm
-        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
-      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞) ^ 2)).symm
-        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
-
-variable {f}
-
-/-- This is a technical result: quite often, we want to impose conditions at all infinite places
-but one and choose the value at the remaining place so that we can apply
-`exists_ne_zero_mem_ringOfIntegers_lt`. -/
-theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁ → f w ≠ 0) :
-    ∃ g : InfinitePlace K → ℝ≥0, (∀ w, w ≠ w₁ → g w = f w) ∧ ∏ w, (g w) ^ mult w = B := by
-  let S := ∏ w in Finset.univ.erase w₁, (f w) ^ mult w
-  refine ⟨Function.update f w₁ ((B * S⁻¹) ^ (mult w₁ : ℝ)⁻¹), ?_, ?_⟩
-  · exact fun w hw => Function.update_noteq hw _ f
-  · rw [← Finset.mul_prod_erase Finset.univ _ (Finset.mem_univ w₁), Function.update_same,
-      Finset.prod_congr rfl fun w hw => by rw [Function.update_noteq (Finset.ne_of_mem_erase hw)],
-      ← NNReal.rpow_nat_cast, ← NNReal.rpow_mul, inv_mul_cancel, NNReal.rpow_one, mul_assoc,
-      inv_mul_cancel, mul_one]
-    · rw [Finset.prod_ne_zero_iff]
-      exact fun w hw => pow_ne_zero _ (hf w (Finset.ne_of_mem_erase hw))
-    · rw [mult]; split_ifs <;> norm_num
-
-end convexBodyLT
-
-section convexBodyLT'
-
-open  Metric ENNReal NNReal
-
-open scoped Classical
-
-variable (f : InfinitePlace K → ℝ≥0) (w₀ : {w : InfinitePlace K // IsComplex w})
-
-/-- A version of `convexBodyLT` with an additional condition at a fixed complex place. This is
-needed to ensure the element constructed is not real, see for example
-`exists_primitive_element_lt_of_isComplex`.
--/
-abbrev convexBodyLT' : Set (E K) :=
-  (Set.univ.pi (fun w : { w : InfinitePlace K // IsReal w } ↦ ball 0 (f w))) ×ˢ
-  (Set.univ.pi (fun w : { w : InfinitePlace K // IsComplex w } ↦
-    if w = w₀ then {x | |x.re| < 1 ∧ |x.im| < (f w : ℝ) ^ 2} else ball 0 (f w)))
-
-theorem convexBodyLT'_mem {x : K} :
-    mixedEmbedding K x ∈ convexBodyLT' K f w₀ ↔
-      (∀ w : InfinitePlace K, w ≠ w₀ → w x < f w) ∧
-      |(w₀.val.embedding x).re| < 1 ∧ |(w₀.val.embedding x).im| < (f w₀: ℝ) ^ 2 := by
-  simp_rw [mixedEmbedding, RingHom.prod_apply, Set.mem_prod, Set.mem_pi, Set.mem_univ,
-    forall_true_left, Pi.ringHom_apply, apply_ite, mem_ball_zero_iff, ← Complex.norm_real,
-    embedding_of_isReal_apply, norm_embedding_eq, Subtype.forall, Set.mem_setOf_eq]
-  refine ⟨fun ⟨h₁, h₂⟩ ↦ ⟨fun w h_ne ↦ ?_, ?_⟩, fun ⟨h₁, h₂⟩ ↦ ⟨fun w hw ↦ ?_, fun w hw ↦ ?_⟩⟩
-  · by_cases hw : IsReal w
-    · exact norm_embedding_eq w _ ▸ h₁ w hw
-    · specialize h₂ w (not_isReal_iff_isComplex.mp hw)
-      rwa [if_neg (by exact Subtype.coe_ne_coe.1 h_ne)] at h₂
-  · simpa [if_true] using h₂ w₀.val w₀.prop
-  · exact h₁ w (ne_of_isReal_isComplex hw w₀.prop)
-  · by_cases h_ne : w = w₀
-    · simpa [h_ne]
-    · rw [if_neg (by exact Subtype.coe_ne_coe.1 h_ne)]
-      exact h₁ w h_ne
-
-theorem convexBodyLT'_neg_mem (x : E K) (hx : x ∈ convexBodyLT' K f w₀) :
-    -x ∈ convexBodyLT' K f w₀ := by
-  simp [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
-    mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
-    Prod.snd_neg, Complex.norm_eq_abs] at hx ⊢
-  convert hx using 3
-  split_ifs <;> simp
-
-theorem convexBodyLT'_convex : Convex ℝ (convexBodyLT' K f w₀) := by
-  refine Convex.prod (convex_pi (fun _ _ => convex_ball _ _)) (convex_pi (fun _ _ => ?_))
-  split_ifs
-  · simp_rw [abs_lt]
-    refine Convex.inter ((convex_halfspace_re_gt _).inter  (convex_halfspace_re_lt _))
-      ((convex_halfspace_im_gt _).inter  (convex_halfspace_im_lt _))
-  · exact convex_ball _ _
-
-open MeasureTheory MeasureTheory.Measure
-
-open scoped Classical BigOperators
-
-variable [NumberField K]
-
-/-- The fudge factor that appears in the formula for the volume of `convexBodyLT'`. -/
-noncomputable abbrev convexBodyLT'Factor : ℝ≥0 :=
-  (2 : ℝ≥0) ^ (NrRealPlaces K + 2) * NNReal.pi ^ (NrComplexPlaces K - 1)
-
-theorem convexBodyLT'Factor_ne_zero : convexBodyLT'Factor K ≠ 0 :=
-  mul_ne_zero (pow_ne_zero _ two_ne_zero) (pow_ne_zero _ pi_ne_zero)
-
-theorem one_le_convexBodyLT'Factor : 1 ≤ convexBodyLT'Factor K :=
-  one_le_mul₀ (one_le_pow_of_one_le one_le_two _)
-    (one_le_pow_of_one_le (le_trans one_le_two Real.two_le_pi) _)
-
-theorem convexBodyLT'_volume :
-    volume (convexBodyLT' K f w₀) = convexBodyLT'Factor K * ∏ w, (f w) ^ (mult w) := by
-  have vol_box : ∀ B : ℝ≥0, volume {x : ℂ | |x.re| < 1 ∧ |x.im| < B^2} = 4*B^2 := by
-    intro B
-    rw [← (Complex.volume_preserving_equiv_real_prod.symm).measure_preimage]
-    simp_rw [Set.preimage_setOf_eq, Complex.measurableEquivRealProd_symm_apply]
-    rw [show {a : ℝ × ℝ | |a.1| < 1 ∧ |a.2| < B ^ 2} =
-      Set.Ioo (-1:ℝ) (1:ℝ) ×ˢ Set.Ioo (- (B:ℝ) ^ 2) ((B:ℝ) ^ 2) by
-        ext; simp_rw [Set.mem_setOf_eq, Set.mem_prod, Set.mem_Ioo, abs_lt]]
-    simp_rw [volume_eq_prod, prod_prod, Real.volume_Ioo, sub_neg_eq_add, one_add_one_eq_two,
-      ← two_mul, ofReal_mul zero_le_two, ofReal_pow (coe_nonneg B), ofReal_ofNat,
-      ofReal_coe_nnreal, ← mul_assoc, show (2:ℝ≥0∞) * 2 = 4 by norm_num]
-    refine MeasurableSet.inter ?_ ?_
-    · exact measurableSet_lt (measurable_norm.comp Complex.measurable_re) measurable_const
-    · exact measurableSet_lt (measurable_norm.comp Complex.measurable_im) measurable_const
-  calc
-    _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
-          ((∏ x in Finset.univ.erase  w₀, ENNReal.ofReal (f x.val) ^ 2 * pi) *
-          (4 * (f w₀) ^ 2)) := by
-      simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball]
-      rw [← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)]
-      congr 2
-      · refine Finset.prod_congr rfl (fun w' hw' ↦ ?_)
-        rw [if_neg (Finset.ne_of_mem_erase hw'), Complex.volume_ball]
-      · simpa only [ite_true] using vol_box (f w₀)
-    _ = ((2 : ℝ≥0) ^ NrRealPlaces K *
-          (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
-            ((∏ x in Finset.univ.erase  w₀, ENNReal.ofReal (f x.val) ^ 2) *
-              ↑pi ^ (NrComplexPlaces K - 1) * (4 * (f w₀) ^ 2)) := by
-      simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
-        Finset.card_erase_of_mem (Finset.mem_univ _), Finset.card_univ, ofReal_ofNat,
-        ofReal_coe_nnreal, coe_ofNat]
-    _ = convexBodyLT'Factor K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))
-        * (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) := by
-      rw [show (4 : ℝ≥0∞) = (2 : ℝ≥0) ^ 2 by norm_num, convexBodyLT'Factor, pow_add,
-        ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀), ofReal_coe_nnreal]
-      simp_rw [coe_mul, ENNReal.coe_pow]
-      ring
-    _ = convexBodyLT'Factor K * ∏ w, (f w) ^ (mult w) := by
-      simp_rw [mult, pow_ite, pow_one, Finset.prod_ite, ofReal_coe_nnreal, not_isReal_iff_isComplex,
-        coe_mul, coe_finset_prod, ENNReal.coe_pow, mul_assoc]
-      congr 3
-      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞))).symm
-        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
-      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞) ^ 2)).symm
-        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
-
-end convexBodyLT'
-
-section convexBodySum
-
-open ENNReal MeasureTheory Fintype
-
-open scoped Real Classical BigOperators NNReal
-
-variable [NumberField K] (B : ℝ)
-variable {K}
-
-/-- The function that sends `x : ({w // IsReal w} → ℝ) × ({w // IsComplex w} → ℂ)` to
-  `∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖`. It defines a norm and it used to define `convexBodySum`. -/
-noncomputable abbrev convexBodySumFun (x : E K) : ℝ := ∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖
-
-theorem convexBodySumFun_nonneg (x : E K) :
-    0 ≤ convexBodySumFun x := by
-  refine add_nonneg ?_ ?_
-  · exact Finset.sum_nonneg (fun _ _ => norm_nonneg _)
-  · exact mul_nonneg zero_le_two (Finset.sum_nonneg (fun _ _ => norm_nonneg _))
-
-theorem convexBodySumFun_neg (x : E K) :
-    convexBodySumFun (- x) = convexBodySumFun x := by
-  simp_rw [convexBodySumFun, Prod.fst_neg, Prod.snd_neg, Pi.neg_apply, norm_neg]
-
-theorem convexBodySumFun_add_le (x y : E K) :
-    convexBodySumFun (x + y) ≤ convexBodySumFun x + convexBodySumFun y := by
-  simp_rw [convexBodySumFun, Prod.fst_add, Pi.add_apply, Prod.snd_add]
-  refine le_trans (add_le_add
-    (Finset.sum_le_sum (fun w _ => norm_add_le (x.1 w) (y.1 w)))
-    (mul_le_mul_of_nonneg_left
-      (Finset.sum_le_sum (fun w _ => norm_add_le (x.2 w) (y.2 w))) (by norm_num))) ?_
-  simp_rw [Finset.sum_add_distrib, mul_add]
-  exact le_of_eq (by ring)
-
-theorem convexBodySumFun_smul (c : ℝ) (x : E K) :
-    convexBodySumFun (c • x) = |c| * convexBodySumFun x := by
-  simp_rw [convexBodySumFun, Prod.smul_fst, Prod.smul_snd, Pi.smul_apply, smul_eq_mul,
-    Complex.real_smul, norm_mul, Complex.norm_real, ← Finset.mul_sum, Real.norm_eq_abs]
-  ring
-
-theorem convexBodySumFun_eq_zero_iff (x : E K) :
-    convexBodySumFun x = 0 ↔ x = 0 := by
-  refine ⟨fun h => ?_, fun h => ?_⟩
-  · rw [add_eq_zero_iff' (Finset.sum_nonneg fun _ _ => norm_nonneg _) (mul_nonneg zero_le_two
-      (Finset.sum_nonneg fun _ _ => norm_nonneg _)), Finset.mul_sum,
-      Finset.sum_eq_zero_iff_of_nonneg (fun _ _ => mul_nonneg zero_le_two (norm_nonneg _)),
-      Finset.sum_eq_zero_iff_of_nonneg (fun _ _ => norm_nonneg _)] at h
-    ext : 2
-    · exact norm_eq_zero.mp (h.1 _ (Finset.mem_univ _))
-    · exact norm_eq_zero.1 <| eq_zero_of_ne_zero_of_mul_left_eq_zero two_ne_zero <| h.2 _ <|
-        Finset.mem_univ _
-  · simp only [convexBodySumFun, h, Prod.fst_zero, Pi.zero_apply, norm_zero, Finset.sum_const_zero,
-      Prod.snd_zero, mul_zero, add_zero]
-
-theorem norm_le_convexBodySumFun (x : E K) : ‖x‖ ≤ convexBodySumFun x := by
-  refine max_le ?_ ?_
-  · refine (pi_norm_le_iff_of_nonneg (convexBodySumFun_nonneg x)).mpr (fun w => ?_)
-    refine le_add_of_le_of_nonneg ?_ ?_
-    · exact Finset.single_le_sum (fun z _ => norm_nonneg (x.1 z)) (Finset.mem_univ w)
-    · exact mul_nonneg zero_le_two <| Finset.sum_nonneg (fun w _ => norm_nonneg (x.2 w))
-  · refine (pi_norm_le_iff_of_nonneg (convexBodySumFun_nonneg x)).mpr (fun w => ?_)
-    refine le_add_of_nonneg_of_le ?_ ?_
-    · exact Finset.sum_nonneg (fun w _ => norm_nonneg (x.1 w))
-    · rw [Finset.mul_sum]
-      refine le_trans (by linarith [norm_nonneg (x.2 w)] : ‖x.2 w‖ ≤ 2 * ‖x.2 w‖) ?_
-      exact Finset.single_le_sum (fun z _ => mul_nonneg zero_le_two (norm_nonneg (x.2 z)))
-        (Finset.mem_univ w)
-
-variable (K)
-
-theorem convexBodySumFun_continuous :
-    Continuous (convexBodySumFun : (E K) → ℝ) := by
-  refine Continuous.add ?_ ?_
-  · exact continuous_finset_sum Finset.univ
-      (fun i _ => continuous_norm.comp' (continuous_apply i).fst')
-  · refine Continuous.const_smul ?_ (2:ℝ)
-    exact continuous_finset_sum Finset.univ
-      (fun i _ => continuous_norm.comp' (continuous_apply i).snd')
-
-/-- The convex body equal to the set of points `x : E` such that
-  `∑ w real, ‖x w‖ + 2 * ∑ w complex, ‖x w‖ ≤ B`. -/
-abbrev convexBodySum : Set (E K)  := { x | convexBodySumFun x ≤ B }
-
-theorem convexBodySum_volume_eq_zero_of_le_zero {B} (hB : B ≤ 0) :
-    volume (convexBodySum K B) = 0 := by
-  obtain hB | hB := lt_or_eq_of_le hB
-  · suffices convexBodySum K B = ∅ by rw [this, measure_empty]
-    ext x
-    refine ⟨fun hx => ?_, fun h => h.elim⟩
-    rw [Set.mem_setOf] at hx
-    linarith [convexBodySumFun_nonneg x]
-  · suffices convexBodySum K B = { 0 } by rw [this, measure_singleton]
-    ext
-    rw [convexBodySum, Set.mem_setOf_eq, Set.mem_singleton_iff, hB, ← convexBodySumFun_eq_zero_iff]
-    exact (convexBodySumFun_nonneg _).le_iff_eq
-
-theorem convexBodySum_mem {x : K} :
-    mixedEmbedding K x ∈ (convexBodySum K B) ↔
-      ∑ w : InfinitePlace K, (mult w) * w.val x ≤ B := by
-  simp_rw [Set.mem_setOf_eq, mixedEmbedding, RingHom.prod_apply, convexBodySumFun, Pi.ringHom_apply,
-    ← Complex.norm_real, embedding_of_isReal_apply, norm_embedding_eq, mult, Nat.cast_ite, ite_mul,
-    Finset.sum_ite, Finset.filter_congr (fun _ _ => not_isReal_iff_isComplex), Finset.mul_sum,
-    ← Finset.sum_subtype_eq_sum_filter, Finset.subtype_univ, Nat.cast_one, one_mul, Nat.cast_ofNat]
-  rfl
-
-theorem convexBodySum_neg_mem {x : E K} (hx : x ∈ (convexBodySum K B)) :
-    -x ∈ (convexBodySum K B) := by
-  rw [Set.mem_setOf, convexBodySumFun_neg]
-  exact hx
-
-theorem convexBodySum_convex : Convex ℝ (convexBodySum K B) := by
-  refine Convex_subadditive_le (fun _ _ => convexBodySumFun_add_le _ _) (fun c x h => ?_) B
-  convert le_of_eq (convexBodySumFun_smul c x)
-  exact (abs_eq_self.mpr h).symm
-
-theorem convexBodySum_isBounded : Bornology.IsBounded (convexBodySum K B) := by
-  refine Metric.isBounded_iff.mpr ⟨B + B, fun x hx y hy => ?_⟩
-  refine le_trans (norm_sub_le x y) (add_le_add ?_ ?_)
-  exact le_trans (norm_le_convexBodySumFun x) hx
-  exact le_trans (norm_le_convexBodySumFun y) hy
-
-theorem convexBodySum_compact : IsCompact (convexBodySum K B) := by
-  rw [Metric.isCompact_iff_isClosed_bounded]
-  refine ⟨?_, convexBodySum_isBounded K B⟩
-  convert IsClosed.preimage (convexBodySumFun_continuous K) (isClosed_Icc : IsClosed (Set.Icc 0 B))
-  ext
-  simp [convexBodySumFun_nonneg]
-
-/-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
-noncomputable abbrev convexBodySumFactor : ℝ≥0 :=
-  (2 : ℝ≥0) ^ NrRealPlaces K * (NNReal.pi / 2) ^ NrComplexPlaces K / (finrank ℚ K).factorial
-
-theorem convexBodySumFactor_ne_zero : convexBodySumFactor K ≠ 0 := by
-  refine div_ne_zero ?_ <| Nat.cast_ne_zero.mpr (Nat.factorial_ne_zero _)
-  exact mul_ne_zero (pow_ne_zero _ two_ne_zero)
-    (pow_ne_zero _ (div_ne_zero NNReal.pi_ne_zero two_ne_zero))
-
-open MeasureTheory MeasureTheory.Measure Real in
-theorem convexBodySum_volume :
-    volume (convexBodySum K B) = (convexBodySumFactor K) * (.ofReal B) ^ (finrank ℚ K) := by
-  obtain hB | hB := le_or_lt B 0
-  · rw [convexBodySum_volume_eq_zero_of_le_zero K hB, ofReal_eq_zero.mpr hB, zero_pow, mul_zero]
-    exact finrank_pos.ne'
-  · suffices volume (convexBodySum K 1) = (convexBodySumFactor K) by
-      rw [mul_comm]
-      convert addHaar_smul volume B (convexBodySum K 1)
-      · simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hB), Set.preimage_setOf_eq, convexBodySumFun,
-          Prod.smul_fst, Prod.smul_snd, Pi.smul_apply, Complex.real_smul, smul_eq_mul, norm_mul,
-          Complex.ofReal_inv, norm_inv, norm_eq_abs B, Complex.norm_eq_abs B, Complex.abs_ofReal,
-          abs_eq_self.mpr (le_of_lt hB), ← Finset.mul_sum, ← mul_assoc, mul_comm (2:ℝ), mul_assoc,
-          ← mul_add, inv_mul_le_iff hB, mul_one]
-      · rw [abs_pow, ofReal_pow (abs_nonneg _), abs_eq_self.mpr (le_of_lt hB),
-          mixedEmbedding.finrank]
-      · exact this.symm
-    rw [MeasureTheory.measure_le_eq_lt _ ((convexBodySumFun_eq_zero_iff 0).mpr rfl)
-      convexBodySumFun_neg convexBodySumFun_add_le
-      (fun hx => (convexBodySumFun_eq_zero_iff _).mp hx)
-      (fun r x => le_of_eq (convexBodySumFun_smul r x))]
-    rw [measure_lt_one_eq_integral_div_gamma (g := fun x : (E K) => convexBodySumFun x)
-      volume ((convexBodySumFun_eq_zero_iff 0).mpr rfl) convexBodySumFun_neg convexBodySumFun_add_le
-      (fun hx => (convexBodySumFun_eq_zero_iff _).mp hx)
-      (fun r x => le_of_eq (convexBodySumFun_smul r x)) zero_lt_one]
-    simp_rw [mixedEmbedding.finrank, div_one, Gamma_nat_eq_factorial, ofReal_div_of_pos
-      (Nat.cast_pos.mpr (Nat.factorial_pos _)), Real.rpow_one, ofReal_coe_nat]
-    suffices ∫ x : E K, exp (-convexBodySumFun x) =
-        (2:ℝ) ^ NrRealPlaces K * (π / 2) ^ NrComplexPlaces K by
-      rw [this, convexBodySumFactor, ofReal_mul (by positivity), ofReal_pow zero_le_two,
-        ofReal_pow (by positivity), ofReal_div_of_pos zero_lt_two, ofReal_ofNat,
-        ← NNReal.coe_real_pi, ofReal_coe_nnreal, coe_div (Nat.cast_ne_zero.mpr
-        (Nat.factorial_ne_zero _)), coe_mul, coe_pow, coe_pow, coe_ofNat, coe_div two_ne_zero,
-        coe_ofNat, coe_nat]
-    calc
-      _ = (∫ x : {w : InfinitePlace K // IsReal w} → ℝ, ∏ w, exp (- ‖x w‖)) *
-              (∫ x : {w : InfinitePlace K // IsComplex w} → ℂ, ∏ w, exp (- 2 * ‖x w‖)) := by
-        simp_rw [convexBodySumFun, neg_add, ← neg_mul, Finset.mul_sum, ← Finset.sum_neg_distrib,
-          exp_add, exp_sum, ← integral_prod_mul, volume_eq_prod]
-      _ = (∫ x : ℝ, exp (-|x|)) ^ NrRealPlaces K *
-              (∫ x : ℂ, Real.exp (-2 * ‖x‖)) ^ NrComplexPlaces K := by
-        rw [integral_fintype_prod_eq_pow _ (fun x => exp (- ‖x‖)), integral_fintype_prod_eq_pow _
-          (fun x => exp (- 2 * ‖x‖))]
-        simp_rw [norm_eq_abs]
-      _ =  (2 * Gamma (1 / 1 + 1)) ^ NrRealPlaces K *
-              (π * (2:ℝ) ^ (-(2:ℝ) / 1) * Gamma (2 / 1 + 1)) ^ NrComplexPlaces K := by
-        rw [integral_comp_abs (f := fun x => exp (- x)), ← integral_exp_neg_rpow zero_lt_one,
-          ← Complex.integral_exp_neg_mul_rpow le_rfl zero_lt_two]
-        simp_rw [Real.rpow_one]
-      _ = (2:ℝ) ^ NrRealPlaces K * (π / 2) ^ NrComplexPlaces K := by
-        simp_rw [div_one, one_add_one_eq_two, Gamma_add_one two_ne_zero, Gamma_two, mul_one,
-          mul_assoc, ← Real.rpow_add_one two_ne_zero, show (-2:ℝ) + 1 = -1 by norm_num,
-          Real.rpow_neg_one]
-        rfl
-
-end convexBodySum
-
-section minkowski
-
-open scoped Classical
-open MeasureTheory MeasureTheory.Measure FiniteDimensional Zspan Real Submodule
-
-open scoped ENNReal NNReal nonZeroDivisors IntermediateField
-
-variable [NumberField K] (I : (FractionalIdeal (𝓞 K)⁰ K)ˣ)
-
-/-- The bound that appears in **Minkowski Convex Body theorem**, see
-`MeasureTheory.exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure`. See
-`NumberField.mixedEmbedding.volume_fundamentalDomain_idealLatticeBasis_eq` and
-`NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis` for the computation of
-`volume (fundamentalDomain (idealLatticeBasis K))`. -/
-noncomputable def minkowskiBound : ℝ≥0∞ :=
-  volume (fundamentalDomain (fractionalIdealLatticeBasis K I)) * (2 : ℝ≥0∞) ^ (finrank ℝ (E K))
-
-theorem volume_fundamentalDomain_fractionalIdealLatticeBasis :
-    volume (fundamentalDomain (fractionalIdealLatticeBasis K I)) =
-      .ofReal (FractionalIdeal.absNorm I.1) *  volume (fundamentalDomain (latticeBasis K)) := by
-  let e : (Module.Free.ChooseBasisIndex ℤ I) ≃ (Module.Free.ChooseBasisIndex ℤ (𝓞 K)) := by
-    refine Fintype.equivOfCardEq ?_
-    rw [← finrank_eq_card_chooseBasisIndex, ← finrank_eq_card_chooseBasisIndex,
-      fractionalIdeal_rank]
-  rw [← fundamentalDomain_reindex (fractionalIdealLatticeBasis K I) e,
-    measure_fundamentalDomain ((fractionalIdealLatticeBasis K I).reindex e)]
-  rw [show (fractionalIdealLatticeBasis K I).reindex e = (mixedEmbedding K) ∘
-      (basisOfFractionalIdeal K I) ∘ e.symm by
-    ext1; simp only [Basis.coe_reindex, Function.comp_apply, fractionalIdealLatticeBasis_apply]]
-  rw [mixedEmbedding.det_basisOfFractionalIdeal_eq_norm]
-
-theorem minkowskiBound_lt_top : minkowskiBound K I < ⊤ := by
-  refine ENNReal.mul_lt_top ?_ ?_
-  · exact ne_of_lt (fundamentalDomain_isBounded _).measure_lt_top
-  · exact ne_of_lt (ENNReal.pow_lt_top (lt_top_iff_ne_top.mpr ENNReal.two_ne_top) _)
-
-theorem minkowskiBound_pos : 0 < minkowskiBound K I := by
-  refine zero_lt_iff.mpr (mul_ne_zero ?_ ?_)
-  · exact Zspan.measure_fundamentalDomain_ne_zero _
-  · exact ENNReal.pow_ne_zero two_ne_zero _
-
-variable {f : InfinitePlace K → ℝ≥0} (I : (FractionalIdeal (𝓞 K)⁰ K)ˣ)
-
-/-- Let `I` be a fractional ideal of `K`. Assume that `f : InfinitePlace K → ℝ≥0` is such that
-`minkowskiBound K I < volume (convexBodyLT K f)` where `convexBodyLT K f` is the set of
-points `x` such that `‖x w‖ < f w` for all infinite places `w` (see `convexBodyLT_volume` for
-the computation of this volume), then there exists a nonzero algebraic number `a` in `I` such
-that `w a < f w` for all infinite places `w`. -/
-theorem exists_ne_zero_mem_ideal_lt (h : minkowskiBound K I < volume (convexBodyLT K f)) :
-    ∃ a ∈ (I : FractionalIdeal (𝓞 K)⁰ K), a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
-  have h_fund := Zspan.isAddFundamentalDomain (fractionalIdealLatticeBasis K I) volume
-  have : Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
-    change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)) : Set (E K))
-    infer_instance
-  obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
-    h_fund (convexBodyLT_neg_mem K f) (convexBodyLT_convex K f) h
-  rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
-  obtain ⟨a, ha, rfl⟩ := hx
-  exact ⟨a, ha, by simpa using h_nz, (convexBodyLT_mem K f).mp h_mem⟩
-
-/-- A version of `exists_ne_zero_mem_ideal_lt` where the absolute value of the real part of `a` is
-smaller than `1` at some fixed complex place. This is useful to ensure that `a` is not real. -/
-theorem exists_ne_zero_mem_ideal_lt' (w₀ : {w : InfinitePlace K // IsComplex w})
-    (h : minkowskiBound K I < volume (convexBodyLT' K f w₀)) :
-    ∃ a ∈ (I : FractionalIdeal (𝓞 K)⁰ K), a ≠ 0 ∧ (∀ w : InfinitePlace K, w ≠ w₀ → w a < f w) ∧
-      |(w₀.val.embedding a).re| < 1 ∧ |(w₀.val.embedding a).im| < (f w₀ : ℝ) ^ 2:= by
-  have h_fund := Zspan.isAddFundamentalDomain (fractionalIdealLatticeBasis K I) volume
-  have : Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
-    change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)) : Set (E K))
-    infer_instance
-  obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
-    h_fund (convexBodyLT'_neg_mem K f w₀) (convexBodyLT'_convex K f w₀) h
-  rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
-  obtain ⟨a, ha, rfl⟩ := hx
-  exact ⟨a, ha, by simpa using h_nz, (convexBodyLT'_mem K f w₀).mp h_mem⟩
-
-/-- A version of `exists_ne_zero_mem_ideal_lt` for the ring of integers of `K`. -/
-theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K ↑1 < volume (convexBodyLT K f)) :
-    ∃ a ∈ 𝓞 K, a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
-  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_lt K ↑1 h
-  obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
-  exact ⟨a, ha, h_nz, h_bd⟩
-
-/-- A version of `exists_ne_zero_mem_ideal_lt'` for the ring of integers of `K`. -/
-theorem exists_ne_zero_mem_ringOfIntegers_lt' (w₀ : {w : InfinitePlace K // IsComplex w})
-    (h : minkowskiBound K ↑1 < volume (convexBodyLT' K f w₀)) :
-    ∃ a ∈ 𝓞 K, a ≠ 0 ∧ (∀ w : InfinitePlace K, w ≠ w₀ → w a < f w) ∧
-      |(w₀.val.embedding a).re| < 1 ∧ |(w₀.val.embedding a).im| < (f w₀ : ℝ) ^ 2 := by
-  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_lt' K ↑1 w₀ h
-  obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
-  exact ⟨a, ha, h_nz, h_bd⟩
-
-theorem exists_primitive_element_lt_of_isReal {w₀ : InfinitePlace K} (hw₀ : IsReal w₀) {B : ℝ≥0}
-    (hB : minkowskiBound K ↑1 < convexBodyLTFactor K * B) :
-    ∃ a ∈ 𝓞 K, ℚ⟮(a:K)⟯ = ⊤ ∧ (∀ w : InfinitePlace K, w a < max B 1) := by
-  have : minkowskiBound K ↑1 < volume (convexBodyLT K (fun w ↦ if w = w₀ then B else 1)) := by
-    rw [convexBodyLT_volume, ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)]
-    simp_rw [ite_pow, one_pow]
-    rw [Finset.prod_ite_eq']
-    simp_rw [Finset.not_mem_erase, ite_false, mult, hw₀, ite_true, one_mul, pow_one]
-    exact hB
-  obtain ⟨a, ha, h_nz, h_le⟩ := exists_ne_zero_mem_ringOfIntegers_lt K this
-  refine ⟨a, ha, ?_, fun w ↦ lt_of_lt_of_le (h_le w) ?_⟩
-  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.coe_ne_coe.1 h_nz)
-      (fun w h_ne ↦ by convert (if_neg h_ne) ▸ h_le w) (Or.inl hw₀)
-  · split_ifs <;> simp
-
-theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀ : IsComplex w₀)
-    {B : ℝ≥0} (hB : minkowskiBound K ↑1 < convexBodyLT'Factor K * B) :
-    ∃ a ∈ 𝓞 K, ℚ⟮(a:K)⟯ = ⊤ ∧ (∀ w : InfinitePlace K, w a < Real.sqrt (1 + B ^ 2)) := by
-  have : minkowskiBound K ↑1 <
-      volume (convexBodyLT' K (fun w ↦ if w = w₀ then NNReal.sqrt B else 1) ⟨w₀, hw₀⟩) := by
-    rw [convexBodyLT'_volume, ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)]
-    simp_rw [ite_pow, one_pow]
-    rw [Finset.prod_ite_eq']
-    simp_rw [Finset.not_mem_erase, ite_false, mult, not_isReal_iff_isComplex.mpr hw₀,
-      ite_true, ite_false, one_mul, NNReal.sq_sqrt]
-    exact hB
-  obtain ⟨a, ha, h_nz, h_le, h_le₀⟩ := exists_ne_zero_mem_ringOfIntegers_lt' K ⟨w₀, hw₀⟩ this
-  refine ⟨a, ha, ?_, fun w ↦ ?_⟩
-  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.coe_ne_coe.1 h_nz)
-      (fun w h_ne ↦ by convert if_neg h_ne ▸ h_le w h_ne) (Or.inr h_le₀.1)
-  · by_cases h_eq : w = w₀
-    · rw [if_pos rfl] at h_le₀
-      dsimp only at h_le₀
-      rw [h_eq, ← norm_embedding_eq, Real.lt_sqrt (norm_nonneg _), ← Complex.re_add_im
-        (embedding w₀ a), Complex.norm_eq_abs, Complex.abs_add_mul_I, Real.sq_sqrt (by positivity)]
-      refine add_lt_add ?_ ?_
-      · rw [← sq_abs, sq_lt_one_iff (abs_nonneg _)]
-        exact h_le₀.1
-      · rw [sq_lt_sq, NNReal.abs_eq, ← NNReal.sq_sqrt B]
-        exact h_le₀.2
-    · refine lt_of_lt_of_le (if_neg h_eq ▸ h_le w h_eq) ?_
-      rw [NNReal.coe_one, Real.le_sqrt' zero_lt_one, one_pow]
-      set_option tactic.skipAssignedInstances false in norm_num
-
-theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
-    (h : (minkowskiBound K I) ≤ volume (convexBodySum K B)) :
-    ∃ a ∈ (I : FractionalIdeal (𝓞 K)⁰ K), a ≠ 0 ∧
-      |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
-  have hB : 0 ≤ B := by
-    contrapose! h
-    rw [convexBodySum_volume_eq_zero_of_le_zero K (le_of_lt h)]
-    exact minkowskiBound_pos K I
-  -- Some inequalities that will be useful later on
-  have h1 : 0 < (finrank ℚ K : ℝ)⁻¹ := inv_pos.mpr (Nat.cast_pos.mpr finrank_pos)
-  have h2 : 0 ≤ B / (finrank ℚ K) := div_nonneg hB (Nat.cast_nonneg _)
-  have h_fund := Zspan.isAddFundamentalDomain (fractionalIdealLatticeBasis K I) volume
-  have : Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
-    change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)): Set (E K))
-    infer_instance
-  obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_le_measure
-      h_fund (fun _ ↦ convexBodySum_neg_mem K B) (convexBodySum_convex K B)
-      (convexBodySum_compact K B) h
-  rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
-  obtain ⟨a, ha, rfl⟩ := hx
-  refine ⟨a, ha, by simpa using h_nz, ?_⟩
-  rw [← rpow_nat_cast, ← rpow_le_rpow_iff (by simp only [Rat.cast_abs, abs_nonneg])
-      (rpow_nonneg h2 _) h1, ← rpow_mul h2,  mul_inv_cancel (Nat.cast_ne_zero.mpr
-      (ne_of_gt finrank_pos)), rpow_one, le_div_iff' (Nat.cast_pos.mpr finrank_pos)]
-  refine le_trans ?_ ((convexBodySum_mem K B).mp h_mem)
-  rw [← le_div_iff' (Nat.cast_pos.mpr finrank_pos), ← sum_mult_eq, Nat.cast_sum]
-  refine le_trans ?_ (geom_mean_le_arith_mean Finset.univ _ _ (fun _ _ => Nat.cast_nonneg _)
-    ?_ (fun _ _ => AbsoluteValue.nonneg _ _))
-  · simp_rw [← prod_eq_abs_norm, rpow_nat_cast]
-    exact le_of_eq rfl
-  · rw [← Nat.cast_sum, sum_mult_eq, Nat.cast_pos]
-    exact finrank_pos
-
-theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
-    (h : (minkowskiBound K ↑1) ≤ volume (convexBodySum K B)) :
-    ∃ a ∈ 𝓞 K, a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
-  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_of_norm_le K ↑1 h
-  obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
-  exact ⟨a, ha, h_nz, h_bd⟩
-
-end minkowski
-
 end NumberField.mixedEmbedding
chore: Delete Init.Data.Subtype.Basic (#11887)

The few useful lemmas can go to Data.Subtype.Basic and the other ones can be deleted.

Diff
@@ -643,12 +643,12 @@ theorem convexBodyLT'_mem {x : K} :
   · by_cases hw : IsReal w
     · exact norm_embedding_eq w _ ▸ h₁ w hw
     · specialize h₂ w (not_isReal_iff_isComplex.mp hw)
-      rwa [if_neg (by exact Subtype.ne_of_val_ne h_ne)] at h₂
+      rwa [if_neg (by exact Subtype.coe_ne_coe.1 h_ne)] at h₂
   · simpa [if_true] using h₂ w₀.val w₀.prop
   · exact h₁ w (ne_of_isReal_isComplex hw w₀.prop)
   · by_cases h_ne : w = w₀
     · simpa [h_ne]
-    · rw [if_neg (by exact Subtype.ne_of_val_ne h_ne)]
+    · rw [if_neg (by exact Subtype.coe_ne_coe.1 h_ne)]
       exact h₁ w h_ne
 
 theorem convexBodyLT'_neg_mem (x : E K) (hx : x ∈ convexBodyLT' K f w₀) :
@@ -1029,7 +1029,7 @@ theorem exists_primitive_element_lt_of_isReal {w₀ : InfinitePlace K} (hw₀ :
     exact hB
   obtain ⟨a, ha, h_nz, h_le⟩ := exists_ne_zero_mem_ringOfIntegers_lt K this
   refine ⟨a, ha, ?_, fun w ↦ lt_of_lt_of_le (h_le w) ?_⟩
-  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.ne_of_val_ne h_nz)
+  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.coe_ne_coe.1 h_nz)
       (fun w h_ne ↦ by convert (if_neg h_ne) ▸ h_le w) (Or.inl hw₀)
   · split_ifs <;> simp
 
@@ -1046,7 +1046,7 @@ theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀
     exact hB
   obtain ⟨a, ha, h_nz, h_le, h_le₀⟩ := exists_ne_zero_mem_ringOfIntegers_lt' K ⟨w₀, hw₀⟩ this
   refine ⟨a, ha, ?_, fun w ↦ ?_⟩
-  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.ne_of_val_ne h_nz)
+  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.coe_ne_coe.1 h_nz)
       (fun w h_ne ↦ by convert if_neg h_ne ▸ h_le w h_ne) (Or.inr h_le₀.1)
   · by_cases h_eq : w = w₀
     · rw [if_pos rfl] at h_le₀
chore(*): remove empty lines between variable statements (#11418)

Empty lines were removed by executing the following Python script twice

import os
import re


# Loop through each file in the repository
for dir_path, dirs, files in os.walk('.'):
  for filename in files:
    if filename.endswith('.lean'):
      file_path = os.path.join(dir_path, filename)

      # Open the file and read its contents
      with open(file_path, 'r') as file:
        content = file.read()

      # Use a regular expression to replace sequences of "variable" lines separated by empty lines
      # with sequences without empty lines
      modified_content = re.sub(r'(variable.*\n)\n(variable(?! .* in))', r'\1\2', content)

      # Write the modified content back to the file
      with open(file_path, 'w') as file:
        file.write(modified_content)
Diff
@@ -740,7 +740,6 @@ open ENNReal MeasureTheory Fintype
 open scoped Real Classical BigOperators NNReal
 
 variable [NumberField K] (B : ℝ)
-
 variable {K}
 
 /-- The function that sends `x : ({w // IsReal w} → ℝ) × ({w // IsComplex w} → ℂ)` to
chore: Define the class IsZlattice (#11356)

See the Zulip thread

Diff
@@ -1078,10 +1078,6 @@ theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
   have : Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
     change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)): Set (E K))
     infer_instance
-  have : DiscreteTopology
-      (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
-    change DiscreteTopology (span ℤ (Set.range (fractionalIdealLatticeBasis K I)): Set (E K))
-    infer_instance
   obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_le_measure
       h_fund (fun _ ↦ convexBodySum_neg_mem K B) (convexBodySum_convex K B)
       (convexBodySum_compact K B) h
chore: tidy various files (#11135)
Diff
@@ -560,7 +560,7 @@ instance : NoAtoms (volume : Measure (E K)) := by
 
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLT`. -/
 noncomputable abbrev convexBodyLTFactor : ℝ≥0 :=
-  (2:ℝ≥0) ^ NrRealPlaces K * NNReal.pi ^ NrComplexPlaces K
+  (2 : ℝ≥0) ^ NrRealPlaces K * NNReal.pi ^ NrComplexPlaces K
 
 theorem convexBodyLTFactor_ne_zero : convexBodyLTFactor K ≠ 0 :=
   mul_ne_zero (pow_ne_zero _ two_ne_zero) (pow_ne_zero _ pi_ne_zero)
@@ -633,7 +633,7 @@ abbrev convexBodyLT' : Set (E K) :=
     if w = w₀ then {x | |x.re| < 1 ∧ |x.im| < (f w : ℝ) ^ 2} else ball 0 (f w)))
 
 theorem convexBodyLT'_mem {x : K} :
-    mixedEmbedding K x ∈ (convexBodyLT' K f w₀) ↔
+    mixedEmbedding K x ∈ convexBodyLT' K f w₀ ↔
       (∀ w : InfinitePlace K, w ≠ w₀ → w x < f w) ∧
       |(w₀.val.embedding x).re| < 1 ∧ |(w₀.val.embedding x).im| < (f w₀: ℝ) ^ 2 := by
   simp_rw [mixedEmbedding, RingHom.prod_apply, Set.mem_prod, Set.mem_pi, Set.mem_univ,
@@ -651,8 +651,8 @@ theorem convexBodyLT'_mem {x : K} :
     · rw [if_neg (by exact Subtype.ne_of_val_ne h_ne)]
       exact h₁ w h_ne
 
-theorem convexBodyLT'_neg_mem (x : E K) (hx : x ∈ (convexBodyLT' K f w₀)) :
-    -x ∈ (convexBodyLT' K f w₀) := by
+theorem convexBodyLT'_neg_mem (x : E K) (hx : x ∈ convexBodyLT' K f w₀) :
+    -x ∈ convexBodyLT' K f w₀ := by
   simp [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
     mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
     Prod.snd_neg, Complex.norm_eq_abs] at hx ⊢
@@ -675,7 +675,7 @@ variable [NumberField K]
 
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLT'`. -/
 noncomputable abbrev convexBodyLT'Factor : ℝ≥0 :=
-  (2:ℝ≥0) ^ (NrRealPlaces K + 2) * NNReal.pi ^ (NrComplexPlaces K - 1)
+  (2 : ℝ≥0) ^ (NrRealPlaces K + 2) * NNReal.pi ^ (NrComplexPlaces K - 1)
 
 theorem convexBodyLT'Factor_ne_zero : convexBodyLT'Factor K ≠ 0 :=
   mul_ne_zero (pow_ne_zero _ two_ne_zero) (pow_ne_zero _ pi_ne_zero)
@@ -685,7 +685,7 @@ theorem one_le_convexBodyLT'Factor : 1 ≤ convexBodyLT'Factor K :=
     (one_le_pow_of_one_le (le_trans one_le_two Real.two_le_pi) _)
 
 theorem convexBodyLT'_volume :
-    volume (convexBodyLT' K f w₀) = (convexBodyLT'Factor K) * ∏ w, (f w) ^ (mult w) := by
+    volume (convexBodyLT' K f w₀) = convexBodyLT'Factor K * ∏ w, (f w) ^ (mult w) := by
   have vol_box : ∀ B : ℝ≥0, volume {x : ℂ | |x.re| < 1 ∧ |x.im| < B^2} = 4*B^2 := by
     intro B
     rw [← (Complex.volume_preserving_equiv_real_prod.symm).measure_preimage]
@@ -709,20 +709,20 @@ theorem convexBodyLT'_volume :
       · refine Finset.prod_congr rfl (fun w' hw' ↦ ?_)
         rw [if_neg (Finset.ne_of_mem_erase hw'), Complex.volume_ball]
       · simpa only [ite_true] using vol_box (f w₀)
-    _ = ((2:ℝ≥0) ^ NrRealPlaces K *
+    _ = ((2 : ℝ≥0) ^ NrRealPlaces K *
           (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
             ((∏ x in Finset.univ.erase  w₀, ENNReal.ofReal (f x.val) ^ 2) *
               ↑pi ^ (NrComplexPlaces K - 1) * (4 * (f w₀) ^ 2)) := by
       simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
         Finset.card_erase_of_mem (Finset.mem_univ _), Finset.card_univ, ofReal_ofNat,
         ofReal_coe_nnreal, coe_ofNat]
-    _ = (convexBodyLT'Factor K) * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))
+    _ = convexBodyLT'Factor K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))
         * (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) := by
-      rw [show (4:ℝ≥0∞) = (2:ℝ≥0) ^ 2 by norm_num, convexBodyLT'Factor, pow_add,
+      rw [show (4 : ℝ≥0∞) = (2 : ℝ≥0) ^ 2 by norm_num, convexBodyLT'Factor, pow_add,
         ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀), ofReal_coe_nnreal]
       simp_rw [coe_mul, ENNReal.coe_pow]
       ring
-    _ = (convexBodyLT'Factor K) * ∏ w, (f w) ^ (mult w) := by
+    _ = convexBodyLT'Factor K * ∏ w, (f w) ^ (mult w) := by
       simp_rw [mult, pow_ite, pow_one, Finset.prod_ite, ofReal_coe_nnreal, not_isReal_iff_isComplex,
         coe_mul, coe_finset_prod, ENNReal.coe_pow, mul_assoc]
       congr 3
@@ -863,7 +863,7 @@ theorem convexBodySum_compact : IsCompact (convexBodySum K B) := by
 
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
 noncomputable abbrev convexBodySumFactor : ℝ≥0 :=
-  (2:ℝ≥0) ^ NrRealPlaces K * (NNReal.pi / 2) ^ NrComplexPlaces K / (finrank ℚ K).factorial
+  (2 : ℝ≥0) ^ NrRealPlaces K * (NNReal.pi / 2) ^ NrComplexPlaces K / (finrank ℚ K).factorial
 
 theorem convexBodySumFactor_ne_zero : convexBodySumFactor K ≠ 0 := by
   refine div_ne_zero ?_ <| Nat.cast_ne_zero.mpr (Nat.factorial_ne_zero _)
@@ -1038,7 +1038,7 @@ theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀
     {B : ℝ≥0} (hB : minkowskiBound K ↑1 < convexBodyLT'Factor K * B) :
     ∃ a ∈ 𝓞 K, ℚ⟮(a:K)⟯ = ⊤ ∧ (∀ w : InfinitePlace K, w a < Real.sqrt (1 + B ^ 2)) := by
   have : minkowskiBound K ↑1 <
-      volume (convexBodyLT' K (fun w ↦ if w = w₀ then (NNReal.sqrt B) else 1) ⟨w₀, hw₀⟩) := by
+      volume (convexBodyLT' K (fun w ↦ if w = w₀ then NNReal.sqrt B else 1) ⟨w₀, hw₀⟩) := by
     rw [convexBodyLT'_volume, ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)]
     simp_rw [ite_pow, one_pow]
     rw [Finset.prod_ite_eq']
chore: scope open Classical (#11199)

We remove all but one open Classicals, instead preferring to use open scoped Classical. The only real side-effect this led to is moving a couple declarations to use Exists.choose instead of Classical.choose.

The first few commits are explicitly labelled regex replaces for ease of review.

Diff
@@ -249,7 +249,8 @@ end commMap
 
 noncomputable section stdBasis
 
-open Classical Complex MeasureTheory MeasureTheory.Measure Zspan Matrix BigOperators
+open scoped Classical
+open Complex MeasureTheory MeasureTheory.Measure Zspan Matrix BigOperators
   ComplexConjugate
 
 variable [NumberField K]
@@ -618,7 +619,7 @@ section convexBodyLT'
 
 open  Metric ENNReal NNReal
 
-open Classical
+open scoped Classical
 
 variable (f : InfinitePlace K → ℝ≥0) (w₀ : {w : InfinitePlace K // IsComplex w})
 
@@ -928,7 +929,8 @@ end convexBodySum
 
 section minkowski
 
-open MeasureTheory MeasureTheory.Measure Classical FiniteDimensional Zspan Real Submodule
+open scoped Classical
+open MeasureTheory MeasureTheory.Measure FiniteDimensional Zspan Real Submodule
 
 open scoped ENNReal NNReal nonZeroDivisors IntermediateField
 
chore: move Mathlib to v4.7.0-rc1 (#11162)

This is a very large PR, but it has been reviewed piecemeal already in PRs to the bump/v4.7.0 branch as we update to intermediate nightlies.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: damiano <adomani@gmail.com>

Diff
@@ -1059,7 +1059,7 @@ theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀
         exact h_le₀.2
     · refine lt_of_lt_of_le (if_neg h_eq ▸ h_le w h_eq) ?_
       rw [NNReal.coe_one, Real.le_sqrt' zero_lt_one, one_pow]
-      norm_num
+      set_option tactic.skipAssignedInstances false in norm_num
 
 theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
     (h : (minkowskiBound K I) ≤ volume (convexBodySum K B)) :
chore: more backporting of simp changes from #10995 (#11001)

Co-authored-by: Patrick Massot <patrickmassot@free.fr> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -536,7 +536,7 @@ theorem convexBodyLT_neg_mem (x : E K) (hx : x ∈ (convexBodyLT K f)) :
     -x ∈ (convexBodyLT K f) := by
   simp only [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
     mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
-    Prod.snd_neg, Complex.norm_eq_abs, hx] at hx ⊢
+    Prod.snd_neg, Complex.norm_eq_abs] at hx ⊢
   exact hx
 
 theorem convexBodyLT_convex : Convex ℝ (convexBodyLT K f) :=
@@ -654,7 +654,7 @@ theorem convexBodyLT'_neg_mem (x : E K) (hx : x ∈ (convexBodyLT' K f w₀)) :
     -x ∈ (convexBodyLT' K f w₀) := by
   simp [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
     mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
-    Prod.snd_neg, Complex.norm_eq_abs, hx] at hx ⊢
+    Prod.snd_neg, Complex.norm_eq_abs] at hx ⊢
   convert hx using 3
   split_ifs <;> simp
 
feat: Proof of Hermite theorem on number fields of bounded discriminant (#10030)

Let N be an integer. Then there are only finitely many number fields (in some fixed extension of ) of discriminant bounded in absolute value by N.

Diff
@@ -532,7 +532,7 @@ theorem convexBodyLT_mem {x : K} :
     embedding_of_isReal_apply, Subtype.forall, ← ball_or_left, ← not_isReal_iff_isComplex, em,
     forall_true_left, norm_embedding_eq]
 
-theorem convexBodyLT_symmetric (x : E K) (hx : x ∈ (convexBodyLT K f)) :
+theorem convexBodyLT_neg_mem (x : E K) (hx : x ∈ (convexBodyLT K f)) :
     -x ∈ (convexBodyLT K f) := by
   simp only [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
     mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
@@ -564,6 +564,10 @@ noncomputable abbrev convexBodyLTFactor : ℝ≥0 :=
 theorem convexBodyLTFactor_ne_zero : convexBodyLTFactor K ≠ 0 :=
   mul_ne_zero (pow_ne_zero _ two_ne_zero) (pow_ne_zero _ pi_ne_zero)
 
+theorem one_le_convexBodyLTFactor : 1 ≤ convexBodyLTFactor K :=
+  one_le_mul₀ (one_le_pow_of_one_le one_le_two _)
+    (one_le_pow_of_one_le (le_trans one_le_two Real.two_le_pi) _)
+
 /-- The volume of `(ConvexBodyLt K f)` where `convexBodyLT K f` is the set of points `x`
 such that `‖x w‖ < f w` for all infinite places `w`. -/
 theorem convexBodyLT_volume :
@@ -610,6 +614,124 @@ theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁
 
 end convexBodyLT
 
+section convexBodyLT'
+
+open  Metric ENNReal NNReal
+
+open Classical
+
+variable (f : InfinitePlace K → ℝ≥0) (w₀ : {w : InfinitePlace K // IsComplex w})
+
+/-- A version of `convexBodyLT` with an additional condition at a fixed complex place. This is
+needed to ensure the element constructed is not real, see for example
+`exists_primitive_element_lt_of_isComplex`.
+-/
+abbrev convexBodyLT' : Set (E K) :=
+  (Set.univ.pi (fun w : { w : InfinitePlace K // IsReal w } ↦ ball 0 (f w))) ×ˢ
+  (Set.univ.pi (fun w : { w : InfinitePlace K // IsComplex w } ↦
+    if w = w₀ then {x | |x.re| < 1 ∧ |x.im| < (f w : ℝ) ^ 2} else ball 0 (f w)))
+
+theorem convexBodyLT'_mem {x : K} :
+    mixedEmbedding K x ∈ (convexBodyLT' K f w₀) ↔
+      (∀ w : InfinitePlace K, w ≠ w₀ → w x < f w) ∧
+      |(w₀.val.embedding x).re| < 1 ∧ |(w₀.val.embedding x).im| < (f w₀: ℝ) ^ 2 := by
+  simp_rw [mixedEmbedding, RingHom.prod_apply, Set.mem_prod, Set.mem_pi, Set.mem_univ,
+    forall_true_left, Pi.ringHom_apply, apply_ite, mem_ball_zero_iff, ← Complex.norm_real,
+    embedding_of_isReal_apply, norm_embedding_eq, Subtype.forall, Set.mem_setOf_eq]
+  refine ⟨fun ⟨h₁, h₂⟩ ↦ ⟨fun w h_ne ↦ ?_, ?_⟩, fun ⟨h₁, h₂⟩ ↦ ⟨fun w hw ↦ ?_, fun w hw ↦ ?_⟩⟩
+  · by_cases hw : IsReal w
+    · exact norm_embedding_eq w _ ▸ h₁ w hw
+    · specialize h₂ w (not_isReal_iff_isComplex.mp hw)
+      rwa [if_neg (by exact Subtype.ne_of_val_ne h_ne)] at h₂
+  · simpa [if_true] using h₂ w₀.val w₀.prop
+  · exact h₁ w (ne_of_isReal_isComplex hw w₀.prop)
+  · by_cases h_ne : w = w₀
+    · simpa [h_ne]
+    · rw [if_neg (by exact Subtype.ne_of_val_ne h_ne)]
+      exact h₁ w h_ne
+
+theorem convexBodyLT'_neg_mem (x : E K) (hx : x ∈ (convexBodyLT' K f w₀)) :
+    -x ∈ (convexBodyLT' K f w₀) := by
+  simp [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
+    mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
+    Prod.snd_neg, Complex.norm_eq_abs, hx] at hx ⊢
+  convert hx using 3
+  split_ifs <;> simp
+
+theorem convexBodyLT'_convex : Convex ℝ (convexBodyLT' K f w₀) := by
+  refine Convex.prod (convex_pi (fun _ _ => convex_ball _ _)) (convex_pi (fun _ _ => ?_))
+  split_ifs
+  · simp_rw [abs_lt]
+    refine Convex.inter ((convex_halfspace_re_gt _).inter  (convex_halfspace_re_lt _))
+      ((convex_halfspace_im_gt _).inter  (convex_halfspace_im_lt _))
+  · exact convex_ball _ _
+
+open MeasureTheory MeasureTheory.Measure
+
+open scoped Classical BigOperators
+
+variable [NumberField K]
+
+/-- The fudge factor that appears in the formula for the volume of `convexBodyLT'`. -/
+noncomputable abbrev convexBodyLT'Factor : ℝ≥0 :=
+  (2:ℝ≥0) ^ (NrRealPlaces K + 2) * NNReal.pi ^ (NrComplexPlaces K - 1)
+
+theorem convexBodyLT'Factor_ne_zero : convexBodyLT'Factor K ≠ 0 :=
+  mul_ne_zero (pow_ne_zero _ two_ne_zero) (pow_ne_zero _ pi_ne_zero)
+
+theorem one_le_convexBodyLT'Factor : 1 ≤ convexBodyLT'Factor K :=
+  one_le_mul₀ (one_le_pow_of_one_le one_le_two _)
+    (one_le_pow_of_one_le (le_trans one_le_two Real.two_le_pi) _)
+
+theorem convexBodyLT'_volume :
+    volume (convexBodyLT' K f w₀) = (convexBodyLT'Factor K) * ∏ w, (f w) ^ (mult w) := by
+  have vol_box : ∀ B : ℝ≥0, volume {x : ℂ | |x.re| < 1 ∧ |x.im| < B^2} = 4*B^2 := by
+    intro B
+    rw [← (Complex.volume_preserving_equiv_real_prod.symm).measure_preimage]
+    simp_rw [Set.preimage_setOf_eq, Complex.measurableEquivRealProd_symm_apply]
+    rw [show {a : ℝ × ℝ | |a.1| < 1 ∧ |a.2| < B ^ 2} =
+      Set.Ioo (-1:ℝ) (1:ℝ) ×ˢ Set.Ioo (- (B:ℝ) ^ 2) ((B:ℝ) ^ 2) by
+        ext; simp_rw [Set.mem_setOf_eq, Set.mem_prod, Set.mem_Ioo, abs_lt]]
+    simp_rw [volume_eq_prod, prod_prod, Real.volume_Ioo, sub_neg_eq_add, one_add_one_eq_two,
+      ← two_mul, ofReal_mul zero_le_two, ofReal_pow (coe_nonneg B), ofReal_ofNat,
+      ofReal_coe_nnreal, ← mul_assoc, show (2:ℝ≥0∞) * 2 = 4 by norm_num]
+    refine MeasurableSet.inter ?_ ?_
+    · exact measurableSet_lt (measurable_norm.comp Complex.measurable_re) measurable_const
+    · exact measurableSet_lt (measurable_norm.comp Complex.measurable_im) measurable_const
+  calc
+    _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
+          ((∏ x in Finset.univ.erase  w₀, ENNReal.ofReal (f x.val) ^ 2 * pi) *
+          (4 * (f w₀) ^ 2)) := by
+      simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball]
+      rw [← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)]
+      congr 2
+      · refine Finset.prod_congr rfl (fun w' hw' ↦ ?_)
+        rw [if_neg (Finset.ne_of_mem_erase hw'), Complex.volume_ball]
+      · simpa only [ite_true] using vol_box (f w₀)
+    _ = ((2:ℝ≥0) ^ NrRealPlaces K *
+          (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
+            ((∏ x in Finset.univ.erase  w₀, ENNReal.ofReal (f x.val) ^ 2) *
+              ↑pi ^ (NrComplexPlaces K - 1) * (4 * (f w₀) ^ 2)) := by
+      simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
+        Finset.card_erase_of_mem (Finset.mem_univ _), Finset.card_univ, ofReal_ofNat,
+        ofReal_coe_nnreal, coe_ofNat]
+    _ = (convexBodyLT'Factor K) * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))
+        * (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) := by
+      rw [show (4:ℝ≥0∞) = (2:ℝ≥0) ^ 2 by norm_num, convexBodyLT'Factor, pow_add,
+        ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀), ofReal_coe_nnreal]
+      simp_rw [coe_mul, ENNReal.coe_pow]
+      ring
+    _ = (convexBodyLT'Factor K) * ∏ w, (f w) ^ (mult w) := by
+      simp_rw [mult, pow_ite, pow_one, Finset.prod_ite, ofReal_coe_nnreal, not_isReal_iff_isComplex,
+        coe_mul, coe_finset_prod, ENNReal.coe_pow, mul_assoc]
+      congr 3
+      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞))).symm
+        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
+      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞) ^ 2)).symm
+        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
+
+end convexBodyLT'
+
 section convexBodySum
 
 open ENNReal MeasureTheory Fintype
@@ -715,7 +837,7 @@ theorem convexBodySum_mem {x : K} :
     ← Finset.sum_subtype_eq_sum_filter, Finset.subtype_univ, Nat.cast_one, one_mul, Nat.cast_ofNat]
   rfl
 
-theorem convexBodySum_symmetric {x : E K} (hx : x ∈ (convexBodySum K B)) :
+theorem convexBodySum_neg_mem {x : E K} (hx : x ∈ (convexBodySum K B)) :
     -x ∈ (convexBodySum K B) := by
   rw [Set.mem_setOf, convexBodySumFun_neg]
   exact hx
@@ -808,7 +930,7 @@ section minkowski
 
 open MeasureTheory MeasureTheory.Measure Classical FiniteDimensional Zspan Real Submodule
 
-open scoped ENNReal NNReal nonZeroDivisors
+open scoped ENNReal NNReal nonZeroDivisors IntermediateField
 
 variable [NumberField K] (I : (FractionalIdeal (𝓞 K)⁰ K)ˣ)
 
@@ -858,19 +980,86 @@ theorem exists_ne_zero_mem_ideal_lt (h : minkowskiBound K I < volume (convexBody
     change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)) : Set (E K))
     infer_instance
   obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
-    h_fund (convexBodyLT_symmetric K f) (convexBodyLT_convex K f) h
+    h_fund (convexBodyLT_neg_mem K f) (convexBodyLT_convex K f) h
   rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
   exact ⟨a, ha, by simpa using h_nz, (convexBodyLT_mem K f).mp h_mem⟩
 
-/- TODO: Remove!. Necessary to prevent a timeout that ends at here. #10131 -/
-attribute [-instance] FractionalIdeal.commSemiring in
+/-- A version of `exists_ne_zero_mem_ideal_lt` where the absolute value of the real part of `a` is
+smaller than `1` at some fixed complex place. This is useful to ensure that `a` is not real. -/
+theorem exists_ne_zero_mem_ideal_lt' (w₀ : {w : InfinitePlace K // IsComplex w})
+    (h : minkowskiBound K I < volume (convexBodyLT' K f w₀)) :
+    ∃ a ∈ (I : FractionalIdeal (𝓞 K)⁰ K), a ≠ 0 ∧ (∀ w : InfinitePlace K, w ≠ w₀ → w a < f w) ∧
+      |(w₀.val.embedding a).re| < 1 ∧ |(w₀.val.embedding a).im| < (f w₀ : ℝ) ^ 2:= by
+  have h_fund := Zspan.isAddFundamentalDomain (fractionalIdealLatticeBasis K I) volume
+  have : Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
+    change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)) : Set (E K))
+    infer_instance
+  obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
+    h_fund (convexBodyLT'_neg_mem K f w₀) (convexBodyLT'_convex K f w₀) h
+  rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
+  obtain ⟨a, ha, rfl⟩ := hx
+  exact ⟨a, ha, by simpa using h_nz, (convexBodyLT'_mem K f w₀).mp h_mem⟩
+
 /-- A version of `exists_ne_zero_mem_ideal_lt` for the ring of integers of `K`. -/
-theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K 1 < volume (convexBodyLT K f)) :
+theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K ↑1 < volume (convexBodyLT K f)) :
     ∃ a ∈ 𝓞 K, a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
-  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_lt K 1 h
+  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_lt K ↑1 h
   obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
-  exact ⟨a, ha, h_nz, fun w ↦ h_bd w⟩
+  exact ⟨a, ha, h_nz, h_bd⟩
+
+/-- A version of `exists_ne_zero_mem_ideal_lt'` for the ring of integers of `K`. -/
+theorem exists_ne_zero_mem_ringOfIntegers_lt' (w₀ : {w : InfinitePlace K // IsComplex w})
+    (h : minkowskiBound K ↑1 < volume (convexBodyLT' K f w₀)) :
+    ∃ a ∈ 𝓞 K, a ≠ 0 ∧ (∀ w : InfinitePlace K, w ≠ w₀ → w a < f w) ∧
+      |(w₀.val.embedding a).re| < 1 ∧ |(w₀.val.embedding a).im| < (f w₀ : ℝ) ^ 2 := by
+  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_lt' K ↑1 w₀ h
+  obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
+  exact ⟨a, ha, h_nz, h_bd⟩
+
+theorem exists_primitive_element_lt_of_isReal {w₀ : InfinitePlace K} (hw₀ : IsReal w₀) {B : ℝ≥0}
+    (hB : minkowskiBound K ↑1 < convexBodyLTFactor K * B) :
+    ∃ a ∈ 𝓞 K, ℚ⟮(a:K)⟯ = ⊤ ∧ (∀ w : InfinitePlace K, w a < max B 1) := by
+  have : minkowskiBound K ↑1 < volume (convexBodyLT K (fun w ↦ if w = w₀ then B else 1)) := by
+    rw [convexBodyLT_volume, ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)]
+    simp_rw [ite_pow, one_pow]
+    rw [Finset.prod_ite_eq']
+    simp_rw [Finset.not_mem_erase, ite_false, mult, hw₀, ite_true, one_mul, pow_one]
+    exact hB
+  obtain ⟨a, ha, h_nz, h_le⟩ := exists_ne_zero_mem_ringOfIntegers_lt K this
+  refine ⟨a, ha, ?_, fun w ↦ lt_of_lt_of_le (h_le w) ?_⟩
+  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.ne_of_val_ne h_nz)
+      (fun w h_ne ↦ by convert (if_neg h_ne) ▸ h_le w) (Or.inl hw₀)
+  · split_ifs <;> simp
+
+theorem exists_primitive_element_lt_of_isComplex {w₀ : InfinitePlace K} (hw₀ : IsComplex w₀)
+    {B : ℝ≥0} (hB : minkowskiBound K ↑1 < convexBodyLT'Factor K * B) :
+    ∃ a ∈ 𝓞 K, ℚ⟮(a:K)⟯ = ⊤ ∧ (∀ w : InfinitePlace K, w a < Real.sqrt (1 + B ^ 2)) := by
+  have : minkowskiBound K ↑1 <
+      volume (convexBodyLT' K (fun w ↦ if w = w₀ then (NNReal.sqrt B) else 1) ⟨w₀, hw₀⟩) := by
+    rw [convexBodyLT'_volume, ← Finset.prod_erase_mul _ _ (Finset.mem_univ w₀)]
+    simp_rw [ite_pow, one_pow]
+    rw [Finset.prod_ite_eq']
+    simp_rw [Finset.not_mem_erase, ite_false, mult, not_isReal_iff_isComplex.mpr hw₀,
+      ite_true, ite_false, one_mul, NNReal.sq_sqrt]
+    exact hB
+  obtain ⟨a, ha, h_nz, h_le, h_le₀⟩ := exists_ne_zero_mem_ringOfIntegers_lt' K ⟨w₀, hw₀⟩ this
+  refine ⟨a, ha, ?_, fun w ↦ ?_⟩
+  · exact is_primitive_element_of_infinitePlace_lt (x := ⟨a, ha⟩) (Subtype.ne_of_val_ne h_nz)
+      (fun w h_ne ↦ by convert if_neg h_ne ▸ h_le w h_ne) (Or.inr h_le₀.1)
+  · by_cases h_eq : w = w₀
+    · rw [if_pos rfl] at h_le₀
+      dsimp only at h_le₀
+      rw [h_eq, ← norm_embedding_eq, Real.lt_sqrt (norm_nonneg _), ← Complex.re_add_im
+        (embedding w₀ a), Complex.norm_eq_abs, Complex.abs_add_mul_I, Real.sq_sqrt (by positivity)]
+      refine add_lt_add ?_ ?_
+      · rw [← sq_abs, sq_lt_one_iff (abs_nonneg _)]
+        exact h_le₀.1
+      · rw [sq_lt_sq, NNReal.abs_eq, ← NNReal.sq_sqrt B]
+        exact h_le₀.2
+    · refine lt_of_lt_of_le (if_neg h_eq ▸ h_le w h_eq) ?_
+      rw [NNReal.coe_one, Real.le_sqrt' zero_lt_one, one_pow]
+      norm_num
 
 theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
     (h : (minkowskiBound K I) ≤ volume (convexBodySum K B)) :
@@ -892,7 +1081,7 @@ theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
     change DiscreteTopology (span ℤ (Set.range (fractionalIdealLatticeBasis K I)): Set (E K))
     infer_instance
   obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_le_measure
-      h_fund (fun _ ↦ convexBodySum_symmetric K B) (convexBodySum_convex K B)
+      h_fund (fun _ ↦ convexBodySum_neg_mem K B) (convexBodySum_convex K B)
       (convexBodySum_compact K B) h
   rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
@@ -909,12 +1098,10 @@ theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
   · rw [← Nat.cast_sum, sum_mult_eq, Nat.cast_pos]
     exact finrank_pos
 
-/- Necessary to prevent a timeout that ends at here. #10131 -/
-attribute [-instance] FractionalIdeal.commSemiring in
 theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
-    (h : (minkowskiBound K 1) ≤ volume (convexBodySum K B)) :
+    (h : (minkowskiBound K ↑1) ≤ volume (convexBodySum K B)) :
     ∃ a ∈ 𝓞 K, a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
-  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_of_norm_le K 1 h
+  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_of_norm_le K ↑1 h
   obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
   exact ⟨a, ha, h_nz, h_bd⟩
 
perf: Use spread notation in ring transfer definitions (#10131)

Make sure that Function.Injective.somethingRing looks like

def ... : SomethingRing β where
  toA := hf.a f ...
  __ := hf.b f ...
  __ := hf.c f ...

if SomethingRing α extends A α, B α, C α.

This should hopefully give a performance boost in applications.

Incidentally, there were a few missing transfer definitions, so I added them as I needed them.

Co-authored-by: Matthew Ballard <matt@mrb.email> Co-authored-by: Johan Commelin <johan@commelin.net>

Diff
@@ -863,6 +863,8 @@ theorem exists_ne_zero_mem_ideal_lt (h : minkowskiBound K I < volume (convexBody
   obtain ⟨a, ha, rfl⟩ := hx
   exact ⟨a, ha, by simpa using h_nz, (convexBodyLT_mem K f).mp h_mem⟩
 
+/- TODO: Remove!. Necessary to prevent a timeout that ends at here. #10131 -/
+attribute [-instance] FractionalIdeal.commSemiring in
 /-- A version of `exists_ne_zero_mem_ideal_lt` for the ring of integers of `K`. -/
 theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K 1 < volume (convexBodyLT K f)) :
     ∃ a ∈ 𝓞 K, a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
@@ -907,6 +909,8 @@ theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
   · rw [← Nat.cast_sum, sum_mult_eq, Nat.cast_pos]
     exact finrank_pos
 
+/- Necessary to prevent a timeout that ends at here. #10131 -/
+attribute [-instance] FractionalIdeal.commSemiring in
 theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
     (h : (minkowskiBound K 1) ≤ volume (convexBodySum K B)) :
     ∃ a ∈ 𝓞 K, a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
chore: Some constants in CanonicalEmbedding should be NNReal and not ENNReal (#10032)

Co-authored-by: Yury G. Kudryashov <urkud@urkud.name>

Diff
@@ -515,7 +515,7 @@ end integerLattice
 
 section convexBodyLT
 
-open Metric ENNReal NNReal
+open Metric NNReal
 
 variable (f : InfinitePlace K → ℝ≥0)
 
@@ -542,7 +542,9 @@ theorem convexBodyLT_symmetric (x : E K) (hx : x ∈ (convexBodyLT K f)) :
 theorem convexBodyLT_convex : Convex ℝ (convexBodyLT K f) :=
   Convex.prod (convex_pi (fun _ _ => convex_ball _ _)) (convex_pi (fun _ _ => convex_ball _ _))
 
-open Classical Fintype MeasureTheory MeasureTheory.Measure BigOperators
+open Fintype MeasureTheory MeasureTheory.Measure ENNReal
+
+open scoped Classical BigOperators
 
 variable [NumberField K]
 
@@ -556,17 +558,11 @@ instance : NoAtoms (volume : Measure (E K)) := by
       (pi_noAtoms ⟨w, not_isReal_iff_isComplex.mp hw⟩)
 
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLT`. -/
-noncomputable abbrev convexBodyLTFactor : ℝ≥0∞ :=
-  (2 : ℝ≥0∞) ^ NrRealPlaces K * (NNReal.pi : ℝ≥0∞) ^ NrComplexPlaces K
-
-theorem convexBodyLTFactor_pos : 0 < (convexBodyLTFactor K) := by
-  refine mul_pos (NeZero.ne _) (ENNReal.pow_ne_zero ?_ _)
-  exact ne_of_gt (coe_pos.mpr Real.pi_pos)
+noncomputable abbrev convexBodyLTFactor : ℝ≥0 :=
+  (2:ℝ≥0) ^ NrRealPlaces K * NNReal.pi ^ NrComplexPlaces K
 
-theorem convexBodyLTFactor_lt_top : (convexBodyLTFactor K) < ⊤ := by
-  refine mul_lt_top ?_ ?_
-  · exact ne_of_lt (pow_lt_top (lt_top_iff_ne_top.mpr two_ne_top) _)
-  · exact ne_of_lt (pow_lt_top coe_lt_top _)
+theorem convexBodyLTFactor_ne_zero : convexBodyLTFactor K ≠ 0 :=
+  mul_ne_zero (pow_ne_zero _ two_ne_zero) (pow_ne_zero _ pi_ne_zero)
 
 /-- The volume of `(ConvexBodyLt K f)` where `convexBodyLT K f` is the set of points `x`
 such that `‖x w‖ < f w` for all infinite places `w`. -/
@@ -576,12 +572,15 @@ theorem convexBodyLT_volume :
     _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
           ∏ x : {w // InfinitePlace.IsComplex w}, ENNReal.ofReal (f x.val) ^ 2 * pi := by
       simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball, Complex.volume_ball]
-    _ = (↑2 ^ NrRealPlaces K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
-          ((∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) * ↑pi ^ NrComplexPlaces K) := by
+    _ = ((2:ℝ≥0) ^ NrRealPlaces K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)))
+          * ((∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) *
+            NNReal.pi ^ NrComplexPlaces K) := by
       simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
-        Finset.card_univ, ofReal_ofNat]
-    _ = (convexBodyLTFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)) *
-        (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by ring
+        Finset.card_univ, ofReal_ofNat, ofReal_coe_nnreal, coe_ofNat]
+    _ = (convexBodyLTFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, .ofReal (f x.val)) *
+        (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by
+      simp_rw [convexBodyLTFactor, coe_mul, ENNReal.coe_pow]
+      ring
     _ = (convexBodyLTFactor K) * ∏ w, (f w) ^ (mult w) := by
       simp_rw [mult, pow_ite, pow_one, Finset.prod_ite, ofReal_coe_nnreal, not_isReal_iff_isComplex,
         coe_mul, coe_finset_prod, ENNReal.coe_pow]
@@ -613,9 +612,9 @@ end convexBodyLT
 
 section convexBodySum
 
-open ENNReal BigOperators Classical MeasureTheory Fintype
+open ENNReal MeasureTheory Fintype
 
-open scoped Real
+open scoped Real Classical BigOperators NNReal
 
 variable [NumberField K] (B : ℝ)
 
@@ -740,21 +739,13 @@ theorem convexBodySum_compact : IsCompact (convexBodySum K B) := by
   simp [convexBodySumFun_nonneg]
 
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
-noncomputable abbrev convexBodySumFactor : ℝ≥0∞ :=
-  (2:ℝ≥0∞) ^ NrRealPlaces K * (NNReal.pi / 2) ^ NrComplexPlaces K / (finrank ℚ K).factorial
+noncomputable abbrev convexBodySumFactor : ℝ≥0 :=
+  (2:ℝ≥0) ^ NrRealPlaces K * (NNReal.pi / 2) ^ NrComplexPlaces K / (finrank ℚ K).factorial
 
 theorem convexBodySumFactor_ne_zero : convexBodySumFactor K ≠ 0 := by
-  dsimp [convexBodySumFactor]
-  refine mul_ne_zero (mul_ne_zero (pow_ne_zero _ two_ne_zero) ?_) ?_
-  · refine ENNReal.pow_ne_zero ?_ _
-    exact ne_of_gt <| div_pos_iff.mpr ⟨coe_ne_zero.mpr NNReal.pi_ne_zero, two_ne_top⟩
-  · exact ENNReal.inv_ne_zero.mpr (nat_ne_top _)
-
-theorem convexBodySumFactor_ne_top : convexBodySumFactor K ≠ ⊤ := by
-  refine mul_ne_top (mul_ne_top (pow_ne_top two_ne_top) ?_) ?_
-  · rw [show (2:ℝ≥0∞) = (2:NNReal) by rfl, ← ENNReal.coe_div two_ne_zero]
-    exact pow_ne_top coe_ne_top
-  · exact inv_ne_top.mpr <| Nat.cast_ne_zero.mpr (Nat.factorial_ne_zero _)
+  refine div_ne_zero ?_ <| Nat.cast_ne_zero.mpr (Nat.factorial_ne_zero _)
+  exact mul_ne_zero (pow_ne_zero _ two_ne_zero)
+    (pow_ne_zero _ (div_ne_zero NNReal.pi_ne_zero two_ne_zero))
 
 open MeasureTheory MeasureTheory.Measure Real in
 theorem convexBodySum_volume :
@@ -787,7 +778,9 @@ theorem convexBodySum_volume :
         (2:ℝ) ^ NrRealPlaces K * (π / 2) ^ NrComplexPlaces K by
       rw [this, convexBodySumFactor, ofReal_mul (by positivity), ofReal_pow zero_le_two,
         ofReal_pow (by positivity), ofReal_div_of_pos zero_lt_two, ofReal_ofNat,
-        ← NNReal.coe_real_pi, ofReal_coe_nnreal]
+        ← NNReal.coe_real_pi, ofReal_coe_nnreal, coe_div (Nat.cast_ne_zero.mpr
+        (Nat.factorial_ne_zero _)), coe_mul, coe_pow, coe_pow, coe_ofNat, coe_div two_ne_zero,
+        coe_ofNat, coe_nat]
     calc
       _ = (∫ x : {w : InfinitePlace K // IsReal w} → ℝ, ∏ w, exp (- ‖x w‖)) *
               (∫ x : {w : InfinitePlace K // IsComplex w} → ℂ, ∏ w, exp (- 2 * ‖x w‖)) := by
feat: Generalize results of CanonicalEmbedding to fractional ideals (#9837)

The main results of NumberTheory.NumberField.CanonicalEmbedding, that is exists_ne_zero_mem_ringOfIntegers_lt and exists_ne_zero_mem_ringOfIntegers_of_norm_le about the existence of algebraic integers satisfying special properties, are generalized from the ring of integers to fractional ideals.

Diff
@@ -7,8 +7,7 @@ import Mathlib.Algebra.Module.Zlattice
 import Mathlib.MeasureTheory.Group.GeometryOfNumbers
 import Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls
 import Mathlib.NumberTheory.NumberField.Embeddings
-import Mathlib.RingTheory.Discriminant
-import Mathlib.Topology.Bornology.Constructions
+import Mathlib.NumberTheory.NumberField.FractionalIdeal
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
 
@@ -390,13 +389,17 @@ theorem stdBasis_repr_eq_matrixToStdBasis_mul (x : (K →+* ℂ) → ℂ)
 
 end stdBasis
 
-section integerLattice
+noncomputable section integerLattice
 
-open Module FiniteDimensional
+variable [NumberField K]
+
+open Module FiniteDimensional Module.Free
+
+open scoped nonZeroDivisors
 
 /-- A `ℝ`-basis of `ℝ^r₁ × ℂ^r₂` that is also a `ℤ`-basis of the image of `𝓞 K`. -/
-noncomputable def latticeBasis [NumberField K] :
-    Basis (Free.ChooseBasisIndex ℤ (𝓞 K)) ℝ (E K) := by
+def latticeBasis :
+    Basis (ChooseBasisIndex ℤ (𝓞 K)) ℝ (E K) := by
   classical
     -- We construct an `ℝ`-linear independent family from the image of
     -- `canonicalEmbedding.lattice_basis` by `commMap`
@@ -413,12 +416,12 @@ noncomputable def latticeBasis [NumberField K] :
       Nat.add_sub_of_le (Fintype.card_subtype_le _)]
 
 @[simp]
-theorem latticeBasis_apply [NumberField K] (i : Free.ChooseBasisIndex ℤ (𝓞 K)) :
+theorem latticeBasis_apply (i : ChooseBasisIndex ℤ (𝓞 K)) :
     latticeBasis K i = (mixedEmbedding K) (integralBasis K i) := by
   simp only [latticeBasis, coe_basisOfLinearIndependentOfCardEqFinrank, Function.comp_apply,
     canonicalEmbedding.latticeBasis_apply, integralBasis_apply, commMap_canonical_eq_mixed]
 
-theorem mem_span_latticeBasis [NumberField K] (x : (E K)) :
+theorem mem_span_latticeBasis (x : (E K)) :
     x ∈ Submodule.span ℤ (Set.range (latticeBasis K)) ↔ x ∈ mixedEmbedding K '' (𝓞 K) := by
   rw [show Set.range (latticeBasis K) =
       (mixedEmbedding K).toIntAlgHom.toLinearMap '' (Set.range (integralBasis K)) by
@@ -428,6 +431,86 @@ theorem mem_span_latticeBasis [NumberField K] (x : (E K)) :
     ext; exact mem_span_integralBasis K]
   rfl
 
+theorem mem_rat_span_latticeBasis (x : K) :
+    mixedEmbedding K x ∈ Submodule.span ℚ (Set.range (latticeBasis K)) := by
+  rw [← Basis.sum_repr (integralBasis K) x, map_sum]
+  simp_rw [map_rat_smul]
+  refine Submodule.sum_smul_mem _ _ (fun i _ ↦ Submodule.subset_span ?_)
+  rw [← latticeBasis_apply]
+  exact Set.mem_range_self i
+
+theorem latticeBasis_repr_apply (x : K) (i : ChooseBasisIndex ℤ (𝓞 K)) :
+    (latticeBasis K).repr (mixedEmbedding K x) i = (integralBasis K).repr x i := by
+  rw [← Basis.restrictScalars_repr_apply ℚ _ ⟨_, mem_rat_span_latticeBasis K x⟩, eq_ratCast,
+    Rat.cast_inj]
+  let f := (mixedEmbedding K).toRatAlgHom.toLinearMap.codRestrict _
+    (fun x ↦ mem_rat_span_latticeBasis K x)
+  suffices ((latticeBasis K).restrictScalars ℚ).repr.toLinearMap ∘ₗ f =
+    (integralBasis K).repr.toLinearMap from DFunLike.congr_fun (LinearMap.congr_fun this x) i
+  refine Basis.ext (integralBasis K) (fun i ↦ ?_)
+  have : f (integralBasis K i) = ((latticeBasis K).restrictScalars ℚ) i := by
+    apply Subtype.val_injective
+    rw [LinearMap.codRestrict_apply, AlgHom.toLinearMap_apply, Basis.restrictScalars_apply,
+      latticeBasis_apply]
+    rfl
+  simp_rw [LinearMap.coe_comp, LinearEquiv.coe_coe, Function.comp_apply, this, Basis.repr_self]
+
+variable (I : (FractionalIdeal (𝓞 K)⁰ K)ˣ)
+
+/-- The generalized index of the lattice generated by `I` in the lattice generated by
+`𝓞 K` is equal to the norm of the ideal `I`. The result is stated in terms of base change
+determinant and is the translation of `NumberField.det_basisOfFractionalIdeal_eq_absNorm` in
+`ℝ^r₁ × ℂ^r₂`. This is useful, in particular, to prove that the family obtained from
+the `ℤ`-basis of `I` is actually an `ℝ`-basis of `ℝ^r₁ × ℂ^r₂`, see
+`fractionalIdealLatticeBasis`. -/
+theorem det_basisOfFractionalIdeal_eq_norm
+    (e : (ChooseBasisIndex ℤ (𝓞 K)) ≃ (ChooseBasisIndex ℤ I)) :
+    |Basis.det (latticeBasis K) ((mixedEmbedding K ∘ (basisOfFractionalIdeal K I) ∘ e))| =
+      FractionalIdeal.absNorm I.1 := by
+  suffices Basis.det (latticeBasis K) ((mixedEmbedding K ∘ (basisOfFractionalIdeal K I) ∘ e)) =
+      (algebraMap ℚ ℝ) ((Basis.det (integralBasis K)) ((basisOfFractionalIdeal K I) ∘ e)) by
+    rw [this, eq_ratCast, ← Rat.cast_abs, ← Equiv.symm_symm e, ← Basis.coe_reindex,
+      det_basisOfFractionalIdeal_eq_absNorm K I e]
+  rw [Basis.det_apply, Basis.det_apply, RingHom.map_det]
+  congr
+  ext i j
+  simp_rw [RingHom.mapMatrix_apply, Matrix.map_apply, Basis.toMatrix_apply, Function.comp_apply]
+  exact latticeBasis_repr_apply K _ i
+
+/-- A `ℝ`-basis of `ℝ^r₁ × ℂ^r₂` that is also a `ℤ`-basis of the image of the fractional
+ideal `I`. -/
+def fractionalIdealLatticeBasis :
+    Basis (ChooseBasisIndex ℤ I) ℝ (E K) := by
+  let e : (ChooseBasisIndex ℤ (𝓞 K)) ≃ (ChooseBasisIndex ℤ I) := by
+    refine Fintype.equivOfCardEq ?_
+    rw [← finrank_eq_card_chooseBasisIndex, ← finrank_eq_card_chooseBasisIndex,
+      fractionalIdeal_rank]
+  refine Basis.reindex ?_ e
+  suffices IsUnit ((latticeBasis K).det ((mixedEmbedding K) ∘ (basisOfFractionalIdeal K I) ∘ e)) by
+    rw [← is_basis_iff_det] at this
+    exact Basis.mk this.1 (by rw [this.2])
+  rw [isUnit_iff_ne_zero, ne_eq, ← abs_eq_zero.not, det_basisOfFractionalIdeal_eq_norm,
+    Rat.cast_eq_zero, FractionalIdeal.absNorm_eq_zero_iff]
+  exact Units.ne_zero I
+
+@[simp]
+theorem fractionalIdealLatticeBasis_apply (i : ChooseBasisIndex ℤ I) :
+    fractionalIdealLatticeBasis K I i = (mixedEmbedding K) (basisOfFractionalIdeal K I i) := by
+  simp only [fractionalIdealLatticeBasis, Basis.coe_reindex, Basis.coe_mk, Function.comp_apply,
+    Equiv.apply_symm_apply]
+
+theorem mem_span_fractionalIdealLatticeBasis (x : (E K)) :
+    x ∈ Submodule.span ℤ (Set.range (fractionalIdealLatticeBasis K I)) ↔
+      x ∈ mixedEmbedding K '' I := by
+  rw [show Set.range (fractionalIdealLatticeBasis K I) =
+        (mixedEmbedding K).toIntAlgHom.toLinearMap '' (Set.range (basisOfFractionalIdeal K I)) by
+      rw [← Set.range_comp]
+      exact congr_arg Set.range (funext (fun i ↦ fractionalIdealLatticeBasis_apply K I i))]
+  rw [← Submodule.map_span, ← SetLike.mem_coe, Submodule.map_coe]
+  rw [show Submodule.span ℤ (Set.range (basisOfFractionalIdeal K I)) = (I : Set K) by
+        ext; erw [mem_span_basisOfFractionalIdeal]]
+  rfl
+
 end integerLattice
 
 section convexBodyLT
@@ -730,86 +813,113 @@ end convexBodySum
 
 section minkowski
 
-open MeasureTheory MeasureTheory.Measure Classical FiniteDimensional Zspan Real
+open MeasureTheory MeasureTheory.Measure Classical FiniteDimensional Zspan Real Submodule
 
-open scoped ENNReal NNReal
+open scoped ENNReal NNReal nonZeroDivisors
 
-variable [NumberField K]
+variable [NumberField K] (I : (FractionalIdeal (𝓞 K)⁰ K)ˣ)
 
 /-- The bound that appears in **Minkowski Convex Body theorem**, see
 `MeasureTheory.exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure`. See
+`NumberField.mixedEmbedding.volume_fundamentalDomain_idealLatticeBasis_eq` and
 `NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis` for the computation of
-`volume (fundamentalDomain (latticeBasis K))`. -/
+`volume (fundamentalDomain (idealLatticeBasis K))`. -/
 noncomputable def minkowskiBound : ℝ≥0∞ :=
-  volume (fundamentalDomain (latticeBasis K)) * (2 : ℝ≥0∞) ^ (finrank ℝ (E K))
-
-theorem minkowskiBound_lt_top : minkowskiBound K < ⊤ := by
+  volume (fundamentalDomain (fractionalIdealLatticeBasis K I)) * (2 : ℝ≥0∞) ^ (finrank ℝ (E K))
+
+theorem volume_fundamentalDomain_fractionalIdealLatticeBasis :
+    volume (fundamentalDomain (fractionalIdealLatticeBasis K I)) =
+      .ofReal (FractionalIdeal.absNorm I.1) *  volume (fundamentalDomain (latticeBasis K)) := by
+  let e : (Module.Free.ChooseBasisIndex ℤ I) ≃ (Module.Free.ChooseBasisIndex ℤ (𝓞 K)) := by
+    refine Fintype.equivOfCardEq ?_
+    rw [← finrank_eq_card_chooseBasisIndex, ← finrank_eq_card_chooseBasisIndex,
+      fractionalIdeal_rank]
+  rw [← fundamentalDomain_reindex (fractionalIdealLatticeBasis K I) e,
+    measure_fundamentalDomain ((fractionalIdealLatticeBasis K I).reindex e)]
+  rw [show (fractionalIdealLatticeBasis K I).reindex e = (mixedEmbedding K) ∘
+      (basisOfFractionalIdeal K I) ∘ e.symm by
+    ext1; simp only [Basis.coe_reindex, Function.comp_apply, fractionalIdealLatticeBasis_apply]]
+  rw [mixedEmbedding.det_basisOfFractionalIdeal_eq_norm]
+
+theorem minkowskiBound_lt_top : minkowskiBound K I < ⊤ := by
   refine ENNReal.mul_lt_top ?_ ?_
-  · exact ne_of_lt (fundamentalDomain_isBounded (latticeBasis K)).measure_lt_top
+  · exact ne_of_lt (fundamentalDomain_isBounded _).measure_lt_top
   · exact ne_of_lt (ENNReal.pow_lt_top (lt_top_iff_ne_top.mpr ENNReal.two_ne_top) _)
 
-theorem minkowskiBound_pos : 0 < minkowskiBound K := by
+theorem minkowskiBound_pos : 0 < minkowskiBound K I := by
   refine zero_lt_iff.mpr (mul_ne_zero ?_ ?_)
-  · exact Zspan.measure_fundamentalDomain_ne_zero (latticeBasis K)
+  · exact Zspan.measure_fundamentalDomain_ne_zero _
   · exact ENNReal.pow_ne_zero two_ne_zero _
 
-variable {f : InfinitePlace K → ℝ≥0}
+variable {f : InfinitePlace K → ℝ≥0} (I : (FractionalIdeal (𝓞 K)⁰ K)ˣ)
 
-/-- Assume that `f : InfinitePlace K → ℝ≥0` is such that
-`minkowskiBound K < volume (convexBodyLT K f)` where `convexBodyLT K f` is the set of
+/-- Let `I` be a fractional ideal of `K`. Assume that `f : InfinitePlace K → ℝ≥0` is such that
+`minkowskiBound K I < volume (convexBodyLT K f)` where `convexBodyLT K f` is the set of
 points `x` such that `‖x w‖ < f w` for all infinite places `w` (see `convexBodyLT_volume` for
-the computation of this volume), then there exists a nonzero algebraic integer `a` in `𝓞 K` such
+the computation of this volume), then there exists a nonzero algebraic number `a` in `I` such
 that `w a < f w` for all infinite places `w`. -/
-theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (convexBodyLT K f)) :
-    ∃ (a : 𝓞 K), a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
-  have h_fund := Zspan.isAddFundamentalDomain (latticeBasis K) volume
-  have : Countable (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
-    change Countable (Submodule.span ℤ (Set.range (latticeBasis K)) : Set (E K))
+theorem exists_ne_zero_mem_ideal_lt (h : minkowskiBound K I < volume (convexBodyLT K f)) :
+    ∃ a ∈ (I : FractionalIdeal (𝓞 K)⁰ K), a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
+  have h_fund := Zspan.isAddFundamentalDomain (fractionalIdealLatticeBasis K I) volume
+  have : Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
+    change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)) : Set (E K))
     infer_instance
-  obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
+  obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
     h_fund (convexBodyLT_symmetric K f) (convexBodyLT_convex K f) h
-  rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
+  rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
-  refine ⟨⟨a, ha⟩, ?_, (convexBodyLT_mem K f).mp h_mem⟩
-  rw [ne_eq, AddSubgroup.mk_eq_zero_iff, map_eq_zero, ← ne_eq] at h_nzr
-  exact Subtype.ne_of_val_ne h_nzr
-
-theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
-    (h : (minkowskiBound K) ≤ volume (convexBodySum K B)) :
-    ∃ (a : 𝓞 K), a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
+  exact ⟨a, ha, by simpa using h_nz, (convexBodyLT_mem K f).mp h_mem⟩
+
+/-- A version of `exists_ne_zero_mem_ideal_lt` for the ring of integers of `K`. -/
+theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K 1 < volume (convexBodyLT K f)) :
+    ∃ a ∈ 𝓞 K, a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
+  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_lt K 1 h
+  obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
+  exact ⟨a, ha, h_nz, fun w ↦ h_bd w⟩
+
+theorem exists_ne_zero_mem_ideal_of_norm_le {B : ℝ}
+    (h : (minkowskiBound K I) ≤ volume (convexBodySum K B)) :
+    ∃ a ∈ (I : FractionalIdeal (𝓞 K)⁰ K), a ≠ 0 ∧
+      |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
   have hB : 0 ≤ B := by
     contrapose! h
     rw [convexBodySum_volume_eq_zero_of_le_zero K (le_of_lt h)]
-    exact minkowskiBound_pos K
+    exact minkowskiBound_pos K I
   -- Some inequalities that will be useful later on
   have h1 : 0 < (finrank ℚ K : ℝ)⁻¹ := inv_pos.mpr (Nat.cast_pos.mpr finrank_pos)
   have h2 : 0 ≤ B / (finrank ℚ K) := div_nonneg hB (Nat.cast_nonneg _)
-  have h_fund := Zspan.isAddFundamentalDomain (latticeBasis K) volume
-  have : Countable (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
-    change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
+  have h_fund := Zspan.isAddFundamentalDomain (fractionalIdealLatticeBasis K I) volume
+  have : Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
+    change Countable (span ℤ (Set.range (fractionalIdealLatticeBasis K I)): Set (E K))
     infer_instance
-  have : DiscreteTopology (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
-    change DiscreteTopology  (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
+  have : DiscreteTopology
+      (span ℤ (Set.range (fractionalIdealLatticeBasis K I))).toAddSubgroup := by
+    change DiscreteTopology (span ℤ (Set.range (fractionalIdealLatticeBasis K I)): Set (E K))
     infer_instance
-  obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_le_measure
+  obtain ⟨⟨x, hx⟩, h_nz, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_le_measure
       h_fund (fun _ ↦ convexBodySum_symmetric K B) (convexBodySum_convex K B)
       (convexBodySum_compact K B) h
-  rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
+  rw [mem_toAddSubgroup, mem_span_fractionalIdealLatticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
-  refine ⟨⟨a, ha⟩, ?_, ?_⟩
-  · rw [ne_eq, AddSubgroup.mk_eq_zero_iff, map_eq_zero, ← ne_eq] at h_nzr
-    exact Subtype.ne_of_val_ne h_nzr
-  · rw [← rpow_nat_cast, ← rpow_le_rpow_iff (by simp only [Rat.cast_abs, abs_nonneg])
+  refine ⟨a, ha, by simpa using h_nz, ?_⟩
+  rw [← rpow_nat_cast, ← rpow_le_rpow_iff (by simp only [Rat.cast_abs, abs_nonneg])
       (rpow_nonneg h2 _) h1, ← rpow_mul h2,  mul_inv_cancel (Nat.cast_ne_zero.mpr
       (ne_of_gt finrank_pos)), rpow_one, le_div_iff' (Nat.cast_pos.mpr finrank_pos)]
-    refine le_trans ?_ ((convexBodySum_mem K B).mp h_mem)
-    rw [← le_div_iff' (Nat.cast_pos.mpr finrank_pos), ← sum_mult_eq, Nat.cast_sum]
-    refine le_trans ?_ (geom_mean_le_arith_mean Finset.univ _ _ (fun _ _ => Nat.cast_nonneg _)
-      ?_ (fun _ _ => AbsoluteValue.nonneg _ _))
-    · simp_rw [← prod_eq_abs_norm, rpow_nat_cast]
-      exact le_of_eq rfl
-    · rw [← Nat.cast_sum, sum_mult_eq, Nat.cast_pos]
-      exact finrank_pos
+  refine le_trans ?_ ((convexBodySum_mem K B).mp h_mem)
+  rw [← le_div_iff' (Nat.cast_pos.mpr finrank_pos), ← sum_mult_eq, Nat.cast_sum]
+  refine le_trans ?_ (geom_mean_le_arith_mean Finset.univ _ _ (fun _ _ => Nat.cast_nonneg _)
+    ?_ (fun _ _ => AbsoluteValue.nonneg _ _))
+  · simp_rw [← prod_eq_abs_norm, rpow_nat_cast]
+    exact le_of_eq rfl
+  · rw [← Nat.cast_sum, sum_mult_eq, Nat.cast_pos]
+    exact finrank_pos
+
+theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
+    (h : (minkowskiBound K 1) ≤ volume (convexBodySum K B)) :
+    ∃ a ∈ 𝓞 K, a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
+  obtain ⟨_, h_mem, h_nz, h_bd⟩ := exists_ne_zero_mem_ideal_of_norm_le K 1 h
+  obtain ⟨⟨a, ha⟩, rfl⟩ := (FractionalIdeal.mem_one_iff _).mp h_mem
+  exact ⟨a, ha, h_nz, h_bd⟩
 
 end minkowski
 
chore: Matrix.mulVec and Matrix.vecMul get infix notation (#10297)

Zulip discussion: https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Notation.20for.20mul_vec.20and.20vec_mul

Co-authored-by: Martin Dvorak <mdvorak@ista.ac.at>

Diff
@@ -357,7 +357,7 @@ representation of `commMap K x` on `stdBasis` is given (up to reindexing) by the
 theorem stdBasis_repr_eq_matrixToStdBasis_mul (x : (K →+* ℂ) → ℂ)
     (hx : ∀ φ, conj (x φ) = x (ComplexEmbedding.conjugate φ)) (c : index K) :
     ((stdBasis K).repr (commMap K x) c : ℂ) =
-      (mulVec (matrixToStdBasis K) (x ∘ (indexEquiv K))) c := by
+      (matrixToStdBasis K *ᵥ (x ∘ (indexEquiv K))) c := by
   simp_rw [commMap, matrixToStdBasis, LinearMap.coe_mk, AddHom.coe_mk,
     mulVec, dotProduct, Function.comp_apply, index, Fintype.sum_sum_type,
     diagonal_one, reindex_apply, ← Finset.univ_product_univ, Finset.sum_product,
feat: The support of f ^ n (#9617)

This involves moving lemmas from Algebra.GroupPower.Ring to Algebra.GroupWithZero.Basic and changing some 0 < n assumptions to n ≠ 0.

From LeanAPAP

Diff
@@ -135,7 +135,7 @@ noncomputable def latticeBasis [NumberField K] :
     let N := Algebra.embeddingsMatrixReindex ℚ ℂ (fun i => integralBasis K (e i))
       RingHom.equivRatAlgHom
     rw [show M = N.transpose by { ext:2; rfl }]
-    rw [Matrix.det_transpose, ← @pow_ne_zero_iff ℂ _ _ _ 2 (by norm_num)]
+    rw [Matrix.det_transpose, ← pow_ne_zero_iff two_ne_zero]
     convert (map_ne_zero_iff _ (algebraMap ℚ ℂ).injective).mpr
       (Algebra.discr_not_zero_of_basis ℚ (integralBasis K))
     rw [← Algebra.discr_reindex ℚ (integralBasis K) e.symm]
@@ -678,7 +678,7 @@ theorem convexBodySum_volume :
     volume (convexBodySum K B) = (convexBodySumFactor K) * (.ofReal B) ^ (finrank ℚ K) := by
   obtain hB | hB := le_or_lt B 0
   · rw [convexBodySum_volume_eq_zero_of_le_zero K hB, ofReal_eq_zero.mpr hB, zero_pow, mul_zero]
-    exact finrank_pos
+    exact finrank_pos.ne'
   · suffices volume (convexBodySum K 1) = (convexBodySumFactor K) by
       rw [mul_comm]
       convert addHaar_smul volume B (convexBodySum K 1)
doc: fix typos (#10100)

Fix minor typos in the following files:

  • Mathlib/GroupTheory/GroupAction/Opposite.lean
  • Mathlib/Init/Control/Lawful.lean
  • Mathlib/ModelTheory/ElementarySubstructures.lean
  • Mathlib/Algebra/Group/Defs.lean
  • Mathlib/Algebra/Group/WithOne/Basic.lean
  • Mathlib/Data/Int/Cast/Defs.lean
  • Mathlib/LinearAlgebra/Dimension/Basic.lean
  • Mathlib/NumberTheory/NumberField/CanonicalEmbedding.lean
  • Mathlib/Algebra/Star/StarAlgHom.lean
  • Mathlib/AlgebraicTopology/SimplexCategory.lean
  • Mathlib/CategoryTheory/Abelian/Homology.lean
  • Mathlib/CategoryTheory/Sites/Grothendieck.lean
  • Mathlib/RingTheory/IsTensorProduct.lean
  • Mathlib/AlgebraicTopology/DoldKan/Homotopies.lean
  • Mathlib/AlgebraicTopology/ExtraDegeneracy.lean
  • Mathlib/AlgebraicTopology/Nerve.lean
  • Mathlib/AlgebraicTopology/SplitSimplicialObject.lean
  • Mathlib/Analysis/ConstantSpeed.lean
  • Mathlib/Analysis/Convolution.lean
Diff
@@ -22,7 +22,7 @@ into the type `(K →+* ℂ) → ℂ` of `ℂ`-vectors indexed by the complex em
 
 ## Main definitions and results
 
-* `NumberField.canonicalEmbedding`: the ring homorphism `K →+* ((K →+* ℂ) → ℂ)` defined by
+* `NumberField.canonicalEmbedding`: the ring homomorphism `K →+* ((K →+* ℂ) → ℂ)` defined by
 sending `x : K` to the vector `(φ x)` indexed by `φ : K →+* ℂ`.
 
 * `NumberField.canonicalEmbedding.integerLattice.inter_ball_finite`: the intersection of the
chore: reduce imports (#9830)

This uses the improved shake script from #9772 to reduce imports across mathlib. The corresponding noshake.json file has been added to #9772.

Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -8,6 +8,7 @@ import Mathlib.MeasureTheory.Group.GeometryOfNumbers
 import Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls
 import Mathlib.NumberTheory.NumberField.Embeddings
 import Mathlib.RingTheory.Discriminant
+import Mathlib.Topology.Bornology.Constructions
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
 
chore: Rename rpow_nonneg_of_nonneg to rpow_nonneg (#9518)

This better matches other lemma names.

From LeanAPAP

Diff
@@ -799,7 +799,7 @@ theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
   · rw [ne_eq, AddSubgroup.mk_eq_zero_iff, map_eq_zero, ← ne_eq] at h_nzr
     exact Subtype.ne_of_val_ne h_nzr
   · rw [← rpow_nat_cast, ← rpow_le_rpow_iff (by simp only [Rat.cast_abs, abs_nonneg])
-      (rpow_nonneg_of_nonneg h2 _) h1, ← rpow_mul h2,  mul_inv_cancel (Nat.cast_ne_zero.mpr
+      (rpow_nonneg h2 _) h1, ← rpow_mul h2,  mul_inv_cancel (Nat.cast_ne_zero.mpr
       (ne_of_gt finrank_pos)), rpow_one, le_div_iff' (Nat.cast_pos.mpr finrank_pos)]
     refine le_trans ?_ ((convexBodySum_mem K B).mp h_mem)
     rw [← le_div_iff' (Nat.cast_pos.mpr finrank_pos), ← sum_mult_eq, Nat.cast_sum]
chore(*): replace $ with <| (#9319)

See Zulip thread for the discussion.

Diff
@@ -576,7 +576,7 @@ theorem convexBodySumFun_eq_zero_iff (x : E K) :
       Finset.sum_eq_zero_iff_of_nonneg (fun _ _ => norm_nonneg _)] at h
     ext : 2
     · exact norm_eq_zero.mp (h.1 _ (Finset.mem_univ _))
-    · exact norm_eq_zero.1 $ eq_zero_of_ne_zero_of_mul_left_eq_zero two_ne_zero $ h.2 _ $
+    · exact norm_eq_zero.1 <| eq_zero_of_ne_zero_of_mul_left_eq_zero two_ne_zero <| h.2 _ <|
         Finset.mem_univ _
   · simp only [convexBodySumFun, h, Prod.fst_zero, Pi.zero_apply, norm_zero, Finset.sum_const_zero,
       Prod.snd_zero, mul_zero, add_zero]
feat: c • x = 0 ↔ c = 0 and similar lemmas (#9390)

and rename and generalise smul_eq_zero_iff_eq'/smul_ne_zero_iff_ne'

From LeanAPAP

Diff
@@ -576,8 +576,8 @@ theorem convexBodySumFun_eq_zero_iff (x : E K) :
       Finset.sum_eq_zero_iff_of_nonneg (fun _ _ => norm_nonneg _)] at h
     ext : 2
     · exact norm_eq_zero.mp (h.1 _ (Finset.mem_univ _))
-    · exact norm_eq_zero.mp ((smul_eq_zero_iff_eq' two_ne_zero (α := ℝ)).mp
-        (h.2 _ (Finset.mem_univ _)))
+    · exact norm_eq_zero.1 $ eq_zero_of_ne_zero_of_mul_left_eq_zero two_ne_zero $ h.2 _ $
+        Finset.mem_univ _
   · simp only [convexBodySumFun, h, Prod.fst_zero, Pi.zero_apply, norm_zero, Finset.sum_const_zero,
       Prod.snd_zero, mul_zero, add_zero]
 
feat: Hermite-Minkowski theorem (#8478)

We prove lower bounds for the abs. value of the discriminant of a number field in terms of its degree and deduce from it Hermite-Minkowski theorem: a nontrivial number field has nontrivial absolute discriminant.

theorem abs_discr_ge (h : 1 < finrank ℚ K) :
    (4 / 9 : ℝ) * (3 * π / 4) ^ finrank ℚ K ≤ |discr K| 

theorem discr_gt_one (h : 1 < finrank ℚ K) : 2 < |discr K|
Diff
@@ -3,11 +3,11 @@ Copyright (c) 2022 Xavier Roblot. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 -/
-import Mathlib.RingTheory.Discriminant
 import Mathlib.Algebra.Module.Zlattice
 import Mathlib.MeasureTheory.Group.GeometryOfNumbers
 import Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls
 import Mathlib.NumberTheory.NumberField.Embeddings
+import Mathlib.RingTheory.Discriminant
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
 
@@ -464,6 +464,13 @@ variable [NumberField K]
 
 instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasure volume volume
 
+instance : NoAtoms (volume : Measure (E K)) := by
+  obtain ⟨w⟩ := (inferInstance : Nonempty (InfinitePlace K))
+  by_cases hw : IsReal w
+  exact @prod.instNoAtoms_fst _ _ _ _ volume volume _ (pi_noAtoms ⟨w, hw⟩)
+  · exact @prod.instNoAtoms_snd _ _ _ _ volume volume _
+      (pi_noAtoms ⟨w, not_isReal_iff_isComplex.mp hw⟩)
+
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLT`. -/
 noncomputable abbrev convexBodyLTFactor : ℝ≥0∞ :=
   (2 : ℝ≥0∞) ^ NrRealPlaces K * (NNReal.pi : ℝ≥0∞) ^ NrComplexPlaces K
@@ -524,50 +531,199 @@ section convexBodySum
 
 open ENNReal BigOperators Classical MeasureTheory Fintype
 
+open scoped Real
+
 variable [NumberField K] (B : ℝ)
 
+variable {K}
+
+/-- The function that sends `x : ({w // IsReal w} → ℝ) × ({w // IsComplex w} → ℂ)` to
+  `∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖`. It defines a norm and it used to define `convexBodySum`. -/
+noncomputable abbrev convexBodySumFun (x : E K) : ℝ := ∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖
+
+theorem convexBodySumFun_nonneg (x : E K) :
+    0 ≤ convexBodySumFun x := by
+  refine add_nonneg ?_ ?_
+  · exact Finset.sum_nonneg (fun _ _ => norm_nonneg _)
+  · exact mul_nonneg zero_le_two (Finset.sum_nonneg (fun _ _ => norm_nonneg _))
+
+theorem convexBodySumFun_neg (x : E K) :
+    convexBodySumFun (- x) = convexBodySumFun x := by
+  simp_rw [convexBodySumFun, Prod.fst_neg, Prod.snd_neg, Pi.neg_apply, norm_neg]
+
+theorem convexBodySumFun_add_le (x y : E K) :
+    convexBodySumFun (x + y) ≤ convexBodySumFun x + convexBodySumFun y := by
+  simp_rw [convexBodySumFun, Prod.fst_add, Pi.add_apply, Prod.snd_add]
+  refine le_trans (add_le_add
+    (Finset.sum_le_sum (fun w _ => norm_add_le (x.1 w) (y.1 w)))
+    (mul_le_mul_of_nonneg_left
+      (Finset.sum_le_sum (fun w _ => norm_add_le (x.2 w) (y.2 w))) (by norm_num))) ?_
+  simp_rw [Finset.sum_add_distrib, mul_add]
+  exact le_of_eq (by ring)
+
+theorem convexBodySumFun_smul (c : ℝ) (x : E K) :
+    convexBodySumFun (c • x) = |c| * convexBodySumFun x := by
+  simp_rw [convexBodySumFun, Prod.smul_fst, Prod.smul_snd, Pi.smul_apply, smul_eq_mul,
+    Complex.real_smul, norm_mul, Complex.norm_real, ← Finset.mul_sum, Real.norm_eq_abs]
+  ring
+
+theorem convexBodySumFun_eq_zero_iff (x : E K) :
+    convexBodySumFun x = 0 ↔ x = 0 := by
+  refine ⟨fun h => ?_, fun h => ?_⟩
+  · rw [add_eq_zero_iff' (Finset.sum_nonneg fun _ _ => norm_nonneg _) (mul_nonneg zero_le_two
+      (Finset.sum_nonneg fun _ _ => norm_nonneg _)), Finset.mul_sum,
+      Finset.sum_eq_zero_iff_of_nonneg (fun _ _ => mul_nonneg zero_le_two (norm_nonneg _)),
+      Finset.sum_eq_zero_iff_of_nonneg (fun _ _ => norm_nonneg _)] at h
+    ext : 2
+    · exact norm_eq_zero.mp (h.1 _ (Finset.mem_univ _))
+    · exact norm_eq_zero.mp ((smul_eq_zero_iff_eq' two_ne_zero (α := ℝ)).mp
+        (h.2 _ (Finset.mem_univ _)))
+  · simp only [convexBodySumFun, h, Prod.fst_zero, Pi.zero_apply, norm_zero, Finset.sum_const_zero,
+      Prod.snd_zero, mul_zero, add_zero]
+
+theorem norm_le_convexBodySumFun (x : E K) : ‖x‖ ≤ convexBodySumFun x := by
+  refine max_le ?_ ?_
+  · refine (pi_norm_le_iff_of_nonneg (convexBodySumFun_nonneg x)).mpr (fun w => ?_)
+    refine le_add_of_le_of_nonneg ?_ ?_
+    · exact Finset.single_le_sum (fun z _ => norm_nonneg (x.1 z)) (Finset.mem_univ w)
+    · exact mul_nonneg zero_le_two <| Finset.sum_nonneg (fun w _ => norm_nonneg (x.2 w))
+  · refine (pi_norm_le_iff_of_nonneg (convexBodySumFun_nonneg x)).mpr (fun w => ?_)
+    refine le_add_of_nonneg_of_le ?_ ?_
+    · exact Finset.sum_nonneg (fun w _ => norm_nonneg (x.1 w))
+    · rw [Finset.mul_sum]
+      refine le_trans (by linarith [norm_nonneg (x.2 w)] : ‖x.2 w‖ ≤ 2 * ‖x.2 w‖) ?_
+      exact Finset.single_le_sum (fun z _ => mul_nonneg zero_le_two (norm_nonneg (x.2 z)))
+        (Finset.mem_univ w)
+
+variable (K)
+
+theorem convexBodySumFun_continuous :
+    Continuous (convexBodySumFun : (E K) → ℝ) := by
+  refine Continuous.add ?_ ?_
+  · exact continuous_finset_sum Finset.univ
+      (fun i _ => continuous_norm.comp' (continuous_apply i).fst')
+  · refine Continuous.const_smul ?_ (2:ℝ)
+    exact continuous_finset_sum Finset.univ
+      (fun i _ => continuous_norm.comp' (continuous_apply i).snd')
+
 /-- The convex body equal to the set of points `x : E` such that
   `∑ w real, ‖x w‖ + 2 * ∑ w complex, ‖x w‖ ≤ B`. -/
-abbrev convexBodySum : Set (E K)  := { x | ∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖ ≤ B }
-
-theorem convexBodySum_empty {B} (h : B < 0) : convexBodySum K B = ∅ := by
-  ext x
-  refine ⟨fun hx => ?_, fun h => h.elim⟩
-  · rw [Set.mem_setOf] at hx
-    have : 0 ≤ ∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖ := by
-      refine add_nonneg ?_ ?_
-      · exact Finset.sum_nonneg (fun _ _ => norm_nonneg _)
-      · exact mul_nonneg zero_le_two (Finset.sum_nonneg (fun _ _ => norm_nonneg _))
-    linarith
+abbrev convexBodySum : Set (E K)  := { x | convexBodySumFun x ≤ B }
+
+theorem convexBodySum_volume_eq_zero_of_le_zero {B} (hB : B ≤ 0) :
+    volume (convexBodySum K B) = 0 := by
+  obtain hB | hB := lt_or_eq_of_le hB
+  · suffices convexBodySum K B = ∅ by rw [this, measure_empty]
+    ext x
+    refine ⟨fun hx => ?_, fun h => h.elim⟩
+    rw [Set.mem_setOf] at hx
+    linarith [convexBodySumFun_nonneg x]
+  · suffices convexBodySum K B = { 0 } by rw [this, measure_singleton]
+    ext
+    rw [convexBodySum, Set.mem_setOf_eq, Set.mem_singleton_iff, hB, ← convexBodySumFun_eq_zero_iff]
+    exact (convexBodySumFun_nonneg _).le_iff_eq
 
 theorem convexBodySum_mem {x : K} :
     mixedEmbedding K x ∈ (convexBodySum K B) ↔
       ∑ w : InfinitePlace K, (mult w) * w.val x ≤ B := by
-  simp_rw [Set.mem_setOf_eq, mixedEmbedding, RingHom.prod_apply, Pi.ringHom_apply,
+  simp_rw [Set.mem_setOf_eq, mixedEmbedding, RingHom.prod_apply, convexBodySumFun, Pi.ringHom_apply,
     ← Complex.norm_real, embedding_of_isReal_apply, norm_embedding_eq, mult, Nat.cast_ite, ite_mul,
     Finset.sum_ite, Finset.filter_congr (fun _ _ => not_isReal_iff_isComplex), Finset.mul_sum,
     ← Finset.sum_subtype_eq_sum_filter, Finset.subtype_univ, Nat.cast_one, one_mul, Nat.cast_ofNat]
   rfl
 
-theorem convexBodySum_symmetric (x : E K) (hx : x ∈ (convexBodySum K B)) :
+theorem convexBodySum_symmetric {x : E K} (hx : x ∈ (convexBodySum K B)) :
     -x ∈ (convexBodySum K B) := by
-  simp_rw [Set.mem_setOf_eq, Prod.fst_neg, Prod.snd_neg, Pi.neg_apply, norm_neg]
+  rw [Set.mem_setOf, convexBodySumFun_neg]
   exact hx
 
 theorem convexBodySum_convex : Convex ℝ (convexBodySum K B) := by
-  refine Convex_subadditive_le ?_ ?_ B
-  · intro x y
-    simp_rw [Prod.fst_add, Pi.add_apply, Prod.snd_add]
-    refine le_trans (add_le_add
-      (Finset.sum_le_sum (fun w _ => norm_add_le (x.1 w) (y.1 w)))
-      (mul_le_mul_of_nonneg_left
-        (Finset.sum_le_sum (fun w _ => norm_add_le (x.2 w) (y.2 w))) (by norm_num))) ?_
-    simp_rw [Finset.sum_add_distrib, mul_add]
-    exact le_of_eq (by ring)
-  · intro _ _ h
-    simp_rw [Prod.smul_fst, Prod.smul_snd, Pi.smul_apply, smul_eq_mul, Complex.real_smul, norm_mul,
-      Complex.norm_real, Real.norm_of_nonneg h, ← Finset.mul_sum]
-    exact le_of_eq (by ring)
+  refine Convex_subadditive_le (fun _ _ => convexBodySumFun_add_le _ _) (fun c x h => ?_) B
+  convert le_of_eq (convexBodySumFun_smul c x)
+  exact (abs_eq_self.mpr h).symm
+
+theorem convexBodySum_isBounded : Bornology.IsBounded (convexBodySum K B) := by
+  refine Metric.isBounded_iff.mpr ⟨B + B, fun x hx y hy => ?_⟩
+  refine le_trans (norm_sub_le x y) (add_le_add ?_ ?_)
+  exact le_trans (norm_le_convexBodySumFun x) hx
+  exact le_trans (norm_le_convexBodySumFun y) hy
+
+theorem convexBodySum_compact : IsCompact (convexBodySum K B) := by
+  rw [Metric.isCompact_iff_isClosed_bounded]
+  refine ⟨?_, convexBodySum_isBounded K B⟩
+  convert IsClosed.preimage (convexBodySumFun_continuous K) (isClosed_Icc : IsClosed (Set.Icc 0 B))
+  ext
+  simp [convexBodySumFun_nonneg]
+
+/-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
+noncomputable abbrev convexBodySumFactor : ℝ≥0∞ :=
+  (2:ℝ≥0∞) ^ NrRealPlaces K * (NNReal.pi / 2) ^ NrComplexPlaces K / (finrank ℚ K).factorial
+
+theorem convexBodySumFactor_ne_zero : convexBodySumFactor K ≠ 0 := by
+  dsimp [convexBodySumFactor]
+  refine mul_ne_zero (mul_ne_zero (pow_ne_zero _ two_ne_zero) ?_) ?_
+  · refine ENNReal.pow_ne_zero ?_ _
+    exact ne_of_gt <| div_pos_iff.mpr ⟨coe_ne_zero.mpr NNReal.pi_ne_zero, two_ne_top⟩
+  · exact ENNReal.inv_ne_zero.mpr (nat_ne_top _)
+
+theorem convexBodySumFactor_ne_top : convexBodySumFactor K ≠ ⊤ := by
+  refine mul_ne_top (mul_ne_top (pow_ne_top two_ne_top) ?_) ?_
+  · rw [show (2:ℝ≥0∞) = (2:NNReal) by rfl, ← ENNReal.coe_div two_ne_zero]
+    exact pow_ne_top coe_ne_top
+  · exact inv_ne_top.mpr <| Nat.cast_ne_zero.mpr (Nat.factorial_ne_zero _)
+
+open MeasureTheory MeasureTheory.Measure Real in
+theorem convexBodySum_volume :
+    volume (convexBodySum K B) = (convexBodySumFactor K) * (.ofReal B) ^ (finrank ℚ K) := by
+  obtain hB | hB := le_or_lt B 0
+  · rw [convexBodySum_volume_eq_zero_of_le_zero K hB, ofReal_eq_zero.mpr hB, zero_pow, mul_zero]
+    exact finrank_pos
+  · suffices volume (convexBodySum K 1) = (convexBodySumFactor K) by
+      rw [mul_comm]
+      convert addHaar_smul volume B (convexBodySum K 1)
+      · simp_rw [← Set.preimage_smul_inv₀ (ne_of_gt hB), Set.preimage_setOf_eq, convexBodySumFun,
+          Prod.smul_fst, Prod.smul_snd, Pi.smul_apply, Complex.real_smul, smul_eq_mul, norm_mul,
+          Complex.ofReal_inv, norm_inv, norm_eq_abs B, Complex.norm_eq_abs B, Complex.abs_ofReal,
+          abs_eq_self.mpr (le_of_lt hB), ← Finset.mul_sum, ← mul_assoc, mul_comm (2:ℝ), mul_assoc,
+          ← mul_add, inv_mul_le_iff hB, mul_one]
+      · rw [abs_pow, ofReal_pow (abs_nonneg _), abs_eq_self.mpr (le_of_lt hB),
+          mixedEmbedding.finrank]
+      · exact this.symm
+    rw [MeasureTheory.measure_le_eq_lt _ ((convexBodySumFun_eq_zero_iff 0).mpr rfl)
+      convexBodySumFun_neg convexBodySumFun_add_le
+      (fun hx => (convexBodySumFun_eq_zero_iff _).mp hx)
+      (fun r x => le_of_eq (convexBodySumFun_smul r x))]
+    rw [measure_lt_one_eq_integral_div_gamma (g := fun x : (E K) => convexBodySumFun x)
+      volume ((convexBodySumFun_eq_zero_iff 0).mpr rfl) convexBodySumFun_neg convexBodySumFun_add_le
+      (fun hx => (convexBodySumFun_eq_zero_iff _).mp hx)
+      (fun r x => le_of_eq (convexBodySumFun_smul r x)) zero_lt_one]
+    simp_rw [mixedEmbedding.finrank, div_one, Gamma_nat_eq_factorial, ofReal_div_of_pos
+      (Nat.cast_pos.mpr (Nat.factorial_pos _)), Real.rpow_one, ofReal_coe_nat]
+    suffices ∫ x : E K, exp (-convexBodySumFun x) =
+        (2:ℝ) ^ NrRealPlaces K * (π / 2) ^ NrComplexPlaces K by
+      rw [this, convexBodySumFactor, ofReal_mul (by positivity), ofReal_pow zero_le_two,
+        ofReal_pow (by positivity), ofReal_div_of_pos zero_lt_two, ofReal_ofNat,
+        ← NNReal.coe_real_pi, ofReal_coe_nnreal]
+    calc
+      _ = (∫ x : {w : InfinitePlace K // IsReal w} → ℝ, ∏ w, exp (- ‖x w‖)) *
+              (∫ x : {w : InfinitePlace K // IsComplex w} → ℂ, ∏ w, exp (- 2 * ‖x w‖)) := by
+        simp_rw [convexBodySumFun, neg_add, ← neg_mul, Finset.mul_sum, ← Finset.sum_neg_distrib,
+          exp_add, exp_sum, ← integral_prod_mul, volume_eq_prod]
+      _ = (∫ x : ℝ, exp (-|x|)) ^ NrRealPlaces K *
+              (∫ x : ℂ, Real.exp (-2 * ‖x‖)) ^ NrComplexPlaces K := by
+        rw [integral_fintype_prod_eq_pow _ (fun x => exp (- ‖x‖)), integral_fintype_prod_eq_pow _
+          (fun x => exp (- 2 * ‖x‖))]
+        simp_rw [norm_eq_abs]
+      _ =  (2 * Gamma (1 / 1 + 1)) ^ NrRealPlaces K *
+              (π * (2:ℝ) ^ (-(2:ℝ) / 1) * Gamma (2 / 1 + 1)) ^ NrComplexPlaces K := by
+        rw [integral_comp_abs (f := fun x => exp (- x)), ← integral_exp_neg_rpow zero_lt_one,
+          ← Complex.integral_exp_neg_mul_rpow le_rfl zero_lt_two]
+        simp_rw [Real.rpow_one]
+      _ = (2:ℝ) ^ NrRealPlaces K * (π / 2) ^ NrComplexPlaces K := by
+        simp_rw [div_one, one_add_one_eq_two, Gamma_add_one two_ne_zero, Gamma_two, mul_one,
+          mul_assoc, ← Real.rpow_add_one two_ne_zero, show (-2:ℝ) + 1 = -1 by norm_num,
+          Real.rpow_neg_one]
+        rfl
 
 end convexBodySum
 
@@ -591,9 +747,12 @@ theorem minkowskiBound_lt_top : minkowskiBound K < ⊤ := by
   · exact ne_of_lt (fundamentalDomain_isBounded (latticeBasis K)).measure_lt_top
   · exact ne_of_lt (ENNReal.pow_lt_top (lt_top_iff_ne_top.mpr ENNReal.two_ne_top) _)
 
-variable {f : InfinitePlace K → ℝ≥0}
+theorem minkowskiBound_pos : 0 < minkowskiBound K := by
+  refine zero_lt_iff.mpr (mul_ne_zero ?_ ?_)
+  · exact Zspan.measure_fundamentalDomain_ne_zero (latticeBasis K)
+  · exact ENNReal.pow_ne_zero two_ne_zero _
 
-instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasure volume volume
+variable {f : InfinitePlace K → ℝ≥0}
 
 /-- Assume that `f : InfinitePlace K → ℝ≥0` is such that
 `minkowskiBound K < volume (convexBodyLT K f)` where `convexBodyLT K f` is the set of
@@ -615,12 +774,12 @@ theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (con
   exact Subtype.ne_of_val_ne h_nzr
 
 theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
-    (h : (minkowskiBound K) < volume (convexBodySum K B)) :
+    (h : (minkowskiBound K) ≤ volume (convexBodySum K B)) :
     ∃ (a : 𝓞 K), a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
   have hB : 0 ≤ B := by
     contrapose! h
-    rw [convexBodySum_empty K h, measure_empty]
-    exact zero_le (minkowskiBound K)
+    rw [convexBodySum_volume_eq_zero_of_le_zero K (le_of_lt h)]
+    exact minkowskiBound_pos K
   -- Some inequalities that will be useful later on
   have h1 : 0 < (finrank ℚ K : ℝ)⁻¹ := inv_pos.mpr (Nat.cast_pos.mpr finrank_pos)
   have h2 : 0 ≤ B / (finrank ℚ K) := div_nonneg hB (Nat.cast_nonneg _)
@@ -628,8 +787,12 @@ theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
   have : Countable (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
     change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
     infer_instance
-  obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
-    h_fund (convexBodySum_symmetric K B) (convexBodySum_convex K B) h
+  have : DiscreteTopology (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
+    change DiscreteTopology  (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
+    infer_instance
+  obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_le_measure
+      h_fund (fun _ ↦ convexBodySum_symmetric K B) (convexBodySum_convex K B)
+      (convexBodySum_compact K B) h
   rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
   refine ⟨⟨a, ha⟩, ?_, ?_⟩
chore: tidy various files (#8880)
Diff
@@ -172,7 +172,7 @@ noncomputable def _root_.NumberField.mixedEmbedding : K →+* (E K) :=
   RingHom.prod (Pi.ringHom fun w => embedding_of_isReal w.prop)
     (Pi.ringHom fun w => w.val.embedding)
 
-instance [NumberField K] :  Nontrivial (E K) := by
+instance [NumberField K] : Nontrivial (E K) := by
   obtain ⟨w⟩ := (inferInstance : Nonempty (InfinitePlace K))
   obtain hw | hw := w.isReal_or_isComplex
   · have : Nonempty {w : InfinitePlace K // IsReal w} := ⟨⟨w, hw⟩⟩
@@ -195,15 +195,15 @@ section commMap
 
 /-- The linear map that makes `canonicalEmbedding` and `mixedEmbedding` commute, see
 `commMap_canonical_eq_mixed`. -/
-noncomputable def commMap : ((K →+* ℂ) → ℂ) →ₗ[ℝ] (E K) :=
-{ toFun := fun x => ⟨fun w => (x w.val.embedding).re, fun w => x w.val.embedding⟩
+noncomputable def commMap : ((K →+* ℂ) → ℂ) →ₗ[ℝ] (E K) where
+  toFun := fun x => ⟨fun w => (x w.val.embedding).re, fun w => x w.val.embedding⟩
   map_add' := by
     simp only [Pi.add_apply, Complex.add_re, Prod.mk_add_mk, Prod.mk.injEq]
     exact fun _ _ => ⟨rfl, rfl⟩
   map_smul' := by
     simp only [Pi.smul_apply, Complex.real_smul, Complex.mul_re, Complex.ofReal_re,
       Complex.ofReal_im, zero_mul, sub_zero, RingHom.id_apply, Prod.smul_mk, Prod.mk.injEq]
-    exact fun _ _ => ⟨rfl, rfl⟩ }
+    exact fun _ _ => ⟨rfl, rfl⟩
 
 theorem commMap_apply_of_isReal (x : (K →+* ℂ) → ℂ) {w : InfinitePlace K} (hw : IsReal w) :
     (commMap K x).1 ⟨w, hw⟩ = (x w.embedding).re := rfl
@@ -232,12 +232,11 @@ theorem disjoint_span_commMap_ker [NumberField K] :
   ext1 φ
   rw [Pi.zero_apply]
   by_cases hφ : ComplexEmbedding.IsReal φ
-  · rw [show x φ = (x φ).re by
-      rw [eq_comm, ← Complex.conj_eq_iff_re, canonicalEmbedding.conj_apply _ h_mem,
-        ComplexEmbedding.isReal_iff.mp hφ], ← Complex.ofReal_zero]
-    congr
-    rw [← embedding_mk_eq_of_isReal hφ, ← commMap_apply_of_isReal K x ⟨φ, hφ, rfl⟩]
-    exact congrFun (congrArg (fun x => x.1) h_zero) ⟨InfinitePlace.mk φ, _⟩
+  · apply Complex.ext
+    · rw [← embedding_mk_eq_of_isReal hφ, ← commMap_apply_of_isReal K x ⟨φ, hφ, rfl⟩]
+      exact congrFun (congrArg (fun x => x.1) h_zero) ⟨InfinitePlace.mk φ, _⟩
+    · rw [Complex.zero_im, ← Complex.conj_eq_iff_im, canonicalEmbedding.conj_apply _ h_mem,
+        ComplexEmbedding.isReal_iff.mp hφ]
   · have := congrFun (congrArg (fun x => x.2) h_zero) ⟨InfinitePlace.mk φ, ⟨φ, hφ, rfl⟩⟩
     cases embedding_mk_eq φ with
     | inl h => rwa [← h, ← commMap_apply_of_isComplex K x ⟨φ, hφ, rfl⟩]
@@ -399,7 +398,7 @@ noncomputable def latticeBasis [NumberField K] :
     Basis (Free.ChooseBasisIndex ℤ (𝓞 K)) ℝ (E K) := by
   classical
     -- We construct an `ℝ`-linear independent family from the image of
-    -- `canonicalEmbedding.lattice_basis` by `comm_map`
+    -- `canonicalEmbedding.lattice_basis` by `commMap`
     have := LinearIndependent.map (LinearIndependent.restrict_scalars
       (by { simpa only [Complex.real_smul, mul_one] using Complex.ofReal_injective })
       (canonicalEmbedding.latticeBasis K).linearIndependent)
@@ -430,7 +429,7 @@ theorem mem_span_latticeBasis [NumberField K] (x : (E K)) :
 
 end integerLattice
 
-section convexBodyLt
+section convexBodyLT
 
 open Metric ENNReal NNReal
 
@@ -438,25 +437,25 @@ variable (f : InfinitePlace K → ℝ≥0)
 
 /-- The convex body defined by `f`: the set of points `x : E` such that `‖x w‖ < f w` for all
 infinite places `w`. -/
-abbrev convexBodyLt : Set (E K) :=
+abbrev convexBodyLT : Set (E K) :=
   (Set.univ.pi (fun w : { w : InfinitePlace K // IsReal w } => ball 0 (f w))) ×ˢ
   (Set.univ.pi (fun w : { w : InfinitePlace K // IsComplex w } => ball 0 (f w)))
 
-theorem convexBodyLt_mem {x : K} :
-    mixedEmbedding K x ∈ (convexBodyLt K f) ↔ ∀ w : InfinitePlace K, w x < f w := by
+theorem convexBodyLT_mem {x : K} :
+    mixedEmbedding K x ∈ (convexBodyLT K f) ↔ ∀ w : InfinitePlace K, w x < f w := by
   simp_rw [mixedEmbedding, RingHom.prod_apply, Set.mem_prod, Set.mem_pi, Set.mem_univ,
     forall_true_left, mem_ball_zero_iff, Pi.ringHom_apply, ← Complex.norm_real,
     embedding_of_isReal_apply, Subtype.forall, ← ball_or_left, ← not_isReal_iff_isComplex, em,
     forall_true_left, norm_embedding_eq]
 
-theorem convexBodyLt_symmetric (x : E K) (hx : x ∈ (convexBodyLt K f)) :
-    -x ∈ (convexBodyLt K f) := by
+theorem convexBodyLT_symmetric (x : E K) (hx : x ∈ (convexBodyLT K f)) :
+    -x ∈ (convexBodyLT K f) := by
   simp only [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
     mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
     Prod.snd_neg, Complex.norm_eq_abs, hx] at hx ⊢
   exact hx
 
-theorem convexBodyLt_convex : Convex ℝ (convexBodyLt K f) :=
+theorem convexBodyLT_convex : Convex ℝ (convexBodyLT K f) :=
   Convex.prod (convex_pi (fun _ _ => convex_ball _ _)) (convex_pi (fun _ _ => convex_ball _ _))
 
 open Classical Fintype MeasureTheory MeasureTheory.Measure BigOperators
@@ -465,23 +464,23 @@ variable [NumberField K]
 
 instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasure volume volume
 
-/-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
-noncomputable abbrev convexBodyLtFactor : ℝ≥0∞ :=
+/-- The fudge factor that appears in the formula for the volume of `convexBodyLT`. -/
+noncomputable abbrev convexBodyLTFactor : ℝ≥0∞ :=
   (2 : ℝ≥0∞) ^ NrRealPlaces K * (NNReal.pi : ℝ≥0∞) ^ NrComplexPlaces K
 
-theorem convexBodyLtFactor_pos : 0 < (convexBodyLtFactor K) := by
+theorem convexBodyLTFactor_pos : 0 < (convexBodyLTFactor K) := by
   refine mul_pos (NeZero.ne _) (ENNReal.pow_ne_zero ?_ _)
   exact ne_of_gt (coe_pos.mpr Real.pi_pos)
 
-theorem convexBodyLtFactor_lt_top : (convexBodyLtFactor K) < ⊤ := by
+theorem convexBodyLTFactor_lt_top : (convexBodyLTFactor K) < ⊤ := by
   refine mul_lt_top ?_ ?_
   · exact ne_of_lt (pow_lt_top (lt_top_iff_ne_top.mpr two_ne_top) _)
   · exact ne_of_lt (pow_lt_top coe_lt_top _)
 
-/-- The volume of `(ConvexBodyLt K f)` where `convexBodyLt K f` is the set of points `x`
+/-- The volume of `(ConvexBodyLt K f)` where `convexBodyLT K f` is the set of points `x`
 such that `‖x w‖ < f w` for all infinite places `w`. -/
-theorem convexBodyLt_volume :
-    volume (convexBodyLt K f) = (convexBodyLtFactor K) * ∏ w, (f w) ^ (mult w) := by
+theorem convexBodyLT_volume :
+    volume (convexBodyLT K f) = (convexBodyLTFactor K) * ∏ w, (f w) ^ (mult w) := by
   calc
     _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
           ∏ x : {w // InfinitePlace.IsComplex w}, ENNReal.ofReal (f x.val) ^ 2 * pi := by
@@ -490,9 +489,9 @@ theorem convexBodyLt_volume :
           ((∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) * ↑pi ^ NrComplexPlaces K) := by
       simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
         Finset.card_univ, ofReal_ofNat]
-    _ = (convexBodyLtFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)) *
+    _ = (convexBodyLTFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)) *
         (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by ring
-    _ = (convexBodyLtFactor K) * ∏ w, (f w) ^ (mult w) := by
+    _ = (convexBodyLTFactor K) * ∏ w, (f w) ^ (mult w) := by
       simp_rw [mult, pow_ite, pow_one, Finset.prod_ite, ofReal_coe_nnreal, not_isReal_iff_isComplex,
         coe_mul, coe_finset_prod, ENNReal.coe_pow]
       congr 2
@@ -506,7 +505,7 @@ variable {f}
 /-- This is a technical result: quite often, we want to impose conditions at all infinite places
 but one and choose the value at the remaining place so that we can apply
 `exists_ne_zero_mem_ringOfIntegers_lt`. -/
-theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁→ f w ≠ 0) :
+theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁ → f w ≠ 0) :
     ∃ g : InfinitePlace K → ℝ≥0, (∀ w, w ≠ w₁ → g w = f w) ∧ ∏ w, (g w) ^ mult w = B := by
   let S := ∏ w in Finset.univ.erase w₁, (f w) ^ mult w
   refine ⟨Function.update f w₁ ((B * S⁻¹) ^ (mult w₁ : ℝ)⁻¹), ?_, ?_⟩
@@ -519,7 +518,7 @@ theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁
       exact fun w hw => pow_ne_zero _ (hf w (Finset.ne_of_mem_erase hw))
     · rw [mult]; split_ifs <;> norm_num
 
-end convexBodyLt
+end convexBodyLT
 
 section convexBodySum
 
@@ -585,7 +584,7 @@ variable [NumberField K]
 `NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis` for the computation of
 `volume (fundamentalDomain (latticeBasis K))`. -/
 noncomputable def minkowskiBound : ℝ≥0∞ :=
-  volume (fundamentalDomain (latticeBasis K)) * (2:ℝ≥0∞) ^ (finrank ℝ (E K))
+  volume (fundamentalDomain (latticeBasis K)) * (2 : ℝ≥0∞) ^ (finrank ℝ (E K))
 
 theorem minkowskiBound_lt_top : minkowskiBound K < ⊤ := by
   refine ENNReal.mul_lt_top ?_ ?_
@@ -597,21 +596,21 @@ variable {f : InfinitePlace K → ℝ≥0}
 instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasure volume volume
 
 /-- Assume that `f : InfinitePlace K → ℝ≥0` is such that
-`minkowskiBound K < volume (convexBodyLt K f)` where `convexBodyLt K f` is the set of
-points `x` such that `‖x w‖ < f w` for all infinite places `w` (see `convexBodyLt_volume` for
+`minkowskiBound K < volume (convexBodyLT K f)` where `convexBodyLT K f` is the set of
+points `x` such that `‖x w‖ < f w` for all infinite places `w` (see `convexBodyLT_volume` for
 the computation of this volume), then there exists a nonzero algebraic integer `a` in `𝓞 K` such
 that `w a < f w` for all infinite places `w`. -/
-theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (convexBodyLt K f)) :
+theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (convexBodyLT K f)) :
     ∃ (a : 𝓞 K), a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
   have h_fund := Zspan.isAddFundamentalDomain (latticeBasis K) volume
   have : Countable (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
-    change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
+    change Countable (Submodule.span ℤ (Set.range (latticeBasis K)) : Set (E K))
     infer_instance
   obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
-    h_fund (convexBodyLt_symmetric K f) (convexBodyLt_convex K f) h
+    h_fund (convexBodyLT_symmetric K f) (convexBodyLT_convex K f) h
   rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
-  refine ⟨⟨a, ha⟩, ?_, (convexBodyLt_mem K f).mp h_mem⟩
+  refine ⟨⟨a, ha⟩, ?_, (convexBodyLT_mem K f).mp h_mem⟩
   rw [ne_eq, AddSubgroup.mk_eq_zero_iff, map_eq_zero, ← ne_eq] at h_nzr
   exact Subtype.ne_of_val_ne h_nzr
 
feat: Compute volume of balls of higher dimension for Lp norms (#8030)

We give a formula measure_unitBall_eq_integral_div_gamma for computing the volume of the unit ball in a normed finite dimensional -vector space E with an Haar measure:

theorem measure_unitBall_eq_integral_div_gamma {E : Type*} {p : ℝ}
    [NormedAddCommGroup E] [NormedSpace ℝ E] [FiniteDimensional ℝ E] [MeasurableSpace E]
    [BorelSpace E] (μ : Measure E) [IsAddHaarMeasure μ] (hp : 0 < p) :
    μ (Metric.ball 0 1) =
      ENNReal.ofReal ((∫ (x : E), Real.exp (- ‖x‖ ^ p) ∂μ) / Real.Gamma (finrank ℝ E / p + 1))

We also provide a theorem measure_lt_one_eq_integral_div_gamma to compute the volume of the ball {x : E | g x < 1} for a function g : E → ℝ defining a norm.

theorem measure_lt_one_eq_integral_div_gamma {E : Type*}
    [AddCommGroup E] [Module ℝ E] [FiniteDimensional ℝ E] [mE : MeasurableSpace E]
    [tE : TopologicalSpace E] [TopologicalAddGroup E] [BorelSpace E] [T2Space E]
    [ContinuousSMul ℝ E] (μ : Measure E) [IsAddHaarMeasure μ]
    {g : E → ℝ} (hg0 : g 0 = 0) (hgn : ∀ x, g (- x) = g x) (hgt : ∀ x y, g (x + y) ≤ g x + g y)
    (hgs : ∀ {x}, g x = 0 → x = 0) (hns :  ∀ r x, g (r • x) ≤ |r| * (g x)) {p : ℝ} (hp : 0 < p) :
    μ {x : E | g x < 1} =
      ENNReal.ofReal ((∫ (x : E), Real.exp (- (g x) ^ p) ∂μ) / Real.Gamma (finrank ℝ E / p + 1))

This provides a way to compute the volume of the unit ball for the norms L_p for 1 ≤ p in any dimension over the reals MeasureTheory.volume_sum_rpow_lt_one and the complex Complex.volume_sum_rpow_lt_one.

variable (ι : Type*) [Fintype ι] {p : ℝ} (hp : 1 ≤ p)

theorem volume_sum_rpow_lt_one :
    volume {x : ι → ℝ | ∑ i, |x i| ^ p < 1} =
      ENNReal.ofReal ((2 * Real.Gamma (1 / p + 1)) ^ card ι / Real.Gamma (card ι / p + 1))

theorem Complex.volume_sum_rpow_lt_one {p : ℝ} (hp : 1 ≤ p) :
    volume {x : ι → ℂ | ∑ i, ‖x i‖ ^ p < 1} =
      ENNReal.ofReal ((π * Real.Gamma (2 / p + 1)) ^ card ι / Real.Gamma (2 * card ι / p + 1)) 

From these, we deduce the volume of balls in several situations.

--

Other significant changes include:

  • Adding MeasurePreserving.integral_comp': when the theorem MeasurePreserving.integral_comp is used with f a measurable equiv, it is necessary to specify that it is a measurable embedding although it is trivial in this case. This version bypasses this hypothesis
  • Proof of volume computations of the unit ball in and in EuclideanSpace ℝ (Fin 2) which are now done with the methods of the file VolumeOfBalls have been moved to this file.

Co-authored-by: Yury G. Kudryashov <urkud@urkud.name>

Diff
@@ -6,6 +6,7 @@ Authors: Xavier Roblot
 import Mathlib.RingTheory.Discriminant
 import Mathlib.Algebra.Module.Zlattice
 import Mathlib.MeasureTheory.Group.GeometryOfNumbers
+import Mathlib.MeasureTheory.Measure.Lebesgue.VolumeOfBalls
 import Mathlib.NumberTheory.NumberField.Embeddings
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
@@ -483,10 +484,10 @@ theorem convexBodyLt_volume :
     volume (convexBodyLt K f) = (convexBodyLtFactor K) * ∏ w, (f w) ^ (mult w) := by
   calc
     _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
-          ∏ x : {w // InfinitePlace.IsComplex w}, pi * ENNReal.ofReal (f x.val) ^ 2 := by
+          ∏ x : {w // InfinitePlace.IsComplex w}, ENNReal.ofReal (f x.val) ^ 2 * pi := by
       simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball, Complex.volume_ball]
     _ = (↑2 ^ NrRealPlaces K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
-          (↑pi ^ NrComplexPlaces K * (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by
+          ((∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2) * ↑pi ^ NrComplexPlaces K) := by
       simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
         Finset.card_univ, ofReal_ofNat]
     _ = (convexBodyLtFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)) *
doc: Mark named theorems (#8749)
Diff
@@ -579,7 +579,7 @@ open scoped ENNReal NNReal
 
 variable [NumberField K]
 
-/-- The bound that appears in Minkowski Convex Body theorem, see
+/-- The bound that appears in **Minkowski Convex Body theorem**, see
 `MeasureTheory.exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure`. See
 `NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis` for the computation of
 `volume (fundamentalDomain (latticeBasis K))`. -/
fix: remove remaining ^ fixes (#8463)
Diff
@@ -42,8 +42,6 @@ nonzero algebraic integer `a` in `K` such that `w a < f w` for all infinite plac
 number field, infinite places
 -/
 
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
-
 variable (K : Type*) [Field K]
 
 namespace NumberField.canonicalEmbedding
chore: bump to v4.3.0-rc2 (#8366)

PR contents

This is the supremum of

along with some minor fixes from failures on nightly-testing as Mathlib master is merged into it.

Note that some PRs for changes that are already compatible with the current toolchain and will be necessary have already been split out: #8380.

I am hopeful that in future we will be able to progressively merge adaptation PRs into a bump/v4.X.0 branch, so we never end up with a "big merge" like this. However one of these adaptation PRs (#8056) predates my new scheme for combined CI, and it wasn't possible to keep that PR viable in the meantime.

Lean PRs involved in this bump

In particular this includes adjustments for the Lean PRs

leanprover/lean4#2778

We can get rid of all the

local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue [lean4#2220](https://github.com/leanprover/lean4/pull/2220)

macros across Mathlib (and in any projects that want to write natural number powers of reals).

leanprover/lean4#2722

Changes the default behaviour of simp to (config := {decide := false}). This makes simp (and consequentially norm_num) less powerful, but also more consistent, and less likely to blow up in long failures. This requires a variety of changes: changing some previously by simp or norm_num to decide or rfl, or adding (config := {decide := true}).

leanprover/lean4#2783

This changed the behaviour of simp so that simp [f] will only unfold "fully applied" occurrences of f. The old behaviour can be recovered with simp (config := { unfoldPartialApp := true }). We may in future add a syntax for this, e.g. simp [!f]; please provide feedback! In the meantime, we have made the following changes:

  • switching to using explicit lemmas that have the intended level of application
  • (config := { unfoldPartialApp := true }) in some places, to recover the old behaviour
  • Using @[eqns] to manually adjust the equation lemmas for a particular definition, recovering the old behaviour just for that definition. See #8371, where we do this for Function.comp and Function.flip.

This change in Lean may require further changes down the line (e.g. adding the !f syntax, and/or upstreaming the special treatment for Function.comp and Function.flip, and/or removing this special treatment). Please keep an open and skeptical mind about these changes!

Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Mauricio Collares <mauricio@collares.org>

Diff
@@ -343,10 +343,10 @@ def matrixToStdBasis : Matrix (index K) (index K) ℂ :=
 theorem det_matrixToStdBasis :
     (matrixToStdBasis K).det = (2⁻¹ * I) ^ NrComplexPlaces K :=
   calc
-  _ = ∏ k : { w : InfinitePlace K // IsComplex w }, det ((2 : ℂ)⁻¹ • !![1, 1; -I, I]) := by
+  _ = ∏ _k : { w : InfinitePlace K // IsComplex w }, det ((2 : ℂ)⁻¹ • !![1, 1; -I, I]) := by
       rw [matrixToStdBasis, det_fromBlocks_zero₂₁, det_diagonal, Finset.prod_const_one, one_mul,
           det_reindex_self, det_blockDiagonal]
-  _ = ∏ k : { w : InfinitePlace K // IsComplex w }, (2⁻¹ * Complex.I) := by
+  _ = ∏ _k : { w : InfinitePlace K // IsComplex w }, (2⁻¹ * Complex.I) := by
       refine Finset.prod_congr (Eq.refl _) (fun _ _ => ?_)
       field_simp; ring
   _ = (2⁻¹ * Complex.I) ^ Fintype.card {w : InfinitePlace K // IsComplex w} := by
feat: Minkowski Convex Body Theorem for compact convex body (#8274)
Diff
@@ -609,7 +609,7 @@ theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (con
     change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
     infer_instance
   obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
-    h_fund h (convexBodyLt_symmetric K f) (convexBodyLt_convex K f)
+    h_fund (convexBodyLt_symmetric K f) (convexBodyLt_convex K f) h
   rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
   refine ⟨⟨a, ha⟩, ?_, (convexBodyLt_mem K f).mp h_mem⟩
@@ -631,7 +631,7 @@ theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
     change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
     infer_instance
   obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
-    h_fund h (convexBodySum_symmetric K B) (convexBodySum_convex K B)
+    h_fund (convexBodySum_symmetric K B) (convexBodySum_convex K B) h
   rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
   obtain ⟨a, ha, rfl⟩ := hx
   refine ⟨⟨a, ha⟩, ?_, ?_⟩
feat: explicit volume computations in NumberTheory.NumberField.CanonicalEmbedding (#6886)

We compute the values of the volumes used in CanonicalEmbedding. In particular, we prove that

volume (fundamentalDomain (latticeBasis K)) =
       (2 : ℝ≥0∞)⁻¹ ^ (NrComplexPlaces K) * NNReal.sqrt ‖discr K‖₊

This will be useful later on to prove Hermite and Hermite-Minkowski theorems.

Diff
@@ -184,9 +184,9 @@ instance [NumberField K] :  Nontrivial (E K) := by
 protected theorem finrank [NumberField K] : finrank ℝ (E K) = finrank ℚ K := by
   classical
   rw [finrank_prod, finrank_pi, finrank_pi_fintype, Complex.finrank_real_complex, Finset.sum_const,
-    Finset.card_univ, ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm,
-    ← card_complex_embeddings, ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
-    Nat.add_sub_of_le (Fintype.card_subtype_le _)]
+    Finset.card_univ, ← NrRealPlaces, ← NrComplexPlaces, ← card_real_embeddings,
+    Algebra.id.smul_eq_mul, mul_comm, ← card_complex_embeddings, ← NumberField.Embeddings.card K ℂ,
+    Fintype.card_subtype_compl, Nat.add_sub_of_le (Fintype.card_subtype_le _)]
 
 theorem _root_.NumberField.mixedEmbedding_injective [NumberField K] :
     Function.Injective (NumberField.mixedEmbedding K) := by
@@ -249,6 +249,148 @@ theorem disjoint_span_commMap_ker [NumberField K] :
 
 end commMap
 
+noncomputable section stdBasis
+
+open Classical Complex MeasureTheory MeasureTheory.Measure Zspan Matrix BigOperators
+  ComplexConjugate
+
+variable [NumberField K]
+
+/-- The type indexing the basis `stdBasis`. -/
+abbrev index := {w : InfinitePlace K // IsReal w} ⊕ ({w : InfinitePlace K // IsComplex w}) × (Fin 2)
+
+/-- The `ℝ`-basis of `({w // IsReal w} → ℝ) × ({ w // IsComplex w } → ℂ)` formed by the vector
+equal to `1` at `w` and `0` elsewhere for `IsReal w` and by the couple of vectors equal to `1`
+(resp. `I`) at `w` and `0` elsewhere for `IsComplex w`. -/
+def stdBasis : Basis (index K) ℝ (E K) :=
+  Basis.prod (Pi.basisFun ℝ _)
+    (Basis.reindex (Pi.basis fun _ => basisOneI) (Equiv.sigmaEquivProd _ _))
+
+variable {K}
+
+@[simp]
+theorem stdBasis_apply_ofIsReal (x : E K) (w : {w : InfinitePlace K // IsReal w}) :
+    (stdBasis K).repr x (Sum.inl w) = x.1 w := rfl
+
+@[simp]
+theorem stdBasis_apply_ofIsComplex_fst (x : E K) (w : {w : InfinitePlace K // IsComplex w}) :
+    (stdBasis K).repr x (Sum.inr ⟨w, 0⟩) = (x.2 w).re := rfl
+
+@[simp]
+theorem stdBasis_apply_ofIsComplex_snd (x : E K) (w : {w : InfinitePlace K // IsComplex w}) :
+    (stdBasis K).repr x (Sum.inr ⟨w, 1⟩) = (x.2 w).im := rfl
+
+variable (K)
+
+theorem fundamentalDomain_stdBasis :
+    fundamentalDomain (stdBasis K) =
+        (Set.univ.pi fun _ => Set.Ico 0 1) ×ˢ
+        (Set.univ.pi fun _ => Complex.measurableEquivPi⁻¹' (Set.univ.pi fun _ => Set.Ico 0 1)) := by
+  ext
+  simp [stdBasis, mem_fundamentalDomain, Complex.measurableEquivPi]
+
+theorem volume_fundamentalDomain_stdBasis :
+    volume (fundamentalDomain (stdBasis K)) = 1 := by
+  rw [fundamentalDomain_stdBasis, volume_eq_prod, prod_prod, volume_pi, volume_pi, pi_pi, pi_pi,
+    Complex.volume_preserving_equiv_pi.measure_preimage ?_, volume_pi, pi_pi, Real.volume_Ico,
+    sub_zero, ENNReal.ofReal_one, Finset.prod_const_one, Finset.prod_const_one,
+    Finset.prod_const_one, one_mul]
+  exact MeasurableSet.pi Set.countable_univ (fun _ _ => measurableSet_Ico)
+
+/-- The `Equiv` between `index K` and `K →+* ℂ` defined by sending a real infinite place `w` to
+the unique corresponding embedding `w.embedding`, and the pair `⟨w, 0⟩` (resp. `⟨w, 1⟩`) for a
+complex infinite place `w` to `w.embedding` (resp. `conjugate w.embedding`). -/
+def indexEquiv : (index K) ≃ (K →+* ℂ) := by
+  refine Equiv.ofBijective (fun c => ?_)
+    ((Fintype.bijective_iff_surjective_and_card _).mpr ⟨?_, ?_⟩)
+  · cases c with
+    | inl w => exact w.val.embedding
+    | inr wj => rcases wj with ⟨w, j⟩
+                exact if j = 0 then w.val.embedding else ComplexEmbedding.conjugate w.val.embedding
+  · intro φ
+    by_cases hφ : ComplexEmbedding.IsReal φ
+    · exact ⟨Sum.inl (InfinitePlace.mkReal ⟨φ, hφ⟩), by simp [embedding_mk_eq_of_isReal hφ]⟩
+    · by_cases hw : (InfinitePlace.mk φ).embedding = φ
+      · exact ⟨Sum.inr ⟨InfinitePlace.mkComplex ⟨φ, hφ⟩, 0⟩, by simp [hw]⟩
+      · exact ⟨Sum.inr ⟨InfinitePlace.mkComplex ⟨φ, hφ⟩, 1⟩,
+          by simp [(embedding_mk_eq φ).resolve_left hw]⟩
+  · rw [Embeddings.card, ← mixedEmbedding.finrank K,
+      ← FiniteDimensional.finrank_eq_card_basis (stdBasis K)]
+
+variable {K}
+
+@[simp]
+theorem indexEquiv_apply_ofIsReal (w : {w : InfinitePlace K // IsReal w}) :
+    (indexEquiv K) (Sum.inl w) = w.val.embedding := rfl
+
+@[simp]
+theorem indexEquiv_apply_ofIsComplex_fst (w : {w : InfinitePlace K // IsComplex w}) :
+    (indexEquiv K) (Sum.inr ⟨w, 0⟩) = w.val.embedding := rfl
+
+@[simp]
+theorem indexEquiv_apply_ofIsComplex_snd (w : {w : InfinitePlace K // IsComplex w}) :
+    (indexEquiv K) (Sum.inr ⟨w, 1⟩) = ComplexEmbedding.conjugate w.val.embedding := rfl
+
+variable (K)
+
+/-- The matrix that gives the representation on `stdBasis` of the image by `commMap` of an
+element `x` of `(K →+* ℂ) → ℂ` fixed by the map `x_φ ↦ conj x_(conjugate φ)`,
+see `stdBasis_repr_eq_matrixToStdBasis_mul`. -/
+def matrixToStdBasis : Matrix (index K) (index K) ℂ :=
+  fromBlocks (diagonal fun _ => 1) 0 0 <| reindex (Equiv.prodComm _ _) (Equiv.prodComm _ _)
+    (blockDiagonal (fun _ => (2 : ℂ)⁻¹ • !![1, 1; - I, I]))
+
+theorem det_matrixToStdBasis :
+    (matrixToStdBasis K).det = (2⁻¹ * I) ^ NrComplexPlaces K :=
+  calc
+  _ = ∏ k : { w : InfinitePlace K // IsComplex w }, det ((2 : ℂ)⁻¹ • !![1, 1; -I, I]) := by
+      rw [matrixToStdBasis, det_fromBlocks_zero₂₁, det_diagonal, Finset.prod_const_one, one_mul,
+          det_reindex_self, det_blockDiagonal]
+  _ = ∏ k : { w : InfinitePlace K // IsComplex w }, (2⁻¹ * Complex.I) := by
+      refine Finset.prod_congr (Eq.refl _) (fun _ _ => ?_)
+      field_simp; ring
+  _ = (2⁻¹ * Complex.I) ^ Fintype.card {w : InfinitePlace K // IsComplex w} := by
+      rw [Finset.prod_const, Fintype.card]
+
+/-- Let `x : (K →+* ℂ) → ℂ` such that `x_φ = conj x_(conj φ)` for all `φ : K →+* ℂ`, then the
+representation of `commMap K x` on `stdBasis` is given (up to reindexing) by the product of
+`matrixToStdBasis` by `x`. -/
+theorem stdBasis_repr_eq_matrixToStdBasis_mul (x : (K →+* ℂ) → ℂ)
+    (hx : ∀ φ, conj (x φ) = x (ComplexEmbedding.conjugate φ)) (c : index K) :
+    ((stdBasis K).repr (commMap K x) c : ℂ) =
+      (mulVec (matrixToStdBasis K) (x ∘ (indexEquiv K))) c := by
+  simp_rw [commMap, matrixToStdBasis, LinearMap.coe_mk, AddHom.coe_mk,
+    mulVec, dotProduct, Function.comp_apply, index, Fintype.sum_sum_type,
+    diagonal_one, reindex_apply, ← Finset.univ_product_univ, Finset.sum_product,
+    indexEquiv_apply_ofIsReal, Fin.sum_univ_two, indexEquiv_apply_ofIsComplex_fst,
+    indexEquiv_apply_ofIsComplex_snd, smul_of, smul_cons, smul_eq_mul,
+    mul_one, smul_empty, Equiv.prodComm_symm, Equiv.coe_prodComm]
+  cases c with
+  | inl w =>
+      simp_rw [stdBasis_apply_ofIsReal, fromBlocks_apply₁₁, fromBlocks_apply₁₂,
+        one_apply, Matrix.zero_apply, ite_mul, one_mul, zero_mul, Finset.sum_ite_eq,
+        Finset.mem_univ, ite_true, add_zero, Finset.sum_const_zero, add_zero,
+        ← conj_eq_iff_re, hx (embedding w.val), conjugate_embedding_eq_of_isReal w.prop]
+  | inr c =>
+    rcases c with ⟨w, j⟩
+    fin_cases j
+    · simp_rw [Fin.mk_zero, stdBasis_apply_ofIsComplex_fst, fromBlocks_apply₂₁,
+        fromBlocks_apply₂₂, Matrix.zero_apply, submatrix_apply,
+        blockDiagonal_apply, Prod.swap_prod_mk, ite_mul, zero_mul, Finset.sum_const_zero,
+        zero_add, Finset.sum_add_distrib, Finset.sum_ite_eq, Finset.mem_univ, ite_true,
+        of_apply, cons_val', cons_val_zero, cons_val_one,
+        head_cons, ← hx (embedding w), re_eq_add_conj]
+      field_simp
+    · simp_rw [Fin.mk_one, stdBasis_apply_ofIsComplex_snd, fromBlocks_apply₂₁,
+        fromBlocks_apply₂₂, Matrix.zero_apply, submatrix_apply,
+        blockDiagonal_apply, Prod.swap_prod_mk, ite_mul, zero_mul, Finset.sum_const_zero,
+        zero_add, Finset.sum_add_distrib, Finset.sum_ite_eq, Finset.mem_univ, ite_true,
+        of_apply, cons_val', cons_val_zero, cons_val_one,
+        head_cons, ← hx (embedding w), im_eq_sub_conj]
+      ring_nf; field_simp
+
+end stdBasis
+
 section integerLattice
 
 open Module FiniteDimensional
@@ -267,8 +409,8 @@ noncomputable def latticeBasis [NumberField K] :
     refine basisOfLinearIndependentOfCardEqFinrank this ?_
     rw [← finrank_eq_card_chooseBasisIndex, RingOfIntegers.rank, finrank_prod, finrank_pi,
       finrank_pi_fintype, Complex.finrank_real_complex, Finset.sum_const, Finset.card_univ,
-      ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm, ← card_complex_embeddings,
-      ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
+      ← NrRealPlaces, ← NrComplexPlaces, ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm,
+      ← card_complex_embeddings, ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
       Nat.add_sub_of_le (Fintype.card_subtype_le _)]
 
 @[simp]
@@ -326,17 +468,16 @@ instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasur
 
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
 noncomputable abbrev convexBodyLtFactor : ℝ≥0∞ :=
-  (2 : ℝ≥0∞) ^ card {w : InfinitePlace K // IsReal w} *
-    volume (ball (0 : ℂ) 1) ^ card {w : InfinitePlace K // IsComplex w}
+  (2 : ℝ≥0∞) ^ NrRealPlaces K * (NNReal.pi : ℝ≥0∞) ^ NrComplexPlaces K
 
 theorem convexBodyLtFactor_pos : 0 < (convexBodyLtFactor K) := by
-  refine mul_pos (NeZero.ne _) ?_
-  exact ENNReal.pow_ne_zero (ne_of_gt (measure_ball_pos _ _ (by norm_num))) _
+  refine mul_pos (NeZero.ne _) (ENNReal.pow_ne_zero ?_ _)
+  exact ne_of_gt (coe_pos.mpr Real.pi_pos)
 
 theorem convexBodyLtFactor_lt_top : (convexBodyLtFactor K) < ⊤ := by
   refine mul_lt_top ?_ ?_
   · exact ne_of_lt (pow_lt_top (lt_top_iff_ne_top.mpr two_ne_top) _)
-  · exact ne_of_lt (pow_lt_top measure_ball_lt_top _)
+  · exact ne_of_lt (pow_lt_top coe_lt_top _)
 
 /-- The volume of `(ConvexBodyLt K f)` where `convexBodyLt K f` is the set of points `x`
 such that `‖x w‖ < f w` for all infinite places `w`. -/
@@ -344,18 +485,10 @@ theorem convexBodyLt_volume :
     volume (convexBodyLt K f) = (convexBodyLtFactor K) * ∏ w, (f w) ^ (mult w) := by
   calc
     _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
-          ∏ x : {w // InfinitePlace.IsComplex w}, volume (ball (0 : ℂ) 1) *
-            ENNReal.ofReal (f x.val) ^ 2 := by
-      simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball]
-      conv_lhs =>
-        congr; next => skip
-        congr; next => skip
-        ext i; rw [addHaar_ball _ _ (by exact (f i).prop), Complex.finrank_real_complex, mul_comm,
-          ENNReal.ofReal_pow (by exact (f i).prop)]
-    _ = (↑2 ^ card {w : InfinitePlace K // InfinitePlace.IsReal w} *
-          (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
-          (volume (ball (0 : ℂ) 1) ^ card {w : InfinitePlace K // IsComplex w} *
-          (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by
+          ∏ x : {w // InfinitePlace.IsComplex w}, pi * ENNReal.ofReal (f x.val) ^ 2 := by
+      simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball, Complex.volume_ball]
+    _ = (↑2 ^ NrRealPlaces K * (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
+          (↑pi ^ NrComplexPlaces K * (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by
       simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
         Finset.card_univ, ofReal_ofNat]
     _ = (convexBodyLtFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)) *
@@ -449,7 +582,9 @@ open scoped ENNReal NNReal
 variable [NumberField K]
 
 /-- The bound that appears in Minkowski Convex Body theorem, see
-`MeasureTheory.exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure`. -/
+`MeasureTheory.exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure`. See
+`NumberField.mixedEmbedding.volume_fundamentalDomain_latticeBasis` for the computation of
+`volume (fundamentalDomain (latticeBasis K))`. -/
 noncomputable def minkowskiBound : ℝ≥0∞ :=
   volume (fundamentalDomain (latticeBasis K)) * (2:ℝ≥0∞) ^ (finrank ℝ (E K))
 
@@ -460,6 +595,8 @@ theorem minkowskiBound_lt_top : minkowskiBound K < ⊤ := by
 
 variable {f : InfinitePlace K → ℝ≥0}
 
+instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasure volume volume
+
 /-- Assume that `f : InfinitePlace K → ℝ≥0` is such that
 `minkowskiBound K < volume (convexBodyLt K f)` where `convexBodyLt K f` is the set of
 points `x` such that `‖x w‖ < f w` for all infinite places `w` (see `convexBodyLt_volume` for
feat: use Minkowski's theorem to prove the existence of algebraic integers of small norm (#8128)

We define the convex body convexBodySum and prove the following

theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
     (h : (minkowskiBound K) < volume (convexBodySum K B)) :
     ∃ (a : 𝓞 K), a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ ((finrank ℚ K : ℝ)⁻¹ * B) ^ (finrank ℚ K) 

Computation of the volume (convexBodySum K B)) and applications of the result are coming in a following PR.

Diff
@@ -3,11 +3,10 @@ Copyright (c) 2022 Xavier Roblot. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 -/
+import Mathlib.RingTheory.Discriminant
 import Mathlib.Algebra.Module.Zlattice
 import Mathlib.MeasureTheory.Group.GeometryOfNumbers
-import Mathlib.MeasureTheory.Measure.Haar.NormedSpace
 import Mathlib.NumberTheory.NumberField.Embeddings
-import Mathlib.RingTheory.Discriminant
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
 
@@ -21,28 +20,30 @@ into the type `(K →+* ℂ) → ℂ` of `ℂ`-vectors indexed by the complex em
 
 ## Main definitions and results
 
-* `canonicalEmbedding`: the ring homorphism `K →+* ((K →+* ℂ) → ℂ)` defined by sending `x : K` to
-the vector `(φ x)` indexed by `φ : K →+* ℂ`.
+* `NumberField.canonicalEmbedding`: the ring homorphism `K →+* ((K →+* ℂ) → ℂ)` defined by
+sending `x : K` to the vector `(φ x)` indexed by `φ : K →+* ℂ`.
 
-* `canonicalEmbedding.integerLattice.inter_ball_finite`: the intersection of the
+* `NumberField.canonicalEmbedding.integerLattice.inter_ball_finite`: the intersection of the
 image of the ring of integers by the canonical embedding and any ball centered at `0` of finite
 radius is finite.
 
-* `mixedEmbedding`: the ring homomorphism from `K →+* ({ w // IsReal w } → ℝ) ×
+* `NumberField.mixedEmbedding`: the ring homomorphism from `K →+* ({ w // IsReal w } → ℝ) ×
 ({ w // IsComplex w } → ℂ)` that sends `x ∈ K` to `(φ_w x)_w` where `φ_w` is the embedding
 associated to the infinite place `w`. In particular, if `w` is real then `φ_w : K →+* ℝ` and, if
 `w` is complex, `φ_w` is an arbitrary choice between the two complex embeddings defining the place
 `w`.
 
-* `exists_ne_zero_mem_ringOfIntegers_lt`: let `f : InfinitePlace K → ℝ≥0`, if the product
-`∏ w, f w` is large enough, then there exists a nonzero algebraic integer `a` in `K` such that
-`w a < f w` for all infinite places `w`.
+* `NumberField.mixedEmbedding.exists_ne_zero_mem_ringOfIntegers_lt`: let
+`f : InfinitePlace K → ℝ≥0`, if the product `∏ w, f w` is large enough, then there exists a
+nonzero algebraic integer `a` in `K` such that `w a < f w` for all infinite places `w`.
 
 ## Tags
 
 number field, infinite places
 -/
 
+local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
+
 variable (K : Type*) [Field K]
 
 namespace NumberField.canonicalEmbedding
@@ -161,7 +162,7 @@ end NumberField.canonicalEmbedding
 
 namespace NumberField.mixedEmbedding
 
-open NumberField NumberField.InfinitePlace NumberField.ComplexEmbedding FiniteDimensional
+open NumberField NumberField.InfinitePlace FiniteDimensional
 
 /-- The space `ℝ^r₁ × ℂ^r₂` with `(r₁, r₂)` the signature of `K`. -/
 local notation "E" K =>
@@ -231,7 +232,7 @@ theorem disjoint_span_commMap_ker [NumberField K] :
     exact ⟨integralBasis K i, (canonicalEmbedding.latticeBasis_apply K i).symm⟩
   ext1 φ
   rw [Pi.zero_apply]
-  by_cases hφ : IsReal φ
+  by_cases hφ : ComplexEmbedding.IsReal φ
   · rw [show x φ = (x φ).re by
       rw [eq_comm, ← Complex.conj_eq_iff_re, canonicalEmbedding.conj_apply _ h_mem,
         ComplexEmbedding.isReal_iff.mp hφ], ← Complex.ofReal_zero]
@@ -319,11 +320,10 @@ theorem convexBodyLt_convex : Convex ℝ (convexBodyLt K f) :=
 
 open Classical Fintype MeasureTheory MeasureTheory.Measure BigOperators
 
--- See: https://github.com/leanprover/lean4/issues/2220
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y)
-
 variable [NumberField K]
 
+instance : IsAddHaarMeasure (volume : Measure (E K)) := prod.instIsAddHaarMeasure volume volume
+
 /-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
 noncomputable abbrev convexBodyLtFactor : ℝ≥0∞ :=
   (2 : ℝ≥0∞) ^ card {w : InfinitePlace K // IsReal w} *
@@ -389,21 +389,74 @@ theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁
 
 end convexBodyLt
 
+section convexBodySum
+
+open ENNReal BigOperators Classical MeasureTheory Fintype
+
+variable [NumberField K] (B : ℝ)
+
+/-- The convex body equal to the set of points `x : E` such that
+  `∑ w real, ‖x w‖ + 2 * ∑ w complex, ‖x w‖ ≤ B`. -/
+abbrev convexBodySum : Set (E K)  := { x | ∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖ ≤ B }
+
+theorem convexBodySum_empty {B} (h : B < 0) : convexBodySum K B = ∅ := by
+  ext x
+  refine ⟨fun hx => ?_, fun h => h.elim⟩
+  · rw [Set.mem_setOf] at hx
+    have : 0 ≤ ∑ w, ‖x.1 w‖ + 2 * ∑ w, ‖x.2 w‖ := by
+      refine add_nonneg ?_ ?_
+      · exact Finset.sum_nonneg (fun _ _ => norm_nonneg _)
+      · exact mul_nonneg zero_le_two (Finset.sum_nonneg (fun _ _ => norm_nonneg _))
+    linarith
+
+theorem convexBodySum_mem {x : K} :
+    mixedEmbedding K x ∈ (convexBodySum K B) ↔
+      ∑ w : InfinitePlace K, (mult w) * w.val x ≤ B := by
+  simp_rw [Set.mem_setOf_eq, mixedEmbedding, RingHom.prod_apply, Pi.ringHom_apply,
+    ← Complex.norm_real, embedding_of_isReal_apply, norm_embedding_eq, mult, Nat.cast_ite, ite_mul,
+    Finset.sum_ite, Finset.filter_congr (fun _ _ => not_isReal_iff_isComplex), Finset.mul_sum,
+    ← Finset.sum_subtype_eq_sum_filter, Finset.subtype_univ, Nat.cast_one, one_mul, Nat.cast_ofNat]
+  rfl
+
+theorem convexBodySum_symmetric (x : E K) (hx : x ∈ (convexBodySum K B)) :
+    -x ∈ (convexBodySum K B) := by
+  simp_rw [Set.mem_setOf_eq, Prod.fst_neg, Prod.snd_neg, Pi.neg_apply, norm_neg]
+  exact hx
+
+theorem convexBodySum_convex : Convex ℝ (convexBodySum K B) := by
+  refine Convex_subadditive_le ?_ ?_ B
+  · intro x y
+    simp_rw [Prod.fst_add, Pi.add_apply, Prod.snd_add]
+    refine le_trans (add_le_add
+      (Finset.sum_le_sum (fun w _ => norm_add_le (x.1 w) (y.1 w)))
+      (mul_le_mul_of_nonneg_left
+        (Finset.sum_le_sum (fun w _ => norm_add_le (x.2 w) (y.2 w))) (by norm_num))) ?_
+    simp_rw [Finset.sum_add_distrib, mul_add]
+    exact le_of_eq (by ring)
+  · intro _ _ h
+    simp_rw [Prod.smul_fst, Prod.smul_snd, Pi.smul_apply, smul_eq_mul, Complex.real_smul, norm_mul,
+      Complex.norm_real, Real.norm_of_nonneg h, ← Finset.mul_sum]
+    exact le_of_eq (by ring)
+
+end convexBodySum
+
 section minkowski
 
-open MeasureTheory MeasureTheory.Measure Classical NNReal ENNReal FiniteDimensional Zspan
+open MeasureTheory MeasureTheory.Measure Classical FiniteDimensional Zspan Real
+
+open scoped ENNReal NNReal
 
 variable [NumberField K]
 
 /-- The bound that appears in Minkowski Convex Body theorem, see
 `MeasureTheory.exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure`. -/
 noncomputable def minkowskiBound : ℝ≥0∞ :=
-  volume (fundamentalDomain (latticeBasis K)) * 2 ^ (finrank ℝ (E K))
+  volume (fundamentalDomain (latticeBasis K)) * (2:ℝ≥0∞) ^ (finrank ℝ (E K))
 
 theorem minkowskiBound_lt_top : minkowskiBound K < ⊤ := by
-  refine mul_lt_top ?_ ?_
+  refine ENNReal.mul_lt_top ?_ ?_
   · exact ne_of_lt (fundamentalDomain_isBounded (latticeBasis K)).measure_lt_top
-  · exact ne_of_lt (pow_lt_top (lt_top_iff_ne_top.mpr two_ne_top) _)
+  · exact ne_of_lt (ENNReal.pow_lt_top (lt_top_iff_ne_top.mpr ENNReal.two_ne_top) _)
 
 variable {f : InfinitePlace K → ℝ≥0}
 
@@ -414,7 +467,6 @@ the computation of this volume), then there exists a nonzero algebraic integer `
 that `w a < f w` for all infinite places `w`. -/
 theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (convexBodyLt K f)) :
     ∃ (a : 𝓞 K), a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
-  have : @IsAddHaarMeasure (E K) _ _ _ volume := prod.instIsAddHaarMeasure volume volume
   have h_fund := Zspan.isAddFundamentalDomain (latticeBasis K) volume
   have : Countable (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
     change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
@@ -427,6 +479,39 @@ theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (con
   rw [ne_eq, AddSubgroup.mk_eq_zero_iff, map_eq_zero, ← ne_eq] at h_nzr
   exact Subtype.ne_of_val_ne h_nzr
 
+theorem exists_ne_zero_mem_ringOfIntegers_of_norm_le {B : ℝ}
+    (h : (minkowskiBound K) < volume (convexBodySum K B)) :
+    ∃ (a : 𝓞 K), a ≠ 0 ∧ |Algebra.norm ℚ (a:K)| ≤ (B / (finrank ℚ K)) ^ (finrank ℚ K) := by
+  have hB : 0 ≤ B := by
+    contrapose! h
+    rw [convexBodySum_empty K h, measure_empty]
+    exact zero_le (minkowskiBound K)
+  -- Some inequalities that will be useful later on
+  have h1 : 0 < (finrank ℚ K : ℝ)⁻¹ := inv_pos.mpr (Nat.cast_pos.mpr finrank_pos)
+  have h2 : 0 ≤ B / (finrank ℚ K) := div_nonneg hB (Nat.cast_nonneg _)
+  have h_fund := Zspan.isAddFundamentalDomain (latticeBasis K) volume
+  have : Countable (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
+    change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
+    infer_instance
+  obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
+    h_fund h (convexBodySum_symmetric K B) (convexBodySum_convex K B)
+  rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
+  obtain ⟨a, ha, rfl⟩ := hx
+  refine ⟨⟨a, ha⟩, ?_, ?_⟩
+  · rw [ne_eq, AddSubgroup.mk_eq_zero_iff, map_eq_zero, ← ne_eq] at h_nzr
+    exact Subtype.ne_of_val_ne h_nzr
+  · rw [← rpow_nat_cast, ← rpow_le_rpow_iff (by simp only [Rat.cast_abs, abs_nonneg])
+      (rpow_nonneg_of_nonneg h2 _) h1, ← rpow_mul h2,  mul_inv_cancel (Nat.cast_ne_zero.mpr
+      (ne_of_gt finrank_pos)), rpow_one, le_div_iff' (Nat.cast_pos.mpr finrank_pos)]
+    refine le_trans ?_ ((convexBodySum_mem K B).mp h_mem)
+    rw [← le_div_iff' (Nat.cast_pos.mpr finrank_pos), ← sum_mult_eq, Nat.cast_sum]
+    refine le_trans ?_ (geom_mean_le_arith_mean Finset.univ _ _ (fun _ _ => Nat.cast_nonneg _)
+      ?_ (fun _ _ => AbsoluteValue.nonneg _ _))
+    · simp_rw [← prod_eq_abs_norm, rpow_nat_cast]
+      exact le_of_eq rfl
+    · rw [← Nat.cast_sum, sum_mult_eq, Nat.cast_pos]
+      exact finrank_pos
+
 end minkowski
 
 end NumberField.mixedEmbedding
chore: fix whitespace typos (#7950)
Diff
@@ -221,7 +221,7 @@ theorem commMap_canonical_eq_mixed (x : K) :
 /-- This is a technical result to ensure that the image of the `ℂ`-basis of `ℂ^n` defined in
 `canonicalEmbedding.latticeBasis` is a `ℝ`-basis of `ℝ^r₁ × ℂ^r₂`,
 see `mixedEmbedding.latticeBasis`. -/
-theorem disjoint_span_commMap_ker [NumberField K]:
+theorem disjoint_span_commMap_ker [NumberField K] :
     Disjoint (Submodule.span ℝ (Set.range (canonicalEmbedding.latticeBasis K)))
       (LinearMap.ker (commMap K)) := by
   refine LinearMap.disjoint_ker.mpr (fun x h_mem h_zero => ?_)
feat(NumberTheory.NumberField.Units): proof of Dirichlet's unit theorem (#5960)

We prove Dirichlet's unit theorem. More precisely, the main results are:

def basisModTorsion : Basis (Fin (Units.rank K)) ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K)))

where Units.rank := Fintype.card (InfinitePlace K) - 1 and

theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K) (e : Fin (Units.rank K) → ℤ),
    x = ζ * ∏ i, (fundSystem K i) ^ (e i)

where fundSystem : Fin (rank K) → (𝓞 K)ˣ is a fundamental system of units.

The exponents in exist_unique_eq_mul_prod can be computed via the following result:

theorem fun_eq_repr {x ζ : (𝓞 K)ˣ} {f : Fin (rank K) → ℤ} (hζ : ζ ∈ torsion K) 
    (h : x = ζ * ∏ i, (fundSystem K i) ^ (f i)) : f = (basisModTorsion K).repr (Additive.ofMul ↑x)
Diff
@@ -329,7 +329,7 @@ noncomputable abbrev convexBodyLtFactor : ℝ≥0∞ :=
   (2 : ℝ≥0∞) ^ card {w : InfinitePlace K // IsReal w} *
     volume (ball (0 : ℂ) 1) ^ card {w : InfinitePlace K // IsComplex w}
 
-theorem convexBodyLtFactor_lt_pos : 0 < (convexBodyLtFactor K) := by
+theorem convexBodyLtFactor_pos : 0 < (convexBodyLtFactor K) := by
   refine mul_pos (NeZero.ne _) ?_
   exact ENNReal.pow_ne_zero (ne_of_gt (measure_ball_pos _ _ (by norm_num))) _
 
chore: only four spaces for subsequent lines (#7286)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -206,10 +206,10 @@ noncomputable def commMap : ((K →+* ℂ) → ℂ) →ₗ[ℝ] (E K) :=
     exact fun _ _ => ⟨rfl, rfl⟩ }
 
 theorem commMap_apply_of_isReal (x : (K →+* ℂ) → ℂ) {w : InfinitePlace K} (hw : IsReal w) :
-  (commMap K x).1 ⟨w, hw⟩ = (x w.embedding).re := rfl
+    (commMap K x).1 ⟨w, hw⟩ = (x w.embedding).re := rfl
 
 theorem commMap_apply_of_isComplex (x : (K →+* ℂ) → ℂ) {w : InfinitePlace K} (hw : IsComplex w) :
-  (commMap K x).2 ⟨w, hw⟩ = x w.embedding := rfl
+    (commMap K x).2 ⟨w, hw⟩ = x w.embedding := rfl
 
 @[simp]
 theorem commMap_canonical_eq_mixed (x : K) :
feat(NumberTheory.NumberField.CanonicalEmbedding): add exists_ne_zero_mem_ringOfIntegers_lt (#5650)

This PR proves the following result:

theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowski_bound K < volume (convex_body_lt K f)) :
     ∃ (a : 𝓞 K), a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w 

where f : InfinitePlace K → ℝ≥0 and convex_body_lt K f is the set of points x such that ‖x w‖ < f w for all infinite places w. This is a key result in the proof of Dirichlet's unit theorem #5960

Diff
@@ -3,6 +3,9 @@ Copyright (c) 2022 Xavier Roblot. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 -/
+import Mathlib.Algebra.Module.Zlattice
+import Mathlib.MeasureTheory.Group.GeometryOfNumbers
+import Mathlib.MeasureTheory.Measure.Haar.NormedSpace
 import Mathlib.NumberTheory.NumberField.Embeddings
 import Mathlib.RingTheory.Discriminant
 
@@ -25,6 +28,16 @@ the vector `(φ x)` indexed by `φ : K →+* ℂ`.
 image of the ring of integers by the canonical embedding and any ball centered at `0` of finite
 radius is finite.
 
+* `mixedEmbedding`: the ring homomorphism from `K →+* ({ w // IsReal w } → ℝ) ×
+({ w // IsComplex w } → ℂ)` that sends `x ∈ K` to `(φ_w x)_w` where `φ_w` is the embedding
+associated to the infinite place `w`. In particular, if `w` is real then `φ_w : K →+* ℝ` and, if
+`w` is complex, `φ_w` is an arbitrary choice between the two complex embeddings defining the place
+`w`.
+
+* `exists_ne_zero_mem_ringOfIntegers_lt`: let `f : InfinitePlace K → ℝ≥0`, if the product
+`∏ w, f w` is large enough, then there exists a nonzero algebraic integer `a` in `K` such that
+`w a < f w` for all infinite places `w`.
+
 ## Tags
 
 number field, infinite places
@@ -145,3 +158,275 @@ theorem mem_span_latticeBasis [NumberField K] (x : (K →+* ℂ) → ℂ) :
   rfl
 
 end NumberField.canonicalEmbedding
+
+namespace NumberField.mixedEmbedding
+
+open NumberField NumberField.InfinitePlace NumberField.ComplexEmbedding FiniteDimensional
+
+/-- The space `ℝ^r₁ × ℂ^r₂` with `(r₁, r₂)` the signature of `K`. -/
+local notation "E" K =>
+  ({w : InfinitePlace K // IsReal w} → ℝ) × ({w : InfinitePlace K // IsComplex w} → ℂ)
+
+/-- The mixed embedding of a number field `K` of signature `(r₁, r₂)` into `ℝ^r₁ × ℂ^r₂`. -/
+noncomputable def _root_.NumberField.mixedEmbedding : K →+* (E K) :=
+  RingHom.prod (Pi.ringHom fun w => embedding_of_isReal w.prop)
+    (Pi.ringHom fun w => w.val.embedding)
+
+instance [NumberField K] :  Nontrivial (E K) := by
+  obtain ⟨w⟩ := (inferInstance : Nonempty (InfinitePlace K))
+  obtain hw | hw := w.isReal_or_isComplex
+  · have : Nonempty {w : InfinitePlace K // IsReal w} := ⟨⟨w, hw⟩⟩
+    exact nontrivial_prod_left
+  · have : Nonempty {w : InfinitePlace K // IsComplex w} := ⟨⟨w, hw⟩⟩
+    exact nontrivial_prod_right
+
+protected theorem finrank [NumberField K] : finrank ℝ (E K) = finrank ℚ K := by
+  classical
+  rw [finrank_prod, finrank_pi, finrank_pi_fintype, Complex.finrank_real_complex, Finset.sum_const,
+    Finset.card_univ, ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm,
+    ← card_complex_embeddings, ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
+    Nat.add_sub_of_le (Fintype.card_subtype_le _)]
+
+theorem _root_.NumberField.mixedEmbedding_injective [NumberField K] :
+    Function.Injective (NumberField.mixedEmbedding K) := by
+  exact RingHom.injective _
+
+section commMap
+
+/-- The linear map that makes `canonicalEmbedding` and `mixedEmbedding` commute, see
+`commMap_canonical_eq_mixed`. -/
+noncomputable def commMap : ((K →+* ℂ) → ℂ) →ₗ[ℝ] (E K) :=
+{ toFun := fun x => ⟨fun w => (x w.val.embedding).re, fun w => x w.val.embedding⟩
+  map_add' := by
+    simp only [Pi.add_apply, Complex.add_re, Prod.mk_add_mk, Prod.mk.injEq]
+    exact fun _ _ => ⟨rfl, rfl⟩
+  map_smul' := by
+    simp only [Pi.smul_apply, Complex.real_smul, Complex.mul_re, Complex.ofReal_re,
+      Complex.ofReal_im, zero_mul, sub_zero, RingHom.id_apply, Prod.smul_mk, Prod.mk.injEq]
+    exact fun _ _ => ⟨rfl, rfl⟩ }
+
+theorem commMap_apply_of_isReal (x : (K →+* ℂ) → ℂ) {w : InfinitePlace K} (hw : IsReal w) :
+  (commMap K x).1 ⟨w, hw⟩ = (x w.embedding).re := rfl
+
+theorem commMap_apply_of_isComplex (x : (K →+* ℂ) → ℂ) {w : InfinitePlace K} (hw : IsComplex w) :
+  (commMap K x).2 ⟨w, hw⟩ = x w.embedding := rfl
+
+@[simp]
+theorem commMap_canonical_eq_mixed (x : K) :
+    commMap K (canonicalEmbedding K x) = mixedEmbedding K x := by
+  simp only [canonicalEmbedding, commMap, LinearMap.coe_mk, AddHom.coe_mk, Pi.ringHom_apply,
+    mixedEmbedding, RingHom.prod_apply, Prod.mk.injEq]
+  exact ⟨rfl, rfl⟩
+
+/-- This is a technical result to ensure that the image of the `ℂ`-basis of `ℂ^n` defined in
+`canonicalEmbedding.latticeBasis` is a `ℝ`-basis of `ℝ^r₁ × ℂ^r₂`,
+see `mixedEmbedding.latticeBasis`. -/
+theorem disjoint_span_commMap_ker [NumberField K]:
+    Disjoint (Submodule.span ℝ (Set.range (canonicalEmbedding.latticeBasis K)))
+      (LinearMap.ker (commMap K)) := by
+  refine LinearMap.disjoint_ker.mpr (fun x h_mem h_zero => ?_)
+  replace h_mem : x ∈ Submodule.span ℝ (Set.range (canonicalEmbedding K)) := by
+    refine (Submodule.span_mono ?_) h_mem
+    rintro _ ⟨i, rfl⟩
+    exact ⟨integralBasis K i, (canonicalEmbedding.latticeBasis_apply K i).symm⟩
+  ext1 φ
+  rw [Pi.zero_apply]
+  by_cases hφ : IsReal φ
+  · rw [show x φ = (x φ).re by
+      rw [eq_comm, ← Complex.conj_eq_iff_re, canonicalEmbedding.conj_apply _ h_mem,
+        ComplexEmbedding.isReal_iff.mp hφ], ← Complex.ofReal_zero]
+    congr
+    rw [← embedding_mk_eq_of_isReal hφ, ← commMap_apply_of_isReal K x ⟨φ, hφ, rfl⟩]
+    exact congrFun (congrArg (fun x => x.1) h_zero) ⟨InfinitePlace.mk φ, _⟩
+  · have := congrFun (congrArg (fun x => x.2) h_zero) ⟨InfinitePlace.mk φ, ⟨φ, hφ, rfl⟩⟩
+    cases embedding_mk_eq φ with
+    | inl h => rwa [← h, ← commMap_apply_of_isComplex K x ⟨φ, hφ, rfl⟩]
+    | inr h =>
+        apply RingHom.injective (starRingEnd ℂ)
+        rwa [canonicalEmbedding.conj_apply _ h_mem, ← h, map_zero,
+          ← commMap_apply_of_isComplex K x ⟨φ, hφ, rfl⟩]
+
+end commMap
+
+section integerLattice
+
+open Module FiniteDimensional
+
+/-- A `ℝ`-basis of `ℝ^r₁ × ℂ^r₂` that is also a `ℤ`-basis of the image of `𝓞 K`. -/
+noncomputable def latticeBasis [NumberField K] :
+    Basis (Free.ChooseBasisIndex ℤ (𝓞 K)) ℝ (E K) := by
+  classical
+    -- We construct an `ℝ`-linear independent family from the image of
+    -- `canonicalEmbedding.lattice_basis` by `comm_map`
+    have := LinearIndependent.map (LinearIndependent.restrict_scalars
+      (by { simpa only [Complex.real_smul, mul_one] using Complex.ofReal_injective })
+      (canonicalEmbedding.latticeBasis K).linearIndependent)
+      (disjoint_span_commMap_ker K)
+    -- and it's a basis since it has the right cardinality
+    refine basisOfLinearIndependentOfCardEqFinrank this ?_
+    rw [← finrank_eq_card_chooseBasisIndex, RingOfIntegers.rank, finrank_prod, finrank_pi,
+      finrank_pi_fintype, Complex.finrank_real_complex, Finset.sum_const, Finset.card_univ,
+      ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm, ← card_complex_embeddings,
+      ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
+      Nat.add_sub_of_le (Fintype.card_subtype_le _)]
+
+@[simp]
+theorem latticeBasis_apply [NumberField K] (i : Free.ChooseBasisIndex ℤ (𝓞 K)) :
+    latticeBasis K i = (mixedEmbedding K) (integralBasis K i) := by
+  simp only [latticeBasis, coe_basisOfLinearIndependentOfCardEqFinrank, Function.comp_apply,
+    canonicalEmbedding.latticeBasis_apply, integralBasis_apply, commMap_canonical_eq_mixed]
+
+theorem mem_span_latticeBasis [NumberField K] (x : (E K)) :
+    x ∈ Submodule.span ℤ (Set.range (latticeBasis K)) ↔ x ∈ mixedEmbedding K '' (𝓞 K) := by
+  rw [show Set.range (latticeBasis K) =
+      (mixedEmbedding K).toIntAlgHom.toLinearMap '' (Set.range (integralBasis K)) by
+    rw [← Set.range_comp]; exact congrArg Set.range (funext (fun i => latticeBasis_apply K i))]
+  rw [← Submodule.map_span, ← SetLike.mem_coe, Submodule.map_coe]
+  rw [show (Submodule.span ℤ (Set.range (integralBasis K)) : Set K) = 𝓞 K by
+    ext; exact mem_span_integralBasis K]
+  rfl
+
+end integerLattice
+
+section convexBodyLt
+
+open Metric ENNReal NNReal
+
+variable (f : InfinitePlace K → ℝ≥0)
+
+/-- The convex body defined by `f`: the set of points `x : E` such that `‖x w‖ < f w` for all
+infinite places `w`. -/
+abbrev convexBodyLt : Set (E K) :=
+  (Set.univ.pi (fun w : { w : InfinitePlace K // IsReal w } => ball 0 (f w))) ×ˢ
+  (Set.univ.pi (fun w : { w : InfinitePlace K // IsComplex w } => ball 0 (f w)))
+
+theorem convexBodyLt_mem {x : K} :
+    mixedEmbedding K x ∈ (convexBodyLt K f) ↔ ∀ w : InfinitePlace K, w x < f w := by
+  simp_rw [mixedEmbedding, RingHom.prod_apply, Set.mem_prod, Set.mem_pi, Set.mem_univ,
+    forall_true_left, mem_ball_zero_iff, Pi.ringHom_apply, ← Complex.norm_real,
+    embedding_of_isReal_apply, Subtype.forall, ← ball_or_left, ← not_isReal_iff_isComplex, em,
+    forall_true_left, norm_embedding_eq]
+
+theorem convexBodyLt_symmetric (x : E K) (hx : x ∈ (convexBodyLt K f)) :
+    -x ∈ (convexBodyLt K f) := by
+  simp only [Set.mem_prod, Prod.fst_neg, Set.mem_pi, Set.mem_univ, Pi.neg_apply,
+    mem_ball_zero_iff, norm_neg, Real.norm_eq_abs, forall_true_left, Subtype.forall,
+    Prod.snd_neg, Complex.norm_eq_abs, hx] at hx ⊢
+  exact hx
+
+theorem convexBodyLt_convex : Convex ℝ (convexBodyLt K f) :=
+  Convex.prod (convex_pi (fun _ _ => convex_ball _ _)) (convex_pi (fun _ _ => convex_ball _ _))
+
+open Classical Fintype MeasureTheory MeasureTheory.Measure BigOperators
+
+-- See: https://github.com/leanprover/lean4/issues/2220
+local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y)
+
+variable [NumberField K]
+
+/-- The fudge factor that appears in the formula for the volume of `convexBodyLt`. -/
+noncomputable abbrev convexBodyLtFactor : ℝ≥0∞ :=
+  (2 : ℝ≥0∞) ^ card {w : InfinitePlace K // IsReal w} *
+    volume (ball (0 : ℂ) 1) ^ card {w : InfinitePlace K // IsComplex w}
+
+theorem convexBodyLtFactor_lt_pos : 0 < (convexBodyLtFactor K) := by
+  refine mul_pos (NeZero.ne _) ?_
+  exact ENNReal.pow_ne_zero (ne_of_gt (measure_ball_pos _ _ (by norm_num))) _
+
+theorem convexBodyLtFactor_lt_top : (convexBodyLtFactor K) < ⊤ := by
+  refine mul_lt_top ?_ ?_
+  · exact ne_of_lt (pow_lt_top (lt_top_iff_ne_top.mpr two_ne_top) _)
+  · exact ne_of_lt (pow_lt_top measure_ball_lt_top _)
+
+/-- The volume of `(ConvexBodyLt K f)` where `convexBodyLt K f` is the set of points `x`
+such that `‖x w‖ < f w` for all infinite places `w`. -/
+theorem convexBodyLt_volume :
+    volume (convexBodyLt K f) = (convexBodyLtFactor K) * ∏ w, (f w) ^ (mult w) := by
+  calc
+    _ = (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (2 * (f x.val))) *
+          ∏ x : {w // InfinitePlace.IsComplex w}, volume (ball (0 : ℂ) 1) *
+            ENNReal.ofReal (f x.val) ^ 2 := by
+      simp_rw [volume_eq_prod, prod_prod, volume_pi, pi_pi, Real.volume_ball]
+      conv_lhs =>
+        congr; next => skip
+        congr; next => skip
+        ext i; rw [addHaar_ball _ _ (by exact (f i).prop), Complex.finrank_real_complex, mul_comm,
+          ENNReal.ofReal_pow (by exact (f i).prop)]
+    _ = (↑2 ^ card {w : InfinitePlace K // InfinitePlace.IsReal w} *
+          (∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val))) *
+          (volume (ball (0 : ℂ) 1) ^ card {w : InfinitePlace K // IsComplex w} *
+          (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by
+      simp_rw [ofReal_mul (by norm_num : 0 ≤ (2 : ℝ)), Finset.prod_mul_distrib, Finset.prod_const,
+        Finset.card_univ, ofReal_ofNat]
+    _ = (convexBodyLtFactor K) * ((∏ x : {w // InfinitePlace.IsReal w}, ENNReal.ofReal (f x.val)) *
+        (∏ x : {w // IsComplex w}, ENNReal.ofReal (f x.val) ^ 2)) := by ring
+    _ = (convexBodyLtFactor K) * ∏ w, (f w) ^ (mult w) := by
+      simp_rw [mult, pow_ite, pow_one, Finset.prod_ite, ofReal_coe_nnreal, not_isReal_iff_isComplex,
+        coe_mul, coe_finset_prod, ENNReal.coe_pow]
+      congr 2
+      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞))).symm
+        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
+      · refine (Finset.prod_subtype (Finset.univ.filter _) ?_ (fun w => (f w : ℝ≥0∞) ^ 2)).symm
+        exact fun _ => by simp only [Finset.mem_univ, forall_true_left, Finset.mem_filter, true_and]
+
+variable {f}
+
+/-- This is a technical result: quite often, we want to impose conditions at all infinite places
+but one and choose the value at the remaining place so that we can apply
+`exists_ne_zero_mem_ringOfIntegers_lt`. -/
+theorem adjust_f {w₁ : InfinitePlace K} (B : ℝ≥0) (hf : ∀ w, w ≠ w₁→ f w ≠ 0) :
+    ∃ g : InfinitePlace K → ℝ≥0, (∀ w, w ≠ w₁ → g w = f w) ∧ ∏ w, (g w) ^ mult w = B := by
+  let S := ∏ w in Finset.univ.erase w₁, (f w) ^ mult w
+  refine ⟨Function.update f w₁ ((B * S⁻¹) ^ (mult w₁ : ℝ)⁻¹), ?_, ?_⟩
+  · exact fun w hw => Function.update_noteq hw _ f
+  · rw [← Finset.mul_prod_erase Finset.univ _ (Finset.mem_univ w₁), Function.update_same,
+      Finset.prod_congr rfl fun w hw => by rw [Function.update_noteq (Finset.ne_of_mem_erase hw)],
+      ← NNReal.rpow_nat_cast, ← NNReal.rpow_mul, inv_mul_cancel, NNReal.rpow_one, mul_assoc,
+      inv_mul_cancel, mul_one]
+    · rw [Finset.prod_ne_zero_iff]
+      exact fun w hw => pow_ne_zero _ (hf w (Finset.ne_of_mem_erase hw))
+    · rw [mult]; split_ifs <;> norm_num
+
+end convexBodyLt
+
+section minkowski
+
+open MeasureTheory MeasureTheory.Measure Classical NNReal ENNReal FiniteDimensional Zspan
+
+variable [NumberField K]
+
+/-- The bound that appears in Minkowski Convex Body theorem, see
+`MeasureTheory.exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure`. -/
+noncomputable def minkowskiBound : ℝ≥0∞ :=
+  volume (fundamentalDomain (latticeBasis K)) * 2 ^ (finrank ℝ (E K))
+
+theorem minkowskiBound_lt_top : minkowskiBound K < ⊤ := by
+  refine mul_lt_top ?_ ?_
+  · exact ne_of_lt (fundamentalDomain_isBounded (latticeBasis K)).measure_lt_top
+  · exact ne_of_lt (pow_lt_top (lt_top_iff_ne_top.mpr two_ne_top) _)
+
+variable {f : InfinitePlace K → ℝ≥0}
+
+/-- Assume that `f : InfinitePlace K → ℝ≥0` is such that
+`minkowskiBound K < volume (convexBodyLt K f)` where `convexBodyLt K f` is the set of
+points `x` such that `‖x w‖ < f w` for all infinite places `w` (see `convexBodyLt_volume` for
+the computation of this volume), then there exists a nonzero algebraic integer `a` in `𝓞 K` such
+that `w a < f w` for all infinite places `w`. -/
+theorem exists_ne_zero_mem_ringOfIntegers_lt (h : minkowskiBound K < volume (convexBodyLt K f)) :
+    ∃ (a : 𝓞 K), a ≠ 0 ∧ ∀ w : InfinitePlace K, w a < f w := by
+  have : @IsAddHaarMeasure (E K) _ _ _ volume := prod.instIsAddHaarMeasure volume volume
+  have h_fund := Zspan.isAddFundamentalDomain (latticeBasis K) volume
+  have : Countable (Submodule.span ℤ (Set.range (latticeBasis K))).toAddSubgroup := by
+    change Countable (Submodule.span ℤ (Set.range (latticeBasis K)): Set (E K))
+    infer_instance
+  obtain ⟨⟨x, hx⟩, h_nzr, h_mem⟩ := exists_ne_zero_mem_lattice_of_measure_mul_two_pow_lt_measure
+    h_fund h (convexBodyLt_symmetric K f) (convexBodyLt_convex K f)
+  rw [Submodule.mem_toAddSubgroup, mem_span_latticeBasis] at hx
+  obtain ⟨a, ha, rfl⟩ := hx
+  refine ⟨⟨a, ha⟩, ?_, (convexBodyLt_mem K f).mp h_mem⟩
+  rw [ne_eq, AddSubgroup.mk_eq_zero_iff, map_eq_zero, ← ne_eq] at h_nzr
+  exact Subtype.ne_of_val_ne h_nzr
+
+end minkowski
+
+end NumberField.mixedEmbedding
refactor(NumberTheory.NumberField.CanonicalEmbedding): make the canonical embedding canonical (#5518)

It was observed by @kbuzzard, and rightly so, that in the first version of this file the canonical_embedding was not so canonical. This refactor fixes that by replacing it with a truly canonical embedding.

More precisely, in the old version, the canonical embedding was defined as the ring homomorphism K →+* ℝ^r₁ × ℂ^r₂ that sends x ∈ K to (φ_₁(x),...,φ_r₁(x)) × (ψ_₁(x),..., ψ_r₂(x)) where φ_₁,...,φ_r₁ are its real embeddings and ψ_₁,..., ψ_r₂ are its complex embeddings (up to complex conjugation). This is not canonical since it depends upon the choice of the ψ's.

In the new version, the canonical embedding is defined as the ring homomorphism K →+* ℂ^n that sends x ∈ K to (φ_₁(x),...,φ_n(x)) where the φ_i's are the complex embeddings of K.

The new version is easier to compute with since one does not have to distinguish between real and complex embeddings as in the first version. It also enables to prove the following result: the image of the ring of integers by canonicalEmbedding is a full ℤ-lattice (see latticeBasis) that will be useful in #5650.

Note that the original version of the canonical embedding will reappear in #5650 (as mixedEmbedding) since it allows for easier volume computation.

Diff
@@ -4,20 +4,24 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 -/
 import Mathlib.NumberTheory.NumberField.Embeddings
+import Mathlib.RingTheory.Discriminant
 
 #align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
 
 /-!
 # Canonical embedding of a number field
 
-The canonical embedding of a number field `K` of signature `(r₁, r₂)` is the ring homomorphism
-`K →+* ℝ^r₁ × ℂ^r₂` that sends `x ∈ K` to `(φ_₁(x),...,φ_r₁(x)) × (ψ_₁(x),..., ψ_r₂(x))` where
-`φ_₁,...,φ_r₁` are its real embeddings and `ψ_₁,..., ψ_r₂` are its complex embeddings (up to
-complex conjugation).
+The canonical embedding of a number field `K` of degree `n` is the ring homomorphism
+`K →+* ℂ^n` that sends `x ∈ K` to `(φ_₁(x),...,φ_n(x))` where the `φ_i`'s are the complex
+embeddings of `K`. Note that we do not choose an ordering of the embeddings, but instead map `K`
+into the type `(K →+* ℂ) → ℂ` of `ℂ`-vectors indexed by the complex embeddings.
 
 ## Main definitions and results
 
-* `NumberField.canonicalEmbedding.integerLattice.inter_ball_finite`: the intersection of the
+* `canonicalEmbedding`: the ring homorphism `K →+* ((K →+* ℂ) → ℂ)` defined by sending `x : K` to
+the vector `(φ x)` indexed by `φ : K →+* ℂ`.
+
+* `canonicalEmbedding.integerLattice.inter_ball_finite`: the intersection of the
 image of the ring of integers by the canonical embedding and any ball centered at `0` of finite
 radius is finite.
 
@@ -26,159 +30,118 @@ radius is finite.
 number field, infinite places
 -/
 
-
-noncomputable section
-
-open Function FiniteDimensional Finset Fintype NumberField NumberField.InfinitePlace Metric Module
-
-open scoped Classical NumberField
-
 variable (K : Type*) [Field K]
 
 namespace NumberField.canonicalEmbedding
 
--- The ambient space `ℝ^r₁ × ℂ^r₂` with `(r₁, r₂)` the signature of `K`.
-set_option quotPrecheck false in -- Porting note: Added.
-scoped[CanonicalEmbedding]
-  notation "E" =>
-    ({ w : InfinitePlace K // IsReal w } → ℝ) × ({ w : InfinitePlace K // IsComplex w } → ℂ)
-
-open CanonicalEmbedding
-
-theorem space_rank [NumberField K] : finrank ℝ E = finrank ℚ K := by
-  haveI : Module.Free ℝ ℂ := inferInstance
-  rw [finrank_prod, finrank_pi, finrank_pi_fintype, Complex.finrank_real_complex, Finset.sum_const,
-    Finset.card_univ, ← card_real_embeddings, Algebra.id.smul_eq_mul, mul_comm,
-    ← card_complex_embeddings, ← NumberField.Embeddings.card K ℂ, Fintype.card_subtype_compl,
-    Nat.add_sub_of_le (Fintype.card_subtype_le _)]
-#align number_field.canonical_embedding.space_rank NumberField.canonicalEmbedding.space_rank
-
-theorem nontrivial_space [NumberField K] : Nontrivial E := by
-  have : Nonempty <| InfinitePlace K := inferInstance
-  rcases this with ⟨w⟩
-  obtain hw | hw := w.isReal_or_isComplex
-  · haveI : Nonempty { w : InfinitePlace K // IsReal w } := ⟨⟨w, hw⟩⟩
-    exact nontrivial_prod_left
-  · haveI : Nonempty { w : InfinitePlace K // IsComplex w } := ⟨⟨w, hw⟩⟩
-    exact nontrivial_prod_right
-#align number_field.canonical_embedding.non_trivial_space NumberField.canonicalEmbedding.nontrivial_space
-
-/-- The canonical embedding of a number field `K` of signature `(r₁, r₂)` into `ℝ^r₁ × ℂ^r₂`. -/
-def _root_.NumberField.canonicalEmbedding : K →+* E :=
-  RingHom.prod (Pi.ringHom fun w => embedding_of_isReal w.prop)
-    (Pi.ringHom fun w => w.val.embedding)
-#align number_field.canonical_embedding NumberField.canonicalEmbedding
+open NumberField
 
-theorem _root_.NumberField.canonicalEmbedding_injective [NumberField K] :
-    Injective (NumberField.canonicalEmbedding K) :=
-  @RingHom.injective _ _ _ _ (nontrivial_space K) _
-#align number_field.canonical_embedding_injective NumberField.canonicalEmbedding_injective
+/-- The canonical embedding of a number field `K` of degree `n` into `ℂ^n`. -/
+def _root_.NumberField.canonicalEmbedding : K →+* ((K →+* ℂ) → ℂ) := Pi.ringHom fun φ => φ
 
-open NumberField
+theorem _root_.NumberField.canonicalEmbedding_injective [NumberField K] :
+    Function.Injective (NumberField.canonicalEmbedding K) := RingHom.injective _
 
 variable {K}
 
 @[simp]
-theorem apply_at_real_infinitePlace (w : { w : InfinitePlace K // IsReal w }) (x : K) :
-    (NumberField.canonicalEmbedding K x).1 w = embedding_of_isReal w.prop x := by
-  simp only [canonicalEmbedding, RingHom.prod_apply, Pi.ringHom_apply]
-#align number_field.canonical_embedding.apply_at_real_infinite_place NumberField.canonicalEmbedding.apply_at_real_infinitePlace
-
-@[simp]
-theorem apply_at_complex_infinitePlace (w : { w : InfinitePlace K // IsComplex w }) (x : K) :
-    (NumberField.canonicalEmbedding K x).2 w = embedding w.val x := by
-  simp only [canonicalEmbedding, RingHom.prod_apply, Pi.ringHom_apply]
-#align number_field.canonical_embedding.apply_at_complex_infinite_place NumberField.canonicalEmbedding.apply_at_complex_infinitePlace
+theorem apply_at (φ : K →+* ℂ) (x : K) : (NumberField.canonicalEmbedding K x) φ = φ x := rfl
+
+open scoped ComplexConjugate
+
+/-- The image of `canonicalEmbedding` lives in the `ℝ`-submodule of the `x ∈ ((K →+* ℂ) → ℂ)` such
+that `conj x_φ = x_(conj φ)` for all `∀ φ : K →+* ℂ`. -/
+theorem conj_apply {x : ((K →+* ℂ) → ℂ)} (φ : K →+* ℂ)
+    (hx : x ∈ Submodule.span ℝ (Set.range (canonicalEmbedding K))) :
+    conj (x φ) = x (ComplexEmbedding.conjugate φ) := by
+  refine Submodule.span_induction hx ?_ ?_ (fun _ _ hx hy => ?_) (fun a _ hx => ?_)
+  · rintro _ ⟨x, rfl⟩
+    rw [apply_at, apply_at, ComplexEmbedding.conjugate_coe_eq]
+  · rw [Pi.zero_apply, Pi.zero_apply, map_zero]
+  · rw [Pi.add_apply, Pi.add_apply, map_add, hx, hy]
+  · rw [Pi.smul_apply, Complex.real_smul, map_mul, Complex.conj_ofReal]
+    exact congrArg ((a : ℂ) * ·) hx
 
 theorem nnnorm_eq [NumberField K] (x : K) :
-    ‖canonicalEmbedding K x‖₊ =
-      Finset.univ.sup fun w : InfinitePlace K => ⟨w x, map_nonneg w x⟩ := by
-  rw [Prod.nnnorm_def', Pi.nnnorm_def, Pi.nnnorm_def]
-  rw [(_ : Finset.univ =
-        {w : InfinitePlace K | IsReal w}.toFinset ∪ {w : InfinitePlace K | IsComplex w}.toFinset)]
-  · rw [Finset.sup_union, sup_eq_max]
-    refine' congr_arg₂ _ _ _
-    · convert
-        (Finset.univ.sup_map (Function.Embedding.subtype fun w : InfinitePlace K => IsReal w)
-          fun w => (⟨w x, map_nonneg w x⟩ : NNReal)).symm using 2
-      ext w
-      dsimp
-      rw [apply_at_real_infinitePlace, ← Complex.abs_ofReal, embedding_of_isReal_apply,
-        ← Complex.norm_eq_abs, norm_embedding_eq]
-    · convert
-        (Finset.univ.sup_map (Function.Embedding.subtype fun w : InfinitePlace K => IsComplex w)
-          fun w => (⟨w x, map_nonneg w x⟩ : NNReal)).symm using 2
-      ext w
-      dsimp
-      rw [apply_at_complex_infinitePlace, ← Complex.norm_eq_abs, norm_embedding_eq]
-  · ext w
-    simp_rw [Finset.mem_univ, Finset.mem_union, Set.mem_toFinset, Set.mem_setOf_eq,
-      w.isReal_or_isComplex]
-#align number_field.canonical_embedding.nnnorm_eq NumberField.canonicalEmbedding.nnnorm_eq
+    ‖canonicalEmbedding K x‖₊ = Finset.univ.sup (fun φ : K →+* ℂ => ‖φ x‖₊) := by
+  simp_rw [Pi.nnnorm_def, apply_at]
 
 theorem norm_le_iff [NumberField K] (x : K) (r : ℝ) :
-    ‖canonicalEmbedding K x‖ ≤ r ↔ ∀ w : InfinitePlace K, w x ≤ r := by
+    ‖canonicalEmbedding K x‖ ≤ r ↔ ∀ φ : K →+* ℂ, ‖φ x‖ ≤ r := by
   obtain hr | hr := lt_or_le r 0
-  · have : Nonempty <| InfinitePlace K := inferInstance
-    rcases this with ⟨w⟩
-    exact iff_of_false
-      (hr.trans_le <| norm_nonneg _).not_le fun h => hr.not_le <| (map_nonneg w _).trans <| h _
+  · obtain ⟨φ⟩ := (inferInstance : Nonempty (K →+* ℂ))
+    refine iff_of_false ?_ ?_
+    exact (hr.trans_le (norm_nonneg _)).not_le
+    exact fun h => hr.not_le (le_trans (norm_nonneg _) (h φ))
   · lift r to NNReal using hr
     simp_rw [← coe_nnnorm, nnnorm_eq, NNReal.coe_le_coe, Finset.sup_le_iff, Finset.mem_univ,
-      forall_true_left, ← NNReal.coe_le_coe, NNReal.toReal]
-#align number_field.canonical_embedding.norm_le_iff NumberField.canonicalEmbedding.norm_le_iff
+      forall_true_left]
 
 variable (K)
 
-/-- The image of `𝓞 K` as a subring of `ℝ^r₁ × ℂ^r₂`. -/
-def integerLattice : Subring E :=
+/-- The image of `𝓞 K` as a subring of `ℂ^n`. -/
+def integerLattice : Subring ((K →+* ℂ) → ℂ) :=
   (RingHom.range (algebraMap (𝓞 K) K)).map (canonicalEmbedding K)
-#align number_field.canonical_embedding.integer_lattice NumberField.canonicalEmbedding.integerLattice
-
--- Porting note: See https://github.com/leanprover-community/mathlib4/issues/5028
-set_option maxHeartbeats 400000 in
-set_option synthInstance.maxHeartbeats 50000 in
-/-- The linear equiv between `𝓞 K` and the integer lattice. -/
-def equivIntegerLattice [NumberField K] : 𝓞 K ≃ₗ[ℤ] integerLattice K :=
-  LinearEquiv.ofBijective
-    { toFun := fun x => (by
-          refine ⟨canonicalEmbedding K (algebraMap (𝓞 K) K x), ⟨algebraMap (𝓞 K) K x, ⟨?_, rfl⟩⟩⟩
-          simp only [Subsemiring.coe_carrier_toSubmonoid, Subring.coe_toSubsemiring,
-            RingHom.coe_range, Set.mem_range, exists_apply_eq_apply] )
-      map_add' := fun x y => (by
-          apply Subtype.eq
-          simp [map_add] )
-      map_smul' := fun c x => (by
-          simp only [RingHom.id_apply, zsmul_eq_mul, RingHom.map_mul, map_intCast]
-          rfl ) }
-   (by
-    refine ⟨fun _ _ h => ?_, fun ⟨_, ⟨_, ⟨⟨a, rfl⟩, rfl⟩⟩⟩ => ⟨a, rfl⟩⟩
-    dsimp only at h
-    rw [LinearMap.coe_mk, Subtype.mk_eq_mk] at h
-    exact IsFractionRing.injective (𝓞 K) K (canonicalEmbedding_injective K h))
-#align number_field.canonical_embedding.equiv_integer_lattice NumberField.canonicalEmbedding.equivIntegerLattice
 
 theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
-    ((integerLattice K : Set E) ∩ closedBall 0 r).Finite := by
+    ((integerLattice K : Set ((K →+* ℂ) → ℂ)) ∩ Metric.closedBall 0 r).Finite := by
   obtain hr | _ := lt_or_le r 0
-  · simp [closedBall_eq_empty.2 hr]
-  have heq : ∀ x, canonicalEmbedding K x ∈ closedBall (0 : E) r ↔ ∀ φ : K →+* ℂ, ‖φ x‖ ≤ r := by
-    simp_rw [← place_apply, mem_closedBall_zero_iff, norm_le_iff, le_iff_le, place_apply,
-      implies_true]
-  convert (Embeddings.finite_of_norm_le K ℂ r).image (canonicalEmbedding K)
-  ext; constructor
-  · rintro ⟨⟨_, ⟨x, rfl⟩, rfl⟩, hx2⟩
-    exact ⟨x, ⟨SetLike.coe_mem x, (heq x).mp hx2⟩, rfl⟩
-  · rintro ⟨x, ⟨hx1, hx2⟩, rfl⟩
-    exact ⟨⟨x, ⟨⟨x, hx1⟩, rfl⟩, rfl⟩, (heq x).mpr hx2⟩
-#align number_field.canonical_embedding.integer_lattice.inter_ball_finite NumberField.canonicalEmbedding.integerLattice.inter_ball_finite
-
-instance [NumberField K] : Countable (integerLattice K) := by
-  have : (⋃ n : ℕ, (integerLattice K : Set E) ∩ closedBall 0 n).Countable :=
-    Set.countable_iUnion fun n => (integerLattice.inter_ball_finite K n).countable
-  refine' (this.mono _).to_subtype
-  rintro _ ⟨x, hx, rfl⟩
-  rw [Set.mem_iUnion]
-  exact ⟨⌈‖canonicalEmbedding K x‖⌉₊, ⟨x, hx, rfl⟩, mem_closedBall_zero_iff.2 (Nat.le_ceil _)⟩
+  · simp [Metric.closedBall_eq_empty.2 hr]
+  · have heq : ∀ x, canonicalEmbedding K x ∈ Metric.closedBall 0 r ↔
+        ∀ φ : K →+* ℂ, ‖φ x‖ ≤ r := by
+      intro x; rw [← norm_le_iff, mem_closedBall_zero_iff]
+    convert (Embeddings.finite_of_norm_le K ℂ r).image (canonicalEmbedding K)
+    ext; constructor
+    · rintro ⟨⟨_, ⟨x, rfl⟩, rfl⟩, hx⟩
+      exact ⟨↑x, ⟨SetLike.coe_mem x, fun φ => (heq x).mp hx φ⟩, rfl⟩
+    · rintro ⟨x, ⟨hx1, hx2⟩, rfl⟩
+      exact ⟨⟨x, ⟨⟨x, hx1⟩, rfl⟩, rfl⟩, (heq x).mpr hx2⟩
+
+open Module Fintype FiniteDimensional
+
+/-- A `ℂ`-basis of `ℂ^n` that is also a `ℤ`-basis of the `integerLattice`. -/
+noncomputable def latticeBasis [NumberField K] :
+    Basis (Free.ChooseBasisIndex ℤ (𝓞 K)) ℂ ((K →+* ℂ) → ℂ) := by
+  classical
+  -- Let `B` be the canonical basis of `(K →+* ℂ) → ℂ`. We prove that the determinant of
+  -- the image by `canonicalEmbedding` of the integral basis of `K` is nonzero. This
+  -- will imply the result.
+    let B := Pi.basisFun ℂ (K →+* ℂ)
+    let e : (K →+* ℂ) ≃ Free.ChooseBasisIndex ℤ (𝓞 K) :=
+      equivOfCardEq ((Embeddings.card K ℂ).trans (finrank_eq_card_basis (integralBasis K)))
+    let M := B.toMatrix (fun i => canonicalEmbedding K (integralBasis K (e i)))
+    suffices M.det ≠ 0 by
+      rw [← isUnit_iff_ne_zero, ← Basis.det_apply, ← is_basis_iff_det] at this
+      refine basisOfLinearIndependentOfCardEqFinrank
+        ((linearIndependent_equiv e.symm).mpr this.1) ?_
+      rw [← finrank_eq_card_chooseBasisIndex, RingOfIntegers.rank, finrank_fintype_fun_eq_card,
+        Embeddings.card]
+  -- In order to prove that the determinant is nonzero, we show that it is equal to the
+  -- square of the discriminant of the integral basis and thus it is not zero
+    let N := Algebra.embeddingsMatrixReindex ℚ ℂ (fun i => integralBasis K (e i))
+      RingHom.equivRatAlgHom
+    rw [show M = N.transpose by { ext:2; rfl }]
+    rw [Matrix.det_transpose, ← @pow_ne_zero_iff ℂ _ _ _ 2 (by norm_num)]
+    convert (map_ne_zero_iff _ (algebraMap ℚ ℂ).injective).mpr
+      (Algebra.discr_not_zero_of_basis ℚ (integralBasis K))
+    rw [← Algebra.discr_reindex ℚ (integralBasis K) e.symm]
+    exact (Algebra.discr_eq_det_embeddingsMatrixReindex_pow_two ℚ ℂ
+      (fun i => integralBasis K (e i)) RingHom.equivRatAlgHom).symm
+
+@[simp]
+theorem latticeBasis_apply [NumberField K] (i : Free.ChooseBasisIndex ℤ (𝓞 K)) :
+    latticeBasis K i = (canonicalEmbedding K) (integralBasis K i) := by
+  simp only [latticeBasis, integralBasis_apply, coe_basisOfLinearIndependentOfCardEqFinrank,
+    Function.comp_apply, Equiv.apply_symm_apply]
+
+theorem mem_span_latticeBasis [NumberField K] (x : (K →+* ℂ) → ℂ) :
+    x ∈ Submodule.span ℤ (Set.range (latticeBasis K)) ↔ x ∈ canonicalEmbedding K '' (𝓞 K) := by
+  rw [show Set.range (latticeBasis K) =
+      (canonicalEmbedding K).toIntAlgHom.toLinearMap '' (Set.range (integralBasis K)) by
+    rw [← Set.range_comp]; exact congrArg Set.range (funext (fun i => latticeBasis_apply K i))]
+  rw [← Submodule.map_span, ← SetLike.mem_coe, Submodule.map_coe]
+  rw [show (Submodule.span ℤ (Set.range (integralBasis K)) : Set K) = 𝓞 K by
+    ext; exact mem_span_integralBasis K]
+  rfl
 
 end NumberField.canonicalEmbedding
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -33,7 +33,7 @@ open Function FiniteDimensional Finset Fintype NumberField NumberField.InfiniteP
 
 open scoped Classical NumberField
 
-variable (K : Type _) [Field K]
+variable (K : Type*) [Field K]
 
 namespace NumberField.canonicalEmbedding
 
refactor of NumberTheory.NumberField.Embeddings (#6164)

Remove unnecessary or redundant results and golf some proofs.

Diff
@@ -65,7 +65,8 @@ theorem nontrivial_space [NumberField K] : Nontrivial E := by
 
 /-- The canonical embedding of a number field `K` of signature `(r₁, r₂)` into `ℝ^r₁ × ℂ^r₂`. -/
 def _root_.NumberField.canonicalEmbedding : K →+* E :=
-  RingHom.prod (Pi.ringHom fun w => w.prop.embedding) (Pi.ringHom fun w => w.val.embedding)
+  RingHom.prod (Pi.ringHom fun w => embedding_of_isReal w.prop)
+    (Pi.ringHom fun w => w.val.embedding)
 #align number_field.canonical_embedding NumberField.canonicalEmbedding
 
 theorem _root_.NumberField.canonicalEmbedding_injective [NumberField K] :
@@ -79,7 +80,7 @@ variable {K}
 
 @[simp]
 theorem apply_at_real_infinitePlace (w : { w : InfinitePlace K // IsReal w }) (x : K) :
-    (NumberField.canonicalEmbedding K x).1 w = w.prop.embedding x := by
+    (NumberField.canonicalEmbedding K x).1 w = embedding_of_isReal w.prop x := by
   simp only [canonicalEmbedding, RingHom.prod_apply, Pi.ringHom_apply]
 #align number_field.canonical_embedding.apply_at_real_infinite_place NumberField.canonicalEmbedding.apply_at_real_infinitePlace
 
@@ -102,15 +103,14 @@ theorem nnnorm_eq [NumberField K] (x : K) :
           fun w => (⟨w x, map_nonneg w x⟩ : NNReal)).symm using 2
       ext w
       dsimp
-      simp only [apply_at_real_infinitePlace, coe_nnnorm, Real.norm_eq_abs,
-        Function.Embedding.coe_subtype, Subtype.coe_mk, IsReal.abs_embedding_apply]
+      rw [apply_at_real_infinitePlace, ← Complex.abs_ofReal, embedding_of_isReal_apply,
+        ← Complex.norm_eq_abs, norm_embedding_eq]
     · convert
         (Finset.univ.sup_map (Function.Embedding.subtype fun w : InfinitePlace K => IsComplex w)
           fun w => (⟨w x, map_nonneg w x⟩ : NNReal)).symm using 2
       ext w
       dsimp
-      simp only [apply_at_complex_infinitePlace, coe_nnnorm,
-        Complex.norm_eq_abs, Function.Embedding.coe_subtype, Subtype.coe_mk, abs_embedding]
+      rw [apply_at_complex_infinitePlace, ← Complex.norm_eq_abs, norm_embedding_eq]
   · ext w
     simp_rw [Finset.mem_univ, Finset.mem_union, Set.mem_toFinset, Set.mem_setOf_eq,
       w.isReal_or_isComplex]
@@ -163,8 +163,8 @@ theorem integerLattice.inter_ball_finite [NumberField K] (r : ℝ) :
   obtain hr | _ := lt_or_le r 0
   · simp [closedBall_eq_empty.2 hr]
   have heq : ∀ x, canonicalEmbedding K x ∈ closedBall (0 : E) r ↔ ∀ φ : K →+* ℂ, ‖φ x‖ ≤ r := by
-    simp only [← place_apply, ← InfinitePlace.coe_mk, mem_closedBall_zero_iff, norm_le_iff]
-    exact fun x => le_iff_le x r
+    simp_rw [← place_apply, mem_closedBall_zero_iff, norm_le_iff, le_iff_le, place_apply,
+      implies_true]
   convert (Embeddings.finite_of_norm_le K ℂ r).image (canonicalEmbedding K)
   ext; constructor
   · rintro ⟨⟨_, ⟨x, rfl⟩, rfl⟩, hx2⟩
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,14 +2,11 @@
 Copyright (c) 2022 Xavier Roblot. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
-
-! This file was ported from Lean 3 source module number_theory.number_field.canonical_embedding
-! leanprover-community/mathlib commit 60da01b41bbe4206f05d34fd70c8dd7498717a30
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.NumberTheory.NumberField.Embeddings
 
+#align_import number_theory.number_field.canonical_embedding from "leanprover-community/mathlib"@"60da01b41bbe4206f05d34fd70c8dd7498717a30"
+
 /-!
 # Canonical embedding of a number field
 
feat: port NumberTheory.NumberField.CanonicalEmbedding (#5414)

Co-authored-by: Moritz Firsching <firsching@google.com> Co-authored-by: Xavier-François Roblot <46200072+xroblot@users.noreply.github.com>

Dependencies 12 + 1175

1176 files ported (99.0%)
516782 lines ported (98.9%)
Show graph

The unported dependencies are

The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file