doc-src/TutorialI/Inductive/Even.thy
author nipkow
Wed, 07 Nov 2007 18:19:04 +0100
changeset 25330 15bf0f47a87d
parent 23928 efee34ff4764
child 43508 381fdcab0f36
permissions -rw-r--r--
added inductive
paulson@10341
     1
(* ID:         $Id$ *)
berghofe@23842
     2
(*<*)theory Even imports Main uses "../../antiquote_setup.ML" begin(*>*)
paulson@10314
     3
berghofe@23842
     4
section{* The Set of Even Numbers *}
berghofe@23842
     5
berghofe@23842
     6
text {*
berghofe@23842
     7
\index{even numbers!defining inductively|(}%
berghofe@23842
     8
The set of even numbers can be inductively defined as the least set
berghofe@23842
     9
containing 0 and closed under the operation $+2$.  Obviously,
berghofe@23842
    10
\emph{even} can also be expressed using the divides relation (@{text dvd}). 
berghofe@23842
    11
We shall prove below that the two formulations coincide.  On the way we
berghofe@23842
    12
shall examine the primary means of reasoning about inductively defined
berghofe@23842
    13
sets: rule induction.
berghofe@23842
    14
*}
berghofe@23842
    15
berghofe@23842
    16
subsection{* Making an Inductive Definition *}
berghofe@23842
    17
berghofe@23842
    18
text {*
berghofe@23928
    19
Using \commdx{inductive\protect\_set}, we declare the constant @{text even} to be
berghofe@23842
    20
a set of natural numbers with the desired properties.
berghofe@23842
    21
*}
paulson@10314
    22
nipkow@25330
    23
inductive_set even :: "nat set" where
nipkow@25330
    24
zero[intro!]: "0 \<in> even" |
nipkow@25330
    25
step[intro!]: "n \<in> even \<Longrightarrow> (Suc (Suc n)) \<in> even"
paulson@10314
    26
berghofe@23842
    27
text {*
berghofe@23842
    28
An inductive definition consists of introduction rules.  The first one
berghofe@23842
    29
above states that 0 is even; the second states that if $n$ is even, then so
berghofe@23842
    30
is~$n+2$.  Given this declaration, Isabelle generates a fixed point
berghofe@23842
    31
definition for @{term even} and proves theorems about it,
berghofe@23842
    32
thus following the definitional approach (see {\S}\ref{sec:definitional}).
berghofe@23842
    33
These theorems
berghofe@23842
    34
include the introduction rules specified in the declaration, an elimination
berghofe@23842
    35
rule for case analysis and an induction rule.  We can refer to these
berghofe@23842
    36
theorems by automatically-generated names.  Here are two examples:
berghofe@23842
    37
@{named_thms[display,indent=0] even.zero[no_vars] (even.zero) even.step[no_vars] (even.step)}
paulson@10314
    38
berghofe@23842
    39
The introduction rules can be given attributes.  Here
berghofe@23842
    40
both rules are specified as \isa{intro!},%
berghofe@23842
    41
\index{intro"!@\isa {intro"!} (attribute)}
berghofe@23842
    42
directing the classical reasoner to 
berghofe@23842
    43
apply them aggressively. Obviously, regarding 0 as even is safe.  The
berghofe@23842
    44
@{text step} rule is also safe because $n+2$ is even if and only if $n$ is
berghofe@23842
    45
even.  We prove this equivalence later.
berghofe@23842
    46
*}
paulson@10314
    47
berghofe@23842
    48
subsection{*Using Introduction Rules*}
paulson@10314
    49
berghofe@23842
    50
text {*
berghofe@23842
    51
Our first lemma states that numbers of the form $2\times k$ are even.
berghofe@23842
    52
Introduction rules are used to show that specific values belong to the
berghofe@23842
    53
inductive set.  Such proofs typically involve 
berghofe@23842
    54
induction, perhaps over some other inductive set.
berghofe@23842
    55
*}
paulson@10314
    56
wenzelm@11705
    57
lemma two_times_even[intro!]: "2*k \<in> even"
nipkow@12328
    58
apply (induct_tac k)
berghofe@23842
    59
 apply auto
berghofe@23842
    60
done
berghofe@23842
    61
(*<*)
berghofe@23842
    62
lemma "2*k \<in> even"
berghofe@23842
    63
apply (induct_tac k)
berghofe@23842
    64
(*>*)
berghofe@23842
    65
txt {*
berghofe@23842
    66
\noindent
berghofe@23842
    67
The first step is induction on the natural number @{text k}, which leaves
paulson@10883
    68
two subgoals:
paulson@10883
    69
@{subgoals[display,indent=0,margin=65]}
berghofe@23842
    70
Here @{text auto} simplifies both subgoals so that they match the introduction
berghofe@23842
    71
rules, which are then applied automatically.
paulson@10314
    72
berghofe@23842
    73
Our ultimate goal is to prove the equivalence between the traditional
berghofe@23842
    74
definition of @{text even} (using the divides relation) and our inductive
berghofe@23842
    75
definition.  One direction of this equivalence is immediate by the lemma
berghofe@23842
    76
just proved, whose @{text "intro!"} attribute ensures it is applied automatically.
berghofe@23842
    77
*}
berghofe@23842
    78
(*<*)oops(*>*)
wenzelm@11705
    79
lemma dvd_imp_even: "2 dvd n \<Longrightarrow> n \<in> even"
paulson@10883
    80
by (auto simp add: dvd_def)
paulson@10314
    81
berghofe@23842
    82
subsection{* Rule Induction \label{sec:rule-induction} *}
berghofe@23842
    83
berghofe@23842
    84
text {*
berghofe@23842
    85
\index{rule induction|(}%
berghofe@23842
    86
From the definition of the set
berghofe@23842
    87
@{term even}, Isabelle has
berghofe@23842
    88
generated an induction rule:
berghofe@23842
    89
@{named_thms [display,indent=0,margin=40] even.induct [no_vars] (even.induct)}
berghofe@23842
    90
A property @{term P} holds for every even number provided it
berghofe@23842
    91
holds for~@{text 0} and is closed under the operation
berghofe@23842
    92
\isa{Suc(Suc \(\cdot\))}.  Then @{term P} is closed under the introduction
berghofe@23842
    93
rules for @{term even}, which is the least set closed under those rules. 
berghofe@23842
    94
This type of inductive argument is called \textbf{rule induction}. 
berghofe@23842
    95
berghofe@23842
    96
Apart from the double application of @{term Suc}, the induction rule above
berghofe@23842
    97
resembles the familiar mathematical induction, which indeed is an instance
berghofe@23842
    98
of rule induction; the natural numbers can be defined inductively to be
berghofe@23842
    99
the least set containing @{text 0} and closed under~@{term Suc}.
berghofe@23842
   100
berghofe@23842
   101
Induction is the usual way of proving a property of the elements of an
berghofe@23842
   102
inductively defined set.  Let us prove that all members of the set
berghofe@23842
   103
@{term even} are multiples of two.
berghofe@23842
   104
*}
berghofe@23842
   105
wenzelm@11705
   106
lemma even_imp_dvd: "n \<in> even \<Longrightarrow> 2 dvd n"
berghofe@23842
   107
txt {*
berghofe@23842
   108
We begin by applying induction.  Note that @{text even.induct} has the form
berghofe@23842
   109
of an elimination rule, so we use the method @{text erule}.  We get two
berghofe@23842
   110
subgoals:
berghofe@23842
   111
*}
paulson@10314
   112
apply (erule even.induct)
berghofe@23842
   113
txt {*
berghofe@23842
   114
@{subgoals[display,indent=0]}
berghofe@23842
   115
We unfold the definition of @{text dvd} in both subgoals, proving the first
berghofe@23842
   116
one and simplifying the second:
berghofe@23842
   117
*}
paulson@10883
   118
apply (simp_all add: dvd_def)
berghofe@23842
   119
txt {*
berghofe@23842
   120
@{subgoals[display,indent=0]}
berghofe@23842
   121
The next command eliminates the existential quantifier from the assumption
berghofe@23842
   122
and replaces @{text n} by @{text "2 * k"}.
berghofe@23842
   123
*}
paulson@10314
   124
apply clarify
berghofe@23842
   125
txt {*
berghofe@23842
   126
@{subgoals[display,indent=0]}
berghofe@23842
   127
To conclude, we tell Isabelle that the desired value is
berghofe@23842
   128
@{term "Suc k"}.  With this hint, the subgoal falls to @{text simp}.
berghofe@23842
   129
*}
paulson@10883
   130
apply (rule_tac x = "Suc k" in exI, simp)
berghofe@23842
   131
(*<*)done(*>*)
paulson@10314
   132
berghofe@23842
   133
text {*
berghofe@23842
   134
Combining the previous two results yields our objective, the
berghofe@23842
   135
equivalence relating @{term even} and @{text dvd}. 
berghofe@23842
   136
%
berghofe@23842
   137
%we don't want [iff]: discuss?
berghofe@23842
   138
*}
paulson@10314
   139
wenzelm@11705
   140
theorem even_iff_dvd: "(n \<in> even) = (2 dvd n)"
paulson@10883
   141
by (blast intro: dvd_imp_even even_imp_dvd)
paulson@10314
   142
berghofe@23842
   143
berghofe@23842
   144
subsection{* Generalization and Rule Induction \label{sec:gen-rule-induction} *}
berghofe@23842
   145
berghofe@23842
   146
text {*
berghofe@23842
   147
\index{generalizing for induction}%
berghofe@23842
   148
Before applying induction, we typically must generalize
berghofe@23842
   149
the induction formula.  With rule induction, the required generalization
berghofe@23842
   150
can be hard to find and sometimes requires a complete reformulation of the
berghofe@23842
   151
problem.  In this  example, our first attempt uses the obvious statement of
berghofe@23842
   152
the result.  It fails:
berghofe@23842
   153
*}
berghofe@23842
   154
berghofe@23842
   155
lemma "Suc (Suc n) \<in> even \<Longrightarrow> n \<in> even"
paulson@10314
   156
apply (erule even.induct)
paulson@10314
   157
oops
berghofe@23842
   158
(*<*)
berghofe@23842
   159
lemma "Suc (Suc n) \<in> even \<Longrightarrow> n \<in> even"
berghofe@23842
   160
apply (erule even.induct)
berghofe@23842
   161
(*>*)
berghofe@23842
   162
txt {*
berghofe@23842
   163
Rule induction finds no occurrences of @{term "Suc(Suc n)"} in the
berghofe@23842
   164
conclusion, which it therefore leaves unchanged.  (Look at
berghofe@23842
   165
@{text even.induct} to see why this happens.)  We have these subgoals:
berghofe@23842
   166
@{subgoals[display,indent=0]}
berghofe@23842
   167
The first one is hopeless.  Rule induction on
berghofe@23842
   168
a non-variable term discards information, and usually fails.
berghofe@23842
   169
How to deal with such situations
berghofe@23842
   170
in general is described in {\S}\ref{sec:ind-var-in-prems} below.
berghofe@23842
   171
In the current case the solution is easy because
berghofe@23842
   172
we have the necessary inverse, subtraction:
berghofe@23842
   173
*}
berghofe@23842
   174
(*<*)oops(*>*)
wenzelm@11705
   175
lemma even_imp_even_minus_2: "n \<in> even \<Longrightarrow> n - 2 \<in> even"
paulson@10314
   176
apply (erule even.induct)
berghofe@23842
   177
 apply auto
paulson@10314
   178
done
berghofe@23842
   179
(*<*)
berghofe@23842
   180
lemma "n \<in>  even \<Longrightarrow> n - 2 \<in> even"
berghofe@23842
   181
apply (erule even.induct)
berghofe@23842
   182
(*>*)
berghofe@23842
   183
txt {*
berghofe@23842
   184
This lemma is trivially inductive.  Here are the subgoals:
berghofe@23842
   185
@{subgoals[display,indent=0]}
berghofe@23842
   186
The first is trivial because @{text "0 - 2"} simplifies to @{text 0}, which is
berghofe@23842
   187
even.  The second is trivial too: @{term "Suc (Suc n) - 2"} simplifies to
berghofe@23842
   188
@{term n}, matching the assumption.%
berghofe@23842
   189
\index{rule induction|)}  %the sequel isn't really about induction
paulson@10314
   190
berghofe@23842
   191
\medskip
berghofe@23842
   192
Using our lemma, we can easily prove the result we originally wanted:
berghofe@23842
   193
*}
berghofe@23842
   194
