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 |