doc-src/IsarAdvanced/Functions/Thy/Functions.thy
author urbanc
Fri, 17 Nov 2006 17:32:30 +0100
changeset 21405 26b51f724fe6
parent 21346 c8aa120fa05d
child 22065 cdd077905eee
permissions -rw-r--r--
added an intro lemma for freshness of products; set up the simplifier so that it can deal with the compact and long notation for freshness constraints (FIXME: it should also be able to deal with the special case of freshness of atoms)
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
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    28
  The function always terminates, since the argument of gets smaller in every
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    29
  recursive call. Termination is an
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    30
  important requirement, since it prevents inconsistencies: From
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    31
  the "definition" @{text "f(n) = f(n) + 1"} we could prove 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    32
  @{text "0  = 1"} by subtracting @{text "f(n)"} on both sides.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    33
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    34
  Isabelle tries to prove termination automatically when a function is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    35
  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
    36
  do then.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    37
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    38
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    39
subsection {* Pattern matching *}
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
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    42
  Like in functional programming, functions can be defined by pattern
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    43
  matching. At the moment we will only consider \emph{datatype
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    44
  patterns}, which only consist of datatype constructors and
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    45
  variables.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    46
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    47
  If patterns overlap, the order of the equations is taken into
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    48
  account. The following function inserts a fixed element between any
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    49
  two elements of a list:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    50
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    51
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    52
fun sep :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    53
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    54
  "sep a (x#y#xs) = x # a # sep a (y # xs)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    55
| "sep a xs       = xs"
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
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    58
  Overlapping patterns are interpreted as "increments" to what is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    59
  already there: The second equation is only meant for the cases where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    60
  the first one does not match. Consequently, Isabelle replaces it
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    61
  internally by the remaining cases, making the patterns disjoint.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    62
  This results in the equations @{thm [display] sep.simps[no_vars]}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    63
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    64
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    65
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
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    72
  The equations from function definitions are automatically used in
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    73
  simplification:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    74
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    75
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    76
lemma "fib (Suc (Suc 0)) = (Suc (Suc 0))"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    77
by simp
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    80
  
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
subsection {* Induction *}
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
text {* FIXME *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    85
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
section {* If it does not work *}
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
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    90
  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
    91
  convenient shorthand notation for simple function definitions. In
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    92
  this mode, Isabelle tries to solve all the necessary proof obligations
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    93
  automatically. If a proof does not go through, the definition is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    94
  rejected. This can mean that the definition is indeed faulty, like,
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    95
  or that the default proof procedures are not smart enough (or
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    96
  rather: not designed) to handle the specific definition.
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
  By expanding the abbreviation to the full \cmd{function} command, the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    99
  proof obligations become visible and can be analyzed and solved manually.
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   102
(*<*)types "\<tau>" = "nat \<Rightarrow> nat"
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
fun f :: "\<tau>"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   105
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   106
  (*<*)"f x = x" (*>*)text {* \vspace{-0.8cm}\emph{equations} *}
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
text {* \noindent abbreviates *}
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
function (sequential) fo :: "\<tau>"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   111
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   112
  (*<*)"fo x = x" (*>*)txt {* \vspace{-0.8cm}\emph{equations} *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   113
by pat_completeness auto 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   114
termination by lexicographic_order
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
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   117
  Some declarations and proofs have now become explicit:
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
  \begin{enumerate}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   120
  \item The "sequential" option enables the preprocessing of
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   121
  pattern overlaps we already saw. Without this option, the equations
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   122
  must already be disjoint and complete. The automatic completion only
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   123
  works with datatype patterns.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   124
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   125
  \item A function definition now produces a proof obligation which
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   126
  expresses completeness and compatibility of patterns (We talk about
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   127
  this later). The combination of the methods {\tt pat\_completeness} and
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   128
  {\tt auto} is used to solve this proof obligation.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   129
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   130
  \item A termination proof follows the definition, started by the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   131
  \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
   132
  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
   133
  measures.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   134
  \end{enumerate}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   135
 *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   136
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   137
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   138
section {* Proving termination *}
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
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   141
  Consider the following function, which sums up natural numbers up to
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   142
  @{text "N"}, using a counter @{text "i"}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   143
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   144
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   145
function sum :: "nat \<Rightarrow> nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   146
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   147
  "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
   148
  by pat_completeness auto
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   149
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   150
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   151
  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
   152
  arguments decreases in the recursive call.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   153
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   154
  A more general method for termination proofs is to supply a wellfounded
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   155
  relation on the argument type, and to show that the argument
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   156
  decreases in every recursive call. 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   157
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   158
  The termination argument for @{text "sum"} is based on the fact that
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   159
  the \emph{difference} between @{text "i"} and @{text "N"} gets
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   160
  smaller in every step, and that the recursion stops when @{text "i"}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   161
  is greater then @{text "n"}. Phrased differently, the expression 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   162
  @{text "N + 1 - i"} decreases in every recursive call.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   163
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   164
  We can use this expression as a measure function to construct a
21346
c8aa120fa05d updated
krauss
parents: 21212
diff changeset
   165
  wellfounded relation, which can prove termination.
21212
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   168
termination 
21346
c8aa120fa05d updated
krauss
parents: 21212
diff changeset
   169
  by (relation "measure (\<lambda>(i,N). N + 1 - i)") auto
21212
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
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   172
  Note that the two (curried) function arguments appear as a pair in
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   173
  the measure function. The \cmd{function} command packs together curried
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   174
  arguments into a tuple to simplify its internal operation. Hence,
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   175
  measure functions and termination relations always work on the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   176
  tupled type.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   177
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   178
  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
   179
*}
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
function foo :: "nat \<Rightarrow> nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   182
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   183
  "foo i N = (if i > N 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   184
              then (if N = 0 then 0 else foo 0 (N - 1))
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   185
              else i + foo (Suc i) N)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   186
by pat_completeness auto
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   187
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   188
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   189
  When @{text "i"} has reached @{text "N"}, it starts at zero again
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   190
  and @{text "N"} is decremented.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   191
  This corresponds to a nested
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   192
  loop where one index counts up and the other down. Termination can
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   193
  be proved using a lexicographic combination of two measures, namely
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   194
  the value of @{text "N"} and the above difference. The @{text "measures"}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   195
  combinator generalizes @{text "measure"} by taking a list of measure functions.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   196
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   197
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   198
termination 
21346
c8aa120fa05d updated
krauss
parents: 21212
diff changeset
   199
  by (relation "measures [\<lambda>(i, N). N, \<lambda>(i,N). N + 1 - i]") auto
21212
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   202
section {* Mutual Recursion *}
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
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   205
  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
   206
  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
   207
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   208
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   209
function even odd :: "nat \<Rightarrow> bool"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   210
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   211
  "even 0 = True"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   212
| "odd 0 = False"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   213
| "even (Suc n) = odd n"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   214
| "odd (Suc n) = even n"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   215
  by pat_completeness auto
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   216
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   217
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   218
  To solve the problem of mutual dependencies, Isabelle internally
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   219
  creates a single function operating on the sum
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   220
  type. Then the original functions are defined as
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   221
  projections. Consequently, termination has to be proved
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   222
  simultaneously for both functions, by specifying a measure on the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   223
  sum type: 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   224
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   225
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   226
termination 
21346
c8aa120fa05d updated
krauss
parents: 21212
diff changeset
   227
  by (relation "measure (sum_case (%n. n) (%n. n))") auto
21212
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   231
(* FIXME: Mutual induction *)
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
section {* Nested recursion *}
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
text {* FIXME *}
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 {* More general patterns *}
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
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   246
end