(*<*)oops(*>*)
paulson@10314
   195
lemma Suc_Suc_even_imp_even: "Suc (Suc n) \<in> even \<Longrightarrow> n \<in> even"
paulson@10883
   196
by (drule even_imp_even_minus_2, simp)
paulson@10883
   197
berghofe@23842
   198
text {*
berghofe@23842
   199
We have just proved the converse of the introduction rule @{text even.step}.
berghofe@23842
   200
This suggests proving the following equivalence.  We give it the
berghofe@23842
   201
\attrdx{iff} attribute because of its obvious value for simplification.
berghofe@23842
   202
*}
paulson@10314
   203
paulson@10326
   204
lemma [iff]: "((Suc (Suc n)) \<in> even) = (n \<in> even)"
paulson@10883
   205
by (blast dest: Suc_Suc_even_imp_even)
paulson@10314
   206
paulson@10314
   207
berghofe@23842
   208
subsection{* Rule Inversion \label{sec:rule-inversion} *}
berghofe@23842
   209
berghofe@23842
   210
text {*
berghofe@23842
   211
\index{rule inversion|(}%
berghofe@23842
   212
Case analysis on an inductive definition is called \textbf{rule
berghofe@23842
   213
inversion}.  It is frequently used in proofs about operational
berghofe@23842
   214
semantics.  It can be highly effective when it is applied
berghofe@23842
   215
automatically.  Let us look at how rule inversion is done in
berghofe@23842
   216
Isabelle/HOL\@.
berghofe@23842
   217
berghofe@23842
   218
Recall that @{term even} is the minimal set closed under these two rules:
berghofe@23842
   219
@{thm [display,indent=0] even.intros [no_vars]}
berghofe@23842
   220
Minimality means that @{term even} contains only the elements that these
berghofe@23842
   221
rules force it to contain.  If we are told that @{term a}
berghofe@23842
   222
belongs to
berghofe@23842
   223
@{term even} then there are only two possibilities.  Either @{term a} is @{text 0}
berghofe@23842
   224
or else @{term a} has the form @{term "Suc(Suc n)"}, for some suitable @{term n}
berghofe@23842
   225
that belongs to
berghofe@23842
   226
@{term even}.  That is the gist of the @{term cases} rule, which Isabelle proves
berghofe@23842
   227
for us when it accepts an inductive definition:
berghofe@23842
   228
@{named_thms [display,indent=0,margin=40] even.cases [no_vars] (even.cases)}
berghofe@23842
   229
This general rule is less useful than instances of it for
berghofe@23842
   230
specific patterns.  For example, if @{term a} has the form
berghofe@23842
   231
@{term "Suc(Suc n)"} then the first case becomes irrelevant, while the second
berghofe@23842
   232
case tells us that @{term n} belongs to @{term even}.  Isabelle will generate
berghofe@23842
   233
this instance for us:
berghofe@23842
   234
*}
berghofe@23842
   235
berghofe@23842
   236
inductive_cases Suc_Suc_cases [elim!]: "Suc(Suc n) \<in> even"
berghofe@23842
   237
berghofe@23842
   238
text {*
berghofe@23842
   239
The \commdx{inductive\protect\_cases} command generates an instance of
berghofe@23842
   240
the @{text cases} rule for the supplied pattern and gives it the supplied name:
berghofe@23842
   241
@{named_thms [display,indent=0] Suc_Suc_cases [no_vars] (Suc_Suc_cases)}
berghofe@23842
   242
Applying this as an elimination rule yields one case where @{text even.cases}
berghofe@23842
   243
would yield two.  Rule inversion works well when the conclusions of the
berghofe@23842
   244
introduction rules involve datatype constructors like @{term Suc} and @{text "#"}
berghofe@23842
   245
(list ``cons''); freeness reasoning discards all but one or two cases.
berghofe@23842
   246
berghofe@23842
   247
In the \isacommand{inductive\_cases} command we supplied an
berghofe@23842
   248
attribute, @{text "elim!"},
berghofe@23842
   249
\index{elim"!@\isa {elim"!} (attribute)}%
berghofe@23842
   250
indicating that this elimination rule can be
berghofe@23842
   251
applied aggressively.  The original
berghofe@23842
   252
@{term cases} rule would loop if used in that manner because the
berghofe@23842
   253
pattern~@{term a} matches everything.
berghofe@23842
   254
berghofe@23842
   255
The rule @{text Suc_Suc_cases} is equivalent to the following implication:
berghofe@23842
   256
@{term [display,indent=0] "Suc (Suc n) \<in> even \<Longrightarrow> n \<in> even"}
berghofe@23842
   257
Just above we devoted some effort to reaching precisely
berghofe@23842
   258
this result.  Yet we could have obtained it by a one-line declaration,
berghofe@23842
   259
dispensing with the lemma @{text even_imp_even_minus_2}. 
berghofe@23842
   260
This example also justifies the terminology
berghofe@23842
   261
\textbf{rule inversion}: the new rule inverts the introduction rule
berghofe@23842
   262
@{text even.step}.  In general, a rule can be inverted when the set of elements
berghofe@23842
   263
it introduces is disjoint from those of the other introduction rules.
berghofe@23842
   264
berghofe@23842
   265
For one-off applications of rule inversion, use the \methdx{ind_cases} method. 
berghofe@23842
   266
Here is an example:
berghofe@23842
   267
*}
berghofe@23842
   268
