doc-src/TutorialI/Types/document/Records.tex
author wenzelm
Sat, 05 Jan 2002 01:14:46 +0100
changeset 12634 3baa6143a9c4
parent 12585 e3cb192aa6ee
child 12656 efcf26bb1361
permissions -rw-r--r--
fixed \index;
     1 %
     2 \begin{isabellebody}%
     3 \def\isabellecontext{Records}%
     4 %
     5 \isamarkupheader{Records \label{sec:records}%
     6 }
     7 \isamarkuptrue%
     8 \isamarkupfalse%
     9 %
    10 \begin{isamarkuptext}%
    11 \index{records|(}%
    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.
    16 
    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
    23   qualified names.
    24 
    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.%
    31 \end{isamarkuptext}%
    32 \isamarkuptrue%
    33 %
    34 \isamarkupsubsection{Record Basics%
    35 }
    36 \isamarkuptrue%
    37 %
    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.%
    44 \end{isamarkuptext}%
    45 \isamarkuptrue%
    46 \isacommand{record}\ point\ {\isacharequal}\isanewline
    47 \ \ Xcoord\ {\isacharcolon}{\isacharcolon}\ int\isanewline
    48 \ \ Ycoord\ {\isacharcolon}{\isacharcolon}\ int\isamarkupfalse%
    49 %
    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}:%
    54 \end{isamarkuptext}%
    55 \isamarkuptrue%
    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%
    59 %
    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
    65   abbreviations):%
    66 \end{isamarkuptext}%
    67 \isamarkuptrue%
    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%
    71 %
    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:%
    76 \end{isamarkuptext}%
    77 \isamarkuptrue%
    78 \isacommand{lemma}\ {\isachardoublequote}Xcoord\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ a{\isachardoublequote}\isanewline
    79 \ \ \isamarkupfalse%
    80 \isacommand{by}\ simp\isamarkupfalse%
    81 %
    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:%
    86 \end{isamarkuptext}%
    87 \isamarkuptrue%
    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
    90 \ \ \isamarkupfalse%
    91 \isacommand{by}\ simp\isamarkupfalse%
    92 %
    93 \begin{isamarkuptext}%
    94 \begin{warn}
    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}.
    98   \end{warn}%
    99 \end{isamarkuptext}%
   100 \isamarkuptrue%
   101 %
   102 \isamarkupsubsection{Extensible Records and Generic Operations%
   103 }
   104 \isamarkuptrue%
   105 %
   106 \begin{isamarkuptext}%
   107 \index{records!extensible|(}%
   108 
   109   Now, let us define coloured points (type \isa{cpoint}) to be
   110   points extended with a field \isa{col} of type \isa{colour}:%
   111 \end{isamarkuptext}%
   112 \isamarkuptrue%
   113 \isacommand{datatype}\ colour\ {\isacharequal}\ Red\ {\isacharbar}\ Green\ {\isacharbar}\ Blue\isanewline
   114 \isanewline
   115 \isamarkupfalse%
   116 \isacommand{record}\ cpoint\ {\isacharequal}\ point\ {\isacharplus}\isanewline
   117 \ \ col\ {\isacharcolon}{\isacharcolon}\ colour\isamarkupfalse%
   118 %
   119 \begin{isamarkuptext}%
   120 The fields of this new type are \isa{Xcoord}, \isa{Ycoord} and
   121   \isa{col}, in that order:%
   122 \end{isamarkuptext}%
   123 \isamarkuptrue%
   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%
   127 %
   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):%
   138 \end{isamarkuptext}%
   139 \isamarkuptrue%
   140 \isacommand{lemma}\ {\isachardoublequote}Xcoord\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ p{\isasymrparr}\ {\isacharequal}\ a{\isachardoublequote}\isanewline
   141 \ \ \isamarkupfalse%
   142 \isacommand{by}\ simp\isamarkupfalse%
   143 %
   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).
   147 
   148   The \isa{more} pseudo-field may be manipulated directly as well,
   149   but the identifier needs to be qualified:%
   150 \end{isamarkuptext}%
   151 \isamarkuptrue%
   152 \isacommand{lemma}\ {\isachardoublequote}point{\isachardot}more\ cpt{\isadigit{1}}\ {\isacharequal}\ {\isasymlparr}col\ {\isacharequal}\ Green{\isasymrparr}{\isachardoublequote}\isanewline
   153 \ \ \isamarkupfalse%
   154 \isacommand{by}\ {\isacharparenleft}simp\ add{\isacharcolon}\ cpt{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}\isamarkupfalse%
   155 %
   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}.
   161 
   162   To define generic operations, we need to know a bit more about
   163   records.  Our definition of \isa{point} above generated two type
   164   abbreviations:
   165 
   166   \medskip
   167   \begin{tabular}{l}
   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}} \\
   170   \end{tabular}
   171   \medskip
   172 
   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}.
   176 
   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.%
   179 \end{isamarkuptext}%
   180 \isamarkuptrue%
   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%
   186 %
   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.):%
   192 \end{isamarkuptext}%
   193 \isamarkuptrue%
   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%
   198 %
   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}:%
   202 \end{isamarkuptext}%
   203 \isamarkuptrue%
   204 \isacommand{lemma}\ {\isachardoublequote}incX\ r\ {\isacharequal}\ setX\ r\ {\isacharparenleft}getX\ r\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequote}\isanewline
   205 \ \ \isamarkupfalse%
   206 \isacommand{by}\ {\isacharparenleft}simp\ add{\isacharcolon}\ getX{\isacharunderscore}def\ setX{\isacharunderscore}def\ incX{\isacharunderscore}def{\isacharparenright}\isamarkupfalse%
   207 %
   208 \begin{isamarkuptext}%
   209 \begin{warn}
   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.)
   215   \end{warn}%
   216   \index{records!extensible|)}%
   217 \end{isamarkuptext}%
   218 \isamarkuptrue%
   219 %
   220 \isamarkupsubsection{Record Equality%
   221 }
   222 \isamarkuptrue%
   223 %
   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
   227   automatically:%
   228 \end{isamarkuptext}%
   229 \isamarkuptrue%
   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
   232 \ \ \isamarkupfalse%
   233 \isacommand{by}\ simp\isamarkupfalse%
   234 %
   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}:%
   238 \end{isamarkuptext}%
   239 \isamarkuptrue%
   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
   241 \ \ \isamarkupfalse%
   242 \isacommand{by}\ simp\isamarkupfalse%
   243 %
   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}}.
   247 
   248   \medskip Record equality is \emph{extensional}:
   249   \index{extensionality!for records} a record is determined entirely
   250   by the values of its fields.%
   251 \end{isamarkuptext}%
   252 \isamarkuptrue%
   253 \isacommand{lemma}\ {\isachardoublequote}r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isasymrparr}{\isachardoublequote}\isanewline
   254 \ \ \isamarkupfalse%
   255 \isacommand{by}\ simp\isamarkupfalse%
   256 %
   257 \begin{isamarkuptext}%
   258 The generic version of this equality includes the pseudo-field
   259   \isa{more}:%
   260 \end{isamarkuptext}%
   261 \isamarkuptrue%
   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
   263 \ \ \isamarkupfalse%
   264 \isacommand{by}\ simp\isamarkupfalse%
   265 %
   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:%
   270 \end{isamarkuptext}%
   271 \isamarkuptrue%
   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
   273 \ \ \isamarkupfalse%
   274 \isacommand{apply}\ simp{\isacharquery}\isanewline
   275 \ \ \isamarkupfalse%
   276 \isacommand{oops}\isamarkupfalse%
   277 %
   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:%
   283 \end{isamarkuptext}%
   284 \isamarkuptrue%
   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
   286 \ \ \isamarkupfalse%
   287 \isacommand{apply}\ {\isacharparenleft}drule{\isacharunderscore}tac\ f\ {\isacharequal}\ Xcoord\ \isakeyword{in}\ arg{\isacharunderscore}cong{\isacharparenright}\isamarkupfalse%
   288 %
   289 \begin{isamarkuptxt}%
   290 \begin{isabelle}%
   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}%
   292 \end{isabelle}
   293     Now, \isa{simp} will reduce the assumption to the desired
   294     conclusion.%
   295 \end{isamarkuptxt}%
   296 \ \ \isamarkuptrue%
   297 \isacommand{apply}\ simp\isanewline
   298 \ \ \isamarkupfalse%
   299 \isacommand{done}\isamarkupfalse%
   300 %
   301 \begin{isamarkuptext}%
   302 The \isa{cases} method is preferable to such a forward proof.  We
   303   state the desired lemma again:%
   304 \end{isamarkuptext}%
   305 \isamarkuptrue%
   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%
   307 %
   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.%
   313 \end{isamarkuptxt}%
   314 \ \ \isamarkuptrue%
   315 \isacommand{apply}\ {\isacharparenleft}cases\ r{\isacharparenright}\isamarkupfalse%
   316 %
   317 \begin{isamarkuptxt}%
   318 \begin{isabelle}%
   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).%
   327 \end{isamarkuptxt}%
   328 \ \ \isamarkuptrue%
   329 \isacommand{apply}\ simp\isanewline
   330 \ \ \isamarkupfalse%
   331 \isacommand{done}\isamarkupfalse%
   332 %
   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}}.%
   339 \end{isamarkuptext}%
   340 \isamarkuptrue%
   341 %
   342 \isamarkupsubsection{Extending and Truncating Records%
   343 }
   344 \isamarkuptrue%
   345 %
   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.
   351 
   352   \begin{itemize}
   353 
   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.
   357 
   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.
   361 
   362   \item Function \cdx{extend} takes two arguments: a record to be
   363   extended and a record containing the new fields.
   364 
   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.
   368 
   369   \end{itemize}
   370 
   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.).
   375 
   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}.
   379 
   380   \begin{isabelle}%
   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}%
   385 \end{isabelle}
   386 
   387   Contrast those with the corresponding functions for record \isa{cpoint}.  Observe \isa{cpoint{\isachardot}fields} in particular.
   388 
   389   \begin{isabelle}%
   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}%
   397 \end{isabelle}
   398 
   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}.%
   403 \end{isamarkuptext}%
   404 \isamarkuptrue%
   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%
   408 %
   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}.%
   414 \end{isamarkuptext}%
   415 \isamarkuptrue%
   416 \isacommand{lemma}\ {\isachardoublequote}cpt{\isadigit{1}}\ {\isacharequal}\ cpt{\isadigit{2}}{\isachardoublequote}\isanewline
   417 \ \ \isamarkupfalse%
   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%
   419 %
   420 \begin{isamarkuptxt}%
   421 \begin{isabelle}%
   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}}%
   423 \end{isabelle}%
   424 \end{isamarkuptxt}%
   425 \ \ \isamarkuptrue%
   426 \isacommand{apply}\ {\isacharparenleft}simp\ add{\isacharcolon}\ pt{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}\isanewline
   427 \ \ \isamarkupfalse%
   428 \isacommand{done}\isamarkupfalse%
   429 %
   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.%
   433 \end{isamarkuptext}%
   434 \isamarkuptrue%
   435 \isacommand{lemma}\ {\isachardoublequote}point{\isachardot}truncate\ cpt{\isadigit{2}}\ {\isacharequal}\ pt{\isadigit{1}}{\isachardoublequote}\isanewline
   436 \ \ \isamarkupfalse%
   437 \isacommand{by}\ {\isacharparenleft}simp\ add{\isacharcolon}\ pt{\isadigit{1}}{\isacharunderscore}def\ cpt{\isadigit{2}}{\isacharunderscore}def\ point{\isachardot}defs{\isacharparenright}\isamarkupfalse%
   438 %
   439 \begin{isamarkuptext}%
   440 \begin{exercise}
   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
   444   types.
   445   \end{exercise}
   446 
   447   \begin{exercise}
   448   (For Java programmers.)
   449   Model a small class hierarchy using records.
   450   \end{exercise}
   451   \index{records|)}%
   452 \end{isamarkuptext}%
   453 \isamarkuptrue%
   454 \isamarkupfalse%
   455 \end{isabellebody}%
   456 %%% Local Variables:
   457 %%% mode: latex
   458 %%% TeX-master: "root"
   459 %%% End: