doc-src/IsarAdvanced/Functions/Thy/Functions.thy
author wenzelm
Thu, 10 May 2007 00:39:46 +0200
changeset 22901 481cd919c47f
parent 22065 cdd077905eee
child 23003 4b0bf04a4d68
permissions -rw-r--r--
Thm.first_order_match;
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    14
section {* Function Definition for Dummies *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    15
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    16
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    17
  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
    18
  *}
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
fun fib :: "nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    21
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    22
  "fib 0 = 1"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    23
| "fib (Suc 0) = 1"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    24
| "fib (Suc (Suc n)) = fib n + fib (Suc n)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    25
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    26
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    27
  The function always terminates, since the argument of gets smaller in every
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    28
  recursive call. Termination is an
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    29
  important requirement, since it prevents inconsistencies: From
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    30
  the "definition" @{text "f(n) = f(n) + 1"} we could prove 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    31
  @{text "0  = 1"} by subtracting @{text "f(n)"} on both sides.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    32
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    33
  Isabelle tries to prove termination automatically when a function is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    34
  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
    35
  do then.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    36
*}
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
subsection {* Pattern matching *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    39
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    40
text {* \label{patmatch}
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    41
  Like in functional programming, functions can be defined by pattern
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    42
  matching. At the moment we will only consider \emph{datatype
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    43
  patterns}, which only consist of datatype constructors and
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    44
  variables.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    45
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    46
  If patterns overlap, the order of the equations is taken into
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    47
  account. The following function inserts a fixed element between any
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    48
  two elements of a list:
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    49
*}
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
fun sep :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    52
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    53
  "sep a (x#y#xs) = x # a # sep a (y # xs)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    54
| "sep a xs       = xs"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    55
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    56
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    57
  Overlapping patterns are interpreted as "increments" to what is
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    58
  already there: The second equation is only meant for the cases where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    59
  the first one does not match. Consequently, Isabelle replaces it
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    60
  internally by the remaining cases, making the patterns disjoint:
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    61
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    62
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    63
thm sep.simps
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    64
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    65
text {* @{thm [display] sep.simps[no_vars]} *}
21212
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
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    68
  The equations from function definitions are automatically used in
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    69
  simplification:
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
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    72
lemma "sep (0::nat) [1, 2, 3] = [1, 0, 2, 0, 3]"
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    73
by simp
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    77
subsection {* Induction *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    78
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    79
text {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    80
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    81
  Isabelle provides customized induction rules for recursive functions.  
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    82
  See \cite[\S3.5.4]{isa-tutorial}.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    83
*}
21212
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
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    86
section {* Full form definitions *}
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    87
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    88
text {* 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    89
  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
    90
  convenient shorthand notation for simple function definitions. In
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    91
  this mode, Isabelle tries to solve all the necessary proof obligations
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
    92
  automatically. If a proof does not go through, the definition is
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    93
  rejected. This can either mean that the definition is indeed faulty,
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    94
  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
    95
  rather: not designed) to handle the definition.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    96
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    97
  By expanding the abbreviated \cmd{fun} to the full \cmd{function}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    98
  command, the proof obligations become visible and can be analyzed or
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
    99
  solved manually.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   100
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   101
\end{isamarkuptext}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   102
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   103
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   104
\fbox{\parbox{\textwidth}{
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   105
\noindent\cmd{fun} @{text "f :: \<tau>"}\\%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   106
\cmd{where}\isanewline%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   107
\ \ {\it equations}\isanewline%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   108
\ \ \quad\vdots
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   109
}}
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   110
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   111
\begin{isamarkuptext}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   112
\vspace*{1em}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   113
\noindent abbreviates
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   114
\end{isamarkuptext}
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   115
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   116
\fbox{\parbox{\textwidth}{
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   117
\noindent\cmd{function} @{text "("}\cmd{sequential}@{text ") f :: \<tau>"}\\%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   118
\cmd{where}\isanewline%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   119
\ \ {\it equations}\isanewline%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   120
\ \ \quad\vdots\\%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   121
\cmd{by} @{text "pat_completeness auto"}\\%
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   122
\cmd{termination by} @{text "lexicographic_order"}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   123
}}
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   124
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   125
\begin{isamarkuptext}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   126
  \vspace*{1em}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   127
  \noindent Some declarations and proofs have now become explicit:
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   128
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   129
  \begin{enumerate}
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   130
  \item The \cmd{sequential} option enables the preprocessing of
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   131
  pattern overlaps we already saw. Without this option, the equations
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   132
  must already be disjoint and complete. The automatic completion only
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   133
  works with datatype patterns.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   134
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   135
  \item A function definition now produces a proof obligation which
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   136
  expresses completeness and compatibility of patterns (We talk about
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   137
  this later). The combination of the methods @{text "pat_completeness"} and
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   138
  @{text "auto"} is used to solve this proof obligation.
21212
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
  \item A termination proof follows the definition, started by the
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   141
  \cmd{termination} command, which sets up the goal. The @{text
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   142
  "lexicographic_order"} method can prove termination of a certain
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   143
  class of functions by searching for a suitable lexicographic
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   144
  combination of size measures.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   145
 \end{enumerate}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   146
  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
   147
  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
   148
  what is actually going on.
21212
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   151
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   152
section {* Proving termination *}
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
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   155
  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
   156
  @{text "N"}, using a counter @{text "i"}:
21212
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
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   159
function sum :: "nat \<Rightarrow> nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   160
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   161
  "sum i N = (if i > N then 0 else i + sum (Suc i) N)"
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   162
by pat_completeness auto
21212
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
text {*
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   165
  \noindent The @{text "lexicographic_order"} method fails on this example, because none of the
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   166
  arguments decreases in the recursive call.
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
  A more general method for termination proofs is to supply a wellfounded
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   169
  relation on the argument type, and to show that the argument
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   170
  decreases in every recursive call. 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   171
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   172
  The termination argument for @{text "sum"} is based on the fact that
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   173
  the \emph{difference} between @{text "i"} and @{text "N"} gets
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   174
  smaller in every step, and that the recursion stops when @{text "i"}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   175
  is greater then @{text "n"}. Phrased differently, the expression 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   176
  @{text "N + 1 - i"} decreases in every recursive call.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   177
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   178
  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
   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
termination 
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   182
by (relation "measure (\<lambda>(i,N). N + 1 - i)") auto
21212
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
text {*
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   185
  The @{text relation} method takes a relation of
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   186
  type @{typ "('a \<times> 'a) set"}, where @{typ "'a"} is the argument type of
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   187
  the function. If the function has multiple curried arguments, then
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   188
  these are packed together into a tuple, as it happened in the above
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   189
  example.
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   190
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   191
  The predefined function @{term_type "measure"} is a very common way of
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   192
  specifying termination relations in terms of a mapping into the
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   193
  natural numbers.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   194
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   195
  After the invocation of @{text "relation"}, we must prove that (a)
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   196
  the relation we supplied is wellfounded, and (b) that the arguments
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   197
  of recursive calls indeed decrease with respect to the
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   198
  relation. These goals are all solved by the subsequent call to
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   199
  @{text "auto"}.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   200
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   201
  Let us complicate the function a little, by adding some more
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   202
  recursive calls: 
21212
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
function foo :: "nat \<Rightarrow> nat \<Rightarrow> nat"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   206
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   207
  "foo i N = (if i > N 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   208
              then (if N = 0 then 0 else foo 0 (N - 1))
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   209
              else i + foo (Suc i) N)"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   210
by pat_completeness auto
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   211
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   212
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   213
  When @{text "i"} has reached @{text "N"}, it starts at zero again
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   214
  and @{text "N"} is decremented.
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   215
  This corresponds to a nested
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   216
  loop where one index counts up and the other down. Termination can
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   217
  be proved using a lexicographic combination of two measures, namely
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   218
  the value of @{text "N"} and the above difference. The @{const
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   219
  "measures"} combinator generalizes @{text "measure"} by taking a
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   220
  list of measure functions.  
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   221
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   222
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   223
termination 
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   224
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
   225
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   226
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   227
section {* Mutual Recursion *}
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
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   230
  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
   231
  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
   232
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   233
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   234
function even :: "nat \<Rightarrow> bool"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   235
    and odd  :: "nat \<Rightarrow> bool"
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   236
where
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   237
  "even 0 = True"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   238
| "odd 0 = False"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   239
| "even (Suc n) = odd n"
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   240
| "odd (Suc n) = even n"
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   241
by pat_completeness auto
21212
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
text {*
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   244
  To solve the problem of mutual dependencies, Isabelle internally
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   245
  creates a single function operating on the sum
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   246
  type. Then the original functions are defined as
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   247
  projections. Consequently, termination has to be proved
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   248
  simultaneously for both functions, by specifying a measure on the
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   249
  sum type: 
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   250
*}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   251
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   252
termination 
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   253
by (relation "measure (\<lambda>x. case x of Inl n \<Rightarrow> n | Inr n \<Rightarrow> n)") 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   254
   auto
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   255
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   256
subsection {* Induction for mutual recursion *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   257
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   258
text {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   259
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   260
  When functions are mutually recursive, proving properties about them
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   261
  generally requires simultaneous induction. The induction rules
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   262
  generated from the definitions reflect this.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   263
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   264
  Let us prove something about @{const even} and @{const odd}:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   265
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   266
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   267
lemma 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   268
  "even n = (n mod 2 = 0)"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   269
  "odd n = (n mod 2 = 1)"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   270
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   271
txt {* 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   272
  We apply simultaneous induction, specifying the induction variable
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   273
  for both goals, separated by \cmd{and}:  *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   274
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   275
apply (induct n and n rule: even_odd.induct)
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   276
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   277
txt {* 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   278
  We get four subgoals, which correspond to the clauses in the
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   279
  definition of @{const even} and @{const odd}:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   280
  @{subgoals[display,indent=0]}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   281
  Simplification solves the first two goals, leaving us with two
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   282
  statements about the @{text "mod"} operation to prove:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   283
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   284
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   285
apply simp_all
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   286
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   287
txt {* 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   288
  @{subgoals[display,indent=0]} 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   289
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   290
  \noindent These can be handeled by the descision procedure for
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   291
  presburger arithmethic.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   292
  
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   293
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   294
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   295
apply presburger
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   296
apply presburger
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   297
done
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   298
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   299
text {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   300
  Even if we were just interested in one of the statements proved by
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   301
  simultaneous induction, the other ones may be necessary to
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   302
  strengthen the induction hypothesis. If we had left out the statement
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   303
  about @{const odd} (by substituting it with @{term "True"}, our
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   304
  proof would have failed:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   305
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   306
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   307
lemma 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   308
  "even n = (n mod 2 = 0)"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   309
  "True"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   310
apply (induct n rule: even_odd.induct)
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   311
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   312
txt {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   313
  \noindent Now the third subgoal is a dead end, since we have no
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   314
  useful induction hypothesis:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   315
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   316
  @{subgoals[display,indent=0]} 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   317
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   318
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   319
oops
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   320
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   321
section {* More general patterns *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   322
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   323
subsection {* Avoiding pattern splitting *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   324
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   325
text {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   326
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   327
  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
   328
  patterns were always disjoint and complete, and if they weren't,
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   329
  they were made disjoint automatically like in the definition of
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   330
  @{const "sep"} in \S\ref{patmatch}.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   331
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   332
  This splitting can significantly increase the number of equations
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   333
  involved, and is not always necessary. The following simple example
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   334
  shows the problem:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   335
  
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   336
  Suppose we are modelling incomplete knowledge about the world by a
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   337
  three-valued datatype, which has values for @{term "T"}, @{term "F"}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   338
  and @{term "X"} for true, false and uncertain propositions. 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   339
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   340
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   341
datatype P3 = T | F | X
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   342
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   343
text {* Then the conjunction of such values can be defined as follows: *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   344
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   345
fun And :: "P3 \<Rightarrow> P3 \<Rightarrow> P3"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   346
where
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   347
  "And T p = p"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   348
  "And p T = p"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   349
  "And p F = F"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   350
  "And F p = F"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   351
  "And X X = X"
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   352
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   353
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   354
text {* 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   355
  This definition is useful, because the equations can directly be used
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   356
  as rules to simplify expressions. But the patterns overlap, e.g.~the
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   357
  expression @{term "And T T"} is matched by the first two
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   358
  equations. By default, Isabelle makes the patterns disjoint by
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   359
  splitting them up, producing instances:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   360
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   361
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   362
thm And.simps
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   363
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   364
text {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   365
  @{thm[indent=4] And.simps}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   366
  
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   367
  \vspace*{1em}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   368
  \noindent There are several problems with this approach:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   369
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   370
  \begin{enumerate}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   371
  \item When datatypes have many constructors, there can be an
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   372
  explosion of equations. For @{const "And"}, we get seven instead of
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   373
  five equation, which can be tolerated, but this is just a small
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   374
  example.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   375
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   376
  \item Since splitting makes the equations "more special", they
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   377
  do not always match in rewriting. While the term @{term "And x F"}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   378
  can be simplified to @{term "F"} by the original specification, a
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   379
  (manual) case split on @{term "x"} is now necessary.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   380
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   381
  \item The splitting also concerns the induction rule @{text
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   382
  "And.induct"}. Instead of five premises it now has seven, which
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   383
  means that our induction proofs will have more cases.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   384
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   385
  \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
   386
  back which we put in.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   387
  \end{enumerate}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   388
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   389
  On the other hand, a definition needs to be consistent and defining
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   390
  both @{term "f x = True"} and @{term "f x = False"} is a bad
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   391
  idea. So if we don't want Isabelle to mangle our definitions, we
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   392
  will have to prove that this is not necessary. By using the full
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   393
  definition form withour the \cmd{sequential} option, we get this
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   394
  behaviour: 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   395
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   396
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   397
function And2 :: "P3 \<Rightarrow> P3 \<Rightarrow> P3"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   398
where
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   399
  "And2 T p = p"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   400
  "And2 p T = p"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   401
  "And2 p F = F"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   402
  "And2 F p = F"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   403
  "And2 X X = X"
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   404
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   405
txt {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   406
  Now it is also time to look at the subgoals generated by a
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   407
  function definition. In this case, they are:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   408
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   409
  @{subgoals[display,indent=0]} 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   410
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   411
  The first subgoal expresses the completeness of the patterns. It has
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   412
  the form of an elimination rule and states that every @{term x} of
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   413
  the function's input type must match one of the patterns. It could
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   414
  be equivalently stated as a disjunction of existential statements: 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   415
@{term "(\<exists>p. x = (T, p)) \<or> (\<exists>p. x = (p, T)) \<or> (\<exists>p. x = (p, F)) \<or>
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   416
  (\<exists>p. x = (F, p)) \<or> (x = (X, X))"} If the patterns just involve
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   417
  datatypes, we can solve it with the @{text "pat_completeness"} method:
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   418
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   419
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   420
apply pat_completeness
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   421
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   422
txt {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   423
  The remaining subgoals express \emph{pattern compatibility}. We do
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   424
  allow that a value is matched by more than one patterns, but in this
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   425
  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
   426
  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
   427
  subgoal. Usually this needs injectivity of the constructors, which
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   428
  is used automatically by @{text "auto"}.
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   429
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   430
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   431
by auto
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   432
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   433
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   434
subsection {* Non-constructor patterns *}
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   435
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   436
text {* FIXME *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   437
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   438
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   439
subsection {* Non-constructor patterns *}
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   440
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   441
text {* FIXME *}
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   442
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   443
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   444
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   445
22065
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   446
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   447
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   448
section {* Partiality *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   449
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   450
text {* 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   451
  In HOL, all functions are total. A function @{term "f"} applied to
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   452
  @{term "x"} always has a value @{term "f x"}, and there is no notion
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   453
  of undefinedness. 
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   454
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   455
  FIXME
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   456
*}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   457
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   458
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   459
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   460
  
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   461
section {* Nested recursion *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   462
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   463
text {*
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   464
  
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   465
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   466
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   467
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   468
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   469
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   470
 FIXME *}
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   471
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   472
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   473
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   474
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   475
cdd077905eee added sections on mutual induction and patterns
krauss
parents: 21346
diff changeset
   476
21212
547224bf9348 Added a (stub of a) function tutorial
krauss
parents:
diff changeset
   477
end