sanity: Replace tabulars by spaces in *.cc *.hh *.hxx

* bin/autfilt.cc, bin/common_aoutput.cc, bin/common_aoutput.hh,
bin/common_finput.cc, bin/common_finput.hh, bin/common_hoaread.cc,
bin/common_output.cc, bin/common_output.hh, bin/common_post.cc,
bin/common_post.hh, bin/common_r.hh, bin/common_range.cc,
bin/common_range.hh, bin/common_setup.cc, bin/common_trans.cc,
bin/common_trans.hh, bin/dstar2tgba.cc, bin/genltl.cc,
bin/ltl2tgba.cc, bin/ltl2tgta.cc, bin/ltlcross.cc, bin/ltldo.cc,
bin/ltlfilt.cc, bin/ltlgrind.cc, bin/randaut.cc, bin/randltl.cc,
bin/spot-x.cc, spot/graph/graph.hh, spot/graph/ngraph.hh,
spot/kripke/kripkegraph.hh, spot/ltsmin/ltsmin.cc,
spot/ltsmin/ltsmin.hh, spot/misc/bareword.cc, spot/misc/bitvect.cc,
spot/misc/bitvect.hh, spot/misc/common.hh, spot/misc/escape.cc,
spot/misc/fixpool.hh, spot/misc/formater.cc, spot/misc/hash.hh,
spot/misc/intvcmp2.cc, spot/misc/intvcmp2.hh, spot/misc/intvcomp.cc,
spot/misc/intvcomp.hh, spot/misc/location.hh, spot/misc/minato.cc,
spot/misc/minato.hh, spot/misc/mspool.hh, spot/misc/optionmap.cc,
spot/misc/optionmap.hh, spot/misc/random.cc, spot/misc/random.hh,
spot/misc/satsolver.cc, spot/misc/satsolver.hh, spot/misc/timer.cc,
spot/misc/timer.hh, spot/misc/tmpfile.cc, spot/misc/trival.hh,
spot/parseaut/fmterror.cc, spot/parseaut/parsedecl.hh,
spot/parseaut/public.hh, spot/parsetl/fmterror.cc,
spot/parsetl/parsedecl.hh, spot/priv/accmap.hh, spot/priv/bddalloc.cc,
spot/priv/freelist.cc, spot/priv/trim.cc, spot/priv/weight.cc,
spot/priv/weight.hh, spot/ta/taexplicit.cc, spot/ta/taexplicit.hh,
spot/ta/taproduct.cc, spot/ta/taproduct.hh, spot/ta/tgtaexplicit.cc,
spot/ta/tgtaexplicit.hh, spot/ta/tgtaproduct.cc,
spot/ta/tgtaproduct.hh, spot/taalgos/dot.cc, spot/taalgos/dot.hh,
spot/taalgos/emptinessta.cc, spot/taalgos/emptinessta.hh,
spot/taalgos/minimize.cc, spot/taalgos/tgba2ta.cc,
spot/taalgos/tgba2ta.hh, spot/tl/apcollect.cc, spot/tl/contain.cc,
spot/tl/contain.hh, spot/tl/dot.cc, spot/tl/exclusive.cc,
spot/tl/exclusive.hh, spot/tl/formula.cc, spot/tl/formula.hh,
spot/tl/length.cc, spot/tl/mark.cc, spot/tl/mutation.cc,
spot/tl/mutation.hh, spot/tl/parse.hh, spot/tl/print.cc,
spot/tl/print.hh, spot/tl/randomltl.cc, spot/tl/randomltl.hh,
spot/tl/relabel.cc, spot/tl/relabel.hh, spot/tl/remove_x.cc,
spot/tl/simplify.cc, spot/tl/simplify.hh, spot/tl/snf.cc,
spot/tl/snf.hh, spot/tl/unabbrev.cc, spot/tl/unabbrev.hh,
spot/twa/acc.cc, spot/twa/acc.hh, spot/twa/bdddict.cc,
spot/twa/bdddict.hh, spot/twa/bddprint.cc, spot/twa/formula2bdd.cc,
spot/twa/formula2bdd.hh, spot/twa/taatgba.cc, spot/twa/taatgba.hh,
spot/twa/twa.cc, spot/twa/twa.hh, spot/twa/twagraph.cc,
spot/twa/twagraph.hh, spot/twa/twaproduct.cc, spot/twa/twaproduct.hh,
spot/twaalgos/are_isomorphic.cc, spot/twaalgos/are_isomorphic.hh,
spot/twaalgos/bfssteps.cc, spot/twaalgos/bfssteps.hh,
spot/twaalgos/cleanacc.cc, spot/twaalgos/complete.cc,
spot/twaalgos/compsusp.cc, spot/twaalgos/compsusp.hh,
spot/twaalgos/copy.cc, spot/twaalgos/cycles.cc,
spot/twaalgos/cycles.hh, spot/twaalgos/degen.cc,
spot/twaalgos/degen.hh, spot/twaalgos/determinize.cc,
spot/twaalgos/determinize.hh, spot/twaalgos/dot.cc,
spot/twaalgos/dot.hh, spot/twaalgos/dtbasat.cc,
spot/twaalgos/dtbasat.hh, spot/twaalgos/dtwasat.cc,
spot/twaalgos/dtwasat.hh, spot/twaalgos/emptiness.cc,
spot/twaalgos/emptiness.hh, spot/twaalgos/emptiness_stats.hh,
spot/twaalgos/gtec/ce.cc, spot/twaalgos/gtec/ce.hh,
spot/twaalgos/gtec/gtec.cc, spot/twaalgos/gtec/gtec.hh,
spot/twaalgos/gtec/sccstack.cc, spot/twaalgos/gtec/status.cc,
spot/twaalgos/gv04.cc, spot/twaalgos/hoa.cc, spot/twaalgos/hoa.hh,
spot/twaalgos/isdet.cc, spot/twaalgos/isunamb.cc,
spot/twaalgos/isweakscc.cc, spot/twaalgos/lbtt.cc,
spot/twaalgos/lbtt.hh, spot/twaalgos/ltl2taa.cc,
spot/twaalgos/ltl2taa.hh, spot/twaalgos/ltl2tgba_fm.cc,
spot/twaalgos/ltl2tgba_fm.hh, spot/twaalgos/magic.cc,
spot/twaalgos/magic.hh, spot/twaalgos/mask.cc, spot/twaalgos/mask.hh,
spot/twaalgos/minimize.cc, spot/twaalgos/minimize.hh,
spot/twaalgos/ndfs_result.hxx, spot/twaalgos/neverclaim.cc,
spot/twaalgos/neverclaim.hh, spot/twaalgos/postproc.cc,
spot/twaalgos/postproc.hh, spot/twaalgos/powerset.cc,
spot/twaalgos/powerset.hh, spot/twaalgos/product.cc,
spot/twaalgos/product.hh, spot/twaalgos/projrun.cc,
spot/twaalgos/projrun.hh, spot/twaalgos/randomgraph.cc,
spot/twaalgos/randomgraph.hh, spot/twaalgos/randomize.cc,
spot/twaalgos/randomize.hh, spot/twaalgos/reachiter.cc,
spot/twaalgos/reachiter.hh, spot/twaalgos/relabel.cc,
spot/twaalgos/relabel.hh, spot/twaalgos/remfin.cc,
spot/twaalgos/remprop.cc, spot/twaalgos/sbacc.cc,
spot/twaalgos/sccfilter.cc, spot/twaalgos/sccfilter.hh,
spot/twaalgos/sccinfo.cc, spot/twaalgos/sccinfo.hh,
spot/twaalgos/se05.cc, spot/twaalgos/se05.hh,
spot/twaalgos/sepsets.cc, spot/twaalgos/simulation.cc,
spot/twaalgos/simulation.hh, spot/twaalgos/stats.cc,
spot/twaalgos/stats.hh, spot/twaalgos/strength.cc,
spot/twaalgos/strength.hh, spot/twaalgos/stripacc.cc,
spot/twaalgos/stutter.cc, spot/twaalgos/stutter.hh,
spot/twaalgos/tau03.cc, spot/twaalgos/tau03opt.cc,
spot/twaalgos/tau03opt.hh, spot/twaalgos/totgba.cc,
spot/twaalgos/translate.cc, spot/twaalgos/word.cc, tests/core/acc.cc,
tests/core/bitvect.cc, tests/core/checkpsl.cc, tests/core/checkta.cc,
tests/core/consterm.cc, tests/core/emptchk.cc, tests/core/equalsf.cc,
tests/core/graph.cc, tests/core/ikwiad.cc, tests/core/intvcmp2.cc,
tests/core/intvcomp.cc, tests/core/kind.cc, tests/core/kripkecat.cc,
tests/core/ltlrel.cc, tests/core/ngraph.cc, tests/core/randtgba.cc,
tests/core/readltl.cc, tests/core/reduc.cc, tests/core/safra.cc,
tests/core/syntimpl.cc, tests/ltsmin/modelcheck.cc: Replace tabulars by
8 spaces.
* tests/sanity/style.test: Add checks for no tabulars in *.cc *.hh *.hxx
This commit is contained in:
Laurent XU 2016-03-09 00:23:20 +01:00 committed by Alexandre Duret-Lutz
parent 1eee12b8b4
commit f7e7b4f14e
239 changed files with 25359 additions and 25355 deletions

View file

@ -363,9 +363,9 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case 'x':
{
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
}
break;
case OPT_AP_N:
@ -376,15 +376,15 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case OPT_ACCEPT_WORD:
try
{
opt->acc_words.push_back(spot::parse_word(arg, opt->dict)
->as_automaton());
}
{
opt->acc_words.push_back(spot::parse_word(arg, opt->dict)
->as_automaton());
}
catch (const spot::parse_error& e)
{
error(2, 0, "failed to parse the argument of --accept-word:\n%s",
e.what());
}
{
error(2, 0, "failed to parse the argument of --accept-word:\n%s",
e.what());
}
break;
case OPT_ARE_ISOMORPHIC:
opt->are_isomorphic = read_automaton(arg, opt->dict);
@ -420,27 +420,27 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case OPT_EQUIVALENT_TO:
if (opt->equivalent_pos)
error(2, 0, "only one --equivalent-to option can be given");
error(2, 0, "only one --equivalent-to option can be given");
opt->equivalent_pos = read_automaton(arg, opt->dict);
opt->equivalent_neg =
spot::dtwa_complement(ensure_deterministic(opt->equivalent_pos));
spot::dtwa_complement(ensure_deterministic(opt->equivalent_pos));
break;
case OPT_INSTUT:
if (!arg || (arg[0] == '1' && arg[1] == 0))
opt_instut = 1;
opt_instut = 1;
else if (arg[0] == '2' && arg[1] == 0)
opt_instut = 2;
opt_instut = 2;
else
error(2, 0, "unknown argument for --instut: %s", arg);
error(2, 0, "unknown argument for --instut: %s", arg);
break;
case OPT_INCLUDED_IN:
{
auto aut = ensure_deterministic(read_automaton(arg, opt->dict));
aut = spot::dtwa_complement(aut);
if (!opt->included_in)
opt->included_in = aut;
else
opt->included_in = spot::product_or(opt->included_in, aut);
auto aut = ensure_deterministic(read_automaton(arg, opt->dict));
aut = spot::dtwa_complement(aut);
if (!opt->included_in)
opt->included_in = aut;
else
opt->included_in = spot::product_or(opt->included_in, aut);
}
break;
case OPT_INTERSECT:
@ -472,18 +472,18 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case OPT_MASK_ACC:
{
for (auto res : to_longs(arg))
{
if (res < 0)
error(2, 0, "acceptance sets should be non-negative:"
" --mask-acc=%ld", res);
if (static_cast<unsigned long>(res)
> sizeof(spot::acc_cond::mark_t::value_t))
error(2, 0, "this implementation does not support that many"
" acceptance sets: --mask-acc=%ld", res);
opt_mask_acc.set(res);
}
break;
for (auto res : to_longs(arg))
{
if (res < 0)
error(2, 0, "acceptance sets should be non-negative:"
" --mask-acc=%ld", res);
if (static_cast<unsigned long>(res)
> sizeof(spot::acc_cond::mark_t::value_t))
error(2, 0, "this implementation does not support that many"
" acceptance sets: --mask-acc=%ld", res);
opt_mask_acc.set(res);
}
break;
}
case OPT_KEEP_STATES:
{
@ -491,71 +491,71 @@ parse_opt(int key, char* arg, struct argp_state*)
if (!values.empty())
opt_keep_states_initial = values[0];
for (auto res : values)
{
if (res < 0)
error(2, 0, "state ids should be non-negative:"
" --mask-acc=%ld", res);
{
if (res < 0)
error(2, 0, "state ids should be non-negative:"
" --mask-acc=%ld", res);
// We don't know yet how many states the automata contain.
if (opt_keep_states.size() <= static_cast<unsigned long>(res))
opt_keep_states.resize(res + 1, false);
opt_keep_states[res] = true;
}
opt_rem_unreach = true;
break;
opt_keep_states[res] = true;
}
opt_rem_unreach = true;
break;
}
case OPT_PRODUCT_AND:
{
auto a = read_automaton(arg, opt->dict);
if (!opt->product_and)
opt->product_and = std::move(a);
else
opt->product_and = spot::product(std::move(opt->product_and),
std::move(a));
auto a = read_automaton(arg, opt->dict);
if (!opt->product_and)
opt->product_and = std::move(a);
else
opt->product_and = spot::product(std::move(opt->product_and),
std::move(a));
}
break;
case OPT_PRODUCT_OR:
{
auto a = read_automaton(arg, opt->dict);
if (!opt->product_or)
opt->product_or = std::move(a);
else
opt->product_or = spot::product_or(std::move(opt->product_or),
std::move(a));
auto a = read_automaton(arg, opt->dict);
if (!opt->product_or)
opt->product_or = std::move(a);
else
opt->product_or = spot::product_or(std::move(opt->product_or),
std::move(a));
}
break;
case OPT_RANDOMIZE:
if (arg)
{
for (auto p = arg; *p; ++p)
switch (*p)
{
case 's':
randomize_st = true;
break;
case 't':
randomize_tr = true;
break;
default:
error(2, 0, "unknown argument for --randomize: '%c'", *p);
}
}
{
for (auto p = arg; *p; ++p)
switch (*p)
{
case 's':
randomize_st = true;
break;
case 't':
randomize_tr = true;
break;
default:
error(2, 0, "unknown argument for --randomize: '%c'", *p);
}
}
else
{
randomize_tr = true;
randomize_st = true;
}
{
randomize_tr = true;
randomize_st = true;
}
break;
case OPT_REJECT_WORD:
try
{
opt->rej_words.push_back(spot::parse_word(arg, opt->dict)
->as_automaton());
}
{
opt->rej_words.push_back(spot::parse_word(arg, opt->dict)
->as_automaton());
}
catch (const spot::parse_error& e)
{
error(2, 0, "failed to parse the argument of --reject-word:\n%s",
e.what());
}
{
error(2, 0, "failed to parse the argument of --reject-word:\n%s",
e.what());
}
break;
case OPT_REM_AP:
opt->rem_ap.add_ap(arg);
@ -621,7 +621,7 @@ namespace
int
process_automaton(const spot::const_parsed_aut_ptr& haut,
const char* filename)
const char* filename)
{
spot::stopwatch sw;
sw.start();
@ -630,30 +630,30 @@ namespace
// never modify the original automaton (e.g. with
// merge_edges()) and the statistics about it make sense.
auto aut = ((automaton_format == Stats) || opt_name)
? spot::make_twa_graph(haut->aut, spot::twa::prop_set::all())
: haut->aut;
? spot::make_twa_graph(haut->aut, spot::twa::prop_set::all())
: haut->aut;
// Preprocessing.
if (opt_stripacc)
spot::strip_acceptance_here(aut);
spot::strip_acceptance_here(aut);
if (opt_merge)
aut->merge_edges();
aut->merge_edges();
if (opt_clean_acc || opt_rem_fin)
cleanup_acceptance_here(aut);
cleanup_acceptance_here(aut);
if (opt_sep_sets)
separate_sets_here(aut);
separate_sets_here(aut);
if (opt_complement_acc)
aut->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().complement());
aut->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().complement());
if (opt_rem_fin)
aut = remove_fin(aut);
aut = remove_fin(aut);
if (opt_dnf_acc)
aut->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().to_dnf());
aut->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().to_dnf());
if (opt_cnf_acc)
aut->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().to_cnf());
aut->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().to_cnf());
// Filters.
@ -664,46 +664,46 @@ namespace
matched &= opt_accsets.contains(aut->acc().num_sets());
matched &= opt_ap_n.contains(aut->ap().size());
if (opt_is_complete)
matched &= is_complete(aut);
matched &= is_complete(aut);
if (opt_is_deterministic)
matched &= is_deterministic(aut);
matched &= is_deterministic(aut);
if (opt_is_deterministic)
matched &= is_deterministic(aut);
matched &= is_deterministic(aut);
else if (opt_is_unambiguous)
matched &= is_unambiguous(aut);
matched &= is_unambiguous(aut);
if (opt_is_terminal)
matched &= is_terminal_automaton(aut);
matched &= is_terminal_automaton(aut);
else if (opt_is_weak)
matched &= is_weak_automaton(aut);
matched &= is_weak_automaton(aut);
else if (opt_is_inherently_weak)
matched &= is_inherently_weak_automaton(aut);
matched &= is_inherently_weak_automaton(aut);
if (opt->are_isomorphic)
matched &= opt->isomorphism_checker->is_isomorphic(aut);
if (opt_is_empty)
matched &= aut->is_empty();
matched &= aut->is_empty();
if (opt->intersect)
matched &= !spot::product(aut, opt->intersect)->is_empty();
matched &= !spot::product(aut, opt->intersect)->is_empty();
if (opt->included_in)
matched &= spot::product(aut, opt->included_in)->is_empty();
matched &= spot::product(aut, opt->included_in)->is_empty();
if (opt->equivalent_pos)
matched &= spot::product(aut, opt->equivalent_neg)->is_empty()
&& spot::product(dtwa_complement(ensure_deterministic(aut)),
opt->equivalent_pos)->is_empty();
matched &= spot::product(aut, opt->equivalent_neg)->is_empty()
&& spot::product(dtwa_complement(ensure_deterministic(aut)),
opt->equivalent_pos)->is_empty();
if (matched && !opt->acc_words.empty())
for (auto& word_aut: opt->acc_words)
if (spot::product(aut, word_aut)->is_empty())
{
matched = false;
break;
}
for (auto& word_aut: opt->acc_words)
if (spot::product(aut, word_aut)->is_empty())
{
matched = false;
break;
}
if (matched && !opt->rej_words.empty())
for (auto& word_aut: opt->rej_words)
if (!spot::product(aut, word_aut)->is_empty())
{
matched = false;
break;
}
for (auto& word_aut: opt->rej_words)
if (!spot::product(aut, word_aut)->is_empty())
{
matched = false;
break;
}
// Drop or keep matched automata depending on the --invert option
if (matched == opt_invert)
@ -712,65 +712,65 @@ namespace
// Postprocessing.
if (opt_mask_acc)
aut = mask_acc_sets(aut, opt_mask_acc & aut->acc().all_sets());
aut = mask_acc_sets(aut, opt_mask_acc & aut->acc().all_sets());
if (!opt->excl_ap.empty())
aut = opt->excl_ap.constrain(aut, opt_simplify_exclusive_ap);
aut = opt->excl_ap.constrain(aut, opt_simplify_exclusive_ap);
if (!opt->rem_ap.empty())
aut = opt->rem_ap.strip(aut);
aut = opt->rem_ap.strip(aut);
if (opt_destut)
aut = spot::closure(std::move(aut));
aut = spot::closure(std::move(aut));
if (opt_instut == 1)
aut = spot::sl(std::move(aut));
aut = spot::sl(std::move(aut));
else if (opt_instut == 2)
aut = spot::sl2(std::move(aut));
aut = spot::sl2(std::move(aut));
if (!opt_keep_states.empty())
aut = mask_keep_states(aut, opt_keep_states, opt_keep_states_initial);
aut = mask_keep_states(aut, opt_keep_states, opt_keep_states_initial);
if (opt_rem_dead)
aut->purge_dead_states();
aut->purge_dead_states();
else if (opt_rem_unreach)
aut->purge_unreachable_states();
aut->purge_unreachable_states();
if (opt->product_and)
aut = spot::product(std::move(aut), opt->product_and);
aut = spot::product(std::move(aut), opt->product_and);
if (opt->product_or)
aut = spot::product_or(std::move(aut), opt->product_or);
aut = spot::product_or(std::move(aut), opt->product_or);
if (opt_decompose_strength)
{
aut = decompose_strength(aut, opt_decompose_strength);
if (!aut)
return 0;
}
{
aut = decompose_strength(aut, opt_decompose_strength);
if (!aut)
return 0;
}
if (opt_sat_minimize)
{
aut = spot::sat_minimize(aut, opt_sat_minimize, sbacc);
if (!aut)
return 0;
}
{
aut = spot::sat_minimize(aut, opt_sat_minimize, sbacc);
if (!aut)
return 0;
}
if (opt_complement)
aut = spot::dtwa_complement(ensure_deterministic(aut));
aut = spot::dtwa_complement(ensure_deterministic(aut));
aut = post.run(aut, nullptr);
if (randomize_st || randomize_tr)
spot::randomize(aut, randomize_st, randomize_tr);
spot::randomize(aut, randomize_st, randomize_tr);
const double conversion_time = sw.stop();
if (opt->uniq)
{
auto tmp =
spot::canonicalize(make_twa_graph(aut,
spot::twa::prop_set::all()));
spot::canonicalize(make_twa_graph(aut,
spot::twa::prop_set::all()));
if (!opt->uniq->emplace(tmp->edge_vector().begin() + 1,
tmp->edge_vector().end()).second)
return 0;
tmp->edge_vector().end()).second)
return 0;
}
++match_count;
@ -778,7 +778,7 @@ namespace
printer.print(aut, nullptr, filename, -1, conversion_time, haut);
if (opt_max_count >= 0 && match_count >= opt_max_count)
abort_run = true;
abort_run = true;
return 0;
}
@ -796,19 +796,19 @@ namespace
auto hp = spot::automaton_stream_parser(filename, opt_parse);
int err = 0;
while (!abort_run)
{
auto haut = hp.parse(opt->dict);
if (!haut->aut && haut->errors.empty())
break;
if (haut->format_errors(std::cerr))
err = 2;
if (!haut->aut)
error(2, 0, "failed to read automaton from %s", filename);
else if (haut->aborted)
err = std::max(err, aborted(haut, filename));
else
{
auto haut = hp.parse(opt->dict);
if (!haut->aut && haut->errors.empty())
break;
if (haut->format_errors(std::cerr))
err = 2;
if (!haut->aut)
error(2, 0, "failed to read automaton from %s", filename);
else if (haut->aborted)
err = std::max(err, aborted(haut, filename));
else
process_automaton(haut, filename);
}
}
return err;
}
};
@ -820,7 +820,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "[FILENAMES...]",
argp_program_doc, children, nullptr, nullptr };
argp_program_doc, children, nullptr, nullptr };
try
{
@ -834,23 +834,23 @@ main(int argc, char** argv)
pref = spot::postprocessor::Any;
type = spot::postprocessor::Generic;
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
exit(err);
if (level_set && !pref_set)
pref = spot::postprocessor::Small;
pref = spot::postprocessor::Small;
if (pref_set && !level_set)
level = spot::postprocessor::High;
level = spot::postprocessor::High;
if (jobs.empty())
jobs.emplace_back("-", true);
jobs.emplace_back("-", true);
if (opt->are_isomorphic)
{
if (opt_merge)
opt->are_isomorphic->merge_edges();
opt->isomorphism_checker = std::unique_ptr<spot::isomorphism_checker>
(new spot::isomorphism_checker(opt->are_isomorphic));
}
{
if (opt_merge)
opt->are_isomorphic->merge_edges();
opt->isomorphism_checker = std::unique_ptr<spot::isomorphism_checker>
(new spot::isomorphism_checker(opt->are_isomorphic));
}
spot::srand(opt_seed);
@ -862,7 +862,7 @@ main(int argc, char** argv)
hoa_processor processor(post);
if (processor.run())
return 2;
return 2;
}
catch (const std::runtime_error& e)
{

View file

@ -136,7 +136,7 @@ static const argp_option options[] =
};
const struct argp aoutput_argp = { options, parse_opt_aoutput, nullptr, nullptr,
nullptr, nullptr, nullptr };
nullptr, nullptr, nullptr };
// Those can be overridden by individual tools. E.g. randaut has no
// notion of input file, so %F and %L represent something else.
@ -181,8 +181,8 @@ static const argp_option io_options[] =
};
const struct argp aoutput_io_format_argp = { io_options, nullptr, nullptr,
nullptr, nullptr,
nullptr, nullptr };
nullptr, nullptr,
nullptr, nullptr };
static const argp_option o_options[] =
{
@ -221,8 +221,8 @@ static const argp_option o_options[] =
};
const struct argp aoutput_o_format_argp = { o_options,
nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr };
nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr };
int parse_opt_aoutput(int key, char* arg, struct argp_state*)
{
@ -249,15 +249,15 @@ int parse_opt_aoutput(int key, char* arg, struct argp_state*)
case 's':
automaton_format = Spin;
if (type != spot::postprocessor::Monitor)
type = spot::postprocessor::BA;
type = spot::postprocessor::BA;
automaton_format_opt = arg;
break;
case OPT_CHECK:
automaton_format = Hoa;
if (arg)
opt_check |= XARGMATCH("--check", arg, check_args, check_types);
opt_check |= XARGMATCH("--check", arg, check_args, check_types);
else
opt_check |= check_all;
opt_check |= check_all;
break;
case OPT_LBTT:
automaton_format = Lbtt;
@ -266,14 +266,14 @@ int parse_opt_aoutput(int key, char* arg, struct argp_state*)
// because print_lbtt will raise an exception anyway. The
// error message is slightly better in the current way.
if (arg && (arg[0] != 't' || arg[1] != 0))
error(2, 0, "unknown argument for --lbtt: '%s'", arg);
error(2, 0, "unknown argument for --lbtt: '%s'", arg);
break;
case OPT_NAME:
opt_name = arg;
break;
case OPT_STATS:
if (!*arg)
error(2, 0, "empty format string for --stats");
error(2, 0, "empty format string for --stats");
stats = arg;
automaton_format = Stats;
break;
@ -288,23 +288,23 @@ void setup_default_output_format()
if (auto val = getenv("SPOT_DEFAULT_FORMAT"))
{
static char const *const args[] =
{
"dot", "hoa", "hoaf", nullptr
};
{
"dot", "hoa", "hoaf", nullptr
};
static automaton_format_t const format[] =
{
Dot, Hoa, Hoa
};
{
Dot, Hoa, Hoa
};
auto eq = strchr(val, '=');
if (eq)
{
val = strndup(val, eq - val);
automaton_format_opt = eq + 1;
}
{
val = strndup(val, eq - val);
automaton_format_opt = eq + 1;
}
ARGMATCH_VERIFY(args, format);
automaton_format = XARGMATCH("SPOT_DEFAULT_FORMAT", val, args, format);
if (eq)
free(val);
free(val);
}
}
@ -320,24 +320,24 @@ automaton_printer::automaton_printer(stat_style input)
void
automaton_printer::print(const spot::twa_graph_ptr& aut,
spot::formula f,
// Input location for errors and statistics.
const char* filename,
int loc,
// Time and input automaton for statistics
double time,
const spot::const_parsed_aut_ptr& haut,
const char* csv_prefix,
const char* csv_suffix)
spot::formula f,
// Input location for errors and statistics.
const char* filename,
int loc,
// Time and input automaton for statistics
double time,
const spot::const_parsed_aut_ptr& haut,
const char* csv_prefix,
const char* csv_suffix)
{
if (opt_check)
{
if (opt_check & check_stutter)
spot::check_stutter_invariance(aut, f);
spot::check_stutter_invariance(aut, f);
if (opt_check & check_unambiguous)
spot::check_unambiguous(aut);
spot::check_unambiguous(aut);
if (opt_check & check_strength)
spot::check_strength(aut);
spot::check_strength(aut);
}
// Name the output automaton.
@ -353,11 +353,11 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
{
outputname.str("");
outputnamer.print(haut, aut, f, filename, loc, time,
csv_prefix, csv_suffix);
csv_prefix, csv_suffix);
std::string fname = outputname.str();
auto p = outputfiles.emplace(fname, nullptr);
if (p.second)
p.first->second.reset(new output_file(fname.c_str()));
p.first->second.reset(new output_file(fname.c_str()));
out = &p.first->second->ostream();
}
@ -383,7 +383,7 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
case Stats:
statistics.set_output(*out);
statistics.print(haut, aut, f, filename, loc, time,
csv_prefix, csv_suffix) << '\n';
csv_prefix, csv_suffix) << '\n';
break;
}
flush_cout();

View file

@ -75,25 +75,25 @@ class hoa_stat_printer: protected spot::stat_printer
{
public:
hoa_stat_printer(std::ostream& os, const char* format,
stat_style input = no_input)
stat_style input = no_input)
: spot::stat_printer(os, format)
{
if (input == aut_input)
{
declare('A', &haut_acc_);
declare('C', &haut_scc_);
declare('E', &haut_edges_);
declare('G', &haut_gen_acc_);
declare('M', &haut_name_);
declare('S', &haut_states_);
declare('T', &haut_trans_);
declare('A', &haut_acc_);
declare('C', &haut_scc_);
declare('E', &haut_edges_);
declare('G', &haut_gen_acc_);
declare('M', &haut_name_);
declare('S', &haut_states_);
declare('T', &haut_trans_);
}
declare('<', &csv_prefix_);
declare('>', &csv_suffix_);
declare('F', &filename_);
declare('L', &location_);
if (input != ltl_input)
declare('f', &filename_); // Override the formula printer.
declare('f', &filename_); // Override the formula printer.
declare('m', &aut_name_);
declare('w', &aut_word_);
}
@ -107,93 +107,93 @@ public:
/// to be output.
std::ostream&
print(const spot::const_parsed_aut_ptr& haut,
const spot::const_twa_graph_ptr& aut,
spot::formula f,
const char* filename, int loc, double run_time,
const char* csv_prefix, const char* csv_suffix)
const spot::const_twa_graph_ptr& aut,
spot::formula f,
const char* filename, int loc, double run_time,
const char* csv_prefix, const char* csv_suffix)
{
filename_ = filename ? filename : "";
csv_prefix_ = csv_prefix ? csv_prefix : "";
csv_suffix_ = csv_suffix ? csv_suffix : "";
if (loc >= 0 && has('L'))
{
std::ostringstream os;
os << loc;
location_ = os.str();
std::ostringstream os;
os << loc;
location_ = os.str();
}
if (haut)
{
if (loc < 0 && has('L'))
{
std::ostringstream os;
os << haut->loc;
location_ = os.str();
}
if (loc < 0 && has('L'))
{
std::ostringstream os;
os << haut->loc;
location_ = os.str();
}
if (has('T'))
{
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
haut_states_ = s.states;
haut_edges_ = s.edges;
haut_trans_ = s.transitions;
}
else if (has('E'))
{
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
haut_states_ = s.states;
haut_edges_ = s.edges;
}
if (has('M'))
{
auto n = haut->aut->get_named_prop<std::string>("automaton-name");
if (n)
haut_name_ = *n;
else
haut_name_.val().clear();
}
if (has('S'))
haut_states_ = haut->aut->num_states();
if (has('T'))
{
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
haut_states_ = s.states;
haut_edges_ = s.edges;
haut_trans_ = s.transitions;
}
else if (has('E'))
{
spot::twa_sub_statistics s = sub_stats_reachable(haut->aut);
haut_states_ = s.states;
haut_edges_ = s.edges;
}
if (has('M'))
{
auto n = haut->aut->get_named_prop<std::string>("automaton-name");
if (n)
haut_name_ = *n;
else
haut_name_.val().clear();
}
if (has('S'))
haut_states_ = haut->aut->num_states();
if (has('A'))
haut_acc_ = haut->aut->acc().num_sets();
if (has('A'))
haut_acc_ = haut->aut->acc().num_sets();
if (has('C'))
haut_scc_ = spot::scc_info(haut->aut).scc_count();
if (has('C'))
haut_scc_ = spot::scc_info(haut->aut).scc_count();
if (has('G'))
{
std::ostringstream os;
os << haut->aut->get_acceptance();
haut_gen_acc_ = os.str();
}
if (has('G'))
{
std::ostringstream os;
os << haut->aut->get_acceptance();
haut_gen_acc_ = os.str();
}
}
if (has('m'))
{
auto n = aut->get_named_prop<std::string>("automaton-name");
if (n)
aut_name_ = *n;
else
aut_name_.val().clear();
}
{
auto n = aut->get_named_prop<std::string>("automaton-name");
if (n)
aut_name_ = *n;
else
aut_name_.val().clear();
}
if (has('w'))
{
auto res = spot::couvreur99(aut)->check();
if (res)
{
auto run = res->accepting_run();
assert(run);
spot::twa_word w(run->reduce());
w.simplify();
std::ostringstream out;
out << w;
aut_word_ = out.str();
}
else
{
aut_word_.val().clear();
}
}
{
auto res = spot::couvreur99(aut)->check();
if (res)
{
auto run = res->accepting_run();
assert(run);
spot::twa_word w(run->reduce());
w.simplify();
std::ostringstream out;
out << w;
aut_word_ = out.str();
}
else
{
aut_word_.val().clear();
}
}
return this->spot::stat_printer::print(aut, f, run_time);
}
@ -230,15 +230,15 @@ public:
void
print(const spot::twa_graph_ptr& aut,
spot::formula f = nullptr,
// Input location for errors and statistics.
const char* filename = nullptr,
int loc = -1,
// Time and input automaton for statistics
double time = 0.0,
const spot::const_parsed_aut_ptr& haut = nullptr,
const char* csv_prefix = nullptr,
const char* csv_suffix = nullptr);
spot::formula f = nullptr,
// Input location for errors and statistics.
const char* filename = nullptr,
int loc = -1,
// Time and input automaton for statistics
double time = 0.0,
const spot::const_parsed_aut_ptr& haut = nullptr,
const char* csv_prefix = nullptr,
const char* csv_suffix = nullptr);
void add_stat(char c, const spot::printable* p);
};

View file

@ -49,8 +49,8 @@ static const argp_option options[] =
};
const struct argp finput_argp = { options, parse_opt_finput,
nullptr, nullptr, nullptr,
nullptr, nullptr };
nullptr, nullptr, nullptr,
nullptr, nullptr };
int
parse_opt_finput(int key, char* arg, struct argp_state*)
@ -105,15 +105,15 @@ job_processor::~job_processor()
int
job_processor::process_string(const std::string& input,
const char* filename,
int linenum)
const char* filename,
int linenum)
{
auto pf = parse_formula(input);
if (!pf.f || !pf.errors.empty())
{
if (filename)
error_at_line(0, 0, filename, linenum, "parse error:");
error_at_line(0, 0, filename, linenum, "parse error:");
pf.format_errors(std::cerr);
return 1;
}
@ -122,7 +122,7 @@ job_processor::process_string(const std::string& input,
int
job_processor::process_stream(std::istream& is,
const char* filename)
const char* filename)
{
int error = 0;
int linenum = 1;
@ -141,148 +141,148 @@ job_processor::process_stream(std::istream& is,
while (!abort_run && std::getline(is, line))
if (!line.empty())
{
if (col_to_read == 0)
{
error |= process_string(line, filename, linenum++);
}
else // We are reading column COL_TO_READ in a CSV file.
{
// If the line we have read contains an odd number
// of double-quotes, then it is an incomplete CSV line
// that should be completed by the next lines.
unsigned dquotes = 0;
std::string fullline;
unsigned csvlines = 0;
do
{
++csvlines;
size_t s = line.size();
for (unsigned i = 0; i < s; ++i)
dquotes += line[i] == '"';
if (fullline.empty())
fullline = line;
else
(fullline += '\n') += line;
if (!(dquotes &= 1))
break;
}
while (std::getline(is, line));
if (dquotes)
error_at_line(2, errno, filename, linenum,
"mismatched double-quote, "
"reached EOF while parsing this line");
if (col_to_read == 0)
{
error |= process_string(line, filename, linenum++);
}
else // We are reading column COL_TO_READ in a CSV file.
{
// If the line we have read contains an odd number
// of double-quotes, then it is an incomplete CSV line
// that should be completed by the next lines.
unsigned dquotes = 0;
std::string fullline;
unsigned csvlines = 0;
do
{
++csvlines;
size_t s = line.size();
for (unsigned i = 0; i < s; ++i)
dquotes += line[i] == '"';
if (fullline.empty())
fullline = line;
else
(fullline += '\n') += line;
if (!(dquotes &= 1))
break;
}
while (std::getline(is, line));
if (dquotes)
error_at_line(2, errno, filename, linenum,
"mismatched double-quote, "
"reached EOF while parsing this line");
// Now that we have a full CSV line, extract the right
// column.
// Now that we have a full CSV line, extract the right
// column.
const char* str = fullline.c_str();
const char* col1_start = str;
// Delimiters for the extracted column.
const char* coln_start = str;
const char* coln_end = nullptr;
// The current column. (1-based)
int colnum = 1;
// Whether we are parsing a double-quoted string.
bool instring = false;
// Note that RFC 4180 has strict rules about
// double-quotes: ① if a field is double-quoted, the first
// and last characters of the field should be
// double-quotes; ② if a field contains a double-quote
// then it should be double quoted, and the occurrences
// of double-quotes should be doubled. Therefore a CSV file
// may no contain a line such as:
// foo,bar"ba""z",12
// Tools have different interpretation of such a line.
// For instance Python's pandas.read_csv() function will
// load the second field verbatim as the string 'bar"ba""z"',
// while R's read.csv() function will load it as the
// string 'barba"z'. We use this second interpretation, because
// it also makes it possible to parse CSVs fields formatted
// with leading spaces (often for cosmetic purpose). When
// extracting the second field of
// foo, "ba""z", 12
// we will return ' baz' and the leading space will be ignored
// by our LTL formula parser.
while (*str)
{
switch (*str)
{
case '"':
// Doubled double-quotes are used to escape
// double-quotes.
if (instring && str[1] == '"')
++str;
else
instring = !instring;
break;
case ',':
if (!instring)
{
if (col_to_read == colnum)
coln_end = str;
++colnum;
if (col_to_read == colnum)
coln_start = str + 1;
}
break;
}
// Once we have the end delimiter for our target
// column, we have all we need.
if (coln_end)
break;
++str;
}
if (!*str)
{
if (colnum != col_to_read)
// Skip this line as it has no enough columns.
continue;
else
// The target columns ends at the end of the line.
coln_end = str;
}
const char* str = fullline.c_str();
const char* col1_start = str;
// Delimiters for the extracted column.
const char* coln_start = str;
const char* coln_end = nullptr;
// The current column. (1-based)
int colnum = 1;
// Whether we are parsing a double-quoted string.
bool instring = false;
// Note that RFC 4180 has strict rules about
// double-quotes: ① if a field is double-quoted, the first
// and last characters of the field should be
// double-quotes; ② if a field contains a double-quote
// then it should be double quoted, and the occurrences
// of double-quotes should be doubled. Therefore a CSV file
// may no contain a line such as:
// foo,bar"ba""z",12
// Tools have different interpretation of such a line.
// For instance Python's pandas.read_csv() function will
// load the second field verbatim as the string 'bar"ba""z"',
// while R's read.csv() function will load it as the
// string 'barba"z'. We use this second interpretation, because
// it also makes it possible to parse CSVs fields formatted
// with leading spaces (often for cosmetic purpose). When
// extracting the second field of
// foo, "ba""z", 12
// we will return ' baz' and the leading space will be ignored
// by our LTL formula parser.
while (*str)
{
switch (*str)
{
case '"':
// Doubled double-quotes are used to escape
// double-quotes.
if (instring && str[1] == '"')
++str;
else
instring = !instring;
break;
case ',':
if (!instring)
{
if (col_to_read == colnum)
coln_end = str;
++colnum;
if (col_to_read == colnum)
coln_start = str + 1;
}
break;
}
// Once we have the end delimiter for our target
// column, we have all we need.
if (coln_end)
break;
++str;
}
if (!*str)
{
if (colnum != col_to_read)
// Skip this line as it has no enough columns.
continue;
else
// The target columns ends at the end of the line.
coln_end = str;
}
// Skip the line if it has an empty field.
if (coln_start == coln_end)
continue;
// Skip the line if it has an empty field.
if (coln_start == coln_end)
continue;
// save the contents before and after that columns for the
// %< and %> escapes (ignoring the trailing and leading
// commas).
prefix = (col_to_read != 1) ?
strndup(col1_start, coln_start - col1_start - 1) : nullptr;
suffix = (*coln_end != 0) ? strdup(coln_end + 1) : nullptr;
std::string field(coln_start, coln_end);
// Remove double-quotes if any.
if (field.find('"') != std::string::npos)
{
unsigned dst = 0;
bool instring = false;
for (; coln_start != coln_end; ++coln_start)
if (*coln_start == '"')
// A doubled double-quote instead a double-quoted
// string is an escaped double-quote.
if (instring && coln_start[1] == '"')
field[dst++] = *++coln_start;
else
instring = !instring;
else
field[dst++] = *coln_start;
field.resize(dst);
}
error |= process_string(field, filename, linenum);
linenum += csvlines;
if (prefix)
{
free(prefix);
prefix = nullptr;
}
if (suffix)
{
free(suffix);
suffix = nullptr;
}
}
// save the contents before and after that columns for the
// %< and %> escapes (ignoring the trailing and leading
// commas).
prefix = (col_to_read != 1) ?
strndup(col1_start, coln_start - col1_start - 1) : nullptr;
suffix = (*coln_end != 0) ? strdup(coln_end + 1) : nullptr;
std::string field(coln_start, coln_end);
// Remove double-quotes if any.
if (field.find('"') != std::string::npos)
{
unsigned dst = 0;
bool instring = false;
for (; coln_start != coln_end; ++coln_start)
if (*coln_start == '"')
// A doubled double-quote instead a double-quoted
// string is an escaped double-quote.
if (instring && coln_start[1] == '"')
field[dst++] = *++coln_start;
else
instring = !instring;
else
field[dst++] = *coln_start;
field.resize(dst);
}
error |= process_string(field, filename, linenum);
linenum += csvlines;
if (prefix)
{
free(prefix);
prefix = nullptr;
}
if (suffix)
{
free(suffix);
suffix = nullptr;
}
}
}
return error;
}
@ -315,23 +315,23 @@ job_processor::process_file(const char* filename)
long int col = strtol(slash + 1, &end, 10);
// strtol ate all remaining characters and NN is positive
if (errno == 0 && !*end && col != 0)
{
col_to_read = col;
if (real_filename)
free(real_filename);
real_filename = strndup(filename, slash - filename);
{
col_to_read = col;
if (real_filename)
free(real_filename);
real_filename = strndup(filename, slash - filename);
// Special case for stdin.
if (real_filename[0] == '-' && real_filename[1] == 0)
return process_stream(std::cin, real_filename);
// Special case for stdin.
if (real_filename[0] == '-' && real_filename[1] == 0)
return process_stream(std::cin, real_filename);
std::ifstream input(real_filename);
if (input)
return process_stream(input, real_filename);
std::ifstream input(real_filename);
if (input)
return process_stream(input, real_filename);
error(2, errno, "cannot open '%s' nor '%s'",
filename, real_filename);
}
error(2, errno, "cannot open '%s' nor '%s'",
filename, real_filename);
}
}
error(2, saved_errno, "cannot open '%s'", filename);
@ -345,11 +345,11 @@ job_processor::run()
for (auto& j: jobs)
{
if (!j.file_p)
error |= process_string(j.str);
error |= process_string(j.str);
else
error |= process_file(j.str);
error |= process_file(j.str);
if (abort_run)
break;
break;
}
return error;
}

View file

@ -28,7 +28,7 @@
struct job
{
const char* str;
bool file_p; // true if str is a filename, false if it is a formula
bool file_p; // true if str is a filename, false if it is a formula
job(const char* str, bool file_p)
: str(str), file_p(file_p)
@ -58,11 +58,11 @@ public:
virtual int
process_formula(spot::formula f,
const char* filename = nullptr, int linenum = 0) = 0;
const char* filename = nullptr, int linenum = 0) = 0;
virtual int
process_string(const std::string& str,
const char* filename = nullptr, int linenum = 0);
const char* filename = nullptr, int linenum = 0);
virtual int
process_stream(std::istream& is, const char* filename);

View file

@ -41,8 +41,8 @@ spot::twa_graph_ptr
read_automaton(const char* filename, spot::bdd_dict_ptr& dict)
{
auto p = spot::parse_aut(filename, dict,
spot::default_environment::instance(),
opt_parse);
spot::default_environment::instance(),
opt_parse);
if (p->format_errors(std::cerr))
error(2, 0, "failed to read automaton from %s", filename);
if (p->aborted)
@ -86,5 +86,5 @@ parse_opt_hoaread(int key, char* arg, struct argp_state*)
const struct argp hoaread_argp = { options, parse_opt_hoaread,
nullptr, nullptr, nullptr,
nullptr, nullptr };
nullptr, nullptr, nullptr,
nullptr, nullptr };

View file

@ -65,13 +65,13 @@ static const argp_option options[] =
};
const struct argp output_argp = { options, parse_opt_output,
nullptr, nullptr, nullptr,
nullptr, nullptr };
nullptr, nullptr, nullptr,
nullptr, nullptr };
static
void
report_not_ltl(spot::formula f,
const char* filename, int linenum, const char* syn)
const char* filename, int linenum, const char* syn)
{
std::string s = spot::str_psl(f);
static const char msg[] =
@ -84,30 +84,30 @@ report_not_ltl(spot::formula f,
std::ostream&
stream_formula(std::ostream& out,
spot::formula f, const char* filename, int linenum)
spot::formula f, const char* filename, int linenum)
{
switch (output_format)
{
case lbt_output:
if (f.is_ltl_formula())
spot::print_lbt_ltl(out, f);
spot::print_lbt_ltl(out, f);
else
report_not_ltl(f, filename, linenum, "LBT");
report_not_ltl(f, filename, linenum, "LBT");
break;
case spot_output:
spot::print_psl(out, f, full_parenth);
break;
case spin_output:
if (f.is_ltl_formula())
spot::print_spin_ltl(out, f, full_parenth);
spot::print_spin_ltl(out, f, full_parenth);
else
report_not_ltl(f, filename, linenum, "Spin");
report_not_ltl(f, filename, linenum, "Spin");
break;
case wring_output:
if (f.is_ltl_formula())
spot::print_wring_ltl(out, f);
spot::print_wring_ltl(out, f);
else
report_not_ltl(f, filename, linenum, "Wring");
report_not_ltl(f, filename, linenum, "Wring");
break;
case utf8_output:
spot::print_utf8_psl(out, f, full_parenth);
@ -124,8 +124,8 @@ stream_formula(std::ostream& out,
static void
stream_escapable_formula(std::ostream& os,
spot::formula f,
const char* filename, int linenum)
spot::formula f,
const char* filename, int linenum)
{
if (escape_csv)
{
@ -260,17 +260,17 @@ parse_opt_output(int key, char* arg, struct argp_state*)
static void
output_formula(std::ostream& out,
spot::formula f,
const char* filename = nullptr, int linenum = 0,
const char* prefix = nullptr, const char* suffix = nullptr)
spot::formula f,
const char* filename = nullptr, int linenum = 0,
const char* prefix = nullptr, const char* suffix = nullptr)
{
if (!format)
{
if (prefix)
out << prefix << ',';
out << prefix << ',';
stream_escapable_formula(out, f, filename, linenum);
if (suffix)
out << ',' << suffix;
out << ',' << suffix;
}
else
{
@ -287,14 +287,14 @@ void
void
output_formula_checked(spot::formula f,
const char* filename, int linenum,
const char* prefix, const char* suffix)
const char* filename, int linenum,
const char* prefix, const char* suffix)
{
if (output_format == count_output)
{
if (outputnamer)
throw std::runtime_error
("options --output and --count are incompatible");
throw std::runtime_error
("options --output and --count are incompatible");
return;
}
if (output_format == quiet_output)
@ -308,7 +308,7 @@ output_formula_checked(spot::formula f,
std::string fname = outputname.str();
auto p = outputfiles.emplace(fname, nullptr);
if (p.second)
p.first->second.reset(new output_file(fname.c_str()));
p.first->second.reset(new output_file(fname.c_str()));
out = &p.first->second->ostream();
}
output_formula(*out, f, filename, linenum, prefix, suffix);

View file

@ -30,7 +30,7 @@
#include "common_file.hh"
enum output_format_t { spot_output, spin_output, utf8_output,
lbt_output, wring_output, latex_output,
lbt_output, wring_output, latex_output,
quiet_output, count_output };
extern output_format_t output_format;
extern bool full_parenth;
@ -43,12 +43,12 @@ int parse_opt_output(int key, char* arg, struct argp_state* state);
// Low-level output
std::ostream&
stream_formula(std::ostream& out,
spot::formula f, const char* filename, int linenum);
spot::formula f, const char* filename, int linenum);
void output_formula_checked(spot::formula f,
const char* filename = nullptr, int linenum = 0,
const char* prefix = nullptr,
const char* suffix = nullptr);
const char* filename = nullptr, int linenum = 0,
const char* prefix = nullptr,
const char* suffix = nullptr);
class printable_formula:
@ -72,15 +72,15 @@ public:
aut_stat_printer(std::ostream& os, const char* format)
: spot::stat_printer(os, format)
{
declare('f', &formula_); // Override the formula printer.
declare('f', &formula_); // Override the formula printer.
}
using spot::formater::set_output;
std::ostream&
print(const spot::const_twa_graph_ptr& aut,
spot::formula f = nullptr,
double run_time = -1.)
spot::formula f = nullptr,
double run_time = -1.)
{
formula_ = f;
return this->spot::stat_printer::print(aut, f, run_time);

View file

@ -155,7 +155,7 @@ parse_opt_post(int key, char*, struct argp_state*)
break;
case OPT_TGBA:
if (automaton_format == Spin)
error(2, 0, "--spin and --tgba are incompatible");
error(2, 0, "--spin and --tgba are incompatible");
type = spot::postprocessor::TGBA;
break;
default:
@ -165,7 +165,7 @@ parse_opt_post(int key, char*, struct argp_state*)
}
const struct argp post_argp = { options, parse_opt_post,
nullptr, nullptr, nullptr, nullptr, nullptr };
nullptr, nullptr, nullptr, nullptr, nullptr };
const struct argp post_argp_disabled = { options_disabled, parse_opt_post,
nullptr, nullptr, nullptr,
nullptr, nullptr };
nullptr, nullptr, nullptr,
nullptr, nullptr };

View file

@ -23,7 +23,7 @@
#include <spot/twaalgos/postproc.hh>
#include <argp.h>
extern const struct argp post_argp; // postprocessing enabled
extern const struct argp post_argp; // postprocessing enabled
extern const struct argp post_argp_disabled; // postprocessing disabled
extern spot::postprocessor::output_type type;

View file

@ -24,21 +24,21 @@
#define OPT_R 'r'
#define DECLARE_OPT_R \
{ "simplify", OPT_R, "LEVEL", OPTION_ARG_OPTIONAL, \
"simplify formulas according to LEVEL (see below); LEVEL is " \
#define DECLARE_OPT_R \
{ "simplify", OPT_R, "LEVEL", OPTION_ARG_OPTIONAL, \
"simplify formulas according to LEVEL (see below); LEVEL is " \
"set to 3 if omitted", 0 }
#define LEVEL_DOC(g) \
{ nullptr, 0, nullptr, 0, \
"The simplification LEVEL may be set as follows.", g }, \
{ " 0", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
"No rewriting", 0 }, \
{ " 1", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
"basic rewritings and eventual/universal rules", 0 }, \
{ " 2", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
"additional syntactic implication rules", 0 }, \
{ " 3", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
#define LEVEL_DOC(g) \
{ nullptr, 0, nullptr, 0, \
"The simplification LEVEL may be set as follows.", g }, \
{ " 0", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
"No rewriting", 0 }, \
{ " 1", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
"basic rewritings and eventual/universal rules", 0 }, \
{ " 2", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
"additional syntactic implication rules", 0 }, \
{ " 3", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, \
"better implications using containment", 0 }
extern int simplification_level;

View file

@ -42,7 +42,7 @@ parse_range(const char* str, int missing_left, int missing_right)
// No leading number. It's OK as long as the string is not
// empty.
if (!*end)
error(1, 0, "invalid empty range");
error(1, 0, "invalid empty range");
res.min = missing_left;
}
if (!*end)
@ -54,24 +54,24 @@ parse_range(const char* str, int missing_left, int missing_right)
{
// Skip : or ..
if (end[0] == ':')
++end;
++end;
else if (end[0] == '.' && end[1] == '.')
end += 2;
end += 2;
if (!*end && missing_right != 0)
{
res.max = missing_right;
}
{
res.max = missing_right;
}
else
{
// Parse the next integer.
char* end2;
res.max = strtol(end, &end2, 10);
if (end == end2)
error(1, 0, "invalid range '%s' (missing end?)", str);
if (*end2)
error(1, 0, "invalid range '%s' (trailing garbage?)", str);
}
{
// Parse the next integer.
char* end2;
res.max = strtol(end, &end2, 10);
if (end == end2)
error(1, 0, "invalid range '%s' (missing end?)", str);
if (*end2)
error(1, 0, "invalid range '%s' (trailing garbage?)", str);
}
}
if (res.min < 0 || res.max < 0)

View file

@ -19,15 +19,15 @@
#pragma once
#define RANGE_DOC \
{ nullptr, 0, nullptr, 0, \
"RANGE may have one of the following forms: 'INT', " \
#define RANGE_DOC \
{ nullptr, 0, nullptr, 0, \
"RANGE may have one of the following forms: 'INT', " \
"'INT..INT', or '..INT'.\nIn the latter case, the missing number " \
"is assumed to be 1.", 0 }
#define RANGE_DOC_FULL \
{ nullptr, 0, nullptr, 0, \
"RANGE may have one of the following forms: 'INT', " \
#define RANGE_DOC_FULL \
{ nullptr, 0, nullptr, 0, \
"RANGE may have one of the following forms: 'INT', " \
"'INT..INT', '..INT', or 'INT..'", 0 }
struct range
@ -47,4 +47,4 @@ struct range
// values. Additionally, if missing_right == 0, then the INT.. form
// is disallowed.
range parse_range(const char* str,
int missing_left = 1, int missing_right = 0);
int missing_left = 1, int missing_right = 0);

View file

@ -129,7 +129,7 @@ parse_opt_misc(int key, char*, struct argp_state* state)
break;
case OPT_USAGE:
argp_state_help(state, state->out_stream,
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
break;
case OPT_VERSION:
display_version(state->out_stream, state);
@ -143,8 +143,8 @@ parse_opt_misc(int key, char*, struct argp_state* state)
const struct argp misc_argp = { options, parse_opt_misc,
nullptr, nullptr, nullptr, nullptr, nullptr };
nullptr, nullptr, nullptr, nullptr, nullptr };
const struct argp misc_argp_hidden = { options_hidden, parse_opt_misc,
nullptr, nullptr, nullptr,
nullptr, nullptr };
nullptr, nullptr, nullptr,
nullptr, nullptr };

View file

@ -53,17 +53,17 @@ static void show_shorthands()
{
std::cout
<< ("If a COMMANDFMT does not use any %-sequence, and starts with one of\n"
"the following words, then the string on the right is appended.\n\n");
"the following words, then the string on the right is appended.\n\n");
for (auto& s: shorthands)
std::cout << " "
<< std::left << std::setw(12) << s.prefix
<< s.suffix << '\n';
<< std::left << std::setw(12) << s.prefix
<< s.suffix << '\n';
std::cout
<< ("\nAny {name} and directory component is skipped for the purpose of\n"
"matching those prefixes. So for instance\n"
" '{DRA} ~/mytools/ltl2dstar-0.5.2'\n"
"will changed into\n"
" '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %L %O'\n");
"matching those prefixes. So for instance\n"
" '{DRA} ~/mytools/ltl2dstar-0.5.2'\n"
"will changed into\n"
" '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %L %O'\n");
}
@ -76,19 +76,19 @@ translator_spec::translator_spec(const char* spec)
const char* pos = cmd;
unsigned count = 1;
while (*++pos)
{
if (*pos == '{')
++count;
else if (*pos == '}')
if (!--count)
{
name = strndup(cmd + 1, pos - cmd - 1);
cmd = pos + 1;
while (*cmd == ' ' || *cmd == '\t')
++cmd;
break;
}
}
{
if (*pos == '{')
++count;
else if (*pos == '}')
if (!--count)
{
name = strndup(cmd + 1, pos - cmd - 1);
cmd = pos + 1;
while (*cmd == ' ' || *cmd == '\t')
++cmd;
break;
}
}
}
// If there is no % in the string, look for a known
// command from our shorthand list. If we find it,
@ -100,29 +100,29 @@ translator_spec::translator_spec(const char* spec)
auto basename = cmd;
auto pos = cmd;
while (*pos)
{
if (*pos == '/')
basename = pos + 1;
else if (*pos == ' ')
break;
++pos;
}
{
if (*pos == '/')
basename = pos + 1;
else if (*pos == ' ')
break;
++pos;
}
// Match a shorthand.
for (auto& p: shorthands)
{
int n = strlen(p.prefix);
if (strncmp(basename, p.prefix, n) == 0)
{
int m = strlen(p.suffix);
int q = strlen(cmd);
char* tmp = static_cast<char*>(malloc(q + m + 1));
strcpy(tmp, cmd);
strcpy(tmp + q, p.suffix);
cmd = tmp;
allocated = true;
break;
}
}
{
int n = strlen(p.prefix);
if (strncmp(basename, p.prefix, n) == 0)
{
int m = strlen(p.suffix);
int q = strlen(cmd);
char* tmp = static_cast<char*>(malloc(q + m + 1));
strcpy(tmp, cmd);
strcpy(tmp + q, p.suffix);
cmd = tmp;
allocated = true;
break;
}
}
}
if (!allocated)
cmd = strdup(cmd);
@ -186,7 +186,7 @@ printable_result_filename::print(std::ostream& os, const char*) const
translator_runner::translator_runner(spot::bdd_dict_ptr dict,
bool no_output_allowed)
bool no_output_allowed)
: dict(dict)
{
declare('f', &string_ltl_spot);
@ -213,17 +213,17 @@ translator_runner::translator_runner(spot::bdd_dict_ptr dict,
const translator_spec& t = translators[n];
scan(t.cmd, has);
if (!(has['f'] || has['s'] || has['l'] || has['w']
|| has['F'] || has['S'] || has['L'] || has['W']))
error(2, 0, "no input %%-sequence in '%s'.\n Use "
"one of %%f,%%s,%%l,%%w,%%F,%%S,%%L,%%W to indicate how "
"to pass the formula.", t.spec);
|| has['F'] || has['S'] || has['L'] || has['W']))
error(2, 0, "no input %%-sequence in '%s'.\n Use "
"one of %%f,%%s,%%l,%%w,%%F,%%S,%%L,%%W to indicate how "
"to pass the formula.", t.spec);
if (!no_output_allowed
&& !(has['O'] ||
// backward-compatibility
has['D'] || has['N'] || has['T'] || has['H']))
error(2, 0, "no output %%-sequence in '%s'.\n Use "
"%%O to indicate where the automaton is output.",
t.spec);
&& !(has['O'] ||
// backward-compatibility
has['D'] || has['N'] || has['T'] || has['H']))
error(2, 0, "no output %%-sequence in '%s'.\n Use "
"%%O to indicate where the automaton is output.",
t.spec);
// Remember the %-sequences used by all translators.
prime(t.cmd);
}
@ -231,7 +231,7 @@ translator_runner::translator_runner(spot::bdd_dict_ptr dict,
void
translator_runner::string_to_tmp(std::string& str, unsigned n,
std::string& tmpname)
std::string& tmpname)
{
char prefix[30];
snprintf(prefix, sizeof prefix, "lcr-i%u-", n);
@ -302,18 +302,18 @@ sig_handler(int sig)
{
timed_out = true;
if (--alarm_on)
{
// Send SIGTERM to children.
kill(-child_pid, SIGTERM);
// Try again later if it didn't work. (alarm() will be reset
// if it did work and the call to wait() returns)
alarm(2);
}
{
// Send SIGTERM to children.
kill(-child_pid, SIGTERM);
// Try again later if it didn't work. (alarm() will be reset
// if it did work and the call to wait() returns)
alarm(2);
}
else
{
// After a few gentle tries, really kill that child.
kill(-child_pid, SIGKILL);
}
{
// After a few gentle tries, really kill that child.
kill(-child_pid, SIGKILL);
}
}
else
{
@ -370,7 +370,7 @@ exec_with_timeout(const char* cmd)
alarm_on = 0;
if (w == -1)
error(2, errno, "error during wait()");
error(2, errno, "error during wait()");
alarm(0);
}
@ -424,7 +424,7 @@ static int parse_opt_trans(int key, char* arg, struct argp_state*)
timeout = to_pos_int(arg);
#if !ENABLE_TIMEOUT
std::cerr << "warning: setting a timeout is not supported "
<< "on your platform" << std::endl;
<< "on your platform" << std::endl;
#endif
break;
case OPT_LIST:
@ -437,4 +437,4 @@ static int parse_opt_trans(int key, char* arg, struct argp_state*)
}
const struct argp trans_argp = { options, parse_opt_trans, nullptr, nullptr,
nullptr, nullptr, nullptr };
nullptr, nullptr, nullptr };

View file

@ -89,9 +89,9 @@ public:
using spot::formater::has;
translator_runner(spot::bdd_dict_ptr dict,
// whether we accept the absence of output
// specifier
bool no_output_allowed = false);
// whether we accept the absence of output
// specifier
bool no_output_allowed = false);
void string_to_tmp(std::string& str, unsigned n, std::string& tmpname);
const std::string& formula() const;
void round_formula(spot::formula f, unsigned serial);

View file

@ -89,9 +89,9 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case 'x':
{
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
}
break;
case ARGP_KEY_ARG:
@ -125,7 +125,7 @@ namespace
int
process_automaton(const spot::const_parsed_aut_ptr& haut,
const char* filename)
const char* filename)
{
spot::stopwatch sw;
sw.start();
@ -151,19 +151,19 @@ namespace
auto hp = spot::automaton_stream_parser(filename, opt_parse);
int err = 0;
while (!abort_run)
{
auto haut = hp.parse(spot::make_bdd_dict());
if (!haut->aut && haut->errors.empty())
break;
if (haut->format_errors(std::cerr))
err = 2;
if (!haut->aut)
error(2, 0, "failed to read automaton from %s", filename);
else if (haut->aborted)
err = std::max(err, aborted(haut, filename));
else
{
auto haut = hp.parse(spot::make_bdd_dict());
if (!haut->aut && haut->errors.empty())
break;
if (haut->format_errors(std::cerr))
err = 2;
if (!haut->aut)
error(2, 0, "failed to read automaton from %s", filename);
else if (haut->aborted)
err = std::max(err, aborted(haut, filename));
else
process_automaton(haut, filename);
}
}
return err;
}
};
@ -175,7 +175,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "[FILENAMES...]",
argp_program_doc, children, nullptr, nullptr };
argp_program_doc, children, nullptr, nullptr };
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
@ -192,7 +192,7 @@ main(int argc, char** argv)
{
dstar_processor processor(post);
if (processor.run())
return 2;
return 2;
}
catch (const std::runtime_error& e)
{

View file

@ -43,8 +43,8 @@
// @InProceedings{gastin.01.cav,
// author = {Paul Gastin and Denis Oddoux},
// title = {Fast {LTL} to {B\"u}chi Automata Translation},
// booktitle = {Proceedings of the 13th International Conference on
// Computer Aided Verification (CAV'01)},
// booktitle = {Proceedings of the 13th International Conference on
// Computer Aided Verification (CAV'01)},
// pages = {53--65},
// year = 2001,
// editor = {G. Berry and H. Comon and A. Finkel},
@ -58,7 +58,7 @@
// author = {Kristin Y. Rozier and Moshe Y. Vardi},
// title = {LTL Satisfiability Checking},
// booktitle = {Proceedings of the 12th International SPIN Workshop on
// Model Checking of Software (SPIN'07)},
// Model Checking of Software (SPIN'07)},
// pages = {149--167},
// year = {2007},
// volume = {4595},
@ -294,9 +294,9 @@ E_n(std::string name, int n)
p << name << n;
formula f = formula::ap(p.str());
if (result)
result = And_(f, result);
result = And_(f, result);
else
result = f;
result = f;
result = F_(result);
}
return result;
@ -314,9 +314,9 @@ phi_n(std::string name, int n)
for (; n > 0; --n)
{
if (result)
result = And_(p, X_(result));
result = And_(p, X_(result));
else
result = p;
result = p;
}
return result;
}
@ -339,14 +339,14 @@ phi_prime_n(std::string name, int n)
for (; n > 0; --n)
{
if (result)
{
p = X_(p);
result = And_(result, p);
}
{
p = X_(p);
result = And_(result, p);
}
else
{
result = p;
}
{
result = p;
}
}
return result;
}
@ -377,9 +377,9 @@ GF_n(std::string name, int n, bool conj = true)
formula f = G_(F_(formula::ap(p.str())));
if (result)
result = formula::multop(o, {f, result});
result = formula::multop(o, {f, result});
else
result = f;
result = f;
}
return result;
}
@ -403,9 +403,9 @@ FG_n(std::string name, int n, bool conj = false)
formula f = F_(G_(formula::ap(p.str())));
if (result)
result = formula::multop(o, {f, result});
result = formula::multop(o, {f, result});
else
result = f;
result = f;
}
return result;
}
@ -426,11 +426,11 @@ bin_n(std::string name, int n, op o, bool right_assoc = false)
p << name << (right_assoc ? (n + 1 - i) : i);
formula f = formula::ap(p.str());
if (!result)
result = f;
result = f;
else if (right_assoc)
result = formula::binop(o, f, result);
result = formula::binop(o, f, result);
else
result = formula::binop(o, result, f);
result = formula::binop(o, result, f);
}
return result;
}
@ -464,9 +464,9 @@ R_n(std::string name, int n)
formula f = Or_(gf, fg);
if (result)
result = And_(f, result);
result = And_(f, result);
else
result = f;
result = f;
}
return result;
}
@ -501,9 +501,9 @@ Q_n(std::string name, int n)
f = Or_(f, g);
if (result)
result = And_(f, result);
result = And_(f, result);
else
result = f;
result = f;
}
return result;
}
@ -527,9 +527,9 @@ combunop_n(std::string name, int n, op o, bool conj = false)
formula f = formula::unop(o, formula::ap(p.str()));
if (result)
result = formula::multop(cop, {f, result});
result = formula::multop(cop, {f, result});
else
result = f;
result = f;
}
return result;
}
@ -575,7 +575,7 @@ ltl_counter(std::string bit, std::string marker, int n, bool linear)
// G(m -> X(!m)&XX(!m)&XXX(m)) [if n = 3]
std::vector<formula> v(n);
for (int i = 0; i + 1 < n; ++i)
v[i] = X_n(neg_m, i + 1);
v[i] = X_n(neg_m, i + 1);
v[n - 1] = X_n(m, n);
res[0] = And_(m, G_(Implies_(m, formula::And(std::move(v)))));
}
@ -584,7 +584,7 @@ ltl_counter(std::string bit, std::string marker, int n, bool linear)
// G(m -> X(!m & X(!m X(m)))) [if n = 3]
formula p = m;
for (int i = n - 1; i > 0; --i)
p = And_(neg_m, X_(p));
p = And_(neg_m, X_(p));
res[0] = And_(m, G_(Implies_(m, X_(p))));
}
@ -594,7 +594,7 @@ ltl_counter(std::string bit, std::string marker, int n, bool linear)
// !b & X(!b) & XX(!b) [if n = 3]
std::vector<formula> v2(n);
for (int i = 0; i < n; ++i)
v2[i] = X_n(neg_b, i);
v2[i] = X_n(neg_b, i);
res[1] = formula::And(std::move(v2));
}
else
@ -602,7 +602,7 @@ ltl_counter(std::string bit, std::string marker, int n, bool linear)
// !b & X(!b & X(!b)) [if n = 3]
formula p = neg_b;
for (int i = n - 1; i > 0; --i)
p = And_(neg_b, X_(p));
p = And_(neg_b, X_(p));
res[1] = p;
}
@ -613,26 +613,26 @@ ltl_counter(std::string bit, std::string marker, int n, bool linear)
formula Xnm1_b = X_n(b, n - 1);
formula Xn_b = X_(Xnm1_b);
res[2] = G_(Implies_(And_(m, neg_b),
AndX_(Xnm1_b, U_(And_(Not_(m), Equiv_(b, Xn_b)), m))));
AndX_(Xnm1_b, U_(And_(Not_(m), Equiv_(b, Xn_b)), m))));
// From the least significant bit to the first 0, all the bits
// are flipped on the next value. Remaining bits are identical.
formula Xnm1_negb = X_n(neg_b, n - 1);
formula Xn_negb = X_(Xnm1_negb);
res[3] = G_(Implies_(And_(m, b),
AndX_(Xnm1_negb,
U_(And_(And_(b, neg_m), Xn_negb),
Or_(m, And_(And_(neg_m, neg_b),
AndX_(Xnm1_b,
U_(And_(neg_m,
Equiv_(b, Xn_b)),
m))))))));
AndX_(Xnm1_negb,
U_(And_(And_(b, neg_m), Xn_negb),
Or_(m, And_(And_(neg_m, neg_b),
AndX_(Xnm1_b,
U_(And_(neg_m,
Equiv_(b, Xn_b)),
m))))))));
return formula::And(std::move(res));
}
static formula
ltl_counter_carry(std::string bit, std::string marker,
std::string carry, int n, bool linear)
std::string carry, int n, bool linear)
{
formula b = formula::ap(bit);
formula neg_b = Not_(b);
@ -650,7 +650,7 @@ ltl_counter_carry(std::string bit, std::string marker,
// G(m -> X(!m)&XX(!m)&XXX(m)) [if n = 3]
std::vector<formula> v(n);
for (int i = 0; i + 1 < n; ++i)
v[i] = X_n(neg_m, i + 1);
v[i] = X_n(neg_m, i + 1);
v[n - 1] = X_n(m, n);
res[0] = And_(m, G_(Implies_(m, formula::And(std::move(v)))));
}
@ -659,7 +659,7 @@ ltl_counter_carry(std::string bit, std::string marker,
// G(m -> X(!m & X(!m X(m)))) [if n = 3]
formula p = m;
for (int i = n - 1; i > 0; --i)
p = And_(neg_m, X_(p));
p = And_(neg_m, X_(p));
res[0] = And_(m, G_(Implies_(m, X_(p))));
}
@ -669,7 +669,7 @@ ltl_counter_carry(std::string bit, std::string marker,
// !b & X(!b) & XX(!b) [if n = 3]
std::vector<formula> v2(n);
for (int i = 0; i < n; ++i)
v2[i] = X_n(neg_b, i);
v2[i] = X_n(neg_b, i);
res[1] = formula::And(std::move(v2));
}
else
@ -677,7 +677,7 @@ ltl_counter_carry(std::string bit, std::string marker,
// !b & X(!b & X(!b)) [if n = 3]
formula p = neg_b;
for (int i = n - 1; i > 0; --i)
p = And_(neg_b, X_(p));
p = And_(neg_b, X_(p));
res[1] = p;
}
@ -694,24 +694,24 @@ ltl_counter_carry(std::string bit, std::string marker,
{
// If there's no carry, then all of the bits stay the same n steps later.
res[4] = G_(Implies_(And_(neg_c, X_(neg_m)),
And_(X_(Not_(c)), Equiv_(X_(b), X_(Xn_b)))));
And_(X_(Not_(c)), Equiv_(X_(b), X_(Xn_b)))));
// If there's a carry, then add one: flip the bits of b and
// adjust the carry.
res[5] = G_(Implies_(c, And_(Implies_(X_(neg_b),
And_(X_(neg_c), X_(Xn_b))),
Implies_(X_(b),
And_(X_(c), X_(Xn_negb))))));
And_(X_(neg_c), X_(Xn_b))),
Implies_(X_(b),
And_(X_(c), X_(Xn_negb))))));
}
else
{
// If there's no carry, then all of the bits stay the same n steps later.
res[4] = G_(Implies_(And_(neg_c, X_(neg_m)),
X_(And_(Not_(c), Equiv_(b, Xn_b)))));
X_(And_(Not_(c), Equiv_(b, Xn_b)))));
// If there's a carry, then add one: flip the bits of b and
// adjust the carry.
res[5] = G_(Implies_(c, X_(And_(Implies_(neg_b, And_(neg_c, Xn_b)),
Implies_(b, And_(c, Xn_negb))))));
Implies_(b, And_(c, Xn_negb))))));
}
return formula::And(std::move(res));
}
@ -804,12 +804,12 @@ run_jobs()
int inc = (j.range.max < j.range.min) ? -1 : 1;
int n = j.range.min;
for (;;)
{
output_pattern(j.pattern, n);
if (n == j.range.max)
break;
n += inc;
}
{
output_pattern(j.pattern, n);
if (n == j.range.max)
break;
n += inc;
}
}
}
@ -820,14 +820,14 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, nullptr, argp_program_doc,
children, nullptr, nullptr };
children, nullptr, nullptr };
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
if (jobs.empty())
error(1, 0, "Nothing to do. Try '%s --help' for more information.",
program_name);
program_name);
run_jobs();
return 0;

View file

@ -90,9 +90,9 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case 'x':
{
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
}
break;
case ARGP_KEY_ARG:
@ -122,19 +122,19 @@ namespace
int
process_formula(spot::formula f,
const char* filename = nullptr, int linenum = 0)
const char* filename = nullptr, int linenum = 0)
{
// This should not happen, because the parser we use can only
// read PSL/LTL formula, but since our formula type can
// represent more than PSL formula, let's make this
// future-proof.
if (!f.is_psl_formula())
{
std::string s = spot::str_psl(f);
error_at_line(2, 0, filename, linenum,
"formula '%s' is not an LTL or PSL formula",
s.c_str());
}
{
std::string s = spot::str_psl(f);
error_at_line(2, 0, filename, linenum,
"formula '%s' is not an LTL or PSL formula",
s.c_str());
}
spot::stopwatch sw;
sw.start();
@ -142,7 +142,7 @@ namespace
const double translation_time = sw.stop();
printer.print(aut, f, filename, linenum, translation_time, nullptr,
prefix, suffix);
prefix, suffix);
return 0;
}
};
@ -157,7 +157,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "[FORMULA...]",
argp_program_doc, children, nullptr, nullptr };
argp_program_doc, children, nullptr, nullptr };
simplification_level = 3;
@ -166,7 +166,7 @@ main(int argc, char** argv)
if (jobs.empty())
error(2, 0, "No formula to translate? Run '%s --help' for usage.",
program_name);
program_name);
spot::translator trans(&extra_options);
trans.set_pref(pref | comp | sbacc | unambig);
@ -177,7 +177,7 @@ main(int argc, char** argv)
{
trans_processor processor(trans);
if (processor.run())
return 2;
return 2;
}
catch (const std::runtime_error& e)
{

View file

@ -119,9 +119,9 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case 'x':
{
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
const char* opt = extra_options.parse_options(arg);
if (opt)
error(2, 0, "failed to parse --options near '%s'", opt);
}
break;
case OPT_TGTA:
@ -171,7 +171,7 @@ namespace
int
process_formula(spot::formula f,
const char* filename = nullptr, int linenum = 0)
const char* filename = nullptr, int linenum = 0)
{
auto aut = trans.run(&f);
@ -180,33 +180,33 @@ namespace
// represent more than PSL formula, let's make this
// future-proof.
if (!f.is_psl_formula())
{
std::string s = spot::str_psl(f);
error_at_line(2, 0, filename, linenum,
"formula '%s' is not an LTL or PSL formula",
s.c_str());
}
{
std::string s = spot::str_psl(f);
error_at_line(2, 0, filename, linenum,
"formula '%s' is not an LTL or PSL formula",
s.c_str());
}
bdd ap_set = atomic_prop_collect_as_bdd(f, aut);
if (ta_type != TGTA)
{
auto testing_automaton =
tgba_to_ta(aut, ap_set, type == spot::postprocessor::BA,
opt_with_artificial_initial_state,
opt_single_pass_emptiness_check,
opt_with_artificial_livelock);
if (level != spot::postprocessor::Low)
testing_automaton = spot::minimize_ta(testing_automaton);
spot::print_dot(std::cout, testing_automaton);
}
{
auto testing_automaton =
tgba_to_ta(aut, ap_set, type == spot::postprocessor::BA,
opt_with_artificial_initial_state,
opt_single_pass_emptiness_check,
opt_with_artificial_livelock);
if (level != spot::postprocessor::Low)
testing_automaton = spot::minimize_ta(testing_automaton);
spot::print_dot(std::cout, testing_automaton);
}
else
{
auto tgta = tgba_to_tgta(aut, ap_set);
if (level != spot::postprocessor::Low)
tgta = spot::minimize_tgta(tgta);
spot::print_dot(std::cout, tgta->get_ta());
}
{
auto tgta = tgba_to_tgta(aut, ap_set);
if (level != spot::postprocessor::Low)
tgta = spot::minimize_tgta(tgta);
spot::print_dot(std::cout, tgta->get_ta());
}
flush_cout();
return 0;
}
@ -219,7 +219,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "[FORMULA...]",
argp_program_doc, children, nullptr, nullptr };
argp_program_doc, children, nullptr, nullptr };
simplification_level = 3;
@ -228,7 +228,7 @@ main(int argc, char** argv)
if (jobs.empty())
error(2, 0, "No formula to translate? Run '%s --help' for usage.",
program_name);
program_name);
spot::translator trans(&extra_options);
trans.set_pref(pref | comp | sbacc);

File diff suppressed because it is too large Load diff

View file

@ -151,57 +151,57 @@ namespace
spot::twa_graph_ptr res = nullptr;
if (timed_out)
{
problem = false; // A timeout is considered benign
std::cerr << "warning: timeout during execution of command \""
<< cmd << "\"\n";
++timeout_count;
}
{
problem = false; // A timeout is considered benign
std::cerr << "warning: timeout during execution of command \""
<< cmd << "\"\n";
++timeout_count;
}
else if (WIFSIGNALED(es))
{
problem = true;
es = WTERMSIG(es);
std::cerr << "error: execution of command \"" << cmd
<< "\" terminated by signal " << es << ".\n";
}
{
problem = true;
es = WTERMSIG(es);
std::cerr << "error: execution of command \"" << cmd
<< "\" terminated by signal " << es << ".\n";
}
else if (WIFEXITED(es) && WEXITSTATUS(es) != 0)
{
problem = true;
es = WEXITSTATUS(es);
std::cerr << "error: execution of command \"" << cmd
<< "\" returned exit code " << es << ".\n";
}
{
problem = true;
es = WEXITSTATUS(es);
std::cerr << "error: execution of command \"" << cmd
<< "\" returned exit code " << es << ".\n";
}
else if (output.val())
{
problem = false;
auto aut = spot::parse_aut(output.val()->name(), dict,
spot::default_environment::instance(),
opt_parse);
if (!aut->errors.empty())
{
problem = true;
std::cerr << "error: failed to parse the automaton "
"produced by \"" << cmd << "\".\n";
aut->format_errors(std::cerr);
res = nullptr;
}
else if (aut->aborted)
{
problem = true;
std::cerr << "error: command \"" << cmd
<< "\" aborted its output.\n";
res = nullptr;
}
else
{
res = aut->aut;
}
}
else // No automaton output
{
problem = false;
res = nullptr;
}
{
problem = false;
auto aut = spot::parse_aut(output.val()->name(), dict,
spot::default_environment::instance(),
opt_parse);
if (!aut->errors.empty())
{
problem = true;
std::cerr << "error: failed to parse the automaton "
"produced by \"" << cmd << "\".\n";
aut->format_errors(std::cerr);
res = nullptr;
}
else if (aut->aborted)
{
problem = true;
std::cerr << "error: command \"" << cmd
<< "\" aborted its output.\n";
res = nullptr;
}
else
{
res = aut->aut;
}
}
else // No automaton output
{
problem = false;
res = nullptr;
}
output.cleanup();
return res;
@ -234,18 +234,18 @@ namespace
int
process_string(const std::string& input,
const char* filename,
int linenum)
const char* filename,
int linenum)
{
spot::parsed_formula pf = parse_formula(input);
if (!pf.f || !pf.errors.empty())
{
if (filename)
error_at_line(0, 0, filename, linenum, "parse error:");
pf.format_errors(std::cerr);
return 1;
}
{
if (filename)
error_at_line(0, 0, filename, linenum, "parse error:");
pf.format_errors(std::cerr);
return 1;
}
inputf = input;
process_formula(pf.f, filename, linenum);
@ -255,43 +255,43 @@ namespace
int
process_formula(spot::formula f,
const char* filename = nullptr, int linenum = 0)
const char* filename = nullptr, int linenum = 0)
{
std::unique_ptr<spot::relabeling_map> relmap;
// If atomic propositions are incompatible with one of the
// output, relabel the formula.
if ((!f.has_lbt_atomic_props() &&
(runner.has('l') || runner.has('L') || runner.has('T')))
|| (!f.has_spin_atomic_props() &&
(runner.has('s') || runner.has('S'))))
{
relmap.reset(new spot::relabeling_map);
f = spot::relabel(f, spot::Pnn, relmap.get());
}
(runner.has('l') || runner.has('L') || runner.has('T')))
|| (!f.has_spin_atomic_props() &&
(runner.has('s') || runner.has('S'))))
{
relmap.reset(new spot::relabeling_map);
f = spot::relabel(f, spot::Pnn, relmap.get());
}
static unsigned round = 1;
runner.round_formula(f, round);
unsigned ts = translators.size();
for (unsigned t = 0; t < ts; ++t)
{
bool problem;
double translation_time;
auto aut = runner.translate(t, problem, translation_time);
if (problem)
error_at_line(2, 0, filename, linenum, "aborting here");
if (aut)
{
if (relmap)
relabel_here(aut, relmap.get());
aut = post.run(aut, f);
cmdname = translators[t].name;
roundval = round;
printer.print(aut, f, filename, linenum, translation_time,
nullptr, prefix, suffix);
};
}
{
bool problem;
double translation_time;
auto aut = runner.translate(t, problem, translation_time);
if (problem)
error_at_line(2, 0, filename, linenum, "aborting here");
if (aut)
{
if (relmap)
relabel_here(aut, relmap.get());
aut = post.run(aut, f);
cmdname = translators[t].name;
roundval = round;
printer.print(aut, f, filename, linenum, translation_time,
nullptr, prefix, suffix);
};
}
spot::cleanup_tmpfiles();
++round;
return 0;
@ -305,7 +305,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "[COMMANDFMT...]",
argp_program_doc, children, nullptr, nullptr };
argp_program_doc, children, nullptr, nullptr };
// Disable post-processing as much as possible by default.
level = spot::postprocessor::Low;
@ -319,7 +319,7 @@ main(int argc, char** argv)
if (translators.empty())
error(2, 0, "No translator to run? Run '%s --help' for usage.",
program_name);
program_name);
setup_sig_handler();
@ -332,7 +332,7 @@ main(int argc, char** argv)
{
processor p(post);
if (p.run())
return 2;
return 2;
}
catch (const std::runtime_error& e)
{

View file

@ -348,10 +348,10 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case OPT_EQUIVALENT_TO:
{
if (opt->equivalent_to)
error(2, 0, "only one --equivalent-to option can be given");
opt->equivalent_to = parse_formula_arg(arg);
break;
if (opt->equivalent_to)
error(2, 0, "only one --equivalent-to option can be given");
opt->equivalent_to = parse_formula_arg(arg);
break;
}
case OPT_EXCLUSIVE_AP:
opt->excl_ap.add_group(arg);
@ -364,17 +364,17 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case OPT_IMPLIED_BY:
{
spot::formula i = parse_formula_arg(arg);
// a→c∧b→c ≡ (ab)→c
opt->implied_by = spot::formula::Or({opt->implied_by, i});
break;
spot::formula i = parse_formula_arg(arg);
// a→c∧b→c ≡ (ab)→c
opt->implied_by = spot::formula::Or({opt->implied_by, i});
break;
}
case OPT_IMPLY:
{
// a→b∧a→c ≡ a→(b∧c)
spot::formula i = parse_formula_arg(arg);
opt->imply = spot::formula::And({opt->imply, i});
break;
// a→b∧a→c ≡ a→(b∧c)
spot::formula i = parse_formula_arg(arg);
opt->imply = spot::formula::And({opt->imply, i});
break;
}
case OPT_LTL:
ltl = true;
@ -392,13 +392,13 @@ parse_opt(int key, char* arg, struct argp_state*)
case OPT_RELABEL_BOOL:
relabeling = (key == OPT_RELABEL_BOOL ? BseRelabeling : ApRelabeling);
if (!arg || !strncasecmp(arg, "abc", 6))
style = spot::Abc;
style = spot::Abc;
else if (!strncasecmp(arg, "pnn", 4))
style = spot::Pnn;
style = spot::Pnn;
else
error(2, 0, "invalid argument for --relabel%s: '%s'",
(key == OPT_RELABEL_BOOL ? "-bool" : ""),
arg);
error(2, 0, "invalid argument for --relabel%s: '%s'",
(key == OPT_RELABEL_BOOL ? "-bool" : ""),
arg);
break;
case OPT_REMOVE_WM:
unabbreviate += "MW";
@ -426,9 +426,9 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case OPT_UNABBREVIATE:
if (arg)
unabbreviate += arg;
unabbreviate += arg;
else
unabbreviate += spot::default_unabbrev_string;
unabbreviate += spot::default_unabbrev_string;
break;
case OPT_AP_N:
ap_n = parse_range(arg, 0, std::numeric_limits<int>::max());
@ -479,87 +479,87 @@ namespace
int
process_string(const std::string& input,
const char* filename = nullptr, int linenum = 0)
const char* filename = nullptr, int linenum = 0)
{
spot::parsed_formula pf = parse_formula(input);
if (!pf.f || !pf.errors.empty())
{
if (!ignore_errors)
{
if (filename)
error_at_line(0, 0, filename, linenum, "parse error:");
pf.format_errors(std::cerr);
}
{
if (!ignore_errors)
{
if (filename)
error_at_line(0, 0, filename, linenum, "parse error:");
pf.format_errors(std::cerr);
}
if (error_style == skip_errors)
std::cout << input << '\n';
else
assert(error_style == drop_errors);
check_cout();
return !ignore_errors;
}
if (error_style == skip_errors)
std::cout << input << '\n';
else
assert(error_style == drop_errors);
check_cout();
return !ignore_errors;
}
try
{
return process_formula(pf.f, filename, linenum);
}
{
return process_formula(pf.f, filename, linenum);
}
catch (const std::runtime_error& e)
{
error_at_line(2, 0, filename, linenum, "%s", e.what());
SPOT_UNREACHABLE();
}
{
error_at_line(2, 0, filename, linenum, "%s", e.what());
SPOT_UNREACHABLE();
}
}
int
process_formula(spot::formula f,
const char* filename = nullptr, int linenum = 0)
const char* filename = nullptr, int linenum = 0)
{
if (opt_max_count >= 0 && match_count >= opt_max_count)
{
abort_run = true;
return 0;
}
{
abort_run = true;
return 0;
}
if (negate)
f = spot::formula::Not(f);
f = spot::formula::Not(f);
if (remove_x)
{
// If simplification are enabled, we do them before and after.
if (simplification_level)
f = simpl.simplify(f);
f = spot::remove_x(f);
}
{
// If simplification are enabled, we do them before and after.
if (simplification_level)
f = simpl.simplify(f);
f = spot::remove_x(f);
}
if (simplification_level || boolean_to_isop)
f = simpl.simplify(f);
f = simpl.simplify(f);
if (nnf)
f = simpl.negative_normal_form(f);
f = simpl.negative_normal_form(f);
switch (relabeling)
{
case ApRelabeling:
{
relmap.clear();
f = spot::relabel(f, style, &relmap);
break;
}
case BseRelabeling:
{
relmap.clear();
f = spot::relabel_bse(f, style, &relmap);
break;
}
case NoRelabeling:
break;
}
{
case ApRelabeling:
{
relmap.clear();
f = spot::relabel(f, style, &relmap);
break;
}
case BseRelabeling:
{
relmap.clear();
f = spot::relabel_bse(f, style, &relmap);
break;
}
case NoRelabeling:
break;
}
if (!unabbreviate.empty())
f = spot::unabbreviate(f, unabbreviate.c_str());
f = spot::unabbreviate(f, unabbreviate.c_str());
if (!opt->excl_ap.empty())
f = opt->excl_ap.constrain(f);
f = opt->excl_ap.constrain(f);
bool matched = true;
@ -575,32 +575,32 @@ namespace
matched &= !syntactic_persistence || f.is_syntactic_persistence();
matched &= !syntactic_si || f.is_syntactic_stutter_invariant();
if (matched && (ap_n.min > 0 || ap_n.max >= 0))
{
auto s = atomic_prop_collect(f);
int n = s->size();
delete s;
matched &= (ap_n.min <= 0) || (n >= ap_n.min);
matched &= (ap_n.max < 0) || (n <= ap_n.max);
}
{
auto s = atomic_prop_collect(f);
int n = s->size();
delete s;
matched &= (ap_n.min <= 0) || (n >= ap_n.min);
matched &= (ap_n.max < 0) || (n <= ap_n.max);
}
if (matched && (size.min > 0 || size.max >= 0))
{
int l = spot::length(f);
matched &= (size.min <= 0) || (l >= size.min);
matched &= (size.max < 0) || (l <= size.max);
}
{
int l = spot::length(f);
matched &= (size.min <= 0) || (l >= size.min);
matched &= (size.max < 0) || (l <= size.max);
}
if (matched && (bsize.min > 0 || bsize.max >= 0))
{
int l = spot::length_boolone(f);
matched &= (bsize.min <= 0) || (l >= bsize.min);
matched &= (bsize.max < 0) || (l <= bsize.max);
}
{
int l = spot::length_boolone(f);
matched &= (bsize.min <= 0) || (l >= bsize.min);
matched &= (bsize.max < 0) || (l <= bsize.max);
}
matched &= !opt->implied_by || simpl.implication(opt->implied_by, f);
matched &= !opt->imply || simpl.implication(f, opt->imply);
matched &= !opt->equivalent_to
|| simpl.are_equivalent(f, opt->equivalent_to);
|| simpl.are_equivalent(f, opt->equivalent_to);
matched &= !stutter_insensitive || spot::is_stutter_invariant(f);
// Match obligations and subclasses using WDBA minimization.
@ -608,46 +608,46 @@ namespace
// have to compute it on formulas that have been discarded for
// other reasons.
if (matched && obligation)
{
auto aut = ltl_to_tgba_fm(f, simpl.get_dict());
auto min = minimize_obligation(aut, f);
assert(min);
if (aut == min)
{
// Not an obligation
matched = false;
}
else
{
matched &= !guarantee || is_terminal_automaton(min);
matched &= !safety || is_safety_mwdba(min);
}
}
{
auto aut = ltl_to_tgba_fm(f, simpl.get_dict());
auto min = minimize_obligation(aut, f);
assert(min);
if (aut == min)
{
// Not an obligation
matched = false;
}
else
{
matched &= !guarantee || is_terminal_automaton(min);
matched &= !safety || is_safety_mwdba(min);
}
}
matched ^= invert;
if (unique && !unique_set.insert(f).second)
matched = false;
matched = false;
if (matched)
{
if (opt->output_define
&& output_format != count_output
&& output_format != quiet_output)
{
// Sort the formulas alphabetically.
std::map<std::string, spot::formula> m;
for (auto& p: relmap)
m.emplace(str_psl(p.first), p.second);
for (auto& p: m)
stream_formula(opt->output_define->ostream()
<< "#define " << p.first << " (",
p.second, filename, linenum) << ")\n";
}
one_match = true;
output_formula_checked(f, filename, linenum, prefix, suffix);
++match_count;
}
{
if (opt->output_define
&& output_format != count_output
&& output_format != quiet_output)
{
// Sort the formulas alphabetically.
std::map<std::string, spot::formula> m;
for (auto& p: relmap)
m.emplace(str_psl(p.first), p.second);
for (auto& p: m)
stream_formula(opt->output_define->ostream()
<< "#define " << p.first << " (",
p.second, filename, linenum) << ")\n";
}
one_match = true;
output_formula_checked(f, filename, linenum, prefix, suffix);
++match_count;
}
return 0;
}
};
@ -659,7 +659,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "[FILENAME[/COL]...]",
argp_program_doc, children, nullptr, nullptr };
argp_program_doc, children, nullptr, nullptr };
try
{
@ -669,20 +669,20 @@ main(int argc, char** argv)
opt = &o;
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
exit(err);
if (jobs.empty())
jobs.emplace_back("-", 1);
jobs.emplace_back("-", 1);
if (boolean_to_isop && simplification_level == 0)
simplification_level = 1;
simplification_level = 1;
spot::tl_simplifier_options opt(simplification_level);
opt.boolean_to_isop = boolean_to_isop;
spot::tl_simplifier simpl(opt);
ltl_processor processor(simpl);
if (processor.run())
return 2;
return 2;
}
catch (const std::runtime_error& e)
{

View file

@ -113,12 +113,12 @@ namespace
public:
int
process_formula(spot::formula f, const char* filename = nullptr,
int linenum = 0)
int linenum = 0)
{
auto mutations =
spot::mutate(f, mut_opts, max_output, mutation_nb, opt_sort);
spot::mutate(f, mut_opts, max_output, mutation_nb, opt_sort);
for (auto g: mutations)
output_formula_checked(g, filename, linenum, prefix, suffix);
output_formula_checked(g, filename, linenum, prefix, suffix);
return 0;
}
};
@ -182,7 +182,7 @@ main(int argc, char* argv[])
setup(argv);
const argp ap = { options, parse_opt, "[FILENAME[/COL]...]", argp_program_doc,
children, nullptr, nullptr };
children, nullptr, nullptr };
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);

View file

@ -191,24 +191,24 @@ parse_opt(int key, char* arg, struct argp_state* as)
case 'a':
opt_acc_prob = to_float(arg);
if (opt_acc_prob < 0.0 || opt_acc_prob > 1.0)
error(2, 0, "probability of acceptance set membership "
"should be between 0.0 and 1.0");
error(2, 0, "probability of acceptance set membership "
"should be between 0.0 and 1.0");
break;
case 'A':
if (looks_like_a_range(arg))
{
opt_acc_sets = parse_range(arg);
if (opt_acc_sets.min > opt_acc_sets.max)
std::swap(opt_acc_sets.min, opt_acc_sets.max);
if (opt_acc_sets.min < 0)
error(2, 0, "number of acceptance sets should be positive");
gba_wanted = true;
}
{
opt_acc_sets = parse_range(arg);
if (opt_acc_sets.min > opt_acc_sets.max)
std::swap(opt_acc_sets.min, opt_acc_sets.max);
if (opt_acc_sets.min < 0)
error(2, 0, "number of acceptance sets should be positive");
gba_wanted = true;
}
else
{
opt_acceptance = arg;
generic_wanted = true;
}
{
opt_acceptance = arg;
generic_wanted = true;
}
break;
case 'B':
ba_options();
@ -217,7 +217,7 @@ parse_opt(int key, char* arg, struct argp_state* as)
case 'e':
opt_density = to_float(arg);
if (opt_density < 0.0 || opt_density > 1.0)
error(2, 0, "density should be between 0.0 and 1.0");
error(2, 0, "density should be between 0.0 and 1.0");
break;
case 'D':
opt_deterministic = true;
@ -228,9 +228,9 @@ parse_opt(int key, char* arg, struct argp_state* as)
case 'Q':
opt_states = parse_range(arg);
if (opt_states.min > opt_states.max)
std::swap(opt_states.min, opt_states.max);
std::swap(opt_states.min, opt_states.max);
if (opt_states.min == 0)
error(1, 0, "cannot build an automaton with 0 states");
error(1, 0, "cannot build an automaton with 0 states");
break;
case 'S':
opt_state_acc = true;
@ -255,14 +255,14 @@ parse_opt(int key, char* arg, struct argp_state* as)
// last non-option argument, and if aprops.empty() we know this
// is the also the first one.
if (opt->aprops.empty()
&& as->argc == as->next && looks_like_a_range(arg))
{
ap_count_given = parse_range(arg);
// Create the set once if the count is fixed.
if (ap_count_given.min == ap_count_given.max)
opt->aprops = spot::create_atomic_prop_set(ap_count_given.min);
break;
}
&& as->argc == as->next && looks_like_a_range(arg))
{
ap_count_given = parse_range(arg);
// Create the set once if the count is fixed.
if (ap_count_given.min == ap_count_given.max)
opt->aprops = spot::create_atomic_prop_set(ap_count_given.min);
break;
}
opt->aprops.insert(spot::formula::ap(arg));
break;
@ -281,7 +281,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "N|PROP...", argp_program_doc,
children, nullptr, nullptr };
children, nullptr, nullptr };
try
{
@ -291,43 +291,43 @@ main(int argc, char** argv)
opt = &o;
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
exit(err);
// running 'randaut 0' is one way to generate automata using no
// atomic propositions so do not complain in that case.
if (opt->aprops.empty() && ap_count_given.max < 0)
error(2, 0,
"No atomic proposition supplied? Run '%s --help' for usage.",
program_name);
error(2, 0,
"No atomic proposition supplied? Run '%s --help' for usage.",
program_name);
if (generic_wanted && automaton_format == Spin)
error(2, 0,
"--spin implies --ba so should not be used with --acceptance");
error(2, 0,
"--spin implies --ba so should not be used with --acceptance");
if (generic_wanted && ba_wanted)
error(2, 0, "--acceptance and --ba may not be used together");
error(2, 0, "--acceptance and --ba may not be used together");
if (automaton_format == Spin && opt_acc_sets.max > 1)
error(2, 0, "--spin is incompatible with --acceptance=%d..%d",
opt_acc_sets.min, opt_acc_sets.max);
error(2, 0, "--spin is incompatible with --acceptance=%d..%d",
opt_acc_sets.min, opt_acc_sets.max);
if (ba_wanted && opt_acc_sets.min != 1 && opt_acc_sets.max != 1)
error(2, 0, "--ba is incompatible with --acceptance=%d..%d",
opt_acc_sets.min, opt_acc_sets.max);
error(2, 0, "--ba is incompatible with --acceptance=%d..%d",
opt_acc_sets.min, opt_acc_sets.max);
if (ba_wanted && generic_wanted)
error(2, 0,
"--ba is incompatible with --acceptance=%s", opt_acceptance);
error(2, 0,
"--ba is incompatible with --acceptance=%s", opt_acceptance);
if (automaton_format == Spin)
ba_options();
ba_options();
if (opt_colored && opt_acc_sets.min == -1 && !generic_wanted)
error(2, 0, "--colored requires at least one acceptance set; "
"use --acceptance");
error(2, 0, "--colored requires at least one acceptance set; "
"use --acceptance");
if (opt_colored && opt_acc_sets.min == 0)
error(2, 0, "--colored requires at least one acceptance set; "
"fix the range of --acceptance");
error(2, 0, "--colored requires at least one acceptance set; "
"fix the range of --acceptance");
if (opt_acc_sets.min == -1)
opt_acc_sets.min = 0;
opt_acc_sets.min = 0;
spot::srand(opt_seed);
auto d = spot::make_bdd_dict();
@ -340,70 +340,70 @@ main(int argc, char** argv)
int automaton_num = 0;
for (;;)
{
spot::stopwatch sw;
sw.start();
{
spot::stopwatch sw;
sw.start();
if (ap_count_given.max > 0
&& ap_count_given.min != ap_count_given.max)
{
int c = spot::rrand(ap_count_given.min, ap_count_given.max);
opt->aprops = spot::create_atomic_prop_set(c);
}
if (ap_count_given.max > 0
&& ap_count_given.min != ap_count_given.max)
{
int c = spot::rrand(ap_count_given.min, ap_count_given.max);
opt->aprops = spot::create_atomic_prop_set(c);
}
int size = opt_states.min;
if (size != opt_states.max)
size = spot::rrand(size, opt_states.max);
int size = opt_states.min;
if (size != opt_states.max)
size = spot::rrand(size, opt_states.max);
int accs = opt_acc_sets.min;
if (accs != opt_acc_sets.max)
accs = spot::rrand(accs, opt_acc_sets.max);
int accs = opt_acc_sets.min;
if (accs != opt_acc_sets.max)
accs = spot::rrand(accs, opt_acc_sets.max);
spot::acc_cond::acc_code code;
if (opt_acceptance)
{
code = spot::acc_cond::acc_code(opt_acceptance);
accs = code.used_sets().max_set();
if (opt_colored && accs == 0)
error(2, 0, "--colored requires at least one acceptance set; "
"fix the range of --acceptance");
}
spot::acc_cond::acc_code code;
if (opt_acceptance)
{
code = spot::acc_cond::acc_code(opt_acceptance);
accs = code.used_sets().max_set();
if (opt_colored && accs == 0)
error(2, 0, "--colored requires at least one acceptance set; "
"fix the range of --acceptance");
}
auto aut =
spot::random_graph(size, opt_density, &opt->aprops, d,
accs, opt_acc_prob, 0.5,
opt_deterministic, opt_state_acc,
opt_colored);
auto aut =
spot::random_graph(size, opt_density, &opt->aprops, d,
accs, opt_acc_prob, 0.5,
opt_deterministic, opt_state_acc,
opt_colored);
if (opt_acceptance)
aut->set_acceptance(accs, code);
if (opt_acceptance)
aut->set_acceptance(accs, code);
if (opt_uniq)
{
auto tmp = spot::canonicalize
(make_twa_graph(aut, spot::twa::prop_set::all()));
std::vector<tr_t> trans(tmp->edge_vector().begin() + 1,
tmp->edge_vector().end());
if (!opt_uniq->emplace(trans).second)
{
--trials;
if (trials == 0)
error(2, 0, "failed to generate a new unique automaton"
" after %d trials", max_trials);
continue;
}
trials = max_trials;
}
if (opt_uniq)
{
auto tmp = spot::canonicalize
(make_twa_graph(aut, spot::twa::prop_set::all()));
std::vector<tr_t> trans(tmp->edge_vector().begin() + 1,
tmp->edge_vector().end());
if (!opt_uniq->emplace(trans).second)
{
--trials;
if (trials == 0)
error(2, 0, "failed to generate a new unique automaton"
" after %d trials", max_trials);
continue;
}
trials = max_trials;
}
auto runtime = sw.stop();
auto runtime = sw.stop();
printer.print(aut, nullptr,
opt_seed_str, automaton_num, runtime, nullptr);
printer.print(aut, nullptr,
opt_seed_str, automaton_num, runtime, nullptr);
++automaton_num;
if (opt_automata > 0 && automaton_num >= opt_automata)
break;
}
++automaton_num;
if (opt_automata > 0 && automaton_num >= opt_automata)
break;
}
}
catch (const std::runtime_error& e)
{

View file

@ -197,7 +197,7 @@ parse_opt(int key, char* arg, struct argp_state* as)
case OPT_TREE_SIZE:
opt_tree_size = parse_range(arg);
if (opt_tree_size.min > opt_tree_size.max)
std::swap(opt_tree_size.min, opt_tree_size.max);
std::swap(opt_tree_size.min, opt_tree_size.max);
break;
case OPT_WF:
opt_wf = true;
@ -211,16 +211,16 @@ parse_opt(int key, char* arg, struct argp_state* as)
// last non-option argument, and if aprops.empty() we know this
// is the also the first one.
if (opt->aprops.empty() && as->argc == as->next)
{
char* endptr;
int res = strtol(arg, &endptr, 10);
if (!*endptr && res >= 0) // arg is a number
{
ap_count_given = true;
opt->aprops = spot::create_atomic_prop_set(res);
break;
}
}
{
char* endptr;
int res = strtol(arg, &endptr, 10);
if (!*endptr && res >= 0) // arg is a number
{
ap_count_given = true;
opt->aprops = spot::create_atomic_prop_set(res);
break;
}
}
opt->aprops.insert(spot::default_environment::instance().require(arg));
break;
default:
@ -235,7 +235,7 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, parse_opt, "N|PROP...", argp_program_doc,
children, nullptr, nullptr };
children, nullptr, nullptr };
try
{
@ -245,78 +245,78 @@ main(int argc, char** argv)
opt = &o;
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
exit(err);
// running 'randltl 0' is one way to generate formulas using no
// atomic propositions so do not complain in that case.
if (opt->aprops.empty() && !ap_count_given)
error(2, 0, "No atomic proposition supplied? "
"Run '%s --help' for usage.", program_name);
error(2, 0, "No atomic proposition supplied? "
"Run '%s --help' for usage.", program_name);
spot::srand(opt_seed);
spot::randltlgenerator rg
(opt->aprops,
[&] (){
spot::option_map opts;
opts.set("output", output);
opts.set("tree_size_min", opt_tree_size.min);
opts.set("tree_size_max", opt_tree_size.max);
opts.set("wf", opt_wf);
opts.set("seed", opt_seed);
opts.set("simplification_level", simplification_level);
return opts;
}(), opt_pL, opt_pS, opt_pB);
(opt->aprops,
[&] (){
spot::option_map opts;
opts.set("output", output);
opts.set("tree_size_min", opt_tree_size.min);
opts.set("tree_size_max", opt_tree_size.max);
opts.set("wf", opt_wf);
opts.set("seed", opt_seed);
opts.set("simplification_level", simplification_level);
return opts;
}(), opt_pL, opt_pS, opt_pB);
if (opt_dump_priorities)
{
switch (output)
{
case OUTPUTLTL:
std::cout <<
"Use --ltl-priorities to set the following LTL priorities:\n";
rg.dump_ltl_priorities(std::cout);
break;
case OUTPUTBOOL:
std::cout <<
"Use --boolean-priorities to set the following Boolean "
"formula priorities:\n";
rg.dump_bool_priorities(std::cout);
break;
case OUTPUTPSL:
std::cout <<
"Use --ltl-priorities to set the following LTL priorities:\n";
rg.dump_psl_priorities(std::cout);
// Fall through.
case OUTPUTSERE:
std::cout <<
"Use --sere-priorities to set the following SERE priorities:\n";
rg.dump_sere_priorities(std::cout);
std::cout <<
"Use --boolean-priorities to set the following Boolean "
"formula priorities:\n";
rg.dump_sere_bool_priorities(std::cout);
break;
default:
error(2, 0, "internal error: unknown type of output");
}
exit(0);
}
{
switch (output)
{
case OUTPUTLTL:
std::cout <<
"Use --ltl-priorities to set the following LTL priorities:\n";
rg.dump_ltl_priorities(std::cout);
break;
case OUTPUTBOOL:
std::cout <<
"Use --boolean-priorities to set the following Boolean "
"formula priorities:\n";
rg.dump_bool_priorities(std::cout);
break;
case OUTPUTPSL:
std::cout <<
"Use --ltl-priorities to set the following LTL priorities:\n";
rg.dump_psl_priorities(std::cout);
// Fall through.
case OUTPUTSERE:
std::cout <<
"Use --sere-priorities to set the following SERE priorities:\n";
rg.dump_sere_priorities(std::cout);
std::cout <<
"Use --boolean-priorities to set the following Boolean "
"formula priorities:\n";
rg.dump_sere_bool_priorities(std::cout);
break;
default:
error(2, 0, "internal error: unknown type of output");
}
exit(0);
}
while (opt_formulas < 0 || opt_formulas--)
{
static int count = 0;
spot::formula f = rg.next();
if (!f)
{
error(2, 0, "failed to generate a new unique formula after %d " \
"trials", MAX_TRIALS);
}
else
{
output_formula_checked(f, nullptr, ++count);
}
};
{
static int count = 0;
spot::formula f = rg.next();
if (!f)
{
error(2, 0, "failed to generate a new unique formula after %d " \
"trials", MAX_TRIALS);
}
else
{
output_formula_checked(f, nullptr, ++count);
}
};
}
catch (const std::runtime_error& e)
{

View file

@ -113,7 +113,7 @@ Enabled by default.") },
if the TGBA is not already deterministic. Doing so will degeneralize \
the automaton. This is disabled by default, unless sat-minimize is set.") },
{ DOC("sat-minimize",
"Set to 1 to enable SAT-based minimization of deterministic \
"Set to 1 to enable SAT-based minimization of deterministic \
TGBA: it starts with the number of states of the input, and iteratively \
tries to find a deterministic TGBA with one less state. Set to 2 to perform \
a binary search instead. Disabled (0) by default. The sat solver to use \
@ -123,7 +123,7 @@ set; this can be changed with the sat-acc option, or of course by using -B \
to construct a Büchi automaton. Enabling SAT-based minimization will \
also enable tba-det.") },
{ DOC("sat-states",
"When this is set to some positive integer, the SAT-based \
"When this is set to some positive integer, the SAT-based \
minimization will attempt to construct a TGBA with the given number of \
states. It may however return an automaton with less states if some of \
these are unreachable or useless. Setting sat-states automatically \
@ -131,13 +131,13 @@ enables sat-minimize, but no iteration is performed. If no equivalent \
automaton could be constructed with the given number of states, the original \
automaton is returned.") },
{ DOC("sat-acc",
"When this is set to some positive integer, the SAT-based will \
"When this is set to some positive integer, the SAT-based will \
attempt to construct a TGBA with the given number of acceptance sets. \
states. It may however return an automaton with less acceptance sets if \
some of these are useless. Setting sat-acc automatically \
sets sat-minimize to 1 if not set differently.") },
{ DOC("state-based",
"Set to 1 to instruct the SAT-minimization procedure to produce \
"Set to 1 to instruct the SAT-minimization procedure to produce \
a TGBA where all outgoing transition of a state have the same acceptance \
sets. By default this is only enabled when option -B is used.") },
{ nullptr, 0, nullptr, 0, nullptr, 0 }
@ -155,13 +155,13 @@ main(int argc, char** argv)
setup(argv);
const argp ap = { options, nullptr, nullptr, argp_program_doc, children,
nullptr, nullptr };
nullptr, nullptr };
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, nullptr, nullptr))
exit(err);
std::cerr << "This binary serves no purpose other than generating"
<< " the spot-x.7 manpage.\n";
<< " the spot-x.7 manpage.\n";
return 1;
}

View file

@ -47,7 +47,7 @@ namespace spot
struct first_is_base_of<Of, Arg1, Args...>
{
static const bool value =
std::is_base_of<Of, typename std::decay<Arg1>::type>::value;
std::is_base_of<Of, typename std::decay<Arg1>::type>::value;
};
#endif
@ -65,11 +65,11 @@ namespace spot
#ifndef SWIG
template <typename... Args,
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: label{std::forward<Args>(args)...}
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: label{std::forward<Args>(args)...}
{
}
#endif
@ -77,23 +77,23 @@ namespace spot
// if Data is a POD type, G++ 4.8.2 wants default values for all
// label fields unless we define this default constructor here.
explicit boxed_label()
noexcept(std::is_nothrow_constructible<Data>::value)
noexcept(std::is_nothrow_constructible<Data>::value)
{
}
Data& data()
{
return label;
return label;
}
const Data& data() const
{
return label;
return label;
}
bool operator<(const boxed_label& other) const
{
return label < other.label;
return label < other.label;
}
};
@ -103,12 +103,12 @@ namespace spot
typedef std::tuple<> data_t;
std::tuple<>& data()
{
return *this;
return *this;
}
const std::tuple<>& data() const
{
return *this;
return *this;
}
};
@ -120,11 +120,11 @@ namespace spot
#ifndef SWIG
template <typename... Args,
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: Data{std::forward<Args>(args)...}
typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type>
boxed_label(Args&&... args)
noexcept(std::is_nothrow_constructible<Data, Args...>::value)
: Data{std::forward<Args>(args)...}
{
}
#endif
@ -132,18 +132,18 @@ namespace spot
// if Data is a POD type, G++ 4.8.2 wants default values for all
// label fields unless we define this default constructor here.
explicit boxed_label()
noexcept(std::is_nothrow_constructible<Data>::value)
noexcept(std::is_nothrow_constructible<Data>::value)
{
}
Data& data()
{
return *this;
return *this;
}
const Data& data() const
{
return *this;
return *this;
}
};
@ -158,15 +158,15 @@ namespace spot
struct SPOT_API distate_storage final: public State_Data
{
Edge succ = 0; // First outgoing edge (used when iterating)
Edge succ_tail = 0; // Last outgoing edge (used for
// appending new edges)
Edge succ_tail = 0; // Last outgoing edge (used for
// appending new edges)
#ifndef SWIG
template <typename... Args,
typename = typename std::enable_if<
!first_is_base_of<distate_storage, Args...>::value>::type>
typename = typename std::enable_if<
!first_is_base_of<distate_storage, Args...>::value>::type>
distate_storage(Args&&... args)
noexcept(std::is_nothrow_constructible<State_Data, Args...>::value)
: State_Data{std::forward<Args>(args)...}
noexcept(std::is_nothrow_constructible<State_Data, Args...>::value)
: State_Data{std::forward<Args>(args)...}
{
}
#endif
@ -179,47 +179,47 @@ namespace spot
// Again two implementation: one with label, and one without.
template <typename StateIn,
typename StateOut, typename Edge, typename Edge_Data>
typename StateOut, typename Edge, typename Edge_Data>
struct SPOT_API edge_storage final: public Edge_Data
{
typedef Edge edge;
StateOut dst; // destination
Edge next_succ; // next outgoing edge with same
// source, or 0
StateIn src; // source
StateOut dst; // destination
Edge next_succ; // next outgoing edge with same
// source, or 0
StateIn src; // source
explicit edge_storage()
noexcept(std::is_nothrow_constructible<Edge_Data>::value)
: Edge_Data{}
noexcept(std::is_nothrow_constructible<Edge_Data>::value)
: Edge_Data{}
{
}
#ifndef SWIG
template <typename... Args>
edge_storage(StateOut dst, Edge next_succ,
StateIn src, Args&&... args)
noexcept(std::is_nothrow_constructible<Edge_Data, Args...>::value
&& std::is_nothrow_constructible<StateOut, StateOut>::value
&& std::is_nothrow_constructible<Edge, Edge>::value)
: Edge_Data{std::forward<Args>(args)...},
dst(dst), next_succ(next_succ), src(src)
StateIn src, Args&&... args)
noexcept(std::is_nothrow_constructible<Edge_Data, Args...>::value
&& std::is_nothrow_constructible<StateOut, StateOut>::value
&& std::is_nothrow_constructible<Edge, Edge>::value)
: Edge_Data{std::forward<Args>(args)...},
dst(dst), next_succ(next_succ), src(src)
{
}
#endif
bool operator<(const edge_storage& other) const
{
if (src < other.src)
return true;
if (src > other.src)
return false;
// This might be costly if the destination is a vector
if (dst < other.dst)
return true;
if (dst > other.dst)
return false;
return this->data() < other.data();
if (src < other.src)
return true;
if (src > other.src)
return false;
// This might be costly if the destination is a vector
if (dst < other.dst)
return true;
if (dst > other.dst)
return false;
return this->data() < other.data();
}
bool operator==(const edge_storage& other) const
@ -241,86 +241,86 @@ namespace spot
template <typename Graph>
class SPOT_API edge_iterator: public
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
{
typedef
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
public:
typedef typename Graph::edge edge;
edge_iterator() noexcept
: g_(nullptr), t_(0)
: g_(nullptr), t_(0)
{
}
edge_iterator(Graph* g, edge t) noexcept
: g_(g), t_(t)
: g_(g), t_(t)
{
}
bool operator==(edge_iterator o) const
{
return t_ == o.t_;
return t_ == o.t_;
}
bool operator!=(edge_iterator o) const
{
return t_ != o.t_;
return t_ != o.t_;
}
typename super::reference
operator*()
{
return g_->edge_storage(t_);
return g_->edge_storage(t_);
}
const typename super::reference
operator*() const
{
return g_->edge_storage(t_);
return g_->edge_storage(t_);
}
typename super::pointer
operator->()
{
return &g_->edge_storage(t_);
return &g_->edge_storage(t_);
}
const typename super::pointer
operator->() const
{
return &g_->edge_storage(t_);
return &g_->edge_storage(t_);
}
edge_iterator operator++()
{
t_ = operator*().next_succ;
return *this;
t_ = operator*().next_succ;
return *this;
}
edge_iterator operator++(int)
{
edge_iterator ti = *this;
t_ = operator*().next_succ;
return ti;
edge_iterator ti = *this;
t_ = operator*().next_succ;
return ti;
}
operator bool() const
{
return t_;
return t_;
}
edge trans() const
{
return t_;
return t_;
}
protected:
@ -337,52 +337,52 @@ namespace spot
typedef typename Graph::edge edge;
killer_edge_iterator(Graph* g, edge t, state_storage_t& src) noexcept
: super(g, t), src_(src), prev_(0)
: super(g, t), src_(src), prev_(0)
{
}
killer_edge_iterator operator++()
{
prev_ = this->t_;
this->t_ = this->operator*().next_succ;
return *this;
prev_ = this->t_;
this->t_ = this->operator*().next_succ;
return *this;
}
killer_edge_iterator operator++(int)
{
killer_edge_iterator ti = *this;
++*this;
return ti;
killer_edge_iterator ti = *this;
++*this;
return ti;
}
// Erase the current edge and advance the iterator.
void erase()
{
edge next = this->operator*().next_succ;
edge next = this->operator*().next_succ;
// Update source state and previous edges
if (prev_)
{
this->g_->edge_storage(prev_).next_succ = next;
}
else
{
if (src_.succ == this->t_)
src_.succ = next;
}
if (src_.succ_tail == this->t_)
{
src_.succ_tail = prev_;
assert(next == 0);
}
// Update source state and previous edges
if (prev_)
{
this->g_->edge_storage(prev_).next_succ = next;
}
else
{
if (src_.succ == this->t_)
src_.succ = next;
}
if (src_.succ_tail == this->t_)
{
src_.succ_tail = prev_;
assert(next == 0);
}
// Erased edges have themselves as next_succ.
this->operator*().next_succ = this->t_;
// Erased edges have themselves as next_succ.
this->operator*().next_succ = this->t_;
// Advance iterator to next edge.
this->t_ = next;
// Advance iterator to next edge.
this->t_ = next;
++this->g_->killed_edge_;
++this->g_->killed_edge_;
}
protected:
@ -403,23 +403,23 @@ namespace spot
public:
typedef typename Graph::edge edge;
state_out(Graph* g, edge t) noexcept
: g_(g), t_(t)
: g_(g), t_(t)
{
}
edge_iterator<Graph> begin()
{
return {g_, t_};
return {g_, t_};
}
edge_iterator<Graph> end()
{
return {};
return {};
}
void recycle(edge t)
{
t_ = t;
t_ = t;
}
protected:
@ -434,92 +434,92 @@ namespace spot
template <typename Graph>
class SPOT_API all_edge_iterator: public
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
{
typedef
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
std::iterator<std::forward_iterator_tag,
typename
std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type>
super;
typedef typename std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
unsigned t_;
tv_t& tv_;
void skip_()
{
unsigned s = tv_.size();
do
++t_;
while (t_ < s && tv_[t_].next_succ == t_);
unsigned s = tv_.size();
do
++t_;
while (t_ < s && tv_[t_].next_succ == t_);
}
public:
all_edge_iterator(unsigned pos, tv_t& tv) noexcept
: t_(pos), tv_(tv)
: t_(pos), tv_(tv)
{
skip_();
skip_();
}
all_edge_iterator(tv_t& tv) noexcept
: t_(tv.size()), tv_(tv)
: t_(tv.size()), tv_(tv)
{
}
all_edge_iterator& operator++()
{
skip_();
return *this;
skip_();
return *this;
}
all_edge_iterator operator++(int)
{
all_edge_iterator old = *this;
++*this;
return old;
all_edge_iterator old = *this;
++*this;
return old;
}
bool operator==(all_edge_iterator o) const
{
return t_ == o.t_;
return t_ == o.t_;
}
bool operator!=(all_edge_iterator o) const
{
return t_ != o.t_;
return t_ != o.t_;
}
typename super::reference
operator*()
{
return tv_[t_];
return tv_[t_];
}
const typename super::reference
operator*() const
{
return tv_[t_];
return tv_[t_];
}
const typename super::pointer
operator->()
{
return &tv_[t_];
return &tv_[t_];
}
typename super::pointer
operator->() const
{
return &tv_[t_];
return &tv_[t_];
}
};
@ -529,27 +529,27 @@ namespace spot
{
public:
typedef typename std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
const typename Graph::edge_vector_t,
typename Graph::edge_vector_t>::type
tv_t;
typedef all_edge_iterator<Graph> iter_t;
private:
tv_t& tv_;
public:
all_trans(tv_t& tv) noexcept
: tv_(tv)
: tv_(tv)
{
}
iter_t begin()
{
return {0, tv_};
return {0, tv_};
}
iter_t end()
{
return {tv_};
return {tv_};
}
};
@ -586,14 +586,14 @@ namespace spot
// The type of an output state (when seen from a edge)
// depends on the kind of graph we build
typedef typename std::conditional<Alternating,
std::vector<state>,
state>::type out_state;
std::vector<state>,
state>::type out_state;
typedef internal::distate_storage<edge,
internal::boxed_label<State_Data>>
internal::boxed_label<State_Data>>
state_storage_t;
typedef internal::edge_storage<state, out_state, edge,
internal::boxed_label<Edge_Data>>
internal::boxed_label<Edge_Data>>
edge_storage_t;
typedef std::vector<state_storage_t> state_vector;
typedef std::vector<edge_storage_t> edge_vector_t;
@ -614,7 +614,7 @@ namespace spot
{
states_.reserve(max_states);
if (max_trans == 0)
max_trans = max_states * 2;
max_trans = max_states * 2;
edges_.reserve(max_trans + 1);
// Edge number 0 is not used, because we use this index
// to mark the absence of a edge.
@ -638,7 +638,7 @@ namespace spot
// Erased edges have their next_succ pointing to
// themselves.
return (t < edges_.size() &&
edges_[t].next_succ != t);
edges_[t].next_succ != t);
}
template <typename... Args>
@ -655,7 +655,7 @@ namespace spot
state s = states_.size();
states_.reserve(s + n);
while (n--)
states_.emplace_back(std::forward<Args>(args)...);
states_.emplace_back(std::forward<Args>(args)...);
return s;
}
@ -730,9 +730,9 @@ namespace spot
edge st = states_[src].succ_tail;
assert(st < t || !st);
if (!st)
states_[src].succ = t;
states_[src].succ = t;
else
edges_[st].next_succ = t;
edges_[st].next_succ = t;
states_[src].succ_tail = t;
return t;
}
@ -836,19 +836,19 @@ namespace spot
{
unsigned tend = edges_.size();
for (unsigned t = 1; t < tend; ++t)
{
o << 't' << t << ": (s"
<< edges_[t].src << ", s"
<< edges_[t].dst << ") t"
<< edges_[t].next_succ << '\n';
}
{
o << 't' << t << ": (s"
<< edges_[t].src << ", s"
<< edges_[t].dst << ") t"
<< edges_[t].next_succ << '\n';
}
unsigned send = states_.size();
for (unsigned s = 0; s < send; ++s)
{
o << 's' << s << ": t"
<< states_[s].succ << " t"
<< states_[s].succ_tail << '\n';
}
{
o << 's' << s << ": t"
<< states_[s].succ << " t"
<< states_[s].succ_tail << '\n';
}
}
// Remove all dead edges. The edges_ vector is left
@ -858,11 +858,11 @@ namespace spot
void remove_dead_edges_()
{
if (killed_edge_ == 0)
return;
return;
auto i = std::remove_if(edges_.begin() + 1, edges_.end(),
[this](const edge_storage_t& t) {
return this->is_dead_edge(t);
});
[this](const edge_storage_t& t) {
return this->is_dead_edge(t);
});
edges_.erase(i, edges_.end());
killed_edge_ = 0;
}
@ -885,38 +885,38 @@ namespace spot
state last_src = -1U;
edge tend = edges_.size();
for (edge t = 1; t < tend; ++t)
{
state src = edges_[t].src;
if (src != last_src)
{
states_[src].succ = t;
if (last_src != -1U)
{
states_[last_src].succ_tail = t - 1;
edges_[t - 1].next_succ = 0;
}
while (++last_src != src)
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
}
else
{
edges_[t - 1].next_succ = t;
}
}
{
state src = edges_[t].src;
if (src != last_src)
{
states_[src].succ = t;
if (last_src != -1U)
{
states_[last_src].succ_tail = t - 1;
edges_[t - 1].next_succ = 0;
}
while (++last_src != src)
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
}
else
{
edges_[t - 1].next_succ = t;
}
}
if (last_src != -1U)
{
states_[last_src].succ_tail = tend - 1;
edges_[tend - 1].next_succ = 0;
}
{
states_[last_src].succ_tail = tend - 1;
edges_[tend - 1].next_succ = 0;
}
unsigned send = states_.size();
while (++last_src != send)
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
{
states_[last_src].succ = 0;
states_[last_src].succ_tail = 0;
}
//std::cerr << "\nafter\n";
//dump_storage(std::cerr);
}
@ -930,10 +930,10 @@ namespace spot
assert(newst.size() == states_.size());
unsigned tend = edges_.size();
for (unsigned t = 1; t < tend; t++)
{
edges_[t].dst = newst[edges_[t].dst];
edges_[t].src = newst[edges_[t].src];
}
{
edges_[t].dst = newst[edges_[t].dst];
edges_[t].src = newst[edges_[t].src];
}
}
void defrag_states(std::vector<unsigned>&& newst, unsigned used_states)
@ -947,22 +947,22 @@ namespace spot
// Shift all states in states_, as indicated by newst.
unsigned send = states_.size();
for (state s = 0; s < send; ++s)
{
state dst = newst[s];
if (dst == s)
continue;
if (dst == -1U)
{
// This is an erased state. Mark all its edges as
// dead (i.e., t.next_succ should point to t for each of
// them).
auto t = states_[s].succ;
while (t)
std::swap(t, edges_[t].next_succ);
continue;
}
states_[dst] = std::move(states_[s]);
}
{
state dst = newst[s];
if (dst == s)
continue;
if (dst == -1U)
{
// This is an erased state. Mark all its edges as
// dead (i.e., t.next_succ should point to t for each of
// them).
auto t = states_[s].succ;
while (t)
std::swap(t, edges_[t].next_succ);
continue;
}
states_[dst] = std::move(states_[s]);
}
states_.resize(used_states);
// Shift all edges in edges_. The algorithm is
@ -972,33 +972,33 @@ namespace spot
std::vector<edge> newidx(tend);
unsigned dest = 1;
for (edge t = 1; t < tend; ++t)
{
if (is_dead_edge(t))
continue;
if (t != dest)
edges_[dest] = std::move(edges_[t]);
newidx[t] = dest;
++dest;
}
{
if (is_dead_edge(t))
continue;
if (t != dest)
edges_[dest] = std::move(edges_[t]);
newidx[t] = dest;
++dest;
}
edges_.resize(dest);
killed_edge_ = 0;
// Adjust next_succ and dst pointers in all edges.
for (edge t = 1; t < dest; ++t)
{
auto& tr = edges_[t];
tr.next_succ = newidx[tr.next_succ];
tr.dst = newst[tr.dst];
tr.src = newst[tr.src];
assert(tr.dst != -1U);
}
{
auto& tr = edges_[t];
tr.next_succ = newidx[tr.next_succ];
tr.dst = newst[tr.dst];
tr.src = newst[tr.src];
assert(tr.dst != -1U);
}
// Adjust succ and succ_tails pointers in all states.
for (auto& s: states_)
{
s.succ = newidx[s.succ];
s.succ_tail = newidx[s.succ_tail];
}
{
s.succ = newidx[s.succ];
s.succ_tail = newidx[s.succ_tail];
}
//std::cerr << "\nafter defrag\n";
//dump_storage(std::cerr);

View file

@ -26,9 +26,9 @@
namespace spot
{
template <typename Graph,
typename State_Name,
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
typename State_Name,
typename Name_Hash = std::hash<State_Name>,
typename Name_Equal = std::equal_to<State_Name>>
class SPOT_API named_graph
{
protected:
@ -40,7 +40,7 @@ namespace spot
typedef State_Name name;
typedef std::unordered_map<name, state,
Name_Hash, Name_Equal> name_to_state_t;
Name_Hash, Name_Equal> name_to_state_t;
name_to_state_t name_to_state;
typedef std::vector<name> state_to_name_t;
state_to_name_t state_to_name;
@ -65,14 +65,14 @@ namespace spot
{
auto p = name_to_state.emplace(n, 0U);
if (p.second)
{
unsigned s = g_.new_state(std::forward<Args>(args)...);
p.first->second = s;
if (state_to_name.size() < s + 1)
state_to_name.resize(s + 1);
state_to_name[s] = n;
return s;
}
{
unsigned s = g_.new_state(std::forward<Args>(args)...);
p.first->second = s;
if (state_to_name.size() < s + 1)
state_to_name.resize(s + 1);
state_to_name[s] = n;
return s;
}
return p.first->second;
}
@ -85,27 +85,27 @@ namespace spot
{
auto p = name_to_state.emplace(newname, s);
if (!p.second)
{
// The state already exists. Change its number.
auto old = p.first->second;
p.first->second = s;
// Add the successor of OLD to those of S.
auto& trans = g_.edge_vector();
auto& states = g_.states();
trans[states[s].succ_tail].next_succ = states[old].succ;
states[s].succ_tail = states[old].succ_tail;
states[old].succ = 0;
states[old].succ_tail = 0;
// Remove all references to old in edges:
unsigned tend = trans.size();
for (unsigned t = 1; t < tend; ++t)
{
if (trans[t].src == old)
trans[t].src = s;
if (trans[t].dst == old)
trans[t].dst = s;
}
}
{
// The state already exists. Change its number.
auto old = p.first->second;
p.first->second = s;
// Add the successor of OLD to those of S.
auto& trans = g_.edge_vector();
auto& states = g_.states();
trans[states[s].succ_tail].next_succ = states[old].succ;
states[s].succ_tail = states[old].succ_tail;
states[old].succ = 0;
states[old].succ_tail = 0;
// Remove all references to old in edges:
unsigned tend = trans.size();
for (unsigned t = 1; t < tend; ++t)
{
if (trans[t].src == old)
trans[t].src = s;
if (trans[t].dst == old)
trans[t].dst = s;
}
}
return !p.second;
}
@ -134,7 +134,7 @@ namespace spot
new_edge(name src, name dst, Args&&... args)
{
return g_.new_edge(get_state(src), get_state(dst),
std::forward<Args>(args)...);
std::forward<Args>(args)...);
}
template <typename... Args>
@ -144,19 +144,19 @@ namespace spot
std::vector<State_Name> d;
d.reserve(dst.size());
for (auto n: dst)
d.push_back(get_state(n));
d.push_back(get_state(n));
return g_.new_edge(get_state(src), d, std::forward<Args>(args)...);
}
template <typename... Args>
edge
new_edge(name src,
const std::initializer_list<State_Name>& dst, Args&&... args)
const std::initializer_list<State_Name>& dst, Args&&... args)
{
std::vector<state> d;
d.reserve(dst.size());
for (auto n: dst)
d.push_back(get_state(n));
d.push_back(get_state(n));
return g_.new_edge(get_state(src), d, std::forward<Args>(args)...);
}
};

View file

@ -46,16 +46,16 @@ namespace spot
// Do not simply return "other - this", it might not fit in an int.
if (o < this)
return -1;
return -1;
if (o > this)
return 1;
return 1;
return 0;
}
virtual size_t hash() const override
{
return
reinterpret_cast<const char*>(this) - static_cast<const char*>(nullptr);
reinterpret_cast<const char*>(this) - static_cast<const char*>(nullptr);
}
virtual kripke_graph_state*
@ -93,7 +93,7 @@ namespace spot
edge p_;
public:
kripke_graph_succ_iterator(const Graph* g,
const typename Graph::state_storage_t* s):
const typename Graph::state_storage_t* s):
kripke_succ_iterator(s->cond()),
g_(g),
t_(s->succ)
@ -131,7 +131,7 @@ namespace spot
{
assert(!done());
return const_cast<kripke_graph_state*>
(&g_->state_data(g_->edge_storage(p_).dst));
(&g_->state_data(g_->edge_storage(p_).dst));
}
};
@ -176,14 +176,14 @@ namespace spot
graph_t::state get_init_state_number() const
{
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
const_cast<graph_t&>(g_).new_state();
return init_number_;
}
virtual const kripke_graph_state* get_init_state() const override
{
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
const_cast<graph_t&>(g_).new_state();
return state_from_number(init_number_);
}
@ -197,13 +197,13 @@ namespace spot
assert(!s->succ || g_.valid_trans(s->succ));
if (this->iter_cache_)
{
auto it =
down_cast<kripke_graph_succ_iterator<graph_t>*>(this->iter_cache_);
it->recycle(s);
this->iter_cache_ = nullptr;
return it;
}
{
auto it =
down_cast<kripke_graph_succ_iterator<graph_t>*>(this->iter_cache_);
it->recycle(s);
this->iter_cache_ = nullptr;
return it;
}
return new kripke_graph_succ_iterator<graph_t>(&g_, s);
}

File diff suppressed because it is too large Load diff

View file

@ -67,9 +67,9 @@ namespace spot
// to enable compression, 2 to enable a faster compression that only
// work if all variables are smaller than 2^28.
kripke_ptr kripke(const atomic_prop_set* to_observe,
bdd_dict_ptr dict,
formula dead = formula::tt(),
int compress = 0) const;
bdd_dict_ptr dict,
formula dead = formula::tt(),
int compress = 0) const;
/// Number of variables in a state
int state_size() const;

View file

@ -32,12 +32,12 @@ namespace spot
{
// Bare words cannot be empty and should start with a letter.
if (!*str
|| !(isalpha(*str) || *str == '_' || *str == '.'))
|| !(isalpha(*str) || *str == '_' || *str == '.'))
return false;
// The remaining of the word must be alphanumeric.
while (*++str)
if (!(isalnum(*str) || *str == '_' || *str == '.'))
return false;
return false;
return true;
}
@ -58,7 +58,7 @@ namespace spot
return false;
while (*++str)
if (!(isalnum(*str) || *str == '_'))
return false;
return false;
return true;
}

View file

@ -39,7 +39,7 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t n = (bitcount + bpb - 1) / bpb;
if (n < 1)
return 1;
return 1;
return n;
}
@ -60,12 +60,12 @@ namespace spot
{
static unsigned long init()
{
return 14695981039346656037UL;
return 14695981039346656037UL;
}
static unsigned long prime()
{
return 1099511628211UL;
return 1099511628211UL;
}
};
#endif
@ -76,12 +76,12 @@ namespace spot
{
static unsigned long init()
{
return 2166136261UL;
return 2166136261UL;
}
static unsigned long prime()
{
return 16777619UL;
return 16777619UL;
}
};
@ -109,7 +109,7 @@ namespace spot
// already contains one int of local_storage_, but
// we allocate n-1 more so that we store the table.
void* mem = operator new(sizeof(bitvect)
+ (n - 1) * sizeof(bitvect::block_t));
+ (n - 1) * sizeof(bitvect::block_t));
bitvect* res = new(mem) bitvect(size_, n, true);
memcpy(res->storage_, storage_, res->block_count_ * sizeof(block_t));
return res;
@ -125,8 +125,8 @@ namespace spot
return res;
for (i = 0; i < m - 1; ++i)
{
res ^= storage_[i];
res *= fnv<sizeof(block_t)>::prime();
res ^= storage_[i];
res *= fnv<sizeof(block_t)>::prime();
}
// Deal with the last block, that might not be fully used.
// Compute the number n of bits used in the last block.
@ -144,7 +144,7 @@ namespace spot
// already contains one int of local_storage_, but
// we allocate n-1 more so that we store the table.
void* mem = operator new(sizeof(bitvect)
+ (n - 1) * sizeof(bitvect::block_t));
+ (n - 1) * sizeof(bitvect::block_t));
return new(mem) bitvect(bitcount, n);
}
@ -176,16 +176,16 @@ namespace spot
size_t end = a.size();
if (end == 0)
{
os << "empty\n";
return os;
os << "empty\n";
return os;
}
int w = floor(log10(end - 1)) + 1;
for (size_t i = 0; i != end; ++i)
{
os.width(w);
os << i;
os.width(1);
os << ": " << a.at(i) << '\n';
os.width(w);
os << i;
os.width(1);
os << ": " << a.at(i) << '\n';
}
return os;
}

View file

@ -44,7 +44,7 @@ namespace spot
///
/// The resulting bitvect_array should be released with <code>delete</code>.
SPOT_API bitvect_array* make_bitvect_array(size_t bitcount,
size_t vectcount);
size_t vectcount);
/// \brief A bit vector
class SPOT_API bitvect
@ -85,14 +85,14 @@ namespace spot
reserve_blocks(other.block_count_);
size_ = other.size();
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = other.storage_[i];
storage_[i] = other.storage_[i];
return *this;
}
~bitvect()
{
if (storage_ != &local_storage_)
free(storage_);
free(storage_);
}
/// Grow the bitvector to \a new_block_count blocks.
@ -101,20 +101,20 @@ namespace spot
void reserve_blocks(size_t new_block_count)
{
if (new_block_count < block_count_)
return;
return;
if (storage_ == &local_storage_)
{
block_t* new_storage_ = static_cast<block_t*>
(malloc(new_block_count * sizeof(block_t)));
for (size_t i = 0; i < block_count_; ++i)
new_storage_[i] = storage_[i];
storage_ = new_storage_;
}
{
block_t* new_storage_ = static_cast<block_t*>
(malloc(new_block_count * sizeof(block_t)));
for (size_t i = 0; i < block_count_; ++i)
new_storage_[i] = storage_[i];
storage_ = new_storage_;
}
else
{
storage_ = static_cast<block_t*>
(realloc(storage_, new_block_count * sizeof(block_t)));
}
{
storage_ = static_cast<block_t*>
(realloc(storage_, new_block_count * sizeof(block_t)));
}
block_count_ = new_block_count;
}
@ -137,44 +137,44 @@ namespace spot
void push_back(bool val)
{
if (size() == capacity())
grow();
grow();
size_t pos = size_++;
if (val)
set(pos);
set(pos);
else
clear(pos);
clear(pos);
}
/// \brief Append the lowest \a count bits of \a data.
void push_back(block_t data, unsigned count)
{
if (size() + count > capacity())
grow();
grow();
const size_t bpb = 8 * sizeof(block_t);
// Clear the higher bits.
if (count != bpb)
data &= (1UL << count) - 1;
data &= (1UL << count) - 1;
size_t n = size() % bpb;
size_t i = size_ / bpb;
size_ += count;
if (n == 0) // Aligned on block_t boundary
{
storage_[i] = data;
}
else // Only (bpb-n) bits free in this block.
{
// Take the lower bpb-n bits of data...
block_t mask = (1UL << (bpb - n)) - 1;
block_t data1 = (data & mask) << n;
mask <<= n;
// ... write them on the higher bpb-n bits of last block.
storage_[i] = (storage_[i] & ~mask) | data1;
// Write the remaining bits in the next block.
if (bpb - n < count)
storage_[i + 1] = data >> (bpb - n);
}
if (n == 0) // Aligned on block_t boundary
{
storage_[i] = data;
}
else // Only (bpb-n) bits free in this block.
{
// Take the lower bpb-n bits of data...
block_t mask = (1UL << (bpb - n)) - 1;
block_t data1 = (data & mask) << n;
mask <<= n;
// ... write them on the higher bpb-n bits of last block.
storage_[i] = (storage_[i] & ~mask) | data1;
// Write the remaining bits in the next block.
if (bpb - n < count)
storage_[i + 1] = data >> (bpb - n);
}
}
size_t size() const
@ -199,7 +199,7 @@ namespace spot
void clear_all()
{
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = 0;
storage_[i] = 0;
}
bool is_fully_clear() const
@ -208,12 +208,12 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < block_count_ - !!rest; ++i)
if (storage_[i] != 0)
return false;
if (storage_[i] != 0)
return false;
// The last block might not be fully used, compare only the
// relevant portion.
if (!rest)
return true;
return true;
block_t mask = (1UL << rest) - 1;
return (storage_[i] & mask) == 0;
}
@ -224,10 +224,10 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < block_count_ - !!rest; ++i)
if (storage_[i] != -1UL)
return false;
if (storage_[i] != -1UL)
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
@ -237,13 +237,13 @@ namespace spot
void set_all()
{
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = -1UL;
storage_[i] = -1UL;
}
void flip_all()
{
for (size_t i = 0; i < block_count_; ++i)
storage_[i] = ~storage_[i];
storage_[i] = ~storage_[i];
}
void set(size_t pos)
@ -273,7 +273,7 @@ namespace spot
assert(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i)
storage_[i] |= other.storage_[i];
storage_[i] |= other.storage_[i];
return *this;
}
@ -282,7 +282,7 @@ namespace spot
assert(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i)
storage_[i] &= other.storage_[i];
storage_[i] &= other.storage_[i];
return *this;
}
@ -291,7 +291,7 @@ namespace spot
assert(other.size_ <= size_);
unsigned m = std::min(other.block_count_, block_count_);
for (size_t i = 0; i < m; ++i)
storage_[i] ^= other.storage_[i];
storage_[i] ^= other.storage_[i];
return *this;
}
@ -299,7 +299,7 @@ namespace spot
{
assert(other.block_count_ <= block_count_);
for (size_t i = 0; i < other.block_count_; ++i)
storage_[i] &= ~other.storage_[i];
storage_[i] &= ~other.storage_[i];
return *this;
}
@ -311,33 +311,33 @@ namespace spot
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < block_count_ - !!rest; ++i)
if ((storage_[i] & other.storage_[i]) != other.storage_[i])
return false;
if ((storage_[i] & other.storage_[i]) != other.storage_[i])
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
return ((storage_[i] & mask & other.storage_[i])
== (other.storage_[i] & mask));
== (other.storage_[i] & mask));
}
bool operator==(const bitvect& other) const
{
if (other.size_ != size_)
return false;
return false;
if (size_ == 0)
return true;
return true;
size_t i;
size_t m = other.used_blocks();
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < m - !!rest; ++i)
if (storage_[i] != other.storage_[i])
return false;
if (storage_[i] != other.storage_[i])
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
@ -352,18 +352,18 @@ namespace spot
bool operator<(const bitvect& other) const
{
if (size_ != other.size_)
return size_ < other.size_;
return size_ < other.size_;
if (size_ == 0)
return false;
return false;
size_t i;
size_t m = other.used_blocks();
const size_t bpb = 8 * sizeof(bitvect::block_t);
size_t rest = size() % bpb;
for (i = 0; i < m - !!rest; ++i)
if (storage_[i] > other.storage_[i])
return false;
if (storage_[i] > other.storage_[i])
return false;
if (!rest)
return true;
return true;
// The last block might not be fully used, compare only the
// relevant portion.
block_t mask = (1UL << rest) - 1;
@ -398,7 +398,7 @@ namespace spot
res->make_empty();
if (end == begin)
return res;
return res;
const size_t bpb = 8 * sizeof(bitvect::block_t);
@ -407,32 +407,32 @@ namespace spot
size_t indexe = (end - 1) / bpb;
if (indexb == indexe)
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, count);
}
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, count);
}
else
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, bpb - bitb);
count -= bpb - bitb;
while (count >= bpb)
{
++indexb;
res->push_back(storage_[indexb], bpb);
count -= bpb;
assert(indexb != indexe || count == 0);
}
if (count > 0)
{
++indexb;
assert(indexb == indexe);
assert(count == end % bpb);
res->push_back(storage_[indexb], count);
}
}
{
block_t data = storage_[indexb];
data >>= bitb;
res->push_back(data, bpb - bitb);
count -= bpb - bitb;
while (count >= bpb)
{
++indexb;
res->push_back(storage_[indexb], bpb);
count -= bpb;
assert(indexb != indexe || count == 0);
}
if (count > 0)
{
++indexb;
assert(indexb == indexe);
assert(count == end % bpb);
res->push_back(storage_[indexb], count);
}
}
return res;
}
@ -441,12 +441,12 @@ namespace spot
/// Print a bitvect.
friend SPOT_API std::ostream& operator<<(std::ostream&,
const bitvect&);
const bitvect&);
private:
friend SPOT_API bitvect_array*
::spot::make_bitvect_array(size_t bitcount,
size_t vectcount);
size_t vectcount);
size_t size_;
size_t block_count_;
@ -485,7 +485,7 @@ namespace spot
~bitvect_array()
{
for (size_t i = 0; i < size_; ++i)
at(i).~bitvect();
at(i).~bitvect();
}
/// The number of bitvect in the array.
@ -506,7 +506,7 @@ namespace spot
// FIXME: This could be changed into a large memset if the
// individual vectors where not allowed to be reallocated.
for (unsigned s = 0; s < size_; s++)
at(s).clear_all();
at(s).clear_all();
}
/// Return the bit-vector at \a index.
@ -518,12 +518,12 @@ namespace spot
friend SPOT_API bitvect_array*
::spot::make_bitvect_array(size_t bitcount,
size_t vectcount);
size_t vectcount);
/// Print a bitvect_array.
friend SPOT_API std::ostream& operator<<(std::ostream&,
const bitvect_array&);
const bitvect_array&);
private:
size_t size_;

View file

@ -93,9 +93,9 @@
// The extra parentheses in assert() is so that this
// pattern is not caught by the style checker.
#define SPOT_UNREACHABLE() do { \
assert(!("unreachable code reached")); \
SPOT_UNREACHABLE_BUILTIN(); \
#define SPOT_UNREACHABLE() do { \
assert(!("unreachable code reached")); \
SPOT_UNREACHABLE_BUILTIN(); \
} while (0)
#define SPOT_UNIMPLEMENTED() throw std::runtime_error("unimplemented");

View file

@ -33,14 +33,14 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '"':
os << "\"\"";
break;
default:
os << i;
break;
}
{
case '"':
os << "\"\"";
break;
default:
os << i;
break;
}
return os;
}
@ -49,28 +49,28 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '~':
os << "\\text{\\textasciitilde}";
break;
case '^':
os << "\\text{\\textasciicircum}";
break;
case '\\':
os << "\\text{\\textbackslash}";
break;
case '&':
case '%':
case '$':
case '#':
case '_':
case '{':
case '}':
os << '\\';
default:
os << i;
break;
}
{
case '~':
os << "\\text{\\textasciitilde}";
break;
case '^':
os << "\\text{\\textasciicircum}";
break;
case '\\':
os << "\\text{\\textbackslash}";
break;
case '&':
case '%':
case '$':
case '#':
case '_':
case '{':
case '}':
os << '\\';
default:
os << i;
break;
}
return os;
}
@ -79,23 +79,23 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '&':
os << "&amp;";
break;
case '"':
os << "&quot;";
break;
case '<':
os << "&lt;";
break;
case '>':
os << "&gt;";
break;
default:
os << i;
break;
}
{
case '&':
os << "&amp;";
break;
case '"':
os << "&quot;";
break;
case '<':
os << "&lt;";
break;
case '>':
os << "&gt;";
break;
default:
os << i;
break;
}
return os;
}
@ -104,20 +104,20 @@ namespace spot
{
for (auto i: str)
switch (i)
{
case '\\':
os << "\\\\";
break;
case '"':
os << "\\\"";
break;
case '\n':
os << "\\n";
break;
default:
os << i;
break;
}
{
case '\\':
os << "\\\\";
break;
case '"':
os << "\\\"";
break;
case '\n':
os << "\\n";
break;
default:
os << i;
break;
}
return os;
}
@ -135,26 +135,26 @@ namespace spot
// Single quotes are best, unless the string to quote contains one.
if (!strchr(str, '\''))
{
os << '\'' << str << '\'';
os << '\'' << str << '\'';
}
else
{
// In double quotes we have to escape $ ` " or \.
os << '"';
while (*str)
switch (*str)
{
case '$':
case '`':
case '"':
case '\\':
os << '\\';
// fall through
default:
os << *str++;
break;
}
os << '"';
// In double quotes we have to escape $ ` " or \.
os << '"';
while (*str)
switch (*str)
{
case '$':
case '`':
case '"':
case '\\':
os << '\\';
// fall through
default:
os << *str++;
break;
}
os << '"';
}
return os;
}

View file

@ -34,22 +34,22 @@ namespace spot
/// Create a pool allocating objects of \a size bytes.
fixed_size_pool(size_t size)
: freelist_(nullptr), free_start_(nullptr),
free_end_(nullptr), chunklist_(nullptr)
free_end_(nullptr), chunklist_(nullptr)
{
const size_t alignement = 2 * sizeof(size_t);
size_ = ((size >= sizeof(block_) ? size : sizeof(block_))
+ alignement - 1) & ~(alignement - 1);
+ alignement - 1) & ~(alignement - 1);
}
/// Free any memory allocated by this pool.
~fixed_size_pool()
{
while (chunklist_)
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
}
/// Allocate \a size bytes of memory.
@ -59,27 +59,27 @@ namespace spot
block_* f = freelist_;
// If we have free blocks available, return the first one.
if (f)
{
freelist_ = f->next;
return f;
}
{
freelist_ = f->next;
return f;
}
// Else, create a block out of the last chunk of allocated
// memory.
// If all the last chunk has been used, allocate one more.
if (free_start_ + size_ > free_end_)
{
const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
{
const size_t requested = (size_ > 128 ? size_ : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
free_start_ = c->data_ + size_;
free_end_ = c->data_ + requested;
}
free_start_ = c->data_ + size_;
free_end_ = c->data_ + requested;
}
void* res = free_start_;
free_start_ += size_;

View file

@ -28,12 +28,12 @@ namespace spot
{
for (const char* pos = fmt; *pos; ++pos)
if (*pos == '%')
{
char c = *++pos;
has[c] = true;
if (!c)
break;
}
{
char c = *++pos;
has[c] = true;
if (!c)
break;
}
}
void
@ -46,17 +46,17 @@ namespace spot
formater::format(const char* fmt)
{
for (const char* pos = fmt; *pos; ++pos)
if (*pos != '%')
{
*output_ << *pos;
}
else
{
char c = *++pos;
call_[c]->print(*output_, pos);
if (!c)
break;
}
if (*pos != '%')
{
*output_ << *pos;
}
else
{
char c = *++pos;
call_[c]->print(*output_, pos);
if (!c)
break;
}
return *output_;
}
}

View file

@ -49,7 +49,7 @@ namespace spot
size_t operator()(const T* p) const
{
return knuth32_hash(reinterpret_cast<const char*>(p)
- static_cast<const char*>(nullptr));
- static_cast<const char*>(nullptr));
}
};
@ -85,7 +85,7 @@ namespace spot
std::hash<U> uh;
return wang32_hash(static_cast<size_t>(th(p.first)) ^
static_cast<size_t>(uh(p.second)));
static_cast<size_t>(uh(p.second)));
}
};
}

View file

@ -43,270 +43,270 @@ namespace spot
{
public:
stream_compression_base(size_t size)
: size_(size)
: size_(size)
{
}
void run()
{
static const unsigned bits_width[7] = { 1, 3, 5, 7, 9, 14, 28 };
static const unsigned max_count[8] = { 30, 10, 6, 4, 3, 2, 1, 0 };
static const unsigned max_allowed[8] = { 1,
(1 << 3) - 1,
(1 << 5) - 1,
(1 << 7) - 1,
(1 << 9) - 1,
(1 << 14) - 1,
(1 << 28) - 1,
-1U };
// If we have only X data to compress and they fit with the
// current bit width, the following table tells us we should
// use bits_width[count_to_level[X - 1]] to limit the number
// of trailing zeros we encode. E.g. count_to_level[5 - 1]
// is 2, which mean that 5 values should be encoded with
// bits_width[2] == 5 bits.
static const unsigned count_to_level[30] =
{
6, // 1
5, // 2
4, // 3
3, // 4
2, // 5
2, // 6
1, // 7
1, // 8
1, // 9
1, // 10
0, 0, 0, 0, 0, // 11-15
0, 0, 0, 0, 0, // 16-20
0, 0, 0, 0, 0, // 21-25
0, 0, 0, 0, 0, // 26-30
};
static const unsigned bits_width[7] = { 1, 3, 5, 7, 9, 14, 28 };
static const unsigned max_count[8] = { 30, 10, 6, 4, 3, 2, 1, 0 };
static const unsigned max_allowed[8] = { 1,
(1 << 3) - 1,
(1 << 5) - 1,
(1 << 7) - 1,
(1 << 9) - 1,
(1 << 14) - 1,
(1 << 28) - 1,
-1U };
// If we have only X data to compress and they fit with the
// current bit width, the following table tells us we should
// use bits_width[count_to_level[X - 1]] to limit the number
// of trailing zeros we encode. E.g. count_to_level[5 - 1]
// is 2, which mean that 5 values should be encoded with
// bits_width[2] == 5 bits.
static const unsigned count_to_level[30] =
{
6, // 1
5, // 2
4, // 3
3, // 4
2, // 5
2, // 6
1, // 7
1, // 8
1, // 9
1, // 10
0, 0, 0, 0, 0, // 11-15
0, 0, 0, 0, 0, // 16-20
0, 0, 0, 0, 0, // 21-25
0, 0, 0, 0, 0, // 26-30
};
while (size_ > 0)
{
unsigned id = 0; // Current level in the above two tables.
unsigned curmax_allowed = max_allowed[id];
unsigned compressable = 0; // Number of integers ready to pack.
do
{
unsigned int val = self().data_at(compressable);
++compressable;
while (val > curmax_allowed)
{
curmax_allowed = max_allowed[++id];
while (size_ > 0)
{
unsigned id = 0; // Current level in the above two tables.
unsigned curmax_allowed = max_allowed[id];
unsigned compressable = 0; // Number of integers ready to pack.
do
{
unsigned int val = self().data_at(compressable);
++compressable;
while (val > curmax_allowed)
{
curmax_allowed = max_allowed[++id];
if (compressable > max_count[id])
goto fast_encode;
}
if (compressable >= max_count[id])
goto fast_encode;
}
while (SPOT_LIKELY(compressable < size_));
if (compressable > max_count[id])
goto fast_encode;
}
if (compressable >= max_count[id])
goto fast_encode;
}
while (SPOT_LIKELY(compressable < size_));
assert(compressable < max_count[id]);
assert(compressable < max_count[id]);
// Since we have less data than the current "id" allows,
// try to use more bits so we can encode faster.
// Since we have less data than the current "id" allows,
// try to use more bits so we can encode faster.
id = count_to_level[compressable - 1];
id = count_to_level[compressable - 1];
if (compressable == max_count[id])
goto fast_encode;
if (compressable == max_count[id])
goto fast_encode;
// Slow compression for situations where we have
// compressable < max_count[id]. We can only be in
// one of the 3 first "id" (1, 3, or 5 bits);
{
assert(id <= 2);
unsigned bits = bits_width[id];
unsigned finalshifts = (max_count[id] - compressable) * bits;
size_t pos = 0;
unsigned output = self().data_at(pos);
while (--compressable)
{
output <<= bits;
output += self().data_at(++pos);
}
output <<= finalshifts;
output += id << 30;
self().push_data(output);
return;
}
// Slow compression for situations where we have
// compressable < max_count[id]. We can only be in
// one of the 3 first "id" (1, 3, or 5 bits);
{
assert(id <= 2);
unsigned bits = bits_width[id];
unsigned finalshifts = (max_count[id] - compressable) * bits;
size_t pos = 0;
unsigned output = self().data_at(pos);
while (--compressable)
{
output <<= bits;
output += self().data_at(++pos);
}
output <<= finalshifts;
output += id << 30;
self().push_data(output);
return;
}
fast_encode:
switch (id)
{
case 0: // 30 1-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 1;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*2]
//
// This optimization is the reason why we use 'output +='
// instead of the more intuitive 'output |=' everywhere in
// this file.
fast_encode:
switch (id)
{
case 0: // 30 1-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 1;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*2]
//
// This optimization is the reason why we use 'output +='
// instead of the more intuitive 'output |=' everywhere in
// this file.
unsigned int output = 0x00 << 1; // 00
output += self().data_at(0);
output <<= 1;
output += self().data_at(1);
output <<= 1;
output += self().data_at(2);
output <<= 1;
output += self().data_at(3);
output <<= 1;
output += self().data_at(4);
output <<= 1;
output += self().data_at(5);
output <<= 1;
output += self().data_at(6);
output <<= 1;
output += self().data_at(7);
output <<= 1;
output += self().data_at(8);
output <<= 1;
output += self().data_at(9);
output <<= 1;
output += self().data_at(10);
output <<= 1;
output += self().data_at(11);
output <<= 1;
output += self().data_at(12);
output <<= 1;
output += self().data_at(13);
output <<= 1;
output += self().data_at(14);
output <<= 1;
output += self().data_at(15);
output <<= 1;
output += self().data_at(16);
output <<= 1;
output += self().data_at(17);
output <<= 1;
output += self().data_at(18);
output <<= 1;
output += self().data_at(19);
output <<= 1;
output += self().data_at(20);
output <<= 1;
output += self().data_at(21);
output <<= 1;
output += self().data_at(22);
output <<= 1;
output += self().data_at(23);
output <<= 1;
output += self().data_at(24);
output <<= 1;
output += self().data_at(25);
output <<= 1;
output += self().data_at(26);
output <<= 1;
output += self().data_at(27);
output <<= 1;
output += self().data_at(28);
output <<= 1;
output += self().data_at(29);
self().push_data(output);
}
break;
case 1: // 10 3-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 3;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*8]
unsigned int output = 0x00 << 1; // 00
output += self().data_at(0);
output <<= 1;
output += self().data_at(1);
output <<= 1;
output += self().data_at(2);
output <<= 1;
output += self().data_at(3);
output <<= 1;
output += self().data_at(4);
output <<= 1;
output += self().data_at(5);
output <<= 1;
output += self().data_at(6);
output <<= 1;
output += self().data_at(7);
output <<= 1;
output += self().data_at(8);
output <<= 1;
output += self().data_at(9);
output <<= 1;
output += self().data_at(10);
output <<= 1;
output += self().data_at(11);
output <<= 1;
output += self().data_at(12);
output <<= 1;
output += self().data_at(13);
output <<= 1;
output += self().data_at(14);
output <<= 1;
output += self().data_at(15);
output <<= 1;
output += self().data_at(16);
output <<= 1;
output += self().data_at(17);
output <<= 1;
output += self().data_at(18);
output <<= 1;
output += self().data_at(19);
output <<= 1;
output += self().data_at(20);
output <<= 1;
output += self().data_at(21);
output <<= 1;
output += self().data_at(22);
output <<= 1;
output += self().data_at(23);
output <<= 1;
output += self().data_at(24);
output <<= 1;
output += self().data_at(25);
output <<= 1;
output += self().data_at(26);
output <<= 1;
output += self().data_at(27);
output <<= 1;
output += self().data_at(28);
output <<= 1;
output += self().data_at(29);
self().push_data(output);
}
break;
case 1: // 10 3-bit values
{
// This code has been tuned so that the compiler can
// efficiently encode it as a series of MOV+LEA
// instructions, without shifts. For instance
//
// output <<= 3;
// output += self().data_at(4);
//
// translates to (assuming %eax points to the input,
// and %edx holds the output) the following:
//
// mov ecx, [eax+16]
// lea edx, [ecx+edx*8]
unsigned int output = 0x01 << 3; // 01
output += self().data_at(0);
output <<= 3;
output += self().data_at(1);
output <<= 3;
output += self().data_at(2);
output <<= 3;
output += self().data_at(3);
output <<= 3;
output += self().data_at(4);
output <<= 3;
output += self().data_at(5);
output <<= 3;
output += self().data_at(6);
output <<= 3;
output += self().data_at(7);
output <<= 3;
output += self().data_at(8);
output <<= 3;
output += self().data_at(9);
self().push_data(output);
}
break;
case 2: // 6 5-bit values
{
unsigned int output = 0x02U << 30; // 10
output += self().data_at(0) << 25;
output += self().data_at(1) << 20;
output += self().data_at(2) << 15;
output += self().data_at(3) << 10;
output += self().data_at(4) << 5;
output += self().data_at(5);
self().push_data(output);
}
break;
case 3: // 4 7-bit values
{
unsigned int output = 0x0CU << 28; // 1100
output += self().data_at(0) << 21;
output += self().data_at(1) << 14;
output += self().data_at(2) << 7;
output += self().data_at(3);
self().push_data(output);
}
break;
case 4: // 3 9-bit values
{
unsigned int output = 0x0DU << 28; // 1101x (1 bit lost)
output += self().data_at(0) << 18;
output += self().data_at(1) << 9;
output += self().data_at(2);
self().push_data(output);
}
break;
case 5: // 2 14-bit values
{
unsigned int output = 0x0EU << 28; // 1110
output += self().data_at(0) << 14;
output += self().data_at(1);
self().push_data(output);
}
break;
case 6: // one 28-bit value
{
unsigned int output = 0x0FU << 28; // 1111
output += self().data_at(0);
self().push_data(output);
}
break;
}
self().forward(max_count[id]);
size_ -= max_count[id];
}
unsigned int output = 0x01 << 3; // 01
output += self().data_at(0);
output <<= 3;
output += self().data_at(1);
output <<= 3;
output += self().data_at(2);
output <<= 3;
output += self().data_at(3);
output <<= 3;
output += self().data_at(4);
output <<= 3;
output += self().data_at(5);
output <<= 3;
output += self().data_at(6);
output <<= 3;
output += self().data_at(7);
output <<= 3;
output += self().data_at(8);
output <<= 3;
output += self().data_at(9);
self().push_data(output);
}
break;
case 2: // 6 5-bit values
{
unsigned int output = 0x02U << 30; // 10
output += self().data_at(0) << 25;
output += self().data_at(1) << 20;
output += self().data_at(2) << 15;
output += self().data_at(3) << 10;
output += self().data_at(4) << 5;
output += self().data_at(5);
self().push_data(output);
}
break;
case 3: // 4 7-bit values
{
unsigned int output = 0x0CU << 28; // 1100
output += self().data_at(0) << 21;
output += self().data_at(1) << 14;
output += self().data_at(2) << 7;
output += self().data_at(3);
self().push_data(output);
}
break;
case 4: // 3 9-bit values
{
unsigned int output = 0x0DU << 28; // 1101x (1 bit lost)
output += self().data_at(0) << 18;
output += self().data_at(1) << 9;
output += self().data_at(2);
self().push_data(output);
}
break;
case 5: // 2 14-bit values
{
unsigned int output = 0x0EU << 28; // 1110
output += self().data_at(0) << 14;
output += self().data_at(1);
self().push_data(output);
}
break;
case 6: // one 28-bit value
{
unsigned int output = 0x0FU << 28; // 1111
output += self().data_at(0);
self().push_data(output);
}
break;
}
self().forward(max_count[id]);
size_ -= max_count[id];
}
}
protected:
@ -315,12 +315,12 @@ namespace spot
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
};
@ -331,29 +331,29 @@ namespace spot
{
public:
int_array_array_compression(const int* array, size_t n,
int* dest, size_t& dest_n)
: stream_compression_base<int_array_array_compression>(n),
array_(array), result_size_(dest_n),
result_(dest), result_end_(dest + dest_n)
int* dest, size_t& dest_n)
: stream_compression_base<int_array_array_compression>(n),
array_(array), result_size_(dest_n),
result_(dest), result_end_(dest + dest_n)
{
result_size_ = 0; // this resets dest_n.
result_size_ = 0; // this resets dest_n.
}
void push_data(unsigned int i)
{
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
}
unsigned int data_at(size_t offset)
{
return static_cast<unsigned int>(array_[offset]);
return static_cast<unsigned int>(array_[offset]);
}
void forward(size_t offset)
{
array_ += offset;
array_ += offset;
}
protected:
@ -368,7 +368,7 @@ namespace spot
void
int_array_array_compress2(const int* array, size_t n,
int* dest, size_t& dest_size)
int* dest, size_t& dest_size)
{
int_array_array_compression c(array, n, dest, dest_size);
c.run();
@ -386,113 +386,113 @@ namespace spot
void run()
{
while (SPOT_LIKELY(self().have_comp_data()))
{
unsigned val = self().next_comp_data();
while (SPOT_LIKELY(self().have_comp_data()))
{
unsigned val = self().next_comp_data();
unsigned id = val >> 28;
switch (id)
{
case 0x00: // 00xx - 30 1-bit values.
case 0x01:
case 0x02:
case 0x03:
self().write_data_at(0, !!(val & (1 << 29)));
self().write_data_at(1, !!(val & (1 << 28)));
self().write_data_at(2, !!(val & (1 << 27)));
self().write_data_at(3, !!(val & (1 << 26)));
self().write_data_at(4, !!(val & (1 << 25)));
self().write_data_at(5, !!(val & (1 << 24)));
self().write_data_at(6, !!(val & (1 << 23)));
self().write_data_at(7, !!(val & (1 << 22)));
self().write_data_at(8, !!(val & (1 << 21)));
self().write_data_at(9, !!(val & (1 << 20)));
self().write_data_at(10, !!(val & (1 << 19)));
self().write_data_at(11, !!(val & (1 << 18)));
self().write_data_at(12, !!(val & (1 << 17)));
self().write_data_at(13, !!(val & (1 << 16)));
self().write_data_at(14, !!(val & (1 << 15)));
self().write_data_at(15, !!(val & (1 << 14)));
self().write_data_at(16, !!(val & (1 << 13)));
self().write_data_at(17, !!(val & (1 << 12)));
self().write_data_at(18, !!(val & (1 << 11)));
self().write_data_at(19, !!(val & (1 << 10)));
self().write_data_at(20, !!(val & (1 << 9)));
self().write_data_at(21, !!(val & (1 << 8)));
self().write_data_at(22, !!(val & (1 << 7)));
self().write_data_at(23, !!(val & (1 << 6)));
self().write_data_at(24, !!(val & (1 << 5)));
self().write_data_at(25, !!(val & (1 << 4)));
self().write_data_at(26, !!(val & (1 << 3)));
self().write_data_at(27, !!(val & (1 << 2)));
self().write_data_at(28, !!(val & (1 << 1)));
self().write_data_at(29, !!(val & (1 << 0)));
self().forward(30);
break;
case 0x04: // 01xx - 10 3-bit values.
case 0x05:
case 0x06:
case 0x07:
self().write_data_at(0, (val >> 27) & 0x07);
self().write_data_at(1, (val >> 24) & 0x07);
self().write_data_at(2, (val >> 21) & 0x07);
self().write_data_at(3, (val >> 18) & 0x07);
self().write_data_at(4, (val >> 15) & 0x07);
self().write_data_at(5, (val >> 12) & 0x07);
self().write_data_at(6, (val >> 9) & 0x07);
self().write_data_at(7, (val >> 6) & 0x07);
self().write_data_at(8, (val >> 3) & 0x07);
self().write_data_at(9, (val >> 0) & 0x07);
self().forward(10);
break;
case 0x08: // 10xx - 6 5-bit values.
case 0x09:
case 0x0A:
case 0x0B:
self().write_data_at(0, (val >> 25) & 0x1F);
self().write_data_at(1, (val >> 20) & 0x1F);
self().write_data_at(2, (val >> 15) & 0x1F);
self().write_data_at(3, (val >> 10) & 0x1F);
self().write_data_at(4, (val >> 5) & 0x1F);
self().write_data_at(5, (val >> 0) & 0x1F);
self().forward(6);
break;
case 0x0C: // 1100 - 4 7-bit values
self().write_data_at(0, (val >> 21) & 0x7F);
self().write_data_at(1, (val >> 14) & 0x7F);
self().write_data_at(2, (val >> 7) & 0x7F);
self().write_data_at(3, (val >> 0) & 0x7F);
self().forward(4);
break;
case 0x0D: // 1101x - 3 9-bit values.
self().write_data_at(0, (val >> 18) & 0x1FF);
self().write_data_at(1, (val >> 9) & 0x1FF);
self().write_data_at(2, (val >> 0) & 0x1FF);
self().forward(3);
break;
case 0x0E: // 110x - 2 14-bit values.
self().write_data_at(0, (val >> 14) & 0x3FFF);
self().write_data_at(1, (val >> 0) & 0x3FFF);
self().forward(2);
break;
case 0x0F: // 1100 - 1 28-bit value.
self().write_data_at(0, val & 0xFFFFFFF);
self().forward(1);
break;
}
}
unsigned id = val >> 28;
switch (id)
{
case 0x00: // 00xx - 30 1-bit values.
case 0x01:
case 0x02:
case 0x03:
self().write_data_at(0, !!(val & (1 << 29)));
self().write_data_at(1, !!(val & (1 << 28)));
self().write_data_at(2, !!(val & (1 << 27)));
self().write_data_at(3, !!(val & (1 << 26)));
self().write_data_at(4, !!(val & (1 << 25)));
self().write_data_at(5, !!(val & (1 << 24)));
self().write_data_at(6, !!(val & (1 << 23)));
self().write_data_at(7, !!(val & (1 << 22)));
self().write_data_at(8, !!(val & (1 << 21)));
self().write_data_at(9, !!(val & (1 << 20)));
self().write_data_at(10, !!(val & (1 << 19)));
self().write_data_at(11, !!(val & (1 << 18)));
self().write_data_at(12, !!(val & (1 << 17)));
self().write_data_at(13, !!(val & (1 << 16)));
self().write_data_at(14, !!(val & (1 << 15)));
self().write_data_at(15, !!(val & (1 << 14)));
self().write_data_at(16, !!(val & (1 << 13)));
self().write_data_at(17, !!(val & (1 << 12)));
self().write_data_at(18, !!(val & (1 << 11)));
self().write_data_at(19, !!(val & (1 << 10)));
self().write_data_at(20, !!(val & (1 << 9)));
self().write_data_at(21, !!(val & (1 << 8)));
self().write_data_at(22, !!(val & (1 << 7)));
self().write_data_at(23, !!(val & (1 << 6)));
self().write_data_at(24, !!(val & (1 << 5)));
self().write_data_at(25, !!(val & (1 << 4)));
self().write_data_at(26, !!(val & (1 << 3)));
self().write_data_at(27, !!(val & (1 << 2)));
self().write_data_at(28, !!(val & (1 << 1)));
self().write_data_at(29, !!(val & (1 << 0)));
self().forward(30);
break;
case 0x04: // 01xx - 10 3-bit values.
case 0x05:
case 0x06:
case 0x07:
self().write_data_at(0, (val >> 27) & 0x07);
self().write_data_at(1, (val >> 24) & 0x07);
self().write_data_at(2, (val >> 21) & 0x07);
self().write_data_at(3, (val >> 18) & 0x07);
self().write_data_at(4, (val >> 15) & 0x07);
self().write_data_at(5, (val >> 12) & 0x07);
self().write_data_at(6, (val >> 9) & 0x07);
self().write_data_at(7, (val >> 6) & 0x07);
self().write_data_at(8, (val >> 3) & 0x07);
self().write_data_at(9, (val >> 0) & 0x07);
self().forward(10);
break;
case 0x08: // 10xx - 6 5-bit values.
case 0x09:
case 0x0A:
case 0x0B:
self().write_data_at(0, (val >> 25) & 0x1F);
self().write_data_at(1, (val >> 20) & 0x1F);
self().write_data_at(2, (val >> 15) & 0x1F);
self().write_data_at(3, (val >> 10) & 0x1F);
self().write_data_at(4, (val >> 5) & 0x1F);
self().write_data_at(5, (val >> 0) & 0x1F);
self().forward(6);
break;
case 0x0C: // 1100 - 4 7-bit values
self().write_data_at(0, (val >> 21) & 0x7F);
self().write_data_at(1, (val >> 14) & 0x7F);
self().write_data_at(2, (val >> 7) & 0x7F);
self().write_data_at(3, (val >> 0) & 0x7F);
self().forward(4);
break;
case 0x0D: // 1101x - 3 9-bit values.
self().write_data_at(0, (val >> 18) & 0x1FF);
self().write_data_at(1, (val >> 9) & 0x1FF);
self().write_data_at(2, (val >> 0) & 0x1FF);
self().forward(3);
break;
case 0x0E: // 110x - 2 14-bit values.
self().write_data_at(0, (val >> 14) & 0x3FFF);
self().write_data_at(1, (val >> 0) & 0x3FFF);
self().forward(2);
break;
case 0x0F: // 1100 - 1 28-bit value.
self().write_data_at(0, val & 0xFFFFFFF);
self().forward(1);
break;
}
}
}
protected:
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
};
@ -502,30 +502,30 @@ namespace spot
{
public:
int_array_array_decompression(const int* array,
size_t array_size,
int* res)
: array_(array), n_(array_size), pos_(0), result_(res)
size_t array_size,
int* res)
: array_(array), n_(array_size), pos_(0), result_(res)
{
}
void write_data_at(size_t pos, unsigned int i)
{
result_[pos] = i;
result_[pos] = i;
}
void forward(size_t i)
{
result_ += i;
result_ += i;
}
bool have_comp_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_comp_data()
{
return array_[pos_++];
return array_[pos_++];
}
protected:
@ -540,7 +540,7 @@ namespace spot
void
int_array_array_decompress2(const int* array, size_t array_size, int* res,
size_t)
size_t)
{
int_array_array_decompression c(array, array_size, res);
c.run();

View file

@ -36,7 +36,7 @@ namespace spot
/// filled in \a dest
SPOT_API void
int_array_array_compress2(const int* array, size_t n,
int* dest, size_t& dest_size);
int* dest, size_t& dest_size);
/// \brief Uncompress an int array of size \a array_size into a int
/// array of size \a size.
@ -44,7 +44,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_array_array_decompress2(const int* array, size_t array_size,
int* res, size_t size);
int* res, size_t size);
/// @}
}

View file

@ -55,129 +55,129 @@ namespace spot
public:
stream_compression_base()
: cur_(0), bits_left_(max_bits)
: cur_(0), bits_left_(max_bits)
{
}
void emit(unsigned int val)
{
if (val == 0)
{
self().push_bits(0x0, 2, 0x3);
}
else if (val == 1)
{
self().push_bits(0x2, 3, 0x7);
}
else if (val >= 2 && val <= 5)
{
self().push_bits(0x3, 3, 0x7);
self().push_bits(val - 2, 2, 0x3);
}
else if (val >= 6 && val <= 22)
{
self().push_bits(0x4, 3, 0x7);
self().push_bits(val - 6, 4, 0xf);
}
else
{
assert(val > 22);
self().push_bits(0x7, 3, 0x7);
self().push_bits(val, 32, -1U);
}
if (val == 0)
{
self().push_bits(0x0, 2, 0x3);
}
else if (val == 1)
{
self().push_bits(0x2, 3, 0x7);
}
else if (val >= 2 && val <= 5)
{
self().push_bits(0x3, 3, 0x7);
self().push_bits(val - 2, 2, 0x3);
}
else if (val >= 6 && val <= 22)
{
self().push_bits(0x4, 3, 0x7);
self().push_bits(val - 6, 4, 0xf);
}
else
{
assert(val > 22);
self().push_bits(0x7, 3, 0x7);
self().push_bits(val, 32, -1U);
}
}
void run()
{
unsigned int last_val = 0;
unsigned int last_val = 0;
while (SPOT_LIKELY(self().have_data()))
{
unsigned int val = self().next_data();
// Repeated value? Try to find more.
if (val == last_val)
{
unsigned int count = 1;
while (count < 40 && self().skip_if(val))
++count;
while (SPOT_LIKELY(self().have_data()))
{
unsigned int val = self().next_data();
// Repeated value? Try to find more.
if (val == last_val)
{
unsigned int count = 1;
while (count < 40 && self().skip_if(val))
++count;
if ((val == 0 && count < 3) || (val == 1 && count == 1))
{
// it is more efficient to emit 0 once or twice directly
// (e.g., 00 00 vs. 011 11)
// for value 1, repetition is worthwhile for count > 1
// (e.g., 010 010 vs. 011 00)
while (count--)
emit(val);
}
else if (count < 9)
{
self().push_bits(0x5, 3, 0x7);
self().push_bits(count - 1, 3, 0x7);
}
else
{
self().push_bits(0x6, 3, 0x7);
self().push_bits(count - 9, 5, 0x1f);
}
}
else
{
emit(val);
last_val = val;
}
}
flush();
if ((val == 0 && count < 3) || (val == 1 && count == 1))
{
// it is more efficient to emit 0 once or twice directly
// (e.g., 00 00 vs. 011 11)
// for value 1, repetition is worthwhile for count > 1
// (e.g., 010 010 vs. 011 00)
while (count--)
emit(val);
}
else if (count < 9)
{
self().push_bits(0x5, 3, 0x7);
self().push_bits(count - 1, 3, 0x7);
}
else
{
self().push_bits(0x6, 3, 0x7);
self().push_bits(count - 9, 5, 0x1f);
}
}
else
{
emit(val);
last_val = val;
}
}
flush();
}
// This version assumes there is at least n bits free in cur_.
void
push_bits_unchecked(unsigned int bits, unsigned int n, unsigned int mask)
{
cur_ <<= n;
cur_ |= (bits & mask);
if (SPOT_LIKELY(bits_left_ -= n))
return;
cur_ <<= n;
cur_ |= (bits & mask);
if (SPOT_LIKELY(bits_left_ -= n))
return;
self().push_data(cur_);
cur_ = 0;
bits_left_ = max_bits;
self().push_data(cur_);
cur_ = 0;
bits_left_ = max_bits;
}
void
push_bits(unsigned int bits, unsigned int n, unsigned int mask)
{
if (SPOT_LIKELY(n <= bits_left_))
{
push_bits_unchecked(bits, n, mask);
return;
}
if (SPOT_LIKELY(n <= bits_left_))
{
push_bits_unchecked(bits, n, mask);
return;
}
// bits_left_ < n
// bits_left_ < n
unsigned int right_bit_count = n - bits_left_;
unsigned int left = bits >> right_bit_count;
push_bits_unchecked(left, bits_left_, (1 << bits_left_) - 1);
push_bits_unchecked(bits, right_bit_count, (1 << right_bit_count) - 1);
unsigned int right_bit_count = n - bits_left_;
unsigned int left = bits >> right_bit_count;
push_bits_unchecked(left, bits_left_, (1 << bits_left_) - 1);
push_bits_unchecked(bits, right_bit_count, (1 << right_bit_count) - 1);
}
void flush()
{
if (bits_left_ == max_bits)
return;
cur_ <<= bits_left_;
self().push_data(cur_);
if (bits_left_ == max_bits)
return;
cur_ <<= bits_left_;
self().push_data(cur_);
}
protected:
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
unsigned int cur_;
@ -189,41 +189,41 @@ namespace spot
{
public:
int_array_vector_compression(const int* array, size_t n)
: array_(array), n_(n), pos_(0), result_(new std::vector<unsigned int>)
: array_(array), n_(n), pos_(0), result_(new std::vector<unsigned int>)
{
}
void push_data(unsigned int i)
{
result_->push_back(i);
result_->push_back(i);
}
const std::vector<unsigned int>*
result() const
{
return result_;
return result_;
}
bool have_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_data()
{
return static_cast<unsigned int>(array_[pos_++]);
return static_cast<unsigned int>(array_[pos_++]);
}
bool skip_if(unsigned int val)
{
if (SPOT_UNLIKELY(!have_data()))
return false;
if (SPOT_UNLIKELY(!have_data()))
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
++pos_;
return true;
++pos_;
return true;
}
protected:
@ -238,36 +238,36 @@ namespace spot
{
public:
int_vector_vector_compression(const std::vector<int>& input,
std::vector<unsigned int>& output)
: input_(input), pos_(input.begin()), end_(input.end()), output_(output)
std::vector<unsigned int>& output)
: input_(input), pos_(input.begin()), end_(input.end()), output_(output)
{
}
void push_data(unsigned int i)
{
output_.push_back(i);
output_.push_back(i);
}
bool have_data() const
{
return pos_ < end_;
return pos_ < end_;
}
unsigned int next_data()
{
return static_cast<unsigned int>(*pos_++);
return static_cast<unsigned int>(*pos_++);
}
bool skip_if(unsigned int val)
{
if (SPOT_UNLIKELY(!have_data()))
return false;
if (SPOT_UNLIKELY(!have_data()))
return false;
if (static_cast<unsigned int>(*pos_) != val)
return false;
if (static_cast<unsigned int>(*pos_) != val)
return false;
++pos_;
return true;
++pos_;
return true;
}
protected:
@ -282,40 +282,40 @@ namespace spot
{
public:
int_array_array_compression(const int* array, size_t n,
int* dest, size_t& dest_n)
: array_(array), n_(n), pos_(0),
result_size_(dest_n), result_(dest), result_end_(dest + dest_n)
int* dest, size_t& dest_n)
: array_(array), n_(n), pos_(0),
result_size_(dest_n), result_(dest), result_end_(dest + dest_n)
{
result_size_ = 0; // this resets dest_n.
result_size_ = 0; // this resets dest_n.
}
void push_data(unsigned int i)
{
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
assert(result_ < result_end_);
++result_size_;
*result_++ = static_cast<int>(i);
}
bool have_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_data()
{
return static_cast<unsigned int>(array_[pos_++]);
return static_cast<unsigned int>(array_[pos_++]);
}
bool skip_if(unsigned int val)
{
if (SPOT_UNLIKELY(!have_data()))
return false;
if (SPOT_UNLIKELY(!have_data()))
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
if (static_cast<unsigned int>(array_[pos_]) != val)
return false;
++pos_;
return true;
++pos_;
return true;
}
protected:
@ -330,7 +330,7 @@ namespace spot
void
int_vector_vector_compress(const std::vector<int>& input,
std::vector<unsigned>& output)
std::vector<unsigned>& output)
{
int_vector_vector_compression c(input, output);
c.run();
@ -346,7 +346,7 @@ namespace spot
void
int_array_array_compress(const int* array, size_t n,
int* dest, size_t& dest_size)
int* dest, size_t& dest_size)
{
int_array_array_compression c(array, n, dest, dest_size);
c.run();
@ -365,154 +365,154 @@ namespace spot
public:
void refill()
{
if (SPOT_UNLIKELY(look_bits_ == 0))
{
look_bits_ = max_bits;
look_ = buffer_;
if (SPOT_UNLIKELY(look_bits_ == 0))
{
look_bits_ = max_bits;
look_ = buffer_;
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
if (SPOT_LIKELY(buffer_bits_ != max_bits))
{
unsigned int fill_size = max_bits - buffer_bits_;
look_ <<= fill_size;
look_ |= buffer_ >> buffer_bits_;
}
}
else
{
unsigned int fill_size = max_bits - look_bits_;
if (fill_size > buffer_bits_)
fill_size = buffer_bits_;
if (SPOT_LIKELY(buffer_bits_ != max_bits))
{
unsigned int fill_size = max_bits - buffer_bits_;
look_ <<= fill_size;
look_ |= buffer_ >> buffer_bits_;
}
}
else
{
unsigned int fill_size = max_bits - look_bits_;
if (fill_size > buffer_bits_)
fill_size = buffer_bits_;
look_ <<= fill_size;
buffer_bits_ -= fill_size;
look_ |= (buffer_ >> buffer_bits_) & ((1 << fill_size) - 1);
look_bits_ += fill_size;
look_ <<= fill_size;
buffer_bits_ -= fill_size;
look_ |= (buffer_ >> buffer_bits_) & ((1 << fill_size) - 1);
look_bits_ += fill_size;
if (buffer_bits_ == 0)
{
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
if (buffer_bits_ == 0)
{
if (SPOT_LIKELY(self().have_comp_data()))
buffer_ = self().next_comp_data();
unsigned int left = max_bits - look_bits_;
if (left != 0)
{
look_ <<= left;
look_ |= buffer_ >> look_bits_;
buffer_bits_ = look_bits_;
look_bits_ = max_bits;
}
else
{
buffer_bits_ = max_bits;
}
}
}
unsigned int left = max_bits - look_bits_;
if (left != 0)
{
look_ <<= left;
look_ |= buffer_ >> look_bits_;
buffer_bits_ = look_bits_;
look_bits_ = max_bits;
}
else
{
buffer_bits_ = max_bits;
}
}
}
}
unsigned int look_n_bits(unsigned int n)
{
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
assert(n <= look_bits_);
return (look_ >> (look_bits_ - n)) & ((1 << n) - 1);
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
assert(n <= look_bits_);
return (look_ >> (look_bits_ - n)) & ((1 << n) - 1);
}
void skip_n_bits(unsigned int n)
{
assert (n <= look_bits_);
look_bits_ -= n;
assert (n <= look_bits_);
look_bits_ -= n;
}
unsigned int get_n_bits(unsigned int n)
{
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
look_bits_ -= n;
return (look_ >> look_bits_) & ((1 << n) - 1);
if (SPOT_UNLIKELY(look_bits_ < n))
refill();
look_bits_ -= n;
return (look_ >> look_bits_) & ((1 << n) - 1);
}
unsigned int get_32_bits()
{
// std::cerr << "get_32" << std::endl;
if (SPOT_LIKELY(look_bits_ < 32))
refill();
unsigned int val = look_;
look_bits_ = 0;
refill();
return val;
// std::cerr << "get_32" << std::endl;
if (SPOT_LIKELY(look_bits_ < 32))
refill();
unsigned int val = look_;
look_bits_ = 0;
refill();
return val;
}
void run()
{
if (SPOT_UNLIKELY(!self().have_comp_data()))
return;
if (SPOT_UNLIKELY(!self().have_comp_data()))
return;
look_ = self().next_comp_data();
look_bits_ = max_bits;
if (SPOT_LIKELY(self().have_comp_data()))
{
buffer_ = self().next_comp_data();
buffer_bits_ = max_bits;
}
else
{
buffer_ = 0;
buffer_bits_ = 0;
}
look_ = self().next_comp_data();
look_bits_ = max_bits;
if (SPOT_LIKELY(self().have_comp_data()))
{
buffer_ = self().next_comp_data();
buffer_bits_ = max_bits;
}
else
{
buffer_ = 0;
buffer_bits_ = 0;
}
while (SPOT_LIKELY(!self().complete()))
{
unsigned int token = look_n_bits(3);
switch (token)
{
case 0x0: // 00[0]
case 0x1: // 00[1]
skip_n_bits(2);
self().push_data(0);
break;
case 0x2: // 010
skip_n_bits(3);
self().push_data(1);
break;
case 0x3: // 011
skip_n_bits(3);
self().push_data(2 + get_n_bits(2));
break;
case 0x4: // 100
skip_n_bits(3);
self().push_data(6 + get_n_bits(4));
break;
case 0x5: // 101
skip_n_bits(3);
self().repeat(1 + get_n_bits(3));
break;
case 0x6: // 110
skip_n_bits(3);
self().repeat(9 + get_n_bits(5));
break;
case 0x7: // 111
skip_n_bits(3);
self().push_data(get_32_bits());
break;
default:
SPOT_UNREACHABLE();
}
}
while (SPOT_LIKELY(!self().complete()))
{
unsigned int token = look_n_bits(3);
switch (token)
{
case 0x0: // 00[0]
case 0x1: // 00[1]
skip_n_bits(2);
self().push_data(0);
break;
case 0x2: // 010
skip_n_bits(3);
self().push_data(1);
break;
case 0x3: // 011
skip_n_bits(3);
self().push_data(2 + get_n_bits(2));
break;
case 0x4: // 100
skip_n_bits(3);
self().push_data(6 + get_n_bits(4));
break;
case 0x5: // 101
skip_n_bits(3);
self().repeat(1 + get_n_bits(3));
break;
case 0x6: // 110
skip_n_bits(3);
self().repeat(9 + get_n_bits(5));
break;
case 0x7: // 111
skip_n_bits(3);
self().push_data(get_32_bits());
break;
default:
SPOT_UNREACHABLE();
}
}
}
protected:
Self& self()
{
return static_cast<Self&>(*this);
return static_cast<Self&>(*this);
}
const Self& self() const
{
return static_cast<const Self&>(*this);
return static_cast<const Self&>(*this);
}
unsigned int look_;
@ -526,41 +526,41 @@ namespace spot
{
public:
int_vector_vector_decompression(const std::vector<unsigned int>& array,
std::vector<int>& res, size_t size)
: prev_(0), array_(array),
pos_(array.begin()), end_(array.end()),
result_(res), size_(size)
std::vector<int>& res, size_t size)
: prev_(0), array_(array),
pos_(array.begin()), end_(array.end()),
result_(res), size_(size)
{
result_.reserve(size);
result_.reserve(size);
}
bool complete() const
{
return size_ == 0;
return size_ == 0;
}
void push_data(int i)
{
prev_ = i;
result_.push_back(i);
--size_;
prev_ = i;
result_.push_back(i);
--size_;
}
void repeat(unsigned int i)
{
size_ -= i;
while (i--)
result_.push_back(prev_);
size_ -= i;
while (i--)
result_.push_back(prev_);
}
bool have_comp_data() const
{
return pos_ != end_;
return pos_ != end_;
}
unsigned int next_comp_data()
{
return *pos_++;
return *pos_++;
}
protected:
@ -577,40 +577,40 @@ namespace spot
{
public:
int_vector_array_decompression(const std::vector<unsigned int>* array,
int* res,
size_t size)
: prev_(0), array_(array), n_(array->size()), pos_(0), result_(res),
size_(size)
int* res,
size_t size)
: prev_(0), array_(array), n_(array->size()), pos_(0), result_(res),
size_(size)
{
}
bool complete() const
{
return size_ == 0;
return size_ == 0;
}
void push_data(int i)
{
prev_ = i;
*result_++ = i;
--size_;
prev_ = i;
*result_++ = i;
--size_;
}
void repeat(unsigned int i)
{
size_ -= i;
while (i--)
*result_++ = prev_;
size_ -= i;
while (i--)
*result_++ = prev_;
}
bool have_comp_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_comp_data()
{
return (*array_)[pos_++];
return (*array_)[pos_++];
}
protected:
@ -627,41 +627,41 @@ namespace spot
{
public:
int_array_array_decompression(const int* array,
size_t array_size,
int* res,
size_t size)
: prev_(0), array_(array), n_(array_size), pos_(0), result_(res),
size_(size)
size_t array_size,
int* res,
size_t size)
: prev_(0), array_(array), n_(array_size), pos_(0), result_(res),
size_(size)
{
}
bool complete() const
{
return size_ == 0;
return size_ == 0;
}
void push_data(int i)
{
prev_ = i;
*result_++ = i;
--size_;
prev_ = i;
*result_++ = i;
--size_;
}
void repeat(unsigned int i)
{
size_ -= i;
while (i--)
*result_++ = prev_;
size_ -= i;
while (i--)
*result_++ = prev_;
}
bool have_comp_data() const
{
return pos_ < n_;
return pos_ < n_;
}
unsigned int next_comp_data()
{
return array_[pos_++];
return array_[pos_++];
}
protected:
@ -677,7 +677,7 @@ namespace spot
void
int_vector_vector_decompress(const std::vector<unsigned int>& input,
std::vector<int>& output, size_t size)
std::vector<int>& output, size_t size)
{
int_vector_vector_decompression c(input, output, size);
c.run();
@ -685,7 +685,7 @@ namespace spot
void
int_vector_array_decompress(const std::vector<unsigned int>* array, int* res,
size_t size)
size_t size)
{
int_vector_array_decompression c(array, res, size);
c.run();
@ -693,7 +693,7 @@ namespace spot
void
int_array_array_decompress(const int* array, size_t array_size,
int* res, size_t size)
int* res, size_t size)
{
int_array_array_decompression c(array, array_size, res, size);
c.run();

View file

@ -31,7 +31,7 @@ namespace spot
/// Compress an int vector into a vector of unsigned int.
SPOT_API void
int_vector_vector_compress(const std::vector<int>& input,
std::vector<unsigned int>& output);
std::vector<unsigned int>& output);
/// \brief Uncompress a vector of unsigned int into a vector of
/// size \a size.
@ -39,7 +39,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_vector_vector_decompress(const std::vector<unsigned int>& array,
std::vector<int>& output, size_t size);
std::vector<int>& output, size_t size);
/// Compress an int array if size \a n into a vector of unsigned int.
SPOT_API const std::vector<unsigned int>*
@ -51,7 +51,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_vector_array_decompress(const std::vector<unsigned int>* array,
int* res, size_t size);
int* res, size_t size);
/// \brief Compress an int array of size \a n into a int array.
///
@ -61,7 +61,7 @@ namespace spot
/// filled in \a dest
SPOT_API void
int_array_array_compress(const int* array, size_t n,
int* dest, size_t& dest_size);
int* dest, size_t& dest_size);
/// \brief Uncompress an int array of size \a array_size into a int
/// array of size \a size.
@ -69,7 +69,7 @@ namespace spot
/// \a size must be the exact expected size of uncompressed array.
SPOT_API void
int_array_array_decompress(const int* array, size_t array_size,
int* res, size_t size);
int* res, size_t size);
/// @}
}

View file

@ -157,8 +157,8 @@ namespace spot
position last = loc.end - 1;
ostr << loc.begin;
if (last.filename
&& (!loc.begin.filename
|| *loc.begin.filename != *last.filename))
&& (!loc.begin.filename
|| *loc.begin.filename != *last.filename))
ostr << '-' << last;
else if (loc.begin.line != last.line)
ostr << '-' << last.line << '.' << last.column;

View file

@ -51,12 +51,12 @@ namespace spot
{
if (input_min == input_max)
{
cube_.push(bdd_satprefix(input_min));
input_max = input_min;
cube_.push(bdd_satprefix(input_min));
input_max = input_min;
}
else
{
cube_.push(bddtrue);
cube_.push(bddtrue);
}
bdd common = input_min & input_max;
todo_.emplace(input_min, input_max, bdd_support(common));
@ -67,110 +67,110 @@ namespace spot
{
while (!todo_.empty())
{
local_vars& l = todo_.top();
switch (l.step)
{
case local_vars::FirstStep:
next_var:
{
if (l.f_min == bddfalse)
{
ret_ = bddfalse;
todo_.pop();
continue;
}
if (l.vars == bddtrue || l.f_max == bddtrue)
{
ret_ = l.f_max;
todo_.pop();
return cube_.top() & ret_;
}
assert(l.vars != bddfalse);
local_vars& l = todo_.top();
switch (l.step)
{
case local_vars::FirstStep:
next_var:
{
if (l.f_min == bddfalse)
{
ret_ = bddfalse;
todo_.pop();
continue;
}
if (l.vars == bddtrue || l.f_max == bddtrue)
{
ret_ = l.f_max;
todo_.pop();
return cube_.top() & ret_;
}
assert(l.vars != bddfalse);
// Pick the first variable in VARS that is used by F_MIN
// or F_MAX. We know that VARS, F_MIN or F_MAX are not
// constants (bddtrue or bddfalse) because one of the
// two above `if' would have matched; so it's ok to call
// bdd_var().
int v = bdd_var(l.vars);
l.vars = bdd_high(l.vars);
int v_min = bdd_var(l.f_min);
int v_max = bdd_var(l.f_max);
if (v < v_min && v < v_max)
// Do not use a while() for this goto, because we want
// `continue' to be relative to the outermost while().
goto next_var;
// Pick the first variable in VARS that is used by F_MIN
// or F_MAX. We know that VARS, F_MIN or F_MAX are not
// constants (bddtrue or bddfalse) because one of the
// two above `if' would have matched; so it's ok to call
// bdd_var().
int v = bdd_var(l.vars);
l.vars = bdd_high(l.vars);
int v_min = bdd_var(l.f_min);
int v_max = bdd_var(l.f_max);
if (v < v_min && v < v_max)
// Do not use a while() for this goto, because we want
// `continue' to be relative to the outermost while().
goto next_var;
l.step = local_vars::SecondStep;
l.step = local_vars::SecondStep;
bdd v0 = bdd_nithvar(v);
l.v1 = bdd_ithvar(v);
bdd v0 = bdd_nithvar(v);
l.v1 = bdd_ithvar(v);
// All the following should be equivalent to
// f0_min = bdd_restrict(f_min, v0);
// f0_max = bdd_restrict(f_max, v0);
// f1_min = bdd_restrict(f_min, v1);
// f1_max = bdd_restrict(f_max, v1);
// but we try to avoid bdd_restrict when possible.
if (v == v_min)
{
l.f0_min = bdd_low(l.f_min);
l.f1_min = bdd_high(l.f_min);
}
else if (v_min < v)
{
l.f0_min = bdd_restrict(l.f_min, v0);
l.f1_min = bdd_restrict(l.f_min, l.v1);
}
else
{
l.f1_min = l.f0_min = l.f_min;
}
if (v == v_max)
{
l.f0_max = bdd_low(l.f_max);
l.f1_max = bdd_high(l.f_max);
}
else if (v_max < v)
{
l.f0_max = bdd_restrict(l.f_max, v0);
l.f1_max = bdd_restrict(l.f_max, l.v1);
}
else
{
l.f1_max = l.f0_max = l.f_max;
}
// All the following should be equivalent to
// f0_min = bdd_restrict(f_min, v0);
// f0_max = bdd_restrict(f_max, v0);
// f1_min = bdd_restrict(f_min, v1);
// f1_max = bdd_restrict(f_max, v1);
// but we try to avoid bdd_restrict when possible.
if (v == v_min)
{
l.f0_min = bdd_low(l.f_min);
l.f1_min = bdd_high(l.f_min);
}
else if (v_min < v)
{
l.f0_min = bdd_restrict(l.f_min, v0);
l.f1_min = bdd_restrict(l.f_min, l.v1);
}
else
{
l.f1_min = l.f0_min = l.f_min;
}
if (v == v_max)
{
l.f0_max = bdd_low(l.f_max);
l.f1_max = bdd_high(l.f_max);
}
else if (v_max < v)
{
l.f0_max = bdd_restrict(l.f_max, v0);
l.f1_max = bdd_restrict(l.f_max, l.v1);
}
else
{
l.f1_max = l.f0_max = l.f_max;
}
cube_.push(cube_.top() & v0);
todo_.emplace(l.f0_min - l.f1_max, l.f0_max, l.vars);
}
continue;
cube_.push(cube_.top() & v0);
todo_.emplace(l.f0_min - l.f1_max, l.f0_max, l.vars);
}
continue;
case local_vars::SecondStep:
l.step = local_vars::ThirdStep;
l.g0 = ret_;
cube_.pop();
cube_.push(cube_.top() & l.v1);
todo_.emplace(l.f1_min - l.f0_max, l.f1_max, l.vars);
continue;
case local_vars::SecondStep:
l.step = local_vars::ThirdStep;
l.g0 = ret_;
cube_.pop();
cube_.push(cube_.top() & l.v1);
todo_.emplace(l.f1_min - l.f0_max, l.f1_max, l.vars);
continue;
case local_vars::ThirdStep:
l.step = local_vars::FourthStep;
l.g1 = ret_;
cube_.pop();
{
bdd fs_max = l.f0_max & l.f1_max;
bdd fs_min = fs_max & ((l.f0_min - l.g0) | (l.f1_min - l.g1));
todo_.emplace(fs_min, fs_max, l.vars);
}
continue;
case local_vars::ThirdStep:
l.step = local_vars::FourthStep;
l.g1 = ret_;
cube_.pop();
{
bdd fs_max = l.f0_max & l.f1_max;
bdd fs_min = fs_max & ((l.f0_min - l.g0) | (l.f1_min - l.g1));
todo_.emplace(fs_min, fs_max, l.vars);
}
continue;
case local_vars::FourthStep:
ret_ |= (l.g0 - l.v1) | (l.g1 & l.v1);
todo_.pop();
continue;
}
SPOT_UNREACHABLE();
case local_vars::FourthStep:
ret_ |= (l.g0 - l.v1) | (l.g1 & l.v1);
todo_.pop();
continue;
}
SPOT_UNREACHABLE();
}
return bddfalse;
}

View file

@ -91,7 +91,7 @@ namespace spot
bdd f1_min, f1_max;
bdd g0, g1;
local_vars(bdd f_min, bdd f_max, bdd vars)
: f_min(f_min), f_max(f_max), step(FirstStep), vars(vars) {}
: f_min(f_min), f_max(f_max), step(FirstStep), vars(vars) {}
};
std::stack<local_vars> todo_;
std::stack<bdd> cube_;

View file

@ -43,17 +43,17 @@ namespace spot
~multiple_size_pool()
{
while (chunklist_)
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
{
chunk_* prev = chunklist_->prev;
free(chunklist_);
chunklist_ = prev;
}
}
size_t fixsize(size_t size) const
{
if (size < sizeof(block_))
size = sizeof(block_);
size = sizeof(block_);
return (size + alignment_ - 1) & ~(alignment_ - 1);
}
@ -67,28 +67,28 @@ namespace spot
block_*& f = freelist_[size];
// If we have free blocks available, return the first one.
if (f)
{
block_* first = f;
f = f->next;
return first;
}
{
block_* first = f;
f = f->next;
return first;
}
// Else, create a block out of the last chunk of allocated
// memory.
// If all the last chunk has been used, allocate one more.
if (free_start_ + size > free_end_)
{
const size_t requested = (size > 128 ? size : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
{
const size_t requested = (size > 128 ? size : 128) * 8192 - 64;
chunk_* c = reinterpret_cast<chunk_*>(malloc(requested));
if (!c)
throw std::bad_alloc();
c->prev = chunklist_;
chunklist_ = c;
free_start_ = c->data_ + size;
free_end_ = c->data_ + requested;
}
free_start_ = c->data_ + size;
free_end_ = c->data_ + requested;
}
void* res = free_start_;
free_start_ += size;

View file

@ -33,96 +33,96 @@ namespace spot
{
while (*options)
{
// Skip leading separators.
while (*options && strchr(" \t\n,;", *options))
++options;
// Skip leading separators.
while (*options && strchr(" \t\n,;", *options))
++options;
// `!foo' is a shorthand for `foo=0'.
const char* negated = nullptr;
if (*options == '!')
{
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
negated = options++;
}
// `!foo' is a shorthand for `foo=0'.
const char* negated = nullptr;
if (*options == '!')
{
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
negated = options++;
}
if (!*options)
{
if (negated)
return negated;
else
break;
}
if (!*options)
{
if (negated)
return negated;
else
break;
}
const char* name_start = options;
const char* name_start = options;
// Find the end of the name.
while (*options && !strchr(", \t\n;=", *options))
++options;
// Find the end of the name.
while (*options && !strchr(", \t\n;=", *options))
++options;
std::string name(name_start, options);
std::string name(name_start, options);
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
if (*options != '=')
{
options_[name] = (negated ? 0 : 1);
}
else if (negated)
{
return negated;
}
else
{
++options;
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
if (!*options)
return name_start;
if (*options != '=')
{
options_[name] = (negated ? 0 : 1);
}
else if (negated)
{
return negated;
}
else
{
++options;
// Skip spaces.
while (*options && strchr(" \t\n", *options))
++options;
if (!*options)
return name_start;
if (*options == '\'' || *options == '"')
{
auto sep = *options;
auto start = options + 1;
do
++options;
while (*options && *options != sep);
if (*options != sep)
return start - 1;
std::string val(start, options);
options_str_[name] = val;
if (*options)
++options;
}
else
{
char* val_end;
int val = strtol(options, &val_end, 10);
if (val_end == options)
return name_start;
if (*options == '\'' || *options == '"')
{
auto sep = *options;
auto start = options + 1;
do
++options;
while (*options && *options != sep);
if (*options != sep)
return start - 1;
std::string val(start, options);
options_str_[name] = val;
if (*options)
++options;
}
else
{
char* val_end;
int val = strtol(options, &val_end, 10);
if (val_end == options)
return name_start;
if (*val_end == 'K')
{
val *= 1024;
++val_end;
}
else if (*val_end == 'M')
{
val *= 1024 * 1024;
++val_end;
}
else if (*val_end && !strchr(" \t\n,;", *val_end))
{
return options;
}
options = val_end;
options_[name] = val;
}
}
if (*val_end == 'K')
{
val *= 1024;
++val_end;
}
else if (*val_end == 'M')
{
val *= 1024 * 1024;
++val_end;
}
else if (*val_end && !strchr(" \t\n,;", *val_end))
{
return options;
}
options = val_end;
options_[name] = val;
}
}
}
return nullptr;
}

View file

@ -84,7 +84,7 @@ namespace spot
/// \return The previous value associated to \a option if declared,
/// or \a def otherwise.
std::string set_str(const char* option,
std::string val, std::string def = {});
std::string val, std::string def = {});
/// Acquire all the settings of \a o.
void set(const option_map& o);

View file

@ -96,8 +96,8 @@ namespace spot
if (has_next)
{
has_next = false;
return next;
has_next = false;
return next;
}
double x;
@ -105,9 +105,9 @@ namespace spot
double r;
do
{
x = 2.0 * drand() - 1.0;
y = 2.0 * drand() - 1.0;
r = x * x + y * y;
x = 2.0 * drand() - 1.0;
y = 2.0 * drand() - 1.0;
r = x * x + y * y;
}
while (r >= 1.0 || r == 0.0);
r = sqrt(-2 * log(r) / r);
@ -124,8 +124,8 @@ namespace spot
while (s < p)
{
s -= log(1.0 - drand());
++x;
s -= log(1.0 - drand());
++x;
}
return x - 1;
}

View file

@ -97,12 +97,12 @@ namespace spot
rand() const
{
for (;;)
{
int x = round(gen() * s_ + m_);
if (x < 0)
continue;
{
int x = round(gen() * s_ + m_);
if (x < 0)
continue;
if (x <= n_)
return x;
return x;
}
SPOT_UNREACHABLE();
return 0;
@ -128,11 +128,11 @@ namespace spot
auto d = std::distance(first, last);
if (d > 1)
{
for (--last; first < last; ++first, --d)
{
auto i = mrand(d);
std::swap(*first, *(first + i));
}
for (--last; first < last; ++first, --d)
{
auto i = mrand(d);
std::swap(*first, *(first + i));
}
}
}
/// @}

View file

@ -37,48 +37,48 @@ namespace spot
satsolver_command()
{
satsolver = getenv("SPOT_SATSOLVER");
if (!satsolver)
{
satsolver = "glucose -verb=0 -model %I >%O";
return;
}
prime(satsolver);
if (!has('I'))
throw std::runtime_error("SPOT_SATSOLVER should contain %I to "
"indicate how to use the input filename.");
if (!has('O'))
throw std::runtime_error("SPOT_SATSOLVER should contain %O to "
"indicate how to use the output filename.");
satsolver = getenv("SPOT_SATSOLVER");
if (!satsolver)
{
satsolver = "glucose -verb=0 -model %I >%O";
return;
}
prime(satsolver);
if (!has('I'))
throw std::runtime_error("SPOT_SATSOLVER should contain %I to "
"indicate how to use the input filename.");
if (!has('O'))
throw std::runtime_error("SPOT_SATSOLVER should contain %O to "
"indicate how to use the output filename.");
}
int
run(printable* in, printable* out)
{
declare('I', in);
declare('O', out);
std::ostringstream s;
format(s, satsolver);
int res = system(s.str().c_str());
if (res < 0 || (WIFEXITED(res) && WEXITSTATUS(res) == 127))
{
s << ": failed to execute";
throw std::runtime_error(s.str());
}
// For POSIX shells, "The exit status of a command that
// terminated because it received a signal shall be reported
// as greater than 128."
if (WIFEXITED(res) && WEXITSTATUS(res) >= 128)
{
s << ": terminated by signal";
throw std::runtime_error(s.str());
}
if (WIFSIGNALED(res))
{
s << ": terminated by signal " << WTERMSIG(res);
throw std::runtime_error(s.str());
}
return res;
declare('I', in);
declare('O', out);
std::ostringstream s;
format(s, satsolver);
int res = system(s.str().c_str());
if (res < 0 || (WIFEXITED(res) && WEXITSTATUS(res) == 127))
{
s << ": failed to execute";
throw std::runtime_error(s.str());
}
// For POSIX shells, "The exit status of a command that
// terminated because it received a signal shall be reported
// as greater than 128."
if (WIFEXITED(res) && WEXITSTATUS(res) >= 128)
{
s << ": terminated by signal";
throw std::runtime_error(s.str());
}
if (WIFSIGNALED(res))
{
s << ": terminated by signal " << WTERMSIG(res);
throw std::runtime_error(s.str());
}
return res;
}
};
}
@ -96,25 +96,25 @@ namespace spot
int c;
while ((c = in->get()) != EOF)
{
// If a line does not start with 'v ', ignore it.
if (c != 'v' || in->get() != ' ')
{
in->ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
// Otherwise, read integers one by one.
int i;
while (*in >> i)
{
if (i == 0)
goto done;
sol.push_back(i);
}
if (!in->eof())
// If we haven't reached end-of-file, then we just attempted
// to extract something that wasn't an integer. Clear the
// fail bit so that will loop over.
in->clear();
// If a line does not start with 'v ', ignore it.
if (c != 'v' || in->get() != ' ')
{
in->ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
// Otherwise, read integers one by one.
int i;
while (*in >> i)
{
if (i == 0)
goto done;
sol.push_back(i);
}
if (!in->eof())
// If we haven't reached end-of-file, then we just attempted
// to extract something that wasn't an integer. Clear the
// fail bit so that will loop over.
in->clear();
}
done:
if (in != &std::cin)
@ -149,7 +149,7 @@ namespace spot
satsolver::solution_pair
satsolver::get_solution()
{
delete cnf_stream_; // Close the file.
delete cnf_stream_; // Close the file.
cnf_stream_ = nullptr;
temporary_file* output = create_tmpfile("sat-", ".out");

View file

@ -43,7 +43,7 @@ namespace spot
void check() const
{
if (count_ < 0)
throw std::runtime_error("too many SAT clauses (more than INT_MAX)");
throw std::runtime_error("too many SAT clauses (more than INT_MAX)");
}
clause_counter& operator++()

View file

@ -37,8 +37,8 @@ namespace spot
time_info total;
for (tm_type::const_iterator i = tm.begin(); i != tm.end(); ++i)
{
total.utime += i->second.first.utime();
total.stime += i->second.first.stime();
total.utime += i->second.first.utime();
total.stime += i->second.first.stime();
}
clock_t grand_total = total.utime + total.stime;
@ -52,30 +52,30 @@ namespace spot
<< std::endl;
for (tm_type::const_iterator i = tm.begin(); i != tm.end(); ++i)
{
// truncate long keys
std::string name = i->first;
if (name.size() > 22)
name.erase(22);
// truncate long keys
std::string name = i->first;
if (name.size() > 22)
name.erase(22);
const spot::timer& t = i->second.first;
const char* sep = t.is_running() ? "+|" : " |";
const spot::timer& t = i->second.first;
const char* sep = t.is_running() ? "+|" : " |";
os << std::setw(22) << name << sep
<< std::setw(6) << t.utime() << ' '
<< std::setw(8) << (total.utime ?
100.0 * t.utime() / total.utime : 0.)
<< sep
<< std::setw(6) << t.stime() << ' '
<< std::setw(8) << (total.stime ?
100.0 * t.stime() / total.stime : 0.)
<< sep
<< std::setw(6) << t.utime() + t.stime() << ' '
<< std::setw(8) << (grand_total ?
(100.0 * (t.utime() + t.stime()) /
grand_total) : 0.)
<< sep
<< std::setw(4) << i->second.second
<< std::endl;
os << std::setw(22) << name << sep
<< std::setw(6) << t.utime() << ' '
<< std::setw(8) << (total.utime ?
100.0 * t.utime() / total.utime : 0.)
<< sep
<< std::setw(6) << t.stime() << ' '
<< std::setw(8) << (total.stime ?
100.0 * t.stime() / total.stime : 0.)
<< sep
<< std::setw(6) << t.utime() + t.stime() << ' '
<< std::setw(8) << (grand_total ?
(100.0 * (t.utime() + t.stime()) /
grand_total) : 0.)
<< sep
<< std::setw(4) << i->second.second
<< std::endl;
}
os << std::setw(79) << std::setfill('-') << "" << std::setfill(' ')
<< std::endl

View file

@ -197,7 +197,7 @@ namespace spot
assert(i != tm.end());
assert(0 < i->second.second);
if (0 == --i->second.second)
tm.erase(i);
tm.erase(i);
}
/// Return the timer \a name.

View file

@ -35,14 +35,14 @@ namespace spot
{
const char* res = secure_getenv("SPOT_TMPDIR");
if (res)
return res;
return res;
return secure_getenv("TMPDIR");
}
static int
create_temporary_file(const char* prefix,
const char* suffix,
char** name)
const char* suffix,
char** name)
throw(std::bad_alloc, std::runtime_error)
{
static const char* tmpdir = get_tmpdir();
@ -51,30 +51,30 @@ namespace spot
size_t len = strlen(prefix);
size_t slen = 0;
if (suffix)
len += slen = strlen(suffix);
len += slen = strlen(suffix);
char* x = *name = static_cast<char*>(malloc(tmpdirlen + 1 + len + 6 + 1));
if (!x)
throw std::bad_alloc();
throw std::bad_alloc();
if (tmpdir)
{
x = stpcpy(x, tmpdir);
if (x[-1] != '/')
*x++ = '/';
}
{
x = stpcpy(x, tmpdir);
if (x[-1] != '/')
*x++ = '/';
}
x = stpcpy(x, prefix);
x = stpcpy(x, "XXXXXX");
int fd;
if (suffix)
{
stpcpy(x, suffix);
fd = mkstemps(*name, slen);
}
{
stpcpy(x, suffix);
fd = mkstemps(*name, slen);
}
else
{
fd = mkstemp(*name);
}
{
fd = mkstemp(*name);
}
if (fd < 0)
throw std::runtime_error(std::string("failed to create ") + *name);
throw std::runtime_error(std::string("failed to create ") + *name);
return fd;
}
}

View file

@ -113,8 +113,8 @@ namespace spot
constexpr trival operator!() const
{
return trival((val_ == yes_value) ? no_value :
(val_ == no_value) ? yes_value :
maybe_value);
(val_ == no_value) ? yes_value :
maybe_value);
}
};
@ -171,8 +171,8 @@ namespace spot
inline std::ostream& operator<<(std::ostream& os, trival v)
{
return os << ((v.val() == trival::no_value) ? "no"
: (v.val() == trival::maybe_value) ? "maybe"
: "yes");
: (v.val() == trival::maybe_value) ? "maybe"
: "yes");
}
/// @}

View file

@ -29,11 +29,11 @@ namespace spot
spot::parse_aut_error_list::iterator it;
for (auto& err : errors)
{
if (!filename.empty() && filename != "-")
os << filename << ':';
os << err.first << ": ";
os << err.second << std::endl;
printed = true;
if (!filename.empty() && filename != "-")
os << filename << ':';
os << err.first << ": ";
os << err.second << std::endl;
printed = true;
}
return printed;
}

View file

@ -25,8 +25,8 @@
# define YY_DECL \
int hoayylex(hoayy::parser::semantic_type *yylval, \
spot::location *yylloc, \
spot::parse_aut_error_list& error_list)
spot::location *yylloc, \
spot::parse_aut_error_list& error_list)
YY_DECL;
namespace spot

View file

@ -91,11 +91,11 @@ namespace spot
struct automaton_parser_options final
{
bool ignore_abort = false; ///< Skip aborted automata
bool debug = false; ///< Run the parser in debug mode?
bool trust_hoa = true; ///< Trust properties in HOA files
bool raise_errors = false; ///< Raise errors as exceptions.
bool want_kripke = false; ///< Parse as a Kripke structure.
bool ignore_abort = false; ///< Skip aborted automata
bool debug = false; ///< Run the parser in debug mode?
bool trust_hoa = true; ///< Trust properties in HOA files
bool raise_errors = false; ///< Raise errors as exceptions.
bool want_kripke = false; ///< Parse as a Kripke structure.
};
/// \brief Parse a stream of automata
@ -128,7 +128,7 @@ namespace spot
/// \param filename The file to read from.
/// \param opts Parser options.
automaton_stream_parser(const std::string& filename,
automaton_parser_options opts = {});
automaton_parser_options opts = {});
/// \brief Parse from an already opened file descriptor.
///
@ -136,7 +136,7 @@ namespace spot
/// \param filename What to display in error messages.
/// \param opts Parser options.
automaton_stream_parser(int fd, const std::string& filename,
automaton_parser_options opts = {});
automaton_parser_options opts = {});
/// \brief Parse from a buffer
///
@ -144,8 +144,8 @@ namespace spot
/// \param filename What to display in error messages.
/// \param opts Parser options.
automaton_stream_parser(const char* data,
const std::string& filename,
automaton_parser_options opts = {});
const std::string& filename,
automaton_parser_options opts = {});
~automaton_stream_parser();
@ -165,8 +165,8 @@ namespace spot
///
/// \warning This function is not reentrant.
parsed_aut_ptr parse(const bdd_dict_ptr& dict,
environment& env =
default_environment::instance());
environment& env =
default_environment::instance());
};
/// \brief Read the first spot::twa_graph from a file.
@ -187,8 +187,8 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API parsed_aut_ptr
parse_aut(const std::string& filename,
const bdd_dict_ptr& dict,
environment& env = default_environment::instance(),
automaton_parser_options opts = {});
const bdd_dict_ptr& dict,
environment& env = default_environment::instance(),
automaton_parser_options opts = {});
/// @}
}

View file

@ -30,7 +30,7 @@ namespace spot
{
void
fix_utf8_locations(const std::string& ltl_string,
parse_error_list& error_list)
parse_error_list& error_list)
{
// LUT to convert byte positions to utf8 positions.
// (The +2 is to account for position 0, not used,
@ -42,15 +42,15 @@ namespace spot
std::string::const_iterator i = b;
std::string::const_iterator e = ltl_string.end();
unsigned n = 0; // number of current utf8 character
unsigned prev = 0; // last byte of previous utf8 character
unsigned n = 0; // number of current utf8 character
unsigned prev = 0; // last byte of previous utf8 character
while (i != e)
{
utf8::next(i, e);
++n;
unsigned d = std::distance(b, i);
while (prev < d)
b2u[++prev] = n;
utf8::next(i, e);
++n;
unsigned d = std::distance(b, i);
while (prev < d)
b2u[++prev] = n;
}
b2u[++prev] = ++n;
@ -58,9 +58,9 @@ namespace spot
parse_error_list::iterator it;
for (it = error_list.begin(); it != error_list.end(); ++it)
{
location& l = it->first;
l.begin.column = b2u[l.begin.column];
l.end.column = b2u[l.end.column];
location& l = it->first;
l.begin.column = b2u[l.begin.column];
l.end.column = b2u[l.end.column];
}
}
@ -68,45 +68,45 @@ namespace spot
{
static bool
format_parse_errors_aux(std::ostream& os,
const std::string& ltl_string,
const parse_error_list& error_list,
unsigned shift)
const std::string& ltl_string,
const parse_error_list& error_list,
unsigned shift)
{
bool printed = false;
for (auto it: error_list)
{
os << ">>> " << ltl_string << '\n';
const location& l = it.first;
{
os << ">>> " << ltl_string << '\n';
const location& l = it.first;
unsigned n = 1;
for (; n < 4 + l.begin.column + shift; ++n)
os << ' ';
// Write at least one '^', even if begin==end.
os << '^';
++n;
for (; n < 4 + l.end.column + shift; ++n)
os << '^';
os << '\n' << it.second << "\n\n";
printed = true;
}
unsigned n = 1;
for (; n < 4 + l.begin.column + shift; ++n)
os << ' ';
// Write at least one '^', even if begin==end.
os << '^';
++n;
for (; n < 4 + l.end.column + shift; ++n)
os << '^';
os << '\n' << it.second << "\n\n";
printed = true;
}
return printed;
}
}
bool
parsed_formula::format_errors(std::ostream& os,
const std::string& real_input,
unsigned shift)
const std::string& real_input,
unsigned shift)
{
if (utf8::is_valid(input.begin(), input.end()))
{
parse_error_list fixed = errors;
fix_utf8_locations(input, fixed);
return format_parse_errors_aux(os, real_input, fixed, shift);
parse_error_list fixed = errors;
fix_utf8_locations(input, fixed);
return format_parse_errors_aux(os, real_input, fixed, shift);
}
else
{
return format_parse_errors_aux(os, real_input, errors, shift);
return format_parse_errors_aux(os, real_input, errors, shift);
}
}

View file

@ -27,8 +27,8 @@
# define YY_DECL \
int tlyylex (tlyy::parser::semantic_type *yylval, \
spot::location *yylloc, \
spot::parse_error_list& error_list)
spot::location *yylloc, \
spot::parse_error_list& error_list)
YY_DECL;
void flex_set_buffer(const std::string& buf, int start_tok, bool lenient);

View file

@ -53,7 +53,7 @@ namespace spot
{
auto i = map_.find(name);
if (i != map_.end())
return true;
return true;
auto v = aut_->acc().add_set();
map_[name] = v;
return true;
@ -63,7 +63,7 @@ namespace spot
{
auto p = map_.find(name);
if (p == map_.end())
return std::make_pair(false, 0U);
return std::make_pair(false, 0U);
return std::make_pair(true, acc_cond::mark_t({p->second}));
}
};
@ -83,9 +83,9 @@ namespace spot
std::pair<bool, acc_cond::mark_t> lookup(unsigned n)
{
if (n < aut_->acc().num_sets())
return std::make_pair(true, acc_cond::mark_t({n}));
return std::make_pair(true, acc_cond::mark_t({n}));
else
return std::make_pair(false, 0U);
return std::make_pair(false, 0U);
}
};
@ -106,13 +106,13 @@ namespace spot
{
auto p = map_.find(n);
if (p != map_.end())
return std::make_pair(true, p->second);
return std::make_pair(true, p->second);
if (used_ < aut_->acc().num_sets())
{
auto res = acc_cond::mark_t({used_++});
map_[n] = res;
return std::make_pair(true, res);
}
{
auto res = acc_cond::mark_t({used_++});
map_[n] = res;
return std::make_pair(true, res);
}
return std::make_pair(false, 0U);
}
};

View file

@ -67,15 +67,15 @@ namespace spot
// externally), use the new variables.
if (lvarnum < varnum)
{
more -= varnum - lvarnum;
lvarnum = varnum;
more -= varnum - lvarnum;
lvarnum = varnum;
}
// If we still need more variable, do allocate them.
if (more > 0)
{
bdd_extvarnum(more);
varnum += more;
lvarnum = varnum;
bdd_extvarnum(more);
varnum += more;
lvarnum = varnum;
}
}
@ -98,19 +98,19 @@ namespace spot
// of the variable space, allocate just the difference.
if (!fl.empty() && fl.back().first + fl.back().second == lvarnum)
{
int res = fl.back().first;
int endvar = fl.back().second;
assert(n > endvar);
extvarnum(n - endvar);
fl.pop_back();
return res;
int res = fl.back().first;
int endvar = fl.back().second;
assert(n > endvar);
extvarnum(n - endvar);
fl.pop_back();
return res;
}
else
{
// Otherwise, allocate as much variables as we need.
int res = lvarnum;
extvarnum(n);
return res;
// Otherwise, allocate as much variables as we need.
int res = lvarnum;
extvarnum(n);
return res;
}
}
}

View file

@ -41,24 +41,24 @@ namespace spot
free_list_type::iterator cur;
for (cur = fl.begin(); cur != fl.end(); ++cur)
{
if (cur->second < n)
continue;
if (n == cur->second)
{
best = cur;
break;
}
if (best == fl.end()
|| cur->second < best->second)
best = cur;
if (cur->second < n)
continue;
if (n == cur->second)
{
best = cur;
break;
}
if (best == fl.end()
|| cur->second < best->second)
best = cur;
}
// We have found enough free variables.
if (best != fl.end())
{
int result = best->first;
remove(best, result, n);
return result;
int result = best->first;
remove(best, result, n);
return result;
}
// We haven't found enough adjacent free variables;
@ -73,67 +73,67 @@ namespace spot
int end = base + n;
for (cur = fl.begin(); cur != fl.end(); ++cur)
{
int cend = cur->first + cur->second;
// cur [...]
// to insert [...]
// -----------------------
// result [...] [...]
// (Insert a new range, unconnected.)
if (cur->first > end)
{
break;
}
// cur [...]
// to insert [...]
// -----------------------
// result unknown : we should look at the rest of the freelist.
else if (base > cend)
{
continue;
}
// cur [....[ [......[
// to insert [....[ [..[
// ----------------------------------
// result [......[ [......[
else if (cur->first <= base)
{
if (cend >= end)
// second case : nothing to do
return;
// cur->second is set below.
}
// cur [....[ [..[
// to insert [....[ [.......[
// ----------------------------------
// result [......[ [.......[
else
{
cur->first = base;
// cur->second is set below.
}
int cend = cur->first + cur->second;
// cur [...]
// to insert [...]
// -----------------------
// result [...] [...]
// (Insert a new range, unconnected.)
if (cur->first > end)
{
break;
}
// cur [...]
// to insert [...]
// -----------------------
// result unknown : we should look at the rest of the freelist.
else if (base > cend)
{
continue;
}
// cur [....[ [......[
// to insert [....[ [..[
// ----------------------------------
// result [......[ [......[
else if (cur->first <= base)
{
if (cend >= end)
// second case : nothing to do
return;
// cur->second is set below.
}
// cur [....[ [..[
// to insert [....[ [.......[
// ----------------------------------
// result [......[ [.......[
else
{
cur->first = base;
// cur->second is set below.
}
// We get here in one of these three situations:
//
// cur [....[ [....[ [..[
// to insert [....[ [....[ [.......[
// -------------------------------------------
// result [......[ [......[ [.......[
//
// cur->first is already set, be cur->second has yet to be.
end = std::max(cend, end);
cur->second = end - cur->first;
// Since we have extended the current range, maybe the next
// items on the list should be merged.
free_list_type::iterator next = cur;
++next;
while (next != fl.end() && next->first <= end)
{
end = std::max(next->first + next->second, end);
cur->second = end - cur->first;
free_list_type::iterator next2 = next++;
fl.erase(next2);
}
return;
// We get here in one of these three situations:
//
// cur [....[ [....[ [..[
// to insert [....[ [....[ [.......[
// -------------------------------------------
// result [......[ [......[ [.......[
//
// cur->first is already set, be cur->second has yet to be.
end = std::max(cend, end);
cur->second = end - cur->first;
// Since we have extended the current range, maybe the next
// items on the list should be merged.
free_list_type::iterator next = cur;
++next;
while (next != fl.end() && next->first <= end)
{
end = std::max(next->first + next->second, end);
cur->second = end - cur->first;
free_list_type::iterator next2 = next++;
fl.erase(next2);
}
return;
}
// We reach this place either because a new unconnected range
@ -148,15 +148,15 @@ namespace spot
int end = base + n;
while (cur != fl.end() && cur->first < end)
{
int cend = cur->first + cur->second;
// Remove may invalidate the current iterator, so advance it first.
free_list_type::iterator old = cur++;
if (cend >= base)
{
int newbase = std::max(base, old->first);
int q = std::min(cend, end) - newbase;
remove(old, newbase, q);
}
int cend = cur->first + cur->second;
// Remove may invalidate the current iterator, so advance it first.
free_list_type::iterator old = cur++;
if (cend >= base)
{
int newbase = std::max(base, old->first);
int q = std::min(cend, end) - newbase;
remove(old, newbase, q);
}
}
}
@ -165,31 +165,31 @@ namespace spot
{
if (base == i->first)
{
// Removing at the beginning of the range
i->second -= n;
assert(i->second >= 0);
// Erase the range if it's now empty.
if (i->second == 0)
fl.erase(i);
else
i->first += n;
// Removing at the beginning of the range
i->second -= n;
assert(i->second >= 0);
// Erase the range if it's now empty.
if (i->second == 0)
fl.erase(i);
else
i->first += n;
}
else if (base + n == i->first + i->second)
{
// Removing at the end of the range
i->second -= n;
assert(i->second > 0); // cannot be empty because base != i->first
// Removing at the end of the range
i->second -= n;
assert(i->second > 0); // cannot be empty because base != i->first
}
else
{
// Removing in the middle of a range.
int b1 = i->first;
int n1 = base - i->first;
int n2 = i->first + i->second - base - n;
assert(n1 > 0);
assert(n2 > 0);
*i = pos_lenght_pair(base + n, n2);
fl.insert(i, pos_lenght_pair(b1, n1));
// Removing in the middle of a range.
int b1 = i->first;
int n1 = base - i->first;
int n2 = i->first + i->second - base - n;
assert(n1 > 0);
assert(n2 > 0);
*i = pos_lenght_pair(base + n, n2);
fl.insert(i, pos_lenght_pair(b1, n1));
}
}

View file

@ -29,11 +29,11 @@ namespace spot
trim(std::string& str)
{
str.erase(std::find_if(str.rbegin(), str.rend(),
std::not1(std::ptr_fun<int, int>
(std::isspace))).base(),
str.end());
std::not1(std::ptr_fun<int, int>
(std::isspace))).base(),
str.end());
str.erase(str.begin(),
std::find_if(str.begin(), str.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
std::find_if(str.begin(), str.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
}
}

View file

@ -42,7 +42,7 @@ namespace spot
{
for (auto s: a.sets())
if (m[s] > 0)
--m[s];
--m[s];
return *this;
}
@ -52,7 +52,7 @@ namespace spot
std::vector<unsigned> res;
for (unsigned n = 0; n < max; ++n)
if (m[n] > w.m[n])
res.push_back(n);
res.push_back(n);
return acc_cond::mark_t(res.begin(), res.end());
}

View file

@ -48,7 +48,7 @@ namespace spot
/// the corresponding counter in w.
acc_cond::mark_t diff(const acc_cond& acc, const weight& w) const;
friend std::ostream& operator<<(std::ostream& os,
const weight& w);
const weight& w);
private:
std::vector<int> m;

View file

@ -276,7 +276,7 @@ namespace spot
bool is_stuttering_transition = (get_tgba_condition()
== (dest)->get_tgba_condition());
bool dest_is_livelock_accepting =
dest->is_livelock_accepting_state();
dest->is_livelock_accepting_state();
//Before deleting stuttering transitions, propaged back livelock
//and initial state's properties
@ -319,7 +319,7 @@ namespace spot
// they are not cloned.
if (trans)
for (auto& t: *trans)
delete t;
delete t;
delete trans;
std::unordered_map<int, transitions*, std::hash<int> >::iterator i =
@ -338,8 +338,8 @@ namespace spot
ta_explicit::ta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state):
unsigned n_acc,
state_ta_explicit* artificial_initial_state):
ta(tgba->get_dict()),
tgba_(tgba),
artificial_initial_state_(artificial_initial_state)
@ -351,7 +351,7 @@ namespace spot
{
auto is = add_state(artificial_initial_state);
assert(is == artificial_initial_state);
(void)is;
(void)is;
}
}
@ -361,8 +361,8 @@ namespace spot
for (it = states_set_.begin(); it != states_set_.end(); ++it)
{
auto* s = const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(*it));
assert(s);
(down_cast<const state_ta_explicit*>(*it));
assert(s);
s->free_transitions();
s->get_tgba_state()->destroy();
delete s;
@ -390,11 +390,11 @@ namespace spot
auto add_state = initial_states_set_.insert(s);
if (get_artificial_initial_state())
if (add_state.second)
{
auto i =
down_cast<state_ta_explicit*>(get_artificial_initial_state());
create_transition(i, condition, 0U, s);
}
{
auto i =
down_cast<state_ta_explicit*>(get_artificial_initial_state());
create_transition(i, condition, 0U, s);
}
}
void
@ -411,9 +411,9 @@ namespace spot
void
ta_explicit::create_transition(state_ta_explicit* source, bdd condition,
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning)
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning)
{
state_ta_explicit::transition* t = new state_ta_explicit::transition;
t->dest = dest;

View file

@ -41,8 +41,8 @@ namespace spot
{
public:
ta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr);
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr);
const_twa_ptr
get_tgba() const;
@ -55,9 +55,9 @@ namespace spot
void
create_transition(state_ta_explicit* source, bdd condition,
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning = false);
acc_cond::mark_t acceptance_conditions,
const state_ta_explicit* dest,
bool add_at_beginning = false);
void
delete_stuttering_transitions();
@ -142,10 +142,10 @@ namespace spot
typedef std::list<transition*> transitions;
state_ta_explicit(const state* tgba_state, const bdd tgba_condition,
bool is_initial_state = false,
bool is_accepting_state = false,
bool is_livelock_accepting_state = false,
transitions* trans = nullptr) :
bool is_initial_state = false,
bool is_accepting_state = false,
bool is_livelock_accepting_state = false,
transitions* trans = nullptr) :
tgba_state_(tgba_state), tgba_condition_(tgba_condition),
is_initial_state_(is_initial_state), is_accepting_state_(
is_accepting_state), is_livelock_accepting_state_(
@ -246,8 +246,8 @@ namespace spot
inline ta_explicit_ptr
make_ta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr)
unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr)
{
return std::make_shared<ta_explicit>(tgba, n_acc, artificial_initial_state);
}

View file

@ -67,8 +67,8 @@ namespace spot
////////////////////////////////////////////////////////////
// ta_succ_iterator_product
ta_succ_iterator_product::ta_succ_iterator_product(const state_ta_product* s,
const ta* t,
const kripke* k)
const ta* t,
const kripke* k)
: source_(s), ta_(t), kripke_(k)
{
kripke_source_condition = kripke_->state_condition(s->get_kripke_state());
@ -243,7 +243,7 @@ namespace spot
ta_product::ta_product(const const_ta_ptr& testing_automata,
const const_kripke_ptr& kripke_structure):
const const_kripke_ptr& kripke_structure):
ta(testing_automata->get_dict()),
dict_(testing_automata->get_dict()),
ta_(testing_automata),
@ -292,9 +292,9 @@ namespace spot
for (auto s: ta_init_states_set)
if (artificial_initial_state ||
(kripke_init_condition == ta_->get_state_condition(s)))
initial_states_set.insert(new state_ta_product(s,
kripke_init->clone()));
(kripke_init_condition == ta_->get_state_condition(s)))
initial_states_set.insert(new state_ta_product(s,
kripke_init->clone()));
kripke_init->destroy();
return initial_states_set;
@ -316,8 +316,8 @@ namespace spot
const state_ta_product* stp = down_cast<const state_ta_product*> (s);
assert(s);
return new ta_succ_iterator_product_by_changeset(stp,
ta_.get(), kripke_.get(),
changeset);
ta_.get(), kripke_.get(),
changeset);
}
@ -402,7 +402,7 @@ namespace spot
ta_succ_iterator_product_by_changeset::
ta_succ_iterator_product_by_changeset(const state_ta_product* s, const ta* t,
const kripke* k, bdd changeset)
const kripke* k, bdd changeset)
: ta_succ_iterator_product(s, t, k)
{
current_condition_ = changeset;

View file

@ -131,7 +131,7 @@ namespace spot
/// \param testing_automaton The TA component in the product.
/// \param kripke_structure The Kripke component in the product.
ta_product(const const_ta_ptr& testing_automaton,
const const_kripke_ptr& kripke_structure);
const const_kripke_ptr& kripke_structure);
virtual
~ta_product();
@ -197,7 +197,7 @@ namespace spot
typedef std::shared_ptr<ta_product> ta_product_ptr;
typedef std::shared_ptr<const ta_product> const_ta_product_ptr;
inline ta_product_ptr product(const const_ta_ptr& testing_automaton,
const const_kripke_ptr& kripke_structure)
const const_kripke_ptr& kripke_structure)
{
return std::make_shared<ta_product>(testing_automaton, kripke_structure);
}
@ -207,8 +207,8 @@ namespace spot
{
public:
ta_succ_iterator_product_by_changeset(const state_ta_product* s,
const ta* t, const kripke* k,
bdd changeset);
const ta* t, const kripke* k,
bdd changeset);
/// \brief Move to the next successor in the Kripke structure
void next_kripke_dest();

View file

@ -25,8 +25,8 @@ namespace spot
{
tgta_explicit::tgta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state) :
unsigned n_acc,
state_ta_explicit* artificial_initial_state) :
tgta(tgba->get_dict()),
ta_(make_ta_explicit(tgba, n_acc, artificial_initial_state))
{

View file

@ -38,8 +38,8 @@ namespace spot
{
public:
tgta_explicit(const const_twa_ptr& tgba,
unsigned n_acc,
state_ta_explicit* artificial_initial_state);
unsigned n_acc,
state_ta_explicit* artificial_initial_state);
// tgba interface
virtual spot::state* get_init_state() const override;
@ -63,9 +63,9 @@ namespace spot
inline tgta_explicit_ptr
make_tgta_explicit(const const_twa_ptr& tgba, unsigned n_acc,
state_ta_explicit* artificial_initial_state = nullptr)
state_ta_explicit* artificial_initial_state = nullptr)
{
return std::make_shared<tgta_explicit>(tgba, n_acc,
artificial_initial_state);
artificial_initial_state);
}
}

View file

@ -44,7 +44,7 @@ namespace spot
// tgta_product
tgta_product::tgta_product(const const_kripke_ptr& left,
const const_tgta_ptr& right):
const const_tgta_ptr& right):
twa_product(left, right)
{
}
@ -207,7 +207,7 @@ namespace spot
kripke_current_dest_state->clone(),
tgta_succ_it_->dst(), pool_);
current_acceptance_conditions_
= tgta_succ_it_->acc();
= tgta_succ_it_->acc();
return true;
}

View file

@ -33,7 +33,7 @@ namespace spot
{
public:
tgta_product(const const_kripke_ptr& left,
const const_tgta_ptr& right);
const const_tgta_ptr& right);
virtual const state* get_init_state() const override;
@ -42,7 +42,7 @@ namespace spot
};
inline twa_ptr product(const const_kripke_ptr& left,
const const_tgta_ptr& right)
const const_tgta_ptr& right)
{
return std::make_shared<tgta_product>(left, right);
}
@ -52,9 +52,9 @@ namespace spot
{
public:
tgta_succ_iterator_product(const state_product* s,
const const_kripke_ptr& k,
const const_tgta_ptr& tgta,
fixed_size_pool* pool);
const const_kripke_ptr& k,
const const_tgta_ptr& tgta,
fixed_size_pool* pool);
virtual
~tgta_succ_iterator_product();

View file

@ -35,109 +35,109 @@ namespace spot
void
parse_opts(const char* options)
{
const char* orig = options;
while (char c = *options++)
switch (c)
{
case '.':
{
// Copy the value in a string, so future calls to
// parse_opts do not fail if the environment has
// changed. (This matters particularly in an ipython
// notebook, where it is tempting to redefine
// SPOT_DOTDEFAULT.)
static std::string def = []()
{
auto s = getenv("SPOT_DOTDEFAULT");
return s ? s : "";
}();
// Prevent infinite recursions...
if (orig == def.c_str())
throw std::runtime_error
(std::string("SPOT_DOTDEFAULT should not contain '.'"));
if (!def.empty())
parse_opts(def.c_str());
break;
}
case 'A':
opt_hide_sets_ = true;
break;
case 'c':
opt_circles_ = true;
break;
case 'C':
if (*options != '(')
throw std::runtime_error
("invalid node color specification for print_dot()");
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
("invalid node color specification for print_dot()");
opt_node_color_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'h':
opt_horizontal_ = true;
break;
case 'f':
if (*options != '(')
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
opt_font_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'v':
opt_horizontal_ = false;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'B':
case 'e':
case 'n':
case 'N':
case 'o':
case 'r':
case 'R':
case 's':
case 't':
case '+':
case '<':
case '#':
// All these options are implemented by dotty() on TGBA,
// but are not implemented here. We simply ignore them,
// because raising an exception if they are in
// SPOT_DEFAULT would be annoying.
break;
default:
throw std::runtime_error
(std::string("unknown option for dotty(): ") + c);
}
const char* orig = options;
while (char c = *options++)
switch (c)
{
case '.':
{
// Copy the value in a string, so future calls to
// parse_opts do not fail if the environment has
// changed. (This matters particularly in an ipython
// notebook, where it is tempting to redefine
// SPOT_DOTDEFAULT.)
static std::string def = []()
{
auto s = getenv("SPOT_DOTDEFAULT");
return s ? s : "";
}();
// Prevent infinite recursions...
if (orig == def.c_str())
throw std::runtime_error
(std::string("SPOT_DOTDEFAULT should not contain '.'"));
if (!def.empty())
parse_opts(def.c_str());
break;
}
case 'A':
opt_hide_sets_ = true;
break;
case 'c':
opt_circles_ = true;
break;
case 'C':
if (*options != '(')
throw std::runtime_error
("invalid node color specification for print_dot()");
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
("invalid node color specification for print_dot()");
opt_node_color_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'h':
opt_horizontal_ = true;
break;
case 'f':
if (*options != '(')
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
{
auto* end = strchr(++options, ')');
if (!end)
throw std::runtime_error
(std::string("invalid font specification for dotty()"));
opt_font_ = std::string(options, end - options);
options = end + 1;
}
break;
case 'v':
opt_horizontal_ = false;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'a':
case 'b':
case 'B':
case 'e':
case 'n':
case 'N':
case 'o':
case 'r':
case 'R':
case 's':
case 't':
case '+':
case '<':
case '#':
// All these options are implemented by dotty() on TGBA,
// but are not implemented here. We simply ignore them,
// because raising an exception if they are in
// SPOT_DEFAULT would be annoying.
break;
default:
throw std::runtime_error
(std::string("unknown option for dotty(): ") + c);
}
}
public:
dotty_bfs(std::ostream& os, const const_ta_ptr& a,
const char* opt) :
const char* opt) :
ta_reachable_iterator_breadth_first(a), os_(os)
{
parse_opts(opt ? opt : ".");
parse_opts(opt ? opt : ".");
}
void
@ -145,56 +145,56 @@ namespace spot
{
os_ << "digraph G {\n";
if (opt_horizontal_)
os_ << " rankdir=LR\n";
if (opt_circles_)
os_ << " node [shape=\"circle\"]\n";
if (!opt_node_color_.empty())
os_ << " node [style=\"filled\", fillcolor=\""
<< opt_node_color_ << "\"]\n";
if (!opt_font_.empty())
os_ << " fontname=\"" << opt_font_
<< "\"\n node [fontname=\"" << opt_font_
<< "\"]\n edge [fontname=\"" << opt_font_
<< "\"]\n";
if (opt_horizontal_)
os_ << " rankdir=LR\n";
if (opt_circles_)
os_ << " node [shape=\"circle\"]\n";
if (!opt_node_color_.empty())
os_ << " node [style=\"filled\", fillcolor=\""
<< opt_node_color_ << "\"]\n";
if (!opt_font_.empty())
os_ << " fontname=\"" << opt_font_
<< "\"\n node [fontname=\"" << opt_font_
<< "\"]\n edge [fontname=\"" << opt_font_
<< "\"]\n";
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string extra = []()
{
auto s = getenv("SPOT_DOTEXTRA");
return s ? s : "";
}();
// Any extra text passed in the SPOT_DOTEXTRA environment
// variable should be output at the end of the "header", so
// that our setup can be overridden.
if (!extra.empty())
os_ << " " << extra << '\n';
// Always copy the environment variable into a static string,
// so that we (1) look it up once, but (2) won't crash if the
// environment is changed.
static std::string extra = []()
{
auto s = getenv("SPOT_DOTEXTRA");
return s ? s : "";
}();
// Any extra text passed in the SPOT_DOTEXTRA environment
// variable should be output at the end of the "header", so
// that our setup can be overridden.
if (!extra.empty())
os_ << " " << extra << '\n';
artificial_initial_state_ = t_automata_->get_artificial_initial_state();
ta::const_states_set_t init_states_set;
if (artificial_initial_state_)
{
init_states_set.insert(artificial_initial_state_);
os_ << " 0 [label=\"\", style=invis, height=0]\n 0 -> 1\n";
}
{
init_states_set.insert(artificial_initial_state_);
os_ << " 0 [label=\"\", style=invis, height=0]\n 0 -> 1\n";
}
else
{
int n = 0;
init_states_set = t_automata_->get_initial_states_set();
for (auto s: init_states_set)
{
bdd init_condition = t_automata_->get_state_condition(s);
std::string label = bdd_format_formula(t_automata_->get_dict(),
init_condition);
++n;
os_ << " " << -n << " [label=\"\", style=invis, height=0]\n "
<< -n << " -> " << n << " [label=\"" << label << "\"]\n";
}
}
{
int n = 0;
init_states_set = t_automata_->get_initial_states_set();
for (auto s: init_states_set)
{
bdd init_condition = t_automata_->get_state_condition(s);
std::string label = bdd_format_formula(t_automata_->get_dict(),
init_condition);
++n;
os_ << " " << -n << " [label=\"\", style=invis, height=0]\n "
<< -n << " -> " << n << " [label=\"" << label << "\"]\n";
}
}
}
void
@ -209,41 +209,41 @@ namespace spot
std::string style;
if (t_automata_->is_accepting_state(s))
style = ",peripheries=2";
style = ",peripheries=2";
if (t_automata_->is_livelock_accepting_state(s))
style += ",shape=box";
if (t_automata_->is_livelock_accepting_state(s))
style += ",shape=box";
os_ << " " << n << " [label=";
if (s == artificial_initial_state_)
os_ << "init";
else
os_ << quote_unless_bare_word(t_automata_->format_state(s));
os_ << style << "]\n";
os_ << " " << n << " [label=";
if (s == artificial_initial_state_)
os_ << "init";
else
os_ << quote_unless_bare_word(t_automata_->format_state(s));
os_ << style << "]\n";
}
void
process_link(int in, int out, const ta_succ_iterator* si)
{
bdd_dict_ptr d = t_automata_->get_dict();
std::string label =
((in == 1 && artificial_initial_state_)
? bdd_format_formula(d, si->cond())
: bdd_format_accset(d, si->cond()));
bdd_dict_ptr d = t_automata_->get_dict();
std::string label =
((in == 1 && artificial_initial_state_)
? bdd_format_formula(d, si->cond())
: bdd_format_accset(d, si->cond()));
if (label.empty())
label = "{}";
if (label.empty())
label = "{}";
if (!opt_hide_sets_)
{
label += "\n";
label += t_automata_->acc().
format(si->acc());
}
if (!opt_hide_sets_)
{
label += "\n";
label += t_automata_->acc().
format(si->acc());
}
os_ << " " << in << " -> " << out << " [label=\"";
escape_str(os_, label);
os_ << "\"]\n";
escape_str(os_, label);
os_ << "\"]\n";
}
private:

View file

@ -26,5 +26,5 @@ namespace spot
{
SPOT_API std::ostream&
print_dot(std::ostream& os, const const_ta_ptr& a,
const char* opt = nullptr);
const char* opt = nullptr);
}

View file

@ -102,10 +102,10 @@ namespace spot
(ta_init_it_->dst()), kripke_init_state->clone());
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
{
init->destroy();
continue;
}
scc.push(++num);
arc.push(0U);
@ -146,7 +146,7 @@ namespace spot
}
// fill rem with any component removed,
auto i = h.find(curr);
auto i = h.find(curr);
assert(i != h.end());
scc.rem().push_front(curr);
@ -168,7 +168,7 @@ namespace spot
{
// removing states
for (auto j: scc.rem())
h[j] = -1;
h[j] = -1;
dec_depth(scc.rem().size());
scc.pop();
assert(!arc.empty());
@ -209,7 +209,7 @@ namespace spot
// We do not need SUCC from now on.
// Are we going to a new state?
auto p = h.emplace(dest, num + 1);
auto p = h.emplace(dest, num + 1);
if (p.second)
{
// Number it, stack it, and register its successors
@ -277,23 +277,23 @@ namespace spot
scc.rem().splice(scc.rem().end(), rem);
bool is_accepting_sscc = scc.top().is_accepting
|| a_->acc().accepting(scc.top().condition);
|| a_->acc().accepting(scc.top().condition);
if (is_accepting_sscc)
{
trace
<< "PASS 1: SUCCESS: a_->is_livelock_accepting_state(curr): "
<< a_->is_livelock_accepting_state(curr) << '\n';
<< "PASS 1: SUCCESS: a_->is_livelock_accepting_state(curr): "
<< a_->is_livelock_accepting_state(curr) << '\n';
trace
<< "PASS 1: scc.top().condition : "
<< scc.top().condition << '\n';
<< scc.top().condition << '\n';
trace
<< "PASS 1: a_->acc().all_sets() : "
<< (a_->acc().all_sets()) << '\n';
<< (a_->acc().all_sets()) << '\n';
trace
<< ("PASS 1 CYCLE and accepting? ")
<< a_->acc().accepting(scc.top().condition)
<< std::endl;
<< ("PASS 1 CYCLE and accepting? ")
<< a_->acc().accepting(scc.top().condition)
<< std::endl;
clear(h, todo, ta_init_it_);
return true;
}
@ -315,19 +315,19 @@ namespace spot
h_livelock_root = h[livelock_roots.top()];
if (heuristic_livelock_detection(dest, h, h_livelock_root,
liveset_curr))
liveset_curr))
{
clear(h, todo, ta_init_it_);
return true;
}
for (const state* succ: liveset_dest)
if (heuristic_livelock_detection(succ, h, h_livelock_root,
liveset_curr))
{
clear(h, todo, ta_init_it_);
return true;
}
if (heuristic_livelock_detection(succ, h, h_livelock_root,
liveset_curr))
{
clear(h, todo, ta_init_it_);
return true;
}
}
}
@ -403,11 +403,11 @@ namespace spot
auto init = ta_init_it_.front();
ta_init_it_.pop();
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
sscc.push(num);
sscc.top().is_accepting = t->is_livelock_accepting_state(init);
@ -435,7 +435,7 @@ namespace spot
trace << "PASS 2 : backtrack\n";
// fill rem with any component removed,
auto i = h.find(curr);
auto i = h.find(curr);
assert(i != h.end());
sscc.rem().push_front(curr);
@ -449,7 +449,7 @@ namespace spot
{
// removing states
for (auto j: sscc.rem())
h[j] = -1;
h[j] = -1;
dec_depth(sscc.rem().size());
sscc.pop();
}
@ -498,10 +498,10 @@ namespace spot
inc_depth();
continue;
}
else
{
dest->destroy();
}
else
{
dest->destroy();
}
// If we have reached a dead component, ignore it.
if (i->second == -1)
@ -509,12 +509,12 @@ namespace spot
//self loop state
if (!curr->compare(i->first))
if (t->is_livelock_accepting_state(curr))
{
clear(h, todo, ta_init_it_);
trace << "PASS 2: SUCCESS\n";
return true;
}
if (t->is_livelock_accepting_state(curr))
{
clear(h, todo, ta_init_it_);
trace << "PASS 2: SUCCESS\n";
return true;
}
// Now this is the most interesting case. We have reached a
// state S1 which is already part of a non-dead SSCC. Any such

View file

@ -34,7 +34,7 @@ namespace spot
namespace
{
typedef std::pair<const spot::state*,
ta_succ_iterator_product*> pair_state_iter;
ta_succ_iterator_product*> pair_state_iter;
}
/// \addtogroup ta_emptiness_check Emptiness-checks
@ -111,7 +111,7 @@ namespace spot
/// this heuristic is described in the paper cited above
bool
check(bool disable_second_pass = false,
bool disable_heuristic_for_livelock_detection = false);
bool disable_heuristic_for_livelock_detection = false);
/// \brief Check whether the product automaton contains
/// a livelock-accepting run

View file

@ -47,8 +47,8 @@ namespace spot
{
static std::ostream&
dump_hash_set(const hash_set* hs,
const const_ta_ptr& aut,
std::ostream& out)
const const_ta_ptr& aut,
std::ostream& out)
{
out << '{';
const char* sep = "";
@ -73,7 +73,7 @@ namespace spot
// automaton
static void
build_result(const const_ta_ptr& a, std::list<hash_set*>& sets,
twa_graph_ptr result_tgba, const ta_explicit_ptr& result)
twa_graph_ptr result_tgba, const ta_explicit_ptr& result)
{
// For each set, create a state in the tgbaulting automaton.
// For a state s, state_num[s] is the number of the state in the minimal
@ -82,103 +82,103 @@ namespace spot
std::list<hash_set*>::iterator sit;
unsigned num = 0;
for (sit = sets.begin(); sit != sets.end(); ++sit)
{
hash_set::iterator hit;
hash_set* h = *sit;
for (hit = h->begin(); hit != h->end(); ++hit)
state_num[*hit] = num;
result_tgba->new_state();
++num;
}
{
hash_set::iterator hit;
hash_set* h = *sit;
for (hit = h->begin(); hit != h->end(); ++hit)
state_num[*hit] = num;
result_tgba->new_state();
++num;
}
// For each transition in the initial automaton, add the corresponding
// transition in ta.
for (sit = sets.begin(); sit != sets.end(); ++sit)
{
hash_set::iterator hit;
hash_set* h = *sit;
hit = h->begin();
const state* src = *hit;
unsigned src_num = state_num[src];
{
hash_set::iterator hit;
hash_set* h = *sit;
hit = h->begin();
const state* src = *hit;
unsigned src_num = state_num[src];
bdd tgba_condition = bddtrue;
bool is_initial_state = a->is_initial_state(src);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(src);
bool is_accepting_state = a->is_accepting_state(src);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(src);
bdd tgba_condition = bddtrue;
bool is_initial_state = a->is_initial_state(src);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(src);
bool is_accepting_state = a->is_accepting_state(src);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(src);
state_ta_explicit* new_src =
new state_ta_explicit(result_tgba->state_from_number(src_num),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* new_src =
new state_ta_explicit(result_tgba->state_from_number(src_num),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* ta_src = result->add_state(new_src);
state_ta_explicit* ta_src = result->add_state(new_src);
if (ta_src != new_src)
{
delete new_src;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == src)
result->set_artificial_initial_state(new_src);
}
else if (is_initial_state)
{
result->add_to_initial_states_set(new_src);
}
if (ta_src != new_src)
{
delete new_src;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == src)
result->set_artificial_initial_state(new_src);
}
else if (is_initial_state)
{
result->add_to_initial_states_set(new_src);
}
ta_succ_iterator* succit = a->succ_iter(src);
ta_succ_iterator* succit = a->succ_iter(src);
for (succit->first(); !succit->done(); succit->next())
{
const state* dst = succit->dst();
hash_map::const_iterator i = state_num.find(dst);
for (succit->first(); !succit->done(); succit->next())
{
const state* dst = succit->dst();
hash_map::const_iterator i = state_num.find(dst);
if (i == state_num.end()) // Ignore useless destinations.
continue;
if (i == state_num.end()) // Ignore useless destinations.
continue;
bdd tgba_condition = bddtrue;
is_initial_state = a->is_initial_state(dst);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(dst);
bool is_accepting_state = a->is_accepting_state(dst);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(dst);
bdd tgba_condition = bddtrue;
is_initial_state = a->is_initial_state(dst);
if (!a->get_artificial_initial_state() && is_initial_state)
tgba_condition = a->get_state_condition(dst);
bool is_accepting_state = a->is_accepting_state(dst);
bool is_livelock_accepting_state =
a->is_livelock_accepting_state(dst);
state_ta_explicit* new_dst =
new state_ta_explicit
(result_tgba->state_from_number(i->second),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* new_dst =
new state_ta_explicit
(result_tgba->state_from_number(i->second),
tgba_condition, is_initial_state,
is_accepting_state,
is_livelock_accepting_state);
state_ta_explicit* ta_dst = result->add_state(new_dst);
state_ta_explicit* ta_dst = result->add_state(new_dst);
if (ta_dst != new_dst)
{
delete new_dst;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == dst)
result->set_artificial_initial_state(new_dst);
}
if (ta_dst != new_dst)
{
delete new_dst;
}
else if (a->get_artificial_initial_state())
{
if (a->get_artificial_initial_state() == dst)
result->set_artificial_initial_state(new_dst);
}
else if (is_initial_state)
result->add_to_initial_states_set(new_dst);
else if (is_initial_state)
result->add_to_initial_states_set(new_dst);
result->create_transition
(ta_src, succit->cond(),
succit->acc(),
ta_dst);
}
delete succit;
}
result->create_transition
(ta_src, succit->cond(),
succit->acc(),
ta_dst);
}
delete succit;
}
}
static partition_t
@ -187,22 +187,22 @@ namespace spot
unsigned num_sets = ta_->acc().num_sets();
std::map<acc_cond::mark_t, bdd> m2b;
int acc_vars = ta_->get_dict()->register_anonymous_variables(num_sets,
&m2b);
&m2b);
auto mark_to_bdd = [&](acc_cond::mark_t m) -> bdd
{
auto i = m2b.find(m);
if (i != m2b.end())
return i->second;
{
auto i = m2b.find(m);
if (i != m2b.end())
return i->second;
bdd res = bddtrue;
for (unsigned n = 0; n < num_sets; ++n)
if (m.has(n))
res &= bdd_ithvar(acc_vars + n);
else
res &= bdd_nithvar(acc_vars + n);
m2b.emplace_hint(i, m, res);
return res;
};
bdd res = bddtrue;
for (unsigned n = 0; n < num_sets; ++n)
if (m.has(n))
res &= bdd_ithvar(acc_vars + n);
else
res &= bdd_nithvar(acc_vars + n);
m2b.emplace_hint(i, m, res);
return res;
};
partition_t cur_run;
partition_t next_run;
@ -231,22 +231,22 @@ namespace spot
auto artificial_initial_state = ta_->get_artificial_initial_state();
for (it = states_set.begin(); it != states_set.end(); ++it)
{
const state* s = *it;
if (s == artificial_initial_state)
I->insert(s);
else if (!artificial_initial_state && ta_->is_initial_state(s))
I->insert(s);
else if (ta_->is_livelock_accepting_state(s)
&& ta_->is_accepting_state(s))
G_F->insert(s);
else if (ta_->is_accepting_state(s))
F->insert(s);
else if (ta_->is_livelock_accepting_state(s))
G->insert(s);
else
S->insert(s);
}
{
const state* s = *it;
if (s == artificial_initial_state)
I->insert(s);
else if (!artificial_initial_state && ta_->is_initial_state(s))
I->insert(s);
else if (ta_->is_livelock_accepting_state(s)
&& ta_->is_accepting_state(s))
G_F->insert(s);
else if (ta_->is_accepting_state(s))
F->insert(s);
else if (ta_->is_livelock_accepting_state(s))
G->insert(s);
else
S->insert(s);
}
hash_map state_set_map;
@ -255,103 +255,103 @@ namespace spot
// Use bdd variables to number sets. set_num is the first variable
// available.
unsigned set_num =
ta_->get_dict()->register_anonymous_variables(size, &m2b);
ta_->get_dict()->register_anonymous_variables(size, &m2b);
std::set<int> free_var;
for (unsigned i = set_num; i < set_num + size; ++i)
free_var.insert(i);
free_var.insert(i);
std::map<int, int> used_var;
for (hash_set::const_iterator i = I->begin(); i != I->end(); ++i)
{
hash_set* cI = new hash_set;
cI->insert(*i);
done.push_back(cI);
{
hash_set* cI = new hash_set;
cI->insert(*i);
done.push_back(cI);
used_var[set_num] = 1;
free_var.erase(set_num);
state_set_map[*i] = set_num;
++set_num;
used_var[set_num] = 1;
free_var.erase(set_num);
state_set_map[*i] = set_num;
++set_num;
}
}
delete I;
if (!G->empty())
{
unsigned s = G->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G);
else
done.push_back(G);
for (hash_set::const_iterator i = G->begin(); i != G->end(); ++i)
state_set_map[*i] = num;
{
unsigned s = G->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G);
else
done.push_back(G);
for (hash_set::const_iterator i = G->begin(); i != G->end(); ++i)
state_set_map[*i] = num;
}
}
else
{
delete G;
}
{
delete G;
}
if (!F->empty())
{
unsigned s = F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(F);
else
done.push_back(F);
for (hash_set::const_iterator i = F->begin(); i != F->end(); ++i)
state_set_map[*i] = num;
}
{
unsigned s = F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(F);
else
done.push_back(F);
for (hash_set::const_iterator i = F->begin(); i != F->end(); ++i)
state_set_map[*i] = num;
}
else
{
delete F;
}
{
delete F;
}
if (!G_F->empty())
{
unsigned s = G_F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G_F);
else
done.push_back(G_F);
for (hash_set::const_iterator i = G_F->begin(); i != G_F->end(); ++i)
state_set_map[*i] = num;
}
{
unsigned s = G_F->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(G_F);
else
done.push_back(G_F);
for (hash_set::const_iterator i = G_F->begin(); i != G_F->end(); ++i)
state_set_map[*i] = num;
}
else
{
delete G_F;
}
{
delete G_F;
}
if (!S->empty())
{
unsigned s = S->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(S);
else
done.push_back(S);
for (hash_set::const_iterator i = S->begin(); i != S->end(); ++i)
state_set_map[*i] = num;
}
{
unsigned s = S->size();
unsigned num = set_num;
++set_num;
used_var[num] = s;
free_var.erase(num);
if (s > 1)
cur_run.push_back(S);
else
done.push_back(S);
for (hash_set::const_iterator i = S->begin(); i != S->end(); ++i)
state_set_map[*i] = num;
}
else
{
delete S;
}
{
delete S;
}
// A bdd_states_map is a list of formulae (in a BDD form)
@ -366,132 +366,132 @@ namespace spot
bdd bdd_false_acceptance_condition = bdd_ithvar(num);
while (did_split)
{
did_split = false;
while (!cur_run.empty())
{
// Get a set to process.
hash_set* cur = cur_run.front();
cur_run.pop_front();
{
did_split = false;
while (!cur_run.empty())
{
// Get a set to process.
hash_set* cur = cur_run.front();
cur_run.pop_front();
trace
<< "processing " << format_hash_set(cur, ta_) << std::endl;
trace
<< "processing " << format_hash_set(cur, ta_) << std::endl;
hash_set::iterator hi;
bdd_states_map bdd_map;
for (hi = cur->begin(); hi != cur->end(); ++hi)
{
const state* src = *hi;
bdd f = bddfalse;
ta_succ_iterator* si = ta_->succ_iter(src);
trace << "+src: " << src << std::endl;
for (si->first(); !si->done(); si->next())
{
const state* dst = si->dst();
hash_map::const_iterator i = state_set_map.find(dst);
hash_set::iterator hi;
bdd_states_map bdd_map;
for (hi = cur->begin(); hi != cur->end(); ++hi)
{
const state* src = *hi;
bdd f = bddfalse;
ta_succ_iterator* si = ta_->succ_iter(src);
trace << "+src: " << src << std::endl;
for (si->first(); !si->done(); si->next())
{
const state* dst = si->dst();
hash_map::const_iterator i = state_set_map.find(dst);
assert(i != state_set_map.end());
auto curacc =
mark_to_bdd(si->acc());
f |= (bdd_ithvar(i->second)
& si->cond() & curacc);
trace
<< "+f: " << bdd_format_accset(ta_->get_dict(), f)
<< "\n -bdd_ithvar(i->second): "
<< bdd_format_accset(ta_->get_dict(),
bdd_ithvar(i->second))
<< "\n -si->cond(): "
<< bdd_format_accset(ta_->get_dict(),
si->cond())
<< "\n -current_acceptance_conditions: "
<< si->acc()
<< std::endl;
}
delete si;
assert(i != state_set_map.end());
auto curacc =
mark_to_bdd(si->acc());
f |= (bdd_ithvar(i->second)
& si->cond() & curacc);
trace
<< "+f: " << bdd_format_accset(ta_->get_dict(), f)
<< "\n -bdd_ithvar(i->second): "
<< bdd_format_accset(ta_->get_dict(),
bdd_ithvar(i->second))
<< "\n -si->cond(): "
<< bdd_format_accset(ta_->get_dict(),
si->cond())
<< "\n -current_acceptance_conditions: "
<< si->acc()
<< std::endl;
}
delete si;
// Have we already seen this formula ?
bdd_states_map::iterator bsi = bdd_map.find(f);
if (bsi == bdd_map.end())
{
// No, create a new set.
hash_set* new_set = new hash_set;
new_set->insert(src);
bdd_map[f] = new_set;
}
else
{
// Yes, add the current state to the set.
bsi->second->insert(src);
}
}
// Have we already seen this formula ?
bdd_states_map::iterator bsi = bdd_map.find(f);
if (bsi == bdd_map.end())
{
// No, create a new set.
hash_set* new_set = new hash_set;
new_set->insert(src);
bdd_map[f] = new_set;
}
else
{
// Yes, add the current state to the set.
bsi->second->insert(src);
}
}
bdd_states_map::iterator bsi = bdd_map.begin();
if (bdd_map.size() == 1)
{
// The set was not split.
trace
<< "set " << format_hash_set(bsi->second, ta_)
<< " was not split" << std::endl;
next_run.push_back(bsi->second);
}
else
{
did_split = true;
for (; bsi != bdd_map.end(); ++bsi)
{
hash_set* set = bsi->second;
// Free the number associated to these states.
unsigned num = state_set_map[*set->begin()];
assert(used_var.find(num) != used_var.end());
unsigned left = (used_var[num] -= set->size());
// Make sure LEFT does not become negative
// (hence bigger than SIZE when read as unsigned)
assert(left < size);
if (left == 0)
{
used_var.erase(num);
free_var.insert(num);
}
// Pick a free number
assert(!free_var.empty());
num = *free_var.begin();
free_var.erase(free_var.begin());
used_var[num] = set->size();
for (hash_set::iterator hit = set->begin();
hit != set->end(); ++hit)
state_set_map[*hit] = num;
// Trivial sets can't be splitted any further.
if (set->size() == 1)
{
trace
<< "set " << format_hash_set(set, ta_)
<< " is minimal" << std::endl;
done.push_back(set);
}
else
{
trace
<< "set " << format_hash_set(set, ta_)
<< " should be processed further" << std::endl;
next_run.push_back(set);
}
}
}
delete cur;
}
if (did_split)
trace
<< "splitting did occur during this pass." << std::endl;
bdd_states_map::iterator bsi = bdd_map.begin();
if (bdd_map.size() == 1)
{
// The set was not split.
trace
<< "set " << format_hash_set(bsi->second, ta_)
<< " was not split" << std::endl;
next_run.push_back(bsi->second);
}
else
{
did_split = true;
for (; bsi != bdd_map.end(); ++bsi)
{
hash_set* set = bsi->second;
// Free the number associated to these states.
unsigned num = state_set_map[*set->begin()];
assert(used_var.find(num) != used_var.end());
unsigned left = (used_var[num] -= set->size());
// Make sure LEFT does not become negative
// (hence bigger than SIZE when read as unsigned)
assert(left < size);
if (left == 0)
{
used_var.erase(num);
free_var.insert(num);
}
// Pick a free number
assert(!free_var.empty());
num = *free_var.begin();
free_var.erase(free_var.begin());
used_var[num] = set->size();
for (hash_set::iterator hit = set->begin();
hit != set->end(); ++hit)
state_set_map[*hit] = num;
// Trivial sets can't be splitted any further.
if (set->size() == 1)
{
trace
<< "set " << format_hash_set(set, ta_)
<< " is minimal" << std::endl;
done.push_back(set);
}
else
{
trace
<< "set " << format_hash_set(set, ta_)
<< " should be processed further" << std::endl;
next_run.push_back(set);
}
}
}
delete cur;
}
if (did_split)
trace
<< "splitting did occur during this pass." << std::endl;
std::swap(cur_run, next_run);
}
std::swap(cur_run, next_run);
}
done.splice(done.end(), cur_run);
#ifdef TRACE
trace << "Final partition: ";
for (partition_t::const_iterator i = done.begin(); i != done.end(); ++i)
trace << format_hash_set(*i, ta_) << ' ';
trace << format_hash_set(*i, ta_) << ' ';
trace << std::endl;
#endif

View file

@ -51,17 +51,17 @@ namespace spot
{
if (artificial_livelock_acc_state)
{
auto artificial_livelock_acc_state_added =
{
auto artificial_livelock_acc_state_added =
testing_automata->add_state(artificial_livelock_acc_state);
// unique artificial_livelock_acc_state
assert(artificial_livelock_acc_state_added
== artificial_livelock_acc_state);
(void)artificial_livelock_acc_state_added;
artificial_livelock_acc_state->set_livelock_accepting_state(true);
artificial_livelock_acc_state->free_transitions();
}
// unique artificial_livelock_acc_state
assert(artificial_livelock_acc_state_added
== artificial_livelock_acc_state);
(void)artificial_livelock_acc_state_added;
artificial_livelock_acc_state->set_livelock_accepting_state(true);
artificial_livelock_acc_state->free_transitions();
}
ta::states_set_t states_set = testing_automata->get_states_set();
ta::states_set_t::iterator it;
@ -70,86 +70,86 @@ namespace spot
new state_ta_explicit::transitions;
for (it = states_set.begin(); it != states_set.end(); ++it)
{
auto source = const_cast<state_ta_explicit*>
(static_cast<const state_ta_explicit*>(*it));
{
auto source = const_cast<state_ta_explicit*>
(static_cast<const state_ta_explicit*>(*it));
transitions_to_livelock_states->clear();
transitions_to_livelock_states->clear();
state_ta_explicit::transitions* trans = source->get_transitions();
state_ta_explicit::transitions::iterator it_trans;
state_ta_explicit::transitions* trans = source->get_transitions();
state_ta_explicit::transitions::iterator it_trans;
if (trans)
for (it_trans = trans->begin(); it_trans != trans->end();)
{
auto dest = const_cast<state_ta_explicit*>((*it_trans)->dest);
if (trans)
for (it_trans = trans->begin(); it_trans != trans->end();)
{
auto dest = const_cast<state_ta_explicit*>((*it_trans)->dest);
state_ta_explicit::transitions* dest_trans =
dest->get_transitions();
bool dest_trans_empty = !dest_trans || dest_trans->empty();
state_ta_explicit::transitions* dest_trans =
dest->get_transitions();
bool dest_trans_empty = !dest_trans || dest_trans->empty();
//select transitions where a destination is a livelock state
// which isn't a Buchi accepting state and has successors
if (dest->is_livelock_accepting_state()
&& (!dest->is_accepting_state()) && (!dest_trans_empty))
transitions_to_livelock_states->push_front(*it_trans);
//select transitions where a destination is a livelock state
// which isn't a Buchi accepting state and has successors
if (dest->is_livelock_accepting_state()
&& (!dest->is_accepting_state()) && (!dest_trans_empty))
transitions_to_livelock_states->push_front(*it_trans);
// optimization to have, after minimization, an unique
// livelock state which has no successors
if (dest->is_livelock_accepting_state() && (dest_trans_empty))
dest->set_accepting_state(false);
// optimization to have, after minimization, an unique
// livelock state which has no successors
if (dest->is_livelock_accepting_state() && (dest_trans_empty))
dest->set_accepting_state(false);
++it_trans;
}
++it_trans;
}
if (transitions_to_livelock_states)
{
state_ta_explicit::transitions::iterator it_trans;
if (transitions_to_livelock_states)
{
state_ta_explicit::transitions::iterator it_trans;
for (it_trans = transitions_to_livelock_states->begin();
it_trans != transitions_to_livelock_states->end();
++it_trans)
{
if (artificial_livelock_acc_state)
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
artificial_livelock_acc_state, true);
}
else
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
((*it_trans)->dest)->stuttering_reachable_livelock,
true);
}
}
}
}
for (it_trans = transitions_to_livelock_states->begin();
it_trans != transitions_to_livelock_states->end();
++it_trans)
{
if (artificial_livelock_acc_state)
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
artificial_livelock_acc_state, true);
}
else
{
testing_automata->create_transition
(source,
(*it_trans)->condition,
(*it_trans)->acceptance_conditions,
((*it_trans)->dest)->stuttering_reachable_livelock,
true);
}
}
}
}
delete transitions_to_livelock_states;
for (it = states_set.begin(); it != states_set.end(); ++it)
{
state_ta_explicit* state = static_cast<state_ta_explicit*> (*it);
state_ta_explicit::transitions* state_trans =
{
state_ta_explicit* state = static_cast<state_ta_explicit*> (*it);
state_ta_explicit::transitions* state_trans =
(state)->get_transitions();
bool state_trans_empty = !state_trans || state_trans->empty();
bool state_trans_empty = !state_trans || state_trans->empty();
if (state->is_livelock_accepting_state()
&& (!state->is_accepting_state()) && (!state_trans_empty))
state->set_livelock_accepting_state(false);
}
if (state->is_livelock_accepting_state()
&& (!state->is_accepting_state()) && (!state_trans_empty))
state->set_livelock_accepting_state(false);
}
}
static void
compute_livelock_acceptance_states(const ta_explicit_ptr& testing_aut,
bool single_pass_emptiness_check,
state_ta_explicit*
artificial_livelock_acc_state)
bool single_pass_emptiness_check,
state_ta_explicit*
artificial_livelock_acc_state)
{
// We use five main data in this algorithm:
// * sscc: a stack of strongly stuttering-connected components (SSCC)
@ -177,234 +177,234 @@ namespace spot
std::stack<const state*> init_set;
for (auto s: testing_aut->get_initial_states_set())
init_set.push(s);
init_set.push(s);
while (!init_set.empty())
{
// Setup depth-first search from initial states.
{
// Setup depth-first search from initial states.
{
auto init = down_cast<const state_ta_explicit*> (init_set.top());
init_set.pop();
{
auto init = down_cast<const state_ta_explicit*> (init_set.top());
init_set.pop();
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
if (!h.emplace(init, num + 1).second)
{
init->destroy();
continue;
}
sscc.push(++num);
arc.push(0U);
sscc.top().is_accepting
sscc.push(++num);
arc.push(0U);
sscc.top().is_accepting
= testing_aut->is_accepting_state(init);
twa_succ_iterator* iter = testing_aut->succ_iter(init);
iter->first();
todo.emplace(init, iter);
}
twa_succ_iterator* iter = testing_aut->succ_iter(init);
iter->first();
todo.emplace(init, iter);
}
while (!todo.empty())
{
auto curr = todo.top().first;
while (!todo.empty())
{
auto curr = todo.top().first;
auto i = h.find(curr);
// If we have reached a dead component, ignore it.
if (i != h.end() && i->second == -1)
{
todo.pop();
continue;
}
auto i = h.find(curr);
// If we have reached a dead component, ignore it.
if (i != h.end() && i->second == -1)
{
todo.pop();
continue;
}
// We are looking at the next successor in SUCC.
twa_succ_iterator* succ = todo.top().second;
// We are looking at the next successor in SUCC.
twa_succ_iterator* succ = todo.top().second;
// If there is no more successor, backtrack.
if (succ->done())
{
// We have explored all successors of state CURR.
// If there is no more successor, backtrack.
if (succ->done())
{
// We have explored all successors of state CURR.
// Backtrack TODO.
todo.pop();
// Backtrack TODO.
todo.pop();
// fill rem with any component removed,
assert(i != h.end());
sscc.rem().push_front(curr);
// fill rem with any component removed,
assert(i != h.end());
sscc.rem().push_front(curr);
// When backtracking the root of an SSCC, we must also
// remove that SSCC from the ROOT stacks. We must
// discard from H all reachable states from this SSCC.
assert(!sscc.empty());
if (sscc.top().index == i->second)
{
// removing states
bool is_livelock_accepting_sscc = (sscc.rem().size() > 1)
&& ((sscc.top().is_accepting) ||
(testing_aut->acc().
accepting(sscc.top().condition)));
trace << "*** sscc.size() = ***" << sscc.size() << '\n';
for (auto j: sscc.rem())
{
h[j] = -1;
// When backtracking the root of an SSCC, we must also
// remove that SSCC from the ROOT stacks. We must
// discard from H all reachable states from this SSCC.
assert(!sscc.empty());
if (sscc.top().index == i->second)
{
// removing states
bool is_livelock_accepting_sscc = (sscc.rem().size() > 1)
&& ((sscc.top().is_accepting) ||
(testing_aut->acc().
accepting(sscc.top().condition)));
trace << "*** sscc.size() = ***" << sscc.size() << '\n';
for (auto j: sscc.rem())
{
h[j] = -1;
if (is_livelock_accepting_sscc)
{
// if it is an accepting sscc add the state to
// G (=the livelock-accepting states set)
trace << "*** sscc.size() > 1: states: ***"
<< testing_aut->format_state(j)
<< '\n';
auto livelock_accepting_state =
const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(j));
if (is_livelock_accepting_sscc)
{
// if it is an accepting sscc add the state to
// G (=the livelock-accepting states set)
trace << "*** sscc.size() > 1: states: ***"
<< testing_aut->format_state(j)
<< '\n';
auto livelock_accepting_state =
const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(j));
livelock_accepting_state->
set_livelock_accepting_state(true);
livelock_accepting_state->
set_livelock_accepting_state(true);
if (single_pass_emptiness_check)
{
livelock_accepting_state
->set_accepting_state(true);
livelock_accepting_state
->stuttering_reachable_livelock
= livelock_accepting_state;
}
}
}
if (single_pass_emptiness_check)
{
livelock_accepting_state
->set_accepting_state(true);
livelock_accepting_state
->stuttering_reachable_livelock
= livelock_accepting_state;
}
}
}
assert(!arc.empty());
sscc.pop();
arc.pop();
}
assert(!arc.empty());
sscc.pop();
arc.pop();
}
// automata reduction
testing_aut->delete_stuttering_and_hole_successors(curr);
// automata reduction
testing_aut->delete_stuttering_and_hole_successors(curr);
delete succ;
// Do not delete CURR: it is a key in H.
continue;
}
delete succ;
// Do not delete CURR: it is a key in H.
continue;
}
// Fetch the values destination state we are interested in...
auto dest = succ->dst();
// Fetch the values destination state we are interested in...
auto dest = succ->dst();
auto acc_cond = succ->acc();
// ... and point the iterator to the next successor, for
// the next iteration.
succ->next();
// We do not need SUCC from now on.
auto acc_cond = succ->acc();
// ... and point the iterator to the next successor, for
// the next iteration.
succ->next();
// We do not need SUCC from now on.
// Are we going to a new state through a stuttering transition?
bool is_stuttering_transition =
testing_aut->get_state_condition(curr)
== testing_aut->get_state_condition(dest);
auto id = h.find(dest);
// Are we going to a new state through a stuttering transition?
bool is_stuttering_transition =
testing_aut->get_state_condition(curr)
== testing_aut->get_state_condition(dest);
auto id = h.find(dest);
// Is this a new state?
if (id == h.end())
{
if (!is_stuttering_transition)
{
init_set.push(dest);
dest->destroy();
continue;
}
// Is this a new state?
if (id == h.end())
{
if (!is_stuttering_transition)
{
init_set.push(dest);
dest->destroy();
continue;
}
// Number it, stack it, and register its successors
// for later processing.
h[dest] = ++num;
sscc.push(num);
arc.push(acc_cond);
sscc.top().is_accepting =
testing_aut->is_accepting_state(dest);
// Number it, stack it, and register its successors
// for later processing.
h[dest] = ++num;
sscc.push(num);
arc.push(acc_cond);
sscc.top().is_accepting =
testing_aut->is_accepting_state(dest);
twa_succ_iterator* iter = testing_aut->succ_iter(dest);
iter->first();
todo.emplace(dest, iter);
continue;
}
dest->destroy();
twa_succ_iterator* iter = testing_aut->succ_iter(dest);
iter->first();
todo.emplace(dest, iter);
continue;
}
dest->destroy();
// If we have reached a dead component, ignore it.
if (id->second == -1)
continue;
// If we have reached a dead component, ignore it.
if (id->second == -1)
continue;
trace << "***compute_livelock_acceptance_states: CYCLE***\n";
trace << "***compute_livelock_acceptance_states: CYCLE***\n";
if (!curr->compare(id->first))
{
auto self_loop_state = const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(curr));
assert(self_loop_state);
if (!curr->compare(id->first))
{
auto self_loop_state = const_cast<state_ta_explicit*>
(down_cast<const state_ta_explicit*>(curr));
assert(self_loop_state);
if (testing_aut->is_accepting_state(self_loop_state)
|| (testing_aut->acc().accepting(acc_cond)))
{
self_loop_state->set_livelock_accepting_state(true);
if (single_pass_emptiness_check)
{
self_loop_state->set_accepting_state(true);
self_loop_state->stuttering_reachable_livelock
= self_loop_state;
}
}
if (testing_aut->is_accepting_state(self_loop_state)
|| (testing_aut->acc().accepting(acc_cond)))
{
self_loop_state->set_livelock_accepting_state(true);
if (single_pass_emptiness_check)
{
self_loop_state->set_accepting_state(true);
self_loop_state->stuttering_reachable_livelock
= self_loop_state;
}
}
trace
<< "***compute_livelock_acceptance_states: CYCLE: "
<< "self_loop_state***\n";
}
trace
<< "***compute_livelock_acceptance_states: CYCLE: "
<< "self_loop_state***\n";
}
// Now this is the most interesting case. We have reached a
// state S1 which is already part of a non-dead SSCC. Any such
// non-dead SSCC has necessarily been crossed by our path to
// this state: there is a state S2 in our path which belongs
// to this SSCC too. We are going to merge all states between
// this S1 and S2 into this SSCC.
//
// This merge is easy to do because the order of the SSCC in
// ROOT is ascending: we just have to merge all SSCCs from the
// top of ROOT that have an index greater to the one of
// the SSCC of S2 (called the "threshold").
int threshold = id->second;
std::list<const state*> rem;
bool acc = false;
// Now this is the most interesting case. We have reached a
// state S1 which is already part of a non-dead SSCC. Any such
// non-dead SSCC has necessarily been crossed by our path to
// this state: there is a state S2 in our path which belongs
// to this SSCC too. We are going to merge all states between
// this S1 and S2 into this SSCC.
//
// This merge is easy to do because the order of the SSCC in
// ROOT is ascending: we just have to merge all SSCCs from the
// top of ROOT that have an index greater to the one of
// the SSCC of S2 (called the "threshold").
int threshold = id->second;
std::list<const state*> rem;
bool acc = false;
while (threshold < sscc.top().index)
{
assert(!sscc.empty());
assert(!arc.empty());
acc |= sscc.top().is_accepting;
acc_cond |= sscc.top().condition;
acc_cond |= arc.top();
rem.splice(rem.end(), sscc.rem());
sscc.pop();
arc.pop();
}
while (threshold < sscc.top().index)
{
assert(!sscc.empty());
assert(!arc.empty());
acc |= sscc.top().is_accepting;
acc_cond |= sscc.top().condition;
acc_cond |= arc.top();
rem.splice(rem.end(), sscc.rem());
sscc.pop();
arc.pop();
}
// Note that we do not always have
// threshold == sscc.top().index
// after this loop, the SSCC whose index is threshold might have
// been merged with a lower SSCC.
// Note that we do not always have
// threshold == sscc.top().index
// after this loop, the SSCC whose index is threshold might have
// been merged with a lower SSCC.
// Accumulate all acceptance conditions into the merged SSCC.
sscc.top().is_accepting |= acc;
sscc.top().condition |= acc_cond;
// Accumulate all acceptance conditions into the merged SSCC.
sscc.top().is_accepting |= acc;
sscc.top().condition |= acc_cond;
sscc.rem().splice(sscc.rem().end(), rem);
sscc.rem().splice(sscc.rem().end(), rem);
}
}
}
}
if (artificial_livelock_acc_state || single_pass_emptiness_check)
transform_to_single_pass_automaton(testing_aut,
artificial_livelock_acc_state);
transform_to_single_pass_automaton(testing_aut,
artificial_livelock_acc_state);
}
ta_explicit_ptr
build_ta(const ta_explicit_ptr& ta, bdd atomic_propositions_set_,
bool degeneralized,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
bool degeneralized,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
{
std::stack<state_ta_explicit*> todo;
@ -414,140 +414,140 @@ namespace spot
auto tgba_init_state = tgba_->get_init_state();
bdd tgba_condition = [&]()
{
bdd cond = bddfalse;
for (auto i: tgba_->succ(tgba_init_state))
cond |= i->cond();
return cond;
}();
{
bdd cond = bddfalse;
for (auto i: tgba_->succ(tgba_init_state))
cond |= i->cond();
return cond;
}();
bool is_acc = false;
if (degeneralized)
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_init_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_init_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
bdd satone_tgba_condition;
while ((satone_tgba_condition = bdd_satoneset(tgba_condition,
atomic_propositions_set_,
bddtrue)) != bddfalse)
{
tgba_condition -= satone_tgba_condition;
state_ta_explicit* init_state = new
state_ta_explicit(tgba_init_state->clone(),
satone_tgba_condition, true, is_acc);
state_ta_explicit* s = ta->add_state(init_state);
assert(s == init_state);
ta->add_to_initial_states_set(s);
atomic_propositions_set_,
bddtrue)) != bddfalse)
{
tgba_condition -= satone_tgba_condition;
state_ta_explicit* init_state = new
state_ta_explicit(tgba_init_state->clone(),
satone_tgba_condition, true, is_acc);
state_ta_explicit* s = ta->add_state(init_state);
assert(s == init_state);
ta->add_to_initial_states_set(s);
todo.push(init_state);
}
todo.push(init_state);
}
tgba_init_state->destroy();
while (!todo.empty())
{
state_ta_explicit* source = todo.top();
todo.pop();
{
state_ta_explicit* source = todo.top();
todo.pop();
twa_succ_iterator* twa_succ_it =
tgba_->succ_iter(source->get_tgba_state());
for (twa_succ_it->first(); !twa_succ_it->done();
twa_succ_it->next())
{
const state* tgba_state = twa_succ_it->dst();
bdd tgba_condition = twa_succ_it->cond();
acc_cond::mark_t tgba_acceptance_conditions =
twa_succ_iterator* twa_succ_it =
tgba_->succ_iter(source->get_tgba_state());
for (twa_succ_it->first(); !twa_succ_it->done();
twa_succ_it->next())
{
const state* tgba_state = twa_succ_it->dst();
bdd tgba_condition = twa_succ_it->cond();
acc_cond::mark_t tgba_acceptance_conditions =
twa_succ_it->acc();
bdd satone_tgba_condition;
while ((satone_tgba_condition =
bdd_satoneset(tgba_condition,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
tgba_condition -= satone_tgba_condition;
bdd satone_tgba_condition;
while ((satone_tgba_condition =
bdd_satoneset(tgba_condition,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
tgba_condition -= satone_tgba_condition;
bdd all_props = bddtrue;
bdd dest_condition;
bdd all_props = bddtrue;
bdd dest_condition;
bool is_acc = false;
if (degeneralized)
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
bool is_acc = false;
if (degeneralized)
{
twa_succ_iterator* it = tgba_->succ_iter(tgba_state);
it->first();
if (!it->done())
is_acc = it->acc() != 0U;
delete it;
}
if (satone_tgba_condition == source->get_tgba_condition())
while ((dest_condition =
bdd_satoneset(all_props,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
all_props -= dest_condition;
state_ta_explicit* new_dest =
new state_ta_explicit(tgba_state->clone(),
dest_condition, false, is_acc);
state_ta_explicit* dest = ta->add_state(new_dest);
if (satone_tgba_condition == source->get_tgba_condition())
while ((dest_condition =
bdd_satoneset(all_props,
atomic_propositions_set_, bddtrue))
!= bddfalse)
{
all_props -= dest_condition;
state_ta_explicit* new_dest =
new state_ta_explicit(tgba_state->clone(),
dest_condition, false, is_acc);
state_ta_explicit* dest = ta->add_state(new_dest);
if (dest != new_dest)
{
// the state dest already exists in the automaton
new_dest->get_tgba_state()->destroy();
delete new_dest;
}
else
{
todo.push(dest);
}
if (dest != new_dest)
{
// the state dest already exists in the automaton
new_dest->get_tgba_state()->destroy();
delete new_dest;
}
else
{
todo.push(dest);
}
bdd cs = bdd_setxor(source->get_tgba_condition(),
dest->get_tgba_condition());
ta->create_transition(source, cs,
tgba_acceptance_conditions, dest);
}
}
tgba_state->destroy();
}
delete twa_succ_it;
}
bdd cs = bdd_setxor(source->get_tgba_condition(),
dest->get_tgba_condition());
ta->create_transition(source, cs,
tgba_acceptance_conditions, dest);
}
}
tgba_state->destroy();
}
delete twa_succ_it;
}
if (no_livelock)
return ta;
return ta;
state_ta_explicit* artificial_livelock_acc_state = nullptr;
trace << "*** build_ta: artificial_livelock_acc_state_mode = ***"
<< artificial_livelock_state_mode << std::endl;
<< artificial_livelock_state_mode << std::endl;
if (artificial_livelock_state_mode)
{
single_pass_emptiness_check = true;
artificial_livelock_acc_state =
new state_ta_explicit(ta->get_tgba()->get_init_state(), bddtrue,
false, false, true, nullptr);
trace
<< "*** build_ta: artificial_livelock_acc_state = ***"
<< artificial_livelock_acc_state << std::endl;
}
{
single_pass_emptiness_check = true;
artificial_livelock_acc_state =
new state_ta_explicit(ta->get_tgba()->get_init_state(), bddtrue,
false, false, true, nullptr);
trace
<< "*** build_ta: artificial_livelock_acc_state = ***"
<< artificial_livelock_acc_state << std::endl;
}
compute_livelock_acceptance_states(ta, single_pass_emptiness_check,
artificial_livelock_acc_state);
artificial_livelock_acc_state);
return ta;
}
}
ta_explicit_ptr
tgba_to_ta(const const_twa_ptr& tgba_, bdd atomic_propositions_set_,
bool degeneralized, bool artificial_initial_state_mode,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
bool degeneralized, bool artificial_initial_state_mode,
bool single_pass_emptiness_check,
bool artificial_livelock_state_mode,
bool no_livelock)
{
ta_explicit_ptr ta;
@ -555,10 +555,10 @@ namespace spot
if (artificial_initial_state_mode)
{
state_ta_explicit* artificial_init_state =
new state_ta_explicit(tgba_init_state->clone(), bddfalse, true);
new state_ta_explicit(tgba_init_state->clone(), bddfalse, true);
ta = make_ta_explicit(tgba_, tgba_->acc().num_sets(),
artificial_init_state);
artificial_init_state);
}
else
{
@ -568,8 +568,8 @@ namespace spot
// build ta automaton
build_ta(ta, atomic_propositions_set_, degeneralized,
single_pass_emptiness_check, artificial_livelock_state_mode,
no_livelock);
single_pass_emptiness_check, artificial_livelock_state_mode,
no_livelock);
// (degeneralized=true) => TA
if (degeneralized)
@ -589,8 +589,8 @@ namespace spot
state_ta_explicit::transitions::iterator it_trans;
for (it_trans = trans->begin(); it_trans != trans->end();
++it_trans)
(*it_trans)->acceptance_conditions = ta->acc().all_sets();
++it_trans)
(*it_trans)->acceptance_conditions = ta->acc().all_sets();
state->set_accepting_state(false);
}
@ -604,11 +604,11 @@ namespace spot
{
auto tgba_init_state = tgba_->get_init_state();
auto artificial_init_state = new state_ta_explicit(tgba_init_state->clone(),
bddfalse, true);
bddfalse, true);
tgba_init_state->destroy();
auto tgta = make_tgta_explicit(tgba_, tgba_->acc().num_sets(),
artificial_init_state);
artificial_init_state);
// build a Generalized TA automaton involving a single_pass_emptiness_check
// (without an artificial livelock state):
@ -625,14 +625,14 @@ namespace spot
initial_states_iter->first();
if (initial_states_iter->done())
{
delete initial_states_iter;
return tgta;
delete initial_states_iter;
return tgta;
}
bdd first_state_condition = initial_states_iter->cond();
delete initial_states_iter;
bdd bdd_stutering_transition = bdd_setxor(first_state_condition,
first_state_condition);
first_state_condition);
for (it = states_set.begin(); it != states_set.end(); ++it)
{
@ -645,13 +645,13 @@ namespace spot
if (trans_empty || state->is_accepting_state())
{
ta->create_transition(state, bdd_stutering_transition,
ta->acc().all_sets(), state);
ta->acc().all_sets(), state);
}
}
if (state->compare(ta->get_artificial_initial_state()))
ta->create_transition(state, bdd_stutering_transition,
0U, state);
0U, state);
state->set_livelock_accepting_state(false);
state->set_accepting_state(false);

View file

@ -83,11 +83,11 @@ namespace spot
/// TGBA \a tgba_to_convert.
SPOT_API ta_explicit_ptr
tgba_to_ta(const const_twa_ptr& tgba_to_convert, bdd atomic_propositions_set,
bool degeneralized = true,
bool artificial_initial_state_mode = true,
bool single_pass_emptiness_check = false,
bool artificial_livelock_state_mode = false,
bool no_livelock = false);
bool degeneralized = true,
bool artificial_initial_state_mode = true,
bool single_pass_emptiness_check = false,
bool artificial_livelock_state_mode = false,
bool no_livelock = false);
/// \ingroup tgba_ta
/// \brief Build a spot::tgta_explicit* (TGTA) from an LTL formula.
@ -100,5 +100,5 @@ namespace spot
/// language as the TGBA \a tgba_to_convert.
SPOT_API tgta_explicit_ptr
tgba_to_tgta(const const_twa_ptr& tgba_to_convert,
bdd atomic_propositions_set);
bdd atomic_propositions_set);
}

View file

@ -31,9 +31,9 @@ namespace spot
atomic_prop_set res;
for (unsigned i = 0; i < n; ++i)
{
std::ostringstream p;
p << 'p' << i;
res.insert(formula::ap(p.str()));
std::ostringstream p;
p << 'p' << i;
res.insert(formula::ap(p.str()));
}
return res;
}
@ -44,11 +44,11 @@ namespace spot
if (!s)
s = new atomic_prop_set;
f.traverse([&](const formula& f)
{
if (f.is(op::ap))
s->insert(f);
return false;
});
{
if (f.is(op::ap))
s->insert(f);
return false;
});
return s;
}

View file

@ -65,7 +65,7 @@ namespace spot
// Check whether L(l) is a subset of L(g).
bool
language_containment_checker::contained(formula l,
formula g)
formula g)
{
if (l == g)
return true;
@ -77,7 +77,7 @@ namespace spot
// Check whether L(!l) is a subset of L(g).
bool
language_containment_checker::neg_contained(formula l,
formula g)
formula g)
{
if (l == g)
return false;
@ -92,7 +92,7 @@ namespace spot
// Check whether L(l) is a subset of L(!g).
bool
language_containment_checker::contained_neg(formula l,
formula g)
formula g)
{
if (l == g)
return false;
@ -122,7 +122,7 @@ namespace spot
return &i->second;
auto e = ltl_to_tgba_fm(f, dict_, exprop_, symb_merge_,
branching_postponement_, fair_loop_approx_);
branching_postponement_, fair_loop_approx_);
record_& r = translated_[f];
r.translation = e;
return &r;

View file

@ -43,9 +43,9 @@ namespace spot
/// This class uses spot::ltl_to_tgba_fm to translate LTL
/// formulae. See that function for the meaning of these options.
language_containment_checker(const bdd_dict_ptr& dict, bool exprop,
bool symb_merge,
bool branching_postponement,
bool fair_loop_approx);
bool symb_merge,
bool branching_postponement,
bool fair_loop_approx);
~language_containment_checker();

View file

@ -37,94 +37,94 @@ namespace spot
std::ostringstream* sinks_;
dot_printer(std::ostream& os, formula f)
: os_(os), sinks_(new std::ostringstream)
{
os_ << "digraph G {\n";
rec(f);
os_ << " subgraph atoms {\n rank=sink;\n"
<< sinks_->str() << " }\n}\n";
}
: os_(os), sinks_(new std::ostringstream)
{
os_ << "digraph G {\n";
rec(f);
os_ << " subgraph atoms {\n rank=sink;\n"
<< sinks_->str() << " }\n}\n";
}
~dot_printer()
{
delete sinks_;
}
{
delete sinks_;
}
int rec(formula f)
{
auto i = node_.emplace(f, node_.size());
int src = i.first->second;
if (!i.second)
return src;
auto i = node_.emplace(f, node_.size());
int src = i.first->second;
if (!i.second)
return src;
op o = f.kind();
std::string str = (o == op::ap) ? f.ap_name() : f.kindstr();
op o = f.kind();
std::string str = (o == op::ap) ? f.ap_name() : f.kindstr();
if (o == op::ap || f.is_constant())
*sinks_ << " " << src << " [label=\""
<< str << "\", shape=box];\n";
else
os_ << " " << src << " [label=\"" << str << "\"];\n";
if (o == op::ap || f.is_constant())
*sinks_ << " " << src << " [label=\""
<< str << "\", shape=box];\n";
else
os_ << " " << src << " [label=\"" << str << "\"];\n";
int childnum = 0;
switch (o)
{
case op::ff:
case op::tt:
case op::eword:
case op::ap:
case op::Not:
case op::X:
case op::F:
case op::G:
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Star:
case op::FStar:
childnum = 0; // No number for children
break;
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
childnum = -2; // L and R markers
break;
case op::Concat:
case op::Fusion:
childnum = 1; // Numbered children
break;
}
int childnum = 0;
switch (o)
{
case op::ff:
case op::tt:
case op::eword:
case op::ap:
case op::Not:
case op::X:
case op::F:
case op::G:
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Star:
case op::FStar:
childnum = 0; // No number for children
break;
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
childnum = -2; // L and R markers
break;
case op::Concat:
case op::Fusion:
childnum = 1; // Numbered children
break;
}
for (auto c: f)
{
// Do not merge the next two lines, as there is no
// guarantee that rec will be called before we start
// printing the transition.
int dst = rec(c);
os_ << " " << src << " -> " << dst;
if (childnum > 0)
os_ << " [taillabel=\"" << childnum << "\"]";
if (childnum == -2)
os_ << " [taillabel=\"L\"]";
else if (childnum == -1)
os_ << " [taillabel=\"R\"]";
os_ << ";\n";
++childnum;
}
for (auto c: f)
{
// Do not merge the next two lines, as there is no
// guarantee that rec will be called before we start
// printing the transition.
int dst = rec(c);
os_ << " " << src << " -> " << dst;
if (childnum > 0)
os_ << " [taillabel=\"" << childnum << "\"]";
if (childnum == -2)
os_ << " [taillabel=\"L\"]";
else if (childnum == -1)
os_ << " [taillabel=\"R\"]";
os_ << ";\n";
++childnum;
}
return src;
return src;
}
};
}

View file

@ -33,66 +33,66 @@ namespace spot
std::vector<formula> group;
auto start = arg;
while (*start)
{
while (*start == ' ' || *start == '\t')
++start;
if (!*start)
break;
if (*start == ',')
{
std::string s = "unexpected ',' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*start == '"')
{
++start;
auto end = start;
while (*end && *end != '"')
{
if (*end == '\\')
++end;
++end;
}
if (!*end)
{
std::string s = "missing closing '\"' in ";
s += arg;
throw std::invalid_argument(s);
}
std::string ap(start, end - start);
group.emplace_back(formula::ap(ap));
do
++end;
while (*end == ' ' || *end == '\t');
if (*end && *end != ',')
{
std::string s = "unexpected character '";
s += *end;
s += "' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*end == ',')
++end;
start = end;
}
else
{
auto end = start;
while (*end && *end != ',')
++end;
auto rend = end;
while (rend > start && (rend[-1] == ' ' || rend[-1] == '\t'))
--rend;
std::string ap(start, rend - start);
group.emplace_back(formula::ap(ap));
if (*end == ',')
start = end + 1;
else
break;
}
}
{
while (*start == ' ' || *start == '\t')
++start;
if (!*start)
break;
if (*start == ',')
{
std::string s = "unexpected ',' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*start == '"')
{
++start;
auto end = start;
while (*end && *end != '"')
{
if (*end == '\\')
++end;
++end;
}
if (!*end)
{
std::string s = "missing closing '\"' in ";
s += arg;
throw std::invalid_argument(s);
}
std::string ap(start, end - start);
group.emplace_back(formula::ap(ap));
do
++end;
while (*end == ' ' || *end == '\t');
if (*end && *end != ',')
{
std::string s = "unexpected character '";
s += *end;
s += "' in ";
s += arg;
throw std::invalid_argument(s);
}
if (*end == ',')
++end;
start = end;
}
else
{
auto end = start;
while (*end && *end != ',')
++end;
auto rend = end;
while (rend > start && (rend[-1] == ' ' || rend[-1] == '\t'))
--rend;
std::string ap(start, rend - start);
group.emplace_back(formula::ap(ap));
if (*end == ',')
start = end + 1;
else
break;
}
}
return group;
}
}
@ -126,16 +126,16 @@ namespace spot
for (auto& g: groups)
{
group.clear();
group.clear();
for (auto ap: g)
if (s->find(ap) != s->end())
group.push_back(ap);
for (auto ap: g)
if (s->find(ap) != s->end())
group.push_back(ap);
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
v.push_back(nand(group[j], group[k]));
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
v.push_back(nand(group[j], group[k]));
};
delete s;
@ -143,15 +143,15 @@ namespace spot
}
twa_graph_ptr exclusive_ap::constrain(const_twa_graph_ptr aut,
bool simplify_guards) const
bool simplify_guards) const
{
// Compute the support of the automaton.
bdd support = bddtrue;
{
std::set<int> bdd_seen;
for (auto& t: aut->edges())
if (bdd_seen.insert(t.cond.id()).second)
support &= bdd_support(t.cond);
if (bdd_seen.insert(t.cond.id()).second)
support &= bdd_support(t.cond);
}
bdd restrict = bddtrue;
@ -160,19 +160,19 @@ namespace spot
std::vector<bdd> group;
for (auto& g: groups)
{
group.clear();
group.clear();
for (auto ap: g)
{
int v = d->has_registered_proposition(ap, aut);
if (v >= 0)
group.push_back(bdd_nithvar(v));
}
for (auto ap: g)
{
int v = d->has_registered_proposition(ap, aut);
if (v >= 0)
group.push_back(bdd_nithvar(v));
}
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
restrict &= group[j] | group[k];
unsigned s = group.size();
for (unsigned j = 0; j < s; ++j)
for (unsigned k = j + 1; k < s; ++k)
restrict &= group[j] | group[k];
}
twa_graph_ptr res = make_twa_graph(aut->get_dict());
@ -181,26 +181,26 @@ namespace spot
res->copy_acceptance_of(aut);
if (simplify_guards)
{
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
minato_isop isop(cond & restrict,
cond | !restrict,
true);
bdd res = bddfalse;
bdd cube = bddfalse;
while ((cube = isop.next()) != bddfalse)
res |= cube;
cond = res;
});
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
minato_isop isop(cond & restrict,
cond | !restrict,
true);
bdd res = bddfalse;
bdd cube = bddfalse;
while ((cube = isop.next()) != bddfalse)
res |= cube;
cond = res;
});
}
else
{
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
cond &= restrict;
});
transform_accessible(aut, res, [&](unsigned, bdd& cond,
acc_cond::mark_t&, unsigned)
{
cond &= restrict;
});
}
return res;
}

View file

@ -41,6 +41,6 @@ namespace spot
formula constrain(formula f) const;
twa_graph_ptr constrain(const_twa_graph_ptr aut,
bool simplify_guards = false) const;
bool simplify_guards = false) const;
};
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -30,14 +30,14 @@ namespace spot
{
int len = 0;
f.traverse([&len](const formula& x)
{
auto s = x.size();
if (s > 1)
len += s - 1;
else
++len;
return false;
});
{
auto s = x.size();
if (s > 1)
len += s - 1;
else
++len;
return false;
});
return len;
}
@ -46,31 +46,31 @@ namespace spot
{
int len = 0;
f.traverse([&len](const formula& x)
{
if (x.is_boolean())
{
++len;
return true;
}
auto s = x.size();
if (s > 2)
{
int b = 0;
for (const auto& y: x)
if (y.is_boolean())
++b;
len += s - b * 2 + 1;
}
else if (s > 1)
{
len += s - 1;
}
else
{
++len;
}
return false;
});
{
if (x.is_boolean())
{
++len;
return true;
}
auto s = x.size();
if (s > 2)
{
int b = 0;
for (const auto& y: x)
if (y.is_boolean())
++b;
len += s - b * 2 + 1;
}
else if (s > 1)
{
len += s - 1;
}
else
{
++len;
}
return false;
});
return len;
}

View file

@ -58,25 +58,25 @@ namespace spot
case op::UConcat:
case op::Concat:
case op::Fusion:
res = f;
break;
res = f;
break;
case op::NegClosure:
res = formula::NegClosureMarked(f[0]);
break;
res = formula::NegClosureMarked(f[0]);
break;
case op::EConcat:
res = formula::EConcatMarked(f[0], f[1]);
break;
res = formula::EConcatMarked(f[0], f[1]);
break;
case op::Or:
case op::And:
res = f.map([this](formula f)
{
return this->mark_concat_ops(f);
});
break;
res = f.map([this](formula f)
{
return this->mark_concat_ops(f);
});
break;
case op::Xor:
case op::Implies:
case op::Equiv:
SPOT_UNIMPLEMENTED();
SPOT_UNIMPLEMENTED();
}
markops_[f] = res;
@ -95,7 +95,7 @@ namespace spot
auto recurse = [this](formula f)
{
return this->simplify_mark(f);
return this->simplify_mark(f);
};
formula res;
@ -119,58 +119,58 @@ namespace spot
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
res = f;
break;
res = f;
break;
case op::Or:
res = f.map(recurse);
break;
res = f.map(recurse);
break;
case op::And:
{
std::set<std::pair<formula, formula>> empairs;
std::set<formula> nmset;
std::vector<formula> elist;
std::vector<formula> nlist;
std::vector<formula> v;
{
std::set<std::pair<formula, formula>> empairs;
std::set<formula> nmset;
std::vector<formula> elist;
std::vector<formula> nlist;
std::vector<formula> v;
for (auto c: f)
{
if (c.is(op::EConcatMarked))
{
empairs.emplace(c[0], c[1]);
v.push_back(c.map(recurse));
}
else if (c.is(op::EConcat))
{
elist.push_back(c);
}
else if (c.is(op::NegClosureMarked))
{
nmset.insert(c[0]);
v.push_back(c.map(recurse));
}
else if (c.is(op::NegClosure))
{
nlist.push_back(c);
}
else
{
v.push_back(c);
}
}
// Keep only the non-marked EConcat for which we
// have not seen a similar EConcatMarked.
for (auto e: elist)
if (empairs.find(std::make_pair(e[0], e[1]))
== empairs.end())
v.push_back(e);
// Keep only the non-marked NegClosure for which we
// have not seen a similar NegClosureMarked.
for (auto n: nlist)
if (nmset.find(n[0]) == nmset.end())
v.push_back(n);
res = formula::And(v);
}
break;
for (auto c: f)
{
if (c.is(op::EConcatMarked))
{
empairs.emplace(c[0], c[1]);
v.push_back(c.map(recurse));
}
else if (c.is(op::EConcat))
{
elist.push_back(c);
}
else if (c.is(op::NegClosureMarked))
{
nmset.insert(c[0]);
v.push_back(c.map(recurse));
}
else if (c.is(op::NegClosure))
{
nlist.push_back(c);
}
else
{
v.push_back(c);
}
}
// Keep only the non-marked EConcat for which we
// have not seen a similar EConcatMarked.
for (auto e: elist)
if (empairs.find(std::make_pair(e[0], e[1]))
== empairs.end())
v.push_back(e);
// Keep only the non-marked NegClosure for which we
// have not seen a similar NegClosureMarked.
for (auto n: nlist)
if (nmset.find(n[0]) == nmset.end())
v.push_back(n);
res = formula::And(v);
}
break;
case op::Xor:
case op::Implies:
case op::Equiv:
@ -181,7 +181,7 @@ namespace spot
case op::FStar:
case op::Concat:
case op::Fusion:
SPOT_UNIMPLEMENTED();
SPOT_UNIMPLEMENTED();
}
simpmark_[f] = res;

View file

@ -37,12 +37,12 @@ namespace spot
formula substitute_ap(formula f, formula ap_src, formula ap_dst)
{
return f.map([&](formula f)
{
if (f == ap_src)
return ap_dst;
else
return substitute_ap(f, ap_src, ap_dst);
});
{
if (f == ap_src)
return ap_dst;
else
return substitute_ap(f, ap_src, ap_dst);
});
}
typedef std::vector<formula> vec;
@ -58,229 +58,229 @@ namespace spot
formula mutate(formula f)
{
auto recurse = [this](formula f)
{
return this->mutate(f);
};
auto recurse = [this](formula f)
{
return this->mutate(f);
};
switch (f.kind())
{
case op::ff:
case op::tt:
case op::eword:
return f;
case op::ap:
if (opts_ & Mut_Ap2Const)
{
if (mutation_counter_-- == 0)
return formula::tt();
if (mutation_counter_-- == 0)
return formula::ff();
}
return f;
case op::Not:
case op::X:
case op::F:
case op::G:
if ((opts_ & Mut_Remove_Ops)
&& mutation_counter_-- == 0)
return f[0];
// fall through
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Concat:
case op::Fusion:
{
int mos = f.size();
if (opts_ & Mut_Remove_Multop_Operands)
{
for (int i = 0; i < mos; ++i)
if (mutation_counter_-- == 0)
return f.all_but(i);
}
switch (f.kind())
{
case op::ff:
case op::tt:
case op::eword:
return f;
case op::ap:
if (opts_ & Mut_Ap2Const)
{
if (mutation_counter_-- == 0)
return formula::tt();
if (mutation_counter_-- == 0)
return formula::ff();
}
return f;
case op::Not:
case op::X:
case op::F:
case op::G:
if ((opts_ & Mut_Remove_Ops)
&& mutation_counter_-- == 0)
return f[0];
// fall through
case op::Closure:
case op::NegClosure:
case op::NegClosureMarked:
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
case op::Or:
case op::OrRat:
case op::And:
case op::AndRat:
case op::AndNLM:
case op::Concat:
case op::Fusion:
{
int mos = f.size();
if (opts_ & Mut_Remove_Multop_Operands)
{
for (int i = 0; i < mos; ++i)
if (mutation_counter_-- == 0)
return f.all_but(i);
}
if (opts_ & Mut_Split_Ops && f.is(op::AndNLM))
{
if (mutation_counter_ >= 0
&& mutation_counter_ < 2 * (mos - 1))
{
vec v1;
vec v2;
v1.push_back(f[0]);
bool reverse = false;
int i = 1;
while (i < mos)
{
if (mutation_counter_-- == 0)
break;
if (mutation_counter_-- == 0)
{
reverse = true;
break;
}
v1.push_back(f[i++]);
}
for (; i < mos; ++i)
v2.push_back(f[i]);
formula first = AndNLM_(v1);
formula second = AndNLM_(v2);
formula ost = formula::one_star();
if (!reverse)
return AndRat_(Concat_(first, ost), second);
else
return AndRat_(Concat_(second, ost), first);
}
else
{
mutation_counter_ -= 2 * (mos - 1);
}
}
if (opts_ & Mut_Split_Ops && f.is(op::AndNLM))
{
if (mutation_counter_ >= 0
&& mutation_counter_ < 2 * (mos - 1))
{
vec v1;
vec v2;
v1.push_back(f[0]);
bool reverse = false;
int i = 1;
while (i < mos)
{
if (mutation_counter_-- == 0)
break;
if (mutation_counter_-- == 0)
{
reverse = true;
break;
}
v1.push_back(f[i++]);
}
for (; i < mos; ++i)
v2.push_back(f[i]);
formula first = AndNLM_(v1);
formula second = AndNLM_(v2);
formula ost = formula::one_star();
if (!reverse)
return AndRat_(Concat_(first, ost), second);
else
return AndRat_(Concat_(second, ost), first);
}
else
{
mutation_counter_ -= 2 * (mos - 1);
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
{
formula first = f[0];
formula second = f[1];
op o = f.kind();
bool left_is_sere = o == op::EConcat
|| o == op::EConcatMarked
|| o == op::UConcat;
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Xor:
case op::Implies:
case op::Equiv:
case op::U:
case op::R:
case op::W:
case op::M:
case op::EConcat:
case op::EConcatMarked:
case op::UConcat:
{
formula first = f[0];
formula second = f[1];
op o = f.kind();
bool left_is_sere = o == op::EConcat
|| o == op::EConcatMarked
|| o == op::UConcat;
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
{
if (!left_is_sere)
return first;
else if (o == op::UConcat)
return formula::NegClosure(first);
else // EConcat or EConcatMarked
return formula::Closure(first);
}
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return second;
if (opts_ & Mut_Rewrite_Ops)
{
switch (o)
{
case op::U:
if (mutation_counter_-- == 0)
return formula::W(first, second);
break;
case op::M:
if (mutation_counter_-- == 0)
return formula::R(first, second);
if (mutation_counter_-- == 0)
return formula::U(second, first);
break;
case op::R:
if (mutation_counter_-- == 0)
return formula::W(second, first);
break;
default:
break;
}
}
if (opts_ & Mut_Split_Ops)
{
switch (o)
{
case op::Equiv:
if (mutation_counter_-- == 0)
return formula::Implies(first, second);
if (mutation_counter_-- == 0)
return formula::Implies(second, first);
if (mutation_counter_-- == 0)
return formula::And({first, second});
if (mutation_counter_-- == 0)
{
// Negate the two argument sequentially (in this
// case right before left, otherwise different
// compilers will make different choices.
auto right = formula::Not(second);
return formula::And({formula::Not(first), right});
}
break;
case op::Xor:
if (mutation_counter_-- == 0)
return formula::And({first, formula::Not(second)});
if (mutation_counter_-- == 0)
return formula::And({formula::Not(first), second});
break;
default:
break;
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Star:
case op::FStar:
{
formula c = f[0];
op o = f.kind();
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return c;
if (opts_ & Mut_Simplify_Bounds)
{
auto min = f.min();
auto max = f.max();
if (min > 0)
{
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min - 1, max);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, 0, max);
}
if (max != formula::unbounded())
{
if (max > min && mutation_counter_-- == 0)
return formula::bunop(o, c, min, max - 1);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min,
formula::unbounded());
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
}
SPOT_UNREACHABLE();
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
{
if (!left_is_sere)
return first;
else if (o == op::UConcat)
return formula::NegClosure(first);
else // EConcat or EConcatMarked
return formula::Closure(first);
}
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return second;
if (opts_ & Mut_Rewrite_Ops)
{
switch (o)
{
case op::U:
if (mutation_counter_-- == 0)
return formula::W(first, second);
break;
case op::M:
if (mutation_counter_-- == 0)
return formula::R(first, second);
if (mutation_counter_-- == 0)
return formula::U(second, first);
break;
case op::R:
if (mutation_counter_-- == 0)
return formula::W(second, first);
break;
default:
break;
}
}
if (opts_ & Mut_Split_Ops)
{
switch (o)
{
case op::Equiv:
if (mutation_counter_-- == 0)
return formula::Implies(first, second);
if (mutation_counter_-- == 0)
return formula::Implies(second, first);
if (mutation_counter_-- == 0)
return formula::And({first, second});
if (mutation_counter_-- == 0)
{
// Negate the two argument sequentially (in this
// case right before left, otherwise different
// compilers will make different choices.
auto right = formula::Not(second);
return formula::And({formula::Not(first), right});
}
break;
case op::Xor:
if (mutation_counter_-- == 0)
return formula::And({first, formula::Not(second)});
if (mutation_counter_-- == 0)
return formula::And({formula::Not(first), second});
break;
default:
break;
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
case op::Star:
case op::FStar:
{
formula c = f[0];
op o = f.kind();
if (opts_ & Mut_Remove_Ops && mutation_counter_-- == 0)
return c;
if (opts_ & Mut_Simplify_Bounds)
{
auto min = f.min();
auto max = f.max();
if (min > 0)
{
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min - 1, max);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, 0, max);
}
if (max != formula::unbounded())
{
if (max > min && mutation_counter_-- == 0)
return formula::bunop(o, c, min, max - 1);
if (mutation_counter_-- == 0)
return formula::bunop(o, c, min,
formula::unbounded());
}
}
if (mutation_counter_ < 0)
return f;
else
return f.map(recurse);
}
}
SPOT_UNREACHABLE();
}
formula
get_mutation(int n)
{
mutation_counter_ = n;
formula mut = mutate(f_);
if (mut == f_)
return nullptr;
return mut;
mutation_counter_ = n;
formula mut = mutate(f_);
if (mut == f_)
return nullptr;
return mut;
}
};
@ -291,13 +291,13 @@ namespace spot
assert(left != nullptr);
assert(right != nullptr);
if (left == right)
return false;
return false;
auto ll = length(left);
auto lr = length(right);
if (ll < lr)
return true;
return true;
if (ll > lr)
return false;
return false;
return left < right;
}
@ -305,55 +305,55 @@ namespace spot
void
single_mutation_rec(formula f, fset_t& mutations, unsigned opts,
unsigned& n, unsigned m)
unsigned& n, unsigned m)
{
if (m == 0)
{
if (mutations.insert(f).second)
--n;
}
{
if (mutations.insert(f).second)
--n;
}
else
{
formula mut;
int i = 0;
mutator mv(f, opts);
while (n > 0 && ((mut = mv.get_mutation(i++)) != nullptr))
single_mutation_rec(mut, mutations, opts, n, m - 1);
}
{
formula mut;
int i = 0;
mutator mv(f, opts);
while (n > 0 && ((mut = mv.get_mutation(i++)) != nullptr))
single_mutation_rec(mut, mutations, opts, n, m - 1);
}
}
void
replace_ap_rec(formula f, fset_t& mutations, unsigned opts,
unsigned& n, unsigned m)
unsigned& n, unsigned m)
{
if (m == 0)
{
if (mutations.insert(f).second)
--n;
}
{
if (mutations.insert(f).second)
--n;
}
else
{
if (!n)
return;
auto aps =
std::unique_ptr<atomic_prop_set>(atomic_prop_collect(f));
for (auto ap1: *aps)
for (auto ap2: *aps)
{
if (ap1 == ap2)
continue;
auto mut = substitute_ap(f, ap1, ap2);
replace_ap_rec(mut, mutations, opts, n, m - 1);
if (!n)
return;
}
}
{
if (!n)
return;
auto aps =
std::unique_ptr<atomic_prop_set>(atomic_prop_collect(f));
for (auto ap1: *aps)
for (auto ap2: *aps)
{
if (ap1 == ap2)
continue;
auto mut = substitute_ap(f, ap1, ap2);
replace_ap_rec(mut, mutations, opts, n, m - 1);
if (!n)
return;
}
}
}
}
std::vector<formula>
mutate(formula f, unsigned opts, unsigned max_output,
unsigned mutation_count, bool sort)
unsigned mutation_count, bool sort)
{
fset_t mutations;
single_mutation_rec(f, mutations, opts, max_output, mutation_count);

View file

@ -38,8 +38,8 @@ namespace spot
SPOT_API
std::vector<formula> mutate(formula f,
unsigned opts = Mut_All,
unsigned max_output = -1U,
unsigned mutation_count = 1,
bool sort = true);
unsigned opts = Mut_All,
unsigned max_output = -1U,
unsigned mutation_count = 1,
bool sort = true);
}

View file

@ -94,8 +94,8 @@ namespace spot
/// \param shift how many characters to add to the error locations
/// \return \c true iff any diagnostic was output.
bool format_errors(std::ostream& os,
const std::string& input,
unsigned shift);
const std::string& input,
unsigned shift);
};
@ -119,10 +119,10 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_infix_psl(const std::string& ltl_string,
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
/// \brief Build a Boolean formula from a string.
/// \param ltl_string The string to parse.
@ -142,10 +142,10 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_infix_boolean(const std::string& ltl_string,
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
/// \brief Build a formula from an LTL string in LBT's format.
/// \param ltl_string The string to parse.
@ -167,9 +167,9 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_prefix_ltl(const std::string& ltl_string,
environment& env =
default_environment::instance(),
bool debug = false);
environment& env =
default_environment::instance(),
bool debug = false);
/// \brief A simple wrapper to parse_infix_psl() and parse_prefix_ltl().
///
@ -179,7 +179,7 @@ namespace spot
/// parse_infix_psl() as a parse_error exception.
SPOT_API formula
parse_formula(const std::string& ltl_string,
environment& env = default_environment::instance());
environment& env = default_environment::instance());
/// \brief Build a formula from a string representing a SERE.
/// \param sere_string The string to parse.
@ -200,10 +200,10 @@ namespace spot
/// \warning This function is not reentrant.
SPOT_API
parsed_formula parse_infix_sere(const std::string& sere_string,
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
environment& env =
default_environment::instance(),
bool debug = false,
bool lenient = false);
/// \brief Fix location of diagnostics assuming the input is utf8.
///
@ -230,7 +230,7 @@ namespace spot
SPOT_API
void
fix_utf8_locations(const std::string& input_string,
parse_error_list& error_list);
parse_error_list& error_list);
/// @}
}

File diff suppressed because it is too large Load diff

View file

@ -34,14 +34,14 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_psl(std::ostream& os, formula f, bool full_parent = false);
/// \brief Convert a PSL formula into a string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_psl(formula f, bool full_parent = false);
@ -49,15 +49,15 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_utf8_psl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Convert a PSL formula into a utf-8 string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_utf8_psl(formula f, bool full_parent = false);
@ -65,14 +65,14 @@ namespace spot
/// \param f The formula to translate.
/// \param os The stream where it should be output.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_sere(std::ostream& os, formula f, bool full_parent = false);
/// \brief Convert a SERE formula into a string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_sere(formula f, bool full_parent = false);
@ -80,15 +80,15 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_utf8_sere(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Convert a SERE formula into a string which is parsable
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_utf8_sere(formula f, bool full_parent = false);
@ -96,15 +96,15 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_spin_ltl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Convert an LTL formula into a string parsable by Spin.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_spin_ltl(formula f, bool full_parent = false);
@ -123,16 +123,16 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_latex_psl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a formula as a LaTeX string which is parsable.
/// unless the formula contains automaton operators (used in ELTL formulae).
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_latex_psl(formula f, bool full_parent = false);
@ -140,16 +140,16 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_latex_sere(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a SERE formula as a LaTeX string which is parsable.
/// unless the formula contains automaton operators (used in ELTL formulae).
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_latex_sere(formula f, bool full_parent = false);
@ -159,17 +159,17 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_sclatex_psl(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a PSL formula as a self-contained LaTeX string.
///
/// The result cannot be parsed bacl.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_sclatex_psl(formula f, bool full_parent = false);
@ -179,17 +179,17 @@ namespace spot
/// \param os The stream where it should be output.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::ostream&
print_sclatex_sere(std::ostream& os, formula f,
bool full_parent = false);
bool full_parent = false);
/// \brief Output a SERE formula as a self-contained LaTeX string.
///
/// The result cannot be parsed bacl.
/// \param f The formula to translate.
/// \param full_parent Whether or not the string should by fully
/// parenthesized.
/// parenthesized.
SPOT_API std::string
str_sclatex_sere(formula f, bool full_parent = false);

View file

@ -183,24 +183,24 @@ namespace spot
total_2_and_more_ = 0.0;
for (unsigned i = 0; i < proba_size_; ++i)
{
if (proba_[i].min_n == 1)
{
total_1_ += proba_[i].proba;
if (proba_ + i >= proba_2_)
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n == 2)
{
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n > 2)
total_2_and_more_ += proba_[i].proba;
else
SPOT_UNREACHABLE(); // unexpected max_n
if (proba_[i].min_n == 1)
{
total_1_ += proba_[i].proba;
if (proba_ + i >= proba_2_)
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n == 2)
{
total_2_ += proba_[i].proba;
if (proba_ + i >= proba_2_or_more_)
total_2_and_more_ += proba_[i].proba;
}
else if (proba_[i].min_n > 2)
total_2_and_more_ += proba_[i].proba;
else
SPOT_UNREACHABLE(); // unexpected max_n
}
assert(total_2_and_more_ >= total_2_);
}
@ -216,48 +216,48 @@ namespace spot
// Approximate impossible cases.
if (n == 1 && total_1_ == 0.0)
{
if (total_2_ != 0.0)
n = 2;
else
n = 3;
if (total_2_ != 0.0)
n = 2;
else
n = 3;
}
else if (n == 2 && total_2_ == 0.0)
{
if (total_1_ != 0.0)
n = 1;
else
n = 3;
if (total_1_ != 0.0)
n = 1;
else
n = 3;
}
else if (n > 2 && total_2_and_more_ == 0.0)
{
if (total_1_ != 0.0)
n = 1;
else
assert(total_2_ == 0.0);
if (total_1_ != 0.0)
n = 1;
else
assert(total_2_ == 0.0);
}
if (n == 1)
{
r *= total_1_;
p = proba_;
r *= total_1_;
p = proba_;
}
else if (n == 2)
{
r *= total_2_;
p = proba_2_;
r *= total_2_;
p = proba_2_;
}
else
{
r *= total_2_and_more_;
p = proba_2_or_more_;
r *= total_2_and_more_;
p = proba_2_or_more_;
}
double s = p->proba;
while (s < r)
{
++p;
s += p->proba;
++p;
s += p->proba;
}
return p->build(this, n);
@ -271,30 +271,30 @@ namespace spot
char* key = strtok(options, "=\t, :;");
while (key)
{
char* value = strtok(nullptr, "=\t, :;");
if (!value)
return key;
char* value = strtok(nullptr, "=\t, :;");
if (!value)
return key;
char* endptr;
double res = strtod(value, &endptr);
if (*endptr)
return value;
char* endptr;
double res = strtod(value, &endptr);
if (*endptr)
return value;
unsigned i;
for (i = 0; i < proba_size_; ++i)
{
if (('a' <= *proba_[i].name && *proba_[i].name <= 'z'
&& !strcasecmp(proba_[i].name, key))
|| !strcmp(proba_[i].name, key))
{
proba_[i].proba = res;
break;
}
}
if (i == proba_size_)
return key;
unsigned i;
for (i = 0; i < proba_size_; ++i)
{
if (('a' <= *proba_[i].name && *proba_[i].name <= 'z'
&& !strcasecmp(proba_[i].name, key))
|| !strcmp(proba_[i].name, key))
{
proba_[i].proba = res;
break;
}
}
if (i == proba_size_)
return key;
key = strtok(nullptr, "=\t, :;");
key = strtok(nullptr, "=\t, :;");
}
update_sums();
return nullptr;
@ -393,7 +393,7 @@ namespace spot
{
// FIXME: This looks very fragile.
memmove(proba_ + 8, proba_ + 7,
((proba_ + 16) - (proba_ + 7)) * sizeof(*proba_));
((proba_ + 16) - (proba_ + 7)) * sizeof(*proba_));
proba_[7].setup("Closure", 2, closure_builder);
proba_[17].setup("EConcat", 3, binop_SERELTL_builder<op::EConcat>);
@ -402,10 +402,10 @@ namespace spot
}
randltlgenerator::randltlgenerator(atomic_prop_set aprops,
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
{
aprops_ = aprops;
output_ = opts.get("output", OUTPUTLTL);
@ -423,51 +423,51 @@ namespace spot
switch (output_)
{
case OUTPUTLTL:
rf_ = new random_ltl(&aprops_);
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities with "
"LTL output");
if (opt_pB)
throw std::invalid_argument("Cannot set boolean priorities with "
"LTL output");
tok_pL = rf_->parse_options(opt_pL);
break;
rf_ = new random_ltl(&aprops_);
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities with "
"LTL output");
if (opt_pB)
throw std::invalid_argument("Cannot set boolean priorities with "
"LTL output");
tok_pL = rf_->parse_options(opt_pL);
break;
case OUTPUTBOOL:
rf_ = new random_boolean(&aprops_);
tok_pB = rf_->parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities with "
"Boolean output");
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities "
"with Boolean output");
break;
rf_ = new random_boolean(&aprops_);
tok_pB = rf_->parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities with "
"Boolean output");
if (opt_pS)
throw std::invalid_argument("Cannot set sere priorities "
"with Boolean output");
break;
case OUTPUTSERE:
rf_ = rs_ = new random_sere(&aprops_);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities "
"with SERE output");
break;
rf_ = rs_ = new random_sere(&aprops_);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
if (opt_pL)
throw std::invalid_argument("Cannot set ltl priorities "
"with SERE output");
break;
case OUTPUTPSL:
rf_ = rp_ = new random_psl(&aprops_);
rs_ = &rp_->rs;
tok_pL = rp_->parse_options(opt_pL);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
break;
rf_ = rp_ = new random_psl(&aprops_);
rs_ = &rp_->rs;
tok_pL = rp_->parse_options(opt_pL);
tok_pS = rs_->parse_options(opt_pS);
tok_pB = rs_->rb.parse_options(opt_pB);
break;
}
if (tok_pL)
throw std::invalid_argument("failed to parse LTL priorities near "
+ std::string(tok_pL));
+ std::string(tok_pL));
if (tok_pS)
throw std::invalid_argument("failed to parse SERE priorities near "
+ std::string(tok_pS));
+ std::string(tok_pS));
if (tok_pB)
throw std::invalid_argument("failed to parse Boolean priorities near "
+ std::string(tok_pB));
+ std::string(tok_pB));
spot::srand(opt_seed_);
tl_simplifier_options simpl_opts(opt_simpl_level_);
@ -475,12 +475,12 @@ namespace spot
}
randltlgenerator::randltlgenerator(int aprops_n,
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
const option_map& opts,
char* opt_pL,
char* opt_pS,
char* opt_pB)
: randltlgenerator(create_atomic_prop_set(aprops_n), opts,
opt_pL, opt_pS, opt_pB)
opt_pL, opt_pS, opt_pB)
{
}
@ -496,24 +496,24 @@ namespace spot
formula f = nullptr;
do
{
ignore = false;
int size = opt_tree_size_min_;
if (size != opt_tree_size_max_)
size = spot::rrand(size, opt_tree_size_max_);
f = rf_->generate(size);
ignore = false;
int size = opt_tree_size_min_;
if (size != opt_tree_size_max_)
size = spot::rrand(size, opt_tree_size_max_);
f = rf_->generate(size);
if (opt_wf_)
{
atomic_prop_set s = aprops_;
remove_some_props(s);
f = formula::And({f, GF_n()});
}
if (opt_wf_)
{
atomic_prop_set s = aprops_;
remove_some_props(s);
f = formula::And({f, GF_n()});
}
if (opt_simpl_level_)
f = simpl_.simplify(f);
if (opt_simpl_level_)
f = simpl_.simplify(f);
if (opt_unique_ && !unique_set_.insert(f).second)
ignore = true;
if (opt_unique_ && !unique_set_.insert(f).second)
ignore = true;
} while (ignore && --trials);
if (trials <= 0)
return nullptr;
@ -529,9 +529,9 @@ namespace spot
while (n--)
{
auto i = s.begin();
std::advance(i, spot::mrand(s.size()));
s.erase(i);
auto i = s.begin();
std::advance(i, spot::mrand(s.size()));
s.erase(i);
}
}
@ -542,11 +542,11 @@ namespace spot
formula res = nullptr;
for (auto v: aprops_)
{
formula f = formula::G(formula::F(v));
if (res)
res = formula::And({f, res});
else
res = f;
formula f = formula::G(formula::F(v));
if (res)
res = formula::And({f, res});
else
res = f;
}
return res;
}

Some files were not shown because too many files have changed in this diff Show more