src/HOL/Library/Formal_Power_Series.thy
changeset 29913 89eadbe71e97
parent 29912 f4ac160d2e77
child 29914 c9ced4f54e82
equal deleted inserted replaced
29912:f4ac160d2e77 29913:89eadbe71e97
   101   unfolding fps_times_def by simp
   101   unfolding fps_times_def by simp
   102 
   102 
   103 declare atLeastAtMost_iff[presburger]
   103 declare atLeastAtMost_iff[presburger]
   104 declare Bex_def[presburger]
   104 declare Bex_def[presburger]
   105 declare Ball_def[presburger]
   105 declare Ball_def[presburger]
       
   106 
       
   107 lemma mult_delta_left:
       
   108   fixes x y :: "'a::mult_zero"
       
   109   shows "(if b then x else 0) * y = (if b then x * y else 0)"
       
   110   by simp
       
   111 
       
   112 lemma mult_delta_right:
       
   113   fixes x y :: "'a::mult_zero"
       
   114   shows "x * (if b then y else 0) = (if b then x * y else 0)"
       
   115   by simp
   106 
   116 
   107 lemma cond_value_iff: "f (if b then x else y) = (if b then f x else f y)"
   117 lemma cond_value_iff: "f (if b then x else y) = (if b then f x else f y)"
   108   by auto
   118   by auto
   109 lemma cond_application_beta: "(if b then f else g) x = (if b then f x else g x)"
   119 lemma cond_application_beta: "(if b then f else g) x = (if b then f x else g x)"
   110   by auto
   120   by auto
   194 qed
   204 qed
   195 
   205 
   196 instance fps :: (semiring_1) monoid_mult
   206 instance fps :: (semiring_1) monoid_mult
   197 proof
   207 proof
   198   fix a :: "'a fps" show "1 * a = a"
   208   fix a :: "'a fps" show "1 * a = a"
   199     apply (rule fps_ext)
   209     by (simp add: fps_ext fps_mult_nth mult_delta_left setsum_delta)
   200     apply (simp add: fps_mult_nth)
       
   201     by (simp add: cond_value_iff cond_application_beta setsum_delta cong del: if_weak_cong)
       
   202 next
   210 next
   203   fix a :: "'a fps" show "a * 1 = a"
   211   fix a :: "'a fps" show "a * 1 = a"
   204     apply (rule fps_ext)
   212     by (simp add: fps_ext fps_mult_nth mult_delta_right setsum_delta')
   205     apply (simp add: fps_mult_nth)
       
   206     by (simp add: cond_value_iff cond_application_beta setsum_delta' cong del: if_weak_cong)
       
   207 qed
   213 qed
   208 
   214 
   209 instance fps :: (cancel_semigroup_add) cancel_semigroup_add
   215 instance fps :: (cancel_semigroup_add) cancel_semigroup_add
   210 proof
   216 proof
   211   fix a b c :: "'a fps"
   217   fix a b c :: "'a fps"
   334 lemma fps_const_add_right: "f + fps_const (c::'a\<Colon>monoid_add) = Abs_fps (\<lambda>n. if n = 0 then f$0 + c else f$n)"
   340 lemma fps_const_add_right: "f + fps_const (c::'a\<Colon>monoid_add) = Abs_fps (\<lambda>n. if n = 0 then f$0 + c else f$n)"
   335   by (simp add: fps_ext)
   341   by (simp add: fps_ext)
   336 
   342 
   337 lemma fps_const_mult_left: "fps_const (c::'a\<Colon>semiring_0) * f = Abs_fps (\<lambda>n. c * f$n)"
   343 lemma fps_const_mult_left: "fps_const (c::'a\<Colon>semiring_0) * f = Abs_fps (\<lambda>n. c * f$n)"
   338   unfolding fps_eq_iff fps_mult_nth
   344   unfolding fps_eq_iff fps_mult_nth
   339   by (simp add: fps_const_def cond_application_beta cond_value_iff setsum_delta cong del: if_weak_cong)
   345   by (simp add: fps_const_def mult_delta_left setsum_delta)
   340 
   346 
   341 lemma fps_const_mult_right: "f * fps_const (c::'a\<Colon>semiring_0) = Abs_fps (\<lambda>n. f$n * c)"
   347 lemma fps_const_mult_right: "f * fps_const (c::'a\<Colon>semiring_0) = Abs_fps (\<lambda>n. f$n * c)"
   342   unfolding fps_eq_iff fps_mult_nth
   348   unfolding fps_eq_iff fps_mult_nth
   343   by (simp add: fps_const_def cond_application_beta cond_value_iff setsum_delta' cong del: if_weak_cong)
   349   by (simp add: fps_const_def mult_delta_right setsum_delta')
   344 
   350 
   345 lemma fps_mult_left_const_nth [simp]: "(fps_const (c::'a::semiring_1) * f)$n = c* f$n"
   351 lemma fps_mult_left_const_nth [simp]: "(fps_const (c::'a::semiring_1) * f)$n = c* f$n"
   346   by (simp add: fps_mult_nth cond_application_beta cond_value_iff setsum_delta cong del: if_weak_cong)
   352   by (simp add: fps_mult_nth mult_delta_left setsum_delta)
   347 
   353 
   348 lemma fps_mult_right_const_nth [simp]: "(f * fps_const (c::'a::semiring_1))$n = f$n * c"
   354 lemma fps_mult_right_const_nth [simp]: "(f * fps_const (c::'a::semiring_1))$n = f$n * c"
   349   by (simp add: fps_mult_nth cond_application_beta cond_value_iff setsum_delta' cong del: if_weak_cong)
   355   by (simp add: fps_mult_nth mult_delta_right setsum_delta')
   350 
   356 
   351 subsection {* Formal power series form an integral domain*}
   357 subsection {* Formal power series form an integral domain*}
   352 
   358 
   353 instance fps :: (ring) ring ..
   359 instance fps :: (ring) ring ..
   354 
   360 
   894 lemma X_mult_nth[simp]: "(X * (f :: ('a::semiring_1) fps)) $n = (if n = 0 then 0 else f $ (n - 1))"
   900 lemma X_mult_nth[simp]: "(X * (f :: ('a::semiring_1) fps)) $n = (if n = 0 then 0 else f $ (n - 1))"
   895 proof-
   901 proof-
   896   {assume n: "n \<noteq> 0"
   902   {assume n: "n \<noteq> 0"
   897     have fN: "finite {0 .. n}" by simp
   903     have fN: "finite {0 .. n}" by simp
   898     have "(X * f) $n = (\<Sum>i = 0..n. X $ i * f $ (n - i))" by (simp add: fps_mult_nth)
   904     have "(X * f) $n = (\<Sum>i = 0..n. X $ i * f $ (n - i))" by (simp add: fps_mult_nth)
   899     also have "\<dots> = f $ (n - 1)" 
   905     also have "\<dots> = f $ (n - 1)"
   900       using n by (simp add: X_def cond_value_iff cond_application_beta setsum_delta[OF fN] 
   906       using n by (simp add: X_def mult_delta_left setsum_delta [OF fN])
   901 	del: One_nat_def cong del:  if_weak_cong)
       
   902   finally have ?thesis using n by simp }
   907   finally have ?thesis using n by simp }
   903   moreover
   908   moreover
   904   {assume n: "n=0" hence ?thesis by (simp add: fps_mult_nth X_def)}
   909   {assume n: "n=0" hence ?thesis by (simp add: fps_mult_nth X_def)}
   905   ultimately show ?thesis by blast
   910   ultimately show ?thesis by blast
   906 qed
   911 qed
   969   fps_compose_def: "a oo b = Abs_fps (\<lambda>n. setsum (\<lambda>i. a$i * (b^i$n)) {0..n})"
   974   fps_compose_def: "a oo b = Abs_fps (\<lambda>n. setsum (\<lambda>i. a$i * (b^i$n)) {0..n})"
   970 
   975 
   971 lemma fps_compose_nth: "(a oo b)$n = setsum (\<lambda>i. a$i * (b^i$n)) {0..n}" by (simp add: fps_compose_def)
   976 lemma fps_compose_nth: "(a oo b)$n = setsum (\<lambda>i. a$i * (b^i$n)) {0..n}" by (simp add: fps_compose_def)
   972 
   977 
   973 lemma fps_compose_X[simp]: "a oo X = (a :: ('a :: comm_ring_1) fps)"
   978 lemma fps_compose_X[simp]: "a oo X = (a :: ('a :: comm_ring_1) fps)"
   974   by (auto simp add: fps_compose_def X_power_iff fps_eq_iff cond_application_beta cond_value_iff setsum_delta' cong del: if_weak_cong)
   979   by (simp add: fps_ext fps_compose_def mult_delta_right setsum_delta')
   975  
   980  
   976 lemma fps_const_compose[simp]: 
   981 lemma fps_const_compose[simp]: 
   977   "fps_const (a::'a::{comm_ring_1}) oo b = fps_const (a)"
   982   "fps_const (a::'a::{comm_ring_1}) oo b = fps_const (a)"
   978   apply (auto simp add: fps_eq_iff fps_compose_nth fps_mult_nth
   983   by (simp add: fps_eq_iff fps_compose_nth mult_delta_left setsum_delta)
   979   cond_application_beta cond_value_iff cong del: if_weak_cong)
       
   980   by (simp add: setsum_delta )
       
   981 
   984 
   982 lemma X_fps_compose_startby0[simp]: "a$0 = 0 \<Longrightarrow> X oo a = (a :: ('a :: comm_ring_1) fps)"
   985 lemma X_fps_compose_startby0[simp]: "a$0 = 0 \<Longrightarrow> X oo a = (a :: ('a :: comm_ring_1) fps)"
   983   apply (auto simp add: fps_compose_def fps_eq_iff cond_application_beta cond_value_iff setsum_delta cong del: if_weak_cong)
   986   by (simp add: fps_eq_iff fps_compose_def mult_delta_left setsum_delta
   984   apply (simp add: power_Suc)
   987                 power_Suc not_le)
   985   apply (subgoal_tac "n = 0")
       
   986   by simp_all
       
   987 
   988 
   988 
   989 
   989 subsection {* Rules from Herbert Wilf's Generatingfunctionology*}
   990 subsection {* Rules from Herbert Wilf's Generatingfunctionology*}
   990 
   991 
   991 subsubsection {* Rule 1 *}
   992 subsubsection {* Rule 1 *}
  1783     unfolding fps_mult_left_const_nth  by (simp add: ring_simps)
  1784     unfolding fps_mult_left_const_nth  by (simp add: ring_simps)
  1784   also have "\<dots> = setsum (\<lambda>i. of_nat i * a$i * (setsum (\<lambda>j. (b^ (i - 1))$j * (fps_deriv b)$(n - j)) {0..n})) {0.. Suc n}"
  1785   also have "\<dots> = setsum (\<lambda>i. of_nat i * a$i * (setsum (\<lambda>j. (b^ (i - 1))$j * (fps_deriv b)$(n - j)) {0..n})) {0.. Suc n}"
  1785     unfolding fps_mult_nth ..
  1786     unfolding fps_mult_nth ..
  1786   also have "\<dots> = setsum (\<lambda>i. of_nat i * a$i * (setsum (\<lambda>j. (b^ (i - 1))$j * (fps_deriv b)$(n - j)) {0..n})) {1.. Suc n}"
  1787   also have "\<dots> = setsum (\<lambda>i. of_nat i * a$i * (setsum (\<lambda>j. (b^ (i - 1))$j * (fps_deriv b)$(n - j)) {0..n})) {1.. Suc n}"
  1787     apply (rule setsum_mono_zero_right)
  1788     apply (rule setsum_mono_zero_right)
  1788     by (auto simp add: cond_value_iff cond_application_beta setsum_delta 
  1789     apply (auto simp add: mult_delta_left setsum_delta not_le)
  1789       not_le cong del: if_weak_cong)
  1790     done
  1790   also have "\<dots> = setsum (\<lambda>i. of_nat (i + 1) * a$(i+1) * (setsum (\<lambda>j. (b^ i)$j * of_nat (n - j + 1) * b$(n - j + 1)) {0..n})) {0.. n}"
  1791   also have "\<dots> = setsum (\<lambda>i. of_nat (i + 1) * a$(i+1) * (setsum (\<lambda>j. (b^ i)$j * of_nat (n - j + 1) * b$(n - j + 1)) {0..n})) {0.. n}"
  1791     unfolding fps_deriv_nth
  1792     unfolding fps_deriv_nth
  1792     apply (rule setsum_reindex_cong[where f="Suc"])
  1793     apply (rule setsum_reindex_cong[where f="Suc"])
  1793     by (auto simp add: mult_assoc)
  1794     by (auto simp add: mult_assoc)
  1794   finally have th0: "(fps_deriv (a oo b))$n = setsum (\<lambda>i. of_nat (i + 1) * a$(i+1) * (setsum (\<lambda>j. (b^ i)$j * of_nat (n - j + 1) * b$(n - j + 1)) {0..n})) {0.. n}" .
  1795   finally have th0: "(fps_deriv (a oo b))$n = setsum (\<lambda>i. of_nat (i + 1) * a$(i+1) * (setsum (\<lambda>j. (b^ i)$j * of_nat (n - j + 1) * b$(n - j + 1)) {0..n})) {0.. n}" .
  1839   shows "a = setsum (\<lambda>i. fps_const (a$i) * X^i) {0..n}" (is "a = ?r")
  1840   shows "a = setsum (\<lambda>i. fps_const (a$i) * X^i) {0..n}" (is "a = ?r")
  1840 proof-
  1841 proof-
  1841   {fix i
  1842   {fix i
  1842     have "a$i = ?r$i" 
  1843     have "a$i = ?r$i" 
  1843       unfolding fps_setsum_nth fps_mult_left_const_nth X_power_nth
  1844       unfolding fps_setsum_nth fps_mult_left_const_nth X_power_nth
  1844       apply (simp add: cond_application_beta cond_value_iff setsum_delta' cong del: if_weak_cong)
  1845       by (simp add: mult_delta_right setsum_delta' z)
  1845       using z by auto}
  1846   }
  1846   then show ?thesis unfolding fps_eq_iff by blast
  1847   then show ?thesis unfolding fps_eq_iff by blast
  1847 qed
  1848 qed
  1848 
  1849 
  1849 subsection{* Compositional inverses *}
  1850 subsection{* Compositional inverses *}
  1850 
  1851 
  1915   apply simp
  1916   apply simp
  1916   apply simp
  1917   apply simp
  1917   done
  1918   done
  1918 
  1919 
  1919 lemma fps_compose_1[simp]: "1 oo a = 1"
  1920 lemma fps_compose_1[simp]: "1 oo a = 1"
  1920   apply (auto simp add: fps_eq_iff fps_compose_nth fps_power_def cond_value_iff cond_application_beta cong del: if_weak_cong)
  1921   by (simp add: fps_eq_iff fps_compose_nth fps_power_def mult_delta_left setsum_delta)
  1921   apply (simp add: setsum_delta)
       
  1922   done
       
  1923 
  1922 
  1924 lemma fps_compose_0[simp]: "0 oo a = 0"
  1923 lemma fps_compose_0[simp]: "0 oo a = 0"
  1925   by (auto simp add: fps_eq_iff fps_compose_nth fps_power_def cond_value_iff cond_application_beta cong del: if_weak_cong)
  1924   by (simp add: fps_eq_iff fps_compose_nth)
  1926 
  1925 
  1927 lemma fps_pow_0: "fps_pow n 0 = (if n = 0 then 1 else 0)"
  1926 lemma fps_pow_0: "fps_pow n 0 = (if n = 0 then 1 else 0)"
  1928   by (induct n, simp_all)
  1927   by (induct n, simp_all)
  1929 
  1928 
  1930 lemma fps_compose_0_right[simp]: "a oo 0 = fps_const (a$0)"
  1929 lemma fps_compose_0_right[simp]: "a oo 0 = fps_const (a$0)"
  1931   apply (auto simp add: fps_eq_iff fps_compose_nth fps_power_def cond_value_iff cond_application_beta cong del: if_weak_cong)
  1930   by (auto simp add: fps_eq_iff fps_compose_nth fps_power_def fps_pow_0 setsum_0')
  1932   by (case_tac n, auto simp add: fps_pow_0 intro: setsum_0')
       
  1933 
  1931 
  1934 lemma fps_compose_add_distrib: "(a + b) oo c = (a oo c) + (b oo c)"
  1932 lemma fps_compose_add_distrib: "(a + b) oo c = (a oo c) + (b oo c)"
  1935   by (simp add: fps_eq_iff fps_compose_nth  ring_simps setsum_addf)
  1933   by (simp add: fps_eq_iff fps_compose_nth  ring_simps setsum_addf)
  1936 
  1934 
  1937 lemma fps_compose_setsum_distrib: "(setsum f S) oo a = setsum (\<lambda>i. f i oo a) S"
  1935 lemma fps_compose_setsum_distrib: "(setsum f S) oo a = setsum (\<lambda>i. f i oo a) S"
  2110     {fix n
  2108     {fix n
  2111       {assume kn: "k>n" hence "?l $ n = ?r $n" using a0 startsby_zero_power_prefix[OF a0] h 
  2109       {assume kn: "k>n" hence "?l $ n = ?r $n" using a0 startsby_zero_power_prefix[OF a0] h 
  2112 	  by (simp add: fps_compose_nth)}
  2110 	  by (simp add: fps_compose_nth)}
  2113       moreover
  2111       moreover
  2114       {assume kn: "k \<le> n"
  2112       {assume kn: "k \<le> n"
  2115 	hence "?l$n = ?r$n" apply (simp only: fps_compose_nth X_power_nth)
  2113 	hence "?l$n = ?r$n"
  2116 	  by (simp add: cond_value_iff cond_application_beta setsum_delta cong del: if_weak_cong)}
  2114           by (simp add: fps_compose_nth mult_delta_left setsum_delta)}
  2117       moreover have "k >n \<or> k\<le> n"  by arith
  2115       moreover have "k >n \<or> k\<le> n"  by arith
  2118       ultimately have "?l$n = ?r$n"  by blast}
  2116       ultimately have "?l$n = ?r$n"  by blast}
  2119     then have ?thesis unfolding fps_eq_iff by blast}
  2117     then have ?thesis unfolding fps_eq_iff by blast}
  2120   ultimately show ?thesis by (cases k, auto)
  2118   ultimately show ?thesis by (cases k, auto)
  2121 qed
  2119 qed
  2226 lemma fps_compose_sub_distrib: 
  2224 lemma fps_compose_sub_distrib: 
  2227   shows "(a - b) oo (c::'a::ring_1 fps) = (a oo c) - (b oo c)"
  2225   shows "(a - b) oo (c::'a::ring_1 fps) = (a oo c) - (b oo c)"
  2228   unfolding diff_minus fps_compose_uminus fps_compose_add_distrib ..
  2226   unfolding diff_minus fps_compose_uminus fps_compose_add_distrib ..
  2229 
  2227 
  2230 lemma X_fps_compose:"X oo a = Abs_fps (\<lambda>n. if n = 0 then (0::'a::comm_ring_1) else a$n)"
  2228 lemma X_fps_compose:"X oo a = Abs_fps (\<lambda>n. if n = 0 then (0::'a::comm_ring_1) else a$n)"
  2231   apply (simp add: fps_eq_iff fps_compose_nth)
  2229   by (simp add: fps_eq_iff fps_compose_nth mult_delta_left setsum_delta power_Suc)
  2232   by (simp add: cond_value_iff cond_application_beta setsum_delta power_Suc cong del: if_weak_cong)
       
  2233 
  2230 
  2234 lemma X_compose_E[simp]: "X oo E (a::'a::{field, recpower}) = E a - 1"
  2231 lemma X_compose_E[simp]: "X oo E (a::'a::{field, recpower}) = E a - 1"
  2235   by (simp add: fps_eq_iff X_fps_compose)
  2232   by (simp add: fps_eq_iff X_fps_compose)
  2236 
  2233 
  2237 lemma LE_compose: 
  2234 lemma LE_compose: