146 text\<open>Now it dawns on us that we do not need the list witness at all --- it |
146 text\<open>Now it dawns on us that we do not need the list witness at all --- it |
147 suffices to talk about reachability, i.e.\ we can use relations directly. The |
147 suffices to talk about reachability, i.e.\ we can use relations directly. The |
148 first version uses a relation on @{typ"'a ref"}:\<close> |
148 first version uses a relation on @{typ"'a ref"}:\<close> |
149 |
149 |
150 lemma "VARS tl p |
150 lemma "VARS tl p |
151 {(p,X) \<in> {(Ref x,tl x) |x. True}^*} |
151 {(p,X) \<in> {(Ref x,tl x) |x. True}\<^sup>*} |
152 WHILE p \<noteq> Null \<and> p \<noteq> X |
152 WHILE p \<noteq> Null \<and> p \<noteq> X |
153 INV {(p,X) \<in> {(Ref x,tl x) |x. True}^*} |
153 INV {(p,X) \<in> {(Ref x,tl x) |x. True}\<^sup>*} |
154 DO p := p^.tl OD |
154 DO p := p^.tl OD |
155 {p = X}" |
155 {p = X}" |
156 apply vcg_simp |
156 apply vcg_simp |
157 apply clarsimp |
157 apply clarsimp |
158 apply(erule converse_rtranclE) |
158 apply(erule converse_rtranclE) |
162 done |
162 done |
163 |
163 |
164 text\<open>Finally, a version based on a relation on type @{typ 'a}:\<close> |
164 text\<open>Finally, a version based on a relation on type @{typ 'a}:\<close> |
165 |
165 |
166 lemma "VARS tl p |
166 lemma "VARS tl p |
167 {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}^*} |
167 {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}\<^sup>*} |
168 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
168 WHILE p \<noteq> Null \<and> p \<noteq> Ref X |
169 INV {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}^*} |
169 INV {p \<noteq> Null \<and> (addr p,X) \<in> {(x,y). tl x = Ref y}\<^sup>*} |
170 DO p := p^.tl OD |
170 DO p := p^.tl OD |
171 {p = Ref X}" |
171 {p = Ref X}" |
172 apply vcg_simp |
172 apply vcg_simp |
173 apply clarsimp |
173 apply clarsimp |
174 apply(erule converse_rtranclE) |
174 apply(erule converse_rtranclE) |
239 (p \<noteq> Null \<or> q \<noteq> Null)} |
239 (p \<noteq> Null \<or> q \<noteq> Null)} |
240 IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
240 IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
241 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; |
241 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; |
242 s := r; |
242 s := r; |
243 WHILE p \<noteq> Null \<or> q \<noteq> Null |
243 WHILE p \<noteq> Null \<or> q \<noteq> Null |
244 INV {EX rs ps qs a. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and> |
244 INV {\<exists>rs ps qs a. Path tl r rs s \<and> List tl p ps \<and> List tl q qs \<and> |
245 distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> |
245 distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> |
246 merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = |
246 merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = |
247 rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> |
247 rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> |
248 (tl a = p \<or> tl a = q)} |
248 (tl a = p \<or> tl a = q)} |
249 DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
249 DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
365 |
365 |
366 lemma [simp]: "islist f p \<Longrightarrow> distinct (list f p)" |
366 lemma [simp]: "islist f p \<Longrightarrow> distinct (list f p)" |
367 by (rule unproven) |
367 by (rule unproven) |
368 |
368 |
369 lemma "VARS hd tl p q r s |
369 lemma "VARS hd tl p q r s |
370 {islist tl p & Ps = list tl p \<and> islist tl q & Qs = list tl q \<and> |
370 {islist tl p \<and> Ps = list tl p \<and> islist tl q \<and> Qs = list tl q \<and> |
371 set Ps \<inter> set Qs = {} \<and> |
371 set Ps \<inter> set Qs = {} \<and> |
372 (p \<noteq> Null \<or> q \<noteq> Null)} |
372 (p \<noteq> Null \<or> q \<noteq> Null)} |
373 IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
373 IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
374 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; |
374 THEN r := p; p := p^.tl ELSE r := q; q := q^.tl FI; |
375 s := r; |
375 s := r; |
376 WHILE p \<noteq> Null \<or> q \<noteq> Null |
376 WHILE p \<noteq> Null \<or> q \<noteq> Null |
377 INV {EX rs ps qs a. ispath tl r s & rs = path tl r s \<and> |
377 INV {\<exists>rs ps qs a. ispath tl r s \<and> rs = path tl r s \<and> |
378 islist tl p & ps = list tl p \<and> islist tl q & qs = list tl q \<and> |
378 islist tl p \<and> ps = list tl p \<and> islist tl q \<and> qs = list tl q \<and> |
379 distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> |
379 distinct(a # ps @ qs @ rs) \<and> s = Ref a \<and> |
380 merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = |
380 merge(Ps,Qs,\<lambda>x y. hd x \<le> hd y) = |
381 rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> |
381 rs @ a # merge(ps,qs,\<lambda>x y. hd x \<le> hd y) \<and> |
382 (tl a = p \<or> tl a = q)} |
382 (tl a = p \<or> tl a = q)} |
383 DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |
383 DO IF cor (q = Null) (cand (p \<noteq> Null) (p^.hd \<le> q^.hd)) |