Theory StrongTricolour
theory StrongTricolour
imports
Global_Invariants_Lemmas
Local_Invariants_Lemmas
Tactics
begin
context mut_m
begin
lemma marked_insertions_store_ins[simp]:
"⟦ marked_insertions s; (∃r'. opt_r' = Some r') ⟶ marked (the opt_r') s ⟧
⟹ marked_insertions
(s(mutator m := s (mutator m)⦇ghost_honorary_root := {}⦈,
sys := s sys
⦇mem_store_buffers := (mem_store_buffers (s sys))(mutator m := sys_mem_store_buffers (mutator m) s @ [mw_Mutate r f opt_r'])⦈))"
by (auto simp: marked_insertions_def
split: mem_store_action.splits option.splits)
lemma marked_insertions_alloc[simp]:
"⟦ heap (s sys) r' = None; valid_refs_inv s ⟧
⟹ marked_insertions (s(mutator m' := s (mutator m')⦇roots := roots'⦈, sys := s sys⦇heap := (sys_heap s)(r' ↦ obj')⦈))
⟷ marked_insertions s"
apply (clarsimp simp: marked_insertions_def split: mem_store_action.splits option.splits)
apply (rule iffI)
apply clarsimp
apply (rename_tac ref field x)
apply (drule_tac x=ref in spec, drule_tac x=field in spec, drule_tac x=x in spec, clarsimp)
apply (drule valid_refs_invD(6)[where x=r' and y=r'], simp_all)
done
lemma marked_deletions_store_ins[simp]:
"⟦ marked_deletions s; obj_at_field_on_heap (λr'. marked r' s) r f s ⟧
⟹ marked_deletions
(s(mutator m := s (mutator m)⦇ghost_honorary_root := {}⦈,
sys := s sys
⦇mem_store_buffers := (mem_store_buffers (s sys))(mutator m := sys_mem_store_buffers (mutator m) s @ [mw_Mutate r f opt_r'])⦈))"
by (auto simp: marked_deletions_def
split: mem_store_action.splits option.splits)
lemma marked_deletions_alloc[simp]:
"⟦ marked_deletions s; heap (s sys) r' = None; valid_refs_inv s ⟧
⟹ marked_deletions (s(mutator m' := s (mutator m')⦇roots := roots'⦈, sys := s sys⦇heap := (sys_heap s)(r' ↦ obj')⦈))"
apply (clarsimp simp: marked_deletions_def split: mem_store_action.splits)
apply (rename_tac ref field option)
apply (drule_tac x="mw_Mutate ref field option" in spec)
apply clarsimp
apply (case_tac "ref = r'")
apply (auto simp: obj_at_field_on_heap_def split: option.splits)
done
end
subsection‹Sweep loop invariants›
lemma (in gc) sweep_loop_invL_eq_imp:
"eq_imp (λ(_::unit) s. (AT s gc, s↓ gc, sys_fM s↓, map_option obj_mark ∘ sys_heap s↓))
sweep_loop_invL"
apply (clarsimp simp: eq_imp_def inv)
apply (rename_tac s s')
apply (subgoal_tac "∀r. valid_ref r s↓ ⟷ valid_ref r s'↓")
apply (subgoal_tac "∀P r. obj_at (λobj. P (obj_mark obj)) r s↓ ⟷ obj_at (λobj. P (obj_mark obj)) r s'↓")
apply (frule_tac x="λmark. Some mark = gc_mark s'↓" in spec)
apply (frule_tac x="λmark. mark = sys_fM s'↓" in spec)
apply clarsimp
apply (clarsimp simp: fun_eq_iff split: obj_at_splits)
apply (rename_tac r)
apply ( (drule_tac x=r in spec)+, auto)[1]
apply (clarsimp simp: fun_eq_iff split: obj_at_splits)
apply (rename_tac r)
apply (drule_tac x=r in spec, auto)[1]
apply (metis map_option_eq_Some)+
done
lemmas gc_sweep_loop_invL_niE[nie] =
iffD1[OF gc.sweep_loop_invL_eq_imp[simplified eq_imp_simps, rule_format, unfolded conj_explode, rule_format], rotated -1]
lemma (in gc) sweep_loop_invL[intro]:
"⦃ fM_fA_invL ❙∧ phase_invL ❙∧ sweep_loop_invL ❙∧ tso_lock_invL
❙∧ LSTP (phase_rel_inv ❙∧ mutators_phase_inv ❙∧ valid_W_inv) ⦄
gc
⦃ sweep_loop_invL ⦄"
proof(vcg_jackhammer, vcg_name_cases)
case sweep_loop_ref_done then show ?case by blast
next case sweep_loop_check then show ?case
apply (clarsimp split: obj_at_splits)
apply (metis (no_types, lifting) option.collapse option.inject)
done
next case sweep_loop_load_mark then show ?case by (clarsimp split: obj_at_splits)
qed
context gc
begin
lemma sweep_loop_locs_subseteq_sweep_locs:
"sweep_loop_locs ⊆ sweep_locs"
by (auto simp: sweep_loop_locs_def sweep_locs_def intro: append_prefixD)
lemma sweep_locs_subseteq_fM_tso_empty_locs:
"sweep_locs ⊆ fM_tso_empty_locs"
by (auto simp: sweep_locs_def fM_tso_empty_locs_def loc_defs)
lemma sweep_loop_locs_fM_eq_locs:
"sweep_loop_locs ⊆ fM_eq_locs"
by (auto simp: sweep_loop_locs_def fM_eq_locs_def sweep_locs_def loc_defs)
lemma sweep_loop_locs_fA_eq_locs:
"sweep_loop_locs ⊆ fA_eq_locs"
apply (simp add: sweep_loop_locs_def fA_eq_locs_def sweep_locs_def)
apply (intro subset_insertI2)
apply (auto intro: append_prefixD)
done
lemma black_heap_locs_subseteq_fM_tso_empty_locs:
"black_heap_locs ⊆ fM_tso_empty_locs"
by (auto simp: black_heap_locs_def fM_tso_empty_locs_def loc_defs)
lemma black_heap_locs_fM_eq_locs:
"black_heap_locs ⊆ fM_eq_locs"
by (simp add: black_heap_locs_def fM_eq_locs_def loc_defs)
lemma black_heap_locs_fA_eq_locs:
"black_heap_locs ⊆ fA_eq_locs"
by (simp add: black_heap_locs_def fA_eq_locs_def sweep_locs_def loc_defs)
lemma fM_fA_invL_tso_emptyD:
"⟦ atS gc ls s; fM_fA_invL s; ls ⊆ fM_tso_empty_locs ⟧ ⟹ tso_pending_fM gc s↓ = []"
by (auto simp: fM_fA_invL_def dest: atS_mono)
lemma gc_sweep_loop_invL_locsE[rule_format]:
"(atS gc (sweep_locs ∪ black_heap_locs) s ⟶ False) ⟹ gc.sweep_loop_invL s"
apply (simp add: gc.sweep_loop_invL_def atS_un)
apply (auto simp: locset_cache atS_simps dest: atS_mono)
apply (simp add: atS_mono gc.sweep_loop_locs_subseteq_sweep_locs; fail)
apply (clarsimp simp: atS_def)
apply (rename_tac x)
apply (drule_tac x=x in bspec)
apply (auto simp: sweep_locs_def sweep_loop_not_choose_ref_locs_def intro: append_prefixD)
done
end
lemma (in sys) gc_sweep_loop_invL[intro]:
"⦃ gc.fM_fA_invL ❙∧ gc.gc_W_empty_invL ❙∧ gc.sweep_loop_invL
❙∧ LSTP (tso_store_inv ❙∧ valid_W_inv) ⦄
sys
⦃ gc.sweep_loop_invL ⦄"
proof(vcg_jackhammer (keep_locs) (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 -
apply (rule gc.gc_sweep_loop_invL_locsE)
apply (simp only: gc.gc_W_empty_invL_def gc.no_grey_refs_locs_def cong del: atS_state_weak_cong)
apply (clarsimp simp: atS_un)
apply (thin_tac "AT _ = _")
apply (thin_tac "at _ _ _ ⟶ _")+
apply (metis (mono_tags, lifting) filter.simps(2) loc_mem_tac_simps(4) no_grey_refs_no_pending_marks)
done
next case (mw_Mutate r f opt_r') with tso_dequeue_store_buffer show ?thesis by clarsimp (erule gc_sweep_loop_invL_niE; simp add: fun_eq_iff fun_upd_apply)
next case (mw_Mutate_Payload r f pl) with tso_dequeue_store_buffer show ?thesis by clarsimp (erule gc_sweep_loop_invL_niE; simp add: fun_eq_iff fun_upd_apply)
next case (mw_fA fl) with tso_dequeue_store_buffer show ?thesis by - (erule gc_sweep_loop_invL_niE; simp add: fun_eq_iff)
next case (mw_fM fl) with tso_dequeue_store_buffer show ?thesis
apply -
apply (rule gc.gc_sweep_loop_invL_locsE)
apply (case_tac p; clarsimp)
apply (drule (1) gc.fM_fA_invL_tso_emptyD)
apply simp_all
using gc.black_heap_locs_subseteq_fM_tso_empty_locs gc.sweep_locs_subseteq_fM_tso_empty_locs apply blast
done
next case (mw_Phase ph) with tso_dequeue_store_buffer show ?thesis by - (erule gc_sweep_loop_invL_niE; simp add: fun_eq_iff)
qed
qed
lemma (in mut_m) gc_sweep_loop_invL[intro]:
"⦃ gc.fM_fA_invL ❙∧ gc.handshake_invL ❙∧ gc.sweep_loop_invL
❙∧ LSTP (mutators_phase_inv ❙∧ valid_refs_inv) ⦄
mutator m
⦃ gc.sweep_loop_invL ⦄"
proof( vcg_chainsaw (no_thin) gc.fM_fA_invL_def gc.sweep_loop_invL_def gc.handshake_invL_def, vcg_name_cases gc)
case (sweep_loop_locs s s' rb) then show ?case by (metis (no_types, lifting) atS_mono gc.sweep_loop_locs_fA_eq_locs gc.sweep_loop_locs_fM_eq_locs)
next case (black_heap_locs s s' rb) then show ?case by (metis (no_types, lifting) atS_mono gc.black_heap_locs_fA_eq_locs gc.black_heap_locs_fM_eq_locs)
qed
subsection‹ Mutator proofs ›
context mut_m
begin
lemma reachable_snapshot_inv_mo_co_mark[simp]:
"⟦ ghost_honorary_grey (s p) = {}; reachable_snapshot_inv s ⟧
⟹ reachable_snapshot_inv (s(p := s p⦇ ghost_honorary_grey := {r} ⦈))"
unfolding in_snapshot_def reachable_snapshot_inv_def by (auto simp: fun_upd_apply)
lemma reachable_snapshot_inv_hs_get_roots_done:
assumes sti: "strong_tricolour_inv s"
assumes m: "∀r ∈ mut_roots s. marked r s"
assumes ghr: "mut_ghost_honorary_root s = {}"
assumes t: "tso_pending_mutate (mutator m) s = []"
assumes vri: "valid_refs_inv s"
shows "reachable_snapshot_inv
(s(mutator m := s (mutator m)⦇W := {}, ghost_hs_phase := ghp'⦈,
sys := s sys⦇hs_pending := hp', W := sys_W s ∪ mut_W s, ghost_hs_in_sync := in'⦈))"
(is "reachable_snapshot_inv ?s'")
proof(rule, clarsimp)
fix r assume "reachable r s"
then show "in_snapshot r ?s'"
proof (induct rule: reachable_induct)
case (root x) with m show ?case
apply (clarsimp simp: in_snapshot_def)
apply (auto dest: marked_imp_black_or_grey)
done
next
case (ghost_honorary_root x) with ghr show ?case by simp
next
case (tso_root x) with t show ?case
apply (clarsimp simp: filter_empty_conv tso_store_refs_def)
apply (rename_tac w; case_tac w; fastforce)
done
next
case (reaches x y)
from reaches vri have "valid_ref x s" "valid_ref y s"
using reachable_points_to by fastforce+
with reaches sti vri show ?case
apply (clarsimp simp: in_snapshot_def)
apply (elim disjE)
apply (clarsimp simp: strong_tricolour_inv_def)
apply (drule spec[where x=x])
apply clarsimp
apply (auto dest!: marked_imp_black_or_grey)[1]
apply (cases "white y s")
apply (auto dest: grey_protects_whiteE
dest!: marked_imp_black_or_grey)
done
qed
qed
lemma reachable_snapshot_inv_hs_get_work_done:
"reachable_snapshot_inv s
⟹ reachable_snapshot_inv
(s(mutator m := s (mutator m)⦇W := {}⦈,
sys := s sys⦇hs_pending := pending', W := sys_W s ∪ mut_W s,
ghost_hs_in_sync := (ghost_hs_in_sync (s sys))(m := True)⦈))"
by (simp add: reachable_snapshot_inv_def in_snapshot_def grey_protects_white_def)
lemma reachable_snapshot_inv_deref_del:
"⟦ reachable_snapshot_inv s; sys_load (mutator m) (mr_Ref r f) (s sys) = mv_Ref opt_r'; r ∈ mut_roots s; mut_ghost_honorary_root s = {} ⟧
⟹ reachable_snapshot_inv (s(mutator m := s (mutator m)⦇ghost_honorary_root := Option.set_option opt_r', ref := opt_r'⦈))"
unfolding reachable_snapshot_inv_def in_snapshot_def grey_protects_white_def by (clarsimp simp: fun_upd_apply)
lemma mutator_phase_inv[intro]:
notes fun_upd_apply[simp]
notes reachable_snapshot_inv_deref_del[simp]
notes if_split_asm[split del]
shows
"⦃ handshake_invL
❙∧ mark_object_invL
❙∧ mut_get_roots.mark_object_invL m
❙∧ mut_store_del.mark_object_invL m
❙∧ mut_store_ins.mark_object_invL m
❙∧ LSTP (handshake_phase_inv ❙∧ mutators_phase_inv ❙∧ phase_rel_inv ❙∧ sys_phase_inv ❙∧ fA_rel_inv ❙∧ fM_rel_inv ❙∧ valid_refs_inv ❙∧ strong_tricolour_inv ❙∧ valid_W_inv) ⦄
mutator m
⦃ LSTP mutator_phase_inv ⦄"
proof( vcg_jackhammer (no_thin_post_inv)
, simp_all add: mutator_phase_inv_aux_case split: hs_phase.splits
, vcg_name_cases)
case alloc then show ?case
apply (drule_tac x=m in spec)
apply (drule handshake_phase_invD)
apply (clarsimp simp: fA_rel_inv_def fM_rel_inv_def fM_rel_def hp_step_rel_def split: if_split_asm)
apply (intro conjI impI; simp)
apply (elim disjE; force simp: fA_rel_def)
apply (rule reachable_snapshot_inv_alloc, simp_all)
apply (elim disjE; force simp: fA_rel_def)
done
next case (store_ins s s') then show ?case
apply (drule_tac x=m in spec)
apply (drule handshake_phase_invD)
apply (intro conjI impI; clarsimp)
apply (rule marked_deletions_store_ins, assumption)
apply (cases "(∀opt_r'. mw_Mutate (mut_tmp_ref s↓) (mut_field s↓) opt_r' ∉ set (sys_mem_store_buffers (mutator m) s↓))"; clarsimp)
apply (force simp: marked_deletions_def)
apply (erule marked_insertions_store_ins)
apply (drule phase_rel_invD)
apply (clarsimp simp: phase_rel_def hp_step_rel_def; elim disjE; fastforce dest: reachable_blackD elim: blackD; fail)
apply (rule marked_deletions_store_ins; clarsimp)
apply (erule disjE; clarsimp)
apply (drule phase_rel_invD)
apply (clarsimp simp: phase_rel_def)
apply (elim disjE; clarsimp)
apply (fastforce simp: hp_step_rel_def)
apply (clarsimp simp: hp_step_rel_def)
apply (case_tac "sys_ghost_hs_phase s↓"; clarsimp)
apply (clarsimp simp: obj_at_field_on_heap_def split: option.splits)
apply (rule conjI, fast, clarsimp)
apply (frule_tac r=x2a in blackD(1)[OF reachable_blackD], simp_all)[1]
apply (rule_tac x="mut_tmp_ref s↓" in reachable_points_to; auto simp: ran_def split: obj_at_splits; fail)
apply (clarsimp simp: obj_at_field_on_heap_def split: option.splits)
apply (rule conjI, fast, clarsimp)
apply (frule_tac r=x2a in blackD(1)[OF reachable_blackD], simp_all)[1]
apply (rule_tac x="mut_tmp_ref s↓" in reachable_points_to; auto simp: ran_def split: obj_at_splits; fail)
apply (force simp: marked_deletions_def)
done
next case (hs_noop_done s s') then show ?case
apply -
apply (drule_tac x=m in spec)
apply (drule handshake_phase_invD)
apply (simp add: fA_rel_def fM_rel_def hp_step_rel_def)
apply (cases "mut_ghost_hs_phase s↓")
apply auto
done
next case (hs_get_roots_done s s') then show ?case
apply -
apply (drule_tac x=m in spec)
apply (drule handshake_phase_invD)
apply (force simp: hp_step_rel_def reachable_snapshot_inv_hs_get_roots_done)
done
next case (hs_get_work_done s s') then show ?case
apply (drule_tac x=m in spec)
apply (drule handshake_phase_invD)
apply (force simp add: hp_step_rel_def reachable_snapshot_inv_hs_get_work_done)
done
qed
end
lemma (in mut_m') mutator_phase_inv[intro]:
notes mut_m.mark_object_invL_def[inv]
notes mut_m.handshake_invL_def[inv]
notes fun_upd_apply[simp]
shows
"⦃ handshake_invL ❙∧ mut_m.handshake_invL m'
❙∧ mut_m.mark_object_invL m'
❙∧ mut_get_roots.mark_object_invL m'
❙∧ mut_store_del.mark_object_invL m'
❙∧ mut_store_ins.mark_object_invL m'
❙∧ LSTP (fA_rel_inv ❙∧ fM_rel_inv ❙∧ handshake_phase_inv ❙∧ mutators_phase_inv ❙∧ valid_refs_inv) ⦄
mutator m'
⦃ LSTP mutator_phase_inv ⦄"
proof( vcg_jackhammer (no_thin_post_inv)
, simp_all add: mutator_phase_inv_aux_case split: hs_phase.splits
, vcg_name_cases)
case (alloc s s' rb) then show ?case
apply -
apply (clarsimp simp: fA_rel_inv_def fM_rel_inv_def white_def)
apply (drule spec[where x=m])
apply (intro conjI impI; clarsimp)
apply (clarsimp simp: hp_step_rel_def simp: fA_rel_def fM_rel_def dest!: handshake_phase_invD)
apply (elim disjE, auto; fail)
apply (rule reachable_snapshot_inv_alloc, simp_all)
apply (clarsimp simp: hp_step_rel_def simp: fA_rel_def fM_rel_def dest!: handshake_phase_invD)
apply (cases "sys_ghost_hs_phase s↓"; clarsimp; blast)
done
next case (hs_get_roots_done s s') then show ?case
apply -
apply (drule spec[where x=m])
apply (simp add: no_black_refs_def reachable_snapshot_inv_def in_snapshot_def)
done
next case (hs_get_work_done s s') then show ?case
apply -
apply (drule spec[where x=m])
apply (clarsimp simp: no_black_refs_def reachable_snapshot_inv_def in_snapshot_def grey_protects_white_def)
done
qed
lemma no_black_refs_sweep_loop_free[simp]:
"no_black_refs s ⟹ no_black_refs (s(sys := s sys⦇heap := (sys_heap s)(gc_tmp_ref s := None)⦈))"
unfolding no_black_refs_def by simp
lemma no_black_refs_load_W[simp]:
"⟦ no_black_refs s; gc_W s = {} ⟧
⟹ no_black_refs (s(gc := s gc⦇W := sys_W s⦈, sys := s sys⦇W := {}⦈))"
unfolding no_black_refs_def by simp
lemma marked_insertions_sweep_loop_free[simp]:
"⟦ mut_m.marked_insertions m s; white r s ⟧
⟹ mut_m.marked_insertions m (s(sys := (s sys)⦇heap := (heap (s sys))(r := None)⦈))"
unfolding mut_m.marked_insertions_def by (fastforce simp: fun_upd_apply split: mem_store_action.splits obj_at_splits option.splits)
lemma marked_deletions_sweep_loop_free[simp]:
notes fun_upd_apply[simp]
shows
"⟦ mut_m.marked_deletions m s; mut_m.reachable_snapshot_inv m s; no_grey_refs s; white r s ⟧
⟹ mut_m.marked_deletions m (s(sys := s sys⦇heap := (sys_heap s)(r := None)⦈))"
unfolding mut_m.marked_deletions_def
apply (clarsimp split: mem_store_action.splits)
apply (rename_tac ref field option)
apply (drule_tac x="mw_Mutate ref field option" in spec)
apply (clarsimp simp: obj_at_field_on_heap_def split: option.splits)
apply (rule conjI)
apply (clarsimp simp: mut_m.reachable_snapshot_inv_def)
apply (drule spec[where x=r], clarsimp simp: in_snapshot_def)
apply (drule mp, auto simp: mut_m.reachable_def mut_m.tso_store_refs_def split: mem_store_action.splits)[1]
apply (drule grey_protects_whiteD)
apply (clarsimp simp: no_grey_refs_def)
apply (clarsimp; fail)
apply (rule conjI; clarsimp)
apply (rule conjI)
apply (clarsimp simp: mut_m.reachable_snapshot_inv_def)
apply (drule spec[where x=r], clarsimp simp: in_snapshot_def)
apply (drule mp, auto simp: mut_m.reachable_def mut_m.tso_store_refs_def split: mem_store_action.splits)[1]
apply (drule grey_protects_whiteD)
apply (clarsimp simp: no_grey_refs_def)
unfolding white_def apply (clarsimp split: obj_at_splits)
done
context gc
begin
lemma obj_fields_marked_inv_blacken:
"⟦ gc_field_set s = {}; obj_fields_marked s; (gc_tmp_ref s points_to w) s; white w s ⟧ ⟹ False"
by (simp add: obj_fields_marked_def obj_at_field_on_heap_def ran_def white_def split: option.splits obj_at_splits)
lemma obj_fields_marked_inv_has_white_path_to_blacken:
"⟦ gc_field_set s = {}; gc_tmp_ref s ∈ gc_W s; (gc_tmp_ref s has_white_path_to w) s; obj_fields_marked s; valid_W_inv s ⟧ ⟹ w = gc_tmp_ref s"
by (metis (mono_tags, lifting) converse_rtranclpE gc.obj_fields_marked_inv_blacken has_white_path_to_def)
lemma mutator_phase_inv[intro]:
notes fun_upd_apply[simp]
shows
"⦃ fM_fA_invL ❙∧ gc_W_empty_invL ❙∧ handshake_invL ❙∧ obj_fields_marked_invL ❙∧ sweep_loop_invL
❙∧ gc_mark.mark_object_invL
❙∧ LSTP (handshake_phase_inv ❙∧ mutators_phase_inv ❙∧ valid_refs_inv ❙∧ valid_W_inv) ⦄
gc
⦃ LSTP (mut_m.mutator_phase_inv m) ⦄"
proof( vcg_jackhammer (no_thin_post_inv)
, simp_all add: mutator_phase_inv_aux_case white_def split: hs_phase.splits
, vcg_name_cases )
case (sweep_loop_free s s') then show ?case
apply (intro allI conjI impI)
apply (drule mut_m.handshake_phase_invD[where m=m], clarsimp simp: hp_step_rel_def; fail)
apply (rule mut_m.reachable_snapshot_inv_sweep_loop_free, simp_all add: white_def)
done
next case (mark_loop_get_work_load_W s s') then show ?case
apply clarsimp
apply (drule spec[where x=m])
apply (clarsimp simp: mut_m.reachable_snapshot_inv_def in_snapshot_def grey_protects_white_def)
done
next case (mark_loop_blacken s s') then show ?case
apply -
apply (drule spec[where x=m])
apply clarsimp
apply (intro allI conjI impI; clarsimp)
apply (drule mut_m.handshake_phase_invD[where m=m], clarsimp simp: hp_step_rel_def)
apply (clarsimp simp: mut_m.reachable_snapshot_inv_def in_snapshot_def grey_protects_white_def)
apply (metis (no_types, opaque_lifting) obj_fields_marked_inv_has_white_path_to_blacken)
done
next case (mark_loop_mo_co_mark s s' y) then show ?case by (clarsimp simp: handshake_in_syncD mut_m.reachable_snapshot_inv_mo_co_mark)
next case (mark_loop_get_roots_load_W s s') then show ?case
apply clarsimp
apply (drule spec[where x=m])
apply (clarsimp simp: mut_m.reachable_snapshot_inv_def in_snapshot_def grey_protects_white_def)
done
qed
end
lemma (in gc) strong_tricolour_inv[intro]:
notes fun_upd_apply[simp]
shows
"⦃ fM_fA_invL ❙∧ gc_W_empty_invL ❙∧ gc_mark.mark_object_invL ❙∧ obj_fields_marked_invL ❙∧ sweep_loop_invL
❙∧ LSTP (strong_tricolour_inv ❙∧ valid_W_inv) ⦄
gc
⦃ LSTP strong_tricolour_inv ⦄"
unfolding strong_tricolour_inv_def
proof(vcg_jackhammer (no_thin_post_inv), vcg_name_cases)
case (mark_loop_blacken s s' x xa) then show ?case by (fastforce elim!: obj_fields_marked_inv_blacken)
qed
lemma (in mut_m) strong_tricolour[intro]:
notes fun_upd_apply[simp]
shows
"⦃ mark_object_invL
❙∧ mut_get_roots.mark_object_invL m
❙∧ mut_store_del.mark_object_invL m
❙∧ mut_store_ins.mark_object_invL m
❙∧ LSTP (fA_rel_inv ❙∧ fM_rel_inv ❙∧ handshake_phase_inv ❙∧ mutators_phase_inv ❙∧ strong_tricolour_inv ❙∧ sys_phase_inv ❙∧ valid_refs_inv) ⦄
mutator m
⦃ LSTP strong_tricolour_inv ⦄"
unfolding strong_tricolour_inv_def
proof(vcg_jackhammer (no_thin_post_inv), vcg_name_cases)
case (alloc s s' x xa rb) then show ?case
apply (clarsimp simp: fA_rel_inv_def fM_rel_inv_def)
apply (drule handshake_phase_invD)
apply (drule spec[where x=m])
apply (clarsimp simp: sys_phase_inv_aux_case
split: hs_phase.splits if_splits)
apply (blast dest: heap_colours_colours)
apply (metis (no_types, lifting) black_def no_black_refsD obj_at_cong option.simps(3))
apply (metis (no_types, lifting) black_def no_black_refsD obj_at_cong option.distinct(1))
apply (clarsimp simp: hp_step_rel_def)
apply (elim disjE; force simp: fA_rel_def fM_rel_def split: obj_at_splits)
apply (clarsimp simp: hp_step_rel_def)
apply (elim disjE; force simp: fA_rel_def fM_rel_def split: obj_at_splits)
done
qed
end