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") |