1 (* Title: HOL/Induct/Common_Patterns.thy
5 header {* Common patterns of induction *}
12 The subsequent Isar proof schemes illustrate common proof patterns
13 supported by the generic @{text "induct"} method.
15 To demonstrate variations on statement (goal) structure we refer to
16 the induction rule of Peano natural numbers: @{thm nat.induct
17 [no_vars]}, which is the simplest case of datatype induction. We
18 shall also see more complex (mutual) datatype inductions involving
19 several rules. Working with inductive predicates is similar, but
20 involves explicit facts about membership, instead of implicit
25 subsection {* Variations on statement structure *}
27 subsubsection {* Local facts and parameters *}
30 Augmenting a problem by additional facts and locally fixed variables
31 is a bread-and-butter method in many applications. This is where
32 unwieldy object-level @{text "\<forall>"} and @{text "\<longrightarrow>"} used to occur in
33 the past. The @{text "induct"} method works with primary means of
34 the proof language instead.
41 shows "P n x" using `A n x`
42 proof (induct n arbitrary: x)
48 note hyp = `\<And>x. A n x \<Longrightarrow> P n x`
49 and prem = `A (Suc n) x`
50 show "P (Suc n) x" sorry
54 subsubsection {* Local definitions *}
57 Here the idea is to turn sub-expressions of the problem into a
58 defined induction variable. This is often accompanied with fixing
59 of auxiliary parameters in the original expression, otherwise the
60 induction step would refer invariably to particular entities. This
61 combination essentially expresses a partially abstracted
62 representation of inductive expressions.
66 fixes a :: "'a \<Rightarrow> nat"
68 shows "P (a x)" using `A (a x)`
69 proof (induct n \<equiv> "a x" arbitrary: x)
76 note hyp = `\<And>x. A (a x) \<Longrightarrow> n = a x \<Longrightarrow> P (a x)`
78 and defn = `Suc n = a x`
83 Observe how the local definition @{text "n = a x"} recurs in the
84 inductive cases as @{text "0 = a x"} and @{text "Suc n = a x"},
85 according to underlying induction rule.
89 subsubsection {* Simple simultaneous goals *}
92 The most basic simultaneous induction operates on several goals
93 one-by-one, where each case refers to induction hypotheses that are
94 duplicated according to the number of conclusions.
108 note hyps = `P n` `Q n`
109 show "P (Suc n)" sorry
112 note hyps = `P n` `Q n`
113 show "Q (Suc n)" sorry
117 The split into subcases may be deferred as follows -- this is
118 particularly relevant for goal statements with local premises.
123 shows "A n \<Longrightarrow> P n"
124 and "B n \<Longrightarrow> Q n"
138 note `A n \<Longrightarrow> P n`
139 and `B n \<Longrightarrow> Q n`
143 show "P (Suc n)" sorry
147 show "Q (Suc n)" sorry
152 subsubsection {* Compound simultaneous goals *}
155 The following pattern illustrates the slightly more complex
156 situation of simultaneous goals with individual local assumptions.
157 In compound simultaneous statements like this, local assumptions
158 need to be included into each goal, using @{text "\<Longrightarrow>"} of the Pure
159 framework. In contrast, local parameters do not require separate
160 @{text "\<And>"} prefixes here, but may be moved into the common context
161 of the whole statement.
168 shows "A n x \<Longrightarrow> P n x"
169 and "B n y \<Longrightarrow> Q n y"
170 proof (induct n arbitrary: x y)
184 note hyps = `\<And>x. A n x \<Longrightarrow> P n x` `\<And>y. B n y \<Longrightarrow> Q n y`
185 then have some_intermediate_result sorry
188 note prem = `A (Suc n) x`
189 show "P (Suc n) x" sorry
193 note prem = `B (Suc n) y`
194 show "Q (Suc n) y" sorry
199 Here @{text "induct"} provides again nested cases with numbered
200 sub-cases, which allows to share common parts of the body context.
201 In typical applications, there could be a long intermediate proof of
202 general consequences of the induction hypotheses, before finishing
203 each conclusion separately.
207 subsection {* Multiple rules *}
210 Multiple induction rules emerge from mutual definitions of
211 datatypes, inductive predicates, functions etc. The @{text
212 "induct"} method accepts replicated arguments (with @{text "and"}
213 separator), corresponding to each projection of the induction
216 The goal statement essentially follows the same arrangement,
217 although it might be subdivided into simultaneous sub-problems as
221 datatype foo = Foo1 nat | Foo2 bar
222 and bar = Bar1 bool | Bar2 bazar
223 and bazar = Bazar foo
226 The pack of induction rules for this datatype is: @{thm [display]
227 foo_bar_bazar.inducts [no_vars]}
229 This corresponds to the following basic proof pattern:
239 proof (induct foo and bar and bazar)
241 show "P (Foo1 n)" sorry
245 show "P (Foo2 bar)" sorry
248 show "Q (Bar1 b)" sorry
252 show "Q (Bar2 bazar)" sorry
256 show "R (Bazar foo)" sorry
260 This can be combined with the previous techniques for compound
261 statements, e.g.\ like this.
265 fixes x :: 'a and y :: 'b and z :: 'c
270 "A x foo \<Longrightarrow> P x foo"
272 "B1 y bar \<Longrightarrow> Q1 y bar"
273 "B2 y bar \<Longrightarrow> Q2 y bar"
275 "C1 z bazar \<Longrightarrow> R1 z bazar"
276 "C2 z bazar \<Longrightarrow> R2 z bazar"
277 "C3 z bazar \<Longrightarrow> R3 z bazar"
278 proof (induct foo and bar and bazar arbitrary: x and y and z)
282 subsection {* Inductive predicates *}
285 The most basic form of induction involving predicates (or sets)
286 essentially eliminates a given membership fact.
289 inductive Even :: "nat \<Rightarrow> bool" where
291 | double: "Even n \<Longrightarrow> Even (2 * n)"
302 note `Even n` and `P n`
303 show "P (2 * n)" sorry
307 Alternatively, an initial rule statement may be proven as follows,
308 performing ``in-situ'' elimination with explicit rule specification.
311 lemma "Even n \<Longrightarrow> P n"
312 proof (induct rule: Even.induct)
316 Simultaneous goals do not introduce anything new.
321 shows "P1 n" and "P2 n"
334 note `Even n` and `P1 n` and `P2 n`
337 show "P1 (2 * n)" sorry
340 show "P2 (2 * n)" sorry
345 Working with mutual rules requires special care in composing the
346 statement as a two-level conjunction, using lists of propositions
347 separated by @{text "and"}. For example:
350 inductive Evn :: "nat \<Rightarrow> bool" and Odd :: "nat \<Rightarrow> bool"
353 | succ_Evn: "Evn n \<Longrightarrow> Odd (Suc n)"
354 | succ_Odd: "Odd n \<Longrightarrow> Evn (Suc n)"
357 "Evn n \<Longrightarrow> P1 n"
358 "Evn n \<Longrightarrow> P2 n"
359 "Evn n \<Longrightarrow> P3 n"
361 "Odd n \<Longrightarrow> Q1 n"
362 "Odd n \<Longrightarrow> Q2 n"
363 proof (induct rule: Evn_Odd.inducts)
365 { case 1 show "P1 0" sorry }
366 { case 2 show "P2 0" sorry }
367 { case 3 show "P3 0" sorry }
370 note `Evn n` and `P1 n` `P2 n` `P3 n`
371 { case 1 show "Q1 (Suc n)" sorry }
372 { case 2 show "Q2 (Suc n)" sorry }
375 note `Odd n` and `Q1 n` `Q2 n`
376 { case 1 show "P1 (Suc n)" sorry }
377 { case 2 show "P2 (Suc n)" sorry }
378 { case 3 show "P3 (Suc n)" sorry }