doc-src/TutorialI/Types/records.tex
author wenzelm
Mon, 19 Nov 2001 20:46:05 +0100
changeset 12240 0760eda193c4
parent 12156 d2758965362e
child 12407 70ebb59264f1
permissions -rw-r--r--
induct method: localize rews for rule;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
     1
\section{Records} 
5a32e6a78993 the records section
paulson
parents:
diff changeset
     2
\label{sec:records}
5a32e6a78993 the records section
paulson
parents:
diff changeset
     3
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
     4
\index{records|(}%
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
     5
Records are familiar from programming languages.  A record of $n$
5a32e6a78993 the records section
paulson
parents:
diff changeset
     6
fields is essentially an $n$-tuple, but the record's components have
5a32e6a78993 the records section
paulson
parents:
diff changeset
     7
names, which can make expressions easier to read and reduces the risk
5a32e6a78993 the records section
paulson
parents:
diff changeset
     8
of confusing one field for another.
5a32e6a78993 the records section
paulson
parents:
diff changeset
     9
5a32e6a78993 the records section
paulson
parents:
diff changeset
    10
A basic Isabelle record has a fixed set of fields, with access
5a32e6a78993 the records section
paulson
parents:
diff changeset
    11
and update operations.  Each field has a specified type, which may be
5a32e6a78993 the records section
paulson
parents:
diff changeset
    12
polymorphic.  The field names are part of the record type, and the
5a32e6a78993 the records section
paulson
parents:
diff changeset
    13
order of the fields is significant --- as it is in Pascal but not in
5a32e6a78993 the records section
paulson
parents:
diff changeset
    14
Standard ML.  If two different record types have fields in common,
5a32e6a78993 the records section
paulson
parents:
diff changeset
    15
then the ambiguity is resolved in the usual way, by qualified names.
5a32e6a78993 the records section
paulson
parents:
diff changeset
    16
5a32e6a78993 the records section
paulson
parents:
diff changeset
    17
Record types can also be defined by extending other record types. 
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
    18
Extensible records make use of the reserved field \cdx{more}, which is
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    19
present in every record type.  Generic methods, or operations that
5a32e6a78993 the records section
paulson
parents:
diff changeset
    20
work on all possible extensions of a given record, can be expressed by
5a32e6a78993 the records section
paulson
parents:
diff changeset
    21
definitions involving \isa{more}, but the details are complicated.
5a32e6a78993 the records section
paulson
parents:
diff changeset
    22
5a32e6a78993 the records section
paulson
parents:
diff changeset
    23
\subsection{Record Basics}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    24
5a32e6a78993 the records section
paulson
parents:
diff changeset
    25
Record types are not primitive in Isabelle and have a complex internal
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
    26
representation.  A \commdx{record} declaration
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    27
introduces a new record type:
5a32e6a78993 the records section
paulson
parents:
diff changeset
    28
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    29
\isacommand{record}\ point\ =\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    30
\ \ Xcoord\ ::\ int\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    31
\ \ Ycoord\ ::\ int
5a32e6a78993 the records section
paulson
parents:
diff changeset
    32
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    33
5a32e6a78993 the records section
paulson
parents:
diff changeset
    34
Records of type \isa{point} have two fields named \isa{Xcoord} and \isa{Ycoord},
5a32e6a78993 the records section
paulson
parents:
diff changeset
    35
both of type~\isa{int}.  We now declare a constant of type
5a32e6a78993 the records section
paulson
parents:
diff changeset
    36
\isa{point}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
    37
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    38
\isacommand{constdefs}\ \ \ pt1\ ::\ point\isanewline
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
    39
\ \ \ \ \ \ \ \ \ \ \ \ "pt1\ ==\ (|\ Xcoord\ =\ 999,\ Ycoord\ =\ 23\ |)"
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    40
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    41
We see above the ASCII notation for record brackets.  You can also use
5a32e6a78993 the records section
paulson
parents:
diff changeset
    42
the symbolic brackets \isa{\isasymlparr} and  \isa{\isasymrparr}.
5a32e6a78993 the records section
paulson
parents:
diff changeset
    43
Record types can be written directly, rather than referring to
5a32e6a78993 the records section
paulson
parents:
diff changeset
    44
previously declared names: 
5a32e6a78993 the records section
paulson
parents:
diff changeset
    45
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    46
\isacommand{constdefs}\ \ \ pt2\ ::\ "(|\ Xcoord\ ::\ int,\ Ycoord\ ::\ int\
5a32e6a78993 the records section
paulson
parents:
diff changeset
    47
|)"\ \isanewline
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
    48
\ \ \ \ \ \ \ \ \ \ \ \ "pt2\ ==\ (|\ Xcoord\ =\ -45,\ Ycoord\ =\ 97\ |)"
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    49
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    50
5a32e6a78993 the records section
paulson
parents:
diff changeset
    51
For each field, there is a \emph{selector} function of the same name.  For
5a32e6a78993 the records section
paulson
parents:
diff changeset
    52
example, if \isa{p} has type \isa{point} then \isa{Xcoord p} denotes the
5a32e6a78993 the records section
paulson
parents:
diff changeset
    53
value of the \isa{Xcoord} field of~\isa{p}.  Expressions involving field
5a32e6a78993 the records section
paulson
parents:
diff changeset
    54
selection are simplified automatically:
5a32e6a78993 the records section
paulson
parents:
diff changeset
    55
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    56
\isacommand{lemma}\ "Xcoord\ (|\ Xcoord\ =\ a,\ Ycoord\ =\ b\ |)\ =\ a"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    57
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
    58
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    59
The \emph{update} operation is functional.  For example,
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
    60
\isa{p\isasymlparr Xcoord:=0\isasymrparr} is a record whose \isa{Xcoord} value
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    61
is zero and whose
5a32e6a78993 the records section
paulson
parents:
diff changeset
    62
\isa{Ycoord} value is copied from~\isa{p}.  Updates are also simplified
5a32e6a78993 the records section
paulson
parents:
diff changeset
    63
automatically:
5a32e6a78993 the records section
paulson
parents:
diff changeset
    64
\begin{isabelle}
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
    65
\isacommand{lemma}\ "(|\ Xcoord\ =\ a,\ Ycoord\ =\ b\ |)\ (|\ Xcoord:=\ 0\ |)\
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    66
=\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    67
\ \ \ \ \ \ \ \ (|\ Xcoord\ =\ 0,\ Ycoord\ =\ b\ |)"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    68
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
    69
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    70
5a32e6a78993 the records section
paulson
parents:
diff changeset
    71
\begin{warn}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    72
Field names are declared as constants and can no longer be
5a32e6a78993 the records section
paulson
parents:
diff changeset
    73
used as variables.  It would be unwise, for example, to call the fields
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
    74
of type \isa{point} simply \isa{x} and~\isa{y}.  Each record
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
    75
declaration introduces a constant \cdx{more}.
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    76
\end{warn}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    77
5a32e6a78993 the records section
paulson
parents:
diff changeset
    78
5a32e6a78993 the records section
paulson
parents:
diff changeset
    79
\subsection{Extensible Records and Generic Operations}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    80
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
    81
\index{records!extensible|(}%
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    82
Now, let us define coloured points
5a32e6a78993 the records section
paulson
parents:
diff changeset
    83
(type \isa{cpoint}) to be points extended with a field \isa{col} of type
5a32e6a78993 the records section
paulson
parents:
diff changeset
    84
\isa{colour}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
    85
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    86
\isacommand{datatype}\ colour\ =\ Red\ |\ Green\ |\
5a32e6a78993 the records section
paulson
parents:
diff changeset
    87
Blue\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    88
\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    89
\isacommand{record}\ cpoint\ =\ point\ +\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
    90
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ col\ ::\ colour
5a32e6a78993 the records section
paulson
parents:
diff changeset
    91
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    92
5a32e6a78993 the records section
paulson
parents:
diff changeset
    93
The fields of this new type are \isa{Xcoord}, \isa{Ycoord} and \isa{col}, in that
5a32e6a78993 the records section
paulson
parents:
diff changeset
    94
order:
5a32e6a78993 the records section
paulson
parents:
diff changeset
    95
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    96
\isacommand{constdefs}\ \ \ cpt1\ ::\ cpoint\isanewline
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
    97
\ \ \ \ \ \ \ \ \ \ \ \ "cpt1\ ==\ (|\ Xcoord\ =\ 999,\ Ycoord\ =\ 23,\ col\
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
    98
=\ Green\ |)"
5a32e6a78993 the records section
paulson
parents:
diff changeset
    99
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   100
5a32e6a78993 the records section
paulson
parents:
diff changeset
   101
Unfortunately, there are no built-in conversions between types
5a32e6a78993 the records section
paulson
parents:
diff changeset
   102
\isa{point} and \isa{cpoint}: to add a colour to
5a32e6a78993 the records section
paulson
parents:
diff changeset
   103
a point,  or to convert a \isa{cpoint} to a \isa{point} by forgetting
5a32e6a78993 the records section
paulson
parents:
diff changeset
   104
its colour, we must define operations that copy across the other
5a32e6a78993 the records section
paulson
parents:
diff changeset
   105
fields.  However,  we can define generic operations
5a32e6a78993 the records section
paulson
parents:
diff changeset
   106
that work on type
5a32e6a78993 the records section
paulson
parents:
diff changeset
   107
\isa{point} and all extensions of it.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   108
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   109
Every record structure has an implicit field, \cdx{more}, to allow
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   110
extension.  Its type is completely polymorphic:~\isa{'a}.  When a
5a32e6a78993 the records section
paulson
parents:
diff changeset
   111
record value is expressed using just its standard fields, the value of
5a32e6a78993 the records section
paulson
parents:
diff changeset
   112
\isa{more} is implicitly set to \isa{()}, the empty tuple, which has
5a32e6a78993 the records section
paulson
parents:
diff changeset
   113
type \isa{unit}.  Within the record brackets, you can refer to the
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   114
\isa{more} field by writing \isa{...} (three periods):
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   115
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   116
\isacommand{lemma}\ "Xcoord\ (|\ Xcoord\ =\ a,\ Ycoord\ =\ b,\ ...\ =\ p\ |)\ =\ a"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   117
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   118
This lemma (trivially proved using \isa{simp}) applies to any
5a32e6a78993 the records section
paulson
parents:
diff changeset
   119
record whose first two fields are \isa{Xcoord} and~\isa{Ycoord}.  Field
5a32e6a78993 the records section
paulson
parents:
diff changeset
   120
\isa{more} can be selected in the usual way, but as all records share
5a32e6a78993 the records section
paulson
parents:
diff changeset
   121
this field, the identifier must be qualified:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   122
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   123
\isacommand{lemma}\ "point.more\ cpt1\ =\ \isasymlparr col\ =\ Green\isasymrparr "\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   124
\isacommand{by}\ (simp\ add:\ cpt1_def)
5a32e6a78993 the records section
paulson
parents:
diff changeset
   125
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   126
%
5a32e6a78993 the records section
paulson
parents:
diff changeset
   127
We see that the colour attached to this \isa{point} is a record in its
5a32e6a78993 the records section
paulson
parents:
diff changeset
   128
own right, namely 
5a32e6a78993 the records section
paulson
parents:
diff changeset
   129
\isa{\isasymlparr col\ =\ Green\isasymrparr}.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   130
5a32e6a78993 the records section
paulson
parents:
diff changeset
   131
To define generic operations, we need to know a bit more about records.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   132
Our declaration of \isa{point} above generated two type
5a32e6a78993 the records section
paulson
parents:
diff changeset
   133
abbreviations:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   134
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   135
\ \ \ \ point\ =\ (|\ Xcoord\ ::\ int,\ Ycoord\ ::\ int\ |)\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   136
\ \ \ \ 'a\ point_scheme\ =\ (|\ Xcoord\ ::\ int,\ Ycoord\ ::\ int,\ ...\ ::\ 'a\ |)
5a32e6a78993 the records section
paulson
parents:
diff changeset
   137
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   138
%
5a32e6a78993 the records section
paulson
parents:
diff changeset
   139
Type \isa{point} is for rigid records having the two fields
5a32e6a78993 the records section
paulson
parents:
diff changeset
   140
