// -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2014 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
#include "tgbaalgos/isdet.hh"
#include
#include
namespace spot
{
namespace
{
template
static
unsigned
count_nondet_states_aux(const const_tgba_ptr& aut)
{
unsigned res = 0;
typedef std::deque todo_list;
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;
for (auto i: aut->succ(src))
{
// If we know the state is nondeterministic, just skip the
// test for the remaining transitions. But don't break
// the loop, because we still have to record the
// destination states.
if (!nondeterministic)
{
bdd label = i->current_condition();
if (!bdd_implies(label, available))
nondeterministic = true;
else
available -= label;
}
const state* dst = i->current_state();
if (seen.insert(dst).second)
todo.push_back(dst);
else
dst->destroy();
}
res += nondeterministic;
if (!count && nondeterministic)
break;
}
for (state_set::const_iterator i = seen.begin(); i != seen.end();)
{
const state* s = *i++;
s->destroy();
}
return res;
}
}
unsigned
count_nondet_states(const const_tgba_ptr& aut)
{
return count_nondet_states_aux(aut);
}
bool
is_deterministic(const const_tgba_ptr& aut)
{
if (aut->is_deterministic())
return true;
return !count_nondet_states_aux(aut);
}
bool
is_complete(const const_tgba_ptr& aut)
{
state_set seen;
typedef std::deque todo_list;
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;
for (auto i: aut->succ(src))
{
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)
{
complete = false;
break;
}
}
for (state_set::const_iterator i = seen.begin(); i != seen.end();)
{
const state* s = *i++;
s->destroy();
}
return complete;
}
}