fix a memory leak in basic LTL simplifications

When something like XFa & FXa is reduced, the subformulae XFa and FXa
are both rewritten separately to XFa, and then the vector of arguments
of the And operators, [XFa,XFa], is passed through a specialized loop
that searches of the form X(...) that can potentially be simplified with
some other terms.  This loop converts the vector [XFa,XFa] into the set
{XFa,XFa}={XFa} and forgot to deal with the case where the insertion
would actually not add an existing subformula.

* src/ltlvisit/simplify.cc: Fix the code for Or, and And.
* src/ltltest/reduc0.test: New file, to test it.
* src/ltltest/Makefile.am (TESTS): Add it.
* src/ltltest/reduccmp.test: Add an extra test that does not
trigger the bug (because reduccmp.test uses more than basic
optimizations, and the implication-based simplifications are
already able to detect that XFa and FXa are equivalent).
This commit is contained in:
Alexandre Duret-Lutz 2013-03-28 17:24:20 +01:00
parent 4b70453d74
commit a9fc213a44
4 changed files with 72 additions and 15 deletions

View file

@ -2600,6 +2600,8 @@ namespace spot
{
if (!(*res)[n])
continue;
if ((*res)[n]->is_X_free())
continue;
const formula* xarg = is_XWU((*res)[n]);
if (xarg)
@ -2612,8 +2614,6 @@ namespace spot
// - X(...)
// - b | X(b R ...)
// - b | X(b M ...)
if ((*res)[n]->is_X_free())
continue;
const binop* barg = is_bXbRM((*res)[n]);
if (barg)
@ -2636,12 +2636,17 @@ namespace spot
{ \
unsigned y = a2->size(); \
for (unsigned n = 0; n < y; ++n) \
xgset. \
insert(a2->nth(n)->clone()); \
{ \
const formula* sub = a2->nth(n); \
if (xgset.insert(sub).second) \
sub->clone(); \
} \
} \
else \
{ \
xgset.insert(g->child()->clone()); \
const formula* sub = g->child(); \
if (xgset.insert(sub).second) \
sub->clone(); \
}
HANDLE_G;
}
@ -2657,13 +2662,15 @@ namespace spot
}
else
{
xset.insert(x->clone());
if (xset.insert(x).second)
x->clone();
}
}
}
else
{
xset.insert(c->clone());
if (xset.insert(c).second)
c->clone();
}
(*res)[n]->destroy();
(*res)[n] = 0;
@ -3307,6 +3314,8 @@ namespace spot
{
if (!(*res)[n])
continue;
if ((*res)[n]->is_X_free())
continue;
const formula* xarg = is_XRM((*res)[n]);
if (xarg)
@ -3319,8 +3328,6 @@ namespace spot
// - X(...)
// - b & X(b W ...)
// - b & X(b U ...)
if ((*res)[n]->is_X_free())
continue;
const binop* barg = is_bXbWU((*res)[n]);
if (barg)
@ -3329,7 +3336,6 @@ namespace spot
continue;
}
const unop* uo = is_X((*res)[n]);
if (!uo)
continue;
@ -3344,12 +3350,17 @@ namespace spot
{ \
unsigned y = o2->size(); \
for (unsigned n = 0; n < y; ++n) \
xfset. \
insert(o2->nth(n)->clone()); \
{ \
const formula* sub = o2->nth(n); \
if (xfset.insert(sub).second) \
sub->clone(); \
} \
} \
else \
{ \
xfset.insert(f->child()->clone()); \
const formula* sub = f->child(); \
if (xfset.insert(sub).second) \
sub->clone(); \
}
HANDLE_F;
}
@ -3365,13 +3376,15 @@ namespace spot
}
else
{
xset.insert(x->clone());
if (xset.insert(x).second)
x->clone();
}
}
}
else
{
xset.insert(c->clone());
if (xset.insert(c).second)
c->clone();
}
(*res)[n]->destroy();
(*res)[n] = 0;
@ -3989,7 +4002,12 @@ namespace spot
simplify_recursively(const formula* f,
ltl_simplifier_cache* c)
{
#ifdef TRACE
static int srec = 0;
for (int i = srec; i; --i)
trace << ' ';
trace << "** simplify_recursively(" << to_string(f) << ")";
#endif
const formula* result = c->lookup_simplified(f);
if (result)
@ -4002,6 +4020,10 @@ namespace spot
trace << " miss" << std::endl;
}
#ifdef TRACE
++srec;
#endif
if (f->is_boolean() && c->options.boolean_to_isop)
{
result = c->boolean_to_isop(f);
@ -4013,8 +4035,13 @@ namespace spot
result = v.result();
}
#ifdef TRACE
--srec;
for (int i = srec; i; --i)
trace << ' ';
trace << "** simplify_recursively(" << to_string(f) << ") result: "
<< to_string(result) << std::endl;
#endif
c->cache_simplified(f, result);
return result;