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

Commit d6420bd

Browse files
committed
feat(ring_theory/principal_ideal_domain): definition of principal submodule (#2761)
This PR generalizes the definition of principal ideals to principal submodules. It turns out that it's essentially enough to replace `ideal R` with `submodule R M` in the relevant places. With this change, it's possible to talk about principal fractional ideals (although that development will have to wait #2714 gets merged). Since the PR already changes the variables used in this file, I took the opportunity to rename them so `[ring α]` becomes `[ring R]`.
1 parent 4c3e1a9 commit d6420bd

File tree

1 file changed

+62
-54
lines changed

1 file changed

+62
-54
lines changed

src/ring_theory/principal_ideal_domain.lean

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,55 +6,64 @@ Author: Chris Hughes, Morenikeji Neri
66
import ring_theory.noetherian
77
import ring_theory.unique_factorization_domain
88

9-
variables {α : Type*}
9+
universes u v
10+
variables {R : Type u} {M : Type v}
1011

11-
open set function ideal
12+
open set function
13+
open submodule
1214
open_locale classical
1315

14-
class ideal.is_principal [comm_ring α] (S : ideal α) : Prop :=
15-
(principal [] : ∃ a, S = span {a})
16+
/-- An `R`-submodule of `M` is principal if it is generated by one element. -/
17+
class submodule.is_principal [ring R] [add_comm_group M] [module R M] (S : submodule R M) : Prop :=
18+
(principal [] : ∃ a, S = span R {a})
1619

1720
section prio
1821
set_option default_priority 100 -- see Note [default priority]
19-
class principal_ideal_domain (α : Type*) extends integral_domain α :=
20-
(principal : ∀ (S : ideal α), S.is_principal)
22+
class principal_ideal_domain (R : Type u) extends integral_domain R :=
23+
(principal : ∀ (S : ideal R), S.is_principal)
2124
end prio
2225

2326
-- see Note [lower instance priority]
2427
attribute [instance, priority 500] principal_ideal_domain.principal
25-
namespace ideal.is_principal
26-
variable [comm_ring α]
28+
namespace submodule.is_principal
29+
30+
variables [comm_ring R] [add_comm_group M] [module R M]
2731

28-
noncomputable def generator (S : ideal α) [S.is_principal] : α :=
32+
/-- `generator I`, if `I` is a principal submodule, is the `x ∈ M` such that `span R {x} = I` -/
33+
noncomputable def generator (S : submodule R M) [S.is_principal] : M :=
2934
classical.some (principal S)
3035

31-
lemma span_singleton_generator (S : ideal α) [S.is_principal] : span {generator S} = S :=
36+
lemma span_singleton_generator (S : submodule R M) [S.is_principal] : span R {generator S} = S :=
3237
eq.symm (classical.some_spec (principal S))
3338

34-
@[simp] lemma generator_mem (S : ideal α) [S.is_principal] : generator S ∈ S :=
35-
by conv {to_rhs, rw ← span_singleton_generator S}; exact subset_span (mem_singleton _)
39+
@[simp] lemma generator_mem (S : submodule R M) [S.is_principal] : generator S ∈ S :=
40+
by { conv_rhs { rw ← span_singleton_generator S }, exact subset_span (mem_singleton _) }
3641

37-
lemma mem_iff_generator_dvd (S : ideal α) [S.is_principal] {x : α} : x ∈ S ↔ generator S ∣ x :=
38-
by rw [← mem_span_singleton, span_singleton_generator]
42+
lemma mem_iff_eq_smul_generator (S : submodule R M) [S.is_principal] {x : M} :
43+
x ∈ S ↔ ∃ s : R, x = s • generator S :=
44+
by simp_rw [@eq_comm _ x, ← mem_span_singleton, span_singleton_generator]
3945

40-
lemma eq_bot_iff_generator_eq_zero (S : ideal α) [S.is_principal] :
46+
lemma mem_iff_generator_dvd (S : ideal R) [S.is_principal] {x : R} : x ∈ S ↔ generator S ∣ x :=
47+
(mem_iff_eq_smul_generator S).trans (exists_congr (λ a, by simp only [mul_comm, smul_eq_mul]))
48+
49+
lemma eq_bot_iff_generator_eq_zero (S : submodule R M) [S.is_principal] :
4150
S = ⊥ ↔ generator S = 0 :=
42-
by rw [← span_singleton_eq_bot, span_singleton_generator]
51+
by rw [← @span_singleton_eq_bot R M, span_singleton_generator]
4352

44-
end ideal.is_principal
53+
end submodule.is_principal
4554

4655
namespace is_prime
47-
open ideal.is_principal ideal
56+
open submodule.is_principal ideal
4857

49-
lemma to_maximal_ideal [principal_ideal_domain α] {S : ideal α}
58+
lemma to_maximal_ideal [principal_ideal_domain R] {S : ideal R}
5059
[hpi : is_prime S] (hS : S ≠ ⊥) : is_maximal S :=
5160
is_maximal_iff.2 ⟨(ne_top_iff_one S).1 hpi.1, begin
5261
assume T x hST hxS hxT,
5362
haveI := principal_ideal_domain.principal S,
5463
haveI := principal_ideal_domain.principal T,
5564
cases (mem_iff_generator_dvd _).1 (hST $ generator_mem S) with z hz,
5665
cases hpi.2 (show generator T * z ∈ S, from hz ▸ generator_mem S),
57-
{ have hTS : T ≤ S, rwa [← span_singleton_generator T, span_le, singleton_subset_iff],
66+
{ have hTS : T ≤ S, rwa [← span_singleton_generator T, submodule.span_le, singleton_subset_iff],
5867
exact (hxS $ hTS hxT).elim },
5968
cases (mem_iff_generator_dvd _).1 h with y hy,
6069
have : generator S ≠ 0 := mt (eq_bot_iff_generator_eq_zero _).2 hS,
@@ -66,43 +75,43 @@ end is_prime
6675

6776
section
6877
open euclidean_domain
69-
variable [euclidean_domain α]
78+
variable [euclidean_domain R]
7079

71-
lemma mod_mem_iff {S : ideal α} {x y : α} (hy : y ∈ S) : x % y ∈ S ↔ x ∈ S :=
72-
⟨λ hxy, div_add_mod x y ▸ ideal.add_mem S (mul_mem_right S hy) hxy,
80+
lemma mod_mem_iff {S : ideal R} {x y : R} (hy : y ∈ S) : x % y ∈ S ↔ x ∈ S :=
81+
⟨λ hxy, div_add_mod x y ▸ ideal.add_mem S (ideal.mul_mem_right S hy) hxy,
7382
λ hx, (mod_eq_sub_mul_div x y).symm ▸ ideal.sub_mem S hx (ideal.mul_mem_right S hy)⟩
7483

7584
@[priority 100] -- see Note [lower instance priority]
76-
instance euclidean_domain.to_principal_ideal_domain : principal_ideal_domain α :=
85+
instance euclidean_domain.to_principal_ideal_domain : principal_ideal_domain R :=
7786
{ principal := λ S, by exactI
78-
if h : {x : α | x ∈ S ∧ x ≠ 0}.nonempty
87+
if h : {x : R | x ∈ S ∧ x ≠ 0}.nonempty
7988
then
80-
have wf : well_founded (euclidean_domain.r : ααProp) := euclidean_domain.r_well_founded,
81-
have hmin : well_founded.min wf {x : α | x ∈ S ∧ x ≠ 0} h ∈ S ∧
82-
well_founded.min wf {x : α | x ∈ S ∧ x ≠ 0} h ≠ 0,
83-
from well_founded.min_mem wf {x : α | x ∈ S ∧ x ≠ 0} h,
84-
⟨well_founded.min wf {x : α | x ∈ S ∧ x ≠ 0} h,
89+
have wf : well_founded (euclidean_domain.r : RRProp) := euclidean_domain.r_well_founded,
90+
have hmin : well_founded.min wf {x : R | x ∈ S ∧ x ≠ 0} h ∈ S ∧
91+
well_founded.min wf {x : R | x ∈ S ∧ x ≠ 0} h ≠ 0,
92+
from well_founded.min_mem wf {x : R | x ∈ S ∧ x ≠ 0} h,
93+
⟨well_founded.min wf {x : R | x ∈ S ∧ x ≠ 0} h,
8594
submodule.ext $ λ x,
86-
⟨λ hx, div_add_mod x (well_founded.min wf {x : α | x ∈ S ∧ x ≠ 0} h) ▸
87-
(mem_span_singleton.2 $ dvd_add (dvd_mul_right _ _) $
88-
have (x % (well_founded.min wf {x : α | x ∈ S ∧ x ≠ 0} h) ∉ {x : α | x ∈ S ∧ x ≠ 0}),
95+
⟨λ hx, div_add_mod x (well_founded.min wf {x : R | x ∈ S ∧ x ≠ 0} h) ▸
96+
(ideal.mem_span_singleton.2 $ dvd_add (dvd_mul_right _ _) $
97+
have (x % (well_founded.min wf {x : R | x ∈ S ∧ x ≠ 0} h) ∉ {x : R | x ∈ S ∧ x ≠ 0}),
8998
from λ h₁, well_founded.not_lt_min wf _ h h₁ (mod_lt x hmin.2),
90-
have x % well_founded.min wf {x : α | x ∈ S ∧ x ≠ 0} h = 0, by finish [(mod_mem_iff hmin.1).2 hx],
99+
have x % well_founded.min wf {x : R | x ∈ S ∧ x ≠ 0} h = 0, by finish [(mod_mem_iff hmin.1).2 hx],
91100
by simp *),
92-
λ hx, let ⟨y, hy⟩ := mem_span_singleton.1 hx in hy.symm ▸ ideal.mul_mem_right _ hmin.1⟩⟩
93-
else0, submodule.ext $ λ a, by rw [← @submodule.bot_coe α α _ _ ring.to_module, span_eq, submodule.mem_bot]; exact
101+
λ hx, let ⟨y, hy⟩ := ideal.mem_span_singleton.1 hx in hy.symm ▸ ideal.mul_mem_right _ hmin.1⟩⟩
102+
else0, submodule.ext $ λ a, by rw [← @submodule.bot_coe R R _ _ ring.to_module, span_eq, submodule.mem_bot]; exact
94103
⟨λ haS, by_contradiction $ λ ha0, h ⟨a, ⟨haS, ha0⟩⟩,
95104
λ h₁, h₁.symm ▸ S.zero_mem⟩⟩⟩ }
96105

97106
end
98107

99108

100109
namespace principal_ideal_domain
101-
variables [principal_ideal_domain α]
110+
variables [principal_ideal_domain R]
102111

103112
@[priority 100] -- see Note [lower instance priority]
104-
instance is_noetherian_ring : is_noetherian_ring α :=
105-
⟨assume s : ideal α,
113+
instance is_noetherian_ring : is_noetherian_ring R :=
114+
⟨assume s : ideal R,
106115
begin
107116
rcases (principal s).principal with ⟨a, rfl⟩,
108117
rw [← finset.coe_singleton],
@@ -111,45 +120,44 @@ end⟩
111120

112121
section
113122
open_locale classical
114-
open submodule
115123

116-
lemma factors_decreasing (b₁ b₂ : α) (h₁ : b₁ ≠ 0) (h₂ : ¬ is_unit b₂) :
117-
submodule.span α ({b₁ * b₂} : set α) < submodule.span α {b₁} :=
124+
lemma factors_decreasing (b₁ b₂ : R) (h₁ : b₁ ≠ 0) (h₂ : ¬ is_unit b₂) :
125+
submodule.span R ({b₁ * b₂} : set R) < submodule.span R {b₁} :=
118126
lt_of_le_not_le (ideal.span_le.2 $ singleton_subset_iff.2 $
119127
ideal.mem_span_singleton.2 ⟨b₂, rfl⟩) $ λ h,
120128
h₂ $ is_unit_of_dvd_one _ $ (mul_dvd_mul_iff_left h₁).1 $
121129
by rwa [mul_one, ← ideal.span_singleton_le_span_singleton]
122130

123131
end
124132

125-
lemma is_maximal_of_irreducible {p : α} (hp : irreducible p) :
126-
is_maximal (span ({p} : set α)) :=
127-
⟨mt span_singleton_eq_top.1 hp.1, λ I hI, begin
133+
lemma is_maximal_of_irreducible {p : R} (hp : irreducible p) :
134+
ideal.is_maximal (span R ({p} : set R)) :=
135+
⟨mt ideal.span_singleton_eq_top.1 hp.1, λ I hI, begin
128136
rcases principal I with ⟨a, rfl⟩,
129-
rw span_singleton_eq_top,
137+
erw ideal.span_singleton_eq_top,
130138
unfreezeI,
131-
rcases span_singleton_le_span_singleton.1 (le_of_lt hI) with ⟨b, rfl⟩,
139+
rcases ideal.span_singleton_le_span_singleton.1 (le_of_lt hI) with ⟨b, rfl⟩,
132140
refine (of_irreducible_mul hp).resolve_right (mt (λ hb, _) (not_le_of_lt hI)),
133-
rw [span_singleton_le_span_singleton, mul_dvd_of_is_unit_right hb]
141+
erw [ideal.span_singleton_le_span_singleton, mul_dvd_of_is_unit_right hb]
134142
end
135143

136-
lemma irreducible_iff_prime {p : α} : irreducible p ↔ prime p :=
137-
⟨λ hp, (span_singleton_prime hp.ne_zero).1 $
144+
lemma irreducible_iff_prime {p : R} : irreducible p ↔ prime p :=
145+
⟨λ hp, (ideal.span_singleton_prime hp.ne_zero).1 $
138146
(is_maximal_of_irreducible hp).is_prime,
139147
irreducible_of_prime⟩
140148

141-
lemma associates_irreducible_iff_prime : ∀{p : associates α}, irreducible p ↔ p.prime :=
149+
lemma associates_irreducible_iff_prime : ∀{p : associates R}, irreducible p ↔ p.prime :=
142150
associates.forall_associated.2 $ assume a,
143151
by rw [associates.irreducible_mk_iff, associates.prime_mk, irreducible_iff_prime]
144152

145153
section
146154
open_locale classical
147155

148-
noncomputable def factors (a : α) : multiset α :=
156+
noncomputable def factors (a : R) : multiset R :=
149157
if h : a = 0 thenelse classical.some
150158
(is_noetherian_ring.exists_factors a h)
151159

152-
lemma factors_spec (a : α) (h : a ≠ 0) :
160+
lemma factors_spec (a : R) (h : a ≠ 0) :
153161
(∀b∈factors a, irreducible b) ∧ associated a (factors a).prod :=
154162
begin
155163
unfold factors, rw [dif_neg h],
@@ -162,7 +170,7 @@ end
162170
This is not added as type class instance, since the `factors` might be computed in a different way.
163171
E.g. factors could return normalized values.
164172
-/
165-
noncomputable def to_unique_factorization_domain : unique_factorization_domain α :=
173+
noncomputable def to_unique_factorization_domain : unique_factorization_domain R :=
166174
{ factors := factors,
167175
factors_prod := assume a ha, associated.symm (factors_spec a ha).2,
168176
prime_factors := assume a ha, by simpa [irreducible_iff_prime] using (factors_spec a ha).1 }

0 commit comments

Comments
 (0)