doc-src/TutorialI/fp.tex
author paulson
Fri Jan 05 18:32:57 2001 +0100 (2001-01-05)
changeset 10795 9e888d60d3e5
parent 10654 458068404143
child 10800 2d4c058749a7
permissions -rw-r--r--
minor edits to Chapters 1-3
nipkow@8743
     1
\chapter{Functional Programming in HOL}
nipkow@8743
     2
nipkow@8743
     3
Although on the surface this chapter is mainly concerned with how to write
nipkow@8743
     4
functional programs in HOL and how to verify them, most of the
nipkow@8743
     5
constructs and proof procedures introduced are general purpose and recur in
nipkow@8743
     6
any specification or verification task.
nipkow@8743
     7
nipkow@9541
     8
The dedicated functional programmer should be warned: HOL offers only
nipkow@9541
     9
\emph{total functional programming} --- all functions in HOL must be total;
nipkow@9541
    10
lazy data structures are not directly available. On the positive side,
nipkow@9541
    11
functions in HOL need not be computable: HOL is a specification language that
nipkow@9541
    12
goes well beyond what can be expressed as a program. However, for the time
nipkow@9541
    13
being we concentrate on the computable.
nipkow@8743
    14
nipkow@8743
    15
\section{An introductory theory}
nipkow@8743
    16
\label{sec:intro-theory}
nipkow@8743
    17
nipkow@8743
    18
Functional programming needs datatypes and functions. Both of them can be
nipkow@8743
    19
defined in a theory with a syntax reminiscent of languages like ML or
nipkow@8743
    20
Haskell. As an example consider the theory in figure~\ref{fig:ToyList}.
nipkow@8743
    21
We will now examine it line by line.
nipkow@8743
    22
nipkow@8743
    23
\begin{figure}[htbp]
nipkow@8743
    24
\begin{ttbox}\makeatother
nipkow@8743
    25
\input{ToyList2/ToyList1}\end{ttbox}
nipkow@8743
    26
\caption{A theory of lists}
nipkow@8743
    27
\label{fig:ToyList}
nipkow@8743
    28
\end{figure}
nipkow@8743
    29
nipkow@8743
    30
{\makeatother\input{ToyList/document/ToyList.tex}}
nipkow@8743
    31
paulson@10795
    32
The complete proof script is shown in Fig.\ts\ref{fig:ToyList-proofs}. The
paulson@10795
    33
concatenation of Figs.\ts\ref{fig:ToyList} and~\ref{fig:ToyList-proofs}
nipkow@8743
    34
constitutes the complete theory \texttt{ToyList} and should reside in file
nipkow@8743
    35
\texttt{ToyList.thy}. It is good practice to present all declarations and
nipkow@8743
    36
definitions at the beginning of a theory to facilitate browsing.
nipkow@8743
    37
nipkow@8743
    38
\begin{figure}[htbp]
nipkow@8743
    39
\begin{ttbox}\makeatother
nipkow@8743
    40
\input{ToyList2/ToyList2}\end{ttbox}
nipkow@8743
    41
\caption{Proofs about lists}
nipkow@8743
    42
\label{fig:ToyList-proofs}
nipkow@8743
    43
\end{figure}
nipkow@8743
    44
nipkow@8743
    45
\subsubsection*{Review}
nipkow@8743
    46
nipkow@8743
    47
This is the end of our toy proof. It should have familiarized you with
nipkow@8743
    48
\begin{itemize}
nipkow@8743
    49
\item the standard theorem proving procedure:
nipkow@8743
    50
state a goal (lemma or theorem); proceed with proof until a separate lemma is
nipkow@8743
    51
required; prove that lemma; come back to the original goal.
nipkow@8743
    52
\item a specific procedure that works well for functional programs:
nipkow@8743
    53
induction followed by all-out simplification via \isa{auto}.
nipkow@8743
    54
\item a basic repertoire of proof commands.
nipkow@8743
    55
\end{itemize}
nipkow@8743
    56
nipkow@8743
    57
nipkow@8743
    58
\section{Some helpful commands}
nipkow@8743
    59
\label{sec:commands-and-hints}
nipkow@8743
    60
nipkow@8743
    61
This section discusses a few basic commands for manipulating the proof state
nipkow@8743
    62
and can be skipped by casual readers.
nipkow@8743
    63
nipkow@8743
    64
There are two kinds of commands used during a proof: the actual proof
nipkow@8743
    65
commands and auxiliary commands for examining the proof state and controlling
nipkow@8743
    66
the display. Simple proof commands are of the form
nipkow@8743
    67
\isacommand{apply}\isa{(method)}\indexbold{apply} where \bfindex{method} is a
nipkow@8743
    68
synonym for ``theorem proving function''. Typical examples are
nipkow@8743
    69
\isa{induct_tac} and \isa{auto}. Further methods are introduced throughout
nipkow@8743
    70
the tutorial.  Unless stated otherwise you may assume that a method attacks
nipkow@8743
    71
merely the first subgoal. An exception is \isa{auto} which tries to solve all
nipkow@8743
    72
subgoals.
nipkow@8743
    73
nipkow@8743
    74
The most useful auxiliary commands are:
nipkow@8743
    75
\begin{description}
nipkow@8743
    76
\item[Undoing:] \isacommand{undo}\indexbold{*undo} undoes the effect of the
nipkow@8743
    77
  last command; \isacommand{undo} can be undone by
nipkow@8743
    78
  \isacommand{redo}\indexbold{*redo}.  Both are only needed at the shell
nipkow@8743
    79
  level and should not occur in the final theory.
nipkow@8743
    80
\item[Printing the current state:] \isacommand{pr}\indexbold{*pr} redisplays
nipkow@8743
    81
  the current proof state, for example when it has disappeared off the
nipkow@8743
    82
  screen.
nipkow@8743
    83
\item[Limiting the number of subgoals:] \isacommand{pr}~$n$ tells Isabelle to
nipkow@8743
    84
  print only the first $n$ subgoals from now on and redisplays the current
nipkow@8743
    85
  proof state. This is helpful when there are many subgoals.
nipkow@8743
    86
\item[Modifying the order of subgoals:]
nipkow@8743
    87
\isacommand{defer}\indexbold{*defer} moves the first subgoal to the end and
nipkow@8743
    88
\isacommand{prefer}\indexbold{*prefer}~$n$ moves subgoal $n$ to the front.
nipkow@8743
    89
\item[Printing theorems:]
nipkow@8743
    90
  \isacommand{thm}\indexbold{*thm}~\textit{name}$@1$~\dots~\textit{name}$@n$
nipkow@8743
    91
  prints the named theorems.
nipkow@8743
    92
\item[Displaying types:] We have already mentioned the flag
nipkow@8743
    93
  \ttindex{show_types} above. It can also be useful for detecting typos in
nipkow@8743
    94
  formulae early on. For example, if \texttt{show_types} is set and the goal
nipkow@8743
    95
  \isa{rev(rev xs) = xs} is started, Isabelle prints the additional output
nipkow@8743
    96
\par\noindent
nipkow@8743
    97
\begin{isabelle}%
nipkow@8743
    98
Variables:\isanewline
nipkow@8743
    99
~~xs~::~'a~list
nipkow@8743
   100
\end{isabelle}%
nipkow@8743
   101
\par\noindent
nipkow@8743
   102
which tells us that Isabelle has correctly inferred that
nipkow@8743
   103
\isa{xs} is a variable of list type. On the other hand, had we
nipkow@8743
   104
made a typo as in \isa{rev(re xs) = xs}, the response
nipkow@8743
   105
\par\noindent
nipkow@8743
   106
\begin{isabelle}%
nipkow@8743
   107
Variables:\isanewline
nipkow@8743
   108
~~re~::~'a~list~{\isasymRightarrow}~'a~list\isanewline
nipkow@8743
   109
~~xs~::~'a~list%
nipkow@8743
   110
\end{isabelle}%
nipkow@8743
   111
\par\noindent
nipkow@8743
   112
would have alerted us because of the unexpected variable \isa{re}.
nipkow@8743
   113
\item[Reading terms and types:] \isacommand{term}\indexbold{*term}
nipkow@8743
   114
  \textit{string} reads, type-checks and prints the given string as a term in
nipkow@8743
   115
  the current context; the inferred type is output as well.
nipkow@8743
   116
  \isacommand{typ}\indexbold{*typ} \textit{string} reads and prints the given
nipkow@8743
   117
  string as a type in the current context.
nipkow@8743
   118
\item[(Re)loading theories:] When you start your interaction you must open a
nipkow@8771
   119
  named theory with the line \isa{\isacommand{theory}~T~=~\dots~:}. Isabelle
nipkow@8771
   120
  automatically loads all the required parent theories from their respective
nipkow@8771
   121
  files (which may take a moment, unless the theories are already loaded and
nipkow@9541
   122
  the files have not been modified).
nipkow@8743
   123
  
nipkow@8743
   124
  If you suddenly discover that you need to modify a parent theory of your
nipkow@9494
   125
  current theory you must first abandon your current theory\indexbold{abandon
nipkow@9494
   126
  theory}\indexbold{theory!abandon} (at the shell
nipkow@8743
   127
  level type \isacommand{kill}\indexbold{*kill}). After the parent theory has
nipkow@8743
   128
  been modified you go back to your original theory. When its first line
nipkow@8743
   129
  \isacommand{theory}\texttt{~T~=}~\dots~\texttt{:} is processed, the
nipkow@8743
   130
  modified parent is reloaded automatically.
nipkow@9541
   131
  
nipkow@9541
   132
  The only time when you need to load a theory by hand is when you simply
nipkow@9541
   133
  want to check if it loads successfully without wanting to make use of the
nipkow@9541
   134
  theory itself. This you can do by typing
nipkow@9541
   135
  \isa{\isacommand{use\_thy}\indexbold{*use_thy}~"T"}.
nipkow@8743
   136
\end{description}
nipkow@8743
   137
Further commands are found in the Isabelle/Isar Reference Manual.
nipkow@8743
   138
nipkow@8771
   139
We now examine Isabelle's functional programming constructs systematically,
nipkow@8771
   140
starting with inductive datatypes.
nipkow@8771
   141
nipkow@8743
   142
nipkow@8743
   143
\section{Datatypes}
nipkow@8743
   144
\label{sec:datatype}
nipkow@8743
   145
nipkow@8743
   146
Inductive datatypes are part of almost every non-trivial application of HOL.
nipkow@8743
   147
First we take another look at a very important example, the datatype of
nipkow@8743
   148
lists, before we turn to datatypes in general. The section closes with a
nipkow@8743
   149
case study.
nipkow@8743
   150
nipkow@8743
   151
nipkow@8743
   152
\subsection{Lists}
nipkow@8743
   153
\indexbold{*list}
nipkow@8743
   154
nipkow@8743
   155
Lists are one of the essential datatypes in computing. Readers of this
nipkow@8743
   156
tutorial and users of HOL need to be familiar with their basic operations.
nipkow@8771
   157
Theory \isa{ToyList} is only a small fragment of HOL's predefined theory
nipkow@8771
   158
\isa{List}\footnote{\url{http://isabelle.in.tum.de/library/HOL/List.html}}.
nipkow@8743
   159
The latter contains many further operations. For example, the functions
nipkow@8771
   160
\isaindexbold{hd} (``head'') and \isaindexbold{tl} (``tail'') return the first
nipkow@8743
   161
element and the remainder of a list. (However, pattern-matching is usually
paulson@10795
   162
preferable to \isa{hd} and \isa{tl}.)  
paulson@10795
   163
Also available are the higher-order
paulson@10795
   164
functions \isa{map}, \isa{filter}, \isa{foldl} and \isa{foldr}.
paulson@10795
   165
Theory \isa{List} also contains
nipkow@8743
   166
more syntactic sugar: \isa{[}$x@1$\isa{,}\dots\isa{,}$x@n$\isa{]} abbreviates
nipkow@8743
   167
$x@1$\isa{\#}\dots\isa{\#}$x@n$\isa{\#[]}.  In the rest of the tutorial we
nipkow@8743
   168
always use HOL's predefined lists.
nipkow@8743
   169
nipkow@8743
   170
nipkow@8743
   171
\subsection{The general format}
nipkow@8743
   172
\label{sec:general-datatype}
nipkow@8743
   173
nipkow@8743
   174
The general HOL \isacommand{datatype} definition is of the form
nipkow@8743
   175
\[
nipkow@8743
   176
\isacommand{datatype}~(\alpha@1, \dots, \alpha@n) \, t ~=~
nipkow@8743
   177
C@1~\tau@{11}~\dots~\tau@{1k@1} ~\mid~ \dots ~\mid~
nipkow@8743
   178
C@m~\tau@{m1}~\dots~\tau@{mk@m}
nipkow@8743
   179
\]
nipkow@8771
   180
where $\alpha@i$ are distinct type variables (the parameters), $C@i$ are distinct
nipkow@8743
   181
constructor names and $\tau@{ij}$ are types; it is customary to capitalize
nipkow@8743
   182
the first letter in constructor names. There are a number of
nipkow@8743
   183
restrictions (such as that the type should not be empty) detailed
nipkow@8743
   184
elsewhere~\cite{isabelle-HOL}. Isabelle notifies you if you violate them.
nipkow@8743
   185
nipkow@8743
   186
Laws about datatypes, such as \isa{[] \isasymnoteq~x\#xs} and
nipkow@8743
   187
\isa{(x\#xs = y\#ys) = (x=y \isasymand~xs=ys)}, are used automatically
nipkow@8743
   188
during proofs by simplification.  The same is true for the equations in
nipkow@8743
   189
primitive recursive function definitions.
nipkow@8743
   190
nipkow@9644
   191
Every datatype $t$ comes equipped with a \isa{size} function from $t$ into
nipkow@10538
   192
the natural numbers (see~{\S}\ref{sec:nat} below). For lists, \isa{size} is
nipkow@9644
   193
just the length, i.e.\ \isa{size [] = 0} and \isa{size(x \# xs) = size xs +
nipkow@10237
   194
  1}.  In general, \isaindexbold{size} returns \isa{0} for all constructors
nipkow@10237
   195
that do not have an argument of type $t$, and for all other constructors
nipkow@10237
   196
\isa{1 +} the sum of the sizes of all arguments of type $t$. Note that because
nipkow@9644
   197
\isa{size} is defined on every datatype, it is overloaded; on lists
nipkow@10237
   198
\isa{size} is also called \isaindexbold{length}, which is not overloaded.
paulson@10795
   199
Isabelle will always show \isa{size} on lists as \isa{length}.
nipkow@9644
   200
nipkow@9644
   201
nipkow@8743
   202
\subsection{Primitive recursion}
nipkow@8743
   203
nipkow@8743
   204
Functions on datatypes are usually defined by recursion. In fact, most of the
nipkow@8743
   205
time they are defined by what is called \bfindex{primitive recursion}.
nipkow@8743
   206
The keyword \isacommand{primrec}\indexbold{*primrec} is followed by a list of
nipkow@8743
   207
equations
nipkow@8743
   208
\[ f \, x@1 \, \dots \, (C \, y@1 \, \dots \, y@k)\, \dots \, x@n = r \]
nipkow@8743
   209
such that $C$ is a constructor of the datatype $t$ and all recursive calls of
nipkow@8743
   210
$f$ in $r$ are of the form $f \, \dots \, y@i \, \dots$ for some $i$. Thus
nipkow@8743
   211
Isabelle immediately sees that $f$ terminates because one (fixed!) argument
nipkow@10654
   212
becomes smaller with every recursive call. There must be at most one equation
nipkow@8743
   213
for each constructor.  Their order is immaterial.
nipkow@8771
   214
A more general method for defining total recursive functions is introduced in
nipkow@10538
   215
{\S}\ref{sec:recdef}.
nipkow@8743
   216
nipkow@9493
   217
\begin{exercise}\label{ex:Tree}
nipkow@8743
   218
\input{Misc/document/Tree.tex}%
nipkow@8743
   219
\end{exercise}
nipkow@8743
   220
nipkow@9721
   221
\input{Misc/document/case_exprs.tex}
nipkow@8743
   222
nipkow@8743
   223
\begin{warn}
nipkow@8743
   224
  Induction is only allowed on free (or \isasymAnd-bound) variables that
nipkow@9644
   225
  should not occur among the assumptions of the subgoal; see
nipkow@10538
   226
  {\S}\ref{sec:ind-var-in-prems} for details. Case distinction
nipkow@8743
   227
  (\isa{case_tac}) works for arbitrary terms, which need to be
nipkow@8743
   228
  quoted if they are non-atomic.
nipkow@8743
   229
\end{warn}
nipkow@8743
   230
nipkow@8743
   231
nipkow@8743
   232
\input{Ifexpr/document/Ifexpr.tex}
nipkow@8743
   233
nipkow@8743
   234
\section{Some basic types}
nipkow@8743
   235
nipkow@8743
   236
nipkow@8743
   237
\subsection{Natural numbers}
nipkow@9644
   238
\label{sec:nat}
nipkow@8743
   239
\index{arithmetic|(}
nipkow@8743
   240
nipkow@8743
   241
\input{Misc/document/fakenat.tex}
nipkow@8743
   242
\input{Misc/document/natsum.tex}
nipkow@8743
   243
nipkow@8743
   244
\index{arithmetic|)}
nipkow@8743
   245
nipkow@8743
   246
nipkow@10396
   247
\subsection{Pairs}
nipkow@9541
   248
\input{Misc/document/pairs.tex}
nipkow@8743
   249
nipkow@10608
   250
\subsection{Datatype {\tt\slshape option}}
nipkow@10543
   251
\label{sec:option}
nipkow@10543
   252
\input{Misc/document/Option2.tex}
nipkow@10543
   253
nipkow@8743
   254
\section{Definitions}
nipkow@8743
   255
\label{sec:Definitions}
nipkow@8743
   256
nipkow@8743
   257
A definition is simply an abbreviation, i.e.\ a new name for an existing
nipkow@8743
   258
construction. In particular, definitions cannot be recursive. Isabelle offers
nipkow@8743
   259
definitions on the level of types and terms. Those on the type level are
nipkow@8743
   260
called type synonyms, those on the term level are called (constant)
nipkow@8743
   261
definitions.
nipkow@8743
   262
nipkow@8743
   263
nipkow@8743
   264
\subsection{Type synonyms}
nipkow@8771
   265
\indexbold{type synonym}
nipkow@8743
   266
paulson@10795
   267
Type synonyms are similar to those found in ML\@. Their syntax is fairly self
nipkow@8743
   268
explanatory:
nipkow@8743
   269
nipkow@8743
   270
\input{Misc/document/types.tex}%
nipkow@8743
   271
nipkow@8743
   272
Note that pattern-matching is not allowed, i.e.\ each definition must be of
nipkow@8743
   273
the form $f\,x@1\,\dots\,x@n~\isasymequiv~t$.
nipkow@10538
   274
Section~{\S}\ref{sec:Simplification} explains how definitions are used
nipkow@8743
   275
in proofs.
nipkow@8743
   276
nipkow@9844
   277
\input{Misc/document/prime_def.tex}
nipkow@8743
   278
nipkow@8743
   279
nipkow@8743
   280
\chapter{More Functional Programming}
nipkow@8743
   281
nipkow@8743
   282
The purpose of this chapter is to deepen the reader's understanding of the
nipkow@8771
   283
concepts encountered so far and to introduce advanced forms of datatypes and
nipkow@8771
   284
recursive functions. The first two sections give a structured presentation of
nipkow@10538
   285
theorem proving by simplification ({\S}\ref{sec:Simplification}) and discuss
nipkow@10538
   286
important heuristics for induction ({\S}\ref{sec:InductionHeuristics}). They can
nipkow@8771
   287
be skipped by readers less interested in proofs. They are followed by a case
nipkow@10538
   288
study, a compiler for expressions ({\S}\ref{sec:ExprCompiler}). Advanced
nipkow@8771
   289
datatypes, including those involving function spaces, are covered in
nipkow@10538
   290
{\S}\ref{sec:advanced-datatypes}, which closes with another case study, search
nipkow@8771
   291
trees (``tries'').  Finally we introduce \isacommand{recdef}, a very general
nipkow@8771
   292
form of recursive function definition which goes well beyond what
nipkow@10538
   293
\isacommand{primrec} allows ({\S}\ref{sec:recdef}).
nipkow@8743
   294
nipkow@8743
   295
nipkow@8743
   296
\section{Simplification}
nipkow@8743
   297
\label{sec:Simplification}
nipkow@8743
   298
\index{simplification|(}
nipkow@8743
   299
paulson@10795
   300
So far we have proved our theorems by \isa{auto}, which simplifies
nipkow@9541
   301
\emph{all} subgoals. In fact, \isa{auto} can do much more than that, except
nipkow@9541
   302
that it did not need to so far. However, when you go beyond toy examples, you
nipkow@9541
   303
need to understand the ingredients of \isa{auto}.  This section covers the
nipkow@9541
   304
method that \isa{auto} always applies first, namely simplification.
nipkow@8743
   305
nipkow@8743
   306
Simplification is one of the central theorem proving tools in Isabelle and
nipkow@8743
   307
many other systems. The tool itself is called the \bfindex{simplifier}. The
nipkow@9754
   308
purpose of this section is introduce the many features of the simplifier.
nipkow@9754
   309
Anybody intending to use HOL should read this section. Later on
nipkow@10538
   310
({\S}\ref{sec:simplification-II}) we explain some more advanced features and a
nipkow@9754
   311
little bit of how the simplifier works. The serious student should read that
nipkow@9754
   312
section as well, in particular in order to understand what happened if things
nipkow@9754
   313
do not simplify as expected.
nipkow@8743
   314
nipkow@9458
   315
\subsubsection{What is simplification}
nipkow@9458
   316
nipkow@8743
   317
In its most basic form, simplification means repeated application of
nipkow@8743
   318
equations from left to right. For example, taking the rules for \isa{\at}
nipkow@8743
   319
and applying them to the term \isa{[0,1] \at\ []} results in a sequence of
nipkow@8743
   320
simplification steps:
nipkow@8743
   321
\begin{ttbox}\makeatother
nipkow@8743
   322
(0#1#[]) @ []  \(\leadsto\)  0#((1#[]) @ [])  \(\leadsto\)  0#(1#([] @ []))  \(\leadsto\)  0#1#[]
nipkow@8743
   323
\end{ttbox}
nipkow@9933
   324
This is also known as \bfindex{term rewriting}\indexbold{rewriting} and the
nipkow@9933
   325
equations are referred to as \textbf{rewrite rules}\indexbold{rewrite rule}.
nipkow@9933
   326
``Rewriting'' is more honest than ``simplification'' because the terms do not
nipkow@9933
   327
necessarily become simpler in the process.
nipkow@8743
   328
nipkow@9844
   329
\input{Misc/document/simp.tex}
nipkow@8743
   330
nipkow@8743
   331
\index{simplification|)}
nipkow@8743
   332
nipkow@9844
   333
\input{Misc/document/Itrev.tex}
nipkow@8743
   334
nipkow@9493
   335
\begin{exercise}
nipkow@9493
   336
\input{Misc/document/Tree2.tex}%
nipkow@9493
   337
\end{exercise}
nipkow@8743
   338
nipkow@9844
   339
\input{CodeGen/document/CodeGen.tex}
nipkow@8743
   340
nipkow@8743
   341
nipkow@8743
   342
\section{Advanced datatypes}
nipkow@8743
   343
\label{sec:advanced-datatypes}
nipkow@8743
   344
\index{*datatype|(}
nipkow@8743
   345
\index{*primrec|(}
nipkow@8743
   346
%|)
nipkow@8743
   347
nipkow@8743
   348
This section presents advanced forms of \isacommand{datatype}s.
nipkow@8743
   349
nipkow@8743
   350
\subsection{Mutual recursion}
nipkow@8743
   351
\label{sec:datatype-mut-rec}
nipkow@8743
   352
nipkow@8743
   353
\input{Datatype/document/ABexpr.tex}
nipkow@8743
   354
nipkow@8743
   355
\subsection{Nested recursion}
nipkow@9644
   356
\label{sec:nested-datatype}
nipkow@8743
   357
nipkow@9644
   358
{\makeatother\input{Datatype/document/Nested.tex}}
nipkow@8743
   359
nipkow@8743
   360
nipkow@8743
   361
\subsection{The limits of nested recursion}
nipkow@8743
   362
nipkow@8743
   363
How far can we push nested recursion? By the unfolding argument above, we can
nipkow@8743
   364
reduce nested to mutual recursion provided the nested recursion only involves
nipkow@8743
   365
previously defined datatypes. This does not include functions:
nipkow@9792
   366
\begin{isabelle}
nipkow@9792
   367
\isacommand{datatype} t = C "t \isasymRightarrow\ bool"
nipkow@9792
   368
\end{isabelle}
paulson@10795
   369
This declaration is a real can of worms.
paulson@10795
   370
In HOL it must be ruled out because it requires a type
nipkow@8743
   371
\isa{t} such that \isa{t} and its power set \isa{t \isasymFun\ bool} have the
nipkow@8743
   372
same cardinality---an impossibility. For the same reason it is not possible
nipkow@8743
   373
to allow recursion involving the type \isa{set}, which is isomorphic to
nipkow@8743
   374
\isa{t \isasymFun\ bool}.
nipkow@8743
   375
nipkow@8743
   376
Fortunately, a limited form of recursion
nipkow@8743
   377
involving function spaces is permitted: the recursive type may occur on the
nipkow@8743
   378
right of a function arrow, but never on the left. Hence the above can of worms
nipkow@8743
   379
is ruled out but the following example of a potentially infinitely branching tree is
nipkow@8743
   380
accepted:
nipkow@8771
   381
\smallskip
nipkow@8743
   382
nipkow@8743
   383
\input{Datatype/document/Fundata.tex}
nipkow@8743
   384
\bigskip
nipkow@8743
   385
nipkow@9792
   386
If you need nested recursion on the left of a function arrow, there are
nipkow@9792
   387
alternatives to pure HOL: LCF~\cite{paulson87} is a logic where types like
nipkow@9792
   388
\begin{isabelle}
nipkow@9792
   389
\isacommand{datatype} lam = C "lam \isasymrightarrow\ lam"
nipkow@9792
   390
\end{isabelle}
paulson@10795
   391
do indeed make sense.  Note the different arrow,
paulson@10795
   392
\isa{\isasymrightarrow} instead of \isa{\isasymRightarrow},
paulson@10795
   393
expressing the type of \textbf{continuous} functions. 
paulson@10795
   394
There is even a version of LCF on top of HOL,
nipkow@9792
   395
called HOLCF~\cite{MuellerNvOS99}.
nipkow@8743
   396
nipkow@8743
   397
\index{*primrec|)}
nipkow@8743
   398
\index{*datatype|)}
nipkow@8743
   399
nipkow@8743
   400
\subsection{Case study: Tries}
nipkow@10543
   401
\label{sec:Trie}
nipkow@8743
   402
nipkow@8743
   403
Tries are a classic search tree data structure~\cite{Knuth3-75} for fast
nipkow@8743
   404
indexing with strings. Figure~\ref{fig:trie} gives a graphical example of a
nipkow@8743
   405
trie containing the words ``all'', ``an'', ``ape'', ``can'', ``car'' and
nipkow@8743
   406
``cat''.  When searching a string in a trie, the letters of the string are
nipkow@8743
   407
examined sequentially. Each letter determines which subtrie to search next.
nipkow@8743
   408
In this case study we model tries as a datatype, define a lookup and an
nipkow@8743
   409
update function, and prove that they behave as expected.
nipkow@8743
   410
nipkow@8743
   411
\begin{figure}[htbp]
nipkow@8743
   412
\begin{center}
nipkow@8743
   413
\unitlength1mm
nipkow@8743
   414
\begin{picture}(60,30)
nipkow@8743
   415
\put( 5, 0){\makebox(0,0)[b]{l}}
nipkow@8743
   416
\put(25, 0){\makebox(0,0)[b]{e}}
nipkow@8743
   417
\put(35, 0){\makebox(0,0)[b]{n}}
nipkow@8743
   418
\put(45, 0){\makebox(0,0)[b]{r}}
nipkow@8743
   419
\put(55, 0){\makebox(0,0)[b]{t}}
nipkow@8743
   420
%
nipkow@8743
   421
\put( 5, 9){\line(0,-1){5}}
nipkow@8743
   422
\put(25, 9){\line(0,-1){5}}
nipkow@8743
   423
\put(44, 9){\line(-3,-2){9}}
nipkow@8743
   424
\put(45, 9){\line(0,-1){5}}
nipkow@8743
   425
\put(46, 9){\line(3,-2){9}}
nipkow@8743
   426
%
nipkow@8743
   427
\put( 5,10){\makebox(0,0)[b]{l}}
nipkow@8743
   428
\put(15,10){\makebox(0,0)[b]{n}}
nipkow@8743
   429
\put(25,10){\makebox(0,0)[b]{p}}
nipkow@8743
   430
\put(45,10){\makebox(0,0)[b]{a}}
nipkow@8743
   431
%
nipkow@8743
   432
\put(14,19){\line(-3,-2){9}}
nipkow@8743
   433
\put(15,19){\line(0,-1){5}}
nipkow@8743
   434
\put(16,19){\line(3,-2){9}}
nipkow@8743
   435
\put(45,19){\line(0,-1){5}}
nipkow@8743
   436
%
nipkow@8743
   437
\put(15,20){\makebox(0,0)[b]{a}}
nipkow@8743
   438
\put(45,20){\makebox(0,0)[b]{c}}
nipkow@8743
   439
%
nipkow@8743
   440
\put(30,30){\line(-3,-2){13}}
nipkow@8743
   441
\put(30,30){\line(3,-2){13}}
nipkow@8743
   442
\end{picture}
nipkow@8743
   443
\end{center}
nipkow@8743
   444
\caption{A sample trie}
nipkow@8743
   445
\label{fig:trie}
nipkow@8743
   446
\end{figure}
nipkow@8743
   447
nipkow@8743
   448
Proper tries associate some value with each string. Since the
nipkow@8743
   449
information is stored only in the final node associated with the string, many
nipkow@10543
   450
nodes do not carry any value. This distinction is modeled with the help
nipkow@10543
   451
of the predefined datatype \isa{option} (see {\S}\ref{sec:option}).
nipkow@8743
   452
\input{Trie/document/Trie.tex}
nipkow@8743
   453
nipkow@8743
   454
\begin{exercise}
nipkow@8743
   455
  Write an improved version of \isa{update} that does not suffer from the
nipkow@8743
   456
  space leak in the version above. Prove the main theorem for your improved
nipkow@8743
   457
  \isa{update}.
nipkow@8743
   458
\end{exercise}
nipkow@8743
   459
nipkow@8743
   460
\begin{exercise}
nipkow@8743
   461
  Write a function to \emph{delete} entries from a trie. An easy solution is
nipkow@8743
   462
  a clever modification of \isa{update} which allows both insertion and
nipkow@8743
   463
  deletion with a single function.  Prove (a modified version of) the main
nipkow@8743
   464
  theorem above. Optimize you function such that it shrinks tries after
nipkow@8743
   465
  deletion, if possible.
nipkow@8743
   466
\end{exercise}
nipkow@8743
   467
nipkow@8743
   468
\section{Total recursive functions}
nipkow@8743
   469
\label{sec:recdef}
nipkow@8743
   470
\index{*recdef|(}
nipkow@8743
   471
nipkow@8743
   472
Although many total functions have a natural primitive recursive definition,
nipkow@8743
   473
this is not always the case. Arbitrary total recursive functions can be
nipkow@8743
   474
defined by means of \isacommand{recdef}: you can use full pattern-matching,
nipkow@8743
   475
recursion need not involve datatypes, and termination is proved by showing
nipkow@8743
   476
that the arguments of all recursive calls are smaller in a suitable (user
nipkow@10522
   477
supplied) sense. In this section we ristrict ourselves to measure functions;
nipkow@10538
   478
more advanced termination proofs are discussed in {\S}\ref{sec:beyond-measure}.
nipkow@8743
   479
nipkow@8743
   480
\subsection{Defining recursive functions}
nipkow@10654
   481
\label{sec:recdef-examples}
nipkow@8743
   482
\input{Recdef/document/examples.tex}
nipkow@8743
   483
nipkow@8743
   484
\subsection{Proving termination}
nipkow@8743
   485
nipkow@8743
   486
\input{Recdef/document/termination.tex}
nipkow@8743
   487
nipkow@8743
   488
\subsection{Simplification with recdef}
paulson@10181
   489
\label{sec:recdef-simplification}
nipkow@8743
   490
nipkow@8743
   491
\input{Recdef/document/simplification.tex}
nipkow@8743
   492
nipkow@8743
   493
\subsection{Induction}
nipkow@8743
   494
\index{induction!recursion|(}
nipkow@8743
   495
\index{recursion induction|(}
nipkow@8743
   496
nipkow@8743
   497
\input{Recdef/document/Induction.tex}
nipkow@9644
   498
\label{sec:recdef-induction}
nipkow@8743
   499
nipkow@8743
   500
\index{induction!recursion|)}
nipkow@8743
   501
\index{recursion induction|)}
nipkow@8743
   502
\index{*recdef|)}