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