Up to index of Isabelle/HOL/JinjaThreads
theory Threaded(* Title: JinjaThreads/J/Threaded.thy Author: Andreas Lochbihler *) header{* \isaheader{The source language as an instance of the framework} *} theory Threaded imports SmallStep "../Framework/FWLiftingSem" JWellForm "../Common/ConformThreaded" "../Framework/FWProgressAux" begin abbreviation final_expr :: "expr × locals => bool"where "final_expr ≡ λ(e, x). final e" abbreviation mred :: "J_prog => (addr, thread_id, expr × locals, heap, addr, obs_event) semantics" where "mred P ≡ (λ((e, l), h) ta ((e', l'), h'). P \<turnstile> 〈e, (h, l)〉 -ta-> 〈e', (h', l')〉)" lemma red_new_thread_heap: "[| convert_extTA extNTA,P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; NewThread t'' ex'' h'' ∈ set \<lbrace>ta\<rbrace>t |] ==> h'' = hp s'" and reds_new_thread_heap: "[| convert_extTA extNTA,P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; NewThread t'' ex'' h'' ∈ set \<lbrace>ta\<rbrace>t |] ==> h'' = hp s'" apply(induct rule: red_reds.inducts) apply(fastsimp dest: red_ext_new_thread_heap)+ done lemma red_mthr: "multithreaded (mred P)" by(unfold_locales)(auto dest: red_new_thread_heap) interpretation red_mthr: multithreaded "final_expr" "mred P" by(rule red_mthr) lemmas red_mthr_redT_elims4 = red_mthr.redT_elims4[consumes 1, case_names normal acquire] abbreviation mredT :: "J_prog => (addr,thread_id,expr × locals,heap,addr) state => (thread_id × (addr,thread_id,expr × locals,heap,addr,(addr, obs_event) observable) thread_action) => (addr,thread_id,expr × locals,heap,addr) state => bool" where "mredT P ≡ multithreaded_base.redT final_expr (mred P)" abbreviation mredT_syntax1 :: "J_prog => (addr,thread_id,expr × locals,heap,addr) state => thread_id => (addr,thread_id,expr × locals,heap,addr,(addr, obs_event) observable) thread_action => (addr,thread_id,expr × locals,heap,addr) state => bool" ("_ \<turnstile> _ -_\<triangleright>_-> _" [50,0,0,0,50] 80) where "mredT_syntax1 P s t ta s' ≡ mredT P s (t, ta) s'" abbreviation mredT_syntax2 :: "J_prog => (addr,thread_id) locks => (addr,thread_id,expr × locals) thread_info × heap => (addr,thread_id) wait_sets => thread_id => (addr,thread_id,expr × locals,heap,addr,(addr,obs_event) observable) thread_action => (addr,thread_id) locks => (addr,thread_id,expr × locals) thread_info × heap => (addr,thread_id) wait_sets => bool" ("_ \<turnstile> 〈_, _, _〉 -_\<triangleright>_-> 〈_, _, _〉" [50,0,0,0,0,0,0,0,0] 80) where "P \<turnstile> 〈ls, tsm, ws〉 -t\<triangleright>ta-> 〈ls', tsm', ws'〉 ≡ P \<turnstile> (ls, tsm, ws) -t\<triangleright>ta-> (ls', tsm', ws')" abbreviation mRedT_syntax1 :: "J_prog => (addr,thread_id,expr × locals,heap,addr) state => (thread_id × (addr,thread_id,expr × locals,heap,addr,(addr, obs_event) observable) thread_action) list => (addr,thread_id,expr × locals,heap,addr) state => bool" ("_ \<turnstile> _ -\<triangleright>_->* _" [50,0,0,50] 80) where "P \<turnstile> s -\<triangleright>ttas->* s' ≡ multithreaded_base.RedT final_expr (mred P) s ttas s'" abbreviation mRedT_syntax2 :: "J_prog => (addr,thread_id) locks => (addr,thread_id,expr × locals) thread_info × heap => (addr,thread_id) wait_sets => (thread_id × (addr,thread_id,expr × locals,heap,addr,(addr, obs_event) observable) thread_action) list => (addr,thread_id) locks => (addr,thread_id,expr × locals) thread_info × heap => (addr,thread_id) wait_sets => bool" ("_ \<turnstile> 〈_, _, _〉 -\<triangleright>_->* 〈_, _, _〉" [50,0,0,0,0,0,0,0] 80) where "P \<turnstile> 〈ls, tsm, ws〉 -\<triangleright>ttas->* 〈ls', tsm', ws'〉 ≡ P \<turnstile> (ls, tsm, ws) -\<triangleright>ttas->* (ls', tsm', ws')" lemma redT_hext_incr: "P \<turnstile> s -t\<triangleright>ta-> s' ==> hext (shr s) (shr s')" by(erule red_mthr.redT.cases, auto dest: red_hext_incr) section {* Towards agreement between the framework semantics' lock state and the locks stored in the expressions *} consts sync_ok :: "('a,'b) exp => bool" sync_oks :: "('a,'b) exp list => bool" primrec "sync_ok (new C) = True" "sync_ok (newA T⌊i⌉) = sync_ok i" "sync_ok (Cast T e) = sync_ok e" "sync_ok (Val v) = True" "sync_ok (Var v) = True" "sync_ok (e «bop» e') = (sync_ok e ∧ sync_ok e' ∧ (contains_insync e' --> is_val e))" "sync_ok (V := e) = sync_ok e" "sync_ok (a⌊i⌉) = (sync_ok a ∧ sync_ok i ∧ (contains_insync i --> is_val a))" "sync_ok (AAss a i e) = (sync_ok a ∧ sync_ok i ∧ sync_ok e ∧ (contains_insync i --> is_val a) ∧ (contains_insync e --> is_val a ∧ is_val i))" "sync_ok (a•length) = sync_ok a" "sync_ok (e•F{D}) = sync_ok e" "sync_ok (FAss e F D e') = (sync_ok e ∧ sync_ok e' ∧ (contains_insync e' --> is_val e))" "sync_ok (e•m(pns)) = (sync_ok e ∧ sync_oks pns ∧ (contains_insyncs pns --> is_val e))" "sync_ok ({V : T=vo; e}) = sync_ok e" "sync_ok (syncV (o') e) = (sync_ok o' ∧ ¬ contains_insync e)" "sync_ok (insyncV (a) e) = sync_ok e" "sync_ok (e;;e') = (sync_ok e ∧ sync_ok e' ∧ (contains_insync e' --> is_val e))" "sync_ok (if (b) e else e') = (sync_ok b ∧ ¬ contains_insync e ∧ ¬ contains_insync e')" "sync_ok (while (b) e) = (¬ contains_insync b ∧ ¬ contains_insync e)" "sync_ok (throw e) = sync_ok e" "sync_ok (try e catch(C v) e') = (sync_ok e ∧ ¬ contains_insync e')" "sync_oks [] = True" "sync_oks (x # xs) = (sync_ok x ∧ sync_oks xs ∧ (contains_insyncs xs --> is_val x))" lemma sync_oks_append [simp]: "sync_oks (xs @ ys) <-> sync_oks xs ∧ sync_oks ys ∧ (contains_insyncs ys --> (∃vs. xs = map Val vs))" by(induct xs)(auto simp add: Cons_eq_map_conv) lemma fixes e :: "('a,'b) exp" and es :: "('a,'b) exp list" shows not_contains_insync_sync_ok: "¬ contains_insync e ==> sync_ok e" and not_contains_insyncs_sync_oks: "¬ contains_insyncs es ==> sync_oks es" by(induct e and es)(auto) lemma expr_locks_sync_ok: "(!!ad. expr_locks e ad = 0) ==> sync_ok e" and expr_lockss_sync_oks: "(!!ad. expr_lockss es ad = 0) ==> sync_oks es" by(auto intro!: not_contains_insync_sync_ok not_contains_insyncs_sync_oks simp add: contains_insync_conv contains_insyncs_conv) lemma sync_ok_extRet2J [simp]: "sync_ok (extRet2J va)" by(cases va) auto lemma assumes wf: "wf_J_prog P" shows red_preserve_sync_ok: "[| extTA,P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; sync_ok e |] ==> sync_ok e'" and reds_preserve_sync_oks: "[| extTA,P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; sync_oks es |] ==> sync_oks es'" proof(induct rule: red_reds.inducts) case (RedCall s a C fs M Ts T pns body D vs) from wf `P \<turnstile> C sees M: Ts->T = (pns, body) in D` have "wf_mdecl wf_J_mdecl P D (M,Ts,T,pns,body)" by(rule sees_wf_mdecl) then obtain T where "P,[this\<mapsto>Class D,pns[\<mapsto>]Ts] \<turnstile> body :: T" by(auto simp add: wf_mdecl_def) hence "expr_locks body = (λad. 0)" by(rule WT_expr_locks) with `length vs = length pns` `length Ts = length pns` have "expr_locks (blocks (pns, Ts, vs, body)) = (λad. 0)" by(simp add: expr_locks_blocks) thus ?case by(auto intro: expr_locks_sync_ok) qed(fastsimp intro: not_contains_insync_sync_ok)+ lemma assumes wf: "wf_J_prog P" shows expr_locks_new_thread: "[| P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; NewThread t (e'', x'') h ∈ set \<lbrace>ta\<rbrace>t |] ==> expr_locks e'' = (λad. 0)" and expr_locks_new_thread': "[| P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; NewThread t (e'', x'') h ∈ set \<lbrace>ta\<rbrace>t |] ==> expr_locks e'' = (λad. 0)" proof(induct rule: red_reds.inducts) case (RedCallExternal s a T M vs ta va h' ta' e' s') then obtain C fs where subThread: "P \<turnstile> C \<preceq>* Thread" and ext: "extNTA2J P (C, run, t) = (e'', x'')" by(fastsimp elim!: red_external.cases split: heapobj.split_asm dest: Array_widen) from sub_Thread_sees_run[OF wf subThread] obtain D pns body where sees: "P \<turnstile> C sees run: []->Void = (pns, body) in D" by auto from sees_wf_mdecl[OF wf this] obtain T where "P,[this \<mapsto> Class D] \<turnstile> body :: T" by(auto simp add: wf_mdecl_def) hence "expr_locks body = (λad. 0)" by(rule WT_expr_locks) with sees ext show ?case by(auto simp add: extNTA2J_def) qed(auto) lemma assumes wf: "wf_J_prog P" shows red_new_thread_sync_ok: "[| P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; NewThread t'' (e'', x'') h'' ∈ set \<lbrace>ta\<rbrace>t |] ==> sync_ok e''" and reds_new_thread_sync_ok: "[| P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; NewThread t'' (e'', x'') h'' ∈ set \<lbrace>ta\<rbrace>t |] ==> sync_ok e''" by(auto dest!: expr_locks_new_thread[OF wf] expr_locks_new_thread'[OF wf] intro: expr_locks_sync_ok expr_lockss_sync_oks) abbreviation sync_es_ok :: "(addr,thread_id,('a,'b) exp×'c) thread_info => heap => bool" where "sync_es_ok ≡ ts_ok (λ(e, x) m. sync_ok e)" lemma lifting_wf_sync_ok: "wf_J_prog P ==> lifting_wf (mred P) (λ(e, x) m. sync_ok e)" by(unfold_locales)(auto intro: red_preserve_sync_ok red_new_thread_sync_ok) lemma redT_preserve_sync_ok: assumes red: "P \<turnstile> s -t\<triangleright>ta-> s'" shows "[| wf_J_prog P; sync_es_ok (thr s) (shr s) |] ==> sync_es_ok (thr s') (shr s')" by(rule lifting_wf.redT_preserves[OF lifting_wf_sync_ok red]) lemmas RedT_preserves_sync_ok = lifting_wf.RedT_preserves[OF lifting_wf_sync_ok] text {* Framework lock state agrees with locks stored in the expression *} definition lock_ok :: "(addr,thread_id) locks => (addr,thread_id,expr × locals) thread_info => bool" where "lock_ok ls ts ≡ ∀t. (case (ts t) of None => (∀l. has_locks (lsf l) t = 0) | ⌊((e, x), ln)⌋ => (∀l. has_locks (lsf l) t + lnf l = expr_locks e l))" lemma lock_okI: "[| !!t l. ts t = None ==> has_locks (lsf l) t = 0; !!t e x ln l. ts t = ⌊((e, x), ln)⌋ ==> has_locks (lsf l) t + lnf l= expr_locks e l |] ==> lock_ok ls ts" apply(fastsimp simp add: lock_ok_def) done lemma lock_okE: "[| lock_ok ls ts; ∀t. ts t = None --> (∀l. has_locks (lsf l) t = 0) ==> Q; ∀t e x ln. ts t = ⌊((e, x), ln)⌋ --> (∀l. has_locks (lsf l) t + lnf l = expr_locks e l) ==> Q |] ==> Q" by(fastsimp simp add: lock_ok_def) lemma lock_okD1: "[| lock_ok ls ts; ts t = None |] ==> ∀l. has_locks (lsf l) t = 0" apply(simp add: lock_ok_def) apply(erule_tac x="t" in allE) apply(auto) done lemma lock_okD2: "[| lock_ok ls ts; ts t = ⌊((e, x), ln)⌋ |] ==> ∀l. has_locks (lsf l) t + lnf l = expr_locks e l" apply(fastsimp simp add: lock_ok_def) done lemma lock_ok_lock_thread_ok: assumes lock: "lock_ok ls ts" shows "lock_thread_ok ls ts" proof(rule lock_thread_okI) fix l t assume lsl: "has_lock (lsf l) t" show "∃xw. ts t = ⌊xw⌋" proof(cases "ts t") case None with lock have "has_locks (lsf l) t = 0" by(auto dest: lock_okD1) with lsl show ?thesis by simp next case (Some a) thus ?thesis by blast qed qed section {* Preservation of lock state agreement *} fun upd_expr_lock_action :: "int => lock_action => int" where "upd_expr_lock_action i Lock = i + 1" | "upd_expr_lock_action i Unlock = i - 1" | "upd_expr_lock_action i UnlockFail = i" | "upd_expr_lock_action i ReleaseAcquire = i" fun upd_expr_lock_actions :: "int => lock_action list => int" where "upd_expr_lock_actions n [] = n" | "upd_expr_lock_actions n (L # Ls) = upd_expr_lock_actions (upd_expr_lock_action n L) Ls" lemma upd_expr_lock_actions_append [simp]: "upd_expr_lock_actions n (Ls @ Ls') = upd_expr_lock_actions (upd_expr_lock_actions n Ls) Ls'" by(induct Ls arbitrary: n, auto) definition upd_expr_locks :: "('l => int) => 'l lock_actions => 'l => int" where "upd_expr_locks els las ≡ λl. upd_expr_lock_actions (els l) (lasf l)" lemma upd_expr_locks_iff [simp]: "upd_expr_locks els las l = upd_expr_lock_actions (els l) (lasf l)" by(simp add: upd_expr_locks_def) lemma upd_expr_lock_action_add [simp]: "upd_expr_lock_action (l + l') L = upd_expr_lock_action l L + l'" by(cases L, auto) lemma upd_expr_lock_actions_add [simp]: "upd_expr_lock_actions (l + l') Ls = upd_expr_lock_actions l Ls + l'" by(induct Ls arbitrary: l, auto) lemma upd_expr_locks_add [simp]: "upd_expr_locks (λa. x a + y a) las = (λa. upd_expr_locks x las a + y a)" by(auto intro: ext) lemma expr_locks_extRet2J [simp]: "expr_locks (extRet2J va) = (λad. 0)" by(cases va) auto lemma assumes wf: "wf_J_prog P" shows red_update_expr_locks: "[| convert_extTA extNTA,P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; sync_ok e |] ==> upd_expr_locks (int o expr_locks e) \<lbrace>ta\<rbrace>l = int o expr_locks e'" and reds_update_expr_lockss: "[| convert_extTA extNTA,P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; sync_oks es |] ==> upd_expr_locks (int o expr_lockss es) \<lbrace>ta\<rbrace>l = int o expr_lockss es'" proof - have "[| convert_extTA extNTA,P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; sync_ok e |] ==> upd_expr_locks (λad. 0) \<lbrace>ta\<rbrace>l = (λad. (int o expr_locks e') ad - (int o expr_locks e) ad)" and "[| convert_extTA extNTA,P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; sync_oks es |] ==> upd_expr_locks (λad. 0) \<lbrace>ta\<rbrace>l = (λad. (int o expr_lockss es') ad - (int o expr_lockss es) ad)" proof(induct rule: red_reds.inducts) case (RedCall s a C fs M Ts T pns body D vs) from wf `P \<turnstile> C sees M: Ts->T = (pns, body) in D` have "wf_mdecl wf_J_mdecl P D (M,Ts,T,pns,body)" by(rule sees_wf_mdecl) then obtain T where "P,[this\<mapsto>Class D,pns[\<mapsto>]Ts] \<turnstile> body :: T" by(auto simp add: wf_mdecl_def) hence "expr_locks body = (λad. 0)" by(rule WT_expr_locks) with `length vs = length pns` `length Ts = length pns` have "expr_locks (blocks (pns, Ts, vs, body)) = (λad. 0)" by(simp add: expr_locks_blocks) thus ?case by(auto intro: expr_locks_sync_ok) next case RedCallExternal thus ?case by(auto simp add: expand_fun_eq contains_insync_conv contains_insyncs_conv finfun_upd_apply elim!: red_external.cases) qed(fastsimp simp add: expand_fun_eq contains_insync_conv contains_insyncs_conv finfun_upd_apply)+ hence "[| convert_extTA extNTA,P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; sync_ok e |] ==> upd_expr_locks (λad. 0 + (int o expr_locks e) ad) \<lbrace>ta\<rbrace>l = int o expr_locks e'" and "[| convert_extTA extNTA,P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; sync_oks es |] ==> upd_expr_locks (λad. 0 + (int o expr_lockss es) ad) \<lbrace>ta\<rbrace>l = int o expr_lockss es'" by(auto intro: ext simp only: upd_expr_locks_add) thus "[| convert_extTA extNTA,P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; sync_ok e |] ==> upd_expr_locks (int o expr_locks e) \<lbrace>ta\<rbrace>l = int o expr_locks e'" and "[| convert_extTA extNTA,P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; sync_oks es |] ==> upd_expr_locks (int o expr_lockss es) \<lbrace>ta\<rbrace>l = int o expr_lockss es'" by(auto simp add: o_def) qed definition lock_expr_locks_ok :: "'t FWState.lock => 't => nat => int => bool" where "lock_expr_locks_ok l t n i ≡ (i = int (has_locks l t) + int n) ∧ i ≥ 0" lemma upd_lock_upd_expr_lock_action_preserve_lock_expr_locks_ok: assumes lao: "lock_action_ok l t L" and lelo: "lock_expr_locks_ok l t n i" shows "lock_expr_locks_ok (upd_lock l t L) t (upd_threadR n l t L) (upd_expr_lock_action i L)" proof - from lelo have i: "i ≥ 0" and hl: "i = int (has_locks l t) + int n" by(auto simp add: lock_expr_locks_ok_def) from lelo show ?thesis proof(cases L) case Lock with lao have "may_lock l t" by(simp) with hl have "has_locks (lock_lock l t) t = (Suc (has_locks l t))" by(auto) with Lock i hl show ?thesis by(simp add: lock_expr_locks_ok_def) next case Unlock with lao have "has_lock l t" by simp then obtain n' where hl': "has_locks l t = Suc n'" by(auto dest: has_lock_has_locks_Suc) hence "has_locks (unlock_lock l) t = n'" by simp with Unlock i hl hl' show ?thesis by(simp add: lock_expr_locks_ok_def) qed(auto simp add: lock_expr_locks_ok_def) qed lemma upd_locks_upd_expr_lock_preserve_lock_expr_locks_ok: "[| lock_actions_ok l t Ls; lock_expr_locks_ok l t n i |] ==> lock_expr_locks_ok (upd_locks l t Ls) t (upd_threadRs n l t Ls) (upd_expr_lock_actions i Ls)" by(induct Ls arbitrary: l i n)(auto intro: upd_lock_upd_expr_lock_action_preserve_lock_expr_locks_ok) definition ls_els_ok :: "(addr,thread_id) locks => thread_id => (addr =>f nat) => (addr => int) => bool" where "ls_els_ok ls t ln els ≡ ∀l. lock_expr_locks_ok (lsf l) t (lnf l) (els l)" lemma ls_els_okI: "(!!l. lock_expr_locks_ok (lsf l) t (lnf l) (els l)) ==> ls_els_ok ls t ln els" by(auto simp add: ls_els_ok_def) lemma ls_els_okE: "[| ls_els_ok ls t ln els; ∀l. lock_expr_locks_ok (lsf l) t (lnf l) (els l) ==> P |] ==> P" by(auto simp add: ls_els_ok_def) lemma ls_els_okD: "ls_els_ok ls t ln els ==> lock_expr_locks_ok (lsf l) t (lnf l) (els l)" by(auto simp add: ls_els_ok_def) lemma redT_updLs_upd_expr_locks_preserves_ls_els_ok: "[| ls_els_ok ls t ln els; lock_ok_las ls t las |] ==> ls_els_ok (redT_updLs ls t las) t (redT_updLns ls t ln las) (upd_expr_locks els las)" by(auto intro!: ls_els_okI upd_locks_upd_expr_lock_preserve_lock_expr_locks_ok elim!: ls_els_okE simp add: redT_updLs_def lock_ok_las_def) lemma sync_ok_redT_updT: assumes "sync_es_ok ts h" and nt: "!!t e x h''. ta = NewThread t (e, x) h'' ==> sync_ok e" shows "sync_es_ok (redT_updT ts ta) h'" using assms proof(cases ta) case (NewThread T x m) obtain E X where [simp]: "x = (E, X)" by (cases x, auto) with NewThread have "sync_ok E" by(simp)(rule nt) with NewThread `sync_es_ok ts h` show ?thesis apply - apply(rule ts_okI) apply(case_tac "t=T") by(auto dest: ts_okD) qed(auto intro: ts_okI dest: ts_okD) lemma sync_ok_redT_updTs: "[| sync_es_ok ts h; !!t e x h. NewThread t (e, x) h ∈ set tas ==> sync_ok e |] ==> sync_es_ok (redT_updTs ts tas) h'" proof(induct tas arbitrary: ts) case Nil thus ?case by(auto intro: ts_okI dest: ts_okD) next case (Cons TA TAS TS) note IH = `!!ts. [|sync_es_ok ts h; !!t e x h''. NewThread t (e, x) h'' ∈ set TAS ==> sync_ok e|] ==> sync_es_ok (redT_updTs ts TAS) h'` note nt = `!!t e x h. NewThread t (e, x) h ∈ set (TA # TAS) ==> sync_ok e` from `sync_es_ok TS h` nt have "sync_es_ok (redT_updT TS TA) h" by(auto elim!: sync_ok_redT_updT) hence "sync_es_ok (redT_updTs (redT_updT TS TA) TAS) h'" by(rule IH)(auto intro: nt) thus ?case by simp qed lemma redT_preserves_lock_ok: assumes wf: "wf_J_prog P" and "P \<turnstile> s -t\<triangleright>ta-> s'" and "lock_ok (locks s) (thr s)" and "sync_es_ok (thr s) (shr s)" shows "lock_ok (locks s') (thr s')" proof - obtain ls ts h ws where s [simp]: "s = (ls, (ts, h), ws)" by(cases s, auto) obtain ls' ts' h' ws' where s' [simp]: "s' = (ls', (ts', h'), ws')" by(cases s', auto) from assms have redT: "P \<turnstile> 〈ls, (ts, h), ws〉 -t\<triangleright>ta-> 〈ls', (ts', h'), ws'〉" and loes: "lock_ok ls ts" and aoes: "sync_es_ok ts h" by auto from redT have "lock_ok ls' ts'" proof(induct rule: red_mthr_redT_elims4) case (normal a a' ta') moreover obtain e x where "a = (e, x)" by (cases a, auto) moreover obtain e' x' where "a' = (e', x')" by (cases a', auto) ultimately have P: "P \<turnstile> 〈e,(h, x)〉 -ta'-> 〈e',(h', x')〉" and est: "ts t = ⌊((e, x), no_wait_locks)⌋" and lota: "lock_ok_las ls t \<lbrace>ta'\<rbrace>l" and cctta: "thread_oks ts \<lbrace>ta'\<rbrace>t" and ls': "ls' = redT_updLs ls t \<lbrace>ta'\<rbrace>l" and es': "ts' = redT_updTs ts \<lbrace>ta'\<rbrace>t(t \<mapsto> ((e', x'), redT_updLns ls t no_wait_locks \<lbrace>ta'\<rbrace>l))" and ws': "ws' = redT_updWs ws t \<lbrace>ta'\<rbrace>w" and ta [simp]: "ta = observable_ta_of ta'" by auto from est aoes have aoe: "sync_ok e" by(auto dest: ts_okD) from aoe P have aoe': "sync_ok e'" by(auto dest: red_preserve_sync_ok[OF wf]) from aoes red_new_thread_sync_ok[OF wf P] have "sync_es_ok (redT_updTs ts \<lbrace>ta'\<rbrace>t) h'" by(rule sync_ok_redT_updTs) with aoe' have aoes': "sync_es_ok (redT_updTs ts \<lbrace>ta\<rbrace>t(t \<mapsto> ((e', x'), redT_updLns ls t no_wait_locks \<lbrace>ta\<rbrace>l))) h" by(auto intro!: ts_okI dest: ts_okD split: split_if_asm) show ?thesis proof(rule lock_okI) fix t'' l assume "ts' t'' = None" with es' have "ts t'' = None" by(auto split: split_if_asm intro: redT_updTs_None) with loes have "has_locks (lsf l) t'' = 0" by(auto dest: lock_okD1) moreover from `ts' t'' = None` es' have "t ≠ t''" by(simp split: split_if_asm) ultimately show "has_locks (ls'f l) t'' = 0" by(simp add: red_mthr.redT_has_locks_inv[OF redT]) next fix t'' e'' x'' l ln'' assume ts't'': "ts' t'' = ⌊((e'', x''), ln'')⌋" with aoes' es' have aoe'': "sync_ok e''" by(auto dest: ts_okD) show "has_locks (ls'f l) t'' + ln''f l = expr_locks e'' l" proof(cases "t = t''") case True note tt'' = `t = t''` with ts't'' es' have e'': "e'' = e'" and x'': "x'' = x'" and ln'': "ln'' = redT_updLns ls t no_wait_locks \<lbrace>ta\<rbrace>l" by auto have "ls_els_ok ls t no_wait_locks (int o expr_locks e)" proof(rule ls_els_okI) fix l note lock_okD2[OF loes, OF est] thus "lock_expr_locks_ok (lsf l) t (no_wait_locksf l) ((int o expr_locks e) l)" by(simp add: lock_expr_locks_ok_def) qed hence "ls_els_ok (redT_updLs ls t \<lbrace>ta'\<rbrace>l) t (redT_updLns ls t no_wait_locks \<lbrace>ta'\<rbrace>l) (upd_expr_locks (int o expr_locks e) \<lbrace>ta'\<rbrace>l)" by(rule redT_updLs_upd_expr_locks_preserves_ls_els_ok[OF _ lota]) hence "ls_els_ok (redT_updLs ls t \<lbrace>ta'\<rbrace>l) t (redT_updLns ls t no_wait_locks \<lbrace>ta'\<rbrace>l) (int o expr_locks e')" by(simp only: red_update_expr_locks[OF wf P aoe]) thus ?thesis using ls' e'' tt'' ln'' by(auto dest: ls_els_okD[where l = l] simp: lock_expr_locks_ok_def) next case False note tt'' = `t ≠ t''` from lota have lao: "lock_actions_ok (lsf l) t (\<lbrace>ta\<rbrace>lf l)" by(simp add: lock_ok_las_def) show ?thesis proof(cases "ts t''") case None with est ts't'' es' tt'' cctta obtain m' where "NewThread t'' (e'', x'') m' ∈ set \<lbrace>ta\<rbrace>t" and ln'': "ln'' = no_wait_locks" by(auto dest: redT_updTs_new_thread) moreover with P have "m' = h'" by(auto dest: red_new_thread_heap) ultimately have "NewThread t'' (e'', x'') h' ∈ set \<lbrace>ta'\<rbrace>t" by simp with wf P ln'' have "expr_locks e'' = (λad. 0)" by -(rule expr_locks_new_thread) hence elel: "expr_locks e'' l = 0" by simp from loes None have "has_locks (lsf l) t'' = 0" by(auto dest: lock_okD1) moreover note lock_actions_ok_has_locks_upd_locks_eq_has_locks[OF lao tt''[symmetric]] ultimately have "has_locks ((redT_updLs ls t \<lbrace>ta\<rbrace>l)f l) t'' = 0" by(auto simp add: expand_fun_eq) with elel ls' ln'' show ?thesis by(auto) next case (Some a) then obtain E X LN where est'': "ts t'' = ⌊((E, X), LN)⌋" by(cases a, auto) with loes have IH: "has_locks (lsf l) t'' + LNf l = expr_locks E l" by(auto dest: lock_okD2) from est est'' es' tt'' cctta have "ts' t'' = ⌊((E, X), LN)⌋" apply(simp) apply(rule redT_updTs_Some) by(simp_all) with ts't'' es' have e'': "E = e''" and x'': "X = x''" and ln'': "ln'' = LN" by(simp_all) with lock_actions_ok_has_locks_upd_locks_eq_has_locks[OF lao tt''[symmetric]] IH ls' show ?thesis by(clarsimp simp add: redT_updLs_def expand_fun_eq) qed qed qed next case (acquire a ln n) note [simp] = `ta = (λf [], [], [], [], ReacquireLocks ln)` `ws' = ws` `h' = h` obtain e x where [simp]: "a = (e, x)" by (cases a, auto) note ls' = `ls' = acquire_all ls t ln` from `ts' = ts(t \<mapsto> (a, no_wait_locks))` have ts': "ts' = ts(t \<mapsto> ((e, x), no_wait_locks))" by simp from `ts t = ⌊(a, ln)⌋` have tst: "ts t = ⌊((e, x), ln)⌋" by simp show ?thesis proof(rule lock_okI) fix t'' l assume rtutes: "ts' t'' = None" with ts' have tst'': "ts t'' = None" by(simp split: split_if_asm) with tst have tt'': "t ≠ t''" by auto from tst'' loes have "has_locks (lsf l) t'' = 0" by(auto dest: lock_okD1) thus "has_locks (ls'f l) t'' = 0" by(simp add: red_mthr.redT_has_locks_inv[OF redT tt'']) next fix t'' e'' x'' ln'' l assume ts't'': "ts' t'' = ⌊((e'', x''), ln'')⌋" show "has_locks (ls'f l) t'' + ln''f l = expr_locks e'' l" proof(cases "t = t''") case True note [simp] = this with ts't'' ts' tst have [simp]: "ln'' = no_wait_locks" "e = e''" by auto from tst loes have "has_locks (lsf l) t + lnf l = expr_locks e l" by(auto dest: lock_okD2) show ?thesis proof(cases "lnf l > 0") case True with `may_acquire_all ls t ln` ls' have "may_lock (lsf l) t" by(auto elim: may_acquire_allE) with ls' have "has_locks (ls'f l) t = has_locks (lsf l) t + lnf l" by(simp add: has_locks_acquire_locks_conv) with `has_locks (lsf l) t + lnf l = expr_locks e l` show ?thesis by(simp) next case False hence "lnf l = 0" by simp with ls' have "has_locks (ls'f l) t = has_locks (lsf l) t" by(simp) with `has_locks (lsf l) t + lnf l = expr_locks e l` `lnf l = 0` show ?thesis by(simp) qed next case False with ts' ts't'' have tst'': "ts t'' = ⌊((e'', x''), ln'')⌋" by(simp) with loes have "has_locks (lsf l) t'' + ln''f l = expr_locks e'' l" by(auto dest: lock_okD2) show ?thesis proof(cases "lnf l > 0") case False with `t ≠ t''` ls' have "has_locks (ls'f l) t'' = has_locks (lsf l) t''" by(simp) with `has_locks (lsf l) t'' + ln''f l = expr_locks e'' l` show ?thesis by(simp) next case True with `may_acquire_all ls t ln` have "may_lock (lsf l) t" by(auto elim: may_acquire_allE) with ls' `t ≠ t''` have "has_locks (ls'f l) t'' = has_locks (lsf l) t''" by(simp add: has_locks_acquire_locks_conv') with ls' `has_locks (lsf l) t'' + ln''f l = expr_locks e'' l` show ?thesis by(simp) qed qed qed qed thus ?thesis by simp qed lemma RedT_preserves_lock_ok: assumes wf: "wf_J_prog P" and Red: "P \<turnstile> s -\<triangleright>ttas->* s'" and ae: "sync_es_ok (thr s) (shr s)" and loes: "lock_ok (locks s) (thr s)" shows "lock_ok (locks s') (thr s')" using Red ae loes proof(induct rule: red_mthr.RedT_induct[consumes 1, case_names refl step]) case refl thus ?case by blast next case step thus ?case apply - apply(erule redT_preserves_lock_ok[OF wf], assumption) by(auto dest: RedT_preserves_sync_ok[OF wf]) qed lemma red_NewThread_Thread_Object: "[| convert_extTA extNTA,P \<turnstile> 〈e, s〉 -ta-> 〈e', s'〉; NewThread t x m ∈ set \<lbrace>ta\<rbrace>t |] ==> ∃C fs. hp s' t = ⌊Obj C fs⌋ ∧ P \<turnstile> C \<preceq>* Thread" and reds_NewThread_Thread_Object: "[| convert_extTA extNTA,P \<turnstile> 〈es, s〉 [-ta->] 〈es', s'〉; NewThread t x m ∈ set \<lbrace>ta\<rbrace>t |] ==> ∃C fs. hp s' t = ⌊Obj C fs⌋ ∧ P \<turnstile> C \<preceq>* Thread" apply(induct rule: red_reds.inducts) apply(fastsimp dest: red_external_new_thread_exists_thread_object)+ done lemma redT_NewThread_Thread_Object: "[| P \<turnstile> s -t'\<triangleright>ta-> s'; NewThread t x m ∈ set \<lbrace>ta\<rbrace>t |] ==> ∃C fs. shr s' t = ⌊Obj C fs⌋ ∧ P \<turnstile> C \<preceq>* Thread" by(auto elim!: red_mthr.redT.cases dest:red_NewThread_Thread_Object) lemma redT_preserves_thread_conf: assumes red: "P \<turnstile> s -t'\<triangleright>ta-> s'" and tc: "thread_conf P (thr s) (shr s)" shows "thread_conf P (thr s') (shr s')" proof(rule thread_confI) fix t xln assume tst': "thr s' t = ⌊xln⌋" obtain e x ln where xln [simp]: "xln = ((e, x), ln)" by(cases xln, auto) show "∃T. typeofshr s' (Addr t) = ⌊T⌋ ∧ P \<turnstile> T ≤ Class Thread" proof(cases "thr s t") case None with red tst' have nt: "NewThread t (e, x) (shr s') ∈ set \<lbrace>ta\<rbrace>t" and [simp]: "ln = no_wait_locks" by(auto dest: red_mthr.redT_new_thread) from red nt obtain C fs where "shr s' t = ⌊Obj C fs⌋" "P \<turnstile> Class C ≤ Class Thread" by(auto dest!: redT_NewThread_Thread_Object) thus ?thesis by(clarsimp) next case (Some Xln) with tc obtain T where "typeofshr s (Addr t) = ⌊T⌋" "P \<turnstile> T ≤ Class Thread" by(rule thread_confDE) moreover from red have "hext (shr s) (shr s')" by(cases s, cases s')(auto intro: redT_hext_incr) ultimately have "typeofshr s' (Addr t) = ⌊T⌋" by(blast dest: type_of_hext_type_of hext_objarrD) with `P \<turnstile> T ≤ Class Thread` show ?thesis by blast qed qed lemma RedT_preserves_thread_conf: "[| P \<turnstile> s -\<triangleright>tta->* s'; thread_conf P (thr s) (shr s) |] ==> thread_conf P (thr s') (shr s')" by(rule red_mthr.RedT_lift_preserveD[OF _ _ redT_preserves_thread_conf]) section {* Interpreting final\_thread\_wf with final *} lemma final_no_red [elim]: "final e ==> ¬ P \<turnstile> 〈e, (h, l)〉 -ta-> 〈e', (h', l')〉" apply(auto elim: red.cases finalE) done lemma final_locks: "final e ==> expr_locks e l = 0" by(auto elim: finalE) lemma final_thread_wf_interp: "final_thread_wf final_expr (mred P)" proof(unfold_locales) fix x m ta x' m' assume "final_expr x" "mred P (x, m) ta (x', m')" moreover obtain e l where e: "x = (e, l)" by (cases x, auto) ultimately have "final e" by simp moreover obtain e' :: expr and l' :: locals where e': "x' = (e', l')" by (cases x', auto) ultimately show "False" using e `mred P (x, m) ta (x', m')` by(auto) qed interpretation red_mthr: final_thread_wf "final_expr" "mred P" for P by(rule final_thread_wf_interp) end