simplify: add four simplification rules for GF and FG

GF(a|Xb) = GF(a|b)      GF(a|Fb) = GF(a|b)
FG(a&Xb) = FG(a&b)      FG(a&Gb) = FG(a&b)

* src/ltlvisit/simplify.cc: Implement them.
* NEWS, doc/tl/tl.tex: Document them.
* src/ltltest/reduccmp.test: Test then.
This commit is contained in:
Alexandre Duret-Lutz 2013-01-11 16:07:10 +01:00
parent 2580fc6f91
commit e4ecc2d465
4 changed files with 107 additions and 8 deletions

View file

@ -1,8 +1,9 @@
#! /bin/sh
# Copyright (C) 2009, 2010, 2011, 2012 Laboratoire de Recherche et
# Developpement de l'Epita (LRDE).
# -*- coding: utf-8 -*-
# Copyright (C) 2009, 2010, 2011, 2012, 2013 Laboratoire de Recherche
# et Developpement de l'Epita (LRDE).
# Copyright (C) 2004, 2006 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
@ -98,6 +99,13 @@ for x in ../reduccmp ../reductaustr; do
run 0 $x 'FX(a)' 'XF(a)'
run 0 $x 'GX(a)' 'XG(a)'
run 0 $x 'GF(a | Xb)' 'GF(a | b)'
run 0 $x 'GF(a | Fb)' 'GF(a | b)'
run 0 $x 'GF(Xa | Fb)' 'GF(a | b)'
run 0 $x 'FG(a & Xb)' 'FG(a & b)'
run 0 $x 'FG(a & Gb)' 'FG(a & b)'
run 0 $x 'FG(Xa & Gb)' 'FG(a & b)'
run 0 $x 'X(a) U X(b)' 'X(a U b)'
run 0 $x 'X(a) R X(b)' 'X(a R b)'
run 0 $x 'Xa & Xb' 'X(a & b)'

View file

@ -1,5 +1,6 @@
// Copyright (C) 2011, 2012 Laboratoire de Recherche et Developpement
// de l'Epita (LRDE).
// -*- coding: utf-8 -*-
// Copyright (C) 2011, 2012, 2013 Laboratoire de Recherche et
// Developpement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -1184,6 +1185,47 @@ namespace spot
result_ = recurse_destroy(res);
return;
}
// FG(a & Xb) = FG(a & b)
// FG(a & Gb) = FG(a & b)
if (const unop* g = is_G(result_))
if (const multop* m = is_And(g->child()))
if (!m->is_boolean())
{
m->clone();
mospliter s(mospliter::Strip_G | mospliter::Strip_X,
m, c_);
if (!s.res_G->empty() || !s.res_X->empty())
{
result_->destroy();
s.res_other->insert(s.res_other->begin(),
s.res_G->begin(),
s.res_G->end());
delete s.res_G;
s.res_other->insert(s.res_other->begin(),
s.res_X->begin(),
s.res_X->end());
delete s.res_X;
const formula* in =
multop::instance(multop::And, s.res_other);
result_ =
recurse_destroy(unop_unop(unop::F, unop::G,
in));
return;
}
else
{
for (multop::vec::iterator j =
s.res_other->begin();
j != s.res_other->end(); ++j)
if (*j)
(*j)->destroy();
delete s.res_other;
delete s.res_G;
delete s.res_X;
// and continue...
}
}
}
// if Fa => a, keep a.
@ -1288,6 +1330,47 @@ namespace spot
result_ = mo;
}
}
// GF(a | Xb) = GF(a | b)
// GF(a | Fb) = GF(a | b)
if (const unop* f = is_F(result_))
if (const multop* m = is_Or(f->child()))
if (!m->is_boolean())
{
m->clone();
mospliter s(mospliter::Strip_F | mospliter::Strip_X,
m, c_);
if (!s.res_F->empty() || !s.res_X->empty())
{
result_->destroy();
s.res_other->insert(s.res_other->begin(),
s.res_F->begin(),
s.res_F->end());
delete s.res_F;
s.res_other->insert(s.res_other->begin(),
s.res_X->begin(),
s.res_X->end());
delete s.res_X;
const formula* in =
multop::instance(multop::Or, s.res_other);
result_ =
recurse_destroy(unop_unop(unop::G, unop::F,
in));
return;
}
else
{
for (multop::vec::iterator j =
s.res_other->begin();
j != s.res_other->end(); ++j)
if (*j)
(*j)->destroy();
delete s.res_other;
delete s.res_F;
delete s.res_X;
// and continue...
}
}
}
// if a => Ga, keep a.
if (opt_.containment_checks_stronger