doc-src/TutorialI/Types/Records.thy
changeset 12655 b8c130dc46be
parent 12634 3baa6143a9c4
child 12657 c8385f8f7816
equal deleted inserted replaced
12654:200565ba1471 12655:b8c130dc46be
    31 
    31 
    32 subsection {* Record Basics *}
    32 subsection {* Record Basics *}
    33 
    33 
    34 text {*
    34 text {*
    35   Record types are not primitive in Isabelle and have a delicate
    35   Record types are not primitive in Isabelle and have a delicate
    36   internal representation based on nested copies of the primitive
    36   internal representation \cite{NaraschewskiW-TPHOLs98}, based on
    37   product type.  A \commdx{record} declaration introduces a new record
    37   nested copies of the primitive product type.  A \commdx{record}
    38   type scheme by specifying its fields, which are packaged internally
    38   declaration introduces a new record type scheme by specifying its
    39   to hold up the perception of the record as a distinguished entity.
    39   fields, which are packaged internally to hold up the perception of
       
    40   the record as a distinguished entity.  Here is a simply example.
    40 *}
    41 *}
    41 
    42 
    42 record point =
    43 record point =
    43   Xcoord :: int
    44   Xcoord :: int
    44   Ycoord :: int
    45   Ycoord :: int
    54   "pt1 \<equiv> (| Xcoord = 999, Ycoord = 23 |)"
    55   "pt1 \<equiv> (| Xcoord = 999, Ycoord = 23 |)"
    55 
    56 
    56 text {*
    57 text {*
    57   We see above the ASCII notation for record brackets.  You can also
    58   We see above the ASCII notation for record brackets.  You can also
    58   use the symbolic brackets @{text \<lparr>} and @{text \<rparr>}.  Record type
    59   use the symbolic brackets @{text \<lparr>} and @{text \<rparr>}.  Record type
    59   expressions can be written directly as well, without referring to
    60   expressions can be also written directly with individual fields.
    60   previously declared names (which happen to be mere type
    61   The type name above is merely an abbreviations.
    61   abbreviations):
       
    62 *}
    62 *}
    63 
    63 
    64 constdefs
    64 constdefs
    65   pt2 :: "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>"
    65   pt2 :: "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>"
    66   "pt2 \<equiv> \<lparr>Xcoord = -45, Ycoord = 97\<rparr>"
    66   "pt2 \<equiv> \<lparr>Xcoord = -45, Ycoord = 97\<rparr>"
    78 
    78 
    79 text {*
    79 text {*
    80   The \emph{update}\index{update!record} operation is functional.  For
    80   The \emph{update}\index{update!record} operation is functional.  For
    81   example, @{term "p\<lparr>Xcoord := 0\<rparr>"} is a record whose @{text Xcoord}
    81   example, @{term "p\<lparr>Xcoord := 0\<rparr>"} is a record whose @{text Xcoord}
    82   value is zero and whose @{text Ycoord} value is copied from~@{text
    82   value is zero and whose @{text Ycoord} value is copied from~@{text
    83   p}.  Updates are also simplified automatically:
    83   p}.  Updates of explicit records are also simplified automatically:
    84 *}
    84 *}
    85 
    85 
    86 lemma "\<lparr>Xcoord = a, Ycoord = b\<rparr>\<lparr>Xcoord := 0\<rparr> =
    86 lemma "\<lparr>Xcoord = a, Ycoord = b\<rparr>\<lparr>Xcoord := 0\<rparr> =
    87     \<lparr>Xcoord = 0, Ycoord = b\<rparr>"
    87     \<lparr>Xcoord = 0, Ycoord = b\<rparr>"
    88   by simp
    88   by simp
   110 record cpoint = point +
   110 record cpoint = point +
   111   col :: colour
   111   col :: colour
   112 
   112 
   113 text {*
   113 text {*
   114   The fields of this new type are @{text Xcoord}, @{text Ycoord} and
   114   The fields of this new type are @{text Xcoord}, @{text Ycoord} and
   115   @{text col}, in that order:
   115   @{text col}, in that order.
   116 *}
   116 *}
   117 
   117 
   118 constdefs
   118 constdefs
   119   cpt1 :: cpoint
   119   cpt1 :: cpoint
   120   "cpt1 \<equiv> \<lparr>Xcoord = 999, Ycoord = 23, col = Green\<rparr>"
   120   "cpt1 \<equiv> \<lparr>Xcoord = 999, Ycoord = 23, col = Green\<rparr>"
   121 
   121 
   122 text {*
   122 text {*
   123   We can define generic operations that work on arbitrary instances of
   123   We can define generic operations that work on arbitrary instances of
   124   a record scheme, e.g.\ covering @{typ point}, @{typ cpoint} and any
   124   a record scheme, e.g.\ covering @{typ point}, @{typ cpoint}, and any
   125   further extensions.  Every record structure has an implicit
   125   further extensions.  Every record structure has an implicit
   126   pseudo-field, \cdx{more}, that keeps the extension as an explicit
   126   pseudo-field, \cdx{more}, that keeps the extension as an explicit
   127   value.  Its type is declared as completely polymorphic:~@{typ 'a}.
   127   value.  Its type is declared as completely polymorphic:~@{typ 'a}.
   128   When a fixed record value is expressed using just its standard
   128   When a fixed record value is expressed using just its standard
   129   fields, the value of @{text more} is implicitly set to @{text "()"},
   129   fields, the value of @{text more} is implicitly set to @{text "()"},
   130   the empty tuple, which has type @{typ unit}.  Within the record
   130   the empty tuple, which has type @{typ unit}.  Within the record
   131   brackets, you can refer to the @{text more} field by writing @{text
   131   brackets, you can refer to the @{text more} field by writing
   132   "\<dots>"} (three dots):
   132   ``@{text "\<dots>"}'' (three dots):
   133 *}
   133 *}
   134 
   134 
   135 lemma "Xcoord \<lparr>Xcoord = a, Ycoord = b, \<dots> = p\<rparr> = a"
   135 lemma "Xcoord \<lparr>Xcoord = a, Ycoord = b, \<dots> = p\<rparr> = a"
   136   by simp
   136   by simp
   137 
   137 
   138 text {*
   138 text {*
   139   This lemma applies to any record whose first two fields are @{text
   139   This lemma applies to any record whose first two fields are @{text
   140   Xcoord} and~@{text Ycoord}.  Note that @{text "\<lparr>Xcoord = a, Ycoord =
   140   Xcoord} and~@{text Ycoord}.  Note that @{text "\<lparr>Xcoord = a, Ycoord
   141   b, \<dots> = ()\<rparr>"} is really the same as @{text "\<lparr>Xcoord = a, Ycoord =
   141   = b, \<dots> = ()\<rparr>"} is exactly the same as @{text "\<lparr>Xcoord = a, Ycoord
   142   b\<rparr>"}.  Selectors and updates are always polymorphic wrt.\ the @{text
   142   = b\<rparr>"}.  Selectors and updates are always polymorphic wrt.\ the
   143   more} part of a record scheme, its value is just ignored (for
   143   @{text more} part of a record scheme, its value is just ignored (for
   144   select) or copied (for update).
   144   select) or copied (for update).
   145 
   145 
   146   The @{text more} pseudo-field may be manipulated directly as well,
   146   The @{text more} pseudo-field may be manipulated directly as well,
   147   but the identifier needs to be qualified:
   147   but the identifier needs to be qualified:
   148 *}
   148 *}
   149 
   149 
   150 lemma "point.more cpt1 = \<lparr>col = Green\<rparr>"
   150 lemma "point.more cpt1 = \<lparr>col = Green\<rparr>"
   151   by (simp add: cpt1_def)
   151   by (simp add: cpt1_def)
   152 
   152 
   153 text {*
   153 text {*
   154   We see that the colour attached to this @{typ point} is a
   154   We see that the colour part attached to this @{typ point} is a
   155   (rudimentary) record in its own right, namely @{text "\<lparr>col =
   155   (rudimentary) record in its own right, namely @{text "\<lparr>col =
   156   Green\<rparr>"}.  In order to select or update @{text col}, this fragment
   156   Green\<rparr>"}.  In order to select or update @{text col}, this fragment
   157   needs to be put back into the context of the parent type scheme, say
   157   needs to be put back into the context of the parent type scheme, say
   158   as @{text more} part of another @{typ point}.
   158   as @{text more} part of another @{typ point}.
   159 
   159 
   160   To define generic operations, we need to know a bit more about
   160   To define generic operations, we need to know a bit more about
   161   records.  Our definition of @{typ point} above generated two type
   161   records.  Our definition of @{typ point} above has generated two
   162   abbreviations:
   162   type abbreviations:
   163 
   163 
   164   \medskip
   164   \medskip
   165   \begin{tabular}{l}
   165   \begin{tabular}{l}
   166   @{typ point}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>"} \\
   166   @{typ point}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int\<rparr>"} \\
   167   @{typ "'a point_scheme"}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int, \<dots> :: 'a\<rparr>"} \\
   167   @{typ "'a point_scheme"}~@{text "="}~@{typ "\<lparr>Xcoord :: int, Ycoord :: int, \<dots> :: 'a\<rparr>"} \\
   193   @{typ point} (including @{typ cpoint} etc.):
   193   @{typ point} (including @{typ cpoint} etc.):
   194 *}
   194 *}
   195 
   195 
   196 constdefs
   196 constdefs
   197   incX :: "'a point_scheme \<Rightarrow> 'a point_scheme"
   197   incX :: "'a point_scheme \<Rightarrow> 'a point_scheme"
   198   "incX r \<equiv> \<lparr>Xcoord = Xcoord r + 1,
   198   "incX r \<equiv>
   199     Ycoord = Ycoord r, \<dots> = point.more r\<rparr>"
   199     \<lparr>Xcoord = Xcoord r + 1, Ycoord = Ycoord r, \<dots> = point.more r\<rparr>"
   200 
   200 
   201 text {*
   201 text {*
   202   Generic theorems can be proved about generic methods.  This trivial
   202   Generic theorems can be proved about generic methods.  This trivial
   203   lemma relates @{text incX} to @{text getX} and @{text setX}:
   203   lemma relates @{text incX} to @{text getX} and @{text setX}:
   204 *}
   204 *}
   220 
   220 
   221 subsection {* Record Equality *}
   221 subsection {* Record Equality *}
   222 
   222 
   223 text {*
   223 text {*
   224   Two records are equal\index{equality!of records} if all pairs of
   224   Two records are equal\index{equality!of records} if all pairs of
   225   corresponding fields are equal.  Record equalities are simplified
   225   corresponding fields are equal.  Concrete record equalities are
   226   automatically:
   226   simplified automatically:
   227 *}
   227 *}
   228 
   228 
   229 lemma "(\<lparr>Xcoord = a, Ycoord = b\<rparr> = \<lparr>Xcoord = a', Ycoord = b'\<rparr>) =
   229 lemma "(\<lparr>Xcoord = a, Ycoord = b\<rparr> = \<lparr>Xcoord = a', Ycoord = b'\<rparr>) =
   230     (a = a' \<and> b = b')"
   230     (a = a' \<and> b = b')"
   231   by simp
   231   by simp
   309 
   309 
   310 text {*
   310 text {*
   311   The generic cases method does not admit references to locally bound
   311   The generic cases method does not admit references to locally bound
   312   parameters of a goal.  In longer proof scripts one might have to
   312   parameters of a goal.  In longer proof scripts one might have to
   313   fall back on the primitive @{text rule_tac} used together with the
   313   fall back on the primitive @{text rule_tac} used together with the
   314   internal representation rules of records.  E.g.\ the above use of
   314   internal field representation rules of records.  E.g.\ the above use
   315   @{text "(cases r)"} would become @{text "(rule_tac r = r in
   315   of @{text "(cases r)"} would become @{text "(rule_tac r = r in
   316   point.cases_scheme)"}.
   316   point.cases_scheme)"}.
   317 *}
   317 *}
   318 
   318 
   319 
   319 
   320 subsection {* Extending and Truncating Records *}
   320 subsection {* Extending and Truncating Records *}