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