void lts_type_serialize(lts_type_t t,stream_t ds){ DSwriteS(ds,"lts signature 1.1"); uint32_t N=lts_type_get_state_length(t); Warning(debug,"state length is %d",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ char*x=lts_type_get_state_name(t,i); if (x) DSwriteS(ds,x); else DSwriteS(ds,""); DSwriteU32(ds,lts_type_get_state_typeno(t,i)); } N=lts_type_get_state_label_count(t); Warning(debug,"%d state labels",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ char*x=lts_type_get_state_label_name(t,i); if (x) DSwriteS(ds,x); else DSwriteS(ds,""); DSwriteU32(ds,lts_type_get_state_label_typeno(t,i)); } N=lts_type_get_edge_label_count(t); Warning(debug,"%d edge labels",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ char*x=lts_type_get_edge_label_name(t,i); if (x) DSwriteS(ds,x); else DSwriteS(ds,""); DSwriteU32(ds,lts_type_get_edge_label_typeno(t,i)); Warning(debug,"edge label %d is %s : %s",i,x,lts_type_get_edge_label_type(t,i)); } N=lts_type_get_type_count(t); Warning(debug,"%d types",N); DSwriteU32(ds,N); for(uint32_t i=0;i<N;i++){ DSwriteS(ds,lts_type_get_type(t,i)); DSwriteS(ds,(char*)data_format_string(t,i)); } }
static void output_init(FILE *tbl_file) { int state[N]; GBgetInitialState(model, state); fprintf(tbl_file, "begin state\n"); for (int i = 0; i < N; i++) { fprint_ltsmin_ident(tbl_file, lts_type_get_state_name(ltstype, i)); fprintf(tbl_file, ":"); fprint_ltsmin_ident(tbl_file, lts_type_get_state_type(ltstype, i)); fprintf(tbl_file, (i == (N - 1))?"\n":" "); } fprintf(tbl_file,"end state\n"); fprintf(tbl_file,"begin edge\n"); for(int i = 0; i < eLbls; i++) { fprint_ltsmin_ident(tbl_file, lts_type_get_edge_label_name(ltstype, i)); fprintf(tbl_file, ":"); fprint_ltsmin_ident(tbl_file, lts_type_get_edge_label_type(ltstype, i)); fprintf(tbl_file, (i == (eLbls - 1))?"\n":" "); } fprintf(tbl_file, "end edge\n"); fprintf(tbl_file, "begin init\n"); for(int i = 0; i < N; i++) fprintf(tbl_file, "%d%s", state[i], (i == (N - 1))?"\n":" "); fprintf(tbl_file,"end init\n"); }
/* * Sanitizes and caches all the variable names of an lts_type_t. Should only be * called once. */ void sanitize_variables(lts_type_t ltstype) { int n_vars = lts_type_get_state_length(ltstype); sanitized_variables = (char**)RTmalloc(n_vars*sizeof(char*)); for (int i=0;i<n_vars;i++) { char *name = lts_type_get_state_name(ltstype,i); int len = strlen(name)+2; sanitized_variables[i] = (char*)RTmalloc(len); sanitize_ID(name,len,sanitized_variables[i]); Debug("Sanitizing variable %s to %s", name, sanitized_variables[i]); } }
static void pvar_slice(lts_type_t ltstype){ if (pvars==NULL) { pv_count=0; return; } int N=lts_type_get_state_length(ltstype); char *tmp=pvars; pv_count=0; while(tmp){ pv_count++; int i=0; while(tmp[i]&&tmp[i]!=' ') { i++; } if (tmp[i]) { tmp[i]=0; tmp=&tmp[i+1]; } else { tmp=NULL; } } pvar_name=RTmalloc(pv_count*sizeof(char*)); pvar_idx=RTmalloc(pv_count*sizeof(int)); tmp=pvars; Warning(info,"state length is %d",N); for(int j=0;j<N;j++) Warning(info,"state %d is %s",j, lts_type_get_state_name(ltstype,j)); for(int i=0;i<pv_count;i++){ pvar_name[i]=tmp; pvar_idx[i]=-1; for(int j=0;j<N;j++){ if (strcmp(tmp,lts_type_get_state_name(ltstype,j))!=0) continue; pvar_idx[i]=j; break; } tmp=tmp+strlen(tmp)+1; } for(int i=0;i<pv_count;i++){ Warning(info,"variable %d is %s, idx %d",i,pvar_name[i],pvar_idx[i]); } }
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; }
void DVE2loadGreyboxModel(model_t model, const char *filename) { lts_type_t ltstype; matrix_t *dm_info = RTmalloc(sizeof(matrix_t)); matrix_t *dm_read_info = RTmalloc(sizeof(matrix_t)); matrix_t *dm_actions_read_info = RTmalloc(sizeof(matrix_t)); matrix_t *dm_may_write_info = RTmalloc(sizeof(matrix_t)); matrix_t *dm_must_write_info = RTmalloc(sizeof(matrix_t)); matrix_t *sl_info = RTmalloc(sizeof(matrix_t)); //assume sequential use: if (NULL == dlHandle) { char *extension = strrchr (filename, '.'); HREassert (extension != NULL, "No filename extension %s", filename); ++extension; if (0==strcmp (extension, "dve2C") || 0==strcmp (extension, "so")) { DVE2loadDynamicLib(model, filename); } else { DVE2compileGreyboxModel(model, filename); } } gb_context_t ctx=(gb_context_t)RTmalloc(sizeof(struct grey_box_context)); GBsetContext(model,ctx); // get ltstypes int state_length = get_state_variable_count(); ltstype=lts_type_create(); // adding types int ntypes = get_state_variable_type_count(); for(int i = 0; i < ntypes; i++) { const char* type_name = get_state_variable_type_name(i); HREassert (type_name != NULL, "invalid type name"); if (lts_type_add_type(ltstype, type_name, NULL) != i) { Abort("wrong type number"); } int type_value_count = get_state_variable_type_value_count(i); if (0 == type_value_count) { lts_type_set_format (ltstype, i, LTStypeDirect); } else { lts_type_set_format (ltstype, i, LTStypeEnum); } } int guard_type = lts_type_add_type (ltstype, "guard", NULL); lts_type_set_format (ltstype, guard_type, LTStypeTrilean); lts_type_set_state_length(ltstype, state_length); // set state name & type for(int i=0; i < state_length; ++i) { const char* name = get_state_variable_name(i); const int type = get_state_variable_type(i); lts_type_set_state_name(ltstype,i,name); lts_type_set_state_typeno(ltstype,i,type); } // compute state label names int nguards = get_guard_count(); // TODO: should be in model has guards block..? int sl_size = 0 + nguards + (have_property() ? 1 : 0); // assumption on state labels: // state labels (idx): 0 - nguards-1 = guard state labels // state label (idx): nguards = property state label lts_type_set_state_label_count (ltstype, sl_size); char buf[256]; for(int i=0; i < nguards; i++) { snprintf(buf, 256, "%s_%d", LTSMIN_LABEL_TYPE_GUARD_PREFIX, i); lts_type_set_state_label_name (ltstype, i, buf); lts_type_set_state_label_typeno (ltstype, i, guard_type); } if (have_property()) { lts_type_set_state_label_name (ltstype, nguards, LTSMIN_STATE_LABEL_ACCEPTING); lts_type_set_state_label_typeno (ltstype, nguards, guard_type); ctx->accepting_state_label_idx = nguards; } else { ctx->accepting_state_label_idx = -1; } GBsetLTStype(model, ltstype); // setting values for types for(int i=0; i < ntypes; i++) { int type_value_count = get_state_variable_type_value_count(i); if (lts_type_get_format(ltstype, i) != LTStypeChunk && lts_type_get_format(ltstype, i) != LTStypeEnum) { Debug ("Skipping type values for non-chunk type %s", lts_type_get_type(ltstype, i)); continue; } for(int j=0; j < type_value_count; ++j) { const char* type_value = get_state_variable_type_value(i, j); pins_chunk_put_at (model, i, chunk_str((char*)type_value), j); } } lts_type_validate(ltstype); int ngroups = get_transition_count(); dm_create(dm_info, ngroups, state_length); dm_create(dm_read_info, ngroups, state_length); dm_create(dm_actions_read_info, ngroups, state_length); dm_create(dm_may_write_info, ngroups, state_length); dm_create(dm_must_write_info, ngroups, state_length); for(int i=0; i < dm_nrows(dm_info); i++) { int* proj = (int*)get_transition_read_dependencies(i); for(int j=0; j<state_length; j++) { if (proj[j]) { dm_set(dm_info, i, j); dm_set(dm_read_info, i, j); } } proj = (int*)get_transition_actions_read_dependencies(i); for(int j=0; j<state_length; j++) { if (proj[j]) { dm_set(dm_actions_read_info, i, j); } } proj = (int*)get_transition_may_write_dependencies(i); for(int j=0; j<state_length; j++) { if (proj[j]) { dm_set(dm_info, i, j); dm_set(dm_may_write_info, i, j); } } proj = (int*)get_transition_must_write_dependencies(i); for(int j=0; j<state_length; j++) { if (proj[j]) { dm_set(dm_must_write_info, i, j); } } } GBsetDMInfo(model, dm_info); GBsetDMInfoRead(model, dm_read_info); GBsetMatrix(model, LTSMIN_MATRIX_ACTIONS_READS, dm_actions_read_info, PINS_MAY_SET, PINS_INDEX_GROUP, PINS_INDEX_STATE_VECTOR); GBsetDMInfoMayWrite(model, dm_may_write_info); GBsetDMInfoMustWrite(model, dm_must_write_info); // set state label matrix (accepting label and guards) get_label_method_t sl_long = NULL; get_label_all_method_t sl_all = NULL; dm_create(sl_info, sl_size, state_length); // if the model exports a property, reserve first for accepting label if (have_property()) { for (int i=0; i<state_length; ++i) { if (strcmp ("LTL_property", lts_type_get_state_name(ltstype, i)) == 0) { dm_set(sl_info, ctx->accepting_state_label_idx, i); } } } // if the model has guards, add guards as state labels if (have_property()) { // filter the property sl_long = sl_long_p_g; sl_all = sl_all_p_g; } else { // pass request directly to dynamic lib sl_long = (get_label_method_t) get_guard; sl_all = (get_label_all_method_t) get_guard_all; } // set the guards per transition group GBsetGuardsInfo(model, (guard_t**) get_all_guards()); // initialize state label matrix // assumption, guards come first (0-nguards) for(int i=0; i < nguards; i++) { int* guards = (int*)get_guard_matrix(i); for(int j=0; j<state_length; j++) { if (guards[j]) dm_set(sl_info, i, j); } } // set guard may be co-enabled relation if (get_guard_may_be_coenabled_matrix) { matrix_t *gce_info = RTmalloc(sizeof(matrix_t)); dm_create(gce_info, nguards, nguards); for(int i=0; i < nguards; i++) { int* guardce = (int*)get_guard_may_be_coenabled_matrix(i); for(int j=0; j<nguards; j++) { if (guardce[j]) dm_set(gce_info, i, j); } } GBsetGuardCoEnabledInfo(model, gce_info); } // set guard necessary enabling set info if (get_guard_nes_matrix) { matrix_t *gnes_info = RTmalloc(sizeof(matrix_t)); dm_create(gnes_info, nguards, ngroups); for(int i=0; i < nguards; i++) { int* guardnes = (int*)get_guard_nes_matrix(i); for(int j=0; j<ngroups; j++) { if (guardnes[j]) dm_set(gnes_info, i, j); } } GBsetGuardNESInfo(model, gnes_info); } // set guard necessary disabling set info if (get_guard_nds_matrix) { matrix_t *gnds_info = RTmalloc(sizeof(matrix_t)); dm_create(gnds_info, nguards, ngroups); for(int i=0; i < nguards; i++) { int* guardnds = (int*)get_guard_nds_matrix(i); for(int j=0; j<ngroups; j++) { if (guardnds[j]) dm_set(gnds_info, i, j); } } GBsetGuardNDSInfo(model, gnds_info); } if (!get_dna_matrix) { Warning (info, "*** Warning ***"); Warning (info, "You are using an old version of our patched DiVinE compiler."); Warning (info, "This might influence the performance of partial order reduction negatively."); Warning (info, "Please download the latest from: http://fmt.cs.utwente.nl/tools/ltsmin/"); Warning (info, "*** Warning ***"); } else { matrix_t *dna_info = RTmalloc(sizeof(matrix_t)); dm_create(dna_info, ngroups, ngroups); for(int i=0; i < ngroups; i++) { int* dna = (int*)get_dna_matrix(i); for(int j=0; j<ngroups; j++) { if (dna[j]) dm_set(dna_info, i, j); } } GBsetDoNotAccordInfo(model, dna_info); } // set the group implementation sl_group_t* sl_group_all = RTmallocZero(sizeof(sl_group_t) + sl_size * sizeof(int)); sl_group_all->count = sl_size; for(int i=0; i < sl_group_all->count; i++) sl_group_all->sl_idx[i] = i; sl_group_t* sl_group_guards = RTmallocZero(sizeof(sl_group_t) + nguards * sizeof(int)); sl_group_guards->count = nguards; for(int i=0; i < sl_group_guards->count; i++) sl_group_guards->sl_idx[i] = i; GBsetStateLabelGroupInfo(model, GB_SL_ALL, sl_group_all); GBsetStateLabelGroupInfo(model, GB_SL_GUARDS, sl_group_guards); GBsetStateLabelsGroup(model, sl_group); GBsetStateLabelInfo(model, sl_info); if (sl_long != NULL) GBsetStateLabelLong(model, sl_long); if (sl_all != NULL) GBsetStateLabelsAll(model, sl_all); // get initial state int state[state_length]; get_initial_state((char*)state); GBsetInitialState(model,state); GBsetNextStateAll (model, (next_method_black_t) get_successors); GBsetNextStateLong (model, (next_method_grey_t) get_successor); GBsetActionsLong (model, (next_method_grey_t) get_action); }
static void init_domain(vset_implementation_t impl) { domain = vdom_create_domain(N, impl); for (int i = 0; i < dm_ncols(GBgetDMInfo(model)); i++) { vdom_set_name(domain, i, lts_type_get_state_name(ltstype, i)); } group_next = (vrel_t*)RTmalloc(nGrps * sizeof(vrel_t)); group_explored = (vset_t*)RTmalloc(nGrps * sizeof(vset_t)); group_tmp = (vset_t*)RTmalloc(nGrps * sizeof(vset_t)); r_projs = (ci_list **)RTmalloc(sizeof(ci_list *[nGrps])); w_projs = (ci_list **)RTmalloc(sizeof(ci_list *[nGrps])); l_projs = (ci_list **)RTmalloc(sizeof(ci_list *[sLbls])); label_false = (vset_t*)RTmalloc(sLbls * sizeof(vset_t)); label_true = (vset_t*)RTmalloc(sLbls * sizeof(vset_t)); label_tmp = (vset_t*)RTmalloc(sLbls * sizeof(vset_t)); if (!vdom_separates_rw(domain) && !PINS_USE_GUARDS) { read_matrix = GBgetDMInfo(model); write_matrix = GBgetDMInfo(model); Warning(info, "Using GBgetTransitionsShort as next-state function"); transitions_short = GBgetTransitionsShort; } else if (!vdom_separates_rw(domain) && PINS_USE_GUARDS) { read_matrix = GBgetMatrix(model, GBgetMatrixID(model, LTSMIN_MATRIX_ACTIONS_READS)); write_matrix = GBgetDMInfo(model); Warning(info, "Using GBgetActionsShort as next-state function"); transitions_short = GBgetActionsShort; } else if (vdom_separates_rw(domain) && !PINS_USE_GUARDS) { read_matrix = GBgetDMInfoRead(model); write_matrix = GBgetDMInfoMayWrite(model); Warning(info, "Using GBgetTransitionsShortR2W as next-state function"); transitions_short = GBgetTransitionsShortR2W; } else { // vdom_separates_rw(domain) && PINS_USE_GUARDS read_matrix = GBgetMatrix(model, GBgetMatrixID(model, LTSMIN_MATRIX_ACTIONS_READS)); write_matrix = GBgetDMInfoMayWrite(model); Warning(info, "Using GBgetActionsShortR2W as next-state function"); transitions_short = GBgetActionsShortR2W; } if (PINS_USE_GUARDS) { if (no_soundness_check) { Warning(info, "Guard-splitting: not checking soundness of the specification, this may result in an incorrect state space!"); } else { Warning(info, "Guard-splitting: checking soundness of specification, this may be slow!"); } } r_projs = (ci_list **) dm_rows_to_idx_table (read_matrix); w_projs = (ci_list **) dm_rows_to_idx_table (write_matrix); for(int i = 0; i < nGrps; i++) { if (HREme(HREglobal())==0) { if (vdom_separates_rw(domain)) { group_next[i] = vrel_create_rw (domain, r_projs[i]->count, r_projs[i]->data, w_projs[i]->count, w_projs[i]->data); } else { group_next[i] = vrel_create (domain, r_projs[i]->count, r_projs[i]->data); } group_explored[i] = vset_create (domain, r_projs[i]->count, r_projs[i]->data); group_tmp[i] = vset_create (domain, r_projs[i]->count, r_projs[i]->data); if (inhibit_matrix != NULL) { inhibit_class_count = dm_nrows(inhibit_matrix); class_enabled = (vset_t*)RTmalloc(inhibit_class_count * sizeof(vset_t)); for(int i=0; i<inhibit_class_count; i++) { class_enabled[i] = vset_create(domain, -1, NULL); } } } } l_projs = (ci_list **) dm_rows_to_idx_table (GBgetStateLabelInfo(model)); for (int i = 0; i < sLbls; i++) { /* Indeed, we skip unused state labels, but allocate memory for pointers * (to vset_t's). Is this bad? Maybe a hashmap is worse. */ if (bitvector_is_set(&state_label_used, i)) { if (HREme(HREglobal()) == 0) { label_false[i] = vset_create(domain, l_projs[i]->count, l_projs[i]->data); label_true[i] = vset_create(domain, l_projs[i]->count, l_projs[i]->data); label_tmp[i] = vset_create(domain, l_projs[i]->count, l_projs[i]->data); } } else { label_false[i] = NULL; label_true[i] = NULL; label_tmp[i] = NULL; } } inv_set = (vset_t *) RTmalloc(sizeof(vset_t[num_inv])); for (int i = 0; i < num_inv; i++) { inv_set[i] = vset_create (domain, inv_proj[i]->count, inv_proj[i]->data); inv_info_prepare (inv_expr[i], inv_parse_env[i], i); } }