Пример #1
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);
}
Пример #2
0
void pins_model_init(model_t m) {

    // create the LTS type LTSmin will generate
    lts_type_t ltstype=lts_type_create();

    // set the length of the state
    lts_type_set_state_length(ltstype, state_length());

    // add an "int" type for a state slot
    int int_type = lts_type_add_type(ltstype, "int", NULL);
    lts_type_set_format (ltstype, int_type, LTStypeDirect);

    // add an "action" type for edge labels
    int action_type = lts_type_add_type(ltstype, "action", NULL);
    lts_type_set_format (ltstype, action_type, LTStypeEnum);

    // add a "bool" type for state labels
    int bool_type = lts_type_add_type (ltstype, LTSMIN_TYPE_BOOL, NULL);
    lts_type_set_format(ltstype, bool_type, LTStypeEnum);

    // set state name & type
    for (int i=0; i < state_length(); ++i) {
        char name[3]; sprintf(name, "%d", i);
        lts_type_set_state_name(ltstype,i,name);
        lts_type_set_state_typeno(ltstype,i,int_type);
    }

    // edge label types
    lts_type_set_edge_label_count (ltstype, 1);
    lts_type_set_edge_label_name(ltstype, 0, "action");
    lts_type_set_edge_label_type(ltstype, 0, "action");
    lts_type_set_edge_label_typeno(ltstype, 0, action_type);

    // state label types
    lts_type_set_state_label_count (ltstype, 1);
    lts_type_set_state_label_name (ltstype, 0, "goal");
    lts_type_set_state_label_typeno (ltstype, 0, bool_type);

    // done with ltstype
    lts_type_validate(ltstype);

    // make sure to set the lts-type before anything else in the GB
    GBsetLTStype(m, ltstype);

    // setting all values for all non direct types
    GBchunkPut(m, action_type, chunk_str("switch_a"));
    GBchunkPut(m, action_type, chunk_str("switch_b"));
    GBchunkPut(m, action_type, chunk_str("switch_c"));
    GBchunkPut(m, action_type, chunk_str("switch_d"));
    GBchunkPut(m, action_type, chunk_str("switch_ab"));
    GBchunkPut(m, action_type, chunk_str("switch_ac"));
    GBchunkPut(m, action_type, chunk_str("switch_ad"));
    GBchunkPut(m, action_type, chunk_str("switch_bc"));
    GBchunkPut(m, action_type, chunk_str("switch_bd"));
    GBchunkPut(m, action_type, chunk_str("switch_cd"));
    GBchunkPut(m, bool_type, chunk_str(LTSMIN_VALUE_BOOL_FALSE));
    GBchunkPut(m, bool_type, chunk_str(LTSMIN_VALUE_BOOL_TRUE));

    // set state variable values for initial state
    GBsetInitialState(m, initial_state());

    // set function pointer for the next-state function
    GBsetNextStateLong(m, (next_method_grey_t) next_state);

    // set function pointer for the label evaluation function
    GBsetStateLabelLong(m, (get_label_method_t) state_label);

    // create combined matrix
    matrix_t *cm = malloc(sizeof(matrix_t));
    dm_create(cm, group_count(), state_length());

    // set the read dependency matrix
    matrix_t *rm = malloc(sizeof(matrix_t));
    dm_create(rm, group_count(), state_length());
    for (int i = 0; i < group_count(); i++) {
        for (int j = 0; j < state_length(); j++) {
            if (read_matrix(i)[j]) {
                dm_set(cm, i, j);
                dm_set(rm, i, j);
            }
        }
    }
    GBsetDMInfoRead(m, rm);

    // set the write dependency matrix
    matrix_t *wm = malloc(sizeof(matrix_t));
    dm_create(wm, group_count(), state_length());
    for (int i = 0; i < group_count(); i++) {
        for (int j = 0; j < state_length(); j++) {
            if (write_matrix(i)[j]) {
                dm_set(cm, i, j);
                dm_set(wm, i, j);
            }
        }
    }
    GBsetDMInfoMustWrite(m, wm);

    // set the combined matrix
    GBsetDMInfo(m, cm);

    // set the label dependency matrix
    matrix_t *lm = malloc(sizeof(matrix_t));
    dm_create(lm, label_count(), state_length());
    for (int i = 0; i < label_count(); i++) {
        for (int j = 0; j < state_length(); j++) {
            if (label_matrix(i)[j]) dm_set(lm, i, j);
        }
    }
    GBsetStateLabelInfo(m, lm);

}
Пример #3
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);
}