| author | wenzelm | 
| Wed, 23 Jan 2008 22:57:07 +0100 | |
| changeset 25946 | 8ceff6c1f2a8 | 
| parent 25731 | b3e415b0cf5c | 
| child 26876 | d50ef6b952ba | 
| permissions | -rw-r--r-- | 
| 21212 | 1  | 
%  | 
2  | 
\begin{isabellebody}%
 | 
|
3  | 
\def\isabellecontext{Functions}%
 | 
|
4  | 
%  | 
|
5  | 
\isadelimtheory  | 
|
6  | 
\isanewline  | 
|
7  | 
\isanewline  | 
|
8  | 
%  | 
|
9  | 
\endisadelimtheory  | 
|
10  | 
%  | 
|
11  | 
\isatagtheory  | 
|
12  | 
\isacommand{theory}\isamarkupfalse%
 | 
|
13  | 
\ Functions\isanewline  | 
|
14  | 
\isakeyword{imports}\ Main\isanewline
 | 
|
15  | 
\isakeyword{begin}%
 | 
|
16  | 
\endisatagtheory  | 
|
17  | 
{\isafoldtheory}%
 | 
|
18  | 
%  | 
|
19  | 
\isadelimtheory  | 
|
20  | 
%  | 
|
21  | 
\endisadelimtheory  | 
|
22  | 
%  | 
|
| 23188 | 23  | 
\isamarkupsection{Function Definitions for Dummies%
 | 
| 21212 | 24  | 
}  | 
25  | 
\isamarkuptrue%  | 
|
26  | 
%  | 
|
27  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 28  | 
In most cases, defining a recursive function is just as simple as other definitions:%  | 
| 21212 | 29  | 
\end{isamarkuptext}%
 | 
30  | 
\isamarkuptrue%  | 
|
31  | 
\isacommand{fun}\isamarkupfalse%
 | 
|
32  | 
\ fib\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
|
33  | 
\isakeyword{where}\isanewline
 | 
|
34  | 
\ \ {\isachardoublequoteopen}fib\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
 | 
|
35  | 
{\isacharbar}\ {\isachardoublequoteopen}fib\ {\isacharparenleft}Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
 | 
|
| 21346 | 36  | 
{\isacharbar}\ {\isachardoublequoteopen}fib\ {\isacharparenleft}Suc\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ fib\ n\ {\isacharplus}\ fib\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isachardoublequoteclose}%
 | 
| 21212 | 37  | 
\begin{isamarkuptext}%
 | 
| 23003 | 38  | 
The syntax is rather self-explanatory: We introduce a function by  | 
| 
25091
 
a2ae7f71613d
Updated function tutorial: Types can be inferred and need not be given anymore
 
krauss 
parents: 
23805 
diff
changeset
 | 
39  | 
giving its name, its type,  | 
| 
 
a2ae7f71613d
Updated function tutorial: Types can be inferred and need not be given anymore
 
krauss 
parents: 
23805 
diff
changeset
 | 
40  | 
and a set of defining recursive equations.  | 
| 
 
a2ae7f71613d
Updated function tutorial: Types can be inferred and need not be given anymore
 
krauss 
parents: 
23805 
diff
changeset
 | 
41  | 
If we leave out the type, the most general type will be  | 
| 25278 | 42  | 
  inferred, which can sometimes lead to surprises: Since both \isa{{\isadigit{1}}} and \isa{{\isacharplus}} are overloaded, we would end up
 | 
| 
25091
 
a2ae7f71613d
Updated function tutorial: Types can be inferred and need not be given anymore
 
krauss 
parents: 
23805 
diff
changeset
 | 
43  | 
  with \isa{fib\ {\isacharcolon}{\isacharcolon}\ nat\ {\isasymRightarrow}\ {\isacharprime}a{\isacharcolon}{\isacharcolon}{\isacharbraceleft}one{\isacharcomma}plus{\isacharbraceright}}.%
 | 
| 23003 | 44  | 
\end{isamarkuptext}%
 | 
45  | 
\isamarkuptrue%  | 
|
46  | 
%  | 
|
47  | 
\begin{isamarkuptext}%
 | 
|
48  | 
The function always terminates, since its argument gets smaller in  | 
|
| 23188 | 49  | 
every recursive call.  | 
50  | 
Since HOL is a logic of total functions, termination is a  | 
|
51  | 
  fundamental requirement to prevent inconsistencies\footnote{From the
 | 
|
52  | 
  \qt{definition} \isa{f{\isacharparenleft}n{\isacharparenright}\ {\isacharequal}\ f{\isacharparenleft}n{\isacharparenright}\ {\isacharplus}\ {\isadigit{1}}} we could prove 
 | 
|
53  | 
  \isa{{\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}} by subtracting \isa{f{\isacharparenleft}n{\isacharparenright}} on both sides.}.
 | 
|
54  | 
Isabelle tries to prove termination automatically when a definition  | 
|
55  | 
  is made. In \S\ref{termination}, we will look at cases where this
 | 
|
56  | 
fails and see what to do then.%  | 
|
| 21212 | 57  | 
\end{isamarkuptext}%
 | 
58  | 
\isamarkuptrue%  | 
|
59  | 
%  | 
|
60  | 
\isamarkupsubsection{Pattern matching%
 | 
|
61  | 
}  | 
|
62  | 
\isamarkuptrue%  | 
|
63  | 
%  | 
|
64  | 
\begin{isamarkuptext}%
 | 
|
| 22065 | 65  | 
\label{patmatch}
 | 
| 23003 | 66  | 
Like in functional programming, we can use pattern matching to  | 
67  | 
  define functions. At the moment we will only consider \emph{constructor
 | 
|
| 21212 | 68  | 
patterns}, which only consist of datatype constructors and  | 
| 23805 | 69  | 
variables. Furthermore, patterns must be linear, i.e.\ all variables  | 
70  | 
on the left hand side of an equation must be distinct. In  | 
|
71  | 
  \S\ref{genpats} we discuss more general pattern matching.
 | 
|
| 21212 | 72  | 
|
73  | 
If patterns overlap, the order of the equations is taken into  | 
|
74  | 
account. The following function inserts a fixed element between any  | 
|
75  | 
two elements of a list:%  | 
|
76  | 
\end{isamarkuptext}%
 | 
|
77  | 
\isamarkuptrue%  | 
|
78  | 
\isacommand{fun}\isamarkupfalse%
 | 
|
79  | 
\ sep\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequoteclose}\isanewline
 | 
|
80  | 
\isakeyword{where}\isanewline
 | 
|
81  | 
\ \ {\isachardoublequoteopen}sep\ a\ {\isacharparenleft}x{\isacharhash}y{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ x\ {\isacharhash}\ a\ {\isacharhash}\ sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
82  | 
{\isacharbar}\ {\isachardoublequoteopen}sep\ a\ xs\ \ \ \ \ \ \ {\isacharequal}\ xs{\isachardoublequoteclose}%
 | 
|
83  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 84  | 
Overlapping patterns are interpreted as \qt{increments} to what is
 | 
| 21212 | 85  | 
already there: The second equation is only meant for the cases where  | 
86  | 
the first one does not match. Consequently, Isabelle replaces it  | 
|
| 22065 | 87  | 
internally by the remaining cases, making the patterns disjoint:%  | 
88  | 
\end{isamarkuptext}%
 | 
|
89  | 
\isamarkuptrue%  | 
|
90  | 
\isacommand{thm}\isamarkupfalse%
 | 
|
91  | 
\ sep{\isachardot}simps%
 | 
|
92  | 
\begin{isamarkuptext}%
 | 
|
93  | 
\begin{isabelle}%
 | 
|
| 21212 | 94  | 
sep\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}\ {\isacharequal}\ x\ {\isacharhash}\ a\ {\isacharhash}\ sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}\isasep\isanewline%
 | 
95  | 
sep\ a\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\isasep\isanewline%
 | 
|
96  | 
sep\ a\ {\isacharbrackleft}v{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}v{\isacharbrackright}%
 | 
|
97  | 
\end{isabelle}%
 | 
|
98  | 
\end{isamarkuptext}%
 | 
|
99  | 
\isamarkuptrue%  | 
|
100  | 
%  | 
|
101  | 
\begin{isamarkuptext}%
 | 
|
| 23805 | 102  | 
\noindent The equations from function definitions are automatically used in  | 
| 21212 | 103  | 
simplification:%  | 
104  | 
\end{isamarkuptext}%
 | 
|
105  | 
\isamarkuptrue%  | 
|
106  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
| 23188 | 107  | 
\ {\isachardoublequoteopen}sep\ {\isadigit{0}}\ {\isacharbrackleft}{\isadigit{1}}{\isacharcomma}\ {\isadigit{2}}{\isacharcomma}\ {\isadigit{3}}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}{\isadigit{1}}{\isacharcomma}\ {\isadigit{0}}{\isacharcomma}\ {\isadigit{2}}{\isacharcomma}\ {\isadigit{0}}{\isacharcomma}\ {\isadigit{3}}{\isacharbrackright}{\isachardoublequoteclose}\isanewline
 | 
| 21212 | 108  | 
%  | 
109  | 
\isadelimproof  | 
|
110  | 
%  | 
|
111  | 
\endisadelimproof  | 
|
112  | 
%  | 
|
113  | 
\isatagproof  | 
|
114  | 
\isacommand{by}\isamarkupfalse%
 | 
|
115  | 
\ simp%  | 
|
116  | 
\endisatagproof  | 
|
117  | 
{\isafoldproof}%
 | 
|
118  | 
%  | 
|
119  | 
\isadelimproof  | 
|
120  | 
%  | 
|
121  | 
\endisadelimproof  | 
|
122  | 
%  | 
|
123  | 
\isamarkupsubsection{Induction%
 | 
|
124  | 
}  | 
|
125  | 
\isamarkuptrue%  | 
|
126  | 
%  | 
|
127  | 
\begin{isamarkuptext}%
 | 
|
| 23805 | 128  | 
Isabelle provides customized induction rules for recursive  | 
129  | 
functions. These rules follow the recursive structure of the  | 
|
130  | 
  definition. Here is the rule \isa{sep{\isachardot}induct} arising from the
 | 
|
131  | 
  above definition of \isa{sep}:
 | 
|
| 23188 | 132  | 
|
| 23805 | 133  | 
  \begin{isabelle}%
 | 
134  | 
{\isasymlbrakk}{\isasymAnd}a\ x\ y\ xs{\isachardot}\ {\isacharquery}P\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharquery}P\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharsemicolon}\ {\isasymAnd}a{\isachardot}\ {\isacharquery}P\ a\ {\isacharbrackleft}{\isacharbrackright}{\isacharsemicolon}\ {\isasymAnd}a\ v{\isachardot}\ {\isacharquery}P\ a\ {\isacharbrackleft}v{\isacharbrackright}{\isasymrbrakk}\isanewline
 | 
|
135  | 
{\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}%
 | 
|
136  | 
\end{isabelle}
 | 
|
137  | 
||
138  | 
We have a step case for list with at least two elements, and two  | 
|
139  | 
base cases for the zero- and the one-element list. Here is a simple  | 
|
140  | 
  proof about \isa{sep} and \isa{map}%
 | 
|
141  | 
\end{isamarkuptext}%
 | 
|
142  | 
\isamarkuptrue%  | 
|
143  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
144  | 
\ {\isachardoublequoteopen}map\ f\ {\isacharparenleft}sep\ x\ ys{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ x{\isacharparenright}\ {\isacharparenleft}map\ f\ ys{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
145  | 
%  | 
|
146  | 
\isadelimproof  | 
|
147  | 
%  | 
|
148  | 
\endisadelimproof  | 
|
149  | 
%  | 
|
150  | 
\isatagproof  | 
|
151  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
152  | 
\ {\isacharparenleft}induct\ x\ ys\ rule{\isacharcolon}\ sep{\isachardot}induct{\isacharparenright}%
 | 
|
153  | 
\begin{isamarkuptxt}%
 | 
|
154  | 
We get three cases, like in the definition.  | 
|
| 23188 | 155  | 
|
| 23805 | 156  | 
  \begin{isabelle}%
 | 
157  | 
\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}a\ x\ y\ xs{\isachardot}\isanewline
 | 
|
158  | 
\isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }map\ f\ {\isacharparenleft}sep\ a\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharparenleft}y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\isanewline
 | 
|
159  | 
\isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }map\ f\ {\isacharparenleft}sep\ a\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharparenleft}x\ {\isacharhash}\ y\ {\isacharhash}\ xs{\isacharparenright}{\isacharparenright}\isanewline
 | 
|
160  | 
\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}a{\isachardot}\ map\ f\ {\isacharparenleft}sep\ a\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\isanewline
 | 
|
161  | 
\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}a\ v{\isachardot}\ map\ f\ {\isacharparenleft}sep\ a\ {\isacharbrackleft}v{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ sep\ {\isacharparenleft}f\ a{\isacharparenright}\ {\isacharparenleft}map\ f\ {\isacharbrackleft}v{\isacharbrackright}{\isacharparenright}%
 | 
|
162  | 
\end{isabelle}%
 | 
|
163  | 
\end{isamarkuptxt}%
 | 
|
164  | 
\isamarkuptrue%  | 
|
165  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
166  | 
\ auto\ \isanewline  | 
|
167  | 
\isacommand{done}\isamarkupfalse%
 | 
|
168  | 
%  | 
|
169  | 
\endisatagproof  | 
|
170  | 
{\isafoldproof}%
 | 
|
171  | 
%  | 
|
172  | 
\isadelimproof  | 
|
173  | 
%  | 
|
174  | 
\endisadelimproof  | 
|
175  | 
%  | 
|
176  | 
\begin{isamarkuptext}%
 | 
|
177  | 
With the \cmd{fun} command, you can define about 80\% of the
 | 
|
| 23188 | 178  | 
functions that occur in practice. The rest of this tutorial explains  | 
179  | 
the remaining 20\%.%  | 
|
| 21212 | 180  | 
\end{isamarkuptext}%
 | 
181  | 
\isamarkuptrue%  | 
|
182  | 
%  | 
|
| 23188 | 183  | 
\isamarkupsection{fun vs.\ function%
 | 
| 21212 | 184  | 
}  | 
185  | 
\isamarkuptrue%  | 
|
186  | 
%  | 
|
187  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 188  | 
The \cmd{fun} command provides a
 | 
| 21212 | 189  | 
convenient shorthand notation for simple function definitions. In  | 
190  | 
this mode, Isabelle tries to solve all the necessary proof obligations  | 
|
| 23188 | 191  | 
automatically. If a proof fails, the definition is  | 
| 22065 | 192  | 
rejected. This can either mean that the definition is indeed faulty,  | 
193  | 
or that the default proof procedures are just not smart enough (or  | 
|
194  | 
rather: not designed) to handle the definition.  | 
|
195  | 
||
| 23188 | 196  | 
  By expanding the abbreviation to the more verbose \cmd{function} command, these proof obligations become visible and can be analyzed or
 | 
197  | 
  solved manually. The expansion from \cmd{fun} to \cmd{function} is as follows:
 | 
|
| 22065 | 198  | 
|
199  | 
\end{isamarkuptext}
 | 
|
200  | 
||
201  | 
||
| 23188 | 202  | 
\[\left[\;\begin{minipage}{0.25\textwidth}\vspace{6pt}
 | 
203  | 
\cmd{fun} \isa{f\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}\\%
 | 
|
204  | 
\cmd{where}\\%
 | 
|
205  | 
\hspace*{2ex}{\it equations}\\%
 | 
|
206  | 
\hspace*{2ex}\vdots\vspace*{6pt}
 | 
|
207  | 
\end{minipage}\right]
 | 
|
208  | 
\quad\equiv\quad  | 
|
209  | 
\left[\;\begin{minipage}{0.45\textwidth}\vspace{6pt}
 | 
|
210  | 
\cmd{function} \isa{{\isacharparenleft}}\cmd{sequential}\isa{{\isacharparenright}\ f\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}\\%
 | 
|
211  | 
\cmd{where}\\%
 | 
|
212  | 
\hspace*{2ex}{\it equations}\\%
 | 
|
213  | 
\hspace*{2ex}\vdots\\%
 | 
|
| 22065 | 214  | 
\cmd{by} \isa{pat{\isacharunderscore}completeness\ auto}\\%
 | 
| 23188 | 215  | 
\cmd{termination by} \isa{lexicographic{\isacharunderscore}order}\vspace{6pt}
 | 
216  | 
\end{minipage}
 | 
|
217  | 
\right]\]  | 
|
| 22065 | 218  | 
|
219  | 
\begin{isamarkuptext}
 | 
|
220  | 
  \vspace*{1em}
 | 
|
| 23188 | 221  | 
\noindent Some details have now become explicit:  | 
| 21212 | 222  | 
|
223  | 
  \begin{enumerate}
 | 
|
| 22065 | 224  | 
  \item The \cmd{sequential} option enables the preprocessing of
 | 
| 23805 | 225  | 
pattern overlaps which we already saw. Without this option, the equations  | 
| 21212 | 226  | 
must already be disjoint and complete. The automatic completion only  | 
| 23188 | 227  | 
works with constructor patterns.  | 
| 21212 | 228  | 
|
| 23188 | 229  | 
\item A function definition produces a proof obligation which  | 
230  | 
expresses completeness and compatibility of patterns (we talk about  | 
|
| 22065 | 231  | 
  this later). The combination of the methods \isa{pat{\isacharunderscore}completeness} and
 | 
232  | 
  \isa{auto} is used to solve this proof obligation.
 | 
|
| 21212 | 233  | 
|
234  | 
\item A termination proof follows the definition, started by the  | 
|
| 23188 | 235  | 
  \cmd{termination} command. This will be explained in \S\ref{termination}.
 | 
| 22065 | 236  | 
 \end{enumerate}
 | 
237  | 
  Whenever a \cmd{fun} command fails, it is usually a good idea to
 | 
|
238  | 
  expand the syntax to the more verbose \cmd{function} form, to see
 | 
|
239  | 
what is actually going on.%  | 
|
| 21212 | 240  | 
\end{isamarkuptext}%
 | 
241  | 
\isamarkuptrue%  | 
|
242  | 
%  | 
|
| 23188 | 243  | 
\isamarkupsection{Termination%
 | 
244  | 
}  | 
|
245  | 
\isamarkuptrue%  | 
|
246  | 
%  | 
|
247  | 
\begin{isamarkuptext}%
 | 
|
248  | 
\label{termination}
 | 
|
| 23805 | 249  | 
  The method \isa{lexicographic{\isacharunderscore}order} is the default method for
 | 
250  | 
termination proofs. It can prove termination of a  | 
|
| 23188 | 251  | 
certain class of functions by searching for a suitable lexicographic  | 
252  | 
combination of size measures. Of course, not all functions have such  | 
|
| 23805 | 253  | 
a simple termination argument. For them, we can specify the termination  | 
254  | 
relation manually.%  | 
|
| 23188 | 255  | 
\end{isamarkuptext}%
 | 
256  | 
\isamarkuptrue%  | 
|
257  | 
%  | 
|
258  | 
\isamarkupsubsection{The {\tt relation} method%
 | 
|
| 21212 | 259  | 
}  | 
260  | 
\isamarkuptrue%  | 
|
261  | 
%  | 
|
262  | 
\begin{isamarkuptext}%
 | 
|
263  | 
Consider the following function, which sums up natural numbers up to  | 
|
| 22065 | 264  | 
  \isa{N}, using a counter \isa{i}:%
 | 
| 21212 | 265  | 
\end{isamarkuptext}%
 | 
266  | 
\isamarkuptrue%  | 
|
267  | 
\isacommand{function}\isamarkupfalse%
 | 
|
268  | 
\ sum\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
|
269  | 
\isakeyword{where}\isanewline
 | 
|
270  | 
\ \ {\isachardoublequoteopen}sum\ i\ N\ {\isacharequal}\ {\isacharparenleft}if\ i\ {\isachargreater}\ N\ then\ {\isadigit{0}}\ else\ i\ {\isacharplus}\ sum\ {\isacharparenleft}Suc\ i{\isacharparenright}\ N{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
271  | 
%  | 
|
272  | 
\isadelimproof  | 
|
| 22065 | 273  | 
%  | 
| 21212 | 274  | 
\endisadelimproof  | 
275  | 
%  | 
|
276  | 
\isatagproof  | 
|
277  | 
\isacommand{by}\isamarkupfalse%
 | 
|
278  | 
\ pat{\isacharunderscore}completeness\ auto%
 | 
|
279  | 
\endisatagproof  | 
|
280  | 
{\isafoldproof}%
 | 
|
281  | 
%  | 
|
282  | 
\isadelimproof  | 
|
283  | 
%  | 
|
284  | 
\endisadelimproof  | 
|
285  | 
%  | 
|
286  | 
\begin{isamarkuptext}%
 | 
|
| 22065 | 287  | 
\noindent The \isa{lexicographic{\isacharunderscore}order} method fails on this example, because none of the
 | 
| 23805 | 288  | 
arguments decreases in the recursive call, with respect to the standard size ordering.  | 
289  | 
To prove termination manually, we must provide a custom wellfounded relation.  | 
|
| 21212 | 290  | 
|
291  | 
  The termination argument for \isa{sum} is based on the fact that
 | 
|
292  | 
  the \emph{difference} between \isa{i} and \isa{N} gets
 | 
|
293  | 
  smaller in every step, and that the recursion stops when \isa{i}
 | 
|
| 23805 | 294  | 
  is greater than \isa{N}. Phrased differently, the expression 
 | 
295  | 
  \isa{N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i} always decreases.
 | 
|
| 21212 | 296  | 
|
| 22065 | 297  | 
We can use this expression as a measure function suitable to prove termination.%  | 
| 21212 | 298  | 
\end{isamarkuptext}%
 | 
299  | 
\isamarkuptrue%  | 
|
300  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
| 23805 | 301  | 
\isanewline  | 
| 21212 | 302  | 
%  | 
303  | 
\isadelimproof  | 
|
| 22065 | 304  | 
%  | 
| 21212 | 305  | 
\endisadelimproof  | 
306  | 
%  | 
|
307  | 
\isatagproof  | 
|
| 23188 | 308  | 
\isacommand{apply}\isamarkupfalse%
 | 
309  | 
\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}%
 | 
|
310  | 
\begin{isamarkuptxt}%
 | 
|
311  | 
The \cmd{termination} command sets up the termination goal for the
 | 
|
312  | 
  specified function \isa{sum}. If the function name is omitted, it
 | 
|
313  | 
implicitly refers to the last function definition.  | 
|
314  | 
||
315  | 
  The \isa{relation} method takes a relation of
 | 
|
316  | 
  type \isa{{\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set}, where \isa{{\isacharprime}a} is the argument type of
 | 
|
317  | 
the function. If the function has multiple curried arguments, then  | 
|
318  | 
these are packed together into a tuple, as it happened in the above  | 
|
319  | 
example.  | 
|
320  | 
||
321  | 
  The predefined function \isa{measure{\isasymColon}{\isacharparenleft}{\isacharprime}a\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ {\isacharparenleft}{\isacharprime}a\ {\isasymtimes}\ {\isacharprime}a{\isacharparenright}\ set} constructs a
 | 
|
322  | 
wellfounded relation from a mapping into the natural numbers (a  | 
|
323  | 
  \emph{measure function}). 
 | 
|
324  | 
||
325  | 
  After the invocation of \isa{relation}, we must prove that (a)
 | 
|
326  | 
the relation we supplied is wellfounded, and (b) that the arguments  | 
|
327  | 
of recursive calls indeed decrease with respect to the  | 
|
328  | 
relation:  | 
|
329  | 
||
330  | 
  \begin{isabelle}%
 | 
|
331  | 
\ {\isadigit{1}}{\isachardot}\ wf\ {\isacharparenleft}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}{\isacharparenright}\isanewline
 | 
|
332  | 
\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}i\ N{\isachardot}\ {\isasymnot}\ N\ {\isacharless}\ i\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isacharparenleft}Suc\ i{\isacharcomma}\ N{\isacharparenright}{\isacharcomma}\ i{\isacharcomma}\ N{\isacharparenright}\ {\isasymin}\ measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharparenright}%
 | 
|
333  | 
\end{isabelle}
 | 
|
334  | 
||
335  | 
  These goals are all solved by \isa{auto}:%
 | 
|
336  | 
\end{isamarkuptxt}%
 | 
|
337  | 
\isamarkuptrue%  | 
|
338  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
339  | 
\ auto\isanewline  | 
|
340  | 
\isacommand{done}\isamarkupfalse%
 | 
|
341  | 
%  | 
|
| 21212 | 342  | 
\endisatagproof  | 
343  | 
{\isafoldproof}%
 | 
|
344  | 
%  | 
|
345  | 
\isadelimproof  | 
|
346  | 
%  | 
|
347  | 
\endisadelimproof  | 
|
348  | 
%  | 
|
349  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 350  | 
Let us complicate the function a little, by adding some more  | 
| 22065 | 351  | 
recursive calls:%  | 
| 21212 | 352  | 
\end{isamarkuptext}%
 | 
353  | 
\isamarkuptrue%  | 
|
354  | 
\isacommand{function}\isamarkupfalse%
 | 
|
355  | 
\ foo\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
|
356  | 
\isakeyword{where}\isanewline
 | 
|
357  | 
\ \ {\isachardoublequoteopen}foo\ i\ N\ {\isacharequal}\ {\isacharparenleft}if\ i\ {\isachargreater}\ N\ \isanewline
 | 
|
358  | 
\ \ \ \ \ \ \ \ \ \ \ \ \ \ then\ {\isacharparenleft}if\ N\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isadigit{0}}\ else\ foo\ {\isadigit{0}}\ {\isacharparenleft}N\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}\isanewline
 | 
|
359  | 
\ \ \ \ \ \ \ \ \ \ \ \ \ \ else\ i\ {\isacharplus}\ foo\ {\isacharparenleft}Suc\ i{\isacharparenright}\ N{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
360  | 
%  | 
|
361  | 
\isadelimproof  | 
|
362  | 
%  | 
|
363  | 
\endisadelimproof  | 
|
364  | 
%  | 
|
365  | 
\isatagproof  | 
|
366  | 
\isacommand{by}\isamarkupfalse%
 | 
|
367  | 
\ pat{\isacharunderscore}completeness\ auto%
 | 
|
368  | 
\endisatagproof  | 
|
369  | 
{\isafoldproof}%
 | 
|
370  | 
%  | 
|
371  | 
\isadelimproof  | 
|
372  | 
%  | 
|
373  | 
\endisadelimproof  | 
|
374  | 
%  | 
|
375  | 
\begin{isamarkuptext}%
 | 
|
376  | 
When \isa{i} has reached \isa{N}, it starts at zero again
 | 
|
377  | 
  and \isa{N} is decremented.
 | 
|
378  | 
This corresponds to a nested  | 
|
379  | 
loop where one index counts up and the other down. Termination can  | 
|
380  | 
be proved using a lexicographic combination of two measures, namely  | 
|
| 22065 | 381  | 
  the value of \isa{N} and the above difference. The \isa{measures} combinator generalizes \isa{measure} by taking a
 | 
382  | 
list of measure functions.%  | 
|
| 21212 | 383  | 
\end{isamarkuptext}%
 | 
384  | 
\isamarkuptrue%  | 
|
385  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
386  | 
\ \isanewline  | 
|
387  | 
%  | 
|
388  | 
\isadelimproof  | 
|
| 22065 | 389  | 
%  | 
| 21212 | 390  | 
\endisadelimproof  | 
391  | 
%  | 
|
392  | 
\isatagproof  | 
|
393  | 
\isacommand{by}\isamarkupfalse%
 | 
|
| 21346 | 394  | 
\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measures\ {\isacharbrackleft}{\isasymlambda}{\isacharparenleft}i{\isacharcomma}\ N{\isacharparenright}{\isachardot}\ N{\isacharcomma}\ {\isasymlambda}{\isacharparenleft}i{\isacharcomma}N{\isacharparenright}{\isachardot}\ N\ {\isacharplus}\ {\isadigit{1}}\ {\isacharminus}\ i{\isacharbrackright}{\isachardoublequoteclose}{\isacharparenright}\ auto%
 | 
| 21212 | 395  | 
\endisatagproof  | 
396  | 
{\isafoldproof}%
 | 
|
397  | 
%  | 
|
398  | 
\isadelimproof  | 
|
399  | 
%  | 
|
400  | 
\endisadelimproof  | 
|
401  | 
%  | 
|
| 23188 | 402  | 
\isamarkupsubsection{How \isa{lexicographic{\isacharunderscore}order} works%
 | 
| 23003 | 403  | 
}  | 
404  | 
\isamarkuptrue%  | 
|
405  | 
%  | 
|
406  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 407  | 
To see how the automatic termination proofs work, let's look at an  | 
408  | 
  example where it fails\footnote{For a detailed discussion of the
 | 
|
409  | 
  termination prover, see \cite{bulwahnKN07}}:
 | 
|
410  | 
||
411  | 
\end{isamarkuptext}  
 | 
|
412  | 
\cmd{fun} \isa{fails\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat\ {\isasymRightarrow}\ nat\ list\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
 | 
|
413  | 
\cmd{where}\\%
 | 
|
414  | 
\hspace*{2ex}\isa{{\isachardoublequote}fails\ a\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ a{\isachardoublequote}}\\%
 | 
|
415  | 
|\hspace*{1.5ex}\isa{{\isachardoublequote}fails\ a\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}\ {\isacharequal}\ fails\ {\isacharparenleft}x\ {\isacharplus}\ a{\isacharparenright}\ {\isacharparenleft}x{\isacharhash}xs{\isacharparenright}{\isachardoublequote}}\\
 | 
|
416  | 
\begin{isamarkuptext}
 | 
|
417  | 
||
418  | 
\noindent Isabelle responds with the following error:  | 
|
419  | 
||
420  | 
\begin{isabelle}
 | 
|
| 23805 | 421  | 
*** Unfinished subgoals:\newline  | 
422  | 
*** (a, 1, <):\newline  | 
|
423  | 
*** \ 1.~\isa{{\isasymAnd}x{\isachardot}\ x\ {\isacharequal}\ {\isadigit{0}}}\newline
 | 
|
424  | 
*** (a, 1, <=):\newline  | 
|
425  | 
*** \ 1.~False\newline  | 
|
426  | 
*** (a, 2, <):\newline  | 
|
427  | 
*** \ 1.~False\newline  | 
|
| 23188 | 428  | 
*** Calls:\newline  | 
429  | 
*** a) \isa{{\isacharparenleft}a{\isacharcomma}\ x\ {\isacharhash}\ xs{\isacharparenright}\ {\isacharminus}{\isacharminus}{\isachargreater}{\isachargreater}\ {\isacharparenleft}x\ {\isacharplus}\ a{\isacharcomma}\ x\ {\isacharhash}\ xs{\isacharparenright}}\newline
 | 
|
430  | 
*** Measures:\newline  | 
|
431  | 
*** 1) \isa{{\isasymlambda}x{\isachardot}\ size\ {\isacharparenleft}fst\ x{\isacharparenright}}\newline
 | 
|
432  | 
*** 2) \isa{{\isasymlambda}x{\isachardot}\ size\ {\isacharparenleft}snd\ x{\isacharparenright}}\newline
 | 
|
| 23805 | 433  | 
*** Result matrix:\newline  | 
434  | 
*** \ \ \ \ 1\ \ 2 \newline  | 
|
435  | 
*** a: ? <= \newline  | 
|
436  | 
*** Could not find lexicographic termination order.\newline  | 
|
| 23188 | 437  | 
*** At command "fun".\newline  | 
438  | 
\end{isabelle}%
 | 
|
| 23003 | 439  | 
\end{isamarkuptext}%
 | 
440  | 
\isamarkuptrue%  | 
|
441  | 
%  | 
|
442  | 
\begin{isamarkuptext}%
 | 
|
| 23805 | 443  | 
The the key to this error message is the matrix at the bottom. The rows  | 
| 23188 | 444  | 
of that matrix correspond to the different recursive calls (In our  | 
445  | 
case, there is just one). The columns are the function's arguments  | 
|
446  | 
(expressed through different measure functions, which map the  | 
|
447  | 
argument tuple to a natural number).  | 
|
448  | 
||
449  | 
The contents of the matrix summarize what is known about argument  | 
|
450  | 
  descents: The second argument has a weak descent (\isa{{\isacharless}{\isacharequal}}) at the
 | 
|
451  | 
recursive call, and for the first argument nothing could be proved,  | 
|
| 23805 | 452  | 
  which is expressed by \isa{{\isacharquery}}. In general, there are the values
 | 
453  | 
  \isa{{\isacharless}}, \isa{{\isacharless}{\isacharequal}} and \isa{{\isacharquery}}.
 | 
|
| 23188 | 454  | 
|
455  | 
For the failed proof attempts, the unfinished subgoals are also  | 
|
| 23805 | 456  | 
printed. Looking at these will often point to a missing lemma.  | 
| 23188 | 457  | 
|
458  | 
% As a more real example, here is quicksort:%  | 
|
| 23003 | 459  | 
\end{isamarkuptext}%
 | 
460  | 
\isamarkuptrue%  | 
|
461  | 
%  | 
|
| 21212 | 462  | 
\isamarkupsection{Mutual Recursion%
 | 
463  | 
}  | 
|
464  | 
\isamarkuptrue%  | 
|
465  | 
%  | 
|
466  | 
\begin{isamarkuptext}%
 | 
|
467  | 
If two or more functions call one another mutually, they have to be defined  | 
|
| 23188 | 468  | 
  in one step. Here are \isa{even} and \isa{odd}:%
 | 
| 21212 | 469  | 
\end{isamarkuptext}%
 | 
470  | 
\isamarkuptrue%  | 
|
471  | 
\isacommand{function}\isamarkupfalse%
 | 
|
| 22065 | 472  | 
\ even\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
 | 
473  | 
\ \ \ \ \isakeyword{and}\ odd\ \ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
 | 
|
| 21212 | 474  | 
\isakeyword{where}\isanewline
 | 
475  | 
\ \ {\isachardoublequoteopen}even\ {\isadigit{0}}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
 | 
|
476  | 
{\isacharbar}\ {\isachardoublequoteopen}odd\ {\isadigit{0}}\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
 | 
|
477  | 
{\isacharbar}\ {\isachardoublequoteopen}even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ odd\ n{\isachardoublequoteclose}\isanewline
 | 
|
478  | 
{\isacharbar}\ {\isachardoublequoteopen}odd\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ even\ n{\isachardoublequoteclose}\isanewline
 | 
|
479  | 
%  | 
|
480  | 
\isadelimproof  | 
|
| 22065 | 481  | 
%  | 
| 21212 | 482  | 
\endisadelimproof  | 
483  | 
%  | 
|
484  | 
\isatagproof  | 
|
485  | 
\isacommand{by}\isamarkupfalse%
 | 
|
486  | 
\ pat{\isacharunderscore}completeness\ auto%
 | 
|
487  | 
\endisatagproof  | 
|
488  | 
{\isafoldproof}%
 | 
|
489  | 
%  | 
|
490  | 
\isadelimproof  | 
|
491  | 
%  | 
|
492  | 
\endisadelimproof  | 
|
493  | 
%  | 
|
494  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 495  | 
To eliminate the mutual dependencies, Isabelle internally  | 
| 21212 | 496  | 
creates a single function operating on the sum  | 
| 23188 | 497  | 
  type \isa{nat\ {\isacharplus}\ nat}. Then, \isa{even} and \isa{odd} are
 | 
498  | 
defined as projections. Consequently, termination has to be proved  | 
|
| 21212 | 499  | 
simultaneously for both functions, by specifying a measure on the  | 
500  | 
sum type:%  | 
|
501  | 
\end{isamarkuptext}%
 | 
|
502  | 
\isamarkuptrue%  | 
|
503  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
504  | 
\ \isanewline  | 
|
505  | 
%  | 
|
506  | 
\isadelimproof  | 
|
| 22065 | 507  | 
%  | 
| 21212 | 508  | 
\endisadelimproof  | 
509  | 
%  | 
|
510  | 
\isatagproof  | 
|
511  | 
\isacommand{by}\isamarkupfalse%
 | 
|
| 23188 | 512  | 
\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ case\ x\ of\ Inl\ n\ {\isasymRightarrow}\ n\ {\isacharbar}\ Inr\ n\ {\isasymRightarrow}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\ auto%
 | 
| 22065 | 513  | 
\endisatagproof  | 
514  | 
{\isafoldproof}%
 | 
|
515  | 
%  | 
|
516  | 
\isadelimproof  | 
|
517  | 
%  | 
|
518  | 
\endisadelimproof  | 
|
519  | 
%  | 
|
| 23188 | 520  | 
\begin{isamarkuptext}%
 | 
521  | 
We could also have used \isa{lexicographic{\isacharunderscore}order}, which
 | 
|
522  | 
supports mutual recursive termination proofs to a certain extent.%  | 
|
523  | 
\end{isamarkuptext}%
 | 
|
524  | 
\isamarkuptrue%  | 
|
525  | 
%  | 
|
| 22065 | 526  | 
\isamarkupsubsection{Induction for mutual recursion%
 | 
527  | 
}  | 
|
528  | 
\isamarkuptrue%  | 
|
529  | 
%  | 
|
530  | 
\begin{isamarkuptext}%
 | 
|
531  | 
When functions are mutually recursive, proving properties about them  | 
|
| 23188 | 532  | 
  generally requires simultaneous induction. The induction rule \isa{even{\isacharunderscore}odd{\isachardot}induct}
 | 
533  | 
generated from the above definition reflects this.  | 
|
| 22065 | 534  | 
|
535  | 
  Let us prove something about \isa{even} and \isa{odd}:%
 | 
|
536  | 
\end{isamarkuptext}%
 | 
|
537  | 
\isamarkuptrue%  | 
|
538  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
| 23188 | 539  | 
\ even{\isacharunderscore}odd{\isacharunderscore}mod{\isadigit{2}}{\isacharcolon}\isanewline
 | 
| 22065 | 540  | 
\ \ {\isachardoublequoteopen}even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
541  | 
\ \ {\isachardoublequoteopen}odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}%
 | 
|
542  | 
\isadelimproof  | 
|
543  | 
%  | 
|
544  | 
\endisadelimproof  | 
|
545  | 
%  | 
|
546  | 
\isatagproof  | 
|
547  | 
%  | 
|
548  | 
\begin{isamarkuptxt}%
 | 
|
549  | 
We apply simultaneous induction, specifying the induction variable  | 
|
550  | 
  for both goals, separated by \cmd{and}:%
 | 
|
551  | 
\end{isamarkuptxt}%
 | 
|
552  | 
\isamarkuptrue%  | 
|
553  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
554  | 
\ {\isacharparenleft}induct\ n\ \isakeyword{and}\ n\ rule{\isacharcolon}\ even{\isacharunderscore}odd{\isachardot}induct{\isacharparenright}%
 | 
|
555  | 
\begin{isamarkuptxt}%
 | 
|
556  | 
We get four subgoals, which correspond to the clauses in the  | 
|
557  | 
  definition of \isa{even} and \isa{odd}:
 | 
|
558  | 
  \begin{isabelle}%
 | 
|
559  | 
\ {\isadigit{1}}{\isachardot}\ even\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
 | 
|
560  | 
\ {\isadigit{2}}{\isachardot}\ odd\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}\isanewline
 | 
|
561  | 
\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}\ {\isasymLongrightarrow}\ even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
 | 
|
562  | 
\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ odd\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{1}}{\isacharparenright}%
 | 
|
563  | 
\end{isabelle}
 | 
|
564  | 
Simplification solves the first two goals, leaving us with two  | 
|
565  | 
  statements about the \isa{mod} operation to prove:%
 | 
|
566  | 
\end{isamarkuptxt}%
 | 
|
567  | 
\isamarkuptrue%  | 
|
568  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
569  | 
\ simp{\isacharunderscore}all%
 | 
|
570  | 
\begin{isamarkuptxt}%
 | 
|
571  | 
\begin{isabelle}%
 | 
|
572  | 
\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ odd\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
 | 
|
573  | 
\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ Suc\ {\isadigit{0}}{\isacharparenright}%
 | 
|
574  | 
\end{isabelle} 
 | 
|
575  | 
||
| 23805 | 576  | 
\noindent These can be handled by Isabelle's arithmetic decision procedures.%  | 
| 22065 | 577  | 
\end{isamarkuptxt}%
 | 
578  | 
\isamarkuptrue%  | 
|
579  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
| 23805 | 580  | 
\ arith\isanewline  | 
| 22065 | 581  | 
\isacommand{apply}\isamarkupfalse%
 | 
| 23805 | 582  | 
\ arith\isanewline  | 
| 22065 | 583  | 
\isacommand{done}\isamarkupfalse%
 | 
584  | 
%  | 
|
585  | 
\endisatagproof  | 
|
586  | 
{\isafoldproof}%
 | 
|
587  | 
%  | 
|
588  | 
\isadelimproof  | 
|
589  | 
%  | 
|
590  | 
\endisadelimproof  | 
|
591  | 
%  | 
|
592  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 593  | 
In proofs like this, the simultaneous induction is really essential:  | 
594  | 
Even if we are just interested in one of the results, the other  | 
|
595  | 
one is necessary to strengthen the induction hypothesis. If we leave  | 
|
596  | 
  out the statement about \isa{odd} (by substituting it with \isa{True}), the same proof fails:%
 | 
|
| 22065 | 597  | 
\end{isamarkuptext}%
 | 
598  | 
\isamarkuptrue%  | 
|
599  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
| 23188 | 600  | 
\ failed{\isacharunderscore}attempt{\isacharcolon}\isanewline
 | 
| 22065 | 601  | 
\ \ {\isachardoublequoteopen}even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
602  | 
\ \ {\isachardoublequoteopen}True{\isachardoublequoteclose}\isanewline
 | 
|
603  | 
%  | 
|
604  | 
\isadelimproof  | 
|
605  | 
%  | 
|
606  | 
\endisadelimproof  | 
|
607  | 
%  | 
|
608  | 
\isatagproof  | 
|
609  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
610  | 
\ {\isacharparenleft}induct\ n\ rule{\isacharcolon}\ even{\isacharunderscore}odd{\isachardot}induct{\isacharparenright}%
 | 
|
611  | 
\begin{isamarkuptxt}%
 | 
|
612  | 
\noindent Now the third subgoal is a dead end, since we have no  | 
|
| 23188 | 613  | 
useful induction hypothesis available:  | 
| 22065 | 614  | 
|
615  | 
  \begin{isabelle}%
 | 
|
616  | 
\ {\isadigit{1}}{\isachardot}\ even\ {\isadigit{0}}\ {\isacharequal}\ {\isacharparenleft}{\isadigit{0}}\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
 | 
|
617  | 
\ {\isadigit{2}}{\isachardot}\ True\isanewline
 | 
|
618  | 
\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ True\ {\isasymLongrightarrow}\ even\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}Suc\ n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\isanewline
 | 
|
619  | 
\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ even\ n\ {\isacharequal}\ {\isacharparenleft}n\ mod\ {\isadigit{2}}\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}\ {\isasymLongrightarrow}\ True%
 | 
|
620  | 
\end{isabelle}%
 | 
|
621  | 
\end{isamarkuptxt}%
 | 
|
622  | 
\isamarkuptrue%  | 
|
623  | 
\isacommand{oops}\isamarkupfalse%
 | 
|
624  | 
%  | 
|
| 21212 | 625  | 
\endisatagproof  | 
626  | 
{\isafoldproof}%
 | 
|
627  | 
%  | 
|
628  | 
\isadelimproof  | 
|
629  | 
%  | 
|
630  | 
\endisadelimproof  | 
|
631  | 
%  | 
|
| 23188 | 632  | 
\isamarkupsection{General pattern matching%
 | 
| 22065 | 633  | 
}  | 
634  | 
\isamarkuptrue%  | 
|
635  | 
%  | 
|
| 23805 | 636  | 
\begin{isamarkuptext}%
 | 
637  | 
\label{genpats}%
 | 
|
638  | 
\end{isamarkuptext}%
 | 
|
639  | 
\isamarkuptrue%  | 
|
640  | 
%  | 
|
| 23188 | 641  | 
\isamarkupsubsection{Avoiding automatic pattern splitting%
 | 
| 22065 | 642  | 
}  | 
643  | 
\isamarkuptrue%  | 
|
644  | 
%  | 
|
645  | 
\begin{isamarkuptext}%
 | 
|
646  | 
Up to now, we used pattern matching only on datatypes, and the  | 
|
647  | 
patterns were always disjoint and complete, and if they weren't,  | 
|
648  | 
they were made disjoint automatically like in the definition of  | 
|
649  | 
  \isa{sep} in \S\ref{patmatch}.
 | 
|
650  | 
||
| 23188 | 651  | 
This automatic splitting can significantly increase the number of  | 
652  | 
equations involved, and this is not always desirable. The following  | 
|
653  | 
example shows the problem:  | 
|
| 22065 | 654  | 
|
| 23805 | 655  | 
Suppose we are modeling incomplete knowledge about the world by a  | 
| 23003 | 656  | 
  three-valued datatype, which has values \isa{T}, \isa{F}
 | 
657  | 
  and \isa{X} for true, false and uncertain propositions, respectively.%
 | 
|
| 22065 | 658  | 
\end{isamarkuptext}%
 | 
659  | 
\isamarkuptrue%  | 
|
660  | 
\isacommand{datatype}\isamarkupfalse%
 | 
|
661  | 
\ P{\isadigit{3}}\ {\isacharequal}\ T\ {\isacharbar}\ F\ {\isacharbar}\ X%
 | 
|
662  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 663  | 
\noindent Then the conjunction of such values can be defined as follows:%  | 
| 22065 | 664  | 
\end{isamarkuptext}%
 | 
665  | 
\isamarkuptrue%  | 
|
666  | 
\isacommand{fun}\isamarkupfalse%
 | 
|
667  | 
\ And\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}{\isachardoublequoteclose}\isanewline
 | 
|
668  | 
\isakeyword{where}\isanewline
 | 
|
669  | 
\ \ {\isachardoublequoteopen}And\ T\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
 | 
|
| 23003 | 670  | 
{\isacharbar}\ {\isachardoublequoteopen}And\ p\ T\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
 | 
671  | 
{\isacharbar}\ {\isachardoublequoteopen}And\ p\ F\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
 | 
|
672  | 
{\isacharbar}\ {\isachardoublequoteopen}And\ F\ p\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
 | 
|
673  | 
{\isacharbar}\ {\isachardoublequoteopen}And\ X\ X\ {\isacharequal}\ X{\isachardoublequoteclose}%
 | 
|
| 22065 | 674  | 
\begin{isamarkuptext}%
 | 
675  | 
This definition is useful, because the equations can directly be used  | 
|
| 23805 | 676  | 
as simplification rules rules. But the patterns overlap: For example,  | 
| 23188 | 677  | 
  the expression \isa{And\ T\ T} is matched by both the first and
 | 
678  | 
the second equation. By default, Isabelle makes the patterns disjoint by  | 
|
| 22065 | 679  | 
splitting them up, producing instances:%  | 
680  | 
\end{isamarkuptext}%
 | 
|
681  | 
\isamarkuptrue%  | 
|
682  | 
\isacommand{thm}\isamarkupfalse%
 | 
|
683  | 
\ And{\isachardot}simps%
 | 
|
684  | 
\begin{isamarkuptext}%
 | 
|
685  | 
\isa{And\ T\ {\isacharquery}p\ {\isacharequal}\ {\isacharquery}p\isasep\isanewline%
 | 
|
686  | 
And\ F\ T\ {\isacharequal}\ F\isasep\isanewline%
 | 
|
687  | 
And\ X\ T\ {\isacharequal}\ X\isasep\isanewline%
 | 
|
688  | 
And\ F\ F\ {\isacharequal}\ F\isasep\isanewline%
 | 
|
689  | 
And\ X\ F\ {\isacharequal}\ F\isasep\isanewline%
 | 
|
690  | 
And\ F\ X\ {\isacharequal}\ F\isasep\isanewline%
 | 
|
691  | 
And\ X\ X\ {\isacharequal}\ X}
 | 
|
692  | 
||
693  | 
  \vspace*{1em}
 | 
|
| 23003 | 694  | 
\noindent There are several problems with this:  | 
| 22065 | 695  | 
|
696  | 
  \begin{enumerate}
 | 
|
| 23188 | 697  | 
\item If the datatype has many constructors, there can be an  | 
| 22065 | 698  | 
  explosion of equations. For \isa{And}, we get seven instead of
 | 
| 23003 | 699  | 
five equations, which can be tolerated, but this is just a small  | 
| 22065 | 700  | 
example.  | 
701  | 
||
| 23188 | 702  | 
  \item Since splitting makes the equations \qt{less general}, they
 | 
| 22065 | 703  | 
  do not always match in rewriting. While the term \isa{And\ x\ F}
 | 
| 23188 | 704  | 
  can be simplified to \isa{F} with the original equations, a
 | 
| 22065 | 705  | 
  (manual) case split on \isa{x} is now necessary.
 | 
706  | 
||
707  | 
  \item The splitting also concerns the induction rule \isa{And{\isachardot}induct}. Instead of five premises it now has seven, which
 | 
|
708  | 
means that our induction proofs will have more cases.  | 
|
709  | 
||
710  | 
\item In general, it increases clarity if we get the same definition  | 
|
711  | 
back which we put in.  | 
|
712  | 
  \end{enumerate}
 | 
|
713  | 
||
| 23188 | 714  | 
If we do not want the automatic splitting, we can switch it off by  | 
715  | 
  leaving out the \cmd{sequential} option. However, we will have to
 | 
|
716  | 
  prove that our pattern matching is consistent\footnote{This prevents
 | 
|
717  | 
  us from defining something like \isa{f\ x\ {\isacharequal}\ True} and \isa{f\ x\ {\isacharequal}\ False} simultaneously.}:%
 | 
|
| 22065 | 718  | 
\end{isamarkuptext}%
 | 
719  | 
\isamarkuptrue%  | 
|
720  | 
\isacommand{function}\isamarkupfalse%
 | 
|
721  | 
\ And{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}\ {\isasymRightarrow}\ P{\isadigit{3}}{\isachardoublequoteclose}\isanewline
 | 
|
722  | 
\isakeyword{where}\isanewline
 | 
|
723  | 
\ \ {\isachardoublequoteopen}And{\isadigit{2}}\ T\ p\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
 | 
|
| 23003 | 724  | 
{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ p\ T\ {\isacharequal}\ p{\isachardoublequoteclose}\isanewline
 | 
725  | 
{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ p\ F\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
 | 
|
726  | 
{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ F\ p\ {\isacharequal}\ F{\isachardoublequoteclose}\isanewline
 | 
|
727  | 
{\isacharbar}\ {\isachardoublequoteopen}And{\isadigit{2}}\ X\ X\ {\isacharequal}\ X{\isachardoublequoteclose}%
 | 
|
| 22065 | 728  | 
\isadelimproof  | 
729  | 
%  | 
|
730  | 
\endisadelimproof  | 
|
731  | 
%  | 
|
732  | 
\isatagproof  | 
|
733  | 
%  | 
|
734  | 
\begin{isamarkuptxt}%
 | 
|
| 23188 | 735  | 
\noindent Now let's look at the proof obligations generated by a  | 
| 22065 | 736  | 
function definition. In this case, they are:  | 
737  | 
||
738  | 
  \begin{isabelle}%
 | 
|
739  | 
\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ {\isasymlbrakk}{\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\isanewline
 | 
|
740  | 
\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ \ }{\isasymAnd}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ p{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ x\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ P{\isasymrbrakk}\isanewline
 | 
|
741  | 
\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ }{\isasymLongrightarrow}\ P\isanewline
 | 
|
742  | 
\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
 | 
|
743  | 
\ {\isadigit{3}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
 | 
|
744  | 
\ {\isadigit{4}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
 | 
|
745  | 
\ {\isadigit{5}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
 | 
|
746  | 
\ {\isadigit{6}}{\isachardot}\ {\isasymAnd}p{\isachardot}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ X\isanewline
 | 
|
747  | 
\ {\isadigit{7}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ T{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ pa\isanewline
 | 
|
748  | 
\ {\isadigit{8}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}pa{\isacharcomma}\ F{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
 | 
|
749  | 
\ {\isadigit{9}}{\isachardot}\ {\isasymAnd}p\ pa{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ pa{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ F\isanewline
 | 
|
750  | 
\ {\isadigit{1}}{\isadigit{0}}{\isachardot}\ {\isasymAnd}p{\isachardot}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}\ {\isasymLongrightarrow}\ p\ {\isacharequal}\ X%
 | 
|
| 23188 | 751  | 
\end{isabelle}\vspace{-1.2em}\hspace{3cm}\vdots\vspace{1.2em}
 | 
| 22065 | 752  | 
|
753  | 
The first subgoal expresses the completeness of the patterns. It has  | 
|
754  | 
  the form of an elimination rule and states that every \isa{x} of
 | 
|
| 23188 | 755  | 
  the function's input type must match at least one of the patterns\footnote{Completeness could
 | 
| 22065 | 756  | 
be equivalently stated as a disjunction of existential statements:  | 
| 23188 | 757  | 
\isa{{\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}T{\isacharcomma}\ p{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ T{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}p{\isacharcomma}\ F{\isacharparenright}{\isacharparenright}\ {\isasymor}\ {\isacharparenleft}{\isasymexists}p{\isachardot}\ x\ {\isacharequal}\ {\isacharparenleft}F{\isacharcomma}\ p{\isacharparenright}{\isacharparenright}\ {\isasymor}\ x\ {\isacharequal}\ {\isacharparenleft}X{\isacharcomma}\ X{\isacharparenright}}.}. If the patterns just involve
 | 
758  | 
  datatypes, we can solve it with the \isa{pat{\isacharunderscore}completeness}
 | 
|
759  | 
method:%  | 
|
| 22065 | 760  | 
\end{isamarkuptxt}%
 | 
761  | 
\isamarkuptrue%  | 
|
762  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
763  | 
\ pat{\isacharunderscore}completeness%
 | 
|
764  | 
\begin{isamarkuptxt}%
 | 
|
765  | 
The remaining subgoals express \emph{pattern compatibility}. We do
 | 
|
| 23188 | 766  | 
allow that an input value matches multiple patterns, but in this  | 
| 22065 | 767  | 
case, the result (i.e.~the right hand sides of the equations) must  | 
768  | 
also be equal. For each pair of two patterns, there is one such  | 
|
769  | 
subgoal. Usually this needs injectivity of the constructors, which  | 
|
770  | 
  is used automatically by \isa{auto}.%
 | 
|
771  | 
\end{isamarkuptxt}%
 | 
|
772  | 
\isamarkuptrue%  | 
|
773  | 
\isacommand{by}\isamarkupfalse%
 | 
|
774  | 
\ auto%  | 
|
775  | 
\endisatagproof  | 
|
776  | 
{\isafoldproof}%
 | 
|
777  | 
%  | 
|
778  | 
\isadelimproof  | 
|
779  | 
%  | 
|
780  | 
\endisadelimproof  | 
|
781  | 
%  | 
|
782  | 
\isamarkupsubsection{Non-constructor patterns%
 | 
|
| 21212 | 783  | 
}  | 
784  | 
\isamarkuptrue%  | 
|
785  | 
%  | 
|
786  | 
\begin{isamarkuptext}%
 | 
|
| 23805 | 787  | 
Most of Isabelle's basic types take the form of inductive datatypes,  | 
788  | 
and usually pattern matching works on the constructors of such types.  | 
|
789  | 
  However, this need not be always the case, and the \cmd{function}
 | 
|
790  | 
command handles other kind of patterns, too.  | 
|
| 23188 | 791  | 
|
| 23805 | 792  | 
One well-known instance of non-constructor patterns are  | 
| 23188 | 793  | 
  so-called \emph{$n+k$-patterns}, which are a little controversial in
 | 
794  | 
the functional programming world. Here is the initial fibonacci  | 
|
795  | 
example with $n+k$-patterns:%  | 
|
| 21212 | 796  | 
\end{isamarkuptext}%
 | 
797  | 
\isamarkuptrue%  | 
|
| 23188 | 798  | 
\isacommand{function}\isamarkupfalse%
 | 
799  | 
\ fib{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
|
800  | 
\isakeyword{where}\isanewline
 | 
|
801  | 
\ \ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
 | 
|
802  | 
{\isacharbar}\ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isadigit{1}}\ {\isacharequal}\ {\isadigit{1}}{\isachardoublequoteclose}\isanewline
 | 
|
803  | 
{\isacharbar}\ {\isachardoublequoteopen}fib{\isadigit{2}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ fib{\isadigit{2}}\ n\ {\isacharplus}\ fib{\isadigit{2}}\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
804  | 
%  | 
|
805  | 
\isadelimML  | 
|
806  | 
%  | 
|
807  | 
\endisadelimML  | 
|
808  | 
%  | 
|
809  | 
\isatagML  | 
|
810  | 
%  | 
|
811  | 
\endisatagML  | 
|
812  | 
{\isafoldML}%
 | 
|
813  | 
%  | 
|
814  | 
\isadelimML  | 
|
815  | 
%  | 
|
816  | 
\endisadelimML  | 
|
817  | 
%  | 
|
818  | 
\isadelimproof  | 
|
819  | 
%  | 
|
820  | 
\endisadelimproof  | 
|
821  | 
%  | 
|
822  | 
\isatagproof  | 
|
823  | 
%  | 
|
824  | 
\begin{isamarkuptxt}%
 | 
|
| 23805 | 825  | 
This kind of matching is again justified by the proof of pattern  | 
826  | 
completeness and compatibility.  | 
|
827  | 
The proof obligation for pattern completeness states that every natural number is  | 
|
| 23188 | 828  | 
  either \isa{{\isadigit{0}}}, \isa{{\isadigit{1}}} or \isa{n\ {\isacharplus}\ {\isadigit{2}}}:
 | 
829  | 
||
830  | 
  \begin{isabelle}%
 | 
|
831  | 
\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}P\ x{\isachardot}\ {\isasymlbrakk}x\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ x\ {\isacharequal}\ {\isadigit{1}}\ {\isasymLongrightarrow}\ P{\isacharsemicolon}\ {\isasymAnd}n{\isachardot}\ x\ {\isacharequal}\ n\ {\isacharplus}\ {\isadigit{2}}\ {\isasymLongrightarrow}\ P{\isasymrbrakk}\ {\isasymLongrightarrow}\ P%
 | 
|
832  | 
\end{isabelle}
 | 
|
833  | 
||
834  | 
This is an arithmetic triviality, but unfortunately the  | 
|
835  | 
  \isa{arith} method cannot handle this specific form of an
 | 
|
| 23805 | 836  | 
  elimination rule. However, we can use the method \isa{elim{\isacharunderscore}to{\isacharunderscore}cases} to do an ad-hoc conversion to a disjunction of
 | 
837  | 
existentials, which can then be soved by the arithmetic decision procedure.  | 
|
838  | 
Pattern compatibility and termination are automatic as usual.%  | 
|
| 23188 | 839  | 
\end{isamarkuptxt}%
 | 
840  | 
\isamarkuptrue%  | 
|
841  | 
%  | 
|
842  | 
\endisatagproof  | 
|
843  | 
{\isafoldproof}%
 | 
|
844  | 
%  | 
|
845  | 
\isadelimproof  | 
|
846  | 
%  | 
|
847  | 
\endisadelimproof  | 
|
848  | 
%  | 
|
849  | 
\isadelimML  | 
|
850  | 
%  | 
|
851  | 
\endisadelimML  | 
|
852  | 
%  | 
|
853  | 
\isatagML  | 
|
854  | 
%  | 
|
855  | 
\endisatagML  | 
|
856  | 
{\isafoldML}%
 | 
|
857  | 
%  | 
|
858  | 
\isadelimML  | 
|
859  | 
%  | 
|
860  | 
\endisadelimML  | 
|
861  | 
%  | 
|
862  | 
\isadelimproof  | 
|
863  | 
%  | 
|
864  | 
\endisadelimproof  | 
|
865  | 
%  | 
|
866  | 
\isatagproof  | 
|
867  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
| 23805 | 868  | 
\ elim{\isacharunderscore}to{\isacharunderscore}cases\isanewline
 | 
869  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
870  | 
\ arith\isanewline  | 
|
| 23188 | 871  | 
\isacommand{apply}\isamarkupfalse%
 | 
872  | 
\ auto\isanewline  | 
|
873  | 
\isacommand{done}\isamarkupfalse%
 | 
|
874  | 
%  | 
|
875  | 
\endisatagproof  | 
|
876  | 
{\isafoldproof}%
 | 
|
877  | 
%  | 
|
878  | 
\isadelimproof  | 
|
879  | 
%  | 
|
880  | 
\endisadelimproof  | 
|
881  | 
\isanewline  | 
|
882  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
883  | 
%  | 
|
884  | 
\isadelimproof  | 
|
885  | 
\ %  | 
|
886  | 
\endisadelimproof  | 
|
887  | 
%  | 
|
888  | 
\isatagproof  | 
|
889  | 
\isacommand{by}\isamarkupfalse%
 | 
|
890  | 
\ lexicographic{\isacharunderscore}order%
 | 
|
891  | 
\endisatagproof  | 
|
892  | 
{\isafoldproof}%
 | 
|
893  | 
%  | 
|
894  | 
\isadelimproof  | 
|
895  | 
%  | 
|
896  | 
\endisadelimproof  | 
|
897  | 
%  | 
|
898  | 
\begin{isamarkuptext}%
 | 
|
899  | 
We can stretch the notion of pattern matching even more. The  | 
|
900  | 
following function is not a sensible functional program, but a  | 
|
901  | 
perfectly valid mathematical definition:%  | 
|
902  | 
\end{isamarkuptext}%
 | 
|
903  | 
\isamarkuptrue%  | 
|
904  | 
\isacommand{function}\isamarkupfalse%
 | 
|
905  | 
\ ev\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
 | 
|
906  | 
\isakeyword{where}\isanewline
 | 
|
907  | 
\ \ {\isachardoublequoteopen}ev\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
 | 
|
908  | 
{\isacharbar}\ {\isachardoublequoteopen}ev\ {\isacharparenleft}{\isadigit{2}}\ {\isacharasterisk}\ n\ {\isacharplus}\ {\isadigit{1}}{\isacharparenright}\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
 | 
|
909  | 
%  | 
|
910  | 
\isadelimproof  | 
|
911  | 
%  | 
|
912  | 
\endisadelimproof  | 
|
913  | 
%  | 
|
914  | 
\isatagproof  | 
|
| 23805 | 915  | 
\isacommand{apply}\isamarkupfalse%
 | 
916  | 
\ elim{\isacharunderscore}to{\isacharunderscore}cases\isanewline
 | 
|
| 23188 | 917  | 
\isacommand{by}\isamarkupfalse%
 | 
| 23805 | 918  | 
\ arith{\isacharplus}%
 | 
| 23188 | 919  | 
\endisatagproof  | 
920  | 
{\isafoldproof}%
 | 
|
921  | 
%  | 
|
922  | 
\isadelimproof  | 
|
923  | 
\isanewline  | 
|
924  | 
%  | 
|
925  | 
\endisadelimproof  | 
|
926  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
927  | 
%  | 
|
928  | 
\isadelimproof  | 
|
929  | 
\ %  | 
|
930  | 
\endisadelimproof  | 
|
931  | 
%  | 
|
932  | 
\isatagproof  | 
|
933  | 
\isacommand{by}\isamarkupfalse%
 | 
|
934  | 
\ {\isacharparenleft}relation\ {\isachardoublequoteopen}{\isacharbraceleft}{\isacharbraceright}{\isachardoublequoteclose}{\isacharparenright}\ simp%
 | 
|
935  | 
\endisatagproof  | 
|
936  | 
{\isafoldproof}%
 | 
|
937  | 
%  | 
|
938  | 
\isadelimproof  | 
|
939  | 
%  | 
|
940  | 
\endisadelimproof  | 
|
941  | 
%  | 
|
942  | 
\begin{isamarkuptext}%
 | 
|
943  | 
This general notion of pattern matching gives you the full freedom  | 
|
944  | 
of mathematical specifications. However, as always, freedom should  | 
|
945  | 
be used with care:  | 
|
946  | 
||
947  | 
If we leave the area of constructor  | 
|
948  | 
patterns, we have effectively departed from the world of functional  | 
|
949  | 
programming. This means that it is no longer possible to use the  | 
|
950  | 
code generator, and expect it to generate ML code for our  | 
|
951  | 
definitions. Also, such a specification might not work very well together with  | 
|
952  | 
simplification. Your mileage may vary.%  | 
|
953  | 
\end{isamarkuptext}%
 | 
|
954  | 
\isamarkuptrue%  | 
|
955  | 
%  | 
|
956  | 
\isamarkupsubsection{Conditional equations%
 | 
|
957  | 
}  | 
|
958  | 
\isamarkuptrue%  | 
|
959  | 
%  | 
|
960  | 
\begin{isamarkuptext}%
 | 
|
961  | 
The function package also supports conditional equations, which are  | 
|
962  | 
similar to guards in a language like Haskell. Here is Euclid's  | 
|
963  | 
  algorithm written with conditional patterns\footnote{Note that the
 | 
|
964  | 
patterns are also overlapping in the base case}:%  | 
|
965  | 
\end{isamarkuptext}%
 | 
|
966  | 
\isamarkuptrue%  | 
|
967  | 
\isacommand{function}\isamarkupfalse%
 | 
|
968  | 
\ gcd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
|
969  | 
\isakeyword{where}\isanewline
 | 
|
970  | 
\ \ {\isachardoublequoteopen}gcd\ x\ {\isadigit{0}}\ {\isacharequal}\ x{\isachardoublequoteclose}\isanewline
 | 
|
971  | 
{\isacharbar}\ {\isachardoublequoteopen}gcd\ {\isadigit{0}}\ y\ {\isacharequal}\ y{\isachardoublequoteclose}\isanewline
 | 
|
972  | 
{\isacharbar}\ {\isachardoublequoteopen}x\ {\isacharless}\ y\ {\isasymLongrightarrow}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}\ {\isacharequal}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}y\ {\isacharminus}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
973  | 
{\isacharbar}\ {\isachardoublequoteopen}{\isasymnot}\ x\ {\isacharless}\ y\ {\isasymLongrightarrow}\ gcd\ {\isacharparenleft}Suc\ x{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}\ {\isacharequal}\ gcd\ {\isacharparenleft}x\ {\isacharminus}\ y{\isacharparenright}\ {\isacharparenleft}Suc\ y{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
974  | 
%  | 
|
975  | 
\isadelimproof  | 
|
976  | 
%  | 
|
977  | 
\endisadelimproof  | 
|
978  | 
%  | 
|
979  | 
\isatagproof  | 
|
980  | 
\isacommand{by}\isamarkupfalse%
 | 
|
| 23805 | 981  | 
\ {\isacharparenleft}elim{\isacharunderscore}to{\isacharunderscore}cases{\isacharcomma}\ auto{\isacharcomma}\ arith{\isacharparenright}%
 | 
| 23188 | 982  | 
\endisatagproof  | 
983  | 
{\isafoldproof}%
 | 
|
984  | 
%  | 
|
985  | 
\isadelimproof  | 
|
986  | 
\isanewline  | 
|
987  | 
%  | 
|
988  | 
\endisadelimproof  | 
|
989  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
990  | 
%  | 
|
991  | 
\isadelimproof  | 
|
992  | 
\ %  | 
|
993  | 
\endisadelimproof  | 
|
994  | 
%  | 
|
995  | 
\isatagproof  | 
|
996  | 
\isacommand{by}\isamarkupfalse%
 | 
|
997  | 
\ lexicographic{\isacharunderscore}order%
 | 
|
998  | 
\endisatagproof  | 
|
999  | 
{\isafoldproof}%
 | 
|
1000  | 
%  | 
|
1001  | 
\isadelimproof  | 
|
1002  | 
%  | 
|
1003  | 
\endisadelimproof  | 
|
1004  | 
%  | 
|
1005  | 
\begin{isamarkuptext}%
 | 
|
1006  | 
By now, you can probably guess what the proof obligations for the  | 
|
1007  | 
pattern completeness and compatibility look like.  | 
|
1008  | 
||
1009  | 
Again, functions with conditional patterns are not supported by the  | 
|
1010  | 
code generator.%  | 
|
1011  | 
\end{isamarkuptext}%
 | 
|
1012  | 
\isamarkuptrue%  | 
|
1013  | 
%  | 
|
1014  | 
\isamarkupsubsection{Pattern matching on strings%
 | 
|
1015  | 
}  | 
|
1016  | 
\isamarkuptrue%  | 
|
1017  | 
%  | 
|
1018  | 
\begin{isamarkuptext}%
 | 
|
| 23805 | 1019  | 
As strings (as lists of characters) are normal datatypes, pattern  | 
| 23188 | 1020  | 
matching on them is possible, but somewhat problematic. Consider the  | 
1021  | 
following definition:  | 
|
1022  | 
||
1023  | 
\end{isamarkuptext}
 | 
|
1024  | 
\noindent\cmd{fun} \isa{check\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}string\ {\isasymRightarrow}\ bool{\isachardoublequote}}\\%
 | 
|
1025  | 
\cmd{where}\\%
 | 
|
1026  | 
\hspace*{2ex}\isa{{\isachardoublequote}check\ {\isacharparenleft}{\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequote}}\\%
 | 
|
1027  | 
\isa{{\isacharbar}\ {\isachardoublequote}check\ s\ {\isacharequal}\ False{\isachardoublequote}}
 | 
|
1028  | 
\begin{isamarkuptext}
 | 
|
1029  | 
||
| 23805 | 1030  | 
  \noindent An invocation of the above \cmd{fun} command does not
 | 
| 23188 | 1031  | 
terminate. What is the problem? Strings are lists of characters, and  | 
| 23805 | 1032  | 
characters are a datatype with a lot of constructors. Splitting the  | 
| 23188 | 1033  | 
catch-all pattern thus leads to an explosion of cases, which cannot  | 
1034  | 
be handled by Isabelle.  | 
|
1035  | 
||
1036  | 
There are two things we can do here. Either we write an explicit  | 
|
1037  | 
  \isa{if} on the right hand side, or we can use conditional patterns:%
 | 
|
1038  | 
\end{isamarkuptext}%
 | 
|
1039  | 
\isamarkuptrue%  | 
|
1040  | 
\isacommand{function}\isamarkupfalse%
 | 
|
1041  | 
\ check\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}string\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
 | 
|
1042  | 
\isakeyword{where}\isanewline
 | 
|
1043  | 
\ \ {\isachardoublequoteopen}check\ {\isacharparenleft}{\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}{\isacharparenright}\ {\isacharequal}\ True{\isachardoublequoteclose}\isanewline
 | 
|
1044  | 
{\isacharbar}\ {\isachardoublequoteopen}s\ {\isasymnoteq}\ {\isacharprime}{\isacharprime}good{\isacharprime}{\isacharprime}\ {\isasymLongrightarrow}\ check\ s\ {\isacharequal}\ False{\isachardoublequoteclose}\isanewline
 | 
|
1045  | 
%  | 
|
1046  | 
\isadelimproof  | 
|
1047  | 
%  | 
|
1048  | 
\endisadelimproof  | 
|
1049  | 
%  | 
|
1050  | 
\isatagproof  | 
|
1051  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1052  | 
\ auto%  | 
|
1053  | 
\endisatagproof  | 
|
1054  | 
{\isafoldproof}%
 | 
|
1055  | 
%  | 
|
1056  | 
\isadelimproof  | 
|
1057  | 
%  | 
|
1058  | 
\endisadelimproof  | 
|
| 21212 | 1059  | 
%  | 
| 22065 | 1060  | 
\isamarkupsection{Partiality%
 | 
1061  | 
}  | 
|
1062  | 
\isamarkuptrue%  | 
|
1063  | 
%  | 
|
1064  | 
\begin{isamarkuptext}%
 | 
|
1065  | 
In HOL, all functions are total. A function \isa{f} applied to
 | 
|
| 23188 | 1066  | 
  \isa{x} always has the value \isa{f\ x}, and there is no notion
 | 
| 22065 | 1067  | 
of undefinedness.  | 
| 23188 | 1068  | 
This is why we have to do termination  | 
1069  | 
proofs when defining functions: The proof justifies that the  | 
|
1070  | 
function can be defined by wellfounded recursion.  | 
|
| 22065 | 1071  | 
|
| 23188 | 1072  | 
  However, the \cmd{function} package does support partiality to a
 | 
1073  | 
certain extent. Let's look at the following function which looks  | 
|
1074  | 
for a zero of a given function f.%  | 
|
| 23003 | 1075  | 
\end{isamarkuptext}%
 | 
1076  | 
\isamarkuptrue%  | 
|
1077  | 
\isacommand{function}\isamarkupfalse%
 | 
|
1078  | 
\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
|
1079  | 
\isakeyword{where}\isanewline
 | 
|
1080  | 
\ \ {\isachardoublequoteopen}findzero\ f\ n\ {\isacharequal}\ {\isacharparenleft}if\ f\ n\ {\isacharequal}\ {\isadigit{0}}\ then\ n\ else\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1081  | 
%  | 
|
1082  | 
\isadelimproof  | 
|
1083  | 
%  | 
|
1084  | 
\endisadelimproof  | 
|
1085  | 
%  | 
|
1086  | 
\isatagproof  | 
|
1087  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1088  | 
\ pat{\isacharunderscore}completeness\ auto%
 | 
|
1089  | 
\endisatagproof  | 
|
1090  | 
{\isafoldproof}%
 | 
|
1091  | 
%  | 
|
1092  | 
\isadelimproof  | 
|
1093  | 
%  | 
|
1094  | 
\endisadelimproof  | 
|
1095  | 
%  | 
|
1096  | 
\begin{isamarkuptext}%
 | 
|
| 23805 | 1097  | 
\noindent Clearly, any attempt of a termination proof must fail. And without  | 
| 23003 | 1098  | 
  that, we do not get the usual rules \isa{findzero{\isachardot}simp} and 
 | 
1099  | 
  \isa{findzero{\isachardot}induct}. So what was the definition good for at all?%
 | 
|
1100  | 
\end{isamarkuptext}%
 | 
|
1101  | 
\isamarkuptrue%  | 
|
1102  | 
%  | 
|
1103  | 
\isamarkupsubsection{Domain predicates%
 | 
|
1104  | 
}  | 
|
1105  | 
\isamarkuptrue%  | 
|
1106  | 
%  | 
|
1107  | 
\begin{isamarkuptext}%
 | 
|
1108  | 
The trick is that Isabelle has not only defined the function \isa{findzero}, but also
 | 
|
1109  | 
  a predicate \isa{findzero{\isacharunderscore}dom} that characterizes the values where the function
 | 
|
| 23188 | 1110  | 
  terminates: the \emph{domain} of the function. If we treat a
 | 
1111  | 
partial function just as a total function with an additional domain  | 
|
1112  | 
predicate, we can derive simplification and  | 
|
1113  | 
induction rules as we do for total functions. They are guarded  | 
|
1114  | 
  by domain conditions and are called \isa{psimps} and \isa{pinduct}:%
 | 
|
| 23003 | 1115  | 
\end{isamarkuptext}%
 | 
1116  | 
\isamarkuptrue%  | 
|
| 23805 | 1117  | 
%  | 
| 23003 | 1118  | 
\begin{isamarkuptext}%
 | 
| 23805 | 1119  | 
\noindent\begin{minipage}{0.79\textwidth}\begin{isabelle}%
 | 
| 23003 | 1120  | 
findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}\ {\isasymLongrightarrow}\isanewline
 | 
1121  | 
findzero\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isacharquery}n\ else\ findzero\ {\isacharquery}f\ {\isacharparenleft}Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}%
 | 
|
| 23805 | 1122  | 
\end{isabelle}\end{minipage}
 | 
1123  | 
  \hfill(\isa{findzero{\isachardot}psimps})
 | 
|
1124  | 
  \vspace{1em}
 | 
|
1125  | 
||
1126  | 
  \noindent\begin{minipage}{0.79\textwidth}\begin{isabelle}%
 | 
|
| 23003 | 1127  | 
{\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}{\isacharcomma}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}{\isacharparenright}{\isacharsemicolon}\isanewline
 | 
1128  | 
\isaindent{\ }{\isasymAnd}f\ n{\isachardot}\ {\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ f\ n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ {\isacharquery}P\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ f\ n{\isasymrbrakk}\isanewline
 | 
|
1129  | 
{\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}a{\isadigit{0}}{\isachardot}{\isadigit{0}}\ {\isacharquery}a{\isadigit{1}}{\isachardot}{\isadigit{0}}%
 | 
|
| 23805 | 1130  | 
\end{isabelle}\end{minipage}
 | 
1131  | 
  \hfill(\isa{findzero{\isachardot}pinduct})%
 | 
|
| 23003 | 1132  | 
\end{isamarkuptext}%
 | 
1133  | 
\isamarkuptrue%  | 
|
1134  | 
%  | 
|
1135  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 1136  | 
Remember that all we  | 
1137  | 
are doing here is use some tricks to make a total function appear  | 
|
| 23003 | 1138  | 
  as if it was partial. We can still write the term \isa{findzero\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ {\isadigit{1}}{\isacharparenright}\ {\isadigit{0}}} and like any other term of type \isa{nat} it is equal
 | 
1139  | 
to some natural number, although we might not be able to find out  | 
|
| 23188 | 1140  | 
  which one. The function is \emph{underdefined}.
 | 
| 23003 | 1141  | 
|
| 23805 | 1142  | 
But it is defined enough to prove something interesting about it. We  | 
| 23188 | 1143  | 
  can prove that if \isa{findzero\ f\ n}
 | 
| 23805 | 1144  | 
  terminates, it indeed returns a zero of \isa{f}:%
 | 
| 23003 | 1145  | 
\end{isamarkuptext}%
 | 
1146  | 
\isamarkuptrue%  | 
|
1147  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
1148  | 
\ findzero{\isacharunderscore}zero{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ n{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}%
 | 
|
1149  | 
\isadelimproof  | 
|
1150  | 
%  | 
|
1151  | 
\endisadelimproof  | 
|
1152  | 
%  | 
|
1153  | 
\isatagproof  | 
|
1154  | 
%  | 
|
1155  | 
\begin{isamarkuptxt}%
 | 
|
| 23805 | 1156  | 
\noindent We apply induction as usual, but using the partial induction  | 
| 23003 | 1157  | 
rule:%  | 
1158  | 
\end{isamarkuptxt}%
 | 
|
1159  | 
\isamarkuptrue%  | 
|
1160  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
1161  | 
\ {\isacharparenleft}induct\ f\ n\ rule{\isacharcolon}\ findzero{\isachardot}pinduct{\isacharparenright}%
 | 
|
1162  | 
\begin{isamarkuptxt}%
 | 
|
| 23805 | 1163  | 
\noindent This gives the following subgoals:  | 
| 23003 | 1164  | 
|
1165  | 
  \begin{isabelle}%
 | 
|
1166  | 
\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}f\ n{\isachardot}\ {\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ f\ n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isasymrbrakk}\isanewline
 | 
|
1167  | 
\isaindent{\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}f\ n{\isachardot}\ }{\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ n{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}%
 | 
|
1168  | 
\end{isabelle}
 | 
|
1169  | 
||
| 23805 | 1170  | 
\noindent The hypothesis in our lemma was used to satisfy the first premise in  | 
| 23188 | 1171  | 
  the induction rule. However, we also get \isa{findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}} as a local assumption in the induction step. This
 | 
| 23003 | 1172  | 
  allows to unfold \isa{findzero\ f\ n} using the \isa{psimps}
 | 
| 23188 | 1173  | 
  rule, and the rest is trivial. Since the \isa{psimps} rules carry the
 | 
| 23003 | 1174  | 
  \isa{{\isacharbrackleft}simp{\isacharbrackright}} attribute by default, we just need a single step:%
 | 
1175  | 
\end{isamarkuptxt}%
 | 
|
1176  | 
\isamarkuptrue%  | 
|
1177  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
1178  | 
\ simp\isanewline  | 
|
1179  | 
\isacommand{done}\isamarkupfalse%
 | 
|
1180  | 
%  | 
|
1181  | 
\endisatagproof  | 
|
1182  | 
{\isafoldproof}%
 | 
|
1183  | 
%  | 
|
1184  | 
\isadelimproof  | 
|
1185  | 
%  | 
|
1186  | 
\endisadelimproof  | 
|
1187  | 
%  | 
|
1188  | 
\begin{isamarkuptext}%
 | 
|
1189  | 
Proofs about partial functions are often not harder than for total  | 
|
1190  | 
  functions. Fig.~\ref{findzero_isar} shows a slightly more
 | 
|
1191  | 
complicated proof written in Isar. It is verbose enough to show how  | 
|
1192  | 
partiality comes into play: From the partial induction, we get an  | 
|
1193  | 
additional domain condition hypothesis. Observe how this condition  | 
|
1194  | 
  is applied when calls to \isa{findzero} are unfolded.%
 | 
|
1195  | 
\end{isamarkuptext}%
 | 
|
1196  | 
\isamarkuptrue%  | 
|
1197  | 
%  | 
|
1198  | 
\begin{figure}
 | 
|
| 23188 | 1199  | 
\hrule\vspace{6pt}
 | 
| 23003 | 1200  | 
\begin{minipage}{0.8\textwidth}
 | 
1201  | 
\isabellestyle{it}
 | 
|
1202  | 
\isastyle\isamarkuptrue  | 
|
1203  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
1204  | 
\ {\isachardoublequoteopen}{\isasymlbrakk}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isacharsemicolon}\ x\ {\isasymin}\ {\isacharbraceleft}n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1205  | 
%  | 
|
1206  | 
\isadelimproof  | 
|
1207  | 
%  | 
|
1208  | 
\endisadelimproof  | 
|
1209  | 
%  | 
|
1210  | 
\isatagproof  | 
|
1211  | 
\isacommand{proof}\isamarkupfalse%
 | 
|
1212  | 
\ {\isacharparenleft}induct\ rule{\isacharcolon}\ findzero{\isachardot}pinduct{\isacharparenright}\isanewline
 | 
|
1213  | 
\ \ \isacommand{fix}\isamarkupfalse%
 | 
|
1214  | 
\ f\ n\ \isacommand{assume}\isamarkupfalse%
 | 
|
1215  | 
\ dom{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
| 23188 | 1216  | 
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \isakeyword{and}\ IH{\isacharcolon}\ {\isachardoublequoteopen}{\isasymlbrakk}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharsemicolon}\ x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharbraceright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
1217  | 
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \isakeyword{and}\ x{\isacharunderscore}range{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\isanewline
 | 
|
| 23003 | 1218  | 
\ \ \isacommand{have}\isamarkupfalse%
 | 
1219  | 
\ {\isachardoublequoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1220  | 
\ \ \isacommand{proof}\isamarkupfalse%
 | 
|
1221  | 
\ \isanewline  | 
|
1222  | 
\ \ \ \ \isacommand{assume}\isamarkupfalse%
 | 
|
1223  | 
\ {\isachardoublequoteopen}f\ n\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1224  | 
\ \ \ \ \isacommand{with}\isamarkupfalse%
 | 
|
1225  | 
\ dom\ \isacommand{have}\isamarkupfalse%
 | 
|
1226  | 
\ {\isachardoublequoteopen}findzero\ f\ n\ {\isacharequal}\ n{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
|
1227  | 
\ simp\isanewline  | 
|
1228  | 
\ \ \ \ \isacommand{with}\isamarkupfalse%
 | 
|
1229  | 
\ x{\isacharunderscore}range\ \isacommand{show}\isamarkupfalse%
 | 
|
1230  | 
\ False\ \isacommand{by}\isamarkupfalse%
 | 
|
1231  | 
\ auto\isanewline  | 
|
1232  | 
\ \ \isacommand{qed}\isamarkupfalse%
 | 
|
1233  | 
\isanewline  | 
|
1234  | 
\ \ \isanewline  | 
|
1235  | 
\ \ \isacommand{from}\isamarkupfalse%
 | 
|
1236  | 
\ x{\isacharunderscore}range\ \isacommand{have}\isamarkupfalse%
 | 
|
1237  | 
\ {\isachardoublequoteopen}x\ {\isacharequal}\ n\ {\isasymor}\ x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
|
1238  | 
\ auto\isanewline  | 
|
1239  | 
\ \ \isacommand{thus}\isamarkupfalse%
 | 
|
1240  | 
\ {\isachardoublequoteopen}f\ x\ {\isasymnoteq}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1241  | 
\ \ \isacommand{proof}\isamarkupfalse%
 | 
|
1242  | 
\isanewline  | 
|
1243  | 
\ \ \ \ \isacommand{assume}\isamarkupfalse%
 | 
|
1244  | 
\ {\isachardoublequoteopen}x\ {\isacharequal}\ n{\isachardoublequoteclose}\isanewline
 | 
|
1245  | 
\ \ \ \ \isacommand{with}\isamarkupfalse%
 | 
|
1246  | 
\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
 | 
|
1247  | 
\ {\isacharquery}thesis\ \isacommand{by}\isamarkupfalse%
 | 
|
1248  | 
\ simp\isanewline  | 
|
1249  | 
\ \ \isacommand{next}\isamarkupfalse%
 | 
|
1250  | 
\isanewline  | 
|
1251  | 
\ \ \ \ \isacommand{assume}\isamarkupfalse%
 | 
|
| 23188 | 1252  | 
\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ n{\isacharbraceright}{\isachardoublequoteclose}\isanewline
 | 
| 23003 | 1253  | 
\ \ \ \ \isacommand{with}\isamarkupfalse%
 | 
1254  | 
\ dom\ \isakeyword{and}\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\ \isacommand{have}\isamarkupfalse%
 | 
|
| 23805 | 1255  | 
\ {\isachardoublequoteopen}x\ {\isasymin}\ {\isacharbraceleft}Suc\ n\ {\isachardot}{\isachardot}{\isacharless}\ findzero\ f\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharbraceright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
| 23003 | 1256  | 
\ simp\isanewline  | 
1257  | 
\ \ \ \ \isacommand{with}\isamarkupfalse%
 | 
|
1258  | 
\ IH\ \isakeyword{and}\ {\isacharbackquoteopen}f\ n\ {\isasymnoteq}\ {\isadigit{0}}{\isacharbackquoteclose}\isanewline
 | 
|
1259  | 
\ \ \ \ \isacommand{show}\isamarkupfalse%
 | 
|
1260  | 
\ {\isacharquery}thesis\ \isacommand{by}\isamarkupfalse%
 | 
|
1261  | 
\ simp\isanewline  | 
|
1262  | 
\ \ \isacommand{qed}\isamarkupfalse%
 | 
|
1263  | 
\isanewline  | 
|
1264  | 
\isacommand{qed}\isamarkupfalse%
 | 
|
1265  | 
%  | 
|
1266  | 
\endisatagproof  | 
|
1267  | 
{\isafoldproof}%
 | 
|
1268  | 
%  | 
|
1269  | 
\isadelimproof  | 
|
1270  | 
%  | 
|
1271  | 
\endisadelimproof  | 
|
1272  | 
%  | 
|
1273  | 
\isamarkupfalse\isabellestyle{tt}
 | 
|
| 23188 | 1274  | 
\end{minipage}\vspace{6pt}\hrule
 | 
| 23003 | 1275  | 
\caption{A proof about a partial function}\label{findzero_isar}
 | 
1276  | 
\end{figure}
 | 
|
1277  | 
%  | 
|
1278  | 
\isamarkupsubsection{Partial termination proofs%
 | 
|
1279  | 
}  | 
|
1280  | 
\isamarkuptrue%  | 
|
1281  | 
%  | 
|
1282  | 
\begin{isamarkuptext}%
 | 
|
1283  | 
Now that we have proved some interesting properties about our  | 
|
1284  | 
function, we should turn to the domain predicate and see if it is  | 
|
1285  | 
actually true for some values. Otherwise we would have just proved  | 
|
1286  | 
  lemmas with \isa{False} as a premise.
 | 
|
1287  | 
||
1288  | 
  Essentially, we need some introduction rules for \isa{findzero{\isacharunderscore}dom}. The function package can prove such domain
 | 
|
1289  | 
introduction rules automatically. But since they are not used very  | 
|
| 23188 | 1290  | 
often (they are almost never needed if the function is total), this  | 
1291  | 
functionality is disabled by default for efficiency reasons. So we have to go  | 
|
| 23003 | 1292  | 
  back and ask for them explicitly by passing the \isa{{\isacharparenleft}domintros{\isacharparenright}} option to the function package:
 | 
1293  | 
||
| 23188 | 1294  | 
\vspace{1ex}
 | 
| 23003 | 1295  | 
\noindent\cmd{function} \isa{{\isacharparenleft}domintros{\isacharparenright}\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
 | 
1296  | 
\cmd{where}\isanewline%
 | 
|
1297  | 
\ \ \ldots\\  | 
|
1298  | 
||
| 23188 | 1299  | 
  \noindent Now the package has proved an introduction rule for \isa{findzero{\isacharunderscore}dom}:%
 | 
| 23003 | 1300  | 
\end{isamarkuptext}%
 | 
1301  | 
\isamarkuptrue%  | 
|
1302  | 
\isacommand{thm}\isamarkupfalse%
 | 
|
1303  | 
\ findzero{\isachardot}domintros%
 | 
|
1304  | 
\begin{isamarkuptext}%
 | 
|
1305  | 
\begin{isabelle}%
 | 
|
| 25182 | 1306  | 
{\isacharparenleft}{\isadigit{0}}\ {\isacharless}\ {\isacharquery}f\ {\isacharquery}n\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}%
 | 
| 23003 | 1307  | 
\end{isabelle}
 | 
1308  | 
||
1309  | 
Domain introduction rules allow to show that a given value lies in the  | 
|
1310  | 
domain of a function, if the arguments of all recursive calls  | 
|
1311  | 
  are in the domain as well. They allow to do a \qt{single step} in a
 | 
|
1312  | 
termination proof. Usually, you want to combine them with a suitable  | 
|
1313  | 
induction principle.  | 
|
1314  | 
||
1315  | 
Since our function increases its argument at recursive calls, we  | 
|
1316  | 
  need an induction principle which works \qt{backwards}. We will use
 | 
|
1317  | 
  \isa{inc{\isacharunderscore}induct}, which allows to do induction from a fixed number
 | 
|
1318  | 
  \qt{downwards}:
 | 
|
1319  | 
||
| 23188 | 1320  | 
  \begin{center}\isa{{\isasymlbrakk}{\isacharquery}i\ {\isasymle}\ {\isacharquery}j{\isacharsemicolon}\ {\isacharquery}P\ {\isacharquery}j{\isacharsemicolon}\ {\isasymAnd}i{\isachardot}\ {\isasymlbrakk}i\ {\isacharless}\ {\isacharquery}j{\isacharsemicolon}\ {\isacharquery}P\ {\isacharparenleft}Suc\ i{\isacharparenright}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ i{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharquery}P\ {\isacharquery}i}\hfill(\isa{inc{\isacharunderscore}induct})\end{center}
 | 
| 23003 | 1321  | 
|
| 23188 | 1322  | 
  Figure \ref{findzero_term} gives a detailed Isar proof of the fact
 | 
| 23003 | 1323  | 
  that \isa{findzero} terminates if there is a zero which is greater
 | 
1324  | 
  or equal to \isa{n}. First we derive two useful rules which will
 | 
|
1325  | 
solve the base case and the step case of the induction. The  | 
|
| 23805 | 1326  | 
induction is then straightforward, except for the unusual induction  | 
| 23003 | 1327  | 
principle.%  | 
1328  | 
\end{isamarkuptext}%
 | 
|
1329  | 
\isamarkuptrue%  | 
|
1330  | 
%  | 
|
1331  | 
\begin{figure}
 | 
|
| 23188 | 1332  | 
\hrule\vspace{6pt}
 | 
| 23003 | 1333  | 
\begin{minipage}{0.8\textwidth}
 | 
1334  | 
\isabellestyle{it}
 | 
|
1335  | 
\isastyle\isamarkuptrue  | 
|
1336  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
1337  | 
\ findzero{\isacharunderscore}termination{\isacharcolon}\isanewline
 | 
|
| 23188 | 1338  | 
\ \ \isakeyword{assumes}\ {\isachardoublequoteopen}x\ {\isasymge}\ n{\isachardoublequoteclose}\ \isakeyword{and}\ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
| 23003 | 1339  | 
\ \ \isakeyword{shows}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
1340  | 
%  | 
|
1341  | 
\isadelimproof  | 
|
1342  | 
%  | 
|
1343  | 
\endisadelimproof  | 
|
1344  | 
%  | 
|
1345  | 
\isatagproof  | 
|
1346  | 
\isacommand{proof}\isamarkupfalse%
 | 
|
1347  | 
\ {\isacharminus}\ \isanewline
 | 
|
1348  | 
\ \ \isacommand{have}\isamarkupfalse%
 | 
|
1349  | 
\ base{\isacharcolon}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1350  | 
\ \ \ \ \isacommand{by}\isamarkupfalse%
 | 
|
1351  | 
\ {\isacharparenleft}rule\ findzero{\isachardot}domintros{\isacharparenright}\ {\isacharparenleft}simp\ add{\isacharcolon}{\isacharbackquoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isacharbackquoteclose}{\isacharparenright}\isanewline
 | 
|
1352  | 
\isanewline  | 
|
1353  | 
\ \ \isacommand{have}\isamarkupfalse%
 | 
|
1354  | 
\ step{\isacharcolon}\ {\isachardoublequoteopen}{\isasymAnd}i{\isachardot}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ Suc\ i{\isacharparenright}\ \isanewline
 | 
|
1355  | 
\ \ \ \ {\isasymLongrightarrow}\ findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ i{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1356  | 
\ \ \ \ \isacommand{by}\isamarkupfalse%
 | 
|
1357  | 
\ {\isacharparenleft}rule\ findzero{\isachardot}domintros{\isacharparenright}\ simp\isanewline
 | 
|
1358  | 
\isanewline  | 
|
1359  | 
\ \ \isacommand{from}\isamarkupfalse%
 | 
|
| 23188 | 1360  | 
\ {\isacharbackquoteopen}x\ {\isasymge}\ n{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
 | 
| 23003 | 1361  | 
\ {\isacharquery}thesis\isanewline
 | 
1362  | 
\ \ \isacommand{proof}\isamarkupfalse%
 | 
|
1363  | 
\ {\isacharparenleft}induct\ rule{\isacharcolon}inc{\isacharunderscore}induct{\isacharparenright}\isanewline
 | 
|
1364  | 
\ \ \ \ \isacommand{show}\isamarkupfalse%
 | 
|
| 23188 | 1365  | 
\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ x{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
| 23003 | 1366  | 
\ {\isacharparenleft}rule\ base{\isacharparenright}\isanewline
 | 
1367  | 
\ \ \isacommand{next}\isamarkupfalse%
 | 
|
1368  | 
\isanewline  | 
|
1369  | 
\ \ \ \ \isacommand{fix}\isamarkupfalse%
 | 
|
1370  | 
\ i\ \isacommand{assume}\isamarkupfalse%
 | 
|
1371  | 
\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ Suc\ i{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1372  | 
\ \ \ \ \isacommand{thus}\isamarkupfalse%
 | 
|
| 23188 | 1373  | 
\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ i{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
| 23003 | 1374  | 
\ {\isacharparenleft}rule\ step{\isacharparenright}\isanewline
 | 
1375  | 
\ \ \isacommand{qed}\isamarkupfalse%
 | 
|
1376  | 
\isanewline  | 
|
1377  | 
\isacommand{qed}\isamarkupfalse%
 | 
|
1378  | 
%  | 
|
1379  | 
\endisatagproof  | 
|
1380  | 
{\isafoldproof}%
 | 
|
1381  | 
%  | 
|
1382  | 
\isadelimproof  | 
|
1383  | 
%  | 
|
1384  | 
\endisadelimproof  | 
|
1385  | 
%  | 
|
1386  | 
\isamarkupfalse\isabellestyle{tt}
 | 
|
| 23188 | 1387  | 
\end{minipage}\vspace{6pt}\hrule
 | 
| 23003 | 1388  | 
\caption{Termination proof for \isa{findzero}}\label{findzero_term}
 | 
1389  | 
\end{figure}
 | 
|
1390  | 
%  | 
|
1391  | 
\begin{isamarkuptext}%
 | 
|
1392  | 
Again, the proof given in Fig.~\ref{findzero_term} has a lot of
 | 
|
1393  | 
detail in order to explain the principles. Using more automation, we  | 
|
1394  | 
can also have a short proof:%  | 
|
1395  | 
\end{isamarkuptext}%
 | 
|
1396  | 
\isamarkuptrue%  | 
|
1397  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
1398  | 
\ findzero{\isacharunderscore}termination{\isacharunderscore}short{\isacharcolon}\isanewline
 | 
|
1399  | 
\ \ \isakeyword{assumes}\ zero{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isachargreater}{\isacharequal}\ n{\isachardoublequoteclose}\ \isanewline
 | 
|
1400  | 
\ \ \isakeyword{assumes}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1401  | 
\ \ \isakeyword{shows}\ {\isachardoublequoteopen}findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1402  | 
%  | 
|
1403  | 
\isadelimproof  | 
|
| 23805 | 1404  | 
%  | 
| 23003 | 1405  | 
\endisadelimproof  | 
1406  | 
%  | 
|
1407  | 
\isatagproof  | 
|
1408  | 
\isacommand{using}\isamarkupfalse%
 | 
|
1409  | 
\ zero\isanewline  | 
|
| 23805 | 1410  | 
\isacommand{by}\isamarkupfalse%
 | 
| 23003 | 1411  | 
\ {\isacharparenleft}induct\ rule{\isacharcolon}inc{\isacharunderscore}induct{\isacharparenright}\ {\isacharparenleft}auto\ intro{\isacharcolon}\ findzero{\isachardot}domintros{\isacharparenright}%
 | 
1412  | 
\endisatagproof  | 
|
1413  | 
{\isafoldproof}%
 | 
|
1414  | 
%  | 
|
1415  | 
\isadelimproof  | 
|
1416  | 
%  | 
|
1417  | 
\endisadelimproof  | 
|
1418  | 
%  | 
|
1419  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 1420  | 
\noindent It is simple to combine the partial correctness result with the  | 
| 23003 | 1421  | 
termination lemma:%  | 
1422  | 
\end{isamarkuptext}%
 | 
|
1423  | 
\isamarkuptrue%  | 
|
1424  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
1425  | 
\ findzero{\isacharunderscore}total{\isacharunderscore}correctness{\isacharcolon}\isanewline
 | 
|
1426  | 
\ \ {\isachardoublequoteopen}f\ x\ {\isacharequal}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ f\ {\isacharparenleft}findzero\ f\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1427  | 
%  | 
|
1428  | 
\isadelimproof  | 
|
1429  | 
%  | 
|
1430  | 
\endisadelimproof  | 
|
1431  | 
%  | 
|
1432  | 
\isatagproof  | 
|
1433  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1434  | 
\ {\isacharparenleft}blast\ intro{\isacharcolon}\ findzero{\isacharunderscore}zero\ findzero{\isacharunderscore}termination{\isacharparenright}%
 | 
|
1435  | 
\endisatagproof  | 
|
1436  | 
{\isafoldproof}%
 | 
|
1437  | 
%  | 
|
1438  | 
\isadelimproof  | 
|
1439  | 
%  | 
|
1440  | 
\endisadelimproof  | 
|
1441  | 
%  | 
|
1442  | 
\isamarkupsubsection{Definition of the domain predicate%
 | 
|
1443  | 
}  | 
|
1444  | 
\isamarkuptrue%  | 
|
1445  | 
%  | 
|
1446  | 
\begin{isamarkuptext}%
 | 
|
1447  | 
Sometimes it is useful to know what the definition of the domain  | 
|
| 23805 | 1448  | 
  predicate looks like. Actually, \isa{findzero{\isacharunderscore}dom} is just an
 | 
| 23003 | 1449  | 
abbreviation:  | 
1450  | 
||
1451  | 
  \begin{isabelle}%
 | 
|
| 23805 | 1452  | 
findzero{\isacharunderscore}dom\ {\isasymequiv}\ accp\ findzero{\isacharunderscore}rel%
 | 
| 23003 | 1453  | 
\end{isabelle}
 | 
1454  | 
||
| 23188 | 1455  | 
  The domain predicate is the \emph{accessible part} of a relation \isa{findzero{\isacharunderscore}rel}, which was also created internally by the function
 | 
| 23003 | 1456  | 
  package. \isa{findzero{\isacharunderscore}rel} is just a normal
 | 
| 23188 | 1457  | 
inductive predicate, so we can inspect its definition by  | 
| 23003 | 1458  | 
  looking at the introduction rules \isa{findzero{\isacharunderscore}rel{\isachardot}intros}.
 | 
1459  | 
In our case there is just a single rule:  | 
|
1460  | 
||
1461  | 
  \begin{isabelle}%
 | 
|
1462  | 
{\isacharquery}f\ {\isacharquery}n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ findzero{\isacharunderscore}rel\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ Suc\ {\isacharquery}n{\isacharparenright}\ {\isacharparenleft}{\isacharquery}f{\isacharcomma}\ {\isacharquery}n{\isacharparenright}%
 | 
|
1463  | 
\end{isabelle}
 | 
|
1464  | 
||
| 23188 | 1465  | 
  The predicate \isa{findzero{\isacharunderscore}rel}
 | 
| 23003 | 1466  | 
  describes the \emph{recursion relation} of the function
 | 
1467  | 
definition. The recursion relation is a binary relation on  | 
|
1468  | 
the arguments of the function that relates each argument to its  | 
|
1469  | 
recursive calls. In general, there is one introduction rule for each  | 
|
1470  | 
recursive call.  | 
|
1471  | 
||
| 23188 | 1472  | 
  The predicate \isa{findzero{\isacharunderscore}dom} is the accessible part of
 | 
| 23003 | 1473  | 
that relation. An argument belongs to the accessible part, if it can  | 
| 23188 | 1474  | 
  be reached in a finite number of steps (cf.~its definition in \isa{Accessible{\isacharunderscore}Part{\isachardot}thy}).
 | 
| 23003 | 1475  | 
|
1476  | 
Since the domain predicate is just an abbreviation, you can use  | 
|
| 23805 | 1477  | 
  lemmas for \isa{accp} and \isa{findzero{\isacharunderscore}rel} directly. Some
 | 
1478  | 
  lemmas which are occasionally useful are \isa{accpI}, \isa{accp{\isacharunderscore}downward}, and of course the introduction and elimination rules
 | 
|
| 23003 | 1479  | 
  for the recursion relation \isa{findzero{\isachardot}intros} and \isa{findzero{\isachardot}cases}.%
 | 
1480  | 
\end{isamarkuptext}%
 | 
|
1481  | 
\isamarkuptrue%  | 
|
1482  | 
%  | 
|
1483  | 
\isamarkupsubsection{A Useful Special Case: Tail recursion%
 | 
|
1484  | 
}  | 
|
1485  | 
\isamarkuptrue%  | 
|
1486  | 
%  | 
|
1487  | 
\begin{isamarkuptext}%
 | 
|
1488  | 
The domain predicate is our trick that allows us to model partiality  | 
|
1489  | 
in a world of total functions. The downside of this is that we have  | 
|
1490  | 
to carry it around all the time. The termination proof above allowed  | 
|
1491  | 
  us to replace the abstract \isa{findzero{\isacharunderscore}dom\ {\isacharparenleft}f{\isacharcomma}\ n{\isacharparenright}} by the more
 | 
|
| 23188 | 1492  | 
  concrete \isa{n\ {\isasymle}\ x\ {\isasymand}\ f\ x\ {\isacharequal}\ {\isadigit{0}}}, but the condition is still
 | 
1493  | 
there and can only be discharged for special cases.  | 
|
1494  | 
In particular, the domain predicate guards the unfolding of our  | 
|
| 23003 | 1495  | 
  function, since it is there as a condition in the \isa{psimp}
 | 
1496  | 
rules.  | 
|
1497  | 
||
1498  | 
Now there is an important special case: We can actually get rid  | 
|
1499  | 
  of the condition in the simplification rules, \emph{if the function
 | 
|
1500  | 
is tail-recursive}. The reason is that for all tail-recursive  | 
|
1501  | 
equations there is a total function satisfying them, even if they  | 
|
1502  | 
are non-terminating.  | 
|
1503  | 
||
| 23188 | 1504  | 
% A function is tail recursive, if each call to the function is either  | 
1505  | 
% equal  | 
|
1506  | 
%  | 
|
1507  | 
% So the outer form of the  | 
|
1508  | 
%  | 
|
1509  | 
%if it can be written in the following  | 
|
1510  | 
% form:  | 
|
1511  | 
%  {term[display] "f x = (if COND x then BASE x else f (LOOP x))"}
 | 
|
1512  | 
||
1513  | 
||
| 23003 | 1514  | 
The function package internally does the right construction and can  | 
1515  | 
derive the unconditional simp rules, if we ask it to do so. Luckily,  | 
|
1516  | 
  our \isa{findzero} function is tail-recursive, so we can just go
 | 
|
1517  | 
  back and add another option to the \cmd{function} command:
 | 
|
1518  | 
||
| 23188 | 1519  | 
\vspace{1ex}
 | 
| 23003 | 1520  | 
\noindent\cmd{function} \isa{{\isacharparenleft}domintros{\isacharcomma}\ tailrec{\isacharparenright}\ findzero\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}nat\ {\isasymRightarrow}\ nat{\isacharparenright}\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat{\isachardoublequote}}\\%
 | 
1521  | 
\cmd{where}\isanewline%
 | 
|
1522  | 
\ \ \ldots\\%  | 
|
1523  | 
||
1524  | 
||
| 23188 | 1525  | 
\noindent Now, we actually get unconditional simplification rules, even  | 
| 23003 | 1526  | 
though the function is partial:%  | 
1527  | 
\end{isamarkuptext}%
 | 
|
1528  | 
\isamarkuptrue%  | 
|
1529  | 
\isacommand{thm}\isamarkupfalse%
 | 
|
1530  | 
\ findzero{\isachardot}simps%
 | 
|
1531  | 
\begin{isamarkuptext}%
 | 
|
1532  | 
\begin{isabelle}%
 | 
|
1533  | 
findzero\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}f\ {\isacharquery}n\ {\isacharequal}\ {\isadigit{0}}\ then\ {\isacharquery}n\ else\ findzero\ {\isacharquery}f\ {\isacharparenleft}Suc\ {\isacharquery}n{\isacharparenright}{\isacharparenright}%
 | 
|
1534  | 
\end{isabelle}
 | 
|
1535  | 
||
| 23188 | 1536  | 
\noindent Of course these would make the simplifier loop, so we better remove  | 
| 23003 | 1537  | 
them from the simpset:%  | 
1538  | 
\end{isamarkuptext}%
 | 
|
1539  | 
\isamarkuptrue%  | 
|
1540  | 
\isacommand{declare}\isamarkupfalse%
 | 
|
1541  | 
\ findzero{\isachardot}simps{\isacharbrackleft}simp\ del{\isacharbrackright}%
 | 
|
1542  | 
\begin{isamarkuptext}%
 | 
|
| 23188 | 1543  | 
Getting rid of the domain conditions in the simplification rules is  | 
1544  | 
not only useful because it simplifies proofs. It is also required in  | 
|
1545  | 
order to use Isabelle's code generator to generate ML code  | 
|
1546  | 
from a function definition.  | 
|
1547  | 
Since the code generator only works with equations, it cannot be  | 
|
1548  | 
  used with \isa{psimp} rules. Thus, in order to generate code for
 | 
|
1549  | 
partial functions, they must be defined as a tail recursion.  | 
|
1550  | 
Luckily, many functions have a relatively natural tail recursive  | 
|
1551  | 
definition.%  | 
|
| 22065 | 1552  | 
\end{isamarkuptext}%
 | 
1553  | 
\isamarkuptrue%  | 
|
1554  | 
%  | 
|
1555  | 
\isamarkupsection{Nested recursion%
 | 
|
| 21212 | 1556  | 
}  | 
1557  | 
\isamarkuptrue%  | 
|
1558  | 
%  | 
|
1559  | 
\begin{isamarkuptext}%
 | 
|
| 23003 | 1560  | 
Recursive calls which are nested in one another frequently cause  | 
1561  | 
complications, since their termination proof can depend on a partial  | 
|
1562  | 
correctness property of the function itself.  | 
|
1563  | 
||
1564  | 
  As a small example, we define the \qt{nested zero} function:%
 | 
|
1565  | 
\end{isamarkuptext}%
 | 
|
1566  | 
\isamarkuptrue%  | 
|
1567  | 
\isacommand{function}\isamarkupfalse%
 | 
|
1568  | 
\ nz\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
|
1569  | 
\isakeyword{where}\isanewline
 | 
|
1570  | 
\ \ {\isachardoublequoteopen}nz\ {\isadigit{0}}\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1571  | 
{\isacharbar}\ {\isachardoublequoteopen}nz\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharequal}\ nz\ {\isacharparenleft}nz\ n{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1572  | 
%  | 
|
1573  | 
\isadelimproof  | 
|
1574  | 
%  | 
|
1575  | 
\endisadelimproof  | 
|
1576  | 
%  | 
|
1577  | 
\isatagproof  | 
|
1578  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1579  | 
\ pat{\isacharunderscore}completeness\ auto%
 | 
|
1580  | 
\endisatagproof  | 
|
1581  | 
{\isafoldproof}%
 | 
|
1582  | 
%  | 
|
1583  | 
\isadelimproof  | 
|
1584  | 
%  | 
|
1585  | 
\endisadelimproof  | 
|
1586  | 
%  | 
|
1587  | 
\begin{isamarkuptext}%
 | 
|
1588  | 
If we attempt to prove termination using the identity measure on  | 
|
1589  | 
naturals, this fails:%  | 
|
1590  | 
\end{isamarkuptext}%
 | 
|
1591  | 
\isamarkuptrue%  | 
|
1592  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
1593  | 
\isanewline  | 
|
1594  | 
%  | 
|
1595  | 
\isadelimproof  | 
|
1596  | 
\ \ %  | 
|
1597  | 
\endisadelimproof  | 
|
1598  | 
%  | 
|
1599  | 
\isatagproof  | 
|
1600  | 
\isacommand{apply}\isamarkupfalse%
 | 
|
1601  | 
\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}n{\isachardot}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\isanewline
 | 
|
1602  | 
\ \ \isacommand{apply}\isamarkupfalse%
 | 
|
1603  | 
\ auto%  | 
|
1604  | 
\begin{isamarkuptxt}%
 | 
|
1605  | 
We get stuck with the subgoal  | 
|
1606  | 
||
1607  | 
  \begin{isabelle}%
 | 
|
1608  | 
\ {\isadigit{1}}{\isachardot}\ {\isasymAnd}n{\isachardot}\ nz{\isacharunderscore}dom\ n\ {\isasymLongrightarrow}\ nz\ n\ {\isacharless}\ Suc\ n%
 | 
|
1609  | 
\end{isabelle}
 | 
|
1610  | 
||
1611  | 
  Of course this statement is true, since we know that \isa{nz} is
 | 
|
1612  | 
the zero function. And in fact we have no problem proving this  | 
|
1613  | 
property by induction.%  | 
|
1614  | 
\end{isamarkuptxt}%
 | 
|
1615  | 
\isamarkuptrue%  | 
|
1616  | 
%  | 
|
1617  | 
\endisatagproof  | 
|
1618  | 
{\isafoldproof}%
 | 
|
1619  | 
%  | 
|
1620  | 
\isadelimproof  | 
|
1621  | 
%  | 
|
1622  | 
\endisadelimproof  | 
|
1623  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
1624  | 
\ nz{\isacharunderscore}is{\isacharunderscore}zero{\isacharcolon}\ {\isachardoublequoteopen}nz{\isacharunderscore}dom\ n\ {\isasymLongrightarrow}\ nz\ n\ {\isacharequal}\ {\isadigit{0}}{\isachardoublequoteclose}\isanewline
 | 
|
1625  | 
%  | 
|
1626  | 
\isadelimproof  | 
|
1627  | 
\ \ %  | 
|
1628  | 
\endisadelimproof  | 
|
1629  | 
%  | 
|
1630  | 
\isatagproof  | 
|
1631  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1632  | 
\ {\isacharparenleft}induct\ rule{\isacharcolon}nz{\isachardot}pinduct{\isacharparenright}\ auto%
 | 
|
1633  | 
\endisatagproof  | 
|
1634  | 
{\isafoldproof}%
 | 
|
1635  | 
%  | 
|
1636  | 
\isadelimproof  | 
|
1637  | 
%  | 
|
1638  | 
\endisadelimproof  | 
|
1639  | 
%  | 
|
1640  | 
\begin{isamarkuptext}%
 | 
|
1641  | 
We formulate this as a partial correctness lemma with the condition  | 
|
1642  | 
  \isa{nz{\isacharunderscore}dom\ n}. This allows us to prove it with the \isa{pinduct} rule before we have proved termination. With this lemma,
 | 
|
1643  | 
the termination proof works as expected:%  | 
|
1644  | 
\end{isamarkuptext}%
 | 
|
1645  | 
\isamarkuptrue%  | 
|
1646  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
1647  | 
\isanewline  | 
|
1648  | 
%  | 
|
1649  | 
\isadelimproof  | 
|
1650  | 
\ \ %  | 
|
1651  | 
\endisadelimproof  | 
|
1652  | 
%  | 
|
1653  | 
\isatagproof  | 
|
1654  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1655  | 
\ {\isacharparenleft}relation\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}n{\isachardot}\ n{\isacharparenright}{\isachardoublequoteclose}{\isacharparenright}\ {\isacharparenleft}auto\ simp{\isacharcolon}\ nz{\isacharunderscore}is{\isacharunderscore}zero{\isacharparenright}%
 | 
|
1656  | 
\endisatagproof  | 
|
1657  | 
{\isafoldproof}%
 | 
|
1658  | 
%  | 
|
1659  | 
\isadelimproof  | 
|
1660  | 
%  | 
|
1661  | 
\endisadelimproof  | 
|
1662  | 
%  | 
|
1663  | 
\begin{isamarkuptext}%
 | 
|
1664  | 
As a general strategy, one should prove the statements needed for  | 
|
1665  | 
termination as a partial property first. Then they can be used to do  | 
|
1666  | 
the termination proof. This also works for less trivial  | 
|
| 23188 | 1667  | 
  examples. Figure \ref{f91} defines the 91-function, a well-known
 | 
1668  | 
challenge problem due to John McCarthy, and proves its termination.%  | 
|
| 23003 | 1669  | 
\end{isamarkuptext}%
 | 
1670  | 
\isamarkuptrue%  | 
|
1671  | 
%  | 
|
1672  | 
\begin{figure}
 | 
|
| 23188 | 1673  | 
\hrule\vspace{6pt}
 | 
| 23003 | 1674  | 
\begin{minipage}{0.8\textwidth}
 | 
1675  | 
\isabellestyle{it}
 | 
|
1676  | 
\isastyle\isamarkuptrue  | 
|
1677  | 
\isacommand{function}\isamarkupfalse%
 | 
|
| 23188 | 1678  | 
\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ nat{\isachardoublequoteclose}\isanewline
 | 
| 23003 | 1679  | 
\isakeyword{where}\isanewline
 | 
1680  | 
\ \ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}\ n\ {\isacharequal}\ {\isacharparenleft}if\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n\ then\ n\ {\isacharminus}\ {\isadigit{1}}{\isadigit{0}}\ else\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1681  | 
%  | 
|
1682  | 
\isadelimproof  | 
|
1683  | 
%  | 
|
1684  | 
\endisadelimproof  | 
|
1685  | 
%  | 
|
1686  | 
\isatagproof  | 
|
1687  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1688  | 
\ pat{\isacharunderscore}completeness\ auto%
 | 
|
1689  | 
\endisatagproof  | 
|
1690  | 
{\isafoldproof}%
 | 
|
1691  | 
%  | 
|
1692  | 
\isadelimproof  | 
|
1693  | 
\isanewline  | 
|
1694  | 
%  | 
|
1695  | 
\endisadelimproof  | 
|
1696  | 
\isanewline  | 
|
1697  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
1698  | 
\ f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}estimate{\isacharcolon}\ \isanewline
 | 
|
1699  | 
\ \ \isakeyword{assumes}\ trm{\isacharcolon}\ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}dom\ n{\isachardoublequoteclose}\ \isanewline
 | 
|
1700  | 
\ \ \isakeyword{shows}\ {\isachardoublequoteopen}n\ {\isacharless}\ f{\isadigit{9}}{\isadigit{1}}\ n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isachardoublequoteclose}\isanewline
 | 
|
1701  | 
%  | 
|
1702  | 
\isadelimproof  | 
|
1703  | 
%  | 
|
1704  | 
\endisadelimproof  | 
|
1705  | 
%  | 
|
1706  | 
\isatagproof  | 
|
1707  | 
\isacommand{using}\isamarkupfalse%
 | 
|
1708  | 
\ trm\ \isacommand{by}\isamarkupfalse%
 | 
|
1709  | 
\ induct\ auto%  | 
|
1710  | 
\endisatagproof  | 
|
1711  | 
{\isafoldproof}%
 | 
|
1712  | 
%  | 
|
1713  | 
\isadelimproof  | 
|
1714  | 
\isanewline  | 
|
1715  | 
%  | 
|
1716  | 
\endisadelimproof  | 
|
1717  | 
\isanewline  | 
|
1718  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
1719  | 
\isanewline  | 
|
1720  | 
%  | 
|
1721  | 
\isadelimproof  | 
|
1722  | 
%  | 
|
1723  | 
\endisadelimproof  | 
|
1724  | 
%  | 
|
1725  | 
\isatagproof  | 
|
1726  | 
\isacommand{proof}\isamarkupfalse%
 | 
|
1727  | 
\isanewline  | 
|
1728  | 
\ \ \isacommand{let}\isamarkupfalse%
 | 
|
1729  | 
\ {\isacharquery}R\ {\isacharequal}\ {\isachardoublequoteopen}measure\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{1}}\ {\isacharminus}\ x{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
1730  | 
\ \ \isacommand{show}\isamarkupfalse%
 | 
|
1731  | 
\ {\isachardoublequoteopen}wf\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{{\isachardot}{\isachardot}}\isamarkupfalse%
 | 
|
1732  | 
\isanewline  | 
|
1733  | 
\isanewline  | 
|
1734  | 
\ \ \isacommand{fix}\isamarkupfalse%
 | 
|
1735  | 
\ n\ {\isacharcolon}{\isacharcolon}\ nat\ \isacommand{assume}\isamarkupfalse%
 | 
|
1736  | 
\ {\isachardoublequoteopen}{\isasymnot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n{\isachardoublequoteclose}\ %
 | 
|
1737  | 
\isamarkupcmt{Assumptions for both calls%
 | 
|
1738  | 
}  | 
|
1739  | 
\isanewline  | 
|
1740  | 
\isanewline  | 
|
1741  | 
\ \ \isacommand{thus}\isamarkupfalse%
 | 
|
1742  | 
\ {\isachardoublequoteopen}{\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharcomma}\ n{\isacharparenright}\ {\isasymin}\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
|
1743  | 
\ simp\ %  | 
|
1744  | 
\isamarkupcmt{Inner call%
 | 
|
1745  | 
}  | 
|
1746  | 
\isanewline  | 
|
1747  | 
\isanewline  | 
|
1748  | 
\ \ \isacommand{assume}\isamarkupfalse%
 | 
|
1749  | 
\ inner{\isacharunderscore}trm{\isacharcolon}\ {\isachardoublequoteopen}f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}dom\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isachardoublequoteclose}\ %
 | 
|
1750  | 
\isamarkupcmt{Outer call%
 | 
|
1751  | 
}  | 
|
1752  | 
\isanewline  | 
|
1753  | 
\ \ \isacommand{with}\isamarkupfalse%
 | 
|
1754  | 
\ f{\isadigit{9}}{\isadigit{1}}{\isacharunderscore}estimate\ \isacommand{have}\isamarkupfalse%
 | 
|
1755  | 
\ {\isachardoublequoteopen}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}\ {\isacharless}\ f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isachardoublequoteclose}\ \isacommand{{\isachardot}}\isamarkupfalse%
 | 
|
1756  | 
\isanewline  | 
|
1757  | 
\ \ \isacommand{with}\isamarkupfalse%
 | 
|
1758  | 
\ {\isacharbackquoteopen}{\isasymnot}\ {\isadigit{1}}{\isadigit{0}}{\isadigit{0}}\ {\isacharless}\ n{\isacharbackquoteclose}\ \isacommand{show}\isamarkupfalse%
 | 
|
1759  | 
\ {\isachardoublequoteopen}{\isacharparenleft}f{\isadigit{9}}{\isadigit{1}}\ {\isacharparenleft}n\ {\isacharplus}\ {\isadigit{1}}{\isadigit{1}}{\isacharparenright}{\isacharcomma}\ n{\isacharparenright}\ {\isasymin}\ {\isacharquery}R{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
|
| 23805 | 1760  | 
\ simp\isanewline  | 
| 23003 | 1761  | 
\isacommand{qed}\isamarkupfalse%
 | 
1762  | 
%  | 
|
1763  | 
\endisatagproof  | 
|
1764  | 
{\isafoldproof}%
 | 
|
1765  | 
%  | 
|
1766  | 
\isadelimproof  | 
|
1767  | 
%  | 
|
1768  | 
\endisadelimproof  | 
|
1769  | 
%  | 
|
1770  | 
\isamarkupfalse\isabellestyle{tt}
 | 
|
| 23188 | 1771  | 
\end{minipage}
 | 
1772  | 
\vspace{6pt}\hrule
 | 
|
| 23003 | 1773  | 
\caption{McCarthy's 91-function}\label{f91}
 | 
1774  | 
\end{figure}
 | 
|
1775  | 
%  | 
|
1776  | 
\isamarkupsection{Higher-Order Recursion%
 | 
|
1777  | 
}  | 
|
1778  | 
\isamarkuptrue%  | 
|
1779  | 
%  | 
|
1780  | 
\begin{isamarkuptext}%
 | 
|
1781  | 
Higher-order recursion occurs when recursive calls  | 
|
1782  | 
  are passed as arguments to higher-order combinators such as \isa{map}, \isa{filter} etc.
 | 
|
| 23805 | 1783  | 
As an example, imagine a datatype of n-ary trees:%  | 
| 23003 | 1784  | 
\end{isamarkuptext}%
 | 
1785  | 
\isamarkuptrue%  | 
|
1786  | 
\isacommand{datatype}\isamarkupfalse%
 | 
|
1787  | 
\ {\isacharprime}a\ tree\ {\isacharequal}\ \isanewline
 | 
|
1788  | 
\ \ Leaf\ {\isacharprime}a\ \isanewline
 | 
|
1789  | 
{\isacharbar}\ Branch\ {\isachardoublequoteopen}{\isacharprime}a\ tree\ list{\isachardoublequoteclose}%
 | 
|
1790  | 
\begin{isamarkuptext}%
 | 
|
| 25278 | 1791  | 
\noindent We can define a function which swaps the left and right subtrees recursively, using the  | 
1792  | 
  list functions \isa{rev} and \isa{map}:%
 | 
|
| 23003 | 1793  | 
\end{isamarkuptext}%
 | 
1794  | 
\isamarkuptrue%  | 
|
| 25731 | 1795  | 
\isacommand{lemma}\isamarkupfalse%
 | 
1796  | 
\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequoteopen}x\ {\isasymin}\ set\ l\ {\isasymLongrightarrow}\ f\ x\ {\isacharless}\ Suc\ {\isacharparenleft}list{\isacharunderscore}size\ f\ l{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
| 23003 | 1797  | 
%  | 
1798  | 
\isadelimproof  | 
|
1799  | 
%  | 
|
1800  | 
\endisadelimproof  | 
|
1801  | 
%  | 
|
1802  | 
\isatagproof  | 
|
1803  | 
\isacommand{by}\isamarkupfalse%
 | 
|
| 25731 | 1804  | 
\ {\isacharparenleft}induct\ l{\isacharparenright}\ auto%
 | 
| 23003 | 1805  | 
\endisatagproof  | 
1806  | 
{\isafoldproof}%
 | 
|
1807  | 
%  | 
|
1808  | 
\isadelimproof  | 
|
| 25731 | 1809  | 
\isanewline  | 
| 23003 | 1810  | 
%  | 
1811  | 
\endisadelimproof  | 
|
| 25731 | 1812  | 
\isanewline  | 
1813  | 
\isanewline  | 
|
1814  | 
\isacommand{fun}\isamarkupfalse%
 | 
|
1815  | 
\ mirror\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ tree\ {\isasymRightarrow}\ {\isacharprime}a\ tree{\isachardoublequoteclose}\isanewline
 | 
|
1816  | 
\isakeyword{where}\isanewline
 | 
|
1817  | 
\ \ {\isachardoublequoteopen}mirror\ {\isacharparenleft}Leaf\ n{\isacharparenright}\ {\isacharequal}\ Leaf\ n{\isachardoublequoteclose}\isanewline
 | 
|
1818  | 
{\isacharbar}\ {\isachardoublequoteopen}mirror\ {\isacharparenleft}Branch\ l{\isacharparenright}\ {\isacharequal}\ Branch\ {\isacharparenleft}rev\ {\isacharparenleft}map\ mirror\ l{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
 | 
|
| 23003 | 1819  | 
\begin{isamarkuptext}%
 | 
| 25731 | 1820  | 
\emph{Note: The handling of size functions is currently changing 
 | 
1821  | 
in the developers version of Isabelle. So this documentation is outdated.}%  | 
|
| 23003 | 1822  | 
\end{isamarkuptext}%
 | 
1823  | 
\isamarkuptrue%  | 
|
1824  | 
\isacommand{termination}\isamarkupfalse%
 | 
|
1825  | 
%  | 
|
1826  | 
\isadelimproof  | 
|
1827  | 
\ %  | 
|
1828  | 
\endisadelimproof  | 
|
1829  | 
%  | 
|
1830  | 
\isatagproof  | 
|
1831  | 
\isacommand{proof}\isamarkupfalse%
 | 
|
1832  | 
%  | 
|
1833  | 
\begin{isamarkuptxt}%
 | 
|
1834  | 
As usual, we have to give a wellfounded relation, such that the  | 
|
1835  | 
arguments of the recursive calls get smaller. But what exactly are  | 
|
1836  | 
the arguments of the recursive calls? Isabelle gives us the  | 
|
1837  | 
subgoals  | 
|
1838  | 
||
1839  | 
  \begin{isabelle}%
 | 
|
1840  | 
\ {\isadigit{1}}{\isachardot}\ wf\ {\isacharquery}R\isanewline
 | 
|
| 25278 | 1841  | 
\ {\isadigit{2}}{\isachardot}\ {\isasymAnd}l\ x{\isachardot}\ x\ {\isasymin}\ set\ l\ {\isasymLongrightarrow}\ {\isacharparenleft}x{\isacharcomma}\ Branch\ l{\isacharparenright}\ {\isasymin}\ {\isacharquery}R%
 | 
| 23003 | 1842  | 
\end{isabelle} 
 | 
1843  | 
||
1844  | 
  So Isabelle seems to know that \isa{map} behaves nicely and only
 | 
|
| 25278 | 1845  | 
  applies the recursive call \isa{mirror} to elements
 | 
| 23003 | 1846  | 
  of \isa{l}. Before we discuss where this knowledge comes from,
 | 
1847  | 
let us finish the termination proof:%  | 
|
1848  | 
\end{isamarkuptxt}%
 | 
|
1849  | 
\isamarkuptrue%  | 
|
1850  | 
\ \ \isacommand{show}\isamarkupfalse%
 | 
|
| 25278 | 1851  | 
\ {\isachardoublequoteopen}wf\ {\isacharparenleft}measure\ size{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse%
 | 
| 23003 | 1852  | 
\ simp\isanewline  | 
1853  | 
\isacommand{next}\isamarkupfalse%
 | 
|
1854  | 
\isanewline  | 
|
1855  | 
\ \ \isacommand{fix}\isamarkupfalse%
 | 
|
1856  | 
\ f\ l\ \isakeyword{and}\ x\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isacharprime}a\ tree{\isachardoublequoteclose}\isanewline
 | 
|
1857  | 
\ \ \isacommand{assume}\isamarkupfalse%
 | 
|
1858  | 
\ {\isachardoublequoteopen}x\ {\isasymin}\ set\ l{\isachardoublequoteclose}\isanewline
 | 
|
1859  | 
\ \ \isacommand{thus}\isamarkupfalse%
 | 
|
| 25278 | 1860  | 
\ {\isachardoublequoteopen}{\isacharparenleft}x{\isacharcomma}\ Branch\ l{\isacharparenright}\ {\isasymin}\ measure\ size{\isachardoublequoteclose}\isanewline
 | 
| 23003 | 1861  | 
\ \ \ \ \isacommand{apply}\isamarkupfalse%
 | 
1862  | 
\ simp%  | 
|
1863  | 
\begin{isamarkuptxt}%
 | 
|
1864  | 
Simplification returns the following subgoal:  | 
|
1865  | 
||
1866  | 
      \begin{isabelle}%
 | 
|
| 25731 | 1867  | 
{\isadigit{1}}{\isachardot}\ x\ {\isasymin}\ set\ l\ {\isasymLongrightarrow}\ size\ x\ {\isacharless}\ Suc\ {\isacharparenleft}list{\isacharunderscore}size\ size\ l{\isacharparenright}%
 | 
| 23003 | 1868  | 
\end{isabelle} 
 | 
1869  | 
||
1870  | 
      We are lacking a property about the function \isa{tree{\isacharunderscore}list{\isacharunderscore}size}, which was generated automatically at the
 | 
|
1871  | 
      definition of the \isa{tree} type. We should go back and prove
 | 
|
1872  | 
it, by induction.%  | 
|
1873  | 
\end{isamarkuptxt}%
 | 
|
1874  | 
\isamarkuptrue%  | 
|
| 23805 | 1875  | 
\ \ \ \ %  | 
| 23003 | 1876  | 
\endisatagproof  | 
1877  | 
{\isafoldproof}%
 | 
|
1878  | 
%  | 
|
1879  | 
\isadelimproof  | 
|
1880  | 
%  | 
|
1881  | 
\endisadelimproof  | 
|
1882  | 
%  | 
|
1883  | 
\begin{isamarkuptext}%
 | 
|
1884  | 
Now the whole termination proof is automatic:%  | 
|
1885  | 
\end{isamarkuptext}%
 | 
|
1886  | 
\isamarkuptrue%  | 
|
| 25278 | 1887  | 
\isacommand{termination}\isamarkupfalse%
 | 
| 23003 | 1888  | 
\ \isanewline  | 
1889  | 
%  | 
|
1890  | 
\isadelimproof  | 
|
| 25278 | 1891  | 
\ \ %  | 
| 23003 | 1892  | 
\endisadelimproof  | 
1893  | 
%  | 
|
1894  | 
\isatagproof  | 
|
1895  | 
\isacommand{by}\isamarkupfalse%
 | 
|
1896  | 
\ lexicographic{\isacharunderscore}order%
 | 
|
1897  | 
\endisatagproof  | 
|
1898  | 
{\isafoldproof}%
 | 
|
1899  | 
%  | 
|
1900  | 
\isadelimproof  | 
|
1901  | 
%  | 
|
1902  | 
\endisadelimproof  | 
|
1903  | 
%  | 
|
1904  | 
\isamarkupsubsection{Congruence Rules%
 | 
|
1905  | 
}  | 
|
1906  | 
\isamarkuptrue%  | 
|
1907  | 
%  | 
|
1908  | 
\begin{isamarkuptext}%
 | 
|
1909  | 
Let's come back to the question how Isabelle knows about \isa{map}.
 | 
|
1910  | 
||
1911  | 
The knowledge about map is encoded in so-called congruence rules,  | 
|
1912  | 
  which are special theorems known to the \cmd{function} command. The
 | 
|
1913  | 
rule for map is  | 
|
1914  | 
||
1915  | 
  \begin{isabelle}%
 | 
|
1916  | 
{\isasymlbrakk}{\isacharquery}xs\ {\isacharequal}\ {\isacharquery}ys{\isacharsemicolon}\ {\isasymAnd}x{\isachardot}\ x\ {\isasymin}\ set\ {\isacharquery}ys\ {\isasymLongrightarrow}\ {\isacharquery}f\ x\ {\isacharequal}\ {\isacharquery}g\ x{\isasymrbrakk}\ {\isasymLongrightarrow}\ map\ {\isacharquery}f\ {\isacharquery}xs\ {\isacharequal}\ map\ {\isacharquery}g\ {\isacharquery}ys%
 | 
|
1917  | 
\end{isabelle}
 | 
|
1918  | 
||
1919  | 
  You can read this in the following way: Two applications of \isa{map} are equal, if the list arguments are equal and the functions
 | 
|
1920  | 
coincide on the elements of the list. This means that for the value  | 
|
1921  | 
  \isa{map\ f\ l} we only have to know how \isa{f} behaves on
 | 
|
1922  | 
  \isa{l}.
 | 
|
1923  | 
||
1924  | 
Usually, one such congruence rule is  | 
|
1925  | 
needed for each higher-order construct that is used when defining  | 
|
| 23805 | 1926  | 
  new functions. In fact, even basic functions like \isa{If} and \isa{Let} are handled by this mechanism. The congruence
 | 
| 23003 | 1927  | 
  rule for \isa{If} states that the \isa{then} branch is only
 | 
1928  | 
  relevant if the condition is true, and the \isa{else} branch only if it
 | 
|
1929  | 
is false:  | 
|
1930  | 
||
1931  | 
  \begin{isabelle}%
 | 
|
1932  | 
{\isasymlbrakk}{\isacharquery}b\ {\isacharequal}\ {\isacharquery}c{\isacharsemicolon}\ {\isacharquery}c\ {\isasymLongrightarrow}\ {\isacharquery}x\ {\isacharequal}\ {\isacharquery}u{\isacharsemicolon}\ {\isasymnot}\ {\isacharquery}c\ {\isasymLongrightarrow}\ {\isacharquery}y\ {\isacharequal}\ {\isacharquery}v{\isasymrbrakk}\isanewline
 | 
|
1933  | 
{\isasymLongrightarrow}\ {\isacharparenleft}if\ {\isacharquery}b\ then\ {\isacharquery}x\ else\ {\isacharquery}y{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ {\isacharquery}c\ then\ {\isacharquery}u\ else\ {\isacharquery}v{\isacharparenright}%
 | 
|
1934  | 
\end{isabelle}
 | 
|
1935  | 
||
1936  | 
Congruence rules can be added to the  | 
|
1937  | 
  function package by giving them the \isa{fundef{\isacharunderscore}cong} attribute.
 | 
|
1938  | 
||
| 23805 | 1939  | 
The constructs that are predefined in Isabelle, usually  | 
1940  | 
come with the respective congruence rules.  | 
|
1941  | 
But if you define your own higher-order functions, you will have to  | 
|
| 23003 | 1942  | 
come up with the congruence rules yourself, if you want to use your  | 
| 23805 | 1943  | 
functions in recursive definitions.%  | 
| 23003 | 1944  | 
\end{isamarkuptext}%
 | 
1945  | 
\isamarkuptrue%  | 
|
1946  | 
%  | 
|
| 23805 | 1947  | 
\isamarkupsubsection{Congruence Rules and Evaluation Order%
 | 
1948  | 
}  | 
|
1949  | 
\isamarkuptrue%  | 
|
1950  | 
%  | 
|
| 23003 | 1951  | 
\begin{isamarkuptext}%
 | 
| 23805 | 1952  | 
Higher order logic differs from functional programming languages in  | 
1953  | 
that it has no built-in notion of evaluation order. A program is  | 
|
1954  | 
just a set of equations, and it is not specified how they must be  | 
|
1955  | 
evaluated.  | 
|
1956  | 
||
1957  | 
However for the purpose of function definition, we must talk about  | 
|
1958  | 
evaluation order implicitly, when we reason about termination.  | 
|
1959  | 
Congruence rules express that a certain evaluation order is  | 
|
1960  | 
consistent with the logical definition.  | 
|
1961  | 
||
1962  | 
Consider the following function.%  | 
|
1963  | 
\end{isamarkuptext}%
 | 
|
1964  | 
\isamarkuptrue%  | 
|
1965  | 
\isacommand{function}\isamarkupfalse%
 | 
|
1966  | 
\ f\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
 | 
|
1967  | 
\isakeyword{where}\isanewline
 | 
|
1968  | 
\ \ {\isachardoublequoteopen}f\ n\ {\isacharequal}\ {\isacharparenleft}n\ {\isacharequal}\ {\isadigit{0}}\ {\isasymor}\ f\ {\isacharparenleft}n\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}{\isacharparenright}{\isachardoublequoteclose}%
 | 
|
1969  | 
\isadelimproof  | 
|
1970  | 
%  | 
|
1971  | 
\endisadelimproof  | 
|
1972  | 
%  | 
|
1973  | 
\isatagproof  | 
|
1974  | 
%  | 
|
1975  | 
\endisatagproof  | 
|
1976  | 
{\isafoldproof}%
 | 
|
1977  | 
%  | 
|
1978  | 
\isadelimproof  | 
|
1979  | 
%  | 
|
1980  | 
\endisadelimproof  | 
|
1981  | 
%  | 
|
1982  | 
\begin{isamarkuptext}%
 | 
|
1983  | 
As given above, the definition fails. The default configuration  | 
|
1984  | 
specifies no congruence rule for disjunction. We have to add a  | 
|
1985  | 
congruence rule that specifies left-to-right evaluation order:  | 
|
1986  | 
||
1987  | 
  \vspace{1ex}
 | 
|
1988  | 
  \noindent \isa{{\isasymlbrakk}{\isacharquery}P\ {\isacharequal}\ {\isacharquery}P{\isacharprime}{\isacharsemicolon}\ {\isasymnot}\ {\isacharquery}P{\isacharprime}\ {\isasymLongrightarrow}\ {\isacharquery}Q\ {\isacharequal}\ {\isacharquery}Q{\isacharprime}{\isasymrbrakk}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isacharquery}P\ {\isasymor}\ {\isacharquery}Q{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}{\isacharquery}P{\isacharprime}\ {\isasymor}\ {\isacharquery}Q{\isacharprime}{\isacharparenright}}\hfill(\isa{disj{\isacharunderscore}cong})
 | 
|
1989  | 
  \vspace{1ex}
 | 
|
| 23003 | 1990  | 
|
| 23805 | 1991  | 
Now the definition works without problems. Note how the termination  | 
1992  | 
proof depends on the extra condition that we get from the congruence  | 
|
1993  | 
rule.  | 
|
| 23003 | 1994  | 
|
| 23805 | 1995  | 
However, as evaluation is not a hard-wired concept, we  | 
1996  | 
could just turn everything around by declaring a different  | 
|
1997  | 
congruence rule. Then we can make the reverse definition:%  | 
|
1998  | 
\end{isamarkuptext}%
 | 
|
1999  | 
\isamarkuptrue%  | 
|
2000  | 
\isacommand{lemma}\isamarkupfalse%
 | 
|
2001  | 
\ disj{\isacharunderscore}cong{\isadigit{2}}{\isacharbrackleft}fundef{\isacharunderscore}cong{\isacharbrackright}{\isacharcolon}\ \isanewline
 | 
|
2002  | 
\ \ {\isachardoublequoteopen}{\isacharparenleft}{\isasymnot}\ Q{\isacharprime}\ {\isasymLongrightarrow}\ P\ {\isacharequal}\ P{\isacharprime}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}Q\ {\isacharequal}\ Q{\isacharprime}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}P\ {\isasymor}\ Q{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}P{\isacharprime}\ {\isasymor}\ Q{\isacharprime}{\isacharparenright}{\isachardoublequoteclose}\isanewline
 | 
