specialize scc_filter for inherently_weak automata
Part of issue #351. * spot/twaalgos/sccfilter.cc, spot/twaalgos/sccfilter.hh: Specialize for inherently-weak automata. * spot/twaalgos/postproc.cc: Simplify. * tests/core/dca2.test, tests/core/parity2.test, tests/core/prodor.test, tests/core/randomize.test, tests/python/automata.ipynb, tests/python/highlighting.ipynb, tests/python/product.ipynb, tests/python/remfin.py, tests/python/stutter-inv.ipynb: Adjust. * NEWS: Mention it.
This commit is contained in:
parent
2fad1ff6de
commit
95d732e331
13 changed files with 1245 additions and 2011 deletions
|
|
@ -38,7 +38,6 @@
|
|||
#include <spot/twaalgos/alternation.hh>
|
||||
#include <spot/twaalgos/parity.hh>
|
||||
#include <spot/twaalgos/cobuchi.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/rabin2parity.hh>
|
||||
|
||||
namespace spot
|
||||
|
|
@ -166,10 +165,7 @@ namespace spot
|
|||
{
|
||||
if (scc_filter_ == 0)
|
||||
return a;
|
||||
// If the automaton is weak, using transition-based acceptance
|
||||
// won't help, so let's preserve state-based acceptance.
|
||||
if ((state_based_ || a->prop_inherently_weak().is_true())
|
||||
&& a->prop_state_acc().is_true())
|
||||
if (state_based_ && a->prop_state_acc().is_true())
|
||||
return scc_filter_states(a, arg);
|
||||
else
|
||||
return scc_filter(a, arg);
|
||||
|
|
|
|||
|
|
@ -124,6 +124,53 @@ namespace spot
|
|||
}
|
||||
};
|
||||
|
||||
// Transform inherently weak automata into weak Büchi automata.
|
||||
template <bool buchi, class next_filter = id_filter>
|
||||
struct weak_filter: next_filter
|
||||
{
|
||||
acc_cond::mark_t acc_m = {0};
|
||||
acc_cond::mark_t rej_m = {};
|
||||
|
||||
template<typename... Args>
|
||||
weak_filter(scc_info* si, Args&&... args)
|
||||
: next_filter(si, std::forward<Args>(args)...)
|
||||
{
|
||||
if (!buchi)
|
||||
{
|
||||
acc_m = {};
|
||||
if (si->get_aut()->acc().is_co_buchi())
|
||||
rej_m = {0};
|
||||
}
|
||||
}
|
||||
|
||||
filtered_trans trans(unsigned src, unsigned dst,
|
||||
bdd cond, acc_cond::mark_t acc)
|
||||
{
|
||||
|
||||
bool keep;
|
||||
std::tie(keep, cond, acc) =
|
||||
this->next_filter::trans(src, dst, cond, acc);
|
||||
|
||||
if (keep)
|
||||
{
|
||||
unsigned ss = this->si->scc_of(src);
|
||||
if (this->si->is_accepting_scc(ss))
|
||||
acc = acc_m;
|
||||
else
|
||||
acc = rej_m;
|
||||
}
|
||||
return filtered_trans(keep, cond, acc);
|
||||
}
|
||||
|
||||
void fix_acceptance(const twa_graph_ptr& out)
|
||||
{
|
||||
if (buchi)
|
||||
out->set_buchi();
|
||||
else
|
||||
out->copy_acceptance_of(this->si->get_aut());
|
||||
}
|
||||
};
|
||||
|
||||
// Remove acceptance conditions from all edges outside of
|
||||
// non-accepting SCCs. If "RemoveAll" is false, keep those on
|
||||
// transitions entering accepting SCCs. If "PreserveSBA", is set
|
||||
|
|
@ -160,7 +207,7 @@ namespace spot
|
|||
unsigned v = this->si->scc_of(dst);
|
||||
// The basic rules are as follows:
|
||||
//
|
||||
// - If an edge is between two SCCs, is OK to remove
|
||||
// - If an edge is between two SCCs, it is OK to remove
|
||||
// all acceptance sets, as this edge cannot be part
|
||||
// of any loop.
|
||||
// - If an edge is in an non-accepting SCC, we can only
|
||||
|
|
@ -370,6 +417,10 @@ namespace spot
|
|||
scc_info* given_si)
|
||||
{
|
||||
twa_graph_ptr res;
|
||||
// For weak automata, scc_filter() is already doing the right
|
||||
// thing and preserves state-based acceptance.
|
||||
if (aut->prop_inherently_weak())
|
||||
return scc_filter(aut, remove_all_useless, given_si);
|
||||
if (remove_all_useless)
|
||||
res = scc_filter_apply<state_filter
|
||||
<acc_filter_mask<true, true>>>(aut, given_si);
|
||||
|
|
@ -385,9 +436,18 @@ namespace spot
|
|||
scc_info* given_si)
|
||||
{
|
||||
twa_graph_ptr res;
|
||||
// acc_filter_simplify only works for generalized Büchi
|
||||
if (aut->acc().is_generalized_buchi())
|
||||
if (aut->prop_inherently_weak())
|
||||
{
|
||||
if (aut->acc().is_t() || aut->acc().is_co_buchi())
|
||||
res =
|
||||
scc_filter_apply<state_filter<weak_filter<false>>>(aut, given_si);
|
||||
else
|
||||
res =
|
||||
scc_filter_apply<state_filter<weak_filter<true>>>(aut, given_si);
|
||||
}
|
||||
else if (aut->acc().is_generalized_buchi())
|
||||
{
|
||||
// acc_filter_simplify only works for generalized Büchi
|
||||
if (remove_all_useless)
|
||||
res =
|
||||
scc_filter_apply<state_filter
|
||||
|
|
@ -421,6 +481,11 @@ namespace spot
|
|||
false,
|
||||
true,
|
||||
});
|
||||
if (aut->prop_inherently_weak())
|
||||
{
|
||||
res->prop_weak(true);
|
||||
res->prop_state_acc(true);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015 Laboratoire de
|
||||
// Copyright (C) 2009, 2010, 2012, 2013, 2014, 2015, 2018 Laboratoire de
|
||||
// Recherche et Developpement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -50,13 +50,18 @@ namespace spot
|
|||
/// degeneralization) will work better if transitions going to an
|
||||
/// accepting SCC are accepting.
|
||||
///
|
||||
/// If the input is inherently weak, the output will be a weak
|
||||
/// automaton with state-based acceptance. The acceptance condition
|
||||
/// is set to Büchi unless the input was co-Büchi or t (in which
|
||||
/// case we keep this acceptance).
|
||||
///
|
||||
/// If \a given_sm is supplied, the function will use its result
|
||||
/// without computing a map of its own.
|
||||
///
|
||||
/// \warning Calling scc_filter on a TωA that has the SBA property
|
||||
/// (i.e., transitions leaving accepting states are all marked as
|
||||
/// accepting) may destroy this property. Use scc_filter_states()
|
||||
/// instead.
|
||||
/// \warning Calling scc_filter on a TωA that is not inherently weak
|
||||
/// and has the SBA property (i.e., transitions leaving accepting
|
||||
/// states are all marked as accepting) may destroy this property.
|
||||
/// Use scc_filter_states() instead.
|
||||
SPOT_API twa_graph_ptr
|
||||
scc_filter(const const_twa_graph_ptr& aut, bool remove_all_useless = false,
|
||||
scc_info* given_si = nullptr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue