doc-src/TutorialI/Types/records.tex
author wenzelm
Tue, 06 Nov 2001 19:27:56 +0100
changeset 12070 c72fe1edc9e7
parent 11427 3ed58bbcf4bd
child 12156 d2758965362e
permissions -rw-r--r--
proper treatment of local syntax; store_thm: test atts; Uses: string;
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
5a32e6a78993 the records section
paulson
parents:
diff changeset
    39
\ \ \ \ \ \ \ \ \ \ \ \ "pt1\ ==\ (|\ Xcoord\ =\ \#999,\ Ycoord\ =\ \#23\ |)"
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
5a32e6a78993 the records section
paulson
parents:
diff changeset
    48
\ \ \ \ \ \ \ \ \ \ \ \ "pt2\ ==\ (|\ Xcoord\ =\ \#-45,\ Ycoord\ =\ \#97\ |)"
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,
5a32e6a78993 the records section
paulson
parents:
diff changeset
    60
\isa{p\isasymlparr Xcoord:=\#0\isasymrparr} is a record whose \isa{Xcoord} value
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}
5a32e6a78993 the records section
paulson
parents:
diff changeset
    65
\isacommand{lemma}\ "(|\ Xcoord\ =\ a,\ Ycoord\ =\ b\ |)\ (|\ Xcoord:=\ \#0\ |)\
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
5a32e6a78993 the records section
paulson
parents:
diff changeset
    97
\ \ \ \ \ \ \ \ \ \ \ \ "cpt1\ ==\ (|\ Xcoord\ =\ \#999,\ Ycoord\ =\ \#23,\ col\
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
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   144
\isa{Xcoord} field.  The sort constraint in \isa{'a::more} is
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   145
required, since all extensions must belong to the type class
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   146
\isa{more}.%
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   147
\REMARK{Why, and what does this imply in practice?}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   148
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   149
\ \ getX\ ::\ "('a::more)\ point_scheme\ \isasymRightarrow \ int"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   150
\ \ \ "getX\ r\ ==\ Xcoord\ r"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   151
\ \ setX\ ::\ "[('a::more)\ point_scheme,\ int]\ \isasymRightarrow \ 'a\ point_scheme"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   152
\ \ \ "setX\ r\ a\ ==\ r\ (|\ Xcoord\ :=\ a\ |)"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   153
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   154
5a32e6a78993 the records section
paulson
parents:
diff changeset
   155
Here is a generic method that modifies a point, incrementing its
5a32e6a78993 the records section
paulson
parents:
diff changeset
   156
\isa{Xcoord} field.  The \isa{Ycoord} and \isa{more} fields
5a32e6a78993 the records section
paulson
parents:
diff changeset
   157
are copied across.  It works for type \isa{point} and any of its
5a32e6a78993 the records section
paulson
parents:
diff changeset
   158
extensions, such as \isa{cpoint}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   159
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   160
\isacommand{constdefs}\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   161
\ \ incX\ ::\ "('a::more)\ point_scheme\ \isasymRightarrow \ 'a\ point_scheme"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   162
\ \ "incX\ r\ ==\ \isasymlparr Xcoord\ =\ (Xcoord\ r)\ +\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   163
\#1,\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   164
\ \ \ \ \ \ \ \ \ \ \ \ \ \ Ycoord\ =\ Ycoord\ r,\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   165
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \isasymdots \ =\ point.more\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   166
r\isasymrparr"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   167
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   168
5a32e6a78993 the records section
paulson
parents:
diff changeset
   169
Generic theorems can be proved about generic methods.  This trivial
5a32e6a78993 the records section
paulson
parents:
diff changeset
   170
lemma relates \isa{incX} to \isa{getX} and \isa{setX}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   171
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   172
\isacommand{lemma}\ "incX\ r\ =\ setX\ r\ ((getX\ r)\ +\ \#1)"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   173
\isacommand{by}\ (simp\ add:\ getX_def\ setX_def\ incX_def)
5a32e6a78993 the records section
paulson
parents:
diff changeset
   174
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   175
5a32e6a78993 the records section
paulson
parents:
diff changeset
   176
\begin{warn}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   177
If you use the symbolic record brackets \isa{\isasymlparr} and 
5a32e6a78993 the records section
paulson
parents:
diff changeset
   178
\isa{\isasymrparr}, then you must also use the symbolic ellipsis,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   179
\isa{\isasymdots}, rather than three consecutive periods,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   180
\isa{...}.  Mixing the ASCII and symbolic versions
5a32e6a78993 the records section
paulson
parents:
diff changeset
   181
causes a syntax error.  (The two versions are more
5a32e6a78993 the records section
paulson
parents:
diff changeset
   182
distinct on screen than they are on paper.)
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   183
\end{warn}%
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   184
\index{records!extensible|)}
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   185
5a32e6a78993 the records section
paulson
parents:
diff changeset
   186
5a32e6a78993 the records section
paulson
parents:
diff changeset
   187
\subsection{Record Equality}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   188
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   189
Two records are equal\index{equality!of records}
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   190
if all pairs of corresponding fields are equal. 
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   191
Record equalities are simplified automatically:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   192
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   193
\isacommand{lemma}\ "(\isasymlparr Xcoord\ =\ a,\ Ycoord\ =\ b\isasymrparr \ =\ \isasymlparr Xcoord\ =\ a',\ Ycoord\ =\ b'\isasymrparr )\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   194
=\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   195
\ \ \ \ \ \ \ \ (a\ =\ a'\ \&\ b\ =\ b')"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   196
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
   197
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   198
5a32e6a78993 the records section
paulson
parents:
diff changeset
   199
The following equality is similar, but generic, in that \isa{r} can
5a32e6a78993 the records section
paulson
parents:
diff changeset
   200
be any instance of \isa{point_scheme}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   201
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   202
\isacommand{lemma}\ "r\ \isasymlparr Xcoord\ :=\ a,\ Ycoord\ :=\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   203
b\isasymrparr \ =\ r\ \isasymlparr Ycoord\ :=\ b,\ Xcoord\ :=\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   204
a\isasymrparr "\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   205
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
   206
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   207
We see above the syntax for iterated updates.  We could equivalently
5a32e6a78993 the records section
paulson
parents:
diff changeset
   208
have written the left-hand side as
5a32e6a78993 the records section
paulson
parents:
diff changeset
   209
\isa{r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ \isasymlparr
5a32e6a78993 the records section
paulson
parents:
diff changeset
   210
Ycoord\ :=\ b\isasymrparr}.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   211
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   212
Record equality is \emph{extensional}:
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   213
\index{extensionality!for records} 
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   214
a record is determined entirely by the values of its fields.
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   215
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   216
\isacommand{lemma}\ "r\ =\ \isasymlparr Xcoord\ =\ Xcoord\ r,\ Ycoord\ =\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   217
Ycoord\ r\isasymrparr "\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   218
\isacommand{by}\ simp
5a32e6a78993 the records section
paulson
parents:
diff changeset
   219
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   220
The generic version of this equality includes the field \isa{more}:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   221
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   222
\isacommand{lemma}\ "r\ =\ \isasymlparr Xcoord\ =\ Xcoord\ r,\ Ycoord\ =\ Ycoord\ r,\ \isasymdots \ =\ point.more\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   223
r\isasymrparr"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   224
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   225
5a32e6a78993 the records section
paulson
parents:
diff changeset
   226
\medskip
5a32e6a78993 the records section
paulson
parents:
diff changeset
   227
The simplifier can prove many record equalities automatically,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   228
but general equality reasoning can be tricky.  Consider proving this
5a32e6a78993 the records section
paulson
parents:
diff changeset
   229
obvious fact:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   230
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   231
\isacommand{lemma}\ "r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ =\ r\ \isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \ a\ =\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   232
a'"
5a32e6a78993 the records section
paulson
parents:
diff changeset
   233
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   234
The simplifier can do nothing.  One way to proceed is by an explicit
5a32e6a78993 the records section
paulson
parents:
diff changeset
   235
