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

Commit 70ca6fd

Browse files
committed
feat(ring_theory/power_basis): equivs between algebras with the same power basis (#4986)
`power_basis.lift` and `power_basis.equiv` use the power basis structure to define `alg_hom`s and `alg_equiv`s. The main application in this PR is `power_basis.equiv_adjoin_simple`, which states that adjoining an element of a power basis of `L : K` gives `L` itself.
1 parent 6bac899 commit 70ca6fd

File tree

11 files changed

+338
-36
lines changed

11 files changed

+338
-36
lines changed

src/data/polynomial/algebra_map.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ We promote `eval₂` to an algebra hom in `aeval`.
1515

1616
noncomputable theory
1717
open finset
18+
open_locale big_operators
1819

1920
namespace polynomial
2021
universes u v w z
@@ -207,6 +208,14 @@ lemma dvd_term_of_is_root_of_dvd_terms {r p : S} {f : polynomial S} (i : ℕ)
207208
(hr : f.is_root r) (h : ∀ (j ≠ i), p ∣ f.coeff j * r ^ j) : p ∣ f.coeff i * r ^ i :=
208209
dvd_term_of_dvd_eval_of_dvd_terms i (eq.symm hr ▸ dvd_zero p) h
209210

211+
lemma aeval_eq_sum_range [algebra R S] {p : polynomial R} (x : S) :
212+
aeval x p = ∑ i in finset.range (p.nat_degree + 1), p.coeff i • x ^ i :=
213+
by { simp_rw algebra.smul_def, exact eval₂_eq_sum_range (algebra_map R S) x }
214+
215+
lemma aeval_eq_sum_range' [algebra R S] {p : polynomial R} {n : ℕ} (hn : p.nat_degree < n) (x : S) :
216+
aeval x p = ∑ i in finset.range n, p.coeff i • x ^ i :=
217+
by { simp_rw algebra.smul_def, exact eval₂_eq_sum_range' (algebra_map R S) hn x }
218+
210219
end aeval
211220

212221
section ring

src/data/polynomial/degree/basic.lean

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -447,23 +447,25 @@ begin
447447
exact mul_X_pow_eq_zero ‹_›, },
448448
end
449449

450-
lemma degree_add_eq_of_degree_lt (h : degree p < degree q) : degree (p + q) = degree q :=
451-
le_antisymm (max_eq_right_of_lt h ▸ degree_add_le _ _) $ degree_le_degree $
450+
lemma degree_add_eq_left_of_degree_lt (h : degree q < degree p) : degree (p + q) = degree p :=
451+
le_antisymm (max_eq_left_of_lt h ▸ degree_add_le _ _) $ degree_le_degree $
452452
begin
453-
rw [coeff_add, coeff_nat_degree_eq_zero_of_degree_lt h, zero_add],
453+
rw [coeff_add, coeff_nat_degree_eq_zero_of_degree_lt h, add_zero],
454454
exact mt leading_coeff_eq_zero.1 (ne_zero_of_degree_gt h)
455455
end
456456

457+
lemma degree_add_eq_right_of_degree_lt (h : degree p < degree q) : degree (p + q) = degree q :=
458+
by rw [add_comm, degree_add_eq_left_of_degree_lt h]
457459

458460
lemma degree_add_C (hp : 0 < degree p) : degree (p + C a) = degree p :=
459-
add_comm (C a) p ▸ degree_add_eq_of_degree_lt $ lt_of_le_of_lt degree_C_le hp
461+
add_comm (C a) p ▸ degree_add_eq_right_of_degree_lt $ lt_of_le_of_lt degree_C_le hp
460462

461463
lemma degree_add_eq_of_leading_coeff_add_ne_zero (h : leading_coeff p + leading_coeff q ≠ 0) :
462464
degree (p + q) = max p.degree q.degree :=
463465
le_antisymm (degree_add_le _ _) $
464466
match lt_trichotomy (degree p) (degree q) with
465467
| or.inl hlt :=
466-
by rw [degree_add_eq_of_degree_lt hlt, max_eq_right_of_lt hlt]; exact le_refl _
468+
by rw [degree_add_eq_right_of_degree_lt hlt, max_eq_right_of_lt hlt]; exact le_refl _
467469
| or.inr (or.inl heq) :=
468470
le_of_not_gt $
469471
assume hlt : max (degree p) (degree q) > degree (p + q),
@@ -474,7 +476,7 @@ le_antisymm (degree_add_le _ _) $
474476
exact coeff_nat_degree_eq_zero_of_degree_lt hlt
475477
end
476478
| or.inr (or.inr hlt) :=
477-
by rw [add_comm, degree_add_eq_of_degree_lt hlt, max_eq_left_of_lt hlt]; exact le_refl _
479+
by rw [degree_add_eq_left_of_degree_lt hlt, max_eq_left_of_lt hlt]; exact le_refl _
478480
end
479481

480482
lemma degree_erase_le (p : polynomial R) (n : ℕ) : degree (p.erase n) ≤ degree p :=
@@ -553,7 +555,7 @@ by { haveI := nontrivial.of_polynomial_ne hne, exact hp.ne_zero }
553555
lemma leading_coeff_add_of_degree_lt (h : degree p < degree q) :
554556
leading_coeff (p + q) = leading_coeff q :=
555557
have coeff p (nat_degree q) = 0, from coeff_nat_degree_eq_zero_of_degree_lt h,
556-
by simp only [leading_coeff, nat_degree_eq_of_degree_eq (degree_add_eq_of_degree_lt h),
558+
by simp only [leading_coeff, nat_degree_eq_of_degree_eq (degree_add_eq_right_of_degree_lt h),
557559
this, coeff_add, zero_add]
558560

559561
lemma leading_coeff_add_of_degree_eq (h : degree p = degree q)
@@ -770,18 +772,42 @@ lemma nat_degree_X_sub_C_le {r : R} : (X - C r).nat_degree ≤ 1 :=
770772
nat_degree_le_iff_degree_le.2 $ le_trans (degree_sub_le _ _) $ max_le degree_X_le $
771773
le_trans degree_C_le $ with_bot.coe_le_coe.2 zero_le_one
772774

775+
lemma degree_sum_fin_lt {n : ℕ} (f : fin n → R) :
776+
degree (∑ i : fin n, C (f i) * X ^ (i : ℕ)) < n :=
777+
begin
778+
haveI : is_commutative (with_bot ℕ) max := ⟨max_comm⟩,
779+
haveI : is_associative (with_bot ℕ) max := ⟨max_assoc⟩,
780+
calc (∑ i, C (f i) * X ^ (i : ℕ)).degree
781+
≤ finset.univ.fold (⊔) ⊥ (λ i, (C (f i) * X ^ (i : ℕ)).degree) : degree_sum_le _ _
782+
... = finset.univ.fold max ⊥ (λ i, (C (f i) * X ^ (i : ℕ)).degree) :
783+
(@finset.fold_hom _ _ _ (⊔) _ _ _ ⊥ finset.univ _ _ _ id (with_bot.sup_eq_max)).symm
784+
... < n : (finset.fold_max_lt (n : with_bot ℕ)).mpr ⟨with_bot.bot_lt_some _, _⟩,
785+
786+
rintros ⟨i, hi⟩ -,
787+
calc (C (f ⟨i, hi⟩) * X ^ i).degree
788+
≤ (C _).degree + (X ^ i).degree : degree_mul_le _ _
789+
... ≤ 0 + i : add_le_add degree_C_le (degree_X_pow_le i)
790+
... = i : zero_add _
791+
... < n : with_bot.some_lt_some.mpr hi,
792+
end
793+
794+
lemma degree_sub_eq_left_of_degree_lt (h : degree q < degree p) : degree (p - q) = degree p :=
795+
by { rw ← degree_neg q at h, rw [sub_eq_add_neg, degree_add_eq_left_of_degree_lt h] }
796+
797+
lemma degree_sub_eq_right_of_degree_lt (h : degree p < degree q) : degree (p - q) = degree q :=
798+
by { rw ← degree_neg q at h, rw [sub_eq_add_neg, degree_add_eq_right_of_degree_lt h, degree_neg] }
799+
773800
end ring
774801

775802
section nonzero_ring
776803
variables [nontrivial R] [ring R]
777804

778805
@[simp] lemma degree_X_sub_C (a : R) : degree (X - C a) = 1 :=
779-
begin
780-
rw [sub_eq_add_neg, add_comm, ← @degree_X R],
781-
by_cases ha : a = 0,
782-
{ simp only [ha, C_0, neg_zero, zero_add] },
783-
exact degree_add_eq_of_degree_lt (by rw [degree_X, degree_neg, degree_C ha]; exact dec_trivial)
784-
end
806+
have degree (C a) < degree (X : polynomial R),
807+
from calc degree (C a) ≤ 0 : degree_C_le
808+
... < 1 : with_bot.some_lt_some.mpr zero_lt_one
809+
... = degree X : degree_X.symm,
810+
by rw [degree_sub_eq_left_of_degree_lt this, degree_X]
785811

786812
@[simp] lemma nat_degree_X_sub_C (x : R) : (X - C x).nat_degree = 1 :=
787813
nat_degree_eq_of_degree_eq_some $ degree_X_sub_C x
@@ -792,11 +818,11 @@ by simp [next_coeff_of_pos_nat_degree]
792818

793819
lemma degree_X_pow_sub_C {n : ℕ} (hn : 0 < n) (a : R) :
794820
degree ((X : polynomial R) ^ n - C a) = n :=
795-
have degree (-C a) < degree ((X : polynomial R) ^ n),
796-
from calc degree (-C a) ≤ 0 : by rw degree_neg; exact degree_C_le
821+
have degree (C a) < degree ((X : polynomial R) ^ n),
822+
from calc degree (C a) ≤ 0 : degree_C_le
797823
... < degree ((X : polynomial R) ^ n) : by rwa [degree_X_pow];
798824
exact with_bot.coe_lt_coe.2 hn,
799-
by rw [sub_eq_add_neg, add_comm, degree_add_eq_of_degree_lt this, degree_X_pow]
825+
by rw [degree_sub_eq_left_of_degree_lt this, degree_X_pow]
800826

801827
lemma X_pow_sub_C_ne_zero {n : ℕ} (hn : 0 < n) (a : R) :
802828
(X : polynomial R) ^ n - C a ≠ 0 :=

src/data/polynomial/div.lean

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ calc (div_X p).degree < (div_X p * X + C (p.coeff 0)).degree :
100100
(by rw [zero_le_degree_iff, ne.def, div_X_eq_zero_iff];
101101
exact λ h0, h (h0.symm ▸ degree_C_le))
102102
(le_refl _),
103-
by rw [add_comm, degree_add_eq_of_degree_lt this];
103+
by rw [degree_add_eq_left_of_degree_lt this];
104104
exact degree_lt_degree_mul_X hXp0
105105
... = p.degree : by rw div_X_mul_X_add
106106

@@ -364,7 +364,7 @@ have hmod : degree (p %ₘ q) < degree (q * (p /ₘ q)) :=
364364
degree_eq_nat_degree hdiv0, ← with_bot.coe_add, with_bot.coe_le_coe];
365365
exact nat.le_add_right _ _,
366366
calc degree q + degree (p /ₘ q) = degree (q * (p /ₘ q)) : eq.symm (degree_mul' hlc)
367-
... = degree (p %ₘ q + q * (p /ₘ q)) : (degree_add_eq_of_degree_lt hmod).symm
367+
... = degree (p %ₘ q + q * (p /ₘ q)) : (degree_add_eq_right_of_degree_lt hmod).symm
368368
... = _ : congr_arg _ (mod_by_monic_add_div _ hq)
369369

370370
lemma degree_div_by_monic_le (p q : polynomial R) : degree (p /ₘ q) ≤ degree p :=
@@ -538,6 +538,11 @@ lemma dvd_iff_is_root : (X - C a) ∣ p ↔ is_root p a :=
538538
lemma mod_by_monic_X (p : polynomial R) : p %ₘ X = C (p.eval 0) :=
539539
by rw [← mod_by_monic_X_sub_C_eq_C_eval, C_0, sub_zero]
540540

541+
lemma eval₂_mod_by_monic_eq_self_of_root [comm_ring S] {f : R →+* S}
542+
{p q : polynomial R} (hq : q.monic) {x : S} (hx : q.eval₂ f x = 0) :
543+
(p %ₘ q).eval₂ f x = p.eval₂ f x :=
544+
by rw [mod_by_monic_eq_sub_mul_div p hq, eval₂_sub, eval₂_mul, hx, zero_mul, sub_zero]
545+
541546
section multiplicity
542547
/-- An algorithm for deciding polynomial divisibility.
543548
The algorithm is "compute `p %ₘ q` and compare to `0`". `

src/data/polynomial/eval.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,14 @@ lemma eval₂_eq_sum_range :
188188
p.eval₂ f x = ∑ i in finset.range (p.nat_degree + 1), f (p.coeff i) * x^i :=
189189
trans (congr_arg _ p.as_sum_range) (trans (eval₂_finset_sum f _ _ x) (congr_arg _ (by simp)))
190190

191+
lemma eval₂_eq_sum_range' (f : R →+* S) {p : polynomial R} {n : ℕ} (hn : p.nat_degree < n) (x : S) :
192+
eval₂ f x p = ∑ i in finset.range n, f (p.coeff i) * x ^ i :=
193+
begin
194+
rw [eval₂_eq_sum, p.sum_over_range' _ _ hn],
195+
intro i,
196+
rw [f.map_zero, zero_mul]
197+
end
198+
191199
end eval₂
192200

193201
section eval

src/data/polynomial/field_division.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ lemma degree_add_div (hq0 : q ≠ 0) (hpq : degree q ≤ degree p) :
175175
have degree (p % q) < degree (q * (p / q)) :=
176176
calc degree (p % q) < degree q : euclidean_domain.mod_lt _ hq0
177177
... ≤ _ : degree_le_mul_left _ (mt (div_eq_zero_iff hq0).1 (not_lt_of_ge hpq)),
178-
by conv {to_rhs, rw [← euclidean_domain.div_add_mod p q, add_comm,
179-
degree_add_eq_of_degree_lt this, degree_mul]}
178+
by conv_rhs { rw [← euclidean_domain.div_add_mod p q,
179+
degree_add_eq_left_of_degree_lt this, degree_mul] }
180180

181181
lemma degree_div_le (p q : polynomial R) : degree (p / q) ≤ degree p :=
182182
if hq : q = 0 then by simp [hq]

src/data/polynomial/lifts.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ begin
177177
rw [←hdeg, erase_lead] at deg_erase,
178178
replace deg_erase := lt_of_le_of_lt degree_le_nat_degree (with_bot.coe_lt_coe.2 deg_erase),
179179
rw [← deg_lead, ← herase.2] at deg_erase,
180-
rw [degree_add_eq_of_degree_lt deg_erase, deg_lead, degree_eq_nat_degree pzero]
180+
rw [degree_add_eq_right_of_degree_lt deg_erase, deg_lead, degree_eq_nat_degree pzero]
181181
end
182182

183183
end lift_deg
@@ -213,7 +213,7 @@ begin
213213
{ simp only [hq, map_add, map_pow, map_X],
214214
nth_rewrite 3 [← erase_lead_add_C_mul_X_pow p],
215215
rw [erase_lead, monic.leading_coeff hmonic, C_1, one_mul] },
216-
{ rw [degree_add_eq_of_degree_lt deg_er, @degree_X_pow R _ Rtrivial p.nat_degree,
216+
{ rw [degree_add_eq_right_of_degree_lt deg_er, @degree_X_pow R _ Rtrivial p.nat_degree,
217217
degree_eq_nat_degree (monic.ne_zero hmonic)] },
218218
{ rw [monic.def, leading_coeff_add_of_degree_lt deg_er],
219219
exact monic_pow monic_X p.nat_degree }

src/data/polynomial/monic.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ lemma monic_pow (hp : monic p) : ∀ (n : ℕ), monic (p ^ n)
9292
| 0 := monic_one
9393
| (n+1) := monic_mul hp (monic_pow n)
9494

95+
lemma monic_add_of_left {p q : polynomial R} (hp : monic p) (hpq : degree q < degree p) :
96+
monic (p + q) :=
97+
by rwa [monic, add_comm, leading_coeff_add_of_degree_lt hpq]
98+
99+
lemma monic_add_of_right {p q : polynomial R} (hq : monic q) (hpq : degree p < degree q) :
100+
monic (p + q) :=
101+
by rwa [monic, leading_coeff_add_of_degree_lt hpq]
102+
95103
end semiring
96104

97105
section comm_semiring

src/data/polynomial/ring_division.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ lemma degree_pos_of_aeval_root [algebra R S] {p : polynomial R} (hp : p ≠ 0)
4040
0 < p.degree :=
4141
nat_degree_pos_iff_degree_pos.mp (nat_degree_pos_of_aeval_root hp hz inj)
4242

43+
lemma aeval_mod_by_monic_eq_self_of_root [algebra R S]
44+
{p q : polynomial R} (hq : q.monic) {x : S} (hx : aeval x q = 0) :
45+
aeval x (p %ₘ q) = aeval x p :=
46+
eval₂_mod_by_monic_eq_self_of_root hq hx
47+
4348
end comm_ring
4449

4550
section integral_domain

src/field_theory/minimal_polynomial.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ lemma min {p : polynomial α} (pmonic : p.monic) (hp : polynomial.aeval x p = 0)
5959
degree (minimal_polynomial hx) ≤ degree p :=
6060
le_of_not_lt $ well_founded.not_lt_min degree_lt_wf _ hx ⟨pmonic, hp⟩
6161

62+
/-- A minimal polynomial is nonzero. -/
63+
lemma ne_zero [nontrivial α] : (minimal_polynomial hx) ≠ 0 :=
64+
ne_zero_of_monic (monic hx)
65+
6266
end ring
6367

6468
section field
@@ -68,10 +72,6 @@ section ring
6872
variables [ring β] [algebra α β]
6973
variables {x : β} (hx : is_integral α x)
7074

71-
/--A minimal polynomial is nonzero.-/
72-
lemma ne_zero : (minimal_polynomial hx) ≠ 0 :=
73-
ne_zero_of_monic (monic hx)
74-
7575
/--If an element x is a root of a nonzero polynomial p,
7676
then the degree of p is at least the degree of the minimal polynomial of x.-/
7777
lemma degree_le_of_ne_zero

src/linear_algebra/char_poly/coeff.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ begin
9292
{ rw degree_eq_iff_nat_degree_eq_of_pos, swap, apply nat.pos_of_ne_zero h,
9393
rw nat_degree_prod', simp_rw nat_degree_X_sub_C, unfold fintype.card, simp,
9494
simp_rw (monic_X_sub_C _).leading_coeff, simp, },
95-
rw degree_add_eq_of_degree_lt, exact h1, rw h1,
95+
rw degree_add_eq_right_of_degree_lt, exact h1, rw h1,
9696
apply lt_trans (char_poly_sub_diagonal_degree_lt M), rw with_bot.coe_lt_coe,
9797
rw ← nat.pred_eq_sub_one, apply nat.pred_lt, apply h,
9898
end

0 commit comments

Comments
 (0)