Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,10 +1,22 @@
|
|||
One of the foundational mathematical constructs behind computer science is the [[wp:Universal Turing machine|universal Turing Machine]]. Indeed one way to definitively prove that a language is Turing complete is to implement a universal Turing machine in it.
|
||||
One of the foundational mathematical constructs behind computer science
|
||||
is the [[wp:Universal Turing machine|universal Turing Machine]].
|
||||
|
||||
Indeed one way to definitively prove that a language
|
||||
is [[wp:Turing_completeness|turing-complete]]
|
||||
is to implement a universal Turing machine in it.
|
||||
|
||||
'''The task'''
|
||||
|
||||
For this task you would simulate such a machine capable of taking the definition of any other Turing machine and executing it. You will not, of course, have an infinite tape, but you should emulate this as much as is possible. The three permissible actions on the tape are "left", "right" and "stay".
|
||||
For this task you would simulate such a machine capable
|
||||
of taking the definition of any other Turing machine and executing it.
|
||||
Of course, you will not have an infinite tape,
|
||||
but you should emulate this as much as is possible.
|
||||
|
||||
To test your universal Turing machine (and prove your programming language is Turing complete!), you should execute the following two Turing machines based on the following definitions.
|
||||
The three permissible actions on the tape are "left", "right" and "stay".
|
||||
|
||||
To test your universal Turing machine (and prove your programming language
|
||||
is Turing complete!), you should execute the following two Turing machines
|
||||
based on the following definitions.
|
||||
|
||||
'''Simple incrementer'''
|
||||
* '''States:''' q0, qf
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
(defun turing (initial terminal blank rules tape &optional (verbose NIL))
|
||||
(labels ((combine (front back)
|
||||
(if front
|
||||
(combine (cdr front) (cons (car front) back))
|
||||
back))
|
||||
|
||||
(update-tape (old-front old-back new-content move)
|
||||
(cond ((eq move 'right)
|
||||
(list (cons new-content old-front)
|
||||
(cdr old-back)))
|
||||
((eq move 'left)
|
||||
(list (cdr old-front)
|
||||
(list* (car old-front) new-content (cdr old-back))))
|
||||
(T (list old-front
|
||||
(cons new-content (cdr old-back))))))
|
||||
|
||||
(show-tape (front back)
|
||||
(format T "~{~a~}[~a]~{~a~}~%"
|
||||
(nreverse (subseq front 0 (min 10 (length front))))
|
||||
(or (car back) blank)
|
||||
(subseq (cdr back) 0 (min 10 (length (cdr back)))))))
|
||||
|
||||
(loop for back = tape then new-back
|
||||
for front = '() then new-front
|
||||
for state = initial then new-state
|
||||
for content = (or (car back) blank)
|
||||
for (new-state new-content move) = (gethash (cons state content) rules)
|
||||
for (new-front new-back) = (update-tape front back new-content move)
|
||||
until (equal state terminal)
|
||||
do (when verbose
|
||||
(show-tape front back))
|
||||
finally (progn
|
||||
(when verbose
|
||||
(show-tape front back))
|
||||
(return (combine front back))))))
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
(defun turing (initial terminal blank rules tape &optional (verbose NIL))
|
||||
(labels ((run (state front back)
|
||||
(if (equal state terminal)
|
||||
(progn
|
||||
(when verbose
|
||||
(show-tape front back))
|
||||
(combine front back))
|
||||
(let ((current-content (or (car back) blank)))
|
||||
(destructuring-bind
|
||||
(new-state new-content move)
|
||||
(gethash (cons state current-content) rules)
|
||||
(when verbose
|
||||
(show-tape front back))
|
||||
(cond ((eq move 'right)
|
||||
(run new-state
|
||||
(cons new-content front)
|
||||
(cdr back)))
|
||||
((eq move 'left)
|
||||
(run new-state
|
||||
(cdr front)
|
||||
(list* (car front) new-content (cdr back))))
|
||||
(T (run new-state
|
||||
front
|
||||
(cons new-content (cdr back)))))))))
|
||||
|
||||
(show-tape (front back)
|
||||
(format T "~{~a~}[~a]~{~a~}~%"
|
||||
(nreverse (subseq front 0 (min 10 (length front))))
|
||||
(or (car back) blank)
|
||||
(subseq (cdr back) 0 (min 10 (length (cdr back))))))
|
||||
|
||||
(combine (front back)
|
||||
(if front
|
||||
(combine (cdr front) (cons (car front) back))
|
||||
back)))
|
||||
|
||||
(run initial '() tape)))
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
;; Helper function for creating the rules table
|
||||
(defun make-rules-table (rules-list)
|
||||
(let ((rules (make-hash-table :test 'equal)))
|
||||
(loop for (state content new-content dir new-state) in rules-list
|
||||
do (setf (gethash (cons state content) rules)
|
||||
(list new-state new-content dir)))
|
||||
rules))
|
||||
|
||||
(format T "Simple incrementer~%")
|
||||
(turing 'q0 'qf 'B (make-rules-table '((q0 1 1 right q0) (q0 B 1 stay qf))) '(1 1 1) T)
|
||||
|
||||
(format T "Three-state busy beaver~%")
|
||||
(turing 'a 'halt 0
|
||||
(make-rules-table '((a 0 1 right b)
|
||||
(a 1 1 left c)
|
||||
(b 0 1 left a)
|
||||
(b 1 1 right b)
|
||||
(c 0 1 left b)
|
||||
(c 1 1 stay halt)))
|
||||
'() T)
|
||||
|
||||
(format T "Sort (final tape)~%")
|
||||
(format T "~{~a~}~%"
|
||||
(turing 'A 'H 0
|
||||
(make-rules-table '((A 1 1 right A)
|
||||
(A 2 3 right B)
|
||||
(A 0 0 left E)
|
||||
(B 1 1 right B)
|
||||
(B 2 2 right B)
|
||||
(B 0 0 left C)
|
||||
(C 1 2 left D)
|
||||
(C 2 2 left C)
|
||||
(C 3 2 left E)
|
||||
(D 1 1 left D)
|
||||
(D 2 2 left D)
|
||||
(D 3 1 right A)
|
||||
(E 1 1 left E)
|
||||
(E 0 0 right H)))
|
||||
'(2 1 2 2 2 1 1)))
|
||||
|
||||
(format T "5-state busy beaver (first 20 cells)~%")
|
||||
(format T "~{~a~}...~%"
|
||||
(subseq (turing 'A 'H 0
|
||||
(make-rules-table '((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)))
|
||||
'())
|
||||
0 20))
|
||||
|
|
@ -5,13 +5,11 @@ 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),
|
||||
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),
|
||||
static assert([EnumMembers!Symbol].equal(EnumMembers!Symbol.length.iota),
|
||||
"Symbol must be a plain enum.");
|
||||
|
||||
enum Direction { right, left, stay }
|
||||
|
|
@ -23,16 +21,15 @@ if (is(State == enum) && is(Symbol == enum)) {
|
|||
// 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;
|
||||
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(in Symbol toWrite_, in Direction direction_, in State nextState_)
|
||||
pure nothrow @safe @nogc {
|
||||
this.toWrite = toWrite_;
|
||||
this.direction = direction_;
|
||||
this.nextState = nextState_;
|
||||
|
|
@ -57,18 +54,18 @@ if (is(State == enum) && is(Symbol == enum)) {
|
|||
const SymbolMap sMap;
|
||||
size_t nSteps;
|
||||
|
||||
this(in ref TuringMachine t) pure /*nothrow*/ {
|
||||
this(in ref TuringMachine t) pure nothrow @safe {
|
||||
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.tapeRight = t.input.dup;
|
||||
this.position = 0;
|
||||
this.sMap = t.symbolMap;
|
||||
}
|
||||
|
||||
pure nothrow invariant() {
|
||||
pure nothrow @safe @nogc invariant {
|
||||
assert(this.tapeRight.length > 0);
|
||||
if (this.position >= 0)
|
||||
assert(this.position < this.tapeRight.length);
|
||||
|
|
@ -76,18 +73,18 @@ if (is(State == enum) && is(Symbol == enum)) {
|
|||
assert(this.position.abs <= this.tapeLeft.length);
|
||||
}
|
||||
|
||||
Symbol readSymb() const pure nothrow {
|
||||
Symbol readSymb() const pure nothrow @safe @nogc {
|
||||
if (this.position >= 0)
|
||||
return this.tapeRight[this.position];
|
||||
else
|
||||
return this.tapeLeft[this.position.abs - 1];
|
||||
}
|
||||
|
||||
void showSymb() const {
|
||||
void showSymb() const @safe {
|
||||
this.write;
|
||||
}
|
||||
|
||||
void writeSymb(in Symbol symbol) {
|
||||
void writeSymb(in Symbol symbol) @safe {
|
||||
static if (doShow)
|
||||
showSymb;
|
||||
if (this.position >= 0)
|
||||
|
|
@ -96,19 +93,19 @@ if (is(State == enum) && is(Symbol == enum)) {
|
|||
this.tapeLeft[this.position.abs - 1] = symbol;
|
||||
}
|
||||
|
||||
void goRight() pure nothrow {
|
||||
void goRight() pure nothrow @safe {
|
||||
this.position++;
|
||||
if (position > 0 && position == tapeRight.length)
|
||||
tapeRight ~= blank;
|
||||
}
|
||||
|
||||
void goLeft() pure nothrow {
|
||||
void goLeft() pure nothrow @safe {
|
||||
this.position--;
|
||||
if (position < 0 && (position.abs - 1) == tapeLeft.length)
|
||||
tapeLeft ~= blank;
|
||||
}
|
||||
|
||||
void move(in Direction dir) pure nothrow {
|
||||
void move(in Direction dir) pure nothrow @safe {
|
||||
nSteps++;
|
||||
final switch (dir) with (Direction) {
|
||||
case left: goLeft; break;
|
||||
|
|
@ -117,10 +114,9 @@ if (is(State == enum) && is(Symbol == enum)) {
|
|||
}
|
||||
}
|
||||
|
||||
string toString() const {
|
||||
const pos = cast(int)tapeLeft.length + this.position + 4;
|
||||
return format("...%-(%)...", tapeLeft.retro
|
||||
.chain(tapeRight)
|
||||
string toString() const @safe {
|
||||
immutable pos = tapeLeft.length.signed + this.position + 4;
|
||||
return format("...%-(%)...", tapeLeft.retro.chain(tapeRight)
|
||||
.map!(s => sMap[s])) ~
|
||||
'\n' ~
|
||||
format("%" ~ pos.text ~ "s", "^") ~
|
||||
|
|
@ -128,25 +124,22 @@ if (is(State == enum) && is(Symbol == enum)) {
|
|||
}
|
||||
}
|
||||
|
||||
void show() const {
|
||||
void show() const @safe {
|
||||
head.showSymb;
|
||||
}
|
||||
|
||||
this(in ref TuringMachine tm_) {
|
||||
static assert(__traits(compiles, State.H),
|
||||
"State needs a 'H' (Halt).");
|
||||
this(in ref TuringMachine tm_) @safe {
|
||||
static assert(__traits(compiles, State.H), "State needs a 'H' (Halt).");
|
||||
immutable errMsg = "Invalid input.";
|
||||
auto runningStates = remove!(s => s == State.H)
|
||||
([EnumMembers!State]);
|
||||
auto runningStates = remove!(s => s == State.H)([EnumMembers!State]);
|
||||
enforce(!runningStates.empty, errMsg);
|
||||
enforce(tm_.rules.length == EnumMembers!State.length - 1,
|
||||
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)
|
||||
foreach (immutable State st, const rset; tm_.rules)
|
||||
foreach (immutable Symbol sy, immutable rule; rset)
|
||||
mRules[st][sy] = rule;
|
||||
|
||||
this.tm = tm_;
|
||||
|
|
@ -165,7 +158,7 @@ if (is(State == enum) && is(Symbol == enum)) {
|
|||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
void main() @safe {
|
||||
"Incrementer:".writeln;
|
||||
enum States1 : ubyte { A, H }
|
||||
enum Symbols1 : ubyte { s0, s1 }
|
||||
|
|
|
|||
177
Task/Universal-Turing-machine/Go/universal-turing-machine-1.go
Normal file
177
Task/Universal-Turing-machine/Go/universal-turing-machine-1.go
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
package turing
|
||||
|
||||
type Symbol byte
|
||||
|
||||
type Motion byte
|
||||
|
||||
const (
|
||||
Left Motion = 'L'
|
||||
Right Motion = 'R'
|
||||
Stay Motion = 'N'
|
||||
)
|
||||
|
||||
type Tape struct {
|
||||
data []Symbol
|
||||
pos, left int
|
||||
blank Symbol
|
||||
}
|
||||
|
||||
// NewTape returns a new tape filled with 'data' and position set to 'start'.
|
||||
// 'start' does not need to be range, the tape will be extended if required.
|
||||
func NewTape(blank Symbol, start int, data []Symbol) *Tape {
|
||||
t := &Tape{
|
||||
data: data,
|
||||
blank: blank,
|
||||
}
|
||||
if start < 0 {
|
||||
t.Left(-start)
|
||||
}
|
||||
t.Right(start)
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *Tape) Stay() {}
|
||||
func (t *Tape) Data() []Symbol { return t.data[t.left:] }
|
||||
func (t *Tape) Read() Symbol { return t.data[t.pos] }
|
||||
func (t *Tape) Write(s Symbol) { t.data[t.pos] = s }
|
||||
|
||||
func (t *Tape) Dup() *Tape {
|
||||
t2 := &Tape{
|
||||
data: make([]Symbol, len(t.Data())),
|
||||
blank: t.blank,
|
||||
}
|
||||
copy(t2.data, t.Data())
|
||||
t2.pos = t.pos - t.left
|
||||
return t2
|
||||
}
|
||||
|
||||
func (t *Tape) String() string {
|
||||
s := ""
|
||||
for i := t.left; i < len(t.data); i++ {
|
||||
b := t.data[i]
|
||||
if i == t.pos {
|
||||
s += "[" + string(b) + "]"
|
||||
} else {
|
||||
s += " " + string(b) + " "
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (t *Tape) Move(a Motion) {
|
||||
switch a {
|
||||
case Left:
|
||||
t.Left(1)
|
||||
case Right:
|
||||
t.Right(1)
|
||||
case Stay:
|
||||
t.Stay()
|
||||
}
|
||||
}
|
||||
|
||||
const minSz = 16
|
||||
|
||||
func (t *Tape) Left(n int) {
|
||||
t.pos -= n
|
||||
if t.pos < 0 {
|
||||
// Extend left
|
||||
var sz int
|
||||
for sz = minSz; cap(t.data[t.left:])-t.pos >= sz; sz <<= 1 {
|
||||
}
|
||||
newd := make([]Symbol, sz)
|
||||
newl := len(newd) - cap(t.data[t.left:])
|
||||
n := copy(newd[newl:], t.data[t.left:])
|
||||
t.data = newd[:newl+n]
|
||||
t.pos += newl - t.left
|
||||
t.left = newl
|
||||
}
|
||||
if t.pos < t.left {
|
||||
if t.blank != 0 {
|
||||
for i := t.pos; i < t.left; i++ {
|
||||
t.data[i] = t.blank
|
||||
}
|
||||
}
|
||||
t.left = t.pos
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tape) Right(n int) {
|
||||
t.pos += n
|
||||
if t.pos >= cap(t.data) {
|
||||
// Extend right
|
||||
var sz int
|
||||
for sz = minSz; t.pos >= sz; sz <<= 1 {
|
||||
}
|
||||
newd := make([]Symbol, sz)
|
||||
n := copy(newd[t.left:], t.data[t.left:])
|
||||
t.data = newd[:t.left+n]
|
||||
}
|
||||
if i := len(t.data); t.pos >= i {
|
||||
t.data = t.data[:t.pos+1]
|
||||
if t.blank != 0 {
|
||||
for ; i < len(t.data); i++ {
|
||||
t.data[i] = t.blank
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type State string
|
||||
|
||||
type Rule struct {
|
||||
State
|
||||
Symbol
|
||||
Write Symbol
|
||||
Motion
|
||||
Next State
|
||||
}
|
||||
|
||||
func (i *Rule) key() key { return key{i.State, i.Symbol} }
|
||||
func (i *Rule) action() action { return action{i.Write, i.Motion, i.Next} }
|
||||
|
||||
type key struct {
|
||||
State
|
||||
Symbol
|
||||
}
|
||||
|
||||
type action struct {
|
||||
write Symbol
|
||||
Motion
|
||||
next State
|
||||
}
|
||||
|
||||
type Machine struct {
|
||||
tape *Tape
|
||||
start, state State
|
||||
transition map[key]action
|
||||
l func(string, ...interface{}) // XXX
|
||||
}
|
||||
|
||||
func NewMachine(rules []Rule) *Machine {
|
||||
m := &Machine{transition: make(map[key]action, len(rules))}
|
||||
if len(rules) > 0 {
|
||||
m.start = rules[0].State
|
||||
}
|
||||
for _, r := range rules {
|
||||
m.transition[r.key()] = r.action()
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Machine) Run(input *Tape) (int, *Tape) {
|
||||
m.tape = input.Dup()
|
||||
m.state = m.start
|
||||
for cnt := 0; ; cnt++ {
|
||||
if m.l != nil {
|
||||
m.l("%3d %4s: %v\n", cnt, m.state, m.tape)
|
||||
}
|
||||
sym := m.tape.Read()
|
||||
act, ok := m.transition[key{m.state, sym}]
|
||||
if !ok {
|
||||
return cnt, m.tape
|
||||
}
|
||||
m.tape.Write(act.write)
|
||||
m.tape.Move(act.Motion)
|
||||
m.state = act.next
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
".." // XXX path to above turing package
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var incrementer = turing.NewMachine([]turing.Rule{
|
||||
{"q0", '1', '1', turing.Right, "q0"},
|
||||
{"q0", 'B', '1', turing.Stay, "qf"},
|
||||
})
|
||||
input := turing.NewTape('B', 0, []turing.Symbol{'1', '1', '1'})
|
||||
cnt, output := incrementer.Run(input)
|
||||
fmt.Println("Turing machine halts after", cnt, "operations")
|
||||
fmt.Println("Resulting tape:", output)
|
||||
|
||||
var beaver = turing.NewMachine([]turing.Rule{
|
||||
{"a", '0', '1', turing.Right, "b"},
|
||||
{"a", '1', '1', turing.Left, "c"},
|
||||
{"b", '0', '1', turing.Left, "a"},
|
||||
{"b", '1', '1', turing.Right, "b"},
|
||||
{"c", '0', '1', turing.Left, "b"},
|
||||
{"c", '1', '1', turing.Stay, "halt"},
|
||||
})
|
||||
cnt, output = beaver.Run(turing.NewTape('0', 0, nil))
|
||||
fmt.Println("Turing machine halts after", cnt, "operations")
|
||||
fmt.Println("Resulting tape:", output)
|
||||
|
||||
beaver = turing.NewMachine([]turing.Rule{
|
||||
{"A", '0', '1', turing.Right, "B"},
|
||||
{"A", '1', '1', turing.Left, "C"},
|
||||
{"B", '0', '1', turing.Right, "C"},
|
||||
{"B", '1', '1', turing.Right, "B"},
|
||||
{"C", '0', '1', turing.Right, "D"},
|
||||
{"C", '1', '0', turing.Left, "E"},
|
||||
{"D", '0', '1', turing.Left, "A"},
|
||||
{"D", '1', '1', turing.Left, "D"},
|
||||
{"E", '0', '1', turing.Stay, "H"},
|
||||
{"E", '1', '0', turing.Left, "A"},
|
||||
})
|
||||
cnt, output = beaver.Run(turing.NewTape('0', 0, nil))
|
||||
fmt.Println("Turing machine halts after", cnt, "operations")
|
||||
fmt.Println("Resulting tape has", len(output.Data()), "cells")
|
||||
|
||||
var sort = turing.NewMachine([]turing.Rule{
|
||||
// Moving right, first b→B;s1
|
||||
{"s0", 'a', 'a', turing.Right, "s0"},
|
||||
{"s0", 'b', 'B', turing.Right, "s1"},
|
||||
{"s0", ' ', ' ', turing.Left, "se"},
|
||||
// Conintue right to end of tape → s2
|
||||
{"s1", 'a', 'a', turing.Right, "s1"},
|
||||
{"s1", 'b', 'b', turing.Right, "s1"},
|
||||
{"s1", ' ', ' ', turing.Left, "s2"},
|
||||
// Continue left over b. a→b;s3, B→b;se
|
||||
{"s2", 'a', 'b', turing.Left, "s3"},
|
||||
{"s2", 'b', 'b', turing.Left, "s2"},
|
||||
{"s2", 'B', 'b', turing.Left, "se"},
|
||||
// Continue left until B→a;s0
|
||||
{"s3", 'a', 'a', turing.Left, "s3"},
|
||||
{"s3", 'b', 'b', turing.Left, "s3"},
|
||||
{"s3", 'B', 'a', turing.Right, "s0"},
|
||||
// Move to tape start → halt
|
||||
{"se", 'a', 'a', turing.Left, "se"},
|
||||
{"se", ' ', ' ', turing.Right, "see"},
|
||||
})
|
||||
input = turing.NewTape(' ', 0, []turing.Symbol("abbabbabababab"))
|
||||
cnt, output = sort.Run(input)
|
||||
fmt.Println("Turing machine halts after", cnt, "operations")
|
||||
fmt.Println("Resulting tape:", output)
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
".@(('utm=. '),,)@(];._2)@(noun=. ".@('(0 : 0)'"_))_ NB. Fixed tacit universal Turing machine code...
|
||||
". noun define -. CRLF NB. Fixed tacit universal Turing machine code...
|
||||
|
||||
utm=.
|
||||
(((":@:(]&:>)@:(6&({::)) ,: (":@] 9&({::))) ,. ':'"_) ,. 2&({::) >@:(((
|
||||
48 + ]) { a."_)@[ ; (] $ ' '"_) , '^'"_) 3&({::))@:([ (0 0 $ 1!:2&2)@:(
|
||||
'A changeless cycle was detected!'"_)^:(-.@:(_1"_ = 1&({::))))@:((((3&(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
Noun=. ".@('(0 : 0)'"_)
|
||||
|
||||
NB. Simple Incrementer...
|
||||
NB. 0 1 Tape Symbol Scan
|
||||
NB. S p m g p m g (p,m,g) → (print,move,goto)
|
||||
QS=. (noun _) ; 0 NB. Reading the transition table and setting the initial state
|
||||
QS=. (Noun _) ; 0 NB. Reading the transition table and setting the initial state
|
||||
0 1 0 _1 1 1 0
|
||||
)
|
||||
TPF=. 1 1 1 ; 0 ; 1 NB. Setting the tape, its pointer and the display frequency
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
NB. Three-state busy beaver..
|
||||
NB. 0 1 Tape Symbol Scan
|
||||
NB. S p m g p m g (p,m,g) → (print,move,goto)
|
||||
QS=. (noun _) ; 0 NB. Reading the transition table and setting the initial state
|
||||
QS=. (Noun _) ; 0 NB. Reading the transition table and setting the initial state
|
||||
0 1 1 1 1 _1 2
|
||||
1 1 _1 0 1 1 1
|
||||
2 1 _1 1 1 0 _1
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
NB. Sorting stress test...
|
||||
NB. 0 1 2 3 Tape Symbol Scan
|
||||
NB. S p m g p m g p m g p m g (p,m,g) ➜ (print,move,goto)
|
||||
QS=. (noun _) ; 0 NB. Reading the transition table and setting the initial state
|
||||
QS=. (Noun _) ; 0 NB. Reading the transition table and setting the initial state
|
||||
0 0 _1 4 1 1 0 3 1 1 _ _ _
|
||||
1 0 _1 2 1 1 1 2 1 1 _ _ _
|
||||
2 _ _ _ 2 _1 3 2 _1 2 2 _1 4
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
left = 1; right = -1; stay = 0;
|
||||
cmp[s_] := ToExpression[StringSplit[s, ","]];
|
||||
utm[rules_, initial_, head_] :=
|
||||
Module[{tape = initial, rh = head, n = 1},
|
||||
Clear[nxt];
|
||||
nxt[state_, field_] :=
|
||||
nxt[state, field] = Position[rules, {rules[[state, 5]], field, _, _, _}][[1, 1]];
|
||||
n = Position[rules, {rules[[n, 1]], BitGet[tape, rh], _, _, _}][[1,1]];
|
||||
While[rules[[n, 4]] != 0,
|
||||
If[rules[[n, 3]] != BitGet[tape, rh],
|
||||
If[rules[[n, 3]] == 1, tape = BitSet[tape, rh],
|
||||
tape = BitClear[tape, rh]]];
|
||||
rh = rh + rules[[n, 4]];
|
||||
If[rh < 0, rh = 0; tape = 2*tape];
|
||||
n = nxt[n, BitGet[tape, rh]];
|
||||
]; {tape, rh}
|
||||
];
|
||||
];
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
printMachine[tape_,pos_]:=(mach=IntegerString[tape,2];
|
||||
ptr=StringReplace[mach,{"0"-> " ","1"->" "}];
|
||||
Print[mach];Print[StringInsert[ptr,"^",StringLength[ptr]-pos]];);
|
||||
|
||||
simpleIncr={"q0,1,1,right,q0","q0,B,1,stay,qf"};
|
||||
simpleIncr=Map[cmp,simpleIncr]/.B->0;
|
||||
fin=utm[simpleIncr,7,2];
|
||||
printMachine[fin[[1]],fin[[2]]];
|
||||
|
||||
busyBeaver3S={
|
||||
"a,0,1,right,b",
|
||||
"a,1,1,left,c",
|
||||
"b,0,1,left,a",
|
||||
"b,1,1,right,b",
|
||||
"c,0,1,left,b",
|
||||
"c,1,1,stay,halt"};
|
||||
fin=utm[Map[cmp,busyBeaver3S],0,0];
|
||||
printMachine[fin[[1]],fin[[2]]];
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
probable5S={
|
||||
"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"};
|
||||
fin=utm[Map[cmp,probable5S],0,0];
|
||||
]
|
||||
|
||||
|
||||
fin[[1]]//N
|
||||
3.254757786465838*10^3698
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
# Finite state machine
|
||||
(de turing (Tape Init Halt Blank Rules Verbose)
|
||||
(let
|
||||
(Head 1
|
||||
State Init
|
||||
Rule NIL
|
||||
S 'start
|
||||
C (length Tape))
|
||||
(catch NIL
|
||||
(loop
|
||||
(state 'S
|
||||
(start 'print
|
||||
(when (=0 C)
|
||||
(setq Tape (insert Head Tape Blank))
|
||||
(inc 'C) ) )
|
||||
(print 'lookup
|
||||
(when Verbose
|
||||
(for (N . I) Tape
|
||||
(if (= N Head)
|
||||
(print (list I))
|
||||
(prin I) ) )
|
||||
(prinl) )
|
||||
(when (= State Halt) (throw NIL) ) )
|
||||
(lookup 'do
|
||||
(setq Rule
|
||||
(find
|
||||
'((X)
|
||||
(and
|
||||
(= (car X) State)
|
||||
(= (cadr X) (car (nth Tape Head))) ) )
|
||||
Rules ) ) )
|
||||
(do 'step
|
||||
(setq Tape (place Head Tape (caddr Rule))) )
|
||||
(step 'print
|
||||
(cond
|
||||
((= (cadddr Rule) 'R) (inc 'Head))
|
||||
((= (cadddr Rule) 'L) (dec 'Head)) )
|
||||
(cond
|
||||
((< Head 1)
|
||||
(setq Tape (insert Head Tape Blank))
|
||||
(inc 'C)
|
||||
(one Head) )
|
||||
((> Head C)
|
||||
(setq Tape (insert Head Tape Blank))
|
||||
(inc 'C) ) )
|
||||
(setq State (last Rule)) ) ) ) ) )
|
||||
Tape )
|
||||
|
||||
(println "Simple incrementer")
|
||||
(turing '(1 1 1) 'A 'H 'B '((A 1 1 R A) (A B 1 S H)) T)
|
||||
|
||||
(println "Three-state busy beaver")
|
||||
(turing '() 'A 'H 0
|
||||
'((A 0 1 R B)
|
||||
(A 1 1 L C)
|
||||
(B 0 1 L A)
|
||||
(B 1 1 R B)
|
||||
(C 0 1 L B)
|
||||
(C 1 1 S H)) T )
|
||||
|
||||
(println "Five-state busy beaver")
|
||||
(let Tape (turing '() 'A 'H 0
|
||||
'((A 0 1 R B)
|
||||
(A 1 1 L C)
|
||||
(B 0 1 R C)
|
||||
(B 1 1 R B)
|
||||
(C 0 1 R D)
|
||||
(C 1 0 L E)
|
||||
(D 0 1 L A)
|
||||
(D 1 1 L D)
|
||||
(E 0 1 S H)
|
||||
(E 1 0 L A)) NIL)
|
||||
(println '0s: (cnt '((X) (= 0 X)) Tape))
|
||||
(println '1s: (cnt '((X) (= 1 X)) Tape)) )
|
||||
|
||||
(bye)
|
||||
Loading…
Add table
Add a link
Reference in a new issue