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 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_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; }
static void dv_do_collapsing_one_depth_r(dv_view_t * V, dm_dag_node_t * node, int depth) { if (!dm_is_set(node)) return; if (dm_is_union(node) && dm_is_inner_loaded(node) && !dm_is_shrinking(node) && (dm_is_expanded(node) || dm_is_expanding(node))) { // check if node has expanded node, excluding shrinking nodes int has_expanded_node = 0; /* Traverse all children */ dm_dag_node_t * x = NULL; while ( (x = dm_dag_node_traverse_children(node, x)) ) { if (dm_is_union(x) && dm_is_inner_loaded(x) && (dm_is_expanded(x) || dm_is_expanding(x)) && !dm_is_shrinking(x)) { has_expanded_node = 1; break; } } if (!has_expanded_node && node->d >= depth) { // collapsing node's parent dv_do_collapsing_one_1(V, node); } else { /* Call inward */ dv_do_collapsing_one_depth_r(V, node->head, depth); } } /* Call link-along */ dm_dag_node_t * x = NULL; while ( (x = dm_dag_node_traverse_nexts(node, x)) ) { dv_do_collapsing_one_depth_r(V, x, depth); } }
static void dv_do_expanding_one_r(dv_view_t * V, dm_dag_node_t * node) { V->S->ntr++; if (!dm_is_set(node)) dm_dag_node_set(V->D, node); if (dm_is_union(node)) { if ((!dm_is_inner_loaded(node) || dm_is_shrinked(node) || dm_is_shrinking(node)) && !dm_is_expanding(node)) { // expand node dv_do_expanding_one_1(V, node); } else { /* Call inward */ dv_check(node->head); dv_do_expanding_one_r(V, node->head); } } /* Call link-along */ dm_dag_node_t * x = NULL; while ( (x = dm_dag_node_traverse_nexts(node, x)) ) { dv_do_expanding_one_r(V, x); } }
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; }
static void dv_dag_expand_implicitly_r(dm_dag_t * D, dm_dag_node_t * node) { if (!dm_is_set(node)) dm_dag_node_set(D, node); if (dm_is_union(node)) { /* Build inner */ if ( !dm_is_inner_loaded(node) ) { if (dm_dag_build_node_inner(D, node) != DV_OK) { fprintf(stderr, "error in dm_dag_build_node_inner\n"); return; } } /* Call inward */ dv_check(node->head); dv_dag_expand_implicitly_r(D, node->head); } /* Call link-along */ dm_dag_node_t * next = NULL; while ( (next = dm_dag_node_traverse_nexts(node, next)) ) { dv_dag_expand_implicitly_r(D, next); } }
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 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 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; }
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; }
int dm_create_row_iterator (dm_row_iterator_t *ix, matrix_t *m, int row) { ix->m = m; ix->row = row; ix->col = 0; if (!dm_is_set (m, row, 0)) dm_row_next (ix); return 0; }
int dm_create_col_iterator (dm_col_iterator_t *ix, matrix_t *m, int col) { ix->m = m; ix->row = 0; ix->col = col; if (!dm_is_set (m, 0, col)) dm_col_next (ix); return 0; }
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 est_first(matrix_t *m,int row, int i, int j, int first) { // what would first be if column i is rotated to position j if (first==-1) return -1; // still no first if (i<first) { if (j<first) return first; // permutation happens left of first else return first-1; // first is in segment rotated to the left } if (i>first) { if (j<=first) { if (dm_is_set (m, row, i)) return j; // set position i is moved left of first else return first+1; // first is in segment rotated to the right } else return first; // permutation happens right of first } // i==first if (j<first) return j; // first is moved to the left to position j for (int k=i+1;k<=j;k++) if (dm_is_set(m,row,k)) return k-1; // first is moved to the right, k is the new first, but moves one left return j; // first is moved to the right to pos j, no k found, so j is new first }
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; }
int est_last(matrix_t *m,int row, int i, int j, int last) { // what would first be if column i is rotated to position j if (last==-1) return -1; // still no last if (i>last) { if (j>last) return last; // permutation happens right of last else return last+1; // last is in segment rotated to the right } if (i<last) { if (j>=last) { if (dm_is_set (m, row, i)) return j; // set position i is moved right of last else return last-1; // last is in segment rotated to the left } else return last; // permutation happens left of last } // i==last if (j>last) return j; // last is moved to the right to position j for (int k=i-1;k>=j;k--) { if (dm_is_set(m,row,k)) return k+1; // last is moved to the left, k is the new last, but moves one right } return j; // last is moved to the left to pos j, no k found, so j is new last }
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; }
static void uncount_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_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 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; }
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_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; }
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]++; } } }
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 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; }
static void dv_view_scan_r(dv_view_t * V, dm_dag_node_t * node) { dm_dag_t * D = V->D; if (!dm_is_set(node)) dm_dag_node_set(D, node); if (dm_is_union(node)) { /* Build inner */ int is_inner_loaded = dm_is_inner_loaded(node); if (!is_inner_loaded) { if (dm_dag_build_node_inner(D, node) != DV_OK) { fprintf(stderr, "error in dm_dag_build_node_inner\n"); return; } } /* Call inward */ dv_check(node->head); dv_view_scan_r(V, node->head); /* Process single */ node->r = node->head->link_r; /* Collapse inner */ if (!is_inner_loaded && !V->S->remain_inner) { dm_dag_collapse_node_inner(D, node); } } else { node->r = 0; int v = dm_dag_node_lookup_value(D, node, V->S->nc); int i; for (i=0; i<((dv_dag_t*)V->D->g)->nr; i++) if (((dv_dag_t*)V->D->g)->ar[i] == v) break; if (i < ((dv_dag_t*)V->D->g)->nr) dv_set_bit(&node->r, i); } /* Call link-along */ node->link_r = node->r; dm_dag_node_t * x = NULL; while ( (x = dm_dag_node_traverse_nexts(node, x)) ) { dv_view_scan_r(V, x); node->link_r |= x->link_r; } }
static void dv_dag_build_inner_all_r(dm_dag_t * D, dm_dag_node_t * node) { if (!dm_is_set(node)) dm_dag_node_set(D, node); if (dm_is_union(node)) { if (!dm_is_inner_loaded(node)) { dm_dag_build_node_inner(D, node); } /* Call inward */ dv_check(node->head); dv_dag_build_inner_all_r(D, node->head); } /* Call link-along */ dm_dag_node_t * x = NULL; while ( (x = dm_dag_node_traverse_nexts(node, x)) ) { dv_dag_build_inner_all_r(D, x); } }
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; }