はじめに
先に投稿した Poem(詩のような日本語で書いたプログラム)が好評をいただいたので調子に乗り、変わったプログラム第2弾を書きます。
経緯
だいぶ昔のことですが、日経mix という電子会議のmindの部屋で「Mind言葉遊び」というものがはやったことがありました。プログラムまがいのもので、たとえば次のようなものです。 1
牛乳とは
牛の 乳を 絞って
殺菌して 容器に 詰めたものである。
このようにMindのプログラムを装いながら適当に言葉を当てて(正しく動作するかは棚上げにして)ナンセンスを楽しむものです。
しばらくは遊びでやっていたのですが、ある時気が付き、ひょっとして走らせられるんじゃないか?と思ったのがこれを作ったきっかけです。デタラメなプログラムを書いてもそれなりに走らせてしまうものです。
仕組み
先の「牛乳」の定義を再度書きます。
牛乳とは
牛の 乳を 絞って
殺菌して 容器に 詰めたものである。
上のソースコード(?)は適当に書いたように見えますが(とはいえMindの流儀で分かち書き)Mindの文法上間違いではありません。しかしこのままコンパイラにかけると「牛」「乳」「絞」などの語が未定義語としてたくさんエラー検出されます。
このソースを簡単なプリプロセッサに通します。コンパイラが吐き出したエラー情報を見て未定義語を把握し、ソースファイル前半に「牛」「乳」などの未定義語を強引に定義するブロックを入れ、実際に動くプログラムとします。そのほかにも多少の工夫をします。そのプリプロセッサ(Mindで記述)が play.exe です。
実行例 - 牛乳
先の牛乳の定義を収めたソースを "牛乳.src" とし、play.exe を使ってこれを処理する様子が以下です。
(まずは play.exe を使って "牛乳.src" を処理する)
samplePlay>play 牛乳
第一回目のコンパイルを行います。
コンパイル中 .. 終了
6 個のエラーが有ります。
未定義語の洗い出し中です・・牛の 乳を 絞って 殺菌して 容器に 詰めたものである
未定義語を定義しています・・牛の 乳を 絞って 殺菌して 容器に 詰めたものである
新しいソースファイルを 牛乳!.src で生成しました。
第二回目のコンパイルを行います。
コンパイル中 .. 終了
処理が終りました。
牛乳! を起動すれば実行できます。
"牛乳! .exe" という実行ファイルが生成されたので実行してみます。
samplePlay>牛乳!
牛乳とは
牛の
乳を
絞って
殺菌して
容器に
詰めたものである
ということで、デタラメなプログラムが動くようになります。ちなみに、もったいぶるために1行出力ごとに1秒のディレイを入れています。
実行例 - お出かけ
条件分岐はこんな感じです。(動かすと「雨降り?」のところで質問が出ます)
お出かけの用意とは
雨降り?
ならば ブーツを履き
傘を差す
さもなければ
靴を履く
つぎに。
実行結果が以下です。
(実行結果:天気が悪いとき)
samplePlay>お出かけ!
お出かけの用意とは
雨降り?(はい/Y/y):はい
ブーツを履き
傘を差す
(実行結果:天気が良いとき)
samplePlay>お出かけ!
お出かけの用意とは
雨降り?(はい/Y/y):いいえ
靴を履く
この遊びの意味
このような遊びはMindのプログラミングに慣れる意味で有意義だと思っています。プログラミング経験の無い人にとってプログラミングの感覚を身に付けられるかも知れないし、Mind経験者にとってもトップダウン設計の感覚が身に付くとか、プロトタイピングができるとか、いろいろ用途がありそうに思えます。
詳しい説明
まず原典のソースコードをそのままの状態でコンパイラにかけます。当然幾つかエラーが発生します。単語の定義開始部や分岐構文などがMindの文法にのっとっていれば、このエラーは”未定義エラー”だけのはずです。たとえば、
小原庄助とは
ここから
遊んで
繰り返すこと。
をコンパイルすると、「遊んで」が唯一のエラー箇所となります。未定義エラーです。
このツールはコンパイラの吐き出したエラー情報のファイルを読みに行き、どんな未定義エラーがあったかを洗い出します。
次に、原典のソースプログラムと似た名前のソースファイルをもう1本生成し、それに未定義の単語の定義を強制的に生成してゆきます。生成ファイル名はオリジナルが test.src であった場合,test!.src とします。
未定義単語の設置が終わった段階で、後続して原典のソースファイルをそのまま複写します。
最後に生成ソース末尾に「メイン」の定義を追加します。シェルから起動できるようにする為です。先の例なら、
メインとは
小原庄助。
という生成になります。
こうして出来上がった生成ソースファイルを改めてコンパイルします。
ここまでが play.exe がおこなう処理です。
さて未定義の単語をどうやって強制的に自動定義するか・・ですが、
まず,
遊び
のような動詞っぽいものは単語名自身をメッセージとしてコンソールに表示します。つまり
遊び
と表示することで遊んだことにします。
次に,何かデータが発生しなくてはならない単語をどうするかです。たとえば、
あなたはお腹が丈夫?
ならば ・・・・
のようなケースです。この場合,コンソールに「あなたはお腹が丈夫?」というプロンプトでキーボードから文字列を受け取るようなプログラムを生成しします。
命題自体を質問文として利用できますから問い合わせは簡単です。
データの入力には次の3種類が考えられます。
1.論理値入力(YES/NOの入力)
2.数値の入力
3.文字列の入力
「あなたはお腹が丈夫?」のように末尾に「?」が付加されたものは1番の論理値入力の為の処理を生成します。
また、「・・を計算」「・・を得る」「・・を入力」の3種類の単語末尾は2の
数値入力であると判断します(このあたりは相当に強引です)。
「・・を尋ねる」「・・を聞く」の2種は文字列入力であると判断します。
さらに、数値や文字列が比較処理の中で用いられることを考慮しました。この場合、入力を表すような表現にならない場合が多いので,別の検出手段を使用しています。たとえば、
身長が 170センチ 以上で
のような記述の場合、「身長が」の部分で問い合わせ処理を生成します。これについては、
”身長?”
というプロンプトでキー入力待ちになります。ポイントは「が」の送り仮名と直後の数値定数です。
同様に、
名前が 「加藤」に 等しい文字列
のような記述の場合、直後の定数が文字列になっているので文字列入力の処理を生成しています。
うまく使うコツは複合語と末尾の「?」を利用することです。たとえば、
マスターが 向こうを向いている
ならば
というソースは次のように,
マスターが向こうを向いている?
ならば
と書いてもらえばうまく質問文を生成できます。
プリプロセッサでの細かな工夫はこんなところです。これ以上やるとだんだん本当のプログラムの領域に入ってしまうので、ほどほどにしています。
ロジック検証に使える?
冒頭の昔話のころ、別の方 2 が、"牛乳.src" の拡張版として次のようなもなのをアップされました。
殺菌とは
貴方はお腹が丈夫?
ならば 終り
つぎに
美味しい牛乳が好き?
ならば 低温殺菌し
つぎに
長持ちする牛乳が好き?
ならば 高温殺菌し
つぎに。
牛乳とは
牛の 乳を 絞って
殺菌して 容器に 詰めたものである。
これを play にかけて改めて走らせてみたのですがミスに気が付きました。
("牛乳2"の実行結果)
>牛乳2!
牛乳とは
牛の
乳を
絞って
貴方はお腹が丈夫?(はい/Y/y):いいえ
美味しい牛乳が好き?(はい/Y/y):いいえ
長持ちする牛乳が好き?(はい/Y/y):いいえ
容器に
詰めたものである
本来であれば「貴方はお腹が丈夫?」の回答が No のときは必ず2種の殺菌のうちどちらかが選ばれなくてはならないはずなのに、その先の「長持ちする牛乳が好き?」で No を答えると殺菌しなくなってしまうのです。
正しいロジックは次のものでした。
~略~
美味しい牛乳が好き?
ならば 低温殺菌し
さもなければ
長持ちする牛乳が好き?
ならば 高温殺菌し
さもなければ
低温殺菌し
つぎに
つぎに。
~略~
この改良版での実行結果が次です。
samplePlay>牛乳3!
牛乳とは
牛の
乳を
絞って
貴方はお腹が丈夫?(はい/Y/y):いいえ
美味しい牛乳が好き?(はい/Y/y):いいえ
長持ちする牛乳が好き?(はい/Y/y):いいえ
低温殺菌し
容器に
詰めたものである
こんな感じで、かなり強引ではあるものの、ロジック検証に使えるかも?などと考えたりします。
ソースファイル
Playのソースファイルを Mind掲示板 にアップしました。
Mind会議室
https://www.scripts-lab.co.jp/support/public/html/mind.cgi?mainframe
に入っていただき(アカウント登録は不要です)、「データライブラリ」の26番に置いてあります。
あとがき
Mindよりもっと昔の話、私がFORTH言語に取り組み始めたころ、本家FORTH社のFORTHを売っていたASRという会社に勤めていた田先さんという方と一緒にFORTH研究会という集まりを開いていた時期がありました。
ある会合でたまたま Dr. Dobb's Journal(コンピュータ関係の機関紙)を見ていたらFORTHで書かれた英語の詩というか歌のような記事を見つけました。田先氏が言うのに「元ネタはマザー・グースではないか?」とのこと。その後本当にマザー・グースだったことが分かりよくそんなことが分かるものだと感心したことがありました。
日本語に比べ語順が違う英語で詩を書くのは難易度が高いかも知れませんが、FORTH言語もまた「単語を羅列すればプログラムになる」ものなので詩/歌を作るのは可能です。当時の「FORTHで書いた英語の歌」をもう一度見たいものだと思っています。