Beispiel #1
0
static int
type_max (check_ctx_t *ctx, int idx)
{
    model_t         model = ctx->parent;
    lts_type_t      ltstype = GBgetLTStype (model);
    int             typeno = lts_type_get_state_typeno (ltstype, idx);
    int              c;
    switch (lts_type_get_format (ltstype, typeno))
    {
        case LTStypeDirect:
            GBgetInitialState (model, ctx->src2);
            c = ctx->src2[idx];
            return c == 0 ? 1 : c;
        case LTStypeRange:
            return lts_type_get_min (ltstype, typeno);
        case LTStypeEnum:
            c = pins_chunk_count (model, typeno);
            HREassert (c > 0, "Empty enum table for slot: %d -- %s", idx, str_slot(ctx, NULL, idx));
            return c;
        case LTStypeChunk:
            c = pins_chunk_count (model, typeno);
            return c == 0 ? 1 : c;
        case LTStypeBool:
            return 1;
        case LTStypeTrilean:
            return 2;
        case LTStypeSInt32:
            return (1ULL<<31) - 1;
        default: {
                HREassert(false);
                return -1;
        }
    }
}
Beispiel #2
0
static void
ltsmin_expr_lookup_value(ltsmin_expr_t top, ltsmin_expr_t e, int typeno,
                         ltsmin_parse_env_t env, model_t model)
{
    switch(e->node_type) {
    case VAR:
    case CHUNK:
    case INT:
        break;
    default:
        return;
    }
    chunk c;
    data_format_t format = lts_type_get_format(GBgetLTStype(model), typeno);
    switch (format) {
    case LTStypeDirect:
    case LTStypeRange:
        if (INT != e->node_type)
            Abort ("Expected an integer value for comparison: %s", LTSminPrintExpr(top, env));
        break;
    case LTStypeEnum:
    case LTStypeChunk:
        c.data = env->buffer;
        c.len = LTSminSPrintExpr(c.data, e, env);
        HREassert (c.len < ENV_BUFFER_SIZE, "Buffer overflow in print expression");
        lookup_type_value (e, typeno, c, model, format==LTStypeEnum);
        Debug ("Bound '%s' to %d in table for type '%s'", c.data,
               e->num, lts_type_get_state_type(GBgetLTStype(model),typeno));
        break;
    }
}
Beispiel #3
0
static const char* data_format_string(lts_type_t  t,int typeno){
    int f=lts_type_get_format(t,typeno);
    switch(f){
    case LTStypeDirect: return "direct";
    case LTStypeRange: {
        char tmp[256];
        sprintf(tmp,"[%d,%d]",lts_type_get_min(t,typeno),lts_type_get_max(t,typeno));
        return strdup(tmp);
    }
    case LTStypeChunk: return "chunk";
    case LTStypeEnum: return "enum";
    }
    Abort("illegal format value: %d",f);
}
Beispiel #4
0
int
print_chunk (model_t model, char *res, int max, int typeno, int val)
{
    chunk           c;
    switch (lts_type_get_format (GBgetLTStype(model), typeno))
    {
        case LTStypeDirect:
        case LTStypeRange:
            return snprintf (res, max, "%d", val);
        case LTStypeEnum:
        case LTStypeChunk:
            c = pins_chunk_get (model, typeno, val);
            return snprintf (res, max, "%s", c.data);
        default: {
            HREassert(false);
            return -1;
        }
    }
}
Beispiel #5
0
static int
type_min (check_ctx_t *ctx, int idx)
{
    model_t         model = ctx->parent;
    lts_type_t      ltstype = GBgetLTStype (model);
    int             typeno = lts_type_get_state_typeno (ltstype, idx);
    switch (lts_type_get_format (ltstype, typeno))
    {
        case LTStypeRange:
            return lts_type_get_min (ltstype, typeno);
        case LTStypeDirect:
        case LTStypeEnum:
        case LTStypeChunk:
        case LTStypeBool:
        case LTStypeTrilean:
        case LTStypeSInt32:
            return 0;
        default: {
            HREassert(false);
            return -1;
        }
    }
}
Beispiel #6
0
static void lts_write_dir(archive_t archive,string_map_t map,lts_t lts,int segments){
    if (map) arch_set_write_policy(archive,map);
    dir_info_t info=DIRinfoCreate(segments);
    int i,j;
    uint32_t k;
    char filename[1024];
    stream_t output;
    stream_t *src_out;
    stream_t *lbl_out;
    stream_t *dst_out;

    if (lts->root_count !=1) Abort("LTS has %u initial states DIR requires 1",lts->root_count);
    lts_set_type(lts,LTS_BLOCK);
    info->label_tau=lts->tau;
    int type_no=lts_type_get_edge_label_typeno(lts->ltstype,0);
    switch(lts_type_get_format(lts->ltstype,type_no)){
        case LTStypeChunk:
        case LTStypeEnum:
            break;
        default:
            Abort("DIR is limited to Chunk/Enum edge labels.");
    }
    info->label_count=VTgetCount(lts->values[type_no]);
    info->initial_seg=lts->root_list[0]%segments;
    info->initial_ofs=lts->root_list[0]/segments;
    output=arch_write(archive,"TermDB");
    int last_idx = 0;
    table_iterator_t it = VTiterator (lts->values[type_no]);
    while (IThasNext(it)) {
        chunk label_c = ITnext (it);
        int idx = VTputChunk (lts->values[type_no], label_c);
        while (last_idx < idx) { // fill non-dense indices
            write_chunk (output, (chunk){0, ""});
            last_idx++;
        }
        write_chunk (output, label_c);
    }
    DSclose(&output);
    src_out=(stream_t*)RTmalloc(segments*sizeof(stream_t));
    lbl_out=(stream_t*)RTmalloc(segments*sizeof(stream_t));
    dst_out=(stream_t*)RTmalloc(segments*sizeof(stream_t));
    for(i=0;i<segments;i++) {
        for(j=0;j<segments;j++) {
            sprintf(filename,"src-%d-%d",i,j);
            src_out[j]=arch_write(archive,filename);
            sprintf(filename,"label-%d-%d",i,j);
            lbl_out[j]=arch_write(archive,filename);
            sprintf(filename,"dest-%d-%d",i,j);
            dst_out[j]=arch_write(archive,filename);
        }
        for(j=i;j<(int)lts->states;j+=segments){
            for(k=lts->begin[j];k<lts->begin[j+1];k++){
                int dseg=(lts->dest[k])%segments;
                info->transition_count[i][dseg]++;
                DSwriteU32(src_out[dseg],info->state_count[i]);
                DSwriteU32(lbl_out[dseg],lts->label[k]);
                DSwriteU32(dst_out[dseg],(lts->dest[k])/segments);
            }
            info->state_count[i]++;
        }
        for(j=0;j<segments;j++) {
            DSclose(&src_out[j]);
            DSclose(&lbl_out[j]);
            DSclose(&dst_out[j]);
        }
    }
    info->info="bsim2 output";
    output=arch_write(archive,"info");
    DIRinfoWrite(output,info);
    DSclose(&output);
    info->info=NULL;
    DIRinfoDestroy(info);
}
Beispiel #7
0
int main(int argc, char *argv[]){
    char* files[2];
    HREinitBegin(argv[0]);
    HREaddOptions(options,"Tool for transforming labeled transition systems\n\nOptions");
    lts_lib_setup();
    HREinitStart(&argc,&argv,1,2,files,"<input> [<output>]");
    int me=HREme(HREglobal());
    int peers=HREpeers(HREglobal());
    if (peers>1) Abort("parallelizing this tool is future work");(void)me;
    string_set_t label_set=NULL;
    if (label_filter!=NULL){
        label_set=SSMcreateSWPset(label_filter);
    }
    switch(task){
        case Undefined:
            Abort("task unspecified");
        case LTScopy:
            if (files[1]==NULL) Abort("second argument required for copy.");
            Print(infoShort,"streaming copy from %s to %s",files[0],files[1]);
            lts_file_t in=lts_file_open(files[0]);
            lts_type_t ltstype=lts_file_get_type(in);
            rd_seg=lts_file_get_segments(in);
            if (wr_seg==0) {
                wr_seg=rd_seg;
            } else {
                Abort("on-the-fly changing the number of segments is future work");
            }
            lts_file_t out;
            if (label_set==NULL){
                out=lts_file_create(files[1],ltstype,wr_seg,in);
            } else {
                out=lts_file_create_filter(files[1],ltstype,label_set,wr_seg,in);
            }
            int N=lts_type_get_type_count(ltstype);
            for(int i=0;i<N;i++){
                char*name=lts_type_get_type(ltstype,i);
                switch(lts_type_get_format(ltstype,i)){
                case LTStypeDirect:
                case LTStypeRange:
                    Debug("integer type %s does not use tables",name);
                    break;
                case LTStypeChunk:
                case LTStypeEnum:
                    Debug("creating table for type %s",name);
                    value_table_t tmp=chunk_table_create(NULL,name);
                    Debug("set in %s",name);
                    lts_file_set_table(in,i,tmp);
                    Debug("set out %s",name);
                    lts_file_set_table(out,i,tmp);
                    break;
                }
            }
            lts_file_copy(in,out);
            lts_file_close(out);
            lts_file_close(in);
            break;
        case LTSrdwr:
            if (files[1]==NULL) Abort("second argument required for rdwr.");
            Print(infoShort,"loading from %s",files[0]);
            lts_t lts=lts_create();
            lts_read(files[0],lts);
            if (encode) {
                Print(infoShort,"single edge label encoding");
                lts=lts_encode_edge(lts);
            }
            if (bfs_reorder) {
                Print(infoShort,"reindexing LTS in BFS order");
                lts_bfs_reorder(lts);
            }
            Print(infoShort,"storing in %s",files[1]);
            if(wr_seg==0) wr_seg=1;
            lts_write(files[1],lts,label_set,wr_seg);
            break;
        case LTSindex:{
            if (peers>1) Abort("parallelizing this tool is future work");
            if (files[1]==NULL) Abort("second argument required for index.");
            Print(infoShort,"opening %s",files[0]);
            lts_file_t in=lts_file_open(files[0]);
            lts_type_t ltstype=lts_file_get_type(in);
            int segments=lts_file_get_segments(in);
            lts_file_t settings=lts_get_template(in);
            if (lts_file_get_edge_owner(settings)!=SourceOwned) Abort("bad edge owner");
            lts_file_set_dest_mode(settings,Index);
            lts_file_set_init_mode(settings,Index);
            Print(infoShort,"creating %s",files[1]);
            lts_file_t out=lts_file_create(files[1],ltstype,segments,settings);
            int N=lts_type_get_type_count(ltstype);
            for(int i=0;i<N;i++){
                char*name=lts_type_get_type(ltstype,i);
                switch(lts_type_get_format(ltstype,i)){
                case LTStypeDirect:
                case LTStypeRange:
                    Debug("integer type %s does not use tables",name);
                    break;
                case LTStypeChunk:
                case LTStypeEnum:
                    Debug("creating table for type %s",name);
                    value_table_t tmp=chunk_table_create(NULL,name);
                    Debug("set in %s",name);
                    lts_file_set_table(in,i,tmp);
                    Debug("set out %s",name);
                    lts_file_set_table(out,i,tmp);
                    break;
                }
            }
            treedbs_t db[segments];
            int SV=lts_type_get_state_length(ltstype);
            int SL=lts_type_get_state_label_count(ltstype);
            int K=lts_type_get_edge_label_count(ltstype);
            for(int i=0;i<segments;i++){
                Print(info,"loading and copying states of segment %d",i);
                uint32_t state[SV];
                uint32_t label[SL];
                db[i]=TreeDBScreate(SV);
                int idx=0;
                while(lts_read_state(in,&i,state,label)){
                    int tmp=TreeFold(db[i],(int*)state);
                    if (idx!=tmp){
                        Abort("unexpected index %u != %u",tmp,idx);
                    }
                    idx++;
                    lts_write_state(out,i,(int*)state,label);
                }
            }
            Print(info,"converting initial states");
            {
                uint32_t seg;
                uint32_t state[SV];
                while(lts_read_init(in,(int*)&seg,state)){
                    int idx=TreeFold(db[seg],(int*)state);
                    lts_write_init(out,seg,&idx);
                }
            }
            for(int i=0;i<segments;i++){
                Print(info,"converting edges of segment %d",i);
                uint32_t src_state[1];
                uint32_t dst_seg;
                uint32_t dst_state[SV];
                uint32_t label[K];
                while(lts_read_edge(in,&i,src_state,(int*)&dst_seg,dst_state,label)){
                    int idx=TreeFold(db[dst_seg],(int*)dst_state);
                    lts_write_edge(out,i,src_state,dst_seg,&idx,label);
                }
            }
            lts_file_close(out);
            lts_file_close(in);
        }
    }
    Print(infoShort,"done");
    HREexit(LTSMIN_EXIT_SUCCESS);
}
Beispiel #8
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);
}