Theory FLS_Prime_Equiv_Depth
theory FLS_Prime_Equiv_Depth
imports
Parametric_Equiv_Depth
"HOL.Equiv_Relations"
"HOL-Computational_Algebra.Formal_Laurent_Series"
begin
unbundle fps_syntax
section ‹
Equivalence of sequences of formal Laurent series relative to divisibility of partial sums by a
fixed prime
›
subsection ‹Preliminaries›
subsubsection ‹Lift/transfer of equivalence relations.›
lemma relfp_transfer:
"reflp r ⟹ reflp (λx y. r (f x) (f y))"
unfolding reflp_def by fast
lemma symp_transfer:
"symp r ⟹ symp (λx y. r (f x) (f y))"
unfolding symp_def by fast
lemma transp_transfer:
"transp r ⟹ transp (λx y. r (f x) (f y))"
unfolding transp_def by fast
lemma equivp_transfer:
"equivp r ⟹ equivp (λx y. r (f x) (f y))"
using relfp_transfer symp_transfer transp_transfer
equivp_reflp_symp_transp[of r] equivp_reflp_symp_transp[of "λx y. r (f x) (f y)"]
by fast
subsubsection ‹An additional fact about products/sums›
lemma (in comm_monoid_set) atLeastAtMost_int_shift_bounds:
"F g {m..n} = F (g ∘ plus m ∘ int) {..nat (n - m)}"
if "m ≤ n"
for m n :: int
proof (rule reindex_bij_witness)
define i :: "nat ⇒ int" and j :: "int ⇒ nat"
where "i ≡ plus m ∘ int"
and "j ≡ (λx. nat (x - m))"
fix a b from i_def j_def that
show "a ∈ {m..n} ⟹ i (j a) = a"
and "a ∈ {m..n} ⟹ j a ∈ {..nat (n - m)}"
and "b ∈ {..nat (n - m)} ⟹ j (i b) = b"
and "b ∈ {..nat (n - m)} ⟹ i b ∈ {m..n}"
and "a ∈ {m..n} ⟹ (g ∘ (+) m ∘ int) (j a) = g a"
by auto
qed
subsubsection ‹An additional fact about algebraic powers of functions›
lemma pow_fun_apply: "(f ^ n) x = (f x) ^ n"
by (induct n, simp_all)
subsubsection ‹Some additional facts about formal power and Laurent series›
lemma fps_shift_fps_mult_by_fps_const:
fixes c :: "'a::{comm_monoid_add,mult_zero}"
shows "fps_shift n (fps_const c * f) = fps_const c * fps_shift n f"
and "fps_shift n (f * fps_const c) = fps_shift n f * fps_const c"
by (auto intro: fps_ext)
lemma fps_shift_mult_Suc:
fixes f g :: "'a::{comm_monoid_add,mult_zero} fps"
shows "fps_shift (Suc n) (f*g)
= fps_const (f$0) * fps_shift (Suc n) g + fps_shift n (fps_shift 1 f * g)"
and "fps_shift (Suc n) (f*g)
= fps_shift n (f * fps_shift 1 g) + fps_shift (Suc n) f * fps_const (g$0)"
proof-
show "fps_shift (Suc n) (f*g)
= fps_const (f$0) * fps_shift (Suc n) g + fps_shift n (fps_shift 1 f * g)"
proof (intro fps_ext)
fix k
have "{0<..Suc (k + n)} = {Suc 0..Suc (k + n)}" by auto
thus
"fps_shift (Suc n) (f*g) $ k
= (fps_const (f$0) * fps_shift (Suc n) g + fps_shift n (fps_shift 1 f * g)) $ k"
using fps_mult_nth[of _ g]
sum.head[of 0 "k + Suc n" "λi. f$i * g$(k + Suc n - i)"]
sum.atLeast_Suc_atMost_Suc_shift[of "λi. f$i * g$(k + Suc n - i)" 0 "k+n"]
by simp
qed
show "fps_shift (Suc n) (f*g)
= fps_shift n (f * fps_shift 1 g) + fps_shift (Suc n) f * fps_const (g$0)"
proof (intro fps_ext)
fix k
have "∀i∈{0..k + n}. Suc (k + n) - i = Suc (k + n -i)" by auto
thus "fps_shift (Suc n) (f*g) $ k
= (fps_shift n (f * fps_shift 1 g) + fps_shift (Suc n) f * fps_const (g$0)) $ k"
using fps_mult_nth[of f] by simp
qed
qed
lemma fls_subdegree_minus':
"fls_subdegree (f - g) = fls_subdegree f"
if "f ≠ 0" and "fls_subdegree g > fls_subdegree f"
using that by (auto intro: fls_subdegree_eqI)
lemma fls_regpart_times_fps_X:
fixes f :: "'a::{comm_monoid_add,mult_zero,monoid_mult} fls"
assumes "fls_subdegree f ≥ 0"
shows "fls_regpart f * fps_X = fls_regpart (fls_shift (-1) f)"
and "fps_X * fls_regpart f = fls_regpart (fls_shift (-1) f)"
proof-
show "fls_regpart f * fps_X = fls_regpart (fls_shift (-1) f)"
proof (intro fps_ext)
fix n show "(fls_regpart f * fps_X) $ n = fls_regpart (fls_shift (-1) f) $ n"
using assms by (cases n) auto
qed
thus "fps_X * fls_regpart f = fls_regpart (fls_shift (-1) f)"
by (simp add: fps_mult_fps_X_commute)
qed
lemma fls_regpart_times_fps_X_power:
fixes f :: "'a::semiring_1 fls"
assumes "fls_subdegree f ≥ 0"
shows "fls_regpart f * fps_X ^ n = fls_regpart (fls_shift (-n) f)"
and "fps_X ^ n * fls_regpart f = fls_regpart (fls_shift (-n) f)"
proof-
show "fps_X ^ n * fls_regpart f = fls_regpart (fls_shift (-n) f)"
proof (induct n)
case (Suc n)
from assms Suc
have A: "fps_X ^ Suc n * fls_regpart f = fls_regpart (fls_shift (-(int n + 1)) f)"
using fls_shift_nonneg_subdegree[of "-int n" f]
by (simp add: mult.assoc fls_regpart_times_fps_X(2))
have B: "- (int n + 1) = - int (Suc n)" by simp
have "fls_regpart (fls_shift (-(int n + 1)) f) = fls_regpart (fls_shift (- int (Suc n)) f)"
using arg_cong[OF B] by simp
with A show ?case by simp
qed simp
thus "fls_regpart f * fps_X ^ n = fls_regpart (fls_shift (-n) f)"
by (simp flip: fps_mult_fps_X_power_commute)
qed
lemma fls_base_factor_uminus: "fls_base_factor (-f) = - fls_base_factor f"
unfolding fls_base_factor_def by simp
subsection ‹Partial evaluation of formal power series›
text ‹Make a degree-n polynomial out of a formal power series.›
definition poly_of_fps
where "poly_of_fps f n = Abs_poly (λi. if i ≤ n then f$i else 0)"
lemma if_then_MOST_zero:
"∀⇩∞x. (if P x then f x else 0) = 0"
if "∀⇩∞x. ¬ P x"
proof (rule iffD2, rule MOST_iff_cofinite)
have "{x. (if P x then f x else 0) ≠ 0} ⊆ {x. ¬ ¬ P x}" by auto
with that show "finite {x. (if P x then f x else 0) ≠ 0}"
using iffD1[OF MOST_iff_cofinite] finite_subset by blast
qed
lemma truncated_fps_eventually_zero:
"(λi. if i ≤ n then f$i else 0) ∈ {g. ∀⇩∞n. g n = 0}"
by (auto intro: if_then_MOST_zero iffD2[OF eventually_cofinite])
lemma coeff_poly_of_fps[simp]:
"coeff (poly_of_fps f n) i = (if i ≤ n then f$i else 0)"
unfolding poly_of_fps_def
using truncated_fps_eventually_zero[of n f]
Abs_poly_inverse[of "λi. if i ≤ n then f$i else 0"]
by simp
lemma poly_of_fps_0[simp]: "poly_of_fps 0 n = 0"
by (auto intro: poly_eqI)
lemma poly_of_fps_0th_conv_pCons[simp]: "poly_of_fps f 0 = [:f$0:]"
proof (intro poly_eqI)
fix i
show "coeff (poly_of_fps f 0) i = coeff [:f$0:] i"
by (cases i) auto
qed
lemma poly_of_fps_degree: "degree (poly_of_fps f n) ≤ n"
by (auto intro: degree_le)
lemma poly_of_fps_Suc:
"poly_of_fps f (Suc n) = poly_of_fps f n + monom (f $ Suc n) (Suc n)"
proof (intro poly_eqI)
fix m
show
"coeff (poly_of_fps f (Suc n)) m =
coeff (poly_of_fps f n + monom (f $ Suc n) (Suc n)) m"
by (cases "m ≤ Suc n") auto
qed
lemma poly_of_fps_Suc_nth_eq0:
"poly_of_fps f (Suc n) = poly_of_fps f n" if "f $ Suc n = 0"
proof (intro poly_eqI)
fix i from that show "coeff (poly_of_fps f (Suc n)) i = coeff (poly_of_fps f n) i"
by (cases i "Suc n" rule: linorder_cases) auto
qed
lemma poly_of_fps_Suc_conv_pCons_shift:
"poly_of_fps f (Suc n) = pCons (f$0) (poly_of_fps (fps_shift 1 f) n)"
proof (intro poly_eqI)
fix i
show "coeff (poly_of_fps f (Suc n)) i
= coeff (pCons (f$0) (poly_of_fps (fps_shift 1 f) n)) i"
by (cases i) auto
qed
abbreviation "fps_parteval f x n ≡ poly (poly_of_fps f n) x"
abbreviation "fls_base_parteval f ≡ fps_parteval (fls_base_factor_to_fps f)"
lemma fps_parteval_0[simp]: "fps_parteval 0 x n = 0"
by (induct n) auto
lemma fps_parteval_0th[simp]: "fps_parteval f x 0 = f $ 0"
by simp
lemma fps_parteval_Suc:
"fps_parteval f x (Suc n) = fps_parteval f x n + (f $ Suc n) * x ^ Suc n"
for f :: "'a::comm_semiring_1 fps"
by (simp add: poly_of_fps_Suc poly_monom)
lemma fps_parteval_Suc_cons:
"fps_parteval f x (Suc n) = f$0 + x * fps_parteval (fps_shift 1 f) x n"
by (simp add: poly_of_fps_Suc_conv_pCons_shift)
lemma fps_parteval_at_0[simp]: "fps_parteval f 0 n = f $ 0"
by (cases n) (auto simp add: fps_parteval_Suc_cons)
lemma fps_parteval_conv_sum:
"fps_parteval f x n = (∑k≤n. f$k * x^k)" for x :: "'a::comm_semiring_1"
by (induct n) (auto simp add: fps_parteval_Suc)
lemma fls_base_parteval_conv_sum:
"fls_base_parteval f x n = (∑k≤n. f$$(fls_subdegree f + int k) * x^k)"
for f :: "'a::comm_semiring_1 fls" and x :: 'a and n :: nat
using fps_parteval_conv_sum[of "fls_base_factor_to_fps f"] fls_base_factor_to_fps_nth[of f]
by presburger
lemma fps_parteval_fps_const[simp]:
"fps_parteval (fps_const c) x n = c"
by (induct n) (auto simp add: fps_parteval_Suc_cons fps_shift_fps_const)
lemma fps_parteval_1[simp]: "fps_parteval 1 x n = 1"
using fps_parteval_fps_const[of 1] by simp
lemma fps_parteval_mult_by_fps_const:
"fps_parteval (fps_const c * f) x n = c * fps_parteval f x n"
using mult.commute[of c x] mult.assoc[of x c] mult.assoc[of c x]
by (induct n arbitrary: f)
(auto simp add: fps_parteval_Suc_cons fps_shift_fps_mult_by_fps_const(1) distrib_left)
lemma fps_parteval_plus[simp]:
"fps_parteval (f + g) x n = fps_parteval f x n + fps_parteval g x n"
by (induct n arbitrary: f g)
(auto simp add: fps_parteval_Suc_cons fps_shift_add algebra_simps)
lemma fps_parteval_uminus[simp]:
"fps_parteval (-f) x n = - fps_parteval f x n" for f :: "'a::comm_ring fps"
by (induct n arbitrary: f) (auto simp add: fps_parteval_Suc_cons fps_shift_uminus)
lemma fps_parteval_minus[simp]:
"fps_parteval (f - g) x n = fps_parteval f x n - fps_parteval g x n"
for f :: "'a::comm_ring fps"
using fps_parteval_plus[of f "-g"] by simp
lemma fps_parteval_mult_fps_X:
fixes f :: "'a::comm_semiring_1 fps"
shows "fps_parteval (f * fps_X) x (Suc n) = x * fps_parteval f x n"
and "fps_parteval (fps_X * f) x (Suc n) = x * fps_parteval f x n"
using fps_shift_times_fps_X'[of f]
by (auto simp add: fps_parteval_Suc_cons simp flip: fps_mult_fps_X_commute)
lemma fps_parteval_mult_fps_X_power:
fixes f :: "'a::comm_semiring_1 fps"
assumes "n ≥ m"
shows "fps_parteval (f * fps_X ^ m) x n = x^m * fps_parteval f x (n - m)"
and "fps_parteval (fps_X ^ m * f) x n = x^m * fps_parteval f x (n - m)"
proof-
have
"n ≥ m ⟹ fps_parteval (f * fps_X ^ m) x n = x^m * fps_parteval f x (n - m)"
proof (induct m arbitrary: n)
case (Suc m) thus ?case
using fps_shift_times_fps_X'[of "f * fps_X^m"]
by (cases n)
(auto simp add: fps_parteval_Suc_cons mult.assoc simp flip: power_Suc2)
qed simp
with assms show "fps_parteval (f * fps_X ^ m) x n = x^m * fps_parteval f x (n - m)"
by fast
thus "fps_parteval (fps_X ^ m * f) x n = x^m * fps_parteval f x (n - m)"
by (simp add: fps_mult_fps_X_power_commute)
qed
lemma fps_parteval_mult_right:
"fps_parteval (f * g) x n =
fps_parteval (Abs_fps (λi. f$i * fps_parteval g x (n - i))) x n"
proof (induct n arbitrary: f)
case (Suc n)
have 1:
"poly_of_fps (Abs_fps (λi. f $ Suc i * fps_parteval g x (n - i))) n
= poly_of_fps (Abs_fps (λi. f $ Suc i * fps_parteval g x (Suc n - Suc i))) n"
by (intro poly_eqI) auto
from Suc have
"fps_parteval (fps_shift 1 f * g) x n
= fps_parteval (Abs_fps (λi. f $ Suc i * fps_parteval g x (n - i))) x n"
by simp
with 1 have
"fps_parteval (f * g) x (Suc n)
= f$0 * fps_parteval g x (Suc n)
+ x * fps_parteval (Abs_fps (λi. f $ Suc i * fps_parteval g x (n - i))) x n
"
using fps_shift_mult_Suc(1)[of 0 f g]
by (simp add: fps_parteval_Suc_cons fps_parteval_mult_by_fps_const algebra_simps)
thus ?case by (simp add: fps_parteval_Suc_cons fps_shift_def)
qed simp
lemma fps_parteval_mult_left:
"fps_parteval (f * g) x n =
fps_parteval (Abs_fps (λi. fps_parteval f x (n - i) * g$i)) x n"
using fps_parteval_mult_right[of g f]
by (simp add: mult.commute)
lemma fps_parteval_mult_conv_sum:
fixes f g :: "'a::comm_semiring_1 fps"
shows "fps_parteval (f * g) x n = (∑k≤n. f$k * fps_parteval g x (n - k) * x^k)"
and "fps_parteval (f * g) x n = (∑k≤n. fps_parteval f x (n - k) * g$k * x^k)"
using fps_parteval_mult_right[of f g n x]
fps_parteval_conv_sum[of "Abs_fps (λi. f$i * fps_parteval g x (n - i))"]
fps_parteval_mult_left[of f g n x]
fps_parteval_conv_sum[of "Abs_fps (λi. fps_parteval f x (n - i) * g$i)"]
by auto
lemma fps_parteval_fls_base_factor_to_fps_diff:
"fls_base_parteval (f - g) x n = fls_base_parteval f x n"
if "f ≠ 0" and "fls_subdegree g > fls_subdegree f + (int n)"
for f g :: "'a::comm_ring_1 fls"
using that
by (induct n) (auto simp add: fps_parteval_Suc fls_subdegree_minus')
subsection ‹
Vanishing of formal power series relative to divisibility of all partial sums
›
definition fps_pvanishes :: "'a::comm_semiring_1 ⇒ 'a fps ⇒ bool"
where "fps_pvanishes p f ≡ (∀n::nat. p ^ Suc n dvd (fps_parteval f p n))"
lemma fps_pvanishesD: "fps_pvanishes p f ⟹ p ^ Suc n dvd (fps_parteval f p n)"
unfolding fps_pvanishes_def by simp
lemma fps_pvanishesI:
"fps_pvanishes p f" if "⋀n::nat. p ^ Suc n dvd (fps_parteval f p n)"
using that unfolding fps_pvanishes_def by simp
lemma fps_pvanishes_0[simp]: "fps_pvanishes p 0"
by (auto intro: fps_pvanishesI)
lemma fps_pvanishes_at_0[simp]: "fps_pvanishes 0 f = (f$0 = 0)"
unfolding fps_pvanishes_def by auto
lemma fps_pvanishes_at_unit: "fps_pvanishes p f" if "is_unit p"
by (metis that is_unit_power_iff unit_imp_dvd fps_pvanishesI)
lemma fps_pvanishes_one_iff:
"fps_pvanishes p 1 = is_unit p"
using fps_pvanishes_def is_unit_power_iff[of p "Suc _"] by auto
lemma fps_pvanishes_uminus[simp]:
"fps_pvanishes p (-f)" if "fps_pvanishes p f" for f :: "'a::comm_ring_1 fps"
using fps_pvanishesD[OF that] iffD2[OF dvd_minus_iff] by (fastforce intro: fps_pvanishesI)
lemma fps_pvanishes_add[simp]:
"fps_pvanishes p (f + g)" if "fps_pvanishes p f" and "fps_pvanishes p g"
for f :: "'a::comm_semiring_1 fps"
proof (intro fps_pvanishesI)
fix n from that show "p ^ Suc n dvd fps_parteval (f+g) p n"
using fps_pvanishesD[of p _ n]
dvd_add[of "p^Suc n" "fps_parteval f p n" "fps_parteval g p n"]
by auto
qed
lemma fps_pvanishes_minus[simp]:
"fps_pvanishes p (f - g)" if "fps_pvanishes p f" and "fps_pvanishes p g"
for f :: "'a::comm_ring_1 fps"
using that fps_pvanishes_uminus[of p g] fps_pvanishes_add[of p f "-g"] by simp
lemma fps_pvanishes_mult: "fps_pvanishes p (f * g)" if "fps_pvanishes p g"
proof (intro fps_pvanishesI)
fix n
have "p ^ Suc n dvd (∑i≤n. f$i * fps_parteval g p (n - i) * p^i)"
proof (intro dvd_sum)
fix k assume "k ∈ {..n}"
with that show "p ^ Suc n dvd f $ k * fps_parteval g p (n - k) * p ^ k"
using fps_pvanishesD[of p g] power_add[of p "Suc (n - k)" k] by (simp add: mult_dvd_mono)
qed
thus "p ^ Suc n dvd fps_parteval (f * g) p n" by (simp add: fps_parteval_mult_conv_sum(1))
qed
lemma fps_pvanishes_mult_fps_X_iff:
assumes "(p::'a::idom) ≠ 0"
shows "fps_pvanishes p f ⟷ fps_pvanishes p (f * fps_X)"
and "fps_pvanishes p f ⟷ fps_pvanishes p (fps_X * f)"
proof-
show "fps_pvanishes p f ⟷ fps_pvanishes p (f * fps_X)"
proof
assume b: "fps_pvanishes p (f * fps_X)"
show "fps_pvanishes p f"
proof (intro fps_pvanishesI)
fix n from b assms show "p ^ Suc n dvd fps_parteval f p n"
using fps_pvanishesD[of p "f * fps_X" "Suc n"] fps_parteval_mult_fps_X(1)[of f n p]
by simp
qed
qed (auto intro: fps_pvanishes_mult simp add: mult.commute)
thus "fps_pvanishes p f ⟷ fps_pvanishes p (fps_X * f)"
by (simp add: fps_mult_fps_X_commute)
qed
lemma fps_pvanishes_mult_fps_X_power_iff:
assumes "(p::'a::idom) ≠ 0"
shows "fps_pvanishes p f ⟷ fps_pvanishes p (f * fps_X ^ n)"
and "fps_pvanishes p f ⟷ fps_pvanishes p (fps_X ^ n * f)"
proof-
show "fps_pvanishes p f ⟷ fps_pvanishes p (fps_X ^ n * f)"
proof (induct n)
case (Suc n) with assms show ?case
using fps_pvanishes_mult_fps_X_iff(2)[of p "fps_X ^ n * f"]
by (simp add: mult.assoc)
qed simp
thus "fps_pvanishes p f ⟷ fps_pvanishes p (f * fps_X ^ n)"
by (simp flip: fps_mult_fps_X_power_commute)
qed
subsection ‹Equivalence and depth of formal Laurent series relative to a prime›
subsubsection ‹Definition of equivalence and basic facts›
abbreviation "fps_primevanishes p ≡ fps_pvanishes (Rep_prime p)"
overloading
p_equal_fls ≡
"p_equal :: 'a::nontrivial_factorial_comm_ring prime ⇒
'a fls ⇒ 'a fls ⇒ bool"
begin
definition p_equal_fls ::
"'a::nontrivial_factorial_comm_ring prime ⇒
'a fls ⇒ 'a fls ⇒ bool"
where
"p_equal_fls p f g ≡ fps_primevanishes p (fls_base_factor_to_fps (f - g))"
end
context
fixes p :: "'a :: nontrivial_factorial_comm_ring prime"
begin
lemma p_equal_flsD:
"f ≃⇩p g ⟹ fps_primevanishes p (fls_base_factor_to_fps (f - g))"
for f g :: "'a fls"
unfolding p_equal_fls_def by simp
lemma p_equal_fls_imp_p_dvd: "p pdvd ((f - g) $$ (fls_subdegree (f - g)))"
if "f ≃⇩p g"
for f g :: "'a fls"
proof-
have "int (0::nat) = 0" by simp
thus ?thesis
by (metis
that p_equal_flsD fps_pvanishesD power_Suc0_right fps_parteval_0th
fls_base_factor_to_fps_nth add_0_right
)
qed
lemma p_equal_flsI:
"fps_primevanishes p (fls_base_factor_to_fps (f - g)) ⟹ f ≃⇩p g"
for f g :: "'a fls"
unfolding p_equal_fls_def by simp
lemma p_equal_fls_conv_p_equal_0:
"f ≃⇩p g ⟷ (f - g) ≃⇩p 0"
for f g :: "'a fls"
unfolding p_equal_fls_def by auto
lemma p_equal_fls_refl: "f ≃⇩p f" for f:: "'a fls"
by (auto intro: p_equal_flsI)
lemma p_equal_fls_sym:
"f ≃⇩p g ⟹ g ≃⇩p f" for f g :: "'a fls"
using p_equal_flsD fps_pvanishes_uminus fls_uminus_subdegree[of "f-g"]
unfolding p_equal_fls_def
by fastforce
lemma p_equal_fls_shift_iff:
"f ≃⇩p g ⟷ (fls_shift n f) ≃⇩p (fls_shift n g)"
for f g :: "'a fls"
using fls_base_factor_shift[of n "f - g"] unfolding p_equal_fls_def by auto
lemma p_equal_fls_extended_sum_iff:
"f ≃⇩p g ⟷
(∀n. (Rep_prime p) ^ Suc n dvd
(∑k≤n. (f - g)$$(N + int k) * (Rep_prime p)^k))"
if "N ≤ min (fls_subdegree f) (fls_subdegree g)"
proof-
define pp where "pp ≡ Rep_prime p"
define dfg where "dfg ≡ fls_subdegree (f - g)"
define D where "D ≡ nat (dfg - N - 1)"
from that dfg_def D_def
have D: "f ≠ g ⟹ N ≠ dfg ⟹ dfg - N - 1 ≥ 0"
using fls_subdegree_minus
by force
have
"(f ≃⇩p g) =
(∀n. pp ^ Suc n dvd (∑k≤n. (f - g) $$ (N + int k) * pp ^ k))"
proof (standard, standard)
fix n :: nat
assume fg: "f ≃⇩p g"
consider
"f = g" |
"N = dfg" |
(n_le_D) "f ≠ g" "N ≠ dfg" "n ≤ D" |
(n_gt_D) "f ≠ g" "N ≠ dfg" "n > D"
by fastforce
thus "pp ^ Suc n dvd (∑k≤n. (f - g) $$ (N + int k) * pp ^ k)"
proof cases
case n_le_D
with D_def have "∀k≤n. N + int k < dfg" using D by linarith
with dfg_def show ?thesis using fls_eq0_below_subdegree[of _ "f - g"] by simp
next
case n_gt_D
with D_def that
have N_k : "∀k≤D. N + int k < dfg"
and N_D_k: "∀k. N + int (Suc D + k) = dfg + int k"
using D
by (force, linarith)
from dfg_def have "∀k≤D. (f - g)$$(N + int k) = 0"
using N_k fls_eq0_below_subdegree[of _ "f - g"] by blast
hence partsum: "(∑k≤D. (f - g)$$(N + int k) * pp^k) = 0" by force
from pp_def ‹f ≃⇩p g› obtain k
where k: "fls_base_parteval (f - g) pp (n - Suc D) = pp ^ Suc (n - Suc D) * k"
using p_equal_flsD fps_pvanishesD by blast
from ‹n > D› have exp: "Suc D + Suc (n - Suc D) = Suc n" by auto
from ‹n > D› have
"(∑k≤n. (f - g)$$(N + int k) * pp^k) =
(∑k≤D. (f - g)$$(N + int k) * pp^k) +
(∑k=Suc D..n. (f - g)$$(N + int k) * pp^k)"
using sum_up_index_split[of _ D "n - D"] by auto
also from ‹n > D› have
"… = (∑k≤n - Suc D.
(f - g) $$ (N + int (Suc D + k)) * pp ^ (Suc D + k))"
using partsum atLeast0AtMost[of "n - Suc D"]
sum.atLeastAtMost_shift_bounds[
of "λk. (f-g)$$(N + int k) * pp^k" 0 "Suc D" "n - Suc D"
]
by auto
also from D_def have
"… = (∑k≤n - Suc D. (f - g) $$ (dfg + int k) * (pp ^ Suc D * pp ^ k))"
using N_D_k power_add[of pp "Suc D"] by force
also have
"… = pp ^ Suc D * (∑k≤n - Suc D. (f - g) $$ (dfg + int k) * pp ^ k)"
by (simp add: algebra_simps sum_distrib_left)
also have "… = pp ^ Suc D * (pp ^ Suc (n - Suc D) * k)"
using k dfg_def fls_base_parteval_conv_sum[of "f - g" "n - Suc D" pp] by presburger
also have "… = pp ^ (Suc D + Suc (n - Suc D)) * k"
by (simp add: algebra_simps power_add)
finally have "(∑k≤n. (f - g)$$(N + int k) * pp^k) = pp ^ Suc n * k"
using ‹n > D› by auto
thus ?thesis by auto
qed (simp, metis fg dfg_def pp_def fls_base_parteval_conv_sum p_equal_flsD fps_pvanishesD)
next
assume *: "∀n. pp ^ Suc n dvd (∑k≤n. (f - g)$$(N + int k) * pp^k)"
consider "f = g" | "N = dfg" | "f ≠ g" "N ≠ dfg" by blast
thus "f ≃⇩p g"
proof cases
case 1 thus ?thesis by (simp add: p_equal_fls_refl)
next
case 2 with pp_def dfg_def * show ?thesis
using p_equal_flsI fps_pvanishesI fls_base_parteval_conv_sum by metis
next
case 3 show ?thesis
proof (intro p_equal_flsI fps_pvanishesI)
fix n
from 3 dfg_def D_def
have ND : "∀k. N + int (Suc D + k) = dfg + int k"
and dfg_N_n: "nat (dfg - N) + n = Suc D + n"
and sum_0 : "(∑k≤D. (f - g) $$ (N + int k) * pp ^ k) = 0"
using D fls_eq0_below_subdegree[of _ "f - g"]
by (fastforce, simp, simp)
have
"(∑k≤nat (dfg - N) + n. (f - g)$$(N + int k) * pp^k) =
(∑k = Suc D..Suc D + n. (f - g) $$ (N + int k) * pp ^ k)"
using dfg_N_n sum_0
sum_up_index_split[of "λk. (f - g)$$(N + int k) * pp^k" D "Suc n"]
by auto
also have
"… = sum ((λk. (f - g) $$ (N + int k) * pp ^ k) ∘ (+) (Suc D))
{0..n}"
using add.commute[of "Suc D" n] add_0_left[of "Suc D"]
sum.atLeastAtMost_shift_bounds[
of "λk. (f-g)$$(N + int k) * pp^k" 0 "Suc D" n
]
by argo
also have "… = pp ^ Suc D * (∑k≤n. (f - g) $$ (dfg + int k) * pp ^ k)"
using ND by (force simp add: algebra_simps atLeast0AtMost power_add sum_distrib_left)
finally have
"(∑k≤nat (dfg - N) + n. (f - g)$$(N + int k) * pp^k) =
pp ^ Suc D * fls_base_parteval (f - g) pp n"
using dfg_def fls_base_parteval_conv_sum[of "f - g" n pp] by force
moreover have "Suc (nat (dfg - N) + n) = Suc D + Suc n" using dfg_N_n by presburger
moreover from pp_def have "pp ^ Suc D ≠ 0" using Rep_prime_n0 by auto
ultimately have "pp ^ Suc n dvd fls_base_parteval (f - g) pp n"
using * power_add dvd_times_left_cancel_iff by metis
with pp_def show "Rep_prime p ^ Suc n dvd fls_base_parteval (f - g) (Rep_prime p) n"
by blast
qed
qed
qed
with pp_def show ?thesis by fast
qed
lemma p_equal_fls_extended_intsum_iff:
"f ≃⇩p g ⟷
(∀n≥N. (Rep_prime p) ^ Suc (nat (n - N)) dvd
(∑k=N..n. (f - g)$$k * (Rep_prime p) ^ nat (k - N)))"
if "N ≤ min (fls_subdegree f) (fls_subdegree g)"
proof (standard, clarify)
assume fg: "f ≃⇩p g"
fix n::int assume n: "n ≥ N"
define m where "m ≡ nat (n - N)"
from that fg have
"(Rep_prime p) ^ Suc m dvd (∑k≤m. (f - g)$$(N + int k) * (Rep_prime p)^k)"
using p_equal_fls_extended_sum_iff by blast
moreover from n m_def have
"(∑k=N..n. (f - g)$$k * (Rep_prime p) ^ nat( k - N)) =
(∑k≤m. (f - g)$$(N + int k) * (Rep_prime p)^k)"
by (simp add: sum.atLeastAtMost_int_shift_bounds algebra_simps)
ultimately show
"(Rep_prime p) ^ Suc (nat (n - N)) dvd
(∑k=N..n. (f - g)$$k * (Rep_prime p) ^ nat (k - N))"
using m_def by argo
next
assume dvd_sum:
"∀n≥N. (Rep_prime p) ^ Suc (nat (n - N)) dvd
(∑k=N..n. (f - g)$$k * (Rep_prime p) ^ nat (k - N))"
show "f ≃⇩p g"
proof (rule iffD2, rule p_equal_fls_extended_sum_iff, rule that, safe)
fix n::nat
have N_n: "N + int n ≥ N" by fastforce
moreover have "nat (N + int n - N) = n" by simp
ultimately have
"(Rep_prime p) ^ Suc n dvd
(∑k=N..N + int n. (f - g)$$k * (Rep_prime p) ^ nat (k - N))"
using dvd_sum by fastforce
moreover from N_n have
"(∑k≤n. (f - g) $$ (N + int k) * Rep_prime p ^ k) =
(∑k=N..N + int n. (f - g)$$k * (Rep_prime p) ^ nat (k - N))"
by (simp add: sum.atLeastAtMost_int_shift_bounds)
ultimately show
"Rep_prime p ^ Suc n dvd (∑k≤n. (f - g) $$ (N + int k) * Rep_prime p ^ k)"
by presburger
qed
qed
lemma fls_p_equal0_extended_sum_iff:
"f ≃⇩p 0 ⟷
(∀n. (Rep_prime p) ^ Suc n dvd
(∑k≤n. f$$(N + int k) * (Rep_prime p)^k))"
if "N ≤ fls_subdegree f"
proof-
define pp where "pp ≡ Rep_prime p"
have d0_case:
"⋀f N. fls_subdegree f = 0 ⟹ N ≤ 0 ⟹
f ≃⇩p 0 ⟷
(∀n. pp ^ Suc n dvd (∑k≤n. f$$(N + int k) * pp^k))"
proof-
fix f N from pp_def
show "fls_subdegree f = 0 ⟹ N ≤ 0 ⟹ ?thesis f N"
using p_equal_fls_extended_sum_iff[of N f 0]
by simp
qed
have "f ≃⇩p 0 ⟷ (fls_base_factor f) ≃⇩p 0"
using p_equal_fls_shift_iff[of f 0] fls_base_factor_def by auto
also from that pp_def have
"… = (∀n. pp ^ Suc n dvd (∑k≤n. f $$ ((N + int k)) * pp^k))"
using fls_base_factor_subdegree[of f] d0_case[of "fls_base_factor f" "N - fls_subdegree f"]
by auto
finally show ?thesis using pp_def by blast
qed
lemma fls_p_equal0_extended_intsum_iff:
"f ≃⇩p 0 ⟷
(∀n≥N. (Rep_prime p) ^ Suc (nat (n - N)) dvd
(∑k=N..n. f$$k * (Rep_prime p) ^ nat (k - N)))"
if "N ≤ fls_subdegree f"
proof (standard, clarify)
assume f: "f ≃⇩p 0"
fix n::int assume n: "n ≥ N"
define m where "m ≡ nat (n - N)"
from that f have
"(Rep_prime p) ^ Suc m dvd (∑k≤m. f$$(N + int k) * (Rep_prime p)^k)"
using fls_p_equal0_extended_sum_iff by blast
moreover from n m_def have
"(∑k=N..n. f$$k * (Rep_prime p) ^ nat (k - N)) =
(∑k≤m. f$$(N + int k) * (Rep_prime p)^k)"
by (simp add: sum.atLeastAtMost_int_shift_bounds algebra_simps)
ultimately show
"(Rep_prime p) ^ Suc (nat (n - N)) dvd
(∑k=N..n. f$$k * (Rep_prime p) ^ nat (k - N))"
using m_def by argo
next
assume dvd_sum:
"∀n≥N. (Rep_prime p) ^ Suc (nat (n - N)) dvd
(∑k=N..n. f$$k * (Rep_prime p) ^ nat (k - N))"
show "f ≃⇩p 0"
proof (rule iffD2, rule fls_p_equal0_extended_sum_iff, rule that, safe)
fix n::nat
have N_n: "N + int n ≥ N" by fastforce
moreover have "nat (N + int n - N) = n" by simp
ultimately have
"(Rep_prime p) ^ Suc n dvd
(∑k=N..N + int n. f$$k * (Rep_prime p) ^ nat (k - N))"
using dvd_sum by fastforce
moreover from N_n have
"(∑k≤n. f $$ (N + int k) * Rep_prime p ^ k) =
(∑k=N..N + int n. f$$k * (Rep_prime p) ^ nat (k - N))"
by (simp add: sum.atLeastAtMost_int_shift_bounds)
ultimately show
"Rep_prime p ^ Suc n dvd (∑k≤n. f $$ (N + int k) * Rep_prime p ^ k)"
by presburger
qed
qed
end
context
fixes p :: "'a :: nontrivial_factorial_idom prime"
begin
lemma fls_1_not_p_equal_0: "(1::'a fls) ¬≃⇩p 0"
using fps_pvanishes_one_iff not_prime_unit Rep_prime[of p] unfolding p_equal_fls_def by auto
lemma p_equal_fls0_nonneg_subdegree:
"f ≃⇩p 0 ⟷ fps_primevanishes p (fls_regpart f)"
if "fls_subdegree f ≥ 0"
proof-
define n where "n ≡ nat (fls_subdegree f)"
moreover have
"f ≃⇩p 0 ⟷
fps_primevanishes p (fls_base_factor_to_fps f * fps_X ^ n)"
unfolding p_equal_fls_def
using Rep_prime[of p] fps_pvanishes_mult_fps_X_power_iff(1)[of "Rep_prime p"]
by simp
ultimately show ?thesis
using fls_base_factor_subdegree[of f] fls_regpart_times_fps_X_power(1)[of "fls_base_factor f" n]
by (auto simp add: that)
qed
lemma p_equal_fls_nonneg_subdegree:
"f ≃⇩p g ⟷ fps_primevanishes p (fls_regpart (f - g))"
if "fls_subdegree f ≥ 0" and "fls_subdegree g ≥ 0"
proof-
from that have "fls_subdegree (f - g) ≥ 0"
using fls_subdegree_minus[of f g] by (cases "f = g") auto
thus ?thesis using p_equal_fls_conv_p_equal_0[of p f g] p_equal_fls0_nonneg_subdegree by blast
qed
lemma p_equal_fls_trans_to_0:
"f ≃⇩p g" if "f ≃⇩p 0" and "g ≃⇩p 0" for f g :: "'a fls"
proof (rule iffD2, rule p_equal_fls_shift_iff, rule iffD2, rule p_equal_fls_nonneg_subdegree)
define n where "n ≡ min (fls_subdegree f) (fls_subdegree g)"
from n_def show "fls_subdegree (fls_shift n f) ≥ 0" "fls_subdegree (fls_shift n g) ≥ 0"
using fls_shift_nonneg_subdegree[of n f] fls_shift_nonneg_subdegree[of n g] by auto
with that show "fps_primevanishes p (fls_regpart (fls_shift n f - fls_shift n g))"
using p_equal_fls0_nonneg_subdegree[of "fls_shift n f"] p_equal_fls_shift_iff[of p f 0]
p_equal_fls0_nonneg_subdegree[of "fls_shift n g"] p_equal_fls_shift_iff[of p g 0]
by (auto intro: fps_pvanishes_minus)
qed
lemma p_equal_fls_trans:
"f ≃⇩p g ⟹ g ≃⇩p h ⟹
f ≃⇩p h"
for f g h :: "'a fls"
using p_equal_fls_conv_p_equal_0[of p f g] p_equal_fls_conv_p_equal_0[of p h g]
p_equal_fls_sym[of p g h] p_equal_fls_trans_to_0[of "f-g" "h-g"]
p_equal_fls_conv_p_equal_0[of p "f-g" "h-g"] p_equal_fls_conv_p_equal_0[of p f h]
by auto
end
global_interpretation p_equality_fls:
p_equality_1
"p_equal :: 'a::nontrivial_factorial_idom prime ⇒
'a fls ⇒ 'a fls ⇒ bool"
proof (unfold_locales, intro equivpI)
fix p :: "'a prime"
define E :: "'a fls ⇒ 'a fls ⇒ bool" where "E ≡ p_equal p"
show "reflp E"
by (auto intro: reflpI simp add: E_def p_equal_fls_refl)
show "symp E" using p_equal_fls_sym by (auto intro: sympI simp add: E_def)
show "transp E"
using E_def p_equal_fls_trans[of p] by (fastforce intro: transpI)
fix x y :: "'a fls"
show "y ≃⇩p 0 ⟹ x * y ≃⇩p 0"
using p_equal_flsD fps_pvanishes_mult fls_base_factor_to_fps_mult[of x y]
unfolding p_equal_fls_def
by fastforce
qed (rule p_equal_fls_conv_p_equal_0)
overloading
globally_p_equal_fls ≡
"globally_p_equal ::
'a::nontrivial_factorial_idom fls ⇒ 'a fls ⇒ bool"
begin
definition globally_p_equal_fls ::
"'a::nontrivial_factorial_idom fls ⇒ 'a fls ⇒ bool"
where globally_p_equal_fls[simp]:
"globally_p_equal_fls = p_equality_fls.globally_p_equal"
end
context
fixes p :: "'a :: nontrivial_factorial_idom prime"
begin
lemma p_equal_fls_const_iff:
"(fls_const c) ≃⇩p (fls_const d) ⟷ c = d" for c d :: 'a
proof
define pp where "pp ≡ Rep_prime p"
assume "(fls_const c) ≃⇩p (fls_const d)"
with pp_def have 1: "∀n::nat. pp ^ Suc n dvd (c - d)"
using p_equal_flsD unfolding fps_pvanishes_def by (fastforce simp add: fls_minus_const)
have "infinite {n. pp ^ n dvd (c - d)}"
proof
assume "finite {n. pp ^ n dvd (c - d)}"
moreover have "Suc (Max {n. pp ^ n dvd (c - d)}) ∈ {n. pp ^ n dvd (c - d)}" using 1 by simp
ultimately have "Suc (Max {n. pp ^ n dvd (c - d)}) ≤ Max {n. pp ^ n dvd (c - d)}" by simp
thus False by simp
qed
with pp_def show "c = d" using Rep_prime_not_unit finite_divisor_powers[of "c - d"] by fastforce
qed simp
lemma p_equal_fls_const_0_iff:
"(fls_const c) ≃⇩p 0 ⟷ c = 0" for c :: 'a
using p_equal_fls_const_iff[of c 0] by simp
lemma p_equal_fls_X_intpow_iff:
"((fls_X_intpow m :: 'a fls) ≃⇩p (fls_X_intpow n)) = (m = n)"
proof (induction m n rule: linorder_less_wlog, standard)
define pp and X :: "int ⇒ 'a fls"
where "pp ≡ Rep_prime p" and "X ≡ fls_X_intpow"
fix m n :: int assume eq: "(X m) ≃⇩p (X n)" and mn: "m < n"
with pp_def X_def have
"pp ^ Suc (nat (n - m)) dvd (∑k=m..n. (X m - X n)$$k * pp ^ nat (k - m))"
using p_equal_fls_extended_intsum_iff[of m "X m" "X n" p]
by auto
moreover have
"(∑k=m..n. (X m - X n)$$k * pp ^ nat (k - m)) =
(∑k∈{m,n}. (X m - X n)$$k * pp ^ nat (k - m))"
proof (rule sum.mono_neutral_right, safe)
from mn show "m ∈ {m..n}" and "n ∈ {m..n}" by auto
fix i
assume i : "i ∈ {m..n}" "i ≠ m"
and Xi: "(X m - X n) $$ i * pp ^ nat (i - m) ≠ 0"
with X_def have "X m $$ i = 0" by simp
moreover from X_def have "i < n ⟹ X n $$ i = 0" by force
ultimately show "i = n" using i(1) Xi by fastforce
qed
ultimately have "pp ^ Suc (nat (n - m)) dvd 1 - (pp ^ nat (n - m))"
using mn X_def by auto
from this obtain k where "1 - (pp ^ nat (n - m)) = pp ^ Suc (nat (n - m)) * k" by fast
hence "1 = pp ^ nat (n - m) * (1 + pp * k)" by (simp add: algebra_simps)
with pp_def mn show "m = n"
using dvdI[of 1] Rep_prime_not_unit is_unit_power_iff[of pp] by fastforce
qed (auto simp add: p_equal_fls_sym)
lemma fls_X_intpow_nequiv0: "(fls_X_intpow m :: 'a fls) ¬≃⇩p 0"
using p_equal_fls_shift_iff fls_1_not_p_equal_0 by fastforce
end
subsubsection ‹Depth as maximum subdegree of equivalent series›
text ‹Each nonzero equivalence class will have a maximum subdegree.›
lemma no_greatest_p_equal_subdegree:
"f ≃⇩p 0"
if "∀n :: int. (∃g. fls_subdegree g > n ∧ f ≃⇩p g)"
for p :: "'a::nontrivial_factorial_comm_ring prime" and f :: "'a fls"
proof (cases "f = 0")
case False show ?thesis
proof (intro p_equal_flsI fps_pvanishesI)
fix n :: nat
define pp where "pp ≡ Rep_prime p"
from that obtain g where g: "fls_subdegree g > fls_subdegree f + int n" "f ≃⇩p g"
by blast
with False pp_def have "fls_base_parteval (f - g) pp n = fls_base_parteval (f - 0) pp n"
using fps_parteval_fls_base_factor_to_fps_diff by auto
with False pp_def g(2) show "pp ^ Suc n dvd fls_base_parteval (f - 0) pp n"
using p_equal_flsD fps_pvanishesD by metis
qed
qed (simp add: p_equal_fls_refl)
abbreviation
"p_equal_fls_simplified_set p f ≡
{g. f ≃⇩p g ∧ fls_subdegree g ≥ fls_subdegree f}"
context
fixes p :: "'a::nontrivial_factorial_comm_ring prime"
and f :: "'a fls"
begin
lemma p_equal_fls_simplifed_nempty:
"fls_subdegree ` (p_equal_fls_simplified_set p f) ≠ {}"
using p_equal_fls_refl[of p f] by fast
lemma p_equal_fls_simplifed_finite:
"finite (fls_subdegree ` (p_equal_fls_simplified_set p f))" if "f ¬≃⇩p 0"
proof-
from that obtain n::int
where "∀g. f ≃⇩p g ⟶ ¬ fls_subdegree g > n"
using no_greatest_p_equal_subdegree[of p f]
by auto
hence n: "∀g. f ≃⇩p g ⟶ fls_subdegree g ≤ n" by auto
define deg_diff where "deg_diff ≡ (λn. n - fls_subdegree f)"
define D where "D ≡ fls_subdegree ` (p_equal_fls_simplified_set p f)"
show "finite D"
proof (rule finite_imageD)
show "finite (deg_diff ` D)"
proof (rule finite_imageD)
have "nat ` deg_diff ` D ⊆ {m::nat. m ≤ nat (deg_diff n)}"
using n D_def deg_diff_def by auto
thus "finite (nat ` deg_diff ` D)" using finite_subset by blast
from D_def deg_diff_def show "inj_on nat (deg_diff ` D)"
by (auto intro: inj_onI)
qed
from deg_diff_def show "inj_on deg_diff D" by (auto intro: inj_onI)
qed
qed
end
overloading
p_depth_fls ≡
"p_depth :: 'a::nontrivial_factorial_comm_ring prime ⇒ 'a fls ⇒ int"
p_depth_const ≡
"p_depth :: 'a::nontrivial_factorial_comm_ring prime ⇒ 'a ⇒ int"
begin
definition
p_depth_fls :: "'a::nontrivial_factorial_comm_ring prime ⇒ 'a fls ⇒ int"
where
"p_depth_fls p f ≡
(if f ≃⇩p 0 then 0 else Max (fls_subdegree ` (p_equal_fls_simplified_set p f)))"
definition
p_depth_const :: "'a::nontrivial_factorial_comm_ring prime ⇒ 'a ⇒ int"
where
"p_depth_const p c ≡ p_depth p (fls_const c)"
end
context
fixes p :: "'a::nontrivial_factorial_comm_ring prime"
begin
lemma p_depth_fls_eqI:
"f°⇧p = fls_subdegree g"
if "f ¬≃⇩p 0" and "f ≃⇩p g"
and "⋀h. f ≃⇩p h ⟹ fls_subdegree h ≤ fls_subdegree g"
for f g :: "'a fls"
proof-
define M where "M ≡ Max (fls_subdegree ` (p_equal_fls_simplified_set p f))"
with that have "M = fls_subdegree g"
using p_equal_fls_simplifed_finite
by (force intro: Max_eqI simp add: p_equal_fls_refl)
with that(1) M_def show ?thesis by (auto simp add: p_depth_fls_def)
qed
lemma p_depth_fls_p_equal0[simp]:
"(f°⇧p) = 0" if "f ≃⇩p 0" for f :: "'a fls"
using that by (simp add: p_depth_fls_def)
lemma p_depth_fls0[simp]: "(0::'a fls)°⇧p = 0"
by (simp add: p_depth_fls_def p_equal_fls_refl)
lemma p_depth_fls_n0D:
"f°⇧p = Max (fls_subdegree ` (p_equal_fls_simplified_set p f))"
if "f ¬≃⇩p 0"
for f :: "'a fls"
using that by (simp add: p_depth_fls_def)
lemma p_depth_flsE:
fixes f :: "'a fls"
assumes "f ¬≃⇩p 0"
obtains g where "f ≃⇩p g" and "fls_subdegree g = (f°⇧p)"
and "∀h. f ≃⇩p h ⟶ fls_subdegree h ≤ fls_subdegree g"
proof-
define M where "M ≡ Max (fls_subdegree ` (p_equal_fls_simplified_set p f))"
with assms have "M ∈ fls_subdegree ` (p_equal_fls_simplified_set p f)"
using p_equal_fls_simplifed_finite[of p f] p_equal_fls_simplifed_nempty[of p f] by simp
from this obtain g where g: "g ∈ p_equal_fls_simplified_set p f" "M = fls_subdegree g" by fast
from g(1) have "f ≃⇩p g" by blast
moreover from g(2) M_def assms have 2: "fls_subdegree g = (f°⇧p)"
by (fastforce simp add: p_depth_fls_def)
moreover have
"∀h. f ≃⇩p h ⟶ fls_subdegree h ≤ fls_subdegree g"
proof clarify
fix h assume "f ≃⇩p h" show "fls_subdegree h ≤ fls_subdegree g"
proof (cases "fls_subdegree h ≥ fls_subdegree f")
case True with assms ‹f ≃⇩p h› M_def g show ?thesis
using p_equal_fls_simplifed_finite by force
next
case False
moreover from assms M_def g have "fls_subdegree f ≤ fls_subdegree g"
using p_equal_fls_simplifed_finite by blast
ultimately show ?thesis by simp
qed
qed
ultimately show thesis using that by simp
qed
lemma p_depth_fls_ge_p_equal_subdegree:
"(f°⇧p) ≥ fls_subdegree g"
if "f ¬≃⇩p 0" and "f ≃⇩p g"
for f g :: "'a fls"
proof (cases "fls_subdegree g ≥ fls_subdegree f")
case True with that show ?thesis
using p_equal_fls_simplifed_finite by (fastforce simp add: p_depth_fls_def)
next
case False
moreover from that(1) have "fls_subdegree f ≤ (f°⇧p)"
using p_equal_fls_simplifed_finite by (fastforce simp add: p_equal_fls_refl p_depth_fls_def)
ultimately show ?thesis by simp
qed
lemma p_depth_fls_ge_p_equal_subdegree':
"(f°⇧p) ≥ fls_subdegree f" if "f ¬≃⇩p 0" for f g :: "'a fls"
using that p_depth_fls_ge_p_equal_subdegree p_equal_fls_refl by blast
lemma p_equal_fls_simplified_set_shift:
"p_equal_fls_simplified_set p (fls_shift n f) = fls_shift n ` p_equal_fls_simplified_set p f"
if "f ¬≃⇩p 0"
for f :: "'a fls"
proof-
have *:
"⋀f n. (f::'a fls) ¬≃⇩p 0 ⟹
fls_shift n ` p_equal_fls_simplified_set p f ⊆
p_equal_fls_simplified_set p (fls_shift n f)"
proof (intro subsetI, clarify)
fix n ::int
and f g :: "'a fls"
assume f_neq_0: "f ¬≃⇩p 0"
and eq : "f ≃⇩p g"
and deg : "fls_subdegree f ≤ fls_subdegree g"
from f_neq_0 eq have "f ≠ 0" "g ≠ 0" using p_equal_fls_refl by auto
with deg have "fls_subdegree (fls_shift n f) ≤ fls_subdegree (fls_shift n g)" by simp
moreover from eq have "(fls_shift n f) ≃⇩p (fls_shift n g)"
using p_equal_fls_shift_iff by fast
ultimately show
"(fls_shift n f) ≃⇩p (fls_shift n g) ∧
fls_subdegree (fls_shift n f) ≤ fls_subdegree (fls_shift n g)"
by fast
qed
have "f ≃⇩p 0 ⟷ (fls_shift n f) ≃⇩p 0"
using p_equal_fls_shift_iff[of p f 0] by simp
with that have
"p_equal_fls_simplified_set p (fls_shift n f) ⊆
fls_shift n ` p_equal_fls_simplified_set p f"
using *[of "fls_shift n f" "-n"] by force
with that show
"p_equal_fls_simplified_set p (fls_shift n f) = fls_shift n ` p_equal_fls_simplified_set p f"
using *[of f n] by fast
qed
lemma p_equal_fls_simplified_set_shift_subdegrees:
"fls_subdegree ` p_equal_fls_simplified_set p (fls_shift n f) =
(λx. x - n) ` fls_subdegree ` p_equal_fls_simplified_set p f"
if "f ¬≃⇩p 0"
for f :: "'a fls"
proof-
from that have
"fls_subdegree ` p_equal_fls_simplified_set p (fls_shift n f) =
fls_subdegree ` fls_shift n ` p_equal_fls_simplified_set p f"
using p_equal_fls_simplified_set_shift by fast
moreover from that have "∀g∈p_equal_fls_simplified_set p f. g ≠ 0" by auto
ultimately show ?thesis by force
qed
lemma p_depth_fls_shift:
"(fls_shift n f)°⇧p = (f°⇧p) - n" if "f ¬≃⇩p 0"
for f :: "'a fls"
proof-
from that have sf_nequiv_0: "(fls_shift n f) ¬≃⇩p 0"
using p_equal_fls_shift_iff by fastforce
with that have
"(fls_shift n f)°⇧p =
Max ((λx. x - n) ` fls_subdegree ` p_equal_fls_simplified_set p f)"
using p_depth_fls_n0D p_equal_fls_simplified_set_shift_subdegrees
by fastforce
thus ?thesis
using p_equal_fls_simplifed_finite[OF that] p_equal_fls_simplifed_nempty
p_depth_fls_n0D[OF that]
Max_add_commute[of
"fls_subdegree ` p_equal_fls_simplified_set p f"
"λx. x"
"-n"
]
by auto
qed
end
context
fixes p :: "'a::nontrivial_factorial_idom prime"
and f g :: "'a fls"
begin
lemma p_depth_fls_p_equal: "(f°⇧p) = (g°⇧p)" if "f ≃⇩p g"
proof (cases "f ≃⇩p 0")
case True with that show ?thesis using p_equality_fls.trans0_iff by fastforce
next
case False
with that have g: "g ¬≃⇩p 0" using p_equality_fls.trans0_iff by blast
from this obtain h where h:
"g ≃⇩p h" "fls_subdegree h = (g°⇧p)"
by (elim p_depth_flsE)
from that h(1) have "f ≃⇩p h" using p_equality_fls.trans by fast
moreover from that g h(2) have
"⋀h'. f ≃⇩p h' ⟹ fls_subdegree h' ≤ fls_subdegree h"
using p_equality_fls.trans_right p_depth_fls_ge_p_equal_subdegree by metis
ultimately show ?thesis
using False h(2) p_depth_fls_eqI by metis
qed
lemma p_depth_fls_can_simplify_iff:
"p pdvd g $$ (fls_subdegree g) = (fls_subdegree g < (f°⇧p))"
if f_nequiv0: "f ¬≃⇩p 0"
and fg_equiv : "f ≃⇩p g"
proof
define gdeg where "gdeg ≡ fls_subdegree g"
define gth where "gth ≡ g $$ gdeg"
define pp where "pp ≡ Rep_prime p"
assume p_dvd: "p pdvd gth"
from this obtain k where k: "gth = pp * k" unfolding pp_def gth_def gdeg_def by (elim dvdE)
define h where
"h ≡ g - fls_shift (-gdeg) (fls_const gth) + fls_shift (-(gdeg + 1)) (fls_const k)"
from f_nequiv0 fg_equiv have "g ≠ 0" by blast
with gth_def gdeg_def have
"fls_subdegree (fls_shift (-gdeg) (fls_const gth) - fls_shift (-(gdeg + 1)) (fls_const k)) =
gdeg"
by (auto intro: fls_subdegree_eqI)
with h_def have g_h: "fls_base_factor_to_fps (g - h) = fps_const gth - fps_const k * fps_X"
by (auto intro: fps_ext)
have p_g_h: "⋀n. pp ^ Suc n dvd fls_base_parteval (g - h) pp n"
proof-
fix n
from k p_dvd show "pp ^ Suc n dvd fls_base_parteval (g - h) pp n"
using g_h by (cases n) (auto simp add: fps_parteval_mult_fps_X(1))
qed
with pp_def have "g ≃⇩p h" by (fastforce intro: p_equal_flsI fps_pvanishesI)
moreover have "gdeg < fls_subdegree h"
proof (intro fls_subdegree_greaterI)
show "h ≠ 0"
proof
assume"h = 0"
with pp_def have "g ≃⇩p 0"
using p_g_h by (fastforce intro: p_equal_flsI fps_pvanishesI)
with f_nequiv0 fg_equiv show False using p_equality_fls.trans0_iff by blast
qed
qed (simp add: h_def gdeg_def gth_def)
ultimately show "gdeg < (f°⇧p)"
using gdeg_def that p_depth_fls_ge_p_equal_subdegree[of p f h]
p_equal_fls_trans[of p f g h]
by force
next
define pp where "pp ≡ Rep_prime p"
assume g: "fls_subdegree g < (f°⇧p)"
with that obtain h where h: "f ≃⇩p h" "fls_subdegree h = (f°⇧p)"
by (elim p_depth_flsE)
from f_nequiv0 fg_equiv have g_n0: "g ≠ 0" by blast
with g h(2) have "fls_subdegree (g - h) = fls_subdegree g" by (auto intro: fls_subdegree_eqI)
moreover from fg_equiv h(1) pp_def
have "pp ^ Suc 0 dvd (fps_parteval (fls_regpart (fls_base_factor (g - h))) pp 0)"
using p_equality_fls.trans_right p_equal_flsD fps_pvanishesD
by blast
ultimately show "p pdvd g $$ (fls_subdegree g)" by (simp add: pp_def g h(2))
qed
lemma p_depth_fls_rep_iff:
"(f°⇧p) = fls_subdegree g ⟷
¬ p pdvd g $$ (fls_subdegree g)"
if "f ¬≃⇩p 0" and "f ≃⇩p g"
using that p_depth_fls_can_simplify_iff p_depth_fls_ge_p_equal_subdegree by fastforce
end