fun strip :: "acom ==> com"where "strip SKIP = SKIP" | "strip (x ::= a) = (x ::= a)" | "strip (C1;; C2) = (strip C1;; strip C2)" | "strip (IF b THEN C1 ELSE C2) = (IF b THEN strip C1 ELSE strip C2)" | "strip ({_} WHILE b DO C) = (WHILE b DO strip C)"
funpre :: "acom ==> assn2 ==> assn2"where "pre SKIP Q = ($1 ** Q)" | "pre (x ::= a) Q = ((λ(ps,t). x∈dom ps ∧ vars a ⊆ dom ps ∧ Q (ps(x↦(paval a ps)),t) ) ** $1)" | "pre (C1;; C2) Q = pre C1 (pre C2 Q)" | "pre (IF b THEN C1 ELSE C2) Q = ( $1 ** (λ(ps,n). vars b ⊆ dom ps ∧ (if pbval b ps then pre C1 Q (ps,n) else pre C2 Q (ps,n) )))" | "pre ({I} WHILE b DO C) Q = (I ** $1)"
fun vc :: "acom ==> assn2 ==> bool"where "vc SKIP Q = True" | "vc (x ::= a) Q = True" | "vc (C1 ;; C2) Q = ((vc C1 (pre C2 Q)) ∧ (vc C2 Q) )" | "vc (IF b THEN C1 ELSE C2) Q = (vc C1 Q ∧ vc C2 Q)" | "vc ({I} WHILE b DO C) Q = ( (∀s. (I s ⟶ vars b ⊆ dom (fst s) ) ∧ ((λ(s,n). I (s,n) ∧ lmaps_to_axpr b True s) s ⟶ pre C (I ** $ 1) s) ∧ ( (λ(s,n). I (s,n) ∧ lmaps_to_axpr b False s) s ⟶ Q s)) ∧ vc C (I ** $ 1))"
lemma dollar0_left: "($ 0 ∧* Q) = Q" apply rule unfolding dollar_def sep_conj_def by force
lemma vc_sound: "vc C Q ==>⊨3' {pre C Q} strip C { Q }" proof (induct C arbitrary: Q) case Askip thenshow ?case apply simp apply(rule conseqS[OF Frame[OF Skip]]) by (auto simp: dollar0_left) next case (Aassign x1 x2) thenshow ?case apply simp apply(rule conseqS) apply(rule Assign4) apply auto done next case (Aseq C1 C2) thenshow ?caseapply (auto intro: Seq) done next case (Aif b C1 C2) thenhave Aif1: "⊨3' {pre C1 Q} strip C1 {Q}" and Aif2: "⊨3' {pre C2 Q} strip C2 {Q}"by auto show ?caseapply simp apply (rule conseqS) apply(rule If[where P="%(ps,n). (if pbval b ps then pre C1 Q (ps,n) else pre C2 Q (ps,n))"and Q="Q"])
subgoal apply simp apply (rule conseqS) apply(fact Aif1) by auto
subgoal apply simp apply (rule conseqS) apply(fact Aif2) by auto apply (auto simp: sep_conj_ac) unfolding sep_conj_def by blast next case (Awhile I b C) thenhave
dom : "∧s. (I s ⟶ vars b ⊆ dom (fst s) )" and i: "∧s. (λ(s,n). I (s,n) ∧ lmaps_to_axpr b True s) s ⟶ pre C (I ** $ 1) s" and ii: "∧s. (λ(s,n). I (s,n) ∧ lmaps_to_axpr b False s) s ⟶ Q s" and C: "⊨3' {pre C (I ** $ 1)} strip C {I ** $ 1}" by fastforce+
show ?case apply simp apply(rule conseqS) apply(rule While[where P=I]) apply(rule conseqS) apply(rule C)
subgoal using i by auto
subgoal apply simp using dom unfolding sep_conj_def by force
subgoal apply simp using dom unfolding sep_conj_def by force
subgoal using ii apply auto done done qed
lemma vc2valid: "vc C Q ==>∀s. P s ⟶ pre C Q s ==>⊨3' {P} strip C { Q}" using hoareT_sound2_part weakenpre vc_sound by metis
lemma pre_mono: assumes"∀s. P s ⟶ Q s"shows"∧s. pre C P s ==> pre C Q s" using assms proof(induct C arbitrary: P Q) case Askip thenshow ?caseapply (auto simp: sep_conj_def dollar_def) by force next case (Aassign x1 x2) thenshow ?caseby (auto simp: sep_conj_def dollar_def) next case (Aseq C1 C2) thenshow ?caseby auto next case (Aif b C1 C2) thenshow ?caseapply (auto simp: sep_conj_def dollar_def)
subgoal for ps n apply(rule exI[where x=0]) apply(rule exI[where x=1]) apply(rule exI[where x=ps]) by auto done next case (Awhile x1 x2 C) thenshow ?caseby auto qed
lemma vc_mono: assumes"∀s. P s ⟶ Q s"shows"vc C P ==> vc C Q" using assms proof(induct C arbitrary: P Q) case Askip thenshow ?caseby auto next case (Aassign x1 x2) thenshow ?caseby auto next case (Aseq C1 C2 P Q) thenhave i: "vc C1 (pre C2 P)"and ii: "vc C2 P"by auto from pre_mono[OF ] Aseq(4) have iii: "∀s. pre C2 P s ⟶ pre C2 Q s"by blast show ?caseapply auto using Aseq(1)[OF i iii] Aseq(2)[OF ii Aseq(4)] by auto next case (Aif x1 C1 C2) thenshow ?caseby auto next case (Awhile I b C P Q) thenshow ?caseby auto qed
lemma vc_sound': "vc C Q ==> (∧s n. P' (s, n) ==> pre C Q (s, k * n)) ==> (∧s n. Q (s, n) ==> Q' (s, n div k)) ==> 0 < k ==>⊨3' {P'} strip C { Q'}" using conseq vc_mono vc_sound by metis
lemma pre_Frame: "(∀s. P s ⟶ pre C Q s) ==> vc C Q ==> (∃C'. strip C = strip C' ∧ vc C' (Q ** F) ∧ (∀s. (P ** F) s ⟶ pre C' (Q ** F) s) )" proof (induct C arbitrary: P Q) case Askip show ?case proof (rule exI[where x="Askip"], safe) fix a b assume"(P ∧* F) (a, b)" thenobtain ps1 ps2 n1 n2 where A: "ps1##ps2""a=ps1+ps2""b=n1+n2" and P: "P (ps1,n1)"and F: "F (ps2,n2)"unfolding sep_conj_def by auto from P Askip have p: "($ (Suc 0) ∧* Q) (ps1, n1)"by auto
from p A F have"(($ (Suc 0) ∧* Q) ∧* F) (a, b)" apply(subst (2) sep_conj_def) by auto thenshow"pre SKIP (Q ∧* F) (a, b)"by (simp add: sep_conj_ac) qed simp next case (Aassign x a) show ?case proof (rule exI[where x="Aassign x a"], safe) fix ps n assume"(P ∧* F) (ps,n)" thenobtain ps1 ps2 n1 n2 where o: "ps1##ps2""ps=ps1+ps2""n=n1+n2" and P: "P (ps1,n1)"and F: "F (ps2,n2)"unfolding sep_conj_def by auto from P Aassign(1) have z: "((λ(ps, t). x ∈ dom ps ∧ vars a ⊆ dom ps ∧ Q (ps(x ↦ paval a ps), t)) ∧* $ (Suc 0)) (ps1, n1)" by auto with o F show" pre (x ::= a) (Q ∧* F) (ps,n)"apply auto unfolding sep_conj_def dollar_def apply (auto)
subgoal by(simp add: plus_fun_def)
subgoal by(auto simp add: plus_fun_def)
subgoal by (smt add_update_distrib dom_fun_upd domain_conv insert_dom option.simps(3) paval_extend sep_disj_fun_def) done qed auto next case (Aseq C1 C2) from Aseq(3) havepre: "∀s. P s ⟶ pre C1 (pre C2 Q) s"by auto from Aseq(4) have vc1: "vc C1 (pre C2 Q)"and vc2: "vc C2 Q"by auto from Aseq(1)[OF pre vc1] obtain C1' where S1: "strip C1 = strip C1'" and vc1': "vc C1' (pre C2 Q ∧* F)" and I1: "(∀s. (P ∧* F) s ⟶ pre C1' (pre C2 Q ∧* F) s)"by blast from Aseq(2)[of "pre C2 Q" Q, OF _ vc2] obtain C2' where S2: "strip C2 = strip C2'" and vc2': "vc C2' (Q ∧* F)" and I2: "(∀s. (pre C2 Q ∧* F) s ⟶ pre C2' (Q ∧* F) s) "by blast
show ?caseapply(rule exI[where x="Aseq C1' C2'"]) apply safe
subgoal using S1 S2 by auto
subgoal apply simp apply safe
subgoal using vc_mono[OF I2 vc1'] .
subgoal by (fact vc2') done
subgoal using I1 I2 pre_mono by force done next case (Aif b C1 C2) from Aif(3) have i: "∀s. P s ⟶ ($ (Suc 0) ∧* (λ(ps, n). vars b ⊆ dom ps ∧ (if pbval b ps then pre C1 Q (ps, n) else pre C2 Q (ps, n)))) s"by simp from Aif(4) have vc1: "vc C1 Q"and vc2: "vc C2 Q"by auto from Aif(1)[where P="pre C1 Q"and Q="Q", OF _ vc1] obtain C1' where
s1: "strip C1 = strip C1'"and v1: "vc C1' (Q ∧* F)" and p1: "(∀s. (pre C1 Q ∧* F) s ⟶ pre C1' (Q ∧* F) s)" by auto from Aif(2)[where P="pre C2 Q"and Q="Q", OF _ vc2] obtain C2' where
s2: "strip C2 = strip C2'"and v2: "vc C2' (Q ∧* F)" and p2: "(∀s. (pre C2 Q ∧* F) s ⟶ pre C2' (Q ∧* F) s)" by auto
show ?caseapply(rule exI[where x="Aif b C1' C2'"]) proof safe fix ps n assume"(P ∧* F) (ps, n)" thenobtain ps1 ps2 n1 n2 where o: "ps1##ps2""ps=ps1+ps2""n=n1+n2" and P: "P (ps1,n1)"and F: "F (ps2,n2)"unfolding sep_conj_def by auto from P i have P': "($ (Suc 0) ∧* (λ(ps, n). vars b ⊆ dom ps ∧ (if pbval b ps then pre C1 Q (ps, n) else pre C2 Q (ps, n)))) (ps1,n1)"by auto have PF: "(($ (Suc 0) ∧* (λ(ps, n). vars b ⊆ dom ps ∧ (if pbval b ps then pre C1 Q (ps, n) else pre C2 Q (ps, n)))) ** F) (ps,n)"apply(subst (2) sep_conj_def) apply(rule exI[where x="(ps1,n1)"]) apply(rule exI[where x="(ps2,n2)"]) using F P' o by auto from this[simplified sep_conj_assoc] obtain ps1 ps2 n1 n2 where o: "ps1##ps2""ps=ps1+ps2""n=n1+n2" and P: "($ (Suc 0)) (ps1,n1)"and F: "((λ(ps, n). vars b ⊆ dom ps ∧ (if pbval b ps then pre C1 Q (ps, n) else pre C2 Q (ps, n))) ∧* F) (ps2,n2)" unfolding sep_conj_def apply auto by fast thenhave"((λ(ps, n). vars b ⊆ dom ps ∧ (if pbval b ps then (pre C1 Q ∧* F) (ps, n) else (pre C2 Q ∧* F) (ps, n)))) (ps2,n2)" unfolding sep_conj_def apply auto apply (metis contra_subsetD domD map_add_dom_app_simps(1) plus_fun_conv sep_add_commute) using pbval_extend apply auto[1] apply (metis contra_subsetD domD map_add_dom_app_simps(1) plus_fun_conv sep_add_commute) using pbval_extend apply auto[1] done thenhave"((λ(ps, n). vars b ⊆ dom ps ∧ (if pbval b ps then (pre C1' (Q ∧* F)) (ps, n) else (pre C2' (Q ∧* F)) (ps, n)))) (ps2,n2)" using p1 p2 by auto with o P show"pre (IF b THEN C1' ELSE C2') (Q ∧* F) (ps, n)" apply auto apply(subst sep_conj_def) by force qed (auto simp: s1 s2 v1 v2) next case (Awhile I b C) from Awhile(2) havepre: "∀s. P s ⟶ (I ** $1) s"by auto from Awhile(3) have
dom: "∀ps n. I (ps, n) ⟶ vars b ⊆ dom ps" and tB: "∀s. I s ∧ vars b ⊆ dom (fst s) ∧ pbval b (fst s) ⟶ pre C (I ∧* $ (Suc 0)) s" and fB: "∀ps n. I (ps, n) ∧ vars b ⊆ dom ps ∧¬ pbval b ps ⟶ Q (ps, n)" and vcB: "vc C (I ∧* $(Suc 0))"by auto from Awhile(1)[OF tB vcB] obtain C' where st: "strip C = strip C'" and vc': "vc C' ((I ∧* $ (Suc 0)) ∧* F)" andpre': "(∀s. ((λa. I a ∧ vars b ⊆ dom (fst a) ∧ pbval b (fst a)) ∧* F) s ⟶ pre C' ((I ∧* $ (Suc 0)) ∧* F) s)" by auto show ?caseapply(rule exI[where x="Awhile (I**F) b C'"]) apply safe
subgoal using st by simp
subgoal apply simp apply safe
subgoal using dom unfolding sep_conj_def apply auto by (metis domD sep_substate_disj_add subState subsetCE)
subgoal usingpre' apply(auto simp: sep_conj_ac) apply(subst (asm) sep_conj_def) apply(subst (asm) sep_conj_def) apply auto by (metis dom pbval_extend sep_add_commute sep_disj_commuteI)
subgoal using fB unfolding sep_conj_def apply auto using dom pbval_extend by fastforce
subgoal using vc' apply(auto simp: sep_conj_ac) done done
subgoal apply simp usingpreunfolding sep_conj_def apply auto by (smt semiring_normalization_rules(23) sep_add_assoc sep_add_commute sep_add_disjD sep_add_disjI1) done qed
lemma vc_complete: "⊨3a {P} c { Q } ==> (∃C. vc C Q ∧ (∀s. P s ⟶ pre C Q s) ∧ strip C = c)" proof(induct rule: hoare3a.induct) case Skip thenshow ?caseapply(rule exI[where x="Askip"]) by auto next case (Assign4 x a Q) thenshow ?caseapply(rule exI[where x="Aassign x a"]) by auto next case (If P b c1 Q c2) fromIf(2) obtain C1 where A1: "vc C1 Q""strip C1 = c1"and
A2: "∧ps n. (P (ps, n) ∧ lmaps_to_axpr b True ps) ⟶ pre C1 Q (ps,n)" by blast fromIf(4) obtain C2 where B1: "vc C2 Q""strip C2 = c2"and B2: "∧ps n. (P (ps, n) ∧ lmaps_to_axpr b False ps) ⟶ pre C2 Q (ps,n)" by blast
show ?caseapply(rule exI[where x="Aif b C1 C2"]) using A1 B1 apply auto
subgoal for ps n unfolding sep_conj_def dollar_def apply auto apply(rule exI[where x="0"]) apply(rule exI[where x="1"]) apply(rule exI[where x="ps"]) using A2 B2 by auto done next case (Frame P C Q F) thenobtain C' where vc: "vc C' Q"andpre: "(∀s. P s ⟶ pre C' Q s)" and strip: "strip C' = C"by auto show ?caseusing pre_Frame[OF pre vc] strip by metis next case (Seq P c1 Q c2 R) from Seq(2) obtain C1 where A1: "vc C1 Q""strip C1 = c1"and
A2: "∧s. P s ⟶ pre C1 Q s" by blast from Seq(4) obtain C2 where B1: "vc C2 R""strip C2 = c2"and
B2: "∧s. Q s ⟶ pre C2 R s" by blast show ?caseapply(rule exI[where x="Aseq C1 C2"]) using B1 A1 apply auto
subgoal using vc_mono B2 by auto
subgoal apply(rule pre_mono[where P=Q]) using B2 apply auto using A2 by auto done next case (While I b c) thenobtain C where1: "vc C ((λ(s, n). I (s, n) ∧ vars b ⊆ dom s) ∧* $ 1)" "strip C = c"and2: "∧ps n. (I (ps, n) ∧ lmaps_to_axpr b True ps) ⟶ pre C ((λ(s, n). I (s, n) ∧ vars b ⊆ dom s) ∧* $ 1) (ps,n) "by blast
show ?caseapply(rule exI[where x="Awhile (λ(s, n). I (s, n) ∧ vars b ⊆ dom s) b C"]) using12by auto next case (conseqS P c Q P' Q') thenobtain C' where C': "vc C' Q""(∀s. P s ⟶ pre C' Q s)""strip C' = c" by blast show ?caseapply(rule exI[where x=C']) using C' conseqS(3,4) pre_mono vc_mono by force qed
theorem vc_completeness: assumes"⊨3' {P} c { Q}" shows"∃C k. vc C (Q ** sep_true) ∧ (∀ps n. P (ps, n) ⟶ pre C (λ(ps, n). (Q ** sep_true) (ps, n div k)) (ps, k * n)) ∧ strip C = c" proof - let ?QG = "λk (ps,n). (Q ** sep_true) (ps,n div k)" from assms obtain k where k[simp]: "k>0"and p: "∧ps n. P (ps, n) ==> wp3' c (λ(ps, n). (Q ** sep_true) (ps, n div k)) (ps, k * n)" using valid_wp by blast
from wpT_is_pre have R: "⊨3a {wp3' c (?QG k)} c {?QG k}"by auto
have z: "(∀s. (λ(ps, n). (Q ∧* (λs. True)) (ps, n div k)) s) ==> (∀s. (λ(ps, n). (Q ∧* (λs. True)) (ps, n)) s)" by (metis (no_types) case_prod_conv k neq0_conv nonzero_mult_div_cancel_left old.prod.exhaust)
have z: "∧ps n. ((Q ∧* (λs. True)) (ps, n div k) ==> (Q ∧* (λs. True)) (ps, n))" proof - fix ps n assume"(Q ∧* (λs. True)) (ps, n div k) " thenobtain ps1 n1 ps2 n2 where o: "ps1 ## ps2""ps = ps1 + ps2""Q (ps1, n1)""n div k = n1 + n2" unfolding sep_conj_def by auto from o(4) have nn1: "n≥n1"using k by (metis (full_types) add_leE div_le_dividend) show"(Q ∧* (λs. True)) (ps, n)"unfolding sep_conj_def apply(rule exI[where x="(ps1, n1)"]) apply(rule exI[where x="(ps2, n - n1)"]) using o nn1 by auto qed thenhave z': "∀s. ((Q ∧* (λs. True)) (fst s, (snd s) div k) ⟶ (Q ∧* (λs. True)) s)" by (metis prod.collapse)
from vc_complete[OF R] obtain C where o: "vc C (λ(ps, n). (Q ∧* (λs. True)) (ps, n div k))" "∀a b. wp3' (strip C) (λ(ps, n). (Q ∧* (λs. True)) (ps, n div k)) (a, b) ⟶ pre C (λ(ps, n). (Q ∧* (λs. True)) (ps, n div k)) (a, b)" "c = strip C"by auto
have y: "∧ps n. P (ps, n) ==> pre C (λ(ps, n). (Q ∧* (λs. True)) (ps, n div k)) (ps, k * n)" using o p by metis
show ?thesis apply(rule exI[where x=C]) apply(rule exI[where x=k]) apply safe
subgoal apply(rule vc_mono[OF _ o(1)]) using z by blast
subgoal using y by blast
subgoal using o by simp done qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.