| author | nipkow | 
| Sun, 22 Jun 2003 01:06:46 +0200 | |
| changeset 14062 | 7f0d5cc52615 | 
| parent 13875 | 12997e3ddd8d | 
| child 14074 | 93dfce3b6f86 | 
| permissions | -rw-r--r-- | 
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 1 | (* Title: HOL/Hoare/Pointers.thy | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 2 | ID: $Id$ | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 3 | Author: Tobias Nipkow | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 4 | Copyright 2002 TUM | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 5 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 6 | Examples of verifications of pointer programs | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 7 | *) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 8 | |
| 13875 | 9 | theory Pointer_Examples = HeapSyntax: | 
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 10 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 11 | section "Verifications" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 12 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 13 | subsection "List reversal" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 14 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 15 | text "A short but unreadable proof:" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 16 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 17 | lemma "VARS tl p q r | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 18 |   {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {}}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 19 | WHILE p \<noteq> Null | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 20 |   INV {\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 21 | rev ps @ qs = rev Ps @ Qs} | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 22 | DO r := p; p := p^.tl; r^.tl := q; q := r OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 23 |   {List tl q (rev Ps @ Qs)}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 24 | apply vcg_simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 25 | apply fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 26 | apply(fastsimp intro:notin_List_update[THEN iffD2]) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 27 | (* explicit: | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 28 | apply clarify | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 29 | apply(rename_tac ps b qs) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 30 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 31 | apply(rename_tac ps') | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 32 | apply(fastsimp intro:notin_List_update[THEN iffD2]) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 33 | apply(rule_tac x = ps' in exI) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 34 | apply simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 35 | apply(rule_tac x = "b#qs" in exI) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 36 | apply simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 37 | *) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 38 | apply fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 39 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 40 | |
| 14062 | 41 | text{* And now with ghost variables @{term ps} and @{term qs}. Even
 | 
| 42 | ``more automatic''. *} | |
| 43 | ||
| 44 | lemma "VARS next p ps q qs r | |
| 45 |   {List next p Ps \<and> List next q Qs \<and> set Ps \<inter> set Qs = {} \<and>
 | |
| 46 | ps = Ps \<and> qs = Qs} | |
| 47 | WHILE p \<noteq> Null | |
| 48 |   INV {List next p ps \<and> List next q qs \<and> set ps \<inter> set qs = {} \<and>
 | |
| 49 | rev ps @ qs = rev Ps @ Qs} | |
| 50 | DO r := p; p := p^.next; r^.next := q; q := r; | |
| 51 | qs := (hd ps) # qs; ps := tl ps OD | |
| 52 |   {List next q (rev Ps @ Qs)}"
 | |
| 53 | apply vcg_simp | |
| 54 | apply fastsimp | |
| 55 | apply fastsimp | |
| 56 | done | |
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 57 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 58 | text "A longer readable version:" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 59 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 60 | lemma "VARS tl p q r | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 61 |   {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {}}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 62 | WHILE p \<noteq> Null | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 63 |   INV {\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 64 | rev ps @ qs = rev Ps @ Qs} | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 65 | DO r := p; p := p^.tl; r^.tl := q; q := r OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 66 |   {List tl q (rev Ps @ Qs)}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 67 | proof vcg | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 68 | fix tl p q r | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 69 |   assume "List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 70 |   thus "\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 71 | rev ps @ qs = rev Ps @ Qs" by fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 72 | next | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 73 | fix tl p q r | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 74 |   assume "(\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 75 | rev ps @ qs = rev Ps @ Qs) \<and> p \<noteq> Null" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 76 | (is "(\<exists>ps qs. ?I ps qs) \<and> _") | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 77 | then obtain ps qs a where I: "?I ps qs \<and> p = Ref a" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 78 | by fast | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 79 | then obtain ps' where "ps = a # ps'" by fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 80 | hence "List (tl(p \<rightarrow> q)) (p^.tl) ps' \<and> | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 81 | List (tl(p \<rightarrow> q)) p (a#qs) \<and> | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 82 |          set ps' \<inter> set (a#qs) = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 83 | rev ps' @ (a#qs) = rev Ps @ Qs" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 84 | using I by fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 85 | thus "\<exists>ps' qs'. List (tl(p \<rightarrow> q)) (p^.tl) ps' \<and> | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 86 | List (tl(p \<rightarrow> q)) p qs' \<and> | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 87 |                   set ps' \<inter> set qs' = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 88 | rev ps' @ qs' = rev Ps @ Qs" by fast | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 89 | next | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 90 | fix tl p q r | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 91 |   assume "(\<exists>ps qs. List tl p ps \<and> List tl q qs \<and> set ps \<inter> set qs = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 92 | rev ps @ qs = rev Ps @ Qs) \<and> \<not> p \<noteq> Null" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 93 | thus "List tl q (rev Ps @ Qs)" by fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 94 | qed | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 95 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 96 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 97 | text{* Finaly, the functional version. A bit more verbose, but automatic! *}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 98 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 99 | lemma "VARS tl p q r | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 100 |   {islist tl p \<and> islist tl q \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 101 |    Ps = list tl p \<and> Qs = list tl q \<and> set Ps \<inter> set Qs = {}}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 102 | WHILE p \<noteq> Null | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 103 |   INV {islist tl p \<and> islist tl q \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 104 |        set(list tl p) \<inter> set(list tl q) = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 105 | rev(list tl p) @ (list tl q) = rev Ps @ Qs} | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 106 | DO r := p; p := p^.tl; r^.tl := q; q := r OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 107 |   {islist tl q \<and> list tl q = rev Ps @ Qs}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 108 | apply vcg_simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 109 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 110 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 111 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 112 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 113 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 114 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 115 | subsection "Searching in a list" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 116 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 117 | text{*What follows is a sequence of successively more intelligent proofs that
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 118 | a simple loop finds an element in a linked list. | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 119 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 120 | We start with a proof based on the @{term List} predicate. This means it only
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 121 | works for acyclic lists. *} | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 122 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 123 | lemma "VARS tl p | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 124 |   {List tl p Ps \<and> X \<in> set Ps}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 125 | WHILE p \<noteq> Null \<and> p \<noteq> Ref X | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 126 |   INV {\<exists>ps. List tl p ps \<and> X \<in> set ps}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 127 | DO p := p^.tl OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 128 |   {p = Ref X}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 129 | apply vcg_simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 130 | apply blast | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 131 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 132 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 133 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 134 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 135 | text{*Using @{term Path} instead of @{term List} generalizes the correctness
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 136 | statement to cyclic lists as well: *} | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 137 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 138 | lemma "VARS tl p | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 139 |   {Path tl p Ps X}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 140 | WHILE p \<noteq> Null \<and> p \<noteq> X | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 141 |   INV {\<exists>ps. Path tl p ps X}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 142 | DO p := p^.tl OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 143 |   {p = X}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 144 | apply vcg_simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 145 | apply blast | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 146 | apply fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 147 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 148 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 149 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 150 | text{*Now it dawns on us that we do not need the list witness at all --- it
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 151 | suffices to talk about reachability, i.e.\ we can use relations directly. The | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 152 | first version uses a relation on @{typ"'a ref"}: *}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 153 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 154 | lemma "VARS tl p | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 155 |   {(p,X) \<in> {(Ref x,tl x) |x. True}^*}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 156 | WHILE p \<noteq> Null \<and> p \<noteq> X | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 157 |   INV {(p,X) \<in> {(Ref x,tl x) |x. True}^*}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 158 | DO p := p^.tl OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 159 |   {p = X}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 160 | apply vcg_simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 161 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 162 | apply(erule converse_rtranclE) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 163 | apply simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 164 | apply(clarsimp elim:converse_rtranclE) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 165 | apply(fast elim:converse_rtranclE) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 166 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 167 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 168 | text{*Finally, a version based on a relation on type @{typ 'a}:*}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 169 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 170 | lemma "VARS tl p | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 171 |   {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}^*}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 172 | WHILE p \<noteq> Null \<and> p \<noteq> Ref X | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 173 |   INV {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}^*}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 174 | DO p := p^.tl OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 175 |   {p = Ref X}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 176 | apply vcg_simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 177 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 178 | apply(erule converse_rtranclE) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 179 | apply simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 180 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 181 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 182 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 183 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 184 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 185 | subsection "Merging two lists" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 186 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 187 | text"This is still a bit rough, especially the proof." | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 188 | |
| 13773 | 189 | constdefs | 
| 190 | cor :: "bool \<Rightarrow> bool \<Rightarrow> bool" | |
| 191 | "cor P Q == if P then True else Q" | |
| 192 | cand :: "bool \<Rightarrow> bool \<Rightarrow> bool" | |
| 193 | "cand P Q == if P then Q else False" | |
| 194 | ||
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 195 | consts merge :: "'a list * 'a list * ('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a list"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 196 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 197 | recdef merge "measure(%(xs,ys,f). size xs + size ys)" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 198 | "merge(x#xs,y#ys,f) = (if f x y then x # merge(xs,y#ys,f) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 199 | else y # merge(x#xs,ys,f))" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 200 | "merge(x#xs,[],f) = x # merge(xs,[],f)" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 201 | "merge([],y#ys,f) = y # merge([],ys,f)" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 202 | "merge([],[],f) = []" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 203 | |
| 13773 | 204 | text{* Simplifies the proof a little: *}
 | 
