Cite

This course has no released version yet: the text at this address may change. Cite a released version when one exists.

/courses/models-of-computation/register-machines
@misc{models-of-computation-register-machines,
  title = {{Register machines}},
  howpublished = {Lesson 4 of \emph{Models of computation}, Computability Theory course notes},
  url = {/courses/models-of-computation/register-machines},
  note = {Unreleased working version}
}

To cite a single statement, use the # link that appears next to its heading.

Lesson 4 of 13

Register machines

Unlimited register machines (URM), their operational semantics, examples, concatenation of programs, and closure of URM-computable functions under composition.

35 min5 questions
Models of computation · lesson 4 of 13
  1. Algorithms and partial functions
  2. Turing machines
  3. Programming Turing machines
  4. Register machines
  5. Primitive recursive functions
  6. Coding finite sequences
  7. The Ackermann function
  8. Minimization and partial recursive functions
  9. LOOP and WHILE programs
  10. The λ-calculus
  11. Computing with λ-terms
  12. Equivalence of the models
  13. The Church–Turing thesis

Turing machines access their memory sequentially, one cell at a time. Register machines instead have a memory made of registers, each holding a natural number, accessed directly by their index. Several variants were introduced around 1960 by Melzak, Lambek, Minsky, and Shepherdson and Sturgis. We use the unlimited register machine (URM) of Shepherdson and Sturgis, in the form popularized by Cutland’s textbook. Its instruction set is small, which makes proofs about it short, and close to an assembly language, which makes it easy to program.

4.1 Definition

The machine has infinitely many registers R1,R2,R3,…R_1, R_2, R_3, \dots, each containing a natural number. There is no bound on the size of these numbers.

Definition 4.1.#

A URM program is a finite sequence P=I1,…,IsP = I_1, \dots, I_s of instructions, each of one of the following four types:

instruction name effect
Z(n)Z(n) zero Rn←0R_n \leftarrow 0
S(n)S(n) successor Rn←Rn+1R_n \leftarrow R_n + 1
T(m,n)T(m, n) transfer Rn←RmR_n \leftarrow R_m
J(m,n,q)J(m, n, q) jump if Rm=RnR_m = R_n, the next instruction is IqI_q; otherwise it is the following one

where m,n,q≥1m, n, q \geq 1.

The operational semantics is defined through configurations.

Definition 4.2.#

A register state is a function r:N≥1→Nr : \nat_{\geq 1} \to \nat with r(n)=0r(n) = 0 for all but finitely many nn. A configuration of PP is a pair (i,r)(i, r) where i≥1i \geq 1 is the index of the next instruction and rr is a register state. It is halting if i>si > s.

If i≤si \leq s, the successor (i′,r′)(i', r') of (i,r)(i, r) is given by:

  • if Ii=Z(n)I_i = Z(n): r′=r[n↦0]r' = r[n \mapsto 0] and i′=i+1i' = i + 1;
  • if Ii=S(n)I_i = S(n): r′=r[n↦r(n)+1]r' = r[n \mapsto r(n) + 1] and i′=i+1i' = i + 1;
  • if Ii=T(m,n)I_i = T(m, n): r′=r[n↦r(m)]r' = r[n \mapsto r(m)] and i′=i+1i' = i + 1;
  • if Ii=J(m,n,q)I_i = J(m, n, q): r′=rr' = r, and i′=qi' = q if r(m)=r(n)r(m) = r(n), i′=i+1i' = i + 1 otherwise.

Here r[n↦v]r[n \mapsto v] denotes the state equal to rr except that register nn contains vv. The computation of PP from a configuration is the sequence of successive configurations, which is infinite or ends at the first halting configuration.

Jumping to an instruction index larger than ss is therefore a way of halting the program.

Definition 4.3.#

Let k≥1k \geq 1. The partial function φP(k):Nk⇀N\varphi^{(k)}_P : \nat^k \rightharpoonup \nat computed by PP is defined as follows. Start from the configuration (1,rx⃗)(1, r_{\vec x}), where rx⃗(n)=xnr_{\vec x}(n) = x_n for n≤kn \leq k and rx⃗(n)=0r_{\vec x}(n) = 0 for n>kn > k. If the computation halts, in a configuration (i,r)(i, r), then φP(k)(x⃗)=r(1)\varphi^{(k)}_P(\vec x) = r(1); otherwise φP(k)(x⃗) ⁣ ⁣↑\varphi^{(k)}_P(\vec x)\diverge.

A partial function is URM-computable if it is φP(k)\varphi^{(k)}_P for some program PP.

Note the asymmetries of the instruction set: registers can only be incremented, never decremented, and the only test is equality between two registers.

4.2 Examples

Addition. With xx in R1R_1 and yy in R2R_2, the following program uses R3R_3 as a counter kk and increments R1R_1 until k=yk = y:

I1I_1 J(2,3,5)J(2, 3, 5) if k=yk = y, halt
I2I_2 S(1)S(1)
I3I_3 S(3)S(3) k←k+1k \leftarrow k + 1
I4I_4 J(1,1,1)J(1, 1, 1) go to I1I_1

The instruction J(1,1,1)J(1, 1, 1) compares R1R_1 with itself and always jumps: it is an unconditional jump. By induction on j≤yj \leq y, the configuration (1,r)(1, r) with r(1)=x+jr(1) = x + j, r(2)=yr(2) = y, r(3)=jr(3) = j is reached; for j=yj = y the program jumps to I5I_5 and halts with x+yx + y in R1R_1.

Multiplication. The product is obtained by two nested loops. Register R3R_3 accumulates the result, R4R_4 counts the rounds of the outer loop and R5R_5 those of the inner loop.

I1I_1 J(4,2,9)J(4, 2, 9) if R4=yR_4 = y, go to the end
I2I_2 Z(5)Z(5)
I3I_3 J(5,1,7)J(5, 1, 7) if R5=xR_5 = x, leave the inner loop
I4I_4 S(3)S(3)
I5I_5 S(5)S(5)
I6I_6 J(1,1,3)J(1, 1, 3)
I7I_7 S(4)S(4)
I8I_8 J(1,1,1)J(1, 1, 1)
I9I_9 T(3,1)T(3, 1) R1←R3R_1 \leftarrow R_3
Proposition 4.4.#

The program above computes (x,y)↦x⋅y(x, y) \mapsto x \cdot y.

Proof of Proposition 4.4.

We prove by induction on j≤yj \leq y that the computation reaches the configuration (1,rj)(1, r_j) where rj(1)=xr_j(1) = x, rj(2)=yr_j(2) = y, rj(3)=jxr_j(3) = jx, rj(4)=jr_j(4) = j, and rj(n)=0r_j(n) = 0 for n>5n > 5. For j=0j = 0 this is the initial configuration. Suppose it holds for j<yj < y. Since rj(4)=j≠yr_j(4) = j \neq y, the jump I1I_1 is not taken, and I2I_2 sets R5R_5 to 00. Then, by an inner induction on ℓ≤x\ell \leq x, the configuration (3,r)(3, r) with R3=jx+ℓR_3 = jx + \ell and R5=ℓR_5 = \ell is reached; for ℓ=x\ell = x, the jump I3I_3 leads to I7I_7, which increments R4R_4, and I8I_8 returns to I1I_1 with R3=(j+1)xR_3 = (j+1)x and R4=j+1R_4 = j + 1. For j=yj = y, I1I_1 jumps to I9I_9, which copies xyxy into R1R_1, and the program halts.

Exercise 4.5 ★.#

Write a URM program computing x−˙1x \dotminus 1, where x−˙1=x−1x \dotminus 1 = x - 1 if x≥1x \geq 1 and 0−˙1=00 \dotminus 1 = 0. Prove that it is correct.

Hint

There is no decrement instruction. Maintain two counters kk and k+1k + 1 in R2R_2 and R3R_3.

Solution
I1I_1 J(1,2,8)J(1, 2, 8) if x=0x = 0, halt with output 00
I2I_2 S(3)S(3) R2=k=0R_2 = k = 0, R3=k+1=1R_3 = k + 1 = 1
I3I_3 J(1,3,7)J(1, 3, 7) if x=k+1x = k + 1, go to I7I_7
I4I_4 S(2)S(2)
I5I_5 S(3)S(3)
I6I_6 J(1,1,3)J(1, 1, 3)
I7I_7 T(2,1)T(2, 1) output kk

If x=0x = 0, the program halts at once with R1=0R_1 = 0. If x≥1x \geq 1, one shows by induction on k≤x−1k \leq x - 1 that the configuration (3,r)(3, r) with r(2)=kr(2) = k and r(3)=k+1r(3) = k + 1 is reached; for k=x−1k = x - 1 the jump is taken and x−1x - 1 is copied into R1R_1. Without I1I_1, the program would loop forever on input 00, since k+1≥1k + 1 \geq 1.

4.3 Combining programs

To build complex programs from simpler ones, we need to run one program after another, and to run a program on arguments stored in arbitrary registers. Two technical points must be handled: jumps that halt a program by jumping far beyond its end, and registers used as scratch space.

Definition 4.6.#

A program P=I1,…,IsP = I_1, \dots, I_s is in standard form if every jump J(m,n,q)J(m, n, q) of PP satisfies q≤s+1q \leq s + 1. We write ρ(P)\rho(P) for the largest register index mentioned in PP.

Every program PP is equivalent to a program in standard form, obtained by replacing every jump J(m,n,q)J(m, n, q) with q>s+1q > s + 1 by J(m,n,s+1)J(m, n, s + 1): the computations are the same, and when PP halts, the standard form program halts in the configuration (s+1,r)(s + 1, r) with the same registers.

Definition 4.7.#

Let P=I1,…,IsP = I_1, \dots, I_s and Q=I1′,…,It′Q = I'_1, \dots, I'_t be programs in standard form. The concatenation PQPQ is the program I1,…,Is,I1′′,…,It′′I_1, \dots, I_s, I''_1, \dots, I''_t where Ij′′I''_j is Ij′I'_j with every jump target qq replaced by q+sq + s.

Lemma 4.8.#

Let P,QP, Q be in standard form and rr a register state. If the computation of PP from (1,r)(1, r) does not halt, neither does that of PQPQ. If it halts with register state r′r', then the computation of PQPQ from (1,r)(1, r) continues as the computation of QQ from (1,r′)(1, r'), with instruction indices shifted by ss.

Proof of Lemma 4.8.

As long as the computation of PP is at an instruction i≤si \leq s, the computations of PP and PQPQ coincide, since the first ss instructions are the same. Because PP is in standard form, when PP halts it is at instruction s+1s + 1, which in PQPQ is the first instruction of the shifted copy of QQ. From there, a straightforward induction shows that a configuration (j,r′′)(j, r'') of QQ corresponds to the configuration (j+s,r′′)(j + s, r'') of PQPQ, since jump targets have been shifted accordingly.

To run a program on arguments located in arbitrary registers, and to place its result in a chosen register, we use the following notation. Let PP be a program in standard form computing a kk-ary function, and let ℓ1,…,ℓk,ℓ\ell_1, \dots, \ell_k, \ell be registers with indices greater than ρ(P)\rho(P) and kk. We write P[ℓ1,…,ℓk→ℓ]P[\ell_1, \dots, \ell_k \to \ell] for the program

Z(1),…,Z(ρ(P)), T(ℓ1,1),…,T(ℓk,k), P, T(1,ℓ),Z(1), \dots, Z(\rho(P)),\ T(\ell_1, 1), \dots, T(\ell_k, k),\ P,\ T(1, \ell),

put in standard form (the concatenations being taken as above). It clears the registers used by PP, copies the arguments into R1,…,RkR_1, \dots, R_k, runs PP, and copies the result into RℓR_\ell.

Lemma 4.9.#

Let PP compute f:Nk⇀Nf : \nat^k \rightharpoonup \nat. Started in any register state rr with r(ℓi)=xir(\ell_i) = x_i, the program P[ℓ1,…,ℓk→ℓ]P[\ell_1, \dots, \ell_k \to \ell] halts if and only if f(x⃗) ⁣ ⁣↓f(\vec x)\converge; in that case it halts with f(x⃗)f(\vec x) in RℓR_\ell, and with all registers RnR_n for n>max⁡(ρ(P),k)n > \max(\rho(P), k), n≠ℓn \neq \ell, unchanged.

Proof of Lemma 4.9.

Since the ℓi\ell_i are larger than ρ(P)\rho(P) and kk, the zeroing instructions do not affect them, and after the transfers the registers R1,…,Rmax⁡(ρ(P),k)R_1, \dots, R_{\max(\rho(P), k)} contain exactly the initial configuration of PP on input x⃗\vec x restricted to these registers. The registers beyond ρ(P)\rho(P) are never mentioned by PP: they do not influence the computation and are not modified by it. Therefore the computation of PP proceeds as from its initial configuration on x⃗\vec x. The conclusion follows from Lemma 4.8.

4.4 Closure under composition

Theorem 4.10.#

Let g1,…,gm:Nk⇀Ng_1, \dots, g_m : \nat^k \rightharpoonup \nat and h:Nm⇀Nh : \nat^m \rightharpoonup \nat be URM-computable. Then the partial function

f(x⃗)≃h(g1(x⃗),…,gm(x⃗))f(\vec x) \simeq h(g_1(\vec x), \dots, g_m(\vec x))

is URM-computable.

Proof of Theorem 4.10.

Let G1,…,Gm,HG_1, \dots, G_m, H be programs in standard form computing g1,…,gm,hg_1, \dots, g_m, h. Let NN be larger than kk, mm and the numbers ρ(Gi)\rho(G_i), ρ(H)\rho(H). We use the registers RN+1,…,RN+kR_{N+1}, \dots, R_{N+k} to save the input, and RN+k+1,…,RN+k+mR_{N+k+1}, \dots, R_{N+k+m} to store the values gi(x⃗)g_i(\vec x). Consider the program

T(1,N+1), …, T(k,N+k),G1[N+1,…,N+k→N+k+1], …, Gm[N+1,…,N+k→N+k+m],H[N+k+1,…,N+k+m→1].\begin{aligned} & T(1, N{+}1),\ \dots,\ T(k, N{+}k), \\ & G_1[N{+}1, \dots, N{+}k \to N{+}k{+}1],\ \dots,\ G_m[N{+}1, \dots, N{+}k \to N{+}k{+}m], \\ & H[N{+}k{+}1, \dots, N{+}k{+}m \to 1]. \end{aligned}

(The last block copies its result into R1R_1; the definition of P[⋯→ℓ]P[\dots \to \ell] is adapted in the obvious way when ℓ=1\ell = 1.) By Lemma 4.9 and Lemma 4.8, if all gi(x⃗)g_i(\vec x) converge, the program successively stores g1(x⃗),…,gm(x⃗)g_1(\vec x), \dots, g_m(\vec x) in RN+k+1,…,RN+k+mR_{N+k+1}, \dots, R_{N+k+m} — the saved input being left unchanged — and then runs HH on these values, halting with f(x⃗)f(\vec x) in R1R_1 if hh converges, and not halting otherwise. If some gi(x⃗)g_i(\vec x) diverges, the program does not halt, in accordance with the convention that f(x⃗) ⁣ ⁣↑f(\vec x)\diverge in that case.

4.5 Goto programs and assembly languages

The URM is a minimal example of a goto program: a numbered list of elementary instructions together with conditional jumps. Processors execute programs of this kind. Other common instruction sets, for instance with a decrement instruction Rn←Rn−˙1R_n \leftarrow R_n \dotminus 1 and a test “if Rn=0R_n = 0 go to qq”, lead to the same class of computable functions; this is a simple exercise in simulating one instruction set by another.

In the lesson LOOP and WHILE programs we consider structured programs, with for and while loops instead of jumps. They are more convenient to write, and the distinction between the two kinds of loops gives a characterization of the primitive recursive functions.

4.6 Exercises

Exercise 4.11 ★.

Write a URM program computing the function sg(x)\mathrm{sg}(x), equal to 00 if x=0x = 0 and to 11 otherwise.

Solution
I1I_1 J(1,2,4)J(1, 2, 4) if x=0x = 0, halt (output 00)
I2I_2 Z(1)Z(1)
I3I_3 S(1)S(1) output 11
Exercise 4.12 ★★.

Consider the variant of the URM without the transfer instruction T(m,n)T(m, n). Show that it computes the same functions.

Solution

For m≠nm \neq n, the instruction T(m,n)T(m, n) can be simulated with ZZ, SS and JJ using as a counter a register RcR_c with c>ρ(P)c > \rho(P), where PP is the program being transformed: Z(n)Z(n), Z(c)Z(c), then the loop “if Rc=RmR_c = R_m, exit; S(n)S(n); S(c)S(c); go back”, the backward jump being J(c,c,⋅)J(c, c, \cdot). The case m=nm = n is a no-op. Replacing each TT instruction by such a block, and shifting all jump targets accordingly, gives a program without TT whose computations follow those of PP on the registers R1,…,Rρ(P)R_1, \dots, R_{\rho(P)}. Since c>ρ(P)≥1c > \rho(P) \geq 1, the output register R1R_1 is never used as the counter, so both programs compute the same functions; the initial content of RcR_c, possibly an input, is irrelevant because RcR_c is zeroed before each use and is not mentioned by PP.

Exercise 4.13 ★★.

Prove that the URM-computable functions are closed under definition by cases: if f1,f2:Nk→Nf_1, f_2 : \nat^k \to \nat are total URM-computable functions and P⊆NkP \subseteq \nat^k is a set whose characteristic function is URM-computable, then f(x⃗)=f1(x⃗)f(\vec x) = f_1(\vec x) if x⃗∈P\vec x \in P and f(x⃗)=f2(x⃗)f(\vec x) = f_2(\vec x) otherwise is URM-computable.

Solution

Let CC compute the characteristic function of PP. Save the input in fresh registers, run CC on it with output in a fresh register RcR_c, and use J(c,z,⋅)J(c, z, \cdot), where RzR_z is a fresh register containing 00, to branch to a block computing f2f_2 on the saved input; otherwise continue with a block computing f1f_1 on the saved input, followed by an unconditional jump past the other block. Correctness follows from Lemma 4.9 and Lemma 4.8.

4.7 Notes and references

Register machines were introduced around 1960 in several variants, by Melzak, Lambek, Minsky, and Shepherdson and Sturgis. The URM and its notation follow Cutland’s textbook, which develops the whole of elementary computability theory on this model.

  • J. C. Shepherdson, H. E. Sturgis, Computability of recursive functions, Journal of the ACM 10 (1963), 217–255.
  • M. Minsky, Computation: Finite and Infinite Machines, Prentice-Hall, 1967.
  • N. Cutland, Computability: An Introduction to Recursive Function Theory, Cambridge University Press, 1980.