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

Commit e700d56

Browse files
feat(ring_theory/polynomial/eisenstein): add a technical lemma (#11839)
A technical lemma about Eiseinstein minimal polynomials. From flt-regular
1 parent 770a7ce commit e700d56

File tree

5 files changed

+153
-3
lines changed

5 files changed

+153
-3
lines changed

src/algebra/associated.lean

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,27 @@ lemma prime.pow_dvd_of_dvd_mul_right
129129
{p a b : α} (hp : prime p) (n : ℕ) (h : ¬p ∣ b) (h' : p ^ n ∣ a * b) : p ^ n ∣ a :=
130130
by { rw [mul_comm] at h', exact hp.pow_dvd_of_dvd_mul_left n h h' }
131131

132+
lemma prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd [cancel_comm_monoid_with_zero α]
133+
{p a b : α} {n : ℕ} (hp : prime p) (hpow : p ^ n.succ ∣ a ^ n.succ * b ^ n)
134+
(hb : ¬ p ^ 2 ∣ b) : p ∣ a :=
135+
begin
136+
-- Suppose `p ∣ b`, write `b = p * x` and `hy : a ^ n.succ * b ^ n = p ^ n.succ * y`.
137+
cases (hp.dvd_or_dvd ((dvd_pow_self p (nat.succ_ne_zero n)).trans hpow)) with H hbdiv,
138+
{ exact hp.dvd_of_dvd_pow H },
139+
obtain ⟨x, rfl⟩ := hp.dvd_of_dvd_pow hbdiv,
140+
obtain ⟨y, hy⟩ := hpow,
141+
-- Then we can divide out a common factor of `p ^ n` from the equation `hy`.
142+
have : a ^ n.succ * x ^ n = p * y,
143+
{ refine mul_left_cancel₀ (pow_ne_zero n hp.ne_zero) _,
144+
rw [← mul_assoc _ p, ← pow_succ', ← hy, mul_pow, ← mul_assoc (a ^ n.succ),
145+
mul_comm _ (p ^ n), mul_assoc] },
146+
-- So `p ∣ a` (and we're done) or `p ∣ x`, which can't be the case since it implies `p^2 ∣ b`.
147+
refine hp.dvd_of_dvd_pow ((hp.dvd_or_dvd ⟨_, this⟩).resolve_right (λ hdvdx, hb _)),
148+
obtain ⟨z, rfl⟩ := hp.dvd_of_dvd_pow hdvdx,
149+
rw [pow_two, ← mul_assoc],
150+
exact dvd_mul_right _ _,
151+
end
152+
132153
/-- `irreducible p` states that `p` is non-unit and only factors into units.
133154
134155
We explicitly avoid stating that `p` is non-zero, this would require a semiring. Assuming only a

src/data/nat/basic.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,12 @@ theorem mul_self_inj {n m : ℕ} : n * n = m * m ↔ n = m :=
607607
le_antisymm_iff.trans (le_antisymm_iff.trans
608608
(and_congr mul_self_le_mul_self_iff mul_self_le_mul_self_iff)).symm
609609

610+
lemma le_add_pred_of_pos (n : ℕ) {i : ℕ} (hi : i ≠ 0) : n ≤ i + (n - 1) :=
611+
begin
612+
refine le_trans _ (add_tsub_le_assoc),
613+
simp [add_comm, nat.add_sub_assoc, one_le_iff_ne_zero.2 hi]
614+
end
615+
610616
/-!
611617
### Recursion and induction principles
612618

src/data/polynomial/monic.lean

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,28 @@ have (-q).coeff (-q).nat_degree = 1 :=
307307
by rw [nat_degree_neg, coeff_neg, show q.coeff q.nat_degree = -1, from hq, neg_neg],
308308
by { rw sub_eq_add_neg, apply monic_add_of_right this, rwa degree_neg }
309309

310+
@[simp]
311+
lemma nat_degree_map_of_monic [semiring S] [nontrivial S] {P : polynomial R} (hmo : P.monic)
312+
(f : R →+* S) : (P.map f).nat_degree = P.nat_degree :=
313+
begin
314+
refine le_antisymm (nat_degree_map_le _ _) (le_nat_degree_of_ne_zero _),
315+
rw [coeff_map, monic.coeff_nat_degree hmo, ring_hom.map_one],
316+
exact one_ne_zero
317+
end
318+
319+
@[simp]
320+
lemma degree_map_of_monic [semiring S] [nontrivial S] {P : polynomial R} (hmo : P.monic)
321+
(f : R →+* S) : (P.map f).degree = P.degree :=
322+
begin
323+
by_cases hP : P = 0,
324+
{ simp [hP] },
325+
{ refine le_antisymm (degree_map_le _ _) _,
326+
rw [degree_eq_nat_degree hP],
327+
refine le_degree_of_ne_zero _,
328+
rw [coeff_map, monic.coeff_nat_degree hmo, ring_hom.map_one],
329+
exact one_ne_zero }
330+
end
331+
310332
section injective
311333
open function
312334
variables [semiring S] {f : R →+* S} (hf : injective f)

src/ring_theory/integral_closure.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,13 @@ theorem is_integral_mul {x y : A}
351351
(hx : is_integral R x) (hy : is_integral R y) : is_integral R (x * y) :=
352352
(algebra_map R A).is_integral_mul hx hy
353353

354+
lemma is_integral_smul [algebra S A] [algebra R S] [is_scalar_tower R S A] {x : A} (r : R)
355+
(hx : is_integral S x) : is_integral S (r • x) :=
356+
begin
357+
rw [algebra.smul_def, is_scalar_tower.algebra_map_apply R S A],
358+
exact is_integral_mul is_integral_algebra_map hx,
359+
end
360+
354361
variables (R A)
355362

356363
/-- The integral closure of R in an R-algebra A. -/

src/ring_theory/polynomial/eisenstein.lean

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Authors: Riccardo Brasca
55
-/
66

77
import ring_theory.eisenstein_criterion
8+
import ring_theory.integrally_closed
9+
import ring_theory.norm
810

911
/-!
1012
# Eisenstein polynomials
@@ -13,10 +15,10 @@ Given an ideal `𝓟` of a commutative semiring `R`, we say that a polynomial `f
1315
`f.coeff 0 ∉ 𝓟 ^ 2`. In this file we gather miscellaneous results about Eisenstein polynomials.
1416
1517
## Main definitions
16-
* `polynomial.is_eisenstein_at f 𝓟` : the property of being Eisenstein at `𝓟`.
18+
* `polynomial.is_eisenstein_at f 𝓟`: the property of being Eisenstein at `𝓟`.
1719
1820
## Main results
19-
* `polynomial.is_eisenstein_at.irreducible` : if a primitive `f` satisfies `f.is_eisenstein_at 𝓟`,
21+
* `polynomial.is_eisenstein_at.irreducible`: if a primitive `f` satisfies `f.is_eisenstein_at 𝓟`,
2022
where `𝓟.is_prime`, then `f` is irreducible.
2123
2224
## Implementation details
@@ -26,7 +28,7 @@ useful since it is sometimes better behaved (for example it is stable under `pol
2628
2729
-/
2830

29-
universes u v
31+
universes u v w z
3032

3133
variables {R : Type u}
3234

@@ -185,3 +187,95 @@ end is_domain
185187
end is_eisenstein_at
186188

187189
end polynomial
190+
191+
section is_integral
192+
193+
variables {K : Type v} {L : Type z} {p : R} [comm_ring R] [field K] [field L]
194+
variables [algebra K L] [algebra R L] [algebra R K] [is_scalar_tower R K L] [is_separable K L]
195+
variables [is_domain R] [normalized_gcd_monoid R] [is_fraction_ring R K] [is_integrally_closed R]
196+
197+
local notation `𝓟` := submodule.span R {p}
198+
199+
open is_integrally_closed power_basis nat polynomial is_scalar_tower
200+
201+
/-- Let `K` be the field of fraction of an integrally closed domain `R` and let `L` be a separable
202+
extension of `K`, generated by an integral power basis `B` such that the minimal polynomial of
203+
`B.gen` is Eisenstein. Given `z : L` integral over `R`, if `Q : polynomial R` is such that
204+
`aeval B.gen Q = p • z`, then `p ∣ Q.coeff 0`. -/
205+
lemma dvd_coeff_zero_of_aeval_eq_prime_smul_of_minpoly_is_eiseinstein_at {B : power_basis K L}
206+
(hp : prime p) (hei : (minpoly R B.gen).is_eisenstein_at 𝓟) (hBint : is_integral R B.gen) {z : L}
207+
{Q : polynomial R} (hQ : aeval B.gen Q = p • z) (hzint : is_integral R z) :
208+
p ∣ Q.coeff 0 :=
209+
begin
210+
-- First define some abbreviations.
211+
letI := B.finite_dimensional,
212+
let P := minpoly R B.gen,
213+
obtain ⟨n , hn⟩ := nat.exists_eq_succ_of_ne_zero B.dim_pos.ne',
214+
have finrank_K_L : finite_dimensional.finrank K L = B.dim := B.finrank,
215+
have deg_K_P : (minpoly K B.gen).nat_degree = B.dim := B.nat_degree_minpoly,
216+
have deg_R_P : P.nat_degree = B.dim,
217+
{ rw [← deg_K_P, minpoly.gcd_domain_eq_field_fractions K hBint,
218+
nat_degree_map_of_monic (minpoly.monic hBint) (algebra_map R K)] },
219+
choose! f hf using hei.is_weakly_eisenstein_at.exists_mem_adjoin_mul_eq_pow_nat_degree_le
220+
(minpoly.aeval R B.gen) (minpoly.monic hBint),
221+
simp only [nat_degree_map_of_monic (minpoly.monic hBint), deg_R_P] at hf,
222+
223+
-- The Eisenstein condition shows that `p` divides `Q.coeff 0`
224+
-- if `p^n` divides the following multiple of `Q^n`:
225+
suffices : p ^ n.succ ∣
226+
(Q.coeff 0 ^ n.succ * ((-1) ^ (n.succ * n) * (minpoly R B.gen).coeff 0 ^ n)),
227+
{ have hndiv : ¬ p ^ 2 ∣ ((minpoly R B.gen)).coeff 0 := λ h,
228+
hei.not_mem ((span_singleton_pow p 2).symm ▸ (ideal.mem_span_singleton.2 h)),
229+
refine prime.dvd_of_pow_dvd_pow_mul_pow_of_square_not_dvd hp ((_ : _ ^ n.succ ∣ _)) hndiv,
230+
convert (is_unit.dvd_mul_right ⟨(-1) ^ (n.succ * n), rfl⟩).mpr this using 1,
231+
push_cast,
232+
ring_nf, simp [pow_right_comm _ _ 2] },
233+
234+
-- We claim the quotient of `Q^n * _` by `p^n` is the following `r`:
235+
have aux : ∀ i ∈ (range (Q.nat_degree + 1)).erase 0, B.dim ≤ i + n,
236+
{ intros i hi,
237+
simp only [mem_range, mem_erase] at hi,
238+
rw [hn],
239+
exact le_add_pred_of_pos _ hi.1 },
240+
have hintsum : is_integral R (z * B.gen ^ n -
241+
∑ (x : ℕ) in (range (Q.nat_degree + 1)).erase 0, Q.coeff x • f (x + n)),
242+
{ refine is_integral_sub (is_integral_mul hzint (is_integral.pow hBint _))
243+
(is_integral.sum _ (λ i hi, (is_integral_smul _ _))),
244+
exact adjoin_le_integral_closure hBint (hf _ (aux i hi)).1 },
245+
obtain ⟨r, hr⟩ := is_integral_iff.1 (is_integral_norm K hintsum),
246+
use r,
247+
248+
-- Do the computation in `K` so we can work in terms of `z` instead of `r`.
249+
apply is_fraction_ring.injective R K,
250+
simp only [_root_.map_mul, _root_.map_pow, _root_.map_neg, _root_.map_one],
251+
-- Both sides are actually norms:
252+
calc _ = norm K (Q.coeff 0 • B.gen ^ n) : _
253+
... = norm K (p • (z * B.gen ^ n) - ∑ (x : ℕ) in (range (Q.nat_degree + 1)).erase 0,
254+
p • Q.coeff x • f (x + n))
255+
: congr_arg (norm K) (eq_sub_of_add_eq _)
256+
... = _ : _,
257+
{ simp only [algebra.smul_def, algebra_map_apply R K L, norm_algebra_map, _root_.map_mul,
258+
_root_.map_pow, finrank_K_L, power_basis.norm_gen_eq_coeff_zero_minpoly,
259+
minpoly.gcd_domain_eq_field_fractions K hBint, coeff_map, ← hn],
260+
ring_exp },
261+
swap, { simp_rw [← smul_sum, ← smul_sub, algebra.smul_def p, algebra_map_apply R K L,
262+
_root_.map_mul, norm_algebra_map, finrank_K_L, hr, ← hn] },
263+
264+
calc _ = (Q.coeff 01 + ∑ (x : ℕ) in (range (Q.nat_degree + 1)).erase 0,
265+
Q.coeff x • B.gen ^ x) * B.gen ^ n : _
266+
... = (Q.coeff 0 • B.gen ^ 0 + ∑ (x : ℕ) in (range (Q.nat_degree + 1)).erase 0,
267+
Q.coeff x • B.gen ^ x) * B.gen ^ n : by rw pow_zero
268+
... = (aeval B.gen Q) * B.gen ^ n : _
269+
... = _ : by rw [hQ, algebra.smul_mul_assoc],
270+
{ have : ∀ i ∈ (range (Q.nat_degree + 1)).erase 0,
271+
Q.coeff i • (B.gen ^ i * B.gen ^ n) =
272+
p • Q.coeff i • f (i + n),
273+
{ intros i hi,
274+
rw [← pow_add, ← (hf _ (aux i hi)).2, ← smul_def, smul_smul, mul_comm _ p, smul_smul] },
275+
simp only [add_mul, smul_mul_assoc, one_mul, sum_mul, sum_congr rfl this] },
276+
{ rw [aeval_eq_sum_range,
277+
finset.add_sum_erase (range (Q.nat_degree + 1)) (λ i, Q.coeff i • B.gen ^ i)],
278+
simp },
279+
end
280+
281+
end is_integral

0 commit comments

Comments
 (0)