src/HOL/ex/Points.thy
changeset 9059 2b537d9e6f49
parent 7742 01386eb4eab0
child 9151 5339a76c6dfe
equal deleted inserted replaced
9058:7856a01119fb 9059:2b537d9e6f49
     1 (*  Title:      HOL/ex/Points.thy
     1 (*  Title:      HOL/ex/Points.thy
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Wolfgang Naraschewski and Markus Wenzel, TU Muenchen
     3     Author:     Wolfgang Naraschewski and Markus Wenzel, TU Muenchen
     4 *)
     4 *)
     5 
     5 
     6 theory Points = Main:;
     6 theory Points = Main:
     7 
     7 
     8 text {* Basic use of extensible records in HOL, including the famous points
     8 text {* Basic use of extensible records in HOL, including the famous points
     9  and coloured points. *};
     9  and coloured points. *}
    10 
    10 
    11 
    11 
    12 section {* Points *};
    12 section {* Points *}
    13 
    13 
    14 record point =
    14 record point =
    15   x :: nat
    15   x :: nat
    16   y :: nat;
    16   y :: nat
    17 
    17 
    18 text {*
    18 text {*
    19   Apart many other things, above record declaration produces the
    19  Apart many other things, above record declaration produces the
    20   following theorems:
    20  following theorems:
       
    21 *}
    21 
    22 
    22     thms "point.simps"
    23 thm "point.simps"
    23     thms "point.iffs"
    24 thm "point.iffs"
    24     thms "point.update_defs"
    25 thm "point.update_defs"
    25 
    26 
    26   The set of theorems "point.simps" is added automatically to the
    27 text {*
    27   standard simpset, "point.iffs" is added to the claset and simpset.
    28  The set of theorems "point.simps" is added automatically to the
    28 *};
    29  standard simpset, "point.iffs" is added to the claset and simpset.
       
    30 *}
    29 
    31 
    30 text {*
    32 text {*
    31   Record declarations define new type abbreviations:
    33   Record declarations define new type abbreviations:
    32 
    34 
    33     point = "(| x :: nat, y :: nat |)"
    35     point = "(| x :: nat, y :: nat |)"
    34     'a point_scheme = "(| x :: nat, y :: nat, ... :: 'a |)"
    36     'a point_scheme = "(| x :: nat, y :: nat, ... :: 'a |)"
    35 
    37 
    36   Extensions `...' must be in type class `more'!
    38   Extensions `...' must be in type class `more'!
    37 *};
    39 *}
    38 
    40 
    39 consts foo1 :: point;
    41 consts foo1 :: point
    40 consts foo2 :: "(| x :: nat, y :: nat |)";
    42 consts foo2 :: "(| x :: nat, y :: nat |)"
    41 consts foo3 :: "'a => ('a::more) point_scheme";
    43 consts foo3 :: "'a => ('a::more) point_scheme"
    42 consts foo4 :: "'a => (| x :: nat, y :: nat, ... :: 'a |)";
    44 consts foo4 :: "'a => (| x :: nat, y :: nat, ... :: 'a |)"
    43 
    45 
    44 
    46 
    45 subsection {* Introducing concrete records and record schemes *};
    47 subsection {* Introducing concrete records and record schemes *}
    46 
    48 
    47 defs
    49 defs
    48   foo1_def: "foo1 == (| x = 1, y = 0 |)"
    50   foo1_def: "foo1 == (| x = 1, y = 0 |)"
    49   foo3_def: "foo3 ext == (| x = 1, y = 0, ... = ext |)";
    51   foo3_def: "foo3 ext == (| x = 1, y = 0, ... = ext |)"
    50 
    52 
    51 
    53 
    52 subsection {* Record selection and record update *};
    54 subsection {* Record selection and record update *}
    53 
    55 
    54 constdefs
    56 constdefs
    55   getX :: "('a::more) point_scheme => nat"
    57   getX :: "('a::more) point_scheme => nat"
    56   "getX r == x r"
    58   "getX r == x r"
    57   setX :: "('a::more) point_scheme => nat => 'a point_scheme"
    59   setX :: "('a::more) point_scheme => nat => 'a point_scheme"
    58   "setX r n == r (| x := n |)";
    60   "setX r n == r (| x := n |)"
    59 
    61 
    60 
    62 
    61 subsection {* Some lemmas about records *};
    63 subsection {* Some lemmas about records *}
    62 
    64 
    63 text {* Note: any of these goals may be solved with a single
    65 text {* basic simplifications *}
    64  stroke of the auto or force proof method. *};
    66 
       
    67 lemma "x (| x = m, y = n, ... = p |) = m"
       
    68   by simp
       
    69 
       
    70 lemma "(| x = m, y = n, ... = p |) (| x:= 0 |) = (| x = 0, y = n, ... = p |)"
       
    71   by simp
    65 
    72 
    66 
    73 
    67 text {* basic simplifications *};
    74 text {* splitting quantifiers: the !!r is NECESSARY here *}
    68 
    75 
    69 lemma "x (| x = m, y = n, ... = p |) = m";
    76 lemma "!!r. r (| x := n |) (| y := m |) = r (| y := m |) (| x := n |)"
    70   by simp;
    77 proof record_split
       
    78   fix x y more
       
    79   show "(| x = x, y = y, ... = more |)(| x := n, y := m |) =
       
    80         (| x = x, y = y, ... = more |)(| y := m, x := n |)"
       
    81     by simp
       
    82 qed
    71 
    83 
    72 lemma "(| x = m, y = n, ... = p |) (| x:= 0 |) = (| x = 0, y = n, ... = p |)";
    84 lemma "!!r. r (| x := n |) (| x := m |) = r (| x := m |)"
    73   by simp;
    85 proof record_split
       
    86   fix x y more
       
    87   show "(| x = x, y = y, ... = more |)(| x := n, x := m |) =
       
    88         (| x = x, y = y, ... = more |)(| x := m |)"
       
    89     by simp
       
    90 qed
    74 
    91 
    75 
    92 
    76 text {* splitting quantifiers: the !!r is NECESSARY *};
    93 text {* equality of records *}
    77 
    94 
    78 lemma "!!r. r (| x := n |) (| y := m |) = r (| y := m |) (| x := n |)";
    95 lemma "(| x = n, y = p |) = (| x = n', y = p' |) ==> n = n'"
    79 proof record_split;
    96   by simp
    80   fix a b rest;
       
    81   show "(| x = a, y = b, ... = rest |)(| x := n, y := m |) =
       
    82         (| x = a, y = b, ... = rest |)(| y := m, x := n |)";
       
    83     by simp;
       
    84 qed;
       
    85 
       
    86 lemma "!!r. r (| x := n |) (| x := m |) = r (| x := m |)";
       
    87 proof record_split;
       
    88   fix a b rest;
       
    89   show "(| x = a, y = b, ... = rest |)(| x := n, x := m |) =
       
    90         (| x = a, y = b, ... = rest |)(| x := m |)";
       
    91     by simp;
       
    92 qed;
       
    93 
    97 
    94 
    98 
    95 text {* equality of records *};
    99 text {* concrete records are type instances of record schemes *}
    96 
       
    97 lemma "(| x = n, y = p |) = (| x = n', y = p' |) --> n = n'" (is "?EQ --> _");
       
    98 proof;
       
    99   assume ?EQ;
       
   100   thus "n = n'"; by simp;
       
   101 qed;
       
   102 
       
   103 
       
   104 text {* concrete records are type instances of record schemes *};
       
   105 
   100 
   106 constdefs
   101 constdefs
   107   foo5 :: nat
   102   foo5 :: nat
   108   "foo5 == getX (| x = 1, y = 0 |)";
   103   "foo5 == getX (| x = 1, y = 0 |)"
   109 
   104 
   110 
   105 
   111 text {* manipulating the `...' (more) part *};
   106 text {* manipulating the `...' (more) part *}
   112 
   107 
   113 constdefs
   108 constdefs
   114   incX :: "('a::more) point_scheme => 'a point_scheme"
   109   incX :: "('a::more) point_scheme => 'a point_scheme"
   115   "incX r == (| x = Suc (x r), y = y r, ... = point.more r |)";
   110   "incX r == (| x = Suc (x r), y = y r, ... = point.more r |)"
   116 
   111 
   117 lemma "!!r n. incX r = setX r (Suc (getX r))";
   112 lemma "!!r n. incX r = setX r (Suc (getX r))"
   118 proof (unfold getX_def setX_def incX_def);
   113 proof (unfold getX_def setX_def incX_def)
   119   show "!! r n. (| x = Suc (x r), y = y r, ... = more r |) = r(| x := Suc (x r) |)";
   114   show "!! r n. (| x = Suc (x r), y = y r, ... = more r |) = r(| x := Suc (x r) |)"
   120     by (record_split, simp);
   115     by record_split simp
   121 qed;
   116 qed
   122 
   117 
   123 
   118 
   124 text {* alternative definition *};
   119 text {* alternative definition *}
   125 
   120 
   126 constdefs
   121 constdefs
   127   incX' :: "('a::more) point_scheme => 'a point_scheme"
   122   incX' :: "('a::more) point_scheme => 'a point_scheme"
   128   "incX' r == r (| x := Suc (x r) |)";
   123   "incX' r == r (| x := Suc (x r) |)"
   129 
   124 
   130 
   125 
   131 
   126 
   132 section {* coloured points: record extension *};
   127 section {* coloured points: record extension *}
   133 
   128 
   134 datatype colour = Red | Green | Blue;
   129 datatype colour = Red | Green | Blue
   135 
   130 
   136 record cpoint = point +
   131 record cpoint = point +
   137   colour :: colour;
   132   colour :: colour
   138 
   133 
   139 
   134 
   140 text {*
   135 text {*
   141   The record declaration defines new type constructors:
   136   The record declaration defines new type constructors:
   142 
   137 
   143     cpoint = (| x :: nat, y :: nat, colour :: colour |)
   138     cpoint = (| x :: nat, y :: nat, colour :: colour |)
   144     'a cpoint_scheme = (| x :: nat, y :: nat, colour :: colour, ... :: 'a |)
   139     'a cpoint_scheme = (| x :: nat, y :: nat, colour :: colour, ... :: 'a |)
   145 *};
   140 *}
   146 
   141 
   147 consts foo6 :: cpoint;
   142 consts foo6 :: cpoint
   148 consts foo7 :: "(| x :: nat, y :: nat, colour :: colour |)";
   143 consts foo7 :: "(| x :: nat, y :: nat, colour :: colour |)"
   149 consts foo8 :: "('a::more) cpoint_scheme";
   144 consts foo8 :: "('a::more) cpoint_scheme"
   150 consts foo9 :: "(| x :: nat, y :: nat, colour :: colour, ... :: 'a |)";
   145 consts foo9 :: "(| x :: nat, y :: nat, colour :: colour, ... :: 'a |)"
   151 
   146 
   152 
   147 
   153 text {* functions on point schemes work for cpoints as well *};
   148 text {* functions on point schemes work for cpoints as well *}
   154 
   149 
   155 constdefs
   150 constdefs
   156   foo10 :: nat
   151   foo10 :: nat
   157   "foo10 == getX (| x = 2, y = 0, colour = Blue |)";
   152   "foo10 == getX (| x = 2, y = 0, colour = Blue |)"
   158 
   153 
   159 
   154 
   160 subsection {* Non-coercive structural subtyping *};
   155 subsection {* Non-coercive structural subtyping *}
   161 
   156 
   162 text {* foo11 has type cpoint, not type point --- Great! *};
   157 text {* foo11 has type cpoint, not type point --- Great! *}
   163 
   158 
   164 constdefs
   159 constdefs
   165   foo11 :: cpoint
   160   foo11 :: cpoint
   166   "foo11 == setX (| x = 2, y = 0, colour = Blue |) 0";
   161   "foo11 == setX (| x = 2, y = 0, colour = Blue |) 0"
   167 
   162 
   168 
   163 
   169 
   164 
   170 section {* Other features *};
   165 section {* Other features *}
   171 
   166 
   172 text {* field names contribute to record identity *};
   167 text {* field names contribute to record identity *}
   173 
   168 
   174 record point' =
   169 record point' =
   175   x' :: nat
   170   x' :: nat
   176   y' :: nat;
   171   y' :: nat
   177 
   172 
   178 consts
   173 consts
   179   foo12 :: nat;
   174   foo12 :: nat
   180 
   175 
   181 text {* Definition @{term "foo12 == getX (| x' = 2, y' = 0 |)"} is invalid *};
   176 text {* Definition @{term "foo12 == getX (| x' = 2, y' = 0 |)"} is invalid *}
   182 
   177 
   183 
   178 
   184 text {* polymorphic records *};
   179 text {* polymorphic records *}
   185 
   180 
   186 record 'a point'' = point +
   181 record 'a point'' = point +
   187   content :: 'a;
   182   content :: 'a
   188 
   183 
   189 types cpoint'' = "colour point''";
   184 types cpoint'' = "colour point''"
   190 
   185 
   191 
   186 end
   192 text {* Have a lot of fun! *};
       
   193 
       
   194 end;