168 |
168 |
169 |
169 |
170 subsection {* Datatype refinement involving invariants *} |
170 subsection {* Datatype refinement involving invariants *} |
171 |
171 |
172 text {* |
172 text {* |
173 FIXME |
173 Datatype representation involving invariants require a dedicated |
|
174 setup for the type and its primitive operations. As a running |
|
175 example, we implement a type @{text "'a dlist"} of list consisting |
|
176 of distinct elements. |
|
177 |
|
178 The first step is to decide on which representation the abstract |
|
179 type (in our example @{text "'a dlist"}) should be implemented. |
|
180 Here we choose @{text "'a list"}. Then a conversion from the concrete |
|
181 type to the abstract type must be specified, here: |
|
182 *} |
|
183 |
|
184 text %quote {* |
|
185 @{term_type Dlist} |
|
186 *} |
|
187 |
|
188 text {* |
|
189 \noindent Next follows the specification of a suitable \emph{projection}, |
|
190 i.e.~a conversion from abstract to concrete type: |
|
191 *} |
|
192 |
|
193 text %quote {* |
|
194 @{term_type list_of_dlist} |
|
195 *} |
|
196 |
|
197 text {* |
|
198 \noindent This projection must be specified such that the following |
|
199 \emph{abstract datatype certificate} can be proven: |
|
200 *} |
|
201 |
|
202 lemma %quote [code abstype]: |
|
203 "Dlist (list_of_dlist dxs) = dxs" |
|
204 by (fact Dlist_list_of_dlist) |
|
205 |
|
206 text {* |
|
207 \noindent Note that so far the invariant on representations |
|
208 (@{term_type distinct}) has never been mentioned explicitly: |
|
209 the invariant is only referred to implicitly: all values in |
|
210 set @{term "{xs. list_of_dlist (Dlist xs) = xs}"} are invariant, |
|
211 and in our example this is exactly @{term "{xs. distinct xs}"}. |
|
212 |
|
213 The primitive operations on @{typ "'a dlist"} are specified |
|
214 indirectly using the projection @{const list_of_dlist}. For |
|
215 the empty @{text "dlist"}, @{const Dlist.empty}, we finally want |
|
216 the code equation |
|
217 *} |
|
218 |
|
219 text %quote {* |
|
220 @{term "Dlist.empty = Dlist []"} |
|
221 *} |
|
222 |
|
223 text {* |
|
224 \noindent This we have to prove indirectly as follows: |
|
225 *} |
|
226 |
|
227 lemma %quote [code abstract]: |
|
228 "list_of_dlist Dlist.empty = []" |
|
229 by (fact list_of_dlist_empty) |
|
230 |
|
231 text {* |
|
232 \noindent This equation logically encodes both the desired code |
|
233 equation and that the expression @{const Dlist} is applied to obeys |
|
234 the implicit invariant. Equations for insertion and removal are |
|
235 similar: |
|
236 *} |
|
237 |
|
238 lemma %quote [code abstract]: |
|
239 "list_of_dlist (Dlist.insert x dxs) = List.insert x (list_of_dlist dxs)" |
|
240 by (fact list_of_dlist_insert) |
|
241 |
|
242 lemma %quote [code abstract]: |
|
243 "list_of_dlist (Dlist.remove x dxs) = remove1 x (list_of_dlist dxs)" |
|
244 by (fact list_of_dlist_remove) |
|
245 |
|
246 text {* |
|
247 \noindent Then the corresponding code is as follows: |
|
248 *} |
|
249 |
|
250 text %quote {* |
|
251 @{code_stmts Dlist.empty Dlist.insert Dlist.remove list_of_dlist (Haskell)} |
|
252 *} (*(types) dlist (consts) dempty dinsert dremove list_of List.member insert remove *) |
|
253 |
|
254 text {* |
|
255 Typical data structures implemented by representations involving |
|
256 invariants are available in the library, e.g.~theories @{theory |
|
257 Fset} and @{theory Mapping} specify sets (type @{typ "'a fset"}) and |
|
258 key-value-mappings (type @{typ "('a, 'b) mapping"}) respectively; |
|
259 these can be implemented by distinct lists as presented here as |
|
260 example (theory @{theory Dlist}) and red-black-trees respectively |
|
261 (theory @{theory RBT}). |
174 *} |
262 *} |
175 |
263 |
176 end |
264 end |