void pins_model_init(model_t m) { // create the LTS type LTSmin will generate lts_type_t ltstype=lts_type_create(); // set the length of the state lts_type_set_state_length(ltstype, state_length()); // add an "int" type for a state slot int int_type = lts_type_add_type(ltstype, "int", NULL); lts_type_set_format (ltstype, int_type, LTStypeDirect); // add an "action" type for edge labels int action_type = lts_type_add_type(ltstype, "action", NULL); lts_type_set_format (ltstype, action_type, LTStypeEnum); // add a "bool" type for state labels int bool_type = lts_type_add_type (ltstype, LTSMIN_TYPE_BOOL, NULL); lts_type_set_format(ltstype, bool_type, LTStypeEnum); // set state name & type for (int i=0; i < state_length(); ++i) { char name[3]; sprintf(name, "%d", i); lts_type_set_state_name(ltstype,i,name); lts_type_set_state_typeno(ltstype,i,int_type); } // edge label types lts_type_set_edge_label_count (ltstype, 1); lts_type_set_edge_label_name(ltstype, 0, "action"); lts_type_set_edge_label_type(ltstype, 0, "action"); lts_type_set_edge_label_typeno(ltstype, 0, action_type); // state label types lts_type_set_state_label_count (ltstype, 1); lts_type_set_state_label_name (ltstype, 0, "goal"); lts_type_set_state_label_typeno (ltstype, 0, bool_type); // done with ltstype lts_type_validate(ltstype); // make sure to set the lts-type before anything else in the GB GBsetLTStype(m, ltstype); // setting all values for all non direct types GBchunkPut(m, action_type, chunk_str("switch_a")); GBchunkPut(m, action_type, chunk_str("switch_b")); GBchunkPut(m, action_type, chunk_str("switch_c")); GBchunkPut(m, action_type, chunk_str("switch_d")); GBchunkPut(m, action_type, chunk_str("switch_ab")); GBchunkPut(m, action_type, chunk_str("switch_ac")); GBchunkPut(m, action_type, chunk_str("switch_ad")); GBchunkPut(m, action_type, chunk_str("switch_bc")); GBchunkPut(m, action_type, chunk_str("switch_bd")); GBchunkPut(m, action_type, chunk_str("switch_cd")); GBchunkPut(m, bool_type, chunk_str(LTSMIN_VALUE_BOOL_FALSE)); GBchunkPut(m, bool_type, chunk_str(LTSMIN_VALUE_BOOL_TRUE)); // set state variable values for initial state GBsetInitialState(m, initial_state()); // set function pointer for the next-state function GBsetNextStateLong(m, (next_method_grey_t) next_state); // set function pointer for the label evaluation function GBsetStateLabelLong(m, (get_label_method_t) state_label); // create combined matrix matrix_t *cm = malloc(sizeof(matrix_t)); dm_create(cm, group_count(), state_length()); // set the read dependency matrix matrix_t *rm = malloc(sizeof(matrix_t)); dm_create(rm, group_count(), state_length()); for (int i = 0; i < group_count(); i++) { for (int j = 0; j < state_length(); j++) { if (read_matrix(i)[j]) { dm_set(cm, i, j); dm_set(rm, i, j); } } } GBsetDMInfoRead(m, rm); // set the write dependency matrix matrix_t *wm = malloc(sizeof(matrix_t)); dm_create(wm, group_count(), state_length()); for (int i = 0; i < group_count(); i++) { for (int j = 0; j < state_length(); j++) { if (write_matrix(i)[j]) { dm_set(cm, i, j); dm_set(wm, i, j); } } } GBsetDMInfoMustWrite(m, wm); // set the combined matrix GBsetDMInfo(m, cm); // set the label dependency matrix matrix_t *lm = malloc(sizeof(matrix_t)); dm_create(lm, label_count(), state_length()); for (int i = 0; i < label_count(); i++) { for (int j = 0; j < state_length(); j++) { if (label_matrix(i)[j]) dm_set(lm, i, j); } } GBsetStateLabelInfo(m, lm); }
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; }
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); }
lts_type_t lts_type_deserialize(stream_t ds){ lts_type_t t=lts_type_create(); char version[1024]; DSreadS(ds,version,1024); int has_format_info; if (strcmp(version,"lts signature 1.1")==0){ has_format_info=1; } else if (strcmp(version,"lts signature 1.0")==0){ has_format_info=0; } else { Abort("cannot deserialize %s",version); } uint32_t N=DSreadU32(ds); Warning(debug,"state length is %d",N); lts_type_set_state_length(t,N); for(uint32_t i=0;i<N;i++){ char*x=DSreadSA(ds); if (strlen(x)) lts_type_set_state_name(t,i,x); RTfree(x); lts_type_set_state_typeno(t,i,DSreadU32(ds)); } N=DSreadU32(ds); Warning(debug,"%d state labels",N); lts_type_set_state_label_count(t,N); for(uint32_t i=0;i<N;i++){ char*x=DSreadSA(ds); if (strlen(x)) lts_type_set_state_label_name(t,i,x); RTfree(x); lts_type_set_state_label_typeno(t,i,DSreadU32(ds)); } N=DSreadU32(ds); Warning(debug,"%d edge labels",N); lts_type_set_edge_label_count(t,N); for(uint32_t i=0;i<N;i++){ char*x=DSreadSA(ds); if (strlen(x)) lts_type_set_edge_label_name(t,i,x); RTfree(x); lts_type_set_edge_label_typeno(t,i,DSreadU32(ds)); } N=DSreadU32(ds); Warning(debug,"%d types",N); for(uint32_t i=0;i<N;i++){ char*x=DSreadSA(ds); int tmp=lts_type_add_type(t,x,NULL); if (tmp!=(int)i) Abort("bad type add"); RTfree(x); if (has_format_info) { x=DSreadSA(ds); if (strcmp(x,"direct")==0){ lts_type_set_format(t,i,LTStypeDirect); } else if (strcmp(x,"chunk")==0){ lts_type_set_format(t,i,LTStypeChunk); } else if (strcmp(x,"enum")==0){ lts_type_set_format(t,i,LTStypeEnum); } else { int n=strlen(x); if (x[0]=='[' && x[n-1]==']') { int k=0; while(k<n && x[k]!=',') k++; if (k<n) { lts_type_set_format(t,i,LTStypeRange); lts_type_set_range(t,i,atoi(x+1),atoi(x+k+1)); } } Abort("unsupported data format %s",x); } RTfree(x); } else { lts_type_set_format(t,i,LTStypeChunk); } } return t; }