Exemplo n.º 1
0
void pins_model_init(model_t model)
{
    lts_type_t ltstype;
    matrix_t *dm_info = malloc(sizeof(matrix_t));
    matrix_t *dm_read_info = malloc(sizeof(matrix_t));
    matrix_t *dm_must_write_info = malloc(sizeof(matrix_t));

    // get ltstypes
    ltstype=lts_type_create();
    const int state_length = pnml_vars;

    // adding types
    int ntypes = 2;
    int int_type = lts_type_add_type(ltstype, "int", NULL);
    int act_type =lts_type_add_type(ltstype, "action", NULL);

    lts_type_set_format (ltstype, int_type, LTStypeDirect);
    lts_type_set_format (ltstype, act_type, LTStypeEnum);

    lts_type_set_state_length(ltstype, state_length);

    // set state name & type
    for (int i=0; i < state_length; ++i) {
        lts_type_set_state_name(ltstype,i,pnml_var_names[i]);
        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, act_type);

    int bool_is_new, bool_type = lts_type_add_type(ltstype, LTSMIN_TYPE_BOOL, NULL);

    GBsetLTStype(model, ltstype); // must set ltstype before setting initial state
                                  // creates tables for types!

    if (bool_is_new) {
        GBchunkPutAt(model, bool_type, chunk_str(LTSMIN_VALUE_BOOL_FALSE), 0);
        GBchunkPutAt(model, bool_type, chunk_str(LTSMIN_VALUE_BOOL_TRUE ), 1);
    }

    // setting values for types
    for (int i = 0; i < pnml_groups; i++) {
        GBchunkPutAt(model, act_type, chunk_str((char*) pnml_group_names[i]), i);
    }

    // get initial state
    GBsetInitialState(model,pnml_initial_state);

    for (int i = 0; i < pnml_vars; i++) {
        if (max_token_count < pnml_initial_state[i]) {
            max_token_count = pnml_initial_state[i];
        }
    }

    // get next state
    GBsetNextStateLong(model, (next_method_grey_t) pnml_get_successor);

    lts_type_validate(ltstype); // done with ltstype

    // initialize the state read/write dependency matrices
    dm_create(dm_read_info, pnml_groups, state_length);
    dm_create(dm_must_write_info, pnml_groups, state_length);

    for (int i = 0; i < pnml_groups; i++) {
        for (int j = 0; j < pnml_sources[i][0]; j++) {
            dm_set(dm_read_info, i, pnml_sources[i][j*2+1]);
            dm_set(dm_must_write_info, i, pnml_sources[i][j*2+1]);
        }
        for (int j = 0; j < pnml_targets[i][0]; j++) {
            if (!pnml_safe_places[pnml_targets[i][j*2+1]]) {
                /* If the place is safe we don't need to mark it read-dependent. */
                dm_set(dm_read_info, i, pnml_targets[i][j*2+1]);
            }
            dm_set(dm_must_write_info, i, pnml_targets[i][j*2+1]);
        }
    }
    dm_copy(dm_read_info, dm_info);
    dm_apply_or(dm_info, dm_must_write_info);

    GBsetDMInfo(model, dm_info);
    GBsetDMInfoRead(model, dm_read_info);
    GBsetDMInfoMustWrite(model, dm_must_write_info);
    GBsetSupportsCopy(model);

    GBsetExit(model, pnml_exit);

    matrix_t *dna_info = malloc(sizeof(matrix_t));
    dm_create(dna_info, pnml_groups, pnml_groups);
    for (int i = 0; i < pnml_groups; i++) {
        for(int j = 0; j < pnml_groups; j++) {
            const int guards_i = pnml_sources[i][0];
            const int guards_j = pnml_sources[j][0];
            for (int g = 0; g < guards_i; g++) {
                const int guard_i = pnml_sources[i][g * 2 + 1];
                for (int h = 0; h < guards_j; h++) {
                    const int guard_j = pnml_sources[j][h * 2 + 1];
                    if (guard_i == guard_j) {
                        dm_set(dna_info, i, j);
                        goto next_dna;
                    }
                }
            }
            next_dna:;
        }
    }
    GBsetDoNotAccordInfo(model, dna_info);

    matrix_t *gnes_info = malloc(sizeof(matrix_t));
    dm_create(gnes_info, pnml_vars, pnml_groups);
    for(int i = 0; i < pnml_groups; i++) {
        const int targets = pnml_targets[i][0];
        for (int t = 0; t < targets; t++) {
            const int target = pnml_targets[i][t * 2 + 1];
            dm_set(gnes_info, target, i);
        }
    }
    GBsetGuardNESInfo(model, gnes_info);

    matrix_t *gnds_info = malloc(sizeof(matrix_t));
    dm_create(gnds_info, pnml_vars, pnml_groups);
    for(int i = 0; i < pnml_groups; i++) {
        const int sources = pnml_sources[i][0];
        for (int s = 0; s < sources; s++) {
            const int source = pnml_sources[i][s * 2 + 1];
            dm_set(gnds_info, source, i);
        }
    }
    GBsetGuardNDSInfo(model, gnds_info);

    matrix_t *ndb_info = malloc(sizeof(matrix_t));
    dm_create(ndb_info, pnml_groups, pnml_groups);
    for (int i = 0; i < pnml_groups; i++) {
        const int sources = pnml_sources[i][0];
        for (int j = 0; j < pnml_groups; j++) {
            const int targets = pnml_targets[j][0];
            for (int s = 0; s < sources; s++) {
                const int source = pnml_sources[i][s * 2 + 1];
                for (int t = 0; t < targets; t++) {
                    const int target = pnml_targets[j][t * 2 + 1];
                    if (source == target) {
                        dm_set(ndb_info, i, j);
                        goto next_ndb;
                    }
                }
            }
            next_ndb:;
        }
    }
    GBsetMatrix(model, LTSMIN_NOT_LEFT_ACCORDS, ndb_info, PINS_STRICT, PINS_INDEX_OTHER, PINS_INDEX_OTHER);
}
Exemplo n.º 2
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);
}