Add support for ELTL (AST & parser), and an adaptation of LaCIM

for ELTL.  This is a new version of the work started in 2008 with
LTL and ELTL formulae now sharing the same class hierarchy.

* configure.ac: Adjust for src/eltlparse/ and src/eltltest/
directories, and call AX_BOOST_BASE.
* m4/boost.m4: New file defining AX_BOOST_BASE([MINIMUM-VERSION]).
* src/Makefile.am: Add eltlparse and eltltest.
* src/eltlparse/: New directory.  Contains the ELTL parser.
* src/eltltest/: New directory.  Contains tests related to
ELTL (parser and AST).
* src/ltlast/Makefile.am: Adjust for ELTL AST files.
* src/ltlast/automatop.cc, src/ltlast/automatop.hh: New files.
Represent automaton operators nodes used in ELTL ASTs.
* src/ltlast/nfa.cc, src/ltlast/nfa.hh: New files.  Represent
simple NFAs used internally by automatop nodes.
* src/ltlast/allnode.hh, src/ltlast/predecl.hh,
src/ltlast/visitor.hh: Adjust for automatop.
* src/ltlvisit/basicreduce.cc, src/ltlvisit/clone.cc,
src/ltlvisit/clone.hh, src/ltlvisit/contain.cc,
src/ltlvisit/dotty.cc, src/ltlvisit/nenoform.cc,
src/ltlvisit/postfix.cc, src/ltlvisit/postfix.hh,
src/ltlvisit/reduce.cc, src/ltlvisit/syntimpl.cc,
src/ltlvisit/tostring.cc: Because LTL and ELTL formulae share the
same class hierarchy, LTL visitors need to handle automatop nodes
to compile.  When it's meaningful the visitor applies on automatop
nodes or simply assert(0) otherwise.
* src/tgba/tgbabddconcretefactory.cc (create_anonymous_state),
src/tgba/tgbabddconcretefactory.hh (create_anonymous_state): New
function used by the LaCIM translation algorithm for ELTL.
* src/tgbaalgos/Makefile.am: Adjust for eltl2tgba_lacim* files.
* src/tgbaalgos/eltl2tgba_lacim.cc,
src/tgbaalgos/eltl2tgba_lacim.hh: New files.  Implementation of
the LaCIM translation algorithm for ELTL.
* src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/ltl2tgba_lacim.cc:
Handle automatop nodes in the translation by an assert(0).
* src/tgbatest/Makefile.am: Adjust for eltl2tgba.* files.
* src/src/tgbatest/eltl2tgba.cc, src/tgbatest/eltl2tgba.test: New
files
This commit is contained in:
Damien Lefortier 2009-03-02 17:31:12 +01:00
parent 90332d8d77
commit 2fbcd7e52f
46 changed files with 2509 additions and 3 deletions

View file

@ -27,10 +27,12 @@ ltlastdir = $(pkgincludedir)/ltlast
ltlast_HEADERS = \
allnodes.hh \
atomic_prop.hh \
automatop.hh \
binop.hh \
constant.hh \
formula.hh \
multop.hh \
nfa.hh \
predecl.hh \
refformula.hh \
unop.hh \
@ -39,9 +41,11 @@ ltlast_HEADERS = \
noinst_LTLIBRARIES = libltlast.la
libltlast_la_SOURCES = \
atomic_prop.cc \
automatop.cc \
binop.cc \
constant.cc \
formula.cc \
multop.cc \
nfa.cc \
refformula.cc \
unop.cc

View file

@ -33,5 +33,6 @@
# include "multop.hh"
# include "atomic_prop.hh"
# include "constant.hh"
# include "automatop.hh"
#endif // SPOT_LTLAST_ALLNODES_HH

108
src/ltlast/automatop.cc Normal file
View file

