void state_print_label(State *s, LmnWord _fp, LmnWord _owner) { Automata a; FILE *f; StateSpace owner; owner = (StateSpace)_owner; if (!statespace_has_property(owner) || (is_dummy(s) && is_encoded(s))) { return; } a = statespace_automata(owner); f = (FILE *)_fp; switch (lmn_env.mc_dump_format) { case Dir_DOT: { if (state_is_accept(a, s) || state_is_end(a, s)) { fprintf(f, " %lu [peripheries = 2]\n", state_format_id(s, owner->is_formated)); } break; } case LaViT: fprintf(f, "%lu::", state_format_id(s, owner->is_formated)); fprintf(f, "%s\n", automata_state_name(a, state_property_state(s))); case FSM: case CUI: /* 状態のグローバルルート膜の膜名としてdump済 */ break; default: lmn_fatal("unexpected"); break; } }
/* 状態sに対応する階層グラフ構造Xを, Xに対して一意なIDとなるバイナリストリングへエンコードする. * エンコードしたバイナリストリングをsに割り当てる. * sに対応する階層グラフ構造Xへのメモリ参照が消えるため, 呼び出し側でメモリ管理を行う. * sが既にバイナリストリングを保持している場合は, そのバイナリストリングは破棄する. * (ただし, sが既に一意なIDとなるバイナリストリングへエンコード済みの場合は何もしない.) * 既に割当済みのバイナリストリングを破棄するため, * sをハッシュ表に登録した後の操作はMT-unsafeとなる. 要注意. */ void state_calc_mem_encode(State *s) { if (!is_encoded(s)) { LmnBinStr mid; if (state_mem(s)) { mid = lmn_mem_encode(state_mem(s)); } else if (state_binstr(s)) { LmnMembrane *m; m = lmn_binstr_decode(state_binstr(s)); mid = lmn_mem_encode(m); state_free_binstr(s); lmn_mem_free_rec(m); } else { lmn_fatal("unexpected."); } state_set_binstr(s, mid); s->hash = binstr_hash(state_binstr(s)); set_encoded(s); } }
/* 状態sに対応する階層グラフ構造をバイナリストリングにエンコードして返す. * sのフラグを操作する. */ LmnBinStr state_calc_mem_dump(State *s) { LmnBinStr ret; if (state_binstr(s)) { /* 既にエンコード済みの場合は何もしない. */ ret = state_binstr(s); } else if (state_mem(s)) { ret = lmn_mem_to_binstr(state_mem(s)); if (s_is_d(s) && state_D_ref(s)) { LmnBinStr dif; dif = state_binstr_D_compress(ret, state_D_ref(s)); /* 元のバイト列は直ちに破棄せず, 一時的にキャッシュしておく. */ state_D_cache(s, ret); ret = dif; } else { s_unset_d(s); } } else { lmn_fatal("unexpected."); ret = NULL; } return ret; }
/** * 引数としてあたえられたStateが等しいかどうかを判定する */ static int state_equals_with_compress(State *check, State *stored) { LmnBinStr bs1, bs2; int t; #ifdef PROFILE if (lmn_env.prof_no_memeq) { /* 本フラグが真の場合はグラフ同形成判定を行わず, ハッシュ値の一致不一致で状態の等価性を判定する. * ハッシュコンフリクトで完全性が損なわれるが, . * ハッシュ値が完全に散らばることが既知の問題に対し, メモリ使用量等のプロファイルを取る際など, * プロファイル収集を円滑に行うべく使用する. グラフ同型成判定の時間分だけ高速化できる */ return (state_hash(check) == state_hash(stored)); } #endif if (s_is_d(check)) { bs1 = state_D_fetch(check); } else { bs1 = state_binstr(check); } if (s_is_d(stored)) { bs2 = state_binstr_reconstructor(stored); } else { bs2 = state_binstr(stored); } if (is_encoded(check) && is_encoded(stored)) { /* 膜のIDで比較 */ t = check->state_name == stored->state_name && binstr_compare(bs1, bs2) == 0; } else if (state_mem(check) && bs2) { /* 同型性判定 */ t = check->state_name == stored->state_name && lmn_mem_equals_enc(bs2, state_mem(check)); } else if (bs1 && bs2) { /* このブロックは基本的には例外処理なので注意. * PORなどでコピー状態を挿入する際に呼ばれることがある. */ LmnMembrane *mem = lmn_binstr_decode(bs1); t = check->state_name == stored->state_name && lmn_mem_equals_enc(bs2, mem); lmn_mem_free_rec(mem); } else { lmn_fatal("implementation error"); } if (s_is_d(stored)) { lmn_binstr_free(bs2); } return t; }
/* バイト列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; }
static int state_equals(State *s1, State *s2) { #ifdef DEBUG if (is_binstr_user(s1) || is_binstr_user(s2)) { lmn_fatal("unexpected"); } #endif return s1->state_name == s2->state_name && s1->hash == s2->hash && lmn_mem_equals(state_mem(s1), state_mem(s2)); }
/* workerの実行アルゴリズムの割当を行う */ static void worker_set_env(LmnWorker *w) { if (!lmn_env.nd) { lmn_fatal("UnExepcted Yet."); } if (lmn_env.enable_parallel) worker_set_parallel(w); if (lmn_env.optimize_loadbalancing) worker_set_dynamic_lb(w); if (!lmn_env.bfs) { /* Depth First Search */ dfs_env_set(w); } else { /* Breadth First Search */ bfs_env_set(w); } if (lmn_env.ltl) { if (lmn_env.enable_owcty) { owcty_env_set(w); } else if (lmn_env.enable_map) { map_env_set(w); } else if(lmn_env.enable_mapndfs) { mapndfs_env_set(w); #ifndef MINIMAL_STATE } else if(lmn_env.enable_mcndfs) { mcndfs_env_set(w); #endif } else if (lmn_env.enable_bledge || worker_use_lsync(w) || worker_on_mc_bfs(w)) { bledge_env_set(w); } /* 特定のアルゴリズムが指定されていない場合のデフォルト動作 */ if (worker_ltl_none(w)) { if (worker_on_parallel(w) || worker_on_mc_bfs(w)) { /* 並列アルゴリズムを使用している or BFSの場合のデフォルト */ owcty_env_set(w); } else { ndfs_env_set(w); } } if (worker_use_owcty(w)) { lmn_env.enable_owcty = TRUE; } else if (worker_use_ble(w)) { lmn_env.enable_bledge = TRUE; } if (!worker_use_opt_scc(w)) { lmn_env.prop_scc_driven = FALSE; } } }
/** -------------------------- * 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 }
/* 状態sに対応した階層グラフ構造のバイナリストリングをzlibで圧縮して返す. * 状態sはread only */ LmnBinStr state_calc_mem_dump_with_z(State *s) { LmnBinStr ret; if (is_binstr_user(s)) { /* 既にバイナリストリングを保持している場合は, なにもしない. */ ret = state_binstr(s); } else if (state_mem(s)) { LmnBinStr bs = lmn_mem_to_binstr(state_mem(s)); /* TODO: --d-compressとの組合わせ */ ret = lmn_bscomp_z_encode(bs); if (ret != bs) { /* 圧縮成功 */ lmn_binstr_free(bs); } } else { lmn_fatal("unexpected"); } return ret; }
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"); } }
/** Printer * ownerはNULLでもok */ void dump_state_data(State *s, LmnWord _fp, LmnWord _owner) { FILE *f; StateSpace owner; unsigned long print_id; #ifdef KWBT_OPT LmnCost cost = lmn_env.opt_mode != OPT_NONE ? state_cost(s) : 0UL; #endif /* Rehashが発生している場合, * dummyフラグが真かつエンコード済みフラグが偽のStateオブジェクトが存在する. * このようなStateオブジェクトのバイナリストリングは * Rehashされた側のテーブルに存在するStateオブジェクトに登録されているためcontinueする. */ if (is_dummy(s) && !is_encoded(s)) return; f = (FILE *)_fp; owner = (StateSpace)_owner; { /* この時点で状態は, ノーマル || (dummyフラグが立っている && エンコード済)である. * dummyならば, バイナリストリング以外のデータはオリジナル側(parent)に記録している. */ State *target = !is_dummy(s) ? s : state_get_parent(s); if (owner) { print_id = state_format_id(target, owner->is_formated); } else { print_id = state_format_id(target, FALSE); } } switch (lmn_env.mc_dump_format) { case LaViT: fprintf(f, "%lu::", print_id); state_print_mem(s, _fp); break; case FSM: /* under constructions.. */ fprintf(f, "1\n"); break; case Dir_DOT: if (state_succ_num(s) == 0) { fprintf(f, " %lu [style=filled, fillcolor = \"#C71585\", shape = Msquare];\n", print_id); } break; case CUI: { BOOL has_property = owner && statespace_has_property(owner); #ifdef KWBT_OPT fprintf(f, "%lu::%lu::%s" , print_id, cost , has_property ? automata_state_name(statespace_automata(owner), state_property_state(s)) : ""); #else fprintf(f, "%lu::%s" , print_id , has_property ? automata_state_name(statespace_automata(owner), state_property_state(s)) : ""); #endif state_print_mem(s, _fp); break; } default: lmn_fatal("unexpected"); break; } }
int state_cmp_with_compress(State *s1, State *s2) { if (lmn_env.debug_isomor && !(is_encoded(s1) && is_encoded(s2))) { LmnMembrane *s2_mem; LmnBinStr s1_mid, s2_mid; BOOL org_check, mid_check, meq_check; /* TODO: --disable-compress時にもチェックできるよう修正して構造化する. */ /* s1がcheckなのでmem, s2がstored(ハッシュ表に記録済み)なのでbinstrを保持 */ /* データ構造の構築 */ s2_mem = lmn_binstr_decode(state_binstr(s2)); s1_mid = lmn_mem_encode(state_mem(s1)); s2_mid = lmn_mem_encode(s2_mem); org_check = (state_equals_with_compress(s1, s2) != 0); /* A. slim本来のグラフ同型成判定手続き */ mid_check = (binstr_compare(s1_mid, s2_mid) == 0); /* B. 互いに一意エンコードしたグラフの比較手続き */ meq_check = (lmn_mem_equals(state_mem(s1), s2_mem)); /* C. 膜同士のグラフ同型性判定 */ /* A, B, Cが同じ判定結果を返す場合はokだが.. */ if (org_check != mid_check || org_check != meq_check || mid_check != meq_check) { FILE *f; LmnBinStr s1_bs; BOOL sp1_check, sp2_check, sp3_check, sp4_check; f = stdout; s1_bs = lmn_mem_to_binstr(state_mem(s1)); sp1_check = (lmn_mem_equals(state_mem(s1), s2_mem) != 0); sp2_check = (lmn_mem_equals_enc(s1_bs, s2_mem) != 0); sp3_check = (lmn_mem_equals_enc(s1_mid, s2_mem) != 0); sp4_check = (lmn_mem_equals_enc(s2_mid, state_mem(s1)) != 0); fprintf(f, "fatal error: checking graphs isomorphism was invalid\n"); fprintf(f, "====================================================================================\n"); fprintf(f, "%18s | %-18s | %-18s | %-18s\n", " - ", "s1.Mem (ORG)", "s1.BS (calc)", "s1.MID (calc)"); fprintf(f, "------------------------------------------------------------------------------------\n"); fprintf(f, "%-18s | %18s | %18s | %18s\n", "s2.Mem (calc)", CMP_STR(sp1_check), CMP_STR(sp2_check), CMP_STR(sp3_check)); fprintf(f, "------------------------------------------------------------------------------------\n"); fprintf(f, "%-18s | %18s | %18s | %18s\n", "s2.BS (ORG)", CMP_STR(org_check), "-", "-"); fprintf(f, "------------------------------------------------------------------------------------\n"); fprintf(f, "%-18s | %18s | %18s | %18s\n", "s2.MID (calc)", CMP_STR(sp4_check), "-", CMP_STR(mid_check)); fprintf(f, "====================================================================================\n"); lmn_binstr_dump(state_binstr(s2)); lmn_dump_mem_stdout(state_mem(s1)); lmn_binstr_free(s1_bs); lmn_fatal("graph isomorphism procedure has invalid implementations"); } lmn_mem_free_rec(s2_mem); lmn_binstr_free(s1_mid); lmn_binstr_free(s2_mid); return !org_check; } else { return !state_equals_with_compress(s1, s2); } }
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; } } }
/* 実行時オプションが増えたため, * Worker起動以前のこの時点で, * 組み合わせをサポートしていないオプションの整合性を取るなどを行う. * 実際に使用するオプションフラグを, lmn_env構造体からworker構造体にコピーする. */ static BOOL workers_flags_init(LmnWorkerGroup *wp, AutomataRef property_a) { BOOL flags = 0x00U; /* === 1. 出力フォーマット === */ /* --- 1-1. GraphViz形式の使用 --- */ if (lmn_env.output_format == DOT) { lmn_env.output_format = DEFAULT; } /* --- 1-2. インクリメンタルな状態の標準出力 --- */ if (lmn_env.sp_dump_format == INCREMENTAL) { mc_set_dump(flags); lmn_env.dump = TRUE; if (lmn_env.mc_dump_format != CUI && lmn_env.mc_dump_format != LaViT) { lmn_fatal("unsupported incremental output format"); } fprintf(stdout, "States\n"); } /* --- 1-3. 並列処理中のサポート外オプション --- */ if (lmn_env.core_num >= 2) { if (lmn_env.sp_dump_format == INCREMENTAL) { #ifndef DEBUG lmn_fatal("unsupported combination incremental state dumper & parallelization."); #endif } #ifdef PROFILE if (lmn_env.optimize_hash_old) { lmn_fatal("unsupported combination optimized hash (old) & parallelization."); } #endif } /* === 2. 状態空間構築オプション === */ /* --- 2-1. 遷移オブジェクトの使用 --- */ if (lmn_env.show_transition) { mc_set_trans(flags); } /* --- 2-2. バイト列エンコードを使用しない場合 ----- * 対応していない全てのオプションフラグを下げる. */ if (lmn_env.enable_compress_mem) { if (lmn_env.delta_mem) { mc_set_delta(flags); } mc_set_compress(flags); } else { lmn_env.delta_mem = FALSE; lmn_env.optimize_hash = FALSE; #ifdef PROFILE lmn_env.optimize_hash_old = FALSE; #endif if (lmn_env.hyperlink) { lmn_fatal("no support: membrane isomorphis tester for hyper graph model"); } } /* --- 2-3. バイト列エンコードと階層グラフ構造の一対一対応 --- */ if (lmn_env.mem_enc) { mc_set_canonical(flags); } /* --- 2-4. Partial Order Reduction --- */ if (lmn_env.enable_por || lmn_env.enable_por_old) { mc_set_por(flags); } /* --- 2-5. binstr compressor --- */ if (lmn_env.z_compress) { lmn_env.d_compress = FALSE; lmn_env.tree_compress = FALSE; lmn_env.hash_compaction = FALSE; } /* --- 2-6. hash compaction --- */ if (lmn_env.hash_compaction) { lmn_env.z_compress = FALSE; lmn_env.d_compress = FALSE; lmn_env.tree_compress = FALSE; } /* --- 2-7. tree compression --- */ if (lmn_env.tree_compress) { lmn_env.z_compress = FALSE; lmn_env.d_compress = FALSE; lmn_env.hash_compaction = FALSE; lmn_env.mem_enc = FALSE; #ifdef PROFILE lmn_env.optimize_hash_old = FALSE; #endif } /* === 3. 状態空間探索(LTLモデル検査)オプション === */ if (lmn_env.ltl) { if (!property_a) { lmn_env.ltl = FALSE; lmn_env.ltl_all = FALSE; wp->do_search = FALSE; wp->do_exhaustive = FALSE; } else { if (lmn_env.ltl_all) { wp->do_exhaustive = TRUE; } wp->do_search = TRUE; } if (lmn_env.enable_parallel) { wp->do_para_algo = TRUE; } } /* === 4. hypergraph ==== */ if (lmn_env.hyperlink) { if (lmn_env.optimize_hash) { lmn_env.optimize_hash = FALSE; } if (lmn_env.delta_mem || lmn_env.mem_enc || !lmn_env.enable_compress_mem) { lmn_fatal("under constructions: delta/canonical membrane methods for hyper graph model"); } } return flags; }