|
2003  | 
%  | 
|
2004  | 
\isadelimproof  | 
|
2005  | 
\ \ %  | 
|
2006  | 
\endisadelimproof  | 
|
2007  | 
%  | 
|
2008  | 
\isatagproof  | 
|
2009  | 
\isacommand{by}\isamarkupfalse%
 | 
|
2010  | 
\ blast%  | 
|
2011  | 
\endisatagproof  | 
|
2012  | 
{\isafoldproof}%
 | 
|
2013  | 
%  | 
|
2014  | 
\isadelimproof  | 
|
2015  | 
\isanewline  | 
|
2016  | 
%  | 
|
2017  | 
\endisadelimproof  | 
|
2018  | 
\isanewline  | 
|
2019  | 
\isacommand{fun}\isamarkupfalse%
 | 
|
2020  | 
\ f{\isacharprime}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ bool{\isachardoublequoteclose}\isanewline
 | 
|
2021  | 
\isakeyword{where}\isanewline
 | 
|
2022  | 
\ \ {\isachardoublequoteopen}f{\isacharprime}\ n\ {\isacharequal}\ {\isacharparenleft}f{\isacharprime}\ {\isacharparenleft}n\ {\isacharminus}\ {\isadigit{1}}{\isacharparenright}\ {\isasymor}\ n\ {\isacharequal}\ {\isadigit{0}}{\isacharparenright}{\isachardoublequoteclose}%
 | 
