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(); }
int main(int argc, char *argv[]){ HREinitBegin(argv[0]); HREaddOptions(options,"Tool for signature minimization\n\nOptions"); char *files[2]; lts_lib_setup(); HREinitStart(&argc,&argv,1,2,files,"<input> [<output>]"); if (task==Undefined){ Abort("Please select the reduction to apply."); } lts_t lts=lts_create(); Debug("reading %s",files[0]); lts_read(files[0],lts); Print(infoShort,"input has %u states and %u transitions", lts->states,lts->transitions); switch(task){ case Strong:{ lowmem_strong_reduce(lts); break; } case Branching:{ bitset_t divergence=NULL; if (divergence_sensitive){ divergence=bitset_create(256,256); lts_find_divergent(lts,tau_step,NULL,divergence); } lowmem_branching_reduce(lts,divergence); break; } case Lumping:{ lowmem_lumping_reduce(lts); break; } case Copy:{ break; } case Silent:{ silent_compression(lts); break; } case Determinize:{ lts_mkdet(lts); break; } case Cycle:{ lts_cycle_elim(lts); break; } default: Abort("missing case"); } Print(infoShort,"reduced LTS has %u states and %u transitions", lts->states,lts->transitions); if (files[1]){ Debug("writing %s",files[1]); lts_write(files[1],lts,NULL,segments); Debug("output written"); } else { Debug("no output"); } HREexit(LTSMIN_EXIT_SUCCESS); }
lts_t lts_copy(lts_t orig){ lts_t copy=lts_create(); lts_set_sig(copy,orig->ltstype); lts_file_t src=lts_reader(orig,1,NULL); lts_file_t dst=lts_writer(copy,1,src); int T=lts_type_get_type_count(orig->ltstype); for(int i=0;i<T;i++){ if (orig->values[i]) { table_iterator_t it = VTiterator (orig->values[i]); for (int j = 0; IThasNext(it); j++) { chunk c = ITnext (it); VTputAtChunk (copy->values[i], c, j); } } } lts_file_copy(src,dst); lts_file_close(src); lts_file_close(dst); return copy; }
int main(int argc, char *argv[]){ char* files[2]; HREinitBegin(argv[0]); HREaddOptions(options,"Tool for transforming labeled transition systems\n\nOptions"); lts_lib_setup(); HREinitStart(&argc,&argv,1,2,files,"<input> [<output>]"); int me=HREme(HREglobal()); int peers=HREpeers(HREglobal()); if (peers>1) Abort("parallelizing this tool is future work");(void)me; string_set_t label_set=NULL; if (label_filter!=NULL){ label_set=SSMcreateSWPset(label_filter); } switch(task){ case Undefined: Abort("task unspecified"); case LTScopy: if (files[1]==NULL) Abort("second argument required for copy."); Print(infoShort,"streaming copy from %s to %s",files[0],files[1]); lts_file_t in=lts_file_open(files[0]); lts_type_t ltstype=lts_file_get_type(in); rd_seg=lts_file_get_segments(in); if (wr_seg==0) { wr_seg=rd_seg; } else { Abort("on-the-fly changing the number of segments is future work"); } lts_file_t out; if (label_set==NULL){ out=lts_file_create(files[1],ltstype,wr_seg,in); } else { out=lts_file_create_filter(files[1],ltstype,label_set,wr_seg,in); } int N=lts_type_get_type_count(ltstype); for(int i=0;i<N;i++){ char*name=lts_type_get_type(ltstype,i); switch(lts_type_get_format(ltstype,i)){ case LTStypeDirect: case LTStypeRange: Debug("integer type %s does not use tables",name); break; case LTStypeChunk: case LTStypeEnum: Debug("creating table for type %s",name); value_table_t tmp=chunk_table_create(NULL,name); Debug("set in %s",name); lts_file_set_table(in,i,tmp); Debug("set out %s",name); lts_file_set_table(out,i,tmp); break; } } lts_file_copy(in,out); lts_file_close(out); lts_file_close(in); break; case LTSrdwr: if (files[1]==NULL) Abort("second argument required for rdwr."); Print(infoShort,"loading from %s",files[0]); lts_t lts=lts_create(); lts_read(files[0],lts); if (encode) { Print(infoShort,"single edge label encoding"); lts=lts_encode_edge(lts); } if (bfs_reorder) { Print(infoShort,"reindexing LTS in BFS order"); lts_bfs_reorder(lts); } Print(infoShort,"storing in %s",files[1]); if(wr_seg==0) wr_seg=1; lts_write(files[1],lts,label_set,wr_seg); break; case LTSindex:{ if (peers>1) Abort("parallelizing this tool is future work"); if (files[1]==NULL) Abort("second argument required for index."); Print(infoShort,"opening %s",files[0]); lts_file_t in=lts_file_open(files[0]); lts_type_t ltstype=lts_file_get_type(in); int segments=lts_file_get_segments(in); lts_file_t settings=lts_get_template(in); if (lts_file_get_edge_owner(settings)!=SourceOwned) Abort("bad edge owner"); lts_file_set_dest_mode(settings,Index); lts_file_set_init_mode(settings,Index); Print(infoShort,"creating %s",files[1]); lts_file_t out=lts_file_create(files[1],ltstype,segments,settings); int N=lts_type_get_type_count(ltstype); for(int i=0;i<N;i++){ char*name=lts_type_get_type(ltstype,i); switch(lts_type_get_format(ltstype,i)){ case LTStypeDirect: case LTStypeRange: Debug("integer type %s does not use tables",name); break; case LTStypeChunk: case LTStypeEnum: Debug("creating table for type %s",name); value_table_t tmp=chunk_table_create(NULL,name); Debug("set in %s",name); lts_file_set_table(in,i,tmp); Debug("set out %s",name); lts_file_set_table(out,i,tmp); break; } } treedbs_t db[segments]; int SV=lts_type_get_state_length(ltstype); int SL=lts_type_get_state_label_count(ltstype); int K=lts_type_get_edge_label_count(ltstype); for(int i=0;i<segments;i++){ Print(info,"loading and copying states of segment %d",i); uint32_t state[SV]; uint32_t label[SL]; db[i]=TreeDBScreate(SV); int idx=0; while(lts_read_state(in,&i,state,label)){ int tmp=TreeFold(db[i],(int*)state); if (idx!=tmp){ Abort("unexpected index %u != %u",tmp,idx); } idx++; lts_write_state(out,i,(int*)state,label); } } Print(info,"converting initial states"); { uint32_t seg; uint32_t state[SV]; while(lts_read_init(in,(int*)&seg,state)){ int idx=TreeFold(db[seg],(int*)state); lts_write_init(out,seg,&idx); } } for(int i=0;i<segments;i++){ Print(info,"converting edges of segment %d",i); uint32_t src_state[1]; uint32_t dst_seg; uint32_t dst_state[SV]; uint32_t label[K]; while(lts_read_edge(in,&i,src_state,(int*)&dst_seg,dst_state,label)){ int idx=TreeFold(db[dst_seg],(int*)dst_state); lts_write_edge(out,i,src_state,dst_seg,&idx,label); } } lts_file_close(out); lts_file_close(in); } } Print(infoShort,"done"); HREexit(LTSMIN_EXIT_SUCCESS); }
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 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); }