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) |