Theory Modulo_Divisibility
subsection ‹Mod is Diophantine›
theory Modulo_Divisibility
imports Existential_Quantifier
begin
text ‹ Divisibility is diophantine ›
definition dvd (‹DVD _ _› 1000) where "DVD Q R ≡ (BINARY (dvd) Q R)"
lemma dvd_repr:
fixes a b :: nat
shows "a dvd b ⟷ (∃x. x * a = b)"
using dvd_class.dvd_def by auto
lemma dvd_dioph[dioph]: "is_dioph_rel (DVD Q R)"
proof -
define Q' R' where pushed_defs: "Q' ≡ push_param Q 1" "R' ≡ push_param R 1"
define D where "D ≡ [∃] (Param 0 [*] Q' [=] R')"
have "eval (DVD Q R) a = eval D a" for a
unfolding D_def pushed_defs defs using push_push1 apply (auto simp: push0)
unfolding dvd_def by (auto simp: dvd_repr binary_eval)
moreover have "is_dioph_rel D"
unfolding D_def by (auto simp: dioph)
ultimately show ?thesis
by (auto simp: is_dioph_rel_def)
qed
declare dvd_def[defs]
definition mod (‹MOD _ _ _› 1000)
where "MOD A B C ≡ (TERNARY (λa b c. a mod b = c mod b) A B C)"
declare mod_def[defs]
lemma mod_repr:
fixes a b c :: nat
shows "a mod b = c mod b ⟷ (∃x y. c + x*b = a + y*b)"
by (metis mult.commute nat_mod_eq_iff)
lemma mod_dioph[dioph]:
fixes A B C
defines "D ≡ (MOD A B C)"
shows "is_dioph_rel D"
proof -
define A' B' C' where pushed_defs: "A' ≡ push_param A 2" "B' ≡ push_param B 2" "C' ≡ push_param C 2"
define DS where "DS ≡ [∃2] (Param 0 [*] B' [+] C' [=] Param 1 [*] B' [+] A')"
have "eval DS a = eval D a" for a
proof
show "eval DS a ⟹ eval D a"
unfolding DS_def defs D_def mod_def
by auto (metis mod_mult_self3 push_push_simp pushed_defs(1) pushed_defs(2) pushed_defs(3))
show "eval D a ⟹ eval DS a"
unfolding DS_def defs D_def mod_def
apply (auto simp add: mod_repr)
subgoal for x y
apply (rule exI[of _ "[x, y]"])
unfolding pushed_defs by (simp add: push_push[where ?n = 2] push_list_eval)
done
qed
moreover have "is_dioph_rel DS"
unfolding DS_def by (simp add: dioph)
ultimately show ?thesis
by (auto simp: is_dioph_rel_def)
qed
declare mod_def[defs]
end