Theory J1Deadlock
section ‹Deadlock perservation for the intermediate language›
theory J1Deadlock imports
J1
"../Framework/FWDeadlock"
"../Common/ExternalCallWF"
begin
context J1_heap_base begin
lemma IUF_red_taD:
"True,P,t ⊢1 ⟨e, s⟩ -ta→ ⟨e', s'⟩
⟹ ∃e' ta' s'. False,P,t ⊢1 ⟨e, s⟩ -ta'→ ⟨e', s'⟩ ∧
collect_locks ⦃ta'⦄⇘l⇙ ⊆ collect_locks ⦃ta⦄⇘l⇙ ∧ set ⦃ta'⦄⇘c⇙ ⊆ set ⦃ta⦄⇘c⇙ ∧ collect_interrupts ⦃ta'⦄⇘i⇙ ⊆ collect_interrupts ⦃ta⦄⇘i⇙ ∧
(∃s. Red1_mthr.actions_ok s t ta')"
and IUFs_reds_taD:
"True,P,t ⊢1 ⟨es, s⟩ [-ta→] ⟨es', s'⟩
⟹ ∃es' ta' s'. False,P,t ⊢1 ⟨es, s⟩ [-ta'→] ⟨es', s'⟩ ∧
collect_locks ⦃ta'⦄⇘l⇙ ⊆ collect_locks ⦃ta⦄⇘l⇙ ∧ set ⦃ta'⦄⇘c⇙ ⊆ set ⦃ta⦄⇘c⇙ ∧ collect_interrupts ⦃ta'⦄⇘i⇙ ⊆ collect_interrupts ⦃ta⦄⇘i⇙ ∧
(∃s. Red1_mthr.actions_ok s t ta')"
proof(induct rule: red1_reds1.inducts)
case Red1InstanceOf thus ?case
using [[hypsubst_thin = true]]
by(auto intro!: exI red1_reds1.Red1InstanceOf simp del: split_paired_Ex)((subst fst_conv snd_conv wset_def)+, simp)
next
case Red1CallExternal thus ?case
by(fastforce simp del: split_paired_Ex dest: red_external_ta_satisfiable[where final="final_expr1 :: ('addr expr1 × 'addr val list) × ('addr expr1 × 'addr val list) list ⇒ bool"] intro: red1_reds1.Red1CallExternal)
next
case Lock1Synchronized thus ?case
by(auto intro!: exI exI[where x="(K$ None, (Map.empty, undefined), Map.empty, {})"] red1_reds1.Lock1Synchronized simp del: split_paired_Ex simp add: lock_ok_las_def finfun_upd_apply may_lock.intros(1))
next
case (Synchronized1Red2 e s ta e' s' V a)
then obtain e' ta' s'
where "False,P,t ⊢1 ⟨e,s⟩ -ta'→ ⟨e',s'⟩"
and L: "collect_locks ⦃ta'⦄⇘l⇙ ⊆ collect_locks ⦃ta⦄⇘l⇙ ∧ set ⦃ta'⦄⇘c⇙ ⊆ set ⦃ta⦄⇘c⇙ ∧ collect_interrupts ⦃ta'⦄⇘i⇙ ⊆ collect_interrupts ⦃ta⦄⇘i⇙"
and aok: "∃s. Red1_mthr.actions_ok s t ta'"
by blast
from ‹False,P,t ⊢1 ⟨e,s⟩ -ta'→ ⟨e',s'⟩› have "False,P,t ⊢1 ⟨insync⇘V⇙ (a) e, s⟩ -ta'→ ⟨insync⇘V⇙ (a) e', s'⟩"
by(rule red1_reds1.Synchronized1Red2)
thus ?case using L aok by blast
next
case Unlock1Synchronized thus ?case
by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ ⌊(t, 0)⌋, (Map.empty, undefined), Map.empty, {})"] red1_reds1.Unlock1Synchronized simp add: lock_ok_las_def finfun_upd_apply)
next
case Unlock1SynchronizedFail thus ?case
by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ ⌊(t, 0)⌋, (Map.empty, undefined), Map.empty, {})"] red1_reds1.Unlock1Synchronized simp add: lock_ok_las_def finfun_upd_apply collect_locks_def split: if_split_asm)
next
case Synchronized1Throw2 thus ?case
by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ ⌊(t, 0)⌋, (Map.empty, undefined), Map.empty, {})"] red1_reds1.Synchronized1Throw2 simp add: lock_ok_las_def finfun_upd_apply)
next
case Synchronized1Throw2Fail thus ?case
by(auto simp del: split_paired_Ex intro!: exI exI[where x="(K$ ⌊(t, 0)⌋, (Map.empty, undefined), Map.empty, {})"] red1_reds1.Synchronized1Throw2 simp add: lock_ok_las_def finfun_upd_apply collect_locks_def split: if_split_asm)
qed(fastforce intro: red1_reds1.intros)+
lemma IUF_Red1_taD:
assumes "True,P,t ⊢1 ⟨ex/exs, h⟩ -ta→ ⟨ex'/exs', h'⟩"
shows "∃ex' exs' h' ta'. False,P,t ⊢1 ⟨ex/exs, h⟩ -ta'→ ⟨ex'/exs', h'⟩ ∧
collect_locks ⦃ta'⦄⇘l⇙ ⊆ collect_locks ⦃ta⦄⇘l⇙ ∧ set ⦃ta'⦄⇘c⇙ ⊆ set ⦃ta⦄⇘c⇙ ∧ collect_interrupts ⦃ta'⦄⇘i⇙ ⊆ collect_interrupts ⦃ta⦄⇘i⇙ ∧
(∃s. Red1_mthr.actions_ok s t ta')"
using assms
apply(cases)
apply(safe dest!: IUF_red_taD)
apply(simp del: split_paired_Ex)
apply(rule exI conjI)+
apply(erule red1Red)
apply simp
apply blast
apply(rule exI conjI red1Call)+
apply(auto simp add: lock_ok_las_def)
apply(rule exI conjI red1Return)+
apply auto
done
lemma mred1'_mred1_must_sync_eq:
"Red1_mthr.must_sync False P t x (shr s) = Red1_mthr.must_sync True P t x (shr s)"
proof
assume "Red1_mthr.must_sync False P t x (shr s)"
thus "Red1_mthr.must_sync True P t x (shr s)"
by(rule Red1_mthr.must_syncE)(rule Red1_mthr.must_syncI, auto simp add: split_def simp del: split_paired_Ex intro: Red1_False_into_Red1_True)
next
assume "Red1_mthr.must_sync True P t x (shr s)"
thus "Red1_mthr.must_sync False P t x (shr s)"
apply(rule Red1_mthr.must_syncE)
apply(rule Red1_mthr.must_syncI)
apply(cases x)
apply(auto simp add: split_beta split_paired_Ex)
apply(drule IUF_Red1_taD)
apply simp
apply blast
done
qed
lemma Red1_Red1'_deadlock_inv:
"Red1_mthr.deadlock True P s = Red1_mthr.deadlock False P s"
proof(rule iffI)
assume dead: "Red1_mthr.deadlock True P s"
show "Red1_mthr.deadlock False P s"
proof(rule multithreaded_base.deadlockI)
fix t x
assume tst: "thr s t = ⌊(x, no_wait_locks)⌋"
and nfin: "¬ final_expr1 x"
and wst: "wset s t = None"
with dead obtain ms: "Red1_mthr.must_sync True P t x (shr s)"
and cs [rule_format]: "∀LT. Red1_mthr.can_sync True P t x (shr s) LT ⟶
(∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
by(rule Red1_mthr.deadlockD1)
from ms[folded mred1'_mred1_must_sync_eq]
show "Red1_mthr.must_sync False P t x (shr s) ∧
(∀LT. Red1_mthr.can_sync False P t x (shr s) LT ⟶
(∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s))))"
proof
show "∀LT. Red1_mthr.can_sync False P t x (shr s) LT ⟶
(∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
proof(intro strip)
fix LT
assume "Red1_mthr.can_sync False P t x (shr s) LT"
then obtain ta x' m' where "mred1' P t (x, shr s) ta (x', m')"
and [simp]: "LT = collect_locks ⦃ta⦄⇘l⇙ <+> collect_cond_actions ⦃ta⦄⇘c⇙ <+> collect_interrupts ⦃ta⦄⇘i⇙"
by(rule Red1_mthr.can_syncE)
hence "mred1 P t (x, shr s) ta (x', m')" by(auto simp add: split_beta intro: Red1_False_into_Red1_True)
hence "Red1_mthr.can_sync True P t x (shr s) LT" by(rule Red1_mthr.can_syncI) simp
thus "∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s))" by(rule cs)
qed
qed
next
fix t x ln l
assume "thr s t = ⌊(x, ln)⌋" "0 < ln $ l" "¬ waiting (wset s t)"
thus "∃l t'. 0 < ln $ l ∧ t ≠ t' ∧ thr s t' ≠ None ∧ has_lock ((locks s) $ l) t'"
by(rule Red1_mthr.deadlockD2[OF dead]) blast
next
fix t x w
assume "thr s t = ⌊(x, no_wait_locks)⌋"
thus "wset s t ≠ ⌊PostWS w⌋"
by(rule Red1_mthr.deadlockD3[OF dead, rule_format])
qed
next
assume dead: "Red1_mthr.deadlock False P s"
show "Red1_mthr.deadlock True P s"
proof(rule Red1_mthr.deadlockI)
fix t x
assume tst: "thr s t = ⌊(x, no_wait_locks)⌋"
and nfin: "¬ final_expr1 x"
and wst: "wset s t = None"
with dead obtain ms: "Red1_mthr.must_sync False P t x (shr s)"
and cs [rule_format]: "∀LT. Red1_mthr.can_sync False P t x (shr s) LT ⟶
(∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
by(rule Red1_mthr.deadlockD1)
from ms[unfolded mred1'_mred1_must_sync_eq]
show "Red1_mthr.must_sync True P t x (shr s) ∧
(∀LT. Red1_mthr.can_sync True P t x (shr s) LT ⟶
(∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s))))"
proof
show "∀LT. Red1_mthr.can_sync True P t x (shr s) LT ⟶
(∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s)))"
proof(intro strip)
fix LT
assume "Red1_mthr.can_sync True P t x (shr s) LT"
then obtain ta x' m' where "mred1 P t (x, shr s) ta (x', m')"
and [simp]: "LT = collect_locks ⦃ta⦄⇘l⇙ <+> collect_cond_actions ⦃ta⦄⇘c⇙ <+> collect_interrupts ⦃ta⦄⇘i⇙"
by(rule Red1_mthr.can_syncE)
then obtain e xs exs e' xs' exs' where x [simp]: "x = ((e, xs), exs)" "x' = ((e', xs'), exs')"
and red: "True,P,t ⊢1 ⟨(e, xs)/exs, shr s⟩ -ta→ ⟨(e', xs')/exs', m'⟩" by(cases x, cases x') fastforce
from IUF_Red1_taD[OF red] obtain ex'' exs'' h'' ta'
where red': "False,P,t ⊢1 ⟨(e, xs)/exs,shr s⟩ -ta'→ ⟨ex''/exs'',h''⟩"
and "collect_locks ⦃ta'⦄⇘l⇙ <+> collect_cond_actions ⦃ta'⦄⇘c⇙ <+> collect_interrupts ⦃ta'⦄⇘i⇙ ⊆ collect_locks ⦃ta⦄⇘l⇙ <+> collect_cond_actions ⦃ta⦄⇘c⇙ <+> collect_interrupts ⦃ta⦄⇘i⇙"
by auto blast
then obtain LT' where cs': "Red1_mthr.can_sync False P t x (shr s) LT'"
and LT': "LT' ⊆ LT" by(cases ex'')(fastforce intro!: Red1_mthr.can_syncI)
with cs[of LT'] show "∃lt∈LT. final_thread.must_wait final_expr1 s t lt (dom (thr s))" by auto
qed
qed
next
fix t x ln l
assume "thr s t = ⌊(x, ln)⌋" "0 < ln $ l" "¬ waiting (wset s t)"
thus "∃l t'. 0 < ln $ l ∧ t ≠ t' ∧ thr s t' ≠ None ∧ has_lock ((locks s) $ l) t'"
by(rule Red1_mthr.deadlockD2[OF dead]) blast
next
fix t x w
assume "thr s t = ⌊(x, no_wait_locks)⌋"
thus "wset s t ≠ ⌊PostWS w⌋"
by(rule Red1_mthr.deadlockD3[OF dead, rule_format])
qed
qed
end
end