「制約論理プログラミングその3」の編集履歴(バックアップ)一覧はこちら
制約論理プログラミングその3 - (2014/05/09 (金) 13:22:37) の最新版との変更点
追加された行は緑色になります。
削除された行は赤色になります。
今回は自然言語処理で実際に使うことを目的とした制約論理プログラミングを作ってみましょう。
通常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 = 20
条件が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 = 14
今回は自然言語処理で実際に使うことを目的とした制約論理プログラミングを作ってみましょう。
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
ただしこれはtraceをしてfreezeの動作を確認するための例です。
実際には意味が無いので、次に実例を見てみましょう。
次に単語を変換するプログラムを書いてみましょう。
例は入力がオノマトペ,制約条件が属性ごとに単語が登録されていて、
属性にヒットしたら、属性の代表的な単語に変換するプログラムです。
constraint('期待','ワクワク').
constraint('苛立ち','イライラ').
constraint('驚き','ドキリ').
test:-
S='ドキドキ',
freezes([(X,'期待'),(Y,'苛立ち'),(Z,'驚き')],T),
func('期待',S,X),
func('苛立ち',S,Y),
func('驚き',S,Z),
write(T).
freezes([],[]).
freezes([(A,N)|L],[B|S]):-freeze(A,constraint(N,B)),!,freezes(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