doc-src/TutorialI/Advanced/document/Partial.tex
author haftmann
Mon, 31 May 2010 17:31:33 +0200
changeset 37212 b8e02ce2559f
parent 25258 22d16596c306
permissions -rw-r--r--
updated generated files
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
     1
%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
     2
\begin{isabellebody}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
     3
\def\isabellecontext{Partial}%
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
     4
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
     5
\isadelimtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
     6
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
     7
\endisadelimtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
     8
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
     9
\isatagtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
    10
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
    11
\endisatagtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
    12
{\isafoldtheory}%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
    13
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
    14
\isadelimtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
    15
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
    16
\endisadelimtheory
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    17
%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    18
\begin{isamarkuptext}%
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    19
\noindent Throughout this tutorial, we have emphasized
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    20
that all functions in HOL are total.  We cannot hope to define
11310
51e70b7bc315 spelling check
paulson
parents: 11285
diff changeset
    21
truly partial functions, but must make them total.  A straightforward
51e70b7bc315 spelling check
paulson
parents: 11285
diff changeset
    22
method is to lift the result type of the function from $\tau$ to
11277
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    23
$\tau$~\isa{option} (see \ref{sec:option}), where \isa{None} is
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    24
returned if the function is applied to an argument not in its
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    25
domain. Function \isa{assoc} in \S\ref{sec:Trie} is a simple example.
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    26
We do not pursue this schema further because it should be clear
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    27
how it works. Its main drawback is that the result of such a lifted
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    28
function has to be unpacked first before it can be processed
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    29
further. Its main advantage is that you can distinguish if the
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    30
function was applied to an argument in its domain or not. If you do
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    31
not need to make this distinction, for example because the function is
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    32
never used outside its domain, it is easier to work with
11428
332347b9b942 tidying the index
paulson
parents: 11310
diff changeset
    33
\emph{underdefined}\index{functions!underdefined} functions: for
11277
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    34
certain arguments we only know that a result exists, but we do not
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    35
know what it is. When defining functions that are normally considered
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    36
partial, underdefinedness turns out to be a very reasonable
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
    37
alternative.
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    38
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    39
We have already seen an instance of underdefinedness by means of
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    40
non-exhaustive pattern matching: the definition of \isa{last} in
25258
22d16596c306 recdef -> fun
nipkow
parents: 19248
diff changeset
    41
\S\ref{sec:fun}. The same is allowed for \isacommand{primrec}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    42
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    43
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    44
\isacommand{consts}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    45
\ hd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    46
\isacommand{primrec}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    47
\ {\isachardoublequoteopen}hd\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ x{\isachardoublequoteclose}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    48
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    49
\noindent
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    50
although it generates a warning.
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    51
Even ordinary definitions allow underdefinedness, this time by means of
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    52
preconditions:%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    53
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    54
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    55
\isacommand{constdefs}\isamarkupfalse%
19248
25bb0a883ac5 renamed const minus to subtract;
wenzelm
parents: 17187
diff changeset
    56
\ subtract\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
25bb0a883ac5 renamed const minus to subtract;
wenzelm
parents: 17187
diff changeset
    57
{\isachardoublequoteopen}n\ {\isasymle}\ m\ {\isasymLongrightarrow}\ subtract\ m\ n\ {\isasymequiv}\ m\ {\isacharminus}\ n{\isachardoublequoteclose}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    58
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    59
The rest of this section is devoted to the question of how to define
11256
49afcce3bada *** empty log message ***
nipkow
parents: 11196
diff changeset
    60
partial recursive functions by other means than non-exhaustive pattern
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    61
matching.%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    62
\end{isamarkuptext}%
11866
fbd097aec213 updated;
wenzelm
parents: 11627
diff changeset
    63
\isamarkuptrue%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    64
%
10878
b254d5ad6dd4 auto update
paulson
parents: 10696
diff changeset
    65
\isamarkupsubsubsection{Guarded Recursion%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    66
}
11866
fbd097aec213 updated;
wenzelm
parents: 11627
diff changeset
    67
\isamarkuptrue%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    68
%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    69
\begin{isamarkuptext}%
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
    70
\index{recursion!guarded}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    71
Neither \isacommand{primrec} nor \isacommand{recdef} allow to
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    72
prefix an equation with a condition in the way ordinary definitions do
19248
25bb0a883ac5 renamed const minus to subtract;
wenzelm
parents: 17187
diff changeset
    73
(see \isa{subtract} above). Instead we have to move the condition over
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    74
to the right-hand side of the equation. Given a partial function $f$
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    75
that should satisfy the recursion equation $f(x) = t$ over its domain
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    76
$dom(f)$, we turn this into the \isacommand{recdef}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    77
\begin{isabelle}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    78
\ \ \ \ \ f\ x\ {\isacharequal}\ {\isacharparenleft}if\ x\ {\isasymin}\ dom\ f\ then\ t\ else\ arbitrary{\isacharparenright}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    79
\end{isabelle}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    80
where \isa{arbitrary} is a predeclared constant of type \isa{{\isacharprime}a}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    81
which has no definition. Thus we know nothing about its value,
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    82
which is ideal for specifying underdefined functions on top of it.
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    83
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    84
As a simple example we define division on \isa{nat}:%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    85
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    86
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    87
\isacommand{consts}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    88
\ divi\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymtimes}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    89
\isacommand{recdef}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    90
\ divi\ {\isachardoublequoteopen}measure{\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}\ m{\isacharparenright}{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    91
\ \ {\isachardoublequoteopen}divi{\isacharparenleft}m{\isacharcomma}{\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ arbitrary{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
    92
\ \ {\isachardoublequoteopen}divi{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ m\ {\isacharless}\ n\ then\ {\isadigit{0}}\ else\ divi{\isacharparenleft}m{\isacharminus}n{\isacharcomma}n{\isacharparenright}{\isacharplus}{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    93
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    94
\noindent Of course we could also have defined
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    95
\isa{divi\ {\isacharparenleft}m{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}} to be some specific number, for example 0. The
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    96
latter option is chosen for the predefined \isa{div} function, which
10878
b254d5ad6dd4 auto update
paulson
parents: 10696
diff changeset
    97
simplifies proofs at the expense of deviating from the
b254d5ad6dd4 auto update
paulson
parents: 10696
diff changeset
    98
standard mathematical division function.
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
    99
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   100
As a more substantial example we consider the problem of searching a graph.
11277
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
   101
For simplicity our graph is given by a function \isa{f} of
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   102
type \isa{{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a} which
12334
60bf75e157e4 *** empty log message ***
nipkow
parents: 12332
diff changeset
   103
maps each node to its successor; the graph has out-degree 1.
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   104
The task is to find the end of a chain, modelled by a node pointing to
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   105
itself. Here is a first attempt:
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   106
\begin{isabelle}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   107
\ \ \ \ \ find\ {\isacharparenleft}f{\isacharcomma}\ x{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ f\ x\ {\isacharequal}\ x\ then\ x\ else\ find\ {\isacharparenleft}f{\isacharcomma}\ f\ x{\isacharparenright}{\isacharparenright}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   108
\end{isabelle}
12334
60bf75e157e4 *** empty log message ***
nipkow
parents: 12332
diff changeset
   109
This may be viewed as a fixed point finder or as the second half of the well
60bf75e157e4 *** empty log message ***
nipkow
parents: 12332
diff changeset
   110
known \emph{Union-Find} algorithm.
11149
e258b536a137 *** empty log message ***
nipkow
parents: 10950
diff changeset
   111
The snag is that it may not terminate if \isa{f} has non-trivial cycles.
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   112
Phrased differently, the relation%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   113
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   114
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   115
\isacommand{constdefs}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   116
\ step{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}set{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   117
\ \ {\isachardoublequoteopen}step{\isadigit{1}}\ f\ {\isasymequiv}\ {\isacharbraceleft}{\isacharparenleft}y{\isacharcomma}x{\isacharparenright}{\isachardot}\ y\ {\isacharequal}\ f\ x\ {\isasymand}\ y\ {\isasymnoteq}\ x{\isacharbraceright}{\isachardoublequoteclose}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   118
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   119
\noindent
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   120
must be well-founded. Thus we make the following definition:%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   121
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   122
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   123
\isacommand{consts}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   124
\ find\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isacharparenright}\ {\isasymtimes}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   125
\isacommand{recdef}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   126
\ find\ {\isachardoublequoteopen}same{\isacharunderscore}fst\ {\isacharparenleft}{\isasymlambda}f{\isachardot}\ wf{\isacharparenleft}step{\isadigit{1}}\ f{\isacharparenright}{\isacharparenright}\ step{\isadigit{1}}{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   127
\ \ {\isachardoublequoteopen}find{\isacharparenleft}f{\isacharcomma}x{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ wf{\isacharparenleft}step{\isadigit{1}}\ f{\isacharparenright}\isanewline
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   128
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ then\ if\ f\ x\ {\isacharequal}\ x\ then\ x\ else\ find{\isacharparenleft}f{\isacharcomma}\ f\ x{\isacharparenright}\isanewline
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   129
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ arbitrary{\isacharparenright}{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   130
{\isacharparenleft}\isakeyword{hints}\ recdef{\isacharunderscore}simp{\isacharcolon}\ step{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   131
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   132
\noindent
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   133
The recursion equation itself should be clear enough: it is our aborted
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   134
first attempt augmented with a check that there are no non-trivial loops.
11277
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
   135
To express the required well-founded relation we employ the
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   136
predefined combinator \isa{same{\isacharunderscore}fst} of type
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   137
\begin{isabelle}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   138
\ \ \ \ \ {\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ bool{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}b{\isasymtimes}{\isacharprime}b{\isacharparenright}set{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharparenleft}{\isacharprime}a{\isasymtimes}{\isacharprime}b{\isacharparenright}\ {\isasymtimes}\ {\isacharparenleft}{\isacharprime}a{\isasymtimes}{\isacharprime}b{\isacharparenright}{\isacharparenright}set%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   139
\end{isabelle}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   140
defined as
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   141
\begin{isabelle}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   142
\ \ \ \ \ same{\isacharunderscore}fst\ P\ R\ {\isasymequiv}\ {\isacharbraceleft}{\isacharparenleft}{\isacharparenleft}x{\isacharprime}{\isacharcomma}\ y{\isacharprime}{\isacharparenright}{\isacharcomma}\ x{\isacharcomma}\ y{\isacharparenright}{\isachardot}\ x{\isacharprime}\ {\isacharequal}\ x\ {\isasymand}\ P\ x\ {\isasymand}\ {\isacharparenleft}y{\isacharprime}{\isacharcomma}\ y{\isacharparenright}\ {\isasymin}\ R\ x{\isacharbraceright}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   143
\end{isabelle}
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   144
This combinator is designed for
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   145
recursive functions on pairs where the first component of the argument is
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   146
passed unchanged to all recursive calls. Given a constraint on the first
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   147
component and a relation on the second component, \isa{same{\isacharunderscore}fst} builds the
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   148
required relation on pairs.  The theorem
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   149
\begin{isabelle}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   150
\ \ \ \ \ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ P\ x\ {\isasymLongrightarrow}\ wf\ {\isacharparenleft}R\ x{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ wf\ {\isacharparenleft}same{\isacharunderscore}fst\ P\ R{\isacharparenright}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   151
\end{isabelle}
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   152
is known to the well-foundedness prover of \isacommand{recdef}.  Thus
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   153
well-foundedness of the relation given to \isacommand{recdef} is immediate.
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   154
Furthermore, each recursive call descends along that relation: the first
11285
3826c51d980e *** empty log message ***
nipkow
parents: 11277
diff changeset
   155
argument stays unchanged and the second one descends along \isa{step{\isadigit{1}}\ f}. The proof requires unfolding the definition of \isa{step{\isadigit{1}}},
3826c51d980e *** empty log message ***
nipkow
parents: 11277
diff changeset
   156
as specified in the \isacommand{hints} above.
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   157
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   158
Normally you will then derive the following conditional variant from
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   159
the recursion equation:%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   160
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   161
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   162
\isacommand{lemma}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   163
\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   164
\ \ {\isachardoublequoteopen}wf{\isacharparenleft}step{\isadigit{1}}\ f{\isacharparenright}\ {\isasymLongrightarrow}\ find{\isacharparenleft}f{\isacharcomma}x{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ f\ x\ {\isacharequal}\ x\ then\ x\ else\ find{\isacharparenleft}f{\isacharcomma}\ f\ x{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   165
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   166
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   167
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   168
\endisadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   169
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   170
\isatagproof
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   171
\isacommand{by}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   172
\ simp%
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   173
\endisatagproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   174
{\isafoldproof}%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   175
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   176
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   177
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   178
\endisadelimproof
11866
fbd097aec213 updated;
wenzelm
parents: 11627
diff changeset
   179
%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   180
\begin{isamarkuptext}%
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   181
\noindent Then you should disable the original recursion equation:%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   182
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   183
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   184
\isacommand{declare}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   185
\ find{\isachardot}simps{\isacharbrackleft}simp\ del{\isacharbrackright}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   186
\begin{isamarkuptext}%
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   187
Reasoning about such underdefined functions is like that for other
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   188
recursive functions.  Here is a simple example of recursion induction:%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   189
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   190
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   191
\isacommand{lemma}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   192
\ {\isachardoublequoteopen}wf{\isacharparenleft}step{\isadigit{1}}\ f{\isacharparenright}\ {\isasymlongrightarrow}\ f{\isacharparenleft}find{\isacharparenleft}f{\isacharcomma}x{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ find{\isacharparenleft}f{\isacharcomma}x{\isacharparenright}{\isachardoublequoteclose}\isanewline
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   193
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   194
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   195
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   196
\endisadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   197
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   198
\isatagproof
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   199
\isacommand{apply}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   200
{\isacharparenleft}induct{\isacharunderscore}tac\ f\ x\ rule{\isacharcolon}\ find{\isachardot}induct{\isacharparenright}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   201
\isacommand{apply}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   202
\ simp\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   203
\isacommand{done}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   204
%
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   205
\endisatagproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   206
{\isafoldproof}%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   207
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   208
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   209
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   210
\endisadelimproof
11866
fbd097aec213 updated;
wenzelm
parents: 11627
diff changeset
   211
%
10878
b254d5ad6dd4 auto update
paulson
parents: 10696
diff changeset
   212
\isamarkupsubsubsection{The {\tt\slshape while} Combinator%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   213
}
11866
fbd097aec213 updated;
wenzelm
parents: 11627
diff changeset
   214
\isamarkuptrue%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   215
%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   216
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   217
If the recursive function happens to be tail recursive, its
11428
332347b9b942 tidying the index
paulson
parents: 11310
diff changeset
   218
definition becomes a triviality if based on the predefined \cdx{while}
12332
aea72a834c85 *** empty log message ***
nipkow
parents: 11866
diff changeset
   219
combinator.  The latter lives in the Library theory \thydx{While_Combinator}.
aea72a834c85 *** empty log message ***
nipkow
parents: 11866
diff changeset
   220
% which is not part of {text Main} but needs to
aea72a834c85 *** empty log message ***
nipkow
parents: 11866
diff changeset
   221
% be included explicitly among the ancestor theories.
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   222
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   223
Constant \isa{while} is of type \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ bool{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isacharparenright}\ {\isasymRightarrow}\ {\isacharprime}a}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   224
and satisfies the recursion equation \begin{isabelle}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   225
\ \ \ \ \ while\ b\ c\ s\ {\isacharequal}\ {\isacharparenleft}if\ b\ s\ then\ while\ b\ c\ {\isacharparenleft}c\ s{\isacharparenright}\ else\ s{\isacharparenright}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   226
\end{isabelle}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   227
That is, \isa{while\ b\ c\ s} is equivalent to the imperative program
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   228
\begin{verbatim}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   229
     x := s; while b(x) do x := c(x); return x
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   230
\end{verbatim}
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   231
In general, \isa{s} will be a tuple or record.  As an example
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   232
consider the following definition of function \isa{find}:%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   233
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   234
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   235
\isacommand{constdefs}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   236
\ find{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isacharparenright}\ {\isasymRightarrow}\ {\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequoteclose}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   237
\ \ {\isachardoublequoteopen}find{\isadigit{2}}\ f\ x\ {\isasymequiv}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   238
\ \ \ fst{\isacharparenleft}while\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}x{\isacharcomma}x{\isacharprime}{\isacharparenright}{\isachardot}\ x{\isacharprime}\ {\isasymnoteq}\ x{\isacharparenright}\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}x{\isacharcomma}x{\isacharprime}{\isacharparenright}{\isachardot}\ {\isacharparenleft}x{\isacharprime}{\isacharcomma}f\ x{\isacharprime}{\isacharparenright}{\isacharparenright}\ {\isacharparenleft}x{\isacharcomma}f\ x{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   239
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   240
\noindent
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   241
The loop operates on two ``local variables'' \isa{x} and \isa{x{\isacharprime}}
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   242
containing the ``current'' and the ``next'' value of function \isa{f}.
11310
51e70b7bc315 spelling check
paulson
parents: 11285
diff changeset
   243
They are initialized with the global \isa{x} and \isa{f\ x}. At the
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   244
end \isa{fst} selects the local \isa{x}.
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   245
11158
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   246
Although the definition of tail recursive functions via \isa{while} avoids
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   247
termination proofs, there is no free lunch. When proving properties of
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   248
functions defined by \isa{while}, termination rears its ugly head
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   249
again. Here is \tdx{while_rule}, the well known proof rule for total
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   250
correctness of loops expressed with \isa{while}:
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   251
\begin{isabelle}%
10696
76d7f6c9a14c *** empty log message ***
nipkow
parents: 10668
diff changeset
   252
\ \ \ \ \ {\isasymlbrakk}P\ s{\isacharsemicolon}\ {\isasymAnd}s{\isachardot}\ {\isasymlbrakk}P\ s{\isacharsemicolon}\ b\ s{\isasymrbrakk}\ {\isasymLongrightarrow}\ P\ {\isacharparenleft}c\ s{\isacharparenright}{\isacharsemicolon}\isanewline
14379
ea10a8c3e9cf updated links to the old ftp site
paulson
parents: 13778
diff changeset
   253
\isaindent{\ \ \ \ \ \ }{\isasymAnd}s{\isachardot}\ {\isasymlbrakk}P\ s{\isacharsemicolon}\ {\isasymnot}\ b\ s{\isasymrbrakk}\ {\isasymLongrightarrow}\ Q\ s{\isacharsemicolon}\ wf\ r{\isacharsemicolon}\isanewline
ea10a8c3e9cf updated links to the old ftp site
paulson
parents: 13778
diff changeset
   254
\isaindent{\ \ \ \ \ \ }{\isasymAnd}s{\isachardot}\ {\isasymlbrakk}P\ s{\isacharsemicolon}\ b\ s{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharparenleft}c\ s{\isacharcomma}\ s{\isacharparenright}\ {\isasymin}\ r{\isasymrbrakk}\isanewline
10950
aa788fcb75a5 updated;
wenzelm
parents: 10878
diff changeset
   255
\isaindent{\ \ \ \ \ }{\isasymLongrightarrow}\ Q\ {\isacharparenleft}while\ b\ c\ s{\isacharparenright}%
11158
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   256
\end{isabelle} \isa{P} needs to be true of
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   257
the initial state \isa{s} and invariant under \isa{c} (premises 1
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   258
and~2). The post-condition \isa{Q} must become true when leaving the loop
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   259
(premise~3). And each loop iteration must descend along a well-founded
5652018b809a *** empty log message ***
nipkow
parents: 11157
diff changeset
   260
relation \isa{r} (premises 4 and~5).
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   261
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   262
Let us now prove that \isa{find{\isadigit{2}}} does indeed find a fixed point. Instead
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   263
of induction we apply the above while rule, suitably instantiated.
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   264
Only the final premise of \isa{while{\isacharunderscore}rule} is left unproved
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   265
by \isa{auto} but falls to \isa{simp}:%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   266
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   267
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   268
\isacommand{lemma}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   269
\ lem{\isacharcolon}\ {\isachardoublequoteopen}wf{\isacharparenleft}step{\isadigit{1}}\ f{\isacharparenright}\ {\isasymLongrightarrow}\isanewline
11277
a2bff98d6e5d *** empty log message ***
nipkow
parents: 11256
diff changeset
   270
\ \ {\isasymexists}y{\isachardot}\ while\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}x{\isacharcomma}x{\isacharprime}{\isacharparenright}{\isachardot}\ x{\isacharprime}\ {\isasymnoteq}\ x{\isacharparenright}\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}x{\isacharcomma}x{\isacharprime}{\isacharparenright}{\isachardot}\ {\isacharparenleft}x{\isacharprime}{\isacharcomma}f\ x{\isacharprime}{\isacharparenright}{\isacharparenright}\ {\isacharparenleft}x{\isacharcomma}f\ x{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}y{\isacharcomma}y{\isacharparenright}\ {\isasymand}\isanewline
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   271
\ \ \ \ \ \ \ f\ y\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   272
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   273
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   274
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   275
\endisadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   276
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   277
\isatagproof
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   278
\isacommand{apply}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   279
{\isacharparenleft}rule{\isacharunderscore}tac\ P\ {\isacharequal}\ {\isachardoublequoteopen}{\isasymlambda}{\isacharparenleft}x{\isacharcomma}x{\isacharprime}{\isacharparenright}{\isachardot}\ x{\isacharprime}\ {\isacharequal}\ f\ x{\isachardoublequoteclose}\ \isakeyword{and}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   280
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ r\ {\isacharequal}\ {\isachardoublequoteopen}inv{\isacharunderscore}image\ {\isacharparenleft}step{\isadigit{1}}\ f{\isacharparenright}\ fst{\isachardoublequoteclose}\ \isakeyword{in}\ while{\isacharunderscore}rule{\isacharparenright}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   281
\isacommand{apply}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   282
\ auto\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   283
\isacommand{apply}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   284
{\isacharparenleft}simp\ add{\isacharcolon}\ inv{\isacharunderscore}image{\isacharunderscore}def\ step{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   285
\isacommand{done}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   286
%
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   287
\endisatagproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   288
{\isafoldproof}%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   289
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   290
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   291
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   292
\endisadelimproof
11866
fbd097aec213 updated;
wenzelm
parents: 11627
diff changeset
   293
%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   294
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   295
The theorem itself is a simple consequence of this lemma:%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   296
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   297
\isamarkuptrue%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   298
\isacommand{theorem}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   299
\ {\isachardoublequoteopen}wf{\isacharparenleft}step{\isadigit{1}}\ f{\isacharparenright}\ {\isasymLongrightarrow}\ f{\isacharparenleft}find{\isadigit{2}}\ f\ x{\isacharparenright}\ {\isacharequal}\ find{\isadigit{2}}\ f\ x{\isachardoublequoteclose}\isanewline
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   300
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   301
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   302
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   303
\endisadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   304
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   305
\isatagproof
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   306
\isacommand{apply}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   307
{\isacharparenleft}drule{\isacharunderscore}tac\ x\ {\isacharequal}\ x\ \isakeyword{in}\ lem{\isacharparenright}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   308
\isacommand{apply}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   309
{\isacharparenleft}auto\ simp\ add{\isacharcolon}\ find{\isadigit{2}}{\isacharunderscore}def{\isacharparenright}\isanewline
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   310
\isacommand{done}\isamarkupfalse%
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   311
%
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   312
\endisatagproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   313
{\isafoldproof}%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   314
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   315
\isadelimproof
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   316
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   317
\endisadelimproof
11866
fbd097aec213 updated;
wenzelm
parents: 11627
diff changeset
   318
%
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   319
\begin{isamarkuptext}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   320
Let us conclude this section on partial functions by a
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   321
discussion of the merits of the \isa{while} combinator. We have
11494
23a118849801 revisions and indexing
paulson
parents: 11428
diff changeset
   322
already seen that the advantage of not having to
11310
51e70b7bc315 spelling check
paulson
parents: 11285
diff changeset
   323
provide a termination argument when defining a function via \isa{while} merely puts off the evil hour. On top of that, tail recursive
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   324
functions tend to be more complicated to reason about. So why use
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   325
\isa{while} at all? The only reason is executability: the recursion
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   326
equation for \isa{while} is a directly executable functional
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   327
program. This is in stark contrast to guarded recursion as introduced
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   328
above which requires an explicit test \isa{x\ {\isasymin}\ dom\ f} in the
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   329
function body.  Unless \isa{dom} is trivial, this leads to a
11196
bb4ede27fcb7 *** empty log message ***
nipkow
parents: 11158
diff changeset
   330
definition that is impossible to execute or prohibitively slow.
10878
b254d5ad6dd4 auto update
paulson
parents: 10696
diff changeset
   331
Thus, if you are aiming for an efficiently executable definition
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   332
of a partial function, you are likely to need \isa{while}.%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   333
\end{isamarkuptext}%
17175
1eced27ee0e1 updated;
wenzelm
parents: 17056
diff changeset
   334
\isamarkuptrue%
17056
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   335
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   336
\isadelimtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   337
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   338
\endisadelimtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   339
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   340
\isatagtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   341
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   342
\endisatagtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   343
{\isafoldtheory}%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   344
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   345
\isadelimtheory
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   346
%
05fc32a23b8b updated;
wenzelm
parents: 16069
diff changeset
   347
\endisadelimtheory
10654
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   348
\end{isabellebody}%
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   349
%%% Local Variables:
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   350
%%% mode: latex
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   351
%%% TeX-master: "root"
458068404143 *** empty log message ***
nipkow
parents:
diff changeset
   352
%%% End: