Theory Worklists
theory Worklists
imports
Global_Invariants_Lemmas
Local_Invariants_Lemmas
Tactics
begin
section‹Worklist invariants \label{sec:worklist-invariants} ›
lemma valid_W_invD0:
"⟦ r ∈ W (s p); valid_W_inv s; p ≠ q ⟧ ⟹ r ∉ WL q s"
"⟦ r ∈ W (s p); valid_W_inv s ⟧ ⟹ r ∉ ghost_honorary_grey (s q)"
"⟦ r ∈ ghost_honorary_grey (s p); valid_W_inv s ⟧ ⟹ r ∉ W (s q)"
"⟦ r ∈ ghost_honorary_grey (s p); valid_W_inv s; p ≠ q ⟧ ⟹ r ∉ WL q s"
using marked_not_white unfolding valid_W_inv_def WL_def by (auto 0 5 split: obj_at_splits)
lemma valid_W_distinct_simps:
"⟦r ∈ ghost_honorary_grey (s p); valid_W_inv s⟧ ⟹ (r ∈ ghost_honorary_grey (s q)) ⟷ (p = q)"
"⟦r ∈ W (s p); valid_W_inv s⟧ ⟹ (r ∈ W (s q)) ⟷ (p = q)"
"⟦r ∈ WL p s; valid_W_inv s⟧ ⟹ (r ∈ WL q s) ⟷ (p = q)"
using valid_W_invD0(4) apply fastforce
using valid_W_invD0(1) apply fastforce
apply (metis UnE WL_def valid_W_invD0(1) valid_W_invD0(4))
done
lemma valid_W_inv_sys_mem_store_buffersD:
"⟦ sys_mem_store_buffers p s = mw_Mutate r' f r'' # ws; mw_Mark r fl ∈ set ws; valid_W_inv s ⟧
⟹ fl = sys_fM s ∧ r ∈ ghost_honorary_grey (s p) ∧ tso_locked_by p s ∧ white r s ∧ filter is_mw_Mark ws = [mw_Mark r fl]"
"⟦ sys_mem_store_buffers p s = mw_fA fl' # ws; mw_Mark r fl ∈ set ws; valid_W_inv s ⟧
⟹ fl = sys_fM s ∧ r ∈ ghost_honorary_grey (s p) ∧ tso_locked_by p s ∧ white r s ∧ filter is_mw_Mark ws = [mw_Mark r fl]"
"⟦ sys_mem_store_buffers p s = mw_fM fl' # ws; mw_Mark r fl ∈ set ws; valid_W_inv s ⟧
⟹ fl = sys_fM s ∧ r ∈ ghost_honorary_grey (s p) ∧ tso_locked_by p s ∧ white r s ∧ filter is_mw_Mark ws = [mw_Mark r fl]"
"⟦ sys_mem_store_buffers p s = mw_Phase ph # ws; mw_Mark r fl ∈ set ws; valid_W_inv s ⟧
⟹ fl = sys_fM s ∧ r ∈ ghost_honorary_grey (s p) ∧ tso_locked_by p s ∧ white r s ∧ filter is_mw_Mark ws = [mw_Mark r fl]"
unfolding valid_W_inv_def white_def by (clarsimp dest!: spec[where x=p], blast)+
lemma valid_W_invE2:
"⟦ r ∈ W (s p); valid_W_inv s; ⋀obj. obj_mark obj = sys_fM s ⟹ P obj⟧ ⟹ obj_at P r s"
"⟦ r ∈ ghost_honorary_grey (s p); sys_mem_lock s ≠ Some p; valid_W_inv s; ⋀obj. obj_mark obj = sys_fM s ⟹ P obj ⟧ ⟹ obj_at P r s"
unfolding valid_W_inv_def
apply (simp_all add: split: obj_at_splits)
apply blast+
done
lemma (in sys) valid_W_inv[intro]:
notes if_split_asm[split del]
notes fun_upd_apply[simp]
shows
"⦃ LSTP (fM_rel_inv ❙∧ sys_phase_inv ❙∧ tso_store_inv ❙∧ valid_refs_inv ❙∧ valid_W_inv) ⦄
sys
⦃ LSTP valid_W_inv ⦄"
proof(vcg_jackhammer (no_thin_post_inv), vcg_name_cases)
case (tso_dequeue_store_buffer s s' p w ws) then show ?case
proof(cases w)
case (mw_Mark r fl) with tso_dequeue_store_buffer show ?thesis
apply (subst valid_W_inv_def)
apply clarsimp
apply (frule (1) valid_W_invD(1))
apply (clarsimp simp: all_conj_distrib white_def valid_W_inv_sys_ghg_empty_iff filter_empty_conv obj_at_simps)
apply (intro allI conjI impI)
apply (auto elim: valid_W_invE2)[3]
apply (meson Int_emptyI valid_W_distinct_simps(3))
apply (meson valid_W_invD0(2))
apply (meson valid_W_invD0(2))
using valid_W_invD(2) apply fastforce
apply auto[1]
using valid_W_invD(2) apply fastforce
done
next case (mw_fM fl) with tso_dequeue_store_buffer show ?thesis
apply (clarsimp simp: fM_rel_inv_def fM_rel_def p_not_sys)
apply (elim disjE; clarsimp)
apply (frule (1) no_grey_refs_no_pending_marks)
apply (subst valid_W_inv_def)
apply clarsimp
apply (meson Int_emptyI no_grey_refsD(1) no_grey_refsD(3) valid_W_distinct_simps(3) valid_W_invD(2) valid_W_inv_sys_ghg_empty_iff valid_W_inv_sys_mem_store_buffersD(3))
done
qed simp_all
qed
lemma valid_W_inv_ghg_disjoint:
"⟦ white y s; sys_mem_lock s = Some p; valid_W_inv s; p0 ≠ p1 ⟧
⟹ WL p0 (s(p := s p⦇ghost_honorary_grey := {y}⦈)) ∩ WL p1 (s(p := s p⦇ghost_honorary_grey := {y}⦈)) = {}"
unfolding valid_W_inv_def WL_def by (auto 5 5 simp: fun_upd_apply)
lemma valid_W_inv_mo_co_mark:
"⟦ valid_W_inv s; white y s; sys_mem_lock s = Some p; filter is_mw_Mark (sys_mem_store_buffers p s) = []; p ≠ sys ⟧
⟹ valid_W_inv (s(p := s p⦇ghost_honorary_grey := {y}⦈, sys := s sys⦇mem_store_buffers := (mem_store_buffers (s sys))(p := sys_mem_store_buffers p s @ [mw_Mark y (sys_fM s)])⦈))"
apply (subst valid_W_inv_def)
apply (clarsimp simp: all_conj_distrib fun_upd_apply)
apply (intro allI conjI impI)
apply (auto simp: valid_W_invD valid_W_distinct_simps(3) valid_W_inv_sys_ghg_empty_iff valid_W_invD0 valid_W_inv_ghg_disjoint valid_W_inv_colours)
done
lemma valid_W_inv_mo_co_lock:
"⟦ valid_W_inv s; sys_mem_lock s = None ⟧
⟹ valid_W_inv (s(sys := s sys⦇mem_lock := Some p⦈))"
by (auto simp: valid_W_inv_def fun_upd_apply)
lemma valid_W_inv_mo_co_W:
"⟦ valid_W_inv s; marked y s; ghost_honorary_grey (s p) = {y}; p ≠ sys ⟧
⟹ valid_W_inv (s(p := s p⦇W := insert y (W (s p)), ghost_honorary_grey := {}⦈))"
apply (subst valid_W_inv_def)
apply (clarsimp simp: all_conj_distrib valid_W_invD0(2) fun_upd_apply)
apply (intro allI conjI impI)
apply (auto simp: valid_W_invD valid_W_invD0(2) valid_W_distinct_simps(3))
using valid_W_distinct_simps(1) apply fastforce
apply (metis marked_not_white singletonD valid_W_invD(2))
done
lemma valid_W_inv_mo_co_unlock:
"⟦ sys_mem_lock s = Some p; sys_mem_store_buffers p s = [];
⋀r. r ∈ ghost_honorary_grey (s p) ⟹ marked r s;
valid_W_inv s
⟧ ⟹ valid_W_inv (s(sys := mem_lock_update Map.empty (s sys)))"
unfolding valid_W_inv_def by (clarsimp simp: fun_upd_apply) (metis emptyE empty_set)
lemma (in gc) valid_W_inv[intro]:
notes if_split_asm[split del]
notes fun_upd_apply[simp]
shows
"⦃ gc_mark.mark_object_invL ❙∧ gc_W_empty_invL
❙∧ obj_fields_marked_invL
❙∧ sweep_loop_invL ❙∧ tso_lock_invL
❙∧ LSTP valid_W_inv ⦄
gc
⦃ LSTP valid_W_inv ⦄"
proof(vcg_jackhammer (no_thin_post_inv), vcg_name_cases)
case (sweep_loop_free s s') then show ?case
apply (subst valid_W_inv_def)
apply (clarsimp simp: all_conj_distrib white_def valid_W_inv_sys_ghg_empty_iff)
apply (meson disjoint_iff_not_equal no_grey_refsD(1) no_grey_refsD(2) no_grey_refsD(3) valid_W_invE(5))
done
next case (mark_loop_get_work_load_W s s') then show ?case
apply (subst valid_W_inv_def)
apply (clarsimp simp: all_conj_distrib)
apply (intro allI conjI impI; auto dest: valid_W_invD0 valid_W_invD simp: valid_W_distinct_simps split: if_splits process_name.splits)
done
next case (mark_loop_blacken s s') then show ?case
apply (subst valid_W_inv_def)
apply (clarsimp simp: all_conj_distrib)
apply (intro allI conjI impI; auto dest: valid_W_invD0 valid_W_invD simp: valid_W_distinct_simps split: if_splits process_name.splits)
done
next case (mark_loop_mo_co_W s s' y) then show ?case by - (erule valid_W_inv_mo_co_W; blast)
next case (mark_loop_mo_co_unlock s s' y) then show ?case by - (erule valid_W_inv_mo_co_unlock; simp split: if_splits)
next case (mark_loop_mo_co_mark s s' y) then show ?case by - (erule valid_W_inv_mo_co_mark; blast)
next case (mark_loop_mo_co_lock s s' y) then show ?case by - (erule valid_W_inv_mo_co_lock; assumption+)
next case (mark_loop_get_roots_load_W s s') then show ?case
apply (subst valid_W_inv_def)
apply (clarsimp simp: all_conj_distrib valid_W_inv_sys_ghg_empty_iff)
apply (intro allI conjI impI)
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (clarsimp split: process_name.splits)
apply (meson Int_emptyI Un_iff process_name.distinct(4) valid_W_distinct_simps(3) valid_W_invD0(1))
apply (auto simp: valid_W_invD valid_W_invD0 split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
using valid_W_invD(2) valid_W_inv_sys_ghg_empty_iff apply fastforce
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
apply (auto simp: valid_W_invD valid_W_invD0 valid_W_inv_sys_ghg_empty_iff split: process_name.splits; fail)[1]
done
qed
lemma (in mut_m) valid_W_inv[intro]:
notes if_split_asm[split del]
notes fun_upd_apply[simp]
shows
"⦃ handshake_invL ❙∧ mark_object_invL ❙∧ tso_lock_invL
❙∧ mut_get_roots.mark_object_invL m
❙∧ mut_store_del.mark_object_invL m
❙∧ mut_store_ins.mark_object_invL m
❙∧ LSTP (fM_rel_inv ❙∧ sys_phase_inv ❙∧ valid_refs_inv ❙∧ valid_W_inv) ⦄
mutator m
⦃ LSTP valid_W_inv ⦄"
proof(vcg_jackhammer (no_thin_post_inv), vcg_name_cases)
case (alloc s s' r) then show ?case
apply (subst valid_W_inv_def)
apply (clarsimp simp: all_conj_distrib split: if_split_asm)
apply (intro allI conjI impI)
apply (auto simp: valid_W_distinct_simps valid_W_invD0(3) valid_W_invD(2))
done
next case (store_ins_mo_co_W s s' y) then show ?case by - (erule valid_W_inv_mo_co_W; blast+)
next case (store_ins_mo_co_unlock s s' y) then show ?case by - (erule valid_W_inv_mo_co_unlock; simp split: if_splits)
next case (store_ins_mo_co_mark s s' y) then show ?case by - (erule valid_W_inv_mo_co_mark; blast+)
next case (store_ins_mo_co_lock s s' y) then show ?case by - (erule valid_W_inv_mo_co_lock; assumption+)
next case (store_del_mo_co_W s s' y) then show ?case by - (erule valid_W_inv_mo_co_W; blast+)
next case (store_del_mo_co_unlock s s' y) then show ?case by - (erule valid_W_inv_mo_co_unlock; simp split: if_splits)
next case (store_del_mo_co_mark s s' y) then show ?case by - (erule valid_W_inv_mo_co_mark; blast+)
next case (store_del_mo_co_lock s s' y) then show ?case by - (erule valid_W_inv_mo_co_lock; assumption+)
next case (hs_get_roots_loop_mo_co_W s s' y) then show ?case by - (erule valid_W_inv_mo_co_W; blast+)
next case (hs_get_roots_loop_mo_co_unlock s s' y) then show ?case by - (erule valid_W_inv_mo_co_unlock; simp split: if_splits)
next case (hs_get_roots_loop_mo_co_mark s s' y) then show ?case by - (erule valid_W_inv_mo_co_mark; blast+)
next case (hs_get_roots_loop_mo_co_lock s s' y) then show ?case by - (erule valid_W_inv_mo_co_lock; assumption+)
next case (hs_get_roots_done s s') then show ?case
apply (subst valid_W_inv_def)
apply (simp add: all_conj_distrib)
apply (intro allI conjI impI; clarsimp simp: valid_W_inv_sys_ghg_empty_iff valid_W_invD(2) valid_W_invD0(2,3) filter_empty_conv dest!: valid_W_invE(5))
apply (fastforce simp: valid_W_distinct_simps split: process_name.splits if_splits)
done
next case (hs_get_work_done s s') then show ?case
apply (subst valid_W_inv_def)
apply (simp add: all_conj_distrib)
apply (intro allI conjI impI; clarsimp simp: valid_W_inv_sys_ghg_empty_iff valid_W_invD(2) valid_W_invD0(2,3) filter_empty_conv dest!: valid_W_invE(5))
apply (fastforce simp: valid_W_distinct_simps split: process_name.splits if_splits)
done
qed
end