src/HOL/Hoare/Pointers.thy
changeset 13771 6cd59cc885a1
parent 13762 9dd78dab72bc
child 13772 73d041cc6a66
equal deleted inserted replaced
13770:8060978feaf4 13771:6cd59cc885a1
   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)