src/HOL/Hoare/Pointers.thy
changeset 13133 03d20664cb79
child 13287 e4134f9eb4dc
equal deleted inserted replaced
13132:d7f33559f871 13133:03d20664cb79
       
     1 (*  Title:      HOL/Hoare/Pointers.thy
       
     2     ID:         $Id$
       
     3     Author:     Tobias Nipkow
       
     4     Copyright   2002 TUM
       
     5 
       
     6 How to use Hoare logic to verify pointer manipulating programs.
       
     7 The old idea: the store is a global mapping from pointers to values.
       
     8 Pointers are modelled by type 'a option, where None is Nil.
       
     9 Thus the heap is of type 'a \<leadsto> 'a (see theory Map).
       
    10 
       
    11 The List reversal example is taken from Richard Bornat's paper
       
    12 Proving pointer programs in Hoare logic
       
    13 What's new? We formalize the foundations, ie the abstraction from the pointer
       
    14 chains to HOL lists. This is merely axiomatized by Bornat.
       
    15 *)
       
    16 
       
    17 theory Pointers = Hoare:
       
    18 
       
    19 section"The heap"
       
    20 
       
    21 subsection"Paths in the heap"
       
    22 
       
    23 consts
       
    24  path :: "('a \<leadsto> 'a) \<Rightarrow> 'a option \<Rightarrow> 'a list \<Rightarrow> 'a option \<Rightarrow> bool"
       
    25 primrec
       
    26 "path h x [] y = (x = y)"
       
    27 "path h x (a#as) y = (x = Some a \<and> path h (h a) as y)"
       
    28 
       
    29 (* useful?
       
    30 lemma [simp]: "!x. reach h x (as @ [a]) (h a) = reach h x as (Some a)"
       
    31 apply(induct_tac as)
       
    32 apply(clarsimp)
       
    33 apply(clarsimp)
       
    34 done
       
    35 *)
       
    36 
       
    37 subsection "Lists on the heap"
       
    38 
       
    39 constdefs
       
    40  list :: "('a \<leadsto> 'a) \<Rightarrow> 'a option \<Rightarrow> 'a list \<Rightarrow> bool"
       
    41 "list h x as == path h x as None"
       
    42 
       
    43 lemma [simp]: "list h x [] = (x = None)"
       
    44 by(simp add:list_def)
       
    45 
       
    46 lemma [simp]: "list h x (a#as) = (x = Some a \<and> list h (h a) as)"
       
    47 by(simp add:list_def)
       
    48 
       
    49 lemma [simp]: "list h None as = (as = [])"
       
    50 by(case_tac as, simp_all)
       
    51 
       
    52 lemma [simp]: "list h (Some a) as = (\<exists>bs. as = a#bs \<and> list h (h a) bs)"
       
    53 by(case_tac as, simp_all, fast)
       
    54 
       
    55 
       
    56 declare fun_upd_apply[simp del]fun_upd_same[simp] fun_upd_other[simp]
       
    57 
       
    58 lemma list_unique: "\<And>x bs. list h x as \<Longrightarrow> list h x bs \<Longrightarrow> as = bs"
       
    59 by(induct as, simp, clarsimp)
       
    60 
       
    61 lemma list_app: "\<And>x. list h x (as@bs) = (\<exists>y. path h x as y \<and> list h y bs)"
       
    62 by(induct as, simp, clarsimp)
       
    63 
       
    64 lemma list_hd_not_in_tl: "list h (h a) as \<Longrightarrow> a \<notin> set as"
       
    65 apply (clarsimp simp add:in_set_conv_decomp)
       
    66 apply(frule list_app[THEN iffD1])
       
    67 apply(fastsimp dest:list_app[THEN iffD1] list_unique)
       
    68 done
       
    69 
       
    70 lemma list_distinct: "\<And>x. list h x as \<Longrightarrow> distinct as"
       
    71 apply(induct as, simp)
       
    72 apply(fastsimp dest:list_hd_not_in_tl)
       
    73 done
       
    74 
       
    75 theorem notin_list_update[rule_format,simp]:
       
    76  "\<forall>x. a \<notin> set as \<longrightarrow> list (h(a := y)) x as = list h x as"
       
    77 apply(induct_tac as)
       
    78 apply simp
       
    79 apply(simp add:fun_upd_apply)
       
    80 done
       
    81 
       
    82 lemma [simp]: "list h (h a) as \<Longrightarrow> list (h(a := y)) (h a) as"
       
    83 by(simp add:list_hd_not_in_tl)
       
    84 (* Note that the opposite direction does NOT hold:
       
    85    If    h = (a \<mapsto> Some a)
       
    86    then  list (h(a := None)) (h a) [a]
       
    87    but   not list h (h a) [] (because h is cyclic)
       
    88 *)
       
    89 
       
    90 section"Hoare logic"
       
    91 
       
    92 (* This should already be done in Hoare.thy, which should be converted to
       
    93 Isar *)
       
    94 
       
    95 method_setup vcg_simp_tac = {*
       
    96   Method.no_args
       
    97     (Method.SIMPLE_METHOD' HEADGOAL (hoare_tac Asm_full_simp_tac)) *}
       
    98   "verification condition generator plus simplification"
       
    99 
       
   100 subsection"List reversal"
       
   101 
       
   102 lemma "|- VARS tl p q r. 
       
   103   {list tl p As \<and> list tl q Bs \<and> set As \<inter> set Bs = {}}
       
   104   WHILE p ~= None
       
   105   INV {\<exists>As' Bs'. list tl p As' \<and> list tl q Bs' \<and> set As' \<inter> set Bs' = {} \<and>
       
   106                  rev As' @ Bs' = rev As @ Bs}
       
   107   DO r := p; p := tl(the p); tl := tl(the r := q); q := r OD
       
   108   {list tl q (rev As @ Bs)}"
       
   109 apply vcg_simp_tac
       
   110 
       
   111 apply(rule_tac x = As in exI)
       
   112 apply simp
       
   113 
       
   114 prefer 2
       
   115 apply clarsimp
       
   116 
       
   117 apply clarify
       
   118 apply(rename_tac As' b Bs')
       
   119 apply(frule list_distinct)
       
   120 apply clarsimp
       
   121 apply(rename_tac As'')
       
   122 apply(rule_tac x = As'' in exI)
       
   123 apply simp
       
   124 apply(rule_tac x = "b#Bs'" in exI)
       
   125 apply simp
       
   126 done
       
   127 
       
   128 end