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:
parent
90a8a912e0
commit
0de5f50da9
28 changed files with 296 additions and 106 deletions
3
NEWS
3
NEWS
|
|
@ -10,6 +10,9 @@ New in spot 2.3.2.dev (not yet released)
|
||||||
- spot::sum() and spot::sum_and() implements the union and the
|
- spot::sum() and spot::sum_and() implements the union and the
|
||||||
intersection of two automatons, respectively.
|
intersection of two automatons, respectively.
|
||||||
|
|
||||||
|
- twa objects have a new property: prop_complete(). This obviously
|
||||||
|
acts as a cache for the is_complete() function.
|
||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
|
|
||||||
- In "lenient" mode the parser would fail to recover from
|
- In "lenient" mode the parser would fail to recover from
|
||||||
|
|
|
||||||
|
|
@ -1056,11 +1056,12 @@ automaton, and that can be queried or set by algorithms:
|
||||||
|
|
||||||
| flag name | meaning when =true= |
|
| flag name | meaning when =true= |
|
||||||
|----------------------+----------------------------------------------------------------------------------------------|
|
|----------------------+----------------------------------------------------------------------------------------------|
|
||||||
| =state_acc= | automaton should be considered has having state-based acceptance |
|
| =state_acc= | automaton should be considered as having state-based acceptance |
|
||||||
| =inherently_weak= | accepting and rejecting cycles cannot be mixed in the same SCC |
|
| =inherently_weak= | accepting and rejecting cycles cannot be mixed in the same SCC |
|
||||||
| =weak= | transitions of an SCC all belong to the same acceptance sets |
|
| =weak= | transitions of an SCC all belong to the same acceptance sets |
|
||||||
| =very-weak= | weak automaton where all SCCs have size 1 |
|
| =very-weak= | weak automaton where all SCCs have size 1 |
|
||||||
| =terminal= | automaton is weak, accepting SCCs are complete, accepting edges may not go to rejecting SCCs |
|
| =terminal= | automaton is weak, accepting SCCs are complete, accepting edges may not go to rejecting SCCs |
|
||||||
|
| =complete= | it is always possible to move the automaton forward, using any letter |
|
||||||
| =deterministic= | there is at most one run *recognizing* a word, but not necessarily accepting it |
|
| =deterministic= | there is at most one run *recognizing* a word, but not necessarily accepting it |
|
||||||
| =semi-deterministic= | any nondeterminism occurs before entering an accepting SCC |
|
| =semi-deterministic= | any nondeterminism occurs before entering an accepting SCC |
|
||||||
| =unambiguous= | there is at most one run *accepting* a word (but it might be recognized several time) |
|
| =unambiguous= | there is at most one run *accepting* a word (but it might be recognized several time) |
|
||||||
|
|
|
||||||
|
|
@ -661,7 +661,7 @@ particular:
|
||||||
| =no-univ-branch= | ignored | no | only if =-Hv= | |
|
| =no-univ-branch= | ignored | no | only if =-Hv= | |
|
||||||
| =univ-branch= | checked | no | checked | |
|
| =univ-branch= | checked | no | checked | |
|
||||||
| =deterministic= | checked | yes | checked | |
|
| =deterministic= | checked | yes | checked | |
|
||||||
| =complete= | checked | no | checked | |
|
| =complete= | checked | yes | checked | |
|
||||||
| =unambiguous= | trusted | yes | as stored if (=-Hv= or not =deterministic=) | can be checked with =--check=unambiguous= |
|
| =unambiguous= | trusted | yes | as stored if (=-Hv= or not =deterministic=) | can be checked with =--check=unambiguous= |
|
||||||
| =semi-deterministic= | trusted | yes | as stored if (=-Hv= or not =deterministic=) | can be checked with =--check=semi-deterministic= |
|
| =semi-deterministic= | trusted | yes | as stored if (=-Hv= or not =deterministic=) | can be checked with =--check=semi-deterministic= |
|
||||||
| =stutter-invariant= | trusted | yes | as stored | can be checked with =--check=stuttering= |
|
| =stutter-invariant= | trusted | yes | as stored | can be checked with =--check=stuttering= |
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ corresponding BDD variable number, and then use for instance
|
||||||
// would set the deterministic property on its output. In this
|
// would set the deterministic property on its output. In this
|
||||||
// example, the properties that are set come from the "properties:"
|
// example, the properties that are set come from the "properties:"
|
||||||
// line of the input file.
|
// line of the input file.
|
||||||
|
out << "Complete: " << aut->prop_complete() << '\n';
|
||||||
out << "Deterministic: " << aut->prop_deterministic() << '\n';
|
out << "Deterministic: " << aut->prop_deterministic() << '\n';
|
||||||
out << "Unambiguous: " << aut->prop_unambiguous() << '\n';
|
out << "Unambiguous: " << aut->prop_unambiguous() << '\n';
|
||||||
out << "State-Based Acc: " << aut->prop_state_acc() << '\n';
|
out << "State-Based Acc: " << aut->prop_state_acc() << '\n';
|
||||||
|
|
@ -169,6 +170,7 @@ Number of edges: 10
|
||||||
Initial state: 0
|
Initial state: 0
|
||||||
Atomic propositions: a (=0) b (=1) c (=2)
|
Atomic propositions: a (=0) b (=1) c (=2)
|
||||||
Name: Fa | G(Fb & Fc)
|
Name: Fa | G(Fb & Fc)
|
||||||
|
Complete: no
|
||||||
Deterministic: no
|
Deterministic: no
|
||||||
Unambiguous: yes
|
Unambiguous: yes
|
||||||
State-Based Acc: maybe
|
State-Based Acc: maybe
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ extern "C" int strverscmp(const char *s1, const char *s2);
|
||||||
bool aliased_states = false;
|
bool aliased_states = false;
|
||||||
|
|
||||||
spot::trival deterministic = spot::trival::maybe();
|
spot::trival deterministic = spot::trival::maybe();
|
||||||
bool complete = false;
|
spot::trival complete = spot::trival::maybe();
|
||||||
bool trans_acc_seen = false;
|
bool trans_acc_seen = false;
|
||||||
|
|
||||||
std::map<std::string, spot::location> labels;
|
std::map<std::string, spot::location> labels;
|
||||||
|
|
@ -471,14 +471,15 @@ header: format-version header-items
|
||||||
error(det.loc,
|
error(det.loc,
|
||||||
"deterministic automata should have at most "
|
"deterministic automata should have at most "
|
||||||
"one initial state");
|
"one initial state");
|
||||||
|
res.deterministic = spot::trival::maybe();
|
||||||
}
|
}
|
||||||
res.deterministic = false;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Assume the automaton is deterministic until proven
|
// Assume the automaton is deterministic until proven
|
||||||
// wrong, or unless we are building a Kripke structure.
|
// wrong, or unless we are building a Kripke structure.
|
||||||
res.deterministic = !res.opts.want_kripke;
|
if (!res.opts.want_kripke)
|
||||||
|
res.deterministic = true;
|
||||||
}
|
}
|
||||||
auto complete = res.prop_is_true("complete");
|
auto complete = res.prop_is_true("complete");
|
||||||
if (ss < 1)
|
if (ss < 1)
|
||||||
|
|
@ -495,7 +496,8 @@ header: format-version header-items
|
||||||
{
|
{
|
||||||
// Assume the automaton is complete until proven
|
// Assume the automaton is complete until proven
|
||||||
// wrong.
|
// wrong.
|
||||||
res.complete = !res.opts.want_kripke;
|
if (!res.opts.want_kripke)
|
||||||
|
res.complete = true;
|
||||||
}
|
}
|
||||||
// if ap_count == 0, then a Kripke structure could be
|
// if ap_count == 0, then a Kripke structure could be
|
||||||
// declared complete, although that probably doesn't
|
// declared complete, although that probably doesn't
|
||||||
|
|
@ -1034,6 +1036,7 @@ body: states
|
||||||
// mention it in the next loop.
|
// mention it in the next loop.
|
||||||
if (s < res.info_states.size())
|
if (s < res.info_states.size())
|
||||||
res.info_states[s].declared = true;
|
res.info_states[s].declared = true;
|
||||||
|
res.complete = spot::trival::maybe();
|
||||||
}
|
}
|
||||||
unsigned n = res.info_states.size();
|
unsigned n = res.info_states.size();
|
||||||
// States with number above res.states have already caused a
|
// States with number above res.states have already caused a
|
||||||
|
|
@ -1043,10 +1046,34 @@ body: states
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (unsigned i = 0; i < n; ++i)
|
||||||
{
|
{
|
||||||
auto& p = res.info_states[i];
|
auto& p = res.info_states[i];
|
||||||
if (p.used && !p.declared)
|
if (!p.declared)
|
||||||
error(p.used_loc,
|
{
|
||||||
"state " + std::to_string(i) + " has no definition");
|
if (p.used)
|
||||||
|
error(p.used_loc,
|
||||||
|
"state " + std::to_string(i) + " has no definition");
|
||||||
|
if (!p.used && res.complete)
|
||||||
|
if (auto p = res.prop_is_true("complete"))
|
||||||
|
{
|
||||||
|
error(res.states_loc,
|
||||||
|
"state " + std::to_string(i) +
|
||||||
|
" has no definition...");
|
||||||
|
error(p.loc, "... despite 'properties: complete'");
|
||||||
|
}
|
||||||
|
res.complete = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (res.complete)
|
||||||
|
if (auto p = res.prop_is_false("complete"))
|
||||||
|
{
|
||||||
|
error(@1, "automaton is complete...");
|
||||||
|
error(p.loc, "... despite 'properties: !complete'");
|
||||||
|
}
|
||||||
|
if (res.deterministic)
|
||||||
|
if (auto p = res.prop_is_false("deterministic"))
|
||||||
|
{
|
||||||
|
error(@1, "automaton is deterministic...");
|
||||||
|
error(p.loc, "... despite 'properties: !deterministic'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state-num: INT
|
state-num: INT
|
||||||
|
|
@ -1104,7 +1131,7 @@ checked-state-num: state-num
|
||||||
|
|
||||||
states: | states state
|
states: | states state
|
||||||
{
|
{
|
||||||
if ((res.deterministic || res.complete) && !res.opts.want_kripke)
|
if ((res.deterministic.is_true() || res.complete.is_true()))
|
||||||
{
|
{
|
||||||
bdd available = bddtrue;
|
bdd available = bddtrue;
|
||||||
bool det = true;
|
bool det = true;
|
||||||
|
|
@ -1114,7 +1141,7 @@ states: | states state
|
||||||
det = false;
|
det = false;
|
||||||
available -= t.cond;
|
available -= t.cond;
|
||||||
}
|
}
|
||||||
if (res.deterministic && !det)
|
if (res.deterministic.is_true() && !det)
|
||||||
{
|
{
|
||||||
res.deterministic = false;
|
res.deterministic = false;
|
||||||
if (auto p = res.prop_is_true("deterministic"))
|
if (auto p = res.prop_is_true("deterministic"))
|
||||||
|
|
@ -1124,7 +1151,7 @@ states: | states state
|
||||||
"... despite 'properties: deterministic'");
|
"... despite 'properties: deterministic'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res.complete && available != bddfalse)
|
if (res.complete.is_true() && available != bddfalse)
|
||||||
{
|
{
|
||||||
res.complete = false;
|
res.complete = false;
|
||||||
if (auto p = res.prop_is_true("complete"))
|
if (auto p = res.prop_is_true("complete"))
|
||||||
|
|
@ -1165,7 +1192,7 @@ state: state-name labeled-edges
|
||||||
// Assume the worse. This skips the tests about determinism
|
// Assume the worse. This skips the tests about determinism
|
||||||
// we might perform on the state.
|
// we might perform on the state.
|
||||||
res.deterministic = spot::trival::maybe();
|
res.deterministic = spot::trival::maybe();
|
||||||
res.complete = false;
|
res.complete = spot::trival::maybe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1177,6 +1204,11 @@ state-name: "State:" state-label_opt checked-state-num string_opt state-acc_opt
|
||||||
std::ostringstream o;
|
std::ostringstream o;
|
||||||
o << "redeclaration of state " << $3;
|
o << "redeclaration of state " << $3;
|
||||||
error(@1 + @3, o.str());
|
error(@1 + @3, o.str());
|
||||||
|
// The additional transitions from extra states might
|
||||||
|
// led us to believe that the automaton is complete
|
||||||
|
// while it is not if we ignore them.
|
||||||
|
if (res.complete.is_true())
|
||||||
|
res.complete = spot::trival::maybe();
|
||||||
}
|
}
|
||||||
res.info_states[$3].declared = true;
|
res.info_states[$3].declared = true;
|
||||||
res.acc_state = $5;
|
res.acc_state = $5;
|
||||||
|
|
@ -1499,7 +1531,7 @@ dstar_header: dstar_sizes
|
||||||
}
|
}
|
||||||
res.acc_style = State_Acc;
|
res.acc_style = State_Acc;
|
||||||
res.deterministic = true;
|
res.deterministic = true;
|
||||||
// res.h->aut->prop_complete();
|
res.complete = true;
|
||||||
fill_guards(res);
|
fill_guards(res);
|
||||||
res.cur_guard = res.guards.end();
|
res.cur_guard = res.guards.end();
|
||||||
}
|
}
|
||||||
|
|
@ -2230,6 +2262,10 @@ static void fix_initial_state(result_& r)
|
||||||
"a single initial state");
|
"a single initial state");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Fiddling with initial state may turn an incomplete automaton
|
||||||
|
// into a complete one.
|
||||||
|
if (r.complete.is_false())
|
||||||
|
r.complete = spot::trival::maybe();
|
||||||
// Multiple initial states. We might need to add a fake one,
|
// Multiple initial states. We might need to add a fake one,
|
||||||
// unless one of the actual initial state has no incoming edge.
|
// unless one of the actual initial state has no incoming edge.
|
||||||
auto& aut = r.h->aut;
|
auto& aut = r.h->aut;
|
||||||
|
|
@ -2299,7 +2335,9 @@ static void fix_initial_state(result_& r)
|
||||||
static void fix_properties(result_& r)
|
static void fix_properties(result_& r)
|
||||||
{
|
{
|
||||||
r.aut_or_ks->prop_deterministic(r.deterministic);
|
r.aut_or_ks->prop_deterministic(r.deterministic);
|
||||||
//r.aut_or_ks->prop_complete(r.complete);
|
// std::cerr << "fix det: " << r.deterministic << '\n';
|
||||||
|
// std::cerr << "fix complete: " << r.complete << '\n';
|
||||||
|
r.aut_or_ks->prop_complete(r.complete);
|
||||||
if (r.acc_style == State_Acc ||
|
if (r.acc_style == State_Acc ||
|
||||||
(r.acc_style == Mixed_Acc && !r.trans_acc_seen))
|
(r.acc_style == Mixed_Acc && !r.trans_acc_seen))
|
||||||
r.aut_or_ks->prop_state_acc(true);
|
r.aut_or_ks->prop_state_acc(true);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement
|
// Copyright (C) 2015-2017 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.
|
||||||
|
|
@ -177,7 +177,7 @@ namespace spot
|
||||||
|
|
||||||
twa_graph_ptr res = make_twa_graph(aut->get_dict());
|
twa_graph_ptr res = make_twa_graph(aut->get_dict());
|
||||||
res->copy_ap_of(aut);
|
res->copy_ap_of(aut);
|
||||||
res->prop_copy(aut, { true, true, false, true, true });
|
res->prop_copy(aut, { true, true, false, true, false, true });
|
||||||
res->copy_acceptance_of(aut);
|
res->copy_acceptance_of(aut);
|
||||||
if (simplify_guards)
|
if (simplify_guards)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2009, 2011, 2013, 2014, 2015, 2016 Laboratoire de
|
// Copyright (C) 2009, 2011, 2013-2017 Laboratoire de Recherche et
|
||||||
// Recherche et Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
// Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de
|
// Copyright (C) 2003-2005 Laboratoire d'Informatique de Paris 6
|
||||||
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
// (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
|
||||||
// Université Pierre et Marie Curie.
|
// Pierre et Marie Curie.
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -992,6 +992,7 @@ namespace spot
|
||||||
trival::repr_t stutter_invariant:2; // Stutter invariant language.
|
trival::repr_t stutter_invariant:2; // Stutter invariant language.
|
||||||
trival::repr_t very_weak:2; // very-weak, or 1-weak
|
trival::repr_t very_weak:2; // very-weak, or 1-weak
|
||||||
trival::repr_t semi_deterministic:2; // semi-deterministic automaton.
|
trival::repr_t semi_deterministic:2; // semi-deterministic automaton.
|
||||||
|
trival::repr_t complete:2; // Complete automaton.
|
||||||
};
|
};
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
|
@ -1267,6 +1268,29 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Whether the automaton is complete..
|
||||||
|
///
|
||||||
|
/// An automaton is complete if for each state the union of the
|
||||||
|
/// labels of its outgoing transitions is always true.
|
||||||
|
///
|
||||||
|
/// Note that this method may return trival::maybe() when it is
|
||||||
|
/// unknown whether the automaton is complete or not. If you
|
||||||
|
/// need a true/false answer, prefer the is_complete() function.
|
||||||
|
///
|
||||||
|
/// \see prop_complete()
|
||||||
|
/// \see is_complete()
|
||||||
|
trival prop_complete() const
|
||||||
|
{
|
||||||
|
return is.complete;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \brief Set the complete property.
|
||||||
|
///
|
||||||
|
/// \see is_complete()
|
||||||
|
void prop_complete(trival val)
|
||||||
|
{
|
||||||
|
is.complete = val.val();
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Whether the automaton is deterministic.
|
/// \brief Whether the automaton is deterministic.
|
||||||
///
|
///
|
||||||
|
|
@ -1404,7 +1428,7 @@ namespace spot
|
||||||
///
|
///
|
||||||
/// This can be used for instance as:
|
/// This can be used for instance as:
|
||||||
/// \code
|
/// \code
|
||||||
/// aut->prop_copy(other_aut, {true, false, false, false, true});
|
/// aut->prop_copy(other_aut, {true, false, false, false, false, true});
|
||||||
/// \endcode
|
/// \endcode
|
||||||
/// This would copy the "state-based acceptance" and
|
/// This would copy the "state-based acceptance" and
|
||||||
/// "stutter invariant" properties from \c other_aut to \c code.
|
/// "stutter invariant" properties from \c other_aut to \c code.
|
||||||
|
|
@ -1428,8 +1452,52 @@ namespace spot
|
||||||
bool inherently_weak; ///< preserve inherently weak, weak, & terminal
|
bool inherently_weak; ///< preserve inherently weak, weak, & terminal
|
||||||
bool deterministic; ///< preserve deterministic, semi-det, unambiguous
|
bool deterministic; ///< preserve deterministic, semi-det, unambiguous
|
||||||
bool improve_det; ///< improves deterministic, semi-det, unambiguous
|
bool improve_det; ///< improves deterministic, semi-det, unambiguous
|
||||||
|
bool complete; ///< preserves completeness
|
||||||
bool stutter_inv; ///< preserve stutter invariance
|
bool stutter_inv; ///< preserve stutter invariance
|
||||||
|
|
||||||
|
prop_set()
|
||||||
|
: state_based(false),
|
||||||
|
inherently_weak(false),
|
||||||
|
deterministic(false),
|
||||||
|
improve_det(false),
|
||||||
|
complete(false),
|
||||||
|
stutter_inv(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_set(bool state_based,
|
||||||
|
bool inherently_weak,
|
||||||
|
bool deterministic,
|
||||||
|
bool improve_det,
|
||||||
|
bool complete,
|
||||||
|
bool stutter_inv)
|
||||||
|
: state_based(state_based),
|
||||||
|
inherently_weak(inherently_weak),
|
||||||
|
deterministic(deterministic),
|
||||||
|
improve_det(improve_det),
|
||||||
|
complete(complete),
|
||||||
|
stutter_inv(stutter_inv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SWIG
|
||||||
|
// The "complete" argument was added in Spot 2.4
|
||||||
|
SPOT_DEPRECATED("prop_set() now takes 6 arguments")
|
||||||
|
prop_set(bool state_based,
|
||||||
|
bool inherently_weak,
|
||||||
|
bool deterministic,
|
||||||
|
bool improve_det,
|
||||||
|
bool stutter_inv)
|
||||||
|
: state_based(state_based),
|
||||||
|
inherently_weak(inherently_weak),
|
||||||
|
deterministic(deterministic),
|
||||||
|
improve_det(improve_det),
|
||||||
|
complete(false),
|
||||||
|
stutter_inv(stutter_inv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief An all-true \c prop_set
|
/// \brief An all-true \c prop_set
|
||||||
///
|
///
|
||||||
/// Use that only in algorithms that copy an automaton without
|
/// Use that only in algorithms that copy an automaton without
|
||||||
|
|
@ -1439,7 +1507,7 @@ namespace spot
|
||||||
/// properties currently implemented, use an explicit
|
/// properties currently implemented, use an explicit
|
||||||
///
|
///
|
||||||
/// \code
|
/// \code
|
||||||
/// {true, true, true, true, true}
|
/// {true, true, true, true, true, true}
|
||||||
/// \endcode
|
/// \endcode
|
||||||
///
|
///
|
||||||
/// instead of calling \c all(). This way, the day a new
|
/// instead of calling \c all(). This way, the day a new
|
||||||
|
|
@ -1447,7 +1515,7 @@ namespace spot
|
||||||
/// algorithm X, in case that new property is not preserved.
|
/// algorithm X, in case that new property is not preserved.
|
||||||
static prop_set all()
|
static prop_set all()
|
||||||
{
|
{
|
||||||
return { true, true, true, true, true };
|
return { true, true, true, true, true, true };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1492,6 +1560,8 @@ namespace spot
|
||||||
prop_unambiguous(true);
|
prop_unambiguous(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (p.complete)
|
||||||
|
prop_complete(other->prop_complete());
|
||||||
if (p.stutter_inv)
|
if (p.stutter_inv)
|
||||||
prop_stutter_invariant(other->prop_stutter_invariant());
|
prop_stutter_invariant(other->prop_stutter_invariant());
|
||||||
}
|
}
|
||||||
|
|
@ -1521,6 +1591,8 @@ namespace spot
|
||||||
if (!(p.improve_det && prop_unambiguous().is_true()))
|
if (!(p.improve_det && prop_unambiguous().is_true()))
|
||||||
prop_unambiguous(trival::maybe());
|
prop_unambiguous(trival::maybe());
|
||||||
}
|
}
|
||||||
|
if (!p.complete)
|
||||||
|
prop_complete(trival::maybe());
|
||||||
if (!p.stutter_inv)
|
if (!p.stutter_inv)
|
||||||
prop_stutter_invariant(trival::maybe());
|
prop_stutter_invariant(trival::maybe());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,14 @@ namespace spot
|
||||||
v = current++;
|
v = current++;
|
||||||
if (current == todo.size())
|
if (current == todo.size())
|
||||||
return; // No unreachable state.
|
return; // No unreachable state.
|
||||||
|
|
||||||
|
// Removing some non-deterministic dead state could make the
|
||||||
|
// automaton deterministic.
|
||||||
|
if (prop_deterministic().is_false())
|
||||||
|
prop_deterministic(trival::maybe());
|
||||||
|
if (prop_complete().is_false())
|
||||||
|
prop_complete(trival::maybe());
|
||||||
|
|
||||||
defrag_states(std::move(todo), current);
|
defrag_states(std::move(todo), current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -393,6 +401,14 @@ namespace spot
|
||||||
useful[s] = -1U;
|
useful[s] = -1U;
|
||||||
if (current == num_states)
|
if (current == num_states)
|
||||||
return; // No useless state.
|
return; // No useless state.
|
||||||
|
|
||||||
|
// Removing some non-deterministic dead state could make the
|
||||||
|
// automaton deterministic. Likewise for non-complete.
|
||||||
|
if (prop_deterministic().is_false())
|
||||||
|
prop_deterministic(trival::maybe());
|
||||||
|
if (prop_complete().is_false())
|
||||||
|
prop_complete(trival::maybe());
|
||||||
|
|
||||||
defrag_states(std::move(useful), current);
|
defrag_states(std::move(useful), current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -362,7 +362,7 @@ namespace spot
|
||||||
res->copy_ap_of(aut_);
|
res->copy_ap_of(aut_);
|
||||||
// We preserve deterministic-like properties, and
|
// We preserve deterministic-like properties, and
|
||||||
// stutter-invariance.
|
// 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_);
|
res->set_generalized_buchi(has_reject_more_ + reject_1_count_);
|
||||||
|
|
||||||
// We for easier computation of outgoing sets, we will
|
// We for easier computation of outgoing sets, we will
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013, 2014, 2015, 2016 Laboratoire de Recherche et
|
// Copyright (C) 2013-2017 Laboratoire de Recherche et Développement
|
||||||
// Développement de l'Epita.
|
// de l'Epita.
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
//
|
//
|
||||||
|
|
@ -21,10 +21,12 @@
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
unsigned complete_here(twa_graph_ptr aut)
|
void complete_here(twa_graph_ptr aut)
|
||||||
{
|
{
|
||||||
unsigned n = aut->num_states();
|
|
||||||
unsigned sink = -1U;
|
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
|
// UM is a pair (bool, mark). If the Boolean is false, the
|
||||||
// acceptance is always satisfiable. Otherwise, MARK is an
|
// 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.
|
// Get rid of any named property if the automaton changed.
|
||||||
if (t < aut->num_edges())
|
if (t < aut->num_edges())
|
||||||
aut->release_named_properties();
|
aut->release_named_properties();
|
||||||
else
|
else
|
||||||
assert(t == aut->num_edges());
|
assert(t == aut->num_edges());
|
||||||
|
|
||||||
return sink;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
twa_graph_ptr complete(const const_twa_ptr& aut)
|
twa_graph_ptr complete(const const_twa_ptr& aut)
|
||||||
{
|
{
|
||||||
auto res = make_twa_graph(aut, {
|
auto res = make_twa_graph(aut, twa::prop_set::all());
|
||||||
true, // state based
|
|
||||||
true, // inherently_weak
|
|
||||||
true, // deterministic
|
|
||||||
true, // improve det
|
|
||||||
true, // stutter inv.
|
|
||||||
});
|
|
||||||
complete_here(res);
|
complete_here(res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- 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.
|
// Développement de l'Epita.
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -25,12 +25,9 @@ namespace spot
|
||||||
{
|
{
|
||||||
/// \brief Complete a twa_graph in place.
|
/// \brief Complete a twa_graph in place.
|
||||||
///
|
///
|
||||||
/// If the TωA has no acceptance set, one will be added. The
|
/// If the TωA has an acceptance condition that is a tautology,
|
||||||
/// returned value is the number of the sink state (it can be a new
|
/// it will be changed into a Büchi automaton.
|
||||||
/// state added for completion, or an existing non-accepting state
|
SPOT_API void complete_here(twa_graph_ptr aut);
|
||||||
/// 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);
|
|
||||||
|
|
||||||
/// \brief Clone a twa and complete it.
|
/// \brief Clone a twa and complete it.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ namespace spot
|
||||||
if (want_sba)
|
if (want_sba)
|
||||||
res->prop_state_acc(true);
|
res->prop_state_acc(true);
|
||||||
// Preserve determinism, weakness, and stutter-invariance
|
// 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
|
// Create an order of acceptance conditions. Each entry in this
|
||||||
// vector correspond to an acceptance set. Each index can
|
// vector correspond to an acceptance set. Each index can
|
||||||
|
|
|
||||||
|
|
@ -641,6 +641,7 @@ namespace spot
|
||||||
{ false, // state based
|
{ false, // state based
|
||||||
false, // inherently_weak
|
false, // inherently_weak
|
||||||
false, false, // deterministic
|
false, false, // deterministic
|
||||||
|
true, // complete
|
||||||
true // stutter inv
|
true // stutter inv
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,8 +160,11 @@ namespace spot
|
||||||
is_colored = colored && (!has_state_acc || nodeadend);
|
is_colored = colored && (!has_state_acc || nodeadend);
|
||||||
// If the automaton declares that it is deterministic or
|
// If the automaton declares that it is deterministic or
|
||||||
// state-based, make sure that it really is.
|
// state-based, make sure that it really is.
|
||||||
assert(deterministic || aut->prop_deterministic() != true);
|
assert(!aut->prop_deterministic().is_known() ||
|
||||||
assert(state_acc || aut->prop_state_acc() != true);
|
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)
|
void number_all_ap(const const_twa_graph_ptr& aut)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012, 2013, 2014, 2015, 2016 Laboratoire de Recherche
|
// Copyright (C) 2012-2017 Laboratoire de Recherche et Développement
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
|
|
@ -134,6 +134,9 @@ namespace spot
|
||||||
bool
|
bool
|
||||||
is_complete(const const_twa_graph_ptr& aut)
|
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();
|
unsigned ns = aut->num_states();
|
||||||
for (unsigned src = 0; src < ns; ++src)
|
for (unsigned src = 0; src < ns; ++src)
|
||||||
{
|
{
|
||||||
|
|
@ -141,11 +144,16 @@ namespace spot
|
||||||
for (auto& t: aut->out(src))
|
for (auto& t: aut->out(src))
|
||||||
available -= t.cond;
|
available -= t.cond;
|
||||||
if (available != bddfalse)
|
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
|
// The empty automaton is not complete since it does not have an
|
||||||
// initial state.
|
// initial state.
|
||||||
return ns > 0;
|
bool res = ns > 0;
|
||||||
|
std::const_pointer_cast<twa_graph>(aut)->prop_complete(res);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- 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).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -26,7 +26,7 @@ namespace spot
|
||||||
{
|
{
|
||||||
auto res = make_twa_graph(in->get_dict());
|
auto res = make_twa_graph(in->get_dict());
|
||||||
res->copy_ap_of(in);
|
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 na = in->num_sets();
|
||||||
unsigned tr = to_remove.count();
|
unsigned tr = to_remove.count();
|
||||||
assert(tr <= na);
|
assert(tr <= na);
|
||||||
|
|
@ -54,7 +54,7 @@ namespace spot
|
||||||
|
|
||||||
auto res = make_twa_graph(in->get_dict());
|
auto res = make_twa_graph(in->get_dict());
|
||||||
res->copy_ap_of(in);
|
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);
|
res->copy_acceptance_of(in);
|
||||||
transform_copy(in, res, [&](unsigned src,
|
transform_copy(in, res, [&](unsigned src,
|
||||||
bdd& cond,
|
bdd& cond,
|
||||||
|
|
@ -76,7 +76,7 @@ namespace spot
|
||||||
|
|
||||||
auto res = make_twa_graph(in->get_dict());
|
auto res = make_twa_graph(in->get_dict());
|
||||||
res->copy_ap_of(in);
|
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);
|
res->copy_acceptance_of(in);
|
||||||
transform_accessible(in, res, [&](unsigned src,
|
transform_accessible(in, res, [&](unsigned src,
|
||||||
bdd& cond,
|
bdd& cond,
|
||||||
|
|
|
||||||
|
|
@ -486,7 +486,7 @@ namespace spot
|
||||||
// final is empty: there is no acceptance condition
|
// final is empty: there is no acceptance condition
|
||||||
build_state_set(det_a, non_final);
|
build_state_set(det_a, non_final);
|
||||||
auto res = minimize_dfa(det_a, final, 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_deterministic(true);
|
||||||
res->prop_weak(true);
|
res->prop_weak(true);
|
||||||
res->prop_state_acc(true);
|
res->prop_state_acc(true);
|
||||||
|
|
@ -595,7 +595,7 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
auto res = minimize_dfa(det_a, final, 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, false, true });
|
||||||
res->prop_deterministic(true);
|
res->prop_deterministic(true);
|
||||||
res->prop_weak(true);
|
res->prop_weak(true);
|
||||||
// If the input was terminal, then the output is also terminal.
|
// If the input was terminal, then the output is also terminal.
|
||||||
|
|
|
||||||
|
|
@ -106,22 +106,21 @@ namespace spot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res->prop_deterministic(left->prop_deterministic()
|
// The product of two non-deterministic automata could be
|
||||||
&& right->prop_deterministic());
|
// deterministic. likewise for non-complete automata.
|
||||||
res->prop_stutter_invariant(left->prop_stutter_invariant()
|
if (left->prop_deterministic() && right->prop_deterministic())
|
||||||
&& right->prop_stutter_invariant());
|
res->prop_deterministic(true);
|
||||||
// The product of X!a and Xa, two stutter-sentive formulas,
|
if (left->prop_complete() && right->prop_complete())
|
||||||
// is stutter-invariant.
|
res->prop_complete(true);
|
||||||
//res->prop_stutter_sensitive(left->prop_stutter_sensitive()
|
if (left->prop_stutter_invariant() && right->prop_stutter_invariant())
|
||||||
// && right->prop_stutter_sensitive());
|
res->prop_stutter_invariant(true);
|
||||||
res->prop_inherently_weak(left->prop_inherently_weak()
|
if (left->prop_inherently_weak() && right->prop_inherently_weak())
|
||||||
&& right->prop_inherently_weak());
|
res->prop_inherently_weak(true);
|
||||||
res->prop_weak(left->prop_weak()
|
if (left->prop_weak() && right->prop_weak())
|
||||||
&& right->prop_weak());
|
res->prop_weak(true);
|
||||||
res->prop_terminal(left->prop_terminal()
|
if (left->prop_terminal() && right->prop_terminal())
|
||||||
&& right->prop_terminal());
|
res->prop_terminal(true);
|
||||||
res->prop_state_acc(left->prop_state_acc()
|
res->prop_state_acc(left->prop_state_acc() && right->prop_state_acc());
|
||||||
&& right->prop_state_acc());
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -224,11 +224,12 @@ namespace spot
|
||||||
unsigned nst = aut->num_states();
|
unsigned nst = aut->num_states();
|
||||||
auto res = make_twa_graph(aut->get_dict());
|
auto res = make_twa_graph(aut->get_dict());
|
||||||
res->copy_ap_of(aut);
|
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->new_states(nst);
|
||||||
res->set_buchi();
|
res->set_buchi();
|
||||||
res->set_init_state(aut->get_init_state_number());
|
res->set_init_state(aut->get_init_state_number());
|
||||||
trival deterministic = aut->prop_deterministic();
|
trival deterministic = aut->prop_deterministic();
|
||||||
|
trival complete = aut->prop_complete();
|
||||||
|
|
||||||
std::vector<unsigned> state_map(aut->num_states());
|
std::vector<unsigned> state_map(aut->num_states());
|
||||||
for (unsigned n = 0; n < scc_max; ++n)
|
for (unsigned n = 0; n < scc_max; ++n)
|
||||||
|
|
@ -245,11 +246,11 @@ namespace spot
|
||||||
for (auto& t: aut->out(s))
|
for (auto& t: aut->out(s))
|
||||||
res->new_acc_edge(s, t.dst, t.cond, acc);
|
res->new_acc_edge(s, t.dst, t.cond, acc);
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
deterministic = false;
|
deterministic = false;
|
||||||
|
complete = trival::maybe();
|
||||||
|
|
||||||
// The main copy is only accepting for inf_alone
|
// The main copy is only accepting for inf_alone
|
||||||
// and for all Inf sets that have no matching Fin
|
// 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->prop_deterministic(deterministic);
|
||||||
|
res->purge_dead_states();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -386,10 +388,11 @@ namespace spot
|
||||||
auto res = make_twa_graph(aut,
|
auto res = make_twa_graph(aut,
|
||||||
{
|
{
|
||||||
true, // state based
|
true, // state based
|
||||||
true, // inherently weak
|
true, // inherently weak
|
||||||
true, true, // determinisitic
|
true, true, // determinisitic
|
||||||
true, // stutter inv.
|
true, // complete
|
||||||
});
|
true, // stutter inv.
|
||||||
|
});
|
||||||
scc_info si(res);
|
scc_info si(res);
|
||||||
|
|
||||||
// We will modify res in place, and the resulting
|
// We will modify res in place, and the resulting
|
||||||
|
|
@ -663,7 +666,7 @@ namespace spot
|
||||||
unsigned nst = aut->num_states();
|
unsigned nst = aut->num_states();
|
||||||
auto res = make_twa_graph(aut->get_dict());
|
auto res = make_twa_graph(aut->get_dict());
|
||||||
res->copy_ap_of(aut);
|
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->new_states(nst);
|
||||||
res->set_acceptance(aut->num_sets() + extra_sets, new_code);
|
res->set_acceptance(aut->num_sets() + extra_sets, new_code);
|
||||||
res->set_init_state(aut->get_init_state_number());
|
res->set_init_state(aut->get_init_state_number());
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de
|
// Copyright (C) 2015-2017 Laboratoire de Recherche et Développement
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
|
|
@ -130,7 +130,7 @@ namespace spot
|
||||||
|
|
||||||
twa_graph_ptr res = make_twa_graph(d);
|
twa_graph_ptr res = make_twa_graph(d);
|
||||||
res->copy_ap_of(aut);
|
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);
|
res->copy_acceptance_of(aut);
|
||||||
|
|
||||||
for (auto ap: props_exist)
|
for (auto ap: props_exist)
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ namespace spot
|
||||||
auto res = make_twa_graph(old->get_dict());
|
auto res = make_twa_graph(old->get_dict());
|
||||||
res->copy_ap_of(old);
|
res->copy_ap_of(old);
|
||||||
res->copy_acceptance_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);
|
res->prop_state_acc(true);
|
||||||
|
|
||||||
typedef std::pair<unsigned, acc_cond::mark_t> pair_t;
|
typedef std::pair<unsigned, acc_cond::mark_t> pair_t;
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ namespace spot
|
||||||
else
|
else
|
||||||
res = scc_filter_apply<state_filter
|
res = scc_filter_apply<state_filter
|
||||||
<acc_filter_mask<false, true>>>(aut, given_si);
|
<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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,6 +417,7 @@ namespace spot
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true, // determinism improved
|
true, // determinism improved
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -451,6 +452,7 @@ namespace spot
|
||||||
{ false, // state-based acceptance is not preserved
|
{ false, // state-based acceptance is not preserved
|
||||||
true,
|
true,
|
||||||
false, false, // determinism may not be preserved
|
false, false, // determinism may not be preserved
|
||||||
|
false,
|
||||||
false, // stutter inv. of suspvars probably altered
|
false, // stutter inv. of suspvars probably altered
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
|
|
|
||||||
|
|
@ -595,6 +595,7 @@ namespace spot
|
||||||
{ false, // state-based acc forced below
|
{ false, // state-based acc forced below
|
||||||
true, // weakness preserved,
|
true, // weakness preserved,
|
||||||
false, true, // determinism improved
|
false, true, // determinism improved
|
||||||
|
true, // completeness preserved
|
||||||
true, // stutter inv.
|
true, // stutter inv.
|
||||||
});
|
});
|
||||||
// !unambiguous and !semi-deterministic are not preserved
|
// !unambiguous and !semi-deterministic are not preserved
|
||||||
|
|
|
||||||
|
|
@ -295,7 +295,7 @@ namespace spot
|
||||||
|
|
||||||
twa_graph_ptr res = make_twa_graph(aut->get_dict());
|
twa_graph_ptr res = make_twa_graph(aut->get_dict());
|
||||||
res->copy_ap_of(aut);
|
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)
|
if (keep & Strong)
|
||||||
res->copy_acceptance_of(aut);
|
res->copy_acceptance_of(aut);
|
||||||
|
|
@ -362,7 +362,7 @@ namespace spot
|
||||||
const_twa_graph_ptr aut = sm.get_aut();
|
const_twa_graph_ptr aut = sm.get_aut();
|
||||||
twa_graph_ptr res = make_twa_graph(aut->get_dict());
|
twa_graph_ptr res = make_twa_graph(aut->get_dict());
|
||||||
res->copy_ap_of(aut);
|
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);
|
res->copy_acceptance_of(aut);
|
||||||
|
|
||||||
auto um = aut->acc().unsat_mark();
|
auto um = aut->acc().unsat_mark();
|
||||||
|
|
|
||||||
|
|
@ -400,10 +400,11 @@ namespace spot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (num_states != a->num_states())
|
if (num_states != a->num_states())
|
||||||
a->prop_keep({true, // state_based
|
a->prop_keep({true, // state_based
|
||||||
false, // inherently_weak
|
false, // inherently_weak
|
||||||
false, false, // deterministic
|
false, false, // deterministic
|
||||||
false, // stutter inv.
|
true, // complete
|
||||||
|
false, // stutter inv.
|
||||||
});
|
});
|
||||||
a->merge_edges();
|
a->merge_edges();
|
||||||
return a;
|
return a;
|
||||||
|
|
@ -423,6 +424,7 @@ namespace spot
|
||||||
a->prop_keep({false, // state_based
|
a->prop_keep({false, // state_based
|
||||||
false, // inherently_weak
|
false, // inherently_weak
|
||||||
false, false, // deterministic
|
false, false, // deterministic
|
||||||
|
true, // complete
|
||||||
false, // stutter inv.
|
false, // stutter inv.
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ namespace spot
|
||||||
|
|
||||||
auto out = make_twa_graph(in->get_dict());
|
auto out = make_twa_graph(in->get_dict());
|
||||||
out->copy_ap_of(in);
|
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);
|
out->set_generalized_buchi(p);
|
||||||
acc_cond::mark_t outall = out->acc().all_sets();
|
acc_cond::mark_t outall = out->acc().all_sets();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Copyright (C) 2014, 2015, 2016 Laboratoire de Recherche et
|
# Copyright (C) 2014-2017 Laboratoire de Recherche et Développement de
|
||||||
# Développement de l'Epita (LRDE).
|
# l'Epita (LRDE).
|
||||||
#
|
#
|
||||||
# This file is part of Spot, a model checking library.
|
# This file is part of Spot, a model checking library.
|
||||||
#
|
#
|
||||||
|
|
@ -367,8 +367,23 @@ State: 1 { 1 }
|
||||||
State: 2 "sink state" { 0 }
|
State: 2 "sink state" { 0 }
|
||||||
2 2 2 2
|
2 2 2 2
|
||||||
--END--
|
--END--
|
||||||
|
HOA: v1.1
|
||||||
|
name: "GFa"
|
||||||
|
States: 1
|
||||||
|
Start: 0
|
||||||
|
AP: 1 "a"
|
||||||
|
acc-name: Buchi
|
||||||
|
Acceptance: 1 Inf(0)
|
||||||
|
properties: trans-labels explicit-labels trans-acc !complete
|
||||||
|
properties: !deterministic stutter-invariant
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[0] 0 {0}
|
||||||
|
[!0] 0
|
||||||
|
--END--
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
err1="this might cause the following errors"
|
||||||
expecterr input <<EOF
|
expecterr input <<EOF
|
||||||
input:9.5-12.7: not enough transitions for this state
|
input:9.5-12.7: not enough transitions for this state
|
||||||
input:10.7-12.7: these transitions have implicit labels but the automaton is...
|
input:10.7-12.7: these transitions have implicit labels but the automaton is...
|
||||||
|
|
@ -377,6 +392,11 @@ input:9.5-12.7: automaton is not complete...
|
||||||
input:7.30-37: ... despite 'properties: complete'
|
input:7.30-37: ... despite 'properties: complete'
|
||||||
input:27.8-10: state label used although the automaton was...
|
input:27.8-10: state label used although the automaton was...
|
||||||
input:25.13-27: ... declared with 'properties: implicit-labels' here
|
input:25.13-27: ... declared with 'properties: implicit-labels' here
|
||||||
|
input:37.6-9: we can read HOA v1 but this file uses v1.1; $err1
|
||||||
|
input:46.9-49.6: automaton is complete...
|
||||||
|
input:44.52-60: ... despite 'properties: !complete'
|
||||||
|
input:46.9-49.6: automaton is deterministic...
|
||||||
|
input:45.13-26: ... despite 'properties: !deterministic'
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat >input<<EOF
|
cat >input<<EOF
|
||||||
|
|
@ -1853,6 +1873,15 @@ properties: !inherently-weak weak
|
||||||
--BODY--
|
--BODY--
|
||||||
State: 0 0
|
State: 0 0
|
||||||
--END--
|
--END--
|
||||||
|
HOA: v1
|
||||||
|
States: 2
|
||||||
|
Start: 0
|
||||||
|
AP: 0
|
||||||
|
Acceptance: 0 t
|
||||||
|
properties: complete
|
||||||
|
--BODY--
|
||||||
|
State: 0 0
|
||||||
|
--END--
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
expecterr input <<EOF
|
expecterr input <<EOF
|
||||||
|
|
@ -1866,6 +1895,8 @@ input:36.36-43: 'properties: terminal' contradicts...
|
||||||
input:36.30-34: ... 'properties: !weak' given here
|
input:36.30-34: ... 'properties: !weak' given here
|
||||||
input:45.30-33: 'properties: weak' contradicts...
|
input:45.30-33: 'properties: weak' contradicts...
|
||||||
input:45.13-28: ... 'properties: !inherently-weak' given here
|
input:45.13-28: ... 'properties: !inherently-weak' given here
|
||||||
|
input:50.1-9: state 1 has no definition...
|
||||||
|
input:54.13-20: ... despite 'properties: complete'
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2051,7 +2082,6 @@ State: 0
|
||||||
--END--
|
--END--
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
err1="this might cause the following errors"
|
|
||||||
expecterr input<<EOF
|
expecterr input<<EOF
|
||||||
input:11.9-11: universal branch used despite previous declaration...
|
input:11.9-11: universal branch used despite previous declaration...
|
||||||
input:7.13-26: ... here
|
input:7.13-26: ... here
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,23 @@
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "",
|
"kernelspec": {
|
||||||
"signature": "sha256:08e64ee189c19ed7e56e5f1c841f51faac25e0bd5e4a6b838856ba8b6f2b5344"
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.5.3"
|
||||||
|
},
|
||||||
|
"name": ""
|
||||||
},
|
},
|
||||||
"nbformat": 3,
|
"nbformat": 3,
|
||||||
"nbformat_minor": 0,
|
"nbformat_minor": 0,
|
||||||
|
|
@ -367,7 +383,7 @@
|
||||||
"output_type": "pyout",
|
"output_type": "pyout",
|
||||||
"prompt_number": 2,
|
"prompt_number": 2,
|
||||||
"text": [
|
"text": [
|
||||||
"<IPython.core.display.HTML at 0x7ff45181d390>"
|
"<IPython.core.display.HTML object>"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -711,7 +727,7 @@
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "display_data",
|
"output_type": "display_data",
|
||||||
"text": [
|
"text": [
|
||||||
"<IPython.core.display.HTML at 0x7ff444140860>"
|
"<IPython.core.display.HTML object>"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -1066,7 +1082,7 @@
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "display_data",
|
"output_type": "display_data",
|
||||||
"text": [
|
"text": [
|
||||||
"<IPython.core.display.HTML at 0x7ff451801208>"
|
"<IPython.core.display.HTML object>"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -1487,7 +1503,7 @@
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "display_data",
|
"output_type": "display_data",
|
||||||
"text": [
|
"text": [
|
||||||
"<IPython.core.display.HTML at 0x7ff44409ef98>"
|
"<IPython.core.display.HTML object>"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1664,7 +1680,7 @@
|
||||||
" result.set_state_names(names)\n",
|
" result.set_state_names(names)\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Loop over all the properties we want to preserve if they hold in both automata\n",
|
" # Loop over all the properties we want to preserve if they hold in both automata\n",
|
||||||
" for p in ('prop_deterministic', 'prop_weak', 'prop_inherently_weak', \n",
|
" for p in ('prop_deterministic', 'prop_complete', 'prop_weak', 'prop_inherently_weak', \n",
|
||||||
" 'prop_terminal', 'prop_stutter_invariant', 'prop_state_acc'):\n",
|
" 'prop_terminal', 'prop_stutter_invariant', 'prop_state_acc'):\n",
|
||||||
" if getattr(left, p)() and getattr(right, p)():\n",
|
" if getattr(left, p)() and getattr(right, p)():\n",
|
||||||
" getattr(result, p)(True)\n",
|
" getattr(result, p)(True)\n",
|
||||||
|
|
@ -1991,7 +2007,7 @@
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "display_data",
|
"output_type": "display_data",
|
||||||
"text": [
|
"text": [
|
||||||
"<IPython.core.display.HTML at 0x7ff44408aa58>"
|
"<IPython.core.display.HTML object>"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -2026,7 +2042,7 @@
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"stream": "stdout",
|
"stream": "stdout",
|
||||||
"text": [
|
"text": [
|
||||||
"1000 loops, best of 3: 342 \u00b5s per loop\n"
|
"1000 loops, best of 3: 206 \u00b5s per loop\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -2045,7 +2061,8 @@
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"stream": "stdout",
|
"stream": "stdout",
|
||||||
"text": [
|
"text": [
|
||||||
"100000 loops, best of 3: 6.44 \u00b5s per loop\n"
|
"The slowest run took 6.27 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
|
||||||
|
"100000 loops, best of 3: 4.2 \u00b5s per loop\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue