diff --git a/NEWS b/NEWS index ca0f9904c..b34463943 100644 --- a/NEWS +++ b/NEWS @@ -93,6 +93,10 @@ New in spot 2.3.3.dev (not yet released) - ltldo and ltlcross could leave temporary files behind when aborting on error. + - The LTL simplifcation rule that turns F(f)|q into F(f|q) + when q is a subformula that is both eventual and universal + was documented but not applied in some forgotten cases. + Backward-incompatible changes: - spot::acc_cond::mark_t::operator bool() has been marked as diff --git a/spot/tl/simplify.cc b/spot/tl/simplify.cc index af5b2e225..3c03666fe 100644 --- a/spot/tl/simplify.cc +++ b/spot/tl/simplify.cc @@ -1,6 +1,6 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016 Laboratoire de -// Recherche et Developpement de l'Epita (LRDE). +// Copyright (C) 2011-2017 Laboratoire de Recherche et Developpement +// de l'Epita (LRDE). // // This file is part of Spot, a model checking library. // @@ -698,7 +698,7 @@ namespace spot { bool e = f.is_eventual(); bool u = f.is_universal(); - bool eu = res_EventUniv && e & u && c_->options.favor_event_univ; + bool eu = res_EventUniv && e & u && c_->options.event_univ; switch (f.kind()) { case op::X: @@ -2137,30 +2137,24 @@ namespace spot vec eu; bool seen_g = false; for (auto f: *s.res_EventUniv) - { - if (f.is_eventual() && f.is_universal()) - { - if (f.is(op::G)) - { - seen_g = true; - eu.emplace_back(f[0]); - } - else - { - eu.emplace_back(f); - } - } - else - { - s.res_other->emplace_back(f); - } - } + if (f.is(op::G)) + { + seen_g = true; + eu.emplace_back(f[0]); + } + else + { + eu.emplace_back(f); + } if (seen_g) { eu.emplace_back(allFG); allFG = nullptr; - s.res_other->emplace_back(unop_multop(op::G, op::And, - eu)); + formula andeu = formula::multop(op::And, eu); + if (!opt_.favor_event_univ) + s.res_G->emplace_back(andeu); + else + s.res_other->emplace_back(formula::G(andeu)); } else { @@ -2673,6 +2667,11 @@ namespace spot formula allGF = unop_unop_multop(op::G, op::F, op::Or, std::move(*s.res_GF)); + bool eu_has_F = false; + for (auto f: *s.res_EventUniv) + if (f.is(op::F)) + eu_has_F = true; + // Xa | Xb = X(a | b) // Xa | Xb | GF(c) = X(a | b | GF(c)) // For Universal&Eventual formula f1...fn we also have: @@ -2686,7 +2685,7 @@ namespace spot s.res_EventUniv->end()); } else if (!opt_.favor_event_univ - && !s.res_F->empty() + && (!s.res_F->empty() || eu_has_F) && s.res_G->empty() && s.res_U_or_W->empty() && s.res_R_or_M->empty() @@ -2715,9 +2714,8 @@ namespace spot // these differences) s.res_F->emplace_back(allGF); allGF = nullptr; - s.res_F->insert(s.res_F->end(), - s.res_EventUniv->begin(), - s.res_EventUniv->end()); + for (auto f: *s.res_EventUniv) + s.res_F->emplace_back(f.is(op::F) ? f[0] : f); } else if (opt_.favor_event_univ) { @@ -2726,7 +2724,7 @@ namespace spot bool seen_f = false; if (s.res_EventUniv->size() > 1) { - // If some of the EventUniv formulae start + // If some of the EventUniv formulas start // with an F, Gather them all under the // same F. Striping any leading F. for (auto& f: *s.res_EventUniv) @@ -2750,9 +2748,13 @@ namespace spot } else { - s.res_other->insert(s.res_other->end(), - s.res_EventUniv->begin(), - s.res_EventUniv->end()); + for (auto f: *s.res_EventUniv) + { + if (f.is(op::F)) + s.res_F->emplace_back(f[0]); + else + s.res_other->emplace_back(f); + } } // Xa | Xb | f1...fn = X(a | b | f1...fn) // is built at the end of this multop::Or case. diff --git a/tests/core/ltl2tgba2.test b/tests/core/ltl2tgba2.test index 82fa422fe..c9bd08a22 100755 --- a/tests/core/ltl2tgba2.test +++ b/tests/core/ltl2tgba2.test @@ -272,7 +272,7 @@ p-patterns,20, 1,8, 1,8, 3,24, 3,24 !sb-patterns,5, 2,7, 2,7, 3,12, 3,12 !sb-patterns,6, 3,11, 4,14, 3,11, 4,14 !sb-patterns,7, 4,16, 4,16, 4,16, 4,16 -!sb-patterns,9, 4,19, 4,19, 6,27, 6,27 +!sb-patterns,9, 3,13, 3,13, 5,21, 5,21 !sb-patterns,10, 2,6, 2,6, 2,6, 2,6 !sb-patterns,11, 1,0, 1,0, 1,0, 1,0 !sb-patterns,12, 1,0, 1,0, 1,0, 1,0 diff --git a/tests/core/reduccmp.test b/tests/core/reduccmp.test index 7188a79ea..74308ecba 100755 --- a/tests/core/reduccmp.test +++ b/tests/core/reduccmp.test @@ -1,7 +1,7 @@ #! /bin/sh # -*- coding: utf-8 -*- -# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Laboratoire de -# Recherche et Developpement de l'Epita (LRDE). +# Copyright (C) 2009-2014, 2016-2017 Laboratoire de Recherche et +# Developpement de l'Epita (LRDE). # Copyright (C) 2004, 2006 Laboratoire d'Informatique de Paris 6 (LIP6), # département Systèmes Répartis Coopératifs (SRC), Université Pierre # et Marie Curie. @@ -179,7 +179,8 @@ G(a | GFb), Ga | GFb F(a & GFb & c), F(a & GFb & c) G(a | GFb | c), G(a | c) | GFb -GFa <=> GFb, G(Fa&Fb)|FG(!a&!b) +GFa <=> GFb, F(G(Fa&Fb)|G(!a&!b)) +FGa | (GFa & GFb), F(Ga | (G(Fa & Fb))) Gb W a, Gb|a Fb M Fa, Fa & Fb diff --git a/tests/python/atva16-fig2a.ipynb b/tests/python/atva16-fig2a.ipynb index 8e2b789aa..6fa7be833 100644 --- a/tests/python/atva16-fig2a.ipynb +++ b/tests/python/atva16-fig2a.ipynb @@ -15,7 +15,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2rc1" + "version": "3.5.3" }, "name": "" }, @@ -86,113 +86,96 @@ "\n", "\n", - "\n", - "\n", + "\n", + "\n", "G\n", - "\n", - "Inf(\n", - "\u24ff\n", - ")&Inf(\n", - "\u2776\n", - ")\n", + "\n", + "Inf(\n", + "\u24ff\n", + ")&Inf(\n", + "\u2776\n", + ")\n", "\n", - "\n", - "0\n", - "\n", - "0\n", - "\n", - "\n", - "I->0\n", - "\n", - "\n", - "\n", "\n", - "1\n", - "\n", - "1\n", + "1\n", + "\n", + "1\n", "\n", - "\n", - "0->1\n", - "\n", - "\n", - "1\n", + "\n", + "I->1\n", + "\n", + "\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "1->0\n", + "\n", + "\n", + "!a & !b\n", "\n", "\n", "2\n", - "\n", - "2\n", + "\n", + "2\n", "\n", - "\n", - "0->2\n", - "\n", - "\n", - "!a & !b\n", + "\n", + "1->2\n", + "\n", + "\n", + "a | b\n", "\n", - "\n", - "3\n", - "\n", - "3\n", + "\n", + "0->0\n", + "\n", + "\n", + "!a & !b\n", + "\u24ff\n", + "\u2776\n", "\n", - "\n", - "0->3\n", - "\n", - "\n", - "1\n", + "\n", + "2->2\n", + "\n", + "\n", + "!a & b\n", + "\u2776\n", "\n", - "\n", - "1->1\n", - "\n", - "\n", - "!a & b\n", - "\u2776\n", + "\n", + "2->2\n", + "\n", + "\n", + "!a & !b\n", "\n", - "\n", - "1->1\n", - "\n", - "\n", - "!a & !b\n", - "\n", - "\n", - "1->1\n", - "\n", - "\n", - "a & b\n", - "\u24ff\n", - "\u2776\n", - "\n", - "\n", - "1->1\n", - "\n", - "\n", - "a & !b\n", - "\u24ff\n", + "\n", + "2->2\n", + "\n", + "\n", + "a & b\n", + "\u24ff\n", + "\u2776\n", "\n", "\n", "2->2\n", - "\n", - "\n", - "!a & !b\n", - "\u24ff\n", - "\u2776\n", - "\n", - "\n", - "3->2\n", - "\n", - "\n", - "!a & !b\n", - "\n", - "\n", - "3->3\n", - "\n", - "\n", - "1\n", + "\n", + "\n", + "a & !b\n", + "\u24ff\n", "\n", "\n", "\n" ], "text": [ - " *' at 0x7f77f87ba300> >" + " *' at 0x7f79506d2900> >" ] } ],