@ -0,0 +1,108 @@
// Copyright (C) 2008 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#include <iostream>
#include "automatop.hh"
#include "visitor.hh"
namespace spot
{
namespace ltl
{
automatop::automatop(const nfa::ptr nfa, vec* v)
: negated_(false), nfa_(nfa), children_(v)
{
dump_= nfa->get_name();
dump_ += "(";
dump_ += (*v)[0]->dump();
for (unsigned n = 1; n < v->size(); ++n)
dump_ += ", " + (*v)[n]->dump();
dump_ += ")";
set_key_();
}
automatop::~automatop()
{
// Get this instance out of the instance map.
pair p(nfa(), children_);
map::iterator i = instances.find(p);
assert (i != instances.end());
instances.erase(i);
delete children_;
}
void
automatop::accept(visitor& v)
{
v.visit(this);
}
void
automatop::accept(const_visitor& v) const
{
v.visit(this);
}
automatop::map automatop::instances;
automatop*
automatop::instance(const nfa::ptr nfa, vec* v)
{
assert(nfa != 0);
pair p(nfa, v);
map::iterator i = instances.find(p);
if (i != instances.end())
{
delete v;
return static_cast<automatop*>(i->second->ref());
}
automatop* res = new automatop(nfa, v);
instances[p] = res;
return static_cast<automatop*>(res->ref());
}
unsigned
automatop::size() const
{
return children_->size();
}
const formula*
automatop::nth(unsigned n) const
{
return (*children_)[n];
}
formula*
automatop::nth(unsigned n)
{
return (*children_)[n];
}
const nfa::ptr
automatop::nfa() const
{
assert(nfa_ != 0);
return nfa_;
}
}
}

98
src/ltlast/automatop.hh Normal file
View file

@ -0,0 +1,98 @@
// Copyright (C) 2008 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
/// \file ltlast/automatop.hh
/// \brief ELTL automaton operators
#ifndef SPOT_LTLAST_AUTOMATOP_HH
# define SPOT_LTLAST_AUTOMATOP_HH
# include <vector>
# include <map>
# include "nfa.hh"
# include "refformula.hh"
namespace spot
{
namespace ltl
{
/// \brief Automaton operators.
/// \ingroup eltl_ast
///
class automatop : public ref_formula
{
public:
/// List of formulae.
typedef std::vector<formula*> vec;
/// \brief Build a spot::ltl::automatop with many children.
///
/// This vector is acquired by the spot::ltl::automatop class,
/// the caller should allocate it with \c new, but not use it
/// (especially not destroy it) after it has been passed to
/// spot::ltl::automatop.
static automatop*
instance(const nfa::ptr nfa, vec* v);
virtual void accept(visitor& v);
virtual void accept(const_visitor& v) const;
/// Get the number of argument.
unsigned size() const;
/// \brief Get the nth argument.
///
/// Starting with \a n = 0.
const formula* nth(unsigned n) const;
/// \brief Get the nth argument.
///
/// Starting with \a n = 0.
formula* nth(unsigned n);
/// Get the NFA of this operator.
const nfa::ptr nfa() const;
bool negated_;
protected:
typedef std::pair<nfa::ptr, vec*> pair;
/// Comparison functor used internally by ltl::automatop.
struct paircmp
{
bool
operator () (const pair& p1, const pair& p2) const
{
if (p1.first != p2.first)
return p1.first < p2.first;
return *p1.second < *p2.second;
}
};
typedef std::map<pair, formula*, paircmp> map;
static map instances;
automatop(const nfa::ptr nfa, vec* v);
virtual ~automatop();
private:
nfa::ptr nfa_;
vec* children_;
};
}
}
#endif // SPOT_LTLAST_AUTOMATOP_HH

145
src/ltlast/nfa.cc Normal file
View file

@ -0,0 +1,145 @@
// Copyright (C) 2008 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#include <cassert>
#include "nfa.hh"
namespace spot
{
namespace ltl
{
nfa::nfa()
: is_(), si_(), arity_(0), name_(), init_(0), finals_()
{
}
nfa::~nfa()
{
is_map::iterator i;
for (i = is_.begin(); i != is_.end(); ++i)
{
state::iterator i2;
for (i2 = i->second->begin(); i2 != i->second->end(); ++i2)
delete *i2;
delete i->second;
}
}
nfa::state*
nfa::add_state(int name)
{
is_map::iterator i = is_.find(name);
if (i == is_.end())
{
state* s = new nfa::state;
is_[name] = s;
si_[s] = name;
if (!init_)
init_ = s;
return s;
}
return i->second;
}
void
nfa::add_transition(int src, int dst, int label)
{
state* s = add_state(src);
nfa::transition* t = new transition;
t->dst = add_state(dst);
t->label = label;
s->push_back(t);
if (label > arity_)
arity_ = label;
}
void
nfa::set_init_state(int name)
{
init_ = add_state(name);
}
void
nfa::set_final(int name)
{
finals_.insert(name);
}
bool
nfa::is_final(const state* s)
{
return finals_.find(format_state(s)) != finals_.end();
}
bool
nfa::is_loop()
{
return finals_.empty();
}
int
nfa::arity()
{
return arity_ + 1;
}
const nfa::state*
nfa::get_init_state()
{
if (!init_)
assert(0);
return init_;
}
nfa::iterator
nfa::begin(const state* s) const
{
return nfa::iterator(s->begin());
}
nfa::iterator
nfa::end(const state* s) const
{
return nfa::iterator(s->end());
}
int
nfa::format_state(const state* s) const
{
si_map::const_iterator i = si_.find(s);
assert(i != si_.end());
return i->second;
}
const std::string&
nfa::get_name() const
{
return name_;
}
void
nfa::set_name(const std::string& name)
{
name_ = name;
}
}
}

148
src/ltlast/nfa.hh Normal file
View file

@ -0,0 +1,148 @@
// Copyright (C) 2008 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Spot; see the file COPYING. If not, write to the Free
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
/// \file ltlast/nfa.hh
/// \brief NFA interface used by automatop
#ifndef SPOT_LTLAST_NFA_HH
# define SPOT_LTLAST_NFA_HH
# include "misc/hash.hh"
# include <boost/shared_ptr.hpp>
# include <list>
# include <set>
# include <map>
namespace spot
{
namespace ltl
{
/// Forward declaration. See below.
class succ_iterator;
/// \brief Nondeterministic Finite Automata used by automata operators.
///
/// States & labels are represented by integers.
/// Currently, only one initial state is possible.
class nfa
{
public:
struct transition;
typedef std::list<transition*> state;
/// Iterator over the successors of a state.
typedef succ_iterator iterator;
typedef boost::shared_ptr<nfa> ptr;
/// Explicit transitions.
struct transition
{
int label;
const state* dst;
};
nfa();
~nfa();
void add_transition(int src, int dst, int label);
void set_init_state(int name);
void set_final(int name);
/// \brief Get the initial state of the NFA.
const state* get_init_state();
/// \brief Tell whether the given state is final or not.
bool is_final(const state* s);
/// \brief Tell whether the NFA is `loop', i.e. without any final state.
bool is_loop();
/// \brief Get the `arity' i.e. max t.cost, for each transition t.
int arity();
/// \brief Return an iterator on the first succesor (if any) of \a state.
///
/// The usual way to do this with a \c for loop.
/// \code
/// for (nfa::iterator i = a.begin(s); i != a.end(s); ++i);
/// \endcode
iterator begin(const state* s) const;
/// \brief Return an iterator just past the last succesor of \a state.
iterator end(const state* s) const;
int format_state(const state* s) const;
const std::string& get_name() const;
void set_name(const std::string&);
private:
state* add_state(int name);
typedef Sgi::hash_map<int, state*, Sgi::hash<int> > is_map;
typedef Sgi::hash_map<const state*, int, ptr_hash<state> > si_map;
is_map is_;
si_map si_;
int arity_;
std::string name_; // FIXME.
state* init_;
std::set<int> finals_;
/// Explicitly disllow use of implicity generated member functions
/// we don't want.
nfa(const nfa& other);
nfa& operator=(const nfa& other);
};
class succ_iterator
{
public:
succ_iterator(const nfa::state::const_iterator s)
: i_(s)
{
}
void
operator++()
{
++i_;
}
bool
operator!=(const succ_iterator& rhs) const
{
return i_ != rhs.i_;
}
const nfa::transition* operator*() const
{
return *i_;
}
private:
nfa::state::const_iterator i_;
};
}
}
#endif // SPOT_LTLAST_NFA_HH_

View file

@ -42,6 +42,7 @@ namespace spot
struct binop;
struct formula;
struct multop;
struct automatop;
}
}

View file

@ -47,6 +47,7 @@ namespace spot
virtual void visit(binop* node) = 0;
virtual void visit(unop* node) = 0;
virtual void visit(multop* node) = 0;
virtual void visit(automatop* node) = 0;
};
/// \brief Formula visitor that cannot modify the formula.
@ -65,6 +66,7 @@ namespace spot
virtual void visit(const binop* node) = 0;
virtual void visit(const unop* node) = 0;
virtual void visit(const multop* node) = 0;
virtual void visit(const automatop* node) = 0;
};