Theory FWWait
section ‹Semantics of the thread actions for wait, notify and interrupt›
theory FWWait
imports
FWState
begin
text ‹Update functions for the wait sets in the multithreaded state›
inductive redT_updW :: "'t ⇒ ('w, 't) wait_sets ⇒ ('t,'w) wait_set_action ⇒ ('w,'t) wait_sets ⇒ bool"
for t :: 't and ws :: "('w, 't) wait_sets"
where
"ws t' = ⌊InWS w⌋ ⟹ redT_updW t ws (Notify w) (ws(t' ↦ PostWS WSNotified))"
| "(⋀t'. ws t' ≠ ⌊InWS w⌋) ⟹ redT_updW t ws (Notify w) ws"
| "redT_updW t ws (NotifyAll w) (λt. if ws t = ⌊InWS w⌋ then ⌊PostWS WSNotified⌋ else ws t)"
| "redT_updW t ws (Suspend w) (ws(t ↦ InWS w))"
| "ws t' = ⌊InWS w⌋ ⟹ redT_updW t ws (WakeUp t') (ws(t' ↦ PostWS WSInterrupted))"
| "(⋀w. ws t' ≠ ⌊InWS w⌋) ⟹ redT_updW t ws (WakeUp t') ws"
| "redT_updW t ws Notified (ws(t := None))"
| "redT_updW t ws WokenUp (ws(t := None))"
definition redT_updWs :: "'t ⇒ ('w,'t) wait_sets ⇒ ('t,'w) wait_set_action list ⇒ ('w,'t) wait_sets ⇒ bool"
where "redT_updWs t = rtrancl3p (redT_updW t)"
inductive_simps redT_updW_simps [simp]:
"redT_updW t ws (Notify w) ws'"
"redT_updW t ws (NotifyAll w) ws'"
"redT_updW t ws (Suspend w) ws'"
"redT_updW t ws (WakeUp t') ws'"
"redT_updW t ws WokenUp ws'"
"redT_updW t ws Notified ws'"
lemma redT_updW_total: "∃ws'. redT_updW t ws wa ws'"
by(cases wa)(auto simp add: redT_updW.simps)
lemma redT_updWs_total: "∃ws'. redT_updWs t ws was ws'"
proof(induct was rule: rev_induct)
case Nil thus ?case by(auto simp add: redT_updWs_def)
next
case (snoc wa was)
then obtain ws' where "redT_updWs t ws was ws'" ..
also from redT_updW_total[of t ws' wa]
obtain ws'' where "redT_updW t ws' wa ws''" ..
ultimately show ?case unfolding redT_updWs_def by(auto intro: rtrancl3p_step)
qed
lemma redT_updWs_trans: "⟦ redT_updWs t ws was ws'; redT_updWs t ws' was' ws'' ⟧ ⟹ redT_updWs t ws (was @ was') ws''"
unfolding redT_updWs_def by(rule rtrancl3p_trans)
lemma redT_updW_None_implies_None:
"⟦ redT_updW t' ws wa ws'; ws t = None; t ≠ t' ⟧ ⟹ ws' t = None"
by(auto simp add: redT_updW.simps)
lemma redT_updWs_None_implies_None:
assumes "redT_updWs t' ws was ws'"
and "t ≠ t'" and "ws t = None"
shows "ws' t = None"
using ‹redT_updWs t' ws was ws'› ‹ws t = None› unfolding redT_updWs_def
by induct(auto intro: redT_updW_None_implies_None[OF _ _ ‹t ≠ t'›])
lemma redT_updW_PostWS_imp_PostWS:
"⟦ redT_updW t ws wa ws'; ws t'' = ⌊PostWS w⌋; t'' ≠ t ⟧ ⟹ ws' t'' = ⌊PostWS w⌋"
by(auto simp add: redT_updW.simps)
lemma redT_updWs_PostWS_imp_PostWS:
"⟦ redT_updWs t ws was ws'; t'' ≠ t; ws t'' = ⌊PostWS w⌋ ⟧ ⟹ ws' t'' = ⌊PostWS w⌋"
unfolding redT_updWs_def
by(induct rule: rtrancl3p.induct)(auto dest: redT_updW_PostWS_imp_PostWS)
lemma redT_updW_Some_otherD:
"⟦ redT_updW t' ws wa ws'; ws' t = ⌊w⌋; t ≠ t' ⟧
⟹ (case w of InWS w' ⇒ ws t = ⌊InWS w'⌋ | _ ⇒ ws t = ⌊w⌋ ∨ (∃w'. ws t = ⌊InWS w'⌋))"
by(auto simp add: redT_updW.simps split: if_split_asm wait_set_status.split)
lemma redT_updWs_Some_otherD:
"⟦ redT_updWs t' ws was ws'; ws' t = ⌊w⌋; t ≠ t' ⟧
⟹ (case w of InWS w' ⇒ ws t = ⌊InWS w'⌋ | _ ⇒ ws t = ⌊w⌋ ∨ (∃w'. ws t = ⌊InWS w'⌋))"
unfolding redT_updWs_def
apply(induct arbitrary: w rule: rtrancl3p.induct)
apply(fastforce split: wait_set_status.splits dest: redT_updW_Some_otherD)+
done
lemma redT_updW_None_SomeD:
"⟦ redT_updW t ws wa ws'; ws' t' = ⌊w⌋; ws t' = None ⟧ ⟹ t = t' ∧ (∃w'. w = InWS w' ∧ wa = Suspend w')"
by(auto simp add: redT_updW.simps split: if_split_asm)
lemma redT_updWs_None_SomeD:
"⟦ redT_updWs t ws was ws'; ws' t' = ⌊w⌋; ws t' = None ⟧ ⟹ t = t' ∧ (∃w'. Suspend w' ∈ set was)"
unfolding redT_updWs_def
proof(induct arbitrary: w rule: rtrancl3p.induct)
case (rtrancl3p_refl ws) thus ?case by simp
next
case (rtrancl3p_step ws was ws' wa ws'')
show ?case
proof(cases "ws' t'")
case None
from redT_updW_None_SomeD[OF ‹redT_updW t ws' wa ws''›, OF ‹ws'' t' = ⌊w⌋› this]
show ?thesis by auto
next
case (Some w')
with ‹ws t' = None› rtrancl3p_step.hyps(2) show ?thesis by auto
qed
qed
lemma redT_updW_neq_Some_SomeD:
"⟦ redT_updW t' ws wa ws'; ws' t = ⌊InWS w⌋; ws t ≠ ⌊InWS w⌋ ⟧ ⟹ t = t' ∧ wa = Suspend w"
by(auto simp add: redT_updW.simps split: if_split_asm)
lemma redT_updWs_neq_Some_SomeD:
"⟦ redT_updWs t ws was ws'; ws' t' = ⌊InWS w⌋; ws t' ≠ ⌊InWS w⌋ ⟧ ⟹ t = t' ∧ Suspend w ∈ set was"
unfolding redT_updWs_def
proof(induct rule: rtrancl3p.induct)
case rtrancl3p_refl thus ?case by simp
next
case (rtrancl3p_step ws was ws' wa ws'')
show ?case
proof(cases "ws' t' = ⌊InWS w⌋")
case True
with ‹ws t' ≠ ⌊InWS w⌋› ‹⟦ws' t' = ⌊InWS w⌋; ws t' ≠ ⌊InWS w⌋⟧ ⟹ t = t' ∧ Suspend w ∈ set was›
show ?thesis by simp
next
case False
with ‹redT_updW t ws' wa ws''› ‹ws'' t' = ⌊InWS w⌋›
have "t' = t ∧ wa = Suspend w" by(rule redT_updW_neq_Some_SomeD)
thus ?thesis by auto
qed
qed
lemma redT_updW_not_Suspend_Some:
"⟦ redT_updW t ws wa ws'; ws' t = ⌊w'⌋; ws t = ⌊w⌋; ⋀w. wa ≠ Suspend w ⟧
⟹ w' = w ∨ (∃w'' w'''. w = InWS w'' ∧ w' = PostWS w''')"
by(auto simp add: redT_updW.simps split: if_split_asm)
lemma redT_updWs_not_Suspend_Some:
"⟦ redT_updWs t ws was ws'; ws' t = ⌊w'⌋; ws t = ⌊w⌋; ⋀w. Suspend w ∉ set was ⟧
⟹ w' = w ∨ (∃w'' w'''. w = InWS w'' ∧ w' = PostWS w''')"
unfolding redT_updWs_def
proof(induct arbitrary: w rule: rtrancl3p_converse_induct)
case refl thus ?case by simp
next
case (step ws wa ws' was ws'')
note ‹ws'' t = ⌊w'⌋›
moreover
have "ws' t ≠ None"
proof
assume "ws' t = None"
with ‹rtrancl3p (redT_updW t) ws' was ws''› ‹ws'' t = ⌊w'⌋›
obtain w' where "Suspend w' ∈ set was" unfolding redT_updWs_def[symmetric]
by(auto dest: redT_updWs_None_SomeD)
with ‹Suspend w' ∉ set (wa # was)› show False by simp
qed
then obtain w'' where "ws' t = ⌊w''⌋" by auto
moreover {
fix w
from ‹Suspend w ∉ set (wa # was)› have "Suspend w ∉ set was" by simp }
ultimately have "w' = w'' ∨ (∃w''' w''''. w'' = InWS w''' ∧ w' = PostWS w'''')" by(rule step.hyps)
moreover { fix w
from ‹Suspend w ∉ set (wa # was)› have "wa ≠ Suspend w" by auto }
note redT_updW_not_Suspend_Some[OF ‹redT_updW t ws wa ws'›, OF ‹ws' t = ⌊w''⌋› ‹ws t = ⌊w⌋› this]
ultimately show ?case by auto
qed
lemma redT_updWs_WokenUp_SuspendD:
"⟦ redT_updWs t ws was ws'; Notified ∈ set was ∨ WokenUp ∈ set was; ws' t = ⌊w⌋ ⟧ ⟹ ∃w. Suspend w ∈ set was"
unfolding redT_updWs_def
by(induct rule: rtrancl3p_converse_induct)(auto dest: redT_updWs_None_SomeD[unfolded redT_updWs_def])
lemma redT_updW_Woken_Up_same_no_Notified_Interrupted:
"⟦ redT_updW t ws wa ws'; ws' t = ⌊PostWS w⌋; ws t = ⌊PostWS w⌋; ⋀w. wa ≠ Suspend w ⟧
⟹ wa ≠ Notified ∧ wa ≠ WokenUp"
by(fastforce)
lemma redT_updWs_Woken_Up_same_no_Notified_Interrupted:
"⟦ redT_updWs t ws was ws'; ws' t = ⌊PostWS w⌋; ws t = ⌊PostWS w⌋; ⋀w. Suspend w ∉ set was ⟧
⟹ Notified ∉ set was ∧ WokenUp ∉ set was"
unfolding redT_updWs_def
proof(induct rule: rtrancl3p_converse_induct)
case refl thus ?case by simp
next
case (step ws wa ws' was ws'')
note Suspend = ‹⋀w. Suspend w ∉ set (wa # was)›
note ‹ws'' t = ⌊PostWS w⌋›
moreover have "ws' t = ⌊PostWS w⌋"
proof(cases "ws' t")
case None
with ‹rtrancl3p (redT_updW t) ws' was ws''› ‹ws'' t = ⌊PostWS w⌋›
obtain w where "Suspend w ∈ set was" unfolding redT_updWs_def[symmetric]
by(auto dest: redT_updWs_None_SomeD)
with Suspend[of w] have False by simp
thus ?thesis ..
next
case (Some w')
thus ?thesis using ‹ws t = ⌊PostWS w⌋› Suspend ‹redT_updW t ws wa ws'›
by(auto simp add: redT_updW.simps split: if_split_asm)
qed
moreover
{ fix w from Suspend[of w] have "Suspend w ∉ set was" by simp }
ultimately have "Notified ∉ set was ∧ WokenUp ∉ set was" by(rule step.hyps)
moreover
{ fix w from Suspend[of w] have "wa ≠ Suspend w" by auto }
with ‹redT_updW t ws wa ws'› ‹ws' t = ⌊PostWS w⌋› ‹ws t = ⌊PostWS w⌋›
have "wa ≠ Notified ∧ wa ≠ WokenUp" by(rule redT_updW_Woken_Up_same_no_Notified_Interrupted)
ultimately show ?case by auto
qed
text ‹Preconditions for wait set actions›
definition wset_actions_ok :: "('w,'t) wait_sets ⇒ 't ⇒ ('t,'w) wait_set_action list ⇒ bool"
where
"wset_actions_ok ws t was ⟷
(if Notified ∈ set was then ws t = ⌊PostWS WSNotified⌋
else if WokenUp ∈ set was then ws t = ⌊PostWS WSWokenUp⌋
else ws t = None)"
lemma wset_actions_ok_Nil [simp]:
"wset_actions_ok ws t [] ⟷ ws t = None"
by(simp add: wset_actions_ok_def)
definition waiting :: "'w wait_set_status option ⇒ bool"
where "waiting w ⟷ (∃w'. w = ⌊InWS w'⌋)"
lemma not_waiting_iff:
"¬ waiting w ⟷ w = None ∨ (∃w'. w = ⌊PostWS w'⌋)"
apply(cases "w")
apply(case_tac [2] a)
apply(auto simp add: waiting_def)
done
lemma waiting_code [code]:
"waiting None = False"
"⋀w. waiting ⌊PostWS w⌋ = False"
"⋀w. waiting ⌊InWS w⌋ = True"
by(simp_all add: waiting_def)
end