added turing machine

This commit is contained in:
overflowerror 2021-06-03 19:42:43 +02:00
parent c266f4e70d
commit c0255a9fe0
5 changed files with 365 additions and 0 deletions

4
turing/Action.java Normal file
View file

@ -0,0 +1,4 @@
@FunctionalInterface
public interface Action {
void execute();
}

177
turing/Number.java Normal file
View file

@ -0,0 +1,177 @@
public class Number {
private class NumberWrapper {
Number n;
}
static class Zero extends Number {
public Zero() {
super(null);
}
@Override
public void executeIfZero(Action action) {
action.execute();
}
@Override
public void executeIfNotZero(Action action) {
}
@Override
public int value() {
return 0;
}
@Override
public void executeIfEquals(Number n, Action a) {
n.executeIfZero(a);
}
}
static class NegativeNumber extends Number {
private Number positive;
public NegativeNumber(Number p) {
super(null);
positive = p;
}
@Override
public Number succ() {
NumberWrapper w = new NumberWrapper();
positive.executeIfZero(() -> {
w.n = zero().succ();
});
positive.executeIfNotZero(() -> {
w.n = new NegativeNumber(positive.pre);
});
return w.n;
}
@Override
public Number pre() {
return new NegativeNumber(positive.succ());
}
@Override
public int value() {
return -positive.value();
}
@Override
public void executeIfNegative(Action a) {
a.execute();
}
@Override
public void executeIfNotNegative(Action a) {
}
@Override
public void executeIfZero(Action a) {
positive.executeIfZero(a);
}
@Override
public void executeIfNotZero(Action a) {
positive.executeIfNotZero(a);
}
@Override
public void executeIfEquals(Number n, Action a) {
n.executeIfNegative(() -> {
positive.executeIfEquals(((NegativeNumber) n).positive, a);
});
}
@Override
public void forEach(Action a) {
positive.forEach(a);
}
}
private Number pre;
private Number(Number pre) {
this.pre = pre;
}
public static Number zero() {
return new Zero();
}
public Number succ() {
return new Number(this);
}
public void forEach(Action a) {
executeIfNotZero(() -> {
a.execute();
pre.forEach(a);
});
}
public Number add(Number n) {
NumberWrapper w = new NumberWrapper();
w.n = this;
n.executeIfNegative(() -> {
n.forEach(() -> {
w.n = w.n.pre();
});
});
n.executeIfNotNegative(() -> {
n.forEach(() -> {
w.n = w.n.succ();
});
});
return w.n;
}
public Number pre() {
NumberWrapper w = new NumberWrapper();
executeIfZero(() -> {
w.n = new NegativeNumber(succ());
});
executeIfNotZero(() -> {
w.n = pre;
});
return w.n;
}
public void executeIfZero(Action action) {
}
public void executeIfNotZero(Action action) {
action.execute();
}
public int value() {
return this.pre.value() + 1;
}
public void executeIfEquals(Number n, Action a) {
n.executeIfNotNegative(() -> {
n.executeIfNotZero(() -> {
pre.executeIfEquals(n.pre, a);
});
});
}
public void executeIfNegative(Action a) {
}
public void executeIfNotNegative(Action a) {
a.execute();
}
public String toString() {
return String.valueOf(value());
}
}

91
turing/StateMachine.java Normal file
View file

@ -0,0 +1,91 @@
public class StateMachine {
public static final Number END_STATE = Number.zero();
public static final Number READ_LEFT = END_STATE.succ();
public static final Number EXPECT_0_RIGHT = READ_LEFT.succ();
public static final Number EXPECT_0_RIGHT_CHECK = EXPECT_0_RIGHT.succ();
public static final Number EXPECT_1_RIGHT = EXPECT_0_RIGHT_CHECK.succ();
public static final Number EXPECT_1_RIGHT_CHECK = EXPECT_1_RIGHT.succ();
public static final Number READ_RIGHT = EXPECT_1_RIGHT_CHECK.succ();
public static final Number EXPECT_0_LEFT = READ_RIGHT.succ();
public static final Number EXPECT_0_LEFT_CHECK = EXPECT_0_LEFT.succ();
public static final Number EXPECT_1_LEFT = EXPECT_0_LEFT_CHECK.succ();
public static final Number EXPECT_1_LEFT_CHECK = EXPECT_1_LEFT.succ();
public static final int INITIAL_STATE = READ_LEFT.value();
public static final Number zero = Number.zero();
public static final Number one = Number.zero().succ();
public static final Number minusOne = Number.zero().pre();
public class Transition {
Number nextState;
char write;
Number move;
public Transition(Number nextState, char write, Number move) {
this.nextState = nextState;
this.write = write;
this.move = move;
}
}
private Transition table[][];
int currentState = INITIAL_STATE;
private Action onHalt;
public StateMachine(Action onHalt) {
this.onHalt = onHalt;
table = new Transition[11][256];
table[READ_LEFT.value()]['1'] = new Transition(EXPECT_1_RIGHT, ' ', one);
table[READ_LEFT.value()]['0'] = new Transition(EXPECT_0_RIGHT, ' ', one);
table[READ_LEFT.value()][' '] = new Transition(END_STATE, ' ', zero);
table[EXPECT_1_RIGHT.value()]['1'] = new Transition(EXPECT_1_RIGHT, '1', one);
table[EXPECT_1_RIGHT.value()]['0'] = new Transition(EXPECT_1_RIGHT, '0', one);
table[EXPECT_1_RIGHT.value()][' '] = new Transition(EXPECT_1_RIGHT_CHECK, ' ', minusOne);
table[EXPECT_1_RIGHT_CHECK.value()]['1'] = new Transition(READ_RIGHT, ' ', minusOne);
table[EXPECT_1_RIGHT_CHECK.value()]['0'] = new Transition(EXPECT_1_RIGHT_CHECK, ' ', zero);
table[EXPECT_1_RIGHT_CHECK.value()][' '] = new Transition(EXPECT_1_RIGHT_CHECK, ' ', zero); // loop endless
table[EXPECT_0_RIGHT.value()]['1'] = new Transition(EXPECT_0_RIGHT, '1', one);
table[EXPECT_0_RIGHT.value()]['0'] = new Transition(EXPECT_0_RIGHT, '0', one);
table[EXPECT_0_RIGHT.value()][' '] = new Transition(EXPECT_0_RIGHT_CHECK, ' ', minusOne);
table[EXPECT_0_RIGHT_CHECK.value()]['0'] = new Transition(READ_RIGHT, ' ', minusOne);
table[EXPECT_0_RIGHT_CHECK.value()]['1'] = new Transition(EXPECT_0_RIGHT_CHECK, ' ', zero);
table[EXPECT_0_RIGHT_CHECK.value()][' '] = new Transition(EXPECT_0_RIGHT_CHECK, ' ', zero); // loop endless
table[READ_RIGHT.value()]['1'] = new Transition(EXPECT_1_LEFT, ' ', minusOne);
table[READ_RIGHT.value()]['0'] = new Transition(EXPECT_0_LEFT, ' ', minusOne);
table[READ_RIGHT.value()][' '] = new Transition(END_STATE, ' ', zero);
table[EXPECT_1_LEFT.value()]['1'] = new Transition(EXPECT_1_LEFT, '1', minusOne);
table[EXPECT_1_LEFT.value()]['0'] = new Transition(EXPECT_1_LEFT, '0', minusOne);
table[EXPECT_1_LEFT.value()][' '] = new Transition(EXPECT_1_LEFT_CHECK, ' ', one);
table[EXPECT_1_LEFT_CHECK.value()]['1'] = new Transition(READ_LEFT, ' ', one);
table[EXPECT_1_LEFT_CHECK.value()]['0'] = new Transition(EXPECT_1_LEFT_CHECK, ' ', zero);
table[EXPECT_1_LEFT_CHECK.value()][' '] = new Transition(EXPECT_1_LEFT_CHECK, ' ', zero); // loop endless
table[EXPECT_0_LEFT.value()]['1'] = new Transition(EXPECT_0_LEFT, '1', minusOne);
table[EXPECT_0_LEFT.value()]['0'] = new Transition(EXPECT_0_LEFT, '0', minusOne);
table[EXPECT_0_LEFT.value()][' '] = new Transition(EXPECT_0_LEFT_CHECK, ' ', one);
table[EXPECT_0_LEFT_CHECK.value()]['0'] = new Transition(READ_LEFT, ' ', one);
table[EXPECT_0_LEFT_CHECK.value()]['1'] = new Transition(EXPECT_0_LEFT_CHECK, ' ', zero);
table[EXPECT_0_LEFT_CHECK.value()][' '] = new Transition(EXPECT_0_LEFT_CHECK, ' ', zero); // loop endless
}
public Transition stateChange(char input) {
Transition t = table[currentState][input];
t.nextState.executeIfZero(onHalt);
currentState = t.nextState.value();
return t;
}
}

38
turing/Tape.java Normal file
View file

@ -0,0 +1,38 @@
public class Tape {
private class CharWrapper {
char c;
}
@FunctionalInterface
private interface Cell {
char value(Number i);
}
private Cell cells;
public Tape() {
cells = (i) -> ' ';
}
public char get(Number i) {
return cells.value(i);
}
public void set(Number i, char c) {
final Cell _cells = cells;
cells = (j) -> {
CharWrapper w = new CharWrapper();
w.c = _cells.value(j);
j.executeIfEquals(i, () -> {
w.c = c;
});
return w.c;
};
}
}

55
turing/TuringMachine.java Normal file
View file

@ -0,0 +1,55 @@
public class TuringMachine {
private Tape tape;
private StateMachine sm;
private Number position;
public TuringMachine() {
tape = new Tape();
sm = new StateMachine(() -> {
System.out.println("halted");
System.exit(0);
});
position = Number.zero();
Number n = Number.zero();
tape.set(n, '0');
n = n.succ();
tape.set(n, '1');
n = n.succ();
tape.set(n, '1');
n = n.succ();
tape.set(n, '0');
n = n.succ();
tape.set(n, '0');
n = n.succ();
tape.set(n, '1');
n = n.succ();
tape.set(n, '1');
n = n.succ();
tape.set(n, '0');
}
public void step() {
Number oldPosition = position;
char in = tape.get(position);
int state = sm.currentState;
StateMachine.Transition t = sm.stateChange(in);
tape.set(position, t.write);
position = position.add(t.move);
//System.out.println(state + ", " + oldPosition + ", " + in + " -> " + t.nextState + ", " + t.write + ", " + position);
step();
}
public void run() {
step();
}
public static void main(String[] args) {
TuringMachine tm = new TuringMachine();
tm.run();
}
}