doc-src/ProgProve/Thys/Types_and_funs.thy
changeset 47711 c1cca2a052e4
parent 47306 56d72c923281
equal deleted inserted replaced
47710:4ced56100757 47711:c1cca2a052e4
   130 total. This simplifies the logic---terms are always defined---but means
   130 total. This simplifies the logic---terms are always defined---but means
   131 that recursive functions must terminate. Otherwise one could define a
   131 that recursive functions must terminate. Otherwise one could define a
   132 function @{prop"f n = f n + (1::nat)"} and conclude \mbox{@{prop"(0::nat) = 1"}} by
   132 function @{prop"f n = f n + (1::nat)"} and conclude \mbox{@{prop"(0::nat) = 1"}} by
   133 subtracting @{term"f n"} on both sides.
   133 subtracting @{term"f n"} on both sides.
   134 
   134 
   135 Isabelle automatic termination checker requires that the arguments of
   135 Isabelle's automatic termination checker requires that the arguments of
   136 recursive calls on the right-hand side must be strictly smaller than the
   136 recursive calls on the right-hand side must be strictly smaller than the
   137 arguments on the left-hand side. In the simplest case, this means that one
   137 arguments on the left-hand side. In the simplest case, this means that one
   138 fixed argument position decreases in size with each recursive call. The size
   138 fixed argument position decreases in size with each recursive call. The size
   139 is measured as the number of constructors (excluding 0-ary ones, e.g.\ @{text
   139 is measured as the number of constructors (excluding 0-ary ones, e.g.\ @{text
   140 Nil}). Lexicographic combinations are also recognised. In more complicated
   140 Nil}). Lexicographic combinations are also recognized. In more complicated
   141 situations, the user may have to prove termination by hand. For details
   141 situations, the user may have to prove termination by hand. For details
   142 see~\cite{Krauss}.
   142 see~\cite{Krauss}.
   143 
   143 
   144 Functions defined with \isacom{fun} come with their own induction schema
   144 Functions defined with \isacom{fun} come with their own induction schema
   145 that mirrors the recursion schema and is derived from the termination
   145 that mirrors the recursion schema and is derived from the termination
   150 "div2 0 = 0" |
   150 "div2 0 = 0" |
   151 "div2 (Suc 0) = Suc 0" |
   151 "div2 (Suc 0) = Suc 0" |
   152 "div2 (Suc(Suc n)) = Suc(div2 n)"
   152 "div2 (Suc(Suc n)) = Suc(div2 n)"
   153 
   153 
   154 text{* does not just define @{const div2} but also proves a
   154 text{* does not just define @{const div2} but also proves a
   155 customised induction rule:
   155 customized induction rule:
   156 \[
   156 \[
   157 \inferrule{
   157 \inferrule{
   158 \mbox{@{thm (prem 1) div2.induct}}\\
   158 \mbox{@{thm (prem 1) div2.induct}}\\
   159 \mbox{@{thm (prem 2) div2.induct}}\\
   159 \mbox{@{thm (prem 2) div2.induct}}\\
   160 \mbox{@{thm (prem 3) div2.induct}}}
   160 \mbox{@{thm (prem 3) div2.induct}}}
   161 {\mbox{@{thm (concl) div2.induct[of _ "m"]}}}
   161 {\mbox{@{thm (concl) div2.induct[of _ "m"]}}}
   162 \]
   162 \]
   163 This customised induction rule can simplify inductive proofs. For example,
   163 This customized induction rule can simplify inductive proofs. For example,
   164 *}
   164 *}
   165 
   165 
   166 lemma "div2(n+n) = n"
   166 lemma "div2(n+n) = n"
   167 apply(induction n rule: div2.induct)
   167 apply(induction n rule: div2.induct)
   168 
   168 
   169 txt{* yields the 3 subgoals
   169 txt{* yields the 3 subgoals
   170 @{subgoals[display,margin=65]}
   170 @{subgoals[display,margin=65]}
   171 An application of @{text auto} finishes the proof.
   171 An application of @{text auto} finishes the proof.
   172 Had we used ordinary structural induction on @{text n},
   172 Had we used ordinary structural induction on @{text n},
   173 the proof would have needed an additional
   173 the proof would have needed an additional
   174 case distinction in the induction step.
   174 case analysis in the induction step.
   175 
   175 
   176 The general case is often called \concept{computation induction},
   176 The general case is often called \concept{computation induction},
   177 because the induction follows the (terminating!) computation.
   177 because the induction follows the (terminating!) computation.
   178 For every defining equation
   178 For every defining equation
   179 \begin{quote}
   179 \begin{quote}
   200 \begin{quote}
   200 \begin{quote}
   201 \emph{Perform induction on argument number $i$\\
   201 \emph{Perform induction on argument number $i$\\
   202  if the function is defined by recursion on argument number $i$.}
   202  if the function is defined by recursion on argument number $i$.}
   203 \end{quote}
   203 \end{quote}
   204 The key heuristic, and the main point of this section, is to
   204 The key heuristic, and the main point of this section, is to
   205 \emph{generalise the goal before induction}.
   205 \emph{generalize the goal before induction}.
   206 The reason is simple: if the goal is
   206 The reason is simple: if the goal is
   207 too specific, the induction hypothesis is too weak to allow the induction
   207 too specific, the induction hypothesis is too weak to allow the induction
   208 step to go through. Let us illustrate the idea with an example.
   208 step to go through. Let us illustrate the idea with an example.
   209 
   209 
   210 Function @{const rev} has quadratic worst-case running time
   210 Function @{const rev} has quadratic worst-case running time
   216 (*<*)
   216 (*<*)
   217 apply auto
   217 apply auto
   218 done
   218 done
   219 (*>*)
   219 (*>*)
   220 fun itrev :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   220 fun itrev :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   221 "itrev []     ys = ys" |
   221 "itrev []        ys = ys" |
   222 "itrev (x#xs) ys = itrev xs (x#ys)"
   222 "itrev (x#xs) ys = itrev xs (x#ys)"
   223 
   223 
   224 text{* The behaviour of @{const itrev} is simple: it reverses
   224 text{* The behaviour of @{const itrev} is simple: it reverses
   225 its first argument by stacking its elements onto the second argument,
   225 its first argument by stacking its elements onto the second argument,
   226 and returning that second argument when the first one becomes
   226 and it returns that second argument when the first one becomes
   227 empty. Note that @{const itrev} is tail-recursive: it can be
   227 empty. Note that @{const itrev} is tail-recursive: it can be
   228 compiled into a loop, no stack is necessary for executing it.
   228 compiled into a loop, no stack is necessary for executing it.
   229 
   229 
   230 Naturally, we would like to show that @{const itrev} does indeed reverse
   230 Naturally, we would like to show that @{const itrev} does indeed reverse
   231 its first argument provided the second one is empty:
   231 its first argument provided the second one is empty:
   245 @{subgoals[display,margin=70]}
   245 @{subgoals[display,margin=70]}
   246 The induction hypothesis is too weak.  The fixed
   246 The induction hypothesis is too weak.  The fixed
   247 argument,~@{term"[]"}, prevents it from rewriting the conclusion.  
   247 argument,~@{term"[]"}, prevents it from rewriting the conclusion.  
   248 This example suggests a heuristic:
   248 This example suggests a heuristic:
   249 \begin{quote}
   249 \begin{quote}
   250 \emph{Generalise goals for induction by replacing constants by variables.}
   250 \emph{Generalize goals for induction by replacing constants by variables.}
   251 \end{quote}
   251 \end{quote}
   252 Of course one cannot do this na\"{\i}vely: @{prop"itrev xs ys = rev xs"} is
   252 Of course one cannot do this na\"{\i}vely: @{prop"itrev xs ys = rev xs"} is
   253 just not true.  The correct generalisation is
   253 just not true.  The correct generalization is
   254 *};
   254 *};
   255 (*<*)oops;(*>*)
   255 (*<*)oops;(*>*)
   256 lemma "itrev xs ys = rev xs @ ys"
   256 lemma "itrev xs ys = rev xs @ ys"
   257 (*<*)apply(induction xs, auto)(*>*)
   257 (*<*)apply(induction xs, auto)(*>*)
   258 txt{*
   258 txt{*
   259 If @{text ys} is replaced by @{term"[]"}, the right-hand side simplifies to
   259 If @{text ys} is replaced by @{term"[]"}, the right-hand side simplifies to
   260 @{term"rev xs"}, as required.
   260 @{term"rev xs"}, as required.
   261 In this instance it was easy to guess the right generalisation.
   261 In this instance it was easy to guess the right generalization.
   262 Other situations can require a good deal of creativity.  
   262 Other situations can require a good deal of creativity.  
   263 
   263 
   264 Although we now have two variables, only @{text xs} is suitable for
   264 Although we now have two variables, only @{text xs} is suitable for
   265 induction, and we repeat our proof attempt. Unfortunately, we are still
   265 induction, and we repeat our proof attempt. Unfortunately, we are still
   266 not there:
   266 not there:
   267 @{subgoals[display,margin=65]}
   267 @{subgoals[display,margin=65]}
   268 The induction hypothesis is still too weak, but this time it takes no
   268 The induction hypothesis is still too weak, but this time it takes no
   269 intuition to generalise: the problem is that the @{text ys}
   269 intuition to generalize: the problem is that the @{text ys}
   270 in the induction hypothesis is fixed,
   270 in the induction hypothesis is fixed,
   271 but the induction hypothesis needs to be applied with
   271 but the induction hypothesis needs to be applied with
   272 @{term"a # ys"} instead of @{text ys}. Hence we prove the theorem
   272 @{term"a # ys"} instead of @{text ys}. Hence we prove the theorem
   273 for all @{text ys} instead of a fixed one. We can instruct induction
   273 for all @{text ys} instead of a fixed one. We can instruct induction
   274 to perform this generalisation for us by adding @{text "arbitrary: ys"}.
   274 to perform this generalization for us by adding @{text "arbitrary: ys"}.
   275 *}
   275 *}
   276 (*<*)oops
   276 (*<*)oops
   277 lemma "itrev xs ys = rev xs @ ys"
   277 lemma "itrev xs ys = rev xs @ ys"
   278 (*>*)
   278 (*>*)
   279 apply(induction xs arbitrary: ys)
   279 apply(induction xs arbitrary: ys)
   285 
   285 
   286 apply auto
   286 apply auto
   287 done
   287 done
   288 
   288 
   289 text{*
   289 text{*
   290 This leads to another heuristic for generalisation:
   290 This leads to another heuristic for generalization:
   291 \begin{quote}
   291 \begin{quote}
   292 \emph{Generalise induction by generalising all free
   292 \emph{Generalize induction by generalizing all free
   293 variables\\ {\em(except the induction variable itself)}.}
   293 variables\\ {\em(except the induction variable itself)}.}
   294 \end{quote}
   294 \end{quote}
   295 Generalisation is best performed with @{text"arbitrary: y\<^isub>1 \<dots> y\<^isub>k"}. 
   295 Generalization is best performed with @{text"arbitrary: y\<^isub>1 \<dots> y\<^isub>k"}. 
   296 This heuristic prevents trivial failures like the one above.
   296 This heuristic prevents trivial failures like the one above.
   297 However, it should not be applied blindly.
   297 However, it should not be applied blindly.
   298 It is not always required, and the additional quantifiers can complicate
   298 It is not always required, and the additional quantifiers can complicate
   299 matters in some cases. The variables that need to be quantified are typically
   299 matters in some cases. The variables that need to be quantified are typically
   300 those that change in recursive calls.
   300 those that change in recursive calls.
   304 So far we have talked a lot about simplifying terms without explaining the concept. \concept{Simplification} means
   304 So far we have talked a lot about simplifying terms without explaining the concept. \concept{Simplification} means
   305 \begin{itemize}
   305 \begin{itemize}
   306 \item using equations $l = r$ from left to right (only),
   306 \item using equations $l = r$ from left to right (only),
   307 \item as long as possible.
   307 \item as long as possible.
   308 \end{itemize}
   308 \end{itemize}
   309 To emphasise the directionality, equations that have been given the
   309 To emphasize the directionality, equations that have been given the
   310 @{text"simp"} attribute are called \concept{simplification}
   310 @{text"simp"} attribute are called \concept{simplification}
   311 rules. Logically, they are still symmetric, but proofs by
   311 rules. Logically, they are still symmetric, but proofs by
   312 simplification use them only in the left-to-right direction.  The proof tool
   312 simplification use them only in the left-to-right direction.  The proof tool
   313 that performs simplifications is called the \concept{simplifier}. It is the
   313 that performs simplifications is called the \concept{simplifier}. It is the
   314 basis of @{text auto} and other related proof methods.
   314 basis of @{text auto} and other related proof methods.