Commit c6dd811b authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

Add []-> and <>->.

* src/ltlast/binop.hh, src/ltlast/binop.cc (EConcat, UConcat):
Add these new operators.
* src/ltlparse/ltlparse.yy, src/ltlparse/ltlscan.ll: Parse
these new operators.
* src/ltlvisit/simpfg.cc, src/ltlvisit/syntimpl.cc,
src/ltlvisit/tostring.cc, src/ltlvisit/basicreduce.cc,
src/ltlvisit/consterm.cc, src/ltlvisit/lunabbrev.cc,
src/ltlvisit/nenoform.cc, src/ltlvisit/reduce.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 these new operators into the
switches.
parent 97b7211b
......@@ -121,6 +121,10 @@ namespace spot
return "W";
case M:
return "M";
case EConcat:
return "EConcat";
case UConcat:
return "UConcat";
}
// Unreachable code.
assert(0);
......@@ -136,7 +140,7 @@ namespace spot
// example the formula instance for 'a xor b' is the same as
// that for 'b xor a'.
/// Trivial identities:
// Trivial identities:
switch (op)
{
case Xor:
......@@ -176,10 +180,10 @@ namespace spot
assert(second != constant::true_instance());
break;
case Implies:
/// - (1 => Exp) = Exp
/// - (0 => Exp) = 0
/// - (Exp => 1) = 1
/// - (Exp => 0) = !Exp
// - (1 => Exp) = Exp
// - (0 => Exp) = 0
// - (Exp => 1) = 1
// - (Exp => 0) = !Exp
if (first == constant::true_instance())
return second;
if (first == constant::false_instance())
......@@ -196,9 +200,9 @@ namespace spot
return unop::instance(unop::Not, first);
break;
case U:
/// - (Exp U 1) = 1
/// - (Exp U 0) = 0
/// - (0 U Exp) = Exp
// - (Exp U 1) = 1
// - (Exp U 0) = 0
// - (0 U Exp) = Exp
if (second == constant::true_instance()
|| second == constant::false_instance()
|| first == constant::false_instance())
......@@ -208,9 +212,9 @@ namespace spot
}
break;
case W:
/// - (Exp W 1) = 1
/// - (0 W Exp) = Exp
/// - (1 W Exp) = 1
// - (Exp W 1) = 1
// - (0 W Exp) = Exp
// - (1 W Exp) = 1
if (second == constant::true_instance()
|| first == constant::false_instance())
{
......@@ -224,9 +228,9 @@ namespace spot
}
break;
case R:
/// - (Exp R 1) = 1
/// - (Exp R 0) = 0
/// - (1 R Exp) = Exp
// - (Exp R 1) = 1
// - (Exp R 0) = 0
// - (1 R Exp) = Exp
if (second == constant::true_instance()
|| second == constant::false_instance()
|| first == constant::true_instance())
......@@ -236,9 +240,9 @@ namespace spot
}
break;
case M:
/// - (Exp M 0) = 0
/// - (1 M Exp) = Exp
/// - (0 M Exp) = 0
// - (Exp M 0) = 0
// - (1 M Exp) = Exp
// - (0 M Exp) = 0
if (second == constant::false_instance()
|| first == constant::true_instance())
{
......@@ -251,6 +255,28 @@ namespace spot
return first;
}
break;
case EConcat:
// - 0 <>-> Exp = 0
// - 1 <>-> Exp = Exp
if (first == constant::false_instance())
return second;
if (first == constant::true_instance())
{
second->destroy();
return first;
}
break;
case UConcat:
// - 0 []-> Exp = 1
// - 1 []-> Exp = Exp
if (first == constant::false_instance())
return constant::true_instance();
if (first == constant::true_instance())
{
second->destroy();
return first;
}
break;
}
pairf pf(first, second);
......
......@@ -53,7 +53,9 @@ namespace spot
U, //< until
R, //< release (dual of until)
W, //< weak until
M //< strong release (dual of weak until)
M, //< strong release (dual of weak until)
EConcat, // Existential Concatenation
UConcat // Universal Concatenation
};
/// \brief Build a unary operator with operation \a op and
......
/* Copyright (C) 2009, 2010 Laboratoire de Recherche et Dveloppement
** de l'Epita (LRDE).
/* Copyright (C) 2010 Laboratoire de Recherche et Dveloppement de
** l'Epita (LRDE).
** Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
** Paris 6 (LIP6), dpartement Systmes Rpartis Coopratifs (SRC),
** Universit Pierre et Marie Curie.
......@@ -29,6 +27,7 @@
%name-prefix "ltlyy"
%debug
%error-verbose
%expect 0
%code requires
{
......@@ -76,12 +75,15 @@ using namespace spot::ltl;
/* All tokens. */
%token PAR_OPEN "opening parenthesis" PAR_CLOSE "closing parenthesis"
%token BRACE_OPEN "opening brace" BRACE_CLOSE "closing brace"
%token OP_OR "or operator" OP_XOR "xor operator" OP_AND "and operator"
%token OP_IMPLIES "implication operator" OP_EQUIV "equivalent operator"
%token OP_U "until operator" OP_R "release operator"
%token OP_W "weak until operator" OP_M "strong release operator"
%token OP_F "sometimes operator" OP_G "always operator"
%token OP_X "next operator" OP_NOT "not operator"
%token OP_UCONCAT "universal concat operator"
%token OP_ECONCAT "existential concat operator"
%token <str> ATOMIC_PROP "atomic proposition"
%token OP_STAR "star operator" OP_CONCAT "concat operator"
%token CONST_TRUE "constant true" CONST_FALSE "constant false"
......@@ -91,6 +93,8 @@ using namespace spot::ltl;
/* Priorities. */
/* Low priority regex operator. */
%left OP_UCONCAT OP_ECONCAT
%left OP_CONCAT
/* Logical operators. */
......@@ -112,7 +116,7 @@ using namespace spot::ltl;
%nonassoc OP_POST_NEG OP_POST_POS
%type <ltl> subformula
%type <ltl> subformula booleanatom rationalexp bracedrationalexp
%destructor { delete $$; } <str>
%destructor { $$->destroy(); } <ltl>
......@@ -145,7 +149,7 @@ result: subformula END_OF_INPUT
/* The reason we use `constant::false_instance()' for error recovery
is that it isn't reference counted. (Hence it can't leak references.) */
subformula: ATOMIC_PROP
booleanatom: ATOMIC_PROP
{
$$ = parse_environment.require(*$1);
if (! $$)
......@@ -201,8 +205,63 @@ subformula: ATOMIC_PROP
{ $$ = constant::true_instance(); }
| CONST_FALSE
{ $$ = constant::false_instance(); }
rationalexp: booleanatom
| CONST_EMPTYWORD
{ $$ = constant::empty_word_instance(); }
| PAR_OPEN rationalexp PAR_CLOSE
{ $$ = $2; }
| PAR_OPEN error PAR_CLOSE
{ error_list.push_back(parse_error(@$,
"treating this parenthetical block as false"));
$$ = constant::false_instance();
}
| PAR_OPEN rationalexp END_OF_INPUT
{ error_list.push_back(parse_error(@1 + @2,
"missing closing parenthesis"));
$$ = $2;
}
| PAR_OPEN error END_OF_INPUT
{ error_list.push_back(parse_error(@$,
"missing closing parenthesis, "
"treating this parenthetical block as false"));
$$ = constant::false_instance();
}
| rationalexp OP_AND rationalexp
{ $$ = multop::instance(multop::And, $1, $3); }
| rationalexp OP_AND error
{ missing_right_binop($$, $1, @2, "and operator"); }
| rationalexp OP_OR rationalexp
{ $$ = multop::instance(multop::Or, $1, $3); }
| rationalexp OP_OR error
{ missing_right_binop($$, $1, @2, "or operator"); }
| rationalexp OP_CONCAT rationalexp
{ $$ = multop::instance(multop::Concat, $1, $3); }
| rationalexp OP_CONCAT error
{ missing_right_binop($$, $1, @2, "concat operator"); }
| rationalexp OP_STAR
{ $$ = unop::instance(unop::Star, $1); }
bracedrationalexp: BRACE_OPEN rationalexp BRACE_CLOSE
{ $$ = $2; }
| BRACE_OPEN error BRACE_CLOSE
{ error_list.push_back(parse_error(@$,
"treating this brace block as false"));
$$ = constant::false_instance();
}
| BRACE_OPEN rationalexp END_OF_INPUT
{ error_list.push_back(parse_error(@1 + @2,
"missing closing brace"));
$$ = $2;
}
| BRACE_OPEN error END_OF_INPUT
{ error_list.push_back(parse_error(@$,
"missing closing brace, "
"treating this brace block as false"));
$$ = constant::false_instance();
}
subformula: booleanatom
| PAR_OPEN subformula PAR_CLOSE
{ $$ = $2; }
| PAR_OPEN error PAR_CLOSE
......@@ -229,10 +288,6 @@ subformula: ATOMIC_PROP
{ $$ = multop::instance(multop::Or, $1, $3); }
| subformula OP_OR error
{ missing_right_binop($$, $1, @2, "or operator"); }
| subformula OP_CONCAT subformula
{ $$ = multop::instance(multop::Concat, $1, $3); }
| subformula OP_CONCAT error
{ missing_right_binop($$, $1, @2, "concat operator"); }
| subformula OP_XOR subformula
{ $$ = binop::instance(binop::Xor, $1, $3); }
| subformula OP_XOR error
......@@ -277,8 +332,14 @@ subformula: ATOMIC_PROP
{ $$ = unop::instance(unop::Not, $2); }
| OP_NOT error
{ missing_right_op($$, @1, "not operator"); }
| subformula OP_STAR
{ $$ = unop::instance(unop::Star, $1); }
| bracedrationalexp OP_UCONCAT subformula
{ $$ = binop::instance(binop::UConcat, $1, $3); }
| bracedrationalexp OP_UCONCAT error
{ missing_right_binop($$, $1, @2, "universal concat operator"); }
| bracedrationalexp OP_ECONCAT subformula
{ $$ = binop::instance(binop::EConcat, $1, $3); }
| bracedrationalexp OP_ECONCAT error
{ missing_right_binop($$, $1, @2, "universal concat operator"); }
;
%%
......
......@@ -65,6 +65,8 @@ flex_set_buffer(const char* buf)
"(" BEGIN(0); return token::PAR_OPEN;
")" BEGIN(not_prop); return token::PAR_CLOSE;
"{" BEGIN(0); return token::BRACE_OPEN;
"}" BEGIN(not_prop); return token::BRACE_CLOSE;
/* Must go before the other operators, because the F of FALSE
should not be mistaken with a unary F. */
......@@ -87,6 +89,8 @@ flex_set_buffer(const char* buf)
"<=>"|"<->"|"<-->" BEGIN(0); return token::OP_EQUIV;
"*" BEGIN(0); return token::OP_STAR;
";" BEGIN(0); return token::OP_CONCAT;
"[]->" BEGIN(0); return token::OP_UCONCAT;
"<>->" BEGIN(0); return token::OP_ECONCAT;
/* <>, [], and () are used in Spin. */
"F"|"<>" BEGIN(0); return token::OP_F;
......
......@@ -261,6 +261,8 @@ namespace spot
case binop::Xor:
case binop::Equiv:
case binop::Implies:
case binop::EConcat:
case binop::UConcat:
result_ = binop::instance(bo->op(),
basic_reduce(f1),
basic_reduce(f2));
......
......@@ -62,7 +62,9 @@ namespace spot
case binop::W:
case binop::M:
case binop::R:
result_ = false;
case binop::EConcat:
case binop::UConcat:
assert(!"unsupported operator");
break;
}
}
......@@ -77,7 +79,7 @@ namespace spot
case unop::F:
case unop::G:
case unop::Finish:
result_ = false;
assert(!"unsupported operator");
break;
case unop::Star:
result_ = true;
......@@ -89,7 +91,6 @@ namespace spot
visit(const automatop*)
{
assert(!"automatop not supported for constant term");
result_ = false;
}
void
......
......@@ -81,10 +81,14 @@ namespace spot
/* f1 R f2 == f1 R f2 */
/* f1 W f2 == f1 W f2 */
/* f1 M f2 == f1 M f2 */
/* f1 UConcat f2 == f1 UConcat f2 */
/* f1 EConcat f2 == f1 EConcat f2 */
case binop::U:
case binop::R:
case binop::W:
case binop::M:
case binop::UConcat:
case binop::EConcat:
result_ = binop::instance(op, f1, f2);
return;
}
......
......@@ -174,6 +174,18 @@ namespace spot
result_ = binop::instance(negated_ ? binop::W : binop::M,
recurse(f1), recurse(f2));
return;
case binop::UConcat:
/* !(a []-> b) == a<>-> !b */
result_ = binop::instance(negated_ ?
binop::EConcat : binop::UConcat,
recurse_(f1, false), recurse(f2));
return;
case binop::EConcat:
/* !(a <>-> b) == a[]-> !b */
result_ = binop::instance(negated_ ?
binop::UConcat : binop::EConcat,
recurse_(f1, false), recurse(f2));
return;
}
/* Unreachable code. */
assert(0);
......
......@@ -156,6 +156,9 @@ namespace spot
if (f2 == constant::false_instance())
ret_.is.universal = true;
return;
case binop::UConcat:
case binop::EConcat:
return;
}
/* Unreachable code. */
assert(0);
......@@ -313,6 +316,8 @@ namespace spot
case binop::Xor:
case binop::Equiv:
case binop::Implies:
case binop::UConcat:
case binop::EConcat:
break;
case binop::U:
......
// Copyright (C) 2010 Laboratoire de Recherche et Dveloppement de
// l'Epita (LRDE).
// dpartement Systmes Rpartis Coopratifs (SRC), Universit Pierre
// et Marie Curie.
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// dpartement Systmes Rpartis Coopratifs (SRC), Universit Pierre
// et Marie Curie.
......@@ -53,6 +51,8 @@ namespace spot
case binop::Xor:
case binop::Implies:
case binop::Equiv:
case binop::UConcat:
case binop::EConcat:
result_ = binop::instance(op, f1, f2);
return;
/* true U f2 == F(f2) */
......
......@@ -126,6 +126,8 @@ namespace spot
case binop::Xor:
case binop::Equiv:
case binop::Implies:
case binop::UConcat:
case binop::EConcat:
return;
case binop::U:
case binop::W:
......@@ -359,6 +361,8 @@ namespace spot
case binop::Xor:
case binop::Equiv:
case binop::Implies:
case binop::UConcat:
case binop::EConcat:
return;
case binop::U:
/* (a < c) && (c < d) => a U b < c U d */
......
......@@ -103,11 +103,23 @@ namespace spot
visit(const binop* bo)
{
bool top_level = top_level_;
top_level_ = false;
if (!top_level)
os_ << "(";
bo->first()->accept(*this);
switch (bo->op())
{
case binop::UConcat:
case binop::EConcat:
os_ << "{ ";
top_level_ = true;
bo->first()->accept(*this);
top_level_ = false;
break;
default:
top_level_ = false;
bo->first()->accept(*this);
break;
}
switch (bo->op())
{
......@@ -132,6 +144,12 @@ namespace spot
case binop::M:
os_ << " M ";
break;
case binop::UConcat:
os_ << " }[]-> ";
break;
case binop::EConcat:
os_ << " }<>-> ";
break;
}
bo->second()->accept(*this);
......@@ -311,7 +329,17 @@ namespace spot
break;
case binop::R:
bo->first()->accept(*this);
os_ << " V ";
os_ << " V ";
bo->second()->accept(*this);
break;
case binop::UConcat:
bo->first()->accept(*this);
os_ << " []-> ";
bo->second()->accept(*this);
break;
case binop::EConcat:
bo->first()->accept(*this);
os_ << " <>-> ";
bo->second()->accept(*this);
break;
/* W and M are not supported by Spin */
......
......@@ -112,6 +112,8 @@ namespace spot
case binop::R:
case binop::W:
case binop::M:
case binop::UConcat:
case binop::EConcat:
assert(!"unsupported operator");
}
/* Unreachable code. */
......
......@@ -129,6 +129,8 @@ namespace spot
case binop::R:
case binop::W:
case binop::M:
case binop::UConcat:
case binop::EConcat:
assert(!"unsupported operator");
}
/* Unreachable code. */
......
......@@ -247,6 +247,9 @@ namespace spot
case binop::Implies:
case binop::Equiv:
assert(0); // TBD
case binop::UConcat:
case binop::EConcat:
assert(!"unsupported operator");
}
/* Unreachable code. */
assert(0);
......
......@@ -418,6 +418,10 @@ namespace spot
res_ = (f1 & f2) | (bdd_ithvar(a) & f2 & bdd_ithvar(x));
return;
}
case binop::UConcat:
case binop::EConcat:
assert(!"unsupported operator");
break;
}
/* Unreachable code. */
assert(0);
......@@ -527,6 +531,10 @@ namespace spot
case binop::W:
res_ = true;
return;
case binop::UConcat:
case binop::EConcat:
node->second()->accept(*this);
return;
}
/* Unreachable code. */
assert(0);
......
......@@ -220,6 +220,10 @@ namespace spot
res_ = now;
return;
}
case binop::UConcat:
case binop::EConcat:
assert(!"unsupported operator");
break;
}
/* Unreachable code. */
assert(0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment