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); }
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); }
int main (int argc, char **argv) { dlts_t lts; rt_timer_t timer; int oldN, oldM, tauN, tauM, N, M, i, j; char *files[2]; HREinitBegin(argv[0]); HREaddOptions(options,"Perform a distributed cycle elimination on the input.\n\nOptions"); lts_lib_setup(); HREselectMPI(); HREinitStart(&argc,&argv,1,2,files,"<input> [<output>]"); MPI_Comm_size (MPI_COMM_WORLD, &nodes); MPI_Comm_rank (MPI_COMM_WORLD, &me); timer = RTcreateTimer (); if (me == 0) Warning (info, "(tau)SCC elimination"); if (me == 0) RTstartTimer (timer); MPI_Barrier (MPI_COMM_WORLD); lts = dlts_read(MPI_COMM_WORLD,files[0]); oldN = lts->state_count[me]; oldM = 0; for (i = 0; i < lts->segment_count; i++) oldM += lts->transition_count[me][i]; MPI_Reduce (&oldN, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&oldM, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); if (me == 0) { oldN = i; oldM = j; Warning (info, "%d states and %d transitions", oldN, oldM); RTstopTimer (timer); RTprintTimer (info, timer, "***** reading the LTS took"); RTresetTimer (timer); RTstartTimer (timer); } MPI_Barrier (MPI_COMM_WORLD); switch (action) { case SCC_COLOR: dlts_elim_tauscc_colours (lts); break; case SCC_GROUP: if (!dlts_elim_tauscc_groups (lts)) { if (me == 0) Abort("cannot get it small enough!"); } MPI_Barrier (MPI_COMM_WORLD); break; default: if (me == 0) Abort("bad action %d", action); MPI_Barrier (MPI_COMM_WORLD); } MPI_Barrier (lts->comm); if (me == 0) { RTstopTimer (timer); RTprintTimer (info, timer, "***** SCC reduction took"); RTresetTimer (timer); RTstartTimer (timer); } // statistics... N = lts->state_count[me]; M = 0; for (i = 0; i < lts->segment_count; i++) M += lts->transition_count[me][i]; MPI_Reduce (&N, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&M, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); if (me == 0) { Warning (info, "LTS initial:%10d states and %10d transitions", oldN, oldM); Warning (info, "LTS reduced:%10d states [%3.3f] and %10d [%3.3f] transitions", i, 100 * i / (float)oldN, j, 100 * j / (float)oldM); } N = Nfinal + Nleft + Nhooked; M = Mfinal + Mhooked; MPI_Reduce (&N, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&M, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); tauN = i; tauM = j; N = Nfinal + Nleft; M = Mfinal; MPI_Reduce (&N, &i, 1, MPI_INT, MPI_SUM, 0, lts->comm); MPI_Reduce (&M, &j, 1, MPI_INT, MPI_SUM, 0, lts->comm); if (me == 0) { Warning (info, "TAU initial:%10d states [%3.3f] and %10d [%3.3f] transitions", tauN, 100 * tauN / (float)oldN, tauM, 100 * tauM / (float)oldM); Warning (info, "TAU reduced:%10d states [%3.3f] and %10d [%3.3f] transitions", i, 100 * i / (float)tauN, j, 100 * j / (float)tauM); } if (files[1]) { if (me == 0) Warning (info, "NOW WRITING"); dlts_writedir (lts, files[1]); } // if (lts != NULL) dlts_free(lts); HREexit(HRE_EXIT_SUCCESS); }
static void actual_main(void *arg) #endif { int argc = ((struct args_t*)arg)->argc; char **argv = ((struct args_t*)arg)->argv; /* initialize HRE */ HREinitBegin(argv[0]); HREaddOptions(options,"Perform a symbolic reachability analysis of <model>\n" "The optional output of this analysis is an ETF " "representation of the input\n\nOptions"); lts_lib_setup(); // add options for LTS library HREinitStart(&argc,&argv,1,2,files,"<model> [<etf>]"); /* initialize HRE on other workers */ init_hre(HREglobal()); /* check for unsupported options */ if (PINS_POR != PINS_POR_NONE) Abort("Partial-order reduction and symbolic model checking are not compatible."); if (inhibit_matrix != NULL && sat_strategy != NO_SAT) Abort("Maximal progress is incompatibale with saturation."); if (files[1] != NULL) { char *ext = strrchr(files[1], '.'); if (ext == NULL || ext == files[1]) { Abort("Output filename has no extension!"); } if (strcasecmp(ext, ".etf") != 0) { // not ETF if (!(vset_default_domain == VSET_Sylvan && strcasecmp(ext, ".bdd") == 0) && !(vset_default_domain == VSET_LDDmc && strcasecmp(ext, ".ldd") == 0)) { Abort("Only supported output formats are ETF, BDD (with --vset=sylvan) and LDD (with --vset=lddmc)"); } if (PINS_USE_GUARDS) { Abort("Exporting symbolic state space not comptabile with " "guard-splitting"); } } } #ifdef HAVE_SYLVAN if (!USE_PARALLELISM) { if (strategy == PAR_P) { strategy = BFS_P; Print(info, "Front-end not thread-safe; using --order=bfs-prev instead of --order=par-prev."); } else if (strategy == PAR) { strategy = BFS; Print(info, "Front-end not thread-safe; using --order=bfs instead of --order=par."); } } #endif /* turn off Lace for now to speed up while not using parallelism */ lace_suspend(); /* initialize the model and PINS wrappers */ init_model(files[0]); /* initialize action detection */ act_label = lts_type_find_edge_label_prefix (ltstype, LTSMIN_EDGE_TYPE_ACTION_PREFIX); if (act_label != -1) action_typeno = lts_type_get_edge_label_typeno(ltstype, act_label); if (act_detect != NULL) init_action_detection(); bitvector_create(&state_label_used, sLbls); if (inv_detect != NULL) init_invariant_detection(); else if (PINS_USE_GUARDS) { for (int i = 0; i < nGuards; i++) { bitvector_set(&state_label_used, i); } } init_maxsum(ltstype); /* turn on Lace again (for Sylvan) */ if (vset_default_domain==VSET_Sylvan || vset_default_domain==VSET_LDDmc) { lace_resume(); } if (next_union) vset_next_fn = vset_next_union_src; init_domain(VSET_IMPL_AUTOSELECT); vset_t initial = vset_create(domain, -1, NULL); int *src = RTmalloc (sizeof(int[N])); GBgetInitialState(model, src); vset_add(initial, src); Print(infoShort, "got initial state"); /* if writing .dot files, open directory first */ if (dot_dir != NULL) { DIR* dir = opendir(dot_dir); if (dir) { closedir(dir); } else if (ENOENT == errno) { Abort("Option 'dot-dir': directory '%s' does not exist", dot_dir); } else { Abort("Option 'dot-dir': failed opening directory '%s'", dot_dir); } } if (vset_dir != NULL) { DIR *dir = opendir(vset_dir); if (dir) { closedir(dir); } else if (errno == ENOENT) { Abort("Option 'save-levels': directory '%s' does not exist", vset_dir); } else { Abort("Option 'save-levels': failed opening directory '%s'", vset_dir); } } init_mu_calculus(); /* determine if we need to generate a symbolic parity game */ #ifdef LTSMIN_PBES bool spg = true; #else bool spg = GBhaveMucalc() ? true : false; #endif /* if spg, then initialize labeling stuff before reachability */ if (spg) { Print(infoShort, "Generating a Symbolic Parity Game (SPG)."); init_spg(model); } /* create timer */ reach_timer = RTcreateTimer(); /* fix level 0 */ visited = vset_create(domain, -1, NULL); vset_copy(visited, initial); /* check the invariants at level 0 */ check_invariants(visited, 0); /* run reachability */ run_reachability(visited, files[1]); /* report states */ final_stat_reporting(visited); /* save LTS */ if (files[1] != NULL) { char *ext = strrchr(files[1], '.'); if (strcasecmp(ext, ".etf") == 0) { do_output(files[1], visited); } else { // if not .etf, then the filename ends with .bdd or .ldd, symbolic LTS do_dd_output (initial, visited, files[1]); } } compute_maxsum(visited, domain); CHECK_MU(visited, src); if (max_mu_count > 0) { Print(info, "Mu-calculus peak nodes: %ld", max_mu_count); } /* optionally print counts of all group_next and group_explored sets */ final_final_stats_reporting (); if (spg) { // converting the LTS to a symbolic parity game, save and solve. lts_to_pg_solve (visited, src); } #ifdef HAVE_SYLVAN /* in case other Lace threads were still suspended... */ if (vset_default_domain!=VSET_Sylvan && vset_default_domain!=VSET_LDDmc) { lace_resume(); } else if (SYLVAN_STATS) { sylvan_stats_report(stderr); } #endif RTfree (src); GBExit(model); }