知識に基づいて、「とはなんですか」という疑問文を生成するprolog文を作った。例えば、「アトムはロボットです」という部分知識があったときに、これを回答にするような問いを考えるということである。プログラムは次のようになる。細かい調整はしていないので、色々バグもあると思う。
単純疑問文の場合と発想を変えてプログラム化した。シンプルだ。単純疑問文の場合も、この発想で書き直せば、もっといい感じになると思う。
%% ----- なんですか 疑問文 ----- nandesuka(T,Out) :- not(functor(T,node,3)),Out=T. nandesuka(node(N,L,R),Out) :- ( 'です'=N, not(functor(L,node,3)) -> N1='ですか', L1='なん', R1=R ; ( 'は'=N -> N1='とは' ; N1=N, true ), %% 左右の葉を再帰的に処理する nandesuka(L,L1), nandesuka(R,R1), true ), Out = node(N1,L1,R1).
変な感じではあるが、元々に知識的ツリーを入れると、それを答えとするような疑問文を生成するということである。
if文を使っている。if文の中にif文を使って、ネストしている。ある意味、if文は、Cやjavaなどの逐次処理言語の得意芸であり、あまりprolog的にはなじまないのかもしれないが、prolog的には、cut(!)を使った単純な構造である。if文の最後にtrueが付いているのは、if文の条件節が成立しなくても、カッコの次を実行するためである。そうしないと、成立しないときに、バックトラックに入って、その後を実行しなくなる。
最初のif文は、node値が「です」の部分木に出会ったら、それを「ですか」に変えて、その左葉の値がツリーでない限り、「なん」という疑問詞に変えるということである。この時の左葉が部分ツリーになる場合は、うまくいかないが、そういう状況は、想像できない。ないと思う。
さらに、「は」とう格助詞がnode値の時は、それを「とは」に変える処理もする。
「です」nodeに出会った時は、それ以上の再帰的処理はしないが(文の最後であるはずだから)、そうでない限り、各葉の再帰的処理に入り、各葉がnodeでないときは、そのまま値を返すという再帰的処理の終端処理が、最初のprolog文である。
実行結果は次のようになる。
?- ['quetion.swi']. true. ?- nandesuka(node(は,[アトム, 'S:普/C:自然物/D:科学・技術'],node(です,[ロボット, 'S:普/C:人工物-その他/D:科学・技術'],[ ])),Out). Out = node(とは, [アトム, 'S:普/C:自然物/D:科学・技術'], node(ですか, なん, [])).
知識文は「アトムはロボットです」をjavaのprolog二分木作成システムで作った二分木である。フォーマット改変の記事で、それぞれの記号的意味は解説している。