Beispiel #1
0
void set_mkdet(lts_t lts){
	int i,j,tcount,tmax,scount;
	lts_t orig;

	orig=lts_create();
	Warning(2,"copying LTS");
	lts_set_type(orig,LTS_BLOCK);
	lts_set_type(lts,LTS_BLOCK);
	lts_set_size(orig,lts->states,lts->transitions);
	orig->root=lts->root;
	for(i=0;i<=lts->states;i++) {
		orig->begin[i]=lts->begin[i];
	}
	for(i=0;i<lts->transitions;i++){
		orig->label[i]=lts->label[i];
		orig->dest[i]=lts->dest[i];
	}
	SetClear(-1);
	tmax=MKDET_BLOCK_SIZE;
	tcount=0;
	scount=0;
	lts_set_type(lts,LTS_LIST);
	lts_set_size(lts,1,tmax);
	fully_expored=0;
	mkdet_dfs(orig,SetInsert(EMPTY_SET,0,orig->root),lts,&scount,&tcount,&tmax);
	//for(i=0;i<orig->states;i++){
	//	mkdet_dfs(orig,SetInsert(EMPTY_SET,0,i),lts,&scount,&tcount,&tmax);
	//}
	lts->root=SetGetTag(SetInsert(EMPTY_SET,0,orig->root));
	lts_set_size(lts,scount,tcount);
	lts_free(orig);
	SetFree();
}
Beispiel #2
0
void set_reduce_strong(lts_t lts){
	int iter, set, *newmap, setcount, count, *tmp, *map;
        uint32_t i;
	mytimer_t timer;
        cell_t j;
	timer=createTimer();
	startTimer(timer);
	lts_uniq(lts);
	lts_sort(lts);
	lts_set_type(lts,LTS_BLOCK);
	map=(int*)malloc(sizeof(int)*lts->states);
	newmap=(int*)malloc(sizeof(int)*lts->states);
	if (!map || !newmap ) Fatal(1,1,"out of memory");
	for(i=0;i<lts->states;i++){
		map[i]=0;
	}
	count=1;
	iter=0;
	for(;;){
		MEMSTAT_CHECK;
		SetClear(-1);
		iter++;
		setcount=0;
		for(i=0;i<lts->states;i++){
			set=EMPTY_SET;
			for(j=lts->begin[i];j<lts->begin[i+1];j++){
				set=SetInsert(set,lts->label[j],map[lts->dest[j]]);
			}
			newmap[i]=SetGetTag(set);
			if (newmap[i]<0) {
				SetSetTag(set,setcount);
				newmap[i]=setcount;
				setcount++;
			}
		}
		Warning(2,"count is %d",setcount);
		if(count==setcount) break;
		count=setcount;
		tmp=map;
		map=newmap;
		newmap=tmp;
	}
	SetFree();
	free(newmap);
	stopTimer(timer);
	/* reportTimer(timer,"computation of partition took"); */
	lts_set_type(lts,LTS_LIST);
	lts->root=map[lts->root];
        lts->root2=map[lts->root2];
	for(j=0;j<lts->transitions;j++){
		lts->src[j]=map[lts->src[j]];
		lts->dest[j]=map[lts->dest[j]];
	}
	lts->states=count;
	free(map);
	lts_uniq(lts);
	Warning(1,"reduction took %d iterations",iter);
}
Beispiel #3
0
void lts_sort_alt(lts_t lts){
	uint32_t i,j,k,l,d;
	int *lbl_index;

	lbl_index=(int*)malloc(lts->label_count*sizeof(int));
	for(i=0;i<lts->label_count;i++){
		lbl_index[i]=-1;
	}
	lts_set_type(lts,LTS_BLOCK);
	k=0;
	for(i=0;i<lts->transitions;i++){
		if (lbl_index[lts->label[i]]==-1){
			lbl_index[lts->label[i]]=k;
			k++;
		}
	}
	for(i=0;i<lts->states;i++){
		for(j=lts->begin[i];j<lts->begin[i+1];j++){
			l=lts->label[j];
			d=lts->dest[j];
			for(k=j;k>lts->begin[i];k--){
				if (lbl_index[lts->label[k-1]]<lbl_index[l]) break;
				if ((lts->label[k-1]==l)&&(lts->dest[k-1]<=d)) break;
				lts->label[k]=lts->label[k-1];
				lts->dest[k]=lts->dest[k-1];
			}
			lts->label[k]=l;
			lts->dest[k]=d;
		}
	}
}
Beispiel #4
0
void lts_uniq(lts_t lts){
	uint32_t i,j,k,count,oldbegin,found;
	lts_set_type(lts,LTS_BLOCK);
	count=0;
	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->label[j]==lts->label[k])&&(lts->dest[j]==lts->dest[k])){
					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->states,count);
}
Beispiel #5
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);
}
Beispiel #6
0
lts_file_t lts_writer(lts_t lts,int segments,lts_file_t settings){
    lts_file_t file=lts_file_bare("<heap>",lts->ltstype,segments,settings,sizeof(struct lts_file_s));
    file->lts=lts;
    file->segments=segments;
    file->state_perseg=(uint32_t*)RTmallocZero(segments*sizeof(uint32_t));
    file->edge_labels=lts_type_get_edge_label_count(lts->ltstype);
    lts_file_set_write_init(file,write_init);
    lts_file_set_write_state(file,write_state);
    lts_file_set_write_edge(file,write_edge);
    lts_file_set_close(file,write_close);
    lts_file_complete(file);
    lts_set_type(file->lts,LTS_LIST);
    int T=lts_type_get_type_count(lts->ltstype);
    for(int i=0;i<T;i++){
        lts_file_set_table(file,i,lts->values[i]);
    }
    return file;
}
Beispiel #7
0
void lts_sort_dest(lts_t lts){
	uint32_t i,j,k,l,d;
	lts_set_type(lts,LTS_BLOCK);
	for(i=0;i<lts->states;i++){
		for(j=lts->begin[i];j<lts->begin[i+1];j++){
			l=lts->label[j];
			d=lts->dest[j];
			for(k=j;k>lts->begin[i];k--){
				if (lts->dest[k-1]<d) break;
				if ((lts->dest[k-1]==d)&&(lts->label[k-1]<=l)) break;
				lts->label[k]=lts->label[k-1];
				lts->dest[k]=lts->dest[k-1];
			}
			lts->label[k]=l;
			lts->dest[k]=d;
		}
	}
}
Beispiel #8
0
lts_file_t lts_reader(lts_t lts,int segments,lts_file_t settings){
    lts_file_t file=lts_file_bare("<heap>",lts->ltstype,segments,settings,sizeof(struct lts_file_s));
    file->lts=lts;
    file->segments=segments;
    file->edge_labels=lts_type_get_edge_label_count(lts->ltstype);
    lts_file_set_read_init(file,read_init);
    lts_file_set_read_state(file,read_state);
    lts_file_set_read_edge(file,read_edge);
    lts_file_set_close(file,read_close);
    lts_file_complete(file);
    int T=lts_type_get_type_count(lts->ltstype);
    for(int i=0;i<T;i++){
        lts_file_set_table(file,i,lts->values[i]);
    }
    lts_set_type(file->lts,LTS_LIST);
    file->init_count=0;
    file->state_count=0;
    file->edge_count=0;
    return file;
}
Beispiel #9
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);
}
Beispiel #10
0
void lts_uniq_sort(lts_t lts){
	uint32_t i,j,k,q,l,d,count,found;
	lts_set_type(lts,LTS_BLOCK);
	count=0;
	for(i=0;i<lts->states;i++){
		j=lts->begin[i];
		lts->begin[i]=count;
		for(;j<lts->begin[i+1];j++){
			l=lts->label[j];
			d=lts->dest[j];
			found=0;
			for(k=count;k>lts->begin[i];k--){
				if (l<lts->label[k-1]) continue;
				if (l==lts->label[k-1]) {
					if (d<lts->dest[k-1]) continue;
					if (d==lts->dest[k-1]) {
						found=1;
						break;
					}
				}
				break;
			}
			if(found) continue;
			for(q=count;q>k;q--){
				lts->label[q]=lts->label[q-1];
				lts->dest[q]=lts->dest[q-1];
			}
			lts->label[k]=l;
			lts->dest[k]=d;
			count++;
		}
	}
	//Warning(1,"count is %d",count);
	lts->begin[lts->states]=count;
	lts_set_size(lts,lts->states,count);
}
Beispiel #11
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 #12
0
void setbased_weak_reduce(lts_t lts){
	int tau,count,i,iter,setcount,set,*repr,t_count,num_states;
	int *map,*newmap;

	tau=lts->tau;
	lts_tau_cycle_elim(lts);
    Print(info,"size after tau cycle elimination is %d states and %d transitions",lts->states,lts->transitions);
	num_states=lts->states;
	map=(int*)malloc(sizeof(int)*lts->states);
	newmap=(int*)malloc(sizeof(int)*lts->states);
	lts_sort(lts);
	lts_set_type(lts,LTS_BLOCK_INV);
	for(i=0;i<num_states;i++){
		map[i]=0;
		newmap[i]=EMPTY_SET;
	}
	count=1;
	iter=0;
	for(;;){
		SetClear(-1);
		iter++;
		for(i=0;i<num_states;i++){
			dfs_weak_tau(lts,tau,map,newmap,i,map[i]);
		}
		SetSetTag(newmap[lts->root_list[0]],0);
		setcount=1;
		for(i=0;i<num_states;i++){
			set=newmap[i];
			if (SetGetTag(set)<0) {
				//fprintf(stderr,"new set:");
				//PrintSet(stderr,set);
				//fprintf(stderr,"\n");
				SetSetTag(set,setcount);
				setcount++;
			}
		}
		Print(info,"count is %d",setcount);
		//for(i=0;i<num_states;i++){
		//	fprintf(stderr,"%d: old %d new %d sig ",i,map[i],SetGetTag(newmap[i]));
		//	SetPrintIndex(stderr,newmap[i],lts->label_string);
		//	fprintf(stderr,"\n");
		//}
		if(count==setcount) break;
		count=setcount;
		for(i=0;i<num_states;i++){
			map[i]=SetGetTag(newmap[i]);
			newmap[i]=EMPTY_SET;
		}
	}
	repr=(int*)malloc(sizeof(int)*count);
	for(i=0;i<count;i++) {
		repr[i]=-1;
	}
	t_count=0;
	for(i=0;i<(int)lts->states;i++){
		if(repr[map[i]]==-1){
			repr[map[i]]=i;
			t_count+=SetGetSize(newmap[i]);
		}
	}
	lts_set_type(lts,LTS_BLOCK);
	lts_set_size(lts,lts->root_count,count,t_count);
	uint32_t r_count=0;
 	for(i=0;i<(int)lts->root_count;i++){
	  uint32_t tmp=map[lts->root_list[i]];
	  uint32_t j=0;
	  for(;j<r_count;j++){
	    if (tmp==lts->root_list[j]){
	      break;
	    }
	  }
	  if (j==r_count){
    	  lts->root_list[r_count]=tmp;
	      r_count++;
      }
	}
	lts->begin[0]=0;
	for(i=0;i<(int)lts->states;i++){
		count=lts->begin[i];
		set=newmap[repr[i]];
		while(set!=EMPTY_SET){
			if(weak_essential(newmap,repr,i,SetGetLabel(set),SetGetDest(set),tau)){
				lts->label[count]=SetGetLabel(set);
				lts->dest[count]=SetGetDest(set);
				count++;
			}
			set=SetGetParent(set);
		}
		lts->begin[i+1]=count;
	}
	lts_set_size(lts,r_count,lts->states,count);
	SetFree();
	free(newmap);
	free(map);
	free(repr);
    Print(info,"set2 reduction took %d iterations",iter);
}
Beispiel #13
0
static void lts_read_dir(archive_t archive,lts_t lts){
    Print(infoShort,"opening info");
    stream_t input=arch_read(archive,"info");
    dir_info_t info=DIRinfoRead(input,1);
    DSclose(&input);
    int segments=info->segment_count;
    Print(infoShort,"got info for %d segments",segments);
    int offset[segments];
    offset[0]=0;
    for(int i=1;i<segments;i++){
        offset[i]=info->state_count[i-1]+offset[i-1];
    }
    int s_count=0;
    int t_count=0;
    for(int i=0;i<segments;i++){
        s_count+=info->state_count[i];
        for(int j=0;j<segments;j++){
            t_count+=info->transition_count[i][j];
        }
    }
    Print(infoShort,"counted %u states and %u transitions",s_count,t_count);
    lts_set_sig(lts,single_action_type());
    lts_set_type(lts,LTS_LIST);
    lts_set_size(lts,1,s_count,t_count);
    lts->root_list[0]=offset[info->initial_seg]+info->initial_ofs;
    lts->tau=info->label_tau;
    Print(infoShort,"getting %d labels from TermDB",info->label_count);
    input=arch_read(archive,"TermDB");
    int type_no=lts_type_get_edge_label_typeno(lts->ltstype,0);
    for(int i=0;i<info->label_count;i++){
        char *line=DSreadLN(input);
        int len=strlen(line);
        char data[len];
        chunk tmp_chunk=chunk_ld(len,data);
        string2chunk(line,&tmp_chunk);
        VTputAtChunk(lts->values[type_no], tmp_chunk, i);
    }
    DSclose(&input);
    Print(infoShort,"got labels");
    int t_offset=0;
    char filename[1024];
    for(int i=0;i<segments;i++){
        for(int j=0;j<segments;j++){
            sprintf(filename,"src-%d-%d",i,j);
            stream_t src=arch_read(archive,filename);
            sprintf(filename,"label-%d-%d",i,j);
            stream_t lbl=arch_read(archive,filename);
            sprintf(filename,"dest-%d-%d",i,j);
            stream_t dst=arch_read(archive,filename);
            for(int k=0;k<info->transition_count[i][j];k++){
                lts->src[t_offset]=offset[i]+DSreadU32(src);
                lts->label[t_offset]=DSreadU32(lbl);
                lts->dest[t_offset]=offset[j]+DSreadU32(dst);
                t_offset++;
            }
            DSclose(&src);
            DSclose(&lbl);
            DSclose(&dst);
        }
    }
    DIRinfoDestroy(info);
}
Beispiel #14
0
void set_reduce_tau_star_a(lts_t lts){
	int tau,*map,count,*newmap,i,*tmp,iter,s,l,d,setcount,j,set,tau_count,a_count;
	int reachable,r_count,t_count,*repr;
	lts_t inv;

	tau=lts->tau;
	if (tau_cycle_elim) {
		lts_tau_cycle_elim(lts);
		Warning(1,"size after tau cycle elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	if (tau_indir_elim) {
		lts_tau_indir_elim(lts);
		Warning(1,"size after trivial tau elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	map=(int*)malloc(sizeof(int)*lts->states);
	newmap=(int*)malloc(sizeof(int)*lts->states);
	lts_set_type(lts,LTS_LIST);
	inv=lts_create();
	lts_set_type(inv,LTS_LIST);
	lts_set_size(inv,lts->states,lts->transitions);
	inv->root=0;
	tau_count=0;
	a_count=0;
	for(i=0;i<lts->states;i++){
		map[i]=0;
	}
	map[lts->root]=1;
	for(i=0;i<lts->transitions;i++) {
		if (lts->label[i]!=tau) map[lts->dest[i]]++;
	}
	reachable=0;
	for(i=0;i<lts->states;i++){
		if(map[i]!=0){
			newmap[i]=reachable;
			reachable++;
		} else {
			newmap[i]=(lts->states)+reachable-i-1;
		}
	}
	Warning(1,"%d states are reachable",reachable); 
	for(i=0;i<lts->transitions;i++) {
		if (lts->label[i]==tau){
			inv->src[tau_count]=newmap[lts->dest[i]];
			inv->label[tau_count]=lts->label[i];
			inv->dest[tau_count]=newmap[lts->src[i]];
			tau_count++;
		} else {
			lts->src[a_count]=newmap[lts->src[i]];
			lts->label[a_count]=lts->label[i];
			lts->dest[a_count]=newmap[lts->dest[i]];
			a_count++;
		}
	}
	lts_set_size(inv,lts->states,tau_count);
	lts_set_size(lts,lts->states,a_count);
	lts_sort(lts);
	lts_set_type(lts,LTS_BLOCK);
	lts_set_type(inv,LTS_BLOCK);
	for(i=0;i<lts->states;i++){
		map[i]=0;
		newmap[i]=EMPTY_SET;
	}
	count=1;
	iter=0;
	for(;;){
		SetClear(-1);
		iter++;
		for(i=0;i<lts->states;i++){
			for(j=lts->begin[i];j<lts->begin[i+1];j++){
				dfs_insert_tau_star_a(inv,newmap,lts->label[j],map[lts->dest[j]],i);
			}
		}
		SetSetTag(newmap[lts->root],0);
		setcount=1;
		for(i=0;i<lts->states;i++){
			if (SetGetTag(newmap[i])<0) {
				//fprintf(stderr,"new set:");
				//PrintSet(stderr,set);
				//fprintf(stderr,"\n");
				SetSetTag(newmap[i],setcount);
				setcount++;
			}
			if (i==(reachable -1)) {
				Warning(2,"reachable count is %d",setcount);
				r_count=setcount;
			}
		}
		Warning(2,"count is %d",setcount);
		if(count==setcount) break;
		count=setcount;
		for(i=0;i<lts->states;i++){
			map[i]=SetGetTag(newmap[i]);
			newmap[i]=EMPTY_SET;
		}
	}
	repr=(int*)malloc(sizeof(int)*r_count);
	for(i=0;i<r_count;i++) {
		repr[i]=-1;
	}
	t_count=0;
	for(i=0;i<reachable;i++){
		if(repr[map[i]]==-1){
			repr[map[i]]=i;
			t_count+=SetGetSize(newmap[i]);
		}
	}
	lts_set_size(lts,r_count,t_count);
	lts->root=0;
	lts->begin[0]=0;
	for(i=0;i<r_count;i++){
		count=lts->begin[i];
		set=newmap[repr[i]];
		while(set!=EMPTY_SET){
			lts->label[count]=SetGetLabel(set);
			lts->dest[count]=SetGetDest(set);
			set=SetGetParent(set);
			count++;
		}
		lts->begin[i+1]=count;
	}
	SetFree();
	free(newmap);
	free(map);
	free(repr);
	Warning(1,"reduction took %d iterations",iter);
}
Beispiel #15
0
void lowmem_lumping_reduce(lts_t lts){
    int *map,*newmap,*tmpmap;
    int *hash,mask,hc;
    int tmp, j;
    uint32_t i;
    uint32_t count=0,oldcount;
    int iter;
    long long int chain_length;
    long long int hash_lookups;
    uint32_t m;
    //mytimer_t timer=SCCcreateTimer();
    lts_set_type(lts,LTS_BLOCK);
    map=(int*)RTmalloc(lts->states*sizeof(int));
    newmap=(int*)RTmalloc(lts->states*sizeof(int));
    for(i=0;i<lts->states;i++){
        map[i]=lts->properties[i];
    }
    for(i=1<<14;i<lts->states;i=i<<1){
    }
    i=(i>>4);
    hash=(int*)RTmalloc(i*sizeof(int));
    mask=i-1;
    oldcount=TreeCount(lts->prop_idx);
    iter=0;
    for(;;){
        //SCCresetTimer(timer);
        //SCCstartTimer(timer);
        chain_length=0;
        hash_lookups=0;
        iter++;
        // sort transitions (bubble sort)
        for(i=0;i<lts->states;i++){
            for(m=lts->begin[i];m<lts->begin[i+1];m++){
                uint32_t k;
                for(k=m;k>lts->begin[i];k--){
                    if(map[lts->dest[k]]>map[lts->dest[k-1]]) break;
                    tmp=lts->label[k];
                    lts->label[k]=lts->label[k-1];
                    lts->label[k-1]=tmp;
                    tmp=lts->dest[k];
                    lts->dest[k]=lts->dest[k-1];
                    lts->dest[k-1]=tmp;
                }
            }
        }
        //SCCstopTimer(timer);
        //SCCreportTimer(timer,"sorting finished after");
        //SCCstartTimer(timer);
        // check if hash table is big enough.
        while((mask/5)<((int)count/3)){
            Print(infoShort,"Hash table resize prior to insertion!");
            RTfree(hash);
            mask=mask+mask+1;
            hash=(int*)RTmalloc((mask+1)*sizeof(int));
        }
        // clear hash table
        for(i=0;i<=(unsigned int)mask;i++){
            hash[i]=-1;
        }
        // insert states into hash table
        count=0;
        for(i=0;i<lts->states;i++){
            hash_lookups++;
            for(hc=lump_hashcode(lts,map,i);;hc=rehash(hc)){
                chain_length++;
                j=hash[hc&mask];
                if(j==-1) break;
                if(same_lump_sig(lts,(uint32_t*)map,i,j)) break;
            }
            if (j==-1) {
                count++;
                hash[hc&mask]=i;
                newmap[i]=i;
                if((mask/4)<((int)count/3)){
                    Print(infoLong,"Hash table resize during insertion!");
                    RTfree(hash);
                    mask=mask+mask+1;
                    hash=(int*)RTmalloc((mask+1)*sizeof(int));
                    for(j=0;j<=mask;j++){
                        hash[j]=-1;
                    }
                    for(j=0;j<=(int)i;j++) if(newmap[j]==j){
                        hash_lookups++;
                        for(hc=lump_hashcode(lts,map,j);hash[hc&mask]!=-1;hc=rehash(hc)){
                            chain_length++;
                        }
                        hash[hc&mask]=j;
                    }
                }
            } else {
                newmap[i]=j;
            }
        }
        //SCCstopTimer(timer);
        //SCCreportTimer(timer,"iteration took");
        Print(infoShort,"Average hash chain length: %2.3f",((float)chain_length)/((float)hash_lookups));
        Print(infoShort,"block count %d => %d",oldcount,count);
        if (count==oldcount) break;
        oldcount=count;
        tmpmap=map;
        map=newmap;
        newmap=tmpmap;
    }
    Print(infoShort,"Reduction took %d iterations",iter);
    if (count < lts->states){
        lts_set_type(lts,LTS_LIST);
        count=0;
        for(i=0;i<lts->states;i++){
            if(map[i]==(int)i){
                newmap[i]=count;
                hash[count]=lts->properties[i];
                count++;
            } else {
                newmap[i]=lts->states-1;
            }
        }
        RTfree(lts->properties);
        lts->properties=(uint32_t*)hash;
        hash=NULL;
        for(i=0;i<lts->root_count;i++){
            lts->root_list[i]=newmap[map[lts->root_list[i]]];
        }
        for(m=0;m<lts->transitions;m++){
            lts->src[m]=newmap[lts->src[m]];
            lts->dest[m]=newmap[map[lts->dest[m]]];
        }
        RTfree(map);
        RTfree(newmap);

        lts_set_type(lts,LTS_BLOCK);
        lts_set_size(lts,lts->root_count,oldcount,lts->begin[oldcount]);

        lts_lump(lts);
    } else {
        RTfree(hash);
        RTfree(map);
        RTfree(newmap);
    }
}
Beispiel #16
0
void set_reduce_branching3(lts_t lts){
	int tau,*map,count,*newmap,i,*tmp,iter,s,l,d,setcount,j,set;
	int itemcount,subitercount,*tmpmap;

	tau=lts->tau;
	if (tau_cycle_elim) {
		lts_tau_cycle_elim(lts);
		Warning(1,"size after tau cycle elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	if (tau_indir_elim) {
		lts_tau_indir_elim(lts);
		Warning(1,"size after trivial tau elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	map=(int*)malloc(sizeof(int)*lts->states);
	tmpmap=(int*)malloc(sizeof(int)*lts->states);
	newmap=(int*)malloc(sizeof(int)*lts->states);
	lts_set_type(lts,LTS_LIST);
	lts_sort(lts);
	lts_set_type(lts,LTS_BLOCK);
	for(i=0;i<lts->states;i++){
		map[i]=0;
	}
	count=1;
	iter=0;
	for(;;){
		SetClear(-1);
		iter++;
		for(i=0;i<lts->states;i++){
			newmap[i]=EMPTY_SET;
		}

		for(i=0;i<lts->states;i++){
			for(j=lts->begin[i];j<lts->begin[i+1];j++){
				if (lts->label[j]!=tau || map[i]!=map[lts->dest[j]]) {
					newmap[i]=SetInsert(newmap[i],lts->label[j],map[lts->dest[j]]);
				} 
			}
			tmpmap[i]=newmap[i];
		}
		subitercount=0;
		itemcount=1;
		while(itemcount>0){
			subitercount++;
			for(i=0;i<lts->states;i++){
				for(j=lts->begin[i];j<lts->begin[i+1];j++){
					if (lts->label[j]==tau && map[i]==map[lts->dest[j]] && tmpmap[i]!= newmap[lts->dest[j]]) {
						tmpmap[i]=SetUnion(tmpmap[i],newmap[lts->dest[j]]);
					}
				}
			}
			itemcount=0;
			for(i=0;i<lts->states;i++){
				if (tmpmap[i]!=newmap[i]) {
					newmap[i]=tmpmap[i];
					itemcount++;
				}
			}
			Warning(2,"sub iteration %d had %d changes",subitercount,itemcount);
		}
		Warning(1,"Needed %d sub iterations",subitercount);

		SetSetTag(newmap[lts->root],0);
		setcount=1;
		for(i=0;i<lts->states;i++){
			set=newmap[i];
			newmap[i]=SetGetTag(set);
			if (newmap[i]<0) {
				//fprintf(stderr,"new set:");
				//PrintSet(stderr,set);
				//fprintf(stderr,"\n");
				SetSetTag(set,setcount);
				newmap[i]=setcount;
				setcount++;
			}
		}
		Warning(2,"count is %d",setcount);
		if(count==setcount) break;
		count=setcount;
		tmp=map;
		map=newmap;
		newmap=tmp;
	}
	SetFree();
	free(newmap);
	lts_set_type(lts,LTS_LIST);
	lts->root=map[lts->root];
        lts->root2=map[lts->root2];
	lts->states=count;
	count=0;
	for(i=0;i<lts->transitions;i++){
		s=map[lts->src[i]];
		l=lts->label[i];
		d=map[lts->dest[i]];
		if ((l==tau)&&(s==d)) continue;
		lts->src[count]=s;
		lts->label[count]=l;
		lts->dest[count]=d;
		count++;
	}
	lts_set_size(lts,lts->states,count);
	lts_uniq(lts);
	free(map);
	Warning(1,"reduction took %d iterations",iter);
}
Beispiel #17
0
void set_reduce_branching2(lts_t lts){
	int tau,count,i,*tmp,iter,s,l,d,setcount,j,set,*repr,t_count,tag,num_states,last_trans;
	//int *map,*newmap;
	//lts_t inv;

	tau=lts->tau;
        lts_divergence_marking(lts);
	if (tau_cycle_elim) {
		lts_tau_cycle_elim(lts);
		Warning(1,"size after tau cycle elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	if (tau_indir_elim) {
		lts_tau_indir_elim(lts);
		Warning(1,"size after trivial tau elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	num_states=lts->states;
	map=(int*)malloc(sizeof(int)*lts->states);
	newmap=(int*)malloc(sizeof(int)*lts->states);
	lts_set_type(lts,LTS_LIST);
	inv=lts_create();
	lts_set_type(inv,LTS_LIST);
	lts_set_size(inv,lts->states,lts->transitions);
	inv->root=0;
	count=0;
	for(i=0;i<lts->transitions;i++) if (lts->label[i]==tau){
		inv->src[count]=lts->dest[i];
		inv->label[count]=lts->label[i];
		inv->dest[count]=lts->src[i];
		count++;
	}
	lts_set_size(inv,lts->states,count);
	lts_sort(lts);
	lts_set_type(lts,LTS_BLOCK);
	lts_set_type(inv,LTS_BLOCK);
	for(i=0;i<num_states;i++){
		map[i]=0;
		newmap[i]=EMPTY_SET;
	}
	count=1;
	iter=0;
	for(;;){
		SetClear(-1);
		iter++;
		for(i=0;i<num_states;i++){
			last_trans=lts->begin[i+1];
			for(j=lts->begin[i];j<last_trans;j++){
				label=lts->label[j];
				dest=map[lts->dest[j]];
				if (label!=tau || map[i]!=dest) {
					//dfs_insert(inv,map,newmap,lts->label[j],map[lts->dest[j]],i);
					dfs_insert(i);
				}
			}
		}
		SetSetTag(newmap[lts->root],0);
		setcount=1;
		for(i=0;i<num_states;i++){
			set=newmap[i];
			if (SetGetTag(set)<0) {
				//fprintf(stderr,"new set:");
				//PrintSet(stderr,set);
				//fprintf(stderr,"\n");
				SetSetTag(set,setcount);
				setcount++;
			}
		}
		Warning(2,"count is %d",setcount);
		if(count==setcount) break;
		count=setcount;
		for(i=0;i<num_states;i++){
			map[i]=SetGetTag(newmap[i]);
			newmap[i]=EMPTY_SET;
		}
	}
	repr=(int*)malloc(sizeof(int)*count);
	for(i=0;i<count;i++) {
		repr[i]=-1;
	}
	t_count=0;
	for(i=0;i<lts->states;i++){
		if(repr[map[i]]==-1){
			repr[map[i]]=i;
			t_count+=SetGetSize(newmap[i]);
		}
	}
	lts_set_size(lts,count,t_count);
	lts->root=0;
        lts->root2=map[lts->root2];
	lts->begin[0]=0;
	for(i=0;i<lts->states;i++){
		count=lts->begin[i];
		set=newmap[repr[i]];
		while(set!=EMPTY_SET){
			lts->label[count]=SetGetLabel(set);
			lts->dest[count]=SetGetDest(set);
			set=SetGetParent(set);
			count++;
		}
		lts->begin[i+1]=count;
	}
	SetFree();
	free(newmap);
	free(map);
	free(repr);
	Warning(1,"set2 reduction took %d iterations",iter);
}
Beispiel #18
0
void set_reduce_branching(lts_t lts){
	int tau,*map,count,*newmap,i,*tmp,iter,s,l,d,setcount,j,set;
	int this_union;
#ifdef PREV_UNION
	int prev_union;
#endif
	tau=lts->tau;
	tau_cycle_elim=1;
	if (tau_cycle_elim) {
		lts_tau_cycle_elim(lts);
		Warning(1,"size after tau cycle elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	if (tau_indir_elim) {
		lts_tau_indir_elim(lts);
		Warning(1,"size after trivial tau elimination is %d states and %d transitions",lts->states,lts->transitions);
	}
	lts_sort(lts);
	lts_set_type(lts,LTS_BLOCK);
	map=(int*)malloc(sizeof(int)*lts->states);
	newmap=(int*)malloc(sizeof(int)*lts->states);
	for(i=0;i<lts->states;i++){
		map[i]=0;
	}
	count=1;
	iter=0;
	for(;;){
		SetClear(-1);
		iter++;
		for(i=lts->states-1;i>=0;i--){
			set=EMPTY_SET;
#ifdef PREV_UNION
			prev_union=EMPTY_SET;
#endif
			for(j=lts->begin[i];j<lts->begin[i+1];j++){
				if (lts->label[j]==tau && map[i]==map[lts->dest[j]]) {
					this_union=newmap[lts->dest[j]];
#ifdef PREV_UNION
					if(this_union!=prev_union){
						prev_union=this_union;
#endif
						set=SetUnion(set,this_union);
#ifdef PREV_UNION
					}
#endif
				} else {
					set=SetInsert(set,lts->label[j],map[lts->dest[j]]);
				}
			}
			newmap[i]=set;
		}
		SetSetTag(newmap[lts->root],0);
		setcount=1;
		for(i=0;i<lts->states;i++){
			set=newmap[i];
			newmap[i]=SetGetTag(set);
			if (newmap[i]<0) {
				//fprintf(stderr,"new set:");
				//PrintSet(stderr,set);
				//fprintf(stderr,"\n");
				SetSetTag(set,setcount);
				newmap[i]=setcount;
				setcount++;
			}
		}
		Warning(2,"count is %d",setcount);
		if(count==setcount) break;
		count=setcount;
		tmp=map;
		map=newmap;
		newmap=tmp;
	}
	SetFree();
	free(newmap);
	lts_set_type(lts,LTS_LIST);
	lts->root=map[lts->root];
        lts->root2=map[lts->root2];
	lts->states=count;
	count=0;
	for(i=0;i<lts->transitions;i++){
		s=map[lts->src[i]];
		l=lts->label[i];
		d=map[lts->dest[i]];
		if ((l==tau)&&(s==d)) continue;
		lts->src[count]=s;
		lts->label[count]=l;
		lts->dest[count]=d;
		count++;
	}
	lts_set_size(lts,lts->states,count);
	lts_uniq(lts);
	free(map);
	Warning(1,"reduction took %d iterations",iter);
}
Beispiel #19
0
void set2_reduce_strong(lts_t lts){
	int *map,count,*newmap,i,*tmp,iter,setcount,j,set;
	bitset_t has_repr;

	has_repr=bitset_create(8,16);
	lts_uniq(lts);
	lts_sort(lts);
	lts_set_type(lts,LTS_BLOCK);
	map=(int*)malloc(sizeof(int)*lts->states);
	newmap=(int*)malloc(sizeof(int)*lts->states);
	if (!map || !newmap || !has_repr) Fatal(1,1,"out of memory");
	for(i=0;i<lts->states;i++){
		map[i]=0;
	}
	count=1;
	iter=0;
	for(;;){
		SetClear(-1);
		iter++;
		setcount=0;
		for(i=0;i<lts->states;i++){
			set=EMPTY_SET;
			for(j=lts->begin[i];j<lts->begin[i+1];j++){
				set=SetInsert(set,lts->label[j],map[lts->dest[j]]);
			}
			newmap[i]=set;
			if (!bitset_test(has_repr,set)){
				bitset_set(has_repr,set);
				setcount++;
			}
		}
		Warning(2,"count is %d",setcount);
		if(count==setcount) break;
		bitset_clear_all(has_repr);
		count=setcount;
		tmp=map;
		map=newmap;
		newmap=tmp;
	}
	setcount=0;
	for(i=0;i<lts->states;i++){
		newmap[i]=SetGetTag(map[i]);
		if (newmap[i]<0) {
			SetSetTag(map[i],setcount);
			newmap[i]=setcount;
			setcount++;
		}
	}
	free(map);
	map=newmap;
	Warning(2,"final count is %d",setcount);
	SetFree();
	lts_set_type(lts,LTS_LIST);
	lts->root=map[lts->root];
        lts->root2=map[lts->root2];
	for(i=0;i<lts->transitions;i++){
		lts->src[i]=map[lts->src[i]];
		lts->dest[i]=map[lts->dest[i]];
	}
	lts->states=count;
	lts_uniq(lts);
	free(map);
	bitset_destroy(has_repr);
	Warning(1,"reduction took %d iterations",iter);
}
Beispiel #20
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);
}