Modify the ELTL parser to be able to support PSL operators. Add a
new keyword in the ELTL format: finish, which applies to an automaton operator and tells whether it just completed. * src/eltlparse/eltlparse.yy: Clean it. Add finish. * src/eltlparse/eltlscan.ll: Add finish. * src/formula_tree.cc, src/formula_tree.hh: New files. Define a small AST representing formulae where atomic props are unknown which is used in the ELTL parser. * src/ltlast/automatop.cc, ltlast/automatop.hh, ltlast/nfa.cc, ltlast/nfa.hh: Adjust. * src/ltlast/unop.cc, src/ltlast/unop.hh: Finish is an unop. * src/ltlvisit/basicreduce.cc, src/ltlvisit/nenoform.cc, src/ltlvisit/reduce.cc, src/ltlvisit/syntimpl.cc, src/ltlvisit/tostring.cc, src/ltlvisit/tunabbrev.cc, src/tgba/formula2bdd.cc, src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/ltl2tgba_lacim.cc: Handle finish in switches. * src/tgbaalgos/eltl2tgba_lacim.cc: Translate finish. * src/tgbatest/eltl2tgba.test: More tests.
This commit is contained in:
parent
4de885afb1
commit
e48338e8d8
23 changed files with 479 additions and 237 deletions
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "ltlast/visitor.hh"
|
||||
#include "ltlast/allnodes.hh"
|
||||
#include "ltlast/formula_tree.hh"
|
||||
#include "ltlvisit/lunabbrev.hh"
|
||||
#include "ltlvisit/nenoform.hh"
|
||||
#include "ltlvisit/destroy.hh"
|
||||
|
|
@ -40,7 +41,7 @@ namespace spot
|
|||
{
|
||||
public:
|
||||
eltl_trad_visitor(tgba_bdd_concrete_factory& fact, bool root = false)
|
||||
: fact_(fact), root_(root)
|
||||
: fact_(fact), root_(root), finish_()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +88,18 @@ namespace spot
|
|||
res_ = bdd_not(recurse(node->child()));
|
||||
return;
|
||||
}
|
||||
case unop::Finish:
|
||||
{
|
||||
// Ensure finish_[node->child()] has been computed if
|
||||
// node->child() is an automaton operator.
|
||||
bdd f = recurse(node->child());
|
||||
finish_map_::const_iterator it = finish_.find(node->child());
|
||||
if (it == finish_.end())
|
||||
res_ = f;
|
||||
else
|
||||
res_ = finish_[node->child()];
|
||||
return;
|
||||
}
|
||||
case unop::X:
|
||||
case unop::F:
|
||||
case unop::G:
|
||||
|
|
@ -149,12 +162,23 @@ namespace spot
|
|||
}
|
||||
|
||||
void
|
||||
visit (const automatop* node)
|
||||
visit(const automatop* node)
|
||||
{
|
||||
nmap m;
|
||||
bdd finish = bddfalse;
|
||||
bdd acc = bddtrue;
|
||||
|
||||
std::vector<formula*> v;
|
||||
for (unsigned i = 0; i < node->size(); ++i)
|
||||
v.push_back(const_cast<formula*>(node->nth(i)));
|
||||
|
||||
std::pair<int, int> vp =
|
||||
recurse_state(node, node->nfa()->get_init_state(), m, acc);
|
||||
recurse_state(node->nfa(),
|
||||
node->nfa()->get_init_state(), v, m, acc, finish);
|
||||
|
||||
// Update finish_ with finish(node).
|
||||
// FIXME: when node is loop, it does not make sense; hence the bddtrue.
|
||||
finish_[node] = !node->nfa()->is_loop() ? bddtrue : finish;
|
||||
|
||||
bdd tmp = bddtrue;
|
||||
for (nmap::iterator it = m.begin(); it != m.end(); ++it)
|
||||
|
|
@ -180,15 +204,22 @@ namespace spot
|
|||
tgba_bdd_concrete_factory& fact_;
|
||||
bool root_;
|
||||
|
||||
/// BDD associated to each automatop A representing finish(A).
|
||||
typedef Sgi::hash_map<const ltl::formula*, bdd,
|
||||
ltl::formula_ptr_hash> finish_map_;
|
||||
|
||||
finish_map_ finish_;
|
||||
|
||||
// Table containing the two now variables associated with each state.
|
||||
// TODO: a little documentation about that.
|
||||
typedef Sgi::hash_map<
|
||||
const nfa::state*, std::pair<int, int>, ptr_hash<nfa::state> > nmap;
|
||||
|
||||
std::pair<int, int>&
|
||||
recurse_state(const automatop* n, const nfa::state* s, nmap& m, bdd& acc)
|
||||
recurse_state(const nfa::ptr& nfa, const nfa::state* s,
|
||||
const std::vector<formula*>& v,
|
||||
nmap& m, bdd& acc, bdd& finish)
|
||||
{
|
||||
const nfa::ptr nfa = n->nfa();
|
||||
bool is_loop = nfa->is_loop();
|
||||
nmap::iterator it;
|
||||
it = m.find(s);
|
||||
|
|
@ -209,16 +240,18 @@ namespace spot
|
|||
bdd tmpacc = bddfalse;
|
||||
for (nfa::iterator i = nfa->begin(s); i != nfa->end(s); ++i)
|
||||
{
|
||||
bdd f = (*i)->label == -1 ? bddtrue : recurse(n->nth((*i)->label));
|
||||
bdd f = recurse(formula_tree::instanciate((*i)->lbl, v));
|
||||
if (nfa->is_final((*i)->dst))
|
||||
{
|
||||
tmp1 |= f;
|
||||
tmp2 |= f;
|
||||
tmpacc |= f;
|
||||
finish |= bdd_ithvar(v1) & f;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::pair<int, int> vp = recurse_state(n, (*i)->dst, m, acc);
|
||||
std::pair<int, int> vp =
|
||||
recurse_state(nfa, (*i)->dst, v, m, acc, finish);
|
||||
tmp1 |= (f & bdd_ithvar(vp.first + 1));
|
||||
tmp2 |= (f & bdd_ithvar(vp.second + 1));
|
||||
if (is_loop)
|
||||
|
|
|
|||
|
|
@ -358,6 +358,8 @@ namespace spot
|
|||
res_ = bdd_ithvar(x);
|
||||
return;
|
||||
}
|
||||
case unop::Finish:
|
||||
assert(!"unsupported operator");
|
||||
}
|
||||
/* Unreachable code. */
|
||||
assert(0);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ namespace spot
|
|||
res_ = next;
|
||||
return;
|
||||
}
|
||||
case unop::Finish:
|
||||
assert(!"unsupported operator");
|
||||
}
|
||||
/* Unreachable code. */
|
||||
assert(0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue