# 便利な LiLFeS モジュール

English version

既に説明したツールに加えて，文法開発を支援するための LiLFeS プログラム がいくつか提供されています．これらは，lilfes から読みこんだり(-l オプ ションで指定する)，パーザから読みこんだりすることにより，利用すること が出来ます．

- 文法開発に使うモジュール
  - Head, argument, modifier のマークをつける
  - 構文木を２分木化する
  - 構文木のパターンマッチを行う
- 構文解析に使うモジュール
  - Lexicon, template を引く
  - 外部タガーを使う
- 文法開発や構文解析の様子を観察する
  - 木構造変換，文法抽出の過程をブラウズする
  - 構文解析結果をブラウズする
  - 構文解析チャートをブラウズする
  - 語彙項目をブラウズする
  - 文法のカバレッジを測る
  - 構文解析の精度を測る
- 構文解析器をアプリケーションで使う
  - 構文解析結果をデータベースに貯める

## Head, argument, modifier のマークをつける

"mayz/markhead.lil" は，構文木の各ノードに head, argument, modifier の マークをつけるためのプログラムです．マークをつけるルールを指定するため のインタフェースを実装すると，構文木へ自動的にマークをつけてくれます．

head マークをつけるためのインタフェースは以下の3つです．最初の2つは MOD 素性の値を，もう一つは SYM 素性の値を見て head を決めます．

`head_tag(+$Tag)`
MOD 素性の中に $Tag があると，そのノードは head マー クにします．

`nonhead_tag(+$Tag)`
MOD 素性の中に $Tag があると，そのノードは head マー クにしません．modifier か argument かは別のルールで決められます．

`head_table(+$Sym, +$Dir, +$SymList)`
$Sym | 親のシンボル
$Dir | head をサーチする方向("left" か "right")
$SymList | head マークをつけるシンボルのリスト
親のシンボルが $Sym の時，子ノードを $Dir で指定され た方向に見ていって，$SymList の最初のシンボルがみつかればそれを head とします．みつからなかったら，$SymList の次のシンボルを探しにいきます． $SymList の要素がリストになっている時は，そのリストのどれかのシンボル がみつかればそれを head とします．

以上のインタフェースで得られる情報を元に，構文木の各ノードに head マー クをつけます．

`mark_head(+$Tree)`
$Tree | 構文木

$Tree の各ノードで，その娘の中の一つに，以下のアルゴ リズムで head マークをつけます．

- すでに head マークがついた娘がいれば終了．
- head_tag がついていれば head マークをつける．
- nonhead_tag がついていれば head マークをつけない．
- head_table を用いて head を決める．

modifier, argument マークをつけるためのインタフェースは以下の通りです． このプログラムでは head マークはすでにつけられていると仮定します．最初 の2つは MOD 素性の値を，残りは SYM 素性の値を見てマークを決めます．

`argument_tag(+$Tag)`
MOD 素性の中に $Tag があると，そのノードは argument マークにします．

`modifier_tag(+$Tag)`
MOD 素性の中に $Tag があると，そのノードは modifier マー クにします．

`head_argument_table(+$HeadSym, +$SymList)`
$HeadSym | 主辞のシンボル(SYM 素性の値)
$SymList | argument マークをつけるシンボルのリスト
主辞のシンボルが $HeadSym の時，$SymList の中のシン ボルをもつノードに argument マークをつけます．

`argument_table(+$Sym, +$SymList)`
$Sym | 親のシンボル
$SymList | argument マークをつけるシンボルのリスト
親のシンボルが $Sym の時，$SymList の中のシン ボルをもつノードに argument マークをつけます．

`left_argument_table(+$Sym, +$SymList)`
$Sym | 親のシンボル
$SymList | argument マークをつけるシンボルのリスト
親のシンボルが $Sym の時，主辞の左側で，$SymList の 中のシンボルをもつノードに argument マークをつけます．

`right_argument_table(+$Sym, +$SymList)`
$Sym | 親のシンボル
$SymList | argument マークをつけるシンボルのリスト
親のシンボルが $Sym の時，主辞の右側で，$SymList の 中のシンボルをもつノードに argument マークをつけます．

以上のインタフェースで与えられる情報を元に，構文木の(head マークがつい ていない)全てのノードに，modifier または argument のマークをつけます．

`mark_modifier(+$Tree)`
$Tree | 構文木

$Tree の各ノードに，以下のアルゴリズムで，modifier または argument マークをつけます．

- argument_tag がついていれば argument マークをつける
- modifier_tag がついていれば，modifier マークをつける
- head_argument_table を使って argument マークをつける
- argument_table を使って argument マークをつける
- left_argument_table を使って argument マークをつける
- right_argument_table を使って argument マークをつける
- 残ったノードに modifier マークをつける

以上のプログラムは，既にマークがついているノードには何もしません．つま り，tree conversion プログラムによって，例外的な木には予めマークをつけ ておくことができます．また，以下のインタフェースを用いて，例外的な木に ユーザがマークをつけることもできます．このインタフェースは，木の各ノー ドにマークをつけるときに呼ばれます．

`mark_exceptional(+$Tree)`
$Tree | 構文木(tree)
ユーザが $Tree にマークをつけます．

## 構文木を２分木化する

"mayz/binarizer.lil" は，head, modifier, argument マークがつけられた木 を，head を中心にして二分木化します．

`tree_binarize(+$Tree, -$BinTree)`
$Tree | 入力の木
$BinTree | 二分木化された木
$Tree を二分木化して $BinTree に返します．

このプログラムは，head を中心にして，head の右側を下に，左側を上にして 二分木化します．例外的に二分木化したい場合は，以下のインタフェースを使 います．このインタフェースは，入力の木の各ノードに対して呼び出されます．

`binarizer_preprocess(+$Tree, -$BinTree)`
$Tree | 入力の木
$BinTree | 二分木化された木

## 構文木のパターンマッチを行う

"mayz/treematch.lil" は，構文木のパターンマッチを行うための述語を提供 します．"treetrans"で構文木の変換を行 う際に便利です．構文木のパターンを利用したマッチングや置換を行うことが できます．

構文木のパターンは，構文木の素性構造表現 (tree 型)で表しますが，それに 加えて，tree_any という型を使うことができます．tree_any は，０個以上の 構文木にマッチします．たとえば，

>     (tree &
>      TREE_NODE\SYM\"S" &
>      TREE_DTRS\[tree_any,
>                 (tree & TREE_NODE\SYM\"VP"),
>                 tree_any])

というパターンは，"S" の娘のうち少なくとも一つが "VP" である木にマッチ します．"VP" の左右に０個以上の木があるときでもマッチします．tree_any にマッチした木のリストは，tree_any の ANY_TREES 素性に格納されます．

以下の述語で，構文木のパターンを指定したマッチングや置換を行うことがで きます．

`tree_match(+$Patten, +$Tree)`
$Pattern | 構文木のパターン (tree または tree_any)
$Tree | 入力の構文木 (tree)
構文木のパターンと構文木がマッチすると，成功します．

    > ?- tree_match((tree &
                     TREE_NODE\SYM\"SBAR" &
                     TREE_DTRS\[TREE_NODE\(SYM\"RB" & WORD\SURFACE\"rather"),
                                TREE_NODE\(SYM\"IN" & WORD\SURFACE\"than"),
                                TREE_NODE\(SYM\"NP")]),
                    (tree &
                     TREE_DTRS\[tree_any & ANY_TREES\[_|_],
                                tree & TREE_NODE\(SYM\"IN" & WORD\SURFACE\"than"),
                                tree & TREE_NODE\HEAD_MARK\argument])).
    yes

`tree_substitution(+$OutPattern, -$OutTree)`
$InPattern | 構文木のパターン (tree または tree_any)
$OutTree | 出力 (tree)
構文木のパターン(tree_any 型を含む)を，通常の構文木 (tree_any 型を含まない)に変換します．

`tree_subst(+$InPattern, +$OutPattern, +$InTree, -$OutTree)`
$InPattern | 入力構文木のパターン (tree または tree_any)
$OutPattern | 出力構文木のパターン (tree または tree_any)
$InTree | 入力の構文木 (tree)
$OutTree | 出力 (tree)

入力構文木をパターンとマッチさせ，マッチした場合は出 力パターンに変換し構文木を出力します．つまり，以下の操作を行います．

>     tree_match($InPattern, $InTree),
>     tree_substitution($OutPattern, $OutTree).

具体例は，treetransのマニュアルを参照して下さい．

## Lexicon, template を引く

"mayz/grammar.lil" は，lexicon, template をデータベースから引くための 述語を提供します．以下の述語で，データベースを操作します．

`import_lexicon(+$LexiconFile, +$TemplateFile)`
$LexiconFile | lexicon データベースのファイル名(string)
$TemplateFile | template データベースのファイル名(string)
lexicon, template のデータベースを読みこみます．

`lookup_lexicon(+$Word, -$TempNameList)`
$Word | 入力単語
$TempNameList | テンプレート名のリスト(string の list)
lexicon データベースを引いて，$Word に割り当てるテン プレートのリストを返します．

`lookup_template(+$TempName, -$Sign)`
$TempName | テンプレート名(string)
$Sign | テンプレートの素性構造
template データベースを引いて，$TempName の素性構造 を返します．

`lookup_lexicon/2`を使うには，以下のインタフェースを実装して， 入力単語から lexicon データベースのキーを返して下さい．

`lexicon_lookup_key(+$Word, -$Key)`
$Word | 入力単語
$Key | lexicon データベースのキー

`unknown_word_lookup_key(+$Word, -$Key)`
$Word | 入力単語
$Key | lexicon データベースの未知語−キー

## 外部タガーを使う

"mayz/tagger.lil" は，外部タガーを使うためのインタフェースを提供します． まず，以下の述語でタガーの初期化/終了化をします．

`initialize_external_tagger(+$Name, +$Arguments)`
$Name | タガーのコマンド名(string)
$Arguments | タガーのコマンド引数(string の list)
タガーを起動します．

`terminate_external_tagger`
タガーを終了します．

`is_external_tagger_initialized`
タガーが既に初期化されているときは成功します．

タガーを初期化後，タガーを使う/使わないを以下のインタフェースで切り替 えることができます．

`enable_external_tagger`
タガーを有効化します．

`disable_external_tagger`
タガーを無効化します．

`is_external_tagger_enabled`
タガーが有効化されていれば成功します．

以下の述語で，タガーに文字列を渡し，結果の文字列を返します．

`external_tagger(+$Input, -$Output)`
$Input | 入力の文字列
$Output | 出力の文字列
タガーが有効であれば $Input をタガーの標準入力に渡し， 標準出力に返ってきた文字列を $Output に返します．タガーが無効であれば $Input をそのまま $Output に返します．

## 木構造変換，文法抽出の過程をブラウズする

"mayz/morivtrans.lil" は，木構造の変換(treetrans)や文法抽出 (lexextract) の過程をグラフィカルに見るためのモジュールです． XHTML/XSLT をサポートしたブラウザ(FireFox など)や，MoriVブラウザを 用いることで，木構造や素性構造をふくめて，文法抽出の過程をブラウズする ことができます．

このモジュールは，http サーバおよび cgi として動作します．まず，木構造 変換，および文法抽出のモジュールといっしょに，mayz/morivtrans.lil を読 みこみます．

    % lilfes -l 木構造変換モジュール -l 文法抽出モジュール -l mayz/morivtrans

次に，cgi コマンドを起動します．

    > ?- cgi.

すると，http サーバが起動し，接続待ち状態になります．サーバを起動した ホストの 27109 ポートの /cgi-lilfes/moriv? に，ブラウザでアクセスしてく ださい．

    http://サーバを起動したホスト:27109/cgi-lilfes/moriv?

一番上のフォームに Penn Treebank スタイルの構文木を入力して Input ボタ ンを押すと，左下にメニューが，右下に入力した構文木が表示されます．あと は，左下のメニューを使ってデータをブラウズしてください．

## 構文解析結果をブラウズする

"mayz/morivparser.lil" は，MAYZ ツールキットで作成した文法および確率モ デルを使って構文解析を行い、その結果をグラフィカルに見るためのモジュー ルです．XHTML/XSLT をサポートしたブラウザ(FireFox など)や，MoriVブラウザを 用いることで，構文解析結果の木構造や素性構造を見ることが出来ます．

このモジュールを利用するためには，構文木に使われるシンボルを得るために "display.lil" で定義されているインタフェースを実装する必要があります．

`sign_label(+$Sign, -$Symbol)`
$Sign | 素性構造
$Symbol | string
$Sign を表す文字列を返す．

`lexname_label(+$LexName, -$Symbol)`
$LexName | LEX_NAME (lexical_entry/3 の第2引数で返したもの)
$Symbol | string
LEX_NAME を表す文字列を返す．

`schema_edge_label_unary(+$SchemaName, -$Label)`
$SchemaName | スキーマの名前
$Label | 娘へのエッジにつける文字列
unary schema が適用されたノードから娘へのエッジに表 示するラベルを返します．

`schema_edge_label_binary(+$SchemaName, -$LeftLabel, -$RightLabel`
$SchemaName | スキーマの名前
$LeftLabel | 左の娘へのエッジにつける文字列
$RightLabel | 右の娘へのエッジにつける文字列
binary schema が適用されたノードから娘たちへのエッジ に表示するラベルを返します．

`schema_label(+$SchemaName, -$Label`
$SchemaName | スキーマの名前
$Label | スキーマの名前を表す文字列
スキーマの名前を表す文字列を返します．

`lex_template_label(+$LexTemplate, -$Label`
$LexTemplate | テンプレートの名前(lex_template)
$Label | テンプレートの名前を表す文字列
テンプレートの名前を表す文字列を返します．

`word_label(+$Word, -$Label)`
$Word | 単語を表す素性構造(word)
$Label | 単語を表す文字列
単語を表す文字列を返します．

`extent_label(+$Extent, -$Label)`
$Extent | extent を表す素性構造
$Label | extent を表す文字列
extent (sentence_to_word_lattice/2 で返すリストの要 素)を表す文字列を返します．

このモジュールは，http サーバおよび cgi として動作します．パーザを起動 するときに，mayz/morivparser.lil を読みこみ，cgi コマンドを起動しま す．たとえば，mayzup パーザを使うときは，以下のように起動します．

    % mayzup -l 文法モジュール -l mayz/movirparser -e cgi

すると，http サーバが起動し，接続待ち状態になります．サーバを起動した ホストの 27109 ポートの /cgi-lilfes/moriv? に，ブラウザでアクセスしてく ださい．

    http://サーバを起動したホスト:27109/cgi-lilfes/moriv?

サーバに接続後，一番上のフォームに文を入力して Input ボタンを押すと， 左下に解析結果の概要とメニューが表示されます．あとは，メニューを使って 構文木や素性構造を表示させてブラウズしてください．

## 構文解析チャートをブラウズする

"mayz/morivchart.lil" は，構文解析のチャート(CKY表)を，XHTML/XSLT をサ ポートしたブラウザ(FireFox など)や，MoriVでブラウズ するためのモジュールです．構文解析の途中で生成されたエッジを見ることが できます．

このモジュールを利用するためには，構文木に使われるシンボルを得るために "display.lil" で定義されているインタフェースを実装する必要があります． 詳しくは，構文解析結果をブラウズするを見て 下さい．

パーザを起動する時に mayz/morivchart を読み込み，cgi コマンドで http サーバを起動したら，ブラウザでサーバに接続して下さい．すると，一番上に 文を入力するフォームが表示されるので，そこに文を入力します．すると，左 下にチャートが表示されます．チャートのセルをクリックすると，右下にその チャート内のエッジの情報が表示されます．

## 語彙項目をブラウズする

"mayz/morivgrammar.lil" は，構文解析で使われる辞書を，XHTML/XSLT をサ ポートしたブラウザ(FireFox など)や，MoriVでブラウズ するためのモジュールです．各単語に割り当てられている語彙項目の一覧やそ の素性構造を見ることができます．

このモジュールを利用するためには，構文木に使われるシンボルを得るために "display.lil" で定義されているインタフェースを実装する必要があります． 詳しくは，構文解析結果をブラウズするを見て 下さい．

パーザを起動する時に mayz/morivgrammar を読み込み，cgi コマンドでhttp サーバを起動したら，ブラウザでサーバに接続して下さい．すると，一番上に 単語を入力するフォームが表示されるので，そこに単語/品詞を入力してくだ さい．すると，左下に語彙項目の一覧が表示されます．語彙項目のリンクをク リックすると，右下にその素性構造が表示されます．

## 文法のカバレッジを測る

"mayz/coverage.lil" は，MAYZ で作成した文法のカバレッジを測定するため のモジュールです．文法モジュールといっしょに mayz/coverage.lil を読み こみ，以下の述語を実行してください．

`eval_coverage(+$Lexbank, +$Lexicon, +$Template, +$OutputFile)`
$Lexbank | 評価の対象となるコーパスの Lexbank ファイルの名前
$Lexicon | 文法の lexicon ファイルの名前
$Templates | 文法の template ファイルの名前
$OutputFile | 測定結果を出力するファイルの名前

カバレッジ測定のために，未知のコーパスの lexbank を使います．したがっ て，未知のコーパスについても，treetrans, lexextract をあらかじめ適用し， lexbank を作っておく必要があります．

## 構文解析の精度を測る

"mayz/evalparse.lil" は，MAYZ で作成した文法および確率モデルを使った構 文解析の精度を測定するためのモジュールです．一文ごとの正解数を測定する 述語を実装するだけで，テストコーパス全体での精度を測定することができま す．

まず，一文ごとの正解数を測定する以下のインタフェースを実装する必要があ ります．

`eval_parse(+$Best, +$Correct, +$TermList, -$NumAnswers, -$NumOutputs, -$NumCorrects, -$NumPartials, -$Errors)`
$Best | パーザが出力した parse_tree
$Correct | 正解の parse_tree
$TermList | derivation の終端ノードのリスト (lexbank に相当)
$NumAnswers | 答の数 (recall の母数)
$NumOutputs | 出力の数 (precision の母数)
$NumCorrects | 完全正解の数
$NumPartials | 部分正解の数
$Errors | error analysis の結果のリスト(出力ファイルに各要素 が出力されます)

パーザを起動するときに，mayz/evalparse.lil を読みこみ，以下の述語を実 行して下さい．精度の測定結果，および各文で不正解だった部分がファイルに 出力されます．

`eval_parse_file(+$Derivbank, +$OutputFile)`
$Derivbank | 評価の対象となる derivbank の名前
$OutputFile | 評価結果を出力するファイルの名前
$Derivbank で構文解析の精度を測定し，結果を $OutputFile に出力します．

## 構文解析結果をデータベースに貯める

"mayz/parseall.lil" は，構文解析結果をデータベース(lildb)に貯めるため の LiLFeS モジュールです．入力テキストの各行を構文解析し，解析木全体を データベースに格納します．データベースのキーは，文番号になります．構文 解析が失敗した場合は， `parse_error`型とその subtype で，失敗した原因を格納します．

このモジュールでは，以下の述語を利用できます．

parse_all(+$Input, +$Output)
$Input | 入力ファイルの名前
$Output | 出力データベースの名前
入力ファイルの各行を解析し，結果を出力データベースに 格納します．

parse_all(+$Output)
$Output | 出力データベースの名前
標準入力の各行を解析し，結果を出力データベースに格納 します．

MAYZツールキットマニュアル MAYZホームページ 辻井研究室