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(); }
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); }
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; } } }
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); }
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); }
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; }
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; } } }
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; }
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); }
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); }
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); }
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); }
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); }
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); }
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); } }
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); }
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); }
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); }
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); }
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); }