doc-src/TutorialI/Recdef/document/simplification.tex
changeset 9674 f789d2490669
parent 9644 6b0b6b471855
child 9719 c753196599f9
equal deleted inserted replaced
9673:1b2d4f995b13 9674:f789d2490669
     6 \isacommand{primrec}. In most cases this works fine, but there is a subtle
     6 \isacommand{primrec}. In most cases this works fine, but there is a subtle
     7 problem that must be mentioned: simplification may not
     7 problem that must be mentioned: simplification may not
     8 terminate because of automatic splitting of \isa{if}.
     8 terminate because of automatic splitting of \isa{if}.
     9 Let us look at an example:%
     9 Let us look at an example:%
    10 \end{isamarkuptext}%
    10 \end{isamarkuptext}%
    11 \isacommand{consts}\ gcd\ ::\ {"}nat*nat\ {\isasymRightarrow}\ nat{"}\isanewline
    11 \isacommand{consts}\ gcd\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isacharasterisk}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
    12 \isacommand{recdef}\ gcd\ {"}measure\ ({\isasymlambda}(m,n).n){"}\isanewline
    12 \isacommand{recdef}\ gcd\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    13 \ \ {"}gcd\ (m,\ n)\ =\ (if\ n=0\ then\ m\ else\ gcd(n,\ m\ mod\ n)){"}%
    13 \ \ {\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}%
    14 \begin{isamarkuptext}%
    14 \begin{isamarkuptext}%
    15 \noindent
    15 \noindent
    16 According to the measure function, the second argument should decrease with
    16 According to the measure function, the second argument should decrease with
    17 each recursive call. The resulting termination condition
    17 each recursive call. The resulting termination condition
    18 \begin{quote}
    18 \begin{quote}
    19 
    19 
    20 \begin{isabelle}%
    20 \begin{isabelle}%
    21 \mbox{n}\ {\isasymnoteq}\ 0\ {\isasymLongrightarrow}\ \mbox{m}\ mod\ \mbox{n}\ <\ \mbox{n}
    21 \mbox{n}\ {\isasymnoteq}\ \isadigit{0}\ {\isasymLongrightarrow}\ \mbox{m}\ mod\ \mbox{n}\ {\isacharless}\ \mbox{n}
    22 \end{isabelle}%
    22 \end{isabelle}%
    23 
    23 
    24 \end{quote}
    24 \end{quote}
    25 is provded automatically because it is already present as a lemma in the
    25 is provded automatically because it is already present as a lemma in the
    26 arithmetic library. Thus the recursion equation becomes a simplification
    26 arithmetic library. Thus the recursion equation becomes a simplification
    31 condition simplifies to neither \isa{True} nor \isa{False}. For
    31 condition simplifies to neither \isa{True} nor \isa{False}. For
    32 example, simplification reduces
    32 example, simplification reduces
    33 \begin{quote}
    33 \begin{quote}
    34 
    34 
    35 \begin{isabelle}%
    35 \begin{isabelle}%
    36 gcd\ (\mbox{m},\ \mbox{n})\ =\ \mbox{k}
    36 gcd\ {\isacharparenleft}\mbox{m}{\isacharcomma}\ \mbox{n}{\isacharparenright}\ {\isacharequal}\ \mbox{k}
    37 \end{isabelle}%
    37 \end{isabelle}%
    38 
    38 
    39 \end{quote}
    39 \end{quote}
    40 in one step to
    40 in one step to
    41 \begin{quote}
    41 \begin{quote}
    42 
    42 
    43 \begin{isabelle}%
    43 \begin{isabelle}%
    44 (if\ \mbox{n}\ =\ 0\ then\ \mbox{m}\ else\ gcd\ (\mbox{n},\ \mbox{m}\ mod\ \mbox{n}))\ =\ \mbox{k}
    44 {\isacharparenleft}if\ \mbox{n}\ {\isacharequal}\ \isadigit{0}\ then\ \mbox{m}\ else\ gcd\ {\isacharparenleft}\mbox{n}{\isacharcomma}\ \mbox{m}\ mod\ \mbox{n}{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ \mbox{k}
    45 \end{isabelle}%
    45 \end{isabelle}%
    46 
    46 
    47 \end{quote}
    47 \end{quote}
    48 where the condition cannot be reduced further, and splitting leads to
    48 where the condition cannot be reduced further, and splitting leads to
    49 \begin{quote}
    49 \begin{quote}
    50 
    50 
    51 \begin{isabelle}%
    51 \begin{isabelle}%
    52 (\mbox{n}\ =\ 0\ {\isasymlongrightarrow}\ \mbox{m}\ =\ \mbox{k})\ {\isasymand}\ (\mbox{n}\ {\isasymnoteq}\ 0\ {\isasymlongrightarrow}\ gcd\ (\mbox{n},\ \mbox{m}\ mod\ \mbox{n})\ =\ \mbox{k})
    52 {\isacharparenleft}\mbox{n}\ {\isacharequal}\ \isadigit{0}\ {\isasymlongrightarrow}\ \mbox{m}\ {\isacharequal}\ \mbox{k}{\isacharparenright}\ {\isasymand}\ {\isacharparenleft}\mbox{n}\ {\isasymnoteq}\ \isadigit{0}\ {\isasymlongrightarrow}\ gcd\ {\isacharparenleft}\mbox{n}{\isacharcomma}\ \mbox{m}\ mod\ \mbox{n}{\isacharparenright}\ {\isacharequal}\ \mbox{k}{\isacharparenright}
    53 \end{isabelle}%
    53 \end{isabelle}%
    54 
    54 
    55 \end{quote}
    55 \end{quote}
    56 Since the recursive call \isa{gcd\ (\mbox{n},\ \mbox{m}\ mod\ \mbox{n})} is no longer protected by
    56 Since the recursive call \isa{gcd\ {\isacharparenleft}\mbox{n}{\isacharcomma}\ \mbox{m}\ mod\ \mbox{n}{\isacharparenright}} is no longer protected by
    57 an \isa{if}, it is unfolded again, which leads to an infinite chain of
    57 an \isa{if}, it is unfolded again, which leads to an infinite chain of
    58 simplification steps. Fortunately, this problem can be avoided in many
    58 simplification steps. Fortunately, this problem can be avoided in many
    59 different ways.
    59 different ways.
    60 
    60 
    61 The most radical solution is to disable the offending
    61 The most radical solution is to disable the offending
    66 
    66 
    67 If possible, the definition should be given by pattern matching on the left
    67 If possible, the definition should be given by pattern matching on the left
    68 rather than \isa{if} on the right. In the case of \isa{gcd} the
    68 rather than \isa{if} on the right. In the case of \isa{gcd} the
    69 following alternative definition suggests itself:%
    69 following alternative definition suggests itself:%
    70 \end{isamarkuptext}%
    70 \end{isamarkuptext}%
    71 \isacommand{consts}\ gcd1\ ::\ {"}nat*nat\ {\isasymRightarrow}\ nat{"}\isanewline
    71 \isacommand{consts}\ gcd\isadigit{1}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isacharasterisk}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
    72 \isacommand{recdef}\ gcd1\ {"}measure\ ({\isasymlambda}(m,n).n){"}\isanewline
    72 \isacommand{recdef}\ gcd\isadigit{1}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    73 \ \ {"}gcd1\ (m,\ 0)\ =\ m{"}\isanewline
    73 \ \ {\isachardoublequote}gcd\isadigit{1}\ {\isacharparenleft}m{\isacharcomma}\ \isadigit{0}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
    74 \ \ {"}gcd1\ (m,\ n)\ =\ gcd1(n,\ m\ mod\ n){"}%
    74 \ \ {\isachardoublequote}gcd\isadigit{1}\ {\isacharparenleft}m{\isacharcomma}\ n{\isacharparenright}\ {\isacharequal}\ gcd\isadigit{1}{\isacharparenleft}n{\isacharcomma}\ m\ mod\ n{\isacharparenright}{\isachardoublequote}%
    75 \begin{isamarkuptext}%
    75 \begin{isamarkuptext}%
    76 \noindent
    76 \noindent
    77 Note that the order of equations is important and hides the side condition
    77 Note that the order of equations is important and hides the side condition
    78 \isa{n \isasymnoteq\ 0}. Unfortunately, in general the case distinction
    78 \isa{n \isasymnoteq\ 0}. Unfortunately, in general the case distinction
    79 may not be expressible by pattern matching.
    79 may not be expressible by pattern matching.
    80 
    80 
    81 A very simple alternative is to replace \isa{if} by \isa{case}, which
    81 A very simple alternative is to replace \isa{if} by \isa{case}, which
    82 is also available for \isa{bool} but is not split automatically:%
    82 is also available for \isa{bool} but is not split automatically:%
    83 \end{isamarkuptext}%
    83 \end{isamarkuptext}%
    84 \isacommand{consts}\ gcd2\ ::\ {"}nat*nat\ {\isasymRightarrow}\ nat{"}\isanewline
    84 \isacommand{consts}\ gcd\isadigit{2}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}nat{\isacharasterisk}nat\ {\isasymRightarrow}\ nat{\isachardoublequote}\isanewline
    85 \isacommand{recdef}\ gcd2\ {"}measure\ ({\isasymlambda}(m,n).n){"}\isanewline
    85 \isacommand{recdef}\ gcd\isadigit{2}\ {\isachardoublequote}measure\ {\isacharparenleft}{\isasymlambda}{\isacharparenleft}m{\isacharcomma}n{\isacharparenright}{\isachardot}n{\isacharparenright}{\isachardoublequote}\isanewline
    86 \ \ {"}gcd2(m,n)\ =\ (case\ n=0\ of\ True\ {\isasymRightarrow}\ m\ |\ False\ {\isasymRightarrow}\ gcd2(n,m\ mod\ n)){"}%
    86 \ \ {\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}%
    87 \begin{isamarkuptext}%
    87 \begin{isamarkuptext}%
    88 \noindent
    88 \noindent
    89 In fact, this is probably the neatest solution next to pattern matching.
    89 In fact, this is probably the neatest solution next to pattern matching.
    90 
    90 
    91 A final alternative is to replace the offending simplification rules by
    91 A final alternative is to replace the offending simplification rules by
    92 derived conditional ones. For \isa{gcd} it means we have to prove%
    92 derived conditional ones. For \isa{gcd} it means we have to prove%
    93 \end{isamarkuptext}%
    93 \end{isamarkuptext}%
    94 \isacommand{lemma}\ [simp]:\ {"}gcd\ (m,\ 0)\ =\ m{"}\isanewline
    94 \isacommand{lemma}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}gcd\ {\isacharparenleft}m{\isacharcomma}\ \isadigit{0}{\isacharparenright}\ {\isacharequal}\ m{\isachardoublequote}\isanewline
    95 \isacommand{by}(simp)\isanewline
    95 \isacommand{by}{\isacharparenleft}simp{\isacharparenright}\isanewline
    96 \isacommand{lemma}\ [simp]:\ {"}n\ {\isasymnoteq}\ 0\ {\isasymLongrightarrow}\ gcd(m,\ n)\ =\ gcd(n,\ m\ mod\ n){"}\isanewline
    96 \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
    97 \isacommand{by}(simp)%
    97 \isacommand{by}{\isacharparenleft}simp{\isacharparenright}%
    98 \begin{isamarkuptext}%
    98 \begin{isamarkuptext}%
    99 \noindent
    99 \noindent
   100 after which we can disable the original simplification rule:%
   100 after which we can disable the original simplification rule:%
   101 \end{isamarkuptext}%
   101 \end{isamarkuptext}%
   102 \isacommand{lemmas}\ [simp\ del]\ =\ gcd.simps\isanewline
   102 \isacommand{lemmas}\ {\isacharbrackleft}simp\ del{\isacharbrackright}\ {\isacharequal}\ gcd{\isachardot}simps\isanewline
   103 \end{isabelle}%
   103 \end{isabelle}%
   104 %%% Local Variables:
   104 %%% Local Variables:
   105 %%% mode: latex
   105 %%% mode: latex
   106 %%% TeX-master: "root"
   106 %%% TeX-master: "root"
   107 %%% End:
   107 %%% End: