header {* \isaheader{VCG Completeness} *} theory VCG_Completeness = VCG: --{* In completeVCG we show that verification conditions are tautologies. If the safety logic is complete, this means they are provable. *} locale completeVCG = VCG + fixes Starters::"'program \ ('pos \ 'mem) set" defines "Starters \ \ {s. \,s \ initF \ \ (\ A. anF \ (fst s) = Some A \ \,s \ A \ \,s \ safeF \ (fst s))}" fixes branch :: "'program \ (('pos \ 'mem) \ ('pos \ 'mem)) set" defines "branch \ \ {(s,s'). \B. (fst s',B) \ set (succsF \ (fst s)) \ \,s \ B}" fixes effS\<^isub>B:: "'program \ (('pos \ 'mem) \ ('pos \ 'mem)) set" defines "effS\<^isub>B \ \ (effS \) \ (branch \)" fixes strongAn:: "'program \ bool" defines "strongAn \ \ (\s \ ReachableFrom (effS\<^isub>B \) (Starters \). \,s \ aF \ (fst s) \ \,s \ safeF \ (fst s))" assumes semImpI: "\ wf \; \,s \ f \ \,s \ f' \ \ \,s \ f \ f'" assumes succsFprogress: "\ wf \; \,(p,m) \ B; (p',B) \ set (succsF \ p'') \ \ p=p'' \ (\ m'. ((p,m),(p',m')) \ (effS \))" assumes completeWpF: "\ wf \; (p',B) \ set (succsF \ p); \,(p,m) \ B; ((p,m),(p',m')) \ (effS \); \,(p',m') \ Q \ \ \,(p,m) \ wpF \ p p' Q" assumes ipc_domC: "wf \ \ ipc \ \ set (domC \)" assumes succsF_domC: "\ wf \; (p',B) \ set (succsF \ p) \ \ (p \ set (domC \)) \ (p' \ set (domC \))" lemma (in completeVCG) ReachableFrom_isafeF_aux: "\ S. \ wf \; strongAn \ \ \ (\ s \ ReachableFrom (effS\<^isub>B \) (Starters \). ((\ 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)))))" --{* S contains positions not yet visited by isafeF. It decreases as isafeF expands. *} (*<*) 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 (simp add: strongAn_def) apply (erule conjE)+ apply (subgoal_tac "fst s \ set (domC \)") prefer 2 apply assumption 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 (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 assumption 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 (erule conjE | erule exE)+ apply (subgoal_tac "(p',m') \ ReachableFrom (effS\<^isub>B \) (Starters \)") prefer 2 apply (rule_tac a="(p,m)" in ReachableFrom.step) apply simp apply (simp add: effS\<^isub>B_def branch_def) apply fastsimp apply (erule_tac x="(p',m')" in ballE) prefer 2 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 (drule mp, assumption) apply assumption apply (subgoal_tac "\,(p, m) \ wpF \ p p' (isafeF \ p')") prefer 2 apply (rule_tac B="B" in completeWpF) apply assumption apply assumption apply assumption apply assumption apply assumption apply assumption 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 (*>*) theorem (in completeVCG) ReachableFrom_isafeF: "\ wf \; strongAn \ \ \ (\s \ ReachableFrom (effS\<^isub>B \) (Starters \). (fst s \ set (domC \)) \ \,s \ isafeF \ (fst s))" (*<*) apply (drule_tac S="domC \" in ReachableFrom_isafeF_aux) apply assumption apply (rule ballI) apply (erule_tac x="s" in ballE) prefer 2 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 (*>*) theorem (in completeVCG) vcg_tautology: assumes wf_Pi: "wf \" assumes strongAn: "strongAn \" shows "\,s \ vcg \" (*<*) proof - from wf_Pi have initial_vc: "\,s \ (initF \) \ (isafeF \ (ipc \))" proof (rule semImpI) { assume s_initF: "\,s \ initF \" show s_isafeF: "\,s \ isafeF \ (ipc \)" proof - from wf_Pi s_initF have s_ipc: "fst s = ipc \" by (rule_tac s="s" in initF_ipc,simp+) from s_initF have s_ReachableFrom: "s \ ReachableFrom (effS\<^isub>B \) (Starters \)" apply - apply (rule ReachableFrom.init) apply (simp add: Starters_def) done from wf_Pi s_ipc have s_domC: "fst s \ set (domC \)" apply - apply (drule ipc_domC) apply simp done from wf_Pi s_domC strongAn s_ReachableFrom have s_isafeF: "\,s \ (isafeF \ (fst s))" apply - apply (drule ReachableFrom_isafeF) apply simp apply simp done from s_isafeF s_ipc show ?thesis by simp qed } qed have vc_sections: "\,s \ \ (map (\ p. (\ (map (\ (p',B). (\ [isafeF \ p,B]) \ (wpF \ p p' (isafeF \ p'))) (succsF \ p)) )) (domA \))" proof - have vc_single_section: "\ p \ set (domC \). \ A. anF \ p = Some A \ (\ p' B. (p',B) \ set (succsF \ p) \ (\,s \ isafeF \ p \ \,s \ B) \ (\,s \ wpF \ p p' (isafeF \ p')))" proof (intro allI ballI impI, elim conjE) fix p A p' B assume p_domC: "p \ set (domC \)" assume anF_p: "anF \ p = Some A" assume succsF_p: "(p',B) \ set (succsF \ p)" assume s_isafeF: "\,s \ isafeF \ p" assume s_B:"\,s \ B" show "\,s \ wpF \ p p' (isafeF \ p')" proof - obtain sp sm where s_def: "s = (sp,sm)" by fastsimp from s_isafeF anF_p s_def wf_Pi p_domC have s_A: "\,s \ A" by (simp add: isafeFdef semConj) from s_isafeF anF_p s_def wf_Pi p_domC have s_safeF: "\,s \ safeF \ p" by (simp add: isafeFdef semConj) from wf_Pi anF_p s_A succsF_p s_B s_def obtain m' where sp_p: "sp = p" and s_s'_effS:"((sp,sm),(p',m')) \ (effS \)" apply - apply (subgoal_tac "sp = p \ (\ m'. ((sp,sm),(p',m')) \ (effS \))") prefer 2 apply (rule_tac B="B" in succsFprogress) apply (simp add: aF_def)+ apply fastsimp done from s_def sp_p s_A anF_p s_safeF s_s'_effS s_B succsF_p have s'_ReachableFrom: "(p',m') \ ReachableFrom (effS\<^isub>B \) (Starters \)" apply - apply (rule_tac a="s" in ReachableFrom.step) apply (rule ReachableFrom.init) apply (simp add: Starters_def) apply (simp add: effS\<^isub>B_def branch_def) apply fastsimp done from wf_Pi succsF_p have p'_domC: "p' \ set (domC \)" apply - apply (rule succsF_domC[THEN conjE]) apply simp apply simp apply simp done from wf_Pi strongAn p'_domC s'_ReachableFrom have s'_isafeF: "\,(p',m') \ isafeF \ p'" apply - apply (drule ReachableFrom_isafeF) apply simp apply (erule_tac x="(p',m')" in ballE) apply simp apply simp done from wf_Pi anF_p s_A sp_p succsF_p s_B s_s'_effS s'_isafeF s_def show ?thesis apply - apply (simp only:) apply (rule completeWpF) apply (simp add: aF_def)+ done qed qed from wf_Pi vc_single_section show ?thesis apply - apply (simp add: semConj domA_def) apply (rule allI | rule impI | rule ballI)+ apply (erule_tac x="x" in ballE) prefer 2 apply simp apply simp apply (erule_tac x="fst xa" in allE) apply (erule_tac x="snd xa" in allE) apply (simp add: split_def semConj) apply (rule semImpI) apply assumption apply (simp add: semConj) done qed from wf_Pi initial_vc vc_sections show ?thesis by (simp add: vcgdef semConj) qed (*>*) theorem (in completeVCG) vcg_completeness: "\ wf \; strongAn \; (\ s. \,s \ vcg \) \ \ \ vcg \ \ \ \ \ vcg \" (*<*) apply (subgoal_tac "\ s. \,s \ vcg \") prefer 2 apply (rule allI) apply (rule vcg_tautology) apply assumption+ apply simp done (*>*) lemma ReachableFrom_trans: "\ a \ ReachableFrom R S; b \ ReachableFrom R {a} \ \ b \ ReachableFrom R S" apply (simp add: ReachableFrom_conv) apply fastsimp done consts ReachableFrom_k:: "('a \ 'a) set \ 'a set \ (nat \ 'a) set" inductive "ReachableFrom_k R S" intros init: "a \ S \ (0,a) \ ReachableFrom_k R S" step: "(k,a) \ ReachableFrom_k R S \ (a,b) \ R \ (k+1,b) \ ReachableFrom_k R S" constdefs ReachableFromIn:: "('a \ 'a) set \ 'a set \ nat \ 'a set" "ReachableFromIn R S k \ {a. (k,a) \ ReachableFrom_k R S}" lemma k_init: "a \ S \ a \ ReachableFromIn R S 0" apply (simp add: ReachableFromIn_def) apply (rule init) apply simp done lemma k_step: "a \ ReachableFromIn R S k \ (a,b) \ R \ b \ ReachableFromIn R S (k+1)" apply (simp add: ReachableFromIn_def) apply (drule step) apply simp apply simp done consts ispecFe:: "('program \ 'pos \ nat \ ('program \ 'pos \ 'form option) \ 'form \ ('form list \ 'form) \ ('form \ 'form \ 'form) \ ( 'program \ 'pos \ 'form) \ ('program \ 'pos \ ('pos \ 'form) list) \ ('program \ 'pos \ 'pos \ 'form \ 'form)) \ 'form" recdef ispecFe "measure (\ a. (fst (snd (snd a))))" "ispecFe (\,p,k,specF,TrueF,Conj,Impl,safeF,succsF,wpF) = (case specF \ p of Some Q \ Q | None \ (case k of 0 \ TrueF | Suc k' \ Conj (map (\(p',B). Impl B (wpF \ p p' (Conj [safeF \ p', ispecFe (\,p',k',specF,TrueF,Conj,Impl,safeF,succsF,wpF)]))) (succsF \ p))))" locale exprSL = completeVCG + fixes finals:: "'program \ 'pos set" defines "finals \ == {p. p \ set (domC \) \ \ (\p' B. (p',B) \ set (succsF \ p))}" fixes specF:: "'program \ 'pos \ 'form option" fixes ispecF:: "'program \ 'pos \ nat \ 'form" defines "ispecF \ \\ p k. ispecFe (\,p,k,specF,TrueF,Conj,Impl,safeF,succsF,wpF)" assumes correctWpF: "\ wf \; (p',B) \ set (succsF \ p); \,(p,m) \ B; ((p,m),(p',m')) \ (effS \); \,(p,m) \ wpF \ p p' Q \\ \,(p',m') \ Q" assumes specF_pos: "\p. p \ {ipc \}\(finals \) = (specF \ p \ None)" assumes specF_ipc: "specF \ (ipc \) = Some (initF \)" assumes ipc_not_succsF: "wf \ \ \p. ipc \ \ set (map fst (succsF \ p))" lemma (in exprSL) ispecFe_def: "ispecFe (\, p, k, specF, TrueF, Conj, Impl, safeF, succsF, wpF) = (case specF \ p of None \ case k of 0 \ TrueF | Suc k' \ Conj (map (\(p', B). Impl B (wpF \ p p' (Conj [safeF \ p', ispecFe (\, p', k', specF, TrueF, Conj, Impl, safeF, succsF, wpF)]))) (succsF \ p)) | Some Q \ Q)" apply (subst ispecFe.simps) apply simp done lemma (in exprSL) ispecF_def: "\ p. ispecF \ p k = (case specF \ p of Some Q \ Q | None \ (case k of 0 \ \ | Suc k' \ \ (map (\(p',B). B \ (wpF \ p p' (\ [safeF \ p', ispecF \ p' k'])))) (succsF \ p)))" apply (induct_tac "k") apply (simp add: ispecF_def) apply (case_tac "specF \ p") apply simp apply simp apply (case_tac "specF \ p") apply (simp add: ispecF_def) apply (simp add: ispecF_def) done lemma ReachableFromIn_elims: "\ s \ ReachableFromIn R S k; \ k = 0; s \ S \ \ P; \s' k'. \k = Suc k'; s' \ ReachableFromIn R S k'; (s', s) \ R\ \ P\ \ P" apply (simp add: ReachableFromIn_def) apply (erule ReachableFrom_k.elims) apply simp apply simp done lemma ReachableFrom_ReachableFromIn: "s \ ReachableFrom R S \ \ k. s \ ReachableFromIn R S k" apply (erule ReachableFrom.induct) apply (drule_tac R="R" in k_init) apply fastsimp apply (erule exE) apply (rule_tac x="k+1" in exI) apply (rule k_step) apply simp apply simp done lemma ReachableFromIn_ReachableFrom: "s \ ReachableFromIn R S k \ s \ ReachableFrom R S" apply (simp add: ReachableFromIn_def) apply (erule ReachableFrom_k.induct) apply (rule ReachableFrom.init) apply simp apply (rule ReachableFrom.step) apply simp apply simp done lemma k_lstep: "\ s' \ ReachableFromIn R S k \ \ k > 0 \ (\ s s''. s \ S \ (s,s'') \ R \ s' \ ReachableFromIn R {s''} (k - 1))" apply (simp add: ReachableFromIn_def) apply (erule ReachableFrom_k.induct) apply simp apply (rule impI | erule conjE)+ apply (case_tac "k") apply simp apply (erule ReachableFrom_k.elims) apply simp apply (rule_tac x="aa" in exI) apply simp apply (rule_tac x="b" in exI) apply simp apply (rule ReachableFrom_k.init) apply simp apply simp apply simp apply (erule conjE | erule exE)+ apply (rule_tac x="s" in exI) apply simp apply (rule_tac x="s''" in exI) apply simp apply (drule_tac k="nat" and a="a" in ReachableFrom_k.step) apply simp apply simp done theorem (in exprSL) strongAn_exist: assumes wf_Pi: "wf \" and bounded_diam: "\s s'. s' \ ReachableFrom (effS\<^isub>B \) {s} \ (\r. r \ d \ s' \ ReachableFromIn (effS\<^isub>B \) {s} r)" and isSafe: "\s \ ReachableFrom (effS\<^isub>B \) {s. \,s \ initF \}. \,s \ safeF \ (fst s)" and correct_specF: "\s \ ReachableFrom (effS\<^isub>B \) {s. \,s \ initF \}. (\Q. specF \ (fst s) = Some Q \ \,s \ Q)" and anF_ispecF: "\p. anF \ p = Some (ispecF \ p d)" shows "strongAn \" proof - have ispecF_safeF_ReachableFromIn: "\k s. \,s \ ispecF \ (fst s) k \ \,s \ safeF \ (fst s) \ fst s \ ipc \ \ (\l. l\k \ (\s' \ ReachableFromIn (effS\<^isub>B \) {s} l. \,s' \ ispecF \ (fst s') (k-l) \ \,s' \ safeF \ (fst s')))" (is "\ z. PROP ?P z") proof - fix z show "PROP ?P z" proof (induct "z" rule: nat_less_induct, intro allI impI ballI) fix k s l s' assume hyp: "\k's. \,s \ ispecF \ (fst s) k' \ \,s \ safeF \ (fst s) \ fst s \ ipc \ \ (\l\k'. (\s'\ReachableFromIn (effS\<^isub>B \) {s} l. \,s' \ ispecF \ (fst s') (k' - l) \ \,s' \ safeF \ (fst s')))" assume s_ispecF_k: "\,s \ ispecF \ (fst s) k" assume s_safeF: "\,s \ safeF \ (fst s)" assume s_not_ipc: "fst s \ ipc \" assume l_k: "l \ k" assume s'_ReachableFromIn_l: "s' \ ReachableFromIn (effS\<^isub>B \) {s} l" show "\,s' \ ispecF \ (fst s') (k - l) \ \,s' \ safeF \ (fst s')" (is ?s'_ispecF) proof (cases "l") case 0 from 0 s'_ReachableFromIn_l have s_eq_s': "s = s'" apply - apply (erule ReachableFromIn_elims) apply simp apply simp done from 0 s_eq_s' s_ispecF_k s_safeF show "?s'_ispecF" by simp next case (Suc l') from Suc have l'_l: "l = Suc l'" by simp from l'_l s'_ReachableFromIn_l obtain s'' where s'_ReachableFromIn_l': "s' \ ReachableFromIn (effS\<^isub>B \) {s''} l'" and s_s''_effSB: "(s,s'') \ (effS\<^isub>B \)" apply - apply (drule k_lstep) apply fastsimp done from l'_l l_k have l'_k: "l' < k" by arith from l'_k obtain k' where k'_k: "k = Suc k'" apply - apply (case_tac "k::nat") by arith from k'_k l'_k have l'_k': "l' \ k'" by arith from k'_k l'_l have k_l_k'_l': "k - l = (k' - l')" by arith obtain p m where s_def: "s = (p,m)" by fastsimp obtain p' m' where s'_def: "s' = (p',m')" by fastsimp obtain p'' m'' where s''_def: "s'' = (p'',m'')" by fastsimp from s_s''_effSB s_def s''_def obtain B where p''_B_succsF_p: "(p'',B) \ set (succsF \ p)" and s_B: "\,s \ B" and s_s''_effS: "(s,s'') \ effS \" apply - apply (simp add: effS\<^isub>B_def branch_def) apply fastsimp done from p''_B_succsF_p have p_not_final: "p \ finals \" by (fastsimp simp add: finals_def) from s_not_ipc s_def p_not_final specF_pos have p_specF: "specF \ p = None" by fastsimp from s_ispecF_k k'_k have s''_safeF_ispecF: "\,s'' \ \ [safeF \ p'', ispecF \ p'' k']" proof - from s_ispecF_k p_specF s_def k'_k p''_B_succsF_p s''_def have s_B_Imp_wpF: "\,s \ B \ wpF \ p p'' (\ [safeF \ p'', ispecF \ p'' k'])" apply - apply (drule_tac P="\ ispecF. \,s \ ispecF" in subst[OF ispecF_def]) apply (simp add: semConj) apply (erule_tac x="(p'',B)" in ballE) apply (simp add: split_def) apply simp done from s_B s_B_Imp_wpF have s_wpF: "\,s \ wpF \ p p'' (\ [safeF \ p'', ispecF \ p'' k'])" apply - apply (drule semImpE) apply simp done from wf_Pi s_wpF s_B p''_B_succsF_p s_def s''_def s_s''_effS s_wpF show "?thesis" apply - apply (simp only:) apply (rule correctWpF) apply simp+ done qed from s''_safeF_ispecF s''_def have s''_ispecF: "\,s'' \ ispecF \ (fst s'') k'" by (simp add: semConj) from s''_safeF_ispecF s''_def have s''_safeF: "\,s'' \ safeF \ (fst s'')" by (simp add: semConj) from p''_B_succsF_p wf_Pi ipc_not_succsF[where \="\"] have p''_not_ipc: "p'' \ ipc \" apply - apply simp apply (erule_tac x="p" in allE) apply clarsimp apply (simp add: in_set_conv_decomp) apply (erule exE | erule conjE)+ apply simp done from k'_k have k'_less_k: "k' < k" by arith from hyp s''_ispecF s''_safeF k'_less_k p''_not_ipc l'_k' s'_ReachableFromIn_l' s''_def have s'_ispecF_k'_l'_safeF: "\,s' \ ispecF \ (fst s') (k' - l') \ \,s' \ safeF \ (fst s')" by fastsimp from s'_ispecF_k'_l'_safeF k_l_k'_l' show "?s'_ispecF" by simp qed qed qed have ReachableFromIn_ispecF: "\k s. (\l. l\k \ (\s' \ ReachableFromIn (effS\<^isub>B \) {s} l. \,s' \ ispecF \ (fst s') (k-l))) \ fst s \ ipc \ \ \,s \ ispecF \ (fst s) k" proof - fix k s assume l_k_ReachableFromIn_ispecF: "\l\k. \s'\ReachableFromIn (effS\<^isub>B \) {s} l. \,s' \ ispecF \ (fst s') (k - l)" assume s_not_ipc: "fst s \ ipc \" have s_ReachableFromIn_0: "s \ ReachableFromIn (effS\<^isub>B \) {s} 0" apply - apply (rule k_init) by simp from l_k_ReachableFromIn_ispecF s_ReachableFromIn_0 show "\,s \ ispecF \ (fst s) k" by fastsimp qed have ispecF_d_inc: "\ s. \,s \ safeF \ (fst s) \ \,s \ ispecF \ (fst s) d \ \,s \ ispecF \ (fst s) (d+1)" proof - fix s assume s_safeF: "\,s \ safeF \ (fst s)" assume s_ispecF_d: "\,s \ ispecF \ (fst s) d" show "\,s \ ispecF \ (fst s) (d+1)" proof (cases "specF \ (fst s)") case (Some Q) from Some s_ispecF_d show "?thesis" by (simp add: ispecF_def) next case None obtain p m where s_def: "s = (p,m)" by fastsimp from None s_def specF_pos[where \="\"] have p_not_ipc: "p \ ipc \" apply - apply (erule_tac x="p" in allE) apply simp done from None s_def specF_pos[where \="\"] have p_not_final: "p \ finals \" apply - apply (erule_tac x="p" in allE) apply simp done from s_ispecF_d s_safeF s_def p_not_ipc have ReachableFromIn_ispecF_d: "\l \ d. \s' \ ReachableFromIn (effS\<^isub>B \) {s} l. \,s' \ ispecF \ (fst s') (d - l) \ \,s' \ safeF \ (fst s')" apply - apply (drule ispecF_safeF_ReachableFromIn) apply simp apply simp apply simp done have ReachableFromIn_ispecF_inc_d: "\ k l s'. k = (d + 1) - l \ l \ d + 1 \ s' \ ReachableFromIn (effS\<^isub>B \) {s} l \ \,s' \ ispecF \ (fst s') ((d + 1) - l) \ \,s' \ safeF \ (fst s')" (is "\ k. PROP ?P k") proof - fix z show "PROP ?P z" proof (induct "z" rule: nat_less_induct, intro impI) fix k l s' assume Hyp: "\k'l' s'. k' = d + 1 - l' \ l' \ d + 1 \ s' \ ReachableFromIn (effS\<^isub>B \) {s} l' \ \,s' \ ispecF \ (fst s') (d + 1 - l') \ \,s' \ safeF \ (fst s')" assume k_d_l: "k = (d + 1) - l" assume l_d: "l \ (d + 1)" assume s'_ReachableFromIn_l: "s' \ ReachableFromIn (effS\<^isub>B \) {s} l" show "\,s' \ ispecF \ (fst s') (d + 1 - l) \ \,s' \ safeF \ (fst s')" (is "?s'_ispecF") proof (cases k) case 0 from 0 k_d_l have l_gr_d: "l > d" by arith from s'_ReachableFromIn_l have s'_ReachableFrom_s: "s' \ ReachableFrom (effS\<^isub>B \) {s}" by (rule ReachableFromIn_ReachableFrom) from bounded_diam s'_ReachableFrom_s obtain r where r_le_d: "r \ d" and s'_ReachableFromIn_r: "s' \ ReachableFromIn (effS\<^isub>B \) {s} r" by fastsimp from ReachableFromIn_ispecF_d r_le_d s'_ReachableFromIn_r have s'_ispecF_d_r_safeF: "\,s' \ ispecF \ (fst s') (d - r) \ \,s' \ safeF \ (fst s')" by fastsimp show "?s'_ispecF" proof (cases "specF \ (fst s')") case (Some Q) from Some s'_ispecF_d_r_safeF show "?s'_ispecF" by (simp add: ispecF_def) next case None from None 0 k_d_l[THEN sym] s'_ispecF_d_r_safeF show "?s'_ispecF" by (simp add: ispecF_def semTrue) qed next case (Suc k') from Suc have k'_k: "k = Suc k'" by simp show "?s'_ispecF" proof (cases "l") case 0 from 0 s'_ReachableFromIn_l have s'_eq_s: "s' = s" apply - apply (erule ReachableFromIn_elims) apply simp apply simp done obtain p' m' where s'_def: "s' = (p',m')" by fastsimp from wf_Pi have s'_B_wpF: "\ (p'',B'') \ set (succsF \ p'). \,s' \ B'' \ wpF \ p' p'' (\ [safeF \ p'', ispecF \ p'' k'])" proof (intro ballI, simp add: split_paired_all s'_def, intro semImpI, assumption) fix p'' B'' assume p''_B''_succsF_p': "(p'',B'') \ set (succsF \ p')" assume s'_B'': "\,(p',m') \ B''" from wf_Pi p''_B''_succsF_p' s'_B'' s'_def obtain m'' where s'_s''_effS: "((p',m'),(p'',m'')) \ effS \" apply - apply (drule succsFprogress) apply simp+ apply (erule exE) apply fastsimp done obtain s'' where s''_def: "s'' = (p'',m'')" by fastsimp have s''_ispecF_safeF: "\,(p'',m'') \ ispecF \ p'' k' \ \,(p'',m'') \ safeF \ p''" proof - from s'_s''_effS s'_def s''_def s'_B'' p''_B''_succsF_p' have s'_s''_effSB: "(s',s'') \ effS\<^isub>B \" by (fastsimp simp add: effS\<^isub>B_def branch_def) from 0 s'_eq_s s'_ReachableFromIn_l s'_s''_effSB have s''_ReachableFromIn_1: "s'' \ ReachableFromIn (effS\<^isub>B \) {s} 1" apply - apply (drule k_step) apply simp apply simp done from k'_k have k'_less_k: "k' < k" by arith from Hyp 0 k_d_l[THEN sym] k'_less_k k'_k s''_ReachableFromIn_1 s''_def show s''_ispecF_safeF: "\,(p'',m'') \ ispecF \ p'' k' \ \,(p'',m'') \ safeF \ p''" apply - apply (erule_tac x="k'" in allE) apply (drule mp, assumption) apply (erule_tac x="1" in allE) apply (erule_tac x="s''" in allE) by fastsimp qed from s''_ispecF_safeF s''_def have s''_safeF_ispecF: "\,(p'',m'') \ \[safeF \ p'', ispecF \ p'' k']" by (simp add: semConj) from wf_Pi p''_B''_succsF_p' s'_B'' s_def s'_def s''_safeF_ispecF s'_s''_effS show "\,(p',m') \ wpF \ p' p'' \[safeF \ p'', ispecF \ p'' k']" apply - apply (rule completeWpF) apply simp+ done qed from 0 s'_ReachableFromIn_l ReachableFromIn_ispecF_d have s'_safeF: "\,s' \ safeF \ (fst s')" by fastsimp from None s'_eq_s k_d_l[THEN sym] k'_k s'_B_wpF s_def s'_def s'_safeF show "?s'_ispecF" apply - apply (subst ispecF_def) apply (simp add: semConj split_def) done next case (Suc l') from Suc have l'_l: "l = Suc l'" by simp from k'_k k_d_l have l_le_d: "l \ d" by arith from ReachableFromIn_ispecF_d l_le_d s'_ReachableFromIn_l have s'_ispecF_d_safeF: "\,s' \ ispecF \ (fst s') (d - l) \ \,s' \ safeF \ (fst s')" by fastsimp show "?s'_ispecF" proof (cases "specF \ (fst s')") case (Some Q) from Some s'_ispecF_d_safeF show "?s'_ispecF" by (simp add: ispecF_def) next case None obtain p' m' where s'_def: "s' = (p',m')" by fastsimp from wf_Pi have s'_B_wpF: "\ (p'',B'') \ set (succsF \ p'). \,s' \ B'' \ wpF \ p' p'' (\ [safeF \ p'', ispecF \ p'' k'])" proof (intro ballI, simp add: split_paired_all s'_def, intro semImpI, assumption) fix p'' B'' assume p''_B''_succsF_p': "(p'',B'') \ set (succsF \ p')" assume s'_B'': "\,(p',m') \ B''" from wf_Pi p''_B''_succsF_p' s'_B'' s'_def obtain m'' where s'_s''_effS: "((p',m'),(p'',m'')) \ effS \" apply - apply (drule succsFprogress) apply simp+ apply (erule exE) apply fastsimp done obtain s'' where s''_def: "s'' = (p'',m'')" by fastsimp have s''_ispecF_safeF: "\,(p'',m'') \ ispecF \ p'' k' \ \,(p'',m'') \ safeF \ p''" proof - from s'_s''_effS s'_def s''_def s'_B'' p''_B''_succsF_p' have s'_s''_effSB: "(s',s'') \ effS\<^isub>B \" by (fastsimp simp add: effS\<^isub>B_def branch_def) have s'_ReachableFromIn_0: "s' \ ReachableFromIn (effS\<^isub>B \) {s'} 0" apply - apply (rule k_init) by simp from s'_ReachableFromIn_l s'_s''_effSB have s''_ReachableFromIn_inc_l: "s'' \ ReachableFromIn (effS\<^isub>B \) {s} (l+1)" apply - apply (drule k_step) apply simp apply simp done from k'_k have k'_less_k: "k' < k" by arith from k'_k k_d_l have k'_d_l: "k' = d - l" by arith from Hyp k_d_l[THEN sym] k'_less_k k'_k k'_d_l l_le_d s''_ReachableFromIn_inc_l s''_def show s''_ispecF_safeF: "\,(p'',m'') \ ispecF \ p'' k' \ \,(p'',m'') \ safeF \ p''" apply - apply (erule_tac x="k'" in allE) apply (drule mp, assumption) apply (erule_tac x="l + 1" in allE) apply (erule_tac x="s''" in allE) apply simp done qed from s''_ispecF_safeF s''_def have s''_safeF_ispecF: "\,(p'',m'') \ \[safeF \ p'', ispecF \ p'' k']" by (simp add: semConj) from wf_Pi p''_B''_succsF_p' s'_B'' s_def s'_def s''_safeF_ispecF s'_s''_effS show "\,(p',m') \ wpF \ p' p'' \[safeF \ p'', ispecF \ p'' k']" apply - apply (rule completeWpF) apply simp+ done qed from None s'_def s'_B_wpF k_d_l[THEN sym] k'_k s'_ispecF_d_safeF show "?s'_ispecF" apply - apply (subst ispecF_def) apply (simp add: semConj split_def) done qed qed qed qed qed have s_ReachableFromIn_0: "s \ ReachableFromIn (effS\<^isub>B \) {s} 0" apply - apply (rule k_init) by simp from s_ReachableFromIn_0 ReachableFromIn_ispecF_inc_d[where k="d + 1" and l="0"] show "?thesis" by simp qed qed have correct_Starters: "\ s. s \ Starters \ \ \,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" proof - fix s assume s_Starters: "s \ Starters \" show "\,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" proof (cases "\,s \ initF \") case True from True have s_initF: "\,s \ initF \" by assumption from s_initF have s_ReachableFrom: "s \ ReachableFrom (effS\<^isub>B \) {s. \,s \ initF \}" apply - apply (rule ReachableFrom.init) by simp from s_ReachableFrom isSafe have s_safeF: "\,s \ safeF \ (fst s)" by fastsimp from wf_Pi s_initF have s_ipc: "fst s = (ipc \)" by (rule initF_ipc) from s_ipc specF_pos obtain Q where Q_def: "specF \ (fst s) = Some Q" by fastsimp from Q_def anF_ispecF have aF_Q: "aF \ (fst s) = Q" apply - apply (simp add: aF_def ispecF_def) done from s_ReachableFrom correct_specF Q_def aF_Q have s_aF: "\,s \ aF \ (fst s)" by fastsimp from s_safeF s_aF show "\,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" by simp next case False from False have s_not_initF: "\ \,s \ initF \" by assumption from s_not_initF s_Starters obtain A where A_def: "anF \ (fst s) = Some A" and s_A: "\,s \ A" and s_safeF: "\,s \ safeF \ (fst s)" apply - apply (simp add: Starters_def) apply fastsimp done from A_def s_A s_safeF show "\,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" by (simp add: aF_def) qed qed from anF_ispecF have in_Starters: "\s. \,s \ aF \ (fst s) \ \,s \ safeF \ (fst s) \ s \ Starters \" by (simp add: aF_def Starters_def) have G1: "\s \ ReachableFrom (effS\<^isub>B \) (Starters \). \,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" (is ?G1) proof - have G2: "\r. \s \ ReachableFromIn (effS\<^isub>B \) (Starters \) r. \,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" (is "\r. PROP ?P r") proof - fix r show "PROP ?P r" proof (induct "r" rule: nat_less_induct) case (1 n) assume Hyp: "\ms\ReachableFromIn (effS\<^isub>B \) (Starters \) m. \,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" show "\s\ReachableFromIn (effS\<^isub>B \) (Starters \) n. \,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" proof (intro ballI impI) fix s assume s_ReachableFromIn_n: "s \ ReachableFromIn (effS\<^isub>B \) (Starters \) n" from s_ReachableFromIn_n have s_ReachableFrom: "s \ ReachableFrom (effS\<^isub>B \) (Starters \)" by (rule ReachableFromIn_ReachableFrom) show "\,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" (is ?G2') proof (rule ReachableFromIn_elims[OF s_ReachableFromIn_n]) assume n_0: "n = 0" assume s_Starters: "s \ Starters \" show "?G2'" by (rule correct_Starters) next fix s' k' assume n_k': "n = Suc k'" assume s'_ReachableFromIn_k': "s' \ ReachableFromIn (effS\<^isub>B \) (Starters \) k'" assume s'_s_effSB: "(s', s) \ effS\<^isub>B \" show "?G2'" proof - from Hyp n_k' s'_ReachableFromIn_k' have s'_aF_safeF: "\,s' \ aF \ (fst s') \ \,s' \ safeF \ (fst s')" by fastsimp from s'_aF_safeF have s'_Starters: "s' \ Starters \" apply - apply (rule in_Starters) apply simp apply simp done from s'_s_effSB obtain B where s'_s_succsF: "(fst s,B) \ set (succsF \ (fst s'))" and s'_B: "\,s' \ B" and s'_s_effS: "(s',s) \ effS \" apply - apply (simp add: effS\<^isub>B_def branch_def) apply fastsimp done from s'_s_succsF have s'_not_final: "fst s' \ finals \" apply - apply (simp add: finals_def) apply fastsimp done from s'_aF_safeF anF_ispecF have s'_ispecF: "\,s' \ ispecF \ (fst s') (d+1)" apply - apply (rule ispecF_d_inc) apply simp apply (simp add: aF_def) done show "?G2'" proof (cases "fst s' = ipc \") case False from False s'_not_final specF_pos have s'_specF_None: "specF \ (fst s') = None" by fastsimp from s'_ispecF s'_specF_None s'_s_succsF have s'_wp_ispecF: "\,s' \ B \ wpF \ (fst s') (fst s) (\ [safeF \ (fst s),ispecF \ (fst s) d])" apply - apply (drule_tac P="\ ispecF. \,s' \ ispecF" in subst[OF ispecF_def]) apply (simp add: semConj) apply (erule_tac x="(fst s,B)" in ballE) apply simp apply simp done obtain p m where s_def: "s = (p,m)" by fastsimp obtain p' m' where s'_def: "s' = (p',m')" by fastsimp from wf_Pi s'_s_effS s'_B s'_s_succsF s'_wp_ispecF s_def s'_def have s_safeF_ispecF: "\,s \ \ [safeF \ (fst s), ispecF \ (fst s) d]" apply - apply (simp only: fst_conv snd_conv) apply (drule semImpE) apply (rule correctWpF) apply simp+ done from s_safeF_ispecF anF_ispecF show "?G2'" apply - apply (simp add: aF_def semConj) done next case True from True have s'_ipc: "fst s' = ipc \" by assumption from s'_ipc specF_ipc have specF_s': "specF \ (fst s') = Some (initF \)" by simp from specF_s' s'_ispecF have s'_initF: "\,s' \ (initF \)" by (simp add: ispecF_def) from s'_initF have s'_ReachableFrom: "s' \ ReachableFrom (effS\<^isub>B \) {s. \,s \ initF \}" apply - apply (rule ReachableFrom.init) apply simp done from s'_initF s'_s_effSB s'_ReachableFrom have s_ReachableFrom: "s \ ReachableFrom (effS\<^isub>B \) {s. \,s \ initF \}" apply - apply (rule ReachableFrom.step) apply simp apply simp done from s_ReachableFrom isSafe have s_safeF: "\,s \ safeF \ (fst s)" by fastsimp have ispecF_trans: "\ k. \ l. k = d -l \ (\ s''\ ReachableFromIn (effS\<^isub>B \) {s} l. \,s'' \ ispecF \ (fst s'') (d - l))" (is "\ k. PROP ?P k") proof - fix k show "PROP ?P k" proof (induct "k" rule: nat_less_induct, intro allI impI ballI) fix n l s'' assume hyp: "\ml. m = d - l \ (\s''\ReachableFromIn (effS\<^isub>B \) {s} l. \,s'' \ ispecF \ (fst s'') (d - l))" assume n_d_l: "n = d - l" assume s''_ReachableFromIn_l: "s'' \ ReachableFromIn (effS\<^isub>B \) {s} l" show "\,s'' \ ispecF \ (fst s'') (d - l)" (is ?G2'') proof (cases "specF \ (fst s'')") case (Some Q) from Some have ispecF_Q: "ispecF \ (fst s'') (d - l) = Q" by (simp add: ispecF_def) from s''_ReachableFromIn_l have s''_ReachableFrom_s: "s'' \ ReachableFrom (effS\<^isub>B \) {s}" by (rule ReachableFromIn_ReachableFrom) from s_ReachableFrom s''_ReachableFrom_s have s''_ReachableFrom: "s'' \ ReachableFrom (effS\<^isub>B \) {s. \,s \ initF \}" apply (rule ReachableFrom_trans) done from correct_specF s''_ReachableFrom Some ispecF_Q show "?G2''" by fastsimp next case None from None have specF_s'': "specF \ (fst s'') = None" by assumption show "?G2''" proof (cases "d - l") case 0 from specF_s'' 0 show "?G2''" apply - apply (simp add:ispecF_def) apply (rule semTrue) done next case (Suc n') have s''_wpF_ispecF: "\,s'' \ \ (map (\(p',B). B \ (wpF \ (fst s'') p' (\ [safeF \ p',ispecF \ p' ((d - l) - 1)]))) (succsF \ (fst s'')))" proof - have s''_wpF_ispecF_p'_B: "\ p' B. (p',B) \ set (succsF \ (fst s'')) \ \,s'' \ B \ (wpF \ (fst s'') p' (\ [safeF \ p',ispecF \ p' ((d - l) - 1)]))" proof (intro semImpI wf_Pi) fix p''' B' assume p'''_B'_succsF: "(p''',B') \ set (succsF \ (fst s''))" assume s''_B': "\,s'' \ B'" show "\,s'' \ wpF \ (fst s'') p''' \[safeF \ p''', ispecF \ p''' (d - l - 1)]" (is ?wpG) proof - obtain p'' m'' where s''_def: "s'' = (p'',m'')" by fastsimp from wf_Pi s''_B' p'''_B'_succsF s''_def obtain m''' where s''_s'''_effS: "((p'',m''),(p''',m''')) \ (effS \)" apply - apply (drule succsFprogress) apply simp+ apply fastsimp done obtain s''' where s'''_def: "s''' = (p''',m''')" by fastsimp from s''_def s'''_def s''_s'''_effS s''_B' p'''_B'_succsF have s''_s'''_effSB: "(s'',s''') \ (effS\<^isub>B \)" apply - apply (simp add: effS\<^isub>B_def branch_def) apply fastsimp done from s''_ReachableFromIn_l s''_s'''_effSB have s'''_ReachableFromIn_l': "s''' \ ReachableFromIn (effS\<^isub>B \) {s} (l+1)" apply - apply (rule k_step) apply simp+ done from s'''_ReachableFromIn_l' have s'''_ReachableFrom_s: "s''' \ ReachableFrom (effS\<^isub>B \) {s}" by (rule ReachableFromIn_ReachableFrom) from s'''_ReachableFrom_s s_ReachableFrom have s'''_ReachableFrom: "s''' \ ReachableFrom (effS\<^isub>B \) {s. \,s \ initF \}" apply - apply (rule ReachableFrom_trans) apply simp apply simp done from s'''_ReachableFrom isSafe have s'''_safeF: "\,s''' \ safeF \ (fst s''')" by fastsimp from hyp s'''_ReachableFromIn_l' Suc n_d_l have s'''_ispecF: "\,s''' \ ispecF \ (fst s''') (d - (l+1))" apply - apply (erule_tac x="d - (l+1)" in allE) apply simp apply (subgoal_tac "d - Suc l < d - l") prefer 2 apply arith apply simp done from s'''_ispecF s'''_safeF s'''_def have s'''_safeF_ispecF: "\, s''' \ \ [safeF \ p''',ispecF \ p''' (d - l - 1)]" apply - apply (simp add: semConj) done from wf_Pi p'''_B'_succsF s''_B' s''_s'''_effS s'''_safeF_ispecF s''_def s'''_def show "?wpG" apply - apply (simp only: fst_conv snd_conv) apply (rule completeWpF) apply simp+ done qed qed from s''_wpF_ispecF_p'_B show ?thesis apply - apply (simp add: semConj split_def) done qed from Suc s''_wpF_ispecF specF_s'' show "?G2''" apply - apply (simp add: ispecF_def) done qed qed qed qed have s_ReachableFromIn_s: "s \ ReachableFromIn (effS\<^isub>B \) {s} 0" apply - apply (rule k_init) by simp from s_ReachableFromIn_s ispecF_trans[where k=d] have s_ispecF: "\,s \ ispecF \ (fst s) d" apply - apply (erule_tac x="0" in allE) apply simp done from s_safeF s_ispecF anF_ispecF show "?G2'" by (simp add: aF_def) qed qed qed qed qed qed show "?G1" proof (intro ballI impI) fix s assume s_ReachableFrom: "s \ ReachableFrom (effS\<^isub>B \) (Starters \)" show "\,s \ aF \ (fst s) \ \,s \ safeF \ (fst s)" (is ?G1') proof - from s_ReachableFrom obtain r where s_ReachableFromIn: "s \ ReachableFromIn (effS\<^isub>B \) (Starters \) r" apply - apply (drule ReachableFrom_ReachableFromIn) apply fastsimp done from G2 s_ReachableFromIn show "?G1'" by fastsimp qed qed qed from G1 show "strongAn \" by (simp add: strongAn_def) qed end