src/HOL/ex/Points.thy
author wenzelm
Fri, 23 Oct 1998 20:28:33 +0200
changeset 5753 c90b5f7d0c61
parent 5741 139a25a1e01e
child 6737 03f0ff7ee029
permissions -rw-r--r--
tuned;

(*  Title:      HOL/ex/Points.thy
    ID:         $Id$
    Author:     Wolfgang Naraschewski and Markus Wenzel, TU Muenchen

Basic use of extensible records in HOL, including the famous points
and coloured points.
*)

Points = Main +


(** points **)

record point =
  x :: nat
  y :: nat

(*
  To find out, which theorems are produced by the record declaration,
  type the following commands:

    thms "point.simps";
    thms "point.iffs";
    thms "point.update_defs";

  The set of theorems "point.simps" is added automatically to the
  standard simpset, "point.iffs" is added to the claset and simpset.
*)


(*
  Record declarations define new type abbreviations:

    point = (| x :: nat, y :: nat |)
    'a point_scheme = (| x :: nat, y :: nat, ... :: 'a |)

  Extensions `...' must be in type class `more'!
*)

consts foo1 :: point
consts foo2 :: "(| x :: nat, y :: nat |)"
consts foo3 :: 'a => ('a::more) point_scheme
consts foo4 :: "'a => (| x :: nat, y :: nat, ... :: 'a |)"


(* Introducing concrete records and record schemes *)

defs
  foo1_def "foo1 == (| x = 1, y = 0 |)"
  foo3_def "foo3 ext == (| x = 1, y = 0, ... = ext |)"


(* Record selection and record update *)

constdefs
  getX :: ('a::more) point_scheme => nat
  "getX r == x r"
  setX :: ('a::more) point_scheme => nat => 'a point_scheme
  "setX r n == r (| x := n |)"


(* concrete records are type instances of record schemes *)

constdefs
  foo5 :: nat
  "foo5 == getX (| x = 1, y = 0 |)"


(* manipulating the `...' (more-part) *)

constdefs
  incX :: ('a::more) point_scheme => 'a point_scheme
  "incX r == (| x = Suc (x r), y = y r, ... = point.more r |)"

(*alternative definition*)
constdefs
  incX' :: ('a::more) point_scheme => 'a point_scheme
  "incX' r == r (| x := Suc (x r) |)"



(** coloured points: record extension **)

datatype colour = Red | Green | Blue

record cpoint = point +
  colour :: colour


(*
  The record declaration defines new type constructors:

    cpoint = (| x :: nat, y :: nat, colour :: colour |)
    'a cpoint_scheme = (| x :: nat, y :: nat, colour :: colour, ... :: 'a |)
*)

consts foo6 :: cpoint
consts foo7 :: "(| x :: nat, y :: nat, colour :: colour |)"
consts foo8 :: ('a::more) cpoint_scheme
consts foo9 :: "(| x :: nat, y :: nat, colour :: colour, ... :: 'a |)"


(* functions on point schemes work for cpoints as well *)

constdefs
  foo10 :: nat
  "foo10 == getX (| x = 2, y = 0, colour = Blue |)"


(* non-coercive structural subtyping *)

(*foo11 has type cpoint, not type point*)                       (*Great!*)
constdefs
  foo11 :: cpoint
  "foo11 == setX (| x = 2, y = 0, colour = Blue |) 0"



(** other features **)

(* field names contribute to record identity *)

record point' =
  x' :: nat
  y' :: nat

consts
  foo12 :: nat
(*"foo12 == getX (| x' = 2, y' = 0 |)"*)        (*invalid*)


(* polymorphic records *)

record 'a point'' = point +
  content :: 'a

types cpoint'' = colour point''



(*Have a lot of fun!*)

end