fix several algorithms that incorrectly preserved !weak
This massive set of changes was triggered by issue #546. In addition to the better handling of !weak, this also adds some weak properties in a few places. * spot/twaalgos/product.cc (product_aux): Throw some exception if an automaton with t or f acceptance has the !weak property. This is a cheap sanity check to help detect algorithms that incorrectly assumed !weak input would necessarily become !weak output. * spot/twaalgos/hoa.cc (print_hoa): Likewise, also do not assume that terminal implies very-weak. * spot/parseaut/parseaut.yy: Add several diagnostics for similar cases. E.g., a one-state automaton cannot be declared as !very-weak. * tests/core/parseaut.test: Check those new diagnostics. * spot/twa/twa.cc (twa::intersecting_run): Temporary remove the weak property by setting it to maybe, not to false. * spot/twaalgos/minimize.cc, spot/twaalgos/parity.cc, spot/twaalgos/sccfilter.cc, spot/twaalgos/simulation.cc: Account for the fact that these algorithm may in fact improve the weakness. * spot/twaalgos/strength.cc: Only look at colors used by the acceptance condition when deciding weakness. * spot/twaalgos/synthesis.cc: Declare the strategy as weak. * bin/randaut.cc: Add weak to automata with t/f acceptance. * spot/kripke/kripke.hh: Make kripke structures as weak. * tests/core/acc_word.test, tests/core/alternating.test, tests/core/complement.test, tests/core/complete.test, tests/core/ltlsynt.test, tests/core/randomize.test, tests/core/readsave.test, tests/core/remfin.test, tests/core/sccsimpl.test, tests/core/strength.test, tests/core/wdba2.test, tests/ltsmin/kripke.test, tests/python/automata-io.ipynb, tests/python/automata.ipynb, tests/python/dbranch.py, tests/python/highlighting.ipynb, tests/python/kripke.py, tests/python/ltsmin-dve.ipynb, tests/python/mealy.py, tests/python/simstate.py: Adjust all these test cases. * NEWS: Mention the fixes.
This commit is contained in:
parent
ac05035267
commit
67b5d2aa9a
34 changed files with 287 additions and 164 deletions
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2014-2022 Laboratoire de Recherche et
|
||||
// Copyright (C) 2014-2023 Laboratoire de Recherche et
|
||||
// Developpement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -507,6 +507,11 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
if (SPOT_UNLIKELY(aut->prop_weak().is_false()
|
||||
&& (aut->acc().is_t() || aut->acc().is_f())))
|
||||
throw std::runtime_error("print_hoa(): automaton is declared not weak, "
|
||||
"but the acceptance makes this impossible");
|
||||
|
||||
metadata md(aut, implicit_labels, state_labels);
|
||||
|
||||
if (acceptance == Hoa_Acceptance_States && !md.has_state_acc)
|
||||
|
|
@ -724,7 +729,7 @@ namespace spot
|
|||
}
|
||||
if (aut->prop_terminal())
|
||||
prop(" terminal");
|
||||
if (aut->prop_very_weak() && (verbose || aut->prop_terminal() != true))
|
||||
if (aut->prop_very_weak())
|
||||
prop(" very-weak");
|
||||
if (aut->prop_weak() && (verbose || (aut->prop_terminal() != true &&
|
||||
aut->prop_very_weak() != true)))
|
||||
|
|
|
|||
|
|
@ -556,6 +556,16 @@ namespace spot
|
|||
// add a quick check inside minimize_dfa.
|
||||
if (a->prop_terminal())
|
||||
res->prop_terminal(true);
|
||||
else if (a->num_states() == 1)
|
||||
{
|
||||
// If thie automaton has only one state, check w
|
||||
for (auto& e: a->out(0))
|
||||
if (e.cond == bddtrue && a->acc().accepting(e.acc))
|
||||
{
|
||||
res->prop_terminal(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2016, 2018, 2019, 2022 Laboratoire de Recherche et
|
||||
// Copyright (C) 2016, 2018, 2019, 2022, 2023 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -649,6 +649,13 @@ namespace spot
|
|||
e.acc = acc_cond::mark_t({n});
|
||||
}
|
||||
|
||||
// Reducing the number of colors could turn a non-weak automaton
|
||||
// into a weak one
|
||||
if (aut->prop_weak().is_false())
|
||||
aut->prop_weak(trival::maybe());
|
||||
if (aut->prop_very_weak().is_false())
|
||||
aut->prop_very_weak(trival::maybe());
|
||||
|
||||
return aut;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <unordered_map>
|
||||
#include <spot/misc/hash.hh>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace spot
|
||||
{
|
||||
namespace
|
||||
|
|
@ -102,6 +104,13 @@ namespace spot
|
|||
|
||||
enum acc_op { and_acc, or_acc, xor_acc, xnor_acc };
|
||||
|
||||
[[noreturn]] static
|
||||
void report_should_be_weak(const char* what)
|
||||
{
|
||||
std::string s = what + " automaton is declared not weak, "
|
||||
"but the acceptance makes this impossible"s;
|
||||
throw std::runtime_error(s);
|
||||
}
|
||||
|
||||
static
|
||||
twa_graph_ptr product_aux(const const_twa_graph_ptr& left,
|
||||
|
|
@ -128,6 +137,13 @@ namespace spot
|
|||
bool leftweak = left->prop_weak().is_true();
|
||||
bool rightweak = right->prop_weak().is_true();
|
||||
|
||||
if (SPOT_UNLIKELY(!leftweak && left->prop_weak().is_false()
|
||||
&& (lacc.is_t() || lacc.is_f())))
|
||||
report_should_be_weak("product: left");
|
||||
if (SPOT_UNLIKELY(!rightweak && right->prop_weak().is_false()
|
||||
&& (racc.is_t() || racc.is_f())))
|
||||
report_should_be_weak("product: right");
|
||||
|
||||
// The conjunction of two co-Büchi automata is a co-Büchi automaton.
|
||||
// The disjunction of two Büchi automata is a Büchi automaton.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2009-2018 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2009-2018, 2023 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -428,6 +428,15 @@ namespace spot
|
|||
res = scc_filter_apply<state_filter
|
||||
<acc_filter_mask<false, true>>>(aut, given_si);
|
||||
res->prop_copy(aut, { true, true, false, true, false, true });
|
||||
if (res->num_edges() != aut->num_edges())
|
||||
{
|
||||
if (res->prop_weak().is_false())
|
||||
res->prop_weak(trival::maybe());
|
||||
if (res->prop_very_weak().is_false())
|
||||
res->prop_very_weak(trival::maybe());
|
||||
}
|
||||
if (res->prop_weak().is_true() && res->num_states() <= 1)
|
||||
res->prop_very_weak(true);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -496,6 +505,16 @@ namespace spot
|
|||
if (!given_si)
|
||||
delete si;
|
||||
}
|
||||
else
|
||||
if (res->num_edges() != aut->num_edges())
|
||||
{
|
||||
if (res->prop_weak().is_false())
|
||||
res->prop_weak(trival::maybe());
|
||||
if (res->prop_very_weak().is_false())
|
||||
res->prop_very_weak(trival::maybe());
|
||||
}
|
||||
if (res->prop_weak().is_true() && res->num_states() <= 1)
|
||||
res->prop_very_weak(true);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -761,11 +761,19 @@ namespace spot
|
|||
delete gb;
|
||||
res->prop_copy(original_,
|
||||
{ false, // state-based acc forced below
|
||||
true, // weakness preserved,
|
||||
true, // weakness preserved
|
||||
false, true, // determinism improved
|
||||
true, // completeness preserved
|
||||
true, // stutter inv.
|
||||
});
|
||||
|
||||
// weakness can actually be improved
|
||||
if (res->prop_weak().is_false())
|
||||
res->prop_weak(trival::maybe());
|
||||
if (res->prop_very_weak().is_false())
|
||||
res->prop_very_weak(trival::maybe());
|
||||
if (res->prop_inherently_weak().is_false())
|
||||
res->prop_inherently_weak(trival::maybe());
|
||||
// !unambiguous and !semi-deterministic are not preserved
|
||||
if (!Cosimulation && nb_minato == nb_minterms)
|
||||
// Note that nb_minato != nb_minterms does not imply
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2010-2011, 2013-2018 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE)
|
||||
// Copyright (C) 2010-2011, 2013-2018, 2023 Laboratoire de Recherche
|
||||
// et Développement de l'Epita (LRDE)
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -43,6 +43,8 @@ namespace spot
|
|||
if (inweak)
|
||||
si->determine_unknown_acceptance();
|
||||
|
||||
acc_cond::mark_t mask = aut->get_acceptance().used_sets();
|
||||
|
||||
bool is_inweak = true;
|
||||
bool is_weak = true;
|
||||
bool is_single_state_scc = true;
|
||||
|
|
@ -66,9 +68,9 @@ namespace spot
|
|||
if (first)
|
||||
{
|
||||
first = false;
|
||||
m = t.acc;
|
||||
m = t.acc & mask;
|
||||
}
|
||||
else if (m != t.acc)
|
||||
else if (m != (t.acc & mask))
|
||||
{
|
||||
is_weak = false;
|
||||
if (!inweak)
|
||||
|
|
|
|||
|
|
@ -1469,6 +1469,9 @@ namespace spot
|
|||
edge.acc = {};
|
||||
}
|
||||
res->set_acceptance(acc_cond::acc_code::t());
|
||||
res->prop_weak(true);
|
||||
if (res->prop_terminal().is_false())
|
||||
res->prop_terminal(trival::maybe());
|
||||
res->set_named_prop<bdd>("synthesis-outputs", new bdd(output_bdd));
|
||||
|
||||
return ret_sol_exists(res);
|
||||
|
|
@ -1478,6 +1481,7 @@ namespace spot
|
|||
if (!want_strategy)
|
||||
return ret_sol_exists(nullptr);
|
||||
auto res = make_twa_graph(dict);
|
||||
res->prop_weak(true);
|
||||
|
||||
bdd output_bdd = bddtrue;
|
||||
std::set<formula> ins_f = form2props.aps_of(f_g).first;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue