anthyで予測入力

組み込み向けというからには予測入力を実装したいよなーという話は未踏採択直後ぐらいからしてた。んでまーCodeFestに便乗して調べてみたという訳だ。とりあえず疑似コード。

in record.c

struct prediction_ent {
  /* 予測する元となる文字列 */
  xstr root_word; 

  /* seq_entの配列 */
  int nr_seq_ents;
  struct seq_ent *seq_ents;
};

static void
traverse_record_for_prediction(struct prediction_ent *pred_ent, struct trie_node *root_node)
{
    if (root_node)
        return;

    pred_ent->nr_seq_ents++;
    pred_ent->seq_ents == (struct seq_ent *)realloc(pred_ent->seq_ents,
                                                    sizeof(struct seq_ent) * pred_ent->nr_seq_ents);
    pred_ent->seq_ents[pred_ent->nr_seq_ents] = anthy_get_seq_ent_from_xstr(root_node->column.key);

    if (root_node->l)
        traverse_record_for_prediction(pred_ent, root_node->l);
    if (root_node->r)
        traverse_record_for_prediction(pred_ent, root_node->r);
}

struct prediction_ent
anthy_traverse_record_for_prediction(xstr *root_word)
{
    struct prediction_ent pred_ent;
    struct record_stat* rst;
    struct trie_node* root_node;

    pred_ent.root_word   = root_word;
    pred_ent.nr_seq_ents = 0;
    pred_ent.seq_ents    = NULL;

    if (anthy_select_section("CAND_HISTORY", 1)) {
        return pred_ent;
    }
    if (anthy_select_column(root_word, 0) == -1) {
        return pred_ent;
    }

    rst = anthy_current_record;
    root_node = rst->cur_column;
    traverse_record_for_prediction(&pred_ent, root_node);
}

まず、予測候補は確定したモノから引っ張ってくる事にする。そのために"CAND_HISTORY"セクションをselect。次に、anthy_select_columnして入力された文字とマッチしたtrieノードを取得する。マッチしたノードはanthy_current_record->cur_columnに代入されている。このノードをルートノードとして、trie構造をtraverseし、anthy_get_seq_ent_from_xstrとnodeのkeyを使用してseq_entを構成する(traverse_record_for_prediction)。これで候補で選んだ履歴からの予測候補が洗い出されると思う。ここ間違ってたらどないしよ...

次に重要なのは候補のスコアリングだ。今までの確定履歴を全部見て予測し、全ての候補を表示されてもそれはそれで困る。ここで参考にさせてもらうのはやはり小松先生のPRIMEだろう。PRIMEのdoc/memo/priority.txtによると、現在時刻・確定した時刻・期限切れとなる時間から優先度を算出している。実際、lib/engine/engine-userdict.rb等を見たらそうなっている。anthyにおいてはCAND_HISTRYに記録する際に確定した時刻も記録しておけば、PRIMEと同じ仕組みを使って優先度を判断出来る。まぁもっと簡単にやるなら、src-ordering/candhistory.cのHISTORY_DEPTHみたいな仕組みでやっても良いだろう。

予測候補を取得する為のAPIを作ったりする必要があるが、基本的には予測入力の導入は可能そうである。どうでせうかね?> oxy君、yusukeさん

んーどうも2人ともあんま乗り気じゃないので、ボツネタかな...個人的には欲しかった機能なんだけどなぁ。パッチ書いても取り込まれなさそうなんで、おとなしく諦めよう。