| 9722 |      1 | %
 | 
|  |      2 | \begin{isabellebody}%
 | 
| 9924 |      3 | \def\isabellecontext{simplification}%
 | 
| 11866 |      4 | \isamarkupfalse%
 | 
| 8749 |      5 | %
 | 
|  |      6 | \begin{isamarkuptext}%
 | 
| 11458 |      7 | Once we have proved all the termination conditions, the \isacommand{recdef} 
 | 
|  |      8 | recursion equations become simplification rules, just as with
 | 
| 8749 |      9 | \isacommand{primrec}. In most cases this works fine, but there is a subtle
 | 
|  |     10 | problem that must be mentioned: simplification may not
 | 
|  |     11 | terminate because of automatic splitting of \isa{if}.
 | 
| 11458 |     12 | \index{*if expressions!splitting of}
 | 
| 8749 |     13 | Let us look at an example:%
 | 
|  |     14 | \end{isamarkuptext}%
 | 
| 11866 |     15 | \isamarkuptrue%
 | 
| 9933 |     16 | \isacommand{consts}\ gcd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isasymtimes}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
 | 
| 11866 |     17 | \isamarkupfalse%
 | 
| 9674 |     18 | \isacommand{recdef}\ gcd\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
 | 
| 11866 |     19 | \ \ {\isachardoublequote}gcd\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}if\ n{\isacharequal}{\isadigit{0}}\ then\ m\ else\ gcd{\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}{\isacharparenright}{\isachardoublequote}\isamarkupfalse%
 | 
|  |     20 | %
 | 
| 8749 |     21 | \begin{isamarkuptext}%
 | 
|  |     22 | \noindent
 | 
|  |     23 | According to the measure function, the second argument should decrease with
 | 
| 9541 |     24 | each recursive call. The resulting termination condition
 | 
|  |     25 | \begin{isabelle}%
 | 
| 12473 |     26 | \ \ \ \ \ n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ m\ mod\ n\ {\isacharless}\ n%
 | 
| 9924 |     27 | \end{isabelle}
 | 
| 10878 |     28 | is proved automatically because it is already present as a lemma in
 | 
|  |     29 | HOL\@.  Thus the recursion equation becomes a simplification
 | 
| 8749 |     30 | rule. Of course the equation is nonterminating if we are allowed to unfold
 | 
| 10171 |     31 | the recursive call inside the \isa{else} branch, which is why programming
 | 
| 8749 |     32 | languages and our simplifier don't do that. Unfortunately the simplifier does
 | 
| 11458 |     33 | something else that leads to the same problem: it splits 
 | 
|  |     34 | each \isa{if}-expression unless its
 | 
|  |     35 | condition simplifies to \isa{True} or \isa{False}.  For
 | 
| 9541 |     36 | example, simplification reduces
 | 
|  |     37 | \begin{isabelle}%
 | 
| 9834 |     38 | \ \ \ \ \ gcd\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ k%
 | 
| 9924 |     39 | \end{isabelle}
 | 
| 9541 |     40 | in one step to
 | 
|  |     41 | \begin{isabelle}%
 | 
| 10187 |     42 | \ \ \ \ \ {\isacharparenleft}if\ n\ {\isacharequal}\ {\isadigit{0}}\ then\ m\ else\ gcd\ {\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ k%
 | 
| 9924 |     43 | \end{isabelle}
 | 
| 9541 |     44 | where the condition cannot be reduced further, and splitting leads to
 | 
|  |     45 | \begin{isabelle}%
 | 
| 10187 |     46 | \ \ \ \ \ {\isacharparenleft}n\ {\isacharequal}\ {\isadigit{0}}\ {\isasymlongrightarrow}\ m\ {\isacharequal}\ k{\isacharparenright}\ {\isasymand}\ {\isacharparenleft}n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymlongrightarrow}\ gcd\ {\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}\ {\isacharequal}\ k{\isacharparenright}%
 | 
| 9924 |     47 | \end{isabelle}
 | 
| 9792 |     48 | Since the recursive call \isa{gcd\ {\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}} is no longer protected by
 | 
| 9541 |     49 | an \isa{if}, it is unfolded again, which leads to an infinite chain of
 | 
|  |     50 | simplification steps. Fortunately, this problem can be avoided in many
 | 
|  |     51 | different ways.
 | 
| 8749 |     52 | 
 | 
| 11458 |     53 | The most radical solution is to disable the offending theorem
 | 
|  |     54 | \isa{split{\isacharunderscore}if},
 | 
| 11215 |     55 | as shown in \S\ref{sec:AutoCaseSplits}.  However, we do not recommend this
 | 
| 11458 |     56 | approach: you will often have to invoke the rule explicitly when
 | 
| 11215 |     57 | \isa{if} is involved.
 | 
| 8749 |     58 | 
 | 
|  |     59 | If possible, the definition should be given by pattern matching on the left
 | 
|  |     60 | rather than \isa{if} on the right. In the case of \isa{gcd} the
 | 
|  |     61 | following alternative definition suggests itself:%
 | 
|  |     62 | \end{isamarkuptext}%
 | 
| 11866 |     63 | \isamarkuptrue%
 | 
| 10187 |     64 | \isacommand{consts}\ gcd{\isadigit{1}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isasymtimes}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
 | 
| 11866 |     65 | \isamarkupfalse%
 | 
| 10187 |     66 | \isacommand{recdef}\ gcd{\isadigit{1}}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
 | 
|  |     67 | \ \ {\isachardoublequote}gcd{\isadigit{1}}\ {\isacharparenleft}m{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
 | 
| 11866 |     68 | \ \ {\isachardoublequote}gcd{\isadigit{1}}\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ gcd{\isadigit{1}}{\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}{\isachardoublequote}\isamarkupfalse%
 | 
|  |     69 | %
 | 
| 8749 |     70 | \begin{isamarkuptext}%
 | 
|  |     71 | \noindent
 | 
| 11458 |     72 | The order of equations is important: it hides the side condition
 | 
| 12473 |     73 | \isa{n\ {\isasymnoteq}\ {\isadigit{0}}}.  Unfortunately, in general the case distinction
 | 
| 8749 |     74 | may not be expressible by pattern matching.
 | 
|  |     75 | 
 | 
| 11458 |     76 | A simple alternative is to replace \isa{if} by \isa{case}, 
 | 
|  |     77 | which is also available for \isa{bool} and is not split automatically:%
 | 
| 8749 |     78 | \end{isamarkuptext}%
 | 
| 11866 |     79 | \isamarkuptrue%
 | 
| 10187 |     80 | \isacommand{consts}\ gcd{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isasymtimes}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
 | 
| 11866 |     81 | \isamarkupfalse%
 | 
| 10187 |     82 | \isacommand{recdef}\ gcd{\isadigit{2}}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
 | 
| 11866 |     83 | \ \ {\isachardoublequote}gcd{\isadigit{2}}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}case\ n{\isacharequal}{\isadigit{0}}\ of\ True\ {\isasymRightarrow}\ m\ {\isacharbar}\ False\ {\isasymRightarrow}\ gcd{\isadigit{2}}{\isacharparenleft}n{\isacharcomma}m\ mod\ n{\isacharparenright}{\isacharparenright}{\isachardoublequote}\isamarkupfalse%
 | 
|  |     84 | %
 | 
| 8749 |     85 | \begin{isamarkuptext}%
 | 
|  |     86 | \noindent
 | 
| 11458 |     87 | This is probably the neatest solution next to pattern matching, and it is
 | 
|  |     88 | always available.
 | 
| 8749 |     89 | 
 | 
|  |     90 | A final alternative is to replace the offending simplification rules by
 | 
| 10795 |     91 | derived conditional ones. For \isa{gcd} it means we have to prove
 | 
|  |     92 | these lemmas:%
 | 
| 8749 |     93 | \end{isamarkuptext}%
 | 
| 11866 |     94 | \isamarkuptrue%
 | 
| 10187 |     95 | \isacommand{lemma}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}gcd\ {\isacharparenleft}m{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
 | 
| 11866 |     96 | \isamarkupfalse%
 | 
| 10171 |     97 | \isacommand{apply}{\isacharparenleft}simp{\isacharparenright}\isanewline
 | 
| 11866 |     98 | \isamarkupfalse%
 | 
| 10171 |     99 | \isacommand{done}\isanewline
 | 
| 11458 |    100 | \isanewline
 | 
| 11866 |    101 | \isamarkupfalse%
 | 
| 10187 |    102 | \isacommand{lemma}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}n\ {\isasymnoteq}\ {\isadigit{0}}\ {\isasymLongrightarrow}\ gcd{\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ gcd{\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}{\isachardoublequote}\isanewline
 | 
| 11866 |    103 | \isamarkupfalse%
 | 
| 10171 |    104 | \isacommand{apply}{\isacharparenleft}simp{\isacharparenright}\isanewline
 | 
| 11866 |    105 | \isamarkupfalse%
 | 
|  |    106 | \isacommand{done}\isamarkupfalse%
 | 
|  |    107 | %
 | 
| 8749 |    108 | \begin{isamarkuptext}%
 | 
|  |    109 | \noindent
 | 
| 11458 |    110 | Simplification terminates for these proofs because the condition of the \isa{if} simplifies to \isa{True} or \isa{False}.
 | 
| 10795 |    111 | Now we can disable the original simplification rule:%
 | 
| 8749 |    112 | \end{isamarkuptext}%
 | 
| 11866 |    113 | \isamarkuptrue%
 | 
| 9933 |    114 | \isacommand{declare}\ gcd{\isachardot}simps\ {\isacharbrackleft}simp\ del{\isacharbrackright}\isanewline
 | 
| 11866 |    115 | \isamarkupfalse%
 | 
|  |    116 | \isamarkupfalse%
 | 
| 9722 |    117 | \end{isabellebody}%
 | 
| 9145 |    118 | %%% Local Variables:
 | 
|  |    119 | %%% mode: latex
 | 
|  |    120 | %%% TeX-master: "root"
 | 
|  |    121 | %%% End:
 |