Mac OS X Lionが出た。さっそくインストールした。マルチタッチジェスチャは秀逸だけど古いノートでは対応していなかった。もうマウスの時代は終わった感じがする。特にノートパソコンに外付けマウスをつけて使っている人はトラックパッドの便利さを知るべきだと思う。
デスクトップの場合はMagic Trackpadがいいようだ。
スピーチ機能が強化された
あちこちでLionのレビューがなされているので、ここは少し特殊なことを書こうと思う。250の新機能があるらしいが、比較的地味なスピーチ機能が強化されている。

Lion スピーチに中国語や日本語が追加されている
適当な中国語の文章をネットで拾って喋らせると、そこそこ上手く喋る。しかし、中国語の発音をどこに持たせているのだろうか?
ありそうなのはスピーチの音声と一緒に中国語の発音についての情報があること。もう一つはmecabの辞書が強化されていること。さて、どっちだろうか。
とりあえずmecabから調査しようと思って
mecab -d /usr/lib/mecab/dic/apple/tc/LE
すると
tagger.cpp(153) [tokenizer_.open(*param)] tokenizer.cpp(112) [unkdic_.open(create_filename (prefix, UNK_DIC_FILE).c_str(), mode)] dictionary.cpp(50) [version_ == DIC_VERSION] incompatible version: 103
となる。あれー、以前のバージョンでは特に問題なく辞書は使えた筈なんだけど。すこしぐぐると
http://namazu.asablo.jp/blog/2009/10/03/4613273
MeCab 0.98 の辞書のフォーマットは MeCab 0.94, 0.95, 0.96, 0.97 と同じ DIC_VERSION 102 です。
DIC_VERSION と MeCab のバージョンとの関係は次の通りです。
DIC_VERSION 102, MeCab 0.94, 0.95, 0.96, 0.97, 0.98
DIC_VERSION 101, MeCab 0.92, 0.93
DIC_VERSION 100, MeCab 0.90, 0.91
0.98まではバージョン102らしい。103というのはバージョンのことか。しかし使っているmecabは最新の0.98である。さて、どうすっぺ?
バージョン103の辞書が入っていると言うことはそれに対応したmecabがMac OS X Lionのどこかにあるはずだから、それを探せばいい。
find /usr -name mecab /usr/lib/mecab /usr/local/bin/mecab /usr/local/lib/mecab /usr/local/libexec/mecab
このmecabは違う。というかlocal以下は独自ビルドを入れるところだろうし、だとすると0.98より新しいものはあるはずもない。
どうせ辞書のフォーマットも大して変わっていないだろうから、mecabのソースを手に入れてMakefileのDIC_VERSIONを103に書き換えたインチキビルドをでっちあげる。その結果、
error in mecab_new2: tagger.cpp(153) [tokenizer_.open(*param)] tokenizer.cpp(164) [n.value != -1] cannot find UNK category: DEFAULT
DEFAULTがないって。。。夜貓族で眠いから今日はここまで。Lionではどうもmecabの辞書が変わっているような気がする。気のせいでなければ。変わっているとしたら何故か。もしかしてまともな中国語の形態素解析辞書が入っているのかなー。
追記:7月21日
mecabのdictionary.cppを見て大雑把な辞書の構造は把握。それに基づいて
#include < stdio.h> #include < iostream> using namespace std; struct Dictionary { unsigned int magic; unsigned int version; unsigned int type; unsigned int lexsize; unsigned int lsize; unsigned int rsize; unsigned int dsize; unsigned int tsize; unsigned int fsize; unsigned int dummy; }; static const unsigned int DictionaryMagicID = 0xef718f77u; int main( int c, char *v[] ) { FILE *in = fopen( v[1], "rb" ); Dictionary dic; fread( &dic, sizeof(dic), 1, in ); cout << (dic.magic ^ DictionaryMagicID) << endl; cout << dic.version << endl; cout << dic.type << endl; cout << dic.lexsize << endl; cout << dic.lsize << endl; cout << dic.rsize << endl; cout << dic.dsize << endl; cout << dic.tsize << endl; cout << dic.fsize << endl; cout << dic.dummy << endl; char charset[32]; fread( charset, 32, 1, in ); cout << charset << endl; unsigned char *data = new unsigned char[dic.dsize]; unsigned char *token = new unsigned char[dic.tsize]; unsigned char *feature = new unsigned char[dic.fsize]; fread( data, dic.dsize, 1, in ); fread( token, dic.tsize, 1, in ); fread( feature, dic.fsize, 1, in ); FILE *out = fopen( "out.txt", "wt" ); fwrite( data, dic.dsize, 1, out ); fwrite( token, dic.tsize, 1, out ); fwrite( feature, dic.fsize, 1, out ); delete [] data; delete [] token; delete [] feature; fclose(out); fclose(in); return 0; }
雑なコードだけど、これをコンパイルしてコマンドラインでsys.dicを第一引数に渡してやると
7495055 103 0 157193 390 390 1646293 2515088 3333602 0 UTF-16LE
を得る。さて問題は(わかりきっているけど)UTF-16LEであること。
そもそもC++の文字列は’