Theory Pi_Relations
theory Pi_Relations
imports J3_Relations
begin
subsection โนThe $\Pi$ polynomialโบ
lemma finite_when: "finite {x. (f x when x = c) โ 0}"
by auto
locale section5_variables
begin
definition ๐ฎ :: "int mpoly" where "๐ฎ โก Var 4"
definition ๐ฏ :: "int mpoly" where "๐ฏ โก Var 5"
definition โ :: "int mpoly" where "โ โก Var 6"
definition โ :: "int mpoly" where "โ โก Var 7"
definition ๐ด :: "int mpoly" where "๐ด โก Var 8"
definition โจ :: "int mpoly" where "โจ โก Var 9"
definition ๐ฅ :: "int mpoly" where "๐ฅ โก Var 10"
definition ๐ :: "int mpoly" where "๐ โก Var 11"
definition ๐ฐ ::"int mpoly" where "๐ฐ = ๐ฎ^2 * (2*โ-1)"
definition ๐ฑ ::"int mpoly" where "๐ฑ = ๐ฏ^2 + ๐ฎ^2 * ๐"
lemmas defs = ๐ฎ_def ๐ฏ_def โ_def โ_def ๐ด_def โจ_def ๐ฅ_def ๐_def ๐ฐ_def ๐ฑ_def
end
locale pi_relations = section5_variables +
fixes โฑ :: "int mpoly"
and v :: nat
assumes F_monom_over_v: "vars โฑ โ {v}"
and F_one: "coeff โฑ (Abs_poly_mapping (ฮปk. (degree โฑ v when k = v))) = 1"
begin
definition coeff_F where
"coeff_F d = coeff โฑ (Abs_poly_mapping (ฮปk. (d when k = v)))"
definition q :: nat where
"q = degree โฑ v"
definition G :: "int mpoly" where
"G = (โi=0..q. of_int (coeff_F i) * (๐ด-โ-๐ฏ^2)^i)"
definition G_sub :: "natโint mpoly" where
"G_sub j = (โi=j..q. of_int (coeff_F i) * of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j))"
definition H :: "int mpoly" where
"H = (โj=0..q. G_sub j * โจ^j * ๐ฅ^(q-j))"
definition ฮ :: "int mpoly" where
"ฮ = (โj=0..q. G_sub j * (๐ฎ^2*๐ + ๐ฏ^2)^j * (๐ฎ^2*(2*โ-1))^(q-j))"
lemma eval_F:
"insertion f โฑ = (โd = 0..q. coeff_F d * (f v ^ d))"
proof -
have aux1: " {a. lookup (mapping_of โฑ) a * (โv. f v ^ lookup a v) โ 0}
โ {a โ range (ฮปd. Abs_poly_mapping (ฮปk. d when k = v)).
lookup (mapping_of โฑ) a * (โv. f v ^ lookup a v) โ 0}"
proof -
have "lookup (mapping_of โฑ) a โ 0 โน
(โv. f v ^ lookup a v) โ 0 โน
a โ range (ฮปd. Abs_poly_mapping (ฮปk. d when k = v))" for a
proof -
assume "lookup (mapping_of โฑ) a โ 0"
hence "a โ keys (mapping_of โฑ)"
unfolding keys.rep_eq
by simp
hence "โv'. v โ v' โน lookup a v' = 0"
subgoal for v'
proof (cases "lookup a v' = 0")
case True
then show ?thesis by simp
next
case False
assume "lookup a v' โ 0"
hence "v' โ โ (keys ` keys (mapping_of โฑ))"
using `a โ keys (mapping_of โฑ)`
unfolding keys.rep_eq
apply simp
apply (rule exI[where ?x=a])
by simp
hence 0: "v' = v"
using F_monom_over_v vars_def
by auto
assume 1: "v โ v'"
from 0 and 1 show ?thesis by simp
qed
done
hence "a = Abs_poly_mapping (ฮปk. (lookup a v) when k = v)"
apply (subst lookup_inverse[symmetric])
apply (rule arg_cong[where ?f=Abs_poly_mapping])
by (metis (mono_tags, opaque_lifting) "when"(1) "when"(2))
thus "a โ range (ฮปd. Abs_poly_mapping (ฮปk. d when k = v))"
by simp
qed
thus ?thesis by auto
qed
have aux2: "lookup (mapping_of โฑ) (Abs_poly_mapping (ฮปk. d when k = v)) โ 0 โน
(โva. f va ^ lookup (Abs_poly_mapping (ฮปk. d when k = v)) va) โ 0 โน d โ {0..q}" for d
proof -
assume "lookup (mapping_of โฑ) (Abs_poly_mapping (ฮปk. d when k = v)) โ 0"
thus "d โ {0..q}"
unfolding q_def degree.rep_eq keys.rep_eq
apply (subst atLeastAtMost_iff)
apply simp
apply (rule Max_ge)
subgoal by simp
apply (rule insertI2)
apply (rule image_eqI[where ?x="Abs_poly_mapping (ฮปk. d when k = v)"])
subgoal
apply (subst lookup_Abs_poly_mapping)
subgoal using finite_when[where ?f="ฮป_. d"] by simp
by auto
by simp
qed
have aux3: "x โค q โน y โค q โน
Abs_poly_mapping (ฮปk. x when k = v) = Abs_poly_mapping (ฮปk. y when k = v) โน x = y" for x y
proof -
assume "Abs_poly_mapping (ฮปk. x when k = v) = Abs_poly_mapping (ฮปk. y when k = v)"
hence 0: "(ฮปk. x when k = v) = (ฮปk. y when k = v)"
apply (subst Abs_poly_mapping_inject[symmetric])
subgoal
apply (rule CollectI)
using finite_when[where ?f="ฮป_. x"] by simp
subgoal
apply (rule CollectI)
using finite_when[where ?f="ฮป_. y"] by simp
by simp
have "(x when v = v) = (y when v = v)"
by (rule fun_cong[OF 0, where ?x=v])
thus ?thesis
by simp
qed
have aux4: "lookup (mapping_of โฑ) (Abs_poly_mapping (ฮปk. d when k = v)) โ 0 โน
(โva. f va ^ lookup (Abs_poly_mapping (ฮปk. d when k = v)) va) โ 0 โน
Abs_poly_mapping (ฮปk. d when k = v) โ (ฮปd. Abs_poly_mapping (ฮปk. d when k = v)) ` {0..q}" for d
apply (rule image_eqI[where ?x=d, OF refl])
using aux2 by simp
have "insertion f โฑ = (โmโ{a. lookup (mapping_of โฑ) a * (โv. f v ^ lookup a v) โ 0}.
lookup (mapping_of โฑ) m * (โv. f v ^ lookup m v))"
unfolding insertion.rep_eq insertion_aux.rep_eq insertion_fun_def
unfolding Sum_any.expand_set
by simp
also have "... =
(โmโ{a โ range (ฮปd. Abs_poly_mapping (ฮปk. d when k = v)).
lookup (mapping_of โฑ) a * (โv. f v ^ lookup a v) โ 0}.
lookup (mapping_of โฑ) m * (โv. f v ^ lookup m v))"
apply (rule sum.mono_neutral_right[symmetric])
subgoal by auto
subgoal using aux1 by auto
subgoal by auto
done
also have "... =
(โmโ{a โ (ฮปd. Abs_poly_mapping (ฮปk. d when k = v)) ` {0..q}.
lookup (mapping_of โฑ) a * (โv. f v ^ lookup a v) โ 0}.
lookup (mapping_of โฑ) m * (โv. f v ^ lookup m v))"
apply (rule arg_cong[where ?f="sum _"])
apply standard
subgoal using aux4 by auto
subgoal by auto
done
also have "... =
(โmโ(ฮปd. Abs_poly_mapping (ฮปk. d when k = v)) ` {0..q}.
lookup (mapping_of โฑ) m * (โv. f v ^ lookup m v))"
apply (rule sum.mono_neutral_right[symmetric])
by auto
also have "... =
sum
((ฮปm. lookup (mapping_of โฑ) m *
(โv. f v ^ lookup m v)) โ (ฮปd. Abs_poly_mapping (ฮปk. d when k = v)))
{0..q}"
apply (rule sum.reindex) unfolding inj_on_def using aux3 by auto
also have "... =
(โdโ{0..q}. lookup (mapping_of โฑ) (Abs_poly_mapping (ฮปk. d when k = v)) *
(โva. f va ^ lookup (Abs_poly_mapping (ฮปk. d when k = v)) va))"
by simp
finally show ?thesis
unfolding coeff_F_def coeff_def
apply simp
apply (rule arg_cong[where ?f="ฮปf. (โd = 0..q. _ d * f d)"])
apply (rule ext)
subgoal for d
apply (subst lookup_Abs_poly_mapping)
subgoal using finite_when[where ?f="ฮป_. d"] by simp
proof (cases d)
case 0
then show "(โva. f va ^ (d when va = v)) = f v ^ d"
apply (subst `d = 0`)
by simp
next
case (Suc nat)
then show "(โva. f va ^ (d when va = v)) = f v ^ d"
apply (subst pow_when)
by simp_all
qed
done
qed
lemma triangular_sum: "(โk=0..(n::nat). (โj=0..k. f j k)) = (โj=0..(n::nat). (โk=j..n. f j k))"
proof -
have 0: "kโ{0..n} โน (โj=0..k. f j k) = (โj=0..n. (if jโคk then f j k else 0))" for k
proof -
assume k_prop: "kโ{0..n}"
hence "(โj=0..k. f j k) = (โj=0..k. f j k) + (โj=(k+1)..n. 0)" by simp
also have "... = (โj=0..k. (if jโคk then f j k else 0)) + (โj=(k+1)..n. (if jโคk then f j k else 0))"
by simp
also have "... = (โj=0..n. (if jโคk then f j k else 0))"
using sum.union_disjoint[of "{0..k}" "{(k+1)..n}"]
by (smt (verit) atLeastAtMost_iff k_prop le_iff_add sum.ub_add_nat zero_order(1))
finally show ?thesis by blast
qed
have 1: "jโ{0..n} โน (โk=j..n. f j k) = (โk=0..n. (if jโคk then f j k else 0))" for j
proof -
assume j_prop: "jโ{0..n}"
hence "(โk=j..n. f j k) = (โk<j. 0) + (โk=j..n. f j k)" by simp
also have "... = (โk<j. (if jโคk then f j k else 0)) + (โk=j..n. (if jโคk then f j k else 0))"
by simp
also have "... = (โk=0..n. (if jโคk then f j k else 0))"
using sum.union_disjoint[of "{0..<j}" "{j..n}"]
by (smt (verit, best) atLeast0LessThan atLeastAtMost_iff finite_atLeastAtMost finite_atLeastLessThan ivl_disj_int_two(7) ivl_disj_un_two(7) j_prop)
finally show ?thesis by blast
qed
hence "(โk=0..(n::nat). (โj=0..k. f j k)) = (โk=0..n. (โj=0..n. (if jโคk then f j k else 0)))"
using 0 by simp
also have "... = (โj=0..n. (โk=0..n. (if jโคk then f j k else 0)))" using sum.swap by fast
finally show ?thesis using 1 by simp
qed
lemma G_expr:
"G = (โj=0..q. ๐ด^j * (โi=j..q. of_int (coeff_F i) * of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j)))"
proof -
have "๐ด-โ-๐ฏ^2 = ๐ด + (-โ-๐ฏ^2)" by simp
hence "(๐ด-โ-๐ฏ^2)^i = (โjโคi. of_nat (i choose j) * ๐ด^j * (-โ-๐ฏ^2)^(i-j))" for i
using binomial_ring[of ๐ด "-โ-๐ฏ^2" i] by presburger
hence "G = (โi=0..q. of_int (coeff_F i) * (โjโคi. of_nat (i choose j) * ๐ด^j * (-โ-๐ฏ^2)^(i-j)))"
using G_def by presburger
also have "... = (โi=0..q. (โj=0..i. of_int (coeff_F i) * of_nat (i choose j) * ๐ด^j * (-โ-๐ฏ^2)^(i-j) ))"
(is "(โi=_.._. ?f i) = (โi=_.._. ?g i)")
proof (rule sum.cong[OF refl])
fix i
have "?f i = of_int (coeff_F i) * (โj=0..i. of_nat (i choose j) * ๐ด^j * (-โ-๐ฏ^2)^(i-j) )"
using atMost_atLeast0 by simp
thus "?f i = ?g i"
unfolding mult.assoc
by (simp add: sum_distrib_left)
qed
also have "... = (โj=0..q. (โi=j..q. of_int (coeff_F i) * of_nat (i choose j) * ๐ด^j * (-โ-๐ฏ^2)^(i-j) ))"
using triangular_sum[of "(ฮปj. (ฮปi. of_int (coeff_F i) * of_nat (i choose j) * ๐ด^j * (-โ-๐ฏ^2)^(i-j)))" q]
by blast
also have "... = (โj=0..q. (โi=j..q. ๐ด^j * of_int (coeff_F i) * of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j) ))"
apply (rule sum.cong[OF refl])
apply (rule sum.cong[OF refl])
by simp
also have "... = (โj=0..q. ๐ด^j * (โi=j..q. of_int (coeff_F i) * of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j) ))"
(is "(โj=_.._. ?f j) = (โj=_.._. ?g j)")
apply (rule sum.cong[OF refl])
unfolding mult.assoc
by (simp add: sum_distrib_left)
finally show ?thesis by simp
qed
lemma G_in_Y: "G = (โj=0..q. ๐ด^j * G_sub j)"
unfolding G_sub_def using G_expr by blast
lemma Gq_eq_1: "G_sub q = 1"
proof -
have "coeff_F q = 1" using q_def F_one unfolding coeff_F_def by simp
have "G_sub q = of_int (coeff_F q)" unfolding G_sub_def by simp
also have "... = of_int 1" using q_def using โนcoeff_F q = 1โบ by presburger
finally show ?thesis using Constโฉ0_one one_mpoly_def by simp
qed
lemma lemma_J_div_Z :
"(โj'=0..q. insertion f (G_sub j') * z^j' * j^(q-j')) = 0 โน j dvd z" for f z j
proof (cases "j=0 โง z=0")
case True
then show ?thesis by blast
next
case False
assume assm: "(โj'=0..q. insertion f (G_sub j') * z^j' * j^(q-j')) = 0"
define d where "d = gcd j z"
have "d dvd j" using d_def by blast
then obtain j0 where j0_def: "j = d * j0" by blast
have "d dvd z" using d_def by blast
then obtain z0 where z0_def: "z = d * z0" by blast
have "gcd j z = d * gcd j0 z0" using d_def j0_def z0_def
by (metis abs_gcd_int gcd_mult_distrib_int)
hence coprime: "gcd j0 z0 = 1" using d_def using False by simp
have dn0: "dโ 0" using False d_def by simp
have "j'โคq โน j' + (q-j') =q" for j' by simp
hence nat_pow: "j'โคq โน d^j' * d^(q-j') = d^q" for j' using power_add by metis
have "z^j' * j^(q-j') = d^j' * z0^j' * d^(q-j') * j0^(q-j')" for j'
using j0_def z0_def by (simp add: power_mult_distrib)
hence "j'โคq โน z^j' * j^(q-j') = d^q * z0^j' * j0^(q-j')" for j'
using power_add nat_pow by simp
hence "0 = (โj'=0..q. insertion f (G_sub j') * d^q * z0^j' * j0^(q-j'))"
using assm
by (metis (no_types, lifting) ab_semigroup_mult_class.mult_ac(1) atLeastAtMost_iff sum.cong)
also have "... = (โj'=0..q. d^q * insertion f (G_sub j') * z0^j' * j0^(q-j'))"
using mult.commute by (metis (no_types, opaque_lifting))
also have "... = d^q * (โj'=0..q. insertion f (G_sub j') * z0^j' * j0^(q-j'))"
using sum_distrib_left[of "d^q" "(ฮปj'. insertion f (G_sub j') * z0^j' * j0^(q-j'))" "{0..q}"]
by (metis (no_types, lifting) ab_semigroup_mult_class.mult_ac(1) sum.cong)
finally have pol_red_0: "(โj'=0..q. insertion f (G_sub j') * z0^j' * j0^(q-j')) = 0"
using dn0 by simp
have inser_Gq_1: "insertion f (G_sub q) = 1" using Gq_eq_1 by simp
have j0_pow: "j'<q โน j0^(q-j') = j0^(q-j'-1) * j0" for j'
by (metis power_minus_mult zero_less_diff)
have "(โj'=0..q. insertion f (G_sub j') * z0^j' * j0^(q-j'))
= (โj'=0..<q. insertion f (G_sub j') * z0^j' * j0^(q-j')) + insertion f (G_sub q) * z0^q * j0^(q-q)"
by (simp add: sum.last_plus)
also have "... = (โj'=0..<q. insertion f (G_sub j') * z0^j' * j0^(q-j')) + z0^q"
using inser_Gq_1 by simp
also have "... = (โj'=0..<q. insertion f (G_sub j') * z0^j' * j0^(q-j'-1)*j0) + z0^q"
using j0_pow sum.cong by (simp add: ab_semigroup_mult_class.mult_ac(1))
also have "... = (โj'=0..<q. insertion f (G_sub j') * z0^j' * j0^(q-j'-1)) * j0 + z0^q"
using sum_distrib_right[of _ _ "j0"] by metis
finally have "z0^q = -(โj'=0..<q. insertion f (G_sub j') * z0^j' * j0^(q-j'-1)) * j0"
using pol_red_0 by simp
hence "j0 dvd z0^q" by simp
hence "j0 dvd z0" using coprime
by (metis coprime_dvd_mult_left_iff coprime_dvd_mult_right_iff coprime_power_right_iff is_unit_gcd one_dvd)
thus "j dvd z" using j0_def z0_def by simp
qed
lemma lemma_pos:
assumes "(โj'=0..q. insertion f (G_sub j') * z^j' * j^(q-j')) = 0"
"jโ 0" "z = z' * j"
shows "insertion (ฮป_. z' - f 7 - (f 5)^2) โฑ = 0"
proof -
have "z^j' = z'^j' * j^j'" for j' using power_mult_distrib[of "z'" "j" "j'"] assms by blast
hence 0: "0 = (โj'=0..q. insertion f (G_sub j') * z'^j' * j^j' * j^(q-j'))" using assms
by (metis (no_types, lifting) ab_semigroup_mult_class.mult_ac(1) sum.cong)
also have "... = (โj'=0..q. insertion f (G_sub j') * z'^j' * j^(j'+(q-j')))"
using power_add[of "j"] by (metis (no_types, lifting) ab_semigroup_mult_class.mult_ac(1))
also have "... = (โj'=0..q. insertion f (G_sub j') * z'^j' * j^q)" by simp
also have "... = (โj'=0..q. insertion f (G_sub j') * z'^j') * j^q"
using sum_distrib_right[of _ _ "j^q"] by metis
finally have G_is_0: "(โj'=0..q. insertion f (G_sub j') * z'^j') = 0" using assms by simp
define f' where "f' = (ฮปx. f x)(8:=z')"
hence "insertion f' ๐ด = z'"
by (simp add: ๐ด_def)
hence ins_f'_Y: "insertion f' (๐ด^j') = z'^j'" for j'::nat using insertion_pow by blast
have ins_f'_Gsub: "insertion f' (G_sub j') = insertion f (G_sub j')" for j'
proof (rule insertion_irrelevant_vars)
fix v
assume H: "v โ vars (G_sub j')"
have "vars (G_sub j') โ vars โ โช vars ๐ฏ"
unfolding G_sub_def
apply (rule subset_trans[OF vars_setsum])
subgoal by simp
apply (rule union_subset)
subgoal for x
apply (rule subset_trans[OF vars_mult])
apply (rule Un_least)
apply (rule subset_trans[OF vars_mult])
apply (subst of_int_Const)
apply (subst of_nat_Const)
using vars_Const
subgoal by simp
apply (rule subset_trans[OF vars_pow])
apply (subst diff_conv_add_uminus)
apply (rule subset_trans[OF vars_add])
apply (rule Un_mono)
using vars_neg
subgoal by auto
apply (subst vars_neg)
apply (subst power2_eq_square)
apply (rule subset_trans[OF vars_mult])
by simp
done
also have "... โ {5, 7}"
unfolding defs
unfolding MPoly_Type.Var.abs_eq[symmetric]
by simp
finally have "v โ 8"
using H
by auto
thus "f' v = f v"
unfolding f'_def
by auto
qed
have "(โj'=0..q. insertion f' (G_sub j') * insertion f' (๐ด^j')) = 0"
using ins_f'_Y ins_f'_Gsub G_is_0 by presburger
hence "(โj'=0..q. insertion f' (G_sub j' * ๐ด^j')) = 0"
using insertion_mult by (metis (no_types, lifting) sum.cong)
hence "insertion f' (โj'=0..q. G_sub j' * ๐ด^j') = 0" using insertion_sum[of "{0..q}" "f'"] by simp
hence "insertion f' G = 0" using G_in_Y mult.commute
by (metis (no_types, lifting) sum.cong)
hence "(โi = 0..q. insertion f' (of_int (coeff_F i) * (๐ด - โ - ๐ฏโง2) ^ i)) = 0"
unfolding G_def using insertion_sum[of "{0..q}" "f'"] by simp
hence "(โi = 0..q. coeff_F i * insertion f' ((๐ด - โ - ๐ฏโง2) ^ i)) = 0"
by simp
hence 1: "(โi = 0..q. coeff_F i * (insertion f' (๐ด - โ - ๐ฏโง2)) ^ i) = 0"
using insertion_pow[of "f'"] by simp
have "insertion f' (๐ด - โ - ๐ฏโง2) = z' - f 7 - (f 5)^2"
proof -
have "insertion f' (๐ด - โ - ๐ฏโง2) = insertion f' ๐ด + insertion f' (-โ-๐ฏ*๐ฏ)"
using insertion_add[of "f'" ๐ด "-โ-๐ฏ*๐ฏ"] power2_eq_square[of ๐ฏ] add.assoc
by (metis ab_group_add_class.ab_diff_conv_add_uminus)
also have "... = insertion f' ๐ด - insertion f' โ - insertion f' (๐ฏ*๐ฏ)"
by simp
also have "... = insertion f' ๐ด - insertion f' โ - (insertion f' ๐ฏ)^2"
using insertion_mult[of "f'" ๐ฏ ๐ฏ] power2_eq_square by metis
also have "... = f' 8 - f' 7 - (f' 5)^2"
unfolding ๐ด_def โ_def ๐ฏ_def by simp
finally show ?thesis using f'_def by simp
qed
hence "(โi = 0..q. coeff_F i * (z' - f 7 - (f 5)^2) ^ i) = 0" using 1 by simp
thus "insertion (ฮป_. z' - f 7 - (f 5)^2) โฑ = 0"
using q_def eval_F
by simp
qed
lemma ฮ _encodes_correctly:
fixes S T R I :: int
assumes "S โ 0"
"(โx. insertion (ฮป_. x) โฑ = 0 โถ x > -I)"
and "S dvd T"
"R > 0"
"insertion (ฮป_. y) โฑ = 0"
defines "ฯ n โก (ฮป_. 0)(4:= S, 5:=T, 6:=R, 7:=I, 11:=int n)"
shows "โn :: nat. insertion (ฯ n) ฮ = 0 โง n = (2*R-1)*(y + I + T^2) - (T div S) ^ 2"
proof -
obtain TdS where TdS_def: "T = TdS * S" using โนS dvd Tโบ by force
define nโฉi where "nโฉi = (2*R-1)*(y+I+T^2) - TdS^2"
have nBe0: "nโฉiโฅ0"
proof -
have 0: "(2*R-1) โฅ 1" using assms by simp
have "y > -I" using assms by blast
hence 1: "y+I+T^2 > T^2" by linarith
have "T^2 โฅ0" by simp
hence "y+I+T^2 > 0" using 1 by linarith
hence "(2*R-1)*(y+I+T^2) โฅ y+I+T^2" using 0 by simp
hence 2: "(2*R-1)*(y+I+T^2) โฅ T^2" using 1 by simp
have 3: "T^2 = TdS^2 * S^2" unfolding TdS_def using power_mult_distrib by blast
have "S^2 > 0" using assms by simp
hence 4: "S^2 โฅ 1" by linarith
have "TdS^2 โฅ 0" by simp
hence "TdS^2 * S^2 โฅ TdS^2" using 4 by (metis mult_cancel_left1 mult_left_mono)
hence "T^2 โฅ TdS^2" using 3 by simp
thus ?thesis unfolding nโฉi_def using 2 by simp
qed
then obtain n where n_def: "int n = nโฉi" using nonneg_int_cases by metis
define f::"natโint" where "f = (ฮป_. 0) (4 := S, 5 := T, 6 := R, 7 := I, 11 := int n)"
have 0: "insertion f ฮ
= (โj = 0..q. insertion f (G_sub j * (๐ฎโง2 * ๐ + ๐ฏโง2) ^ j * (๐ฎโง2 * (2 * โ - 1)) ^ (q - j)))"
unfolding ฮ _def using insertion_sum by blast
have 1: "insertion f (G_sub j * (๐ฎโง2 * ๐ + ๐ฏโง2) ^ j * (๐ฎโง2 * (2 * โ - 1)) ^ (q - j))
= insertion f (G_sub j) * (S^2 * n + T^2)^j * (S^2 * (2*R- 1)) ^ (q - j)" for j
proof -
have 0: "insertion f (G_sub j * (๐ฎโง2 * ๐ + ๐ฏโง2) ^ j * (๐ฎโง2 * (2 * โ - 1)) ^ (q - j))
= insertion f (G_sub j) * insertion f ((๐ฎโง2 * ๐ + ๐ฏโง2) ^ j) * insertion f ((๐ฎโง2 * (2 * โ - 1)) ^ (q - j))"
using insertion_mult[of f] by simp
have 1: "insertion f ((๐ฎโง2 * ๐ + ๐ฏโง2) ^ j) * insertion f ((๐ฎโง2 * (2 * โ - 1)) ^ (q - j))
= (insertion f (๐ฎโง2 * ๐ + ๐ฏโง2)) ^ j * (insertion f (๐ฎโง2 * (2 * โ - 1))) ^ (q - j)"
using insertion_pow by metis
have "insertion f (๐ฎโง2 * ๐ + ๐ฏโง2) = insertion f (๐ฎ*๐ฎ) * insertion f ๐ + insertion f (๐ฏ*๐ฏ)"
using insertion_add[of f] insertion_mult[of f] power2_eq_square by metis
also have "... = (insertion f ๐ฎ)^2 * insertion f ๐ + (insertion f ๐ฏ)^2"
using insertion_mult[of f] power2_eq_square by metis
also have "... = S^2 * n + T^2"
unfolding ๐ฎ_def ๐_def ๐ฏ_def using f_def by simp
finally have 2: "insertion f (๐ฎโง2 * ๐ + ๐ฏโง2) = S^2 * n + T^2" by simp
have "insertion f (๐ฎโง2 * (2 * โ - 1)) = (insertion f ๐ฎ)^2 * insertion f (2 * โ - 1)"
using insertion_mult[of f] power2_eq_square by metis
also have "... = (insertion f ๐ฎ)^2 * (insertion f (2*โ) - insertion f 1)"
by simp
also have "... = (insertion f ๐ฎ)^2 * (2 * insertion f โ - 1)"
by (simp add: insertion_mult[of f])
also have "... = S^2 * (2*R-1)"
unfolding ๐ฎ_def โ_def using f_def by simp
finally have 3: "insertion f (๐ฎโง2 * (2 * โ - 1)) = S^2 * (2*R-1)" by simp
show ?thesis using 0 1 2 3 by simp
qed
have 2: "jโคq โน (S^2 * n + T^2)^j * (S^2 * (2*R- 1)) ^ (q - j)
= (y+I+T^2)^j * (S^2 * (2*R- 1)) ^ q" for j
proof -
assume jLeq: "jโคq"
have "S^2 * n + T^2 = S^2*(2*R-1)*(y+I+T^2) - S^2 * TdS^2 + T^2" unfolding n_def nโฉi_def
by (simp add: right_diff_distrib)
also have "... = S^2*(2*R-1)*(y+I+T^2) - (S* TdS)^2 + T^2" using power_mult_distrib by metis
also have "... = S^2*(2*R-1)*(y+I+T^2)" using TdS_def by (simp add: mult.commute)
finally have "(S^2 * n + T^2)^j * (S^2 * (2*R- 1)) ^ (q - j)
= (S^2*(2*R-1)*(y+I+T^2))^j * (S^2 * (2*R- 1)) ^ (q - j)" by simp
also have "... = (y+I+T^2)^j * (S^2*(2*R-1))^j * (S^2 * (2*R- 1)) ^ (q - j)"
using power_mult_distrib mult.commute by metis
also have "... = (y+I+T^2)^j * (S^2 * (2*R- 1))^q" using power_add jLeq
by (metis (no_types, lifting) add_diff_cancel_left' mult.assoc nat_le_iff_add)
finally show ?thesis by simp
qed
hence "insertion f ฮ
= (โj = 0..q. insertion f (G_sub j) * (S^2 * n + T^2)^j * (S^2 * (2*R- 1)) ^ (q - j))"
using 0 1 by presburger
also have "... = (โj = 0..q. insertion f (G_sub j) * (y+I+T^2)^j * (S^2 * (2*R- 1)) ^ q)"
using 2 by (metis (no_types, lifting) ab_semigroup_mult_class.mult_ac(1) atLeastAtMost_iff sum.cong)
finally have inser_expr_1: "insertion f ฮ =
(โj = 0..q. insertion f (G_sub j) * (y+I+T^2)^j) * (S^2 * (2*R- 1)) ^ q"
using sum_distrib_right[of _ _ "(S^2 * (2*R- 1)) ^ q"] by metis
have inser_G_sub: "insertion f (G_sub j) = (โi=j..q. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j))"
for j
proof -
have "insertion f (G_sub j)
= insertion f (โi=j..q. of_int (coeff_F i) * of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j))"
unfolding G_sub_def by blast
also have "... = (โi=j..q. insertion f (of_int (coeff_F i) * of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j)))"
using insertion_sum by blast
also have "... = (โi=j..q. (coeff_F i) * of_nat (i choose j) * insertion f ((-โ-๐ฏ^2)^(i-j)))"
proof -
have 1: "insertion f (of_int (coeff_F i) * of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j))
= (coeff_F i) * insertion f (of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j))" for i
using mult.assoc insertion_of_int_times by metis
moreover have "(coeff_F i) * insertion f (of_nat (i choose j) * (-โ-๐ฏ^2)^(i-j))
= (coeff_F i) * (i choose j) * insertion f ((-โ-๐ฏ^2)^(i-j))" for i
using insertion_mult
by (smt (verit) ab_semigroup_mult_class.mult_ac(1) insertion_of_int_times mult.commute
of_int_of_nat_eq)
ultimately show ?thesis by presburger
qed
also have "... = (โi=j..q. (coeff_F i) * of_nat (i choose j) * (insertion f (-โ-๐ฏ^2))^(i-j))"
proof -
have "insertion f ((-โ-๐ฏ^2)^(i-j)) = (insertion f (-โ-๐ฏ^2))^(i-j)" for i
using insertion_pow by blast
thus ?thesis by simp
qed
also have "... = (โi=j..q. (coeff_F i) * of_nat (i choose j) * (-insertion f โ - (insertion f ๐ฏ) ^2 )^(i-j))"
proof -
have "insertion f (-โ-๐ฏ^2) = -insertion f (โ + ๐ฏ^2)" by simp
also have "... = -insertion f โ - (insertion f (๐ฏ^2))" by simp
finally have "insertion f (-โ-๐ฏ^2) = -insertion f โ - (insertion f ๐ฏ) ^2"
using insertion_mult[of "f" ๐ฏ ๐ฏ] power2_eq_square by metis
thus ?thesis by simp
qed
also have "... = (โi=j..q. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j))"
unfolding defs using f_def by simp
finally show ?thesis by blast
qed
hence "(โj = 0..q. insertion f (G_sub j) * (y+I+T^2)^j)
= (โj = 0..q. (โi=j..q. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j)) * (y+I+T^2)^j)"
using inser_G_sub by presburger
also have "... = (โj = 0..q. (โi=j..q. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j))"
proof -
have "(โi=j..q. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j)) * (y+I+T^2)^j
= (โi=j..q. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j)" for j
using sum_distrib_right by blast
thus ?thesis by presburger
qed
also have "... = (โi = 0..q. (โj=0..i. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j))"
using triangular_sum[of "(ฮปj. (ฮปi. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j))" q]
by argo
also have "... = (โi = 0..q. coeff_F i * (โj=0..i. of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j))"
proof -
have "(โj=0..i. coeff_F i * of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j)
= coeff_F i * (โj=0..i. of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j)" for i
using sum_distrib_left[of "coeff_F i" "(ฮปj. of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j)" "{0..i}"]
by (metis (no_types, lifting) ab_semigroup_mult_class.mult_ac(1) sum.cong)
thus ?thesis by presburger
qed
also have "... = (โi = 0..q. coeff_F i * y^i)"
proof -
have "(โj=0..i. of_nat (i choose j) * (-I-T^2)^(i-j) * (y+I+T^2)^j) = y^i" for i
using binomial_ring[of "y+I+T^2" "-I-T^2" i]
by (smt (verit, best) ab_semigroup_mult_class.mult_ac(1) atLeast0AtMost mult.commute sum.cong)
thus ?thesis by simp
qed
also have "... = insertion (ฮป_. y) โฑ" using q_def eval_F by metis
also have "... = 0" using assms by blast
finally have "insertion f ฮ = 0" using inser_expr_1 by presburger
hence "insertion (ฯ n) ฮ = 0"
unfolding f_def ฯ_def by auto
moreover have "n = (2*R-1)*(y + I + T^2) - (T div S) ^ 2"
unfolding n_def nโฉi_def TdS_def using โนS โ 0โบ by auto
ultimately show "?thesis" by auto
qed
lemma ฮ _encodes_correctly_2:
fixes S T R I :: int
assumes "S โ 0"
"(โx. insertion (ฮป_. x) โฑ = 0 โถ x > -I)"
defines "ฯ n โก (ฮป_. 0)(4:= S, 5:=T, 6:=R, 7:=I, 11:=int n)"
assumes "โn :: nat. insertion (ฯ n) ฮ = 0"
shows "S dvd T โง R > 0 โง (โx::int. (insertion (ฮป_. x) โฑ) = 0)"
proof -
from assms obtain n where
prop_2_n: "insertion ((ฮป_. 0) (4 := S, 5:=T, 6:=R, 7:= I, 11:= int n)) ฮ = 0"
unfolding ฯ_def by auto
define subst::"natโint" where "subst = ((ฮป_. 0) (4 := S, 5 := T, 6 := R, 7 := I, 11 := n))"
define J::int where "J = S^2 * (2*R-1)"
have "2*R-1 โ 0" by presburger
hence Jnot0: "Jโ 0" unfolding J_def using assms by simp
have "0 = insertion subst (โj=0..q. G_sub j * (๐ฎ^2 * ๐ + ๐ฏ^2)^j * (๐ฎ^2*(2*โ-1))^(q-j))"
using prop_2_n unfolding ฮ _def[symmetric] subst_def by argo
also have "... = (โj=0..q. insertion subst (G_sub j * (๐ฎ^2 * ๐ + ๐ฏ^2)^j * (๐ฎ^2*(2*โ-1))^(q-j)))"
using insertion_sum by blast
also have "... = (โj=0..q. insertion subst (G_sub j) * insertion subst ((๐ฎ^2 * ๐ + ๐ฏ^2)^j * (๐ฎ^2*(2*โ-1))^(q-j)))"
proof -
have "insertion subst (G_sub j * (๐ฎ^2 * ๐ + ๐ฏ^2)^j * (๐ฎ^2*(2*โ-1))^(q-j))
= insertion subst (G_sub j) * insertion subst ((๐ฎ^2 * ๐ + ๐ฏ^2)^j * (๐ฎ^2*(2*โ-1))^(q-j))" for j
using insertion_mult[of subst] by simp
thus ?thesis by presburger
qed
also have "... = (โj=0..q. insertion subst (G_sub j) * (S^2 * n + T^2)^j * (S^2*(2*R-1))^(q-j))"
proof -
have "insertion subst ((๐ฎ^2 * ๐ + ๐ฏ^2)^j * (๐ฎ^2*(2*โ-1))^(q-j)) = (S^2 * n + T^2)^j * (S^2*(2*R-1))^(q-j)" for j
proof -
have 0: "insertion subst ((๐ฎโง2 * ๐ + ๐ฏโง2) ^ j * (๐ฎโง2 * (2 * โ - 1)) ^ (q - j))
= insertion subst ((๐ฎโง2 * ๐ + ๐ฏโง2) ^ j) * insertion subst ((๐ฎโง2 * (2 * โ - 1)) ^ (q - j))"
using insertion_mult[of subst] by simp
have 1: "insertion subst ((๐ฎโง2 * ๐ + ๐ฏโง2) ^ j) * insertion subst ((๐ฎโง2 * (2 * โ - 1)) ^ (q - j))
= (insertion subst (๐ฎโง2 * ๐ + ๐ฏโง2)) ^ j * (insertion subst (๐ฎโง2 * (2 * โ - 1))) ^ (q - j)"
using insertion_pow by metis
have "insertion subst (๐ฎโง2 * ๐ + ๐ฏโง2) = insertion subst (๐ฎ*๐ฎ) * insertion subst ๐ + insertion subst (๐ฏ*๐ฏ)"
using insertion_add[of subst] insertion_mult[of subst] power2_eq_square by metis
also have "... = (insertion subst ๐ฎ)^2 * insertion subst ๐ + (insertion subst ๐ฏ)^2"
using insertion_mult[of subst] power2_eq_square by metis
also have "... = S^2 * n + T^2"
unfolding ๐ฎ_def ๐_def ๐ฏ_def using subst_def by simp
finally have 2: "insertion subst (๐ฎโง2 * ๐ + ๐ฏโง2) = S^2 * n + T^2" by simp
have "insertion subst (๐ฎโง2 * (2 * โ - 1)) = (insertion subst ๐ฎ)^2 * insertion subst (2 * โ - 1)"
using insertion_mult[of subst] power2_eq_square by metis
also have "... = (insertion subst ๐ฎ)^2 * (insertion subst (2*โ) - insertion subst 1)"
by simp
also have "... = (insertion subst ๐ฎ)^2 * (2 * insertion subst โ - 1)"
using insertion_of_int_times[of subst 2] by simp
also have "... = S^2 * (2*R-1)"
unfolding ๐ฎ_def โ_def using subst_def by simp
finally have 3: "insertion subst (๐ฎโง2 * (2 * โ - 1)) = S^2 * (2*R-1)" by simp
show ?thesis using 0 1 2 3 by argo
qed
thus ?thesis using sum.cong by (simp add: ab_semigroup_mult_class.mult_ac(1))
qed
finally have ฮ _eq_0: "(โj=0..q. insertion subst (G_sub j) * (S^2 * n + T^2)^j * (S^2*(2*R-1))^(q-j)) = 0"
by simp
hence J_div_ST: "J dvd S^2 * n + T^2" using lemma_J_div_Z unfolding J_def by blast
hence "S^2 dvd S^2 * n + T^2" unfolding J_def by fastforce
hence "S^2 dvd (S^2*n + T^2) - S^2*n" by fastforce
hence "S^2 dvd T^2" by simp
hence S_dvd_T: "S dvd T" by simp
obtain Z::int where Z_prop: "S^2 * n + T^2 = Z * J" using J_div_ST by fastforce
hence "insertion (ฮป_. Z - subst 7 - (subst 5)^2) โฑ = 0"
using ฮ _eq_0 Jnot0 lemma_pos[of subst "S^2*n+T^2" "J" "Z"]
unfolding J_def by blast
hence F_cancels: "insertion (ฮป_. Z - I - T^2) โฑ = 0"
unfolding subst_def by simp
hence "Z - I - T^2 > -I"
using assms by blast
hence "Z > T^2" by simp
hence "Z โ 0" by fastforce
hence SnT_not_0: "S^2 * n + T^2 โ 0" using Z_prop Jnot0 by simp
have Snt: "S^2 * n + T^2 โฅ 0" using prop_2_n by simp
hence SnT_B_0: "S^2 * n + T^2 > 0" using SnT_not_0 by linarith
have "T^2 โฅ0" by simp
hence ZB0:"Z > 0" using โนZ > T^2โบ by linarith
hence "Jโค0 โน False"
proof -
assume "Jโค0"
hence "J<0" using Jnot0 by simp
hence "S^2 * n + T^2 < 0" using Z_prop ZB0
by (metis SnT_B_0 one_dvd plus_int_code(2) zdvd_not_zless zero_less_mult_pos zless_add1_eq)
thus "False" using Snt by simp
qed
hence JB0:"J>0" by fastforce
hence "S^2 * (2 * R- 1) > 0" unfolding J_def by blast
hence "2 * R- 1 > 0"
by (metis mult_eq_0_iff zero_eq_power2 zero_less_mult_pos zero_less_power2)
hence "2*R > 0" by simp
hence RB0: "R > 0" by simp
thus "?thesis" using S_dvd_T RB0 F_cancels by blast
qed
end
end