src/HOL/Library/Poly_Deriv.thy
changeset 60500 903bb1495239
parent 58881 b9556a055632
child 60688 01488b559910
equal deleted inserted replaced
60499:54a3db2ed201 60500:903bb1495239
     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