sbacc: improve using SCCs and common marks

* spot/twaalgos/sbacc.cc: Here.
* tests/core/parseaut.test, tests/python/automata.ipynb: Adjust.
* tests/core/sbacc.test: Likewise + more tests.
* NEWS: Mention it.
This commit is contained in:
Alexandre Duret-Lutz 2016-07-31 22:57:50 +02:00
parent d271dfd592
commit d2068bb1a0
5 changed files with 157 additions and 115 deletions

6
NEWS
View file

@ -117,6 +117,12 @@ New in spot 2.0.3a (not yet released)
the corresponding properties of the automaton as a side-effect of the corresponding properties of the automaton as a side-effect of
their check. their check.
* the sbacc() function, used by "ltl2tgba -S" and "autfilt -S" to
convert automata to state-based acceptance, learned some tricks
(using SCCs, pulling accepting marks common to all outgoing edges,
and pushing acceptance marks common to all incoming edges) to
reduce the number of additional states needed.
* language_containment_checker now has default values for all * language_containment_checker now has default values for all
parameters of its constructor. parameters of its constructor.

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2015 Laboratoire de Recherche et Développement // Copyright (C) 2015, 2016 Laboratoire de Recherche et 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,6 +21,7 @@
#include <map> #include <map>
#include <utility> #include <utility>
#include <spot/twaalgos/sbacc.hh> #include <spot/twaalgos/sbacc.hh>
#include <spot/twaalgos/sccinfo.hh>
namespace spot namespace spot
{ {
@ -29,6 +30,26 @@ namespace spot
if (old->prop_state_acc()) if (old->prop_state_acc())
return old; return old;
scc_info si(old);
unsigned ns = old->num_states();
acc_cond::mark_t all = old->acc().all_sets();
std::vector<acc_cond::mark_t> common_in(ns, all);
std::vector<acc_cond::mark_t> common_out(ns, all);
std::vector<acc_cond::mark_t> one_in(ns, 0U);
for (auto& e: old->edges())
if (si.scc_of(e.src) == si.scc_of(e.dst))
{
common_in[e.dst] &= e.acc;
common_out[e.src] &= e.acc;
one_in[e.dst] = e.acc;
}
for (unsigned s = 0; s < ns; ++s)
common_out[s] |= common_in[s];
for (auto& e: old->edges())
if (si.scc_of(e.src) == si.scc_of(e.dst))
one_in[e.dst] = (e.acc - common_out[e.src]);
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);
@ -54,28 +75,39 @@ namespace spot
return p.first->second; return p.first->second;
}; };
// Find any edge going into the initial state, and use its
// acceptance as mark.
acc_cond::mark_t init_acc = 0U;
unsigned old_init = old->get_init_state_number(); unsigned old_init = old->get_init_state_number();
for (auto& t: old->edges()) acc_cond::mark_t init_acc = 0U;
if (t.dst == old_init) if (!si.is_rejecting_scc(si.scc_of(old_init)))
{ // Use any edge going into the initial state to set the first
init_acc = t.acc; // acceptance mark.
break; init_acc = one_in[old_init] | common_out[init_acc];
}
res->set_init_state(new_state(old_init, init_acc)); res->set_init_state(new_state(old_init, init_acc));
while (!todo.empty()) while (!todo.empty())
{ {
auto one = todo.back(); auto one = todo.back();
todo.pop_back(); todo.pop_back();
unsigned scc_src = si.scc_of(one.first.first);
bool maybe_accepting = !si.is_rejecting_scc(scc_src);
for (auto& t: old->out(one.first.first)) for (auto& t: old->out(one.first.first))
res->new_edge(one.second, {
new_state(t.dst, t.acc), unsigned scc_dst = si.scc_of(t.dst);
t.cond, acc_cond::mark_t acc = 0U;
one.first.second); bool dst_acc = si.is_accepting_scc(scc_dst);
if (maybe_accepting && scc_src == scc_dst)
acc = t.acc - common_out[t.src];
else if (dst_acc)
// We enter a new accepting SCC. Use any edge going into
// t.dst from this SCC to set the initial acceptance mark.
acc = one_in[t.dst];
if (dst_acc)
acc |= common_out[t.dst];
common_out[t.dst];
res->new_edge(one.second, new_state(t.dst, acc),
t.cond, one.first.second);
} }
}
res->merge_edges();
return res; return res;
} }
} }

View file

@ -1755,14 +1755,14 @@ State: 0
1 0 2 2 1 0 2 2 1 0 2 2 1 0 2 2 1 0 2 2 1 0 2 2 1 0 2 2 1 0 2 2
State: 1 State: 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
State: 2 State: 2 {0 1}
2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 3 3 3 3 4 4 4 4 5 5 5 5 2 2 2 2
State: 3 {0} State: 3
2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 3 3 3 3 4 4 4 4 5 5 5 5 2 2 2 2
State: 4 {1} State: 4 {0}
2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 3 3 3 3 4 4 4 4 5 5 5 5 2 2 2 2
State: 5 {0 1} State: 5 {1}
2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 3 3 3 3 4 4 4 4 5 5 5 5 2 2 2 2
--END-- --END--
EOF EOF

View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2015 Laboratoire de Recherche et Développement # Copyright (C) 2015, 2016 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.
@ -37,26 +37,26 @@ Acceptance: 2 Inf(0)&Inf(1)
properties: trans-labels explicit-labels state-acc complete properties: trans-labels explicit-labels state-acc complete
properties: deterministic stutter-invariant properties: deterministic stutter-invariant
--BODY-- --BODY--
State: 0 {0 1} State: 0 {0}
[0&1] 0 [0&!1] 0
[!0&!1] 1 [0&1] 1
[!0&1] 2 [!0&!1] 2
[0&!1] 3 [!0&1] 3
State: 1 State: 1 {0 1}
[0&1] 0 [0&!1] 0
[!0&!1] 1 [0&1] 1
[!0&1] 2 [!0&!1] 2
[0&!1] 3 [!0&1] 3
State: 2 {1} State: 2
[0&1] 0 [0&!1] 0
[!0&!1] 1 [0&1] 1
[!0&1] 2 [!0&!1] 2
[0&!1] 3 [!0&1] 3
State: 3 {0} State: 3 {1}
[0&1] 0 [0&!1] 0
[!0&!1] 1 [0&1] 1
[!0&1] 2 [!0&!1] 2
[0&!1] 3 [!0&1] 3
--END-- --END--
EOF EOF
@ -91,9 +91,9 @@ properties: trans-labels explicit-labels state-acc deterministic
--BODY-- --BODY--
State: 0 {1} State: 0 {1}
[0] 1 [0] 1
State: 1 State: 1 {0}
[0] 2 [0] 2
State: 2 {0} State: 2 {0 1}
[0] 0 [0] 0
--END-- --END--
EOF EOF
@ -124,4 +124,8 @@ EOF
diff out.hoa expected diff out.hoa expected
randltl --weak-fairness -n 20 2 | randltl --weak-fairness -n 20 2 |
ltlcross "$ltl2tgba -DH %f >%O" "$ltl2tgba -H %f | $autfilt -H >%O" ltlcross "$ltl2tgba -DH %f >%O" \
"$ltl2tgba -S %f >%O" \
"$ltl2tgba -H %f | $autfilt -H >%O"
test 4 = `ltl2tgba -S 'F(a & X(!a &Xb))' --any --stats=%s`

View file

