Theory Basic_Assn
theory Basic_Assn
imports
"Refine_Imperative_HOL.Sepref_HOL_Bindings"
"Refine_Imperative_HOL.Sepref_Basic"
begin
section "Auxilary imperative assumptions"
text "The following auxiliary assertion types and lemmas were provided by Peter Lammich"
subsection ‹List-Assn›
lemma list_assn_cong[fundef_cong]:
"⟦ xs=xs'; ys=ys'; ⋀x y. ⟦ x∈set xs; y∈set ys ⟧ ⟹ A x y = A' x y ⟧ ⟹ list_assn A xs ys = list_assn A' xs' ys'"
by (induction xs ys arbitrary: xs' ys' rule: list_assn.induct) auto
lemma list_assn_app_one: "list_assn P (l1@[x]) (l1'@[y]) = list_assn P l1 l1' * P x y"
by simp
lemma list_assn_len: "h ⊨ list_assn A xs ys ⟹ length xs = length ys"
using list_assn_aux_ineq_len by fastforce
lemma list_assn_append_Cons_left: "list_assn A (xs@x#ys) zs = (∃⇩A zs1 z zs2. list_assn A xs zs1 * A x z * list_assn A ys zs2 * ↑(zs1@z#zs2 = zs))"
by (sep_auto simp add: list_assn_aux_cons_conv list_assn_aux_append_conv1 intro!: ent_iffI)
lemma list_assn_aux_append_Cons:
shows "length xs = length zsl ⟹ list_assn A (xs@x#ys) (zsl@z#zsr) = (list_assn A xs zsl * A x z * list_assn A ys zsr) "
by (sep_auto simp add: mult.assoc)
lemma list_assn_prod_split: "list_assn (λx y. P x y * Q x y) as bs = list_assn P as bs * list_assn Q as bs"
proof(cases "length as = length bs")
case True
then show ?thesis
proof (induction rule: list_induct2)
case Nil
then show ?case by sep_auto
next
case (Cons x xs y ys)
show ?case
proof (rule ent_iffI, goal_cases)
case 1
then show ?case
using Cons by sep_auto
next
case 2
then show ?case
using Cons by sep_auto
qed
qed
next
case False
then show ?thesis
by (simp add: list_assn_aux_ineq_len)
qed
subsection ‹Prod-Assn›
lemma prod_assn_cong[fundef_cong]:
"⟦ p=p'; pi=pi'; A (fst p) (fst pi) = A' (fst p) (fst pi); B (snd p) (snd pi) = B' (snd p) (snd pi) ⟧
⟹ (A×⇩aB) p pi = (A'×⇩aB') p' pi'"
apply (cases p; cases pi)
by auto
subsection ‹Assertions and Magic Wand›
lemma entails_preI: "(⋀h. h ⊨ P ⟹ P ⟹⇩A Q) ⟹ P ⟹⇩A Q"
unfolding entails_def
by auto
lemma ent_true_drop_true:
"P*true⟹⇩AQ*true ⟹ P*R*true⟹⇩AQ*true"
using assn_aci(10) ent_true_drop(1) by presburger
lemma rem_true: "P*true ⟹⇩A Q*true ⟹ P ⟹⇩AQ*true"
using enttD enttI_true by blast
lemma assn_eq_split:
assumes "B = C"
shows "B ⟹⇩A C"
and "C ⟹⇩A B"
by (simp_all add: assms)
lemma ent_ex_inst: "∃⇩Ax. P x ⟹⇩A Q ⟹ P y ⟹⇩A Q"
using ent_trans by blast
lemma ent_ex_inst2: "∃⇩Ax y. P x y ⟹⇩A Q ⟹ P x y ⟹⇩A Q"
using ent_trans by blast
lemma ent_wandI2:
assumes IMP: "P ⟹⇩A (Q -* R)"
shows "Q*P ⟹⇩A R"
using assms
unfolding entails_def
proof (clarsimp, goal_cases)
case (1 h as)
then obtain as1 as2 where "as = as1 ∪ as2" "as1 ∩ as2 = {}" "(h,as1) ⊨ Q" "(h,as2) ⊨ P"
by (metis mod_star_conv prod.inject)
then have "(h,as2) ⊨ (Q-*R)"
by (simp add: "1"(1))
then have "(h,as1∪as2) ⊨ Q * (Q-*R)"
by (simp add: ‹(h, as1) ⊨ Q› ‹as1 ∩ as2 = {}› star_assnI)
then show ?case
using ‹as = as1 ∪ as2› ent_fwd ent_mp by blast
qed
lemma ent_wand: "(P ⟹⇩A (Q -* R)) = (Q*P ⟹⇩A R)"
using ent_wandI2 ent_wandI by blast
lemma wand_ent_trans:
assumes "P' ⟹⇩A P"
and "Q ⟹⇩A Q'"
shows "P -* Q ⟹⇩A P' -* Q'"
by (meson assms(1) assms(2) ent_wand ent_frame_fwd ent_refl ent_trans)
lemma wand_elim: "(P -* Q) * (Q -* R) ⟹⇩A (P -* R)"
by (metis ent_wand ent_frame_fwd ent_mp ent_refl star_assoc)
lemma emp_wand_same: "emp ⟹⇩A (H -* H)"
by (simp add: ent_wandI)
lemma emp_wand_equal: "(emp -* H) = H"
apply(intro ent_iffI)
apply (metis ent_mp norm_assertion_simps(1))
by (simp add: ent_wandI)
lemma pure_wand_equal: "P ⟹ (↑(P) -* H) = H"
by (simp add: emp_wand_equal)
lemma pure_wand_ent: "(P ⟹ (H1 ⟹⇩A H2)) ⟹ H1 ⟹⇩A ↑(P) -* H2"
by (simp add: ent_wand)
lemma "↑(P ⟶ Q) ⟹⇩A (↑(P) -* ↑(Q))"
by (simp add: pure_wand_ent)
lemma wand_uncurry: "(P*Q) -* R ⟹⇩A P -* (Q -* R)"
by (simp add: assn_aci ent_mp ent_wandI fr_rot)
lemma wand_absorb: "(P -* Q) * R ⟹⇩A (P -* (Q * R))"
by (smt (z3) ent_mp ent_refl ent_star_mono ent_wandI star_aci(2) star_aci(3))
lemma wand_ent_self: "P ⟹⇩A Q -* (Q * P)"
by (simp add: ent_wandI)
lemma wand_ent_cancel: "P * ((P * Q) -* R) ⟹⇩A Q -* R"
by (simp add: ent_wandI2 wand_uncurry)
lemma "∃R. Q * R ⟹⇩A P"
using ent_mp by auto
lemma "P ⟹⇩A Q * true ⟹ P = Q * (Q -* P)"
apply(intro ent_iffI)
proof(goal_cases)
case 2
then show ?case
by (simp add: ent_mp)
next
case test: 1
show ?case
unfolding entails_def
apply clarsimp
proof (goal_cases)
case (1 a b)
then have "(a,b) ⊨ Q * true"
using test entails_def
by blast
then obtain h as1 as2 where *:
"(a,b) = (h, as1 ∪ as2) ∧ as1 ∩ as2 = {} ∧ (h, as1) ⊨ Q ∧ (h, as2) ⊨ true"
using mod_star_conv by auto
then have "(h, as1 ∪ as2) ⊨ P" "(a,b) = (h, as1 ∪ as2)"
using "1" by blast+
then show ?case
apply simp
thm star_assnI
apply(intro star_assnI)
apply (simp_all add: *)
apply(intro wand_assnI)
apply (meson "*" models_in_range)
apply auto
oops
end