Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 7302e11

Browse files
pbazinfpvandoorn
andcommitted
feat(algebra/module/torsion): define torsion submodules (#12027)
This file defines the a-torsion and torsion submodules for a R-module M and gives some basic properties. (The ultimate goal I'm working on is to classify the finitely-generated modules over a PID). Co-authored-by: Floris van Doorn <fpvdoorn@gmail.com>
1 parent c7745b3 commit 7302e11

File tree

2 files changed

+271
-0
lines changed

2 files changed

+271
-0
lines changed

src/algebra/group/basic.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,17 @@ theorem left_inverse_inv_mul_mul_right (c : G) :
467467
function.left_inverse (λ x, c⁻¹ * x) (λ x, c * x) :=
468468
assume x, inv_mul_cancel_left c x
469469

470+
@[to_additive]
471+
lemma exists_npow_eq_one_of_zpow_eq_one {n : ℤ} (hn : n ≠ 0) {x : G} (h : x ^ n = 1) :
472+
∃ n : ℕ, 0 < n ∧ x ^ n = 1 :=
473+
begin
474+
cases n with n n,
475+
{ rw zpow_of_nat at h,
476+
refine ⟨n, nat.pos_of_ne_zero (λ n0, hn _), h⟩, rw n0, refl },
477+
{ rw [zpow_neg_succ_of_nat, inv_eq_one] at h,
478+
refine ⟨n + 1, n.succ_pos, h⟩ }
479+
end
480+
470481
end group
471482

472483
section comm_group

src/algebra/module/torsion.lean

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/-
2+
Copyright (c) 2022 Pierre-Alexandre Bazin. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Pierre-Alexandre Bazin
5+
-/
6+
import algebra.module
7+
import linear_algebra.quotient
8+
import ring_theory.ideal.quotient
9+
import ring_theory.non_zero_divisors
10+
import group_theory.torsion
11+
12+
/-!
13+
# Torsion submodules
14+
15+
## Main definitions
16+
17+
* `submodule.torsion_by R M a` : the `a`-torsion submodule, containing all elements `x` of `M` such
18+
that `a • x = 0`.
19+
* `submodule.torsion' R M S` : the `S`-torsion submodule, containing all elements `x` of `M` such
20+
that `a • x = 0` for some `a` in `S`.
21+
* `submodule.torsion R M` : the torsion submoule, containing all elements `x` of `M` such that
22+
`a • x = 0` for some non-zero-divisor `a` in `R`.
23+
* `module.is_torsion_by R M a` : the property that defines a `a`-torsion module. Similarly,
24+
`is_torsion'` and `is_torsion`.
25+
26+
## Main statements
27+
28+
* `torsion' R M S` and `torsion R M` are submodules.
29+
* `torsion_by R M a` can be viewed as a `(R ⧸ R∙a)`-module.
30+
* `submodule.torsion_by_is_torsion_by` : the `a`-torsion submodule is a `a`-torsion module.
31+
Similar lemmas for `torsion'` and `torsion`.
32+
* `submodule.no_zero_smul_divisors_iff_torsion_bot` : a module over a domain has
33+
`no_zero_smul_divisors` (that is, there is no non-zero `a`, `x` such that `a • x = 0`)
34+
iff its torsion submodule is trivial.
35+
* `submodule.quotient_torsion.torsion_eq_bot` : quotienting by the torsion submodule makes the
36+
torsion submodule of the new module trivial. If `R` is a domain, we can derive an instance
37+
`submodule.quotient_torsion.no_zero_smul_divisors : no_zero_smul_divisors R (M ⧸ torsion R M)`.
38+
39+
## Notation
40+
41+
* The notions are defined for a `comm_semiring R` and a `module R M`. Some additional hypotheses on
42+
`R` and `M` are required by some lemmas.
43+
* The letters `a`, `b`, ... are used for scalars (in `R`), while `x`, `y`, ... are used for vectors
44+
(in `M`).
45+
46+
## Tags
47+
48+
Torsion, submodule, module, quotient
49+
-/
50+
51+
open_locale non_zero_divisors
52+
53+
section defs
54+
55+
variables (R M : Type*) [comm_semiring R] [add_comm_monoid M] [module R M]
56+
57+
namespace submodule
58+
59+
/-- The `a`-torsion submodule for `a` in `R`, containing all elements `x` of `M` such that
60+
`a • x = 0`. -/
61+
@[simps] def torsion_by (a : R) : submodule R M := (distrib_mul_action.to_linear_map _ _ a).ker
62+
63+
/-- The `S`-torsion submodule, containing all elements `x` of `M` such that `a • x = 0` for some
64+
`a` in `S`. -/
65+
@[simps] def torsion' (S : Type*)
66+
[comm_monoid S] [distrib_mul_action S M] [smul_comm_class S R M] :
67+
submodule R M :=
68+
{ carrier := { x | ∃ a : S, a • x = 0 },
69+
zero_mem' := ⟨1, smul_zero _⟩,
70+
add_mem' := λ x y ⟨a, hx⟩ ⟨b, hy⟩,
71+
⟨b * a,
72+
by rw [smul_add, mul_smul, mul_comm, mul_smul, hx, hy, smul_zero, smul_zero, add_zero]⟩,
73+
smul_mem' := λ a x ⟨b, h⟩, ⟨b, by rw [smul_comm, h, smul_zero]⟩ }
74+
75+
/-- The torsion submodule, containing all elements `x` of `M` such that `a • x = 0` for some
76+
non-zero-divisor `a` in `R`. -/
77+
@[reducible] def torsion := torsion' R M R⁰
78+
end submodule
79+
80+
namespace module
81+
82+
/-- A `a`-torsion module is a module where every element is `a`-torsion. -/
83+
@[reducible] def is_torsion_by (a : R) := ∀ ⦃x : M⦄, a • x = 0
84+
85+
/-- A `S`-torsion module is a module where every element is `a`-torsion for some `a` in `S`. -/
86+
@[reducible] def is_torsion' (S : Type*) [has_scalar S M] := ∀ ⦃x : M⦄, ∃ a : S, a • x = 0
87+
88+
/-- A torsion module is a module where every element is `a`-torsion for some non-zero-divisor `a`.
89+
-/
90+
@[reducible] def is_torsion := ∀ ⦃x : M⦄, ∃ a : R⁰, a • x = 0
91+
92+
end module
93+
94+
end defs
95+
96+
namespace submodule
97+
98+
open module
99+
100+
variables {R M : Type*}
101+
102+
section torsion_by
103+
104+
variables [comm_semiring R] [add_comm_monoid M] [module R M] (a : R)
105+
106+
@[simp] lemma smul_torsion_by (x : torsion_by R M a) : a • x = 0 := subtype.ext x.prop
107+
@[simp] lemma smul_coe_torsion_by (x : torsion_by R M a) : a • (x : M) = 0 := x.prop
108+
@[simp] lemma mem_torsion_by_iff (x : M) : x ∈ torsion_by R M a ↔ a • x = 0 := iff.rfl
109+
110+
/-- A `a`-torsion module is a module whose `a`-torsion submodule is the full space. -/
111+
lemma is_torsion_by_iff_torsion_by_eq_top : is_torsion_by R M a ↔ torsion_by R M a = ⊤ :=
112+
⟨λ h, eq_top_iff.mpr (λ _ _, @h _), λ h x, by { rw [← mem_torsion_by_iff, h], trivial }⟩
113+
114+
/-- The `a`-torsion submodule is a `a`-torsion module. -/
115+
lemma torsion_by_is_torsion_by : is_torsion_by R (torsion_by R M a) a := λ _, smul_torsion_by _ _
116+
117+
@[simp] lemma torsion_by_torsion_by_eq_top : torsion_by R (torsion_by R M a) a = ⊤ :=
118+
(is_torsion_by_iff_torsion_by_eq_top a).mp $ torsion_by_is_torsion_by a
119+
120+
end torsion_by
121+
122+
section quotient
123+
124+
variables [comm_ring R] [add_comm_group M] [module R M] (a : R)
125+
126+
instance : has_scalar (R ⧸ R ∙ a) (torsion_by R M a) :=
127+
{ smul := λ b x, quotient.lift_on' b (• x) $ λ b₁ b₂ (h : b₁ - b₂ ∈ _), begin
128+
show b₁ • x = b₂ • x,
129+
obtain ⟨c, h⟩ := ideal.mem_span_singleton'.mp h,
130+
rw [← sub_eq_zero, ← sub_smul, ← h, mul_smul, smul_torsion_by, smul_zero],
131+
end }
132+
133+
@[simp] lemma torsion_by.mk_smul (b : R) (x : torsion_by R M a) :
134+
ideal.quotient.mk (R ∙ a) b • x = b • x := rfl
135+
136+
/-- The `a`-torsion submodule as a `(R ⧸ R∙a)`-module. -/
137+
instance : module (R ⧸ R ∙ a) (torsion_by R M a) :=
138+
@function.surjective.module_left _ _ (torsion_by R M a) _ _ _ _ _ (ideal.quotient.mk $ R ∙ a)
139+
ideal.quotient.mk_surjective (torsion_by.mk_smul _)
140+
141+
instance {S : Type*} [has_scalar S R] [has_scalar S M]
142+
[is_scalar_tower S R M] [is_scalar_tower S R R] :
143+
is_scalar_tower S (R ⧸ R ∙ a) (torsion_by R M a) :=
144+
{ smul_assoc := λ b d x, quotient.induction_on' d $ λ c, (smul_assoc b c x : _) }
145+
146+
end quotient
147+
148+
section torsion'
149+
150+
variables [comm_semiring R] [add_comm_monoid M] [module R M]
151+
variables (S : Type*) [comm_monoid S] [distrib_mul_action S M] [smul_comm_class S R M]
152+
153+
@[simp] lemma mem_torsion'_iff (x : M) : x ∈ torsion' R M S ↔ ∃ a : S, a • x = 0 := iff.rfl
154+
@[simp] lemma mem_torsion_iff (x : M) : x ∈ torsion R M ↔ ∃ a : R⁰, a • x = 0 := iff.rfl
155+
156+
@[simps] instance : has_scalar S (torsion' R M S) :=
157+
⟨λ s x, ⟨s • x, by { obtain ⟨x, a, h⟩ := x, use a, dsimp, rw [smul_comm, h, smul_zero] }⟩⟩
158+
instance : distrib_mul_action S (torsion' R M S) := subtype.coe_injective.distrib_mul_action
159+
((torsion' R M S).subtype).to_add_monoid_hom (λ (c : S) x, rfl)
160+
instance : smul_comm_class S R (torsion' R M S) := ⟨λ s a x, subtype.ext $ smul_comm _ _ _⟩
161+
162+
/-- A `S`-torsion module is a module whose `S`-torsion submodule is the full space. -/
163+
lemma is_torsion'_iff_torsion'_eq_top : is_torsion' M S ↔ torsion' R M S = ⊤ :=
164+
⟨λ h, eq_top_iff.mpr (λ _ _, @h _), λ h x, by { rw [← @mem_torsion'_iff R, h], trivial }⟩
165+
166+
/-- The `S`-torsion submodule is a `S`-torsion module. -/
167+
lemma torsion'_is_torsion' : is_torsion' (torsion' R M S) S := λ ⟨x, ⟨a, h⟩⟩, ⟨a, subtype.ext h⟩
168+
169+
@[simp] lemma torsion'_torsion'_eq_top : torsion' R (torsion' R M S) S = ⊤ :=
170+
(is_torsion'_iff_torsion'_eq_top S).mp $ torsion'_is_torsion' S
171+
172+
/-- The torsion submodule of the torsion submodule (viewed as a module) is the full
173+
torsion module. -/
174+
@[simp] lemma torsion_torsion_eq_top : torsion R (torsion R M) = ⊤ := torsion'_torsion'_eq_top R⁰
175+
176+
/-- The torsion submodule is always a torsion module. -/
177+
lemma torsion_is_torsion : module.is_torsion R (torsion R M) := torsion'_is_torsion' R⁰
178+
179+
end torsion'
180+
181+
section torsion
182+
variables [comm_semiring R] [add_comm_monoid M] [module R M] [no_zero_divisors R] [nontrivial R]
183+
184+
lemma coe_torsion_eq_annihilator_ne_bot :
185+
(torsion R M : set M) = { x : M | (R ∙ x).annihilator ≠ ⊥ } :=
186+
begin
187+
ext x, simp_rw [submodule.ne_bot_iff, mem_annihilator, mem_span_singleton],
188+
exact ⟨λ ⟨a, hax⟩, ⟨a, λ _ ⟨b, hb⟩, by rw [← hb, smul_comm, ← submonoid.smul_def, hax, smul_zero],
189+
non_zero_divisors.coe_ne_zero _⟩,
190+
λ ⟨a, hax, ha⟩, ⟨⟨_, mem_non_zero_divisors_of_ne_zero ha⟩, hax x ⟨1, one_smul _ _⟩⟩⟩
191+
end
192+
193+
/-- A module over a domain has `no_zero_smul_divisors` iff its torsion submodule is trivial. -/
194+
lemma no_zero_smul_divisors_iff_torsion_eq_bot :
195+
no_zero_smul_divisors R M ↔ torsion R M = ⊥ :=
196+
begin
197+
split; intro h,
198+
{ haveI : no_zero_smul_divisors R M := h,
199+
rw eq_bot_iff, rintro x ⟨a, hax⟩,
200+
change (a : R) • x = 0 at hax,
201+
cases eq_zero_or_eq_zero_of_smul_eq_zero hax with h0 h0,
202+
{ exfalso, exact non_zero_divisors.coe_ne_zero a h0 }, { exact h0 } },
203+
{ exact { eq_zero_or_eq_zero_of_smul_eq_zero := λ a x hax, begin
204+
by_cases ha : a = 0,
205+
{ left, exact ha },
206+
{ right, rw [← mem_bot _, ← h],
207+
exact ⟨⟨a, mem_non_zero_divisors_of_ne_zero ha⟩, hax⟩ }
208+
end } }
209+
end
210+
end torsion
211+
212+
namespace quotient_torsion
213+
214+
variables [comm_ring R] [add_comm_group M] [module R M]
215+
216+
/-- Quotienting by the torsion submodule gives a torsion-free module. -/
217+
@[simp] lemma torsion_eq_bot : torsion R (M ⧸ torsion R M) = ⊥ :=
218+
eq_bot_iff.mpr $ λ z, quotient.induction_on' z $ λ x ⟨a, hax⟩,
219+
begin
220+
rw [quotient.mk'_eq_mk, ← quotient.mk_smul, quotient.mk_eq_zero] at hax,
221+
rw [mem_bot, quotient.mk'_eq_mk, quotient.mk_eq_zero],
222+
cases hax with b h,
223+
exact ⟨b * a, (mul_smul _ _ _).trans h⟩
224+
end
225+
226+
instance no_zero_smul_divisors [is_domain R] : no_zero_smul_divisors R (M ⧸ torsion R M) :=
227+
no_zero_smul_divisors_iff_torsion_eq_bot.mpr torsion_eq_bot
228+
229+
end quotient_torsion
230+
231+
end submodule
232+
233+
namespace add_monoid
234+
235+
variables {M : Type*}
236+
237+
theorem is_torsion_iff_is_torsion_nat [add_comm_monoid M] :
238+
add_monoid.is_torsion M ↔ module.is_torsion ℕ M :=
239+
begin
240+
refine ⟨λ h x, _, λ h x, _⟩,
241+
{ obtain ⟨n, h0, hn⟩ := (is_of_fin_add_order_iff_nsmul_eq_zero x).mp (h x),
242+
exact ⟨⟨n, mem_non_zero_divisors_of_ne_zero $ ne_of_gt h0⟩, hn⟩ },
243+
{ rw is_of_fin_add_order_iff_nsmul_eq_zero,
244+
obtain ⟨n, hn⟩ := @h x,
245+
refine ⟨n, nat.pos_of_ne_zero (non_zero_divisors.coe_ne_zero _), hn⟩ }
246+
end
247+
248+
theorem is_torsion_iff_is_torsion_int [add_comm_group M] :
249+
add_monoid.is_torsion M ↔ module.is_torsion ℤ M :=
250+
begin
251+
refine ⟨λ h x, _, λ h x, _⟩,
252+
{ obtain ⟨n, h0, hn⟩ := (is_of_fin_add_order_iff_nsmul_eq_zero x).mp (h x),
253+
exact ⟨⟨n, mem_non_zero_divisors_of_ne_zero $ ne_of_gt $ int.coe_nat_pos.mpr h0⟩,
254+
(coe_nat_zsmul _ _).trans hn⟩ },
255+
{ rw is_of_fin_add_order_iff_nsmul_eq_zero,
256+
obtain ⟨n, hn⟩ := @h x,
257+
exact exists_nsmul_eq_zero_of_zsmul_eq_zero (non_zero_divisors.coe_ne_zero n) hn }
258+
end
259+
260+
end add_monoid

0 commit comments

Comments
 (0)