isdet: rewrite using the tgba_digraph interface

* src/tgbaalgos/isdet.cc, src/tgbaalgos/isdet.hh: Rewrite
using the tgba_digraph interface.
* src/tgbatest/ltl2tgba.cc: Adjust call.
This commit is contained in:
Alexandre Duret-Lutz 2015-01-11 13:58:52 +01:00
parent c85ba787e8
commit 6f7f9ef8bc
3 changed files with 36 additions and 86 deletions

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2014 Laboratoire de Recherche et // Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -28,66 +28,40 @@ namespace spot
template<bool count> template<bool count>
static static
unsigned unsigned
count_nondet_states_aux(const const_tgba_ptr& aut) count_nondet_states_aux(const const_tgba_digraph_ptr& aut)
{ {
unsigned res = 0; unsigned nondet_states = 0;
typedef std::deque<const state*> todo_list; unsigned ns = aut->num_states();
for (unsigned src = 0; src < ns; ++src)
state_set seen;
todo_list todo;
{
const state* s = aut->get_init_state();
seen.insert(s);
todo.push_back(s);
}
while (!todo.empty())
{ {
const state* src = todo.front();
todo.pop_front();
bool nondeterministic = false;
bdd available = bddtrue; bdd available = bddtrue;
for (auto i: aut->succ(src)) for (auto& t: aut->out(src))
{ if (!bdd_implies(t.cond, available))
// If we know the state is nondeterministic, just skip the {
// test for the remaining transitions. But don't break ++nondet_states;
// the loop, because we still have to record the break;
// destination states. }
if (!nondeterministic) else
{ {
bdd label = i->current_condition(); available -= t.cond;
if (!bdd_implies(label, available)) }
nondeterministic = true; // If we are not counting non-deterministic states, abort as
else // soon as possible.
available -= label; if (!count && nondet_states)
}
const state* dst = i->current_state();
if (seen.insert(dst).second)
todo.push_back(dst);
else
dst->destroy();
}
res += nondeterministic;
if (!count && nondeterministic)
break; break;
} }
for (state_set::const_iterator i = seen.begin(); i != seen.end();) return nondet_states;
{
const state* s = *i++;
s->destroy();
}
return res;
} }
} }
unsigned unsigned
count_nondet_states(const const_tgba_ptr& aut) count_nondet_states(const const_tgba_digraph_ptr& aut)
{ {
return count_nondet_states_aux<true>(aut); return count_nondet_states_aux<true>(aut);
} }
bool bool
is_deterministic(const const_tgba_ptr& aut) is_deterministic(const const_tgba_digraph_ptr& aut)
{ {
if (aut->is_deterministic()) if (aut->is_deterministic())
return true; return true;
@ -95,43 +69,19 @@ namespace spot
} }
bool bool
is_complete(const const_tgba_ptr& aut) is_complete(const const_tgba_digraph_ptr& aut)
{ {
state_set seen; unsigned ns = aut->num_states();
typedef std::deque<const state*> todo_list; for (unsigned src = 0; src < ns; ++src)
todo_list todo;
bool complete = true;
{
const state* s = aut->get_init_state();
seen.insert(s);
todo.push_back(s);
}
while (!todo.empty())
{ {
const state* src = todo.front();
todo.pop_front();
bdd available = bddtrue; bdd available = bddtrue;
for (auto i: aut->succ(src)) for (auto& t: aut->out(src))
{ available -= t.cond;
available -= i->current_condition();
const state* dst = i->current_state();
if (seen.insert(dst).second)
todo.push_back(dst);
else
dst->destroy();
}
if (available != bddfalse) if (available != bddfalse)
{ return false;
complete = false;
break;
}
} }
for (state_set::const_iterator i = seen.begin(); i != seen.end();) // The empty automaton is not complete since it does not have an
{ // initial state.
const state* s = *i++; return ns > 0;
s->destroy();
}
return complete;
} }
} }

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2014 Laboratoire de Recherche et // Copyright (C) 2012, 2013, 2014, 2015 Laboratoire de Recherche et
// Développement de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -20,7 +20,7 @@
#ifndef SPOT_TGBAALGOS_ISDET_HH #ifndef SPOT_TGBAALGOS_ISDET_HH
# define SPOT_TGBAALGOS_ISDET_HH # define SPOT_TGBAALGOS_ISDET_HH
# include "tgba/tgba.hh" # include "tgba/tgbagraph.hh"
namespace spot namespace spot
{ {
@ -33,7 +33,7 @@ namespace spot
/// but it is more efficient to call is_deterministic() if you do not /// but it is more efficient to call is_deterministic() if you do not
/// care about the number of nondeterministic states. /// care about the number of nondeterministic states.
SPOT_API unsigned SPOT_API unsigned
count_nondet_states(const const_tgba_ptr& aut); count_nondet_states(const const_tgba_digraph_ptr& aut);
/// \brief Return true iff \a aut is deterministic. /// \brief Return true iff \a aut is deterministic.
/// ///
@ -41,14 +41,14 @@ namespace spot
/// the automaton is nondeterministic, because it can return before /// the automaton is nondeterministic, because it can return before
/// the entire automaton has been explored. /// the entire automaton has been explored.
SPOT_API bool SPOT_API bool
is_deterministic(const const_tgba_ptr& aut); is_deterministic(const const_tgba_digraph_ptr& aut);
/// \brief Return true iff \a aut is complete. /// \brief Return true iff \a aut is complete.
/// ///
/// An automaton is complete if its translation relation is total, /// An automaton is complete if its translation relation is total,
/// i.e., each state as a successor for any possible configuration. /// i.e., each state as a successor for any possible configuration.
SPOT_API bool SPOT_API bool
is_complete(const const_tgba_ptr& aut); is_complete(const const_tgba_digraph_ptr& aut);
/// @} /// @}
} }

View file

@ -1638,7 +1638,7 @@ checked_main(int argc, char** argv)
case 13: case 13:
sub_stats_reachable(a).dump(std::cout); sub_stats_reachable(a).dump(std::cout);
std::cout << "nondeterministic states: " std::cout << "nondeterministic states: "
<< count_nondet_states(a) << std::endl; << count_nondet_states(ensure_digraph(a)) << std::endl;
break; break;
case 14: case 14:
if (!wdba_minimization_is_success) if (!wdba_minimization_is_success)