プログラムでリストを扱うとき,リストの中身全体が必要というわけでは ない.リストの中身を次のように見分けてみよう.
(リスト全体) = [ 扱いたい部分 | 扱いたくない部分 ]
普通,プログラムを作るとき,「扱いたい部分」だけを1つの変数で表す が,「差分リスト」の考えかたでプログラムを作るとき「リスト全体」と「扱 いたくない部分」の2つの変数を用いて「扱いたい部分」を表す.
なお,Prolog では,その2つの変数を同時にプログラムに書くことがポ イントである.その書き方は,統一されていれば何でもよい.
単語・熟語の辞書を差分リストで表してみよう.そして,リスト中から,名前を抽出しよう.
(プログラム) % list1301.pl noun([texas|R]-R,n(texas)). noun([kansas|R]-R,n(kansas)). noun([new,york|R]-R,n(new_york)). noun([north,dakota|R]-R,n(north_dakota)). noun([south,dakota|R]-R,n(south_dakota)). noun([new,mexico|R]-R,n(new_mexico)). noun([washington|R]-R,n(washington)). (質問) *その1 ?- noun([texas]-A,N1). *その2 ?- noun([kansas,texas,washington]-A,N1),noun(A-B,N2),noun(B-C,N3). *その3 ?- L = [new,york,new,mexico,kansas,north,dakota,washington,south,dakota], | noun(L-A,N1), | noun(A-B,N2), | noun(B-C,N3), | noun(C-D,N4). |
変数 N1, N2, … に,地名がバインドされていることを確認しよう.リス トのうち,扱わない部分を表す変数に何がバインドされているか確認しよう.
特に,その3では,リスト全体のうち,4つぶんの名詞が抽出されている. 抽出されなかった残りの部分は変数 D に残されていることを確認しよう.
品詞ごとの辞書を用意しよう.そして,名詞のかたまりを抽出しよう.
(プログラム) % list1302.pl noun([texas|R]-R,n(texas)). - - -(list1301.plと同様)- - - noun([new,mexico|R]-R,n(new_mexico)). noun([washington|R]-R,n(washington)). noun([book|R]-R,n(book)). noun([pen|R]-R,n(pen)). noun([office|R]-R,n(office)). noun([school|R]-R,n(school)). noun([church|R]-R,n(church)). noun([i|R]-R,n(i)). det([the|R]-R,det(the)). det([a|R]-R,det(a)). det([an|R]-R,det(an)). aj([good|R]-R,aj(good)). aj([bad|R]-R,aj(bad)). aj([new|R]-R,aj(new)). aj([old|R]-R,aj(old)). (質問) *その1 ?- E1 = [a,pen], | det(E1-E2,D), | noun(E2-E3,N). *その2 ?- E1 = [a,new,book], | det(E1-E2,D), | aj(E2-E3,A), | noun(E3-E4,N). *その3 ?- E1 = [new,york,where,i,have,ever,lived], | noun(E1-E2,N). |
上記の質問のその1,その2,その3を基にして,英語の名詞のかたまり (名詞句 Noun Phrase と言う)の規則を書いてみよう.ただし,その規則は 次のように使えること.
?- E1 = [a,new,book], | np(E1-X,NP). E1 = [a, new, book] X = [] NP = np(det(a),aj(new),n(book)) Yes |
Prolog は,質問に対する答えを求めて,規則の適用を試行錯誤している.
仮りに規則を適用し,途中で辻褄が合わなくなると,その仮りの適用をと りやめて,別の規則を適用することがある.これをバックトラックという.
練習1ができた人は次の規則を持っているだろう.
np(E1-X,np(N)) :- noun(E1-X,N). np(E1-X,np(D,N)) :- det(E1-E2,D), noun(E2-X,N). np(E1-X,np(D,A,N)) :- det(E1-E2,D), aj(E2-E3,A), noun(E3-X,N). |
ここで,次の質問をすると,Prolog はどのように動作するだろうか?
?- E1=[the,new,book], np(E1-X,NP). |
トレースを実行すると,その様子がわかる.具体的には次のように実行する.
?- trace. Yes [trace] ?- E1=[the,new,book], np(E1-X,NP). Call: (9) - - - - - -(以降は自分で確認しよう)- - - - - - [debug] ?- nodebug. Yes ?- |
英語の簡単な文法規則をプログラムにしてみよう.
名詞句 np の規則は上述した.その他のかたまりとして,動詞句 vp (Verb Phrase) や前置詞句 pp (Prepositional Phrase) がある.たとえば, "buy the book" は動詞句,"in the store" は前置詞句である.それぞれ名詞 句に品詞(動詞や前置詞など)を追加した規則で定義できる.
pp(E1-X,pp(P,NP)) :- preposition(E1-E2,P), np(E2-X,NP). preposition([in|R]-R,p(in)). |
さらに,英語の文 s (Sentence) は,名詞句と動詞句などの組み合わせで 定義できる.
そこで,次の文が解析できるように,文法規則を作り小レポートとして提 出せよ.小レポートには,プログラム,質問方法,および,結果(セミコロン を押して,複数解を表示)を記載せよ.