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