97 done)" |
97 done)" |
98 |
98 |
99 hide (open) const new map -- {* avoid clashed with some popular names *} |
99 hide (open) const new map -- {* avoid clashed with some popular names *} |
100 |
100 |
101 |
101 |
102 subsection {* Converting arrays to lists *} |
|
103 |
|
104 primrec list_of_aux :: "nat \<Rightarrow> ('a\<Colon>heap) array \<Rightarrow> 'a list \<Rightarrow> 'a list Heap" where |
|
105 "list_of_aux 0 a xs = return xs" |
|
106 | "list_of_aux (Suc n) a xs = (do |
|
107 x \<leftarrow> Array.nth a n; |
|
108 list_of_aux n a (x#xs) |
|
109 done)" |
|
110 |
|
111 definition list_of :: "('a\<Colon>heap) array \<Rightarrow> 'a list Heap" where |
|
112 "list_of a = (do n \<leftarrow> Array.length a; |
|
113 list_of_aux n a [] |
|
114 done)" |
|
115 |
|
116 |
|
117 subsection {* Properties *} |
102 subsection {* Properties *} |
118 |
103 |
119 lemma array_make [code func]: |
104 lemma array_make [code func]: |
120 "Array.new n x = make n (\<lambda>_. x)" |
105 "Array.new n x = make n (\<lambda>_. x)" |
121 by (induct n) (simp_all add: make_def new_def Heap_Monad.heap_def |
106 by (induct n) (simp_all add: make_def new_def Heap_Monad.heap_def |
125 |
110 |
126 lemma array_of_list_make [code func]: |
111 lemma array_of_list_make [code func]: |
127 "of_list xs = make (List.length xs) (\<lambda>n. xs ! n)" |
112 "of_list xs = make (List.length xs) (\<lambda>n. xs ! n)" |
128 unfolding make_def map_nth .. |
113 unfolding make_def map_nth .. |
129 |
114 |
|
115 |
|
116 subsection {* Code generator setup *} |
|
117 |
|
118 subsubsection {* Logical intermediate layer *} |
|
119 |
|
120 definition new' where |
|
121 [code del]: "new' = Array.new o nat_of_index" |
|
122 hide (open) const new' |
|
123 lemma [code func]: |
|
124 "Array.new = Array.new' o index_of_nat" |
|
125 by (simp add: new'_def o_def) |
|
126 |
|
127 definition of_list' where |
|
128 [code del]: "of_list' i xs = Array.of_list (take (nat_of_index i) xs)" |
|
129 hide (open) const of_list' |
|
130 lemma [code func]: |
|
131 "Array.of_list xs = Array.of_list' (index_of_nat (List.length xs)) xs" |
|
132 by (simp add: of_list'_def) |
|
133 |
|
134 definition make' where |
|
135 [code del]: "make' i f = Array.make (nat_of_index i) (f o index_of_nat)" |
|
136 hide (open) const make' |
|
137 lemma [code func]: |
|
138 "Array.make n f = Array.make' (index_of_nat n) (f o nat_of_index)" |
|
139 by (simp add: make'_def o_def) |
|
140 |
|
141 definition length' where |
|
142 [code del]: "length' = Array.length \<guillemotright>== liftM index_of_nat" |
|
143 hide (open) const length' |
|
144 lemma [code func]: |
|
145 "Array.length = Array.length' \<guillemotright>== liftM nat_of_index" |
|
146 by (simp add: length'_def monad_simp', |
|
147 simp add: liftM_def comp_def monad_simp, |
|
148 simp add: monad_simp') |
|
149 |
|
150 definition nth' where |
|
151 [code del]: "nth' a = Array.nth a o nat_of_index" |
|
152 hide (open) const nth' |
|
153 lemma [code func]: |
|
154 "Array.nth a n = Array.nth' a (index_of_nat n)" |
|
155 by (simp add: nth'_def) |
|
156 |
|
157 definition upd' where |
|
158 [code del]: "upd' a i x = Array.upd (nat_of_index i) x a \<guillemotright> return ()" |
|
159 hide (open) const upd' |
|
160 lemma [code func]: |
|
161 "Array.upd i x a = Array.upd' a (index_of_nat i) x \<guillemotright> return a" |
|
162 by (simp add: upd'_def monad_simp upd_return) |
|
163 |
|
164 |
|
165 subsubsection {* SML *} |
|
166 |
|
167 code_type array (SML "_/ array") |
|
168 code_const Array (SML "raise/ (Fail/ \"bare Array\")") |
|
169 code_const Array.new' (SML "Array.array ((_), (_))") |
|
170 code_const Array.of_list (SML "Array.fromList") |
|
171 code_const Array.make' (SML "Array.tabulate ((_), (_))") |
|
172 code_const Array.length' (SML "Array.length") |
|
173 code_const Array.nth' (SML "Array.sub ((_), (_))") |
|
174 code_const Array.upd' (SML "Array.update ((_), (_), (_))") |
|
175 |
|
176 code_reserved SML Array |
|
177 |
|
178 |
|
179 subsubsection {* OCaml *} |
|
180 |
|
181 code_type array (OCaml "_/ array") |
|
182 code_const Array (OCaml "failwith/ \"bare Array\"") |
|
183 code_const Array.new' (OCaml "Array.make") |
|
184 code_const Array.of_list (OCaml "Array.of_list") |
|
185 code_const Array.make' (OCaml "Array.init") |
|
186 code_const Array.length' (OCaml "Array.length") |
|
187 code_const Array.nth' (OCaml "Array.get") |
|
188 code_const Array.upd' (OCaml "Array.set") |
|
189 |
|
190 code_reserved OCaml Array |
|
191 |
|
192 |
|
193 subsubsection {* Haskell *} |
|
194 |
|
195 code_type array (Haskell "STArray '_s _") |
|
196 code_const Array (Haskell "error/ \"bare Array\"") |
|
197 code_const Array.new' (Haskell "newArray/ (0,/ _)") |
|
198 code_const Array.of_list' (Haskell "newListArray/ (0,/ _)") |
|
199 code_const Array.length' (Haskell "length") |
|
200 code_const Array.nth' (Haskell "readArray") |
|
201 code_const Array.upd' (Haskell "writeArray") |
|
202 |
|
203 |
130 end |
204 end |