mirror of
https://github.com/sigmasternchen/javagony2
synced 2025-03-15 11:48:54 +00:00
added turing machine
This commit is contained in:
parent
c266f4e70d
commit
c0255a9fe0
5 changed files with 365 additions and 0 deletions
4
turing/Action.java
Normal file
4
turing/Action.java
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Action {
|
||||||
|
void execute();
|
||||||
|
}
|
177
turing/Number.java
Normal file
177
turing/Number.java
Normal 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
91
turing/StateMachine.java
Normal 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
38
turing/Tape.java
Normal 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
55
turing/TuringMachine.java
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue