void lts_read(char *name,lts_t lts){ int format=lts_guess_format(name); switch(format){ case LTS_GCF: case LTS_DIR: { archive_t archive=format==LTS_DIR?arch_dir_open(name,65536):arch_gcf_read(raf_unistd(name)); stream_t ds=arch_read(archive,"info"); int magic=DSreadS32(ds); DSclose(&ds); if (magic==31) { // DIR in .dir lts_read_dir(archive,lts); arch_close(&archive); return; } else { // VEC in .dir arch_close(&archive); break; } } case LTS_TRA: lts_read_tra(name,lts); return; case LTS_IMCA: Abort("no read support for imca"); default: break; } lts_file_t src=lts_file_open(name); int segments=lts_file_get_segments(src); lts_type_t ltstype=lts_file_get_type(src); if (lts->ltstype==NULL){ lts_set_sig(lts,ltstype); } else { Print(info,"** warning ** omitting signature check"); } lts_file_t dst=lts_writer(lts,segments,src); int T=lts_type_get_type_count(ltstype); for(int i=0;i<T;i++){ if (lts->values[i]) lts_file_set_table(src,i,lts->values[i]); } lts_file_copy(src,dst); lts_file_close(src); lts_file_close(dst); }
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_write(char *name,lts_t lts,string_set_t filter,int segments){ int format=lts_guess_format(name); lts_type_t ltstype=lts->ltstype; switch(format){ case LTS_IMCA: lts_write_imca(name,lts); break; case LTS_TRA: lts_write_tra(name,lts); break; case LTS_PG: lts_write_pg(name,lts); break; case LTS_DIR: if (lts_type_get_state_length(ltstype)==0 && lts_type_get_state_label_count(ltstype)==0 && lts_type_get_edge_label_count(ltstype)==1 ){ archive_t archive=arch_dir_create(name,65536,DELETE_ALL); lts_write_dir(archive,NULL,lts,segments); arch_close(&archive); break; } else // fall through default: { lts_file_t src=lts_reader(lts,segments,NULL); lts_file_t dst; if (filter==NULL){ dst=lts_file_create(name,lts->ltstype,segments,src); } else { dst=lts_file_create_filter(name,lts->ltstype,filter,segments,src); } int T=lts_type_get_type_count(lts->ltstype); for(int i=0;i<T;i++){ if (lts->values[i]) lts_file_set_table(dst,i,lts->values[i]); } lts_file_copy(src,dst); lts_file_close(src); lts_file_close(dst); break; } } }
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; }
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); }