Theory RM_Sums_Diophantine
theory RM_Sums_Diophantine imports Equation_Setup "../Diophantine/Register_Machine_Sums"
"../Diophantine/Binary_And"
begin
context register_machine
begin
definition sum_ssub_nzero_of_bit_and :: "polynomial ⇒ nat ⇒ polynomial list ⇒ polynomial list
⇒ relation"
(‹[_ = ∑S- _ '(_ && _')]›) where
"[x = ∑S- d (s && z)] ≡ let x' = push_param x (length p);
s' = push_param_list s (length p);
z' = push_param_list z (length p)
in [∃length p] [∀<length p] (λi. [Param i = s'!i && z'!i])
[∧] x' [=] ([∑S-] p d Param)"
lemma sum_ssub_nzero_of_bit_and_dioph[dioph]:
fixes s z :: "polynomial list" and d :: nat and x
shows "is_dioph_rel [x = ∑S- d (s && z)]"
unfolding sum_ssub_nzero_of_bit_and_def by (auto simp add: dioph)
lemma sum_rsub_nzero_of_bit_and_eval:
fixes z s :: "polynomial list" and d :: nat and x :: polynomial
assumes "length s = Suc m" "length z = Suc m" "length p > 0"
shows "eval [x = ∑S- d (s && z)] a
⟷ peval x a = ∑S- p d (λk. peval (s!k) a && peval (z!k) a)" (is "?P ⟷ ?Q")
proof -
have invariance: "∀k<length p. y1 k = y2 k ⟹ ∑S- p d y1 = ∑S- p d y2" for y1 y2
unfolding sum_ssub_nzero.simps apply (intro sum.cong, simp)
using ‹length p > 0› by auto (metis Suc_pred le_imp_less_Suc length_greater_0_conv)
have len_ps: "length s = length p"
using m_def ‹length s = Suc m› ‹length p > 0› by auto
have len_pz: "length z = length p"
using m_def ‹length z = Suc m› ‹length p > 0› by auto
show ?thesis
proof (rule)
assume ?P
thus ?Q
using sum_ssub_nzero_of_bit_and_def ‹length p > 0› apply (auto simp add: defs push_push)
using push_push_map_i apply (simp add: push_param_list_def len_ps len_pz)
unfolding list_eval_def apply (auto simp: assms len_ps len_pz invariance)
apply (rule sum_ssub_nzero_cong) apply auto
by (metis (no_types, lifting) One_nat_def assms(1) assms(2)
le_imp_less_Suc len_ps m_def nth_map)
next
assume ?Q
thus ?P
using sum_ssub_nzero_of_bit_and_def ‹length p > 0› apply (auto simp add: defs push_push)
apply (rule exI[of _ "map (λk. peval (s ! k) a && peval (z ! k) a) [0..<length p]"], simp)
using push_push push_push_map_i
by (simp add: push_param_list_def invariance push_list_eval len_ps len_pz)
qed
qed
definition sum_ssub_zero_of_bit_and :: "polynomial ⇒ nat ⇒ polynomial list ⇒ polynomial list
⇒ relation"
(‹[_ = ∑S0 _ '(_ && _')]›) where
"[x = ∑S0 d (s && z)] ≡ let x' = push_param x (length p);
s' = push_param_list s (length p);
z' = push_param_list z (length p)
in [∃length p] [∀<length p] (λi. [Param i = s'!i && z'!i])
[∧] x' [=] [∑S0] p d Param"
lemma sum_ssub_zero_of_bit_and_dioph[dioph]:
fixes s z :: "polynomial list" and d :: nat and x
shows "is_dioph_rel [x = ∑S0 d (s && z)]"
unfolding sum_ssub_zero_of_bit_and_def by (auto simp add: dioph)
lemma sum_rsub_zero_of_bit_and_eval:
fixes z s :: "polynomial list" and d :: nat and x :: polynomial
assumes "length s = Suc m" "length z = Suc m" "length p > 0"
shows "eval [x = ∑S0 d (s && z)] a
⟷ peval x a = ∑S0 p d (λk. peval (s!k) a && peval (z!k) a)" (is "?P ⟷ ?Q")
proof -
have invariance: "∀k<length p. y1 k = y2 k ⟹ ∑S0 p d y1 = ∑S0 p d y2" for y1 y2
unfolding sum_ssub_zero.simps apply (intro sum.cong, simp)
using ‹length p > 0› by auto (metis Suc_pred le_imp_less_Suc length_greater_0_conv)
have len_ps: "length s = length p"
using m_def ‹length s = Suc m› ‹length p > 0› by auto
have len_pz: "length z = length p"
using m_def ‹length z = Suc m› ‹length p > 0› by auto
show ?thesis
proof (rule)
assume ?P
thus ?Q
using sum_ssub_zero_of_bit_and_def ‹length p > 0› apply (auto simp add: defs push_push)
using push_push_map_i apply (simp add: push_param_list_def len_ps len_pz)
unfolding list_eval_def apply (auto simp: assms len_ps len_pz invariance)
apply (rule sum_ssub_zero_cong) apply auto
by (metis (no_types, lifting) One_nat_def assms(1) assms(2)
le_imp_less_Suc len_ps m_def nth_map)
next
assume ?Q
thus ?P
using sum_ssub_zero_of_bit_and_def ‹length p > 0› apply (auto simp add: defs push_push)
apply (rule exI[of _ "map (λk. peval (s ! k) a && peval (z!k) a) [0..<length p]"], simp)
using push_push push_push_map_i
by (simp add: push_param_list_def invariance push_list_eval len_ps len_pz)
qed
qed
end
end