たまたま、このページ(元は404になっていたので、グーグルのキャッシュ?のページより)を見つけました。
あ、
計算論 計算可能性とラムダ計算
http://www.amazon.co.jp/gp/product/product-description/4764901846
ですね(^^)/
これの、12ページ、定理1.2.1の話ですね。
任意のNプログラムに関して、whileプログラムが存在する
Nプログラムっていうのは、簡単に言うと、
・代入文(っていうか、なんか処理する文)
・条件分岐文
・入力文
・出力文
でできていて、この順番は、矢印引っ張って(有向グラフ)、どこでもいけるってもの。
つまり、これは、プログラムだと、GoTo文使って、どこでもいけるっていうこと。
一方、Whileプログラムは入れ子にはできるんだけど、入れ子が交差するようなことはできない。
いわゆる、GoToレスなプログラムですね。
つまりこれは、
あらゆるGoTo文を使ったプログラムはGoToレスなプログラムに出来る
ってことなんだけど、この証明、そのリンク先より、実務的には、もっと面白いので、ちょっと書きますね。
■方法
(1)まず、元のNプログラムをGOTO文をつかって、かきますね!
(上記の本の12ページの図3)
input x
TOP:
if ( a == true )
GOTO OUTPUT
else
b();
if ( c == true )
e();
GOTO OUTPUT
else
d();
GOTO TOP
endif
endif
OUTPUT:
output y
(2)全部の処理の頭に、ラベルを振ってください
本では、0、1と振ってあるのですが、数字だとわかりにくいので、
ZERO,ONE,TWOと、英語で振りますね。また、TOPはZERO,OUTPUTはFIVEなので、
そのように書き直します。
input x
ZERO:
if ( a == true )
GOTO FIVE
else
ONE:
b();
TWO:
if ( c == true )
FOUR:
e();
GOTO FIVE
else
TREE:
d();
GOTO ZERO
endif
endif
FIVE:
output y
(3)b()のような普通の文の場合、下の行にいきます。
IF文は、TRUEの場合、FALSEの場合で行き先が分かれます。
GOTO文が書かれていないところに対して、
普通の文ならGOTO次の処理のラベル
IF 文は GOTO TRUEのとき、GOTO FALSEのときで書き直します。
input x
GOTO ZERO
ZERO:
if ( a == true )
GOTO FIVE
else
GOTO ONE
endif
ONE:
b();
GOTO TWO:
TWO:
if ( c == true )
GOTO FOUR
ELSE
GOTO THREE
ENDIF
FOUR:
e();
GOTO FIVE
TREE:
d();
GOTO ZERO
FIVE:
output y
(4)ここで、ステータス変数u(本ではプログラムカウンタになっている)を利用しましょう。
・GOTO 何とかのところを、u = に書き換え
・それぞれのラベルをcaseにして、switch文に置き換え、
・全体をwhileでくくります。
そうすると・・・
u = START
while(u != END)
{
switch(u)
{
case START:
input x;
u=ZERO;
break;
case ZERO:
if ( a == true )
u = FIVE;
else
u = ONE;
endif
break;
case ONE:
b();
u = TWO;
break;
case TWO:
if ( c == true )
u = FOUR;
ELSE
u = THREE;
ENDIF
break;
case FOUR:
e();
u = FIVE;
break;
case TREE:
d();
u = ZERO;
break;
case FIVE:
output y
u = END;
}
}
ちゃんとしたプログラムではないけど、こんなかんじ。
■つまり、
上記のuをイベントと考えれば、上のプログラムは、まさにイベントドリブンなわけで、
結局、
GOTOを含むようなプログラムは、イベントドリブンのGOTOレスプログラムに置き換えられる
ってわけ。
イベントドリブンって、強力だよね(^^)/