Automata with no state are no longer allowed.

* NEWS, spot/twa/twa.hh: Document the change.
* spot/twa/twagraph.hh, spot/kripke/kripkegraph.hh:
  Add an exception in get_init_state_number().
  get_init_state() now calls get_init_state_number().
* spot/twa/twagraph.cc, spot/twaalgos/simulation.cc,
  spot/twaalgos/powerset.cc, spot/twaalgos/complete.cc,
  spot/twaalgos/sccfilter.cc: Remove now useless tests.
* spot/twaalgos/hoa.cc: Remove now useless comment.
* spot/twaalgos/minimize.cc: Never return an automaton with no state.
This commit is contained in:
Maximilien Colange 2016-11-25 13:42:13 +01:00
parent da6fc955a3
commit b3ee68310f
11 changed files with 24 additions and 38 deletions

View file

@ -595,7 +595,8 @@ namespace spot
/// Browsing a TωA is usually achieved using two methods: \c
/// get_init_state(), and succ(). The former returns the initial
/// state while the latter allows iterating over the outgoing edges
/// of any given state.
/// of any given state. A TωA is always assumed to have at least
/// one state, the initial one.
///
/// Note that although this is a transition-based automata, we never
/// represent edges in the API. Information about edges can be
@ -605,7 +606,7 @@ namespace spot
/// The interface presented here is what we call the on-the-fly
/// interface of automata, because the TωA class can be subclassed
/// to implement an object that computes its successors on-the-fly.
/// The down-side is that all these methods are virtual, so you you
/// The down-side is that all these methods are virtual, so you
/// pay the cost of virtual calls when iterating over automata
/// constructed on-the-fly. Also the interface assumes that each
/// successor state is a new object whose memory management is the

View file

@ -154,8 +154,6 @@ namespace spot
void twa_graph::purge_unreachable_states()
{
unsigned num_states = g_.num_states();
if (SPOT_UNLIKELY(num_states == 0))
return;
// The TODO vector serves two purposes:
// - it is a stack of state to process,
// - it is a set of processed states.
@ -166,7 +164,7 @@ namespace spot
std::vector<unsigned> todo(num_states, 0);
const unsigned seen = 1 << (sizeof(unsigned)*8-1);
const unsigned mask = seen - 1;
todo[0] = init_number_;
todo[0] = get_init_state_number();
todo[init_number_] |= seen;
unsigned todo_pos = 1;
do
@ -197,16 +195,13 @@ namespace spot
void twa_graph::purge_dead_states()
{
unsigned num_states = g_.num_states();
if (num_states == 0)
return;
std::vector<unsigned> useful(num_states, 0);
// Make a DFS to compute a topological order.
std::vector<unsigned> order;
order.reserve(num_states);
std::vector<std::pair<unsigned, unsigned>> todo; // state, trans
useful[init_number_] = 1;
useful[get_init_state_number()] = 1;
todo.emplace_back(init_number_, g_.state_storage(init_number_).succ);
do
{

View file

@ -264,16 +264,15 @@ namespace spot
state_num get_init_state_number() const
{
// If the automaton has no state, it has no initial state.
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
throw std::runtime_error("automaton has no state at all");
return init_number_;
}
virtual const twa_graph_state* get_init_state() const override
{
if (num_states() == 0)
const_cast<graph_t&>(g_).new_state();
return state_from_number(init_number_);
return state_from_number(get_init_state_number());
}
virtual twa_succ_iterator*