Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
|
|
@ -0,0 +1,101 @@
|
|||
(require 'struct)
|
||||
|
||||
(struct TM (read-only: name states symbs final rules mem state-values: tape pos state))
|
||||
|
||||
(define-syntax-rule (rule-idx state symb numstates)
|
||||
(+ state (* symb numstates)))
|
||||
|
||||
(define-syntax-rule (make-TM name states symbs rules)
|
||||
(_make-TM name 'states 'symbs 'rules))
|
||||
|
||||
;; a rule is (state symbol --> write move new-state)
|
||||
;; index for rule = state-num + (number of states) * symbol-num
|
||||
;; convert states/symbol into vector indices
|
||||
(define (compile-rule T rule into: rules)
|
||||
(define numstates (vector-length (TM-states T)))
|
||||
(define state (vector-index [rule 0](TM-states T) )) ; index
|
||||
(define symb (vector-index [rule 1](TM-symbs T) ))
|
||||
(define write-symb (vector-index [rule 2] (TM-symbs T) ))
|
||||
(define move (1- (vector-index [rule 3] #(left stay right) )))
|
||||
(define new-state (vector-index [rule 4](TM-states T)))
|
||||
(define rulenum (rule-idx state symb numstates))
|
||||
(vector-set! rules rulenum (vector write-symb move new-state))
|
||||
; (writeln 'rule rulenum [rules rulenum])
|
||||
)
|
||||
|
||||
(define (_make-TM name states symbs rules)
|
||||
(define T (TM name (list->vector states) (list->vector symbs) null null))
|
||||
(set-TM-final! T (1- (length states))) ;; assume one final state
|
||||
(set-TM-rules! T (make-vector (* (length states) (length symbs))))
|
||||
(for ((rule rules)) (compile-rule T (list->vector rule) into: (TM-rules T)))
|
||||
T ) ; returns a TM
|
||||
|
||||
;;------------------
|
||||
;; TM-trace
|
||||
;;-------------------
|
||||
(string-delimiter "")
|
||||
|
||||
(define (TM-print T symb-index: symb (hilite #f))
|
||||
(cond
|
||||
((= 0 symb) (if hilite "🔲" "◽️" ))
|
||||
((= 1 symb) (if hilite "🔳 " "◾️" ))
|
||||
(else "X")))
|
||||
|
||||
(define (TM-trace T tape pos state step)
|
||||
(if (= (TM-final T) state)
|
||||
(write "🔴")
|
||||
(write "🔵"))
|
||||
|
||||
(for [(p (in-range (- (TM-mem T) 7) (+ (TM-mem T) 8)))]
|
||||
(write (TM-print T [tape p] (= p pos))))
|
||||
(write step)
|
||||
(writeln))
|
||||
|
||||
;;---------------
|
||||
;; TM-init : alloc and init tape
|
||||
;;---------------
|
||||
(define (TM-init T input-symbs (mem 20))
|
||||
;; init state variables
|
||||
(set-TM-tape! T (make-vector (* 2 mem)))
|
||||
(set-TM-pos! T mem)
|
||||
(set-TM-state! T 0)
|
||||
(set-TM-mem! T mem)
|
||||
|
||||
(for [(symb input-symbs) (i (in-naturals))]
|
||||
(vector-set! (TM-tape T) [+ i (TM-pos T)] (vector-index symb (TM-symbs T))))
|
||||
(TM-trace T (TM-tape T) mem 0 0)
|
||||
mem )
|
||||
|
||||
;;---------------
|
||||
;; TM-run : run at most maxsteps
|
||||
;;---------------
|
||||
(define (TM-run T (verbose #f) (maxsteps 1_000_000))
|
||||
(define count 0)
|
||||
(define final (TM-final T))
|
||||
(define rules (TM-rules T))
|
||||
(define rule 0)
|
||||
(define numstates (vector-length (TM-states T)))
|
||||
;; set current state vars
|
||||
(define pos (TM-pos T))
|
||||
(define state (TM-state T))
|
||||
(define tape (TM-tape T))
|
||||
|
||||
(when (and (zero? state) (= pos (TM-mem T)))
|
||||
(writeln 'Starting (TM-name T))
|
||||
(TM-trace T tape pos 0 count))
|
||||
|
||||
(while (and (!= state final) (< count maxsteps))
|
||||
(++ count)
|
||||
;; The machine
|
||||
(set! rule [rules (rule-idx state [tape pos] numstates)])
|
||||
(when (= rule 0) (error "missing rule" (list state [tape pos])))
|
||||
(vector-set! tape pos [rule 0])
|
||||
(set! state [rule 2])
|
||||
(+= pos [rule 1])
|
||||
;; end machine
|
||||
(when verbose (TM-trace T tape pos state count )))
|
||||
;; save TM state
|
||||
(set-TM-pos! T pos)
|
||||
(set-TM-state! T state)
|
||||
(when (= final state) (writeln 'Stopping (TM-name T) 'at-pos (- pos (TM-mem T))))
|
||||
count)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
(define steps 0)
|
||||
(define (TM-task T)
|
||||
(define count (TM-run T #f 1000000))
|
||||
(when (zero? steps) (writeln 'START (date)))
|
||||
(+= steps count)
|
||||
(writeln 'TM-steps steps (date))
|
||||
(when (zero? count) (writeln 'END steps (date)))
|
||||
(if (zero? count) #f T)) ;; return #f to signal end of task
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import strutils, tables
|
||||
|
||||
proc runUTM(state, halt, blank: string, tape: seq[string] = @[],
|
||||
rules: seq[seq[string]]) =
|
||||
var
|
||||
st = state
|
||||
pos = 0
|
||||
tape = tape
|
||||
rulesTable = initTable[tuple[s0, v0: string], tuple[v1, dr, s1: string]]()
|
||||
|
||||
if tape.len == 0: tape = @[blank]
|
||||
if pos < 0: pos += tape.len
|
||||
assert pos in 0..tape.high
|
||||
|
||||
for r in rules:
|
||||
assert r.len == 5
|
||||
rulesTable[(r[0], r[1])] = (r[2], r[3], r[4])
|
||||
|
||||
while true:
|
||||
stdout.write st,'\t'
|
||||
for i, v in tape:
|
||||
if i == pos: stdout.write '[',v,']'
|
||||
else: stdout.write ' ',v,' '
|
||||
echo ""
|
||||
|
||||
if st == halt: break
|
||||
if not rulesTable.hasKey((st, tape[pos])): break
|
||||
|
||||
let (v1, dr, s1) = rulesTable[(st, tape[pos])]
|
||||
tape[pos] = v1
|
||||
if dr == "left":
|
||||
if pos > 0: dec pos
|
||||
else: tape.insert blank
|
||||
if dr == "right":
|
||||
inc pos
|
||||
if pos >= tape.len: tape.add blank
|
||||
st = s1
|
||||
|
||||
echo "incr machine\n"
|
||||
runUTM(halt = "qf",
|
||||
state = "q0",
|
||||
tape = "1 1 1".split,
|
||||
blank = "B",
|
||||
rules = @["q0 1 1 right q0".split,
|
||||
"q0 B 1 stay qf".split])
|
||||
|
||||
echo "\nbusy beaver\n"
|
||||
runUTM(halt = "halt",
|
||||
state = "a",
|
||||
blank = "0",
|
||||
rules = @["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])
|
||||
|
||||
echo "\nsorting test\n"
|
||||
runUTM(halt = "STOP",
|
||||
state = "A",
|
||||
blank = "0",
|
||||
tape = "2 2 2 1 2 2 1 2 1 2 1 2 1 2".split,
|
||||
rules = @["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])
|
||||
152
Task/Universal-Turing-machine/PHL/universal-turing-machine.phl
Normal file
152
Task/Universal-Turing-machine/PHL/universal-turing-machine.phl
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
module turing;
|
||||
|
||||
extern printf;
|
||||
|
||||
struct @Command {
|
||||
field @Integer tape {get:tape,set:stape};
|
||||
field @Integer move {get:move,set:smove};
|
||||
field @Integer next {get:next,set:snext};
|
||||
|
||||
@Command init(@Integer tape, @Integer move, @Integer next) [
|
||||
this.stape(tape);
|
||||
this.smove(move);
|
||||
this.snext(next);
|
||||
return this;
|
||||
]
|
||||
};
|
||||
|
||||
doc 2 dimansional array structure;
|
||||
|
||||
struct @Rules {
|
||||
|
||||
field @Integer maxstates { get: maxstates, set: smaxstates };
|
||||
field @Integer maxvalue { get: maxvalue, set: smaxvalue };
|
||||
|
||||
field @Array<@Array<@Command> > table {get: t, set: st};
|
||||
|
||||
@Rules init(@Integer states, @Integer values)
|
||||
[
|
||||
this.smaxstates(states);
|
||||
this.smaxvalue(values);
|
||||
this.st(new @Array<@Array<@Command> >.init(states));
|
||||
return this;
|
||||
]
|
||||
|
||||
@Void setRule(@Integer state, @Integer tape, @Command command)
|
||||
[
|
||||
if (null == this::t.get(state)) {
|
||||
this::t.set(state, new @Array<@Command>.init(this::maxvalue));
|
||||
}
|
||||
this::t.get(state).set(tape, command);
|
||||
]
|
||||
|
||||
@Command getRule(@Integer state, @Integer tape)
|
||||
[
|
||||
return this::t.get(state).get(tape);
|
||||
]
|
||||
|
||||
};
|
||||
|
||||
@Void emulateTuring(@Rules rules, @Integer start, @Integer stop, @Array<@Integer> tape, @Integer blank) [
|
||||
var tapepointer = 0;
|
||||
var state = start;
|
||||
|
||||
doc output;
|
||||
printf("Tape\tState\n");
|
||||
|
||||
while (state != stop) {
|
||||
doc add more cells to the tape;
|
||||
if (tapepointer == tape::size) tape.add(blank);
|
||||
if (tapepointer == 0-1) { tape = (new @Array<@Integer>..blank).addAll(tape); tapepointer = 0; }
|
||||
|
||||
doc output;
|
||||
for (var i = 0; i < tape::size; i=i+1) {
|
||||
printf("%i", tape.get(i));
|
||||
}
|
||||
printf("\t%i\n", state);
|
||||
for (var i = 0; i < tapepointer; i=i+1) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("^\n");
|
||||
|
||||
doc the value of the current cell;
|
||||
var tapeval = tape.get(tapepointer);
|
||||
|
||||
doc the current state;
|
||||
var command = rules.getRule(state, tapeval);
|
||||
|
||||
tape.set(tapepointer, command::tape);
|
||||
tapepointer = tapepointer + command::move;
|
||||
state = command::next;
|
||||
}
|
||||
|
||||
doc output;
|
||||
for (var i = 0; i < tape::size; i=i+1) {
|
||||
printf("%i", tape.get(i));
|
||||
}
|
||||
printf("\t%i\n", state);
|
||||
for (var i = 0; i < tapepointer; i=i+1) {
|
||||
printf(" ");
|
||||
}
|
||||
printf("^\n");
|
||||
]
|
||||
|
||||
@Integer main [
|
||||
|
||||
doc incrementer;
|
||||
|
||||
doc 2 states, 2 symbols;
|
||||
|
||||
var rules = new @Rules.init(2, 2);
|
||||
|
||||
doc q0, 1 -> 1, right, q0;
|
||||
doc q0, B -> 1, stay, qf;
|
||||
|
||||
rules.setRule(0, 1, new @Command.init(1, 1, 0));
|
||||
rules.setRule(0, 0, new @Command.init(1, 0, 1));
|
||||
|
||||
doc tape = [1, 1, 1];
|
||||
|
||||
var tape = new @Array<@Integer>..1..1..1;
|
||||
|
||||
doc start turing machine;
|
||||
|
||||
emulateTuring(rules, 0, 1, tape, 0);
|
||||
|
||||
doc ---------------------------------------------------;
|
||||
|
||||
doc three state busy beaver;
|
||||
|
||||
doc 4 states, 2 symbols;
|
||||
|
||||
rules = new @Rules.init(4, 2);
|
||||
|
||||
doc 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
|
||||
;
|
||||
|
||||
doc a = 0,
|
||||
b = 1,
|
||||
c = 2,
|
||||
halt = 3;
|
||||
|
||||
rules.setRule(0, 0, new @Command.init(1, 1, 1));
|
||||
rules.setRule(0, 1, new @Command.init(1, 0-1, 2));
|
||||
rules.setRule(1, 0, new @Command.init(1, 0-1, 0));
|
||||
rules.setRule(1, 1, new @Command.init(1, 1, 1));
|
||||
rules.setRule(2, 0, new @Command.init(1, 0-1, 1));
|
||||
rules.setRule(2, 1, new @Command.init(1, 0, 3));
|
||||
|
||||
doc tape = [];
|
||||
|
||||
tape = new @Array<@Integer>;
|
||||
|
||||
doc start turing machine;
|
||||
|
||||
emulateTuring(rules, 0, 3, tape, 0);
|
||||
return 0;
|
||||
]
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
//region Imports
|
||||
|
||||
import <Utilities/Conversion.sl>;
|
||||
import <Utilities/Sequence.sl>;
|
||||
|
||||
//endregion
|
||||
|
||||
//region Types
|
||||
|
||||
MCONFIG ::= (Label: char(1), Symbols: char(2), Operations: char(2), FinalConfig: char(1));
|
||||
STATE ::= (CurrentConfig: char(1), CurrentPosition: int(0), Tape: char(1));
|
||||
INPUT_DATA ::= (Iterations: int(0), InitialTape: char(1), StartingPosition: int(0), InitialConfig: char(1), MConfigs: MCONFIG(1));
|
||||
|
||||
//endregion
|
||||
|
||||
//region Constants
|
||||
|
||||
SPACE_CHAR := '_';
|
||||
DELIMITTER := '|';
|
||||
|
||||
NULL_CONFIG := (Label: "", Symbols: [], Operations: [], FinalConfig: "");
|
||||
|
||||
TRACE_HEADER := ["Config:\t| Place:\t| Tape:"];
|
||||
|
||||
//endregion
|
||||
|
||||
//region Helpers
|
||||
|
||||
StateToString(state(0)) :=
|
||||
state.CurrentConfig ++
|
||||
" \t\t| " ++ intToString(state.CurrentPosition) ++
|
||||
" \t| " ++ state.Tape;
|
||||
|
||||
StateToArrowString(state(0)) :=
|
||||
state.Tape ++ "\n" ++
|
||||
duplicate(' ', state.CurrentPosition - 1) ++ "|\n" ++
|
||||
duplicate(' ', state.CurrentPosition - 1) ++ state.CurrentConfig ++ "\n";
|
||||
|
||||
HeadOfEach(strings(2))[i] :=
|
||||
head(strings[i]);
|
||||
|
||||
RemoveCharacter(character(0), string(1))[i] :=
|
||||
string[i] when not(string[i] = character);
|
||||
|
||||
GetFSquares(Tape(1))[i] :=
|
||||
Tape[i] when (i mod 2) = 1;
|
||||
|
||||
//endregion
|
||||
|
||||
//region Parsing
|
||||
|
||||
ParseConfig(Line(1)) :=
|
||||
let
|
||||
entries := split(Line, DELIMITTER);
|
||||
label := entries[1];
|
||||
symbols := split(entries[2], ',');
|
||||
operations := split(entries[3], ',');
|
||||
finalConfig := entries[4];
|
||||
in
|
||||
((Label: label, Symbols: symbols, Operations: operations, FinalConfig: finalConfig) when not((Line[1] = '/') and (Line[2] = '/')))
|
||||
when size(Line) > 0;
|
||||
|
||||
ParseTextFile(Text(1)) :=
|
||||
let
|
||||
noSpaces := RemoveCharacter('\t', RemoveCharacter('\r', RemoveCharacter(' ', Text)));
|
||||
lines := split(noSpaces, '\n');
|
||||
iterations := stringToInt(lines[1]);
|
||||
initialTape := lines[2];
|
||||
initialPosition := stringToInt(lines[3]);
|
||||
initialConfig := lines[4];
|
||||
mConfigs := ParseConfig(lines[5 ... size(lines)]);
|
||||
in
|
||||
(Iterations: iterations, InitialTape: initialTape, StartingPosition: initialPosition, InitialConfig: initialConfig, MConfigs: mConfigs);
|
||||
|
||||
//endregion
|
||||
|
||||
//region Config Finding
|
||||
|
||||
Matches: char(0) * char(2) -> bool;
|
||||
Matches(currentSymbol(0), symbols(2)) :=
|
||||
true when size(symbols) = 0 //some(equalListNT("", symbols))
|
||||
else
|
||||
true when currentSymbol = SPACE_CHAR and some(equalListNT("none", symbols))
|
||||
else
|
||||
true when not(currentSymbol = SPACE_CHAR) and some(equalListNT("any", symbols))
|
||||
else
|
||||
true when some(currentSymbol = HeadOfEach(symbols))
|
||||
else
|
||||
false;
|
||||
|
||||
GetCurrentSymbol(State(0)) :=
|
||||
State.Tape[State.CurrentPosition] when size(State.Tape) >= State.CurrentPosition and State.CurrentPosition > 0
|
||||
else
|
||||
SPACE_CHAR;
|
||||
|
||||
GetConfigHelper(label(1), symbol(0), mConfigs(1))[i] :=
|
||||
mConfigs[i] when equalList(mConfigs[i].Label, label) and Matches(symbol, mConfigs[i].Symbols);
|
||||
|
||||
GetConfig(label(1), symbol(0), mConfigs(1)) :=
|
||||
let
|
||||
searchResults := GetConfigHelper(label, symbol, mConfigs);
|
||||
in
|
||||
NULL_CONFIG when size(searchResults) = 0
|
||||
else
|
||||
searchResults[1];
|
||||
|
||||
//endregion
|
||||
|
||||
//region Operations
|
||||
|
||||
TrimTapeEnd(tape(1), position(0)) :=
|
||||
tape when position = size(tape)
|
||||
else
|
||||
tape when not(last(tape) = SPACE_CHAR)
|
||||
else
|
||||
TrimTapeEnd(allButLast(tape), position);
|
||||
|
||||
ApplyOperations(State(0), Operations(2)) :=
|
||||
let
|
||||
newState := ApplyOperation(State, head(Operations));
|
||||
in
|
||||
State when size(Operations) = 0
|
||||
else
|
||||
ApplyOperations(newState, tail(Operations));
|
||||
|
||||
ApplyOperation(State(0), Operation(1)) :=
|
||||
let
|
||||
newTape :=
|
||||
PrintOperation(head(tail(Operation)), State.CurrentPosition, State.Tape) when head(Operation) = 'P'
|
||||
else
|
||||
EraseOperation(State.CurrentPosition, State.Tape) when head(Operation) = 'E'
|
||||
else
|
||||
[SPACE_CHAR] ++ State.Tape when head(Operation) = 'L' and State.CurrentPosition = 1
|
||||
else
|
||||
State.Tape ++ [SPACE_CHAR] when head(Operation) = 'R' and State.CurrentPosition = size(State.Tape)
|
||||
else
|
||||
State.Tape;
|
||||
|
||||
newPosition :=
|
||||
1 when head(Operation) = 'L' and State.CurrentPosition = 1
|
||||
else
|
||||
State.CurrentPosition + 1 when head(Operation) = 'R'
|
||||
else
|
||||
State.CurrentPosition - 1 when head(Operation) = 'L'
|
||||
else
|
||||
State.CurrentPosition;
|
||||
|
||||
trimmedTape := TrimTapeEnd(newTape, newPosition);
|
||||
in
|
||||
State when size(Operation) = 0
|
||||
else
|
||||
(CurrentPosition: newPosition, Tape: trimmedTape);
|
||||
|
||||
PrintOperation(Symbol(0), Position(0), Tape(1)) :=
|
||||
let
|
||||
diff := Position - size(Tape) when Position > size(Tape) else 0;
|
||||
expandedTape := Tape ++ duplicate(SPACE_CHAR, diff);
|
||||
finalTape := setElementAt(expandedTape, Position, Symbol);
|
||||
in
|
||||
finalTape;
|
||||
|
||||
EraseOperation(Position(0), Tape(1)) :=
|
||||
PrintOperation(SPACE_CHAR, Position, Tape);
|
||||
|
||||
//endregion
|
||||
|
||||
//region Execution
|
||||
|
||||
RunMachine(Text(1), Flag(1)) :=
|
||||
let
|
||||
input := ParseTextFile(Text);
|
||||
initialState := (CurrentConfig: input.InitialConfig, CurrentPosition: input.StartingPosition, Tape: input.InitialTape);
|
||||
|
||||
processed := Process(initialState, input.MConfigs, input.Iterations);
|
||||
processedWithTrace := ProcessWithTrace(initialState, input.MConfigs, input.Iterations);
|
||||
in
|
||||
"\n" ++ delimit(TRACE_HEADER ++ StateToString(processedWithTrace), '\n') when equalList(Flag, "trace")
|
||||
else
|
||||
"\n" ++ delimit(StateToArrowString(processedWithTrace), '\n') when equalList(Flag, "arrow-trace")
|
||||
else
|
||||
processed.Tape when equalList(Flag, "tape")
|
||||
else
|
||||
TrimTapeEnd(GetFSquares(processed.Tape), 1) when equalList(Flag, "f-squares")
|
||||
else
|
||||
boolToString(DoesMachineHalt(initialState, input.MConfigs, input.Iterations)) when equalList(Flag, "halts")
|
||||
else
|
||||
StateToString(processed);
|
||||
|
||||
DoesMachineHalt(InitialState(0), mConfigs(1), Iterations(0)) :=
|
||||
let
|
||||
resultState := Process(InitialState, mConfigs, Iterations);
|
||||
in
|
||||
equalList(resultState.CurrentConfig, "halt");
|
||||
|
||||
ProcessWithTrace(InitialState(0), mConfigs(1), Iterations(0)) :=
|
||||
[InitialState] when Iterations <= 0 or size(InitialState.CurrentConfig) = 0 or equalList(InitialState.CurrentConfig, "halt")
|
||||
else
|
||||
[InitialState] ++ ProcessWithTrace(Iterate(InitialState, mConfigs), mConfigs, Iterations - 1);
|
||||
|
||||
Process(InitialState(0), mConfigs(1), Iterations(0)) :=
|
||||
InitialState when Iterations = 0 or size(InitialState.CurrentConfig) = 0 or equalList(InitialState.CurrentConfig, "halt")
|
||||
else
|
||||
Process(Iterate(InitialState, mConfigs), mConfigs, Iterations - 1);
|
||||
|
||||
Iterate(State(0), mConfigs(1)) :=
|
||||
let
|
||||
currentConfig := GetConfig(State.CurrentConfig, GetCurrentSymbol(State), mConfigs);
|
||||
newState := Execute(State, currentConfig);
|
||||
in
|
||||
newState;
|
||||
|
||||
Execute(State(0), mConfig(0)) :=
|
||||
let
|
||||
newState := ApplyOperations(State, mConfig.Operations);
|
||||
in
|
||||
(CurrentConfig: mConfig.FinalConfig, CurrentPosition: newState.CurrentPosition, Tape: newState.Tape);
|
||||
|
||||
//endregion
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <cerrno>
|
||||
#include "SL_Generated.h"
|
||||
|
||||
int cores = 0;
|
||||
string fileName = "../../INPUT/irrational.tm";
|
||||
string flag = "tape";
|
||||
string fileContents = "";
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::string get_file_contents(const char *filename);
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
if(argc >= 2)
|
||||
{
|
||||
fileName = argv[1];
|
||||
}
|
||||
|
||||
if(argc >= 3)
|
||||
{
|
||||
flag = argv[2];
|
||||
}
|
||||
|
||||
if(argc >= 4)
|
||||
{
|
||||
cores = atoi(argv[3]);
|
||||
}
|
||||
|
||||
int flagDims[] = { flag.length(), 0};
|
||||
Sequence<char> flagSeq((void*)(flag.c_str()), flagDims);
|
||||
|
||||
fileContents = get_file_contents(fileName.c_str());
|
||||
int inputDims[] = { fileContents.length(), 0};
|
||||
Sequence<char> input((void*)(fileContents.c_str()), inputDims);
|
||||
|
||||
Sequence<char> result;
|
||||
|
||||
sl_init(cores);
|
||||
|
||||
sl_RunMachine(input, flagSeq, cores, result);
|
||||
|
||||
cout<<result<<endl;
|
||||
|
||||
sl_done();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string get_file_contents(const char *filename)
|
||||
{
|
||||
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
||||
if (in)
|
||||
{
|
||||
std::string contents;
|
||||
in.seekg(0, std::ios::end);
|
||||
contents.resize(in.tellg());
|
||||
in.seekg(0, std::ios::beg);
|
||||
in.read(&contents[0], contents.size());
|
||||
in.close();
|
||||
return(contents);
|
||||
}
|
||||
throw(errno);
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
func run_utm(state="", blank="", rules=[], tape=[blank], halt="", pos=0) {
|
||||
|
||||
if (pos < 0) {
|
||||
pos += tape.len;
|
||||
}
|
||||
|
||||
if (pos !~ tape.range) {
|
||||
die "Bad initial position";
|
||||
}
|
||||
|
||||
loop {
|
||||
print "#{state}\t";
|
||||
tape.range.each { |i|
|
||||
var v = tape[i];
|
||||
print (i == pos ? "[#{v}]" : " #{v} ");
|
||||
};
|
||||
print "\n";
|
||||
|
||||
if (state == halt) {
|
||||
break;
|
||||
}
|
||||
|
||||
rules.each { |rule|
|
||||
var (s0, v0, v1, dir, s1) = rule...;
|
||||
if ((s0 != state) || (tape[pos] != v0)) {
|
||||
next;
|
||||
}
|
||||
|
||||
tape[pos] = v1;
|
||||
|
||||
given(dir) {
|
||||
when ('left') {
|
||||
if (pos == 0) { tape.unshift(blank) }
|
||||
else { --pos };
|
||||
}
|
||||
when ('right') {
|
||||
if (++pos >= tape.len) {
|
||||
tape.append(blank)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state = s1;
|
||||
goto :NEXT;
|
||||
}
|
||||
|
||||
die 'No matching rules';
|
||||
@:NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
print "incr machine\n";
|
||||
run_utm(
|
||||
halt: 'qf',
|
||||
state: 'q0',
|
||||
tape: %w(1 1 1),
|
||||
blank: 'B',
|
||||
rules: [
|
||||
%w(q0 1 1 right q0),
|
||||
%w(q0 B 1 stay qf),
|
||||
]);
|
||||
|
||||
say "\nbusy beaver";
|
||||
run_utm(
|
||||
halt: 'halt',
|
||||
state: 'a',
|
||||
blank: '0',
|
||||
rules: [
|
||||
%w(a 0 1 right b),
|
||||
%w(a 1 1 left c),
|
||||
%w(b 0 1 left a),
|
||||
%w(b 1 1 right b),
|
||||
%w(c 0 1 left b),
|
||||
%w(c 1 1 stay halt),
|
||||
]);
|
||||
|
||||
say "\nsorting test";
|
||||
run_utm(
|
||||
halt: 'STOP',
|
||||
state: 'A',
|
||||
blank: '0',
|
||||
tape: %w(2 2 2 1 2 2 1 2 1 2 1 2 1 2),
|
||||
rules: [
|
||||
%w(A 1 1 right A),
|
||||
%w(A 2 3 right B),
|
||||
%w(A 0 0 left E),
|
||||
%w(B 1 1 right B),
|
||||
%w(B 2 2 right B),
|
||||
%w(B 0 0 left C),
|
||||
%w(C 1 2 left D),
|
||||
%w(C 2 2 left C),
|
||||
%w(C 3 2 left E),
|
||||
%w(D 1 1 left D),
|
||||
%w(D 2 2 left D),
|
||||
%w(D 3 1 right A),
|
||||
%w(E 1 1 left E),
|
||||
%w(E 0 0 right STOP),
|
||||
]);
|
||||
Loading…
Add table
Add a link
Reference in a new issue