Single Instruction URM Programs

Basic Primitive Recursive Functions
The basic primitive recursive functions are URM computable by a single-instruction URM program:

Zero Function
The zero function $$\operatorname{zero}: \N \to \N$$, defined as:
 * $$\forall n \in \N: \operatorname{zero} \left({n}\right) = 0$$.

Successor Function
The successor function $$\operatorname{succ}: \N \to \N$$, defined as:
 * $$\forall n \in \N: \operatorname{succ} \left({n}\right) = n + 1$$.

Projection Function
The projection functions $$\operatorname{pr}^k_j: \N^k \to \N$$, defined as:
 * $$\forall \left({n_1, n_2, \ldots, n_k}\right) \in \N^k: \operatorname{pr}^k_j \left({\left({n_1, n_2, \ldots, n_k}\right)}\right) = n_j$$

where $$j \in \left[{1 \,. \, . \, k}\right]$$.

Identity Function
In addition, so is the identity function $$I_{\N}: \N \to \N$$ defined as:
 * $$\forall n \in \N: I_{\N} \left({n}\right) = n$$.

No other functions $$f: \N^k \to \N$$ can be computed using a single-instruction URM program.

Proof
These functions are computed by the following URM programs:

Program for Zero Function
This sets the value $$0$$ into $$R_1$$ and then stops.

The output $$0$$ is in $$R_1$$ when the program terminates.

Program for Successor Function
The input $$n$$ is in $$R_1$$ when the program starts.

The program adds $$1$$ to $$r_1$$ and then stops.

The output $$n+1$$ is in $$R_1$$ when the program terminates.

Program for Projection Function
The input $$\left({n_1, n_2, \ldots, n_j, \ldots, n_k}\right)$$ is in $$R_1, R_2, \ldots, R_j, \ldots, R_k$$ when the program starts.

The program copies $$r_j$$ to $$r_1$$ and then stops.

The output $$n_j$$ is in $$R_1$$ when the program terminates.

Program for Identity Function
Any of the following URM programs compute the identity function:

... where $$m \ne 1$$.

This sets the value $$0$$ into $$R_m$$ and then stops.

... where $$m \ne 1$$.

The input $$n$$ is in $$R_1$$ when the program starts.

The program adds $$1$$ to $$r_m$$ and then stops.

... where $$m \ne 1$$.

The input $$n$$ is in $$R_1$$ when the program starts.

The program copies $$r_j$$ to $$r_m$$ and then stops.

The input $$n$$ is in $$R_1$$ when the program starts.

The program copies $$r_1$$ to $$r_1$$, i.e. to itself, and then stops.

In none of these programs is $$R_1$$ affected, and so no change is effected to the input, which is returned as the output unchanged.

Hence they all compute the identity function.

Note that the latter program consisting entirely of $$C \left({1, 1}\right)$$ is a direct implementation of the projection function $$\operatorname{pr}^1_1: \N \to \N$$.

This latter function is the usual way of implementing the identity function as it is well-defined and obvious, and guaranteed to have no other side-effects when embedded in a larger program.

Proof that No Others Exist
The only other single-instruction programs are of the form:

The convention is that, at the start of the program, $$R_1$$ contains the input, and all other registers contain $$0$$.


 * Suppose $$q > 1$$.

Then whatever $$m$$ or $$n$$ are, the program either jumps to $$q$$ (a location outside the program) or steps one instruction.

In either case the program stops without changing what is in $$R_1$$.

Hence this is another way of computing the identity function $$I_{\N}$$.


 * Suppose $$q = 1$$.

If $$m = n$$ then whatever is held in the registers, $$r_m = r_n$$ and the program will go back to execute step 1 again.

Thus the program will loop round and do step 1 endlessly, and never terminate.

If $$m \ne n$$ the program's behaviour depends on the contents of $$R_n$$ and $$R_m$$.


 * If $$m = 1$$ and $$n \ne 1$$, then the program will compare the input against the contents of $$r_n$$.

If $$r_1 = 0$$ the program will go into an endless loop, and never terminate.

Otherwise, i.e. if $$r_1 \ne 0$$, the program will never terminate with $$r_1$$ unchanged.


 * If $$m \ne 1$$ and $$n \ne 1$$ then the program will once more never terminate, as $$r_m = r_n = 0$$ at the start of the program.

So the program:

does not specify a URM computable function, as:
 * when $$m = n$$ the program will never terminate for any input;
 * when $$m \ne n, m = 1$$ the program will never terminate on input $$0$$;
 * when $$m \ne n, n = 1$$ the program similarly will never terminate on input $$0$$;
 * when $$m \ne n, m \ne 1, n \ne 1$$ the program will never terminate for any input.

In all cases there is at least one input for which the program will never terminate.

The result follows from the definition of URM computability.