complete: Fix completion of automata using Fin-acceptance

* src/tgba/acc.cc, src/tgba/acc.hh: Add a way to extract
an unstatisfiable mark, and fix the eval() function for
Fin acceptance.
* src/tgbaalgos/complete.cc: Label the sink state using
an unsatisfiable mark.  Do not assume generalized Büchi.
* src/tgbatest/complete.test: New test.
* src/tgbatest/Makefile.am: Add it.
This commit is contained in:
Alexandre Duret-Lutz 2015-03-25 20:00:27 +01:00
parent 7353e47f0c
commit 23bcbb5b37
5 changed files with 199 additions and 14 deletions

View file

@ -25,21 +25,26 @@ namespace spot
{
unsigned n = aut->num_states();
unsigned sink = -1U;
acc_cond::mark_t allacc = aut->acc().all_sets();
if (allacc == 0U)
// UM is a pair (bool, mark). If the Boolean is false, the
// acceptance is always satisfiable. Otherwise, MARK is an
// example of unsatisfiable mark.
auto um = aut->get_acceptance().unsat_mark();
if (!um.first)
{
// We cannot safely complete an automaton if it has no
// acceptance set as the added sink would become accepting.
// In this case, add an acceptance set to all transitions.
allacc = aut->set_buchi();
// We cannot safely complete an automaton if its
// acceptance is always satisfiable.
auto acc = aut->set_buchi();
for (auto& t: aut->transition_vector())
t.acc = allacc;
t.acc = acc;
}
else
{
// If some acceptance sets were used, loop over the states and
// seek a state that has only self loops, and that is not
// accepting. This will be our sink state.
// Loop over the states and seek a state that has only self
// loops, and that is not accepting. This will be our sink
// state. Note that we do not even have to ensure that the
// state is complete as we will complete the whole automaton
// in a second pass.
for (unsigned i = 0; i < n; ++i)
{
bool selfloop = true;
@ -53,8 +58,9 @@ namespace spot
}
accsum |= t.acc;
}
if (selfloop && accsum != allacc) // We have found a sink!
if (selfloop && !aut->acc().accepting(accsum))
{
// We have found a sink!
sink = i;
break;
}
@ -63,7 +69,7 @@ namespace spot
unsigned t = aut->num_transitions();
// Now complete all states (including the sink).
// Now complete all states (excluding any newly added the sink).
for (unsigned i = 0; i < n; ++i)
{
bdd missingcond = bddtrue;
@ -94,7 +100,7 @@ namespace spot
if (sink == -1U)
{
sink = aut->new_state();
++n;
aut->new_transition(sink, sink, bddtrue, um.second);
}
// In case the automaton use state-based acceptance, propagate
// the acceptance of the first transition to the one we add.