doc-src/TutorialI/Types/Typedefs.thy
author wenzelm
Sun, 21 Oct 2001 19:35:40 +0200
changeset 11858 ca128c9100b6
child 11901 e1aa90e4ef4e
permissions -rw-r--r--
renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11858
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     1
(*<*)theory Typedefs = Main:(*>*)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     2
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     3
section{*Introducing New Types*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     4
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     5
text{*\label{sec:adv-typedef}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     6
For most applications, a combination of predefined types like @{typ bool} and
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     7
@{text"\<Rightarrow>"} with recursive datatypes and records is quite sufficient. Very
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     8
occasionally you may feel the need for a more advanced type.  If you
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
     9
are certain that your type is not definable by any of the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    10
standard means, then read on.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    11
\begin{warn}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    12
  Types in HOL must be non-empty; otherwise the quantifier rules would be
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    13
  unsound, because $\exists x.\ x=x$ is a theorem.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    14
\end{warn}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    15
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    16
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    17
subsection{*Declaring New Types*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    18
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    19
text{*\label{sec:typedecl}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    20
\index{types!declaring|(}%
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    21
\index{typedecl@\isacommand {typedecl} (command)}%
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    22
The most trivial way of introducing a new type is by a \textbf{type
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    23
declaration}: *}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    24
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    25
typedecl my_new_type
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    26
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    27
text{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    28
This does not define @{typ my_new_type} at all but merely introduces its
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    29
name. Thus we know nothing about this type, except that it is
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    30
non-empty. Such declarations without definitions are
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    31
useful if that type can be viewed as a parameter of the theory.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    32
A typical example is given in \S\ref{sec:VMC}, where we define a transition
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    33
relation over an arbitrary type of states.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    34
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    35
In principle we can always get rid of such type declarations by making those
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    36
types parameters of every other type, thus keeping the theory generic. In
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    37
practice, however, the resulting clutter can make types hard to read.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    38
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    39
If you are looking for a quick and dirty way of introducing a new type
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    40
together with its properties: declare the type and state its properties as
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    41
axioms. Example:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    42
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    43
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    44
axioms
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    45
just_one: "\<exists>x::my_new_type. \<forall>y. x = y"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    46
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    47
text{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    48
However, we strongly discourage this approach, except at explorative stages
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    49
of your development. It is extremely easy to write down contradictory sets of
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    50
axioms, in which case you will be able to prove everything but it will mean
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    51
nothing.  In the example above, the axiomatic approach is
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    52
unnecessary: a one-element type called @{typ unit} is already defined in HOL.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    53
\index{types!declaring|)}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    54
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    55
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    56
subsection{*Defining New Types*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    57
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    58
text{*\label{sec:typedef}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    59
\index{types!defining|(}%
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    60
\index{typedecl@\isacommand {typedef} (command)|(}%
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    61
Now we come to the most general means of safely introducing a new type, the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    62
\textbf{type definition}. All other means, for example
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    63
\isacommand{datatype}, are based on it. The principle is extremely simple:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    64
any non-empty subset of an existing type can be turned into a new type.  Thus
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    65
a type definition is merely a notational device: you introduce a new name for
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    66
a subset of an existing type. This does not add any logical power to HOL,
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    67
because you could base all your work directly on the subset of the existing
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    68
type. However, the resulting theories could easily become indigestible
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    69
because instead of implicit types you would have explicit sets in your
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    70
formulae.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    71
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    72
Let us work a simple example, the definition of a three-element type.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    73
It is easily represented by the first three natural numbers:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    74
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    75
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    76
typedef three = "{n::nat. n \<le> 2}"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    77
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    78
txt{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    79
In order to enforce that the representing set on the right-hand side is
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    80
non-empty, this definition actually starts a proof to that effect:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    81
@{subgoals[display,indent=0]}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    82
Fortunately, this is easy enough to show: take 0 as a witness.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    83
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    84
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    85
apply(rule_tac x = 0 in exI)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    86
by simp
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    87
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    88
text{*
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    89
This type definition introduces the new type @{typ three} and asserts
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    90
that it is a copy of the set @{term"{0,1,2}"}. This assertion
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    91
is expressed via a bijection between the \emph{type} @{typ three} and the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    92
\emph{set} @{term"{0,1,2}"}. To this end, the command declares the following
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    93
constants behind the scenes:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    94
\begin{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    95
\begin{tabular}{rcl}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    96
@{term three} &::& @{typ"nat set"} \\
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    97
@{term Rep_three} &::& @{typ"three \<Rightarrow> nat"}\\
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    98
@{term Abs_three} &::& @{typ"nat \<Rightarrow> three"}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
    99
\end{tabular}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   100
\end{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   101
where constant @{term three} is explicitly defined as the representing set:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   102
\begin{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   103
@{thm three_def}\hfill(@{thm[source]three_def})
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   104
\end{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   105
The situation is best summarized with the help of the following diagram,
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   106
where squares are types and circles are sets:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   107
\begin{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   108
\unitlength1mm
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   109
\thicklines
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   110
\begin{picture}(100,40)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   111
\put(3,13){\framebox(15,15){@{typ three}}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   112
\put(55,5){\framebox(30,30){@{term three}}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   113
\put(70,32){\makebox(0,0){@{typ nat}}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   114
\put(70,20){\circle{40}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   115
\put(10,15){\vector(1,0){60}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   116
\put(25,14){\makebox(0,0)[tl]{@{term Rep_three}}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   117
\put(70,25){\vector(-1,0){60}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   118
\put(25,26){\makebox(0,0)[bl]{@{term Abs_three}}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   119
\end{picture}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   120
\end{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   121
Finally, \isacommand{typedef} asserts that @{term Rep_three} is
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   122
surjective on the subset @{term three} and @{term Abs_three} and @{term
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   123
Rep_three} are inverses of each other:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   124
\begin{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   125
\begin{tabular}{@ {}r@ {\qquad\qquad}l@ {}}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   126
@{thm Rep_three[no_vars]} & (@{thm[source]Rep_three}) \\
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   127
@{thm Rep_three_inverse[no_vars]} & (@{thm[source]Rep_three_inverse}) \\
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   128
@{thm Abs_three_inverse[no_vars]} & (@{thm[source]Abs_three_inverse})
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   129
\end{tabular}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   130
\end{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   131
%
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   132
From this example it should be clear what \isacommand{typedef} does
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   133
in general given a name (here @{text three}) and a set
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   134
(here @{term"{n. n\<le>2}"}).
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   135
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   136
Our next step is to define the basic functions expected on the new type.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   137
Although this depends on the type at hand, the following strategy works well:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   138
\begin{itemize}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   139
\item define a small kernel of basic functions that can express all other
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   140
functions you anticipate.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   141
\item define the kernel in terms of corresponding functions on the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   142
representing type using @{term Abs} and @{term Rep} to convert between the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   143
two levels.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   144
\end{itemize}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   145
In our example it suffices to give the three elements of type @{typ three}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   146
names:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   147
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   148
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   149
constdefs
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   150
  A:: three
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   151
 "A \<equiv> Abs_three 0"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   152
  B:: three
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   153
 "B \<equiv> Abs_three 1"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   154
  C :: three
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   155
 "C \<equiv> Abs_three 2"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   156
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   157
text{*
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   158
So far, everything was easy. But it is clear that reasoning about @{typ
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   159
three} will be hell if we have to go back to @{typ nat} every time. Thus our
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   160
aim must be to raise our level of abstraction by deriving enough theorems
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   161
about type @{typ three} to characterize it completely. And those theorems
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   162
should be phrased in terms of @{term A}, @{term B} and @{term C}, not @{term
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   163
Abs_three} and @{term Rep_three}. Because of the simplicity of the example,
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   164
we merely need to prove that @{term A}, @{term B} and @{term C} are distinct
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   165
and that they exhaust the type.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   166
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   167
In processing our \isacommand{typedef} declaration, 
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   168
Isabelle helpfully proves several lemmas.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   169
One, @{thm[source]Abs_three_inject},
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   170
expresses that @{term Abs_three} is injective on the representing subset:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   171
\begin{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   172
@{thm Abs_three_inject[no_vars]}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   173
\end{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   174
Another, @{thm[source]Rep_three_inject}, expresses that the representation
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   175
function is also injective:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   176
\begin{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   177
@{thm Rep_three_inject[no_vars]}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   178
\end{center}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   179
Distinctness of @{term A}, @{term B} and @{term C} follows immediately
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   180
if we expand their definitions and rewrite with the injectivity
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   181
of @{term Abs_three}:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   182
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   183
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   184
lemma "A \<noteq> B \<and> B \<noteq> A \<and> A \<noteq> C \<and> C \<noteq> A \<and> B \<noteq> C \<and> C \<noteq> B"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   185
by(simp add: Abs_three_inject A_def B_def C_def three_def)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   186
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   187
text{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   188
Of course we rely on the simplifier to solve goals like @{prop"0 \<noteq> 1"}.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   189
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   190
The fact that @{term A}, @{term B} and @{term C} exhaust type @{typ three} is
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   191
best phrased as a case distinction theorem: if you want to prove @{prop"P x"}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   192
(where @{term x} is of type @{typ three}) it suffices to prove @{prop"P A"},
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   193
@{prop"P B"} and @{prop"P C"}. First we prove the analogous proposition for the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   194
representation: *}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   195
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   196
lemma cases_lemma: "\<lbrakk> Q 0; Q 1; Q 2; n \<in> three \<rbrakk> \<Longrightarrow>  Q n"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   197
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   198
txt{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   199
Expanding @{thm[source]three_def} yields the premise @{prop"n\<le>2"}. Repeated
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   200
elimination with @{thm[source]le_SucE}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   201
@{thm[display]le_SucE}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   202
reduces @{prop"n\<le>2"} to the three cases @{prop"n\<le>0"}, @{prop"n=1"} and
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   203
@{prop"n=2"} which are trivial for simplification:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   204
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   205
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   206
apply(simp add: three_def numerals)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   207
apply((erule le_SucE)+)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   208
apply simp_all
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   209
done
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   210
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   211
text{*
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   212
Now the case distinction lemma on type @{typ three} is easy to derive if you 
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   213
know how:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   214
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   215
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   216
lemma three_cases: "\<lbrakk> P A; P B; P C \<rbrakk> \<Longrightarrow> P x"
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   217
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   218
txt{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   219
We start by replacing the @{term x} by @{term"Abs_three(Rep_three x)"}:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   220
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   221
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   222
apply(rule subst[OF Rep_three_inverse])
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   223
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   224
txt{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   225
This substitution step worked nicely because there was just a single
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   226
occurrence of a term of type @{typ three}, namely @{term x}.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   227
When we now apply @{thm[source]cases_lemma}, @{term Q} becomes @{term"\<lambda>n. P(Abs_three
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   228
n)"} because @{term"Rep_three x"} is the only term of type @{typ nat}:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   229
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   230
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   231
apply(rule cases_lemma)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   232
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   233
txt{*
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   234
@{subgoals[display,indent=0]}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   235
The resulting subgoals are easily solved by simplification:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   236
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   237
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   238
apply(simp_all add:A_def B_def C_def Rep_three)
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   239
done
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   240
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   241
text{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   242
This concludes the derivation of the characteristic theorems for
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   243
type @{typ three}.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   244
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   245
The attentive reader has realized long ago that the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   246
above lengthy definition can be collapsed into one line:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   247
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   248
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   249
datatype three' = A | B | C
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   250
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   251
text{*\noindent
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   252
In fact, the \isacommand{datatype} command performs internally more or less
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   253
the same derivations as we did, which gives you some idea what life would be
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   254
like without \isacommand{datatype}.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   255
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   256
Although @{typ three} could be defined in one line, we have chosen this
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   257
example to demonstrate \isacommand{typedef} because its simplicity makes the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   258
key concepts particularly easy to grasp. If you would like to see a
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   259
non-trivial example that cannot be defined more directly, we recommend the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   260
definition of \emph{finite multisets} in the HOL Library.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   261
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   262
Let us conclude by summarizing the above procedure for defining a new type.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   263
Given some abstract axiomatic description $P$ of a type $ty$ in terms of a
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   264
set of functions $F$, this involves three steps:
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   265
\begin{enumerate}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   266
\item Find an appropriate type $\tau$ and subset $A$ which has the desired
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   267
  properties $P$, and make a type definition based on this representation.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   268
\item Define the required functions $F$ on $ty$ by lifting
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   269
analogous functions on the representation via $Abs_ty$ and $Rep_ty$.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   270
\item Prove that $P$ holds for $ty$ by lifting $P$ from the representation.
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   271
\end{enumerate}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   272
You can now forget about the representation and work solely in terms of the
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   273
abstract functions $F$ and properties $P$.%
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   274
\index{typedecl@\isacommand {typedef} (command)|)}%
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   275
\index{types!defining|)}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   276
*}
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   277
ca128c9100b6 renamed Typedef.thy to Typedefs.thy (former already present in main HOL);
wenzelm
parents:
diff changeset
   278
(*<*)end(*>*)