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; }
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 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_row(bitvector_t *bv, const matrix_t *m, int row) { // check size if (bitvector_size (bv) != (size_t)dm_ncols (m)) return -1; // copy row for (int i = 0; i < dm_ncols (m); i++) { if (dm_is_set (m, row, i)) { 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_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 dm_ungroup_cols (matrix_t *m) { int i; for (i = 0; i < dm_ncols (m); i++) { unmerge_col_ (m, i); } return 0; }
static int last_ (matrix_t *m, int row) { int i; for (i = dm_ncols (m) - 1; i >= 0; i--) { if (dm_is_set (m, row, i)) return i; } return -1; }
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; }
static int first_ (matrix_t *m, int row) { int i; for (i = 0; i < dm_ncols (m); i++) { if (dm_is_set (m, row, i)) return i; } return -1; }
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 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; }
int dm_project_vector (matrix_t *m, int row, int *src, int *tgt) { int k = 0; // iterate over matrix, copy src to tgt when matrix is set for (int i = 0; i < dm_ncols (m); i++) { if (dm_is_set (m, row, i)) { tgt[k++] = src[i]; } } // return lenght of tgt return k; }
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_rows (matrix_t *r, matrix_t *mayw, matrix_t *mustw, const dm_nub_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++) { for (j = i + 1; j < dm_nrows (r); j++) { 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--; } } } return 0; }
static void count_row_ (matrix_t *m, int row) { // get permutation int rowp = m->row_perm.data[row].becomes; int i; for (i = 0; i < dm_ncols (m); i++) { if (dm_is_set (m, row, i)) { int colp = m->col_perm.data[i].becomes; m->row_perm.count[rowp]++; m->col_perm.count[colp]++; } } }
int dm_expand_vector (matrix_t *m, int row, int *s0, int *src, int *tgt) { int k = 0; for (int i = 0; i < dm_ncols (m); i++) { if (dm_is_set (m, row, i)) { // copy from source tgt[i] = src[k++]; } else { // copy initial state tgt[i] = s0[i]; } } // return number of copied items from src return k; }
int dm_row_next (dm_row_iterator_t *ix) { int result = ix->col; if (result != -1) { // advance iterator ix->col = -1; for (int i = result + 1; i < dm_ncols (ix->m); i++) { if (dm_is_set (ix->m, ix->row, i)) { ix->col = i; break; } } } return result; }
void mark_predicate (model_t m, ltsmin_expr_t e, int *dep, ltsmin_parse_env_t env) { if (!e) return; switch(e->node_type) { case BINARY_OP: mark_predicate(m,e->arg1,dep,env); mark_predicate(m,e->arg2,dep,env); break; case UNARY_OP: mark_predicate(m,e->arg1,dep,env); break; default: switch(e->token) { case PRED_TRUE: case PRED_FALSE: case PRED_NUM: case PRED_VAR: case PRED_CHUNK: break; case PRED_EQ: mark_predicate(m,e->arg1, dep,env); mark_predicate(m,e->arg2, dep,env); break; case PRED_SVAR: { lts_type_t ltstype = GBgetLTStype(m); int N = lts_type_get_state_length (ltstype); if (e->idx < N) { // state variable dep[e->idx] = 1; } else { // state label HREassert (e->idx < N + lts_type_get_state_label_count(ltstype)); matrix_t *sl = GBgetStateLabelInfo (m); HREassert (N == dm_ncols(sl)); for (int i = 0; i < N; i++) { if (dm_is_set(sl, e->idx - N, i)) dep[i] = 1; } } break; } default: LTSminLogExpr (error, "Unhandled predicate expression: ", e, env); HREabort (LTSMIN_EXIT_FAILURE); } break; } }
int min_row_first (matrix_t *m, int rowa, int rowb) { int i, ra, rb; for (i = 0; i < dm_ncols (m); i++) { ra = dm_is_set (m, rowa, i); rb = dm_is_set (m, rowb, i); if ((ra && rb) || (!ra && !rb)) continue; return (ra - rb); } return 0; }
int eq_rows(matrix_t *r, matrix_t *mayw, matrix_t *mustw, int rowa, int rowb, void *context) { if ( dm_ones_in_row (r, rowa) != dm_ones_in_row (r, rowb) || dm_ones_in_row (mayw, rowa) != dm_ones_in_row (mayw, rowb) || dm_ones_in_row (mustw, rowa) != dm_ones_in_row (mustw, rowb)) return 0; int i; for (i = 0; i < dm_ncols (r); i++) { int ar = dm_is_set (r, rowa, i); int br = dm_is_set (r, rowb, i); int amayw = dm_is_set (mayw, rowa, i); int bmayw = dm_is_set (mayw, rowb, i); int amustw = dm_is_set (mustw, rowa, i); int bmustw = dm_is_set (mustw, rowb, i); if (ar != br || amayw != bmayw || amustw != bmustw) return 0; // unequal } return 1; // equal (void)context; }
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; }
int state_mapping (matrix_t *m) { // optimized matrix row -> original matrix rows.. int i, sepi; printf ("["); for (i = 0, sepi = 0; i < dm_ncols (m); i++) { if (sepi) printf (","); sepi = 1; printf ("(%d,[", i); // TODO unify with transition mapping printf ("%d", m->col_perm.data[i].becomes); printf ("])"); } printf ("]\n"); return 1; }
// merge cola and colb, remove colb from the matrix static int merge_cols_ (matrix_t *m, int cola, int colb) { int cols = dm_ncols (m); permutation_group_t o; int d[cols]; int j; // make sure colb > cola if (cola == colb) return -1; if (colb < cola) { // in this case, cola will move 1 col up cola--; } // create permutation dm_create_permutation_group (&o, cols, d); // create proper permutation group for (j = colb; j < cols; j++) { dm_add_to_permutation_group (&o, j); } dm_permute_cols (m, &o); dm_free_permutation_group (&o); // merge the groups (last col in matrix is now colb) merge_group_ (&(m->col_perm), m->col_perm.data[cols - 1].becomes, m->col_perm.data[cola].becomes); // update matrix counts uncount_col_ (m, cols - 1); // remove the last col from the matrix m->cols--; return 0; }
int max_row_first (matrix_t *r, matrix_t *w, int rowa, int rowb) { int i, ra, wa, rb, wb; for (i = 0; i < dm_ncols (r); i++) { ra = dm_is_set (r, rowa, i); wa = dm_is_set (w, rowa, i); rb = dm_is_set (r, rowb, i); wb = dm_is_set (w, rowb, i); if ((ra && wa && rb && wb) || (!ra && !wa && !rb && !wb)) continue; return (rb + wb - ra - wa); } 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; }