twa: add support for prop_complete()

* spot/twa/twa.hh: Add support.  Make two constructors for prop_set in
order to diagnose constructions with 5 arguments.
* spot/parseaut/parseaut.yy: Adjust diagnostics for complete and
deterministic.
* spot/tl/exclusive.cc, spot/twa/twagraph.cc,
spot/twaalgos/alternation.cc, spot/twaalgos/complete.cc,
spot/twaalgos/complete.hh, spot/twaalgos/degen.cc,
spot/twaalgos/determinize.cc, spot/twaalgos/hoa.cc,
spot/twaalgos/isdet.cc, spot/twaalgos/mask.cc,
spot/twaalgos/minimize.cc, spot/twaalgos/product.cc,
spot/twaalgos/remfin.cc, spot/twaalgos/remprop.cc,
spot/twaalgos/sbacc.cc, spot/twaalgos/sccfilter.cc,
spot/twaalgos/simulation.cc, spot/twaalgos/strength.cc,
spot/twaalgos/stutter.cc, spot/twaalgos/totgba.cc,
tests/core/parseaut.test, tests/python/product.ipynb: Adjust.
* NEWS, doc/org/concepts.org, doc/org/hoa.org,
doc/org/tut21.org: Document it.
This commit is contained in:
Alexandre Duret-Lutz 2017-03-16 18:25:07 +01:00
parent 90a8a912e0
commit 0de5f50da9
28 changed files with 296 additions and 106 deletions

View file

@ -362,7 +362,7 @@ namespace spot
res->copy_ap_of(aut_);
// We preserve deterministic-like properties, and
// stutter-invariance.
res->prop_copy(aut_, {false, false, false, true, true});
res->prop_copy(aut_, {false, false, false, true, true, true});
res->set_generalized_buchi(has_reject_more_ + reject_1_count_);
// We for easier computation of outgoing sets, we will

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014, 2015, 2016 Laboratoire de Recherche et
// Développement de l'Epita.
// Copyright (C) 2013-2017 Laboratoire de Recherche et Développement
// de l'Epita.
//
// This file is part of Spot, a model checking library.
//
@ -21,10 +21,12 @@
namespace spot
{
unsigned complete_here(twa_graph_ptr aut)
void complete_here(twa_graph_ptr aut)
{
unsigned n = aut->num_states();
unsigned sink = -1U;
if (aut->prop_complete().is_true())
return;
unsigned n = aut->num_states();
// UM is a pair (bool, mark). If the Boolean is false, the
// acceptance is always satisfiable. Otherwise, MARK is an
@ -126,24 +128,17 @@ namespace spot
}
}
aut->prop_complete(true);
// Get rid of any named property if the automaton changed.
if (t < aut->num_edges())
aut->release_named_properties();
else
assert(t == aut->num_edges());
return sink;
}
twa_graph_ptr complete(const const_twa_ptr& aut)
{
auto res = make_twa_graph(aut, {
true, // state based
true, // inherently_weak
true, // deterministic
true, // improve det
true, // stutter inv.
});
auto res = make_twa_graph(aut, twa::prop_set::all());
complete_here(res);
return res;
}

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et
// Copyright (C) 2013, 2014, 2015, 2017 Laboratoire de Recherche et
// Développement de l'Epita.
//
// This file is part of Spot, a model checking library.
@ -25,12 +25,9 @@ namespace spot
{
/// \brief Complete a twa_graph in place.
///
/// If the TωA has no acceptance set, one will be added. The
/// returned value is the number of the sink state (it can be a new
/// state added for completion, or an existing non-accepting state
/// that has been reused as sink state because it had no outgoing
/// transitions apart from self-loops.)
SPOT_API unsigned complete_here(twa_graph_ptr aut);
/// If the TωA has an acceptance condition that is a tautology,
/// it will be changed into a Büchi automaton.
SPOT_API void complete_here(twa_graph_ptr aut);
/// \brief Clone a twa and complete it.
///

View file

@ -212,7 +212,7 @@ namespace spot
if (want_sba)
res->prop_state_acc(true);
// Preserve determinism, weakness, and stutter-invariance
res->prop_copy(a, { false, true, true, true, true });
res->prop_copy(a, { false, true, true, true, true, true });
// Create an order of acceptance conditions. Each entry in this
// vector correspond to an acceptance set. Each index can

View file

@ -641,6 +641,7 @@ namespace spot
{ false, // state based
false, // inherently_weak
false, false, // deterministic
true, // complete
true // stutter inv
});

View file

@ -160,8 +160,11 @@ namespace spot
is_colored = colored && (!has_state_acc || nodeadend);
// If the automaton declares that it is deterministic or
// state-based, make sure that it really is.
assert(deterministic || aut->prop_deterministic() != true);
assert(state_acc || aut->prop_state_acc() != true);
assert(!aut->prop_deterministic().is_known() ||
deterministic == aut->prop_deterministic().is_true());
assert(!aut->prop_complete().is_known() ||
complete == aut->prop_complete().is_true());
assert(state_acc || !aut->prop_state_acc().is_true());
}
void number_all_ap(const const_twa_graph_ptr& aut)

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2012, 2013, 2014, 2015, 2016 Laboratoire de Recherche
// et Développement de l'Epita (LRDE).
// Copyright (C) 2012-2017 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -134,6 +134,9 @@ namespace spot
bool
is_complete(const const_twa_graph_ptr& aut)
{
trival cp = aut->prop_complete();
if (cp.is_known())
return cp.is_true();
unsigned ns = aut->num_states();
for (unsigned src = 0; src < ns; ++src)
{
@ -141,11 +144,16 @@ namespace spot
for (auto& t: aut->out(src))
available -= t.cond;
if (available != bddfalse)
return false;
{
std::const_pointer_cast<twa_graph>(aut)->prop_complete(false);
return false;
}
}
// The empty automaton is not complete since it does not have an
// initial state.
return ns > 0;
bool res = ns > 0;
std::const_pointer_cast<twa_graph>(aut)->prop_complete(res);
return res;
}
bool

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement
// Copyright (C) 2015, 2016, 2017 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
@ -26,7 +26,7 @@ namespace spot
{
auto res = make_twa_graph(in->get_dict());
res->copy_ap_of(in);
res->prop_copy(in, { true, true, true, true, false });
res->prop_copy(in, { true, true, false, true, false, false });
unsigned na = in->num_sets();
unsigned tr = to_remove.count();
assert(tr <= na);
@ -54,7 +54,7 @@ namespace spot
auto res = make_twa_graph(in->get_dict());
res->copy_ap_of(in);
res->prop_copy(in, { true, true, false, true, false });
res->prop_copy(in, { true, true, false, true, false, false });
res->copy_acceptance_of(in);
transform_copy(in, res, [&](unsigned src,
bdd& cond,
@ -76,7 +76,7 @@ namespace spot
auto res = make_twa_graph(in->get_dict());
res->copy_ap_of(in);
res->prop_copy(in, { true, true, false, true, false });
res->prop_copy(in, { true, true, false, true, false, false });
res->copy_acceptance_of(in);
transform_accessible(in, res, [&](unsigned src,
bdd& cond,

View file

@ -486,7 +486,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_copy(a, { false, false, false, false, true, true });
res->prop_deterministic(true);
res->prop_weak(true);
res->prop_state_acc(true);
@ -595,7 +595,7 @@ namespace spot
}
auto res = minimize_dfa(det_a, final, non_final);
res->prop_copy(a, { false, false, false, false, true });
res->prop_copy(a, { false, false, false, false, false, true });
res->prop_deterministic(true);
res->prop_weak(true);
// If the input was terminal, then the output is also terminal.

View file

@ -106,22 +106,21 @@ namespace spot
}
}
res->prop_deterministic(left->prop_deterministic()
&& right->prop_deterministic());
res->prop_stutter_invariant(left->prop_stutter_invariant()
&& right->prop_stutter_invariant());
// The product of X!a and Xa, two stutter-sentive formulas,
// is stutter-invariant.
//res->prop_stutter_sensitive(left->prop_stutter_sensitive()
// && right->prop_stutter_sensitive());
res->prop_inherently_weak(left->prop_inherently_weak()
&& right->prop_inherently_weak());
res->prop_weak(left->prop_weak()
&& right->prop_weak());
res->prop_terminal(left->prop_terminal()
&& right->prop_terminal());
res->prop_state_acc(left->prop_state_acc()
&& right->prop_state_acc());
// The product of two non-deterministic automata could be
// deterministic. likewise for non-complete automata.
if (left->prop_deterministic() && right->prop_deterministic())
res->prop_deterministic(true);
if (left->prop_complete() && right->prop_complete())
res->prop_complete(true);
if (left->prop_stutter_invariant() && right->prop_stutter_invariant())
res->prop_stutter_invariant(true);
if (left->prop_inherently_weak() && right->prop_inherently_weak())
res->prop_inherently_weak(true);
if (left->prop_weak() && right->prop_weak())
res->prop_weak(true);
if (left->prop_terminal() && right->prop_terminal())
res->prop_terminal(true);
res->prop_state_acc(left->prop_state_acc() && right->prop_state_acc());
return res;
}
}

View file

