header {* \isaheader{VCG Invariant} *} theory VCG_Invariant = VCG: --{* In invariantVCG we show that if wpF computes weakest(!) preconditions and if branch conditions of succsF ensure progress then VCG emits invariants. *} locale invariantVCG = VCG + fixes isSafe'::"'prog \ bool" defines "isSafe' \ \ prg. \ s s'. s \ initS prg \ (s,s') \ (effS prg)\<^sup>* \ prg,s' \ saF prg (fst s')" assumes semImpI: "\ prg,s \ f1 \ prg,s \ f2 \ \ prg,s \ f1 \ f2" assumes succsFprogress: "\ wf prg; correctAn prg; isSafe prg; (p,m) \ Reachables prg; prg,(p,m) \ B; (p',B) \ set (succsF prg p'') \ \ p=p'' \ (\ m'. ((p,m),(p',m')) \ (effS prg))" assumes completeWpF: "\ wf prg; correctAn prg; isSafe prg; (p,m) \ Reachables prg; ((p,m),(p',m')) \ (effS prg) ; prg,(p',m') \ Q; \ B. (p',B) \ set (succsF prg p) \ \ prg,(p,m) \ wpF prg p p' Q" assumes ipc_domC: "wf prg \ ipc prg \ set (domC prg)" assumes succsF_domC: "\ wf \; (p',B) \ set (succsF \ p) \ \ (p \ set (domC \)) \ (p' \ set (domC \))" (* lemma (in invariantVCG) paths_domC: "\ wf \ ; cfp \ paths (succsF \) \ \ (\ p \ set cfp. p \ set (domC \))" apply (erule paths.induct) apply (subgoal_tac "pc \ set (domC \) \ pc' \ set (domC \)") prefer 2 apply (rule succsF_domC) apply simp apply simp apply simp apply (rule ballI) apply (erule_tac x="p" in ballE) apply simp apply (subgoal_tac "pc \ set (domC \) \ pc' \ set (domC \)") prefer 2 apply (rule succsF_domC) apply simp apply simp apply simp done *) lemma (in invariantVCG) isSafe'_correctAn_isSafe: "isSafe' \ = (isSafe \ \ correctAn \)" (*<*) apply (rule iffI) apply (rule conjI) apply (simp only: isSafe'_def isSafe_def Reachables_conv saF_def semConj) apply fastsimp apply (simp only: isSafe'_def correctAn_def Reachables_conv saF_def semConj) apply fastsimp apply (simp only: isSafe'_def correctAn_def isSafe_def Reachables_conv saF_def semConj) apply fastsimp done (*>*) (*<*) lemma (in invariantVCG) isSafe_correctAn_isafeF: "\ S. \ wf \; isSafe \; correctAn \ \ \ (\ s \ Reachables \. ((\ V. noAnn V (anF \) \ set V \ set S = set (domC \) \ set V \ set S = {} \ (V \ [] \ V@[fst s] \ (paths (succsF \)))) \ ((fst s \ set (domC \)) \ (\,s \ isafeF \ (fst s)))))" apply (subgoal_tac "\ k. length S = k") prefer 2 apply simp apply (erule exE) apply (erule rev_mp)+ apply (simp only: atomize_all) apply (rule forall_switch2) apply (rule allI) apply (rule_tac n="k" in nat_less_induct) apply (rule allI | rule impI | rule ballI | simp add: Let_def split_def)+ apply (erule exE | erule conjE)+ apply (subgoal_tac "\,s \ safeF \ (fst s) \ \,s \ aF \ (fst s)") prefer 2 apply (subgoal_tac "isSafe' \") prefer 2 apply (simp add: isSafe'_correctAn_isSafe) apply (simp add: isSafe'_def Reachables_conv) apply (erule exE | erule conjE)+ apply (erule_tac x="a" in allE) apply (erule_tac x="b" in allE) apply (erule_tac x="fst s" in allE) apply (erule_tac x="snd s" in allE) apply (simp add: saF_def semConj) apply (erule conjE)+ apply (case_tac "anF \ (fst s)") prefer 2 --{* anF Pi (fst s) = Some a *} apply (simp add: isafeFdef semConj aF_def) --{* anF Pi (fst s) = None *} apply (subgoal_tac "\ p m. s = (p,m)") prefer 2 apply fastsimp apply (erule exE)+ apply (case_tac "p \ set S") --{* p in set S *} apply (erule_tac x="length [q \ S. q \ p]" in allE) apply (subgoal_tac "length [q \ S. q \ p] < length S") prefer 2 apply (rule AuxBox.length_filter_less) apply (simp add: set_mem_eq) apply simp apply (erule_tac x="[q \ S. q \ p]" in allE) apply simp apply (subgoal_tac "(p,m) \ Reachables \") prefer 2 apply (simp only: Reachables_conv) apply (simplesubst isafeFdef) apply assumption apply (simp add: semConj) apply (rule ballI) apply (subgoal_tac "\ p' B. x = (p',B)") prefer 2 apply fastsimp apply (erule exE)+ apply (simp only: split_def snd_conv) apply (rule semImpI) apply (subgoal_tac "p = p \ (\ m'. ((p,m),(p',m')) \ (effS \))") prefer 2 apply (rule_tac B="B" in succsFprogress) apply assumption apply simp apply simp apply simp apply simp apply simp apply (erule conjE | erule exE)+ apply (subgoal_tac "(p',m') \ Reachables \") prefer 2 apply (simp add: Reachables_def) apply (rule_tac a="(p,m)" in ReachableFrom.step) apply simp apply simp apply (subgoal_tac "\,(p',m') \ isafeF \ p'") prefer 2 apply (subgoal_tac "(\V. noAnn V (anF \) \ set V \ {x \ set S. x \ fst s} = set (domC \) \ set V \ {x \ set S. x \ fst s} = {} \ (V \ [] \ V @ [fst (p', m')] \ paths (succsF \)))") prefer 2 apply (rule_tac x="V@[p]" in exI) apply (rule conjI) apply (rule noAnn_ext) apply simp+ apply (rule conjI) apply (simplesubst insert_union_right) apply (simplesubst insert_set_filter) apply (subgoal_tac "insert p (set S) = set S") prefer 2 apply (simp add: set_mem_eq insert_absorb) apply (simp only:) apply (rule conjI) apply (subgoal_tac "set V \ {x. x \ set S \ x \ p} \ set V \ set S") prefer 2 apply (rule intersect_mono) apply simp apply (case_tac "V") apply simp apply (rule paths.start) apply simp apply simp apply (subgoal_tac "(a # list) @ [p] @ [p'] \ paths (succsF \)") prefer 2 apply (rule paths.step) apply simp apply simp apply simp apply simp apply (subgoal_tac "p' \ set (domC \)") prefer 2 apply (rule succsF_domC[THEN conjE]) apply simp apply simp apply simp apply (erule_tac x="(p',m')" in ballE) prefer 2 apply simp apply simp apply (subgoal_tac "\,(p, m) \ wpF \ p p' (isafeF \ p')") prefer 2 apply (rule completeWpF) apply assumption apply assumption apply assumption apply assumption apply assumption apply assumption apply simp apply (rule_tac x="B" in exI) apply simp apply simp --{* fst notin set S *} apply (subgoal_tac "noAnn (V@[p]) (anF \)") prefer 2 apply (rule noAnn_ext) apply simp apply simp apply (subgoal_tac "p \ set V") prefer 2 apply (drule_tac t="set (domC \)" in sym) apply simp --{* p in V and noAnn V@[p] contradicts wf Pi, which enforces loop annotations. *} apply (frule wf_anF) apply (unfold enoughAn_def) apply (simp only: in_set_conv_decomp) apply (erule exE | erule conjE)+ apply (erule_tac x="p # zsa @ [p]" in allE) apply (simp add: isCycle_def) apply (subgoal_tac "p # zsa @ [p] \ (paths (succsF \))") prefer 2 apply (rule_tac ps="ysa" in paths_append) apply simp apply (case_tac "ysa") apply simp apply simp apply simp apply simp apply (simp add:noAnn_def) done (*>*) lemma (in invariantVCG) isSafe'_isafeF: "\ wf \; isSafe' \; s \ initS \; (s,s') \ (effS \)\<^sup>* ; fst s' \ set (domC \)\ \ \,s' \ isafeF \ (fst s')" (*<*) apply (simp only: isSafe'_correctAn_isSafe) apply (drule_tac S="domC \" in isSafe_correctAn_isafeF) apply simp apply simp apply (erule_tac x="s'" in ballE) prefer 2 apply (simp add: Reachables_conv) apply (erule_tac x="fst s" in allE) apply (erule_tac x="snd s" in allE) apply simp apply (subgoal_tac "(\V. noAnn V (anF \) \ set V \ set (domC \) = set (domC \) \ set V \ set (domC \) = {} \ (V \ [] \ V @ [fst s'] \ paths (succsF \)))") prefer 2 apply (rule_tac x="[]" in exI) apply (simp add: noAnn_def) apply simp done (*>*) lemma (in invariantVCG) vcg_invariant: "\ wf \; isSafe' \ \ \ (\ s \ Reachables \. \,s \ vcg \)" (*<*) apply (rule ballI) apply (subgoal_tac "\ p m. s = (p,m)") prefer 2 apply simp apply (erule exE)+ apply (simp add: vcgdef semConj) apply (rule conjI) apply (rule semImpI) apply (subgoal_tac "(s,s) \ (effS \)\<^sup>*") prefer 2 apply (rule rtrancl.intros) apply (frule initF_ipc) apply assumption apply (drule_tac t="ipc \" in sym) apply simp apply (simp add: Reachables_conv) apply (erule exE | erule conjE)+ apply (rename_tac "s" "p" "m" "p0" "m0") apply (frule_tac s="(p0,m0)" and s'="(p,m)" in isSafe'_isafeF) apply assumption apply simp apply assumption+ apply (drule ipc_domC) apply simp apply simp apply (rule ballI) apply (rule ballI) apply (subgoal_tac "\ p' B. xa = (p',B)") prefer 2 apply simp apply (erule exE)+ apply (simp only: split_def fst_conv snd_conv) apply (rule semImpI) apply (simp add: semConj) apply (erule conjE)+ apply (subgoal_tac "p=x \ (\ m'. ((p,m),(p',m')) \ (effS \))") prefer 2 apply (rule_tac p''="x" and B="B" in succsFprogress) apply (simp add: isSafe'_correctAn_isSafe)+ apply (erule exE | erule conjE)+ apply (drule_tac t="x" in sym) apply (simp only:) apply (rule completeWpF) apply (simp add: isSafe'_correctAn_isSafe)+ apply (simp add: Reachables_conv) apply (erule exE | erule conjE)+ apply (rename_tac "s" "p" "m" "x" "xa" "p'" "B" "m'" "p0" "m0") apply (frule_tac s="(p0,m0)" and s'="(p',m')" in isSafe'_isafeF) apply (simp add: isSafe'_correctAn_isSafe)+ apply (rule succsF_domC[THEN conjE]) apply simp apply simp apply assumption apply simp apply (rule_tac x="B" in exI) apply simp done (*>*) lemma (in invariantVCG) vcg_inv_completeness: "\ wf \; isSafe \; correctAn \; (\ s \ Reachables \. \,s \ vcg \) \ \ \ vcg \ \ \ \ \ vcg \" (*<*) apply (subgoal_tac "isSafe' \") prefer 2 apply (simp add: isSafe'_correctAn_isSafe) apply (drule vcg_invariant) apply simp+ done (*>*) end