Check trivial multop equality at build time. The makes the

equal visitor useless, since two equals formulae will now
share the same address.

* src/ltlast/multop.hh (add_sorted): New function.
(paircmp): New comparison functor.
(map): Use paircmp, we want to compare the vectors' contents,
not their addresses.
* src/ltlast/multop.cc (add_sorted): New function.
(add): Use it.
* src/ltltest/equals.cc, src/ltltest/tostring.cc: Compare
pointers instead of calling equal.
* src/ltlvisit/equals.cc, src/ltlvisit/equals.hh: Delete.
* src/ltlvisit/Makefile.am (libltlvisit_la_SOURCES): Remove
equals.cc and equals.hh.
* wrap/spot.i: Do not include equals.hh.
This commit is contained in:
Alexandre Duret-Lutz 2003-05-16 07:39:41 +00:00
parent 9123e56ff9
commit 1cdfea31b0
10 changed files with 65 additions and 197 deletions

View file

@ -13,8 +13,6 @@ libltlvisit_la_SOURCES = \
dump.hh \
tostring.cc \
tostring.hh \
equals.cc \
equals.hh \
lunabbrev.hh \
lunabbrev.cc \
nenoform.hh \

View file

@ -1,136 +0,0 @@
#include <vector>
#include "equals.hh"
#include "ltlast/allnodes.hh"
namespace spot
{
namespace ltl
{
equals_visitor::equals_visitor(const formula* f)
: f_(f), result_(false)
{
}
equals_visitor::~equals_visitor()
{
}
bool
equals_visitor::result() const
{
return result_;
}
void
equals_visitor::visit(const atomic_prop* ap)
{
result_ = f_ == ap;
}
void
equals_visitor::visit(const constant* c)
{
result_ = f_ == c;
}
void
equals_visitor::visit(const unop* uo)
{
const unop* p = dynamic_cast<const unop*>(f_);
if (!p || p->op() != uo->op())
return;
f_ = p->child();
uo->child()->accept(*this);
}
void
equals_visitor::visit(const binop* bo)
{
const binop* p = dynamic_cast<const binop*>(f_);
if (!p || p->op() != bo->op())
return;
// The current visitor will descend the left branch.
// Build a second visitor for the right branch.
equals_visitor v2(p->second());
f_ = p->first();
bo->first()->accept(*this);
if (result_ == false)
return;
bo->second()->accept(v2);
result_ = v2.result();
}
void
equals_visitor::visit(const multop* m)
{
const multop* p = dynamic_cast<const multop*>(f_);
if (!p || p->op() != m->op())
return;
// This check is a bit more complicated than other checks
// because And(a, b, c) is equal to And(c, a, b, a).
unsigned m_size = m->size();
unsigned p_size = p->size();
std::vector<bool> p_seen(p_size, false);
for (unsigned nf = 0; nf < m_size; ++nf)
{
unsigned np;
const formula* mnth = m->nth(nf);
for (np = 0; np < p_size; ++np)
{
if (equals(p->nth(np), mnth))
{
p_seen[np] = true;
break;
}
}
// We we haven't found mnth in any child of p, then
// the two formulas aren't equal.
if (np == p_size)
return;
}
// At this point, we have found all children of m' in children
// of `p'. That doesn't means that both formula are equal.
// Condider m = And(a, b, c) against p = And(c, d, a, b).
// We should now check if any unmarked (accodring to p_seen)
// child of `p' has an counterpart in `m'. Because `m' might
// contain duplicate children, its faster to test that
// unmarked children of `p' have a counterpart in marked children
// of `p'.
for (unsigned np = 0; np < p_size; ++np)
{
// Consider only unmarked children.
if (p_seen[np])
continue;
// Compare with marked children.
unsigned np2;
const formula *pnth = p->nth(np);
for (np2 = 0; np2 < p_size; ++np2)
if (p_seen[np2] && equals(p->nth(np2), pnth))
break;
// No match? Too bad.
if (np2 == p_size)
return;
}
// The two formulas match.
result_ = true;
}
bool
equals(const formula* f1, const formula* f2)
{
equals_visitor v(f1);
f2->accept(v);
return v.result();
}
}
}

View file

@ -1,46 +0,0 @@
#include "ltlast/formula.hh"
#include "ltlast/visitor.hh"
namespace spot
{
namespace ltl
{
/// \brief Check for equality between two formulae.
///
/// This visitor is public, because it's convenient
/// to derive from it and override some of its methods.
/// But if you just want the functionality, consider using
/// spot::ltl::equals instead.
class equals_visitor : public const_visitor
{
public:
equals_visitor(const formula* f);
virtual ~equals_visitor();
// Return true iff the visitor has visited a
// formula which is equal to `f'.
bool result() const;
void visit(const atomic_prop* ap);
void visit(const unop* uo);
void visit(const binop* bo);
void visit(const multop* bo);
void visit(const constant* c);
private:
const formula* f_;
bool result_;
};
/// \brief Check whether two formulae are syntaxically equal.
/// \return \c true iff \a f1 equals \a f2.
///
/// This tests for syntaxic equality rather than semantic equality.
/// Two formulae are equals of their abstract syntax tree are equals.
/// ltl::multop children can be permuted or repeated without
/// impact on the result of this comparison.
bool equals(const formula* f1, const formula* f2);
}
}