第2章 プログラムの実行
1. ETIのダウンロードとインストールの方法
ダウンロードサイトhttp://assam.cims.hokudai.ac.jp/etiからETGUI.exe(ETI)の最新版をクリックし、
任意のフォルダに保存する。すると、フォルダ内にアイコン(電子レンジ)が出てくる。これは自己解凍 形式になっており、アイコンをダブルクリックすると解凍先の指定が出てくるので、ETGUIをインストー ルするフォルダを指定して、OKボタンを押す。すると、解凍が始まり、解凍後に自動的にセットアップが 起動する。
インストールの画面が出てきたら、指示に従ってNextボタンを押す(インストール先の指定が間違って いないかを確認する)。
インストール終了後に、再起動を促すダイアログボックスが出ることがあるが、ETGUIは再起動の必要が ないように作られているので、それはキャンセルをする。インストールが成功すると、デスクトップに ETIのアイコンが現れる。このアイコンをダブルクリックすると、ETIを起動することができる。
2.エディタによるプログラムの記述
ETにおけるプログラムはルールの集合であり、それらのルールは、エディタ(例えば「メモ帳」「秀丸」
等)を用いてテキストファイルに記述する。 ここでは試しにエディタを起動し、次のコメントとルールを 記述しよう。
(1) コメント
「// (半角スラッシュ2つ)」を記述すると、そこから行末までがコメントとなる。コメントはプログ ラムの実行には何も影響を与えない。しかしプログラム中にルールの内容などを説明する文章があると、
プログラムが理解しやすくなり、プログラム作成を効率化することができる。
// 家族関係
と入力し改行しなさい。
(2) ルールの記述
ルールは基本的に半角英数字で記述する。 エディタを開いて、以下のようにルールを記述しなさい。
ただし、半角で入力すること。 シンボルや文字列の中では漢字も使うことができる。
(father *X *Y) ==> (= *X yusuke), (= *Y taro);
==> (= *X yuka), (= *y taro);
==> (= *X taro), (= *y shigeta);
==> (= *X shigeta), (= *y kumakichi).
また、(= *X yusuke)などを処理する = 述語はETの組み込み述語である。実行列を用いて、
(= *X *Y) ==> {(= *X *Y)}.
と記述する。
(3) 保 存
ETIを保存するフォルダを作っていない場合は、Windowsの画面を右クリックし、[新規作成]−[フォル ダ]で「ETI」という名前のフォルダを作成する。エディタで記述したプログラム(ルール)を保存する には、[ファイル]−[名前をつけて保存]をクリックし、ファイルに名前(例えば test.etr)を付ける。
ファイルにつける拡張子は、.etを推奨する。
名前をつけて保存したならば、それ以降の編集はルールの修正のたびに[上書き保存]を行う。ここまで の操作を振り返ってみると作られたファイルの内容は以下のようになる。
// 家族関係
(father *X *Y) ==> (= *X yusuke), (= *Y taro);
==> (= *X yuka), (= *y taro);
==> (= *X taro), (= *y shigeta);
==> (= *X shigeta), (= *y kumakichi).
(= *X *Y) ==> {(= *X *Y)}.
3.プログラムの実行
記述したプログラムを実際に計算機で動かして、質問の解答を求めてみよう。まず、ETを起動するに は、「ETI.exe」をダブルクリックして、システムを起動する。すると [D]> というプロンプトが画面 に表示される。プロンプトとは入力を促す記号である。この例題は、Nモードで実行可能であるので、
ETGUIの中央下にあるExec Mode のNをチェックして、[N]> プロンプトに切り替える。メニューの [File]−[Open]から、test.etrを選択し、プログラムをロードする。ロードが成功すると再び[N]>と表示 され、そのプログラムが(Nモードで)実行可能な状態になる。
下部の入力欄に (father yusuke ?) という質問を入力し、enterを押すとその質問に対する計算結果 が表示される。
[N]>(father yusuke ?)
---N execution --- (ans (father yusuke taro))<-.
これは、「yusukeの父親は誰ですか。」という質問をアトムで与えられた結果、ETが「yusukeの父親が taroである」と答えたことを示している。ETは、質問のアトム中の?もtaroに変更することによってこの 質問に答えているのである。その後、同じようにプロンプトが表示されるので、質問と応答は何回も繰り 返すことができる。(father yuka ?)や、(father taro ?) などの質問も試してみよう。ETを終了すると きは、[N]>q と入力する。ウインドウが閉じて終了となる。
再びETを起動して、test.etrをロードしなさい。次に、「誰の父親がshigetaですか」という質問を与 えてみよう。この場合の質問のアトムは、
(father ? shigeta)
であり、実行は次のようになる。
[N]>(father ? shigeta)
---N execution --- (ans (father taro shigeta))<-.
これは、「taroがshigetaの父親である」ことを示している。では、「誰の父親がtaroですか」という 質問について実行してみよう。これも
(father ? taro)
と質問すればよいが、答えは2つある。
[N]>(father ? taro)
---N execution --- (ans (father yusuke taro))<-.
(ans (father yuka taro))<-.
これらの質問は ? に入るべき対象を正しく求める「穴埋め問題」と考えることができる。例題では、
ETGUIは様々な穴埋め問題に的確に答えることができた。もし複数の解答があっても、それらをすべて答 えていることを試してほしい。
最後に、穴埋め問題は、特別な場合として、
(A) 穴がない場合 (B) 穴だらけの場合
も含んでいることを指摘しておこう。(A) の「穴がない場合」とは、例えば、
(father yuka taro)
のような質問である。これは、「yukaの父親はtaroですか」という yes-no 判定問題に対応している。
[N]>(father yuka taro)
---N execution --- (ans (father yuka taro))<-.
ここで「yukaの父親はtaroです」という答えがでたので、yes-no問題にyesという答えを出したことに なる。しかし、「shigetaの父親はtaroですか」という質問には、noという答えが次のように得られる。
[N]>(father shigeta taro)
---N execution ---
noという答えは0個の出力結果によって示されている。
次に、(B)の「穴だらけの場合」も試してみよう。(father ? ?) は「誰の父親は誰ですか」すなわち、
父子関係にあるものをすべて求めよという意味である。
[N]>(father ? ?)
---N execution --- (ans (father yusuke taro))<-.
(ans (father yuka taro))<-.
(ans (father taro shigeta))<-.
(ans (father shigeta kumakichi))<-.
これはすべての父子関係を列挙している。
次に新たに、祖父に言及した
taroの祖父は誰ですか。 誰の祖父がshigetaですか。
などの質問に答えるためのプログラムを作ろう。この場合「子供-父親関係」の他に「孫-祖父関係」も考 える必要がある。この「孫-祖父関係」を (grandfather *X *Y) というアトムで表すことにしよう。これ は、(grandfather *X *Y)が 「*X の祖父は*Y である」というアトムだと仮定したことを意味する。祖父 は「父の父」であることを考えると、(grandfather *X *Y)を計算するルールは、
(grandfather *X *Y) ==> (father *X *Y), (father *Y *Z).
というルールが思いつくであろう。これは、(grandfather *X *Y) というアトムがあるならば、それを (father *X *Y)と(father *Y *Z)の2つのアトムの論理積に置き換えるというルールである。このルール をtest.etrに加え、上書き保存すると、現在のファイルの内容は次のようになる。
//家族関係
(father *X *Y) ==> (= *X yusuke), (= *Y taro);
==> (= *X yuka), (= *Y taro);
==> (= *X taro), (= *Y shigeta);
==> (= *X shigeta), (= *Y kumakichi).
(= *X *Y) ==> {(= *X *Y)}.
(grandfather *X *Z) ==> (father *X *Y), (father *Y *Z).
このプログラムをロードして
taroの祖父は誰ですか。 誰の祖父がshigetaですか。
などの質問の答えを求めてみよう。すると、taroの祖父はkumakichiだけであるが、shigetaが祖父である 者(すなわちshigetaの孫)は2人いることがわかる。
[N]>(grandfather taro ?)
---N execution --- (ans (grandfather taro kumakichi))<-.
[N]>(grandfather ? shigeta)
---N execution --- (ans (grandfather yuka shigeta))<-.
(ans (grandfather yusuke shigeta))<-.
すべての「孫と祖父の関係」を求める場合には、(grandfather ? ?) と質問すればよい。これまでに引 数に ? を何度か用いたが、ここで?に関して簡単な説明をしておこう。 ? は無名変数と呼ばれる変数 であり、「他と異なる変数」を表す。(grandfather ? ?) は、(grandfather *X *Y) や(grandfather *A
*B) などと書かれた質問と同じ意味である。しかし、「同一の変数」を用いた(grandfather *X *X) の意 味は「自分が自分の祖父である人を求めよ」であり、(grandfather ? ?)とは異なるので注意が必要であ る。