\isa{Xcoord} and~\isa{Ycoord}, while the polymorphic type \isa{'a\ point_scheme}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   141
comprises all possible extensions to those two fields.  For example,
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   142
let us define two operations --- methods, if we regard records as
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   143
objects --- to get and set any point's
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
   144
\isa{Xcoord} field. 
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   145
\begin{isabelle}
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
   146
\ \ getX\ ::\ "'a\ point_scheme\ \isasymRightarrow \ int"\isanewline
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   147
\ \ \ "getX\ r\ ==\ Xcoord\ r"\isanewline
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
   148
\ \ setX\ ::\ "['a\ point_scheme,\ int]\ \isasymRightarrow \ 'a\ point_scheme"\isanewline
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   149
\ \ \ "setX\ r\ a\ ==\ r\ (|\ Xcoord\ :=\ a\ |)"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   150
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   151
5a32e6a78993 the records section
paulson
parents:
diff changeset
   152
Here is a generic method that modifies a point, incrementing its
5a32e6a78993 the records section
paulson
parents:
diff changeset
   153
\isa{Xcoord} field.  The \isa{Ycoord} and \isa{more} fields
5a32e6a78993 the records section
paulson
parents:
diff changeset
   154
are copied across.  It works for type \isa{point} and any of its
5a32e6a78993 the records section
paulson
parents:
diff changeset
   155
extensions, such as \isa{cpoint}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   156
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   157
\isacommand{constdefs}\isanewline
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
   158
\ \ incX\ ::\ "'a\ point_scheme\ \isasymRightarrow \ 'a\ point_scheme"\isanewline
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
   159
\ \ "incX\ r\ ==\ \isasymlparr Xcoord\ =\ (Xcoord\ r)\ +\ 1,\isanewline
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   160
\ \ \ \ \ \ \ \ \ \ \ \ \ \ Ycoord\ =\ Ycoord\ r,\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   161
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \isasymdots \ =\ point.more\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   162
r\isasymrparr"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   163
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   164
5a32e6a78993 the records section
paulson
parents:
diff changeset
   165
Generic theorems can be proved about generic methods.  This trivial
5a32e6a78993 the records section
paulson
parents:
diff changeset
   166
lemma relates \isa{incX} to \isa{getX} and \isa{setX}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   167
\begin{isabelle}
12156
d2758965362e new-style numerals without leading #, along with generic 0 and 1
paulson
parents: 11427
diff changeset
   168
\isacommand{lemma}\ "incX\ r\ =\ setX\ r\ ((getX\ r)\ +\ 1)"\isanewline
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   169
\isacommand{by}\ (simp\ add:\ getX_def\ setX_def\ incX_def)
5a32e6a78993 the records section
paulson
parents:
diff changeset
   170
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   171
5a32e6a78993 the records section
paulson
parents:
diff changeset
   172
\begin{warn}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   173
If you use the symbolic record brackets \isa{\isasymlparr} and 
5a32e6a78993 the records section
paulson
parents:
diff changeset
   174
\isa{\isasymrparr}, then you must also use the symbolic ellipsis,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   175
\isa{\isasymdots}, rather than three consecutive periods,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   176
\isa{...}.  Mixing the ASCII and symbolic versions
5a32e6a78993 the records section
paulson
parents:
diff changeset
   177
causes a syntax error.  (The two versions are more
5a32e6a78993 the records section
paulson
parents:
diff changeset
   178
distinct on screen than they are on paper.)
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   179
\end{warn}%
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   180
\index{records!extensible|)}
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   181
5a32e6a78993 the records section
paulson
parents:
diff changeset
   182
5a32e6a78993 the records section
paulson
parents:
diff changeset
   183
\subsection{Record Equality}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   184
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   185
Two records are equal\index{equality!of records}
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   186
if all pairs of corresponding fields are equal. 
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   187
Record equalities are simplified automatically:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   188
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   189
\isacommand{lemma}\ "(\isasymlparr Xcoord\ =\ a,\ Ycoord\ =\ b\isasymrparr \ =\ \isasymlparr Xcoord\ =\ a',\ Ycoord\ =\ b'\isasymrparr )\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   190
=\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   191
\ \ \ \ \ \ \ \ (a\ =\ a'\ \&\ b\ =\ b')"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   192
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
   193
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   194
5a32e6a78993 the records section
paulson
parents:
diff changeset
   195
The following equality is similar, but generic, in that \isa{r} can
5a32e6a78993 the records section
paulson
parents:
diff changeset
   196
be any instance of \isa{point_scheme}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   197
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   198
\isacommand{lemma}\ "r\ \isasymlparr Xcoord\ :=\ a,\ Ycoord\ :=\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   199
b\isasymrparr \ =\ r\ \isasymlparr Ycoord\ :=\ b,\ Xcoord\ :=\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   200
a\isasymrparr "\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   201
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
   202
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   203
We see above the syntax for iterated updates.  We could equivalently
5a32e6a78993 the records section
paulson
parents:
diff changeset
   204
have written the left-hand side as
5a32e6a78993 the records section
paulson
parents:
diff changeset
   205
