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

Merge branch 'master' into next

Conflicts:
	src/ltlvisit/simplify.cc
	src/tgbatest/Makefile.am
parents 2a155593 f431852a
...@@ -12,7 +12,7 @@ Guillaume Sadegh ...@@ -12,7 +12,7 @@ Guillaume Sadegh
Heikki Tauriainen Heikki Tauriainen
Pierre Parutto Pierre Parutto
Rachid Rebiha Rachid Rebiha
Soheib Baarir Souheib Baarir
Thomas Badie Thomas Badie
Thomas Martinez Thomas Martinez
Tomáš Babiak Tomáš Babiak
New in spot 1.2.3a (not yet released) New in spot 1.2.4a (not yet released)
* Major changes (including backward incompatible changes): * Major changes (including backward incompatible changes):
...@@ -69,6 +69,30 @@ New in spot 1.2.3a (not yet released) ...@@ -69,6 +69,30 @@ New in spot 1.2.3a (not yet released)
implementation of Couvreur's FM'99 emptiness check. implementation of Couvreur's FM'99 emptiness check.
New in spot 1.2.4 (2014-05-15)
* New features:
- "-B -x degen-lskip" can be used to disable level-skipping in the
degeralization procedure called by ltl2tgba and dstar2tgba.
This is mostly meant for running experiments.
- "-B -x degen-lcache=N" can be used to experiment with different
type of level caching during degeneralization.
* Bug fixes:
- Change the Python bindings to make them compatible with Swig 3.0.
- "ltl2tgta --ta" could crash in certain conditions due to the
introduction of a simulation-based reduction after
degeneralization.
- Fix four incorrect formula-simplification rules, three were
related to the factorization of Boolean subformulas in
operands of the non-length-matching "&" SERE operator, and
a fourth one could only be enabled by explicitely passing the
favor_event_univ option to the simplifier (not the default).
- Fix incorrect translation of the fusion operator (":") in SERE
such as {xx;1}:yy[*] where the left operand has 1 as tail.
New in spot 1.2.3 (2014-02-11) New in spot 1.2.3 (2014-02-11)
* New features: * New features:
...@@ -100,8 +124,8 @@ New in spot 1.2.3 (2014-02-11) ...@@ -100,8 +124,8 @@ New in spot 1.2.3 (2014-02-11)
- Fix determinism of the SAT-based minimization encoding. - Fix determinism of the SAT-based minimization encoding.
(It would sometimes produce different equivalent automata, (It would sometimes produce different equivalent automata,
because of a different encoding order.) because of a different encoding order.)
- A the SAT-based minimization is asked for a 10-state automaton - If the SAT-based minimization is asked for a 10-state automaton
and return a 6-state automaton, do not ask for a 9-state and returns a 6-state automaton, do not ask for a 9-state
automaton in the next iteration... automaton in the next iteration...
- Fix some compilation issue with the version of Apple's Clang - Fix some compilation issue with the version of Apple's Clang
that is installed with MacOS X 10.9. that is installed with MacOS X 10.9.
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ([2.61]) AC_PREREQ([2.61])
AC_INIT([spot], [1.2.3a], [spot@lrde.epita.fr]) AC_INIT([spot], [1.2.4a], [spot@lrde.epita.fr])
AC_CONFIG_AUX_DIR([tools]) AC_CONFIG_AUX_DIR([tools])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([1.11 gnu tar-ustar color-tests parallel-tests]) AM_INIT_AUTOMAKE([1.11 gnu tar-ustar color-tests parallel-tests])
......
...@@ -31,8 +31,10 @@ Let us first state a few facts about this minimization procedure. ...@@ -31,8 +31,10 @@ Let us first state a few facts about this minimization procedure.
automaton: when the number of clauses output by Spot (and to be fed automaton: when the number of clauses output by Spot (and to be fed
to the SAT solver) exceeds $2^{31}$, or when the SAT-solver was to the SAT solver) exceeds $2^{31}$, or when the SAT-solver was
killed by a signal. killed by a signal.
6) Details about the SAT encoding used in the two procedures can be
found in our [[http://www.lrde.epita.fr/~adl/dl/adl/baarir.14.forte.pdf][FORTE'14 paper]].
* How change the SAT solver used * How to change the SAT solver used
The environment variable =SPOT_SATSOLVER= can be used to change the The environment variable =SPOT_SATSOLVER= can be used to change the
SAT solver used by Spot. The default is "=glucose -verb=0 -model %I SAT solver used by Spot. The default is "=glucose -verb=0 -model %I
......
#+TITLE: Command-line tools installed by Spot 1.2.3 #+TITLE: Command-line tools installed by Spot 1.2.4
#+EMAIL spot@lrde.epita.fr #+EMAIL spot@lrde.epita.fr
#+OPTIONS: H:2 num:nil toc:t #+OPTIONS: H:2 num:nil toc:t
...@@ -60,9 +60,9 @@ the following articles: ...@@ -60,9 +60,9 @@ the following articles:
This focuses on =ltlfilt=, =randltl=, and =ltlcross=. This focuses on =ltlfilt=, =randltl=, and =ltlcross=.
- *LTL translation improvements in Spot*, /Alexandre Duret-Lutz/. - *LTL translation improvements in Spot 1.0*, /Alexandre Duret-Lutz/.
In Proc. of VECoS'11. Electronic Workshops in Computing. Tunis, Tunisia, Sep. 2011. Int. J. on Critical Computer-Based Systems, 5(1/2):31--54, March 2014.
([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.11.vecos][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.11.vecos.pdf][pdf]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.11.vecos.slides.pdf][slides]]) ([[https://www.lrde.epita.fr/~adl/dl/adl_bib.html#duret.14.ijccbs][bib]] | [[https://www.lrde.epita.fr/~adl/dl/adl/duret.14.ijccbs.draft.pdf][pdf]])
This describes the translation from LTL to TGBA used by =ltl2tgba= This describes the translation from LTL to TGBA used by =ltl2tgba=
and =ltl2tgta=. and =ltl2tgta=.
......
...@@ -1460,13 +1460,11 @@ SERE. ...@@ -1460,13 +1460,11 @@ SERE.
\0 &\text{else}\\ \0 &\text{else}\\
\end{cases}\\ \end{cases}\\
\sere{b_1\CONCAT r_1}\ANDALT\sere{b_2\CONCAT r_2} &\equiv \sere{b_1\ANDALT b_2}\CONCAT\sere{r_1\ANDALT r_2} & \sere{b_1\CONCAT r_1}\ANDALT\sere{b_2\CONCAT r_2} &\equiv \sere{b_1\ANDALT b_2}\CONCAT\sere{r_1\ANDALT r_2} &
\sere{b_1\CONCAT r_1}\AND \sere{b_2\CONCAT r_2} &\equiv \sere{b_1\ANDALT b_2}\CONCAT\sere{r_1\AND r_2} \\ \sere{r_1\CONCAT b_1}\ANDALT\sere{r_2\CONCAT b_2} &\equiv \sere{r_1\ANDALT r_2}\CONCAT\sere{b_1\ANDALT b_2} \\
\sere{b_1\FUSION r_1}\ANDALT\sere{b_2\FUSION r_2} &\equiv \sere{b_1\ANDALT b_2}\FUSION\sere{r_1\ANDALT r_2} & \sere{b_1\FUSION r_1}\ANDALT\sere{b_2\FUSION r_2} &\equiv \sere{b_1\ANDALT b_2}\FUSION\sere{r_1\ANDALT r_2} &
\sere{b_1\FUSION r_1}\AND \sere{b_2\FUSION r_2} &\equiv \sere{b_1\ANDALT b_2}\FUSION\sere{r_1\AND r_2} \\ \sere{r_1\FUSION b_1}\ANDALT\sere{r_2\FUSION b_2} &\equiv \sere{r_1\ANDALT r_2}\FUSION\sere{b_1\ANDALT b_2} \\
\sere{r_1\CONCAT b_1}\ANDALT\sere{r_2\CONCAT b_2} &\equiv \sere{r_1\ANDALT r_2}\CONCAT\sere{b_1\ANDALT b_2} & \sere{b_1\CONCAT r_1}\AND \sere{b_2\CONCAT r_2} &\equiv \sere{b_1\ANDALT b_2}\CONCAT\sere{r_1\AND r_2} \\
\sere{r_1\CONCAT b_1}\AND \sere{r_2\CONCAT b_2} &\equiv \sere{r_1\ANDALT r_2}\CONCAT\sere{b_1\AND b_2} \\ \sere{b_1\FUSION r_1}\AND \sere{b_2\FUSION r_2} &\equiv \sere{b_1\ANDALT b_2}\FUSION\sere{r_1\AND r_2} \mathrlap{\quad\text{if~}\varepsilon\nVDash r_1\land\varepsilon\nVDash r_2}\\
\sere{r_1\FUSION b_1}\ANDALT\sere{r_2\FUSION b_2} &\equiv \sere{r_1\ANDALT r_2}\FUSION\sere{b_1\ANDALT b_2} &
\sere{r_1\FUSION b_1}\AND \sere{r_2\FUSION b_2} &\equiv \sere{r_1\ANDALT r_2}\FUSION\sere{b_1\AND b_2} \\
\end{align*} \end{align*}
Starred subformul\ae{} are rewritten in Star Normal Starred subformul\ae{} are rewritten in Star Normal
...@@ -1582,7 +1580,6 @@ $q,\,q_i$ & a pure eventuality that is also purely universal \\ ...@@ -1582,7 +1580,6 @@ $q,\,q_i$ & a pure eventuality that is also purely universal \\
& & f \U (g\AND q) & \equivEU (f \U g)\AND q & (f\AND q)\M g & \equivEU (f \M g)\AND q \\ & & f \U (g\AND q) & \equivEU (f \U g)\AND q & (f\AND q)\M g & \equivEU (f \M g)\AND q \\
\G u & \equiv u & u \W g & \equiv u\OR g & f \R u & \equiv u & e_1 \W e_2 & \equiV (\G e_1) \OR e_2 \\ \G u & \equiv u & u \W g & \equiv u\OR g & f \R u & \equiv u & e_1 \W e_2 & \equiV (\G e_1) \OR e_2 \\
\G(e)\AND q & \equiv \G(e\AND q) & f \W (g\OR e) & \equivEU (f \W g)\OR e & f\R (g\AND u) & \equivEU (f \R g)\AND u \\ \G(e)\AND q & \equiv \G(e\AND q) & f \W (g\OR e) & \equivEU (f \W g)\OR e & f\R (g\AND u) & \equivEU (f \R g)\AND u \\
& & (f\OR u) \W g & \equivEU (f \W g)\OR u \\
\X q & \equiv q & q \AND \X f & \equivNeu \X(q \AND f) & q\OR \X f & \equivNeu \X(q \OR f) \\ \X q & \equiv q & q \AND \X f & \equivNeu \X(q \AND f) & q\OR \X f & \equivNeu \X(q \OR f) \\
& & \X(q \AND f) & \equivEU q \AND \X f & \X(q \OR f) & \equivEU q\OR \X f \\ & & \X(q \AND f) & \equivEU q \AND \X f & \X(q \OR f) & \equivEU q\OR \X f \\
\end{align*} \end{align*}
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
dstar2tgba \- convert Rabin or Streett automata into Büchi automata dstar2tgba \- convert Rabin or Streett automata into Büchi automata
[BIBLIOGRAPHY] [BIBLIOGRAPHY]
.TP .TP
1. 1.
<http://www.ltl2dstar.de/docs/ltl2dstar.html> <http://www.ltl2dstar.de/docs/ltl2dstar.html>
Documents the output format of ltl2dstar. Documents the output format of ltl2dstar.
...@@ -28,5 +28,15 @@ dstar2tgba implements this for the Rabin case only. In other words, ...@@ -28,5 +28,15 @@ dstar2tgba implements this for the Rabin case only. In other words,
translating a deterministic Rabin automaton with dstar2tgba will translating a deterministic Rabin automaton with dstar2tgba will
produce a deterministic TGBA or BA if such a automaton exists. produce a deterministic TGBA or BA if such a automaton exists.
.TP
4.
Souheib Baarir and Alexandre Duret-Lutz: Mechanizing the minimization
of deterministic generalized Büchi automata. Proceedings of FORTE'14.
LNCS 8461.
Explains the SAT-based minimization techniques that can be used (on
request only) by dstar2tgba to minimize deterministic Büchi automata.
[SEE ALSO] [SEE ALSO]
.BR spot-x (7) .BR spot-x (7)
...@@ -85,11 +85,22 @@ If you would like to give a reference to this tool in an article, ...@@ -85,11 +85,22 @@ If you would like to give a reference to this tool in an article,
we suggest you cite one of the following papers: we suggest you cite one of the following papers:
.TP .TP
\(bu \(bu
Alexandre Duret-Lutz: LTL translation improvements in Spot. Proceedings of VECoS'11. Alexandre Duret-Lutz: LTL translation improvements in Spot 1.0.
Int. J. on Critical Computer-Based Systems, 5(1/2):31--54, March 2014.
.TP .TP
\(bu \(bu
Alexandre Duret-Lutz: Manipulating LTL formulas using Spot 1.0. Alexandre Duret-Lutz: Manipulating LTL formulas using Spot 1.0.
Proceedings of ATVA'13. LNCS 8172. Proceedings of ATVA'13. LNCS 8172.
.TP
\(bu
Tomáš Babiak, Thomas Badie, Alexandre Duret-Lutz, Mojmír Křetínský,
and Jan Strejček: Compositional approach to suspension and other
improvements to LTL translation. Proceedings of SPIN'13. LNCS 7976.
.TP
\(bu
Souheib Baarir and Alexandre Duret-Lutz: Mechanizing the minimization
of deterministic generalized Büchi automata. Proceedings of FORTE'14.
LNCS 8461.
[SEE ALSO] [SEE ALSO]
.BR spot-x (7) .BR spot-x (7)
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013 Laboratoire de Recherche et Développement // Copyright (C) 2013, 2014 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.
...@@ -70,10 +69,20 @@ a non-accepting SCC.") }, ...@@ -70,10 +69,20 @@ a non-accepting SCC.") },
{ DOC("degen-lcache", "If non-zero (the default), whenever the \ { DOC("degen-lcache", "If non-zero (the default), whenever the \
degeneralization algorithm enters an SCC on a state that has already \ degeneralization algorithm enters an SCC on a state that has already \
been associated to a level elsewhere, it should reuse that level. \ been associated to a level elsewhere, it should reuse that level. \
The \"lcache\" stands for \"level cache\".") }, Different values can be used to select which level to reuse: 1 always \
uses the first level seen, 2 uses the minimum level seen so far, and \
3 uses the maximum level seen so far. The \"lcache\" stands for \
\"level cache\".") },
{ DOC("degen-order", "If non-zero, the degeneralization algorithm \ { DOC("degen-order", "If non-zero, the degeneralization algorithm \
will compute one degeneralization order for each SCC it processes. \ will compute one degeneralization order for each SCC it processes. \
This is currently disabled by default.") }, This is currently disabled by default.") },
{ DOC("degen-lskip", "If non-zero (the default), the degeneralization \
algorithm will skip as much levels as possible for each transition. This \
is enabled by default as it very often reduce the number of resulting \
states. A consequence of skipping levels is that the degeneralized \
automaton tends to have smaller cycles around the accepting states. \
Disabling skipping will produce automata with large cycles, and often \
with more states.") },
{ DOC("simul", "Set to 0 to disable simulation-based reductions. \ { DOC("simul", "Set to 0 to disable simulation-based reductions. \
Set to 1 to use only direct simulation. Set to 2 to use only reverse \ Set to 1 to use only direct simulation. Set to 2 to use only reverse \
simulation. Set to 3 to iterate both direct and reverse simulations. \ simulation. Set to 3 to iterate both direct and reverse simulations. \
......
...@@ -140,7 +140,7 @@ namespace spot ...@@ -140,7 +140,7 @@ namespace spot
/// \brief construct a formula without the nth child. /// \brief construct a formula without the nth child.
/// ///
/// If the formula \c f is <code>a|b|c|d</code> and <code>d</code> /// If the formula \c f is <code>a|b|c|d</code> and <code>c</code>
/// is child number 2, then calling <code>f->all_but(2)</code> will /// is child number 2, then calling <code>f->all_but(2)</code> will
/// return a new formula <code>a|b|d</code>. /// return a new formula <code>a|b|d</code>.
const formula* all_but(unsigned n) const; const formula* all_but(unsigned n) const;
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2008, 2009, 2010, 2011, 2012 Laboratoire de Recherche // Copyright (C) 2008, 2009, 2010, 2011, 2012, 2014 Laboratoire de
// et Développement de l'Epita (LRDE). // Recherche et Développement de l'Epita (LRDE).
// Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de // Copyright (C) 2003, 2004, 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.
...@@ -68,7 +68,7 @@ main(int argc, char** argv) ...@@ -68,7 +68,7 @@ main(int argc, char** argv)
if (spot::ltl::format_parse_errors(std::cerr, argv[2], p2)) if (spot::ltl::format_parse_errors(std::cerr, argv[2], p2))
return 2; return 2;
int exit_code; int exit_code = 0;
{ {
#if defined LUNABBREV || defined TUNABBREV || defined NENOFORM || defined WM #if defined LUNABBREV || defined TUNABBREV || defined NENOFORM || defined WM
...@@ -112,6 +112,14 @@ main(int argc, char** argv) ...@@ -112,6 +112,14 @@ main(int argc, char** argv)
const spot::ltl::formula* tmp; const spot::ltl::formula* tmp;
tmp = f1; tmp = f1;
f1 = simp.simplify(f1); f1 = simp.simplify(f1);
if (!simp.are_equivalent(f1, tmp))
{
std::cerr << "Source and simplified formulae are not equivalent!\n";
std::cerr << "Simplified: " << spot::ltl::to_string(f1) << "\n";
exit_code = 1;
}
tmp->destroy(); tmp->destroy();
} }
spot::ltl::dump(std::cout, f1); spot::ltl::dump(std::cout, f1);
...@@ -124,6 +132,14 @@ main(int argc, char** argv) ...@@ -124,6 +132,14 @@ main(int argc, char** argv)
const spot::ltl::formula* tmp; const spot::ltl::formula* tmp;
tmp = f1; tmp = f1;
f1 = simp.simplify(f1); f1 = simp.simplify(f1);
if (!simp.are_equivalent(f1, tmp))
{
std::cerr << "Source and simplified formulae are not equivalent!\n";
std::cerr << "Simplified: " << spot::ltl::to_string(f1) << "\n";
exit_code = 1;
}
tmp->destroy(); tmp->destroy();
} }
spot::ltl::dump(std::cout, f1); spot::ltl::dump(std::cout, f1);
...@@ -136,13 +152,21 @@ main(int argc, char** argv) ...@@ -136,13 +152,21 @@ main(int argc, char** argv)
const spot::ltl::formula* tmp; const spot::ltl::formula* tmp;
tmp = f1; tmp = f1;
f1 = simp.simplify(f1); f1 = simp.simplify(f1);
if (!simp.are_equivalent(f1, tmp))
{
std::cerr << "Source and simplified formulae are not equivalent!\n";
std::cerr << "Simplified: " << spot::ltl::to_string(f1) << "\n";
exit_code = 1;
}
tmp->destroy(); tmp->destroy();
} }
spot::ltl::dump(std::cout, f1); spot::ltl::dump(std::cout, f1);
std::cout << std::endl; std::cout << std::endl;
#endif #endif
exit_code = f1 != f2; exit_code |= f1 != f2;
#if (!defined(REDUC) && !defined(REDUC_TAU) && !defined(REDUC_TAUSTR)) #if (!defined(REDUC) && !defined(REDUC_TAU) && !defined(REDUC_TAUSTR))
spot::ltl::ltl_simplifier simp; spot::ltl::ltl_simplifier simp;
...@@ -150,8 +174,11 @@ main(int argc, char** argv) ...@@ -150,8 +174,11 @@ main(int argc, char** argv)
if (!simp.are_equivalent(f1, f2)) if (!simp.are_equivalent(f1, f2))
{ {
std::cerr << "Source and destination formulae are not equivalent!" #if (!defined(REDUC) && !defined(REDUC_TAU) && !defined(REDUC_TAUSTR))
<< std::endl; std::cerr << "Source and destination formulae are not equivalent!\n";
#else
std::cerr << "Simpl. and destination formulae are not equivalent!\n";
#endif
exit_code = 1; exit_code = 1;
} }
......
#! /bin/sh #! /bin/sh
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2012, 2013 Laboratoire de Recherche et Developpement # Copyright (C) 2012, 2013, 2014 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.
# #
...@@ -48,7 +48,7 @@ check 'a U (b | Fc)' '(a U b) | Fc' ...@@ -48,7 +48,7 @@ check 'a U (b | Fc)' '(a U b) | Fc'
check 'a W (b | Fc)' '(a W b) | Fc' check 'a W (b | Fc)' '(a W b) | Fc'
check 'a U (b & GFc)' '(a U b) & GFc' check 'a U (b & GFc)' '(a U b) & GFc'
check 'a W (b & GFc)' 'a W (b & GFc)' # Unchanged check 'a W (b & GFc)' 'a W (b & GFc)' # Unchanged
check '(a | Gc) W g' '(a W g) | Gc' check '(a | Gc) W g' '(a | Gc) W g' # Unchanged
check '(a | Gc) U g' '(a | Gc) U g' # Unchanged check '(a | Gc) U g' '(a | Gc) U g' # Unchanged
check '(a & GFc) M b' '(a M b) & GFc' check '(a & GFc) M b' '(a M b) & GFc'
......
#! /bin/sh #! /bin/sh
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2009, 2010, 2011, 2012, 2013 Laboratoire de Recherche # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
# et Developpement de l'Epita (LRDE). # Recherche et Developpement de l'Epita (LRDE).
# Copyright (C) 2004, 2006 Laboratoire d'Informatique de Paris 6 (LIP6), # Copyright (C) 2004, 2006 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.
...@@ -317,9 +317,10 @@ for x in ../reduccmp ../reductaustr; do ...@@ -317,9 +317,10 @@ for x in ../reduccmp ../reductaustr; do
run 0 $x '{{a;b*;c}&&{d;e*}&&{f*;g}&&{h*}}' \ run 0 $x '{{a;b*;c}&&{d;e*}&&{f*;g}&&{h*}}' \
'{{f*;g}&&{h*}&&{{a&&d};{e* && {b*;c}}}}' '{{f*;g}&&{h*}&&{{a&&d};{e* && {b*;c}}}}'
run 0 $x '{{{b1;r1*}&{b2;r2*}};c}' 'b1&b2&X{{r1*&r2*};c}' run 0 $x '{{{b1;r1*}&{b2;r2*}};c}' 'b1&b2&X{{r1*&r2*};c}'
run 0 $x '{{b1:r1*}&{b2:r2*}}' '{{b1&&b2}:{r1*&r2*}}' run 0 $x '{{b1:(r1;x1*)}&{b2:(r2;x2*)}}' '{{b1&&b2}:{{r1&&r2};{x1*&x2*}}}'
run 0 $x '{{r1*;b1}&{r2*;b2}}' '{{r1*&r2*};{b1&&b2}}' run 0 $x '{{b1:r1*}&{b2:r2*}}' '{{b1:r1*}&{b2:r2*}}' # Not reduced
run 0 $x '{{r1*:b1}&{r2*:b2}}' '{{r1*&r2*}:{b1&&b2}}' run 0 $x '{{r1*;b1}&{r2*;b2}}' '{{r1*;b1}&{r2*;b2}}' # Not reduced
run 0 $x '{{r1*:b1}&{r2*:b2}}' '{{r1*:b1}&{r2*:b2}}' # Not reduced
run 0 $x '{{a;b*;c}&{d;e*}&{f*;g}&{h*}}' \ run 0 $x '{{a;b*;c}&{d;e*}&{f*;g}&{h*}}' \
'{{f*;g}&{h*}&{{a&&d};{e* & {b*;c}}}}' '{{f*;g}&{h*}&{{a&&d};{e* & {b*;c}}}}'
run 0 $x '{a;(b*;c*;([*0]+{d;e}))*}!' '{a;{b|c|{d;e}}*}!' run 0 $x '{a;(b*;c*;([*0]+{d;e}))*}!' '{a;{b|c|{d;e}}*}!'
...@@ -347,6 +348,8 @@ for x in ../reduccmp ../reductaustr; do ...@@ -347,6 +348,8 @@ for x in ../reduccmp ../reductaustr; do
run 0 $x '{s[*]}<>->b' 'b M s' run 0 $x '{s[*]}<>->b' 'b M s'
run 0 $x '{s[+]}<>->b' 'b M s' run 0 $x '{s[+]}<>->b' 'b M s'
run 0 $x '{s[*2..]}<>->b' 's & X(b M s)' run 0 $x '{s[*2..]}<>->b' 's & X(b M s)'
run 0 $x '{1:a*}!' 'a'
run 0 $x '{(1;1):a*}!' 'Xa'
run 0 $x '{a;b*;c;d*}<>->e' 'a & X(b U (c & (e | X(e M d))))' run 0 $x '{a;b*;c;d*}<>->e' 'a & X(b U (c & (e | X(e M d))))'
run 0 $x '{a:b*:c:d*}<>->e' 'a & ((c & (e M d)) M b)' run 0 $x '{a:b*:c:d*}<>->e' 'a & ((c & (e M d)) M b)'
run 0 $x '{a|b*|c|d*}<>->e' '((a | c) & e) | (e M b) | (e M d)' run 0 $x '{a|b*|c|d*}<>->e' '((a | c) & e) | (e M b) | (e M d)'
......
...@@ -2068,7 +2068,6 @@ namespace spot ...@@ -2068,7 +2068,6 @@ namespace spot
// (a W (b|e)) = (a W b)|e // (a W (b|e)) = (a W b)|e
// (a U (b&q)) = (a U b)&q // (a U (b&q)) = (a U b)&q
// ((a&q) M b) = (a M b)&q // ((a&q) M b) = (a M b)&q
// ((a|u) W b) = u|(a W b)
// (a R (b&u)) = (a R b)&u // (a R (b&u)) = (a R b)&u
// (a M (b&u)) = (a M b)&u // (a M (b&u)) = (a M b)&u
if (opt_.favor_event_univ) if (opt_.favor_event_univ)
...@@ -2092,24 +2091,6 @@ namespace spot ...@@ -2092,24 +2091,6 @@ namespace spot
b2->destroy(); b2->destroy();
delete s.res_Event; delete s.res_Event;
} }
if (op == binop::W)
if (const multop* mo = is_Or(a))
{
a->clone();
mospliter s(mospliter::Split_Univ, mo, c_);
const formula* a2 =
multop::instance(multop::Or, s.res_other);
if (a2 != a)
{
a->destroy();
s.res_Univ->push_back(binop::instance(op, a2, b));
result_ = recurse_destroy
(multop::instance(multop::Or, s.res_Univ));
return;
}
a2->destroy();
delete s.res_Univ;
}
if (op == binop::U) if (op == binop::U)
if (const multop* mo = is_And(b)) if (const multop* mo = is_And(b))
{ {
...@@ -3438,22 +3419,14 @@ namespace spot ...@@ -3438,22 +3419,14 @@ namespace spot
if (op == multop::Concat) if (op == multop::Concat)
{ {
head1->push_back(h->clone()); head1->push_back(h->clone());
multop::vec* tail = new multop::vec; tail1->push_back(f->all_but(0));
unsigned s = f->size();
for (unsigned j = 1; j < s; ++j)
tail->push_back(f->nth(j)->clone());
tail1->push_back(multop::instance(op, tail));
i->destroy(); i->destroy();
i = 0; i = 0;
} }
else if (op == multop::Fusion) else if (op == multop::Fusion)
{ {
head2->push_back(h->clone()); head2->push_back(h->clone());
multop::vec* tail = new multop::vec; tail2->push_back(f->all_but(0));
unsigned s = f->size();
for (unsigned j = 1; j < s; ++j)
tail->push_back(f->nth(j)->clone());
tail2->push_back(multop::instance(op, tail));
i->destroy(); i->destroy();
i = 0; i = 0;
} }
...@@ -3516,20 +3489,14 @@ namespace spot ...@@ -3516,20 +3489,14 @@ namespace spot
if (op == multop::Concat) if (op == multop::Concat)
{ {
tail3->push_back(t->clone()); tail3->push_back(t->clone());
multop::vec* head = new multop::vec; head3->push_back(f->all_but(s));
for (unsigned j = 0; j < s; ++j)
head->push_back(f->nth(j)->clone());
head3->push_back(multop::instance(op, head));
i->destroy(); i->destroy();
i = 0; i = 0;
} }
else if (op == multop::Fusion) else if (op == multop::Fusion)
{ {
tail4->push_back(t->clone()); tail4->push_back(t->clone());
multop::vec* head = new multop::vec; head4->push_back(f->all_but(s));
for (unsigned j = 0; j < s; ++j)
head->push_back(f->nth(j)->clone());
head4->push_back(multop::instance(op, head));
i->destroy(); i->destroy();
i = 0; i = 0;
} }
...@@ -4127,6 +4094,8 @@ namespace spot ...@@ -4127,6 +4094,8 @@ namespace spot
// head1 tail1 // head1 tail1
// {b1:r1}&{b2:r2} = {b1∧b2}:{r1&r2} // {b1:r1}&{b2:r2} = {b1∧b2}:{r1&r2}
// head2 tail2 // head2 tail2
// BEWARE: The second rule is correct only when
// both r1 and r2 do not accept [*0].
multop::vec* head1 = new multop::vec; multop::vec* head1 = new multop::vec;
multop::vec* tail1 = new multop::vec; multop::vec* tail1 = new multop::vec;
...@@ -4146,22 +4115,20 @@ namespace spot ...@@ -4146,22 +4115,20 @@ namespace spot
if (op == multop::Concat) if (op == multop::Concat)
{ {
head1->push_back(h->clone()); head1->push_back(h->clone());
multop::vec* tail = new multop::vec; tail1->push_back(f->all_but(0));
unsigned s = f->size();
for (unsigned j = 1; j < s; ++j)
tail->push_back(f->nth(j)->clone());
tail1->push_back(multop::instance(op, tail));
i->destroy(); i->destroy();
i = 0; i = 0;
} }
else if (op == multop::Fusion) else if (op == multop::Fusion)
{