Esempio n. 1
0
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());
}
Esempio n. 2
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 3
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 4
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 5
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 8
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 9
0
void
print_matrix (matrix_t *m)
{
    printf ("matrix(%d, %d)\n", dm_nrows (m), dm_ncols (m));
    dm_print (stdout, m);
    printf ("\n");
}
Esempio n. 10
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 11
0
File: dm.c Progetto: graydon/ltsmin
int
dm_ungroup_rows (matrix_t *m)
{
    int                 i;
    for (i = 0; i < dm_nrows (m); i++) {
        unmerge_row_ (m, i);
    }

    return 0;
}
Esempio n. 12
0
File: dm.c Progetto: graydon/ltsmin
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;

}
Esempio n. 13
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 14
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 15
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);
    }
}
Esempio n. 16
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 17
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;
}
Esempio n. 18
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 19
0
File: dm.c Progetto: graydon/ltsmin
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]++;
        }
    }
}
Esempio n. 20
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 21
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;
}
Esempio n. 22
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 23
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;
}
Esempio n. 24
0
File: dm.c Progetto: graydon/ltsmin
// 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;
}
Esempio n. 25
0
File: dm.c Progetto: graydon/ltsmin
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;
}
Esempio n. 26
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);
}
Esempio n. 27
0
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;
}
Esempio n. 28
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);
}
Esempio n. 29
0
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);
}
Esempio n. 30
0
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;
}