Add support for the {SERE}! PSL operator.
* src/ltlparse/ltlscan.ll: Recognize }!. Also remove
five duplicate rules.
* src/ltlparse/ltlparse.yy: Build {r}<>->1 when parsing {r}!.
* src/ltlvisit/tostring.cc: Print {r}! instead of {r}<>->1.
* src/ltltest/tostring.test, src/ltltest/equals.test:
Add more tests.
This commit is contained in:
parent
c48b9bcfb5
commit
fdd73d5123
5 changed files with 27 additions and 7 deletions
|
|
@ -83,6 +83,7 @@ using namespace spot::ltl;
|
||||||
%token START_RATEXP "RATEXP start marker"
|
%token START_RATEXP "RATEXP start marker"
|
||||||
%token PAR_OPEN "opening parenthesis" PAR_CLOSE "closing parenthesis"
|
%token PAR_OPEN "opening parenthesis" PAR_CLOSE "closing parenthesis"
|
||||||
%token BRACE_OPEN "opening brace" BRACE_CLOSE "closing brace"
|
%token BRACE_OPEN "opening brace" BRACE_CLOSE "closing brace"
|
||||||
|
%token BRACE_BANG_CLOSE "closing brace-bang"
|
||||||
%token OP_OR "or operator" OP_XOR "xor operator"
|
%token OP_OR "or operator" OP_XOR "xor operator"
|
||||||
%token OP_AND "and operator" OP_SHORT_AND "short and operator"
|
%token OP_AND "and operator" OP_SHORT_AND "short and operator"
|
||||||
%token OP_IMPLIES "implication operator" OP_EQUIV "equivalent operator"
|
%token OP_IMPLIES "implication operator" OP_EQUIV "equivalent operator"
|
||||||
|
|
@ -627,6 +628,10 @@ subformula: booleanatom
|
||||||
{ missing_right_binop($$, $1, @2,
|
{ missing_right_binop($$, $1, @2,
|
||||||
"existential non-overlapping concat operator");
|
"existential non-overlapping concat operator");
|
||||||
}
|
}
|
||||||
|
| BRACE_OPEN rationalexp BRACE_BANG_CLOSE
|
||||||
|
/* {SERE}! = {SERE} <>-> 1 */
|
||||||
|
{ $$ = binop::instance(binop::EConcat, $2,
|
||||||
|
constant::true_instance()); }
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ flex_set_buffer(const char* buf, int start_tok)
|
||||||
"(" BEGIN(0); return token::PAR_OPEN;
|
"(" BEGIN(0); return token::PAR_OPEN;
|
||||||
")" BEGIN(not_prop); return token::PAR_CLOSE;
|
")" BEGIN(not_prop); return token::PAR_CLOSE;
|
||||||
"{" BEGIN(0); return token::BRACE_OPEN;
|
"{" BEGIN(0); return token::BRACE_OPEN;
|
||||||
|
"}"[ \t\n]*"!" BEGIN(not_prop); return token::BRACE_BANG_CLOSE;
|
||||||
"}" BEGIN(not_prop); return token::BRACE_CLOSE;
|
"}" BEGIN(not_prop); return token::BRACE_CLOSE;
|
||||||
|
|
||||||
/* Must go before the other operators, because the F of FALSE
|
/* Must go before the other operators, because the F of FALSE
|
||||||
|
|
@ -135,11 +136,6 @@ flex_set_buffer(const char* buf, int start_tok)
|
||||||
"^"|"xor" BEGIN(0); return token::OP_XOR;
|
"^"|"xor" BEGIN(0); return token::OP_XOR;
|
||||||
"=>"|"->"|"-->" BEGIN(0); return token::OP_IMPLIES;
|
"=>"|"->"|"-->" BEGIN(0); return token::OP_IMPLIES;
|
||||||
"<=>"|"<->"|"<-->" BEGIN(0); return token::OP_EQUIV;
|
"<=>"|"<->"|"<-->" BEGIN(0); return token::OP_EQUIV;
|
||||||
"*"|"[*]" BEGIN(0); return token::OP_STAR;
|
|
||||||
";" BEGIN(0); return token::OP_CONCAT;
|
|
||||||
":" BEGIN(0); return token::OP_FUSION;
|
|
||||||
"[]->" BEGIN(0); return token::OP_UCONCAT;
|
|
||||||
"<>->" BEGIN(0); return token::OP_ECONCAT;
|
|
||||||
|
|
||||||
/* <>, [], and () are used in Spin. */
|
/* <>, [], and () are used in Spin. */
|
||||||
"F"|"<>" BEGIN(0); return token::OP_F;
|
"F"|"<>" BEGIN(0); return token::OP_F;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ run 0 ../equals 'a & a & true' 'a'
|
||||||
run 0 ../equals 'a & false & a' 'false'
|
run 0 ../equals 'a & false & a' 'false'
|
||||||
run 0 ../equals 'a | false | a' 'a'
|
run 0 ../equals 'a | false | a' 'a'
|
||||||
run 0 ../equals 'true | a | a' 'true'
|
run 0 ../equals 'true | a | a' 'true'
|
||||||
|
run 0 ../equals '{a*}!' '{a*}<>->1'
|
||||||
|
|
||||||
# other formulae which are not
|
# other formulae which are not
|
||||||
run 1 ../equals 'a' 'b'
|
run 1 ../equals 'a' 'b'
|
||||||
|
|
@ -62,6 +63,10 @@ run 1 ../equals 'a & b & c' 'c & a'
|
||||||
run 1 ../equals 'b & c' 'c & a & b'
|
run 1 ../equals 'b & c' 'c & a & b'
|
||||||
run 1 ../equals 'a & b & (c |(f U g)| e)' \
|
run 1 ../equals 'a & b & (c |(f U g)| e)' \
|
||||||
'b & a & a & (c | e |(g U g)| e | c) & b'
|
'b & a & a & (c | e |(g U g)| e | c) & b'
|
||||||
|
run 1 ../equals '{a*}' '{a*}<>->1'
|
||||||
|
run 1 ../equals '!{a*}' '{a*}<>->1'
|
||||||
|
run 1 ../equals '{a*}' '{a*}!'
|
||||||
|
run 1 ../equals '!{a*}' '{a*}!'
|
||||||
|
|
||||||
# Precedence
|
# Precedence
|
||||||
run 0 ../equals 'a & b ^ c | d' 'd | c ^ b & a'
|
run 0 ../equals 'a & b ^ c | d' 'd | c ^ b & a'
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Copyright (C) 2009, 2010 Laboratoire de Recherche et Développement
|
# Copyright (C) 2009, 2010, 2011 Laboratoire de Recherche et Développement
|
||||||
# de l'Epita (LRDE).
|
# de l'Epita (LRDE).
|
||||||
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
# Copyright (C) 2003, 2004 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
|
||||||
|
|
@ -69,3 +69,6 @@ run 0 ../tostring '{a[*1..]}'
|
||||||
run 0 ../tostring '{a[+]}'
|
run 0 ../tostring '{a[+]}'
|
||||||
run 0 ../tostring '{[+]}'
|
run 0 ../tostring '{[+]}'
|
||||||
run 0 ../tostring '{a[*2..3][*4..5]}'
|
run 0 ../tostring '{a[*2..3][*4..5]}'
|
||||||
|
|
||||||
|
run 0 ../tostring '{a**}<>->1' > out
|
||||||
|
test "`sed 1q < out `" = '{a[*]}!'
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,12 @@ namespace spot
|
||||||
top_level_ = top_level;
|
top_level_ = top_level;
|
||||||
break;
|
break;
|
||||||
case binop::EConcat:
|
case binop::EConcat:
|
||||||
|
if (bo->second() == constant::true_instance())
|
||||||
|
{
|
||||||
|
os_ << "}!";
|
||||||
|
in_ratexp_ = false;
|
||||||
|
goto second_done;
|
||||||
|
}
|
||||||
os_ << "} <>-> ";
|
os_ << "} <>-> ";
|
||||||
in_ratexp_ = false;
|
in_ratexp_ = false;
|
||||||
top_level_ = false;
|
top_level_ = false;
|
||||||
|
|
@ -177,6 +183,7 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
bo->second()->accept(*this);
|
bo->second()->accept(*this);
|
||||||
|
second_done:
|
||||||
if (!top_level)
|
if (!top_level)
|
||||||
closep();
|
closep();
|
||||||
}
|
}
|
||||||
|
|
@ -255,7 +262,6 @@ namespace spot
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
top_level_ = false;
|
|
||||||
if (need_parent || full_parent_)
|
if (need_parent || full_parent_)
|
||||||
openp();
|
openp();
|
||||||
uo->child()->accept(*this);
|
uo->child()->accept(*this);
|
||||||
|
|
@ -416,6 +422,11 @@ namespace spot
|
||||||
top_level_ = true;
|
top_level_ = true;
|
||||||
os_ << "{";
|
os_ << "{";
|
||||||
bo->first()->accept(*this);
|
bo->first()->accept(*this);
|
||||||
|
if (bo->second() == constant::true_instance())
|
||||||
|
{
|
||||||
|
os_ << "}!";
|
||||||
|
break;
|
||||||
|
}
|
||||||
os_ << "} <>-> ";
|
os_ << "} <>-> ";
|
||||||
top_level_ = false;
|
top_level_ = false;
|
||||||
bo->second()->accept(*this);
|
bo->second()->accept(*this);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue