src/HOL/Imperative_HOL/Ref.thy
changeset 37753 3ac6867279f0
parent 37725 6d28a2aea936
child 37758 bf86a65403a8
equal deleted inserted replaced
37752:d0a384c84d69 37753:3ac6867279f0
    12   Imperative reference operations; modeled after their ML counterparts.
    12   Imperative reference operations; modeled after their ML counterparts.
    13   See http://caml.inria.fr/pub/docs/manual-caml-light/node14.15.html
    13   See http://caml.inria.fr/pub/docs/manual-caml-light/node14.15.html
    14   and http://www.smlnj.org/doc/Conversion/top-level-comparison.html
    14   and http://www.smlnj.org/doc/Conversion/top-level-comparison.html
    15 *}
    15 *}
    16 
    16 
    17 subsection {* Primitive layer *}
    17 subsection {* Primitives *}
    18 
    18 
    19 definition present :: "heap \<Rightarrow> 'a\<Colon>heap ref \<Rightarrow> bool" where
    19 definition present :: "heap \<Rightarrow> 'a\<Colon>heap ref \<Rightarrow> bool" where
    20   "present h r \<longleftrightarrow> addr_of_ref r < lim h"
    20   "present h r \<longleftrightarrow> addr_of_ref r < lim h"
    21 
    21 
    22 definition get :: "heap \<Rightarrow> 'a\<Colon>heap ref \<Rightarrow> 'a" where
    22 definition get :: "heap \<Rightarrow> 'a\<Colon>heap ref \<Rightarrow> 'a" where
    33    in (r, set r x (h\<lparr>lim := l + 1\<rparr>)))"
    33    in (r, set r x (h\<lparr>lim := l + 1\<rparr>)))"
    34 
    34 
    35 definition noteq :: "'a\<Colon>heap ref \<Rightarrow> 'b\<Colon>heap ref \<Rightarrow> bool" (infix "=!=" 70) where
    35 definition noteq :: "'a\<Colon>heap ref \<Rightarrow> 'b\<Colon>heap ref \<Rightarrow> bool" (infix "=!=" 70) where
    36   "r =!= s \<longleftrightarrow> TYPEREP('a) \<noteq> TYPEREP('b) \<or> addr_of_ref r \<noteq> addr_of_ref s"
    36   "r =!= s \<longleftrightarrow> TYPEREP('a) \<noteq> TYPEREP('b) \<or> addr_of_ref r \<noteq> addr_of_ref s"
    37 
    37 
    38 lemma noteq_sym: "r =!= s \<Longrightarrow> s =!= r"
    38 
    39   and unequal [simp]: "r \<noteq> r' \<longleftrightarrow> r =!= r'" -- "same types!"
    39 subsection {* Monad operations *}
    40   by (auto simp add: noteq_def)
       
    41 
       
    42 lemma noteq_irrefl: "r =!= r \<Longrightarrow> False"
       
    43   by (auto simp add: noteq_def)
       
    44 
       
    45 lemma present_alloc_neq: "present h r \<Longrightarrow> r =!= fst (alloc v h)"
       
    46   by (simp add: present_def alloc_def noteq_def Let_def)
       
    47 
       
    48 lemma next_fresh [simp]:
       
    49   assumes "(r, h') = alloc x h"
       
    50   shows "\<not> present h r"
       
    51   using assms by (cases h) (auto simp add: alloc_def present_def Let_def)
       
    52 
       
    53 lemma next_present [simp]:
       
    54   assumes "(r, h') = alloc x h"
       
    55   shows "present h' r"
       
    56   using assms by (cases h) (auto simp add: alloc_def set_def present_def Let_def)
       
    57 
       
    58 lemma get_set_eq [simp]:
       
    59   "get (set r x h) r = x"
       
    60   by (simp add: get_def set_def)
       
    61 
       
    62 lemma get_set_neq [simp]:
       
    63   "r =!= s \<Longrightarrow> get (set s x h) r = get h r"
       
    64   by (simp add: noteq_def get_def set_def)
       
    65 
       
    66 lemma set_same [simp]:
       
    67   "set r x (set r y h) = set r x h"
       
    68   by (simp add: set_def)
       
    69 
       
    70 lemma set_set_swap:
       
    71   "r =!= r' \<Longrightarrow> set r x (set r' x' h) = set r' x' (set r x h)"
       
    72   by (simp add: noteq_def set_def expand_fun_eq)
       
    73 
       
    74 lemma alloc_set:
       
    75   "fst (alloc x (set r x' h)) = fst (alloc x h)"
       
    76   by (simp add: alloc_def set_def Let_def)
       
    77 
       
    78 lemma get_alloc [simp]:
       
    79   "get (snd (alloc x h)) (fst (alloc x' h)) = x"
       
    80   by (simp add: alloc_def Let_def)
       
    81 
       
    82 lemma set_alloc [simp]:
       
    83   "set (fst (alloc v h)) v' (snd (alloc v h)) = snd (alloc v' h)"
       
    84   by (simp add: alloc_def Let_def)
       
    85 
       
    86 lemma get_alloc_neq: "r =!= fst (alloc v h) \<Longrightarrow> 
       
    87   get (snd (alloc v h)) r  = get h r"
       
    88   by (simp add: get_def set_def alloc_def Let_def noteq_def)
       
    89 
       
    90 lemma lim_set [simp]:
       
    91   "lim (set r v h) = lim h"
       
    92   by (simp add: set_def)
       
    93 
       
    94 lemma present_alloc [simp]: 
       
    95   "present h r \<Longrightarrow> present (snd (alloc v h)) r"
       
    96   by (simp add: present_def alloc_def Let_def)
       
    97 
       
    98 lemma present_set [simp]:
       
    99   "present (set r v h) = present h"
       
   100   by (simp add: present_def expand_fun_eq)
       
   101 
       
   102 lemma noteq_I:
       
   103   "present h r \<Longrightarrow> \<not> present h r' \<Longrightarrow> r =!= r'"
       
   104   by (auto simp add: noteq_def present_def)
       
   105 
       
   106 
       
   107 subsection {* Primitives *}
       
   108 
    40 
   109 definition ref :: "'a\<Colon>heap \<Rightarrow> 'a ref Heap" where
    41 definition ref :: "'a\<Colon>heap \<Rightarrow> 'a ref Heap" where
   110   [code del]: "ref v = Heap_Monad.heap (alloc v)"
    42   [code del]: "ref v = Heap_Monad.heap (alloc v)"
   111 
    43 
   112 definition lookup :: "'a\<Colon>heap ref \<Rightarrow> 'a Heap" ("!_" 61) where
    44 definition lookup :: "'a\<Colon>heap ref \<Rightarrow> 'a Heap" ("!_" 61) where
   113   [code del]: "lookup r = Heap_Monad.heap (\<lambda>h. (get h r, h))"
    45   [code del]: "lookup r = Heap_Monad.heap (\<lambda>h. (get h r, h))"
   114 
    46 
   115 definition update :: "'a ref \<Rightarrow> 'a\<Colon>heap \<Rightarrow> unit Heap" ("_ := _" 62) where
    47 definition update :: "'a ref \<Rightarrow> 'a\<Colon>heap \<Rightarrow> unit Heap" ("_ := _" 62) where
   116   [code del]: "update r v = Heap_Monad.heap (\<lambda>h. ((), set r v h))"
    48   [code del]: "update r v = Heap_Monad.heap (\<lambda>h. ((), set r v h))"
   117 
       
   118 
       
   119 subsection {* Derivates *}
       
   120 
    49 
   121 definition change :: "('a\<Colon>heap \<Rightarrow> 'a) \<Rightarrow> 'a ref \<Rightarrow> 'a Heap" where
    50 definition change :: "('a\<Colon>heap \<Rightarrow> 'a) \<Rightarrow> 'a ref \<Rightarrow> 'a Heap" where
   122   "change f r = (do
    51   "change f r = (do
   123      x \<leftarrow> ! r;
    52      x \<leftarrow> ! r;
   124      let y = f x;
    53      let y = f x;
   127    done)"
    56    done)"
   128 
    57 
   129 
    58 
   130 subsection {* Properties *}
    59 subsection {* Properties *}
   131 
    60 
       
    61 lemma noteq_sym: "r =!= s \<Longrightarrow> s =!= r"
       
    62   and unequal [simp]: "r \<noteq> r' \<longleftrightarrow> r =!= r'" -- "same types!"
       
    63   by (auto simp add: noteq_def)
       
    64 
       
    65 lemma noteq_irrefl: "r =!= r \<Longrightarrow> False"
       
    66   by (auto simp add: noteq_def)
       
    67 
       
    68 lemma present_alloc_neq: "present h r \<Longrightarrow> r =!= fst (alloc v h)"
       
    69   by (simp add: present_def alloc_def noteq_def Let_def)
       
    70 
       
    71 lemma next_fresh [simp]:
       
    72   assumes "(r, h') = alloc x h"
       
    73   shows "\<not> present h r"
       
    74   using assms by (cases h) (auto simp add: alloc_def present_def Let_def)
       
    75 
       
    76 lemma next_present [simp]:
       
    77   assumes "(r, h') = alloc x h"
       
    78   shows "present h' r"
       
    79   using assms by (cases h) (auto simp add: alloc_def set_def present_def Let_def)
       
    80 
       
    81 lemma get_set_eq [simp]:
       
    82   "get (set r x h) r = x"
       
    83   by (simp add: get_def set_def)
       
    84 
       
    85 lemma get_set_neq [simp]:
       
    86   "r =!= s \<Longrightarrow> get (set s x h) r = get h r"
       
    87   by (simp add: noteq_def get_def set_def)
       
    88 
       
    89 lemma set_same [simp]:
       
    90   "set r x (set r y h) = set r x h"
       
    91   by (simp add: set_def)
       
    92 
       
    93 lemma set_set_swap:
       
    94   "r =!= r' \<Longrightarrow> set r x (set r' x' h) = set r' x' (set r x h)"
       
    95   by (simp add: noteq_def set_def expand_fun_eq)
       
    96 
       
    97 lemma alloc_set:
       
    98   "fst (alloc x (set r x' h)) = fst (alloc x h)"
       
    99   by (simp add: alloc_def set_def Let_def)
       
   100 
       
   101 lemma get_alloc [simp]:
       
   102   "get (snd (alloc x h)) (fst (alloc x' h)) = x"
       
   103   by (simp add: alloc_def Let_def)
       
   104 
       
   105 lemma set_alloc [simp]:
       
   106   "set (fst (alloc v h)) v' (snd (alloc v h)) = snd (alloc v' h)"
       
   107   by (simp add: alloc_def Let_def)
       
   108 
       
   109 lemma get_alloc_neq: "r =!= fst (alloc v h) \<Longrightarrow> 
       
   110   get (snd (alloc v h)) r  = get h r"
       
   111   by (simp add: get_def set_def alloc_def Let_def noteq_def)
       
   112 
       
   113 lemma lim_set [simp]:
       
   114   "lim (set r v h) = lim h"
       
   115   by (simp add: set_def)
       
   116 
       
   117 lemma present_alloc [simp]: 
       
   118   "present h r \<Longrightarrow> present (snd (alloc v h)) r"
       
   119   by (simp add: present_def alloc_def Let_def)
       
   120 
       
   121 lemma present_set [simp]:
       
   122   "present (set r v h) = present h"
       
   123   by (simp add: present_def expand_fun_eq)
       
   124 
       
   125 lemma noteq_I:
       
   126   "present h r \<Longrightarrow> \<not> present h r' \<Longrightarrow> r =!= r'"
       
   127   by (auto simp add: noteq_def present_def)
       
   128 
       
   129 lemma execute_ref [simp]:
       
   130   "Heap_Monad.execute (ref v) h = Some (alloc v h)"
       
   131   by (simp add: ref_def)
       
   132 
       
   133 lemma execute_lookup [simp]:
       
   134   "Heap_Monad.execute (lookup r) h = Some (get h r, h)"
       
   135   by (simp add: lookup_def)
       
   136 
       
   137 lemma execute_update [simp]:
       
   138   "Heap_Monad.execute (update r v) h = Some ((), set r v h)"
       
   139   by (simp add: update_def)
       
   140 
       
   141 lemma execute_change [simp]:
       
   142   "Heap_Monad.execute (change f r) h = Some (f (get h r), set r (f (get h r)) h)"
       
   143   by (cases "!r" h rule: heap_cases)
       
   144     (simp_all only: change_def execute_bind, auto simp add: Let_def)
       
   145 
   132 lemma lookup_chain:
   146 lemma lookup_chain:
   133   "(!r \<guillemotright> f) = f"
   147   "(!r \<guillemotright> f) = f"
   134   by (rule Heap_eqI) (simp add: lookup_def)
   148   by (rule Heap_eqI) (simp add: lookup_def)
   135 
   149 
   136 lemma update_change [code]:
   150 lemma update_change [code]:
   187 hide_const (open) present get set alloc lookup update change
   201 hide_const (open) present get set alloc lookup update change
   188 
   202 
   189 
   203 
   190 subsection {* Code generator setup *}
   204 subsection {* Code generator setup *}
   191 
   205 
   192 subsubsection {* SML *}
   206 text {* SML *}
   193 
   207 
   194 code_type ref (SML "_/ Unsynchronized.ref")
   208 code_type ref (SML "_/ Unsynchronized.ref")
   195 code_const Ref (SML "raise/ (Fail/ \"bare Ref\")")
   209 code_const Ref (SML "raise/ (Fail/ \"bare Ref\")")
   196 code_const ref (SML "(fn/ ()/ =>/ Unsynchronized.ref/ _)")
   210 code_const ref (SML "(fn/ ()/ =>/ Unsynchronized.ref/ _)")
   197 code_const Ref.lookup (SML "(fn/ ()/ =>/ !/ _)")
   211 code_const Ref.lookup (SML "(fn/ ()/ =>/ !/ _)")
   198 code_const Ref.update (SML "(fn/ ()/ =>/ _/ :=/ _)")
   212 code_const Ref.update (SML "(fn/ ()/ =>/ _/ :=/ _)")
   199 
   213 
   200 code_reserved SML ref
   214 code_reserved SML ref
   201 
   215 
   202 
   216 
   203 subsubsection {* OCaml *}
   217 text {* OCaml *}
   204 
   218 
   205 code_type ref (OCaml "_/ ref")
   219 code_type ref (OCaml "_/ ref")
   206 code_const Ref (OCaml "failwith/ \"bare Ref\")")
   220 code_const Ref (OCaml "failwith/ \"bare Ref\")")
   207 code_const ref (OCaml "(fn/ ()/ =>/ ref/ _)")
   221 code_const ref (OCaml "(fn/ ()/ =>/ ref/ _)")
   208 code_const Ref.lookup (OCaml "(fn/ ()/ =>/ !/ _)")
   222 code_const Ref.lookup (OCaml "(fn/ ()/ =>/ !/ _)")
   209 code_const Ref.update (OCaml "(fn/ ()/ =>/ _/ :=/ _)")
   223 code_const Ref.update (OCaml "(fn/ ()/ =>/ _/ :=/ _)")
   210 
   224 
   211 code_reserved OCaml ref
   225 code_reserved OCaml ref
   212 
   226 
   213 
   227 
   214 subsubsection {* Haskell *}
   228 text {* Haskell *}
   215 
   229 
   216 code_type ref (Haskell "Heap.STRef/ Heap.RealWorld/ _")
   230 code_type ref (Haskell "Heap.STRef/ Heap.RealWorld/ _")
   217 code_const Ref (Haskell "error/ \"bare Ref\"")
   231 code_const Ref (Haskell "error/ \"bare Ref\"")
   218 code_const ref (Haskell "Heap.newSTRef")
   232 code_const ref (Haskell "Heap.newSTRef")
   219 code_const Ref.lookup (Haskell "Heap.readSTRef")
   233 code_const Ref.lookup (Haskell "Heap.readSTRef")