Theory Classical_Extra
section ‹Derived facts about classical registers›
theory Classical_Extra
imports Laws_Classical Misc
begin
lemma [simp]: ‹register_from_getter_setter (getter F) (setter F) = F› if ‹register F›
by (metis getter_of_register_from_getter_setter register_def setter_of_register_from_getter_setter that)
lemma [simp]: ‹valid_getter_setter (getter F) (setter F)› if ‹register F›
by (metis getter_of_register_from_getter_setter register_def setter_of_register_from_getter_setter that)
lemma [simp]: ‹register (register_from_getter_setter g s)› if ‹valid_getter_setter g s›
using register_def that by blast
‹ f = (∀x. f x ≠ None)›
lemma :
assumes ‹register F›
assumes ‹total_fun a›
shows ‹total_fun (F a)›
using assms
by (auto simp: register_def total_fun_def register_from_getter_setter_def option.case_eq_if)
lemma :
assumes ‹register F›
shows ‹Some o register_apply F a = F (Some o a)›
proof -
have ‹total_fun (F (Some o a))›
using assms apply (rule register_total)
by (auto simp: total_fun_def)
then show ?thesis
by (auto simp: register_apply_def dom_def total_fun_def)
qed
lemma :
assumes ‹preregister F›
shows ‹F Map.empty = Map.empty›
using assms unfolding preregister_def by auto
lemma :
fixes F :: ‹('a,'c) preregister› and G :: ‹('b,'c) preregister›
assumes [simp]: ‹register F› ‹register G›
shows ‹compatible F G ⟷ (∀a b. setter F a o setter G b = setter G b o setter F a)›
proof (intro allI iffI)
fix a b
assume ‹compatible F G›
then show ‹setter F a o setter G b = setter G b o setter F a›
apply (rule_tac compatible_setter)
unfolding compatible_def by auto
next
assume commute[rule_format, THEN fun_cong, unfolded o_def]: ‹∀a b. setter F a ∘ setter G b = setter G b ∘ setter F a›
have ‹valid_getter_setter (getter F) (setter F)›
by auto
then have ‹F a ∘⇩m G b = G b ∘⇩m F a› for a b
apply (subst (2) register_from_getter_setter_of_getter_setter[symmetric, of F], simp)
apply (subst (1) register_from_getter_setter_of_getter_setter[symmetric, of F], simp)
apply (subst (2) register_from_getter_setter_of_getter_setter[symmetric, of G], simp)
apply (subst (1) register_from_getter_setter_of_getter_setter[symmetric, of G], simp)
unfolding register_from_getter_setter_def valid_getter_setter_def
apply (auto intro!: ext simp: option.case_eq_if map_comp_def)
apply ((metis commute option.distinct option.simps)+)[4]
apply (smt (verit, ccfv_threshold) assms(2) commute valid_getter_setter_def valid_getter_setter_getter_setter)
apply (smt (verit, ccfv_threshold) assms(2) commute valid_getter_setter_def valid_getter_setter_getter_setter)
by (smt (verit, del_insts) assms(2) commute option.inject valid_getter_setter_def valid_getter_setter_getter_setter)
then show ‹compatible F G›
unfolding compatible_def by auto
qed
lemma [intro]:
assumes [simp]: ‹valid_getter_setter g s› ‹valid_getter_setter g' s'›
assumes ‹⋀x y m. s x (s' y m) = s' y (s x m)›
shows ‹compatible (register_from_getter_setter g s) (register_from_getter_setter g' s')›
apply (subst compatible_setter)
using assms by auto
lemma :
‹separating TYPE(_) {update1 x y | x y. True}›
by (smt (verit) mem_Collect_eq separating_def update1_extensionality)
" (p::'b⇒'a) = register_from_getter_setter p (λa _. inv p a)"
lemma [simp]:
fixes p :: "'b ⇒ 'a"
assumes [simp]: "bij p"
shows "register (permutation_register p)"
apply (auto intro!: register_register_from_getter_setter simp: permutation_register_def valid_getter_setter_def bij_inv_eq_iff)
by (meson assms bij_inv_eq_iff)
lemma : ‹bij p ⟹ getter (permutation_register p) = p›
by (smt (verit, ccfv_threshold) bij_inv_eq_iff getter_of_register_from_getter_setter permutation_register_def valid_getter_setter_def)
lemma : ‹bij p ⟹ setter (permutation_register p) a m = inv p a›
by (metis bij_inv_eq_iff getter_permutation_register permutation_register_register valid_getter_setter_def valid_getter_setter_getter_setter)
:: ‹'a::{CARD_1} update ⇒ 'b update› where
"empty_var = register_from_getter_setter (λ_. undefined) (λ_ m. m)"
lemma [simp]: ‹valid_getter_setter (λ_. (undefined::_::CARD_1)) (λ_ m. m)›
by (simp add: valid_getter_setter_def)
lemma [simp]: ‹register empty_var›
using empty_var_def register_def valid_empty_var by blast
lemma [simp]: ‹getter empty_var m = undefined›
by (rule everything_the_same)
lemma [simp]: ‹setter empty_var a m = m›
by (simp add: empty_var_def setter_of_register_from_getter_setter)
lemma [simp]: ‹compatible empty_var X› if [simp]: ‹register X›
apply (subst compatible_setter) by auto
lemma [simp]: ‹register X ⟹ compatible X empty_var›
using compatible_sym empty_var_compatible by blast
paragraph ‹Example›
=
x :: "int*int"
y :: nat
" = register_from_getter_setter x (λa b. b⦇x:=a⦈)"
" = register_from_getter_setter y (λa b. b⦇y:=a⦈)"
lemma [simp]: ‹valid_getter_setter x (λa b. b⦇x:=a⦈)›
unfolding valid_getter_setter_def by auto
lemma [simp]: ‹register X›
using X_def register_def validX by blast
lemma [simp]: ‹valid_getter_setter y (λa b. b⦇y:=a⦈)›
unfolding valid_getter_setter_def by auto
lemma [simp]: ‹register Y›
using Y_def register_def validY by blast
lemma [simp]: ‹compatible X Y›
unfolding X_def Y_def by auto
hide_const (open) x y x_update y_update X Y
end