Theory Tactics
theory Tactics
imports
Proofs_Basis
begin
section‹ CIMP specialisation \label{sec:cimp-specialisation} ›
subsection‹ Hoare triples ›
text‹
Specialise CIMP's pre/post validity to our system.
›
definition
valid_proc :: "('field, 'mut, 'payload, 'ref) gc_pred ⇒ 'mut process_name ⇒ ('field, 'mut, 'payload, 'ref) gc_pred ⇒ bool" ("⦃_⦄ _ ⦃_⦄")
where
"⦃P⦄ p ⦃Q⦄ = (∀(c, afts) ∈ vcg_fragments (gc_coms p). gc_coms, p, afts ⊢ ⦃P⦄ c ⦃Q⦄)"
abbreviation
valid_proc_inv_syn :: "('field, 'mut, 'payload, 'ref) gc_pred ⇒ 'mut process_name ⇒ bool" ("⦃_⦄ _" [100,0] 100)
where
"⦃P⦄ p ≡ ⦃P⦄ p ⦃P⦄"
lemma valid_pre:
assumes "⦃Q⦄ p ⦃R⦄"
assumes "⋀s. P s ⟹ Q s"
shows "⦃P⦄ p ⦃R⦄"
using assms
apply (clarsimp simp: valid_proc_def)
apply (drule (1) bspec)
apply (auto elim: vcg_pre)
done
lemma valid_conj_lift:
assumes x: "⦃P⦄ p ⦃Q⦄"
assumes y: "⦃P'⦄ p ⦃Q'⦄"
shows "⦃P ❙∧ P'⦄ p ⦃Q ❙∧ Q'⦄"
apply (clarsimp simp: valid_proc_def)
apply (rule vcg_conj)
apply (rule vcg_pre[OF spec[OF spec[OF x[unfolded Ball_def valid_proc_def split_paired_All]], simplified, rule_format]], simp, simp)
apply (rule vcg_pre[OF spec[OF spec[OF y[unfolded Ball_def valid_proc_def split_paired_All]], simplified, rule_format]], simp, simp)
done
lemma valid_all_lift:
assumes "⋀x. ⦃P x⦄ p ⦃Q x⦄"
shows "⦃λs. ∀x. P x s⦄ p ⦃λs. ∀x. Q x s⦄"
using assms by (fastforce simp: valid_proc_def intro: vcg_all_lift)
subsection‹ Tactics ›
subsubsection‹ Model-specific ›
text‹
The following is unfortunately overspecialised to the GC. One might
hope for general tactics that work on all CIMP programs.
The system responds to all requests. The schematic variable is
instantiated with the semantics of the responses. Thanks to Thomas
Sewell for the hackery.
›
schematic_goal system_responds_actionE:
"⟦ (⦃l⦄ Response action, afts) ∈ fragments (gc_coms p) {}; v ∈ action x s;
⟦ p = sys; ?P ⟧ ⟹ Q ⟧ ⟹ Q"
apply (cases p)
apply (simp_all add: all_com_interned_defs)
apply atomize
apply (drule_tac P="x ∨ y" and Q="v ∈ action p k" for x y p k in conjI, assumption)
apply (thin_tac "v ∈ action p k" for p k)
apply (simp only: conj_disj_distribR conj_assoc mem_Collect_eq cong: conj_cong)
apply (erule mp)
apply (thin_tac "p = sys")
apply (assumption)
done
schematic_goal system_responds_action_caseE:
"⟦ (⦃l⦄ Response action, afts) ∈ fragments (gc_coms p) {}; v ∈ action (pname, req) s;
⟦ p = sys; case_request_op ?P1 ?P2 ?P3 ?P4 ?P5 ?P6 ?P7 ?P8 ?P9 ?P10 ?P11 ?P12 ?P13 ?P14 req ⟧ ⟹ Q ⟧ ⟹ Q"
apply (erule(1) system_responds_actionE)
apply (cases req; simp only: request_op.simps prod.inject simp_thms fst_conv snd_conv if_cancel empty_def[symmetric] empty_iff)
apply (drule meta_mp[OF _ TrueI], erule meta_mp, erule_tac P="A ∧ B" for A B in triv)+
done
schematic_goal system_responds_action_specE:
"⟦ (⦃l⦄ Response action, afts) ∈ fragments (gc_coms p) {}; v ∈ action x s;
⟦ p = sys; case_request_op ?P1 ?P2 ?P3 ?P4 ?P5 ?P6 ?P7 ?P8 ?P9 ?P10 ?P11 ?P12 ?P13 ?P14 (snd x) ⟧ ⟹ Q ⟧ ⟹ Q"
apply (erule system_responds_action_caseE[where pname="fst x" and req="snd x"])
apply simp
apply assumption
done
subsubsection ‹ Locations›
lemma atS_dests:
"⟦ atS p ls s; atS p ls' s ⟧ ⟹ atS p (ls ∪ ls') s"
"⟦ ¬atS p ls s; ¬atS p ls' s ⟧ ⟹ ¬atS p (ls ∪ ls') s"
"⟦ ¬atS p ls s; atS p ls' s ⟧ ⟹ atS p (ls' - ls) s"
"⟦ ¬atS p ls s; at p l s ⟧ ⟹ atS p ({l} - ls) s"
by (auto simp: atS_def)
lemma schematic_prem: "⟦Q ⟹ P; Q⟧ ⟹ P"
by blast
lemma TrueE: "⟦True; P⟧ ⟹ P"
by blast
lemma thin_locs_pre_discardE:
"⟦at p l' s ⟶ P; at p l s; l' ≠ l; Q⟧ ⟹ Q"
"⟦atS p ls s ⟶ P; at p l s; l ∉ ls; Q⟧ ⟹ Q"
unfolding atS_def by blast+
lemma thin_locs_pre_keep_atE:
"⟦at p l s ⟶ P; at p l s; P ⟹ Q⟧ ⟹ Q"
by blast
lemma thin_locs_pre_keep_atSE:
"⟦atS p ls s ⟶ P; at p l s; l ∈ ls; P ⟹ Q⟧ ⟹ Q"
unfolding atS_def by blast
lemma thin_locs_post_discardE:
"⟦AT s' = (AT s)(p := lfn, q := lfn'); l' ∉ lfn; p ≠ q⟧ ⟹ at p l' s' ⟶ P"
"⟦AT s' = (AT s)(p := lfn); l' ∉ lfn⟧ ⟹ at p l' s' ⟶ P"
"⟦AT s' = (AT s)(p := lfn, q := lfn'); ⋀l. l ∈ lfn ⟹ l ∉ ls; p ≠ q⟧ ⟹ atS p ls s' ⟶ P"
"⟦AT s' = (AT s)(p := lfn); ⋀l. l ∈ lfn ⟹ l ∉ ls⟧ ⟹ atS p ls s' ⟶ P"
unfolding atS_def by (auto simp: fun_upd_apply)
lemmas thin_locs_post_discard_conjE =
conjI[OF thin_locs_post_discardE(1)]
conjI[OF thin_locs_post_discardE(2)]
conjI[OF thin_locs_post_discardE(3)]
conjI[OF thin_locs_post_discardE(4)]
lemma thin_locs_post_keep_locsE:
"⟦(L ⟶ P) ∧ R; R ⟹ Q⟧ ⟹ (L ⟶ P) ∧ Q"
"L ⟶ P ⟹ L ⟶ P"
by blast+
lemma thin_locs_post_keepE:
"⟦P ∧ R; R ⟹ Q⟧ ⟹ (L ⟶ P) ∧ Q"
"P ⟹ L ⟶ P"
by blast+
lemma ni_thin_locs_discardE:
"⟦at proc l s ⟶ P; AT s' = (AT s)(p := lfn, q := lfn'); at proc l' s'; l ≠ l'; proc ≠ p; proc ≠ q; Q⟧ ⟹ Q"
"⟦at proc l s ⟶ P; AT s' = (AT s)(p := lfn); at proc l' s'; l ≠ l'; proc ≠ p; Q⟧ ⟹ Q"
"⟦atS proc ls s ⟶ P; AT s' = (AT s)(p := lfn, q := lfn'); at proc l' s'; l' ∉ ls; proc ≠ p; proc ≠ q; Q⟧ ⟹ Q"
"⟦atS proc ls s ⟶ P; AT s' = (AT s)(p := lfn); at proc l' s'; l' ∉ ls; proc ≠ p; Q⟧ ⟹ Q"
"⟦at proc l s ⟶ P; AT s' = (AT s)(p := lfn, q := lfn'); atS proc ls' s'; l ∉ ls'; proc ≠ p; proc ≠ q; Q⟧ ⟹ Q"
"⟦at proc l s ⟶ P; AT s' = (AT s)(p := lfn); atS proc ls' s'; l ∉ ls'; proc ≠ p; Q⟧ ⟹ Q"
unfolding atS_def by auto
lemma ni_thin_locs_keep_atE:
"⟦at proc l s ⟶ P; AT s' = (AT s)(p := lfn, q := lfn'); at proc l s'; proc ≠ p; proc ≠ q; P ⟹ Q⟧ ⟹ Q"
"⟦at proc l s ⟶ P; AT s' = (AT s)(p := lfn); at proc l s'; proc ≠ p; P ⟹ Q⟧ ⟹ Q"
by (auto simp: fun_upd_apply)
lemma ni_thin_locs_keep_atSE:
"⟦atS proc ls s ⟶ P; AT s' = (AT s)(p := lfn, q := lfn'); at proc l' s'; l' ∈ ls; proc ≠ p; proc ≠ q; P ⟹ Q⟧ ⟹ Q"
"⟦atS proc ls s ⟶ P; AT s' = (AT s)(p := lfn); at proc l' s'; l' ∈ ls; proc ≠ p; P ⟹ Q⟧ ⟹ Q"
"⟦atS proc ls s ⟶ P; AT s' = (AT s)(p := lfn, q := lfn'); atS proc ls' s'; ls' ⊆ ls; proc ≠ p; proc ≠ q; P ⟹ Q⟧ ⟹ Q"
"⟦atS proc ls s ⟶ P; AT s' = (AT s)(p := lfn); atS proc ls' s'; ls' ⊆ ls; proc ≠ p; P ⟹ Q⟧ ⟹ Q"
unfolding atS_def by (auto simp: fun_upd_apply)
lemma loc_mem_tac_intros:
"⟦c ∉ A; c ∉ B⟧ ⟹ c ∉ A ∪ B"
"c ≠ d ⟹ c ∉ {d}"
"c ∉ A ⟹ c ∈ - A"
"c ∈ A ⟹ c ∉ - A"
"A ⊆ A"
by blast+
lemmas loc_mem_tac_elims =
singletonE
UnE
lemmas loc_mem_tac_simps =
append.simps list.simps rev.simps
char.inject cong_exp_iff_simps
prefix_code suffix_to_prefix
simp_thms
Eq_FalseI
not_Cons_self
lemmas vcg_fragments'_simps =
valid_proc_def gc_coms.simps vcg_fragments'.simps atC.simps
ball_Un bool_simps if_False if_True
lemmas