changeset 12655 | b8c130dc46be |
parent 12634 | 3baa6143a9c4 |
child 12657 | c8385f8f7816 |
12654:200565ba1471 | 12655:b8c130dc46be |
---|---|
31 |
31 |
32 subsection {* Record Basics *} |
32 subsection {* Record Basics *} |
33 |
33 |
34 text {* |
34 text {* |
35 Record types are not primitive in Isabelle and have a delicate |
35 Record types are not primitive in Isabelle and have a delicate |
36 internal representation based on nested copies of the primitive |
36 internal representation \cite{NaraschewskiW-TPHOLs98}, based on |
37 product type. A \commdx{record} declaration introduces a new record |
37 nested copies of the primitive product type. A \commdx{record} |
38 type scheme by specifying its fields, which are packaged internally |
38 declaration introduces a new record type scheme by specifying its |
39 to hold up the perception of the record as a distinguished entity. |
39 fields, which are packaged internally to hold up the perception of |
40 the record as a distinguished entity. Here is a simply example. |
|
40 *} |
41 *} |
41 |
42 |
42 record point = |
43 record point = |
43 Xcoord :: int |
44 Xcoord :: int |
44 Ycoord :: int |
45 Ycoord :: int |
54 "pt1 \<equiv> (| Xcoord = 999, Ycoord = 23 |)" |
55 "pt1 \<equiv> (| Xcoord = 999, Ycoord = 23 |)" |
55 |
56 |
56 text {* |
57 text {* |
57 We see above the ASCII notation for record brackets. You can also |
58 We see above the ASCII notation for record brackets. You can also |
58 use the symbolic brackets @{text \<lparr>} and @{text \<rparr>}. Record type |
59 use the symbolic brackets @{text \<lparr>} and @{text \<rparr>}. Record type |
59 expressions can be written directly as well, without referring to |
60 expressions can be also written directly with individual fields. |
60 previously declared names (which happen to be mere type |
61 The type name above is merely an abbreviations. |
61 abbreviations): |
|
62 *} |
62 *} |
63 |
63 |
64 constdefs |
64 constdefs |
65 pt2 :: "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>" |
65 pt2 :: "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>" |
66 "pt2 \<equiv> \<lparr>Xcoord = -45, Ycoord = 97\<rparr>" |
66 "pt2 \<equiv> \<lparr>Xcoord = -45, Ycoord = 97\<rparr>" |
78 |
78 |
79 text {* |
79 text {* |
80 The \emph{update}\index{update!record} operation is functional. For |
80 The \emph{update}\index{update!record} operation is functional. For |
81 example, @{term "p\<lparr>Xcoord := 0\<rparr>"} is a record whose @{text Xcoord} |
81 example, @{term "p\<lparr>Xcoord := 0\<rparr>"} is a record whose @{text Xcoord} |
82 value is zero and whose @{text Ycoord} value is copied from~@{text |
82 value is zero and whose @{text Ycoord} value is copied from~@{text |
83 p}. Updates are also simplified automatically: |
83 p}. Updates of explicit records are also simplified automatically: |
84 *} |
84 *} |
85 |
85 |
86 lemma "\<lparr>Xcoord = a, Ycoord = b\<rparr>\<lparr>Xcoord := 0\<rparr> = |
86 lemma "\<lparr>Xcoord = a, Ycoord = b\<rparr>\<lparr>Xcoord := 0\<rparr> = |
87 \<lparr>Xcoord = 0, Ycoord = b\<rparr>" |
87 \<lparr>Xcoord = 0, Ycoord = b\<rparr>" |
88 by simp |
88 by simp |
110 record cpoint = point + |
110 record cpoint = point + |
111 col :: colour |
111 col :: colour |
112 |
112 |
113 text {* |
113 text {* |
114 The fields of this new type are @{text Xcoord}, @{text Ycoord} and |
114 The fields of this new type are @{text Xcoord}, @{text Ycoord} and |
115 @{text col}, in that order: |
115 @{text col}, in that order. |
116 *} |
116 *} |
117 |
117 |
118 constdefs |
118 constdefs |
119 cpt1 :: cpoint |
119 cpt1 :: cpoint |
120 "cpt1 \<equiv> \<lparr>Xcoord = 999, Ycoord = 23, col = Green\<rparr>" |
120 "cpt1 \<equiv> \<lparr>Xcoord = 999, Ycoord = 23, col = Green\<rparr>" |
121 |
121 |
122 text {* |
122 text {* |
123 We can define generic operations that work on arbitrary instances of |
123 We can define generic operations that work on arbitrary instances of |
124 a record scheme, e.g.\ covering @{typ point}, @{typ cpoint} and any |
124 a record scheme, e.g.\ covering @{typ point}, @{typ cpoint}, and any |
125 further extensions. Every record structure has an implicit |
125 further extensions. Every record structure has an implicit |
126 pseudo-field, \cdx{more}, that keeps the extension as an explicit |
126 pseudo-field, \cdx{more}, that keeps the extension as an explicit |
127 value. Its type is declared as completely polymorphic:~@{typ 'a}. |
127 value. Its type is declared as completely polymorphic:~@{typ 'a}. |
128 When a fixed record value is expressed using just its standard |
128 When a fixed record value is expressed using just its standard |
129 fields, the value of @{text more} is implicitly set to @{text "()"}, |
129 fields, the value of @{text more} is implicitly set to @{text "()"}, |
130 the empty tuple, which has type @{typ unit}. Within the record |
130 the empty tuple, which has type @{typ unit}. Within the record |
131 brackets, you can refer to the @{text more} field by writing @{text |
131 brackets, you can refer to the @{text more} field by writing |
132 "\<dots>"} (three dots): |
132 ``@{text "\<dots>"}'' (three dots): |
133 *} |
133 *} |
134 |
134 |
135 lemma "Xcoord \<lparr>Xcoord = a, Ycoord = b, \<dots> = p\<rparr> = a" |
135 lemma "Xcoord \<lparr>Xcoord = a, Ycoord = b, \<dots> = p\<rparr> = a" |
136 by simp |
136 by simp |
137 |
137 |
138 text {* |
138 text {* |
139 This lemma applies to any record whose first two fields are @{text |
139 This lemma applies to any record whose first two fields are @{text |
140 Xcoord} and~@{text Ycoord}. Note that @{text "\<lparr>Xcoord = a, Ycoord = |
140 Xcoord} and~@{text Ycoord}. Note that @{text "\<lparr>Xcoord = a, Ycoord |
141 b, \<dots> = ()\<rparr>"} is really the same as @{text "\<lparr>Xcoord = a, Ycoord = |
141 = b, \<dots> = ()\<rparr>"} is exactly the same as @{text "\<lparr>Xcoord = a, Ycoord |
142 b\<rparr>"}. Selectors and updates are always polymorphic wrt.\ the @{text |
142 = b\<rparr>"}. Selectors and updates are always polymorphic wrt.\ the |
143 more} part of a record scheme, its value is just ignored (for |
143 @{text more} part of a record scheme, its value is just ignored (for |
144 select) or copied (for update). |
144 select) or copied (for update). |
145 |
145 |
146 The @{text more} pseudo-field may be manipulated directly as well, |
146 The @{text more} pseudo-field may be manipulated directly as well, |
147 but the identifier needs to be qualified: |
147 but the identifier needs to be qualified: |
148 *} |
148 *} |
149 |
149 |
150 lemma "point.more cpt1 = \<lparr>col = Green\<rparr>" |
150 lemma "point.more cpt1 = \<lparr>col = Green\<rparr>" |
151 by (simp add: cpt1_def) |
151 by (simp add: cpt1_def) |
152 |
152 |
153 text {* |
153 text {* |
154 We see that the colour attached to this @{typ point} is a |
154 We see that the colour part attached to this @{typ point} is a |
155 (rudimentary) record in its own right, namely @{text "\<lparr>col = |
155 (rudimentary) record in its own right, namely @{text "\<lparr>col = |
156 Green\<rparr>"}. In order to select or update @{text col}, this fragment |
156 Green\<rparr>"}. In order to select or update @{text col}, this fragment |
157 needs to be put back into the context of the parent type scheme, say |
157 needs to be put back into the context of the parent type scheme, say |
158 as @{text more} part of another @{typ point}. |
158 as @{text more} part of another @{typ point}. |
159 |
159 |
160 To define generic operations, we need to know a bit more about |
160 To define generic operations, we need to know a bit more about |
161 records. Our definition of @{typ point} above generated two type |
161 records. Our definition of @{typ point} above has generated two |
162 abbreviations: |
162 type abbreviations: |
163 |
163 |
164 \medskip |
164 \medskip |
165 \begin{tabular}{l} |
165 \begin{tabular}{l} |
166 @{typ point}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>"} \\ |
166 @{typ point}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>"} \\ |
167 @{typ "'a point_scheme"}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int, \<dots> :: 'a\<rparr>"} \\ |
167 @{typ "'a point_scheme"}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int, \<dots> :: 'a\<rparr>"} \\ |
193 @{typ point} (including @{typ cpoint} etc.): |
193 @{typ point} (including @{typ cpoint} etc.): |
194 *} |
194 *} |
195 |
195 |
196 constdefs |
196 constdefs |
197 incX :: "'a point_scheme \<Rightarrow> 'a point_scheme" |
197 incX :: "'a point_scheme \<Rightarrow> 'a point_scheme" |
198 "incX r \<equiv> \<lparr>Xcoord = Xcoord r + 1, |
198 "incX r \<equiv> |
199 Ycoord = Ycoord r, \<dots> = point.more r\<rparr>" |
199 \<lparr>Xcoord = Xcoord r + 1, Ycoord = Ycoord r, \<dots> = point.more r\<rparr>" |
200 |
200 |
201 text {* |
201 text {* |
202 Generic theorems can be proved about generic methods. This trivial |
202 Generic theorems can be proved about generic methods. This trivial |
203 lemma relates @{text incX} to @{text getX} and @{text setX}: |
203 lemma relates @{text incX} to @{text getX} and @{text setX}: |
204 *} |
204 *} |
220 |
220 |
221 subsection {* Record Equality *} |
221 subsection {* Record Equality *} |
222 |
222 |
223 text {* |
223 text {* |
224 Two records are equal\index{equality!of records} if all pairs of |
224 Two records are equal\index{equality!of records} if all pairs of |
225 corresponding fields are equal. Record equalities are simplified |
225 corresponding fields are equal. Concrete record equalities are |
226 automatically: |
226 simplified automatically: |
227 *} |
227 *} |
228 |
228 |
229 lemma "(\<lparr>Xcoord = a, Ycoord = b\<rparr> = \<lparr>Xcoord = a', Ycoord = b'\<rparr>) = |
229 lemma "(\<lparr>Xcoord = a, Ycoord = b\<rparr> = \<lparr>Xcoord = a', Ycoord = b'\<rparr>) = |
230 (a = a' \<and> b = b')" |
230 (a = a' \<and> b = b')" |
231 by simp |
231 by simp |
309 |
309 |
310 text {* |
310 text {* |
311 The generic cases method does not admit references to locally bound |
311 The generic cases method does not admit references to locally bound |
312 parameters of a goal. In longer proof scripts one might have to |
312 parameters of a goal. In longer proof scripts one might have to |
313 fall back on the primitive @{text rule_tac} used together with the |
313 fall back on the primitive @{text rule_tac} used together with the |
314 internal representation rules of records. E.g.\ the above use of |
314 internal field representation rules of records. E.g.\ the above use |
315 @{text "(cases r)"} would become @{text "(rule_tac r = r in |
315 of @{text "(cases r)"} would become @{text "(rule_tac r = r in |
316 point.cases_scheme)"}. |
316 point.cases_scheme)"}. |
317 *} |
317 *} |
318 |
318 |
319 |
319 |
320 subsection {* Extending and Truncating Records *} |
320 subsection {* Extending and Truncating Records *} |