Use taa_tgba_formula instead of taa_tgba_string in ltl_to_taa to

speed up a little the translation.

* src/tgbaalgos/ltl2taa.cc: Adjust.  Also fix a bug with
acceptance conditions in all_n_tuples.
* src/tgba/taatgba.cc, src/tgba/taatgba.hh: Adjust.
This commit is contained in:
Damien Lefortier 2010-01-16 13:33:04 +01:00
parent 7c20d8ae5d
commit beb3744581
4 changed files with 65 additions and 41 deletions

View file

@ -1,3 +1,12 @@
2010-01-16 Damien Lefortier <dam@lrde.epita.fr>
Use taa_tgba_formula instead of taa_tgba_string in ltl_to_taa to
speed up a little the translation.
* src/tgbaalgos/ltl2taa.cc: Adjust. Also fix a bug with
acceptance conditions in all_n_tuples.
* src/tgba/taatgba.cc, src/tgba/taatgba.hh: Adjust.
2010-01-16 Damien Lefortier <dam@lrde.epita.fr> 2010-01-16 Damien Lefortier <dam@lrde.epita.fr>
Introduce taa_tgba_labelled<label> so that we can build Introduce taa_tgba_labelled<label> so that we can build

View file

@ -350,7 +350,7 @@ namespace spot
`----------------*/ `----------------*/
std::string std::string
taa_tgba_string::label_to_string(const std::string& label) const taa_tgba_string::label_to_string(const std::string label) const
{ {
return label; return label;
} }

View file

@ -338,7 +338,7 @@ namespace spot
taa_tgba_string(bdd_dict* dict) : taa_tgba_string(bdd_dict* dict) :
taa_tgba_labelled<std::string, string_hash>(dict) {}; taa_tgba_labelled<std::string, string_hash>(dict) {};
protected: protected:
std::string label_to_string(const std::string& label) const; virtual std::string label_to_string(const std::string label) const;
}; };
class taa_tgba_formula : class taa_tgba_formula :
@ -348,7 +348,7 @@ namespace spot
taa_tgba_formula(bdd_dict* dict): taa_tgba_formula(bdd_dict* dict):
taa_tgba_labelled<const ltl::formula*, ltl::formula_ptr_hash>(dict) {}; taa_tgba_labelled<const ltl::formula*, ltl::formula_ptr_hash>(dict) {};
protected: protected:
std::string label_to_string(const ltl::formula* label) const; virtual std::string label_to_string(const ltl::formula* label) const;
}; };
} }

View file

@ -39,7 +39,7 @@ namespace spot
class ltl2taa_visitor : public const_visitor class ltl2taa_visitor : public const_visitor
{ {
public: public:
ltl2taa_visitor(taa_tgba_string* res, language_containment_checker* lcc, ltl2taa_visitor(taa_tgba_formula* res, language_containment_checker* lcc,
bool refined = false, bool negated = false) bool refined = false, bool negated = false)
: res_(res), refined_(refined), negated_(negated), : res_(res), refined_(refined), negated_(negated),
lcc_(lcc), init_(), succ_(), to_free_() lcc_(lcc), init_(), succ_(), to_free_()
@ -51,7 +51,7 @@ namespace spot
{ {
} }
taa_tgba_string* taa_tgba_formula*
result() result()
{ {
for (unsigned i = 0; i < to_free_.size(); ++i) for (unsigned i = 0; i < to_free_.size(); ++i)
@ -69,28 +69,35 @@ namespace spot
f = unop::instance(unop::Not, node->clone()); f = unop::instance(unop::Not, node->clone());
to_free_.push_back(f); to_free_.push_back(f);
} }
init_ = to_string(f); init_ = f;
std::vector<std::string> dst; std::vector<const formula*> dst;
std::vector<const formula*> a;
dst.push_back(std::string("sink")); // A little hack to define a sink
dst.push_back(unop::instance(unop::Finish, constant::true_instance()));
to_free_.push_back(dst[0]);
taa_tgba::transition* t = res_->create_transition(init_, dst); taa_tgba::transition* t = res_->create_transition(init_, dst);
res_->add_condition(t, f->clone()); res_->add_condition(t, f->clone());
succ_state ss = { dst, f, constant::true_instance() }; succ_state ss = { dst, f, a };
succ_.push_back(ss); succ_.push_back(ss);
} }
void void
visit(const constant* node) visit(const constant* node)
{ {
init_ = to_string(node); init_ = node;
std::vector<std::string> dst;
switch (node->val()) switch (node->val())
{ {
case constant::True: case constant::True:
{ {
dst.push_back(std::string("sink")); std::vector<const formula*> dst;
std::vector<const formula*> a;
// A little hack to define a sink
dst.push_back(unop::instance(unop::Finish,
constant::true_instance()));
to_free_.push_back(dst[0]);
res_->create_transition(init_, dst); res_->create_transition(init_, dst);
succ_state ss = { dst, node, constant::true_instance() }; succ_state ss = { dst, node, a };
succ_.push_back(ss); succ_.push_back(ss);
return; return;
} }
@ -107,18 +114,19 @@ namespace spot
negated_ = node->op() == unop::Not; negated_ = node->op() == unop::Not;
ltl2taa_visitor v = recurse(node->child()); ltl2taa_visitor v = recurse(node->child());
init_ = to_string(node); init_ = node;
std::vector<std::string> dst;
switch (node->op()) switch (node->op())
{ {
case unop::X: case unop::X:
{ {
std::vector<const formula*> dst;
std::vector<const formula*> a;
if (v.succ_.empty()) // Handle X(0) if (v.succ_.empty()) // Handle X(0)
return; return;
dst.push_back(v.init_); dst.push_back(v.init_);
res_->create_transition(init_, dst); res_->create_transition(init_, dst);
succ_state ss = succ_state ss =
{ dst, constant::true_instance(), constant::true_instance() }; { dst, constant::true_instance(), a };
succ_.push_back(ss); succ_.push_back(ss);
return; return;
} }
@ -143,7 +151,7 @@ namespace spot
ltl2taa_visitor v1 = recurse(node->first()); ltl2taa_visitor v1 = recurse(node->first());
ltl2taa_visitor v2 = recurse(node->second()); ltl2taa_visitor v2 = recurse(node->second());
init_ = to_string(node); init_ = node;
std::vector<succ_state>::iterator i1; std::vector<succ_state>::iterator i1;
std::vector<succ_state>::iterator i2; std::vector<succ_state>::iterator i2;
taa_tgba::transition* t = 0; taa_tgba::transition* t = 0;
@ -161,10 +169,10 @@ namespace spot
(remove(i1->Q.begin(), i1->Q.end(), v1.init_), i1->Q.end()); (remove(i1->Q.begin(), i1->Q.end(), v1.init_), i1->Q.end());
i1->Q.push_back(init_); // Add the initial state i1->Q.push_back(init_); // Add the initial state
i1->acc = node; i1->acc.push_back(node);
t = res_->create_transition(init_, i1->Q); t = res_->create_transition(init_, i1->Q);
res_->add_condition(t, i1->condition->clone()); res_->add_condition(t, i1->condition->clone());
res_->add_acceptance_condition(t, node->clone()); res_->add_acceptance_condition(t, node->second()->clone());
succ_.push_back(*i1); succ_.push_back(*i1);
} }
for (i2 = v2.succ_.begin(); i2 != v2.succ_.end(); ++i2) for (i2 = v2.succ_.begin(); i2 != v2.succ_.end(); ++i2)
@ -181,19 +189,20 @@ namespace spot
{ {
for (i1 = v1.succ_.begin(); i1 != v1.succ_.end(); ++i1) for (i1 = v1.succ_.begin(); i1 != v1.succ_.end(); ++i1)
{ {
std::vector<std::string> u; // Union std::vector<const formula*> u; // Union
std::copy(i1->Q.begin(), i1->Q.end(), ii(u, u.begin())); std::vector<const formula*> a; // Acceptance conditions
std::copy(i1->Q.begin(), i1->Q.end(), ii(u, u.end()));
formula* f = i1->condition->clone(); // Refined rule formula* f = i1->condition->clone(); // Refined rule
if (!refined_ || !contained) if (!refined_ || !contained)
{ {
std::copy(i2->Q.begin(), i2->Q.end(), ii(u, u.begin())); std::copy(i2->Q.begin(), i2->Q.end(), ii(u, u.end()));
f = multop::instance(multop::And, f, i2->condition->clone()); f = multop::instance(multop::And, f, i2->condition->clone());
} }
to_free_.push_back(f); to_free_.push_back(f);
t = res_->create_transition(init_, u); t = res_->create_transition(init_, u);
res_->add_condition(t, f->clone()); res_->add_condition(t, f->clone());
succ_state ss = { u, f, constant::true_instance() }; succ_state ss = { u, f, a };
succ_.push_back(ss); succ_.push_back(ss);
} }
@ -204,8 +213,9 @@ namespace spot
i2->Q.push_back(init_); // Add the initial state i2->Q.push_back(init_); // Add the initial state
t = res_->create_transition(init_, i2->Q); t = res_->create_transition(init_, i2->Q);
res_->add_condition(t, i2->condition->clone()); res_->add_condition(t, i2->condition->clone());
if (refined_ && i2->acc != constant::true_instance()) if (refined_)
res_->add_acceptance_condition(t, i2->acc->clone()); for (unsigned i = 0; i < i2->acc.size(); ++i)
res_->add_acceptance_condition(t, i2->acc[i]->clone());
succ_.push_back(*i2); succ_.push_back(*i2);
} }
return; return;
@ -230,7 +240,7 @@ namespace spot
ok = false; ok = false;
} }
init_ = to_string(node); init_ = node;
std::vector<succ_state>::iterator i; std::vector<succ_state>::iterator i;
taa_tgba::transition* t = 0; taa_tgba::transition* t = 0;
switch (node->op()) switch (node->op())
@ -242,7 +252,7 @@ namespace spot
{ {
if (refined_) if (refined_)
{ {
std::vector<std::string> v; // All sub initial states. std::vector<const formula*> v; // All sub initial states.
sort(p[n].Q.begin(), p[n].Q.end()); sort(p[n].Q.begin(), p[n].Q.end());
for (unsigned m = 0; m < node->size(); ++m) for (unsigned m = 0; m < node->size(); ++m)
{ {
@ -253,7 +263,7 @@ namespace spot
if (v.size() == node->size()) if (v.size() == node->size())
{ {
std::vector<std::string> Q; std::vector<const formula*> Q;
sort(v.begin(), v.end()); sort(v.begin(), v.end());
for (unsigned m = 0; m < p[n].Q.size(); ++m) for (unsigned m = 0; m < p[n].Q.size(); ++m)
if (!binary_search(v.begin(), v.end(), p[n].Q[m])) if (!binary_search(v.begin(), v.end(), p[n].Q[m]))
@ -261,8 +271,8 @@ namespace spot
Q.push_back(init_); Q.push_back(init_);
t = res_->create_transition(init_, Q); t = res_->create_transition(init_, Q);
res_->add_condition(t, p[n].condition->clone()); res_->add_condition(t, p[n].condition->clone());
if (p[n].acc != constant::true_instance()) for (unsigned i = 0; i < p[n].acc.size(); ++i)
res_->add_acceptance_condition(t, p[n].acc->clone()); res_->add_acceptance_condition(t, p[n].acc[i]->clone());
succ_.push_back(p[n]); succ_.push_back(p[n]);
return; return;
} }
@ -305,23 +315,23 @@ namespace spot
} }
private: private:
taa_tgba_string* res_; taa_tgba_formula* res_;
bool refined_; bool refined_;
bool negated_; bool negated_;
language_containment_checker* lcc_; language_containment_checker* lcc_;
typedef std::insert_iterator< typedef std::insert_iterator<
std::vector<std::string> std::vector<const formula*>
> ii; > ii;
struct succ_state struct succ_state
{ {
std::vector<std::string> Q; // States std::vector<const formula*> Q; // States
const formula* condition; const formula* condition;
const formula* acc; std::vector<const formula*> acc;
}; };
std::string init_; const formula* init_;
std::vector<succ_state> succ_; std::vector<succ_state> succ_;
std::vector<const formula*> to_free_; std::vector<const formula*> to_free_;
@ -338,20 +348,25 @@ namespace spot
while (pos[0] != 0) while (pos[0] != 0)
{ {
std::vector<std::string> u; // Union std::vector<const formula*> u; // Union
std::vector<const formula*> a; // Acceptance conditions
formula* f = constant::true_instance(); formula* f = constant::true_instance();
formula* a = constant::true_instance(); formula* g = 0;
for (unsigned i = 0; i < vs.size(); ++i) for (unsigned i = 0; i < vs.size(); ++i)
{ {
if (vs[i].succ_.empty()) if (vs[i].succ_.empty())
continue; continue;
const succ_state& ss(vs[i].succ_[pos[i] - 1]); const succ_state& ss(vs[i].succ_[pos[i] - 1]);
std::copy(ss.Q.begin(), ss.Q.end(), ii(u, u.begin())); std::copy(ss.Q.begin(), ss.Q.end(), ii(u, u.end()));
f = multop::instance(multop::And, ss.condition->clone(), f); f = multop::instance(multop::And, ss.condition->clone(), f);
a = multop::instance(multop::And, ss.acc->clone(), a); for (unsigned i = 0; i < ss.acc.size(); ++i)
{
g = ss.acc[i]->clone();
a.push_back(g);
to_free_.push_back(g);
}
} }
to_free_.push_back(f); to_free_.push_back(f);
to_free_.push_back(a);
succ_state ss = { u, f, a }; succ_state ss = { u, f, a };
product.push_back(ss); product.push_back(ss);
@ -381,7 +396,7 @@ namespace spot
const ltl::formula* f2 = ltl::negative_normal_form(f1); const ltl::formula* f2 = ltl::negative_normal_form(f1);
f1->destroy(); f1->destroy();
spot::taa_tgba_string* res = new spot::taa_tgba_string(dict); spot::taa_tgba_formula* res = new spot::taa_tgba_formula(dict);
bdd_dict b; bdd_dict b;
language_containment_checker* lcc = language_containment_checker* lcc =
new language_containment_checker(&b, false, false, false, false); new language_containment_checker(&b, false, false, false, false);