1 (*<*) |
1 (*<*) |
2 theory AdvancedInd imports Main begin |
2 theory AdvancedInd imports Main begin |
3 (*>*) |
3 (*>*) |
4 |
4 |
5 text{*\noindent |
5 text\<open>\noindent |
6 Now that we have learned about rules and logic, we take another look at the |
6 Now that we have learned about rules and logic, we take another look at the |
7 finer points of induction. We consider two questions: what to do if the |
7 finer points of induction. We consider two questions: what to do if the |
8 proposition to be proved is not directly amenable to induction |
8 proposition to be proved is not directly amenable to induction |
9 (\S\ref{sec:ind-var-in-prems}), and how to utilize (\S\ref{sec:complete-ind}) |
9 (\S\ref{sec:ind-var-in-prems}), and how to utilize (\S\ref{sec:complete-ind}) |
10 and even derive (\S\ref{sec:derive-ind}) new induction schemas. We conclude |
10 and even derive (\S\ref{sec:derive-ind}) new induction schemas. We conclude |
11 with an extended example of induction (\S\ref{sec:CTL-revisited}). |
11 with an extended example of induction (\S\ref{sec:CTL-revisited}). |
12 *} |
12 \<close> |
13 |
13 |
14 subsection{*Massaging the Proposition*} |
14 subsection\<open>Massaging the Proposition\<close> |
15 |
15 |
16 text{*\label{sec:ind-var-in-prems} |
16 text\<open>\label{sec:ind-var-in-prems} |
17 Often we have assumed that the theorem to be proved is already in a form |
17 Often we have assumed that the theorem to be proved is already in a form |
18 that is amenable to induction, but sometimes it isn't. |
18 that is amenable to induction, but sometimes it isn't. |
19 Here is an example. |
19 Here is an example. |
20 Since @{term"hd"} and @{term"last"} return the first and last element of a |
20 Since @{term"hd"} and @{term"last"} return the first and last element of a |
21 non-empty list, this lemma looks easy to prove: |
21 non-empty list, this lemma looks easy to prove: |
22 *} |
22 \<close> |
23 |
23 |
24 lemma "xs \<noteq> [] \<Longrightarrow> hd(rev xs) = last xs" |
24 lemma "xs \<noteq> [] \<Longrightarrow> hd(rev xs) = last xs" |
25 apply(induct_tac xs) |
25 apply(induct_tac xs) |
26 |
26 |
27 txt{*\noindent |
27 txt\<open>\noindent |
28 But induction produces the warning |
28 But induction produces the warning |
29 \begin{quote}\tt |
29 \begin{quote}\tt |
30 Induction variable occurs also among premises! |
30 Induction variable occurs also among premises! |
31 \end{quote} |
31 \end{quote} |
32 and leads to the base case |
32 and leads to the base case |
49 \end{quote} |
49 \end{quote} |
50 Thus we should state the lemma as an ordinary |
50 Thus we should state the lemma as an ordinary |
51 implication~(@{text"\<longrightarrow>"}), letting |
51 implication~(@{text"\<longrightarrow>"}), letting |
52 \attrdx{rule_format} (\S\ref{sec:forward}) convert the |
52 \attrdx{rule_format} (\S\ref{sec:forward}) convert the |
53 result to the usual @{text"\<Longrightarrow>"} form: |
53 result to the usual @{text"\<Longrightarrow>"} form: |
54 *} |
54 \<close> |
55 (*<*)oops(*>*) |
55 (*<*)oops(*>*) |
56 lemma hd_rev [rule_format]: "xs \<noteq> [] \<longrightarrow> hd(rev xs) = last xs" |
56 lemma hd_rev [rule_format]: "xs \<noteq> [] \<longrightarrow> hd(rev xs) = last xs" |
57 (*<*) |
57 (*<*) |
58 apply(induct_tac xs) |
58 apply(induct_tac xs) |
59 (*>*) |
59 (*>*) |
60 |
60 |
61 txt{*\noindent |
61 txt\<open>\noindent |
62 This time, induction leaves us with a trivial base case: |
62 This time, induction leaves us with a trivial base case: |
63 @{subgoals[display,indent=0,goals_limit=1]} |
63 @{subgoals[display,indent=0,goals_limit=1]} |
64 And @{text"auto"} completes the proof. |
64 And @{text"auto"} completes the proof. |
65 |
65 |
66 If there are multiple premises $A@1$, \dots, $A@n$ containing the |
66 If there are multiple premises $A@1$, \dots, $A@n$ containing the |
107 where $\overline{y}$ stands for $y@1 \dots y@n$ and the dependence of $t$ and |
107 where $\overline{y}$ stands for $y@1 \dots y@n$ and the dependence of $t$ and |
108 $C$ on the free variables of $t$ has been made explicit. |
108 $C$ on the free variables of $t$ has been made explicit. |
109 Unfortunately, this induction schema cannot be expressed as a |
109 Unfortunately, this induction schema cannot be expressed as a |
110 single theorem because it depends on the number of free variables in $t$ --- |
110 single theorem because it depends on the number of free variables in $t$ --- |
111 the notation $\overline{y}$ is merely an informal device. |
111 the notation $\overline{y}$ is merely an informal device. |
112 *} |
112 \<close> |
113 (*<*)by auto(*>*) |
113 (*<*)by auto(*>*) |
114 |
114 |
115 subsection{*Beyond Structural and Recursion Induction*} |
115 subsection\<open>Beyond Structural and Recursion Induction\<close> |
116 |
116 |
117 text{*\label{sec:complete-ind} |
117 text\<open>\label{sec:complete-ind} |
118 So far, inductive proofs were by structural induction for |
118 So far, inductive proofs were by structural induction for |
119 primitive recursive functions and recursion induction for total recursive |
119 primitive recursive functions and recursion induction for total recursive |
120 functions. But sometimes structural induction is awkward and there is no |
120 functions. But sometimes structural induction is awkward and there is no |
121 recursive function that could furnish a more appropriate |
121 recursive function that could furnish a more appropriate |
122 induction schema. In such cases a general-purpose induction schema can |
122 induction schema. In such cases a general-purpose induction schema can |
128 induction, where you prove $P(n)$ under the assumption that $P(m)$ |
128 induction, where you prove $P(n)$ under the assumption that $P(m)$ |
129 holds for all $m<n$. In Isabelle, this is the theorem \tdx{nat_less_induct}: |
129 holds for all $m<n$. In Isabelle, this is the theorem \tdx{nat_less_induct}: |
130 @{thm[display]"nat_less_induct"[no_vars]} |
130 @{thm[display]"nat_less_induct"[no_vars]} |
131 As an application, we prove a property of the following |
131 As an application, we prove a property of the following |
132 function: |
132 function: |
133 *} |
133 \<close> |
134 |
134 |
135 axiomatization f :: "nat \<Rightarrow> nat" |
135 axiomatization f :: "nat \<Rightarrow> nat" |
136 where f_ax: "f(f(n)) < f(Suc(n))" for n :: nat |
136 where f_ax: "f(f(n)) < f(Suc(n))" for n :: nat |
137 |
137 |
138 text{* |
138 text\<open> |
139 \begin{warn} |
139 \begin{warn} |
140 We discourage the use of axioms because of the danger of |
140 We discourage the use of axioms because of the danger of |
141 inconsistencies. Axiom @{text f_ax} does |
141 inconsistencies. Axiom @{text f_ax} does |
142 not introduce an inconsistency because, for example, the identity function |
142 not introduce an inconsistency because, for example, the identity function |
143 satisfies it. Axioms can be useful in exploratory developments, say when |
143 satisfies it. Axioms can be useful in exploratory developments, say when |
146 development, you should replace axioms by theorems. |
146 development, you should replace axioms by theorems. |
147 \end{warn}\noindent |
147 \end{warn}\noindent |
148 The axiom for @{term"f"} implies @{prop"n <= f n"}, which can |
148 The axiom for @{term"f"} implies @{prop"n <= f n"}, which can |
149 be proved by induction on \mbox{@{term"f n"}}. Following the recipe outlined |
149 be proved by induction on \mbox{@{term"f n"}}. Following the recipe outlined |
150 above, we have to phrase the proposition as follows to allow induction: |
150 above, we have to phrase the proposition as follows to allow induction: |
151 *} |
151 \<close> |
152 |
152 |
153 lemma f_incr_lem: "\<forall>i. k = f i \<longrightarrow> i \<le> f i" |
153 lemma f_incr_lem: "\<forall>i. k = f i \<longrightarrow> i \<le> f i" |
154 |
154 |
155 txt{*\noindent |
155 txt\<open>\noindent |
156 To perform induction on @{term k} using @{thm[source]nat_less_induct}, we use |
156 To perform induction on @{term k} using @{thm[source]nat_less_induct}, we use |
157 the same general induction method as for recursion induction (see |
157 the same general induction method as for recursion induction (see |
158 \S\ref{sec:fun-induction}): |
158 \S\ref{sec:fun-induction}): |
159 *} |
159 \<close> |
160 |
160 |
161 apply(induct_tac k rule: nat_less_induct) |
161 apply(induct_tac k rule: nat_less_induct) |
162 |
162 |
163 txt{*\noindent |
163 txt\<open>\noindent |
164 We get the following proof state: |
164 We get the following proof state: |
165 @{subgoals[display,indent=0,margin=65]} |
165 @{subgoals[display,indent=0,margin=65]} |
166 After stripping the @{text"\<forall>i"}, the proof continues with a case |
166 After stripping the @{text"\<forall>i"}, the proof continues with a case |
167 distinction on @{term"i"}. The case @{prop"i = (0::nat)"} is trivial and we focus on |
167 distinction on @{term"i"}. The case @{prop"i = (0::nat)"} is trivial and we focus on |
168 the other case: |
168 the other case: |
169 *} |
169 \<close> |
170 |
170 |
171 apply(rule allI) |
171 apply(rule allI) |
172 apply(case_tac i) |
172 apply(case_tac i) |
173 apply(simp) |
173 apply(simp) |
174 txt{* |
174 txt\<open> |
175 @{subgoals[display,indent=0]} |
175 @{subgoals[display,indent=0]} |
176 *} |
176 \<close> |
177 by(blast intro!: f_ax Suc_leI intro: le_less_trans) |
177 by(blast intro!: f_ax Suc_leI intro: le_less_trans) |
178 |
178 |
179 text{*\noindent |
179 text\<open>\noindent |
180 If you find the last step puzzling, here are the two lemmas it employs: |
180 If you find the last step puzzling, here are the two lemmas it employs: |
181 \begin{isabelle} |
181 \begin{isabelle} |
182 @{thm Suc_leI[no_vars]} |
182 @{thm Suc_leI[no_vars]} |
183 \rulename{Suc_leI}\isanewline |
183 \rulename{Suc_leI}\isanewline |
184 @{thm le_less_trans[no_vars]} |
184 @{thm le_less_trans[no_vars]} |
201 will usually not tell you how the proof goes, because it can be hard to |
201 will usually not tell you how the proof goes, because it can be hard to |
202 translate the internal proof into a human-readable format. Automatic |
202 translate the internal proof into a human-readable format. Automatic |
203 proofs are easy to write but hard to read and understand. |
203 proofs are easy to write but hard to read and understand. |
204 |
204 |
205 The desired result, @{prop"i <= f i"}, follows from @{thm[source]f_incr_lem}: |
205 The desired result, @{prop"i <= f i"}, follows from @{thm[source]f_incr_lem}: |
206 *} |
206 \<close> |
207 |
207 |
208 lemmas f_incr = f_incr_lem[rule_format, OF refl] |
208 lemmas f_incr = f_incr_lem[rule_format, OF refl] |
209 |
209 |
210 text{*\noindent |
210 text\<open>\noindent |
211 The final @{thm[source]refl} gets rid of the premise @{text"?k = f ?i"}. |
211 The final @{thm[source]refl} gets rid of the premise @{text"?k = f ?i"}. |
212 We could have included this derivation in the original statement of the lemma: |
212 We could have included this derivation in the original statement of the lemma: |
213 *} |
213 \<close> |
214 |
214 |
215 lemma f_incr[rule_format, OF refl]: "\<forall>i. k = f i \<longrightarrow> i \<le> f i" |
215 lemma f_incr[rule_format, OF refl]: "\<forall>i. k = f i \<longrightarrow> i \<le> f i" |
216 (*<*)oops(*>*) |
216 (*<*)oops(*>*) |
217 |
217 |
218 text{* |
218 text\<open> |
219 \begin{exercise} |
219 \begin{exercise} |
220 From the axiom and lemma for @{term"f"}, show that @{term"f"} is the |
220 From the axiom and lemma for @{term"f"}, show that @{term"f"} is the |
221 identity function. |
221 identity function. |
222 \end{exercise} |
222 \end{exercise} |
223 |
223 |
233 induction on the length of a list\indexbold{*length_induct} |
233 induction on the length of a list\indexbold{*length_induct} |
234 @{thm[display]length_induct[no_vars]} |
234 @{thm[display]length_induct[no_vars]} |
235 which is a special case of @{thm[source]measure_induct} |
235 which is a special case of @{thm[source]measure_induct} |
236 @{thm[display]measure_induct[no_vars]} |
236 @{thm[display]measure_induct[no_vars]} |
237 where @{term f} may be any function into type @{typ nat}. |
237 where @{term f} may be any function into type @{typ nat}. |
238 *} |
238 \<close> |
239 |
239 |
240 subsection{*Derivation of New Induction Schemas*} |
240 subsection\<open>Derivation of New Induction Schemas\<close> |
241 |
241 |
242 text{*\label{sec:derive-ind} |
242 text\<open>\label{sec:derive-ind} |
243 \index{induction!deriving new schemas}% |
243 \index{induction!deriving new schemas}% |
244 Induction schemas are ordinary theorems and you can derive new ones |
244 Induction schemas are ordinary theorems and you can derive new ones |
245 whenever you wish. This section shows you how, using the example |
245 whenever you wish. This section shows you how, using the example |
246 of @{thm[source]nat_less_induct}. Assume we only have structural induction |
246 of @{thm[source]nat_less_induct}. Assume we only have structural induction |
247 available for @{typ"nat"} and want to derive complete induction. We |
247 available for @{typ"nat"} and want to derive complete induction. We |
248 must generalize the statement as shown: |
248 must generalize the statement as shown: |
249 *} |
249 \<close> |
250 |
250 |
251 lemma induct_lem: "(\<And>n::nat. \<forall>m<n. P m \<Longrightarrow> P n) \<Longrightarrow> \<forall>m<n. P m" |
251 lemma induct_lem: "(\<And>n::nat. \<forall>m<n. P m \<Longrightarrow> P n) \<Longrightarrow> \<forall>m<n. P m" |
252 apply(induct_tac n) |
252 apply(induct_tac n) |
253 |
253 |
254 txt{*\noindent |
254 txt\<open>\noindent |
255 The base case is vacuously true. For the induction step (@{prop"m < |
255 The base case is vacuously true. For the induction step (@{prop"m < |
256 Suc n"}) we distinguish two cases: case @{prop"m < n"} is true by induction |
256 Suc n"}) we distinguish two cases: case @{prop"m < n"} is true by induction |
257 hypothesis and case @{prop"m = n"} follows from the assumption, again using |
257 hypothesis and case @{prop"m = n"} follows from the assumption, again using |
258 the induction hypothesis: |
258 the induction hypothesis: |
259 *} |
259 \<close> |
260 apply(blast) |
260 apply(blast) |
261 by(blast elim: less_SucE) |
261 by(blast elim: less_SucE) |
262 |
262 |
263 text{*\noindent |
263 text\<open>\noindent |
264 The elimination rule @{thm[source]less_SucE} expresses the case distinction: |
264 The elimination rule @{thm[source]less_SucE} expresses the case distinction: |
265 @{thm[display]"less_SucE"[no_vars]} |
265 @{thm[display]"less_SucE"[no_vars]} |
266 |
266 |
267 Now it is straightforward to derive the original version of |
267 Now it is straightforward to derive the original version of |
268 @{thm[source]nat_less_induct} by manipulating the conclusion of the above |
268 @{thm[source]nat_less_induct} by manipulating the conclusion of the above |
269 lemma: instantiate @{term"n"} by @{term"Suc n"} and @{term"m"} by @{term"n"} |
269 lemma: instantiate @{term"n"} by @{term"Suc n"} and @{term"m"} by @{term"n"} |
270 and remove the trivial condition @{prop"n < Suc n"}. Fortunately, this |
270 and remove the trivial condition @{prop"n < Suc n"}. Fortunately, this |
271 happens automatically when we add the lemma as a new premise to the |
271 happens automatically when we add the lemma as a new premise to the |
272 desired goal: |
272 desired goal: |
273 *} |
273 \<close> |
274 |
274 |
275 theorem nat_less_induct: "(\<And>n::nat. \<forall>m<n. P m \<Longrightarrow> P n) \<Longrightarrow> P n" |
275 theorem nat_less_induct: "(\<And>n::nat. \<forall>m<n. P m \<Longrightarrow> P n) \<Longrightarrow> P n" |
276 by(insert induct_lem, blast) |
276 by(insert induct_lem, blast) |
277 |
277 |
278 text{* |
278 text\<open> |
279 HOL already provides the mother of |
279 HOL already provides the mother of |
280 all inductions, well-founded induction (see \S\ref{sec:Well-founded}). For |
280 all inductions, well-founded induction (see \S\ref{sec:Well-founded}). For |
281 example theorem @{thm[source]nat_less_induct} is |
281 example theorem @{thm[source]nat_less_induct} is |
282 a special case of @{thm[source]wf_induct} where @{term r} is @{text"<"} on |
282 a special case of @{thm[source]wf_induct} where @{term r} is @{text"<"} on |
283 @{typ nat}. The details can be found in theory \isa{Wellfounded_Recursion}. |
283 @{typ nat}. The details can be found in theory \isa{Wellfounded_Recursion}. |
284 *} |
284 \<close> |
285 (*<*)end(*>*) |
285 (*<*)end(*>*) |