void pins_model_init(model_t model) { lts_type_t ltstype; matrix_t *dm_info = malloc(sizeof(matrix_t)); matrix_t *dm_read_info = malloc(sizeof(matrix_t)); matrix_t *dm_must_write_info = malloc(sizeof(matrix_t)); // get ltstypes ltstype=lts_type_create(); const int state_length = pnml_vars; // adding types int ntypes = 2; int int_type = lts_type_add_type(ltstype, "int", NULL); int act_type =lts_type_add_type(ltstype, "action", NULL); lts_type_set_format (ltstype, int_type, LTStypeDirect); lts_type_set_format (ltstype, act_type, LTStypeEnum); lts_type_set_state_length(ltstype, state_length); // set state name & type for (int i=0; i < state_length; ++i) { lts_type_set_state_name(ltstype,i,pnml_var_names[i]); 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, act_type); int bool_is_new, bool_type = lts_type_add_type(ltstype, LTSMIN_TYPE_BOOL, NULL); GBsetLTStype(model, ltstype); // must set ltstype before setting initial state // creates tables for types! if (bool_is_new) { GBchunkPutAt(model, bool_type, chunk_str(LTSMIN_VALUE_BOOL_FALSE), 0); GBchunkPutAt(model, bool_type, chunk_str(LTSMIN_VALUE_BOOL_TRUE ), 1); } // setting values for types for (int i = 0; i < pnml_groups; i++) { GBchunkPutAt(model, act_type, chunk_str((char*) pnml_group_names[i]), i); } // get initial state GBsetInitialState(model,pnml_initial_state); for (int i = 0; i < pnml_vars; i++) { if (max_token_count < pnml_initial_state[i]) { max_token_count = pnml_initial_state[i]; } } // get next state GBsetNextStateLong(model, (next_method_grey_t) pnml_get_successor); lts_type_validate(ltstype); // done with ltstype // initialize the state read/write dependency matrices dm_create(dm_read_info, pnml_groups, state_length); dm_create(dm_must_write_info, pnml_groups, state_length); for (int i = 0; i < pnml_groups; i++) { for (int j = 0; j < pnml_sources[i][0]; j++) { dm_set(dm_read_info, i, pnml_sources[i][j*2+1]); dm_set(dm_must_write_info, i, pnml_sources[i][j*2+1]); } for (int j = 0; j < pnml_targets[i][0]; j++) { if (!pnml_safe_places[pnml_targets[i][j*2+1]]) { /* If the place is safe we don't need to mark it read-dependent. */ dm_set(dm_read_info, i, pnml_targets[i][j*2+1]); } dm_set(dm_must_write_info, i, pnml_targets[i][j*2+1]); } } dm_copy(dm_read_info, dm_info); dm_apply_or(dm_info, dm_must_write_info); GBsetDMInfo(model, dm_info); GBsetDMInfoRead(model, dm_read_info); GBsetDMInfoMustWrite(model, dm_must_write_info); GBsetSupportsCopy(model); GBsetExit(model, pnml_exit); matrix_t *dna_info = malloc(sizeof(matrix_t)); dm_create(dna_info, pnml_groups, pnml_groups); for (int i = 0; i < pnml_groups; i++) { for(int j = 0; j < pnml_groups; j++) { const int guards_i = pnml_sources[i][0]; const int guards_j = pnml_sources[j][0]; for (int g = 0; g < guards_i; g++) { const int guard_i = pnml_sources[i][g * 2 + 1]; for (int h = 0; h < guards_j; h++) { const int guard_j = pnml_sources[j][h * 2 + 1]; if (guard_i == guard_j) { dm_set(dna_info, i, j); goto next_dna; } } } next_dna:; } } GBsetDoNotAccordInfo(model, dna_info); matrix_t *gnes_info = malloc(sizeof(matrix_t)); dm_create(gnes_info, pnml_vars, pnml_groups); for(int i = 0; i < pnml_groups; i++) { const int targets = pnml_targets[i][0]; for (int t = 0; t < targets; t++) { const int target = pnml_targets[i][t * 2 + 1]; dm_set(gnes_info, target, i); } } GBsetGuardNESInfo(model, gnes_info); matrix_t *gnds_info = malloc(sizeof(matrix_t)); dm_create(gnds_info, pnml_vars, pnml_groups); for(int i = 0; i < pnml_groups; i++) { const int sources = pnml_sources[i][0]; for (int s = 0; s < sources; s++) { const int source = pnml_sources[i][s * 2 + 1]; dm_set(gnds_info, source, i); } } GBsetGuardNDSInfo(model, gnds_info); matrix_t *ndb_info = malloc(sizeof(matrix_t)); dm_create(ndb_info, pnml_groups, pnml_groups); for (int i = 0; i < pnml_groups; i++) { const int sources = pnml_sources[i][0]; for (int j = 0; j < pnml_groups; j++) { const int targets = pnml_targets[j][0]; for (int s = 0; s < sources; s++) { const int source = pnml_sources[i][s * 2 + 1]; for (int t = 0; t < targets; t++) { const int target = pnml_targets[j][t * 2 + 1]; if (source == target) { dm_set(ndb_info, i, j); goto next_ndb; } } } next_ndb:; } } GBsetMatrix(model, LTSMIN_NOT_LEFT_ACCORDS, ndb_info, PINS_STRICT, PINS_INDEX_OTHER, PINS_INDEX_OTHER); }
void ETFloadGreyboxModel(model_t model, const char *name) { gb_context_t ctx=(gb_context_t)RTmalloc(sizeof(struct grey_box_context)); GBsetContext(model,ctx); etf_model_t etf=etf_parse_file(name); lts_type_t ltstype=etf_type(etf); int state_length=lts_type_get_state_length(ltstype); ctx->edge_labels=lts_type_get_edge_label_count(ltstype); if (ctx->edge_labels>1) { ctx->label_idx=SIcreate(); } else { ctx->label_idx=NULL; } GBsetLTStype(model,ltstype); matrix_t* p_dm_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); matrix_t* p_dm_read_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); matrix_t* p_dm_write_info = (matrix_t*)RTmalloc(sizeof(matrix_t)); dm_create(p_dm_info, etf_trans_section_count(etf), state_length); dm_create(p_dm_read_info, etf_trans_section_count(etf), state_length); dm_create(p_dm_write_info, etf_trans_section_count(etf), state_length); ctx->trans_key_idx=(string_index_t*)RTmalloc(dm_nrows(p_dm_info)*sizeof(string_index_t)); ctx->trans_table=(matrix_table_t*)RTmalloc(dm_nrows(p_dm_info)*sizeof(matrix_table_t)); for(int i=0; i < dm_nrows(p_dm_info); i++) { Warning(infoLong,"parsing table %d",i); etf_rel_t trans=etf_trans_section(etf,i); int used[state_length]; int src[state_length]; int dst[state_length]; int lbl[ctx->edge_labels]; int proj[state_length]; ETFrelIterate(trans); if (!ETFrelNext(trans,src,dst,lbl)){ Abort("unexpected empty transition section"); } int len=0; for(int j=0;j<state_length;j++){ if (src[j]) { proj[len]=j; Warning(debug,"pi[%d]=%d",len,proj[len]); len++; dm_set(p_dm_info, i, j); used[j]=1; } else { used[j]=0; } } Warning(infoLong,"length is %d",len); ctx->trans_key_idx[i]=SIcreate(); ctx->trans_table[i]=MTcreate(3); int src_short[len]; int dst_short[len]; uint32_t row[3]; do { /* * If an element is non-zero, we always consider it a read. If the * value is changed for at least one transition in a group then * we also consider it a write. Note that this could be slightly * optimized by omitting those elements from read where the value * varies over all possible inputs. */ for(int k=0;k<state_length;k++) { if (src[k] != 0) { dm_set(p_dm_read_info, i, k); if (src[k] != dst[k]) dm_set(p_dm_write_info, i, k); } } for(int k=0;k<state_length;k++) { if(used[k]?(src[k]==0):(src[k]!=0)){ Abort("inconsistent section in src vector"); } } for(int k=0;k<len;k++) src_short[k]=src[proj[k]]-1; for(int k=0;k<state_length;k++) { if(used[k]?(dst[k]==0):(dst[k]!=0)){ Abort("inconsistent section in dst vector"); } } for(int k=0;k<len;k++) dst_short[k]=dst[proj[k]]-1; row[0]=(uint32_t)SIputC(ctx->trans_key_idx[i],(char*)src_short,len<<2); switch(ctx->edge_labels){ case 0: row[2]=0; break; case 1: row[2]=(uint32_t)lbl[0]; break; default: row[2]=(uint32_t)SIputC(ctx->label_idx,(char*)lbl,(ctx->edge_labels)<<2); break; } row[1]=(int32_t)SIputC(ctx->trans_key_idx[i],(char*)dst_short,len<<2); MTaddRow(ctx->trans_table[i],row); } while(ETFrelNext(trans,src,dst,lbl)); Warning(infoLong,"table %d has %d states and %d transitions", i,SIgetCount(ctx->trans_key_idx[i]),ETFrelCount(trans)); ETFrelDestroy(&trans); MTclusterBuild(ctx->trans_table[i],0,SIgetCount(ctx->trans_key_idx[i])); } GBsetDMInfo(model, p_dm_info); /* * Set these again when ETF supports read, write and copy. GBsetDMInfoRead(model, p_dm_read_info); GBsetDMInfoMustWrite(model, p_dm_write_info); GBsetSupportsCopy(model); // no may-write so we support copy. */ GBsetNextStateShort(model,etf_short); matrix_t *p_sl_info = RTmalloc(sizeof *p_sl_info); dm_create(p_sl_info, etf_map_section_count(etf), state_length); ctx->label_key_idx=(string_index_t*)RTmalloc(dm_nrows(p_sl_info)*sizeof(string_index_t)); ctx->label_data=(int**)RTmalloc(dm_nrows(p_sl_info)*sizeof(int*)); for(int i=0;i<dm_nrows(p_sl_info);i++){ Warning(infoLong,"parsing map %d",i); etf_map_t map=etf_get_map(etf,i); int used[state_length]; int state[state_length]; int value; ETFmapIterate(map); if (!ETFmapNext(map,state,&value)){ Abort("Unexpected empty map"); } int len=0; for(int j=0;j<state_length;j++){ if (state[j]) { used[len]=j; len++; dm_set(p_sl_info, i, j); } } int*proj=(int*)RTmalloc(len*sizeof(int)); for(int j=0;j<len;j++) proj[j]=used[j]; for(int j=0;j<state_length;j++) used[j]=state[j]; string_index_t key_idx=SIcreate(); int *data=(int*)RTmalloc(ETFmapCount(map)*sizeof(int)); int key[len]; do { for(int k=0;k<state_length;k++) { if(used[k]?(state[k]==0):(state[k]!=0)){ Abort("inconsistent map section"); } } for(int k=0;k<len;k++) key[k]=state[proj[k]]-1; data[SIputC(key_idx,(char*)key,len<<2)]=value; } while(ETFmapNext(map,state,&value)); ctx->label_key_idx[i]=key_idx; ctx->label_data[i]=data; } GBsetStateLabelInfo(model, p_sl_info); GBsetStateLabelShort(model,etf_state_short); GBsetTransitionInGroup(model,etf_transition_in_group); int type_count=lts_type_get_type_count(ltstype); for(int i=0;i<type_count;i++){ Warning(infoLong,"Setting values for type %d (%s)",i,lts_type_get_type(ltstype,i)); int count=etf_get_value_count(etf,i); for(int j=0;j<count;j++){ GBchunkPutAt(model,i,etf_get_value(etf,i,j),j); } } int state[state_length]; etf_get_initial(etf,state); GBsetInitialState(model,state); }