Mac で SimString を使ってみた

類似文字列検索ライブラリの SimString を Mac で使ってみました。
ちょっとググった感じだと Mac でのインストール方法が見つからなかったので、しょーもない内容ですが載せておきます。

とりあえず使ってみる

formula を作ったので、たぶん次のコマンドでインストールできます。

% brew tap abicky/formulae
% brew install simstring

試しに日本語版 Wikipedia のタイトルを検索できるようにしてみます。

% curl -LO http://dumps.wikimedia.org/jawiki/20150602/jawiki-20150602-all-titles.gz
% gunzip jawiki-20150602-all-titles.gz
% tail +2 jawiki-20150602-all-titles | simstring -bu -d jawiki-20150602-all-titles.db
% simstring -u -d jawiki-20150602-all-titles.db -t 0.7 -s cosine
スパゲティ
        ゲティ
        パスティ
        パステウ
        パステナ
        パステル
        スパゲティ
        パスティス
        パスティス
        スパゲッティ
        スパゲティー
        スパゲッティ
        スパゲッティー
        スパゲティ継承
        たらこスパゲティ
        スパゲッティの木
        スパゲッティーニ
        スパゲッティ継承
        スパゲティコード
        明太スパゲッティ
        スパゲッティーノ
        あんかけスパゲティ
        たらこスパゲッティ
        スパゲッティコード
        スパゲティーの年に
        ママースパゲッティ
        明太子スパゲッティ
        チャックスパゲティ
27 strings retrieved (0.033896 sec)

ちゃんと動いてそうですね!!

ハマりどころ

まず、公式サイトに用意さいれているアーカイブのやつはそのままだとインストールできません。

% curl -LO http://www.chokkan.org/software/dist/simstring-1.0.tar.gz
% tar xvf simstring-1.0.tar.gz
% cd ./simstring-1.0
% ./configure
% make
/Applications/Xcode.app/Contents/Developer/usr/bin/make  all-recursive
Making all in include
make[2]: Nothing to be done for `all'.
Making all in frontend
g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../include   -O3 -ffast-math  -O3 -ffast-math  -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cpp
In file included from main.cpp:43:
In file included from ../include/simstring/simstring.h:52:
In file included from ../include/simstring/memory_mapped_file.h:62:
../include/simstring/memory_mapped_file_posix.h:91:19: error: no type named 'close' in the global namespace
                ::close(m_fd);
                ~~^
../include/simstring/memory_mapped_file_posix.h:106:15: error: no type named 'close' in the global namespace
            ::close(m_fd);
            ~~^
../include/simstring/memory_mapped_file_posix.h:126:19: error: no member named 'lseek' in the global namespace; did you mean 'fseek'?
            if (::lseek(m_size, size, SEEK_SET) >= 0) {
                ~~^~~~~
                  fseek
/usr/include/stdio.h:249:6: note: 'fseek' declared here
int      fseek(FILE *, long, int);
         ^
In file included from main.cpp:43:
In file included from ../include/simstring/simstring.h:52:
In file included from ../include/simstring/memory_mapped_file.h:62:
../include/simstring/memory_mapped_file_posix.h:126:25: error: cannot initialize a parameter of type 'FILE *' (aka '__sFILE *') with an
      lvalue of type 'size_type' (aka 'unsigned long')
            if (::lseek(m_size, size, SEEK_SET) >= 0) {
                        ^~~~~~
/usr/include/stdio.h:249:18: note: passing argument to parameter here
int      fseek(FILE *, long, int);
                     ^
In file included from main.cpp:43:
In file included from ../include/simstring/simstring.h:52:
In file included from ../include/simstring/memory_mapped_file.h:62:
../include/simstring/memory_mapped_file_posix.h:128:21: error: use of undeclared identifier 'read'
                if (read(m_fd, &c, sizeof(char)) == -1) {
                    ^
../include/simstring/memory_mapped_file_posix.h:131:21: error: use of undeclared identifier 'write'
                if (write(m_fd, &c, sizeof(char)) == -1) {
                    ^
6 errors generated.
make[2]: *** [main.o] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

というわけで、GitHub で公開されている最新バージョンをインストールしてみました。

% git clone git@github.com:chokkan/simstring.git
% ./autogen.sh
% ./configure
% make install

ところが、データベースの構築が一瞬で終わってしまいます。”Total number of strings: 9”!!

% tail +2 jawiki-20150602-all-titles | simstring -bu -d jawiki-20150602-all-titles.db
SimString 1.1 Copyright (c) 2009-2011 Naoaki Okazaki

Constructing the database
Database name: jawiki-20150602-all-titles.db
N-gram length: 3
Begin/end marks: false
Char type: w (4)
Number of strings: 9

Flushing the database

Total number of strings: 9
Seconds required: 0.001341

検索の際にも日本語を入力するとそこで終了しています。

ちょっと調べた感じだと main 関数の次の内容があるとワイド文字がファイル終端とみなされるみたいなのでコメントアウトする patch を適用することにしました。

    // Change the locale of wcin and wcout if necessary.
    if (opt.code == option::CC_WCHAR) {
        std::ios_base::sync_with_stdio(false);
        std::locale::global(std::locale("")); 
        std::wcout.imbue(std::locale(""));
        std::wcin.imbue(std::locale(""));
    }