制約論理プログラミングその3

「制約論理プログラミングその3」の編集履歴(バックアップ)一覧に戻る

制約論理プログラミングその3 - (2014/05/09 (金) 14:45:19) のソース

今回は自然言語処理で実際に使うことを目的とした制約論理プログラミングを作ってみましょう。
通常prologでは単位説を使ってデータとして値を保存し、プログラムによって単位説を選んでいって、
ユニフィケーションしていくのですが、条件が複数含まれていたり(条件なしも含む)、
条件が動的に決まるような場合はプログラムが複雑になることがあります。
制約論理プログラミングではこの問題を解決してくれます。

サンプルを見てみましょう。
 test:-
 	freeze(A,member(X,['喜','怒','哀','楽'])),
 	freeze(A,member(X,['怒','哀','楽'])),
 	freeze(A,member(X,['哀','楽'])),
 	freeze(A,member(X,['楽'])),
 	A = true,
 	write(X).
 
 ||?-test.
 楽
 yes
 LOOP = 18

条件が4つあっても変数Xが4つ目の条件が終わるまでは値が決まらないので、記述が簡単にです。
条件が動的に代わる問題、例えば上の例の条件を反転してみましょう。

 test:-
 	freeze(A,member(X,['楽'])),
 	freeze(A,member(X,['哀','楽'])),
 	freeze(A,member(X,['怒','哀','楽'])),
 	freeze(A,member(X,['喜','怒','哀','楽'])),
 	A = true,
 	write(X).
 
 ||?-test.
 楽
 yes
 LOOP = 12

次に単語を変換するプログラムを書いてみましょう。
例は入力がオノマトペとして属性ごとに単語が登録されていて、
属性にヒットしたら、其の属性の代表的な単語に変換するプログラムです。
 constraint('期待','ワクワク').
 constraint('苛立ち','イライラ').
 constraint('驚き','ドキリ').
 
 test:-
	S='ドキドキ',
 	frees([(X,'期待'),(Y,'苛立ち'),(Z,'驚き')],T),
 	func('期待',S,X),
 	func('苛立ち',S,Y),
 	func('驚き',S,Z),
 	write(T).
 
 frees([],[]).
 frees([(A,N)|L],[B|S]):-freeze(A,constraint(N,B)),!,frees(L,S).
 
 func('期待'  ,S,true):-member(S,['ワクワク','ドキドキ']).
 func('苛立ち',S,true):-member(S,['イライラ','ムカムカ']).
 func('驚き'  ,S,true):-member(S,['ドキドキ','ドキリ','ギクリ']).
 func(_,_,_).
 
 ||?-test.
 [ワクワク,B_49,ドキリ]
 yes
 LOOP = 22

制約func述語はassert,retractを使って追加、更新、削除ができます。
例えば追加はこんな感じです。
 以下を追加したい場合、
 func('泣',S,true):-member(S,['シクシク','ウルウル']).
 
 X =..[':-',func('泣',S,true),member(S,['シクシク','ウルウル'])],assert(X).

最後に制約論理を用いたDCG表記法を書いてみましょう。
もう少し手の込んだプログラムにすれば制約条件を行なった自動応答文ができそうです。

 降水確率(70).
 
 weather --> a,b,c,d.
 a --> ['今日'].
 b --> ['の天気は'].
 d --> ['です'].
 
 test:-
  abolish(c,2),
  freeze(A,assert(c(['晴れ'|_0],_0))), %_だけだとc(['晴れ'|_0],_1 となるので注意。
  freeze(B,assert(c(['雨'|_0],_0))),
  freeze(C,assert(c(['曇'|_0],_0))), 
  'How''s weather'(A,B,C),
  weather(X,[]),
  atom_appends(X,Y),write(Y),nl,fail.
 test:-!.
 
 'How''s weather'(A,B,C):-'How''s weather2'(A,B,C),fail.
 'How''s weather'(A,B,C):-!.
 'How''s weather2'(A,_,_):-降水確率(X),X=<20,!,A=true.
 'How''s weather2'(_,B,_):-降水確率(X),X>=60,!,B=true.
 'How''s weather2'(_,_,C):-降水確率(X),X=<30,X>=50,!,C=true.
 
 ||?-test.
 今日の天気は雨です
 yes
 LOOP = 27