
nipkow@8743: \chapter{Functional Programming in HOL}
nipkow@8743: 
nipkow@8743: Although on the surface this chapter is mainly concerned with how to write
nipkow@8743: functional programs in HOL and how to verify them, most of the
nipkow@8743: constructs and proof procedures introduced are general purpose and recur in
nipkow@8743: any specification or verification task.
nipkow@8743: 
nipkow@9541: The dedicated functional programmer should be warned: HOL offers only
nipkow@9541: \emph{total functional programming} --- all functions in HOL must be total;
nipkow@9541: lazy data structures are not directly available. On the positive side,
nipkow@9541: functions in HOL need not be computable: HOL is a specification language that
nipkow@9541: goes well beyond what can be expressed as a program. However, for the time
nipkow@9541: being we concentrate on the computable.
nipkow@8743: 
paulson@10885: \section{An Introductory Theory}
nipkow@8743: \label{sec:intro-theory}
nipkow@8743: 
nipkow@8743: Functional programming needs datatypes and functions. Both of them can be
nipkow@8743: defined in a theory with a syntax reminiscent of languages like ML or
nipkow@8743: Haskell. As an example consider the theory in figure~\ref{fig:ToyList}.
nipkow@8743: We will now examine it line by line.
nipkow@8743: 
nipkow@8743: \begin{figure}[htbp]
nipkow@8743: \begin{ttbox}\makeatother
nipkow@8743: \input{ToyList2/ToyList1}\end{ttbox}
nipkow@8743: \caption{A theory of lists}
nipkow@8743: \label{fig:ToyList}
nipkow@8743: \end{figure}
nipkow@8743: 
nipkow@8743: {\makeatother\input{ToyList/document/ToyList.tex}}
nipkow@8743: 
paulson@10795: The complete proof script is shown in Fig.\ts\ref{fig:ToyList-proofs}. The
paulson@10795: concatenation of Figs.\ts\ref{fig:ToyList} and~\ref{fig:ToyList-proofs}
nipkow@8743: constitutes the complete theory \texttt{ToyList} and should reside in file
nipkow@8743: \texttt{ToyList.thy}. It is good practice to present all declarations and
nipkow@8743: definitions at the beginning of a theory to facilitate browsing.
nipkow@8743: 
nipkow@8743: \begin{figure}[htbp]
nipkow@8743: \begin{ttbox}\makeatother
nipkow@8743: \input{ToyList2/ToyList2}\end{ttbox}
nipkow@8743: \caption{Proofs about lists}
nipkow@8743: \label{fig:ToyList-proofs}
nipkow@8743: \end{figure}
nipkow@8743: 
nipkow@8743: \subsubsection*{Review}
nipkow@8743: 
nipkow@8743: This is the end of our toy proof. It should have familiarized you with
nipkow@8743: \begin{itemize}
nipkow@8743: \item the standard theorem proving procedure:
nipkow@8743: state a goal (lemma or theorem); proceed with proof until a separate lemma is
nipkow@8743: required; prove that lemma; come back to the original goal.
nipkow@8743: \item a specific procedure that works well for functional programs:
nipkow@8743: induction followed by all-out simplification via \isa{auto}.
nipkow@8743: \item a basic repertoire of proof commands.
nipkow@8743: \end{itemize}
nipkow@8743: 
nipkow@8743: 
paulson@10885: \section{Some Helpful Commands}
nipkow@8743: \label{sec:commands-and-hints}
nipkow@8743: 
nipkow@8743: This section discusses a few basic commands for manipulating the proof state
nipkow@8743: and can be skipped by casual readers.
nipkow@8743: 
nipkow@8743: There are two kinds of commands used during a proof: the actual proof
nipkow@8743: commands and auxiliary commands for examining the proof state and controlling
nipkow@8743: the display. Simple proof commands are of the form
nipkow@8743: \isacommand{apply}\isa{(method)}\indexbold{apply} where \bfindex{method} is a
nipkow@8743: synonym for ``theorem proving function''. Typical examples are
nipkow@8743: \isa{induct_tac} and \isa{auto}. Further methods are introduced throughout
nipkow@8743: the tutorial.  Unless stated otherwise you may assume that a method attacks
nipkow@8743: merely the first subgoal. An exception is \isa{auto} which tries to solve all
nipkow@8743: subgoals.
nipkow@8743: 
nipkow@8743: The most useful auxiliary commands are:
nipkow@8743: \begin{description}
nipkow@8743: \item[Undoing:] \isacommand{undo}\indexbold{*undo} undoes the effect of the
nipkow@8743:   last command; \isacommand{undo} can be undone by
nipkow@8743:   \isacommand{redo}\indexbold{*redo}.  Both are only needed at the shell
nipkow@8743:   level and should not occur in the final theory.
nipkow@8743: \item[Printing the current state:] \isacommand{pr}\indexbold{*pr} redisplays
nipkow@8743:   the current proof state, for example when it has disappeared off the
nipkow@8743:   screen.
nipkow@8743: \item[Limiting the number of subgoals:] \isacommand{pr}~$n$ tells Isabelle to
nipkow@8743:   print only the first $n$ subgoals from now on and redisplays the current
nipkow@8743:   proof state. This is helpful when there are many subgoals.
nipkow@8743: \item[Modifying the order of subgoals:]
nipkow@8743: \isacommand{defer}\indexbold{*defer} moves the first subgoal to the end and
nipkow@8743: \isacommand{prefer}\indexbold{*prefer}~$n$ moves subgoal $n$ to the front.
nipkow@8743: \item[Printing theorems:]
nipkow@8743:   \isacommand{thm}\indexbold{*thm}~\textit{name}$@1$~\dots~\textit{name}$@n$
nipkow@8743:   prints the named theorems.
nipkow@8743: \item[Displaying types:] We have already mentioned the flag
nipkow@8743:   \ttindex{show_types} above. It can also be useful for detecting typos in
nipkow@8743:   formulae early on. For example, if \texttt{show_types} is set and the goal
nipkow@8743:   \isa{rev(rev xs) = xs} is started, Isabelle prints the additional output
nipkow@8743: \par\noindent
nipkow@8743: \begin{isabelle}%
nipkow@8743: Variables:\isanewline
nipkow@8743: ~~xs~::~'a~list
nipkow@8743: \end{isabelle}%
nipkow@8743: \par\noindent
nipkow@8743: which tells us that Isabelle has correctly inferred that
nipkow@8743: \isa{xs} is a variable of list type. On the other hand, had we
nipkow@8743: made a typo as in \isa{rev(re xs) = xs}, the response
nipkow@8743: \par\noindent
nipkow@8743: \begin{isabelle}%
nipkow@8743: Variables:\isanewline
nipkow@8743: ~~re~::~'a~list~{\isasymRightarrow}~'a~list\isanewline
nipkow@8743: ~~xs~::~'a~list%
nipkow@8743: \end{isabelle}%
nipkow@8743: \par\noindent
nipkow@8743: would have alerted us because of the unexpected variable \isa{re}.
nipkow@8743: \item[Reading terms and types:] \isacommand{term}\indexbold{*term}
nipkow@8743:   \textit{string} reads, type-checks and prints the given string as a term in
nipkow@8743:   the current context; the inferred type is output as well.
nipkow@8743:   \isacommand{typ}\indexbold{*typ} \textit{string} reads and prints the given
nipkow@8743:   string as a type in the current context.
nipkow@8743: \item[(Re)loading theories:] When you start your interaction you must open a
nipkow@8771:   named theory with the line \isa{\isacommand{theory}~T~=~\dots~:}. Isabelle
nipkow@8771:   automatically loads all the required parent theories from their respective
nipkow@8771:   files (which may take a moment, unless the theories are already loaded and
nipkow@9541:   the files have not been modified).
nipkow@8743:   
nipkow@8743:   If you suddenly discover that you need to modify a parent theory of your
nipkow@9494:   current theory you must first abandon your current theory\indexbold{abandon
nipkow@9494:   theory}\indexbold{theory!abandon} (at the shell
nipkow@8743:   level type \isacommand{kill}\indexbold{*kill}). After the parent theory has
nipkow@8743:   been modified you go back to your original theory. When its first line
nipkow@8743:   \isacommand{theory}\texttt{~T~=}~\dots~\texttt{:} is processed, the
nipkow@8743:   modified parent is reloaded automatically.
nipkow@9541:   
nipkow@9541:   The only time when you need to load a theory by hand is when you simply
nipkow@9541:   want to check if it loads successfully without wanting to make use of the
nipkow@9541:   theory itself. This you can do by typing
nipkow@9541:   \isa{\isacommand{use\_thy}\indexbold{*use_thy}~"T"}.
nipkow@8743: \end{description}
nipkow@8743: Further commands are found in the Isabelle/Isar Reference Manual.
nipkow@8743: 
nipkow@8771: We now examine Isabelle's functional programming constructs systematically,
nipkow@8771: starting with inductive datatypes.
nipkow@8771: 
nipkow@8743: 
nipkow@8743: \section{Datatypes}
nipkow@8743: \label{sec:datatype}
nipkow@8743: 
nipkow@8743: Inductive datatypes are part of almost every non-trivial application of HOL.
nipkow@8743: First we take another look at a very important example, the datatype of
nipkow@8743: lists, before we turn to datatypes in general. The section closes with a
nipkow@8743: case study.
nipkow@8743: 
nipkow@8743: 
nipkow@8743: \subsection{Lists}
nipkow@8743: \indexbold{*list}
nipkow@8743: 
nipkow@8743: Lists are one of the essential datatypes in computing. Readers of this
nipkow@8743: tutorial and users of HOL need to be familiar with their basic operations.
nipkow@8771: Theory \isa{ToyList} is only a small fragment of HOL's predefined theory
nipkow@8771: \isa{List}\footnote{\url{http://isabelle.in.tum.de/library/HOL/List.html}}.
nipkow@8743: The latter contains many further operations. For example, the functions
nipkow@8771: \isaindexbold{hd} (``head'') and \isaindexbold{tl} (``tail'') return the first
nipkow@8743: element and the remainder of a list. (However, pattern-matching is usually
paulson@10795: preferable to \isa{hd} and \isa{tl}.)  
nipkow@10800: Also available are higher-order functions like \isa{map} and \isa{filter}.
paulson@10795: Theory \isa{List} also contains
nipkow@8743: more syntactic sugar: \isa{[}$x@1$\isa{,}\dots\isa{,}$x@n$\isa{]} abbreviates
nipkow@8743: $x@1$\isa{\#}\dots\isa{\#}$x@n$\isa{\#[]}.  In the rest of the tutorial we
nipkow@8743: always use HOL's predefined lists.
nipkow@8743: 
nipkow@8743: 
paulson@10885: \subsection{The General Format}
nipkow@8743: \label{sec:general-datatype}
nipkow@8743: 
nipkow@8743: The general HOL \isacommand{datatype} definition is of the form
nipkow@8743: \[
nipkow@8743: \isacommand{datatype}~(\alpha@1, \dots, \alpha@n) \, t ~=~
nipkow@8743: C@1~\tau@{11}~\dots~\tau@{1k@1} ~\mid~ \dots ~\mid~
nipkow@8743: C@m~\tau@{m1}~\dots~\tau@{mk@m}
nipkow@8743: \]
nipkow@8771: where $\alpha@i$ are distinct type variables (the parameters), $C@i$ are distinct
nipkow@8743: constructor names and $\tau@{ij}$ are types; it is customary to capitalize
nipkow@8743: the first letter in constructor names. There are a number of
nipkow@8743: restrictions (such as that the type should not be empty) detailed
nipkow@8743: elsewhere~\cite{isabelle-HOL}. Isabelle notifies you if you violate them.
nipkow@8743: 
nipkow@8743: Laws about datatypes, such as \isa{[] \isasymnoteq~x\#xs} and
nipkow@8743: \isa{(x\#xs = y\#ys) = (x=y \isasymand~xs=ys)}, are used automatically
nipkow@8743: during proofs by simplification.  The same is true for the equations in
nipkow@8743: primitive recursive function definitions.
nipkow@8743: 
nipkow@9644: Every datatype $t$ comes equipped with a \isa{size} function from $t$ into
nipkow@10538: the natural numbers (see~{\S}\ref{sec:nat} below). For lists, \isa{size} is
nipkow@9644: just the length, i.e.\ \isa{size [] = 0} and \isa{size(x \# xs) = size xs +
nipkow@10237:   1}.  In general, \isaindexbold{size} returns \isa{0} for all constructors
nipkow@10237: that do not have an argument of type $t$, and for all other constructors
nipkow@10237: \isa{1 +} the sum of the sizes of all arguments of type $t$. Note that because
nipkow@9644: \isa{size} is defined on every datatype, it is overloaded; on lists
nipkow@10237: \isa{size} is also called \isaindexbold{length}, which is not overloaded.
paulson@10795: Isabelle will always show \isa{size} on lists as \isa{length}.
nipkow@9644: 
nipkow@9644: 
paulson@10885: \subsection{Primitive Recursion}
nipkow@8743: 
nipkow@8743: Functions on datatypes are usually defined by recursion. In fact, most of the
nipkow@8743: time they are defined by what is called \bfindex{primitive recursion}.
nipkow@8743: The keyword \isacommand{primrec}\indexbold{*primrec} is followed by a list of
nipkow@8743: equations
nipkow@8743: \[ f \, x@1 \, \dots \, (C \, y@1 \, \dots \, y@k)\, \dots \, x@n = r \]
nipkow@8743: such that $C$ is a constructor of the datatype $t$ and all recursive calls of
nipkow@8743: $f$ in $r$ are of the form $f \, \dots \, y@i \, \dots$ for some $i$. Thus
nipkow@8743: Isabelle immediately sees that $f$ terminates because one (fixed!) argument
nipkow@10654: becomes smaller with every recursive call. There must be at most one equation
nipkow@8743: for each constructor.  Their order is immaterial.
nipkow@8771: A more general method for defining total recursive functions is introduced in
nipkow@10538: {\S}\ref{sec:recdef}.
nipkow@8743: 
nipkow@9493: \begin{exercise}\label{ex:Tree}
nipkow@8743: \input{Misc/document/Tree.tex}%
nipkow@8743: \end{exercise}
nipkow@8743: 
nipkow@9721: \input{Misc/document/case_exprs.tex}
nipkow@8743: 
nipkow@8743: \input{Ifexpr/document/Ifexpr.tex}
nipkow@8743: 
paulson@10885: \section{Some Basic Types}
nipkow@8743: 
nipkow@8743: 
paulson@10885: \subsection{Natural Numbers}
nipkow@9644: \label{sec:nat}
nipkow@8743: \index{arithmetic|(}
nipkow@8743: 
nipkow@8743: \input{Misc/document/fakenat.tex}
nipkow@8743: \input{Misc/document/natsum.tex}
nipkow@8743: 
nipkow@8743: \index{arithmetic|)}
nipkow@8743: 
nipkow@8743: 
nipkow@10396: \subsection{Pairs}
nipkow@9541: \input{Misc/document/pairs.tex}
nipkow@8743: 
nipkow@10608: \subsection{Datatype {\tt\slshape option}}
nipkow@10543: \label{sec:option}
nipkow@10543: \input{Misc/document/Option2.tex}
nipkow@10543: 
nipkow@8743: \section{Definitions}
nipkow@8743: \label{sec:Definitions}
nipkow@8743: 
nipkow@8743: A definition is simply an abbreviation, i.e.\ a new name for an existing
nipkow@8743: construction. In particular, definitions cannot be recursive. Isabelle offers
nipkow@8743: definitions on the level of types and terms. Those on the type level are
nipkow@8743: called type synonyms, those on the term level are called (constant)
nipkow@8743: definitions.
nipkow@8743: 
nipkow@8743: 
paulson@10885: \subsection{Type Synonyms}
nipkow@8771: \indexbold{type synonym}
nipkow@8743: 
paulson@10795: Type synonyms are similar to those found in ML\@. Their syntax is fairly self
nipkow@8743: explanatory:
nipkow@8743: 
nipkow@8743: \input{Misc/document/types.tex}%
nipkow@8743: 
nipkow@8743: Note that pattern-matching is not allowed, i.e.\ each definition must be of
nipkow@8743: the form $f\,x@1\,\dots\,x@n~\isasymequiv~t$.
nipkow@10538: Section~{\S}\ref{sec:Simplification} explains how definitions are used
nipkow@8743: in proofs.
nipkow@8743: 
nipkow@9844: \input{Misc/document/prime_def.tex}
nipkow@8743: 
nipkow@8743: 
nipkow@8743: \chapter{More Functional Programming}
nipkow@8743: 
nipkow@8743: The purpose of this chapter is to deepen the reader's understanding of the
nipkow@8771: concepts encountered so far and to introduce advanced forms of datatypes and
nipkow@8771: recursive functions. The first two sections give a structured presentation of
nipkow@10538: theorem proving by simplification ({\S}\ref{sec:Simplification}) and discuss
nipkow@10538: important heuristics for induction ({\S}\ref{sec:InductionHeuristics}). They can
nipkow@8771: be skipped by readers less interested in proofs. They are followed by a case
nipkow@10538: study, a compiler for expressions ({\S}\ref{sec:ExprCompiler}). Advanced
nipkow@8771: datatypes, including those involving function spaces, are covered in
nipkow@10538: {\S}\ref{sec:advanced-datatypes}, which closes with another case study, search
nipkow@8771: trees (``tries'').  Finally we introduce \isacommand{recdef}, a very general
nipkow@8771: form of recursive function definition which goes well beyond what
nipkow@10538: \isacommand{primrec} allows ({\S}\ref{sec:recdef}).
nipkow@8743: 
nipkow@8743: 
nipkow@8743: \section{Simplification}
nipkow@8743: \label{sec:Simplification}
nipkow@8743: \index{simplification|(}
nipkow@8743: 
paulson@10795: So far we have proved our theorems by \isa{auto}, which simplifies
nipkow@9541: \emph{all} subgoals. In fact, \isa{auto} can do much more than that, except
nipkow@9541: that it did not need to so far. However, when you go beyond toy examples, you
nipkow@9541: need to understand the ingredients of \isa{auto}.  This section covers the
nipkow@9541: method that \isa{auto} always applies first, namely simplification.
nipkow@8743: 
nipkow@8743: Simplification is one of the central theorem proving tools in Isabelle and
nipkow@8743: many other systems. The tool itself is called the \bfindex{simplifier}. The
nipkow@9754: purpose of this section is introduce the many features of the simplifier.
nipkow@9754: Anybody intending to use HOL should read this section. Later on
nipkow@10538: ({\S}\ref{sec:simplification-II}) we explain some more advanced features and a
nipkow@9754: little bit of how the simplifier works. The serious student should read that
nipkow@9754: section as well, in particular in order to understand what happened if things
nipkow@9754: do not simplify as expected.
nipkow@8743: 
paulson@10885: \subsubsection{What is Simplification?}
nipkow@9458: 
nipkow@8743: In its most basic form, simplification means repeated application of
nipkow@8743: equations from left to right. For example, taking the rules for \isa{\at}
nipkow@8743: and applying them to the term \isa{[0,1] \at\ []} results in a sequence of
nipkow@8743: simplification steps:
nipkow@8743: \begin{ttbox}\makeatother
nipkow@8743: (0#1#[]) @ []  \(\leadsto\)  0#((1#[]) @ [])  \(\leadsto\)  0#(1#([] @ []))  \(\leadsto\)  0#1#[]
nipkow@8743: \end{ttbox}
nipkow@9933: This is also known as \bfindex{term rewriting}\indexbold{rewriting} and the
nipkow@9933: equations are referred to as \textbf{rewrite rules}\indexbold{rewrite rule}.
nipkow@9933: ``Rewriting'' is more honest than ``simplification'' because the terms do not
nipkow@9933: necessarily become simpler in the process.
nipkow@8743: 
nipkow@9844: \input{Misc/document/simp.tex}
nipkow@8743: 
nipkow@8743: \index{simplification|)}
nipkow@8743: 
nipkow@9844: \input{Misc/document/Itrev.tex}
nipkow@8743: 
nipkow@9493: \begin{exercise}
nipkow@9493: \input{Misc/document/Tree2.tex}%
nipkow@9493: \end{exercise}
nipkow@8743: 
nipkow@9844: \input{CodeGen/document/CodeGen.tex}
nipkow@8743: 
nipkow@8743: 
paulson@10885: \section{Advanced Datatypes}
nipkow@8743: \label{sec:advanced-datatypes}
nipkow@8743: \index{*datatype|(}
nipkow@8743: \index{*primrec|(}
nipkow@8743: %|)
nipkow@8743: 
nipkow@8743: This section presents advanced forms of \isacommand{datatype}s.
nipkow@8743: 
paulson@10885: \subsection{Mutual Recursion}
nipkow@8743: \label{sec:datatype-mut-rec}
nipkow@8743: 
nipkow@8743: \input{Datatype/document/ABexpr.tex}
nipkow@8743: 
paulson@10885: \subsection{Nested Recursion}
nipkow@9644: \label{sec:nested-datatype}
nipkow@8743: 
nipkow@9644: {\makeatother\input{Datatype/document/Nested.tex}}
nipkow@8743: 
nipkow@8743: 
paulson@10885: \subsection{The Limits of Nested Recursion}
nipkow@8743: 
nipkow@8743: How far can we push nested recursion? By the unfolding argument above, we can
nipkow@8743: reduce nested to mutual recursion provided the nested recursion only involves
nipkow@8743: previously defined datatypes. This does not include functions:
nipkow@9792: \begin{isabelle}
nipkow@9792: \isacommand{datatype} t = C "t \isasymRightarrow\ bool"
nipkow@9792: \end{isabelle}
paulson@10795: This declaration is a real can of worms.
paulson@10795: In HOL it must be ruled out because it requires a type
nipkow@8743: \isa{t} such that \isa{t} and its power set \isa{t \isasymFun\ bool} have the
nipkow@8743: same cardinality---an impossibility. For the same reason it is not possible
nipkow@8743: to allow recursion involving the type \isa{set}, which is isomorphic to
nipkow@8743: \isa{t \isasymFun\ bool}.
nipkow@8743: 
nipkow@8743: Fortunately, a limited form of recursion
nipkow@8743: involving function spaces is permitted: the recursive type may occur on the
nipkow@8743: right of a function arrow, but never on the left. Hence the above can of worms
nipkow@8743: is ruled out but the following example of a potentially infinitely branching tree is
nipkow@8743: accepted:
nipkow@8771: \smallskip
nipkow@8743: 
nipkow@8743: \input{Datatype/document/Fundata.tex}
nipkow@8743: \bigskip
nipkow@8743: 
nipkow@9792: If you need nested recursion on the left of a function arrow, there are
nipkow@9792: alternatives to pure HOL: LCF~\cite{paulson87} is a logic where types like
nipkow@9792: \begin{isabelle}
nipkow@9792: \isacommand{datatype} lam = C "lam \isasymrightarrow\ lam"
nipkow@9792: \end{isabelle}
paulson@10795: do indeed make sense.  Note the different arrow,
paulson@10795: \isa{\isasymrightarrow} instead of \isa{\isasymRightarrow},
paulson@10795: expressing the type of \textbf{continuous} functions. 
paulson@10795: There is even a version of LCF on top of HOL,
nipkow@9792: called HOLCF~\cite{MuellerNvOS99}.
nipkow@8743: 
nipkow@8743: \index{*primrec|)}
nipkow@8743: \index{*datatype|)}
nipkow@8743: 
paulson@10885: \subsection{Case Study: Tries}
nipkow@10543: \label{sec:Trie}
nipkow@8743: 
nipkow@8743: Tries are a classic search tree data structure~\cite{Knuth3-75} for fast
nipkow@8743: indexing with strings. Figure~\ref{fig:trie} gives a graphical example of a
nipkow@8743: trie containing the words ``all'', ``an'', ``ape'', ``can'', ``car'' and
nipkow@8743: ``cat''.  When searching a string in a trie, the letters of the string are
nipkow@8743: examined sequentially. Each letter determines which subtrie to search next.
nipkow@8743: In this case study we model tries as a datatype, define a lookup and an
nipkow@8743: update function, and prove that they behave as expected.
nipkow@8743: 
nipkow@8743: \begin{figure}[htbp]
nipkow@8743: \begin{center}
nipkow@8743: \unitlength1mm
nipkow@8743: \begin{picture}(60,30)
nipkow@8743: \put( 5, 0){\makebox(0,0)[b]{l}}
nipkow@8743: \put(25, 0){\makebox(0,0)[b]{e}}
nipkow@8743: \put(35, 0){\makebox(0,0)[b]{n}}
nipkow@8743: \put(45, 0){\makebox(0,0)[b]{r}}
nipkow@8743: \put(55, 0){\makebox(0,0)[b]{t}}
nipkow@8743: %
nipkow@8743: \put( 5, 9){\line(0,-1){5}}
nipkow@8743: \put(25, 9){\line(0,-1){5}}
nipkow@8743: \put(44, 9){\line(-3,-2){9}}
nipkow@8743: \put(45, 9){\line(0,-1){5}}
nipkow@8743: \put(46, 9){\line(3,-2){9}}
nipkow@8743: %
nipkow@8743: \put( 5,10){\makebox(0,0)[b]{l}}
nipkow@8743: \put(15,10){\makebox(0,0)[b]{n}}
nipkow@8743: \put(25,10){\makebox(0,0)[b]{p}}
nipkow@8743: \put(45,10){\makebox(0,0)[b]{a}}
nipkow@8743: %
nipkow@8743: \put(14,19){\line(-3,-2){9}}
nipkow@8743: \put(15,19){\line(0,-1){5}}
nipkow@8743: \put(16,19){\line(3,-2){9}}
nipkow@8743: \put(45,19){\line(0,-1){5}}
nipkow@8743: %
nipkow@8743: \put(15,20){\makebox(0,0)[b]{a}}
nipkow@8743: \put(45,20){\makebox(0,0)[b]{c}}
nipkow@8743: %
nipkow@8743: \put(30,30){\line(-3,-2){13}}
nipkow@8743: \put(30,30){\line(3,-2){13}}
nipkow@8743: \end{picture}
nipkow@8743: \end{center}
nipkow@8743: \caption{A sample trie}
nipkow@8743: \label{fig:trie}
nipkow@8743: \end{figure}
nipkow@8743: 
nipkow@8743: Proper tries associate some value with each string. Since the
nipkow@8743: information is stored only in the final node associated with the string, many
nipkow@10543: nodes do not carry any value. This distinction is modeled with the help
nipkow@10543: of the predefined datatype \isa{option} (see {\S}\ref{sec:option}).
nipkow@8743: \input{Trie/document/Trie.tex}
nipkow@8743: 
nipkow@8743: \begin{exercise}
nipkow@8743:   Write an improved version of \isa{update} that does not suffer from the
nipkow@8743:   space leak in the version above. Prove the main theorem for your improved
nipkow@8743:   \isa{update}.
nipkow@8743: \end{exercise}
nipkow@8743: 
nipkow@8743: \begin{exercise}
nipkow@8743:   Write a function to \emph{delete} entries from a trie. An easy solution is
nipkow@8743:   a clever modification of \isa{update} which allows both insertion and
nipkow@8743:   deletion with a single function.  Prove (a modified version of) the main
nipkow@8743:   theorem above. Optimize you function such that it shrinks tries after
nipkow@8743:   deletion, if possible.
nipkow@8743: \end{exercise}
nipkow@8743: 
paulson@10885: \section{Total Recursive Functions}
nipkow@8743: \label{sec:recdef}
nipkow@8743: \index{*recdef|(}
nipkow@8743: 
nipkow@8743: Although many total functions have a natural primitive recursive definition,
nipkow@8743: this is not always the case. Arbitrary total recursive functions can be
nipkow@8743: defined by means of \isacommand{recdef}: you can use full pattern-matching,
nipkow@8743: recursion need not involve datatypes, and termination is proved by showing
nipkow@8743: that the arguments of all recursive calls are smaller in a suitable (user
nipkow@10522: supplied) sense. In this section we ristrict ourselves to measure functions;
nipkow@10538: more advanced termination proofs are discussed in {\S}\ref{sec:beyond-measure}.
nipkow@8743: 
paulson@10885: \subsection{Defining Recursive Functions}
nipkow@10654: \label{sec:recdef-examples}
nipkow@8743: \input{Recdef/document/examples.tex}
nipkow@8743: 
paulson@10885: \subsection{Proving Termination}
nipkow@8743: 
nipkow@8743: \input{Recdef/document/termination.tex}
nipkow@8743: 
paulson@10885: \subsection{Simplification with Recdef}
paulson@10181: \label{sec:recdef-simplification}
nipkow@8743: 
nipkow@8743: \input{Recdef/document/simplification.tex}
nipkow@8743: 
nipkow@8743: \subsection{Induction}
nipkow@8743: \index{induction!recursion|(}
nipkow@8743: \index{recursion induction|(}
nipkow@8743: 
nipkow@8743: \input{Recdef/document/Induction.tex}
nipkow@9644: \label{sec:recdef-induction}
nipkow@8743: 
nipkow@8743: \index{induction!recursion|)}
nipkow@8743: \index{recursion induction|)}
nipkow@8743: \index{*recdef|)}




