misc: add simple turing machine from DAS.

This commit is contained in:
Kyle Isom 2018-04-07 13:36:30 -07:00
parent b6e24b44ad
commit af2db4ac8c
2 changed files with 115 additions and 0 deletions

View File

@ -0,0 +1,79 @@
h1{Turing machines}
h2{Introduction}
One of the motivators is exploring the limits of computation via the halting
problem:
halt :: function bool
The question is: does `function` always return? This is an undecidable problem.
The Chomsky hierarchy:
1. Regular expressions
2. Simple programming languages
3. Complex programming languages
4. Turing equivalence
h2{Computing by changing}
Imperative model of computation: order of instructions matters, and generally
destructive operations.
Turing machine:
* infinite tape composed of cells, initialisation is the blank symbol ('B')
* head pointing to a cell on the tape
* instructions: head movement, read, write
Example machine: X_B
two-cell tape:
```
BB
^
```
rewrite first cell with X->B repeatedly: when we see a B, write an X. When we see an X, write a B.
head has to move on every single instruction, only one step
we'll move to the right
cell 2: read B, see B, move left
ex:
BB
^
XB
^
XB
^
BB
^
Turing machines aren't imperatively organised; it uses a state table.
state symbols:
s_1...s_4
(symbol, state) -> write, head move, next state
B, s1 -> X, R, s2
B, s2 -> B, L, s3
X, s3 -> B, R, s4
B, s4 -> B, L, s1
a state table and four-line turing machine:
X_B = {
('B', 's1'): ('X', 'R', 's2'),
('B', 's2'): ('B', 'L', 's3'),
('X', 's3'): ('B', 'R', 's4'),
('B', 's4'): ('B', 'L', 's1')
}
def simulate(instructions):
tape, head, state = ['B', 'B'], 0, 's1'
for _ in range(8):
(tape[head], head_dir, state) = instructions[(tape[head], state)]
head += 1 if head_dir == 'R' else -1
simulate(X_B)

36
misc/turing-machine/turing.py Executable file
View File

@ -0,0 +1,36 @@
#!/usr/bin/env python3
X_B = {
('B', 's1'): ('X', 'R', 's2'),
('B', 's2'): ('B', 'L', 's3'),
('X', 's3'): ('B', 'R', 's4'),
('B', 's4'): ('B', 'L', 's1')
}
def simulate(instructions):
# set up initial state
# note that tape is hard-coded for now, but should be a data structure that
# can grow in either direction and the state shouldn't be hard-coded. This
# works for the initial pass at this.
tape, head, state = ['B', 'B'], 0, 's1'
# loop: this should be an infinite loop (with a possible halting state in the state table)
for _ in range(8):
print(state + ': ' + ''.join(tape))
print(' ' + ' ' * head + '^')
# look up instruction
(tape[head], head_dir, state) = instructions[(tape[head], state)]
# apply instruction
head += 1 if head_dir == 'R' else -1
# sanity checks
assert(head_dir in ['R', 'L'])
assert(head >= 0)
assert(head < len(tape))
# four lines of actual code that can simulate any CPU
simulate(X_B)