A finite set of registers, A, B, C, ..., each of which contains a natural number.

A list of numbered instructions.



Increment: increment takes two parameters: a register, and an instruction number. It increments the value stored in the specified register, and then jumps to the instruction at the number.

Decrement: decrement takes three parameters: a register, and two instruction numbers. If the value in the register is 0, it jumps to the instruction at the first number; if the value in the register is greater than zero, it decrements it, and jumps to the instruction at the second number.

Halt.



1: Decrement(B, 4, 2)

2: Decrement(A, 3, 1)

3: Incr(B,4)

4: Halt



I've said before that all computing systems are ultimately equivalent. This is something known as the Church-Turing thesis. It's interesting to look at one or two machines other than the Turing machine, just to get some idea of why we believe that, and what other computers might look like.There's a really fun computing machine designed by Marvin Minsky, an incredibly smart and prolific computer scientist. He just called them "program machines" when he first proposed them; most of us call them "Minsky Machines". I really like Minsky machines; I find their programs much easier to read and write than Turing machine programs, and their behavior is closer to real computers.The minsky machine is astoundingly simple: even simpler than the turing machine. A minsky machine consists of:There are only three instructions in a minsky machine:You start with the instruction at position 0, and keep going until you hit a Halt.Here's a subtraction program for a minsky machine with two registers. It takes two numbers in registers A and B, and leaves the result in A. If it halts with anything but 0 in B, then it's an error.First, it decrements the value in register B; if B is zero, then the subtraction is done, so it jumps to halt. If B is greater than 0, then it subtracts one from B, and then tries to subtract one from A. If A is already zero, then it adds one to B (to be sure that B != 0) and halts. If A isn't zero, then it decrements it, and goes back to the beginning.Now, here's a question: is this really equivalent to a turing machine? Intuitively, you can problably get a sense that this is a complete effective computing system. But how do we prove it?Well, we know that a two-stack push-down automaton is completely equivalent to a turing machine: the two stacks can simulate the parts of the tape on either side of the head. And we know that if something can be done with a turing machine, it can be done with a binary (two symbol) turing machine. So - we need to show that we can simulate a two-stack binary push-down automaton using a minsky machine. A pushdown automaton is really just a FSM with two stacks.Since we already showed we can implement fully general natural number subtraction with a Minsky machine, we know that we can implement an FSM: subtraction is strictly harder than anything an FSM can do - so if our machine can implement a general subtraction, it can implement an FSM. So what we need to do is show that we can implement the stacks.And that's easy. Here's how you implement a stack with two registers: one register holds a binary number. That binary number is the stack. To push a value on the stack, you multiply by two, and add the value. To pop the value on top of the stack, you take divide by two; the result of the division is the popped stack, and the remainder is the value that was on top. So you've got the stack data in one register. You need a second register to use to implement the multiplications and divisions.So, if you've got four registers, then you've got two stacks. Poof. You've got a turing machine.Going the other direction, it should be pretty easy to see how to implement a Minsky machine with a turing machine. To make things easy, we can use a multi-tape turing machine (since we know that that's no more powerful than a one-tape). Each register is one tape, containing its value in unary; and one tape contains the program.