Parse the fusion operator (":") and translate it in ltl2tgba_fm().

* src/ltlast/multop.hh (multop::type::Fusion): New operator.
* src/ltlast/multop.cc: Handle it.
* src/ltlparse/ltlparse.yy: Declare OP_FUSION and add grammar
rules.
* src/ltlparse/ltlscan.ll: Recognize ":" as OP_FUSION.
* src/tgbaalgos/ltl2tgba_fm.cc (ratexp_trad_visitor::visit):
Add translation rule for multop::Fusion.
* src/tgbatest/ltl2tgba.test: Add more tests.
* src/ltlvisit/basicreduce.cc, src/ltlvisit/consterm.cc,
src/ltlvisit/contain.cc, src/ltlvisit/mark.cc,
src/ltlvisit/nenoform.cc, src/ltlvisit/syntimpl.cc,
src/ltlvisit/tostring.cc, src/tgba/formula2bdd.cc,
src/tgbaalgos/eltl2tgba_lacim.cc, src/tgbaalgos/ltl2taa.cc,
src/tgbaalgos/ltl2tgba_lacim.cc: Handle multop::Fusion in switches.
This commit is contained in:
Alexandre Duret-Lutz 2010-03-02 16:25:08 +01:00
parent ad519b8568
commit c2b3dac7aa
17 changed files with 146 additions and 25 deletions

View file

@ -486,6 +486,70 @@ namespace spot
multop::instance(multop::Concat, v));
break;
}
case multop::Fusion:
{
assert(node->size() >= 2);
// the head
bdd res = recurse(node->nth(0));
// the tail
multop::vec* v = new multop::vec;
unsigned s = node->size();
v->reserve(s - 1);
for (unsigned n = 1; n < s; ++n)
v->push_back(node->nth(n)->clone());
formula* tail = multop::instance(multop::Fusion, v);
bdd tail_bdd;
bool tail_computed = false;
//trace_ltl_bdd(dict_, res);
minato_isop isop(res);
bdd cube;
res_ = bddfalse;
while ((cube = isop.next()) != bddfalse)
{
bdd label = bdd_exist(cube, dict_.next_set);
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
formula* dest = dict_.conj_bdd_to_formula(dest_bdd);
if (constant_term_as_bool(dest))
{
// The destination is a final state. Make sure we
// can also exit if tail is satisfied.
if (!tail_computed)
{
tail_bdd = recurse(tail,
to_concat_ ?
to_concat_->clone() : 0);
tail_computed = true;
}
res_ |= label & tail_bdd;
}
if (dynamic_cast<constant*>(dest) == 0)
{
// If the destination is not a constant, it
// means it can have successors. Fusion the
// tail and append anything to concatenate.
formula* dest2 = multop::instance(multop::Fusion, dest,
tail->clone());
if (to_concat_)
dest2 = multop::instance(multop::Concat, dest2,
to_concat_->clone());
if (dest2 != constant::false_instance())
{
int x = dict_.register_next_variable(dest2);
dest2->destroy();
res_ |= label & bdd_ithvar(x);
}
}
}
tail->destroy();
break;
}
}
}
@ -822,6 +886,7 @@ namespace spot
break;
}
case multop::Concat:
case multop::Fusion:
assert(!"Not an LTL operator");
break;
}