Commit a70589fe authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

remfin: fix handling of weak automata

* spot/twaalgos/remfin.cc: Do not add a sink states to deterministic
weak automata, and actually apply the "weak" Fin-removal to any weak
automaton.
* tests/core/explprod.test: Add a test case for the previous patch,
but that used to fail because of this bug.
* NEWS: Mention the bug.
parent 49266dee
...@@ -63,6 +63,9 @@ New in spot 2.1.2.dev (not yet released) ...@@ -63,6 +63,9 @@ New in spot 2.1.2.dev (not yet released)
already opened file descriptor, it will not close the file already opened file descriptor, it will not close the file
anymore. anymore.
* remove_fin() could produce incorrect result on incomplete
automata tagged as weak and deterministic.
New in spot 2.1.2 (2016-10-14) New in spot 2.1.2 (2016-10-14)
Command-line tools: Command-line tools:
......
...@@ -452,7 +452,7 @@ namespace spot ...@@ -452,7 +452,7 @@ namespace spot
} }
static twa_graph_ptr static twa_graph_ptr
remove_fin_det_weak(const const_twa_graph_ptr& aut) remove_fin_weak(const const_twa_graph_ptr& aut)
{ {
// Clone the original automaton. // Clone the original automaton.
auto res = make_twa_graph(aut, auto res = make_twa_graph(aut,
...@@ -462,42 +462,23 @@ namespace spot ...@@ -462,42 +462,23 @@ namespace spot
true, // determinisitic true, // determinisitic
true, // stutter inv. true, // stutter inv.
}); });
res->purge_dead_states();
scc_info si(res); scc_info si(res);
// We will modify res in place, and the resulting // We will modify res in place, and the resulting
// automaton will only have one acceptance set. // automaton will only have one acceptance set.
acc_cond::mark_t all_acc = res->set_buchi(); acc_cond::mark_t all_acc = res->set_buchi();
res->prop_state_acc(true); res->prop_state_acc(true);
res->prop_deterministic(true); unsigned n = res->num_states();
unsigned sink = res->num_states(); for (unsigned src = 0; src < n; ++src)
for (unsigned src = 0; src < sink; ++src)
{ {
acc_cond::mark_t acc = 0U; acc_cond::mark_t acc = 0U;
unsigned scc = si.scc_of(src); unsigned scc = si.scc_of(src);
if (si.is_accepting_scc(scc) && !si.is_trivial(scc)) if (si.is_accepting_scc(scc) && !si.is_trivial(scc))
acc = all_acc; acc = all_acc;
// Keep track of all conditions on edge leaving state
// SRC, so we can complete it.
bdd missingcond = bddtrue;
for (auto& t: res->out(src)) for (auto& t: res->out(src))
{ t.acc = acc;
missingcond -= t.cond;
t.acc = acc;
}
// Complete the original automaton.
if (missingcond != bddfalse)
{
if (res->num_states() == sink)
{
res->new_state();
res->new_acc_edge(sink, sink, bddtrue);
}
res->new_edge(src, sink, missingcond);
}
} }
//res->merge_edges();
return res; return res;
} }
} }
...@@ -507,9 +488,9 @@ namespace spot ...@@ -507,9 +488,9 @@ namespace spot
if (!aut->acc().uses_fin_acceptance()) if (!aut->acc().uses_fin_acceptance())
return std::const_pointer_cast<twa_graph>(aut); return std::const_pointer_cast<twa_graph>(aut);
// FIXME: we should check whether the automaton is weak. // FIXME: we should check whether the automaton is inherently weak.
if (aut->prop_inherently_weak().is_true() && is_deterministic(aut)) if (aut->prop_weak().is_true())
return remove_fin_det_weak(aut); return remove_fin_weak(aut);
if (auto maybe = streett_to_generalized_buchi_maybe(aut)) if (auto maybe = streett_to_generalized_buchi_maybe(aut))
return maybe; return maybe;
......
#!/bin/sh #!/bin/sh
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2008, 2009, 2013, 2014 Laboratoire de Recherche et # Copyright (C) 2008, 2009, 2013, 2014, 2016 Laboratoire de Recherche et
# Développement de l'Epita (LRDE). # Développement de l'Epita (LRDE).
# Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de # Copyright (C) 2003, 2004, 2005 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),
...@@ -99,4 +99,6 @@ EOF ...@@ -99,4 +99,6 @@ EOF
run 0 autfilt input1 --product input2 --hoa --small | tee stdout run 0 autfilt input1 --product input2 --hoa --small | tee stdout
run 0 autfilt -F stdout --isomorph expected run 0 autfilt -F stdout --isomorph expected
rm input1 input2 stdout expected # Reading two automata from stdin
ltl2tgba '!a' 'a U b' | autfilt --product=- - > aut1
ltl2tgba '!a&b' | autfilt -q --equivalent-to=aut1
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment