155 lines
4.8 KiB
Plaintext
155 lines
4.8 KiB
Plaintext
import "./dynamic" for Enum, Tuple, Struct
|
|
import "./fmt" for Fmt
|
|
|
|
var Dir = Enum.create("Dir", ["LEFT", "RIGHT", "STAY"])
|
|
|
|
var Rule = Tuple.create("Rule", ["state1", "symbol1", "symbol2", "dir", "state2"])
|
|
|
|
var Tape = Struct.create("Tape", ["symbol", "left", "right"])
|
|
|
|
class Turing {
|
|
construct new(states, finalStates, symbols, blank, state, tapeInput, rules) {
|
|
_states = states
|
|
_finalStates = finalStates
|
|
_symbols = symbols
|
|
_blank = blank
|
|
_state = state
|
|
_tape = null
|
|
_transitions = List.filled(_states.count, null)
|
|
for (i in 0..._states.count) _transitions[i] = List.filled(_symbols.count, null)
|
|
for (i in 0...tapeInput.count) {
|
|
move_(Dir.RIGHT)
|
|
_tape.symbol = tapeInput[i]
|
|
}
|
|
if (tapeInput.count == 0) move_(Dir.RIGHT)
|
|
while (_tape.left) _tape = _tape.left
|
|
for (i in 0...rules.count) {
|
|
var rule = rules[i]
|
|
_transitions[stateIndex_(rule.state1)][symbolIndex_(rule.symbol1)] = rule
|
|
}
|
|
}
|
|
|
|
stateIndex_(state) {
|
|
var i = _states.indexOf(state)
|
|
return (i >= 0) ? i : 0
|
|
}
|
|
|
|
symbolIndex_(symbol) {
|
|
var i = _symbols.indexOf(symbol)
|
|
return (i >= 0) ? i : 0
|
|
}
|
|
|
|
move_(dir) {
|
|
var orig = _tape
|
|
if (dir == Dir.RIGHT) {
|
|
if (orig && orig.right) {
|
|
_tape = orig.right
|
|
} else {
|
|
_tape = Tape.new(_blank, null, null)
|
|
if (orig) {
|
|
_tape.left = orig
|
|
orig.right = _tape
|
|
}
|
|
}
|
|
} else if (dir == Dir.LEFT) {
|
|
if (orig && orig.left) {
|
|
_tape = orig.left
|
|
} else {
|
|
_tape = Tape.new(_blank, null, null)
|
|
if (orig) {
|
|
_tape.right = orig
|
|
orig.left = _tape
|
|
}
|
|
}
|
|
} else if (dir == Dir.STAY) {}
|
|
}
|
|
|
|
printState() {
|
|
Fmt.write("$-10s ", _state)
|
|
var t = _tape
|
|
while (t.left) t = t.left
|
|
while (t) {
|
|
if (t == _tape) {
|
|
System.write("[%(t.symbol)]")
|
|
} else {
|
|
System.write(" %(t.symbol) ")
|
|
}
|
|
t = t.right
|
|
}
|
|
System.print()
|
|
}
|
|
|
|
run(maxLines) {
|
|
var lines = 0
|
|
while (true) {
|
|
printState()
|
|
for (finalState in _finalStates) {
|
|
if (finalState == _state) return
|
|
}
|
|
lines = lines + 1
|
|
if (lines == maxLines) {
|
|
System.print("(Only the first %(maxLines) lines displayed)")
|
|
return
|
|
}
|
|
var rule = _transitions[stateIndex_(_state)][symbolIndex_(_tape.symbol)]
|
|
_tape.symbol = rule.symbol2
|
|
move_(rule.dir)
|
|
_state = rule.state2
|
|
}
|
|
}
|
|
}
|
|
|
|
System.print("Simple incrementer")
|
|
Turing.new(
|
|
["q0", "qf"], // states
|
|
["qf"], // finalStates
|
|
["B", "1"], // symbols
|
|
"B", // blank
|
|
"q0", // state
|
|
["1", "1", "1"], // tapeInput
|
|
[ // rules
|
|
Rule.new("q0", "1", "1", Dir.RIGHT, "q0"),
|
|
Rule.new("q0", "B", "1", Dir.STAY, "qf")
|
|
]
|
|
).run(20)
|
|
|
|
System.print("\nThree-state busy beaver")
|
|
Turing.new(
|
|
["a", "b", "c", "halt"], // states
|
|
["halt"], // finalStates
|
|
["0", "1"], // symbols
|
|
"0", // blank
|
|
"a", // state
|
|
[], // tapeInput
|
|
[ // rules
|
|
Rule.new("a", "0", "1", Dir.RIGHT, "b"),
|
|
Rule.new("a", "1", "1", Dir.LEFT, "c"),
|
|
Rule.new("b", "0", "1", Dir.LEFT, "a"),
|
|
Rule.new("b", "1", "1", Dir.RIGHT, "b"),
|
|
Rule.new("c", "0", "1", Dir.LEFT, "b"),
|
|
Rule.new("c", "1", "1", Dir.STAY, "halt")
|
|
]
|
|
).run(20)
|
|
|
|
System.print("\nFive-state two-symbol probable busy beaver")
|
|
Turing.new(
|
|
["A", "B", "C", "D", "E", "H"], // states
|
|
["H"], // finalStates
|
|
["0", "1"], // symbols
|
|
"0", // blank
|
|
"A", // state
|
|
[], // tapeInput
|
|
[ // rules
|
|
Rule.new("A", "0", "1", Dir.RIGHT, "B"),
|
|
Rule.new("A", "1", "1", Dir.LEFT, "C"),
|
|
Rule.new("B", "0", "1", Dir.RIGHT, "C"),
|
|
Rule.new("B", "1", "1", Dir.RIGHT, "B"),
|
|
Rule.new("C", "0", "1", Dir.RIGHT, "D"),
|
|
Rule.new("C", "1", "0", Dir.LEFT, "E"),
|
|
Rule.new("D", "0", "1", Dir.LEFT, "A"),
|
|
Rule.new("D", "1", "1", Dir.LEFT, "D"),
|
|
Rule.new("E", "0", "1", Dir.STAY, "H"),
|
|
Rule.new("E", "1", "0", Dir.LEFT, "A")
|
|
]
|
|
).run(20)
|