3 \def\isabellecontext{Records}%
5 \isamarkupheader{Records \label{sec:records}%
10 \begin{isamarkuptext}%
12 Records are familiar from programming languages. A record of $n$
13 fields is essentially an $n$-tuple, but the record's components have
14 names, which can make expressions easier to read and reduces the
15 risk of confusing one field for another.
17 A record of Isabelle/HOL covers a collection of fields, with select
18 and update operations. Each field has a specified type, which may
19 be polymorphic. The field names are part of the record type, and
20 the order of the fields is significant --- as it is in Pascal but
21 not in Standard ML. If two different record types have field names
22 in common, then the ambiguity is resolved in the usual way, by
25 Record types can also be defined by extending other record types.
26 Extensible records make use of the reserved pseudo-field \cdx{more},
27 which is present in every record type. Generic record operations
28 work on all possible extensions of a given type scheme; polymorphism
29 takes care of structural sub-typing behind the scenes. There are
30 also explicit coercion functions between fixed record types.%
34 \isamarkupsubsection{Record Basics%
38 \begin{isamarkuptext}%
39 Record types are not primitive in Isabelle and have a delicate
40 internal representation based on nested copies of the primitive
41 product type. A \commdx{record} declaration introduces a new record
42 type scheme by specifying its fields, which are packaged internally
43 to hold up the perception of the record as a distinguished entity.%
46 \isacommand{record}\ point\ {\isacharequal}\isanewline
47 \ \ Xcoord\ {\isacharcolon}{\isacharcolon}\ int\isanewline
48 \ \ Ycoord\ {\isacharcolon}{\isacharcolon}\ int\isamarkupfalse%
50 \begin{isamarkuptext}%
51 Records of type \isa{point} have two fields named \isa{Xcoord}
52 and \isa{Ycoord}, both of type~\isa{int}. We now define a
53 constant of type \isa{point}:%
56 \isacommand{constdefs}\isanewline
57 \ \ pt{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ point\isanewline
58 \ \ {\isachardoublequote}pt{\isadigit{1}}\ {\isasymequiv}\ {\isacharparenleft}{\isacharbar}\ Xcoord\ {\isacharequal}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}{\isacharcomma}\ Ycoord\ {\isacharequal}\ {\isadigit{2}}{\isadigit{3}}\ {\isacharbar}{\isacharparenright}{\isachardoublequote}\isamarkupfalse%
60 \begin{isamarkuptext}%
61 We see above the ASCII notation for record brackets. You can also
62 use the symbolic brackets \isa{{\isasymlparr}} and \isa{{\isasymrparr}}. Record type
63 expressions can be written directly as well, without referring to
64 previously declared names (which happen to be mere type
68 \isacommand{constdefs}\isanewline
69 \ \ pt{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharcolon}\ int{\isacharcomma}\ Ycoord\ {\isacharcolon}{\isacharcolon}\ int{\isasymrparr}{\isachardoublequote}\isanewline
70 \ \ {\isachardoublequote}pt{\isadigit{2}}\ {\isasymequiv}\ {\isasymlparr}Xcoord\ {\isacharequal}\ {\isacharminus}{\isadigit{4}}{\isadigit{5}}{\isacharcomma}\ Ycoord\ {\isacharequal}\ {\isadigit{9}}{\isadigit{7}}{\isasymrparr}{\isachardoublequote}\isamarkupfalse%
72 \begin{isamarkuptext}%
73 For each field, there is a \emph{selector}\index{selector!record}
74 function of the same name. For example, if \isa{p} has type \isa{point} then \isa{Xcoord\ p} denotes the value of the \isa{Xcoord} field of~\isa{p}. Expressions involving field selection
75 of explicit records are simplified automatically:%
78 \isacommand{lemma}\ {\isachardoublequote}Xcoord\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ a{\isachardoublequote}\isanewline
80 \isacommand{by}\ simp\isamarkupfalse%
82 \begin{isamarkuptext}%
83 The \emph{update}\index{update!record} operation is functional. For
84 example, \isa{p{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ {\isadigit{0}}{\isasymrparr}} is a record whose \isa{Xcoord}
85 value is zero and whose \isa{Ycoord} value is copied from~\isa{p}. Updates are also simplified automatically:%
88 \isacommand{lemma}\ {\isachardoublequote}{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ {\isadigit{0}}{\isasymrparr}\ {\isacharequal}\isanewline
89 \ \ \ \ {\isasymlparr}Xcoord\ {\isacharequal}\ {\isadigit{0}}{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}{\isachardoublequote}\isanewline
91 \isacommand{by}\ simp\isamarkupfalse%
93 \begin{isamarkuptext}%
95 Field names are declared as constants and can no longer be used as
96 variables. It would be unwise, for example, to call the fields of
97 type \isa{point} simply \isa{x} and~\isa{y}.
102 \isamarkupsubsection{Extensible Records and Generic Operations%
106 \begin{isamarkuptext}%
107 \index{records!extensible|(}%
109 Now, let us define coloured points (type \isa{cpoint}) to be
110 points extended with a field \isa{col} of type \isa{colour}:%
113 \isacommand{datatype}\ colour\ {\isacharequal}\ Red\ {\isacharbar}\ Green\ {\isacharbar}\ Blue\isanewline
116 \isacommand{record}\ cpoint\ {\isacharequal}\ point\ {\isacharplus}\isanewline
117 \ \ col\ {\isacharcolon}{\isacharcolon}\ colour\isamarkupfalse%
119 \begin{isamarkuptext}%
120 The fields of this new type are \isa{Xcoord}, \isa{Ycoord} and
121 \isa{col}, in that order:%
124 \isacommand{constdefs}\isanewline
125 \ \ cpt{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ cpoint\isanewline
126 \ \ {\isachardoublequote}cpt{\isadigit{1}}\ {\isasymequiv}\ {\isasymlparr}Xcoord\ {\isacharequal}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}{\isacharcomma}\ Ycoord\ {\isacharequal}\ {\isadigit{2}}{\isadigit{3}}{\isacharcomma}\ col\ {\isacharequal}\ Green{\isasymrparr}{\isachardoublequote}\isamarkupfalse%
128 \begin{isamarkuptext}%
129 We can define generic operations that work on arbitrary instances of
130 a record scheme, e.g.\ covering \isa{point}, \isa{cpoint} and any
131 further extensions. Every record structure has an implicit
132 pseudo-field, \cdx{more}, that keeps the extension as an explicit
133 value. Its type is declared as completely polymorphic:~\isa{{\isacharprime}a}.
134 When a fixed record value is expressed using just its standard
135 fields, the value of \isa{more} is implicitly set to \isa{{\isacharparenleft}{\isacharparenright}},
136 the empty tuple, which has type \isa{unit}. Within the record
137 brackets, you can refer to the \isa{more} field by writing \isa{{\isasymdots}} (three dots):%
140 \isacommand{lemma}\ {\isachardoublequote}Xcoord\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ p{\isasymrparr}\ {\isacharequal}\ a{\isachardoublequote}\isanewline
142 \isacommand{by}\ simp\isamarkupfalse%
144 \begin{isamarkuptext}%
145 This lemma applies to any record whose first two fields are \isa{Xcoord} and~\isa{Ycoord}. Note that \isa{{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ {\isacharparenleft}{\isacharparenright}{\isasymrparr}} is really the same as \isa{{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}}. Selectors and updates are always polymorphic wrt.\ the \isa{more} part of a record scheme, its value is just ignored (for
146 select) or copied (for update).
148 The \isa{more} pseudo-field may be manipulated directly as well,
149 but the identifier needs to be qualified:%
152 \isacommand{lemma}\ {\isachardoublequote}point{\isachardot}more\ cpt{\isadigit{1}}\ {\isacharequal}\ {\isasymlparr}col\ {\isacharequal}\ Green{\isasymrparr}{\isachardoublequote}\isanewline
154 \isacommand{by}\ {\isacharparenleft}simp\ add{\isacharcolon}\ cpt{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}\isamarkupfalse%
156 \begin{isamarkuptext}%
157 We see that the colour attached to this \isa{point} is a
158 (rudimentary) record in its own right, namely \isa{{\isasymlparr}col\ {\isacharequal}\ Green{\isasymrparr}}. In order to select or update \isa{col}, this fragment
159 needs to be put back into the context of the parent type scheme, say
160 as \isa{more} part of another \isa{point}.
162 To define generic operations, we need to know a bit more about
163 records. Our definition of \isa{point} above generated two type
168 \isa{point}~\isa{{\isacharequal}}~\isa{{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharcolon}\ int{\isacharcomma}\ Ycoord\ {\isacharcolon}{\isacharcolon}\ int{\isasymrparr}} \\
169 \isa{{\isacharprime}a\ point{\isacharunderscore}scheme}~\isa{{\isacharequal}}~\isa{{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharcolon}\ int{\isacharcomma}\ Ycoord\ {\isacharcolon}{\isacharcolon}\ int{\isacharcomma}\ {\isasymdots}\ {\isacharcolon}{\isacharcolon}\ {\isacharprime}a{\isasymrparr}} \\
173 Type \isa{point} is for fixed records having exactly the two fields
174 \isa{Xcoord} and~\isa{Ycoord}, while the polymorphic type \isa{{\isacharprime}a\ point{\isacharunderscore}scheme} comprises all possible extensions to those two
175 fields. Note that \isa{unit\ point{\isacharunderscore}scheme} coincides with \isa{point}, and \isa{{\isasymlparr}col\ {\isacharcolon}{\isacharcolon}\ colour{\isasymrparr}\ point{\isacharunderscore}scheme} with \isa{cpoint}.
177 In the following example we define two operations --- methods, if we
178 regard records as objects --- to get and set any point's \isa{Xcoord} field.%
181 \isacommand{constdefs}\isanewline
182 \ \ getX\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharprime}a\ point{\isacharunderscore}scheme\ {\isasymRightarrow}\ int{\isachardoublequote}\isanewline
183 \ \ {\isachardoublequote}getX\ r\ {\isasymequiv}\ Xcoord\ r{\isachardoublequote}\isanewline
184 \ \ setX\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharprime}a\ point{\isacharunderscore}scheme\ {\isasymRightarrow}\ int\ {\isasymRightarrow}\ {\isacharprime}a\ point{\isacharunderscore}scheme{\isachardoublequote}\isanewline
185 \ \ {\isachardoublequote}setX\ r\ a\ {\isasymequiv}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isachardoublequote}\isamarkupfalse%
187 \begin{isamarkuptext}%
188 Here is a generic method that modifies a point, incrementing its
189 \isa{Xcoord} field. The \isa{Ycoord} and \isa{more} fields
190 are copied across. It works for any record type scheme derived from
191 \isa{point} (including \isa{cpoint} etc.):%
194 \isacommand{constdefs}\isanewline
195 \ \ incX\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharprime}a\ point{\isacharunderscore}scheme\ {\isasymRightarrow}\ {\isacharprime}a\ point{\isacharunderscore}scheme{\isachardoublequote}\isanewline
196 \ \ {\isachardoublequote}incX\ r\ {\isasymequiv}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r\ {\isacharplus}\ {\isadigit{1}}{\isacharcomma}\isanewline
197 \ \ \ \ Ycoord\ {\isacharequal}\ Ycoord\ r{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ point{\isachardot}more\ r{\isasymrparr}{\isachardoublequote}\isamarkupfalse%
199 \begin{isamarkuptext}%
200 Generic theorems can be proved about generic methods. This trivial
201 lemma relates \isa{incX} to \isa{getX} and \isa{setX}:%
204 \isacommand{lemma}\ {\isachardoublequote}incX\ r\ {\isacharequal}\ setX\ r\ {\isacharparenleft}getX\ r\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequote}\isanewline
206 \isacommand{by}\ {\isacharparenleft}simp\ add{\isacharcolon}\ getX{\isacharunderscore}def\ setX{\isacharunderscore}def\ incX{\isacharunderscore}def{\isacharparenright}\isamarkupfalse%
208 \begin{isamarkuptext}%
210 If you use the symbolic record brackets \isa{{\isasymlparr}} and \isa{{\isasymrparr}},
211 then you must also use the symbolic ellipsis, ``\isa{{\isasymdots}}'', rather
212 than three consecutive periods, ``\isa{{\isachardot}{\isachardot}{\isachardot}}''. Mixing the ASCII
213 and symbolic versions causes a syntax error. (The two versions are
214 more distinct on screen than they are on paper.)
216 \index{records!extensible|)}%
220 \isamarkupsubsection{Record Equality%
224 \begin{isamarkuptext}%
225 Two records are equal\index{equality!of records} if all pairs of
226 corresponding fields are equal. Record equalities are simplified
230 \isacommand{lemma}\ {\isachardoublequote}{\isacharparenleft}{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharprime}{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isacharprime}{\isasymrparr}{\isacharparenright}\ {\isacharequal}\isanewline
231 \ \ \ \ {\isacharparenleft}a\ {\isacharequal}\ a{\isacharprime}\ {\isasymand}\ b\ {\isacharequal}\ b{\isacharprime}{\isacharparenright}{\isachardoublequote}\isanewline
233 \isacommand{by}\ simp\isamarkupfalse%
235 \begin{isamarkuptext}%
236 The following equality is similar, but generic, in that \isa{r}
237 can be any instance of \isa{{\isacharprime}a\ point{\isacharunderscore}scheme}:%
240 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isacharcomma}\ Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isachardoublequote}\isanewline
242 \isacommand{by}\ simp\isamarkupfalse%
244 \begin{isamarkuptext}%
245 We see above the syntax for iterated updates. We could equivalently
246 have written the left-hand side as \isa{r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isasymlparr}Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isasymrparr}}.
248 \medskip Record equality is \emph{extensional}:
249 \index{extensionality!for records} a record is determined entirely
250 by the values of its fields.%
253 \isacommand{lemma}\ {\isachardoublequote}r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isasymrparr}{\isachardoublequote}\isanewline
255 \isacommand{by}\ simp\isamarkupfalse%
257 \begin{isamarkuptext}%
258 The generic version of this equality includes the pseudo-field
262 \isacommand{lemma}\ {\isachardoublequote}r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ point{\isachardot}more\ r{\isasymrparr}{\isachardoublequote}\isanewline
264 \isacommand{by}\ simp\isamarkupfalse%
266 \begin{isamarkuptext}%
267 \medskip The simplifier can prove many record equalities
268 automatically, but general equality reasoning can be tricky.
269 Consider proving this obvious fact:%
272 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isanewline
274 \isacommand{apply}\ simp{\isacharquery}\isanewline
276 \isacommand{oops}\isamarkupfalse%
278 \begin{isamarkuptext}%
279 Here the simplifier can do nothing, since general record equality is
280 not eliminated automatically. One way to proceed is by an explicit
281 forward step that applies the selector \isa{Xcoord} to both sides
282 of the assumed record equality:%
285 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isanewline
287 \isacommand{apply}\ {\isacharparenleft}drule{\isacharunderscore}tac\ f\ {\isacharequal}\ Xcoord\ \isakeyword{in}\ arg{\isacharunderscore}cong{\isacharparenright}\isamarkupfalse%
289 \begin{isamarkuptxt}%
291 \ {\isadigit{1}}{\isachardot}\ Xcoord\ {\isacharparenleft}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isacharparenright}\ {\isacharequal}\ Xcoord\ {\isacharparenleft}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}{\isacharparenright}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}%
293 Now, \isa{simp} will reduce the assumption to the desired
297 \isacommand{apply}\ simp\isanewline
299 \isacommand{done}\isamarkupfalse%
301 \begin{isamarkuptext}%
302 The \isa{cases} method is preferable to such a forward proof. We
303 state the desired lemma again:%
306 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isamarkupfalse%
308 \begin{isamarkuptxt}%
309 The \methdx{cases} method adds an equality to replace the
310 named record term by an explicit record expression, listing all
311 fields. It even includes the pseudo-field \isa{more}, since the
312 record equality stated here is generic for all extensions.%
315 \isacommand{apply}\ {\isacharparenleft}cases\ r{\isacharparenright}\isamarkupfalse%
317 \begin{isamarkuptxt}%
319 \ {\isadigit{1}}{\isachardot}\ {\isasymAnd}Xcoord\ Ycoord\ more{\isachardot}\isanewline
320 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }{\isasymlbrakk}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}{\isacharsemicolon}\isanewline
321 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ \ \ \ }r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ more{\isasymrparr}{\isasymrbrakk}\isanewline
322 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }{\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}%
323 \end{isabelle} Again, \isa{simp} finishes the proof. Because \isa{r} is now represented as
324 an explicit record construction, the updates can be applied and the
325 record equality can be replaced by equality of the corresponding
326 fields (due to injectivity).%
329 \isacommand{apply}\ simp\isanewline
331 \isacommand{done}\isamarkupfalse%
333 \begin{isamarkuptext}%
334 The generic cases method does not admit references to locally bound
335 parameters of a goal. In longer proof scripts one might have to
336 fall back on the primitive \isa{rule{\isacharunderscore}tac} used together with the
337 internal representation rules of records. E.g.\ the above use of
338 \isa{{\isacharparenleft}cases\ r{\isacharparenright}} would become \isa{{\isacharparenleft}rule{\isacharunderscore}tac\ r\ {\isacharequal}\ r\ in\ point{\isachardot}cases{\isacharunderscore}scheme{\isacharparenright}}.%
342 \isamarkupsubsection{Extending and Truncating Records%
346 \begin{isamarkuptext}%
347 Each record declaration introduces a number of derived operations to
348 refer collectively to a record's fields and to convert between fixed
349 record types. They can, for instance, convert between types \isa{point} and \isa{cpoint}. We can add a colour to a point or convert
350 a \isa{cpoint} to a \isa{point} by forgetting its colour.
354 \item Function \cdx{make} takes as arguments all of the record's
355 fields (including those inherited from ancestors). It returns the
356 corresponding record.
358 \item Function \cdx{fields} takes the record's very own fields and
359 returns a record fragment consisting of just those fields. This may
360 be filled into the \isa{more} part of the parent record scheme.
362 \item Function \cdx{extend} takes two arguments: a record to be
363 extended and a record containing the new fields.
365 \item Function \cdx{truncate} takes a record (possibly an extension
366 of the original record type) and returns a fixed record, removing
367 any additional fields.
371 These functions merely provide handsome abbreviations for standard
372 record expressions involving constructors and selectors. The
373 definitions, which are \emph{not} unfolded by default, are made
374 available by the collective name of \isa{defs} (\isa{point{\isachardot}defs}, \isa{cpoint{\isachardot}defs}, etc.).
376 For example, here are the versions of those functions generated for
377 record \isa{point}. We omit \isa{point{\isachardot}fields}, which happens to
378 be the same as \isa{point{\isachardot}make}.
381 point{\isachardot}make\ Xcoord\ Ycoord\ {\isasymequiv}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord{\isasymrparr}\isanewline
382 point{\isachardot}extend\ r\ more\ {\isasymequiv}\isanewline
383 {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ more{\isasymrparr}\isanewline
384 point{\isachardot}truncate\ r\ {\isasymequiv}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isasymrparr}%
387 Contrast those with the corresponding functions for record \isa{cpoint}. Observe \isa{cpoint{\isachardot}fields} in particular.
390 cpoint{\isachardot}make\ Xcoord\ Ycoord\ col\ {\isasymequiv}\isanewline
391 {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord{\isacharcomma}\ col\ {\isacharequal}\ col{\isasymrparr}\isanewline
392 cpoint{\isachardot}fields\ col\ {\isasymequiv}\ {\isasymlparr}col\ {\isacharequal}\ col{\isasymrparr}\isanewline
393 cpoint{\isachardot}extend\ r\ more\ {\isasymequiv}\isanewline
394 {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isacharcomma}\ col\ {\isacharequal}\ col\ r{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ more{\isasymrparr}\isanewline
395 cpoint{\isachardot}truncate\ r\ {\isasymequiv}\isanewline
396 {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isacharcomma}\ col\ {\isacharequal}\ col\ r{\isasymrparr}%
399 To demonstrate these functions, we declare a new coloured point by
400 extending an ordinary point. Function \isa{point{\isachardot}extend} augments
401 \isa{pt{\isadigit{1}}} with a colour value, which is converted into an
402 appropriate record fragment by \isa{cpoint{\isachardot}fields}.%
405 \isacommand{constdefs}\isanewline
406 \ \ cpt{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ cpoint\isanewline
407 \ \ {\isachardoublequote}cpt{\isadigit{2}}\ {\isasymequiv}\ point{\isachardot}extend\ pt{\isadigit{1}}\ {\isacharparenleft}cpoint{\isachardot}fields\ Green{\isacharparenright}{\isachardoublequote}\isamarkupfalse%
409 \begin{isamarkuptext}%
410 The coloured points \isa{cpt{\isadigit{1}}} and \isa{cpt{\isadigit{2}}} are equal. The
411 proof is trivial, by unfolding all the definitions. We deliberately
412 omit the definition of~\isa{pt{\isadigit{1}}} in order to reveal the underlying
413 comparison on type \isa{point}.%
416 \isacommand{lemma}\ {\isachardoublequote}cpt{\isadigit{1}}\ {\isacharequal}\ cpt{\isadigit{2}}{\isachardoublequote}\isanewline
418 \isacommand{apply}\ {\isacharparenleft}simp\ add{\isacharcolon}\ cpt{\isadigit{1}}{\isacharunderscore}def\ cpt{\isadigit{2}}{\isacharunderscore}def\ point{\isachardot}defs\ cpoint{\isachardot}defs{\isacharparenright}\isamarkupfalse%
420 \begin{isamarkuptxt}%
422 \ {\isadigit{1}}{\isachardot}\ Xcoord\ pt{\isadigit{1}}\ {\isacharequal}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}\ {\isasymand}\ Ycoord\ pt{\isadigit{1}}\ {\isacharequal}\ {\isadigit{2}}{\isadigit{3}}%
426 \isacommand{apply}\ {\isacharparenleft}simp\ add{\isacharcolon}\ pt{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}\isanewline
428 \isacommand{done}\isamarkupfalse%
430 \begin{isamarkuptext}%
431 In the example below, a coloured point is truncated to leave a
432 point. We use the \isa{truncate} function of the target record.%
435 \isacommand{lemma}\ {\isachardoublequote}point{\isachardot}truncate\ cpt{\isadigit{2}}\ {\isacharequal}\ pt{\isadigit{1}}{\isachardoublequote}\isanewline
437 \isacommand{by}\ {\isacharparenleft}simp\ add{\isacharcolon}\ pt{\isadigit{1}}{\isacharunderscore}def\ cpt{\isadigit{2}}{\isacharunderscore}def\ point{\isachardot}defs{\isacharparenright}\isamarkupfalse%
439 \begin{isamarkuptext}%
441 Extend record \isa{cpoint} to have a further field, \isa{intensity}, of type~\isa{nat}. Experiment with generic operations
442 (using polymorphic selectors and updates) and explicit coercions
443 (using \isa{extend}, \isa{truncate} etc.) among the three record
448 (For Java programmers.)
449 Model a small class hierarchy using records.
458 %%% TeX-master: "root"