1 (* Title: HOL/Library/Poly_Deriv.thy |
1 (* Title: HOL/Library/Poly_Deriv.thy |
2 Author: Amine Chaieb |
2 Author: Amine Chaieb |
3 Author: Brian Huffman |
3 Author: Brian Huffman |
4 *) |
4 *) |
5 |
5 |
6 section{* Polynomials and Differentiation *} |
6 section\<open>Polynomials and Differentiation\<close> |
7 |
7 |
8 theory Poly_Deriv |
8 theory Poly_Deriv |
9 imports Deriv Polynomial |
9 imports Deriv Polynomial |
10 begin |
10 begin |
11 |
11 |
12 subsection {* Derivatives of univariate polynomials *} |
12 subsection \<open>Derivatives of univariate polynomials\<close> |
13 |
13 |
14 function pderiv :: "'a::real_normed_field poly \<Rightarrow> 'a poly" |
14 function pderiv :: "'a::real_normed_field poly \<Rightarrow> 'a poly" |
15 where |
15 where |
16 [simp del]: "pderiv (pCons a p) = (if p = 0 then 0 else p + pCons 0 (pderiv p))" |
16 [simp del]: "pderiv (pCons a p) = (if p = 0 then 0 else p + pCons 0 (pderiv p))" |
17 by (auto intro: pCons_cases) |
17 by (auto intro: pCons_cases) |
93 by (rule DERIV_cong, rule DERIV_add, auto) |
93 by (rule DERIV_cong, rule DERIV_add, auto) |
94 |
94 |
95 lemma poly_DERIV[simp]: "DERIV (%x. poly p x) x :> poly (pderiv p) x" |
95 lemma poly_DERIV[simp]: "DERIV (%x. poly p x) x :> poly (pderiv p) x" |
96 by (induct p, auto intro!: derivative_eq_intros simp add: pderiv_pCons) |
96 by (induct p, auto intro!: derivative_eq_intros simp add: pderiv_pCons) |
97 |
97 |
98 text{* Consequences of the derivative theorem above*} |
98 text\<open>Consequences of the derivative theorem above\<close> |
99 |
99 |
100 lemma poly_differentiable[simp]: "(%x. poly p x) differentiable (at x::real filter)" |
100 lemma poly_differentiable[simp]: "(%x. poly p x) differentiable (at x::real filter)" |
101 apply (simp add: real_differentiable_def) |
101 apply (simp add: real_differentiable_def) |
102 apply (blast intro: poly_DERIV) |
102 apply (blast intro: poly_DERIV) |
103 done |
103 done |
120 apply auto |
120 apply auto |
121 apply (rule_tac x = z in exI) |
121 apply (rule_tac x = z in exI) |
122 apply (auto simp add: mult_left_cancel poly_DERIV [THEN DERIV_unique]) |
122 apply (auto simp add: mult_left_cancel poly_DERIV [THEN DERIV_unique]) |
123 done |
123 done |
124 |
124 |
125 text{*Lemmas for Derivatives*} |
125 text\<open>Lemmas for Derivatives\<close> |
126 |
126 |
127 lemma order_unique_lemma: |
127 lemma order_unique_lemma: |
128 fixes p :: "'a::idom poly" |
128 fixes p :: "'a::idom poly" |
129 assumes "[:-a, 1:] ^ n dvd p" "\<not> [:-a, 1:] ^ Suc n dvd p" |
129 assumes "[:-a, 1:] ^ n dvd p" "\<not> [:-a, 1:] ^ Suc n dvd p" |
130 shows "n = order a p" |
130 shows "n = order a p" |
176 show "\<not> [:- a, 1:] ^ Suc n' dvd pderiv ([:- a, 1:] ^ Suc n' * q)" |
176 show "\<not> [:- a, 1:] ^ Suc n' dvd pderiv ([:- a, 1:] ^ Suc n' * q)" |
177 apply (subst lemma_order_pderiv1) |
177 apply (subst lemma_order_pderiv1) |
178 by (metis * nd dvd_mult_cancel_right field_power_not_zero pCons_eq_0_iff power_Suc zero_neq_one) |
178 by (metis * nd dvd_mult_cancel_right field_power_not_zero pCons_eq_0_iff power_Suc zero_neq_one) |
179 qed |
179 qed |
180 then show ?thesis |
180 then show ?thesis |
181 by (metis `n = Suc n'` pe) |
181 by (metis \<open>n = Suc n'\<close> pe) |
182 qed |
182 qed |
183 |
183 |
184 lemma order_decomp: |
184 lemma order_decomp: |
185 "p \<noteq> 0 |
185 "p \<noteq> 0 |
186 ==> \<exists>q. p = [:-a, 1:] ^ (order a p) * q & |
186 ==> \<exists>q. p = [:-a, 1:] ^ (order a p) * q & |
213 apply (rule order_unique_lemma [symmetric], fold t_def) |
213 apply (rule order_unique_lemma [symmetric], fold t_def) |
214 apply (simp_all add: power_add t_dvd_iff) |
214 apply (simp_all add: power_add t_dvd_iff) |
215 done |
215 done |
216 qed |
216 qed |
217 |
217 |
218 text{*Now justify the standard squarefree decomposition, i.e. f / gcd(f,f'). *} |
218 text\<open>Now justify the standard squarefree decomposition, i.e. f / gcd(f,f').\<close> |
219 |
219 |
220 lemma order_divides: "[:-a, 1:] ^ n dvd p \<longleftrightarrow> p = 0 \<or> n \<le> order a p" |
220 lemma order_divides: "[:-a, 1:] ^ n dvd p \<longleftrightarrow> p = 0 \<or> n \<le> order a p" |
221 apply (cases "p = 0", auto) |
221 apply (cases "p = 0", auto) |
222 apply (drule order_2 [where a=a and p=p]) |
222 apply (drule order_2 [where a=a and p=p]) |
223 apply (metis not_less_eq_eq power_le_dvd) |
223 apply (metis not_less_eq_eq power_le_dvd) |
230 and p': "pderiv p = e * d" |
230 and p': "pderiv p = e * d" |
231 and d: "d = r * p + s * pderiv p" |
231 and d: "d = r * p + s * pderiv p" |
232 shows "order a q = (if order a p = 0 then 0 else 1)" |
232 shows "order a q = (if order a p = 0 then 0 else 1)" |
233 proof (rule classical) |
233 proof (rule classical) |
234 assume 1: "order a q \<noteq> (if order a p = 0 then 0 else 1)" |
234 assume 1: "order a q \<noteq> (if order a p = 0 then 0 else 1)" |
235 from `pderiv p \<noteq> 0` have "p \<noteq> 0" by auto |
235 from \<open>pderiv p \<noteq> 0\<close> have "p \<noteq> 0" by auto |
236 with p have "order a p = order a q + order a d" |
236 with p have "order a p = order a q + order a d" |
237 by (simp add: order_mult) |
237 by (simp add: order_mult) |
238 with 1 have "order a p \<noteq> 0" by (auto split: if_splits) |
238 with 1 have "order a p \<noteq> 0" by (auto split: if_splits) |
239 have "order a (pderiv p) = order a e + order a d" |
239 have "order a (pderiv p) = order a e + order a d" |
240 using `pderiv p \<noteq> 0` `pderiv p = e * d` by (simp add: order_mult) |
240 using \<open>pderiv p \<noteq> 0\<close> \<open>pderiv p = e * d\<close> by (simp add: order_mult) |
241 have "order a p = Suc (order a (pderiv p))" |
241 have "order a p = Suc (order a (pderiv p))" |
242 using `pderiv p \<noteq> 0` `order a p \<noteq> 0` by (rule order_pderiv) |
242 using \<open>pderiv p \<noteq> 0\<close> \<open>order a p \<noteq> 0\<close> by (rule order_pderiv) |
243 have "d \<noteq> 0" using `p \<noteq> 0` `p = q * d` by simp |
243 have "d \<noteq> 0" using \<open>p \<noteq> 0\<close> \<open>p = q * d\<close> by simp |
244 have "([:-a, 1:] ^ (order a (pderiv p))) dvd d" |
244 have "([:-a, 1:] ^ (order a (pderiv p))) dvd d" |
245 apply (simp add: d) |
245 apply (simp add: d) |
246 apply (rule dvd_add) |
246 apply (rule dvd_add) |
247 apply (rule dvd_mult) |
247 apply (rule dvd_mult) |
248 apply (simp add: order_divides `p \<noteq> 0` |
248 apply (simp add: order_divides \<open>p \<noteq> 0\<close> |
249 `order a p = Suc (order a (pderiv p))`) |
249 \<open>order a p = Suc (order a (pderiv p))\<close>) |
250 apply (rule dvd_mult) |
250 apply (rule dvd_mult) |
251 apply (simp add: order_divides) |
251 apply (simp add: order_divides) |
252 done |
252 done |
253 then have "order a (pderiv p) \<le> order a d" |
253 then have "order a (pderiv p) \<le> order a d" |
254 using `d \<noteq> 0` by (simp add: order_divides) |
254 using \<open>d \<noteq> 0\<close> by (simp add: order_divides) |
255 show ?thesis |
255 show ?thesis |
256 using `order a p = order a q + order a d` |
256 using \<open>order a p = order a q + order a d\<close> |
257 using `order a (pderiv p) = order a e + order a d` |
257 using \<open>order a (pderiv p) = order a e + order a d\<close> |
258 using `order a p = Suc (order a (pderiv p))` |
258 using \<open>order a p = Suc (order a (pderiv p))\<close> |
259 using `order a (pderiv p) \<le> order a d` |
259 using \<open>order a (pderiv p) \<le> order a d\<close> |
260 by auto |
260 by auto |
261 qed |
261 qed |
262 |
262 |
263 lemma poly_squarefree_decomp_order2: "[| pderiv p \<noteq> 0; |
263 lemma poly_squarefree_decomp_order2: "[| pderiv p \<noteq> 0; |
264 p = q * d; |
264 p = q * d; |
296 and "p = q * d" |
296 and "p = q * d" |
297 and "pderiv p = e * d" |
297 and "pderiv p = e * d" |
298 and "d = r * p + s * pderiv p" |
298 and "d = r * p + s * pderiv p" |
299 shows "rsquarefree q & (\<forall>a. (poly q a = 0) = (poly p a = 0))" |
299 shows "rsquarefree q & (\<forall>a. (poly q a = 0) = (poly p a = 0))" |
300 proof - |
300 proof - |
301 from `pderiv p \<noteq> 0` have "p \<noteq> 0" by auto |
301 from \<open>pderiv p \<noteq> 0\<close> have "p \<noteq> 0" by auto |
302 with `p = q * d` have "q \<noteq> 0" by simp |
302 with \<open>p = q * d\<close> have "q \<noteq> 0" by simp |
303 have "\<forall>a. order a q = (if order a p = 0 then 0 else 1)" |
303 have "\<forall>a. order a q = (if order a p = 0 then 0 else 1)" |
304 using assms by (rule poly_squarefree_decomp_order2) |
304 using assms by (rule poly_squarefree_decomp_order2) |
305 with `p \<noteq> 0` `q \<noteq> 0` show ?thesis |
305 with \<open>p \<noteq> 0\<close> \<open>q \<noteq> 0\<close> show ?thesis |
306 by (simp add: rsquarefree_def order_root) |
306 by (simp add: rsquarefree_def order_root) |
307 qed |
307 qed |
308 |
308 |
309 end |
309 end |