swi-prologに知識そのものを乗せることになるのだが、だとすると、それに対するアクセスのために、prologから、自然言語解析のツールを利用できた方がいいと考えた。
そこで、さしあたって、swi-prologで、jumanを利用した形態素解析をさせるプログラムを作成した。swi-prologのlibrary(process)マニュアルにあるサンプルを利用している。
jumanをサーバーモードで立ち上げる方が、効率的だが、その場合はswi-prologでクライアントを作成するという問題になる。が、ここでは直接jumanを起動する方法をとる。prologから外部コマンドを実行するのが、どのような手続きで実現するのかを確認する意味も込めている。
jumanには、pathが通っていなければ起動できない。
juman(String, Lines) :- setup_call_cleanup( process_create(path(juman), [ ], [ stdout(pipe(Out)), stdin(pipe(In)) ]), proc_stream(In, Out, String, Lines), close(Out)). proc_stream(In, Out, String, Lines) :- write(In,String), close(In), read_line_to_codes(Out, Line1), read_morpheme(Line1, Out, Lines). read_morpheme(end_of_file, _, []) :- !. read_morpheme(Codes, Out, [Line|Lines]) :- atom_codes(Line, Codes), read_line_to_codes(Out, Line2), read_morpheme(Line2, Out, Lines).
jumanは、標準入力から解析対象の文章を受け取るので、process_createのオプションにstdinを加えた。proc_streamでは、標準入力と標準出力を受け取って、まず、標準入力に文章を書き込む、それを閉じて、標準出力から結果を受け取る。read_morphemeは、end_of_fileまで一行ずつ受け取る(再帰的に繰り返す)。
実行結果は次のようになる。juman.swiが上に示したプログラムファイルである。
?- ['juman.swi']. true. ?- juman(今日はいい天気ですね,Lines). Lines = ['今日 きょう 今日 名詞 6 時相名詞 10 * 0 * 0 "代表表記:今日/きょう カテゴリ:時間"', '@ 今日 こんにち 今日 名詞 6 時相名詞 10 * 0 * 0 "代表表記:今日/こんにち カテゴリ:時間"', 'は は は 助詞 9 副助詞 2 * 0 * 0 NIL', 'いい いい いい 形容詞 3 * 0 イ形容詞イ段 19 基本形 2 "代表表記:良い/よい 反義:形容詞:悪い/わるい"', '天気 てんき 天気 名詞 6 普通名詞 1 * 0 * 0 "代表表記:天気/てんき カテゴリ:抽象物"', 'です です だ 判定詞 4 * 0 判定詞 25 デス列基本形 27 NIL', 'ね ね ね 助詞 9 終助詞 4 * 0 * 0 NIL', 'EOS'].
出力がリストで獲得できる。