src/HOL/Library/Formal_Power_Series.thy
changeset 63317 ca187a9f66da
parent 63040 eb4ddd18d635
child 63367 6c731c8b7f03
equal deleted inserted replaced
63305:3b6975875633 63317:ca187a9f66da
   245 
   245 
   246 instance fps :: (semiring_1) semiring_1 ..
   246 instance fps :: (semiring_1) semiring_1 ..
   247 
   247 
   248 
   248 
   249 subsection \<open>Selection of the nth power of the implicit variable in the infinite sum\<close>
   249 subsection \<open>Selection of the nth power of the implicit variable in the infinite sum\<close>
       
   250 
       
   251 lemma fps_square_nth: "(f^2) $ n = (\<Sum>k\<le>n. f $ k * f $ (n - k))"
       
   252   by (simp add: power2_eq_square fps_mult_nth atLeast0AtMost)
   250 
   253 
   251 lemma fps_nonzero_nth: "f \<noteq> 0 \<longleftrightarrow> (\<exists> n. f $n \<noteq> 0)"
   254 lemma fps_nonzero_nth: "f \<noteq> 0 \<longleftrightarrow> (\<exists> n. f $n \<noteq> 0)"
   252   by (simp add: expand_fps_eq)
   255   by (simp add: expand_fps_eq)
   253 
   256 
   254 lemma fps_nonzero_nth_minimal: "f \<noteq> 0 \<longleftrightarrow> (\<exists>n. f $ n \<noteq> 0 \<and> (\<forall>m < n. f $ m = 0))"
   257 lemma fps_nonzero_nth_minimal: "f \<noteq> 0 \<longleftrightarrow> (\<exists>n. f $ n \<noteq> 0 \<and> (\<forall>m < n. f $ m = 0))"
   385   by (simp add: numeral_fps_const)
   388   by (simp add: numeral_fps_const)
   386 
   389 
   387 lemma fps_numeral_nth_0 [simp]: "numeral n $ 0 = numeral n"
   390 lemma fps_numeral_nth_0 [simp]: "numeral n $ 0 = numeral n"
   388   by (simp add: numeral_fps_const)
   391   by (simp add: numeral_fps_const)
   389 
   392 
       
   393 lemma fps_of_nat: "fps_const (of_nat c) = of_nat c"
       
   394   by (induction c) (simp_all add: fps_const_add [symmetric] del: fps_const_add)
       
   395 
       
   396 
   390 
   397 
   391 subsection \<open>The eXtractor series X\<close>
   398 subsection \<open>The eXtractor series X\<close>
   392 
   399 
   393 lemma minus_one_power_iff: "(- (1::'a::comm_ring_1)) ^ n = (if even n then 1 else - 1)"
   400 lemma minus_one_power_iff: "(- (1::'a::comm_ring_1)) ^ n = (if even n then 1 else - 1)"
   394   by (induct n) auto
   401   by (induct n) auto
   410   then show ?thesis
   417   then show ?thesis
   411     by (simp add: fps_mult_nth X_def)
   418     by (simp add: fps_mult_nth X_def)
   412 qed
   419 qed
   413 
   420 
   414 lemma X_mult_right_nth[simp]:
   421 lemma X_mult_right_nth[simp]:
   415     "((f :: 'a::comm_semiring_1 fps) * X) $n = (if n = 0 then 0 else f $ (n - 1))"
   422   "((a::'a::semiring_1 fps) * X) $ n = (if n = 0 then 0 else a $ (n - 1))"
   416   by (metis X_mult_nth mult.commute)
   423 proof -
       
   424   have "(a * X) $ n = (\<Sum>i = 0..n. a $ i * (if n - i = Suc 0 then 1 else 0))"
       
   425     by (simp add: fps_times_def X_def)
       
   426   also have "\<dots> = (\<Sum>i = 0..n. if i = n - 1 then if n = 0 then 0 else a $ i else 0)"
       
   427     by (intro setsum.cong) auto
       
   428   also have "\<dots> = (if n = 0 then 0 else a $ (n - 1))" by (simp add: setsum.delta)
       
   429   finally show ?thesis .
       
   430 qed
       
   431 
       
   432 lemma fps_mult_X_commute: "X * (a :: 'a :: semiring_1 fps) = a * X" 
       
   433   by (simp add: fps_eq_iff)
   417 
   434 
   418 lemma X_power_iff: "X^k = Abs_fps (\<lambda>n. if n = k then 1::'a::comm_ring_1 else 0)"
   435 lemma X_power_iff: "X^k = Abs_fps (\<lambda>n. if n = k then 1::'a::comm_ring_1 else 0)"
   419 proof (induct k)
   436 proof (induct k)
   420   case 0
   437   case 0
   421   then show ?case by (simp add: X_def fps_eq_iff)
   438   then show ?case by (simp add: X_def fps_eq_iff)
  1055     using f0
  1072     using f0
  1056     unfolding mult_cancel_right
  1073     unfolding mult_cancel_right
  1057     by (auto simp add: expand_fps_eq)
  1074     by (auto simp add: expand_fps_eq)
  1058 qed
  1075 qed
  1059 
  1076 
       
  1077 lemma fps_inverse_eq_0: "f$0 = 0 \<Longrightarrow> inverse (f :: 'a :: division_ring fps) = 0"
       
  1078   by simp
       
  1079   
  1060 lemma setsum_zero_lemma:
  1080 lemma setsum_zero_lemma:
  1061   fixes n::nat
  1081   fixes n::nat
  1062   assumes "0 < n"
  1082   assumes "0 < n"
  1063   shows "(\<Sum>i = 0..n. if n = i then 1 else if n - i = 1 then - 1 else 0) = (0::'a::field)"
  1083   shows "(\<Sum>i = 0..n. if n = i then 1 else if n - i = 1 then - 1 else 0) = (0::'a::field)"
  1064 proof -
  1084 proof -
  1309   with assms have "g mod f = 0"
  1329   with assms have "g mod f = 0"
  1310     by (simp add: fps_mod_def Let_def fps_cutoff_zero_iff)
  1330     by (simp add: fps_mod_def Let_def fps_cutoff_zero_iff)
  1311   thus "f dvd g" by (simp add: dvd_eq_mod_eq_0)
  1331   thus "f dvd g" by (simp add: dvd_eq_mod_eq_0)
  1312 qed (simp add: assms dvd_imp_subdegree_le)
  1332 qed (simp add: assms dvd_imp_subdegree_le)
  1313 
  1333 
       
  1334 lemma fps_shift_altdef:
       
  1335   "fps_shift n f = (f :: 'a :: field fps) div X^n"
       
  1336   by (simp add: fps_divide_def)
       
  1337   
       
  1338 lemma fps_div_X_power_nth: "((f :: 'a :: field fps) div X^n) $ k = f $ (k + n)"
       
  1339   by (simp add: fps_shift_altdef [symmetric])
       
  1340 
       
  1341 lemma fps_div_X_nth: "((f :: 'a :: field fps) div X) $ k = f $ Suc k"
       
  1342   using fps_div_X_power_nth[of f 1] by simp
       
  1343 
  1314 lemma fps_const_inverse: "inverse (fps_const (a::'a::field)) = fps_const (inverse a)"
  1344 lemma fps_const_inverse: "inverse (fps_const (a::'a::field)) = fps_const (inverse a)"
  1315   by (cases "a \<noteq> 0", rule fps_inverse_unique) (auto simp: fps_eq_iff)
  1345   by (cases "a \<noteq> 0", rule fps_inverse_unique) (auto simp: fps_eq_iff)
  1316 
  1346 
  1317 lemma fps_const_divide: "fps_const (x :: _ :: field) / fps_const y = fps_const (x / y)"
  1347 lemma fps_const_divide: "fps_const (x :: _ :: field) / fps_const y = fps_const (x / y)"
  1318   by (cases "y = 0") (simp_all add: fps_divide_unit fps_const_inverse divide_inverse)
  1348   by (cases "y = 0") (simp_all add: fps_divide_unit fps_const_inverse divide_inverse)
  1319 
  1349 
  1320 lemma inverse_fps_numeral:
  1350 lemma inverse_fps_numeral:
  1321   "inverse (numeral n :: ('a :: field_char_0) fps) = fps_const (inverse (numeral n))"
  1351   "inverse (numeral n :: ('a :: field_char_0) fps) = fps_const (inverse (numeral n))"
  1322   by (intro fps_inverse_unique fps_ext) (simp_all add: fps_numeral_nth)
  1352   by (intro fps_inverse_unique fps_ext) (simp_all add: fps_numeral_nth)
  1323 
  1353 
       
  1354 lemma fps_numeral_divide_divide:
       
  1355   "x / numeral b / numeral c = (x / numeral (b * c) :: 'a :: field fps)"
       
  1356   by (cases "numeral b = (0::'a)"; cases "numeral c = (0::'a)")
       
  1357       (simp_all add: fps_divide_unit fps_inverse_mult [symmetric] numeral_fps_const numeral_mult 
       
  1358                 del: numeral_mult [symmetric])
       
  1359 
       
  1360 lemma fps_numeral_mult_divide:
       
  1361   "numeral b * x / numeral c = (numeral b / numeral c * x :: 'a :: field fps)"
       
  1362   by (cases "numeral c = (0::'a)") (simp_all add: fps_divide_unit numeral_fps_const)
       
  1363 
       
  1364 lemmas fps_numeral_simps = 
       
  1365   fps_numeral_divide_divide fps_numeral_mult_divide inverse_fps_numeral neg_numeral_fps_const
  1324 
  1366 
  1325 
  1367 
  1326 
  1368 
  1327 instantiation fps :: (field) normalization_semidom
  1369 instantiation fps :: (field) normalization_semidom
  1328 begin
  1370 begin
  1826 lemma inverse_mult_eq_1':
  1868 lemma inverse_mult_eq_1':
  1827   assumes f0: "f$0 \<noteq> (0::'a::field)"
  1869   assumes f0: "f$0 \<noteq> (0::'a::field)"
  1828   shows "f * inverse f = 1"
  1870   shows "f * inverse f = 1"
  1829   by (metis mult.commute inverse_mult_eq_1 f0)
  1871   by (metis mult.commute inverse_mult_eq_1 f0)
  1830 
  1872 
       
  1873 lemma fps_inverse_minus [simp]: "inverse (-f) = -inverse (f :: 'a :: field fps)"
       
  1874   by (cases "f$0 = 0") (auto intro: fps_inverse_unique simp: inverse_mult_eq_1' fps_inverse_eq_0)
       
  1875   
       
  1876 lemma divide_fps_const [simp]: "f / fps_const (c :: 'a :: field) = fps_const (inverse c) * f"
       
  1877   by (cases "c = 0") (simp_all add: fps_divide_unit fps_const_inverse)
       
  1878 
  1831 (* FIXME: The last part of this proof should go through by simp once we have a proper
  1879 (* FIXME: The last part of this proof should go through by simp once we have a proper
  1832    theorem collection for simplifying division on rings *)
  1880    theorem collection for simplifying division on rings *)
  1833 lemma fps_divide_deriv:
  1881 lemma fps_divide_deriv:
  1834   assumes "b dvd (a :: 'a :: field fps)"
  1882   assumes "b dvd (a :: 'a :: field fps)"
  1835   shows   "fps_deriv (a / b) = (fps_deriv a * b - a * fps_deriv b) / b^2"
  1883   shows   "fps_deriv (a / b) = (fps_deriv a * b - a * fps_deriv b) / b^2"
  1843   thus ?thesis by (cases "b = 0") (auto simp: eq_divide_imp)
  1891   thus ?thesis by (cases "b = 0") (auto simp: eq_divide_imp)
  1844 qed
  1892 qed
  1845 
  1893 
  1846 lemma fps_inverse_gp': "inverse (Abs_fps (\<lambda>n. 1::'a::field)) = 1 - X"
  1894 lemma fps_inverse_gp': "inverse (Abs_fps (\<lambda>n. 1::'a::field)) = 1 - X"
  1847   by (simp add: fps_inverse_gp fps_eq_iff X_def)
  1895   by (simp add: fps_inverse_gp fps_eq_iff X_def)
       
  1896 
       
  1897 lemma fps_one_over_one_minus_X_squared:
       
  1898   "inverse ((1 - X)^2 :: 'a :: field fps) = Abs_fps (\<lambda>n. of_nat (n+1))"
       
  1899 proof -
       
  1900   have "inverse ((1 - X)^2 :: 'a fps) = fps_deriv (inverse (1 - X))"
       
  1901     by (subst fps_inverse_deriv) (simp_all add: fps_inverse_power)
       
  1902   also have "inverse (1 - X :: 'a fps) = Abs_fps (\<lambda>_. 1)"
       
  1903     by (subst fps_inverse_gp' [symmetric]) simp
       
  1904   also have "fps_deriv \<dots> = Abs_fps (\<lambda>n. of_nat (n + 1))"
       
  1905     by (simp add: fps_deriv_def)
       
  1906   finally show ?thesis .
       
  1907 qed
  1848 
  1908 
  1849 lemma fps_nth_deriv_X[simp]: "fps_nth_deriv n X = (if n = 0 then X else if n=1 then 1 else 0)"
  1909 lemma fps_nth_deriv_X[simp]: "fps_nth_deriv n X = (if n = 0 then X else if n=1 then 1 else 0)"
  1850   by (cases n) simp_all
  1910   by (cases n) simp_all
  1851 
  1911 
  1852 lemma fps_inverse_X_plus1: "inverse (1 + X) = Abs_fps (\<lambda>n. (- (1::'a::field)) ^ n)"
  1912 lemma fps_inverse_X_plus1: "inverse (1 + X) = Abs_fps (\<lambda>n. (- (1::'a::field)) ^ n)"
  2305   also have "\<dots> = (a$0) ^ m"
  2365   also have "\<dots> = (a$0) ^ m"
  2306    unfolding c by (rule setprod_constant)
  2366    unfolding c by (rule setprod_constant)
  2307  finally show ?thesis .
  2367  finally show ?thesis .
  2308 qed
  2368 qed
  2309 
  2369 
       
  2370 lemma natpermute_max_card:
       
  2371   assumes n0: "n \<noteq> 0"
       
  2372   shows "card {xs \<in> natpermute n (k + 1). n \<in> set xs} = k + 1"
       
  2373   unfolding natpermute_contain_maximal
       
  2374 proof -
       
  2375   let ?A = "\<lambda>i. {replicate (k + 1) 0[i := n]}"
       
  2376   let ?K = "{0 ..k}"
       
  2377   have fK: "finite ?K"
       
  2378     by simp
       
  2379   have fAK: "\<forall>i\<in>?K. finite (?A i)"
       
  2380     by auto
       
  2381   have d: "\<forall>i\<in> ?K. \<forall>j\<in> ?K. i \<noteq> j \<longrightarrow>
       
  2382     {replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}"
       
  2383   proof clarify
       
  2384     fix i j
       
  2385     assume i: "i \<in> ?K" and j: "j \<in> ?K" and ij: "i \<noteq> j"
       
  2386     have False if eq: "replicate (k+1) 0 [i:=n] = replicate (k+1) 0 [j:= n]"
       
  2387     proof -
       
  2388       have "(replicate (k+1) 0 [i:=n] ! i) = n"
       
  2389         using i by (simp del: replicate.simps)
       
  2390       moreover
       
  2391       have "(replicate (k+1) 0 [j:=n] ! i) = 0"
       
  2392         using i ij by (simp del: replicate.simps)
       
  2393       ultimately show ?thesis
       
  2394         using eq n0 by (simp del: replicate.simps)
       
  2395     qed
       
  2396     then show "{replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}"
       
  2397       by auto
       
  2398   qed
       
  2399   from card_UN_disjoint[OF fK fAK d]
       
  2400   show "card (\<Union>i\<in>{0..k}. {replicate (k + 1) 0[i := n]}) = k + 1"
       
  2401     by simp
       
  2402 qed
       
  2403 
       
  2404 lemma fps_power_Suc_nth:
       
  2405   fixes f :: "'a :: comm_ring_1 fps"
       
  2406   assumes k: "k > 0"
       
  2407   shows "(f ^ Suc m) $ k = 
       
  2408            of_nat (Suc m) * (f $ k * (f $ 0) ^ m) +
       
  2409            (\<Sum>v\<in>{v\<in>natpermute k (m+1). k \<notin> set v}. \<Prod>j = 0..m. f $ v ! j)"
       
  2410 proof -
       
  2411   define A B 
       
  2412     where "A = {v\<in>natpermute k (m+1). k \<in> set v}" 
       
  2413       and  "B = {v\<in>natpermute k (m+1). k \<notin> set v}"
       
  2414   have [simp]: "finite A" "finite B" "A \<inter> B = {}" by (auto simp: A_def B_def natpermute_finite)
       
  2415 
       
  2416   from natpermute_max_card[of k m] k have card_A: "card A = m + 1" by (simp add: A_def)
       
  2417   {
       
  2418     fix v assume v: "v \<in> A"
       
  2419     from v have [simp]: "length v = Suc m" by (simp add: A_def natpermute_def)
       
  2420     from v have "\<exists>j. j \<le> m \<and> v ! j = k" 
       
  2421       by (auto simp: set_conv_nth A_def natpermute_def less_Suc_eq_le)
       
  2422     then guess j by (elim exE conjE) note j = this
       
  2423     
       
  2424     from v have "k = listsum v" by (simp add: A_def natpermute_def)
       
  2425     also have "\<dots> = (\<Sum>i=0..m. v ! i)"
       
  2426       by (simp add: listsum_setsum_nth atLeastLessThanSuc_atLeastAtMost del: setsum_op_ivl_Suc)
       
  2427     also from j have "{0..m} = insert j ({0..m}-{j})" by auto
       
  2428     also from j have "(\<Sum>i\<in>\<dots>. v ! i) = k + (\<Sum>i\<in>{0..m}-{j}. v ! i)"
       
  2429       by (subst setsum.insert) simp_all
       
  2430     finally have "(\<Sum>i\<in>{0..m}-{j}. v ! i) = 0" by simp
       
  2431     hence zero: "v ! i = 0" if "i \<in> {0..m}-{j}" for i using that
       
  2432       by (subst (asm) setsum_eq_0_iff) auto
       
  2433       
       
  2434     from j have "{0..m} = insert j ({0..m} - {j})" by auto
       
  2435     also from j have "(\<Prod>i\<in>\<dots>. f $ (v ! i)) = f $ k * (\<Prod>i\<in>{0..m} - {j}. f $ (v ! i))"
       
  2436       by (subst setprod.insert) auto
       
  2437     also have "(\<Prod>i\<in>{0..m} - {j}. f $ (v ! i)) = (\<Prod>i\<in>{0..m} - {j}. f $ 0)"
       
  2438       by (intro setprod.cong) (simp_all add: zero)
       
  2439     also from j have "\<dots> = (f $ 0) ^ m" by (subst setprod_constant) simp_all
       
  2440     finally have "(\<Prod>j = 0..m. f $ (v ! j)) = f $ k * (f $ 0) ^ m" .
       
  2441   } note A = this
       
  2442   
       
  2443   have "(f ^ Suc m) $ k = (\<Sum>v\<in>natpermute k (m + 1). \<Prod>j = 0..m. f $ v ! j)"
       
  2444     by (rule fps_power_nth_Suc)
       
  2445   also have "natpermute k (m+1) = A \<union> B" unfolding A_def B_def by blast
       
  2446   also have "(\<Sum>v\<in>\<dots>. \<Prod>j = 0..m. f $ (v ! j)) = 
       
  2447                (\<Sum>v\<in>A. \<Prod>j = 0..m. f $ (v ! j)) + (\<Sum>v\<in>B. \<Prod>j = 0..m. f $ (v ! j))"
       
  2448     by (intro setsum.union_disjoint) simp_all   
       
  2449   also have "(\<Sum>v\<in>A. \<Prod>j = 0..m. f $ (v ! j)) = of_nat (Suc m) * (f $ k * (f $ 0) ^ m)"
       
  2450     by (simp add: A card_A)
       
  2451   finally show ?thesis by (simp add: B_def)
       
  2452 qed 
       
  2453   
       
  2454 lemma fps_power_Suc_eqD:
       
  2455   fixes f g :: "'a :: {idom,semiring_char_0} fps"
       
  2456   assumes "f ^ Suc m = g ^ Suc m" "f $ 0 = g $ 0" "f $ 0 \<noteq> 0"
       
  2457   shows   "f = g"
       
  2458 proof (rule fps_ext)
       
  2459   fix k :: nat
       
  2460   show "f $ k = g $ k"
       
  2461   proof (induction k rule: less_induct)
       
  2462     case (less k)
       
  2463     show ?case
       
  2464     proof (cases "k = 0")
       
  2465       case False
       
  2466       let ?h = "\<lambda>f. (\<Sum>v | v \<in> natpermute k (m + 1) \<and> k \<notin> set v. \<Prod>j = 0..m. f $ v ! j)"
       
  2467       from False fps_power_Suc_nth[of k f m] fps_power_Suc_nth[of k g m]
       
  2468         have "f $ k * (of_nat (Suc m) * (f $ 0) ^ m) + ?h f =
       
  2469                 g $ k * (of_nat (Suc m) * (f $ 0) ^ m) + ?h g" using assms 
       
  2470         by (simp add: mult_ac del: power_Suc of_nat_Suc)
       
  2471       also have "v ! i < k" if "v \<in> {v\<in>natpermute k (m+1). k \<notin> set v}" "i \<le> m" for v i
       
  2472         using that elem_le_listsum_nat[of i v] unfolding natpermute_def
       
  2473         by (auto simp: set_conv_nth dest!: spec[of _ i])
       
  2474       hence "?h f = ?h g"
       
  2475         by (intro setsum.cong refl setprod.cong less lessI) (auto simp: natpermute_def)
       
  2476       finally have "f $ k * (of_nat (Suc m) * (f $ 0) ^ m) = g $ k * (of_nat (Suc m) * (f $ 0) ^ m)"
       
  2477         by simp
       
  2478       with assms show "f $ k = g $ k" 
       
  2479         by (subst (asm) mult_right_cancel) (auto simp del: of_nat_Suc)
       
  2480     qed (simp_all add: assms)
       
  2481   qed
       
  2482 qed
       
  2483 
       
  2484 lemma fps_power_Suc_eqD':
       
  2485   fixes f g :: "'a :: {idom,semiring_char_0} fps"
       
  2486   assumes "f ^ Suc m = g ^ Suc m" "f $ subdegree f = g $ subdegree g"
       
  2487   shows   "f = g"
       
  2488 proof (cases "f = 0")
       
  2489   case False
       
  2490   have "Suc m * subdegree f = subdegree (f ^ Suc m)"
       
  2491     by (rule subdegree_power [symmetric])
       
  2492   also have "f ^ Suc m = g ^ Suc m" by fact
       
  2493   also have "subdegree \<dots> = Suc m * subdegree g" by (rule subdegree_power)
       
  2494   finally have [simp]: "subdegree f = subdegree g"
       
  2495     by (subst (asm) Suc_mult_cancel1)
       
  2496   have "fps_shift (subdegree f) f * X ^ subdegree f = f"
       
  2497     by (rule subdegree_decompose [symmetric])
       
  2498   also have "\<dots> ^ Suc m = g ^ Suc m" by fact
       
  2499   also have "g = fps_shift (subdegree g) g * X ^ subdegree g"
       
  2500     by (rule subdegree_decompose)
       
  2501   also have "subdegree f = subdegree g" by fact
       
  2502   finally have "fps_shift (subdegree g) f ^ Suc m = fps_shift (subdegree g) g ^ Suc m"
       
  2503     by (simp add: algebra_simps power_mult_distrib del: power_Suc)
       
  2504   hence "fps_shift (subdegree g) f = fps_shift (subdegree g) g"
       
  2505     by (rule fps_power_Suc_eqD) (insert assms False, auto)
       
  2506   with subdegree_decompose[of f] subdegree_decompose[of g] show ?thesis by simp
       
  2507 qed (insert assms, simp_all)
       
  2508 
       
  2509 lemma fps_power_eqD':
       
  2510   fixes f g :: "'a :: {idom,semiring_char_0} fps"
       
  2511   assumes "f ^ m = g ^ m" "f $ subdegree f = g $ subdegree g" "m > 0"
       
  2512   shows   "f = g"
       
  2513   using fps_power_Suc_eqD'[of f "m-1" g] assms by simp
       
  2514 
       
  2515 lemma fps_power_eqD:
       
  2516   fixes f g :: "'a :: {idom,semiring_char_0} fps"
       
  2517   assumes "f ^ m = g ^ m" "f $ 0 = g $ 0" "f $ 0 \<noteq> 0" "m > 0"
       
  2518   shows   "f = g"
       
  2519   by (rule fps_power_eqD'[of f m g]) (insert assms, simp_all)
       
  2520 
  2310 lemma fps_compose_inj_right:
  2521 lemma fps_compose_inj_right:
  2311   assumes a0: "a$0 = (0::'a::idom)"
  2522   assumes a0: "a$0 = (0::'a::idom)"
  2312     and a1: "a$1 \<noteq> 0"
  2523     and a1: "a$1 \<noteq> 0"
  2313   shows "(b oo a = c oo a) \<longleftrightarrow> b = c"
  2524   shows "(b oo a = c oo a) \<longleftrightarrow> b = c"
  2314   (is "?lhs \<longleftrightarrow>?rhs")
  2525   (is "?lhs \<longleftrightarrow>?rhs")
  2438     done
  2649     done
  2439   also have "\<dots> = a$0"
  2650   also have "\<dots> = a$0"
  2440     using r Suc by (simp add: setprod_constant)
  2651     using r Suc by (simp add: setprod_constant)
  2441   finally show ?thesis
  2652   finally show ?thesis
  2442     using Suc by simp
  2653     using Suc by simp
  2443 qed
       
  2444 
       
  2445 lemma natpermute_max_card:
       
  2446   assumes n0: "n \<noteq> 0"
       
  2447   shows "card {xs \<in> natpermute n (k + 1). n \<in> set xs} = k + 1"
       
  2448   unfolding natpermute_contain_maximal
       
  2449 proof -
       
  2450   let ?A = "\<lambda>i. {replicate (k + 1) 0[i := n]}"
       
  2451   let ?K = "{0 ..k}"
       
  2452   have fK: "finite ?K"
       
  2453     by simp
       
  2454   have fAK: "\<forall>i\<in>?K. finite (?A i)"
       
  2455     by auto
       
  2456   have d: "\<forall>i\<in> ?K. \<forall>j\<in> ?K. i \<noteq> j \<longrightarrow>
       
  2457     {replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}"
       
  2458   proof clarify
       
  2459     fix i j
       
  2460     assume i: "i \<in> ?K" and j: "j \<in> ?K" and ij: "i \<noteq> j"
       
  2461     have False if eq: "replicate (k+1) 0 [i:=n] = replicate (k+1) 0 [j:= n]"
       
  2462     proof -
       
  2463       have "(replicate (k+1) 0 [i:=n] ! i) = n"
       
  2464         using i by (simp del: replicate.simps)
       
  2465       moreover
       
  2466       have "(replicate (k+1) 0 [j:=n] ! i) = 0"
       
  2467         using i ij by (simp del: replicate.simps)
       
  2468       ultimately show ?thesis
       
  2469         using eq n0 by (simp del: replicate.simps)
       
  2470     qed
       
  2471     then show "{replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}"
       
  2472       by auto
       
  2473   qed
       
  2474   from card_UN_disjoint[OF fK fAK d]
       
  2475   show "card (\<Union>i\<in>{0..k}. {replicate (k + 1) 0[i := n]}) = k + 1"
       
  2476     by simp
       
  2477 qed
  2654 qed
  2478 
  2655 
  2479 lemma power_radical:
  2656 lemma power_radical:
  2480   fixes a:: "'a::field_char_0 fps"
  2657   fixes a:: "'a::field_char_0 fps"
  2481   assumes a0: "a$0 \<noteq> 0"
  2658   assumes a0: "a$0 \<noteq> 0"
  3211   apply (induct S rule: finite_induct)
  3388   apply (induct S rule: finite_induct)
  3212   apply simp
  3389   apply simp
  3213   apply (simp add: fps_compose_mult_distrib[OF c0])
  3390   apply (simp add: fps_compose_mult_distrib[OF c0])
  3214   done
  3391   done
  3215 
  3392 
       
  3393 lemma fps_compose_divide:
       
  3394   assumes [simp]: "g dvd f" "h $ 0 = 0"
       
  3395   shows   "fps_compose f h = fps_compose (f / g :: 'a :: field fps) h * fps_compose g h"
       
  3396 proof -
       
  3397   have "f = (f / g) * g" by simp
       
  3398   also have "fps_compose \<dots> h = fps_compose (f / g) h * fps_compose g h"
       
  3399     by (subst fps_compose_mult_distrib) simp_all
       
  3400   finally show ?thesis .
       
  3401 qed
       
  3402 
       
  3403 lemma fps_compose_divide_distrib:
       
  3404   assumes "g dvd f" "h $ 0 = 0" "fps_compose g h \<noteq> 0"
       
  3405   shows   "fps_compose (f / g :: 'a :: field fps) h = fps_compose f h / fps_compose g h"
       
  3406   using fps_compose_divide[OF assms(1,2)] assms(3) by simp
       
  3407 
  3216 lemma fps_compose_power:
  3408 lemma fps_compose_power:
  3217   assumes c0: "c$0 = (0::'a::idom)"
  3409   assumes c0: "c$0 = (0::'a::idom)"
  3218   shows "(a oo c)^n = a^n oo c"
  3410   shows "(a oo c)^n = a^n oo c"
  3219 proof (cases n)
  3411 proof (cases n)
  3220   case 0
  3412   case 0
  3491     unfolding fps_compose_assoc[OF iXa0 a0] .
  3683     unfolding fps_compose_assoc[OF iXa0 a0] .
  3492   then show ?thesis unfolding fps_inv_ginv[symmetric]
  3684   then show ?thesis unfolding fps_inv_ginv[symmetric]
  3493     unfolding fps_inv_right[OF a0 a1] by simp
  3685     unfolding fps_inv_right[OF a0 a1] by simp
  3494 qed
  3686 qed
  3495 
  3687 
       
  3688 lemma fps_compose_linear:
       
  3689   "fps_compose (f :: 'a :: comm_ring_1 fps) (fps_const c * X) = Abs_fps (\<lambda>n. c^n * f $ n)"
       
  3690   by (simp add: fps_eq_iff fps_compose_def power_mult_distrib
       
  3691                 if_distrib setsum.delta' cong: if_cong)
  3496 
  3692 
  3497 subsection \<open>Elementary series\<close>
  3693 subsection \<open>Elementary series\<close>
  3498 
  3694 
  3499 subsubsection \<open>Exponential series\<close>
  3695 subsubsection \<open>Exponential series\<close>
  3500 
  3696 
  3740       done
  3936       done
  3741     with eq show ?thesis ..
  3937     with eq show ?thesis ..
  3742   qed
  3938   qed
  3743 qed
  3939 qed
  3744 
  3940 
       
  3941 lemma fps_binomial_ODE_unique':
       
  3942   "(fps_deriv a = fps_const c * a / (1 + X) \<and> a $ 0 = 1) \<longleftrightarrow> (a = fps_binomial c)"
       
  3943   by (subst fps_binomial_ODE_unique) auto
       
  3944 
  3745 lemma fps_binomial_deriv: "fps_deriv (fps_binomial c) = fps_const c * fps_binomial c / (1 + X)"
  3945 lemma fps_binomial_deriv: "fps_deriv (fps_binomial c) = fps_const c * fps_binomial c / (1 + X)"
  3746 proof -
  3946 proof -
  3747   let ?a = "fps_binomial c"
  3947   let ?a = "fps_binomial c"
  3748   have th0: "?a = fps_const (?a$0) * ?a" by (simp)
  3948   have th0: "?a = fps_const (?a$0) * ?a" by (simp)
  3749   from iffD2[OF fps_binomial_ODE_unique, OF th0] show ?thesis .
  3949   from iffD2[OF fps_binomial_ODE_unique, OF th0] show ?thesis .
  3780   have eq: "inverse ?r $ 0 = 1"
  3980   have eq: "inverse ?r $ 0 = 1"
  3781     by (simp add: fps_inverse_def)
  3981     by (simp add: fps_inverse_def)
  3782   from iffD1[OF fps_binomial_ODE_unique[of "inverse (1 + X)" "- 1"] th'] eq
  3982   from iffD1[OF fps_binomial_ODE_unique[of "inverse (1 + X)" "- 1"] th'] eq
  3783   show ?thesis by (simp add: fps_inverse_def)
  3983   show ?thesis by (simp add: fps_inverse_def)
  3784 qed
  3984 qed
       
  3985 
       
  3986 lemma fps_binomial_of_nat: "fps_binomial (of_nat n) = (1 + X :: 'a :: field_char_0 fps) ^ n"
       
  3987 proof (cases "n = 0")
       
  3988   case [simp]: True
       
  3989   have "fps_deriv ((1 + X) ^ n :: 'a fps) = 0" by simp
       
  3990   also have "\<dots> = fps_const (of_nat n) * (1 + X) ^ n / (1 + X)" by (simp add: fps_binomial_def)
       
  3991   finally show ?thesis by (subst sym, subst fps_binomial_ODE_unique' [symmetric]) simp_all
       
  3992 next
       
  3993   case False
       
  3994   have "fps_deriv ((1 + X) ^ n :: 'a fps) = fps_const (of_nat n) * (1 + X) ^ (n - 1)"
       
  3995     by (simp add: fps_deriv_power)
       
  3996   also have "(1 + X :: 'a fps) $ 0 \<noteq> 0" by simp
       
  3997   hence "(1 + X :: 'a fps) \<noteq> 0" by (intro notI) (simp only: , simp)
       
  3998   with False have "(1 + X :: 'a fps) ^ (n - 1) = (1 + X) ^ n / (1 + X)"
       
  3999     by (cases n) (simp_all )
       
  4000   also have "fps_const (of_nat n :: 'a) * ((1 + X) ^ n / (1 + X)) =
       
  4001                fps_const (of_nat n) * (1 + X) ^ n / (1 + X)"
       
  4002     by (simp add: unit_div_mult_swap)
       
  4003   finally show ?thesis
       
  4004     by (subst sym, subst fps_binomial_ODE_unique' [symmetric]) (simp_all add: fps_power_nth)
       
  4005 qed
       
  4006 
       
  4007 lemma fps_binomial_0 [simp]: "fps_binomial 0 = 1"
       
  4008   using fps_binomial_of_nat[of 0] by simp
       
  4009   
       
  4010 lemma fps_binomial_power: "fps_binomial a ^ n = fps_binomial (of_nat n * a)"
       
  4011   by (induction n) (simp_all add: fps_binomial_add_mult ring_distribs)
       
  4012 
       
  4013 lemma fps_binomial_1: "fps_binomial 1 = 1 + X"
       
  4014   using fps_binomial_of_nat[of 1] by simp
       
  4015 
       
  4016 lemma fps_binomial_minus_of_nat:
       
  4017   "fps_binomial (- of_nat n) = inverse ((1 + X :: 'a :: field_char_0 fps) ^ n)"
       
  4018   by (rule sym, rule fps_inverse_unique)
       
  4019      (simp add: fps_binomial_of_nat [symmetric] fps_binomial_add_mult [symmetric])
       
  4020 
       
  4021 lemma one_minus_const_X_power:
       
  4022   "c \<noteq> 0 \<Longrightarrow> (1 - fps_const c * X) ^ n =
       
  4023      fps_compose (fps_binomial (of_nat n)) (-fps_const c * X)"
       
  4024   by (subst fps_binomial_of_nat)
       
  4025      (simp add: fps_compose_power [symmetric] fps_compose_add_distrib fps_const_neg [symmetric] 
       
  4026            del: fps_const_neg)
       
  4027 
       
  4028 lemma one_minus_X_const_neg_power:
       
  4029   "inverse ((1 - fps_const c * X) ^ n) = 
       
  4030        fps_compose (fps_binomial (-of_nat n)) (-fps_const c * X)"
       
  4031 proof (cases "c = 0")
       
  4032   case False
       
  4033   thus ?thesis
       
  4034   by (subst fps_binomial_minus_of_nat)
       
  4035      (simp add: fps_compose_power [symmetric] fps_inverse_compose fps_compose_add_distrib
       
  4036                 fps_const_neg [symmetric] del: fps_const_neg)
       
  4037 qed simp
       
  4038 
       
  4039 lemma X_plus_const_power:
       
  4040   "c \<noteq> 0 \<Longrightarrow> (X + fps_const c) ^ n =
       
  4041      fps_const (c^n) * fps_compose (fps_binomial (of_nat n)) (fps_const (inverse c) * X)"
       
  4042   by (subst fps_binomial_of_nat)
       
  4043      (simp add: fps_compose_power [symmetric] fps_binomial_of_nat fps_compose_add_distrib
       
  4044                 fps_const_power [symmetric] power_mult_distrib [symmetric] 
       
  4045                 algebra_simps inverse_mult_eq_1' del: fps_const_power)
       
  4046 
       
  4047 lemma X_plus_const_neg_power:
       
  4048   "c \<noteq> 0 \<Longrightarrow> inverse ((X + fps_const c) ^ n) =
       
  4049      fps_const (inverse c^n) * fps_compose (fps_binomial (-of_nat n)) (fps_const (inverse c) * X)"
       
  4050   by (subst fps_binomial_minus_of_nat)
       
  4051      (simp add: fps_compose_power [symmetric] fps_binomial_of_nat fps_compose_add_distrib
       
  4052                 fps_const_power [symmetric] power_mult_distrib [symmetric] fps_inverse_compose 
       
  4053                 algebra_simps fps_const_inverse [symmetric] fps_inverse_mult [symmetric]
       
  4054                 fps_inverse_power [symmetric] inverse_mult_eq_1'
       
  4055            del: fps_const_power)
       
  4056 
       
  4057 
       
  4058 lemma one_minus_const_X_neg_power':
       
  4059   "n > 0 \<Longrightarrow> inverse ((1 - fps_const (c :: 'a :: field_char_0) * X) ^ n) =
       
  4060        Abs_fps (\<lambda>k. of_nat ((n + k - 1) choose k) * c^k)"
       
  4061   apply (rule fps_ext)
       
  4062   apply (subst one_minus_X_const_neg_power, subst fps_const_neg, subst fps_compose_linear)
       
  4063   apply (simp add: power_mult_distrib [symmetric] mult.assoc [symmetric] 
       
  4064                    gbinomial_minus binomial_gbinomial of_nat_diff)
       
  4065   done
  3785 
  4066 
  3786 text \<open>Vandermonde's Identity as a consequence.\<close>
  4067 text \<open>Vandermonde's Identity as a consequence.\<close>
  3787 lemma gbinomial_Vandermonde:
  4068 lemma gbinomial_Vandermonde:
  3788   "setsum (\<lambda>k. (a gchoose k) * (b gchoose (n - k))) {0..n} = (a + b) gchoose n"
  4069   "setsum (\<lambda>k. (a gchoose k) * (b gchoose (n - k))) {0..n} = (a + b) gchoose n"
  3789 proof -
  4070 proof -
  4214   unfolding minus_mult_right Eii_sin_cos by (simp add: fps_sin_even fps_cos_odd)
  4495   unfolding minus_mult_right Eii_sin_cos by (simp add: fps_sin_even fps_cos_odd)
  4215 
  4496 
  4216 lemma fps_const_minus: "fps_const (c::'a::group_add) - fps_const d = fps_const (c - d)"
  4497 lemma fps_const_minus: "fps_const (c::'a::group_add) - fps_const d = fps_const (c - d)"
  4217   by (fact fps_const_sub)
  4498   by (fact fps_const_sub)
  4218 
  4499 
       
  4500 lemma fps_of_int: "fps_const (of_int c) = of_int c"
       
  4501   by (induction c) (simp_all add: fps_const_minus [symmetric] fps_of_nat fps_const_neg [symmetric] 
       
  4502                              del: fps_const_minus fps_const_neg)
       
  4503 
  4219 lemma fps_numeral_fps_const: "numeral i = fps_const (numeral i :: 'a::comm_ring_1)"
  4504 lemma fps_numeral_fps_const: "numeral i = fps_const (numeral i :: 'a::comm_ring_1)"
  4220   by (fact numeral_fps_const) (* FIXME: duplicate *)
  4505   by (fact numeral_fps_const) (* FIXME: duplicate *)
  4221 
  4506 
  4222 lemma fps_cos_Eii: "fps_cos c = (E (ii * c) + E (- ii * c)) / fps_const 2"
  4507 lemma fps_cos_Eii: "fps_cos c = (E (ii * c) + E (- ii * c)) / fps_const 2"
  4223 proof -
  4508 proof -