Implements spot::ltl::destroy() and exercise it.

* src/ltlast/atomic_prop.hh: Declare instance_count().
* src/ltlast/binop.hh, src/ltlast/unop.hh, src/ltlast/multop.hh:
Likewise.  Also, really inherit for ref_formula this time.
* src/ltlast/atomic_prop.cc, src/ltlast/binop.cc,
src/ltlast/unop.cc, src/ltlast/multop.cc: On destruction, suppress
the instance from the instance map.  Implement instance_count().
* src/ltlast/formula.cc, src/ltlast/formula.hh,
src/ltlast/ref_formula.cc, src/ltlast/ref_formula.hh: Add virtual
destructors.
* src/ltlparse/ltlparse.yy: Recover from binary operators with
missing right hand operand (the point is just to destroy the
the left hand operand).
* src/ltltest/equals.cc, src/ltltest/readltl.cc,
src/ltltest/tostring.cc: Destroy used formulae.  Make sure
instance_count()s are null are the end.
* src/ltltest/parseerr.test: Adjust expected result, now
that the parser lnows about missing right hand operands.
* src/ltlvisit/destroy.hh, src/ltlvisit/destroy.cc,
src/ltlvisit/postfix.hh, src/ltlvisit/postfix.cc: New files.
* src/ltlvisit/Makefile.am (libltlvisit_la_SOURCES): Add them.
* src/ltlvisit/lunabbrev.cc (Xor, Equiv): Clone formulae
occurring twice in the rewritten expression.
This commit is contained in:
Alexandre Duret-Lutz 2003-05-15 18:06:54 +00:00
parent 5f6d8b6234
commit 9123e56ff9
24 changed files with 382 additions and 24 deletions

View file

@ -1,5 +1,30 @@
2003-05-15 Alexandre Duret-Lutz <aduret@src.lip6.fr> 2003-05-15 Alexandre Duret-Lutz <aduret@src.lip6.fr>
Implements spot::ltl::destroy() and exercise it.
* src/ltlast/atomic_prop.hh: Declare instance_count().
* src/ltlast/binop.hh, src/ltlast/unop.hh, src/ltlast/multop.hh:
Likewise. Also, really inherit for ref_formula this time.
* src/ltlast/atomic_prop.cc, src/ltlast/binop.cc,
src/ltlast/unop.cc, src/ltlast/multop.cc: On destruction, suppress
the instance from the instance map. Implement instance_count().
* src/ltlast/formula.cc, src/ltlast/formula.hh,
src/ltlast/ref_formula.cc, src/ltlast/ref_formula.hh: Add virtual
destructors.
* src/ltlparse/ltlparse.yy: Recover from binary operators with
missing right hand operand (the point is just to destroy the
the left hand operand).
* src/ltltest/equals.cc, src/ltltest/readltl.cc,
src/ltltest/tostring.cc: Destroy used formulae. Make sure
instance_count()s are null are the end.
* src/ltltest/parseerr.test: Adjust expected result, now
that the parser lnows about missing right hand operands.
* src/ltlvisit/destroy.hh, src/ltlvisit/destroy.cc,
src/ltlvisit/postfix.hh, src/ltlvisit/postfix.cc: New files.
* src/ltlvisit/Makefile.am (libltlvisit_la_SOURCES): Add them.
* src/ltlvisit/lunabbrev.cc (Xor, Equiv): Clone formulae
occurring twice in the rewritten expression.
Massage the AST so that identical sub-formula share the same Massage the AST so that identical sub-formula share the same
reference-counted formula*. One can't call constructors for AST reference-counted formula*. One can't call constructors for AST
items anymore, everything need to be acquired through instance() items anymore, everything need to be acquired through instance()

View file

@ -13,6 +13,11 @@ namespace spot
atomic_prop::~atomic_prop() atomic_prop::~atomic_prop()
{ {
// Get this instance out of the instance map.
pair p(name(), &env());
map::iterator i = instances.find(p);
assert (i != instances.end());
instances.erase(i);
} }
void void
@ -55,5 +60,11 @@ namespace spot
return static_cast<atomic_prop*>(ap->ref()); return static_cast<atomic_prop*>(ap->ref());
} }
unsigned
atomic_prop::instance_count()
{
return instances.size();
}
} }
} }

View file

