* src/tgbaalgos/ndfs_result.hh: New file factorizing the computation of

accepting runs for ndfs emptiness check algoritms.
* src/tgbaalgos/Makefile.am: Add it.
* src/tgbaalgos/magic.cc, src/tgbaalgos/se05.cc,
src/tgbaalgos/tau03.cc, src/tgbaalgos/tau03opt.cc: Remove the old
result classes and use the new one.
This commit is contained in:
Denis Poitrenaud 2004-12-13 08:43:05 +00:00
parent abbd0eee07
commit 964f856bb5
7 changed files with 506 additions and 468 deletions

View file

@ -35,6 +35,7 @@
#include "emptiness.hh"
#include "emptiness_stats.hh"
#include "se05.hh"
#include "ndfs_result.hh"
/// FIXME: make compiling depedent the taking into account of weights.
@ -98,17 +99,17 @@ namespace spot
h.add_new_state(s0, CYAN);
push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue())
return new result(*this);
return new ndfs_result<se05_search<heap>, heap>(*this);
}
else
{
h.pop_notify(st_red.front().s);
pop(st_red);
if (!st_red.empty() && dfs_red())
return new result(*this);
return new ndfs_result<se05_search<heap>, heap>(*this);
else
if (dfs_blue())
return new result(*this);
return new ndfs_result<se05_search<heap>, heap>(*this);
}
return 0;
}
@ -127,26 +128,22 @@ namespace spot
return os;
}
const heap& get_heap() const
{
return h;
}
const stack_type& get_st_blue() const
{
return st_blue;
}
const stack_type& get_st_red() const
{
return st_red;
}
private:
struct stack_item
{
stack_item(const state* n, tgba_succ_iterator* i, bdd l, bdd a)
: s(n), it(i), label(l), acc(a) {};
/// The visited state.
const state* s;
/// Design the next successor of \a s which has to be visited.
tgba_succ_iterator* it;
/// The label of the transition traversed to reach \a s
/// (false for the first one).
bdd label;
/// The acceptance set of the transition traversed to reach \a s
/// (false for the first one).
bdd acc;
};
typedef std::list<stack_item> stack_type;
void push(stack_type& st, const state* s,
const bdd& label, const bdd& acc)
{
@ -325,60 +322,6 @@ namespace spot
return false;
}
class result: public emptiness_check_result
{
public:
result(se05_search& ms)
: emptiness_check_result(ms.automaton()), ms_(ms)
{
}
virtual tgba_run* accepting_run()
{
assert(!ms_.st_blue.empty());
assert(!ms_.st_red.empty());
tgba_run* run = new tgba_run;
typename stack_type::const_reverse_iterator i, j, end;
tgba_run::steps* l;
const state* target = ms_.st_red.front().s;
l = &run->prefix;
i = ms_.st_blue.rbegin();
end = ms_.st_blue.rend(); --end;
j = i; ++j;
for (; i != end; ++i, ++j)
{
if (l == &run->prefix && i->s->compare(target) == 0)
l = &run->cycle;
tgba_run::step s = { i->s->clone(), j->label, j->acc };
l->push_back(s);
}
if (l == &run->prefix && i->s->compare(target) == 0)
l = &run->cycle;
assert(l == &run->cycle);
j = ms_.st_red.rbegin();
tgba_run::step s = { i->s->clone(), j->label, j->acc };
l->push_back(s);
i = j; ++j;
end = ms_.st_red.rend(); --end;
for (; i != end; ++i, ++j)
{
tgba_run::step s = { i->s->clone(), j->label, j->acc };
l->push_back(s);
}
return run;
}
private:
se05_search& ms_;
};
};
class explicit_se05_search_heap
@ -491,6 +434,29 @@ namespace spot
{
}
bool has_been_visited(const state*& s) const
{
hcyan_type::const_iterator ic = hc.find(s);
if (ic==hc.end())
{
hash_type::const_iterator it = h.find(s);
if (it==h.end())
return false; // white state
if (s!=it->first)
{
delete s;
s = it->first;
}
return true; // blue or red state
}
if (s!=*ic)
{
delete s;
s = *ic;
}
return true; // cyan state
}
private:
hash_type h; // associate to each blue and red state its color
@ -580,6 +546,15 @@ namespace spot
delete s;
}
bool has_been_visited(const state*& s) const
{
hcyan_type::const_iterator ic = hc.find(s);
if (ic!=hc.end())
return true;
size_t ha = s->hash();
return color((h[ha%size] >> (ha%4)) & 3U) != WHITE;
}
private:
size_t size;
unsigned char* h;