doc-src/TutorialI/Misc/Itrev.thy
author nipkow
Tue, 05 Sep 2000 13:53:39 +0200
changeset 9844 8016321c7de1
parent 9792 bbefb6ce5cb2
child 10362 c6b197ccf1f1
permissions -rw-r--r--
*** empty log message ***
     1 (*<*)
     2 theory Itrev = Main:;
     3 (*>*)
     4 
     5 section{*Induction heuristics*}
     6 
     7 text{*\label{sec:InductionHeuristics}
     8 The purpose of this section is to illustrate some simple heuristics for
     9 inductive proofs. The first one we have already mentioned in our initial
    10 example:
    11 \begin{quote}
    12 \emph{Theorems about recursive functions are proved by induction.}
    13 \end{quote}
    14 In case the function has more than one argument
    15 \begin{quote}
    16 \emph{Do induction on argument number $i$ if the function is defined by
    17 recursion in argument number $i$.}
    18 \end{quote}
    19 When we look at the proof of @{term[source]"(xs @ ys) @ zs = xs @ (ys @ zs)"}
    20 in \S\ref{sec:intro-proof} we find (a) @{text"@"} is recursive in
    21 the first argument, (b) @{term xs} occurs only as the first argument of
    22 @{text"@"}, and (c) both @{term ys} and @{term zs} occur at least once as
    23 the second argument of @{text"@"}. Hence it is natural to perform induction
    24 on @{term xs}.
    25 
    26 The key heuristic, and the main point of this section, is to
    27 generalize the goal before induction. The reason is simple: if the goal is
    28 too specific, the induction hypothesis is too weak to allow the induction
    29 step to go through. Let us now illustrate the idea with an example.
    30 
    31 Function @{term"rev"} has quadratic worst-case running time
    32 because it calls function @{text"@"} for each element of the list and
    33 @{text"@"} is linear in its first argument.  A linear time version of
    34 @{term"rev"} reqires an extra argument where the result is accumulated
    35 gradually, using only @{text"#"}:
    36 *}
    37 
    38 consts itrev :: "'a list \\<Rightarrow> 'a list \\<Rightarrow> 'a list";
    39 primrec
    40 "itrev []     ys = ys"
    41 "itrev (x#xs) ys = itrev xs (x#ys)";
    42 
    43 text{*\noindent
    44 The behaviour of @{term"itrev"} is simple: it reverses
    45 its first argument by stacking its elements onto the second argument,
    46 and returning that second argument when the first one becomes
    47 empty. Note that @{term"itrev"} is tail-recursive, i.e.\ it can be
    48 compiled into a loop.
    49 
    50 Naturally, we would like to show that @{term"itrev"} does indeed reverse
    51 its first argument provided the second one is empty:
    52 *};
    53 
    54 lemma "itrev xs [] = rev xs";
    55 
    56 txt{*\noindent
    57 There is no choice as to the induction variable, and we immediately simplify:
    58 *};
    59 
    60 apply(induct_tac xs, simp_all);
    61 
    62 txt{*\noindent
    63 Unfortunately, this is not a complete success:
    64 \begin{isabelle}\makeatother
    65 ~1.~\dots~itrev~list~[]~=~rev~list~{\isasymLongrightarrow}~itrev~list~[a]~=~rev~list~@~[a]%
    66 \end{isabelle}
    67 Just as predicted above, the overall goal, and hence the induction
    68 hypothesis, is too weak to solve the induction step because of the fixed
    69 @{term"[]"}. The corresponding heuristic:
    70 \begin{quote}
    71 \emph{Generalize goals for induction by replacing constants by variables.}
    72 \end{quote}
    73 Of course one cannot do this na\"{\i}vely: @{term"itrev xs ys = rev xs"} is
    74 just not true---the correct generalization is
    75 *};
    76 (*<*)oops;(*>*)
    77 lemma "itrev xs ys = rev xs @ ys";
    78 
    79 txt{*\noindent
    80 If @{term"ys"} is replaced by @{term"[]"}, the right-hand side simplifies to
    81 @{term"rev xs"}, just as required.
    82 
    83 In this particular instance it was easy to guess the right generalization,
    84 but in more complex situations a good deal of creativity is needed. This is
    85 the main source of complications in inductive proofs.
    86 
    87 Although we now have two variables, only @{term"xs"} is suitable for
    88 induction, and we repeat our above proof attempt. Unfortunately, we are still
    89 not there:
    90 \begin{isabelle}\makeatother
    91 ~1.~{\isasymAnd}a~list.\isanewline
    92 ~~~~~~~itrev~list~ys~=~rev~list~@~ys~{\isasymLongrightarrow}\isanewline
    93 ~~~~~~~itrev~list~(a~\#~ys)~=~rev~list~@~a~\#~ys
    94 \end{isabelle}
    95 The induction hypothesis is still too weak, but this time it takes no
    96 intuition to generalize: the problem is that @{term"ys"} is fixed throughout
    97 the subgoal, but the induction hypothesis needs to be applied with
    98 @{term"a # ys"} instead of @{term"ys"}. Hence we prove the theorem
    99 for all @{term"ys"} instead of a fixed one:
   100 *};
   101 (*<*)oops;(*>*)
   102 lemma "\\<forall>ys. itrev xs ys = rev xs @ ys";
   103 (*<*)
   104 by(induct_tac xs, simp_all);
   105 (*>*)
   106 
   107 text{*\noindent
   108 This time induction on @{term"xs"} followed by simplification succeeds. This
   109 leads to another heuristic for generalization:
   110 \begin{quote}
   111 \emph{Generalize goals for induction by universally quantifying all free
   112 variables {\em(except the induction variable itself!)}.}
   113 \end{quote}
   114 This prevents trivial failures like the above and does not change the
   115 provability of the goal. Because it is not always required, and may even
   116 complicate matters in some cases, this heuristic is often not
   117 applied blindly.
   118 
   119 In general, if you have tried the above heuristics and still find your
   120 induction does not go through, and no obvious lemma suggests itself, you may
   121 need to generalize your proposition even further. This requires insight into
   122 the problem at hand and is beyond simple rules of thumb. In a nutshell: you
   123 will need to be creative. Additionally, you can read \S\ref{sec:advanced-ind}
   124 to learn about some advanced techniques for inductive proofs.
   125 
   126 A final point worth mentioning is the orientation of the equation we just
   127 proved: the more complex notion (@{term itrev}) is on the left-hand
   128 side, the simpler one (@{term rev}) on the right-hand side. This constitutes
   129 another, albeit weak heuristic that is not restricted to induction:
   130 \begin{quote}
   131   \emph{The right-hand side of an equation should (in some sense) be simpler
   132     than the left-hand side.}
   133 \end{quote}
   134 This heuristic is tricky to apply because it is not obvious that
   135 @{term"rev xs @ ys"} is simpler than @{term"itrev xs ys"}. But see what
   136 happens if you try to prove @{prop"rev xs @ ys = itrev xs ys"}!
   137 *}
   138 (*<*)
   139 end
   140 (*>*)