diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2009-02-07 16:32:56 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2009-02-07 16:32:56 +0000 |
commit | a7a06a7ccfe0af1e134357678b8fa6cf87dff3b0 (patch) | |
tree | a966aeee62e69ae3ad13275d07ddb15049b14e0e /src-ordering/candswap.c | |
download | anthy-master.tar.gz |
anthy-9100hHEADanthy-9100hmaster
Diffstat (limited to 'src-ordering/candswap.c')
-rw-r--r-- | src-ordering/candswap.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/src-ordering/candswap.c b/src-ordering/candswap.c new file mode 100644 index 0000000..79e2ac8 --- /dev/null +++ b/src-ordering/candswap.c @@ -0,0 +1,216 @@ +/* + * 候補の交換のヒストリを管理する。 + * + * anthy_swap_cand_ent() で学習する + * anthy_proc_swap_candidate() で学習結果を用いる + * + * 「田端が」という候補をトップに出して「田畑が」で確定された場合は + * 自立語部:「田端」->「田畑」 + * の二つのエントリを追加する + * + */ +#include <stdlib.h> + +#include <anthy/record.h> +#include <anthy/segment.h> +/* for OCHAIRE_SCORE */ +#include <anthy/splitter.h> +#include "sorter.h" + +#define MAX_INDEP_PAIR_ENTRY 100 + +/* 候補の自立語部を学習する */ +static void +learn_swap_cand_indep(struct cand_ent *o, struct cand_ent *n) +{ + xstr os, ns; + int res; + int o_idx = o->core_elm_index; + int n_idx = n->core_elm_index; + + /* 自立語部を含む文節しか学習しない */ + if (o_idx < 0 || n_idx < 0) { + return ; + } + if (o->elm[o_idx].str.len != n->elm[n_idx].str.len) { + return ; + } + if (o->elm[o_idx].nth == -1 || n->elm[n_idx].nth == -1) { + return ; + } + res = anthy_get_nth_dic_ent_str(o->elm[o_idx].se, &o->elm[o_idx].str, + o->elm[o_idx].nth, &os); + if (res) { + return ; + } + res = anthy_get_nth_dic_ent_str(n->elm[n_idx].se, &n->elm[n_idx].str, + n->elm[n_idx].nth, &ns); + if (res) { + free(os.str); + return ; + } + if (anthy_select_section("INDEPPAIR", 1) == 0) { + if (anthy_select_row(&os, 1) == 0) { + anthy_set_nth_xstr(0, &ns); + } + } + free(os.str); + free(ns.str); +} + +/* + * 候補o を出したらn がコミットされたので + * o -> n をrecordにセットする + */ +void +anthy_swap_cand_ent(struct cand_ent *o, struct cand_ent *n) +{ + if (o == n) { + /* 同じ候補 */ + return ; + } + if (n->flag & CEF_USEDICT) { + /* 用例辞書から出てきた候補 */ + return ; + } + /* 自立語部 */ + learn_swap_cand_indep(o, n); +} + + +/* + * 変換時に生成した候補を並べた状態で最優先の候補を決める + * ループの除去なども行う + */ +static xstr * +prepare_swap_candidate(xstr *target) +{ + xstr *xs, *n; + if (anthy_select_row(target, 0) == -1) { + return NULL; + } + xs = anthy_get_nth_xstr(0); + if (!xs) { + return NULL; + } + /* 第一候補 -> xs となるのを発見 */ + anthy_mark_row_used(); + if (anthy_select_row(xs, 0) != 0){ + /* xs -> ⊥ */ + return xs; + } + /* xs -> n */ + n = anthy_get_nth_xstr(0); + if (!n) { + return NULL; + } + + if (!anthy_xstrcmp(target, n)) { + /* 第一候補 -> xs -> n で n = 第一候補のループ */ + anthy_select_row(target, 0); + anthy_release_row(); + anthy_select_row(xs, 0); + anthy_release_row(); + /* 第一候補 -> xs を消して、交換の必要は無し */ + return NULL; + } + /* 第一候補 -> xs -> n で n != 第一候補なので + * 第一候補 -> nを設定 + */ + if (anthy_select_row(target, 0) == 0){ + anthy_set_nth_xstr(0, n); + } + return n; +} + +#include <src-worddic/dic_ent.h> + +/* + * 自立語のみ + */ +static void +proc_swap_candidate_indep(struct seg_ent *se) +{ + xstr *xs; + xstr key; + int i; + int core_elm_idx; + int res; + struct cand_elm *core_elm; + + core_elm_idx = se->cands[0]->core_elm_index; + if (core_elm_idx < 0) { + return ; + } + + /* 0番目の候補の文字列を取り出す */ + core_elm = &se->cands[0]->elm[core_elm_idx]; + if (core_elm->nth < 0) { + return ; + } + res = anthy_get_nth_dic_ent_str(core_elm->se, + &core_elm->str, + core_elm->nth, + &key); + if (res) { + return ; + } + + /**/ + anthy_select_section("INDEPPAIR", 1); + xs = prepare_swap_candidate(&key); + free(key.str); + if (!xs) { + return ; + } + + /* 第一候補 -> xs なので xsの候補を探す */ + for (i = 1; i < se->nr_cands; i++) { + if (se->cands[i]->nr_words == se->cands[0]->nr_words && + se->cands[i]->core_elm_index == core_elm_idx) { + xstr cand; + res = anthy_get_nth_dic_ent_str(se->cands[i]->elm[core_elm_idx].se, + &se->cands[i]->elm[core_elm_idx].str, + se->cands[i]->elm[core_elm_idx].nth, + &cand); + if (res == 0 && + !anthy_xstrcmp(&cand, xs)) { + free(cand.str); + /* みつけたのでその候補のスコアをアップ */ + se->cands[i]->score = se->cands[0]->score + 1; + return ; + } + free(cand.str); + } + } +} + +/* + * 変換時に生成した候補を並べた状態で最優先の候補を決める + */ +void +anthy_proc_swap_candidate(struct seg_ent *seg) +{ + if (NULL == seg->cands) { /* 辞書もしくは学習データが壊れていた時の対策 */ + return; + } + + if (seg->cands[0]->score >= OCHAIRE_SCORE) { + /* cands[0] は特別な点数を持っている */ + return ; + } + if (seg->cands[0]->flag & CEF_USEDICT) { + return ; + } + /**/ + proc_swap_candidate_indep(seg); +} + +/* 候補交換の古いエントリを消す */ +void +anthy_cand_swap_ageup(void) +{ + if (anthy_select_section("INDEPPAIR", 0) == 0) { + anthy_truncate_section(MAX_INDEP_PAIR_ENTRY); + } +} |