src/HOL/Imperative_HOL/Ref.thy
changeset 61076 bdc1e2f0a86a
parent 58889 5b7a9633cfa8
child 62026 ea3b1b0413b4
equal deleted inserted replaced
61075:f6b0d827240e 61076:bdc1e2f0a86a
    14   and @{url "http://www.smlnj.org/doc/Conversion/top-level-comparison.html"}
    14   and @{url "http://www.smlnj.org/doc/Conversion/top-level-comparison.html"}
    15 *}
    15 *}
    16 
    16 
    17 subsection {* Primitives *}
    17 subsection {* Primitives *}
    18 
    18 
    19 definition present :: "heap \<Rightarrow> 'a\<Colon>heap ref \<Rightarrow> bool" where
    19 definition present :: "heap \<Rightarrow> 'a::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::heap ref \<Rightarrow> 'a" where
    23   "get h = from_nat \<circ> refs h TYPEREP('a) \<circ> addr_of_ref"
    23   "get h = from_nat \<circ> refs h TYPEREP('a) \<circ> addr_of_ref"
    24 
    24 
    25 definition set :: "'a\<Colon>heap ref \<Rightarrow> 'a \<Rightarrow> heap \<Rightarrow> heap" where
    25 definition set :: "'a::heap ref \<Rightarrow> 'a \<Rightarrow> heap \<Rightarrow> heap" where
    26   "set r x = refs_update
    26   "set r x = refs_update
    27     (\<lambda>h. h(TYPEREP('a) := ((h (TYPEREP('a))) (addr_of_ref r := to_nat x))))"
    27     (\<lambda>h. h(TYPEREP('a) := ((h (TYPEREP('a))) (addr_of_ref r := to_nat x))))"
    28 
    28 
    29 definition alloc :: "'a \<Rightarrow> heap \<Rightarrow> 'a\<Colon>heap ref \<times> heap" where
    29 definition alloc :: "'a \<Rightarrow> heap \<Rightarrow> 'a::heap ref \<times> heap" where
    30   "alloc x h = (let
    30   "alloc x h = (let
    31      l = lim h;
    31      l = lim h;
    32      r = Ref l
    32      r = Ref l
    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::heap ref \<Rightarrow> 'b::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 
    38 
    39 subsection {* Monad operations *}
    39 subsection {* Monad operations *}
    40 
    40 
    41 definition ref :: "'a\<Colon>heap \<Rightarrow> 'a ref Heap" where
    41 definition ref :: "'a::heap \<Rightarrow> 'a ref Heap" where
    42   [code del]: "ref v = Heap_Monad.heap (alloc v)"
    42   [code del]: "ref v = Heap_Monad.heap (alloc v)"
    43 
    43 
    44 definition lookup :: "'a\<Colon>heap ref \<Rightarrow> 'a Heap" ("!_" 61) where
    44 definition lookup :: "'a::heap ref \<Rightarrow> 'a Heap" ("!_" 61) where
    45   [code del]: "lookup r = Heap_Monad.tap (\<lambda>h. get h r)"
    45   [code del]: "lookup r = Heap_Monad.tap (\<lambda>h. get h r)"
    46 
    46 
    47 definition update :: "'a ref \<Rightarrow> 'a\<Colon>heap \<Rightarrow> unit Heap" ("_ := _" 62) where
    47 definition update :: "'a ref \<Rightarrow> 'a::heap \<Rightarrow> unit Heap" ("_ := _" 62) where
    48   [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))"
    49 
    49 
    50 definition change :: "('a\<Colon>heap \<Rightarrow> 'a) \<Rightarrow> 'a ref \<Rightarrow> 'a Heap" where
    50 definition change :: "('a::heap \<Rightarrow> 'a) \<Rightarrow> 'a ref \<Rightarrow> 'a Heap" where
    51   "change f r = do {
    51   "change f r = do {
    52      x \<leftarrow> ! r;
    52      x \<leftarrow> ! r;
    53      let y = f x;
    53      let y = f x;
    54      r := y;
    54      r := y;
    55      return y
    55      return y