number_theory.number_field.units
⟷
Mathlib.NumberTheory.NumberField.Units
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.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(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)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -36,7 +36,7 @@ section Rat
theorem Rat.RingOfIntegers.isUnit_iff {x : 𝓞 ℚ} : IsUnit x ↔ (x : ℚ) = 1 ∨ (x : ℚ) = -1 := by
simp_rw [(isUnit_map_iff (Rat.ringOfIntegersEquiv : 𝓞 ℚ →+* ℤ) x).symm, Int.isUnit_iff,
RingEquiv.coe_toRingHom, RingEquiv.map_eq_one_iff, RingEquiv.map_eq_neg_one_iff, ←
- subtype.coe_injective.eq_iff, AddSubgroupClass.coe_neg, algebraMap.coe_one]
+ subtype.coe_injective.eq_iff, NegMemClass.coe_neg, algebraMap.coe_one]
#align rat.ring_of_integers.is_unit_iff Rat.RingOfIntegers.isUnit_iff
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -50,13 +50,13 @@ attribute [local instance] NumberField.inst_ringOfIntegersAlgebra
variable {K}
-#print isUnit_iff_norm /-
-theorem isUnit_iff_norm [NumberField K] (x : 𝓞 K) :
+#print NumberField.isUnit_iff_norm /-
+theorem NumberField.isUnit_iff_norm [NumberField K] (x : 𝓞 K) :
IsUnit x ↔ |(RingOfIntegers.norm ℚ x : ℚ)| = 1 :=
by
convert (RingOfIntegers.isUnit_norm ℚ).symm
rw [← abs_one, abs_eq_abs, ← Rat.RingOfIntegers.isUnit_iff]
-#align is_unit_iff_norm isUnit_iff_norm
+#align is_unit_iff_norm NumberField.isUnit_iff_norm
-/
end IsUnit
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,7 +3,7 @@ Copyright (c) 2023 Xavier Roblot. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Xavier Roblot
-/
-import Mathbin.NumberTheory.NumberField.Norm
+import NumberTheory.NumberField.Norm
#align_import number_theory.number_field.units from "leanprover-community/mathlib"@"5d0c76894ada7940957143163d7b921345474cbc"
mathlib commit https://github.com/leanprover-community/mathlib/commit/48a058d7e39a80ed56858505719a0b2197900999
@@ -46,7 +46,7 @@ variable (K : Type _) [Field K]
section IsUnit
-attribute [local instance] NumberField.ringOfIntegersAlgebra
+attribute [local instance] NumberField.inst_ringOfIntegersAlgebra
variable {K}
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,14 +2,11 @@
Copyright (c) 2023 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.units
-! leanprover-community/mathlib commit 5d0c76894ada7940957143163d7b921345474cbc
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.NumberTheory.NumberField.Norm
+#align_import number_theory.number_field.units from "leanprover-community/mathlib"@"5d0c76894ada7940957143163d7b921345474cbc"
+
/-!
# Units of a number field
mathlib commit https://github.com/leanprover-community/mathlib/commit/93f880918cb51905fd51b76add8273cbc27718ab
@@ -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.units
-! leanprover-community/mathlib commit 00f91228655eecdcd3ac97a7fd8dbcb139fe990a
+! leanprover-community/mathlib commit 5d0c76894ada7940957143163d7b921345474cbc
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -12,6 +12,9 @@ import Mathbin.NumberTheory.NumberField.Norm
/-!
# Units of a number field
+
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
We prove results about the group `(𝓞 K)ˣ` of units of the ring of integers `𝓞 K` of a number
field `K`.
mathlib commit https://github.com/leanprover-community/mathlib/commit/6285167a053ad0990fc88e56c48ccd9fae6550eb
@@ -32,11 +32,13 @@ open NumberField Units
section Rat
+#print Rat.RingOfIntegers.isUnit_iff /-
theorem Rat.RingOfIntegers.isUnit_iff {x : 𝓞 ℚ} : IsUnit x ↔ (x : ℚ) = 1 ∨ (x : ℚ) = -1 := by
simp_rw [(isUnit_map_iff (Rat.ringOfIntegersEquiv : 𝓞 ℚ →+* ℤ) x).symm, Int.isUnit_iff,
RingEquiv.coe_toRingHom, RingEquiv.map_eq_one_iff, RingEquiv.map_eq_neg_one_iff, ←
subtype.coe_injective.eq_iff, AddSubgroupClass.coe_neg, algebraMap.coe_one]
#align rat.ring_of_integers.is_unit_iff Rat.RingOfIntegers.isUnit_iff
+-/
end Rat
@@ -48,12 +50,14 @@ attribute [local instance] NumberField.ringOfIntegersAlgebra
variable {K}
+#print isUnit_iff_norm /-
theorem isUnit_iff_norm [NumberField K] (x : 𝓞 K) :
IsUnit x ↔ |(RingOfIntegers.norm ℚ x : ℚ)| = 1 :=
by
convert (RingOfIntegers.isUnit_norm ℚ).symm
rw [← abs_one, abs_eq_abs, ← Rat.RingOfIntegers.isUnit_iff]
#align is_unit_iff_norm isUnit_iff_norm
+-/
end IsUnit
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -51,7 +51,7 @@ variable {K}
theorem isUnit_iff_norm [NumberField K] (x : 𝓞 K) :
IsUnit x ↔ |(RingOfIntegers.norm ℚ x : ℚ)| = 1 :=
by
- convert(RingOfIntegers.isUnit_norm ℚ).symm
+ convert (RingOfIntegers.isUnit_norm ℚ).symm
rw [← abs_one, abs_eq_abs, ← Rat.RingOfIntegers.isUnit_iff]
#align is_unit_iff_norm isUnit_iff_norm
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -24,7 +24,7 @@ number field, units
-/
-open NumberField
+open scoped NumberField
noncomputable section
mathlib commit https://github.com/leanprover-community/mathlib/commit/3905fa80e62c0898131285baab35559fbc4e5cda
This PR splits the file NumberField/Units.lean
into two files placed into a new folder NumberField/Units
:
Units/Basic.lean
contains the basic definitions and results about the unit group and its torsion subgroup,Units/DirichletTheorem.lean
contains the proof of Dirichlet unit theorem and results about the structure of the unit group and its rank.@@ -5,15 +5,16 @@ Authors: Xavier Roblot
-/
import Mathlib.LinearAlgebra.Matrix.Gershgorin
import Mathlib.NumberTheory.NumberField.CanonicalEmbedding.ConvexBody
-import Mathlib.NumberTheory.NumberField.Norm
+import Mathlib.NumberTheory.NumberField.Units.Basic
import Mathlib.RingTheory.RootsOfUnity.Basic
#align_import number_theory.number_field.units from "leanprover-community/mathlib"@"00f91228655eecdcd3ac97a7fd8dbcb139fe990a"
/-!
-# Units of a number field
-We prove results about the group `(𝓞 K)ˣ` of units of the ring of integers `𝓞 K` of a number
-field `K`.
+# Dirichlet theorem on the group of units of a number field
+This file is devoted to the proof of Dirichlet unit theorem that states that the group of
+units `(𝓞 K)ˣ` of units of the ring of integers `𝓞 K` of a number field `K` modulo its torsion
+subgroup is a free `ℤ`-module of rank `card (InfinitePlace K) - 1`.
## Main definitions
@@ -26,147 +27,29 @@ as an additive `ℤ`-module.
## Main results
-* `NumberField.isUnit_iff_norm`: an algebraic integer `x : 𝓞 K` is a unit if and only if
-`|norm ℚ x| = 1`.
-
-* `NumberField.Units.mem_torsion`: a unit `x : (𝓞 K)ˣ` is torsion iff `w x = 1` for all infinite
-places `w` of `K`.
+* `NumberField.Units.rank_modTorsion`: the `ℤ`-rank of `(𝓞 K)ˣ ⧸ (torsion K)` is equal to
+`card (InfinitePlace K) - 1`.
* `NumberField.Units.exist_unique_eq_mul_prod`: **Dirichlet Unit Theorem**. Any unit of `𝓞 K`
can be written uniquely as the product of a root of unity and powers of the units of the
fundamental system `fundSystem`.
## Tags
-number field, units
+number field, units, Dirichlet unit theorem
-/
open scoped NumberField
noncomputable section
-open NumberField Units BigOperators
-
-section Rat
-
-theorem Rat.RingOfIntegers.isUnit_iff {x : 𝓞 ℚ} : IsUnit x ↔ (x : ℚ) = 1 ∨ (x : ℚ) = -1 := by
- simp_rw [(isUnit_map_iff (Rat.ringOfIntegersEquiv : 𝓞 ℚ →+* ℤ) x).symm, Int.isUnit_iff,
- RingEquiv.coe_toRingHom, RingEquiv.map_eq_one_iff, RingEquiv.map_eq_neg_one_iff, ←
- Subtype.coe_injective.eq_iff]; rfl
-#align rat.ring_of_integers.is_unit_iff Rat.RingOfIntegers.isUnit_iff
-
-end Rat
-
-variable (K : Type*) [Field K]
-
-section IsUnit
-
-variable {K}
-
-theorem NumberField.isUnit_iff_norm [NumberField K] {x : 𝓞 K} :
- IsUnit x ↔ |(RingOfIntegers.norm ℚ x : ℚ)| = 1 := by
- convert (RingOfIntegers.isUnit_norm ℚ (F := K)).symm
- rw [← abs_one, abs_eq_abs, ← Rat.RingOfIntegers.isUnit_iff]
-#align is_unit_iff_norm NumberField.isUnit_iff_norm
-
-end IsUnit
-
-namespace NumberField.Units
-
-section coe
-
-theorem coe_injective : Function.Injective ((↑) : (𝓞 K)ˣ → K) :=
- fun _ _ h => by rwa [SetLike.coe_eq_coe, Units.eq_iff] at h
-
-variable {K}
-
-theorem coe_mul (x y : (𝓞 K)ˣ) : ((x * y : (𝓞 K)ˣ) : K) = (x : K) * (y : K) := rfl
-
-theorem coe_pow (x : (𝓞 K)ˣ) (n : ℕ) : (↑(x ^ n) : K) = (x : K) ^ n := by
- rw [← SubmonoidClass.coe_pow, ← val_pow_eq_pow_val]
+open NumberField NumberField.InfinitePlace NumberField.Units BigOperators
-theorem coe_zpow (x : (𝓞 K)ˣ) (n : ℤ) : (↑(x ^ n) : K) = (x : K) ^ n := by
- change ((Units.coeHom K).comp (map (algebraMap (𝓞 K) K))) (x ^ n) = _
- exact map_zpow _ x n
+variable (K : Type*) [Field K] [NumberField K]
-theorem coe_one : ((1 : (𝓞 K)ˣ) : K) = (1 : K) := rfl
-
-theorem coe_neg_one : ((-1 : (𝓞 K)ˣ) : K) = (-1 : K) := rfl
-
-theorem coe_ne_zero (x : (𝓞 K)ˣ) : (x : K) ≠ 0 :=
- Subtype.coe_injective.ne_iff.mpr (_root_.Units.ne_zero x)
-
-end coe
-
-open NumberField.InfinitePlace
-
-section torsion
-
-/-- The torsion subgroup of the group of units. -/
-def torsion : Subgroup (𝓞 K)ˣ := CommGroup.torsion (𝓞 K)ˣ
-
-theorem mem_torsion {x : (𝓞 K)ˣ} [NumberField K] :
- x ∈ torsion K ↔ ∀ w : InfinitePlace K, w x = 1 := by
- rw [eq_iff_eq (x : K) 1, torsion, CommGroup.mem_torsion]
- refine ⟨fun hx φ ↦ (((φ.comp $ algebraMap (𝓞 K) K).toMonoidHom.comp $
- Units.coeHom _).isOfFinOrder hx).norm_eq_one, fun h ↦ isOfFinOrder_iff_pow_eq_one.2 ?_⟩
- obtain ⟨n, hn, hx⟩ := Embeddings.pow_eq_one_of_norm_eq_one K ℂ x.val.prop h
- exact ⟨n, hn, by ext; rw [coe_pow, hx, coe_one]⟩
-
-/-- Shortcut instance because Lean tends to time out before finding the general instance. -/
-instance : Nonempty (torsion K) := One.instNonempty
-
-/-- The torsion subgroup is finite. -/
-instance [NumberField K] : Fintype (torsion K) := by
- refine @Fintype.ofFinite _ (Set.finite_coe_iff.mpr ?_)
- refine Set.Finite.of_finite_image ?_ ((coe_injective K).injOn _)
- refine (Embeddings.finite_of_norm_le K ℂ 1).subset
- (fun a ⟨u, ⟨h_tors, h_ua⟩⟩ => ⟨?_, fun φ => ?_⟩)
- · rw [← h_ua]
- exact u.val.prop
- · rw [← h_ua]
- exact le_of_eq ((eq_iff_eq _ 1).mp ((mem_torsion K).mp h_tors) φ)
-
--- a shortcut instance to stop the next instance from timing out
-instance [NumberField K] : Finite (torsion K) := inferInstance
-
-/-- The torsion subgroup is cylic. -/
-instance [NumberField K] : IsCyclic (torsion K) := subgroup_units_cyclic _
-
-/-- The order of the torsion subgroup as a positive integer. -/
-def torsionOrder [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.card_pos⟩
-
-/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
- order dividing `k`. -/
-theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
- {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
- rw [mem_rootsOfUnity]
- refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
- refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
- · exact orderOf_dvd_of_pow_eq_one h
- · have hζ : ζ ∈ torsion K := by
- rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
- exact ⟨k, k.prop, h⟩
- rw [orderOf_submonoid (⟨ζ, hζ⟩ : torsion K)]
- exact orderOf_dvd_card
-
-/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
-group. -/
-theorem rootsOfUnity_eq_torsion [NumberField K] :
- rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
- ext ζ
- rw [torsion, mem_rootsOfUnity]
- refine ⟨fun h => ?_, fun h => ?_⟩
- · rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
- exact ⟨↑(torsionOrder K), (torsionOrder K).prop, h⟩
- · exact Subtype.ext_iff.mp (@pow_card_eq_one (torsion K) _ _ ⟨ζ, h⟩)
-
-end torsion
-
-namespace dirichletUnitTheorem
+namespace NumberField.Units.dirichletUnitTheorem
/-!
### Dirichlet Unit Theorem
-This section is devoted to the proof of Dirichlet's unit theorem.
We define a group morphism from `(𝓞 K)ˣ` to `{w : InfinitePlace K // w ≠ w₀} → ℝ` where `w₀` is a
distinguished (arbitrary) infinite place, prove that its kernel is the torsion subgroup (see
@@ -181,7 +64,6 @@ see the section `span_top` below for more details.
open scoped Classical
open Finset
-variable [NumberField K]
variable {K}
/-- The distinguished infinite place. -/
@@ -404,7 +286,7 @@ theorem exists_unit (w₁ : InfinitePlace K) :
(Ideal.span ({ (seq K w₁ hB n : 𝓞 K) }) = Ideal.span ({ (seq K w₁ hB m : 𝓞 K) }))
· have hu := Ideal.span_singleton_eq_span_singleton.mp h
refine ⟨hu.choose, fun w hw => Real.log_neg ?_ ?_⟩
- · simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, ne_zero, not_false_eq_true]
+ · simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, Units.ne_zero, not_false_eq_true]
· calc
_ = w ((seq K w₁ hB m : K) * (seq K w₁ hB n : K)⁻¹) := by
rw [← congr_arg ((↑) : (𝓞 K) → K) hu.choose_spec, mul_comm, Submonoid.coe_mul,
This PR splits the file NumberField/Units.lean
into two files placed into a new folder NumberField/Units
:
Units/Basic.lean
contains the basic definitions and results about the unit group and its torsion subgroup,Units/DirichletTheorem.lean
contains the proof of Dirichlet unit theorem and results about the structure of the unit group and its rank.@@ -442,12 +442,12 @@ theorem unitLattice_span_eq_top :
simp_rw [Real.norm_eq_abs, B, Basis.coePiBasisFun.toMatrix_eq_transpose, Matrix.transpose_apply]
rw [← sub_pos, sum_congr rfl (fun x hx => abs_of_neg ?_), sum_neg_distrib, sub_neg_eq_add,
sum_erase_eq_sub (mem_univ _), ← add_comm_sub]
- refine add_pos_of_nonneg_of_pos ?_ ?_
- · rw [sub_nonneg]
- exact le_abs_self _
- · rw [sum_logEmbedding_component (exists_unit K w).choose]
- refine mul_pos_of_neg_of_neg ?_ ((exists_unit K w).choose_spec _ w.prop.symm)
- rw [mult]; split_ifs <;> norm_num
+ · refine add_pos_of_nonneg_of_pos ?_ ?_
+ · rw [sub_nonneg]
+ exact le_abs_self _
+ · rw [sum_logEmbedding_component (exists_unit K w).choose]
+ refine mul_pos_of_neg_of_neg ?_ ((exists_unit K w).choose_spec _ w.prop.symm)
+ rw [mult]; split_ifs <;> norm_num
· refine mul_neg_of_pos_of_neg ?_ ((exists_unit K w).choose_spec x ?_)
· rw [mult]; split_ifs <;> norm_num
· exact Subtype.ext_iff_val.not.mp (ne_of_mem_erase hx)
The theorem NumberField.Units.exist_unique_eq_mul_prod
was using nested ∃!
's rather than a single ∃!
.
@@ -567,8 +567,8 @@ theorem fun_eq_repr {x ζ : (𝓞 K)ˣ} {f : Fin (rank K) → ℤ} (hζ : ζ ∈
/-- **Dirichlet Unit Theorem**. Any unit `x` of `𝓞 K` can be written uniquely as the product of
a root of unity and powers of the units of the fundamental system `fundSystem`. -/
-theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K), ∃! (e : Fin (rank K) → ℤ),
- x = ζ * ∏ i, (fundSystem K i) ^ (e i) := by
+theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! ζe : torsion K × (Fin (rank K) → ℤ),
+ x = ζe.1 * ∏ i, (fundSystem K i) ^ (ζe.2 i) := by
let ζ := x * (∏ i, (fundSystem K i) ^ ((basisModTorsion K).repr (Additive.ofMul ↑x) i))⁻¹
have h_tors : ζ ∈ torsion K := by
rw [← QuotientGroup.eq_one_iff, QuotientGroup.mk_mul, QuotientGroup.mk_inv, ← ofMul_eq_zero,
@@ -576,13 +576,10 @@ theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K), ∃!
simp_rw [QuotientGroup.mk_zpow, ofMul_zpow, fundSystem, QuotientGroup.out_eq']
rw [add_eq_zero_iff_eq_neg, neg_neg]
exact ((basisModTorsion K).sum_repr (Additive.ofMul ↑x)).symm
- refine ⟨⟨ζ, h_tors⟩, ?_, ?_⟩
- · refine ⟨((basisModTorsion K).repr (Additive.ofMul ↑x) : Fin (rank K) → ℤ), ?_, ?_⟩
- · simp only [ζ, _root_.inv_mul_cancel_right]
- · exact fun _ hf => fun_eq_repr K h_tors hf
- · rintro η ⟨_, hf, _⟩
- simp_rw [fun_eq_repr K η.prop hf] at hf
- ext1; dsimp only [ζ]
+ refine ⟨⟨⟨ζ, h_tors⟩, ((basisModTorsion K).repr (Additive.ofMul ↑x) : Fin (rank K) → ℤ)⟩, ?_, ?_⟩
+ · simp only [ζ, _root_.inv_mul_cancel_right]
+ · rintro ⟨⟨ζ', h_tors'⟩, η⟩ hf
+ simp only [ζ, ← fun_eq_repr K h_tors' hf, Prod.mk.injEq, Subtype.mk.injEq, and_true]
nth_rewrite 1 [hf]
rw [_root_.mul_inv_cancel_right]
ExistsUnique
notation throw an error when used with more than one binder (#12218)
@@ -567,7 +567,7 @@ theorem fun_eq_repr {x ζ : (𝓞 K)ˣ} {f : Fin (rank K) → ℤ} (hζ : ζ ∈
/-- **Dirichlet Unit Theorem**. Any unit `x` of `𝓞 K` can be written uniquely as the product of
a root of unity and powers of the units of the fundamental system `fundSystem`. -/
-theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K) (e : Fin (rank K) → ℤ),
+theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K), ∃! (e : Fin (rank K) → ℤ),
x = ζ * ∏ i, (fundSystem K i) ^ (e i) := by
let ζ := x * (∏ i, (fundSystem K i) ^ ((basisModTorsion K).repr (Additive.ofMul ↑x) i))⁻¹
have h_tors : ζ ∈ torsion K := by
@@ -425,7 +425,7 @@ theorem exists_unit (w₁ : InfinitePlace K) :
theorem unitLattice_span_eq_top :
Submodule.span ℝ (unitLattice K : Set ({w : InfinitePlace K // w ≠ w₀} → ℝ)) = ⊤ := by
- refine le_antisymm (le_top) ?_
+ refine le_antisymm le_top ?_
-- The standard basis
let B := Pi.basisFun ℝ {w : InfinitePlace K // w ≠ w₀}
-- The image by log_embedding of the family of units constructed above
CanonicalEmbedding
(#11917)
Create a new directory for the split of CanonicalEmbedding
since more material is coming.
Also add some docstrings.
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Xavier Roblot
-/
import Mathlib.LinearAlgebra.Matrix.Gershgorin
-import Mathlib.NumberTheory.NumberField.ConvexBody
+import Mathlib.NumberTheory.NumberField.CanonicalEmbedding.ConvexBody
import Mathlib.NumberTheory.NumberField.Norm
import Mathlib.RingTheory.RootsOfUnity.Basic
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.
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Xavier Roblot
-/
import Mathlib.LinearAlgebra.Matrix.Gershgorin
-import Mathlib.NumberTheory.NumberField.CanonicalEmbedding
+import Mathlib.NumberTheory.NumberField.ConvexBody
import Mathlib.NumberTheory.NumberField.Norm
import Mathlib.RingTheory.RootsOfUnity.Basic
Init.Data.Subtype.Basic
(#11887)
The few useful lemmas can go to Data.Subtype.Basic
and the other ones can be deleted.
@@ -327,7 +327,7 @@ theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
obtain ⟨g, h_geqf, h_gprod⟩ := adjust_f K B this
obtain ⟨y, hy, h_ynz, h_yle⟩ := exists_ne_zero_mem_ringOfIntegers_lt (f := g)
(by rw [convexBodyLT_volume]; convert hB; exact congr_arg ((↑): NNReal → ENNReal) h_gprod)
- refine ⟨⟨y, hy⟩, Subtype.ne_of_val_ne h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
+ refine ⟨⟨y, hy⟩, Subtype.coe_ne_coe.1 h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
· rw [← Rat.cast_le (K := ℝ), Rat.cast_natCast]
calc
_ = ∏ w : InfinitePlace K, w y ^ mult w := (prod_eq_abs_norm (y : K)).symm
@@ -360,7 +360,7 @@ theorem seq_ne_zero (n : ℕ) : (seq K w₁ hB n : K) ≠ 0 := by
/-- The terms of the sequence have nonzero norm. -/
theorem seq_norm_ne_zero (n : ℕ) : Algebra.norm ℤ (seq K w₁ hB n : 𝓞 K) ≠ 0 :=
- Algebra.norm_ne_zero_iff.mpr (Subtype.ne_of_val_ne (seq_ne_zero K w₁ hB n))
+ Algebra.norm_ne_zero_iff.mpr (Subtype.coe_ne_coe.1 (seq_ne_zero K w₁ hB n))
/-- The sequence is strictly decreasing at infinite places distinct from `w₁`. -/
theorem seq_decreasing {n m : ℕ} (h : n < m) (w : InfinitePlace K) (hw : w ≠ w₁) :
@@ -328,7 +328,7 @@ theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
obtain ⟨y, hy, h_ynz, h_yle⟩ := exists_ne_zero_mem_ringOfIntegers_lt (f := g)
(by rw [convexBodyLT_volume]; convert hB; exact congr_arg ((↑): NNReal → ENNReal) h_gprod)
refine ⟨⟨y, hy⟩, Subtype.ne_of_val_ne h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
- · rw [← Rat.cast_le (K := ℝ), Rat.cast_coe_nat]
+ · rw [← Rat.cast_le (K := ℝ), Rat.cast_natCast]
calc
_ = ∏ w : InfinitePlace K, w y ^ mult w := (prod_eq_abs_norm (y : K)).symm
_ ≤ ∏ w : InfinitePlace K, (g w : ℝ) ^ mult w := by
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)
@@ -182,7 +182,6 @@ open scoped Classical
open Finset
variable [NumberField K]
-
variable {K}
/-- The distinguished infinite place. -/
@@ -478,22 +478,18 @@ instance instDiscrete_unitLattice : DiscreteTopology (unitLattice K) := by
rintro ⟨x, hx, rfl⟩
exact ⟨Subtype.mem x, hx⟩
+instance instZlattice_unitLattice : IsZlattice ℝ (unitLattice K) where
+ span_top := unitLattice_span_eq_top K
+
protected theorem finrank_eq_rank :
finrank ℝ ({w : InfinitePlace K // w ≠ w₀} → ℝ) = Units.rank K := by
simp only [finrank_fintype_fun_eq_card, Fintype.card_subtype_compl,
Fintype.card_ofSubsingleton, rank]
-instance instModuleFree_unitLattice : Module.Free ℤ (unitLattice K) :=
- Zlattice.module_free ℝ (unitLattice_span_eq_top K)
-
-instance instModuleFinite_unitLattice : Module.Finite ℤ (unitLattice K) :=
- Zlattice.module_finite ℝ (unitLattice_span_eq_top K)
-
@[simp]
theorem unitLattice_rank :
finrank ℤ (unitLattice K) = Units.rank K := by
- rw [← Units.finrank_eq_rank]
- exact Zlattice.rank ℝ (unitLattice_span_eq_top K)
+ rw [← Units.finrank_eq_rank, Zlattice.rank ℝ]
/-- The linear equivalence between `unitLattice` and `(𝓞 K)ˣ ⧸ (torsion K)` as an additive
`ℤ`-module. -/
@@ -514,7 +510,7 @@ def unitLatticeEquiv : (unitLattice K) ≃ₗ[ℤ] Additive ((𝓞 K)ˣ ⧸ (tor
rfl
instance : Module.Free ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
- (instModuleFree_unitLattice K).of_equiv' (unitLatticeEquiv K)
+ Module.Free.of_equiv (unitLatticeEquiv K)
instance : Module.Finite ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
Module.Finite.equiv (unitLatticeEquiv K)
open Classical
(#11199)
We remove all but one open Classical
s, 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.
@@ -178,7 +178,8 @@ spans the full space over `ℝ` (see `unitLattice_span_eq_top`); this is the mai
see the section `span_top` below for more details.
-/
-open Classical Finset
+open scoped Classical
+open Finset
variable [NumberField K]
@@ -460,7 +461,8 @@ section statements
variable [NumberField K]
-open dirichletUnitTheorem FiniteDimensional Classical
+open scoped Classical
+open dirichletUnitTheorem FiniteDimensional
/-- The unit rank of the number field `K`, it is equal to `card (InfinitePlace K) - 1`. -/
def rank : ℕ := Fintype.card (InfinitePlace K) - 1
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>
@@ -439,7 +439,7 @@ theorem unitLattice_span_eq_top :
rw [Basis.det_apply]
-- We use a specific lemma to prove that this determinant is nonzero
refine det_ne_zero_of_sum_col_lt_diag (fun w => ?_)
- simp_rw [Real.norm_eq_abs, Basis.coePiBasisFun.toMatrix_eq_transpose, Matrix.transpose_apply]
+ simp_rw [Real.norm_eq_abs, B, Basis.coePiBasisFun.toMatrix_eq_transpose, Matrix.transpose_apply]
rw [← sub_pos, sum_congr rfl (fun x hx => abs_of_neg ?_), sum_neg_distrib, sub_neg_eq_add,
sum_erase_eq_sub (mem_univ _), ← add_comm_sub]
refine add_pos_of_nonneg_of_pos ?_ ?_
@@ -581,11 +581,11 @@ theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K) (e : F
exact ((basisModTorsion K).sum_repr (Additive.ofMul ↑x)).symm
refine ⟨⟨ζ, h_tors⟩, ?_, ?_⟩
· refine ⟨((basisModTorsion K).repr (Additive.ofMul ↑x) : Fin (rank K) → ℤ), ?_, ?_⟩
- · simp only [_root_.inv_mul_cancel_right]
+ · simp only [ζ, _root_.inv_mul_cancel_right]
· exact fun _ hf => fun_eq_repr K h_tors hf
· rintro η ⟨_, hf, _⟩
simp_rw [fun_eq_repr K η.prop hf] at hf
- ext1; dsimp only
+ ext1; dsimp only [ζ]
nth_rewrite 1 [hf]
rw [_root_.mul_inv_cancel_right]
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>
@@ -314,6 +314,8 @@ sequence defining the same ideal and their quotient is the desired unit `u_w₁`
open NumberField.mixedEmbedding NNReal
+/- TODO: Remove!. Necessary to prevent a timeout that ends at here. #10131 -/
+attribute [-instance] FractionalIdeal.commSemiring
variable (w₁ : InfinitePlace K) {B : ℕ} (hB : minkowskiBound K 1 < (convexBodyLTFactor K) * B)
/-- This result shows that there always exists a next term in the sequence. -/
@@ -325,7 +325,7 @@ theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
obtain ⟨g, h_geqf, h_gprod⟩ := adjust_f K B this
obtain ⟨y, hy, h_ynz, h_yle⟩ := exists_ne_zero_mem_ringOfIntegers_lt (f := g)
(by rw [convexBodyLT_volume]; convert hB; exact congr_arg ((↑): NNReal → ENNReal) h_gprod)
- refine ⟨⟨y, hy⟩, Subtype.ne_of_val_ne h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
+ refine ⟨⟨y, hy⟩, Subtype.ne_of_val_ne h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
· rw [← Rat.cast_le (K := ℝ), Rat.cast_coe_nat]
calc
_ = ∏ w : InfinitePlace K, w y ^ mult w := (prod_eq_abs_norm (y : K)).symm
@@ -396,7 +396,7 @@ theorem exists_unit (w₁ : InfinitePlace K) :
∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K 1 < (convexBodyLTFactor K) * B := by
conv => congr; ext; rw [mul_comm]
- exact ENNReal.exists_nat_mul_gt (ne_of_gt (convexBodyLTFactor_pos K))
+ exact ENNReal.exists_nat_mul_gt (ENNReal.coe_ne_zero.mpr (convexBodyLTFactor_ne_zero K))
(ne_of_lt (minkowskiBound_lt_top K 1))
rsuffices ⟨n, m, hnm, h⟩ : ∃ n m, n < m ∧
(Ideal.span ({ (seq K w₁ hB n : 𝓞 K) }) = Ideal.span ({ (seq K w₁ hB m : 𝓞 K) }))
@@ -218,7 +218,7 @@ theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
mult w * Real.log (w x) = 0 ↔ w x = 1 := by
rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
- · linarith [(map_nonneg _ _ : 0 ≤ w x)]
+ · linarith [(apply_nonneg _ _ : 0 ≤ w x)]
· simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
· refine (ne_of_gt ?_)
rw [mult]; split_ifs <;> norm_num
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.
@@ -6,7 +6,6 @@ Authors: Xavier Roblot
import Mathlib.LinearAlgebra.Matrix.Gershgorin
import Mathlib.NumberTheory.NumberField.CanonicalEmbedding
import Mathlib.NumberTheory.NumberField.Norm
-import Mathlib.RingTheory.Ideal.Norm
import Mathlib.RingTheory.RootsOfUnity.Basic
#align_import number_theory.number_field.units from "leanprover-community/mathlib"@"00f91228655eecdcd3ac97a7fd8dbcb139fe990a"
@@ -33,7 +32,7 @@ as an additive `ℤ`-module.
* `NumberField.Units.mem_torsion`: a unit `x : (𝓞 K)ˣ` is torsion iff `w x = 1` for all infinite
places `w` of `K`.
-* `NumberField.Units.exist_unique_eq_mul_prod`: **Dirichlet Unit Theorem**. Any unit `x` of `𝓞 K`
+* `NumberField.Units.exist_unique_eq_mul_prod`: **Dirichlet Unit Theorem**. Any unit of `𝓞 K`
can be written uniquely as the product of a root of unity and powers of the units of the
fundamental system `fundSystem`.
@@ -315,7 +314,7 @@ sequence defining the same ideal and their quotient is the desired unit `u_w₁`
open NumberField.mixedEmbedding NNReal
-variable (w₁ : InfinitePlace K) {B : ℕ} (hB : minkowskiBound K < (convexBodyLTFactor K) * B)
+variable (w₁ : InfinitePlace K) {B : ℕ} (hB : minkowskiBound K 1 < (convexBodyLTFactor K) * B)
/-- This result shows that there always exists a next term in the sequence. -/
theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
@@ -324,9 +323,9 @@ theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
fun w => ⟨(w x) / 2, div_nonneg (AbsoluteValue.nonneg _ _) (by norm_num)⟩
suffices ∀ w, w ≠ w₁ → f w ≠ 0 by
obtain ⟨g, h_geqf, h_gprod⟩ := adjust_f K B this
- obtain ⟨y, h_ynz, h_yle⟩ := exists_ne_zero_mem_ringOfIntegers_lt (f := g)
+ obtain ⟨y, hy, h_ynz, h_yle⟩ := exists_ne_zero_mem_ringOfIntegers_lt (f := g)
(by rw [convexBodyLT_volume]; convert hB; exact congr_arg ((↑): NNReal → ENNReal) h_gprod)
- refine ⟨y, h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
+ refine ⟨⟨y, hy⟩, Subtype.ne_of_val_ne h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
· rw [← Rat.cast_le (K := ℝ), Rat.cast_coe_nat]
calc
_ = ∏ w : InfinitePlace K, w y ^ mult w := (prod_eq_abs_norm (y : K)).symm
@@ -395,10 +394,10 @@ image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
`unitLattice_span_eq_top`. -/
theorem exists_unit (w₁ : InfinitePlace K) :
∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
- obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLTFactor K) * B := by
+ obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K 1 < (convexBodyLTFactor K) * B := by
conv => congr; ext; rw [mul_comm]
exact ENNReal.exists_nat_mul_gt (ne_of_gt (convexBodyLTFactor_pos K))
- (ne_of_lt (minkowskiBound_lt_top K))
+ (ne_of_lt (minkowskiBound_lt_top K 1))
rsuffices ⟨n, m, hnm, h⟩ : ∃ n m, n < m ∧
(Ideal.span ({ (seq K w₁ hB n : 𝓞 K) }) = Ideal.span ({ (seq K w₁ hB m : 𝓞 K) }))
· have hu := Ideal.span_singleton_eq_span_singleton.mp h
@@ -114,7 +114,7 @@ theorem mem_torsion {x : (𝓞 K)ˣ} [NumberField K] :
exact ⟨n, hn, by ext; rw [coe_pow, hx, coe_one]⟩
/-- Shortcut instance because Lean tends to time out before finding the general instance. -/
-instance : Nonempty (torsion K) := One.nonempty
+instance : Nonempty (torsion K) := One.instNonempty
/-- The torsion subgroup is finite. -/
instance [NumberField K] : Fintype (torsion K) := by
Infinite
assumption by Nontrivial
in Ideal.absNorm (#9684)
Also fix a typo and remove a now useless maxHeartbeats
in Mathlib.NumberTheory.NumberField.Units
.
@@ -34,7 +34,7 @@ as an additive `ℤ`-module.
places `w` of `K`.
* `NumberField.Units.exist_unique_eq_mul_prod`: **Dirichlet Unit Theorem**. Any unit `x` of `𝓞 K`
-can be written uniquely as the product of a root of unity and powers of the units of of the
+can be written uniquely as the product of a root of unity and powers of the units of the
fundamental system `fundSystem`.
## Tags
@@ -492,7 +492,6 @@ theorem unitLattice_rank :
rw [← Units.finrank_eq_rank]
exact Zlattice.rank ℝ (unitLattice_span_eq_top K)
-set_option synthInstance.maxHeartbeats 27000 in
/-- The linear equivalence between `unitLattice` and `(𝓞 K)ˣ ⧸ (torsion K)` as an additive
`ℤ`-module. -/
def unitLatticeEquiv : (unitLattice K) ≃ₗ[ℤ] Additive ((𝓞 K)ˣ ⧸ (torsion K)) := by
This lemma already existed, but with an impractical spelling.
From LeanAPAP
@@ -107,12 +107,11 @@ def torsion : Subgroup (𝓞 K)ˣ := CommGroup.torsion (𝓞 K)ˣ
theorem mem_torsion {x : (𝓞 K)ˣ} [NumberField K] :
x ∈ torsion K ↔ ∀ w : InfinitePlace K, w x = 1 := by
- rw [eq_iff_eq (x : K) 1, torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
- refine ⟨fun ⟨n, h_pos, h_eq⟩ φ => ?_, fun h => ?_⟩
- · refine norm_map_one_of_pow_eq_one φ.toMonoidHom (k := ⟨n, h_pos⟩) ?_
- rw [PNat.mk_coe, ← coe_pow, h_eq, coe_one]
- · obtain ⟨n, hn, hx⟩ := Embeddings.pow_eq_one_of_norm_eq_one K ℂ x.val.prop h
- exact ⟨n, hn, by ext; rw [coe_pow, hx, coe_one]⟩
+ rw [eq_iff_eq (x : K) 1, torsion, CommGroup.mem_torsion]
+ refine ⟨fun hx φ ↦ (((φ.comp $ algebraMap (𝓞 K) K).toMonoidHom.comp $
+ Units.coeHom _).isOfFinOrder hx).norm_eq_one, fun h ↦ isOfFinOrder_iff_pow_eq_one.2 ?_⟩
+ obtain ⟨n, hn, hx⟩ := Embeddings.pow_eq_one_of_norm_eq_one K ℂ x.val.prop h
+ exact ⟨n, hn, by ext; rw [coe_pow, hx, coe_one]⟩
/-- Shortcut instance because Lean tends to time out before finding the general instance. -/
instance : Nonempty (torsion K) := One.nonempty
The names for lemmas about monotonicity of (a ^ ·)
and (· ^ n)
were a mess. This PR tidies up everything related by following the naming convention for (a * ·)
and (· * b)
. Namely, (a ^ ·)
is pow_right
and (· ^ n)
is pow_left
in lemma names. All lemma renames follow the corresponding multiplication lemma names closely.
Algebra.GroupPower.Order
pow_mono
→ pow_right_mono
pow_le_pow
→ pow_le_pow_right
pow_le_pow_of_le_left
→ pow_le_pow_left
pow_lt_pow_of_lt_left
→ pow_lt_pow_left
strictMonoOn_pow
→ pow_left_strictMonoOn
pow_strictMono_right
→ pow_right_strictMono
pow_lt_pow
→ pow_lt_pow_right
pow_lt_pow_iff
→ pow_lt_pow_iff_right
pow_le_pow_iff
→ pow_le_pow_iff_right
self_lt_pow
→ lt_self_pow
strictAnti_pow
→ pow_right_strictAnti
pow_lt_pow_iff_of_lt_one
→ pow_lt_pow_iff_right_of_lt_one
pow_lt_pow_of_lt_one
→ pow_lt_pow_right_of_lt_one
lt_of_pow_lt_pow
→ lt_of_pow_lt_pow_left
le_of_pow_le_pow
→ le_of_pow_le_pow_left
pow_lt_pow₀
→ pow_lt_pow_right₀
Algebra.GroupPower.CovariantClass
pow_le_pow_of_le_left'
→ pow_le_pow_left'
nsmul_le_nsmul_of_le_right
→ nsmul_le_nsmul_right
pow_lt_pow'
→ pow_lt_pow_right'
nsmul_lt_nsmul
→ nsmul_lt_nsmul_left
pow_strictMono_left
→ pow_right_strictMono'
nsmul_strictMono_right
→ nsmul_left_strictMono
StrictMono.pow_right'
→ StrictMono.pow_const
StrictMono.nsmul_left
→ StrictMono.const_nsmul
pow_strictMono_right'
→ pow_left_strictMono
nsmul_strictMono_left
→ nsmul_right_strictMono
Monotone.pow_right
→ Monotone.pow_const
Monotone.nsmul_left
→ Monotone.const_nsmul
lt_of_pow_lt_pow'
→ lt_of_pow_lt_pow_left'
lt_of_nsmul_lt_nsmul
→ lt_of_nsmul_lt_nsmul_right
pow_le_pow'
→ pow_le_pow_right'
nsmul_le_nsmul
→ nsmul_le_nsmul_left
pow_le_pow_of_le_one'
→ pow_le_pow_right_of_le_one'
nsmul_le_nsmul_of_nonpos
→ nsmul_le_nsmul_left_of_nonpos
le_of_pow_le_pow'
→ le_of_pow_le_pow_left'
le_of_nsmul_le_nsmul'
→ le_of_nsmul_le_nsmul_right'
pow_le_pow_iff'
→ pow_le_pow_iff_right'
nsmul_le_nsmul_iff
→ nsmul_le_nsmul_iff_left
pow_lt_pow_iff'
→ pow_lt_pow_iff_right'
nsmul_lt_nsmul_iff
→ nsmul_lt_nsmul_iff_left
Data.Nat.Pow
Nat.pow_lt_pow_of_lt_left
→ Nat.pow_lt_pow_left
Nat.pow_le_iff_le_left
→ Nat.pow_le_pow_iff_left
Nat.pow_lt_iff_lt_left
→ Nat.pow_lt_pow_iff_left
pow_le_pow_iff_left
pow_lt_pow_iff_left
pow_right_injective
pow_right_inj
Nat.pow_le_pow_left
to have the correct name since Nat.pow_le_pow_of_le_left
is in Std.Nat.pow_le_pow_right
to have the correct name since Nat.pow_le_pow_of_le_right
is in Std.self_le_pow
was a duplicate of le_self_pow
.Nat.pow_lt_pow_of_lt_right
is defeq to pow_lt_pow_right
.Nat.pow_right_strictMono
is defeq to pow_right_strictMono
.Nat.pow_le_iff_le_right
is defeq to pow_le_pow_iff_right
.Nat.pow_lt_iff_lt_right
is defeq to pow_lt_pow_iff_right
.0 < n
or 1 ≤ n
to n ≠ 0
.Nat
lemmas have been protected
.@@ -334,7 +334,7 @@ theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
_ ≤ ∏ w : InfinitePlace K, (g w : ℝ) ^ mult w := by
refine prod_le_prod ?_ ?_
· exact fun _ _ => pow_nonneg (by positivity) _
- · exact fun w _ => pow_le_pow_of_le_left (by positivity) (le_of_lt (h_yle w)) (mult w)
+ · exact fun w _ => pow_le_pow_left (by positivity) (le_of_lt (h_yle w)) (mult w)
_ ≤ (B : ℝ) := by
simp_rw [← NNReal.coe_pow, ← NNReal.coe_prod]
exact le_of_eq (congr_arg toReal h_gprod)
@@ -248,9 +248,9 @@ theorem logEmbedding_component_le {r : ℝ} {x : (𝓞 K)ˣ} (hr : 0 ≤ r) (h :
theorem log_le_of_logEmbedding_le {r : ℝ} {x : (𝓞 K)ˣ} (hr : 0 ≤ r) (h : ‖logEmbedding K x‖ ≤ r)
(w : InfinitePlace K) : |Real.log (w x)| ≤ (Fintype.card (InfinitePlace K)) * r := by
have tool : ∀ x : ℝ, 0 ≤ x → x ≤ mult w * x := fun x hx => by
- nth_rw 1 [← one_mul x]
- refine mul_le_mul ?_ le_rfl hx ?_
- all_goals { rw [mult]; split_ifs <;> norm_num }
+ nth_rw 1 [← one_mul x]
+ refine mul_le_mul ?_ le_rfl hx ?_
+ all_goals { rw [mult]; split_ifs <;> norm_num }
by_cases hw : w = w₀
· have hyp := congr_arg (‖·‖) (sum_logEmbedding_component x).symm
replace hyp := (le_of_eq hyp).trans (norm_sum_le _ _)
@@ -316,7 +316,7 @@ sequence defining the same ideal and their quotient is the desired unit `u_w₁`
open NumberField.mixedEmbedding NNReal
-variable (w₁ : InfinitePlace K) {B : ℕ} (hB : minkowskiBound K < (convexBodyLtFactor K) * B)
+variable (w₁ : InfinitePlace K) {B : ℕ} (hB : minkowskiBound K < (convexBodyLTFactor K) * B)
/-- This result shows that there always exists a next term in the sequence. -/
theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
@@ -326,7 +326,7 @@ theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
suffices ∀ w, w ≠ w₁ → f w ≠ 0 by
obtain ⟨g, h_geqf, h_gprod⟩ := adjust_f K B this
obtain ⟨y, h_ynz, h_yle⟩ := exists_ne_zero_mem_ringOfIntegers_lt (f := g)
- (by rw [convexBodyLt_volume]; convert hB; exact congr_arg ((↑): NNReal → ENNReal) h_gprod)
+ (by rw [convexBodyLT_volume]; convert hB; exact congr_arg ((↑): NNReal → ENNReal) h_gprod)
refine ⟨y, h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
· rw [← Rat.cast_le (K := ℝ), Rat.cast_coe_nat]
calc
@@ -396,9 +396,9 @@ image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
`unitLattice_span_eq_top`. -/
theorem exists_unit (w₁ : InfinitePlace K) :
∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
- obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLtFactor K) * B := by
+ obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLTFactor K) * B := by
conv => congr; ext; rw [mul_comm]
- exact ENNReal.exists_nat_mul_gt (ne_of_gt (convexBodyLtFactor_pos K))
+ exact ENNReal.exists_nat_mul_gt (ne_of_gt (convexBodyLTFactor_pos K))
(ne_of_lt (minkowskiBound_lt_top K))
rsuffices ⟨n, m, hnm, h⟩ : ∃ n m, n < m ∧
(Ideal.span ({ (seq K w₁ hB n : 𝓞 K) }) = Ideal.span ({ (seq K w₁ hB m : 𝓞 K) }))
@@ -562,11 +562,12 @@ theorem fun_eq_repr {x ζ : (𝓞 K)ˣ} {f : Fin (rank K) → ℤ} (hζ : ζ ∈
suffices Additive.ofMul ↑x = ∑ i, (f i) • (basisModTorsion K i) by
rw [← (basisModTorsion K).repr_sum_self f, ← this]
calc
- Additive.ofMul ↑x = ∑ i, (f i) • Additive.ofMul ↑(fundSystem K i) := by
- rw [h, QuotientGroup.mk_mul, (QuotientGroup.eq_one_iff _).mpr hζ, one_mul,
- QuotientGroup.mk_prod, ofMul_prod]; rfl
- _ = ∑ i, (f i) • (basisModTorsion K i) := by
- simp_rw [fundSystem, QuotientGroup.out_eq', ofMul_toMul]
+ Additive.ofMul ↑x
+ _ = ∑ i, (f i) • Additive.ofMul ↑(fundSystem K i) := by
+ rw [h, QuotientGroup.mk_mul, (QuotientGroup.eq_one_iff _).mpr hζ, one_mul,
+ QuotientGroup.mk_prod, ofMul_prod]; rfl
+ _ = ∑ i, (f i) • (basisModTorsion K i) := by
+ simp_rw [fundSystem, QuotientGroup.out_eq', ofMul_toMul]
/-- **Dirichlet Unit Theorem**. Any unit `x` of `𝓞 K` can be written uniquely as the product of
a root of unity and powers of the units of the fundamental system `fundSystem`. -/
Currently in Mathlib there is no class for magma that are commutative but not associative - Field
extends CommRing
and DivisionRing
, CommRing
extends Ring
and CommMonoid
, CommGroup
extends Group
and CommMonoid
and CommMonoid
extends CommSemigroup
and Monoid
. CommSemigroup
currently extends only Semigroup
and has mul_comm
as a property.
This PR moves mul_comm
into a new CommMagma
(AddCommMagma
) class which extends Mul
(Add
). CommSemigroup
now extends Semigroup
and CommMagma
.
The rest of Mathlib4 compiles as before, except with the need to increase synthInstance.maxHeartbeats
for lift_of_splits
.
(Update: The linter is objecting to an unused argument in what seems to be a completely unrelated bit of code (AddEquiv.lpPiLp
). Trying a nolint
for now.)
Also referenced in https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/.60add_comm.60.20without.20.60add_assoc.60
Co-authored-by: Jireh Loreaux <loreaujy@gmail.com> Co-authored-by: Christopher Hoskin <mans0954@users.noreply.github.com> Co-authored-by: Christopher Hoskin <christopher.hoskin@overleaf.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com>
@@ -493,6 +493,7 @@ theorem unitLattice_rank :
rw [← Units.finrank_eq_rank]
exact Zlattice.rank ℝ (unitLattice_span_eq_top K)
+set_option synthInstance.maxHeartbeats 27000 in
/-- The linear equivalence between `unitLattice` and `(𝓞 K)ˣ ⧸ (torsion K)` as an additive
`ℤ`-module. -/
def unitLatticeEquiv : (unitLattice K) ≃ₗ[ℤ] Additive ((𝓞 K)ˣ ⧸ (torsion K)) := by
Mostly, this means replacing "of_open" by "of_isOpen". A few lemmas names were misleading and are corrected differently. Zulip discussion.
@@ -466,7 +466,7 @@ open dirichletUnitTheorem FiniteDimensional Classical
def rank : ℕ := Fintype.card (InfinitePlace K) - 1
instance instDiscrete_unitLattice : DiscreteTopology (unitLattice K) := by
- refine discreteTopology_of_open_singleton_zero ?_
+ refine discreteTopology_of_isOpen_singleton_zero ?_
refine isOpen_singleton_of_finite_mem_nhds 0 (s := Metric.closedBall 0 1) ?_ ?_
· exact Metric.closedBall_mem_nhds _ (by norm_num)
· refine Set.Finite.of_finite_image ?_ (Set.injOn_of_injective Subtype.val_injective _)
The following lemma:
theorem Algebra.coe_norm_int {K : Type*} [Field K] [NumberField K] (x : 𝓞 K) :
Algebra.norm ℤ x = Algebra.norm ℚ (x : K)
is currently in NumberField.Units
but it belongs to NumberField.Norm
@@ -55,10 +55,6 @@ theorem Rat.RingOfIntegers.isUnit_iff {x : 𝓞 ℚ} : IsUnit x ↔ (x : ℚ) =
Subtype.coe_injective.eq_iff]; rfl
#align rat.ring_of_integers.is_unit_iff Rat.RingOfIntegers.isUnit_iff
-theorem Algebra.coe_norm_int {K : Type*} [Field K] [NumberField K] (x : 𝓞 K) :
- Algebra.norm ℤ x = Algebra.norm ℚ (x : K) :=
- (Algebra.norm_localization (R := ℤ) (Rₘ := ℚ) (S := 𝓞 K) (Sₘ := K) (nonZeroDivisors ℤ) x).symm
-
end Rat
variable (K : Type*) [Field K]
@@ -41,8 +41,6 @@ fundamental system `fundSystem`.
number field, units
-/
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
-
open scoped NumberField
noncomputable section
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.
In particular this includes adjustments for the Lean PRs
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).
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})
.
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:
(config := { unfoldPartialApp := true })
in some places, to recover the old behaviour@[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>
@@ -88,10 +88,10 @@ variable {K}
theorem coe_mul (x y : (𝓞 K)ˣ) : ((x * y : (𝓞 K)ˣ) : K) = (x : K) * (y : K) := rfl
-theorem coe_pow (x : (𝓞 K)ˣ) (n : ℕ) : (x ^ n : K) = (x : K) ^ n := by
+theorem coe_pow (x : (𝓞 K)ˣ) (n : ℕ) : (↑(x ^ n) : K) = (x : K) ^ n := by
rw [← SubmonoidClass.coe_pow, ← val_pow_eq_pow_val]
-theorem coe_zpow (x : (𝓞 K)ˣ) (n : ℤ) : (x ^ n : K) = (x : K) ^ n := by
+theorem coe_zpow (x : (𝓞 K)ˣ) (n : ℤ) : (↑(x ^ n) : K) = (x : K) ^ n := by
change ((Units.coeHom K).comp (map (algebraMap (𝓞 K) K))) (x ^ n) = _
exact map_zpow _ x n
@@ -227,7 +227,7 @@ theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
mult w * Real.log (w x) = 0 ↔ w x = 1 := by
rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
· linarith [(map_nonneg _ _ : 0 ≤ w x)]
- · simp only [ne_eq, map_eq_zero, coe_ne_zero x]
+ · simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
· refine (ne_of_gt ?_)
rw [mult]; split_ifs <;> norm_num
@@ -345,7 +345,7 @@ theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
simp_rw [← NNReal.coe_pow, ← NNReal.coe_prod]
exact le_of_eq (congr_arg toReal h_gprod)
· refine div_lt_self ?_ (by norm_num)
- simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, hx]
+ simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, hx, not_false_eq_true]
intro _ _
rw [ne_eq, Nonneg.mk_eq_zero, div_eq_zero_iff, map_eq_zero, not_or, ZeroMemClass.coe_eq_zero]
exact ⟨hx, by norm_num⟩
@@ -410,7 +410,7 @@ theorem exists_unit (w₁ : InfinitePlace K) :
(Ideal.span ({ (seq K w₁ hB n : 𝓞 K) }) = Ideal.span ({ (seq K w₁ hB m : 𝓞 K) }))
· have hu := Ideal.span_singleton_eq_span_singleton.mp h
refine ⟨hu.choose, fun w hw => Real.log_neg ?_ ?_⟩
- · simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, ne_zero]
+ · simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, ne_zero, not_false_eq_true]
· calc
_ = w ((seq K w₁ hB m : K) * (seq K w₁ hB n : K)⁻¹) := by
rw [← congr_arg ((↑) : (𝓞 K) → K) hu.choose_spec, mul_comm, Submonoid.coe_mul,
@@ -199,7 +199,7 @@ variable (K)
/-- The logarithmic embedding of the units (seen as an `Additive` group). -/
def logEmbedding : Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
-{ toFun := fun x w => mult w.val * Real.log (w.val (Additive.toMul x))
+{ toFun := fun x w => mult w.val * Real.log (w.val ↑(Additive.toMul x))
map_zero' := by simp; rfl
map_add' := fun _ _ => by simp [Real.log_mul, mul_add]; rfl }
@@ -555,7 +555,8 @@ def basisModTorsion : Basis (Fin (rank K)) ℤ (Additive ((𝓞 K)ˣ ⧸ (torsio
/-- A fundamental system of units of `K`. The units of `fundSystem` are arbitrary lifts of the
units in `basisModTorsion`. -/
def fundSystem : Fin (rank K) → (𝓞 K)ˣ :=
- fun i => Quotient.out' (Additive.toMul (basisModTorsion K i))
+ -- `:)` prevents the `⧸` decaying to a quotient by `leftRel` when we unfold this later
+ fun i => Quotient.out' (Additive.toMul (basisModTorsion K i) :)
/-- The exponents that appear in the unique decomposition of a unit as the product of
a root of unity and powers of the units of the fundamental system `fundSystem` (see
@@ -580,7 +581,7 @@ theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K) (e : F
have h_tors : ζ ∈ torsion K := by
rw [← QuotientGroup.eq_one_iff, QuotientGroup.mk_mul, QuotientGroup.mk_inv, ← ofMul_eq_zero,
ofMul_mul, ofMul_inv, QuotientGroup.mk_prod, ofMul_prod]
- simp_rw [QuotientGroup.mk_zpow, ofMul_zpow, fundSystem, QuotientGroup.out_eq', ofMul_toMul]
+ simp_rw [QuotientGroup.mk_zpow, ofMul_zpow, fundSystem, QuotientGroup.out_eq']
rw [add_eq_zero_iff_eq_neg, neg_neg]
exact ((basisModTorsion K).sum_repr (Additive.ofMul ↑x)).symm
refine ⟨⟨ζ, h_tors⟩, ?_, ?_⟩
The cardinality of a subgroup is greater than the order of any of its elements.
Rename
order_eq_card_zpowers
→ Fintype.card_zpowers
order_eq_card_zpowers'
→ Nat.card_zpowers
(and turn it around to match Nat.card_subgroupPowers
)Submonoid.powers_subset
→ Submonoid.powers_le
orderOf_dvd_card_univ
→ orderOf_dvd_card
orderOf_subgroup
→ Subgroup.orderOf
Subgroup.nonempty
→ Subgroup.coe_nonempty
@@ -155,7 +155,7 @@ theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (tors
rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
exact ⟨k, k.prop, h⟩
rw [orderOf_submonoid (⟨ζ, hζ⟩ : torsion K)]
- exact orderOf_dvd_card_univ
+ exact orderOf_dvd_card
/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
Many lemmas in GroupTheory.OrderOfElement
were stated for elements of finite groups even though they work more generally for torsion elements of possibly infinite groups. This PR generalises those lemmas (and leaves convenience lemmas stated for finite groups), and fixes a bunch of names to use dot notation.
Function.eq_of_lt_minimalPeriod_of_iterate_eq
→ Function.iterate_injOn_Iio_minimalPeriod
Function.eq_iff_lt_minimalPeriod_of_iterate_eq
→ Function.iterate_eq_iterate_iff_of_lt_minimalPeriod
isOfFinOrder_iff_coe
→ Submonoid.isOfFinOrder_coe
orderOf_pos'
→ IsOfFinOrder.orderOf_pos
pow_eq_mod_orderOf
→ pow_mod_orderOf
(and turned around)pow_injective_of_lt_orderOf
→ pow_injOn_Iio_orderOf
mem_powers_iff_mem_range_order_of'
→ IsOfFinOrder.mem_powers_iff_mem_range_orderOf
orderOf_pow''
→ IsOfFinOrder.orderOf_pow
orderOf_pow_coprime
→ Nat.Coprime.orderOf_pow
zpow_eq_mod_orderOf
→ zpow_mod_orderOf
(and turned around)exists_pow_eq_one
→ isOfFinOrder_of_finite
pow_apply_eq_pow_mod_orderOf_cycleOf_apply
→ pow_mod_orderOf_cycleOf_apply
IsOfFinOrder.powers_eq_image_range_orderOf
IsOfFinOrder.natCard_powers_le_orderOf
IsOfFinOrder.finite_powers
finite_powers
infinite_powers
Nat.card_submonoidPowers
IsOfFinOrder.mem_powers_iff_mem_zpowers
IsOfFinOrder.powers_eq_zpowers
IsOfFinOrder.mem_zpowers_iff_mem_range_orderOf
IsOfFinOrder.exists_pow_eq_one
decidableMemPowers
/fintypePowers
to GroupTheory.Submonoid.Membership
and decidableMemZpowers
/fintypeZpowers
to GroupTheory.Subgroup.ZPowers
.finEquivPowers
, finEquivZpowers
, powersEquivPowers
and zpowersEquivZpowers
now assume IsOfFinTorsion x
instead of Finite G
.isOfFinOrder_iff_pow_eq_one
now takes one less explicit argument.Equiv.Perm.IsCycle.exists_pow_eq_one
since it was saying that a permutation over a finite type is torsion, but this is trivial since the group of permutation is itself finite, so we can use isOfFinOrder_of_finite
instead.@@ -166,7 +166,7 @@ theorem rootsOfUnity_eq_torsion [NumberField K] :
refine ⟨fun h => ?_, fun h => ?_⟩
· rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
exact ⟨↑(torsionOrder K), (torsionOrder K).prop, h⟩
- · exact Subtype.ext_iff.mp (@pow_card_eq_one (torsion K) _ ⟨ζ, h⟩ _)
+ · exact Subtype.ext_iff.mp (@pow_card_eq_one (torsion K) _ _ ⟨ζ, h⟩)
end torsion
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.
@@ -41,6 +41,7 @@ fundamental system `fundSystem`.
number field, units
-/
+local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue lean4#2220
open scoped NumberField
@@ -321,9 +322,6 @@ sequence defining the same ideal and their quotient is the desired unit `u_w₁`
open NumberField.mixedEmbedding NNReal
--- See: https://github.com/leanprover/lean4/issues/2220
-local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y)
-
variable (w₁ : InfinitePlace K) {B : ℕ} (hB : minkowskiBound K < (convexBodyLtFactor K) * B)
/-- This result shows that there always exists a next term in the sequence. -/
@@ -405,10 +403,9 @@ image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
theorem exists_unit (w₁ : InfinitePlace K) :
∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLtFactor K) * B := by
- simp_rw [mul_comm]
- refine ENNReal.exists_nat_mul_gt ?_ ?_
- exact ne_of_gt (convexBodyLtFactor_pos K)
- exact ne_of_lt (minkowskiBound_lt_top K)
+ conv => congr; ext; rw [mul_comm]
+ exact ENNReal.exists_nat_mul_gt (ne_of_gt (convexBodyLtFactor_pos K))
+ (ne_of_lt (minkowskiBound_lt_top K))
rsuffices ⟨n, m, hnm, h⟩ : ∃ n m, n < m ∧
(Ideal.span ({ (seq K w₁ hB n : 𝓞 K) }) = Ideal.span ({ (seq K w₁ hB m : 𝓞 K) }))
· have hu := Ideal.span_singleton_eq_span_singleton.mp h
@@ -263,7 +263,7 @@ theorem log_le_of_logEmbedding_le {r : ℝ} {x : (𝓞 K)ˣ} (hr : 0 ≤ r) (h :
refine (le_trans ?_ hyp).trans ?_
· rw [← hw]
exact tool _ (abs_nonneg _)
- · refine (sum_le_card_nsmul univ _ _
+ · refine (sum_le_card_nsmul univ _ _
(fun w _ => logEmbedding_component_le hr h w)).trans ?_
rw [nsmul_eq_mul]
refine mul_le_mul ?_ le_rfl hr (Fintype.card (InfinitePlace K)).cast_nonneg
@@ -400,9 +400,9 @@ theorem seq_norm_le (n : ℕ) :
exact (seq_next K w₁ hB (seq K w₁ hB n).prop).choose_spec.2.2
/-- Construct a unit associated to the place `w₁`. The family, for `w₁ ≠ w₀`, formed by the
-image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
+image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
`unitLattice_span_eq_top`. -/
-theorem exists_unit (w₁ : InfinitePlace K ) :
+theorem exists_unit (w₁ : InfinitePlace K) :
∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLtFactor K) * B := by
simp_rw [mul_comm]
@@ -427,7 +427,7 @@ theorem exists_unit (w₁ : InfinitePlace K ) :
(fun n => ?_) ?_
· rw [Set.mem_setOf_eq, Ideal.absNorm_span_singleton]
refine ⟨?_, seq_norm_le K w₁ hB n⟩
- exact Nat.one_le_iff_ne_zero.mpr (Int.natAbs_ne_zero.mpr (seq_norm_ne_zero K w₁ hB n))
+ exact Nat.one_le_iff_ne_zero.mpr (Int.natAbs_ne_zero.mpr (seq_norm_ne_zero K w₁ hB n))
· rw [show { I : Ideal (𝓞 K) | 1 ≤ Ideal.absNorm I ∧ Ideal.absNorm I ≤ B } =
(⋃ n ∈ Set.Icc 1 B, { I : Ideal (𝓞 K) | Ideal.absNorm I = n }) by ext; simp]
exact Set.Finite.biUnion (Set.finite_Icc _ _) (fun n hn => Ideal.finite_setOf_absNorm_eq hn.1)
Add the following instance
instance : Module.Finite ℤ (Additive (𝓞 K)ˣ)
To prove this instance, it is helpful to add some rfl
lemmas about Additive
and AddMonoidHom.toIntLinearMap
This PR also fixes a couple of typo in the docstring
@@ -139,7 +139,7 @@ instance [NumberField K] : Finite (torsion K) := inferInstance
/-- The torsion subgroup is cylic. -/
instance [NumberField K] : IsCyclic (torsion K) := subgroup_units_cyclic _
-/-- The order of the torsion subgroup as positive integer. -/
+/-- The order of the torsion subgroup as a positive integer. -/
def torsionOrder [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.card_pos⟩
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
@@ -178,7 +178,7 @@ This section is devoted to the proof of Dirichlet's unit theorem.
We define a group morphism from `(𝓞 K)ˣ` to `{w : InfinitePlace K // w ≠ w₀} → ℝ` where `w₀` is a
distinguished (arbitrary) infinite place, prove that its kernel is the torsion subgroup (see
`logEmbedding_eq_zero_iff`) and that its image, called `unitLattice`, is a full `ℤ`-lattice. It
-follows that `unitLattice` is a free `ℤ`-module (see `unitLattice_moduleFree `) of rank
+follows that `unitLattice` is a free `ℤ`-module (see `instModuleFree_unitLattice`) of rank
`card (InfinitePlaces K) - 1` (see `unitLattice_rank`). To prove that the `unitLattice` is a full
`ℤ`-lattice, we need to prove that it is discrete (see `unitLattice_inter_ball_finite`) and that it
spans the full space over `ℝ` (see `unitLattice_span_eq_top`); this is the main part of the proof,
@@ -401,8 +401,8 @@ theorem seq_norm_le (n : ℕ) :
/-- Construct a unit associated to the place `w₁`. The family, for `w₁ ≠ w₀`, formed by the
image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
-`unit_lattice_span_eq_top`. -/
-theorem exists_unit (w₁ : InfinitePlace K) :
+`unitLattice_span_eq_top`. -/
+theorem exists_unit (w₁ : InfinitePlace K ) :
∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLtFactor K) * B := by
simp_rw [mul_comm]
@@ -512,9 +512,8 @@ def unitLatticeEquiv : (unitLattice K) ≃ₗ[ℤ] Additive ((𝓞 K)ˣ ⧸ (tor
(QuotientAddGroup.quotientKerEquivOfSurjective
(MonoidHom.toAdditive (QuotientGroup.mk' (torsion K))) (fun x => ?_))
· ext
- rw [AddMonoidHom.mem_ker, AddMonoidHom.mem_ker, logEmbedding_eq_zero_iff,
- MonoidHom.toAdditive_apply_apply, ofMul_eq_zero, QuotientGroup.mk'_apply,
- QuotientGroup.eq_one_iff]
+ rw [MonoidHom.coe_toAdditive_ker, QuotientGroup.ker_mk', AddMonoidHom.mem_ker,
+ logEmbedding_eq_zero_iff]
rfl
· refine ⟨Additive.ofMul x.out', ?_⟩
simp only [MonoidHom.toAdditive_apply_apply, toMul_ofMul, QuotientGroup.mk'_apply,
@@ -527,6 +526,26 @@ instance : Module.Free ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
instance : Module.Finite ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
Module.Finite.equiv (unitLatticeEquiv K)
+-- Note that we prove this instance first and then deduce from it the instance
+-- `Monoid.FG (𝓞 K)ˣ`, and not the other way around, due to no `Subgroup` version
+-- of `Submodule.fg_of_fg_map_of_fg_inf_ker` existing.
+instance : Module.Finite ℤ (Additive (𝓞 K)ˣ) := by
+ rw [Module.finite_def]
+ refine Submodule.fg_of_fg_map_of_fg_inf_ker
+ (MonoidHom.toAdditive (QuotientGroup.mk' (torsion K))).toIntLinearMap ?_ ?_
+ · rw [Submodule.map_top, LinearMap.range_eq_top.mpr
+ (by exact QuotientGroup.mk'_surjective (torsion K)), ← Module.finite_def]
+ infer_instance
+ · rw [inf_of_le_right le_top, AddMonoidHom.coe_toIntLinearMap_ker, MonoidHom.coe_toAdditive_ker,
+ QuotientGroup.ker_mk', Submodule.fg_iff_add_subgroup_fg,
+ AddSubgroup.toIntSubmodule_toAddSubgroup, ← AddGroup.fg_iff_addSubgroup_fg]
+ have : Finite (Subgroup.toAddSubgroup (torsion K)) := (inferInstance : Finite (torsion K))
+ exact AddGroup.fg_of_finite
+
+instance : Monoid.FG (𝓞 K)ˣ := by
+ rw [Monoid.fg_iff_add_fg, ← AddGroup.fg_iff_addMonoid_fg, ← Module.Finite.iff_addGroup_fg]
+ infer_instance
+
theorem rank_modTorsion :
FiniteDimensional.finrank ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) = rank K := by
rw [← LinearEquiv.finrank_eq (unitLatticeEquiv K), unitLattice_rank]
@@ -543,7 +562,7 @@ def fundSystem : Fin (rank K) → (𝓞 K)ˣ :=
/-- The exponents that appear in the unique decomposition of a unit as the product of
a root of unity and powers of the units of the fundamental system `fundSystem` (see
-`exist_unique_eq_mul_prod`) are given by the representation of the unit of `basisModTorsion`. -/
+`exist_unique_eq_mul_prod`) are given by the representation of the unit on `basisModTorsion`. -/
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) := by
This will improve spaces in the mathlib4 docs.
@@ -181,7 +181,7 @@ distinguished (arbitrary) infinite place, prove that its kernel is the torsion s
follows that `unitLattice` is a free `ℤ`-module (see `unitLattice_moduleFree `) of rank
`card (InfinitePlaces K) - 1` (see `unitLattice_rank`). To prove that the `unitLattice` is a full
`ℤ`-lattice, we need to prove that it is discrete (see `unitLattice_inter_ball_finite`) and that it
-spans the full space over `ℝ` (see ` unitLattice_span_eq_top`); this is the main part of the proof,
+spans the full space over `ℝ` (see `unitLattice_span_eq_top`); this is the main part of the proof,
see the section `span_top` below for more details.
-/
@@ -402,7 +402,7 @@ theorem seq_norm_le (n : ℕ) :
/-- Construct a unit associated to the place `w₁`. The family, for `w₁ ≠ w₀`, formed by the
image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
`unit_lattice_span_eq_top`. -/
-theorem exists_unit (w₁ : InfinitePlace K ) :
+theorem exists_unit (w₁ : InfinitePlace K) :
∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLtFactor K) * B := by
simp_rw [mul_comm]
@@ -56,6 +56,10 @@ theorem Rat.RingOfIntegers.isUnit_iff {x : 𝓞 ℚ} : IsUnit x ↔ (x : ℚ) =
Subtype.coe_injective.eq_iff]; rfl
#align rat.ring_of_integers.is_unit_iff Rat.RingOfIntegers.isUnit_iff
+theorem Algebra.coe_norm_int {K : Type*} [Field K] [NumberField K] (x : 𝓞 K) :
+ Algebra.norm ℤ x = Algebra.norm ℚ (x : K) :=
+ (Algebra.norm_localization (R := ℤ) (Rₘ := ℚ) (S := 𝓞 K) (Sₘ := K) (nonZeroDivisors ℤ) x).symm
+
end Rat
variable (K : Type*) [Field K]
@@ -392,9 +396,7 @@ theorem seq_norm_le (n : ℕ) :
simp only [Nat.lt_one_iff.mp hB, CharP.cast_eq_zero, mul_zero, zero_le]
simp only [ne_eq, seq, map_one, Int.natAbs_one, this]
| succ n =>
- rw [← Nat.cast_le (α := ℚ), Int.cast_natAbs, Int.cast_abs]
- change |algebraMap ℤ ℚ _| ≤ _
- rw [← Algebra.norm_localization ℤ (Sₘ := K) (nonZeroDivisors ℤ)]
+ rw [← Nat.cast_le (α := ℚ), Int.cast_natAbs, Int.cast_abs, Algebra.coe_norm_int]
exact (seq_next K w₁ hB (seq K w₁ hB n).prop).choose_spec.2.2
/-- Construct a unit associated to the place `w₁`. The family, for `w₁ ≠ w₀`, formed by the
@@ -368,7 +368,7 @@ theorem seq_norm_ne_zero (n : ℕ) : Algebra.norm ℤ (seq K w₁ hB n : 𝓞 K)
/-- The sequence is strictly decreasing at infinite places distinct from `w₁`. -/
theorem seq_decreasing {n m : ℕ} (h : n < m) (w : InfinitePlace K) (hw : w ≠ w₁) :
- w (seq K w₁ hB m) < w (seq K w₁ hB n) := by
+ w (seq K w₁ hB m) < w (seq K w₁ hB n) := by
induction m with
| zero =>
exfalso
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)
@@ -3,9 +3,10 @@ Copyright (c) 2023 Xavier Roblot. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Xavier Roblot
-/
-import Mathlib.GroupTheory.Torsion
-import Mathlib.NumberTheory.NumberField.Embeddings
+import Mathlib.LinearAlgebra.Matrix.Gershgorin
+import Mathlib.NumberTheory.NumberField.CanonicalEmbedding
import Mathlib.NumberTheory.NumberField.Norm
+import Mathlib.RingTheory.Ideal.Norm
import Mathlib.RingTheory.RootsOfUnity.Basic
#align_import number_theory.number_field.units from "leanprover-community/mathlib"@"00f91228655eecdcd3ac97a7fd8dbcb139fe990a"
@@ -15,22 +16,37 @@ import Mathlib.RingTheory.RootsOfUnity.Basic
We prove results about the group `(𝓞 K)ˣ` of units of the ring of integers `𝓞 K` of a number
field `K`.
+## Main definitions
+
+* `NumberField.Units.rank`: the unit rank of the number field `K`.
+
+* `NumberField.Units.fundSystem`: a fundamental system of units of `K`.
+
+* `NumberField.Units.basisModTorsion`: a `ℤ`-basis of `(𝓞 K)ˣ ⧸ (torsion K)`
+as an additive `ℤ`-module.
+
## Main results
-* `isUnit_iff_norm`: an algebraic integer `x : 𝓞 K` is a unit if and only if `|norm ℚ x| = 1`.
-* `mem_torsion`: a unit `x : (𝓞 K)ˣ` is torsion iff `w x = 1` for all infinite places of `K`.
+
+* `NumberField.isUnit_iff_norm`: an algebraic integer `x : 𝓞 K` is a unit if and only if
+`|norm ℚ x| = 1`.
+
+* `NumberField.Units.mem_torsion`: a unit `x : (𝓞 K)ˣ` is torsion iff `w x = 1` for all infinite
+places `w` of `K`.
+
+* `NumberField.Units.exist_unique_eq_mul_prod`: **Dirichlet Unit Theorem**. Any unit `x` of `𝓞 K`
+can be written uniquely as the product of a root of unity and powers of the units of of the
+fundamental system `fundSystem`.
## Tags
number field, units
-/
-set_option autoImplicit true
-
open scoped NumberField
noncomputable section
-open NumberField Units
+open NumberField Units BigOperators
section Rat
@@ -48,11 +64,11 @@ section IsUnit
variable {K}
-theorem isUnit_iff_norm [NumberField K] {x : 𝓞 K} :
+theorem NumberField.isUnit_iff_norm [NumberField K] {x : 𝓞 K} :
IsUnit x ↔ |(RingOfIntegers.norm ℚ x : ℚ)| = 1 := by
convert (RingOfIntegers.isUnit_norm ℚ (F := K)).symm
rw [← abs_one, abs_eq_abs, ← Rat.RingOfIntegers.isUnit_iff]
-#align is_unit_iff_norm isUnit_iff_norm
+#align is_unit_iff_norm NumberField.isUnit_iff_norm
end IsUnit
@@ -124,8 +140,8 @@ def torsionOrder [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
order dividing `k`. -/
-theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K)) :
- ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
+theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
+ {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
rw [mem_rootsOfUnity]
refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
@@ -149,4 +165,416 @@ theorem rootsOfUnity_eq_torsion [NumberField K] :
end torsion
+namespace dirichletUnitTheorem
+
+/-!
+### Dirichlet Unit Theorem
+This section is devoted to the proof of Dirichlet's unit theorem.
+
+We define a group morphism from `(𝓞 K)ˣ` to `{w : InfinitePlace K // w ≠ w₀} → ℝ` where `w₀` is a
+distinguished (arbitrary) infinite place, prove that its kernel is the torsion subgroup (see
+`logEmbedding_eq_zero_iff`) and that its image, called `unitLattice`, is a full `ℤ`-lattice. It
+follows that `unitLattice` is a free `ℤ`-module (see `unitLattice_moduleFree `) of rank
+`card (InfinitePlaces K) - 1` (see `unitLattice_rank`). To prove that the `unitLattice` is a full
+`ℤ`-lattice, we need to prove that it is discrete (see `unitLattice_inter_ball_finite`) and that it
+spans the full space over `ℝ` (see ` unitLattice_span_eq_top`); this is the main part of the proof,
+see the section `span_top` below for more details.
+-/
+
+open Classical Finset
+
+variable [NumberField K]
+
+variable {K}
+
+/-- The distinguished infinite place. -/
+def w₀ : InfinitePlace K := (inferInstance : Nonempty (InfinitePlace K)).some
+
+variable (K)
+
+/-- The logarithmic embedding of the units (seen as an `Additive` group). -/
+def logEmbedding : Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
+{ toFun := fun x w => mult w.val * Real.log (w.val (Additive.toMul x))
+ map_zero' := by simp; rfl
+ map_add' := fun _ _ => by simp [Real.log_mul, mul_add]; rfl }
+
+variable {K}
+
+@[simp]
+theorem logEmbedding_component (x : (𝓞 K)ˣ) (w : {w : InfinitePlace K // w ≠ w₀}) :
+ (logEmbedding K x) w = mult w.val * Real.log (w.val x) := rfl
+
+theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
+ ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
+ have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
+ rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
+ Real.log_one, Real.log_prod] at h
+ · simp_rw [Real.log_pow] at h
+ rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
+ add_eq_zero_iff_eq_neg] at h
+ convert h using 1
+ · refine (sum_subtype _ (fun w => ?_) (fun w => (mult w) * (Real.log (w (x : K))))).symm
+ exact ⟨ne_of_mem_erase, fun h => mem_erase_of_ne_of_mem h (mem_univ w)⟩
+ · norm_num
+ · exact fun w _ => pow_ne_zero _ (AbsoluteValue.ne_zero _ (coe_ne_zero x))
+
+theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
+ mult w * Real.log (w x) = 0 ↔ w x = 1 := by
+ rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
+ · linarith [(map_nonneg _ _ : 0 ≤ w x)]
+ · simp only [ne_eq, map_eq_zero, coe_ne_zero x]
+ · refine (ne_of_gt ?_)
+ rw [mult]; split_ifs <;> norm_num
+
+theorem logEmbedding_eq_zero_iff {x : (𝓞 K)ˣ} :
+ logEmbedding K x = 0 ↔ x ∈ torsion K := by
+ rw [mem_torsion]
+ refine ⟨fun h w => ?_, fun h => ?_⟩
+ · by_cases hw : w = w₀
+ · suffices -mult w₀ * Real.log (w₀ (x : K)) = 0 by
+ rw [neg_mul, neg_eq_zero, ← hw] at this
+ exact mult_log_place_eq_zero.mp this
+ rw [← sum_logEmbedding_component, sum_eq_zero]
+ exact fun w _ => congrFun h w
+ · exact mult_log_place_eq_zero.mp (congrFun h ⟨w, hw⟩)
+ · ext w
+ rw [logEmbedding_component, h w.val, Real.log_one, mul_zero, Pi.zero_apply]
+
+theorem logEmbedding_component_le {r : ℝ} {x : (𝓞 K)ˣ} (hr : 0 ≤ r) (h : ‖logEmbedding K x‖ ≤ r)
+ (w : {w : InfinitePlace K // w ≠ w₀}) : |logEmbedding K x w| ≤ r := by
+ lift r to NNReal using hr
+ simp_rw [Pi.norm_def, NNReal.coe_le_coe, Finset.sup_le_iff, ← NNReal.coe_le_coe] at h
+ exact h w (mem_univ _)
+
+theorem log_le_of_logEmbedding_le {r : ℝ} {x : (𝓞 K)ˣ} (hr : 0 ≤ r) (h : ‖logEmbedding K x‖ ≤ r)
+ (w : InfinitePlace K) : |Real.log (w x)| ≤ (Fintype.card (InfinitePlace K)) * r := by
+ have tool : ∀ x : ℝ, 0 ≤ x → x ≤ mult w * x := fun x hx => by
+ nth_rw 1 [← one_mul x]
+ refine mul_le_mul ?_ le_rfl hx ?_
+ all_goals { rw [mult]; split_ifs <;> norm_num }
+ by_cases hw : w = w₀
+ · have hyp := congr_arg (‖·‖) (sum_logEmbedding_component x).symm
+ replace hyp := (le_of_eq hyp).trans (norm_sum_le _ _)
+ simp_rw [norm_mul, norm_neg, Real.norm_eq_abs, Nat.abs_cast] at hyp
+ refine (le_trans ?_ hyp).trans ?_
+ · rw [← hw]
+ exact tool _ (abs_nonneg _)
+ · refine (sum_le_card_nsmul univ _ _
+ (fun w _ => logEmbedding_component_le hr h w)).trans ?_
+ rw [nsmul_eq_mul]
+ refine mul_le_mul ?_ le_rfl hr (Fintype.card (InfinitePlace K)).cast_nonneg
+ simp [card_univ]
+ · have hyp := logEmbedding_component_le hr h ⟨w, hw⟩
+ rw [logEmbedding_component, abs_mul, Nat.abs_cast] at hyp
+ refine (le_trans ?_ hyp).trans ?_
+ · exact tool _ (abs_nonneg _)
+ · nth_rw 1 [← one_mul r]
+ exact mul_le_mul (Nat.one_le_cast.mpr Fintype.card_pos) (le_of_eq rfl) hr (Nat.cast_nonneg _)
+
+variable (K)
+
+/-- The lattice formed by the image of the logarithmic embedding. -/
+noncomputable def _root_.NumberField.Units.unitLattice :
+ AddSubgroup ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
+ AddSubgroup.map (logEmbedding K) ⊤
+
+theorem unitLattice_inter_ball_finite (r : ℝ) :
+ ((unitLattice K : Set ({ w : InfinitePlace K // w ≠ w₀} → ℝ)) ∩
+ Metric.closedBall 0 r).Finite := by
+ obtain hr | hr := lt_or_le r 0
+ · convert Set.finite_empty
+ rw [Metric.closedBall_eq_empty.mpr hr]
+ exact Set.inter_empty _
+ · suffices {x : (𝓞 K)ˣ | IsIntegral ℤ (x : K) ∧
+ ∀ (φ : K →+* ℂ), ‖φ x‖ ≤ Real.exp ((Fintype.card (InfinitePlace K)) * r)}.Finite by
+ refine (Set.Finite.image (logEmbedding K) this).subset ?_
+ rintro _ ⟨⟨x, ⟨_, rfl⟩⟩, hx⟩
+ refine ⟨x, ⟨x.val.prop, (le_iff_le _ _).mp (fun w => (Real.log_le_iff_le_exp ?_).mp ?_)⟩, rfl⟩
+ · exact pos_iff.mpr (coe_ne_zero x)
+ · rw [mem_closedBall_zero_iff] at hx
+ exact (le_abs_self _).trans (log_le_of_logEmbedding_le hr hx w)
+ refine Set.Finite.of_finite_image ?_ ((coe_injective K).injOn _)
+ refine (Embeddings.finite_of_norm_le K ℂ
+ (Real.exp ((Fintype.card (InfinitePlace K)) * r))).subset ?_
+ rintro _ ⟨x, ⟨⟨h_int, h_le⟩, rfl⟩⟩
+ exact ⟨h_int, h_le⟩
+
+section span_top
+
+/-!
+#### Section `span_top`
+
+In this section, we prove that the span over `ℝ` of the `unitLattice` is equal to the full space.
+For this, we construct for each infinite place `w₁ ≠ w₀` a unit `u_w₁` of `K` such that, for all
+infinite places `w` such that `w ≠ w₁`, we have `Real.log w (u_w₁) < 0`
+(and thus `Real.log w₁ (u_w₁) > 0`). It follows then from a determinant computation
+(using `Matrix.det_ne_zero_of_sum_col_lt_diag`) that the image by `logEmbedding` of these units is
+a `ℝ`-linearly independent family. The unit `u_w₁` is obtained by constructing a sequence `seq n`
+of nonzero algebraic integers that is strictly decreasing at infinite places distinct from `w₁` and
+of norm `≤ B`. Since there are finitely many ideals of norm `≤ B`, there exists two term in the
+sequence defining the same ideal and their quotient is the desired unit `u_w₁` (see `exists_unit`).
+-/
+
+open NumberField.mixedEmbedding NNReal
+
+-- See: https://github.com/leanprover/lean4/issues/2220
+local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y)
+
+variable (w₁ : InfinitePlace K) {B : ℕ} (hB : minkowskiBound K < (convexBodyLtFactor K) * B)
+
+/-- This result shows that there always exists a next term in the sequence. -/
+theorem seq_next {x : 𝓞 K} (hx : x ≠ 0) :
+ ∃ y : 𝓞 K, y ≠ 0 ∧ (∀ w, w ≠ w₁ → w y < w x) ∧ |Algebra.norm ℚ (y : K)| ≤ B := by
+ let f : InfinitePlace K → ℝ≥0 :=
+ fun w => ⟨(w x) / 2, div_nonneg (AbsoluteValue.nonneg _ _) (by norm_num)⟩
+ suffices ∀ w, w ≠ w₁ → f w ≠ 0 by
+ obtain ⟨g, h_geqf, h_gprod⟩ := adjust_f K B this
+ obtain ⟨y, h_ynz, h_yle⟩ := exists_ne_zero_mem_ringOfIntegers_lt (f := g)
+ (by rw [convexBodyLt_volume]; convert hB; exact congr_arg ((↑): NNReal → ENNReal) h_gprod)
+ refine ⟨y, h_ynz, fun w hw => (h_geqf w hw ▸ h_yle w).trans ?_, ?_⟩
+ · rw [← Rat.cast_le (K := ℝ), Rat.cast_coe_nat]
+ calc
+ _ = ∏ w : InfinitePlace K, w y ^ mult w := (prod_eq_abs_norm (y : K)).symm
+ _ ≤ ∏ w : InfinitePlace K, (g w : ℝ) ^ mult w := by
+ refine prod_le_prod ?_ ?_
+ · exact fun _ _ => pow_nonneg (by positivity) _
+ · exact fun w _ => pow_le_pow_of_le_left (by positivity) (le_of_lt (h_yle w)) (mult w)
+ _ ≤ (B : ℝ) := by
+ simp_rw [← NNReal.coe_pow, ← NNReal.coe_prod]
+ exact le_of_eq (congr_arg toReal h_gprod)
+ · refine div_lt_self ?_ (by norm_num)
+ simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, hx]
+ intro _ _
+ rw [ne_eq, Nonneg.mk_eq_zero, div_eq_zero_iff, map_eq_zero, not_or, ZeroMemClass.coe_eq_zero]
+ exact ⟨hx, by norm_num⟩
+
+/-- An infinite sequence of nonzero algebraic integers of `K` satisfying the following properties:
+• `seq n` is nonzero;
+• for `w : InfinitePlace K`, `w ≠ w₁ → w (seq n+1) < w (seq n)`;
+• `∣norm (seq n)∣ ≤ B`. -/
+def seq : ℕ → { x : 𝓞 K // x ≠ 0 }
+ | 0 => ⟨1, by norm_num⟩
+ | n + 1 =>
+ ⟨(seq_next K w₁ hB (seq n).prop).choose, (seq_next K w₁ hB (seq n).prop).choose_spec.1⟩
+
+/-- The terms of the sequence are nonzero. -/
+theorem seq_ne_zero (n : ℕ) : (seq K w₁ hB n : K) ≠ 0 := by
+ refine (map_ne_zero_iff (algebraMap (𝓞 K) K) ?_).mpr (seq K w₁ hB n).prop
+ exact IsFractionRing.injective { x // x ∈ 𝓞 K } K
+
+/-- The terms of the sequence have nonzero norm. -/
+theorem seq_norm_ne_zero (n : ℕ) : Algebra.norm ℤ (seq K w₁ hB n : 𝓞 K) ≠ 0 :=
+ Algebra.norm_ne_zero_iff.mpr (Subtype.ne_of_val_ne (seq_ne_zero K w₁ hB n))
+
+/-- The sequence is strictly decreasing at infinite places distinct from `w₁`. -/
+theorem seq_decreasing {n m : ℕ} (h : n < m) (w : InfinitePlace K) (hw : w ≠ w₁) :
+ w (seq K w₁ hB m) < w (seq K w₁ hB n) := by
+ induction m with
+ | zero =>
+ exfalso
+ exact Nat.not_succ_le_zero n h
+ | succ m m_ih =>
+ cases eq_or_lt_of_le (Nat.le_of_lt_succ h) with
+ | inl hr =>
+ rw [hr]
+ exact (seq_next K w₁ hB (seq K w₁ hB m).prop).choose_spec.2.1 w hw
+ | inr hr =>
+ refine lt_trans ?_ (m_ih hr)
+ exact (seq_next K w₁ hB (seq K w₁ hB m).prop).choose_spec.2.1 w hw
+
+/-- The terms of the sequence have norm bounded by `B`. -/
+theorem seq_norm_le (n : ℕ) :
+ Int.natAbs (Algebra.norm ℤ (seq K w₁ hB n : 𝓞 K)) ≤ B := by
+ cases n with
+ | zero =>
+ have : 1 ≤ B := by
+ contrapose! hB
+ simp only [Nat.lt_one_iff.mp hB, CharP.cast_eq_zero, mul_zero, zero_le]
+ simp only [ne_eq, seq, map_one, Int.natAbs_one, this]
+ | succ n =>
+ rw [← Nat.cast_le (α := ℚ), Int.cast_natAbs, Int.cast_abs]
+ change |algebraMap ℤ ℚ _| ≤ _
+ rw [← Algebra.norm_localization ℤ (Sₘ := K) (nonZeroDivisors ℤ)]
+ exact (seq_next K w₁ hB (seq K w₁ hB n).prop).choose_spec.2.2
+
+/-- Construct a unit associated to the place `w₁`. The family, for `w₁ ≠ w₀`, formed by the
+image by the `logEmbedding` of these units is `ℝ`-linearly independent, see
+`unit_lattice_span_eq_top`. -/
+theorem exists_unit (w₁ : InfinitePlace K ) :
+ ∃ u : (𝓞 K)ˣ, ∀ w : InfinitePlace K, w ≠ w₁ → Real.log (w u) < 0 := by
+ obtain ⟨B, hB⟩ : ∃ B : ℕ, minkowskiBound K < (convexBodyLtFactor K) * B := by
+ simp_rw [mul_comm]
+ refine ENNReal.exists_nat_mul_gt ?_ ?_
+ exact ne_of_gt (convexBodyLtFactor_pos K)
+ exact ne_of_lt (minkowskiBound_lt_top K)
+ rsuffices ⟨n, m, hnm, h⟩ : ∃ n m, n < m ∧
+ (Ideal.span ({ (seq K w₁ hB n : 𝓞 K) }) = Ideal.span ({ (seq K w₁ hB m : 𝓞 K) }))
+ · have hu := Ideal.span_singleton_eq_span_singleton.mp h
+ refine ⟨hu.choose, fun w hw => Real.log_neg ?_ ?_⟩
+ · simp only [pos_iff, ne_eq, ZeroMemClass.coe_eq_zero, ne_zero]
+ · calc
+ _ = w ((seq K w₁ hB m : K) * (seq K w₁ hB n : K)⁻¹) := by
+ rw [← congr_arg ((↑) : (𝓞 K) → K) hu.choose_spec, mul_comm, Submonoid.coe_mul,
+ ← mul_assoc, inv_mul_cancel (seq_ne_zero K w₁ hB n), one_mul]
+ _ = w (seq K w₁ hB m) * w (seq K w₁ hB n)⁻¹ := _root_.map_mul _ _ _
+ _ < 1 := by
+ rw [map_inv₀, mul_inv_lt_iff (pos_iff.mpr (seq_ne_zero K w₁ hB n)), mul_one]
+ exact seq_decreasing K w₁ hB hnm w hw
+ refine Set.Finite.exists_lt_map_eq_of_forall_mem
+ (t := { I : Ideal (𝓞 K) | 1 ≤ Ideal.absNorm I ∧ Ideal.absNorm I ≤ B })
+ (fun n => ?_) ?_
+ · rw [Set.mem_setOf_eq, Ideal.absNorm_span_singleton]
+ refine ⟨?_, seq_norm_le K w₁ hB n⟩
+ exact Nat.one_le_iff_ne_zero.mpr (Int.natAbs_ne_zero.mpr (seq_norm_ne_zero K w₁ hB n))
+ · rw [show { I : Ideal (𝓞 K) | 1 ≤ Ideal.absNorm I ∧ Ideal.absNorm I ≤ B } =
+ (⋃ n ∈ Set.Icc 1 B, { I : Ideal (𝓞 K) | Ideal.absNorm I = n }) by ext; simp]
+ exact Set.Finite.biUnion (Set.finite_Icc _ _) (fun n hn => Ideal.finite_setOf_absNorm_eq hn.1)
+
+theorem unitLattice_span_eq_top :
+ Submodule.span ℝ (unitLattice K : Set ({w : InfinitePlace K // w ≠ w₀} → ℝ)) = ⊤ := by
+ refine le_antisymm (le_top) ?_
+ -- The standard basis
+ let B := Pi.basisFun ℝ {w : InfinitePlace K // w ≠ w₀}
+ -- The image by log_embedding of the family of units constructed above
+ let v := fun w : { w : InfinitePlace K // w ≠ w₀ } => logEmbedding K (exists_unit K w).choose
+ -- To prove the result, it is enough to prove that the family `v` is linearly independent
+ suffices B.det v ≠ 0 by
+ rw [← isUnit_iff_ne_zero, ← is_basis_iff_det] at this
+ rw [← this.2]
+ exact Submodule.span_monotone (fun _ ⟨w, hw⟩ =>
+ ⟨(exists_unit K w).choose, trivial, by rw [← hw]⟩)
+ rw [Basis.det_apply]
+ -- We use a specific lemma to prove that this determinant is nonzero
+ refine det_ne_zero_of_sum_col_lt_diag (fun w => ?_)
+ simp_rw [Real.norm_eq_abs, Basis.coePiBasisFun.toMatrix_eq_transpose, Matrix.transpose_apply]
+ rw [← sub_pos, sum_congr rfl (fun x hx => abs_of_neg ?_), sum_neg_distrib, sub_neg_eq_add,
+ sum_erase_eq_sub (mem_univ _), ← add_comm_sub]
+ refine add_pos_of_nonneg_of_pos ?_ ?_
+ · rw [sub_nonneg]
+ exact le_abs_self _
+ · rw [sum_logEmbedding_component (exists_unit K w).choose]
+ refine mul_pos_of_neg_of_neg ?_ ((exists_unit K w).choose_spec _ w.prop.symm)
+ rw [mult]; split_ifs <;> norm_num
+ · refine mul_neg_of_pos_of_neg ?_ ((exists_unit K w).choose_spec x ?_)
+ · rw [mult]; split_ifs <;> norm_num
+ · exact Subtype.ext_iff_val.not.mp (ne_of_mem_erase hx)
+
+end span_top
+
+end dirichletUnitTheorem
+
+section statements
+
+variable [NumberField K]
+
+open dirichletUnitTheorem FiniteDimensional Classical
+
+/-- The unit rank of the number field `K`, it is equal to `card (InfinitePlace K) - 1`. -/
+def rank : ℕ := Fintype.card (InfinitePlace K) - 1
+
+instance instDiscrete_unitLattice : DiscreteTopology (unitLattice K) := by
+ refine discreteTopology_of_open_singleton_zero ?_
+ refine isOpen_singleton_of_finite_mem_nhds 0 (s := Metric.closedBall 0 1) ?_ ?_
+ · exact Metric.closedBall_mem_nhds _ (by norm_num)
+ · refine Set.Finite.of_finite_image ?_ (Set.injOn_of_injective Subtype.val_injective _)
+ convert unitLattice_inter_ball_finite K 1
+ ext x
+ refine ⟨?_, fun ⟨hx1, hx2⟩ => ⟨⟨x, hx1⟩, hx2, rfl⟩⟩
+ rintro ⟨x, hx, rfl⟩
+ exact ⟨Subtype.mem x, hx⟩
+
+protected theorem finrank_eq_rank :
+ finrank ℝ ({w : InfinitePlace K // w ≠ w₀} → ℝ) = Units.rank K := by
+ simp only [finrank_fintype_fun_eq_card, Fintype.card_subtype_compl,
+ Fintype.card_ofSubsingleton, rank]
+
+instance instModuleFree_unitLattice : Module.Free ℤ (unitLattice K) :=
+ Zlattice.module_free ℝ (unitLattice_span_eq_top K)
+
+instance instModuleFinite_unitLattice : Module.Finite ℤ (unitLattice K) :=
+ Zlattice.module_finite ℝ (unitLattice_span_eq_top K)
+
+@[simp]
+theorem unitLattice_rank :
+ finrank ℤ (unitLattice K) = Units.rank K := by
+ rw [← Units.finrank_eq_rank]
+ exact Zlattice.rank ℝ (unitLattice_span_eq_top K)
+
+/-- The linear equivalence between `unitLattice` and `(𝓞 K)ˣ ⧸ (torsion K)` as an additive
+`ℤ`-module. -/
+def unitLatticeEquiv : (unitLattice K) ≃ₗ[ℤ] Additive ((𝓞 K)ˣ ⧸ (torsion K)) := by
+ refine AddEquiv.toIntLinearEquiv ?_
+ rw [unitLattice, ← AddMonoidHom.range_eq_map (logEmbedding K)]
+ refine (QuotientAddGroup.quotientKerEquivRange (logEmbedding K)).symm.trans ?_
+ refine (QuotientAddGroup.quotientAddEquivOfEq ?_).trans
+ (QuotientAddGroup.quotientKerEquivOfSurjective
+ (MonoidHom.toAdditive (QuotientGroup.mk' (torsion K))) (fun x => ?_))
+ · ext
+ rw [AddMonoidHom.mem_ker, AddMonoidHom.mem_ker, logEmbedding_eq_zero_iff,
+ MonoidHom.toAdditive_apply_apply, ofMul_eq_zero, QuotientGroup.mk'_apply,
+ QuotientGroup.eq_one_iff]
+ rfl
+ · refine ⟨Additive.ofMul x.out', ?_⟩
+ simp only [MonoidHom.toAdditive_apply_apply, toMul_ofMul, QuotientGroup.mk'_apply,
+ QuotientGroup.out_eq']
+ rfl
+
+instance : Module.Free ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
+ (instModuleFree_unitLattice K).of_equiv' (unitLatticeEquiv K)
+
+instance : Module.Finite ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
+ Module.Finite.equiv (unitLatticeEquiv K)
+
+theorem rank_modTorsion :
+ FiniteDimensional.finrank ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) = rank K := by
+ rw [← LinearEquiv.finrank_eq (unitLatticeEquiv K), unitLattice_rank]
+
+/-- A basis of the quotient `(𝓞 K)ˣ ⧸ (torsion K)` seen as an additive ℤ-module. -/
+def basisModTorsion : Basis (Fin (rank K)) ℤ (Additive ((𝓞 K)ˣ ⧸ (torsion K))) :=
+ Basis.reindex (Module.Free.chooseBasis ℤ _) (Fintype.equivOfCardEq <| by
+ rw [← FiniteDimensional.finrank_eq_card_chooseBasisIndex, rank_modTorsion, Fintype.card_fin])
+
+/-- A fundamental system of units of `K`. The units of `fundSystem` are arbitrary lifts of the
+units in `basisModTorsion`. -/
+def fundSystem : Fin (rank K) → (𝓞 K)ˣ :=
+ fun i => Quotient.out' (Additive.toMul (basisModTorsion K i))
+
+/-- The exponents that appear in the unique decomposition of a unit as the product of
+a root of unity and powers of the units of the fundamental system `fundSystem` (see
+`exist_unique_eq_mul_prod`) are given by the representation of the unit of `basisModTorsion`. -/
+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) := by
+ suffices Additive.ofMul ↑x = ∑ i, (f i) • (basisModTorsion K i) by
+ rw [← (basisModTorsion K).repr_sum_self f, ← this]
+ calc
+ Additive.ofMul ↑x = ∑ i, (f i) • Additive.ofMul ↑(fundSystem K i) := by
+ rw [h, QuotientGroup.mk_mul, (QuotientGroup.eq_one_iff _).mpr hζ, one_mul,
+ QuotientGroup.mk_prod, ofMul_prod]; rfl
+ _ = ∑ i, (f i) • (basisModTorsion K i) := by
+ simp_rw [fundSystem, QuotientGroup.out_eq', ofMul_toMul]
+
+/-- **Dirichlet Unit Theorem**. Any unit `x` of `𝓞 K` can be written uniquely as the product of
+a root of unity and powers of the units of the fundamental system `fundSystem`. -/
+theorem exist_unique_eq_mul_prod (x : (𝓞 K)ˣ) : ∃! (ζ : torsion K) (e : Fin (rank K) → ℤ),
+ x = ζ * ∏ i, (fundSystem K i) ^ (e i) := by
+ let ζ := x * (∏ i, (fundSystem K i) ^ ((basisModTorsion K).repr (Additive.ofMul ↑x) i))⁻¹
+ have h_tors : ζ ∈ torsion K := by
+ rw [← QuotientGroup.eq_one_iff, QuotientGroup.mk_mul, QuotientGroup.mk_inv, ← ofMul_eq_zero,
+ ofMul_mul, ofMul_inv, QuotientGroup.mk_prod, ofMul_prod]
+ simp_rw [QuotientGroup.mk_zpow, ofMul_zpow, fundSystem, QuotientGroup.out_eq', ofMul_toMul]
+ rw [add_eq_zero_iff_eq_neg, neg_neg]
+ exact ((basisModTorsion K).sum_repr (Additive.ofMul ↑x)).symm
+ refine ⟨⟨ζ, h_tors⟩, ?_, ?_⟩
+ · refine ⟨((basisModTorsion K).repr (Additive.ofMul ↑x) : Fin (rank K) → ℤ), ?_, ?_⟩
+ · simp only [_root_.inv_mul_cancel_right]
+ · exact fun _ hf => fun_eq_repr K h_tors hf
+ · rintro η ⟨_, hf, _⟩
+ simp_rw [fun_eq_repr K η.prop hf] at hf
+ ext1; dsimp only
+ nth_rewrite 1 [hf]
+ rw [_root_.mul_inv_cancel_right]
+
+end statements
+
end NumberField.Units
@@ -124,7 +124,7 @@ def torsionOrder [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
order dividing `k`. -/
-theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.coprime k (torsionOrder K)) :
+theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K)) :
ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
rw [mem_rootsOfUnity]
refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
@@ -124,7 +124,7 @@ def torsionOrder [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
order dividing `k`. -/
-theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K)) :
+theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.coprime k (torsionOrder K)) :
ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
rw [mem_rootsOfUnity]
refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
Some changes have already been review and delegated in #6910 and #7148.
The diff that needs looking at is https://github.com/leanprover-community/mathlib4/pull/7174/commits/64d6d07ee18163627c8f517eb31455411921c5ac
The std bump PR was insta-merged already!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -124,7 +124,7 @@ def torsionOrder [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
order dividing `k`. -/
-theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.coprime k (torsionOrder K)) :
+theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K)) :
ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
rw [mem_rootsOfUnity]
refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
@@ -120,11 +120,11 @@ instance [NumberField K] : Finite (torsion K) := inferInstance
instance [NumberField K] : IsCyclic (torsion K) := subgroup_units_cyclic _
/-- The order of the torsion subgroup as positive integer. -/
-def torsion_order [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.card_pos⟩
+def torsionOrder [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.card_pos⟩
-/-- If `k` does not divide `torsion_order` then there are no nontrivial roots of unity of
+/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
order dividing `k`. -/
-theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.coprime k (torsion_order K)) :
+theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.coprime k (torsionOrder K)) :
ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
rw [mem_rootsOfUnity]
refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
@@ -136,15 +136,15 @@ theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.coprime k (tors
rw [orderOf_submonoid (⟨ζ, hζ⟩ : torsion K)]
exact orderOf_dvd_card_univ
-/-- The group of roots of unity of order dividing `torsion_order` is equal to the torsion
+/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
theorem rootsOfUnity_eq_torsion [NumberField K] :
- rootsOfUnity (torsion_order K) (𝓞 K) = torsion K := by
+ rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
ext ζ
rw [torsion, mem_rootsOfUnity]
refine ⟨fun h => ?_, fun h => ?_⟩
· rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
- exact ⟨↑(torsion_order K), (torsion_order K).prop, h⟩
+ exact ⟨↑(torsionOrder K), (torsionOrder K).prop, h⟩
· exact Subtype.ext_iff.mp (@pow_card_eq_one (torsion K) _ ⟨ζ, h⟩ _)
end torsion
Autoimplicits are highly controversial and also defeat the performance-improving work in #6474.
The intent of this PR is to make autoImplicit
opt-in on a per-file basis, by disabling it in the lakefile and enabling it again with set_option autoImplicit true
in the few files that rely on it.
That also keeps this PR small, as opposed to attempting to "fix" files to not need it any more.
I claim that many of the uses of autoImplicit
in these files are accidental; situations such as:
variables
are in scope, but pasting the lemma in the wrong sectionHaving set_option autoImplicit false
as the default prevents these types of mistake being made in the 90% of files where autoImplicit
s are not used at all, and causes them to be caught by CI during review.
I think there were various points during the port where we encouraged porters to delete the universes u v
lines; I think having autoparams for universe variables only would cover a lot of the cases we actually use them, while avoiding any real shortcomings.
A Zulip poll (after combining overlapping votes accordingly) was in favor of this change with 5:5:18
as the no:dontcare:yes
vote ratio.
While this PR was being reviewed, a handful of files gained some more likely-accidental autoImplicits. In these places, set_option autoImplicit true
has been placed locally within a section, rather than at the top of the file.
@@ -23,6 +23,8 @@ field `K`.
number field, units
-/
+set_option autoImplicit true
+
open scoped NumberField
This removes a maxHeartbeats bump (the only one in the file).
@@ -111,7 +111,9 @@ instance [NumberField K] : Fintype (torsion K) := by
· rw [← h_ua]
exact le_of_eq ((eq_iff_eq _ 1).mp ((mem_torsion K).mp h_tors) φ)
-set_option synthInstance.maxHeartbeats 30000 in
+-- a shortcut instance to stop the next instance from timing out
+instance [NumberField K] : Finite (torsion K) := inferInstance
+
/-- The torsion subgroup is cylic. -/
instance [NumberField K] : IsCyclic (torsion K) := subgroup_units_cyclic _
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -40,7 +40,7 @@ theorem Rat.RingOfIntegers.isUnit_iff {x : 𝓞 ℚ} : IsUnit x ↔ (x : ℚ) =
end Rat
-variable (K : Type _) [Field K]
+variable (K : Type*) [Field K]
section IsUnit
Don't mind at all if anyone would like to push refactors or golfs. My main requirement from this PR is that
import Mathlib
example : WellFoundedLT { x : ℕ // x ≤ 37 }ᵒᵈ := inferInstance
works out of the box.
Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Matthew Robert Ballard <matt@mrb.email> Co-authored-by: Xavier Roblot <46200072+xroblot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Jz Pan <acme_pjz@hotmail.com> Co-authored-by: Thomas Browning <tb65536@uw.edu> Co-authored-by: Oliver Nash <github@olivernash.org> Co-authored-by: Christopher Hoskin <christopher.hoskin@gmail.com> Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com> Co-authored-by: Anatole Dedecker <anatolededecker@gmail.com> Co-authored-by: Matthew Robert Ballard <k.buzzard@imperial.ac.uk> Co-authored-by: Peter Nelson <71660771+apnelson1@users.noreply.github.com> Co-authored-by: Rémy Degenne <remydegenne@gmail.com> Co-authored-by: MohanadAhmed <m.a.m.elhassan@gmail.com> Co-authored-by: Mario Carneiro <di.gama@gmail.com> Co-authored-by: damiano <adomani@gmail.com> Co-authored-by: Chris Hughes <chrishughes24@gmail.com> Co-authored-by: Rémy Degenne <Remydegenne@gmail.com> Co-authored-by: Jon Eugster <eugster.jon@gmail.com> Co-authored-by: Kevin Buzzard <k.buzzard@imperial.ac.uk>
@@ -111,6 +111,7 @@ instance [NumberField K] : Fintype (torsion K) := by
· rw [← h_ua]
exact le_of_eq ((eq_iff_eq _ 1).mp ((mem_torsion K).mp h_tors) φ)
+set_option synthInstance.maxHeartbeats 30000 in
/-- The torsion subgroup is cylic. -/
instance [NumberField K] : IsCyclic (torsion K) := subgroup_units_cyclic _
We define the torsion subgroup of the units of a number field and prove some results about it, mostly: it is finite, cyclic and
an unit is torsion iff its value is 1 at all infinite places. Some results linking to rootsOfUnity
are also proved.
This PR also includes a direct coercion from (𝓞 K)ˣ
to K
that is very convenient, although I am not sure it's done properly.
@@ -3,7 +3,10 @@ Copyright (c) 2023 Xavier Roblot. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Xavier Roblot
-/
+import Mathlib.GroupTheory.Torsion
+import Mathlib.NumberTheory.NumberField.Embeddings
import Mathlib.NumberTheory.NumberField.Norm
+import Mathlib.RingTheory.RootsOfUnity.Basic
#align_import number_theory.number_field.units from "leanprover-community/mathlib"@"00f91228655eecdcd3ac97a7fd8dbcb139fe990a"
@@ -13,7 +16,8 @@ We prove results about the group `(𝓞 K)ˣ` of units of the ring of integers `
field `K`.
## Main results
-* `isUnit_iff_norm`: an algebraic integer `x : 𝓞 K` is a unit if and only if `|norm ℚ x| = 1`
+* `isUnit_iff_norm`: an algebraic integer `x : 𝓞 K` is a unit if and only if `|norm ℚ x| = 1`.
+* `mem_torsion`: a unit `x : (𝓞 K)ˣ` is torsion iff `w x = 1` for all infinite places of `K`.
## Tags
number field, units
@@ -42,10 +46,102 @@ section IsUnit
variable {K}
-theorem isUnit_iff_norm [NumberField K] (x : 𝓞 K) :
+theorem isUnit_iff_norm [NumberField K] {x : 𝓞 K} :
IsUnit x ↔ |(RingOfIntegers.norm ℚ x : ℚ)| = 1 := by
convert (RingOfIntegers.isUnit_norm ℚ (F := K)).symm
rw [← abs_one, abs_eq_abs, ← Rat.RingOfIntegers.isUnit_iff]
#align is_unit_iff_norm isUnit_iff_norm
end IsUnit
+
+namespace NumberField.Units
+
+section coe
+
+theorem coe_injective : Function.Injective ((↑) : (𝓞 K)ˣ → K) :=
+ fun _ _ h => by rwa [SetLike.coe_eq_coe, Units.eq_iff] at h
+
+variable {K}
+
+theorem coe_mul (x y : (𝓞 K)ˣ) : ((x * y : (𝓞 K)ˣ) : K) = (x : K) * (y : K) := rfl
+
+theorem coe_pow (x : (𝓞 K)ˣ) (n : ℕ) : (x ^ n : K) = (x : K) ^ n := by
+ rw [← SubmonoidClass.coe_pow, ← val_pow_eq_pow_val]
+
+theorem coe_zpow (x : (𝓞 K)ˣ) (n : ℤ) : (x ^ n : K) = (x : K) ^ n := by
+ change ((Units.coeHom K).comp (map (algebraMap (𝓞 K) K))) (x ^ n) = _
+ exact map_zpow _ x n
+
+theorem coe_one : ((1 : (𝓞 K)ˣ) : K) = (1 : K) := rfl
+
+theorem coe_neg_one : ((-1 : (𝓞 K)ˣ) : K) = (-1 : K) := rfl
+
+theorem coe_ne_zero (x : (𝓞 K)ˣ) : (x : K) ≠ 0 :=
+ Subtype.coe_injective.ne_iff.mpr (_root_.Units.ne_zero x)
+
+end coe
+
+open NumberField.InfinitePlace
+
+section torsion
+
+/-- The torsion subgroup of the group of units. -/
+def torsion : Subgroup (𝓞 K)ˣ := CommGroup.torsion (𝓞 K)ˣ
+
+theorem mem_torsion {x : (𝓞 K)ˣ} [NumberField K] :
+ x ∈ torsion K ↔ ∀ w : InfinitePlace K, w x = 1 := by
+ rw [eq_iff_eq (x : K) 1, torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
+ refine ⟨fun ⟨n, h_pos, h_eq⟩ φ => ?_, fun h => ?_⟩
+ · refine norm_map_one_of_pow_eq_one φ.toMonoidHom (k := ⟨n, h_pos⟩) ?_
+ rw [PNat.mk_coe, ← coe_pow, h_eq, coe_one]
+ · obtain ⟨n, hn, hx⟩ := Embeddings.pow_eq_one_of_norm_eq_one K ℂ x.val.prop h
+ exact ⟨n, hn, by ext; rw [coe_pow, hx, coe_one]⟩
+
+/-- Shortcut instance because Lean tends to time out before finding the general instance. -/
+instance : Nonempty (torsion K) := One.nonempty
+
+/-- The torsion subgroup is finite. -/
+instance [NumberField K] : Fintype (torsion K) := by
+ refine @Fintype.ofFinite _ (Set.finite_coe_iff.mpr ?_)
+ refine Set.Finite.of_finite_image ?_ ((coe_injective K).injOn _)
+ refine (Embeddings.finite_of_norm_le K ℂ 1).subset
+ (fun a ⟨u, ⟨h_tors, h_ua⟩⟩ => ⟨?_, fun φ => ?_⟩)
+ · rw [← h_ua]
+ exact u.val.prop
+ · rw [← h_ua]
+ exact le_of_eq ((eq_iff_eq _ 1).mp ((mem_torsion K).mp h_tors) φ)
+
+/-- The torsion subgroup is cylic. -/
+instance [NumberField K] : IsCyclic (torsion K) := subgroup_units_cyclic _
+
+/-- The order of the torsion subgroup as positive integer. -/
+def torsion_order [NumberField K] : ℕ+ := ⟨Fintype.card (torsion K), Fintype.card_pos⟩
+
+/-- If `k` does not divide `torsion_order` then there are no nontrivial roots of unity of
+ order dividing `k`. -/
+theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.coprime k (torsion_order K)) :
+ ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
+ rw [mem_rootsOfUnity]
+ refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
+ refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
+ · exact orderOf_dvd_of_pow_eq_one h
+ · have hζ : ζ ∈ torsion K := by
+ rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
+ exact ⟨k, k.prop, h⟩
+ rw [orderOf_submonoid (⟨ζ, hζ⟩ : torsion K)]
+ exact orderOf_dvd_card_univ
+
+/-- The group of roots of unity of order dividing `torsion_order` is equal to the torsion
+group. -/
+theorem rootsOfUnity_eq_torsion [NumberField K] :
+ rootsOfUnity (torsion_order K) (𝓞 K) = torsion K := by
+ ext ζ
+ rw [torsion, mem_rootsOfUnity]
+ refine ⟨fun h => ?_, fun h => ?_⟩
+ · rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
+ exact ⟨↑(torsion_order K), (torsion_order K).prop, h⟩
+ · exact Subtype.ext_iff.mp (@pow_card_eq_one (torsion K) _ ⟨ζ, h⟩ _)
+
+end torsion
+
+end NumberField.Units
@@ -40,8 +40,6 @@ variable (K : Type _) [Field K]
section IsUnit
-attribute [local instance] NumberField.ringOfIntegersAlgebra
-
variable {K}
theorem isUnit_iff_norm [NumberField K] (x : 𝓞 K) :
@@ -2,14 +2,11 @@
Copyright (c) 2023 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.units
-! leanprover-community/mathlib commit 00f91228655eecdcd3ac97a7fd8dbcb139fe990a
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.NumberTheory.NumberField.Norm
+#align_import number_theory.number_field.units from "leanprover-community/mathlib"@"00f91228655eecdcd3ac97a7fd8dbcb139fe990a"
+
/-!
# Units of a number field
We prove results about the group `(𝓞 K)ˣ` of units of the ring of integers `𝓞 K` of a number
The unported dependencies are