field_theory.finite.basic
⟷
Mathlib.FieldTheory.Finite.Basic
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -516,10 +516,10 @@ theorem Int.ModEq.pow_card_sub_one_eq_one {p : ℕ} (hp : Nat.Prime p) {n : ℤ}
haveI : Fact p.prime := ⟨hp⟩
have : ¬(n : ZMod p) = 0 :=
by
- rw [CharP.int_cast_eq_zero_iff _ p, ← (nat.prime_iff_prime_int.mp hp).coprime_iff_not_dvd]
+ rw [CharP.intCast_eq_zero_iff _ p, ← (nat.prime_iff_prime_int.mp hp).coprime_iff_not_dvd]
· exact hpn.symm
exact ZMod.charP p
- simpa [← ZMod.int_cast_eq_int_cast_iff] using ZMod.pow_card_sub_one_eq_one this
+ simpa [← ZMod.intCast_eq_intCast_iff] using ZMod.pow_card_sub_one_eq_one this
#align int.modeq.pow_card_sub_one_eq_one Int.ModEq.pow_card_sub_one_eq_one
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -143,7 +143,7 @@ theorem pow_card (a : K) : a ^ q = a :=
by
have hp : 0 < Fintype.card K := lt_trans zero_lt_one Fintype.one_lt_card
by_cases h : a = 0; · rw [h]; apply zero_pow hp
- rw [← Nat.succ_pred_eq_of_pos hp, pow_succ, Nat.pred_eq_sub_one, pow_card_sub_one_eq_one a h,
+ rw [← Nat.succ_pred_eq_of_pos hp, pow_succ', Nat.pred_eq_sub_one, pow_card_sub_one_eq_one a h,
mul_one]
#align finite_field.pow_card FiniteField.pow_card
-/
@@ -153,7 +153,7 @@ theorem pow_card_pow (n : ℕ) (a : K) : a ^ q ^ n = a :=
by
induction' n with n ih
· simp
- · simp [pow_succ, pow_mul, ih, pow_card]
+ · simp [pow_succ', pow_mul, ih, pow_card]
#align finite_field.pow_card_pow FiniteField.pow_card_pow
-/
@@ -331,7 +331,7 @@ theorem frobenius_pow {p : ℕ} [Fact p.Prime] [CharP K p] {n : ℕ} (hcard : q
frobenius K p ^ n = 1 := by
ext; conv_rhs => rw [RingHom.one_def, RingHom.id_apply, ← pow_card x, hcard]; clear hcard
induction n; · simp
- rw [pow_succ, pow_succ', pow_mul, RingHom.mul_def, RingHom.comp_apply, frobenius_def, n_ih]
+ rw [pow_succ', pow_succ, pow_mul, RingHom.mul_def, RingHom.comp_apply, frobenius_def, n_ih]
#align finite_field.frobenius_pow FiniteField.frobenius_pow
-/
@@ -453,7 +453,7 @@ theorem pow_card_pow {n p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p ^ n = x :=
by
induction' n with n ih
· simp
- · simp [pow_succ, pow_mul, ih, pow_card]
+ · simp [pow_succ', pow_mul, ih, pow_card]
#align zmod.pow_card_pow ZMod.pow_card_pow
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -83,8 +83,8 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
letI := Classical.decEq R
suffices ¬Disjoint (univ.image fun x : R => eval x f) (univ.image fun x : R => eval x (-g))
by
- simp only [disjoint_left, mem_image] at this
- push_neg at this
+ simp only [disjoint_left, mem_image] at this
+ push_neg at this
rcases this with ⟨x, ⟨a, _, ha⟩, ⟨b, _, hb⟩⟩
exact ⟨a, b, by rw [ha, ← hb, eval_neg, neg_add_self]⟩
fun hd : Disjoint _ _ =>
@@ -167,11 +167,11 @@ theorem card (p : ℕ) [CharP K p] : ∃ n : ℕ+, Nat.Prime p ∧ q = p ^ (n :
haveI hp : Fact p.prime := ⟨CharP.char_is_prime K p⟩
letI : Module (ZMod p) K := { (ZMod.castHom dvd_rfl K : ZMod p →+* _).toModule with }
obtain ⟨n, h⟩ := VectorSpace.card_fintype (ZMod p) K
- rw [ZMod.card] at h
+ rw [ZMod.card] at h
refine' ⟨⟨n, _⟩, hp.1, h⟩
apply Or.resolve_left (Nat.eq_zero_or_pos n)
rintro rfl
- rw [pow_zero] at h
+ rw [pow_zero] at h
have : (0 : K) = 1 := by apply fintype.card_le_one_iff.mp (le_of_eq h)
exact absurd this zero_ne_one
#align finite_field.card FiniteField.card
@@ -207,7 +207,7 @@ theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣
constructor
· intro h; apply h
· intro h y
- simp_rw [← mem_powers_iff_mem_zpowers] at hx
+ simp_rw [← mem_powers_iff_mem_zpowers] at hx
rcases hx y with ⟨j, rfl⟩
rw [← pow_mul, mul_comm, pow_mul, h, one_pow]
#align finite_field.forall_pow_eq_one_iff FiniteField.forall_pow_eq_one_iff
@@ -344,7 +344,7 @@ theorem expand_card (f : K[X]) : expand K q f = f ^ q :=
letI := hp
rcases FiniteField.card K p with ⟨⟨n, npos⟩, ⟨hp, hn⟩⟩
haveI : Fact p.prime := ⟨hp⟩
- dsimp at hn
+ dsimp at hn
rw [hn, ← map_expand_pow_char, frobenius_pow hn, RingHom.one_def, map_id]
#align finite_field.expand_card FiniteField.expand_card
-/
@@ -359,7 +359,7 @@ open FiniteField Polynomial
theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p, a ^ 2 + b ^ 2 = x :=
by
cases' hp.1.eq_two_or_odd with hp2 hp_odd
- · subst p; change Fin 2 at x ; fin_cases x; · use 0; simp; · use 0, 1; simp
+ · subst p; change Fin 2 at x; fin_cases x; · use 0; simp; · use 0, 1; simp
let f : (ZMod p)[X] := X ^ 2
let g : (ZMod p)[X] := X ^ 2 - C x
obtain ⟨a, b, hab⟩ : ∃ a b, f.eval a + g.eval b = 0 :=
@@ -412,7 +412,7 @@ theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.Coprime x n) : x ^ φ n ≡ 1
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
have := ZMod.pow_totient x'
- apply_fun (coe : Units (ZMod n) → ZMod n) at this
+ apply_fun (coe : Units (ZMod n) → ZMod n) at this
simpa only [-ZMod.pow_totient, Nat.succ_eq_add_one, Nat.cast_pow, Units.val_one, Nat.cast_one,
coe_unit_of_coprime, Units.val_pow_eq_pow_val]
#align nat.modeq.pow_totient Nat.ModEq.pow_totient
@@ -443,7 +443,7 @@ namespace ZMod
/-- A variation on Fermat's little theorem. See `zmod.pow_card_sub_one_eq_one` -/
@[simp]
theorem pow_card {p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p = x := by
- have h := FiniteField.pow_card x; rwa [ZMod.card p] at h
+ have h := FiniteField.pow_card x; rwa [ZMod.card p] at h
#align zmod.pow_card ZMod.pow_card
-/
@@ -481,7 +481,7 @@ theorem units_pow_card_sub_one_eq_one (p : ℕ) [Fact p.Prime] (a : (ZMod p)ˣ)
#print ZMod.pow_card_sub_one_eq_one /-
/-- **Fermat's Little Theorem**: for all nonzero `a : zmod p`, we have `a ^ (p - 1) = 1`. -/
theorem pow_card_sub_one_eq_one {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a ≠ 0) :
- a ^ (p - 1) = 1 := by have h := pow_card_sub_one_eq_one a ha; rwa [ZMod.card p] at h
+ a ^ (p - 1) = 1 := by have h := pow_card_sub_one_eq_one a ha; rwa [ZMod.card p] at h
#align zmod.pow_card_sub_one_eq_one ZMod.pow_card_sub_one_eq_one
-/
@@ -502,7 +502,7 @@ open Polynomial
#print ZMod.expand_card /-
theorem expand_card {p : ℕ} [Fact p.Prime] (f : Polynomial (ZMod p)) :
- expand (ZMod p) p f = f ^ p := by have h := FiniteField.expand_card f; rwa [ZMod.card p] at h
+ expand (ZMod p) p f = f ^ p := by have h := FiniteField.expand_card f; rwa [ZMod.card p] at h
#align zmod.expand_card ZMod.expand_card
-/
@@ -552,7 +552,7 @@ theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a :=
simp only [injective, Classical.not_forall, exists_prop]
refine' ⟨-1, 1, _, Ring.neg_one_ne_one_of_char_ne_two hF⟩
simp only [sq, one_pow, neg_one_sq]
- rw [Finite.injective_iff_surjective] at h
+ rw [Finite.injective_iff_surjective] at h
-- sq not surjective
simp_rw [IsSquare, ← pow_two, @eq_comm _ _ (_ ^ 2)]
push_neg at h ⊢
@@ -576,7 +576,7 @@ theorem even_card_iff_char_two : ringChar F = 2 ↔ Fintype.card F % 2 = 0 :=
simp only [Nat.bit0_mod_two, zero_pow, Ne.def, PNat.ne_zero, not_false_iff, Nat.zero_mod]
· rw [← Nat.even_iff, Nat.even_pow]
rintro ⟨hev, hnz⟩
- rw [Nat.even_iff, Nat.mod_mod] at hev
+ rw [Nat.even_iff, Nat.mod_mod] at hev
exact (Nat.Prime.eq_two_or_odd hp).resolve_right (ne_of_eq_of_ne hev zero_ne_one)
#align finite_field.even_card_iff_char_two FiniteField.even_card_iff_char_two
-/
@@ -600,7 +600,7 @@ theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
by
have h₁ := FiniteField.pow_card_sub_one_eq_one a ha
rw [← Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF), mul_comm, pow_mul,
- pow_two] at h₁
+ pow_two] at h₁
exact mul_self_eq_one_iff.mp h₁
#align finite_field.pow_dichotomy FiniteField.pow_dichotomy
-/
@@ -623,7 +623,7 @@ theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
· subst a; intro h
have key : 2 * (Fintype.card F / 2) ∣ n * (Fintype.card F / 2) :=
by
- rw [← pow_mul] at h
+ rw [← pow_mul] at h
rw [hodd, ← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg]
apply orderOf_dvd_of_pow_eq_one h
have : 0 < Fintype.card F / 2 := Nat.div_pos Fintype.one_lt_card (by norm_num)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -573,7 +573,7 @@ theorem even_card_iff_char_two : ringChar F = 2 ↔ Fintype.card F % 2 = 0 :=
constructor
· intro hF
rw [hF]
- simp only [Nat.bit0_mod_two, zero_pow', Ne.def, PNat.ne_zero, not_false_iff, Nat.zero_mod]
+ simp only [Nat.bit0_mod_two, zero_pow, Ne.def, PNat.ne_zero, not_false_iff, Nat.zero_mod]
· rw [← Nat.even_iff, Nat.even_pow]
rintro ⟨hev, hnz⟩
rw [Nat.even_iff, Nat.mod_mod] at hev
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -112,7 +112,13 @@ end Polynomial
#print FiniteField.prod_univ_units_id_eq_neg_one /-
theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
- ∏ x : Kˣ, x = (-1 : Kˣ) := by classical
+ ∏ x : Kˣ, x = (-1 : Kˣ) := by
+ classical
+ have : ∏ x in (@univ Kˣ _).eraseₓ (-1), x = 1 :=
+ prod_involution (fun x _ => x⁻¹) (by simp)
+ (fun a => by simp (config := { contextual := true }) [Units.inv_eq_self_iff])
+ (fun a => by simp [@inv_eq_iff_eq_inv _ _ a]) (by simp)
+ rw [← insert_erase (mem_univ (-1 : Kˣ)), prod_insert (not_mem_erase _ _), this, mul_one]
#align finite_field.prod_univ_units_id_eq_neg_one FiniteField.prod_univ_units_id_eq_neg_one
-/
@@ -125,7 +131,10 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 :=
calc
a ^ (Fintype.card K - 1) = (Units.mk0 a ha ^ (Fintype.card K - 1) : Kˣ) := by
rw [Units.val_pow_eq_pow_val, Units.val_mk0]
- _ = 1 := by classical
+ _ = 1 := by
+ classical
+ rw [← Fintype.card_units, pow_card_eq_one]
+ rfl
#align finite_field.pow_card_sub_one_eq_one FiniteField.pow_card_sub_one_eq_one
-/
@@ -191,7 +200,16 @@ theorem cast_card_eq_zero : (q : K) = 0 :=
-/
#print FiniteField.forall_pow_eq_one_iff /-
-theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣ i := by classical
+theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣ i := by
+ classical
+ obtain ⟨x, hx⟩ := IsCyclic.exists_generator Kˣ
+ rw [← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hx, orderOf_dvd_iff_pow_eq_one]
+ constructor
+ · intro h; apply h
+ · intro h y
+ simp_rw [← mem_powers_iff_mem_zpowers] at hx
+ rcases hx y with ⟨j, rfl⟩
+ rw [← pow_mul, mul_comm, pow_mul, h, one_pow]
#align finite_field.forall_pow_eq_one_iff FiniteField.forall_pow_eq_one_iff
-/
@@ -204,7 +222,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) : ∑ x : Kˣ, (x ^ i : K) = if q
{ toFun := fun x => x ^ i
map_one' := by rw [Units.val_one, one_pow]
map_mul' := by intros; rw [Units.val_mul, mul_pow] }
- have : Decidable (φ = 1) := by classical
+ have : Decidable (φ = 1) := by classical infer_instance
calc
∑ x : Kˣ, φ x = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
_ = if q - 1 ∣ i then -1 else 0 := _
@@ -228,6 +246,18 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0
by_cases hi : i = 0
· simp only [hi, nsmul_one, sum_const, pow_zero, card_univ, cast_card_eq_zero]
classical
+ have hiq : ¬q - 1 ∣ i := by contrapose! h; exact Nat.le_of_dvd (Nat.pos_of_ne_zero hi) h
+ let φ : Kˣ ↪ K := ⟨coe, Units.ext⟩
+ have : univ.map φ = univ \ {0} := by
+ ext x
+ simp only [true_and_iff, embedding.coe_fn_mk, mem_sdiff, Units.exists_iff_ne_zero, mem_univ,
+ mem_map, exists_prop_of_true, mem_singleton]
+ calc
+ ∑ x : K, x ^ i = ∑ x in univ \ {(0 : K)}, x ^ i := by
+ rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton, zero_pow (Nat.pos_of_ne_zero hi),
+ add_zero]
+ _ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
+ _ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
-/
@@ -275,7 +305,22 @@ end
variable (p : ℕ) [Fact p.Prime] [Algebra (ZMod p) K]
#print FiniteField.roots_X_pow_card_sub_X /-
-theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := by classical
+theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := by
+ classical
+ have aux : (X ^ q - X : K[X]) ≠ 0 := X_pow_card_sub_X_ne_zero K Fintype.one_lt_card
+ have : (roots (X ^ q - X : K[X])).toFinset = Finset.univ :=
+ by
+ rw [eq_univ_iff_forall]
+ intro x
+ rw [Multiset.mem_toFinset, mem_roots aux, is_root.def, eval_sub, eval_pow, eval_X, sub_eq_zero,
+ pow_card]
+ rw [← this, Multiset.toFinset_val, eq_comm, Multiset.dedup_eq_self]
+ apply nodup_roots
+ rw [separable_def]
+ convert is_coprime_one_right.neg_right using 1
+ ·
+ rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
+ MulZeroClass.zero_mul, zero_sub]
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_X_pow_card_sub_X
-/
@@ -564,7 +609,27 @@ theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
/-- A unit `a` of a finite field `F` of odd characteristic is a square
if and only if `a ^ (#F / 2) = 1`. -/
theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
- IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 := by classical
+ IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 := by
+ classical
+ obtain ⟨g, hg⟩ := IsCyclic.exists_generator Fˣ
+ obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g := by rw [mem_powers_iff_mem_zpowers]; apply hg
+ have hodd := Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF)
+ constructor
+ · rintro ⟨y, rfl⟩
+ rw [← pow_two, ← pow_mul, hodd]
+ apply_fun @coe Fˣ F _ using Units.ext
+ · push_cast
+ exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y)
+ · subst a; intro h
+ have key : 2 * (Fintype.card F / 2) ∣ n * (Fintype.card F / 2) :=
+ by
+ rw [← pow_mul] at h
+ rw [hodd, ← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg]
+ apply orderOf_dvd_of_pow_eq_one h
+ have : 0 < Fintype.card F / 2 := Nat.div_pos Fintype.one_lt_card (by norm_num)
+ obtain ⟨m, rfl⟩ := Nat.dvd_of_mul_dvd_mul_right this key
+ refine' ⟨g ^ m, _⟩
+ rw [mul_comm, pow_mul, pow_two]
#align finite_field.unit_is_square_iff FiniteField.unit_isSquare_iff
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -112,13 +112,7 @@ end Polynomial
#print FiniteField.prod_univ_units_id_eq_neg_one /-
theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
- ∏ x : Kˣ, x = (-1 : Kˣ) := by
- classical
- have : ∏ x in (@univ Kˣ _).eraseₓ (-1), x = 1 :=
- prod_involution (fun x _ => x⁻¹) (by simp)
- (fun a => by simp (config := { contextual := true }) [Units.inv_eq_self_iff])
- (fun a => by simp [@inv_eq_iff_eq_inv _ _ a]) (by simp)
- rw [← insert_erase (mem_univ (-1 : Kˣ)), prod_insert (not_mem_erase _ _), this, mul_one]
+ ∏ x : Kˣ, x = (-1 : Kˣ) := by classical
#align finite_field.prod_univ_units_id_eq_neg_one FiniteField.prod_univ_units_id_eq_neg_one
-/
@@ -131,10 +125,7 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 :=
calc
a ^ (Fintype.card K - 1) = (Units.mk0 a ha ^ (Fintype.card K - 1) : Kˣ) := by
rw [Units.val_pow_eq_pow_val, Units.val_mk0]
- _ = 1 := by
- classical
- rw [← Fintype.card_units, pow_card_eq_one]
- rfl
+ _ = 1 := by classical
#align finite_field.pow_card_sub_one_eq_one FiniteField.pow_card_sub_one_eq_one
-/
@@ -200,16 +191,7 @@ theorem cast_card_eq_zero : (q : K) = 0 :=
-/
#print FiniteField.forall_pow_eq_one_iff /-
-theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣ i := by
- classical
- obtain ⟨x, hx⟩ := IsCyclic.exists_generator Kˣ
- rw [← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hx, orderOf_dvd_iff_pow_eq_one]
- constructor
- · intro h; apply h
- · intro h y
- simp_rw [← mem_powers_iff_mem_zpowers] at hx
- rcases hx y with ⟨j, rfl⟩
- rw [← pow_mul, mul_comm, pow_mul, h, one_pow]
+theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣ i := by classical
#align finite_field.forall_pow_eq_one_iff FiniteField.forall_pow_eq_one_iff
-/
@@ -222,7 +204,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) : ∑ x : Kˣ, (x ^ i : K) = if q
{ toFun := fun x => x ^ i
map_one' := by rw [Units.val_one, one_pow]
map_mul' := by intros; rw [Units.val_mul, mul_pow] }
- have : Decidable (φ = 1) := by classical infer_instance
+ have : Decidable (φ = 1) := by classical
calc
∑ x : Kˣ, φ x = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
_ = if q - 1 ∣ i then -1 else 0 := _
@@ -246,18 +228,6 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0
by_cases hi : i = 0
· simp only [hi, nsmul_one, sum_const, pow_zero, card_univ, cast_card_eq_zero]
classical
- have hiq : ¬q - 1 ∣ i := by contrapose! h; exact Nat.le_of_dvd (Nat.pos_of_ne_zero hi) h
- let φ : Kˣ ↪ K := ⟨coe, Units.ext⟩
- have : univ.map φ = univ \ {0} := by
- ext x
- simp only [true_and_iff, embedding.coe_fn_mk, mem_sdiff, Units.exists_iff_ne_zero, mem_univ,
- mem_map, exists_prop_of_true, mem_singleton]
- calc
- ∑ x : K, x ^ i = ∑ x in univ \ {(0 : K)}, x ^ i := by
- rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton, zero_pow (Nat.pos_of_ne_zero hi),
- add_zero]
- _ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
- _ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
-/
@@ -305,22 +275,7 @@ end
variable (p : ℕ) [Fact p.Prime] [Algebra (ZMod p) K]
#print FiniteField.roots_X_pow_card_sub_X /-
-theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := by
- classical
- have aux : (X ^ q - X : K[X]) ≠ 0 := X_pow_card_sub_X_ne_zero K Fintype.one_lt_card
- have : (roots (X ^ q - X : K[X])).toFinset = Finset.univ :=
- by
- rw [eq_univ_iff_forall]
- intro x
- rw [Multiset.mem_toFinset, mem_roots aux, is_root.def, eval_sub, eval_pow, eval_X, sub_eq_zero,
- pow_card]
- rw [← this, Multiset.toFinset_val, eq_comm, Multiset.dedup_eq_self]
- apply nodup_roots
- rw [separable_def]
- convert is_coprime_one_right.neg_right using 1
- ·
- rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
- MulZeroClass.zero_mul, zero_sub]
+theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := by classical
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_X_pow_card_sub_X
-/
@@ -609,27 +564,7 @@ theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
/-- A unit `a` of a finite field `F` of odd characteristic is a square
if and only if `a ^ (#F / 2) = 1`. -/
theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
- IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 := by
- classical
- obtain ⟨g, hg⟩ := IsCyclic.exists_generator Fˣ
- obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g := by rw [mem_powers_iff_mem_zpowers]; apply hg
- have hodd := Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF)
- constructor
- · rintro ⟨y, rfl⟩
- rw [← pow_two, ← pow_mul, hodd]
- apply_fun @coe Fˣ F _ using Units.ext
- · push_cast
- exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y)
- · subst a; intro h
- have key : 2 * (Fintype.card F / 2) ∣ n * (Fintype.card F / 2) :=
- by
- rw [← pow_mul] at h
- rw [hodd, ← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg]
- apply orderOf_dvd_of_pow_eq_one h
- have : 0 < Fintype.card F / 2 := Nat.div_pos Fintype.one_lt_card (by norm_num)
- obtain ⟨m, rfl⟩ := Nat.dvd_of_mul_dvd_mul_right this key
- refine' ⟨g ^ m, _⟩
- rw [mul_comm, pow_mul, pow_two]
+ IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 := by classical
#align finite_field.unit_is_square_iff FiniteField.unit_isSquare_iff
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/b1abe23ae96fef89ad30d9f4362c307f72a55010
@@ -549,7 +549,7 @@ theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a :=
let sq : F → F := fun x => x ^ 2
have h : ¬injective sq :=
by
- simp only [injective, not_forall, exists_prop]
+ simp only [injective, Classical.not_forall, exists_prop]
refine' ⟨-1, 1, _, Ring.neg_one_ne_one_of_char_ne_two hF⟩
simp only [sq, one_pow, neg_one_sq]
rw [Finite.injective_iff_surjective] at h
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,9 +3,9 @@ Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Joey van Langen, Casper Putz
-/
-import Mathbin.FieldTheory.Separable
-import Mathbin.RingTheory.IntegralDomain
-import Mathbin.Tactic.ApplyFun
+import FieldTheory.Separable
+import RingTheory.IntegralDomain
+import Tactic.ApplyFun
#align_import field_theory.finite.basic from "leanprover-community/mathlib"@"af471b9e3ce868f296626d33189b4ce730fa4c00"
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -407,7 +407,7 @@ theorem ZMod.pow_totient {n : ℕ} (x : (ZMod n)ˣ) : x ^ φ n = 1 :=
#print Nat.ModEq.pow_totient /-
/-- The **Fermat-Euler totient theorem**. `zmod.pow_totient` is an alternative statement
of the same theorem. -/
-theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1 [MOD n] :=
+theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.Coprime x n) : x ^ φ n ≡ 1 [MOD n] :=
by
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,16 +2,13 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Joey van Langen, Casper Putz
-
-! This file was ported from Lean 3 source module field_theory.finite.basic
-! leanprover-community/mathlib commit af471b9e3ce868f296626d33189b4ce730fa4c00
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.FieldTheory.Separable
import Mathbin.RingTheory.IntegralDomain
import Mathbin.Tactic.ApplyFun
+#align_import field_theory.finite.basic from "leanprover-community/mathlib"@"af471b9e3ce868f296626d33189b4ce730fa4c00"
+
/-!
# Finite fields
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -51,7 +51,6 @@ diamonds, as `fintype` carries data.
variable {K : Type _} {R : Type _}
--- mathport name: exprq
local notation "q" => Fintype.card K
open Finset Function
@@ -80,6 +79,7 @@ theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp :
#align finite_field.card_image_polynomial_eval FiniteField.card_image_polynomial_eval
-/
+#print FiniteField.exists_root_sum_quadratic /-
/-- If `f` and `g` are quadratic polynomials, then the `f.eval a + g.eval b = 0` has a solution. -/
theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2) (hg2 : degree g = 2)
(hR : Fintype.card R % 2 = 1) : ∃ a b, f.eval a + g.eval b = 0 :=
@@ -109,9 +109,11 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
simp [nat_degree_eq_of_degree_eq_some hf2, nat_degree_eq_of_degree_eq_some hg2, bit0,
mul_add]
#align finite_field.exists_root_sum_quadratic FiniteField.exists_root_sum_quadratic
+-/
end Polynomial
+#print FiniteField.prod_univ_units_id_eq_neg_one /-
theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
∏ x : Kˣ, x = (-1 : Kˣ) := by
classical
@@ -121,11 +123,13 @@ theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
(fun a => by simp [@inv_eq_iff_eq_inv _ _ a]) (by simp)
rw [← insert_erase (mem_univ (-1 : Kˣ)), prod_insert (not_mem_erase _ _), this, mul_one]
#align finite_field.prod_univ_units_id_eq_neg_one FiniteField.prod_univ_units_id_eq_neg_one
+-/
section
variable [GroupWithZero K] [Fintype K]
+#print FiniteField.pow_card_sub_one_eq_one /-
theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 :=
calc
a ^ (Fintype.card K - 1) = (Units.mk0 a ha ^ (Fintype.card K - 1) : Kˣ) := by
@@ -135,6 +139,7 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 :=
rw [← Fintype.card_units, pow_card_eq_one]
rfl
#align finite_field.pow_card_sub_one_eq_one FiniteField.pow_card_sub_one_eq_one
+-/
#print FiniteField.pow_card /-
theorem pow_card (a : K) : a ^ q = a :=
@@ -159,6 +164,7 @@ end
variable (K) [Field K] [Fintype K]
+#print FiniteField.card /-
theorem card (p : ℕ) [CharP K p] : ∃ n : ℕ+, Nat.Prime p ∧ q = p ^ (n : ℕ) :=
by
haveI hp : Fact p.prime := ⟨CharP.char_is_prime K p⟩
@@ -172,6 +178,7 @@ theorem card (p : ℕ) [CharP K p] : ∃ n : ℕ+, Nat.Prime p ∧ q = p ^ (n :
have : (0 : K) = 1 := by apply fintype.card_le_one_iff.mp (le_of_eq h)
exact absurd this zero_ne_one
#align finite_field.card FiniteField.card
+-/
#print FiniteField.card' /-
-- this statement doesn't use `q` because we want `K` to be an explicit parameter
@@ -181,6 +188,7 @@ theorem card' : ∃ (p : ℕ) (n : ℕ+), Nat.Prime p ∧ Fintype.card K = p ^ (
#align finite_field.card' FiniteField.card'
-/
+#print FiniteField.cast_card_eq_zero /-
@[simp]
theorem cast_card_eq_zero : (q : K) = 0 :=
by
@@ -192,7 +200,9 @@ theorem cast_card_eq_zero : (q : K) = 0 :=
rw [← pow_one p]
exact pow_dvd_pow _ n.2
#align finite_field.cast_card_eq_zero FiniteField.cast_card_eq_zero
+-/
+#print FiniteField.forall_pow_eq_one_iff /-
theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣ i := by
classical
obtain ⟨x, hx⟩ := IsCyclic.exists_generator Kˣ
@@ -204,7 +214,9 @@ theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣
rcases hx y with ⟨j, rfl⟩
rw [← pow_mul, mul_comm, pow_mul, h, one_pow]
#align finite_field.forall_pow_eq_one_iff FiniteField.forall_pow_eq_one_iff
+-/
+#print FiniteField.sum_pow_units /-
/-- The sum of `x ^ i` as `x` ranges over the units of a finite field of cardinality `q`
is equal to `0` unless `(q - 1) ∣ i`, in which case the sum is `q - 1`. -/
theorem sum_pow_units [Fintype Kˣ] (i : ℕ) : ∑ x : Kˣ, (x ^ i : K) = if q - 1 ∣ i then -1 else 0 :=
@@ -227,7 +239,9 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) : ∑ x : Kˣ, (x ^ i : K) = if q
rw [Units.ext_iff, Units.val_pow_eq_pow_val, Units.val_one, MonoidHom.one_apply]
rfl
#align finite_field.sum_pow_units FiniteField.sum_pow_units
+-/
+#print FiniteField.sum_pow_lt_card_sub_one /-
/-- The sum of `x ^ i` as `x` ranges over a finite field of cardinality `q`
is equal to `0` if `i < q - 1`. -/
theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0 :=
@@ -248,6 +262,7 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0
_ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
_ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
+-/
open Polynomial
@@ -255,6 +270,7 @@ section
variable (K' : Type _) [Field K'] {p n : ℕ}
+#print FiniteField.X_pow_card_sub_X_natDegree_eq /-
theorem X_pow_card_sub_X_natDegree_eq (hp : 1 < p) : (X ^ p - X : K'[X]).natDegree = p :=
by
have h1 : (X : K'[X]).degree < (X ^ p : K'[X]).degree :=
@@ -263,27 +279,35 @@ theorem X_pow_card_sub_X_natDegree_eq (hp : 1 < p) : (X ^ p - X : K'[X]).natDegr
exact_mod_cast hp
rw [nat_degree_eq_of_degree_eq (degree_sub_eq_left_of_degree_lt h1), nat_degree_X_pow]
#align finite_field.X_pow_card_sub_X_nat_degree_eq FiniteField.X_pow_card_sub_X_natDegree_eq
+-/
+#print FiniteField.X_pow_card_pow_sub_X_natDegree_eq /-
theorem X_pow_card_pow_sub_X_natDegree_eq (hn : n ≠ 0) (hp : 1 < p) :
(X ^ p ^ n - X : K'[X]).natDegree = p ^ n :=
X_pow_card_sub_X_natDegree_eq K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
#align finite_field.X_pow_card_pow_sub_X_nat_degree_eq FiniteField.X_pow_card_pow_sub_X_natDegree_eq
+-/
+#print FiniteField.X_pow_card_sub_X_ne_zero /-
theorem X_pow_card_sub_X_ne_zero (hp : 1 < p) : (X ^ p - X : K'[X]) ≠ 0 :=
ne_zero_of_natDegree_gt <|
calc
1 < _ := hp
_ = _ := (X_pow_card_sub_X_natDegree_eq K' hp).symm
#align finite_field.X_pow_card_sub_X_ne_zero FiniteField.X_pow_card_sub_X_ne_zero
+-/
+#print FiniteField.X_pow_card_pow_sub_X_ne_zero /-
theorem X_pow_card_pow_sub_X_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (X ^ p ^ n - X : K'[X]) ≠ 0 :=
X_pow_card_sub_X_ne_zero K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
#align finite_field.X_pow_card_pow_sub_X_ne_zero FiniteField.X_pow_card_pow_sub_X_ne_zero
+-/
end
variable (p : ℕ) [Fact p.Prime] [Algebra (ZMod p) K]
+#print FiniteField.roots_X_pow_card_sub_X /-
theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := by
classical
have aux : (X ^ q - X : K[X]) ≠ 0 := X_pow_card_sub_X_ne_zero K Fintype.one_lt_card
@@ -301,18 +325,22 @@ theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := b
rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
MulZeroClass.zero_mul, zero_sub]
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_X_pow_card_sub_X
+-/
variable {K}
+#print FiniteField.frobenius_pow /-
theorem frobenius_pow {p : ℕ} [Fact p.Prime] [CharP K p] {n : ℕ} (hcard : q = p ^ n) :
frobenius K p ^ n = 1 := by
ext; conv_rhs => rw [RingHom.one_def, RingHom.id_apply, ← pow_card x, hcard]; clear hcard
induction n; · simp
rw [pow_succ, pow_succ', pow_mul, RingHom.mul_def, RingHom.comp_apply, frobenius_def, n_ih]
#align finite_field.frobenius_pow FiniteField.frobenius_pow
+-/
open Polynomial
+#print FiniteField.expand_card /-
theorem expand_card (f : K[X]) : expand K q f = f ^ q :=
by
cases' CharP.exists K with p hp
@@ -322,6 +350,7 @@ theorem expand_card (f : K[X]) : expand K q f = f ^ q :=
dsimp at hn
rw [hn, ← map_expand_pow_char, frobenius_pow hn, RingHom.one_def, map_id]
#align finite_field.expand_card FiniteField.expand_card
+-/
end FiniteField
@@ -329,6 +358,7 @@ namespace ZMod
open FiniteField Polynomial
+#print ZMod.sq_add_sq /-
theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p, a ^ 2 + b ^ 2 = x :=
by
cases' hp.1.eq_two_or_odd with hp2 hp_odd
@@ -342,11 +372,13 @@ theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p,
rw [← sub_eq_zero]
simpa only [eval_C, eval_X, eval_pow, eval_sub, ← add_sub_assoc] using hab
#align zmod.sq_add_sq ZMod.sq_add_sq
+-/
end ZMod
namespace CharP
+#print CharP.sq_add_sq /-
theorem sq_add_sq (R : Type _) [CommRing R] [IsDomain R] (p : ℕ) [NeZero p] [CharP R p] (x : ℤ) :
∃ a b : ℕ, (a ^ 2 + b ^ 2 : R) = x :=
by
@@ -355,6 +387,7 @@ theorem sq_add_sq (R : Type _) [CommRing R] [IsDomain R] (p : ℕ) [NeZero p] [C
refine' ⟨a.val, b.val, _⟩
simpa using congr_arg (ZMod.castHom dvd_rfl R) hab
#align char_p.sq_add_sq CharP.sq_add_sq
+-/
end CharP
@@ -362,6 +395,7 @@ open scoped Nat
open ZMod
+#print ZMod.pow_totient /-
/-- The **Fermat-Euler totient theorem**. `nat.modeq.pow_totient` is an alternative statement
of the same theorem. -/
@[simp]
@@ -371,6 +405,7 @@ theorem ZMod.pow_totient {n : ℕ} (x : (ZMod n)ˣ) : x ^ φ n = 1 :=
· rw [Nat.totient_zero, pow_zero]
· rw [← card_units_eq_totient, pow_card_eq_one]
#align zmod.pow_totient ZMod.pow_totient
+-/
#print Nat.ModEq.pow_totient /-
/-- The **Fermat-Euler totient theorem**. `zmod.pow_totient` is an alternative statement
@@ -407,12 +442,15 @@ open FiniteField
namespace ZMod
+#print ZMod.pow_card /-
/-- A variation on Fermat's little theorem. See `zmod.pow_card_sub_one_eq_one` -/
@[simp]
theorem pow_card {p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p = x := by
have h := FiniteField.pow_card x; rwa [ZMod.card p] at h
#align zmod.pow_card ZMod.pow_card
+-/
+#print ZMod.pow_card_pow /-
@[simp]
theorem pow_card_pow {n p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p ^ n = x :=
by
@@ -420,44 +458,60 @@ theorem pow_card_pow {n p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p ^ n = x :=
· simp
· simp [pow_succ, pow_mul, ih, pow_card]
#align zmod.pow_card_pow ZMod.pow_card_pow
+-/
+#print ZMod.frobenius_zmod /-
@[simp]
theorem frobenius_zmod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom.id _ := by ext a;
rw [frobenius_def, ZMod.pow_card, RingHom.id_apply]
#align zmod.frobenius_zmod ZMod.frobenius_zmod
+-/
+#print ZMod.card_units /-
@[simp]
theorem card_units (p : ℕ) [Fact p.Prime] : Fintype.card (ZMod p)ˣ = p - 1 := by
rw [Fintype.card_units, card]
#align zmod.card_units ZMod.card_units
+-/
+#print ZMod.units_pow_card_sub_one_eq_one /-
/-- **Fermat's Little Theorem**: for every unit `a` of `zmod p`, we have `a ^ (p - 1) = 1`. -/
theorem units_pow_card_sub_one_eq_one (p : ℕ) [Fact p.Prime] (a : (ZMod p)ˣ) : a ^ (p - 1) = 1 := by
rw [← card_units p, pow_card_eq_one]
#align zmod.units_pow_card_sub_one_eq_one ZMod.units_pow_card_sub_one_eq_one
+-/
+#print ZMod.pow_card_sub_one_eq_one /-
/-- **Fermat's Little Theorem**: for all nonzero `a : zmod p`, we have `a ^ (p - 1) = 1`. -/
theorem pow_card_sub_one_eq_one {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a ≠ 0) :
a ^ (p - 1) = 1 := by have h := pow_card_sub_one_eq_one a ha; rwa [ZMod.card p] at h
#align zmod.pow_card_sub_one_eq_one ZMod.pow_card_sub_one_eq_one
+-/
+#print ZMod.orderOf_units_dvd_card_sub_one /-
theorem orderOf_units_dvd_card_sub_one {p : ℕ} [Fact p.Prime] (u : (ZMod p)ˣ) : orderOf u ∣ p - 1 :=
orderOf_dvd_of_pow_eq_one <| units_pow_card_sub_one_eq_one _ _
#align zmod.order_of_units_dvd_card_sub_one ZMod.orderOf_units_dvd_card_sub_one
+-/
+#print ZMod.orderOf_dvd_card_sub_one /-
theorem orderOf_dvd_card_sub_one {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a ≠ 0) :
orderOf a ∣ p - 1 :=
orderOf_dvd_of_pow_eq_one <| pow_card_sub_one_eq_one ha
#align zmod.order_of_dvd_card_sub_one ZMod.orderOf_dvd_card_sub_one
+-/
open Polynomial
+#print ZMod.expand_card /-
theorem expand_card {p : ℕ} [Fact p.Prime] (f : Polynomial (ZMod p)) :
expand (ZMod p) p f = f ^ p := by have h := FiniteField.expand_card f; rwa [ZMod.card p] at h
#align zmod.expand_card ZMod.expand_card
+-/
end ZMod
+#print Int.ModEq.pow_card_sub_one_eq_one /-
/-- **Fermat's Little Theorem**: for all `a : ℤ` coprime to `p`, we have
`a ^ (p - 1) ≡ 1 [ZMOD p]`. -/
theorem Int.ModEq.pow_card_sub_one_eq_one {p : ℕ} (hp : Nat.Prime p) {n : ℤ} (hpn : IsCoprime n p) :
@@ -470,6 +524,7 @@ theorem Int.ModEq.pow_card_sub_one_eq_one {p : ℕ} (hp : Nat.Prime p) {n : ℤ}
exact ZMod.charP p
simpa [← ZMod.int_cast_eq_int_cast_iff] using ZMod.pow_card_sub_one_eq_one this
#align int.modeq.pow_card_sub_one_eq_one Int.ModEq.pow_card_sub_one_eq_one
+-/
section
@@ -481,12 +536,15 @@ section Finite
variable [Finite F]
+#print FiniteField.isSquare_of_char_two /-
/-- In a finite field of characteristic `2`, all elements are squares. -/
theorem isSquare_of_char_two (hF : ringChar F = 2) (a : F) : IsSquare a :=
haveI hF' : CharP F 2 := ringChar.of_eq hF
isSquare_of_charTwo' a
#align finite_field.is_square_of_char_two FiniteField.isSquare_of_char_two
+-/
+#print FiniteField.exists_nonsquare /-
/-- In a finite field of odd characteristic, not every element is a square. -/
theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a :=
by
@@ -503,6 +561,7 @@ theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a :=
push_neg at h ⊢
exact h
#align finite_field.exists_nonsquare FiniteField.exists_nonsquare
+-/
end Finite
@@ -537,6 +596,7 @@ theorem odd_card_of_char_ne_two (hF : ringChar F ≠ 2) : Fintype.card F % 2 = 1
#align finite_field.odd_card_of_char_ne_two FiniteField.odd_card_of_char_ne_two
-/
+#print FiniteField.pow_dichotomy /-
/-- If `F` has odd characteristic, then for nonzero `a : F`, we have that `a ^ (#F / 2) = ±1`. -/
theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
a ^ (Fintype.card F / 2) = 1 ∨ a ^ (Fintype.card F / 2) = -1 :=
@@ -546,7 +606,9 @@ theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
pow_two] at h₁
exact mul_self_eq_one_iff.mp h₁
#align finite_field.pow_dichotomy FiniteField.pow_dichotomy
+-/
+#print FiniteField.unit_isSquare_iff /-
/-- A unit `a` of a finite field `F` of odd characteristic is a square
if and only if `a ^ (#F / 2) = 1`. -/
theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
@@ -572,7 +634,9 @@ theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
refine' ⟨g ^ m, _⟩
rw [mul_comm, pow_mul, pow_two]
#align finite_field.unit_is_square_iff FiniteField.unit_isSquare_iff
+-/
+#print FiniteField.isSquare_iff /-
/-- A non-zero `a : F` is a square if and only if `a ^ (#F / 2) = 1`. -/
theorem isSquare_iff (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 :=
@@ -586,6 +650,7 @@ theorem isSquare_iff (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
have hy : y ≠ 0 := by rintro rfl; simpa [zero_pow] using ha
refine' ⟨Units.mk0 y hy, _⟩; simp
#align finite_field.is_square_iff FiniteField.isSquare_iff
+-/
end FiniteField
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -113,9 +113,9 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
end Polynomial
theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
- (∏ x : Kˣ, x) = (-1 : Kˣ) := by
+ ∏ x : Kˣ, x = (-1 : Kˣ) := by
classical
- have : (∏ x in (@univ Kˣ _).eraseₓ (-1), x) = 1 :=
+ have : ∏ x in (@univ Kˣ _).eraseₓ (-1), x = 1 :=
prod_involution (fun x _ => x⁻¹) (by simp)
(fun a => by simp (config := { contextual := true }) [Units.inv_eq_self_iff])
(fun a => by simp [@inv_eq_iff_eq_inv _ _ a]) (by simp)
@@ -207,8 +207,7 @@ theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣
/-- The sum of `x ^ i` as `x` ranges over the units of a finite field of cardinality `q`
is equal to `0` unless `(q - 1) ∣ i`, in which case the sum is `q - 1`. -/
-theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
- (∑ x : Kˣ, (x ^ i : K)) = if q - 1 ∣ i then -1 else 0 :=
+theorem sum_pow_units [Fintype Kˣ] (i : ℕ) : ∑ x : Kˣ, (x ^ i : K) = if q - 1 ∣ i then -1 else 0 :=
by
let φ : Kˣ →* K :=
{ toFun := fun x => x ^ i
@@ -216,7 +215,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
map_mul' := by intros; rw [Units.val_mul, mul_pow] }
have : Decidable (φ = 1) := by classical infer_instance
calc
- (∑ x : Kˣ, φ x) = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
+ ∑ x : Kˣ, φ x = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
_ = if q - 1 ∣ i then -1 else 0 := _
suffices q - 1 ∣ i ↔ φ = 1 by
simp only [this]
@@ -231,7 +230,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
/-- The sum of `x ^ i` as `x` ranges over a finite field of cardinality `q`
is equal to `0` if `i < q - 1`. -/
-theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) = 0 :=
+theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0 :=
by
by_cases hi : i = 0
· simp only [hi, nsmul_one, sum_const, pow_zero, card_univ, cast_card_eq_zero]
@@ -243,7 +242,7 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
simp only [true_and_iff, embedding.coe_fn_mk, mem_sdiff, Units.exists_iff_ne_zero, mem_univ,
mem_map, exists_prop_of_true, mem_singleton]
calc
- (∑ x : K, x ^ i) = ∑ x in univ \ {(0 : K)}, x ^ i := by
+ ∑ x : K, x ^ i = ∑ x in univ \ {(0 : K)}, x ^ i := by
rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton, zero_pow (Nat.pos_of_ne_zero hi),
add_zero]
_ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -77,7 +77,6 @@ theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp :
congr_arg card (by simp [Finset.ext_iff, mem_roots_sub_C hp])
_ ≤ (p - C a).roots.card := (Multiset.toFinset_card_le _)
_ ≤ _ := card_roots_sub_C' hp
-
#align finite_field.card_image_polynomial_eval FiniteField.card_image_polynomial_eval
-/
@@ -109,7 +108,6 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
rw [card_disjoint_union hd] <;>
simp [nat_degree_eq_of_degree_eq_some hf2, nat_degree_eq_of_degree_eq_some hg2, bit0,
mul_add]
-
#align finite_field.exists_root_sum_quadratic FiniteField.exists_root_sum_quadratic
end Polynomial
@@ -136,7 +134,6 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 :=
classical
rw [← Fintype.card_units, pow_card_eq_one]
rfl
-
#align finite_field.pow_card_sub_one_eq_one FiniteField.pow_card_sub_one_eq_one
#print FiniteField.pow_card /-
@@ -221,7 +218,6 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
calc
(∑ x : Kˣ, φ x) = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
_ = if q - 1 ∣ i then -1 else 0 := _
-
suffices q - 1 ∣ i ↔ φ = 1 by
simp only [this]
split_ifs with h h; swap; rfl
@@ -252,7 +248,6 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
add_zero]
_ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
_ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
-
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
open Polynomial
@@ -280,7 +275,6 @@ theorem X_pow_card_sub_X_ne_zero (hp : 1 < p) : (X ^ p - X : K'[X]) ≠ 0 :=
calc
1 < _ := hp
_ = _ := (X_pow_card_sub_X_natDegree_eq K' hp).symm
-
#align finite_field.X_pow_card_sub_X_ne_zero FiniteField.X_pow_card_sub_X_ne_zero
theorem X_pow_card_pow_sub_X_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (X ^ p ^ n - X : K'[X]) ≠ 0 :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/58a272265b5e05f258161260dd2c5d247213cbd3
@@ -429,9 +429,9 @@ theorem pow_card_pow {n p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p ^ n = x :=
#align zmod.pow_card_pow ZMod.pow_card_pow
@[simp]
-theorem frobenius_zMod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom.id _ := by ext a;
+theorem frobenius_zmod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom.id _ := by ext a;
rw [frobenius_def, ZMod.pow_card, RingHom.id_apply]
-#align zmod.frobenius_zmod ZMod.frobenius_zMod
+#align zmod.frobenius_zmod ZMod.frobenius_zmod
@[simp]
theorem card_units (p : ℕ) [Fact p.Prime] : Fintype.card (ZMod p)ˣ = p - 1 := by
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Joey van Langen, Casper Putz
! This file was ported from Lean 3 source module field_theory.finite.basic
-! leanprover-community/mathlib commit 12a85fac627bea918960da036049d611b1a3ee43
+! leanprover-community/mathlib commit af471b9e3ce868f296626d33189b4ce730fa4c00
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -15,6 +15,9 @@ import Mathbin.Tactic.ApplyFun
/-!
# Finite fields
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file contains basic results about finite fields.
Throughout most of this file, `K` denotes a finite field
and `q` is notation for the cardinality of `K`.
@@ -63,6 +66,7 @@ variable [CommRing R] [IsDomain R]
open Polynomial
+#print FiniteField.card_image_polynomial_eval /-
/-- The cardinality of a field is at most `n` times the cardinality of the image of a degree `n`
polynomial -/
theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp : 0 < p.degree) :
@@ -75,6 +79,7 @@ theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp :
_ ≤ _ := card_roots_sub_C' hp
#align finite_field.card_image_polynomial_eval FiniteField.card_image_polynomial_eval
+-/
/-- If `f` and `g` are quadratic polynomials, then the `f.eval a + g.eval b = 0` has a solution. -/
theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2) (hg2 : degree g = 2)
@@ -83,7 +88,7 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
suffices ¬Disjoint (univ.image fun x : R => eval x f) (univ.image fun x : R => eval x (-g))
by
simp only [disjoint_left, mem_image] at this
- push_neg at this
+ push_neg at this
rcases this with ⟨x, ⟨a, _, ha⟩, ⟨b, _, hb⟩⟩
exact ⟨a, b, by rw [ha, ← hb, eval_neg, neg_add_self]⟩
fun hd : Disjoint _ _ =>
@@ -112,11 +117,11 @@ end Polynomial
theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
(∏ x : Kˣ, x) = (-1 : Kˣ) := by
classical
- have : (∏ x in (@univ Kˣ _).eraseₓ (-1), x) = 1 :=
- prod_involution (fun x _ => x⁻¹) (by simp)
- (fun a => by simp (config := { contextual := true }) [Units.inv_eq_self_iff])
- (fun a => by simp [@inv_eq_iff_eq_inv _ _ a]) (by simp)
- rw [← insert_erase (mem_univ (-1 : Kˣ)), prod_insert (not_mem_erase _ _), this, mul_one]
+ have : (∏ x in (@univ Kˣ _).eraseₓ (-1), x) = 1 :=
+ prod_involution (fun x _ => x⁻¹) (by simp)
+ (fun a => by simp (config := { contextual := true }) [Units.inv_eq_self_iff])
+ (fun a => by simp [@inv_eq_iff_eq_inv _ _ a]) (by simp)
+ rw [← insert_erase (mem_univ (-1 : Kˣ)), prod_insert (not_mem_erase _ _), this, mul_one]
#align finite_field.prod_univ_units_id_eq_neg_one FiniteField.prod_univ_units_id_eq_neg_one
section
@@ -129,11 +134,12 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 :=
rw [Units.val_pow_eq_pow_val, Units.val_mk0]
_ = 1 := by
classical
- rw [← Fintype.card_units, pow_card_eq_one]
- rfl
+ rw [← Fintype.card_units, pow_card_eq_one]
+ rfl
#align finite_field.pow_card_sub_one_eq_one FiniteField.pow_card_sub_one_eq_one
+#print FiniteField.pow_card /-
theorem pow_card (a : K) : a ^ q = a :=
by
have hp : 0 < Fintype.card K := lt_trans zero_lt_one Fintype.one_lt_card
@@ -141,13 +147,16 @@ theorem pow_card (a : K) : a ^ q = a :=
rw [← Nat.succ_pred_eq_of_pos hp, pow_succ, Nat.pred_eq_sub_one, pow_card_sub_one_eq_one a h,
mul_one]
#align finite_field.pow_card FiniteField.pow_card
+-/
+#print FiniteField.pow_card_pow /-
theorem pow_card_pow (n : ℕ) (a : K) : a ^ q ^ n = a :=
by
induction' n with n ih
· simp
· simp [pow_succ, pow_mul, ih, pow_card]
#align finite_field.pow_card_pow FiniteField.pow_card_pow
+-/
end
@@ -167,11 +176,13 @@ theorem card (p : ℕ) [CharP K p] : ∃ n : ℕ+, Nat.Prime p ∧ q = p ^ (n :
exact absurd this zero_ne_one
#align finite_field.card FiniteField.card
+#print FiniteField.card' /-
-- this statement doesn't use `q` because we want `K` to be an explicit parameter
theorem card' : ∃ (p : ℕ) (n : ℕ+), Nat.Prime p ∧ Fintype.card K = p ^ (n : ℕ) :=
let ⟨p, hc⟩ := CharP.exists K
⟨p, @FiniteField.card K _ _ p hc⟩
#align finite_field.card' FiniteField.card'
+-/
@[simp]
theorem cast_card_eq_zero : (q : K) = 0 :=
@@ -187,15 +198,14 @@ theorem cast_card_eq_zero : (q : K) = 0 :=
theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣ i := by
classical
- obtain ⟨x, hx⟩ := IsCyclic.exists_generator Kˣ
- rw [← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hx,
- orderOf_dvd_iff_pow_eq_one]
- constructor
- · intro h; apply h
- · intro h y
- simp_rw [← mem_powers_iff_mem_zpowers] at hx
- rcases hx y with ⟨j, rfl⟩
- rw [← pow_mul, mul_comm, pow_mul, h, one_pow]
+ obtain ⟨x, hx⟩ := IsCyclic.exists_generator Kˣ
+ rw [← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hx, orderOf_dvd_iff_pow_eq_one]
+ constructor
+ · intro h; apply h
+ · intro h y
+ simp_rw [← mem_powers_iff_mem_zpowers] at hx
+ rcases hx y with ⟨j, rfl⟩
+ rw [← pow_mul, mul_comm, pow_mul, h, one_pow]
#align finite_field.forall_pow_eq_one_iff FiniteField.forall_pow_eq_one_iff
/-- The sum of `x ^ i` as `x` ranges over the units of a finite field of cardinality `q`
@@ -230,19 +240,19 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
by_cases hi : i = 0
· simp only [hi, nsmul_one, sum_const, pow_zero, card_univ, cast_card_eq_zero]
classical
- have hiq : ¬q - 1 ∣ i := by contrapose! h; exact Nat.le_of_dvd (Nat.pos_of_ne_zero hi) h
- let φ : Kˣ ↪ K := ⟨coe, Units.ext⟩
- have : univ.map φ = univ \ {0} := by
- ext x
- simp only [true_and_iff, embedding.coe_fn_mk, mem_sdiff, Units.exists_iff_ne_zero, mem_univ,
- mem_map, exists_prop_of_true, mem_singleton]
- calc
- (∑ x : K, x ^ i) = ∑ x in univ \ {(0 : K)}, x ^ i := by
- rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton,
- zero_pow (Nat.pos_of_ne_zero hi), add_zero]
- _ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
- _ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
-
+ have hiq : ¬q - 1 ∣ i := by contrapose! h; exact Nat.le_of_dvd (Nat.pos_of_ne_zero hi) h
+ let φ : Kˣ ↪ K := ⟨coe, Units.ext⟩
+ have : univ.map φ = univ \ {0} := by
+ ext x
+ simp only [true_and_iff, embedding.coe_fn_mk, mem_sdiff, Units.exists_iff_ne_zero, mem_univ,
+ mem_map, exists_prop_of_true, mem_singleton]
+ calc
+ (∑ x : K, x ^ i) = ∑ x in univ \ {(0 : K)}, x ^ i := by
+ rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton, zero_pow (Nat.pos_of_ne_zero hi),
+ add_zero]
+ _ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
+ _ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
+
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
open Polynomial
@@ -251,53 +261,53 @@ section
variable (K' : Type _) [Field K'] {p n : ℕ}
-theorem x_pow_card_sub_x_natDegree_eq (hp : 1 < p) : (X ^ p - X : K'[X]).natDegree = p :=
+theorem X_pow_card_sub_X_natDegree_eq (hp : 1 < p) : (X ^ p - X : K'[X]).natDegree = p :=
by
have h1 : (X : K'[X]).degree < (X ^ p : K'[X]).degree :=
by
rw [degree_X_pow, degree_X]
exact_mod_cast hp
rw [nat_degree_eq_of_degree_eq (degree_sub_eq_left_of_degree_lt h1), nat_degree_X_pow]
-#align finite_field.X_pow_card_sub_X_nat_degree_eq FiniteField.x_pow_card_sub_x_natDegree_eq
+#align finite_field.X_pow_card_sub_X_nat_degree_eq FiniteField.X_pow_card_sub_X_natDegree_eq
-theorem x_pow_card_pow_sub_x_natDegree_eq (hn : n ≠ 0) (hp : 1 < p) :
+theorem X_pow_card_pow_sub_X_natDegree_eq (hn : n ≠ 0) (hp : 1 < p) :
(X ^ p ^ n - X : K'[X]).natDegree = p ^ n :=
- x_pow_card_sub_x_natDegree_eq K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
-#align finite_field.X_pow_card_pow_sub_X_nat_degree_eq FiniteField.x_pow_card_pow_sub_x_natDegree_eq
+ X_pow_card_sub_X_natDegree_eq K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
+#align finite_field.X_pow_card_pow_sub_X_nat_degree_eq FiniteField.X_pow_card_pow_sub_X_natDegree_eq
-theorem x_pow_card_sub_x_ne_zero (hp : 1 < p) : (X ^ p - X : K'[X]) ≠ 0 :=
+theorem X_pow_card_sub_X_ne_zero (hp : 1 < p) : (X ^ p - X : K'[X]) ≠ 0 :=
ne_zero_of_natDegree_gt <|
calc
1 < _ := hp
- _ = _ := (x_pow_card_sub_x_natDegree_eq K' hp).symm
+ _ = _ := (X_pow_card_sub_X_natDegree_eq K' hp).symm
-#align finite_field.X_pow_card_sub_X_ne_zero FiniteField.x_pow_card_sub_x_ne_zero
+#align finite_field.X_pow_card_sub_X_ne_zero FiniteField.X_pow_card_sub_X_ne_zero
-theorem x_pow_card_pow_sub_x_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (X ^ p ^ n - X : K'[X]) ≠ 0 :=
- x_pow_card_sub_x_ne_zero K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
-#align finite_field.X_pow_card_pow_sub_X_ne_zero FiniteField.x_pow_card_pow_sub_x_ne_zero
+theorem X_pow_card_pow_sub_X_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (X ^ p ^ n - X : K'[X]) ≠ 0 :=
+ X_pow_card_sub_X_ne_zero K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
+#align finite_field.X_pow_card_pow_sub_X_ne_zero FiniteField.X_pow_card_pow_sub_X_ne_zero
end
variable (p : ℕ) [Fact p.Prime] [Algebra (ZMod p) K]
-theorem roots_x_pow_card_sub_x : roots (X ^ q - X : K[X]) = Finset.univ.val := by
+theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := by
classical
- have aux : (X ^ q - X : K[X]) ≠ 0 := X_pow_card_sub_X_ne_zero K Fintype.one_lt_card
- have : (roots (X ^ q - X : K[X])).toFinset = Finset.univ :=
- by
- rw [eq_univ_iff_forall]
- intro x
- rw [Multiset.mem_toFinset, mem_roots aux, is_root.def, eval_sub, eval_pow, eval_X,
- sub_eq_zero, pow_card]
- rw [← this, Multiset.toFinset_val, eq_comm, Multiset.dedup_eq_self]
- apply nodup_roots
- rw [separable_def]
- convert is_coprime_one_right.neg_right using 1
- ·
- rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
- MulZeroClass.zero_mul, zero_sub]
-#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_x_pow_card_sub_x
+ have aux : (X ^ q - X : K[X]) ≠ 0 := X_pow_card_sub_X_ne_zero K Fintype.one_lt_card
+ have : (roots (X ^ q - X : K[X])).toFinset = Finset.univ :=
+ by
+ rw [eq_univ_iff_forall]
+ intro x
+ rw [Multiset.mem_toFinset, mem_roots aux, is_root.def, eval_sub, eval_pow, eval_X, sub_eq_zero,
+ pow_card]
+ rw [← this, Multiset.toFinset_val, eq_comm, Multiset.dedup_eq_self]
+ apply nodup_roots
+ rw [separable_def]
+ convert is_coprime_one_right.neg_right using 1
+ ·
+ rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
+ MulZeroClass.zero_mul, zero_sub]
+#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_X_pow_card_sub_X
variable {K}
@@ -369,6 +379,7 @@ theorem ZMod.pow_totient {n : ℕ} (x : (ZMod n)ˣ) : x ^ φ n = 1 :=
· rw [← card_units_eq_totient, pow_card_eq_one]
#align zmod.pow_totient ZMod.pow_totient
+#print Nat.ModEq.pow_totient /-
/-- The **Fermat-Euler totient theorem**. `zmod.pow_totient` is an alternative statement
of the same theorem. -/
theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1 [MOD n] :=
@@ -376,15 +387,17 @@ theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
have := ZMod.pow_totient x'
- apply_fun (coe : Units (ZMod n) → ZMod n) at this
+ apply_fun (coe : Units (ZMod n) → ZMod n) at this
simpa only [-ZMod.pow_totient, Nat.succ_eq_add_one, Nat.cast_pow, Units.val_one, Nat.cast_one,
coe_unit_of_coprime, Units.val_pow_eq_pow_val]
#align nat.modeq.pow_totient Nat.ModEq.pow_totient
+-/
section
variable {V : Type _} [Fintype K] [DivisionRing K] [AddCommGroup V] [Module K V]
+#print card_eq_pow_finrank /-
-- should this go in a namespace?
-- finite_dimensional would be natural,
-- but we don't assume it...
@@ -393,6 +406,7 @@ theorem card_eq_pow_finrank [Fintype V] : Fintype.card V = q ^ FiniteDimensional
let b := IsNoetherian.finsetBasis K V
rw [Module.card_fintype b, ← FiniteDimensional.finrank_eq_card_basis b]
#align card_eq_pow_finrank card_eq_pow_finrank
+-/
end
@@ -493,7 +507,7 @@ theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a :=
rw [Finite.injective_iff_surjective] at h
-- sq not surjective
simp_rw [IsSquare, ← pow_two, @eq_comm _ _ (_ ^ 2)]
- push_neg at h ⊢
+ push_neg at h ⊢
exact h
#align finite_field.exists_nonsquare FiniteField.exists_nonsquare
@@ -501,6 +515,7 @@ end Finite
variable [Fintype F]
+#print FiniteField.even_card_iff_char_two /-
/-- The finite field `F` has even cardinality iff it has characteristic `2`. -/
theorem even_card_iff_char_two : ringChar F = 2 ↔ Fintype.card F % 2 = 0 :=
by
@@ -515,14 +530,19 @@ theorem even_card_iff_char_two : ringChar F = 2 ↔ Fintype.card F % 2 = 0 :=
rw [Nat.even_iff, Nat.mod_mod] at hev
exact (Nat.Prime.eq_two_or_odd hp).resolve_right (ne_of_eq_of_ne hev zero_ne_one)
#align finite_field.even_card_iff_char_two FiniteField.even_card_iff_char_two
+-/
+#print FiniteField.even_card_of_char_two /-
theorem even_card_of_char_two (hF : ringChar F = 2) : Fintype.card F % 2 = 0 :=
even_card_iff_char_two.mp hF
#align finite_field.even_card_of_char_two FiniteField.even_card_of_char_two
+-/
+#print FiniteField.odd_card_of_char_ne_two /-
theorem odd_card_of_char_ne_two (hF : ringChar F ≠ 2) : Fintype.card F % 2 = 1 :=
Nat.mod_two_ne_zero.mp (mt even_card_iff_char_two.mpr hF)
#align finite_field.odd_card_of_char_ne_two FiniteField.odd_card_of_char_ne_two
+-/
/-- If `F` has odd characteristic, then for nonzero `a : F`, we have that `a ^ (#F / 2) = ±1`. -/
theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
@@ -539,25 +559,25 @@ if and only if `a ^ (#F / 2) = 1`. -/
theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 := by
classical
- obtain ⟨g, hg⟩ := IsCyclic.exists_generator Fˣ
- obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g := by rw [mem_powers_iff_mem_zpowers]; apply hg
- have hodd := Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF)
- constructor
- · rintro ⟨y, rfl⟩
- rw [← pow_two, ← pow_mul, hodd]
- apply_fun @coe Fˣ F _ using Units.ext
- · push_cast
- exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y)
- · subst a; intro h
- have key : 2 * (Fintype.card F / 2) ∣ n * (Fintype.card F / 2) :=
- by
- rw [← pow_mul] at h
- rw [hodd, ← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg]
- apply orderOf_dvd_of_pow_eq_one h
- have : 0 < Fintype.card F / 2 := Nat.div_pos Fintype.one_lt_card (by norm_num)
- obtain ⟨m, rfl⟩ := Nat.dvd_of_mul_dvd_mul_right this key
- refine' ⟨g ^ m, _⟩
- rw [mul_comm, pow_mul, pow_two]
+ obtain ⟨g, hg⟩ := IsCyclic.exists_generator Fˣ
+ obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g := by rw [mem_powers_iff_mem_zpowers]; apply hg
+ have hodd := Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF)
+ constructor
+ · rintro ⟨y, rfl⟩
+ rw [← pow_two, ← pow_mul, hodd]
+ apply_fun @coe Fˣ F _ using Units.ext
+ · push_cast
+ exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y)
+ · subst a; intro h
+ have key : 2 * (Fintype.card F / 2) ∣ n * (Fintype.card F / 2) :=
+ by
+ rw [← pow_mul] at h
+ rw [hodd, ← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg]
+ apply orderOf_dvd_of_pow_eq_one h
+ have : 0 < Fintype.card F / 2 := Nat.div_pos Fintype.one_lt_card (by norm_num)
+ obtain ⟨m, rfl⟩ := Nat.dvd_of_mul_dvd_mul_right this key
+ refine' ⟨g ^ m, _⟩
+ rw [mul_comm, pow_mul, pow_two]
#align finite_field.unit_is_square_iff FiniteField.unit_isSquare_iff
/-- A non-zero `a : F` is a square if and only if `a ^ (#F / 2) = 1`. -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -82,8 +82,8 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
letI := Classical.decEq R
suffices ¬Disjoint (univ.image fun x : R => eval x f) (univ.image fun x : R => eval x (-g))
by
- simp only [disjoint_left, mem_image] at this
- push_neg at this
+ simp only [disjoint_left, mem_image] at this
+ push_neg at this
rcases this with ⟨x, ⟨a, _, ha⟩, ⟨b, _, hb⟩⟩
exact ⟨a, b, by rw [ha, ← hb, eval_neg, neg_add_self]⟩
fun hd : Disjoint _ _ =>
@@ -158,17 +158,17 @@ theorem card (p : ℕ) [CharP K p] : ∃ n : ℕ+, Nat.Prime p ∧ q = p ^ (n :
haveI hp : Fact p.prime := ⟨CharP.char_is_prime K p⟩
letI : Module (ZMod p) K := { (ZMod.castHom dvd_rfl K : ZMod p →+* _).toModule with }
obtain ⟨n, h⟩ := VectorSpace.card_fintype (ZMod p) K
- rw [ZMod.card] at h
+ rw [ZMod.card] at h
refine' ⟨⟨n, _⟩, hp.1, h⟩
apply Or.resolve_left (Nat.eq_zero_or_pos n)
rintro rfl
- rw [pow_zero] at h
+ rw [pow_zero] at h
have : (0 : K) = 1 := by apply fintype.card_le_one_iff.mp (le_of_eq h)
exact absurd this zero_ne_one
#align finite_field.card FiniteField.card
-- this statement doesn't use `q` because we want `K` to be an explicit parameter
-theorem card' : ∃ (p : ℕ)(n : ℕ+), Nat.Prime p ∧ Fintype.card K = p ^ (n : ℕ) :=
+theorem card' : ∃ (p : ℕ) (n : ℕ+), Nat.Prime p ∧ Fintype.card K = p ^ (n : ℕ) :=
let ⟨p, hc⟩ := CharP.exists K
⟨p, @FiniteField.card K _ _ p hc⟩
#align finite_field.card' FiniteField.card'
@@ -193,7 +193,7 @@ theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣
constructor
· intro h; apply h
· intro h y
- simp_rw [← mem_powers_iff_mem_zpowers] at hx
+ simp_rw [← mem_powers_iff_mem_zpowers] at hx
rcases hx y with ⟨j, rfl⟩
rw [← pow_mul, mul_comm, pow_mul, h, one_pow]
#align finite_field.forall_pow_eq_one_iff FiniteField.forall_pow_eq_one_iff
@@ -206,7 +206,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
let φ : Kˣ →* K :=
{ toFun := fun x => x ^ i
map_one' := by rw [Units.val_one, one_pow]
- map_mul' := by intros ; rw [Units.val_mul, mul_pow] }
+ map_mul' := by intros; rw [Units.val_mul, mul_pow] }
have : Decidable (φ = 1) := by classical infer_instance
calc
(∑ x : Kˣ, φ x) = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
@@ -316,7 +316,7 @@ theorem expand_card (f : K[X]) : expand K q f = f ^ q :=
letI := hp
rcases FiniteField.card K p with ⟨⟨n, npos⟩, ⟨hp, hn⟩⟩
haveI : Fact p.prime := ⟨hp⟩
- dsimp at hn
+ dsimp at hn
rw [hn, ← map_expand_pow_char, frobenius_pow hn, RingHom.one_def, map_id]
#align finite_field.expand_card FiniteField.expand_card
@@ -329,7 +329,7 @@ open FiniteField Polynomial
theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p, a ^ 2 + b ^ 2 = x :=
by
cases' hp.1.eq_two_or_odd with hp2 hp_odd
- · subst p; change Fin 2 at x; fin_cases x; · use 0; simp; · use 0, 1; simp
+ · subst p; change Fin 2 at x ; fin_cases x; · use 0; simp; · use 0, 1; simp
let f : (ZMod p)[X] := X ^ 2
let g : (ZMod p)[X] := X ^ 2 - C x
obtain ⟨a, b, hab⟩ : ∃ a b, f.eval a + g.eval b = 0 :=
@@ -376,7 +376,7 @@ theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
have := ZMod.pow_totient x'
- apply_fun (coe : Units (ZMod n) → ZMod n) at this
+ apply_fun (coe : Units (ZMod n) → ZMod n) at this
simpa only [-ZMod.pow_totient, Nat.succ_eq_add_one, Nat.cast_pow, Units.val_one, Nat.cast_one,
coe_unit_of_coprime, Units.val_pow_eq_pow_val]
#align nat.modeq.pow_totient Nat.ModEq.pow_totient
@@ -403,7 +403,7 @@ namespace ZMod
/-- A variation on Fermat's little theorem. See `zmod.pow_card_sub_one_eq_one` -/
@[simp]
theorem pow_card {p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p = x := by
- have h := FiniteField.pow_card x; rwa [ZMod.card p] at h
+ have h := FiniteField.pow_card x; rwa [ZMod.card p] at h
#align zmod.pow_card ZMod.pow_card
@[simp]
@@ -431,7 +431,7 @@ theorem units_pow_card_sub_one_eq_one (p : ℕ) [Fact p.Prime] (a : (ZMod p)ˣ)
/-- **Fermat's Little Theorem**: for all nonzero `a : zmod p`, we have `a ^ (p - 1) = 1`. -/
theorem pow_card_sub_one_eq_one {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a ≠ 0) :
- a ^ (p - 1) = 1 := by have h := pow_card_sub_one_eq_one a ha; rwa [ZMod.card p] at h
+ a ^ (p - 1) = 1 := by have h := pow_card_sub_one_eq_one a ha; rwa [ZMod.card p] at h
#align zmod.pow_card_sub_one_eq_one ZMod.pow_card_sub_one_eq_one
theorem orderOf_units_dvd_card_sub_one {p : ℕ} [Fact p.Prime] (u : (ZMod p)ˣ) : orderOf u ∣ p - 1 :=
@@ -446,7 +446,7 @@ theorem orderOf_dvd_card_sub_one {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a
open Polynomial
theorem expand_card {p : ℕ} [Fact p.Prime] (f : Polynomial (ZMod p)) :
- expand (ZMod p) p f = f ^ p := by have h := FiniteField.expand_card f; rwa [ZMod.card p] at h
+ expand (ZMod p) p f = f ^ p := by have h := FiniteField.expand_card f; rwa [ZMod.card p] at h
#align zmod.expand_card ZMod.expand_card
end ZMod
@@ -490,10 +490,10 @@ theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a :=
simp only [injective, not_forall, exists_prop]
refine' ⟨-1, 1, _, Ring.neg_one_ne_one_of_char_ne_two hF⟩
simp only [sq, one_pow, neg_one_sq]
- rw [Finite.injective_iff_surjective] at h
+ rw [Finite.injective_iff_surjective] at h
-- sq not surjective
simp_rw [IsSquare, ← pow_two, @eq_comm _ _ (_ ^ 2)]
- push_neg at h⊢
+ push_neg at h ⊢
exact h
#align finite_field.exists_nonsquare FiniteField.exists_nonsquare
@@ -512,7 +512,7 @@ theorem even_card_iff_char_two : ringChar F = 2 ↔ Fintype.card F % 2 = 0 :=
simp only [Nat.bit0_mod_two, zero_pow', Ne.def, PNat.ne_zero, not_false_iff, Nat.zero_mod]
· rw [← Nat.even_iff, Nat.even_pow]
rintro ⟨hev, hnz⟩
- rw [Nat.even_iff, Nat.mod_mod] at hev
+ rw [Nat.even_iff, Nat.mod_mod] at hev
exact (Nat.Prime.eq_two_or_odd hp).resolve_right (ne_of_eq_of_ne hev zero_ne_one)
#align finite_field.even_card_iff_char_two FiniteField.even_card_iff_char_two
@@ -530,7 +530,7 @@ theorem pow_dichotomy (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
by
have h₁ := FiniteField.pow_card_sub_one_eq_one a ha
rw [← Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF), mul_comm, pow_mul,
- pow_two] at h₁
+ pow_two] at h₁
exact mul_self_eq_one_iff.mp h₁
#align finite_field.pow_dichotomy FiniteField.pow_dichotomy
@@ -551,7 +551,7 @@ theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
· subst a; intro h
have key : 2 * (Fintype.card F / 2) ∣ n * (Fintype.card F / 2) :=
by
- rw [← pow_mul] at h
+ rw [← pow_mul] at h
rw [hodd, ← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hg]
apply orderOf_dvd_of_pow_eq_one h
have : 0 < Fintype.card F / 2 := Nat.div_pos Fintype.one_lt_card (by norm_num)
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -4,12 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Joey van Langen, Casper Putz
! This file was ported from Lean 3 source module field_theory.finite.basic
-! leanprover-community/mathlib commit 2196ab363eb097c008d4497125e0dde23fb36db2
+! leanprover-community/mathlib commit 12a85fac627bea918960da036049d611b1a3ee43
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.FieldTheory.Separable
-import Mathbin.FieldTheory.SplittingField
import Mathbin.RingTheory.IntegralDomain
import Mathbin.Tactic.ApplyFun
@@ -246,8 +245,6 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
-section IsSplittingField
-
open Polynomial
section
@@ -302,22 +299,6 @@ theorem roots_x_pow_card_sub_x : roots (X ^ q - X : K[X]) = Finset.univ.val := b
MulZeroClass.zero_mul, zero_sub]
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_x_pow_card_sub_x
-instance (F : Type _) [Field F] [Algebra F K] : IsSplittingField F K (X ^ q - X)
- where
- Splits :=
- by
- have h : (X ^ q - X : K[X]).natDegree = q :=
- X_pow_card_sub_X_nat_degree_eq K Fintype.one_lt_card
- rw [← splits_id_iff_splits, splits_iff_card_roots, Polynomial.map_sub, Polynomial.map_pow,
- map_X, h, roots_X_pow_card_sub_X K, ← Finset.card_def, Finset.card_univ]
- adjoin_roots := by
- classical
- trans Algebra.adjoin F ((roots (X ^ q - X : K[X])).toFinset : Set K)
- · simp only [Polynomial.map_pow, map_X, Polynomial.map_sub]
- · rw [roots_X_pow_card_sub_X, val_to_finset, coe_univ, Algebra.adjoin_univ]
-
-end IsSplittingField
-
variable {K}
theorem frobenius_pow {p : ℕ} [Fact p.Prime] [CharP K p] {n : ℕ} (hcard : q = p ^ n) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -54,7 +54,7 @@ local notation "q" => Fintype.card K
open Finset Function
-open BigOperators Polynomial
+open scoped BigOperators Polynomial
namespace FiniteField
@@ -374,7 +374,7 @@ theorem sq_add_sq (R : Type _) [CommRing R] [IsDomain R] (p : ℕ) [NeZero p] [C
end CharP
-open Nat
+open scoped Nat
open ZMod
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -138,9 +138,7 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 :=
theorem pow_card (a : K) : a ^ q = a :=
by
have hp : 0 < Fintype.card K := lt_trans zero_lt_one Fintype.one_lt_card
- by_cases h : a = 0;
- · rw [h]
- apply zero_pow hp
+ by_cases h : a = 0; · rw [h]; apply zero_pow hp
rw [← Nat.succ_pred_eq_of_pos hp, pow_succ, Nat.pred_eq_sub_one, pow_card_sub_one_eq_one a h,
mul_one]
#align finite_field.pow_card FiniteField.pow_card
@@ -194,8 +192,7 @@ theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣
rw [← Fintype.card_units, ← orderOf_eq_card_of_forall_mem_zpowers hx,
orderOf_dvd_iff_pow_eq_one]
constructor
- · intro h
- apply h
+ · intro h; apply h
· intro h y
simp_rw [← mem_powers_iff_mem_zpowers] at hx
rcases hx y with ⟨j, rfl⟩
@@ -210,9 +207,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
let φ : Kˣ →* K :=
{ toFun := fun x => x ^ i
map_one' := by rw [Units.val_one, one_pow]
- map_mul' := by
- intros
- rw [Units.val_mul, mul_pow] }
+ map_mul' := by intros ; rw [Units.val_mul, mul_pow] }
have : Decidable (φ = 1) := by classical infer_instance
calc
(∑ x : Kˣ, φ x) = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
@@ -220,15 +215,11 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
suffices q - 1 ∣ i ↔ φ = 1 by
simp only [this]
- split_ifs with h h
- swap
- rfl
+ split_ifs with h h; swap; rfl
rw [Fintype.card_units, Nat.cast_sub, cast_card_eq_zero, Nat.cast_one, zero_sub]
- show 1 ≤ q
- exact fintype.card_pos_iff.mpr ⟨0⟩
+ show 1 ≤ q; exact fintype.card_pos_iff.mpr ⟨0⟩
rw [← forall_pow_eq_one_iff, MonoidHom.ext_iff]
- apply forall_congr'
- intro x
+ apply forall_congr'; intro x
rw [Units.ext_iff, Units.val_pow_eq_pow_val, Units.val_one, MonoidHom.one_apply]
rfl
#align finite_field.sum_pow_units FiniteField.sum_pow_units
@@ -240,9 +231,7 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
by_cases hi : i = 0
· simp only [hi, nsmul_one, sum_const, pow_zero, card_univ, cast_card_eq_zero]
classical
- have hiq : ¬q - 1 ∣ i := by
- contrapose! h
- exact Nat.le_of_dvd (Nat.pos_of_ne_zero hi) h
+ have hiq : ¬q - 1 ∣ i := by contrapose! h; exact Nat.le_of_dvd (Nat.pos_of_ne_zero hi) h
let φ : Kˣ ↪ K := ⟨coe, Units.ext⟩
have : univ.map φ = univ \ {0} := by
ext x
@@ -252,12 +241,8 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
(∑ x : K, x ^ i) = ∑ x in univ \ {(0 : K)}, x ^ i := by
rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton,
zero_pow (Nat.pos_of_ne_zero hi), add_zero]
- _ = ∑ x : Kˣ, x ^ i := by
- rw [← this, univ.sum_map φ]
- rfl
- _ = 0 := by
- rw [sum_pow_units K i, if_neg]
- exact hiq
+ _ = ∑ x : Kˣ, x ^ i := by rw [← this, univ.sum_map φ]; rfl
+ _ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
@@ -363,13 +348,7 @@ open FiniteField Polynomial
theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p, a ^ 2 + b ^ 2 = x :=
by
cases' hp.1.eq_two_or_odd with hp2 hp_odd
- · subst p
- change Fin 2 at x
- fin_cases x
- · use 0
- simp
- · use 0, 1
- simp
+ · subst p; change Fin 2 at x; fin_cases x; · use 0; simp; · use 0, 1; simp
let f : (ZMod p)[X] := X ^ 2
let g : (ZMod p)[X] := X ^ 2 - C x
obtain ⟨a, b, hab⟩ : ∃ a b, f.eval a + g.eval b = 0 :=
@@ -442,10 +421,8 @@ namespace ZMod
/-- A variation on Fermat's little theorem. See `zmod.pow_card_sub_one_eq_one` -/
@[simp]
-theorem pow_card {p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p = x :=
- by
- have h := FiniteField.pow_card x
- rwa [ZMod.card p] at h
+theorem pow_card {p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p = x := by
+ have h := FiniteField.pow_card x; rwa [ZMod.card p] at h
#align zmod.pow_card ZMod.pow_card
@[simp]
@@ -457,9 +434,7 @@ theorem pow_card_pow {n p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p ^ n = x :=
#align zmod.pow_card_pow ZMod.pow_card_pow
@[simp]
-theorem frobenius_zMod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom.id _ :=
- by
- ext a
+theorem frobenius_zMod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom.id _ := by ext a;
rw [frobenius_def, ZMod.pow_card, RingHom.id_apply]
#align zmod.frobenius_zmod ZMod.frobenius_zMod
@@ -475,9 +450,7 @@ theorem units_pow_card_sub_one_eq_one (p : ℕ) [Fact p.Prime] (a : (ZMod p)ˣ)
/-- **Fermat's Little Theorem**: for all nonzero `a : zmod p`, we have `a ^ (p - 1) = 1`. -/
theorem pow_card_sub_one_eq_one {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a ≠ 0) :
- a ^ (p - 1) = 1 := by
- have h := pow_card_sub_one_eq_one a ha
- rwa [ZMod.card p] at h
+ a ^ (p - 1) = 1 := by have h := pow_card_sub_one_eq_one a ha; rwa [ZMod.card p] at h
#align zmod.pow_card_sub_one_eq_one ZMod.pow_card_sub_one_eq_one
theorem orderOf_units_dvd_card_sub_one {p : ℕ} [Fact p.Prime] (u : (ZMod p)ˣ) : orderOf u ∣ p - 1 :=
@@ -492,10 +465,7 @@ theorem orderOf_dvd_card_sub_one {p : ℕ} [Fact p.Prime] {a : ZMod p} (ha : a
open Polynomial
theorem expand_card {p : ℕ} [Fact p.Prime] (f : Polynomial (ZMod p)) :
- expand (ZMod p) p f = f ^ p :=
- by
- have h := FiniteField.expand_card f
- rwa [ZMod.card p] at h
+ expand (ZMod p) p f = f ^ p := by have h := FiniteField.expand_card f; rwa [ZMod.card p] at h
#align zmod.expand_card ZMod.expand_card
end ZMod
@@ -589,10 +559,7 @@ theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
IsSquare a ↔ a ^ (Fintype.card F / 2) = 1 := by
classical
obtain ⟨g, hg⟩ := IsCyclic.exists_generator Fˣ
- obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g :=
- by
- rw [mem_powers_iff_mem_zpowers]
- apply hg
+ obtain ⟨n, hn⟩ : a ∈ Submonoid.powers g := by rw [mem_powers_iff_mem_zpowers]; apply hg
have hodd := Nat.two_mul_odd_div_two (FiniteField.odd_card_of_char_ne_two hF)
constructor
· rintro ⟨y, rfl⟩
@@ -600,8 +567,7 @@ theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
apply_fun @coe Fˣ F _ using Units.ext
· push_cast
exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y)
- · subst a
- intro h
+ · subst a; intro h
have key : 2 * (Fintype.card F / 2) ∣ n * (Fintype.card F / 2) :=
by
rw [← pow_mul] at h
@@ -621,14 +587,10 @@ theorem isSquare_iff (hF : ringChar F ≠ 2) {a : F} (ha : a ≠ 0) :
(iff_congr _ (by simp [Units.ext_iff])).mp (FiniteField.unit_isSquare_iff hF (Units.mk0 a ha))
simp only [IsSquare, Units.ext_iff, Units.val_mk0, Units.val_mul]
constructor
- · rintro ⟨y, hy⟩
- exact ⟨y, hy⟩
+ · rintro ⟨y, hy⟩; exact ⟨y, hy⟩
· rintro ⟨y, rfl⟩
- have hy : y ≠ 0 := by
- rintro rfl
- simpa [zero_pow] using ha
- refine' ⟨Units.mk0 y hy, _⟩
- simp
+ have hy : y ≠ 0 := by rintro rfl; simpa [zero_pow] using ha
+ refine' ⟨Units.mk0 y hy, _⟩; simp
#align finite_field.is_square_iff FiniteField.isSquare_iff
end FiniteField
mathlib commit https://github.com/leanprover-community/mathlib/commit/02ba8949f486ebecf93fe7460f1ed0564b5e442c
@@ -510,7 +510,7 @@ theorem Int.ModEq.pow_card_sub_one_eq_one {p : ℕ} (hp : Nat.Prime p) {n : ℤ}
rw [CharP.int_cast_eq_zero_iff _ p, ← (nat.prime_iff_prime_int.mp hp).coprime_iff_not_dvd]
· exact hpn.symm
exact ZMod.charP p
- simpa [← ZMod.int_coe_eq_int_coe_iff] using ZMod.pow_card_sub_one_eq_one this
+ simpa [← ZMod.int_cast_eq_int_cast_iff] using ZMod.pow_card_sub_one_eq_one this
#align int.modeq.pow_card_sub_one_eq_one Int.ModEq.pow_card_sub_one_eq_one
section
mathlib commit https://github.com/leanprover-community/mathlib/commit/2196ab363eb097c008d4497125e0dde23fb36db2
@@ -526,7 +526,7 @@ variable [Finite F]
/-- In a finite field of characteristic `2`, all elements are squares. -/
theorem isSquare_of_char_two (hF : ringChar F = 2) (a : F) : IsSquare a :=
haveI hF' : CharP F 2 := ringChar.of_eq hF
- isSquare_of_char_two' a
+ isSquare_of_charTwo' a
#align finite_field.is_square_of_char_two FiniteField.isSquare_of_char_two
/-- In a finite field of odd characteristic, not every element is a square. -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/2196ab363eb097c008d4497125e0dde23fb36db2
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Joey van Langen, Casper Putz
! This file was ported from Lean 3 source module field_theory.finite.basic
-! leanprover-community/mathlib commit 55d224c38461be1e8e4363247dd110137c24a4ff
+! leanprover-community/mathlib commit 2196ab363eb097c008d4497125e0dde23fb36db2
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -116,7 +116,7 @@ theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
have : (∏ x in (@univ Kˣ _).eraseₓ (-1), x) = 1 :=
prod_involution (fun x _ => x⁻¹) (by simp)
(fun a => by simp (config := { contextual := true }) [Units.inv_eq_self_iff])
- (fun a => by simp [@inv_eq_iff_inv_eq _ _ a, eq_comm]) (by simp)
+ (fun a => by simp [@inv_eq_iff_eq_inv _ _ a]) (by simp)
rw [← insert_erase (mem_univ (-1 : Kˣ)), prod_insert (not_mem_erase _ _), this, mul_one]
#align finite_field.prod_univ_units_id_eq_neg_one FiniteField.prod_univ_units_id_eq_neg_one
mathlib commit https://github.com/leanprover-community/mathlib/commit/3180fab693e2cee3bff62675571264cb8778b212
@@ -313,8 +313,8 @@ theorem roots_x_pow_card_sub_x : roots (X ^ q - X : K[X]) = Finset.univ.val := b
rw [separable_def]
convert is_coprime_one_right.neg_right using 1
·
- rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0, zero_mul,
- zero_sub]
+ rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
+ MulZeroClass.zero_mul, zero_sub]
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_x_pow_card_sub_x
instance (F : Type _) [Field F] [Algebra F K] : IsSplittingField F K (X ^ q - X)
mathlib commit https://github.com/leanprover-community/mathlib/commit/38f16f960f5006c6c0c2bac7b0aba5273188f4e5
@@ -70,9 +70,9 @@ theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp :
Fintype.card R ≤ natDegree p * (univ.image fun x => eval x p).card :=
Finset.card_le_mul_card_image _ _ fun a _ =>
calc
- _ = (p - c a).roots.toFinset.card :=
+ _ = (p - C a).roots.toFinset.card :=
congr_arg card (by simp [Finset.ext_iff, mem_roots_sub_C hp])
- _ ≤ (p - c a).roots.card := (Multiset.toFinset_card_le _)
+ _ ≤ (p - C a).roots.card := (Multiset.toFinset_card_le _)
_ ≤ _ := card_roots_sub_C' hp
#align finite_field.card_image_polynomial_eval FiniteField.card_image_polynomial_eval
@@ -269,7 +269,7 @@ section
variable (K' : Type _) [Field K'] {p n : ℕ}
-theorem x_pow_card_sub_x_natDegree_eq (hp : 1 < p) : (x ^ p - x : K'[X]).natDegree = p :=
+theorem x_pow_card_sub_x_natDegree_eq (hp : 1 < p) : (X ^ p - X : K'[X]).natDegree = p :=
by
have h1 : (X : K'[X]).degree < (X ^ p : K'[X]).degree :=
by
@@ -279,11 +279,11 @@ theorem x_pow_card_sub_x_natDegree_eq (hp : 1 < p) : (x ^ p - x : K'[X]).natDegr
#align finite_field.X_pow_card_sub_X_nat_degree_eq FiniteField.x_pow_card_sub_x_natDegree_eq
theorem x_pow_card_pow_sub_x_natDegree_eq (hn : n ≠ 0) (hp : 1 < p) :
- (x ^ p ^ n - x : K'[X]).natDegree = p ^ n :=
+ (X ^ p ^ n - X : K'[X]).natDegree = p ^ n :=
x_pow_card_sub_x_natDegree_eq K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
#align finite_field.X_pow_card_pow_sub_X_nat_degree_eq FiniteField.x_pow_card_pow_sub_x_natDegree_eq
-theorem x_pow_card_sub_x_ne_zero (hp : 1 < p) : (x ^ p - x : K'[X]) ≠ 0 :=
+theorem x_pow_card_sub_x_ne_zero (hp : 1 < p) : (X ^ p - X : K'[X]) ≠ 0 :=
ne_zero_of_natDegree_gt <|
calc
1 < _ := hp
@@ -291,7 +291,7 @@ theorem x_pow_card_sub_x_ne_zero (hp : 1 < p) : (x ^ p - x : K'[X]) ≠ 0 :=
#align finite_field.X_pow_card_sub_X_ne_zero FiniteField.x_pow_card_sub_x_ne_zero
-theorem x_pow_card_pow_sub_x_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (x ^ p ^ n - x : K'[X]) ≠ 0 :=
+theorem x_pow_card_pow_sub_x_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (X ^ p ^ n - X : K'[X]) ≠ 0 :=
x_pow_card_sub_x_ne_zero K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
#align finite_field.X_pow_card_pow_sub_X_ne_zero FiniteField.x_pow_card_pow_sub_x_ne_zero
@@ -299,7 +299,7 @@ end
variable (p : ℕ) [Fact p.Prime] [Algebra (ZMod p) K]
-theorem roots_x_pow_card_sub_x : roots (x ^ q - x : K[X]) = Finset.univ.val := by
+theorem roots_x_pow_card_sub_x : roots (X ^ q - X : K[X]) = Finset.univ.val := by
classical
have aux : (X ^ q - X : K[X]) ≠ 0 := X_pow_card_sub_X_ne_zero K Fintype.one_lt_card
have : (roots (X ^ q - X : K[X])).toFinset = Finset.univ :=
@@ -317,7 +317,7 @@ theorem roots_x_pow_card_sub_x : roots (x ^ q - x : K[X]) = Finset.univ.val := b
zero_sub]
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_x_pow_card_sub_x
-instance (F : Type _) [Field F] [Algebra F K] : IsSplittingField F K (x ^ q - x)
+instance (F : Type _) [Field F] [Algebra F K] : IsSplittingField F K (X ^ q - X)
where
Splits :=
by
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -72,7 +72,7 @@ theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp :
calc
_ = (p - c a).roots.toFinset.card :=
congr_arg card (by simp [Finset.ext_iff, mem_roots_sub_C hp])
- _ ≤ (p - c a).roots.card := Multiset.toFinset_card_le _
+ _ ≤ (p - c a).roots.card := (Multiset.toFinset_card_le _)
_ ≤ _ := card_roots_sub_C' hp
#align finite_field.card_image_polynomial_eval FiniteField.card_image_polynomial_eval
@@ -93,14 +93,14 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
2 * ((univ.image fun x : R => eval x f) ∪ univ.image fun x : R => eval x (-g)).card ≤
2 * Fintype.card R :=
Nat.mul_le_mul_left _ (Finset.card_le_univ _)
- _ = Fintype.card R + Fintype.card R := two_mul _
+ _ = Fintype.card R + Fintype.card R := (two_mul _)
_ <
nat_degree f * (univ.image fun x : R => eval x f).card +
nat_degree (-g) * (univ.image fun x : R => eval x (-g)).card :=
- add_lt_add_of_lt_of_le
+ (add_lt_add_of_lt_of_le
(lt_of_le_of_ne (card_image_polynomial_eval (by rw [hf2] <;> exact by decide))
(mt (congr_arg (· % 2)) (by simp [nat_degree_eq_of_degree_eq_some hf2, hR])))
- (card_image_polynomial_eval (by rw [degree_neg, hg2] <;> exact by decide))
+ (card_image_polynomial_eval (by rw [degree_neg, hg2] <;> exact by decide)))
_ = 2 * ((univ.image fun x : R => eval x f) ∪ univ.image fun x : R => eval x (-g)).card := by
rw [card_disjoint_union hd] <;>
simp [nat_degree_eq_of_degree_eq_some hf2, nat_degree_eq_of_degree_eq_some hg2, bit0,
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
nat_cast
/int_cast
/rat_cast
to natCast
/intCast
/ratCast
(#11486)
Now that I am defining NNRat.cast
, I want a definitive answer to this naming issue. Plenty of lemmas in mathlib already use natCast
/intCast
/ratCast
over nat_cast
/int_cast
/rat_cast
, and this matches with the general expectation that underscore-separated name parts correspond to a single declaration.
@@ -427,7 +427,7 @@ theorem Nat.sq_add_sq_zmodEq (p : ℕ) [Fact p.Prime] (x : ℤ) :
ZMod.natAbs_valMinAbs_le _, ?_⟩
rw [← a.coe_valMinAbs, ← b.coe_valMinAbs] at hx
push_cast
- rw [sq_abs, sq_abs, ← ZMod.int_cast_eq_int_cast_iff]
+ rw [sq_abs, sq_abs, ← ZMod.intCast_eq_intCast_iff]
exact mod_cast hx
/-- If `p` is a prime natural number and `x` is a natural number, then there exist natural numbers
@@ -555,9 +555,9 @@ theorem Int.ModEq.pow_card_sub_one_eq_one {p : ℕ} (hp : Nat.Prime p) {n : ℤ}
n ^ (p - 1) ≡ 1 [ZMOD p] := by
haveI : Fact p.Prime := ⟨hp⟩
have : ¬(n : ZMod p) = 0 := by
- rw [CharP.int_cast_eq_zero_iff _ p, ← (Nat.prime_iff_prime_int.mp hp).coprime_iff_not_dvd]
+ rw [CharP.intCast_eq_zero_iff _ p, ← (Nat.prime_iff_prime_int.mp hp).coprime_iff_not_dvd]
· exact hpn.symm
- simpa [← ZMod.int_cast_eq_int_cast_iff] using ZMod.pow_card_sub_one_eq_one this
+ simpa [← ZMod.intCast_eq_intCast_iff] using ZMod.pow_card_sub_one_eq_one this
#align int.modeq.pow_card_sub_one_eq_one Int.ModEq.pow_card_sub_one_eq_one
section
@@ -68,7 +68,7 @@ theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp :
calc
_ = (p - C a).roots.toFinset.card :=
congr_arg card (by simp [Finset.ext_iff, ← mem_roots_sub_C hp])
- _ ≤ Multiset.card (p - C a).roots := (Multiset.toFinset_card_le _)
+ _ ≤ Multiset.card (p - C a).roots := Multiset.toFinset_card_le _
_ ≤ _ := card_roots_sub_C' hp)
#align finite_field.card_image_polynomial_eval FiniteField.card_image_polynomial_eval
@@ -86,7 +86,7 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
lt_irrefl (2 * ((univ.image fun x : R => eval x f) ∪ univ.image fun x : R => eval x (-g)).card) <|
calc 2 * ((univ.image fun x : R => eval x f) ∪ univ.image fun x : R => eval x (-g)).card
≤ 2 * Fintype.card R := Nat.mul_le_mul_left _ (Finset.card_le_univ _)
- _ = Fintype.card R + Fintype.card R := (two_mul _)
+ _ = Fintype.card R + Fintype.card R := two_mul _
_ < natDegree f * (univ.image fun x : R => eval x f).card +
natDegree (-g) * (univ.image fun x : R => eval x (-g)).card :=
(add_lt_add_of_lt_of_le
@@ -90,9 +90,9 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
_ < natDegree f * (univ.image fun x : R => eval x f).card +
natDegree (-g) * (univ.image fun x : R => eval x (-g)).card :=
(add_lt_add_of_lt_of_le
- (lt_of_le_of_ne (card_image_polynomial_eval (by rw [hf2]; exact by decide))
+ (lt_of_le_of_ne (card_image_polynomial_eval (by rw [hf2]; decide))
(mt (congr_arg (· % 2)) (by simp [natDegree_eq_of_degree_eq_some hf2, hR])))
- (card_image_polynomial_eval (by rw [degree_neg, hg2]; exact by decide)))
+ (card_image_polynomial_eval (by rw [degree_neg, hg2]; decide)))
_ = 2 * ((univ.image fun x : R => eval x f) ∪ univ.image fun x : R => eval x (-g)).card := by
rw [card_union_of_disjoint hd];
simp [natDegree_eq_of_degree_eq_some hf2, natDegree_eq_of_degree_eq_some hg2, mul_add]
@@ -359,7 +359,7 @@ theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := b
have : (roots (X ^ q - X : K[X])).toFinset = Finset.univ := by
rw [eq_univ_iff_forall]
intro x
- rw [Multiset.mem_toFinset, mem_roots aux, IsRoot.definition, eval_sub, eval_pow, eval_X,
+ rw [Multiset.mem_toFinset, mem_roots aux, IsRoot.def, eval_sub, eval_pow, eval_X,
sub_eq_zero, pow_card]
rw [← this, Multiset.toFinset_val, eq_comm, Multiset.dedup_eq_self]
apply nodup_roots
@@ -46,7 +46,6 @@ diamonds, as `Fintype` carries data.
variable {K : Type*} {R : Type*}
--- mathport name: exprq
local notation "q" => Fintype.card K
open Finset
coe_nat
to natCast
(#11637)
Reduce the diff of #11499
All in the Int
namespace:
ofNat_eq_cast
→ ofNat_eq_natCast
cast_eq_cast_iff_Nat
→ natCast_inj
natCast_eq_ofNat
→ ofNat_eq_natCast
coe_nat_sub
→ natCast_sub
coe_nat_nonneg
→ natCast_nonneg
sign_coe_add_one
→ sign_natCast_add_one
nat_succ_eq_int_succ
→ natCast_succ
succ_neg_nat_succ
→ succ_neg_natCast_succ
coe_pred_of_pos
→ natCast_pred_of_pos
coe_nat_div
→ natCast_div
coe_nat_ediv
→ natCast_ediv
sign_coe_nat_of_nonzero
→ sign_natCast_of_ne_zero
toNat_coe_nat
→ toNat_natCast
toNat_coe_nat_add_one
→ toNat_natCast_add_one
coe_nat_dvd
→ natCast_dvd_natCast
coe_nat_dvd_left
→ natCast_dvd
coe_nat_dvd_right
→ dvd_natCast
le_coe_nat_sub
→ le_natCast_sub
succ_coe_nat_pos
→ succ_natCast_pos
coe_nat_modEq_iff
→ natCast_modEq_iff
coe_natAbs
→ natCast_natAbs
coe_nat_eq_zero
→ natCast_eq_zero
coe_nat_ne_zero
→ natCast_ne_zero
coe_nat_ne_zero_iff_pos
→ natCast_ne_zero_iff_pos
abs_coe_nat
→ abs_natCast
coe_nat_nonpos_iff
→ natCast_nonpos_iff
Also rename Nat.coe_nat_dvd
to Nat.cast_dvd_cast
@@ -436,7 +436,7 @@ theorem Nat.sq_add_sq_zmodEq (p : ℕ) [Fact p.Prime] (x : ℤ) :
`ZMod.sq_add_sq` with estimates on `a` and `b`. -/
theorem Nat.sq_add_sq_modEq (p : ℕ) [Fact p.Prime] (x : ℕ) :
∃ a b : ℕ, a ≤ p / 2 ∧ b ≤ p / 2 ∧ a ^ 2 + b ^ 2 ≡ x [MOD p] := by
- simpa only [← Int.coe_nat_modEq_iff] using Nat.sq_add_sq_zmodEq p x
+ simpa only [← Int.natCast_modEq_iff] using Nat.sq_add_sq_zmodEq p x
namespace CharP
We change the following field in the definition of an additive commutative monoid:
nsmul_succ : ∀ (n : ℕ) (x : G),
- AddMonoid.nsmul (n + 1) x = x + AddMonoid.nsmul n x
+ AddMonoid.nsmul (n + 1) x = AddMonoid.nsmul n x + x
where the latter is more natural
We adjust the definitions of ^
in monoids, groups, etc.
Originally there was a warning comment about why this natural order was preferred
use
x * npowRec n x
and notnpowRec n x * x
in the definition to make sure that definitional unfolding ofnpowRec
is blocked, to avoid deep recursion issues.
but it seems to no longer apply.
Remarks on the PR :
pow_succ
and pow_succ'
have switched their meanings.Ideal.IsPrime.mul_mem_pow
which is defined in [Mathlib/RingTheory/DedekindDomain/Ideal.lean]. Changing the order of operation forced me to add the symmetric lemma Ideal.IsPrime.mem_pow_mul
.@@ -226,7 +226,7 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 := by
theorem pow_card (a : K) : a ^ q = a := by
by_cases h : a = 0; · rw [h]; apply zero_pow Fintype.card_ne_zero
rw [← Nat.succ_pred_eq_of_pos Fintype.card_pos, pow_succ, Nat.pred_eq_sub_one,
- pow_card_sub_one_eq_one a h, mul_one]
+ pow_card_sub_one_eq_one a h, one_mul]
#align finite_field.pow_card FiniteField.pow_card
theorem pow_card_pow (n : ℕ) (a : K) : a ^ q ^ n = a := by
@@ -379,7 +379,7 @@ theorem frobenius_pow {p : ℕ} [Fact p.Prime] [CharP K p] {n : ℕ} (hcard : q
clear hcard
induction' n with n hn
· simp
- · rw [pow_succ, pow_succ', pow_mul, RingHom.mul_def, RingHom.comp_apply, frobenius_def, hn]
+ · rw [pow_succ', pow_succ, pow_mul, RingHom.mul_def, RingHom.comp_apply, frobenius_def, hn]
#align finite_field.frobenius_pow FiniteField.frobenius_pow
open Polynomial
Move basic Nat
lemmas from Data.Nat.Order.Basic
and Data.Nat.Pow
to Data.Nat.Defs
. Most proofs need adapting, but that's easily solved by replacing the general mathlib lemmas by the new Std Nat
-specific lemmas and using omega
.
Data.Nat.Pow
to Algebra.GroupPower.Order
Data.Nat.Pow
to Algebra.GroupPower.Order
bit
/bit0
/bit1
lemmas from Data.Nat.Order.Basic
to Data.Nat.Bits
Data.Nat.Order.Basic
anymoreNat
-specific lemmas to help fix the fallout (look for nolint simpNF
)Nat.mul_self_le_mul_self_iff
and Nat.mul_self_lt_mul_self_iff
around (they were misnamed)Nat.one_lt_pow
implicit@@ -333,7 +333,7 @@ set_option linter.uppercaseLean3 false in
theorem X_pow_card_pow_sub_X_natDegree_eq (hn : n ≠ 0) (hp : 1 < p) :
(X ^ p ^ n - X : K'[X]).natDegree = p ^ n :=
- X_pow_card_sub_X_natDegree_eq K' <| Nat.one_lt_pow _ _ hn hp
+ X_pow_card_sub_X_natDegree_eq K' <| Nat.one_lt_pow hn hp
set_option linter.uppercaseLean3 false in
#align finite_field.X_pow_card_pow_sub_X_nat_degree_eq FiniteField.X_pow_card_pow_sub_X_natDegree_eq
@@ -346,7 +346,7 @@ set_option linter.uppercaseLean3 false in
#align finite_field.X_pow_card_sub_X_ne_zero FiniteField.X_pow_card_sub_X_ne_zero
theorem X_pow_card_pow_sub_X_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (X ^ p ^ n - X : K'[X]) ≠ 0 :=
- X_pow_card_sub_X_ne_zero K' <| Nat.one_lt_pow _ _ hn hp
+ X_pow_card_sub_X_ne_zero K' <| Nat.one_lt_pow hn hp
set_option linter.uppercaseLean3 false in
#align finite_field.X_pow_card_pow_sub_X_ne_zero FiniteField.X_pow_card_pow_sub_X_ne_zero
These will be caught by the linter in a future lean version.
@@ -204,13 +204,10 @@ theorem sum_subgroup_pow_eq_zero [CommRing K] [NoZeroDivisors K]
* (Multiset.map (fun i : G => (i.val : K) ^ k) Finset.univ.val).sum = 0 := by
rw [sub_mul, mul_comm, ← h_multiset_map_sum, one_mul, sub_self]
rw [mul_eq_zero] at hzero
- rcases hzero with h | h
- · contrapose! ha
- ext
- rw [← sub_eq_zero]
- simp_rw [SubmonoidClass.coe_pow, Units.val_pow_eq_pow_val, OneMemClass.coe_one,
- Units.val_one, h]
- · exact h
+ refine hzero.resolve_left fun h => ha ?_
+ ext
+ rw [← sub_eq_zero]
+ simp_rw [SubmonoidClass.coe_pow, Units.val_pow_eq_pow_val, OneMemClass.coe_one, Units.val_one, h]
section
@@ -363,7 +363,7 @@ theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := b
have : (roots (X ^ q - X : K[X])).toFinset = Finset.univ := by
rw [eq_univ_iff_forall]
intro x
- rw [Multiset.mem_toFinset, mem_roots aux, IsRoot.def, eval_sub, eval_pow, eval_X,
+ rw [Multiset.mem_toFinset, mem_roots aux, IsRoot.definition, eval_sub, eval_pow, eval_X,
sub_eq_zero, pow_card]
rw [← this, Multiset.toFinset_val, eq_comm, Multiset.dedup_eq_self]
apply nodup_roots
Homogenises porting notes via capitalisation and addition of whitespace.
It makes the following changes:
@@ -261,7 +261,7 @@ theorem card' : ∃ (p : ℕ) (n : ℕ+), Nat.Prime p ∧ Fintype.card K = p ^ (
⟨p, @FiniteField.card K _ _ p hc⟩
#align finite_field.card' FiniteField.card'
---Porting note: this was a `simp` lemma with a 5 lines proof.
+-- Porting note: this was a `simp` lemma with a 5 lines proof.
theorem cast_card_eq_zero : (q : K) = 0 := by
simp
#align finite_field.cast_card_eq_zero FiniteField.cast_card_eq_zero
@@ -519,7 +519,7 @@ theorem frobenius_zmod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom
rw [frobenius_def, ZMod.pow_card, RingHom.id_apply]
#align zmod.frobenius_zmod ZMod.frobenius_zmod
---Porting note: this was a `simp` lemma, but now the LHS simplify to `φ p`.
+-- Porting note: this was a `simp` lemma, but now the LHS simplify to `φ p`.
theorem card_units (p : ℕ) [Fact p.Prime] : Fintype.card (ZMod p)ˣ = p - 1 := by
rw [Fintype.card_units, card]
#align zmod.card_units ZMod.card_units
@@ -152,7 +152,7 @@ theorem sum_subgroup_units_eq_zero [Ring K] [NoZeroDivisors K]
have h_sum_map := Finset.univ.sum_map a_mul_emb fun x => ((x : Kˣ) : K)
-- ... and the former is the sum of x over G.
-- By algebraic manipulation, we have Σ G, x = ∑ G, a x = a ∑ G, x
- simp only [h_unchanged, Function.Embedding.coeFn_mk, Function.Embedding.toFun_eq_coe,
+ simp only [a_mul_emb, h_unchanged, Function.Embedding.coeFn_mk, Function.Embedding.toFun_eq_coe,
mulLeftEmbedding_apply, Submonoid.coe_mul, Subgroup.coe_toSubmonoid, Units.val_mul,
← Finset.mul_sum] at h_sum_map
-- thus one of (a - 1) or ∑ G, x is zero
@@ -298,7 +298,7 @@ theorem sum_pow_units [DecidableEq K] (i : ℕ) :
cast_card_eq_zero, Nat.cast_one, zero_sub]
show 1 ≤ q; exact Fintype.card_pos_iff.mpr ⟨0⟩
rw [← forall_pow_eq_one_iff, DFunLike.ext_iff]
- apply forall_congr'; intro x; simp [Units.ext_iff]
+ apply forall_congr'; intro x; simp [φ, Units.ext_iff]
#align finite_field.sum_pow_units FiniteField.sum_pow_units
/-- The sum of `x ^ i` as `x` ranges over a finite field of cardinality `q`
@@ -311,12 +311,12 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0
let φ : Kˣ ↪ K := ⟨fun x ↦ x, Units.ext⟩
have : univ.map φ = univ \ {0} := by
ext x
- simp only [true_and_iff, Function.Embedding.coeFn_mk, mem_sdiff, Units.exists_iff_ne_zero,
+ simp only [φ, true_and_iff, Function.Embedding.coeFn_mk, mem_sdiff, Units.exists_iff_ne_zero,
mem_univ, mem_map, exists_prop_of_true, mem_singleton]
calc
∑ x : K, x ^ i = ∑ x in univ \ {(0 : K)}, x ^ i := by
rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton, zero_pow hi, add_zero]
- _ = ∑ x : Kˣ, (x ^ i : K) := by simp [← this, univ.sum_map φ]
+ _ = ∑ x : Kˣ, (x ^ i : K) := by simp [φ, ← this, univ.sum_map φ]
_ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
@@ -416,7 +416,7 @@ theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p,
(by rw [ZMod.card, hp_odd])
refine' ⟨a, b, _⟩
rw [← sub_eq_zero]
- simpa only [eval_C, eval_X, eval_pow, eval_sub, ← add_sub_assoc] using hab
+ simpa only [f, g, eval_C, eval_X, eval_pow, eval_sub, ← add_sub_assoc] using hab
#align zmod.sq_add_sq ZMod.sq_add_sq
end ZMod
have
, replace
and suffices
(#10640)
No changes to tactic file, it's just boring fixes throughout the library.
This follows on from #6964.
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>
@@ -196,10 +196,9 @@ theorem sum_subgroup_pow_eq_zero [CommRing K] [NoZeroDivisors K]
congr
rw [eq_comm]
exact Multiset.map_univ_val_equiv (Equiv.mulRight a)
- have h_multiset_map_sum :
- (Multiset.map (fun x : G => ((x : Kˣ) : K) ^ k) Finset.univ.val).sum =
- (Multiset.map (fun x : G => ((x : Kˣ) : K) ^ k * ((a : Kˣ) : K) ^ k) Finset.univ.val).sum
- rw [h_multiset_map]
+ have h_multiset_map_sum : (Multiset.map (fun x : G => ((x : Kˣ) : K) ^ k) Finset.univ.val).sum =
+ (Multiset.map (fun x : G => ((x : Kˣ) : K) ^ k * ((a : Kˣ) : K) ^ k) Finset.univ.val).sum := by
+ rw [h_multiset_map]
rw [Multiset.sum_map_mul_right] at h_multiset_map_sum
have hzero : (((a : Kˣ) : K) ^ k - 1 : K)
* (Multiset.map (fun i : G => (i.val : K) ^ k) Finset.univ.val).sum = 0 := by
(s ∩ t).card = s.card + t.card - (s ∪ t).card
(#10224)
once coerced to an AddGroupWithOne
. Also unify Finset.card_disjoint_union
and Finset.card_union_eq
From LeanAPAP
@@ -95,7 +95,7 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
(mt (congr_arg (· % 2)) (by simp [natDegree_eq_of_degree_eq_some hf2, hR])))
(card_image_polynomial_eval (by rw [degree_neg, hg2]; exact by decide)))
_ = 2 * ((univ.image fun x : R => eval x f) ∪ univ.image fun x : R => eval x (-g)).card := by
- rw [card_disjoint_union hd];
+ rw [card_union_of_disjoint hd];
simp [natDegree_eq_of_degree_eq_some hf2, natDegree_eq_of_degree_eq_some hg2, mul_add]
#align finite_field.exists_root_sum_quadratic FiniteField.exists_root_sum_quadratic
f ^ n
(#9617)
This involves moving lemmas from Algebra.GroupPower.Ring
to Algebra.GroupWithZero.Basic
and changing some 0 < n
assumptions to n ≠ 0
.
From LeanAPAP
@@ -228,10 +228,9 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 := by
#align finite_field.pow_card_sub_one_eq_one FiniteField.pow_card_sub_one_eq_one
theorem pow_card (a : K) : a ^ q = a := by
- have hp : 0 < Fintype.card K := lt_trans zero_lt_one Fintype.one_lt_card
- by_cases h : a = 0; · rw [h]; apply zero_pow hp
- rw [← Nat.succ_pred_eq_of_pos hp, pow_succ, Nat.pred_eq_sub_one, pow_card_sub_one_eq_one a h,
- mul_one]
+ by_cases h : a = 0; · rw [h]; apply zero_pow Fintype.card_ne_zero
+ rw [← Nat.succ_pred_eq_of_pos Fintype.card_pos, pow_succ, Nat.pred_eq_sub_one,
+ pow_card_sub_one_eq_one a h, mul_one]
#align finite_field.pow_card FiniteField.pow_card
theorem pow_card_pow (n : ℕ) (a : K) : a ^ q ^ n = a := by
@@ -317,8 +316,7 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0
mem_univ, mem_map, exists_prop_of_true, mem_singleton]
calc
∑ x : K, x ^ i = ∑ x in univ \ {(0 : K)}, x ^ i := by
- rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton,
- zero_pow (Nat.pos_of_ne_zero hi), add_zero]
+ rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton, zero_pow hi, add_zero]
_ = ∑ x : Kˣ, (x ^ i : K) := by simp [← this, univ.sum_map φ]
_ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
Motivated by @Ruben-VandeVelde's leanprover-community/mathlib#15206
@@ -586,17 +586,9 @@ theorem isSquare_of_char_two (hF : ringChar F = 2) (a : F) : IsSquare a :=
/-- In a finite field of odd characteristic, not every element is a square. -/
theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a := by
-- Idea: the squaring map on `F` is not injective, hence not surjective
- let sq : F → F := fun x => x ^ 2
- have h : ¬Function.Injective sq := by
- simp only [Function.Injective, not_forall, exists_prop]
- refine' ⟨-1, 1, _, Ring.neg_one_ne_one_of_char_ne_two hF⟩
- simp only [one_pow, neg_one_sq]
- rw [Finite.injective_iff_surjective] at h
- -- sq not surjective
- simp_rw [IsSquare, ← pow_two, @eq_comm _ _ (_ ^ 2)]
- unfold Function.Surjective at h
- push_neg at h ⊢
- exact h
+ have h : ¬Function.Injective fun x : F ↦ x * x := fun h ↦
+ h.ne (Ring.neg_one_ne_one_of_char_ne_two hF) <| by simp
+ simpa [Finite.injective_iff_surjective, Function.Surjective, IsSquare, eq_comm] using h
#align finite_field.exists_nonsquare FiniteField.exists_nonsquare
end Finite
@@ -606,14 +598,8 @@ variable [Fintype F]
/-- The finite field `F` has even cardinality iff it has characteristic `2`. -/
theorem even_card_iff_char_two : ringChar F = 2 ↔ Fintype.card F % 2 = 0 := by
rcases FiniteField.card F (ringChar F) with ⟨n, hp, h⟩
- rw [h, Nat.pow_mod]
- constructor
- · intro hF
- simp [hF]
- · rw [← Nat.even_iff, Nat.even_pow]
- rintro ⟨hev, hnz⟩
- rw [Nat.even_iff, Nat.mod_mod] at hev
- exact (Nat.Prime.eq_two_or_odd hp).resolve_right (ne_of_eq_of_ne hev zero_ne_one)
+ rw [h, ← Nat.even_iff, Nat.even_pow, hp.even_iff]
+ simp
#align finite_field.even_card_iff_char_two FiniteField.even_card_iff_char_two
theorem even_card_of_char_two (hF : ringChar F = 2) : Fintype.card F % 2 = 0 :=
FunLike
to DFunLike
(#9785)
This prepares for the introduction of a non-dependent synonym of FunLike, which helps a lot with keeping #8386 readable.
This is entirely search-and-replace in 680197f combined with manual fixes in 4145626, e900597 and b8428f8. The commands that generated this change:
sed -i 's/\bFunLike\b/DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoFunLike\b/toDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/import Mathlib.Data.DFunLike/import Mathlib.Data.FunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bHom_FunLike\b/Hom_DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\binstFunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bfunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoo many metavariables to apply `fun_like.has_coe_to_fun`/too many metavariables to apply `DFunLike.hasCoeToFun`/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>
@@ -299,7 +299,7 @@ theorem sum_pow_units [DecidableEq K] (i : ℕ) :
· rw [Fintype.card_units, Nat.cast_sub,
cast_card_eq_zero, Nat.cast_one, zero_sub]
show 1 ≤ q; exact Fintype.card_pos_iff.mpr ⟨0⟩
- rw [← forall_pow_eq_one_iff, FunLike.ext_iff]
+ rw [← forall_pow_eq_one_iff, DFunLike.ext_iff]
apply forall_congr'; intro x; simp [Units.ext_iff]
#align finite_field.sum_pow_units FiniteField.sum_pow_units
The names for lemmas about monotonicity of (a ^ ·)
and (· ^ n)
were a mess. This PR tidies up everything related by following the naming convention for (a * ·)
and (· * b)
. Namely, (a ^ ·)
is pow_right
and (· ^ n)
is pow_left
in lemma names. All lemma renames follow the corresponding multiplication lemma names closely.
Algebra.GroupPower.Order
pow_mono
→ pow_right_mono
pow_le_pow
→ pow_le_pow_right
pow_le_pow_of_le_left
→ pow_le_pow_left
pow_lt_pow_of_lt_left
→ pow_lt_pow_left
strictMonoOn_pow
→ pow_left_strictMonoOn
pow_strictMono_right
→ pow_right_strictMono
pow_lt_pow
→ pow_lt_pow_right
pow_lt_pow_iff
→ pow_lt_pow_iff_right
pow_le_pow_iff
→ pow_le_pow_iff_right
self_lt_pow
→ lt_self_pow
strictAnti_pow
→ pow_right_strictAnti
pow_lt_pow_iff_of_lt_one
→ pow_lt_pow_iff_right_of_lt_one
pow_lt_pow_of_lt_one
→ pow_lt_pow_right_of_lt_one
lt_of_pow_lt_pow
→ lt_of_pow_lt_pow_left
le_of_pow_le_pow
→ le_of_pow_le_pow_left
pow_lt_pow₀
→ pow_lt_pow_right₀
Algebra.GroupPower.CovariantClass
pow_le_pow_of_le_left'
→ pow_le_pow_left'
nsmul_le_nsmul_of_le_right
→ nsmul_le_nsmul_right
pow_lt_pow'
→ pow_lt_pow_right'
nsmul_lt_nsmul
→ nsmul_lt_nsmul_left
pow_strictMono_left
→ pow_right_strictMono'
nsmul_strictMono_right
→ nsmul_left_strictMono
StrictMono.pow_right'
→ StrictMono.pow_const
StrictMono.nsmul_left
→ StrictMono.const_nsmul
pow_strictMono_right'
→ pow_left_strictMono
nsmul_strictMono_left
→ nsmul_right_strictMono
Monotone.pow_right
→ Monotone.pow_const
Monotone.nsmul_left
→ Monotone.const_nsmul
lt_of_pow_lt_pow'
→ lt_of_pow_lt_pow_left'
lt_of_nsmul_lt_nsmul
→ lt_of_nsmul_lt_nsmul_right
pow_le_pow'
→ pow_le_pow_right'
nsmul_le_nsmul
→ nsmul_le_nsmul_left
pow_le_pow_of_le_one'
→ pow_le_pow_right_of_le_one'
nsmul_le_nsmul_of_nonpos
→ nsmul_le_nsmul_left_of_nonpos
le_of_pow_le_pow'
→ le_of_pow_le_pow_left'
le_of_nsmul_le_nsmul'
→ le_of_nsmul_le_nsmul_right'
pow_le_pow_iff'
→ pow_le_pow_iff_right'
nsmul_le_nsmul_iff
→ nsmul_le_nsmul_iff_left
pow_lt_pow_iff'
→ pow_lt_pow_iff_right'
nsmul_lt_nsmul_iff
→ nsmul_lt_nsmul_iff_left
Data.Nat.Pow
Nat.pow_lt_pow_of_lt_left
→ Nat.pow_lt_pow_left
Nat.pow_le_iff_le_left
→ Nat.pow_le_pow_iff_left
Nat.pow_lt_iff_lt_left
→ Nat.pow_lt_pow_iff_left
pow_le_pow_iff_left
pow_lt_pow_iff_left
pow_right_injective
pow_right_inj
Nat.pow_le_pow_left
to have the correct name since Nat.pow_le_pow_of_le_left
is in Std.Nat.pow_le_pow_right
to have the correct name since Nat.pow_le_pow_of_le_right
is in Std.self_le_pow
was a duplicate of le_self_pow
.Nat.pow_lt_pow_of_lt_right
is defeq to pow_lt_pow_right
.Nat.pow_right_strictMono
is defeq to pow_right_strictMono
.Nat.pow_le_iff_le_right
is defeq to pow_le_pow_iff_right
.Nat.pow_lt_iff_lt_right
is defeq to pow_lt_pow_iff_right
.0 < n
or 1 ≤ n
to n ≠ 0
.Nat
lemmas have been protected
.@@ -339,7 +339,7 @@ set_option linter.uppercaseLean3 false in
theorem X_pow_card_pow_sub_X_natDegree_eq (hn : n ≠ 0) (hp : 1 < p) :
(X ^ p ^ n - X : K'[X]).natDegree = p ^ n :=
- X_pow_card_sub_X_natDegree_eq K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
+ X_pow_card_sub_X_natDegree_eq K' <| Nat.one_lt_pow _ _ hn hp
set_option linter.uppercaseLean3 false in
#align finite_field.X_pow_card_pow_sub_X_nat_degree_eq FiniteField.X_pow_card_pow_sub_X_natDegree_eq
@@ -352,7 +352,7 @@ set_option linter.uppercaseLean3 false in
#align finite_field.X_pow_card_sub_X_ne_zero FiniteField.X_pow_card_sub_X_ne_zero
theorem X_pow_card_pow_sub_X_ne_zero (hn : n ≠ 0) (hp : 1 < p) : (X ^ p ^ n - X : K'[X]) ≠ 0 :=
- X_pow_card_sub_X_ne_zero K' <| Nat.one_lt_pow _ _ (Nat.pos_of_ne_zero hn) hp
+ X_pow_card_sub_X_ne_zero K' <| Nat.one_lt_pow _ _ hn hp
set_option linter.uppercaseLean3 false in
#align finite_field.X_pow_card_pow_sub_X_ne_zero FiniteField.X_pow_card_pow_sub_X_ne_zero
@@ -5,6 +5,7 @@ Authors: Chris Hughes, Joey van Langen, Casper Putz
-/
import Mathlib.FieldTheory.Separable
import Mathlib.RingTheory.IntegralDomain
+import Mathlib.Algebra.CharP.Reduced
import Mathlib.Tactic.ApplyFun
#align_import field_theory.finite.basic from "leanprover-community/mathlib"@"12a85fac627bea918960da036049d611b1a3ee43"
@@ -156,11 +156,11 @@ theorem sum_subgroup_units_eq_zero [Ring K] [NoZeroDivisors K]
← Finset.mul_sum] at h_sum_map
-- thus one of (a - 1) or ∑ G, x is zero
have hzero : (((a : Kˣ) : K) - 1) = 0 ∨ ∑ x : ↥G, ((x : Kˣ) : K) = 0 := by
- rw [←mul_eq_zero, sub_mul, ← h_sum_map, one_mul, sub_self]
+ rw [← mul_eq_zero, sub_mul, ← h_sum_map, one_mul, sub_self]
apply Or.resolve_left hzero
contrapose! ha
ext
- rwa [←sub_eq_zero]
+ rwa [← sub_eq_zero]
/-- The sum of a subgroup of the units of a field is 1 if the subgroup is trivial and 1 otherwise -/
@[simp]
@@ -207,7 +207,7 @@ theorem sum_subgroup_pow_eq_zero [CommRing K] [NoZeroDivisors K]
rcases hzero with h | h
· contrapose! ha
ext
- rw [←sub_eq_zero]
+ rw [← sub_eq_zero]
simp_rw [SubmonoidClass.coe_pow, Units.val_pow_eq_pow_val, OneMemClass.coe_one,
Units.val_one, h]
· exact h
This adds NumberTheory.DirichletCharacter.Bounds
containing proofs of ‖χ a‖ = 1
if a
is a unit and ‖χ a‖ ≤ 1
in general, where χ
is a Dirichlet character with values in a normed field.
There are also two API lemmas added elsewhere that are used in the proofs.
@@ -479,6 +479,11 @@ theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.Coprime x n) : x ^ φ n ≡ 1
coe_unitOfCoprime, Units.val_pow_eq_pow_val]
#align nat.modeq.pow_totient Nat.ModEq.pow_totient
+/-- For each `n ≥ 0`, the unit group of `ZMod n` is finite. -/
+instance instFiniteZModUnits : (n : ℕ) → Finite (ZMod n)ˣ
+| 0 => Finite.of_fintype ℤˣ
+| _ + 1 => instFiniteUnits
+
section
variable {V : Type*} [Fintype K] [DivisionRing K] [AddCommGroup V] [Module K V]
exact_mod_cast
tactic with mod_cast
elaborator where possible (#8404)
We still have the exact_mod_cast
tactic, used in a few places, which somehow (?) works a little bit harder to prevent the expected type influencing the elaboration of the term. I would like to get to the bottom of this, and it will be easier once the only usages of exact_mod_cast
are the ones that don't work using the term elaborator by itself.
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -331,8 +331,7 @@ variable (K' : Type*) [Field K'] {p n : ℕ}
theorem X_pow_card_sub_X_natDegree_eq (hp : 1 < p) : (X ^ p - X : K'[X]).natDegree = p := by
have h1 : (X : K'[X]).degree < (X ^ p : K'[X]).degree := by
rw [degree_X_pow, degree_X]
- -- Porting note: the following line was `exact_mod_cast hp`
- exact WithBot.coe_lt_coe.2 hp
+ exact mod_cast hp
rw [natDegree_eq_of_degree_eq (degree_sub_eq_left_of_degree_lt h1), natDegree_X_pow]
set_option linter.uppercaseLean3 false in
#align finite_field.X_pow_card_sub_X_nat_degree_eq FiniteField.X_pow_card_sub_X_natDegree_eq
@@ -435,7 +434,7 @@ theorem Nat.sq_add_sq_zmodEq (p : ℕ) [Fact p.Prime] (x : ℤ) :
rw [← a.coe_valMinAbs, ← b.coe_valMinAbs] at hx
push_cast
rw [sq_abs, sq_abs, ← ZMod.int_cast_eq_int_cast_iff]
- exact_mod_cast hx
+ exact mod_cast hx
/-- If `p` is a prime natural number and `x` is a natural number, then there exist natural numbers
`a ≤ p / 2` and `b ≤ p / 2` such that `a ^ 2 + b ^ 2 ≡ x [MOD p]`. This is a version of
The cardinality of a subgroup is greater than the order of any of its elements.
Rename
order_eq_card_zpowers
→ Fintype.card_zpowers
order_eq_card_zpowers'
→ Nat.card_zpowers
(and turn it around to match Nat.card_subgroupPowers
)Submonoid.powers_subset
→ Submonoid.powers_le
orderOf_dvd_card_univ
→ orderOf_dvd_card
orderOf_subgroup
→ Subgroup.orderOf
Subgroup.nonempty
→ Subgroup.coe_nonempty
@@ -126,7 +126,7 @@ theorem card_cast_subgroup_card_ne_zero [Ring K] [NoZeroDivisors K] [Nontrivial
have ⟨x, hx⟩ := exists_prime_orderOf_dvd_card p hd
-- F has an element u (= ↑↑x) of order p
let u := ((x : Kˣ) : K)
- have hu : orderOf u = p := by rwa [orderOf_units, orderOf_subgroup]
+ have hu : orderOf u = p := by rwa [orderOf_units, Subgroup.orderOf_coe]
-- u ^ p = 1 implies (u - 1) ^ p = 0 and hence u = 1 ...
have h : u = 1 := by
rw [← sub_left_inj, sub_self 1]
Adds a theorem saying the cardinality of a multiplicative subgroup of a field, cast to the field, is nonzero. As well as sum_subgroup_units_zero_of_ne_bot
and other theorems about summing over multiplicative subgroups.
Co-authored-by: Pratyush Mishra <prat@upenn.edu> Co-authored-by: Buster <rcopley@gmail.com>
@@ -111,6 +111,107 @@ theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
rw [← insert_erase (mem_univ (-1 : Kˣ)), prod_insert (not_mem_erase _ _), this, mul_one]
#align finite_field.prod_univ_units_id_eq_neg_one FiniteField.prod_univ_units_id_eq_neg_one
+theorem card_cast_subgroup_card_ne_zero [Ring K] [NoZeroDivisors K] [Nontrivial K]
+ (G : Subgroup Kˣ) [Fintype G] : (Fintype.card G : K) ≠ 0 := by
+ let n := Fintype.card G
+ intro nzero
+ have ⟨p, char_p⟩ := CharP.exists K
+ have hd : p ∣ n := (CharP.cast_eq_zero_iff K p n).mp nzero
+ cases CharP.char_is_prime_or_zero K p with
+ | inr pzero =>
+ exact (Fintype.card_pos).ne' <| Nat.eq_zero_of_zero_dvd <| pzero ▸ hd
+ | inl pprime =>
+ have fact_pprime := Fact.mk pprime
+ -- G has an element x of order p by Cauchy's theorem
+ have ⟨x, hx⟩ := exists_prime_orderOf_dvd_card p hd
+ -- F has an element u (= ↑↑x) of order p
+ let u := ((x : Kˣ) : K)
+ have hu : orderOf u = p := by rwa [orderOf_units, orderOf_subgroup]
+ -- u ^ p = 1 implies (u - 1) ^ p = 0 and hence u = 1 ...
+ have h : u = 1 := by
+ rw [← sub_left_inj, sub_self 1]
+ apply pow_eq_zero (n := p)
+ rw [sub_pow_char_of_commute, one_pow, ← hu, pow_orderOf_eq_one, sub_self]
+ exact Commute.one_right u
+ -- ... meaning x didn't have order p after all, contradiction
+ apply pprime.one_lt.ne
+ rw [← hu, h, orderOf_one]
+
+/-- The sum of a nontrivial subgroup of the units of a field is zero. -/
+theorem sum_subgroup_units_eq_zero [Ring K] [NoZeroDivisors K]
+ {G : Subgroup Kˣ} [Fintype G] (hg : G ≠ ⊥) :
+ ∑ x : G, (x.val : K) = 0 := by
+ rw [Subgroup.ne_bot_iff_exists_ne_one] at hg
+ rcases hg with ⟨a, ha⟩
+ -- The action of a on G as an embedding
+ let a_mul_emb : G ↪ G := mulLeftEmbedding a
+ -- ... and leaves G unchanged
+ have h_unchanged : Finset.univ.map a_mul_emb = Finset.univ := by simp
+ -- Therefore the sum of x over a G is the sum of a x over G
+ have h_sum_map := Finset.univ.sum_map a_mul_emb fun x => ((x : Kˣ) : K)
+ -- ... and the former is the sum of x over G.
+ -- By algebraic manipulation, we have Σ G, x = ∑ G, a x = a ∑ G, x
+ simp only [h_unchanged, Function.Embedding.coeFn_mk, Function.Embedding.toFun_eq_coe,
+ mulLeftEmbedding_apply, Submonoid.coe_mul, Subgroup.coe_toSubmonoid, Units.val_mul,
+ ← Finset.mul_sum] at h_sum_map
+ -- thus one of (a - 1) or ∑ G, x is zero
+ have hzero : (((a : Kˣ) : K) - 1) = 0 ∨ ∑ x : ↥G, ((x : Kˣ) : K) = 0 := by
+ rw [←mul_eq_zero, sub_mul, ← h_sum_map, one_mul, sub_self]
+ apply Or.resolve_left hzero
+ contrapose! ha
+ ext
+ rwa [←sub_eq_zero]
+
+/-- The sum of a subgroup of the units of a field is 1 if the subgroup is trivial and 1 otherwise -/
+@[simp]
+theorem sum_subgroup_units [Ring K] [NoZeroDivisors K]
+ {G : Subgroup Kˣ} [Fintype G] [Decidable (G = ⊥)] :
+ ∑ x : G, (x.val : K) = if G = ⊥ then 1 else 0 := by
+ by_cases G_bot : G = ⊥
+ · subst G_bot
+ simp only [ite_true, Subgroup.mem_bot, Fintype.card_ofSubsingleton, Nat.cast_ite, Nat.cast_one,
+ Nat.cast_zero, univ_unique, Set.default_coe_singleton, sum_singleton, Units.val_one]
+ · simp only [G_bot, ite_false]
+ exact sum_subgroup_units_eq_zero G_bot
+
+@[simp]
+theorem sum_subgroup_pow_eq_zero [CommRing K] [NoZeroDivisors K]
+ {G : Subgroup Kˣ} [Fintype G] {k : ℕ} (k_pos : k ≠ 0) (k_lt_card_G : k < Fintype.card G) :
+ ∑ x : G, ((x : Kˣ) : K) ^ k = 0 := by
+ nontriviality K
+ have := NoZeroDivisors.to_isDomain K
+ rcases (exists_pow_ne_one_of_isCyclic k_pos k_lt_card_G) with ⟨a, ha⟩
+ rw [Finset.sum_eq_multiset_sum]
+ have h_multiset_map :
+ Finset.univ.val.map (fun x : G => ((x : Kˣ) : K) ^ k) =
+ Finset.univ.val.map (fun x : G => ((x : Kˣ) : K) ^ k * ((a : Kˣ) : K) ^ k) := by
+ simp_rw [← mul_pow]
+ have as_comp :
+ (fun x : ↥G => (((x : Kˣ) : K) * ((a : Kˣ) : K)) ^ k)
+ = (fun x : ↥G => ((x : Kˣ) : K) ^ k) ∘ fun x : ↥G => x * a := by
+ funext x
+ simp only [Function.comp_apply, Submonoid.coe_mul, Subgroup.coe_toSubmonoid, Units.val_mul]
+ rw [as_comp, ← Multiset.map_map]
+ congr
+ rw [eq_comm]
+ exact Multiset.map_univ_val_equiv (Equiv.mulRight a)
+ have h_multiset_map_sum :
+ (Multiset.map (fun x : G => ((x : Kˣ) : K) ^ k) Finset.univ.val).sum =
+ (Multiset.map (fun x : G => ((x : Kˣ) : K) ^ k * ((a : Kˣ) : K) ^ k) Finset.univ.val).sum
+ rw [h_multiset_map]
+ rw [Multiset.sum_map_mul_right] at h_multiset_map_sum
+ have hzero : (((a : Kˣ) : K) ^ k - 1 : K)
+ * (Multiset.map (fun i : G => (i.val : K) ^ k) Finset.univ.val).sum = 0 := by
+ rw [sub_mul, mul_comm, ← h_multiset_map_sum, one_mul, sub_self]
+ rw [mul_eq_zero] at hzero
+ rcases hzero with h | h
+ · contrapose! ha
+ ext
+ rw [←sub_eq_zero]
+ simp_rw [SubmonoidClass.coe_pow, Units.val_pow_eq_pow_val, OneMemClass.coe_one,
+ Units.val_one, h]
+ · exact h
+
section
variable [GroupWithZero K] [Fintype K]
@@ -370,7 +370,7 @@ theorem ZMod.pow_totient {n : ℕ} (x : (ZMod n)ˣ) : x ^ φ n = 1 := by
/-- The **Fermat-Euler totient theorem**. `ZMod.pow_totient` is an alternative statement
of the same theorem. -/
-theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1 [MOD n] := by
+theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.Coprime x n) : x ^ φ n ≡ 1 [MOD n] := by
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
have := ZMod.pow_totient x'
@@ -370,7 +370,7 @@ theorem ZMod.pow_totient {n : ℕ} (x : (ZMod n)ˣ) : x ^ φ n = 1 := by
/-- The **Fermat-Euler totient theorem**. `ZMod.pow_totient` is an alternative statement
of the same theorem. -/
-theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.Coprime x n) : x ^ φ n ≡ 1 [MOD n] := by
+theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1 [MOD n] := by
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
have := ZMod.pow_totient x'
Some changes have already been review and delegated in #6910 and #7148.
The diff that needs looking at is https://github.com/leanprover-community/mathlib4/pull/7174/commits/64d6d07ee18163627c8f517eb31455411921c5ac
The std bump PR was insta-merged already!
Co-authored-by: leanprover-community-mathlib4-bot <leanprover-community-mathlib4-bot@users.noreply.github.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -370,7 +370,7 @@ theorem ZMod.pow_totient {n : ℕ} (x : (ZMod n)ˣ) : x ^ φ n = 1 := by
/-- The **Fermat-Euler totient theorem**. `ZMod.pow_totient` is an alternative statement
of the same theorem. -/
-theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1 [MOD n] := by
+theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.Coprime x n) : x ^ φ n ≡ 1 [MOD n] := by
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
have := ZMod.pow_totient x'
@@ -538,7 +538,7 @@ theorem unit_isSquare_iff (hF : ringChar F ≠ 2) (a : Fˣ) :
constructor
· rintro ⟨y, rfl⟩
rw [← pow_two, ← pow_mul, hodd]
- apply_fun Units.val using Units.ext (α := F)
+ apply_fun Units.val using Units.ext
· push_cast
exact FiniteField.pow_card_sub_one_eq_one (y : F) (Units.ne_zero y)
· subst a; intro h
MulZeroClass.
in mul_zero
/zero_mul
(#6682)
Search&replace MulZeroClass.mul_zero
-> mul_zero
, MulZeroClass.zero_mul
-> zero_mul
.
These were introduced by Mathport, as the full name of mul_zero
is actually MulZeroClass.mul_zero
(it's exported with the short name).
@@ -272,7 +272,7 @@ theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := b
rw [separable_def]
convert isCoprime_one_right.neg_right (R := K[X]) using 1
rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
- MulZeroClass.zero_mul, zero_sub]
+ zero_mul, zero_sub]
set_option linter.uppercaseLean3 false in
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_X_pow_card_sub_X
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -43,7 +43,7 @@ diamonds, as `Fintype` carries data.
-/
-variable {K : Type _} {R : Type _}
+variable {K : Type*} {R : Type*}
-- mathport name: exprq
local notation "q" => Fintype.card K
@@ -225,7 +225,7 @@ open Polynomial
section
-variable (K' : Type _) [Field K'] {p n : ℕ}
+variable (K' : Type*) [Field K'] {p n : ℕ}
theorem X_pow_card_sub_X_natDegree_eq (hp : 1 < p) : (X ^ p - X : K'[X]).natDegree = p := by
have h1 : (X : K'[X]).degree < (X ^ p : K'[X]).degree := by
@@ -345,7 +345,7 @@ theorem Nat.sq_add_sq_modEq (p : ℕ) [Fact p.Prime] (x : ℕ) :
namespace CharP
-theorem sq_add_sq (R : Type _) [CommRing R] [IsDomain R] (p : ℕ) [NeZero p] [CharP R p] (x : ℤ) :
+theorem sq_add_sq (R : Type*) [CommRing R] [IsDomain R] (p : ℕ) [NeZero p] [CharP R p] (x : ℤ) :
∃ a b : ℕ, ((a : R) ^ 2 + (b : R) ^ 2) = x := by
haveI := char_is_prime_of_pos R p
obtain ⟨a, b, hab⟩ := ZMod.sq_add_sq p x
@@ -381,7 +381,7 @@ theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1
section
-variable {V : Type _} [Fintype K] [DivisionRing K] [AddCommGroup V] [Module K V]
+variable {V : Type*} [Fintype K] [DivisionRing K] [AddCommGroup V] [Module K V]
-- should this go in a namespace?
-- finite_dimensional would be natural,
@@ -465,7 +465,7 @@ section
namespace FiniteField
-variable {F : Type _} [Field F]
+variable {F : Type*} [Field F]
section Finite
@@ -22,7 +22,7 @@ cyclic group, as well as the fact that every finite integral domain is a field
## Main results
-1. `Fintype.card_units`: The unit group of a finite field is has cardinality `q - 1`.
+1. `Fintype.card_units`: The unit group of a finite field has cardinality `q - 1`.
2. `sum_pow_units`: The sum of `x^i`, where `x` ranges over the units of `K`, is
- `q-1` if `q-1 ∣ i`
- `0` otherwise
A lemma to reexpress card_units without subtraction.
@@ -181,7 +181,7 @@ theorem forall_pow_eq_one_iff (i : ℕ) : (∀ x : Kˣ, x ^ i = 1) ↔ q - 1 ∣
/-- The sum of `x ^ i` as `x` ranges over the units of a finite field of cardinality `q`
is equal to `0` unless `(q - 1) ∣ i`, in which case the sum is `q - 1`. -/
-theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
+theorem sum_pow_units [DecidableEq K] (i : ℕ) :
(∑ x : Kˣ, (x ^ i : K)) = if q - 1 ∣ i then -1 else 0 := by
let φ : Kˣ →* K :=
{ toFun := fun x => x ^ i
@@ -2,16 +2,13 @@
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Joey van Langen, Casper Putz
-
-! This file was ported from Lean 3 source module field_theory.finite.basic
-! leanprover-community/mathlib commit 12a85fac627bea918960da036049d611b1a3ee43
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.FieldTheory.Separable
import Mathlib.RingTheory.IntegralDomain
import Mathlib.Tactic.ApplyFun
+#align_import field_theory.finite.basic from "leanprover-community/mathlib"@"12a85fac627bea918960da036049d611b1a3ee43"
+
/-!
# Finite fields
This is the second half of the changes originally in #5699, removing all occurrences of ;
after a space and implementing a linter rule to enforce it.
In most cases this 2-character substring has a space after it, so the following command was run first:
find . -type f -name "*.lean" -exec sed -i -E 's/ ; /; /g' {} \;
The remaining cases were few enough in number that they were done manually.
@@ -189,7 +189,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
let φ : Kˣ →* K :=
{ toFun := fun x => x ^ i
map_one' := by simp
- map_mul' := by intros ; simp [mul_pow] }
+ map_mul' := by intros; simp [mul_pow] }
have : Decidable (φ = 1) := by classical infer_instance
calc (∑ x : Kˣ, φ x) = if φ = 1 then Fintype.card Kˣ else 0 := sum_hom_units φ
_ = if q - 1 ∣ i then -1 else 0 := by
∑'
precedence (#5615)
∑
, ∏
and variants).([^a-zA-Zα-ωΑ-Ω'𝓝ℳ₀𝕂ₛ)]) \(([∑∏][^()∑∏]*,[^()∑∏:]*)\) ([⊂⊆=<≤])
replaced by $1 $2 $3
@@ -105,7 +105,7 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
end Polynomial
theorem prod_univ_units_id_eq_neg_one [CommRing K] [IsDomain K] [Fintype Kˣ] :
- (∏ x : Kˣ, x) = (-1 : Kˣ) := by
+ ∏ x : Kˣ, x = (-1 : Kˣ) := by
classical
have : (∏ x in (@univ Kˣ _).erase (-1), x) = 1 :=
prod_involution (fun x _ => x⁻¹) (by simp)
@@ -206,7 +206,7 @@ theorem sum_pow_units [Fintype Kˣ] (i : ℕ) :
/-- The sum of `x ^ i` as `x` ranges over a finite field of cardinality `q`
is equal to `0` if `i < q - 1`. -/
-theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) = 0 := by
+theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : ∑ x : K, x ^ i = 0 := by
by_cases hi : i = 0
· simp only [hi, nsmul_one, sum_const, pow_zero, card_univ, cast_card_eq_zero]
classical
@@ -217,7 +217,7 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
simp only [true_and_iff, Function.Embedding.coeFn_mk, mem_sdiff, Units.exists_iff_ne_zero,
mem_univ, mem_map, exists_prop_of_true, mem_singleton]
calc
- (∑ x : K, x ^ i) = ∑ x in univ \ {(0 : K)}, x ^ i := by
+ ∑ x : K, x ^ i = ∑ x in univ \ {(0 : K)}, x ^ i := by
rw [← sum_sdiff ({0} : Finset K).subset_univ, sum_singleton,
zero_pow (Nat.pos_of_ne_zero hi), add_zero]
_ = ∑ x : Kˣ, (x ^ i : K) := by simp [← this, univ.sum_map φ]
at
and goals (#5387)
Changes are of the form
some_tactic at h⊢
-> some_tactic at h ⊢
some_tactic at h
-> some_tactic at h
@@ -82,7 +82,7 @@ theorem exists_root_sum_quadratic [Fintype R] {f g : R[X]} (hf2 : degree f = 2)
suffices ¬Disjoint (univ.image fun x : R => eval x f)
(univ.image fun x : R => eval x (-g)) by
simp only [disjoint_left, mem_image] at this
- push_neg at this
+ push_neg at this
rcases this with ⟨x, ⟨a, _, ha⟩, ⟨b, _, hb⟩⟩
exact ⟨a, b, by rw [ha, ← hb, eval_neg, neg_add_self]⟩
fun hd : Disjoint _ _ =>
@@ -377,7 +377,7 @@ theorem Nat.ModEq.pow_totient {x n : ℕ} (h : Nat.coprime x n) : x ^ φ n ≡ 1
rw [← ZMod.eq_iff_modEq_nat]
let x' : Units (ZMod n) := ZMod.unitOfCoprime _ h
have := ZMod.pow_totient x'
- apply_fun ((fun (x : Units (ZMod n)) => (x : ZMod n)) : Units (ZMod n) → ZMod n) at this
+ apply_fun ((fun (x : Units (ZMod n)) => (x : ZMod n)) : Units (ZMod n) → ZMod n) at this
simpa only [Nat.succ_eq_add_one, Nat.cast_pow, Units.val_one, Nat.cast_one,
coe_unitOfCoprime, Units.val_pow_eq_pow_val]
#align nat.modeq.pow_totient Nat.ModEq.pow_totient
@@ -492,7 +492,7 @@ theorem exists_nonsquare (hF : ringChar F ≠ 2) : ∃ a : F, ¬IsSquare a := by
-- sq not surjective
simp_rw [IsSquare, ← pow_two, @eq_comm _ _ (_ ^ 2)]
unfold Function.Surjective at h
- push_neg at h⊢
+ push_neg at h ⊢
exact h
#align finite_field.exists_nonsquare FiniteField.exists_nonsquare
@@ -159,7 +159,7 @@ theorem card (p : ℕ) [CharP K p] : ∃ n : ℕ+, Nat.Prime p ∧ q = p ^ (n :
#align finite_field.card FiniteField.card
-- this statement doesn't use `q` because we want `K` to be an explicit parameter
-theorem card' : ∃ (p : ℕ)(n : ℕ+), Nat.Prime p ∧ Fintype.card K = p ^ (n : ℕ) :=
+theorem card' : ∃ (p : ℕ) (n : ℕ+), Nat.Prime p ∧ Fintype.card K = p ^ (n : ℕ) :=
let ⟨p, hc⟩ := CharP.exists K
⟨p, @FiniteField.card K _ _ p hc⟩
#align finite_field.card' FiniteField.card'
@@ -73,7 +73,6 @@ theorem card_image_polynomial_eval [DecidableEq R] [Fintype R] {p : R[X]} (hp :
congr_arg card (by simp [Finset.ext_iff, ← mem_roots_sub_C hp])
_ ≤ Multiset.card (p - C a).roots := (Multiset.toFinset_card_le _)
_ ≤ _ := card_roots_sub_C' hp)
-
#align finite_field.card_image_polynomial_eval FiniteField.card_image_polynomial_eval
/-- If `f` and `g` are quadratic polynomials, then the `f.eval a + g.eval b = 0` has a solution. -/
@@ -127,7 +126,6 @@ theorem pow_card_sub_one_eq_one (a : K) (ha : a ≠ 0) : a ^ (q - 1) = 1 := by
classical
rw [← Fintype.card_units, pow_card_eq_one]
rfl
-
#align finite_field.pow_card_sub_one_eq_one FiniteField.pow_card_sub_one_eq_one
theorem pow_card (a : K) : a ^ q = a := by
@@ -224,7 +222,6 @@ theorem sum_pow_lt_card_sub_one (i : ℕ) (h : i < q - 1) : (∑ x : K, x ^ i) =
zero_pow (Nat.pos_of_ne_zero hi), add_zero]
_ = ∑ x : Kˣ, (x ^ i : K) := by simp [← this, univ.sum_map φ]
_ = 0 := by rw [sum_pow_units K i, if_neg]; exact hiq
-
#align finite_field.sum_pow_lt_card_sub_one FiniteField.sum_pow_lt_card_sub_one
open Polynomial
@@ -277,8 +274,8 @@ theorem roots_X_pow_card_sub_X : roots (X ^ q - X : K[X]) = Finset.univ.val := b
apply nodup_roots
rw [separable_def]
convert isCoprime_one_right.neg_right (R := K[X]) using 1
- · rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
- MulZeroClass.zero_mul, zero_sub]
+ rw [derivative_sub, derivative_X, derivative_X_pow, CharP.cast_card_eq_zero K, C_0,
+ MulZeroClass.zero_mul, zero_sub]
set_option linter.uppercaseLean3 false in
#align finite_field.roots_X_pow_card_sub_X FiniteField.roots_X_pow_card_sub_X
@@ -315,7 +312,7 @@ theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p,
· subst p
change Fin 2 at x
fin_cases x
- · use 0; simp;
+ · use 0; simp
· use 0, 1; simp
let f : (ZMod p)[X] := X ^ 2
let g : (ZMod p)[X] := X ^ 2 - C x
@@ -417,10 +414,10 @@ theorem pow_card_pow {n p : ℕ} [Fact p.Prime] (x : ZMod p) : x ^ p ^ n = x :=
#align zmod.pow_card_pow ZMod.pow_card_pow
@[simp]
-theorem frobenius_zMod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom.id _ := by
+theorem frobenius_zmod (p : ℕ) [Fact p.Prime] : frobenius (ZMod p) p = RingHom.id _ := by
ext a
rw [frobenius_def, ZMod.pow_card, RingHom.id_apply]
-#align zmod.frobenius_zmod ZMod.frobenius_zMod
+#align zmod.frobenius_zmod ZMod.frobenius_zmod
--Porting note: this was a `simp` lemma, but now the LHS simplify to `φ p`.
theorem card_units (p : ℕ) [Fact p.Prime] : Fintype.card (ZMod p)ˣ = p - 1 := by
@@ -329,6 +329,26 @@ theorem sq_add_sq (p : ℕ) [hp : Fact p.Prime] (x : ZMod p) : ∃ a b : ZMod p,
end ZMod
+/-- If `p` is a prime natural number and `x` is an integer number, then there exist natural numbers
+`a ≤ p / 2` and `b ≤ p / 2` such that `a ^ 2 + b ^ 2 ≡ x [ZMOD p]`. This is a version of
+`ZMod.sq_add_sq` with estimates on `a` and `b`. -/
+theorem Nat.sq_add_sq_zmodEq (p : ℕ) [Fact p.Prime] (x : ℤ) :
+ ∃ a b : ℕ, a ≤ p / 2 ∧ b ≤ p / 2 ∧ (a : ℤ) ^ 2 + (b : ℤ) ^ 2 ≡ x [ZMOD p] := by
+ rcases ZMod.sq_add_sq p x with ⟨a, b, hx⟩
+ refine ⟨a.valMinAbs.natAbs, b.valMinAbs.natAbs, ZMod.natAbs_valMinAbs_le _,
+ ZMod.natAbs_valMinAbs_le _, ?_⟩
+ rw [← a.coe_valMinAbs, ← b.coe_valMinAbs] at hx
+ push_cast
+ rw [sq_abs, sq_abs, ← ZMod.int_cast_eq_int_cast_iff]
+ exact_mod_cast hx
+
+/-- If `p` is a prime natural number and `x` is a natural number, then there exist natural numbers
+`a ≤ p / 2` and `b ≤ p / 2` such that `a ^ 2 + b ^ 2 ≡ x [MOD p]`. This is a version of
+`ZMod.sq_add_sq` with estimates on `a` and `b`. -/
+theorem Nat.sq_add_sq_modEq (p : ℕ) [Fact p.Prime] (x : ℕ) :
+ ∃ a b : ℕ, a ≤ p / 2 ∧ b ≤ p / 2 ∧ a ^ 2 + b ^ 2 ≡ x [MOD p] := by
+ simpa only [← Int.coe_nat_modEq_iff] using Nat.sq_add_sq_zmodEq p x
+
namespace CharP
theorem sq_add_sq (R : Type _) [CommRing R] [IsDomain R] (p : ℕ) [NeZero p] [CharP R p] (x : ℤ) :
The unported dependencies are