doc-src/TutorialI/Types/document/Typedef.tex
author nipkow
Fri, 30 Mar 2001 16:12:57 +0200
changeset 11235 860c65c7388a
parent 11196 bb4ede27fcb7
child 11277 a2bff98d6e5d
permissions -rw-r--r--
*** empty log message ***
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
     1
%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
     2
\begin{isabellebody}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
     3
\def\isabellecontext{Typedef}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
     4
%
10878
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
     5
\isamarkupsection{Introducing New Types%
10397
e2d0dda41f2c auto update
paulson
parents: 10396
diff changeset
     6
}
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
     7
%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
     8
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
     9
\label{sec:adv-typedef}
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    10
For most applications, a combination of predefined types like \isa{bool} and
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    11
\isa{{\isasymRightarrow}} with recursive datatypes and records is quite sufficient. Very
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    12
occasionally you may feel the need for a more advanced type. If you cannot do
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    13
without that type, and you are certain that it is not definable by any of the
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    14
standard means, then read on.
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    15
\begin{warn}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    16
  Types in HOL must be non-empty; otherwise the quantifier rules would be
10420
ef006735bee8 *** empty log message ***
nipkow
parents: 10397
diff changeset
    17
  unsound, because $\exists x.\ x=x$ is a theorem.
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    18
\end{warn}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    19
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    20
%
10878
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
    21
\isamarkupsubsection{Declaring New Types%
10397
e2d0dda41f2c auto update
paulson
parents: 10396
diff changeset
    22
}
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    23
%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    24
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    25
\label{sec:typedecl}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    26
The most trivial way of introducing a new type is by a \bfindex{type
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    27
declaration}:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    28
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    29
\isacommand{typedecl}\ my{\isacharunderscore}new{\isacharunderscore}type%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    30
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    31
\noindent\indexbold{*typedecl}%
10420
ef006735bee8 *** empty log message ***
nipkow
parents: 10397
diff changeset
    32
This does not define \isa{my{\isacharunderscore}new{\isacharunderscore}type} at all but merely introduces its
ef006735bee8 *** empty log message ***
nipkow
parents: 10397
diff changeset
    33
name. Thus we know nothing about this type, except that it is
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    34
non-empty. Such declarations without definitions are
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    35
useful only if that type can be viewed as a parameter of a theory and we do
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    36
not intend to impose any restrictions on it. A typical example is given in
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    37
\S\ref{sec:VMC}, where we define transition relations over an arbitrary type
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    38
of states without any internal structure.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    39
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    40
In principle we can always get rid of such type declarations by making those
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    41
types parameters of every other type, thus keeping the theory generic. In
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    42
practice, however, the resulting clutter can make types hard to read.
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    43
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    44
If you are looking for a quick and dirty way of introducing a new type
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    45
together with its properties: declare the type and state its properties as
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    46
axioms. Example:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    47
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    48
\isacommand{axioms}\isanewline
10420
ef006735bee8 *** empty log message ***
nipkow
parents: 10397
diff changeset
    49
just{\isacharunderscore}one{\isacharcolon}\ {\isachardoublequote}{\isasymexists}x{\isacharcolon}{\isacharcolon}my{\isacharunderscore}new{\isacharunderscore}type{\isachardot}\ {\isasymforall}y{\isachardot}\ x\ {\isacharequal}\ y{\isachardoublequote}%
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    50
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    51
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    52
However, we strongly discourage this approach, except at explorative stages
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    53
of your development. It is extremely easy to write down contradictory sets of
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    54
axioms, in which case you will be able to prove everything but it will mean
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    55
nothing.  In the example above, the axiomatic approach is
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    56
unnecessary: a one-element type called \isa{unit} is already defined in HOL.%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    57
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    58
%
10878
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
    59
\isamarkupsubsection{Defining New Types%
10397
e2d0dda41f2c auto update
paulson
parents: 10396
diff changeset
    60
}
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    61
%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    62
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    63
\label{sec:typedef}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    64
Now we come to the most general method of safely introducing a new type, the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    65
\bfindex{type definition}. All other methods, for example
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    66
\isacommand{datatype}, are based on it. The principle is extremely simple:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    67
any non-empty subset of an existing type can be turned into a new type.  Thus
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    68
a type definition is merely a notational device: you introduce a new name for
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    69
a subset of an existing type. This does not add any logical power to HOL,
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    70
because you could base all your work directly on the subset of the existing
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    71
type. However, the resulting theories could easily become indigestible
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    72
because instead of implicit types you would have explicit sets in your
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    73
formulae.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    74
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    75
Let us work a simple example, the definition of a three-element type.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    76
It is easily represented by the first three natural numbers:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    77
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    78
\isacommand{typedef}\ three\ {\isacharequal}\ {\isachardoublequote}{\isacharbraceleft}n{\isachardot}\ n\ {\isasymle}\ {\isadigit{2}}{\isacharbraceright}{\isachardoublequote}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    79
\begin{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    80
\noindent\indexbold{*typedef}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    81
In order to enforce that the representing set on the right-hand side is
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    82
non-empty, this definition actually starts a proof to that effect:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    83
\begin{isabelle}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    84
\ {\isadigit{1}}{\isachardot}\ {\isasymexists}x{\isachardot}\ x\ {\isasymin}\ {\isacharbraceleft}n{\isachardot}\ n\ {\isasymle}\ {\isadigit{2}}{\isacharbraceright}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    85
\end{isabelle}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    86
Fortunately, this is easy enough to show: take 0 as a witness.%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    87
\end{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    88
\isacommand{apply}{\isacharparenleft}rule{\isacharunderscore}tac\ x\ {\isacharequal}\ {\isadigit{0}}\ \isakeyword{in}\ exI{\isacharparenright}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    89
\isacommand{by}\ simp%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    90
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    91
This type definition introduces the new type \isa{three} and asserts
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
    92
that it is a copy of the set \isa{{\isacharbraceleft}{\isadigit{0}}{\isacharcomma}\ {\isadigit{1}}{\isacharcomma}\ {\isadigit{2}}{\isacharbraceright}}. This assertion
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    93
is expressed via a bijection between the \emph{type} \isa{three} and the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    94
\emph{set} \isa{{\isacharbraceleft}{\isadigit{0}}{\isacharcomma}\ {\isadigit{1}}{\isacharcomma}\ {\isadigit{2}}{\isacharbraceright}}. To this end, the command declares the following
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    95
constants behind the scenes:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    96
\begin{center}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    97
\begin{tabular}{rcl}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    98
\isa{three} &::& \isa{nat\ set} \\
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
    99
\isa{Rep{\isacharunderscore}three} &::& \isa{three\ {\isasymRightarrow}\ nat}\\
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   100
\isa{Abs{\isacharunderscore}three} &::& \isa{nat\ {\isasymRightarrow}\ three}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   101
\end{tabular}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   102
\end{center}
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
   103
where constant \isa{three} is explicitly defined as the representing set:
10983
59961d32b1ae *** empty log message ***
nipkow
parents: 10878
diff changeset
   104
\begin{center}
59961d32b1ae *** empty log message ***
nipkow
parents: 10878
diff changeset
   105
\isa{three\ {\isasymequiv}\ {\isacharbraceleft}n{\isachardot}\ n\ {\isasymle}\ {\isadigit{2}}{\isacharbraceright}}\hfill(\isa{three{\isacharunderscore}def})
59961d32b1ae *** empty log message ***
nipkow
parents: 10878
diff changeset
   106
\end{center}
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   107
The situation is best summarized with the help of the following diagram,
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   108
where squares are types and circles are sets:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   109
\begin{center}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   110
\unitlength1mm
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   111
\thicklines
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   112
\begin{picture}(100,40)
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   113
\put(3,13){\framebox(15,15){\isa{three}}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   114
\put(55,5){\framebox(30,30){\isa{three}}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   115
\put(70,32){\makebox(0,0){\isa{nat}}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   116
\put(70,20){\circle{40}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   117
\put(10,15){\vector(1,0){60}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   118
\put(25,14){\makebox(0,0)[tl]{\isa{Rep{\isacharunderscore}three}}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   119
\put(70,25){\vector(-1,0){60}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   120
\put(25,26){\makebox(0,0)[bl]{\isa{Abs{\isacharunderscore}three}}}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   121
\end{picture}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   122
\end{center}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   123
Finally, \isacommand{typedef} asserts that \isa{Rep{\isacharunderscore}three} is
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   124
surjective on the subset \isa{three} and \isa{Abs{\isacharunderscore}three} and \isa{Rep{\isacharunderscore}three} are inverses of each other:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   125
\begin{center}
10983
59961d32b1ae *** empty log message ***
nipkow
parents: 10878
diff changeset
   126
\begin{tabular}{@ {}r@ {\qquad\qquad}l@ {}}
59961d32b1ae *** empty log message ***
nipkow
parents: 10878
diff changeset
   127
\isa{Rep{\isacharunderscore}three\ x\ {\isasymin}\ three} & (\isa{Rep{\isacharunderscore}three}) \\
59961d32b1ae *** empty log message ***
nipkow
parents: 10878
diff changeset
   128
\isa{Abs{\isacharunderscore}three\ {\isacharparenleft}Rep{\isacharunderscore}three\ x{\isacharparenright}\ {\isacharequal}\ x} & (\isa{Rep{\isacharunderscore}three{\isacharunderscore}inverse}) \\
59961d32b1ae *** empty log message ***
nipkow
parents: 10878
diff changeset
   129
\isa{y\ {\isasymin}\ three\ {\isasymLongrightarrow}\ Rep{\isacharunderscore}three\ {\isacharparenleft}Abs{\isacharunderscore}three\ y{\isacharparenright}\ {\isacharequal}\ y} & (\isa{Abs{\isacharunderscore}three{\isacharunderscore}inverse})
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   130
\end{tabular}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   131
\end{center}
10878
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   132
%
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   133
From this example it should be clear what \isacommand{typedef} does
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   134
in general given a name (here \isa{three}) and a set
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   135
(here \isa{{\isacharbraceleft}n{\isachardot}\ n\ {\isasymle}\ {\isadigit{2}}{\isacharbraceright}}).
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   136
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   137
Our next step is to define the basic functions expected on the new type.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   138
Although this depends on the type at hand, the following strategy works well:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   139
\begin{itemize}
10878
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   140
\item define a small kernel of basic functions that can express all other
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   141
functions you anticipate.
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   142
\item define the kernel in terms of corresponding functions on the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   143
representing type using \isa{Abs} and \isa{Rep} to convert between the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   144
two levels.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   145
\end{itemize}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   146
In our example it suffices to give the three elements of type \isa{three}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   147
names:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   148
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   149
\isacommand{constdefs}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   150
\ \ A{\isacharcolon}{\isacharcolon}\ three\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   151
\ {\isachardoublequote}A\ {\isasymequiv}\ Abs{\isacharunderscore}three\ {\isadigit{0}}{\isachardoublequote}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   152
\ \ B{\isacharcolon}{\isacharcolon}\ three\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   153
\ {\isachardoublequote}B\ {\isasymequiv}\ Abs{\isacharunderscore}three\ {\isadigit{1}}{\isachardoublequote}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   154
\ \ C\ {\isacharcolon}{\isacharcolon}\ three\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   155
\ {\isachardoublequote}C\ {\isasymequiv}\ Abs{\isacharunderscore}three\ {\isadigit{2}}{\isachardoublequote}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   156
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   157
So far, everything was easy. But it is clear that reasoning about \isa{three} will be hell if we have to go back to \isa{nat} every time. Thus our
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   158
aim must be to raise our level of abstraction by deriving enough theorems
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   159
about type \isa{three} to characterize it completely. And those theorems
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   160
should be phrased in terms of \isa{A}, \isa{B} and \isa{C}, not \isa{Abs{\isacharunderscore}three} and \isa{Rep{\isacharunderscore}three}. Because of the simplicity of the example,
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   161
we merely need to prove that \isa{A}, \isa{B} and \isa{C} are distinct
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   162
and that they exhaust the type.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   163
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   164
We start with a helpful version of injectivity of \isa{Abs{\isacharunderscore}three} on the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   165
representing subset:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   166
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   167
\isacommand{lemma}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   168
\ {\isachardoublequote}{\isasymlbrakk}\ x\ {\isasymin}\ three{\isacharsemicolon}\ y\ {\isasymin}\ three\ {\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharparenleft}Abs{\isacharunderscore}three\ x\ {\isacharequal}\ Abs{\isacharunderscore}three\ y{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}x{\isacharequal}y{\isacharparenright}{\isachardoublequote}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   169
\begin{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   170
\noindent
10878
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   171
We prove each direction separately. From \isa{Abs{\isacharunderscore}three\ x\ {\isacharequal}\ Abs{\isacharunderscore}three\ y}
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   172
we use \isa{arg{\isacharunderscore}cong} to apply \isa{Rep{\isacharunderscore}three} to both sides,
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   173
deriving \begin{isabelle}%
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   174
Rep{\isacharunderscore}three\ {\isacharparenleft}Abs{\isacharunderscore}three\ x{\isacharparenright}\ {\isacharequal}\ Rep{\isacharunderscore}three\ {\isacharparenleft}Abs{\isacharunderscore}three\ y{\isacharparenright}%
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   175
\end{isabelle}
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   176
Thus we get the required \isa{x\ {\isacharequal}\ y} by simplification with \isa{Abs{\isacharunderscore}three{\isacharunderscore}inverse}. 
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   177
The other direction
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   178
is trivial by simplification:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   179
\end{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   180
\isacommand{apply}{\isacharparenleft}rule\ iffI{\isacharparenright}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   181
\ \isacommand{apply}{\isacharparenleft}drule{\isacharunderscore}tac\ f\ {\isacharequal}\ Rep{\isacharunderscore}three\ \isakeyword{in}\ arg{\isacharunderscore}cong{\isacharparenright}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   182
\ \isacommand{apply}{\isacharparenleft}simp\ add{\isacharcolon}Abs{\isacharunderscore}three{\isacharunderscore}inverse{\isacharparenright}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   183
\isacommand{by}\ simp%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   184
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   185
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   186
Analogous lemmas can be proved in the same way for arbitrary type definitions.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   187
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   188
Distinctness of \isa{A}, \isa{B} and \isa{C} follows immediately
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   189
if we expand their definitions and rewrite with the above simplification rule:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   190
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   191
\isacommand{lemma}\ {\isachardoublequote}A\ {\isasymnoteq}\ B\ {\isasymand}\ B\ {\isasymnoteq}\ A\ {\isasymand}\ A\ {\isasymnoteq}\ C\ {\isasymand}\ C\ {\isasymnoteq}\ A\ {\isasymand}\ B\ {\isasymnoteq}\ C\ {\isasymand}\ C\ {\isasymnoteq}\ B{\isachardoublequote}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   192
\isacommand{by}{\isacharparenleft}simp\ add{\isacharcolon}A{\isacharunderscore}def\ B{\isacharunderscore}def\ C{\isacharunderscore}def\ three{\isacharunderscore}def{\isacharparenright}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   193
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   194
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   195
Of course we rely on the simplifier to solve goals like \isa{{\isadigit{0}}\ {\isasymnoteq}\ {\isadigit{1}}}.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   196
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   197
The fact that \isa{A}, \isa{B} and \isa{C} exhaust type \isa{three} is
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   198
best phrased as a case distinction theorem: if you want to prove \isa{P\ x}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   199
(where \isa{x} is of type \isa{three}) it suffices to prove \isa{P\ A},
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   200
\isa{P\ B} and \isa{P\ C}. First we prove the analogous proposition for the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   201
representation:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   202
\end{isamarkuptext}%
10654
458068404143 *** empty log message ***
nipkow
parents: 10645
diff changeset
   203
\isacommand{lemma}\ cases{\isacharunderscore}lemma{\isacharcolon}\ {\isachardoublequote}{\isasymlbrakk}\ Q\ {\isadigit{0}}{\isacharsemicolon}\ Q\ {\isadigit{1}}{\isacharsemicolon}\ Q\ {\isadigit{2}}{\isacharsemicolon}\ n\ {\isacharcolon}\ three\ {\isasymrbrakk}\ {\isasymLongrightarrow}\ \ Q\ n{\isachardoublequote}%
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   204
\begin{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   205
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   206
Expanding \isa{three{\isacharunderscore}def} yields the premise \isa{n\ {\isasymle}\ {\isadigit{2}}}. Repeated
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   207
elimination with \isa{le{\isacharunderscore}SucE}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   208
\begin{isabelle}%
10777
a5a6255748c3 initial material on the Reals
paulson
parents: 10696
diff changeset
   209
{\isasymlbrakk}{\isacharquery}m\ {\isasymle}\ Suc\ {\isacharquery}n{\isacharsemicolon}\ {\isacharquery}m\ {\isasymle}\ {\isacharquery}n\ {\isasymLongrightarrow}\ {\isacharquery}R{\isacharsemicolon}\ {\isacharquery}m\ {\isacharequal}\ Suc\ {\isacharquery}n\ {\isasymLongrightarrow}\ {\isacharquery}R{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}R%
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   210
\end{isabelle}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   211
reduces \isa{n\ {\isasymle}\ {\isadigit{2}}} to the three cases \isa{n\ {\isasymle}\ {\isadigit{0}}}, \isa{n\ {\isacharequal}\ {\isadigit{1}}} and
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   212
\isa{n\ {\isacharequal}\ {\isadigit{2}}} which are trivial for simplification:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   213
\end{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   214
\isacommand{apply}{\isacharparenleft}simp\ add{\isacharcolon}three{\isacharunderscore}def{\isacharparenright}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   215
\isacommand{apply}{\isacharparenleft}{\isacharparenleft}erule\ le{\isacharunderscore}SucE{\isacharparenright}{\isacharplus}{\isacharparenright}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   216
\isacommand{apply}\ simp{\isacharunderscore}all\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   217
\isacommand{done}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   218
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   219
Now the case distinction lemma on type \isa{three} is easy to derive if you know how to:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   220
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   221
\isacommand{lemma}\ three{\isacharunderscore}cases{\isacharcolon}\ {\isachardoublequote}{\isasymlbrakk}\ P\ A{\isacharsemicolon}\ P\ B{\isacharsemicolon}\ P\ C\ {\isasymrbrakk}\ {\isasymLongrightarrow}\ P\ x{\isachardoublequote}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   222
\begin{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   223
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   224
We start by replacing the \isa{x} by \isa{Abs{\isacharunderscore}three\ {\isacharparenleft}Rep{\isacharunderscore}three\ x{\isacharparenright}}:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   225
\end{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   226
\isacommand{apply}{\isacharparenleft}rule\ subst{\isacharbrackleft}OF\ Rep{\isacharunderscore}three{\isacharunderscore}inverse{\isacharbrackright}{\isacharparenright}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   227
\begin{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   228
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   229
This substitution step worked nicely because there was just a single
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   230
occurrence of a term of type \isa{three}, namely \isa{x}.
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11149
diff changeset
   231
When we now apply \isa{cases{\isacharunderscore}lemma}, \isa{Q} becomes \isa{{\isasymlambda}n{\isachardot}\ P\ {\isacharparenleft}Abs{\isacharunderscore}three\ n{\isacharparenright}} because \isa{Rep{\isacharunderscore}three\ x} is the only term of type \isa{nat}:%
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   232
\end{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   233
\isacommand{apply}{\isacharparenleft}rule\ cases{\isacharunderscore}lemma{\isacharparenright}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   234
\begin{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   235
\begin{isabelle}%
10696
76d7f6c9a14c *** empty log message ***
nipkow
parents: 10668
diff changeset
   236
\ {\isadigit{1}}{\isachardot}\ {\isasymlbrakk}P\ A{\isacharsemicolon}\ P\ B{\isacharsemicolon}\ P\ C{\isasymrbrakk}\ {\isasymLongrightarrow}\ P\ {\isacharparenleft}Abs{\isacharunderscore}three\ {\isadigit{0}}{\isacharparenright}\isanewline
76d7f6c9a14c *** empty log message ***
nipkow
parents: 10668
diff changeset
   237
\ {\isadigit{2}}{\isachardot}\ {\isasymlbrakk}P\ A{\isacharsemicolon}\ P\ B{\isacharsemicolon}\ P\ C{\isasymrbrakk}\ {\isasymLongrightarrow}\ P\ {\isacharparenleft}Abs{\isacharunderscore}three\ {\isadigit{1}}{\isacharparenright}\isanewline
76d7f6c9a14c *** empty log message ***
nipkow
parents: 10668
diff changeset
   238
\ {\isadigit{3}}{\isachardot}\ {\isasymlbrakk}P\ A{\isacharsemicolon}\ P\ B{\isacharsemicolon}\ P\ C{\isasymrbrakk}\ {\isasymLongrightarrow}\ P\ {\isacharparenleft}Abs{\isacharunderscore}three\ {\isadigit{2}}{\isacharparenright}\isanewline
76d7f6c9a14c *** empty log message ***
nipkow
parents: 10668
diff changeset
   239
\ {\isadigit{4}}{\isachardot}\ {\isasymlbrakk}P\ A{\isacharsemicolon}\ P\ B{\isacharsemicolon}\ P\ C{\isasymrbrakk}\ {\isasymLongrightarrow}\ Rep{\isacharunderscore}three\ x\ {\isasymin}\ three%
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   240
\end{isabelle}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   241
The resulting subgoals are easily solved by simplification:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   242
\end{isamarkuptxt}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   243
\isacommand{apply}{\isacharparenleft}simp{\isacharunderscore}all\ add{\isacharcolon}A{\isacharunderscore}def\ B{\isacharunderscore}def\ C{\isacharunderscore}def\ Rep{\isacharunderscore}three{\isacharparenright}\isanewline
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   244
\isacommand{done}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   245
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   246
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   247
This concludes the derivation of the characteristic theorems for
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   248
type \isa{three}.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   249
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   250
The attentive reader has realized long ago that the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   251
above lengthy definition can be collapsed into one line:%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   252
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   253
\isacommand{datatype}\ three{\isacharprime}\ {\isacharequal}\ A\ {\isacharbar}\ B\ {\isacharbar}\ C%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   254
\begin{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   255
\noindent
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   256
In fact, the \isacommand{datatype} command performs internally more or less
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   257
the same derivations as we did, which gives you some idea what life would be
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   258
like without \isacommand{datatype}.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   259
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   260
Although \isa{three} could be defined in one line, we have chosen this
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   261
example to demonstrate \isacommand{typedef} because its simplicity makes the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   262
key concepts particularly easy to grasp. If you would like to see a
11149
e258b536a137 *** empty log message ***
nipkow
parents: 10983
diff changeset
   263
non-trivial example that cannot be defined more directly, we recommend the
10878
b254d5ad6dd4 auto update
paulson
parents: 10777
diff changeset
   264
definition of \emph{finite multisets} in the HOL Library.
10366
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   265
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   266
Let us conclude by summarizing the above procedure for defining a new type.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   267
Given some abstract axiomatic description $P$ of a type $ty$ in terms of a
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   268
set of functions $F$, this involves three steps:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   269
\begin{enumerate}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   270
\item Find an appropriate type $\tau$ and subset $A$ which has the desired
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   271
  properties $P$, and make a type definition based on this representation.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   272
\item Define the required functions $F$ on $ty$ by lifting
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   273
analogous functions on the representation via $Abs_ty$ and $Rep_ty$.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   274
\item Prove that $P$ holds for $ty$ by lifting $P$ from the representation.
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   275
\end{enumerate}
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   276
You can now forget about the representation and work solely in terms of the
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   277
abstract functions $F$ and properties $P$.%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   278
\end{isamarkuptext}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   279
\end{isabellebody}%
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   280
%%% Local Variables:
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   281
%%% mode: latex
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   282
%%% TeX-master: "root"
dd74d0a56df9 *** empty log message ***
nipkow
parents:
diff changeset
   283
%%% End: