* src/tgba/taa.cc, src/tgba/taa.hh: Speed up the cartesian product
in taa_succ_iterator and allow multiple initial states in taa. * src/tgba/ltl2taa.cc: Remove temporary printing.
This commit is contained in:
parent
eab1261437
commit
11ecdf2b86
4 changed files with 84 additions and 46 deletions
|
|
@ -1,3 +1,9 @@
|
||||||
|
2009-11-07 Damien Lefortier <dam@lrde.epita.fr>
|
||||||
|
|
||||||
|
* src/tgba/taa.cc, src/tgba/taa.hh: Speed up the cartesian product
|
||||||
|
in taa_succ_iterator and allow multiple initial states in taa.
|
||||||
|
* src/tgba/ltl2taa.cc: Remove temporary printing.
|
||||||
|
|
||||||
2009-11-05 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
2009-11-05 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
|
|
||||||
Fix ltlcounter.test for VPATH builds and n > 2.
|
Fix ltlcounter.test for VPATH builds and n > 2.
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "ltlvisit/destroy.hh"
|
#include "ltlvisit/destroy.hh"
|
||||||
#include "tgba/formula2bdd.hh"
|
#include "tgba/formula2bdd.hh"
|
||||||
|
|
@ -61,7 +62,15 @@ namespace spot
|
||||||
void
|
void
|
||||||
taa::set_init_state(const std::string& s)
|
taa::set_init_state(const std::string& s)
|
||||||
{
|
{
|
||||||
init_ = add_state(s);
|
std::vector<std::string> v;
|
||||||
|
v.push_back(s);
|
||||||
|
set_init_state(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
taa::set_init_state(const std::vector<std::string>& s)
|
||||||
|
{
|
||||||
|
init_ = add_state_set(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
taa::transition*
|
taa::transition*
|
||||||
|
|
@ -141,9 +150,7 @@ namespace spot
|
||||||
state*
|
state*
|
||||||
taa::get_init_state() const
|
taa::get_init_state() const
|
||||||
{
|
{
|
||||||
taa::state_set* s = new taa::state_set;
|
return new spot::state_set(init_);
|
||||||
s->insert(init_);
|
|
||||||
return new spot::state_set(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tgba_succ_iterator*
|
tgba_succ_iterator*
|
||||||
|
|
@ -233,12 +240,6 @@ namespace spot
|
||||||
taa::state* s = new taa::state;
|
taa::state* s = new taa::state;
|
||||||
name_state_map_[name] = s;
|
name_state_map_[name] = s;
|
||||||
state_name_map_[s] = name;
|
state_name_map_[s] = name;
|
||||||
|
|
||||||
// The first state we add is the inititial state.
|
|
||||||
// It can also be overridden with set_init_state().
|
|
||||||
if (!init_)
|
|
||||||
init_ = s;
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
return i->second;
|
return i->second;
|
||||||
|
|
@ -352,13 +353,18 @@ namespace spot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<iterator> pos;
|
bounds_t bounds;
|
||||||
std::vector<std::pair<iterator, iterator> > bounds;
|
|
||||||
for (taa::state_set::const_iterator i = s->begin(); i != s->end(); ++i)
|
for (taa::state_set::const_iterator i = s->begin(); i != s->end(); ++i)
|
||||||
{
|
|
||||||
pos.push_back((*i)->begin());
|
|
||||||
bounds.push_back(std::make_pair((*i)->begin(), (*i)->end()));
|
bounds.push_back(std::make_pair((*i)->begin(), (*i)->end()));
|
||||||
}
|
|
||||||
|
/// Sorting might make the cartesian product faster by not
|
||||||
|
/// exploring all possibilities.
|
||||||
|
std::sort(bounds.begin(), bounds.end(), distance_sort());
|
||||||
|
|
||||||
|
std::vector<iterator> pos;
|
||||||
|
pos.reserve(bounds.size());
|
||||||
|
for (bounds_t::const_iterator i = bounds.begin(); i != bounds.end(); ++i)
|
||||||
|
pos.push_back(i->first);
|
||||||
|
|
||||||
while (pos[0] != bounds[0].second)
|
while (pos[0] != bounds[0].second)
|
||||||
{
|
{
|
||||||
|
|
@ -366,39 +372,50 @@ namespace spot
|
||||||
t->condition = bddtrue;
|
t->condition = bddtrue;
|
||||||
t->acceptance_conditions = bddfalse;
|
t->acceptance_conditions = bddfalse;
|
||||||
taa::state_set* ss = new taa::state_set;
|
taa::state_set* ss = new taa::state_set;
|
||||||
for (unsigned i = 0; i < pos.size(); ++i)
|
|
||||||
|
unsigned p;
|
||||||
|
for (p = 0; p < pos.size() && t->condition != bddfalse; ++p)
|
||||||
{
|
{
|
||||||
taa::state_set::const_iterator j;
|
taa::state_set::const_iterator j;
|
||||||
for (j = (*pos[i])->dst->begin(); j != (*pos[i])->dst->end(); ++j)
|
for (j = (*pos[p])->dst->begin(); j != (*pos[p])->dst->end(); ++j)
|
||||||
if ((*j)->size() > 0) // Remove well states.
|
if ((*j)->size() > 0) // Remove sink states.
|
||||||
ss->insert(*j);
|
ss->insert(*j);
|
||||||
|
|
||||||
// Fill the new transition.
|
// Fill the new transition.
|
||||||
t->dst = ss;
|
t->dst = ss;
|
||||||
t->condition &= (*pos[i])->condition;
|
t->condition &= (*pos[p])->condition;
|
||||||
t->acceptance_conditions |= (*pos[i])->acceptance_conditions;
|
t->acceptance_conditions |= (*pos[p])->acceptance_conditions;
|
||||||
}
|
}
|
||||||
// Look for another transition to merge with.
|
// If p != pos.size() we have found a contradiction
|
||||||
|
assert(p > 0);
|
||||||
|
|
||||||
|
// If no contradiction, then look for another transition to
|
||||||
|
// merge with the new one.
|
||||||
seen_map::iterator i;
|
seen_map::iterator i;
|
||||||
for (i = seen_.find(*ss); i != seen_.end(); ++i)
|
if (t->condition != bddfalse)
|
||||||
{
|
{
|
||||||
if (*i->second->dst == *t->dst
|
for (i = seen_.find(ss); i != seen_.end(); ++i)
|
||||||
&& i->second->condition == t->condition)
|
|
||||||
{
|
{
|
||||||
i->second->acceptance_conditions &= t->acceptance_conditions;
|
if (*i->second->dst == *t->dst
|
||||||
break;
|
&& i->second->condition == t->condition)
|
||||||
}
|
{
|
||||||
if (*i->second->dst == *t->dst
|
i->second->acceptance_conditions &= t->acceptance_conditions;
|
||||||
&& i->second->acceptance_conditions == t->acceptance_conditions)
|
break;
|
||||||
{
|
}
|
||||||
i->second->condition |= t->condition;
|
if (*i->second->dst == *t->dst
|
||||||
break;
|
&& i->second->acceptance_conditions == t->acceptance_conditions)
|
||||||
|
{
|
||||||
|
i->second->condition |= t->condition;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Mark this transition as seen and keep it, or delete it.
|
// Mark the new transition as seen and keep it if we have not
|
||||||
if (i == seen_.end() && t->condition != bddfalse)
|
// found any contraction and no other transition to merge with,
|
||||||
|
// or delete it otherwise.
|
||||||
|
if (t->condition != bddfalse && i == seen_.end())
|
||||||
{
|
{
|
||||||
seen_.insert(std::make_pair(*ss, t));
|
seen_.insert(std::make_pair(ss, t));
|
||||||
succ_.push_back(t);
|
succ_.push_back(t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -409,8 +426,9 @@ namespace spot
|
||||||
|
|
||||||
for (int i = pos.size() - 1; i >= 0; --i)
|
for (int i = pos.size() - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
if (std::distance(pos[i], bounds[i].second) > 1 ||
|
if ((i < int(p))
|
||||||
(i == 0 && std::distance(pos[i], bounds[i].second) == 1))
|
&& (std::distance(pos[i], bounds[i].second) > 1
|
||||||
|
|| (i == 0 && std::distance(pos[i], bounds[i].second) == 1)))
|
||||||
{
|
{
|
||||||
++pos[i];
|
++pos[i];
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ namespace spot
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_init_state(const std::string& state);
|
void set_init_state(const std::string& state);
|
||||||
|
void set_init_state(const std::vector<std::string>& state);
|
||||||
|
|
||||||
transition*
|
transition*
|
||||||
create_transition(const std::string& src,
|
create_transition(const std::string& src,
|
||||||
|
|
@ -106,7 +107,7 @@ namespace spot
|
||||||
mutable bdd all_acceptance_conditions_;
|
mutable bdd all_acceptance_conditions_;
|
||||||
mutable bool all_acceptance_conditions_computed_;
|
mutable bool all_acceptance_conditions_computed_;
|
||||||
bdd neg_acceptance_conditions_;
|
bdd neg_acceptance_conditions_;
|
||||||
taa::state* init_;
|
taa::state_set* init_;
|
||||||
ss_vec state_set_vec_;
|
ss_vec state_set_vec_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -167,8 +168,26 @@ namespace spot
|
||||||
virtual bdd current_acceptance_conditions() const;
|
virtual bdd current_acceptance_conditions() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Those typedefs are used to generate all possible successors in
|
||||||
|
/// the constructor using a cartesian product.
|
||||||
typedef taa::state::const_iterator iterator;
|
typedef taa::state::const_iterator iterator;
|
||||||
typedef std::multimap<taa::state_set, taa::transition*> seen_map;
|
typedef std::pair<iterator, iterator> iterator_pair;
|
||||||
|
typedef std::vector<iterator_pair> bounds_t;
|
||||||
|
typedef Sgi::hash_multimap<
|
||||||
|
const taa::state_set*, taa::transition*, ptr_hash<taa::state_set>
|
||||||
|
> seen_map;
|
||||||
|
|
||||||
|
struct distance_sort :
|
||||||
|
public std::binary_function<const iterator_pair&,
|
||||||
|
const iterator_pair&, bool>
|
||||||
|
{
|
||||||
|
bool
|
||||||
|
operator()(const iterator_pair& lhs, const iterator_pair& rhs) const
|
||||||
|
{
|
||||||
|
return std::distance(lhs.first, lhs.second) <
|
||||||
|
std::distance(rhs.first, rhs.second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<taa::transition*>::const_iterator i_;
|
std::vector<taa::transition*>::const_iterator i_;
|
||||||
std::vector<taa::transition*> succ_;
|
std::vector<taa::transition*> succ_;
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ namespace spot
|
||||||
init_ = to_string(f);
|
init_ = to_string(f);
|
||||||
std::vector<std::string> dst;
|
std::vector<std::string> dst;
|
||||||
|
|
||||||
dst.push_back(std::string("well"));
|
dst.push_back(std::string("sink"));
|
||||||
taa::transition* t = res_->create_transition(init_, dst);
|
taa::transition* t = res_->create_transition(init_, dst);
|
||||||
res_->add_condition(t, clone(f));
|
res_->add_condition(t, clone(f));
|
||||||
succ_state ss = { dst, f, constant::true_instance() };
|
succ_state ss = { dst, f, constant::true_instance() };
|
||||||
|
|
@ -90,7 +90,7 @@ namespace spot
|
||||||
{
|
{
|
||||||
case constant::True:
|
case constant::True:
|
||||||
{
|
{
|
||||||
dst.push_back(std::string("well"));
|
dst.push_back(std::string("sink"));
|
||||||
res_->create_transition(init_, dst);
|
res_->create_transition(init_, dst);
|
||||||
succ_state ss = { dst, node, constant::true_instance() };
|
succ_state ss = { dst, node, constant::true_instance() };
|
||||||
succ_.push_back(ss);
|
succ_.push_back(ss);
|
||||||
|
|
@ -383,8 +383,6 @@ namespace spot
|
||||||
const ltl::formula* f2 = ltl::negative_normal_form(f1);
|
const ltl::formula* f2 = ltl::negative_normal_form(f1);
|
||||||
ltl::destroy(f1);
|
ltl::destroy(f1);
|
||||||
|
|
||||||
std::cerr << ltl::to_string(f2) << std::endl;
|
|
||||||
|
|
||||||
spot::taa* res = new spot::taa(dict);
|
spot::taa* res = new spot::taa(dict);
|
||||||
language_containment_checker* lcc =
|
language_containment_checker* lcc =
|
||||||
new language_containment_checker(dict, false, false, false, false);
|
new language_containment_checker(dict, false, false, false, false);
|
||||||
|
|
@ -393,9 +391,6 @@ namespace spot
|
||||||
ltl::destroy(f2);
|
ltl::destroy(f2);
|
||||||
delete lcc;
|
delete lcc;
|
||||||
|
|
||||||
// TODO: temporary.
|
|
||||||
res->output(std::cerr);
|
|
||||||
|
|
||||||
return v.result();
|
return v.result();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue