fix handling of Rabin-like input for dnf_to_dca()

The bug is mentioned by Maximilien Colange in a comment to issue #317,
but turned out to be unrelated to that original issue.

* spot/twaalgos/totgba.cc (dnf_to_streett): Save the correspondence
between the created states an the DNF clause in a named property.
* doc/org/concepts.org, spot/twaalgos/totgba.hh: Mention the new
property.
* spot/twaalgos/cobuchi.cc (save_inf_nca_st): Rewrite using the named
property.  Relying on seen marks and trying to deduce the matching
original clause could only work from plain Rabin.
* tests/core/dca.test: Add the test from Maximilien.
* NEWS: Mention the issue.
This commit is contained in:
Alexandre Duret-Lutz 2018-02-18 15:20:53 +01:00
parent 69f31c89c6
commit 81e5357e62
6 changed files with 63 additions and 54 deletions

View file

@ -134,38 +134,27 @@ namespace spot
unsigned nb_states_; // Number of states.
unsigned was_rabin_; // Was it Rabin before Streett?
std::vector<unsigned>* orig_states_; // Match old Rabin st. from new.
std::vector<unsigned>* orig_clauses_; // Associated Rabin clauses.
unsigned orig_num_st_; // Rabin original nb states.
// Keep information of states that are wanted to be seen infinitely
// often (cf Header).
void save_inf_nca_st(unsigned s, acc_cond::mark_t m,
vect_nca_info* nca_info)
void save_inf_nca_st(unsigned s, vect_nca_info* nca_info)
{
if (was_rabin_ && m)
const pair_state_nca& st = (*res_map_)[s];
auto bv = make_bitvect(orig_num_st_);
for (unsigned state : pmap_.states_of(st.second))
bv->set(state);
unsigned clause = 0;
unsigned state = st.first;
if (was_rabin_)
{
for (unsigned p = 0; p < nb_pairs_; ++p)
if (pairs_[p].fin || m & pairs_[p].inf)
{
const pair_state_nca& st = (*res_map_)[s];
auto bv = make_bitvect(orig_num_st_);
for (unsigned state : pmap_.states_of(st.second))
bv->set(state);
assert(!was_rabin_
|| ((int)(*orig_states_)[st.first] >= 0));
unsigned state = was_rabin_ ? (*orig_states_)[st.first]
: st.first;
unsigned clause_nb = was_rabin_ ? p / 2 : p;
nca_info->push_back(new nca_st_info(clause_nb, state, bv));
}
}
else if (!was_rabin_)
{
const pair_state_nca& st = (*res_map_)[s];
auto bv = make_bitvect(aut_->num_states());
for (unsigned state : pmap_.states_of(st.second))
bv->set(state);
nca_info->push_back(new nca_st_info(0, st.first, bv));
clause = (*orig_clauses_)[state];
assert((int)clause >= 0);
state = (*orig_states_)[state];
assert((int)state >= 0);
}
nca_info->push_back(new nca_st_info(clause, state, bv));
}
// Helper function that marks states that we want to see finitely often
@ -179,17 +168,11 @@ namespace spot
unsigned src_scc = si_.scc_of(s);
if (nca_is_inf_state[s])
{
acc_cond::mark_t m = 0u;
for (auto& e : res_->out(s))
{
if (nca_info && e.acc && (si_.scc_of(e.dst) == src_scc
|| state_based_))
m |= e.acc;
e.acc = 0u;
}
e.acc = 0U;
if (nca_info)
save_inf_nca_st(s, m, nca_info);
save_inf_nca_st(s, nca_info);
}
else
{
@ -223,11 +206,15 @@ namespace spot
| scc_info_options::TRACK_SUCCS)),
nb_states_(res_->num_states()),
was_rabin_(was_rabin),
orig_num_st_(orig_num_st)
orig_num_st_(orig_num_st ? orig_num_st : ref_prod->num_states())
{
if (was_rabin)
orig_states_ = ref_prod->get_named_prop<std::vector<unsigned>>
("original-states");
{
orig_states_ = ref_prod->get_named_prop<std::vector<unsigned>>
("original-states");
orig_clauses_ = ref_prod->get_named_prop<std::vector<unsigned>>
("original-clauses");
}
}
~nsa_to_nca_converter()

View file

@ -402,18 +402,22 @@ namespace spot
auto orig_states = new std::vector<unsigned>();
orig_states->resize(res_->num_states(), -1U);
res_->set_named_prop("original-states", orig_states);
auto orig_clauses = new std::vector<unsigned>();
orig_clauses->resize(res_->num_states(), -1U);
res_->set_named_prop("original-clauses", orig_clauses);
unsigned orig_num_states = in_->num_states();
for (unsigned orig = 0; orig < orig_num_states; ++orig)
{
if (!si_.is_useful_scc(si_.scc_of(orig)))
continue;
for (const auto& p : st_repr_[orig])
(*orig_states)[p.second] = orig;
{
(*orig_states)[p.second] = orig;
(*orig_clauses)[p.second] = p.first;
}
}
#if DEBUG
for (unsigned i = 1; i < orig_states->size(); ++i)
assert((int)(*orig_states)[i] >= 0);
#endif
}
set_acc_condition();

View file

@ -114,7 +114,9 @@ namespace spot
/// automaton and the original state of the input automaton. This is stored
/// in the "original-states" named property of the produced automaton. Call
/// `aut->get_named_prop<std::vector<unsigned>>("original-states")`
/// to retrieve it.
/// to retrieve it. Additionally, the correspondence between each created
/// state and the associated DNF clause is recorded in the
/// "original-clauses" property (also a vector of unsigned).
SPOT_API twa_graph_ptr
dnf_to_streett(const const_twa_graph_ptr& aut, bool original_states = false);
}