doc-src/TutorialI/Misc/Itrev.thy
changeset 9754 a123a64cadeb
parent 9723 a977245dfc8a
child 9792 bbefb6ce5cb2
equal deleted inserted replaced
9753:f25ac7194f71 9754:a123a64cadeb
     1 (*<*)
     1 (*<*)
     2 theory Itrev = Main:;
     2 theory Itrev = Main:;
     3 (*>*)
     3 (*>*)
     4 
     4 
     5 text{* Function \isa{rev} has quadratic worst-case running time
     5 text{*
     6 because it calls function \isa{\at} for each element of the list and
     6 Function @{term"rev"} has quadratic worst-case running time
     7 \isa{\at} is linear in its first argument.  A linear time version of
     7 because it calls function @{term"@"} for each element of the list and
     8 \isa{rev} reqires an extra argument where the result is accumulated
     8 @{term"@"} is linear in its first argument.  A linear time version of
     9 gradually, using only \isa{\#}:*}
     9 @{term"rev"} reqires an extra argument where the result is accumulated
       
    10 gradually, using only @{name"#"}:
       
    11 *}
    10 
    12 
    11 consts itrev :: "'a list \\<Rightarrow> 'a list \\<Rightarrow> 'a list";
    13 consts itrev :: "'a list \\<Rightarrow> 'a list \\<Rightarrow> 'a list";
    12 primrec
    14 primrec
    13 "itrev []     ys = ys"
    15 "itrev []     ys = ys"
    14 "itrev (x#xs) ys = itrev xs (x#ys)";
    16 "itrev (x#xs) ys = itrev xs (x#ys)";
    15 
    17 
    16 text{*\noindent The behaviour of \isa{itrev} is simple: it reverses
    18 text{*\noindent
       
    19 The behaviour of @{term"itrev"} is simple: it reverses
    17 its first argument by stacking its elements onto the second argument,
    20 its first argument by stacking its elements onto the second argument,
    18 and returning that second argument when the first one becomes
    21 and returning that second argument when the first one becomes
    19 empty. Note that \isa{itrev} is tail-recursive, i.e.\ it can be
    22 empty. Note that @{term"itrev"} is tail-recursive, i.e.\ it can be
    20 compiled into a loop.
    23 compiled into a loop.
    21 
    24 
    22 Naturally, we would like to show that \isa{itrev} does indeed reverse
    25 Naturally, we would like to show that @{term"itrev"} does indeed reverse
    23 its first argument provided the second one is empty: *};
    26 its first argument provided the second one is empty:
       
    27 *};
    24 
    28 
    25 lemma "itrev xs [] = rev xs";
    29 lemma "itrev xs [] = rev xs";
    26 
    30 
    27 txt{*\noindent
    31 txt{*\noindent
    28 There is no choice as to the induction variable, and we immediately simplify:
    32 There is no choice as to the induction variable, and we immediately simplify:
    35 \begin{isabelle}
    39 \begin{isabelle}
    36 ~1.~\dots~itrev~list~[]~=~rev~list~{\isasymLongrightarrow}~itrev~list~[a]~=~rev~list~@~[a]%
    40 ~1.~\dots~itrev~list~[]~=~rev~list~{\isasymLongrightarrow}~itrev~list~[a]~=~rev~list~@~[a]%
    37 \end{isabelle}
    41 \end{isabelle}
    38 Just as predicted above, the overall goal, and hence the induction
    42 Just as predicted above, the overall goal, and hence the induction
    39 hypothesis, is too weak to solve the induction step because of the fixed
    43 hypothesis, is too weak to solve the induction step because of the fixed
    40 \isa{[]}. The corresponding heuristic:
    44 @{term"[]"}. The corresponding heuristic:
    41 \begin{quote}
    45 \begin{quote}
    42 {\em 3. Generalize goals for induction by replacing constants by variables.}
    46 \emph{Generalize goals for induction by replacing constants by variables.}
    43 \end{quote}
    47 \end{quote}
    44 
    48 Of course one cannot do this na\"{\i}vely: @{term"itrev xs ys = rev xs"} is
    45 Of course one cannot do this na\"{\i}vely: \isa{itrev xs ys = rev xs} is
       
    46 just not true---the correct generalization is
    49 just not true---the correct generalization is
    47 *};
    50 *};
    48 (*<*)oops;(*>*)
    51 (*<*)oops;(*>*)
    49 lemma "itrev xs ys = rev xs @ ys";
    52 lemma "itrev xs ys = rev xs @ ys";
    50 
    53 
    51 txt{*\noindent
    54 txt{*\noindent
    52 If \isa{ys} is replaced by \isa{[]}, the right-hand side simplifies to
    55 If @{term"ys"} is replaced by @{term"[]"}, the right-hand side simplifies to
    53 @{term"rev xs"}, just as required.
    56 @{term"rev xs"}, just as required.
    54 
    57 
    55 In this particular instance it was easy to guess the right generalization,
    58 In this particular instance it was easy to guess the right generalization,
    56 but in more complex situations a good deal of creativity is needed. This is
    59 but in more complex situations a good deal of creativity is needed. This is
    57 the main source of complications in inductive proofs.
    60 the main source of complications in inductive proofs.
    58 
    61 
    59 Although we now have two variables, only \isa{xs} is suitable for
    62 Although we now have two variables, only @{term"xs"} is suitable for
    60 induction, and we repeat our above proof attempt. Unfortunately, we are still
    63 induction, and we repeat our above proof attempt. Unfortunately, we are still
    61 not there:
    64 not there:
    62 \begin{isabelle}
    65 \begin{isabelle}
    63 ~1.~{\isasymAnd}a~list.\isanewline
    66 ~1.~{\isasymAnd}a~list.\isanewline
    64 ~~~~~~~itrev~list~ys~=~rev~list~@~ys~{\isasymLongrightarrow}\isanewline
    67 ~~~~~~~itrev~list~ys~=~rev~list~@~ys~{\isasymLongrightarrow}\isanewline
    65 ~~~~~~~itrev~list~(a~\#~ys)~=~rev~list~@~a~\#~ys%
    68 ~~~~~~~itrev~list~(a~\#~ys)~=~rev~list~@~a~\#~ys
    66 \end{isabelle}
    69 \end{isabelle}
    67 The induction hypothesis is still too weak, but this time it takes no
    70 The induction hypothesis is still too weak, but this time it takes no
    68 intuition to generalize: the problem is that \isa{ys} is fixed throughout
    71 intuition to generalize: the problem is that @{term"ys"} is fixed throughout
    69 the subgoal, but the induction hypothesis needs to be applied with
    72 the subgoal, but the induction hypothesis needs to be applied with
    70 @{term"a # ys"} instead of \isa{ys}. Hence we prove the theorem
    73 @{term"a # ys"} instead of @{term"ys"}. Hence we prove the theorem
    71 for all \isa{ys} instead of a fixed one:
    74 for all @{term"ys"} instead of a fixed one:
    72 *};
    75 *};
    73 (*<*)oops;(*>*)
    76 (*<*)oops;(*>*)
    74 lemma "\\<forall>ys. itrev xs ys = rev xs @ ys";
    77 lemma "\\<forall>ys. itrev xs ys = rev xs @ ys";
    75 
    78 
    76 txt{*\noindent
    79 txt{*\noindent
    77 This time induction on \isa{xs} followed by simplification succeeds. This
    80 This time induction on @{term"xs"} followed by simplification succeeds. This
    78 leads to another heuristic for generalization:
    81 leads to another heuristic for generalization:
    79 \begin{quote}
    82 \begin{quote}
    80 {\em 4. Generalize goals for induction by universally quantifying all free
    83 \emph{Generalize goals for induction by universally quantifying all free
    81 variables {\em(except the induction variable itself!)}.}
    84 variables {\em(except the induction variable itself!)}.}
    82 \end{quote}
    85 \end{quote}
    83 This prevents trivial failures like the above and does not change the
    86 This prevents trivial failures like the above and does not change the
    84 provability of the goal. Because it is not always required, and may even
    87 provability of the goal. Because it is not always required, and may even
    85 complicate matters in some cases, this heuristic is often not
    88 complicate matters in some cases, this heuristic is often not