Example #1
0
static void
output_types(FILE *tbl_file)
{
    int type_count = lts_type_get_type_count(ltstype);

    for (int i = 0; i < type_count; i++) {
        Warning(info, "dumping type %s", lts_type_get_type(ltstype, i));
        fprintf(tbl_file, "begin sort ");
        fprint_ltsmin_ident(tbl_file, lts_type_get_type(ltstype, i));
        fprintf(tbl_file, "\n");

        int values = pins_chunk_count (model,i);

        for (int j = 0; j < values; j++) {
            chunk c    = pins_chunk_get (model, i, j);
            size_t len = c.len * 2 + 6;
            char str[len];

            chunk2string(c, len, str);
            fprintf(tbl_file, "%s\n", str);
        }

        fprintf(tbl_file,"end sort\n");
    }
}
Example #2
0
void lts_type_serialize(lts_type_t t,stream_t ds){
	DSwriteS(ds,"lts signature 1.1");
	uint32_t N=lts_type_get_state_length(t);
	Warning(debug,"state length is %d",N);
	DSwriteU32(ds,N);
	for(uint32_t i=0;i<N;i++){
		char*x=lts_type_get_state_name(t,i);
		if (x) DSwriteS(ds,x); else DSwriteS(ds,"");
		DSwriteU32(ds,lts_type_get_state_typeno(t,i));
	}
	N=lts_type_get_state_label_count(t);
	Warning(debug,"%d state labels",N);
	DSwriteU32(ds,N);
	for(uint32_t i=0;i<N;i++){
		char*x=lts_type_get_state_label_name(t,i);
		if (x) DSwriteS(ds,x); else DSwriteS(ds,"");
		DSwriteU32(ds,lts_type_get_state_label_typeno(t,i));
	}
	N=lts_type_get_edge_label_count(t);
	Warning(debug,"%d edge labels",N);
	DSwriteU32(ds,N);
	for(uint32_t i=0;i<N;i++){
		char*x=lts_type_get_edge_label_name(t,i);
		if (x) DSwriteS(ds,x); else DSwriteS(ds,"");
		DSwriteU32(ds,lts_type_get_edge_label_typeno(t,i));
		Warning(debug,"edge label %d is %s : %s",i,x,lts_type_get_edge_label_type(t,i));
	}
	N=lts_type_get_type_count(t);
	Warning(debug,"%d types",N);
	DSwriteU32(ds,N);
	for(uint32_t i=0;i<N;i++){
		DSwriteS(ds,lts_type_get_type(t,i));
		DSwriteS(ds,(char*)data_format_string(t,i));
	}
}
Example #3
0
/**
 * Enums need their values to be present in the tables, hence the strict lookup.
 */
static void
lookup_type_value (ltsmin_expr_t e, int type, const chunk c,
                   model_t m, bool strict)
{
    HREassert (NULL != c.data, "Empty chunk");
    int count = GBchunkCount(m,type);
    e->num = GBchunkPut(m,type,c);
    if (strict && count != GBchunkCount(m,type)) // value was added
        Warning (info, "Value for identifier '%s' cannot be found in table for enum type '%s'.",
                 c.data, lts_type_get_type(GBgetLTStype(m),type));
    e->lts_type = type;
}
Example #4
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);
}
Example #5
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);
}
Example #6
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);
}