Esempio n. 1
0
static int lump_hashcode(lts_t lts,int *map,int i){
    long j;
    uint32_t temp[2];
    uint32_t contrib[3];
    int last=lts->begin[i+1]-1;
    int hc=map[i];
    //int sigptr=0, *sig=alloca(2*(last-lts->begin[i]));
    //Warning(1,"signature for %d %x %x",i,sig,map);
    for(j=lts->begin[i];j<=last;j++){
        int block=map[lts->dest[j]];
        contrib[2]=block;
        TreeUnfold(lts->edge_idx,lts->label[j],(int*)contrib);
        //Warning(1,"collecting");
        while(j<last && block==map[lts->dest[j+1]]){
            j++;
            TreeUnfold(lts->edge_idx,lts->label[j],(int*)temp);
            uint64_t teller=((uint64_t)contrib[0])*((uint64_t)temp[1]);
                    teller+=((uint64_t)temp[0])*((uint64_t)contrib[1]);
            uint64_t noemer=((uint64_t)contrib[1])*((uint64_t)temp[1]);
            uint64_t gcd=gcd64(teller,noemer);
            contrib[0]=teller/gcd;
            contrib[1]=noemer/gcd;
        }
        hc=SuperFastHash(contrib,12,hc);
    }
    return hc;
}
Esempio n. 2
0
static void lts_merge_hyperedges(lts_t lts){
    if (lts->transitions==0) return;
    lts_set_type(lts,LTS_LIST);
    int group_pos=lts_type_find_edge_label(lts->ltstype,"group");
    int param_pos=lts_type_find_edge_label(lts->ltstype,"numerator");
    uint32_t e=1;
    uint32_t t=0;
    uint32_t label[6];
    TreeUnfold(lts->edge_idx,lts->label[0],(int*)label);
    for(uint32_t i=1;i<lts->transitions;i++){
        uint32_t next[6];
        TreeUnfold(lts->edge_idx,lts->label[i],(int*)next);
        int k=0;
        if (lts->src[t]==lts->src[i]){
            for(;k<=group_pos;k++){
                if (label[k]!=next[k]) break;
            }
        }
        if (k<=group_pos){
            e++;
        }
        if (lts->dest[t]!=lts->dest[i]){
            k=0;
        }
        if (k==group_pos && label[param_pos]==1 && label[param_pos+1]==1 && next[param_pos]==1 && next[param_pos+1]==1){
            // identical non-hyperedge: skip;
            e--;
        } else if (k<=group_pos) {
            // difference: ship out.
            lts->label[t]=TreeFold(lts->edge_idx,(int*)label);
            t++;
            lts->src[t]=lts->src[i];
            lts->dest[t]=lts->dest[i];
            TreeUnfold(lts->edge_idx,lts->label[i],(int*)label);
        } else {
            // same: add;
            fprintf(stderr,"merge %u/%u + %u/%u = ",label[param_pos],label[param_pos+1],next[param_pos],next[param_pos+1]);
            uint64_t teller=((uint64_t)label[param_pos])*((uint64_t)next[param_pos+1]);
                    teller+=((uint64_t)next[param_pos])*((uint64_t)label[param_pos+1]);
            uint64_t noemer=((uint64_t)next[param_pos+1])*((uint64_t)label[param_pos+1]);
            uint64_t gcd=gcd64(teller,noemer);
            label[param_pos]=teller/gcd;
            label[param_pos+1]=noemer/gcd;
            fprintf(stderr,"%u/%u\n",label[param_pos],label[param_pos+1]);
        }
    }
    lts->label[t]=TreeFold(lts->edge_idx,(int*)label);
    t++;
    fprintf(stderr,"result has %u real edges\n",e);
    lts_set_size(lts,lts->root_count,lts->states,t);
}
Esempio n. 3
0
static int same_lump_sig(lts_t lts,uint32_t* map,uint32_t s1,uint32_t s2){
    uint32_t t1,t2,m1,m2,t,block,rate1[2],rate2[2],temp[2];
    if (map[s1]!=map[s2]) {
        //Warning(1,"source maps different");
        return 0;
    }

    t1=lts->begin[s1];
    t2=lts->begin[s2];
    m1=lts->begin[s1+1];
    m2=lts->begin[s2+1];
    for(;;){
        if(t1==m1 && t2==m2) return 1;
        if(t1==m1 || t2==m2) {
            //Warning(1,"different lengths");
            return 0;
        }
        block=map[lts->dest[t1]];
        if(block!=map[lts->dest[t2]]) return 0;
        t=t1+1;
        TreeUnfold(lts->edge_idx,lts->label[t1],(int*)rate1);
        while(t<m1 && map[lts->dest[t]]==block){
            TreeUnfold(lts->edge_idx,lts->label[t],(int*)temp);
            uint64_t teller=((uint64_t)rate1[0])*((uint64_t)temp[1]);
                    teller+=((uint64_t)temp[0])*((uint64_t)rate1[1]);
            uint64_t noemer=((uint64_t)rate1[1])*((uint64_t)temp[1]);
            uint64_t gcd=gcd64(teller,noemer);
            rate1[0]=teller/gcd;
            rate1[1]=noemer/gcd;
            t++;
        }
        t1=t;
        t=t2+1;
        TreeUnfold(lts->edge_idx,lts->label[t2],(int*)rate2);
        while(t<m2 && map[lts->dest[t]]==block){
            TreeUnfold(lts->edge_idx,lts->label[t],(int*)temp);
            uint64_t teller=((uint64_t)rate2[0])*((uint64_t)temp[1]);
                    teller+=((uint64_t)temp[0])*((uint64_t)rate2[1]);
            uint64_t noemer=((uint64_t)rate2[1])*((uint64_t)temp[1]);
            uint64_t gcd=gcd64(teller,noemer);
            rate2[0]=teller/gcd;
            rate2[1]=noemer/gcd;
            t++;
        }
        t2=t;
        if (rate1[0]!=rate2[0] || rate1[1]!= rate2[1]) return 0;
    }
    return 0;
}
Esempio n. 4
0
static int read_state(lts_file_t file,int *seg,void* state,void*labels){
    if (file->state_count<file->lts->states){
        *seg=file->state_count%file->segments;
        if (file->lts->prop_idx) {
            TreeUnfold(file->lts->prop_idx,file->lts->properties[file->state_count],labels);
        } else if (file->lts->properties) {
            *((uint32_t*)labels)=file->lts->properties[file->state_count];
        }
        if (file->lts->state_db) {
            TreeUnfold(file->lts->state_db,file->state_count,state);
        } else {
            // TODO: decide if reading state number is allowed/required.
            *((uint32_t*)state)=file->state_count;
        }
        file->state_count++;
        return 1;
    } else {
        return 0;
    }
}
Esempio n. 5
0
static void lts_lump(lts_t lts){
    int found;
    uint32_t  i, k, j, count, oldbegin;
    lts_set_type(lts,LTS_BLOCK);
    count=0;
    uint32_t rate[2];
    uint32_t temp[2];
    for(i=0;i<lts->states;i++){
        oldbegin=lts->begin[i];
        lts->begin[i]=count;
        for(j=oldbegin;j<lts->begin[i+1];j++){
            found=0;
            for(k=lts->begin[i];k<count;k++){
                if(lts->dest[j]==lts->dest[k]){
                    TreeUnfold(lts->edge_idx,lts->label[k],(int*)rate);
                    TreeUnfold(lts->edge_idx,lts->label[j],(int*)temp);
                    uint64_t teller=((uint64_t)rate[0])*((uint64_t)temp[1]);
                            teller+=((uint64_t)temp[0])*((uint64_t)rate[1]);
                    uint64_t noemer=((uint64_t)rate[1])*((uint64_t)temp[1]);
                    uint64_t gcd=gcd64(teller,noemer);
                    rate[0]=teller/gcd;
                    rate[1]=noemer/gcd;
                    lts->label[k]=TreeFold(lts->edge_idx,(int*)rate);
                    found=1;
                    break;
                }
            }
            if (!found){
                lts->label[count]=lts->label[j];
                lts->dest[count]=lts->dest[j];
                count++;
            }
        }
    }
    lts->begin[lts->states]=count;
    lts_set_size(lts,lts->root_count,lts->states,count);
}
Esempio n. 6
0
static int torx_handle_request(torx_struct_t *context, char *req)
{
	while(isspace((int)*req))
		req++;
	switch(req[0]) {
	case 'r': {			/* reset */
		fprintf(stdout, "R 0\t1\n");
		fflush(stdout);
		break;
	}
	case 'e': {			/*explore */
		int n, res;
		req++;
		while(isspace((int)*req))
			req++;
		if ((res = sscanf(req, "%u", &n)) != 1) {
			int l = strlen(req);
			if (req[l - 1] == '\n')
				req[l - 1] = '\0';
			fprintf(stdout, "E0 Missing event number (%s; sscanf found #%d)\n", req, res);
		} else if (n >= TreeCount(dbs)) {
			fprintf(stdout, "E0 Unknown event number\n");
			fflush(stdout);
		} else {
			int src[N], c;
			TreeUnfold(dbs,n,src);
			fprintf(stdout, "EB\n");
			c=GBgetTransitionsAll(context->model,src,torx_transition,context);
			fprintf(stdout, "EE\n");
			fflush(stdout);
		}
		break;
	}
	case 'q': {
		fprintf(stdout, "Q\n");
		fflush(stdout);
		return 1;
		break;
	}
	default:			/* unknown command */
		fprintf(stdout, "A_ERROR UnknownCommand: %s\n", req);
		fflush(stdout);
	}
	return 0;
}
Esempio n. 7
0
static int read_edge(lts_file_t file,int *src_seg,void* src_state,
                           int *dst_seg,void*dst_state,void* labels
){
    if (file->edge_count<file->lts->transitions) {
        *((uint32_t*)src_seg)=file->lts->src[file->edge_count]%file->segments;
        *((uint32_t*)src_state)=file->lts->src[file->edge_count]/file->segments;
        *((uint32_t*)dst_seg)=file->lts->dest[file->edge_count]%file->segments;
        *((uint32_t*)dst_state)=file->lts->dest[file->edge_count]/file->segments;
        if (file->lts->edge_idx) {
            TreeUnfold(file->lts->edge_idx,file->lts->label[file->edge_count],labels);
        } else if (file->lts->label) {
            *((uint32_t*)labels)=file->lts->label[file->edge_count];
        }
        file->edge_count++;
        return 1;
    } else {
        return 0;
    }
}
Esempio n. 8
0
int main(int argc, char *argv[]){
	char *files[2];
	RTinitPopt(&argc,&argv,options,1,2,files,NULL,"<model> [<lts>]",
		"Perform an enumerative reachability analysis of <model>\n"
		"Run the TorX remote procedure call protocol on <model> (--torx).\n\n"
		"Options");
	if (files[1]) {
		Warning(info,"Writing output to %s",files[1]);
		write_lts=1;
	} else {
		Warning(info,"No output, just counting the number of states");
		write_lts=0;
	}
	if (application==RunTorX && write_lts) Fatal(1,error,"A TorX server does not write to a file");
	Warning(info,"loading model from %s",files[0]);
	model_t model=GBcreateBase();
	GBsetChunkMethods(model,new_string_index,NULL,
		(int2chunk_t)SIgetC,(chunk2int_t)SIputC,(get_count_t)SIgetCount);

	GBloadFile(model,files[0],&model);

	if (RTverbosity >=2) {
	  fprintf(stderr,"Dependency Matrix:\n");
	  GBprintDependencyMatrix(stderr,model);
	}
	if (matrix) {
	  GBprintDependencyMatrix(stdout,model);
	  exit(0);
	}
	lts_type_t ltstype=GBgetLTStype(model);
	N=lts_type_get_state_length(ltstype);
	edge_info_t e_info=GBgetEdgeInfo(model);
	K=e_info->groups;
	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 (state_labels&&write_lts&&!write_state) {
		Fatal(1,error,"Writing state labels, but not state vectors unsupported. "
			"Writing of state vector is enabled with the option --write-state");
	}
	int src[N];
	GBgetInitialState(model,src);
	Warning(info,"got initial state");
	int level=0;
	switch(application){
	case ReachVset:
		domain=vdom_create_default(N);
		visited_set=vset_create(domain,0,NULL);
		next_set=vset_create(domain,0,NULL);
		if (write_lts){
			output=lts_output_open(files[1],model,1,0,1,"viv",NULL);
			lts_output_set_root_vec(output,(uint32_t*)src);
			lts_output_set_root_idx(output,0,0);
			output_handle=lts_output_begin(output,0,0,0);	
		}
		vset_add(visited_set,src);
		vset_add(next_set,src);
		vset_t current_set=vset_create(domain,0,NULL);
		while (!vset_is_empty(next_set)){
		  if (RTverbosity >= 1)
		    Warning(info,"level %d has %d states, explored %d states %d trans",
			    level,(visited-explored),explored,trans);
		  level++;
		  vset_copy(current_set,next_set);
		  vset_clear(next_set);
		  vset_enum(current_set,explore_state_vector,model);
		}
		long long size;
		long nodes;
		vset_count(visited_set,&nodes,&size);
	    	Warning(info,"%lld reachable states represented symbolically with %ld nodes",size,nodes);
		break;
	case ReachTreeDBS:
		dbs=TreeDBScreate(N);
		if(TreeFold(dbs,src)!=0){
			Fatal(1,error,"expected 0");
		}
		if (write_lts){
			output=lts_output_open(files[1],model,1,0,1,write_state?"vsi":"-ii",NULL);
			if (write_state) lts_output_set_root_vec(output,(uint32_t*)src);
			lts_output_set_root_idx(output,0,0);
			output_handle=lts_output_begin(output,0,0,0);	
		}
		int limit=visited;
		while(explored<visited){
		  if (limit==explored){
		    if (RTverbosity >= 1)
		      Warning(info,"level %d has %d states, explored %d states %d trans",
			      level,(visited-explored),explored,trans);
		    limit=visited;
		    level++;
		  }
		  TreeUnfold(dbs,explored,src);
		  explore_state_index(model,explored,src);
		}
		break;
	case RunTorX:
		{
		torx_struct_t context = { model, ltstype };
		torx_ui(&context);
		return 0;
		}
	}
	if (write_lts){
		lts_output_end(output,output_handle);
		Warning(info,"finishing the writing");
		lts_output_close(&output);
		Warning(info,"state space has %d levels %d states %d transitions",level,visited,trans);
	} else {
		printf("state space has %d levels %d states %d transitions\n",level,visited,trans);
	}
	return 0;
}
Esempio n. 9
0
void lts_write_pg (const char*name, lts_t lts) {
    Print(infoShort,"writing %s",name);
    FILE* f=fopen(name,"w");
    if (f == NULL) {
        AbortCall("Could not open %s for writing",name);
    }
    lts_set_type(lts,LTS_BLOCK);
    //int N=lts_type_get_state_length(lts->ltstype);
    int L=lts_type_get_state_label_count(lts->ltstype);
    //int K=lts_type_get_edge_label_count(lts->ltstype);
    if (L != 2){
        Abort("Number of state labels is %d, needs to be 2 for parity games.",L);
    }
    Warning(info,"Number of states: %d", lts->states);
    Warning(info,"First pass...");
    // compute max priority
    // determine if there are nodes without successors
    int max_priority = 0;
    int labels[L];
    bool first_edge = true;
    bool write_true = false;
    bool write_false = false;
    for(uint32_t src_idx=0; src_idx<lts->states; src_idx++){
        TreeUnfold(lts->prop_idx, lts->properties[src_idx], labels);
        int priority = labels[PG_PRIORITY];
        if (priority > max_priority) {
            max_priority = priority;
        }
        int player = labels[PG_PLAYER];
        if (lts->begin[src_idx] >= lts->begin[src_idx+1]){
            // no edges
            if (player==PG_AND) {
                write_true = true;
            } else if (player==PG_OR) {
                write_false = true;
            }
            //Warning(info, "State %d has no successors.",src_idx);
        }
    }
    if (max_priority%2!=0)
    {
        // when converting from min to max-priority game,
        // the maximum priority should be even.
        max_priority++;
    }
    Warning(info,"Second pass...");
    bool min_game = false;
    int max_id = lts->states;
    int offset = 0;
    int true_idx = 0;
    int false_idx = 0;
    if (write_true) {
        true_idx = max_id;
        max_id++;
    }
    if (write_false) {
        false_idx = max_id;
        max_id++;
    }
    // write header.
    fprintf(f,"parity %d;\n",max_id-1);
    // write states and edges
    for(uint32_t src_idx=0; src_idx<lts->states; src_idx++){
        if (src_idx > 0){
            fprintf(f,";\n");
        }
        TreeUnfold(lts->prop_idx, lts->properties[src_idx], labels);
        int priority = min_game ? labels[PG_PRIORITY] : max_priority-labels[PG_PRIORITY];
        int player = labels[1];
        fprintf(f, "%d %d %d ", src_idx+offset, priority /* priority */, player /* player */);
        first_edge = true;
        for(uint32_t edge_idx=lts->begin[src_idx]; edge_idx<lts->begin[src_idx+1]; edge_idx++){
            if (!first_edge){
                fprintf(f, ",");
            }
            fprintf(f,"%d",lts->dest[edge_idx]+offset);
            first_edge = false;
        }
        if (first_edge)
        {
            //Warning(info,"State %d has no successors.",src_idx);
            // add transition to true/false node
            fprintf(f,"%d",((player==PG_AND) ? true_idx : false_idx));
        }
    }
    fprintf(f,";\n");
    // write true and false
    if (write_true)
    {
        fprintf(f, "%d %d %d ", true_idx, min_game ? 0 : max_priority /* priority */, PG_AND /* player */);
        fprintf(f,"%d;\n",true_idx);
    }
    if (write_false)
    {
        fprintf(f, "%d %d %d ", false_idx, min_game ? 1 : max_priority-1 /* priority */, PG_OR /* player */);
        fprintf(f,"%d;\n",false_idx);
    }
    fclose(f);
}
Esempio n. 10
0
static void dbs_unfold(void*context,int seg,int ofs,int*vec){
	struct dbs_ctx *ctx=(struct dbs_ctx *)context;
	TreeUnfold(ctx->dbs,ctx->begin[seg]+ofs,vec);
}