doc-src/TutorialI/Recdef/document/simplification.tex
changeset 11458 09a6c44a48ea
parent 11215 b44ad7e4c4d2
child 11706 885e053ae664
equal deleted inserted replaced
11457:279da0358aa9 11458:09a6c44a48ea
     1 %
     1 %
     2 \begin{isabellebody}%
     2 \begin{isabellebody}%
     3 \def\isabellecontext{simplification}%
     3 \def\isabellecontext{simplification}%
     4 %
     4 %
     5 \begin{isamarkuptext}%
     5 \begin{isamarkuptext}%
     6 Once we have succeeded in proving all termination conditions, the recursion
     6 Once we have proved all the termination conditions, the \isacommand{recdef} 
     7 equations become simplification rules, just as with
     7 recursion equations become simplification rules, just as with
     8 \isacommand{primrec}. In most cases this works fine, but there is a subtle
     8 \isacommand{primrec}. In most cases this works fine, but there is a subtle
     9 problem that must be mentioned: simplification may not
     9 problem that must be mentioned: simplification may not
    10 terminate because of automatic splitting of \isa{if}.
    10 terminate because of automatic splitting of \isa{if}.
       
    11 \index{*if expressions!splitting of}
    11 Let us look at an example:%
    12 Let us look at an example:%
    12 \end{isamarkuptext}%
    13 \end{isamarkuptext}%
    13 \isacommand{consts}\ gcd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isasymtimes}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
    14 \isacommand{consts}\ gcd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isasymtimes}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
    14 \isacommand{recdef}\ gcd\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    15 \isacommand{recdef}\ gcd\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    15 \ \ {\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}%
    16 \ \ {\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}%
    23 is proved automatically because it is already present as a lemma in
    24 is proved automatically because it is already present as a lemma in
    24 HOL\@.  Thus the recursion equation becomes a simplification
    25 HOL\@.  Thus the recursion equation becomes a simplification
    25 rule. Of course the equation is nonterminating if we are allowed to unfold
    26 rule. Of course the equation is nonterminating if we are allowed to unfold
    26 the recursive call inside the \isa{else} branch, which is why programming
    27 the recursive call inside the \isa{else} branch, which is why programming
    27 languages and our simplifier don't do that. Unfortunately the simplifier does
    28 languages and our simplifier don't do that. Unfortunately the simplifier does
    28 something else which leads to the same problem: it splits \isa{if}s if the
    29 something else that leads to the same problem: it splits 
    29 condition simplifies to neither \isa{True} nor \isa{False}. For
    30 each \isa{if}-expression unless its
       
    31 condition simplifies to \isa{True} or \isa{False}.  For
    30 example, simplification reduces
    32 example, simplification reduces
    31 \begin{isabelle}%
    33 \begin{isabelle}%
    32 \ \ \ \ \ gcd\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ k%
    34 \ \ \ \ \ gcd\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ k%
    33 \end{isabelle}
    35 \end{isabelle}
    34 in one step to
    36 in one step to
    42 Since the recursive call \isa{gcd\ {\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}} is no longer protected by
    44 Since the recursive call \isa{gcd\ {\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}} is no longer protected by
    43 an \isa{if}, it is unfolded again, which leads to an infinite chain of
    45 an \isa{if}, it is unfolded again, which leads to an infinite chain of
    44 simplification steps. Fortunately, this problem can be avoided in many
    46 simplification steps. Fortunately, this problem can be avoided in many
    45 different ways.
    47 different ways.
    46 
    48 
    47 The most radical solution is to disable the offending \isa{split{\isacharunderscore}if}
    49 The most radical solution is to disable the offending theorem
       
    50 \isa{split{\isacharunderscore}if},
    48 as shown in \S\ref{sec:AutoCaseSplits}.  However, we do not recommend this
    51 as shown in \S\ref{sec:AutoCaseSplits}.  However, we do not recommend this
    49 because it means you will often have to invoke the rule explicitly when
    52 approach: you will often have to invoke the rule explicitly when
    50 \isa{if} is involved.
    53 \isa{if} is involved.
    51 
    54 
    52 If possible, the definition should be given by pattern matching on the left
    55 If possible, the definition should be given by pattern matching on the left
    53 rather than \isa{if} on the right. In the case of \isa{gcd} the
    56 rather than \isa{if} on the right. In the case of \isa{gcd} the
    54 following alternative definition suggests itself:%
    57 following alternative definition suggests itself:%
    57 \isacommand{recdef}\ gcd{\isadigit{1}}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    60 \isacommand{recdef}\ gcd{\isadigit{1}}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    58 \ \ {\isachardoublequote}gcd{\isadigit{1}}\ {\isacharparenleft}m{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
    61 \ \ {\isachardoublequote}gcd{\isadigit{1}}\ {\isacharparenleft}m{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
    59 \ \ {\isachardoublequote}gcd{\isadigit{1}}\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ gcd{\isadigit{1}}{\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}{\isachardoublequote}%
    62 \ \ {\isachardoublequote}gcd{\isadigit{1}}\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ gcd{\isadigit{1}}{\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}{\isachardoublequote}%
    60 \begin{isamarkuptext}%
    63 \begin{isamarkuptext}%
    61 \noindent
    64 \noindent
    62 Note that the order of equations is important and hides the side condition
    65 The order of equations is important: it hides the side condition
    63 \isa{n\ {\isasymnoteq}\ {\isadigit{0}}}. Unfortunately, in general the case distinction
    66 \isa{n\ {\isasymnoteq}\ {\isadigit{0}}}.  Unfortunately, in general the case distinction
    64 may not be expressible by pattern matching.
    67 may not be expressible by pattern matching.
    65 
    68 
    66 A very simple alternative is to replace \isa{if} by \isa{case}, which
    69 A simple alternative is to replace \isa{if} by \isa{case}, 
    67 is also available for \isa{bool} but is not split automatically:%
    70 which is also available for \isa{bool} and is not split automatically:%
    68 \end{isamarkuptext}%
    71 \end{isamarkuptext}%
    69 \isacommand{consts}\ gcd{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isasymtimes}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
    72 \isacommand{consts}\ gcd{\isadigit{2}}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isasymtimes}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
    70 \isacommand{recdef}\ gcd{\isadigit{2}}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    73 \isacommand{recdef}\ gcd{\isadigit{2}}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    71 \ \ {\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}%
    74 \ \ {\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}%
    72 \begin{isamarkuptext}%
    75 \begin{isamarkuptext}%
    73 \noindent
    76 \noindent
    74 In fact, this is probably the neatest solution next to pattern matching.
    77 This is probably the neatest solution next to pattern matching, and it is
       
    78 always available.
    75 
    79 
    76 A final alternative is to replace the offending simplification rules by
    80 A final alternative is to replace the offending simplification rules by
    77 derived conditional ones. For \isa{gcd} it means we have to prove
    81 derived conditional ones. For \isa{gcd} it means we have to prove
    78 these lemmas:%
    82 these lemmas:%
    79 \end{isamarkuptext}%
    83 \end{isamarkuptext}%
    80 \isacommand{lemma}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}gcd\ {\isacharparenleft}m{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
    84 \isacommand{lemma}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}gcd\ {\isacharparenleft}m{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
    81 \isacommand{apply}{\isacharparenleft}simp{\isacharparenright}\isanewline
    85 \isacommand{apply}{\isacharparenleft}simp{\isacharparenright}\isanewline
    82 \isacommand{done}\isanewline
    86 \isacommand{done}\isanewline
       
    87 \isanewline
    83 \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
    88 \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
    84 \isacommand{apply}{\isacharparenleft}simp{\isacharparenright}\isanewline
    89 \isacommand{apply}{\isacharparenleft}simp{\isacharparenright}\isanewline
    85 \isacommand{done}%
    90 \isacommand{done}%
    86 \begin{isamarkuptext}%
    91 \begin{isamarkuptext}%
    87 \noindent
    92 \noindent
       
    93 Simplification terminates for these proofs because the condition of the \isa{if} simplifies to \isa{True} or \isa{False}.
    88 Now we can disable the original simplification rule:%
    94 Now we can disable the original simplification rule:%
    89 \end{isamarkuptext}%
    95 \end{isamarkuptext}%
    90 \isacommand{declare}\ gcd{\isachardot}simps\ {\isacharbrackleft}simp\ del{\isacharbrackright}\isanewline
    96 \isacommand{declare}\ gcd{\isachardot}simps\ {\isacharbrackleft}simp\ del{\isacharbrackright}\isanewline
    91 \end{isabellebody}%
    97 \end{isabellebody}%
    92 %%% Local Variables:
    98 %%% Local Variables: