第11回 Prolog の概要(6月25日;6月26日)

今日の課題

■ Prolog の操作

処理系

本演習では、SWI-Prolog という処理系を使用する。SWI-Prolog は、Linux 版と Windows 版の両方が存在する。Web ページからダウンロードして、自分のパソコンで使用できるようにしておこう。

  http://www.swi-prolog.org/ 

基本操作

  1. 起動: コンソール上で、次のコマンドを実行
    pl
    
  2. プログラムのロード: Prolog コンソール上で以下を実行
    ?- ['ファイル名'].
    
  3. 終了: Prolog コンソール上で、Control-d と押す。

プログラムの例

プログラムは、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行目は、好みの知識である。

練習1

まず、emacs を使って、上記のプログラムを入力しよう(Webページからコピー&ペーストせよ)。セーブする際、ファイル名は「list1101.pl」とせよ。次に、コンソール上で、SWI-Prolog を起動せよ。それから、上記プログラムをロードせよ。ロードに成功すると「% list1101.pl compiled 0.00 sec 648 bytes」「Yes」と表示される(bytes数の違いはあるかもしれないが)。「ERROR:…」のように表示された場合は、入力にミスがあるので、エラーメッセージをよく読み、修正しよう。

■ Prolog の文法

知識(プログラム)

■ 質問

Prolog には2とおりの質問がある。

例1

動作確認として以下を実行してみよう。
?- person(but,'ジェンソン・バトン').
?- person(but,X).
?- person(X,Y).

1行目は、「質問1」である。Yes か No という返事が返る。

2行目は、「質問2」である。変数 X に該当するものが返る。

3行目は、「質問2」である。変数 X と Yに該当するものが返る。セミコロンキーを押すと、該当するものが次々と表示され、Enter キーを押すと X と Y が定まる。全ての該当するものが表示されると、それ以上に答がないので、No という返事が返る。

練習2

list1101.pl に次の事実を追加して、list1102.pl を作成しよう。

入力し終えたら、以下の動作を確認しよう。
?- team(but,'ブラウンGP').
?- team(kub,'BMW').
?- team(alo,'フェラーリ').

質問に対しては、Yes か No が返される。

例2

複数の条件で質問をしてみよう。

?- person(X,'ジェンソン・バトン'), team(X,Y). ← Xがニックネームで、Yが所属
?- team(X,'フェラーリ'), person(X,Y). ← Xがニックネームで、Yが名前

変数を使った質問なので、変数に該当するものが返される。セミコロンのキーを押すと、別の答えが返される。

■ 規則の作成

前半で示した like(jessica,X) :- person(but,X). は規則である。この意味は、「jessica はニックネームがbutという人が好き」である。しかし、計算機は、こうした言語の意味を関知しておらず、単に、「 like(jessica,X) が true になるには、 person(but,X) が true にならなければならない」とだけを知識としており、「like」についての質問があると、「:-」の右辺の成立を確認して、「Yes/No」を返している。

規則の書き方について、直観的な説明をするとすれば、『「:-」の右側に質問を記述し、左側にはその呼出し名を記述する』ということになる。

例3

「hanako は、フェラーリの選手が好き」という規則をlist1102.plに追加しよう。
(list1102.pl の末行)
like(hanako,X) :- team(Y,'フェラーリ'), person(Y,X).

練習3

list1102.pl に次の事実と規則を追加して、list1103.pl を作成しよう。

(1) nationality(X,Y)

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

(2) age(X,Y)

age(X,Y)は、Xの年齢がYであることを表すこととする。たとえば、「age(ham,24).」と記述する。ニックネームと年齢は以下のとおりである。

ham(24), kov(27), mas(28), rai(29), kub(25), hei(32), alo(28), piq(24), tru(34), glo(27), bou(30), bue(21), web(32), vet(21), ros(23), nak(24), sut(26), fis(36), but(29), bar(37)

(3) young(X,Y), middle(X,Y), senior(X,Y)

25歳未満は若いという規則を次のように書く。

「young(X) :- age(X,Y), Y < 25.」

同様にして、「25歳以上30歳未満は中堅」という規則の名前を「middle」、「30歳以上はシニア」という規則の名前を「senior」として、それぞれ規則を書こう。

(4) like(X,Y)

like(X,Y) は、XはYが好きということを表すこととする。ただし、Y はニックネームではなく名前とする。

次の質問をしてみよう

□ 小レポート

list1103.pl に次の事実と規則を追加して、prac1101.pl を作成しよう。

実行結果として、次の質問の結果を示せ。

  1. 「goro の好きな選手は誰ですか?」
  2. 「rokuro の好きな選手は誰ですか?」
  3. 「goro と rokuro が共に好きな選手は誰ですか?」

小レポートには、「プログラムソース」、「手書きのコメント(何が事実で、何が規則か。規則はどんな意味か。)」、「上記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

参考


(c) 2009.6.23 by tokuhisa