Time for an 2014 update…
This commit is contained in:
parent
372c577f83
commit
09687c4926
2520 changed files with 34227 additions and 7318 deletions
|
|
@ -33,3 +33,27 @@ The input for this machine should be a tape of <code>1 1 1</code>
|
|||
** (c, 1, 1, stay, halt)
|
||||
|
||||
The input for this machine should be an empty tape.
|
||||
|
||||
'''Bonus:'''
|
||||
|
||||
'''5-state, 2-symbol probable Busy Beaver machine from Wikipedia'''
|
||||
* '''States:''' A, B, C, D, E, H
|
||||
* '''Initial state:''' A
|
||||
* '''Terminating states:''' H
|
||||
* '''Permissible symbols:''' 0, 1
|
||||
* '''Blank symbol:''' 0
|
||||
* '''Rules:'''
|
||||
** (A, 0, 1, right, B)
|
||||
** (A, 1, 1, left, C)
|
||||
** (B, 0, 1, right, C)
|
||||
** (B, 1, 1, right, B)
|
||||
** (C, 0, 1, right, D)
|
||||
** (C, 1, 0, left, E)
|
||||
** (D, 0, 1, left, A)
|
||||
** (D, 1, 1, left, D)
|
||||
** (E, 0, 1, stay, H)
|
||||
** (E, 1, 0, left, A)
|
||||
|
||||
The input for this machine should be an empty tape.
|
||||
|
||||
This machine runs for more than 47 millions steps.
|
||||
|
|
|
|||
243
Task/Universal-Turing-machine/D/universal-turing-machine-1.d
Normal file
243
Task/Universal-Turing-machine/D/universal-turing-machine-1.d
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
import std.stdio, std.algorithm, std.string, std.conv, std.array,
|
||||
std.exception, std.traits, std.math, std.range;
|
||||
|
||||
struct UTM(State, Symbol, bool doShow=true)
|
||||
if (is(State == enum) && is(Symbol == enum)) {
|
||||
static assert(is(typeof({ size_t x = State.init; })),
|
||||
"State must to be usable as array index.");
|
||||
static assert([EnumMembers!State]
|
||||
.equal(EnumMembers!State.length.iota),
|
||||
"State must be a plain enum.");
|
||||
static assert(is(typeof({ size_t x = Symbol.init; })),
|
||||
"Symbol must to be usable as array index.");
|
||||
static assert([EnumMembers!Symbol]
|
||||
.equal(EnumMembers!Symbol.length.iota),
|
||||
"Symbol must be a plain enum.");
|
||||
|
||||
enum Direction { right, left, stay }
|
||||
|
||||
private const TuringMachine tm;
|
||||
private TapeHead head;
|
||||
alias SymbolMap = string[EnumMembers!Symbol.length];
|
||||
|
||||
// The first index of this 'rules' matrix is a subtype of State
|
||||
// because it can't contain H, but currently D can't enforce this,
|
||||
// statically unlike Ada language.
|
||||
Rule[EnumMembers!Symbol.length]
|
||||
[EnumMembers!State.length - 1] mRules;
|
||||
|
||||
static struct Rule {
|
||||
Symbol toWrite;
|
||||
Direction direction;
|
||||
State nextState;
|
||||
|
||||
this(in Symbol toWrite_, in Direction direction_,
|
||||
in State nextState_) pure nothrow {
|
||||
this.toWrite = toWrite_;
|
||||
this.direction = direction_;
|
||||
this.nextState = nextState_;
|
||||
}
|
||||
}
|
||||
|
||||
// This is kept separated from the rest so it can be inialized
|
||||
// one field at a time in the main function, yet it will become
|
||||
// const.
|
||||
static struct TuringMachine {
|
||||
Symbol blank;
|
||||
State initialState;
|
||||
Rule[Symbol][State] rules;
|
||||
Symbol[] input;
|
||||
SymbolMap symbolMap;
|
||||
}
|
||||
|
||||
static struct TapeHead {
|
||||
immutable Symbol blank;
|
||||
Symbol[] tapeLeft, tapeRight;
|
||||
int position;
|
||||
const SymbolMap sMap;
|
||||
size_t nSteps;
|
||||
|
||||
this(in ref TuringMachine t) pure /*nothrow*/ {
|
||||
this.blank = EnumMembers!Symbol[0];
|
||||
//tapeRight = t.input.empty ? [this.blank] : t.input.dup;
|
||||
if (t.input.empty)
|
||||
this.tapeRight = [this.blank];
|
||||
else
|
||||
this.tapeRight = t.input.dup; // Not nothrow.
|
||||
this.position = 0;
|
||||
this.sMap = t.symbolMap;
|
||||
}
|
||||
|
||||
pure nothrow invariant() {
|
||||
assert(this.tapeRight.length > 0);
|
||||
if (this.position >= 0)
|
||||
assert(this.position < this.tapeRight.length);
|
||||
else
|
||||
assert(this.position.abs <= this.tapeLeft.length);
|
||||
}
|
||||
|
||||
Symbol readSymb() const pure nothrow {
|
||||
if (this.position >= 0)
|
||||
return this.tapeRight[this.position];
|
||||
else
|
||||
return this.tapeLeft[this.position.abs - 1];
|
||||
}
|
||||
|
||||
void showSymb() const {
|
||||
this.write;
|
||||
}
|
||||
|
||||
void writeSymb(in Symbol symbol) {
|
||||
static if (doShow)
|
||||
showSymb;
|
||||
if (this.position >= 0)
|
||||
this.tapeRight[this.position] = symbol;
|
||||
else
|
||||
this.tapeLeft[this.position.abs - 1] = symbol;
|
||||
}
|
||||
|
||||
void goRight() pure nothrow {
|
||||
this.position++;
|
||||
if (position > 0 && position == tapeRight.length)
|
||||
tapeRight ~= blank;
|
||||
}
|
||||
|
||||
void goLeft() pure nothrow {
|
||||
this.position--;
|
||||
if (position < 0 && (position.abs - 1) == tapeLeft.length)
|
||||
tapeLeft ~= blank;
|
||||
}
|
||||
|
||||
void move(in Direction dir) pure nothrow {
|
||||
nSteps++;
|
||||
final switch (dir) with (Direction) {
|
||||
case left: goLeft; break;
|
||||
case right: goRight; break;
|
||||
case stay: /*Do nothing*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
string toString() const {
|
||||
const pos = cast(int)tapeLeft.length + this.position + 4;
|
||||
return format("...%-(%)...", tapeLeft.retro
|
||||
.chain(tapeRight)
|
||||
.map!(s => sMap[s])) ~
|
||||
'\n' ~
|
||||
format("%" ~ pos.text ~ "s", "^") ~
|
||||
'\n';
|
||||
}
|
||||
}
|
||||
|
||||
void show() const {
|
||||
head.showSymb;
|
||||
}
|
||||
|
||||
this(in ref TuringMachine tm_) {
|
||||
static assert(__traits(compiles, State.H),
|
||||
"State needs a 'H' (Halt).");
|
||||
immutable errMsg = "Invalid input.";
|
||||
auto runningStates = remove!(s => s == State.H)
|
||||
([EnumMembers!State]);
|
||||
enforce(!runningStates.empty, errMsg);
|
||||
enforce(tm_.rules.length == EnumMembers!State.length - 1,
|
||||
errMsg);
|
||||
enforce(State.H !in tm_.rules, errMsg);
|
||||
enforce(runningStates.canFind(tm_.initialState), errMsg);
|
||||
|
||||
// Create a matrix to reduce running time.
|
||||
foreach (const State st, const rset; tm_.rules)
|
||||
foreach (const Symbol sy, const rule; rset)
|
||||
mRules[st][sy] = rule;
|
||||
|
||||
this.tm = tm_;
|
||||
head = TapeHead(this.tm);
|
||||
|
||||
State state = tm.initialState;
|
||||
while (state != State.H) {
|
||||
immutable next = mRules[state][head.readSymb];
|
||||
head.writeSymb(next.toWrite);
|
||||
head.move(next.direction);
|
||||
state = next.nextState;
|
||||
}
|
||||
static if (doShow)
|
||||
show;
|
||||
writeln("Performed ", head.nSteps, " steps.");
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
"Incrementer:".writeln;
|
||||
enum States1 : ubyte { A, H }
|
||||
enum Symbols1 : ubyte { s0, s1 }
|
||||
alias M1 = UTM!(States1, Symbols1);
|
||||
M1.TuringMachine tm1;
|
||||
with (tm1) with (States1) with (Symbols1) with (M1.Direction) {
|
||||
alias R = M1.Rule;
|
||||
initialState = A;
|
||||
rules = [A: [s0: R(s1, stay, H), s1: R(s1, right, A)]];
|
||||
input = [s1, s1, s1];
|
||||
symbolMap = ["0", "1"];
|
||||
}
|
||||
M1(tm1);
|
||||
|
||||
// http://en.wikipedia.org/wiki/Busy_beaver
|
||||
"\nBusy Beaver machine (3-state, 2-symbol):".writeln;
|
||||
enum States2 : ubyte { A, B, C, H }
|
||||
alias Symbols2 = Symbols1;
|
||||
alias M2 = UTM!(States2, Symbols2);
|
||||
M2.TuringMachine tm2;
|
||||
with (tm2) with (States2) with (Symbols2) with (M2.Direction) {
|
||||
alias R = M2.Rule;
|
||||
initialState = A;
|
||||
rules = [A: [s0: R(s1, right, B), s1: R(s1, left, C)],
|
||||
B: [s0: R(s1, left, A), s1: R(s1, right, B)],
|
||||
C: [s0: R(s1, left, B), s1: R(s1, stay, H)]];
|
||||
symbolMap = ["0", "1"];
|
||||
}
|
||||
M2(tm2);
|
||||
|
||||
"\nSorting stress test (12212212121212):".writeln;
|
||||
enum States3 : ubyte { A, B, C, D, E, H }
|
||||
enum Symbols3 : ubyte { s0, s1, s2, s3 }
|
||||
alias M3 = UTM!(States3, Symbols3, false);
|
||||
M3.TuringMachine tm3;
|
||||
with (tm3) with (States3) with (Symbols3) with (M3.Direction) {
|
||||
alias R = M3.Rule;
|
||||
initialState = A;
|
||||
rules = [A: [s1: R(s1, right, A),
|
||||
s2: R(s3, right, B),
|
||||
s0: R(s0, left, E)],
|
||||
B: [s1: R(s1, right, B),
|
||||
s2: R(s2, right, B),
|
||||
s0: R(s0, left, C)],
|
||||
C: [s1: R(s2, left, D),
|
||||
s2: R(s2, left, C),
|
||||
s3: R(s2, left, E)],
|
||||
D: [s1: R(s1, left, D),
|
||||
s2: R(s2, left, D),
|
||||
s3: R(s1, right, A)],
|
||||
E: [s1: R(s1, left, E),
|
||||
s0: R(s0, stay, H)]];
|
||||
input = [s1, s2, s2, s1, s2, s2, s1,
|
||||
s2, s1, s2, s1, s2, s1, s2];
|
||||
symbolMap = ["0", "1", "2", "3"];
|
||||
}
|
||||
M3(tm3).show;
|
||||
|
||||
"\nPossible best Busy Beaver machine (5-state, 2-symbol):".writeln;
|
||||
alias States4 = States3;
|
||||
alias Symbols4 = Symbols1;
|
||||
alias M4 = UTM!(States4, Symbols4, false);
|
||||
M4.TuringMachine tm4;
|
||||
with (tm4) with (States4) with (Symbols4) with (M4.Direction) {
|
||||
alias R = M4.Rule;
|
||||
initialState = A;
|
||||
rules = [A: [s0: R(s1, right, B), s1: R(s1, left, C)],
|
||||
B: [s0: R(s1, right, C), s1: R(s1, right, B)],
|
||||
C: [s0: R(s1, right, D), s1: R(s0, left, E)],
|
||||
D: [s0: R(s1, left, A), s1: R(s1, left, D)],
|
||||
E: [s0: R(s1, stay, H), s1: R(s0, left, A)]];
|
||||
symbolMap = ["0", "1"];
|
||||
}
|
||||
M4(tm4);
|
||||
}
|
||||
52
Task/Universal-Turing-machine/D/universal-turing-machine-2.d
Normal file
52
Task/Universal-Turing-machine/D/universal-turing-machine-2.d
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import std.stdio, std.typecons, std.array, std.algorithm, std.string;
|
||||
|
||||
void turing(Sy, St)(in Sy[] symbols, in Sy blank, in St initialState,
|
||||
in St[] haltStates, in St[] runningStates,
|
||||
in Tuple!(Sy, string, St)[Sy][St] rules,
|
||||
in Sy[] startingTape = []) {
|
||||
Sy[int] tape;
|
||||
foreach (i, sy; startingTape)
|
||||
tape[i] = sy;
|
||||
int pos = 0;
|
||||
St state = initialState;
|
||||
|
||||
while (!haltStates.canFind(state)) {
|
||||
//auto symbol = tape.setDefault(pos, blank);
|
||||
if (pos !in tape)
|
||||
tape[pos] = blank;
|
||||
auto symbol = tape[pos];
|
||||
tape.keys.sort()
|
||||
.map!(i => format(["%s", "(%s)"][i == pos], tape[i]))
|
||||
.join(" ").writeln;
|
||||
//{const outsym, const action, state} = rules[state][symbol];
|
||||
const r = rules[state][symbol];
|
||||
state = r[2];
|
||||
tape[pos] = r[0];
|
||||
pos += ["left": -1, "stay": 0, "right": 1][r[1]];
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
alias t = tuple;
|
||||
|
||||
turing(['b', '1'], // Permitted symbols.
|
||||
'b', // Blank symbol.
|
||||
"q0", // Starting state.
|
||||
["qf"], // Terminating states.
|
||||
["q0"], // Running states.
|
||||
// Operating rules.
|
||||
["q0": ['1': t('1', "right", "q0"),
|
||||
'b': t('1', "stay", "qf")]],
|
||||
['1', '1', '1']); // Starting tape.
|
||||
writeln;
|
||||
|
||||
turing([0, 1], // Permitted symbols.
|
||||
0, // Blank symbol.
|
||||
"a", // Starting state.
|
||||
["halt"], // Terminating states.
|
||||
["a", "b", "c"], // Running states.
|
||||
// Operating rules.
|
||||
["a": [0: t(1, "right", "b"), 1: t(1, "left", "c")],
|
||||
"b": [0: t(1, "left", "a"), 1: t(1, "right", "b")],
|
||||
"c": [0: t(1, "left", "b"), 1: t(1, "stay", "halt")]]);
|
||||
}
|
||||
|
|
@ -1,190 +0,0 @@
|
|||
import std.stdio, std.algorithm, std.string, std.conv, std.array,
|
||||
std.exception;
|
||||
|
||||
struct UTM(bool doShow=true) {
|
||||
alias Symbol = uint;
|
||||
alias State = char; // Typedef?
|
||||
enum Direction { right, left, stay }
|
||||
|
||||
private TapeHead head;
|
||||
private const TuringMachine tm;
|
||||
|
||||
static struct Rule {
|
||||
Symbol toWrite;
|
||||
Direction direction;
|
||||
State nextState;
|
||||
}
|
||||
|
||||
static struct TuringMachine {
|
||||
Symbol[] symbols;
|
||||
Symbol blank;
|
||||
State initialState;
|
||||
State[] haltStates, runningStates;
|
||||
Rule[Symbol][State] rules;
|
||||
Symbol[] input;
|
||||
}
|
||||
|
||||
static struct TapeHead {
|
||||
immutable Symbol blank;
|
||||
Symbol[] tape;
|
||||
size_t position;
|
||||
|
||||
this(in ref TuringMachine t) pure /*nothrow*/ {
|
||||
this.blank = t.blank;
|
||||
this.tape = t.input.dup; // Not nothrow.
|
||||
if (this.tape.empty)
|
||||
this.tape = [this.blank];
|
||||
this.position = 0;
|
||||
}
|
||||
|
||||
pure nothrow invariant() {
|
||||
assert(this.position < this.tape.length);
|
||||
}
|
||||
|
||||
Symbol read() const pure nothrow {
|
||||
return this.tape[this.position];
|
||||
}
|
||||
|
||||
void show() const {
|
||||
.write(this);
|
||||
}
|
||||
|
||||
void write(in Symbol symbol) {
|
||||
static if (doShow)
|
||||
show();
|
||||
this.tape[this.position] = symbol;
|
||||
}
|
||||
|
||||
void right() pure nothrow {
|
||||
this.position++;
|
||||
if (this.position == this.tape.length)
|
||||
this.tape ~= this.blank;
|
||||
}
|
||||
|
||||
void left() pure nothrow {
|
||||
if (this.position == 0)
|
||||
this.tape = this.blank ~ this.tape;
|
||||
else
|
||||
this.position--;
|
||||
}
|
||||
|
||||
void move(in Direction dir) {
|
||||
final switch (dir) {
|
||||
case Direction.left: left(); break;
|
||||
case Direction.right: right(); break;
|
||||
case Direction.stay: /*Do nothing.*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
string toString() const {
|
||||
return format("...%(%)...", this.tape)
|
||||
~ '\n'
|
||||
~ format("%" ~ text(this.position + 4) ~ "s", "^")
|
||||
~ '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void show() const {
|
||||
head.show();
|
||||
}
|
||||
|
||||
this(const ref TuringMachine tm_) {
|
||||
immutable errMsg = "Invalid input.";
|
||||
enforce(!tm_.runningStates.empty, errMsg);
|
||||
enforce(!tm_.haltStates.empty, errMsg);
|
||||
enforce(!tm_.symbols.empty, errMsg);
|
||||
enforce(tm_.rules.length, errMsg);
|
||||
enforce(tm_.runningStates.canFind(tm_.initialState), errMsg);
|
||||
enforce(tm_.symbols.canFind(tm_.blank), errMsg);
|
||||
const allStates = tm_.runningStates ~ tm_.haltStates;
|
||||
foreach (const s; tm_.rules.keys.to!(dchar[])().sort())
|
||||
enforce(tm_.runningStates.canFind(s), errMsg);
|
||||
foreach (const aa; tm_.rules.byValue)
|
||||
foreach (/*const*/ s, const rule; aa) {
|
||||
enforce(tm_.symbols.canFind(s), errMsg);
|
||||
enforce(tm_.symbols.canFind(rule.toWrite), errMsg);
|
||||
enforce(allStates.canFind(rule.nextState), errMsg);
|
||||
}
|
||||
|
||||
this.tm = tm_;
|
||||
this.head = TapeHead(this.tm);
|
||||
|
||||
State state = this.tm.initialState;
|
||||
while (true) {
|
||||
if (tm.haltStates.canFind(state))
|
||||
break;
|
||||
if (!tm.runningStates.canFind(state))
|
||||
throw new Exception("Unknown state.");
|
||||
immutable symbol = this.head.read();
|
||||
immutable rule = this.tm.rules[state][symbol];
|
||||
this.head.write(rule.toWrite);
|
||||
this.head.move(rule.direction);
|
||||
state = rule.nextState;
|
||||
}
|
||||
static if (doShow)
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
with (UTM!()) {
|
||||
alias R = Rule;
|
||||
writeln("Incrementer:");
|
||||
TuringMachine tm1;
|
||||
tm1.symbols = [0, 1];
|
||||
tm1.blank = 0;
|
||||
tm1.initialState = 'A';
|
||||
tm1.haltStates = ['H'];
|
||||
tm1.runningStates = ['A'];
|
||||
with (Direction)
|
||||
tm1.rules = ['A': [0: R(1, left, 'H'),
|
||||
1: R(1, right, 'A')]];
|
||||
tm1.input = [1, 1, 1];
|
||||
UTM!()(tm1);
|
||||
|
||||
// http://en.wikipedia.org/wiki/Busy_beaver
|
||||
writeln("\nBusy beaver machine (3-state, 2-symbol):");
|
||||
TuringMachine tm2;
|
||||
tm2.symbols = [0, 1];
|
||||
tm2.blank = 0;
|
||||
tm2.initialState = 'A';
|
||||
tm2.haltStates = ['H'];
|
||||
tm2.runningStates = ['A', 'B', 'C'];
|
||||
with (Direction)
|
||||
tm2.rules = ['A': [0: R(1, right, 'B'),
|
||||
1: R(1, left, 'C')],
|
||||
'B': [0: R(1, left, 'A'),
|
||||
1: R(1, right, 'B')],
|
||||
'C': [0: R(1, left, 'B'),
|
||||
1: R(1, stay, 'H')]];
|
||||
UTM!()(tm2);
|
||||
}
|
||||
|
||||
with (UTM!false) {
|
||||
writeln("\nSorting stress test (12212212121212):");
|
||||
alias R = Rule;
|
||||
TuringMachine tm3;
|
||||
tm3.symbols = [0, 1, 2, 3];
|
||||
tm3.blank = 0;
|
||||
tm3.initialState = 'A';
|
||||
tm3.haltStates = ['H'];
|
||||
tm3.runningStates = ['A', 'B', 'C', 'D', 'E'];
|
||||
with (Direction)
|
||||
tm3.rules = ['A': [1: R(1, right, 'A'),
|
||||
2: R(3, right, 'B'),
|
||||
0: R(0, left, 'E')],
|
||||
'B': [1: R(1, right, 'B'),
|
||||
2: R(2, right, 'B'),
|
||||
0: R(0, left, 'C')],
|
||||
'C': [1: R(2, left, 'D'),
|
||||
2: R(2, left, 'C'),
|
||||
3: R(2, left, 'E')],
|
||||
'D': [1: R(1, left, 'D'),
|
||||
2: R(2, left, 'D'),
|
||||
3: R(1, right, 'A')],
|
||||
'E': [1: R(1, left, 'E'),
|
||||
0: R(0, right, 'H')]];
|
||||
tm3.input = [1, 2, 2, 1, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2];
|
||||
UTM!false(tm3).show();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
transitions(:
|
||||
local :t {}
|
||||
while /= ) dup:
|
||||
set-to t swap & rot & rot rot &
|
||||
t drop
|
||||
|
||||
take-from tape:
|
||||
if tape:
|
||||
pop-from tape
|
||||
else:
|
||||
:B
|
||||
|
||||
paste-together a h b:
|
||||
push-to b h
|
||||
while a:
|
||||
push-to b pop-from a
|
||||
b
|
||||
|
||||
universal-turing-machine transitions initial final tape:
|
||||
local :tape-left []
|
||||
local :state initial
|
||||
|
||||
local :head take-from tape
|
||||
|
||||
local :move { :stay @pass }
|
||||
|
||||
move!left:
|
||||
push-to tape head
|
||||
set :head take-from tape-left
|
||||
|
||||
move!right:
|
||||
push-to tape-left head
|
||||
set :head take-from tape
|
||||
|
||||
while /= state final:
|
||||
if opt-get transitions & state head:
|
||||
set :state &<>
|
||||
set :head &<>
|
||||
move!
|
||||
else:
|
||||
return paste-together tape-left head tape
|
||||
paste-together tape-left head tape
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
:q0 :qf [ 1 1 1 ]
|
||||
)
|
||||
:q0 1 1 :right :q0
|
||||
:q0 :B 1 :stay :qf
|
||||
!. universal-turing-machine transitions(
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
:a :halt []
|
||||
)
|
||||
:a :B 1 :right :b
|
||||
:a 1 1 :left :c
|
||||
:b :B 1 :left :a
|
||||
:b 1 1 :right :b
|
||||
:c :B 1 :left :b
|
||||
:c 1 1 :stay :halt
|
||||
!. universal-turing-machine transitions(
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
:A :H []
|
||||
)
|
||||
:A :B 1 :right :B
|
||||
:A 1 1 :left :C
|
||||
:B :B 1 :right :C
|
||||
:B 1 1 :right :B
|
||||
:C :B 1 :right :D
|
||||
:C 1 :B :left :E
|
||||
:D :B 1 :left :A
|
||||
:D 1 1 :left :D
|
||||
:E :B 1 :stay :H
|
||||
:E 1 :B :left :A
|
||||
!. universal-turing-machine transitions(
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
-- Some elementary types for Turing Machine
|
||||
data Move = MLeft | MRight | Stay deriving (Show, Eq)
|
||||
data Tape a = Tape a [a] [a]
|
||||
data Action state val = Action val Move state deriving (Show)
|
||||
|
||||
instance (Show a) => Show (Tape a) where
|
||||
show (Tape x lts rts) = concat $ left ++ [hd] ++ right
|
||||
where hd = "[" ++ show x ++ "]"
|
||||
left = map show $ reverse $ take 10 lts
|
||||
right = map show $ take 10 rts
|
||||
|
||||
-- new tape
|
||||
tape blank lts rts | null rts = Tape blank left blanks
|
||||
| otherwise = Tape (head rts) left right
|
||||
where blanks = repeat blank
|
||||
left = reverse lts ++ blanks
|
||||
right = tail rts ++ blanks
|
||||
|
||||
-- Turing Machine
|
||||
step rules (state, Tape x (lh:lts) (rh:rts)) = (state', tape')
|
||||
where Action x' dir state' = rules state x
|
||||
tape' = move dir
|
||||
move Stay = Tape x' (lh:lts) (rh:rts)
|
||||
move MLeft = Tape lh lts (x':rh:rts)
|
||||
move MRight = Tape rh (x':lh:lts) rts
|
||||
|
||||
runUTM rules stop start tape = steps ++ [final]
|
||||
where (steps, final:_) = break ((== stop) . fst) $ iterate (step rules) (start, tape)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
incr "q0" 1 = Action 1 MRight "q0"
|
||||
incr "q0" 0 = Action 1 Stay "qf"
|
||||
|
||||
tape1 = tape 0 [] [1,1, 1]
|
||||
machine1 = runUTM incr "qf" "q0" tape1
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
*Main> mapM_ print machine1
|
||||
("q0",0000000000[1]1100000000)
|
||||
("q0",0000000001[1]1000000000)
|
||||
("q0",0000000011[1]0000000000)
|
||||
("q0",0000000111[0]0000000000)
|
||||
("qf",0000000111[1]0000000000)
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
beaver "a" 0 = Action 1 MRight "b"
|
||||
beaver "a" 1 = Action 1 MLeft "c"
|
||||
beaver "b" 0 = Action 1 MLeft "a"
|
||||
beaver "b" 1 = Action 1 MRight "b"
|
||||
beaver "c" 0 = Action 1 MLeft "b"
|
||||
beaver "c" 1 = Action 1 Stay "halt"
|
||||
|
||||
tape2 = tape 0 [] []
|
||||
machine2 = runUTM beaver "halt" "a" tape2
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
sorting "A" 1 = Action 1 MRight "A"
|
||||
sorting "A" 2 = Action 3 MRight "B"
|
||||
sorting "A" 0 = Action 0 MLeft "E"
|
||||
sorting "B" 1 = Action 1 MRight "B"
|
||||
sorting "B" 2 = Action 2 MRight "B"
|
||||
sorting "B" 0 = Action 0 MLeft "C"
|
||||
sorting "C" 1 = Action 2 MLeft "D"
|
||||
sorting "C" 2 = Action 2 MLeft "C"
|
||||
sorting "C" 3 = Action 2 MLeft "E"
|
||||
sorting "D" 1 = Action 1 MLeft "D"
|
||||
sorting "D" 2 = Action 2 MLeft "D"
|
||||
sorting "D" 3 = Action 1 MRight "A"
|
||||
sorting "E" 1 = Action 1 MLeft "E"
|
||||
sorting "E" 0 = Action 0 MRight "STOP"
|
||||
|
||||
tape3 = tape 0 [] [2,2,2,1,2,2,1,2,1,2,1,2,1,2]
|
||||
machine3 = runUTM sorting "STOP" "A" tape3
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
from __future__ import print_function
|
||||
|
||||
def run_utm(
|
||||
state = None,
|
||||
blank = None,
|
||||
rules = [],
|
||||
tape = [],
|
||||
halt = None,
|
||||
pos = 0):
|
||||
st = state
|
||||
if not tape: tape = [blank]
|
||||
if pos < 0: pos += len(tape)
|
||||
if pos >= len(tape) or pos < 0: raise Error( "bad init position")
|
||||
rules = dict(((s0, v0), (v1, dr, s1)) for (s0, v0, v1, dr, s1) in rules)
|
||||
|
||||
while True:
|
||||
print(st, '\t', end=" ")
|
||||
for i, v in enumerate(tape):
|
||||
if i == pos: print("[%s]" % (v,), end=" ")
|
||||
else: print(v, end=" ")
|
||||
print()
|
||||
|
||||
if st == halt: break
|
||||
if (st, tape[pos]) not in rules: break
|
||||
|
||||
(v1, dr, s1) = rules[(st, tape[pos])]
|
||||
tape[pos] = v1
|
||||
if dr == 'left':
|
||||
if pos > 0: pos -= 1
|
||||
else: tape.insert(0, blank)
|
||||
if dr == 'right':
|
||||
pos += 1
|
||||
if pos >= len(tape): tape.append(blank)
|
||||
st = s1
|
||||
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
print("incr machine\n")
|
||||
run_utm(
|
||||
halt = 'qf',
|
||||
state = 'q0',
|
||||
tape = list("111"),
|
||||
blank = 'B',
|
||||
rules = map(tuple,
|
||||
["q0 1 1 right q0".split(),
|
||||
"q0 B 1 stay qf".split()]
|
||||
)
|
||||
)
|
||||
|
||||
print("\nbusy beaver\n")
|
||||
run_utm(
|
||||
halt = 'halt',
|
||||
state = 'a',
|
||||
blank = '0',
|
||||
rules = map(tuple,
|
||||
["a 0 1 right b".split(),
|
||||
"a 1 1 left c".split(),
|
||||
"b 0 1 left a".split(),
|
||||
"b 1 1 right b".split(),
|
||||
"c 0 1 left b".split(),
|
||||
"c 1 1 stay halt".split()]
|
||||
)
|
||||
)
|
||||
|
||||
print("\nsorting test\n")
|
||||
run_utm(halt = 'STOP',
|
||||
state = 'A',
|
||||
blank = '0',
|
||||
tape = "2 2 2 1 2 2 1 2 1 2 1 2 1 2".split(),
|
||||
rules = map(tuple,
|
||||
["A 1 1 right A".split(),
|
||||
"A 2 3 right B".split(),
|
||||
"A 0 0 left E".split(),
|
||||
"B 1 1 right B".split(),
|
||||
"B 2 2 right B".split(),
|
||||
"B 0 0 left C".split(),
|
||||
"C 1 2 left D".split(),
|
||||
"C 2 2 left C".split(),
|
||||
"C 3 2 left E".split(),
|
||||
"D 1 1 left D".split(),
|
||||
"D 2 2 left D".split(),
|
||||
"D 3 1 right A".split(),
|
||||
"E 1 1 left E".split(),
|
||||
"E 0 0 right STOP".split()]
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*REXX pgm executes a Turing machine based on initial state, tape, rules*/
|
||||
state = 'q0' /*initial Turing machine state. */
|
||||
term = 'qf' /*a state that is used for halt. */
|
||||
blank = 'B' /*this character is a true blank.*/
|
||||
call turing_rule 'q0 1 1 right q0' /*define a rule for the machine. */
|
||||
call turing_rule 'q0 B 1 stay qf' /* " " " " " " */
|
||||
call turing_init 1 1 1 /*initialize tape to string(s). */
|
||||
call turing_machine /*go invoke the Turning machine. */
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────TURING_MACHINE subroutine───────────*/
|
||||
turing_machine: !=1; bot=1; top=1 /*start at the tape location 1. */
|
||||
say /*might as well show a blank line*/
|
||||
do cycle=1 until state==term /*do Turing machine instructions.*/
|
||||
do k=1 for rules /*process the Turning mach. rules*/
|
||||
parse var rule.k rState rTape rWrite rMove rNext . /*pick pieces*/
|
||||
if state\==rState | @.!\==rTape then iterate /*wrong rule?*/
|
||||
@.!=rWrite /*right rule; write it ──► tape.*/
|
||||
if rMove== 'left' then !=!-1 /*Move left? Then subtract one.*/
|
||||
if rMove=='right' then !=!+1 /*Move right? Then add one.*/
|
||||
bot=min(bot,!); top=max(top,!) /*find the tape bottom and top.*/
|
||||
state=rNext /*use this for the next state. */
|
||||
iterate cycle /*go process another instruction.*/
|
||||
end /*k*/
|
||||
say '***error!*** unknown state:' state; leave /*oops.*/
|
||||
end /*cycle*/
|
||||
$= /*start with empty string (tape).*/
|
||||
do t=bot to top; _=@.t; if _==blank then _=' ' /*translate?*/
|
||||
$=$ || pad || _ /*build chr by chr, maybe pad it.*/
|
||||
end /*t*/ /* [↑] build the tape's contents.*/
|
||||
if $='' then $= "[tape is blank.]" /*make an empty tape visible.*/
|
||||
say 'Turning machine used' rules "rules in" cycle 'cycles, tape is:' $
|
||||
return
|
||||
/*──────────────────────────────────TURING_INIT subroutine──────────────*/
|
||||
turing_init: @.=blank; parse arg x
|
||||
do j=1 for words(x); @.j=word(x,j); end /*j*/
|
||||
return
|
||||
/*──────────────────────────────────TURING_RULE subroutine──────────────*/
|
||||
turing_rule: if symbol('RULES')=="LIT" then rules=0; rules=rules+1
|
||||
pad=left('',length(word(arg(1),2))\==1) /*used if any symbol's length>1.*/
|
||||
rule.rules=arg(1); say right('rule' rules,20) "═══►" rule.rules
|
||||
return
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/*REXX pgm executes a Turing machine based on initial state, tape, rules*/
|
||||
state = 'a' /*initial Turing machine state. */
|
||||
term = 'halt' /*a state that is used for halt. */
|
||||
blank = 0 /*this character is a true blank.*/
|
||||
call turing_rule 'a 0 1 right b' /*define a rule for the machine. */
|
||||
call turing_rule 'a 1 1 left c' /* " " " " " " */
|
||||
call turing_rule 'b 0 1 left a' /* " " " " " " */
|
||||
call turing_rule 'b 1 1 right b' /* " " " " " " */
|
||||
call turing_rule 'c 0 1 left b' /* " " " " " " */
|
||||
call turing_rule 'c 1 1 stay halt' /* " " " " " " */
|
||||
call turing_init /*initialize tape to string(s). */
|
||||
call turing_machine /*go invoke the Turning machine. */
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────TURING_MACHINE subroutine───────────*/
|
||||
turing_machine ∙∙∙
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*REXX pgm executes a Turing machine based on initial state, tape, rules*/
|
||||
state = 'A' /*initial Turing machine state. */
|
||||
term = 'H' /*a state that is used for halt. */
|
||||
blank = 0 /*this character is a true blank.*/
|
||||
call turing_rule 'A 0 1 right B' /*define a rule for the machine. */
|
||||
call turing_rule 'A 1 1 left C' /* " " " " " " */
|
||||
call turing_rule 'B 0 1 right C' /* " " " " " " */
|
||||
call turing_rule 'B 1 1 right B' /* " " " " " " */
|
||||
call turing_rule 'C 0 1 right D' /* " " " " " " */
|
||||
call turing_rule 'C 1 1 left E' /* " " " " " " */
|
||||
call turing_rule 'D 0 1 left A' /* " " " " " " */
|
||||
call turing_rule 'D 1 1 left D' /* " " " " " " */
|
||||
call turing_rule 'E 0 1 stay H' /* " " " " " " */
|
||||
call turing_rule 'E 1 1 left A' /* " " " " " " */
|
||||
call turing_init /*initialize tape to string(s). */
|
||||
call turing_machine /*go invoke the Turning machine. */
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────TURING_MACHINE subroutine───────────*/
|
||||
turing_machine ∙∙∙
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*REXX pgm executes a Turing machine based on initial state, tape, rules*/
|
||||
state = 'A' /*initial Turing machine state. */
|
||||
term = 'halt' /*a state that is used for halt. */
|
||||
blank = 0 /*this character is a true blank.*/
|
||||
call turing_rule 'A 1 1 right A' /*define a rule for the machine. */
|
||||
call turing_rule 'A 2 3 right B' /* " " " " " " */
|
||||
call turing_rule 'A 0 0 left E' /* " " " " " " */
|
||||
call turing_rule 'B 1 1 right B' /* " " " " " " */
|
||||
call turing_rule 'B 2 2 right B' /* " " " " " " */
|
||||
call turing_rule 'B 0 0 left C' /* " " " " " " */
|
||||
call turing_rule 'C 1 2 left D' /* " " " " " " */
|
||||
call turing_rule 'C 2 2 left C' /* " " " " " " */
|
||||
call turing_rule 'C 3 2 left E' /* " " " " " " */
|
||||
call turing_rule 'D 1 1 left D' /* " " " " " " */
|
||||
call turing_rule 'D 2 2 left D' /* " " " " " " */
|
||||
call turing_rule 'D 3 1 right A' /* " " " " " " */
|
||||
call turing_rule 'E 1 1 left E' /* " " " " " " */
|
||||
call turing_rule 'E 0 0 right halt' /* " " " " " " */
|
||||
call turing_init 1 2 2 1 2 2 1 2 1 2 1 2 1 2 /*init. tape to string(s). */
|
||||
call turing_machine /*go invoke the Turning machine. */
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────TURING_MACHINE subroutine───────────*/
|
||||
turing_machine ∙∙∙
|
||||
Loading…
Add table
Add a link
Reference in a new issue