minimize_wdba() failed to fully minimize some automata.

* src/tgbaalgos/minimize.cc (minimize_wdba): Fix the Löding
algorithm to use colors.  The previous implementation was an
incorrect approximation.
* src/tgbatest/wdba2.test: New file showing two equivalent
formulas that were minimized in automata with different sizes.
* src/tgbatest/Makefile.am: Add it.
This commit is contained in:
Alexandre Duret-Lutz 2012-01-17 12:11:33 +01:00
parent 2952daf0ba
commit a5787937ef
5 changed files with 103 additions and 50 deletions

View file

@ -1,3 +1,14 @@
2012-01-17 Alexandre Duret-Lutz <adl@lrde.epita.fr>
minimize_wdba() failed to fully minimize some automata.
* src/tgbaalgos/minimize.cc (minimize_wdba): Fix the Löding
algorithm to use colors. The previous implementation was an
incorrect approximation.
* src/tgbatest/wdba2.test: New file showing two equivalent
formulas that were minimized in automata with different sizes.
* src/tgbatest/Makefile.am: Add it.
2012-01-13 Alexandre Duret-Lutz <adl@lrde.epita.fr> 2012-01-13 Alexandre Duret-Lutz <adl@lrde.epita.fr>
* NEWS: Update with recent fixes. * NEWS: Update with recent fixes.

2
NEWS
View file

@ -3,6 +3,8 @@ New in spot 0.8.1a:
* Bug fixes: * Bug fixes:
- spot::ltl::length() forgot to count the '&' and '|' operators - spot::ltl::length() forgot to count the '&' and '|' operators
in an LTL formula. in an LTL formula.
- minimize_wdba() could fail to mark some transiant SCCs as accepting,
producing an automaton that was not fully minimized.
- minimize_dfa() could produce incorrect automata, but it's not - minimize_dfa() could produce incorrect automata, but it's not
clear whether this could have had an inpact on WDBA minimization clear whether this could have had an inpact on WDBA minimization
(the worse case is that some TGBA would not have been minimized (the worse case is that some TGBA would not have been minimized

View file

@ -531,83 +531,84 @@ namespace spot
power_map pm; power_map pm;
det_a = tgba_powerset(a, pm); det_a = tgba_powerset(a, pm);
// For each SCC of the deterministic automaton, determine if // For each SCC of the deterministic automaton, determine if it
// it is accepting or not. // is accepting or not.
// This corresponds to the algorithm in Fig. 1 of "Efficient
// minimization of deterministic weak omega-automata" written by
// Christof Löding and published in Information Processing
// Letters 79 (2001) pp 105--109.
// We also keep track of whether an SCC is useless
// (i.e., it is not the start of any accepting word).
scc_map sm(det_a); scc_map sm(det_a);
sm.build_map(); sm.build_map();
unsigned scc_count = sm.scc_count(); unsigned scc_count = sm.scc_count();
// SCC that have been marked as accepting.
std::vector<bool> accepting(scc_count);
// SCC that have been marked as useless. // SCC that have been marked as useless.
std::vector<bool> useless(scc_count); std::vector<bool> useless(scc_count);
// The "color". Even number correspond to
// accepting SCCs.
std::vector<unsigned> d(scc_count);
// An even number larger than scc_count.
unsigned k = (scc_count | 1) + 1;
// SCC are numbered in topological order // SCC are numbered in topological order
for (unsigned n = 0; n < scc_count; ++n) // (but in the reverse order as Löding's)
for (unsigned m = 0; m < scc_count; ++m)
{ {
bool acc = true;
bool is_useless = true; bool is_useless = true;
bool transient = sm.trivial(m);
const scc_map::succ_type& succ = sm.succ(m);
if (sm.trivial(n)) if (transient && succ.empty())
{ {
const scc_map::succ_type& succ = sm.succ(n); // A trivial SCC without successor is useless.
if (succ.empty()) useless[m] = true;
{ d[m] = k - 1;
// A trivial SCC without successor is useless. continue;
useless[n] = true; }
accepting[n] = false;
// Do not add even add it to final or non_final.
continue;
}
// Trivial SCCs are accepting if all their
// useful successors are accepting.
// This corresponds to the algorithm in Fig. 1 of // Compute the minimum color l of the successors.
// "Efficient minimization of deterministic weak // Also SCCs are useless if all their successor are
// omega-automata" written by Christof Löding and // useless.
// published in Information Processing Letters 79 unsigned l = k;
// (2001) pp 105--109. Except we do not keep track for (scc_map::succ_type::const_iterator j = succ.begin();
// of the actual color associated to each SCC. j != succ.end(); ++j)
{
is_useless &= useless[j->first];
unsigned dj = d[j->first];
if (dj < l)
l = dj;
}
// Also they are useless if all their successor are if (transient)
// useless. {
for (scc_map::succ_type::const_iterator i = succ.begin(); d[m] = l;
i != succ.end(); ++i)
{
if (!useless[i->first])
{
is_useless = false;
acc &= accepting[i->first];
}
}
} }
else else
{ {
// Regular SCCs are accepting if any of their loop // Regular SCCs are accepting if any of their loop
// corresponds to an accepted word in the original // corresponds to an accepted word in the original
// automaton. // automaton.
acc = wdba_scc_is_accepting(det_a, n, a, sm, pm); if (wdba_scc_is_accepting(det_a, m, a, sm, pm))
if (acc)
{ {
is_useless = false; is_useless = false;
d[m] = (l | 1) - 1; // largest even number inferior or equal
} }
else else
{ {
// Unaccepting SCCs are useless if their successors d[m] = (l - 1) | 1; // largest odd number inferior or equal
// are all useless.
const scc_map::succ_type& succ = sm.succ(n);
for (scc_map::succ_type::const_iterator i = succ.begin();
i != succ.end(); ++i)
is_useless &= useless[i->first];
} }
} }
useless[n] = is_useless; useless[m] = is_useless;
accepting[n] = acc;
if (!is_useless) if (!is_useless)
{ {
hash_set* dest_set = acc ? final : non_final; hash_set* dest_set = (d[m]&1) ? non_final : final;
const std::list<const state*>& l = sm.states_of(n); const std::list<const state*>& l = sm.states_of(m);
std::list<const state*>::const_iterator il; std::list<const state*>::const_iterator il;
for (il = l.begin(); il != l.end(); ++il) for (il = l.begin(); il != l.end(); ++il)
dest_set->insert((*il)->clone()); dest_set->insert((*il)->clone());

View file

@ -1,5 +1,5 @@
## Copyright (C) 2009, 2010, 2011 Laboratoire de Recherche et Développement ## Copyright (C) 2009, 2010, 2011, 2012 Laboratoire de Recherche et
## de l'Epita (LRDE). ## Développement de l'Epita (LRDE).
## Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de ## Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
## Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), ## Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
## Université Pierre et Marie Curie. ## Université Pierre et Marie Curie.
@ -100,6 +100,7 @@ TESTS = \
sccsimpl.test \ sccsimpl.test \
obligation.test \ obligation.test \
wdba.test \ wdba.test \
wdba2.test \
babiak.test \ babiak.test \
randtgba.test \ randtgba.test \
emptchk.test \ emptchk.test \

38
src/tgbatest/wdba2.test Executable file
View file

@ -0,0 +1,38 @@
#!/bin/sh
# Copyright (C) 2012 Laboratoire de Recherche et Développement
# de l'Epita (LRDE).
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Spot; see the file COPYING. If not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
. ./defs
set -e
cat >expected <<EOF
sub trans.: 16
transitions: 8
states: 4
EOF
# These two equivalent formulae used to produce
# minimized automata of different sizes...
run 0 ../ltl2tgba -Rm -kt 'a | X(Gd|Fa)' > out
run 0 ../ltl2tgba -Rm -kt 'Fa | XGd' > out2
cmp out expected
cmp out2 expected