src/HOL/Library/Polynomial.thy
changeset 64267 b9a1486e79be
parent 63950 cdc1e59aa513
child 64272 f76b6dda2e56
equal deleted inserted replaced
64265:8eb6365f5916 64267:b9a1486e79be
   505       let ?p' = "pCons a p"
   505       let ?p' = "pCons a p"
   506       note poly_pCons[of a p x]
   506       note poly_pCons[of a p x]
   507       also note pCons.IH
   507       also note pCons.IH
   508       also have "a + x * (\<Sum>i\<le>degree p. coeff p i * x ^ i) =
   508       also have "a + x * (\<Sum>i\<le>degree p. coeff p i * x ^ i) =
   509                  coeff ?p' 0 * x^0 + (\<Sum>i\<le>degree p. coeff ?p' (Suc i) * x^Suc i)"
   509                  coeff ?p' 0 * x^0 + (\<Sum>i\<le>degree p. coeff ?p' (Suc i) * x^Suc i)"
   510           by (simp add: field_simps setsum_distrib_left coeff_pCons)
   510           by (simp add: field_simps sum_distrib_left coeff_pCons)
   511       also note setsum_atMost_Suc_shift[symmetric]
   511       also note sum_atMost_Suc_shift[symmetric]
   512       also note degree_pCons_eq[OF \<open>p \<noteq> 0\<close>, of a, symmetric]
   512       also note degree_pCons_eq[OF \<open>p \<noteq> 0\<close>, of a, symmetric]
   513       finally show ?thesis .
   513       finally show ?thesis .
   514    qed simp
   514    qed simp
   515 qed simp
   515 qed simp
   516 
   516 
   719   by (rule poly_eqI) simp
   719   by (rule poly_eqI) simp
   720 
   720 
   721 lemma minus_monom: "- monom a n = monom (-a) n"
   721 lemma minus_monom: "- monom a n = monom (-a) n"
   722   by (rule poly_eqI) simp
   722   by (rule poly_eqI) simp
   723 
   723 
   724 lemma coeff_setsum: "coeff (\<Sum>x\<in>A. p x) i = (\<Sum>x\<in>A. coeff (p x) i)"
   724 lemma coeff_sum: "coeff (\<Sum>x\<in>A. p x) i = (\<Sum>x\<in>A. coeff (p x) i)"
   725   by (cases "finite A", induct set: finite, simp_all)
   725   by (cases "finite A", induct set: finite, simp_all)
   726 
   726 
   727 lemma monom_setsum: "monom (\<Sum>x\<in>A. a x) n = (\<Sum>x\<in>A. monom (a x) n)"
   727 lemma monom_sum: "monom (\<Sum>x\<in>A. a x) n = (\<Sum>x\<in>A. monom (a x) n)"
   728   by (rule poly_eqI) (simp add: coeff_setsum)
   728   by (rule poly_eqI) (simp add: coeff_sum)
   729 
   729 
   730 fun plus_coeffs :: "'a::comm_monoid_add list \<Rightarrow> 'a list \<Rightarrow> 'a list"
   730 fun plus_coeffs :: "'a::comm_monoid_add list \<Rightarrow> 'a list \<Rightarrow> 'a list"
   731 where
   731 where
   732   "plus_coeffs xs [] = xs"
   732   "plus_coeffs xs [] = xs"
   733 | "plus_coeffs [] ys = ys"
   733 | "plus_coeffs [] ys = ys"
   782 lemma poly_diff [simp]:
   782 lemma poly_diff [simp]:
   783   fixes x :: "'a::comm_ring"
   783   fixes x :: "'a::comm_ring"
   784   shows "poly (p - q) x = poly p x - poly q x"
   784   shows "poly (p - q) x = poly p x - poly q x"
   785   using poly_add [of p "- q" x] by simp
   785   using poly_add [of p "- q" x] by simp
   786 
   786 
   787 lemma poly_setsum: "poly (\<Sum>k\<in>A. p k) x = (\<Sum>k\<in>A. poly (p k) x)"
   787 lemma poly_sum: "poly (\<Sum>k\<in>A. p k) x = (\<Sum>k\<in>A. poly (p k) x)"
   788   by (induct A rule: infinite_finite_induct) simp_all
   788   by (induct A rule: infinite_finite_induct) simp_all
   789 
   789 
   790 lemma degree_setsum_le: "finite S \<Longrightarrow> (\<And> p . p \<in> S \<Longrightarrow> degree (f p) \<le> n)
   790 lemma degree_sum_le: "finite S \<Longrightarrow> (\<And> p . p \<in> S \<Longrightarrow> degree (f p) \<le> n)
   791   \<Longrightarrow> degree (setsum f S) \<le> n"
   791   \<Longrightarrow> degree (sum f S) \<le> n"
   792 proof (induct S rule: finite_induct)
   792 proof (induct S rule: finite_induct)
   793   case (insert p S)
   793   case (insert p S)
   794   hence "degree (setsum f S) \<le> n" "degree (f p) \<le> n" by auto
   794   hence "degree (sum f S) \<le> n" "degree (f p) \<le> n" by auto
   795   thus ?case unfolding setsum.insert[OF insert(1-2)] by (metis degree_add_le)
   795   thus ?case unfolding sum.insert[OF insert(1-2)] by (metis degree_add_le)
   796 qed simp
   796 qed simp
   797 
   797 
   798 lemma poly_as_sum_of_monoms': 
   798 lemma poly_as_sum_of_monoms': 
   799   assumes n: "degree p \<le> n" 
   799   assumes n: "degree p \<le> n" 
   800   shows "(\<Sum>i\<le>n. monom (coeff p i) i) = p"
   800   shows "(\<Sum>i\<le>n. monom (coeff p i) i) = p"
   801 proof -
   801 proof -
   802   have eq: "\<And>i. {..n} \<inter> {i} = (if i \<le> n then {i} else {})"
   802   have eq: "\<And>i. {..n} \<inter> {i} = (if i \<le> n then {i} else {})"
   803     by auto
   803     by auto
   804   show ?thesis
   804   show ?thesis
   805     using n by (simp add: poly_eq_iff coeff_setsum coeff_eq_0 setsum.If_cases eq 
   805     using n by (simp add: poly_eq_iff coeff_sum coeff_eq_0 sum.If_cases eq 
   806                   if_distrib[where f="\<lambda>x. x * a" for a])
   806                   if_distrib[where f="\<lambda>x. x * a" for a])
   807 qed
   807 qed
   808 
   808 
   809 lemma poly_as_sum_of_monoms: "(\<Sum>i\<le>degree p. monom (coeff p i) i) = p"
   809 lemma poly_as_sum_of_monoms: "(\<Sum>i\<le>degree p. monom (coeff p i) i) = p"
   810   by (intro poly_as_sum_of_monoms' order_refl)
   810   by (intro poly_as_sum_of_monoms' order_refl)
   971   "coeff (p * q) n = (\<Sum>i\<le>n. coeff p i * coeff q (n-i))"
   971   "coeff (p * q) n = (\<Sum>i\<le>n. coeff p i * coeff q (n-i))"
   972 proof (induct p arbitrary: n)
   972 proof (induct p arbitrary: n)
   973   case 0 show ?case by simp
   973   case 0 show ?case by simp
   974 next
   974 next
   975   case (pCons a p n) thus ?case
   975   case (pCons a p n) thus ?case
   976     by (cases n, simp, simp add: setsum_atMost_Suc_shift
   976     by (cases n, simp, simp add: sum_atMost_Suc_shift
   977                             del: setsum_atMost_Suc)
   977                             del: sum_atMost_Suc)
   978 qed
   978 qed
   979 
   979 
   980 lemma degree_mult_le: "degree (p * q) \<le> degree p + degree q"
   980 lemma degree_mult_le: "degree (p * q) \<le> degree p + degree q"
   981 apply (rule degree_le)
   981 apply (rule degree_le)
   982 apply (induct p)
   982 apply (induct p)
  1055   by (induct n) simp_all
  1055   by (induct n) simp_all
  1056 
  1056 
  1057 lemma poly_setprod: "poly (\<Prod>k\<in>A. p k) x = (\<Prod>k\<in>A. poly (p k) x)"
  1057 lemma poly_setprod: "poly (\<Prod>k\<in>A. p k) x = (\<Prod>k\<in>A. poly (p k) x)"
  1058   by (induct A rule: infinite_finite_induct) simp_all
  1058   by (induct A rule: infinite_finite_induct) simp_all
  1059 
  1059 
  1060 lemma degree_setprod_setsum_le: "finite S \<Longrightarrow> degree (setprod f S) \<le> setsum (degree o f) S"
  1060 lemma degree_setprod_sum_le: "finite S \<Longrightarrow> degree (setprod f S) \<le> sum (degree o f) S"
  1061 proof (induct S rule: finite_induct)
  1061 proof (induct S rule: finite_induct)
  1062   case (insert a S)
  1062   case (insert a S)
  1063   show ?case unfolding setprod.insert[OF insert(1-2)] setsum.insert[OF insert(1-2)]
  1063   show ?case unfolding setprod.insert[OF insert(1-2)] sum.insert[OF insert(1-2)]
  1064     by (rule le_trans[OF degree_mult_le], insert insert, auto)
  1064     by (rule le_trans[OF degree_mult_le], insert insert, auto)
  1065 qed simp
  1065 qed simp
  1066 
  1066 
  1067 subsection \<open>Conversions from natural numbers\<close>
  1067 subsection \<open>Conversions from natural numbers\<close>
  1068 
  1068 
  2850 lemma pcompose_idR[simp]:
  2850 lemma pcompose_idR[simp]:
  2851   fixes p :: "'a :: comm_semiring_1 poly"
  2851   fixes p :: "'a :: comm_semiring_1 poly"
  2852   shows "pcompose p [: 0, 1 :] = p"
  2852   shows "pcompose p [: 0, 1 :] = p"
  2853   by (induct p; simp add: pcompose_pCons)
  2853   by (induct p; simp add: pcompose_pCons)
  2854 
  2854 
  2855 lemma pcompose_setsum: "pcompose (setsum f A) p = setsum (\<lambda>i. pcompose (f i) p) A"
  2855 lemma pcompose_sum: "pcompose (sum f A) p = sum (\<lambda>i. pcompose (f i) p) A"
  2856   by (cases "finite A", induction rule: finite_induct)
  2856   by (cases "finite A", induction rule: finite_induct)
  2857      (simp_all add: pcompose_1 pcompose_add)
  2857      (simp_all add: pcompose_1 pcompose_add)
  2858 
  2858 
  2859 lemma pcompose_setprod: "pcompose (setprod f A) p = setprod (\<lambda>i. pcompose (f i) p) A"
  2859 lemma pcompose_setprod: "pcompose (setprod f A) p = setprod (\<lambda>i. pcompose (f i) p) A"
  2860   by (cases "finite A", induction rule: finite_induct)
  2860   by (cases "finite A", induction rule: finite_induct)
  3183       from True have "coeff (reflect_poly (p * q)) i = coeff (p * q) (degree (p * q) - i)"
  3183       from True have "coeff (reflect_poly (p * q)) i = coeff (p * q) (degree (p * q) - i)"
  3184         by (simp add: coeff_reflect_poly)
  3184         by (simp add: coeff_reflect_poly)
  3185       also have "\<dots> = (\<Sum>j\<le>degree (p * q) - i. coeff p j * coeff q (degree (p * q) - i - j))"
  3185       also have "\<dots> = (\<Sum>j\<le>degree (p * q) - i. coeff p j * coeff q (degree (p * q) - i - j))"
  3186         unfolding coeff_mult by simp
  3186         unfolding coeff_mult by simp
  3187       also have "\<dots> = (\<Sum>j\<in>B. coeff p j * coeff q (degree (p * q) - i - j))"
  3187       also have "\<dots> = (\<Sum>j\<in>B. coeff p j * coeff q (degree (p * q) - i - j))"
  3188         by (intro setsum.mono_neutral_right) (auto simp: B_def degree_mult_eq not_le coeff_eq_0)
  3188         by (intro sum.mono_neutral_right) (auto simp: B_def degree_mult_eq not_le coeff_eq_0)
  3189       also from True have "\<dots> = (\<Sum>j\<in>A. coeff p (degree p - j) * coeff q (degree q - (i - j)))"
  3189       also from True have "\<dots> = (\<Sum>j\<in>A. coeff p (degree p - j) * coeff q (degree q - (i - j)))"
  3190         by (intro setsum.reindex_bij_witness[of _ ?f ?f])
  3190         by (intro sum.reindex_bij_witness[of _ ?f ?f])
  3191            (auto simp: A_def B_def degree_mult_eq add_ac)
  3191            (auto simp: A_def B_def degree_mult_eq add_ac)
  3192       also have "\<dots> = (\<Sum>j\<le>i. if j \<in> {i - degree q..degree p} then
  3192       also have "\<dots> = (\<Sum>j\<le>i. if j \<in> {i - degree q..degree p} then
  3193                  coeff p (degree p - j) * coeff q (degree q - (i - j)) else 0)"
  3193                  coeff p (degree p - j) * coeff q (degree q - (i - j)) else 0)"
  3194         by (subst setsum.inter_restrict [symmetric]) (simp_all add: A_def)
  3194         by (subst sum.inter_restrict [symmetric]) (simp_all add: A_def)
  3195        also have "\<dots> = coeff (reflect_poly p * reflect_poly q) i"
  3195        also have "\<dots> = coeff (reflect_poly p * reflect_poly q) i"
  3196           by (fastforce simp: coeff_mult coeff_reflect_poly intro!: setsum.cong)
  3196           by (fastforce simp: coeff_mult coeff_reflect_poly intro!: sum.cong)
  3197        finally show ?thesis .
  3197        finally show ?thesis .
  3198     qed (auto simp: coeff_mult coeff_reflect_poly coeff_eq_0 degree_mult_eq intro!: setsum.neutral)
  3198     qed (auto simp: coeff_mult coeff_reflect_poly coeff_eq_0 degree_mult_eq intro!: sum.neutral)
  3199   qed
  3199   qed
  3200 qed auto
  3200 qed auto
  3201 
  3201 
  3202 lemma reflect_poly_smult: 
  3202 lemma reflect_poly_smult: 
  3203   "reflect_poly (Polynomial.smult (c::'a::{comm_semiring_0,semiring_no_zero_divisors}) p) = 
  3203   "reflect_poly (Polynomial.smult (c::'a::{comm_semiring_0,semiring_no_zero_divisors}) p) = 
  3398 lemma pderiv_setprod: "pderiv (setprod f (as)) = 
  3398 lemma pderiv_setprod: "pderiv (setprod f (as)) = 
  3399   (\<Sum>a \<in> as. setprod f (as - {a}) * pderiv (f a))"
  3399   (\<Sum>a \<in> as. setprod f (as - {a}) * pderiv (f a))"
  3400 proof (induct as rule: infinite_finite_induct)
  3400 proof (induct as rule: infinite_finite_induct)
  3401   case (insert a as)
  3401   case (insert a as)
  3402   hence id: "setprod f (insert a as) = f a * setprod f as" 
  3402   hence id: "setprod f (insert a as) = f a * setprod f as" 
  3403     "\<And> g. setsum g (insert a as) = g a + setsum g as"
  3403     "\<And> g. sum g (insert a as) = g a + sum g as"
  3404     "insert a as - {a} = as"
  3404     "insert a as - {a} = as"
  3405     by auto
  3405     by auto
  3406   {
  3406   {
  3407     fix b
  3407     fix b
  3408     assume "b \<in> as"
  3408     assume "b \<in> as"
  3410     have "setprod f (insert a as - {b}) = f a * setprod f (as - {b})"
  3410     have "setprod f (insert a as - {b}) = f a * setprod f (as - {b})"
  3411       unfolding id2
  3411       unfolding id2
  3412       by (subst setprod.insert, insert insert, auto)
  3412       by (subst setprod.insert, insert insert, auto)
  3413   } note id2 = this
  3413   } note id2 = this
  3414   show ?case
  3414   show ?case
  3415     unfolding id pderiv_mult insert(3) setsum_distrib_left
  3415     unfolding id pderiv_mult insert(3) sum_distrib_left
  3416     by (auto simp add: ac_simps id2 intro!: setsum.cong)
  3416     by (auto simp add: ac_simps id2 intro!: sum.cong)
  3417 qed auto
  3417 qed auto
  3418 
  3418 
  3419 lemma DERIV_pow2: "DERIV (%x. x ^ Suc n) x :> real (Suc n) * (x ^ n)"
  3419 lemma DERIV_pow2: "DERIV (%x. x ^ Suc n) x :> real (Suc n) * (x ^ n)"
  3420 by (rule DERIV_cong, rule DERIV_pow, simp)
  3420 by (rule DERIV_cong, rule DERIV_pow, simp)
  3421 declare DERIV_pow2 [simp] DERIV_pow [simp]
  3421 declare DERIV_pow2 [simp] DERIV_pow [simp]
  3875   "coeff (monom c n * p) k = (if k < n then 0 else c * coeff p (k - n))"
  3875   "coeff (monom c n * p) k = (if k < n then 0 else c * coeff p (k - n))"
  3876 proof -
  3876 proof -
  3877   have "coeff (monom c n * p) k = (\<Sum>i\<le>k. (if n = i then c else 0) * coeff p (k - i))"
  3877   have "coeff (monom c n * p) k = (\<Sum>i\<le>k. (if n = i then c else 0) * coeff p (k - i))"
  3878     by (simp add: coeff_mult)
  3878     by (simp add: coeff_mult)
  3879   also have "\<dots> = (\<Sum>i\<le>k. (if n = i then c * coeff p (k - i) else 0))"
  3879   also have "\<dots> = (\<Sum>i\<le>k. (if n = i then c * coeff p (k - i) else 0))"
  3880     by (intro setsum.cong) simp_all
  3880     by (intro sum.cong) simp_all
  3881   also have "\<dots> = (if k < n then 0 else c * coeff p (k - n))" by (simp add: setsum.delta')
  3881   also have "\<dots> = (if k < n then 0 else c * coeff p (k - n))" by (simp add: sum.delta')
  3882   finally show ?thesis .
  3882   finally show ?thesis .
  3883 qed
  3883 qed
  3884 
  3884 
  3885 lemma monom_1_dvd_iff':
  3885 lemma monom_1_dvd_iff':
  3886   "monom 1 n dvd p \<longleftrightarrow> (\<forall>k<n. coeff p k = 0)"
  3886   "monom 1 n dvd p \<longleftrightarrow> (\<forall>k<n. coeff p k = 0)"