int dm_apply_xor(matrix_t* a, const matrix_t* b) { if (dm_ncols(a) != dm_ncols(b) || dm_nrows(a) != dm_nrows(b)) { return -1; } for (int i = 0; i < dm_nrows(a); i++) { for (int j = 0; j < dm_ncols(a); j++) { if (dm_is_set(a, i, j) != dm_is_set(b, i, j)) dm_set(a, i, j); else dm_unset(a, i, j); } } return 0; }
int dm_flatten (matrix_t *m) { matrix_t m_new; int i, j; dm_create (&m_new, dm_nrows (m), dm_ncols (m)); for (i = 0; i < dm_nrows (m); i++) { for (j = 0; j < dm_ncols (m); j++) { if (dm_is_set (m, i, j)) dm_set (&m_new, i, j); } } dm_free (m); *m = m_new; return 0; }
int resize_matrix (matrix_t *m, int rows, int cols) { matrix_t m_new; printf ("resize_matrix %d %d\n", rows, cols); dm_create (&m_new, rows, cols); // copy data int i, j; for (i = 0; i < dm_nrows (m); i++) { for (j = 0; j < dm_ncols (m); j++) { if (dm_is_set (m, i, j)) dm_set (&m_new, i, j); } } dm_free (m); *m = m_new; return 1; }
matrix_t read_matrix () { matrix_t m; dm_create (&m, 100, 100); char c; int row = -1; int col = -1; int max_row = 0, max_col = 0; while ((c = getchar ()) != EOF) { col++; if (col == 0) max_row = ++row + 1; if (c == '+' || c == '1') { if (col >= dm_ncols (&m)) resize_matrix (&m, dm_nrows (&m), dm_ncols (&m) * 2); if (row >= dm_nrows (&m)) resize_matrix (&m, dm_nrows (&m) * 2, dm_ncols (&m)); dm_set (&m, row, col); } if (c == '-' || c == '0') { } ; if (c == '\n') { max_col = max_col < col ? col : max_col; col = -1; } } resize_matrix (&m, max_row, max_col); return m; }
int main (void) { bitvector_t b1; bitvector_t b2; bitvector_create (&b1, 20); user_bitvector_print (&b1); bitvector_set (&b1, 4); user_bitvector_print (&b1); bitvector_copy (&b2, &b1); bitvector_unset (&b1, 4); user_bitvector_print (&b1); user_bitvector_print (&b2); // test is_empty printf ("is_empty b1? %c (should be t)\n", bitvector_is_empty(&b1)?'t':'f'); printf ("is_empty b2? %c (should be f)\n", bitvector_is_empty(&b2)?'t':'f'); // set even/odd bits in b1/b2 for(int i=0; i<20; ++i) { if (i%2) { bitvector_set(&b1,i); } else { bitvector_set(&b2,i); } } // print before union printf ("before union\n"); user_bitvector_print (&b1); user_bitvector_print (&b2); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); printf ("union\n"); bitvector_union(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after union user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("intersect\n"); bitvector_intersect(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after intersection user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("invert b1\n"); bitvector_invert(&b1); // print after inversion user_bitvector_print (&b1); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); bitvector_free (&b2); bitvector_free (&b1); matrix_t m1; matrix_t m2; dm_create (&m1, 10, 10); print_matrix (&m1); printf ("dm_set(4,4)\n"); dm_set (&m1, 4, 4); print_matrix (&m1); printf ("dm_unset(4,4)\n"); dm_unset (&m1, 4, 4); print_matrix (&m1); printf ("test shift permutation (3,4,5)(6,7)\n"); printf ("before\n"); dm_set (&m1, 3, 3); dm_set (&m1, 4, 4); dm_set (&m1, 5, 5); dm_set (&m1, 6, 6); dm_set (&m1, 7, 7); print_matrix (&m1); printf ("after\n"); // create permutation_group, apply permutation_group_t o1; dm_create_permutation_group (&o1, 2, NULL); dm_add_to_permutation_group (&o1, 3); dm_add_to_permutation_group (&o1, 4); dm_add_to_permutation_group (&o1, 5); dm_close_group (&o1); dm_add_to_permutation_group (&o1, 6); dm_add_to_permutation_group (&o1, 7); dm_permute_cols (&m1, &o1); print_matrix (&m1); dm_free_permutation_group (&o1); printf ("swap cols 6,7\n"); dm_swap_cols (&m1, 6, 7); print_matrix (&m1); printf ("swap rows 6,7\n"); dm_swap_rows (&m1, 6, 7); print_matrix (&m1); printf ("copy\n"); dm_create(&m2, dm_nrows(&m1), dm_ncols(&m1)); dm_copy (&m1, &m2); // TODO: needs some more work print_matrix (&m2); dm_sort_rows (&m1, &min_row_first); print_matrix (&m1); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("to nub rows added & resorted\n"); dm_set (&m1, 7, 3); dm_set (&m1, 8, 4); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); printf ("flatten \n"); dm_flatten (&m1); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("nub sorted\n"); //dm_nub_rows (&m1, &eq_rows, NULL); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); /* * printf("again, now to test row order & nub idx\n"); dm_free(&m1); * dm_create(&m1, 10, 10); dm_set(&m1, 0,0); dm_set(&m1, 1,0); * dm_set(&m1, 2,3); dm_set(&m1, 3,3); print_matrix(&m1); * * printf("nub sorted\n"); * * dm_nub_rows(&m1); * * print_matrix(&m1); * * dm_print_perm(&(m1.row_perm)); */ printf ("optimize sorted\n"); dm_set (&m1, 0, 7); dm_set (&m1, 1, 6); dm_set (&m1, 3, 9); printf ("before\n"); print_matrix (&m1); dm_optimize (&m1); printf ("after\n"); print_matrix (&m1); printf ("resorted\n"); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); /* dm_nub_cols(&m1); dm_ungroup_rows(&m1); dm_ungroup_cols(&m1); print_matrix (&m1); */ // get bitvector from matrix text bitvector_create (&b1, 6); bitvector_create (&b2, 10); printf ("bitvector of row 0\n"); user_bitvector_print (&b2); printf ("bitvector of col 8\n"); user_bitvector_print (&b1); bitvector_free (&b2); bitvector_free (&b1); printf ("count test\n"); for (int i = 0; i < dm_nrows (&m1); i++) printf ("ones in row %d: %d\n", i, dm_ones_in_row (&m1, i)); for (int i = 0; i < dm_ncols (&m1); i++) printf ("ones in col %d: %d\n", i, dm_ones_in_col (&m1, i)); printf ("iterator test\n"); dm_row_iterator_t mx; dm_col_iterator_t my; for (int i = 0; i < dm_nrows (&m1); i++) { printf ("iterator row: %d\n", i); dm_create_row_iterator (&mx, &m1, i); int r; while ((r = dm_row_next (&mx)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } for (int i = 0; i < dm_ncols (&m1); i++) { printf ("iterator col: %d\n", i); dm_create_col_iterator (&my, &m1, i); int r; while ((r = dm_col_next (&my)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } printf ("projection test\n"); int s0[10]; int src[10]; int prj[2]; int tgt[10]; // initialize for (int i = 0; i < 10; i++) { s0[i] = -i; src[i] = i; } // do projection int prj_n = dm_project_vector (&m1, 0, src, prj); // print projection printf ("projection:"); for (int i = 0; i < prj_n; i++) { printf (" %d", prj[i]); } printf ("\n"); printf ("expansion test\n"); // do expansion int exp_n = dm_expand_vector (&m1, 0, s0, prj, tgt); (void)exp_n; // print expansion printf ("expansion:"); for (int i = 0; i < 10; i++) { printf (" %d", tgt[i]); } printf ("\n"); // subsumption printf ("subsumption test:\n"); dm_swap_rows (&m1, 0, 3); dm_swap_rows (&m1, 1, 2); dm_flatten (&m1); print_matrix (&m1); dm_subsume_rows (&m1, &eq_rows, NULL); printf ("after subsumption:\n"); print_matrix (&m1); printf ("\n"); printf ("after ungrouping:\n"); dm_ungroup_rows (&m1); print_matrix (&m1); printf ("\n"); printf ("column sort test:\n"); dm_flatten (&m1); printf ("max col first:\n"); dm_sort_cols (&m1, &max_col_first); print_matrix (&m1); printf ("min col first:\n"); dm_sort_cols (&m1, &min_col_first); print_matrix (&m1); printf ("nub columns test:\n"); dm_set (&m1, 0, 1); dm_set (&m1, 3, 1); dm_set (&m1, 3, 4); dm_set (&m1, 3, 5); dm_sort_cols (&m1, &max_col_first); // dm_flatten(&m1); printf ("max col first:\n"); print_matrix (&m1); //printf ("subsume columns:\n"); //dm_subsume_cols (&m1, &eq_cols, NULL); //dm_subsume_rows (&m1, &eq_rows, NULL); print_matrix (&m1); printf ("column permutation:\n"); dm_print_perm (&(m1.col_perm)); printf ("optimize columns:\n"); dm_optimize (&m1); print_matrix (&m1); //printf ("ungroup columns:\n"); //dm_ungroup_cols (&m1); //print_matrix (&m1); //printf ("all permutations:\n"); //dm_set (&m1, 0, 9); //dm_nub_cols(&m1, &eq_cols, NULL); //print_matrix (&m1); //dm_all_perm (&m1); dm_free (&m2); dm_free (&m1); return 0; }
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 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); }
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); }
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); }