tl: add support for ##n and ##[i:j] from SVA
* spot/tl/formula.cc, spot/tl/formula.hh (formula::sugar_delay): New function to implement this operator as syntactic sugar. * spot/parsetl/parsetl.yy, spot/parsetl/scantl.ll: Parse it. * doc/tl/tl.tex: Document the syntactic sugar rules and precedence. * tests/core/sugar.test: Add tests. * NEWS: Mention this new feature.
This commit is contained in:
parent
00f70257db
commit
60d488b30c
7 changed files with 213 additions and 27 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- coding: utf-8 -*-
|
||||
|
||||
** Copyright (C) 2009-2018 Laboratoire de Recherche et Développement
|
||||
** Copyright (C) 2009-2019 Laboratoire de Recherche et Développement
|
||||
** de l'Epita (LRDE).
|
||||
** Copyright (C) 2003-2006 Laboratoire d'Informatique de Paris 6
|
||||
** (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||
|
|
@ -229,6 +229,8 @@ using namespace spot;
|
|||
%token CONST_TRUE "constant true" CONST_FALSE "constant false"
|
||||
%token END_OF_INPUT "end of formula"
|
||||
%token OP_POST_NEG "negative suffix" OP_POST_POS "positive suffix"
|
||||
%token <num> OP_DELAY_N "SVA delay operator"
|
||||
%token OP_DELAY_OPEN "opening bracket for SVA delay operator"
|
||||
|
||||
/* Priorities. */
|
||||
|
||||
|
|
@ -237,6 +239,7 @@ using namespace spot;
|
|||
|
||||
%left OP_CONCAT
|
||||
%left OP_FUSION
|
||||
%left OP_DELAY_N OP_DELAY_OPEN
|
||||
|
||||
/* Logical operators. */
|
||||
%right OP_IMPLIES OP_EQUIV
|
||||
|
|
@ -244,7 +247,8 @@ using namespace spot;
|
|||
%left OP_XOR
|
||||
%left OP_AND OP_SHORT_AND
|
||||
|
||||
/* OP_STAR can be used as an AND when occurring in some LTL formula in
|
||||
|
||||
/* OP_STAR can be used as an AND when occurring in some LTL formula in
|
||||
Wring's syntax (so it has to be close to OP_AND), and as a Kleen
|
||||
Star in SERE (so it has to be close to OP_BSTAR -- luckily
|
||||
U/R/M/W/F/G/X are not used in SERE). */
|
||||
|
|
@ -267,7 +271,7 @@ using namespace spot;
|
|||
|
||||
%type <ltl> subformula atomprop booleanatom sere lbtformula boolformula
|
||||
%type <ltl> bracedsere parenthesedsubformula
|
||||
%type <minmax> starargs fstarargs equalargs sqbracketargs gotoargs
|
||||
%type <minmax> starargs fstarargs equalargs sqbracketargs gotoargs delayargs
|
||||
|
||||
%destructor { delete $$; } <str>
|
||||
%destructor { $$->destroy(); } <ltl>
|
||||
|
|
@ -437,6 +441,16 @@ equalargs: OP_EQUAL_OPEN sqbracketargs
|
|||
emplace_back(@$, "missing closing bracket for equal operator");
|
||||
$$.min = $$.max = 0U; }
|
||||
|
||||
delayargs: OP_DELAY_OPEN sqbracketargs
|
||||
{ $$ = $2; }
|
||||
| OP_DELAY_OPEN error OP_SQBKT_CLOSE
|
||||
{ error_list.emplace_back(@$, "treating this delay block as ##1");
|
||||
$$.min = $$.max = 1U; }
|
||||
| OP_DELAY_OPEN error_opt END_OF_INPUT
|
||||
{ error_list.
|
||||
emplace_back(@$, "missing closing bracket for ##[");
|
||||
$$.min = $$.max = 1U; }
|
||||
|
||||
|
||||
atomprop: ATOMIC_PROP
|
||||
{
|
||||
|
|
@ -520,6 +534,40 @@ sere: booleanatom
|
|||
{ $$ = fnode::multop(op::Fusion, {$1, $3}); }
|
||||
| sere OP_FUSION error
|
||||
{ missing_right_binop($$, $1, @2, "fusion operator"); }
|
||||
| OP_DELAY_N sere
|
||||
{ $$ = formula::sugar_delay(formula::tt(), formula($2),
|
||||
$1, $1).to_node_(); }
|
||||
| OP_DELAY_N error
|
||||
{ missing_right_binop($$, fnode::tt(), @1, "SVA delay operator"); }
|
||||
| sere OP_DELAY_N sere
|
||||
{ $$ = formula::sugar_delay(formula($1), formula($3),
|
||||
$2, $2).to_node_(); }
|
||||
| sere OP_DELAY_N error
|
||||
{ missing_right_binop($$, $1, @2, "SVA delay operator"); }
|
||||
| delayargs sere %prec OP_DELAY_OPEN
|
||||
{
|
||||
if ($1.max < $1.min)
|
||||
{
|
||||
error_list.emplace_back(@1, "reversed range");
|
||||
std::swap($1.max, $1.min);
|
||||
}
|
||||
$$ = formula::sugar_delay(formula::tt(), formula($2),
|
||||
$1.min, $1.max).to_node_();
|
||||
}
|
||||
| delayargs error
|
||||
{ missing_right_binop($$, fnode::tt(), @1, "SVA delay operator"); }
|
||||
| sere delayargs sere %prec OP_DELAY_OPEN
|
||||
{
|
||||
if ($2.max < $2.min)
|
||||
{
|
||||
error_list.emplace_back(@1, "reversed range");
|
||||
std::swap($2.max, $2.min);
|
||||
}
|
||||
$$ = formula::sugar_delay(formula($1), formula($3),
|
||||
$2.min, $2.max).to_node_();
|
||||
}
|
||||
| sere delayargs error
|
||||
{ missing_right_binop($$, $1, @2, "SVA delay operator"); }
|
||||
| starargs
|
||||
{
|
||||
if ($1.max < $1.min)
|
||||
|
|
|
|||
|
|
@ -217,6 +217,22 @@ eol2 (\n\r)+|(\r\n)+
|
|||
/* ~ comes from Goal, ! from everybody else */
|
||||
{NOT} BEGIN(0); return token::OP_NOT;
|
||||
|
||||
/* SVA operators */
|
||||
"##"[0-9]+ {
|
||||
errno = 0;
|
||||
unsigned long n = strtoul(yytext + 2, 0, 10);
|
||||
yylval->num = n;
|
||||
if (errno || yylval->num != n)
|
||||
{
|
||||
error_list.push_back(
|
||||
spot::one_parse_error(*yylloc,
|
||||
"value too large ignored"));
|
||||
yylval->num = 1;
|
||||
}
|
||||
return token::OP_DELAY_N;
|
||||
}
|
||||
"##[" BEGIN(sqbracket); return token::OP_DELAY_OPEN;
|
||||
|
||||
/* PSL operators */
|
||||
{BOXARROW} BEGIN(0); return token::OP_UCONCAT;
|
||||
{DIAMOND}{ARROWL} BEGIN(0); return token::OP_ECONCAT;
|
||||
|
|
|
|||
|
|
@ -1743,6 +1743,21 @@ namespace spot
|
|||
return Concat({Star(Concat({s, b}), min, max), s});
|
||||
}
|
||||
|
||||
formula formula::sugar_delay(const formula& a, const formula& b,
|
||||
unsigned min, unsigned max)
|
||||
{
|
||||
// In general
|
||||
// a ##[min:max] b = a:(1[*min:max];b)
|
||||
// however if min>=1 we prefer the following rule
|
||||
// a ##[min:max] b = a;1[*min-1:max-1];b
|
||||
if (min == 0)
|
||||
return Fusion({a, Concat({Star(tt(), min, max), b})});
|
||||
--min;
|
||||
if (max != unbounded())
|
||||
--max;
|
||||
return Concat({a, Star(tt(), min, max), b});
|
||||
}
|
||||
|
||||
int atomic_prop_cmp(const fnode* f, const fnode* g)
|
||||
{
|
||||
return strverscmp(f->ap_name().c_str(), g->ap_name().c_str());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015-2018 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2015-2019 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -1220,18 +1220,29 @@ namespace spot
|
|||
|
||||
/// \brief Create a SERE equivalent to b[->min..max]
|
||||
///
|
||||
/// The operator does not exist: it is handled as sugar by the parser
|
||||
/// and the printer. This functions is used by the parser to create
|
||||
/// the equivalent SERE.
|
||||
/// The operator does not exist: it is handled as syntactic sugar
|
||||
/// by the parser and the printer. This function is used by the
|
||||
/// parser to create the equivalent SERE.
|
||||
static formula sugar_goto(const formula& b, uint8_t min, uint8_t max);
|
||||
|
||||
/// Create the SERE b[=min..max]
|
||||
///
|
||||
/// The operator does not exist: it is handled as sugar by the parser
|
||||
/// and the printer. This functions is used by the parser to create
|
||||
/// the equivalent SERE.
|
||||
/// The operator does not exist: it is handled as syntactic sugar
|
||||
/// by the parser and the printer. This function is used by the
|
||||
/// parser to create the equivalent SERE.
|
||||
static formula sugar_equal(const formula& b, uint8_t min, uint8_t max);
|
||||
|
||||
/// Create the SERE a ##[n:m] b
|
||||
///
|
||||
/// This ##[n:m] operator comes from SVA. When n=m, it is simply
|
||||
/// written ##n.
|
||||
///
|
||||
/// The operator does not exist in Spot it is handled as syntactic
|
||||
/// sugar by the parser. This function is used by the parser to
|
||||
/// create the equivalent SERE.
|
||||
static formula sugar_delay(const formula& a, const formula& b,
|
||||
unsigned min, unsigned max);
|
||||
|
||||
#ifndef SWIG
|
||||
/// \brief Return the underlying pointer to the formula.
|
||||
///
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue