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

Commit e23b97e

Browse files
committed
feat(ring_theory/polynomial): decomposing the kernel of an endomorphism polynomial (#4174)
1 parent 03894df commit e23b97e

File tree

6 files changed

+115
-13
lines changed

6 files changed

+115
-13
lines changed

src/algebra/ring/basic.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,13 @@ theorem coe_monoid_hom_injective : function.injective (coe : (α →+* β) → (
260260
/-- Ring homomorphisms preserve multiplication. -/
261261
@[simp] lemma map_mul (f : α →+* β) (a b : α) : f (a * b) = f a * f b := f.map_mul' a b
262262

263+
/-- Ring homomorphisms preserve `bit0`. -/
264+
@[simp] lemma map_bit0 (f : α →+* β) (a : α) : f (bit0 a) = bit0 (f a) := map_add _ _ _
265+
266+
/-- Ring homomorphisms preserve `bit1`. -/
267+
@[simp] lemma map_bit1 (f : α →+* β) (a : α) : f (bit1 a) = bit1 (f a) :=
268+
by simp [bit1]
269+
263270
/-- `f : R →+* S` has a trivial codomain iff `f 1 = 0`. -/
264271
lemma codomain_trivial_iff_map_one_eq_zero : (0 : β) = 1 ↔ f 1 = 0 :=
265272
by rw [map_one, eq_comm]

src/data/polynomial/algebra_map.lean

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ end comp
9595
end comm_semiring
9696

9797
section aeval
98-
variables [comm_semiring R] {p : polynomial R}
98+
variables [comm_semiring R] {p q : polynomial R}
9999

100100
variables [semiring A] [algebra R A]
101101
variables {B : Type*} [semiring B] [algebra R B]
@@ -111,10 +111,37 @@ variables {R A}
111111

112112
theorem aeval_def (p : polynomial R) : aeval x p = eval₂ (algebra_map R A) x p := rfl
113113

114+
@[simp] lemma aeval_zero : aeval x (0 : polynomial R) = 0 :=
115+
alg_hom.map_zero (aeval x)
116+
114117
@[simp] lemma aeval_X : aeval x (X : polynomial R) = x := eval₂_X _ x
115118

116119
@[simp] lemma aeval_C (r : R) : aeval x (C r) = algebra_map R A r := eval₂_C _ x
117120

121+
lemma aeval_monomial {n : ℕ} {r : R} : aeval x (monomial n r) = (algebra_map _ _ r) * x^n :=
122+
eval₂_monomial _ _
123+
124+
@[simp] lemma aeval_X_pow {n : ℕ} : aeval x ((X : polynomial R)^n) = x^n :=
125+
eval₂_X_pow _ _
126+
127+
@[simp] lemma aeval_add : aeval x (p + q) = aeval x p + aeval x q :=
128+
alg_hom.map_add _ _ _
129+
130+
@[simp] lemma aeval_one : aeval x (1 : polynomial R) = 1 :=
131+
alg_hom.map_one _
132+
133+
@[simp] lemma aeval_bit0 : aeval x (bit0 p) = bit0 (aeval x p) :=
134+
alg_hom.map_bit0 _ _
135+
136+
@[simp] lemma aeval_bit1 : aeval x (bit1 p) = bit1 (aeval x p) :=
137+
alg_hom.map_bit1 _ _
138+
139+
@[simp] lemma aeval_nat_cast (n : ℕ) : aeval x (n : polynomial R) = n :=
140+
alg_hom.map_nat_cast _ _
141+
142+
lemma aeval_mul : aeval x (p * q) = aeval x p * aeval x q :=
143+
alg_hom.map_mul _ _ _
144+
118145
theorem eval_unique (φ : polynomial R →ₐ[R] A) (p) :
119146
φ p = eval₂ (algebra_map R A) (φ X) p :=
120147
begin
@@ -221,6 +248,9 @@ lemma aeval_endomorphism {M : Type*}
221248
[comm_ring R] [add_comm_group M] [module R M]
222249
(f : M →ₗ[R] M) (v : M) (p : polynomial R) :
223250
aeval f p v = p.sum (λ n b, b • (f ^ n) v) :=
224-
eval₂_endomorphism_algebra_map f v p
251+
begin
252+
rw [aeval_def, eval₂],
253+
exact (finset.sum_hom p.support (λ h : M →ₗ[R] M, h v)).symm
254+
end
225255

226256
end polynomial

src/data/polynomial/eval.lean

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -580,15 +580,6 @@ by apply is_ring_hom.of_semiring
580580

581581
instance eval.is_ring_hom {x : R} : is_ring_hom (eval x) := eval₂.is_ring_hom _
582582

583-
lemma eval₂_endomorphism_algebra_map {M : Type w}
584-
[add_comm_group M] [module R M]
585-
(f : M →ₗ[R] M) (v : M) (p : polynomial R) :
586-
p.eval₂ (algebra_map R (M →ₗ[R] M)) f v = p.sum (λ n b, b • (f ^ n) v) :=
587-
begin
588-
dunfold polynomial.eval₂ finsupp.sum,
589-
exact (finset.sum_hom p.support (λ h : M →ₗ[R] M, h v)).symm
590-
end
591-
592583
end comm_ring
593584

594585
end polynomial

src/linear_algebra/basic.lean

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,14 @@ end comm_semiring
388388

389389
section ring
390390

391-
instance endomorphism_ring [ring R] [add_comm_group M] [semimodule R M] : ring (M →ₗ[R] M) :=
391+
variables [ring R] [add_comm_group M] [semimodule R M]
392+
393+
instance endomorphism_ring : ring (M →ₗ[R] M) :=
392394
by refine {mul := (*), one := 1, ..linear_map.add_comm_group, ..};
393395
{ intros, apply linear_map.ext, simp {proj := ff} }
394396

397+
@[simp] lemma mul_apply (f g : M →ₗ[R] M) (x : M) : (f * g) x = f (g x) := rfl
398+
395399
end ring
396400

397401
section comm_ring

src/ring_theory/algebra.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,12 @@ lemma map_sum {ι : Type*} (f : ι → A) (s : finset ι) :
431431
@[simp] lemma map_nat_cast (n : ℕ) : φ n = n :=
432432
φ.to_ring_hom.map_nat_cast n
433433

434+
@[simp] lemma map_bit0 (x) : φ (bit0 x) = bit0 (φ x) :=
435+
φ.to_ring_hom.map_bit0 x
436+
437+
@[simp] lemma map_bit1 (x) : φ (bit1 x) = bit1 (φ x) :=
438+
φ.to_ring_hom.map_bit1 x
439+
434440
section
435441

436442
variables (R A)

src/ring_theory/polynomial/basic.lean

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,13 +429,77 @@ exists_irreducible_of_nat_degree_pos $ nat.pos_of_ne_zero hf
429429
lemma linear_independent_powers_iff_eval₂
430430
(f : M →ₗ[R] M) (v : M) :
431431
linear_independent R (λ n : ℕ, (f ^ n) v)
432-
↔ ∀ (p : polynomial R), polynomial.aeval f p v = 0 → p = 0 :=
432+
↔ ∀ (p : polynomial R), aeval f p v = 0 → p = 0 :=
433433
begin
434434
rw linear_independent_iff,
435435
simp only [finsupp.total_apply, aeval_endomorphism],
436436
refl
437437
end
438438

439+
lemma disjoint_ker_aeval_of_coprime
440+
(f : M →ₗ[R] M) {p q : polynomial R} (hpq : is_coprime p q) :
441+
disjoint (aeval f p).ker (aeval f q).ker :=
442+
begin
443+
intros v hv,
444+
rcases hpq with ⟨p', q', hpq'⟩,
445+
simpa [linear_map.mem_ker.1 (submodule.mem_inf.1 hv).1,
446+
linear_map.mem_ker.1 (submodule.mem_inf.1 hv).2]
447+
using congr_arg (λ p : polynomial R, aeval f p v) hpq'.symm,
448+
end
449+
450+
lemma sup_aeval_range_eq_top_of_coprime
451+
(f : M →ₗ[R] M) {p q : polynomial R} (hpq : is_coprime p q) :
452+
(aeval f p).range ⊔ (aeval f q).range = ⊤ :=
453+
begin
454+
rw eq_top_iff,
455+
intros v hv,
456+
rw submodule.mem_sup,
457+
rcases hpq with ⟨p', q', hpq'⟩,
458+
use aeval f (p * p') v,
459+
use linear_map.mem_range.2 ⟨aeval f p' v, by simp only [linear_map.mul_app, aeval_mul]⟩,
460+
use aeval f (q * q') v,
461+
use linear_map.mem_range.2 ⟨aeval f q' v, by simp only [linear_map.mul_app, aeval_mul]⟩,
462+
simpa only [mul_comm p p', mul_comm q q', aeval_one, aeval_add]
463+
using congr_arg (λ p : polynomial R, aeval f p v) hpq'
464+
end
465+
466+
lemma sup_ker_aeval_le_ker_aeval_mul {f : M →ₗ[R] M} {p q : polynomial R} :
467+
(aeval f p).ker ⊔ (aeval f q).ker ≤ (aeval f (p * q)).ker :=
468+
begin
469+
intros v hv,
470+
rcases submodule.mem_sup.1 hv with ⟨x, hx, y, hy, hxy⟩,
471+
have h_eval_x : aeval f (p * q) x = 0,
472+
{ rw [mul_comm, aeval_mul, linear_map.mul_apply, linear_map.mem_ker.1 hx, linear_map.map_zero] },
473+
have h_eval_y : aeval f (p * q) y = 0,
474+
{ rw [aeval_mul, linear_map.mul_apply, linear_map.mem_ker.1 hy, linear_map.map_zero] },
475+
rw [linear_map.mem_ker, ←hxy, linear_map.map_add, h_eval_x, h_eval_y, add_zero],
476+
end
477+
478+
lemma sup_ker_aeval_eq_ker_aeval_mul_of_coprime
479+
(f : M →ₗ[R] M) {p q : polynomial R} (hpq : is_coprime p q) :
480+
(aeval f p).ker ⊔ (aeval f q).ker = (aeval f (p * q)).ker :=
481+
begin
482+
apply le_antisymm sup_ker_aeval_le_ker_aeval_mul,
483+
intros v hv,
484+
rw submodule.mem_sup,
485+
rcases hpq with ⟨p', q', hpq'⟩,
486+
have h_eval₂_qpp' := calc
487+
aeval f (q * (p * p')) v = aeval f (p' * (p * q)) v :
488+
by rw [mul_comm, mul_assoc, mul_comm, mul_assoc, mul_comm q p]
489+
... = 0 :
490+
by rw [aeval_mul, linear_map.mul_apply, linear_map.mem_ker.1 hv, linear_map.map_zero],
491+
have h_eval₂_pqq' := calc
492+
aeval f (p * (q * q')) v = aeval f (q' * (p * q)) v :
493+
by rw [←mul_assoc, mul_comm]
494+
... = 0 :
495+
by rw [aeval_mul, linear_map.mul_apply, linear_map.mem_ker.1 hv, linear_map.map_zero],
496+
rw aeval_mul at h_eval₂_qpp' h_eval₂_pqq',
497+
refine ⟨aeval f (q * q') v, linear_map.mem_ker.1 h_eval₂_pqq',
498+
aeval f (p * p') v, linear_map.mem_ker.1 h_eval₂_qpp', _⟩,
499+
rw [add_comm, mul_comm p p', mul_comm q q'],
500+
simpa using congr_arg (λ p : polynomial R, aeval f p v) hpq'
501+
end
502+
439503
end polynomial
440504

441505
namespace mv_polynomial

0 commit comments

Comments
 (0)