|
2023  | 
\begin{isamarkuptext}%
 | 
|
2024  | 
\noindent These examples show that, in general, there is no \qt{best} set of
 | 
|
2025  | 
congruence rules.  | 
|
2026  | 
||
2027  | 
However, such tweaking should rarely be necessary in  | 
|
2028  | 
practice, as most of the time, the default set of congruence rules  | 
|
2029  | 
works well.%  | 
|
| 21212 | 2030  | 
\end{isamarkuptext}%
 | 
2031  | 
\isamarkuptrue%  | 
|
2032  | 
%  | 
|
2033  | 
\isadelimtheory  | 
|
2034  | 
%  | 
|
2035  | 
\endisadelimtheory  | 
|
2036  | 
%  | 
|
2037  | 
\isatagtheory  | 
|
2038  | 
\isacommand{end}\isamarkupfalse%
 | 
|
2039  | 
%  | 
|
2040  | 
\endisatagtheory  | 
|
2041  | 
{\isafoldtheory}%
 | 
|
2042  | 
%  | 
|
2043  | 
\isadelimtheory  | 
|
2044  | 
%  | 
|
2045  | 
\endisadelimtheory  | 
|
2046  | 
\isanewline  | 
|
2047  | 
\end{isabellebody}%
 | 
|
2048  | 
%%% Local Variables:  | 
|
2049  | 
%%% mode: latex  | 
|
2050  | 
%%% TeX-master: "root"  | 
|
2051  | 
%%% End:  |