Etoysで作るチューリング機械シミュレータ

チューリング機械のシミュレータはいろいろ作られているが,ここではSqueak Etoysのテキストオブジェクトを利用したシミュレータを作成する。

1. チューリング機械Mは,本体とテープ及びテープから記号を読んだり書いたりするヘッドからなっている.
2. テープは両側に無限に延びていて,ます目に区切られている.また各マス目にはあらかじめ定められた有限個の入力アルファベット記号を一つだけ書くことができる.
3. テープには最初有限の長さの記号列が書かれ,その両側には無限に空白記号が書かれている.
4. 本体は各瞬間に有限種類の状態のうちのいずれか1つの状態にある.
5. Mは各瞬間にヘッドの下にあるテープのます目に着目しており,ヘッドによってそこに書いてある記号を読みとって本体へ送る.Mは本体の現在の状態と送られてきたテープ記号に応じて,本体の状態を他に変えて(同じ状態のままでもよい)現在着目している記号を書き換える(書き込む記号はあらかじめ決められた有限個の記号の中から選ぶ.同じ記号で書き換えてもよい).次にヘッドを1ます分左に動かすか(Lで記す),右に動かす(Rで記す).

5で述べたような,現在の状態 sとテープ記号cに対し,次の瞬間に状態をt に変え,cをdに書き換え,ヘッドの移動(左,右)を行う規則をscdmt (ただし,mはRかL)と表現し,このチューリング機械の基本操作と呼ぶ.基本操作をどのように定めるかは,実行したい計算による.記号や状態の集合はいずれも有限であるから,これらの基本操作も高々有限個である.

本体の動作は初期状態と呼ばれる状態からヘッドをテープ上の指定されたます目において開始し,停止状態と呼ばれる状態になったとき停止する.停止状態は複数あってもよい.

テキストオブジェクトを用いて,本体・テープ・基本操作を表す

フラップの部品からテキストオブジェクトを三つ取り出す。

それぞれ本体,テープ,基本操作と名前を付ける。

初期状態は記号sであらわすことにする。本体の文字列をsに書き換えておく。テープは横長に使うので黄ハロを用いて大きくする。文字列はとりあえずbbbbbbにしておく(なんでもよい)。

本体の状態を表す変数を作成

次に本体のビューワを出して,新たに変数を作成する。変数の作成はビューワ上部のVボタンを押すとできる。

変数のNameは状態,Typeは文字列にしてAcceptする。

基本操作を解釈してチューリング機械の動作を行うスクリプトの作成

次にチューリング機械の基本操作を読み込んで動く部分のスクリプトの作成である。スクリプトは基本操作のスクリプトとして作成する。

本体が読んでいるテープの位置はテキストのカーソル位置を用いる。カーソル位置は文字文書カテゴリの中にあるタイルを利用する。

スクリプト本体(詳細は下で説明)

スクリプトは本体の状態と現在見ているテープ記号にマッチする基本操作を探し,見つけたらその基本操作の定義に従って動作するようにする。また,本体の状態が停止状態(ここではhを停止状態としている)になったらスクリプトをストップする。

スクリプトの詳細

本体の状態と基本操作のカーソル位置の文字(各基本操作の先頭の文字)が等しくなければ,次の基本操作に進む。等しければ基本操作のカーソル位置に1を足して次を行う。

テープのカーソル位置の文字(本体が見ているテープ上の文字)と基本操作のカーソル位置の文字(各基本操作の2番目の文字)が等しくなければ,次の基本操作に進む。もし等しければ,探している基本操作なので,その後に書かれている情報を読んでテープの書換,ヘッドの移動,状態の遷移を行う。テープのカーソル位置の文字を基本操作で指定される文字に書換し,テープのカーソル位置をヘッドの移動に応じて1増減し,最後に本体の状態と本体の記号を書き換える。

基本操作は5文字であるが改行文字も1文字として計算するため,次の基本操作に移動するときのカーソル位置の増加数に注意する。また,カーソル位置が右端や先頭にある場合に,それぞれヘッドを右や左に動かす場合,そこには空白文字があると考えるので,空白記号のbを挿入する。「append characters」は文字列の最後,「文字列を挿入」は先頭に入れるタイルである。

本体の状態が停止状態になったらストップする

本体の状態がhになったらスクリプト「チューリング機械の実行」をストップする。

スクリプトをストップするためのタイルはスクリプティングカテゴリ内にある。

初期設定のためのスクリプトの作成

最後に初期設定のスクリプトを作る。本体から空のスクリプトを出し名前は初期設定にする。スクリプトの内容は,本体の状態をsにして,テープや基本操作のカーソル位置を先頭にもってくるものである。また,この初期設定を実行するためのボタンも用意する。ボタンの作成はスクリプト右上のメニューから「このスクリプトを実行するボタン」をクリックして取出す。

この初期設定を実行するためのボタンも用意する。ボタンの作成はスクリプト右上のメニューから「このスクリプトを実行するボタン」をクリックして取出す。

チューリング機械の動作開始用のスクリプトとボタン

チューリング機械の実行スクリプトをずっと動かすためのスクリプトとそのスクリプト用のボタンを作成する。

実行例

次の基本操作は与えられた数を3で割ったときの余りを求めるものである。ただし,ここでは自然数nを表すために1をn+1個並べた文字列をとることにする。

s1bRu
u11Rv
v11Rw
w11Ru
ubbLx
x1bLx
xb1Rh
vbbLy
y1bLy
yb1Rz
zb1Rh
wbbLp
p1bLp
pb1Rq
qb1Rr
rb1Rh

実行例はテープに7(1が8個)を書き込んで動作させる。初期設定をクリックして,スタートをクリックすると次のようにテープに1を2個残して状態が停止状態で停止する。これは7を3で割ったときの余りが1であることを表している。