4

I'm currently working on formalizing the theory of partial recursive functions, and something seems peculiar about the standard definition. The definition of the primitive recursion clause of $\mu$-recursive functions reads as follows (according to Wikipedia):

Given the $k$-ary function $g({\bf x})$ and $k+2$-ary function $h(y,z,{\bf x})$: \begin{align} \rho(g, h) &\stackrel{\mathrm{def}}{=} f \quad\text{where}\\ f(0,{\bf x}) &= g({\bf x}) \\ f(y+1,{\bf x}) &= h(y,f(y,{\bf x}),{\bf x}). \end{align}

I assume that this definition uses eager evaluation, which is to say that $h(y,f(y,{\bf x}),{\bf x})$ is defined only when $f(y,{\bf x})$ is, even if when we evaluate $h$ it turns out to be a projection or otherwise ignores this argument.

Now this evaluation order means that if $f(y,{\bf x})=\bot$ then $f(y+1,{\bf x})=\bot$. But now how can I define a conditional operator like so:

$$\mathrm{ifz}(g,h)(x)\simeq g(x)\quad\mbox{if }x=0$$ $$\mathrm{ifz}(g,h)(x)\simeq h(x)\quad\mbox{if }x\ne 0$$

where $a\simeq b$ means that both sides are undefined, or defined and equal? Without worrying about definedness, $\mathrm{ifz}$ is a trivial application of primitive recursion, but the naive definition will have $\mathrm{ifz}(\bot,0)(1)=\bot$ since it first tries to evaluate the zero branch. Since obviously Turing machines can define an $\mathrm{ifz}$ operator, either my definition is wrong or there is a more clever way to construct it.

Related (but also unanswered): Eager vs. lazy interpretation of recursive functions

  • With the caveat that I'm not very familiar with the conventions of the subject, generally there is no notion of "eager/lazy evaluation" in this place of the mathematics. An equation is simply a proposition that two things are the same, not a prescription of how to do a "computation". –  May 19 '18 at 15:26
  • @Hurkyl Here eagerness is manifested in the domain of the resulting function, so as a partial function it makes a difference. The evaluation order $\mapsto^*$ was only for discussion purposes; I'm representing these purely as partial functions in the mathematical sense. – Mario Carneiro May 19 '18 at 15:29
  • Usually, when writing some composite expression involving partial functions, one must make a decision about what to do about undefined subterms, and this is where "eagerness" comes in. For example, $\pi_2(\bot,0)$ is $\bot$ under eager semantics (the usual convention), and under lazy semantics $\pi_2(\bot,0)$ is $0$. There is no actual evaluation order here, but one expression is undefined and the other is defined so they are not $\simeq$ equivalent. – Mario Carneiro May 19 '18 at 15:32
  • This actually manifests in ordinary algebra. "Sets and partial functions" turns out to be equivalent to "Pointed sets and homomorphisms". There are two distinct, relevant notions of product in the category of pointed sets: the cartesian product, in which you'd have $(\bot, 0) \neq (\bot, \bot)$, and the smash product in which you'd have $(\bot, 0) = (\bot, \bot)$. (in both cases, $(\bot, \bot)$ is the bottom element). –  May 19 '18 at 15:43
  • And, IIRC, it's the smash product, not the Cartesian product, that plays the natural role in the logic of functions. (e.g. currying/uncurrying) –  May 19 '18 at 15:46
  • There is an slight error in the linked question - we do not allow minimization to be applied to just any partial function, only to total functions. If we are allowed to apply minimization to partial computable functions, we end up with a class of functions larger than the class of partial computable functions. For example if we iterate $f(x) = \mu e. [ e \geq x \land \phi_e(0)\downarrow]$ we can enumerate the halting set $K$ in increasing order - no enumeration of that kind can be computable because $K$ is not computable. – Carl Mummert May 20 '18 at 01:45
  • @CarlMummert When using partial functions in the $\mu$ operator (which is not uncommon), $\mu n.,[f(n)=0]$ is only said to be defined when there is a number $n$ satisfying $f(n)=0$ and also $f(m)$ is defined and nonzero at all $m<n$. That way it can be implemented as a naive sequential search on a Turing machine, and this does not enlarge the class. – Mario Carneiro May 20 '18 at 02:37
  • Dear @CarlMummert I really do disagree with the fact that $\mu$ can only be used on total functions, otherwise it would not be recursive to know if a function is valid, as it is not recursive to know if a function is total. – Xoff May 20 '18 at 05:39
  • @Xoff: indeed, but it there is no reason to expect that we know if a function is valid when written in that way. The way around this is to just write functions directly in the style of the normal form theorem - every definition written in that way is valid and every partial computable function can be written in that way. – Carl Mummert May 20 '18 at 10:53
  • @CarlMummert But let's say you have $f$ and $g$ on normal form. How can you compute the normal form of $\mu(f\circ g)$, if you can't even know if it's valid or not, because if it's not valid, it should probably be everywhere undefined, while if it is valid, it can be even total ! You're losing the fondamental recursiveness of $\mu$ and $\circ$ operators. The Gödel numbering rely ultimately on that. Every operations/compositions must lead to a valid function/program. – Xoff May 20 '18 at 12:24
  • You can compute the index of the normal form of the composition uniformly from the indices of the two functions you are composing. // But one standard version of the $\mu$ operator does always not lead to partial computable functions when applied to partial computable functions (I typed an example somewhere in this discussion) - although that same form of the $\mu$ operator works fine for the normal form theorem. That version of the $\mu$ operator is only effective when applied to total functions. – Carl Mummert May 20 '18 at 12:42
  • At the same time, for the other version of the $\mu$ operator - the one that is essentially just a while loop - we can again effectively compute an index of $\mu x.f$ from an index of $f$, of course. – Carl Mummert May 20 '18 at 12:45
  • @CarlMummert I'm sorry, I don't see myself as an expert, so i won't go on arguing, but explaining there are two different $\mu$ operators looks dangerously wrong to me. The one and only is a while loop, the other you are describing is just not computable. So I probably disagree with the spirit of your answer too, as the Kleene NF is a theorem not an axiom. Sorry – Xoff May 20 '18 at 14:16

2 Answers2

3

In many treatments of computability theory, primitive recursion is only applied to total functions, and then the $\mu$ operator is also only applied to total functions. Composition is the only operation that needs to be applied to (potentially) partial functions.

This shows up in Kleene's normal form theorem: each partial computable function $f(\bar x)$ can be written in the form $$ f(\bar x) \simeq U(\mu z. T(e,z,\bar x)) $$ for some fixed "index" $e$. Here both $T$ and $U$ are specific total primitive recursive functions, and the only possible way that $f$ could be partial is from the single application of the $\mu$ operator.

So, if $f$ and $g$ are partial computable, how do we find the normal form for the partial function $I(g,h,y,x)$ with $$ I(g,h,y,x) \simeq \begin{cases} g(x) & y = 0, \\ h(x) & y \not = 0.\end{cases} $$

Start by letting $e_g$ be an index of $g$ and $e_h$ be an index of $h$. Let $w(z,y,x) $ be the primitive recursive relation $$ w(z,y,x) = \text{True} \leftrightarrow [ ( y = 0 \land T(e_g, z, x) ) \lor ( y \not = 0 \land T(e_h, z, x)] $$ This function for $w$ is a total primitive recursive function. Let $e_w$ be the appropriate index for $w$. Then we have $$ I(g,h,y,x) \simeq U(\mu z.T(e_w,z,y,x)) $$ as desired. Here we do not need to worry about whether the definition of primitive recursion allows for lazy evaluation because we can build it into the index $e_w$.

Carl Mummert
  • 84,178
  • Of course this same method can be used to make lazy projection functions and all other sorts of lazy functions - which is to say we can prove that if the lazy projection is applied to a pair of partial computable function then the desired reutling function is also partial computable. – Carl Mummert May 20 '18 at 02:04
  • I came to a similar conclusion - you need the normal form theorem to do "parallel computation", so that you can make internal sense of "lazy operations". – Mario Carneiro May 20 '18 at 02:41
  • This answer can also be simplified a bit: Given indices $e_g$ and $e_h$, the function $E(x)=\begin{cases}e_g&x=0\e_h&x\ne 0\end{cases}$ is primitive recursive (by the usual definition of ifz), and then $\phi(E(x),x)$ is the desired function, where $\phi(e,\bar x)\simeq U(\mu z.T(e,z,\bar x))$ is the universal pcf. – Mario Carneiro May 24 '18 at 04:45
0

$ifz(g,h)$ can be defined by

$\rho(g,h\circ(P^3_1))\circ(P^1_1,P^1_1)$

Note that evaluation strategy is not a problem here because $ifz$ need only to evaluate its input (is $x=0$ ?) and not the result of $g(0)$ or $h(x)$ to decide what it must do. But of course, if the strategy is not lazy, the case $x>0$ can be problematic. That's a good remark. I usually go with the lazy evaluation when I teach or simulate those functions. Note that the semantic is supposed to be lazy anyway : $P ^2_1(x_1,x_2)=x_1$ even if $x_2=\bot$.

Xoff
  • 10,493
  • With respect, this seems to be dodging the question. Do you have sources for evidence that lazy semantics is normally used here? Or is every textbook wrong? Personally, I am loath to adopt lazy semantics because it breaks the pairing function (you can't encode $(n,\bot)$ as a number in such a way that $L(n,\bot)=n$), which is important for cutting down on the parameter complexity. – Mario Carneiro May 19 '18 at 23:00
  • I would say that in computability theory (the mathematical one, rather than computer science), $P^2_1$ is typically defined as a function from $\mathbb{N} \times \mathbb{N}$ to $\mathbb{N}$. It does not make sense to evaluate it at $\bot$, but we don't treat $\bot$ as an actual value in any case, just a shorthand for some computation not halting. – Carl Mummert May 20 '18 at 01:41
  • @MarioCarneiro The pairing function must be seen as an actual computation that use both parameters (like the Cantor bijection), and so we have implicitly $\langle n,\bot\rangle=\bot$. But projection functions are another thing. – Xoff May 20 '18 at 05:14
  • @CarlMummert But $ P^2_1\circ(0,\mu(S))$ is a valid mu-recursive function. So, if it doesn't make sense to evaluate this expression, you implies always an eager evaluation. I don't read that in the Kleene's definitions. – Xoff May 20 '18 at 05:22
  • @Xoff: it makes sense to evaluate the latter because of the definition of generalized composition; that does not mean actually evaluating $P^2_1$ at the value $\bot$. In this case, because $\mu x.S(x)$ is never defined, $(0, \mu x.S(x))$ will also never be defined (its program won't halt unless it has a value for both arguments), and so $P^2_1 \circ (0, \mu x.S(x))$ is also never defined by the definition of generalized composition. But nevertheless $P^2_1 \circ (0, \mu x.S(x))$ is a partial computable function. – Carl Mummert May 20 '18 at 10:58