Theory FWThread
section ‹Semantics of the thread actions for thread creation›
theory FWThread
imports
FWState
begin
text‹Abstractions for thread ids›
context
notes [[inductive_internals]]
begin
inductive free_thread_id :: "('l,'t,'x) thread_info ⇒ 't ⇒ bool"
for ts :: "('l,'t,'x) thread_info" and t :: 't
where "ts t = None ⟹ free_thread_id ts t"
declare free_thread_id.cases [elim]
end
lemma free_thread_id_iff: "free_thread_id ts t = (ts t = None)"
by(auto elim: free_thread_id.cases intro: free_thread_id.intros)
text‹Update functions for the multithreaded state›
fun redT_updT :: "('l,'t,'x) thread_info ⇒ ('t,'x,'m) new_thread_action ⇒ ('l,'t,'x) thread_info"
where
"redT_updT ts (NewThread t' x m) = ts(t' ↦ (x, no_wait_locks))"
| "redT_updT ts _ = ts"
fun redT_updTs :: "('l,'t,'x) thread_info ⇒ ('t,'x,'m) new_thread_action list ⇒ ('l,'t,'x) thread_info"
where
"redT_updTs ts [] = ts"
| "redT_updTs ts (ta#tas) = redT_updTs (redT_updT ts ta) tas"
lemma redT_updTs_append [simp]:
"redT_updTs ts (tas @ tas') = redT_updTs (redT_updTs ts tas) tas'"
by(induct ts tas rule: redT_updTs.induct) auto
lemma redT_updT_None:
"redT_updT ts ta t = None ⟹ ts t = None"
by(cases ta)(auto split: if_splits)
lemma redT_updTs_None: "redT_updTs ts tas t = None ⟹ ts t = None"
by(induct ts tas rule: redT_updTs.induct)(auto intro: redT_updT_None)
lemma redT_updT_Some1:
"ts t = ⌊xw⌋ ⟹ ∃xw. redT_updT ts ta t = ⌊xw⌋"
by(cases ta) auto
lemma redT_updTs_Some1:
"ts t = ⌊xw⌋ ⟹ ∃xw. redT_updTs ts tas t = ⌊xw⌋"
unfolding not_None_eq[symmetric]
by(induct ts tas arbitrary: xw rule: redT_updTs.induct)(simp_all del: split_paired_Ex, blast dest: redT_updT_Some1)
lemma redT_updT_finite_dom_inv:
"finite (dom (redT_updT ts ta)) = finite (dom ts)"
by(cases ta) auto
lemma redT_updTs_finite_dom_inv:
"finite (dom (redT_updTs ts tas)) = finite (dom ts)"
by(induct ts tas rule: redT_updTs.induct)(simp_all add: redT_updT_finite_dom_inv)
text‹Preconditions for thread creation actions›
text‹These primed versions are for checking preconditions only. They allow the thread actions to have a type for thread-local information that is different than the thread info state itself.›
fun redT_updT' :: "('l,'t,'x) thread_info ⇒ ('t,'x','m) new_thread_action ⇒ ('l,'t,'x) thread_info"
where
"redT_updT' ts (NewThread t' x m) = ts(t' ↦ (undefined, no_wait_locks))"
| "redT_updT' ts _ = ts"
fun redT_updTs' :: "('l,'t,'x) thread_info ⇒ ('t,'x','m) new_thread_action list ⇒ ('l,'t,'x) thread_info"
where
"redT_updTs' ts [] = ts"
| "redT_updTs' ts (ta#tas) = redT_updTs' (redT_updT' ts ta) tas"
lemma redT_updT'_None:
"redT_updT' ts ta t = None ⟹ ts t = None"
by(cases ta)(auto split: if_splits)
primrec thread_ok :: "('l,'t,'x) thread_info ⇒ ('t,'x','m) new_thread_action ⇒ bool"
where
"thread_ok ts (NewThread t x m) = free_thread_id ts t"
| "thread_ok ts (ThreadExists t b) = (b ≠ free_thread_id ts t)"
fun thread_oks :: "('l,'t,'x) thread_info ⇒ ('t,'x','m) new_thread_action list ⇒ bool"
where
"thread_oks ts [] = True"
| "thread_oks ts (ta#tas) = (thread_ok ts ta ∧ thread_oks (redT_updT' ts ta) tas)"
lemma thread_ok_ts_change:
"(⋀t. ts t = None ⟷ ts' t = None) ⟹ thread_ok ts ta ⟷ thread_ok ts' ta"
by(cases ta)(auto simp add: free_thread_id_iff)
lemma thread_oks_ts_change:
"(⋀t. ts t = None ⟷ ts' t = None) ⟹ thread_oks ts tas ⟷ thread_oks ts' tas"
proof(induct tas arbitrary: ts ts')
case Nil thus ?case by simp
next
case (Cons ta tas ts ts')
note IH = ‹⋀ts ts'. (⋀t. (ts t = None) = (ts' t = None)) ⟹ thread_oks ts tas = thread_oks ts' tas›
note eq = ‹⋀t. (ts t = None) = (ts' t = None)›
from eq have "thread_ok ts ta ⟷ thread_ok ts' ta" by(rule thread_ok_ts_change)
moreover from eq have "⋀t. (redT_updT' ts ta t = None) = (redT_updT' ts' ta t = None)"
by(cases ta)(auto)
hence "thread_oks (redT_updT' ts ta) tas = thread_oks (redT_updT' ts' ta) tas" by(rule IH)
ultimately show ?case by simp
qed
lemma redT_updT'_eq_None_conv:
"(⋀t. ts t = None ⟷ ts' t = None) ⟹ redT_updT' ts ta t = None ⟷ redT_updT ts' ta t = None"
by(cases ta) simp_all
lemma redT_updTs'_eq_None_conv:
"(⋀t. ts t = None ⟷ ts' t = None) ⟹ redT_updTs' ts tas t = None ⟷ redT_updTs ts' tas t = None"
apply(induct tas arbitrary: ts ts')
apply simp_all
apply(blast intro: redT_updT'_eq_None_conv del: iffI)
done
lemma thread_oks_redT_updT_conv [simp]:
"thread_oks (redT_updT' ts ta) tas = thread_oks (redT_updT ts ta) tas"
by(rule thread_oks_ts_change)(rule redT_updT'_eq_None_conv refl)+
lemma thread_oks_append [simp]:
"thread_oks ts (tas @ tas') = (thread_oks ts tas ∧ thread_oks (redT_updTs' ts tas) tas')"
by(induct tas arbitrary: ts, auto)
lemma thread_oks_redT_updTs_conv [simp]:
"thread_oks (redT_updTs' ts ta) tas = thread_oks (redT_updTs ts ta) tas"
by(rule thread_oks_ts_change)(rule redT_updTs'_eq_None_conv refl)+
lemma redT_updT_Some:
"⟦ ts t = ⌊xw⌋; thread_ok ts ta ⟧ ⟹ redT_updT ts ta t = ⌊xw⌋"
by(cases ta) auto
lemma redT_updTs_Some:
"⟦ ts t = ⌊xw⌋; thread_oks ts tas ⟧ ⟹ redT_updTs ts tas t = ⌊xw⌋"
by(induct ts tas rule: redT_updTs.induct)(auto intro: redT_updT_Some)
lemma redT_updT'_Some:
"⟦ ts t = ⌊xw⌋; thread_ok ts ta ⟧ ⟹ redT_updT' ts ta t = ⌊xw⌋"
by(cases ta) auto
lemma redT_updTs'_Some:
"⟦ ts t = ⌊xw⌋; thread_oks ts tas ⟧ ⟹ redT_updTs' ts tas t = ⌊xw⌋"
by(induct ts tas rule: redT_updTs'.induct)(auto intro: redT_updT'_Some)
lemma thread_ok_new_thread:
"thread_ok ts (NewThread t m' x) ⟹ ts t = None"
by(auto)
lemma thread_oks_new_thread:
"⟦ thread_oks ts tas; NewThread t x m ∈ set tas ⟧ ⟹ ts t = None"
by(induct ts tas rule: thread_oks.induct)(auto intro: redT_updT'_None)
lemma redT_updT_new_thread_ts:
"thread_ok ts (NewThread t x m) ⟹ redT_updT ts (NewThread t x m) t = ⌊(x, no_wait_locks)⌋"
by(simp)
lemma redT_updTs_new_thread_ts:
"⟦ thread_oks ts tas; NewThread t x m ∈ set tas ⟧ ⟹ redT_updTs ts tas t = ⌊(x, no_wait_locks)⌋"
by(induct ts tas rule: redT_updTs.induct)(auto intro: redT_updTs_Some)
lemma redT_updT_new_thread:
"⟦ redT_updT ts ta t = ⌊(x, w)⌋; thread_ok ts ta; ts t = None ⟧ ⟹ ∃m. ta = NewThread t x m ∧ w = no_wait_locks"
by(cases ta)(auto split: if_split_asm)
lemma redT_updTs_new_thread:
"⟦ redT_updTs ts tas t = ⌊(x, w)⌋; thread_oks ts tas; ts t = None ⟧
⟹ ∃m .NewThread t x m ∈ set tas ∧ w = no_wait_locks"
proof(induct tas arbitrary: ts)
case Nil thus ?case by simp
next
case (Cons TA TAS TS)
note IH = ‹⋀ts. ⟦redT_updTs ts TAS t = ⌊(x, w)⌋; thread_oks ts TAS; ts t = None⟧ ⟹ ∃m. NewThread t x m ∈ set TAS ∧ w = no_wait_locks›
note es't = ‹redT_updTs TS (TA # TAS) t = ⌊(x, w)⌋›
note cct = ‹thread_oks TS (TA # TAS)›
hence cctta: "thread_ok TS TA" and ccts: "thread_oks (redT_updT TS TA) TAS" by auto
note est = ‹TS t = None›
{ fix X W
assume rest: "redT_updT TS TA t = ⌊(X, W)⌋"
then obtain m where "TA = NewThread t X m ∧ W = no_wait_locks" using cctta est
by (auto dest!: redT_updT_new_thread)
then obtain "TA = NewThread t X m" "W = no_wait_locks" ..
moreover from rest ccts
have "redT_updTs TS (TA # TAS) t = ⌊(X, W)⌋"
by(auto intro:redT_updTs_Some)
with es't have "X = x" "W = w" by auto
ultimately have ?case by auto }
moreover
{ assume rest: "redT_updT TS TA t = None"
hence "⋀m. TA ≠ NewThread t x m" using est cct
by(clarsimp)
with rest ccts es't have ?case by(auto dest: IH) }
ultimately show ?case by(cases "redT_updT TS TA t", auto)
qed
lemma redT_updT_upd:
"⟦ ts t = ⌊xw⌋; thread_ok ts ta ⟧ ⟹ (redT_updT ts ta)(t ↦ xw') = redT_updT (ts(t ↦ xw')) ta"
by(cases ta)(fastforce intro: fun_upd_twist)+
lemma redT_updTs_upd:
"⟦ ts t = ⌊xw⌋; thread_oks ts tas ⟧ ⟹ (redT_updTs ts tas)(t ↦ xw') = redT_updTs (ts(t ↦ xw')) tas"
by(induct ts tas rule: redT_updTs.induct)(auto simp del: fun_upd_apply simp add: redT_updT_upd dest: redT_updT_Some)
lemma thread_ok_upd:
"ts t = ⌊xln⌋ ⟹ thread_ok (ts(t ↦ xln')) ta = thread_ok ts ta"
by(rule thread_ok_ts_change) simp
lemma thread_oks_upd:
"ts t = ⌊xln⌋ ⟹ thread_oks (ts(t ↦ xln')) tas = thread_oks ts tas"
by(rule thread_oks_ts_change) simp
lemma thread_ok_convert_new_thread_action [simp]:
"thread_ok ts (convert_new_thread_action f ta) = thread_ok ts ta"
by(cases ta) auto
lemma redT_updT'_convert_new_thread_action_eq_None:
"redT_updT' ts (convert_new_thread_action f ta) t = None ⟷ redT_updT' ts ta t = None"
by(cases ta) auto
lemma thread_oks_convert_new_thread_action [simp]:
"thread_oks ts (map (convert_new_thread_action f) tas) = thread_oks ts tas"
by(induct ts tas rule: thread_oks.induct)(simp_all add: thread_oks_ts_change[OF redT_updT'_convert_new_thread_action_eq_None])
lemma map_redT_updT:
"map_option (map_prod f id) (redT_updT ts ta t) =
redT_updT (λt. map_option (map_prod f id) (ts t)) (convert_new_thread_action f ta) t"
by(cases ta) auto
lemma map_redT_updTs:
"map_option (map_prod f id) (redT_updTs ts tas t) =
redT_updTs (λt. map_option (map_prod f id) (ts t)) (map (convert_new_thread_action f) tas) t"
by(induct tas arbitrary: ts)(auto simp add: map_redT_updT)
end