| 205 | ||
| 206 | lemma [simp]: "({} = insert a A \<inter> B) = (a \<notin> B & {} = A \<inter> B)"
 | |
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 207 | by blast | 
| 13773 | 208 | lemma [simp]: "({} = A \<inter> insert b B) = (b \<notin> A & {} = A \<inter> B)"
 | 
| 209 | by blast | |
| 210 | lemma [simp]: "({} = A \<inter> (B \<union> C)) = ({} = A \<inter> B & {} = A \<inter> C)"
 | |
| 211 | by blast | |
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 212 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 213 | lemma "VARS hd tl p q r s | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 214 |  {List tl p Ps \<and> List tl q Qs \<and> set Ps \<inter> set Qs = {} \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 215 | (p \<noteq> Null \<or> q \<noteq> Null)} | 
| 13773 | 216 | IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) | 
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 217 | THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 218 | s := r; | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 219 | WHILE p \<noteq> Null \<or> q \<noteq> Null | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 220 |  INV {EX rs ps qs a. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 221 | distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 222 | merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 223 | rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 224 | (tl a = p \<or> tl a = q)} | 
| 13773 | 225 | DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) | 
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 226 | THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI; | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 227 | s := s^.tl | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 228 | OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 229 |  {List tl r (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 230 | apply vcg_simp | 
| 13773 | 231 | apply (simp_all add: cand_def cor_def) | 
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 232 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 233 | apply (fastsimp) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 234 | |
| 13773 | 235 | apply clarsimp | 
| 236 | apply(rule conjI) | |
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 237 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 238 | apply(rule conjI) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 239 | apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 240 | apply clarsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 241 | apply(rule conjI) | 
| 13773 | 242 | apply (clarsimp) | 
| 243 | apply(rule_tac x = "rs @ [a]" in exI) | |
| 244 | apply(clarsimp simp:eq_sym_conv) | |
| 245 | apply(rule_tac x = "bs" in exI) | |
| 246 | apply(clarsimp simp:eq_sym_conv) | |
| 247 | apply(rule_tac x = "ya#bsa" in exI) | |
| 248 | apply(simp) | |
| 249 | apply(clarsimp simp:eq_sym_conv) | |
| 250 | apply(rule_tac x = "rs @ [a]" in exI) | |
| 251 | apply(clarsimp simp:eq_sym_conv) | |
| 252 | apply(rule_tac x = "y#bs" in exI) | |
| 253 | apply(clarsimp simp:eq_sym_conv) | |
| 254 | apply(rule_tac x = "bsa" in exI) | |
| 255 | apply(simp) | |
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 256 | apply (fastsimp intro!:Path_snoc intro:Path_upd[THEN iffD2] notin_List_update[THEN iffD2] simp:eq_sym_conv) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 257 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 258 | apply(clarsimp simp add:List_app) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 259 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 260 | |
| 13773 | 261 | |
| 262 | text{* More of the proof can be automated, but the runtime goes up
 | |
| 263 | drastically. In general it is usually more efficient to give the | |
| 264 | witness directly than to have it found by proof. | |
| 265 | ||
| 266 | Now we try a functional version of the abstraction relation @{term
 | |
| 267 | Path}. Since the result is not that convincing, we do not prove any of | |
| 268 | the lemmas.*} | |
| 269 | ||
| 270 | consts ispath:: "('a \<Rightarrow> 'a ref) \<Rightarrow> 'a ref \<Rightarrow> 'a ref \<Rightarrow> bool"
 | |
| 271 |        path:: "('a \<Rightarrow> 'a ref) \<Rightarrow> 'a ref \<Rightarrow> 'a ref \<Rightarrow> 'a list"
 | |
| 272 | ||
| 273 | ML"set quick_and_dirty" | |
| 274 | ||
| 275 | text"First some basic lemmas:" | |
| 276 | ||
| 277 | lemma [simp]: "ispath f p p" | |
| 278 | sorry | |
| 279 | lemma [simp]: "path f p p = []" | |
| 280 | sorry | |
| 281 | lemma [simp]: "ispath f p q \<Longrightarrow> a \<notin> set(path f p q) \<Longrightarrow> ispath (f(a := r)) p q" | |
| 282 | sorry | |
| 283 | lemma [simp]: "ispath f p q \<Longrightarrow> a \<notin> set(path f p q) \<Longrightarrow> | |
| 284 | path (f(a := r)) p q = path f p q" | |
| 285 | sorry | |
| 286 | ||
| 287 | text"Some more specific lemmas needed by the example:" | |
| 288 | ||
| 289 | lemma [simp]: "ispath (f(a := q)) p (Ref a) \<Longrightarrow> ispath (f(a := q)) p q" | |
| 290 | sorry | |
| 291 | lemma [simp]: "ispath (f(a := q)) p (Ref a) \<Longrightarrow> | |
| 292 | path (f(a := q)) p q = path (f(a := q)) p (Ref a) @ [a]" | |
| 293 | sorry | |
| 294 | lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Ref b \<Longrightarrow> | |
| 295 | b \<notin> set (path f p (Ref a))" | |
| 296 | sorry | |
| 297 | lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Null \<Longrightarrow> islist f p" | |
| 298 | sorry | |
| 299 | lemma [simp]: "ispath f p (Ref a) \<Longrightarrow> f a = Null \<Longrightarrow> list f p = path f p (Ref a) @ [a]" | |
| 300 | sorry | |
| 301 | ||
| 302 | lemma [simp]: "islist f p \<Longrightarrow> distinct (list f p)" | |
| 303 | sorry | |
| 304 | ML"reset quick_and_dirty" | |
| 305 | ||
| 306 | lemma "VARS hd tl p q r s | |
| 307 |  {islist tl p & Ps = list tl p \<and> islist tl q & Qs = list tl q \<and>
 | |
| 308 |   set Ps \<inter> set Qs = {} \<and>
 | |
| 309 | (p \<noteq> Null \<or> q \<noteq> Null)} | |
| 310 | IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) | |
| 311 | THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; | |
| 312 | s := r; | |
| 313 | WHILE p \<noteq> Null \<or> q \<noteq> Null | |
| 314 |  INV {EX rs ps qs a. ispath tl r s & rs = path tl r s \<and>
 | |
| 315 | islist tl p & ps = list tl p \<and> islist tl q & qs = list tl q \<and> | |
| 316 | distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> | |
| 317 | merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = | |
| 318 | rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> | |
| 319 | (tl a = p \<or> tl a = q)} | |
| 320 | DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) | |
| 321 | THEN s^.tl := p; p := p^.tl ELSE s^.tl := q; q := q^.tl FI; | |
| 322 | s := s^.tl | |
| 323 | OD | |
| 324 |  {islist tl r & list tl r = (merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y))}"
 | |
