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.
This commit is contained in:
parent
9464043d39
commit
61b0a542f1
14 changed files with 618 additions and 531 deletions
|
|
@ -29,6 +29,8 @@
|
|||
#include <spot/twaalgos/product.hh>
|
||||
#include <spot/twaalgos/sccinfo.hh>
|
||||
#include <spot/twaalgos/totgba.hh>
|
||||
#include <spot/twaalgos/isdet.hh>
|
||||
#include <spot/twaalgos/strength.hh>
|
||||
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
|
|
@ -196,7 +198,7 @@ namespace spot
|
|||
bool was_rabin = false,
|
||||
unsigned orig_num_st = 0)
|
||||
: aut_(ref_prod),
|
||||
state_based_((bool)aut_->prop_state_acc()),
|
||||
state_based_(aut_->prop_state_acc().is_true()),
|
||||
pairs_(pairs),
|
||||
nb_pairs_(pairs.size()),
|
||||
named_states_(named_states),
|
||||
|
|
@ -241,29 +243,30 @@ namespace spot
|
|||
|
||||
|
||||
twa_graph_ptr
|
||||
nsa_to_nca(const const_twa_graph_ptr& ref,
|
||||
nsa_to_nca(const_twa_graph_ptr ref,
|
||||
bool named_states,
|
||||
vect_nca_info* nca_info)
|
||||
{
|
||||
twa_graph_ptr ref_tmp = ref->acc().is_parity() ? to_generalized_streett(ref)
|
||||
: nullptr;
|
||||
if (ref->acc().is_parity())
|
||||
ref = to_generalized_streett(ref);
|
||||
|
||||
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 "
|
||||
"Parity acceptance condition");
|
||||
|
||||
nsa_to_nca_converter nca_converter(ref_tmp ? ref_tmp : ref,
|
||||
ref_tmp ? ref_tmp : ref,
|
||||
pairs,
|
||||
named_states,
|
||||
false);
|
||||
// FIXME: At the moment this algorithm does not support
|
||||
// transition-based acceptance. See issue #317. Once that is
|
||||
// fixed we may remove the next line.
|
||||
ref = sbacc(std::const_pointer_cast<twa_graph>(ref));
|
||||
|
||||
nsa_to_nca_converter nca_converter(ref, ref, pairs, named_states, false);
|
||||
return nca_converter.run(nca_info);
|
||||
}
|
||||
|
||||
|
||||
twa_graph_ptr
|
||||
dnf_to_nca(const const_twa_graph_ptr& ref,
|
||||
bool named_states,
|
||||
dnf_to_nca(const_twa_graph_ptr ref, bool named_states,
|
||||
vect_nca_info* nca_info)
|
||||
{
|
||||
const acc_cond::acc_code& code = ref->get_acceptance();
|
||||
|
|
@ -287,6 +290,61 @@ namespace spot
|
|||
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
|
||||
{
|
||||
|
|
@ -543,7 +601,7 @@ namespace spot
|
|||
|
||||
|
||||
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;
|
||||
std::vector<acc_cond::rs_pair> pairs;
|
||||
|
|
@ -568,7 +626,7 @@ namespace spot
|
|||
|
||||
|
||||
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;
|
||||
const acc_cond::acc_code& code = aut->get_acceptance();
|
||||
|
|
@ -599,8 +657,12 @@ namespace spot
|
|||
|
||||
|
||||
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();
|
||||
|
||||
std::vector<acc_cond::rs_pair> pairs;
|
||||
|
|
@ -608,8 +670,10 @@ namespace spot
|
|||
return nsa_to_dca(aut, named_states);
|
||||
else if (code.is_dnf())
|
||||
return dnf_to_dca(aut, named_states);
|
||||
else
|
||||
throw std::runtime_error("to_dca() only works with Streett-like, Parity "
|
||||
"or any acceptance condition in DNF");
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ namespace spot
|
|||
/// \a named_states name each state for easier debugging.
|
||||
/// \a nca_info retrieve information about state visited infinitely often.
|
||||
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,
|
||||
vect_nca_info* nca_info = nullptr);
|
||||
|
||||
|
|
@ -103,10 +103,21 @@ namespace spot
|
|||
/// \a named_states name each state for easier debugging.
|
||||
/// \a nca_info retrieve information about state visited infinitely often.
|
||||
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,
|
||||
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.
|
||||
///
|
||||
/// This function calls first nsa_to_nca() in order to retrieve som
|
||||
|
|
@ -127,7 +138,7 @@ namespace spot
|
|||
/// \a aut The automaton to convert.
|
||||
/// \a named_states name each state for easier debugging.
|
||||
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.
|
||||
///
|
||||
|
|
@ -149,13 +160,16 @@ namespace spot
|
|||
/// \a aut The automaton to convert.
|
||||
/// \a named_states name each state for easier debugging.
|
||||
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 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.
|
||||
/// 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_dca, nsa_to_dca,
|
||||
/// and a trivial implementation for deterministic weak automata.
|
||||
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 @@
|
|||
#include <spot/twaalgos/determinize.hh>
|
||||
#include <spot/twaalgos/alternation.hh>
|
||||
#include <spot/twaalgos/parity.hh>
|
||||
#include <spot/twaalgos/cobuchi.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
|
||||
namespace spot
|
||||
{
|
||||
|
|
@ -194,6 +196,7 @@ namespace spot
|
|||
if (type_ == BA || SBACC_)
|
||||
state_based_ = true;
|
||||
|
||||
bool via_gba = (type_ == BA) || (type_ == TGBA) || (type_ == Monitor);
|
||||
bool want_parity = (type_ & Parity) == Parity;
|
||||
if (COLORED_ && !want_parity)
|
||||
throw std::runtime_error("postprocessor: the Colored setting only works "
|
||||
|
|
@ -234,7 +237,7 @@ namespace spot
|
|||
!(type_ == Generic && PREF_ == Any && level_ == Low))
|
||||
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()))
|
||||
{
|
||||
a = to_generalized_buchi(a);
|
||||
|
|
@ -247,7 +250,8 @@ namespace spot
|
|||
|| type_ == TGBA
|
||||
|| (type_ == BA && a->is_sba())
|
||||
|| (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);
|
||||
|
||||
int original_acc = a->num_sets();
|
||||
|
|
@ -290,6 +294,8 @@ namespace spot
|
|||
{
|
||||
if (type_ == BA)
|
||||
a = do_degen(a);
|
||||
else if (type_ == CoBuchi)
|
||||
a = to_nca(a);
|
||||
return finalize(a);
|
||||
}
|
||||
|
||||
|
|
@ -552,6 +558,21 @@ namespace spot
|
|||
sim = dba ? dba : sim;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ namespace spot
|
|||
/// options used for debugging or benchmarking.
|
||||
postprocessor(const option_map* opt = nullptr);
|
||||
|
||||
enum output_type { TGBA = 0,
|
||||
BA = 1,
|
||||
enum output_type { TGBA = 0, // should be renamed GeneralizedBuchi
|
||||
BA = 1, // should be renamed Buchi and not imply SBAcc
|
||||
Monitor = 2,
|
||||
Generic = 3,
|
||||
Parity = 4,
|
||||
|
|
@ -85,6 +85,7 @@ namespace spot
|
|||
ParityMaxOdd = ParityMax | ParityOdd,
|
||||
ParityMinEven = ParityMin | ParityEven,
|
||||
ParityMaxEven = ParityMax | ParityEven,
|
||||
CoBuchi = 128,
|
||||
};
|
||||
|
||||
/// \brief Select the desired output type.
|
||||
|
|
@ -121,6 +122,10 @@ namespace spot
|
|||
/// but other parity types can be obtained from there by minor
|
||||
/// adjustments.
|
||||
///
|
||||
/// \a CoBuchi requests a Co-Büchi automaton equivalent to
|
||||
/// the input, when possible, or a Co-Büchi automaton that
|
||||
/// recognize a larger language otherwise.
|
||||
///
|
||||
/// If set_type() is not called, the default \c output_type is \c TGBA.
|
||||
void
|
||||
set_type(output_type type)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue