| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- process main {
- # Turing machine specification.
- var("B") blank;
- var([
- {"0", "0"}:{"0", "0", "right"},
- {"0", "1"}:{"1", "x", "right"},
- {"1", "1"}:{"1", "1", "right"},
- {"1", "0"}:{"2", "0", "right"},
- {"2", "0"}:{"2", "0", "right"},
- {"2", "1"}:{"3", "1", "right"},
- {"3", "1"}:{"3", "1", "right"},
- {"3", "0"}:{"4", "1", "left"},
- {"3", "B"}:{"4", "1", "left"},
- {"4", "1"}:{"4", "1", "left"},
- {"4", "0"}:{"5", "0", "left"},
- {"5", "0"}:{"5", "0", "left"},
- {"5", "1"}:{"6", "1", "left"},
- {"5", "x"}:{"h", "x", "stay"},
- {"6", "1"}:{"6", "1", "left"},
- {"6", "x"}:{"0", "x", "right"},
- {"6", "0"}:{"0", "0", "right"}
- ]) rules;
- var("0") initial_state;
- var({}) initial_tape_left;
- var({
- "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
- "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
- "0", "0",
- "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
- "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"
- }) initial_tape_right;
- # Perform the computation, stopping when no rule matches.
- call("turing", {blank, rules, initial_state, initial_tape_left, initial_tape_right}) results;
- # Check results.
- val_equal(results.tape_left, {"B"}) a;
- assert(a);
- val_equal(results.tape_right,
- {"x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x",
- "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x", "x",
- "0", "0", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
- "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
- "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
- "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1",
- "1", "1"}
- ) a;
- assert(a);
- val_equal({results.side, results.pos}, {"right", "55"}) a;
- assert(a);
- val_equal(results.state, "h") a;
- assert(a);
- exit("0");
- }
- template turing {
- alias("_arg0") blank;
- value(_arg1) rules;
- alias("_arg2") initial_state;
- alias("_arg3") initial_tape_left;
- alias("_arg4") initial_tape_right;
- # Head state.
- var(initial_state) state;
- # Tape. Positions go like this: ... L2 L1 L0 R0 R1 R2 ...
- value(initial_tape_left) tape_left;
- value(initial_tape_right) tape_right;
- # Make sure each side of the tape has at least one symbol so we can flip easily.
- tape_left->insert(tape_left.length, blank);
- tape_right->insert(tape_right.length, blank);
- # Head position.
- var("right") side;
- var("0") pos;
- # Enter loop.
- blocker() loop_blk;
- loop_blk->up();
- loop_blk->use();
- # Get symbol under head.
- concat("tape_", side) tape_name;
- alias(tape_name) cur_tape;
- cur_tape->get(pos) symbol;
- # Look for a matching rule.
- rules->try_get({state, symbol}) rule;
- If (rule.exists) {
- # Extract directions from rule.
- rule->get("0") new_state;
- rule->get("1") new_symbol;
- rule->get("2") move;
- # Change head state.
- state->set(new_state);
- # Replace symbol under head.
- cur_tape->remove(pos);
- cur_tape->insert(pos, new_symbol);
- # Branch based on how we move.
- strcmp(move, side) is_outside;
- strcmp(move, "stay") is_stay;
- strcmp(pos, "0") is_zero;
- If (is_outside) {
- # Increment position.
- num_add(pos, "1") new_pos;
- pos->set(new_pos);
- # If the new position is out of range, extend tape.
- strcmp(pos, cur_tape.length) need_extend;
- If (need_extend) {
- cur_tape->insert(pos, blank);
- };
- } elif (is_stay) {
- # Nop.
- getargs();
- } elif (is_zero) {
- # Flip side, leave pos at zero.
- side->set(move);
- } else {
- # Decrement position.
- num_subtract(pos, "1") new_pos;
- pos->set(new_pos);
- };
- # Continue loop.
- loop_blk->downup();
- };
- }
|