絶対アドレスと節の位置との相互変換

二分木の中のノードやリーフの位置は、lとrの系列で示している。が、語と語の距離をそのアドレスから計算するのがとてもややこしいプログラムになっていた。そこで、アドレスと語の位置を相互に交換できるようにした。

ベースにしたのは、次のような、二分木を平板に出力するプログラムだ。記録のために書いておく

print_top :-
    data(Tree),
    set_flag(location,0),
    print(Tree,[]).

print(Tree,Address):-
    atom(Tree),
    get_flag(location,No),
    format('~w(~w:~w), ',[Tree,No,Address]),
    asserta(address(Address,No)),
    No1 is No + 1,
    set_flag(location,No1).

print(Tree,Address):-
    node(N,L,R)=Tree,
    append(Address,[l],Address_l),
    append(Address,[r],Address_r),
    print(L,Address_l),print(N,Address),print(R,Address_r).

data(
node(h,
    node(d,
        node(b,
            a,
            c
        ),
        node(f,
            e,
            g
        )
    ),
    node(l,
        node(j,
            i,
            k
        ),
        node(n,
            m,
            o
        )
    )
)
).

実行すると次のようになる。

?- print_top.
a(0:[l,l,l]), b(1:[l,l]), c(2:[l,l,r]), d(3:[l]), e(4:[l,r,l]), f(5:[l,r]), g(6:[l,r,r]), h(7:[]), i(8:[r,l,l]), j(9:[r,l]), k(10:[r,l,r]), l(11:[r]), m(12:[r,r,l]), n(13:[r,r]), o(14:[r,r,r]), 
true .

assertaでprologの説も構成している。

prolog二分木知識によるシステム相互の応答

没頭していたというよりも、どうするか苦悶していたので前回書いた時から三週間近く経過してしまった。苦闘の理由は、システムを発展性のあるものにすることだった。

ようやく、基礎的なところで納得できるものになったので、何か書いておくことにした。自然言語解釈のところとprologによるsocket相互通信のシステム構築に手間かけた。

自然言語処理のところでは、大きなところは、質問文の解釈の基礎的なところをどのようにするか、設計上の問題に直面した。色々な知識はprolog二分木で表現されていて、その二分木がどのような構造になっているかを踏まえなければならない。二分木は、ノード値と二つのリーフ値の重層的連結になっている。ここに構文情報がはめ込まれてもいる。

ノード値は助詞を中心に付随する修飾語から成り立っていて、動詞や名詞はそこには全く入ってこない。したがって、色々な意味で有限である。限られている。質問文かどうかは、このノード値を解析すればわかる。主語的なものは、格助詞の「は」などがノード値にあれば、その左のリーフか、ないしは、左側のツリーのいずれかのリーフに主語があるはず。

ノード値からの距離が重要で、例えば、格助詞の場合は左側で一番近いところにある名詞が、その主要候補となるだろう。また、距離に、状況によって左の葉を優先するか、右の葉を優先するかの設定もする。この距離は、ノードやリーフの絶対アドレスから算出する。

一つの文章の二分木ツリーから、ノード値、名詞、動詞、修飾語、およびその絶対アドレスの全てを、それぞれリストにして、最初に一挙に取得してしまうという方法も取り入れた。これは別な形で二分木を分解してしまう方法でもある。こうすると、文章のほとんどがそのリスト軍の中に写像される。

こうすると文章の意味取得が容易になる。質問に対して、このリストを使って返信が可能になる。

通信については、javaを経由すればソケット通信は楽になるが、あくまで、prolog動詞て対話の通信ができるようにした。c++やjavaの時と同様に、ソケットとそのストリームを作成して、あとは自由に相互にやり取りをするというソケット通信の本来の形を実現するのに苦労した。ソケットを作って、一個の文章のやり取りをすることはすぐにできるが、ソケットを二つのシステムの対話の間じゅう維持するのが難しかったのだ。しかし、それもできた。

これから、自由な問いかけに、自らの知識(prolog二分木)に基づいて、自由に返答できるシステムにしていこう。形としては、あの巨大なwikipediaの知識を利用できる形にしてあるのだから。