mirror of
https://github.com/sigmasternchen/javagony2
synced 2025-03-15 03:38: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