doc-src/IsarAdvanced/Functions/Thy/Functions.thy
author huffman
Wed, 08 Nov 2006 00:34:15 +0100
changeset 21238 c46bc715bdfd
parent 21212 547224bf9348
child 21346 c8aa120fa05d
permissions -rw-r--r--
generalized types of of_nat and of_int to work with non-commutative types
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
     1
(*  Title:      Doc/IsarAdvanced/Functions/Thy/Fundefs.thy
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
     2
    ID:         $Id$
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
     3
    Author:     Alexander Krauss, TU Muenchen
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
Tutorial for function definitions with the new "function" package.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
     6
*)
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
     7
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
     8
theory Functions
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
     9
imports Main
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    10
begin
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    11
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    12
chapter {* Defining Recursive Functions in Isabelle/HOL *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    13
text {* \cite{isa-tutorial} *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    14
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    15
section {* Function Definition for Dummies *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    16
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    17
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    18
  In most cases, defining a recursive function is just as simple as other definitions:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    19
  *}
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
fun fib :: "nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    22
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    23
  "fib 0 = 1"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    24
| "fib (Suc 0) = 1"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    25
| "fib (Suc (Suc n)) = fib n + fib (Suc n)"
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
(*<*)termination by lexicographic_order(*>*)
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    28
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    29
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    30
  The function always terminates, since the argument of gets smaller in every
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    31
  recursive call. Termination is an
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    32
  important requirement, since it prevents inconsistencies: From
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    33
  the "definition" @{text "f(n) = f(n) + 1"} we could prove 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    34
  @{text "0  = 1"} by subtracting @{text "f(n)"} on both sides.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    35
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    36
  Isabelle tries to prove termination automatically when a function is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    37
  defined. We will later look at cases where this fails and see what to
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    38
  do then.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    39
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    40
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    41
subsection {* Pattern matching *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    42
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    43
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    44
  Like in functional programming, functions can be defined by pattern
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    45
  matching. At the moment we will only consider \emph{datatype
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    46
  patterns}, which only consist of datatype constructors and
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    47
  variables.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    48
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    49
  If patterns overlap, the order of the equations is taken into
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    50
  account. The following function inserts a fixed element between any
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    51
  two elements of a list:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    52
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    53
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    54
fun sep :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    55
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    56
  "sep a (x#y#xs) = x # a # sep a (y # xs)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    57
| "sep a xs       = xs"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    58
(*<*)termination by lexicographic_order(*>*)
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    59
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    60
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    61
  Overlapping patterns are interpreted as "increments" to what is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    62
  already there: The second equation is only meant for the cases where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    63
  the first one does not match. Consequently, Isabelle replaces it
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    64
  internally by the remaining cases, making the patterns disjoint.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    65
  This results in the equations @{thm [display] sep.simps[no_vars]}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    66
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    67
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    68
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    71
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    72
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    73
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    74
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    75
  The equations from function definitions are automatically used in
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    76
  simplification:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    77
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    78
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    79
lemma "fib (Suc (Suc 0)) = (Suc (Suc 0))"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    80
by simp
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    81
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    82
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    83
  
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    84
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    85
subsection {* Induction *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    86
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    87
text {* FIXME *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    88
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    89
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    90
section {* If it does not work *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    91
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    92
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    93
  Up to now, we were using the \cmd{fun} command, which provides a
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    94
  convenient shorthand notation for simple function definitions. In
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    95
  this mode, Isabelle tries to solve all the necessary proof obligations
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    96
  automatically. If a proof does not go through, the definition is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    97
  rejected. This can mean that the definition is indeed faulty, like,
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    98
  or that the default proof procedures are not smart enough (or
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    99
  rather: not designed) to handle the specific definition.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   100
.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   101
  By expanding the abbreviation to the full \cmd{function} command, the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   102
  proof obligations become visible and can be analyzed and solved manually.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   103
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   104
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   105
(*<*)types "\<tau>" = "nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   106
(*>*)
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   107
fun f :: "\<tau>"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   108
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   109
  (*<*)"f x = x" (*>*)text {* \vspace{-0.8cm}\emph{equations} *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   110
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   111
text {* \noindent abbreviates *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   112
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   113
function (sequential) fo :: "\<tau>"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   114
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   115
  (*<*)"fo x = x" (*>*)txt {* \vspace{-0.8cm}\emph{equations} *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   116
by pat_completeness auto 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   117
termination by lexicographic_order
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   118
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   119
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   120
  Some declarations and proofs have now become explicit:
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
  \begin{enumerate}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   123
  \item The "sequential" option enables the preprocessing of
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   124
  pattern overlaps we already saw. Without this option, the equations
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   125
  must already be disjoint and complete. The automatic completion only
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   126
  works with datatype patterns.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   127
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   128
  \item A function definition now produces a proof obligation which
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   129
  expresses completeness and compatibility of patterns (We talk about
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   130
  this later). The combination of the methods {\tt pat\_completeness} and
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   131
  {\tt auto} is used to solve this proof obligation.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   132
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   133
  \item A termination proof follows the definition, started by the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   134
  \cmd{termination} command. The {\tt lexicographic\_order} method can prove termination of a
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   135
  certain class of functions by searching for a suitable lexicographic combination of size
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   136
  measures.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   137
  \end{enumerate}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   138
 *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   139
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   140
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   141
section {* Proving termination *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   142
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   143
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   144
  Consider the following function, which sums up natural numbers up to
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   145
  @{text "N"}, using a counter @{text "i"}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   146
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   147
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   148
function sum :: "nat \<Rightarrow> nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   149
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   150
  "sum i N = (if i > N then 0 else i + sum (Suc i) N)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   151
  by pat_completeness auto
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   152
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   153
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   154
  The {\tt lexicographic\_order} method fails on this example, because none of the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   155
  arguments decreases in the recursive call.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   156
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   157
  A more general method for termination proofs is to supply a wellfounded
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   158
  relation on the argument type, and to show that the argument
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   159
  decreases in every recursive call. 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   160
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   161
  The termination argument for @{text "sum"} is based on the fact that
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   162
  the \emph{difference} between @{text "i"} and @{text "N"} gets
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   163
  smaller in every step, and that the recursion stops when @{text "i"}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   164
  is greater then @{text "n"}. Phrased differently, the expression 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   165
  @{text "N + 1 - i"} decreases in every recursive call.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   166
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   167
  We can use this expression as a measure function to construct a
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   168
  wellfounded relation, which is a proof of termination:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   169
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   170
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   171
termination 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   172
  by (auto_term "measure (\<lambda>(i,N). N + 1 - i)")
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   173
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   174
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   175
  Note that the two (curried) function arguments appear as a pair in
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   176
  the measure function. The \cmd{function} command packs together curried
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   177
  arguments into a tuple to simplify its internal operation. Hence,
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   178
  measure functions and termination relations always work on the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   179
  tupled type.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   180
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   181
  Let us complicate the function a little, by adding some more recursive calls:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   182
*}
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
function foo :: "nat \<Rightarrow> nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   185
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   186
  "foo i N = (if i > N 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   187
              then (if N = 0 then 0 else foo 0 (N - 1))
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   188
              else i + foo (Suc i) N)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   189
by pat_completeness auto
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   190
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   191
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   192
  When @{text "i"} has reached @{text "N"}, it starts at zero again
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   193
  and @{text "N"} is decremented.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   194
  This corresponds to a nested
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   195
  loop where one index counts up and the other down. Termination can
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   196
  be proved using a lexicographic combination of two measures, namely
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   197
  the value of @{text "N"} and the above difference. The @{text "measures"}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   198
  combinator generalizes @{text "measure"} by taking a list of measure functions.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   199
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   200
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   201
termination 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   202
  by (auto_term "measures [\<lambda>(i, N). N, \<lambda>(i,N). N + 1 - i]")
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   203
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   204
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   205
section {* Mutual Recursion *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   206
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   207
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   208
  If two or more functions call one another mutually, they have to be defined
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   209
  in one step. The simplest example are probably @{text "even"} and @{text "odd"}:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   210
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   211
(*<*)hide const even odd(*>*)
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   213
function even odd :: "nat \<Rightarrow> bool"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   214
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   215
  "even 0 = True"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   216
| "odd 0 = False"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   217
| "even (Suc n) = odd n"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   218
| "odd (Suc n) = even n"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   219
  by pat_completeness auto
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   220
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   221
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   222
  To solve the problem of mutual dependencies, Isabelle internally
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   223
  creates a single function operating on the sum
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   224
  type. Then the original functions are defined as
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   225
  projections. Consequently, termination has to be proved
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   226
  simultaneously for both functions, by specifying a measure on the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   227
  sum type: 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   228
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   229
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   230
termination 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   231
  by (auto_term "measure (sum_case (%n. n) (%n. n))")
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   232
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   233
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   234
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   235
(* FIXME: Mutual induction *)
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   236
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   237
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   238
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   239
section {* Nested recursion *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   240
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   241
text {* FIXME *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   242
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   243
section {* More general patterns *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   244
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   245
text {* FIXME *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   246
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   247
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   248
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   249
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   250
end