Enju の文法開発では, まず Penn Treebank の構文木を変形して HPSG 構文木に似た形の木にします. この変形は mayz の treetrans ツールを利用し,下記のコマンドによって行われます. (treetrans ツールについて詳しくは mayz のマニュアルを参照して下さい.)
treetrans ルールモジュール 入力ファイル 出力データベース | |
ルールモジュール | 構文木を変換するパターンルール (lilfes ファイル) |
入力ファイル | 入力の treebank (テキスト形式) |
出力データベース | 出力の treebank (lildb 形式) |
Enju の文法開発の場合,
入力ファイルの各行には Penn Treebank の各構文木が書かれています.
つまり入力ファイルの一行は次のようなテキストです.
treetrans は上のようなテキストを読み込み,
構文木を "mayz/treetypes.lil" で定義された素性構造に格納します.
その後,ルールモジュールに書かれたルールに従って素性構造を変形したり付加情報をつけたりして,
構文木の変形を行います.
変形後の構文木(例)は
lildb 形式のデータベースに格納され出力されます.
(S (NP-SBJ Ms./NNP Haag/NNP) (VP plays/VBZ (NP Elianti/NNP)) ./.)
実際の処理は次の順序で行われます.
この段階では, テキスト形式の構文木を読み込んでその木を表す素性構造を作ります. 具体的には, treetrans ツールから呼ばれるインターフェース述語 input_parse_tree/2 によって作業が行われます. 述語 input_parse_tree/2 を,構文木一個分のテキストが渡されたら対応する素性構造を返すように定義してください.
Enju 文法では入力 treebank として Penn Treebank を用いているので, input_parse_tree/2 の実体は Penn Treebank のために定義された述語 input_ptb_parse_tree/2 です. この述語は mayz で提供されており,"mayz/treeio.lil" で定義されています. 述語 input_ptb_parse_tree/2 では, 入力された木の形をほとんど変えずに素性構造にします. しかし葉ノードについてのみ,変更を加えるためのインターフェース述語 ptb_empty_category/1,ptb_delete_pos/1, ptb_morph/6 が用意されています. これらの述語を使い,葉ノードには次のような順序で変更が加えられます.
Enju文法の場合,葉ノードの変更に関して次のことを指定しています. 実装は "enju-devel/transmain.lil" にあります.
この段階では,パターンルールの適用前に構文木の素性構造を整形する処理を行います.
具体的には, 構文木のノードを深さ優先で見ていき,各ノードに対して整形処理をしていきます. 整形処理は, インターフェース述語 delete_tree/1,nonterminal_mapping/2, preterminal_mapping/4,preterminal_projection/2 を用いて,次のような順序で行われます.
Enju の場合,整形処理に関して次のように指定しています. 実装は "enju-devel/transmain.lil" にあります.
nonterminal_mapping("NAC", "NP"). preterminal_mapping("%", "NN", "%", "%").
この段階では,パターンルールを適用し構文木の変形を行います. 変形した構文木は出力データベースに格納されます.
Enju の場合,変形後の構文木を HPSG 構文木と似た形の木にすることが目的なので, パターンルールには次のようなものが含まれています.
変換のためのパターンルールは,インターフェース述語 tree_transform_class/3,tree_ignore/2, tree_transform_rule/3,tree_subst_pattern/3, tree_unify/2,tree_match_pattern/2 によって定義します. まずパターンルールを宣言するため, 述語 tree_transform_class/3 で名前,木のノードへの適用順序, 適用後の振る舞いを定義します. パターンルールは宣言された順に実行されます.
tree_transform_class(+$Name, +$Direction, +$Strict) | |||
+$Name | パターンルールの名前 | ||
+$Direction | パターンルールの適用順序
|
パターンルールの処理内容は,述語 tree_ignore/2, tree_transform_rule/3,tree_subst_pattern/3, tree_unify/2,tree_match_pattern/2 を用いて指定します.これらの述語を使い,ルールの処理は次のように行われます.
Enju の場合,次のようにパターンルールが定義されています.
このルールは "than" 句の構造を明示化するパターンルール,
つまり (... than/IN XXX) という構造を (... (PP than/IN XXX:argument)) と
いう構造に変換するパターンルールです.
tree_transform_class("than", "topdown", "weak").
tree_subst_pattern("than",
TREE_NODE\$Node & TREE_DTRS\$Dtrs,
TREE_NODE\$Node & TREE_DTRS\$NewDtrs) :-
$Dtrs = [$Left & tree_any & ANY_TREES\[_|_],
$Than & tree & TREE_NODE\(SYM\"IN" & WORD\SURFACE\"than"),
$Right & tree & TREE_NODE\HEAD_MARK\argument],
$NewDtrs = [$Left,
TREE_NODE\(SYM\"PP" & FUNC\[] & ID\[] & HEAD_MARK\modifier_non_empty) &
TREE_DTRS\[$Than, $Right]].
変換が終わった段階で, 構文木の各ノード TREENODE\SCHEMANAME\ 素性が正しい値であるよう注意してください. この素性は,そのノードの娘ノードに適用したスキーマ名であるとされ, 次の処理,辞書抽出で使われます.