static void print_trans_rulesets(const char *filename) { int count, i; count = count_rulesets(); /* ルールセットテーブルで各ルールセットのデータ名を参照するので、先に個々のデータを出力する */ print_trans_rules(filename); fprintf(OUT, "struct trans_ruleset trans_%s_maindata_rulesets[%d] = {\n", filename, count); /* ruleset id is 2,3,4,5... ? 1:systemrulesetただし登録はされていない */ /* ruleset0番は存在しないが数合わせに出力 */ fprintf(OUT, " {0,0},\n"); /* ruleset1番はtableに登録されていないがsystemrulesetなので出力 */ fprintf(OUT, " {%d,trans_%s_1_rules},\n", lmn_ruleset_rule_num(system_ruleset), filename); /* ruleset2番,3番はinitial ruleset, initial system ruleset */ fprintf(OUT, " {%d,trans_%s_2_rules},\n", lmn_ruleset_rule_num(initial_ruleset), filename); fprintf(OUT, " {%d,trans_%s_3_rules},\n", lmn_ruleset_rule_num(initial_system_ruleset), filename); /* 以降は普通のrulesetなので出力(どれが初期データルールかはload時に拾う) */ for (i = FIRST_ID_OF_NORMAL_RULESET; i < count; i++) { LmnRuleSet rs = lmn_ruleset_from_id(i); LMN_ASSERT(rs); /* countで数えているからNULLにあたることはないはず */ fprintf(OUT, " {%d,trans_%s_%d_rules}", lmn_ruleset_rule_num(rs), filename, i); if(i != count - 1) { fprintf(OUT, ","); } fprintf(OUT, "\n"); } fprintf(OUT, "};\n"); fprintf(OUT, "int trans_%s_maindata_rulesetexchange[%d];\n\n", filename, count); }
/* バイト列refからバイト列orgへの差分を求めて返す. * org, ref共にRead Only */ LmnBinStr lmn_bscomp_d_encode(const LmnBinStr org, const LmnBinStr ref) { LmnBinStr dif; unsigned long org_8len, ref_8len, dif_8len; int ret, mul; #ifdef PROFILE unsigned long old_space, dif_space; if (lmn_env.profile_level >= 3) { profile_start_timer(PROFILE_TIME__D_COMPRESS); } #endif LMN_ASSERT(!is_comp_d(org)); /* diffからのdiff計算は禁止 */ org_8len = (org->len + 1) / TAG_IN_BYTE; ref_8len = (ref->len + 1) / TAG_IN_BYTE; mul = zd_buf_n; dif = NULL; dif_8len = org_8len; while (1) { if (dif) lmn_binstr_free(dif); dif_8len *= mul; dif = lmn_binstr_make(dif_8len); ret = zd_compress(ref->v, ref_8len, org->v, org_8len, dif->v, &dif_8len); if (ret == ZD_BUF_ERROR) { zd_buf_n *= mul; } else { break; } } if (ret != ZD_OK) { fprintf(stderr, "%s\n", zd_ret_str(ret)); lmn_fatal("fail to compress"); } dif->len = dif_8len * TAG_IN_BYTE + ((org->len & 0x1U) ? 1 : 0); dif->type = org->type; set_comp_d(dif); #ifdef PROFILE old_space = lmn_binstr_space(org); dif_space = lmn_binstr_space(dif); if (lmn_env.profile_level >= 3) { profile_add_space(PROFILE_SPACE__STATE_BINSTR, dif_space); profile_add_space(PROFILE_SPACE__REDUCED_BINSTR, old_space - dif_space); profile_finish_timer(PROFILE_TIME__D_COMPRESS); } #endif return dif; }
/* バイト列refに対して差分difを適用してorgを復元して返す. * メモリは読み出し専用 */ LmnBinStr lmn_bscomp_d_decode(const LmnBinStr ref, const LmnBinStr dif) { LmnBinStr org; unsigned long ref_8len, dif_8len, org_8len; int ret, mul; #ifdef PROFILE unsigned long org_space; if (lmn_env.profile_level >= 3) { profile_start_timer(PROFILE_TIME__D_UNCOMPRESS); } #endif LMN_ASSERT(is_comp_d(dif)); ref_8len = (ref->len + 1) / TAG_IN_BYTE; dif_8len = dif->len / TAG_IN_BYTE; mul = zd_buf_n; org = NULL; org_8len = ref_8len + dif_8len; while (1) { if (org) lmn_binstr_free(org); org_8len *= mul; org = lmn_binstr_make(org_8len); ret = zd_uncompress(ref->v, ref_8len, org->v, &org_8len, dif->v, dif_8len); if (ret == ZD_BUF_ERROR) { zd_buf_n *= mul; } else { break; } } if (ret != ZD_OK) { fprintf(stderr, "%s\n", zd_ret_str(ret)); lmn_fatal("fail to uncompress: zdlib"); } org->len = org_8len * TAG_IN_BYTE - ((dif->len & 0x1U) ? 1 : 0); org->type = dif->type; unset_comp_d(org); #ifdef PROFILE org_space = lmn_binstr_space(org); if (lmn_env.profile_level >= 3) { profile_add_space(PROFILE_SPACE__STATE_BINSTR, org_space); profile_finish_timer(PROFILE_TIME__D_UNCOMPRESS); } #endif return org; }
/* 状態sに対応するバイナリストリングを, sがrefする状態を基に再構築して返す. */ LmnBinStr state_binstr_reconstructor(State *s) { LmnBinStr ret; if (!s_is_d(s)) { ret = state_binstr(s); } else { LmnBinStr ref; LMN_ASSERT(state_D_ref(s)); ref = state_binstr_reconstructor(state_D_ref(s)); ret = lmn_bscomp_d_decode(ref, state_binstr(s)); if (s_is_d(state_D_ref(s))) { lmn_binstr_free(ref); } } return ret; }
/** -------------------------- * Method1: zlib * "A Massively Spiffy Yet Delicately Unobtrusive Compression Library" * @see http://www.zlib.net/ */ LmnBinStr lmn_bscomp_z_encode(const LmnBinStr org) { #ifndef HAVE_LIBZ return org; #else LmnBinStr cmp; unsigned long org_8len, cmp_8len; int ret; #ifdef PROFILE unsigned long old_space, cmp_space; if (lmn_env.profile_level >= 3) { profile_start_timer(PROFILE_TIME__Z_COMPRESS); } #endif LMN_ASSERT(!is_comp_z(org)); /* z圧縮の多重掛けは想定していない */ org_8len = (org->len + 1) / TAG_IN_BYTE; cmp_8len = org_8len * 2; cmp = lmn_binstr_make(cmp_8len); cmp->type = org->type; ret = compress(cmp->v, &cmp_8len, org->v, org_8len); if (ret != Z_OK) { /* zlib */ fprintf(stderr, "%s\n", ret == Z_MEM_ERROR ? "Z_MEM_ERROR" : "Z_BUF_ERROR"); lmn_fatal("fail to compress: zlib"); } cmp->len = cmp_8len * TAG_IN_BYTE + ((org->len & 0x1U) ? 1 : 0); set_comp_z(cmp); #ifdef PROFILE old_space = lmn_binstr_space(org); cmp_space = lmn_binstr_space(cmp); if (lmn_env.profile_level >= 3) { profile_add_space(PROFILE_SPACE__STATE_BINSTR, cmp_space); profile_add_space(PROFILE_SPACE__REDUCED_BINSTR, old_space - cmp_space); profile_finish_timer(PROFILE_TIME__Z_COMPRESS); } #endif return cmp; #endif }
LmnBinStr lmn_bscomp_z_decode(const LmnBinStr cmp) { #ifndef HAVE_LIBZ return cmp; #else LmnBinStr org; unsigned long cmp_8len, org_8len; int ret; #ifdef PROFILE unsigned long org_space; if (lmn_env.profile_level >= 3) { profile_start_timer(PROFILE_TIME__Z_UNCOMPRESS); } #endif LMN_ASSERT(is_comp_z(cmp)); cmp_8len = cmp->len / TAG_IN_BYTE; org_8len = cmp_8len * 5; org = lmn_binstr_make(org_8len); ret = uncompress(org->v, &org_8len, cmp->v, cmp_8len); if (ret != Z_OK) { /* zlib */ fprintf(stderr, "%s\n", ret == Z_MEM_ERROR ? "Z_MEM_ERROR" : "Z_BUF_ERROR"); lmn_fatal("fail to uncompress: zlib"); } org->type = cmp->type; org->len = org_8len * TAG_IN_BYTE - ((cmp->len & 0x1U) ? 1 : 0); unset_comp_z(org); #ifdef PROFILE org_space = lmn_binstr_space(org); if (lmn_env.profile_level >= 3) { profile_add_space(PROFILE_SPACE__STATE_BINSTR, org_space); profile_finish_timer(PROFILE_TIME__Z_UNCOMPRESS); } #endif return org; #endif }
/* TODO: 美しさ */ void state_print_transition(State *s, LmnWord _fp, LmnWord _owner) { FILE *f; StateSpace owner; unsigned int i; BOOL need_id_foreach_trans; char *state_separator, *trans_separator, *label_begin, *label_end; BOOL formated; /* Rehashが発生している場合, * サクセッサへの情報は, RehashしたオリジナルのStateオブジェクトが保持しているため, * dummyフラグが真かつエンコード済みの状態には遷移情報は載っていない. * (エンコード済のバイナリストリングしか載っていない) */ if ((is_dummy(s) && is_encoded(s))) return; f = (FILE *)_fp; owner = (StateSpace)_owner; need_id_foreach_trans = TRUE; switch (lmn_env.mc_dump_format) { case DOT: state_separator = " -> "; trans_separator = NULL; label_begin = " [ label = \""; label_end = "\" ];"; break; case FSM: state_separator = " "; trans_separator = NULL; label_begin = " \""; label_end = "\""; break; case LaViT: /* FALLTHROUGH: CUIモードと共通 */ case CUI: state_separator = "::"; /* なぜかspaceが混ざるとlavitは読み込むことができない */ trans_separator = ","; label_begin = "("; label_end = ")"; need_id_foreach_trans = FALSE; break; default: lmn_fatal("unexpected"); break; } formated = owner ? owner->is_formated : FALSE; if (!need_id_foreach_trans) { fprintf(f, "%lu%s", state_format_id(s, formated), state_separator); } if (s->successors) { for (i = 0; i < state_succ_num(s); i++) { /* dump dst state's IDs */ if (need_id_foreach_trans) { fprintf(f, "%lu%s", state_format_id(s, formated), state_separator); } else if (i > 0) { LMN_ASSERT(trans_separator); fprintf(f, "%s", trans_separator); } /* MEMO: rehashが発生していても, successorポインタを辿る先は, オリジナル */ fprintf(f, "%lu", state_format_id(state_succ_state(s, i), formated)); if (has_trans_obj(s)) { Transition t; unsigned int j; fprintf(f, "%s", label_begin); t = transition(s, i); for (j = 0; j < transition_rule_num(t); j++) { if (j > 0) fprintf(f, " "); /* ルール名の区切りは半角スペース1文字 */ fprintf(f, "%s", lmn_id_to_name(transition_rule(t, j))); } fprintf(f, "%s", label_end); } if (i + 1 < state_succ_num(s) && need_id_foreach_trans) { fprintf(f,"\n"); } } fprintf(f, "\n"); } else if (!need_id_foreach_trans){ fprintf(f, "\n"); } }
void tr_instr_commit_ready(LmnReactCxt *rc, LmnRule rule, lmn_interned_str rule_name, LmnLineNum line_num, LmnMembrane **ptmp_global_root, LmnRegister **p_v_tmp, unsigned int *org_next_id) { LMN_ASSERT(rule); lmn_rule_set_name(rule, rule_name); *org_next_id = env_next_id(); #ifdef KWBT_OPT if (lmn_env.opt_mode != OPT_NONE) { lmn_fatal("translter mode, optimize mode is not supported"); } #endif if (RC_GET_MODE(rc, REACT_PROPERTY)) { return; } if (RC_GET_MODE(rc, REACT_ND)) { if (RC_MC_USE_DMEM(rc)) { /* dmemインタプリタ(body命令)を書かないとだめだ */ lmn_fatal("transalter mode, delta-membrane execution is not supported."); } else { LmnRegister *v, *tmp; ProcessTbl copymap; LmnMembrane *tmp_global_root; unsigned int i, warry_size_org, warry_use_org; #ifdef PROFILE if (lmn_env.profile_level >= 3) { profile_start_timer(PROFILE_TIME__STATE_COPY_IN_COMMIT); } #endif warry_size_org = warry_size(rc); warry_use_org = warry_use_size(rc); tmp_global_root = lmn_mem_copy_with_map(RC_GROOT_MEM(rc), ©map); /** 変数配列および属性配列のコピー */ v = lmn_register_make(warry_size_org); /** copymapの情報を基に変数配列を書換える */ #ifdef TIME_OPT for (i = 0; i < warry_use_org; i++) { LmnWord t; v[i].at = at(rc, i); v[i].tt = tt(rc, i); if (v[i].tt == TT_ATOM) { if (LMN_ATTR_IS_DATA(v[i].at)) { v[i].wt = (LmnWord)lmn_copy_data_atom((LmnAtom)wt(rc, i), (LmnLinkAttr)v[i].at); } else if (proc_tbl_get_by_atom(copymap, LMN_SATOM(wt(rc, i)), &t)) { v[i].wt = (LmnWord)t; } else { t = 0; lmn_fatal("implementation error"); } } else if (v[i].tt == TT_MEM) { if (wt(rc, i) == (LmnWord)RC_GROOT_MEM(rc)) { /* グローバルルート膜 */ v[i].wt = (LmnWord)tmp_global_root; } else if (proc_tbl_get_by_mem(copymap, (LmnMembrane *)wt(rc, i), &t)) { v[i].wt = (LmnWord)t; } else { t = 0; lmn_fatal("implementation error"); } } else { /* TT_OTHER */ v[i].wt = wt(rc, i); } } #else for (i = 0; i < warry_size_org; i++) { v[i].at = at(rc, i); if (LMN_ATTR_IS_DATA(v[i].at)) { v[i].wt = (LmnWord)lmn_copy_data_atom((LmnAtom)wt(rc, i), (LmnLinkAttr)v[i].at); } else if (proc_tbl_get(copymap, wt(rc, i), &t)) { v[i].wt = t; } else if(wt(rc, i) == (LmnWord)RC_GROOT_MEM(rc)) { /* グローバルルート膜 */ v[i].wt = (LmnWord)tmp_global_root; } } #endif proc_tbl_free(copymap); /** SWAP */ tmp = rc_warry(rc); rc_warry_set(rc, v); #ifdef PROFILE if (lmn_env.profile_level >= 3) { profile_finish_timer(PROFILE_TIME__STATE_COPY_IN_COMMIT); } #endif /* 処理中の変数を外へ持ち出す */ *ptmp_global_root = tmp_global_root; *p_v_tmp = tmp; } } }
struct SpecialAtomCallback *sp_atom_get_callback(int id) { LMN_ASSERT(vec_num(sp_atom_callback_tbl) > id); return (struct SpecialAtomCallback *)vec_get(sp_atom_callback_tbl, id); }