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

Commit 1029974

Browse files
committed
feat(*): finite rings with char = card = n are isomorphic to zmod n (#4234)
From the Witt vector project I've made use of the opportunity to remove some unused arguments, and to clean up some code by using namespacing and such. Co-authored-by: Rob Y. Lewis <rob.y.lewis@gmail.com>
1 parent aee16bd commit 1029974

File tree

4 files changed

+181
-57
lines changed

4 files changed

+181
-57
lines changed

src/algebra/char_p.lean

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import data.nat.choose
99
import data.int.modeq
1010
import algebra.module.basic
1111
import algebra.iterate_hom
12+
import group_theory.order_of_element
13+
import algebra.group.type_tags
1214

1315
/-!
1416
# Characteristic of semirings
@@ -23,6 +25,13 @@ class char_p (α : Type u) [semiring α] (p : ℕ) : Prop :=
2325
theorem char_p.cast_eq_zero (α : Type u) [semiring α] (p : ℕ) [char_p α p] : (p:α) = 0 :=
2426
(char_p.cast_eq_zero_iff α p p).2 (dvd_refl p)
2527

28+
@[simp] lemma char_p.cast_card_eq_zero (R : Type*) [ring R] [fintype R] : (fintype.card R : R) = 0 :=
29+
begin
30+
have : fintype.card R •ℕ (1 : R) = 0 :=
31+
@pow_card_eq_one (multiplicative R) _ _ (multiplicative.of_add 1),
32+
simpa only [mul_one, nsmul_eq_mul]
33+
end
34+
2635
lemma char_p.int_cast_eq_zero_iff (R : Type u) [ring R] (p : ℕ) [char_p R p] (a : ℤ) :
2736
(a : R) = 0 ↔ (p:ℤ) ∣ a :=
2837
begin
@@ -317,3 +326,38 @@ lemma nontrivial_of_char_ne_one {v : ℕ} (hv : v ≠ 1) {R : Type*} [semiring R
317326
end char_one
318327

319328
end char_p
329+
330+
section
331+
332+
variables (n : ℕ) (R : Type*) [comm_ring R] [fintype R]
333+
334+
lemma char_p_of_ne_zero (hn : fintype.card R = n) (hR : ∀ i < n, (i : R) = 0 → i = 0) :
335+
char_p R n :=
336+
{ cast_eq_zero_iff :=
337+
begin
338+
have H : (n : R) = 0, by { rw [← hn, char_p.cast_card_eq_zero] },
339+
intro k,
340+
split,
341+
{ intro h,
342+
rw [← nat.mod_add_div k n, nat.cast_add, nat.cast_mul, H, zero_mul, add_zero] at h,
343+
rw nat.dvd_iff_mod_eq_zero,
344+
apply hR _ (nat.mod_lt _ _) h,
345+
rw [← hn, gt, fintype.card_pos_iff],
346+
exact ⟨0⟩, },
347+
{ rintro ⟨k, rfl⟩, rw [nat.cast_mul, H, zero_mul] }
348+
end }
349+
350+
lemma char_p_of_prime_pow_injective (p : ℕ) [hp : fact p.prime] (n : ℕ) (hn : fintype.card R = p ^ n)
351+
(hR : ∀ i ≤ n, (p ^ i : R) = 0 → i = n) :
352+
char_p R (p ^ n) :=
353+
begin
354+
obtain ⟨c, hc⟩ := char_p.exists R, resetI,
355+
have hcpn : c ∣ p ^ n,
356+
{ rw [← char_p.cast_eq_zero_iff R c, ← hn, char_p.cast_card_eq_zero], },
357+
obtain ⟨i, hi, hc⟩ : ∃ i ≤ n, c = p ^ i, by rwa nat.dvd_prime_pow hp at hcpn,
358+
obtain rfl : i = n,
359+
{ apply hR i hi, rw [← nat.cast_pow, ← hc, char_p.cast_eq_zero] },
360+
rwa ← hc
361+
end
362+
363+
end

src/data/equiv/ring.lean

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ instance : has_coe_to_fun (R ≃+* S) := ⟨_, ring_equiv.to_fun⟩
5353

5454
@[simp] lemma to_fun_eq_coe_fun (f : R ≃+* S) : f.to_fun = f := rfl
5555

56+
/-- Two ring isomorphisms agree if they are defined by the
57+
same underlying function. -/
58+
@[ext] lemma ext {f g : R ≃+* S} (h : ∀ x, f x = g x) : f = g :=
59+
begin
60+
have h₁ : f.to_equiv = g.to_equiv := equiv.ext h,
61+
cases f, cases g, congr,
62+
{ exact (funext h) },
63+
{ exact congr_arg equiv.inv_fun h₁ }
64+
end
65+
5666
instance has_coe_to_mul_equiv : has_coe (R ≃+* S) (R ≃* S) := ⟨ring_equiv.to_mul_equiv⟩
5767

5868
instance has_coe_to_add_equiv : has_coe (R ≃+* S) (R ≃+ S) := ⟨ring_equiv.to_add_equiv⟩
@@ -174,6 +184,10 @@ instance has_coe_to_ring_hom : has_coe (R ≃+* S) (R →+* S) := ⟨ring_equiv.
174184
@[norm_cast] lemma coe_ring_hom (f : R ≃+* S) (a : R) :
175185
(f : R →+* S) a = f a := rfl
176186

187+
lemma coe_ring_hom_inj_iff {R S : Type*} [semiring R] [semiring S] (f g : R ≃+* S) :
188+
f = g ↔ (f : R →+* S) = g :=
189+
⟨congr_arg _, λ h, ext $ ring_hom.ext_iff.mp h⟩
190+
177191
/-- Reinterpret a ring equivalence as a monoid homomorphism. -/
178192
abbreviation to_monoid_hom (e : R ≃+* S) : R →* S := e.to_ring_hom.to_monoid_hom
179193

@@ -239,16 +253,6 @@ namespace ring_equiv
239253

240254
variables [has_add R] [has_add S] [has_mul R] [has_mul S]
241255

242-
/-- Two ring isomorphisms agree if they are defined by the
243-
same underlying function. -/
244-
@[ext] lemma ext {f g : R ≃+* S} (h : ∀ x, f x = g x) : f = g :=
245-
begin
246-
have h₁ : f.to_equiv = g.to_equiv := equiv.ext h,
247-
cases f, cases g, congr,
248-
{ exact (funext h) },
249-
{ exact congr_arg equiv.inv_fun h₁ }
250-
end
251-
252256
@[simp] theorem trans_symm (e : R ≃+* S) : e.trans e.symm = ring_equiv.refl R := ext e.3
253257
@[simp] theorem symm_trans (e : R ≃+* S) : e.symm.trans e = ring_equiv.refl S := ext e.4
254258

src/data/fintype/basic.lean

Lines changed: 83 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ end set
267267
lemma finset.card_univ [fintype α] : (finset.univ : finset α).card = fintype.card α :=
268268
rfl
269269

270+
lemma finset.eq_univ_of_card [fintype α] (s : finset α) (hs : s.card = fintype.card α) :
271+
s = univ :=
272+
eq_of_subset_of_card_le (subset_univ _) $ by rw [hs, finset.card_univ]
273+
270274
lemma finset.card_le_univ [fintype α] (s : finset α) :
271275
s.card ≤ fintype.card α :=
272276
card_le_of_subset (subset_univ s)
@@ -430,75 +434,73 @@ instance (α : Type u) (β : Type v) [fintype α] [fintype β] : fintype (α ⊕
430434
((equiv.sum_equiv_sigma_bool _ _).symm.trans
431435
(equiv.sum_congr equiv.ulift equiv.ulift))
432436

433-
lemma fintype.card_le_of_injective [fintype α] [fintype β] (f : α → β)
434-
(hf : function.injective f) : fintype.card α ≤ fintype.card β :=
437+
namespace fintype
438+
variables [fintype α] [fintype β]
439+
440+
lemma card_le_of_injective (f : α → β) (hf : function.injective f) : card α ≤ card β :=
435441
finset.card_le_card_of_inj_on f (λ _ _, finset.mem_univ _) (λ _ _ _ _ h, hf h)
436442

437-
lemma fintype.card_eq_one_iff [fintype α] : fintype.card α = 1 ↔ (∃ x : α, ∀ y, y = x) :=
438-
by rw [← fintype.card_unit, fintype.card_eq]; exact
443+
lemma card_eq_one_iff : card α = 1 ↔ (∃ x : α, ∀ y, y = x) :=
444+
by rw [← card_unit, card_eq]; exact
439445
⟨λ ⟨a⟩, ⟨a.symm (), λ y, a.injective (subsingleton.elim _ _)⟩,
440446
λ ⟨x, hx⟩, ⟨⟨λ _, (), λ _, x, λ _, (hx _).trans (hx _).symm,
441447
λ _, subsingleton.elim _ _⟩⟩⟩
442448

443-
lemma fintype.card_eq_zero_iff [fintype α] : fintype.card α = 0 ↔ (α → false) :=
444-
⟨λ h a, have e : α ≃ empty := classical.choice (fintype.card_eq.1 (by simp [h])), (e a).elim,
449+
lemma card_eq_zero_iff : card α = 0 ↔ (α → false) :=
450+
⟨λ h a, have e : α ≃ empty := classical.choice (card_eq.1 (by simp [h])), (e a).elim,
445451
λ h, have e : α ≃ empty := ⟨λ a, (h a).elim, λ a, a.elim, λ a, (h a).elim, λ a, a.elim⟩,
446-
by simp [fintype.card_congr e]⟩
452+
by simp [card_congr e]⟩
447453

448454
/-- A `fintype` with cardinality zero is (constructively) equivalent to `pempty`. -/
449-
def fintype.card_eq_zero_equiv_equiv_pempty {α : Type v} [fintype α] :
450-
fintype.card α = 0 ≃ (α ≃ pempty.{v+1}) :=
455+
def card_eq_zero_equiv_equiv_pempty :
456+
card α = 0 ≃ (α ≃ pempty.{v+1}) :=
451457
{ to_fun := λ h,
452-
{ to_fun := λ a, false.elim (fintype.card_eq_zero_iff.1 h a),
458+
{ to_fun := λ a, false.elim (card_eq_zero_iff.1 h a),
453459
inv_fun := λ a, pempty.elim a,
454-
left_inv := λ a, false.elim (fintype.card_eq_zero_iff.1 h a),
460+
left_inv := λ a, false.elim (card_eq_zero_iff.1 h a),
455461
right_inv := λ a, pempty.elim a, },
456462
inv_fun := λ e,
457-
by { simp only [←fintype.of_equiv_card e], convert fintype.card_pempty, },
463+
by { simp only [←of_equiv_card e], convert card_pempty, },
458464
left_inv := λ h, rfl,
459465
right_inv := λ e, by { ext x, cases e x, } }
460466

461-
lemma fintype.card_pos_iff [fintype α] : 0 < fintype.card α ↔ nonempty α :=
467+
lemma card_pos_iff : 0 < card α ↔ nonempty α :=
462468
⟨λ h, classical.by_contradiction (λ h₁,
463-
have fintype.card α = 0 := fintype.card_eq_zero_iff.2 (λ a, h₁ ⟨a⟩),
469+
have card α = 0 := card_eq_zero_iff.2 (λ a, h₁ ⟨a⟩),
464470
lt_irrefl 0 $ by rwa this at h),
465-
λ ⟨a⟩, nat.pos_of_ne_zero (mt fintype.card_eq_zero_iff.1 (λ h, h a))⟩
471+
λ ⟨a⟩, nat.pos_of_ne_zero (mt card_eq_zero_iff.1 (λ h, h a))⟩
466472

467-
lemma fintype.card_le_one_iff [fintype α] : fintype.card α ≤ 1 ↔ (∀ a b : α, a = b) :=
468-
let n := fintype.card α in
469-
have hn : n = fintype.card α := rfl,
473+
lemma card_le_one_iff : card α ≤ 1 ↔ (∀ a b : α, a = b) :=
474+
let n := card α in
475+
have hn : n = card α := rfl,
470476
match n, hn with
471-
| 0 := λ ha, ⟨λ h, λ a, (fintype.card_eq_zero_iff.1 ha.symm a).elim, λ _, ha ▸ nat.le_succ _⟩
472-
| 1 := λ ha, ⟨λ h, λ a b, let ⟨x, hx⟩ := fintype.card_eq_one_iff.1 ha.symm in
477+
| 0 := λ ha, ⟨λ h, λ a, (card_eq_zero_iff.1 ha.symm a).elim, λ _, ha ▸ nat.le_succ _⟩
478+
| 1 := λ ha, ⟨λ h, λ a b, let ⟨x, hx⟩ := card_eq_one_iff.1 ha.symm in
473479
by rw [hx a, hx b],
474480
λ _, ha ▸ le_refl _⟩
475481
| (n+2) := λ ha, ⟨λ h, by rw ← ha at h; exact absurd h dec_trivial,
476-
(λ h, fintype.card_unit ▸ fintype.card_le_of_injective (λ _, ())
482+
(λ h, card_unit ▸ card_le_of_injective (λ _, ())
477483
(λ _ _ _, h _ _))⟩
478484
end
479485

480-
lemma fintype.card_le_one_iff_subsingleton [fintype α] :
481-
fintype.card α ≤ 1 ↔ subsingleton α :=
482-
iff.trans fintype.card_le_one_iff subsingleton_iff.symm
486+
lemma card_le_one_iff_subsingleton : card α ≤ 1 ↔ subsingleton α :=
487+
iff.trans card_le_one_iff subsingleton_iff.symm
483488

484-
lemma fintype.one_lt_card_iff_nontrivial [fintype α] :
485-
1 < fintype.card α ↔ nontrivial α :=
489+
lemma one_lt_card_iff_nontrivial : 1 < card α ↔ nontrivial α :=
486490
begin
487491
classical,
488492
rw ← not_iff_not,
489493
push_neg,
490-
rw [not_nontrivial_iff_subsingleton, fintype.card_le_one_iff_subsingleton]
494+
rw [not_nontrivial_iff_subsingleton, card_le_one_iff_subsingleton]
491495
end
492496

493-
lemma fintype.exists_ne_of_one_lt_card [fintype α] (h : 1 < fintype.card α) (a : α) :
494-
∃ b : α, b ≠ a :=
495-
by { haveI : nontrivial α := fintype.one_lt_card_iff_nontrivial.1 h, exact exists_ne a }
497+
lemma exists_ne_of_one_lt_card (h : 1 < card α) (a : α) : ∃ b : α, b ≠ a :=
498+
by { haveI : nontrivial α := one_lt_card_iff_nontrivial.1 h, exact exists_ne a }
496499

497-
lemma fintype.exists_pair_of_one_lt_card [fintype α] (h : 1 < fintype.card α) :
498-
∃ (a b : α), a ≠ b :=
499-
by { haveI : nontrivial α := fintype.one_lt_card_iff_nontrivial.1 h, exact exists_pair_ne α }
500+
lemma exists_pair_of_one_lt_card (h : 1 < card α) : ∃ (a b : α), a ≠ b :=
501+
by { haveI : nontrivial α := one_lt_card_iff_nontrivial.1 h, exact exists_pair_ne α }
500502

501-
lemma fintype.injective_iff_surjective [fintype α] {f : α → α} : injective f ↔ surjective f :=
503+
lemma injective_iff_surjective {f : α → α} : injective f ↔ surjective f :=
502504
by haveI := classical.prop_decidable; exact
503505
have ∀ {f : α → α}, injective f → surjective f,
504506
from λ f hinj x,
@@ -511,20 +513,58 @@ from λ f hinj x,
511513
⟨surj_inv hsurj, left_inverse_of_surjective_of_right_inverse
512514
(this (injective_surj_inv _)) (right_inverse_surj_inv _)⟩⟩
513515

514-
lemma fintype.injective_iff_bijective [fintype α] {f : α → α} : injective f ↔ bijective f :=
515-
by simp [bijective, fintype.injective_iff_surjective]
516+
lemma injective_iff_bijective {f : α → α} : injective f ↔ bijective f :=
517+
by simp [bijective, injective_iff_surjective]
516518

517-
lemma fintype.surjective_iff_bijective [fintype α] {f : α → α} : surjective f ↔ bijective f :=
518-
by simp [bijective, fintype.injective_iff_surjective]
519+
lemma surjective_iff_bijective {f : α → α} : surjective f ↔ bijective f :=
520+
by simp [bijective, injective_iff_surjective]
519521

520-
lemma fintype.injective_iff_surjective_of_equiv [fintype α] {f : α → β} (e : α ≃ β) :
522+
lemma injective_iff_surjective_of_equiv {β : Type*} {f : α → β} (e : α ≃ β) :
521523
injective f ↔ surjective f :=
522-
have injective (e.symm ∘ f) ↔ surjective (e.symm ∘ f), from fintype.injective_iff_surjective,
524+
have injective (e.symm ∘ f) ↔ surjective (e.symm ∘ f), from injective_iff_surjective,
523525
⟨λ hinj, by simpa [function.comp] using
524526
e.surjective.comp (this.1 (e.symm.injective.comp hinj)),
525527
λ hsurj, by simpa [function.comp] using
526528
e.injective.comp (this.2 (e.symm.surjective.comp hsurj))⟩
527529

530+
lemma nonempty_equiv_of_card_eq (h : card α = card β) :
531+
nonempty (α ≃ β) :=
532+
begin
533+
obtain ⟨m, ⟨f⟩⟩ := exists_equiv_fin α,
534+
obtain ⟨n, ⟨g⟩⟩ := exists_equiv_fin β,
535+
suffices : m = n,
536+
{ subst this, exact ⟨f.trans g.symm⟩ },
537+
calc m = card (fin m) : (card_fin m).symm
538+
... = card α : card_congr f.symm
539+
... = card β : h
540+
... = card (fin n) : card_congr g
541+
... = n : card_fin n
542+
end
543+
544+
lemma bijective_iff_injective_and_card (f : α → β) :
545+
bijective f ↔ injective f ∧ card α = card β :=
546+
begin
547+
split,
548+
{ intro h, exact ⟨h.1, card_congr (equiv.of_bijective f h)⟩ },
549+
{ rintro ⟨hf, h⟩,
550+
refine ⟨hf, _⟩,
551+
obtain ⟨e⟩ : nonempty (α ≃ β) := nonempty_equiv_of_card_eq h,
552+
rwa ← injective_iff_surjective_of_equiv e }
553+
end
554+
555+
lemma bijective_iff_surjective_and_card (f : α → β) :
556+
bijective f ↔ surjective f ∧ card α = card β :=
557+
begin
558+
split,
559+
{ intro h, exact ⟨h.2, card_congr (equiv.of_bijective f h)⟩, },
560+
{ rintro ⟨hf, h⟩,
561+
refine ⟨_, hf⟩,
562+
obtain ⟨e⟩ : nonempty (α ≃ β) := nonempty_equiv_of_card_eq h,
563+
rwa injective_iff_surjective_of_equiv e }
564+
end
565+
566+
end fintype
567+
528568
lemma fintype.coe_image_univ [fintype α] [decidable_eq β] {f : α → β} :
529569
↑(finset.image f finset.univ) = set.range f :=
530570
by { ext x, simp }
@@ -940,7 +980,7 @@ section choose
940980
open fintype
941981
open equiv
942982

943-
variables [decidable_eq α] [fintype α] (p : α → Prop) [decidable_pred p]
983+
variables [fintype α] (p : α → Prop) [decidable_pred p]
944984

945985
def choose_x (hp : ∃! a : α, p a) : {a // p a} :=
946986
⟨finset.choose p univ (by simp; exact hp), finset.choose_property _ _ _⟩
@@ -955,8 +995,8 @@ end choose
955995
section bijection_inverse
956996
open function
957997

958-
variables [decidable_eq α] [fintype α]
959-
variables [decidable_eq β] [fintype β]
998+
variables [fintype α]
999+
variables [decidable_eq β]
9601000
variables {f : α → β}
9611001

9621002
/-- `

src/data/zmod/basic.lean

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,35 @@ cast_nat_cast (dvd_refl _) k
362362
lemma cast_int_cast' (k : ℤ) : ((k : zmod n) : R) = k :=
363363
cast_int_cast (dvd_refl _) k
364364

365+
variables (R)
366+
367+
lemma cast_hom_injective : function.injective (zmod.cast_hom (dvd_refl n) R) :=
368+
begin
369+
rw ring_hom.injective_iff,
370+
intro x,
371+
obtain ⟨k, rfl⟩ := zmod.int_cast_surjective x,
372+
rw [ring_hom.map_int_cast, char_p.int_cast_eq_zero_iff R n, char_p.int_cast_eq_zero_iff (zmod n) n],
373+
exact id
374+
end
375+
376+
lemma cast_hom_bijective [fintype R] (h : fintype.card R = n) :
377+
function.bijective (zmod.cast_hom (dvd_refl n) R) :=
378+
begin
379+
haveI : fact (0 < n) :=
380+
begin
381+
rw [nat.pos_iff_ne_zero],
382+
unfreezingI { rintro rfl },
383+
exact fintype.card_eq_zero_iff.mp h 0
384+
end,
385+
rw [fintype.bijective_iff_injective_and_card, zmod.card, h, eq_self_iff_true, and_true],
386+
apply zmod.cast_hom_injective
387+
end
388+
389+
/-- The unique ring isomorphism between `zmod n` and a ring `R`
390+
of characteristic `n` and cardinality `n`. -/
391+
noncomputable def ring_equiv [fintype R] (h : fintype.card R = n) : zmod n ≃+* R :=
392+
ring_equiv.of_bijective _ (zmod.cast_hom_bijective R h)
393+
365394
end char_eq
366395

367396
end universal_property
@@ -771,20 +800,27 @@ begin
771800
rw φ.ext_int ψ,
772801
end
773802

774-
instance zmod.subsingleton_ring_hom {n : ℕ} {R : Type*} [semiring R] :
775-
subsingleton ((zmod n) →+* R) :=
803+
namespace zmod
804+
variables {n : ℕ} {R : Type*}
805+
806+
instance subsingleton_ring_hom [semiring R] : subsingleton ((zmod n) →+* R) :=
776807
⟨ring_hom.ext_zmod⟩
777808

778-
lemma zmod.ring_hom_surjective {R : Type*} [comm_ring R] {n : ℕ} (f : R →+* (zmod n)) :
809+
instance subsingleton_ring_equiv [semiring R] : subsingleton (zmod n ≃+* R) :=
810+
⟨λ f g, by { rw ring_equiv.coe_ring_hom_inj_iff, apply ring_hom.ext_zmod _ _ }⟩
811+
812+
lemma ring_hom_surjective [ring R] (f : R →+* (zmod n)) :
779813
function.surjective f :=
780814
begin
781815
intros k,
782816
rcases zmod.int_cast_surjective k with ⟨n, rfl⟩,
783817
refine ⟨n, f.map_int_cast n⟩
784818
end
785819

786-
lemma zmod.ring_hom_eq_of_ker_eq {R : Type*} [comm_ring R] {n : ℕ} (f g : R →+* (zmod n))
820+
lemma ring_hom_eq_of_ker_eq [comm_ring R] (f g : R →+* (zmod n))
787821
(h : f.ker = g.ker) : f = g :=
788822
by rw [← f.lift_of_surjective_comp (zmod.ring_hom_surjective f) g (le_of_eq h),
789823
ring_hom.ext_zmod (f.lift_of_surjective _ _ _) (ring_hom.id _),
790824
ring_hom.id_comp]
825+
826+
end zmod

0 commit comments

Comments
 (0)