Skip to content

Commit 5759937

Browse files
feat: add API for multiplicative characters (#13392)
This adds some API lemmas for multiplicative characters. We also remove a couple of porting notes (the previous proof lines work again).
1 parent 668bf7f commit 5759937

File tree

2 files changed

+84
-41
lines changed

2 files changed

+84
-41
lines changed

Mathlib/Algebra/Group/Hom/Instances.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ theorem AddMonoid.End.intCast_apply [AddCommGroup M] (z : ℤ) (m : M) :
106106
@[deprecated (since := "2024-04-17")]
107107
alias AddMonoid.End.int_cast_apply := AddMonoid.End.intCast_apply
108108

109+
@[to_additive (attr := simp)] lemma MonoidHom.pow_apply {M N : Type*} [MulOneClass M]
110+
[CommMonoid N] (f : M →* N) (n : ℕ) (x : M) :
111+
(f ^ n) x = (f x) ^ n :=
112+
rfl
113+
109114
/-!
110115
### Morphisms of morphisms
111116

Mathlib/NumberTheory/LegendreSymbol/MulCharacter.lean

Lines changed: 79 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Michael Stoll
55
-/
66
import Mathlib.Algebra.CharP.Basic
7-
import Mathlib.Algebra.EuclideanDomain.Instances
87
import Mathlib.Data.Fintype.Units
98

109
#align_import number_theory.legendre_symbol.mul_character from "leanprover-community/mathlib"@"f0c8bf9245297a541f468be517f1bde6195105e9"
@@ -37,8 +36,6 @@ multiplicative character
3736
-/
3837

3938

40-
section DefinitionAndGroup
41-
4239
/-!
4340
### Definitions related to multiplicative characters
4441
@@ -54,15 +51,13 @@ have a natural structure as a commutative group.
5451
-/
5552

5653

57-
universe u v
58-
5954
section Defi
6055

6156
-- The domain of our multiplicative characters
62-
variable (R : Type u) [CommMonoid R]
57+
variable (R : Type*) [CommMonoid R]
6358

6459
-- The target
65-
variable (R' : Type v) [CommMonoidWithZero R']
60+
variable (R' : Type*) [CommMonoidWithZero R']
6661

6762
/-- Define a structure for multiplicative characters.
6863
A multiplicative character from a commutative monoid `R` to a commutative monoid with zero `R'`
@@ -87,20 +82,17 @@ attribute [simp] MulCharClass.map_nonunit
8782

8883
end Defi
8984

90-
section Group
91-
9285
namespace MulChar
9386

87+
section Group
88+
9489
-- The domain of our multiplicative characters
95-
variable {R : Type u} [CommMonoid R]
90+
variable {R : Type*} [CommMonoid R]
9691

9792
-- The target
98-
variable {R' : Type v} [CommMonoidWithZero R']
99-
100-
section trivial
101-
102-
variable (R R')
93+
variable {R' : Type*} [CommMonoidWithZero R']
10394

95+
variable (R R') in
10496
/-- The trivial multiplicative character. It takes the value `0` on non-units and
10597
the value `1` on units. -/
10698
@[simps]
@@ -117,8 +109,6 @@ noncomputable def trivial : MulChar R R' where
117109
split_ifs <;> tauto
118110
#align mul_char.trivial MulChar.trivial
119111

120-
end trivial
121-
122112
@[simp]
123113
theorem coe_mk (f : R →* R') (hf) : (MulChar.mk f hf : R → R') = f :=
124114
rfl
@@ -251,7 +241,7 @@ protected theorem map_one (χ : MulChar R R') : χ (1 : R) = 1 :=
251241
#align mul_char.map_one MulChar.map_one
252242

253243
/-- If the domain has a zero (and is nontrivial), then `χ 0 = 0`. -/
254-
protected theorem map_zero {R : Type u} [CommMonoidWithZero R] [Nontrivial R] (χ : MulChar R R') :
244+
protected theorem map_zero {R : Type*} [CommMonoidWithZero R] [Nontrivial R] (χ : MulChar R R') :
255245
χ (0 : R) = 0 := by rw [map_nonunit χ not_isUnit_zero]
256246
#align mul_char.map_zero MulChar.map_zero
257247

@@ -266,7 +256,7 @@ def toMonoidWithZeroHom {R : Type*} [CommMonoidWithZero R] [Nontrivial R] (χ :
266256
map_mul' := χ.map_mul'
267257

268258
/-- If the domain is a ring `R`, then `χ (ringChar R) = 0`. -/
269-
theorem map_ringChar {R : Type u} [CommRing R] [Nontrivial R] (χ : MulChar R R') :
259+
theorem map_ringChar {R : Type*} [CommRing R] [Nontrivial R] (χ : MulChar R R') :
270260
χ (ringChar R) = 0 := by rw [ringChar.Nat.cast_ringChar, χ.map_zero]
271261
#align mul_char.map_ring_char MulChar.map_ringChar
272262

@@ -334,23 +324,20 @@ theorem inv_apply_eq_inv (χ : MulChar R R') (a : R) : χ⁻¹ a = Ring.inverse
334324

335325
/-- The inverse of a multiplicative character `χ`, applied to `a`, is the inverse of `χ a`.
336326
Variant when the target is a field -/
337-
theorem inv_apply_eq_inv' {R' : Type v} [Field R'] (χ : MulChar R R') (a : R) : χ⁻¹ a = (χ a)⁻¹ :=
327+
theorem inv_apply_eq_inv' {R' : Type*} [Field R'] (χ : MulChar R R') (a : R) : χ⁻¹ a = (χ a)⁻¹ :=
338328
(inv_apply_eq_inv χ a).trans <| Ring.inverse_eq_inv (χ a)
339329
#align mul_char.inv_apply_eq_inv' MulChar.inv_apply_eq_inv'
340330

341331
/-- When the domain has a zero, then the inverse of a multiplicative character `χ`,
342332
applied to `a`, is `χ` applied to the inverse of `a`. -/
343-
theorem inv_apply {R : Type u} [CommMonoidWithZero R] (χ : MulChar R R') (a : R) :
333+
theorem inv_apply {R : Type*} [CommMonoidWithZero R] (χ : MulChar R R') (a : R) :
344334
χ⁻¹ a = χ (Ring.inverse a) := by
345335
by_cases ha : IsUnit a
346336
· rw [inv_apply_eq_inv]
347337
have h := IsUnit.map χ ha
348338
apply_fun (χ a * ·) using IsUnit.mul_right_injective h
349339
dsimp only
350-
-- Porting note: was
351-
-- rw [Ring.mul_inverse_cancel _ h, ← map_mul, Ring.mul_inverse_cancel _ ha, MulChar.map_one]
352-
erw [Ring.mul_inverse_cancel _ h, ← map_mul, Ring.mul_inverse_cancel _ ha]
353-
exact (MulChar.map_one χ).symm
340+
rw [Ring.mul_inverse_cancel _ h, ← map_mul, Ring.mul_inverse_cancel _ ha, map_one]
354341
· revert ha
355342
nontriviality R
356343
intro ha
@@ -360,7 +347,7 @@ theorem inv_apply {R : Type u} [CommMonoidWithZero R] (χ : MulChar R R') (a : R
360347

361348
/-- When the domain has a zero, then the inverse of a multiplicative character `χ`,
362349
applied to `a`, is `χ` applied to the inverse of `a`. -/
363-
theorem inv_apply' {R : Type u} [Field R] (χ : MulChar R R') (a : R) : χ⁻¹ a = χ a⁻¹ :=
350+
theorem inv_apply' {R : Type*} [Field R] (χ : MulChar R R') (a : R) : χ⁻¹ a = χ a⁻¹ :=
364351
(inv_apply χ a).trans <| congr_arg _ (Ring.inverse_eq_inv a)
365352
#align mul_char.inv_apply' MulChar.inv_apply'
366353

@@ -369,9 +356,7 @@ theorem inv_apply' {R : Type u} [Field R] (χ : MulChar R R') (a : R) : χ⁻¹
369356
theorem inv_mul (χ : MulChar R R') : χ⁻¹ * χ = 1 := by
370357
ext x
371358
rw [coeToFun_mul, Pi.mul_apply, inv_apply_eq_inv]
372-
-- Porting note: was
373-
-- simp only [Ring.inverse_mul_cancel _ (IsUnit.map _ x.isUnit)]
374-
erw [Ring.inverse_mul_cancel _ (IsUnit.map χ x.isUnit)]
359+
simp only [Ring.inverse_mul_cancel _ (IsUnit.map χ x.isUnit)]
375360
rw [one_apply_coe]
376361
#align mul_char.inv_mul MulChar.inv_mul
377362

@@ -407,11 +392,27 @@ theorem pow_apply' (χ : MulChar R R') {n : ℕ} (hn : n ≠ 0) (a : R) : (χ ^
407392
· rw [map_nonunit (χ ^ n) ha, map_nonunit χ ha, zero_pow hn]
408393
#align mul_char.pow_apply' MulChar.pow_apply'
409394

410-
end MulChar
395+
lemma equivToUnitHom_mul_apply (χ₁ χ₂ : MulChar R R') (a : Rˣ) :
396+
equivToUnitHom (χ₁ * χ₂) a = equivToUnitHom χ₁ a * equivToUnitHom χ₂ a := by
397+
apply_fun ((↑) : R'ˣ → R') using Units.ext
398+
push_cast
399+
simp_rw [coe_equivToUnitHom]
400+
rfl
401+
402+
/-- The equivalence between multiplicative characters and homomorphisms of unit groups
403+
as a multiplicative equivalence. -/
404+
noncomputable
405+
def mulEquivToUnitHom : MulChar R R' ≃* (Rˣ →* R'ˣ) :=
406+
{ equivToUnitHom with
407+
map_mul' := by
408+
intro χ ψ
409+
ext
410+
simp only [Equiv.toFun_as_coe, coe_equivToUnitHom, coeToFun_mul, Pi.mul_apply,
411+
MonoidHom.mul_apply, Units.val_mul]
412+
}
411413

412414
end Group
413415

414-
end DefinitionAndGroup
415416

416417
/-!
417418
### Properties of multiplicative characters
@@ -425,13 +426,9 @@ We now (mostly) assume that the target is a commutative ring.
425426

426427
section Properties
427428

428-
namespace MulChar
429-
430-
universe u v w
431-
432429
section nontrivial
433430

434-
variable {R : Type u} [CommMonoid R] {R' : Type v} [CommMonoidWithZero R']
431+
variable {R : Type*} [CommMonoid R] {R' : Type*} [CommMonoidWithZero R']
435432

436433
/-- A multiplicative character is *nontrivial* if it takes a value `≠ 1` on a unit. -/
437434
def IsNontrivial (χ : MulChar R R') : Prop :=
@@ -447,7 +444,7 @@ end nontrivial
447444

448445
section quadratic_and_comp
449446

450-
variable {R : Type u} [CommMonoid R] {R' : Type v} [CommRing R'] {R'' : Type w} [CommRing R'']
447+
variable {R : Type*} [CommMonoid R] {R' : Type*} [CommRing R'] {R'' : Type*} [CommRing R'']
451448

452449
/-- A multiplicative character is *quadratic* if it takes only the values `0`, `1`, `-1`. -/
453450
def IsQuadratic (χ : MulChar R R') : Prop :=
@@ -532,17 +529,46 @@ theorem IsQuadratic.pow_odd {χ : MulChar R R'} (hχ : χ.IsQuadratic) {n : ℕ}
532529

533530
end quadratic_and_comp
534531

532+
end Properties
533+
534+
/-!
535+
### Multiplicative characters with finite domain
536+
-/
537+
538+
section Finite
539+
540+
variable {M : Type*} [CommMonoid M] [Fintype M] [DecidableEq M]
541+
variable {R : Type*} [CommMonoidWithZero R]
542+
543+
/-- A multiplicative character on a finite commutative monoid has finite (= positive) order. -/
544+
lemma orderOf_pos (χ : MulChar M R) : 0 < orderOf χ := by
545+
let e := MulChar.mulEquivToUnitHom (R := M) (R' := R)
546+
rw [← MulEquiv.orderOf_eq e χ]
547+
have : orderOf (e χ) ∣ Fintype.card Mˣ := by
548+
refine orderOf_dvd_of_pow_eq_one ?_
549+
ext1 x
550+
simp only [MonoidHom.pow_apply, ← map_pow (e χ), pow_card_eq_one, map_one, MonoidHom.one_apply]
551+
exact Nat.pos_of_ne_zero <| ne_zero_of_dvd_ne_zero Fintype.card_ne_zero this
552+
553+
/-- If `χ` is a multiplicative character on a finite commutative monoid `M`, then `χ ^ #Mˣ = 1`. -/
554+
protected
555+
lemma pow_card_eq_one (χ : MulChar M R) : χ ^ (Fintype.card Mˣ) = 1 := by
556+
ext1
557+
rw [pow_apply_coe, ← map_pow, one_apply_coe, ← Units.val_pow_eq_pow_val, pow_card_eq_one,
558+
Units.val_eq_one.mpr rfl, map_one]
559+
560+
end Finite
561+
535562
section sum
536563

537-
variable {R : Type u} [CommMonoid R] [Fintype R] {R' : Type v} [CommRing R']
564+
variable {R : Type*} [CommMonoid R] [Fintype R] {R' : Type*} [CommRing R']
538565

539566
/-- The sum over all values of a nontrivial multiplicative character on a finite ring is zero
540567
(when the target is a domain). -/
541568
theorem IsNontrivial.sum_eq_zero [IsDomain R'] {χ : MulChar R R'}
542569
(hχ : χ.IsNontrivial) : ∑ a, χ a = 0 := by
543570
rcases hχ with ⟨b, hb⟩
544571
refine eq_zero_of_mul_eq_self_left hb ?_
545-
-- POrting note: `map_mul` isn't applied
546572
simp only [Finset.mul_sum, ← map_mul]
547573
exact Fintype.sum_bijective _ (Units.mulLeft_bijective b) _ _ fun x => rfl
548574
#align mul_char.is_nontrivial.sum_eq_zero MulChar.IsNontrivial.sum_eq_zero
@@ -568,6 +594,18 @@ theorem sum_one_eq_card_units [DecidableEq R] :
568594

569595
end sum
570596

571-
end MulChar
597+
/-!
598+
### Multiplicative characters on rings
599+
-/
572600

573-
end Properties
601+
section Ring
602+
603+
variable {R R' : Type*} [CommRing R] [CommMonoidWithZero R']
604+
605+
/-- If `χ` is of odd order, then `χ(-1) = 1` -/
606+
lemma val_neg_one_eq_one_of_odd_order {χ : MulChar R R'} {n : ℕ} (hn : Odd n) (hχ : χ ^ n = 1) :
607+
χ (-1) = 1 := by
608+
rw [← hn.neg_one_pow, map_pow, ← χ.pow_apply' (Nat.ne_of_odd_add hn), hχ]
609+
exact MulChar.one_apply_coe (-1)
610+
611+
end Ring

0 commit comments

Comments
 (0)