Commit 61b0a542 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

postproc: add support for co-Büchi output

* spot/twaalgos/cobuchi.cc, spot/twaalgos/cobuchi.hh (to_nca): New
function.
(weak_to_cobuchi): New internal function, used in to_nca and to_dca
when appropriate.
* spot/twaalgos/postproc.cc, spot/twaalgos/postproc.hh: Implement
the CoBuchi option.
* python/spot/__init__.py: Support it in Python.
* bin/common_post.cc: Add support for --buchi.
* bin/autfilt.cc: Remove the --dca option.
* tests/core/dca.test, tests/python/automata.ipynb: Adjust and add
more tests.  In particular, add more complex persistence and
recurrence formulas to the list of dca.test.
* tests/python/dca.test: Adjust and rename to...
* tests/core/dca2.test: ... this.  Add more tests, to the point
that this is now failing, as described in issue #317.
* tests/python/dca.py: Remove.
* tests/Makefile.am: Adjust.
parent 9464043d
...@@ -30,6 +30,11 @@ New in spot 2.4.4.dev (net yet released) ...@@ -30,6 +30,11 @@ New in spot 2.4.4.dev (net yet released)
output. Different styles can be requested using for instance output. Different styles can be requested using for instance
--parity='min odd' or --parity='max even'. --parity='min odd' or --parity='max even'.
- ltl2tgba, autfilt, and dstar2tgba have some new '--cobuchi' option
to force co-Büchi acceptance on the output. Beware: if the input
language is not co-Büchi realizable the output automaton will
recognize a superset of the input.
- genltl learned to generate six new families of formulas, taken from - genltl learned to generate six new families of formulas, taken from
the SYNTCOMP competition on reactive synthesis, and from from the SYNTCOMP competition on reactive synthesis, and from from
Müller & Sickert's GandALF'17 paper: Müller & Sickert's GandALF'17 paper:
...@@ -40,11 +45,8 @@ New in spot 2.4.4.dev (net yet released) ...@@ -40,11 +45,8 @@ New in spot 2.4.4.dev (net yet released)
--ms-phi-r=RANGE (FGa{n}&GFb{n})|((FGa{n-1}|GFb{n-1})&(...)) --ms-phi-r=RANGE (FGa{n}&GFb{n})|((FGa{n-1}|GFb{n-1})&(...))
--ms-phi-s=RANGE (FGa{n}|GFb{n})&((FGa{n-1}&GFb{n-1})|(...)) --ms-phi-s=RANGE (FGa{n}|GFb{n})&((FGa{n-1}&GFb{n-1})|(...))
- autfilt learned a couple of acceptance transformations: - autfilt learned --streett-like to convert automata with DNF
--streett-like converts automata with DNF acceptance acceptance into automata with Streett-like acceptance.
into automata with Streett-like acceptance.
--dca converts automata with DNF or Streett-like
acceptance into deterministic co-Büchi.
- autfilt learned --acceptance-is=ACC to filter automata by - autfilt learned --acceptance-is=ACC to filter automata by
acceptance condition. ACC can be the name of some acceptance acceptance condition. ACC can be the name of some acceptance
...@@ -91,10 +93,11 @@ New in spot 2.4.4.dev (net yet released) ...@@ -91,10 +93,11 @@ New in spot 2.4.4.dev (net yet released)
- spot::nsa_to_nca(), spot::dfn_to_nca(), spot::dfn_to_dca(), and - spot::nsa_to_nca(), spot::dfn_to_nca(), spot::dfn_to_dca(), and
spot::nsa_to_dca(), convert automata with DNF or Streett-like spot::nsa_to_dca(), convert automata with DNF or Streett-like
acceptance into deterministic or non-deterministic co-Büchi acceptance into deterministic or non-deterministic co-Büchi
automata. spot::to_dca() dispatches between the last two automata. spot::to_dca() and spot::to_nca() dispatches between
functions. The language of produced automata include the original these four functions. The language of produced automata include
language, but may be larger if the original automaton is not the original language, but may be larger if the original automaton
co-Büchi realizable. Based on Boker & Kupferman FOSSACS'11 paper. is not co-Büchi realizable. Based on Boker & Kupferman FOSSACS'11
paper.
- spot::scc_info::states_on_acc_cycle_of() return all states - spot::scc_info::states_on_acc_cycle_of() return all states
visited by any accepting cycle of the specified SCC. It only visited by any accepting cycle of the specified SCC. It only
...@@ -182,6 +185,10 @@ New in spot 2.4.4.dev (net yet released) ...@@ -182,6 +185,10 @@ New in spot 2.4.4.dev (net yet released)
have parity acceptance, it will simply be degeneralized or have parity acceptance, it will simply be degeneralized or
determinized. determinized.
- spot::postprocessor::set_type() can now request co-Büchi
acceptance as output. This calls the aforementioned to_nca() or
to_dca() functions.
- spot::remove_fin() will now call simplify_acceptance(), - spot::remove_fin() will now call simplify_acceptance(),
introduced in 2.4, before attempting its different Fin-removal introduced in 2.4, before attempting its different Fin-removal
strategies. strategies.
......
...@@ -359,12 +359,6 @@ static const argp_option options[] = ...@@ -359,12 +359,6 @@ static const argp_option options[] =
"solver can be set thanks to the SPOT_SATSOLVER environment variable" "solver can be set thanks to the SPOT_SATSOLVER environment variable"
"(see spot-x)." "(see spot-x)."
, 0 }, , 0 },
{ "dca", OPT_DCA, nullptr, 0,
"convert to deterministic co-Büchi. The resulting automaton will always "
"recognize at least the same language. Actually, it can recognize "
"more if the original language can not be expressed using a co-Büchi "
"acceptance condition."
, 0 },
{ nullptr, 0, nullptr, 0, "Decorations (for -d and -H1.1 output):", 9 }, { nullptr, 0, nullptr, 0, "Decorations (for -d and -H1.1 output):", 9 },
{ "highlight-nondet-states", OPT_HIGHLIGHT_NONDET_STATES, "NUM", { "highlight-nondet-states", OPT_HIGHLIGHT_NONDET_STATES, "NUM",
OPTION_ARG_OPTIONAL, "highlight nondeterministic states with color NUM", OPTION_ARG_OPTIONAL, "highlight nondeterministic states with color NUM",
...@@ -1440,8 +1434,6 @@ namespace ...@@ -1440,8 +1434,6 @@ namespace
aut = spot::to_generalized_rabin(aut, opt_gra == GRA_SHARE_INF); aut = spot::to_generalized_rabin(aut, opt_gra == GRA_SHARE_INF);
if (opt_gsa) if (opt_gsa)
aut = spot::to_generalized_streett(aut, opt_gsa == GSA_SHARE_FIN); aut = spot::to_generalized_streett(aut, opt_gsa == GSA_SHARE_FIN);
if (opt_dca)
aut = spot::to_dca(aut, false);
if (opt_streett_like) if (opt_streett_like)
aut = spot::dnf_to_streett(aut); aut = spot::dnf_to_streett(aut);
......
...@@ -34,7 +34,8 @@ bool level_set = false; ...@@ -34,7 +34,8 @@ bool level_set = false;
bool pref_set = false; bool pref_set = false;
enum { enum {
OPT_HIGH = 1, OPT_COBUCHI = 256,
OPT_HIGH,
OPT_LOW, OPT_LOW,
OPT_MEDIUM, OPT_MEDIUM,
OPT_SMALL, OPT_SMALL,
...@@ -65,6 +66,11 @@ static constexpr const argp_option options[] = ...@@ -65,6 +66,11 @@ static constexpr const argp_option options[] =
"any|min|max|odd|even|min odd|min even|max odd|max even", "any|min|max|odd|even|min odd|min even|max odd|max even",
OPTION_ARG_OPTIONAL, OPTION_ARG_OPTIONAL,
"colored automaton with parity acceptance", 0, }, "colored automaton with parity acceptance", 0, },
{ "cobuchi", OPT_COBUCHI, nullptr, 0,
"automaton with co-Büchi acceptance (will recognize"
"a superset of the input language if not co-Büchi "
"realizable)", 0 },
{ "coBuchi", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
/**************************************************/ /**************************************************/
{ nullptr, 0, nullptr, 0, "Simplification goal:", 20 }, { nullptr, 0, nullptr, 0, "Simplification goal:", 20 },
{ "small", OPT_SMALL, nullptr, 0, "prefer small automata (default)", 0 }, { "small", OPT_SMALL, nullptr, 0, "prefer small automata (default)", 0 },
...@@ -123,6 +129,11 @@ static const argp_option options_disabled[] = ...@@ -123,6 +129,11 @@ static const argp_option options_disabled[] =
"any|min|max|odd|even|min odd|min even|max odd|max even", "any|min|max|odd|even|min odd|min even|max odd|max even",
OPTION_ARG_OPTIONAL, OPTION_ARG_OPTIONAL,
"colored automaton with parity acceptance", 0, }, "colored automaton with parity acceptance", 0, },
{ "cobuchi", OPT_COBUCHI, nullptr, 0,
"automaton with co-Büchi acceptance (will recognize"
"a superset of the input language if not co-Büchi "
"realizable)", 0 },
{ "coBuchi", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
/**************************************************/ /**************************************************/
{ nullptr, 0, nullptr, 0, "Simplification goal:", 20 }, { nullptr, 0, nullptr, 0, "Simplification goal:", 20 },
{ "small", OPT_SMALL, nullptr, 0, "prefer small automata", 0 }, { "small", OPT_SMALL, nullptr, 0, "prefer small automata", 0 },
...@@ -210,6 +221,9 @@ parse_opt_post(int key, char* arg, struct argp_state*) ...@@ -210,6 +221,9 @@ parse_opt_post(int key, char* arg, struct argp_state*)
case 'S': case 'S':
sbacc = spot::postprocessor::SBAcc; sbacc = spot::postprocessor::SBAcc;
break; break;
case OPT_COBUCHI:
type = spot::postprocessor::CoBuchi;
break;
case OPT_HIGH: case OPT_HIGH:
level = spot::postprocessor::High; level = spot::postprocessor::High;
simplification_level = 3; simplification_level = 3;
......
...@@ -503,6 +503,11 @@ def _postproc_translate_options(obj, default_type, *args): ...@@ -503,6 +503,11 @@ def _postproc_translate_options(obj, default_type, *args):
type_ = postprocessor.TGBA type_ = postprocessor.TGBA
elif val == 'ba': elif val == 'ba':
type_ = postprocessor.BA type_ = postprocessor.BA
elif val == 'cobuchi' or val == 'nca':
type_ = postprocessor.CoBuchi
elif val == 'dca':
type_ = postprocessor.CoBuchi
pref_ = postprocessor.Deterministic
elif val == 'parity min odd': elif val == 'parity min odd':
type_ = postprocessor.ParityMinOdd type_ = postprocessor.ParityMinOdd
elif val == 'parity min even': elif val == 'parity min even':
...@@ -566,14 +571,17 @@ def _postproc_translate_options(obj, default_type, *args): ...@@ -566,14 +571,17 @@ def _postproc_translate_options(obj, default_type, *args):
options = { options = {
'any': pref_set, 'any': pref_set,
'ba': type_set, 'ba': type_set,
'complete': misc_set, 'cobuchi': type_set,
'colored': misc_set, 'colored': misc_set,
'complete': misc_set,
'dca': type_set,
'deterministic': pref_set, 'deterministic': pref_set,
'generic': type_set, 'generic': type_set,
'high': optm_set, 'high': optm_set,
'low': optm_set, 'low': optm_set,
'medium': optm_set, 'medium': optm_set,
'monitor': type_set, 'monitor': type_set,
'nca': type_set,
'parity even': type_set, 'parity even': type_set,
'parity max even': type_set, 'parity max even': type_set,
'parity max odd': type_set, 'parity max odd': type_set,
...@@ -635,7 +643,7 @@ def translate(formula, *args, dict=_bdd_dict): ...@@ -635,7 +643,7 @@ def translate(formula, *args, dict=_bdd_dict):
- at most one in 'TGBA', 'BA', or 'Monitor', 'generic', - at most one in 'TGBA', 'BA', or 'Monitor', 'generic',
'parity', 'parity min odd', 'parity min even', 'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to 'parity max odd', 'parity max even' (type of automaton to
build) build), 'coBuchi'
- at most one in 'Small', 'Deterministic', 'Any' - at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton) (preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High' - at most one in 'Low', 'Medium', 'High'
...@@ -668,7 +676,7 @@ def postprocess(automaton, *args, formula=None): ...@@ -668,7 +676,7 @@ def postprocess(automaton, *args, formula=None):
- at most one in 'Generic', 'TGBA', 'BA', or 'Monitor', - at most one in 'Generic', 'TGBA', 'BA', or 'Monitor',
'parity', 'parity min odd', 'parity min even', 'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to 'parity max odd', 'parity max even' (type of automaton to
build) build), 'coBuchi'
- at most one in 'Small', 'Deterministic', 'Any' - at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton) (preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High' - at most one in 'Low', 'Medium', 'High'
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <spot/twaalgos/product.hh> #include <spot/twaalgos/product.hh>
#include <spot/twaalgos/sccinfo.hh> #include <spot/twaalgos/sccinfo.hh>
#include <spot/twaalgos/totgba.hh> #include <spot/twaalgos/totgba.hh>
#include <spot/twaalgos/isdet.hh>
#include <spot/twaalgos/strength.hh>
#include <stack> #include <stack>
#include <unordered_map> #include <unordered_map>
...@@ -196,7 +198,7 @@ namespace spot ...@@ -196,7 +198,7 @@ namespace spot
bool was_rabin = false, bool was_rabin = false,
unsigned orig_num_st = 0) unsigned orig_num_st = 0)
: aut_(ref_prod), : aut_(ref_prod),
state_based_((bool)aut_->prop_state_acc()), state_based_(aut_->prop_state_acc().is_true()),
pairs_(pairs), pairs_(pairs),
nb_pairs_(pairs.size()), nb_pairs_(pairs.size()),
named_states_(named_states), named_states_(named_states),
...@@ -241,29 +243,30 @@ namespace spot ...@@ -241,29 +243,30 @@ namespace spot
twa_graph_ptr twa_graph_ptr
nsa_to_nca(const const_twa_graph_ptr& ref, nsa_to_nca(const_twa_graph_ptr ref,
bool named_states, bool named_states,
vect_nca_info* nca_info) vect_nca_info* nca_info)
{ {
twa_graph_ptr ref_tmp = ref->acc().is_parity() ? to_generalized_streett(ref) if (ref->acc().is_parity())
: nullptr; ref = to_generalized_streett(ref);
std::vector<acc_cond::rs_pair> pairs; std::vector<acc_cond::rs_pair> pairs;
if (!(ref_tmp ? ref_tmp : ref)->acc().is_streett_like(pairs)) if (!ref->acc().is_streett_like(pairs))
throw std::runtime_error("nsa_to_nca() only works with Streett-like or " throw std::runtime_error("nsa_to_nca() only works with Streett-like or "
"Parity acceptance condition"); "Parity acceptance condition");
nsa_to_nca_converter nca_converter(ref_tmp ? ref_tmp : ref, // FIXME: At the moment this algorithm does not support
ref_tmp ? ref_tmp : ref, // transition-based acceptance. See issue #317. Once that is
pairs, // fixed we may remove the next line.
named_states, ref = sbacc(std::const_pointer_cast<twa_graph>(ref));
false);
nsa_to_nca_converter nca_converter(ref, ref, pairs, named_states, false);
return nca_converter.run(nca_info); return nca_converter.run(nca_info);
} }
twa_graph_ptr twa_graph_ptr
dnf_to_nca(const const_twa_graph_ptr& ref, dnf_to_nca(const_twa_graph_ptr ref, bool named_states,
bool named_states,
vect_nca_info* nca_info) vect_nca_info* nca_info)
{ {
const acc_cond::acc_code& code = ref->get_acceptance(); const acc_cond::acc_code& code = ref->get_acceptance();
...@@ -287,6 +290,61 @@ namespace spot ...@@ -287,6 +290,61 @@ namespace spot
return nca_converter.run(nca_info); return nca_converter.run(nca_info);
} }
namespace
{
twa_graph_ptr
weak_to_cobuchi(const const_twa_graph_ptr& aut)
{
trival iw = aut->prop_inherently_weak();
if (iw.is_false())
return nullptr;
scc_info si(aut);
if (iw.is_maybe() && !is_weak_automaton(aut, &si))
return nullptr;
auto res = make_twa_graph(aut->get_dict());
res->copy_ap_of(aut);
res->prop_copy(aut, twa::prop_set::all());
res->new_states(aut->num_states());
si.determine_unknown_acceptance();
unsigned ns = si.scc_count();
for (unsigned s = 0; s < ns; ++s)
{
acc_cond::mark_t m = 0U;
if (si.is_rejecting_scc(s))
m = acc_cond::mark_t{0};
else
assert(si.is_accepting_scc(s));
for (auto& e: si.edges_of(s))
res->new_edge(e.src, e.dst, e.cond, m);
}
res->set_co_buchi();
res->set_init_state(aut->get_init_state_number());
res->prop_weak(true);
res->prop_state_acc(true);
return res;
}
}
twa_graph_ptr
to_nca(const_twa_graph_ptr aut, bool named_states)
{
if (auto weak = weak_to_cobuchi(aut))
return weak;
const acc_cond::acc_code& code = aut->get_acceptance();
std::vector<acc_cond::rs_pair> pairs;
if (aut->acc().is_streett_like(pairs) || aut->acc().is_parity())
return nsa_to_nca(aut, named_states);
else if (code.is_dnf())
return dnf_to_nca(aut, named_states);
auto tmp = make_twa_graph(aut, twa::prop_set::all());
tmp->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().to_dnf());
return to_nca(tmp, named_states);
}
namespace namespace
{ {
...@@ -543,7 +601,7 @@ namespace spot ...@@ -543,7 +601,7 @@ namespace spot
twa_graph_ptr twa_graph_ptr
nsa_to_dca(const const_twa_graph_ptr& aut, bool named_states) nsa_to_dca(const_twa_graph_ptr aut, bool named_states)
{ {
debug << "NSA_to_dca" << std::endl; debug << "NSA_to_dca" << std::endl;
std::vector<acc_cond::rs_pair> pairs; std::vector<acc_cond::rs_pair> pairs;
...@@ -568,7 +626,7 @@ namespace spot ...@@ -568,7 +626,7 @@ namespace spot
twa_graph_ptr twa_graph_ptr
dnf_to_dca(const const_twa_graph_ptr& aut, bool named_states) dnf_to_dca(const_twa_graph_ptr aut, bool named_states)
{ {
debug << "DNF_to_dca" << std::endl; debug << "DNF_to_dca" << std::endl;
const acc_cond::acc_code& code = aut->get_acceptance(); const acc_cond::acc_code& code = aut->get_acceptance();
...@@ -599,8 +657,12 @@ namespace spot ...@@ -599,8 +657,12 @@ namespace spot
twa_graph_ptr twa_graph_ptr
to_dca(const const_twa_graph_ptr& aut, bool named_states) to_dca(const_twa_graph_ptr aut, bool named_states)
{ {
if (is_deterministic(aut))
if (auto weak = weak_to_cobuchi(aut))
return weak;
const acc_cond::acc_code& code = aut->get_acceptance(); const acc_cond::acc_code& code = aut->get_acceptance();
std::vector<acc_cond::rs_pair> pairs; std::vector<acc_cond::rs_pair> pairs;
...@@ -608,8 +670,10 @@ namespace spot ...@@ -608,8 +670,10 @@ namespace spot
return nsa_to_dca(aut, named_states); return nsa_to_dca(aut, named_states);
else if (code.is_dnf()) else if (code.is_dnf())
return dnf_to_dca(aut, named_states); return dnf_to_dca(aut, named_states);
else
throw std::runtime_error("to_dca() only works with Streett-like, Parity " auto tmp = make_twa_graph(aut, twa::prop_set::all());
"or any acceptance condition in DNF"); tmp->set_acceptance(aut->acc().num_sets(),
aut->get_acceptance().to_dnf());
return to_nca(tmp, named_states);
} }
} }
...@@ -78,7 +78,7 @@ namespace spot ...@@ -78,7 +78,7 @@ namespace spot
/// \a named_states name each state for easier debugging. /// \a named_states name each state for easier debugging.
/// \a nca_info retrieve information about state visited infinitely often. /// \a nca_info retrieve information about state visited infinitely often.
SPOT_API twa_graph_ptr SPOT_API twa_graph_ptr
nsa_to_nca(const const_twa_graph_ptr& aut, nsa_to_nca(const_twa_graph_ptr aut,
bool named_states = false, bool named_states = false,
vect_nca_info* nca_info = nullptr); vect_nca_info* nca_info = nullptr);
...@@ -103,10 +103,21 @@ namespace spot ...@@ -103,10 +103,21 @@ namespace spot
/// \a named_states name each state for easier debugging. /// \a named_states name each state for easier debugging.
/// \a nca_info retrieve information about state visited infinitely often. /// \a nca_info retrieve information about state visited infinitely often.
SPOT_API twa_graph_ptr SPOT_API twa_graph_ptr
dnf_to_nca(const const_twa_graph_ptr& aut, dnf_to_nca(const_twa_graph_ptr aut,
bool named_states = false, bool named_states = false,
vect_nca_info* nca_info = nullptr); vect_nca_info* nca_info = nullptr);
/// \brief Converts any ω-automata to non-deterministic co-buchi
///
/// The language of the resulting automaton always include the
/// original language, and is a superset iff the original language
/// can not be expressed using a co-Büchi acceptance condition.
///
/// The implementation dispatches between dnf_to_nca, nsa_to_nca,
/// and a trivial implementation for weak automata.
SPOT_API twa_graph_ptr
to_nca(const_twa_graph_ptr aut, bool named_states = false);
/// \brief Converts a nondet Streett-like aut. to a det. co-Büchi aut. /// \brief Converts a nondet Streett-like aut. to a det. co-Büchi aut.
/// ///
/// This function calls first nsa_to_nca() in order to retrieve som /// This function calls first nsa_to_nca() in order to retrieve som
...@@ -127,7 +138,7 @@ namespace spot ...@@ -127,7 +138,7 @@ namespace spot
/// \a aut The automaton to convert. /// \a aut The automaton to convert.
/// \a named_states name each state for easier debugging. /// \a named_states name each state for easier debugging.
SPOT_API twa_graph_ptr SPOT_API twa_graph_ptr
nsa_to_dca(const const_twa_graph_ptr& aut, bool named_states = false); nsa_to_dca(const_twa_graph_ptr aut, bool named_states = false);
/// \brief Converts an aut. with acceptance in DNF to a det. co-Büchi aut. /// \brief Converts an aut. with acceptance in DNF to a det. co-Büchi aut.
/// ///
...@@ -149,13 +160,16 @@ namespace spot ...@@ -149,13 +160,16 @@ namespace spot
/// \a aut The automaton to convert. /// \a aut The automaton to convert.
/// \a named_states name each state for easier debugging. /// \a named_states name each state for easier debugging.
SPOT_API twa_graph_ptr SPOT_API twa_graph_ptr
dnf_to_dca(const const_twa_graph_ptr& aut, bool named_states = false); dnf_to_dca(const_twa_graph_ptr aut, bool named_states = false);
/// \brief Converts any ω-automata to det. co-buchi (when possible) /// \brief Converts any ω-automata to deterministic co-buchi
///
/// The language of the resulting automaton always include the
/// original language, and is a superset iff the original language
/// can not be expressed using a co-Büchi acceptance condition.
/// ///
/// The resulting automaton will always recognize at least the same language. /// The implementation dispatches between dnf_to_dca, nsa_to_dca,
/// Actually, it can recognize more if the original language can not be /// and a trivial implementation for deterministic weak automata.
/// expressed using a co-Büchi acceptance condition.
SPOT_API twa_graph_ptr SPOT_API twa_graph_ptr
to_dca(const const_twa_graph_ptr& aut, bool named_states = false); to_dca(const_twa_graph_ptr aut, bool named_states = false);
} }
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include <spot/twaalgos/determinize.hh> #include <spot/twaalgos/determinize.hh>
#include <spot/twaalgos/alternation.hh> #include <spot/twaalgos/alternation.hh>
#include <spot/twaalgos/parity.hh> #include <spot/twaalgos/parity.hh>
#include <spot/twaalgos/cobuchi.hh>
#include <spot/twaalgos/dot.hh>
namespace spot namespace spot
{ {
...@@ -194,6 +196,7 @@ namespace spot ...@@ -194,6 +196,7 @@ namespace spot
if (type_ == BA || SBACC_) if (type_ == BA || SBACC_)
state_based_ = true; state_based_ = true;
bool via_gba = (type_ == BA) || (type_ == TGBA) || (type_ == Monitor);
bool want_parity = (type_ & Parity) == Parity; bool want_parity = (type_ & Parity) == Parity;
if (COLORED_ && !want_parity) if (COLORED_ && !want_parity)
throw std::runtime_error("postprocessor: the Colored setting only works " throw std::runtime_error("postprocessor: the Colored setting only works "
...@@ -234,7 +237,7 @@ namespace spot ...@@ -234,7 +237,7 @@ namespace spot
!(type_ == Generic && PREF_ == Any && level_ == Low)) !(type_ == Generic && PREF_ == Any && level_ == Low))
a = remove_alternation(a); a = remove_alternation(a);
if ((type_ != Generic && !a->acc().is_generalized_buchi()) if ((via_gba && !a->acc().is_generalized_buchi())
|| (want_parity && !a->acc().is_parity())) || (want_parity && !a->acc().is_parity()))
{ {
a = to_generalized_buchi(a); a = to_generalized_buchi(a);
...@@ -247,7 +250,8 @@ namespace spot ...@@ -247,7 +250,8 @@ namespace spot
|| type_ == TGBA || type_ == TGBA
|| (type_ == BA && a->is_sba()) || (type_ == BA && a->is_sba())
|| (type_ == Monitor && a->num_sets() == 0) || (type_ == Monitor && a->num_sets() == 0)
|| (want_parity && a->acc().is_parity()))) || (want_parity && a->acc().is_parity())
|| (type_ == CoBuchi && a->acc().is_co_buchi())))
return finalize(a); return finalize(a);
int original_acc = a->num_sets(); int original_acc = a->num_sets();
...@@ -290,6 +294,8 @@ namespace spot ...@@ -290,6 +294,8 @@ namespace spot
{ {
if (type_ == BA) if (type_ == BA)
a = do_degen(a); a = do_degen(a);
else if (type_ == CoBuchi)
a = to_nca(a);
return finalize(a); return finalize(a);
} }
...@@ -552,6 +558,21 @@ namespace spot ...@@ -552,6 +558,21 @@ namespace spot
sim = dba ? dba : sim; sim = dba ? dba : sim;
sim->remove_unused_ap(); sim->remove_unused_ap();
if (type_ == CoBuchi)
{
unsigned ns = sim->num_states();
if (PREF_ == Deterministic)
sim = to_dca(sim);
else
sim = to_nca(sim);
// if the input of to_dca/to_nca was weak, the number of
// states has not changed, and running simulation is useless.
if (level_ != Low && ns < sim->num_states())
sim = do_simul(sim, simul_);
}
return finalize(sim); return finalize(sim);
} }
} }
...@@ -72,8 +72,8 @@ namespace spot ...@@ -72,8 +72,8 @@ namespace spot
/// options used for debugging or benchmarking. /// options used for debugging or benchmarking.
postprocessor(const option_map* opt = nullptr); postprocessor(const option_map* opt = nullptr);
enum output_type { TGBA = 0, enum output_type { TGBA = 0, // should be renamed GeneralizedBuchi
BA = 1, BA = 1, // should be renamed Buchi and not imply SBAcc
Monitor = 2, Monitor = 2,
Generic = 3, Generic = 3,
Parity = 4, Parity = 4,
...@@ -85,6 +85,7 @@ namespace spot ...@@ -85,6 +85,7 @@ namespace spot
ParityMaxOdd = ParityMax | ParityOdd, ParityMaxOdd = ParityMax | ParityOdd,
ParityMinEven = ParityMin | ParityEven, ParityMinEven = ParityMin | ParityEven,
ParityMaxEven = ParityMax | ParityEven, ParityMaxEven = ParityMax | ParityEven,
CoBuchi = 128,
}; };