forked from leanprover-community/mathlib4
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCoeff.lean
More file actions
233 lines (161 loc) · 7.55 KB
/
Coeff.lean
File metadata and controls
233 lines (161 loc) · 7.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/-
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Johannes Hölzl, Kim Morrison, Jens Wagemaker
-/
module
public import Mathlib.Algebra.Polynomial.Coeff
public import Mathlib.Algebra.Polynomial.Eval.Defs
/-!
# Evaluation of polynomials
This file contains results on the interaction of `Polynomial.eval` and `Polynomial.coeff`
-/
@[expose] public section
noncomputable section
open Finset AddMonoidAlgebra
open Polynomial
namespace Polynomial
universe u v w y
variable {R : Type u} {S : Type v} {T : Type w} {ι : Type y} {a b : R} {m n : ℕ}
section Semiring
variable [Semiring R] {p q r : R[X]}
section
variable [Semiring S]
variable (f : R →+* S) (x : S)
@[simp]
theorem eval₂_at_zero : p.eval₂ f 0 = f (coeff p 0) := by
simp +contextual only [eval₂_eq_sum, zero_pow_eq, mul_ite, mul_zero,
mul_one, sum, Classical.not_not, mem_support_iff, sum_ite_eq', ite_eq_left_iff, map_zero,
imp_true_iff]
@[simp]
theorem eval₂_C_X : eval₂ C X p = p :=
Polynomial.induction_on' p (fun p q hp hq => by simp [hp, hq]) fun n x => by
rw [eval₂_monomial, ← smul_X_eq_monomial, C_mul']
end
section Eval
variable {x : R}
theorem coeff_zero_eq_eval_zero (p : R[X]) : coeff p 0 = p.eval 0 :=
calc
coeff p 0 = coeff p 0 * 0 ^ 0 := by simp
_ = p.eval 0 := by
symm
rw [eval_eq_sum]
exact Finset.sum_eq_single _ (fun b _ hb => by simp [zero_pow hb]) (by simp)
theorem zero_isRoot_iff_coeff_zero_eq_zero {p : R[X]} : IsRoot p 0 ↔ p.coeff 0 = 0 := by
rw [coeff_zero_eq_eval_zero, IsRoot]
alias ⟨coeff_zero_eq_zero_of_zero_isRoot, zero_isRoot_of_coeff_zero_eq_zero⟩ :=
zero_isRoot_iff_coeff_zero_eq_zero
end Eval
section Map
variable [Semiring S]
variable (f : R →+* S)
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) := by
rw [map, eval₂_def, coeff_sum, sum]
simp_all
lemma coeff_map_eq_comp (p : R[X]) (f : R →+* S) : (p.map f).coeff = f ∘ p.coeff := by
ext n; exact coeff_map ..
theorem map_map [Semiring T] (g : S →+* T) (p : R[X]) : (p.map f).map g = p.map (g.comp f) :=
ext (by simp [coeff_map])
@[simp]
theorem map_id : p.map (RingHom.id _) = p := by simp [Polynomial.ext_iff, coeff_map]
/-- The polynomial ring over a finite product of rings is isomorphic to
the product of polynomial rings over individual rings. -/
def piEquiv {ι} [Finite ι] (R : ι → Type*) [∀ i, Semiring (R i)] :
(∀ i, R i)[X] ≃+* ∀ i, (R i)[X] :=
.ofBijective (Pi.ringHom fun i ↦ mapRingHom (Pi.evalRingHom R i))
⟨fun p q h ↦ by ext n i; simpa using congr_arg (fun p ↦ coeff (p i) n) h,
fun p ↦ ⟨.ofFinsupp (.ofSupportFinite (fun n i ↦ coeff (p i) n) <|
(Set.finite_iUnion fun i ↦ (p i).support.finite_toSet).subset fun n hn ↦ by
simp only [Set.mem_iUnion, Finset.mem_coe, mem_support_iff, Function.mem_support] at hn ⊢
contrapose! hn; exact funext hn), by ext i n; exact coeff_map _ _⟩⟩
theorem map_injective (hf : Function.Injective f) : Function.Injective (map f) := fun p q h =>
ext fun m => hf <| by rw [← coeff_map f, ← coeff_map f, h]
theorem map_injective_iff : Function.Injective (map f) ↔ Function.Injective f :=
⟨fun h r r' eq ↦ by simpa using h (a₁ := C r) (a₂ := C r') (by simpa), map_injective f⟩
theorem map_surjective (hf : Function.Surjective f) : Function.Surjective (map f) := fun p =>
p.induction_on'
(by rintro _ _ ⟨p, rfl⟩ ⟨q, rfl⟩; exact ⟨p + q, Polynomial.map_add f⟩)
fun n s ↦
let ⟨r, hr⟩ := hf s
⟨monomial n r, by rw [map_monomial f, hr]⟩
theorem map_surjective_iff : Function.Surjective (map f) ↔ Function.Surjective f :=
⟨fun h s ↦ let ⟨p, h⟩ := h (C s); ⟨p.coeff 0, by simpa using congr(coeff $h 0)⟩, map_surjective f⟩
variable {f}
protected theorem map_eq_zero_iff (hf : Function.Injective f) : p.map f = 0 ↔ p = 0 :=
map_eq_zero_iff (mapRingHom f) (map_injective f hf)
protected theorem map_ne_zero_iff (hf : Function.Injective f) : p.map f ≠ 0 ↔ p ≠ 0 :=
(Polynomial.map_eq_zero_iff hf).not
variable (f)
@[simp]
theorem mapRingHom_id : mapRingHom (RingHom.id R) = RingHom.id R[X] :=
RingHom.ext fun _x => map_id
@[simp]
theorem mapRingHom_comp [Semiring T] (f : S →+* T) (g : R →+* S) :
(mapRingHom f).comp (mapRingHom g) = mapRingHom (f.comp g) :=
RingHom.ext <| Polynomial.map_map g f
theorem eval₂_map [Semiring T] (g : S →+* T) (x : T) :
(p.map f).eval₂ g x = p.eval₂ (g.comp f) x := by
rw [eval₂_eq_eval_map, eval₂_eq_eval_map, map_map]
@[simp]
theorem eval_zero_map (f : R →+* S) (p : R[X]) : (p.map f).eval 0 = f (p.eval 0) := by
simp [← coeff_zero_eq_eval_zero]
@[simp]
theorem eval_one_map (f : R →+* S) (p : R[X]) : (p.map f).eval 1 = f (p.eval 1) := by
induction p using Polynomial.induction_on' with
| add p q hp hq => simp only [hp, hq, Polynomial.map_add, map_add, eval_add]
| monomial n r => simp only [one_pow, mul_one, eval_monomial, map_monomial]
@[simp]
theorem eval_natCast_map (f : R →+* S) (p : R[X]) (n : ℕ) :
(p.map f).eval (n : S) = f (p.eval n) := by
induction p using Polynomial.induction_on' with
| add p q hp hq => simp only [hp, hq, Polynomial.map_add, map_add, eval_add]
| monomial n r => simp only [map_natCast f, eval_monomial, map_monomial, f.map_pow, f.map_mul]
@[simp]
theorem eval_intCast_map {R S : Type*} [Ring R] [Ring S] (f : R →+* S) (p : R[X]) (i : ℤ) :
(p.map f).eval (i : S) = f (p.eval i) := by
induction p using Polynomial.induction_on' with
| add p q hp hq => simp only [hp, hq, Polynomial.map_add, map_add, eval_add]
| monomial n r => simp only [map_intCast, eval_monomial, map_monomial, map_pow, map_mul]
end Map
section HomEval₂
variable [Semiring S] [Semiring T] (f : R →+* S) (g : S →+* T) (p)
theorem hom_eval₂ (x : S) : g (p.eval₂ f x) = p.eval₂ (g.comp f) (g x) := by
rw [← eval₂_map, eval₂_at_apply, eval_map]
end HomEval₂
end Semiring
section CommSemiring
section Eval
section
variable [Semiring R] {p q : R[X]} {x : R} [Semiring S] (f : R →+* S)
theorem eval₂_hom (x : R) : p.eval₂ f (f x) = f (p.eval x) :=
RingHom.comp_id f ▸ (hom_eval₂ p (RingHom.id R) f x).symm
end
section
variable [CommSemiring R] {p q : R[X]} {x : R} [CommSemiring S] (f : R →+* S)
theorem evalRingHom_zero : evalRingHom 0 = constantCoeff :=
DFunLike.ext _ _ fun p => p.coeff_zero_eq_eval_zero.symm
end
end Eval
section Map
theorem support_map_subset [Semiring R] [Semiring S] (f : R →+* S) (p : R[X]) :
(map f p).support ⊆ p.support := by
intro x
contrapose
simp +contextual
theorem support_map_of_injective [Semiring R] [Semiring S] (p : R[X]) {f : R →+* S}
(hf : Function.Injective f) : (map f p).support = p.support := by
simp_rw [Finset.ext_iff, mem_support_iff, coeff_map, ← map_zero f, hf.ne_iff,
forall_const]
variable [CommSemiring R] [CommSemiring S] (f : R →+* S)
theorem IsRoot.map {f : R →+* S} {x : R} {p : R[X]} (h : IsRoot p x) : IsRoot (p.map f) (f x) := by
rw [IsRoot, eval_map, eval₂_hom, h.eq_zero, f.map_zero]
theorem IsRoot.of_map {R} [Ring R] {f : R →+* S} {x : R} {p : R[X]} (h : IsRoot (p.map f) (f x))
(hf : Function.Injective f) : IsRoot p x := by
rwa [IsRoot, ← (injective_iff_map_eq_zero' f).mp hf, ← eval₂_hom, ← eval_map]
theorem isRoot_map_iff {R : Type*} [CommRing R] {f : R →+* S} {x : R} {p : R[X]}
(hf : Function.Injective f) : IsRoot (p.map f) (f x) ↔ IsRoot p x :=
⟨fun h => h.of_map hf, fun h => h.map⟩
end Map
end CommSemiring
end Polynomial