@ -26,6 +26,10 @@ namespace spot
const std::string& name() const; const std::string& name() const;
/// Get the environment of the atomic proposition. /// Get the environment of the atomic proposition.
environment& env() const; environment& env() const;
/// Number of instantiated atomic propositions. For debugging.
static unsigned instance_count();
protected: protected:
atomic_prop(const std::string& name, environment& env); atomic_prop(const std::string& name, environment& env);
virtual ~atomic_prop(); virtual ~atomic_prop();

View file

@ -13,6 +13,12 @@ namespace spot
binop::~binop() binop::~binop()
{ {
// Get this instance out of the instance map.
pairf pf(first(), second());
pair p(op(), pf);
map::iterator i = instances.find(p);
assert (i != instances.end());
instances.erase(i);
} }
void void
@ -95,5 +101,10 @@ namespace spot
return static_cast<binop*>(ap->ref()); return static_cast<binop*>(ap->ref());
} }
unsigned
binop::instance_count()
{
return instances.size();
}
} }
} }

View file

@ -2,7 +2,7 @@
# define SPOT_LTLAST_BINOP_HH # define SPOT_LTLAST_BINOP_HH
#include <map> #include <map>
#include "formula.hh" #include "refformula.hh"
namespace spot namespace spot
{ {
@ -10,7 +10,7 @@ namespace spot
{ {
/// Binary operator. /// Binary operator.
class binop : public formula class binop : public ref_formula
{ {
public: public:
/// Different kinds of binary opertaors /// Different kinds of binary opertaors
@ -40,6 +40,9 @@ namespace spot
/// Get the type of this operator, as a string. /// Get the type of this operator, as a string.
const char* op_name() const; const char* op_name() const;
/// Number of instantiated binary operators. For debugging.
static unsigned instance_count();
protected: protected:
typedef std::pair<formula*, formula*> pairf; typedef std::pair<formula*, formula*> pairf;
typedef std::pair<type, pairf> pair; typedef std::pair<type, pairf> pair;

View file

@ -11,6 +11,10 @@ namespace spot
return this; return this;
} }
formula::~formula()
{
}
void void
formula::unref(formula* f) formula::unref(formula* f)
{ {

View file

@ -15,6 +15,8 @@ namespace spot
class formula class formula
{ {
public: public:
virtual ~formula();
virtual void accept(visitor& v) = 0; virtual void accept(visitor& v) = 0;
virtual void accept(const_visitor& v) const = 0; virtual void accept(const_visitor& v) const = 0;

View file

@ -14,6 +14,12 @@ namespace spot
multop::~multop() multop::~multop()
{ {
// Get this instance out of the instance map.
pair p(op(), children_);
map::iterator i = instances.find(p);
assert (i != instances.end());
instances.erase(i);
delete children_; delete children_;
} }
@ -132,5 +138,10 @@ namespace spot
*m = instance(op, v); *m = instance(op, v);
} }
unsigned
multop::instance_count()
{
return instances.size();
}
} }
} }

View file

@ -3,7 +3,7 @@
#include <vector> #include <vector>
#include <map> #include <map>
#include "formula.hh" #include "refformula.hh"
namespace spot namespace spot
{ {
@ -13,7 +13,7 @@ namespace spot
/// \brief Multi-operand operators. /// \brief Multi-operand operators.
/// ///
/// These operators are considered commutative and associative. /// These operators are considered commutative and associative.
class multop : public formula class multop : public ref_formula
{ {
public: public:
enum type { Or, And }; enum type { Or, And };
@ -61,6 +61,9 @@ namespace spot
/// Get the type of this operator, as a string. /// Get the type of this operator, as a string.
const char* op_name() const; const char* op_name() const;
/// Number of instantiated multi-operand operators. For debugging.
static unsigned instance_count();
protected: protected:
typedef std::vector<formula*> vec; typedef std::vector<formula*> vec;
typedef std::pair<type, vec*> pair; typedef std::pair<type, vec*> pair;

View file

@ -10,6 +10,10 @@ namespace spot
{ {
} }
ref_formula::~ref_formula()
{
}
void void
ref_formula::ref_() ref_formula::ref_()
{ {

View file

@ -12,6 +12,7 @@ namespace spot
class ref_formula : public formula class ref_formula : public formula
{ {
protected: protected:
virtual ~ref_formula();
ref_formula(); ref_formula();
void ref_(); void ref_();
bool unref_(); bool unref_();

View file

@ -13,6 +13,11 @@ namespace spot
unop::~unop() unop::~unop()
{ {
// Get this instance out of the instance map.
pair p(op(), child());
map::iterator i = instances.find(p);
assert (i != instances.end());
instances.erase(i);
} }
void void
@ -80,5 +85,10 @@ namespace spot
return static_cast<unop*>(ap->ref()); return static_cast<unop*>(ap->ref());
} }
unsigned
unop::instance_count()
{
return instances.size();
}
} }
} }

View file

@ -2,7 +2,7 @@
# define SPOT_LTLAST_UNOP_HH # define SPOT_LTLAST_UNOP_HH
#include <map> #include <map>
#include "formula.hh" #include "refformula.hh"
namespace spot namespace spot
{ {
@ -10,7 +10,7 @@ namespace spot
{ {
/// Unary operator. /// Unary operator.
class unop : public formula class unop : public ref_formula
{ {
public: public:
enum type { Not, X, F, G }; enum type { Not, X, F, G };
@ -32,6 +32,9 @@ namespace spot
/// Get the type of this operator, as a string. /// Get the type of this operator, as a string.
const char* op_name() const; const char* op_name() const;
/// Number of instantiated unary operators. For debugging.
static unsigned instance_count();
protected: protected:
typedef std::pair<type, formula*> pair; typedef std::pair<type, formula*> pair;
typedef std::map<pair, formula*> map; typedef std::map<pair, formula*> map;

View file

@ -2,6 +2,7 @@
#include <string> #include <string>
#include "public.hh" #include "public.hh"
#include "ltlast/allnodes.hh" #include "ltlast/allnodes.hh"
#include "ltlvisit/destroy.hh"
extern spot::ltl::formula* result; extern spot::ltl::formula* result;
@ -83,6 +84,9 @@ ltl_formula: subformula
many_errors: error many_errors: error
| many_errors error | many_errors error
/* The reason we use `constant::false_instance()' for error recovery
is that it isn't reference counted. (Hence it can't leak references.) */
subformula: ATOMIC_PROP subformula: ATOMIC_PROP
{ {
$$ = parse_environment.require(*$1); $$ = parse_environment.require(*$1);
@ -120,18 +124,67 @@ subformula: ATOMIC_PROP
{ $$ = unop::instance(unop::Not, $2); } { $$ = unop::instance(unop::Not, $2); }
| subformula OP_AND subformula | subformula OP_AND subformula
{ $$ = multop::instance(multop::And, $1, $3); } { $$ = multop::instance(multop::And, $1, $3); }
| subformula OP_AND error
{
destroy($1);
error_list.push_back(parse_error(@2,
"missing right operand for OP_AND"));
$$ = constant::false_instance();
}
| subformula OP_OR subformula | subformula OP_OR subformula
{ $$ = multop::instance(multop::Or, $1, $3); } { $$ = multop::instance(multop::Or, $1, $3); }
| subformula OP_OR error
{
destroy($1);
error_list.push_back(parse_error(@2,
"missing right operand for OP_OR"));
$$ = constant::false_instance();
}
| subformula OP_XOR subformula | subformula OP_XOR subformula
{ $$ = binop::instance(binop::Xor, $1, $3); } { $$ = binop::instance(binop::Xor, $1, $3); }
| subformula OP_XOR error
{
destroy($1);
error_list.push_back(parse_error(@2,
"missing right operand for OP_XOR"));
$$ = constant::false_instance();
}
| subformula OP_IMPLIES subformula | subformula OP_IMPLIES subformula
{ $$ = binop::instance(binop::Implies, $1, $3); } { $$ = binop::instance(binop::Implies, $1, $3); }
| subformula OP_IMPLIES error
{
destroy($1);
error_list.push_back(parse_error(@2,
"missing right operand for OP_IMPLIES"));
$$ = constant::false_instance();
}
| subformula OP_EQUIV subformula | subformula OP_EQUIV subformula
{ $$ = binop::instance(binop::Equiv, $1, $3); } { $$ = binop::instance(binop::Equiv, $1, $3); }
| subformula OP_EQUIV error
{
destroy($1);
error_list.push_back(parse_error(@2,
"missing right operand for OP_EQUIV"));
$$ = constant::false_instance();
}
| subformula OP_U subformula | subformula OP_U subformula
{ $$ = binop::instance(binop::U, $1, $3); } { $$ = binop::instance(binop::U, $1, $3); }
| subformula OP_U error
{
destroy($1);
error_list.push_back(parse_error(@2,
"missing right operand for OP_U"));
$$ = constant::false_instance();
}
| subformula OP_R subformula | subformula OP_R subformula
{ $$ = binop::instance(binop::R, $1, $3); } { $$ = binop::instance(binop::R, $1, $3); }
| subformula OP_R error
{
destroy($1);
error_list.push_back(parse_error(@2,
"missing right operand for OP_R"));
$$ = constant::false_instance();
}
| OP_F subformula | OP_F subformula
{ $$ = unop::instance(unop::F, $2); } { $$ = unop::instance(unop::F, $2); }
| OP_G subformula | OP_G subformula

View file

@ -5,6 +5,8 @@
#include "ltlvisit/tunabbrev.hh" #include "ltlvisit/tunabbrev.hh"
#include "ltlvisit/dump.hh" #include "ltlvisit/dump.hh"
#include "ltlvisit/nenoform.hh" #include "ltlvisit/nenoform.hh"
#include "ltlvisit/destroy.hh"
#include "ltlast/allnodes.hh"
void void
syntax(char* prog) syntax(char* prog)
@ -32,24 +34,44 @@ main(int argc, char** argv)
if (spot::ltl::format_parse_errors(std::cerr, argv[2], p2)) if (spot::ltl::format_parse_errors(std::cerr, argv[2], p2))
return 2; return 2;
#if (defined LUNABBREV) || (defined TUNABBREV) || (defined NENOFORM)
spot::ltl::formula* tmp;
#endif
#ifdef LUNABBREV #ifdef LUNABBREV
tmp = f1;
std::cout << spot::ltl::atomic_prop::instance_count() << std::endl;
f1 = spot::ltl::unabbreviate_logic(f1); f1 = spot::ltl::unabbreviate_logic(f1);
std::cout << spot::ltl::atomic_prop::instance_count() << std::endl;
spot::ltl::destroy(tmp);
std::cout << spot::ltl::atomic_prop::instance_count() << std::endl;
spot::ltl::dump(*f1, std::cout); spot::ltl::dump(*f1, std::cout);
std::cout << std::endl; std::cout << std::endl;
#endif #endif
#ifdef TUNABBREV #ifdef TUNABBREV
tmp = f1;
f1 = spot::ltl::unabbreviate_ltl(f1); f1 = spot::ltl::unabbreviate_ltl(f1);
spot::ltl::destroy(tmp);
spot::ltl::dump(*f1, std::cout); spot::ltl::dump(*f1, std::cout);
std::cout << std::endl; std::cout << std::endl;
#endif #endif
#ifdef NENOFORM #ifdef NENOFORM
tmp = f1;
f1 = spot::ltl::negative_normal_form(f1); f1 = spot::ltl::negative_normal_form(f1);
spot::ltl::destroy(tmp);
spot::ltl::dump(*f1, std::cout); spot::ltl::dump(*f1, std::cout);
std::cout << std::endl; std::cout << std::endl;
#endif #endif
if (equals(f1, f2)) int exit_code = !equals(f1, f2);
return 0;
return 1;
spot::ltl::destroy(f1);
std::cout << spot::ltl::atomic_prop::instance_count() << std::endl;
spot::ltl::destroy(f2);
std::cout << spot::ltl::atomic_prop::instance_count() << std::endl;
assert(spot::ltl::atomic_prop::instance_count() == 0);
assert(spot::ltl::unop::instance_count() == 0);
assert(spot::ltl::binop::instance_count() == 0);
assert(spot::ltl::multop::instance_count() == 0);
return exit_code;
} }

View file

@ -33,17 +33,19 @@ check()
# Empty or unparsable strings # Empty or unparsable strings
check '' '' check '' ''
check '+' '' check '+' ''
check 'a U' ''
check 'a U b V c R' ''
# leading and trailing garbage are skipped # leading and trailing garbage are skipped
check '/2/3/4/5 a + b /6/7/8/' 'multop(Or, AP(a), AP(b))' check '/2/3/4/5 a + b /6/7/8/' 'multop(Or, AP(a), AP(b))'
check 'a U b c' 'binop(U, AP(a), AP(b))' check 'a U b c' 'binop(U, AP(a), AP(b))'
check 'a &&& b' 'AP(b)' check 'a &&& b' 'multop(And, constant(0), AP(b))'
# (check multop merging while we are at it) # (check multop merging while we are at it)
check 'a & b & c & d e' 'multop(And, AP(a), AP(b), AP(c), AP(d))' check 'a & b & c & d e' 'multop(And, AP(a), AP(b), AP(c), AP(d))'
check 'a & (b | c) & d should work' 'multop(And, AP(a), multop(Or, AP(b), AP(c)), AP(d))' check 'a & (b | c) & d should work' 'multop(And, AP(a), multop(Or, AP(b), AP(c)), AP(d))'
# Binop recovery
check 'a U' 'constant(0)'
check 'a U b V c R' 'constant(0)'
# Recovery inside parentheses # Recovery inside parentheses
check 'a U (b c) U e R (f g <=> h)' \ check 'a U (b c) U e R (f g <=> h)' \
'binop(R, binop(U, binop(U, AP(a), AP(b)), AP(e)), AP(f))' 'binop(R, binop(U, binop(U, AP(a), AP(b)), AP(e)), AP(f))'

View file

@ -2,6 +2,8 @@
#include "ltlparse/public.hh" #include "ltlparse/public.hh"
#include "ltlvisit/dump.hh" #include "ltlvisit/dump.hh"
#include "ltlvisit/dotty.hh" #include "ltlvisit/dotty.hh"
#include "ltlvisit/destroy.hh"
#include "ltlast/allnodes.hh"
void void
syntax(char* prog) syntax(char* prog)
@ -46,11 +48,16 @@ main(int argc, char** argv)
spot::ltl::dump(*f, std::cout); spot::ltl::dump(*f, std::cout);
std::cout << std::endl; std::cout << std::endl;
#endif #endif
spot::ltl::destroy(f);
} }
else else
{ {
exit_code = 1; exit_code = 1;
} }
assert(spot::ltl::atomic_prop::instance_count() == 0);
assert(spot::ltl::unop::instance_count() == 0);
assert(spot::ltl::binop::instance_count() == 0);
assert(spot::ltl::multop::instance_count() == 0);
return exit_code; return exit_code;
} }

View file

@ -2,6 +2,8 @@
#include "ltlparse/public.hh" #include "ltlparse/public.hh"
#include "ltlvisit/tostring.hh" #include "ltlvisit/tostring.hh"
#include "ltlvisit/equals.hh" #include "ltlvisit/equals.hh"
#include "ltlvisit/destroy.hh"
#include "ltlast/allnodes.hh"
void void
syntax(char *prog) syntax(char *prog)
@ -45,5 +47,12 @@ main(int argc, char **argv)
if (f2s != f1s) if (f2s != f1s)
return 1; return 1;
}
spot::ltl::destroy(f1);
spot::ltl::destroy(f2);
assert(spot::ltl::atomic_prop::instance_count() == 0);
assert(spot::ltl::unop::instance_count() == 0);
assert(spot::ltl::binop::instance_count() == 0);
assert(spot::ltl::multop::instance_count() == 0);
return 0;
}

View file

@ -5,6 +5,8 @@ noinst_LTLIBRARIES = libltlvisit.la
libltlvisit_la_SOURCES = \ libltlvisit_la_SOURCES = \
clone.cc \ clone.cc \
clone.hh \ clone.hh \
destroy.cc \
destroy.hh \
dotty.cc \ dotty.cc \
dotty.hh \ dotty.hh \
dump.cc \ dump.cc \
@ -17,5 +19,7 @@ libltlvisit_la_SOURCES = \
lunabbrev.cc \ lunabbrev.cc \
nenoform.hh \ nenoform.hh \
nenoform.cc \ nenoform.cc \
postfix.hh \
postfix.cc \
tunabbrev.hh \ tunabbrev.hh \
tunabbrev.cc tunabbrev.cc

25
src/ltlvisit/destroy.cc Normal file
View file

@ -0,0 +1,25 @@
#include "ltlvisit/destroy.hh"
namespace spot
{
namespace ltl
{
class destroy_visitor : public postfix_visitor
{
public:
virtual void
doit_default(formula* c)
{
formula::unref(c);
}
};
void
destroy(formula *f)
{
destroy_visitor v;
f->accept(v);
}
}
}

15
src/ltlvisit/destroy.hh Normal file
View file

@ -0,0 +1,15 @@
#ifndef SPOT_LTLVISIT_DESTROY_HH
# define SPOT_LTLVISIT_DESTROY_HH
#include "ltlvisit/postfix.hh"
namespace spot
{
namespace ltl
{
/// \brief Destroys a formula
void destroy(formula *f);
}
}
#endif // SPOT_LTLVISIT_DESTROY_HH

View file

@ -1,4 +1,5 @@
#include "ltlast/allnodes.hh" #include "ltlast/allnodes.hh"
#include "ltlvisit/clone.hh"
#include "lunabbrev.hh" #include "lunabbrev.hh"
namespace spot namespace spot
@ -23,10 +24,10 @@ namespace spot
/* f1 ^ f2 == (f1 & !f2) | (f2 & !f1) */ /* f1 ^ f2 == (f1 & !f2) | (f2 & !f1) */
case binop::Xor: case binop::Xor:
result_ = multop::instance(multop::Or, result_ = multop::instance(multop::Or,
multop::instance(multop::And, f1, multop::instance(multop::And, clone(f1),
unop::instance(unop::Not, unop::instance(unop::Not,
f2)), f2)),
multop::instance(multop::And, f2, multop::instance(multop::And, clone(f2),
unop::instance(unop::Not, unop::instance(unop::Not,
f1))); f1)));
return; return;
@ -38,7 +39,8 @@ namespace spot
/* f1 <=> f2 == (f1 & f2) | (!f1 & !f2) */ /* f1 <=> f2 == (f1 & f2) | (!f1 & !f2) */
case binop::Equiv: case binop::Equiv:
result_ = multop::instance(multop::Or, result_ = multop::instance(multop::Or,
multop::instance(multop::And, f1, f2), multop::instance(multop::And,
clone(f1), clone(f2)),
multop::instance(multop::And, multop::instance(multop::And,
unop::instance(unop::Not, unop::instance(unop::Not,
f1), f1),

89
src/ltlvisit/postfix.cc Normal file
View file

@ -0,0 +1,89 @@
#include "ltlvisit/postfix.hh"
#include "ltlast/allnodes.hh"
namespace spot
{
namespace ltl
{
postfix_visitor::postfix_visitor()
{
}
postfix_visitor::~postfix_visitor()
{
}
void
postfix_visitor::visit(atomic_prop* ap)
{
doit(ap);
}
void
postfix_visitor::visit(unop* uo)
{
uo->child()->accept(*this);
doit(uo);
}
void
postfix_visitor::visit(binop* bo)
{
bo->first()->accept(*this);
bo->second()->accept(*this);
doit(bo);
}
void
postfix_visitor::visit(multop* mo)
{
unsigned s = mo->size();
for (unsigned i = 0; i < s; ++i)
mo->nth(i)->accept(*this);
doit(mo);
}
void
postfix_visitor::visit(constant* c)
{
doit(c);
}
void
postfix_visitor::doit(atomic_prop* ap)
{
doit_default(ap);
}
void
postfix_visitor::doit(unop* uo)
{
doit_default(uo);
}
void
postfix_visitor::doit(binop* bo)
{
doit_default(bo);
}
void
postfix_visitor::doit(multop* mo)
{
doit_default(mo);
}
void
postfix_visitor::doit(constant* c)
{
doit_default(c);
}
void
postfix_visitor::doit_default(formula* f)
{
(void)f;
// Dummy implementation that does nothing.
}
}
}

38
src/ltlvisit/postfix.hh Normal file
View file

@ -0,0 +1,38 @@
#ifndef SPOT_LTLVISIT_POSTFIX_HH
# define SPOT_LTLVISIT_POSTFIX_HH
#include "ltlast/formula.hh"
#include "ltlast/visitor.hh"
namespace spot
{
namespace ltl
{
/// \brief Apply a algorithm on each node of an AST,
/// during a postfix traversal.
///
/// Override one or more of the postifix_visitor::doit methods
/// with the algorithm to apply.
class postfix_visitor : public visitor
{
public:
postfix_visitor();
virtual ~postfix_visitor();
void visit(atomic_prop* ap);
void visit(unop* uo);
void visit(binop* bo);
void visit(multop* mo);
void visit(constant* c);
virtual void doit(atomic_prop* ap);
virtual void doit(unop* uo);
virtual void doit(binop* bo);
virtual void doit(multop* mo);
virtual void doit(constant* c);
virtual void doit_default(formula* f);
};
}
}
#endif // SPOT_LTLVISIT_POSTFIX_HH