decompose: merge decompose_strength() and decompose_scc()

These two functions were doing almost identical work, the only
difference was the way to select the SCC to keep.  Now we have a more
uniform way to do that.  Closes #172.

* bin/autfilt.cc: Offer a unique --decompose-scc option, but keep
--decompose-strength as an alias for backward compatibility.
* spot/twaalgos/strength.cc, spot/twaalgos/strength.hh: Rename
decompose_strength as decompose_scc, and handle a way to list
all SCC numers in the string specifier.  This gets rid
of the nearly identical
* tests/core/scc.test, tests/core/strength.test,
tests/python/decompose.ipynb, tests/python/decompose_scc.py: Adjust
test cases.
* NEWS: Adjust.
This commit is contained in:
Alexandre Duret-Lutz 2017-06-30 23:05:43 +02:00
parent fba3c78206
commit 09e47d648a
8 changed files with 453 additions and 294 deletions

18
NEWS
View file

@ -21,6 +21,10 @@ New in spot 2.3.5.dev (not yet released)
- autfilt learned --simplify-acceptance to simplify some acceptance
conditions. (See spot::simplify_acceptance() below.)
- autfilt --decompote-strength has been renamed to --decompose-scc
because it can now extract the subautomaton leading to an SCC
specified by number. (The old name is still kept as an alias.)
Library:
- A new library, libspotgen, gathers all functions used to generate
@ -41,6 +45,12 @@ New in spot 2.3.5.dev (not yet released)
- spot::dtwa_complement now simply returns the result of dualize()
- spot::decompose_strength() was extended and renamed to
spot::decompose_scc() as it can now also extract a subautomaton
leading to a particular SCC. A demonstration of this feature via
the Python bindings can be found at
https://spot.lrde.epita.fr/ipynb/decompose.html
- A new named property for automata called "original-states" can be
used to record the origin of a state before transformation. It is
currently defined by the degeneralization algorithms, and by
@ -161,6 +171,9 @@ New in spot 2.3.5.dev (not yet released)
Deprecation notice:
- spot::decompose_strength() is deprecated, it has been renamed
to spot::decompose_scc().
- spot::dtwa_complement() is deprecated. Prefer the more generic
spot::dualize() instead.
@ -330,11 +343,6 @@ New in spot 2.3.1 (2017-02-20)
Kupferman & Rosenberg [MoChArt'10] are recognizable by
deterministic Büchi automata with at least 2^2^n states.
- autfilt has a new transformation: --decompose-scc, which allows
decomposition of automata through their accepting SCCs.
A demonstration of this feature via the Python bindings
can be found at https://spot.lrde.epita.fr/ipynb/decompose.html
Library:
- spot::twa_run::as_twa() has an option to preserve state names.

View file

@ -89,7 +89,6 @@ enum {
OPT_COMPLEMENT,
OPT_COMPLEMENT_ACC,
OPT_COUNT,
OPT_DECOMPOSE_STRENGTH,
OPT_DECOMPOSE_SCC,
OPT_DESTUT,
OPT_DUALIZE,
@ -300,11 +299,12 @@ static const argp_option options[] =
{ "complement-acceptance", OPT_COMPLEMENT_ACC, nullptr, 0,
"complement the acceptance condition (without touching the automaton)",
0 },
{ "decompose-strength", OPT_DECOMPOSE_STRENGTH, "t|w|s", 0,
{ "decompose-scc", OPT_DECOMPOSE_SCC, "t|w|s|N|aN", 0,
"extract the (t) terminal, (w) weak, or (s) strong part of an automaton"
" (letters may be combined to combine more strengths in the output)", 0 },
{ "decompose-scc", OPT_DECOMPOSE_SCC, "N", 0, "keep only the Nth accepting"
" SCC as accepting", 0 },
" or (N) the subautomaton leading to the Nth SCC, or (aN) to the Nth "
"accepting SCC (option can be combined with ccomas to extract multiple "
"parts)", 0 },
{ "decompose-strength", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
{ "dualize", OPT_DUALIZE, nullptr, 0,
"dualize each automaton", 0 },
{ "exclusive-ap", OPT_EXCLUSIVE_AP, "AP,AP,...", 0,
@ -495,8 +495,7 @@ static bool opt_rem_fin = false;
static bool opt_clean_acc = false;
static bool opt_complement = false;
static bool opt_complement_acc = false;
static char* opt_decompose_strength = nullptr;
static int opt_decompose_scc = -1;
static char* opt_decompose_scc = nullptr;
static bool opt_dualize = false;
static spot::acc_cond::mark_t opt_mask_acc = 0U;
static std::vector<bool> opt_keep_states = {};
@ -595,11 +594,8 @@ parse_opt(int key, char* arg, struct argp_state*)
case OPT_COMPLEMENT_ACC:
opt_complement_acc = true;
break;
case OPT_DECOMPOSE_STRENGTH:
opt_decompose_strength = arg;
break;
case OPT_DECOMPOSE_SCC:
opt_decompose_scc = to_pos_int(arg);
opt_decompose_scc = arg;
break;
case OPT_DESTUT:
opt_destut = true;
@ -1259,16 +1255,9 @@ namespace
if (opt->sum_and)
aut = spot::sum_and(std::move(aut), opt->sum_and);
if (opt_decompose_strength)
if (opt_decompose_scc)
{
aut = decompose_strength(aut, opt_decompose_strength);
if (!aut)
return 0;
}
if (opt_decompose_scc != -1)
{
aut = decompose_acc_scc(aut, opt_decompose_scc);
aut = decompose_scc(aut, opt_decompose_scc);
if (!aut)
return 0;
}

View file

@ -201,11 +201,11 @@ namespace spot
twa_graph_ptr
decompose_strength(const const_twa_graph_ptr& aut, const char* keep_opt)
decompose_scc(scc_info& si, const char* keep_opt)
{
if (keep_opt == nullptr || *keep_opt == 0)
throw std::runtime_error
(std::string("option for decompose_strength() should not be empty"));
(std::string("option for decompose_scc() should not be empty"));
enum strength {
Ignore = 0,
@ -213,13 +213,70 @@ namespace spot
WeakStrict = 2,
Weak = Terminal | WeakStrict,
Strong = 4,
Needed = 8, // Needed SCCs are those that lead to
// the SCCs we want to keep.
Needed = 8, // Needed SCCs are those that lead to the SCCs we
// want to keep, and also unaccepting SCC we were
// asked to keep.
};
auto aut = si.get_aut();
si.determine_unknown_acceptance();
unsigned n = si.scc_count();
std::vector<unsigned char> want(n, Ignore);
unsigned char keep = Ignore;
while (auto c = *keep_opt++)
switch (c)
{
case ',':
case ' ':
break;
case '0': // SCC number N.
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
char* endptr;
long int scc = strtol(keep_opt - 1, &endptr, 10);
if (scc >= n)
{
throw std::runtime_error
(std::string("decompose_scc(): there is no SCC ")
+ std::to_string(scc) + " in this automaton");
}
keep_opt = endptr;
want[scc] = Needed;
break;
}
case 'a': // Accepting SCC number N.
{
char* endptr;
long int scc = strtol(keep_opt, &endptr, 10);
if (endptr == keep_opt)
throw std::runtime_error
("decompose_scc(): 'a' should be followed by an SCC number");
int j = 0;
for (unsigned s = 0; s < n; ++s)
if (si.is_accepting_scc(s))
if (j++ == scc)
{
want[s] = Needed;
break;
}
if (j != scc + 1)
{
throw std::runtime_error
(std::string("decompose_scc(): there is no SCC 'a")
+ std::to_string(scc) + "' in this automaton");
}
keep_opt = endptr;
break;
}
case 's':
keep |= Strong;
break;
@ -231,12 +288,12 @@ namespace spot
break;
default:
throw std::runtime_error
(std::string("unknown option for decompose_strength(): ") + c);
(std::string("unknown option for decompose_scc(): ") + c);
}
auto p = aut->acc().unsat_mark();
bool all_accepting = !p.first;
acc_cond::mark_t wacc = 0U; // Acceptance for weak SCCs
acc_cond::mark_t wacc = 0U; // acceptance for weak SCCs
acc_cond::mark_t uacc = p.second; // Acceptance for "needed" SCCs, that
// we only want to traverse.
@ -244,42 +301,38 @@ namespace spot
// consider the automaton as weak (even if that is not the
// case syntactically) and not output any strong part.
if (all_accepting)
{
keep &= ~Strong;
if (keep == Ignore)
return nullptr;
}
scc_info si(aut);
si.determine_unknown_acceptance();
unsigned n = si.scc_count();
std::vector<unsigned char> want(n, Ignore);
bool nonempty = false;
bool strong_seen = false;
bool kept_scc_are_weak = true;
bool kept_scc_are_terminal = true;
for (unsigned i = 0; i < n; ++i) // SCC are topologically ordered
{
if (si.is_accepting_scc(i))
{
strength scc_strength = Ignore;
if (all_accepting | is_inherently_weak_scc(si, i))
{
if (keep & Weak)
{
if ((keep & Weak) == Weak)
want[i] = Weak;
scc_strength = is_complete_scc(si, i) ? Terminal : WeakStrict;
else
want[i] = keep &
(is_complete_scc(si, i) ? Terminal : WeakStrict);
}
}
scc_strength = Strong;
if (want[i] == Needed)
want[i] = scc_strength;
else
want[i] = scc_strength & keep;
if (want[i])
{
want[i] = keep & Strong;
strong_seen = true;
if (!(scc_strength & Weak))
kept_scc_are_weak = false;
if (!(scc_strength & Terminal))
kept_scc_are_terminal = false;
}
nonempty |= want[i];
}
nonempty |= want[i]; // also works "Needed" rejecting SCCs
// An SCC is needed if one of its successor is.
for (unsigned j: si.succ(i))
if (want[j])
@ -296,12 +349,12 @@ namespace spot
res->copy_ap_of(aut);
res->prop_copy(aut, { true, false, false, true, false, false });
if (keep & Strong)
res->copy_acceptance_of(aut);
else
if (kept_scc_are_weak)
wacc = res->set_buchi();
else
res->copy_acceptance_of(aut);
auto fun = [&si, &want, uacc, wacc, keep]
auto fun = [&si, &want, uacc, wacc, kept_scc_are_weak]
(unsigned src, bdd& cond, acc_cond::mark_t& acc, unsigned dst)
{
if (want[si.scc_of(dst)] == Ignore)
@ -314,99 +367,35 @@ namespace spot
acc = uacc;
return;
}
if (keep & Strong)
return;
if (kept_scc_are_weak)
acc = wacc;
};
transform_accessible(aut, res, fun);
if (!(keep & Strong))
{
res->prop_weak(true);
if (!(keep & WeakStrict))
{
assert(keep & Terminal);
res->prop_terminal(true);
}
}
else
{
res->prop_weak(!strong_seen);
}
res->prop_weak(kept_scc_are_weak);
res->prop_terminal(kept_scc_are_terminal);
return res;
}
twa_graph_ptr
decompose_scc(scc_info& sm, unsigned scc_num)
{
unsigned n = sm.scc_count();
if (n <= scc_num)
throw std::invalid_argument
(std::string("decompose_scc(): requested SCC index is out of bounds"));
std::vector<bool> want(n, false);
want[scc_num] = true;
// mark all the SCCs that can reach scc_num as wanted
for (unsigned i = scc_num + 1; i < n; ++i)
for (unsigned succ : sm.succ(i))
if (want[succ])
{
want[i] = true;
break;
}
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, false });
res->copy_acceptance_of(aut);
auto um = aut->acc().unsat_mark();
// If aut has an unsatisfying mark, we are going to use it to remove the
// acceptance of some transitions. If it doesn't, we make res a rejecting
// Büchi automaton, and get back an accepting mark that we are going to set
// on the transitions of the SCC we selected.
auto new_mark = um.first ? um.second : res->set_buchi();
auto fun = [sm, &want, um, new_mark, scc_num]
(unsigned src, bdd& cond, acc_cond::mark_t& acc, unsigned dst)
{
if (!want[sm.scc_of(dst)])
{
cond = bddfalse;
return;
}
// no need to check if src is wanted, we already know dst is.
// if res is accepting, make only the upstream SCCs rejecting
// if res is rejecting, make only the requested SCC accepting
if (um.first != (sm.scc_of(src) == scc_num))
acc = new_mark;
};
transform_accessible(aut, res, fun);
return res;
}
twa_graph_ptr
decompose_acc_scc(const const_twa_graph_ptr& aut, int scc_index)
decompose_scc(const const_twa_graph_ptr& aut, const char* keep_opt)
{
scc_info si(aut);
unsigned scc_num = 0;
for (; scc_num < si.scc_count(); ++scc_num)
{
if (si.is_accepting_scc(scc_num))
{
if (!scc_index)
break;
--scc_index;
}
return decompose_scc(si, keep_opt);
}
return decompose_scc(si, scc_num);
twa_graph_ptr
decompose_strength(const const_twa_graph_ptr& aut, const char* keep_opt)
{
return decompose_scc(aut, keep_opt);
}
twa_graph_ptr
decompose_scc(scc_info& sm, unsigned scc_num, bool accepting)
{
std::string num = std::to_string(scc_num);
return decompose_scc(sm, (accepting ? ('a' + num) : num).c_str());
}
}

View file

@ -137,10 +137,14 @@ namespace spot
/// are not terminal.
/// - 't': keep terminal SCCs (i.e., inherently weak SCCs that are complete)
/// - 's': keep strong SCCs (i.e., SCCs that are not inherently weak).
/// Additionally, the string may contain comma-separated numbers representing
/// SCC number, optionally prefixed by 'a' to denote the Nth accepting SCC.
///
/// This algorithm returns a subautomaton that contains all SCCs of the
/// requested strength, plus any upstream SCC (but adjusted not to be
/// accepting).
/// This algorithm returns a subautomaton that contains all SCCs of
/// the requested strength (or given SCC numbers), plus any upstream
/// SCC (but adjusted not to be accepting). The output may be null if
/// no SCC match a given strength. An exception will be raised if
/// an incorrect SCC number is supplied.
///
/// The definition are basically those used in the following paper,
/// except that we extra the "inherently weak" part instead of the
@ -168,27 +172,33 @@ namespace spot
\endverbatim */
///
/// \param aut the automaton to decompose
/// \param keep a string specifying the strengths to keep: it should
/// \param keep a string specifying the strengths/SCCs to keep
SPOT_API twa_graph_ptr
decompose_scc(const const_twa_graph_ptr& aut, const char* keep);
/// \brief Extract a sub-automaton of a given strength
///
/// This works exactly like
/// decompose_scc(const const_twa_graph_ptr&, const char*)
/// but takes an \c scc_info as first argument. This avoids
/// wasting time to reconstruct that object if one is already
/// available.
SPOT_API twa_graph_ptr
decompose_scc(scc_info& sm, const char* keep);
SPOT_DEPRECATED("use decompose_scc() instead")
SPOT_API twa_graph_ptr
decompose_strength(const const_twa_graph_ptr& aut, const char* keep);
/// \brief Extract a sub-automaton of a SCC
/// \brief Extract a sub-automaton above an SCC
///
/// This algorithm returns a subautomaton that contains the requested SCC,
/// plus any upstream SCC (but adjusted not to be accepting).
///
/// \param sm the SCC info map of the automaton
/// \param scc_num the index in the map of the SCC to keep
/// \param accepting if true, scc_num is interpreted as the Nth
/// accepting SCC instead of the Nth SCC
SPOT_API twa_graph_ptr
decompose_scc(scc_info& sm, unsigned scc_num);
/// \brief Extract a sub-automaton of an accepting SCC
///
/// This algorithm returns a subautomaton that contains the `scc_index'th
/// accepting SCC, plus any upstream SCC (but adjusted not to be accepting).
///
/// \param aut the automaton to decompose
/// \param scc_index the ID of the accepting SCC to keep
SPOT_API twa_graph_ptr
decompose_acc_scc(const const_twa_graph_ptr& aut, int scc_index);
decompose_scc(scc_info& sm, unsigned scc_num, bool accepting = false);
}

View file

@ -44,6 +44,7 @@ AP: 2 "a" "b"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic
properties: terminal
--BODY--
State: 0
[1] 1
@ -53,7 +54,7 @@ State: 1 {0}
--END--
EOF
run 0 autfilt --decompose-scc=0 -F aut> out
run 0 autfilt --decompose-scc=a0 aut> out
cat out
diff out ref
@ -65,20 +66,23 @@ AP: 2 "a" "b"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc colored
properties: deterministic
properties: deterministic weak
--BODY--
State: 0 {0}
[0&!1] 0
--END--
EOF
run 0 autfilt --decompose-scc=1 -F aut> out
cat out
run 0 autfilt --decompose-scc=a1 aut> out
diff out ref
autfilt --decompose-scc=2 -F aut 2>stderr && exit 1
autfilt --decompose-scc=a2 aut 2>stderr && exit 1
[ $? -eq 2 ]
grep "out of bounds" stderr
grep "no SCC 'a2'" stderr
autfilt --decompose-scc=2 aut 2>stderr && exit 1
[ $? -eq 2 ]
grep "no SCC 2" stderr
# always satisfied acceptance
ltl2tgba 'Ga R b | Gc R b' > aut
@ -90,7 +94,7 @@ Start: 0
AP: 3 "b" "a" "c"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc
properties: trans-labels explicit-labels state-acc weak
--BODY--
State: 0
[0] 0
@ -100,7 +104,7 @@ State: 1 {0}
--END--
EOF
run 0 autfilt --decompose-scc=1 -F aut> out
run 0 autfilt --decompose-scc=a1 -F aut> out
cat out
diff out ref

View file

@ -368,7 +368,8 @@ Start: 0
AP: 2 "a" "b"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic weak
properties: trans-labels explicit-labels state-acc deterministic
properties: terminal
--BODY--
State: 0
[1] 1
@ -383,7 +384,7 @@ AP: 1 "a"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc colored complete
properties: deterministic weak
properties: deterministic terminal
--BODY--
State: 0 {0}
[0] 1
@ -398,7 +399,7 @@ AP: 1 "a"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc colored complete
properties: deterministic weak
properties: deterministic terminal
--BODY--
State: 0 {0}
[0] 1
@ -413,7 +414,7 @@ AP: 0
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc colored complete
properties: deterministic weak
properties: deterministic terminal
--BODY--
State: 0 {0}
[t] 1
@ -496,7 +497,8 @@ Start: 0
AP: 2 "a" "b"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic weak
properties: trans-labels explicit-labels state-acc deterministic
properties: terminal
--BODY--
State: 0
[1] 1
@ -511,7 +513,7 @@ AP: 1 "a"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc colored complete
properties: deterministic weak
properties: deterministic terminal
--BODY--
State: 0 {0}
[0] 1
@ -523,15 +525,16 @@ HOA: v1
States: 2
Start: 0
AP: 1 "a"
Acceptance: 2 Inf(0) | Inf(1)
properties: trans-labels explicit-labels trans-acc colored complete
properties: deterministic weak
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc colored complete
properties: deterministic terminal
--BODY--
State: 0
[0] 1 {1}
[!0] 0 {0}
State: 1
[t] 0 {0}
State: 0 {0}
[0] 1
[!0] 0
State: 1 {0}
[t] 0
--END--
HOA: v1
States: 2
@ -540,7 +543,7 @@ AP: 0
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc colored complete
properties: deterministic weak
properties: deterministic terminal
--BODY--
State: 0 {0}
[t] 1

View file

@ -15,7 +15,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.3"
"version": "3.5.3+"
},
"name": ""
},
@ -41,9 +41,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook demonstrates how to use the `decompose_strength()` function to split an automaton in up to three automata capturing different behaviors. This is based on the paper [Strength-based decomposition of the property B\u00fcchi automaton for faster model checking](https://www.lrde.epita.fr/~adl/dl/adl/renault.13.tacas.pdf) (TACAS'13).\n",
"This notebook demonstrates how to use the `decompose_scc()` function to split an automaton in up to three automata capturing different behaviors. This is based on the paper [Strength-based decomposition of the property B\u00fcchi automaton for faster model checking](https://www.lrde.epita.fr/~adl/dl/adl/renault.13.tacas.pdf) (TACAS'13).\n",
"\n",
"This page uses the Python bindings, but the same decompositions can be performed from the shell using [`autfilt`](https://spot.lrde.epita.fr/autfilt.html) and its `--decompose-strength` and `--decompose-scc` option.\n",
"This page uses the Python bindings, but the same decompositions can be performed from the shell using [`autfilt`](https://spot.lrde.epita.fr/autfilt.html) and its `--decompose-scc` option.\n",
"\n",
"# Basics\n",
"\n",
@ -211,7 +211,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9690> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f37e0> >"
]
}
],
@ -236,7 +236,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
"spot.decompose_strength(aut, 'w')"
"spot.decompose_scc(aut, 'w')"
],
"language": "python",
"metadata": {},
@ -328,7 +328,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9360> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff545b37570> >"
]
}
],
@ -345,7 +345,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
"spot.decompose_strength(aut, 't')"
"spot.decompose_scc(aut, 't')"
],
"language": "python",
"metadata": {},
@ -469,7 +469,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9510> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5442858a0> >"
]
}
],
@ -486,7 +486,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
"strong = spot.decompose_strength(aut, 's'); strong"
"strong = spot.decompose_scc(aut, 's'); strong"
],
"language": "python",
"metadata": {},
@ -559,7 +559,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9660> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f37b0> >"
]
}
],
@ -636,7 +636,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9ed0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3660> >"
]
}
],
@ -656,7 +656,7 @@
"collapsed": false,
"input": [
"for opt in ('sw', 'st', 'wt'):\n",
" a = spot.decompose_strength(aut, opt)\n",
" a = spot.decompose_scc(aut, opt)\n",
" a.set_name(\"option: \" + opt)\n",
" display(a)"
],
@ -752,7 +752,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a30923420> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f36c0> >"
]
},
{
@ -876,7 +876,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9e40> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3f90> >"
]
},
{
@ -1019,7 +1019,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9540> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f36f0> >"
]
}
],
@ -1424,7 +1424,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777360> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f570> >"
]
}
],
@ -1442,7 +1442,7 @@
"collapsed": false,
"input": [
"for (name, opt) in (('terminal', 't'), ('strictly weak', 'w'), ('strong', 's')):\n",
" a = spot.decompose_strength(aut, opt)\n",
" a = spot.decompose_scc(aut, opt)\n",
" a.set_name(name)\n",
" display(a)"
],
@ -1749,7 +1749,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777450> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f36c0> >"
]
},
{
@ -1946,7 +1946,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d95d0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3540> >"
]
},
{
@ -2126,7 +2126,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9e40> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3720> >"
]
}
],
@ -2145,7 +2145,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
"spot.decompose_strength(aut, \"st\")"
"spot.decompose_scc(aut, \"st\")"
],
"language": "python",
"metadata": {},
@ -2461,7 +2461,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a30923420> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f630> >"
]
}
],
@ -2479,7 +2479,7 @@
"collapsed": false,
"input": [
"for (name, opt) in (('inherently terminal', 't'), ('strictly inherently weak', 'w'), ('strong', 's')):\n",
" a = spot.decompose_strength(aut, opt).postprocess('deterministic', 'SBAcc')\n",
" a = spot.decompose_scc(aut, opt).postprocess('deterministic', 'SBAcc')\n",
" a.set_name(name)\n",
" display(a)"
],
@ -2605,7 +2605,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7774e0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f8a0> >"
]
},
{
@ -2724,7 +2724,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9e70> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f690> >"
]
},
{
@ -2904,7 +2904,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2d0686f0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f4b0> >"
]
}
],
@ -3261,7 +3261,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7774e0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f540> >"
]
}
],
@ -3551,7 +3551,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7773f0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f36c0> >"
]
},
{
@ -3703,7 +3703,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9e40> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f720> >"
]
},
{
@ -3840,7 +3840,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d93f0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f4b0> >"
]
}
],
@ -3859,7 +3859,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
"spot.decompose_strength(aut, 'st')"
"spot.decompose_scc(aut, 'st')"
],
"language": "python",
"metadata": {},
@ -4143,7 +4143,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777510> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420fa20> >"
]
}
],
@ -4254,7 +4254,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777750> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420fc00> >"
]
}
],
@ -4265,7 +4265,7 @@
"collapsed": false,
"input": [
"# There is no strong part for this automaton\n",
"assert spot.decompose_strength(aut, 's') is None"
"assert spot.decompose_scc(aut, 's') is None"
],
"language": "python",
"metadata": {},
@ -4277,7 +4277,7 @@
"collapsed": false,
"input": [
"for opt in ('w', 't'):\n",
" display(spot.decompose_strength(aut, opt))"
" display(spot.decompose_scc(aut, opt))"
],
"language": "python",
"metadata": {},
@ -4346,7 +4346,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777870> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3720> >"
]
},
{
@ -4412,7 +4412,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9ea0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3720> >"
]
}
],
@ -4429,7 +4429,7 @@
"cell_type": "code",
"collapsed": false,
"input": [
"spot.decompose_strength(aut, 'st')"
"spot.decompose_scc(aut, 'st')"
],
"language": "python",
"metadata": {},
@ -4498,7 +4498,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777930> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff544285660> >"
]
}
],
@ -4653,7 +4653,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777990> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3540> >"
]
}
],
@ -4671,7 +4671,7 @@
"collapsed": false,
"input": [
"for (name, opt) in (('terminal', 't'), ('strictly weak', 'w'), ('strong', 's'), ('all strengths', 'swt')):\n",
" a = spot.decompose_strength(aut, opt)\n",
" a = spot.decompose_scc(aut, opt)\n",
" if a:\n",
" a.set_name(name)\n",
" display(a)\n",
@ -4782,7 +4782,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777420> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f3f90> >"
]
},
{
@ -4870,7 +4870,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7d9540> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff5441f36f0> >"
]
},
{
@ -4987,7 +4987,7 @@
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777a50> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f4b0> >"
]
}
],
@ -4999,9 +4999,10 @@
"collapsed": false
},
"source": [
"# `decompose_acc_scc()`\n",
"# `decompose_scc()` by SCC number\n",
"\n",
"Similarly to `decompose_strength()`, the `decompose_acc_scc()` function takes an automaton and the index of an accepting SCC, and preserves only this SCC and its upstream SCCs:"
"Decompose SCC can also be called by SCC numbers.\n",
"The example below show the different SCC numbers and the state they contains, before extracting the sub-automaton containing SCC 1 and 2 (i.e., anything leading to states 1 and 4 of the original automaton). This example also shows that when an `scc_info` is available for to automaton to decompose, it can be passed to `decompose_scc()` in lieu of the automaton: doing so is faster because `decompose_scc()` does not need to rebuild this object. "
]
},
{
@ -5009,11 +5010,169 @@
"collapsed": false,
"input": [
"aut = spot.translate('(Ga -> Gb) W c')\n",
"spot.decompose_acc_scc(aut, 1)"
"si = spot.scc_info(aut)\n",
"for scc in range(si.scc_count()):\n",
" print(\"SCC #{} containts states {}\".format(scc, list(si.states_of(scc))))\n",
"display(aut)\n",
"spot.decompose_scc(si, '1,2')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"SCC #0 containts states [1]\n",
"SCC #1 containts states [2]\n",
"SCC #2 containts states [4]\n",
"SCC #3 containts states [0, 3]\n"
]
},
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"419pt\" height=\"289pt\"\n",
" viewBox=\"0.00 0.00 419.00 289.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 285)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-285 415,-285 415,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"184.5\" y=\"-266.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"206.5\" y=\"-266.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"<text text-anchor=\"start\" x=\"222.5\" y=\"-266.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<g id=\"clust1\" class=\"cluster\"><title>cluster_0</title>\n",
"<polygon fill=\"none\" stroke=\"green\" points=\"351,-148 351,-248 403,-248 403,-148 351,-148\"/>\n",
"</g>\n",
"<g id=\"clust2\" class=\"cluster\"><title>cluster_1</title>\n",
"<polygon fill=\"none\" stroke=\"green\" points=\"164,-8 164,-108 216,-108 216,-8 164,-8\"/>\n",
"</g>\n",
"<g id=\"clust3\" class=\"cluster\"><title>cluster_2</title>\n",
"<polygon fill=\"none\" stroke=\"red\" points=\"268,-148 268,-233 320,-233 320,-148 268,-148\"/>\n",
"</g>\n",
"<g id=\"clust4\" class=\"cluster\"><title>cluster_3</title>\n",
"<polygon fill=\"none\" stroke=\"green\" points=\"30,-135 30,-237 216,-237 216,-135 30,-135\"/>\n",
"</g>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-161\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-157.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-161C2.79388,-161 17.1543,-161 30.6317,-161\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-161 30.9419,-164.15 34.4419,-161 30.9419,-161 30.9419,-161 30.9419,-161 34.4419,-161 30.9418,-157.85 37.9419,-161 37.9419,-161\"/>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-178.037C48.3189,-187.858 50.4453,-197 56,-197 60.166,-197 62.4036,-191.858 62.7128,-185.143\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-178.037 65.8541,-184.882 62.5434,-181.533 62.7076,-185.03 62.7076,-185.03 62.7076,-185.03 62.5434,-181.533 59.561,-185.177 62.3792,-178.037 62.3792,-178.037\"/>\n",
"<text text-anchor=\"start\" x=\"36\" y=\"-215.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"<text text-anchor=\"start\" x=\"48\" y=\"-200.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"377\" cy=\"-174\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"377\" y=\"-170.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.63,-156.447C115.658,-145.684 229.246,-121.222 320,-144 332.58,-147.157 345.419,-153.744 355.624,-159.943\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"361.612,-163.719 354.011,-162.65 358.652,-161.852 355.691,-159.986 355.691,-159.986 355.691,-159.986 358.652,-161.852 357.371,-157.321 361.612,-163.719 361.612,-163.719\"/>\n",
"<text text-anchor=\"start\" x=\"238.5\" y=\"-139.8\" font-family=\"Lato\" font-size=\"14.00\">c</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node4\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"190\" cy=\"-34\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"190\" y=\"-30.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;2 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M63.6726,-144.642C69.681,-131.298 79.4843,-112.511 92,-99 113.848,-75.4146 145.853,-56.1055 167.046,-44.8262\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"173.253,-41.5877 168.504,-47.6186 170.15,-43.2068 167.047,-44.8259 167.047,-44.8259 167.047,-44.8259 170.15,-43.2068 165.59,-42.0332 173.253,-41.5877 173.253,-41.5877\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-102.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; b &amp; !c</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node6\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"190\" cy=\"-176\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"190\" y=\"-172.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;3 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>0&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.0161,-159.298C93.5381,-157.777 126.41,-156.539 154,-162 158.195,-162.83 162.529,-164.149 166.657,-165.652\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"173.35,-168.304 165.682,-168.654 170.096,-167.015 166.842,-165.726 166.842,-165.726 166.842,-165.726 170.096,-167.015 168.002,-162.797 173.35,-168.304 173.35,-168.304\"/>\n",
"<text text-anchor=\"start\" x=\"105\" y=\"-165.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !c</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M369.969,-190.664C368.406,-200.625 370.75,-210 377,-210 381.688,-210 384.178,-204.727 384.471,-197.888\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"384.031,-190.664 387.601,-197.46 384.244,-194.158 384.456,-197.651 384.456,-197.651 384.456,-197.651 384.244,-194.158 381.312,-197.842 384.031,-190.664 384.031,-190.664\"/>\n",
"<text text-anchor=\"start\" x=\"372.5\" y=\"-228.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"<text text-anchor=\"start\" x=\"369\" y=\"-213.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M181.021,-49.916C178.679,-60.1504 181.672,-70 190,-70 196.376,-70 199.625,-64.2263 199.746,-56.9268\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"198.979,-49.916 202.872,-56.5315 199.36,-53.3952 199.741,-56.8744 199.741,-56.8744 199.741,-56.8744 199.36,-53.3952 196.61,-57.2174 198.979,-49.916 198.979,-49.916\"/>\n",
"<text text-anchor=\"start\" x=\"185.5\" y=\"-88.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"<text text-anchor=\"start\" x=\"182\" y=\"-73.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node5\" class=\"node\"><title>4</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"294\" cy=\"-174\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"294\" y=\"-170.3\" font-family=\"Lato\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;1 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>4&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M312.178,-174C323.669,-174 338.959,-174 351.693,-174\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"358.847,-174 351.847,-177.15 355.347,-174 351.847,-174 351.847,-174 351.847,-174 355.347,-174 351.847,-170.85 358.847,-174 358.847,-174\"/>\n",
"<text text-anchor=\"start\" x=\"330\" y=\"-177.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;4 -->\n",
"<g id=\"edge13\" class=\"edge\"><title>4&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M286.969,-190.664C285.406,-200.625 287.75,-210 294,-210 298.688,-210 301.178,-204.727 301.471,-197.888\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"301.031,-190.664 304.601,-197.46 301.244,-194.158 301.456,-197.651 301.456,-197.651 301.456,-197.651 301.244,-194.158 298.312,-197.842 301.031,-190.664 301.031,-190.664\"/>\n",
"<text text-anchor=\"start\" x=\"290.5\" y=\"-213.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;0 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>3&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M171.945,-178.448C152.386,-180.735 119.481,-182.984 92,-177 87.5445,-176.03 82.977,-174.44 78.6739,-172.629\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"72.1836,-169.66 79.8596,-169.708 75.3664,-171.116 78.5492,-172.572 78.5492,-172.572 78.5492,-172.572 75.3664,-171.116 77.2387,-175.437 72.1836,-169.66 72.1836,-169.66\"/>\n",
"<text text-anchor=\"start\" x=\"103\" y=\"-199.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"<text text-anchor=\"start\" x=\"115\" y=\"-184.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;1 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>3&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M202.448,-189.329C216.236,-204.254 240.941,-227.581 268,-237 289.826,-244.598 298.917,-246.468 320,-237 338.806,-228.555 353.873,-210.326 363.62,-195.64\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"367.468,-189.601 366.363,-197.197 365.587,-192.553 363.706,-195.504 363.706,-195.504 363.706,-195.504 365.587,-192.553 361.05,-193.812 367.468,-189.601 367.468,-189.601\"/>\n",
"<text text-anchor=\"start\" x=\"276\" y=\"-246.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; c</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>3&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M208.303,-175.661C224.962,-175.334 250.303,-174.837 268.927,-174.472\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"275.953,-174.334 269.016,-177.621 272.453,-174.403 268.954,-174.472 268.954,-174.472 268.954,-174.472 272.453,-174.403 268.892,-171.322 275.953,-174.334 275.953,-174.334\"/>\n",
"<text text-anchor=\"start\" x=\"226\" y=\"-179.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; c</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M181.021,-191.916C178.679,-202.15 181.672,-212 190,-212 196.376,-212 199.625,-206.226 199.746,-198.927\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"198.979,-191.916 202.872,-198.532 199.36,-195.395 199.741,-198.874 199.741,-198.874 199.741,-198.874 199.36,-195.395 196.61,-199.217 198.979,-191.916 198.979,-191.916\"/>\n",
"<text text-anchor=\"start\" x=\"172\" y=\"-215.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !c</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420fea0> >"
]
},
{
"metadata": {},
"output_type": "pyout",
@ -5025,18 +5184,21 @@
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"232pt\" height=\"242pt\"\n",
" viewBox=\"0.00 0.00 232.00 242.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<svg width=\"336pt\" height=\"242pt\"\n",
" viewBox=\"0.00 0.00 336.00 242.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 238)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-238 228,-238 228,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"91\" y=\"-219.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"113\" y=\"-219.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"<text text-anchor=\"start\" x=\"129\" y=\"-219.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-238 332,-238 332,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"143\" y=\"-219.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"165\" y=\"-219.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"<text text-anchor=\"start\" x=\"181\" y=\"-219.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<g id=\"clust1\" class=\"cluster\"><title>cluster_0</title>\n",
"<polygon fill=\"none\" stroke=\"green\" points=\"164,-8 164,-108 216,-108 216,-8 164,-8\"/>\n",
"</g>\n",
"<g id=\"clust2\" class=\"cluster\"><title>cluster_1</title>\n",
"<polygon fill=\"none\" stroke=\"grey\" points=\"268,-117 268,-202 320,-202 320,-117 268,-117\"/>\n",
"</g>\n",
"<g id=\"clust3\" class=\"cluster\"><title>cluster_2</title>\n",
"<polygon fill=\"none\" stroke=\"red\" points=\"30,-116 30,-203 216,-203 216,-116 30,-116\"/>\n",
"</g>\n",
"<!-- I -->\n",
@ -5068,7 +5230,7 @@
"<text text-anchor=\"start\" x=\"92\" y=\"-117.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; b &amp; !c</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node4\" class=\"node\"><title>2</title>\n",
"<g id=\"node5\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"190\" cy=\"-143\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"190\" y=\"-139.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
@ -5080,28 +5242,45 @@
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M179.087,-48.4167C175.276,-59.166 178.914,-70 190,-70 198.661,-70 202.776,-63.3875 202.344,-55.3688\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"200.913,-48.4167 205.41,-54.6375 201.619,-51.8447 202.325,-55.2728 202.325,-55.2728 202.325,-55.2728 201.619,-51.8447 199.239,-55.9082 200.913,-48.4167 200.913,-48.4167\"/>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M181.021,-49.916C178.679,-60.1504 181.672,-70 190,-70 196.376,-70 199.625,-64.2263 199.746,-56.9268\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"198.979,-49.916 202.872,-56.5315 199.36,-53.3952 199.741,-56.8744 199.741,-56.8744 199.741,-56.8744 199.36,-53.3952 196.61,-57.2174 198.979,-49.916 198.979,-49.916\"/>\n",
"<text text-anchor=\"start\" x=\"185.5\" y=\"-88.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"<text text-anchor=\"start\" x=\"182\" y=\"-73.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node4\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"294\" cy=\"-143\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"294\" y=\"-139.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M285.021,-158.916C282.679,-169.15 285.672,-179 294,-179 300.376,-179 303.625,-173.226 303.746,-165.927\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"302.979,-158.916 306.872,-165.532 303.36,-162.395 303.741,-165.874 303.741,-165.874 303.741,-165.874 303.36,-162.395 300.61,-166.217 302.979,-158.916 302.979,-158.916\"/>\n",
"<text text-anchor=\"start\" x=\"290.5\" y=\"-182.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;0 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>2&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M173.759,-151.123C167.774,-153.883 160.735,-156.618 154,-158 127.007,-163.54 118.925,-163.862 92,-158 87.5445,-157.03 82.977,-155.44 78.6739,-153.629\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"72.1836,-150.66 79.8596,-150.708 75.3664,-152.116 78.5492,-153.572 78.5492,-153.572 78.5492,-153.572 75.3664,-152.116 77.2387,-156.437 72.1836,-150.66 72.1836,-150.66\"/>\n",
"<text text-anchor=\"start\" x=\"103\" y=\"-165.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>2&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M208.303,-143C224.962,-143 250.303,-143 268.927,-143\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"275.953,-143 268.953,-146.15 272.453,-143 268.953,-143 268.953,-143 268.953,-143 272.453,-143 268.953,-139.85 275.953,-143 275.953,-143\"/>\n",
"<text text-anchor=\"start\" x=\"226\" y=\"-146.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; c</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M179.087,-157.417C175.276,-168.166 178.914,-179 190,-179 198.661,-179 202.776,-172.387 202.344,-164.369\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"200.913,-157.417 205.41,-163.637 201.619,-160.845 202.325,-164.273 202.325,-164.273 202.325,-164.273 201.619,-160.845 199.239,-164.908 200.913,-157.417 200.913,-157.417\"/>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M181.021,-158.916C178.679,-169.15 181.672,-179 190,-179 196.376,-179 199.625,-173.226 199.746,-165.927\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"198.979,-158.916 202.872,-165.532 199.36,-162.395 199.741,-165.874 199.741,-165.874 199.741,-165.874 199.36,-162.395 196.61,-166.217 198.979,-158.916 198.979,-158.916\"/>\n",
"<text text-anchor=\"start\" x=\"172\" y=\"-182.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !c</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c777870> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f060> >"
]
}
],
@ -5109,21 +5288,16 @@
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"metadata": {},
"source": [
"# `decompose_scc()`\n",
"\n",
"You can also, like in the C++ interface, use a `scc_info` to extract a particular SCC and its parents, even non accepting."
"If an SCC number N is prefixed by `a`, it signifies that we want to extract the Nth *accepting* SCC. In the above example SCC 2 is rejecting so SCC `a2` denotes SCC 3."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"si = spot.scc_info(aut)\n",
"spot.decompose_scc(si, 2)"
"spot.decompose_scc(si, 'a2')"
],
"language": "python",
"metadata": {},
@ -5139,19 +5313,16 @@
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"314pt\" height=\"134pt\"\n",
" viewBox=\"0.00 0.00 314.00 134.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 130)\">\n",
"<svg width=\"210pt\" height=\"149pt\"\n",
" viewBox=\"0.00 0.00 210.00 149.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 145)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-130 310,-130 310,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"132\" y=\"-111.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"154\" y=\"-111.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"<text text-anchor=\"start\" x=\"170\" y=\"-111.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-145 206,-145 206,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"80\" y=\"-126.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"102\" y=\"-126.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"<text text-anchor=\"start\" x=\"118\" y=\"-126.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<g id=\"clust1\" class=\"cluster\"><title>cluster_0</title>\n",
"<polygon fill=\"none\" stroke=\"grey\" points=\"246,-9 246,-94 298,-94 298,-9 246,-9\"/>\n",
"</g>\n",
"<g id=\"clust2\" class=\"cluster\"><title>cluster_1</title>\n",
"<polygon fill=\"none\" stroke=\"grey\" points=\"30,-8 30,-95 194,-95 194,-8 30,-8\"/>\n",
"<polygon fill=\"none\" stroke=\"green\" points=\"30,-8 30,-110 194,-110 194,-8 30,-8\"/>\n",
"</g>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
@ -5168,53 +5339,38 @@
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-52.0373C48.3189,-61.8579 50.4453,-71 56,-71 60.166,-71 62.4036,-65.8576 62.7128,-59.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-52.0373 65.8541,-58.8818 62.5434,-55.5335 62.7076,-59.0296 62.7076,-59.0296 62.7076,-59.0296 62.5434,-55.5335 59.561,-59.1774 62.3792,-52.0373 62.3792,-52.0373\"/>\n",
"<text text-anchor=\"start\" x=\"36\" y=\"-74.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"<text text-anchor=\"start\" x=\"36\" y=\"-89.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"<text text-anchor=\"start\" x=\"48\" y=\"-74.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node4\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"168\" cy=\"-35\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"168\" y=\"-31.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"168\" cy=\"-42\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"168\" y=\"-38.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.1875,-35C92.5925,-35 121.947,-35 142.709,-35\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.933,-35 142.933,-38.1501 146.433,-35 142.933,-35.0001 142.933,-35.0001 142.933,-35.0001 146.433,-35 142.933,-31.8501 149.933,-35 149.933,-35\"/>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.0256,-34.0467C89.2577,-33.4204 112.175,-33.0369 132,-35 135.683,-35.3646 139.552,-35.9401 143.32,-36.6081\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"150.366,-37.9759 142.894,-39.7343 146.93,-37.3089 143.495,-36.642 143.495,-36.642 143.495,-36.642 146.93,-37.3089 144.095,-33.5497 150.366,-37.9759 150.366,-37.9759\"/>\n",
"<text text-anchor=\"start\" x=\"94\" y=\"-38.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !c</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node3\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"272\" cy=\"-35\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"272\" y=\"-31.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M263.021,-50.916C260.679,-61.1504 263.672,-71 272,-71 278.376,-71 281.625,-65.2263 281.746,-57.9268\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"280.979,-50.916 284.872,-57.5315 281.36,-54.3952 281.741,-57.8744 281.741,-57.8744 281.741,-57.8744 281.36,-54.3952 278.61,-58.2174 280.979,-50.916 280.979,-50.916\"/>\n",
"<text text-anchor=\"start\" x=\"268.5\" y=\"-74.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;0 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M151.759,-43.1226C145.774,-45.8828 138.735,-48.6176 132,-50 114.585,-53.5745 109.415,-53.5745 92,-50 87.5802,-49.0928 83.0294,-47.6032 78.7315,-45.9062\"/>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M150.474,-46.6588C135.183,-50.2874 111.882,-54.081 92,-50 87.5802,-49.0928 83.0294,-47.6032 78.7315,-45.9062\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"72.2412,-43.1226 79.9161,-42.9868 75.4579,-44.5022 78.6745,-45.8818 78.6745,-45.8818 78.6745,-45.8818 75.4579,-44.5022 77.4329,-48.7768 72.2412,-43.1226 72.2412,-43.1226\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-55.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;2 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>1&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M186.303,-35C202.962,-35 228.303,-35 246.927,-35\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"253.953,-35 246.953,-38.1501 250.453,-35 246.953,-35.0001 246.953,-35.0001 246.953,-35.0001 250.453,-35 246.953,-31.8501 253.953,-35 253.953,-35\"/>\n",
"<text text-anchor=\"start\" x=\"204\" y=\"-38.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; c</text>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-69.8\" font-family=\"Lato\" font-size=\"14.00\">!a &amp; !c</text>\n",
"<text text-anchor=\"start\" x=\"104\" y=\"-54.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M159.021,-50.916C156.679,-61.1504 159.672,-71 168,-71 174.376,-71 177.625,-65.2263 177.746,-57.9268\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"176.979,-50.916 180.872,-57.5315 177.36,-54.3952 177.741,-57.8744 177.741,-57.8744 177.741,-57.8744 177.36,-54.3952 174.61,-58.2174 176.979,-50.916 176.979,-50.916\"/>\n",
"<text text-anchor=\"start\" x=\"150\" y=\"-74.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !c</text>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M158.425,-57.5414C155.73,-67.9087 158.922,-78 168,-78 174.95,-78 178.45,-72.0847 178.499,-64.6591\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"177.575,-57.5414 181.6,-64.0771 178.026,-61.0123 178.477,-64.4831 178.477,-64.4831 178.477,-64.4831 178.026,-61.0123 175.353,-64.889 177.575,-57.5414 177.575,-57.5414\"/>\n",
"<text text-anchor=\"start\" x=\"150\" y=\"-81.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !c</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f3a2c7941b0> >"
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7ff54420f4e0> >"
]
}
],

