tl: extend F[n:m] and G[n:m] to the case of m=$
Suggested by Victor Khomenko. * spot/tl/formula.cc, spot/tl/formula.hh, spot/parsetl/parsetl.yy: Implement this. * NEWS, doc/tl/tl.tex: Document it. * tests/core/sugar.test, tests/python/ltlparse.py: Add some tests.
This commit is contained in:
parent
74786324f4
commit
58389bdb80
7 changed files with 57 additions and 16 deletions
|
|
@ -887,6 +887,10 @@ subformula: booleanatom
|
|||
| OP_FREP OP_SQBKT_NUM OP_SQBKT_SEP OP_SQBKT_NUM OP_SQBKT_CLOSE
|
||||
subformula %prec OP_FREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::Or, $2, $4, $6); }
|
||||
| OP_FREP OP_SQBKT_NUM OP_SQBKT_SEP_unbounded OP_SQBKT_CLOSE
|
||||
subformula %prec OP_FREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::Or, $2,
|
||||
fnode::unbounded(), $5); }
|
||||
| OP_FREP OP_SQBKT_NUM OP_SQBKT_SEP OP_SQBKT_NUM OP_SQBKT_CLOSE
|
||||
error
|
||||
{ missing_right_op($$, @1 + @5, "F[.] operator"); }
|
||||
|
|
@ -904,6 +908,10 @@ subformula: booleanatom
|
|||
| OP_GREP OP_SQBKT_NUM OP_SQBKT_SEP OP_SQBKT_NUM OP_SQBKT_CLOSE
|
||||
subformula %prec OP_GREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::And, $2, $4, $6); }
|
||||
| OP_GREP OP_SQBKT_NUM OP_SQBKT_SEP_unbounded OP_SQBKT_CLOSE
|
||||
subformula %prec OP_GREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::And, $2,
|
||||
fnode::unbounded(), $5); }
|
||||
| OP_GREP OP_SQBKT_NUM OP_SQBKT_CLOSE subformula %prec OP_GREP
|
||||
{ $$ = fnode::nested_unop_range(op::X, op::And, $2, $2, $4);
|
||||
error_list.emplace_back(@1 + @3,
|
||||
|
|
|
|||
|
|
@ -1657,11 +1657,14 @@ namespace spot
|
|||
const fnode* res = f;
|
||||
if (max < min)
|
||||
std::swap(min, max);
|
||||
for (unsigned i = min; i < max; ++i)
|
||||
{
|
||||
const fnode* a = f->clone();
|
||||
res = fnode::multop(bo, {a, fnode::unop(uo, res)});
|
||||
}
|
||||
if (max != unbounded())
|
||||
for (unsigned i = min; i < max; ++i)
|
||||
{
|
||||
const fnode* a = f->clone();
|
||||
res = fnode::multop(bo, {a, fnode::unop(uo, res)});
|
||||
}
|
||||
else
|
||||
res = fnode::unop(bo == op::Or ? op::F : op::G, res);
|
||||
for (unsigned i = 0; i < min; ++i)
|
||||
res = fnode::unop(uo, res);
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -906,7 +906,8 @@ namespace spot
|
|||
|
||||
/// \brief Construct F[n:m]
|
||||
///
|
||||
/// F[2:3] = XX(a | Xa)
|
||||
/// F[2:3]a = XX(a | Xa)
|
||||
/// F[2:$]a = XXFa
|
||||
///
|
||||
/// This syntax is from TSLF; the operator is called next_e![n..m] in PSL.
|
||||
static formula F(unsigned min_level, unsigned max_level, const formula& f)
|
||||
|
|
@ -916,7 +917,8 @@ namespace spot
|
|||
|
||||
/// \brief Construct G[n:m]
|
||||
///
|
||||
/// G[2:3] = XX(a & Xa)
|
||||
/// G[2:3]a = XX(a & Xa)
|
||||
/// G[2:$]a = XXGa
|
||||
///
|
||||
/// This syntax is from TSLF; the operator is called next_a![n..m] in PSL.
|
||||
static formula G(unsigned min_level, unsigned max_level, const formula& f)
|
||||
|
|
@ -1217,6 +1219,10 @@ namespace spot
|
|||
///
|
||||
/// For instance nested_unup_range(op::X, op::Or, 2, 4, a) returns
|
||||
/// XX(a | X(a | Xa)).
|
||||
///
|
||||
/// For `max==unbounded()`, \a uo is repeated \a min times, and
|
||||
/// its child is set to `F(a)` if \a bo is `op::Or` or to `G(a)`
|
||||
/// otherwise.
|
||||
static const formula nested_unop_range(op uo, op bo, unsigned min,
|
||||
unsigned max, formula f)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue