本演習では、SWI-Prolog という処理系を使用する。SWI-Prolog は、Linux 版と Windows 版の両方が存在する。Web ページからダウンロードして、自分のパソコンで使用できるようにしておこう。
http://www.swi-prolog.org/
pl |
?- ['ファイル名']. |
プログラムは、emacs などのエディタを用いて作成する。以下に例を示す。ここで、日本語を使用する際、文字コードは EUC であることを確認せよ。
%-*-prolog-*- % list1101.pl % 人名 person(ham,'ルイス・ハミルトン'). person(kov,'ヘイキ・コバライネン'). person(mas,'フェリペ・マッサ'). person(rai,'キミ・ライコネン'). person(kub,'ロバート・クビサ'). person(hei,'ニック・ハイドヘルド'). person(alo,'フェルナンド・アロンソ'). person(piq,'ネルソン・ピケ・ジュニア'). person(tru,'ヤルノ・トゥルーリ'). person(glo,'ティモ・グロック'). person(vet,'セバスチャン・ベッテル'). person(bue,'セバスチャン・ブエミ'). person(bou,'セバスチャン・ブルデー'). person(web,'マーク・ウエーバー'). person(ros,'ニコ・ロズベルグ'). person(nak,'中嶋一貴'). person(sut,'エードリアン・スーティル'). person(fis,'ジャンカルロ・フィジケラ'). person(but,'ジェンソン・バトン'). person(bar,'ルーベンス・バリチェロ'). % 好みの知識 like(jessica,X) :- person(but,X). |
% はコメントの始まりを表す記号である。
1行目の -*-prolog-*- は、emacs でのプログラミングを楽にするためのおまじないである(M-x prolog-mode の効果がある)。emacs を使わない場合は不要である。
5〜24行目は、F1選手についての知識である。27行目は、好みの知識である。
まず、emacs を使って、上記のプログラムを入力しよう(Webページからコピー&ペーストせよ)。セーブする際、ファイル名は「list1101.pl」とせよ。次に、コンソール上で、SWI-Prolog を起動せよ。それから、上記プログラムをロードせよ。ロードに成功すると「% list1101.pl compiled 0.00 sec 648 bytes」「Yes」と表示される(bytes数の違いはあるかもしれないが)。「ERROR:…」のように表示された場合は、入力にミスがあるので、エラーメッセージをよく読み、修正しよう。
Prolog には2とおりの質問がある。
動作確認として以下を実行してみよう。
?- person(but,'ジェンソン・バトン'). ?- person(but,X). ?- person(X,Y). |
1行目は、「質問1」である。Yes か No という返事が返る。
2行目は、「質問2」である。変数 X に該当するものが返る。
3行目は、「質問2」である。変数 X と Yに該当するものが返る。セミコロンキーを押すと、該当するものが次々と表示され、Enter キーを押すと X と Y が定まる。全ての該当するものが表示されると、それ以上に答がないので、No という返事が返る。
list1101.pl に次の事実を追加して、list1102.pl を作成しよう。
チーム名 | 選手名(ニックネーム) |
---|---|
マクラーレン | ham, kov |
フェラーリ | mas, rai |
BMW | kub, hei |
ルノー | alo, piq |
トヨタ | tru, glo |
トロロッソ | bou, bue |
レッドブル | web, vet |
ウイリアムズ | ros, nak |
フォースインデア | sut, fis |
ブラウンGP | but, bar |
入力し終えたら、以下の動作を確認しよう。
?- team(but,'ブラウンGP'). ?- team(kub,'BMW'). ?- team(alo,'フェラーリ'). |
質問に対しては、Yes か No が返される。
複数の条件で質問をしてみよう。
?- person(X,'ジェンソン・バトン'), team(X,Y). ← Xがニックネームで、Yが所属 ?- team(X,'フェラーリ'), person(X,Y). ← Xがニックネームで、Yが名前 |
変数を使った質問なので、変数に該当するものが返される。セミコロンのキーを押すと、別の答えが返される。
前半で示した
規則の書き方について、直観的な説明をするとすれば、『「:-」の右側に質問を記述し、左側にはその呼出し名を記述する』ということになる。
「hanako は、フェラーリの選手が好き」という規則をlist1102.plに追加しよう。
(list1102.pl の末行) like(hanako,X) :- team(Y,'フェラーリ'), person(Y,X). |
list1102.pl に次の事実と規則を追加して、list1103.pl を作成しよう。
nationality(X,Y)は、XはY国の出身であることを表すこととする。たとえば、「nationality(ham,'イギリス').」と記述する。国籍とニックネームの関係は以下のとおりである。
国籍 | 選手名(ニックネーム) |
---|---|
'イギリス' | ham, but |
'フィンランド' | kov, rai |
'ブラジル' | mas, piq, bar |
'ポーランド' | kub |
'ドイツ' | hei, glo, vet, ros, sut |
'スペイン' | alo |
'イタリア' | tru, fis |
'フランス' | bou |
'スイス' | bue |
'オーストラリア' | web |
'日本' | nak |
age(X,Y)は、Xの年齢がYであることを表すこととする。たとえば、「age(ham,24).」と記述する。ニックネームと年齢は以下のとおりである。
25歳未満は若いという規則を次のように書く。
「young(X) :- age(X,Y), Y < 25.」
同様にして、「25歳以上30歳未満は中堅」という規則の名前を「middle」、「30歳以上はシニア」という規則の名前を「senior」として、それぞれ規則を書こう。
like(X,Y) は、XはYが好きということを表すこととする。ただし、Y はニックネームではなく名前とする。
list1103.pl に次の事実と規則を追加して、prac1101.pl を作成しよう。
実行結果として、次の質問の結果を示せ。
小レポートには、「プログラムソース」、「手書きのコメント(何が事実で、何が規則か。規則はどんな意味か。)」、「上記3点の実行結果の画面」、「実行結果への手書きのコメント」を記載すること。
ニックネーム | 身長 | 体重 |
---|---|---|
ham | 174 | 68 |
kov | 172 | 66 |
mas | 166 | 59 |
rai | 175 | 62 |
kub | 184 | 72 |
hei | 167 | 61 |
alo | 171 | 68 |
piq | 177 | 70 |
tru | 173 | 60 |
glo | 169 | 64 |
bou | 179 | 72 |
bue | 177 | 62 |
web | 184 | 74 |
vet | 174 | 64 |
ros | 178 | 72 |
nak | 175 | 62 |
sut | 183 | 75 |
fis | 172 | 66 |
but | 183 | 70.5 |
bar | 172 | 71 |