Add support for W (weak until) and M (strong release) operators.

* src/ltlast/binop.cc, src/ltlast/binop.cc: Add support for
these new operators.
* src/ltlparse/ltlparse.yy, src/ltlparse/ltlscan.ll: Parse them.
* src/ltltest/reduccmp.test: Add new tests for W and M.
* src/ltlvisit/basicreduce.cc, src/ltlvisit/contain.cc,
src/ltlvisit/lunabbrev.cc, src/ltlvisit/nenoform.cc,
src/ltlvisit/randomltl.cc, src/ltlvisit/randomltl.hh,
src/ltlvisit/reduce.cc, src/ltlvisite/simpfg.cc,
src/ltlvisit/simpfg.hh, src/ltlvisit/syntimpl.cc,
src/ltlvisit/tostring.cc, src/tgba/formula2bdd.cc,
src/tgbaalgos/eltl2tgba_lacim.cc, src/tgbaalgos/ltl2taa.cc,
src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/ltl2tgba_lacim.cc:
Add support for W and M.
* src/tgbatest/ltl2neverclaim.test: Test never claim output
using LBTT, this is more thorough.  Also we cannot use -N
any more in the spotlbtt.test.
* src/tgbatests/ltl2tgba.cc: Define M and W for ELTL.
* src/tgbatest/ltl2neverclaim.test: Test W and M, and use
-DS instead of -N, because lbtt-translate does not want
to translate these operators for tools that masquerade as Spin.
This commit is contained in:
Alexandre Duret-Lutz 2010-04-07 10:44:07 +02:00
parent 35a57c6dff
commit 0fc0ea3166
25 changed files with 584 additions and 123 deletions

View file

@ -253,7 +253,8 @@ namespace spot
formula* f2 = bo->second();
unop* fu1;
unop* fu2;
switch (bo->op())
binop::type op = bo->op();
switch (op)
{
case binop::Xor:
case binop::Equiv:
@ -262,31 +263,49 @@ namespace spot
basic_reduce(f1),
basic_reduce(f2));
return;
case binop::W:
case binop::M:
case binop::U:
case binop::R:
f1 = basic_reduce(f1);
f2 = basic_reduce(f2);
// a W false = Ga
if (op == binop::W && f2 == constant::false_instance())
{
result_ = unop::instance(unop::G, f1);
return;
}
// a M true = Fa
if (op == binop::M && f2 == constant::true_instance())
{
result_ = unop::instance(unop::F, f1);
return;
}
// a U false = false
// a U true = true
// a R false = false
// a R true = true
// a W true = true
// a M false = false
if (dynamic_cast<constant*>(f2))
{
result_ = f2;
f1->destroy();
return;
}
f1 = basic_reduce(f1);
// X(a) U X(b) = X(a U b)
// X(a) R X(b) = X(a R b)
// X(a) W X(b) = X(a W b)
// X(a) M X(b) = X(a M b)
fu1 = dynamic_cast<unop*>(f1);
fu2 = dynamic_cast<unop*>(f2);
if (fu1 && fu2
&& fu1->op() == unop::X
&& fu2->op() == unop::X)
{
formula* ftmp = binop::instance(bo->op(),
formula* ftmp = binop::instance(op,
basic_reduce(fu1->child()),
basic_reduce(fu2->child()));
result_ = unop::instance(unop::X, basic_reduce(ftmp));
@ -296,7 +315,7 @@ namespace spot
return;
}
result_ = binop::instance(bo->op(), f1, f2);
result_ = binop::instance(op, f1, f2);
return;
}
/* Unreachable code. */

View file

@ -1,4 +1,4 @@
// Copyright (C) 2009 Laboratoire de Recherche et Développement
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2006, 2007 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -202,6 +202,31 @@ namespace spot
result_ = binop::instance(binop::U, a, b);
}
break;
case binop::W:
// if (a W b) => b, then keep b !
if (stronger && lcc->contained(bo, b))
{
a->destroy();
result_ = b;
}
// if a => b, then a W b = b.
else if ((!stronger) && lcc->contained(a, b))
{
a->destroy();
result_ = b;
}
// if !a => b, then a W b = 1
else if (lcc->neg_contained(a, b))
{
a->destroy();
b->destroy();
result_ = constant::true_instance();
}
else
{
result_ = binop::instance(binop::W, a, b);
}
break;
case binop::R:
// if (a R b) => b, then keep b !
if (stronger && lcc->contained(b, bo))
@ -226,6 +251,31 @@ namespace spot
result_ = binop::instance(binop::R, a, b);
}
break;
case binop::M:
// if (a M b) => b, then keep b !
if (stronger && lcc->contained(b, bo))
{
a->destroy();
result_ = b;
}
// if b => a, then a M b = b.
else if ((!stronger) && lcc->contained(b, a))
{
a->destroy();
result_ = b;
}
// if a => !b, then a M b = 0
else if (lcc->contained_neg(a, b))
{
a->destroy();
b->destroy();
result_ = constant::false_instance();
}
else
{
result_ = binop::instance(binop::M, a, b);
}
break;
default:
result_ = binop::instance(bo->op(), a, b);
}

View file

@ -1,4 +1,4 @@
// Copyright (C) 2009 Laboratoire de Recherche et Développement
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -44,7 +44,8 @@ namespace spot
formula* f1 = recurse(bo->first());
formula* f2 = recurse(bo->second());
switch (bo->op())
binop::type op = bo->op();
switch (op)
{
/* f1 ^ f2 == (f1 & !f2) | (f2 & !f1) */
case binop::Xor:
@ -74,9 +75,13 @@ namespace spot
return;
/* f1 U f2 == f1 U f2 */
/* f1 R f2 == f1 R f2 */
/* f1 W f2 == f1 W f2 */
/* f1 M f2 == f1 M f2 */
case binop::U:
case binop::R:
result_ = binop::instance(bo->op(), f1, f2);
case binop::W:
case binop::M:
result_ = binop::instance(op, f1, f2);
return;
}
/* Unreachable code. */

View file

@ -1,4 +1,4 @@
// Copyright (C) 2009 Laboratoire de Recherche et Développement
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -154,6 +154,16 @@ namespace spot
result_ = binop::instance(negated_ ? binop::U : binop::R,
recurse(f1), recurse(f2));
return;
case binop::W:
/* !(a W b) == !a M !b */
result_ = binop::instance(negated_ ? binop::M : binop::W,
recurse(f1), recurse(f2));
return;
case binop::M:
/* !(a M b) == !a W !b */
result_ = binop::instance(negated_ ? binop::W : binop::M,
recurse(f1), recurse(f2));
return;
}
/* Unreachable code. */
assert(0);

View file

@ -1,4 +1,4 @@
// Copyright (C) 2008, 2009 Laboratoire de Recherche et Développement
// Copyright (C) 2008, 2009, 2010 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2005 Laboratoire d'Informatique de Paris 6
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
@ -102,7 +102,7 @@ namespace spot
namespace
{
const int proba_size = 14;
const int proba_size = 16;
}
random_ltl::random_ltl(const atomic_prop_set* ap)
@ -122,8 +122,10 @@ namespace spot
proba_[9].setup("xor", 3, binop_builder<binop::Xor>);
proba_[10].setup("R", 3, binop_builder<binop::R>);
proba_[11].setup("U", 3, binop_builder<binop::U>);
proba_[12].setup("and", 3, multop_builder<multop::And>);
proba_[13].setup("or", 3, multop_builder<multop::Or>);
proba_[12].setup("W", 3, binop_builder<binop::W>);
proba_[13].setup("M", 3, binop_builder<binop::M>);
proba_[14].setup("and", 3, multop_builder<multop::And>);
proba_[15].setup("or", 3, multop_builder<multop::Or>);
proba_[0].proba = ap_->size();

View file

@ -1,3 +1,5 @@
// Copyright (C) 2010 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// Copyright (C) 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
@ -82,6 +84,8 @@ namespace spot
/// xor 1
/// R 1
/// U 1
/// W 1
/// M 1
/// and 1
/// or 1
/// \endverbatim

View file

@ -1,5 +1,5 @@
// Copyright (C) 2008, 2009 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2008, 2009, 2010 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
// Copyright (C) 2004, 2006, 2007 Laboratoire d'Informatique de
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
// Université Pierre et Marie Curie.
@ -110,23 +110,46 @@ namespace spot
void
visit(binop* bo)
{
binop::type op = bo->op();
formula* f2 = recurse(bo->second());
bool f2_eventual = false;
/* If b is a pure eventuality formula then a U b = b.
If b is a pure universality formula a R b = b. */
if ((opt_ & Reduce_Eventuality_And_Universality)
&& ((is_eventual(f2) && ((bo->op()) == binop::U))
|| (is_universal(f2) && ((bo->op()) == binop::R))))
if (opt_ & Reduce_Eventuality_And_Universality)
{
result_ = f2;
return;
f2_eventual = is_eventual(f2);
/* If b is a pure eventuality formula then a U b = b.
If b is a pure universality formula a R b = b. */
if ((f2_eventual && (op == binop::U))
|| (is_universal(f2) && (op == binop::R)))
{
result_ = f2;
return;
}
}
/* case of implies */
formula* f1 = recurse(bo->first());
formula* f1 = recurse(bo->first());
if (opt_ & Reduce_Eventuality_And_Universality)
{
/* If a&b is a pure eventuality formula then a M b = a & b.
If a is a pure universality formula a W b = a|b. */
if (is_eventual(f1) && f2_eventual && (op == binop::M))
{
result_ = multop::instance(multop::And, f1, f2);
return;
}
if (is_universal(f1) && (op == binop::W))
{
result_ = multop::instance(multop::Or, f1, f2);
return;
}
}
/* case of implies */
if (opt_ & Reduce_Syntactic_Implications)
{
switch (bo->op())
switch (op)
{
case binop::Xor:
case binop::Equiv:
@ -149,9 +172,10 @@ namespace spot
return;
}
/* a < b => a U (b U c) = (b U c) */
/* a < b => a U (b W c) = (b W c) */
{
binop* bo = dynamic_cast<binop*>(f2);
if (bo && bo->op() == binop::U
if (bo && (bo->op() == binop::U || bo->op() == binop::W)
&& syntactic_implication(f1, bo->first()))
{
result_ = f2;
@ -188,9 +212,68 @@ namespace spot
}
}
break;
case binop::W:
/* a < b => a W b = b */
if (syntactic_implication(f1, f2))
{
result_ = f2;
f1->destroy();
return;
}
/* !b < a => a W b = 1 */
if (syntactic_implication_neg(f2, f1, false))
{
result_ = constant::true_instance();
f1->destroy();
f2->destroy();
return;
}
/* a < b => a W (b U c) = (b U c) */
/* a < b => a W (b W c) = (b W c) */
{
binop* bo = dynamic_cast<binop*>(f2);
if (bo && (bo->op() == binop::U || bo->op() == binop::W)
&& syntactic_implication(f1, bo->first()))
{
result_ = f2;
f1->destroy();
return;
}
}
break;
case binop::M:
/* b < a => a M b = b */
if (syntactic_implication(f2, f1))
{
result_ = f2;
f1->destroy();
return;
}
/* b < !a => a M b = 0 */
if (syntactic_implication_neg(f2, f1, true))
{
result_ = constant::false_instance();
f1->destroy();
f2->destroy();
return;
}
/* b < a => a R (b R c) = b R c */
{
binop* bo = dynamic_cast<binop*>(f2);
if (bo && bo->op() == binop::R
&& syntactic_implication(bo->first(), f1))
{
result_ = f2;
f1->destroy();
return;
}
}
break;
}
}
result_ = binop::instance(bo->op(), f1, f2);
result_ = binop::instance(op, f1, f2);
}
void

View file

@ -1,3 +1,7 @@
// Copyright (C) 2010 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
@ -42,13 +46,14 @@ namespace spot
{
formula* f1 = recurse(bo->first());
formula* f2 = recurse(bo->second());
binop::type op = bo->op();
switch (bo->op())
switch (op)
{
case binop::Xor:
case binop::Implies:
case binop::Equiv:
result_ = binop::instance(bo->op(), f1, f2);
result_ = binop::instance(op, f1, f2);
return;
/* true U f2 == F(f2) */
case binop::U:
@ -64,6 +69,20 @@ namespace spot
else
result_ = binop::instance(binop::R, f1, f2);
return;
/* f1 W false == G(f1) */
case binop::W:
if (f2 == constant::false_instance())
result_ = unop::instance(unop::G, f1);
else
result_ = binop::instance(binop::W, f1, f2);
return;
/* f1 M true == F(f1) */
case binop::M:
if (f1 == constant::true_instance())
result_ = unop::instance(unop::F, f2);
else
result_ = binop::instance(binop::M, f1, f2);
return;
}
/* Unreachable code. */
assert(0);

View file

@ -1,3 +1,5 @@
// Copyright (C) 2010 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
// et Marie Curie.
@ -30,6 +32,14 @@ namespace spot
{
/// \brief Replace <code>true U f</code> and <code>false R g</code> by
/// <code>F f</code> and <code>G g</code>.
///
/// Perform the following rewriting (from left to right):
///
/// - true U a = F a
/// - a M true = F a
/// - false R a = G a
/// - a W false = G a
///
/// \ingroup ltl_visitor
class simplify_f_g_visitor : public clone_visitor
{
@ -46,6 +56,14 @@ namespace spot
/// \brief Replace <code>true U f</code> and <code>false R g</code> by
/// <code>F f</code> and <code>G g</code>.
///
/// Perform the following rewriting (from left to right):
///
/// - true U a = F a
/// - a M true = F a
/// - false R a = G a
/// - a W false = G a
///
/// \ingroup ltl_rewriting
formula* simplify_f_g(const formula* f);
}

View file

@ -1,4 +1,4 @@
// Copyright (C) 2009 Laboratoire de Recherche et Développement
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -108,7 +108,13 @@ namespace spot
// Both operand must be purely eventual, unlike in
// the proceedings of Concur'00. (The revision of
// the paper available at
// http://www1.bell-labs.com/project/TMP/ is fixed.)
// http://www.bell-labs.com/project/TMP/ is fixed.)
|| (recurse_ev(f1) && recurse_ev(f2)))
eventual = true;
return;
case binop::W:
universal = recurse_un(f1) && recurse_un(f2);
if ((f2 == constant::true_instance())
|| (recurse_ev(f1) && recurse_ev(f2)))
eventual = true;
return;
@ -118,6 +124,12 @@ namespace spot
|| (recurse_un(f1) && recurse_un(f2)))
universal = true;
return;
case binop::M:
eventual = recurse_ev(f1) && recurse_ev(f2);
if ((f2 == constant::false_instance())
|| (recurse_un(f1) && recurse_un(f2)))
universal = true;
return;
}
/* Unreachable code. */
assert(0);
@ -263,6 +275,7 @@ namespace spot
case binop::Implies:
return;
case binop::U:
case binop::W:
if (syntactic_implication(f, f2))
result_ = true;
return;
@ -285,6 +298,25 @@ namespace spot
&& syntactic_implication(f, f2))
result_ = true;
return;
case binop::M:
if (fb && fb->op() == binop::M)
if (syntactic_implication(fb->first(), f1) &&
syntactic_implication(fb->second(), f2))
{
result_ = true;
return;
}
if (fu && fu->op() == unop::F)
if (f2 == constant::true_instance() &&
syntactic_implication(fu->child(), f1))
{
result_ = true;
return;
}
if (syntactic_implication(f, f1)
&& syntactic_implication(f, f2))
result_ = true;
return;
}
/* Unreachable code. */
assert(0);
@ -480,6 +512,26 @@ namespace spot
&& syntactic_implication(f2, f))
result_ = true;
return;
case binop::W:
/* (a < c) && (c < d) => a W b < c W d */
if (fb && fb->op() == binop::W)
if (syntactic_implication(f1, fb->first()) &&
syntactic_implication(f2, fb->second()))
{
result_ = true;
return;
}
if (fu && fu->op() == unop::G)
if (f2 == constant::false_instance() &&
syntactic_implication(f1, fu->child()))
{
result_ = true;
return;
}
if (syntactic_implication(f1, f)
&& syntactic_implication(f2, f))
result_ = true;
return;
case binop::R:
if (fu && fu->op() == unop::G)
if (f1 == constant::false_instance() &&
@ -491,6 +543,17 @@ namespace spot
if (syntactic_implication(f2, f))
result_ = true;
return;
case binop::M:
if (fu && fu->op() == unop::F)
if (f2 == constant::true_instance() &&
syntactic_implication(f1, fu->child()))
{
result_ = true;
return;
}
if (syntactic_implication(f2, f))
result_ = true;
return;
}
/* Unreachable code. */
assert(0);

View file

@ -1,4 +1,4 @@
// Copyright (C) 2008 Laboratoire de Recherche et Développement
// Copyright (C) 2008, 2010 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
// Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
@ -118,6 +118,12 @@ namespace spot
case binop::R:
os_ << " R ";
break;
case binop::W:
os_ << " W ";
break;
case binop::M:
os_ << " M ";
break;
}
bo->second()->accept(*this);
@ -276,6 +282,17 @@ namespace spot
os_ << " V ";
bo->second()->accept(*this);
break;
/* W and M are not supported by Spin */
case binop::W:
bo->first()->accept(*this);
os_ << " W ";
bo->second()->accept(*this);
break;
case binop::M:
bo->first()->accept(*this);
os_ << " M ";
bo->second()->accept(*this);
break;
}
if (!top_level)