202 rev ps @ qs = rev Ps @ Qs} |
202 rev ps @ qs = rev Ps @ Qs} |
203 DO r := p; p := p^.tl; r^.tl := q; q := r OD |
203 DO r := p; p := p^.tl; r^.tl := q; q := r OD |
204 {List tl q (rev Ps @ Qs)}" |
204 {List tl q (rev Ps @ Qs)}" |
205 apply vcg_simp |
205 apply vcg_simp |
206 apply fastsimp |
206 apply fastsimp |
|
207 apply(fastsimp intro:notin_List_update[THEN iffD2]) |
|
208 (* explicit: |
207 apply clarify |
209 apply clarify |
208 apply(rename_tac ps b qs) |
210 apply(rename_tac ps b qs) |
209 apply clarsimp |
211 apply clarsimp |
210 apply(rename_tac ps') |
212 apply(rename_tac ps') |
|
213 apply(fastsimp intro:notin_List_update[THEN iffD2]) |
211 apply(rule_tac x = ps' in exI) |
214 apply(rule_tac x = ps' in exI) |
212 apply simp |
215 apply simp |
213 apply(rule_tac x = "b#qs" in exI) |
216 apply(rule_tac x = "b#qs" in exI) |
214 apply simp |
217 apply simp |
|
218 *) |
215 apply fastsimp |
219 apply fastsimp |
216 done |
220 done |
217 |
221 |
218 |
222 |
219 text "A longer readable version:" |
223 text "A longer readable version:" |
282 works for acyclic lists. *} |
286 works for acyclic lists. *} |
283 |
287 |
284 lemma "VARS tl p |
288 lemma "VARS tl p |
285 {List tl p Ps \<and> X \<in> set Ps} |
289 {List tl p Ps \<and> X \<in> set Ps} |
286 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
290 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
287 INV {p \<noteq> Null \<and> (\<exists>ps. List tl p ps \<and> X \<in> set ps)} |
291 INV {\<exists>ps. List tl p ps \<and> X \<in> set ps} |
288 DO p := p^.tl OD |
292 DO p := p^.tl OD |
289 {p = Ref X}" |
293 {p = Ref X}" |
290 apply vcg_simp |
294 apply vcg_simp |
291 apply(case_tac p) |
295 apply blast |
292 apply clarsimp |
296 apply clarsimp |
293 apply fastsimp |
|
294 apply clarsimp |
|
295 apply fastsimp |
|
296 apply clarsimp |
297 apply clarsimp |
297 done |
298 done |
298 |
299 |
299 text{*Using @{term Path} instead of @{term List} generalizes the correctness |
300 text{*Using @{term Path} instead of @{term List} generalizes the correctness |
300 statement to cyclic lists as well: *} |
301 statement to cyclic lists as well: *} |
301 |
302 |
302 lemma "VARS tl p |
303 lemma "VARS tl p |
303 {Path tl p Ps (Ref X)} |
304 {Path tl p Ps X} |
304 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
305 WHILE p \<noteq> Null \<and> p \<noteq> X |
305 INV {p \<noteq> Null \<and> (\<exists>ps. Path tl p ps (Ref X))} |
306 INV {\<exists>ps. Path tl p ps X} |
306 DO p := p^.tl OD |
307 DO p := p^.tl OD |
307 {p = Ref X}" |
308 {p = X}" |
308 apply vcg_simp |
309 apply vcg_simp |
309 apply(case_tac p) |
|
310 apply clarsimp |
|
311 apply(rule conjI) |
|
312 apply simp |
|
313 apply blast |
310 apply blast |
314 apply clarsimp |
311 apply fastsimp |
315 apply(erule disjE) |
|
316 apply clarsimp |
|
317 apply(erule disjE) |
|
318 apply clarsimp |
|
319 apply clarsimp |
|
320 apply clarsimp |
312 apply clarsimp |
321 done |
313 done |
322 |
314 |
323 text{*Now it dawns on us that we do not need the list witness at all --- it |
315 text{*Now it dawns on us that we do not need the list witness at all --- it |
324 suffices to talk about reachability, i.e.\ we can use relations directly. The |
316 suffices to talk about reachability, i.e.\ we can use relations directly. The |
325 first version uses a relation on @{typ"'a option"} and needs a lemma: *} |
317 first version uses a relation on @{typ"'a ref"}: *} |
326 |
|
327 lemma lem1: "(\<forall>(x,y) \<in>r. a \<noteq> x) \<Longrightarrow> ((a,b) \<in> r^* = (a=b))" |
|
328 apply(rule iffI) |
|
329 apply(erule converse_rtranclE) |
|
330 apply assumption |
|
331 apply blast |
|
332 apply simp |
|
333 done |
|
334 |
318 |
335 lemma "VARS tl p |
319 lemma "VARS tl p |
336 {Ref X \<in> ({(Ref x,tl x) |x. True}^* `` {p})} |
320 {(p,X) \<in> {(Ref x,tl x) |x. True}^*} |
337 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
321 WHILE p \<noteq> Null \<and> p \<noteq> X |
338 INV {p \<noteq> Null \<and> Ref X \<in> ({(Ref x,tl x) |x. True}^* `` {p})} |
322 INV {(p,X) \<in> {(Ref x,tl x) |x. True}^*} |
339 DO p := p^.tl OD |
323 DO p := p^.tl OD |
340 {p = Ref X}" |
324 {p = X}" |
341 apply vcg_simp |
325 apply vcg_simp |
342 apply(case_tac p) |
|
343 apply(simp add:lem1 eq_sym_conv) |
|
344 apply simp |
|
345 apply clarsimp |
326 apply clarsimp |
346 apply(erule converse_rtranclE) |
327 apply(erule converse_rtranclE) |
347 apply simp |
328 apply simp |
348 apply(clarsimp simp add:lem1 eq_sym_conv) |
329 apply(clarsimp elim:converse_rtranclE) |
349 apply clarsimp |
330 apply(fast elim:converse_rtranclE) |
350 done |
331 done |
351 |
332 |
352 text{*Finally, the simplest version, based on a relation on type @{typ 'a}:*} |
333 text{*Finally, a version based on a relation on type @{typ 'a}:*} |
353 |
334 |
354 lemma "VARS tl p |
335 lemma "VARS tl p |
355 {p \<noteq> Null \<and> X \<in> ({(x,y). tl x = Ref y}^* `` {addr p})} |
336 {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}^*} |
356 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
337 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
357 INV {p \<noteq> Null \<and> X \<in> ({(x,y). tl x = Ref y}^* `` {addr p})} |
338 INV {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}^*} |
358 DO p := p^.tl OD |
339 DO p := p^.tl OD |
359 {p = Ref X}" |
340 {p = Ref X}" |
360 apply vcg_simp |
341 apply vcg_simp |
361 apply clarsimp |
342 apply clarsimp |
362 apply(erule converse_rtranclE) |
343 apply(erule converse_rtranclE) |