algebra.module.zlatticeMathlib.Algebra.Module.Zlattice

This file has been ported!

Changes since the initial port

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

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -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
 -/
 
Diff
@@ -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
 -/
 
Diff
@@ -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
 -/
Diff
@@ -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
 -/
 
Diff
@@ -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"
 
Diff
@@ -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 /-
Diff
@@ -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
Diff
@@ -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
 
Diff
@@ -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
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Xavier Roblot
 
 ! This file was ported from Lean 3 source module 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`.
Diff
@@ -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
 

Changes in mathlib4

mathlib3
mathlib4
chore: adapt to multiple goal linter 2 (#12361)

A PR analogous to #12338: reformatting proofs following the multiple goals linter of #12339.

Diff
@@ -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 ?_ ?_
chore: remove redundant LinearEquiv.map_neg/sub (#12330)

These are redundant with _root_.{map_neg,map_sub}.

Diff
@@ -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
 
feat: Define the covolume of a ZLattice (#11327)

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

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

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

Diff
@@ -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
chore: backports from #11997, adaptations for nightly-2024-04-07 (#12176)

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>

Diff
@@ -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 ℚ,
chore: superfluous parentheses part 2 (#12131)

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

Diff
@@ -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)`
feat: Add 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>

Diff
@@ -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
chore(Module/Zlattice): fix Fintype/Finite (#11538)
Diff
@@ -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
 
feat: Add 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.

Diff
@@ -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
chore(*): remove empty lines between variable statements (#11418)

Empty lines were removed by executing the following Python script twice

import os
import re


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

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

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

      # Write the modified content back to the file
      with open(file_path, 'w') as file:
        file.write(modified_content)
Diff
@@ -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]
chore: Define the class IsZlattice (#11356)

See the Zulip thread

Diff
@@ -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]
chore(*): Fintype -> Finite, drop Decidable (#11423)

Also, in some cases drop unneeded Fintype arguments.

Diff
@@ -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 ⊢
chore: replace λ 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

  • In lines I was modifying anyway, I also converted => to .
  • Also contains some mild in-passing indentation fixes in Mathlib/Order/SupClosed.
  • Some doc comments still contained Lean 3 syntax λ x, , which I also replaced.
Diff
@@ -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 ?_ ?_
chore: prepare Lean version bump with explicit simp (#10999)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -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
feat: Proof of Hermite theorem on number fields of bounded discriminant (#10030)

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

Diff
@@ -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
feat: Generalize results of CanonicalEmbedding to fractional ideals (#9837)

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

Diff
@@ -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]
chore: reduce imports (#9830)

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

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

Diff
@@ -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
chore: replace SubgroupClass.inv by InvMemClass.inv (#9761)
Diff
@@ -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
feat: Rank-nullity theorem for commutative domains (#9412)

Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com>

Diff
@@ -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
feat: Provide glue between AddCommGroup and Module ℤ (#9345)

Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com>

Diff
@@ -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
 
chore: Improve Finset lemma names (#8894)

Change a few lemma names that have historically bothered me.

  • Finset.card_le_of_subsetFinset.card_le_card
  • Multiset.card_le_of_leMultiset.card_le_card
  • Multiset.card_lt_of_ltMultiset.card_lt_card
  • Set.ncard_le_of_subsetSet.ncard_le_ncard
  • Finset.image_filterFinset.filter_image
  • CompleteLattice.finset_sup_compact_of_compactCompleteLattice.isCompactElement_finset_sup
Diff
@@ -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
chore(Data/Set/Function): rename some lemmas (#9257)
  • Set.maps_image_toSet.mapsTo_image_iff;
  • Set.maps_univ_toSet.mapsTo_univ_iff;
  • Set.maps_range_toSet.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.

Diff
@@ -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]
feat: A lin. indep. family of vectors in a fin. dim. space is finite (#9103)

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

Diff
@@ -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))
feat: add a discrete topology instance for zlattice (#8480)

Add the following

variable [NormedAddCommGroup E] [NormedSpace ℝ E] (b : Basis ι ℝ E)

instance [Fintype ι] : DiscreteTopology (span ℤ (Set.range b)) 
Diff
@@ -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 ι] :
chore: tidy various files (#8823)
Diff
@@ -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) :
feat: Prove that a fundamental domain has nonzero volume (#8287)
Diff
@@ -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
refactor(Topology/MetricSpace): remove Metric.Bounded (#7240)

Use Bornology.IsBounded instead.

Diff
@@ -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
chore: use _root_.map_sum more consistently (#7189)

Also _root_.map_smul when in the neighbourhood.

Diff
@@ -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]
feat: add results for the computation of the volume of Zspan.fundamentalDomain (#6904)

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|
Diff
@@ -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
chore: tidy various files (#7017)
Diff
@@ -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]
feat(Algebra.Module.Zlattice): add Zlattice.module_free and Zlattice.rank (#5728)

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).

Diff
@@ -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
chore: banish Type _ and Sort _ (#6499)

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

This has nice performance benefits.

Diff
@@ -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]
 
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

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

Diff
@@ -2,14 +2,11 @@
 Copyright (c) 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
 
feat: port Algebra.Module.Zlattice (#4944)

Maybe this file should be called ZLattice....

Dependencies 12 + 946

947 files ported (98.7%)
433220 lines ported (98.7%)
Show graph

The unported dependencies are

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