| 325 | apply vcg_simp | |
| 326 | ||
| 327 | apply (simp_all add: cand_def cor_def) | |
| 328 | apply (fastsimp) | |
| 329 | apply (fastsimp simp: eq_sym_conv) | |
| 330 | apply(clarsimp) | |
| 331 | done | |
| 332 | ||
| 333 | text"The proof is automatic, but requires a numbet of special lemmas." | |
| 334 | ||
| 14062 | 335 | text{* And now with ghost variables: *}
 | 
| 336 | ||
| 337 | lemma "VARS elem next p q r s ps qs rs a | |
| 338 |  {List next p Ps \<and> List next q Qs \<and> set Ps \<inter> set Qs = {} \<and>
 | |
| 339 | (p \<noteq> Null \<or> q \<noteq> Null) \<and> ps = Ps \<and> qs = Qs} | |
| 340 | IF cor (q = Null) (cand (p \<noteq> Null) (p^.elem \<le> q^.elem)) | |
| 341 | THEN r := p; p := p^.next; ps := tl ps | |
| 342 | ELSE r := q; q := q^.next; qs := tl qs FI; | |
| 343 | s := r; rs := []; a := addr s; | |
| 344 | WHILE p \<noteq> Null \<or> q \<noteq> Null | |
| 345 |  INV {Path next r rs s \<and> List next p ps \<and> List next q qs \<and>
 | |
| 346 | distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> | |
| 347 | merge(Ps,Qs,\<lambda>x y. elem x \<le> elem y) = | |
| 348 | rs @ a # merge(ps,qs,\<lambda>x y. elem x \<le> elem y) \<and> | |
| 349 | (next a = p \<or> next a = q)} | |
| 350 | DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.elem \<le> q^.elem)) | |
| 351 | THEN s^.next := p; p := p^.next; ps := tl ps | |
| 352 | ELSE s^.next := q; q := q^.next; qs := tl qs FI; | |
| 353 | rs := rs @ [a]; s := s^.next; a := addr s | |
| 354 | OD | |
| 355 |  {List next r (merge(Ps,Qs,\<lambda>x y. elem x \<le> elem y))}"
 | |
