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

Commit d1b34f7

Browse files
committed
feat(ring_theory): define the ideal class group (#8626)
This PR defines the ideal class group of an integral domain, as the quotient of the invertible fractional ideals by the principal fractional ideals. It also shows that this corresponds to the more traditional definition in a Dedekind domain, namely the quotient of the nonzero ideals by `I ~ J ↔ ∃ xy, xI = yJ`. Co-Authored-By: Ashvni ashvni.n@gmail.com Co-Authored-By: Filippo A. E. Nuccio filippo.nuccio@univ-st-etienne.fr Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>
1 parent a0aee51 commit d1b34f7

File tree

6 files changed

+299
-22
lines changed

6 files changed

+299
-22
lines changed

src/ring_theory/class_group.lean

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/-
2+
Copyright (c) 2021 Anne Baanen. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Anne Baanen
5+
-/
6+
7+
import group_theory.quotient_group
8+
import ring_theory.dedekind_domain
9+
10+
/-!
11+
# The ideal class group
12+
13+
This file defines the ideal class group `class_group R K` of fractional ideals of `R`
14+
inside `A`'s field of fractions `K`.
15+
16+
## Main definitions
17+
- `to_principal_ideal` sends an invertible `x : K` to an invertible fractional ideal
18+
- `class_group` is the quotient of invertible fractional ideals modulo `to_principal_ideal.range`
19+
- `class_group.mk0` sends a nonzero integral ideal in a Dedekind domain to its class
20+
21+
## Main results
22+
- `class_group.mk0_eq_mk0_iff` shows the equivalence with the "classical" definition,
23+
where `I ~ J` iff `x I = y J` for `x y ≠ (0 : R)`
24+
-/
25+
26+
section integral_domain
27+
28+
variables {R K L : Type*} [integral_domain R]
29+
variables [field K] [field L] [decidable_eq L]
30+
variables [algebra R K] [is_fraction_ring R K]
31+
variables [algebra K L] [finite_dimensional K L]
32+
variables [algebra R L] [is_scalar_tower R K L]
33+
34+
open_locale non_zero_divisors
35+
36+
open is_localization is_fraction_ring fractional_ideal units
37+
38+
section
39+
40+
variables (R K)
41+
42+
/-- `to_principal_ideal R K x` sends `x ≠ 0 : K` to the fractional `R`-ideal generated by `x` -/
43+
@[irreducible]
44+
def to_principal_ideal : units K →* units (fractional_ideal R⁰ K) :=
45+
{ to_fun := λ x,
46+
⟨span_singleton _ x,
47+
span_singleton _ x⁻¹,
48+
by simp only [span_singleton_one, units.mul_inv', span_singleton_mul_span_singleton],
49+
by simp only [span_singleton_one, units.inv_mul', span_singleton_mul_span_singleton]⟩,
50+
map_mul' := λ x y, ext
51+
(by simp only [units.coe_mk, units.coe_mul, span_singleton_mul_span_singleton]),
52+
map_one' := ext (by simp only [span_singleton_one, units.coe_mk, units.coe_one]) }
53+
54+
local attribute [semireducible] to_principal_ideal
55+
56+
variables {R K}
57+
58+
@[simp] lemma coe_to_principal_ideal (x : units K) :
59+
(to_principal_ideal R K x : fractional_ideal R⁰ K) = span_singleton _ x :=
60+
rfl
61+
62+
@[simp] lemma to_principal_ideal_eq_iff {I : units (fractional_ideal R⁰ K)} {x : units K} :
63+
to_principal_ideal R K x = I ↔ span_singleton R⁰ (x : K) = I :=
64+
units.ext_iff
65+
66+
end
67+
68+
instance principal_ideals.normal : (to_principal_ideal R K).range.normal :=
69+
subgroup.normal_of_comm _
70+
71+
section
72+
73+
variables (R K)
74+
75+
/-- The ideal class group of `R` in a field of fractions `K`
76+
is the group of invertible fractional ideals modulo the principal ideals. -/
77+
@[derive(comm_group)]
78+
def class_group := quotient_group.quotient (to_principal_ideal R K).range
79+
80+
instance : inhabited (class_group R K) := ⟨1
81+
82+
variables {R}
83+
84+
/-- Send a nonzero integral ideal to an invertible fractional ideal. -/
85+
@[simps]
86+
noncomputable def fractional_ideal.mk0 [is_dedekind_domain R] :
87+
(ideal R)⁰ →* units (fractional_ideal R⁰ K) :=
88+
{ to_fun := λ I, units.mk0 I ((fractional_ideal.coe_to_fractional_ideal_ne_zero (le_refl R⁰)).mpr
89+
(mem_non_zero_divisors_iff_ne_zero.mp I.2)),
90+
map_one' := by simp,
91+
map_mul' := λ x y, by simp }
92+
93+
/-- Send a nonzero ideal to the corresponding class in the class group. -/
94+
@[simps]
95+
noncomputable def class_group.mk0 [is_dedekind_domain R] :
96+
(ideal R)⁰ →* class_group R K :=
97+
(quotient_group.mk' _).comp (fractional_ideal.mk0 K)
98+
99+
variables {K}
100+
101+
lemma quotient_group.mk'_eq_mk' {G : Type*} [group G] {N : subgroup G} [hN : N.normal] {x y : G} :
102+
quotient_group.mk' N x = quotient_group.mk' N y ↔ ∃ z ∈ N, x * z = y :=
103+
(@quotient.eq _ (quotient_group.left_rel _) _ _).trans
104+
⟨λ (h : x⁻¹ * y ∈ N), ⟨_, h, by rw [← mul_assoc, mul_right_inv, one_mul]⟩,
105+
λ ⟨z, z_mem, eq_y⟩,
106+
by { rw ← eq_y, show x⁻¹ * (x * z) ∈ N, rwa [← mul_assoc, mul_left_inv, one_mul] }⟩
107+
108+
lemma class_group.mk0_eq_mk0_iff_exists_fraction_ring [is_dedekind_domain R] {I J : (ideal R)⁰} :
109+
class_group.mk0 K I = class_group.mk0 K J ↔
110+
∃ (x ≠ (0 : K)), span_singleton R⁰ x * I = J :=
111+
begin
112+
simp only [class_group.mk0, monoid_hom.comp_apply, quotient_group.mk'_eq_mk'],
113+
split,
114+
{ rintros ⟨_, ⟨x, rfl⟩, hx⟩,
115+
refine ⟨x, x.ne_zero, _⟩,
116+
simpa only [mul_comm, coe_mk0, monoid_hom.to_fun_eq_coe, coe_to_principal_ideal, units.coe_mul]
117+
using congr_arg (coe : _ → fractional_ideal R⁰ K) hx },
118+
{ rintros ⟨x, hx, eq_J⟩,
119+
refine ⟨_, ⟨units.mk0 x hx, rfl⟩, units.ext _⟩,
120+
simpa only [fractional_ideal.mk0_apply, units.coe_mk0, mul_comm, coe_to_principal_ideal,
121+
coe_coe, units.coe_mul] using eq_J }
122+
end
123+
124+
lemma class_group.mk0_eq_mk0_iff [is_dedekind_domain R] {I J : (ideal R)⁰} :
125+
class_group.mk0 K I = class_group.mk0 K J ↔
126+
∃ (x y : R) (hx : x ≠ 0) (hy : y ≠ 0), ideal.span {x} * (I : ideal R) = ideal.span {y} * J :=
127+
begin
128+
refine class_group.mk0_eq_mk0_iff_exists_fraction_ring.trans ⟨_, _⟩,
129+
{ rintros ⟨z, hz, h⟩,
130+
obtain ⟨x, ⟨y, hy⟩, rfl⟩ := is_localization.mk'_surjective R⁰ z,
131+
refine ⟨x, y, _, mem_non_zero_divisors_iff_ne_zero.mp hy, _⟩,
132+
{ rintro hx, apply hz,
133+
rw [hx, is_fraction_ring.mk'_eq_div, (algebra_map R K).map_zero, zero_div] },
134+
{ exact (fractional_ideal.mk'_mul_coe_ideal_eq_coe_ideal K hy).mp h } },
135+
{ rintros ⟨x, y, hx, hy, h⟩,
136+
have hy' : y ∈ R⁰ := mem_non_zero_divisors_iff_ne_zero.mpr hy,
137+
refine ⟨is_localization.mk' K x ⟨y, hy'⟩, _, _⟩,
138+
{ contrapose! hx,
139+
rwa [is_localization.mk'_eq_iff_eq_mul, zero_mul, ← (algebra_map R K).map_zero,
140+
(is_fraction_ring.injective R K).eq_iff] at hx },
141+
{ exact (fractional_ideal.mk'_mul_coe_ideal_eq_coe_ideal K hy').mpr h } },
142+
end
143+
144+
lemma class_group.mk0_surjective [is_dedekind_domain R] :
145+
function.surjective (class_group.mk0 K : (ideal R)⁰ → class_group R K) :=
146+
begin
147+
rintros ⟨I⟩,
148+
obtain ⟨a, a_ne_zero', ha⟩ := I.1.2,
149+
have a_ne_zero := mem_non_zero_divisors_iff_ne_zero.mp a_ne_zero',
150+
have fa_ne_zero : (algebra_map R K) a ≠ 0 :=
151+
is_fraction_ring.to_map_ne_zero_of_mem_non_zero_divisors a_ne_zero',
152+
refine ⟨⟨{ carrier := { x | (algebra_map R K a)⁻¹ * algebra_map R K x ∈ I.1 }, .. }, _⟩, _⟩,
153+
{ simp only [ring_hom.map_zero, set.mem_set_of_eq, mul_zero, ring_hom.map_mul],
154+
exact submodule.zero_mem I },
155+
{ simp only [ring_hom.map_add, set.mem_set_of_eq, mul_zero, ring_hom.map_mul, mul_add],
156+
exact λ _ _ ha hb, submodule.add_mem I ha hb },
157+
{ intros c _ hb,
158+
simp only [smul_eq_mul, set.mem_set_of_eq, mul_zero, ring_hom.map_mul, mul_add,
159+
mul_left_comm ((algebra_map R K) a)⁻¹],
160+
rw ← algebra.smul_def c,
161+
exact submodule.smul_mem I c hb },
162+
{ rw [mem_non_zero_divisors_iff_ne_zero, submodule.zero_eq_bot, submodule.ne_bot_iff],
163+
obtain ⟨x, x_ne, x_mem⟩ := exists_ne_zero_mem_is_integer I.ne_zero,
164+
refine ⟨a * x, _, mul_ne_zero a_ne_zero x_ne⟩,
165+
change ((algebra_map R K) a)⁻¹ * (algebra_map R K) (a * x) ∈ I.1,
166+
rwa [ring_hom.map_mul, ← mul_assoc, inv_mul_cancel fa_ne_zero, one_mul] },
167+
{ symmetry,
168+
apply quotient.sound,
169+
refine ⟨units.mk0 (algebra_map R K a) fa_ne_zero, _⟩,
170+
apply @mul_left_cancel _ _ I,
171+
rw [← mul_assoc, mul_right_inv, one_mul, eq_comm, mul_comm I],
172+
apply units.ext,
173+
simp only [monoid_hom.coe_mk, subtype.coe_mk, ring_hom.map_mul, coe_coe,
174+
units.coe_mul, coe_to_principal_ideal, coe_mk0,
175+
fractional_ideal.eq_span_singleton_mul],
176+
split,
177+
{ intros zJ' hzJ',
178+
obtain ⟨zJ, hzJ : (algebra_map R K a)⁻¹ * algebra_map R K zJ ∈ ↑I, rfl⟩ :=
179+
(mem_coe_ideal R⁰).mp hzJ',
180+
refine ⟨_, hzJ, _⟩,
181+
rw [← mul_assoc, mul_inv_cancel fa_ne_zero, one_mul] },
182+
{ intros zI' hzI',
183+
obtain ⟨y, hy⟩ := ha zI' hzI',
184+
rw [← algebra.smul_def, fractional_ideal.mk0_apply, coe_mk0, coe_coe, mem_coe_ideal],
185+
refine ⟨y, _, hy⟩,
186+
show (algebra_map R K a)⁻¹ * algebra_map R K y ∈ (I : fractional_ideal R⁰ K),
187+
rwa [hy, algebra.smul_def, ← mul_assoc, inv_mul_cancel fa_ne_zero, one_mul] } }
188+
end
189+
190+
end
191+
192+
lemma class_group.mk_eq_one_iff
193+
{I : units (fractional_ideal R⁰ K)} :
194+
quotient_group.mk' (to_principal_ideal R K).range I = 1
195+
(I : submodule R K).is_principal :=
196+
begin
197+
rw [← (quotient_group.mk' _).map_one, eq_comm, quotient_group.mk'_eq_mk'],
198+
simp only [exists_prop, one_mul, exists_eq_right, to_principal_ideal_eq_iff,
199+
monoid_hom.mem_range, coe_coe],
200+
refine ⟨λ ⟨x, hx⟩, ⟨⟨x, by rw [← hx, coe_span_singleton]⟩⟩, _⟩,
201+
unfreezingI { intros hI },
202+
obtain ⟨x, hx⟩ := @submodule.is_principal.principal _ _ _ _ _ _ hI,
203+
have hx' : (I : fractional_ideal R⁰ K) = span_singleton R⁰ x,
204+
{ apply subtype.coe_injective, rw [hx, coe_span_singleton] },
205+
refine ⟨units.mk0 x _, _⟩,
206+
{ intro x_eq, apply units.ne_zero I, simp [hx', x_eq] },
207+
simp [hx']
208+
end
209+
210+
lemma class_group.mk0_eq_one_iff [is_dedekind_domain R]
211+
{I : ideal R} (hI : I ∈ (ideal R)⁰) :
212+
class_group.mk0 K ⟨I, hI⟩ = 1 ↔ I.is_principal :=
213+
class_group.mk_eq_one_iff.trans (coe_submodule_is_principal R K)
214+
215+
/-- The class group of principal ideal domain is finite (in fact a singleton).
216+
TODO: generalize to Dedekind domains -/
217+
instance [is_principal_ideal_ring R] :
218+
fintype (class_group R K) :=
219+
{ elems := {1},
220+
complete :=
221+
begin
222+
rintros ⟨I⟩,
223+
rw [finset.mem_singleton],
224+
exact class_group.mk_eq_one_iff.mpr (I : fractional_ideal R⁰ K).is_principal
225+
end }
226+
227+
/-- The class number of a principal ideal domain is `1`. -/
228+
lemma card_class_group_eq_one [is_principal_ideal_ring R] :
229+
fintype.card (class_group R K) = 1 :=
230+
begin
231+
rw fintype.card_eq_one_iff,
232+
use 1,
233+
rintros ⟨I⟩,
234+
exact class_group.mk_eq_one_iff.mpr (I : fractional_ideal R⁰ K).is_principal
235+
end
236+
237+
/-- The class number is `1` iff the ring of integers is a principal ideal domain. -/
238+
lemma card_class_group_eq_one_iff [is_dedekind_domain R] [fintype (class_group R K)] :
239+
fintype.card (class_group R K) = 1 ↔ is_principal_ideal_ring R :=
240+
begin
241+
split, swap, { introsI, convert card_class_group_eq_one, assumption },
242+
rw fintype.card_eq_one_iff,
243+
rintros ⟨I, hI⟩,
244+
have eq_one : ∀ J : class_group R K, J = 1 := λ J, trans (hI J) (hI 1).symm,
245+
refine ⟨λ I, _⟩,
246+
by_cases hI : I = ⊥,
247+
{ rw hI, exact bot_is_principal },
248+
exact (class_group.mk0_eq_one_iff (mem_non_zero_divisors_iff_ne_zero.mpr hI)).mp (eq_one _),
249+
end
250+
251+
end integral_domain

src/ring_theory/dedekind_domain.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ dedekind domain, dedekind ring
4646

4747
variables (R A K : Type*) [comm_ring R] [integral_domain A] [field K]
4848

49-
local notation R`⁰`:9000 := non_zero_divisors R
49+
open_locale non_zero_divisors
5050

5151
/-- A ring `R` has Krull dimension at most one if all nonzero prime ideals are maximal. -/
5252
def ring.dimension_le_one : Prop :=

src/ring_theory/fractional_ideal.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fractional ideal, fractional ideals, invertible ideal
6666
open is_localization
6767
open_locale pointwise
6868

69-
local notation R`⁰`:9000 := non_zero_divisors R
69+
open_locale non_zero_divisors
7070

7171
section defs
7272

src/ring_theory/localization.lean

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,16 @@ lemma mk'_spec' (x) (y : M) :
266266
algebra_map R S y * mk' S x y = algebra_map R S x :=
267267
(to_localization_map M S).mk'_spec' _ _
268268

269+
@[simp]
270+
lemma mk'_spec_mk (x) (y : R) (hy : y ∈ M) :
271+
mk' S x ⟨y, hy⟩ * algebra_map R S y = algebra_map R S x :=
272+
mk'_spec S x ⟨y, hy⟩
273+
274+
@[simp]
275+
lemma mk'_spec'_mk (x) (y : R) (hy : y ∈ M) :
276+
algebra_map R S y * mk' S x ⟨y, hy⟩ = algebra_map R S x :=
277+
mk'_spec' S x ⟨y, hy⟩
278+
269279
variables {S}
270280

271281
theorem eq_mk'_iff_mul_eq {x} {y : M} {z} :
@@ -1502,10 +1512,15 @@ lemma mk'_mk_eq_div {r s} (hs : s ∈ non_zero_divisors A) :
15021512
mk'_eq_iff_eq_mul.2 $ (div_mul_cancel (algebra_map A K r)
15031513
(is_fraction_ring.to_map_ne_zero_of_mem_non_zero_divisors hs)).symm
15041514

1505-
lemma mk'_eq_div {r} (s : non_zero_divisors A) :
1515+
@[simp] lemma mk'_eq_div {r} (s : non_zero_divisors A) :
15061516
mk' K r s = algebra_map A K r / algebra_map A K s :=
15071517
mk'_mk_eq_div s.2
15081518

1519+
lemma div_surjective (z : K) : ∃ (x y : A) (hy : y ∈ non_zero_divisors A),
1520+
algebra_map _ _ x / algebra_map _ _ y = z :=
1521+
let ⟨x, ⟨y, hy⟩, h⟩ := mk'_surjective (non_zero_divisors A) z
1522+
in ⟨x, y, hy, by rwa mk'_eq_div at h⟩
1523+
15091524
lemma is_unit_map_of_injective (hg : function.injective g)
15101525
(y : non_zero_divisors A) : is_unit (g y) :=
15111526
is_unit.mk0 (g y) $ show g.to_monoid_with_zero_hom y ≠ 0,
@@ -1518,19 +1533,21 @@ such that `z = f x * (f y)⁻¹`. -/
15181533
noncomputable def lift (hg : injective g) : K →+* L :=
15191534
lift $ λ (y : non_zero_divisors A), is_unit_map_of_injective hg y
15201535

1536+
/-- Given an integral domain `A` with field of fractions `K`,
1537+
and an injective ring hom `g : A →+* L` where `L` is a field,
1538+
the field hom induced from `K` to `L` maps `x` to `g x` for all
1539+
`x : A`. -/
1540+
@[simp] lemma lift_algebra_map (hg : injective g) (x) :
1541+
lift hg (algebra_map A K x) = g x :=
1542+
lift_eq _ _
1543+
15211544
/-- Given an integral domain `A` with field of fractions `K`,
15221545
and an injective ring hom `g : A →+* L` where `L` is a field,
15231546
field hom induced from `K` to `L` maps `f x / f y` to `g x / g y` for all
15241547
`x : A, y ∈ non_zero_divisors A`. -/
1525-
@[simp] lemma lift_mk' (hg : injective g) (x) (y : non_zero_divisors A) :
1548+
lemma lift_mk' (hg : injective g) (x) (y : non_zero_divisors A) :
15261549
lift hg (mk' K x y) = g x / g y :=
1527-
begin
1528-
erw lift_mk' (is_unit_map_of_injective hg),
1529-
erw submonoid.localization_map.mul_inv_left
1530-
(λ y : non_zero_divisors A, show is_unit (g.to_monoid_hom y), from
1531-
is_unit_map_of_injective hg y),
1532-
exact (mul_div_cancel' _ (g.map_ne_zero_of_mem_non_zero_divisors hg y.2)).symm,
1533-
end
1550+
by simp only [mk'_eq_div, ring_hom.map_div, lift_algebra_map]
15341551

15351552
/-- Given integral domains `A, B` with fields of fractions `K`, `L`
15361553
and an injective ring hom `j : A →+* B`, we get a field hom

0 commit comments

Comments
 (0)