View file

@ -29,7 +29,7 @@ AP: 3 "b" "a" "c"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc !complete
properties: deterministic
properties: deterministic terminal
--BODY--
State: 0
[!1&!2] 0
@ -44,19 +44,19 @@ State: 2
try:
spot.decompose_scc(si, 4)
except ValueError:
except RuntimeError:
pass
else:
raise AssertionError
assert (spot.decompose_acc_scc(aut, 0).to_str('hoa', '1.1') == """HOA: v1.1
assert (spot.decompose_scc(si, 0, True).to_str('hoa', '1.1') == """HOA: v1.1
States: 4
Start: 0
AP: 3 "b" "a" "c"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete
properties: deterministic
properties: deterministic terminal
--BODY--
State: 0
[!1&!2] 0
@ -74,14 +74,14 @@ State: 3
[1] 3
--END--""")
assert (spot.decompose_acc_scc(aut, 2).to_str('hoa', '1.1') == """HOA: v1.1
assert (spot.decompose_scc(si, 2, True).to_str('hoa', '1.1') == """HOA: v1.1
States: 2
Start: 0
AP: 3 "b" "a" "c"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels trans-acc !complete
properties: deterministic
properties: deterministic !weak
--BODY--
State: 0
[!1&!2] 0 {0}
@ -92,8 +92,8 @@ State: 1
--END--""")
try:
spot.decompose_acc_scc(aut, 3)
except ValueError:
spot.decompose_scc(si, 3, True)
except RuntimeError:
pass
else:
raise AssertionError