forward step that applies the selector \isa{Xcoord} to both sides
5a32e6a78993 the records section
paulson
parents:
diff changeset
   236
of the assumed record equality:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   237
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   238
\isacommand{apply}\ (drule_tac\ f=Xcoord\ \isakeyword{in}\ arg_cong)\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   239
\ 1.\ Xcoord\ (r\isasymlparr Xcoord\ :=\ a\isasymrparr )\ =\ Xcoord\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   240
(r\isasymlparr Xcoord\ :=\ a'\isasymrparr )\ \isasymLongrightarrow \
5a32e6a78993 the records section
paulson
parents:
diff changeset
   241
a\ =\ a'
5a32e6a78993 the records section
paulson
parents:
diff changeset
   242
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   243
Now, \isa{simp} will reduce the assumption to the desired
5a32e6a78993 the records section
paulson
parents:
diff changeset
   244
conclusion.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   245
5a32e6a78993 the records section
paulson
parents:
diff changeset
   246
An alternative to such forward steps is record splitting.  A record
5a32e6a78993 the records section
paulson
parents:
diff changeset
   247
variable can be split only if it is bound in the subgoal by the 
5a32e6a78993 the records section
paulson
parents:
diff changeset
   248
meta-quantifier \isa{\isasymAnd}, or \isa{!!} in ASCII\@.  So,
5a32e6a78993 the records section
paulson
parents:
diff changeset
   249
we enter the lemma again:
5a32e6a78993 the records section
paulson
parents:
diff changeset
   250
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   251
\isacommand{lemma}\ "!!r.\ r\ \isasymlparr Xcoord\ :=\ a\isasymrparr \ =\ r\ \isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \ a\ =\
5a32e6a78993 the records section
paulson
parents:
diff changeset
   252
a'"\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   253
\end{isabelle}
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   254
The \methdx{record_split} method replaces the record variable by an
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   255
explicit record, listing all fields.  Even the field \isa{more} is
5a32e6a78993 the records section
paulson
parents:
diff changeset
   256
included, since the record equality is generic.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   257
\begin{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   258
\isacommand{apply}\ record_split\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   259
\ 1.\ \isasymAnd Xcoord\ Ycoord\ more.\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   260
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ =\ Xcoord,\ Ycoord\ =\ Ycoord,\ \isasymdots \ =\ more\isasymrparr \isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   261
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ :=\ a\isasymrparr \ =\isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   262
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ =\ Xcoord,\ Ycoord\ =\ Ycoord,\ \isasymdots \ =\ more\isasymrparr \isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   263
\isaindent{\ 1.\ \ \ \ }\isasymlparr Xcoord\ :=\ a'\isasymrparr \ \isasymLongrightarrow \isanewline
5a32e6a78993 the records section
paulson
parents:
diff changeset
   264
\isaindent{\ 1.\ \ \ \ }a\ =\ a'
5a32e6a78993 the records section
paulson
parents:
diff changeset
   265
\end{isabelle}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   266
Again, \isa{simp} finishes the proof.  Because the records have
5a32e6a78993 the records section
paulson
parents:
diff changeset
   267
been split, the updates can be applied and the record equality can be
5a32e6a78993 the records section
paulson
parents:
diff changeset
   268
replaced by equality of the corresponding fields.
5a32e6a78993 the records section
paulson
parents:
diff changeset
   269
5a32e6a78993 the records section
paulson
parents:
diff changeset
   270
\begin{exercise}
5a32e6a78993 the records section
paulson
parents:
diff changeset
   271
\REMARK{There should be some, but I can't think of any.} 
5a32e6a78993 the records section
paulson
parents:
diff changeset
   272
\end{exercise}
11427
3ed58bbcf4bd indexing
paulson
parents: 11388
diff changeset
   273
\index{records|)}
11388
5a32e6a78993 the records section
paulson
parents:
diff changeset
   274
5a32e6a78993 the records section
paulson
parents:
diff changeset
   275
\endinput
5a32e6a78993 the records section
paulson
parents:
diff changeset
   276