文章をprolog化するJAVAプログラム(2)

前の(1)の記事で示したプログラムは、ごちゃごちゃして醜かった。この記事の前の二つの記事を踏まえて、基幹部分を全面的に書き直した。要点は次のとおりである。

(1)二分木であることをしっかりと踏まえる。句番号のリストを与えると、二分木が自然にできることを示したが、そのアルゴリズムはシンプルなのだ。
(2)二分木の作成と、それに文章のフレーズを実際に乗せてprolog化するプロセスを完全に分離すること。前者は上に述べたような単純さがあり、後者は複雑な一面を持つ。分離することにより、後者の複雑さに対応しやすくなる。

javaで二分木を扱うについては以下のページがとても参考になる。そこに記載されているアルゴリズムは、基本、そのままここでも使うことができる。これを踏まえて、これまでも使った抽象的文章をprolog化するプログラムを以下のように作成した。(以下のGitHubディレクトリのPhraseTree.java)を参照。

phrasetree/PhraseTree.java

このプログラムは、仮想的な文章を使っていて、cabochaなどの構文解析やparseの必要がないので、このjavaファイルだけで実行できる。

やり方は、このファイルを PhraseTree.java という名前で保存し、jdkがインストールしてあれば、javacで

$ javac PhraseTree.java

とすれば、コンパイルされclassファイルができるので、引数など何も指定せずに、

$ java PhraseTree

とやれば、仮想的文章の解析を行った結果を出力するはずである。($はコマンどうプロンプトである)

プログラムに組み込まれている仮想文章は、

「aあbいcうdえeおfかgきhく」

というもので、小文字のアルファベットが名詞や動詞、ひらがなが助詞や助動詞、接続詞などを表している。アルファベット1文字と、ひらがな1文字のペアを一つの句とみなすと、全部で8個ある。句に0番から7番までの番号をつける。(アルファベットの小文字にしたのは、大文字にすると、prologの変数と間違われてしまうからである)

ここで、これまでの記事の中の例と同様に句リストを、プログラム中に次のようなものとして与えている。

[ [ 0 1 r2 3 4 ] r5 6 7 ]

全体のルート句が「か」が助詞となった5番目の句、0番から4番がサブリストで、それは2番目の句が「または」のような接続詞になっていると同時に、それがサブリストのルートにもなっているというものである。(ルートの句番号にはrがついている)

そのまま実行すると、出力は、次のようになる。後半部分に、prolog の宣言文となっているものが出力されている。プログラム中の310行目あたりにある、クリストを変えると、文章の構造が変わる。試して見られるといい。

リストのトークン化
[ [ 0 1 r2 3 4 ] r5 6 7 ] 
rootから左側のフレーズ番号を調べます
rootから左側のフレーズ番号を調べます
リスト/サブリストのフレーズシーケンスを作成しました
rootから右側のフレーズ番号を調べます
リスト/サブリストのフレーズシーケンスを作成しました
リスト/サブリストのフレーズシーケンスを作成しました
rootから右側のフレーズ番号を調べます
リスト/サブリストのフレーズシーケンスを作成しました
フレーズ番号: 5
フレーズ番号: 2
フレーズ番号: 1
フレーズ番号: 0
フレーズ番号: 3
フレーズ番号: 4
フレーズ番号: 6
フレーズ番号: 7
pl000(
    node(か,
        node(う,
            node(い,
                node(あ,
                    a,
                    b
                ),
                c
            ),
            node(え,
                d,
                node(お,
                    e,
                    f
                )
            )
        ),
        node(き,
            g,
            node(く,
                h,
                [ ]
            )
        )
    )
).