* src/tgbaalgos/tarjan_on_fly.hh,

src/tgbaalgos/tarjan_on_fly.cc,
src/tgbaalgos/nesteddfs.hh,
src/tgbaalgos/nesteddfs.cc,
src/tgbaalgos/minimalce.hh,
src/tgbaalgos/minimalce.cc,
src/tgbaalgos/colordfs.hh,
src/tgbaalgos/colordfs.cc: four new algorithms for emptyness check.

src/tgbaalgos/gtec/ce.hh,
src/tgbaalgos/gtec/ce.cc: Adapt the counter exemple for the ce
object in minimalce.hh.

src/tgbatest/ltl2tgba.cc,
src/tgbatest/emptchk.test,
src/tgbaalgos/Makefile.am: Add files for emptyness-check.


* src/tgbaalgos/reductgba_sim_del.cc: Restrict to degeneralize automata.
* src/tgba/tgbareduc.hh: src/tgba/tgbareduc.cc: Merge transition
for scc reduce.
This commit is contained in:
martinez 2004-08-23 12:48:33 +00:00
parent 3d2135c883
commit 2d1151e018
17 changed files with 2526 additions and 157 deletions

View file

@ -0,0 +1,258 @@
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// 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 2 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 Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#include "tgbaalgos/tarjan_on_fly.hh"
namespace spot
{
tarjan_on_fly::tarjan_on_fly(const tgba_tba_proxy *a)
: a(a), x(0)
{
}
tarjan_on_fly::~tarjan_on_fly()
{
for (stack_type::iterator i = stack.begin();
i != stack.end(); ++i)
{
if ((*i).s)
delete (*i).s;
if ((*i).lasttr)
delete (*i).lasttr;
}
}
ce::counter_example*
tarjan_on_fly::check()
{
std::cout << "tarjan_on_fly::check()" << std::endl;
clock();
top = dftop = -1;
violation = false;
const state* s = a->get_init_state();
push(s);
while (!violation && dftop >= 0)
{
//std::cout << "iter while" << std::endl;
s = stack[dftop].s;
std::cout << "s : " << a->format_state(s) << std::endl;
tgba_succ_iterator* iter = stack[dftop].lasttr;
if (iter == 0)
{
iter = a->succ_iter(s);
//std::cout << "iter->first" << std::endl;
iter->first();
stack[dftop].lasttr = iter;
}
else
{
//std::cout << "iter->next" << std::endl;
iter->next();
}
const state* succ = 0;
if (!iter->done())
{
succ = iter->current_state();
if (h.find(succ) == h.end())
push(succ);
else
{
int pos = in_stack(succ);
delete succ;
if (pos != -1) // succ is in stack
lowlinkupdate(dftop, pos);
}
}
else
pop();
}
tps_ = clock();
if (violation)
return build_counter();
//std::cout << "NO COUNTER EXAMPLE FOUND" << std::endl;
return 0;
}
void
tarjan_on_fly::push(const state* s)
{
std::cout << "tarjan_on_fly::push() : "
<< a->format_state(s) << " : " << std::endl;
h[s] = 1;
top++;
struct_state ss = { s, 0, top, dftop, 0, 0 };
if (a->state_is_accepting(s))
{
ss.acc = top;
x = s; // FIXME
}
else if (dftop >= 0)
ss.acc = stack[dftop].acc;
else
ss.acc = -1;
/*
std::cout << " lowlink : " << ss.lowlink << std::endl;
std::cout << " pre : " << ss.pre << std::endl;
std::cout << " acc : " << ss.acc << std::endl;
*/
if (top < (int)stack.size())
{
std::cout << "MAJ" << std::endl;
/*
const state* sdel = stack[top].s;
tgba_succ_iterator* iter = stack[top].lasttr;
*/
stack[top] = ss;
/*
delete sdel;
if (iter)
delete iter;
*/
}
else
{
std::cout << "INS" << std::endl;
stack.push_back(ss);
}
dftop = top;
}
void
tarjan_on_fly::pop()
{
std::cout << "tarjan_on_fly::pop()" << std::endl;
int p = stack[dftop].pre;
if (p >= 0)
lowlinkupdate(p, dftop);
if (stack[dftop].lowlink == dftop)
top = dftop - 1;
dftop = p;
}
void
tarjan_on_fly::lowlinkupdate(int f, int t)
{
/*
std::cout << "tarjan_on_fly::lowlinkupdate() : " << std::endl
<< " stack[t].lowlink : " << stack[t].lowlink
<< " stack[f].lowlink : " << stack[f].lowlink
<< " stack[f].acc : " << stack[f].acc
<< std::endl;
*/
if (stack[t].lowlink <= stack[f].lowlink)
{
if (stack[t].lowlink <= stack[f].acc)
{
violation = true;
std::cout << "VIOLATION DETECTED" << std::endl;
}
stack[f].lowlink = stack[t].lowlink;
}
}
int
tarjan_on_fly::in_stack(const state* s) const
{
std::cout << "tarjan_on_fly::in_stack() : "
<< a->format_state(s) << std::endl;
int n = 0;
stack_type::const_iterator i;
for (i = stack.begin(); i != stack.end(); ++i, ++n)
if (s->compare((*i).s) == 0)
break;
if (i == stack.end())
return -1;
return n;
}
ce::counter_example*
tarjan_on_fly::build_counter()
{
std::cout << "tarjan_on_fly::build_counter()" << std::endl;
ce = new ce::counter_example(a);
stack_type::iterator i;
for (i = stack.begin(); i != stack.end(); ++i)
{
if (x && x->compare((*i).s) == 0)
break;
//os << " " << a->format_state(i->first) << std::endl;
ce->prefix.push_back(ce::state_ce((*i).s->clone(),
//bddtrue));
(*i).lasttr->current_condition()));
}
for (; i != stack.end(); ++i)
{
//os << " " << a->format_state(i->first) << std::endl;
ce->cycle.push_back(ce::state_ce((*i).s->clone(),
//bddtrue));
(*i).lasttr->current_condition()));
}
return ce;
}
std::ostream&
tarjan_on_fly::print_stat(std::ostream& os) const
{
int ce_size = 0;
if (ce)
ce_size = ce->size();
os << "Size of Counter Example : " << ce_size << std::endl
<< "States explored : " << h.size() << std::endl
<< "Computed time : " << tps_ << " microseconds" << std::endl;
return os;
}
}