src/HOL/Library/Formal_Power_Series.thy
changeset 62102 877463945ce9
parent 62101 26c0a70f78a3
child 62343 24106dc44def
equal deleted inserted replaced
62101:26c0a70f78a3 62102:877463945ce9
   381   "(- numeral k :: 'a :: ring_1 fps) = fps_const (- numeral k)"
   381   "(- numeral k :: 'a :: ring_1 fps) = fps_const (- numeral k)"
   382   by (simp add: numeral_fps_const)
   382   by (simp add: numeral_fps_const)
   383 
   383 
   384 lemma fps_numeral_nth: "numeral n $ i = (if i = 0 then numeral n else 0)"
   384 lemma fps_numeral_nth: "numeral n $ i = (if i = 0 then numeral n else 0)"
   385   by (simp add: numeral_fps_const)
   385   by (simp add: numeral_fps_const)
   386   
   386 
   387 lemma fps_numeral_nth_0 [simp]: "numeral n $ 0 = numeral n"
   387 lemma fps_numeral_nth_0 [simp]: "numeral n $ 0 = numeral n"
   388   by (simp add: numeral_fps_const)
   388   by (simp add: numeral_fps_const)
   389 
   389 
   390 
   390 
   391 subsection \<open>The eXtractor series X\<close>
   391 subsection \<open>The eXtractor series X\<close>
   465   by (simp only: fps_const_1_eq_1[symmetric] X_neq_fps_const) simp
   465   by (simp only: fps_const_1_eq_1[symmetric] X_neq_fps_const) simp
   466 
   466 
   467 lemma X_neq_numeral [simp]: "(X :: 'a :: {semiring_1,zero_neq_one} fps) \<noteq> numeral c"
   467 lemma X_neq_numeral [simp]: "(X :: 'a :: {semiring_1,zero_neq_one} fps) \<noteq> numeral c"
   468   by (simp only: numeral_fps_const X_neq_fps_const) simp
   468   by (simp only: numeral_fps_const X_neq_fps_const) simp
   469 
   469 
   470 lemma X_pow_eq_X_pow_iff [simp]: 
   470 lemma X_pow_eq_X_pow_iff [simp]:
   471   "(X :: ('a :: {comm_ring_1}) fps) ^ m = X ^ n \<longleftrightarrow> m = n"
   471   "(X :: ('a :: {comm_ring_1}) fps) ^ m = X ^ n \<longleftrightarrow> m = n"
   472 proof
   472 proof
   473   assume "(X :: 'a fps) ^ m = X ^ n"
   473   assume "(X :: 'a fps) ^ m = X ^ n"
   474   hence "(X :: 'a fps) ^ m $ m = X ^ n $ m" by (simp only:)
   474   hence "(X :: 'a fps) ^ m $ m = X ^ n $ m" by (simp only:)
   475   thus "m = n" by (simp split: split_if_asm)
   475   thus "m = n" by (simp split: split_if_asm)
   476 qed simp_all
   476 qed simp_all
   477   
   477 
   478 
   478 
   479 subsection \<open>Subdegrees\<close>  
   479 subsection \<open>Subdegrees\<close>
   480   
   480 
   481 definition subdegree :: "('a::zero) fps \<Rightarrow> nat" where
   481 definition subdegree :: "('a::zero) fps \<Rightarrow> nat" where
   482   "subdegree f = (if f = 0 then 0 else LEAST n. f$n \<noteq> 0)"
   482   "subdegree f = (if f = 0 then 0 else LEAST n. f$n \<noteq> 0)"
   483 
   483 
   484 lemma subdegreeI:
   484 lemma subdegreeI:
   485   assumes "f $ d \<noteq> 0" and "\<And>i. i < d \<Longrightarrow> f $ i = 0"
   485   assumes "f $ d \<noteq> 0" and "\<And>i. i < d \<Longrightarrow> f $ i = 0"
   509   assume "f \<noteq> 0" and less: "n < subdegree f"
   509   assume "f \<noteq> 0" and less: "n < subdegree f"
   510   note less
   510   note less
   511   also from \<open>f \<noteq> 0\<close> have "subdegree f = (LEAST n. f $ n \<noteq> 0)" by (simp add: subdegree_def)
   511   also from \<open>f \<noteq> 0\<close> have "subdegree f = (LEAST n. f $ n \<noteq> 0)" by (simp add: subdegree_def)
   512   finally show "f $ n = 0" using not_less_Least by blast
   512   finally show "f $ n = 0" using not_less_Least by blast
   513 qed simp_all
   513 qed simp_all
   514   
   514 
   515 lemma subdegree_geI:
   515 lemma subdegree_geI:
   516   assumes "f \<noteq> 0" "\<And>i. i < n \<Longrightarrow> f$i = 0"
   516   assumes "f \<noteq> 0" "\<And>i. i < n \<Longrightarrow> f$i = 0"
   517   shows   "subdegree f \<ge> n"
   517   shows   "subdegree f \<ge> n"
   518 proof (rule ccontr)
   518 proof (rule ccontr)
   519   assume "\<not>(subdegree f \<ge> n)"
   519   assume "\<not>(subdegree f \<ge> n)"
   596   also have "... = f $ subdegree f * g $ subdegree g" by (simp add: setsum.delta)
   596   also have "... = f $ subdegree f * g $ subdegree g" by (simp add: setsum.delta)
   597   also from assms have "... \<noteq> 0" by auto
   597   also from assms have "... \<noteq> 0" by auto
   598   finally show "(f * g) $ (subdegree f + subdegree g) \<noteq> 0" .
   598   finally show "(f * g) $ (subdegree f + subdegree g) \<noteq> 0" .
   599 next
   599 next
   600   fix m assume m: "m < subdegree f + subdegree g"
   600   fix m assume m: "m < subdegree f + subdegree g"
   601   have "(f * g) $ m = (\<Sum>i=0..m. f$i * g$(m-i))" by (simp add: fps_mult_nth) 
   601   have "(f * g) $ m = (\<Sum>i=0..m. f$i * g$(m-i))" by (simp add: fps_mult_nth)
   602   also have "... = (\<Sum>i=0..m. 0)"
   602   also have "... = (\<Sum>i=0..m. 0)"
   603   proof (rule setsum.cong)
   603   proof (rule setsum.cong)
   604     fix i assume "i \<in> {0..m}"
   604     fix i assume "i \<in> {0..m}"
   605     with m have "i < subdegree f \<or> m - i < subdegree g" by auto
   605     with m have "i < subdegree f \<or> m - i < subdegree g" by auto
   606     thus "f$i * g$(m-i) = 0" by (elim disjE) auto
   606     thus "f$i * g$(m-i) = 0" by (elim disjE) auto
   693   by (intro fps_ext) (simp add: fps_shift_def)
   693   by (intro fps_ext) (simp add: fps_shift_def)
   694 
   694 
   695 lemma fps_shift_numeral: "fps_shift n (numeral c) = (if n = 0 then numeral c else 0)"
   695 lemma fps_shift_numeral: "fps_shift n (numeral c) = (if n = 0 then numeral c else 0)"
   696   by (simp add: numeral_fps_const fps_shift_fps_const)
   696   by (simp add: numeral_fps_const fps_shift_fps_const)
   697 
   697 
   698 lemma fps_shift_X_power [simp]: 
   698 lemma fps_shift_X_power [simp]:
   699   "n \<le> m \<Longrightarrow> fps_shift n (X ^ m) = (X ^ (m - n) ::'a::comm_ring_1 fps)"
   699   "n \<le> m \<Longrightarrow> fps_shift n (X ^ m) = (X ^ (m - n) ::'a::comm_ring_1 fps)"
   700   by (intro fps_ext) (auto simp: fps_shift_def ) 
   700   by (intro fps_ext) (auto simp: fps_shift_def )
   701 
   701 
   702 lemma fps_shift_times_X_power:
   702 lemma fps_shift_times_X_power:
   703   "n \<le> subdegree f \<Longrightarrow> fps_shift n f * X ^ n = (f :: 'a :: comm_ring_1 fps)"
   703   "n \<le> subdegree f \<Longrightarrow> fps_shift n f * X ^ n = (f :: 'a :: comm_ring_1 fps)"
   704   by (intro fps_ext) (auto simp: X_power_mult_right_nth nth_less_subdegree_zero)
   704   by (intro fps_ext) (auto simp: X_power_mult_right_nth nth_less_subdegree_zero)
   705 
   705 
   709 
   709 
   710 lemma fps_shift_times_X_power'':
   710 lemma fps_shift_times_X_power'':
   711   "m \<le> n \<Longrightarrow> fps_shift n (f * X^m) = fps_shift (n - m) (f :: 'a :: comm_ring_1 fps)"
   711   "m \<le> n \<Longrightarrow> fps_shift n (f * X^m) = fps_shift (n - m) (f :: 'a :: comm_ring_1 fps)"
   712   by (intro fps_ext) (auto simp: X_power_mult_right_nth nth_less_subdegree_zero)
   712   by (intro fps_ext) (auto simp: X_power_mult_right_nth nth_less_subdegree_zero)
   713 
   713 
   714 lemma fps_shift_subdegree [simp]: 
   714 lemma fps_shift_subdegree [simp]:
   715   "n \<le> subdegree f \<Longrightarrow> subdegree (fps_shift n f) = subdegree (f :: 'a :: comm_ring_1 fps) - n"
   715   "n \<le> subdegree f \<Longrightarrow> subdegree (fps_shift n f) = subdegree (f :: 'a :: comm_ring_1 fps) - n"
   716   by (cases "f = 0") (force intro: nth_less_subdegree_zero subdegreeI)+
   716   by (cases "f = 0") (force intro: nth_less_subdegree_zero subdegreeI)+
   717 
   717 
   718 lemma subdegree_decompose:
   718 lemma subdegree_decompose:
   719   "f = fps_shift (subdegree f) f * X ^ subdegree (f :: ('a :: comm_ring_1) fps)"
   719   "f = fps_shift (subdegree f) f * X ^ subdegree (f :: ('a :: comm_ring_1) fps)"
   724   by (rule fps_ext) (auto simp: X_power_mult_right_nth intro!: nth_less_subdegree_zero)
   724   by (rule fps_ext) (auto simp: X_power_mult_right_nth intro!: nth_less_subdegree_zero)
   725 
   725 
   726 lemma fps_shift_fps_shift:
   726 lemma fps_shift_fps_shift:
   727   "fps_shift (m + n) f = fps_shift m (fps_shift n f)"
   727   "fps_shift (m + n) f = fps_shift m (fps_shift n f)"
   728   by (rule fps_ext) (simp add: add_ac)
   728   by (rule fps_ext) (simp add: add_ac)
   729   
   729 
   730 lemma fps_shift_add:
   730 lemma fps_shift_add:
   731   "fps_shift n (f + g) = fps_shift n f + fps_shift n g"
   731   "fps_shift n (f + g) = fps_shift n f + fps_shift n g"
   732   by (simp add: fps_eq_iff)
   732   by (simp add: fps_eq_iff)
   733   
   733 
   734 lemma fps_shift_mult:
   734 lemma fps_shift_mult:
   735   assumes "n \<le> subdegree (g :: 'b :: {comm_ring_1} fps)"
   735   assumes "n \<le> subdegree (g :: 'b :: {comm_ring_1} fps)"
   736   shows   "fps_shift n (h*g) = h * fps_shift n g"
   736   shows   "fps_shift n (h*g) = h * fps_shift n g"
   737 proof -
   737 proof -
   738   from assms have "g = fps_shift n g * X^n" by (rule subdegree_decompose')
   738   from assms have "g = fps_shift n g * X^n" by (rule subdegree_decompose')
   772   qed simp
   772   qed simp
   773 qed (auto simp: fps_eq_iff intro: nth_less_subdegree_zero)
   773 qed (auto simp: fps_eq_iff intro: nth_less_subdegree_zero)
   774 
   774 
   775 lemma fps_cutoff_0 [simp]: "fps_cutoff 0 f = 0"
   775 lemma fps_cutoff_0 [simp]: "fps_cutoff 0 f = 0"
   776   by (simp add: fps_eq_iff)
   776   by (simp add: fps_eq_iff)
   777   
   777 
   778 lemma fps_cutoff_zero [simp]: "fps_cutoff n 0 = 0"
   778 lemma fps_cutoff_zero [simp]: "fps_cutoff n 0 = 0"
   779   by (simp add: fps_eq_iff)
   779   by (simp add: fps_eq_iff)
   780 
   780 
   781 lemma fps_cutoff_one: "fps_cutoff n 1 = (if n = 0 then 0 else 1)"
   781 lemma fps_cutoff_one: "fps_cutoff n 1 = (if n = 0 then 0 else 1)"
   782   by (simp add: fps_eq_iff)
   782   by (simp add: fps_eq_iff)
   783 
   783 
   784 lemma fps_cutoff_fps_const: "fps_cutoff n (fps_const c) = (if n = 0 then 0 else fps_const c)"
   784 lemma fps_cutoff_fps_const: "fps_cutoff n (fps_const c) = (if n = 0 then 0 else fps_const c)"
   785   by (simp add: fps_eq_iff)  
   785   by (simp add: fps_eq_iff)
   786 
   786 
   787 lemma fps_cutoff_numeral: "fps_cutoff n (numeral c) = (if n = 0 then 0 else numeral c)"
   787 lemma fps_cutoff_numeral: "fps_cutoff n (numeral c) = (if n = 0 then 0 else numeral c)"
   788   by (simp add: numeral_fps_const fps_cutoff_fps_const)
   788   by (simp add: numeral_fps_const fps_cutoff_fps_const)
   789 
   789 
   790 lemma fps_shift_cutoff: 
   790 lemma fps_shift_cutoff:
   791   "fps_shift n (f :: ('a :: comm_ring_1) fps) * X^n + fps_cutoff n f = f"
   791   "fps_shift n (f :: ('a :: comm_ring_1) fps) * X^n + fps_cutoff n f = f"
   792   by (simp add: fps_eq_iff X_power_mult_right_nth)
   792   by (simp add: fps_eq_iff X_power_mult_right_nth)
   793 
   793 
   794 
   794 
   795 subsection \<open>Formal Power series form a metric space\<close>
   795 subsection \<open>Formal Power series form a metric space\<close>
   842     have False if "dist a b > dist a c + dist b c"
   842     have False if "dist a b > dist a c + dist b c"
   843     proof -
   843     proof -
   844       let ?n = "subdegree (a - b)"
   844       let ?n = "subdegree (a - b)"
   845       from neq have "dist a b > 0" "dist b c > 0" and "dist a c > 0" by (simp_all add: dist_fps_def)
   845       from neq have "dist a b > 0" "dist b c > 0" and "dist a c > 0" by (simp_all add: dist_fps_def)
   846       with that have "dist a b > dist a c" and "dist a b > dist b c" by simp_all
   846       with that have "dist a b > dist a c" and "dist a b > dist b c" by simp_all
   847       with neq have "?n < subdegree (a - c)" and "?n < subdegree (b - c)"  
   847       with neq have "?n < subdegree (a - c)" and "?n < subdegree (b - c)"
   848         by (simp_all add: dist_fps_def field_simps)
   848         by (simp_all add: dist_fps_def field_simps)
   849       hence "(a - c) $ ?n = 0" and "(b - c) $ ?n = 0" 
   849       hence "(a - c) $ ?n = 0" and "(b - c) $ ?n = 0"
   850         by (simp_all only: nth_less_subdegree_zero)
   850         by (simp_all only: nth_less_subdegree_zero)
   851       hence "(a - b) $ ?n = 0" by simp
   851       hence "(a - b) $ ?n = 0" by simp
   852       moreover from neq have "(a - b) $ ?n \<noteq> 0" by (intro nth_subdegree_nonzero) simp_all
   852       moreover from neq have "(a - b) $ ?n \<noteq> 0" by (intro nth_subdegree_nonzero) simp_all
   853       ultimately show False by contradiction
   853       ultimately show False by contradiction
   854     qed
   854     qed
   855     thus ?thesis by (auto simp add: not_le[symmetric])
   855     thus ?thesis by (auto simp add: not_le[symmetric])
   856   qed
   856   qed
   857 qed (rule open_fps_def' uniformity_fps_def)+
   857 qed (rule open_fps_def' uniformity_fps_def)+
   858 
   858 
   859 end
   859 end
       
   860 
       
   861 declare uniformity_Abort[where 'a="'a :: comm_ring_1 fps", code]
   860 
   862 
   861 lemma open_fps_def: "open (S :: 'a::comm_ring_1 fps set) = (\<forall>a \<in> S. \<exists>r. r >0 \<and> ball a r \<subseteq> S)"
   863 lemma open_fps_def: "open (S :: 'a::comm_ring_1 fps set) = (\<forall>a \<in> S. \<exists>r. r >0 \<and> ball a r \<subseteq> S)"
   862   unfolding open_dist ball_def subset_eq by simp
   864   unfolding open_dist ball_def subset_eq by simp
   863 
   865 
   864 text \<open>The infinite sums and justification of the notation in textbooks.\<close>
   866 text \<open>The infinite sums and justification of the notation in textbooks.\<close>
   923         next
   925         next
   924           case False
   926           case False
   925           from False have dth: "dist (?s n) a = (1/2)^subdegree (?s n - a)"
   927           from False have dth: "dist (?s n) a = (1/2)^subdegree (?s n - a)"
   926             by (simp add: dist_fps_def field_simps)
   928             by (simp add: dist_fps_def field_simps)
   927           from False have kn: "subdegree (?s n - a) > n"
   929           from False have kn: "subdegree (?s n - a) > n"
   928             by (intro subdegree_greaterI) (simp_all add: fps_sum_rep_nth)              
   930             by (intro subdegree_greaterI) (simp_all add: fps_sum_rep_nth)
   929           then have "dist (?s n) a < (1/2)^n" 
   931           then have "dist (?s n) a < (1/2)^n"
   930             by (simp add: field_simps dist_fps_def)
   932             by (simp add: field_simps dist_fps_def)
   931           also have "\<dots> \<le> (1/2)^n0"
   933           also have "\<dots> \<le> (1/2)^n0"
   932             using nn0 by (simp add: divide_simps)
   934             using nn0 by (simp add: divide_simps)
   933           also have "\<dots> < r"
   935           also have "\<dots> < r"
   934             using n0 by simp
   936             using n0 by simp
   956 | "natfun_inverse f n = - inverse (f$0) * setsum (\<lambda>i. f$i * natfun_inverse f (n - i)) {1..n}"
   958 | "natfun_inverse f n = - inverse (f$0) * setsum (\<lambda>i. f$i * natfun_inverse f (n - i)) {1..n}"
   957 
   959 
   958 definition fps_inverse_def: "inverse f = (if f $ 0 = 0 then 0 else Abs_fps (natfun_inverse f))"
   960 definition fps_inverse_def: "inverse f = (if f $ 0 = 0 then 0 else Abs_fps (natfun_inverse f))"
   959 
   961 
   960 definition fps_divide_def:
   962 definition fps_divide_def:
   961   "f div g = (if g = 0 then 0 else 
   963   "f div g = (if g = 0 then 0 else
   962      let n = subdegree g; h = fps_shift n g
   964      let n = subdegree g; h = fps_shift n g
   963      in  fps_shift n (f * inverse h))"
   965      in  fps_shift n (f * inverse h))"
   964 
   966 
   965 instance ..
   967 instance ..
   966 
   968 
  1010     by (simp add: fps_eq_iff)
  1012     by (simp add: fps_eq_iff)
  1011 qed
  1013 qed
  1012 
  1014 
  1013 lemma fps_inverse_0_iff[simp]: "(inverse f) $ 0 = (0::'a::division_ring) \<longleftrightarrow> f $ 0 = 0"
  1015 lemma fps_inverse_0_iff[simp]: "(inverse f) $ 0 = (0::'a::division_ring) \<longleftrightarrow> f $ 0 = 0"
  1014   by (simp add: fps_inverse_def nonzero_imp_inverse_nonzero)
  1016   by (simp add: fps_inverse_def nonzero_imp_inverse_nonzero)
  1015   
  1017 
  1016 lemma fps_inverse_nth_0 [simp]: "inverse f $ 0 = inverse (f $ 0 :: 'a :: division_ring)"
  1018 lemma fps_inverse_nth_0 [simp]: "inverse f $ 0 = inverse (f $ 0 :: 'a :: division_ring)"
  1017   by (simp add: fps_inverse_def)
  1019   by (simp add: fps_inverse_def)
  1018 
  1020 
  1019 lemma fps_inverse_eq_0_iff[simp]: "inverse f = (0:: ('a::division_ring) fps) \<longleftrightarrow> f $ 0 = 0"
  1021 lemma fps_inverse_eq_0_iff[simp]: "inverse f = (0:: ('a::division_ring) fps) \<longleftrightarrow> f $ 0 = 0"
  1020 proof
  1022 proof
  1098   assume A: "f$0 = 0 \<or> g$0 = 0"
  1100   assume A: "f$0 = 0 \<or> g$0 = 0"
  1099   hence "inverse (f * g) = 0" by simp
  1101   hence "inverse (f * g) = 0" by simp
  1100   also from A have "... = inverse f * inverse g" by auto
  1102   also from A have "... = inverse f * inverse g" by auto
  1101   finally show "inverse (f * g) = inverse f * inverse g" .
  1103   finally show "inverse (f * g) = inverse f * inverse g" .
  1102 qed
  1104 qed
  1103   
  1105 
  1104 
  1106 
  1105 lemma fps_inverse_gp: "inverse (Abs_fps(\<lambda>n. (1::'a::field))) =
  1107 lemma fps_inverse_gp: "inverse (Abs_fps(\<lambda>n. (1::'a::field))) =
  1106     Abs_fps (\<lambda>n. if n= 0 then 1 else if n=1 then - 1 else 0)"
  1108     Abs_fps (\<lambda>n. if n= 0 then 1 else if n=1 then - 1 else 0)"
  1107   apply (rule fps_inverse_unique)
  1109   apply (rule fps_inverse_unique)
  1108   apply (simp_all add: fps_eq_iff fps_mult_nth setsum_zero_lemma)
  1110   apply (simp_all add: fps_eq_iff fps_mult_nth setsum_zero_lemma)
  1140 instantiation fps :: (field) ring_div
  1142 instantiation fps :: (field) ring_div
  1141 begin
  1143 begin
  1142 
  1144 
  1143 definition fps_mod_def:
  1145 definition fps_mod_def:
  1144   "f mod g = (if g = 0 then f else
  1146   "f mod g = (if g = 0 then f else
  1145      let n = subdegree g; h = fps_shift n g 
  1147      let n = subdegree g; h = fps_shift n g
  1146      in  fps_cutoff n (f * inverse h) * h)"
  1148      in  fps_cutoff n (f * inverse h) * h)"
  1147 
  1149 
  1148 lemma fps_mod_eq_zero: 
  1150 lemma fps_mod_eq_zero:
  1149   assumes "g \<noteq> 0" and "subdegree f \<ge> subdegree g"
  1151   assumes "g \<noteq> 0" and "subdegree f \<ge> subdegree g"
  1150   shows   "f mod g = 0"
  1152   shows   "f mod g = 0"
  1151   using assms by (cases "f = 0") (auto simp: fps_cutoff_zero_iff fps_mod_def Let_def)
  1153   using assms by (cases "f = 0") (auto simp: fps_cutoff_zero_iff fps_mod_def Let_def)
  1152 
  1154 
  1153 lemma fps_times_divide_eq: 
  1155 lemma fps_times_divide_eq:
  1154   assumes "g \<noteq> 0" and "subdegree f \<ge> subdegree (g :: 'a fps)"
  1156   assumes "g \<noteq> 0" and "subdegree f \<ge> subdegree (g :: 'a fps)"
  1155   shows   "f div g * g = f"
  1157   shows   "f div g * g = f"
  1156 proof (cases "f = 0")
  1158 proof (cases "f = 0")
  1157   assume nz: "f \<noteq> 0"
  1159   assume nz: "f \<noteq> 0"
  1158   def n \<equiv> "subdegree g"
  1160   def n \<equiv> "subdegree g"
  1159   def h \<equiv> "fps_shift n g"
  1161   def h \<equiv> "fps_shift n g"
  1160   from assms have [simp]: "h $ 0 \<noteq> 0" unfolding h_def by (simp add: n_def)
  1162   from assms have [simp]: "h $ 0 \<noteq> 0" unfolding h_def by (simp add: n_def)
  1161   
  1163 
  1162   from assms nz have "f div g * g = fps_shift n (f * inverse h) * g"
  1164   from assms nz have "f div g * g = fps_shift n (f * inverse h) * g"
  1163     by (simp add: fps_divide_def Let_def h_def n_def)
  1165     by (simp add: fps_divide_def Let_def h_def n_def)
  1164   also have "... = fps_shift n (f * inverse h) * X^n * h" unfolding h_def n_def
  1166   also have "... = fps_shift n (f * inverse h) * X^n * h" unfolding h_def n_def
  1165     by (subst subdegree_decompose[of g]) simp
  1167     by (subst subdegree_decompose[of g]) simp
  1166   also have "fps_shift n (f * inverse h) * X^n = f * inverse h"
  1168   also have "fps_shift n (f * inverse h) * X^n = f * inverse h"
  1168   also have "... * h = f * (inverse h * h)" by simp
  1170   also have "... * h = f * (inverse h * h)" by simp
  1169   also have "inverse h * h = 1" by (rule inverse_mult_eq_1) simp
  1171   also have "inverse h * h = 1" by (rule inverse_mult_eq_1) simp
  1170   finally show ?thesis by simp
  1172   finally show ?thesis by simp
  1171 qed (simp_all add: fps_divide_def Let_def)
  1173 qed (simp_all add: fps_divide_def Let_def)
  1172 
  1174 
  1173 lemma 
  1175 lemma
  1174   assumes "g$0 \<noteq> 0"
  1176   assumes "g$0 \<noteq> 0"
  1175   shows   fps_divide_unit: "f div g = f * inverse g" and fps_mod_unit [simp]: "f mod g = 0"
  1177   shows   fps_divide_unit: "f div g = f * inverse g" and fps_mod_unit [simp]: "f mod g = 0"
  1176 proof -
  1178 proof -
  1177   from assms have [simp]: "subdegree g = 0" by (simp add: subdegree_eq_0_iff)
  1179   from assms have [simp]: "subdegree g = 0" by (simp add: subdegree_eq_0_iff)
  1178   from assms show "f div g = f * inverse g" 
  1180   from assms show "f div g = f * inverse g"
  1179     by (auto simp: fps_divide_def Let_def subdegree_eq_0_iff)
  1181     by (auto simp: fps_divide_def Let_def subdegree_eq_0_iff)
  1180   from assms show "f mod g = 0" by (intro fps_mod_eq_zero) auto
  1182   from assms show "f mod g = 0" by (intro fps_mod_eq_zero) auto
  1181 qed
  1183 qed
  1182 
  1184 
  1183 context
  1185 context
  1188 proof (cases "g = 0")
  1190 proof (cases "g = 0")
  1189   assume "g \<noteq> 0"
  1191   assume "g \<noteq> 0"
  1190   from assms have "h \<noteq> 0" by auto
  1192   from assms have "h \<noteq> 0" by auto
  1191   note nz [simp] = \<open>g \<noteq> 0\<close> \<open>h \<noteq> 0\<close>
  1193   note nz [simp] = \<open>g \<noteq> 0\<close> \<open>h \<noteq> 0\<close>
  1192   from assms have [simp]: "subdegree h = 0" by (simp add: subdegree_eq_0_iff)
  1194   from assms have [simp]: "subdegree h = 0" by (simp add: subdegree_eq_0_iff)
  1193   
  1195 
  1194   have "(h * f) div (h * g) = 
  1196   have "(h * f) div (h * g) =
  1195           fps_shift (subdegree g) (h * f * inverse (fps_shift (subdegree g) (h*g)))"
  1197           fps_shift (subdegree g) (h * f * inverse (fps_shift (subdegree g) (h*g)))"
  1196     by (simp add: fps_divide_def Let_def)
  1198     by (simp add: fps_divide_def Let_def)
  1197   also have "h * f * inverse (fps_shift (subdegree g) (h*g)) = 
  1199   also have "h * f * inverse (fps_shift (subdegree g) (h*g)) =
  1198                (inverse h * h) * f * inverse (fps_shift (subdegree g) g)"
  1200                (inverse h * h) * f * inverse (fps_shift (subdegree g) g)"
  1199     by (subst fps_shift_mult) (simp_all add: algebra_simps fps_inverse_mult)
  1201     by (subst fps_shift_mult) (simp_all add: algebra_simps fps_inverse_mult)
  1200   also from assms have "inverse h * h = 1" by (rule inverse_mult_eq_1)
  1202   also from assms have "inverse h * h = 1" by (rule inverse_mult_eq_1)
  1201   finally show "(h * f) div (h * g) = f div g" by (simp_all add: fps_divide_def Let_def)
  1203   finally show "(h * f) div (h * g) = f div g" by (simp_all add: fps_divide_def Let_def)
  1202 qed (simp_all add: fps_divide_def)
  1204 qed (simp_all add: fps_divide_def)
  1203 
  1205 
  1204 private lemma fps_divide_cancel_aux2:
  1206 private lemma fps_divide_cancel_aux2:
  1205   "(f * X^m) div (g * X^m) = f div (g :: 'a :: field fps)"
  1207   "(f * X^m) div (g * X^m) = f div (g :: 'a :: field fps)"
  1206 proof (cases "g = 0")
  1208 proof (cases "g = 0")
  1207   assume [simp]: "g \<noteq> 0"
  1209   assume [simp]: "g \<noteq> 0"
  1208   have "(f * X^m) div (g * X^m) = 
  1210   have "(f * X^m) div (g * X^m) =
  1209           fps_shift (subdegree g + m) (f*inverse (fps_shift (subdegree g + m) (g*X^m))*X^m)"
  1211           fps_shift (subdegree g + m) (f*inverse (fps_shift (subdegree g + m) (g*X^m))*X^m)"
  1210     by (simp add: fps_divide_def Let_def algebra_simps)
  1212     by (simp add: fps_divide_def Let_def algebra_simps)
  1211   also have "... = f div g"
  1213   also have "... = f div g"
  1212     by (simp add: fps_shift_times_X_power'' fps_divide_def Let_def)
  1214     by (simp add: fps_shift_times_X_power'' fps_divide_def Let_def)
  1213   finally show ?thesis .
  1215   finally show ?thesis .
  1215 
  1217 
  1216 instance proof
  1218 instance proof
  1217   fix f g :: "'a fps"
  1219   fix f g :: "'a fps"
  1218   def n \<equiv> "subdegree g"
  1220   def n \<equiv> "subdegree g"
  1219   def h \<equiv> "fps_shift n g"
  1221   def h \<equiv> "fps_shift n g"
  1220   
  1222 
  1221   show "f div g * g + f mod g = f"
  1223   show "f div g * g + f mod g = f"
  1222   proof (cases "g = 0 \<or> f = 0")
  1224   proof (cases "g = 0 \<or> f = 0")
  1223     assume "\<not>(g = 0 \<or> f = 0)"
  1225     assume "\<not>(g = 0 \<or> f = 0)"
  1224     hence nz [simp]: "f \<noteq> 0" "g \<noteq> 0" by simp_all
  1226     hence nz [simp]: "f \<noteq> 0" "g \<noteq> 0" by simp_all
  1225     show ?thesis
  1227     show ?thesis
  1227       assume "subdegree f \<ge> subdegree g"
  1229       assume "subdegree f \<ge> subdegree g"
  1228       with nz show ?thesis by (simp add: fps_mod_eq_zero fps_times_divide_eq)
  1230       with nz show ?thesis by (simp add: fps_mod_eq_zero fps_times_divide_eq)
  1229     next
  1231     next
  1230       assume "subdegree f < subdegree g"
  1232       assume "subdegree f < subdegree g"
  1231       have g_decomp: "g = h * X^n" unfolding h_def n_def by (rule subdegree_decompose)
  1233       have g_decomp: "g = h * X^n" unfolding h_def n_def by (rule subdegree_decompose)
  1232       have "f div g * g + f mod g = 
  1234       have "f div g * g + f mod g =
  1233               fps_shift n (f * inverse h) * g + fps_cutoff n (f * inverse h) * h" 
  1235               fps_shift n (f * inverse h) * g + fps_cutoff n (f * inverse h) * h"
  1234         by (simp add: fps_mod_def fps_divide_def Let_def n_def h_def)
  1236         by (simp add: fps_mod_def fps_divide_def Let_def n_def h_def)
  1235       also have "... = h * (fps_shift n (f * inverse h) * X^n + fps_cutoff n (f * inverse h))"
  1237       also have "... = h * (fps_shift n (f * inverse h) * X^n + fps_cutoff n (f * inverse h))"
  1236         by (subst g_decomp) (simp add: algebra_simps)
  1238         by (subst g_decomp) (simp add: algebra_simps)
  1237       also have "... = f * (inverse h * h)"
  1239       also have "... = f * (inverse h * h)"
  1238         by (subst fps_shift_cutoff) simp
  1240         by (subst fps_shift_cutoff) simp
  1266     by (simp add: fps_divide_def Let_def dfs[symmetric] algebra_simps fps_shift_add)
  1268     by (simp add: fps_divide_def Let_def dfs[symmetric] algebra_simps fps_shift_add)
  1267   also have "h * inverse h' = (inverse h' * h') * X^n"
  1269   also have "h * inverse h' = (inverse h' * h') * X^n"
  1268     by (subst subdegree_decompose) (simp_all add: dfs)
  1270     by (subst subdegree_decompose) (simp_all add: dfs)
  1269   also have "... = X^n" by (subst inverse_mult_eq_1) (simp_all add: dfs)
  1271   also have "... = X^n" by (subst inverse_mult_eq_1) (simp_all add: dfs)
  1270   also have "fps_shift n (g * X^n) = g" by simp
  1272   also have "fps_shift n (g * X^n) = g" by simp
  1271   also have "fps_shift n (f * inverse h') = f div h" 
  1273   also have "fps_shift n (f * inverse h') = f div h"
  1272     by (simp add: fps_divide_def Let_def dfs)
  1274     by (simp add: fps_divide_def Let_def dfs)
  1273   finally show "(f + g * h) div h = g + f div h" by simp
  1275   finally show "(f + g * h) div h = g + f div h" by simp
  1274 qed (auto simp: fps_divide_def fps_mod_def Let_def)
  1276 qed (auto simp: fps_divide_def fps_mod_def Let_def)
  1275 
  1277 
  1276 end
  1278 end
  1295 
  1297 
  1296 lemma fps_divide_nth_0 [simp]: "g $ 0 \<noteq> 0 \<Longrightarrow> (f div g) $ 0 = f $ 0 / (g $ 0 :: _ :: field)"
  1298 lemma fps_divide_nth_0 [simp]: "g $ 0 \<noteq> 0 \<Longrightarrow> (f div g) $ 0 = f $ 0 / (g $ 0 :: _ :: field)"
  1297   by (simp add: fps_divide_unit divide_inverse)
  1299   by (simp add: fps_divide_unit divide_inverse)
  1298 
  1300 
  1299 
  1301 
  1300 lemma dvd_imp_subdegree_le: 
  1302 lemma dvd_imp_subdegree_le:
  1301   "(f :: 'a :: idom fps) dvd g \<Longrightarrow> g \<noteq> 0 \<Longrightarrow> subdegree f \<le> subdegree g"
  1303   "(f :: 'a :: idom fps) dvd g \<Longrightarrow> g \<noteq> 0 \<Longrightarrow> subdegree f \<le> subdegree g"
  1302   by (auto elim: dvdE)
  1304   by (auto elim: dvdE)
  1303 
  1305 
  1304 lemma fps_dvd_iff: 
  1306 lemma fps_dvd_iff:
  1305   assumes "(f :: 'a :: field fps) \<noteq> 0" "g \<noteq> 0"
  1307   assumes "(f :: 'a :: field fps) \<noteq> 0" "g \<noteq> 0"
  1306   shows   "f dvd g \<longleftrightarrow> subdegree f \<le> subdegree g"
  1308   shows   "f dvd g \<longleftrightarrow> subdegree f \<le> subdegree g"
  1307 proof
  1309 proof
  1308   assume "subdegree f \<le> subdegree g"
  1310   assume "subdegree f \<le> subdegree g"
  1309   with assms have "g mod f = 0" 
  1311   with assms have "g mod f = 0"
  1310     by (simp add: fps_mod_def Let_def fps_cutoff_zero_iff)
  1312     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)
  1313   thus "f dvd g" by (simp add: dvd_eq_mod_eq_0)
  1312 qed (simp add: assms dvd_imp_subdegree_le)
  1314 qed (simp add: assms dvd_imp_subdegree_le)
  1313 
  1315 
  1314 lemma fps_const_inverse: "inverse (fps_const (a::'a::field)) = fps_const (inverse a)"
  1316 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)
  1317   by (cases "a \<noteq> 0", rule fps_inverse_unique) (auto simp: fps_eq_iff)
  1316 
  1318 
  1317 lemma fps_const_divide: "fps_const (x :: _ :: field) / fps_const y = fps_const (x / y)"
  1319 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)
  1320   by (cases "y = 0") (simp_all add: fps_divide_unit fps_const_inverse divide_inverse)
  1319 
  1321 
  1320 lemma inverse_fps_numeral: 
  1322 lemma inverse_fps_numeral:
  1321   "inverse (numeral n :: ('a :: field_char_0) fps) = fps_const (inverse (numeral n))"
  1323   "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)
  1324   by (intro fps_inverse_unique fps_ext) (simp_all add: fps_numeral_nth)
  1323 
  1325 
  1324 
  1326 
  1325 
  1327 
  1326 
  1328 
  1327 instantiation fps :: (field) normalization_semidom
  1329 instantiation fps :: (field) normalization_semidom
  1328 begin
  1330 begin
  1329 
  1331 
  1330 definition fps_unit_factor_def [simp]: 
  1332 definition fps_unit_factor_def [simp]:
  1331   "unit_factor f = fps_shift (subdegree f) f"
  1333   "unit_factor f = fps_shift (subdegree f) f"
  1332 
  1334 
  1333 definition fps_normalize_def [simp]:
  1335 definition fps_normalize_def [simp]:
  1334   "normalize f = (if f = 0 then 0 else X ^ subdegree f)"
  1336   "normalize f = (if f = 0 then 0 else X ^ subdegree f)"
  1335 
  1337 
  1356 subsection \<open>Formal power series form a Euclidean ring\<close>
  1358 subsection \<open>Formal power series form a Euclidean ring\<close>
  1357 
  1359 
  1358 instantiation fps :: (field) euclidean_ring
  1360 instantiation fps :: (field) euclidean_ring
  1359 begin
  1361 begin
  1360 
  1362 
  1361 definition fps_euclidean_size_def: 
  1363 definition fps_euclidean_size_def:
  1362   "euclidean_size f = (if f = 0 then 0 else Suc (subdegree f))"
  1364   "euclidean_size f = (if f = 0 then 0 else Suc (subdegree f))"
  1363 
  1365 
  1364 instance proof
  1366 instance proof
  1365   fix f g :: "'a fps" assume [simp]: "g \<noteq> 0"
  1367   fix f g :: "'a fps" assume [simp]: "g \<noteq> 0"
  1366   show "euclidean_size f \<le> euclidean_size (f * g)"
  1368   show "euclidean_size f \<le> euclidean_size (f * g)"
  1393     fix d assume "d dvd f" "d dvd g"
  1395     fix d assume "d dvd f" "d dvd g"
  1394     thus "d dvd X ^ ?m" by (cases "d = 0") (auto simp: fps_dvd_iff)
  1396     thus "d dvd X ^ ?m" by (cases "d = 0") (auto simp: fps_dvd_iff)
  1395   qed (simp_all add: fps_dvd_iff)
  1397   qed (simp_all add: fps_dvd_iff)
  1396 qed
  1398 qed
  1397 
  1399 
  1398 lemma fps_gcd_altdef: "gcd (f :: 'a :: field fps) g = 
  1400 lemma fps_gcd_altdef: "gcd (f :: 'a :: field fps) g =
  1399   (if f = 0 \<and> g = 0 then 0 else
  1401   (if f = 0 \<and> g = 0 then 0 else
  1400    if f = 0 then X ^ subdegree g else 
  1402    if f = 0 then X ^ subdegree g else
  1401    if g = 0 then X ^ subdegree f else 
  1403    if g = 0 then X ^ subdegree f else
  1402      X ^ min (subdegree f) (subdegree g))"
  1404      X ^ min (subdegree f) (subdegree g))"
  1403   by (simp add: fps_gcd)
  1405   by (simp add: fps_gcd)
  1404 
  1406 
  1405 lemma fps_lcm:
  1407 lemma fps_lcm:
  1406   assumes [simp]: "f \<noteq> 0" "g \<noteq> 0"
  1408   assumes [simp]: "f \<noteq> 0" "g \<noteq> 0"
  1412     fix d assume "f dvd d" "g dvd d"
  1414     fix d assume "f dvd d" "g dvd d"
  1413     thus "X ^ ?m dvd d" by (cases "d = 0") (auto simp: fps_dvd_iff)
  1415     thus "X ^ ?m dvd d" by (cases "d = 0") (auto simp: fps_dvd_iff)
  1414   qed (simp_all add: fps_dvd_iff)
  1416   qed (simp_all add: fps_dvd_iff)
  1415 qed
  1417 qed
  1416 
  1418 
  1417 lemma fps_lcm_altdef: "lcm (f :: 'a :: field fps) g = 
  1419 lemma fps_lcm_altdef: "lcm (f :: 'a :: field fps) g =
  1418   (if f = 0 \<or> g = 0 then 0 else X ^ max (subdegree f) (subdegree g))"
  1420   (if f = 0 \<or> g = 0 then 0 else X ^ max (subdegree f) (subdegree g))"
  1419   by (simp add: fps_lcm)
  1421   by (simp add: fps_lcm)
  1420 
  1422 
  1421 lemma fps_Gcd:
  1423 lemma fps_Gcd:
  1422   assumes "A - {0} \<noteq> {}"
  1424   assumes "A - {0} \<noteq> {}"
  1432   from d assms have "subdegree d \<le> (INF f:A-{0}. subdegree f)"
  1434   from d assms have "subdegree d \<le> (INF f:A-{0}. subdegree f)"
  1433     by (intro cINF_greatest) (auto simp: fps_dvd_iff[symmetric])
  1435     by (intro cINF_greatest) (auto simp: fps_dvd_iff[symmetric])
  1434   with d assms show "d dvd X ^ (INF f:A-{0}. subdegree f)" by (simp add: fps_dvd_iff)
  1436   with d assms show "d dvd X ^ (INF f:A-{0}. subdegree f)" by (simp add: fps_dvd_iff)
  1435 qed simp_all
  1437 qed simp_all
  1436 
  1438 
  1437 lemma fps_Gcd_altdef: "Gcd (A :: 'a :: field fps set) = 
  1439 lemma fps_Gcd_altdef: "Gcd (A :: 'a :: field fps set) =
  1438   (if A \<subseteq> {0} then 0 else X ^ (INF f:A-{0}. subdegree f))"
  1440   (if A \<subseteq> {0} then 0 else X ^ (INF f:A-{0}. subdegree f))"
  1439   using fps_Gcd by auto
  1441   using fps_Gcd by auto
  1440 
  1442 
  1441 lemma fps_Lcm:
  1443 lemma fps_Lcm:
  1442   assumes "A \<noteq> {}" "0 \<notin> A" "bdd_above (subdegree`A)"
  1444   assumes "A \<noteq> {}" "0 \<notin> A" "bdd_above (subdegree`A)"
  1458     with \<open>d \<noteq> 0\<close> show ?thesis by (simp add: fps_dvd_iff)
  1460     with \<open>d \<noteq> 0\<close> show ?thesis by (simp add: fps_dvd_iff)
  1459   qed simp_all
  1461   qed simp_all
  1460 qed simp_all
  1462 qed simp_all
  1461 
  1463 
  1462 lemma fps_Lcm_altdef:
  1464 lemma fps_Lcm_altdef:
  1463   "Lcm (A :: 'a :: field fps set) = 
  1465   "Lcm (A :: 'a :: field fps set) =
  1464      (if 0 \<in> A \<or> \<not>bdd_above (subdegree`A) then 0 else
  1466      (if 0 \<in> A \<or> \<not>bdd_above (subdegree`A) then 0 else
  1465       if A = {} then 1 else X ^ (SUP f:A. subdegree f))"
  1467       if A = {} then 1 else X ^ (SUP f:A. subdegree f))"
  1466 proof (cases "bdd_above (subdegree`A)")
  1468 proof (cases "bdd_above (subdegree`A)")
  1467   assume unbounded: "\<not>bdd_above (subdegree`A)"
  1469   assume unbounded: "\<not>bdd_above (subdegree`A)"
  1468   have "Lcm A = 0"
  1470   have "Lcm A = 0"
  2874       by (simp add: fps_divide_unit fps_mult_nth fps_inverse_def nonzero_imp_inverse_nonzero)
  2876       by (simp add: fps_divide_unit fps_mult_nth fps_inverse_def nonzero_imp_inverse_nonzero)
  2875     note tha[simp] = iffD1[OF power_radical[where r=r and k=h], OF a0 ra0[unfolded k], unfolded k[symmetric]]
  2877     note tha[simp] = iffD1[OF power_radical[where r=r and k=h], OF a0 ra0[unfolded k], unfolded k[symmetric]]
  2876     note thb[simp] = iffD1[OF power_radical[where r=r and k=h], OF b0 rb0[unfolded k], unfolded k[symmetric]]
  2878     note thb[simp] = iffD1[OF power_radical[where r=r and k=h], OF b0 rb0[unfolded k], unfolded k[symmetric]]
  2877     from b0 rb0' have th2: "(?r a / ?r b)^k = a/b"
  2879     from b0 rb0' have th2: "(?r a / ?r b)^k = a/b"
  2878       by (simp add: fps_divide_unit power_mult_distrib fps_inverse_power[symmetric])
  2880       by (simp add: fps_divide_unit power_mult_distrib fps_inverse_power[symmetric])
  2879       
  2881 
  2880     from iffD1[OF radical_unique[where r=r and a="?r a / ?r b" and b="a/b" and k=h], symmetric, unfolded k[symmetric], OF th0 th1 ab0' th2]
  2882     from iffD1[OF radical_unique[where r=r and a="?r a / ?r b" and b="a/b" and k=h], symmetric, unfolded k[symmetric], OF th0 th1 ab0' th2]
  2881     show ?thesis .
  2883     show ?thesis .
  2882   qed
  2884   qed
  2883 qed
  2885 qed
  2884 
  2886 
  4176 
  4178 
  4177 lemma fps_tan_deriv: "fps_deriv (fps_tan c) = fps_const c / (fps_cos c)\<^sup>2"
  4179 lemma fps_tan_deriv: "fps_deriv (fps_tan c) = fps_const c / (fps_cos c)\<^sup>2"
  4178 proof -
  4180 proof -
  4179   have th0: "fps_cos c $ 0 \<noteq> 0" by (simp add: fps_cos_def)
  4181   have th0: "fps_cos c $ 0 \<noteq> 0" by (simp add: fps_cos_def)
  4180   from this have "fps_cos c \<noteq> 0" by (intro notI) simp
  4182   from this have "fps_cos c \<noteq> 0" by (intro notI) simp
  4181   hence "fps_deriv (fps_tan c) = 
  4183   hence "fps_deriv (fps_tan c) =
  4182            fps_const c * (fps_cos c^2 + fps_sin c^2) / (fps_cos c^2)"
  4184            fps_const c * (fps_cos c^2 + fps_sin c^2) / (fps_cos c^2)"
  4183     by (simp add: fps_tan_def fps_divide_deriv power2_eq_square algebra_simps 
  4185     by (simp add: fps_tan_def fps_divide_deriv power2_eq_square algebra_simps
  4184                   fps_sin_deriv fps_cos_deriv fps_const_neg[symmetric] div_mult_swap
  4186                   fps_sin_deriv fps_cos_deriv fps_const_neg[symmetric] div_mult_swap
  4185              del: fps_const_neg)
  4187              del: fps_const_neg)
  4186   also note fps_sin_cos_sum_of_squares
  4188   also note fps_sin_cos_sum_of_squares
  4187   finally show ?thesis by simp
  4189   finally show ?thesis by simp
  4188 qed
  4190 qed