@ -224,11 +224,12 @@ namespace spot
unsigned nst = aut->num_states();
auto res = make_twa_graph(aut->get_dict());
res->copy_ap_of(aut);
res->prop_copy(aut, { true, false, false, false, true });
res->prop_copy(aut, { true, false, false, false, false, true });
res->new_states(nst);
res->set_buchi();
res->set_init_state(aut->get_init_state_number());
trival deterministic = aut->prop_deterministic();
trival complete = aut->prop_complete();
std::vector<unsigned> state_map(aut->num_states());
for (unsigned n = 0; n < scc_max; ++n)
@ -245,11 +246,11 @@ namespace spot
for (auto& t: aut->out(s))
res->new_acc_edge(s, t.dst, t.cond, acc);
}
continue;
}
else
{
deterministic = false;
complete = trival::maybe();
// The main copy is only accepting for inf_alone
// and for all Inf sets that have no matching Fin
@ -300,8 +301,9 @@ namespace spot
}
}
}
res->purge_dead_states();
res->prop_complete(complete);
res->prop_deterministic(deterministic);
res->purge_dead_states();
return res;
}
@ -386,10 +388,11 @@ namespace spot
auto res = make_twa_graph(aut,
{
true, // state based
true, // inherently weak
true, true, // determinisitic
true, // stutter inv.
});
true, // inherently weak
true, true, // determinisitic
true, // complete
true, // stutter inv.
});
scc_info si(res);
// We will modify res in place, and the resulting
@ -663,7 +666,7 @@ namespace spot
unsigned nst = aut->num_states();
auto res = make_twa_graph(aut->get_dict());
res->copy_ap_of(aut);
res->prop_copy(aut, { true, false, false, false, true });
res->prop_copy(aut, { true, false, false, false, false, true });
res->new_states(nst);
res->set_acceptance(aut->num_sets() + extra_sets, new_code);
res->set_init_state(aut->get_init_state_number());

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
// l'Epita (LRDE).
// Copyright (C) 2015-2017 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
//
@ -130,7 +130,7 @@ namespace spot
twa_graph_ptr res = make_twa_graph(d);
res->copy_ap_of(aut);
res->prop_copy(aut, { true, true, false, false, false });
res->prop_copy(aut, { true, true, false, false, false, false });
res->copy_acceptance_of(aut);
for (auto ap: props_exist)

View file

@ -57,7 +57,7 @@ namespace spot
auto res = make_twa_graph(old->get_dict());
res->copy_ap_of(old);
res->copy_acceptance_of(old);
res->prop_copy(old, {false, true, true, true, true});
res->prop_copy(old, {false, true, true, true, true, true});
res->prop_state_acc(true);
typedef std::pair<unsigned, acc_cond::mark_t> pair_t;

View file

@ -375,7 +375,7 @@ namespace spot
else
res = scc_filter_apply<state_filter
<acc_filter_mask<false, true>>>(aut, given_si);
res->prop_copy(aut, { true, true, false, true, true });
res->prop_copy(aut, { true, true, false, true, false, true });
return res;
}
@ -417,6 +417,7 @@ namespace spot
true,
false,
true, // determinism improved
false,
true,
});
return res;
@ -451,6 +452,7 @@ namespace spot
{ false, // state-based acceptance is not preserved
true,
false, false, // determinism may not be preserved
false,
false, // stutter inv. of suspvars probably altered
});
return res;

View file

@ -595,6 +595,7 @@ namespace spot
{ false, // state-based acc forced below
true, // weakness preserved,
false, true, // determinism improved
true, // completeness preserved
true, // stutter inv.
});
// !unambiguous and !semi-deterministic are not preserved

View file

@ -295,7 +295,7 @@ namespace spot
twa_graph_ptr res = make_twa_graph(aut->get_dict());
res->copy_ap_of(aut);
res->prop_copy(aut, { true, false, false, true, false });
res->prop_copy(aut, { true, false, false, true, false, false });
if (keep & Strong)
res->copy_acceptance_of(aut);
@ -362,7 +362,7 @@ namespace spot
const_twa_graph_ptr aut = sm.get_aut();
twa_graph_ptr res = make_twa_graph(aut->get_dict());
res->copy_ap_of(aut);
res->prop_copy(aut, { true, false, false, true, false });
res->prop_copy(aut, { true, false, false, true, false, false });
res->copy_acceptance_of(aut);
auto um = aut->acc().unsat_mark();

View file

@ -400,10 +400,11 @@ namespace spot
}
}
if (num_states != a->num_states())
a->prop_keep({true, // state_based
a->prop_keep({true, // state_based
false, // inherently_weak
false, false, // deterministic
false, // stutter inv.
true, // complete
false, // stutter inv.
});
a->merge_edges();
return a;
@ -423,6 +424,7 @@ namespace spot
a->prop_keep({false, // state_based
false, // inherently_weak
false, false, // deterministic
true, // complete
false, // stutter inv.
});

View file

@ -146,7 +146,7 @@ namespace spot
auto out = make_twa_graph(in->get_dict());
out->copy_ap_of(in);
out->prop_copy(in, {false, false, false, false, true});
out->prop_copy(in, {false, false, false, false, false, true});
out->set_generalized_buchi(p);
acc_cond::mark_t outall = out->acc().all_sets();