strength: generalize is_safety_automaton to any type of automata
Reported by Samuel Judson. * spot/twaalgos/strength.cc (is_safety_automaton): Reimplement it. * spot/twaalgos/strength.hh (is_safety_automaton): Update documentation. * tests/python/safety.py: New file. * tests/Makefile.am: Add it. * NEWS: Mention this change. * THANKS: Add Samuel.
This commit is contained in:
parent
e8c2b27ad2
commit
983964d037
6 changed files with 122 additions and 16 deletions
|
|
@ -23,6 +23,8 @@
|
|||
#include <spot/twaalgos/minimize.hh>
|
||||
#include <spot/twaalgos/isdet.hh>
|
||||
#include <spot/twaalgos/sccfilter.hh>
|
||||
#include <spot/twaalgos/contains.hh>
|
||||
#include <spot/twaalgos/stripacc.hh>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
|
@ -182,23 +184,55 @@ namespace spot
|
|||
{
|
||||
if (aut->acc().is_t())
|
||||
return true;
|
||||
if (!aut->is_existential())
|
||||
throw std::runtime_error
|
||||
("is_safety_automaton() does not support alternation");
|
||||
|
||||
bool need_si = !si;
|
||||
if (need_si)
|
||||
si = new scc_info(aut);
|
||||
std::unique_ptr<scc_info> localsi;
|
||||
if (!si)
|
||||
{
|
||||
localsi = std::make_unique<scc_info>(aut);
|
||||
si = localsi.get();
|
||||
}
|
||||
si->determine_unknown_acceptance();
|
||||
|
||||
bool res = true;
|
||||
unsigned scount = si->scc_count();
|
||||
for (unsigned scc = 0; scc < scount; ++scc)
|
||||
if (!si->is_trivial(scc) && si->is_rejecting_scc(scc))
|
||||
// a trim automaton without rejecting cycle is a safety automaton
|
||||
bool has_rejecting_cycle = false;
|
||||
|
||||
// first, look for rejecting SCCs.
|
||||
unsigned scccount = si->scc_count();
|
||||
for (unsigned scc = 0; scc < scccount; ++scc)
|
||||
if (si->is_useful_scc(scc)
|
||||
&& !si->is_trivial(scc)
|
||||
&& si->is_rejecting_scc(scc))
|
||||
{
|
||||
res = false;
|
||||
has_rejecting_cycle = true;
|
||||
break;
|
||||
}
|
||||
if (!has_rejecting_cycle && !aut->prop_inherently_weak().is_true())
|
||||
{
|
||||
// maybe we have rejecting cycles inside accepting SCCs?
|
||||
for (unsigned scc = 0; scc < scccount; ++scc)
|
||||
if (si->is_useful_scc(scc)
|
||||
&& !si->is_trivial(scc)
|
||||
&& si->is_accepting_scc(scc)
|
||||
&& scc_has_rejecting_cycle(*si, scc))
|
||||
{
|
||||
has_rejecting_cycle = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_rejecting_cycle)
|
||||
return true;
|
||||
|
||||
if (need_si)
|
||||
delete si;
|
||||
return res;
|
||||
// If the automaton has a rejecting loop and is deterministic, it
|
||||
// cannot be a safety automaton.
|
||||
if (is_universal(aut))
|
||||
return false;
|
||||
|
||||
twa_graph_ptr b = make_twa_graph(aut, twa::prop_set::all());
|
||||
strip_acceptance_here(b);
|
||||
return spot::contains(aut, b);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -104,12 +104,24 @@ namespace spot
|
|||
|
||||
/// \brief Check whether an automaton is a safety automaton.
|
||||
///
|
||||
/// A safety automaton has only accepting SCCs (or trivial
|
||||
/// SCCs).
|
||||
/// An automaton is a safety automaton if its acceptance condition
|
||||
/// can be changed to "true" without changing its language.
|
||||
///
|
||||
/// A minimized WDBA (as returned by a successful run of
|
||||
/// minimize_obligation()) represents safety property if it is a
|
||||
/// safety automaton.
|
||||
/// The test performed by this function differs depending on
|
||||
/// the nature of the input \a aut.
|
||||
///
|
||||
/// If \a aut is an automaton with `t` acceptance, it is necessarily
|
||||
/// a safety automaton.
|
||||
///
|
||||
/// Else we check for the absence of rejecting cycle in the
|
||||
/// useful part of the automaton. This absence is only a sufficient
|
||||
/// condition in the non-deterministic case, because a rejecting
|
||||
/// run might correspond to a word that is accepted by another run.
|
||||
///
|
||||
/// If the previous test could not conclude, we build the automaton
|
||||
/// B that is a copy of \a aut with acceptance set to true, and we
|
||||
/// check that \a aut contains all words of B. This last test
|
||||
/// requires complementing \a aut.
|
||||
///
|
||||
/// \param aut the automaton to check
|
||||
///
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue