|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Riccardo Brasca. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Riccardo Brasca |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module number_theory.cyclotomic.discriminant |
| 7 | +! leanprover-community/mathlib commit 3e068ece210655b7b9a9477c3aff38a492400aa1 |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.NumberTheory.Cyclotomic.PrimitiveRoots |
| 12 | +import Mathlib.RingTheory.Discriminant |
| 13 | + |
| 14 | +/-! |
| 15 | +# Discriminant of cyclotomic fields |
| 16 | +We compute the discriminant of a `p ^ n`-th cyclotomic extension. |
| 17 | +
|
| 18 | +## Main results |
| 19 | +* `IsCyclotomicExtension.discr_odd_prime` : if `p` is an odd prime such that |
| 20 | + `IsCyclotomicExtension {p} K L` and `Irreducible (cyclotomic p K)`, then |
| 21 | + `discr K (hζ.powerBasis K).basis = (-1) ^ ((p - 1) / 2) * p ^ (p - 2)` for any |
| 22 | + `hζ : IsPrimitiveRoot ζ p`. |
| 23 | +
|
| 24 | +-/ |
| 25 | + |
| 26 | + |
| 27 | +universe u v |
| 28 | + |
| 29 | +local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue #2220 |
| 30 | + |
| 31 | +open Algebra Polynomial Nat IsPrimitiveRoot PowerBasis |
| 32 | + |
| 33 | +open scoped Polynomial Cyclotomic |
| 34 | + |
| 35 | +namespace IsPrimitiveRoot |
| 36 | + |
| 37 | +variable {n : ℕ+} {K : Type u} [Field K] [CharZero K] {ζ : K} |
| 38 | + |
| 39 | +variable [ce : IsCyclotomicExtension {n} ℚ K] |
| 40 | + |
| 41 | +/-- The discriminant of the power basis given by a primitive root of unity `ζ` is the same as the |
| 42 | +discriminant of the power basis given by `ζ - 1`. -/ |
| 43 | +theorem discr_zeta_eq_discr_zeta_sub_one (hζ : IsPrimitiveRoot ζ n) : |
| 44 | + discr ℚ (hζ.powerBasis ℚ).basis = discr ℚ (hζ.subOnePowerBasis ℚ).basis := by |
| 45 | + haveI : NumberField K := @NumberField.mk _ _ _ (IsCyclotomicExtension.finiteDimensional {n} ℚ K) |
| 46 | + have H₁ : (aeval (hζ.powerBasis ℚ).gen) (X - 1 : ℤ[X]) = (hζ.subOnePowerBasis ℚ).gen := by simp |
| 47 | + have H₂ : (aeval (hζ.subOnePowerBasis ℚ).gen) (X + 1 : ℤ[X]) = (hζ.powerBasis ℚ).gen := by simp |
| 48 | + refine' discr_eq_discr_of_toMatrix_coeff_isIntegral _ (fun i j => toMatrix_isIntegral H₁ _ _ _ _) |
| 49 | + fun i j => toMatrix_isIntegral H₂ _ _ _ _ |
| 50 | + · exact hζ.isIntegral n.pos |
| 51 | + · refine' minpoly.isIntegrallyClosed_eq_field_fractions' (K := ℚ) (hζ.isIntegral n.pos) |
| 52 | + · exact isIntegral_sub (hζ.isIntegral n.pos) isIntegral_one |
| 53 | + · refine' minpoly.isIntegrallyClosed_eq_field_fractions' (K := ℚ) _ |
| 54 | + exact isIntegral_sub (hζ.isIntegral n.pos) isIntegral_one |
| 55 | +#align is_primitive_root.discr_zeta_eq_discr_zeta_sub_one IsPrimitiveRoot.discr_zeta_eq_discr_zeta_sub_one |
| 56 | + |
| 57 | +end IsPrimitiveRoot |
| 58 | + |
| 59 | +namespace IsCyclotomicExtension |
| 60 | + |
| 61 | +variable {p : ℕ+} {k : ℕ} {K : Type u} {L : Type v} {ζ : L} [Field K] [Field L] |
| 62 | + |
| 63 | +variable [Algebra K L] |
| 64 | + |
| 65 | +/-- If `p` is a prime and `IsCyclotomicExtension {p ^ (k + 1)} K L`, then the discriminant of |
| 66 | +`hζ.powerBasis K` is `(-1) ^ ((p ^ (k + 1).totient) / 2) * p ^ (p ^ k * ((p - 1) * (k + 1) - 1))` |
| 67 | +if `Irreducible (cyclotomic (p ^ (k + 1)) K))`, and `p ^ (k + 1) ≠ 2`. -/ |
| 68 | +theorem discr_prime_pow_ne_two [IsCyclotomicExtension {p ^ (k + 1)} K L] [hp : Fact (p : ℕ).Prime] |
| 69 | + (hζ : IsPrimitiveRoot ζ ↑(p ^ (k + 1))) (hirr : Irreducible (cyclotomic (↑(p ^ (k + 1)) : ℕ) K)) |
| 70 | + (hk : p ^ (k + 1) ≠ 2) : discr K (hζ.powerBasis K).basis = |
| 71 | + (-1) ^ ((p ^ (k + 1) : ℕ).totient / 2) * p ^ ((p : ℕ) ^ k * ((p - 1) * (k + 1) - 1)) := by |
| 72 | + haveI hne := IsCyclotomicExtension.ne_zero' (p ^ (k + 1)) K L |
| 73 | + -- Porting note: these two instances are not automatically synthesised and must be constructed |
| 74 | + haveI mf : Module.Finite K L := finiteDimensional {p ^ (k + 1)} K L |
| 75 | + haveI se : IsSeparable K L := (isGalois (p ^ (k + 1)) K L).to_isSeparable |
| 76 | + rw [discr_powerBasis_eq_norm, finrank L hirr, hζ.powerBasis_gen _, ← |
| 77 | + hζ.minpoly_eq_cyclotomic_of_irreducible hirr, PNat.pow_coe, |
| 78 | + totient_prime_pow hp.out (succ_pos k), succ_sub_one] |
| 79 | + have coe_two : ((2 : ℕ+) : ℕ) = 2 := rfl |
| 80 | + have hp2 : p = 2 → k ≠ 0 := by |
| 81 | + rintro rfl rfl |
| 82 | + exact absurd rfl hk |
| 83 | + congr 1 |
| 84 | + · rcases eq_or_ne p 2 with (rfl | hp2) |
| 85 | + · rcases Nat.exists_eq_succ_of_ne_zero (hp2 rfl) with ⟨k, rfl⟩ |
| 86 | + rw [coe_two, succ_sub_succ_eq_sub, tsub_zero, mul_one]; simp only [_root_.pow_succ] |
| 87 | + rw [mul_assoc, Nat.mul_div_cancel_left _ zero_lt_two, Nat.mul_div_cancel_left _ zero_lt_two] |
| 88 | + cases k |
| 89 | + · simp |
| 90 | + · norm_num; simp_rw [_root_.pow_succ, (even_two.mul_right _).neg_one_pow, |
| 91 | + ((even_two.mul_right _).mul_right _).neg_one_pow] |
| 92 | + · replace hp2 : (p : ℕ) ≠ 2 |
| 93 | + · rwa [Ne.def, ← coe_two, PNat.coe_inj] |
| 94 | + have hpo : Odd (p : ℕ) := hp.out.odd_of_ne_two hp2 |
| 95 | + obtain ⟨a, ha⟩ := (hp.out.even_sub_one hp2).two_dvd |
| 96 | + rw [ha, mul_left_comm, mul_assoc, Nat.mul_div_cancel_left _ two_pos, |
| 97 | + Nat.mul_div_cancel_left _ two_pos, mul_right_comm, pow_mul, (hpo.pow.mul _).neg_one_pow, |
| 98 | + pow_mul, hpo.pow.neg_one_pow]; · norm_cast |
| 99 | + refine' Nat.Even.sub_odd _ (even_two_mul _) odd_one |
| 100 | + rw [mul_left_comm, ← ha] |
| 101 | + exact one_le_mul (one_le_pow _ _ hp.1.pos) (succ_le_iff.2 <| tsub_pos_of_lt hp.1.one_lt) |
| 102 | + · have H := congr_arg (@derivative K _) (cyclotomic_prime_pow_mul_X_pow_sub_one K p k) |
| 103 | + rw [derivative_mul, derivative_sub, derivative_one, sub_zero, derivative_X_pow, C_eq_nat_cast, |
| 104 | + derivative_sub, derivative_one, sub_zero, derivative_X_pow, C_eq_nat_cast, ← PNat.pow_coe, |
| 105 | + hζ.minpoly_eq_cyclotomic_of_irreducible hirr] at H |
| 106 | + replace H := congr_arg (fun P => aeval ζ P) H |
| 107 | + simp only [aeval_add, aeval_mul, minpoly.aeval, MulZeroClass.zero_mul, add_zero, aeval_nat_cast, |
| 108 | + _root_.map_sub, aeval_one, aeval_X_pow] at H |
| 109 | + replace H := congr_arg (Algebra.norm K) H |
| 110 | + have hnorm : (norm K) (ζ ^ (p : ℕ) ^ k - 1) = (p : K) ^ (p : ℕ) ^ k := by |
| 111 | + by_cases hp : p = 2 |
| 112 | + · exact_mod_cast hζ.pow_sub_one_norm_prime_pow_of_ne_zero hirr le_rfl (hp2 hp) |
| 113 | + · exact_mod_cast hζ.pow_sub_one_norm_prime_ne_two hirr le_rfl hp |
| 114 | + rw [MonoidHom.map_mul, hnorm, MonoidHom.map_mul, ← map_natCast (algebraMap K L), |
| 115 | + Algebra.norm_algebraMap, finrank L hirr] at H |
| 116 | + conv_rhs at H => -- Porting note: need to drill down to successfully rewrite the totient |
| 117 | + enter [1, 2] |
| 118 | + rw [PNat.pow_coe, ← succ_eq_add_one, totient_prime_pow hp.out (succ_pos k), Nat.sub_one, |
| 119 | + Nat.pred_succ] |
| 120 | + rw [← hζ.minpoly_eq_cyclotomic_of_irreducible hirr, map_pow, hζ.norm_eq_one hk hirr, one_pow, |
| 121 | + mul_one, PNat.pow_coe, cast_pow, ← pow_mul, ← mul_assoc, mul_comm (k + 1), mul_assoc] at H |
| 122 | + have := mul_pos (succ_pos k) (tsub_pos_of_lt hp.out.one_lt) |
| 123 | + rw [← succ_pred_eq_of_pos this, mul_succ, pow_add _ _ ((p : ℕ) ^ k)] at H |
| 124 | + replace H := (mul_left_inj' fun h => ?_).1 H |
| 125 | + · simp only [H, mul_comm _ (k + 1)]; norm_cast |
| 126 | + · -- Porting note: was `replace h := pow_eq_zero h; rw [coe_coe] at h; simpa using hne.1` |
| 127 | + have := hne.1 |
| 128 | + rw [PNat.pow_coe, Nat.cast_pow, Ne.def, pow_eq_zero_iff (by linarith)] at this |
| 129 | + exact absurd (pow_eq_zero h) this |
| 130 | +#align is_cyclotomic_extension.discr_prime_pow_ne_two IsCyclotomicExtension.discr_prime_pow_ne_two |
| 131 | + |
| 132 | +/-- If `p` is a prime and `IsCyclotomicExtension {p ^ (k + 1)} K L`, then the discriminant of |
| 133 | +`hζ.powerBasis K` is `(-1) ^ (p ^ k * (p - 1) / 2) * p ^ (p ^ k * ((p - 1) * (k + 1) - 1))` |
| 134 | +if `Irreducible (cyclotomic (p ^ (k + 1)) K))`, and `p ^ (k + 1) ≠ 2`. -/ |
| 135 | +theorem discr_prime_pow_ne_two' [IsCyclotomicExtension {p ^ (k + 1)} K L] [hp : Fact (p : ℕ).Prime] |
| 136 | + (hζ : IsPrimitiveRoot ζ ↑(p ^ (k + 1))) (hirr : Irreducible (cyclotomic (↑(p ^ (k + 1)) : ℕ) K)) |
| 137 | + (hk : p ^ (k + 1) ≠ 2) : discr K (hζ.powerBasis K).basis = |
| 138 | + (-1) ^ ((p : ℕ) ^ k * (p - 1) / 2) * p ^ ((p : ℕ) ^ k * ((p - 1) * (k + 1) - 1)) := |
| 139 | + by simpa [totient_prime_pow hp.out (succ_pos k)] using discr_prime_pow_ne_two hζ hirr hk |
| 140 | +#align is_cyclotomic_extension.discr_prime_pow_ne_two' IsCyclotomicExtension.discr_prime_pow_ne_two' |
| 141 | + |
| 142 | +/-- If `p` is a prime and `IsCyclotomicExtension {p ^ k} K L`, then the discriminant of |
| 143 | +`hζ.powerBasis K` is `(-1) ^ ((p ^ k).totient / 2) * p ^ (p ^ (k - 1) * ((p - 1) * k - 1))` |
| 144 | +if `Irreducible (cyclotomic (p ^ k) K))`. Beware that in the cases `p ^ k = 1` and `p ^ k = 2` |
| 145 | +the formula uses `1 / 2 = 0` and `0 - 1 = 0`. It is useful only to have a uniform result. |
| 146 | +See also `IsCyclotomicExtension.discr_prime_pow_eq_unit_mul_pow`. -/ |
| 147 | +theorem discr_prime_pow [hcycl : IsCyclotomicExtension {p ^ k} K L] [hp : Fact (p : ℕ).Prime] |
| 148 | + (hζ : IsPrimitiveRoot ζ ↑(p ^ k)) (hirr : Irreducible (cyclotomic (↑(p ^ k) : ℕ) K)) : |
| 149 | + discr K (hζ.powerBasis K).basis = |
| 150 | + (-1) ^ ((p ^ k : ℕ).totient / 2) * p ^ ((p : ℕ) ^ (k - 1) * ((p - 1) * k - 1)) := by |
| 151 | + cases' k with k k |
| 152 | + · simp only [coe_basis, _root_.pow_zero, powerBasis_gen, totient_one, mul_zero, mul_one, |
| 153 | + show 1 / 2 = 0 by rfl, discr, traceMatrix] |
| 154 | + have hζone : ζ = 1 := by simpa using hζ |
| 155 | + rw [hζ.powerBasis_dim _, hζone, ← (algebraMap K L).map_one, |
| 156 | + minpoly.eq_X_sub_C_of_algebraMap_inj _ (algebraMap K L).injective, natDegree_X_sub_C] |
| 157 | + simp only [traceMatrix, map_one, one_pow, Matrix.det_unique, traceForm_apply, mul_one] |
| 158 | + rw [← (algebraMap K L).map_one, trace_algebraMap, finrank _ hirr] |
| 159 | + simp; norm_num |
| 160 | + · by_cases hk : p ^ (k + 1) = 2 |
| 161 | + · have coe_two : 2 = ((2 : ℕ+) : ℕ) := rfl |
| 162 | + have hp : p = 2 := by |
| 163 | + rw [← PNat.coe_inj, PNat.pow_coe, ← pow_one 2] at hk |
| 164 | + replace hk := |
| 165 | + eq_of_prime_pow_eq (prime_iff.1 hp.out) (prime_iff.1 Nat.prime_two) (succ_pos _) hk |
| 166 | + rwa [coe_two, PNat.coe_inj] at hk |
| 167 | + rw [hp, ← PNat.coe_inj, PNat.pow_coe] at hk |
| 168 | + nth_rw 2 [← pow_one 2] at hk |
| 169 | + replace hk := Nat.pow_right_injective rfl.le hk |
| 170 | + rw [add_left_eq_self] at hk |
| 171 | + rw [hp, hk] at hζ; norm_num at hζ; rw [← coe_two] at hζ |
| 172 | + rw [coe_basis, powerBasis_gen]; simp only [hp, hk]; norm_num |
| 173 | + rw [← coe_two, totient_two, show 1 / 2 = 0 by rfl, _root_.pow_zero] |
| 174 | + -- Porting note: the goal at this point is `(discr K fun i ↦ ζ ^ ↑i) = 1`. |
| 175 | + -- This `simp_rw` is needed so the next `rw` can rewrite the type of `i` from |
| 176 | + -- `Fin (natDegree (minpoly K ζ))` to `Fin 1` |
| 177 | + simp_rw [hζ.eq_neg_one_of_two_right, show (-1 : L) = algebraMap K L (-1) by simp] |
| 178 | + rw [hζ.eq_neg_one_of_two_right, show (-1 : L) = algebraMap K L (-1) by simp, |
| 179 | + minpoly.eq_X_sub_C_of_algebraMap_inj _ (algebraMap K L).injective, natDegree_X_sub_C] |
| 180 | + simp only [discr, traceMatrix_apply, Matrix.det_unique, Fin.default_eq_zero, Fin.val_zero, |
| 181 | + _root_.pow_zero, traceForm_apply, mul_one] |
| 182 | + rw [← (algebraMap K L).map_one, trace_algebraMap, finrank _ hirr, hp, hk]; norm_num |
| 183 | + simp [← coe_two] |
| 184 | + · exact discr_prime_pow_ne_two hζ hirr hk |
| 185 | +#align is_cyclotomic_extension.discr_prime_pow IsCyclotomicExtension.discr_prime_pow |
| 186 | + |
| 187 | +/-- If `p` is a prime and `IsCyclotomicExtension {p ^ k} K L`, then there are `u : ℤˣ` and |
| 188 | +`n : ℕ` such that the discriminant of `hζ.powerBasis K` is `u * p ^ n`. Often this is enough and |
| 189 | +less cumbersome to use than `IsCyclotomicExtension.discr_prime_pow`. -/ |
| 190 | +theorem discr_prime_pow_eq_unit_mul_pow [IsCyclotomicExtension {p ^ k} K L] |
| 191 | + [hp : Fact (p : ℕ).Prime] (hζ : IsPrimitiveRoot ζ ↑(p ^ k)) |
| 192 | + (hirr : Irreducible (cyclotomic (↑(p ^ k) : ℕ) K)) : |
| 193 | + ∃ (u : ℤˣ) (n : ℕ), discr K (hζ.powerBasis K).basis = u * p ^ n := by |
| 194 | + rw [discr_prime_pow hζ hirr] |
| 195 | + by_cases heven : Even ((p ^ k : ℕ).totient / 2) |
| 196 | + · refine' ⟨1, (p : ℕ) ^ (k - 1) * ((p - 1) * k - 1), by rw [heven.neg_one_pow]; norm_num⟩ |
| 197 | + · exact ⟨-1, (p : ℕ) ^ (k - 1) * ((p - 1) * k - 1), by |
| 198 | + rw [(odd_iff_not_even.2 heven).neg_one_pow]; norm_num⟩ |
| 199 | +#align is_cyclotomic_extension.discr_prime_pow_eq_unit_mul_pow IsCyclotomicExtension.discr_prime_pow_eq_unit_mul_pow |
| 200 | + |
| 201 | +/-- If `p` is an odd prime and `IsCyclotomicExtension {p} K L`, then |
| 202 | +`discr K (hζ.powerBasis K).basis = (-1) ^ ((p - 1) / 2) * p ^ (p - 2)` if |
| 203 | +`Irreducible (cyclotomic p K)`. -/ |
| 204 | +theorem discr_odd_prime [IsCyclotomicExtension {p} K L] [hp : Fact (p : ℕ).Prime] |
| 205 | + (hζ : IsPrimitiveRoot ζ p) (hirr : Irreducible (cyclotomic p K)) (hodd : p ≠ 2) : |
| 206 | + discr K (hζ.powerBasis K).basis = (-1) ^ (((p : ℕ) - 1) / 2) * p ^ ((p : ℕ) - 2) := by |
| 207 | + have : IsCyclotomicExtension {p ^ (0 + 1)} K L := by |
| 208 | + rw [zero_add, pow_one] |
| 209 | + infer_instance |
| 210 | + have hζ' : IsPrimitiveRoot ζ ↑(p ^ (0 + 1)) := by simpa using hζ |
| 211 | + convert discr_prime_pow_ne_two hζ' (by simpa [hirr]) (by simp [hodd]) using 2 |
| 212 | + · rw [zero_add, pow_one, totient_prime hp.out] |
| 213 | + · rw [_root_.pow_zero, one_mul, zero_add, mul_one, Nat.sub_sub] |
| 214 | +#align is_cyclotomic_extension.discr_odd_prime IsCyclotomicExtension.discr_odd_prime |
| 215 | + |
| 216 | +end IsCyclotomicExtension |
0 commit comments