@ -18,7 +18,7 @@
"version": "3.4.3+" "version": "3.4.3+"
}, },
"name": "", "name": "",
"signature": "sha256:91af67353e0a35fefd672b53bd005af28720c0c7a8dfc922ce70fa8f3ef6a42e" "signature": "sha256:4ddb9b8fc1c41bacd7e47f70861303cde0ad425f842ade8e1f23ee74738914b0"
}, },
"nbformat": 3, "nbformat": 3,
"nbformat_minor": 0, "nbformat_minor": 0,
@ -178,7 +178,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc0c24900> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe334de9900> >"
] ]
} }
], ],
@ -317,7 +317,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc18bd1d0>" "<IPython.core.display.SVG at 0x7fe335a6c0f0>"
] ]
} }
], ],
@ -470,7 +470,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc013a710>" "<IPython.core.display.SVG at 0x7fe3340e5588>"
] ]
} }
], ],
@ -570,7 +570,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e1b0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c8331b0> >"
] ]
} }
], ],
@ -640,7 +640,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e060> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c833060> >"
] ]
} }
], ],
@ -716,7 +716,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e0f0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c8330f0> >"
] ]
} }
], ],
@ -839,7 +839,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc013a908>" "<IPython.core.display.SVG at 0x7fe3340e56d8>"
] ]
} }
], ],
@ -1029,7 +1029,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc0101978>" "<IPython.core.display.SVG at 0x7fe3340aba20>"
] ]
} }
], ],
@ -1176,7 +1176,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e300> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c833300> >"
] ]
} }
], ],
@ -1277,7 +1277,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e2d0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c8332d0> >"
] ]
} }
], ],
@ -1310,92 +1310,92 @@
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n", " -->\n",
"<!-- Title: G Pages: 1 -->\n", "<!-- Title: G Pages: 1 -->\n",
"<svg width=\"258pt\" height=\"180pt\"\n", "<svg width=\"266pt\" height=\"176pt\"\n",
" viewBox=\"0.00 0.00 258.00 180.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", " viewBox=\"0.00 0.00 266.00 176.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 176)\">\n", "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 172)\">\n",
"<title>G</title>\n", "<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-176 254,-176 254,4 -4,4\"/>\n", "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-172 262,-172 262,4 -4,4\"/>\n",
"<!-- I -->\n", "<!-- I -->\n",
"<!-- 0 -->\n", "<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n", "<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-76\" rx=\"18\" ry=\"18\"/>\n", "<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-73\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-72.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n", "<text text-anchor=\"middle\" x=\"56\" y=\"-69.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n", "</g>\n",
"<!-- I&#45;&gt;0 -->\n", "<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n", "<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-76C2.79388,-76 17.1543,-76 30.6317,-76\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-73C2.79388,-73 17.1543,-73 30.6317,-73\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-76 30.9419,-79.1501 34.4419,-76 30.9419,-76.0001 30.9419,-76.0001 30.9419,-76.0001 34.4419,-76 30.9418,-72.8501 37.9419,-76 37.9419,-76\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-73 30.9419,-76.1501 34.4419,-73 30.9419,-73.0001 30.9419,-73.0001 30.9419,-73.0001 34.4419,-73 30.9418,-69.8501 37.9419,-73 37.9419,-73\"/>\n",
"</g>\n", "</g>\n",
"<!-- 0&#45;&gt;0 -->\n", "<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;0</title>\n", "<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-93.0373C48.3189,-102.858 50.4453,-112 56,-112 60.166,-112 62.4036,-106.858 62.7128,-100.143\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-90.0373C48.3189,-99.8579 50.4453,-109 56,-109 60.166,-109 62.4036,-103.858 62.7128,-97.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-93.0373 65.8541,-99.8818 62.5434,-96.5335 62.7076,-100.03 62.7076,-100.03 62.7076,-100.03 62.5434,-96.5335 59.561,-100.177 62.3792,-93.0373 62.3792,-93.0373\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-90.0373 65.8541,-96.8818 62.5434,-93.5335 62.7076,-97.0296 62.7076,-97.0296 62.7076,-97.0296 62.5434,-93.5335 59.561,-97.1774 62.3792,-90.0373 62.3792,-90.0373\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-115.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n", "<text text-anchor=\"start\" x=\"51.5\" y=\"-112.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n", "</g>\n",
"<!-- 1 -->\n", "<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n", "<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"143\" cy=\"-117\" rx=\"18\" ry=\"18\"/>\n", "<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"143\" cy=\"-113\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"143\" cy=\"-117\" rx=\"22\" ry=\"22\"/>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"143\" cy=\"-113\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"143\" y=\"-113.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n", "<text text-anchor=\"start\" x=\"138.5\" y=\"-109.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n", "</g>\n",
"<!-- 0&#45;&gt;1 -->\n", "<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;1</title>\n", "<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M72.5903,-83.52C84.8926,-89.4541 102.305,-97.8532 116.612,-104.754\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M72.5903,-80.3366C84.6994,-86.035 101.76,-94.0634 115.936,-100.735\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"122.938,-107.805 115.264,-107.601 119.785,-106.285 116.633,-104.764 116.633,-104.764 116.633,-104.764 119.785,-106.285 118.001,-101.927 122.938,-107.805 122.938,-107.805\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"122.629,-103.884 114.954,-103.754 119.462,-102.394 116.295,-100.904 116.295,-100.904 116.295,-100.904 119.462,-102.394 117.637,-98.0535 122.629,-103.884 122.629,-103.884\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-100.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n", "<text text-anchor=\"start\" x=\"92\" y=\"-97.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n", "</g>\n",
"<!-- 2 -->\n", "<!-- 2 -->\n",
"<g id=\"node4\" class=\"node\"><title>2</title>\n", "<g id=\"node4\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"143\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n", "<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"143\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"143\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"143\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n", "<text text-anchor=\"middle\" x=\"143\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n", "</g>\n",
"<!-- 0&#45;&gt;2 -->\n", "<!-- 0&#45;&gt;2 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;2</title>\n", "<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M71.8059,-66.5939C84.5413,-58.5032 103.153,-46.6792 118.012,-37.2391\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M71.8059,-64.1165C85.3737,-55.9758 105.611,-43.8333 120.875,-34.6748\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"124.123,-33.3572 119.904,-39.7697 121.169,-35.234 118.214,-37.1109 118.214,-37.1109 118.214,-37.1109 121.169,-35.234 116.525,-34.452 124.123,-33.3572 124.123,-33.3572\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"127.079,-30.9528 122.697,-37.2555 124.077,-32.7536 121.076,-34.5544 121.076,-34.5544 121.076,-34.5544 124.077,-32.7536 119.455,-31.8532 127.079,-30.9528 127.079,-30.9528\"/>\n",
"<text text-anchor=\"start\" x=\"93\" y=\"-55.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n", "<text text-anchor=\"start\" x=\"93\" y=\"-53.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n", "</g>\n",
"<!-- 1&#45;&gt;1 -->\n", "<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;1</title>\n", "<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M134.994,-137.581C133.886,-147.845 136.555,-157 143,-157 147.834,-157 150.544,-151.85 151.129,-144.945\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M134.994,-133.581C133.886,-143.845 136.555,-153 143,-153 147.834,-153 150.544,-147.85 151.129,-140.945\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"151.006,-137.581 154.273,-144.527 151.065,-141.08 151.123,-144.58 151.123,-144.58 151.123,-144.58 151.065,-141.08 147.973,-144.632 151.006,-137.581 151.006,-137.581\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"151.006,-133.581 154.273,-140.527 151.065,-137.08 151.123,-140.58 151.123,-140.58 151.123,-140.58 151.065,-137.08 147.973,-140.632 151.006,-133.581 151.006,-133.581\"/>\n",
"<text text-anchor=\"start\" x=\"137.5\" y=\"-160.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n", "<text text-anchor=\"start\" x=\"137.5\" y=\"-156.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n", "</g>\n",
"<!-- 2&#45;&gt;2 -->\n", "<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>2&#45;&gt;2</title>\n", "<g id=\"edge6\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M134.994,-42.5808C133.886,-52.8447 136.555,-62 143,-62 147.834,-62 150.544,-56.8502 151.129,-49.9451\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M135.332,-38.2903C133.483,-48.3892 136.039,-58 143,-58 148.221,-58 150.964,-52.5939 151.229,-45.6304\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"151.006,-42.5808 154.273,-49.5273 151.065,-46.0803 151.123,-49.5798 151.123,-49.5798 151.123,-49.5798 151.065,-46.0803 147.973,-49.6324 151.006,-42.5808 151.006,-42.5808\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"150.668,-38.2903 154.342,-45.0299 150.935,-41.7801 151.201,-45.2699 151.201,-45.2699 151.201,-45.2699 150.935,-41.7801 148.06,-45.5099 150.668,-38.2903 150.668,-38.2903\"/>\n",
"<text text-anchor=\"start\" x=\"138.5\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n", "<text text-anchor=\"start\" x=\"136.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n",
"</g>\n", "</g>\n",
"<!-- 3 -->\n", "<!-- 3 -->\n",
"<g id=\"node5\" class=\"node\"><title>3</title>\n", "<g id=\"node5\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"232\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n", "<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"236\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"232\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n", "<ellipse fill=\"none\" stroke=\"black\" cx=\"236\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"236\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n", "</g>\n",
"<!-- 2&#45;&gt;3 -->\n", "<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;3</title>\n", "<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M165.06,-22C177.588,-22 193.534,-22 206.607,-22\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M161.116,-22C173.948,-22 191.793,-22 206.731,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"213.925,-22 206.925,-25.1501 210.425,-22 206.925,-22.0001 206.925,-22.0001 206.925,-22.0001 210.425,-22 206.925,-18.8501 213.925,-22 213.925,-22\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"213.796,-22 206.796,-25.1501 210.296,-22 206.796,-22.0001 206.796,-22.0001 206.796,-22.0001 210.296,-22 206.795,-18.8501 213.796,-22 213.796,-22\"/>\n",
"<text text-anchor=\"start\" x=\"183\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n", "<text text-anchor=\"start\" x=\"185\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n", "</g>\n",
"<!-- 3&#45;&gt;2 -->\n", "<!-- 3&#45;&gt;2 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>3&#45;&gt;2</title>\n", "<g id=\"edge8\" class=\"edge\"><title>3&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M216.689,-12.1343C210.598,-8.50652 203.237,-4.83778 196,-3 186.646,-0.624833 176.631,-3.03558 167.911,-6.84342\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M217.045,-9.91849C207.177,-4.69562 194.613,-0.32156 183,-3 176.881,-4.41121 170.611,-6.91853 164.938,-9.6583\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"161.529,-9.97151 166.428,-4.06232 164.671,-8.4312 167.814,-6.8909 167.814,-6.8909 167.814,-6.8909 164.671,-8.4312 169.201,-9.71947 161.529,-9.97151 161.529,-9.97151\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"158.596,-12.9296 163.373,-6.92094 161.707,-11.325 164.817,-9.72043 164.817,-9.72043 164.817,-9.72043 161.707,-11.325 166.261,-12.5199 158.596,-12.9296 158.596,-12.9296\"/>\n",
"<text text-anchor=\"start\" x=\"185\" y=\"-6.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n", "<text text-anchor=\"start\" x=\"183\" y=\"-6.8\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n",
"</g>\n", "</g>\n",
"<!-- 3&#45;&gt;3 -->\n", "<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>3&#45;&gt;3</title>\n", "<g id=\"edge9\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M224.617,-38.6641C222.977,-48.625 225.438,-58 232,-58 236.922,-58 239.537,-52.7266 239.844,-45.8876\"/>\n", "<path fill=\"none\" stroke=\"black\" d=\"M227.63,-42.5808C226.472,-52.8447 229.262,-62 236,-62 241.054,-62 243.887,-56.8502 244.499,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"239.383,-38.6641 242.973,-45.449 239.606,-42.1569 239.829,-45.6498 239.829,-45.6498 239.829,-45.6498 239.606,-42.1569 236.686,-45.8507 239.383,-38.6641 239.383,-38.6641\"/>\n", "<polygon fill=\"black\" stroke=\"black\" points=\"244.37,-42.5808 247.642,-49.5248 244.431,-46.0803 244.492,-49.5797 244.492,-49.5797 244.492,-49.5797 244.431,-46.0803 241.343,-49.6347 244.37,-42.5808 244.37,-42.5808\"/>\n",
"<text text-anchor=\"start\" x=\"225.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n", "<text text-anchor=\"start\" x=\"231.5\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n", "</g>\n",
"</g>\n", "</g>\n",
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e120> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c833120> >"
] ]
} }
], ],
@ -1494,7 +1494,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e330> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c833330> >"
] ]
} }
], ],
@ -1964,7 +1964,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e2a0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c8332a0> >"
] ]
} }
], ],
@ -2161,7 +2161,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc00cd3c8>" "<IPython.core.display.SVG at 0x7fe334078400>"
] ]
}, },
{ {
@ -2286,7 +2286,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc00d38d0>" "<IPython.core.display.SVG at 0x7fe33407f8d0>"
] ]
}, },
{ {
@ -2428,7 +2428,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc014cb38>" "<IPython.core.display.SVG at 0x7fe3340f9ba8>"
] ]
}, },
{ {
@ -2579,7 +2579,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc0b98ae0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe334d5cae0> >"
] ]
} }
], ],
@ -2735,7 +2735,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc0b98fc0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe334d5cfc0> >"
] ]
} }
], ],
@ -2805,7 +2805,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc0b98ae0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe334d5cae0> >"
] ]
} }
], ],
@ -2877,7 +2877,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc00e4a20>" "<IPython.core.display.SVG at 0x7fe33408fa58>"
] ]
}, },
{ {
@ -2930,7 +2930,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc010f828>" "<IPython.core.display.SVG at 0x7fe3340b0828>"
] ]
}, },
{ {
@ -3042,7 +3042,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc01223c8>" "<IPython.core.display.SVG at 0x7fe3340cf3c8>"
] ]
}, },
{ {
@ -3154,7 +3154,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc00fcc88>" "<IPython.core.display.SVG at 0x7fe3340a9cf8>"
] ]
} }
], ],
@ -3232,7 +3232,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc866e390> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c833390> >"
] ]
}, },
{ {
@ -3315,7 +3315,7 @@
"</svg>" "</svg>"
], ],
"text": [ "text": [
"<IPython.core.display.SVG at 0x7f5fc00c0cf8>" "<IPython.core.display.SVG at 0x7fe33406c7b8>"
] ]
} }
], ],
@ -3400,7 +3400,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc85824e0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c747540> >"
] ]
} }
], ],
@ -3489,7 +3489,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc85824e0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c747540> >"
] ]
} }
], ],
@ -3578,7 +3578,7 @@
"</svg>\n" "</svg>\n"
], ],
"text": [ "text": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f5fc85824e0> >" "<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fe33c747540> >"
] ]
} }
], ],