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:
parent
2580fc6f91
commit
e4ecc2d465
4 changed files with 107 additions and 8 deletions
6
NEWS
6
NEWS
|
|
@ -9,6 +9,12 @@ New in spot 1.0a (not released):
|
||||||
- "P0.init" is parsed as an atomic even without the double quotes,
|
- "P0.init" is parsed as an atomic even without the double quotes,
|
||||||
but it was always output with double quotes. This version will
|
but it was always output with double quotes. This version will
|
||||||
not quote this atomic proposition anymore.
|
not quote this atomic proposition anymore.
|
||||||
|
* Minor improvements:
|
||||||
|
- Four new LTL simplifications rules:
|
||||||
|
GF(a|Xb) = GF(a|b)
|
||||||
|
GF(a|Fb) = GF(a|b)
|
||||||
|
FG(a&Xb) = FG(a&b)
|
||||||
|
FG(a&Gb) = FG(a&b)
|
||||||
* Pruning:
|
* Pruning:
|
||||||
- lbtt has been removed from the distribution. A copy of the last
|
- lbtt has been removed from the distribution. A copy of the last
|
||||||
version we distributed is still available at
|
version we distributed is still available at
|
||||||
|
|
|
||||||
|
|
@ -1313,9 +1313,11 @@ instead of $\equiv$, and they can be disabled by setting the
|
||||||
The following are simplification rules for unary operators (applied
|
The following are simplification rules for unary operators (applied
|
||||||
from left to right, as usual):
|
from left to right, as usual):
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
\X\F\G f & \equiv \F\G f & \F\X f & \equiv \X\F f & \G\X f & \equiv \X\G f\\
|
\X\F\G f & \equiv \F\G f & \F\X f & \equiv \X\F f & \G\X f & \equiv \X\G f \\
|
||||||
\X\G\F f & \equiv \G\F f & \F(f\U g) & \equiv \F g & \G(f \R g) & \equiv \G g \\
|
\X\G\F f & \equiv \G\F f & \F(f\U g) & \equiv \F g & \G(f \R g) & \equiv \G g \\
|
||||||
& & \F(f\M g) & \equiv \F (f\AND g) & \G(f \W g) & \equiv \G(f\OR g)
|
& & \F(f\M g) & \equiv \F (f\AND g) & \G(f \W g) & \equiv \G(f\OR g) \\
|
||||||
|
& & \F\G(f\AND \X g) & \equiv \F\G(f\AND g) & \G\F(f\OR \X g) & \equiv \G\F(f\OR g) \\
|
||||||
|
& & \F\G(f\AND \G g) & \equiv \F\G(f\AND g) & \G\F(f\OR \F g) & \equiv \G\F(f\OR g) \\
|
||||||
\end{align*}
|
\end{align*}
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
\G(f_1\OR\ldots\OR f_n \OR \G\F(g_1)\OR\ldots\OR \G\F(g_m)) & \equiv \G(f_1\OR\ldots\OR f_n)\OR \G\F(g_1\OR\ldots\OR g_m)
|
\G(f_1\OR\ldots\OR f_n \OR \G\F(g_1)\OR\ldots\OR \G\F(g_m)) & \equiv \G(f_1\OR\ldots\OR f_n)\OR \G\F(g_1\OR\ldots\OR g_m)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Copyright (C) 2009, 2010, 2011, 2012 Laboratoire de Recherche et
|
# -*- coding: utf-8 -*-
|
||||||
# Developpement de l'Epita (LRDE).
|
# 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),
|
# 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.
|
# et Marie Curie.
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# 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 'FX(a)' 'XF(a)'
|
||||||
run 0 $x 'GX(a)' 'XG(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) U X(b)' 'X(a U b)'
|
||||||
run 0 $x 'X(a) R X(b)' 'X(a R b)'
|
run 0 $x 'X(a) R X(b)' 'X(a R b)'
|
||||||
run 0 $x 'Xa & Xb' 'X(a & b)'
|
run 0 $x 'Xa & Xb' 'X(a & b)'
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright (C) 2011, 2012 Laboratoire de Recherche et Developpement
|
// -*- coding: utf-8 -*-
|
||||||
// de l'Epita (LRDE).
|
// Copyright (C) 2011, 2012, 2013 Laboratoire de Recherche et
|
||||||
|
// Developpement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -1184,6 +1185,47 @@ namespace spot
|
||||||
result_ = recurse_destroy(res);
|
result_ = recurse_destroy(res);
|
||||||
return;
|
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.
|
// if Fa => a, keep a.
|
||||||
|
|
@ -1288,6 +1330,47 @@ namespace spot
|
||||||
result_ = mo;
|
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 a => Ga, keep a.
|
||||||
if (opt_.containment_checks_stronger
|
if (opt_.containment_checks_stronger
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue