Commit 36f7c648 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

Make state_explicit instances persistent objects.

* src/tgba/tgbaexplicit.cc, src/tgba/tgbaexplicit.hh: Merge
state_explicit and tgba_explicit::state.  In the past,
state_explicit was a small object encapsulating a pointer to the
persistent tgba_explicit::state; and we used to clone() and
destroy() a lot of state_explicit instance.  Now state_explicit is
persistent, and clone() and destroy() have no effects.
* src/tgba/tgbareduce.cc: Adjust, since this inherits from
tgbaexplicit and uses the internals of state_explicit.
* src/tgbatest/reductgba.cc: Fix deletion order for automata.
* src/tgba/tgba.hh (last_support_conditions_input_,
last_support_variables_input_): Make these protected, so
they can be zeroed by tgba_explicit.
parent cd900a40
2011-03-31 Alexandre Duret-Lutz <adl@lrde.epita.fr>
Make state_explicit instances persistent objects.
* src/tgba/tgbaexplicit.cc, src/tgba/tgbaexplicit.hh: Merge
state_explicit and tgba_explicit::state. In the past,
state_explicit was a small object encapsulating a pointer to the
persistent tgba_explicit::state; and we used to clone() and
destroy() a lot of state_explicit instance. Now state_explicit is
persistent, and clone() and destroy() have no effects.
* src/tgba/tgbareduce.cc: Adjust, since this inherits from
tgbaexplicit and uses the internals of state_explicit.
* src/tgbatest/reductgba.cc: Fix deletion order for automata.
* src/tgba/tgba.hh (last_support_conditions_input_,
last_support_variables_input_): Make these protected, so
they can be zeroed by tgba_explicit.
2011-03-30 Alexandre Duret-Lutz <adl@lrde.epita.fr> 2011-03-30 Alexandre Duret-Lutz <adl@lrde.epita.fr>
Remove tgba_reduc::format_state(). Remove tgba_reduc::format_state().
......
...@@ -209,10 +209,11 @@ namespace spot ...@@ -209,10 +209,11 @@ namespace spot
virtual bdd compute_support_conditions(const state* state) const = 0; virtual bdd compute_support_conditions(const state* state) const = 0;
/// Do the actual computation of tgba::support_variables(). /// Do the actual computation of tgba::support_variables().
virtual bdd compute_support_variables(const state* state) const = 0; virtual bdd compute_support_variables(const state* state) const = 0;
private: protected:
mutable const state* last_support_conditions_input_; mutable const state* last_support_conditions_input_;
mutable bdd last_support_conditions_output_;
mutable const state* last_support_variables_input_; mutable const state* last_support_variables_input_;
private:
mutable bdd last_support_conditions_output_;
mutable bdd last_support_variables_output_; mutable bdd last_support_variables_output_;
mutable int num_acc_; mutable int num_acc_;
}; };
......
...@@ -37,7 +37,7 @@ namespace spot ...@@ -37,7 +37,7 @@ namespace spot
// tgba_explicit_succ_iterator // tgba_explicit_succ_iterator
tgba_explicit_succ_iterator::tgba_explicit_succ_iterator tgba_explicit_succ_iterator::tgba_explicit_succ_iterator
(const tgba_explicit::state* s, bdd all_acc) (const state_explicit::transitions_t* s, bdd all_acc)
: s_(s), all_acceptance_conditions_(all_acc) : s_(s), all_acceptance_conditions_(all_acc)
{ {
} }
...@@ -64,53 +64,47 @@ namespace spot ...@@ -64,53 +64,47 @@ namespace spot
tgba_explicit_succ_iterator::current_state() const tgba_explicit_succ_iterator::current_state() const
{ {
assert(!done()); assert(!done());
return new state_explicit((*i_)->dest); return const_cast<state_explicit*>(i_->dest);
} }
bdd bdd
tgba_explicit_succ_iterator::current_condition() const tgba_explicit_succ_iterator::current_condition() const
{ {
assert(!done()); assert(!done());
return (*i_)->condition; return i_->condition;
} }
bdd bdd
tgba_explicit_succ_iterator::current_acceptance_conditions() const tgba_explicit_succ_iterator::current_acceptance_conditions() const
{ {
assert(!done()); assert(!done());
return (*i_)->acceptance_conditions & all_acceptance_conditions_; return i_->acceptance_conditions & all_acceptance_conditions_;
} }
//////////////////////////////////////// ////////////////////////////////////////
// state_explicit // state_explicit
const tgba_explicit::state*
state_explicit::get_state() const
{
return state_;
}
int int
state_explicit::compare(const spot::state* other) const state_explicit::compare(const spot::state* other) const
{ {
const state_explicit* o = dynamic_cast<const state_explicit*>(other); const state_explicit* o = dynamic_cast<const state_explicit*>(other);
assert(o); assert(o);
return o->get_state() - get_state(); // Do not simply return "o - this", it might not fit in an int.
if (o < this)
return -1;
if (o > this)
return 1;
return 0;
} }
size_t size_t
state_explicit::hash() const state_explicit::hash() const
{ {
return return
reinterpret_cast<const char*>(get_state()) - static_cast<const char*>(0); reinterpret_cast<const char*>(this) - static_cast<const char*>(0);
} }
state_explicit*
state_explicit::clone() const
{
return new state_explicit(*this);
}
//////////////////////////////////////// ////////////////////////////////////////
// tgba_explicit // tgba_explicit
...@@ -131,12 +125,13 @@ namespace spot ...@@ -131,12 +125,13 @@ namespace spot
tgba_explicit::transition* tgba_explicit::transition*
tgba_explicit::create_transition(state* source, const state* dest) tgba_explicit::create_transition(state* source, const state* dest)
{ {
transition* t = new transition; transition t;
t->dest = dest; t.dest = dest;
t->condition = bddtrue; t.condition = bddtrue;
t->acceptance_conditions = bddfalse; t.acceptance_conditions = bddfalse;
source->push_back(t); state_explicit::transitions_t::iterator i =
return t; source->successors.insert(source->successors.end(), t);
return &*i;
} }
void void
tgba_explicit::add_condition(transition* t, const ltl::formula* f) tgba_explicit::add_condition(transition* t, const ltl::formula* f)
...@@ -219,7 +214,7 @@ namespace spot ...@@ -219,7 +214,7 @@ namespace spot
// Fix empty automata by adding a lone initial state. // Fix empty automata by adding a lone initial state.
if (!init_) if (!init_)
const_cast<tgba_explicit*>(this)->add_default_init(); const_cast<tgba_explicit*>(this)->add_default_init();
return new state_explicit(init_); return init_;
} }
tgba_succ_iterator* tgba_succ_iterator*
...@@ -231,7 +226,7 @@ namespace spot ...@@ -231,7 +226,7 @@ namespace spot
assert(s); assert(s);
(void) global_state; (void) global_state;
(void) global_automaton; (void) global_automaton;
return new tgba_explicit_succ_iterator(s->get_state(), return new tgba_explicit_succ_iterator(&s->successors,
all_acceptance_conditions()); all_acceptance_conditions());
} }
...@@ -240,12 +235,12 @@ namespace spot ...@@ -240,12 +235,12 @@ namespace spot
{ {
const state_explicit* s = dynamic_cast<const state_explicit*>(in); const state_explicit* s = dynamic_cast<const state_explicit*>(in);
assert(s); assert(s);
const state* st = s->get_state(); const state_explicit::transitions_t& st = s->successors;
bdd res = bddfalse; bdd res = bddfalse;
tgba_explicit::state::const_iterator i; state_explicit::transitions_t::const_iterator i;
for (i = st->begin(); i != st->end(); ++i) for (i = st.begin(); i != st.end(); ++i)
res |= (*i)->condition; res |= i->condition;
return res; return res;
} }
...@@ -254,12 +249,12 @@ namespace spot ...@@ -254,12 +249,12 @@ namespace spot
{ {
const state_explicit* s = dynamic_cast<const state_explicit*>(in); const state_explicit* s = dynamic_cast<const state_explicit*>(in);
assert(s); assert(s);
const state* st = s->get_state(); const state_explicit::transitions_t& st = s->successors;
bdd res = bddtrue; bdd res = bddtrue;
tgba_explicit::state::const_iterator i; state_explicit::transitions_t::const_iterator i;
for (i = st->begin(); i != st->end(); ++i) for (i = st.begin(); i != st.end(); ++i)
res &= bdd_support((*i)->condition); res &= bdd_support(i->condition);
return res; return res;
} }
...@@ -295,9 +290,6 @@ namespace spot ...@@ -295,9 +290,6 @@ namespace spot
// Do not erase the same state twice. (Because of possible aliases.) // Do not erase the same state twice. (Because of possible aliases.)
if (state_name_map_.erase(i->second)) if (state_name_map_.erase(i->second))
{ {
tgba_explicit::state::iterator i2;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2)
delete *i2;
delete i->second; delete i->second;
} }
} }
...@@ -314,7 +306,7 @@ namespace spot ...@@ -314,7 +306,7 @@ namespace spot
{ {
const state_explicit* se = dynamic_cast<const state_explicit*>(s); const state_explicit* se = dynamic_cast<const state_explicit*>(s);
assert(se); assert(se);
sn_map::const_iterator i = state_name_map_.find(se->get_state()); sn_map::const_iterator i = state_name_map_.find(se);
assert(i != state_name_map_.end()); assert(i != state_name_map_.end());
return i->second; return i->second;
} }
...@@ -324,9 +316,6 @@ namespace spot ...@@ -324,9 +316,6 @@ namespace spot
ns_map::iterator i = name_state_map_.begin(); ns_map::iterator i = name_state_map_.begin();
while (i != name_state_map_.end()) while (i != name_state_map_.end())
{ {
tgba_explicit::state::iterator i2;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2)
delete *i2;
// Advance the iterator before deleting the formula. // Advance the iterator before deleting the formula.
const ltl::formula* s = i->first; const ltl::formula* s = i->first;
delete i->second; delete i->second;
...@@ -345,7 +334,7 @@ namespace spot ...@@ -345,7 +334,7 @@ namespace spot
{ {
const state_explicit* se = dynamic_cast<const state_explicit*>(s); const state_explicit* se = dynamic_cast<const state_explicit*>(s);
assert(se); assert(se);
sn_map::const_iterator i = state_name_map_.find(se->get_state()); sn_map::const_iterator i = state_name_map_.find(se);
assert(i != state_name_map_.end()); assert(i != state_name_map_.end());
return ltl::to_string(i->second); return ltl::to_string(i->second);
} }
...@@ -354,14 +343,10 @@ namespace spot ...@@ -354,14 +343,10 @@ namespace spot
{ {
ns_map::iterator i = name_state_map_.begin(); ns_map::iterator i = name_state_map_.begin();
while (i != name_state_map_.end()) while (i != name_state_map_.end())
{ {
tgba_explicit::state::iterator i2; delete i->second;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2) ++i;
delete *i2; }
// Advance the iterator before deleting the state.
delete i->second;
++i;
}
} }
tgba_explicit::state* tgba_explicit_number::add_default_init() tgba_explicit::state* tgba_explicit_number::add_default_init()
...@@ -374,7 +359,7 @@ namespace spot ...@@ -374,7 +359,7 @@ namespace spot
{ {
const state_explicit* se = dynamic_cast<const state_explicit*>(s); const state_explicit* se = dynamic_cast<const state_explicit*>(s);
assert(se); assert(se);
sn_map::const_iterator i = state_name_map_.find(se->get_state()); sn_map::const_iterator i = state_name_map_.find(se);
assert(i != state_name_map_.end()); assert(i != state_name_map_.end());
std::stringstream ss; std::stringstream ss;
ss << i->second; ss << i->second;
......
...@@ -37,24 +37,66 @@ namespace spot ...@@ -37,24 +37,66 @@ namespace spot
class tgba_explicit_succ_iterator; class tgba_explicit_succ_iterator;
class tgba_explicit; class tgba_explicit;
/// Explicit representation of a spot::tgba. /// States used by spot::tgba_explicit.
/// \ingroup tgba_representation /// \ingroup tgba_representation
class tgba_explicit: public tgba class state_explicit: public spot::state
{ {
public: public:
tgba_explicit(bdd_dict* dict); state_explicit()
{
}
virtual int compare(const spot::state* other) const;
virtual size_t hash() const;
virtual state_explicit* clone() const
{
return const_cast<state_explicit*>(this);
}
bool empty() const
{
return successors.empty();
}
struct transition; virtual
typedef std::list<transition*> state; void destroy() const
{
}
/// Explicit transitions (used by spot::tgba_explicit). /// Explicit transitions.
struct transition struct transition
{ {
bdd condition; bdd condition;
bdd acceptance_conditions; bdd acceptance_conditions;
const state* dest; const state_explicit* dest;
}; };
typedef std::list<transition> transitions_t;
transitions_t successors;
private:
state_explicit(const state_explicit& other);
state_explicit& operator=(const state_explicit& other);
virtual ~state_explicit()
{
}
friend class tgba_explicit_string;
friend class tgba_explicit_formula;
friend class tgba_explicit_number;
};
/// Explicit representation of a spot::tgba.
/// \ingroup tgba_representation
class tgba_explicit: public tgba
{
public:
typedef state_explicit state;
typedef state_explicit::transition transition;
tgba_explicit(bdd_dict* dict);
/// Add a default initial state. /// Add a default initial state.
virtual state* add_default_init() = 0; virtual state* add_default_init() = 0;
...@@ -100,7 +142,7 @@ namespace spot ...@@ -100,7 +142,7 @@ namespace spot
bdd get_acceptance_condition(const ltl::formula* f); bdd get_acceptance_condition(const ltl::formula* f);
bdd_dict* dict_; bdd_dict* dict_;
tgba_explicit::state* init_; state_explicit* init_;
mutable bdd all_acceptance_conditions_; mutable bdd all_acceptance_conditions_;
bdd neg_acceptance_conditions_; bdd neg_acceptance_conditions_;
mutable bool all_acceptance_conditions_computed_; mutable bool all_acceptance_conditions_computed_;
...@@ -113,36 +155,13 @@ namespace spot ...@@ -113,36 +155,13 @@ namespace spot
/// States used by spot::tgba_explicit.
/// \ingroup tgba_representation
class state_explicit : public spot::state
{
public:
state_explicit(const tgba_explicit::state* s)
: state_(s)
{
}
virtual int compare(const spot::state* other) const;
virtual size_t hash() const;
virtual state_explicit* clone() const;
virtual ~state_explicit()
{
}
const tgba_explicit::state* get_state() const;
private:
const tgba_explicit::state* state_;
};
/// Successor iterators used by spot::tgba_explicit. /// Successor iterators used by spot::tgba_explicit.
/// \ingroup tgba_representation /// \ingroup tgba_representation
class tgba_explicit_succ_iterator: public tgba_succ_iterator class tgba_explicit_succ_iterator: public tgba_succ_iterator
{ {
public: public:
tgba_explicit_succ_iterator(const tgba_explicit::state* s, bdd all_acc); tgba_explicit_succ_iterator(const state_explicit::transitions_t* s,
bdd all_acc);
virtual void first(); virtual void first();
virtual void next(); virtual void next();
...@@ -153,8 +172,8 @@ namespace spot ...@@ -153,8 +172,8 @@ namespace spot
virtual bdd current_acceptance_conditions() const; virtual bdd current_acceptance_conditions() const;
private: private:
const tgba_explicit::state* s_; const state_explicit::transitions_t* s_;
tgba_explicit::state::const_iterator i_; state_explicit::transitions_t::const_iterator i_;
bdd all_acceptance_conditions_; bdd all_acceptance_conditions_;
}; };
...@@ -164,10 +183,10 @@ namespace spot ...@@ -164,10 +183,10 @@ namespace spot
{ {
protected: protected:
typedef label label_t; typedef label label_t;
typedef Sgi::hash_map<label, tgba_explicit::state*, typedef Sgi::hash_map<label, state_explicit*,
label_hash> ns_map; label_hash> ns_map;
typedef Sgi::hash_map<const tgba_explicit::state*, label, typedef Sgi::hash_map<const state_explicit*, label,
ptr_hash<tgba_explicit::state> > sn_map; ptr_hash<state_explicit> > sn_map;
ns_map name_state_map_; ns_map name_state_map_;
sn_map state_name_map_; sn_map state_name_map_;
public: public:
...@@ -178,7 +197,7 @@ namespace spot ...@@ -178,7 +197,7 @@ namespace spot
return name_state_map_.find(name) != name_state_map_.end(); return name_state_map_.find(name) != name_state_map_.end();
} }
const label& get_label(const tgba_explicit::state* s) const const label& get_label(const state_explicit* s) const
{ {
typename sn_map::const_iterator i = state_name_map_.find(s); typename sn_map::const_iterator i = state_name_map_.find(s);
assert(i != state_name_map_.end()); assert(i != state_name_map_.end());
...@@ -189,17 +208,17 @@ namespace spot ...@@ -189,17 +208,17 @@ namespace spot
{ {
const state_explicit* se = dynamic_cast<const state_explicit*>(s); const state_explicit* se = dynamic_cast<const state_explicit*>(s);
assert(se); assert(se);
return get_label(se->get_state()); return get_label(se);
} }
/// Return the tgba_explicit::state for \a name, creating the state if /// Return the state_explicit for \a name, creating the state if
/// it does not exist. /// it does not exist.
state* add_state(const label& name) state* add_state(const label& name)
{ {
typename ns_map::iterator i = name_state_map_.find(name); typename ns_map::iterator i = name_state_map_.find(name);
if (i == name_state_map_.end()) if (i == name_state_map_.end())
{ {
tgba_explicit::state* s = new tgba_explicit::state; state_explicit* s = new state_explicit;
name_state_map_[name] = s; name_state_map_[name] = s;
state_name_map_[s] = name; state_name_map_[s] = name;
...@@ -216,7 +235,7 @@ namespace spot ...@@ -216,7 +235,7 @@ namespace spot
state* state*
set_init_state(const label& state) set_init_state(const label& state)
{ {
tgba_explicit::state* s = add_state(state); state_explicit* s = add_state(state);
init_ = s; init_ = s;
return s; return s;
} }
...@@ -245,10 +264,11 @@ namespace spot ...@@ -245,10 +264,11 @@ namespace spot
typename ns_map::iterator i; typename ns_map::iterator i;
for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i) for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i)
{ {
tgba_explicit::state::iterator i2; state_explicit::transitions_t::iterator i2;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2) for (i2 = i->second->successors.begin();
i2 != i->second->successors.end(); ++i2)
{ {
(*i2)->acceptance_conditions = all - (*i2)->acceptance_conditions; i2->acceptance_conditions = all - i2->acceptance_conditions;
} }
} }
} }
...@@ -265,9 +285,10 @@ namespace spot ...@@ -265,9 +285,10 @@ namespace spot
typename ns_map::iterator i; typename ns_map::iterator i;
for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i) for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i)
{ {
tgba_explicit::state::iterator i2; state_explicit::transitions_t::iterator i2;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2) for (i2 = i->second->successors.begin();
(*i2)->acceptance_conditions &= neg; i2 != i->second->successors.end(); ++i2)
i2->acceptance_conditions &= neg;
} }
all_acceptance_conditions_computed_ = false; all_acceptance_conditions_computed_ = false;
...@@ -280,25 +301,25 @@ namespace spot ...@@ -280,25 +301,25 @@ namespace spot
typename ns_map::iterator i; typename ns_map::iterator i;
for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i) for (i = name_state_map_.begin(); i != name_state_map_.end(); ++i)
{ {
state::iterator t1; state_explicit::transitions_t::iterator t1;