Add support for {SERE} and !{SERE} closure operators.
* src/ltlast/unop.hh, src/ltlast/unop.cc: Introduce Closure and
NegClosure operators.
* src/ltlparse/ltlparse.yy: Recognize {foo} as a Closure.
* src/ltlvisit/mark.cc: Consider NegClosure as a marked operator.
* src/tgbaalgos/ltl2tgba_fm.cc (ratexp_trad_visitor): Add option to
select whether the empty_word should act like true (for {SERE}
and {!SERE}) or false (for {SERE}<>->Exp or {SERE}[]->Exp).
(ltl_trad_visitor): Translate Closure and NegClosure.
* src/tgbatest/ltl2tgba.test: Add more tests.
* src/ltlvisit/basicreduce.cc, src/ltlvisit/consterm.cc,
src/ltlvisit/nenoform.cc, src/ltlvisit/reduce.cc,
src/ltlvisit/syntimpl.cc, src/ltlvisit/tostring.cc,
src/ltlvisit/tunabbrev.cc, src/tgba/formula2bdd.cc,
src/tgbaalgos/eltl2tgba_lacim.cc, src/tgbaalgos/ltl2tgba_lacim.cc,
src/tgbaalgos/ltl2taa.cc: Straightforward update to support or
assert on these new operators.
This commit is contained in:
parent
f618e6bc1a
commit
2f8c4ac8b7
17 changed files with 343 additions and 74 deletions
|
|
@ -239,11 +239,10 @@ namespace spot
|
|||
return;
|
||||
|
||||
case unop::Finish:
|
||||
result_ = unop::instance(unop::Finish, result_);
|
||||
return;
|
||||
|
||||
case unop::Star:
|
||||
result_ = unop::instance(unop::Star, result_);
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
result_ = unop::instance(uo->op(), result_);
|
||||
return;
|
||||
}
|
||||
/* Unreachable code. */
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ namespace spot
|
|||
case unop::F:
|
||||
case unop::G:
|
||||
case unop::Finish:
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
assert(!"unsupported operator");
|
||||
break;
|
||||
case unop::Star:
|
||||
|
|
|
|||
|
|
@ -59,8 +59,24 @@ namespace spot
|
|||
}
|
||||
|
||||
void
|
||||
visit(unop*)
|
||||
visit(unop* uo)
|
||||
{
|
||||
switch (uo->op())
|
||||
{
|
||||
case unop::NegClosure:
|
||||
result_ = true;
|
||||
return;
|
||||
case unop::Finish:
|
||||
case unop::Star:
|
||||
case unop::Closure:
|
||||
case unop::Not:
|
||||
case unop::X:
|
||||
case unop::F:
|
||||
case unop::G:
|
||||
return;
|
||||
}
|
||||
/* Unreachable code. */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -148,7 +164,23 @@ namespace spot
|
|||
void
|
||||
visit(unop* uo)
|
||||
{
|
||||
result_ = uo->clone();
|
||||
switch (uo->op())
|
||||
{
|
||||
case unop::NegClosure:
|
||||
has_mark_ = true;
|
||||
/* fall through */
|
||||
case unop::Finish:
|
||||
case unop::Star:
|
||||
case unop::Closure:
|
||||
case unop::Not:
|
||||
case unop::X:
|
||||
case unop::F:
|
||||
case unop::G:
|
||||
result_ = uo->clone();
|
||||
return;
|
||||
}
|
||||
/* Unreachable code. */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -181,7 +213,9 @@ namespace spot
|
|||
|
||||
binop* bo = dynamic_cast<binop*>(f);
|
||||
if (!bo)
|
||||
res->push_back(recurse(f));
|
||||
{
|
||||
res->push_back(recurse(f));
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (bo->op())
|
||||
|
|
@ -317,7 +351,7 @@ namespace spot
|
|||
case binop::Xor:
|
||||
case binop::Implies:
|
||||
case binop::Equiv:
|
||||
assert(!"mark no defined on logic abbreviations");
|
||||
assert(!"mark not defined on logic abbreviations");
|
||||
case binop::U:
|
||||
case binop::W:
|
||||
case binop::M:
|
||||
|
|
|
|||
|
|
@ -108,15 +108,21 @@ namespace spot
|
|||
result_ = unop::instance(negated_ ? unop::F : unop::G,
|
||||
recurse(f));
|
||||
return;
|
||||
case unop::Finish:
|
||||
/* Finish(x) is not simplified */
|
||||
result_ = unop::instance(unop::Finish, recurse_(f, false));
|
||||
if (negated_)
|
||||
result_ = unop::instance(unop::Not, result_);
|
||||
case unop::Closure:
|
||||
result_ = unop::instance(negated_ ?
|
||||
unop::NegClosure : unop::Closure,
|
||||
recurse_(f, false));
|
||||
return;
|
||||
case unop::Star:
|
||||
case unop::NegClosure:
|
||||
result_ = unop::instance(negated_ ?
|
||||
unop::Closure : uo->op(),
|
||||
recurse_(f, false));
|
||||
return;
|
||||
/* !Finish(x), is not simplified */
|
||||
/* !(a*) is not simplified */
|
||||
result_ = unop::instance(unop::Star, recurse_(f, false));
|
||||
case unop::Finish:
|
||||
case unop::Star:
|
||||
result_ = unop::instance(uo->op(), recurse_(f, false));
|
||||
if (negated_)
|
||||
result_ = unop::instance(unop::Not, result_);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -235,14 +235,6 @@ namespace spot
|
|||
|
||||
switch (uo->op())
|
||||
{
|
||||
case unop::Not:
|
||||
result_ = unop::instance(unop::Not, result_);
|
||||
return;
|
||||
|
||||
case unop::X:
|
||||
result_ = unop::instance(unop::X, result_);
|
||||
return;
|
||||
|
||||
case unop::F:
|
||||
/* If f is a pure eventuality formula then F(f)=f. */
|
||||
if (!(opt_ & Reduce_Eventuality_And_Universality)
|
||||
|
|
@ -257,14 +249,14 @@ namespace spot
|
|||
result_ = unop::instance(unop::G, result_);
|
||||
return;
|
||||
|
||||
case unop::Not:
|
||||
case unop::X:
|
||||
case unop::Finish:
|
||||
result_ = unop::instance(unop::Finish, result_);
|
||||
return;
|
||||
|
||||
case unop::Star:
|
||||
result_ = unop::instance(unop::Star, result_);
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
result_ = unop::instance(uo->op(), result_);
|
||||
return;
|
||||
|
||||
}
|
||||
/* Unreachable code. */
|
||||
assert(0);
|
||||
|
|
|
|||
|
|
@ -106,8 +106,9 @@ namespace spot
|
|||
result_ = true;
|
||||
return;
|
||||
case unop::Finish:
|
||||
return;
|
||||
case unop::Star:
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
return;
|
||||
}
|
||||
/* Unreachable code. */
|
||||
|
|
@ -337,8 +338,9 @@ namespace spot
|
|||
return;
|
||||
}
|
||||
case unop::Finish:
|
||||
return;
|
||||
case unop::Star:
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
return;
|
||||
}
|
||||
/* Unreachable code. */
|
||||
|
|
|
|||
|
|
@ -164,6 +164,7 @@ namespace spot
|
|||
void
|
||||
visit(const unop* uo)
|
||||
{
|
||||
top_level_ = false;
|
||||
// The parser treats F0, F1, G0, G1, X0, and X1 as atomic
|
||||
// propositions. So make sure we output F(0), G(1), etc.
|
||||
bool need_parent = !!dynamic_cast<const constant*>(uo->child());
|
||||
|
|
@ -196,24 +197,43 @@ namespace spot
|
|||
os_ << "finish";
|
||||
need_parent = true;
|
||||
break;
|
||||
case unop::Closure:
|
||||
os_ << "{";
|
||||
top_level_ = true;
|
||||
break;
|
||||
case unop::NegClosure:
|
||||
os_ << "!{";
|
||||
break;
|
||||
case unop::Star:
|
||||
// Do not output anything yet, star is a postfix operator.
|
||||
// 1* is OK, no need to print (1)*.
|
||||
need_parent = false;
|
||||
// Do not output anything yet, star is a postfix operator.
|
||||
break;
|
||||
}
|
||||
|
||||
top_level_ = false;
|
||||
if (need_parent)
|
||||
if (need_parent || full_parent_)
|
||||
os_ << "(";
|
||||
uo->child()->accept(*this);
|
||||
if (need_parent)
|
||||
os_ << ")";
|
||||
|
||||
switch (uo->op())
|
||||
{
|
||||
case unop::Star:
|
||||
os_ << "*";
|
||||
break;
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
os_ << "}";
|
||||
top_level_ = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (full_parent_ && !top_level)
|
||||
os_ << ")";
|
||||
|
||||
if (uo->op() == unop::Star)
|
||||
os_ << "*";
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -377,15 +397,17 @@ namespace spot
|
|||
bool top_level = top_level_;
|
||||
if (full_parent_ && !top_level)
|
||||
os_ << "(";
|
||||
|
||||
bool need_parent = false;
|
||||
top_level_ = false;
|
||||
switch (uo->op())
|
||||
{
|
||||
case unop::Not:
|
||||
os_ << "!";
|
||||
break;
|
||||
case unop::X:
|
||||
// The parser treats X0, and X1 as atomic propositions. So
|
||||
// make sure we output X(0) and X(1).
|
||||
// The parser treats X0, and X1 as atomic
|
||||
// propositions. So make sure we output X(0) and X(1).
|
||||
need_parent = !!dynamic_cast<const constant*>(uo->child());
|
||||
if (full_parent_)
|
||||
need_parent = false;
|
||||
|
|
@ -401,14 +423,19 @@ namespace spot
|
|||
os_ << "finish";
|
||||
need_parent = true;
|
||||
break;
|
||||
case unop::Closure:
|
||||
os_ << "{";
|
||||
top_level_ = true;
|
||||
break;
|
||||
case unop::NegClosure:
|
||||
os_ << "!{";
|
||||
top_level_ = true;
|
||||
break;
|
||||
case unop::Star:
|
||||
// Do not output anything yet, star is a postfix operator.
|
||||
// FIXME: is there a better way to output "Star" for Spin?
|
||||
need_parent = false;
|
||||
break;
|
||||
}
|
||||
|
||||
top_level_ = false;
|
||||
if (need_parent)
|
||||
os_ << "(";
|
||||
uo->child()->accept(*this);
|
||||
|
|
@ -416,6 +443,21 @@ namespace spot
|
|||
os_ << ")";
|
||||
if (uo->op() == unop::Star)
|
||||
os_ << "*";
|
||||
|
||||
switch (uo->op())
|
||||
{
|
||||
case unop::Star:
|
||||
os_ << "*";
|
||||
break;
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
os_ << "}";
|
||||
top_level_ = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (full_parent_ && !top_level)
|
||||
os_ << ")";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
// Copyright (C) 2003, 2009 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
// Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
// et Marie Curie.
|
||||
//
|
||||
|
|
@ -43,6 +45,8 @@ namespace spot
|
|||
case unop::X:
|
||||
case unop::Not:
|
||||
case unop::Star:
|
||||
case unop::Closure:
|
||||
case unop::NegClosure:
|
||||
this->super::visit(uo);
|
||||
return;
|
||||
case unop::F:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue