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:
parent
69f31c89c6
commit
81e5357e62
6 changed files with 63 additions and 54 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue