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