168 |
168 |
169 subsection "Merging two lists" |
169 subsection "Merging two lists" |
170 |
170 |
171 text"This is still a bit rough, especially the proof." |
171 text"This is still a bit rough, especially the proof." |
172 |
172 |
|
173 constdefs |
|
174 cor :: "bool \<Rightarrow> bool \<Rightarrow> bool" |
|
175 "cor P Q == if P then True else Q" |
|
176 cand :: "bool \<Rightarrow> bool \<Rightarrow> bool" |
|
177 "cand P Q == if P then Q else False" |
|
178 |
173 consts merge :: "'a list * 'a list * ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list" |
179 consts merge :: "'a list * 'a list * ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list" |
174 |
180 |
175 recdef merge "measure(%(xs,ys,f). size xs + size ys)" |
181 recdef merge "measure(%(xs,ys,f). size xs + size ys)" |
176 "merge(x#xs,y#ys,f) = (if f x y then x # merge(xs,y#ys,f) |
182 "merge(x#xs,y#ys,f) = (if f x y then x # merge(xs,y#ys,f) |
177 else y # merge(x#xs,ys,f))" |
183 else y # merge(x#xs,ys,f))" |
178 "merge(x#xs,[],f) = x # merge(xs,[],f)" |
184 "merge(x#xs,[],f) = x # merge(xs,[],f)" |
179 "merge([],y#ys,f) = y # merge([],ys,f)" |
185 "merge([],y#ys,f) = y # merge([],ys,f)" |
180 "merge([],[],f) = []" |
186 "merge([],[],f) = []" |
181 |
187 |
182 lemma imp_disjCL: "(P|Q \<longrightarrow> R) = ((P \<longrightarrow> R) \<and> (~P \<longrightarrow> Q \<longrightarrow> R))" |
188 text{* Simplifies the proof a little: *} |
|
189 |
|
190 lemma [simp]: "({} = insert a A \<inter> B) = (a \<notin> B & {} = A \<inter> B)" |
183 by blast |
191 by blast |
184 |
192 lemma [simp]: "({} = A \<inter> insert b B) = (b \<notin> A & {} = A \<inter> B)" |
185 declare imp_disjL[simp del] imp_disjCL[simp] |
193 by blast |
|
194 lemma [simp]: "({} = A \<inter> (B \<union> C)) = ({} = A \<inter> B & {} = A \<inter> C)" |
|
195 by blast |
186 |
196 |
187 lemma "VARS hd tl p q r s |
197 lemma "VARS hd tl p q r s |
188 {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {} \<and> |
198 {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {} \<and> |
189 (p \<noteq> Null \<or> q \<noteq> Null)} |
199 (p \<noteq> Null \<or> q \<noteq> Null)} |
190 IF if q = Null then True else p \<noteq> Null \<and> p^.hd \<le> q^.hd |
200 IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
191 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; |
201 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; |
192 s := r; |
202 s := r; |
193 WHILE p \<noteq> Null \<or> q \<noteq> Null |
203 WHILE p \<noteq> Null \<or> q \<noteq> Null |
194 INV {EX rs ps qs a. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and> |
204 INV {EX rs ps qs a. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and> |
195 distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> |
205 distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> |
196 merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = |
206 merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = |
197 rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> |
207 rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> |
198 (tl a = p \<or> tl a = q)} |
208 (tl a = p \<or> tl a = q)} |
199 DO IF if q = Null then True else p \<noteq> Null \<and> p^.hd \<le> q^.hd |
209 DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
200 THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI; |
210 THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI; |
201 s := s^.tl |
211 s := s^.tl |
202 OD |
212 OD |
203 {List tl r (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}" |
213 {List tl r (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}" |
204 apply vcg_simp |
214 apply vcg_simp |
|
215 apply (simp_all add: cand_def cor_def) |
205 |
216 |
206 apply (fastsimp) |
217 apply (fastsimp) |
207 |
218 |
208 (* One big fastsimp does not seem to converge: *) |
219 apply clarsimp |
|
220 apply(rule conjI) |
209 apply clarsimp |
221 apply clarsimp |
210 apply(rule conjI) |
222 apply(rule conjI) |
211 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv) |
223 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv) |
212 apply clarsimp |
224 apply clarsimp |
213 apply(rule conjI) |
225 apply(rule conjI) |
|
226 apply (clarsimp) |
|
227 apply(rule_tac x = "rs @ [a]" in exI) |
|
228 apply(clarsimp simp:eq_sym_conv) |
|
229 apply(rule_tac x = "bs" in exI) |
|
230 apply(clarsimp simp:eq_sym_conv) |
|
231 apply(rule_tac x = "ya#bsa" in exI) |
|
232 apply(simp) |
|
233 apply(clarsimp simp:eq_sym_conv) |
|
234 apply(rule_tac x = "rs @ [a]" in exI) |
|
235 apply(clarsimp simp:eq_sym_conv) |
|
236 apply(rule_tac x = "y#bs" in exI) |
|
237 apply(clarsimp simp:eq_sym_conv) |
|
238 apply(rule_tac x = "bsa" in exI) |
|
239 apply(simp) |
214 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv) |
240 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv) |
215 apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv) |
|
216 |
241 |
217 apply(clarsimp simp add:List_app) |
242 apply(clarsimp simp add:List_app) |
218 done |
243 done |
219 |
244 |
220 (* merging with islist/list instead of List? Unlikely to be simpler *) |
245 |
|
246 text{* More of the proof can be automated, but the runtime goes up |
|
247 drastically. In general it is usually more efficient to give the |
|
248 witness directly than to have it found by proof. |
|
249 |
|
250 Now we try a functional version of the abstraction relation @{term |
|
251 Path}. Since the result is not that convincing, we do not prove any of |
|
252 the lemmas.*} |
|
253 |
|
254 consts ispath:: "('a \<Rightarrow> 'a ref) \<Rightarrow> 'a ref \<Rightarrow> 'a ref \<Rightarrow> bool" |
|
255 path:: "('a \<Rightarrow> 'a ref) \<Rightarrow> 'a ref \<Rightarrow> 'a ref \<Rightarrow> 'a list" |
|
256 |
|
257 ML"set quick_and_dirty" |
|
258 |
|
259 text"First some basic lemmas:" |
|
260 |
|
261 lemma [simp]: "ispath f p p" |
|
262 sorry |
|
263 lemma [simp]: "path f p p = []" |
|
264 sorry |
|
265 lemma [simp]: "ispath f p q \<Longrightarrow> a \<notin> set(path f p q) \<Longrightarrow> ispath (f(a := r)) p q" |
|
266 sorry |
|
267 lemma [simp]: "ispath f p q \<Longrightarrow> a \<notin> set(path f p q) \<Longrightarrow> |
|
268 path (f(a := r)) p q = path f p q" |
|
269 sorry |
|
270 |
|
271 text"Some more specific lemmas needed by the example:" |
|
272 |
|
273 lemma [simp]: "ispath (f(a := q)) p (Ref a) \<Longrightarrow> ispath (f(a := q)) p q" |
|
274 sorry |
|
275 lemma [simp]: "ispath (f(a := q)) p (Ref a) \<Longrightarrow> |
|
276 path (f(a := q)) p q = path (f(a := q)) p (Ref a) @ [a]" |
|
277 sorry |
|
278 lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Ref b \<Longrightarrow> |
|
279 b \<notin> set (path f p (Ref a))" |
|
280 sorry |
|
281 lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Null \<Longrightarrow> islist f p" |
|
282 sorry |
|
283 lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Null \<Longrightarrow> list f p = path f p (Ref a) @ [a]" |
|
284 sorry |
|
285 |
|
286 lemma [simp]: "islist f p \<Longrightarrow> distinct (list f p)" |
|
287 sorry |
|
288 ML"reset quick_and_dirty" |
|
289 |
|
290 lemma "VARS hd tl p q r s |
|
291 {islist tl p & Ps = list tl p \<and> islist tl q & Qs = list tl q \<and> |
|
292 set Ps \<inter> set Qs = {} \<and> |
|
293 (p \<noteq> Null \<or> q \<noteq> Null)} |
|
294 IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
|
295 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; |
|
296 s := r; |
|
297 WHILE p \<noteq> Null \<or> q \<noteq> Null |
|
298 INV {EX rs ps qs a. ispath tl r s & rs = path tl r s \<and> |
|
299 islist tl p & ps = list tl p \<and> islist tl q & qs = list tl q \<and> |
|
300 distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> |
|
301 merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = |
|
302 rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> |
|
303 (tl a = p \<or> tl a = q)} |
|
304 DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
|
305 THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI; |
|
306 s := s^.tl |
|
307 OD |
|
308 {islist tl r & list tl r = (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}" |
|
309 apply vcg_simp |
|
310 |
|
311 apply (simp_all add: cand_def cor_def) |
|
312 apply (fastsimp) |
|
313 apply (fastsimp simp: eq_sym_conv) |
|
314 apply(clarsimp) |
|
315 done |
|
316 |
|
317 text"The proof is automatic, but requires a numbet of special lemmas." |
|
318 |
221 |
319 |
222 subsection "Storage allocation" |
320 subsection "Storage allocation" |
223 |
321 |
224 constdefs new :: "'a set \<Rightarrow> 'a" |
322 constdefs new :: "'a set \<Rightarrow> 'a" |
225 "new A == SOME a. a \<notin> A" |
323 "new A == SOME a. a \<notin> A" |