src/Doc/Functions/Functions.thy
changeset 53107 57c7294eac0a
parent 50530 6266e44b3396
child 54017 2a3c07f49615
equal deleted inserted replaced
53092:7e89edba3db6 53107:57c7294eac0a
    85 
    85 
    86 text {*
    86 text {*
    87 
    87 
    88   Isabelle provides customized induction rules for recursive
    88   Isabelle provides customized induction rules for recursive
    89   functions. These rules follow the recursive structure of the
    89   functions. These rules follow the recursive structure of the
    90   definition. Here is the rule @{text sep.induct} arising from the
    90   definition. Here is the rule @{thm [source] sep.induct} arising from the
    91   above definition of @{const sep}:
    91   above definition of @{const sep}:
    92 
    92 
    93   @{thm [display] sep.induct}
    93   @{thm [display] sep.induct}
    94   
    94   
    95   We have a step case for list with at least two elements, and two
    95   We have a step case for list with at least two elements, and two
   385 subsection {* Induction for mutual recursion *}
   385 subsection {* Induction for mutual recursion *}
   386 
   386 
   387 text {*
   387 text {*
   388 
   388 
   389   When functions are mutually recursive, proving properties about them
   389   When functions are mutually recursive, proving properties about them
   390   generally requires simultaneous induction. The induction rule @{text "even_odd.induct"}
   390   generally requires simultaneous induction. The induction rule @{thm [source] "even_odd.induct"}
   391   generated from the above definition reflects this.
   391   generated from the above definition reflects this.
   392 
   392 
   393   Let us prove something about @{const even} and @{const odd}:
   393   Let us prove something about @{const even} and @{const odd}:
   394 *}
   394 *}
   395 
   395 
   505   \item Since splitting makes the equations \qt{less general}, they
   505   \item Since splitting makes the equations \qt{less general}, they
   506   do not always match in rewriting. While the term @{term "And x F"}
   506   do not always match in rewriting. While the term @{term "And x F"}
   507   can be simplified to @{term "F"} with the original equations, a
   507   can be simplified to @{term "F"} with the original equations, a
   508   (manual) case split on @{term "x"} is now necessary.
   508   (manual) case split on @{term "x"} is now necessary.
   509 
   509 
   510   \item The splitting also concerns the induction rule @{text
   510   \item The splitting also concerns the induction rule @{thm [source]
   511   "And.induct"}. Instead of five premises it now has seven, which
   511   "And.induct"}. Instead of five premises it now has seven, which
   512   means that our induction proofs will have more cases.
   512   means that our induction proofs will have more cases.
   513 
   513 
   514   \item In general, it increases clarity if we get the same definition
   514   \item In general, it increases clarity if we get the same definition
   515   back which we put in.
   515   back which we put in.
   728   pinduct}: 
   728   pinduct}: 
   729 *}
   729 *}
   730 
   730 
   731 text {*
   731 text {*
   732   \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.psimps}\end{minipage}
   732   \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.psimps}\end{minipage}
   733   \hfill(@{text "findzero.psimps"})
   733   \hfill(@{thm [source] "findzero.psimps"})
   734   \vspace{1em}
   734   \vspace{1em}
   735 
   735 
   736   \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.pinduct}\end{minipage}
   736   \noindent\begin{minipage}{0.79\textwidth}@{thm[display,margin=85] findzero.pinduct}\end{minipage}
   737   \hfill(@{text "findzero.pinduct"})
   737   \hfill(@{thm [source] "findzero.pinduct"})
   738 *}
   738 *}
   739 
   739 
   740 text {*
   740 text {*
   741   Remember that all we
   741   Remember that all we
   742   are doing here is use some tricks to make a total function appear
   742   are doing here is use some tricks to make a total function appear
   852   termination proof. Usually, you want to combine them with a suitable
   852   termination proof. Usually, you want to combine them with a suitable
   853   induction principle.
   853   induction principle.
   854 
   854 
   855   Since our function increases its argument at recursive calls, we
   855   Since our function increases its argument at recursive calls, we
   856   need an induction principle which works \qt{backwards}. We will use
   856   need an induction principle which works \qt{backwards}. We will use
   857   @{text inc_induct}, which allows to do induction from a fixed number
   857   @{thm [source] inc_induct}, which allows to do induction from a fixed number
   858   \qt{downwards}:
   858   \qt{downwards}:
   859 
   859 
   860   \begin{center}@{thm inc_induct}\hfill(@{text "inc_induct"})\end{center}
   860   \begin{center}@{thm inc_induct}\hfill(@{thm [source] "inc_induct"})\end{center}
   861 
   861 
   862   Figure \ref{findzero_term} gives a detailed Isar proof of the fact
   862   Figure \ref{findzero_term} gives a detailed Isar proof of the fact
   863   that @{text findzero} terminates if there is a zero which is greater
   863   that @{text findzero} terminates if there is a zero which is greater
   864   or equal to @{term n}. First we derive two useful rules which will
   864   or equal to @{term n}. First we derive two useful rules which will
   865   solve the base case and the step case of the induction. The
   865   solve the base case and the step case of the induction. The
   934 
   934 
   935   The domain predicate is the \emph{accessible part} of a relation @{const
   935   The domain predicate is the \emph{accessible part} of a relation @{const
   936   findzero_rel}, which was also created internally by the function
   936   findzero_rel}, which was also created internally by the function
   937   package. @{const findzero_rel} is just a normal
   937   package. @{const findzero_rel} is just a normal
   938   inductive predicate, so we can inspect its definition by
   938   inductive predicate, so we can inspect its definition by
   939   looking at the introduction rules @{text findzero_rel.intros}.
   939   looking at the introduction rules @{thm [source] findzero_rel.intros}.
   940   In our case there is just a single rule:
   940   In our case there is just a single rule:
   941 
   941 
   942   @{thm[display] findzero_rel.intros}
   942   @{thm[display] findzero_rel.intros}
   943 
   943 
   944   The predicate @{const findzero_rel}
   944   The predicate @{const findzero_rel}
   953   be reached in a finite number of steps (cf.~its definition in @{text
   953   be reached in a finite number of steps (cf.~its definition in @{text
   954   "Wellfounded.thy"}).
   954   "Wellfounded.thy"}).
   955 
   955 
   956   Since the domain predicate is just an abbreviation, you can use
   956   Since the domain predicate is just an abbreviation, you can use
   957   lemmas for @{const accp} and @{const findzero_rel} directly. Some
   957   lemmas for @{const accp} and @{const findzero_rel} directly. Some
   958   lemmas which are occasionally useful are @{text accpI}, @{text
   958   lemmas which are occasionally useful are @{thm [source] accpI}, @{thm [source]
   959   accp_downward}, and of course the introduction and elimination rules
   959   accp_downward}, and of course the introduction and elimination rules
   960   for the recursion relation @{text "findzero.intros"} and @{text "findzero.cases"}.
   960   for the recursion relation @{thm [source] "findzero_rel.intros"} and @{thm
       
   961   [source] "findzero_rel.cases"}.
   961 *}
   962 *}
   962 
   963 
   963 section {* Nested recursion *}
   964 section {* Nested recursion *}
   964 
   965 
   965 text {*
   966 text {*
  1156   For this definition, the termination proof fails. The default configuration
  1157   For this definition, the termination proof fails. The default configuration
  1157   specifies no congruence rule for disjunction. We have to add a
  1158   specifies no congruence rule for disjunction. We have to add a
  1158   congruence rule that specifies left-to-right evaluation order:
  1159   congruence rule that specifies left-to-right evaluation order:
  1159 
  1160 
  1160   \vspace{1ex}
  1161   \vspace{1ex}
  1161   \noindent @{thm disj_cong}\hfill(@{text "disj_cong"})
  1162   \noindent @{thm disj_cong}\hfill(@{thm [source] "disj_cong"})
  1162   \vspace{1ex}
  1163   \vspace{1ex}
  1163 
  1164 
  1164   Now the definition works without problems. Note how the termination
  1165   Now the definition works without problems. Note how the termination
  1165   proof depends on the extra condition that we get from the congruence
  1166   proof depends on the extra condition that we get from the congruence
  1166   rule.
  1167   rule.