How to simplest Turing Machine works on postgreSQL

yuyabu - Feb 7 '19 - - Dev Community

version

postgres:10.6

postgres=# SELECT version();
 PostgreSQL 10.6 (Ubuntu 10.6-0ubuntu0.18.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0, 64-bit
Enter fullscreen mode Exit fullscreen mode

Preface

I found interesting post about SQL is Turing complete.

http://blog.coelho.net/database/2013/08/17/turing-sql-1.html

This site try to emulate Turing machine on SQL.

This is table definition.

CREATE TABLE State(    -- TM states
  sid INTEGER PRIMARY KEY,    -- 0 is always the initial state
  isFinal BOOLEAN NOT NULL,
  sname TEXT UNIQUE NOT NULL -- just for show
);

CREATE TABLE Symbol( -- TM symbols
  cid INTEGER PRIMARY KEY,  -- 0 is always the blank symbol
  cname TEXT UNIQUE NOT NULL
);

CREATE TABLE Transition( -- TM transition function
  sid INTEGER NOT NULL REFERENCES State,     -- initial state
  symbol INTEGER NOT NULL REFERENCES Symbol, -- & symbol
  UNIQUE(sid, symbol),
  new_state INTEGER NOT NULL REFERENCES State,
  new_symbol INTEGER NOT NULL REFERENCES Symbol,
  move INTEGER NOT NULL CHECK(move=-1 OR move=1)
);

CREATE TABLE Tape( -- TM initial tape contents
  tid INTEGER PRIMARY KEY,
  symbol INTEGER REFERENCES Symbol
);

Enter fullscreen mode Exit fullscreen mode

This is execution query.

WITH RECURSIVE running(rid, sid, tape, pos) AS (
  -- first store initial tape contents
  SELECT 0, 0, ARRAY(SELECT symbol FROM Tape ORDER BY tid), 1
  UNION
  -- then proceed to compute iterations
  SELECT p.rid+1, t.new_state,
         -- build updated tape as an array
         p.tape[1:p.pos-1] ||                      -- prefix
           t.new_symbol ||                         -- updated cell
           p.tape[p.pos+1:array_length(p.tape,1)], -- suffix
         -- move cursor position
         p.pos+t.move
  FROM running AS p
  -- get state details, to know whether to stop
  JOIN State AS s ON (p.sid=s.sid)
  -- get corresponding state transition
  JOIN Transition AS t ON (t.sid=p.sid AND
                           -- coalesce defaults to blank
                           t.symbol=COALESCE(p.tape[p.pos],0))
  WHERE -- stop on a final state
        NOT s.isFinal
)
-- just store the computed table
INSERT INTO Run
  SELECT * FROM running;
Enter fullscreen mode Exit fullscreen mode

But It didn't work with queries in that site only.

ERROR:  insert or update on table "run" violates foreign key constraint "run_sid_fkey"
DETAIL:  Key (sid)=(0) is not present in table "state".
Enter fullscreen mode Exit fullscreen mode

Because this post has only the table definition(create statement) and no machine data(insert statement)

So I need data of Turing Machine.

note:I found out later that CTS(Cyclic Tag System) data is written here.
https://wiki.postgresql.org/wiki/Turing_Machine_(with_recursive)

(2,3) Turing machine

This time,I choose most simplest Turing machine called "Wolfram's 2-state 3-symbol Turing machine"

https://www.wolframscience.com/prizes/tm23/technicaldetails.html

This Turing machine has 2 satate({1,2}) and 3 Symbol({2,1,0}).

{state, color} -> {next_state, next_color, offset(header position)}

{1, 2} -> {1, 1, -1},
{1, 1} -> {1, 2, -1},
{1, 0} -> {2, 1, 1 },
{2, 2} -> {1, 0, 1 },
{2, 1} -> {2, 2, 1 },
{2, 0} -> {1, 2, -1}
Enter fullscreen mode Exit fullscreen mode

I check this on paper, and make DB record.

paper

INSERT INTO State VALUES(0,FALSE,1),(1,FALSE,2); 
INSERT INTO Symbol VALUES(0,'0'),(1,'1'),(2,'2');
INSERT INTO Transition VALUES
(0,2,0,1,-1),
(0,1,0,2,-1),
(0,0,1,1, 1),
(1,2,0,0, 1),
(1,1,1,2, 1),
(1,0,0,2,-1)

INSERT INTO Tape VALUES(0,0);
Enter fullscreen mode Exit fullscreen mode

(2,3)Turing machine don't have halt state.

Note that there is no halt state for this Turing machine.

Execution query assumes the existence of a halt state,I need change execution query.

WITH RECURSIVE running(rid, sid, tape, pos) AS (
  -- first store initial tape contents
  SELECT 0, 0, ARRAY(SELECT symbol FROM Tape ORDER BY tid), 1
  UNION
  -- then proceed to compute iterations
  SELECT p.rid+1, t.new_state,
         -- build updated tape as an array
         p.tape[1:p.pos-1] ||                      -- prefix
           t.new_symbol ||                         -- updated cell
           p.tape[p.pos+1:array_length(p.tape,1)], -- suffix
         -- move cursor position
         p.pos+t.move
  FROM running AS p
  -- get state details, to know whether to stop
  JOIN State AS s ON (p.sid=s.sid)
  -- get corresponding state transition
  JOIN Transition AS t ON (t.sid=p.sid AND
                           -- coalesce defaults to blank
                           t.symbol=COALESCE(p.tape[p.pos],0))
  WHERE -- stop on a final state
        --NOT s.isFinal -- There is no halt state.
        NOT p.rid = 100 -- By changing this number 
                        -- you can set the number of generations of cellular automata on tape.
)
-- just store the computed table
INSERT INTO Run
  SELECT * FROM running;
Enter fullscreen mode Exit fullscreen mode

Result

Execution result is here.

rid sid tape pos
0 0 {0} 1
1 1 {1} 2
2 0 {1,2} 1
3 0 {2,2} 0
4 1 {1,2,2} 1
5 1 {2,2,2} 2
6 0 {2,0,2} 3
7 0 {2,0,1} 2
8 1 {2,1,1} 3
9 1 {2,1,2} 4
10 0 {2,1,2,2} 3
... ... ... ...
89 0 {2,2,1,1,2,2,2,1,2,2,1,2} 2
90 0 {2,1,1,1,2,2,2,1,2,2,1,2} 1
91 0 {1,1,1,1,2,2,2,1,2,2,1,2} 0
92 1 {1,1,1,1,1,2,2,2,1,2,2,1,2} 1
93 1 {2,1,1,1,1,2,2,2,1,2,2,1,2} 2
94 1 {2,2,1,1,1,2,2,2,1,2,2,1,2} 3
95 1 {2,2,2,1,1,2,2,2,1,2,2,1,2} 4
96 1 {2,2,2,2,1,2,2,2,1,2,2,1,2} 5
97 1 {2,2,2,2,2,2,2,2,1,2,2,1,2} 6
98 0 {2,2,2,2,2,0,2,2,1,2,2,1,2} 7
99 0 {2,2,2,2,2,0,1,2,1,2,2,1,2} 6
100 1 {2,2,2,2,2,1,1,2,1,2,2,1,2} 7

full version is "result.txt" on my github repository

https://github.com/yuyabu/2state-3color-turing-machine-on-sql

I convert "tape" column to image on this rule.

2 -> orange
1 -> yellowfins
0 -> white
Enter fullscreen mode Exit fullscreen mode

and after all, I made this cell automaton image.

automaton

Although the method of complementing the white cell is different, it is misaligned, but it is almost the same image as wolfram's page's.

next time

I'll try to make rule 60. Transition function of rule 60 is on NKS book.

{{1, 2} -> {2, 2, 1}, {1, 1} -> {1, 1, 1}, {1, 0} -> {3, 1, -1}, {2, 2} -> {2,1, 1}, {2, 1} -> {1, 2, 1}, {3, 2} -> {3, 2, -1}, {3, 1} -> {3, 1, -1}, {3, 0} -> {1, 0, 1}}
Enter fullscreen mode Exit fullscreen mode

https://www.wolframscience.com/nks/notes-11-12--rule-60-turing-machines/

This article is translated from my blog post(original is japanese).
http://yuyubu.hatenablog.com/entry/2019/01/15/SQL%E4%B8%8A%E3%81%A72%E7%8A%B6%E6%85%8B3%E8%A8%98%E5%8F%B7%E3%83%81%E3%83%A5%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%83%9E%E3%82%B7%E3%83%B3%E3%82%92%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%B7

. . . . . . . . .