\isa{r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ \isasymlparr
5a32e6a78993 the records section
paulson
parents:
diff changeset
   206
Ycoord\ :=\ b\isasymrparr}.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   207
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   208
Record equality is \emph{extensional}:
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   209
\index{extensionality!for records} 
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   210
a record is determined entirely by the values of its fields.
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   211
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   212
\isacommand{lemma}\ "r\ =\ \isasymlparr Xcoord\ =\ Xcoord\ r,\ Ycoord\ =\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   213
Ycoord\ r\isasymrparr "\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   214
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
   215
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   216
The generic version of this equality includes the field \isa{more}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   217
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   218
\isacommand{lemma}\ "r\ =\ \isasymlparr Xcoord\ =\ Xcoord\ r,\ Ycoord\ =\ Ycoord\ r,\ \isasymdots \ =\ point.more\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   219
r\isasymrparr"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   220
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   221
5a32e6a78993 the records section
paulson
parents:
diff changeset
   222
\medskip
5a32e6a78993 the records section
paulson
parents:
diff changeset
   223
The simplifier can prove many record equalities automatically,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   224
but general equality reasoning can be tricky.  Consider proving this
5a32e6a78993 the records section
paulson
parents:
diff changeset
   225
obvious fact:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   226
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   227
\isacommand{lemma}\ "r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ =\ r\ \isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \ a\ =\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   228
a'"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   229
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   230
The simplifier can do nothing.  One way to proceed is by an explicit
5a32e6a78993 the records section
paulson
parents:
diff changeset
   231
forward step that applies the selector \isa{Xcoord} to both sides
5a32e6a78993 the records section
paulson
parents:
diff changeset
   232
of the assumed record equality:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   233
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   234
\isacommand{apply}\ (drule_tac\ f=Xcoord\ \isakeyword{in}\ arg_cong)\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   235
\ 1.\ Xcoord\ (r\isasymlparr Xcoord\ :=\ a\isasymrparr )\ =\ Xcoord\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   236
(r\isasymlparr Xcoord\ :=\ a'\isasymrparr )\ \isasymLongrightarrow \
5a32e6a78993 the records section
paulson
parents:
diff changeset
   237
a\ =\ a'
5a32e6a78993 the records section
paulson
parents:
diff changeset
   238
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   239
Now, \isa{simp} will reduce the assumption to the desired
5a32e6a78993 the records section
paulson
parents:
diff changeset
   240
conclusion.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   241
5a32e6a78993 the records section
paulson
parents:
diff changeset
   242
An alternative to such forward steps is record splitting.  A record
5a32e6a78993 the records section
paulson
parents:
diff changeset
   243
variable can be split only if it is bound in the subgoal by the 
5a32e6a78993 the records section
paulson
parents:
diff changeset
   244
meta-quantifier \isa{\isasymAnd}, or \isa{!!} in ASCII\@.  So,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   245
we enter the lemma again:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   246
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   247
\isacommand{lemma}\ "!!r.\ r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ =\ r\ \isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \ a\ =\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   248
a'"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   249
\end{isabelle}
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   250
The \methdx{record_split} method replaces the record variable by an
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   251
explicit record, listing all fields.  Even the field \isa{more} is
5a32e6a78993 the records section
paulson
parents:
diff changeset
   252
included, since the record equality is generic.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   253
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   254
\isacommand{apply}\ record_split\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   255
\ 1.\ \isasymAnd Xcoord\ Ycoord\ more.\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   256
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ =\ Xcoord,\ Ycoord\ =\ Ycoord,\ \isasymdots \ =\ more\isasymrparr \isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   257
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ :=\ a\isasymrparr \ =\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   258
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ =\ Xcoord,\ Ycoord\ =\ Ycoord,\ \isasymdots \ =\ more\isasymrparr \isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   259
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   260
\isaindent{\ 1.\ \ \ \ }a\ =\ a'
5a32e6a78993 the records section
paulson
parents:
diff changeset
   261
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   262
Again, \isa{simp} finishes the proof.  Because the records have
5a32e6a78993 the records section
paulson
parents:
diff changeset
   263
been split, the updates can be applied and the record equality can be
5a32e6a78993 the records section
paulson
parents:
diff changeset
   264
replaced by equality of the corresponding fields.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   265
5a32e6a78993 the records section
paulson
parents:
diff changeset
   266
\begin{exercise}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   267
\REMARK{There should be some, but I can't think of any.} 
5a32e6a78993 the records section
paulson
parents:
diff changeset
   268
\end{exercise}
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   269
\index{records|)}
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   270
5a32e6a78993 the records section
paulson
parents:
diff changeset
   271
\endinput
5a32e6a78993 the records section
paulson
parents:
diff changeset
   272