Alan Turing published a ground-breaking paper in 1936, On computable numbers, with an application to the Entscheidungsproblem (PDF). It was about an esoteric problem in mathematics, for which he needed a theoretical model of how a mathematician computes with pencil & paper. He called this model an automatic machine; we now call it a Turing Machine, which we now recognise as containing the minimal elements of computers. In a sense, he invented computers as a by-product of his mathematical research! That paper is also generally acknowledged to have founded the modern discipline of theoretical computer science.
The Turing Machine is very simple. It consists of:
Here’s a simple program to add 2 unary numbers (numbers in base 1, e.g. 5 = 11111).
|0||1, +1, 1||1, +1, 0|
|1||0, -1, 2||1, +1, 1|
|2||0, +1, 2||0, +1, 9|
The machine starts in state 0. If it reads a 1 from the tape, it gets the ‘instruction’ 1, +1, 0. The first element is the symbol to write back to the tape (replacing the current symbol). The 2nd is the direction to move the head: -1 = left, +1 = right. The 3rd is the new state. This is effectively a primitive programming language. You wouldn’t want to use this instead of Python! However, it is, in principle, as powerful as Python, in that it can compute anything that Python can!
The point of such a primitive language is that it allows us to reason clearly about the possibilities and limitations of computers. In his 1936 paper On Computable Numbers, Dr. Turing showed that there are programs which no other program can analyse and determine if they will ever halt!
This simple example implements the instruction table as a list of lists of tuples. The outermost list is states, the innermost is symbols ─ and the tuples are (symbol to write, direction to move tape head, next state)
The example above only solves one problem, namely adding 2 numbers in unary notation. The numbers themselves are provided on the ‘tape’ and so at least we can use the machine to solve an infinite number of additions. But the program is specific to this machine! Suppose I want the machine to compute something other adding unary numbers. All I need to do is change prog – so it must be universal! No. This is a simulation of an (imaginary) mechanical device, changing prog would effectively require repatching cables or whatever, which is a different machine. The Universal Turing Machine however is a fixed machine, which accepts the program of another TM on the tape – followed by any data. Changing prog is tantamount to using the underlying compiler or interpreter (plus hardware) as the UTM.
A Turing machine is an abstract machine that manipulates symbols on a strip of tape according to a table of rules; to be more exact, it is a mathematical model of computation that defines such a device. Despite the model's simplicity, given any computer algorithm, a Turing machine can be constructed that is capable of simulating that algorithm's logic.
The machine operates on an infinite memory tape divided into discrete cells. The machine positions its head over a cell and "reads" (scans) the symbol there. Then, as per the symbol and its present place in a finite table of user-specified instructions, the machine (i) writes a symbol (e.g. a digit or a letter from a finite alphabet) in the cell (some models allowing symbol erasure or no writing), then (ii) either moves the tape one cell left or right (some models allow no motion, some models move the head), then (iii) (as determined by the observed symbol and the machine's place in the table) either proceeds to a subsequent instruction or halts the computation.
The Turing machine was invented in 1936 by Alan Turing, who called it an a-machine (automatic machine). With this model, Turing was able to answer two questions in the negative: (1) Does a machine exist that can determine whether any arbitrary machine on its tape is "circular" (e.g. freezes, or fails to continue its computational task); similarly, (2) does a machine exist that can determine whether any arbitrary machine on its tape ever prints a given symbol. Thus by providing a mathematical description of a very simple device capable of arbitrary computations, he was able to prove properties of computation in general—and in particular, the uncomputability of the Entscheidungsproblem ("decision problem").
Thus, Turing machines prove fundamental limitations on the power of mechanical computation. While they can express arbitrary computations, their minimalistic design makes them unsuitable for computation in practice: real-world computers are based on different designs that, unlike Turing machines, use random-access memory.
Turing completeness is the ability for a system of instructions to simulate a Turing machine. A programming language that is Turing complete is theoretically capable of expressing all tasks accomplishable by computers; nearly all programming languages are Turing complete if the limitations of finite memory are ignored.