diff --git a/src/tgba/tgba.hh b/src/tgba/tgba.hh index e3d1541d0..88b6ca4b6 100644 --- a/src/tgba/tgba.hh +++ b/src/tgba/tgba.hh @@ -675,6 +675,7 @@ namespace spot bool state_based_acc:1; // State-based acceptance. bool inherently_weak:1; // Weak automaton. bool deterministic:1; // Deterministic automaton. + bool stutter_inv:1; // Stutter invariant }; union { @@ -757,16 +758,27 @@ namespace spot is.deterministic = val; } + bool is_stutter_invariant() const + { + return is.stutter_inv; + } + + void prop_stutter_invariant(bool val = true) + { + is.stutter_inv = val; + } + struct prop_set { bool state_based; bool single_acc; bool inherently_weak; bool deterministic; + bool stutter_inv; static prop_set all() { - return { true, true, true, true }; + return { true, true, true, true, true }; } }; @@ -782,6 +794,8 @@ namespace spot prop_inherently_weak(other->is_inherently_weak()); if (p.deterministic) prop_deterministic(other->is_deterministic()); + if (p.stutter_inv) + prop_stutter_invariant(other->is_stutter_invariant()); } void prop_keep(prop_set p) diff --git a/src/tgbaalgos/are_isomorphic.cc b/src/tgbaalgos/are_isomorphic.cc index 97b2d823b..5deafe8c0 100644 --- a/src/tgbaalgos/are_isomorphic.cc +++ b/src/tgbaalgos/are_isomorphic.cc @@ -112,7 +112,7 @@ namespace spot { isomorphism_checker::isomorphism_checker(const const_tgba_digraph_ptr ref) { - ref_ = make_tgba_digraph(ref, {true, true, true, true}); + ref_ = make_tgba_digraph(ref, tgba::prop_set::all()); ref_deterministic_ = ref_->is_deterministic(); if (!ref_deterministic_) { @@ -144,7 +144,7 @@ namespace spot } } - auto tmp = make_tgba_digraph(aut, {true, true, true, true}); + auto tmp = make_tgba_digraph(aut, tgba::prop_set::all()); spot::canonicalize(tmp); return *tmp == *ref_; } diff --git a/src/tgbaalgos/complete.cc b/src/tgbaalgos/complete.cc index 0d36c7d2e..e8d302e29 100644 --- a/src/tgbaalgos/complete.cc +++ b/src/tgbaalgos/complete.cc @@ -1,6 +1,6 @@ // -*- coding: utf-8 -*- -// Copyright (C) 2013, 2014 Laboratoire de Recherche et Développement -// de l'Epita. +// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et +// Développement de l'Epita. // // This file is part of Spot, a model checking library. // @@ -105,11 +105,12 @@ namespace spot tgba_digraph_ptr tgba_complete(const const_tgba_ptr& aut) { auto res = make_tgba_digraph(aut, { - true, // state based - true, // single acc - true, // inherently_weak - true, // deterministic - }); + true, // state based + true, // single acc + true, // inherently_weak + true, // deterministic + true, // stutter inv. + }); tgba_complete_here(res); return res; } diff --git a/src/tgbaalgos/degen.cc b/src/tgbaalgos/degen.cc index 881343d4f..e52013c85 100644 --- a/src/tgbaalgos/degen.cc +++ b/src/tgbaalgos/degen.cc @@ -204,8 +204,8 @@ namespace spot res->set_single_acceptance_set(); if (want_sba) res->prop_state_based_acc(); - // Preserve determinism and weakness - res->prop_copy(a, { false, false, true, true }); + // Preserve determinism, weakness, and stutter-invariance + res->prop_copy(a, { false, false, true, true, true }); // Create an order of acceptance conditions. Each entry in this // vector correspond to an acceptance set. Each index can diff --git a/src/tgbaalgos/dtgbacomp.cc b/src/tgbaalgos/dtgbacomp.cc index c732dbe8c..b90caecc0 100644 --- a/src/tgbaalgos/dtgbacomp.cc +++ b/src/tgbaalgos/dtgbacomp.cc @@ -32,6 +32,7 @@ namespace spot false, // single acc false, // inherently_weak false, // deterministic + true, // stutter inv. }); // Copy the old acceptance condition before we replace it. acc_cond oldacc = aut->acc(); // Copy it! @@ -120,6 +121,7 @@ namespace spot true, // single acc true, // inherently weak true, // determinisitic + true, // stutter inv. }); scc_info si(res); diff --git a/src/tgbaalgos/hoa.cc b/src/tgbaalgos/hoa.cc index 8adbbebb2..f9148e108 100644 --- a/src/tgbaalgos/hoa.cc +++ b/src/tgbaalgos/hoa.cc @@ -22,6 +22,7 @@ #include #include +#include #include #include "tgba/tgba.hh" #include "tgba/tgbagraph.hh" @@ -296,19 +297,41 @@ namespace spot os << aut->acc().get_acceptance(); os << nl; os << "properties:"; + + // Make sure the property line is not too large, + // otherwise our test cases do not fit in 80 columns... + unsigned prop_len = 60; + auto prop = [&](const char* str) + { + if (newline) + { + auto l = strlen(str); + if (prop_len < l) + { + prop_len = 60; + os << "\nproperties:"; + } + prop_len -= l; + } + os << str; + }; implicit_labels = md.use_implicit_labels; if (implicit_labels) - os << " implicit-labels"; + prop(" implicit-labels"); else - os << " trans-labels explicit-labels"; + prop(" trans-labels explicit-labels"); if (acceptance == Hoa_Acceptance_States) - os << " state-acc"; + prop(" state-acc"); else if (acceptance == Hoa_Acceptance_Transitions) - os << " trans-acc"; + prop(" trans-acc"); if (md.is_complete) - os << " complete"; + prop(" complete"); if (md.is_deterministic) - os << " deterministic"; + prop(" deterministic"); + if (aut->is_stutter_invariant()) + prop(" stutter-invariant"); + if (aut->is_inherently_weak()) + prop(" inherently-weak"); os << nl; // If we want to output implicit labels, we have to diff --git a/src/tgbaalgos/ltl2tgba_fm.cc b/src/tgbaalgos/ltl2tgba_fm.cc index cd0bebef3..de52301bb 100644 --- a/src/tgbaalgos/ltl2tgba_fm.cc +++ b/src/tgbaalgos/ltl2tgba_fm.cc @@ -2514,6 +2514,9 @@ namespace spot acc.set_generalized_buchi(); + a->prop_inherently_weak(f->is_syntactic_persistence()); + a->prop_stutter_invariant(f->is_syntactic_stutter_invariant()); + if (!simplifier) // This should not be deleted before we have registered all propositions. delete s; diff --git a/src/tgbaalgos/mask.cc b/src/tgbaalgos/mask.cc index 387ca59c4..5f2634788 100644 --- a/src/tgbaalgos/mask.cc +++ b/src/tgbaalgos/mask.cc @@ -26,7 +26,7 @@ namespace spot { auto res = make_tgba_digraph(in->get_dict()); res->copy_ap_of(in); - res->prop_copy(in, { true, false, true, true }); + res->prop_copy(in, { true, false, true, true, false }); unsigned na = in->acc().num_sets(); unsigned tr = to_remove.count(); assert(tr <= na); @@ -54,7 +54,7 @@ namespace spot auto res = make_tgba_digraph(in->get_dict()); res->copy_ap_of(in); - res->prop_copy(in, { true, true, true, true }); + res->prop_copy(in, { true, true, true, true, false }); res->copy_acceptance_conditions_of(in); transform_copy(in, res, [&](unsigned src, bdd& cond, diff --git a/src/tgbaalgos/minimize.cc b/src/tgbaalgos/minimize.cc index d9d61a52e..07d32c334 100644 --- a/src/tgbaalgos/minimize.cc +++ b/src/tgbaalgos/minimize.cc @@ -485,6 +485,7 @@ namespace spot // final is empty: there is no acceptance condition build_state_set(det_a, non_final); auto res = minimize_dfa(det_a, final, non_final); + res->prop_copy(a, { false, false, false, false, true }); res->prop_deterministic(); res->prop_inherently_weak(); res->prop_state_based_acc(); @@ -588,6 +589,7 @@ namespace spot } auto res = minimize_dfa(det_a, final, non_final); + res->prop_copy(a, { false, false, false, false, true }); res->prop_deterministic(); res->prop_inherently_weak(); return res; diff --git a/src/tgbaalgos/remfin.cc b/src/tgbaalgos/remfin.cc index e5aed4883..4a9c3742a 100644 --- a/src/tgbaalgos/remfin.cc +++ b/src/tgbaalgos/remfin.cc @@ -262,6 +262,7 @@ namespace spot unsigned nst = aut->num_states(); auto res = make_tgba_digraph(aut->get_dict()); res->copy_ap_of(aut); + res->prop_copy(aut, { false, false, false, false, true }); res->new_states(nst); res->set_acceptance(aut->acc().num_sets() + extra_sets, new_code); res->set_init_state(aut->get_init_state_number()); diff --git a/src/tgbaalgos/sccfilter.cc b/src/tgbaalgos/sccfilter.cc index 8f50f63c7..f2026cef2 100644 --- a/src/tgbaalgos/sccfilter.cc +++ b/src/tgbaalgos/sccfilter.cc @@ -317,7 +317,7 @@ namespace spot scc_filter_states(const const_tgba_digraph_ptr& aut, scc_info* given_si) { auto res = scc_filter_apply>(aut, given_si); - res->prop_copy(aut, { true, true, true, true }); + res->prop_copy(aut, { true, true, true, true, true }); return res; } @@ -340,6 +340,7 @@ namespace spot true, true, true, + true, }); return res; } @@ -372,6 +373,7 @@ namespace spot true, true, false, // determinism may not be preserved + false, // stutter inv. of suspvars probably altered }); return res; } diff --git a/src/tgbaalgos/simulation.cc b/src/tgbaalgos/simulation.cc index bd2196103..e6dad7a47 100644 --- a/src/tgbaalgos/simulation.cc +++ b/src/tgbaalgos/simulation.cc @@ -635,6 +635,7 @@ namespace spot false, // single acc set by set_generalized_buchi true, // weakness preserved, false, // determinism checked and set below + true, // stutter inv. }); if (nb_minato == nb_satoneset && !Cosimulation) res->prop_deterministic(); diff --git a/src/tgbaalgos/stutter.cc b/src/tgbaalgos/stutter.cc index 6d9be18b4..125ef1736 100644 --- a/src/tgbaalgos/stutter.cc +++ b/src/tgbaalgos/stutter.cc @@ -432,6 +432,7 @@ namespace spot true, // single_acc false, // inherently_weak false, // deterministic + false, // stutter inv. }); a->merge_transitions(); return a; @@ -452,6 +453,7 @@ namespace spot true, // single_acc false, // inherently_weak false, // deterministic + false, // stutter inv. }); unsigned n = a->num_states(); @@ -516,7 +518,7 @@ namespace spot tgba_digraph_ptr closure(const const_tgba_digraph_ptr& a) { - return closure(make_tgba_digraph(a, {true, true, true, true})); + return closure(make_tgba_digraph(a, {true, true, true, true, false})); } // The stutter check algorithm to use can be overridden via an diff --git a/src/tgbatest/hoaparse.test b/src/tgbatest/hoaparse.test index d0bd723c3..2988b169d 100755 --- a/src/tgbatest/hoaparse.test +++ b/src/tgbatest/hoaparse.test @@ -267,7 +267,8 @@ Start: 0 AP: 2 "a" "b" acc-name: generalized-Buchi 2 Acceptance: 2 Inf(0)&Inf(1) -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic --BODY-- State: 0 "foo" {0} [!0&!1] 2 @@ -483,7 +484,8 @@ Start: 0 AP: 3 "a" "b" "c" acc-name: generalized-Buchi 2 Acceptance: 2 Inf(0)&Inf(1) -properties: trans-labels explicit-labels trans-acc complete deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic --BODY-- State: 0 [!0&!1 | !0&!2] 0 @@ -566,7 +568,8 @@ Start: 0 AP: 1 "a" acc-name: generalized-Buchi 3 Acceptance: 3 Inf(0)&Inf(1)&Inf(2) -properties: trans-labels explicit-labels trans-acc complete deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic --BODY-- State: 0 [0] 1 {0 1} @@ -778,7 +781,8 @@ Start: 0 AP: 2 "a" "b" acc-name: Buchi Acceptance: 1 Inf(0) -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic --BODY-- State: 0 {0} [1] 1 @@ -878,7 +882,8 @@ Start: 0 AP: 0 acc-name: Buchi Acceptance: 1 Inf(0) -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic --BODY-- State: 0 {0} [t] 1 @@ -1033,7 +1038,8 @@ run 2 ../ltl2tgba -XH foob 2>output.err grep 'foob:1.1: Cannot open file foob' output.err # Make sure we can read multiple automata from stdin -../../bin/ltl2tgba 'a U b' 'GFa' --hoa | grep -v '^name:' > input +../../bin/ltl2tgba 'a U b' 'GFa' --hoa | grep -v '^name:' | + sed 's/ stutter-invariant//;s/ inherently-weak//;/properties:$/d' > input ../../bin/autfilt --hoa < input | ../../bin/autfilt --hoa > output diff input output @@ -1366,7 +1372,8 @@ States: 2 Start: 0 AP: 1 "a" Acceptance: 1 t -properties: trans-labels explicit-labels trans-acc complete deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic --BODY-- State: 0 "F(a)" [0] 1 {0} @@ -1379,7 +1386,8 @@ States: 1 Start: 0 AP: 3 "a" "b" "c" Acceptance: 6 Inf(0)&Inf(2)&Inf(4)&Inf(5) -properties: trans-labels explicit-labels trans-acc complete deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic --BODY-- State: 0 [0&1&2] 0 {0 2 4} @@ -1412,7 +1420,8 @@ Start: 0 AP: 1 "a" acc-name: all Acceptance: 0 t -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic --BODY-- State: 0 "F(a)" [0] 1 @@ -1426,7 +1435,8 @@ Start: 0 AP: 3 "a" "b" "c" acc-name: generalized-Buchi 4 Acceptance: 4 Inf(0)&Inf(1)&Inf(2)&Inf(3) -properties: trans-labels explicit-labels trans-acc complete deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic --BODY-- State: 0 [0&1&2] 0 {0 1 2} @@ -1444,7 +1454,8 @@ EOF # Implicit labels ../../bin/ltl2tgba -H 'GFa & GFb & (c U d)' > out.hoa -../../bin/ltl2tgba -C -Hi 'GFa & GFb & (c U d)' > out-i.hoa +../../bin/ltl2tgba -C -Hi 'GFa & GFb & (c U d)' | + sed 's/ stutter-invariant//;/properties:$/d' > out-i.hoa ../../bin/autfilt -C -Hi out.hoa --name=%M > out-i2.hoa diff out-i.hoa out-i2.hoa diff --git a/src/tgbatest/ltldo.test b/src/tgbatest/ltldo.test index f6f7df7fe..b8fadba2d 100755 --- a/src/tgbatest/ltldo.test +++ b/src/tgbatest/ltldo.test @@ -75,7 +75,8 @@ Start: 0 AP: 1 "_foo_" acc-name: Buchi Acceptance: 1 Inf(0) -properties: trans-labels explicit-labels trans-acc complete deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic --BODY-- State: 0 [0] 0 {0} @@ -95,7 +96,8 @@ Start: 0 AP: 1 "_foo_" acc-name: Buchi Acceptance: 1 Inf(0) -properties: trans-labels explicit-labels trans-acc complete deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic --BODY-- State: 0 [0] 0 {0} diff --git a/src/tgbatest/monitor.test b/src/tgbatest/monitor.test index b9afbdd95..3e75aef31 100755 --- a/src/tgbatest/monitor.test +++ b/src/tgbatest/monitor.test @@ -52,6 +52,7 @@ AP: 1 "a" acc-name: all Acceptance: 0 t properties: trans-labels explicit-labels state-acc deterministic +properties: stutter-invariant inherently-weak --BODY-- State: 0 [t] 0 @@ -68,7 +69,8 @@ Start: 0 AP: 0 acc-name: all Acceptance: 0 t -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic stutter-invariant --BODY-- State: 0 [t] 0 diff --git a/src/tgbatest/randomize.test b/src/tgbatest/randomize.test index 84aa716fd..6cfbc7eab 100755 --- a/src/tgbatest/randomize.test +++ b/src/tgbatest/randomize.test @@ -35,7 +35,8 @@ Start: 0 AP: 4 "a" "b" "c" "d" acc-name: all Acceptance: 0 t -properties: trans-labels explicit-labels state-acc +properties: trans-labels explicit-labels state-acc stutter-invariant +properties: inherently-weak --BODY-- State: 0 [0] 1 diff --git a/src/tgbatest/remfin.test b/src/tgbatest/remfin.test index 283779b5e..12aa8bb38 100755 --- a/src/tgbatest/remfin.test +++ b/src/tgbatest/remfin.test @@ -258,7 +258,8 @@ Start: 0 AP: 0 acc-name: all Acceptance: 0 t -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic --BODY-- State: 0 [t] 0 @@ -269,7 +270,8 @@ Start: 0 AP: 1 "p0" acc-name: Buchi Acceptance: 1 Inf(0) -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic --BODY-- State: 0 [!0] 0 diff --git a/src/tgbatest/sbacc.test b/src/tgbatest/sbacc.test index 3674af1de..e2eee7d11 100755 --- a/src/tgbatest/sbacc.test +++ b/src/tgbatest/sbacc.test @@ -34,7 +34,8 @@ Start: 0 AP: 2 "a" "b" acc-name: generalized-Buchi 2 Acceptance: 2 Inf(0)&Inf(1) -properties: trans-labels explicit-labels state-acc complete deterministic +properties: trans-labels explicit-labels state-acc complete +properties: deterministic --BODY-- State: 0 {0 1} [0&1] 0