sql-turing-machine/turing.sql

115 lines
3.7 KiB
MySQL
Raw Normal View History

2024-09-14 19:57:10 +00:00
CREATE TABLE input (
input BYTEA
);
INSERT INTO input VALUES ('aabbbaa'::BYTEA || '\x00'::BYTEA);
CREATE TABLE program (
state INT,
read INT,
next_state INT,
write INT,
move INT,
accept BOOL DEFAULT false,
reject BOOL DEFAULT false
);
2024-09-16 19:46:19 +00:00
-- This program is a binary palindrome recognizer, using the value 'a' and 'b'.
2024-09-14 19:57:10 +00:00
INSERT INTO program VALUES
-- search right
(000, 0 , 100, 0 , 0, false, false), -- input is empty; accept
(000, ASCII('a'), 011, 0 , 1, false, false),
(000, ASCII('b'), 016, 0 , 1, false, false),
-- search right for 'a'
(011, 0 , 012, 0 , -1, false, false), -- end found
(011, ASCII('a'), 011, ASCII('a'), 1, false, false),
(011, ASCII('b'), 011, ASCII('b'), 1, false, false),
-- search right for 'a': verify value
(012, 0 , 100, 0 , 0, false, false),
(012, ASCII('a'), 001, 0 , -1, false, false),
2024-09-14 20:02:21 +00:00
(012, ASCII('b'), 101, 0 , 0, false, false), -- 'a' expected, 'b' found
2024-09-14 19:57:10 +00:00
-- search right for 'b'
(016, 0 , 017, 0 , -1, false, false), -- end found
(016, ASCII('a'), 016, ASCII('a'), 1, false, false),
(016, ASCII('b'), 016, ASCII('b'), 1, false, false),
-- search right for 'b': verify value
(017, 0 , 100, 0 , 0, false, false),
2024-09-14 20:02:21 +00:00
(017, ASCII('a'), 101, 0 , 0, false, false), -- 'b' expected, 'a' found
2024-09-14 19:57:10 +00:00
(017, ASCII('b'), 001, 0 , -1, false, false),
-- search left
(001, 0 , 100, 0 , 0, false, false), -- input is empty; accept
(001, ASCII('a'), 021, 0 , -1, false, false),
(001, ASCII('b'), 026, 0 , -1, false, false),
-- search left for 'a'
(021, 0 , 022, 0 , 1, false, false), -- end found
(021, ASCII('a'), 021, ASCII('a'), -1, false, false),
(021, ASCII('b'), 021, ASCII('b'), -1, false, false),
-- search left for 'a': verify value
(022, 0 , 100, 0 , 0, false, false),
(022, ASCII('a'), 000, 0 , 1, false, false),
2024-09-14 20:02:21 +00:00
(022, ASCII('b'), 101, 0 , 0, false, false), -- 'a' expected, 'b' found
2024-09-14 19:57:10 +00:00
-- search left for 'b'
(026, 0 , 027, 0 , 1, false, false), -- end found
(026, ASCII('a'), 026, ASCII('a'), -1, false, false),
(026, ASCII('b'), 026, ASCII('b'), -1, false, false),
-- search left for 'b': verify value
(027, 0 , 100, 0 , 0, false, false),
2024-09-14 20:02:21 +00:00
(027, ASCII('a'), 101, 0 , 0, false, false), -- 'b' expected, 'a' found
2024-09-14 19:57:10 +00:00
(027, ASCII('b'), 000, 0 , 1, false, false),
-- accept state
(100, 0 , 100, 0 , 0, true, false),
(100, ASCII('a'), 100, 0 , 0, true, false),
(100, ASCII('b'), 100, 0 , 0, true, false),
-- reject state
(101, 0 , 101, 0 , 0, false, true),
(101, ASCII('a'), 101, 0 , 0, false, true),
(101, ASCII('b'), 101, 0 , 0, false, true)
;
WITH RECURSIVE run_state (iteration, state, position, band, accept, reject) AS (
SELECT
0, 000, 0 , input, false, false
FROM input
UNION ALL
SELECT
run_state.iteration + 1,
program.next_state,
run_state.position + program.move,
set_byte(run_state.band, run_state.position, program.write),
program.accept,
program.reject
FROM run_state
INNER JOIN program
ON program.state = run_state.state
AND program.read = get_byte(run_state.band, run_state.position)
WHERE
NOT run_state.accept
AND NOT run_state.reject
)
SELECT
CASE
WHEN run.accept THEN 'Input was accepted in ' || run.iteration || ' iterations.'
WHEN run.reject THEN 'Input was rejected in ' || run.iteration || ' iterations.'
ELSE '[insert confused meme here]'
END
FROM run_state AS run
WHERE
run.accept
OR run.reject;