Section 2: WAM の基礎

このセクションでは極めて簡単な WAM ファイルを作り, GETA および WAM の基本構成要素とそのセットアップの方法について学びます.

2.1 ci.conf の作成

GETA では, WAM に関するメタ知識を"$GETAROOT/etc/ci.conf"というファイルに記述します. まず, このセクションで必要なメタ知識を$GETAROOT/etc/ci.confに追加します. GETA をインストールしたばかりで, まだ, $GETAROOT/etc/ci.confが無ければファイルを新たに作成して下さい.

このセクションでは"test.walkuere.geta.hatoyama.hitachi.co.jp"という名前(ハンドルと呼びます)の WAM を作成します. この例ではハンドルの最後にドメインネームを付しています. こうすることでハンドルがユニークに定まる様になりますが, これは慣習でしかありません. また, この様にして付けたハンドルは多くの場合長くなるので扱いが面倒です. そこで, GETA では別名として短い呼び名(ショートネームと呼びます)を付ける機能が提供されています. この例ではショートネームを "test"にします. なお, これらの名前は衝突してはいけないことにも 注意して下さい.

この様にハンドルが決まったら$GETAROOT/etc/ci.confに, 以下に示す 2 行を追加します.


handle: test.walkuere.geta.hatoyama.hitachi.co.jp
short-name: test

これでci.confの準備は終わりです.

2.2 WAM の基礎知識(名前, 内部表現, etc.)

ここで少しこみいった話をします. ややこしいので, 例を混じえて説明しましょう.

ここでは以下の様な 3行×4列の WAM を仮定します. なお, WAM の要素は0..232-1(圧縮モードでは0..228-1) の範囲の正の整数です.

        WAM:
             Ci       Cii      Ciii     Civ
        Ra    3        0        2        1
        Rb    0        1        5        0
        Rc    0        0        4        3

WAM の行や列には全て固有の名前(以後, name)が付きます. この例に出て来た"Ra"や"Ci"などがそれです. また, 行と列にはそれぞれ 1 から通し番号が振られています. これが ID です. このことから, WAM の行か列が決まれば, ID と name は 1 対 1 に対応が決まります. name と ID の対応表は CW と呼ばれ, libwam に含まれる libcw というモジュールがこれを管理します. 以下の様な具合です.

                    ID: 1    2    3    4
        行(ROW)のname: Ra   Rb   Rc
        列(COL)のname: Ci   Cii  Ciii Civ
例えば, Rbの ID は 2, Ciiiの ID は 3, となります. name と ID の相互変換は, cw_id2name(3), cw_name2id(3) などの関数で行うことが可能です. なお, ID の割り振りはシステムが自動で行うため, どの name がどの ID になるかをユーザが指定することはできません(*1).

行列本体は libwam に含まれる libxr というモジュールにより管理されます(そのインスタンスを XR と呼びます). libxr では行や列を指定するのに, name ではなく ID を用います. 例えば, この WAM の Rb,Ciii要素(その値は5)は, XR では 2, 3 要素ということになります.

libxr は, 行列をそのまま管理するのではなく, 行(列)ごとに, 値が 0 でない要素についてだけその列(行)の ID と共に管理しています. 以下の様な具合です.

        行1: elem_num=3, freq_sum=6, (列=1,値=3), (列=3,値=2), (列=4,値=1)
        行2: elem_num=2, freq_sum=6, (列=2,値=1), (列=3,値=5)
        行3: elem_num=2, freq_sum=7, (列=3,値=4), (列=4,値=3)

        列1: elem_num=1, freq_sum=3, (行=1,値=3)
        列2: elem_num=1, freq_sum=1, (行=2,値=1)
        列3: elem_num=3, freq_sum=11, (行=1,値=2), (行=2,値=5), (行=3,値=4)
        列4: elem_num=2, freq_sum=4, (行=1,値=1), (行=3,値=3)
ここに,
        elem_num は値が 0 でないその行(列)の要素の数, 
        freq_sum はその行(列)の値の合計
です. そして, xr_get_vec(3) で WAM のデータを取り出すと, 常にこの形式のデータが返されます. これが WAM の内部表現です.


*1: 現在の実装では, 行の ID は 次節で説明する外部表現に現れた順に, 列の ID は, その値の合計が大きい順に 1 から振られますが, この動作は将来に渡って保証されるものではありません.

2.3 WAM の外部表現

CW や XR は, 計算機上で name の表や行列のデータを効率的に扱うことができるよう WAM の内部表現をさらに圧縮した形式で管理しており, ユーザがその様な形式のファイルを直接作るのは大変です. そのために, freqfile(5)形式と呼ばれる WAM の外部表現形式が準備されており, mkwというコマンドを用いることでフォーマット変換を行うことができます.

freqfile(5) はline(*2)指向のテキストファイルで, WAM を行ごとに, 列の name とその値の組を 1 line ごとに表現したものです. つまり, freqfile の 1 line は WAM の 1 要素(*3)に相当します. そして, WAM の1行は, freqfile の複数の line で表されるということになります.

WAM の 1 行は, freqfile では次の様に記述されます. まず, 先頭の文字が '@' である line により行の name が示されます. '@' の直後の文字から改行文字の直前までが行の name です. ここから次の '@' で始まる line の直前の line までがその行に関する記述です. ここではその行の(値が0でない)各要素がそれぞれ 1 line で記述されます. 行の name の記述および要素の記述は以下の通りです.

        '@',  行の name, 改行

        要素の値(1個以上の数字の列), ちょうど1個の空白文字(040), 列の name, 改行
WAM の全部の行について, それぞれ記述を 1 つのファイルに連続して書いたものがその WAM の外部表現になります. 以下に 2.2 の WAM の外部表現(*4)を示します.
@Ra
3 Ci
2 Ciii
1 Civ
@Rb
1 Cii
5 Ciii
@Rc
4 Ciii
3 Civ

*2: WAMの行と, テキストファイルの行がまぎらわしいので, テキストファイルの行には line という言葉をあてておきます.
*3: 同じ name の列が複数回現れた場合値の和が計算されるので, この説明は正確ではない.
*4: 一般に同一の WAM についての外部表現や, 内部表現は複数存在し得ます.

2.4 セットアップの準備

このセクションでは, 2.2 で仮定した WAM をセットアップする準備をします. WAM のデータは標準では$GETAROOT/data/$handle以下に置かれます(*5). ここに, $handleはその WAM のハンドルです. (この例ではtest.walkuere.geta.hatoyama.hitachi.co.jpです. )GETAROOTなどは GETA をインストールした時にセットされているものを使います.

まず, $GETAROOT/data/$handleを作ります.

        $ handle=test.walkuere.geta.hatoyama.hitachi.co.jp
        $ mkdir -p $GETAROOT/data/$handle
次に, 2.3 で説明した WAM の外部表現を$GETAROOT/data/$handle/freqfileという名前で作成します.
        $ your-favorite-editor $GETAROOT/data/$handle/freqfile
or
        $ your-freqfile-generotr $GETAROOT/data/$handle/freqfile
これで準備は完了です.


*5: このディレクトリは$GETAROOT/etc/ci.confでdataroot属性を指定することで WAM ごとに変更可能です.

2.4 セットアップの実行

"mkw"というコマンドによりセットアップを実行します. 作業ディレクトリはどこでも構いません(*6).

        $ handle=test.walkuere.geta.hatoyama.hitachi.co.jp
        $ $GETAROOT/sbin/mkw $handle $GETAROOT/data/$handle/freqfile
これで, $GETAROOT/data/$handle以下にcw.c, cw.r, xr.c, xr.rという 4 つのファィルができます. これでセットアップは完了です.


*6: 実は freqfile もどこにあっても構いません. しかし, freqfile は何回も走査されますから, NFS や CD-ROM など低速のデバイス上に置くのは避けた方が良いでしょう.

2.5 セットアップされたファイルの確認

2.4 でセットアップされた WAM の内容を確認してみましょう. 幸いこの WAM は非常に小さいので 全体をタイプして人間の力で確認することができます. はじめに(タイピングの負担を軽減するために)環境変数をセットしておきます.

        $ handle=test.walkuere.geta.hatoyama.hitachi.co.jp
まず, CW の印刷から試します. CW には行と列の二つがあります. 行の CW は
        $ $GETAROOT/bin/dumpwam $handle cw_row
列の CW は
        $ $GETAROOT/bin/dumpwam $handle cw_col
で印刷されます. CW は ID の順に表示されます. この表示結果で列の CW は注意が必要です. 列の name の順序が 2.2 で仮定した WAM の順序と異っています. これは, 列の ID はその列の値の合計が多い順に振られるためです(*7).

次に, XR をタイプさせてみます. dumpwam により, 行方向の XR と, 列方向の XR をそれぞれ印刷することができます.

        $ $GETAROOT/bin/dumpwam $handle xr_row
        $ $GETAROOT/bin/dumpwam $handle xr_col

この様にして, 先の例や, freqfile とは, 列の ID (順番)が変わっているので少しみづらいですが, 同じものが印刷されていることを確認することができます. dumpwamでは特定の ID の情報だけをタイプさせることもできます. 例えば

        $ $GETAROOT/bin/dumpwam $handle cw_row 1
とすれば, 行 ID が 1 の行の name が, また,
        $ $GETAROOT/bin/dumpwam $handle xr_col 2
とすると列 ID が 2 の列についての情報がタイプされます.

なお, ここまでハンドルを使ってきましたが, ショートネームで代用することができます. そうすることでタイプの手間を削減することができます.


*7: 現在の実装ではそうなっているということ. この振舞は将来変更される可能性があるので, ユーザアプリケーションはこのことに依存すべきではない.