lemmas fls_eqI = iffD1[OF fls_nth_inject, OF iffD2, OF fun_eq_iff, OF allI]
lemma fls_eq_iff: "f = g ⟷ (∀n. f $$ n = g $$ n)" by (simp add: fls_nth_inject[symmetric] fun_eq_iff)
lemma nth_Abs_fls [simp]: "∀🪙∞n. f (- int n) = 0 ==> Abs_fls f $$ n = f n" by (simp add: Abs_fls_inverse[OF CollectI])
lemmas nth_Abs_fls_finite_nonzero_neg_nth = nth_Abs_fls[OF iffD2, OF eventually_cofinite] lemmas nth_Abs_fls_ex_nat_lower_bound = nth_Abs_fls[OF iffD2, OF MOST_nat] lemmas nth_Abs_fls_nat_lower_bound = nth_Abs_fls_ex_nat_lower_bound[OF exI]
lemma nth_Abs_fls_ex_lower_bound: assumes"∃N. ∀n shows"Abs_fls f $$ n = f n" proof (intro nth_Abs_fls_ex_nat_lower_bound) from assms obtain N::int where"∀nby fast hence"∀n > (if N < 0 then nat (-N) else 0). f (-int n) = 0"by auto thus"∃M. ∀n>M. f (- int n) = 0"by fast qed
lemma fls_nth_vanishes_below_natE: fixes f :: "'a::zero fls" obtains N :: nat where"∀n>N. f$$(-int n) = 0" using iffD1[OF MOST_nat MOST_fls_neg_nth_eq_0] by blast
lemma fls_nth_vanishes_belowE: fixes f :: "'a::zero fls" obtains N :: int where"∀n
proof- obtain K :: nat where K: "∀n>K. f$$(-int n) = 0"by (elim fls_nth_vanishes_below_natE) have"∀n < -int K. f$$n = 0" proof clarify fix n assume n: "n < -int K"
define m where"m ≡ nat (-n)" with n have"m > K"by simp moreoverfrom n m_def have"f$$n = f $$ (-int m)"by simp ultimatelyshow"f $$ n = 0"using K by simp qed thus"(∧N. ∀n==> thesis) ==> thesis"by fast qed
subsubsection ‹Definition of basic Laurent series›
instantiation fls :: (zero) zero begin
lift_definition zero_fls :: "'a fls"is"λ_. 0"by simp instance .. end
lemma fls_zero_nth [simp]: "0 $$ n = 0" by (simp add: zero_fls_def)
lemma fls_zero_eqI: "(∧n. f$$n = 0) ==> f = 0" by (fastforce intro: fls_eqI)
lemma fls_nonzeroI: "f$$n ≠ 0 ==> f ≠ 0" by auto
lemma fls_nonzero_nth: "f ≠ 0 ⟷ (∃ n. f $$ n ≠ 0)" using fls_zero_eqI by fastforce
lemma fls_trivial_delta_eq_zero [simp]: "b = 0 ==> Abs_fls (λn. if n=a then b else 0) = 0" by (intro fls_zero_eqI) simp
lemma fls_delta_nth [simp]: "Abs_fls (λn. if n=a then b else 0) $$ n = (if n=a then b else 0)" using nth_Abs_fls_lower_bound[of a "λn. if n=a then b else 0"] by simp
instantiation fls :: ("{zero,one}") one begin
lift_definition one_fls :: "'a fls"is"λk. if k = 0 then 1 else 0" by (simp add: eventually_cofinite) instance .. end
lemma fls_one_nth [simp]: "1 $$ n = (if n = 0 then 1 else 0)" by (simp add: one_fls_def eventually_cofinite)
lemma fls_const_eq_1_iff [simp]: "fls_const c = 1 ⟷ c = 1" by (auto simp: fls_eq_iff)
lift_definition fls_X :: "'a::{zero,one} fls" is"λn. if n = 1 then 1 else 0" by simp
lemma fls_X_nth [simp]: "fls_X $$ n = (if n = 1 then 1 else 0)" by (simp add: fls_X_def)
lemma fls_X_nonzero [simp]: "(fls_X :: 'a :: zero_neq_one fls) ≠ 0" by (intro fls_nonzeroI) simp
lift_definition fls_X_inv :: "'a::{zero,one} fls" is"λn. if n = -1 then 1 else 0" by (simp add: eventually_cofinite)
lemma fls_X_inv_nth [simp]: "fls_X_inv $$ n = (if n = -1 then 1 else 0)" by (simp add: fls_X_inv_def eventually_cofinite)
lemma fls_X_inv_nonzero [simp]: "(fls_X_inv :: 'a :: zero_neq_one fls) ≠ 0" by (intro fls_nonzeroI) simp
subsection‹Subdegrees›
lemma unique_fls_subdegree: assumes"f ≠ 0" shows"∃!n. f$$n ≠ 0 ∧ (∀m. f$$m ≠ 0 ⟶ n ≤ m)"
proof- obtain N::nat where N: "∀n>N. f$$(-int n) = 0"by (elim fls_nth_vanishes_below_natE)
define M where"M ≡ -int N" have M: "∧m. f$$m ≠ 0 ==> M ≤ m"
proof- fix m assume m: "f$$m ≠ 0" show"M ≤ m" proof (cases "m<0") case True with m N M_def show ?thesis using allE[OF N, of "nat (-m)" False] by force qed (simp add: M_def) qed have"¬ (∀k::nat. f$$(M + int k) = 0)" proof assume above0: "∀k::nat. f$$(M + int k) = 0" have"f=0" proof (rule fls_zero_eqI) fix n show"f$$n = 0" proof (cases "M ≤ n") case True
define k where"k = nat (n - M)" from True have"n = M + int k"by (simp add: k_def) with above0 show ?thesis by simp next case False with M show ?thesis by auto qed qed with assms show False by fast qed hence ex_k: "∃k::nat. f$$(M + int k) ≠ 0"by fast
define k where"k ≡ (LEAST k::nat. f$$(M + int k) ≠ 0)"
define n where"n ≡ M + int k" from k_def n_def have fn: "f$$n ≠ 0"using LeastI_ex[OF ex_k] by simp moreoverhave"∀m. f$$m ≠ 0 ⟶ n ≤ m" proof (clarify) fix m assume m: "f$$m ≠ 0" with M have"M ≤ m"by fast
define l where"l = nat (m - M)" from‹M ≤ m›have l: "m = M + int l"by (simp add: l_def) with n_def m k_def l show"n ≤ m" using Least_le[of "λk. f$$(M + int k) ≠ 0" l] by auto qed moreoverhave"∧n'. f$$n' ≠ 0 ==> (∀m. f$$m ≠ 0 ⟶ n' ≤ m) ==> n' = n"
proof- fix n' :: int assume n': "f$$n' ≠ 0""∀m. f$$m ≠ 0 ⟶ n' ≤ m" from n'(1) M have"M ≤ n'"by fast
define l where"l = nat (n' - M)" from‹M ≤ n'›have l: "n' = M + int l"by (simp add: l_def) with n_def k_def n' fn show"n' = n" using Least_le[of "λk. f$$(M + int k) ≠ 0" l] by force qed ultimatelyshow ?thesis using ex1I[of "λn. f$$n ≠ 0 ∧ (∀m. f$$m ≠ 0 ⟶ n ≤ m)" n] by blast qed
definition fls_subdegree :: "('a::zero) fls ==> int" where"fls_subdegree f ≡ (if f = 0 then 0 else LEAST n::int. f$$n ≠ 0)"
lemma nth_fls_subdegree_nonzero [simp]: "f ≠ 0 ==> f $$ fls_subdegree f ≠ 0" using Least1I[OF unique_fls_subdegree] by (simp add: fls_subdegree_def)
lemma nth_fls_subdegree_zero_iff: "(f $$ fls_subdegree f = 0) ⟷ (f = 0)" using nth_fls_subdegree_nonzero by auto
lemma fls_subdegree_leI: "f $$ n ≠ 0 ==> fls_subdegree f ≤ n" using Least1_le[OF unique_fls_subdegree] by (auto simp: fls_subdegree_def)
lemma fls_subdegree_leI': "f $$ n ≠ 0 ==> n ≤ m ==> fls_subdegree f ≤ m" using fls_subdegree_leI by fastforce
lemma fls_eq0_below_subdegree [simp]: "n < fls_subdegree f ==> f $$ n = 0" using fls_subdegree_leI by fastforce
lemma fls_subdegree_geI: "f ≠ 0 ==> (∧k. k < n ==> f $$ k = 0) ==> n ≤ fls_subdegree f" using nth_fls_subdegree_nonzero by force
lemma fls_subdegree_ge0I: "(∧k. k < 0 ==> f $$ k = 0) ==> 0 ≤ fls_subdegree f" using fls_subdegree_geI[of f 0] by (cases "f=0") auto
lemma fls_subdegree_greaterI: assumes"f ≠ 0""∧k. k ≤ n ==> f $$ k = 0" shows"n < fls_subdegree f" using assms(1) assms(2)[of "fls_subdegree f"] nth_fls_subdegree_nonzero[of f] by force
lemma fls_subdegree_eqI: "f $$ n ≠ 0 ==> (∧k. k < n ==> f $$ k = 0) ==> fls_subdegree f = n" using fls_subdegree_leI fls_subdegree_geI[of f] by fastforce
lemma fls_delta_subdegree [simp]: "b ≠ 0 ==> fls_subdegree (Abs_fls (λn. if n=a then b else 0)) = a" by (intro fls_subdegree_eqI) simp_all
lemma fls_delta0_subdegree: "fls_subdegree (Abs_fls (λn. if n=0 then a else 0)) = 0" by (cases "a=0") simp_all
lemma fls_eq_above_subdegreeI: assumes"N ≤ fls_subdegree f""N ≤ fls_subdegree g""∀k≥N. f $$ k = g $$ k" shows"f = g" proof (rule fls_eqI) fix n from assms show"f $$ n = g $$ n"by (cases "n < N") auto qed
subsection‹Shifting›
subsubsection ‹Shift definition›
definition fls_shift :: "int ==> ('a::zero) fls ==> 'a fls" where"fls_shift n f ≡ Abs_fls (λk. f $$ (k+n))" 🍋‹Since the index set is unbounded in both directions, we can shift in either direction.›
lemma fls_shift_nth [simp]: "fls_shift m f $$ n = f $$ (n+m)" unfolding fls_shift_def proof (rule nth_Abs_fls_ex_lower_bound) obtain K::int where K: "∀nby (elim fls_nth_vanishes_belowE) hence"∀nby auto thus"∃N. ∀nby fast qed
lemma fls_shift_eq_iff: "(fls_shift m f = fls_shift m g) ⟷ (f = g)" proof (rule iffI, rule fls_eqI) fix k assume 1: "fls_shift m f = fls_shift m g" have"f $$ k = fls_shift m g $$ (k - m)"by (simp add: 1[symmetric]) thus"f $$ k = g $$ k"by simp qed (intro fls_eqI, simp)
lemma fls_shift_0 [simp]: "fls_shift 0 f = f" by (intro fls_eqI) simp
lemma fls_shift_subdegree [simp]: "f ≠ 0 ==> fls_subdegree (fls_shift n f) = fls_subdegree f - n" by (intro fls_subdegree_eqI) simp_all
lemma fls_shift_fls_shift [simp]: "fls_shift m (fls_shift k f) = fls_shift (k+m) f" by (intro fls_eqI) (simp add: algebra_simps)
lemma fls_shift_fls_shift_reorder: "fls_shift m (fls_shift k f) = fls_shift k (fls_shift m f)" using fls_shift_fls_shift[of m k f] fls_shift_fls_shift[of k m f] by (simp add: add.commute)
lemma fls_shift_zero [simp]: "fls_shift m 0 = 0" by (intro fls_zero_eqI) simp
lemma fls_shift_eq0_iff: "fls_shift m f = 0 ⟷ f = 0" using fls_shift_eq_iff[of m f 0] by simp
lemma fls_shift_eq_1_iff: "fls_shift n f = 1 ⟷ f = fls_shift (-n) 1" by (metis add_minus_cancel fls_shift_eq_iff fls_shift_fls_shift)
lemma fls_shift_nonneg_subdegree: "m ≤ fls_subdegree f ==> fls_subdegree (fls_shift m f) ≥ 0" by (cases "f=0") (auto intro: fls_subdegree_geI)
lemma fls_shift_delta: "fls_shift m (Abs_fls (λn. if n=a then b else 0)) = Abs_fls (λn. if n=a-m then b else 0)" by (intro fls_eqI) simp
lemma fls_shift_const: "fls_shift m (fls_const c) = Abs_fls (λn. if n=-m then c else 0)" by (intro fls_eqI) simp
lemma fls_shift_const_nth: "fls_shift m (fls_const c) $$ n = (if n=-m then c else 0)" by (simp add: fls_shift_const)
text‹ Similarly to the @{const unit_factor} for formal power series, we can decompose a formal Laurent series as a power of the implied variable times a series of subdegree 0. (See lemma @{text "fls_base_factor_X_power_decompose"}.) But we will call this something other @{const unit_factor} because it will not satisfy assumption @{text "is_unit_unit_factor"} of @{class semidom_divide_unit_factor}. ›
definition fls_base_factor :: "('a::zero) fls ==> 'a fls" where fls_base_factor_def[simp]: "fls_base_factor f = fls_shift (fls_subdegree f) f"
lemma fls_base_factor_nth: "fls_base_factor f $$ n = f $$ (n + fls_subdegree f)" by simp
lemma fls_base_factor_nonzero [simp]: "f ≠ 0 ==> fls_base_factor f ≠ 0" using fls_nonzeroI[of "fls_base_factor f" 0] by simp
lemma fls_base_factor_subdegree [simp]: "fls_subdegree (fls_base_factor f) = 0" by (cases "f=0") auto
lemma fls_base_factor_base [simp]: "fls_base_factor f $$ fls_subdegree (fls_base_factor f) = f $$ fls_subdegree f" using fls_base_factor_subdegree[of f] by simp
lemma fls_regpart_Abs_fls: "∀🪙∞n. F (- int n) = 0 ==> fls_regpart (Abs_fls F) = Abs_fps (λn. F (int n))" by (intro fps_ext) auto
lemma fls_regpart_delta: "fls_regpart (Abs_fls (λn. if n=a then b else 0)) = (if a < 0 then 0 else Abs_fps (λn. if n=nat a then b else 0))" by (rule fps_ext, auto)
lemma fls_regpart_const [simp]: "fls_regpart (fls_const c) = fps_const c" by (intro fps_ext) simp
lemma fls_regpart_eq0_imp_nonpos_subdegree: assumes"fls_regpart f = 0" shows"fls_subdegree f ≤ 0" proof (cases "f=0") case False have"fls_subdegree f ≥ 0 ==> f $$ fls_subdegree f = 0"
proof- assume"fls_subdegree f ≥ 0" hence"f $$ (fls_subdegree f) = (fls_regpart f) $ (nat (fls_subdegree f))"by simp with assms show"f $$ (fls_subdegree f) = 0"by simp qed with False show ?thesis by fastforce qed simp
lemma fls_subdegree_lt_fls_regpart_subdegree: "fls_subdegree f ≤ int (subdegree (fls_regpart f))" using fls_subdegree_leI nth_subdegree_nonzero[of "fls_regpart f"] by (cases "(fls_regpart f) = 0")
(simp_all add: fls_regpart_eq0_imp_nonpos_subdegree)
lemma fls_regpart_subdegree_conv: assumes"fls_subdegree f ≥ 0" shows"subdegree (fls_regpart f) = nat (fls_subdegree f)" 🍋‹ This is the best we can do since if the subdegree is negative, we might still have the bad luck that the term at index 0 is equal to 0. › proof (cases "f=0") case False with assms show ?thesis by (intro subdegreeI) simp_all qed simp
lemma fls_eq_conv_fps_eqI: assumes"0 ≤ fls_subdegree f""0 ≤ fls_subdegree g""fls_regpart f = fls_regpart g" shows"f = g" proof (rule fls_eq_above_subdegreeI, rule assms(1), rule assms(2), clarify) fix k::int assume"0 ≤ k" with assms(3) show"f $$ k = g $$ k" using fls_regpart_nth[of f "nat k"] fls_regpart_nth[of g] by simp qed
lemma fls_regpart_shift_conv_fps_shift: "m ≥ 0 ==> fls_regpart (fls_shift m f) = fps_shift (nat m) (fls_regpart f)" by (intro fps_ext) simp_all
lemma fps_shift_fls_regpart_conv_fls_shift: "fps_shift m (fls_regpart f) = fls_regpart (fls_shift m f)" by (intro fps_ext) simp_all
lemma fps_unit_factor_fls_regpart: "fls_subdegree f ≥ 0 ==> unit_factor (fls_regpart f) = fls_regpart (fls_base_factor f)" by (auto intro: fps_ext simp: fls_regpart_subdegree_conv)
text‹ The terms below the zeroth form a polynomial in the inverse of the implied variable, called the principle part. ›
lift_definition fls_prpart :: "('a::zero) fls ==> 'a poly" is"λf. Abs_poly (λn. if n = 0 then 0 else f (- int n))"
.
lemma fls_prpart_coeff [simp]: "coeff (fls_prpart f) n = (if n = 0 then 0 else f $$ (- int n))"
proof- have"{x. (if x = 0 then 0 else f $$ - int x) ≠ 0} ⊆ {x. f $$ - int x ≠ 0}" by auto hence"finite {x. (if x = 0 then 0 else f $$ - int x) ≠ 0}" using fls_finite_nonzero_neg_nth[of f] by (simp add: rev_finite_subset) hence"coeff (fls_prpart f) = (λn. if n = 0 then 0 else f $$ (- int n))" using Abs_poly_inverse[OF CollectI, OF iffD2, OF eventually_cofinite] by (simp add: fls_prpart_def) thus ?thesis by simp qed
lemma fls_prpart_eq0_iff: "(fls_prpart f = 0) ⟷ (fls_subdegree f ≥ 0)" proof assume 1: "fls_prpart f = 0" show"fls_subdegree f ≥ 0" proof (intro fls_subdegree_ge0I) fix k::int assume"k < 0" with 1 show"f $$ k = 0"using fls_prpart_coeff[of f "nat (-k)"] by simp qed qed (intro poly_eqI, simp)
lemma fls_prpart_X_inv: "fls_prpart fls_X_inv = [:0,1:]" proof (intro poly_eqI) fix n show"coeff (fls_prpart fls_X_inv) n = coeff [:0,1:] n" proof (cases n) case (Suc i) thus ?thesis by (cases i) simp_all qed simp qed
lemma degree_fls_prpart [simp]: "degree (fls_prpart f) = nat (-fls_subdegree f)" proof (cases "f=0") case False show ?thesis unfolding degree_def proof (intro Least_equality) fix N assume N: "∀i>N. coeff (fls_prpart f) i = 0" have"∀i < -int N. f $$ i = 0" proof clarify fix i assume i: "i < -int N" hence"nat (-i) > N"by simp with N i show"f $$ i = 0"using fls_prpart_coeff[of f "nat (-i)"] by auto qed with False have"fls_subdegree f ≥ -int N"using fls_subdegree_geI by auto thus"nat (- fls_subdegree f) ≤ N"by simp qed auto qed simp
lemma fls_prpart_shift: assumes"m ≤ 0" shows"fls_prpart (fls_shift m f) = pCons 0 (poly_shift (Suc (nat (-m))) (fls_prpart f))" proof (intro poly_eqI) fix n
define LHS RHS where"LHS ≡ fls_prpart (fls_shift m f)" and"RHS ≡ pCons 0 (poly_shift (Suc (nat (-m))) (fls_prpart f))" show"coeff LHS n = coeff RHS n" proof (cases n) case (Suc k) from assms have 1: "-int (Suc k + nat (-m)) = -int (Suc k) + m"by simp have"coeff RHS n = f $$ (-int (Suc k) + m)" using arg_cong[OF 1, of "($$) f"] by (simp add: Suc RHS_def coeff_poly_shift) with Suc show ?thesis by (simp add: LHS_def) qed (simp add: LHS_def RHS_def) qed
lemma fls_prpart_base_factor: "fls_prpart (fls_base_factor f) = 0" using fls_base_factor_subdegree[of f] by (simp add: fls_prpart_eq0_iff)
text‹The essential data of a formal Laurant series resides from the subdegree up.›
abbreviation fls_base_factor_to_fps :: "('a::zero) fls ==> 'a fps" where"fls_base_factor_to_fps f ≡ fls_regpart (fls_base_factor f)"
lemma fls_base_factor_to_fps_conv_fps_shift: assumes"fls_subdegree f ≥ 0" shows"fls_base_factor_to_fps f = fps_shift (nat (fls_subdegree f)) (fls_regpart f)" by (simp add: assms fls_regpart_shift_conv_fps_shift)
lemma fls_base_factor_to_fps_nth: "fls_base_factor_to_fps f $ n = f $$ (fls_subdegree f + int n)" by (simp add: algebra_simps)
lemma fls_base_factor_to_fps_base: "f ≠ 0 ==> fls_base_factor_to_fps f $ 0 ≠ 0" by simp
lemma fls_base_factor_to_fps_nonzero: "f ≠ 0 ==> fls_base_factor_to_fps f ≠ 0" using fps_nonzeroI[of "fls_base_factor_to_fps f" 0] fls_base_factor_to_fps_base by simp
lemma fls_base_factor_to_fps_subdegree [simp]: "subdegree (fls_base_factor_to_fps f) = 0" by (cases "f=0") auto
lemma fls_base_factor_to_fps_trivial: "fls_subdegree f = 0 ==> fls_base_factor_to_fps f = fls_regpart f" by simp
lemma fls_base_factor_to_fps_zero: "fls_base_factor_to_fps 0 = 0" by simp
lemma fls_base_factor_to_fps_one: "fls_base_factor_to_fps 1 = 1" by simp
lemma fls_base_factor_to_fps_delta: "fls_base_factor_to_fps (Abs_fls (λn. if n=a then c else 0)) = fps_const c" using fls_base_factor_delta[of a c] by simp
lemma fls_base_factor_to_fps_const: "fls_base_factor_to_fps (fls_const c) = fps_const c" by simp
lemma fls_base_factor_to_fps_X: "fls_base_factor_to_fps (fls_X::'a::{zero_neq_one} fls) = 1" by simp
lemma fls_base_factor_to_fps_X_inv: "fls_base_factor_to_fps (fls_X_inv::'a::{zero_neq_one} fls) = 1" by simp
lemma fls_base_factor_to_fps_shift: "fls_base_factor_to_fps (fls_shift m f) = fls_base_factor_to_fps f" using fls_base_factor_shift[of m f] by simp
lemma fls_base_factor_to_fps_base_factor: "fls_base_factor_to_fps (fls_base_factor f) = fls_base_factor_to_fps f" using fls_base_factor_to_fps_shift by simp
lemma fps_unit_factor_fls_base_factor: "unit_factor (fls_base_factor_to_fps f) = fls_base_factor_to_fps f" using fls_base_factor_to_fps_subdegree[of f] by simp
subsubsection ‹Converting power to Laurent series›
text‹We can extend a power series by 0s below to create a Laurent series.›
definition fps_to_fls :: "('a::zero) fps ==> 'a fls" where"fps_to_fls f ≡ Abs_fls (λk::int. if k<0 then 0 else f $ (nat k))"
lemma fps_to_fls_nth [simp]: "(fps_to_fls f) $$ n = (if n < 0 then 0 else f$(nat n))" using nth_Abs_fls_lower_bound[of 0 "(λk::int. if k<0 then 0 else f $ (nat k))"] unfolding fps_to_fls_def by simp
lemma fps_to_fls_eq_imp_fps_eq: assumes"fps_to_fls f = fps_to_fls g" shows"f = g" proof (intro fps_ext) fix n have"f $ n = fps_to_fls g $$ int n"by (simp add: assms[symmetric]) thus"f $ n = g $ n"by simp qed
lemma fps_to_fls_eq_iff [simp]: "fps_to_fls f = fps_to_fls g ⟷ f = g" using fps_to_fls_eq_imp_fps_eq by blast
lemma fps_to_fls_Abs_fps: "fps_to_fls (Abs_fps F) = Abs_fls (λn. if n<0 then 0 else F (nat n))" using nth_Abs_fls_lower_bound[of 0 "(λn::int. if n<0 then 0 else F (nat n))"] by (intro fls_eqI) simp
lemma fps_delta_to_fls: "fps_to_fls (Abs_fps (λn. if n=a then b else 0)) = Abs_fls (λn. if n=int a then b else 0)" using fls_eqI[of _ "Abs_fls (λn. if n=int a then b else 0)"] by force
lemma fps_const_to_fls [simp]: "fps_to_fls (fps_const c) = fls_const c" by (intro fls_eqI) simp
lemma fps_to_fls_eq_0_iff [simp]: "(fps_to_fls f = 0) ⟷ (f=0)" using fps_to_fls_nonzeroI by auto
lemma fps_to_fls_eq_1_iff [simp]: "fps_to_fls f = 1 ⟷ f = 1" using fps_to_fls_eq_iff by fastforce
lemma fls_subdegree_fls_to_fps_gt0: "fls_subdegree (fps_to_fls f) ≥ 0" proof (cases "f=0") case False show ?thesis proof (rule fls_subdegree_geI, rule fls_nonzeroI) from False show"fps_to_fls f $$ int (subdegree f) ≠ 0" by simp qed simp qed simp
lemma fls_subdegree_fls_to_fps: "fls_subdegree (fps_to_fls f) = int (subdegree f)" proof (cases "f=0") case False have"subdegree f = nat (fls_subdegree (fps_to_fls f))" proof (rule subdegreeI) from False show"f $ (nat (fls_subdegree (fps_to_fls f))) ≠ 0" using fls_subdegree_fls_to_fps_gt0[of f] nth_fls_subdegree_nonzero[of "fps_to_fls f"]
fps_to_fls_nonzeroI[of f] by simp next fix k assume k: "k < nat (fls_subdegree (fps_to_fls f))" thus"f $ k = 0" using fls_eq0_below_subdegree[of "int k""fps_to_fls f"] by simp qed thus ?thesis by (simp add: fls_subdegree_fls_to_fps_gt0) qed simp
lemma fps_shift_to_fls [simp]: "n ≤ subdegree f ==> fps_to_fls (fps_shift n f) = fls_shift (int n) (fps_to_fls f)" by (auto intro: fls_eqI simp: nat_add_distrib nth_less_subdegree_zero)
lemma fls_base_factor_fps_to_fls: "fls_base_factor (fps_to_fls f) = fps_to_fls (unit_factor f)" using nth_less_subdegree_zero[of _ f] by (auto intro: fls_eqI simp: fls_subdegree_fls_to_fps nat_add_distrib)
lemma fls_regpart_to_fls_trivial [simp]: "fls_subdegree f ≥ 0 ==> fps_to_fls (fls_regpart f) = f" by (intro fls_eqI) simp
lemma fls_conv_base_factor_to_fps_shift_subdegree: "f = fls_shift (-fls_subdegree f) (fps_to_fls (fls_base_factor_to_fps f))" using fps_to_fls_base_factor_to_fps[of f] fps_to_fls_base_factor_to_fps[of f] by simp
lemma fls_base_factor_to_fps_to_fls: "fls_base_factor_to_fps (fps_to_fls f) = unit_factor f" using fls_base_factor_fps_to_fls[of f] fls_regpart_fps_trivial[of "unit_factor f"] by simp
lemma fls_as_fps: fixes f :: "'a :: zero fls"and n :: int assumes n: "n ≥ -fls_subdegree f" obtains f' where"f = fls_shift n (fps_to_fls f')" proof - have"fls_subdegree (fls_shift (- n) f) ≥ 0" by (rule fls_shift_nonneg_subdegree) (use n in simp) hence"f = fls_shift n (fps_to_fls (fls_regpart (fls_shift (-n) f)))" by (subst fls_regpart_to_fls_trivial) simp_all thus ?thesis by (rule that) qed
lemma fls_as_fps': fixes f :: "'a :: zero fls"and n :: int assumes n: "n ≥ -fls_subdegree f" shows"∃f'. f = fls_shift n (fps_to_fls f')" using fls_as_fps[OF assms] by metis
abbreviation "fls_regpart_as_fls f ≡ fps_to_fls (fls_regpart f)" abbreviation "fls_prpart_as_fls f ≡ fls_shift (-fls_subdegree f) (fps_to_fls (fps_of_poly (reflect_poly (fls_prpart f))))"
lemma fls_regpart_as_fls_nth: "fls_regpart_as_fls f $$ n = (if n < 0 then 0 else f $$ n)" by simp
lemma fls_regpart_idem: "fls_regpart (fls_regpart_as_fls f) = fls_regpart f" by simp
lemma fls_prpart_as_fls_nth: "fls_prpart_as_fls f $$ n = (if n < 0 then f $$ n else 0)" proof (cases "n < fls_subdegree f""n < 0" rule: case_split[case_product case_split]) case False_True hence"nat (-fls_subdegree f) - nat (n - fls_subdegree f) = nat (-n)"by auto with False_True show ?thesis using coeff_reflect_poly[of "fls_prpart f""nat (n - fls_subdegree f)"] by auto next case False_False thus ?thesis using coeff_reflect_poly[of "fls_prpart f""nat (n - fls_subdegree f)"] by auto qed simp_all
lemma fls_prpart_idem [simp]: "fls_prpart (fls_prpart_as_fls f) = fls_prpart f" using fls_prpart_as_fls_nth[of f] by (intro poly_eqI) simp
lemma fls_regpart_prpart: "fls_regpart (fls_prpart_as_fls f) = 0" using fls_prpart_as_fls_nth[of f] by (intro fps_ext) simp
instantiation fls :: (monoid_add) plus begin
lift_definition plus_fls :: "'a fls ==> 'a fls ==> 'a fls"is"λf g n. f n + g n"
proof- fix f f' :: "int ==> 'a" assume"∀🪙∞n. f (- int n) = 0""∀🪙∞n. f' (- int n) = 0" from this obtain N N' where"∀n>N. f (-int n) = 0""∀n>N'. f' (-int n) = 0" by (auto simp: MOST_nat) hence"∀n > max N N'. f (-int n) + f' (-int n) = 0"by auto hence"∃K. ∀n>K. f (-int n) + f' (-int n) = 0"by fast thus"∀🪙∞n. f (- int n) + f' (-int n) = 0"by (simp add: MOST_nat) qed instance .. end
lemma fls_plus_nth [simp]: "(f + g) $$ n = f $$ n + g $$ n" by transfer simp
lemma fls_plus_const: "fls_const x + fls_const y = fls_const (x+y)" by (intro fls_eqI) simp
lemma fls_plus_subdegree: "f + g ≠ 0 ==> fls_subdegree (f + g) ≥ min (fls_subdegree f) (fls_subdegree g)" by (auto intro: fls_subdegree_geI)
lemma fls_shift_plus [simp]: "fls_shift m (f + g) = (fls_shift m f) + (fls_shift m g)" by (intro fls_eqI) simp
lemma fls_regpart_plus [simp]: "fls_regpart (f + g) = fls_regpart f + fls_regpart g" by (intro fps_ext) simp
lemma fls_prpart_plus [simp] : "fls_prpart (f + g) = fls_prpart f + fls_prpart g" by (intro poly_eqI) simp
lemma fls_decompose_reg_pr_parts: fixes f :: "'a :: monoid_add fls" defines"R ≡ fls_regpart_as_fls f" and"P ≡ fls_prpart_as_fls f" shows"f = P + R" and"f = R + P" using fls_prpart_as_fls_nth[of f] by (auto intro: fls_eqI simp add: assms)
lemma fps_to_fls_plus [simp]: "fps_to_fls (f + g) = fps_to_fls f + fps_to_fls g" by (intro fls_eqI) simp
instance fls :: (monoid_add) monoid_add proof fix a b c :: "'a fls" show"a + b + c = a + (b + c)"by transfer (simp add: add.assoc) show"0 + a = a"by transfer simp show"a + 0 = a"by transfer simp qed
instance fls :: (comm_monoid_add) comm_monoid_add by (standard, transfer, auto simp: add.commute)
lemma fls_nth_sum: "fls_nth (∑x∈A. f x) n = (∑x∈A. fls_nth (f x) n)" by (induction A rule: infinite_finite_induct) auto
subsubsection ‹Subtraction and negatives›
instantiation fls :: (group_add) minus begin
lift_definition minus_fls :: "'a fls ==> 'a fls ==> 'a fls"is"λf g n. f n - g n"
proof- fix f f' :: "int ==> 'a" assume"∀🪙∞n. f (- int n) = 0""∀🪙∞n. f' (- int n) = 0" from this obtain N N' where"∀n>N. f (-int n) = 0""∀n>N'. f' (-int n) = 0" by (auto simp: MOST_nat) hence"∀n > max N N'. f (-int n) - f' (-int n) = 0"by auto hence"∃K. ∀n>K. f (-int n) - f' (-int n) = 0"by fast thus"∀🪙∞n. f (- int n) - f' (-int n) = 0"by (simp add: MOST_nat) qed instance .. end
lemma fls_minus_nth [simp]: "(f - g) $$ n = f $$ n - g $$ n" by transfer simp
lemma fls_minus_const: "fls_const x - fls_const y = fls_const (x-y)" by (intro fls_eqI) simp
lemma fls_subdegree_minus: "f - g ≠ 0 ==> fls_subdegree (f - g) ≥ min (fls_subdegree f) (fls_subdegree g)" by (intro fls_subdegree_geI) simp_all
lemma fls_shift_minus [simp]: "fls_shift m (f - g) = (fls_shift m f) - (fls_shift m g)" by (auto intro: fls_eqI)
lemma fls_regpart_minus [simp]: "fls_regpart (f - g) = fls_regpart f - fls_regpart g" by (intro fps_ext) simp
lemma fls_prpart_minus [simp] : "fls_prpart (f - g) = fls_prpart f - fls_prpart g" by (intro poly_eqI) simp
lemma fps_to_fls_minus [simp]: "fps_to_fls (f - g) = fps_to_fls f - fps_to_fls g" by (intro fls_eqI) simp
instantiation fls :: (group_add) uminus begin
lift_definition uminus_fls :: "'a fls ==> 'a fls"is"λf n. - f n"
proof- fix f :: "int ==> 'a"assume"∀🪙∞n. f (- int n) = 0" from this obtain N where"∀n>N. f (-int n) = 0" by (auto simp: MOST_nat) hence"∀n>N. - f (-int n) = 0"by auto hence"∃K. ∀n>K. - f (-int n) = 0"by fast thus"∀🪙∞n. - f (- int n) = 0"by (simp add: MOST_nat) qed instance .. end
lemma fls_uminus_nth [simp]: "(-f) $$ n = - (f $$ n)" by transfer simp
lemma fls_subdegree_minus_sym: "fls_subdegree (g - f) = fls_subdegree (f - g)" using fls_uminus_subdegree[of "g-f"] by (simp add: algebra_simps)
lemma fls_regpart_sub_prpart: "fls_regpart (f - fls_prpart_as_fls f) = fls_regpart f" using fls_decompose_reg_pr_parts(2)[of f]
add_diff_cancel[of "fls_regpart_as_fls f""fls_prpart_as_fls f"] by simp
lemma fls_prpart_sub_regpart: "fls_prpart (f - fls_regpart_as_fls f) = fls_prpart f" using fls_decompose_reg_pr_parts(1)[of f]
add_diff_cancel[of "fls_prpart_as_fls f""fls_regpart_as_fls f"] by simp
subsubsection ‹Multiplication›
instantiation fls :: ("{comm_monoid_add, times}") times begin definition fls_times_def: "(*) = (\f g. fls_shift (- (fls_subdegree f + fls_subdegree g)) (fps_to_fls (fls_base_factor_to_fps f * fls_base_factor_to_fps g)) )" instance .. end
lemma fls_times_nth_eq0: "n < fls_subdegree f + fls_subdegree g ==> (f * g) $$ n = 0" by (simp add: fls_times_def)
lemma fls_times_nth: fixes f df g dg defines"df ≡ fls_subdegree f"and"dg ≡ fls_subdegree g" shows"(f * g) $$ n = (∑i=df + dg..n. f $$ (i - dg) * g $$ (dg + n - i))" and"(f * g) $$ n = (∑i=df..n - dg. f $$ i * g $$ (n - i))" and"(f * g) $$ n = (∑i=dg..n - df. f $$ (df + i - dg) * g $$ (dg + n - df - i))" and"(f * g) $$ n = (∑i=0..n - (df + dg). f $$ (df + i) * g $$ (n - df - i))"
proof-
define dfg where"dfg ≡ df + dg"
show 4: "(f * g) $$ n = (∑i=0..n - dfg. f $$ (df + i) * g $$ (n - df - i))" proof (cases "n < dfg") case False from False assms have "(f * g) $$ n = (∑i = 0..nat (n - dfg). f $$ (df + int i) * g $$ (dg + int (nat (n - dfg) - i)))" using fps_mult_nth[of "fls_base_factor_to_fps f""fls_base_factor_to_fps g"]
fls_base_factor_to_fps_nth[of f]
fls_base_factor_to_fps_nth[of g] by (simp add: dfg_def fls_times_def algebra_simps) moreoverfrom False have index: "∧i. i ∈ {0..nat (n - dfg)} ==> dg + int (nat (n - dfg) - i) = n - df - int i" by (auto simp: dfg_def) ultimatelyhave "(f * g) $$ n = (∑i=0..nat (n - dfg). f $$ (df + int i) * g $$ (n - df - int i))" by (simp del: of_nat_diff) moreoverhave "(∑i=0..nat (n - dfg). f $$ (df + int i) * g $$ (n - df - int i)) = (∑i=0..n - dfg. f $$ (df + i) * g $$ (n - df - i))" proof (intro sum.reindex_cong) show"inj_on nat {0..n - dfg}"by standard auto show"{0..nat (n - dfg)} = nat ` {0..n - dfg}" proof show"{0..nat (n - dfg)} ⊆ nat ` {0..n - dfg}" proof fix i assume"i ∈ {0..nat (n - dfg)}" hence i: "i ≥ 0""i ≤ nat (n - dfg)"by auto with False have"int i ≥ 0""int i ≤ n - dfg"by auto hence"int i ∈ {0..n - dfg}"by simp moreoverfrom i(1) have"i = nat (int i)"by simp ultimatelyshow"i ∈ nat ` {0..n - dfg}"by fast qed qed (auto simp: False) qed (simp add: False) ultimatelyshow"(f * g) $$ n = (∑i=0..n - dfg. f $$ (df + i) * g $$ (n - df - i))" by simp qed (simp add: fls_times_nth_eq0 assms dfg_def)
have "(∑i=dfg..n. f $$ (i - dg) * g $$ (dg + n - i)) = (∑i=0..n - dfg. f $$ (df + i) * g $$ (n - df - i))" proof (intro sum.reindex_cong)
define T where"T ≡ λi. i + dfg" show"inj_on T {0..n - dfg}"by standard (simp add: T_def) qed (simp_all add: dfg_def algebra_simps) with 4 show 1: "(f * g) $$ n = (∑i=dfg..n. f $$ (i - dg) * g $$ (dg + n - i))" by simp
have "(∑i=dfg..n. f $$ (i - dg) * g $$ (dg + n - i)) = (∑i=df..n - dg. f $$ i * g $$ (n - i))" proof (intro sum.reindex_cong)
define T where"T ≡ λi. i + dg" show"inj_on T {df..n - dg}"by standard (simp add: T_def) qed (auto simp: dfg_def) with 1 show"(f * g) $$ n = (∑i=df..n - dg. f $$ i * g $$ (n - i))" by simp
have "(∑i=dfg..n. f $$ (i - dg) * g $$ (dg + n - i)) = (∑i=dg..n - df. f $$ (df + i - dg) * g $$ (dg + n - df - i))" proof (intro sum.reindex_cong)
define T where"T ≡ λi. i + df" show"inj_on T {dg..n - df}"by standard (simp add: T_def) qed (simp_all add: dfg_def algebra_simps) with 1 show"(f * g) $$ n = (∑i=dg..n - df. f $$ (df + i - dg) * g $$ (dg + n - df - i))" by simp
instance fls :: ("{comm_monoid_add, mult_zero}") mult_zero proof fix a :: "'a fls" have "(0::'a fls) * a = fls_shift (fls_subdegree a) (fps_to_fls ( (0::'a fps)*(fls_base_factor_to_fps a) ))" by (simp add: fls_times_def) moreoverhave "a * (0::'a fls) = fls_shift (fls_subdegree a) (fps_to_fls ( (fls_base_factor_to_fps a)*(0::'a fps) ))" by (simp add: fls_times_def) ultimatelyshow"0 * a = (0::'a fls)""a * 0 = (0::'a fls)" by auto qed
lemma fls_mult_one: fixes f :: "'a::{comm_monoid_add, mult_zero, monoid_mult} fls" shows"1 * f = f" and"f * 1 = f" using fls_conv_base_factor_to_fps_shift_subdegree[of f] by (simp_all add: fls_times_def fps_one_mult)
lemma fls_mult_const_nth [simp]: fixes f :: "'a::{comm_monoid_add, mult_zero} fls" shows"(fls_const x * f) $$ n = x * f$$n" and"(f * fls_const x ) $$ n = f$$n * x"
proof- show"(fls_const x * f) $$ n = x * f$$n" proof (cases "n) case False hence"{fls_subdegree f..n} = insert (fls_subdegree f) {fls_subdegree f+1..n}"by auto thus ?thesis by (simp add: fls_times_nth(1)) qed (simp add: fls_times_nth_eq0) show"(f * fls_const x ) $$ n = f$$n * x" proof (cases "n) case False hence"{fls_subdegree f..n} = insert n {fls_subdegree f..n-1}"by auto thus ?thesis by (simp add: fls_times_nth(1)) qed (simp add: fls_times_nth_eq0) qed
lemma fls_const_mult_const[simp]: fixes x y :: "'a::{comm_monoid_add, mult_zero}" shows"fls_const x * fls_const y = fls_const (x*y)" by (intro fls_eqI) simp
lemma fls_subdegree_add_eq1: assumes"f ≠ 0""fls_subdegree f < fls_subdegree g" shows"fls_subdegree (f + g) = fls_subdegree f" proof (intro antisym) from assms have *: "fls_nth (f + g) (fls_subdegree f) ≠ 0" by auto from * show"fls_subdegree (f + g) ≤ fls_subdegree f" by (rule fls_subdegree_leI) from * have"f + g ≠ 0" using fls_nonzeroI by blast thus"fls_subdegree f ≤ fls_subdegree (f + g)" using assms(2) fls_plus_subdegree by force qed
lemma fls_subdegree_add_eq2: assumes"g ≠ 0""fls_subdegree g < fls_subdegree f" shows"fls_subdegree (f + g) = fls_subdegree g" proof (intro antisym) from assms have *: "fls_nth (f + g) (fls_subdegree g) ≠ 0" by auto from * show"fls_subdegree (f + g) ≤ fls_subdegree g" by (rule fls_subdegree_leI) from * have"f + g ≠ 0" using fls_nonzeroI by blast thus"fls_subdegree g ≤ fls_subdegree (f + g)" using assms(2) fls_plus_subdegree by force qed
lemma fls_subdegree_diff_eq1: assumes"f ≠ 0""fls_subdegree f < fls_subdegree g" shows"fls_subdegree (f - g) = fls_subdegree f" using fls_subdegree_add_eq1[of f "-g"] assms by simp
lemma fls_subdegree_diff_eq2: assumes"g ≠ 0""fls_subdegree g < fls_subdegree f" shows"fls_subdegree (f - g) = fls_subdegree g" using fls_subdegree_add_eq2[of "-g" f] assms by simp
lemma nat_minus_fls_subdegree_plus_const_eq: "nat (-fls_subdegree (F + fls_const c)) = nat (-fls_subdegree F)" proof (cases "fls_subdegree F < 0") case True hence"fls_subdegree (F + fls_const c) = fls_subdegree F" by (intro fls_subdegree_add_eq1) auto thus ?thesis by simp next case False thus ?thesis by (auto simp: fls_subdegree_ge0I) qed
lemma fls_mult_subdegree_ge: fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" assumes"f*g ≠ 0" shows"fls_subdegree (f*g) ≥ fls_subdegree f + fls_subdegree g" by (auto intro: fls_subdegree_geI simp: assms fls_times_nth_eq0)
lemma fls_mult_subdegree_ge_0: fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" assumes"fls_subdegree f ≥ 0""fls_subdegree g ≥ 0" shows"fls_subdegree (f*g) ≥ 0" using assms fls_mult_subdegree_ge[of f g] by fastforce
lemma fls_mult_nonzero_base_subdegree_eq: fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" assumes"f $$ (fls_subdegree f) * g $$ (fls_subdegree g) ≠ 0" shows"fls_subdegree (f*g) = fls_subdegree f + fls_subdegree g"
proof- from assms have"fls_subdegree (f*g) ≥ fls_subdegree f + fls_subdegree g" using fls_nonzeroI[of "f*g""fls_subdegree f + fls_subdegree g"]
fls_mult_subdegree_ge[of f g] by simp moreoverfrom assms have"fls_subdegree (f*g) ≤ fls_subdegree f + fls_subdegree g" by (intro fls_subdegree_leI) simp ultimatelyshow ?thesis by simp qed
lemma fls_subdegree_mult [simp]: fixes f g :: "'a::semiring_no_zero_divisors fls" assumes"f ≠ 0""g ≠ 0" shows"fls_subdegree (f * g) = fls_subdegree f + fls_subdegree g" using assms by (auto intro: fls_subdegree_eqI simp: fls_times_nth_eq0)
lemma fls_shifted_times_simps: fixes f g :: "'a::{comm_monoid_add, mult_zero} fls" shows"f * (fls_shift n g) = fls_shift n (f*g)""(fls_shift n f) * g = fls_shift n (f*g)"
proof-
show"f * (fls_shift n g) = fls_shift n (f*g)" proof (cases "g=0") case False hence "f * (fls_shift n g) = fls_shift (- (fls_subdegree f + (fls_subdegree g - n))) (fps_to_fls (fls_base_factor_to_fps f * fls_base_factor_to_fps g))" unfolding fls_times_def by (simp add: fls_base_factor_to_fps_shift) thus"f * (fls_shift n g) = fls_shift n (f*g)" by (simp add: algebra_simps fls_times_def) qed auto
show"(fls_shift n f)*g = fls_shift n (f*g)" proof (cases "f=0") case False hence "(fls_shift n f)*g = fls_shift (- ((fls_subdegree f - n) + fls_subdegree g)) (fps_to_fls (fls_base_factor_to_fps f * fls_base_factor_to_fps g))" unfolding fls_times_def by (simp add: fls_base_factor_to_fps_shift) thus"(fls_shift n f) * g = fls_shift n (f*g)" by (simp add: algebra_simps fls_times_def) qed auto
qed
lemma fls_shifted_times_transfer: fixes f g :: "'a::{comm_monoid_add, mult_zero} fls" shows"fls_shift n f * g = f * fls_shift n g" using fls_shifted_times_simps(1)[of f n g] fls_shifted_times_simps(2)[of n f g] by simp
lemma fls_times_both_shifted_simp: fixes f g :: "'a::{comm_monoid_add, mult_zero} fls" shows"(fls_shift m f) * (fls_shift n g) = fls_shift (m+n) (f*g)" by (simp add: fls_shifted_times_simps)
lemma fls_base_factor_mult_base_factor: fixes f g :: "'a::{comm_monoid_add, mult_zero} fls" shows"fls_base_factor (f * fls_base_factor g) = fls_base_factor (f * g)" and"fls_base_factor (fls_base_factor f * g) = fls_base_factor (f * g)" using fls_base_factor_shift[of "fls_subdegree g""f*g"]
fls_base_factor_shift[of "fls_subdegree f""f*g"] by (simp_all add: fls_shifted_times_simps)
lemma fls_base_factor_mult_both_base_factor: fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" shows"fls_base_factor (fls_base_factor f * fls_base_factor g) = fls_base_factor (f * g)" using fls_base_factor_mult_base_factor(1)[of "fls_base_factor f" g]
fls_base_factor_mult_base_factor(2)[of f g] by simp
lemma fls_base_factor_mult: fixes f g :: "'a::semiring_no_zero_divisors fls" shows"fls_base_factor (f * g) = fls_base_factor f * fls_base_factor g" by (cases "f≠0 ∧ g≠0")
(auto simp: fls_times_both_shifted_simp)
lemma fls_times_conv_base_factor_times: fixes f g :: "'a::{comm_monoid_add, mult_zero} fls" shows "f * g = fls_shift (-(fls_subdegree f + fls_subdegree g)) (fls_base_factor f * fls_base_factor g)" by (simp add: fls_times_both_shifted_simp)
lemma fls_times_base_factor_conv_shifted_times: 🍋‹Convenience form of lemma @{text "fls_times_both_shifted_simp"}.› fixes f g :: "'a::{comm_monoid_add, mult_zero} fls" shows "fls_base_factor f * fls_base_factor g = fls_shift (fls_subdegree f + fls_subdegree g) (f * g)" by (simp add: fls_times_both_shifted_simp)
lemma fls_times_conv_regpart: fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" assumes"fls_subdegree f ≥ 0""fls_subdegree g ≥ 0" shows"fls_regpart (f * g) = fls_regpart f * fls_regpart g"
proof- from assms have 1: "f * g = fls_shift (- (fls_subdegree f + fls_subdegree g)) ( fps_to_fls ( fps_shift (nat (fls_subdegree f) + nat (fls_subdegree g)) ( fls_regpart f * fls_regpart g ) ) )" by (simp add:
fls_times_def fls_base_factor_to_fps_conv_fps_shift[symmetric]
fls_regpart_subdegree_conv fps_shift_mult_both[symmetric]
) show ?thesis proof (cases "fls_regpart f * fls_regpart g = 0") case False with assms have "subdegree (fls_regpart f * fls_regpart g) ≥ nat (fls_subdegree f) + nat (fls_subdegree g)" by (simp add: fps_mult_subdegree_ge fls_regpart_subdegree_conv[symmetric]) with 1 assms show ?thesis by simp qed (simp add: 1) qed
lemma fls_base_factor_to_fps_mult_conv_unit_factor: fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" shows "fls_base_factor_to_fps (f * g) = unit_factor (fls_base_factor_to_fps f * fls_base_factor_to_fps g)" using fls_base_factor_mult_both_base_factor[of f g]
fps_unit_factor_fls_regpart[of "fls_base_factor f * fls_base_factor g"]
fls_base_factor_subdegree[of f] fls_base_factor_subdegree[of g]
fls_mult_subdegree_ge_0[of "fls_base_factor f""fls_base_factor g"]
fls_times_conv_regpart[of "fls_base_factor f""fls_base_factor g"] by simp
lemma fls_base_factor_to_fps_mult': fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" assumes"(f $$ fls_subdegree f) * (g $$ fls_subdegree g) ≠ 0" shows"fls_base_factor_to_fps (f * g) = fls_base_factor_to_fps f * fls_base_factor_to_fps g" using assms fls_mult_nonzero_base_subdegree_eq[of f g]
fls_times_base_factor_conv_shifted_times[of f g]
fls_times_conv_regpart[of "fls_base_factor f""fls_base_factor g"]
fls_base_factor_subdegree[of f] fls_base_factor_subdegree[of g] by fastforce
lemma fls_base_factor_to_fps_mult: fixes f g :: "'a::semiring_no_zero_divisors fls" shows"fls_base_factor_to_fps (f * g) = fls_base_factor_to_fps f * fls_base_factor_to_fps g" using fls_base_factor_to_fps_mult'[of f g] by (cases "f=0 ∨ g=0") auto
lemma fls_times_conv_fps_times: fixes f g :: "'a::{comm_monoid_add,mult_zero} fls" assumes"fls_subdegree f ≥ 0""fls_subdegree g ≥ 0" shows"f * g = fps_to_fls (fls_regpart f * fls_regpart g)" using assms fls_mult_subdegree_ge[of f g] by (cases "f * g = 0") (simp_all add: fls_times_conv_regpart[symmetric])
lemma fps_times_conv_fls_times: fixes f g :: "'a::{comm_monoid_add,mult_zero} fps" shows"f * g = fls_regpart (fps_to_fls f * fps_to_fls g)" using fls_subdegree_fls_to_fps_gt0 fls_times_conv_regpart[symmetric] by fastforce
lemma fls_times_fps_to_fls: fixes f g :: "'a::{comm_monoid_add,mult_zero} fps" shows"fps_to_fls (f * g) = fps_to_fls f * fps_to_fls g" proof (intro fls_eq_conv_fps_eqI, rule fls_subdegree_fls_to_fps_gt0) show"fls_subdegree (fps_to_fls f * fps_to_fls g) ≥ 0" proof (cases "fps_to_fls f * fps_to_fls g = 0") case False thus ?thesis using fls_mult_subdegree_ge fls_subdegree_fls_to_fps_gt0[of f]
fls_subdegree_fls_to_fps_gt0[of g] by fastforce qed simp qed (simp add: fps_times_conv_fls_times)
lemma fls_X_times_conv_shift: fixes f :: "'a::{comm_monoid_add,mult_zero,monoid_mult} fls" shows"fls_X * f = fls_shift (-1) f""f * fls_X = fls_shift (-1) f" by (simp_all add: fls_X_conv_shift_1 fls_mult_one fls_shifted_times_simps)
lemma fls_subdegree_mult_fls_X_inv: fixes f :: "'a::{comm_monoid_add,mult_zero,monoid_mult} fls" assumes"f ≠ 0" shows"fls_subdegree (fls_X_inv * f) = fls_subdegree f - 1" and"fls_subdegree (f * fls_X_inv) = fls_subdegree f - 1" by (auto simp: fls_X_inv_times_conv_shift assms)
lemma fls_mult_fls_X_inv_nonzero: fixes f :: "'a::{comm_monoid_add,mult_zero,monoid_mult} fls" assumes"f ≠ 0" shows"fls_X_inv * f ≠ 0" and"f * fls_X_inv ≠ 0" by (auto simp: fls_X_inv_times_conv_shift fls_shift_eq0_iff assms)
lemma fls_base_factor_mult_fls_X_inv: fixes f :: "'a::{comm_monoid_add,monoid_mult,mult_zero} fls" shows"fls_base_factor (fls_X_inv * f) = fls_base_factor f" and"fls_base_factor (f * fls_X_inv) = fls_base_factor f" using fls_base_factor_shift[of 1 f] by (auto simp: fls_X_inv_times_conv_shift)
lemma fls_mult_assoc_subdegree_ge_0: fixes f g h :: "'a::semiring_0 fls" assumes"fls_subdegree f ≥ 0""fls_subdegree g ≥ 0""fls_subdegree h ≥ 0" shows"f * g * h = f * (g * h)" using assms by (simp add: fls_times_conv_fps_times fls_subdegree_fls_to_fps_gt0 mult.assoc)
lemma fls_mult_assoc_base_factor: fixes a b c :: "'a::semiring_0 fls" shows "fls_base_factor a * fls_base_factor b * fls_base_factor c = fls_base_factor a * (fls_base_factor b * fls_base_factor c)" by (simp add: fls_mult_assoc_subdegree_ge_0 del: fls_base_factor_def)
lemma fls_mult_distrib_subdegree_ge_0: fixes f g h :: "'a::semiring_0 fls" assumes"fls_subdegree f ≥ 0""fls_subdegree g ≥ 0""fls_subdegree h ≥ 0" shows"(f + g) * h = f * h + g * h" and"h * (f + g) = h * f + h * g"
proof- have"fls_subdegree (f+g) ≥ 0" proof (cases "f+g = 0") case False with assms(1,2) show ?thesis using fls_plus_subdegree by fastforce qed simp with assms show"(f + g) * h = f * h + g * h""h * (f + g) = h * f + h * g" using distrib_right[of "fls_regpart f"] distrib_left[of "fls_regpart h"] by (simp_all add: fls_times_conv_fps_times) qed
lemma fls_mult_distrib_base_factor: fixes a b c :: "'a::semiring_0 fls" shows "fls_base_factor a * (fls_base_factor b + fls_base_factor c) = fls_base_factor a * fls_base_factor b + fls_base_factor a * fls_base_factor c" by (simp add: fls_mult_distrib_subdegree_ge_0 del: fls_base_factor_def)
instance fls :: (semiring_0) semiring_0 proof
fix a b c :: "'a fls" have "a * b * c = fls_shift (- (fls_subdegree a + fls_subdegree b + fls_subdegree c)) (fls_base_factor a * fls_base_factor b * fls_base_factor c)" by (simp add: fls_times_both_shifted_simp) moreoverhave "a * (b * c) = fls_shift (- (fls_subdegree a + fls_subdegree b + fls_subdegree c)) (fls_base_factor a * fls_base_factor b * fls_base_factor c)" using fls_mult_assoc_base_factor[of a b c] by (simp add: fls_times_both_shifted_simp) ultimatelyshow"a * b * c = a * (b * c)"by simp
have ab: "fls_subdegree (fls_shift (min (fls_subdegree a) (fls_subdegree b)) a) ≥ 0" "fls_subdegree (fls_shift (min (fls_subdegree a) (fls_subdegree b)) b) ≥ 0" by (simp_all add: fls_shift_nonneg_subdegree) have "(a + b) * c = fls_shift (- (min (fls_subdegree a) (fls_subdegree b) + fls_subdegree c)) ( ( fls_shift (min (fls_subdegree a) (fls_subdegree b)) a + fls_shift (min (fls_subdegree a) (fls_subdegree b)) b ) * fls_base_factor c)" using fls_times_both_shifted_simp[of "-min (fls_subdegree a) (fls_subdegree b)" "fls_shift (min (fls_subdegree a) (fls_subdegree b)) a + fls_shift (min (fls_subdegree a) (fls_subdegree b)) b" "-fls_subdegree c""fls_base_factor c"
] by simp alsohave "… = fls_shift (-(min (fls_subdegree a) (fls_subdegree b) + fls_subdegree c)) (fls_shift (min (fls_subdegree a) (fls_subdegree b)) a * fls_base_factor c) + fls_shift (-(min (fls_subdegree a) (fls_subdegree b) + fls_subdegree c)) (fls_shift (min (fls_subdegree a) (fls_subdegree b)) b * fls_base_factor c)" using ab by (simp add: fls_mult_distrib_subdegree_ge_0(1) del: fls_base_factor_def) finallyshow"(a + b) * c = a * c + b * c"by (simp add: fls_times_both_shifted_simp)
have bc: "fls_subdegree (fls_shift (min (fls_subdegree b) (fls_subdegree c)) b) ≥ 0" "fls_subdegree (fls_shift (min (fls_subdegree b) (fls_subdegree c)) c) ≥ 0" by (simp_all add: fls_shift_nonneg_subdegree) have "a * (b + c) = fls_shift (- (fls_subdegree a + min (fls_subdegree b) (fls_subdegree c))) ( fls_base_factor a * ( fls_shift (min (fls_subdegree b) (fls_subdegree c)) b + fls_shift (min (fls_subdegree b) (fls_subdegree c)) c ) ) " using fls_times_both_shifted_simp[of "-fls_subdegree a""fls_base_factor a" "-min (fls_subdegree b) (fls_subdegree c)" "fls_shift (min (fls_subdegree b) (fls_subdegree c)) b + fls_shift (min (fls_subdegree b) (fls_subdegree c)) c"
] by simp alsohave "… = fls_shift (-(fls_subdegree a + min (fls_subdegree b) (fls_subdegree c))) (fls_base_factor a * fls_shift (min (fls_subdegree b) (fls_subdegree c)) b) + fls_shift (-(fls_subdegree a + min (fls_subdegree b) (fls_subdegree c))) (fls_base_factor a * fls_shift (min (fls_subdegree b) (fls_subdegree c)) c) " using bc by (simp add: fls_mult_distrib_subdegree_ge_0(2) del: fls_base_factor_def) finallyshow"a * (b + c) = a * b + a * c"by (simp add: fls_times_both_shifted_simp)
qed
lemma fls_mult_commute_subdegree_ge_0: fixes f g :: "'a::comm_semiring_0 fls" assumes"fls_subdegree f ≥ 0""fls_subdegree g ≥ 0" shows"f * g = g * f" using assms by (simp add: fls_times_conv_fps_times mult.commute)
lemma fls_mult_commute_base_factor: fixes a b c :: "'a::comm_semiring_0 fls" shows"fls_base_factor a * fls_base_factor b = fls_base_factor b * fls_base_factor a" by (simp add: fls_mult_commute_subdegree_ge_0 del: fls_base_factor_def)
instance fls :: (comm_semiring_0) comm_semiring_0 proof fix a b c :: "'a fls" show"a * b = b * a" using fls_times_conv_base_factor_times[of a b] fls_times_conv_base_factor_times[of b a]
fls_mult_commute_base_factor[of a b] by (simp add: add.commute) qed (simp add: distrib_right)
instance fls :: (semiring_1) semiring_1 by (standard, simp_all add: fls_mult_one)
lemma fls_of_nat: "(of_nat n :: 'a::semiring_1 fls) = fls_const (of_nat n)" by (induct n) (auto intro: fls_eqI)
lemma fls_of_nat_nth: "of_nat n $$ k = (if k=0 then of_nat n else 0)" by (simp add: fls_of_nat)
lemma fls_mult_of_nat_nth [simp]: shows"(of_nat k * f) $$ n = of_nat k * f$$n" and"(f * of_nat k ) $$ n = f$$n * of_nat k" by (simp_all add: fls_of_nat)
lemma fls_mult_of_numeral_nth [simp]: shows"(numeral k * f) $$ n = numeral k * f $$ n" and"(f * numeral k) $$ n = f $$ n * numeral k" by (metis fls_const_numeral fls_mult_const_nth)+
lemma fls_nth_numeral' [simp]: "numeral n $$ 0 = numeral n""k ≠ 0 ==> numeral n $$ k = 0" by (metis fls_const_nth fls_const_numeral)+
instance fls :: (comm_semiring_1) comm_semiring_1 by standard simp
lemma fls_of_int: "(of_int i :: 'a::ring_1 fls) = fls_const (of_int i)" proof (induct i) case (neg i) have"of_int (int (Suc i)) = fls_const (of_int (int (Suc i)) :: 'a)" using fls_of_int_nonneg[of "Suc i"] by simp hence"- of_int (int (Suc i)) = - fls_const (of_int (int (Suc i)) :: 'a)" by simp thus ?caseby (simp add: fls_const_uminus[symmetric]) qed (rule fls_of_int_nonneg)
lemma fls_of_int_nth: "of_int n $$ k = (if k=0 then of_int n else 0)" by (simp add: fls_of_int)
lemma fls_mult_of_int_nth [simp]: shows"(of_int k * f) $$ n = of_int k * f$$n" and"(f * of_int k ) $$ n = f$$n * of_int k" by (simp_all add: fls_of_int)
lemma fls_base_factor_to_fps_of_int: "fls_base_factor_to_fps (of_int i) = (of_int i :: 'a::ring_1 fps)" by simp
lemma fps_to_fls_of_int: "fps_to_fls (of_int i) = (of_int i :: 'a::ring_1 fls)" proof - have"fps_to_fls (of_int i) = fps_to_fls (fps_const (of_int i))" by (simp add: fps_of_int) thus ?thesis by (simp add: fls_of_int) qed
instance fls :: (comm_ring_1) comm_ring_1 ..
instance fls :: (semiring_no_zero_divisors) semiring_no_zero_divisors proof fix a b :: "'a fls" assume"a ≠ 0"and"b ≠ 0" hence"(a * b) $$ (fls_subdegree a + fls_subdegree b) ≠ 0"by simp thus"a * b ≠ 0"using fls_nonzeroI by fast qed
instance fls :: ("{semiring_prime_char,comm_semiring_1}") semiring_prime_char by (rule semiring_prime_charI) auto instance fls :: ("{comm_semiring_prime_char,comm_semiring_1}") comm_semiring_prime_char by standard instance fls :: ("{comm_ring_prime_char,comm_semiring_1}") comm_ring_prime_char by standard instance fls :: ("{idom_prime_char,comm_semiring_1}") idom_prime_char by standard
lemma fls_subdegree_prod: fixes F :: "'a ==> 'b :: field_char_0 fls" assumes"∧x. x ∈ I ==> F x ≠ 0" shows"fls_subdegree (∏x∈I. F x) = (∑x∈I. fls_subdegree (F x))" using assms by (induction I rule: infinite_finite_induct) auto
lemma fls_subdegree_prod': fixes F :: "'a ==> 'b :: field_char_0 fls" assumes"∧x. x ∈ I ==> fls_subdegree (F x) ≠ 0" shows"fls_subdegree (∏x∈I. F x) = (∑x∈I. fls_subdegree (F x))" proof (intro fls_subdegree_prod) show"F x ≠ 0"if"x ∈ I"for x using assms[OF that] by auto qed
lemma fls_pow_subdegree_ge: "f^n ≠ 0 ==> fls_subdegree (f^n) ≥ n * fls_subdegree f" proof (induct n) case (Suc n) thus ?case using fls_mult_subdegree_ge[of f "f^n"] by (fastforce simp: algebra_simps) qed simp
lemma fls_pow_nth_below_subdegree: "k < n * fls_subdegree f ==> (f^n) $$ k = 0" using fls_pow_subdegree_ge[of f n] by (cases "f^n = 0") auto
lemma fls_pow_base [simp]: "(f ^ n) $$ (n * fls_subdegree f) = (f $$ fls_subdegree f) ^ n" proof (induct n) case (Suc n) show ?case proof (cases "Suc n * fls_subdegree f < fls_subdegree f + fls_subdegree (f^n)") case True with Suc show ?thesis by (simp_all add: fls_times_nth_eq0 distrib_right) next case False from False have "{0..int n * fls_subdegree f - fls_subdegree (f ^ n)} = insert 0 {1..int n * fls_subdegree f - fls_subdegree (f ^ n)}" by (auto simp: algebra_simps) with False Suc show ?thesis by (simp add: algebra_simps fls_times_nth(4) fls_pow_nth_below_subdegree) qed qed simp
lemma fls_pow_subdegree_eqI: "(f $$ fls_subdegree f) ^ n ≠ 0 ==> fls_subdegree (f^n) = n * fls_subdegree f" using fls_pow_nth_below_subdegree by (fastforce intro: fls_subdegree_eqI)
lemma fls_unit_base_subdegree_power: "x * f $$ fls_subdegree f = 1 ==> fls_subdegree (f ^ n) = n * fls_subdegree f" "f $$ fls_subdegree f * y = 1 ==> fls_subdegree (f ^ n) = n * fls_subdegree f"
proof- show"x * f $$ fls_subdegree f = 1 ==> fls_subdegree (f ^ n) = n * fls_subdegree f" using left_right_inverse_power[of x "f $$ fls_subdegree f" n] by (auto intro: fls_pow_subdegree_eqI) show"f $$ fls_subdegree f * y = 1 ==> fls_subdegree (f ^ n) = n * fls_subdegree f" using left_right_inverse_power[of "f $$ fls_subdegree f" y n] by (auto intro: fls_pow_subdegree_eqI) qed
lemma fls_base_dvd1_subdegree_power: "f $$ fls_subdegree f dvd 1 ==> fls_subdegree (f ^ n) = n * fls_subdegree f" using fls_unit_base_subdegree_power unfolding dvd_def by auto
lemma fls_pow_subdegree_ge0: assumes"fls_subdegree f ≥ 0" shows"fls_subdegree (f^n) ≥ 0" proof (cases "f^n = 0") case False moreoverfrom assms have"int n * fls_subdegree f ≥ 0"by simp ultimatelyshow ?thesis using fls_pow_subdegree_ge by fastforce qed simp
lemma fls_subdegree_pow: fixes f :: "'a::semiring_1_no_zero_divisors fls" shows"fls_subdegree (f ^ n) = n * fls_subdegree f" proof (cases "f=0") case False thus ?thesis by (induct n) (simp_all add: algebra_simps) qed (cases "n=0", auto simp: zero_power)
lemma fls_shifted_pow: "(fls_shift m f) ^ n = fls_shift (n*m) (f ^ n)" by (induct n) (simp_all add: fls_times_both_shifted_simp algebra_simps)
lemma fls_pow_conv_fps_pow: assumes"fls_subdegree f ≥ 0" shows"f ^ n = fps_to_fls ( (fls_regpart f) ^ n )" proof (induct n) case (Suc n) with assms show ?case using fls_pow_subdegree_ge0[of f n] by (simp add: fls_times_conv_fps_times) qed simp
lemma fps_to_fls_power: "fps_to_fls (f ^ n) = fps_to_fls f ^ n" by (simp add: fls_pow_conv_fps_pow fls_subdegree_fls_to_fps_gt0)
lemma fls_pow_conv_regpart: "fls_subdegree f ≥ 0 ==> fls_regpart (f ^ n) = (fls_regpart f) ^ n" by (simp add: fls_pow_conv_fps_pow)
text‹These two lemmas show that shifting 1 is equivalent to powers of the implied variable.›
lemma fls_X_power_conv_shift_1: "fls_X ^ n = fls_shift (-n) 1" by (simp add: fls_X_conv_shift_1 fls_shifted_pow)
lemma fls_X_inv_power_conv_shift_1: "fls_X_inv ^ n = fls_shift n 1" by (simp add: fls_X_inv_conv_shift_1 fls_shifted_pow)
abbreviation"fls_X_intpow ≡ (λi. fls_shift (-i) 1)" 🍋‹ Unifies @{term fls_X} and @{term fls_X_inv} so that @{term "fls_X_intpow"} returns the equivalent of the implied variable raised to the supplied integer argument of @{term "fls_X_intpow"}, whether positive or negative. ›
lemma fls_X_intpow_nonzero[simp]: "(fls_X_intpow i :: 'a::zero_neq_one fls) ≠ 0" by (simp add: fls_shift_eq0_iff)
lemma fls_X_intpow_power: "(fls_X_intpow i) ^ n = fls_X_intpow (n * i)" by (simp add: fls_shifted_pow)
lemma fls_X_power_nth [simp]: "fls_X ^ n $$ k = (if k=n then 1 else 0)" by (simp add: fls_X_power_conv_shift_1)
lemma fls_X_inv_power_nth [simp]: "fls_X_inv ^ n $$ k = (if k=-n then 1 else 0)" by (simp add: fls_X_inv_power_conv_shift_1)
lemma fls_X_pow_nonzero[simp]: "(fls_X ^ n :: 'a :: semiring_1 fls) ≠ 0" proof assume"(fls_X ^ n :: 'a fls) = 0" hence"(fls_X ^ n :: 'a fls) $$ n = 0"by simp thus False by simp qed
lemma fls_X_inv_pow_nonzero[simp]: "(fls_X_inv ^ n :: 'a :: semiring_1 fls) ≠ 0" proof assume"(fls_X_inv ^ n :: 'a fls) = 0" hence"(fls_X_inv ^ n :: 'a fls) $$ -n = 0"by simp thus False by simp qed
lemma fls_X_intpow_times_comm: fixes f :: "'a::semiring_1 fls" shows"fls_X_intpow i * f = f * fls_X_intpow i" by (simp add: fls_X_intpow_times_conv_shift)
lemma fls_X_intpow_times_fls_X_intpow: "(fls_X_intpow i :: 'a::semiring_1 fls) * fls_X_intpow j = fls_X_intpow (i+j)" by (simp add: fls_times_both_shifted_simp)
lemma fls_X_intpow_diff_conv_times: "fls_X_intpow (i-j) = (fls_X_intpow i :: 'a::semiring_1 fls) * fls_X_intpow (-j)" using fls_X_intpow_times_fls_X_intpow[of i "-j",symmetric] by simp
lemma fls_mult_fls_X_power_nonzero: assumes"f ≠ 0" shows"fls_X ^ n * f ≠ 0""f * fls_X ^ n ≠ 0" by (auto simp: fls_X_power_times_conv_shift fls_shift_eq0_iff assms)
lemma fls_mult_fls_X_inv_power_nonzero: assumes"f ≠ 0" shows"fls_X_inv ^ n * f ≠ 0""f * fls_X_inv ^ n ≠ 0" by (auto simp: fls_X_inv_power_times_conv_shift fls_shift_eq0_iff assms)
lemma fls_mult_fls_X_intpow_nonzero: fixes f :: "'a::semiring_1 fls" assumes"f ≠ 0" shows"fls_X_intpow i * f ≠ 0""f * fls_X_intpow i ≠ 0" by (auto simp: fls_X_intpow_times_conv_shift fls_shift_eq0_iff assms)
lemma fls_subdegree_mult_fls_X_power: assumes"f ≠ 0" shows"fls_subdegree (fls_X ^ n * f) = fls_subdegree f + n" and"fls_subdegree (f * fls_X ^ n) = fls_subdegree f + n" by (auto simp: fls_X_power_times_conv_shift assms)
lemma fls_subdegree_mult_fls_X_inv_power: assumes"f ≠ 0" shows"fls_subdegree (fls_X_inv ^ n * f) = fls_subdegree f - n" and"fls_subdegree (f * fls_X_inv ^ n) = fls_subdegree f - n" by (auto simp: fls_X_inv_power_times_conv_shift assms)
lemma fls_subdegree_mult_fls_X_intpow: fixes f :: "'a::semiring_1 fls" assumes"f ≠ 0" shows"fls_subdegree (fls_X_intpow i * f) = fls_subdegree f + i" and"fls_subdegree (f * fls_X_intpow i) = fls_subdegree f + i" by (auto simp: fls_X_intpow_times_conv_shift assms)
lemma fls_X_intpow_base_factor_to_fps: "fls_base_factor_to_fps (fls_X_intpow i) = 1"
proof-
define f :: "'a fls"where"f ≡ fls_X_intpow i" moreoverhave"fls_base_factor (fls_X_intpow i) = 1"by (rule fls_X_intpow_base_factor) ultimatelyhave"fls_base_factor f = 1"by simp thus"fls_base_factor_to_fps f = 1"by simp qed
lemma fls_base_factor_X_power_decompose: fixes f :: "'a::semiring_1 fls" shows"f = fls_base_factor f * fls_X_intpow (fls_subdegree f)" and"f = fls_X_intpow (fls_subdegree f) * fls_base_factor f" by (simp_all add: fls_times_both_shifted_simp)
lemma fls_normalized_product_of_inverses: assumes"f * g = 1" shows"fls_base_factor f * fls_base_factor g = fls_X ^ (nat (-(fls_subdegree f+fls_subdegree g)))" and"fls_base_factor f * fls_base_factor g = fls_X_intpow (-(fls_subdegree f+fls_subdegree g))" using fls_mult_subdegree_ge[of f g]
fls_times_base_factor_conv_shifted_times[of f g] by (simp_all add: assms fls_X_power_conv_shift_1 algebra_simps)
lemma fls_fps_normalized_product_of_inverses: assumes"f * g = 1" shows"fls_base_factor_to_fps f * fls_base_factor_to_fps g = fps_X ^ (nat (-(fls_subdegree f+fls_subdegree g)))" using fls_times_conv_regpart[of "fls_base_factor f""fls_base_factor g"]
fls_base_factor_subdegree[of f] fls_base_factor_subdegree[of g]
fls_normalized_product_of_inverses(1)[OF assms] by (force simp: fls_X_pow_conv_fps_X_pow)
subsubsection ‹Inverses›
abbreviation fls_left_inverse :: "'a::{comm_monoid_add,uminus,times} fls ==> 'a ==> 'a fls" where "fls_left_inverse f x ≡ fls_shift (fls_subdegree f) (fps_to_fls (fps_left_inverse (fls_base_factor_to_fps f) x))"
abbreviation fls_right_inverse :: "'a::{comm_monoid_add,uminus,times} fls ==> 'a ==> 'a fls" where "fls_right_inverse f y ≡ fls_shift (fls_subdegree f) (fps_to_fls (fps_right_inverse (fls_base_factor_to_fps f) y))"
instantiation fls :: ("{comm_monoid_add,uminus,times,inverse}") inverse begin definition fls_divide_def: "f div g = fls_shift (fls_subdegree g - fls_subdegree f) ( fps_to_fls ((fls_base_factor_to_fps f) div (fls_base_factor_to_fps g)) ) " definition fls_inverse_def: "inverse f = fls_shift (fls_subdegree f) (fps_to_fls (inverse (fls_base_factor_to_fps f)))" instance .. end
lemma fls_inverse_def': "inverse f = fls_right_inverse f (inverse (f $$ fls_subdegree f))" by (simp add: fls_inverse_def fps_inverse_def)
lemma fls_lr_inverse_base: "fls_left_inverse f x $$ (-fls_subdegree f) = x" "fls_right_inverse f y $$ (-fls_subdegree f) = y" by auto
lemma fls_lr_inverse_starting0: fixes f :: "'a::{comm_monoid_add,mult_zero,uminus} fls" and g :: "'b::{ab_group_add,mult_zero} fls" shows"fls_left_inverse f 0 = 0" and"fls_right_inverse g 0 = 0" by (simp_all add: fps_lr_inverse_starting0)
lemma fls_lr_inverse_eq0_imp_starting0: "fls_left_inverse f x = 0 ==> x = 0" "fls_right_inverse f x = 0 ==> x = 0" by (metis fls_lr_inverse_base fls_nonzeroI)+
lemma fls_lr_inverse_eq_0_iff: fixes x :: "'a::{comm_monoid_add,mult_zero,uminus}" and y :: "'b::{ab_group_add,mult_zero}" shows"fls_left_inverse f x = 0 ⟷ x = 0" and"fls_right_inverse g y = 0 ⟷ y = 0" using fls_lr_inverse_starting0 fls_lr_inverse_eq0_imp_starting0 by auto
lemma fls_inverse_eq_0_iff': fixes f :: "'a::{ab_group_add,inverse,mult_zero} fls" shows"inverse f = 0 ⟷ (inverse (f $$ fls_subdegree f) = 0)" using fls_lr_inverse_eq_0_iff(2)[of f "inverse (f $$ fls_subdegree f)"] by (simp add: fls_inverse_def')
lemma fls_inverse_eq_0_iff[simp]: "inverse f = (0:: ('a::division_ring) fls) ⟷ f $$ fls_subdegree f = 0" using fls_inverse_eq_0_iff'[of f] by (cases "f=0") auto
lemma fls_lr_inverse_const: fixes a :: "'a::{ab_group_add,mult_zero}" and b :: "'b::{comm_monoid_add,mult_zero,uminus}" shows"fls_left_inverse (fls_const a) x = fls_const x" and"fls_right_inverse (fls_const b) y = fls_const y" by (simp_all add: fps_const_lr_inverse)
lemma fls_inverse_const: fixes a :: "'a::{comm_monoid_add,inverse,mult_zero,uminus}" shows"inverse (fls_const a) = fls_const (inverse a)" using fls_lr_inverse_const(2) by (auto simp: fls_inverse_def')
lemma fls_lr_inverse_of_nat: fixes x :: "'a::{ring_1,mult_zero}" and y :: "'b::{semiring_1,uminus}" shows"fls_left_inverse (of_nat n) x = fls_const x" and"fls_right_inverse (of_nat n) y = fls_const y" using fls_lr_inverse_const by (auto simp: fls_of_nat)
lemma fls_inverse_of_nat: "inverse (of_nat n :: 'a :: {semiring_1,inverse,uminus} fls) = fls_const (inverse (of_nat n))" by (simp add: fls_inverse_const fls_of_nat)
lemma fls_lr_inverse_of_int: fixes x :: "'a::{ring_1,mult_zero}" shows"fls_left_inverse (of_int n) x = fls_const x" and"fls_right_inverse (of_int n) x = fls_const x" using fls_lr_inverse_const by (auto simp: fls_of_int)
lemma fls_inverse_of_int: "inverse (of_int n :: 'a :: {ring_1,inverse,uminus} fls) = fls_const (inverse (of_int n))" by (simp add: fls_inverse_const fls_of_int)
lemma fls_lr_inverse_zero: fixes x :: "'a::{ab_group_add,mult_zero}" and y :: "'b::{comm_monoid_add,mult_zero,uminus}" shows"fls_left_inverse 0 x = fls_const x" and"fls_right_inverse 0 y = fls_const y" using fls_lr_inverse_const[of 0] by auto
lemma fls_inverse_zero_conv_fls_const: "inverse (0::'a::{comm_monoid_add,mult_zero,uminus,inverse} fls) = fls_const (inverse 0)" using fls_lr_inverse_zero(2)[of "inverse (0::'a)"] by (simp add: fls_inverse_def')
lemma fls_inverse_base2: fixes f :: "'a::{comm_monoid_add,mult_zero,uminus,inverse} fls" shows"inverse f $$ (-fls_subdegree f) = inverse (f $$ fls_subdegree f)" by (cases "f=0") (simp_all add: fls_inverse_zero_conv_fls_const fls_inverse_def')
lemma fls_lr_inverse_one: fixes x :: "'a::{ab_group_add,mult_zero,one}" and y :: "'b::{comm_monoid_add,mult_zero,uminus,one}" shows"fls_left_inverse 1 x = fls_const x" and"fls_right_inverse 1 y = fls_const y" using fls_lr_inverse_const[of 1] by auto
lemma fls_lr_inverse_one_one: "fls_left_inverse 1 1 = (1::'a::{ab_group_add,mult_zero,one} fls)" "fls_right_inverse 1 1 = (1::'b::{comm_monoid_add,mult_zero,uminus,one} fls)" using fls_lr_inverse_one[of 1] by auto
lemma fls_inverse_one: assumes"inverse (1::'a::{comm_monoid_add,inverse,mult_zero,uminus,one}) = 1" shows"inverse (1::'a fls) = 1" using assms fls_lr_inverse_one_one(2) by (simp add: fls_inverse_def')
lemma fls_left_inverse_delta: fixes b :: "'a::{ab_group_add,mult_zero}" assumes"b ≠ 0" shows"fls_left_inverse (Abs_fls (λn. if n=a then b else 0)) x = Abs_fls (λn. if n=-a then x else 0)" proof (intro fls_eqI) fix n from assms show "fls_left_inverse (Abs_fls (λn. if n=a then b else 0)) x $$ n = Abs_fls (λn. if n = - a then x else 0) $$ n" using fls_base_factor_to_fps_delta[of a b]
fls_lr_inverse_const(1)[of b]
fls_shift_const by simp qed
lemma fls_right_inverse_delta: fixes b :: "'a::{comm_monoid_add,mult_zero,uminus}" assumes"b ≠ 0" shows"fls_right_inverse (Abs_fls (λn. if n=a then b else 0)) x = Abs_fls (λn. if n=-a then x else 0)" proof (intro fls_eqI) fix n from assms show "fls_right_inverse (Abs_fls (λn. if n=a then b else 0)) x $$ n = Abs_fls (λn. if n = - a then x else 0) $$ n" using fls_base_factor_to_fps_delta[of a b]
fls_lr_inverse_const(2)[of b]
fls_shift_const by simp qed
lemma fls_inverse_delta_nonzero: fixes b :: "'a::{comm_monoid_add,inverse,mult_zero,uminus}" assumes"b ≠ 0" shows"inverse (Abs_fls (λn. if n=a then b else 0)) = Abs_fls (λn. if n=-a then inverse b else 0)" using assms fls_nonzeroI[of "Abs_fls (λn. if n=a then b else 0)" a] by (simp add: fls_inverse_def' fls_right_inverse_delta[symmetric])
lemma fls_inverse_delta: fixes b :: "'a::division_ring" shows"inverse (Abs_fls (λn. if n=a then b else 0)) = Abs_fls (λn. if n=-a then inverse b else 0)" by (cases "b=0") (simp_all add: fls_inverse_delta_nonzero)
lemma fls_lr_inverse_X: fixes x :: "'a::{ab_group_add,mult_zero,zero_neq_one}" and y :: "'b::{comm_monoid_add,uminus,mult_zero,zero_neq_one}" shows"fls_left_inverse fls_X x = fls_shift 1 (fls_const x)" and"fls_right_inverse fls_X y = fls_shift 1 (fls_const y)" using fls_lr_inverse_one(1)[of x] fls_lr_inverse_one(2)[of y] by auto
lemma fls_lr_inverse_X': fixes x :: "'a::{ab_group_add,mult_zero,zero_neq_one,monoid_mult}" and y :: "'b::{comm_monoid_add,uminus,mult_zero,zero_neq_one,monoid_mult}" shows"fls_left_inverse fls_X x = fls_const x * fls_X_inv" and"fls_right_inverse fls_X y = fls_const y * fls_X_inv" using fls_lr_inverse_X(1)[of x] fls_lr_inverse_X(2)[of y] by (simp_all add: fls_X_inv_times_conv_shift(2))
lemma fls_inverse_X': assumes"inverse 1 = (1::'a::{comm_monoid_add,inverse,mult_zero,uminus,zero_neq_one})" shows"inverse (fls_X::'a fls) = fls_X_inv" using assms fls_lr_inverse_X(2)[of "1::'a"] by (simp add: fls_inverse_def' fls_X_inv_conv_shift_1)
lemma fls_lr_inverse_X_inv: fixes x :: "'a::{ab_group_add,mult_zero,zero_neq_one}" and y :: "'b::{comm_monoid_add,uminus,mult_zero,zero_neq_one}" shows"fls_left_inverse fls_X_inv x = fls_shift (-1) (fls_const x)" and"fls_right_inverse fls_X_inv y = fls_shift (-1) (fls_const y)" using fls_lr_inverse_one(1)[of x] fls_lr_inverse_one(2)[of y] by auto
lemma fls_lr_inverse_X_inv': fixes x :: "'a::{ab_group_add,mult_zero,zero_neq_one,monoid_mult}" and y :: "'b::{comm_monoid_add,uminus,mult_zero,zero_neq_one,monoid_mult}" shows"fls_left_inverse fls_X_inv x = fls_const x * fls_X" and"fls_right_inverse fls_X_inv y = fls_const y * fls_X" using fls_lr_inverse_X_inv(1)[of x] fls_lr_inverse_X_inv(2)[of y] by (simp_all add: fls_X_times_conv_shift(2))
lemma fls_inverse_X_inv': assumes"inverse 1 = (1::'a::{comm_monoid_add,inverse,mult_zero,uminus,zero_neq_one})" shows"inverse (fls_X_inv::'a fls) = fls_X" using assms fls_lr_inverse_X_inv(2)[of "1::'a"] by (simp add: fls_inverse_def' fls_X_conv_shift_1)
lemma fls_inverse_subdegree_base: fixes f :: "'a::{ab_group_add,inverse,mult_zero} fls" shows"inverse f $$ (fls_subdegree (inverse f)) = inverse (f $$ fls_subdegree f)" using fls_inverse_eq_0_iff'[of f] fls_inverse_subdegree_base_nonzero[of f] by (cases "f=0 ∨ inverse (f $$ fls_subdegree f) = 0")
(auto simp: fls_inverse_zero_conv_fls_const)
lemma fls_lr_inverse_subdegree_0: assumes"fls_subdegree f = 0" shows"fls_subdegree (fls_left_inverse f x) ≥ 0" and"fls_subdegree (fls_right_inverse f x) ≥ 0" using fls_subdegree_ge0I[of "fls_left_inverse f x"]
fls_subdegree_ge0I[of "fls_right_inverse f x"] by (auto simp: assms)
lemma fls_inverse_subdegree_0: "fls_subdegree f = 0 ==> fls_subdegree (inverse f) ≥ 0" using fls_lr_inverse_subdegree_0(2)[of f] by (simp add: fls_inverse_def')
lemma fls_lr_inverse_shift_nonzero: fixes f :: "'a::{comm_monoid_add,mult_zero,uminus} fls" assumes"f ≠ 0" shows"fls_left_inverse (fls_shift m f) x = fls_shift (-m) (fls_left_inverse f x)" and"fls_right_inverse (fls_shift m f) x = fls_shift (-m) (fls_right_inverse f x)" using assms fls_base_factor_to_fps_shift[of m f] fls_shift_subdegree by auto
lemma fls_inverse_shift_nonzero: fixes f :: "'a::{comm_monoid_add,inverse,mult_zero,uminus} fls" assumes"f ≠ 0" shows"inverse (fls_shift m f) = fls_shift (-m) (inverse f)" using assms fls_lr_inverse_shift_nonzero(2)[of f m "inverse (f $$ fls_subdegree f)"] by (simp add: fls_inverse_def')
lemma fls_inverse_shift: fixes f :: "'a::division_ring fls" shows"inverse (fls_shift m f) = fls_shift (-m) (inverse f)" using fls_inverse_shift_nonzero by (cases "f=0") simp_all
lemma fls_left_inverse_base_factor: fixes x :: "'a::{ab_group_add,mult_zero}" assumes"x ≠ 0" shows"fls_left_inverse (fls_base_factor f) x = fls_base_factor (fls_left_inverse f x)" using assms fls_lr_inverse_zero(1)[of x] fls_lr_inverse_subdegree(1)[of x] by (cases "f=0") auto
lemma fls_right_inverse_base_factor: fixes y :: "'a::{comm_monoid_add,mult_zero,uminus}" assumes"y ≠ 0" shows"fls_right_inverse (fls_base_factor f) y = fls_base_factor (fls_right_inverse f y)" using assms fls_lr_inverse_zero(2)[of y] fls_lr_inverse_subdegree(2)[of y] by (cases "f=0") auto
lemma fls_lr_inverse_regpart: assumes"fls_subdegree f = 0" shows"fls_regpart (fls_left_inverse f x) = fps_left_inverse (fls_regpart f) x" and"fls_regpart (fls_right_inverse f y) = fps_right_inverse (fls_regpart f) y" using assms by auto
lemma fls_inverse_regpart: assumes"fls_subdegree f = 0" shows"fls_regpart (inverse f) = inverse (fls_regpart f)" by (simp add: assms fls_inverse_def)
lemma fls_base_factor_to_fps_left_inverse: fixes x :: "'a::{ab_group_add,mult_zero}" shows"fls_base_factor_to_fps (fls_left_inverse f x) = fps_left_inverse (fls_base_factor_to_fps f) x" using fls_left_inverse_base_factor[of x f] fls_base_factor_subdegree[of f] by (cases "x=0") (simp_all add: fls_lr_inverse_starting0(1) fps_lr_inverse_starting0(1))
lemma fls_base_factor_to_fps_right_inverse_nonzero: fixes y :: "'a::{comm_monoid_add,mult_zero,uminus}" assumes"y ≠ 0" shows"fls_base_factor_to_fps (fls_right_inverse f y) = fps_right_inverse (fls_base_factor_to_fps f) y" using assms fls_right_inverse_base_factor[of y f]
fls_base_factor_subdegree[of f] by simp
lemma fls_base_factor_to_fps_right_inverse: fixes y :: "'a::{ab_group_add,mult_zero}" shows"fls_base_factor_to_fps (fls_right_inverse f y) = fps_right_inverse (fls_base_factor_to_fps f) y" using fls_base_factor_to_fps_right_inverse_nonzero[of y f] by (cases "y=0") (simp_all add: fls_lr_inverse_starting0(2) fps_lr_inverse_starting0(2))
lemma fls_base_factor_to_fps_inverse_nonzero: fixes f :: "'a::{comm_monoid_add,inverse,mult_zero,uminus} fls" assumes"inverse (f $$ fls_subdegree f) ≠ 0" shows"fls_base_factor_to_fps (inverse f) = inverse (fls_base_factor_to_fps f)" using assms fls_base_factor_to_fps_right_inverse_nonzero by (simp add: fls_inverse_def' fps_inverse_def)
lemma fls_base_factor_to_fps_inverse: fixes f :: "'a::{ab_group_add,inverse,mult_zero} fls" shows"fls_base_factor_to_fps (inverse f) = inverse (fls_base_factor_to_fps f)" using fls_base_factor_to_fps_right_inverse by (simp add: fls_inverse_def' fps_inverse_def)
lemma fls_lr_inverse_fps_to_fls: assumes"subdegree f = 0" shows"fls_left_inverse (fps_to_fls f) x = fps_to_fls (fps_left_inverse f x)" and"fls_right_inverse (fps_to_fls f) x = fps_to_fls (fps_right_inverse f x)" using assms fls_base_factor_to_fps_to_fls[of f] by (simp_all add: fls_subdegree_fls_to_fps)
lemma fls_inverse_fps_to_fls: "subdegree f = 0 ==> inverse (fps_to_fls f) = fps_to_fls (inverse f)" using nth_subdegree_nonzero[of f] by (cases "f=0")
(auto simp add:
fps_to_fls_nonzeroI fls_inverse_def' fls_subdegree_fls_to_fps fps_inverse_def
fls_lr_inverse_fps_to_fls(2)
)
lemma fls_lr_inverse_X_power: fixes x :: "'a::ring_1" and y :: "'b::{semiring_1,uminus}" shows"fls_left_inverse (fls_X ^ n) x = fls_shift n (fls_const x)" and"fls_right_inverse (fls_X ^ n) y = fls_shift n (fls_const y)" using fls_lr_inverse_one(1)[of x] fls_lr_inverse_one(2)[of y] by (simp_all add: fls_X_power_conv_shift_1)
lemma fls_lr_inverse_X_power': fixes x :: "'a::ring_1" and y :: "'b::{semiring_1,uminus}" shows"fls_left_inverse (fls_X ^ n) x = fls_const x * fls_X_inv ^ n" and"fls_right_inverse (fls_X ^ n) y = fls_const y * fls_X_inv ^ n" using fls_lr_inverse_X_power(1)[of n x] fls_lr_inverse_X_power(2)[of n y] by (simp_all add: fls_X_inv_power_times_conv_shift(2))
lemma fls_inverse_X_power': assumes"inverse 1 = (1::'a::{semiring_1,uminus,inverse})" shows"inverse ((fls_X ^ n)::'a fls) = fls_X_inv ^ n" using fls_lr_inverse_X_power'(2)[of n 1] by (simp add: fls_inverse_def' assms )
lemma fls_lr_inverse_X_inv_power: fixes x :: "'a::ring_1" and y :: "'b::{semiring_1,uminus}" shows"fls_left_inverse (fls_X_inv ^ n) x = fls_shift (-n) (fls_const x)" and"fls_right_inverse (fls_X_inv ^ n) y = fls_shift (-n) (fls_const y)" using fls_lr_inverse_one(1)[of x] fls_lr_inverse_one(2)[of y] by (simp_all add: fls_X_inv_power_conv_shift_1)
lemma fls_lr_inverse_X_inv_power': fixes x :: "'a::ring_1" and y :: "'b::{semiring_1,uminus}" shows"fls_left_inverse (fls_X_inv ^ n) x = fls_const x * fls_X ^ n" and"fls_right_inverse (fls_X_inv ^ n) y = fls_const y * fls_X ^ n" using fls_lr_inverse_X_inv_power(1)[of n x] fls_lr_inverse_X_inv_power(2)[of n y] by (simp_all add: fls_X_power_times_conv_shift(2))
lemma fls_inverse_X_inv_power': assumes"inverse 1 = (1::'a::{semiring_1,uminus,inverse})" shows"inverse ((fls_X_inv ^ n)::'a fls) = fls_X ^ n" using fls_lr_inverse_X_inv_power'(2)[of n 1] by (simp add: fls_inverse_def' assms)
lemma fls_lr_inverse_X_intpow: fixes x :: "'a::ring_1" and y :: "'b::{semiring_1,uminus}" shows"fls_left_inverse (fls_X_intpow i) x = fls_shift i (fls_const x)" and"fls_right_inverse (fls_X_intpow i) y = fls_shift i (fls_const y)" using fls_lr_inverse_one(1)[of x] fls_lr_inverse_one(2)[of y] by auto
lemma fls_lr_inverse_X_intpow': fixes x :: "'a::ring_1" and y :: "'b::{semiring_1,uminus}" shows"fls_left_inverse (fls_X_intpow i) x = fls_const x * fls_X_intpow (-i)" and"fls_right_inverse (fls_X_intpow i) y = fls_const y * fls_X_intpow (-i)" using fls_lr_inverse_X_intpow(1)[of i x] fls_lr_inverse_X_intpow(2)[of i y] by (simp_all add: fls_shifted_times_simps(1))
lemma fls_inverse_X_intpow': assumes"inverse 1 = (1::'a::{semiring_1,uminus,inverse})" shows"inverse (fls_X_intpow i :: 'a fls) = fls_X_intpow (-i)" using fls_lr_inverse_X_intpow'(2)[of i 1] by (simp add: fls_inverse_def' assms)
lemma fls_inverse_X_intpow: "inverse (fls_X_intpow i :: 'a::division_ring fls) = fls_X_intpow (-i)" by (simp add: fls_inverse_X_intpow')
lemma fls_left_inverse: fixes f :: "'a::ring_1 fls" assumes"x * f $$ fls_subdegree f = 1" shows"fls_left_inverse f x * f = 1"
proof- from assms have"x ≠ 0""x * (fls_base_factor_to_fps f$0) = 1"by auto thus ?thesis using fls_base_factor_to_fps_left_inverse[of f x]
fls_lr_inverse_subdegree(1)[of x] fps_left_inverse by (fastforce simp: fls_times_def) qed
lemma fls_right_inverse: fixes f :: "'a::ring_1 fls" assumes"f $$ fls_subdegree f * y = 1" shows"f * fls_right_inverse f y = 1"
proof- from assms have"y ≠ 0""(fls_base_factor_to_fps f$0) * y = 1"by auto thus ?thesis using fls_base_factor_to_fps_right_inverse[of f y]
fls_lr_inverse_subdegree(2)[of y] fps_right_inverse by (fastforce simp: fls_times_def) qed
🍋‹ It is possible in a ring for an element to have a left inverse but not a right inverse, or vice versa. But when an element has both, they must be the same. › lemma fls_left_inverse_eq_fls_right_inverse: fixes f :: "'a::ring_1 fls" assumes"x * f $$ fls_subdegree f = 1""f $$ fls_subdegree f * y = 1" 🍋‹These assumptions imply x equals y, but no need to assume that.› shows"fls_left_inverse f x = fls_right_inverse f y" using assms by (simp add: fps_left_inverse_eq_fps_right_inverse)
lemma fls_left_inverse_eq_inverse: fixes f :: "'a::division_ring fls" shows"fls_left_inverse f (inverse (f $$ fls_subdegree f)) = inverse f" proof (cases "f=0") case True hence"fls_left_inverse f (inverse (f $$ fls_subdegree f)) = fls_const (0::'a)" by (simp add: fls_lr_inverse_zero(1)[symmetric]) with True show ?thesis by simp next case False thus ?thesis using fls_left_inverse_eq_fls_right_inverse[of "inverse (f $$ fls_subdegree f)"] by (auto simp add: fls_inverse_def') qed
lemma fls_right_inverse_eq_inverse: fixes f :: "'a::division_ring fls" shows"fls_right_inverse f (inverse (f $$ fls_subdegree f)) = inverse f" proof (cases "f=0") case True hence"fls_right_inverse f (inverse (f $$ fls_subdegree f)) = fls_const (0::'a)" by (simp add: fls_lr_inverse_zero(2)[symmetric]) with True show ?thesis by simp qed (simp add: fls_inverse_def')
lemma fls_left_inverse_eq_fls_right_inverse_comm: fixes f :: "'a::comm_ring_1 fls" assumes"x * f $$ fls_subdegree f = 1" shows"fls_left_inverse f x = fls_right_inverse f x" using assms fls_left_inverse_eq_fls_right_inverse[of x f x] by (simp add: mult.commute)
lemma fls_left_inverse': fixes f :: "'a::ring_1 fls" assumes"x * f $$ fls_subdegree f = 1""f $$ fls_subdegree f * y = 1" 🍋‹These assumptions imply x equals y, but no need to assume that.› shows"fls_right_inverse f y * f = 1" using assms fls_left_inverse_eq_fls_right_inverse[of x f y] fls_left_inverse[of x f] by simp
lemma fls_right_inverse': fixes f :: "'a::ring_1 fls" assumes"x * f $$ fls_subdegree f = 1""f $$ fls_subdegree f * y = 1" 🍋‹These assumptions imply x equals y, but no need to assume that.› shows"f * fls_left_inverse f x = 1" using assms fls_left_inverse_eq_fls_right_inverse[of x f y] fls_right_inverse[of f y] by simp
lemma fls_mult_left_inverse_base_factor: fixes f :: "'a::ring_1 fls" assumes"x * (f $$ fls_subdegree f) = 1" shows"fls_left_inverse (fls_base_factor f) x * f = fls_X_intpow (fls_subdegree f)" using assms fls_base_factor_to_fps_base_factor[of f] fls_base_factor_subdegree[of f]
fls_shifted_times_simps(2)[of "-fls_subdegree f""fls_left_inverse f x" f]
fls_left_inverse[of x f] by simp
lemma fls_mult_right_inverse_base_factor: fixes f :: "'a::ring_1 fls" assumes"(f $$ fls_subdegree f) * y = 1" shows"f * fls_right_inverse (fls_base_factor f) y = fls_X_intpow (fls_subdegree f)" using assms fls_base_factor_to_fps_base_factor[of f] fls_base_factor_subdegree[of f]
fls_shifted_times_simps(1)[of f "-fls_subdegree f""fls_right_inverse f y"]
fls_right_inverse[of f y] by simp
lemma fls_mult_inverse_base_factor: fixes f :: "'a::division_ring fls" assumes"f ≠ 0" shows"f * inverse (fls_base_factor f) = fls_X_intpow (fls_subdegree f)" using fls_mult_right_inverse_base_factor[of f "inverse (f $$ fls_subdegree f)"]
fls_base_factor_base[of f] by (simp add: assms fls_right_inverse_eq_inverse[symmetric])
lemma fls_left_inverse_idempotent_ring1: fixes f :: "'a::ring_1 fls" assumes"x * f $$ fls_subdegree f = 1""y * x = 1" 🍋‹These assumptions imply y equals ‹f $$ fls_subdegree f›, but no need to assume that.› shows"fls_left_inverse (fls_left_inverse f x) y = f"
proof- from assms(1) have "fls_left_inverse (fls_left_inverse f x) y * fls_left_inverse f x * f = fls_left_inverse (fls_left_inverse f x) y" using fls_left_inverse[of x f] by (simp add: mult.assoc) moreoverhave "fls_left_inverse (fls_left_inverse f x) y * fls_left_inverse f x = 1" using assms fls_lr_inverse_subdegree(1)[of x f] fls_lr_inverse_base(1)[of f x] by (fastforce intro: fls_left_inverse) ultimatelyshow ?thesis by simp qed
lemma fls_left_inverse_idempotent_comm_ring1: fixes f :: "'a::comm_ring_1 fls" assumes"x * f $$ fls_subdegree f = 1" shows"fls_left_inverse (fls_left_inverse f x) (f $$ fls_subdegree f) = f" using assms fls_left_inverse_idempotent_ring1[of x f "f $$ fls_subdegree f"] by (simp add: mult.commute)
lemma fls_right_inverse_idempotent_ring1: fixes f :: "'a::ring_1 fls" assumes"f $$ fls_subdegree f * x = 1""x * y = 1" 🍋‹These assumptions imply y equals ‹f $$ fls_subdegree f›, but no need to assume that.› shows"fls_right_inverse (fls_right_inverse f x) y = f"
proof- from assms(1) have "f * (fls_right_inverse f x * fls_right_inverse (fls_right_inverse f x) y) = fls_right_inverse (fls_right_inverse f x) y" using fls_right_inverse [of f] by (simp add: mult.assoc[symmetric]) moreoverhave "fls_right_inverse f x * fls_right_inverse (fls_right_inverse f x) y = 1" using assms fls_lr_inverse_subdegree(2)[of x f] fls_lr_inverse_base(2)[of f x] by (fastforce intro: fls_right_inverse) ultimatelyshow ?thesis by simp qed
lemma fls_right_inverse_idempotent_comm_ring1: fixes f :: "'a::comm_ring_1 fls" assumes"f $$ fls_subdegree f * x = 1" shows"fls_right_inverse (fls_right_inverse f x) (f $$ fls_subdegree f) = f" using assms fls_right_inverse_idempotent_ring1[of f x "f $$ fls_subdegree f"] by (simp add: mult.commute)
lemma fls_lr_inverse_unique_ring1: fixes f g :: "'a :: ring_1 fls" assumes fg: "f * g = 1""g $$ fls_subdegree g * f $$ fls_subdegree f = 1" shows"fls_left_inverse g (f $$ fls_subdegree f) = f" and"fls_right_inverse f (g $$ fls_subdegree g) = g"
proof-
have"f $$ fls_subdegree f * g $$ fls_subdegree g ≠ 0" proof assume"f $$ fls_subdegree f * g $$ fls_subdegree g = 0" hence"f $$ fls_subdegree f * (g $$ fls_subdegree g * f $$ fls_subdegree f) = 0" by (simp add: mult.assoc[symmetric]) with fg(2) show False by simp qed with fg(1) have subdeg_sum: "fls_subdegree f + fls_subdegree g = 0" using fls_mult_nonzero_base_subdegree_eq[of f g] by simp hence subdeg_sum': "fls_subdegree f = -fls_subdegree g""fls_subdegree g = -fls_subdegree f" by auto
from fg(1) have f_ne_0: "f≠0"by auto moreoverhave "fps_left_inverse (fls_base_factor_to_fps g) (fls_regpart (fls_shift (-fls_subdegree g) f)$0) = fls_regpart (fls_shift (-fls_subdegree g) f)" proof (intro fps_lr_inverse_unique_ring1(1)) from fg(1) show "fls_regpart (fls_shift (-fls_subdegree g) f) * fls_base_factor_to_fps g = 1" using f_ne_0 fls_times_conv_regpart[of "fls_shift (-fls_subdegree g) f""fls_base_factor g"]
fls_base_factor_subdegree[of g] by (simp add: fls_times_both_shifted_simp subdeg_sum) from fg(2) show "fls_base_factor_to_fps g $ 0 * fls_regpart (fls_shift (-fls_subdegree g) f) $ 0 = 1" by (simp add: subdeg_sum'(2)) qed ultimatelyshow"fls_left_inverse g (f $$ fls_subdegree f) = f" by (simp add: subdeg_sum'(2))
from fg(1) have g_ne_0: "g≠0"by auto moreoverhave "fps_right_inverse (fls_base_factor_to_fps f) (fls_regpart (fls_shift (-fls_subdegree f) g)$0) = fls_regpart (fls_shift (-fls_subdegree f) g)" proof (intro fps_lr_inverse_unique_ring1(2)) from fg(1) show "fls_base_factor_to_fps f * fls_regpart (fls_shift (-fls_subdegree f) g) = 1" using g_ne_0 fls_times_conv_regpart[of "fls_base_factor f""fls_shift (-fls_subdegree f) g"]
fls_base_factor_subdegree[of f] by (simp add: fls_times_both_shifted_simp subdeg_sum add.commute) from fg(2) show "fls_regpart (fls_shift (-fls_subdegree f) g) $ 0 * fls_base_factor_to_fps f $ 0 = 1" by (simp add: subdeg_sum'(1)) qed ultimatelyshow"fls_right_inverse f (g $$ fls_subdegree g) = g" by (simp add: subdeg_sum'(2))
qed
lemma fls_lr_inverse_unique_divring: fixes f g :: "'a ::division_ring fls" assumes fg: "f * g = 1" shows"fls_left_inverse g (f $$ fls_subdegree f) = f" and"fls_right_inverse f (g $$ fls_subdegree g) = g"
proof- from fg have"f ≠0""g ≠ 0"by auto with fg have"fls_subdegree f + fls_subdegree g = 0"using fls_subdegree_mult by force with fg have"f $$ fls_subdegree f * g $$ fls_subdegree g = 1" using fls_times_base[of f g] by simp hence"g $$ fls_subdegree g * f $$ fls_subdegree f = 1" using inverse_unique[of "f $$ fls_subdegree f"] left_inverse[of "f $$ fls_subdegree f"] by force thus "fls_left_inverse g (f $$ fls_subdegree f) = f" "fls_right_inverse f (g $$ fls_subdegree g) = g" using fg fls_lr_inverse_unique_ring1 by auto qed
lemma fls_lr_inverse_minus: fixes f :: "'a::ring_1 fls" shows"fls_left_inverse (-f) (-x) = - fls_left_inverse f x" and"fls_right_inverse (-f) (-x) = - fls_right_inverse f x" by (simp_all add: fps_lr_inverse_minus)
lemma fls_inverse_minus [simp]: "inverse (-f) = -inverse (f :: 'a :: division_ring fls)" using fls_lr_inverse_minus(2)[of f] by (simp add: fls_inverse_def')
lemma fls_lr_inverse_mult_ring1: fixes f g :: "'a::ring_1 fls" assumes x: "x * f $$ fls_subdegree f = 1""f $$ fls_subdegree f * x = 1" and y: "y * g $$ fls_subdegree g = 1""g $$ fls_subdegree g * y = 1" shows"fls_left_inverse (f * g) (y*x) = fls_left_inverse g y * fls_left_inverse f x" and"fls_right_inverse (f * g) (y*x) = fls_right_inverse g y * fls_right_inverse f x"
proof- from x(1) y(2) have"x * (f $$ fls_subdegree f * g $$ fls_subdegree g) * y = 1" by (simp add: mult.assoc) hence base_prod: "f $$ fls_subdegree f * g $$ fls_subdegree g ≠ 0"by auto hence subdegrees: "fls_subdegree (f*g) = fls_subdegree f + fls_subdegree g" using fls_mult_nonzero_base_subdegree_eq[of f g] by simp
have norm: "fls_base_factor_to_fps (f * g) = fls_base_factor_to_fps f * fls_base_factor_to_fps g" using base_prod fls_base_factor_to_fps_mult'[of f g] by simp
have "fls_left_inverse (f * g) (y*x) = fls_shift (fls_subdegree (f * g)) ( fps_to_fls ( fps_left_inverse (fls_base_factor_to_fps f * fls_base_factor_to_fps g) (y*x) ) ) " using norm by simp thus"fls_left_inverse (f * g) (y*x) = fls_left_inverse g y * fls_left_inverse f x" using x y
fps_lr_inverse_mult_ring1(1)[of
x "fls_base_factor_to_fps f" y "fls_base_factor_to_fps g"
] by (simp add:
fls_times_both_shifted_simp fls_times_fps_to_fls subdegrees algebra_simps
)
have "fls_right_inverse (f * g) (y*x) = fls_shift (fls_subdegree (f * g)) ( fps_to_fls ( fps_right_inverse (fls_base_factor_to_fps f * fls_base_factor_to_fps g) (y*x) ) ) " using norm by simp thus"fls_right_inverse (f * g) (y*x) = fls_right_inverse g y * fls_right_inverse f x" using x y
fps_lr_inverse_mult_ring1(2)[of
x "fls_base_factor_to_fps f" y "fls_base_factor_to_fps g"
] by (simp add:
fls_times_both_shifted_simp fls_times_fps_to_fls subdegrees algebra_simps
)
qed
lemma fls_lr_inverse_power_ring1: fixes f :: "'a::ring_1 fls" assumes x: "x * f $$ fls_subdegree f = 1""f $$ fls_subdegree f * x = 1" shows"fls_left_inverse (f ^ n) (x ^ n) = (fls_left_inverse f x) ^ n" "fls_right_inverse (f ^ n) (x ^ n) = (fls_right_inverse f x) ^ n"
proof-
show"fls_left_inverse (f ^ n) (x ^ n) = (fls_left_inverse f x) ^ n" proof (induct n) case 0 show ?caseusing fls_lr_inverse_one(1)[of 1] by simp next case (Suc n) with assms show ?case using fls_lr_inverse_mult_ring1(1)[of x f "x^n""f^n"] by (simp add:
power_Suc2[symmetric] fls_unit_base_subdegree_power(1) left_right_inverse_power
) qed
show"fls_right_inverse (f ^ n) (x ^ n) = (fls_right_inverse f x) ^ n" proof (induct n) case 0 show ?caseusing fls_lr_inverse_one(2)[of 1] by simp next case (Suc n) with assms show ?case using fls_lr_inverse_mult_ring1(2)[of x f "x^n""f^n"] by (simp add:
power_Suc2[symmetric] fls_unit_base_subdegree_power(1) left_right_inverse_power
) qed
qed
lemma fls_divide_convert_times_inverse: fixes f g :: "'a::{comm_monoid_add,inverse,mult_zero,uminus} fls" shows"f / g = f * inverse g" using fls_base_factor_to_fps_subdegree[of g] fps_to_fls_base_factor_to_fps[of f]
fls_times_both_shifted_simp[of "-fls_subdegree f""fls_base_factor f"] by (simp add:
fls_divide_def fps_divide_unit' fls_times_fps_to_fls
fls_conv_base_factor_shift_subdegree fls_inverse_def
)
instance fls :: (division_ring) division_ring proof fix a b :: "'a fls" show"a ≠ 0 ==> inverse a * a = 1" using fls_left_inverse'[of "inverse (a $$ fls_subdegree a)" a] by (simp add: fls_inverse_def') show"a ≠ 0 ==> a * inverse a = 1" using fls_right_inverse[of a] by (simp add: fls_inverse_def') show"a / b = a * inverse b"using fls_divide_convert_times_inverse by fast show"inverse (0::'a fls) = 0"by simp qed
lemma fls_lr_inverse_mult_divring: fixes f g :: "'a::division_ring fls" and df dg :: int defines"df ≡ fls_subdegree f" and"dg ≡ fls_subdegree g" shows"fls_left_inverse (f*g) (inverse ((f*g)$$(df+dg))) = fls_left_inverse g (inverse (g$$dg)) * fls_left_inverse f (inverse (f$$df))" and"fls_right_inverse (f*g) (inverse ((f*g)$$(df+dg))) = fls_right_inverse g (inverse (g$$dg)) * fls_right_inverse f (inverse (f$$df))" proof - show "fls_left_inverse (f*g) (inverse ((f*g)$$(df+dg))) = fls_left_inverse g (inverse (g$$dg)) * fls_left_inverse f (inverse (f$$df))" proof (cases "f=0 ∨ g=0") case True thus ?thesis using fls_lr_inverse_zero(1)[of "inverse (0::'a)"] by (auto simp add: assms) next case False thus ?thesis using fls_left_inverse_eq_inverse[of "f*g"] nonzero_inverse_mult_distrib[of f g]
fls_left_inverse_eq_inverse[of g] fls_left_inverse_eq_inverse[of f] by (simp add: assms) qed show "fls_right_inverse (f*g) (inverse ((f*g)$$(df+dg))) = fls_right_inverse g (inverse (g$$dg)) * fls_right_inverse f (inverse (f$$df))" proof (cases "f=0 ∨ g=0") case True thus ?thesis using fls_lr_inverse_zero(2)[of "inverse (0::'a)"] by (auto simp add: assms) next case False thus ?thesis using fls_inverse_def'[of "f*g"] nonzero_inverse_mult_distrib[of f g]
fls_inverse_def'[of g] fls_inverse_def'[of f] by (simp add: assms) qed qed
lemma fls_lr_inverse_power_divring: "fls_left_inverse (f ^ n) ((inverse (f $$ fls_subdegree f)) ^ n) = (fls_left_inverse f (inverse (f $$ fls_subdegree f))) ^ n" (is ?P) and"fls_right_inverse (f ^ n) ((inverse (f $$ fls_subdegree f)) ^ n) = (fls_right_inverse f (inverse (f $$ fls_subdegree f))) ^ n" (is ?Q) for f :: "'a::division_ring fls" proof - note fls_left_inverse_eq_inverse [of f] fls_right_inverse_eq_inverse[of f] moreoverhave "fls_right_inverse (f ^ n) ((inverse (f $$ fls_subdegree f)) ^ n) = inverse f ^ n" using fls_right_inverse_eq_inverse [of "f ^ n"] by (simp add: fls_subdegree_pow power_inverse) moreoverhave "fls_left_inverse (f ^ n) ((inverse (f $$ fls_subdegree f)) ^ n) = inverse f ^ n" using fls_left_inverse_eq_inverse [of "f ^ n"] by (simp add: fls_subdegree_pow power_inverse) ultimatelyshow ?P and ?Q by simp_all qed
lemma one_plus_fls_X_powi_eq: "(1 + fls_X) powi n = fps_to_fls (fps_binomial (of_int n :: 'a :: field_char_0))" proof (cases "n ≥ 0") case True thus ?thesis using fps_binomial_of_nat[of "nat n", where ?'a = 'a] by (simp add: power_int_def fps_to_fls_power) next case False thus ?thesis using fps_binomial_minus_of_nat[of "nat (-n)", where ?'a = 'a] by (simp add: power_int_def fps_to_fls_power fps_inverse_power flip: fls_inverse_fps_to_fls) qed
instance fls :: (field) field by (standard, simp_all add: field_simps)
instance fls :: ("{field_prime_char,comm_semiring_1}") field_prime_char by (rule field_prime_charI') auto
instance fls :: (semiring_char_0) semiring_char_0 proof show"inj (of_nat :: nat ==> 'a fls)" by (metis fls_regpart_of_nat injI of_nat_eq_iff) qed
instance fls :: (field_char_0) field_char_0 ..
lemma fls_subdegree_power_int [simp]: fixes F :: "'a :: field fls" shows"fls_subdegree (F powi n) = n * fls_subdegree F" by (auto simp: power_int_def fls_subdegree_pow)
subsubsection ‹Division›
lemma fls_divide_nth_below: fixes f g :: "'a::{comm_monoid_add,uminus,times,inverse} fls" shows"n < fls_subdegree f - fls_subdegree g ==> (f div g) $$ n = 0" by (simp add: fls_divide_def)
lemma fls_divide_nth_base: fixes f g :: "'a::division_ring fls" shows "(f div g) $$ (fls_subdegree f - fls_subdegree g) = f $$ fls_subdegree f / g $$ fls_subdegree g" using fps_divide_nth_0'[of "fls_base_factor_to_fps g""fls_base_factor_to_fps f"]
fls_base_factor_to_fps_subdegree[of g] by (simp add: fls_divide_def)
lemma fls_div_zero [simp]: "0 div (g :: 'a :: {comm_monoid_add,inverse,mult_zero,uminus} fls) = 0" by (simp add: fls_divide_def)
lemma fls_div_by_zero: fixes g :: "'a::{comm_monoid_add,inverse,mult_zero,uminus} fls" assumes"inverse (0::'a) = 0" shows"g div 0 = 0" by (simp add: fls_divide_def assms fps_div_by_zero')
lemma fls_divide_times: fixes f g :: "'a::{semiring_0,inverse,uminus} fls" shows"(f * g) / h = f * (g / h)" by (simp add: fls_divide_convert_times_inverse mult.assoc)
lemma fls_divide_times2: fixes f g :: "'a::{comm_semiring_0,inverse,uminus} fls" shows"(f * g) / h = (f / h) * g" using fls_divide_times[of g f h] by (simp add: mult.commute)
lemma fls_divide_subdegree_ge: fixes f g :: "'a::{comm_monoid_add,uminus,times,inverse} fls" assumes"f / g ≠ 0" shows"fls_subdegree (f / g) ≥ fls_subdegree f - fls_subdegree g" using assms fls_divide_nth_below by (intro fls_subdegree_geI) simp
lemma fls_divide_subdegree: fixes f g :: "'a::division_ring fls" assumes"f ≠ 0""g ≠ 0" shows"fls_subdegree (f / g) = fls_subdegree f - fls_subdegree g" proof (intro antisym) from assms have"f $$ fls_subdegree f / g $$ fls_subdegree g ≠ 0"by (simp add: field_simps) thus"fls_subdegree (f/g) ≤ fls_subdegree f - fls_subdegree g" using fls_divide_nth_base[of f g] by (intro fls_subdegree_leI) simp from assms have"f / g ≠ 0"by (simp add: field_simps) thus"fls_subdegree (f/g) ≥ fls_subdegree f - fls_subdegree g" using fls_divide_subdegree_ge by fast qed
lemma fls_divide_shift_numer_nonzero: fixes f g :: "'a :: {comm_monoid_add,inverse,times,uminus} fls" assumes"f ≠ 0" shows"fls_shift m f / g = fls_shift m (f/g)" using assms fls_base_factor_to_fps_shift[of m f] by (simp add: fls_divide_def algebra_simps)
lemma fls_divide_shift_numer: fixes f g :: "'a :: {comm_monoid_add,inverse,mult_zero,uminus} fls" shows"fls_shift m f / g = fls_shift m (f/g)" using fls_divide_shift_numer_nonzero by (cases "f=0") auto
lemma fls_divide_shift_denom_nonzero: fixes f g :: "'a :: {comm_monoid_add,inverse,times,uminus} fls" assumes"g ≠ 0" shows"f / fls_shift m g = fls_shift (-m) (f/g)" using assms fls_base_factor_to_fps_shift[of m g] by (simp add: fls_divide_def algebra_simps)
lemma fls_divide_shift_denom: fixes f g :: "'a :: division_ring fls" shows"f / fls_shift m g = fls_shift (-m) (f/g)" using fls_divide_shift_denom_nonzero by (cases "g=0") auto
lemma fls_divide_shift_both_nonzero: fixes f g :: "'a :: {comm_monoid_add,inverse,times,uminus} fls" assumes"f ≠ 0""g ≠ 0" shows"fls_shift n f / fls_shift m g = fls_shift (n-m) (f/g)" by (simp add: assms fls_divide_shift_numer_nonzero fls_divide_shift_denom_nonzero)
lemma fls_divide_shift_both [simp]: fixes f g :: "'a :: division_ring fls" shows"fls_shift n f / fls_shift m g = fls_shift (n-m) (f/g)" using fls_divide_shift_both_nonzero by (cases "f=0 ∨ g=0") auto
lemma fls_divide_base_factor_numer: "fls_base_factor f / g = fls_shift (fls_subdegree f) (f/g)" using fls_base_factor_to_fps_base_factor[of f]
fls_base_factor_subdegree[of f] by (simp add: fls_divide_def algebra_simps)
lemma fls_divide_base_factor_denom: "f / fls_base_factor g = fls_shift (-fls_subdegree g) (f/g)" using fls_base_factor_to_fps_base_factor[of g]
fls_base_factor_subdegree[of g] by (simp add: fls_divide_def)
lemma fls_divide_base_factor': "fls_base_factor f / fls_base_factor g = fls_shift (fls_subdegree f - fls_subdegree g) (f/g)" using fls_divide_base_factor_numer[of f "fls_base_factor g"]
fls_divide_base_factor_denom[of f g] by simp
lemma fls_divide_base_factor: fixes f g :: "'a :: division_ring fls" shows"fls_base_factor f / fls_base_factor g = fls_base_factor (f/g)" using fls_divide_subdegree[of f g] fls_divide_base_factor' by fastforce
lemma fls_divide_regpart: fixes f g :: "'a::{inverse,comm_monoid_add,uminus,mult_zero} fls" assumes"fls_subdegree f ≥ 0""fls_subdegree g ≥ 0" shows"fls_regpart (f / g) = fls_regpart f / fls_regpart g" proof - have deg0: "∧g. fls_subdegree g = 0 ==> fls_regpart (f / g) = fls_regpart f / fls_regpart g" by (simp add:
assms(1) fls_divide_convert_times_inverse fls_inverse_subdegree_0
fls_times_conv_regpart fls_inverse_regpart fls_regpart_subdegree_conv fps_divide_unit'
) show ?thesis proof (cases "fls_subdegree g = 0") case False hence"fls_base_factor g ≠ 0"using fls_base_factor_nonzero[of g] by force with assms(2) show ?thesis using fls_divide_shift_denom_nonzero[of "fls_base_factor g" f "-fls_subdegree g"]
fps_shift_fls_regpart_conv_fls_shift[of "nat (fls_subdegree g)""f / fls_base_factor g"
]
fls_base_factor_subdegree[of g] deg0
fls_regpart_subdegree_conv[of g] fps_unit_factor_fls_regpart[of g] by (simp add:
fls_conv_base_factor_shift_subdegree fls_regpart_subdegree_conv fps_divide_def
) qed (rule deg0) qed
lemma fls_divide_fls_base_factor_to_fps': fixes f g :: "'a::{comm_monoid_add,uminus,inverse,mult_zero} fls" shows "fls_base_factor_to_fps f / fls_base_factor_to_fps g = fls_regpart (fls_shift (fls_subdegree f - fls_subdegree g) (f / g))" using fls_base_factor_subdegree[of f] fls_base_factor_subdegree[of g]
fls_divide_regpart[of "fls_base_factor f""fls_base_factor g"]
fls_divide_base_factor'[of f g] by simp
lemma fls_divide_fls_base_factor_to_fps: fixes f g :: "'a::division_ring fls" shows"fls_base_factor_to_fps f / fls_base_factor_to_fps g = fls_base_factor_to_fps (f / g)" using fls_divide_fls_base_factor_to_fps' fls_divide_subdegree[of f g] by fastforce
lemma fls_divide_fps_to_fls: fixes f g :: "'a::{inverse,ab_group_add,mult_zero} fps" assumes"subdegree f ≥ subdegree g" shows"fps_to_fls f / fps_to_fls g = fps_to_fls (f/g)"
proof- have 1: "fps_to_fls f / fps_to_fls g = fls_shift (int (subdegree g)) (fps_to_fls (f * inverse (unit_factor g)))" using fls_base_factor_to_fps_to_fls[of f] fls_base_factor_to_fps_to_fls[of g]
fls_subdegree_fls_to_fps[of f] fls_subdegree_fls_to_fps[of g]
fps_divide_def[of "unit_factor f""unit_factor g"]
fls_times_fps_to_fls[of "unit_factor f""inverse (unit_factor g)"]
fls_shifted_times_simps(2)[of "-int (subdegree f)""fps_to_fls (unit_factor f)"]
fls_times_fps_to_fls[of f "inverse (unit_factor g)"] by (simp add: fls_divide_def) with assms show ?thesis using fps_mult_subdegree_ge[of f "inverse (unit_factor g)"]
fps_shift_to_fls[of "subdegree g""f * inverse (unit_factor g)"] by (cases "f * inverse (unit_factor g) = 0") (simp_all add: fps_divide_def) qed
lemma fls_divide_1': fixes f :: "'a::{comm_monoid_add,inverse,mult_zero,uminus,zero_neq_one,monoid_mult} fls" assumes"inverse (1::'a) = 1" shows"f / 1 = f" using assms fls_conv_base_factor_to_fps_shift_subdegree[of f] by (simp add: fls_divide_def fps_divide_1')
lemma fls_divide_1 [simp]: "a / 1 = (a::'a::division_ring fls)" by (rule fls_divide_1'[OF inverse_1])
lemma fls_const_divide_const: fixes x y :: "'a::division_ring" shows"fls_const x / fls_const y = fls_const (x/y)" by (simp add: fls_divide_def fls_base_factor_to_fps_const fps_const_divide)
lemma fls_divide_X': fixes f :: "'a::{comm_monoid_add,inverse,mult_zero,uminus,zero_neq_one,monoid_mult} fls" assumes"inverse (1::'a) = 1" shows"f / fls_X = fls_shift 1 f"
proof- from assms have "f / fls_X = fls_shift 1 (fls_shift (-fls_subdegree f) (fps_to_fls (fls_base_factor_to_fps f)))" by (simp add: fls_divide_def fps_divide_1') alsohave"… = fls_shift 1 f" using fls_conv_base_factor_to_fps_shift_subdegree[of f] by simp finallyshow ?thesis by simp qed
lemma fls_divide_X [simp]: fixes f :: "'a::division_ring fls" shows"f / fls_X = fls_shift 1 f" by (rule fls_divide_X'[OF inverse_1])
lemma fls_divide_X_power': fixes f :: "'a::{semiring_1,inverse,uminus} fls" assumes"inverse (1::'a) = 1" shows"f / (fls_X ^ n) = fls_shift n f"
proof- have"fls_base_factor_to_fps ((fls_X::'a fls) ^ n) = 1"by (rule fls_X_power_base_factor_to_fps) with assms have "f / (fls_X ^ n) = fls_shift n (fls_shift (-fls_subdegree f) (fps_to_fls (fls_base_factor_to_fps f)))" by (simp add: fls_divide_def fps_divide_1') alsohave"… = fls_shift n f" using fls_conv_base_factor_to_fps_shift_subdegree[of f] by simp finallyshow ?thesis by simp qed
lemma fls_divide_X_power [simp]: fixes f :: "'a::division_ring fls" shows"f / (fls_X ^ n) = fls_shift n f" by (rule fls_divide_X_power'[OF inverse_1])
lemma fls_divide_X_inv': fixes f :: "'a::{comm_monoid_add,inverse,mult_zero,uminus,zero_neq_one,monoid_mult} fls" assumes"inverse (1::'a) = 1" shows"f / fls_X_inv = fls_shift (-1) f"
proof- from assms have "f / fls_X_inv = fls_shift (-1) (fls_shift (-fls_subdegree f) (fps_to_fls (fls_base_factor_to_fps f)))" by (simp add: fls_divide_def fps_divide_1' algebra_simps) alsohave"… = fls_shift (-1) f" using fls_conv_base_factor_to_fps_shift_subdegree[of f] by simp finallyshow ?thesis by simp qed
lemma fls_divide_X_inv [simp]: fixes f :: "'a::division_ring fls" shows"f / fls_X_inv = fls_shift (-1) f" by (rule fls_divide_X_inv'[OF inverse_1])
lemma fls_divide_X_inv_power': fixes f :: "'a::{semiring_1,inverse,uminus} fls" assumes"inverse (1::'a) = 1" shows"f / (fls_X_inv ^ n) = fls_shift (-int n) f"
proof- have"fls_base_factor_to_fps ((fls_X_inv::'a fls) ^ n) = 1" by (rule fls_X_inv_power_base_factor_to_fps) with assms have "f / (fls_X_inv ^ n) = fls_shift (-int n + -fls_subdegree f) (fps_to_fls (fls_base_factor_to_fps f))" by (simp add: fls_divide_def fps_divide_1') alsohave "… = fls_shift (-int n) (fls_shift (-fls_subdegree f) (fps_to_fls (fls_base_factor_to_fps f)))" by (simp add: add.commute) alsohave"… = fls_shift (-int n) f" using fls_conv_base_factor_to_fps_shift_subdegree[of f] by simp finallyshow ?thesis by simp qed
lemma fls_divide_X_intpow': fixes f :: "'a::{semiring_1,inverse,uminus} fls" assumes"inverse (1::'a) = 1" shows"f / (fls_X_intpow i) = fls_shift i f" using assms by (simp add: fls_divide_shift_denom_nonzero fls_divide_1')
lemma fls_divide_X_intpow_conv_times': fixes f :: "'a::{semiring_1,inverse,uminus} fls" assumes"inverse (1::'a) = 1" shows"f / (fls_X_intpow i) = f * fls_X_intpow (-i)" using assms fls_X_intpow_times_conv_shift(2)[of f "-i"] by (simp add: fls_divide_X_intpow')
lemma fls_divide_X_intpow: fixes f :: "'a::division_ring fls" shows"f / (fls_X_intpow i) = fls_shift i f" by (rule fls_divide_X_intpow'[OF inverse_1])
lemma fls_divide_X_intpow_conv_times: fixes f :: "'a::division_ring fls" shows"f / (fls_X_intpow i) = f * fls_X_intpow (-i)" by (rule fls_divide_X_intpow_conv_times'[OF inverse_1])
lemma fls_X_intpow_div_fls_X_intpow_semiring1: assumes"inverse (1::'a::{semiring_1,inverse,uminus}) = 1" shows"(fls_X_intpow i :: 'a fls) / fls_X_intpow j = fls_X_intpow (i-j)" by (simp add: assms fls_divide_shift_both_nonzero fls_divide_1')
lemma fls_X_intpow_div_fls_X_intpow: "(fls_X_intpow i :: 'a::division_ring fls) / fls_X_intpow j = fls_X_intpow (i-j)" by (rule fls_X_intpow_div_fls_X_intpow_semiring1[OF inverse_1])
lemma fls_divide_add: fixes f g h :: "'a::{semiring_0,inverse,uminus} fls" shows"(f + g) / h = f / h + g / h" by (simp add: fls_divide_convert_times_inverse algebra_simps)
lemma fls_divide_diff: fixes f g h :: "'a::{ring,inverse} fls" shows"(f - g) / h = f / h - g / h" by (simp add: fls_divide_convert_times_inverse algebra_simps)
lemma fls_divide_uminus: fixes f g h :: "'a::{ring,inverse} fls" shows"(- f) / g = - (f / g)" by (simp add: fls_divide_convert_times_inverse)
lemma fls_divide_uminus': fixes f g h :: "'a::division_ring fls" shows"f / (- g) = - (f / g)" by (simp add: fls_divide_convert_times_inverse)
subsubsection ‹Units›
lemma fls_is_left_unit_iff_base_is_left_unit: fixes f :: "'a :: ring_1_no_zero_divisors fls" shows"(∃g. 1 = f * g) ⟷ (∃k. 1 = f $$ fls_subdegree f * k)" proof assume"∃g. 1 = f * g" thenobtain g where"1 = f * g"by fast hence"1 = (f $$ fls_subdegree f) * (g $$ fls_subdegree g)" using fls_subdegree_mult[of f g] fls_times_base[of f g] by fastforce thus"∃k. 1 = f $$ fls_subdegree f * k"by fast next assume"∃k. 1 = f $$ fls_subdegree f * k" thenobtain k where"1 = f $$ fls_subdegree f * k"by fast hence"1 = f * fls_right_inverse f k" using fls_right_inverse by simp thus"∃g. 1 = f * g"by fast qed
lemma fls_is_right_unit_iff_base_is_right_unit: fixes f :: "'a :: ring_1_no_zero_divisors fls" shows"(∃g. 1 = g * f) ⟷ (∃k. 1 = k * f $$ fls_subdegree f)" proof assume"∃g. 1 = g * f" thenobtain g where"1 = g * f"by fast hence"1 = (g $$ fls_subdegree g) * (f $$ fls_subdegree f)" using fls_subdegree_mult[of g f] fls_times_base[of g f] by fastforce thus"∃k. 1 = k * f $$ fls_subdegree f"by fast next assume"∃k. 1 = k * f $$ fls_subdegree f" thenobtain k where"1 = k * f $$ fls_subdegree f"by fast hence"1 = fls_left_inverse f k * f" using fls_left_inverse by simp thus"∃g. 1 = g * f"by fast qed
subsection‹Composition›
definition fls_compose_fps :: "'a :: field fls ==> 'a fps ==> 'a fls"where "fls_compose_fps F G = fps_to_fls (fps_compose (fls_base_factor_to_fps F) G) * fps_to_fls G powi fls_subdegree F"
lemma fps_compose_of_nat [simp]: "fps_compose (of_nat n :: 'a :: comm_ring_1 fps) H = of_nat n" and fps_compose_of_int [simp]: "fps_compose (of_int i) H = of_int i" unfolding fps_of_nat [symmetric] fps_of_int [symmetric] numeral_fps_const by (rule fps_const_compose)+
lemma fls_compose_fps_0 [simp]: "fls_compose_fps 0 H = 0" and fls_compose_fps_1 [simp]: "fls_compose_fps 1 H = 1" and fls_compose_fps_const [simp]: "fls_compose_fps (fls_const c) H = fls_const c" and fls_compose_fps_of_nat [simp]: "fls_compose_fps (of_nat n) H = of_nat n" and fls_compose_fps_of_int [simp]: "fls_compose_fps (of_int i) H = of_int i" and fls_compose_fps_X [simp]: "fls_compose_fps fls_X F = fps_to_fls F" by (simp_all add: fls_compose_fps_def)
lemma fls_compose_fps_0_right: "fls_compose_fps F 0 = (if 0 ≤ fls_subdegree F then fls_const (F $$ 0) else 0)" by (cases "fls_subdegree F = 0") (simp_all add: fls_compose_fps_def)
lemma fls_compose_fps_shift: assumes"H ≠ 0" shows"fls_compose_fps (fls_shift n F) H = fls_compose_fps F H * fps_to_fls H powi (-n)" proof (cases "F = 0") case False thus ?thesis using assms by (simp add: fls_compose_fps_def power_int_diff power_int_minus field_simps) qed auto
lemma fls_compose_fps_to_fls [simp]: assumes [simp]: "G ≠ 0""fps_nth G 0 = 0" shows"fls_compose_fps (fps_to_fls F) G = fps_to_fls (fps_compose F G)" proof (cases "F = 0") case False
define n where"n = subdegree F"
define F' where"F' = fps_shift n F" have [simp]: "F' ≠ 0""subdegree F' = 0" using False by (auto simp: F'_def n_def) have F_eq: "F = F' * fps_X ^ n" unfolding F'_def n_def using subdegree_decompose by blast have"fls_compose_fps (fps_to_fls F) G = fps_to_fls (fps_shift n (fls_regpart (fps_to_fls F' * fls_X_intpow (int n))) oo G) * fps_to_fls (G ^ n)" unfolding F_eq fls_compose_fps_def by (simp add: fls_times_fps_to_fls fls_X_power_conv_shift_1 power_int_add
fls_subdegree_fls_to_fps fps_to_fls_power fls_regpart_shift_conv_fps_shift
flip: fls_times_both_shifted_simp) alsohave"fps_to_fls F' * fls_X_intpow (int n) = fps_to_fls F" by (simp add: F_eq fls_times_fps_to_fls fps_to_fls_power fls_X_power_conv_shift_1) alsohave"fps_to_fls (fps_shift n (fls_regpart (fps_to_fls F)) oo G) * fps_to_fls (G ^ n) = fps_to_fls ((fps_shift n (fls_regpart (fps_to_fls F)) * fps_X ^ n) oo G)" by (simp add: fls_times_fps_to_fls flip: fps_compose_power add: fps_compose_mult_distrib) alsohave"fps_shift n (fls_regpart (fps_to_fls F)) * fps_X ^ n = F" by (simp add: F_eq) finallyshow ?thesis . qed (auto simp: fls_compose_fps_def)
lemma fls_compose_fps_mult: assumes [simp]: "H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps (F * G) H = fls_compose_fps F H * fls_compose_fps G H" using assms proof (cases "F * G = 0") case False hence [simp]: "F ≠ 0""G ≠ 0" by auto
define n m where"n = fls_subdegree F""m = fls_subdegree G"
define F' where"F' = fls_regpart (fls_shift n F)"
define G' where"G' = fls_regpart (fls_shift m G)" have F_eq: "F = fls_shift (-n) (fps_to_fls F')"and G_eq: "G = fls_shift (-m) (fps_to_fls G')" by (simp_all add: F'_def G'_def n_m_def) have"fls_compose_fps (F * G) H = fls_compose_fps (fls_shift (-(n + m)) (fps_to_fls (F' * G'))) H" by (simp add: fls_times_fps_to_fls F_eq G_eq fls_shifted_times_simps) alsohave"… = fps_to_fls ((F' oo H) * (G' oo H)) * fps_to_fls H powi (m + n)" by (simp add: fls_compose_fps_shift fps_compose_mult_distrib) alsohave"… = fls_compose_fps F H * fls_compose_fps G H" by (simp add: F_eq G_eq fls_compose_fps_shift fls_times_fps_to_fls power_int_add) finallyshow ?thesis . qed auto
lemma fls_compose_fps_power: assumes [simp]: "G ≠ 0""fps_nth G 0 = 0" shows"fls_compose_fps (F ^ n) G = fls_compose_fps F G ^ n" by (induction n) (auto simp: fls_compose_fps_mult)
lemma fls_compose_fps_add: assumes [simp]: "H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps (F + G) H = fls_compose_fps F H + fls_compose_fps G H" proof (cases "F = 0 ∨ G = 0") case False hence [simp]: "F ≠ 0""G ≠ 0" by auto
define n where"n = min (fls_subdegree F) (fls_subdegree G)"
define F' where"F' = fls_regpart (fls_shift n F)"
define G' where"G' = fls_regpart (fls_shift n G)" have F_eq: "F = fls_shift (-n) (fps_to_fls F')"and G_eq: "G = fls_shift (-n) (fps_to_fls G')" unfolding n_def by (simp_all add: F'_def G'_def n_def) have"F + G = fls_shift (-n) (fps_to_fls (F' + G'))" by (simp add: F_eq G_eq) alsohave"fls_compose_fps … H = fls_compose_fps (fps_to_fls (F' + G')) H * fps_to_fls H powi n" by (subst fls_compose_fps_shift) auto alsohave"… = fps_to_fls (fps_compose (F' + G') H) * fps_to_fls H powi n" by (subst fls_compose_fps_to_fls) auto alsohave"… = fls_compose_fps F H + fls_compose_fps G H" by (simp add: F_eq G_eq fls_compose_fps_shift fps_compose_add_distrib algebra_simps) finallyshow ?thesis . qed auto
lemma fls_compose_fps_uminus [simp]: "fls_compose_fps (-F) H = -fls_compose_fps F H" by (simp add: fls_compose_fps_def fps_compose_uminus)
lemma fls_compose_fps_diff: assumes [simp]: "H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps (F - G) H = fls_compose_fps F H - fls_compose_fps G H" using fls_compose_fps_add[of H F "-G"] by simp
lemma fls_compose_fps_eq_0_iff: assumes"H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps F H = 0 ⟷ F = 0" using assms fls_base_factor_to_fps_nonzero[of F] by (cases "F = 0") (auto simp: fls_compose_fps_def fps_compose_eq_0_iff)
lemma fls_compose_fps_inverse: assumes [simp]: "H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps (inverse F) H = inverse (fls_compose_fps F H)" proof (cases "F = 0") case False have"fls_compose_fps (inverse F) H * fls_compose_fps F H = fls_compose_fps (inverse F * F) H" by (subst fls_compose_fps_mult) auto alsohave"inverse F * F = 1" using False by simp finallyshow ?thesis using False by (simp add: field_simps fls_compose_fps_eq_0_iff) qed auto
lemma fls_compose_fps_divide: assumes [simp]: "H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps (F / G) H = fls_compose_fps F H / fls_compose_fps G H" using fls_compose_fps_mult[of H F "inverse G"] fls_compose_fps_inverse[of H G] by (simp add: field_simps)
lemma fls_compose_fps_powi: assumes [simp]: "H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps (F powi n) H = fls_compose_fps F H powi n" by (simp add: power_int_def fls_compose_fps_power fls_compose_fps_inverse)
lemma fls_compose_fps_assoc: assumes [simp]: "G ≠ 0""fps_nth G 0 = 0""H ≠ 0""fps_nth H 0 = 0" shows"fls_compose_fps (fls_compose_fps F G) H = fls_compose_fps F (fps_compose G H)" proof (cases "F = 0") case [simp]: False
define n where"n = fls_subdegree F"
define F' where"F' = fls_regpart (fls_shift n F)" have F_eq: "F = fls_shift (-n) (fps_to_fls F')" by (simp add: F'_def n_def) show ?thesis by (simp add: F_eq fls_compose_fps_shift fls_compose_fps_mult fls_compose_fps_powi
fps_compose_eq_0_iff fps_compose_assoc) qed auto
lemma subdegree_pos_iff: "subdegree F > 0 ⟷ F ≠ 0 ∧ fps_nth F 0 = 0" using subdegree_eq_0_iff[of F] by auto
lemma fls_X_power_int [simp]: "fls_X powi n = (fls_X_intpow n :: 'a :: division_ring fls)" by (auto simp: power_int_def fls_X_power_conv_shift_1 fls_inverse_X fls_inverse_shift
simp flip: fls_inverse_X_power)
lemma fls_nth_fls_compose_fps_linear: fixes c :: "'a :: field" assumes [simp]: "c ≠ 0" shows"fls_compose_fps F (fps_const c * fps_X) $$ n = F $$ n * c powi n" proof -
{ assume *: "n ≥ fls_subdegree F" hence"c ^ nat (n - fls_subdegree F) = c powi int (nat (n - fls_subdegree F))" by (simp add: power_int_def) alsohave"… * c powi fls_subdegree F = c powi (int (nat (n - fls_subdegree F)) + fls_subdegree F)" using * by (subst power_int_add) auto alsohave"… = c powi n" using * by simp finallyhave"c ^ nat (n - fls_subdegree F) * c powi fls_subdegree F = c powi n" .
} thus ?thesis by (simp add: fls_compose_fps_def fps_compose_linear fls_times_fps_to_fls power_int_mult_distrib
fls_shifted_times_simps
flip: fls_const_power_int) qed
lemma fls_const_transfer [transfer_rule]: "rel_fun (=) (pcr_fls (=)) (λc n. if n = 0 then c else 0) fls_const" by (auto simp: fls_const_def rel_fun_def pcr_fls_def OO_def cr_fls_def)
lemma fls_shift_transfer [transfer_rule]: "rel_fun (=) (rel_fun (pcr_fls (=)) (pcr_fls (=))) (λn f k. f (k+n)) fls_shift" by (auto simp: fls_const_def rel_fun_def pcr_fls_def OO_def cr_fls_def)
lift_definition fls_compose_power :: "'a :: zero fls ==> nat ==> 'a fls"is "λf d n. if d > 0 ∧ int d dvd n then f (n div int d) else 0" proof - fix f :: "int ==> 'a"and d :: nat assume *: "eventually (λn. f (-int n) = 0) cofinite" show"eventually (λn. (if d > 0 ∧ int d dvd -int n then f (-int n div int d) else 0) = 0) cofinite" proof (cases "d = 0") case False from * have"eventually (λn. f (-int n) = 0) at_top" by (simp add: cofinite_eq_sequentially) hence"eventually (λn. f (-int (n div d)) = 0) at_top" by (rule eventually_compose_filterlim[OF _ filterlim_at_top_div_const_nat]) (use False in auto) hence"eventually (λn. (if d > 0 ∧ int d dvd -int n then f (-int n div int d) else 0) = 0) at_top" by eventually_elim (auto simp: zdiv_int dvd_neg_div) thus ?thesis by (simp add: cofinite_eq_sequentially) qed auto qed
lemma fls_nth_compose_power: assumes"d > 0" shows"fls_compose_power f d $$ n = (if int d dvd n then f $$ (n div int d) else 0)" by (simp add: assms fls_compose_power.rep_eq)
lemma fls_compose_power_0_left [simp]: "fls_compose_power 0 d = 0" by transfer auto
lemma fls_compose_power_1_left [simp]: "d > 0 ==> fls_compose_power 1 d = 1" by transfer (auto simp: fun_eq_iff)
lemma fls_compose_power_const_left [simp]: "d > 0 ==> fls_compose_power (fls_const c) d = fls_const c" by transfer (auto simp: fun_eq_iff)
lemma fls_compose_power_shift [simp]: "d > 0 ==> fls_compose_power (fls_shift n f) d = fls_shift (d * n) (fls_compose_power f d)" by transfer (auto simp: fun_eq_iff add_ac mult_ac)
lemma fls_compose_power_X_intpow [simp]: "d > 0 ==> fls_compose_power (fls_X_intpow n) d = fls_X_intpow (int d * n)" by simp
lemma fls_compose_power_X [simp]: "d > 0 ==> fls_compose_power fls_X d = fls_X_intpow (int d)" by transfer (auto simp: fun_eq_iff)
lemma fls_compose_power_X_inv [simp]: "d > 0 ==> fls_compose_power fls_X_inv d = fls_X_intpow (-int d)" by (simp add: fls_X_inv_conv_shift_1)
lemma fls_compose_power_0_right [simp]: "fls_compose_power f 0 = 0" by transfer auto
lemma fls_compose_power_add [simp]: "fls_compose_power (f + g) d = fls_compose_power f d + fls_compose_power g d" by transfer auto
lemma fls_compose_power_diff [simp]: "fls_compose_power (f - g) d = fls_compose_power f d - fls_compose_power g d" by transfer auto
lemma fls_compose_power_uminus [simp]: "fls_compose_power (-f) d = -fls_compose_power f d" by transfer auto
lemma fps_nth_compose_X_power: "fps_nth (f oo (fps_X ^ d)) n = (if d dvd n then fps_nth f (n div d) else 0)" proof - have"fps_nth (f oo (fps_X ^ d)) n = (∑i = 0..n. f $ i * (fps_X ^ (d * i)) $ n)" unfolding fps_compose_def by (simp add: power_mult) alsohave"… = (∑i∈(if d dvd n then {n div d} else {}). f $ i * (fps_X ^ (d * i)) $ n)" by (intro sum.mono_neutral_right) auto alsohave"… = (if d dvd n then fps_nth f (n div d) else 0)" by auto finallyshow ?thesis . qed
lemma fls_compose_power_fps_to_fls: assumes"d > 0" shows"fls_compose_power (fps_to_fls f) d = fps_to_fls (fps_compose f (fps_X ^ d))" using assms by (intro fls_eqI) (auto simp: fls_nth_compose_power fps_nth_compose_X_power
pos_imp_zdiv_neg_iff div_neg_pos_less0 nat_div_distrib
simp flip: int_dvd_int_iff)
lemma fls_compose_power_mult [simp]: "fls_compose_power (f * g :: 'a :: idom fls) d = fls_compose_power f d * fls_compose_power g d" proof (cases "d > 0") case True
define n where"n = nat (max 0 (max (- fls_subdegree f) (- fls_subdegree g)))" have n_ge: "-fls_subdegree f ≤ int n""-fls_subdegree g ≤ int n" unfolding n_def by auto obtain f' where f': "f = fls_shift n (fps_to_fls f')" using fls_as_fps[OF n_ge(1)] by (auto simp: n_def) obtain g' where g': "g = fls_shift n (fps_to_fls g')" using fls_as_fps[OF n_ge(2)] by (auto simp: n_def) show ?thesis using‹d > 0› by (simp add: f' g' fls_shifted_times_simps mult_ac fls_compose_power_fps_to_fls
fps_compose_mult_distrib flip: fls_times_fps_to_fls) qed auto
lemma fls_compose_power_power [simp]: assumes"d > 0 ∨ n > 0" shows"fls_compose_power (f ^ n :: 'a :: idom fls) d = fls_compose_power f d ^ n" proof (cases "d > 0") case True thus ?thesis by (induction n) auto qed (use assms in auto)
lemma fls_nth_compose_power' [simp]: "d = 0 ∨¬d dvd n ==> fls_compose_power f d $$ int n = 0" "d dvd n ==> d > 0 ==> fls_compose_power f d $$ int n = f $$ int (n div d)" by (transfer; force; fail)+
lemma subdegree_fls_compose_fps [simp]: fixes G :: "'a :: field fps" assumes [simp]: "fps_nth G 0 = 0" shows"fls_subdegree (fls_compose_fps F G) = fls_subdegree F * subdegree G" proof (cases "F = 0"; cases "G = 0") assume [simp]: "G ≠ 0""F ≠ 0" have nz1: "fls_base_factor_to_fps F ≠ 0" using‹F ≠ 0› fls_base_factor_to_fps_nonzero by blast show ?thesis unfolding fls_compose_fps_def using nz1 by (subst fls_subdegree_mult) (simp_all add: fps_compose_eq_0_iff fls_subdegree_fls_to_fps) qed (auto simp: fls_compose_fps_0_right)
subsection‹Formal differentiation and integration›
subsubsection ‹Derivative›
definition"fls_deriv f = Abs_fls (λn. of_int (n+1) * f$$(n+1))"
lemma fls_deriv_nth[simp]: "fls_deriv f $$ n = of_int (n+1) * f$$(n+1)"
proof- obtain N where"∀nby (elim fls_nth_vanishes_belowE) hence"∀nby auto thus ?thesis using nth_Abs_fls_lower_bound unfolding fls_deriv_def by simp qed
lemma fls_deriv_residue: "fls_deriv f $$ -1 = 0" by simp
lemma fls_deriv_const[simp]: "fls_deriv (fls_const x) = 0" proof (intro fls_eqI) fix n show"fls_deriv (fls_const x) $$ n = 0$$n" by (cases "n+1=0") auto qed
lemma fls_deriv_subdegree': assumes"of_int (fls_subdegree f) * f $$ fls_subdegree f ≠ 0" shows"fls_subdegree (fls_deriv f) = fls_subdegree f - 1" by (auto intro: fls_subdegree_eqI simp: assms)
lemma fls_deriv_subdegree0: assumes"fls_subdegree f = 0" shows"fls_subdegree (fls_deriv f) ≥ 0" proof (cases "fls_deriv f = 0") case False show ?thesis proof (intro fls_subdegree_geI, rule False) fix k :: int assume"k < 0" with assms show"fls_deriv f $$ k = 0"by (cases "k=-1") auto qed qed simp
lemma fls_subdegree_deriv': fixes f :: "'a::ring_1_no_zero_divisors fls" assumes"(of_int (fls_subdegree f) :: 'a) ≠ 0" shows"fls_subdegree (fls_deriv f) = fls_subdegree f - 1" using assms nth_fls_subdegree_zero_iff[of f] by (auto intro: fls_deriv_subdegree')
lemma fls_subdegree_deriv: fixes f :: "'a::{ring_1_no_zero_divisors,ring_char_0} fls" assumes"fls_subdegree f ≠ 0" shows"fls_subdegree (fls_deriv f) = fls_subdegree f - 1" by (auto intro: fls_subdegree_deriv' simp: assms)
lemma fls_deriv_X_inv [simp]: "fls_deriv fls_X_inv = - (fls_X_inv🪙2)"
proof- have"fls_deriv fls_X_inv = - (fls_shift 2 1)" by (simp add: fls_X_inv_conv_shift_1 fls_deriv_shift) thus ?thesis by (simp add: fls_X_inv_power_conv_shift_1) qed
lemma fls_deriv_delta: "fls_deriv (Abs_fls (λn. if n=m then c else 0)) = Abs_fls (λn. if n=m-1 then of_int m * c else 0)"
proof- have "fls_deriv (Abs_fls (λn. if n=m then c else 0)) = fls_shift (1-m) (fls_const (of_int m * c))" using fls_deriv_shift[of "-m""fls_const c"] by (simp
add: fls_shift_const fls_of_int fls_shifted_times_simps(1)[symmetric]
fls_const_mult_const[symmetric]
del: fls_const_mult_const
) thus ?thesis by (simp add: fls_shift_const) qed
lemma fls_deriv_base_factor: "fls_deriv (fls_base_factor f) = of_int (-fls_subdegree f) * fls_shift (fls_subdegree f + 1) f + fls_shift (fls_subdegree f) (fls_deriv f)" by (simp add: fls_deriv_shift)
lemma fls_regpart_deriv: "fls_regpart (fls_deriv f) = fps_deriv (fls_regpart f)" proof (intro fps_ext) fix n have 1: "(of_nat n :: 'a) + 1 = of_nat (n+1)" and 2: "int n + 1 = int (n + 1)" by auto show"fls_regpart (fls_deriv f) $ n = fps_deriv (fls_regpart f) $ n"by (simp add: 1 2) qed
lemma fls_prpart_deriv: fixes f :: "'a :: {comm_ring_1,ring_no_zero_divisors} fls" 🍋‹Commutivity and no zero divisors are required by the definition of @{const pderiv}.› shows"fls_prpart (fls_deriv f) = - pCons 0 (pCons 0 (pderiv (fls_prpart f)))" proof (intro poly_eqI) fix n show "coeff (fls_prpart (fls_deriv f)) n = coeff (- pCons 0 (pCons 0 (pderiv (fls_prpart f)))) n" proof (cases n) case (Suc m) hence n: "n = Suc m"by fast show ?thesis proof (cases m) case (Suc k) with n have "coeff (- pCons 0 (pCons 0 (pderiv (fls_prpart f)))) n = - coeff (pderiv (fls_prpart f)) k" by (simp flip: coeff_minus) with Suc n show ?thesis by (simp add: coeff_pderiv algebra_simps) qed (simp add: n) qed simp qed
lemma fls_deriv_fps_to_fls: "fls_deriv (fps_to_fls f) = fps_to_fls (fps_deriv f)" proof (intro fls_eqI) fix n show"fls_deriv (fps_to_fls f) $$ n = fps_to_fls (fps_deriv f) $$ n" proof (cases "n≥0") case True from True have 1: "nat (n + 1) = nat n + 1"by simp from True have 2: "(of_int (n + 1) :: 'a) = of_nat (nat (n+1))"by simp from True show ?thesis using arg_cong[OF 2, of "λx. x * f $ (nat n+1)"] by (simp add: 1) next case False thus ?thesis by (cases "n=-1") auto qed qed
subsubsection ‹Algebraic rules of the derivative›
lemma fls_deriv_add [simp]: "fls_deriv (f+g) = fls_deriv f + fls_deriv g" by (auto intro: fls_eqI simp: algebra_simps)
lemma fls_deriv_sub [simp]: "fls_deriv (f-g) = fls_deriv f - fls_deriv g" by (auto intro: fls_eqI simp: algebra_simps)
lemma fls_deriv_neg [simp]: "fls_deriv (-f) = - fls_deriv f" using fls_deriv_sub[of 0 f] by simp
lemma fls_deriv_mult_const_left: "fls_deriv (fls_const c * f) = fls_const c * fls_deriv f" by simp
lemma fls_deriv_linear: "fls_deriv (fls_const a * f + fls_const b * g) = fls_const a * fls_deriv f + fls_const b * fls_deriv g" by simp
lemma fls_deriv_mult_const_right: "fls_deriv (f * fls_const c) = fls_deriv f * fls_const c" by simp
lemma fls_deriv_linear2: "fls_deriv (f * fls_const a + g * fls_const b) = fls_deriv f * fls_const a + fls_deriv g * fls_const b" by simp
lemma fls_deriv_sum: "fls_deriv (sum f S) = sum (λi. fls_deriv (f i)) S" proof (cases "finite S") case True show ?thesis by (induct rule: finite_induct [OF True]) simp_all qed simp
lemma fls_deriv_power: fixes f :: "'a::comm_ring_1 fls" shows"fls_deriv (f^n) = of_nat n * f^(n-1) * fls_deriv f" proof (cases n) case (Suc m) have"fls_deriv (f^Suc m) = of_nat (Suc m) * f^m * fls_deriv f" by (induct m) (simp_all add: algebra_simps) with Suc show ?thesis by simp qed simp
lemma fls_deriv_X_power: "fls_deriv (fls_X ^ n) = of_nat n * fls_X ^ (n-1)" proof (cases n) case (Suc m) have"fls_deriv (fls_X^Suc m) = of_nat (Suc m) * fls_X^m" by (induct m) (simp_all add: mult_of_nat_commute algebra_simps) with Suc show ?thesis by simp qed simp
lemma fls_deriv_X_inv_power: "fls_deriv (fls_X_inv ^ n) = - of_nat n * fls_X_inv ^ (Suc n)" proof (cases n) case (Suc m)
define iX :: "'a fls"where"iX ≡ fls_X_inv" have"fls_deriv (iX ^ Suc m) = - of_nat (Suc m) * iX ^ (Suc (Suc m))" proof (induct m) case (Suc m) have"- of_nat (Suc m + 1) * iX ^ Suc (Suc (Suc m)) = iX * (-of_nat (Suc m) * iX ^ Suc (Suc m)) + - (iX ^ 2 * iX ^ Suc m)" using distrib_right[of "-of_nat (Suc m)""-(1::'a fls)""fls_X_inv ^ Suc (Suc (Suc m))"] by (simp add: algebra_simps mult_of_nat_commute power2_eq_square Suc iX_def) thus ?caseusing Suc by (simp add: iX_def) qed (simp add: numeral_2_eq_2 iX_def) with Suc show ?thesis by (simp add: iX_def) qed simp
lemma fls_deriv_X_intpow: "fls_deriv (fls_X_intpow i) = of_int i * fls_X_intpow (i-1)" by (simp add: fls_deriv_shift)
lemma fls_deriv_lr_inverse: assumes"x * f $$ fls_subdegree f = 1""f $$ fls_subdegree f * y = 1" 🍋‹These assumptions imply x equals y, but no need to assume that.› shows"fls_deriv (fls_left_inverse f x) = - fls_left_inverse f x * fls_deriv f * fls_left_inverse f x" and"fls_deriv (fls_right_inverse f y) = - fls_right_inverse f y * fls_deriv f * fls_right_inverse f y"
proof-
define L where"L ≡ fls_left_inverse f x" hence"fls_deriv (L * f) = 0"using fls_left_inverse[OF assms(1)] by simp with assms show"fls_deriv L = - L * fls_deriv f * L" using fls_right_inverse'[OF assms] by (simp add: minus_unique mult.assoc L_def)
define R where"R ≡ fls_right_inverse f y" hence"fls_deriv (f * R) = 0"using fls_right_inverse[OF assms(2)] by simp hence 1: "f * fls_deriv R + fls_deriv f * R = 0"by simp have"R * f * fls_deriv R = - R * fls_deriv f * R" using iffD2[OF eq_neg_iff_add_eq_0, OF 1] by (simp add: mult.assoc) thus"fls_deriv R = - R * fls_deriv f * R" using fls_left_inverse'[OF assms] by (simp add: R_def)
qed
lemma fls_deriv_lr_inverse_comm: fixes x y :: "'a::comm_ring_1" assumes"x * f $$ fls_subdegree f = 1" shows"fls_deriv (fls_left_inverse f x) = - fls_deriv f * (fls_left_inverse f x)??2" and"fls_deriv (fls_right_inverse f x) = - fls_deriv f * (fls_right_inverse f x)??2" using assms fls_deriv_lr_inverse[of x f x] by (simp_all add: mult.commute power2_eq_square)
lemma fls_inverse_deriv_divring: fixes a :: "'a::division_ring fls" shows"fls_deriv (inverse a) = - inverse a * fls_deriv a * inverse a" proof (cases "a=0") case False thus ?thesis using fls_deriv_lr_inverse(2)[of "inverse (a $$ fls_subdegree a)" a "inverse (a $$ fls_subdegree a)"
] by (auto simp add: fls_inverse_def') qed simp
lemma fls_inverse_deriv: fixes a :: "'a::field fls" shows"fls_deriv (inverse a) = - fls_deriv a * (inverse a)🪙2" by (simp add: fls_inverse_deriv_divring power2_eq_square)
lemma fls_inverse_deriv': fixes a :: "'a::field fls" shows"fls_deriv (inverse a) = - fls_deriv a / a🪙2" using fls_inverse_deriv[of a] by (simp add: field_simps)
subsubsection ‹Equality of derivatives›
lemma fls_deriv_eq_0_iff: "fls_deriv f = 0 ⟷ f = fls_const (f$$0 :: 'a::{ring_1_no_zero_divisors,ring_char_0})" proof assume f: "fls_deriv f = 0" show"f = fls_const (f$$0)" proof (intro fls_eqI) fix n from f have"of_int n * f$$ n = 0"using fls_deriv_nth[of f "n-1"] by simp thus"f$$n = fls_const (f$$0) $$ n"by (cases "n=0") auto qed next show"f = fls_const (f$$0) ==> fls_deriv f = 0"using fls_deriv_const[of "f$$0"] by simp qed
lemma fls_deriv_eq_iff: fixes f g :: "'a::{ring_1_no_zero_divisors,ring_char_0} fls" shows"fls_deriv f = fls_deriv g ⟷ (f = fls_const(f$$0 - g$$0) + g)" proof - have"fls_deriv f = fls_deriv g ⟷ fls_deriv (f - g) = 0" by simp alsohave"…⟷ f - g = fls_const ((f - g) $$ 0)" unfolding fls_deriv_eq_0_iff .. finallyshow ?thesis by (simp add: field_simps) qed
lemma fls_deriv_eq_iff_ex: fixes f g :: "'a::{ring_1_no_zero_divisors,ring_char_0} fls" shows"(fls_deriv f = fls_deriv g) ⟷ (∃c. f = fls_const c + g)" by (auto simp: fls_deriv_eq_iff)
subsubsection ‹Residues›
definition fls_residue_def[simp]: "fls_residue f ≡ f $$ -1"
lemma fls_residue_deriv: "fls_residue (fls_deriv f) = 0" by simp
lemma fls_residue_add: "fls_residue (f+g) = fls_residue f + fls_residue g" by simp
lemma fls_residue_times_deriv: "fls_residue (fls_deriv f * g) = - fls_residue (f * fls_deriv g)" using fls_residue_deriv[of "f*g"] minus_unique[of "fls_residue (f * fls_deriv g)"] by simp
lemma fls_residue_power_series: "fls_subdegree f ≥ 0 ==> fls_residue f = 0" by simp
lemma fls_residue_fls_X_intpow: "fls_residue (fls_X_intpow i) = (if i=-1 then 1 else 0)" by simp
lemma fls_residue_shift_nth: fixes f :: "'a::semiring_1 fls" shows"f$$n = fls_residue (fls_X_intpow (-n-1) * f)" by (simp add: fls_shifted_times_transfer)
lemma fls_residue_fls_const_times: fixes f :: "'a::{comm_monoid_add, mult_zero} fls" shows"fls_residue (fls_const c * f) = c * fls_residue f" and"fls_residue (f * fls_const c) = fls_residue f * c" by simp_all
lemma fls_residue_of_int_times: fixes f :: "'a::ring_1 fls" shows"fls_residue (of_int i * f) = of_int i * fls_residue f" and"fls_residue (f * of_int i) = fls_residue f * of_int i" by (simp_all add: fls_residue_fls_const_times fls_of_int)
lemma fls_residue_deriv_times_lr_inverse_eq_subdegree: fixes f g :: "'a::ring_1 fls" assumes"y * (f $$ fls_subdegree f) = 1""(f $$ fls_subdegree f) * y = 1" shows"fls_residue (fls_deriv f * fls_right_inverse f y) = of_int (fls_subdegree f)" and"fls_residue (fls_deriv f * fls_left_inverse f y) = of_int (fls_subdegree f)" and"fls_residue (fls_left_inverse f y * fls_deriv f) = of_int (fls_subdegree f)" and"fls_residue (fls_right_inverse f y * fls_deriv f) = of_int (fls_subdegree f)"
proof-
define df :: int where"df ≡ fls_subdegree f"
define B X :: "'a fls" where"B ≡ fls_base_factor f" and"X ≡ (fls_X_intpow df :: 'a fls)"
define D L R :: "'a fls" where"D ≡ fls_deriv B" and"L ≡ fls_left_inverse B y" and"R ≡ fls_right_inverse B y" have intpow_diff: "fls_X_intpow (df - 1) = X * fls_X_inv" using fls_X_intpow_diff_conv_times[of df 1] by (simp add: X_def fls_X_inv_conv_shift_1)
show"fls_residue (fls_deriv f * fls_right_inverse f y) = of_int df"
proof- have subdegree_DR: "fls_subdegree (D * R) ≥ 0" using fls_base_factor_subdegree[of f] fls_base_factor_subdegree[of "fls_right_inverse f y"]
assms(1) fls_right_inverse_base_factor[of y f] fls_mult_subdegree_ge_0[of D R] by (force simp: fls_deriv_subdegree0 D_def R_def B_def) have decomp: "f = X * B" unfolding X_def B_def df_def by (rule fls_base_factor_X_power_decompose(2)[of f]) hence"fls_deriv f = X * D + of_int df * X * fls_X_inv * B" using intpow_diff fls_deriv_mult[of X B] by (simp add: fls_deriv_X_intpow X_def B_def D_def mult.assoc) moreoverfrom assms have"fls_right_inverse (X * B) y = R * fls_right_inverse X 1" using fls_base_factor_base[of f] fls_lr_inverse_mult_ring1(2)[of 1 X] by (simp add: X_def B_def R_def) ultimatelyhave "fls_deriv f * fls_right_inverse f y = (D + of_int df * fls_X_inv * B) * R * (X * fls_right_inverse X 1)" by (simp add: decomp algebra_simps X_def fls_X_intpow_times_comm) alsohave"… = D * R + of_int df * fls_X_inv" using fls_right_inverse[of X 1]
assms fls_base_factor_base[of f] fls_right_inverse[of B y] by (simp add: X_def distrib_right mult.assoc B_def R_def) finallyshow ?thesis using subdegree_DR by simp qed
with assms show"fls_residue (fls_deriv f * fls_left_inverse f y) = of_int df" using fls_left_inverse_eq_fls_right_inverse[of y f] by simp
show"fls_residue (fls_left_inverse f y * fls_deriv f) = of_int df"
proof- have subdegree_LD: "fls_subdegree (L * D) ≥ 0" using fls_base_factor_subdegree[of f] fls_base_factor_subdegree[of "fls_left_inverse f y"]
assms(1) fls_left_inverse_base_factor[of y f] fls_mult_subdegree_ge_0[of L D] by (force simp: fls_deriv_subdegree0 D_def L_def B_def) have decomp: "f = B * X" unfolding X_def B_def df_def by (rule fls_base_factor_X_power_decompose(1)[of f]) hence"fls_deriv f = D * X + B * of_int df * X * fls_X_inv" using intpow_diff fls_deriv_mult[of B X] by (simp add: fls_deriv_X_intpow X_def D_def B_def mult.assoc) moreoverfrom assms have"fls_left_inverse (B * X) y = fls_left_inverse X 1 * L" using fls_base_factor_base[of f] fls_lr_inverse_mult_ring1(1)[of _ _ 1 X] by (simp add: X_def B_def L_def) ultimatelyhave "fls_left_inverse f y * fls_deriv f = fls_left_inverse X 1 * X * L * (D + B * (of_int df * fls_X_inv))" by (simp add: decomp algebra_simps X_def fls_X_intpow_times_comm) alsohave"… = L * D + of_int df * fls_X_inv" using assms fls_left_inverse[of 1 X] fls_base_factor_base[of f] fls_left_inverse[of y B] by (simp add: X_def distrib_left mult.assoc[symmetric] L_def B_def) finallyshow ?thesis using subdegree_LD by simp qed
with assms show"fls_residue (fls_right_inverse f y * fls_deriv f) = of_int df" using fls_left_inverse_eq_fls_right_inverse[of y f] by simp
qed
lemma fls_residue_deriv_times_inverse_eq_subdegree: fixes f g :: "'a::division_ring fls" shows"fls_residue (fls_deriv f * inverse f) = of_int (fls_subdegree f)" and"fls_residue (inverse f * fls_deriv f) = of_int (fls_subdegree f)"
proof- show"fls_residue (fls_deriv f * inverse f) = of_int (fls_subdegree f)" using fls_residue_deriv_times_lr_inverse_eq_subdegree(1)[of _ f] by (cases "f=0") (auto simp: fls_inverse_def') show"fls_residue (inverse f * fls_deriv f) = of_int (fls_subdegree f)" using fls_residue_deriv_times_lr_inverse_eq_subdegree(4)[of _ f] by (cases "f=0") (auto simp: fls_inverse_def') qed
subsubsection ‹Integral definition and basic properties›
definition fls_integral :: "'a::{ring_1,inverse} fls ==> 'a fls" where"fls_integral a = Abs_fls (λn. if n=0 then 0 else inverse (of_int n) * a$$(n - 1))"
lemma fls_integral_nth [simp]: "fls_integral a $$ n = (if n=0 then 0 else inverse (of_int n) * a$$(n-1))"
proof-
define F where"F ≡ (λn. if n=0 then 0 else inverse (of_int n) * a$$(n - 1))" obtain N where"∀nby (elim fls_nth_vanishes_belowE) hence"∀nby (auto simp add: F_def) thus ?thesis using nth_Abs_fls_lower_bound[of N F] unfolding fls_integral_def F_def by simp qed
lemma fls_integral_conv_fps_zeroth_integral: assumes"fls_subdegree a ≥ 0" shows"fls_integral a = fps_to_fls (fps_integral0 (fls_regpart a))" proof (rule fls_eqI) fix n show"fls_integral a $$ n = fps_to_fls (fps_integral0 (fls_regpart a)) $$ n" proof (cases "n>0") case False with assms show ?thesis by simp next case True hence"int ((nat n) - 1) = n - 1"by simp with True show ?thesis by (simp add: fps_integral_def) qed qed
lemma fls_integral_X_inv_power: assumes"n ≥ 2" shows "fls_integral (fls_X_inv ^ n :: 'a :: {ring_1,inverse} fls) = fls_const (inverse (of_int (1 - int n))) * fls_X_inv ^ (n-1)" proof (rule fls_eqI) fix k show "fls_integral (fls_X_inv ^ n :: 'a fls) $$ k= (fls_const (inverse (of_int (1 - int n))) * fls_X_inv ^ (n-1)) $$ k" proof (cases "k=0") case True with assms show ?thesis by simp next case False from assms have"int (n-1) = int n - 1"by simp hence "(fls_const (inverse (of_int (1 - int n))) * (fls_X_inv:: 'a fls) ^ (n-1)) $$ k = (if k = 1 - int n then inverse (of_int k) else 0)" by (simp add: fls_X_inv_power_times_conv_shift(2)) with False show ?thesis by (simp add: algebra_simps) qed qed
lemma fls_integral_X_inv_power_char0: assumes"n ≥ 2" shows "fls_integral (fls_X_inv ^ n :: 'a :: {ring_char_0,inverse} fls) = inverse (of_int (1 - int n)) * fls_X_inv ^ (n-1)"
proof- from assms have"(of_int (1 - int n) :: 'a) ≠ 0"by simp hence "fls_const (inverse (of_int (1 - int n) :: 'a)) = inverse (fls_const (of_int (1 - int n)))" by (simp add: fls_inverse_const) moreoverhave "fls_integral (fls_X_inv ^ n :: 'a fls) = fls_const (inverse (of_int (1 - int n))) * fls_X_inv ^ (n-1)" using assms by (rule fls_integral_X_inv_power) ultimatelyshow ?thesis by (simp add: fls_of_int) qed
lemma fls_integral_X_inv_power': assumes"n ≥ 1" shows "fls_integral (fls_X_inv ^ n :: 'a :: division_ring fls) = - fls_const (inverse (of_nat (n-1))) * fls_X_inv ^ (n-1)" proof (cases "n = 1") case False with assms have n: "n ≥ 2"by simp hence "fls_integral (fls_X_inv ^ n :: 'a fls) = fls_const (inverse (- of_nat (nat (int n - 1)))) * fls_X_inv ^ (n-1)" by (simp add: fls_integral_X_inv_power) moreoverfrom n have"nat (int n - 1) = n - 1"by simp ultimatelyshow ?thesis using inverse_minus_eq[of "of_nat (n-1) :: 'a"] by simp qed simp
lemma fls_integral_X_inv_power_char0': assumes"n ≥ 1" shows "fls_integral (fls_X_inv ^ n :: 'a :: {division_ring,ring_char_0} fls) = - inverse (of_nat (n-1)) * fls_X_inv ^ (n-1)" proof (cases "n=1") case False with assms show ?thesis by (simp add: fls_integral_X_inv_power' fls_inverse_const fls_of_nat) qed simp
lemma fls_integral_delta: assumes"m ≠ -1" shows "fls_integral (Abs_fls (λn. if n=m then c else 0)) = Abs_fls (λn. if n=m+1 then inverse (of_int (m+1)) * c else 0)" using assms by (intro fls_eqI) auto
lemma fls_regpart_integral: "fls_regpart (fls_integral f) = fps_integral0 (fls_regpart f)" proof (rule fps_ext) fix n show"fls_regpart (fls_integral f) $ n = fps_integral0 (fls_regpart f) $ n" by (cases n) (simp_all add: fps_integral_def) qed
lemma fls_integral_fps_to_fls: "fls_integral (fps_to_fls f) = fps_to_fls (fps_integral0 f)" proof (intro fls_eqI) fix n :: int show"fls_integral (fps_to_fls f) $$ n = fps_to_fls (fps_integral0 f) $$ n" proof (cases "n<1") case True thus ?thesis by simp next case False hence"nat (n-1) = nat n - 1"by simp with False show ?thesis by (cases "nat n") auto qed qed
subsubsection ‹Algebraic rules of the integral›
lemma fls_integral_add [simp]: "fls_integral (f+g) = fls_integral f + fls_integral g" by (intro fls_eqI) (simp add: algebra_simps)
lemma fls_integral_sub [simp]: "fls_integral (f-g) = fls_integral f - fls_integral g" by (intro fls_eqI) (simp add: algebra_simps)
lemma fls_integral_neg [simp]: "fls_integral (-f) = - fls_integral f" using fls_integral_sub[of 0 f] by simp
lemma fls_integral_mult_const_left: "fls_integral (fls_const c * f) = fls_const c * fls_integral (f :: 'a::division_ring fls)" by (intro fls_eqI) (simp add: mult.assoc mult_inverse_of_int_commute)
lemma fls_integral_mult_const_left_comm: fixes f :: "'a::{comm_ring_1,inverse} fls" shows"fls_integral (fls_const c * f) = fls_const c * fls_integral f" by (intro fls_eqI) (simp add: mult.assoc mult.commute)
lemma fls_integral_linear: fixes f g :: "'a::division_ring fls" shows "fls_integral (fls_const a * f + fls_const b * g) = fls_const a * fls_integral f + fls_const b * fls_integral g" by (simp add: fls_integral_mult_const_left)
lemma fls_integral_linear_comm: fixes f g :: "'a::{comm_ring_1,inverse} fls" shows "fls_integral (fls_const a * f + fls_const b * g) = fls_const a * fls_integral f + fls_const b * fls_integral g" by (simp add: fls_integral_mult_const_left_comm)
lemma fls_integral_mult_const_right: "fls_integral (f * fls_const c) = fls_integral f * fls_const c" by (intro fls_eqI) (simp add: mult.assoc)
lemma fls_integral_linear2: "fls_integral (f * fls_const a + g * fls_const b) = fls_integral f * fls_const a + fls_integral g * fls_const b" by (simp add: fls_integral_mult_const_right)
lemma fls_integral_sum: "fls_integral (sum f S) = sum (λi. fls_integral (f i)) S" proof (cases "finite S") case True show ?thesis by (induct rule: finite_induct [OF True]) simp_all qed simp
subsubsection ‹Derivatives of integrals and vice versa›
lemma fls_integral_fls_deriv: fixes a :: "'a::{division_ring,ring_char_0} fls" shows"fls_integral (fls_deriv a) + fls_const (a$$0) = a" by (intro fls_eqI) (simp add: mult.assoc[symmetric])
lemma fls_deriv_fls_integral: fixes a :: "'a::{division_ring,ring_char_0} fls" assumes"fls_residue a = 0" shows"fls_deriv (fls_integral a) = a" proof (intro fls_eqI) fix n :: int show"fls_deriv (fls_integral a) $$ n = a $$ n" proof (cases "n=-1") case True with assms show ?thesis by simp next case False hence"(of_int (n+1) :: 'a) ≠ 0"using of_int_eq_0_iff[of "n+1"] by simp hence"(of_int (n+1) :: 'a) * inverse (of_int (n+1) :: 'a) = (1::'a)" using of_int_eq_0_iff[of "n+1"] by simp moreoverhave "fls_deriv (fls_integral a) $$ n = (if n=-1 then 0 else of_int (n+1) * inverse (of_int (n+1)) * a$$n)" by (simp add: mult.assoc) ultimatelyshow ?thesis by (simp add: False) qed qed
text‹Series with zero residue are precisely the derivatives.›
lemma fls_residue_nonzero_ex_antiderivative: fixes f :: "'a::{division_ring,ring_char_0} fls" assumes"fls_residue f = 0" shows"∃F. fls_deriv F = f" using assms fls_deriv_fls_integral by auto
lemma fls_ex_antiderivative_residue_nonzero: assumes"∃F. fls_deriv F = f" shows"fls_residue f = 0" using assms fls_residue_deriv by auto
lemma fls_residue_nonzero_ex_anitderivative_iff: fixes f :: "'a::{division_ring,ring_char_0} fls" shows"fls_residue f = 0 ⟷ (∃F. fls_deriv F = f)" using fls_residue_nonzero_ex_antiderivative fls_ex_antiderivative_residue_nonzero by fast
subsection‹Topology›
instantiation fls :: (group_add) metric_space begin
definition
dist_fls_def: "dist (a :: 'a fls) b = (if a = b then 0 else if fls_subdegree (a-b) ≥ 0 then inverse (2 ^ nat (fls_subdegree (a-b))) else 2 ^ nat (-fls_subdegree (a-b)) )"
lemma dist_fls_ge0: "dist (a :: 'a fls) b ≥ 0" by (simp add: dist_fls_def)
definition uniformity_fls_def [code del]: "(uniformity :: ('a fls × 'a fls) filter) = (INF e ∈ {0 <..}. principal {(x, y). dist x y < e})"
definition open_fls_def' [code del]: "open (U :: 'a fls set) ⟷ (∀x∈U. eventually (λ(x', y). x' = x ⟶ y ∈ U) uniformity)"
lemma dist_fls_sym: "dist (a :: 'a fls) b = dist b a" by (cases "a≠b", cases "fls_subdegree (a-b) ≥ 0")
(simp_all add: fls_subdegree_minus_sym dist_fls_def)
context begin
private lemma instance_helper: fixes a b c :: "'a fls" assumes neq: "a≠b""a≠c" and dist_ineq: "dist a b > dist a c" shows"fls_subdegree (a - b) < fls_subdegree (a - c)" proof (
cases "fls_subdegree (a-b) ≥ 0""fls_subdegree (a-c) ≥ 0"
rule: case_split[case_product case_split]
) case True_True with neq dist_ineq show ?thesis by (simp add: dist_fls_def) next case False_True with dist_ineq show ?thesis by (simp add: dist_fls_def) next case False_False with neq dist_ineq show ?thesis by (simp add: dist_fls_def) next case True_False with neq have"(1::real) > 2 ^ (nat (fls_subdegree (a-b)) + nat (-fls_subdegree (a-c)))" and"nat (fls_subdegree (a-b)) + nat (-fls_subdegree (a-c)) = nat (fls_subdegree (a-b) - fls_subdegree (a-c))" using dist_ineq by (simp_all add: dist_fls_def field_simps power_add) hence"¬ (1::real) < 2 ^ (nat (fls_subdegree (a-b) - fls_subdegree (a-c)))"by simp hence"¬ (0 < nat (fls_subdegree (a - b) - fls_subdegree (a - c)))"by auto hence"fls_subdegree (a - b) ≤ fls_subdegree (a - c)"by simp with True_False show ?thesis by simp qed
instance proof show th: "dist a b = 0 ⟷ a = b"for a b :: "'a fls" by (simp add: dist_fls_def split: if_split_asm) thenhave th'[simp]: "dist a a = 0"for a :: "'a fls"by simp
fix a b c :: "'a fls"
consider "a = b" | "c = a ∨ c = b" | "a ≠ b""a ≠ c""b ≠ c"by blast thenshow"dist a b ≤ dist a c + dist b c" proof cases case 1 thenshow ?thesis by (simp add: dist_fls_def) next case 2 thenshow ?thesis by (cases "c = a") (simp_all add: th dist_fls_sym) next case neq: 3 have False if"dist a b > dist a c + dist b c" proof - from neq have"dist a b > 0""dist b c > 0""dist a c > 0"by (simp_all add: dist_fls_def) with that have dist_ineq: "dist a b > dist a c""dist a b > dist b c"by simp_all have"fls_subdegree (a - b) < fls_subdegree (a - c)" and"fls_subdegree (a - b) < fls_subdegree (b - c)" using instance_helper[of a b c] instance_helper[of b a c] neq dist_ineq by (simp_all add: dist_fls_sym fls_subdegree_minus_sym) hence"(a - c) $$ fls_subdegree (a - b) = 0"and"(b - c) $$ fls_subdegree (a - b) = 0" by (simp_all only: fls_eq0_below_subdegree) hence"(a - b) $$ fls_subdegree (a - b) = 0"by simp moreoverfrom neq have"(a - b) $$ fls_subdegree (a - b) ≠ 0" by (intro nth_fls_subdegree_nonzero) simp ultimatelyshow False by contradiction qed thus ?thesis by (auto simp: not_le[symmetric]) qed qed (rule open_fls_def' uniformity_fls_def)+
lemma open_fls_def: "open (S :: 'a::group_add fls set) = (∀a ∈ S. ∃r. r >0 ∧ {y. dist y a < r} ⊆ S)" unfolding open_dist subset_eq by simp
subsection‹Notation›
bundle fps_syntax begin notation fls_nth (infixl‹$$› 75) end
unbundle no fps_syntax
end
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.285Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-04-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.