* src/ltlvisit/nenoform.hh, src/ltlvisit/nenoform.cc: New files.

* src/ltlvisit/Makefile.am (libltlvisit_a_SOURCES): Add them.
* src/ltltest/equals.cc (main) [NENOFORM]: Call negative_normal_form.
* src/ltltest/nenoform.test, src/ltltest/tunenoform.test: New files.
* src/ltltest/Makefile.am (check_PROGRAMS): Add nenoform and
tunenoform.
(nenoform_SOURCES, nenoform_CPPFLAGS, tunenoform_SOURCES,
tunenoform_CPPFLAGS): New variables.
(TESTS): Add nenoform.test and tunenoform.test.
This commit is contained in:
Alexandre Duret-Lutz 2003-04-17 13:12:11 +00:00
parent e58aae95c0
commit 0c7a2412a4
9 changed files with 308 additions and 2 deletions

View file

@ -11,5 +11,7 @@ libltlvisit_a_SOURCES = \
equals.hh \
lunabbrev.hh \
lunabbrev.cc \
nenoform.hh \
nenoform.cc \
tunabbrev.hh \
tunabbrev.cc

173
src/ltlvisit/nenoform.cc Normal file
View file

@ -0,0 +1,173 @@
#include "nenoform.hh"
#include "ltlast/allnodes.hh"
namespace spot
{
namespace ltl
{
class negative_normal_form_visitor : public const_visitor
{
public:
negative_normal_form_visitor(bool negated)
: negated_(negated)
{
}
virtual
~negative_normal_form_visitor()
{
}
formula* result() const
{
return result_;
}
void
visit(const atomic_prop* ap)
{
formula* f = new atomic_prop(ap->name());
if (negated_)
result_ = new unop(unop::Not, f);
else
result_ = f;
}
void
visit(const constant* c)
{
if (! negated_)
{
result_ = new constant(c->val());
return;
}
switch (c->val())
{
case constant::True:
result_ = new constant(constant::False);
return;
case constant::False:
result_ = new constant(constant::True);
return;
}
/* Unreachable code. */
assert(0);
}
void
visit(const unop* uo)
{
const formula* f = uo->child();
switch (uo->op())
{
case unop::Not:
result_ = recurse_(f, negated_ ^ true);
return;
case unop::X:
/* !Xa == X!a */
result_ = new unop(unop::X, recurse(f));
return;
case unop::F:
/* !Fa == G!a */
result_ = new unop(negated_ ? unop::G : unop::F, recurse(f));
return;
case unop::G:
/* !Ga == F!a */
result_ = new unop(negated_ ? unop::F : unop::G, recurse(f));
return;
}
/* Unreachable code. */
assert(0);
}
void
visit(const binop* bo)
{
const formula* f1 = bo->first();
const formula* f2 = bo->second();
switch (bo->op())
{
case binop::Xor:
/* !(a ^ b) == a <=> b */
result_ = new binop(negated_ ? binop::Equiv : binop::Xor,
recurse_(f1, false), recurse_(f2, false));
return;
case binop::Equiv:
/* !(a <=> b) == a ^ b */
result_ = new binop(negated_ ? binop::Xor : binop::Equiv,
recurse_(f1, false), recurse_(f2, false));
return;
case binop::Implies:
if (negated_)
/* !(a => b) == a & !b */
result_ = new multop(multop::And,
recurse_(f1, false), recurse_(f2, true));
else
result_ = new binop(binop::Implies, recurse(f1), recurse(f2));
return;
case binop::U:
/* !(a U b) == !a R !b */
result_ = new binop(negated_ ? binop::R : binop::U,
recurse(f1), recurse(f2));
return;
case binop::R:
/* !(a R b) == !a U !b */
result_ = new binop(negated_ ? binop::U : binop::R,
recurse(f1), recurse(f2));
return;
}
/* Unreachable code. */
assert(0);
}
void
visit(const multop* mo)
{
/* !(a & b & c) == !a | !b | !c */
/* !(a | b | c) == !a & !b & !c */
multop::type op = mo->op();
if (negated_)
switch (op)
{
case multop::And:
op = multop::Or;
break;
case multop::Or:
op = multop::And;
break;
}
multop* res = new multop(op);
unsigned mos = mo->size();
for (unsigned i = 0; i < mos; ++i)
res->add(recurse(mo->nth(i)));
result_ = res;
}
formula*
recurse_(const formula* f, bool negated)
{
return negative_normal_form(f, negated);
}
formula*
recurse(const formula* f)
{
return recurse_(f, negated_);
}
protected:
formula* result_;
bool negated_;
};
formula*
negative_normal_form(const formula* f, bool negated)
{
negative_normal_form_visitor v(negated);
f->accept(v);
return v.result();
}
}
}

18
src/ltlvisit/nenoform.hh Normal file
View file

@ -0,0 +1,18 @@
#ifndef SPOT_LTLVISIT_NENOFORM_HH
# define SPOT_LTLVISIT_NENOFORM_HH
#include "ltlast/formula.hh"
#include "ltlast/visitor.hh"
namespace spot
{
namespace ltl
{
/* Return the negative normal form of F, i.e., all negations
of the formula are pushed in front of the atomic propositions.
If NEGATED is true, return the normal form of !F instead. */
formula* negative_normal_form(const formula* f, bool negated = false);
}
}
#endif // SPOT_LTLVISIT_NENOFORM_HH