static void ltsmin_expr_lookup_value(ltsmin_expr_t top, ltsmin_expr_t e, int typeno, ltsmin_parse_env_t env, model_t model) { switch(e->node_type) { case VAR: case CHUNK: case INT: break; default: return; } chunk c; data_format_t format = lts_type_get_format(GBgetLTStype(model), typeno); switch (format) { case LTStypeDirect: case LTStypeRange: if (INT != e->node_type) Abort ("Expected an integer value for comparison: %s", LTSminPrintExpr(top, env)); break; case LTStypeEnum: case LTStypeChunk: c.data = env->buffer; c.len = LTSminSPrintExpr(c.data, e, env); HREassert (c.len < ENV_BUFFER_SIZE, "Buffer overflow in print expression"); lookup_type_value (e, typeno, c, model, format==LTStypeEnum); Debug ("Bound '%s' to %d in table for type '%s'", c.data, e->num, lts_type_get_state_type(GBgetLTStype(model),typeno)); break; } }
static int type_max (check_ctx_t *ctx, int idx) { model_t model = ctx->parent; lts_type_t ltstype = GBgetLTStype (model); int typeno = lts_type_get_state_typeno (ltstype, idx); int c; switch (lts_type_get_format (ltstype, typeno)) { case LTStypeDirect: GBgetInitialState (model, ctx->src2); c = ctx->src2[idx]; return c == 0 ? 1 : c; case LTStypeRange: return lts_type_get_min (ltstype, typeno); case LTStypeEnum: c = pins_chunk_count (model, typeno); HREassert (c > 0, "Empty enum table for slot: %d -- %s", idx, str_slot(ctx, NULL, idx)); return c; case LTStypeChunk: c = pins_chunk_count (model, typeno); return c == 0 ? 1 : c; case LTStypeBool: return 1; case LTStypeTrilean: return 2; case LTStypeSInt32: return (1ULL<<31) - 1; default: { HREassert(false); return -1; } } }
static void init_model(char *file) { Warning(info, "opening %s", file); model = GBcreateBase(); GBsetChunkMap (model, HREgreyboxTableFactory()); HREbarrier(HREglobal()); GBloadFile(model, file, &model); HREbarrier(HREglobal()); if (HREme(HREglobal())==0 && !PINS_USE_GUARDS && no_soundness_check) { Abort("Option --no-soundness-check is incompatible with --pins-guards=false"); } if (HREme(HREglobal())==0 && log_active(infoLong) && !no_matrix) { fprintf(stderr, "Dependency Matrix:\n"); GBprintDependencyMatrixCombined(stderr, model); } ltstype = GBgetLTStype(model); N = lts_type_get_state_length(ltstype); eLbls = lts_type_get_edge_label_count(ltstype); sLbls = GBgetStateLabelInfo(model) == NULL ? 0 : dm_nrows(GBgetStateLabelInfo(model)); nGrps = dm_nrows(GBgetDMInfo(model)); max_sat_levels = (N / sat_granularity) + 1; if (PINS_USE_GUARDS) { nGuards = GBgetStateLabelGroupInfo(model, GB_SL_GUARDS)->count; if (HREme(HREglobal())==0) { Warning(info, "state vector length is %d; there are %d groups and %d guards", N, nGrps, nGuards); } } else { if (HREme(HREglobal())==0) { Warning(info, "state vector length is %d; there are %d groups", N, nGrps); } } int id=GBgetMatrixID(model,"inhibit"); if (id>=0){ inhibit_matrix=GBgetMatrix(model,id); if (HREme(HREglobal())==0) { Warning(infoLong,"inhibit matrix is:"); if (log_active(infoLong)) dm_print(stderr,inhibit_matrix); } } id = GBgetMatrixID(model,LTSMIN_EDGE_TYPE_ACTION_CLASS); if (id>=0){ class_matrix=GBgetMatrix(model,id); if (HREme(HREglobal())==0) { Warning(infoLong,"inhibit class matrix is:"); if (log_active(infoLong)) dm_print(stderr,class_matrix); } } HREbarrier(HREglobal()); }
/** * Parses file using parser * Chunk values are looked up in PINS. */ ltsmin_expr_t parse_file_env(const char *file, parse_f parser, model_t model, ltsmin_parse_env_t env) { lts_type_t ltstype = GBgetLTStype(model); ltsmin_expr_t expr = parser(file, env, ltstype); ltsmin_expr_lookup_values(expr, env, model); env->expr = NULL; return expr; }
static void dbg_found_read_dep_error (check_ctx_t *ctx, int *dst, int *dst2, int idx) { char *res = RTmalloc (1024); lts_type_t ltstype = GBgetLTStype (ctx->parent); int typeno = lts_type_get_state_typeno (ltstype, idx); print_chunk (ctx->parent, res, 1024, typeno, dst[idx]); Print1 (lerror, "Found missing read dependency in group %d (diff slot: %d -- %s != %s).\\" "Identifying culprit read slot...", ctx->group, idx, str_slot(ctx, dst2, idx), res); RTfree (res); }
/** * Enums need their values to be present in the tables, hence the strict lookup. */ static void lookup_type_value (ltsmin_expr_t e, int type, const chunk c, model_t m, bool strict) { HREassert (NULL != c.data, "Empty chunk"); int count = GBchunkCount(m,type); e->num = GBchunkPut(m,type,c); if (strict && count != GBchunkCount(m,type)) // value was added Warning (info, "Value for identifier '%s' cannot be found in table for enum type '%s'.", c.data, lts_type_get_type(GBgetLTStype(m),type)); e->lts_type = type; }
trc_env_t * trc_create (model_t model, trc_get_state_f get, void *arg) { trc_env_t *trace = RTmalloc(sizeof(trc_env_t)); lts_type_t ltstype = GBgetLTStype (model); trace->N = lts_type_get_state_length (ltstype); trace->state_labels = lts_type_get_state_label_count (ltstype); trace->get_state = get; trace->get_state_arg = arg; trace->model = model; return trace; }
static char * str_group (check_ctx_t *ctx, int group) { model_t model = ctx->parent; lts_type_t ltstype = GBgetLTStype (model); int label = lts_type_find_edge_label (ltstype, LTSMIN_EDGE_TYPE_STATEMENT); if (label) return "NULL"; int type = lts_type_get_edge_label_typeno (ltstype, label); int count = pins_chunk_count (model, type); if (count < ctx->K) return "NULL"; chunk c = pins_chunk_get (model, type, group); return c.data; }
void mark_predicate (model_t m, ltsmin_expr_t e, int *dep, ltsmin_parse_env_t env) { if (!e) return; switch(e->node_type) { case BINARY_OP: mark_predicate(m,e->arg1,dep,env); mark_predicate(m,e->arg2,dep,env); break; case UNARY_OP: mark_predicate(m,e->arg1,dep,env); break; default: switch(e->token) { case PRED_TRUE: case PRED_FALSE: case PRED_NUM: case PRED_VAR: case PRED_CHUNK: break; case PRED_EQ: mark_predicate(m,e->arg1, dep,env); mark_predicate(m,e->arg2, dep,env); break; case PRED_SVAR: { lts_type_t ltstype = GBgetLTStype(m); int N = lts_type_get_state_length (ltstype); if (e->idx < N) { // state variable dep[e->idx] = 1; } else { // state label HREassert (e->idx < N + lts_type_get_state_label_count(ltstype)); matrix_t *sl = GBgetStateLabelInfo (m); HREassert (N == dm_ncols(sl)); for (int i = 0; i < N; i++) { if (dm_is_set(sl, e->idx - N, i)) dep[i] = 1; } } break; } default: LTSminLogExpr (error, "Unhandled predicate expression: ", e, env); HREabort (LTSMIN_EXIT_FAILURE); } break; } }
static char * str_slot (check_ctx_t *ctx, int *s, int i) { model_t model = ctx->parent; lts_type_t ltstype = GBgetLTStype (model); char *name = lts_type_get_state_name (ltstype, i); char *type = lts_type_get_state_type (ltstype, i); int typeno = lts_type_get_state_typeno (ltstype, i); int max = 4096; char *res = RTmalloc (max); int l = snprintf (res, max, "%s : %s = ", name, type); if (s != NULL) { print_chunk (model, res+l, max-l, typeno, s[i]); } else { res[l-2] = '\0'; } return res; }
int print_chunk (model_t model, char *res, int max, int typeno, int val) { chunk c; switch (lts_type_get_format (GBgetLTStype(model), typeno)) { case LTStypeDirect: case LTStypeRange: return snprintf (res, max, "%d", val); case LTStypeEnum: case LTStypeChunk: c = pins_chunk_get (model, typeno, val); return snprintf (res, max, "%s", c.data); default: { HREassert(false); return -1; } } }
static inline void print_ti (check_ctx_t *ctx, transition_info_t *ti) { if (ti == NULL || ti->labels == NULL) return; model_t model = ctx->parent; lts_type_t ltstype = GBgetLTStype (model); int Max = 4096; char *tmp = RTmalloc (Max); int l; for (int i = 0; i < ctx->L; i++) { char *name = lts_type_get_edge_label_name (ltstype, i); char *type = lts_type_get_edge_label_type (ltstype, i); int typeno = lts_type_get_edge_label_typeno (ltstype, i); char *res = tmp; l = snprintf (res, Max, " --> %s : %s = ", name, type); l += print_chunk (model, res+l, Max-l, typeno, ti->labels[i]); Printf (lerror, "%s\n", res); } RTfree (tmp); }
static int type_min (check_ctx_t *ctx, int idx) { model_t model = ctx->parent; lts_type_t ltstype = GBgetLTStype (model); int typeno = lts_type_get_state_typeno (ltstype, idx); switch (lts_type_get_format (ltstype, typeno)) { case LTStypeRange: return lts_type_get_min (ltstype, typeno); case LTStypeDirect: case LTStypeEnum: case LTStypeChunk: case LTStypeBool: case LTStypeTrilean: case LTStypeSInt32: return 0; default: { HREassert(false); return -1; } } }
/* avoid rebuilding the whole tree, by storing extra info for the chunks */ static int ltsmin_expr_lookup_values(ltsmin_expr_t ltl,ltsmin_parse_env_t env,model_t model) { //return type(SVAR) idx or -1 if (!ltl) return -1; int left, right; switch(ltl->node_type) { case BINARY_OP: left = ltsmin_expr_lookup_values(ltl->arg1, env, model); right = ltsmin_expr_lookup_values(ltl->arg2, env, model); switch(ltl->token) { case PRED_EQ: if (left >= 0) { // type(SVAR) ltsmin_expr_lookup_value (ltl, ltl->arg2, left, env, model); } else if (right >= 0) { // type(SVAR) ltsmin_expr_lookup_value (ltl, ltl->arg1, right, env, model); } } return -1; case UNARY_OP: ltsmin_expr_lookup_values(ltl->arg1, env, model); return -1; default: switch(ltl->token) { case SVAR: { lts_type_t ltstype = GBgetLTStype (model); int N = lts_type_get_state_length (ltstype); if (ltl->idx < N) return lts_type_get_state_typeno (ltstype, ltl->idx); else return lts_type_get_state_label_typeno (ltstype, ltl->idx - N); } default: return -1; } } }
int main(int argc, char *argv[]){ char *files[2]; RTinitPopt(&argc,&argv,options,1,2,files,NULL,"<model> [<lts>]", "Perform an enumerative reachability analysis of <model>\n" "Run the TorX remote procedure call protocol on <model> (--torx).\n\n" "Options"); if (files[1]) { Warning(info,"Writing output to %s",files[1]); write_lts=1; } else { Warning(info,"No output, just counting the number of states"); write_lts=0; } if (application==RunTorX && write_lts) Fatal(1,error,"A TorX server does not write to a file"); Warning(info,"loading model from %s",files[0]); model_t model=GBcreateBase(); GBsetChunkMethods(model,new_string_index,NULL, (int2chunk_t)SIgetC,(chunk2int_t)SIputC,(get_count_t)SIgetCount); GBloadFile(model,files[0],&model); if (RTverbosity >=2) { fprintf(stderr,"Dependency Matrix:\n"); GBprintDependencyMatrix(stderr,model); } if (matrix) { GBprintDependencyMatrix(stdout,model); exit(0); } lts_type_t ltstype=GBgetLTStype(model); N=lts_type_get_state_length(ltstype); edge_info_t e_info=GBgetEdgeInfo(model); K=e_info->groups; Warning(info,"length is %d, there are %d groups",N,K); state_labels=lts_type_get_state_label_count(ltstype); edge_labels=lts_type_get_edge_label_count(ltstype); Warning(info,"There are %d state labels and %d edge labels",state_labels,edge_labels); if (state_labels&&write_lts&&!write_state) { Fatal(1,error,"Writing state labels, but not state vectors unsupported. " "Writing of state vector is enabled with the option --write-state"); } int src[N]; GBgetInitialState(model,src); Warning(info,"got initial state"); int level=0; switch(application){ case ReachVset: domain=vdom_create_default(N); visited_set=vset_create(domain,0,NULL); next_set=vset_create(domain,0,NULL); if (write_lts){ output=lts_output_open(files[1],model,1,0,1,"viv",NULL); lts_output_set_root_vec(output,(uint32_t*)src); lts_output_set_root_idx(output,0,0); output_handle=lts_output_begin(output,0,0,0); } vset_add(visited_set,src); vset_add(next_set,src); vset_t current_set=vset_create(domain,0,NULL); while (!vset_is_empty(next_set)){ if (RTverbosity >= 1) Warning(info,"level %d has %d states, explored %d states %d trans", level,(visited-explored),explored,trans); level++; vset_copy(current_set,next_set); vset_clear(next_set); vset_enum(current_set,explore_state_vector,model); } long long size; long nodes; vset_count(visited_set,&nodes,&size); Warning(info,"%lld reachable states represented symbolically with %ld nodes",size,nodes); break; case ReachTreeDBS: dbs=TreeDBScreate(N); if(TreeFold(dbs,src)!=0){ Fatal(1,error,"expected 0"); } if (write_lts){ output=lts_output_open(files[1],model,1,0,1,write_state?"vsi":"-ii",NULL); if (write_state) lts_output_set_root_vec(output,(uint32_t*)src); lts_output_set_root_idx(output,0,0); output_handle=lts_output_begin(output,0,0,0); } int limit=visited; while(explored<visited){ if (limit==explored){ if (RTverbosity >= 1) Warning(info,"level %d has %d states, explored %d states %d trans", level,(visited-explored),explored,trans); limit=visited; level++; } TreeUnfold(dbs,explored,src); explore_state_index(model,explored,src); } break; case RunTorX: { torx_struct_t context = { model, ltstype }; torx_ui(&context); return 0; } } if (write_lts){ lts_output_end(output,output_handle); Warning(info,"finishing the writing"); lts_output_close(&output); Warning(info,"state space has %d levels %d states %d transitions",level,visited,trans); } else { printf("state space has %d levels %d states %d transitions\n",level,visited,trans); } return 0; }
void CAESAR_INIT_GRAPH(void) { char *opencaesar_args, *opencaesar_prog,*ltsmin_options; int argc; char **argv; opencaesar_prog = getenv ("OPEN_CAESAR_PROG"); if (opencaesar_prog == NULL) CAESAR_ERROR ("undefined environment variable $OPEN_CAESAR_PROG"); opencaesar_args = getenv ("OPEN_CAESAR_FILE"); if (opencaesar_args == NULL) CAESAR_ERROR ("undefined environment variable $OPEN_CAESAR_FILE"); ltsmin_options = getenv ("LTSMIN_OPTIONS"); if (ltsmin_options == NULL) CAESAR_ERROR ("undefined environment variable $LTSMIN_OPTIONS"); int len=strlen(opencaesar_prog)+strlen(ltsmin_options)+strlen(opencaesar_args); char cmdline[len+6]; sprintf(cmdline,"%s %s %s",opencaesar_prog,ltsmin_options,opencaesar_args); int res=poptParseArgvString(cmdline,&argc,(void*)(&argv)); if (res){ Abort("could not parse %s: %s",opencaesar_args,poptStrerror(res)); } char *files[2]; HREinitBegin(argv[0]); HREaddOptions(options,"Options"); HREinitStart(&argc,&argv,1,1,(char**)files,"<model>"); Warning(info,"loading model from %s",files[0]); model=GBcreateBase(); GBsetChunkMethods(model,new_string_index,NULL, (int2chunk_t)SIgetC, (chunk2int_t)SIputC, (chunkatint_t)SIputCAt, (get_count_t)SIgetCount); GBloadFile(model,files[0],&model); ltstype=GBgetLTStype(model); N = lts_type_get_state_length(ltstype); K = dm_nrows(GBgetDMInfo(model)); Warning(info,"length is %d, there are %d groups",N,K); state_labels=lts_type_get_state_label_count(ltstype); edge_labels=lts_type_get_edge_label_count(ltstype); Warning(info,"There are %d state labels and %d edge labels",state_labels,edge_labels); if (edge_encode){ edge_size=edge_labels+N+state_labels; Warning(info,"encoding state information on edges"); } else { edge_size=edge_labels; Warning(info,"state information is hidden"); } CAESAR_HINT_SIZE_STATE = N*sizeof(int); CAESAR_HINT_HASH_SIZE_STATE = CAESAR_HINT_SIZE_STATE; CAESAR_HINT_SIZE_LABEL = edge_size*sizeof(int); CAESAR_HINT_HASH_SIZE_LABEL = CAESAR_HINT_SIZE_LABEL; Warning(info,"CAESAR_HINT_SIZE_STATE=%lu CAESAR_HINT_SIZE_LABEL=%lu", (unsigned long)CAESAR_HINT_SIZE_STATE,(unsigned long)CAESAR_HINT_SIZE_LABEL); }
/** * \brief Initialises the data structures for generating symbolic parity games. */ void init_spg(model_t model) { lts_type_t type = GBgetLTStype(model); var_pos = 0; var_type_no = 0; for(int i=0; i<N; i++) { //Printf(infoLong, "%d: %s (%d [%s])\n", i, lts_type_get_state_name(type, i), lts_type_get_state_typeno(type, i), lts_type_get_state_type(type, i)); #ifdef LTSMIN_PBES char* str1 = "string"; // for the PBES language module #else char* str1 = "mu"; // for the mu-calculus PINS layer #endif size_t strlen1 = strlen(str1); char* str2 = lts_type_get_state_type(type, i); size_t strlen2 = strlen(str2); if (strlen1==strlen2 && strncmp(str1, str2, strlen1)==0) { var_pos = i; var_type_no = lts_type_get_state_typeno(type, i); if (GBhaveMucalc()) { true_index = 0; // enforced by mucalc parser (mucalc-grammar.lemon / mucalc-syntax.c) false_index = 1; } else { // required for the PBES language module. true_index = pins_chunk_put (model, var_type_no, chunk_str("true")); false_index = pins_chunk_put (model, var_type_no, chunk_str("false")); } } } int p_len = 1; int proj[1] = {var_pos}; // position 0 encodes the variable variable_projection = vproj_create(domain, p_len, proj); num_vars = pins_chunk_count (model, var_type_no); // number of propositional variables if (GBhaveMucalc()) { num_vars = GBgetMucalcNodeCount(); // number of mu-calculus subformulae } Print(infoLong, "init_spg: var_type_no=%d, num_vars=%zu", var_type_no, num_vars); priority = RTmalloc(num_vars * sizeof(int)); // priority of variables player = RTmalloc(num_vars * sizeof(int)); // player of variables for(size_t i=0; i<num_vars; i++) { lts_type_t type = GBgetLTStype(model); int state_length = lts_type_get_state_length(type); // create dummy state with variable i: int state[state_length]; for(int j=0; j < state_length; j++) { state[j] = 0; } state[var_pos] = i; int label = GBgetStateLabelLong(model, PG_PRIORITY, state); // priority priority[i] = label; if (label < min_priority) { min_priority = label; } if (label > max_priority) { max_priority = label; } //Print(infoLong, " label %d (priority): %d", 0, label); label = GBgetStateLabelLong(model, PG_PLAYER, state); // player player[i] = label; //Print(infoLong, " label %d (player): %d", 1, label); } true_states = vset_create(domain, -1, NULL); false_states = vset_create(domain, -1, NULL); }
void trc_write_trace (trc_env_t *env, char *trc_output, ref_t *trace, int level) { lts_type_t ltstype = GBgetLTStype(env->model); hre_context_t n = HREctxCreate(0, 1, "blah", 0); lts_file_t template = lts_index_template();
permute_t * permute_create (permutation_perm_t permutation, model_t model, alg_state_seen_f ssf, int worker_index, void *run_ctx) { permute_t *perm = RTalign (CACHE_LINE_SIZE, sizeof(permute_t)); perm->todos = RTalign (CACHE_LINE_SIZE, sizeof(permute_todo_t[K+TODO_MAX])); perm->tosort = RTalign (CACHE_LINE_SIZE, sizeof(int[K+TODO_MAX])); perm->shift = ((double)K)/W; perm->shiftorder = (1UL<<dbs_size) / W * worker_index; perm->start_group = perm->shift * worker_index; perm->model = model; perm->state_seen = ssf; perm->por_proviso = 1; perm->permutation = permutation; perm->run_ctx = run_ctx; perm->next = state_info_create (); if (Perm_Otf == perm->permutation) perm->pad = RTalign (CACHE_LINE_SIZE, sizeof(int[K+TODO_MAX])); if (Perm_Random == perm->permutation) { perm->rand = RTalignZero (CACHE_LINE_SIZE, sizeof(int*[K+TODO_MAX])); for (size_t i = 1; i < K+TODO_MAX; i++) { perm->rand[i] = RTalign (CACHE_LINE_SIZE, sizeof(int[ i ])); randperm (perm->rand[i], i, perm->shiftorder); } } if (Perm_RR == perm->permutation) { perm->rand = RTalignZero (CACHE_LINE_SIZE, sizeof(int*)); perm->rand[0] = RTalign (CACHE_LINE_SIZE, sizeof(int[1<<RR_ARRAY_SIZE])); srandom (time(NULL) + 9876432*worker_index); for (int i =0; i < (1<<RR_ARRAY_SIZE); i++) perm->rand[0][i] = random(); } if (Perm_SR == perm->permutation || Perm_Dynamic == perm->permutation) { perm->rand = RTalignZero (CACHE_LINE_SIZE, sizeof(int*)); perm->rand[0] = RTalign (CACHE_LINE_SIZE, sizeof(int[K+TODO_MAX])); randperm (perm->rand[0], K+TODO_MAX, (time(NULL) + 9876*worker_index)); } perm->labels = lts_type_get_edge_label_count (GBgetLTStype(model)); for (size_t i = 0; i < K+TODO_MAX; i++) { if (act_detect || files[1] || (PINS_BUCHI_TYPE == PINS_BUCHI_TYPE_TGBA)) { perm->todos[i].ti.labels = RTmalloc (sizeof(int*[perm->labels])); } else { perm->todos[i].ti.labels = NULL; } } perm->class_label = lts_type_find_edge_label (GBgetLTStype(model),LTSMIN_EDGE_TYPE_ACTION_CLASS); if (inhibit){ int id=GBgetMatrixID(model,"inhibit"); if (id>=0){ perm->inhibit_matrix = GBgetMatrix (model, id); Warning(infoLong,"inhibit matrix is:"); if (log_active(infoLong)) dm_print (stderr, perm->inhibit_matrix); perm->inhibited_by = (ci_list **)dm_cols_to_idx_table (perm->inhibit_matrix); } else { Warning(infoLong,"no inhibit matrix"); } id = GBgetMatrixID(model,LTSMIN_EDGE_TYPE_ACTION_CLASS); if (id>=0){ perm->class_matrix=GBgetMatrix(model,id); Warning(infoLong,"inhibit class matrix is:"); if (log_active(infoLong)) dm_print(stderr,perm->class_matrix); } else { Warning(infoLong,"no inhibit class matrix"); } if (perm->class_label>=0) { Warning(infoLong,"inhibit class label is %d",perm->class_label); } else { Warning(infoLong,"no inhibit class label"); } } if (PINS_POR) por_set_find_state (state_find, perm); return perm; }
int main(int argc, char *argv[]){ char* files[2]; RTinitPopt(&argc,&argv,options,2,2,files,NULL,"<input> <output>","Stream based file format conversion\n\nOptions"); model_t model=GBcreateBase(); GBsetChunkMethods(model,new_string_index,NULL, (int2chunk_t)SIgetC,(chunk2int_t)SIputC,(get_count_t)SIgetCount); Warning(info,"copying %s to %s",files[0],files[1]); lts_input_t input=lts_input_open(files[0],model,0,1); if (segments==0) { segments=lts_input_segments(input); } char*input_mode=lts_input_mode(input); if (input_mode) { Warning(debug,"input was written in %s mode",input_mode); if (!strcmp(input_mode,"viv") || !strcmp(input_mode,"vsi")){ if (segments!=1) Fatal(1,error,"cannot write more than one segment"); lts_type_t ltstype=GBgetLTStype(model); int N=lts_type_get_state_length(ltstype); Warning(info,"state length is %d",N); treedbs_t dbs=TreeDBScreate(N); // we should convert the GB not and not hack the ltstype. lts_type_set_state_label_count(ltstype,0); lts_output_t output=lts_output_open(files[1],model,segments,0,1,"-ii",NULL); lts_output_set_root_idx(output,0,0); lts_enum_cb_t ecb=lts_output_begin(output,segments,segments,segments); // We should have two passes (if the file is not in BFS order then the state numbers are wrong!) // pass 1: states with labels. // pass 2: edges with labels. // Currently the viv reader illegally does two passes. N=lts_input_segments(input); uint32_t begin[N]; lts_count_t *count=lts_input_count(input); begin[0]=0; for(int i=1;i<N;i++) begin[i]=begin[i-1]+count->state[i-1]; struct dbs_ctx ctx; ctx.dbs=dbs; ctx.begin=begin; lts_input_enum(input,N,N,N,lts_enum_convert(ecb,&ctx,dbs_fold,dbs_unfold,1)); lts_output_end(output,ecb); lts_output_close(&output); uint32_t* root=lts_input_root(input); uint32_t root_no=TreeFold(dbs,(int*)root); if (root_no!=0){ Fatal(1,error,"root is %u rather than 0",root_no); } } else { Warning(info,"input mode %s not supported",input_mode); } } else if (segments==lts_input_segments(input)){ Warning(debug,"undefined input mode"); lts_output_t output=lts_output_open(files[1],model,segments,0,1,"-ii",NULL); lts_output_set_root_idx(output,lts_root_segment(input),lts_root_offset(input)); lts_enum_cb_t ecb=lts_output_begin(output,segments,segments,segments); lts_input_enum(input,segments,segments,segments,ecb); lts_output_end(output,ecb); lts_output_close(&output); } else { Warning(debug,"undefined input mode with segment conversion"); int N=lts_input_segments(input); uint64_t offset[N+1]; lts_count_t *count=lts_input_count(input); offset[0]=segments; offset[1]=0; for(int i=1;i<N;i++){ offset[i+1]=offset[i]+count->state[i-1]; } uint64_t root=offset[lts_root_segment(input)+1]+lts_root_offset(input); lts_output_t output=lts_output_open(files[1],model,segments,0,1,"-ii",NULL); lts_output_set_root_idx(output,root%segments,root/segments); lts_enum_cb_t ecb=lts_output_begin(output,segments,segments,segments); lts_input_enum(input,N,N,N,lts_enum_convert(ecb,offset,convert_div_mod,copy_seg_ofs,1)); lts_output_end(output,ecb); lts_output_close(&output); } lts_input_close(&input); return 0; }