前の(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, [ ] ) ) ) ).