src/Doc/Tutorial/Misc/AdvancedInd.thy
changeset 67406 23307fd33906
parent 63178 b9e1d53124f5
child 69505 cc2d676d5395
equal deleted inserted replaced
67405:e9ab4ad7bd15 67406:23307fd33906
     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(*>*)