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 |