Implement a unicity table for states created by tgba_tba_proxy.

Suggested by Nikos Gorogiannis.

* src/tgba/tgbatba.hh (tgba_tba_proxy::create_state): New method.
(tgba_tba_proxy::uniq_map_): New attribute.
* src/tgba/tgbatba.cc (state_tba_proxy): Use the default
copy constructor.  Empty the destructor.  Implement an empty
destroy() method.  Use addresses for comparison.  Make clone()
a no-op.
(tgba_tba_proxy): Allocate and deallocate the unicity table.
Implement create_sates().
(tgba_tba_proxy, tgba_sba_proxy, tgba_tba_proxy_succ_iterator):
Adjust state construction to call create_state().
This commit is contained in:
Alexandre Duret-Lutz 2012-01-18 10:13:57 +01:00
parent 578c5894f5
commit 75032c9fc4
3 changed files with 100 additions and 20 deletions

View file

@ -1,3 +1,20 @@
2012-01-18 Alexandre Duret-Lutz <adl@lrde.epita.fr>
Implement a unicity table for states created by tgba_tba_proxy.
Suggested by Nikos Gorogiannis.
* src/tgba/tgbatba.hh (tgba_tba_proxy::create_state): New method.
(tgba_tba_proxy::uniq_map_): New attribute.
* src/tgba/tgbatba.cc (state_tba_proxy): Use the default
copy constructor. Empty the destructor. Implement an empty
destroy() method. Use addresses for comparison. Make clone()
a no-op.
(tgba_tba_proxy): Allocate and deallocate the unicity table.
Implement create_sates().
(tgba_tba_proxy, tgba_sba_proxy, tgba_tba_proxy_succ_iterator):
Adjust state construction to call create_state().
2012-01-17 Alexandre Duret-Lutz <adl@lrde.epita.fr> 2012-01-17 Alexandre Duret-Lutz <adl@lrde.epita.fr>
Minor speedups in tgba_safra_complement(). Minor speedups in tgba_safra_complement().

View file

@ -1,4 +1,4 @@
// Copyright (C) 2010, 2011 Laboratoire de Recherche et Développement de // Copyright (C) 2010, 2011, 2012 Laboratoire de Recherche et Développement de
// l'Epita. // l'Epita.
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris // Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
@ -45,18 +45,19 @@ namespace spot
{ {
} }
/// Copy constructor // Note: There is a default copy constructor, needed by
state_tba_proxy(const state_tba_proxy& o) // Sgi::hash_set. It does not clone the state "s", because the
: state(), // destructor will not destroy it either. Actually, the states
s_(o.real_state()->clone()), // are all destroyed in the tgba_tba_proxy destructor.
acc_(o.acceptance_iterator())
{
}
virtual virtual
~state_tba_proxy() ~state_tba_proxy()
{ {
s_->destroy(); }
void
destroy() const
{
} }
state* state*
@ -82,10 +83,12 @@ namespace spot
{ {
const state_tba_proxy* o = down_cast<const state_tba_proxy*>(other); const state_tba_proxy* o = down_cast<const state_tba_proxy*>(other);
assert(o); assert(o);
int res = s_->compare(o->real_state()); // Do not simply return "o - this", it might not fit in an int.
if (res != 0) if (o < this)
return res; return -1;
return acc_->id() - o->acceptance_cond().id(); if (o > this)
return 1;
return 0;
} }
virtual size_t virtual size_t
@ -97,7 +100,7 @@ namespace spot
virtual virtual
state_tba_proxy* clone() const state_tba_proxy* clone() const
{ {
return new state_tba_proxy(*this); return const_cast<state_tba_proxy*>(this);
} }
private: private:
@ -105,6 +108,30 @@ namespace spot
iterator acc_; iterator acc_;
}; };
struct state_tba_proxy_hash
{
size_t
operator()(const state_tba_proxy& s) const
{
return s.state_tba_proxy::hash();
}
};
struct state_tba_proxy_equal
{
bool
operator()(const state_tba_proxy& left,
const state_tba_proxy& right) const
{
if (left.acceptance_iterator() != right.acceptance_iterator())
return false;
return left.real_state()->compare(right.real_state()) == 0;
}
};
typedef Sgi::hash_set<state_tba_proxy,
state_tba_proxy_hash,
state_tba_proxy_equal> uniq_map_t;
typedef std::pair<const state_tba_proxy*, bool> state_ptr_bool_t; typedef std::pair<const state_tba_proxy*, bool> state_ptr_bool_t;
@ -267,7 +294,8 @@ namespace spot
while (next != expected && (acc & *next) == *next) while (next != expected && (acc & *next) == *next)
++next; ++next;
next_is_set: next_is_set:
state_tba_proxy* dest = new state_tba_proxy(odest, next); state_tba_proxy* dest =
down_cast<state_tba_proxy*>(aut->create_state(odest, next));
// Is DEST already reachable with the same value of ACCEPTING? // Is DEST already reachable with the same value of ACCEPTING?
state_ptr_bool_t key(dest, accepting); state_ptr_bool_t key(dest, accepting);
transmap_t::iterator id = transmap_.find(key); transmap_t::iterator id = transmap_.find(key);
@ -369,7 +397,7 @@ namespace spot
} // anonymous } // anonymous
tgba_tba_proxy::tgba_tba_proxy(const tgba* a) tgba_tba_proxy::tgba_tba_proxy(const tgba* a)
: a_(a) : a_(a), uniq_map_(new uniq_map_t)
{ {
// We will use one acceptance condition for this automata. // We will use one acceptance condition for this automata.
// Let's call it Acc[True]. // Let's call it Acc[True].
@ -421,12 +449,37 @@ namespace spot
++i; ++i;
s->destroy(); s->destroy();
} }
uniq_map_t* m = static_cast<uniq_map_t*>(uniq_map_);
uniq_map_t::const_iterator j = m->begin();
while (j != m->end())
{
const state* s = j->real_state();
++j;
s->destroy();
}
delete m;
} }
state*
tgba_tba_proxy::create_state(state* s, cycle_list::const_iterator acc) const
{
uniq_map_t* m = static_cast<uniq_map_t*>(uniq_map_);
state_tba_proxy st(s, acc);
std::pair<uniq_map_t::iterator, bool> res = m->insert(st);
if (!res.second)
s->destroy();
return const_cast<state_tba_proxy*>(&(*res.first));
}
state* state*
tgba_tba_proxy::get_init_state() const tgba_tba_proxy::get_init_state() const
{ {
return new state_tba_proxy(a_->get_init_state(), acc_cycle_.begin()); return create_state(a_->get_init_state(), acc_cycle_.begin());
} }
tgba_succ_iterator* tgba_succ_iterator*
@ -596,7 +649,7 @@ namespace spot
state* state*
tgba_sba_proxy::get_init_state() const tgba_sba_proxy::get_init_state() const
{ {
return new state_tba_proxy(a_->get_init_state(), cycle_start_); return create_state(a_->get_init_state(), cycle_start_);
} }
bool bool

View file

@ -1,5 +1,5 @@
// Copyright (C) 2010, 2011 Laboratoire de Recherche et Développement de // Copyright (C) 2010, 2011, 2012 Laboratoire de Recherche et
// l'Epita. // Développement de l'Epita.
// Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de Paris // Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de Paris
// 6 (LIP6), département Systèmes Répartis Coopératifs (SRC), // 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
// Université Pierre et Marie Curie. // Université Pierre et Marie Curie.
@ -97,12 +97,19 @@ namespace spot
/// then cached. /// then cached.
bdd union_acceptance_conditions_of_original_state(const state* s) const; bdd union_acceptance_conditions_of_original_state(const state* s) const;
/// \brief Create a degeneralized state using the unicity table.
///
/// This is an internal function. \a s should be a fresh state
/// from the source automaton.
state* create_state(state* s, cycle_list::const_iterator acc) const;
protected: protected:
virtual bdd compute_support_conditions(const state* state) const; virtual bdd compute_support_conditions(const state* state) const;
virtual bdd compute_support_variables(const state* state) const; virtual bdd compute_support_variables(const state* state) const;
cycle_list acc_cycle_; cycle_list acc_cycle_;
const tgba* a_; const tgba* a_;
private: private:
bdd the_acceptance_cond_; bdd the_acceptance_cond_;
typedef Sgi::hash_map<const state*, bdd, typedef Sgi::hash_map<const state*, bdd,
@ -110,6 +117,9 @@ namespace spot
mutable accmap_t accmap_; mutable accmap_t accmap_;
mutable accmap_t accmapu_; mutable accmap_t accmapu_;
/// Unicity table for degeneralized states. See create_state()
mutable void* uniq_map_;
// Disallow copy. // Disallow copy.
tgba_tba_proxy(const tgba_tba_proxy&); tgba_tba_proxy(const tgba_tba_proxy&);
tgba_tba_proxy& operator=(const tgba_tba_proxy&); tgba_tba_proxy& operator=(const tgba_tba_proxy&);