doc-src/TutorialI/Advanced/Partial.thy
changeset 11277 a2bff98d6e5d
parent 11256 49afcce3bada
child 11285 3826c51d980e
equal deleted inserted replaced
11276:f8353c722d4e 11277:a2bff98d6e5d
     1 (*<*)theory Partial = While_Combinator:(*>*)
     1 (*<*)theory Partial = While_Combinator:(*>*)
     2 
     2 
     3 text{*\noindent
     3 text{*\noindent Throughout the tutorial we have emphasized the fact
     4 Throughout the tutorial we have emphasized the fact that all functions
     4 that all functions in HOL are total. Hence we cannot hope to define
     5 in HOL are total. Hence we cannot hope to define truly partial
     5 truly partial functions but must totalize them. A straightforward
     6 functions. The best we can do are functions that are
     6 totalization is to lift the result type of the function from $\tau$ to
     7 \emph{underdefined}\index{underdefined function}:
     7 $\tau$~@{text option} (see \ref{sec:option}), where @{term None} is
     8 for certain arguments we only know that a result
     8 returned if the function is applied to an argument not in its
     9 exists, but we do not know what it is. When defining functions that are
     9 domain. Function @{term assoc} in \S\ref{sec:Trie} is a simple example.
    10 normally considered partial, underdefinedness turns out to be a very
    10 We do not pursue this schema further because it should be clear
    11 reasonable alternative.
    11 how it works. Its main drawback is that the result of such a lifted
       
    12 function has to be unpacked first before it can be processed
       
    13 further. Its main advantage is that you can distinguish if the
       
    14 function was applied to an argument in its domain or not. If you do
       
    15 not need to make this distinction, for example because the function is
       
    16 never used outside its domain, it is easier to work with
       
    17 \emph{underdefined}\index{underdefined function} functions: for
       
    18 certain arguments we only know that a result exists, but we do not
       
    19 know what it is. When defining functions that are normally considered
       
    20 partial, underdefinedness turns out to be a very reasonable
       
    21 alternative.
    12 
    22 
    13 We have already seen an instance of underdefinedness by means of
    23 We have already seen an instance of underdefinedness by means of
    14 non-exhaustive pattern matching: the definition of @{term last} in
    24 non-exhaustive pattern matching: the definition of @{term last} in
    15 \S\ref{sec:recdef-examples}. The same is allowed for \isacommand{primrec}
    25 \S\ref{sec:recdef-examples}. The same is allowed for \isacommand{primrec}
    16 *}
    26 *}
    59 latter option is chosen for the predefined @{text div} function, which
    69 latter option is chosen for the predefined @{text div} function, which
    60 simplifies proofs at the expense of deviating from the
    70 simplifies proofs at the expense of deviating from the
    61 standard mathematical division function.
    71 standard mathematical division function.
    62 
    72 
    63 As a more substantial example we consider the problem of searching a graph.
    73 As a more substantial example we consider the problem of searching a graph.
    64 For simplicity our graph is given by a function (@{term f}) of
    74 For simplicity our graph is given by a function @{term f} of
    65 type @{typ"'a \<Rightarrow> 'a"} which
    75 type @{typ"'a \<Rightarrow> 'a"} which
    66 maps each node to its successor, i.e.\ the graph is really a tree.
    76 maps each node to its successor, i.e.\ the graph is really a tree.
    67 The task is to find the end of a chain, modelled by a node pointing to
    77 The task is to find the end of a chain, modelled by a node pointing to
    68 itself. Here is a first attempt:
    78 itself. Here is a first attempt:
    69 @{prop[display]"find(f,x) = (if f x = x then x else find(f, f x))"}
    79 @{prop[display]"find(f,x) = (if f x = x then x else find(f, f x))"}
    88 (hints recdef_simp:same_fst_def step1_def)
    98 (hints recdef_simp:same_fst_def step1_def)
    89 
    99 
    90 text{*\noindent
   100 text{*\noindent
    91 The recursion equation itself should be clear enough: it is our aborted
   101 The recursion equation itself should be clear enough: it is our aborted
    92 first attempt augmented with a check that there are no non-trivial loops.
   102 first attempt augmented with a check that there are no non-trivial loops.
    93 
   103 To express the required well-founded relation we employ the
    94 What complicates the termination proof is that the argument of @{term find}
       
    95 is a pair. To express the required well-founded relation we employ the
       
    96 predefined combinator @{term same_fst} of type
   104 predefined combinator @{term same_fst} of type
    97 @{text[display]"('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> ('b\<times>'b)set) \<Rightarrow> (('a\<times>'b) \<times> ('a\<times>'b))set"}
   105 @{text[display]"('a \<Rightarrow> bool) \<Rightarrow> ('a \<Rightarrow> ('b\<times>'b)set) \<Rightarrow> (('a\<times>'b) \<times> ('a\<times>'b))set"}
    98 defined as
   106 defined as
    99 @{thm[display]same_fst_def[no_vars]}
   107 @{thm[display]same_fst_def[no_vars]}
   100 This combinator is designed for
   108 This combinator is designed for
   175 of induction we apply the above while rule, suitably instantiated.
   183 of induction we apply the above while rule, suitably instantiated.
   176 Only the final premise of @{thm[source]while_rule} is left unproved
   184 Only the final premise of @{thm[source]while_rule} is left unproved
   177 by @{text auto} but falls to @{text simp}:
   185 by @{text auto} but falls to @{text simp}:
   178 *}
   186 *}
   179 
   187 
   180 lemma lem: "\<lbrakk> wf(step1 f); x' = f x \<rbrakk> \<Longrightarrow> 
   188 lemma lem: "wf(step1 f) \<Longrightarrow>
   181    \<exists>y. while (\<lambda>(x,x'). x' \<noteq> x) (\<lambda>(x,x'). (x',f x')) (x,x') = (y,y) \<and>
   189   \<exists>y. while (\<lambda>(x,x'). x' \<noteq> x) (\<lambda>(x,x'). (x',f x')) (x,f x) = (y,y) \<and>
   182        f y = y"
   190        f y = y"
   183 apply(rule_tac P = "\<lambda>(x,x'). x' = f x" and
   191 apply(rule_tac P = "\<lambda>(x,x'). x' = f x" and
   184                r = "inv_image (step1 f) fst" in while_rule);
   192                r = "inv_image (step1 f) fst" in while_rule);
   185 apply auto
   193 apply auto
   186 apply(simp add:inv_image_def step1_def)
   194 apply(simp add:inv_image_def step1_def)