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:
parent
2952daf0ba
commit
a5787937ef
5 changed files with 103 additions and 50 deletions
11
ChangeLog
11
ChangeLog
|
|
@ -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
2
NEWS
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
// SCC are numbered in topological order
|
// The "color". Even number correspond to
|
||||||
for (unsigned n = 0; n < scc_count; ++n)
|
// accepting SCCs.
|
||||||
{
|
std::vector<unsigned> d(scc_count);
|
||||||
bool acc = true;
|
|
||||||
bool is_useless = true;
|
|
||||||
|
|
||||||
if (sm.trivial(n))
|
// An even number larger than scc_count.
|
||||||
|
unsigned k = (scc_count | 1) + 1;
|
||||||
|
|
||||||
|
// SCC are numbered in topological order
|
||||||
|
// (but in the reverse order as Löding's)
|
||||||
|
for (unsigned m = 0; m < scc_count; ++m)
|
||||||
{
|
{
|
||||||
const scc_map::succ_type& succ = sm.succ(n);
|
bool is_useless = true;
|
||||||
if (succ.empty())
|
bool transient = sm.trivial(m);
|
||||||
|
const scc_map::succ_type& succ = sm.succ(m);
|
||||||
|
|
||||||
|
if (transient && succ.empty())
|
||||||
{
|
{
|
||||||
// A trivial SCC without successor is useless.
|
// A trivial SCC without successor is useless.
|
||||||
useless[n] = true;
|
useless[m] = true;
|
||||||
accepting[n] = false;
|
d[m] = k - 1;
|
||||||
// Do not add even add it to final or non_final.
|
|
||||||
continue;
|
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
|
|
||||||
// published in Information Processing Letters 79
|
|
||||||
// (2001) pp 105--109. Except we do not keep track
|
|
||||||
// of the actual color associated to each SCC.
|
|
||||||
|
|
||||||
// Also they are useless if all their successor are
|
|
||||||
// useless.
|
// useless.
|
||||||
for (scc_map::succ_type::const_iterator i = succ.begin();
|
unsigned l = k;
|
||||||
i != succ.end(); ++i)
|
for (scc_map::succ_type::const_iterator j = succ.begin();
|
||||||
|
j != succ.end(); ++j)
|
||||||
{
|
{
|
||||||
if (!useless[i->first])
|
is_useless &= useless[j->first];
|
||||||
|
unsigned dj = d[j->first];
|
||||||
|
if (dj < l)
|
||||||
|
l = dj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transient)
|
||||||
{
|
{
|
||||||
is_useless = false;
|
d[m] = l;
|
||||||
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());
|
||||||
|
|
|
||||||
|
|
@ -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
38
src/tgbatest/wdba2.test
Executable 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue