psl: add support for the [:*i..j] operator
This operator is to ':' what [*i..j] is to ';'. Part of issue #51. * doc/tl/tl.tex: Document syntax, semantic, and trivial simplifications. * doc/tl/spotltl.sty: Add macros for new operators. * src/ltlast/bunop.cc, src/ltlast/bunop.hh: Implement it. * src/ltlast/multop.cc: Add some trivial simplifications. * src/ltlparse/ltlparse.yy, src/ltlparse/ltlscan.ll: Parse it. * src/ltltest/equals.test, src/ltltest/latex.test, src/tgbatest/ltl2tgba.test: Add more tests. * src/ltlvisit/randomltl.cc: Output this operator in random PSL formulas. * src/ltltest/rand.test: Adjust. * src/tgbaalgos/ltl2tgba_fm.cc: Add translation rules. * src/ltlvisit/tostring.cc: Add pretty printing code. * src/ltlvisit/simplify.cc, src/ltlvisit/snf.cc: Adjust switches. * NEWS: Mention the new operator.
This commit is contained in:
parent
eebbcac281
commit
a79db4eefe
17 changed files with 442 additions and 162 deletions
9
NEWS
9
NEWS
|
|
@ -67,7 +67,14 @@ New in spot 1.99a (not yet released)
|
||||||
either by Divine (as patched by the LTSmin people) or by
|
either by Divine (as patched by the LTSmin people) or by
|
||||||
Spins (the LTSmin compiler for Promela).
|
Spins (the LTSmin compiler for Promela).
|
||||||
|
|
||||||
- LTL formulas can include /* comments */.
|
- LTL/PSL formulas can include /* comments */.
|
||||||
|
|
||||||
|
- PSL SEREs support a new operator [:*i..j], the iterated fusion.
|
||||||
|
[:*i..j] is to the fusion operator ':' what [*i..j] is to the
|
||||||
|
concatenation operator ';'. For instance (a*;b)[:*3] is the
|
||||||
|
same as (a*;b):(a*;b):(a*;b). The operator [:+], is syntactic
|
||||||
|
sugar for [:*1..], and corresponds to the operator ⊕ introduced
|
||||||
|
by Dax et al. (ATVA'09).
|
||||||
|
|
||||||
- GraphViz output now uses an horizontal layout by default.
|
- GraphViz output now uses an horizontal layout by default.
|
||||||
The --dot option of the various command-line tools takes an
|
The --dot option of the various command-line tools takes an
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@
|
||||||
\newcommand{\ffalse}{\bot}
|
\newcommand{\ffalse}{\bot}
|
||||||
\newcommand{\eword}{\varepsilon} % empty word, denoted by [*0] in PSL
|
\newcommand{\eword}{\varepsilon} % empty word, denoted by [*0] in PSL
|
||||||
|
|
||||||
% These three are not declared as operator
|
% These three are not declared as operators
|
||||||
\newcommand{\F}{\mathsf{F}} % eventually
|
\newcommand{\F}{\mathsf{F}} % eventually
|
||||||
\newcommand{\G}{\mathsf{G}} % always
|
\newcommand{\G}{\mathsf{G}} % always
|
||||||
\newcommand{\X}{\mathsf{X}} % next
|
\newcommand{\X}{\mathsf{X}} % next
|
||||||
% The \mathbin tell TeX to adjust spacing for binary operators
|
% The \mathbin tells TeX to adjust spacing for binary operators
|
||||||
\newcommand{\M}{\mathbin{\mathsf{M}}} % strong release
|
\newcommand{\M}{\mathbin{\mathsf{M}}} % strong release
|
||||||
\newcommand{\R}{\mathbin{\mathsf{R}}} % release
|
\newcommand{\R}{\mathbin{\mathsf{R}}} % release
|
||||||
\newcommand{\U}{\mathbin{\mathsf{U}}} % until
|
\newcommand{\U}{\mathbin{\mathsf{U}}} % until
|
||||||
|
|
@ -25,9 +25,11 @@
|
||||||
|
|
||||||
% Star-like PSL operators
|
% Star-like PSL operators
|
||||||
\newcommand{\SereStar}[1]{^{\star#1}}
|
\newcommand{\SereStar}[1]{^{\star#1}}
|
||||||
|
\newcommand{\SereFStar}[1]{^{\mathsf{:}\star#1}}
|
||||||
\newcommand{\SereEqual}[1]{^{=#1}}
|
\newcommand{\SereEqual}[1]{^{=#1}}
|
||||||
\newcommand{\SereGoto}[1]{^{\to#1}}
|
\newcommand{\SereGoto}[1]{^{\to#1}}
|
||||||
\newcommand{\SerePlus}{^+}
|
\newcommand{\SerePlus}{^+}
|
||||||
|
\newcommand{\SereFPlus}{^{\mathsf{:}+}}
|
||||||
\newcommand{\SereFusion}{\mathbin{\mathsf{:}}}
|
\newcommand{\SereFusion}{\mathbin{\mathsf{:}}}
|
||||||
\newcommand{\SereConcat}{\mathbin{\mathsf{;}}}
|
\newcommand{\SereConcat}{\mathbin{\mathsf{;}}}
|
||||||
\newcommand{\SereOr}{\cup}
|
\newcommand{\SereOr}{\cup}
|
||||||
|
|
@ -45,5 +47,3 @@
|
||||||
%\newcommand{\seqXM}{\seqX}
|
%\newcommand{\seqXM}{\seqX}
|
||||||
\newcommand{\triggers}{\boxright}
|
\newcommand{\triggers}{\boxright}
|
||||||
\newcommand{\triggersX}{\boxRight}
|
\newcommand{\triggersX}{\boxRight}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@
|
||||||
\newcommand{\EQUAL}[1]{\texttt{[=#1]}}
|
\newcommand{\EQUAL}[1]{\texttt{[=#1]}}
|
||||||
\newcommand{\GOTO}[1]{\texttt{[->#1]}}
|
\newcommand{\GOTO}[1]{\texttt{[->#1]}}
|
||||||
\newcommand{\PLUS}{\texttt{[+]}}
|
\newcommand{\PLUS}{\texttt{[+]}}
|
||||||
|
\newcommand{\FPLUS}{\texttt{[:+]}}
|
||||||
\newcommand{\eword}{\texttt{[*0]}}
|
\newcommand{\eword}{\texttt{[*0]}}
|
||||||
|
|
||||||
\newcommand{\Esuffix}{\texttt{<>->}}
|
\newcommand{\Esuffix}{\texttt{<>->}}
|
||||||
|
|
@ -599,14 +600,22 @@ denote arbitrary SERE.
|
||||||
NLM intersection\footnotemark & $f\AND g$ \\
|
NLM intersection\footnotemark & $f\AND g$ \\
|
||||||
concatenation & $f\CONCAT g$ \\
|
concatenation & $f\CONCAT g$ \\
|
||||||
fusion & $f\FUSION g$ \\
|
fusion & $f\FUSION g$ \\
|
||||||
bounded repetition & $f\STAR{\mvar{i}..\mvar{j}}$
|
bounded ;-iter. & $f\STAR{\mvar{i}..\mvar{j}}$
|
||||||
& $f\STAR{\mvar{i}:\mvar{j}}$
|
& $f\STAR{\mvar{i}:\mvar{j}}$
|
||||||
& $f\STAR{\mvar{i} to \mvar{j}}$
|
& $f\STAR{\mvar{i} to \mvar{j}}$
|
||||||
& $f\STAR{\mvar{i},\mvar{j}}$\\
|
& $f\STAR{\mvar{i},\mvar{j}}$\\
|
||||||
\llap{un}bounded repetition & $f\STAR{\mvar{i}..}$
|
\llap{un}bounded ;-iter. & $f\STAR{\mvar{i}..}$
|
||||||
& $f\STAR{\mvar{i}:}$
|
& $f\STAR{\mvar{i}:}$
|
||||||
& $f\STAR{\mvar{i} to}$
|
& $f\STAR{\mvar{i} to}$
|
||||||
& $f\STAR{\mvar{i},}$\\
|
& $f\STAR{\mvar{i},}$\\
|
||||||
|
bounded :-iter. & $f\FSTAR{\mvar{i}..\mvar{j}}$
|
||||||
|
& $f\FSTAR{\mvar{i}:\mvar{j}}$
|
||||||
|
& $f\FSTAR{\mvar{i} to \mvar{j}}$
|
||||||
|
& $f\FSTAR{\mvar{i},\mvar{j}}$\\
|
||||||
|
\llap{un}bounded :-iter. & $f\FSTAR{\mvar{i}..}$
|
||||||
|
& $f\FSTAR{\mvar{i}:}$
|
||||||
|
& $f\FSTAR{\mvar{i} to}$
|
||||||
|
& $f\FSTAR{\mvar{i},}$\\
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
|
|
@ -657,6 +666,26 @@ $a$ is an atomic proposition.
|
||||||
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
||||||
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
(\sigma^{0..k-1}\VDash f) \land (\sigma^{k..}
|
||||||
\VDash f\STAR{\mvar{i-1}..}))\\
|
\VDash f\STAR{\mvar{i-1}..}))\\
|
||||||
|
\end{cases}\\
|
||||||
|
\sigma\VDash f\FSTAR{\mvar{i}..\mvar{j}}& \iff
|
||||||
|
\begin{cases}
|
||||||
|
\text{either} & \mvar{i}=0 \land \mvar{j}=0 \land \sigma\VDash\1 \\
|
||||||
|
\text{or} & \mvar{i}=0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||||
|
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||||
|
\VDash f\FSTAR{\mvar{0}..\mvar{j-1}}))\\
|
||||||
|
\text{or} & \mvar{i}>0 \land \mvar{j}>0 \land (\exists k\in\N,\,
|
||||||
|
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||||
|
\VDash f\FSTAR{\mvar{i-1}..\mvar{j-1}}))\\
|
||||||
|
\end{cases}\\
|
||||||
|
\sigma\VDash f\FSTAR{\mvar{i}..} & \iff
|
||||||
|
\begin{cases}
|
||||||
|
\text{either} & \mvar{i}=0 \land \sigma\VDash\1 \\
|
||||||
|
\text{or} & \mvar{i}=0 \land (\exists k\in\N,\,
|
||||||
|
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||||
|
\VDash f\FSTAR{\mvar{0}..}))\\
|
||||||
|
\text{or} & \mvar{i}>0 \land (\exists k\in\N,\,
|
||||||
|
(\sigma^{0..k}\VDash f) \land (\sigma^{k..}
|
||||||
|
\VDash f\FSTAR{\mvar{i-1}..}))\\
|
||||||
\end{cases}
|
\end{cases}
|
||||||
\end{align*}}
|
\end{align*}}
|
||||||
|
|
||||||
|
|
@ -668,6 +697,29 @@ operands are Boolean formulas.
|
||||||
regardless of the value of $f$ and $g$. For instance
|
regardless of the value of $f$ and $g$. For instance
|
||||||
$a\STAR{}\FUSION b\STAR{}$ is actually equivalent to
|
$a\STAR{}\FUSION b\STAR{}$ is actually equivalent to
|
||||||
$a\STAR{}\CONCAT\sere{a\ANDALT b}\CONCAT b\STAR{}$.
|
$a\STAR{}\CONCAT\sere{a\ANDALT b}\CONCAT b\STAR{}$.
|
||||||
|
\item The $\FSTAR{\mvar{i}..}$ and $\FSTAR{\mvar{i}..\mvar{j}}$ operators are
|
||||||
|
iterations of the $\FUSION$ operator just like
|
||||||
|
The $\STAR{\mvar{i}..}$ and $\STAR{\mvar{i}..\mvar{j}}$ are
|
||||||
|
iterations of the $\CONCAT$ operator. More graphically:
|
||||||
|
\begin{align*}
|
||||||
|
f\STAR{\mvar{i}..\mvar{j}} &=
|
||||||
|
\underbrace{f\CONCAT f\CONCAT \ldots \CONCAT f}_{\text{between $\mvar{i}$ and $\mvar{j}$ copies of $f$}} &
|
||||||
|
f\FSTAR{\mvar{i}..\mvar{j}} &=
|
||||||
|
\underbrace{f\FUSION f\FUSION \ldots \FUSION f}_{\text{between $\mvar{i}$ and $\mvar{j}$ copies of $f$}}\\
|
||||||
|
\intertext{with the convention that}
|
||||||
|
f\STAR{0..0} &= \eword &
|
||||||
|
f\FSTAR{0..0} &= \1
|
||||||
|
\end{align*}
|
||||||
|
\item The $\FSTAR{\mvar{i}..}$ and $\FSTAR{\mvar{i}..\mvar{j}}$
|
||||||
|
operators are not defined in PSL. While the bounded iteration can
|
||||||
|
be seen as syntactic sugar on $\FUSION$, the unbounded version
|
||||||
|
really is a new operator.
|
||||||
|
|
||||||
|
$\FSTAR{1..}$, for which we define the $\FPLUS$ syntactic sugar
|
||||||
|
below, actually corresponds to the $^\oplus$ operator introduced
|
||||||
|
by~\citet{dax.09.atva}. With this simple addition, it is possible
|
||||||
|
to define a subset of PSL that expresses exactly the
|
||||||
|
stutter-invariant $\omega$-regular languages.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
\subsection{Syntactic Sugar}
|
\subsection{Syntactic Sugar}
|
||||||
|
|
@ -687,24 +739,28 @@ it for output. $b$ must be a Boolean formula.
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
f\STARALT &\equiv f\STAR{0..}\\
|
f\STARALT &\equiv f\STAR{0..}\\
|
||||||
f\STAR{} &\equiv f\STAR{0..} &
|
f\STAR{} &\equiv f\STAR{0..} &
|
||||||
f\PLUS{} &\equiv f\STAR{1..} &
|
f\FSTAR{} &\equiv f\FSTAR{0..} &
|
||||||
f\EQUAL{} &\equiv f\EQUAL{0..} &
|
f\EQUAL{} &\equiv f\EQUAL{0..} &
|
||||||
f\GOTO{} &\equiv f\GOTO{1..1} \\
|
f\GOTO{} &\equiv f\GOTO{1..1} \\
|
||||||
f\STAR{..} &\equiv f\STAR{0..} &
|
f\STAR{..} &\equiv f\STAR{0..} &
|
||||||
&&
|
f\FSTAR{..} &\equiv f\FSTAR{0..} &
|
||||||
f\EQUAL{..} &\equiv f\EQUAL{0..} &
|
f\EQUAL{..} &\equiv f\EQUAL{0..} &
|
||||||
f\GOTO{..} &\equiv f\GOTO{1..} \\
|
f\GOTO{..} &\equiv f\GOTO{1..} \\
|
||||||
f\STAR{..\mvar{j}} &\equiv f\STAR{0..\mvar{j}} &
|
f\STAR{..\mvar{j}} &\equiv f\STAR{0..\mvar{j}} &
|
||||||
&&
|
f\FSTAR{..\mvar{j}} &\equiv f\FSTAR{0..\mvar{j}} &
|
||||||
f\EQUAL{..\mvar{j}} &\equiv f\EQUAL{0..\mvar{j}} &
|
f\EQUAL{..\mvar{j}} &\equiv f\EQUAL{0..\mvar{j}} &
|
||||||
f\GOTO{..\mvar{j}} &\equiv f\GOTO{1..\mvar{j}} \\
|
f\GOTO{..\mvar{j}} &\equiv f\GOTO{1..\mvar{j}} \\
|
||||||
f\STAR{\mvar{k}} &\equiv f\STAR{\mvar{k}..\mvar{k}} &
|
f\STAR{\mvar{k}} &\equiv f\STAR{\mvar{k}..\mvar{k}} &
|
||||||
&&
|
f\FSTAR{\mvar{k}} &\equiv f\FSTAR{\mvar{k}..\mvar{k}} &
|
||||||
f\EQUAL{\mvar{k}} &\equiv f\EQUAL{\mvar{k}..\mvar{k}} &
|
f\EQUAL{\mvar{k}} &\equiv f\EQUAL{\mvar{k}..\mvar{k}} &
|
||||||
f\GOTO{\mvar{k}} &\equiv f\GOTO{\mvar{k}..\mvar{k}} \\
|
f\GOTO{\mvar{k}} &\equiv f\GOTO{\mvar{k}..\mvar{k}} \\
|
||||||
\STAR{} &\equiv \1\STAR{0..} &
|
f\PLUS{} &\equiv f\STAR{1..} &
|
||||||
\PLUS{} &\equiv \1\STAR{1..} \\
|
f\FPLUS{} &\equiv f\FSTAR{1..}
|
||||||
\STAR{\mvar{k}} &\equiv \1\STAR{\mvar{k}..\mvar{k}} &
|
\end{align*}
|
||||||
|
\begin{align*}
|
||||||
|
\STAR{\mvar{k}} &\equiv \1\STAR{\mvar{k}..\mvar{k}} &
|
||||||
|
\STAR{} &\equiv \1\STAR{0..} &
|
||||||
|
\PLUS{} &\equiv \1\STAR{1..}
|
||||||
\end{align*}
|
\end{align*}
|
||||||
|
|
||||||
\subsection{Trivial Identities (Occur Automatically)}
|
\subsection{Trivial Identities (Occur Automatically)}
|
||||||
|
|
@ -720,6 +776,14 @@ $b_1$, $b_2$ are assumed to be Boolean formulas.
|
||||||
f\STAR{\mvar{i}..\mvar{j}}\STAR{\mvar{k}..\mvar{l}} &\equiv f\STAR{\mvar{ik}..\mvar{jl}}\text{~if~}i(k+1)\le jk+1 \\
|
f\STAR{\mvar{i}..\mvar{j}}\STAR{\mvar{k}..\mvar{l}} &\equiv f\STAR{\mvar{ik}..\mvar{jl}}\text{~if~}i(k+1)\le jk+1 \\
|
||||||
f\STAR{0}&\equiv \eword &
|
f\STAR{0}&\equiv \eword &
|
||||||
f\STAR{1}&\equiv f\\
|
f\STAR{1}&\equiv f\\
|
||||||
|
b\FSTAR{0..\mvar{j}} &\equiv \1 &
|
||||||
|
b\FSTAR{\mvar{i}..\mvar{j}} &\equiv b \text{~if~}i>0 \\
|
||||||
|
\eword\FSTAR{0..\mvar{j}} &\equiv \1&
|
||||||
|
\eword\FSTAR{\mvar{i}..\mvar{j}} &\equiv \0\text{~if~}i>0 \\
|
||||||
|
&&
|
||||||
|
f\FSTAR{\mvar{i}..\mvar{j}}\FSTAR{\mvar{k}..\mvar{l}} &\equiv f\FSTAR{\mvar{ik}..\mvar{jl}}\text{~if~}i(k+1)\le jk+1 \\
|
||||||
|
f\FSTAR{0}&\equiv \1 &
|
||||||
|
f\FSTAR{1}&\equiv f\text{~if~}\varepsilon\nVDash f\\
|
||||||
\end{align*}
|
\end{align*}
|
||||||
|
|
||||||
\noindent
|
\noindent
|
||||||
|
|
@ -758,20 +822,19 @@ The following rules are all valid with the two arguments swapped.
|
||||||
f\AND f &\equiv f&
|
f\AND f &\equiv f&
|
||||||
f\ANDALT f &\equiv f &
|
f\ANDALT f &\equiv f &
|
||||||
f\OR f &\equiv f&
|
f\OR f &\equiv f&
|
||||||
&&
|
f\FUSION f&\equiv f\FSTAR{2}&
|
||||||
f\CONCAT f&\equiv f\STAR{2}\\
|
f\CONCAT f&\equiv f\STAR{2}\\
|
||||||
b_1 \AND b_2 &\equiv b_1\ANDALT b_2 &
|
b_1 \AND b_2 &\equiv b_1\ANDALT b_2 &
|
||||||
&&
|
&&
|
||||||
&&
|
&&
|
||||||
b_1:b_2 &\equiv b_1\ANDALT b_2 &
|
b_1:b_2 &\equiv b_1\ANDALT b_2
|
||||||
f\STAR{\mvar{i}..\mvar{j}}\CONCAT f&\equiv f\STAR{\mvar{i+1}..\mvar{j+1}}\\
|
\end{align*}
|
||||||
&&
|
\begin{align*}
|
||||||
&&
|
f\STAR{\mvar{i}..\mvar{j}}\CONCAT f&\equiv f\STAR{\mvar{i+1}..\mvar{j+1}} &
|
||||||
&&
|
f\STAR{\mvar{i}..\mvar{j}}\CONCAT f\STAR{\mvar{k}..\mvar{l}}&\equiv f\STAR{\mvar{i+k}..\mvar{j+l}}\\
|
||||||
&&
|
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f&\equiv f\FSTAR{\mvar{i+1}..\mvar{j+1}} &
|
||||||
\mathllap{f\STAR{\mvar{i}..\mvar{j}}}\CONCAT f\STAR{\mvar{k}..\mvar{l}}&\equiv f\STAR{\mvar{i+k}..\mvar{j+l}}\\
|
f\FSTAR{\mvar{i}..\mvar{j}}\FUSION f\FSTAR{\mvar{k}..\mvar{l}}&\equiv f\FSTAR{\mvar{i+k}..\mvar{j+l}}
|
||||||
\end{align*}
|
\end{align*}
|
||||||
|
|
||||||
\section{SERE-LTL Binding Operators}
|
\section{SERE-LTL Binding Operators}
|
||||||
|
|
||||||
The following operators combine a SERE $r$ with a PSL
|
The following operators combine a SERE $r$ with a PSL
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
|
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire de
|
||||||
// Recherche et Développement de l'Epita (LRDE).
|
// Recherche et Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -61,6 +61,11 @@ namespace spot
|
||||||
if (min_ == 0)
|
if (min_ == 0)
|
||||||
is.accepting_eword = true;
|
is.accepting_eword = true;
|
||||||
break;
|
break;
|
||||||
|
case FStar:
|
||||||
|
is.accepting_eword = false;
|
||||||
|
if (max_ == unbounded)
|
||||||
|
is.finite = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,6 +111,8 @@ namespace spot
|
||||||
{
|
{
|
||||||
case Star:
|
case Star:
|
||||||
return "Star";
|
return "Star";
|
||||||
|
case FStar:
|
||||||
|
return "FStar";
|
||||||
}
|
}
|
||||||
SPOT_UNREACHABLE();
|
SPOT_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
@ -120,20 +127,22 @@ namespace spot
|
||||||
case Star:
|
case Star:
|
||||||
// Syntactic sugaring
|
// Syntactic sugaring
|
||||||
if (min_ == 1 && max_ == unbounded)
|
if (min_ == 1 && max_ == unbounded)
|
||||||
{
|
return "[+]";
|
||||||
out << "[+]";
|
|
||||||
return out.str();
|
|
||||||
}
|
|
||||||
out << "[*";
|
out << "[*";
|
||||||
break;
|
break;
|
||||||
|
case FStar:
|
||||||
|
// Syntactic sugaring
|
||||||
|
if (min_ == 1 && max_ == unbounded)
|
||||||
|
return "[:+]";
|
||||||
|
out << "[:*";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_ != 0 || max_ != unbounded)
|
if (min_ != 0 || max_ != unbounded)
|
||||||
{
|
{
|
||||||
// Always print the min_, even when it is equal to
|
// Always print the min_, even when it is equal to 0, this
|
||||||
// default_min, this way we avoid ambiguities (like
|
// way we avoid ambiguities (like when reading
|
||||||
// when reading a[*..3];b[->..2] which actually
|
// a[*..3];b[->..2] which actually means a[*0..3];b[->1..2].
|
||||||
// means a[*0..3];b[->1..2].
|
|
||||||
out << min_;
|
out << min_;
|
||||||
if (min_ != max_)
|
if (min_ != max_)
|
||||||
{
|
{
|
||||||
|
|
@ -154,86 +163,110 @@ namespace spot
|
||||||
{
|
{
|
||||||
assert(min <= max);
|
assert(min <= max);
|
||||||
|
|
||||||
// Some trivial simplifications.
|
const formula* neutral = nullptr;
|
||||||
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case Star:
|
case Star:
|
||||||
|
neutral = constant::empty_word_instance();
|
||||||
|
break;
|
||||||
|
case FStar:
|
||||||
|
neutral = constant::true_instance();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// common trivial simplifications
|
||||||
|
|
||||||
|
// - [*0][*min..max] = [*0]
|
||||||
|
// - [*0][:*0..max] = 1
|
||||||
|
// - [*0][:*min..max] = 0 if min > 0
|
||||||
|
if (child == constant::empty_word_instance())
|
||||||
|
switch (op)
|
||||||
{
|
{
|
||||||
// - [*0][*min..max] = [*0]
|
case Star:
|
||||||
if (child == constant::empty_word_instance())
|
return neutral;
|
||||||
return child;
|
case FStar:
|
||||||
|
if (min == 0)
|
||||||
// - 0[*0..max] = [*0]
|
return neutral;
|
||||||
// - 0[*min..max] = 0 if min > 0
|
else
|
||||||
if (child == constant::false_instance())
|
return constant::false_instance();
|
||||||
{
|
|
||||||
if (min == 0)
|
|
||||||
return constant::empty_word_instance();
|
|
||||||
else
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - Exp[*0] = [*0]
|
|
||||||
if (max == 0)
|
|
||||||
{
|
|
||||||
child->destroy();
|
|
||||||
return constant::empty_word_instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - Exp[*1] = Exp
|
|
||||||
if (min == 1 && max == 1)
|
|
||||||
return child;
|
|
||||||
|
|
||||||
// - Exp[*i..j][*min..max] = Exp[*i(min)..j(max)]
|
|
||||||
// if i*(min+1)<=j(min)+1.
|
|
||||||
if (const bunop* s = is_bunop(child))
|
|
||||||
{
|
|
||||||
unsigned i = s->min();
|
|
||||||
unsigned j = s->max();
|
|
||||||
|
|
||||||
// Exp has to be true between i*min and j*min
|
|
||||||
// then between i*(min+1) and j*(min+1)
|
|
||||||
// ...
|
|
||||||
// finally between i*max and j*max
|
|
||||||
//
|
|
||||||
// We can merge these intervals into [i*min..j*max] iff the
|
|
||||||
// first are adjacent or overlap, i.e. iff
|
|
||||||
// i*(min+1) <= j*min+1.
|
|
||||||
// (Because i<=j, this entails that the other intervals also
|
|
||||||
// overlap).
|
|
||||||
|
|
||||||
const formula* exp = s->child();
|
|
||||||
if (j == unbounded)
|
|
||||||
{
|
|
||||||
min *= i;
|
|
||||||
max = unbounded;
|
|
||||||
|
|
||||||
// Exp[*min..max]
|
|
||||||
exp->clone();
|
|
||||||
child->destroy();
|
|
||||||
child = exp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i * (min + 1) <= (j * min) + 1)
|
|
||||||
{
|
|
||||||
min *= i;
|
|
||||||
if (max != unbounded)
|
|
||||||
{
|
|
||||||
if (j == unbounded)
|
|
||||||
max = unbounded;
|
|
||||||
else
|
|
||||||
max *= j;
|
|
||||||
}
|
|
||||||
exp->clone();
|
|
||||||
child->destroy();
|
|
||||||
child = exp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - 0[*0..max] = [*0]
|
||||||
|
// - 0[*min..max] = 0 if min > 0
|
||||||
|
// - b[:*0..max] = 1
|
||||||
|
// - b[:*min..max] = 0 if min > 0
|
||||||
|
if (child == constant::false_instance()
|
||||||
|
|| (op == FStar && child->is_boolean()))
|
||||||
|
{
|
||||||
|
if (min == 0)
|
||||||
|
{
|
||||||
|
child->destroy();
|
||||||
|
return neutral;
|
||||||
|
}
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Exp[*0] = [*0]
|
||||||
|
// - Exp[:*0] = 1
|
||||||
|
if (max == 0)
|
||||||
|
{
|
||||||
|
child->destroy();
|
||||||
|
return neutral;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - Exp[*1] = Exp
|
||||||
|
// - Exp[:*1] = Exp if Exp does not accept [*0]
|
||||||
|
if (min == 1 && max == 1)
|
||||||
|
if (op == Star || !child->accepts_eword())
|
||||||
|
return child;
|
||||||
|
|
||||||
|
// - Exp[*i..j][*k..l] = Exp[*ik..jl] if i*(k+1)<=jk+1.
|
||||||
|
// - Exp[:*i..j][:*k..l] = Exp[:*ik..jl] if i*(k+1)<=jk+1.
|
||||||
|
if (const bunop* s = is_bunop(child, op))
|
||||||
|
{
|
||||||
|
unsigned i = s->min();
|
||||||
|
unsigned j = s->max();
|
||||||
|
|
||||||
|
// Exp has to be true between i*min and j*min
|
||||||
|
// then between i*(min+1) and j*(min+1)
|
||||||
|
// ...
|
||||||
|
// finally between i*max and j*max
|
||||||
|
//
|
||||||
|
// We can merge these intervals into [i*min..j*max] iff the
|
||||||
|
// first are adjacent or overlap, i.e. iff
|
||||||
|
// i*(min+1) <= j*min+1.
|
||||||
|
// (Because i<=j, this entails that the other intervals also
|
||||||
|
// overlap).
|
||||||
|
|
||||||
|
const formula* exp = s->child();
|
||||||
|
if (j == unbounded)
|
||||||
|
{
|
||||||
|
min *= i;
|
||||||
|
max = unbounded;
|
||||||
|
|
||||||
|
// Exp[*min..max]
|
||||||
|
exp->clone();
|
||||||
|
child->destroy();
|
||||||
|
child = exp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i * (min + 1) <= (j * min) + 1)
|
||||||
|
{
|
||||||
|
min *= i;
|
||||||
|
if (max != unbounded)
|
||||||
|
{
|
||||||
|
if (j == unbounded)
|
||||||
|
max = unbounded;
|
||||||
|
else
|
||||||
|
max *= j;
|
||||||
|
}
|
||||||
|
exp->clone();
|
||||||
|
child->destroy();
|
||||||
|
child = exp;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const formula* res;
|
const formula* res;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2010, 2011, 2012, 2013, 2014 Laboratoire de Recherche
|
// Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire de Recherche
|
||||||
// et Développement de l'Epita (LRDE).
|
// et Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -38,7 +38,7 @@ namespace spot
|
||||||
class SPOT_API bunop final : public formula
|
class SPOT_API bunop final : public formula
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum type { Star };
|
enum type { Star, FStar };
|
||||||
|
|
||||||
static const unsigned unbounded = -1U;
|
static const unsigned unbounded = -1U;
|
||||||
|
|
||||||
|
|
@ -50,9 +50,16 @@ namespace spot
|
||||||
/// - 0[*0..max] = [*0]
|
/// - 0[*0..max] = [*0]
|
||||||
/// - 0[*min..max] = 0 if min > 0
|
/// - 0[*min..max] = 0 if min > 0
|
||||||
/// - [*0][*min..max] = [*0]
|
/// - [*0][*min..max] = [*0]
|
||||||
/// - Exp[*0] = [*0]
|
|
||||||
/// - Exp[*i..j][*k..l] = Exp[*ik..jl] if i*(k+1)<=jk+1.
|
/// - Exp[*i..j][*k..l] = Exp[*ik..jl] if i*(k+1)<=jk+1.
|
||||||
|
/// - Exp[*0] = [*0]
|
||||||
/// - Exp[*1] = Exp
|
/// - Exp[*1] = Exp
|
||||||
|
/// - b[:*0..max] = 1
|
||||||
|
/// - b[:*min..max] = b if min > 0
|
||||||
|
/// - [*0][:*0..max] = 1
|
||||||
|
/// - [*0][:*min..max] = 0 if min > 0
|
||||||
|
/// - Exp[:*i..j][:*k..l] = Exp[:*ik..jl] if i*(k+1)<=jk+1.
|
||||||
|
/// - Exp[:*0] = 1
|
||||||
|
/// - Exp[:*1] = Exp if Exp does not accept [*0]
|
||||||
///
|
///
|
||||||
/// These rewriting rules imply that it is not possible to build
|
/// These rewriting rules imply that it is not possible to build
|
||||||
/// an LTL formula object that is SYNTACTICALLY equal to one of
|
/// an LTL formula object that is SYNTACTICALLY equal to one of
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
|
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire de
|
||||||
// Recherche et Développement de l'Epita (LRDE).
|
// Recherche et Développement de l'Epita (LRDE).
|
||||||
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
|
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
|
||||||
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||||
|
|
@ -495,13 +495,19 @@ namespace spot
|
||||||
v->swap(tmp);
|
v->swap(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (op == Concat)
|
else if (op == Concat || op == Fusion)
|
||||||
{
|
{
|
||||||
// Perform an extra loop to merge starable items.
|
// Perform an extra loop to merge starable items.
|
||||||
// f;f -> f[*2]
|
// f;f -> f[*2]
|
||||||
// f;f[*i..j] -> f[*i+1..j+1]
|
// f;f[*i..j] -> f[*i+1..j+1]
|
||||||
// f[*i..j];f -> f[*i+1..j+1]
|
// f[*i..j];f -> f[*i+1..j+1]
|
||||||
// f[*i..j];f[*k..l] -> f[*i+k..j+l]
|
// f[*i..j];f[*k..l] -> f[*i+k..j+l]
|
||||||
|
// same for FStar:
|
||||||
|
// f:f -> f[:*2]
|
||||||
|
// f:f[*i..j] -> f[:*i+1..j+1]
|
||||||
|
// f[:*i..j];f -> f[:*i+1..j+1]
|
||||||
|
// f[:*i..j];f[:*k..l] -> f[:*i+k..j+l]
|
||||||
|
bunop::type bop = op == Concat ? bunop::Star : bunop::FStar;
|
||||||
i = v->begin();
|
i = v->begin();
|
||||||
while (i != v->end())
|
while (i != v->end())
|
||||||
{
|
{
|
||||||
|
|
@ -510,7 +516,7 @@ namespace spot
|
||||||
unsigned min;
|
unsigned min;
|
||||||
unsigned max;
|
unsigned max;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
if (const bunop* is = is_Star(*i))
|
if (const bunop* is = is_bunop(*i, bop))
|
||||||
{
|
{
|
||||||
f = is->child();
|
f = is->child();
|
||||||
min = is->min();
|
min = is->min();
|
||||||
|
|
@ -528,7 +534,7 @@ namespace spot
|
||||||
const formula* f2;
|
const formula* f2;
|
||||||
unsigned min2;
|
unsigned min2;
|
||||||
unsigned max2;
|
unsigned max2;
|
||||||
if (const bunop* is = is_Star(*i))
|
if (const bunop* is = is_bunop(*i, bop))
|
||||||
{
|
{
|
||||||
f2 = is->child();
|
f2 = is->child();
|
||||||
if (f2 != f)
|
if (f2 != f)
|
||||||
|
|
@ -558,7 +564,7 @@ namespace spot
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
const formula* newfs =
|
const formula* newfs =
|
||||||
bunop::instance(bunop::Star, f->clone(), min, max);
|
bunop::instance(bop, f->clone(), min, max);
|
||||||
(*fpos)->destroy();
|
(*fpos)->destroy();
|
||||||
*fpos = newfs;
|
*fpos = newfs;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* -*- coding: utf-8 -*-
|
/* -*- coding: utf-8 -*-
|
||||||
** Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
|
** Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire
|
||||||
** Recherche et Développement de l'Epita (LRDE).
|
** de Recherche et Développement de l'Epita (LRDE).
|
||||||
** Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
|
** Copyright (C) 2003, 2004, 2005, 2006 Laboratoire d'Informatique de
|
||||||
** Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
** Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||||
** Université Pierre et Marie Curie.
|
** Université Pierre et Marie Curie.
|
||||||
|
|
@ -176,8 +176,11 @@ using namespace spot::ltl;
|
||||||
%token OP_F "sometimes operator" OP_G "always operator"
|
%token OP_F "sometimes operator" OP_G "always operator"
|
||||||
%token OP_X "next operator" OP_NOT "not operator"
|
%token OP_X "next operator" OP_NOT "not operator"
|
||||||
%token OP_STAR "star operator" OP_BSTAR "bracket star operator"
|
%token OP_STAR "star operator" OP_BSTAR "bracket star operator"
|
||||||
|
%token OP_BFSTAR "bracket fusion-star operator"
|
||||||
%token OP_PLUS "plus operator"
|
%token OP_PLUS "plus operator"
|
||||||
|
%token OP_FPLUS "fusion-plus operator"
|
||||||
%token OP_STAR_OPEN "opening bracket for star operator"
|
%token OP_STAR_OPEN "opening bracket for star operator"
|
||||||
|
%token OP_FSTAR_OPEN "opening bracket for fusion-star operator"
|
||||||
%token OP_EQUAL_OPEN "opening bracket for equal operator"
|
%token OP_EQUAL_OPEN "opening bracket for equal operator"
|
||||||
%token OP_GOTO_OPEN "opening bracket for goto operator"
|
%token OP_GOTO_OPEN "opening bracket for goto operator"
|
||||||
%token OP_SQBKT_CLOSE "closing bracket"
|
%token OP_SQBKT_CLOSE "closing bracket"
|
||||||
|
|
@ -220,7 +223,9 @@ using namespace spot::ltl;
|
||||||
%nonassoc OP_X
|
%nonassoc OP_X
|
||||||
|
|
||||||
/* High priority regex operator. */
|
/* High priority regex operator. */
|
||||||
%nonassoc OP_BSTAR OP_STAR_OPEN OP_PLUS OP_EQUAL_OPEN OP_GOTO_OPEN
|
%nonassoc OP_BSTAR OP_STAR_OPEN OP_PLUS
|
||||||
|
OP_BFSTAR OP_FSTAR_OPEN OP_FPLUS
|
||||||
|
OP_EQUAL_OPEN OP_GOTO_OPEN
|
||||||
|
|
||||||
/* Not has the most important priority (after Wring's `=0' and `=1',
|
/* Not has the most important priority (after Wring's `=0' and `=1',
|
||||||
but as those can only attach to atomic proposition, they do not
|
but as those can only attach to atomic proposition, they do not
|
||||||
|
|
@ -229,7 +234,7 @@ using namespace spot::ltl;
|
||||||
|
|
||||||
%type <ltl> subformula booleanatom sere lbtformula boolformula
|
%type <ltl> subformula booleanatom sere lbtformula boolformula
|
||||||
%type <ltl> bracedsere parenthesedsubformula
|
%type <ltl> bracedsere parenthesedsubformula
|
||||||
%type <minmax> starargs equalargs sqbracketargs gotoargs
|
%type <minmax> starargs fstarargs equalargs sqbracketargs gotoargs
|
||||||
|
|
||||||
%destructor { delete $$; } <str>
|
%destructor { delete $$; } <str>
|
||||||
%destructor { $$->destroy(); } <ltl>
|
%destructor { $$->destroy(); } <ltl>
|
||||||
|
|
@ -370,6 +375,21 @@ starargs: kleen_star
|
||||||
{ error_list.emplace_back(@$, "missing closing bracket for star");
|
{ error_list.emplace_back(@$, "missing closing bracket for star");
|
||||||
$$.min = $$.max = 0U; }
|
$$.min = $$.max = 0U; }
|
||||||
|
|
||||||
|
fstarargs: OP_BFSTAR
|
||||||
|
{ $$.min = 0U; $$.max = bunop::unbounded; }
|
||||||
|
| OP_FPLUS
|
||||||
|
{ $$.min = 1U; $$.max = bunop::unbounded; }
|
||||||
|
| OP_FSTAR_OPEN sqbracketargs
|
||||||
|
{ $$ = $2; }
|
||||||
|
| OP_FSTAR_OPEN error OP_SQBKT_CLOSE
|
||||||
|
{ error_list.emplace_back
|
||||||
|
(@$, "treating this fusion-star block as [:*]");
|
||||||
|
$$.min = 0U; $$.max = bunop::unbounded; }
|
||||||
|
| OP_FSTAR_OPEN error_opt END_OF_INPUT
|
||||||
|
{ error_list.emplace_back
|
||||||
|
(@$, "missing closing bracket for fusion-star");
|
||||||
|
$$.min = $$.max = 0U; }
|
||||||
|
|
||||||
equalargs: OP_EQUAL_OPEN sqbracketargs
|
equalargs: OP_EQUAL_OPEN sqbracketargs
|
||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
| OP_EQUAL_OPEN error OP_SQBKT_CLOSE
|
| OP_EQUAL_OPEN error OP_SQBKT_CLOSE
|
||||||
|
|
@ -507,15 +527,6 @@ sere: booleanatom
|
||||||
{ $$ = multop::instance(multop::Fusion, $1, $3); }
|
{ $$ = multop::instance(multop::Fusion, $1, $3); }
|
||||||
| sere OP_FUSION error
|
| sere OP_FUSION error
|
||||||
{ missing_right_binop($$, $1, @2, "fusion operator"); }
|
{ missing_right_binop($$, $1, @2, "fusion operator"); }
|
||||||
| sere starargs
|
|
||||||
{
|
|
||||||
if ($2.max < $2.min)
|
|
||||||
{
|
|
||||||
error_list.emplace_back(@2, "reversed range");
|
|
||||||
std::swap($2.max, $2.min);
|
|
||||||
}
|
|
||||||
$$ = bunop::instance(bunop::Star, $1, $2.min, $2.max);
|
|
||||||
}
|
|
||||||
| starargs
|
| starargs
|
||||||
{
|
{
|
||||||
if ($1.max < $1.min)
|
if ($1.max < $1.min)
|
||||||
|
|
@ -526,6 +537,24 @@ sere: booleanatom
|
||||||
$$ = bunop::instance(bunop::Star, constant::true_instance(),
|
$$ = bunop::instance(bunop::Star, constant::true_instance(),
|
||||||
$1.min, $1.max);
|
$1.min, $1.max);
|
||||||
}
|
}
|
||||||
|
| sere starargs
|
||||||
|
{
|
||||||
|
if ($2.max < $2.min)
|
||||||
|
{
|
||||||
|
error_list.emplace_back(@2, "reversed range");
|
||||||
|
std::swap($2.max, $2.min);
|
||||||
|
}
|
||||||
|
$$ = bunop::instance(bunop::Star, $1, $2.min, $2.max);
|
||||||
|
}
|
||||||
|
| sere fstarargs
|
||||||
|
{
|
||||||
|
if ($2.max < $2.min)
|
||||||
|
{
|
||||||
|
error_list.emplace_back(@2, "reversed range");
|
||||||
|
std::swap($2.max, $2.min);
|
||||||
|
}
|
||||||
|
$$ = bunop::instance(bunop::FStar, $1, $2.min, $2.max);
|
||||||
|
}
|
||||||
| sere equalargs
|
| sere equalargs
|
||||||
{
|
{
|
||||||
if ($2.max < $2.min)
|
if ($2.max < $2.min)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* -*- coding: utf-8 -*-
|
/* -*- coding: utf-8 -*-
|
||||||
** Copyright (C) 2010, 2011, 2012, 2013, 2014, Laboratoire de
|
** Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, Laboratoire de
|
||||||
** Recherche et Développement de l'Epita (LRDE).
|
** Recherche et Développement 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
|
||||||
|
|
@ -224,6 +224,9 @@ eol2 (\n\r)+|(\r\n)+
|
||||||
"[*]" BEGIN(0); return token::OP_BSTAR;
|
"[*]" BEGIN(0); return token::OP_BSTAR;
|
||||||
"[+]" BEGIN(0); return token::OP_PLUS;
|
"[+]" BEGIN(0); return token::OP_PLUS;
|
||||||
"[*" BEGIN(sqbracket); return token::OP_STAR_OPEN;
|
"[*" BEGIN(sqbracket); return token::OP_STAR_OPEN;
|
||||||
|
"[:*]" BEGIN(0); return token::OP_BFSTAR;
|
||||||
|
"[:+]" BEGIN(0); return token::OP_FPLUS;
|
||||||
|
"[:*" BEGIN(sqbracket); return token::OP_FSTAR_OPEN;
|
||||||
"[=" BEGIN(sqbracket); return token::OP_EQUAL_OPEN;
|
"[=" BEGIN(sqbracket); return token::OP_EQUAL_OPEN;
|
||||||
"["{ARROWL} BEGIN(sqbracket); return token::OP_GOTO_OPEN;
|
"["{ARROWL} BEGIN(sqbracket); return token::OP_GOTO_OPEN;
|
||||||
<sqbracket>"]" BEGIN(0); return token::OP_SQBKT_CLOSE;
|
<sqbracket>"]" BEGIN(0); return token::OP_SQBKT_CLOSE;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2009, 2010, 2011, 2012, 2014 Laboratoire de Recherche et
|
# Copyright (C) 2009, 2010, 2011, 2012, 2014, 2015 Laboratoire de Recherche et
|
||||||
# Développement de l'Epita (LRDE).
|
# Développement 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
|
||||||
|
|
@ -181,6 +181,20 @@ G({1}<>->1), 1
|
||||||
{1[->10\,20];b}, {[*10..20];b}
|
{1[->10\,20];b}, {[*10..20];b}
|
||||||
{1[->..];b}, {[*1..];b}
|
{1[->..];b}, {[*1..];b}
|
||||||
{{a&!c}[->0];b}, b
|
{{a&!c}[->0];b}, b
|
||||||
|
|
||||||
|
{(a|c)[:*0..3];d}, {1;d}
|
||||||
|
{(a|c)[:*1..3];d}, {(a|c);d}
|
||||||
|
{0[:*0..3];d}, {1;d}
|
||||||
|
{0[:*1..3];d}, 0
|
||||||
|
{1[:*0..3];d}, {1;d}
|
||||||
|
{1[:*1..3];d}, {1;d}
|
||||||
|
{[*0][:*0..3];d}, {1;d}
|
||||||
|
{[*0][:*1..3];d}, 0
|
||||||
|
{(a*;b|c)[:*1to3][:*2:4]}, {(a*;b|c)[:*2..12]}
|
||||||
|
{(a*;b|c)[:*][:+]}, {(a*;b|c)[:*]}
|
||||||
|
{(a*;b|c)[:*0]}, 1
|
||||||
|
{(a*;b|c)[:*1]}, {(a*;b|c)}
|
||||||
|
{(a;b):(a;b):(a;b)[:*2]:(a;b):b*:b*:(c;d)[:*1]}, {(a;b)[:*5]:b*[:*2]:(c;d)}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2013 Laboratoire de Recherche et Développement
|
# Copyright (C) 2013, 2015 Laboratoire de Recherche et Développement
|
||||||
# de l'Epita (LRDE).
|
# de l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
|
|
@ -35,6 +35,7 @@ a U b W c R (d & e) M f
|
||||||
{a;b[=2];((c:d*) && f*);e[*2..]}<>-> {((a | [*0])*;b[+]) & (c1[->2])}[]-> h
|
{a;b[=2];((c:d*) && f*);e[*2..]}<>-> {((a | [*0])*;b[+]) & (c1[->2])}[]-> h
|
||||||
{a;b;c} []=> {d*;e} <>=> !f
|
{a;b;c} []=> {d*;e} <>=> !f
|
||||||
!{a;b*;c}! -> d
|
!{a;b*;c}! -> d
|
||||||
|
{a*;(b;c)[:*3..4];(c;d)[:+];d}!
|
||||||
G(uglyname->Fuglierlongname42)
|
G(uglyname->Fuglierlongname42)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2014 Laboratoire de Recherche et Développement
|
# Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
|
||||||
# de l'Epita (LRDE).
|
# de l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
|
|
@ -34,6 +34,8 @@ eword 1
|
||||||
boolform 1
|
boolform 1
|
||||||
star 1
|
star 1
|
||||||
star_b 1
|
star_b 1
|
||||||
|
fstar 1
|
||||||
|
fstar_b 1
|
||||||
and 0
|
and 0
|
||||||
andNLM 0
|
andNLM 0
|
||||||
or 1
|
or 1
|
||||||
|
|
@ -53,8 +55,11 @@ EOF
|
||||||
diff stdout expected
|
diff stdout expected
|
||||||
|
|
||||||
|
|
||||||
|
sere='eword=0,and=0,andNLM=0,fusion=0,star=0,star_b=0'
|
||||||
|
sere="$sere,or=0,concat=0,fstar=0,fstar_b=0"
|
||||||
|
|
||||||
run 0 $randltl -S -n 10000 a b c --tree-size=10..20 \
|
run 0 $randltl -S -n 10000 a b c --tree-size=10..20 \
|
||||||
--sere-p=eword=0,and=0,andNLM=0,fusion=0,star=0,star_b=0,or=0,concat=0 \
|
--sere-p=$sere \
|
||||||
--boolean-p=equiv=0,implies=0,xor=0,and=0,not=0,false=0,true=0,or=0 \
|
--boolean-p=equiv=0,implies=0,xor=0,and=0,not=0,false=0,true=0,or=0 \
|
||||||
--dump-pr > stdout
|
--dump-pr > stdout
|
||||||
|
|
||||||
|
|
@ -64,6 +69,8 @@ eword 0
|
||||||
boolform 1
|
boolform 1
|
||||||
star 0
|
star 0
|
||||||
star_b 0
|
star_b 0
|
||||||
|
fstar 0
|
||||||
|
fstar_b 0
|
||||||
and 0
|
and 0
|
||||||
andNLM 0
|
andNLM 0
|
||||||
or 0
|
or 0
|
||||||
|
|
@ -86,7 +93,7 @@ diff stdout expected
|
||||||
|
|
||||||
# Disabling all operators will prevent more formulas to be generated.
|
# Disabling all operators will prevent more formulas to be generated.
|
||||||
$randltl -S -n 10000 a b c --tree-size=10..20 \
|
$randltl -S -n 10000 a b c --tree-size=10..20 \
|
||||||
--sere-p=eword=0,and=0,andNLM=0,fusion=0,star=0,star_b=0,or=0,concat=0 \
|
--sere-p=$sere \
|
||||||
--boolean-p=equiv=0,implies=0,xor=0,and=0,not=0,false=0,true=0,or=0 > out &&
|
--boolean-p=equiv=0,implies=0,xor=0,and=0,not=0,false=0,true=0,or=0 > out &&
|
||||||
exit 1
|
exit 1
|
||||||
sort out > out2
|
sort out > out2
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ namespace spot
|
||||||
|
|
||||||
// SEREs
|
// SEREs
|
||||||
random_sere::random_sere(const atomic_prop_set* ap)
|
random_sere::random_sere(const atomic_prop_set* ap)
|
||||||
: random_formula(9, ap), rb(ap)
|
: random_formula(11, ap), rb(ap)
|
||||||
{
|
{
|
||||||
proba_[0].setup("eword", 1, eword_builder);
|
proba_[0].setup("eword", 1, eword_builder);
|
||||||
proba_2_ = proba_ + 1;
|
proba_2_ = proba_ + 1;
|
||||||
|
|
@ -316,11 +316,13 @@ namespace spot
|
||||||
proba_[1].setup("boolform", 1, boolform_builder);
|
proba_[1].setup("boolform", 1, boolform_builder);
|
||||||
proba_[2].setup("star", 2, bunop_unbounded_builder<bunop::Star>);
|
proba_[2].setup("star", 2, bunop_unbounded_builder<bunop::Star>);
|
||||||
proba_[3].setup("star_b", 2, bunop_bounded_builder<bunop::Star>);
|
proba_[3].setup("star_b", 2, bunop_bounded_builder<bunop::Star>);
|
||||||
proba_[4].setup("and", 3, multop_builder<multop::AndRat>);
|
proba_[4].setup("fstar", 2, bunop_unbounded_builder<bunop::FStar>);
|
||||||
proba_[5].setup("andNLM", 3, multop_builder<multop::AndNLM>);
|
proba_[5].setup("fstar_b", 2, bunop_bounded_builder<bunop::FStar>);
|
||||||
proba_[6].setup("or", 3, multop_builder<multop::OrRat>);
|
proba_[6].setup("and", 3, multop_builder<multop::AndRat>);
|
||||||
proba_[7].setup("concat", 3, multop_builder<multop::Concat>);
|
proba_[7].setup("andNLM", 3, multop_builder<multop::AndNLM>);
|
||||||
proba_[8].setup("fusion", 3, multop_builder<multop::Fusion>);
|
proba_[8].setup("or", 3, multop_builder<multop::OrRat>);
|
||||||
|
proba_[9].setup("concat", 3, multop_builder<multop::Concat>);
|
||||||
|
proba_[10].setup("fusion", 3, multop_builder<multop::Fusion>);
|
||||||
|
|
||||||
update_sums();
|
update_sums();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2011, 2012, 2013, 2014 Laboratoire de Recherche et
|
// Copyright (C) 2011, 2012, 2013, 2014, 2015 Laboratoire de Recherche
|
||||||
// Developpement de l'Epita (LRDE).
|
// et Developpement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -1085,6 +1085,9 @@ namespace spot
|
||||||
}
|
}
|
||||||
result_ = bunop::instance(op, h, min, bo->max());
|
result_ = bunop::instance(op, h, min, bo->max());
|
||||||
break;
|
break;
|
||||||
|
case bunop::FStar:
|
||||||
|
result_ = bunop::instance(op, h, min, bo->max());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3274,6 +3277,8 @@ namespace spot
|
||||||
r->destroy();
|
r->destroy();
|
||||||
f = 0;
|
f = 0;
|
||||||
break;
|
break;
|
||||||
|
case bunop::FStar:
|
||||||
|
goto common;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012, 2014 Laboratoire de Recherche et Developpement
|
// Copyright (C) 2012, 2014, 2015 Laboratoire de Recherche et
|
||||||
// de l'Epita (LRDE).
|
// Developpement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -70,6 +70,11 @@ namespace spot
|
||||||
// Strip the star.
|
// Strip the star.
|
||||||
result_ = recurse(bo->child());
|
result_ = recurse(bo->child());
|
||||||
break;
|
break;
|
||||||
|
case bunop::FStar:
|
||||||
|
// FIXME: Can we deal with FStar in a better way?
|
||||||
|
result_ = bo->clone();
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,6 +176,9 @@ namespace spot
|
||||||
std::max(bo->min(), 1U),
|
std::max(bo->min(), 1U),
|
||||||
bo->max());
|
bo->max());
|
||||||
break;
|
break;
|
||||||
|
case bunop::FStar:
|
||||||
|
result_ = bo->clone();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2008, 2010, 2012, 2013, 2014 Laboratoire de Recherche
|
// Copyright (C) 2008, 2010, 2012, 2013, 2014, 2015 Laboratoire de
|
||||||
// et Développement de l'Epita (LRDE)
|
// Recherche et Développement 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
|
||||||
// et Marie Curie.
|
// et Marie Curie.
|
||||||
|
|
@ -71,6 +71,8 @@ namespace spot
|
||||||
KCloseBunop,
|
KCloseBunop,
|
||||||
KStarBunop,
|
KStarBunop,
|
||||||
KPlusBunop,
|
KPlusBunop,
|
||||||
|
KFStarBunop,
|
||||||
|
KFPlusBunop,
|
||||||
KEqualBunop,
|
KEqualBunop,
|
||||||
KGotoBunop,
|
KGotoBunop,
|
||||||
};
|
};
|
||||||
|
|
@ -108,6 +110,8 @@ namespace spot
|
||||||
"]",
|
"]",
|
||||||
"[*",
|
"[*",
|
||||||
"[+]",
|
"[+]",
|
||||||
|
"[:*",
|
||||||
|
"[:+]",
|
||||||
"[=",
|
"[=",
|
||||||
"[->",
|
"[->",
|
||||||
};
|
};
|
||||||
|
|
@ -121,7 +125,7 @@ namespace spot
|
||||||
" <-> ", // rewritten, although supported
|
" <-> ", // rewritten, although supported
|
||||||
" U ",
|
" U ",
|
||||||
" V ",
|
" V ",
|
||||||
" W ", // rewritten, although supported
|
" W ", // rewritten
|
||||||
" M ", // rewritten
|
" M ", // rewritten
|
||||||
"<>-> ", // not supported
|
"<>-> ", // not supported
|
||||||
"<>=> ", // not supported
|
"<>=> ", // not supported
|
||||||
|
|
@ -145,6 +149,8 @@ namespace spot
|
||||||
"]", // not supported
|
"]", // not supported
|
||||||
"[*", // not supported
|
"[*", // not supported
|
||||||
"[+]", // not supported
|
"[+]", // not supported
|
||||||
|
"[:*", // not supported
|
||||||
|
"[:+]", // not supported
|
||||||
"[=", // not supported
|
"[=", // not supported
|
||||||
"[->", // not supported
|
"[->", // not supported
|
||||||
};
|
};
|
||||||
|
|
@ -182,6 +188,8 @@ namespace spot
|
||||||
"]", // not supported
|
"]", // not supported
|
||||||
"[*", // not supported
|
"[*", // not supported
|
||||||
"[+]", // not supported
|
"[+]", // not supported
|
||||||
|
"[:*", // not supported
|
||||||
|
"[:+]", // not supported
|
||||||
"[=", // not supported
|
"[=", // not supported
|
||||||
"[->", // not supported
|
"[->", // not supported
|
||||||
};
|
};
|
||||||
|
|
@ -219,6 +227,8 @@ namespace spot
|
||||||
"]",
|
"]",
|
||||||
"[*",
|
"[*",
|
||||||
"[+]",
|
"[+]",
|
||||||
|
"[:*",
|
||||||
|
"[:+]",
|
||||||
"[=",
|
"[=",
|
||||||
"[->",
|
"[->",
|
||||||
};
|
};
|
||||||
|
|
@ -256,6 +266,8 @@ namespace spot
|
||||||
"}",
|
"}",
|
||||||
"\\SereStar{",
|
"\\SereStar{",
|
||||||
"\\SerePlus{}",
|
"\\SerePlus{}",
|
||||||
|
"\\SereFStar{",
|
||||||
|
"\\SereFPlus{}",
|
||||||
"\\SereEqual{",
|
"\\SereEqual{",
|
||||||
"\\SereGoto{",
|
"\\SereGoto{",
|
||||||
};
|
};
|
||||||
|
|
@ -297,6 +309,8 @@ namespace spot
|
||||||
"}",
|
"}",
|
||||||
"^{\\star",
|
"^{\\star",
|
||||||
"^+",
|
"^+",
|
||||||
|
"^{\\mathsf{:}\\star",
|
||||||
|
"^{\\mathsf{:}+}",
|
||||||
"^{=",
|
"^{=",
|
||||||
"^{\\to",
|
"^{\\to",
|
||||||
};
|
};
|
||||||
|
|
@ -577,17 +591,18 @@ namespace spot
|
||||||
visit(const bunop* bo)
|
visit(const bunop* bo)
|
||||||
{
|
{
|
||||||
const formula* c = bo->child();
|
const formula* c = bo->child();
|
||||||
enum { Star, Goto, Equal } sugar = Star;
|
enum { Star, FStar, Goto } sugar = Star;
|
||||||
unsigned default_min = 0;
|
unsigned default_min = 0;
|
||||||
unsigned default_max = bunop::unbounded;
|
unsigned default_max = bunop::unbounded;
|
||||||
|
|
||||||
|
bunop::type op = bo->op();
|
||||||
// Abbreviate "1[*]" as "[*]".
|
// Abbreviate "1[*]" as "[*]".
|
||||||
if (c != constant::true_instance())
|
if (c != constant::true_instance() || op != bunop::Star)
|
||||||
{
|
{
|
||||||
bunop::type op = bo->op();
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case bunop::Star:
|
case bunop::Star:
|
||||||
|
// Is this a Goto?
|
||||||
if (const multop* mo = is_Concat(c))
|
if (const multop* mo = is_Concat(c))
|
||||||
{
|
{
|
||||||
unsigned s = mo->size();
|
unsigned s = mo->size();
|
||||||
|
|
@ -599,6 +614,9 @@ namespace spot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case bunop::FStar:
|
||||||
|
sugar = FStar;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_bunop_child(c);
|
emit_bunop_child(c);
|
||||||
|
|
@ -616,8 +634,13 @@ namespace spot
|
||||||
}
|
}
|
||||||
emit(KStarBunop);
|
emit(KStarBunop);
|
||||||
break;
|
break;
|
||||||
case Equal:
|
case FStar:
|
||||||
emit(KEqualBunop);
|
if (min == 1 && max == bunop::unbounded)
|
||||||
|
{
|
||||||
|
emit(KFPlusBunop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit(KFStarBunop);
|
||||||
break;
|
break;
|
||||||
case Goto:
|
case Goto:
|
||||||
emit(KGotoBunop);
|
emit(KGotoBunop);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire
|
// Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
|
||||||
// de Recherche et Développement de l'Epita (LRDE).
|
// Laboratoire de Recherche et Développement de l'Epita (LRDE).
|
||||||
// Copyright (C) 2003, 2004, 2005, 2006 Laboratoire
|
// Copyright (C) 2003, 2004, 2005, 2006 Laboratoire
|
||||||
// d'Informatique de Paris 6 (LIP6), département Systèmes Répartis
|
// d'Informatique de Paris 6 (LIP6), département Systèmes Répartis
|
||||||
// Coopératifs (SRC), Université Pierre et Marie Curie.
|
// Coopératifs (SRC), Université Pierre et Marie Curie.
|
||||||
|
|
@ -708,20 +708,30 @@ namespace spot
|
||||||
unsigned max = bo->max();
|
unsigned max = bo->max();
|
||||||
|
|
||||||
assert(max > 0);
|
assert(max > 0);
|
||||||
|
bunop::type op = bo->op();
|
||||||
|
|
||||||
|
// we will interpret
|
||||||
|
// c[*i..j]
|
||||||
|
// or c[:*i..j]
|
||||||
|
// as
|
||||||
|
// c;c[*i-1..j-1]
|
||||||
|
// or c:c[*i-1..j-1]
|
||||||
|
// \........../
|
||||||
|
// this is f
|
||||||
unsigned min2 = (min == 0) ? 0 : (min - 1);
|
unsigned min2 = (min == 0) ? 0 : (min - 1);
|
||||||
unsigned max2 =
|
unsigned max2 =
|
||||||
(max == bunop::unbounded) ? bunop::unbounded : (max - 1);
|
(max == bunop::unbounded) ? bunop::unbounded : (max - 1);
|
||||||
|
f = bunop::instance(op, bo->child()->clone(), min2, max2);
|
||||||
|
|
||||||
|
// If we have something to append, we can actually append it
|
||||||
|
// to f. This is correct even in the case of FStar, as f
|
||||||
|
// cannot accept [*0].
|
||||||
|
if (to_concat_)
|
||||||
|
f = multop::instance(multop::Concat, f, to_concat_->clone());
|
||||||
|
|
||||||
bunop::type op = bo->op();
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case bunop::Star:
|
case bunop::Star:
|
||||||
f = bunop::instance(op, bo->child()->clone(), min2, max2);
|
|
||||||
|
|
||||||
if (to_concat_)
|
|
||||||
f = multop::instance(multop::Concat, f, to_concat_->clone());
|
|
||||||
|
|
||||||
if (!bo->child()->accepts_eword())
|
if (!bo->child()->accepts_eword())
|
||||||
{
|
{
|
||||||
// f*;g -> f;f*;g | g
|
// f*;g -> f;f*;g | g
|
||||||
|
|
@ -777,6 +787,57 @@ namespace spot
|
||||||
res_ |= now_to_concat();
|
res_ |= now_to_concat();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
case bunop::FStar:
|
||||||
|
{
|
||||||
|
res_ = recurse(bo->child());
|
||||||
|
bdd tail_bdd;
|
||||||
|
bool tail_computed = false;
|
||||||
|
|
||||||
|
minato_isop isop(res_);
|
||||||
|
bdd cube;
|
||||||
|
res_ = bddfalse;
|
||||||
|
if (min == 0)
|
||||||
|
{
|
||||||
|
// f[:*0..j];g can be satisfied by X(g).
|
||||||
|
res_ = next_to_concat();
|
||||||
|
}
|
||||||
|
while ((cube = isop.next()) != bddfalse)
|
||||||
|
{
|
||||||
|
bdd label = bdd_exist(cube, dict_.next_set);
|
||||||
|
bdd dest_bdd = bdd_existcomp(cube, dict_.next_set);
|
||||||
|
const formula* dest = dict_.conj_bdd_to_sere(dest_bdd);
|
||||||
|
|
||||||
|
// The destination is a final state. Make sure we
|
||||||
|
// can also exit if tail is satisfied. We do not
|
||||||
|
// even have to check the tail if min == 0.
|
||||||
|
if (dest->accepts_eword() && min != 0)
|
||||||
|
{
|
||||||
|
if (!tail_computed)
|
||||||
|
{
|
||||||
|
tail_bdd = recurse(f);
|
||||||
|
tail_computed = true;
|
||||||
|
}
|
||||||
|
res_ |= label & tail_bdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the destination is not 0 or [*0], it means it
|
||||||
|
// can have successors. Fusion the tail.
|
||||||
|
if (dest != constant::false_instance()
|
||||||
|
&& dest != constant::empty_word_instance())
|
||||||
|
{
|
||||||
|
const formula* dest2 =
|
||||||
|
multop::instance(multop::Fusion, dest, f->clone());
|
||||||
|
if (dest2 != constant::false_instance())
|
||||||
|
{
|
||||||
|
int x = dict_.register_next_variable(dest2);
|
||||||
|
dest2->destroy();
|
||||||
|
res_ |= label & bdd_ithvar(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f->destroy();
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
SPOT_UNREACHABLE();
|
SPOT_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
@ -961,8 +1022,8 @@ namespace spot
|
||||||
// If the destination is not 0 or [*0], it means it
|
// If the destination is not 0 or [*0], it means it
|
||||||
// can have successors. Fusion the tail and append
|
// can have successors. Fusion the tail and append
|
||||||
// anything to concatenate.
|
// anything to concatenate.
|
||||||
if (dest->kind() != formula::Constant
|
if (dest != constant::false_instance()
|
||||||
|| dest == ltl::constant::true_instance())
|
&& dest != constant::empty_word_instance())
|
||||||
{
|
{
|
||||||
const formula* dest2 =
|
const formula* dest2 =
|
||||||
multop::instance(multop::Fusion, dest, tail->clone());
|
multop::instance(multop::Fusion, dest, tail->clone());
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,17 @@ grep 'states: 4$' stdout
|
||||||
../../bin/ltlfilt -f '{a[*];b[*]}' --equivalent-to 'a | b'
|
../../bin/ltlfilt -f '{a[*];b[*]}' --equivalent-to 'a | b'
|
||||||
../../bin/ltlfilt -r -f '{a[*];b[*]}' --equivalent-to 'a | b'
|
../../bin/ltlfilt -r -f '{a[*];b[*]}' --equivalent-to 'a | b'
|
||||||
|
|
||||||
|
|
||||||
|
# A couple of tests for the [:*i..j] operator
|
||||||
|
../../bin/ltlfilt -q -f '{{a;b}[:*1..2];c}' \
|
||||||
|
--equivalent-to '(a&X(b&Xc)) | a&(X(b&a&X(b&Xc)))'
|
||||||
|
../../bin/ltlfilt -q -r -f '{{a;b}[:*1..2];c}' \
|
||||||
|
--equivalent-to '(a&X(b&Xc)) | a&(X(b&a&X(b&Xc)))'
|
||||||
|
../../bin/ltlfilt -q -f '{{a*}[:+];c}' --equivalent-to 'Xc R a'
|
||||||
|
../../bin/ltlfilt -q -r -f '{{a*}[:+];c}' --equivalent-to 'Xc R a'
|
||||||
|
../../bin/ltlfilt -q -f '{c && {b | [*0]}[:+]}' --equivalent-to 'c & b'
|
||||||
|
../../bin/ltlfilt -q -r -f '{c && {b | [*0]}[:+]}' --equivalent-to 'c & b'
|
||||||
|
|
||||||
# test unknown dot options
|
# test unknown dot options
|
||||||
../../bin/ltl2tgba --dot=@ a 2>stderr && exit 1
|
../../bin/ltl2tgba --dot=@ a 2>stderr && exit 1
|
||||||
grep 'ltl2tgba: unknown option.*@' stderr
|
grep 'ltl2tgba: unknown option.*@' stderr
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue