|
1 theory Collecting1 |
|
2 imports Collecting |
|
3 begin |
|
4 |
|
5 subsection "A small step semantics on annotated commands" |
|
6 |
|
7 text{* The idea: the state is propagated through the annotated command as an |
|
8 annotation @{term "Some s"}, all other annotations are @{const None}. *} |
|
9 |
|
10 fun join :: "'a option \<Rightarrow> 'a option \<Rightarrow> 'a option" where |
|
11 "join None x = x" | |
|
12 "join x None = x" |
|
13 |
|
14 definition bfilter :: "bexp \<Rightarrow> bool \<Rightarrow> state option \<Rightarrow> state option" where |
|
15 "bfilter b r so = |
|
16 (case so of None \<Rightarrow> None | Some s \<Rightarrow> if bval b s = r then Some s else None)" |
|
17 |
|
18 lemma bfilter_None[simp]: "bfilter b r None = None" |
|
19 by(simp add: bfilter_def split: option.split) |
|
20 |
|
21 fun step1 :: "state option \<Rightarrow> state option acom \<Rightarrow> state option acom" where |
|
22 "step1 so (SKIP {P}) = SKIP {so}" | |
|
23 "step1 so (x::=e {P}) = |
|
24 x ::= e {case so of None \<Rightarrow> None | Some s \<Rightarrow> Some(s(x := aval e s))}" | |
|
25 "step1 so (c1;c2) = step1 so c1; step1 (post c1) c2" | |
|
26 "step1 so (IF b THEN c1 ELSE c2 {P}) = |
|
27 IF b THEN step1 (bfilter b True so) c1 |
|
28 ELSE step1 (bfilter b False so) c2 |
|
29 {join (post c1) (post c2)}" | |
|
30 "step1 so ({I} WHILE b DO c {P}) = |
|
31 {join so (post c)} |
|
32 WHILE b DO step1 (bfilter b True I) c |
|
33 {bfilter b False I}" |
|
34 |
|
35 definition "show_acom xs = map_acom (Option.map (show_state xs))" |
|
36 |
|
37 definition |
|
38 "p1 = ''x'' ::= N 2; IF Less (V ''x'') (N 3) THEN ''x'' ::= N 1 ELSE com.SKIP" |
|
39 |
|
40 definition "p2 = |
|
41 ''x'' ::= N 0; WHILE Less (V ''x'') (N 2) DO ''x'' ::= Plus (V ''x'') (N 1)" |
|
42 |
|
43 value "show_acom [''x''] |
|
44 (((step1 None)^^6) (step1 (Some <>) (anno None p2)))" |
|
45 |
|
46 subsubsection "Relating the small step and the collecting semantics" |
|
47 |
|
48 hide_const (open) set |
|
49 |
|
50 abbreviation set :: "'a option acom \<Rightarrow> 'a set acom" where |
|
51 "set == map_acom Option.set" |
|
52 |
|
53 definition some :: "'a option \<Rightarrow> nat" where |
|
54 "some opt = (case opt of Some x \<Rightarrow> 1 | None \<Rightarrow> 0)" |
|
55 |
|
56 lemma some[simp]: "some None = 0 \<and> some (Some x) = 1" |
|
57 by(simp add: some_def split:option.split) |
|
58 |
|
59 fun somes :: "'a option acom \<Rightarrow> nat" where |
|
60 "somes(SKIP {p}) = some p" | |
|
61 "somes(x::=e {p}) = some p" | |
|
62 "somes(c1;c2) = somes c1 + somes c2" | |
|
63 "somes(IF b THEN c1 ELSE c2 {p}) = somes c1 + somes c2 + some p" | |
|
64 "somes({i} WHILE b DO c {p}) = some i + somes c + some p" |
|
65 |
|
66 lemma some_anno_None: "somes(anno None c) = 0" |
|
67 by(induction c) auto |
|
68 |
|
69 lemma some_post: "some(post co) \<le> somes co" |
|
70 by(induction co) auto |
|
71 |
|
72 lemma some_join: |
|
73 "some so1 + some so2 \<le> 1 \<Longrightarrow> some(join so1 so2) = some so1 + some so2" |
|
74 by(simp add: some_def split: option.splits) |
|
75 |
|
76 lemma somes_step1: "some so + somes co \<le> 1 \<Longrightarrow> |
|
77 somes(step1 so co) + some(post co) = some so + somes co" |
|
78 proof(induction co arbitrary: so) |
|
79 case SKIP thus ?case by simp |
|
80 next |
|
81 case Assign thus ?case by (simp split:option.split) |
|
82 next |
|
83 case (Semi co1 _) |
|
84 from Semi.prems Semi.IH(1)[of so] Semi.IH(2)[of "post co1"] |
|
85 show ?case by simp |
|
86 next |
|
87 case (If b) |
|
88 from If.prems If.IH(1)[of "bfilter b True so"] |
|
89 If.prems If.IH(2)[of "bfilter b False so"] |
|
90 show ?case |
|
91 by (auto simp: bfilter_def some_join split:option.split) |
|
92 next |
|
93 case (While i b c p) |
|
94 from While.prems While.IH[of "bfilter b True i"] |
|
95 show ?case |
|
96 by(auto simp: bfilter_def some_join split:option.split) |
|
97 qed |
|
98 |
|
99 lemma post_map_acom[simp]: "post(map_acom f c) = f(post c)" |
|
100 by(induction c) auto |
|
101 |
|
102 lemma join_eq_Some: "some so1 + some so2 \<le> 1 \<Longrightarrow> |
|
103 join so1 so2 = Some s = |
|
104 (so1 = Some s & so2 = None | so1 = None & so2 = Some s)" |
|
105 apply(cases so1) apply simp |
|
106 apply(cases so2) apply auto |
|
107 done |
|
108 |
|
109 lemma set_bfilter: |
|
110 "Option.set (bfilter b r so) = {s : Option.set so. bval b s = r}" |
|
111 by(auto simp: bfilter_def split: option.splits) |
|
112 |
|
113 lemma set_join: "some so1 + some so2 \<le> 1 \<Longrightarrow> |
|
114 Option.set (join so1 so2) = Option.set so1 \<union> Option.set so2" |
|
115 apply(cases so1) apply simp |
|
116 apply(cases so2) apply auto |
|
117 done |
|
118 |
|
119 lemma add_le1_iff: "m + n \<le> (Suc 0) \<longleftrightarrow> (m=0 \<and> n\<le>1 | m\<le>1 & n=0)" |
|
120 by arith |
|
121 |
|
122 lemma some_0_iff: "some opt = 0 \<longleftrightarrow> opt = None" |
|
123 by(auto simp add: some_def split: option.splits) |
|
124 |
|
125 lemma some_le1[simp]: "some x \<le> Suc 0" |
|
126 by(auto simp add: some_def split: option.splits) |
|
127 |
|
128 lemma step1_preserves_le: |
|
129 "\<lbrakk> step_cs S cs = cs; Option.set so \<subseteq> S; set co \<le> cs; |
|
130 somes co + some so \<le> 1 \<rbrakk> \<Longrightarrow> |
|
131 set(step1 so co) \<le> cs" |
|
132 proof(induction co arbitrary: S cs so) |
|
133 case SKIP thus ?case by (clarsimp simp: SKIP_le) |
|
134 next |
|
135 case Assign thus ?case by (fastforce simp: Assign_le split: option.splits) |
|
136 next |
|
137 case (Semi co1 co2) |
|
138 from Semi.prems show ?case using some_post[of co1] |
|
139 by (fastforce simp add: Semi_le add_le1_iff Semi.IH dest: le_post) |
|
140 next |
|
141 case (If _ co1 co2) |
|
142 from If.prems show ?case |
|
143 using some_post[of co1] some_post[of co2] |
|
144 by (fastforce simp: If_le add_le1_iff some_0_iff set_bfilter subset_iff |
|
145 join_eq_Some If.IH dest: le_post) |
|
146 next |
|
147 case (While _ _ co) |
|
148 from While.prems show ?case |
|
149 using some_post[of co] |
|
150 by (fastforce simp: While_le set_bfilter subset_iff join_eq_Some |
|
151 add_le1_iff some_0_iff While.IH dest: le_post) |
|
152 qed |
|
153 |
|
154 lemma step1_None_preserves_le: |
|
155 "\<lbrakk> step_cs S cs = cs; set co \<le> cs; somes co \<le> 1 \<rbrakk> \<Longrightarrow> |
|
156 set(step1 None co) \<le> cs" |
|
157 by(auto dest: step1_preserves_le[of _ _ None]) |
|
158 |
|
159 lemma step1_Some_preserves_le: |
|
160 "\<lbrakk> step_cs S cs = cs; s : S; set co \<le> cs; somes co = 0 \<rbrakk> \<Longrightarrow> |
|
161 set(step1 (Some s) co) \<le> cs" |
|
162 by(auto dest: step1_preserves_le[of _ _ "Some s"]) |
|
163 |
|
164 lemma steps_None_preserves_le: assumes "step_cs S cs = cs" |
|
165 shows "set co \<le> cs \<Longrightarrow> somes co \<le> 1 \<Longrightarrow> set ((step1 None ^^ n) co) \<le> cs" |
|
166 proof(induction n arbitrary: co) |
|
167 case 0 thus ?case by simp |
|
168 next |
|
169 case (Suc n) thus ?case |
|
170 using somes_step1[of None co] step1_None_preserves_le[OF assms Suc.prems] |
|
171 by(simp add:funpow_swap1 Suc.IH) |
|
172 qed |
|
173 |
|
174 |
|
175 definition steps :: "state \<Rightarrow> com \<Rightarrow> nat \<Rightarrow> state option acom" where |
|
176 "steps s c n = ((step1 None)^^n) (step1 (Some s) (anno None c))" |
|
177 |
|
178 lemma steps_approx_fix_step_cs: assumes "step_cs S cs = cs" and "s:S" |
|
179 shows "set (steps s (strip cs) n) \<le> cs" |
|
180 proof- |
|
181 { fix c have "somes (anno None c) = 0" by(induction c) auto } |
|
182 note somes_None = this |
|
183 let ?cNone = "anno None (strip cs)" |
|
184 have "set ?cNone \<le> cs" by(induction cs) auto |
|
185 from step1_Some_preserves_le[OF assms this somes_None] |
|
186 have 1: "set(step1 (Some s) ?cNone) \<le> cs" . |
|
187 have 2: "somes (step1 (Some s) ?cNone) \<le> 1" |
|
188 using some_post somes_step1[of "Some s" ?cNone] |
|
189 by (simp add:some_anno_None[of "strip cs"]) |
|
190 from steps_None_preserves_le[OF assms(1) 1 2] |
|
191 show ?thesis by(simp add: steps_def) |
|
192 qed |
|
193 |
|
194 theorem steps_approx_CS: "s:S \<Longrightarrow> set (steps s c n) \<le> CS S c" |
|
195 by (metis CS_unfold steps_approx_fix_step_cs strip_CS) |
|
196 |
|
197 lemma While_final_False: "(WHILE b DO c, s) \<Rightarrow> t \<Longrightarrow> \<not> bval b t" |
|
198 by(induct "WHILE b DO c" s t rule: big_step_induct) simp_all |
|
199 |
|
200 lemma step_cs_complete: |
|
201 "\<lbrakk> step_cs S c = c; (strip c,s) \<Rightarrow> t; s:S \<rbrakk> \<Longrightarrow> t : post c" |
|
202 proof(induction c arbitrary: S s t) |
|
203 case (While Inv b c P) |
|
204 from While.prems have inv: "step_cs {s:Inv. bval b s} c = c" |
|
205 and "post c \<subseteq> Inv" and "S \<subseteq> Inv" and "{s:Inv. \<not> bval b s} \<subseteq> P" by(auto) |
|
206 { fix s t have "(WHILE b DO strip c,s) \<Rightarrow> t \<Longrightarrow> s : Inv \<Longrightarrow> t : Inv" |
|
207 proof(induction "WHILE b DO strip c" s t rule: big_step_induct) |
|
208 case WhileFalse thus ?case by simp |
|
209 next |
|
210 case (WhileTrue s1 s2 s3) |
|
211 from WhileTrue.hyps(5) While.IH[OF inv `(strip c, s1) \<Rightarrow> s2`] |
|
212 `s1 : Inv` `post c \<subseteq> Inv` `bval b s1` |
|
213 show ?case by auto |
|
214 qed |
|
215 } note Inv = this |
|
216 from While.prems(2) have "(WHILE b DO strip c, s) \<Rightarrow> t" and "\<not> bval b t" |
|
217 by(auto dest: While_final_False) |
|
218 from Inv[OF this(1)] `s : S` `S \<subseteq> Inv` have "t : Inv" by blast |
|
219 with `{s:Inv. \<not> bval b s} \<subseteq> P` show ?case using `\<not> bval b t` by auto |
|
220 qed auto |
|
221 |
|
222 theorem CS_complete: "\<lbrakk> (c,s) \<Rightarrow> t; s:S \<rbrakk> \<Longrightarrow> t : post(CS S c)" |
|
223 by (metis CS_unfold step_cs_complete strip_CS) |
|
224 |
|
225 end |