| 356 | apply vcg_simp | |
| 357 | apply (simp_all add: cand_def cor_def) | |
| 358 | ||
| 359 | apply (fastsimp) | |
| 360 | ||
| 361 | apply clarsimp | |
| 362 | apply(rule conjI) | |
| 363 | apply(clarsimp) | |
| 364 | apply(rule conjI) | |
| 365 | apply(clarsimp simp:eq_sym_conv) | |
| 366 | apply(clarsimp simp:eq_sym_conv) | |
| 367 | apply(clarsimp simp:eq_sym_conv) | |
| 368 | ||
| 369 | apply(clarsimp simp add:List_app) | |
| 370 | done | |
| 371 | ||
| 372 | text{* The proof is a LOT simpler because it does not need
 | |
| 373 | instantiations anymore, but it is still not quite automatic, probably | |
| 374 | because of this wrong orientation business. *} | |
| 13772 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 375 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 376 | subsection "Storage allocation" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 377 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 378 | constdefs new :: "'a set \<Rightarrow> 'a" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 379 | "new A == SOME a. a \<notin> A" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 380 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 381 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 382 | lemma new_notin: | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 383 | "\<lbrakk> ~finite(UNIV::'a set); finite(A::'a set); B \<subseteq> A \<rbrakk> \<Longrightarrow> new (A) \<notin> B" | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 384 | apply(unfold new_def) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 385 | apply(rule someI2_ex) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 386 | apply (fast intro:ex_new_if_finite) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 387 | apply (fast) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 388 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 389 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 390 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 391 | lemma "~finite(UNIV::'a set) \<Longrightarrow> | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 392 | VARS xs elem next alloc p q | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 393 |   {Xs = xs \<and> p = (Null::'a ref)}
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 394 | WHILE xs \<noteq> [] | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 395 |   INV {islist next p \<and> set(list next p) \<subseteq> set alloc \<and>
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 396 | map elem (rev(list next p)) @ xs = Xs} | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 397 | DO q := Ref(new(set alloc)); alloc := (addr q)#alloc; | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 398 | q^.next := p; q^.elem := hd xs; xs := tl xs; p := q | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 399 | OD | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 400 |   {islist next p \<and> map elem (rev(list next p)) = Xs}"
 | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 401 | apply vcg_simp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 402 | apply (clarsimp simp: subset_insert_iff neq_Nil_conv fun_upd_apply new_notin) | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 403 | apply fastsimp | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 404 | done | 
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 405 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 406 | |
| 
73d041cc6a66
Split Pointers.thy and automated one proof, which caused the runtime to explode
 nipkow parents: diff
changeset | 407 | end |