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()); }
static int cost_ (matrix_t *r, matrix_t *mayw) { HREassert( dm_ncols(r) == dm_ncols(mayw) && dm_nrows(r) == dm_nrows(mayw), "matrix sizes do not match"); int i, result; result = 0; for (i = 0; i < dm_nrows (r); i++) result += row_costs_ (r, mayw, i); return result; }
int dm_equals(const 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)) return 0; } } return 1; }
int dm_print_combined (FILE * f, const matrix_t *r, const matrix_t *mayw, const matrix_t *mustw) { fprintf(f, " 0"); for (int j = 0; j+10 < dm_ncols(r); j+=10) fprintf(f, "%10d", j+10); fprintf(f, " \n"); for (int i = 0; i < dm_nrows(r); i++) { fprintf(f, "%4d: ", i); for (int j = 0; j < dm_ncols(r); j++) { if (dm_is_set(r, i, j) && (dm_is_set(mayw, i, j))) { fprintf(f, "+"); } else if (dm_is_set(r, i, j)) { fprintf(f, "r"); } else if (dm_is_set(mustw, i, j)) { fprintf(f, "w"); } else if (dm_is_set(mayw, i, j)) { fprintf(f, "W"); } else { fprintf(f, "-"); } } fprintf(f, "\n"); } return 0; }
int transition_mapping (matrix_t *m) { // optimized matrix row -> original matrix rows.. int i, sepi, sepj; printf ("["); for (i = 0, sepi = 0; i < dm_nrows (m); i++) { if (sepi) printf (","); sepi = 1; printf ("(%d,[", i); sepj = 0; int group = m->row_perm.data[i].becomes; int allg = group; do { if (sepj) printf (","); sepj = 1; printf ("%d", allg); allg = m->row_perm.data[allg].group; } while (allg != group); printf ("])"); } printf ("]\n"); return 1; }
int dependencies (matrix_t *m) { int i, j; int sepi, sepj; printf ("["); for (i = 0, sepi = 0; i < dm_nrows (m); i++) { if (sepi) printf (","); sepi = 1; printf ("(%d,[", i); for (j = 0, sepj = 0; j < dm_ncols (m); j++) { if (dm_is_set (m, i, j)) { if (sepj) printf (","); sepj = 1; printf ("%d", j); } } printf ("])"); } printf ("]\n"); return 1; }
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_bitvector_col(bitvector_t *bv, const matrix_t *m, int col) { // check size if (bitvector_size (bv) != (size_t)dm_nrows (m)) return -1; // copy row for (int i = 0; i < dm_nrows (m); i++) { if (dm_is_set (m, i, col)) { bitvector_set(bv, i); } else { bitvector_unset(bv, i); } } return 0; }
void print_matrix (matrix_t *m) { printf ("matrix(%d, %d)\n", dm_nrows (m), dm_ncols (m)); dm_print (stdout, m); printf ("\n"); }
int dm_is_empty(const matrix_t* m) { for (int i = 0; i < dm_nrows(m); i++) for (int j = 0; j < dm_ncols(m); j++) if (dm_is_set(m, i, j)) return 0; return 1; }
int dm_ungroup_rows (matrix_t *m) { int i; for (i = 0; i < dm_nrows (m); i++) { unmerge_row_ (m, i); } return 0; }
static inline int row_costs_ (matrix_t *r, matrix_t *mayw, int row) { HREassert( dm_ncols(r) == dm_ncols(mayw) && dm_nrows(r) == dm_nrows(mayw), "matrix sizes do not match"); int writes = 0; int cost = 0; for (int i = 0; i < dm_ncols(r); i++) { if (dm_is_set(mayw, row, i)) writes++; if (dm_is_set(r, row, i)) cost += writes; } cost += max(last_ (mayw, row), last_ (r, row)) - min(first_ (mayw, row), first_ (r, row)) + 1; return cost; }
int estimate_cost(matrix_t *m, int i, int j, int firsts[], int lasts[]) { int row,ef,el,ec; ec=0; for (row=0;row<dm_nrows(m);row++) { ef=est_first(m,row,i,j,firsts[row]); el=est_last(m,row,i,j,lasts[row]); ec += (el-ef+1); } return ec; }
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; }
static void output_lbls(FILE *tbl_file, vset_t visited) { matrix_t *sl_info = GBgetStateLabelInfo(model); nGuards = dm_nrows(sl_info); if (dm_nrows(sl_info) != lts_type_get_state_label_count(ltstype)) Warning(error, "State label count mismatch!"); for (int i = 0; i < nGuards; i++){ int len = dm_ones_in_row(sl_info, i); int used[len]; // get projection for (int pi = 0, pk = 0; pi < dm_ncols (sl_info); pi++) { if (dm_is_set (sl_info, i, pi)) used[pk++] = pi; } vset_t patterns = vset_create(domain, len, used); map_context ctx; vset_project(patterns, visited); ctx.tbl_file = tbl_file; ctx.mapno = i; ctx.len = len; ctx.used = used; fprintf(tbl_file, "begin map "); fprint_ltsmin_ident(tbl_file, lts_type_get_state_label_name(ltstype,i)); fprintf(tbl_file, ":"); fprint_ltsmin_ident(tbl_file, lts_type_get_state_label_type(ltstype,i)); fprintf(tbl_file,"\n"); vset_enum(patterns, enum_map, &ctx); fprintf(tbl_file, "end map\n"); vset_destroy(patterns); } }
int dm_subsume_cols (matrix_t *r, matrix_t *mayw, matrix_t *mustw, const dm_subsume_cols_fn fn) { HREassert( dm_ncols(r) == dm_ncols(mayw) && dm_nrows(r) == dm_nrows(mayw) && dm_ncols(r) == dm_ncols(mustw) && dm_nrows(r) == dm_nrows(mustw), "matrix sizes do not match"); int i, j; for (i = 0; i < dm_ncols (r); i++) { int col_i_removed; for (j = i + 1; j < dm_ncols (r); j++) { // is col i subsumed by row j? if (fn (r, mayw, mustw, i, j)) { merge_cols_ (r, i, j); merge_cols_ (mayw, i, j); merge_cols_ (mustw, i, j); // now col j is removed, don't increment it in the for loop col_i_removed=1; } else { // is col j subsumed by row i? if (fn (r, mayw, mustw, j, i)) { merge_cols_ (r, j, i); merge_cols_ (mayw, j, i); merge_cols_ (mustw, j, i); // now col j is removed, don't increment it in the for loop j--; } } } if (col_i_removed) i--; } return 0; }
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 dm_nub_cols (matrix_t *r, matrix_t *mayw, matrix_t *mustw, const dm_nub_cols_fn fn) { HREassert( dm_ncols(r) == dm_ncols(mayw) && dm_nrows(r) == dm_nrows(mayw) && dm_ncols(r) == dm_ncols(mustw) && dm_nrows(r) == dm_nrows(mustw), "matrix sizes do not match"); int i, j; for (i = 0; i < dm_ncols (r); i++) { for (j = i + 1; j < dm_ncols (r); j++) { if (fn (r, mayw, mustw, i, j)) { merge_cols_ (r, i, j); merge_cols_ (mayw, i, j); merge_cols_ (mustw, i, j); // now row j is removed, don't increment it in the for loop j--; } } } return 0; }
static void count_col_ (matrix_t *m, int col) { // get permutation int colp = m->col_perm.data[col].becomes; int i; for (i = 0; i < dm_nrows (m); i++) { if (dm_is_set (m, i, col)) { int rowp = m->row_perm.data[i].becomes; m->col_perm.count[colp]++; m->row_perm.count[rowp]++; } } }
int dm_col_next (dm_col_iterator_t *ix) { int result = ix->row; if (result != -1) { // advance iterator ix->row = -1; for (int i = result + 1; i < dm_nrows (ix->m); i++) { if (dm_is_set (ix->m, i, ix->col)) { ix->row = i; break; } } } return result; }
int min_col_first (matrix_t *m, int cola, int colb) { int i, ca, cb; for (i = 0; i < dm_nrows (m); i++) { ca = dm_is_set (m, i, cola); cb = dm_is_set (m, i, colb); if ((ca && cb) || (!ca && !cb)) continue; return (ca - cb); } return 0; }
int dm_print (FILE * f, const matrix_t *m) { int i, j; fprintf(f, " "); for (j = 0; j < dm_ncols(m); j+=10) fprintf(f, "0 "); fprintf(f, "\n"); for (i = 0; i < dm_nrows (m); i++) { fprintf(f, "%4d: ", i); for (j = 0; j < dm_ncols (m); j++) { fprintf (f, "%c", (char)(dm_is_set (m, i, j) ? '+' : '-')); } fprintf (f, "\n"); } 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; }
// merge rowa and rowb, remove rowb from the matrix static int merge_rows_ (matrix_t *m, int rowa, int rowb) { int rows = dm_nrows (m); permutation_group_t o; int d[rows]; int j; // make sure rowb > rowa if (rowa == rowb) return -1; if (rowb < rowa) { // in this case, rowa will move 1 row up rowa--; } // create permutation dm_create_permutation_group (&o, rows, d); // create proper permutation group for (j = rowb; j < rows; j++) { dm_add_to_permutation_group (&o, j); } dm_permute_rows (m, &o); dm_free_permutation_group (&o); // merge the groups (last row in matrix is now rowb) merge_group_ (&(m->row_perm), m->row_perm.data[rows - 1].becomes, m->row_perm.data[rowa].becomes); // update matrix counts uncount_row_ (m, rows - 1); // remove the last row from the matrix m->rows--; return 0; }
int dm_subsume_rows (matrix_t *r, matrix_t *mayw, matrix_t *mustw, const dm_subsume_rows_fn fn, void *context) { HREassert( dm_ncols(r) == dm_ncols(mayw) && dm_nrows(r) == dm_nrows(mayw) && dm_ncols(r) == dm_ncols(mustw) && dm_nrows(r) == dm_nrows(mustw), "matrix sizes do not match"); int i, j; for (i = 0; i < dm_nrows (r); i++) { int row_i_removed = 0; for (j = i + 1; j < dm_nrows (r); j++) { // is row j subsumed by row i? if (fn (r, mayw, mustw, i, j, context)) { merge_rows_ (r, i, j); merge_rows_ (mayw, i, j); merge_rows_ (mustw, i, j); // now row j is removed, don't increment it in the for // loop j--; } else { // is row i subsumed by row j? if (fn (r, mayw, mustw, j, i, context)) { merge_rows_ (r, j, i); merge_rows_ (mayw, j, i); merge_rows_ (mustw, j, i); // now row i is removed, don't increment it in the for // loop row_i_removed=1; } } } if (row_i_removed) i--; } 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); }
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 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); }
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); }
int permute_trans (permute_t *perm, state_info_t *state, perm_cb_f cb, void *ctx) { perm->call_ctx = ctx; perm->real_cb = cb; perm->state = state; perm->nstored = perm->start_group_index = 0; int count = 0; state_data_t data = state_info_pins_state (state); if (inhibit) { int N = dm_nrows (perm->inhibit_matrix); int class_count[N]; for (int i = 0; i < N; i++) { class_count[i] = 0; if (is_inhibited(perm, class_count, i)) continue; if (perm->class_label >= 0) { class_count[i] = GBgetTransitionsMatching (perm->model, perm->class_label, i, data, permute_one, perm); } else if (perm->class_matrix != NULL) { class_count[i] = GBgetTransitionsMarked (perm->model, perm->class_matrix, i, data, permute_one, perm); } else { Abort ("inhibit set, but no known classification found."); } count += class_count[i]; } } else { count = GBgetTransitionsAll (perm->model, data, permute_one, perm); } switch (perm->permutation) { case Perm_Otf: randperm (perm->pad, perm->nstored, state->ref + perm->shiftorder); for (size_t i = 0; i < perm->nstored; i++) perm_do (perm, perm->pad[i]); break; case Perm_Random: for (size_t i = 0; i < perm->nstored; i++) perm_do (perm, perm->rand[perm->nstored][i]); break; case Perm_Dynamic: sort_r (perm->tosort, perm->nstored, sizeof(int), dyn_cmp, perm); perm_do_all (perm); break; case Perm_RR: sort_r (perm->tosort, perm->nstored, sizeof(int), rr_cmp, perm); perm_do_all (perm); break; case Perm_SR: sort_r (perm->tosort, perm->nstored, sizeof(int), rand_cmp, perm); perm_do_all (perm); break; case Perm_Sort: sort_r (perm->tosort, perm->nstored, sizeof(int), sort_cmp, perm); perm_do_all (perm); break; case Perm_Shift: perm_do_all (perm); break; case Perm_Shift_All: for (size_t i = 0; i < perm->nstored; i++) { size_t j = (perm->start_group_index + i); j = j < perm->nstored ? j : 0; perm_do (perm, j); } break; case Perm_None: break; default: Abort ("Unknown permutation!"); } return count; }