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

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.
parent eebbcac2
...@@ -67,7 +67,14 @@ New in spot 1.99a (not yet released) ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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. ...@@ -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. ...@@ -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. ...@@ -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. ...@@ -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. ...@@ -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. ...@@ -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
......
// -*- 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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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;
......
// -*- 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 ...@@ -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 ...@@ -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
......
// -*- 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),