Theory HoarePartialProps
section ‹Properties of Partial Correctness Hoare Logic›
theory HoarePartialProps imports HoarePartialDef begin
subsection ‹Soundness›
lemma hoare_cnvalid:
assumes hoare: "Γ,Θ⊢⇘/F⇙ P c Q,A"
shows "⋀n. Γ,Θ⊨n:⇘/F⇙ P c Q,A"
using hoare
proof (induct)
case (Skip Θ F P A)
show "Γ,Θ ⊨n:⇘/F⇙ P Skip P,A"
proof (rule cnvalidI)
fix s t
assume "Γ⊢⟨Skip,Normal s⟩ =n⇒ t" "s ∈ P"
thus "t ∈ Normal ` P ∪ Abrupt ` A"
by cases auto
qed
next
case (Basic Θ F f P A)
show "Γ,Θ ⊨n:⇘/F⇙ {s. f s ∈ P} (Basic f) P,A"
proof (rule cnvalidI)
fix s t
assume "Γ⊢⟨Basic f,Normal s⟩ =n⇒ t" "s ∈ {s. f s ∈ P}"
thus "t ∈ Normal ` P ∪ Abrupt ` A"
by cases auto
qed
next
case (Spec Θ F r Q A)
show "Γ,Θ⊨n:⇘/F⇙ {s. (∀t. (s, t) ∈ r ⟶ t ∈ Q) ∧ (∃t. (s, t) ∈ r)} Spec r Q,A"
proof (rule cnvalidI)
fix s t
assume exec: "Γ⊢⟨Spec r,Normal s⟩ =n⇒ t"
assume P: "s ∈ {s. (∀t. (s, t) ∈ r ⟶ t ∈ Q) ∧ (∃t. (s, t) ∈ r)}"
from exec P
show "t ∈ Normal ` Q ∪ Abrupt ` A"
by cases auto
qed
next
case (Seq Θ F P c1 R A c2 Q)
have valid_c1: "⋀n. Γ,Θ ⊨n:⇘/F⇙ P c1 R,A" by fact
have valid_c2: "⋀n. Γ,Θ ⊨n:⇘/F⇙ R c2 Q,A" by fact
show "Γ,Θ ⊨n:⇘/F⇙ P Seq c1 c2 Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨Seq c1 c2,Normal s⟩ =n⇒ t"
assume t_notin_F: "t ∉ Fault ` F"
assume P: "s ∈ P"
from exec P obtain r where
exec_c1: "Γ⊢⟨c1,Normal s⟩ =n⇒ r" and exec_c2: "Γ⊢⟨c2,r⟩ =n⇒ t"
by cases auto
with t_notin_F have "r ∉ Fault ` F"
by (auto dest: execn_Fault_end)
with valid_c1 ctxt exec_c1 P
have r: "r∈Normal ` R ∪ Abrupt ` A"
by (rule cnvalidD)
show "t∈Normal ` Q ∪ Abrupt ` A"
proof (cases r)
case (Normal r')
with exec_c2 r
show "t∈Normal ` Q ∪ Abrupt ` A"
apply -
apply (rule cnvalidD [OF valid_c2 ctxt _ _ t_notin_F])
apply auto
done
next
case (Abrupt r')
with exec_c2 have "t=Abrupt r'"
by (auto elim: execn_elim_cases)
with Abrupt r show ?thesis
by auto
next
case Fault with r show ?thesis by blast
next
case Stuck with r show ?thesis by blast
qed
qed
next
case (Cond Θ F P b c1 Q A c2)
have valid_c1: "⋀n. Γ,Θ ⊨n:⇘/F⇙ (P ∩ b) c1 Q,A" by fact
have valid_c2: "⋀n. Γ,Θ ⊨n:⇘/F⇙ (P ∩ - b) c2 Q,A" by fact
show "Γ,Θ ⊨n:⇘/F⇙ P Cond b c1 c2 Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨Cond b c1 c2,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases "s∈b")
case True
with exec have "Γ⊢⟨c1,Normal s⟩ =n⇒ t"
by cases auto
with P True
show ?thesis
by - (rule cnvalidD [OF valid_c1 ctxt _ _ t_notin_F],auto)
next
case False
with exec P have "Γ⊢⟨c2,Normal s⟩ =n⇒ t"
by cases auto
with P False
show ?thesis
by - (rule cnvalidD [OF valid_c2 ctxt _ _ t_notin_F],auto)
qed
qed
next
case (While Θ F P b c A n)
have valid_c: "⋀n. Γ,Θ ⊨n:⇘/F⇙ (P ∩ b) c P,A" by fact
show "Γ,Θ ⊨n:⇘/F⇙ P While b c (P ∩ - b),A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨While b c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` (P ∩ - b) ∪ Abrupt ` A"
proof (cases "s ∈ b")
case True
{
fix d::"('b,'a,'c) com" fix s t
assume exec: "Γ⊢⟨d,s⟩ =n⇒ t"
assume d: "d=While b c"
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
from exec d ctxt
have "⟦s ∈ Normal ` P; t ∉ Fault ` F⟧
⟹ t ∈ Normal ` (P ∩ - b) ∪ Abrupt`A"
proof (induct)
case (WhileTrue s b' c' n r t)
have t_notin_F: "t ∉ Fault ` F" by fact
have eqs: "While b' c' = While b c" by fact
note valid_c
moreover have ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A" by fact
moreover from WhileTrue
obtain "Γ⊢⟨c,Normal s⟩ =n⇒ r" and
"Γ⊢⟨While b c,r⟩ =n⇒ t" and
"Normal s ∈ Normal `(P ∩ b)" by auto
moreover with t_notin_F have "r ∉ Fault ` F"
by (auto dest: execn_Fault_end)
ultimately
have r: "r ∈ Normal ` P ∪ Abrupt ` A"
by - (rule cnvalidD,auto)
from this _ ctxt
show "t ∈ Normal ` (P ∩ - b) ∪ Abrupt ` A "
proof (cases r)
case (Normal r')
with r ctxt eqs t_notin_F
show ?thesis
by - (rule WhileTrue.hyps,auto)
next
case (Abrupt r')
have "Γ⊢⟨While b' c',r⟩ =n⇒ t" by fact
with Abrupt have "t=r"
by (auto dest: execn_Abrupt_end)
with r Abrupt show ?thesis
by blast
next
case Fault with r show ?thesis by blast
next
case Stuck with r show ?thesis by blast
qed
qed auto
}
with exec ctxt P t_notin_F
show ?thesis
by auto
next
case False
with exec P have "t=Normal s"
by cases auto
with P False
show ?thesis
by auto
qed
qed
next
case (Guard Θ F g P c Q A f)
have valid_c: "⋀n. Γ,Θ ⊨n:⇘/F⇙ (g ∩ P) c Q,A" by fact
show "Γ,Θ ⊨n:⇘/F⇙ (g ∩ P) Guard f g c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨Guard f g c,Normal s⟩ =n⇒ t"
assume t_notin_F: "t ∉ Fault ` F"
assume P:"s ∈ (g ∩ P)"
from exec P have "Γ⊢⟨c,Normal s⟩ =n⇒ t"
by cases auto
from valid_c ctxt this P t_notin_F
show "t ∈ Normal ` Q ∪ Abrupt ` A"
by (rule cnvalidD)
qed
next
case (Guarantee f F Θ g P c Q A)
have valid_c: "⋀n. Γ,Θ ⊨n:⇘/F⇙ (g ∩ P) c Q,A" by fact
have f_F: "f ∈ F" by fact
show "Γ,Θ ⊨n:⇘/F⇙ P Guard f g c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨Guard f g c,Normal s⟩ =n⇒ t"
assume t_notin_F: "t ∉ Fault ` F"
assume P:"s ∈ P"
from exec f_F t_notin_F have g: "s ∈ g"
by cases auto
with P have P': "s ∈ g ∩ P"
by blast
from exec P g have "Γ⊢⟨c,Normal s⟩ =n⇒ t"
by cases auto
from valid_c ctxt this P' t_notin_F
show "t ∈ Normal ` Q ∪ Abrupt ` A"
by (rule cnvalidD)
qed
next
case (CallRec P p Q A Specs Θ F)
have p: "(P,p,Q,A) ∈ Specs" by fact
have valid_body:
"∀(P,p,Q,A) ∈ Specs. p ∈ dom Γ ∧ (∀n. Γ,Θ ∪ Specs ⊨n:⇘/F⇙ P (the (Γ p)) Q,A)"
using CallRec.hyps by blast
show "Γ,Θ⊨n:⇘/F⇙ P Call p Q,A"
proof -
{
fix n
have "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A
⟹ ∀(P,p,Q,A) ∈Specs. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
proof (induct n)
case 0
show "∀(P,p,Q,A) ∈Specs. Γ⊨0:⇘/F⇙ P (Call p) Q,A"
by (fastforce elim!: execn_elim_cases simp add: nvalid_def)
next
case (Suc m)
have hyp: "∀(P, p, Q, A)∈Θ. Γ ⊨m:⇘/F⇙ P (Call p) Q,A
⟹ ∀(P,p,Q,A) ∈Specs. Γ⊨m:⇘/F⇙ P (Call p) Q,A" by fact
have "∀(P, p, Q, A)∈Θ. Γ ⊨Suc m:⇘/F⇙ P (Call p) Q,A" by fact
hence ctxt_m: "∀(P, p, Q, A)∈Θ. Γ ⊨m:⇘/F⇙ P (Call p) Q,A"
by (fastforce simp add: nvalid_def intro: execn_Suc)
hence valid_Proc:
"∀(P,p,Q,A) ∈Specs. Γ⊨m:⇘/F⇙ P (Call p) Q,A"
by (rule hyp)
let ?Θ'= "Θ ∪ Specs"
from valid_Proc ctxt_m
have "∀(P, p, Q, A)∈?Θ'. Γ ⊨m:⇘/F⇙ P (Call p) Q,A"
by fastforce
with valid_body
have valid_body_m:
"∀(P,p,Q,A) ∈Specs. ∀n. Γ ⊨m:⇘/F⇙ P (the (Γ p)) Q,A"
by (fastforce simp add: cnvalid_def)
show "∀(P,p,Q,A) ∈Specs. Γ ⊨Suc m:⇘/F⇙ P (Call p) Q,A"
proof (clarify)
fix P p Q A assume p: "(P,p,Q,A) ∈ Specs"
show "Γ ⊨Suc m:⇘/F⇙ P (Call p) Q,A"
proof (rule nvalidI)
fix s t
assume exec_call:
"Γ⊢⟨Call p,Normal s⟩ =Suc m⇒ t"
assume Pre: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
from exec_call
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases)
fix bdy m'
assume m: "Suc m = Suc m'"
assume bdy: "Γ p = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal s⟩ =m'⇒ t"
from Pre valid_body_m exec_body bdy m p t_notin_F
show ?thesis
by (fastforce simp add: nvalid_def)
next
assume "Γ p = None"
with valid_body p have False by auto
thus ?thesis ..
qed
qed
qed
qed
}
with p show ?thesis
by (fastforce simp add: cnvalid_def)
qed
next
case (DynCom P Θ F c Q A)
hence valid_c: "∀s∈P. (∀n. Γ,Θ⊨n:⇘/F⇙ P (c s) Q,A)" by auto
show "Γ,Θ⊨n:⇘/F⇙ P DynCom c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨DynCom c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_Fault: "t ∉ Fault ` F"
from exec show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases)
assume "Γ⊢⟨c s,Normal s⟩ =n⇒ t"
from cnvalidD [OF valid_c [rule_format, OF P] ctxt this P t_notin_Fault]
show ?thesis .
qed
qed
next
case (Throw Θ F A Q)
show "Γ,Θ ⊨n:⇘/F⇙ A Throw Q,A"
proof (rule cnvalidI)
fix s t
assume "Γ⊢⟨Throw,Normal s⟩ =n⇒ t" "s ∈ A"
then show "t ∈ Normal ` Q ∪ Abrupt ` A"
by cases simp
qed
next
case (Catch Θ F P c⇩1 Q R c⇩2 A)
have valid_c1: "⋀n. Γ,Θ ⊨n:⇘/F⇙ P c⇩1 Q,R" by fact
have valid_c2: "⋀n. Γ,Θ ⊨n:⇘/F⇙ R c⇩2 Q,A" by fact
show "Γ,Θ ⊨n:⇘/F⇙ P Catch c⇩1 c⇩2 Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨Catch c⇩1 c⇩2,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_Fault: "t ∉ Fault ` F"
from exec show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases)
fix s'
assume exec_c1: "Γ⊢⟨c⇩1,Normal s⟩ =n⇒ Abrupt s'"
assume exec_c2: "Γ⊢⟨c⇩2,Normal s'⟩ =n⇒ t"
from cnvalidD [OF valid_c1 ctxt exec_c1 P ]
have "Abrupt s' ∈ Abrupt ` R"
by auto
with cnvalidD [OF valid_c2 ctxt _ _ t_notin_Fault] exec_c2
show ?thesis
by fastforce
next
assume exec_c1: "Γ⊢⟨c⇩1,Normal s⟩ =n⇒ t"
assume notAbr: "¬ isAbr t"
from cnvalidD [OF valid_c1 ctxt exec_c1 P t_notin_Fault]
have "t ∈ Normal ` Q ∪ Abrupt ` R" .
with notAbr
show ?thesis
by auto
qed
qed
next
case (Conseq P Θ F c Q A)
hence adapt: "∀s ∈ P. (∃P' Q' A'. Γ,Θ ⊨n:⇘/F⇙ P' c Q',A' ∧
s ∈ P' ∧ Q' ⊆ Q ∧ A' ⊆ A)"
by blast
show "Γ,Θ ⊨n:⇘/F⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt:"∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof -
from P adapt obtain P' Q' A' Z where
spec: "Γ,Θ⊨n:⇘/F⇙ P' c Q',A'" and
P': "s ∈ P'" and strengthen: "Q' ⊆ Q ∧ A' ⊆ A"
by auto
from spec [rule_format] ctxt exec P' t_notin_F
have "t ∈ Normal ` Q' ∪ Abrupt ` A'"
by (rule cnvalidD)
with strengthen show ?thesis
by blast
qed
qed
next
case (Asm P p Q A Θ F)
have asm: "(P, p, Q, A) ∈ Θ" by fact
show "Γ,Θ ⊨n:⇘/F⇙ P (Call p) Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨Call p,Normal s⟩ =n⇒ t"
from asm ctxt have "Γ ⊨n:⇘/F⇙ P Call p Q,A" by auto
moreover
assume "s ∈ P" "t ∉ Fault ` F"
ultimately
show "t ∈ Normal ` Q ∪ Abrupt ` A"
using exec
by (auto simp add: nvalid_def)
qed
next
case ExFalso thus ?case by iprover
qed
theorem hoare_sound: "Γ,Θ⊢⇘/F⇙ P c Q,A ⟹ Γ,Θ⊨⇘/F⇙ P c Q,A"
by (iprover intro: cnvalid_to_cvalid hoare_cnvalid)
subsection ‹Completeness›
lemma MGT_valid:
"Γ⊨⇘/F⇙{s. s=Z ∧ Γ⊢⟨c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Normal t}, {t. Γ⊢⟨c,Normal Z⟩ ⇒ Abrupt t}"
proof (rule validI)
fix s t
assume "Γ⊢⟨c,Normal s⟩ ⇒ t"
"s ∈ {s. s = Z ∧ Γ⊢⟨c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}"
"t ∉ Fault ` F"
thus "t ∈ Normal ` {t. Γ⊢⟨c,Normal Z⟩ ⇒ Normal t} ∪
Abrupt ` {t. Γ⊢⟨c,Normal Z⟩ ⇒ Abrupt t}"
by (cases t) (auto simp add: final_notin_def)
qed
text ‹The consequence rule where the existential @{term Z} is instantiated
to @{term s}. Usefull in proof of ‹MGT_lemma›.›
lemma ConseqMGT:
assumes modif: "∀Z. Γ,Θ ⊢⇘/F⇙ (P' Z) c (Q' Z),(A' Z)"
assumes impl: "⋀s. s ∈ P ⟹ s ∈ P' s ∧ (∀t. t ∈ Q' s ⟶ t ∈ Q) ∧
(∀t. t ∈ A' s ⟶ t ∈ A)"
shows "Γ,Θ ⊢⇘/F⇙ P c Q,A"
using impl
by - (rule conseq [OF modif],blast)
lemma Seq_NoFaultStuckD1:
assumes noabort: "Γ⊢⟨Seq c1 c2,s⟩ ⇒∉({Stuck} ∪ Fault ` F)"
shows "Γ⊢⟨c1,s⟩ ⇒∉({Stuck} ∪ Fault ` F)"
proof (rule final_notinI)
fix t
assume exec_c1: "Γ⊢⟨c1,s⟩ ⇒ t"
show "t ∉ {Stuck} ∪ Fault ` F"
proof
assume "t ∈ {Stuck} ∪ Fault ` F"
moreover
{
assume "t = Stuck"
with exec_c1
have "Γ⊢⟨Seq c1 c2,s⟩ ⇒ Stuck"
by (auto intro: exec_Seq')
with noabort have False
by (auto simp add: final_notin_def)
hence False ..
}
moreover
{
assume "t ∈ Fault ` F"
then obtain f where
t: "t=Fault f" and f: "f ∈ F"
by auto
from t exec_c1
have "Γ⊢⟨Seq c1 c2,s⟩ ⇒ Fault f"
by (auto intro: exec_Seq')
with noabort f have False
by (auto simp add: final_notin_def)
hence False ..
}
ultimately show False by auto
qed
qed
lemma Seq_NoFaultStuckD2:
assumes noabort: "Γ⊢⟨Seq c1 c2,s⟩ ⇒∉({Stuck} ∪ Fault ` F)"
shows "∀t. Γ⊢⟨c1,s⟩ ⇒ t ⟶ t∉ ({Stuck} ∪ Fault ` F) ⟶
Γ⊢⟨c2,t⟩ ⇒∉({Stuck} ∪ Fault ` F)"
using noabort
by (auto simp add: final_notin_def intro: exec_Seq')
lemma MGT_implies_complete:
assumes MGT: "∀Z. Γ,{}⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Abrupt t}"
assumes valid: "Γ ⊨⇘/F⇙ P c Q,A"
shows "Γ,{} ⊢⇘/F⇙ P c Q,A"
using MGT
apply (rule ConseqMGT)
apply (insert valid)
apply (auto simp add: valid_def intro!: final_notinI)
done
text ‹Equipped only with the classic consequence rule @{thm "conseqPrePost"}
we can only derive this syntactically more involved version
of completeness. But semantically it is equivalent to the "real" one
(see below)›
lemma MGT_implies_complete':
assumes MGT: "∀Z. Γ,{}⊢⇘/F⇙
{s. s=Z ∧ Γ⊢⟨c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Abrupt t}"
assumes valid: "Γ ⊨⇘/F⇙ P c Q,A"
shows "Γ,{} ⊢⇘/F⇙ {s. s=Z ∧ s ∈ P} c {t. Z ∈ P ⟶ t ∈ Q},{t. Z ∈ P ⟶ t ∈ A}"
using MGT [rule_format, of Z]
apply (rule conseqPrePost)
apply (insert valid)
apply (fastforce simp add: valid_def final_notin_def)
apply (fastforce simp add: valid_def)
apply (fastforce simp add: valid_def)
done
text ‹Semantic equivalence of both kind of formulations›
lemma valid_involved_to_valid:
assumes valid:
"∀Z. Γ⊨⇘/F⇙ {s. s=Z ∧ s ∈ P} c {t. Z ∈ P ⟶ t ∈ Q},{t. Z ∈ P ⟶ t ∈ A}"
shows "Γ ⊨⇘/F⇙ P c Q,A"
using valid
apply (simp add: valid_def)
apply clarsimp
apply (erule_tac x="x" in allE)
apply (erule_tac x="Normal x" in allE)
apply (erule_tac x=t in allE)
apply fastforce
done
text ‹The sophisticated consequence rule allow us to do this
semantical transformation on the hoare-level, too.
The magic is, that it allow us to
choose the instance of @{term Z} under the assumption of an state @{term "s ∈ P"}›
lemma
assumes deriv:
"∀Z. Γ,{}⊢⇘/F⇙ {s. s=Z ∧ s ∈ P} c {t. Z ∈ P ⟶ t ∈ Q},{t. Z ∈ P ⟶ t ∈ A}"
shows "Γ,{} ⊢⇘/F⇙ P c Q,A"
apply (rule ConseqMGT [OF deriv])
apply auto
done
lemma valid_to_valid_involved:
"Γ ⊨⇘/F⇙ P c Q,A ⟹
Γ⊨⇘/F⇙ {s. s=Z ∧ s ∈ P} c {t. Z ∈ P ⟶ t ∈ Q},{t. Z ∈ P ⟶ t ∈ A}"
by (simp add: valid_def Collect_conv_if)
lemma
assumes deriv: "Γ,{} ⊢⇘/F⇙ P c Q,A"
shows "Γ,{}⊢⇘/F⇙ {s. s=Z ∧ s ∈ P} c {t. Z ∈ P ⟶ t ∈ Q},{t. Z ∈ P ⟶ t ∈ A}"
apply (rule conseqPrePost [OF deriv])
apply auto
done
lemma :
assumes state_indep_prop:"∀s ∈ P. R"
assumes to_show: "R ⟹ Γ,Θ⊢⇘/F⇙ P c Q,A"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A"
apply (rule Conseq)
apply (clarify)
apply (rule_tac x="P" in exI)
apply (rule_tac x="Q" in exI)
apply (rule_tac x="A" in exI)
using state_indep_prop to_show
by blast
lemma MGT_lemma:
assumes MGT_Calls:
"∀p∈dom Γ. ∀Z. Γ,Θ ⊢⇘/F⇙
{s. s=Z ∧ Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
(Call p)
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t}"
shows "⋀Z. Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Normal t},{t. Γ⊢⟨c,Normal Z⟩ ⇒ Abrupt t}"
proof (induct c)
case Skip
show "Γ,Θ⊢⇘/F⇙ {s. s = Z ∧ Γ⊢⟨Skip,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} Skip
{t. Γ⊢⟨Skip,Normal Z⟩ ⇒ Normal t},{t. Γ⊢⟨Skip,Normal Z⟩ ⇒ Abrupt t}"
by (rule hoarep.Skip [THEN conseqPre])
(auto elim: exec_elim_cases simp add: final_notin_def intro: exec.intros)
next
case (Basic f)
show "Γ,Θ⊢⇘/F⇙ {s. s = Z ∧ Γ⊢⟨Basic f,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} Basic f
{t. Γ⊢⟨Basic f,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Basic f,Normal Z⟩ ⇒ Abrupt t}"
by (rule hoarep.Basic [THEN conseqPre])
(auto elim: exec_elim_cases simp add: final_notin_def intro: exec.intros)
next
case (Spec r)
show "Γ,Θ⊢⇘/F⇙ {s. s = Z ∧ Γ⊢⟨Spec r,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} Spec r
{t. Γ⊢⟨Spec r,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Spec r,Normal Z⟩ ⇒ Abrupt t}"
apply (rule hoarep.Spec [THEN conseqPre])
apply (clarsimp simp add: final_notin_def)
apply (case_tac "∃t. (Z,t) ∈ r")
apply (auto elim: exec_elim_cases simp add: final_notin_def intro: exec.intros)
done
next
case (Seq c1 c2)
have hyp_c1: "∀Z. Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c1,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c1
{t. Γ⊢⟨c1,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c1,Normal Z⟩ ⇒ Abrupt t}"
using Seq.hyps by iprover
have hyp_c2: "∀Z. Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c2
{t. Γ⊢⟨c2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c2,Normal Z⟩ ⇒ Abrupt t}"
using Seq.hyps by iprover
from hyp_c1
have "Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨Seq c1 c2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c1
{t. Γ⊢⟨c1,Normal Z⟩ ⇒ Normal t ∧
Γ⊢⟨c2,Normal t⟩ ⇒∉({Stuck} ∪ Fault ` (-F))},
{t. Γ⊢⟨Seq c1 c2,Normal Z⟩ ⇒ Abrupt t}"
by (rule ConseqMGT)
(auto dest: Seq_NoFaultStuckD1 [simplified] Seq_NoFaultStuckD2 [simplified]
intro: exec.Seq)
thus "Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨Seq c1 c2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
Seq c1 c2
{t. Γ⊢⟨Seq c1 c2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Seq c1 c2,Normal Z⟩ ⇒ Abrupt t}"
proof (rule hoarep.Seq )
show "Γ,Θ⊢⇘/F⇙ {t. Γ⊢⟨c1,Normal Z⟩ ⇒ Normal t ∧
Γ⊢⟨c2,Normal t⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
c2
{t. Γ⊢⟨Seq c1 c2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Seq c1 c2,Normal Z⟩ ⇒ Abrupt t}"
proof (rule ConseqMGT [OF hyp_c2],safe)
fix r t
assume "Γ⊢⟨c1,Normal Z⟩ ⇒ Normal r" "Γ⊢⟨c2,Normal r⟩ ⇒ Normal t"
then show "Γ⊢⟨Seq c1 c2,Normal Z⟩ ⇒ Normal t"
by (iprover intro: exec.intros)
next
fix r t
assume "Γ⊢⟨c1,Normal Z⟩ ⇒ Normal r" "Γ⊢⟨c2,Normal r⟩ ⇒ Abrupt t"
then show "Γ⊢⟨Seq c1 c2,Normal Z⟩ ⇒ Abrupt t"
by (iprover intro: exec.intros)
qed
qed
next
case (Cond b c1 c2)
have "∀Z. Γ,Θ⊢⇘/F⇙{s. s=Z ∧ Γ⊢⟨c1,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c1
{t. Γ⊢⟨c1,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c1,Normal Z⟩ ⇒ Abrupt t}"
using Cond.hyps by iprover
hence "Γ,Θ⊢⇘/F⇙ ({s. s=Z ∧ Γ⊢⟨Cond b c1 c2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}∩b)
c1
{t. Γ⊢⟨Cond b c1 c2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Cond b c1 c2,Normal Z⟩ ⇒ Abrupt t}"
by (rule ConseqMGT)
(fastforce intro: exec.CondTrue simp add: final_notin_def)
moreover
have "∀Z. Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c2
{t. Γ⊢⟨c2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c2,Normal Z⟩ ⇒ Abrupt t}"
using Cond.hyps by iprover
hence "Γ,Θ⊢⇘/F⇙({s. s=Z ∧ Γ⊢⟨Cond b c1 c2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}∩-b)
c2
{t. Γ⊢⟨Cond b c1 c2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Cond b c1 c2,Normal Z⟩ ⇒ Abrupt t}"
by (rule ConseqMGT)
(fastforce intro: exec.CondFalse simp add: final_notin_def)
ultimately
show "Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨Cond b c1 c2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
Cond b c1 c2
{t. Γ⊢⟨Cond b c1 c2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Cond b c1 c2,Normal Z⟩ ⇒ Abrupt t}"
by (rule hoarep.Cond)
next
case (While b c)
let ?unroll = "({(s,t). s∈b ∧ Γ⊢⟨c,Normal s⟩ ⇒ Normal t})⇧*"
let ?P' = "λZ. {t. (Z,t)∈?unroll ∧
(∀e. (Z,e)∈?unroll ⟶ e∈b
⟶ Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F)) ∧
(∀u. Γ⊢⟨c,Normal e⟩ ⇒Abrupt u ⟶
Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt u))}"
let ?A' = "λZ. {t. Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt t}"
show "Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨While b c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
While b c
{t. Γ⊢⟨While b c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt t}"
proof (rule ConseqMGT [where ?P'="?P'"
and ?Q'="λZ. ?P' Z ∩ - b" and ?A'="?A'"])
show "∀Z. Γ,Θ⊢⇘/F⇙ (?P' Z) (While b c) (?P' Z ∩ - b),(?A' Z)"
proof (rule allI, rule hoarep.While)
fix Z
from While
have "∀Z. Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Abrupt t}" by iprover
then show "Γ,Θ⊢⇘/F⇙ (?P' Z ∩ b) c (?P' Z),(?A' Z)"
proof (rule ConseqMGT)
fix s
assume "s∈ {t. (Z, t) ∈ ?unroll ∧
(∀e. (Z,e)∈?unroll ⟶ e∈b
⟶ Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F)) ∧
(∀u. Γ⊢⟨c,Normal e⟩ ⇒Abrupt u ⟶
Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt u))}
∩ b"
then obtain
Z_s_unroll: "(Z,s) ∈ ?unroll" and
noabort:"∀e. (Z,e)∈?unroll ⟶ e∈b
⟶ Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F)) ∧
(∀u. Γ⊢⟨c,Normal e⟩ ⇒Abrupt u ⟶
Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt u)" and
s_in_b: "s∈b"
by blast
show "s ∈ {t. t = s ∧ Γ⊢⟨c,Normal t⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} ∧
(∀t. t ∈ {t. Γ⊢⟨c,Normal s⟩ ⇒ Normal t} ⟶
t ∈ {t. (Z, t) ∈ ?unroll ∧
(∀e. (Z,e)∈?unroll ⟶ e∈b
⟶ Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F)) ∧
(∀u. Γ⊢⟨c,Normal e⟩ ⇒Abrupt u ⟶
Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt u))}) ∧
(∀t. t ∈ {t. Γ⊢⟨c,Normal s⟩ ⇒ Abrupt t} ⟶
t ∈ {t. Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt t})"
(is "?C1 ∧ ?C2 ∧ ?C3")
proof (intro conjI)
from Z_s_unroll noabort s_in_b show ?C1 by blast
next
{
fix t
assume s_t: "Γ⊢⟨c,Normal s⟩ ⇒ Normal t"
moreover
from Z_s_unroll s_t s_in_b
have "(Z, t) ∈ ?unroll"
by (blast intro: rtrancl_into_rtrancl)
moreover note noabort
ultimately
have "(Z, t) ∈ ?unroll ∧
(∀e. (Z,e)∈?unroll ⟶ e∈b
⟶ Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F)) ∧
(∀u. Γ⊢⟨c,Normal e⟩ ⇒Abrupt u ⟶
Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt u))"
by iprover
}
then show ?C2 by blast
next
{
fix t
assume s_t: "Γ⊢⟨c,Normal s⟩ ⇒ Abrupt t"
from Z_s_unroll noabort s_t s_in_b
have "Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt t"
by blast
} thus ?C3 by simp
qed
qed
qed
next
fix s
assume P: "s ∈ {s. s=Z ∧ Γ⊢⟨While b c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}"
hence WhileNoFault: "Γ⊢⟨While b c,Normal Z⟩ ⇒∉({Stuck} ∪ Fault ` (-F))"
by auto
show "s ∈ ?P' s ∧
(∀t. t∈(?P' s ∩ - b)⟶
t∈{t. Γ⊢⟨While b c,Normal Z⟩ ⇒ Normal t})∧
(∀t. t∈?A' s ⟶ t∈?A' Z)"
proof (intro conjI)
{
fix e
assume "(Z,e) ∈ ?unroll" "e ∈ b"
from this WhileNoFault
have "Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F)) ∧
(∀u. Γ⊢⟨c,Normal e⟩ ⇒Abrupt u ⟶
Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt u)" (is "?Prop Z e")
proof (induct rule: converse_rtrancl_induct [consumes 1])
assume e_in_b: "e ∈ b"
assume WhileNoFault: "Γ⊢⟨While b c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F))"
with e_in_b WhileNoFault
have cNoFault: "Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F))"
by (auto simp add: final_notin_def intro: exec.intros)
moreover
{
fix u assume "Γ⊢⟨c,Normal e⟩ ⇒ Abrupt u"
with e_in_b have "Γ⊢⟨While b c,Normal e⟩ ⇒ Abrupt u"
by (blast intro: exec.intros)
}
ultimately
show "?Prop e e"
by iprover
next
fix Z r
assume e_in_b: "e∈b"
assume WhileNoFault: "Γ⊢⟨While b c,Normal Z⟩ ⇒∉({Stuck} ∪ Fault ` (-F))"
assume hyp: "⟦e∈b;Γ⊢⟨While b c,Normal r⟩ ⇒∉({Stuck} ∪ Fault ` (-F))⟧
⟹ ?Prop r e"
assume Z_r:
"(Z, r) ∈ {(Z, r). Z ∈ b ∧ Γ⊢⟨c,Normal Z⟩ ⇒ Normal r}"
with WhileNoFault
have "Γ⊢⟨While b c,Normal r⟩ ⇒∉({Stuck} ∪ Fault ` (-F))"
by (auto simp add: final_notin_def intro: exec.intros)
from hyp [OF e_in_b this] obtain
cNoFault: "Γ⊢⟨c,Normal e⟩ ⇒∉({Stuck} ∪ Fault ` (-F))" and
Abrupt_r: "∀u. Γ⊢⟨c,Normal e⟩ ⇒ Abrupt u ⟶
Γ⊢⟨While b c,Normal r⟩ ⇒ Abrupt u"
by simp
{
fix u assume "Γ⊢⟨c,Normal e⟩ ⇒ Abrupt u"
with Abrupt_r have "Γ⊢⟨While b c,Normal r⟩ ⇒ Abrupt u" by simp
moreover from Z_r obtain
"Z ∈ b" "Γ⊢⟨c,Normal Z⟩ ⇒ Normal r"
by simp
ultimately have "Γ⊢⟨While b c,Normal Z⟩ ⇒ Abrupt u"
by (blast intro: exec.intros)
}
with cNoFault show "?Prop Z e"
by iprover
qed
}
with P show "s ∈ ?P' s"
by blast
next
{
fix t
assume "termination": "t ∉ b"
assume "(Z, t) ∈ ?unroll"
hence "Γ⊢⟨While b c,Normal Z⟩ ⇒ Normal t"
proof (induct rule: converse_rtrancl_induct [consumes 1])
from "termination"
show "Γ⊢⟨While b c,Normal t⟩ ⇒ Normal t"
by (blast intro: exec.WhileFalse)
next
fix Z r
assume first_body:
"(Z, r) ∈ {(s, t). s ∈ b ∧ Γ⊢⟨c,Normal s⟩ ⇒ Normal t}"
assume "(r, t) ∈ ?unroll"
assume rest_loop: "Γ⊢⟨While b c, Normal r⟩ ⇒ Normal t"
show "Γ⊢⟨While b c,Normal Z⟩ ⇒ Normal t"
proof -
from first_body obtain
"Z ∈ b" "Γ⊢⟨c,Normal Z⟩ ⇒ Normal r"
by fast
moreover
from rest_loop have
"Γ⊢⟨While b c,Normal r⟩ ⇒ Normal t"
by fast
ultimately show "Γ⊢⟨While b c,Normal Z⟩ ⇒ Normal t"
by (rule exec.WhileTrue)
qed
qed
}
with P
show "(∀t. t∈(?P' s ∩ - b)
⟶t∈{t. Γ⊢⟨While b c,Normal Z⟩ ⇒ Normal t})"
by blast
next
from P show "∀t. t∈?A' s ⟶ t∈?A' Z" by simp
qed
qed
next
case (Call p)
let ?P = "{s. s=Z ∧ Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}"
from noStuck_Call have "∀s ∈ ?P. p ∈ dom Γ"
by (fastforce simp add: final_notin_def )
then show "Γ,Θ⊢⇘/F⇙ ?P (Call p)
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t}"
proof (rule conseq_extract_state_indep_prop)
assume p_definied: "p ∈ dom Γ"
with MGT_Calls show
"Γ,Θ⊢⇘/F⇙{s. s=Z ∧
Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
(Call p)
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t}"
by (auto)
qed
next
case (DynCom c)
have hyp:
"⋀s'. ∀Z. Γ,Θ⊢⇘/F⇙{s. s = Z ∧ Γ⊢⟨c s',Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c s'
{t. Γ⊢⟨c s',Normal Z⟩ ⇒ Normal t},{t. Γ⊢⟨c s',Normal Z⟩ ⇒ Abrupt t}"
using DynCom by simp
have hyp':
"Γ,Θ⊢⇘/F⇙{s. s = Z ∧ Γ⊢⟨DynCom c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c Z
{t. Γ⊢⟨DynCom c,Normal Z⟩ ⇒ Normal t},{t. Γ⊢⟨DynCom c,Normal Z⟩ ⇒ Abrupt t}"
by (rule ConseqMGT [OF hyp])
(fastforce simp add: final_notin_def intro: exec.intros)
show "Γ,Θ⊢⇘/F⇙{s. s = Z ∧ Γ⊢⟨DynCom c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
DynCom c
{t. Γ⊢⟨DynCom c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨DynCom c,Normal Z⟩ ⇒ Abrupt t}"
apply (rule hoarep.DynCom)
apply (clarsimp)
apply (rule hyp' [simplified])
done
next
case (Guard f g c)
have hyp_c: "∀Z. Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c,Normal Z⟩ ⇒ Abrupt t}"
using Guard by iprover
show ?case
proof (cases "f ∈ F")
case True
from hyp_c
have "Γ,Θ⊢⇘/F ⇙(g ∩ {s. s = Z ∧
Γ⊢⟨Guard f g c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (- F))})
c
{t. Γ⊢⟨Guard f g c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Guard f g c,Normal Z⟩ ⇒ Abrupt t}"
apply (rule ConseqMGT)
apply (insert True)
apply (auto simp add: final_notin_def intro: exec.intros)
done
from True this
show ?thesis
by (rule conseqPre [OF Guarantee]) auto
next
case False
from hyp_c
have "Γ,Θ⊢⇘/F⇙
(g ∩ {s. s=Z ∧ Γ⊢⟨Guard f g c,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))})
c
{t. Γ⊢⟨Guard f g c,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Guard f g c,Normal Z⟩ ⇒ Abrupt t}"
apply (rule ConseqMGT)
apply clarify
apply (frule Guard_noFaultStuckD [OF _ False])
apply (auto simp add: final_notin_def intro: exec.intros)
done
then show ?thesis
apply (rule conseqPre [OF hoarep.Guard])
apply clarify
apply (frule Guard_noFaultStuckD [OF _ False])
apply auto
done
qed
next
case Throw
show "Γ,Θ⊢⇘/F⇙ {s. s = Z ∧ Γ⊢⟨Throw,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} Throw
{t. Γ⊢⟨Throw,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Throw,Normal Z⟩ ⇒ Abrupt t}"
by (rule conseqPre [OF hoarep.Throw]) (blast intro: exec.intros)
next
case (Catch c⇩1 c⇩2)
have "∀Z. Γ,Θ⊢⇘/F⇙ {s. s = Z ∧ Γ⊢⟨c⇩1,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c⇩1
{t. Γ⊢⟨c⇩1,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c⇩1,Normal Z⟩ ⇒ Abrupt t}"
using Catch.hyps by iprover
hence "Γ,Θ⊢⇘/F⇙ {s. s = Z ∧ Γ⊢⟨Catch c⇩1 c⇩2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c⇩1
{t. Γ⊢⟨Catch c⇩1 c⇩2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c⇩1,Normal Z⟩ ⇒ Abrupt t ∧
Γ⊢⟨Catch c⇩1 c⇩2,Normal Z⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}"
by (rule ConseqMGT)
(fastforce intro: exec.intros simp add: final_notin_def)
moreover
have "∀Z. Γ,Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨c⇩2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))} c⇩2
{t. Γ⊢⟨c⇩2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨c⇩2,Normal Z⟩ ⇒ Abrupt t}"
using Catch.hyps by iprover
hence "Γ,Θ⊢⇘/F⇙{s. Γ⊢⟨c⇩1,Normal Z⟩ ⇒Abrupt s ∧
Γ⊢⟨Catch c⇩1 c⇩2,Normal Z⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
c⇩2
{t. Γ⊢⟨Catch c⇩1 c⇩2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Catch c⇩1 c⇩2,Normal Z⟩ ⇒ Abrupt t}"
by (rule ConseqMGT)
(fastforce intro: exec.intros simp add: final_notin_def)
ultimately
show "Γ,Θ⊢⇘/F⇙ {s. s = Z ∧ Γ⊢⟨Catch c⇩1 c⇩2,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
Catch c⇩1 c⇩2
{t. Γ⊢⟨Catch c⇩1 c⇩2,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Catch c⇩1 c⇩2,Normal Z⟩ ⇒ Abrupt t}"
by (rule hoarep.Catch)
qed
lemma MGT_Calls:
"∀p∈dom Γ. ∀Z.
Γ,{}⊢⇘/F⇙{s. s=Z ∧ Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
(Call p)
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t}"
proof -
{
fix p Z
assume defined: "p ∈ dom Γ"
have
"Γ,(⋃p∈dom Γ. ⋃Z.
{({s. s=Z ∧
Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))},
p,
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t})})
⊢⇘/F⇙{s. s = Z ∧ Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
(the (Γ p))
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t}"
(is "Γ,?Θ ⊢⇘/F⇙ (?Pre p Z) (the (Γ p)) (?Post p Z),(?Abr p Z)")
proof -
have MGT_Calls:
"∀p∈dom Γ. ∀Z. Γ,?Θ ⊢⇘/F⇙
{s. s=Z ∧ Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}
(Call p)
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t}"
by (intro ballI allI, rule HoarePartialDef.Asm,auto)
have "∀Z. Γ,?Θ⊢⇘/F⇙ {s. s=Z ∧ Γ⊢⟨the (Γ p) ,Normal s⟩ ⇒∉({Stuck} ∪ Fault`(-F))}
(the (Γ p))
{t. Γ⊢⟨the (Γ p),Normal Z⟩ ⇒ Normal t},
{t. Γ⊢⟨the (Γ p),Normal Z⟩ ⇒ Abrupt t}"
by (iprover intro: MGT_lemma [OF MGT_Calls])
thus "Γ,?Θ⊢⇘/F⇙ (?Pre p Z) (the (Γ p)) (?Post p Z),(?Abr p Z)"
apply (rule ConseqMGT)
apply (clarify,safe)
proof -
assume "Γ⊢⟨Call p,Normal Z⟩ ⇒∉({Stuck} ∪ Fault ` (-F))"
with defined show "Γ⊢⟨the (Γ p),Normal Z⟩ ⇒∉({Stuck} ∪ Fault ` (-F))"
by (fastforce simp add: final_notin_def
intro: exec.intros)
next
fix t
assume "Γ⊢⟨the (Γ p),Normal Z⟩ ⇒ Normal t"
with defined
show "Γ⊢⟨Call p,Normal Z⟩ ⇒Normal t"
by (auto intro: exec.Call)
next
fix t
assume "Γ⊢⟨the (Γ p),Normal Z⟩ ⇒ Abrupt t"
with defined
show "Γ⊢⟨Call p,Normal Z⟩ ⇒Abrupt t"
by (auto intro: exec.Call)
qed
qed
}
then show ?thesis
apply -
apply (intro ballI allI)
apply (rule CallRec' [where Procs="dom Γ" and
P="λp Z. {s. s=Z ∧
Γ⊢⟨Call p,Normal s⟩ ⇒∉({Stuck} ∪ Fault ` (-F))}"and
Q="λp Z.
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Normal t}" and
A="λp Z.
{t. Γ⊢⟨Call p,Normal Z⟩ ⇒ Abrupt t}"] )
apply simp+
done
qed
theorem hoare_complete: "Γ⊨⇘/F⇙ P c Q,A ⟹ Γ,{}⊢⇘/F⇙ P c Q,A"
by (iprover intro: MGT_implies_complete MGT_lemma [OF MGT_Calls])
lemma hoare_complete':
assumes cvalid: "∀n. Γ,Θ⊨n:⇘/F⇙ P c Q,A"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A"
proof (cases "Γ⊨⇘/F⇙ P c Q,A")
case True
hence "Γ,{}⊢⇘/F⇙ P c Q,A"
by (rule hoare_complete)
thus "Γ,Θ⊢⇘/F ⇙P c Q,A"
by (rule hoare_augment_context) simp
next
case False
with cvalid
show ?thesis
by (rule ExFalso)
qed
lemma hoare_strip_Γ:
assumes deriv: "Γ,{}⊢⇘/F⇙ P p Q,A"
assumes F': "F' ⊆ -F"
shows "strip F' Γ,{}⊢⇘/F⇙ P p Q,A"
proof (rule hoare_complete)
from hoare_sound [OF deriv] have "Γ⊨⇘/F⇙ P p Q,A"
by (simp add: cvalid_def)
from this F'
show "strip F' Γ⊨⇘/F⇙ P p Q,A"
by (rule valid_to_valid_strip)
qed
subsection ‹And Now: Some Useful Rules›
subsubsection ‹Consequence›
lemma LiberalConseq_sound:
fixes F::"'f set"
assumes cons: "∀s ∈ P. ∀(t::('s,'f) xstate). ∃P' Q' A'. (∀n. Γ,Θ⊨n:⇘/F⇙ P' c Q',A') ∧
((s ∈ P' ⟶ t ∈ Normal ` Q' ∪ Abrupt ` A')
⟶ t ∈ Normal ` Q ∪ Abrupt ` A)"
shows "Γ,Θ⊨n:⇘/F⇙ P c Q,A "
proof (rule cnvalidI)
fix s t
assume ctxt:"∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof -
from P cons obtain P' Q' A' where
spec: "∀n. Γ,Θ⊨n:⇘/F⇙ P' c Q',A'" and
adapt: "(s ∈ P' ⟶ t ∈ Normal ` Q' ∪ Abrupt ` A')
⟶ t ∈ Normal ` Q ∪ Abrupt ` A"
apply -
apply (drule (1) bspec)
apply (erule_tac x=t in allE)
apply (elim exE conjE)
apply iprover
done
from exec spec ctxt t_notin_F
have "s ∈ P' ⟶ t ∈ Normal ` Q' ∪ Abrupt ` A'"
by (simp add: cnvalid_def nvalid_def)
with adapt show ?thesis
by simp
qed
qed
lemma LiberalConseq:
fixes F:: "'f set"
assumes cons: "∀s ∈ P. ∀(t::('s,'f) xstate). ∃P' Q' A'. Γ,Θ⊢⇘/F⇙ P' c Q',A' ∧
((s ∈ P' ⟶ t ∈ Normal ` Q' ∪ Abrupt ` A')
⟶ t ∈ Normal ` Q ∪ Abrupt ` A)"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A "
apply (rule hoare_complete')
apply (rule allI)
apply (rule LiberalConseq_sound)
using cons
apply (clarify)
apply (drule (1) bspec)
apply (erule_tac x=t in allE)
apply clarify
apply (rule_tac x=P' in exI)
apply (rule_tac x=Q' in exI)
apply (rule_tac x=A' in exI)
apply (rule conjI)
apply (blast intro: hoare_cnvalid)
apply assumption
done
lemma "∀s ∈ P. ∃P' Q' A'. Γ,Θ⊢⇘/F⇙ P' c Q',A' ∧ s ∈ P' ∧ Q' ⊆ Q ∧ A' ⊆ A
⟹ Γ,Θ⊢⇘/F⇙ P c Q,A"
apply (rule LiberalConseq)
apply (rule ballI)
apply (drule (1) bspec)
apply clarify
apply (rule_tac x=P' in exI)
apply (rule_tac x=Q' in exI)
apply (rule_tac x=A' in exI)
apply auto
done
lemma
fixes F:: "'f set"
assumes cons: "∀s ∈ P. ∃P' Q' A'. Γ,Θ⊢⇘/F⇙ P' c Q',A' ∧
(∀(t::('s,'f) xstate). (s ∈ P' ⟶ t ∈ Normal ` Q' ∪ Abrupt ` A')
⟶ t ∈ Normal ` Q ∪ Abrupt ` A)"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A "
apply (rule Conseq)
apply (rule ballI)
apply (insert cons)
apply (drule (1) bspec)
apply clarify
apply (rule_tac x=P' in exI)
apply (rule_tac x=Q' in exI)
apply (rule_tac x=A' in exI)
apply (rule conjI)
apply assumption
oops
lemma LiberalConseq':
fixes F:: "'f set"
assumes cons: "∀s ∈ P. ∃P' Q' A'. Γ,Θ⊢⇘/F⇙ P' c Q',A' ∧
(∀(t::('s,'f) xstate). (s ∈ P' ⟶ t ∈ Normal ` Q' ∪ Abrupt ` A')
⟶ t ∈ Normal ` Q ∪ Abrupt ` A)"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A "
apply (rule LiberalConseq)
apply (rule ballI)
apply (rule allI)
apply (insert cons)
apply (drule (1) bspec)
apply clarify
apply (rule_tac x=P' in exI)
apply (rule_tac x=Q' in exI)
apply (rule_tac x=A' in exI)
apply iprover
done
lemma LiberalConseq'':
fixes F:: "'f set"
assumes spec: "∀Z. Γ,Θ⊢⇘/F⇙ (P' Z) c (Q' Z),(A' Z)"
assumes cons: "∀s (t::('s,'f) xstate).
(∀Z. s ∈ P' Z ⟶ t ∈ Normal ` Q' Z ∪ Abrupt ` A' Z)
⟶ (s ∈ P ⟶ t ∈ Normal ` Q ∪ Abrupt ` A)"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A "
apply (rule LiberalConseq)
apply (rule ballI)
apply (rule allI)
apply (insert cons)
apply (erule_tac x=s in allE)
apply (erule_tac x=t in allE)
apply (case_tac "t ∈ Normal ` Q ∪ Abrupt ` A")
apply (insert spec)
apply iprover
apply auto
done
primrec procs:: "('s,'p,'f) com ⇒ 'p set"
where
"procs Skip = {}" |
"procs (Basic f) = {}" |
"procs (Seq c⇩1 c⇩2) = (procs c⇩1 ∪ procs c⇩2)" |
"procs (Cond b c⇩1 c⇩2) = (procs c⇩1 ∪ procs c⇩2)" |
"procs (While b c) = procs c" |
"procs (Call p) = {p}" |
"procs (DynCom c) = (⋃s. procs (c s))" |
"procs (Guard f g c) = procs c" |
"procs Throw = {}" |
"procs (Catch c⇩1 c⇩2) = (procs c⇩1 ∪ procs c⇩2)"
primrec noSpec:: "('s,'p,'f) com ⇒ bool"
where
"noSpec Skip = True" |
"noSpec (Basic f) = True" |
"noSpec (Spec r) = False" |
"noSpec (Seq c⇩1 c⇩2) = (noSpec c⇩1 ∧ noSpec c⇩2)" |
"noSpec (Cond b c⇩1 c⇩2) = (noSpec c⇩1 ∧ noSpec c⇩2)" |
"noSpec (While b c) = noSpec c" |
"noSpec (Call p) = True" |
"noSpec (DynCom c) = (∀s. noSpec (c s))" |
"noSpec (Guard f g c) = noSpec c" |
"noSpec Throw = True" |
"noSpec (Catch c⇩1 c⇩2) = (noSpec c⇩1 ∧ noSpec c⇩2)"
lemma exec_noSpec_no_Stuck:
assumes exec: "Γ⊢⟨c,s⟩ ⇒ t"
assumes noSpec_c: "noSpec c"
assumes noSpec_Γ: "∀p ∈ dom Γ. noSpec (the (Γ p))"
assumes procs_subset: "procs c ⊆ dom Γ"
assumes procs_subset_Γ: "∀p ∈ dom Γ. procs (the (Γ p)) ⊆ dom Γ"
assumes s_no_Stuck: "s≠Stuck"
shows "t≠Stuck"
using exec noSpec_c procs_subset s_no_Stuck proof induct
case (Call p bdy s t) with noSpec_Γ procs_subset_Γ show ?case
by (auto dest!: bspec [of _ _ p])
next
case (DynCom c s t) then show ?case
by auto blast
qed auto
lemma execn_noSpec_no_Stuck:
assumes exec: "Γ⊢⟨c,s⟩ =n⇒ t"
assumes noSpec_c: "noSpec c"
assumes noSpec_Γ: "∀p ∈ dom Γ. noSpec (the (Γ p))"
assumes procs_subset: "procs c ⊆ dom Γ"
assumes procs_subset_Γ: "∀p ∈ dom Γ. procs (the (Γ p)) ⊆ dom Γ"
assumes s_no_Stuck: "s≠Stuck"
shows "t≠Stuck"
using exec noSpec_c procs_subset s_no_Stuck proof induct
case (Call p bdy n s t) with noSpec_Γ procs_subset_Γ show ?case
by (auto dest!: bspec [of _ _ p])
next
case (DynCom c s t) then show ?case
by auto blast
qed auto
lemma LiberalConseq_noguards_nothrows_sound:
assumes spec: "∀Z. ∀n. Γ,Θ⊨n:⇘/F⇙ (P' Z) c (Q' Z),(A' Z)"
assumes cons: "∀s t. (∀Z. s ∈ P' Z ⟶ t ∈ Q' Z )
⟶ (s ∈ P ⟶ t ∈ Q )"
assumes noguards_c: "noguards c"
assumes noguards_Γ: "∀p ∈ dom Γ. noguards (the (Γ p))"
assumes nothrows_c: "nothrows c"
assumes nothrows_Γ: "∀p ∈ dom Γ. nothrows (the (Γ p))"
assumes noSpec_c: "noSpec c"
assumes noSpec_Γ: "∀p ∈ dom Γ. noSpec (the (Γ p))"
assumes procs_subset: "procs c ⊆ dom Γ"
assumes procs_subset_Γ: "∀p ∈ dom Γ. procs (the (Γ p)) ⊆ dom Γ"
shows "Γ,Θ⊨n:⇘/F⇙ P c Q,A "
proof (rule cnvalidI)
fix s t
assume ctxt:"∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof -
from execn_noguards_no_Fault [OF exec noguards_c noguards_Γ]
execn_nothrows_no_Abrupt [OF exec nothrows_c nothrows_Γ ]
execn_noSpec_no_Stuck [OF exec
noSpec_c noSpec_Γ procs_subset
procs_subset_Γ]
obtain t' where t: "t=Normal t'"
by (cases t) auto
with exec spec ctxt
have "(∀Z. s ∈ P' Z ⟶ t' ∈ Q' Z)"
by (unfold cnvalid_def nvalid_def) blast
with cons P t show ?thesis
by simp
qed
qed
lemma LiberalConseq_noguards_nothrows:
assumes spec: "∀Z. Γ,Θ⊢⇘/F⇙ (P' Z) c (Q' Z),(A' Z)"
assumes cons: "∀s t. (∀Z. s ∈ P' Z ⟶ t ∈ Q' Z )
⟶ (s ∈ P ⟶ t ∈ Q )"
assumes noguards_c: "noguards c"
assumes noguards_Γ: "∀p ∈ dom Γ. noguards (the (Γ p))"
assumes nothrows_c: "nothrows c"
assumes nothrows_Γ: "∀p ∈ dom Γ. nothrows (the (Γ p))"
assumes noSpec_c: "noSpec c"
assumes noSpec_Γ: "∀p ∈ dom Γ. noSpec (the (Γ p))"
assumes procs_subset: "procs c ⊆ dom Γ"
assumes procs_subset_Γ: "∀p ∈ dom Γ. procs (the (Γ p)) ⊆ dom Γ"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A "
apply (rule hoare_complete')
apply (rule allI)
apply (rule LiberalConseq_noguards_nothrows_sound
[OF _ cons noguards_c noguards_Γ nothrows_c nothrows_Γ
noSpec_c noSpec_Γ
procs_subset procs_subset_Γ])
apply (insert spec)
apply (intro allI)
apply (erule_tac x=Z in allE)
by (rule hoare_cnvalid)
lemma
assumes spec: "∀Z. Γ,Θ⊢⇘/F⇙{s. s=fst Z ∧ P s (snd Z)} c {t. Q (fst Z) (snd Z) t},{}"
assumes noguards_c: "noguards c"
assumes noguards_Γ: "∀p ∈ dom Γ. noguards (the (Γ p))"
assumes nothrows_c: "nothrows c"
assumes nothrows_Γ: "∀p ∈ dom Γ. nothrows (the (Γ p))"
assumes noSpec_c: "noSpec c"
assumes noSpec_Γ: "∀p ∈ dom Γ. noSpec (the (Γ p))"
assumes procs_subset: "procs c ⊆ dom Γ"
assumes procs_subset_Γ: "∀p ∈ dom Γ. procs (the (Γ p)) ⊆ dom Γ"
shows "∀σ. Γ,Θ⊢⇘/F⇙{s. s=σ} c {t. ∀l. P σ l ⟶ Q σ l t},{}"
apply (rule allI)
apply (rule LiberalConseq_noguards_nothrows
[OF spec _ noguards_c noguards_Γ nothrows_c nothrows_Γ
noSpec_c noSpec_Γ
procs_subset procs_subset_Γ])
apply auto
done
subsubsection ‹Modify Return›
lemma Proc_exnModifyReturn_sound:
assumes valid_call: "∀n. Γ,Θ ⊨n:⇘/F⇙ P call_exn init p return' result_exn c Q,A"
assumes valid_modif:
"∀σ. ∀n. Γ,Θ⊨n:⇘/UNIV⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ result_exn (return' s t) t = result_exn (return s t) t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (call_exn init p return result_exn c) Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
then have ctxt': "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/UNIV⇙ P (Call p) Q,A"
by (auto intro: nvalid_augment_Faults)
assume exec: "Γ⊢⟨call_exn init p return result_exn c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
from exec
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases rule: execn_call_exn_Normal_elim)
fix bdy m t'
assume bdy: "Γ p = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Normal t'"
assume exec_c: "Γ⊢⟨c s t',Normal (return s t')⟩ =Suc m⇒ t"
assume n: "n = Suc m"
from exec_body n bdy
have "Γ⊢⟨Call p,Normal (init s)⟩ =n⇒ Normal t'"
by (auto simp add: intro: execn.Call)
from cnvalidD [OF valid_modif [rule_format, of n "init s"] ctxt' this] P
have "t' ∈ Modif (init s)"
by auto
with ret_modif have "Normal (return' s t') =
Normal (return s t')"
by simp
with exec_body exec_c bdy n
have "Γ⊢⟨call_exn init p return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exn)
from cnvalidD [OF valid_call [rule_format] ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m t'
assume bdy: "Γ p = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Abrupt t'"
assume n: "n = Suc m"
assume t: "t = Abrupt (result_exn (return s t') t')"
also from exec_body n bdy
have "Γ⊢⟨Call p,Normal (init s)⟩ =n⇒ Abrupt t'"
by (auto simp add: intro: execn.intros)
from cnvalidD [OF valid_modif [rule_format, of n "init s"] ctxt' this] P
have "t' ∈ ModifAbr (init s)"
by auto
with ret_modifAbr have "Abrupt (result_exn (return s t') t') = Abrupt (result_exn (return' s t') t')"
by simp
finally have "t = Abrupt (result_exn (return' s t') t')" .
with exec_body bdy n
have "Γ⊢⟨call_exn init p return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnAbrupt)
from cnvalidD [OF valid_call [rule_format] ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m f
assume bdy: "Γ p = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Fault f" "n = Suc m"
"t = Fault f"
with bdy have "Γ⊢⟨call_exn init p return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnFault)
from valid_call [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
fix bdy m
assume bdy: "Γ p = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Stuck" "n = Suc m"
"t = Stuck"
with bdy have "Γ⊢⟨call_exn init p return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnStuck)
from valid_call [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
fix m
assume "Γ p = None"
and "n = Suc m" "t = Stuck"
then have "Γ⊢⟨call_exn init p return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnUndefined)
from valid_call [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
qed
qed
lemma ProcModifyReturn_sound:
assumes valid_call: "∀n. Γ,Θ ⊨n:⇘/F⇙ P call init p return' c Q,A"
assumes valid_modif:
"∀σ. ∀n. Γ,Θ⊨n:⇘/UNIV⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ return' s t = return s t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (call init p return c) Q,A"
using valid_call valid_modif ret_modif ret_modifAbr
unfolding call_call_exn
by (rule Proc_exnModifyReturn_sound)
lemma Proc_exnModifyReturn:
assumes spec: "Γ,Θ⊢⇘/F⇙ P (call_exn init p return' result_exn c) Q,A"
assumes result_conform:
"∀s t. t ∈ Modif (init s) ⟶ (return' s t) = (return s t)"
assumes return_conform:
"∀s t. t ∈ ModifAbr (init s)
⟶ (result_exn (return' s t) t) = (result_exn (return s t) t)"
assumes modifies_spec:
"∀σ. Γ,Θ⊢⇘/UNIV⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (call_exn init p return result_exn c) Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule Proc_exnModifyReturn_sound
[where Modif=Modif and ModifAbr=ModifAbr,
OF _ _ result_conform return_conform] )
using spec
apply (blast intro: hoare_cnvalid)
using modifies_spec
apply (blast intro: hoare_cnvalid)
done
lemma ProcModifyReturn:
assumes spec: "Γ,Θ⊢⇘/F⇙ P (call init p return' c) Q,A"
assumes result_conform:
"∀s t. t ∈ Modif (init s) ⟶ (return' s t) = (return s t)"
assumes return_conform:
"∀s t. t ∈ ModifAbr (init s)
⟶ (return' s t) = (return s t)"
assumes modifies_spec:
"∀σ. Γ,Θ⊢⇘/UNIV⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (call init p return c) Q,A"
using spec result_conform return_conform modifies_spec
unfolding call_call_exn
by (rule Proc_exnModifyReturn)
lemma Proc_exnModifyReturnSameFaults_sound:
assumes valid_call: "∀n. Γ,Θ ⊨n:⇘/F⇙ P call_exn init p return' result_exn c Q,A"
assumes valid_modif:
"∀σ. ∀n. Γ,Θ⊨n:⇘/F⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ result_exn (return' s t) t = result_exn (return s t) t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (call_exn init p return result_exn c) Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨call_exn init p return result_exn c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
from exec
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases rule: execn_call_exn_Normal_elim)
fix bdy m t'
assume bdy: "Γ p = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Normal t'"
assume exec_c: "Γ⊢⟨c s t',Normal (return s t')⟩ =Suc m⇒ t"
assume n: "n = Suc m"
from exec_body n bdy
have "Γ⊢⟨Call p,Normal (init s)⟩ =n⇒ Normal t'"
by (auto simp add: intro: execn.intros)
from cnvalidD [OF valid_modif [rule_format, of n "init s"] ctxt this] P
have "t' ∈ Modif (init s)"
by auto
with ret_modif have "Normal (return' s t') =
Normal (return s t')"
by simp
with exec_body exec_c bdy n
have "Γ⊢⟨call_exn init p return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exn)
from cnvalidD [OF valid_call [rule_format] ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m t'
assume bdy: "Γ p = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Abrupt t'"
assume n: "n = Suc m"
assume t: "t = Abrupt (result_exn (return s t') t')"
also
from exec_body n bdy
have "Γ⊢⟨Call p,Normal (init s)⟩ =n ⇒ Abrupt t'"
by (auto simp add: intro: execn.intros)
from cnvalidD [OF valid_modif [rule_format, of n "init s"] ctxt this] P
have "t' ∈ ModifAbr (init s)"
by auto
with ret_modifAbr have "Abrupt (result_exn (return s t') t') = Abrupt (result_exn (return' s t') t')"
by simp
finally have "t = Abrupt (result_exn (return' s t') t')" .
with exec_body bdy n
have "Γ⊢⟨call_exn init p return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnAbrupt)
from cnvalidD [OF valid_call [rule_format] ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m f
assume bdy: "Γ p = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Fault f" "n = Suc m" and
t: "t = Fault f"
with bdy have "Γ⊢⟨call_exn init p return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnFault)
from cnvalidD [OF valid_call [rule_format] ctxt this P] t t_notin_F
show ?thesis
by simp
next
fix bdy m
assume bdy: "Γ p = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Stuck" "n = Suc m"
"t = Stuck"
with bdy have "Γ⊢⟨call_exn init p return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnStuck)
from valid_call [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
fix m
assume "Γ p = None"
and "n = Suc m" "t = Stuck"
then have "Γ⊢⟨call_exn init p return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnUndefined)
from valid_call [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
qed
qed
lemma ProcModifyReturnSameFaults_sound:
assumes valid_call: "∀n. Γ,Θ ⊨n:⇘/F⇙ P call init p return' c Q,A"
assumes valid_modif:
"∀σ. ∀n. Γ,Θ⊨n:⇘/F⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ return' s t = return s t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (call init p return c) Q,A"
using valid_call valid_modif ret_modif ret_modifAbr
unfolding call_call_exn
by (rule Proc_exnModifyReturnSameFaults_sound)
lemma Proc_exnModifyReturnSameFaults:
assumes spec: "Γ,Θ⊢⇘/F⇙ P (call_exn init p return' result_exn c) Q,A"
assumes result_conform:
"∀s t. t ∈ Modif (init s) ⟶ (return' s t) = (return s t)"
assumes return_conform:
"∀s t. t ∈ ModifAbr (init s) ⟶ (result_exn (return' s t) t) = (result_exn (return s t) t)"
assumes modifies_spec:
"∀σ. Γ,Θ⊢⇘/F⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (call_exn init p return result_exn c) Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule Proc_exnModifyReturnSameFaults_sound
[where Modif=Modif and ModifAbr=ModifAbr,
OF _ _ result_conform return_conform])
using spec
apply (blast intro: hoare_cnvalid)
using modifies_spec
apply (blast intro: hoare_cnvalid)
done
lemma ProcModifyReturnSameFaults:
assumes spec: "Γ,Θ⊢⇘/F⇙ P (call init p return' c) Q,A"
assumes result_conform:
"∀s t. t ∈ Modif (init s) ⟶ (return' s t) = (return s t)"
assumes return_conform:
"∀s t. t ∈ ModifAbr (init s) ⟶ (return' s t) = (return s t)"
assumes modifies_spec:
"∀σ. Γ,Θ⊢⇘/F⇙ {σ} Call p (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (call init p return c) Q,A"
using spec result_conform return_conform modifies_spec
unfolding call_call_exn
by (rule Proc_exnModifyReturnSameFaults)
subsubsection ‹DynCall›
lemma dynProc_exnModifyReturn_sound:
assumes valid_call: "⋀n. Γ,Θ ⊨n:⇘/F⇙ P dynCall_exn f g init p return' result_exn c Q,A"
assumes valid_modif:
"∀s ∈ P. ∀σ. ∀n.
Γ,Θ⊨n:⇘/UNIV⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ result_exn (return' s t) t = result_exn (return s t) t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (dynCall_exn f g init p return result_exn c) Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
then have ctxt': "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/UNIV⇙ P (Call p) Q,A"
by (auto intro: nvalid_augment_Faults)
assume exec: "Γ⊢⟨dynCall_exn f g init p return result_exn c,Normal s⟩ =n⇒ t"
assume t_notin_F: "t ∉ Fault ` F"
assume P: "s ∈ P"
with valid_modif
have valid_modif': "∀σ. ∀n.
Γ,Θ⊨n:⇘/UNIV⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
by blast
from exec
have exec_call: "Γ⊢⟨maybe_guard f g (call_exn init (p s) return result_exn c),Normal s⟩ =n⇒ t"
by (cases rule: execn_dynCall_exn_Normal_elim)
then show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases rule: execn_maybe_guard_Normal_elim_cases)
case noFault
from noFault have guards_ok: "s ∈ g" by simp
from noFault have "Γ⊢ ⟨call_exn init (p s) return result_exn c,Normal s⟩ =n⇒ t" by simp
then show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases rule: execn_call_exn_Normal_elim)
fix bdy m t'
assume bdy: "Γ (p s) = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Normal t'"
assume exec_c: "Γ⊢⟨c s t',Normal (return s t')⟩ =Suc m⇒ t"
assume n: "n = Suc m"
from exec_body n bdy
have "Γ⊢⟨Call (p s) ,Normal (init s)⟩ =n⇒ Normal t'"
by (auto simp add: intro: execn.intros)
from cnvalidD [OF valid_modif' [rule_format, of n "init s"] ctxt' this] P
have "t' ∈ Modif (init s)"
by auto
with ret_modif have "Normal (return' s t') = Normal (return s t')"
by simp
with exec_body exec_c bdy n
have "Γ⊢⟨call_exn init (p s) return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exn)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from cnvalidD [OF valid_call ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m t'
assume bdy: "Γ (p s) = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Abrupt t'"
assume n: "n = Suc m"
assume t: "t = Abrupt (result_exn (return s t') t')"
also from exec_body n bdy
have "Γ⊢⟨Call (p s) ,Normal (init s)⟩ =n⇒ Abrupt t'"
by (auto simp add: intro: execn.intros)
from cnvalidD [OF valid_modif' [rule_format, of n "init s"] ctxt' this] P
have "t' ∈ ModifAbr (init s)"
by auto
with ret_modifAbr have "Abrupt (result_exn (return s t') t') = Abrupt (result_exn (return' s t') t')"
by simp
finally have "t = Abrupt (result_exn (return' s t') t')" .
with exec_body bdy n
have "Γ⊢⟨call_exn init (p s) return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnAbrupt)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from cnvalidD [OF valid_call ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m f'
assume bdy: "Γ (p s) = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Fault f'" "n = Suc m"
"t = Fault f'"
with bdy have "Γ⊢⟨call_exn init (p s) return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnFault)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from valid_call ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
fix bdy m
assume bdy: "Γ (p s) = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Stuck" "n = Suc m"
"t = Stuck"
with bdy have "Γ⊢⟨call_exn init (p s) return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnStuck)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from valid_call ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
fix m
assume "Γ (p s) = None"
and "n = Suc m" "t = Stuck"
hence "Γ⊢⟨call_exn init (p s) return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnUndefined)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from valid_call ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
qed
next
case (someFault)
then obtain guards_fail:"s ∉ g"
and t: "t = Fault f" by simp
from execn_maybe_guard_Fault [OF guards_fail] t
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from cnvalidD [OF valid_call ctxt this] P t_notin_F
show ?thesis by simp
qed
qed
lemma dynProcModifyReturn_sound:
assumes valid_call: "⋀n. Γ,Θ ⊨n:⇘/F⇙ P dynCall init p return' c Q,A"
assumes valid_modif:
"∀s ∈ P. ∀σ. ∀n.
Γ,Θ⊨n:⇘/UNIV⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ return' s t = return s t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (dynCall init p return c) Q,A"
using valid_call valid_modif ret_modif ret_modifAbr
unfolding dynCall_dynCall_exn
by (rule dynProc_exnModifyReturn_sound)
lemma dynProc_exnModifyReturn:
assumes dyn_call: "Γ,Θ⊢⇘/F⇙ P dynCall_exn f g init p return' result_exn c Q,A"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ result_exn (return' s t) t = result_exn (return s t) t"
assumes modif:
"∀s ∈ P. ∀σ.
Γ,Θ⊢⇘/UNIV⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (dynCall_exn f g init p return result_exn c) Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule dynProc_exnModifyReturn_sound [where Modif=Modif and ModifAbr=ModifAbr,
OF hoare_cnvalid [OF dyn_call] _ ret_modif ret_modifAbr])
apply (intro ballI allI)
apply (rule hoare_cnvalid [OF modif [rule_format]])
apply assumption
done
lemma dynProcModifyReturn:
assumes dyn_call: "Γ,Θ⊢⇘/F⇙ P dynCall init p return' c Q,A"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ return' s t = return s t"
assumes modif:
"∀s ∈ P. ∀σ.
Γ,Θ⊢⇘/UNIV⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (dynCall init p return c) Q,A"
using dyn_call ret_modif ret_modifAbr modif
unfolding dynCall_dynCall_exn
by (rule dynProc_exnModifyReturn)
lemma dynProc_exnModifyReturnSameFaults_sound:
assumes valid_call: "⋀n. Γ,Θ ⊨n:⇘/F⇙ P dynCall_exn f g init p return' result_exn c Q,A"
assumes valid_modif:
"∀s ∈ P. ∀σ. ∀n.
Γ,Θ⊨n:⇘/F⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s) ⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s) ⟶ result_exn (return' s t) t = result_exn (return s t) t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (dynCall_exn f g init p return result_exn c) Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨dynCall_exn f g init p return result_exn c,Normal s⟩ =n⇒ t"
assume t_notin_F: "t ∉ Fault ` F"
assume P: "s ∈ P"
with valid_modif
have valid_modif': "∀σ. ∀n.
Γ,Θ⊨n:⇘/F⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
by blast
from exec
have exec_call: "Γ⊢⟨maybe_guard f g (call_exn init (p s) return result_exn c),Normal s⟩ =n⇒ t"
by (cases rule: execn_dynCall_exn_Normal_elim)
then show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases rule: execn_maybe_guard_Normal_elim_cases)
case noFault
from noFault have guards_ok: "s ∈ g" by simp
from noFault have "Γ⊢ ⟨call_exn init (p s) return result_exn c,Normal s⟩ =n⇒ t" by simp
then show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases rule: execn_call_exn_Normal_elim)
fix bdy m t'
assume bdy: "Γ (p s) = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Normal t'"
assume exec_c: "Γ⊢⟨c s t',Normal (return s t')⟩ =Suc m⇒ t"
assume n: "n = Suc m"
from exec_body n bdy
have "Γ⊢⟨Call (p s) ,Normal (init s)⟩ =n ⇒ Normal t'"
by (auto simp add: intro: execn.Call)
from cnvalidD [OF valid_modif' [rule_format, of n "init s"] ctxt this] P
have "t' ∈ Modif (init s)"
by auto
with ret_modif have "Normal (return' s t') = Normal (return s t')"
by simp
with exec_body exec_c bdy n
have "Γ⊢⟨call_exn init (p s) return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exn)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from cnvalidD [OF valid_call ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m t'
assume bdy: "Γ (p s) = Some bdy"
assume exec_body: "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Abrupt t'"
assume n: "n = Suc m"
assume t: "t = Abrupt (result_exn (return s t') t')"
also from exec_body n bdy
have "Γ⊢⟨Call (p s) ,Normal (init s)⟩ =n ⇒ Abrupt t'"
by (auto simp add: intro: execn.intros)
from cnvalidD [OF valid_modif' [rule_format, of n "init s"] ctxt this] P
have "t' ∈ ModifAbr (init s)"
by auto
with ret_modifAbr have "Abrupt (result_exn (return s t') t') = Abrupt (result_exn (return' s t') t')"
by simp
finally have "t = Abrupt (result_exn (return' s t') t')" .
with exec_body bdy n
have "Γ⊢⟨call_exn init (p s) return' result_exn c,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnAbrupt)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from cnvalidD [OF valid_call ctxt this] P t_notin_F
show ?thesis
by simp
next
fix bdy m f'
assume bdy: "Γ (p s) = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Fault f'" "n = Suc m" and
t: "t = Fault f'"
with bdy have "Γ⊢⟨call_exn init (p s) return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnFault)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from cnvalidD [OF valid_call ctxt this P] t t_notin_F
show ?thesis
by simp
next
fix bdy m
assume bdy: "Γ (p s) = Some bdy"
assume "Γ⊢⟨bdy,Normal (init s)⟩ =m⇒ Stuck" "n = Suc m"
"t = Stuck"
with bdy have "Γ⊢⟨call_exn init (p s) return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnStuck)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from valid_call ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
fix m
assume "Γ (p s) = None"
and "n = Suc m" "t = Stuck"
hence "Γ⊢⟨call_exn init (p s) return' result_exn c ,Normal s⟩ =n⇒ t"
by (auto intro: execn_call_exnUndefined)
from execn_maybe_guard_noFault [OF this guards_ok]
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_maybe_guard_DynCom)
from valid_call ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
qed
next
case (someFault)
then obtain guards_fail:"s ∉ g"
and t: "t = Fault f" by simp
from execn_maybe_guard_Fault [OF guards_fail] t
have "Γ⊢⟨dynCall_exn f g init p return' result_exn c,Normal s⟩ =n⇒ t"
by (simp add: dynCall_exn_def execn_guards_DynCom)
from cnvalidD [OF valid_call ctxt this] P t_notin_F
show ?thesis by simp
qed
qed
lemma dynProcModifyReturnSameFaults_sound:
assumes valid_call: "⋀n. Γ,Θ ⊨n:⇘/F⇙ P dynCall init p return' c Q,A"
assumes valid_modif:
"∀s ∈ P. ∀σ. ∀n.
Γ,Θ⊨n:⇘/F⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
assumes ret_modif:
"∀s t. t ∈ Modif (init s) ⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s) ⟶ return' s t = return s t"
shows "Γ,Θ ⊨n:⇘/F⇙ P (dynCall init p return c) Q,A"
using valid_call valid_modif ret_modif ret_modifAbr
unfolding dynCall_dynCall_exn
by (rule dynProc_exnModifyReturnSameFaults_sound)
lemma dynProc_exnModifyReturnSameFaults:
assumes dyn_call: "Γ,Θ⊢⇘/F⇙ P dynCall_exn f g init p return' result_exn c Q,A"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ result_exn (return' s t) t = result_exn (return s t) t"
assumes modif:
"∀s ∈ P. ∀σ. Γ,Θ⊢⇘/F⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (dynCall_exn f g init p return result_exn c) Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule dynProc_exnModifyReturnSameFaults_sound
[where Modif=Modif and ModifAbr=ModifAbr,
OF hoare_cnvalid [OF dyn_call] _ ret_modif ret_modifAbr])
apply (intro ballI allI)
apply (rule hoare_cnvalid [OF modif [rule_format]])
apply assumption
done
lemma dynProcModifyReturnSameFaults:
assumes dyn_call: "Γ,Θ⊢⇘/F⇙ P dynCall init p return' c Q,A"
assumes ret_modif:
"∀s t. t ∈ Modif (init s)
⟶ return' s t = return s t"
assumes ret_modifAbr: "∀s t. t ∈ ModifAbr (init s)
⟶ return' s t = return s t"
assumes modif:
"∀s ∈ P. ∀σ. Γ,Θ⊢⇘/F⇙ {σ} Call (p s) (Modif σ),(ModifAbr σ)"
shows "Γ,Θ⊢⇘/F⇙ P (dynCall init p return c) Q,A"
using dyn_call ret_modif ret_modifAbr modif
unfolding dynCall_dynCall_exn
by (rule dynProc_exnModifyReturnSameFaults)
subsubsection ‹Conjunction of Postcondition›
lemma PostConjI_sound:
assumes valid_Q: "∀n. Γ,Θ ⊨n:⇘/F⇙ P c Q,A"
assumes valid_R: "∀n. Γ,Θ ⊨n:⇘/F⇙ P c R,B"
shows "Γ,Θ ⊨n:⇘/F⇙ P c (Q ∩ R),(A ∩ B)"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
from valid_Q [rule_format] ctxt exec P t_notin_F have "t ∈ Normal ` Q ∪ Abrupt ` A"
by (rule cnvalidD)
moreover
from valid_R [rule_format] ctxt exec P t_notin_F have "t ∈ Normal ` R ∪ Abrupt ` B"
by (rule cnvalidD)
ultimately show "t ∈ Normal ` (Q ∩ R) ∪ Abrupt ` (A ∩ B)"
by blast
qed
lemma PostConjI:
assumes deriv_Q: "Γ,Θ⊢⇘/F⇙ P c Q,A"
assumes deriv_R: "Γ,Θ⊢⇘/F⇙ P c R,B"
shows "Γ,Θ⊢⇘/F⇙ P c (Q ∩ R),(A ∩ B)"
apply (rule hoare_complete')
apply (rule allI)
apply (rule PostConjI_sound)
using deriv_Q
apply (blast intro: hoare_cnvalid)
using deriv_R
apply (blast intro: hoare_cnvalid)
done
lemma Merge_PostConj_sound:
assumes validF: "∀n. Γ,Θ⊨n:⇘/F⇙ P c Q,A"
assumes validG: "∀n. Γ,Θ⊨n:⇘/G⇙ P' c R,X"
assumes F_G: "F ⊆ G"
assumes P_P': "P ⊆ P'"
shows "Γ,Θ⊨n:⇘/F⇙ P c (Q ∩ R),(A ∩ X)"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
with F_G have ctxt': "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/G⇙ P (Call p) Q,A"
by (auto intro: nvalid_augment_Faults)
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
with P_P' have P': "s ∈ P'"
by auto
assume t_noFault: "t ∉ Fault ` F"
show "t ∈ Normal ` (Q ∩ R) ∪ Abrupt ` (A ∩ X)"
proof -
from cnvalidD [OF validF [rule_format] ctxt exec P t_noFault]
have *: "t ∈ Normal ` Q ∪ Abrupt ` A".
then have "t ∉ Fault ` G"
by auto
from cnvalidD [OF validG [rule_format] ctxt' exec P' this]
have "t ∈ Normal ` R ∪ Abrupt ` X" .
with * show ?thesis by auto
qed
qed
lemma Merge_PostConj:
assumes validF: "Γ,Θ⊢⇘/F⇙ P c Q,A"
assumes validG: "Γ,Θ⊢⇘/G⇙ P' c R,X"
assumes F_G: "F ⊆ G"
assumes P_P': "P ⊆ P'"
shows "Γ,Θ⊢⇘/F⇙ P c (Q ∩ R),(A ∩ X)"
apply (rule hoare_complete')
apply (rule allI)
apply (rule Merge_PostConj_sound [OF _ _ F_G P_P'])
using validF apply (blast intro:hoare_cnvalid)
using validG apply (blast intro:hoare_cnvalid)
done
subsubsection ‹Weaken Context›
lemma WeakenContext_sound:
assumes valid_c: "∀n. Γ,Θ'⊨n:⇘/F⇙ P c Q,A"
assumes valid_ctxt: "∀(P, p, Q, A)∈Θ'. Γ,Θ⊨n:⇘/F⇙ P (Call p) Q,A"
shows "Γ,Θ⊨n:⇘/F⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
with valid_ctxt
have ctxt': "∀(P, p, Q, A)∈Θ'. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
by (simp add: cnvalid_def)
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
from valid_c [rule_format] ctxt' exec P t_notin_F
show "t ∈ Normal ` Q ∪ Abrupt ` A"
by (rule cnvalidD)
qed
lemma WeakenContext:
assumes deriv_c: "Γ,Θ'⊢⇘/F⇙ P c Q,A"
assumes deriv_ctxt: "∀(P,p,Q,A)∈Θ'. Γ,Θ⊢⇘/F⇙ P (Call p) Q,A"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule WeakenContext_sound)
using deriv_c
apply (blast intro: hoare_cnvalid)
using deriv_ctxt
apply (blast intro: hoare_cnvalid)
done
subsubsection ‹Guards and Guarantees›
lemma SplitGuards_sound:
assumes valid_c1: "∀n. Γ,Θ⊨n:⇘/F⇙ P c⇩1 Q,A"
assumes valid_c2: "∀n. Γ,Θ⊨n:⇘/F⇙ P c⇩2 UNIV,UNIV"
assumes c: "(c⇩1 ∩⇩g c⇩2) = Some c"
shows "Γ,Θ⊨n:⇘/F⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases t)
case Normal
with inter_guards_execn_noFault [OF c exec]
have "Γ⊢⟨c⇩1,Normal s⟩ =n⇒ t" by simp
from valid_c1 [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
case Abrupt
with inter_guards_execn_noFault [OF c exec]
have "Γ⊢⟨c⇩1,Normal s⟩ =n⇒ t" by simp
from valid_c1 [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
next
case (Fault f)
with exec inter_guards_execn_Fault [OF c]
have "Γ⊢⟨c⇩1,Normal s⟩ =n⇒ Fault f ∨ Γ⊢⟨c⇩2,Normal s⟩ =n⇒ Fault f"
by auto
then show ?thesis
proof (cases rule: disjE [consumes 1])
assume "Γ⊢⟨c⇩1,Normal s⟩ =n⇒ Fault f"
from Fault cnvalidD [OF valid_c1 [rule_format] ctxt this P] t_notin_F
show ?thesis
by blast
next
assume "Γ⊢⟨c⇩2,Normal s⟩ =n⇒ Fault f"
from Fault cnvalidD [OF valid_c2 [rule_format] ctxt this P] t_notin_F
show ?thesis
by blast
qed
next
case Stuck
with inter_guards_execn_noFault [OF c exec]
have "Γ⊢⟨c⇩1,Normal s⟩ =n⇒ t" by simp
from valid_c1 [rule_format] ctxt this P t_notin_F
show ?thesis
by (rule cnvalidD)
qed
qed
lemma SplitGuards:
assumes c: "(c⇩1 ∩⇩g c⇩2) = Some c"
assumes deriv_c1: "Γ,Θ⊢⇘/F⇙ P c⇩1 Q,A"
assumes deriv_c2: "Γ,Θ⊢⇘/F⇙ P c⇩2 UNIV,UNIV"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule SplitGuards_sound [OF _ _ c])
using deriv_c1
apply (blast intro: hoare_cnvalid)
using deriv_c2
apply (blast intro: hoare_cnvalid)
done
lemma CombineStrip_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/F⇙ P c Q,A"
assumes valid_strip: "∀n. Γ,Θ⊨n:⇘/{}⇙ P (strip_guards (-F) c) UNIV,UNIV"
shows "Γ,Θ⊨n:⇘/{}⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/{}⇙ P (Call p) Q,A"
hence ctxt': "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
by (auto intro: nvalid_augment_Faults)
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_noFault: "t ∉ Fault ` {}"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases t)
case (Normal t')
from cnvalidD [OF valid [rule_format] ctxt' exec P] Normal
show ?thesis
by auto
next
case (Abrupt t')
from cnvalidD [OF valid [rule_format] ctxt' exec P] Abrupt
show ?thesis
by auto
next
case (Fault f)
show ?thesis
proof (cases "f ∈ F")
case True
hence "f ∉ -F" by simp
with exec Fault
have "Γ⊢⟨strip_guards (-F) c,Normal s⟩ =n⇒ Fault f"
by (auto intro: execn_to_execn_strip_guards_Fault)
from cnvalidD [OF valid_strip [rule_format] ctxt this P] Fault
have False
by auto
thus ?thesis ..
next
case False
with cnvalidD [OF valid [rule_format] ctxt' exec P] Fault
show ?thesis
by auto
qed
next
case Stuck
from cnvalidD [OF valid [rule_format] ctxt' exec P] Stuck
show ?thesis
by auto
qed
qed
lemma CombineStrip:
assumes deriv: "Γ,Θ⊢⇘/F⇙ P c Q,A"
assumes deriv_strip: "Γ,Θ⊢⇘/{}⇙ P (strip_guards (-F) c) UNIV,UNIV"
shows "Γ,Θ⊢⇘/{}⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule CombineStrip_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
apply (iprover intro: hoare_cnvalid [OF deriv_strip])
done
lemma GuardsFlip_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/F⇙ P c Q,A"
assumes validFlip: "∀n. Γ,Θ⊨n:⇘/-F⇙ P c UNIV,UNIV"
shows "Γ,Θ⊨n:⇘/{}⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/{}⇙ P (Call p) Q,A"
hence ctxt': "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
by (auto intro: nvalid_augment_Faults)
from ctxt have ctxtFlip: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/-F⇙ P (Call p) Q,A"
by (auto intro: nvalid_augment_Faults)
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_noFault: "t ∉ Fault ` {}"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases t)
case (Normal t')
from cnvalidD [OF valid [rule_format] ctxt' exec P] Normal
show ?thesis
by auto
next
case (Abrupt t')
from cnvalidD [OF valid [rule_format] ctxt' exec P] Abrupt
show ?thesis
by auto
next
case (Fault f)
show ?thesis
proof (cases "f ∈ F")
case True
hence "f ∉ -F" by simp
with cnvalidD [OF validFlip [rule_format] ctxtFlip exec P] Fault
have False
by auto
thus ?thesis ..
next
case False
with cnvalidD [OF valid [rule_format] ctxt' exec P] Fault
show ?thesis
by auto
qed
next
case Stuck
from cnvalidD [OF valid [rule_format] ctxt' exec P] Stuck
show ?thesis
by auto
qed
qed
lemma GuardsFlip:
assumes deriv: "Γ,Θ⊢⇘/F⇙ P c Q,A"
assumes derivFlip: "Γ,Θ⊢⇘/-F⇙ P c UNIV,UNIV"
shows "Γ,Θ⊢⇘/{}⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule GuardsFlip_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
apply (iprover intro: hoare_cnvalid [OF derivFlip])
done
lemma MarkGuardsI_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/{}⇙ P c Q,A"
shows "Γ,Θ⊨n:⇘/{}⇙ P mark_guards f c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/{}⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨mark_guards f c,Normal s⟩ =n⇒ t"
from execn_mark_guards_to_execn [OF exec] obtain t' where
exec_c: "Γ⊢⟨c,Normal s⟩ =n⇒ t'" and
t'_noFault: "¬ isFault t' ⟶ t' = t"
by blast
assume P: "s ∈ P"
assume t_noFault: "t ∉ Fault ` {}"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof -
from cnvalidD [OF valid [rule_format] ctxt exec_c P]
have "t' ∈ Normal ` Q ∪ Abrupt ` A"
by blast
with t'_noFault
show ?thesis
by auto
qed
qed
lemma MarkGuardsI:
assumes deriv: "Γ,Θ⊢⇘/{}⇙ P c Q,A"
shows "Γ,Θ⊢⇘/{}⇙ P mark_guards f c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule MarkGuardsI_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
done
lemma MarkGuardsD_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/{}⇙ P mark_guards f c Q,A"
shows "Γ,Θ⊨n:⇘/{}⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/{}⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_noFault: "t ∉ Fault ` {}"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof (cases "isFault t")
case True
with execn_to_execn_mark_guards_Fault [OF exec ]
obtain f' where "Γ⊢⟨mark_guards f c,Normal s⟩ =n⇒ Fault f'"
by (fastforce elim: isFaultE)
from cnvalidD [OF valid [rule_format] ctxt this P]
have False
by auto
thus ?thesis ..
next
case False
from execn_to_execn_mark_guards [OF exec False]
obtain f' where "Γ⊢⟨mark_guards f c,Normal s⟩ =n⇒ t"
by auto
from cnvalidD [OF valid [rule_format] ctxt this P]
show ?thesis
by auto
qed
qed
lemma MarkGuardsD:
assumes deriv: "Γ,Θ⊢⇘/{}⇙ P mark_guards f c Q,A"
shows "Γ,Θ⊢⇘/{}⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule MarkGuardsD_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
done
lemma MergeGuardsI_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/F⇙ P c Q,A"
shows "Γ,Θ⊨n:⇘/F⇙ P merge_guards c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec_merge: "Γ⊢⟨merge_guards c,Normal s⟩ =n⇒ t"
from execn_merge_guards_to_execn [OF exec_merge]
have exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t" .
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
from cnvalidD [OF valid [rule_format] ctxt exec P t_notin_F]
show "t ∈ Normal ` Q ∪ Abrupt ` A".
qed
lemma MergeGuardsI:
assumes deriv: "Γ,Θ⊢⇘/F⇙ P c Q,A"
shows "Γ,Θ⊢⇘/F⇙ P merge_guards c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule MergeGuardsI_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
done
lemma MergeGuardsD_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/F⇙ P merge_guards c Q,A"
shows "Γ,Θ⊨n:⇘/F⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
from execn_to_execn_merge_guards [OF exec]
have exec_merge: "Γ⊢⟨merge_guards c,Normal s⟩ =n⇒ t".
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
from cnvalidD [OF valid [rule_format] ctxt exec_merge P t_notin_F]
show "t ∈ Normal ` Q ∪ Abrupt ` A".
qed
lemma MergeGuardsD:
assumes deriv: "Γ,Θ⊢⇘/F⇙ P merge_guards c Q,A"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule MergeGuardsD_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
done
lemma SubsetGuards_sound:
assumes c_c': "c ⊆⇩g c'"
assumes valid: "∀n. Γ,Θ⊨n:⇘/{}⇙ P c' Q,A"
shows "Γ,Θ⊨n:⇘/{}⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/{}⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
from execn_to_execn_subseteq_guards [OF c_c' exec] obtain t' where
exec_c': "Γ⊢⟨c',Normal s⟩ =n⇒ t'" and
t'_noFault: "¬ isFault t' ⟶ t' = t"
by blast
assume P: "s ∈ P"
assume t_noFault: "t ∉ Fault ` {}"
from cnvalidD [OF valid [rule_format] ctxt exec_c' P] t'_noFault t_noFault
show "t ∈ Normal ` Q ∪ Abrupt ` A"
by auto
qed
lemma SubsetGuards:
assumes c_c': "c ⊆⇩g c'"
assumes deriv: "Γ,Θ⊢⇘/{}⇙ P c' Q,A"
shows "Γ,Θ⊢⇘/{}⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule SubsetGuards_sound [OF c_c'])
apply (iprover intro: hoare_cnvalid [OF deriv])
done
lemma NormalizeD_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/F⇙ P (normalize c) Q,A"
shows "Γ,Θ⊨n:⇘/F⇙ P c Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
hence exec_norm: "Γ⊢⟨normalize c,Normal s⟩ =n⇒ t"
by (rule execn_to_execn_normalize)
assume P: "s ∈ P"
assume noFault: "t ∉ Fault ` F"
from cnvalidD [OF valid [rule_format] ctxt exec_norm P noFault]
show "t ∈ Normal ` Q ∪ Abrupt ` A".
qed
lemma NormalizeD:
assumes deriv: "Γ,Θ⊢⇘/F⇙ P (normalize c) Q,A"
shows "Γ,Θ⊢⇘/F⇙ P c Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule NormalizeD_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
done
lemma NormalizeI_sound:
assumes valid: "∀n. Γ,Θ⊨n:⇘/F⇙ P c Q,A"
shows "Γ,Θ⊨n:⇘/F⇙ P (normalize c) Q,A"
proof (rule cnvalidI)
fix s t
assume ctxt: "∀(P, p, Q, A)∈Θ. Γ⊨n:⇘/F⇙ P (Call p) Q,A"
assume "Γ⊢⟨normalize c,Normal s⟩ =n⇒ t"
hence exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
by (rule execn_normalize_to_execn)
assume P: "s ∈ P"
assume noFault: "t ∉ Fault ` F"
from cnvalidD [OF valid [rule_format] ctxt exec P noFault]
show "t ∈ Normal ` Q ∪ Abrupt ` A".
qed
lemma NormalizeI:
assumes deriv: "Γ,Θ⊢⇘/F⇙ P c Q,A"
shows "Γ,Θ⊢⇘/F⇙ P (normalize c) Q,A"
apply (rule hoare_complete')
apply (rule allI)
apply (rule NormalizeI_sound)
apply (iprover intro: hoare_cnvalid [OF deriv])
done
subsubsection ‹Restricting the Procedure Environment›
lemma nvalid_restrict_to_nvalid:
assumes valid_c: "Γ|⇘M⇙⊨n:⇘/F⇙ P c Q,A"
shows "Γ⊨n:⇘/F⇙ P c Q,A"
proof (rule nvalidI)
fix s t
assume exec: "Γ⊢⟨c,Normal s⟩ =n⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof -
from execn_to_execn_restrict [OF exec]
obtain t' where
exec_res: "Γ|⇘M⇙⊢⟨c,Normal s⟩ =n⇒ t'" and
t_Fault: "∀f. t = Fault f ⟶ t' ∈ {Fault f, Stuck}" and
t'_notStuck: "t'≠Stuck ⟶ t'=t"
by blast
from t_Fault t_notin_F t'_notStuck have "t' ∉ Fault ` F"
by (cases t') auto
with valid_c exec_res P
have "t' ∈ Normal ` Q ∪ Abrupt ` A"
by (auto simp add: nvalid_def)
with t'_notStuck
show ?thesis
by auto
qed
qed
lemma valid_restrict_to_valid:
assumes valid_c: "Γ|⇘M⇙⊨⇘/F⇙ P c Q,A"
shows "Γ⊨⇘/F⇙ P c Q,A"
proof (rule validI)
fix s t
assume exec: "Γ⊢⟨c,Normal s⟩ ⇒ t"
assume P: "s ∈ P"
assume t_notin_F: "t ∉ Fault ` F"
show "t ∈ Normal ` Q ∪ Abrupt ` A"
proof -
from exec_to_exec_restrict [OF exec]
obtain t' where
exec_res: "Γ|⇘M⇙⊢⟨c,Normal s⟩ ⇒ t'" and
t_Fault: "∀f. t = Fault f ⟶ t' ∈ {Fault f, Stuck}" and
t'_notStuck: "t'≠Stuck ⟶ t'=t"
by blast
from t_Fault t_notin_F t'_notStuck have "t' ∉ Fault ` F"
by (cases t') auto
with valid_c exec_res P
have "t' ∈ Normal ` Q ∪ Abrupt ` A"
by (auto simp add: valid_def)
with t'_notStuck
show ?thesis
by auto
qed
qed
lemma augment_procs:
assumes deriv_c: "Γ|⇘M⇙,{}⊢⇘/F⇙ P c Q,A"
shows "Γ,{}⊢⇘/F⇙ P c Q,A"
apply (rule hoare_complete)
apply (rule valid_restrict_to_valid)
apply (insert hoare_sound [OF deriv_c])
by (simp add: cvalid_def)
lemma augment_Faults:
assumes deriv_c: "Γ,{}⊢⇘/F⇙ P c Q,A"
assumes F: "F ⊆ F'"
shows "Γ,{}⊢⇘/F'⇙ P c Q,A"
apply (rule hoare_complete)
apply (rule valid_augment_Faults [OF _ F])
apply (insert hoare_sound [OF deriv_c])
by (simp add: cvalid_def)
end