Пример #1
0
static void mkdet_dfs(lts_t orig,int S,lts_t lts,int*scount,int*tcount,int*tmax){
	int l,T;

	if(SetGetTag(S)==-1){
		SetSetTag(S,*scount);
		(*scount)++;
		for(l=0;l<lts->label_count;l++){
			T=mkdet_next(orig,l,S);
			if (T!=EMPTY_SET) {
				mkdet_dfs(orig,T,lts,scount,tcount,tmax);
				if ((*tcount)==(*tmax)) {
					(*tmax)+=MKDET_BLOCK_SIZE;
					lts_set_size(lts,1,(*tmax));
				}
				lts->src[*tcount]=SetGetTag(S);
				lts->label[*tcount]=l;
				lts->dest[*tcount]=SetGetTag(T);
				(*tcount)++;
				if (((*tcount)%MKDET_MONITOR_INTERVAL)==0){
					Warning(1,"visited %d states and %d transitions, fully expored %d states",
						*scount,*tcount,fully_expored);
				}
			}
		}
		fully_expored++;
	}
}
Пример #2
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);
}
Пример #3
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);
}
Пример #4
0
static void write_state(lts_file_t file,int seg,void* state,void*labels){
    uint32_t state_no;
    if (file->lts->state_db){
        state_no=TreeFold(file->lts->state_db,state);
    } else {
        state_no=file->state_perseg[seg]*file->segments+seg;
    }
    while(state_no>=file->lts->states) {
        lts_set_size(file->lts,file->lts->root_count,file->lts->states+32768,file->lts->transitions);
    }
    (void) state;
    if (file->lts->prop_idx) {
        file->lts->properties[state_no]=TreeFold(file->lts->prop_idx,labels);
    } else if (file->lts->properties) {
        file->lts->properties[state_no]=*((uint32_t*)labels);
    }
    file->state_perseg[seg]++;
}
Пример #5
0
static void write_init(lts_file_t file,int seg,void* state){
    uint32_t state_no;
    switch(lts_file_init_mode(file)){
    case Index:
        state_no=*((uint32_t*)state) * file->segments + seg;
        break;
    case SegVector:
    case Vector:
        if (seg != 0) Abort("(Seg)Vector format with multiple segments unsupported");
        state_no=TreeFold(file->lts->state_db,state);
        break;
    default:
        Abort("missing case");
    }
    if (file->init_count>=file->lts->root_count) {
        lts_set_size(file->lts,file->lts->root_count+32,file->lts->states,file->lts->transitions);
    }
    file->lts->root_list[file->init_count]=state_no;
    file->init_count++;
}
Пример #6
0
static void write_edge(lts_file_t file,int src_seg,void* src_state,
                           int dst_seg,void*dst_state,void* labels
){
    uint32_t src_no;
    switch(lts_file_source_mode(file)){
    case Index:
        src_no=*((uint32_t*)src_state)*file->segments+src_seg;
        break;
    case SegVector:
    case Vector:
        if (src_seg != 0) Abort("(Seg)Vector format with multiple segments unsupported");
        src_no=TreeFold(file->lts->state_db,src_state);
        break;
    default:
        Abort("missing case");
    }
    uint32_t dst_no;
    switch(lts_file_dest_mode(file)){
    case Index:
        dst_no=*((uint32_t*)dst_state)*file->segments+dst_seg;
        break;
    case SegVector:
    case Vector:
        if (dst_seg != 0) Abort("(Seg)Vector format with multiple segments unsupported");
        dst_no=TreeFold(file->lts->state_db,dst_state);
        break;
    default:
        Abort("missing case");
    }
    if (file->edge_count>=file->lts->transitions) {
        lts_set_size(file->lts,file->lts->root_count,file->lts->states,file->lts->transitions+32768);
    }
    file->lts->src[file->edge_count]=src_no;
    file->lts->dest[file->edge_count]=dst_no;
    if (file->lts->edge_idx) {
        file->lts->label[file->edge_count]=TreeFold(file->lts->edge_idx,labels);
    } else if (file->lts->label) {
        file->lts->label[file->edge_count]=*((uint32_t*)labels);
    }
    file->edge_count++;
}
Пример #7
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);
}
Пример #8
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);
}
Пример #9
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);
}
Пример #10
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);
}
Пример #11
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);
}
Пример #12
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);
}
Пример #13
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);
}
Пример #14
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);
}
Пример #15
0
static void write_close(lts_file_t file){
    //if (file->init_count!=1) Abort("missing initial state"); in some cases no initial states makes sense!
    uint32_t pre_sum=0;
    for(int i=0;i<file->segments;i++) pre_sum+=file->state_perseg[i];
    uint32_t tmp;
    for (int i=0;i<file->segments;i++){
        tmp=lts_get_max_src_p1(file,i);
        if (tmp>file->state_perseg[i]) file->state_perseg[i]=tmp;
        tmp=lts_get_max_dst_p1(file,i);
        if (tmp>file->state_perseg[i]) file->state_perseg[i]=tmp;
    }
    file->state_count=0;
    for(int i=0;i<file->segments;i++) file->state_count+=file->state_perseg[i];
    if (pre_sum && pre_sum!=file->state_count) {
        Abort("edges use unwritten states");
    }
    uint32_t offset[file->segments];
    offset[0]=0;
    for(int i=1;i<file->segments;i++) offset[i]=offset[i-1]+file->state_perseg[i-1];
    uint32_t seg,ofs;
    for(uint32_t i=0;i<file->lts->root_count;i++){
        seg=file->lts->root_list[i]%file->segments;
        ofs=file->lts->root_list[i]/file->segments;
        file->lts->root_list[i]=offset[seg]+ofs;
    }
    for(uint32_t i=0;i<file->edge_count;i++){
        seg=file->lts->src[i]%file->segments;
        ofs=file->lts->src[i]/file->segments;
        file->lts->src[i]=offset[seg]+ofs;
        seg=file->lts->dest[i]%file->segments;
        ofs=file->lts->dest[i]/file->segments;
        file->lts->dest[i]=offset[seg]+ofs;
    }
    if (file->lts->properties){
        uint32_t* temp=file->lts->properties;
        file->lts->properties=(uint32_t*)RTmalloc(file->state_count*sizeof(uint32_t));
        for(int i=0;i<file->segments;i++){
            for(uint32_t j=0;j<file->state_perseg[i];j++){
                file->lts->properties[offset[i]+j]=temp[j*file->segments+i];
            }
        }
        RTfree(temp);
    }
    lts_set_size(file->lts,file->init_count,file->state_count,file->edge_count);
    file->lts->tau=-1;
    if (lts_type_get_edge_label_count(file->lts->ltstype)==1 &&
        strncmp(lts_type_get_edge_label_name(file->lts->ltstype,0),LTSMIN_EDGE_TYPE_ACTION_PREFIX,6)==0)
    {
        Print(infoShort,"action labeled, detecting silent step");
        int tableno=lts_type_get_edge_label_typeno(file->lts->ltstype,0);
        value_table_t vt=file->lts->values[tableno];
        int N=VTgetCount(vt);
        for(int i=0;i<N;i++){
            chunk c=VTgetChunk(vt,i);
            if ( (c.len==strlen(LTSMIN_EDGE_VALUE_TAU) && strcmp(c.data,LTSMIN_EDGE_VALUE_TAU)==0)
              || (c.len==1 && strcmp(c.data,"i")==0)
               )
            {
                Print(infoShort,"invisible label is %s",c.data);
                if (file->lts->tau>=0) Abort("two silent labels");
                file->lts->tau=i;
            }
        }
        if (file->lts->tau<0) {
            Print(infoShort,"no silent label");
        }
    }
}
Пример #16
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);
    }
}