8 invariants. *} |
8 invariants. *} |
9 |
9 |
10 datatype acom = |
10 datatype acom = |
11 ASKIP | |
11 ASKIP | |
12 Aassign vname aexp ("(_ ::= _)" [1000, 61] 61) | |
12 Aassign vname aexp ("(_ ::= _)" [1000, 61] 61) | |
13 Asemi acom acom ("_;/ _" [60, 61] 60) | |
13 Aseq acom acom ("_;/ _" [60, 61] 60) | |
14 Aif bexp acom acom ("(IF _/ THEN _/ ELSE _)" [0, 0, 61] 61) | |
14 Aif bexp acom acom ("(IF _/ THEN _/ ELSE _)" [0, 0, 61] 61) | |
15 Awhile assn bexp acom ("({_}/ WHILE _/ DO _)" [0, 0, 61] 61) |
15 Awhile assn bexp acom ("({_}/ WHILE _/ DO _)" [0, 0, 61] 61) |
16 |
16 |
17 text{* Weakest precondition from annotated commands: *} |
17 text{* Weakest precondition from annotated commands: *} |
18 |
18 |
19 fun pre :: "acom \<Rightarrow> assn \<Rightarrow> assn" where |
19 fun pre :: "acom \<Rightarrow> assn \<Rightarrow> assn" where |
20 "pre ASKIP Q = Q" | |
20 "pre ASKIP Q = Q" | |
21 "pre (Aassign x a) Q = (\<lambda>s. Q(s(x := aval a s)))" | |
21 "pre (Aassign x a) Q = (\<lambda>s. Q(s(x := aval a s)))" | |
22 "pre (Asemi c\<^isub>1 c\<^isub>2) Q = pre c\<^isub>1 (pre c\<^isub>2 Q)" | |
22 "pre (Aseq c\<^isub>1 c\<^isub>2) Q = pre c\<^isub>1 (pre c\<^isub>2 Q)" | |
23 "pre (Aif b c\<^isub>1 c\<^isub>2) Q = |
23 "pre (Aif b c\<^isub>1 c\<^isub>2) Q = |
24 (\<lambda>s. (bval b s \<longrightarrow> pre c\<^isub>1 Q s) \<and> |
24 (\<lambda>s. (bval b s \<longrightarrow> pre c\<^isub>1 Q s) \<and> |
25 (\<not> bval b s \<longrightarrow> pre c\<^isub>2 Q s))" | |
25 (\<not> bval b s \<longrightarrow> pre c\<^isub>2 Q s))" | |
26 "pre (Awhile I b c) Q = I" |
26 "pre (Awhile I b c) Q = I" |
27 |
27 |
28 text{* Verification condition: *} |
28 text{* Verification condition: *} |
29 |
29 |
30 fun vc :: "acom \<Rightarrow> assn \<Rightarrow> assn" where |
30 fun vc :: "acom \<Rightarrow> assn \<Rightarrow> assn" where |
31 "vc ASKIP Q = (\<lambda>s. True)" | |
31 "vc ASKIP Q = (\<lambda>s. True)" | |
32 "vc (Aassign x a) Q = (\<lambda>s. True)" | |
32 "vc (Aassign x a) Q = (\<lambda>s. True)" | |
33 "vc (Asemi c\<^isub>1 c\<^isub>2) Q = (\<lambda>s. vc c\<^isub>1 (pre c\<^isub>2 Q) s \<and> vc c\<^isub>2 Q s)" | |
33 "vc (Aseq c\<^isub>1 c\<^isub>2) Q = (\<lambda>s. vc c\<^isub>1 (pre c\<^isub>2 Q) s \<and> vc c\<^isub>2 Q s)" | |
34 "vc (Aif b c\<^isub>1 c\<^isub>2) Q = (\<lambda>s. vc c\<^isub>1 Q s \<and> vc c\<^isub>2 Q s)" | |
34 "vc (Aif b c\<^isub>1 c\<^isub>2) Q = (\<lambda>s. vc c\<^isub>1 Q s \<and> vc c\<^isub>2 Q s)" | |
35 "vc (Awhile I b c) Q = |
35 "vc (Awhile I b c) Q = |
36 (\<lambda>s. (I s \<and> \<not> bval b s \<longrightarrow> Q s) \<and> |
36 (\<lambda>s. (I s \<and> \<not> bval b s \<longrightarrow> Q s) \<and> |
37 (I s \<and> bval b s \<longrightarrow> pre c I s) \<and> |
37 (I s \<and> bval b s \<longrightarrow> pre c I s) \<and> |
38 vc c I s)" |
38 vc c I s)" |
40 text{* Strip annotations: *} |
40 text{* Strip annotations: *} |
41 |
41 |
42 fun strip :: "acom \<Rightarrow> com" where |
42 fun strip :: "acom \<Rightarrow> com" where |
43 "strip ASKIP = SKIP" | |
43 "strip ASKIP = SKIP" | |
44 "strip (Aassign x a) = (x::=a)" | |
44 "strip (Aassign x a) = (x::=a)" | |
45 "strip (Asemi c\<^isub>1 c\<^isub>2) = (strip c\<^isub>1; strip c\<^isub>2)" | |
45 "strip (Aseq c\<^isub>1 c\<^isub>2) = (strip c\<^isub>1; strip c\<^isub>2)" | |
46 "strip (Aif b c\<^isub>1 c\<^isub>2) = (IF b THEN strip c\<^isub>1 ELSE strip c\<^isub>2)" | |
46 "strip (Aif b c\<^isub>1 c\<^isub>2) = (IF b THEN strip c\<^isub>1 ELSE strip c\<^isub>2)" | |
47 "strip (Awhile I b c) = (WHILE b DO strip c)" |
47 "strip (Awhile I b c) = (WHILE b DO strip c)" |
48 |
48 |
49 subsection "Soundness" |
49 subsection "Soundness" |
50 |
50 |
71 subsection "Completeness" |
71 subsection "Completeness" |
72 |
72 |
73 lemma pre_mono: |
73 lemma pre_mono: |
74 "\<forall>s. P s \<longrightarrow> P' s \<Longrightarrow> pre c P s \<Longrightarrow> pre c P' s" |
74 "\<forall>s. P s \<longrightarrow> P' s \<Longrightarrow> pre c P s \<Longrightarrow> pre c P' s" |
75 proof (induction c arbitrary: P P' s) |
75 proof (induction c arbitrary: P P' s) |
76 case Asemi thus ?case by simp metis |
76 case Aseq thus ?case by simp metis |
77 qed simp_all |
77 qed simp_all |
78 |
78 |
79 lemma vc_mono: |
79 lemma vc_mono: |
80 "\<forall>s. P s \<longrightarrow> P' s \<Longrightarrow> vc c P s \<Longrightarrow> vc c P' s" |
80 "\<forall>s. P s \<longrightarrow> P' s \<Longrightarrow> vc c P s \<Longrightarrow> vc c P' s" |
81 proof(induction c arbitrary: P P') |
81 proof(induction c arbitrary: P P') |
82 case Asemi thus ?case by simp (metis pre_mono) |
82 case Aseq thus ?case by simp (metis pre_mono) |
83 qed simp_all |
83 qed simp_all |
84 |
84 |
85 lemma vc_complete: |
85 lemma vc_complete: |
86 "\<turnstile> {P}c{Q} \<Longrightarrow> \<exists>c'. strip c' = c \<and> (\<forall>s. vc c' Q s) \<and> (\<forall>s. P s \<longrightarrow> pre c' Q s)" |
86 "\<turnstile> {P}c{Q} \<Longrightarrow> \<exists>c'. strip c' = c \<and> (\<forall>s. vc c' Q s) \<and> (\<forall>s. P s \<longrightarrow> pre c' Q s)" |
87 (is "_ \<Longrightarrow> \<exists>c'. ?G P c Q c'") |
87 (is "_ \<Longrightarrow> \<exists>c'. ?G P c Q c'") |
92 next |
92 next |
93 case (Assign P a x) |
93 case (Assign P a x) |
94 show ?case (is "\<exists>ac. ?C ac") |
94 show ?case (is "\<exists>ac. ?C ac") |
95 proof show "?C(Aassign x a)" by simp qed |
95 proof show "?C(Aassign x a)" by simp qed |
96 next |
96 next |
97 case (Semi P c1 Q c2 R) |
97 case (Seq P c1 Q c2 R) |
98 from Semi.IH obtain ac1 where ih1: "?G P c1 Q ac1" by blast |
98 from Seq.IH obtain ac1 where ih1: "?G P c1 Q ac1" by blast |
99 from Semi.IH obtain ac2 where ih2: "?G Q c2 R ac2" by blast |
99 from Seq.IH obtain ac2 where ih2: "?G Q c2 R ac2" by blast |
100 show ?case (is "\<exists>ac. ?C ac") |
100 show ?case (is "\<exists>ac. ?C ac") |
101 proof |
101 proof |
102 show "?C(Asemi ac1 ac2)" |
102 show "?C(Aseq ac1 ac2)" |
103 using ih1 ih2 by (fastforce elim!: pre_mono vc_mono) |
103 using ih1 ih2 by (fastforce elim!: pre_mono vc_mono) |
104 qed |
104 qed |
105 next |
105 next |
106 case (If P b c1 Q c2) |
106 case (If P b c1 Q c2) |
107 from If.IH obtain ac1 where ih1: "?G (\<lambda>s. P s \<and> bval b s) c1 Q ac1" |
107 from If.IH obtain ac1 where ih1: "?G (\<lambda>s. P s \<and> bval b s) c1 Q ac1" |
125 subsection "An Optimization" |
125 subsection "An Optimization" |
126 |
126 |
127 fun vcpre :: "acom \<Rightarrow> assn \<Rightarrow> assn \<times> assn" where |
127 fun vcpre :: "acom \<Rightarrow> assn \<Rightarrow> assn \<times> assn" where |
128 "vcpre ASKIP Q = (\<lambda>s. True, Q)" | |
128 "vcpre ASKIP Q = (\<lambda>s. True, Q)" | |
129 "vcpre (Aassign x a) Q = (\<lambda>s. True, \<lambda>s. Q(s[a/x]))" | |
129 "vcpre (Aassign x a) Q = (\<lambda>s. True, \<lambda>s. Q(s[a/x]))" | |
130 "vcpre (Asemi c\<^isub>1 c\<^isub>2) Q = |
130 "vcpre (Aseq c\<^isub>1 c\<^isub>2) Q = |
131 (let (vc\<^isub>2,wp\<^isub>2) = vcpre c\<^isub>2 Q; |
131 (let (vc\<^isub>2,wp\<^isub>2) = vcpre c\<^isub>2 Q; |
132 (vc\<^isub>1,wp\<^isub>1) = vcpre c\<^isub>1 wp\<^isub>2 |
132 (vc\<^isub>1,wp\<^isub>1) = vcpre c\<^isub>1 wp\<^isub>2 |
133 in (\<lambda>s. vc\<^isub>1 s \<and> vc\<^isub>2 s, wp\<^isub>1))" | |
133 in (\<lambda>s. vc\<^isub>1 s \<and> vc\<^isub>2 s, wp\<^isub>1))" | |
134 "vcpre (Aif b c\<^isub>1 c\<^isub>2) Q = |
134 "vcpre (Aif b c\<^isub>1 c\<^isub>2) Q = |
135 (let (vc\<^isub>2,wp\<^isub>2) = vcpre c\<^isub>2 Q; |
135 (let (vc\<^isub>2,wp\<^isub>2) = vcpre c\<^isub>2 Q; |