algebra.module.zlattice
⟷
Mathlib.Algebra.Module.Zlattice
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)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -88,13 +88,19 @@ def ceil (m : E) : span ℤ (Set.range b) :=
#print Zspan.repr_floor_apply /-
@[simp]
-theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by classical
+theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by
+ classical simp only [floor, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
+ Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
+ Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
#align zspan.repr_floor_apply Zspan.repr_floor_apply
-/
#print Zspan.repr_ceil_apply /-
@[simp]
-theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by classical
+theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by
+ classical simp only [ceil, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
+ Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
+ Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
#align zspan.repr_ceil_apply Zspan.repr_ceil_apply
-/
@@ -148,14 +154,20 @@ theorem repr_fract_apply (m : E) (i : ι) : b.repr (fract b m) i = Int.fract (b.
#print Zspan.fract_fract /-
@[simp]
theorem fract_fract (m : E) : fract b (fract b m) = fract b m :=
- Basis.ext_elem b fun _ => by classical
+ Basis.ext_elem b fun _ => by classical simp only [repr_fract_apply, Int.fract_fract]
#align zspan.fract_fract Zspan.fract_fract
-/
#print Zspan.fract_zspan_add /-
@[simp]
theorem fract_zspan_add (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
- fract b (v + m) = fract b m := by classical
+ fract b (v + m) = fract b m := by
+ classical
+ refine' (Basis.ext_elem_iff b).mpr fun i => _
+ simp_rw [repr_fract_apply, Int.fract_eq_fract]
+ use(b.restrict_scalars ℤ).repr ⟨v, h⟩ i
+ rw [map_add, Finsupp.coe_add, Pi.add_apply, add_tsub_cancel_right, ←
+ eq_intCast (algebraMap ℤ K) _, Basis.restrictScalars_repr_apply, coe_mk]
#align zspan.fract_zspan_add Zspan.fract_zspan_add
-/
@@ -169,7 +181,9 @@ theorem fract_add_zspan (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
variable {b}
#print Zspan.fract_eq_self /-
-theorem fract_eq_self {x : E} : fract b x = x ↔ x ∈ fundamentalDomain b := by classical
+theorem fract_eq_self {x : E} : fract b x = x ↔ x ∈ fundamentalDomain b := by
+ classical simp only [Basis.ext_elem_iff b, repr_fract_apply, Int.fract_eq_self,
+ mem_fundamental_domain, Set.mem_Ico]
#align zspan.fract_eq_self Zspan.fract_eq_self
-/
@@ -184,11 +198,30 @@ theorem fract_mem_fundamentalDomain (x : E) : fract b x ∈ fundamentalDomain b
#print Zspan.fract_eq_fract /-
theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ (Set.range b) := by
classical
+ rw [eq_comm, Basis.ext_elem_iff b]
+ simp_rw [repr_fract_apply, Int.fract_eq_fract, eq_comm, Basis.mem_span_iff_repr_mem,
+ sub_eq_neg_add, map_add, LinearEquiv.map_neg, Finsupp.coe_add, Finsupp.coe_neg, Pi.add_apply,
+ Pi.neg_apply, ← eq_intCast (algebraMap ℤ K) _, Set.mem_range]
#align zspan.fract_eq_fract Zspan.fract_eq_fract
-/
#print Zspan.norm_fract_le /-
-theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b i‖ := by classical
+theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b i‖ := by
+ classical
+ calc
+ ‖fract b m‖ = ‖∑ i, b.repr (fract b m) i • b i‖ := by rw [b.sum_repr]
+ _ = ‖∑ i, Int.fract (b.repr m i) • b i‖ := by simp_rw [repr_fract_apply]
+ _ ≤ ∑ i, ‖Int.fract (b.repr m i) • b i‖ := (norm_sum_le _ _)
+ _ ≤ ∑ i, ‖Int.fract (b.repr m i)‖ * ‖b i‖ := by simp_rw [norm_smul]
+ _ ≤ ∑ i, ‖b i‖ := Finset.sum_le_sum fun i _ => _
+ suffices ‖Int.fract ((b.repr m) i)‖ ≤ 1
+ by
+ convert mul_le_mul_of_nonneg_right this (norm_nonneg _ : 0 ≤ ‖b i‖)
+ exact (one_mul _).symm
+ rw [(norm_one.symm : 1 = ‖(1 : K)‖)]
+ apply norm_le_norm_of_abs_le_abs
+ rw [abs_one, Int.abs_fract]
+ exact le_of_lt (Int.fract_lt_one _)
#align zspan.norm_fract_le Zspan.norm_fract_le
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -88,19 +88,13 @@ def ceil (m : E) : span ℤ (Set.range b) :=
#print Zspan.repr_floor_apply /-
@[simp]
-theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by
- classical simp only [floor, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
- Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
- Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
+theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by classical
#align zspan.repr_floor_apply Zspan.repr_floor_apply
-/
#print Zspan.repr_ceil_apply /-
@[simp]
-theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by
- classical simp only [ceil, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
- Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
- Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
+theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by classical
#align zspan.repr_ceil_apply Zspan.repr_ceil_apply
-/
@@ -154,20 +148,14 @@ theorem repr_fract_apply (m : E) (i : ι) : b.repr (fract b m) i = Int.fract (b.
#print Zspan.fract_fract /-
@[simp]
theorem fract_fract (m : E) : fract b (fract b m) = fract b m :=
- Basis.ext_elem b fun _ => by classical simp only [repr_fract_apply, Int.fract_fract]
+ Basis.ext_elem b fun _ => by classical
#align zspan.fract_fract Zspan.fract_fract
-/
#print Zspan.fract_zspan_add /-
@[simp]
theorem fract_zspan_add (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
- fract b (v + m) = fract b m := by
- classical
- refine' (Basis.ext_elem_iff b).mpr fun i => _
- simp_rw [repr_fract_apply, Int.fract_eq_fract]
- use(b.restrict_scalars ℤ).repr ⟨v, h⟩ i
- rw [map_add, Finsupp.coe_add, Pi.add_apply, add_tsub_cancel_right, ←
- eq_intCast (algebraMap ℤ K) _, Basis.restrictScalars_repr_apply, coe_mk]
+ fract b (v + m) = fract b m := by classical
#align zspan.fract_zspan_add Zspan.fract_zspan_add
-/
@@ -181,9 +169,7 @@ theorem fract_add_zspan (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
variable {b}
#print Zspan.fract_eq_self /-
-theorem fract_eq_self {x : E} : fract b x = x ↔ x ∈ fundamentalDomain b := by
- classical simp only [Basis.ext_elem_iff b, repr_fract_apply, Int.fract_eq_self,
- mem_fundamental_domain, Set.mem_Ico]
+theorem fract_eq_self {x : E} : fract b x = x ↔ x ∈ fundamentalDomain b := by classical
#align zspan.fract_eq_self Zspan.fract_eq_self
-/
@@ -198,30 +184,11 @@ theorem fract_mem_fundamentalDomain (x : E) : fract b x ∈ fundamentalDomain b
#print Zspan.fract_eq_fract /-
theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ (Set.range b) := by
classical
- rw [eq_comm, Basis.ext_elem_iff b]
- simp_rw [repr_fract_apply, Int.fract_eq_fract, eq_comm, Basis.mem_span_iff_repr_mem,
- sub_eq_neg_add, map_add, LinearEquiv.map_neg, Finsupp.coe_add, Finsupp.coe_neg, Pi.add_apply,
- Pi.neg_apply, ← eq_intCast (algebraMap ℤ K) _, Set.mem_range]
#align zspan.fract_eq_fract Zspan.fract_eq_fract
-/
#print Zspan.norm_fract_le /-
-theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b i‖ := by
- classical
- calc
- ‖fract b m‖ = ‖∑ i, b.repr (fract b m) i • b i‖ := by rw [b.sum_repr]
- _ = ‖∑ i, Int.fract (b.repr m i) • b i‖ := by simp_rw [repr_fract_apply]
- _ ≤ ∑ i, ‖Int.fract (b.repr m i) • b i‖ := (norm_sum_le _ _)
- _ ≤ ∑ i, ‖Int.fract (b.repr m i)‖ * ‖b i‖ := by simp_rw [norm_smul]
- _ ≤ ∑ i, ‖b i‖ := Finset.sum_le_sum fun i _ => _
- suffices ‖Int.fract ((b.repr m) i)‖ ≤ 1
- by
- convert mul_le_mul_of_nonneg_right this (norm_nonneg _ : 0 ≤ ‖b i‖)
- exact (one_mul _).symm
- rw [(norm_one.symm : 1 = ‖(1 : K)‖)]
- apply norm_le_norm_of_abs_le_abs
- rw [abs_one, Int.abs_fract]
- exact le_of_lt (Int.fract_lt_one _)
+theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b i‖ := by classical
#align zspan.norm_fract_le Zspan.norm_fract_le
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -264,8 +264,8 @@ theorem fundamentalDomain_isBounded [Finite ι] [HasSolidNorm K] :
#print Zspan.vadd_mem_fundamentalDomain /-
theorem vadd_mem_fundamentalDomain [Fintype ι] (y : span ℤ (Set.range b)) (x : E) :
y +ᵥ x ∈ fundamentalDomain b ↔ y = -floor b x := by
- rw [Subtype.ext_iff, ← add_right_inj x, AddSubgroupClass.coe_neg, ← sub_eq_add_neg, ← fract_apply,
- ← fract_zspan_add b _ (Subtype.mem y), add_comm, ← vadd_eq_add, ← vadd_def, eq_comm, ←
+ rw [Subtype.ext_iff, ← add_right_inj x, NegMemClass.coe_neg, ← sub_eq_add_neg, ← fract_apply, ←
+ fract_zspan_add b _ (Subtype.mem y), add_comm, ← vadd_eq_add, ← vadd_def, eq_comm, ←
fract_eq_self]
#align zspan.vadd_mem_fundamental_domain Zspan.vadd_mem_fundamentalDomain
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -91,7 +91,7 @@ def ceil (m : E) : span ℤ (Set.range b) :=
theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by
classical simp only [floor, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
- Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, LinearEquiv.map_sum]
+ Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
#align zspan.repr_floor_apply Zspan.repr_floor_apply
-/
@@ -100,7 +100,7 @@ theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i
theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by
classical simp only [ceil, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
- Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, LinearEquiv.map_sum]
+ Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
#align zspan.repr_ceil_apply Zspan.repr_ceil_apply
-/
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.MeasureTheory.Group.FundamentalDomain
+import MeasureTheory.Group.FundamentalDomain
#align_import algebra.module.zlattice from "leanprover-community/mathlib"@"660b3a2db3522fa0db036e569dc995a615c4c848"
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -247,9 +247,9 @@ end Unique
end Fintype
-#print Zspan.fundamentalDomain_bounded /-
-theorem fundamentalDomain_bounded [Finite ι] [HasSolidNorm K] :
- Metric.Bounded (fundamentalDomain b) :=
+#print Zspan.fundamentalDomain_isBounded /-
+theorem fundamentalDomain_isBounded [Finite ι] [HasSolidNorm K] :
+ Bornology.IsBounded (fundamentalDomain b) :=
by
cases nonempty_fintype ι
use 2 * ∑ j, ‖b j‖
@@ -258,7 +258,7 @@ theorem fundamentalDomain_bounded [Finite ι] [HasSolidNorm K] :
rw [← fract_eq_self.mpr hx, ← fract_eq_self.mpr hy]
refine' (add_le_add (norm_fract_le b x) (norm_fract_le b y)).trans _
rw [← two_mul]
-#align zspan.fundamental_domain_bounded Zspan.fundamentalDomain_bounded
+#align zspan.fundamental_domain_bounded Zspan.fundamentalDomain_isBounded
-/
#print Zspan.vadd_mem_fundamentalDomain /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/63721b2c3eba6c325ecf8ae8cca27155a4f6306f
@@ -165,7 +165,7 @@ theorem fract_zspan_add (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
classical
refine' (Basis.ext_elem_iff b).mpr fun i => _
simp_rw [repr_fract_apply, Int.fract_eq_fract]
- use (b.restrict_scalars ℤ).repr ⟨v, h⟩ i
+ use(b.restrict_scalars ℤ).repr ⟨v, h⟩ i
rw [map_add, Finsupp.coe_add, Pi.add_apply, add_tsub_cancel_right, ←
eq_intCast (algebraMap ℤ K) _, Basis.restrictScalars_repr_apply, coe_mk]
#align zspan.fract_zspan_add Zspan.fract_zspan_add
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 algebra.module.zlattice
-! leanprover-community/mathlib commit 660b3a2db3522fa0db036e569dc995a615c4c848
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.MeasureTheory.Group.FundamentalDomain
+#align_import algebra.module.zlattice from "leanprover-community/mathlib"@"660b3a2db3522fa0db036e569dc995a615c4c848"
+
/-!
# ℤ-lattices
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -59,11 +59,13 @@ def fundamentalDomain : Set E :=
#align zspan.fundamental_domain Zspan.fundamentalDomain
-/
+#print Zspan.mem_fundamentalDomain /-
@[simp]
theorem mem_fundamentalDomain {m : E} :
m ∈ fundamentalDomain b ↔ ∀ i, b.repr m i ∈ Set.Ico (0 : K) 1 :=
Iff.rfl
#align zspan.mem_fundamental_domain Zspan.mem_fundamentalDomain
+-/
variable [FloorRing K]
@@ -71,32 +73,41 @@ section Fintype
variable [Fintype ι]
+#print Zspan.floor /-
/-- The map that sends a vector of `E` to the element of the ℤ-lattice spanned by `b` obtained
by rounding down its coordinates on the basis `b`. -/
def floor (m : E) : span ℤ (Set.range b) :=
∑ i, ⌊b.repr m i⌋ • b.restrictScalars ℤ i
#align zspan.floor Zspan.floor
+-/
+#print Zspan.ceil /-
/-- The map that sends a vector of `E` to the element of the ℤ-lattice spanned by `b` obtained
by rounding up its coordinates on the basis `b`. -/
def ceil (m : E) : span ℤ (Set.range b) :=
∑ i, ⌈b.repr m i⌉ • b.restrictScalars ℤ i
#align zspan.ceil Zspan.ceil
+-/
+#print Zspan.repr_floor_apply /-
@[simp]
theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by
classical simp only [floor, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, LinearEquiv.map_sum]
#align zspan.repr_floor_apply Zspan.repr_floor_apply
+-/
+#print Zspan.repr_ceil_apply /-
@[simp]
theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by
classical simp only [ceil, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, LinearEquiv.map_sum]
#align zspan.repr_ceil_apply Zspan.repr_ceil_apply
+-/
+#print Zspan.floor_eq_self_of_mem /-
@[simp]
theorem floor_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (floor b m : E) = m :=
by
@@ -107,7 +118,9 @@ theorem floor_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (floor
rw [← hz]
exact congr_arg (coe : ℤ → K) (Int.floor_intCast z)
#align zspan.floor_eq_self_of_mem Zspan.floor_eq_self_of_mem
+-/
+#print Zspan.ceil_eq_self_of_mem /-
@[simp]
theorem ceil_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (ceil b m : E) = m :=
by
@@ -118,6 +131,7 @@ theorem ceil_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (ceil b
rw [← hz]
exact congr_arg (coe : ℤ → K) (Int.ceil_intCast z)
#align zspan.ceil_eq_self_of_mem Zspan.ceil_eq_self_of_mem
+-/
#print Zspan.fract /-
/-- The map that sends a vector `E` to the fundamental domain of the lattice,
@@ -127,20 +141,27 @@ def fract (m : E) : E :=
#align zspan.fract Zspan.fract
-/
+#print Zspan.fract_apply /-
theorem fract_apply (m : E) : fract b m = m - floor b m :=
rfl
#align zspan.fract_apply Zspan.fract_apply
+-/
+#print Zspan.repr_fract_apply /-
@[simp]
theorem repr_fract_apply (m : E) (i : ι) : b.repr (fract b m) i = Int.fract (b.repr m i) := by
rw [fract, map_sub, Finsupp.coe_sub, Pi.sub_apply, repr_floor_apply, Int.fract]
#align zspan.repr_fract_apply Zspan.repr_fract_apply
+-/
+#print Zspan.fract_fract /-
@[simp]
theorem fract_fract (m : E) : fract b (fract b m) = fract b m :=
Basis.ext_elem b fun _ => by classical simp only [repr_fract_apply, Int.fract_fract]
#align zspan.fract_fract Zspan.fract_fract
+-/
+#print Zspan.fract_zspan_add /-
@[simp]
theorem fract_zspan_add (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
fract b (v + m) = fract b m := by
@@ -151,25 +172,33 @@ theorem fract_zspan_add (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
rw [map_add, Finsupp.coe_add, Pi.add_apply, add_tsub_cancel_right, ←
eq_intCast (algebraMap ℤ K) _, Basis.restrictScalars_repr_apply, coe_mk]
#align zspan.fract_zspan_add Zspan.fract_zspan_add
+-/
+#print Zspan.fract_add_zspan /-
@[simp]
theorem fract_add_zspan (m : E) {v : E} (h : v ∈ span ℤ (Set.range b)) :
fract b (m + v) = fract b m := by rw [add_comm, fract_zspan_add b m h]
#align zspan.fract_add_zspan Zspan.fract_add_zspan
+-/
variable {b}
+#print Zspan.fract_eq_self /-
theorem fract_eq_self {x : E} : fract b x = x ↔ x ∈ fundamentalDomain b := by
classical simp only [Basis.ext_elem_iff b, repr_fract_apply, Int.fract_eq_self,
mem_fundamental_domain, Set.mem_Ico]
#align zspan.fract_eq_self Zspan.fract_eq_self
+-/
variable (b)
+#print Zspan.fract_mem_fundamentalDomain /-
theorem fract_mem_fundamentalDomain (x : E) : fract b x ∈ fundamentalDomain b :=
fract_eq_self.mp (fract_fract b _)
#align zspan.fract_mem_fundamental_domain Zspan.fract_mem_fundamentalDomain
+-/
+#print Zspan.fract_eq_fract /-
theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ (Set.range b) := by
classical
rw [eq_comm, Basis.ext_elem_iff b]
@@ -177,7 +206,9 @@ theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ
sub_eq_neg_add, map_add, LinearEquiv.map_neg, Finsupp.coe_add, Finsupp.coe_neg, Pi.add_apply,
Pi.neg_apply, ← eq_intCast (algebraMap ℤ K) _, Set.mem_range]
#align zspan.fract_eq_fract Zspan.fract_eq_fract
+-/
+#print Zspan.norm_fract_le /-
theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b i‖ := by
classical
calc
@@ -195,15 +226,18 @@ theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b
rw [abs_one, Int.abs_fract]
exact le_of_lt (Int.fract_lt_one _)
#align zspan.norm_fract_le Zspan.norm_fract_le
+-/
section Unique
variable [Unique ι]
+#print Zspan.coe_floor_self /-
@[simp]
theorem coe_floor_self (k : K) : (floor (Basis.singleton ι K) k : K) = ⌊k⌋ :=
Basis.ext_elem _ fun _ => by rw [repr_floor_apply, Basis.singleton_repr, Basis.singleton_repr]
#align zspan.coe_floor_self Zspan.coe_floor_self
+-/
#print Zspan.coe_fract_self /-
@[simp]
@@ -216,6 +250,7 @@ end Unique
end Fintype
+#print Zspan.fundamentalDomain_bounded /-
theorem fundamentalDomain_bounded [Finite ι] [HasSolidNorm K] :
Metric.Bounded (fundamentalDomain b) :=
by
@@ -227,14 +262,18 @@ theorem fundamentalDomain_bounded [Finite ι] [HasSolidNorm K] :
refine' (add_le_add (norm_fract_le b x) (norm_fract_le b y)).trans _
rw [← two_mul]
#align zspan.fundamental_domain_bounded Zspan.fundamentalDomain_bounded
+-/
+#print Zspan.vadd_mem_fundamentalDomain /-
theorem vadd_mem_fundamentalDomain [Fintype ι] (y : span ℤ (Set.range b)) (x : E) :
y +ᵥ x ∈ fundamentalDomain b ↔ y = -floor b x := by
rw [Subtype.ext_iff, ← add_right_inj x, AddSubgroupClass.coe_neg, ← sub_eq_add_neg, ← fract_apply,
← fract_zspan_add b _ (Subtype.mem y), add_comm, ← vadd_eq_add, ← vadd_def, eq_comm, ←
fract_eq_self]
#align zspan.vadd_mem_fundamental_domain Zspan.vadd_mem_fundamentalDomain
+-/
+#print Zspan.exist_unique_vadd_mem_fundamentalDomain /-
theorem exist_unique_vadd_mem_fundamentalDomain [Finite ι] (x : E) :
∃! v : span ℤ (Set.range b), v +ᵥ x ∈ fundamentalDomain b :=
by
@@ -243,6 +282,7 @@ theorem exist_unique_vadd_mem_fundamentalDomain [Finite ι] (x : E) :
· exact (vadd_mem_fundamental_domain b (-floor b x) x).mpr rfl
· exact (vadd_mem_fundamental_domain b y x).mp h
#align zspan.exist_unique_vadd_mem_fundamental_domain Zspan.exist_unique_vadd_mem_fundamentalDomain
+-/
end NormedLatticeField
@@ -252,6 +292,7 @@ variable [NormedAddCommGroup E] [NormedSpace ℝ E]
variable (b : Basis ι ℝ E)
+#print Zspan.fundamentalDomain_measurableSet /-
@[measurability]
theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpace E] [Finite ι] :
MeasurableSet (fundamentalDomain b) :=
@@ -267,7 +308,9 @@ theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpac
LinearEquiv.coe_toLinearMap, Set.mem_preimage, Function.comp_apply, Set.mem_univ_pi,
Finsupp.linearEquivFunOnFinite_apply]
#align zspan.fundamental_domain_measurable_set Zspan.fundamentalDomain_measurableSet
+-/
+#print Zspan.isAddFundamentalDomain /-
/-- For a ℤ-lattice `submodule.span ℤ (set.range b)`, proves that the set defined
by `zspan.fundamental_domain` is a fundamental domain. -/
protected theorem isAddFundamentalDomain [Finite ι] [MeasurableSpace E] [OpensMeasurableSpace E]
@@ -279,6 +322,7 @@ protected theorem isAddFundamentalDomain [Finite ι] [MeasurableSpace E] [OpensM
is_add_fundamental_domain.mk' (null_measurable_set (fundamental_domain_measurable_set b))
fun x => exist_unique_vadd_mem_fundamental_domain b x
#align zspan.is_add_fundamental_domain Zspan.isAddFundamentalDomain
+-/
end Real
mathlib commit https://github.com/leanprover-community/mathlib/commit/ccdbfb6e5614667af5aa3ab2d50885e0ef44a46f
@@ -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 algebra.module.zlattice
-! leanprover-community/mathlib commit a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
+! leanprover-community/mathlib commit 660b3a2db3522fa0db036e569dc995a615c4c848
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -13,6 +13,9 @@ import Mathbin.MeasureTheory.Group.FundamentalDomain
/-!
# ℤ-lattices
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
Let `E` be a finite dimensional vector space over a `normed_linear_ordered_field` `K` with a solid
norm and that is also a `floor_ring`, e.g. `ℚ` or `ℝ`. A (full) ℤ-lattice `L` of `E` is a discrete
subgroup of `E` such that `L` spans `E` over `K`.
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -48,11 +48,13 @@ variable [NormedAddCommGroup E] [NormedSpace K E]
variable (b : Basis ι K E)
+#print Zspan.fundamentalDomain /-
/-- The fundamental domain of the ℤ-lattice spanned by `b`. See `zspan.is_add_fundamental_domain`
for the proof that it is the fundamental domain. -/
def fundamentalDomain : Set E :=
{m | ∀ i, b.repr m i ∈ Set.Ico (0 : K) 1}
#align zspan.fundamental_domain Zspan.fundamentalDomain
+-/
@[simp]
theorem mem_fundamentalDomain {m : E} :
@@ -114,11 +116,13 @@ theorem ceil_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (ceil b
exact congr_arg (coe : ℤ → K) (Int.ceil_intCast z)
#align zspan.ceil_eq_self_of_mem Zspan.ceil_eq_self_of_mem
+#print Zspan.fract /-
/-- The map that sends a vector `E` to the fundamental domain of the lattice,
see `zspan.fract_mem_fundamental_domain`. -/
def fract (m : E) : E :=
m - floor b m
#align zspan.fract Zspan.fract
+-/
theorem fract_apply (m : E) : fract b m = m - floor b m :=
rfl
@@ -198,10 +202,12 @@ theorem coe_floor_self (k : K) : (floor (Basis.singleton ι K) k : K) = ⌊k⌋
Basis.ext_elem _ fun _ => by rw [repr_floor_apply, Basis.singleton_repr, Basis.singleton_repr]
#align zspan.coe_floor_self Zspan.coe_floor_self
+#print Zspan.coe_fract_self /-
@[simp]
theorem coe_fract_self (k : K) : (fract (Basis.singleton ι K) k : K) = Int.fract k :=
Basis.ext_elem _ fun _ => by rw [repr_fract_apply, Basis.singleton_repr, Basis.singleton_repr]
#align zspan.coe_fract_self Zspan.coe_fract_self
+-/
end Unique
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -518,8 +518,8 @@ theorem Zlattice.rank [hs : IsZlattice K L] : finrank ℤ L = finrank K E := by
have h_card : Fintype.card (Module.Free.ChooseBasisIndex ℤ L) =
(Set.range b).toFinset.card := by
rw [Set.toFinset_range, Finset.univ.card_image_of_injective]
- rfl
- exact Subtype.coe_injective.comp (Basis.injective _)
+ · rfl
+ · exact Subtype.coe_injective.comp (Basis.injective _)
rw [finrank_eq_card_chooseBasisIndex]
-- We prove that `finrank ℤ L ≤ finrank K E` and `finrank K E ≤ finrank ℤ L`
refine le_antisymm ?_ ?_
These are redundant with _root_.{map_neg,map_sub}
.
@@ -145,7 +145,7 @@ theorem fract_apply (m : E) : fract b m = m - floor b m := rfl
@[simp]
theorem repr_fract_apply (m : E) (i : ι) : b.repr (fract b m) i = Int.fract (b.repr m i) := by
- rw [fract, LinearEquiv.map_sub, Finsupp.coe_sub, Pi.sub_apply, repr_floor_apply, Int.fract]
+ rw [fract, map_sub, Finsupp.coe_sub, Pi.sub_apply, repr_floor_apply, Int.fract]
#align zspan.repr_fract_apply Zspan.repr_fract_apply
@[simp]
@@ -195,7 +195,7 @@ theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ
classical
rw [eq_comm, Basis.ext_elem_iff b]
simp_rw [repr_fract_apply, Int.fract_eq_fract, eq_comm, Basis.mem_span_iff_repr_mem,
- sub_eq_neg_add, map_add, LinearEquiv.map_neg, Finsupp.coe_add, Finsupp.coe_neg, Pi.add_apply,
+ sub_eq_neg_add, map_add, map_neg, Finsupp.coe_add, Finsupp.coe_neg, Pi.add_apply,
Pi.neg_apply, ← eq_intCast (algebraMap ℤ K) _, Set.mem_range]
#align zspan.fract_eq_fract Zspan.fract_eq_fract
ZLattice
(#11327)
This PR defines the covolume of a Zlattice
as the (finite) volume of any of its fundamental domain and proves some results about it, mainly: it's nonzero, it does not depend of the choice of the fundamental domain and it is equal to the absolute value of the determinant of any basis of the lattice.
This PR also creates a directory Zlattice
(with the original file becoming Zlattice/Basic.lean
) and a new file Zlattice/Covolume.lean
.
Co-authored-by: Xavier Roblot <roblot@Algorithmi.local> Co-authored-by: Xavier Roblot <roblot@math.univ-lyon1.fr>
@@ -391,7 +391,7 @@ theorem fundamentalDomain_ae_parallelepiped [Fintype ι] [MeasurableSpace E] (μ
rw [← b.sum_repr x, ← Finset.sum_erase_add _ _ (Finset.mem_univ i), this, one_smul, ← vadd_eq_add]
refine Set.mem_iUnion.mpr ⟨i, AffineSubspace.vadd_mem_mk' _
(sum_smul_mem _ _ (fun i hi ↦ Submodule.subset_span ?_))⟩
- exact ⟨i, ⟨Set.mem_diff_singleton.mpr ⟨trivial, Finset.ne_of_mem_erase hi⟩, rfl⟩⟩
+ exact ⟨i, Set.mem_diff_singleton.mpr ⟨trivial, Finset.ne_of_mem_erase hi⟩, rfl⟩
end Real
@@ -486,7 +486,7 @@ theorem Zlattice.module_free [IsZlattice K L] : Module.Free ℤ L := by
exact noZeroSMulDivisors _
infer_instance
-instance instModuleFree__of_discrete_addSubgroup {E : Type*} [NormedAddCommGroup E]
+instance instModuleFree_of_discrete_addSubgroup {E : Type*} [NormedAddCommGroup E]
[NormedSpace ℝ E] [FiniteDimensional ℝ E] (L : AddSubgroup E) [DiscreteTopology L] :
Module.Free ℤ L := by
have : Module ℚ E := Module.compHom E (algebraMap ℚ ℝ)
@@ -618,4 +618,18 @@ theorem Basis.ofZlatticeBasis_span :
rw [Submodule.map_span]
_ = L := by simp [b.span_eq]
+theorem Zlattice.isAddFundamentalDomain {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
+ [FiniteDimensional ℝ E] {L : AddSubgroup E} [DiscreteTopology L] [IsZlattice ℝ L] [Finite ι]
+ (b : Basis ι ℤ L) [MeasurableSpace E] [OpensMeasurableSpace E] (μ : MeasureTheory.Measure E) :
+ MeasureTheory.IsAddFundamentalDomain L (Zspan.fundamentalDomain (b.ofZlatticeBasis ℝ)) μ := by
+ convert Zspan.isAddFundamentalDomain (b.ofZlatticeBasis ℝ) μ
+ all_goals exact (b.ofZlatticeBasis_span ℝ).symm
+
+instance instCountable_of_discrete_addSubgroup {E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
+ [FiniteDimensional ℝ E] (L : AddSubgroup E) [DiscreteTopology L] [IsZlattice ℝ L] :
+ Countable L := by
+ rw [← (Module.Free.chooseBasis ℤ L).ofZlatticeBasis_span ℝ]
+ change Countable (span ℤ (Set.range (Basis.ofZlatticeBasis ℝ L _)))
+ infer_instance
+
end Zlattice
These are changes from #11997, the latest adaptation PR for nightly-2024-04-07, which can be made directly on master.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>
@@ -568,7 +568,7 @@ theorem Zlattice.rank [hs : IsZlattice K L] : finrank ℤ L = finrank K E := by
obtain ⟨n, -, m, -, h_neq, h_eq⟩ := Set.Infinite.exists_ne_map_eq_of_mapsTo
Set.infinite_univ h_mapsto h_finite
have h_nz : (-n + m : ℚ) ≠ 0 := by
- rwa [Ne.def, add_eq_zero_iff_eq_neg.not, neg_inj, Rat.coe_int_inj, ← Ne.def]
+ rwa [Ne, add_eq_zero_iff_eq_neg.not, neg_inj, Rat.coe_int_inj, ← Ne]
apply (smul_mem_iff _ h_nz).mp
refine span_subset_span ℤ ℚ _ ?_
rwa [add_smul, neg_smul, SetLike.mem_coe, ← Zspan.fract_eq_fract, ← zsmul_eq_smul_cast ℚ,
@@ -204,7 +204,7 @@ theorem norm_fract_le [HasSolidNorm K] (m : E) : ‖fract b m‖ ≤ ∑ i, ‖b
calc
‖fract b m‖ = ‖∑ i, b.repr (fract b m) i • b i‖ := by rw [b.sum_repr]
_ = ‖∑ i, Int.fract (b.repr m i) • b i‖ := by simp_rw [repr_fract_apply]
- _ ≤ ∑ i, ‖Int.fract (b.repr m i) • b i‖ := (norm_sum_le _ _)
+ _ ≤ ∑ i, ‖Int.fract (b.repr m i) • b i‖ := norm_sum_le _ _
_ = ∑ i, ‖Int.fract (b.repr m i)‖ * ‖b i‖ := by simp_rw [norm_smul]
_ ≤ ∑ i, ‖b i‖ := Finset.sum_le_sum fun i _ => ?_
suffices ‖Int.fract ((b.repr m) i)‖ ≤ 1 by
@@ -549,7 +549,7 @@ theorem Zlattice.rank [hs : IsZlattice K L] : finrank ℤ L = finrank K E := by
-- We prove finally that `e ∪ {v}` is not ℤ-linear independent or, equivalently,
-- not ℚ-linear independent by showing that `v ∈ span ℚ e`.
rw [LinearIndependent.iff_fractionRing ℤ ℚ,
- (linearIndependent_insert (Set.not_mem_of_mem_diff hv)), not_and, not_not]
+ linearIndependent_insert (Set.not_mem_of_mem_diff hv), not_and, not_not]
intro _
-- But that follows from the fact that there exist `n, m : ℕ`, `n ≠ m`
-- such that `(n - m) • v ∈ span ℤ e` which is true since `n ↦ Zspan.fract e (n • v)`
Zspan.fundamentalDomain_ae_parallelepiped
(#11321)
Prove that the fundamental domain of a ℤ
-lattice is almost equal to the corresponding parallelepiped. This is useful because many results in measure theory use the parallelepiped associated to a basis.
Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>
@@ -302,6 +302,11 @@ theorem discreteTopology_pi_basisFun [Finite ι] :
variable [NormedAddCommGroup E] [NormedSpace ℝ E] (b : Basis ι ℝ E)
+theorem fundamentalDomain_subset_parallelepiped [Fintype ι] :
+ fundamentalDomain b ⊆ parallelepiped b := by
+ rw [fundamentalDomain, parallelepiped_basis_eq, Set.setOf_subset_setOf]
+ exact fun _ h i ↦ Set.Ico_subset_Icc_self (h i)
+
instance [Finite ι] : DiscreteTopology (span ℤ (Set.range b)) := by
have h : Set.MapsTo b.equivFun (span ℤ (Set.range b)) (span ℤ (Set.range (Pi.basisFun ℝ ι))) := by
intro _ hx
@@ -364,6 +369,30 @@ theorem volume_fundamentalDomain [Fintype ι] [DecidableEq ι] (b : Basis ι ℝ
mul_one, ← Matrix.det_transpose]
rfl
+theorem fundamentalDomain_ae_parallelepiped [Fintype ι] [MeasurableSpace E] (μ : Measure E)
+ [BorelSpace E] [Measure.IsAddHaarMeasure μ] :
+ fundamentalDomain b =ᵐ[μ] parallelepiped b := by
+ classical
+ have : FiniteDimensional ℝ E := FiniteDimensional.of_fintype_basis b
+ rw [← measure_symmDiff_eq_zero_iff, symmDiff_of_le (fundamentalDomain_subset_parallelepiped b)]
+ suffices (parallelepiped b \ fundamentalDomain b) ⊆ ⋃ i,
+ AffineSubspace.mk' (b i) (span ℝ (b '' (Set.univ \ {i}))) by
+ refine measure_mono_null this
+ (measure_iUnion_null_iff.mpr fun i ↦ Measure.addHaar_affineSubspace μ _ ?_)
+ refine (ne_of_mem_of_not_mem' (AffineSubspace.mem_top _ _ 0)
+ (AffineSubspace.mem_mk'_iff_vsub_mem.not.mpr ?_)).symm
+ simp_rw [vsub_eq_sub, zero_sub, neg_mem_iff]
+ exact linearIndependent_iff_not_mem_span.mp b.linearIndependent i
+ intro x hx
+ simp_rw [parallelepiped_basis_eq, Set.mem_Icc, Set.mem_diff, Set.mem_setOf_eq,
+ mem_fundamentalDomain, Set.mem_Ico, not_forall, not_and, not_lt] at hx
+ obtain ⟨i, hi⟩ := hx.2
+ have : b.repr x i = 1 := le_antisymm (hx.1 i).2 (hi (hx.1 i).1)
+ rw [← b.sum_repr x, ← Finset.sum_erase_add _ _ (Finset.mem_univ i), this, one_smul, ← vadd_eq_add]
+ refine Set.mem_iUnion.mpr ⟨i, AffineSubspace.vadd_mem_mk' _
+ (sum_smul_mem _ _ (fun i hi ↦ Submodule.subset_span ?_))⟩
+ exact ⟨i, ⟨Set.mem_diff_singleton.mpr ⟨trivial, Finset.ne_of_mem_erase hi⟩, rfl⟩⟩
+
end Real
end Zspan
@@ -310,9 +310,8 @@ instance [Finite ι] : DiscreteTopology (span ℤ (Set.range b)) := by
· exact discreteTopology_pi_basisFun
· refine Subtype.map_injective _ (Basis.equivFun b).injective
-instance [Fintype ι] : DiscreteTopology (span ℤ (Set.range b)).toAddSubgroup := by
- change DiscreteTopology (span ℤ (Set.range b))
- infer_instance
+instance [Finite ι] : DiscreteTopology (span ℤ (Set.range b)).toAddSubgroup :=
+ inferInstanceAs <| DiscreteTopology (span ℤ (Set.range b))
@[measurability]
theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpace E] [Finite ι] :
@@ -382,7 +381,7 @@ class IsZlattice (K : Type*) [NormedField K] {E : Type*} [NormedAddCommGroup E]
span_top : span K (L : Set E) = ⊤
theorem _root_.Zspan.isZlattice {E ι : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
- [Fintype ι] (b : Basis ι ℝ E) :
+ [Finite ι] (b : Basis ι ℝ E) :
IsZlattice ℝ (span ℤ (Set.range b)).toAddSubgroup where
span_top := Zspan.span_top b
Zlattice.basis
(#11323)
For a ℤ
-lattice L
of E
, defined as a discrete subgroup that spans the whole space E
over K
, proves that any ℤ
-basis of L
is also a K
-basis of E
. This provides the link between the two points of view on lattices in this file.
@@ -550,4 +550,44 @@ theorem Zlattice.rank [hs : IsZlattice K L] : finrank ℤ L = finrank K E := by
rw [← topEquiv.finrank_eq, ← h_spanE]
convert finrank_span_le_card (R := K) (Set.range b)
+open Module
+
+variable {ι : Type*} [hs : IsZlattice K L] (b : Basis ι ℤ L)
+/-- Any `ℤ`-basis of `L` is also a `K`-basis of `E`. -/
+def Basis.ofZlatticeBasis :
+ Basis ι K E := by
+ have : Finite ℤ L := Zlattice.module_finite K L
+ have : Free ℤ L := Zlattice.module_free K L
+ let e := Basis.indexEquiv (Free.chooseBasis ℤ L) b
+ have : Fintype ι := Fintype.ofEquiv _ e
+ refine basisOfTopLeSpanOfCardEqFinrank (L.subtype.toIntLinearMap ∘ b) ?_ ?_
+ · rw [← span_span_of_tower ℤ, Set.range_comp, ← map_span, Basis.span_eq, Submodule.map_top,
+ top_le_iff, AddMonoidHom.coe_toIntLinearMap_range, AddSubgroup.subtype_range,
+ AddSubgroup.coe_toIntSubmodule, hs.span_top]
+ · rw [← Fintype.card_congr e, ← finrank_eq_card_chooseBasisIndex, Zlattice.rank K L]
+
+@[simp]
+theorem Basis.ofZlatticeBasis_apply (i : ι) :
+ b.ofZlatticeBasis K L i = b i := by simp [Basis.ofZlatticeBasis]
+
+@[simp]
+theorem Basis.ofZlatticeBasis_repr_apply (x : L) (i : ι) :
+ (b.ofZlatticeBasis K L).repr x i = b.repr x i := by
+ suffices ((b.ofZlatticeBasis K L).repr.toLinearMap.restrictScalars ℤ) ∘ₗ L.subtype.toIntLinearMap
+ = Finsupp.mapRange.linearMap (Algebra.linearMap ℤ K) ∘ₗ b.repr.toLinearMap by
+ exact DFunLike.congr_fun (LinearMap.congr_fun this x) i
+ refine Basis.ext b fun i ↦ ?_
+ simp_rw [LinearMap.coe_comp, Function.comp_apply, LinearMap.coe_restrictScalars,
+ LinearEquiv.coe_coe, AddMonoidHom.coe_toIntLinearMap, AddSubgroup.coeSubtype,
+ ← b.ofZlatticeBasis_apply K, repr_self, Finsupp.mapRange.linearMap_apply,
+ Finsupp.mapRange_single, Algebra.linearMap_apply, map_one]
+
+theorem Basis.ofZlatticeBasis_span :
+ (span ℤ (Set.range (b.ofZlatticeBasis K))).toAddSubgroup = L := by
+ calc (span ℤ (Set.range (b.ofZlatticeBasis K))).toAddSubgroup
+ _ = (span ℤ (L.subtype.toIntLinearMap '' (Set.range b))).toAddSubgroup := by congr; ext; simp
+ _ = (map L.subtype.toIntLinearMap (span ℤ (Set.range b))).toAddSubgroup := by
+ rw [Submodule.map_span]
+ _ = L := by simp [b.span_eq]
+
end Zlattice
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)
@@ -50,9 +50,7 @@ variable {E ι : Type*}
section NormedLatticeField
variable {K : Type*} [NormedLinearOrderedField K]
-
variable [NormedAddCommGroup E] [NormedSpace K E]
-
variable (b : Basis ι K E)
theorem span_top : span K (span ℤ (Set.range b) : Set E) = ⊤ := by simp [span_span_of_tower]
@@ -55,6 +55,8 @@ variable [NormedAddCommGroup E] [NormedSpace K E]
variable (b : Basis ι K E)
+theorem span_top : span K (span ℤ (Set.range b) : Set E) = ⊤ := by simp [span_span_of_tower]
+
/-- The fundamental domain of the ℤ-lattice spanned by `b`. See `Zspan.isAddFundamentalDomain`
for the proof that it is a fundamental domain. -/
def fundamentalDomain : Set E := {m | ∀ i, b.repr m i ∈ Set.Ico (0 : K) 1}
@@ -310,6 +312,10 @@ instance [Finite ι] : DiscreteTopology (span ℤ (Set.range b)) := by
· exact discreteTopology_pi_basisFun
· refine Subtype.map_injective _ (Basis.equivFun b).injective
+instance [Fintype ι] : DiscreteTopology (span ℤ (Set.range b)).toAddSubgroup := by
+ change DiscreteTopology (span ℤ (Set.range b))
+ infer_instance
+
@[measurability]
theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpace E] [Finite ι] :
MeasurableSet (fundamentalDomain b) := by
@@ -367,14 +373,26 @@ end Zspan
section Zlattice
-open Submodule
+open Submodule FiniteDimensional
+
+-- TODO: generalize this class to other rings than `ℤ`
+/-- An `L : Addsubgroup E` where `E` is a vector space over a normed field `K` is a `ℤ`-lattice if
+it is discrete and spans `E` over `K`. -/
+class IsZlattice (K : Type*) [NormedField K] {E : Type*} [NormedAddCommGroup E] [NormedSpace K E]
+ (L : AddSubgroup E) [DiscreteTopology L] : Prop where
+ /-- `L` spans the full space `E` over `K`. -/
+ span_top : span K (L : Set E) = ⊤
+
+theorem _root_.Zspan.isZlattice {E ι : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E]
+ [Fintype ι] (b : Basis ι ℝ E) :
+ IsZlattice ℝ (span ℤ (Set.range b)).toAddSubgroup where
+ span_top := Zspan.span_top b
variable (K : Type*) [NormedLinearOrderedField K] [HasSolidNorm K] [FloorRing K]
variable {E : Type*} [NormedAddCommGroup E] [NormedSpace K E] [FiniteDimensional K E]
-variable [ProperSpace E] {L : AddSubgroup E} [DiscreteTopology L]
-variable (hs : span K (L : Set E) = ⊤)
+variable [ProperSpace E] (L : AddSubgroup E) [DiscreteTopology L]
-theorem Zlattice.FG : AddSubgroup.FG L := by
+theorem Zlattice.FG [hs : IsZlattice K L] : AddSubgroup.FG L := by
suffices (AddSubgroup.toIntSubmodule L).FG by exact (fg_iff_add_subgroup_fg _).mp this
obtain ⟨s, ⟨h_incl, ⟨h_span, h_lind⟩⟩⟩ := exists_linearIndependent K (L : Set E)
-- Let `s` be a maximal `K`-linear independent family of elements of `L`. We show that
@@ -386,7 +404,7 @@ theorem Zlattice.FG : AddSubgroup.FG L := by
-- so there are finitely many since `fundamentalDomain b` is bounded.
refine fg_def.mpr ⟨map (span ℤ s).mkQ (AddSubgroup.toIntSubmodule L), ?_, span_eq _⟩
let b := Basis.mk h_lind (by
- rw [← hs, ← h_span]
+ rw [← hs.span_top, ← h_span]
exact span_mono (by simp only [Subtype.range_coe_subtype, Set.setOf_mem_eq, subset_rfl]))
rw [show span ℤ s = span ℤ (Set.range b) by simp [b, Basis.coe_mk, Subtype.range_coe_subtype]]
have : Fintype s := h_lind.setFinite.fintype
@@ -409,11 +427,32 @@ theorem Zlattice.FG : AddSubgroup.FG L := by
rw [ker_mkQ, inf_of_le_right (span_le.mpr h_incl)]
exact fg_span (LinearIndependent.setFinite h_lind)
-theorem Zlattice.module_finite : Module.Finite ℤ L :=
- Module.Finite.iff_addGroup_fg.mpr ((AddGroup.fg_iff_addSubgroup_fg L).mpr (FG K hs))
-
-theorem Zlattice.module_free : Module.Free ℤ L := by
- have : Module.Finite ℤ L := module_finite K hs
+theorem Zlattice.module_finite [IsZlattice K L] : Module.Finite ℤ L :=
+ Module.Finite.iff_addGroup_fg.mpr ((AddGroup.fg_iff_addSubgroup_fg L).mpr (FG K L))
+
+instance instModuleFinite_of_discrete_addSubgroup {E : Type*} [NormedAddCommGroup E]
+ [NormedSpace ℝ E] [FiniteDimensional ℝ E] (L : AddSubgroup E) [DiscreteTopology L] :
+ Module.Finite ℤ L := by
+ let f := (span ℝ (L : Set E)).subtype
+ let L₀ := (AddSubgroup.toIntSubmodule L).comap (f.restrictScalars ℤ)
+ have h_img : f '' L₀ = L := by
+ rw [← LinearMap.coe_restrictScalars ℤ f, ← Submodule.map_coe (f.restrictScalars ℤ),
+ Submodule.map_comap_eq_self, AddSubgroup.coe_toIntSubmodule]
+ exact fun x hx ↦ LinearMap.mem_range.mpr ⟨⟨x, Submodule.subset_span hx⟩, rfl⟩
+ suffices Module.Finite ℤ L₀ by
+ have : L₀.map (f.restrictScalars ℤ) = (AddSubgroup.toIntSubmodule L) :=
+ SetLike.ext'_iff.mpr h_img
+ convert this ▸ Module.Finite.map L₀ (f.restrictScalars ℤ)
+ have : DiscreteTopology L₀.toAddSubgroup := by
+ refine DiscreteTopology.preimage_of_continuous_injective (L : Set E) ?_ (injective_subtype _)
+ exact LinearMap.continuous_of_finiteDimensional f
+ have : IsZlattice ℝ L₀.toAddSubgroup := ⟨by
+ rw [← (Submodule.map_injective_of_injective (injective_subtype _)).eq_iff, Submodule.map_span,
+ Submodule.map_top, range_subtype, coe_toAddSubgroup, h_img]⟩
+ exact Zlattice.module_finite ℝ L₀.toAddSubgroup
+
+theorem Zlattice.module_free [IsZlattice K L] : Module.Free ℤ L := by
+ have : Module.Finite ℤ L := module_finite K L
have : Module ℚ E := Module.compHom E (algebraMap ℚ K)
have : NoZeroSMulDivisors ℤ E := RatModule.noZeroSMulDivisors
have : NoZeroSMulDivisors ℤ L := by
@@ -421,12 +460,20 @@ theorem Zlattice.module_free : Module.Free ℤ L := by
exact noZeroSMulDivisors _
infer_instance
-open FiniteDimensional
+instance instModuleFree__of_discrete_addSubgroup {E : Type*} [NormedAddCommGroup E]
+ [NormedSpace ℝ E] [FiniteDimensional ℝ E] (L : AddSubgroup E) [DiscreteTopology L] :
+ Module.Free ℤ L := by
+ have : Module ℚ E := Module.compHom E (algebraMap ℚ ℝ)
+ have : NoZeroSMulDivisors ℤ E := RatModule.noZeroSMulDivisors
+ have : NoZeroSMulDivisors ℤ L := by
+ change NoZeroSMulDivisors ℤ (AddSubgroup.toIntSubmodule L)
+ exact noZeroSMulDivisors _
+ infer_instance
-theorem Zlattice.rank : finrank ℤ L = finrank K E := by
+theorem Zlattice.rank [hs : IsZlattice K L] : finrank ℤ L = finrank K E := by
classical
- have : Module.Finite ℤ L := module_finite K hs
- have : Module.Free ℤ L := module_free K hs
+ have : Module.Finite ℤ L := module_finite K L
+ have : Module.Free ℤ L := module_free K L
have : Module ℚ E := Module.compHom E (algebraMap ℚ K)
let b₀ := Module.Free.chooseBasis ℤ L
-- Let `b` be a `ℤ`-basis of `L` formed of vectors of `E`
@@ -439,7 +486,9 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
· rw [map_span, Set.range_comp]
rfl
· exact (map_subtype_top _).symm
- have h_spanE : span K (Set.range b) = ⊤ := by rwa [← span_span_of_tower (R := ℤ), h_spanL]
+ have h_spanE : span K (Set.range b) = ⊤ := by
+ rw [← span_span_of_tower (R := ℤ), h_spanL]
+ exact hs.span_top
have h_card : Fintype.card (Module.Free.ChooseBasisIndex ℤ L) =
(Set.range b).toFinset.card := by
rw [Set.toFinset_range, Finset.univ.card_image_of_injective]
Also, in some cases drop unneeded Fintype
arguments.
@@ -288,8 +288,9 @@ end NormedLatticeField
section Real
-theorem discreteTopology_pi_basisFun [Fintype ι] :
+theorem discreteTopology_pi_basisFun [Finite ι] :
DiscreteTopology (span ℤ (Set.range (Pi.basisFun ℝ ι))) := by
+ cases nonempty_fintype ι
refine discreteTopology_iff_isOpen_singleton_zero.mpr ⟨Metric.ball 0 1, Metric.isOpen_ball, ?_⟩
ext x
rw [Set.mem_preimage, mem_ball_zero_iff, pi_norm_lt_iff zero_lt_one, Set.mem_singleton_iff]
@@ -301,7 +302,7 @@ theorem discreteTopology_pi_basisFun [Fintype ι] :
variable [NormedAddCommGroup E] [NormedSpace ℝ E] (b : Basis ι ℝ E)
-instance [Fintype ι] : DiscreteTopology (span ℤ (Set.range b)) := by
+instance [Finite ι] : DiscreteTopology (span ℤ (Set.range b)) := by
have h : Set.MapsTo b.equivFun (span ℤ (Set.range b)) (span ℤ (Set.range (Pi.basisFun ℝ ι))) := by
intro _ hx
rwa [SetLike.mem_coe, Basis.mem_span_iff_repr_mem] at hx ⊢
λ
by fun
(#11301)
Per the style guidelines, λ
is disallowed in mathlib.
This is close to exhaustive; I left some tactic code alone when it seemed to me that tactic could be upstreamed soon.
Notes
=>
to ↦
.Mathlib/Order/SupClosed
.λ x,
, which I also replaced.@@ -481,7 +481,7 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
have h_mapsto : Set.MapsTo (fun n : ℤ => Zspan.fract e (n • v)) Set.univ
(Metric.closedBall 0 (∑ i, ‖e i‖) ∩ (L : Set E)) := by
rw [Set.mapsTo_inter, Set.mapsTo_univ_iff, Set.mapsTo_univ_iff]
- refine ⟨fun _ => mem_closedBall_zero_iff.mpr (Zspan.norm_fract_le e _), fun _ => ?_⟩
+ refine ⟨fun _ ↦ mem_closedBall_zero_iff.mpr (Zspan.norm_fract_le e _), fun _ => ?_⟩
· change _ ∈ AddSubgroup.toIntSubmodule L
rw [← h_spanL]
refine sub_mem ?_ ?_
@@ -319,7 +319,7 @@ theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpac
· refine measurableSet_preimage (LinearMap.continuous_of_finiteDimensional _).measurable ?_
exact MeasurableSet.pi Set.countable_univ fun _ _ => measurableSet_Ico
· ext
- simp only [fundamentalDomain, Set.mem_Ico, Set.mem_setOf_eq, LinearEquiv.coe_coe,
+ simp only [D, fundamentalDomain, Set.mem_Ico, Set.mem_setOf_eq, LinearEquiv.coe_coe,
Set.mem_preimage, Basis.equivFun_apply, Set.mem_pi, Set.mem_univ, forall_true_left]
#align zspan.fundamental_domain_measurable_set Zspan.fundamentalDomain_measurableSet
@@ -387,7 +387,7 @@ theorem Zlattice.FG : AddSubgroup.FG L := by
let b := Basis.mk h_lind (by
rw [← hs, ← h_span]
exact span_mono (by simp only [Subtype.range_coe_subtype, Set.setOf_mem_eq, subset_rfl]))
- rw [show span ℤ s = span ℤ (Set.range b) by simp [Basis.coe_mk, Subtype.range_coe_subtype]]
+ rw [show span ℤ s = span ℤ (Set.range b) by simp [b, Basis.coe_mk, Subtype.range_coe_subtype]]
have : Fintype s := h_lind.setFinite.fintype
refine Set.Finite.of_finite_image (f := ((↑) : _ → E) ∘ Zspan.quotientEquiv b) ?_
(Function.Injective.injOn (Subtype.coe_injective.comp (Zspan.quotientEquiv b).injective) _)
@@ -469,7 +469,7 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
suffices ¬ LinearIndependent ℤ (fun x : ↥(insert v (Set.range e)) => (x : E)) by
contrapose! this
refine LinearIndependent.mono ?_ this
- exact Set.insert_subset (Set.mem_of_mem_diff hv) (by simp [ht_inc])
+ exact Set.insert_subset (Set.mem_of_mem_diff hv) (by simp [e, ht_inc])
-- We prove finally that `e ∪ {v}` is not ℤ-linear independent or, equivalently,
-- not ℚ-linear independent by showing that `v ∈ span ℚ e`.
rw [LinearIndependent.iff_fractionRing ℤ ℚ,
@@ -486,7 +486,7 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
rw [← h_spanL]
refine sub_mem ?_ ?_
· exact zsmul_mem (subset_span (Set.diff_subset _ _ hv)) _
- · exact span_mono (by simp [ht_inc]) (coe_mem _)
+ · exact span_mono (by simp [e, ht_inc]) (coe_mem _)
have h_finite : Set.Finite (Metric.closedBall 0 (∑ i, ‖e i‖) ∩ (L : Set E)) :=
Metric.finite_isBounded_inter_isClosed Metric.isBounded_closedBall inferInstance
obtain ⟨n, -, m, -, h_neq, h_eq⟩ := Set.Infinite.exists_ne_map_eq_of_mapsTo
Let N
be an integer. Then there are only finitely many number fields (in some fixed extension of ℚ
) of discriminant bounded in absolute value by N
.
@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Xavier Roblot
-/
import Mathlib.LinearAlgebra.FreeModule.PID
-import Mathlib.LinearAlgebra.FreeModule.Finite.Basic
import Mathlib.MeasureTheory.Group.FundamentalDomain
import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar
import Mathlib.RingTheory.Localization.Module
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.
@@ -343,12 +343,12 @@ theorem measure_fundamentalDomain_ne_zero [Finite ι] [MeasurableSpace E] [Borel
theorem measure_fundamentalDomain [Fintype ι] [DecidableEq ι] [MeasurableSpace E] (μ : Measure E)
[BorelSpace E] [Measure.IsAddHaarMeasure μ] (b₀ : Basis ι ℝ E) :
- μ (fundamentalDomain b) = ENNReal.ofReal |(b₀.toMatrix b).det| * μ (fundamentalDomain b₀) := by
+ μ (fundamentalDomain b) = ENNReal.ofReal |b₀.det b| * μ (fundamentalDomain b₀) := by
have : FiniteDimensional ℝ E := FiniteDimensional.of_fintype_basis b
convert μ.addHaar_preimage_linearEquiv (b.equiv b₀ (Equiv.refl ι)) (fundamentalDomain b₀)
· rw [Set.eq_preimage_iff_image_eq (LinearEquiv.bijective _), map_fundamentalDomain,
Basis.map_equiv, Equiv.refl_symm, Basis.reindex_refl]
- · rw [← LinearMap.det_toMatrix b₀, Basis.equiv_symm, Equiv.refl_symm]
+ · rw [← LinearMap.det_toMatrix b₀, Basis.equiv_symm, Equiv.refl_symm, Basis.det_apply]
congr
ext
simp [Basis.toMatrix_apply, LinearMap.toMatrix_apply, LinearEquiv.coe_coe, Basis.equiv_apply]
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Xavier Roblot
-/
import Mathlib.LinearAlgebra.FreeModule.PID
+import Mathlib.LinearAlgebra.FreeModule.Finite.Basic
import Mathlib.MeasureTheory.Group.FundamentalDomain
import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar
import Mathlib.RingTheory.Localization.Module
@@ -244,7 +244,7 @@ theorem fundamentalDomain_isBounded [Finite ι] [HasSolidNorm K] :
theorem vadd_mem_fundamentalDomain [Fintype ι] (y : span ℤ (Set.range b)) (x : E) :
y +ᵥ x ∈ fundamentalDomain b ↔ y = -floor b x := by
- rw [Subtype.ext_iff, ← add_right_inj x, AddSubgroupClass.coe_neg, ← sub_eq_add_neg, ← fract_apply,
+ rw [Subtype.ext_iff, ← add_right_inj x, NegMemClass.coe_neg, ← sub_eq_add_neg, ← fract_apply,
← fract_zspan_add b _ (Subtype.mem y), add_comm, ← vadd_eq_add, ← vadd_def, eq_comm, ←
fract_eq_self]
#align zspan.vadd_mem_fundamental_domain Zspan.vadd_mem_fundamentalDomain
@@ -464,7 +464,7 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
Finset.sdiff_eq_empty_iff_subset] at h
replace h := Finset.card_le_card h
rwa [not_lt, h_card, ← topEquiv.finrank_eq, ← h_spanE, ← ht_span,
- finrank_span_set_eq_card _ ht_lin]
+ finrank_span_set_eq_card ht_lin]
-- Assume that `e ∪ {v}` is not `ℤ`-linear independent then we get the contradiction
suffices ¬ LinearIndependent ℤ (fun x : ↥(insert v (Set.range e)) => (x : E)) by
contrapose! this
@@ -500,6 +500,6 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
· -- To prove that `finrank K E ≤ finrank ℤ L`, we use the fact `b` generates `E` over `K`
-- and thus `finrank K E ≤ card b = finrank ℤ L`
rw [← topEquiv.finrank_eq, ← h_spanE]
- convert finrank_span_le_card (K := K) (Set.range b)
+ convert finrank_span_le_card (R := K) (Set.range b)
end Zlattice
@@ -418,7 +418,7 @@ theorem Zlattice.module_free : Module.Free ℤ L := by
have : NoZeroSMulDivisors ℤ L := by
change NoZeroSMulDivisors ℤ (AddSubgroup.toIntSubmodule L)
exact noZeroSMulDivisors _
- exact Module.free_of_finite_type_torsion_free'
+ infer_instance
open FiniteDimensional
Finset
lemma names (#8894)
Change a few lemma names that have historically bothered me.
Finset.card_le_of_subset
→ Finset.card_le_card
Multiset.card_le_of_le
→ Multiset.card_le_card
Multiset.card_lt_of_lt
→ Multiset.card_lt_card
Set.ncard_le_of_subset
→ Set.ncard_le_ncard
Finset.image_filter
→ Finset.filter_image
CompleteLattice.finset_sup_compact_of_compact
→ CompleteLattice.isCompactElement_finset_sup
@@ -462,7 +462,7 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
contrapose h
rw [Finset.not_nonempty_iff_eq_empty, Set.toFinset_diff,
Finset.sdiff_eq_empty_iff_subset] at h
- replace h := Finset.card_le_of_subset h
+ replace h := Finset.card_le_card h
rwa [not_lt, h_card, ← topEquiv.finrank_eq, ← h_spanE, ← ht_span,
finrank_span_set_eq_card _ ht_lin]
-- Assume that `e ∪ {v}` is not `ℤ`-linear independent then we get the contradiction
Set.maps_image_to
→ Set.mapsTo_image_iff
;Set.maps_univ_to
→ Set.mapsTo_univ_iff
;Set.maps_range_to
→ Set.mapsTo_range_iff
.In all cases, use implicit arguments instead of explicit arguments.
In the last case, also generalize from Type*
to Sort*
and replace the RHS with its simp
-normal form.
Old lemmas stay there but are now deprecated.
@@ -480,7 +480,7 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
-- takes value into the finite set `fundamentalDomain e ∩ L`
have h_mapsto : Set.MapsTo (fun n : ℤ => Zspan.fract e (n • v)) Set.univ
(Metric.closedBall 0 (∑ i, ‖e i‖) ∩ (L : Set E)) := by
- rw [Set.mapsTo_inter, Set.maps_univ_to, Set.maps_univ_to]
+ rw [Set.mapsTo_inter, Set.mapsTo_univ_iff, Set.mapsTo_univ_iff]
refine ⟨fun _ => mem_closedBall_zero_iff.mpr (Zspan.norm_fract_le e _), fun _ => ?_⟩
· change _ ∈ AddSubgroup.toIntSubmodule L
rw [← h_spanL]
This is just a repackaging of existing lemmas, except that the correct name is already taken by the Set
version, so we fix that too.
From LeanAPAP
@@ -388,7 +388,7 @@ theorem Zlattice.FG : AddSubgroup.FG L := by
rw [← hs, ← h_span]
exact span_mono (by simp only [Subtype.range_coe_subtype, Set.setOf_mem_eq, subset_rfl]))
rw [show span ℤ s = span ℤ (Set.range b) by simp [Basis.coe_mk, Subtype.range_coe_subtype]]
- have : Fintype s := Set.Finite.fintype h_lind.finite
+ have : Fintype s := h_lind.setFinite.fintype
refine Set.Finite.of_finite_image (f := ((↑) : _ → E) ∘ Zspan.quotientEquiv b) ?_
(Function.Injective.injOn (Subtype.coe_injective.comp (Zspan.quotientEquiv b).injective) _)
have : Set.Finite ((Zspan.fundamentalDomain b) ∩ L) :=
@@ -406,7 +406,7 @@ theorem Zlattice.FG : AddSubgroup.FG L := by
exact span_le.mpr h_incl
· -- `span ℤ s` is finitely generated because `s` is finite
rw [ker_mkQ, inf_of_le_right (span_le.mpr h_incl)]
- exact fg_span (LinearIndependent.finite h_lind)
+ exact fg_span (LinearIndependent.setFinite h_lind)
theorem Zlattice.module_finite : Module.Finite ℤ L :=
Module.Finite.iff_addGroup_fg.mpr ((AddGroup.fg_iff_addSubgroup_fg L).mpr (FG K hs))
Add the following
variable [NormedAddCommGroup E] [NormedSpace ℝ E] (b : Basis ι ℝ E)
instance [Fintype ι] : DiscreteTopology (span ℤ (Set.range b))
@@ -288,9 +288,26 @@ end NormedLatticeField
section Real
-variable [NormedAddCommGroup E] [NormedSpace ℝ E]
-
-variable (b : Basis ι ℝ E)
+theorem discreteTopology_pi_basisFun [Fintype ι] :
+ DiscreteTopology (span ℤ (Set.range (Pi.basisFun ℝ ι))) := by
+ refine discreteTopology_iff_isOpen_singleton_zero.mpr ⟨Metric.ball 0 1, Metric.isOpen_ball, ?_⟩
+ ext x
+ rw [Set.mem_preimage, mem_ball_zero_iff, pi_norm_lt_iff zero_lt_one, Set.mem_singleton_iff]
+ simp_rw [← coe_eq_zero, Function.funext_iff, Pi.zero_apply, Real.norm_eq_abs]
+ refine forall_congr' (fun i => ?_)
+ rsuffices ⟨y, hy⟩ : ∃ (y : ℤ), (y : ℝ) = (x : ι → ℝ) i
+ · rw [← hy, ← Int.cast_abs, ← Int.cast_one, Int.cast_lt, Int.abs_lt_one_iff, Int.cast_eq_zero]
+ exact ((Pi.basisFun ℝ ι).mem_span_iff_repr_mem ℤ x).mp (SetLike.coe_mem x) i
+
+variable [NormedAddCommGroup E] [NormedSpace ℝ E] (b : Basis ι ℝ E)
+
+instance [Fintype ι] : DiscreteTopology (span ℤ (Set.range b)) := by
+ have h : Set.MapsTo b.equivFun (span ℤ (Set.range b)) (span ℤ (Set.range (Pi.basisFun ℝ ι))) := by
+ intro _ hx
+ rwa [SetLike.mem_coe, Basis.mem_span_iff_repr_mem] at hx ⊢
+ convert DiscreteTopology.of_continuous_injective ((continuous_equivFun_basis b).restrict h) ?_
+ · exact discreteTopology_pi_basisFun
+ · refine Subtype.map_injective _ (Basis.equivFun b).injective
@[measurability]
theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpace E] [Finite ι] :
@@ -320,7 +320,8 @@ theorem measure_fundamentalDomain_ne_zero [Finite ι] [MeasurableSpace E] [Borel
{μ : Measure E} [Measure.IsAddHaarMeasure μ] :
μ (fundamentalDomain b) ≠ 0 := by
convert (Zspan.isAddFundamentalDomain b μ).measure_ne_zero (NeZero.ne μ)
- exact (by infer_instance : Countable (span ℤ (Set.range b)))
+ simp only [mem_toAddSubgroup]
+ infer_instance
theorem measure_fundamentalDomain [Fintype ι] [DecidableEq ι] [MeasurableSpace E] (μ : Measure E)
[BorelSpace E] [Measure.IsAddHaarMeasure μ] (b₀ : Basis ι ℝ E) :
@@ -5,7 +5,6 @@ Authors: Xavier Roblot
-/
import Mathlib.LinearAlgebra.FreeModule.PID
import Mathlib.MeasureTheory.Group.FundamentalDomain
-import Mathlib.MeasureTheory.Group.Measure
import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar
import Mathlib.RingTheory.Localization.Module
@@ -317,6 +316,12 @@ protected theorem isAddFundamentalDomain [Finite ι] [MeasurableSpace E] [OpensM
fun x => exist_unique_vadd_mem_fundamentalDomain b x
#align zspan.is_add_fundamental_domain Zspan.isAddFundamentalDomain
+theorem measure_fundamentalDomain_ne_zero [Finite ι] [MeasurableSpace E] [BorelSpace E]
+ {μ : Measure E} [Measure.IsAddHaarMeasure μ] :
+ μ (fundamentalDomain b) ≠ 0 := by
+ convert (Zspan.isAddFundamentalDomain b μ).measure_ne_zero (NeZero.ne μ)
+ exact (by infer_instance : Countable (span ℤ (Set.range b)))
+
theorem measure_fundamentalDomain [Fintype ι] [DecidableEq ι] [MeasurableSpace E] (μ : Measure E)
[BorelSpace E] [Measure.IsAddHaarMeasure μ] (b₀ : Basis ι ℝ E) :
μ (fundamentalDomain b) = ENNReal.ofReal |(b₀.toMatrix b).det| * μ (fundamentalDomain b₀) := by
Metric.Bounded
(#7240)
Use Bornology.IsBounded
instead.
@@ -44,7 +44,7 @@ noncomputable section
namespace Zspan
-open MeasureTheory MeasurableSet Submodule
+open MeasureTheory MeasurableSet Submodule Bornology
variable {E ι : Type*}
@@ -235,16 +235,13 @@ end Unique
end Fintype
-theorem fundamentalDomain_bounded [Finite ι] [HasSolidNorm K] :
- Metric.Bounded (fundamentalDomain b) := by
+theorem fundamentalDomain_isBounded [Finite ι] [HasSolidNorm K] :
+ IsBounded (fundamentalDomain b) := by
cases nonempty_fintype ι
- use 2 * ∑ j, ‖b j‖
- intro x hx y hy
- refine le_trans (dist_le_norm_add_norm x y) ?_
- rw [← fract_eq_self.mpr hx, ← fract_eq_self.mpr hy]
- refine (add_le_add (norm_fract_le b x) (norm_fract_le b y)).trans ?_
- rw [← two_mul]
-#align zspan.fundamental_domain_bounded Zspan.fundamentalDomain_bounded
+ refine isBounded_iff_forall_norm_le.2 ⟨∑ j, ‖b j‖, fun x hx ↦ ?_⟩
+ rw [← fract_eq_self.mpr hx]
+ apply norm_fract_le
+#align zspan.fundamental_domain_bounded Zspan.fundamentalDomain_isBounded
theorem vadd_mem_fundamentalDomain [Fintype ι] (y : span ℤ (Set.range b)) (x : E) :
y +ᵥ x ∈ fundamentalDomain b ↔ y = -floor b x := by
@@ -372,7 +369,7 @@ theorem Zlattice.FG : AddSubgroup.FG L := by
refine Set.Finite.of_finite_image (f := ((↑) : _ → E) ∘ Zspan.quotientEquiv b) ?_
(Function.Injective.injOn (Subtype.coe_injective.comp (Zspan.quotientEquiv b).injective) _)
have : Set.Finite ((Zspan.fundamentalDomain b) ∩ L) :=
- Metric.Finite_bounded_inter_isClosed (Zspan.fundamentalDomain_bounded b) inferInstance
+ Metric.finite_isBounded_inter_isClosed (Zspan.fundamentalDomain_isBounded b) inferInstance
refine Set.Finite.subset this ?_
rintro _ ⟨_, ⟨⟨x, ⟨h_mem, rfl⟩⟩, rfl⟩⟩
rw [Function.comp_apply, mkQ_apply, Zspan.quotientEquiv_apply_mk, Zspan.fractRestrict_apply]
@@ -468,7 +465,7 @@ theorem Zlattice.rank : finrank ℤ L = finrank K E := by
· exact zsmul_mem (subset_span (Set.diff_subset _ _ hv)) _
· exact span_mono (by simp [ht_inc]) (coe_mem _)
have h_finite : Set.Finite (Metric.closedBall 0 (∑ i, ‖e i‖) ∩ (L : Set E)) :=
- Metric.Finite_bounded_inter_isClosed Metric.bounded_closedBall inferInstance
+ Metric.finite_isBounded_inter_isClosed Metric.isBounded_closedBall inferInstance
obtain ⟨n, -, m, -, h_neq, h_eq⟩ := Set.Infinite.exists_ne_map_eq_of_mapsTo
Set.infinite_univ h_mapsto h_finite
have h_nz : (-n + m : ℚ) ≠ 0 := by
_root_.map_sum
more consistently (#7189)
Also _root_.map_smul
when in the neighbourhood.
@@ -105,14 +105,14 @@ def ceil (m : E) : span ℤ (Set.range b) := ∑ i, ⌈b.repr m i⌉ • b.restr
theorem repr_floor_apply (m : E) (i : ι) : b.repr (floor b m) i = ⌊b.repr m i⌋ := by
classical simp only [floor, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
- Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, LinearEquiv.map_sum]
+ Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
#align zspan.repr_floor_apply Zspan.repr_floor_apply
@[simp]
theorem repr_ceil_apply (m : E) (i : ι) : b.repr (ceil b m) i = ⌈b.repr m i⌉ := by
classical simp only [ceil, zsmul_eq_smul_cast K, b.repr.map_smul, Finsupp.single_apply,
Finset.sum_apply', Basis.repr_self, Finsupp.smul_single', mul_one, Finset.sum_ite_eq', coe_sum,
- Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, LinearEquiv.map_sum]
+ Finset.mem_univ, if_true, coe_smul_of_tower, Basis.restrictScalars_apply, map_sum]
#align zspan.repr_ceil_apply Zspan.repr_ceil_apply
@[simp]
We prove that the covolume of a $\mathbb{Z}$-lattice of $\mathbb{R}^n$ generated by the basis $b$ is equal to the absolute value of the determinant of the matrix formed by the vectors of $b$, that is
theorem volume_fundamentalDomain [Fintype ι] [DecidableEq ι] (b : Basis ι ℝ (ι → ℝ)) :
volume (fundamentalDomain b) = ENNReal.ofReal |(Matrix.of b).det|
@@ -5,6 +5,8 @@ Authors: Xavier Roblot
-/
import Mathlib.LinearAlgebra.FreeModule.PID
import Mathlib.MeasureTheory.Group.FundamentalDomain
+import Mathlib.MeasureTheory.Group.Measure
+import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar
import Mathlib.RingTheory.Localization.Module
#align_import algebra.module.zlattice from "leanprover-community/mathlib"@"a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3"
@@ -64,6 +66,25 @@ theorem mem_fundamentalDomain {m : E} :
m ∈ fundamentalDomain b ↔ ∀ i, b.repr m i ∈ Set.Ico (0 : K) 1 := Iff.rfl
#align zspan.mem_fundamental_domain Zspan.mem_fundamentalDomain
+theorem map_fundamentalDomain {F : Type*} [NormedAddCommGroup F] [NormedSpace K F] (f : E ≃ₗ[K] F) :
+ f '' (fundamentalDomain b) = fundamentalDomain (b.map f) := by
+ ext x
+ rw [mem_fundamentalDomain, Basis.map_repr, LinearEquiv.trans_apply, ← mem_fundamentalDomain,
+ show f.symm x = f.toEquiv.symm x by rfl, ← Set.mem_image_equiv]
+ rfl
+
+@[simp]
+theorem fundamentalDomain_reindex {ι' : Type*} (e : ι ≃ ι') :
+ fundamentalDomain (b.reindex e) = fundamentalDomain b := by
+ ext
+ simp_rw [mem_fundamentalDomain, Basis.repr_reindex_apply]
+ rw [Equiv.forall_congr' e]
+ simp_rw [implies_true]
+
+lemma fundamentalDomain_pi_basisFun [Fintype ι] :
+ fundamentalDomain (Pi.basisFun ℝ ι) = Set.pi Set.univ fun _ : ι ↦ Set.Ico (0 : ℝ) 1 := by
+ ext; simp
+
variable [FloorRing K]
section Fintype
@@ -278,16 +299,15 @@ variable (b : Basis ι ℝ E)
@[measurability]
theorem fundamentalDomain_measurableSet [MeasurableSpace E] [OpensMeasurableSpace E] [Finite ι] :
MeasurableSet (fundamentalDomain b) := by
+ cases nonempty_fintype ι
haveI : FiniteDimensional ℝ E := FiniteDimensional.of_fintype_basis b
- let f := (Finsupp.linearEquivFunOnFinite ℝ ℝ ι).toLinearMap.comp b.repr.toLinearMap
let D : Set (ι → ℝ) := Set.pi Set.univ fun _ : ι => Set.Ico (0 : ℝ) 1
- rw [(_ : fundamentalDomain b = f ⁻¹' D)]
- · refine measurableSet_preimage (LinearMap.continuous_of_finiteDimensional f).measurable ?_
+ rw [(_ : fundamentalDomain b = b.equivFun.toLinearMap ⁻¹' D)]
+ · refine measurableSet_preimage (LinearMap.continuous_of_finiteDimensional _).measurable ?_
exact MeasurableSet.pi Set.countable_univ fun _ _ => measurableSet_Ico
· ext
- simp only [fundamentalDomain, Set.mem_setOf_eq, LinearMap.coe_comp,
- LinearEquiv.coe_toLinearMap, Set.mem_preimage, Function.comp_apply, Set.mem_univ_pi,
- Finsupp.linearEquivFunOnFinite_apply]
+ simp only [fundamentalDomain, Set.mem_Ico, Set.mem_setOf_eq, LinearEquiv.coe_coe,
+ Set.mem_preimage, Basis.equivFun_apply, Set.mem_pi, Set.mem_univ, forall_true_left]
#align zspan.fundamental_domain_measurable_set Zspan.fundamentalDomain_measurableSet
/-- For a ℤ-lattice `Submodule.span ℤ (Set.range b)`, proves that the set defined
@@ -300,6 +320,26 @@ protected theorem isAddFundamentalDomain [Finite ι] [MeasurableSpace E] [OpensM
fun x => exist_unique_vadd_mem_fundamentalDomain b x
#align zspan.is_add_fundamental_domain Zspan.isAddFundamentalDomain
+theorem measure_fundamentalDomain [Fintype ι] [DecidableEq ι] [MeasurableSpace E] (μ : Measure E)
+ [BorelSpace E] [Measure.IsAddHaarMeasure μ] (b₀ : Basis ι ℝ E) :
+ μ (fundamentalDomain b) = ENNReal.ofReal |(b₀.toMatrix b).det| * μ (fundamentalDomain b₀) := by
+ have : FiniteDimensional ℝ E := FiniteDimensional.of_fintype_basis b
+ convert μ.addHaar_preimage_linearEquiv (b.equiv b₀ (Equiv.refl ι)) (fundamentalDomain b₀)
+ · rw [Set.eq_preimage_iff_image_eq (LinearEquiv.bijective _), map_fundamentalDomain,
+ Basis.map_equiv, Equiv.refl_symm, Basis.reindex_refl]
+ · rw [← LinearMap.det_toMatrix b₀, Basis.equiv_symm, Equiv.refl_symm]
+ congr
+ ext
+ simp [Basis.toMatrix_apply, LinearMap.toMatrix_apply, LinearEquiv.coe_coe, Basis.equiv_apply]
+
+@[simp]
+theorem volume_fundamentalDomain [Fintype ι] [DecidableEq ι] (b : Basis ι ℝ (ι → ℝ)) :
+ volume (fundamentalDomain b) = ENNReal.ofReal |(Matrix.of b).det| := by
+ rw [measure_fundamentalDomain b volume (b₀ := Pi.basisFun ℝ ι), fundamentalDomain_pi_basisFun,
+ volume_pi, Measure.pi_pi, Real.volume_Ico, sub_zero, ENNReal.ofReal_one, Finset.prod_const_one,
+ mul_one, ← Matrix.det_transpose]
+ rfl
+
end Real
end Zspan
@@ -115,7 +115,7 @@ theorem ceil_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (ceil b
#align zspan.ceil_eq_self_of_mem Zspan.ceil_eq_self_of_mem
/-- The map that sends a vector `E` to the `fundamentalDomain` of the lattice,
-see `Zspan.fract_mem_fundamentalDomain`, and `fract_restrict` for the map with the codomain
+see `Zspan.fract_mem_fundamentalDomain`, and `fractRestrict` for the map with the codomain
restricted to `fundamentalDomain`. -/
def fract (m : E) : E := m - floor b m
#align zspan.fract Zspan.fract
@@ -163,13 +163,13 @@ theorem fract_mem_fundamentalDomain (x : E) : fract b x ∈ fundamentalDomain b
#align zspan.fract_mem_fundamental_domain Zspan.fract_mem_fundamentalDomain
/-- The map `fract` with codomain restricted to `fundamentalDomain`. -/
-def fract_restrict (x : E) : fundamentalDomain b := ⟨fract b x, fract_mem_fundamentalDomain b x⟩
+def fractRestrict (x : E) : fundamentalDomain b := ⟨fract b x, fract_mem_fundamentalDomain b x⟩
-theorem fract_restrict_surjective : Function.Surjective (fract_restrict b) :=
+theorem fractRestrict_surjective : Function.Surjective (fractRestrict b) :=
fun x => ⟨↑x, Subtype.eq (fract_eq_self.mpr (Subtype.mem x))⟩
@[simp]
-theorem fract_restrict_apply (x : E) : (fract_restrict b x : E) = fract b x := rfl
+theorem fractRestrict_apply (x : E) : (fractRestrict b x : E) = fract b x := rfl
theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ (Set.range b) := by
classical
@@ -240,31 +240,31 @@ theorem exist_unique_vadd_mem_fundamentalDomain [Finite ι] (x : E) :
· exact (vadd_mem_fundamentalDomain b y x).mp h
#align zspan.exist_unique_vadd_mem_fundamental_domain Zspan.exist_unique_vadd_mem_fundamentalDomain
-/-- The map `Zspan.fract_restrict` defines an equiv map between `E ⧸ span ℤ (Set.range b)`
+/-- The map `Zspan.fractRestrict` defines an equiv map between `E ⧸ span ℤ (Set.range b)`
and `Zspan.fundamentalDomain b`. -/
-def QuotientEquiv [Fintype ι] :
+def quotientEquiv [Fintype ι] :
E ⧸ span ℤ (Set.range b) ≃ (fundamentalDomain b) := by
refine Equiv.ofBijective ?_ ⟨fun x y => ?_, fun x => ?_⟩
- · refine fun q => Quotient.liftOn q (fract_restrict b) (fun _ _ h => ?_)
- rw [Subtype.mk.injEq, fract_restrict_apply, fract_restrict_apply, fract_eq_fract]
+ · refine fun q => Quotient.liftOn q (fractRestrict b) (fun _ _ h => ?_)
+ rw [Subtype.mk.injEq, fractRestrict_apply, fractRestrict_apply, fract_eq_fract]
exact QuotientAddGroup.leftRel_apply.mp h
· refine Quotient.inductionOn₂ x y (fun _ _ hxy => ?_)
- rw [Quotient.liftOn_mk (s := quotientRel (span ℤ (Set.range b))), fract_restrict,
- Quotient.liftOn_mk (s := quotientRel (span ℤ (Set.range b))), fract_restrict,
+ rw [Quotient.liftOn_mk (s := quotientRel (span ℤ (Set.range b))), fractRestrict,
+ Quotient.liftOn_mk (s := quotientRel (span ℤ (Set.range b))), fractRestrict,
Subtype.mk.injEq] at hxy
apply Quotient.sound'
rwa [QuotientAddGroup.leftRel_apply, mem_toAddSubgroup, ← fract_eq_fract]
- · obtain ⟨a, rfl⟩ := fract_restrict_surjective b x
+ · obtain ⟨a, rfl⟩ := fractRestrict_surjective b x
exact ⟨Quotient.mk'' a, rfl⟩
@[simp]
theorem quotientEquiv_apply_mk [Fintype ι] (x : E) :
- QuotientEquiv b (Submodule.Quotient.mk x) = fract_restrict b x := rfl
+ quotientEquiv b (Submodule.Quotient.mk x) = fractRestrict b x := rfl
@[simp]
theorem quotientEquiv.symm_apply [Fintype ι] (x : fundamentalDomain b) :
- (QuotientEquiv b).symm x = Submodule.Quotient.mk ↑x := by
- rw [Equiv.symm_apply_eq, quotientEquiv_apply_mk b ↑x, Subtype.ext_iff, fract_restrict_apply]
+ (quotientEquiv b).symm x = Submodule.Quotient.mk ↑x := by
+ rw [Equiv.symm_apply_eq, quotientEquiv_apply_mk b ↑x, Subtype.ext_iff, fractRestrict_apply]
exact (fract_eq_self.mpr x.prop).symm
end NormedLatticeField
@@ -329,13 +329,13 @@ theorem Zlattice.FG : AddSubgroup.FG L := by
exact span_mono (by simp only [Subtype.range_coe_subtype, Set.setOf_mem_eq, subset_rfl]))
rw [show span ℤ s = span ℤ (Set.range b) by simp [Basis.coe_mk, Subtype.range_coe_subtype]]
have : Fintype s := Set.Finite.fintype h_lind.finite
- refine Set.Finite.of_finite_image (f := ((↑) : _ → E) ∘ Zspan.QuotientEquiv b) ?_
- (Function.Injective.injOn (Subtype.coe_injective.comp (Zspan.QuotientEquiv b).injective) _)
+ refine Set.Finite.of_finite_image (f := ((↑) : _ → E) ∘ Zspan.quotientEquiv b) ?_
+ (Function.Injective.injOn (Subtype.coe_injective.comp (Zspan.quotientEquiv b).injective) _)
have : Set.Finite ((Zspan.fundamentalDomain b) ∩ L) :=
Metric.Finite_bounded_inter_isClosed (Zspan.fundamentalDomain_bounded b) inferInstance
refine Set.Finite.subset this ?_
rintro _ ⟨_, ⟨⟨x, ⟨h_mem, rfl⟩⟩, rfl⟩⟩
- rw [Function.comp_apply, mkQ_apply, Zspan.quotientEquiv_apply_mk, Zspan.fract_restrict_apply]
+ rw [Function.comp_apply, mkQ_apply, Zspan.quotientEquiv_apply_mk, Zspan.fractRestrict_apply]
refine ⟨?_, ?_⟩
· exact Zspan.fract_mem_fundamentalDomain b x
· rw [Zspan.fract, SetLike.mem_coe, sub_eq_add_neg]
We prove the main characterisation of $\mathbb{Z}$-lattices: a subgroup $L$ of $\mathbb{R}^n$ that is discrete and that spans $\mathbb{R}^n$ is a free $\mathbb{Z}$-module of rank $n$ (in a slightly more general setting).
@@ -3,7 +3,9 @@ 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.LinearAlgebra.FreeModule.PID
import Mathlib.MeasureTheory.Group.FundamentalDomain
+import Mathlib.RingTheory.Localization.Module
#align_import algebra.module.zlattice from "leanprover-community/mathlib"@"a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3"
@@ -11,19 +13,26 @@ import Mathlib.MeasureTheory.Group.FundamentalDomain
# ℤ-lattices
Let `E` be a finite dimensional vector space over a `NormedLinearOrderedField` `K` with a solid
-norm and that is also a `FloorRing`, e.g. `ℚ` or `ℝ`. A (full) ℤ-lattice `L` of `E` is a discrete
+norm that is also a `FloorRing`, e.g. `ℝ`. A (full) `ℤ`-lattice `L` of `E` is a discrete
subgroup of `E` such that `L` spans `E` over `K`.
-The ℤ-lattice `L` can be defined in two ways:
-* For `b` a basis of `E`, then `Submodule.span ℤ (Set.range b)` is a ℤ-lattice of `E`.
+A `ℤ`-lattice `L` can be defined in two ways:
+* For `b` a basis of `E`, then `L = Submodule.span ℤ (Set.range b)` is a ℤ-lattice of `E`
* As an `AddSubgroup E` with the additional properties:
- * `∀ r : ℝ, (L ∩ Metric.closedBall 0 r).finite`, that is `L` is discrete
+ * `DiscreteTopology L`, that is `L` is discrete
* `Submodule.span ℝ (L : Set E) = ⊤`, that is `L` spans `E` over `K`.
-## Main result
+Results about the first point of view are in the `Zspan` namespace and results about the second
+point of view are in the `Zlattice` namespace.
+
+## Main results
+
* `Zspan.isAddFundamentalDomain`: for a ℤ-lattice `Submodule.span ℤ (Set.range b)`, proves that
the set defined by `Zspan.fundamentalDomain` is a fundamental domain.
-
+* `Zlattice.module_free`: an AddSubgroup of `E` that is discrete and spans `E` over `K` is a free
+`ℤ`-module
+* `Zlattice.rank`: an AddSubgroup of `E` that is discrete and spans `E` over `K` is a free
+`ℤ`-module of `ℤ`-rank equal to the `K`-rank of `E`
-/
@@ -52,8 +61,7 @@ def fundamentalDomain : Set E := {m | ∀ i, b.repr m i ∈ Set.Ico (0 : K) 1}
@[simp]
theorem mem_fundamentalDomain {m : E} :
- m ∈ fundamentalDomain b ↔ ∀ i, b.repr m i ∈ Set.Ico (0 : K) 1 :=
- Iff.rfl
+ m ∈ fundamentalDomain b ↔ ∀ i, b.repr m i ∈ Set.Ico (0 : K) 1 := Iff.rfl
#align zspan.mem_fundamental_domain Zspan.mem_fundamentalDomain
variable [FloorRing K]
@@ -107,7 +115,8 @@ theorem ceil_eq_self_of_mem (m : E) (h : m ∈ span ℤ (Set.range b)) : (ceil b
#align zspan.ceil_eq_self_of_mem Zspan.ceil_eq_self_of_mem
/-- The map that sends a vector `E` to the `fundamentalDomain` of the lattice,
-see `Zspan.fract_mem_fundamentalDomain`. -/
+see `Zspan.fract_mem_fundamentalDomain`, and `fract_restrict` for the map with the codomain
+restricted to `fundamentalDomain`. -/
def fract (m : E) : E := m - floor b m
#align zspan.fract Zspan.fract
@@ -153,6 +162,15 @@ theorem fract_mem_fundamentalDomain (x : E) : fract b x ∈ fundamentalDomain b
fract_eq_self.mp (fract_fract b _)
#align zspan.fract_mem_fundamental_domain Zspan.fract_mem_fundamentalDomain
+/-- The map `fract` with codomain restricted to `fundamentalDomain`. -/
+def fract_restrict (x : E) : fundamentalDomain b := ⟨fract b x, fract_mem_fundamentalDomain b x⟩
+
+theorem fract_restrict_surjective : Function.Surjective (fract_restrict b) :=
+ fun x => ⟨↑x, Subtype.eq (fract_eq_self.mpr (Subtype.mem x))⟩
+
+@[simp]
+theorem fract_restrict_apply (x : E) : (fract_restrict b x : E) = fract b x := rfl
+
theorem fract_eq_fract (m n : E) : fract b m = fract b n ↔ -m + n ∈ span ℤ (Set.range b) := by
classical
rw [eq_comm, Basis.ext_elem_iff b]
@@ -222,6 +240,33 @@ theorem exist_unique_vadd_mem_fundamentalDomain [Finite ι] (x : E) :
· exact (vadd_mem_fundamentalDomain b y x).mp h
#align zspan.exist_unique_vadd_mem_fundamental_domain Zspan.exist_unique_vadd_mem_fundamentalDomain
+/-- The map `Zspan.fract_restrict` defines an equiv map between `E ⧸ span ℤ (Set.range b)`
+and `Zspan.fundamentalDomain b`. -/
+def QuotientEquiv [Fintype ι] :
+ E ⧸ span ℤ (Set.range b) ≃ (fundamentalDomain b) := by
+ refine Equiv.ofBijective ?_ ⟨fun x y => ?_, fun x => ?_⟩
+ · refine fun q => Quotient.liftOn q (fract_restrict b) (fun _ _ h => ?_)
+ rw [Subtype.mk.injEq, fract_restrict_apply, fract_restrict_apply, fract_eq_fract]
+ exact QuotientAddGroup.leftRel_apply.mp h
+ · refine Quotient.inductionOn₂ x y (fun _ _ hxy => ?_)
+ rw [Quotient.liftOn_mk (s := quotientRel (span ℤ (Set.range b))), fract_restrict,
+ Quotient.liftOn_mk (s := quotientRel (span ℤ (Set.range b))), fract_restrict,
+ Subtype.mk.injEq] at hxy
+ apply Quotient.sound'
+ rwa [QuotientAddGroup.leftRel_apply, mem_toAddSubgroup, ← fract_eq_fract]
+ · obtain ⟨a, rfl⟩ := fract_restrict_surjective b x
+ exact ⟨Quotient.mk'' a, rfl⟩
+
+@[simp]
+theorem quotientEquiv_apply_mk [Fintype ι] (x : E) :
+ QuotientEquiv b (Submodule.Quotient.mk x) = fract_restrict b x := rfl
+
+@[simp]
+theorem quotientEquiv.symm_apply [Fintype ι] (x : fundamentalDomain b) :
+ (QuotientEquiv b).symm x = Submodule.Quotient.mk ↑x := by
+ rw [Equiv.symm_apply_eq, quotientEquiv_apply_mk b ↑x, Subtype.ext_iff, fract_restrict_apply]
+ exact (fract_eq_self.mpr x.prop).symm
+
end NormedLatticeField
section Real
@@ -258,3 +303,143 @@ protected theorem isAddFundamentalDomain [Finite ι] [MeasurableSpace E] [OpensM
end Real
end Zspan
+
+section Zlattice
+
+open Submodule
+
+variable (K : Type*) [NormedLinearOrderedField K] [HasSolidNorm K] [FloorRing K]
+variable {E : Type*} [NormedAddCommGroup E] [NormedSpace K E] [FiniteDimensional K E]
+variable [ProperSpace E] {L : AddSubgroup E} [DiscreteTopology L]
+variable (hs : span K (L : Set E) = ⊤)
+
+theorem Zlattice.FG : AddSubgroup.FG L := by
+ suffices (AddSubgroup.toIntSubmodule L).FG by exact (fg_iff_add_subgroup_fg _).mp this
+ obtain ⟨s, ⟨h_incl, ⟨h_span, h_lind⟩⟩⟩ := exists_linearIndependent K (L : Set E)
+ -- Let `s` be a maximal `K`-linear independent family of elements of `L`. We show that
+ -- `L` is finitely generated (as a ℤ-module) because it fits in the exact sequence
+ -- `0 → span ℤ s → L → L ⧸ span ℤ s → 0` with `span ℤ s` and `L ⧸ span ℤ s` finitely generated.
+ refine fg_of_fg_map_of_fg_inf_ker (span ℤ s).mkQ ?_ ?_
+ · -- Let `b` be the `K`-basis of `E` formed by the vectors in `s`. The elements of
+ -- `L ⧸ span ℤ s = L ⧸ span ℤ b` are in bijection with elements of `L ∩ fundamentalDomain b`
+ -- so there are finitely many since `fundamentalDomain b` is bounded.
+ refine fg_def.mpr ⟨map (span ℤ s).mkQ (AddSubgroup.toIntSubmodule L), ?_, span_eq _⟩
+ let b := Basis.mk h_lind (by
+ rw [← hs, ← h_span]
+ exact span_mono (by simp only [Subtype.range_coe_subtype, Set.setOf_mem_eq, subset_rfl]))
+ rw [show span ℤ s = span ℤ (Set.range b) by simp [Basis.coe_mk, Subtype.range_coe_subtype]]
+ have : Fintype s := Set.Finite.fintype h_lind.finite
+ refine Set.Finite.of_finite_image (f := ((↑) : _ → E) ∘ Zspan.QuotientEquiv b) ?_
+ (Function.Injective.injOn (Subtype.coe_injective.comp (Zspan.QuotientEquiv b).injective) _)
+ have : Set.Finite ((Zspan.fundamentalDomain b) ∩ L) :=
+ Metric.Finite_bounded_inter_isClosed (Zspan.fundamentalDomain_bounded b) inferInstance
+ refine Set.Finite.subset this ?_
+ rintro _ ⟨_, ⟨⟨x, ⟨h_mem, rfl⟩⟩, rfl⟩⟩
+ rw [Function.comp_apply, mkQ_apply, Zspan.quotientEquiv_apply_mk, Zspan.fract_restrict_apply]
+ refine ⟨?_, ?_⟩
+ · exact Zspan.fract_mem_fundamentalDomain b x
+ · rw [Zspan.fract, SetLike.mem_coe, sub_eq_add_neg]
+ refine AddSubgroup.add_mem _ h_mem
+ (neg_mem (Set.mem_of_subset_of_mem ?_ (Subtype.mem (Zspan.floor b x))))
+ rw [show (L : Set E) = AddSubgroup.toIntSubmodule L by rfl]
+ rw [SetLike.coe_subset_coe, Basis.coe_mk, Subtype.range_coe_subtype, Set.setOf_mem_eq]
+ exact span_le.mpr h_incl
+ · -- `span ℤ s` is finitely generated because `s` is finite
+ rw [ker_mkQ, inf_of_le_right (span_le.mpr h_incl)]
+ exact fg_span (LinearIndependent.finite h_lind)
+
+theorem Zlattice.module_finite : Module.Finite ℤ L :=
+ Module.Finite.iff_addGroup_fg.mpr ((AddGroup.fg_iff_addSubgroup_fg L).mpr (FG K hs))
+
+theorem Zlattice.module_free : Module.Free ℤ L := by
+ have : Module.Finite ℤ L := module_finite K hs
+ have : Module ℚ E := Module.compHom E (algebraMap ℚ K)
+ have : NoZeroSMulDivisors ℤ E := RatModule.noZeroSMulDivisors
+ have : NoZeroSMulDivisors ℤ L := by
+ change NoZeroSMulDivisors ℤ (AddSubgroup.toIntSubmodule L)
+ exact noZeroSMulDivisors _
+ exact Module.free_of_finite_type_torsion_free'
+
+open FiniteDimensional
+
+theorem Zlattice.rank : finrank ℤ L = finrank K E := by
+ classical
+ have : Module.Finite ℤ L := module_finite K hs
+ have : Module.Free ℤ L := module_free K hs
+ have : Module ℚ E := Module.compHom E (algebraMap ℚ K)
+ let b₀ := Module.Free.chooseBasis ℤ L
+ -- Let `b` be a `ℤ`-basis of `L` formed of vectors of `E`
+ let b := Subtype.val ∘ b₀
+ have : LinearIndependent ℤ b :=
+ LinearIndependent.map' b₀.linearIndependent (L.toIntSubmodule.subtype) (ker_subtype _)
+ -- We prove some assertions that will be useful later on
+ have h_spanL : span ℤ (Set.range b) = AddSubgroup.toIntSubmodule L := by
+ convert congrArg (map (Submodule.subtype (AddSubgroup.toIntSubmodule L))) b₀.span_eq
+ · rw [map_span, Set.range_comp]
+ rfl
+ · exact (map_subtype_top _).symm
+ have h_spanE : span K (Set.range b) = ⊤ := by rwa [← span_span_of_tower (R := ℤ), h_spanL]
+ have h_card : Fintype.card (Module.Free.ChooseBasisIndex ℤ L) =
+ (Set.range b).toFinset.card := by
+ rw [Set.toFinset_range, Finset.univ.card_image_of_injective]
+ rfl
+ exact Subtype.coe_injective.comp (Basis.injective _)
+ rw [finrank_eq_card_chooseBasisIndex]
+ -- We prove that `finrank ℤ L ≤ finrank K E` and `finrank K E ≤ finrank ℤ L`
+ refine le_antisymm ?_ ?_
+ · -- To prove that `finrank ℤ L ≤ finrank K E`, we proceed by contradiction and prove that, in
+ -- this case, there is a ℤ-relation between the vectors of `b`
+ obtain ⟨t, ⟨ht_inc, ⟨ht_span, ht_lin⟩⟩⟩ := exists_linearIndependent K (Set.range b)
+ -- `e` is a `K`-basis of `E` formed of vectors of `b`
+ let e : Basis t K E := Basis.mk ht_lin (by simp [ht_span, h_spanE])
+ have : Fintype t := Set.Finite.fintype ((Set.range b).toFinite.subset ht_inc)
+ have h : LinearIndependent ℤ (fun x : (Set.range b) => (x : E)) := by
+ rwa [linearIndependent_subtype_range (Subtype.coe_injective.comp b₀.injective)]
+ contrapose! h
+ -- Since `finrank ℤ L > finrank K E`, there exists a vector `v ∈ b` with `v ∉ e`
+ obtain ⟨v, hv⟩ : (Set.range b \ Set.range e).Nonempty := by
+ rw [Basis.coe_mk, Subtype.range_coe_subtype, Set.setOf_mem_eq, ← Set.toFinset_nonempty]
+ contrapose h
+ rw [Finset.not_nonempty_iff_eq_empty, Set.toFinset_diff,
+ Finset.sdiff_eq_empty_iff_subset] at h
+ replace h := Finset.card_le_of_subset h
+ rwa [not_lt, h_card, ← topEquiv.finrank_eq, ← h_spanE, ← ht_span,
+ finrank_span_set_eq_card _ ht_lin]
+ -- Assume that `e ∪ {v}` is not `ℤ`-linear independent then we get the contradiction
+ suffices ¬ LinearIndependent ℤ (fun x : ↥(insert v (Set.range e)) => (x : E)) by
+ contrapose! this
+ refine LinearIndependent.mono ?_ this
+ exact Set.insert_subset (Set.mem_of_mem_diff hv) (by simp [ht_inc])
+ -- We prove finally that `e ∪ {v}` is not ℤ-linear independent or, equivalently,
+ -- not ℚ-linear independent by showing that `v ∈ span ℚ e`.
+ rw [LinearIndependent.iff_fractionRing ℤ ℚ,
+ (linearIndependent_insert (Set.not_mem_of_mem_diff hv)), not_and, not_not]
+ intro _
+ -- But that follows from the fact that there exist `n, m : ℕ`, `n ≠ m`
+ -- such that `(n - m) • v ∈ span ℤ e` which is true since `n ↦ Zspan.fract e (n • v)`
+ -- takes value into the finite set `fundamentalDomain e ∩ L`
+ have h_mapsto : Set.MapsTo (fun n : ℤ => Zspan.fract e (n • v)) Set.univ
+ (Metric.closedBall 0 (∑ i, ‖e i‖) ∩ (L : Set E)) := by
+ rw [Set.mapsTo_inter, Set.maps_univ_to, Set.maps_univ_to]
+ refine ⟨fun _ => mem_closedBall_zero_iff.mpr (Zspan.norm_fract_le e _), fun _ => ?_⟩
+ · change _ ∈ AddSubgroup.toIntSubmodule L
+ rw [← h_spanL]
+ refine sub_mem ?_ ?_
+ · exact zsmul_mem (subset_span (Set.diff_subset _ _ hv)) _
+ · exact span_mono (by simp [ht_inc]) (coe_mem _)
+ have h_finite : Set.Finite (Metric.closedBall 0 (∑ i, ‖e i‖) ∩ (L : Set E)) :=
+ Metric.Finite_bounded_inter_isClosed Metric.bounded_closedBall inferInstance
+ obtain ⟨n, -, m, -, h_neq, h_eq⟩ := Set.Infinite.exists_ne_map_eq_of_mapsTo
+ Set.infinite_univ h_mapsto h_finite
+ have h_nz : (-n + m : ℚ) ≠ 0 := by
+ rwa [Ne.def, add_eq_zero_iff_eq_neg.not, neg_inj, Rat.coe_int_inj, ← Ne.def]
+ apply (smul_mem_iff _ h_nz).mp
+ refine span_subset_span ℤ ℚ _ ?_
+ rwa [add_smul, neg_smul, SetLike.mem_coe, ← Zspan.fract_eq_fract, ← zsmul_eq_smul_cast ℚ,
+ ← zsmul_eq_smul_cast ℚ]
+ · -- To prove that `finrank K E ≤ finrank ℤ L`, we use the fact `b` generates `E` over `K`
+ -- and thus `finrank K E ≤ card b = finrank ℤ L`
+ rw [← topEquiv.finrank_eq, ← h_spanE]
+ convert finrank_span_le_card (K := K) (Set.range b)
+
+end Zlattice
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -35,11 +35,11 @@ namespace Zspan
open MeasureTheory MeasurableSet Submodule
-variable {E ι : Type _}
+variable {E ι : Type*}
section NormedLatticeField
-variable {K : Type _} [NormedLinearOrderedField K]
+variable {K : Type*} [NormedLinearOrderedField K]
variable [NormedAddCommGroup E] [NormedSpace K E]
@@ -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 algebra.module.zlattice
-! leanprover-community/mathlib commit a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.MeasureTheory.Group.FundamentalDomain
+#align_import algebra.module.zlattice from "leanprover-community/mathlib"@"a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3"
+
/-!
# ℤ-lattices
The unported dependencies are
algebra.order.module
init.core
linear_algebra.free_module.finite.rank
algebra.order.monoid.cancel.defs
algebra.abs
algebra.group_power.lemmas
init.data.list.basic
linear_algebra.free_module.rank
algebra.order.monoid.cancel.basic
init.data.list.default
topology.subset_properties
init.logic
The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file