@@ -9,8 +9,8 @@ import data.finsupp algebra.euclidean_domain
9
9
10
10
/-- `polynomial α` is the type of univariate polynomials over `α`.
11
11
12
- Polynomials should be seen as (semi-)rings with the additional the constructor `X`. `C` is the
13
- embedding from `α `. -/
12
+ Polynomials should be seen as (semi-)rings with the additional constructor `X`.
13
+ The embedding from α is called `C `. -/
14
14
def polynomial (α : Type *) [comm_semiring α] := ℕ →₀ α
15
15
16
16
open finsupp finset lattice
@@ -52,6 +52,12 @@ def C (a : α) : polynomial α := single 0 a
52
52
/-- `X` is the polynomial variable (aka indeterminant). -/
53
53
def X : polynomial α := single 1 1
54
54
55
+ /-- coeff p n is the coefficient of X^n in p -/
56
+ def coeff (p : polynomial α) (n : ℕ) := p n
57
+
58
+ theorem ext (p q : polynomial α) : p = q ↔ ∀ n, coeff p n = coeff q n :=
59
+ ⟨λ h n, h ▸ rfl,finsupp.ext⟩
60
+
55
61
/-- `degree p` is the degree of the polynomial `p`, i.e. the largest `X`-exponent in `p`.
56
62
`degree p = some n` when `p ≠ 0` and `n` is the highest power of `X` that appears in `p`, otherwise
57
63
`degree 0 = ⊥`. -/
@@ -60,7 +66,7 @@ def degree (p : polynomial α) : with_bot ℕ := p.support.sup some
60
66
def degree_lt_wf : well_founded (λp q : polynomial α, degree p < degree q) :=
61
67
inv_image.wf degree (with_bot.well_founded_lt nat.lt_wf)
62
68
63
- /-- `nat_degree p` forces `degree p` to ℕ, by fixing the zero polnomial to the 0 degree . -/
69
+ /-- `nat_degree p` forces `degree p` to ℕ, by defining nat_degree 0 = 0 . -/
64
70
def nat_degree (p : polynomial α) : ℕ := (degree p).get_or_else 0
65
71
66
72
lemma single_eq_C_mul_X : ∀{n}, single n a = C a * X^n
@@ -134,6 +140,113 @@ suffices (single n 1 : polynomial α) i = (if n = i then 1 else 0),
134
140
by rw [single_eq_C_mul_X] at this ; simpa,
135
141
single_apply
136
142
143
+ section coeff
144
+
145
+ @[simp] lemma coeff_zero (n : ℕ) : coeff (0 : polynomial α) n = 0 := rfl
146
+
147
+ @[simp] lemma coeff_C_mul_X (x : α) (k n : ℕ) :
148
+ coeff (C x * X^k : polynomial α) n = if n = k then x else 0 :=
149
+ by rw [← single_eq_C_mul_X, coeff, single_apply]; split_ifs; cc
150
+
151
+ @[simp] lemma coeff_C (x : α) (n : ℕ) :
152
+ coeff (C x) n = if n = 0 then x else 0 :=
153
+ by simpa only [pow_zero, mul_one] using coeff_C_mul_X x 0 n
154
+
155
+ @[simp] lemma coeff_one (n : ℕ) :
156
+ coeff (1 : polynomial α) n = if n = 0 then 1 else 0 :=
157
+ coeff_C 1 n
158
+
159
+ variable α
160
+ @[simp] lemma coeff_X_pow (k n : ℕ) :
161
+ coeff (X^k : polynomial α) n = if n = k then 1 else 0 :=
162
+ by simpa only [C_1, one_mul] using coeff_C_mul_X (1 :α) k n
163
+
164
+ @[simp] lemma coeff_X (n : ℕ) :
165
+ coeff (X : polynomial α) n = if n = 1 then 1 else 0 :=
166
+ by simpa only [pow_one] using coeff_X_pow α 1 n
167
+ variable {α}
168
+
169
+ @[simp] lemma coeff_add (p q : polynomial α) (n : ℕ) :
170
+ coeff (p + q) n = coeff p n + coeff q n := rfl
171
+
172
+ lemma coeff_mul_left (p q : polynomial α) (n : ℕ) :
173
+ coeff (p * q) n = (range (n+1 )).sum (λ k, coeff p k * coeff q (n-k)) :=
174
+ begin
175
+ refine polynomial.induction_on p (λ x, _) (λ p1 p2 ih1 ih2, _) (λ pn x ih, _),
176
+ { refine polynomial.induction_on q (λ y, _) (λ q1 q2 ih1 ih2, _) (λ qn y ih, _),
177
+ { rw [sum_eq_single 0 , ← C_mul, coeff_C, coeff_C, coeff_C, if_pos rfl, nat.sub_zero],
178
+ { by_cases h : n = 0 ,
179
+ { simp only [if_pos h] },
180
+ { simp only [if_neg h, mul_zero] } },
181
+ { intros k h1 h2, rw [coeff_C, if_neg h2, zero_mul] },
182
+ { exact λ h1, (h1 (mem_range.2 (nat.zero_lt_succ n))).elim } },
183
+ { simp only [mul_add, coeff_add],
184
+ -- why can't I just rw [ih1, ih2]???
185
+ generalize_hyp h1 : coeff (C x * q1) n = Q1 at ih1 ⊢, rw ih1,
186
+ generalize_hyp h2 : coeff (C x * q2) n = Q2 at ih2 ⊢, rw ih2,
187
+ rw finset.sum_add_distrib },
188
+ { rw [sum_eq_single 0 , ← mul_assoc, ← C_mul, coeff_C_mul_X, coeff_C_mul_X, coeff_C, if_pos rfl, nat.sub_zero],
189
+ { split_ifs; simp only [h, if_pos rfl, if_false, mul_zero] },
190
+ { intros k h1 h2, rw [coeff_C, if_neg h2, zero_mul] },
191
+ { exact λ h1, (h1 (mem_range.2 (nat.zero_lt_succ n))).elim } } },
192
+ { simp only [add_mul, coeff_add],
193
+ -- why can't I just rw [ih1, ih2]???
194
+ generalize_hyp h1 : coeff (p1 * q) n = P1 at ih1 ⊢, rw ih1,
195
+ generalize_hyp h2 : coeff (p2 * q) n = P2 at ih2 ⊢, rw ih2,
196
+ rw finset.sum_add_distrib },
197
+ { refine polynomial.induction_on q (λ y, _) (λ q1 q2 ih1 ih2, _) (λ qn y ih, _),
198
+ { rw [sum_eq_single n, mul_right_comm, ← C_mul, coeff_C_mul_X, coeff_C_mul_X, coeff_C, if_pos (nat.sub_self _)],
199
+ { split_ifs with h; simp only [h, if_pos rfl, if_false, zero_mul] },
200
+ { intros k h1 h2, rw [coeff_C, if_neg, mul_zero],
201
+ refine mt (λ H, le_antisymm (nat.le_of_lt_succ (mem_range.1 h1)) (nat.sub_eq_zero_iff_le.1 H)) h2 },
202
+ { exact λ h1, (h1 (mem_range.2 (le_refl (n+1 )))).elim } },
203
+ { simp only [mul_add, coeff_add],
204
+ generalize_hyp h1 : coeff (C x * X ^ (pn + 1 ) * q1) n = Q1 at ih1 ⊢, rw ih1,
205
+ generalize_hyp h2 : coeff (C x * X ^ (pn + 1 ) * q2) n = Q2 at ih2 ⊢, rw ih2,
206
+ rw finset.sum_add_distrib },
207
+ { rw [mul_left_comm, mul_assoc, ← pow_add, ← mul_assoc, ← C_mul],
208
+ rw [sum_eq_single (pn + 1 ), coeff_C_mul_X, coeff_C_mul_X, coeff_C_mul_X, if_pos rfl],
209
+ { have H : n = pn + 1 + (qn + 1 ) ↔ n - (pn + 1 ) = qn + 1 ,
210
+ { split, { intro H, rw [H, nat.add_sub_cancel_left] },
211
+ intro H,
212
+ have H1 : pn + 1 < n,
213
+ { refine lt_of_not_ge (λ H1, _),
214
+ rw [nat.sub_eq_zero_of_le H1] at H,
215
+ exact nat.succ_ne_zero qn H.symm },
216
+ rw [(nat.sub_eq_iff_eq_add (le_of_lt H1)).1 H, add_comm] },
217
+ split_ifs with h,
218
+ { rw [if_pos (H.1 h), mul_comm] },
219
+ { rw [if_neg (mt H.2 h), mul_zero] } },
220
+ { intros k h1 h2, rw [coeff_C_mul_X, if_neg h2, zero_mul] },
221
+ { intro H,
222
+ rw [coeff_C_mul_X, if_pos rfl, coeff_C_mul_X, if_neg, mul_zero],
223
+ rw [mem_range, not_lt] at H,
224
+ rw [nat.sub_eq_zero_of_le (le_of_lt H)],
225
+ exact ne.symm (nat.succ_ne_zero _) } } }
226
+ end
227
+
228
+ lemma coeff_mul_right (p q : polynomial α) (n : ℕ) :
229
+ coeff (p * q) n = (range (n+1 )).sum (λ k, coeff p (n-k) * coeff q k) :=
230
+ by rw [mul_comm, coeff_mul_left]; simp only [mul_comm]
231
+
232
+ theorem coeff_mul_X_pow (p : polynomial α) (n d : ℕ) :
233
+ coeff (p * polynomial.X ^ n) (d + n) = coeff p d :=
234
+ begin
235
+ rw [coeff_mul_right, sum_eq_single n, coeff_X_pow, if_pos rfl, mul_one, nat.add_sub_cancel],
236
+ { intros b h1 h2, rw [coeff_X_pow, if_neg h2, mul_zero] },
237
+ { exact λ h1, (h1 (mem_range.2 (nat.le_add_left _ _))).elim }
238
+ end
239
+
240
+ theorem coeff_mul_X (p : polynomial α) (n : ℕ) :
241
+ coeff (p * X) (n + 1 ) = coeff p n :=
242
+ by simpa only [pow_one] using coeff_mul_X_pow p 1 n
243
+
244
+ theorem mul_X_pow_eq_zero {p : polynomial α} {n : ℕ}
245
+ (H : p * X ^ n = 0 ) : p = 0 :=
246
+ (ext _ _).2 $ λ k, (coeff_mul_X_pow p n k).symm.trans $ (ext _ _).1 H (k+n)
247
+
248
+ end coeff
249
+
137
250
section eval₂
138
251
variables {β : Type *} [comm_semiring β]
139
252
variables (f : α → β) [is_semiring_hom f] (x : β)
@@ -529,8 +642,22 @@ section comm_ring
529
642
variables [comm_ring α] {p q : polynomial α}
530
643
instance : comm_ring (polynomial α) := finsupp.to_comm_ring
531
644
instance : has_scalar α (polynomial α) := finsupp.to_has_scalar
532
- instance : module α (polynomial α) := finsupp.to_module α
533
-
645
+ -- TODO if this becomes a semimodule then the below lemma could be proved for semimodules
646
+ instance : module α (polynomial α) := finsupp.to_module α
647
+
648
+ -- TODO -- this is OK for semimodules
649
+ @[simp] lemma coeff_smul (p : polynomial α) (r : α) (n : ℕ) :
650
+ coeff (r • p) n = r * coeff p n := finsupp.smul_apply
651
+
652
+ -- TODO -- this is OK for semimodules
653
+ lemma C_mul' (a : α) (f : polynomial α) : C a * f = a • f :=
654
+ (ext _ _).2 $ λ n, C_mul_apply f
655
+
656
+ -- TODO -- this is OK for semimodules
657
+ lemma coeff_is_linear (n : ℕ) : is_linear_map (λ f : polynomial α, coeff f n) := {
658
+ add := λ f g, coeff_add f g n,
659
+ smul := λ r p, coeff_smul p r n
660
+ }
534
661
instance C.is_ring_hom : is_ring_hom (@C α _ _) := by apply is_ring_hom.of_semiring
535
662
536
663
instance eval₂.is_ring_hom {β} [comm_ring β]
@@ -936,7 +1063,7 @@ lemma degree_pos_of_root (hp : p ≠ 0) (h : is_root p a) : 0 < degree p :=
936
1063
lt_of_not_ge $ λ hlt, begin
937
1064
have := eq_C_of_degree_le_zero hlt,
938
1065
rw [is_root, this , eval_C] at h,
939
- exact hp (ext (λ n, show p n = 0 , from
1066
+ exact hp (finsupp. ext (λ n, show p n = 0 , from
940
1067
nat.cases_on n h (λ _, eq_zero_of_degree_lt (lt_of_le_of_lt hlt
941
1068
(with_bot.coe_lt_coe.2 (nat.succ_pos _)))))),
942
1069
end
0 commit comments