1 \section{Records} |
1 \section{Records} |
2 \label{sec:records} |
2 \label{sec:records} |
3 |
3 |
|
4 \index{records|(}% |
4 Records are familiar from programming languages. A record of $n$ |
5 Records are familiar from programming languages. A record of $n$ |
5 fields is essentially an $n$-tuple, but the record's components have |
6 fields is essentially an $n$-tuple, but the record's components have |
6 names, which can make expressions easier to read and reduces the risk |
7 names, which can make expressions easier to read and reduces the risk |
7 of confusing one field for another. |
8 of confusing one field for another. |
8 |
9 |
12 order of the fields is significant --- as it is in Pascal but not in |
13 order of the fields is significant --- as it is in Pascal but not in |
13 Standard ML. If two different record types have fields in common, |
14 Standard ML. If two different record types have fields in common, |
14 then the ambiguity is resolved in the usual way, by qualified names. |
15 then the ambiguity is resolved in the usual way, by qualified names. |
15 |
16 |
16 Record types can also be defined by extending other record types. |
17 Record types can also be defined by extending other record types. |
17 The effect resembles inheritance in object-oriented programming. |
18 Extensible records make use of the reserved field \cdx{more}, which is |
18 Extensible records make use of the reserved field \isa{more}, which is |
|
19 present in every record type. Generic methods, or operations that |
19 present in every record type. Generic methods, or operations that |
20 work on all possible extensions of a given record, can be expressed by |
20 work on all possible extensions of a given record, can be expressed by |
21 definitions involving \isa{more}, but the details are complicated. |
21 definitions involving \isa{more}, but the details are complicated. |
22 |
22 |
23 \subsection{Record Basics} |
23 \subsection{Record Basics} |
24 |
24 |
25 Record types are not primitive in Isabelle and have a complex internal |
25 Record types are not primitive in Isabelle and have a complex internal |
26 representation. A \isacommand{record} declaration |
26 representation. A \commdx{record} declaration |
27 introduces a new record type: |
27 introduces a new record type: |
28 \begin{isabelle} |
28 \begin{isabelle} |
29 \isacommand{record}\ point\ =\isanewline |
29 \isacommand{record}\ point\ =\isanewline |
30 \ \ Xcoord\ ::\ int\isanewline |
30 \ \ Xcoord\ ::\ int\isanewline |
31 \ \ Ycoord\ ::\ int |
31 \ \ Ycoord\ ::\ int |
69 \end{isabelle} |
69 \end{isabelle} |
70 |
70 |
71 \begin{warn} |
71 \begin{warn} |
72 Field names are declared as constants and can no longer be |
72 Field names are declared as constants and can no longer be |
73 used as variables. It would be unwise, for example, to call the fields |
73 used as variables. It would be unwise, for example, to call the fields |
74 of type \isa{point} simply \isa{x} and~\isa{y}. |
74 of type \isa{point} simply \isa{x} and~\isa{y}. Each record |
|
75 declaration introduces a constant \cdx{more}. |
75 \end{warn} |
76 \end{warn} |
76 |
77 |
77 |
78 |
78 \subsection{Extensible Records and Generic Operations} |
79 \subsection{Extensible Records and Generic Operations} |
79 |
80 |
|
81 \index{records!extensible|(}% |
80 Now, let us define coloured points |
82 Now, let us define coloured points |
81 (type \isa{cpoint}) to be points extended with a field \isa{col} of type |
83 (type \isa{cpoint}) to be points extended with a field \isa{col} of type |
82 \isa{colour}: |
84 \isa{colour}: |
83 \begin{isabelle} |
85 \begin{isabelle} |
84 \isacommand{datatype}\ colour\ =\ Red\ |\ Green\ |\ |
86 \isacommand{datatype}\ colour\ =\ Red\ |\ Green\ |\ |
102 its colour, we must define operations that copy across the other |
104 its colour, we must define operations that copy across the other |
103 fields. However, we can define generic operations |
105 fields. However, we can define generic operations |
104 that work on type |
106 that work on type |
105 \isa{point} and all extensions of it. |
107 \isa{point} and all extensions of it. |
106 |
108 |
107 Every record structure has an implicit field, \isa{more}, to allow |
109 Every record structure has an implicit field, \cdx{more}, to allow |
108 extension. Its type is completely polymorphic:~\isa{'a}. When a |
110 extension. Its type is completely polymorphic:~\isa{'a}. When a |
109 record value is expressed using just its standard fields, the value of |
111 record value is expressed using just its standard fields, the value of |
110 \isa{more} is implicitly set to \isa{()}, the empty tuple, which has |
112 \isa{more} is implicitly set to \isa{()}, the empty tuple, which has |
111 type \isa{unit}. Within the record brackets, you can refer to the |
113 type \isa{unit}. Within the record brackets, you can refer to the |
112 \isa{more} field by writing \isa{...}: |
114 \isa{more} field by writing \isa{...} (three periods): |
113 \begin{isabelle} |
115 \begin{isabelle} |
114 \isacommand{lemma}\ "Xcoord\ (|\ Xcoord\ =\ a,\ Ycoord\ =\ b,\ ...\ =\ p\ |)\ =\ a" |
116 \isacommand{lemma}\ "Xcoord\ (|\ Xcoord\ =\ a,\ Ycoord\ =\ b,\ ...\ =\ p\ |)\ =\ a" |
115 \end{isabelle} |
117 \end{isabelle} |
116 This lemma (trivially proved using \isa{simp}) applies to any |
118 This lemma (trivially proved using \isa{simp}) applies to any |
117 record whose first two fields are \isa{Xcoord} and~\isa{Ycoord}. Field |
119 record whose first two fields are \isa{Xcoord} and~\isa{Ycoord}. Field |
135 \end{isabelle} |
137 \end{isabelle} |
136 % |
138 % |
137 Type \isa{point} is for rigid records having the two fields |
139 Type \isa{point} is for rigid records having the two fields |
138 \isa{Xcoord} and~\isa{Ycoord}, while the polymorphic type \isa{'a\ point_scheme} |
140 \isa{Xcoord} and~\isa{Ycoord}, while the polymorphic type \isa{'a\ point_scheme} |
139 comprises all possible extensions to those two fields. For example, |
141 comprises all possible extensions to those two fields. For example, |
140 let us define two operations (``methods'') to get and set any point's \isa{Xcoord} |
142 let us define two operations --- methods, if we regard records as |
141 field. The sort constraint in \isa{'a::more} is required, since |
143 objects --- to get and set any point's |
142 all extensions must belong to the type class \isa{more}.% |
144 \isa{Xcoord} field. The sort constraint in \isa{'a::more} is |
|
145 required, since all extensions must belong to the type class |
|
146 \isa{more}.% |
143 \REMARK{Why, and what does this imply in practice?} |
147 \REMARK{Why, and what does this imply in practice?} |
144 \begin{isabelle} |
148 \begin{isabelle} |
145 \ \ getX\ ::\ "('a::more)\ point_scheme\ \isasymRightarrow \ int"\isanewline |
149 \ \ getX\ ::\ "('a::more)\ point_scheme\ \isasymRightarrow \ int"\isanewline |
146 \ \ \ "getX\ r\ ==\ Xcoord\ r"\isanewline |
150 \ \ \ "getX\ r\ ==\ Xcoord\ r"\isanewline |
147 \ \ setX\ ::\ "[('a::more)\ point_scheme,\ int]\ \isasymRightarrow \ 'a\ point_scheme"\isanewline |
151 \ \ setX\ ::\ "[('a::more)\ point_scheme,\ int]\ \isasymRightarrow \ 'a\ point_scheme"\isanewline |
174 \isa{\isasymrparr}, then you must also use the symbolic ellipsis, |
178 \isa{\isasymrparr}, then you must also use the symbolic ellipsis, |
175 \isa{\isasymdots}, rather than three consecutive periods, |
179 \isa{\isasymdots}, rather than three consecutive periods, |
176 \isa{...}. Mixing the ASCII and symbolic versions |
180 \isa{...}. Mixing the ASCII and symbolic versions |
177 causes a syntax error. (The two versions are more |
181 causes a syntax error. (The two versions are more |
178 distinct on screen than they are on paper.) |
182 distinct on screen than they are on paper.) |
179 \end{warn} |
183 \end{warn}% |
|
184 \index{records!extensible|)} |
180 |
185 |
181 |
186 |
182 \subsection{Record Equality} |
187 \subsection{Record Equality} |
183 |
188 |
184 Two records are equal if all pairs of corresponding fields are equal. |
189 Two records are equal\index{equality!of records} |
|
190 if all pairs of corresponding fields are equal. |
185 Record equalities are simplified automatically: |
191 Record equalities are simplified automatically: |
186 \begin{isabelle} |
192 \begin{isabelle} |
187 \isacommand{lemma}\ "(\isasymlparr Xcoord\ =\ a,\ Ycoord\ =\ b\isasymrparr \ =\ \isasymlparr Xcoord\ =\ a',\ Ycoord\ =\ b'\isasymrparr )\ |
193 \isacommand{lemma}\ "(\isasymlparr Xcoord\ =\ a,\ Ycoord\ =\ b\isasymrparr \ =\ \isasymlparr Xcoord\ =\ a',\ Ycoord\ =\ b'\isasymrparr )\ |
188 =\isanewline |
194 =\isanewline |
189 \ \ \ \ \ \ \ \ (a\ =\ a'\ \&\ b\ =\ b')"\isanewline |
195 \ \ \ \ \ \ \ \ (a\ =\ a'\ \&\ b\ =\ b')"\isanewline |
201 We see above the syntax for iterated updates. We could equivalently |
207 We see above the syntax for iterated updates. We could equivalently |
202 have written the left-hand side as |
208 have written the left-hand side as |
203 \isa{r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ \isasymlparr |
209 \isa{r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ \isasymlparr |
204 Ycoord\ :=\ b\isasymrparr}. |
210 Ycoord\ :=\ b\isasymrparr}. |
205 |
211 |
206 Record equality is \emph{extensional}: a record is determined entirely |
212 Record equality is \emph{extensional}: |
207 by the values of its fields. |
213 \index{extensionality!for records} |
|
214 a record is determined entirely by the values of its fields. |
208 \begin{isabelle} |
215 \begin{isabelle} |
209 \isacommand{lemma}\ "r\ =\ \isasymlparr Xcoord\ =\ Xcoord\ r,\ Ycoord\ =\ |
216 \isacommand{lemma}\ "r\ =\ \isasymlparr Xcoord\ =\ Xcoord\ r,\ Ycoord\ =\ |
210 Ycoord\ r\isasymrparr "\isanewline |
217 Ycoord\ r\isasymrparr "\isanewline |
211 \isacommand{by}\ simp |
218 \isacommand{by}\ simp |
212 \end{isabelle} |
219 \end{isabelle} |
242 we enter the lemma again: |
249 we enter the lemma again: |
243 \begin{isabelle} |
250 \begin{isabelle} |
244 \isacommand{lemma}\ "!!r.\ r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ =\ r\ \isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \ a\ =\ |
251 \isacommand{lemma}\ "!!r.\ r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ =\ r\ \isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \ a\ =\ |
245 a'"\isanewline |
252 a'"\isanewline |
246 \end{isabelle} |
253 \end{isabelle} |
247 The \isa{record_split} method replaces the record variable by an |
254 The \methdx{record_split} method replaces the record variable by an |
248 explicit record, listing all fields. Even the field \isa{more} is |
255 explicit record, listing all fields. Even the field \isa{more} is |
249 included, since the record equality is generic. |
256 included, since the record equality is generic. |
250 \begin{isabelle} |
257 \begin{isabelle} |
251 \isacommand{apply}\ record_split\isanewline |
258 \isacommand{apply}\ record_split\isanewline |
252 \ 1.\ \isasymAnd Xcoord\ Ycoord\ more.\isanewline |
259 \ 1.\ \isasymAnd Xcoord\ Ycoord\ more.\isanewline |