berghofe@23842
   269
(*<*)lemma "Suc(Suc n) \<in> even \<Longrightarrow> P"(*>*)
berghofe@23842
   270
apply (ind_cases "Suc(Suc n) \<in> even")
berghofe@23842
   271
(*<*)oops(*>*)
berghofe@23842
   272
berghofe@23842
   273
text {*
berghofe@23842
   274
The specified instance of the @{text cases} rule is generated, then applied
berghofe@23842
   275
as an elimination rule.
berghofe@23842
   276
berghofe@23842
   277
To summarize, every inductive definition produces a @{text cases} rule.  The
berghofe@23842
   278
\commdx{inductive\protect\_cases} command stores an instance of the
berghofe@23842
   279
@{text cases} rule for a given pattern.  Within a proof, the
berghofe@23842
   280
@{text ind_cases} method applies an instance of the @{text cases}
berghofe@23842
   281
rule.
berghofe@23842
   282
berghofe@23842
   283
The even numbers example has shown how inductive definitions can be
berghofe@23842
   284
used.  Later examples will show that they are actually worth using.%
berghofe@23842
   285
\index{rule inversion|)}%
berghofe@23842
   286
\index{even numbers!defining inductively|)}
berghofe@23842
   287
*}
berghofe@23842
   288
berghofe@23842
   289
(*<*)end(*>*)