Commit 9a17f567 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

game: rewrite, document, and rename solve_reachability_game

* spot/twaalgos/game.hh, spot/twaalgos/game.cc: Rename
solve_reachability_game() as solve_safety_game(), rewrite it (the old
implementation incorrectly marked dead states as winning for their
owner).
* tests/python/paritygame.ipynb: Rename as...
* tests/python/games.ipynb: ... this, and illustrate
solve_safety_game().
* tests/Makefile.am, NEWS, doc/org/tut.org: Adjust.
* tests/python/except.py: Add more tests.
parent 05449a42
Pipeline #24195 passed with stages
in 193 minutes and 59 seconds
......@@ -148,8 +148,8 @@ New in spot 2.9.5.dev (not yet released)
Python:
- Bindings for functions related to parity games.
See https://spot.lrde.epita.fr/ipynb/paritygame.html for examples.
- Bindings for functions related to games.
See https://spot.lrde.epita.fr/ipynb/games.html for examples.
Bugs fixed:
......
......@@ -72,7 +72,7 @@ real notebooks instead.
automata
- [[https://spot.lrde.epita.fr/ipynb/parity.html][=parity.ipynb=]] documents algorithms for manipulating parity automata
in Python
- [[https://spot.lrde.epita.fr/ipynb/paritygame.html][=paritygame.ipynb=]] illustrates support for parity games
- [[https://spot.lrde.epita.fr/ipynb/games.html][=games.ipynb=]] illustrates support for games
- [[https://spot.lrde.epita.fr/ipynb/product.html][=product.ipynb=]] shows how to re-implement the product of two automata
in Python
- [[https://spot.lrde.epita.fr/ipynb/randltl.html][=randltl.ipynb=]] demonstrates a Python-version of [[file:randltl.org][=randltl=]]
......
......@@ -19,7 +19,6 @@
#include "config.h"
#include <cmath>
#include <spot/twaalgos/game.hh>
#include <spot/misc/bddlt.hh>
#include <spot/twaalgos/sccinfo.hh>
......@@ -958,53 +957,91 @@ namespace spot
return (*owners)[state] ? 1 : 0;
}
bool solve_reachability_game(twa_graph_ptr game)
bool solve_safety_game(twa_graph_ptr game)
{
if (!game->acc().is_t())
throw std::runtime_error
("solve_safety_game(): arena should have true acceptance");
auto owners = get_state_players(game);
auto winners = new region_t(game->num_states(), true);
unsigned ns = game->num_states();
auto winners = new region_t(ns, true);
game->set_named_prop("state-winner", winners);
auto strategy = new strategy_t(game->num_states(), 0);
auto strategy = new strategy_t(ns, 0);
game->set_named_prop("strategy", strategy);
std::vector<bool> seen(game->num_states(), false);
std::vector<unsigned> todo;
todo.reserve(game->num_states());
auto& g = game->get_graph();
todo.push_back(game->get_init_state_number());
while (!todo.empty())
{
unsigned cur = todo.back();
auto edges = game->out(cur);
if (!seen[cur])
// transposed is a reversed copy of game to compute predecessors
// more easily. It also keep track of the original edge iindex.
struct edge_data {
unsigned edgeidx;
};
digraph<void, edge_data> transposed;
// Reverse the automaton, compute the out degree of
// each state, and save dead-states in queue.
transposed.new_states(ns);
std::vector<unsigned> out_degree;
out_degree.reserve(ns);
std::vector<unsigned> queue;
for (unsigned s = 0; s < ns; ++s)
{
for (const auto& e : edges)
todo.push_back(e.dst);
seen[cur] = true;
unsigned deg = 0;
for (auto& e: game->out(s))
{
transposed.new_edge(e.dst, e.src, game->edge_number(e));
++deg;
}
out_degree.push_back(deg);
if (deg == 0)
{
(*winners)[s] = false;
queue.push_back(s);
}
}
else
// queue is initially filled with dead-states, which are winning
// for player 0. Any predecessor owned by player 0 is therefore
// winning as well (check 1), and any predecessor owned by player
// 1 that has all its successors winning for player 0 (check 2) is
// also winning. Use queue to propagate everything.
// For the second check, we decrease out_degree by each edge leading
// to a state winning for player 0, so if out_degree reaches 0,
// we have ensured that all outgoing transitions are winning for 0.
//
// We use queue as a stack, to propagate bad states in DFS.
// However it would be ok to replace the vector by a std::deque
// to implement a BFS and build shorter strategies for player 0.
// Right no we are assuming that strategies for player 0 have
// limited uses, so we just avoid the overhead of std::deque in
// favor of the simpler std::vector.
while (!queue.empty())
{
todo.pop_back();
bool player = owners[cur];
auto it = std::find_if(edges.begin(), edges.end(),
[&winners, player](auto& e)
unsigned s = queue.back();
queue.pop_back();
for (auto& e: transposed.out(s))
{
return (*winners)[e.dst] == player;
});
if (it != edges.end())
{
(*strategy)[cur] = g.index_of_edge(*it);
(*winners)[cur] = player;
}
else
(*winners)[cur] = !player;
}
}
unsigned pred = e.dst;
if (!(*winners)[pred])
continue;
// check 1 || check 2
bool check1 = owners[pred] == false;
if (check1 || --out_degree[pred] == 0)
{
(*winners)[pred] = false;
queue.push_back(pred);
if (check1)
(*strategy)[pred] = e.edgeidx;
}
}
}
// Let's fill in the strategy for Player 1.
for (unsigned s = 0; s < ns; ++s)
if (owners[s] && (*winners)[s])
for (auto& e: game->out(s))
if ((*winners)[e.dst])
{
(*strategy)[s] = game->edge_number(e);
break;
}
return (*winners)[game->get_init_state_number()];
}
......
......@@ -58,9 +58,11 @@ namespace spot
/// The arena is a deterministic max odd parity automaton with a
/// "state-player" property.
///
/// This computes the winning strategy and winning region of this
/// game for player 1 using Zielonka's recursive algorithm.
/// \cite zielonka.98.tcs
/// Player 1 tries to satisfy the acceptance condition, while player
/// 0 tries to prevent that.
///
/// This computes the winning strategy and winning region using
/// Zielonka's recursive algorithm. \cite zielonka.98.tcs
///
/// Also includes some inspiration from Oink.
/// \cite vandijk.18.tacas
......@@ -70,6 +72,22 @@ namespace spot
SPOT_API
bool solve_parity_game(const twa_graph_ptr& arena);
/// \brief Solve a safety game.
///
/// The arena should be represented by an automaton with true
/// acceptance.
///
/// Player 1 tries to satisfy the acceptance condition, while player
/// 0 tries to prevent that. The only way for player 0 to win is
/// to find a way to move the play toward a state without successor.
/// If there no state without successors, then the game is necessarily
/// winning for player 1.
///
/// Returns the player winning in the initial state, and sets
/// the state-winner and strategy named properties.
SPOT_API
bool solve_safety_game(twa_graph_ptr game);
/// \brief Print a max odd parity game using PG-solver syntax
SPOT_API
void pg_print(std::ostream& os, const const_twa_graph_ptr& arena);
......@@ -100,8 +118,4 @@ namespace spot
/// \brief Get the owner of a state.
SPOT_API
unsigned get_state_player(const_twa_graph_ptr arena, unsigned state);
/// \brief Solve a reachability game.
SPOT_API
bool solve_reachability_game(twa_graph_ptr game);
}
......@@ -357,12 +357,12 @@ TESTS_ipython = \
python/contains.ipynb \
python/decompose.ipynb \
python/formulas.ipynb \
python/games.ipynb \
python/gen.ipynb \
python/highlighting.ipynb \
python/ltsmin-dve.ipynb \
python/ltsmin-pml.ipynb \
python/parity.ipynb \
python/paritygame.ipynb \
python/product.ipynb \
python/randaut.ipynb \
python/randltl.ipynb \
......
......@@ -196,24 +196,39 @@ assert spot.is_deterministic(a2)
try:
spot.product_xor(a1, a2)
except RuntimeError as e:
assert "product_xor() only works with deterministic automata"
assert "product_xor() only works with deterministic automata" in str(e)
else:
report_missing_exception()
try:
spot.product_xor(a2, a1)
except RuntimeError as e:
assert "product_xor() only works with deterministic automata"
assert "product_xor() only works with deterministic automata" in str(e)
else:
report_missing_exception()
try:
spot.product_xnor(a1, a2)
except RuntimeError as e:
assert "product_xnor() only works with deterministic automata"
assert "product_xnor() only works with deterministic automata" in str(e)
else:
report_missing_exception()
try:
spot.product_xnor(a2, a1)
except RuntimeError as e:
assert "product_xnor() only works with deterministic automata"
assert "product_xnor() only works with deterministic automata" in str(e)
else:
report_missing_exception()
try:
spot.solve_safety_game(a1)
except RuntimeError as e:
assert "solve_safety_game(): arena should have true acceptance" in str(e)
else:
report_missing_exception()
try:
spot.solve_parity_game(a1)
except RuntimeError as e:
assert "solve_parity_game(): arena must have max-odd acceptance condition" \
in str(e)
else:
report_missing_exception()
%% Cell type:code id: tags:
``` python
import spot
from buddy import bddtrue
spot.setup()
```
%% Cell type:markdown id: tags:
# Support for parity games
# Support for games
The support for parity games is currently quite rudimentary, as Spot currently only uses those games in `ltlsynt`.
The support for games is currently quite rudimentary, as Spot currently only uses those games in `ltlsynt`.
In essence, a parity game is just a parity automaton with a property named `state-player` that stores the player owning each state. The players are named 0 and 1.
In essence, agame is just an ω-automaton with a property named `state-player` that stores the player owning each state. The players are named 0 and 1. The player owning a state can decide what the next transition from this state should be. The goal for player 1 is to force the play to be infinite and to satisfy the acceptance condition of the automaton, while the goal for player 0 is to prevent it by either forcing a finite play, or forcing an infinite play that does not satisfy the acceptance condition.
Player 1 is winning if it has a strategy to satisfy the acceptance condition regardless of player 0's moves.
Player 0 is winning if it has a strategy to not satisfy the acceptance codition regardless of player 1's moves.
The support is currently restricted to games that use:
- `t` acceptance: all infinite run are accepting, and player 0 can only win if it manages to force a finite play (this requires reaching states without successors).
- max odd parity acceptance: player 0 can win if the maximal value seen infinitely often is even
%% Cell type:markdown id: tags:
# Creating games from scratch
Games can be [created like any automaton](https://spot.lrde.epita.fr/tut22.html).
Using `set_state_players()` will fix the state owners.
%% Cell type:code id: tags:
``` python
bdict = spot.make_bdd_dict();
game = spot.make_twa_graph(bdict)
game.new_states(9)
for (s, d) in ((0,1), (0, 3),
(1, 0), (1, 2),
(2, 1), (2, 5),
(3, 2), (3, 4), (3, 6),
(6, 7),
(7, 6), (7, 8),
(8, 5)):
game.new_edge(s, d, bddtrue)
spot.set_state_players(game, [True, False, True, False, True, True, True, False, False])
game.show('.g') # Use "g" to hide the irrelevant edge labels.
```
%%%% Output: execute_result
![](data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><!-- Generated by graphviz version 2.43.0 (0)--><!-- Pages: 1 --><svg width="495pt" height="190pt"viewBox="0.00 0.00 495.00 190.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="graph0" class="graph" transform="scale(1.0 1.0) rotate(0) translate(4 186)"><polygon fill="white" stroke="transparent" points="-4,4 -4,-186 491,-186 491,4 -4,4"/><text text-anchor="start" x="240.5" y="-166.8" font-family="Lato" font-size="14.00">t</text><text text-anchor="start" x="232.5" y="-151.8" font-family="Lato" font-size="14.00">[all]</text><!-- I --><!-- 0 --><g id="node2" class="node"><title>0</title><polygon fill="#ffffaa" stroke="black" points="64,-144 37,-126 64,-108 91,-126 64,-144"/><text text-anchor="middle" x="64" y="-122.3" font-family="Lato" font-size="14.00">0</text></g><!-- I&#45;&gt;0 --><g id="edge1" class="edge"><title>I&#45;&gt;0</title><path fill="none" stroke="black" d="M1.04,-126C1.93,-126 15.66,-126 29.98,-126"/><polygon fill="black" stroke="black" points="37,-126 30,-129.15 33.5,-126 30,-126 30,-126 30,-126 33.5,-126 30,-122.85 37,-126 37,-126"/></g><!-- 1 --><g id="node3" class="node"><title>1</title><ellipse fill="#ffffaa" stroke="black" cx="145" cy="-126" rx="18" ry="18"/><text text-anchor="middle" x="145" y="-122.3" font-family="Lato" font-size="14.00">1</text></g><!-- 0&#45;&gt;1 --><g id="edge2" class="edge"><title>0&#45;&gt;1</title><path fill="none" stroke="black" d="M82.53,-120.28C93.75,-119.1 108.43,-118.93 120.64,-119.78"/><polygon fill="black" stroke="black" points="127.86,-120.43 120.61,-122.94 124.38,-120.12 120.89,-119.8 120.89,-119.8 120.89,-119.8 124.38,-120.12 121.17,-116.66 127.86,-120.43 127.86,-120.43"/></g><!-- 3 --><g id="node4" class="node"><title>3</title><ellipse fill="#ffffaa" stroke="black" cx="145" cy="-72" rx="18" ry="18"/><text text-anchor="middle" x="145" y="-68.3" font-family="Lato" font-size="14.00">3</text></g><!-- 0&#45;&gt;3 --><g id="edge3" class="edge"><title>0&#45;&gt;3</title><path fill="none" stroke="black" d="M78.05,-117.08C90.47,-108.59 109.36,-95.68 123.74,-85.85"/><polygon fill="black" stroke="black" points="129.6,-81.85 125.59,-88.4 126.71,-83.82 123.82,-85.8 123.82,-85.8 123.82,-85.8 126.71,-83.82 122.04,-83.2 129.6,-81.85 129.6,-81.85"/></g><!-- 1&#45;&gt;0 --><g id="edge4" class="edge"><title>1&#45;&gt;0</title><path fill="none" stroke="black" d="M127.86,-131.57C116.84,-132.84 102.04,-133.09 89.56,-132.3"/><polygon fill="black" stroke="black" points="82.53,-131.72 89.77,-129.16 86.02,-132.01 89.51,-132.3 89.51,-132.3 89.51,-132.3 86.02,-132.01 89.25,-135.44 82.53,-131.72 82.53,-131.72"/></g><!-- 2 --><g id="node5" class="node"><title>2</title><polygon fill="#ffffaa" stroke="black" points="226,-144 199,-126 226,-108 253,-126 226,-144"/><text text-anchor="middle" x="226" y="-122.3" font-family="Lato" font-size="14.00">2</text></g><!-- 1&#45;&gt;2 --><g id="edge5" class="edge"><title>1&#45;&gt;2</title><path fill="none" stroke="black" d="M162.37,-120.41C173.4,-119.15 188.15,-118.92 200.56,-119.71"/><polygon fill="black" stroke="black" points="207.56,-120.29 200.32,-122.85 204.07,-120 200.58,-119.71 200.58,-119.71 200.58,-119.71 204.07,-120 200.84,-116.57 207.56,-120.29 207.56,-120.29"/></g><!-- 3&#45;&gt;2 --><g id="edge8" class="edge"><title>3&#45;&gt;2</title><path fill="none" stroke="black" d="M160.49,-81.9C173.24,-90.62 191.89,-103.37 205.86,-112.92"/><polygon fill="black" stroke="black" points="211.91,-117.05 204.36,-115.7 209.02,-115.08 206.13,-113.1 206.13,-113.1 206.13,-113.1 209.02,-115.08 207.91,-110.5 211.91,-117.05 211.91,-117.05"/></g><!-- 4 --><g id="node7" class="node"><title>4</title><polygon fill="#ffffaa" stroke="black" points="226,-90 199,-72 226,-54 253,-72 226,-90"/><text text-anchor="middle" x="226" y="-68.3" font-family="Lato" font-size="14.00">4</text></g><!-- 3&#45;&gt;4 --><g id="edge9" class="edge"><title>3&#45;&gt;4</title><path fill="none" stroke="black" d="M163.14,-72C171.54,-72 181.95,-72 191.82,-72"/><polygon fill="black" stroke="black" points="198.87,-72 191.87,-75.15 195.37,-72 191.87,-72 191.87,-72 191.87,-72 195.37,-72 191.87,-68.85 198.87,-72 198.87,-72"/></g><!-- 6 --><g id="node8" class="node"><title>6</title><polygon fill="#ffffaa" stroke="black" points="226,-36 199,-18 226,0 253,-18 226,-36"/><text text-anchor="middle" x="226" y="-14.3" font-family="Lato" font-size="14.00">6</text></g><!-- 3&#45;&gt;6 --><g id="edge10" class="edge"><title>3&#45;&gt;6</title><path fill="none" stroke="black" d="M160.49,-62.1C173.24,-53.38 191.89,-40.63 205.86,-31.08"/><polygon fill="black" stroke="black" points="211.91,-26.95 207.91,-33.5 209.02,-28.92 206.13,-30.9 206.13,-30.9 206.13,-30.9 209.02,-28.92 204.36,-28.3 211.91,-26.95 211.91,-26.95"/></g><!-- 2&#45;&gt;1 --><g id="edge6" class="edge"><title>2&#45;&gt;1</title><path fill="none" stroke="black" d="M207.56,-131.71C196.4,-132.89 181.78,-133.07 169.59,-132.24"/><polygon fill="black" stroke="black" points="162.37,-131.59 169.62,-129.08 165.85,-131.9 169.34,-132.22 169.34,-132.22 169.34,-132.22 165.85,-131.9 169.06,-135.35 162.37,-131.59 162.37,-131.59"/></g><!-- 5 --><g id="node6" class="node"><title>5</title><polygon fill="#ffffaa" stroke="black" points="460,-90 433,-72 460,-54 487,-72 460,-90"/><text text-anchor="middle" x="460" y="-68.3" font-family="Lato" font-size="14.00">5</text></g><!-- 2&#45;&gt;5 --><g id="edge7" class="edge"><title>2&#45;&gt;5</title><path fill="none" stroke="black" d="M246.38,-121.49C287.92,-111.82 385.57,-89.09 432.67,-78.13"/><polygon fill="black" stroke="black" points="439.51,-76.54 433.41,-81.19 436.1,-77.33 432.69,-78.12 432.69,-78.12 432.69,-78.12 436.1,-77.33 431.98,-75.06 439.51,-76.54 439.51,-76.54"/></g><!-- 7 --><g id="node9" class="node"><title>7</title><ellipse fill="#ffffaa" stroke="black" cx="307" cy="-18" rx="18" ry="18"/><text text-anchor="middle" x="307" y="-14.3" font-family="Lato" font-size="14.00">7</text></g><!-- 6&#45;&gt;7 --><g id="edge11" class="edge"><title>6&#45;&gt;7</title><path fill="none" stroke="black" d="M244.53,-12.28C255.75,-11.1 270.43,-10.93 282.64,-11.78"/><polygon fill="black" stroke="black" points="289.86,-12.43 282.61,-14.94 286.38,-12.12 282.89,-11.8 282.89,-11.8 282.89,-11.8 286.38,-12.12 283.17,-8.66 289.86,-12.43 289.86,-12.43"/></g><!-- 7&#45;&gt;6 --><g id="edge12" class="edge"><title>7&#45;&gt;6</title><path fill="none" stroke="black" d="M289.86,-23.57C278.84,-24.84 264.04,-25.09 251.56,-24.3"/><polygon fill="black" stroke="black" points="244.53,-23.72 251.77,-21.16 248.02,-24.01 251.51,-24.3 251.51,-24.3 251.51,-24.3 248.02,-24.01 251.25,-27.44 244.53,-23.72 244.53,-23.72"/></g><!-- 8 --><g id="node10" class="node"><title>8</title><ellipse fill="#ffffaa" stroke="black" cx="379" cy="-49" rx="18" ry="18"/><text text-anchor="middle" x="379" y="-45.3" font-family="Lato" font-size="14.00">8</text></g><!-- 7&#45;&gt;8 --><g id="edge13" class="edge"><title>7&#45;&gt;8</title><path fill="none" stroke="black" d="M323.88,-25.03C333.28,-29.2 345.33,-34.53 355.67,-39.11"/><polygon fill="black" stroke="black" points="362.18,-41.99 354.5,-42.04 358.98,-40.58 355.78,-39.16 355.78,-39.16 355.78,-39.16 358.98,-40.58 357.05,-36.28 362.18,-41.99 362.18,-41.99"/></g><!-- 8&#45;&gt;5 --><g id="edge14" class="edge"><title>8&#45;&gt;5</title><path fill="none" stroke="black" d="M396.37,-53.77C407.17,-56.91 421.54,-61.1 433.79,-64.66"/><polygon fill="black" stroke="black" points="440.72,-66.68 433.12,-67.75 437.36,-65.7 434,-64.72 434,-64.72 434,-64.72 437.36,-65.7 434.88,-61.7 440.72,-66.68 440.72,-66.68"/></g></g></svg>)
<spot.jupyter.SVG object>
%% Cell type:markdown id: tags:
The `set_state_players()` function takes a list of owner for each of the states in the automaton. In the output,
states from player 0 use circles, ellispes, or rectangle with rounded corners (mnemonic: 0 is round) while states from player 1 have a losanse shape (1 has only straight lines).
State ownership can also be manipulated by the following functions:
%% Cell type:code id: tags:
``` python
spot.get_state_players(game)
```
%%%% Output: execute_result
(True, False, True, False, True, True, True, False, False)
%% Cell type:code id: tags:
``` python
spot.get_state_player(game, 4)
```
%%%% Output: execute_result
1
%% Cell type:code id: tags:
``` python
spot.set_state_player(game, 4, False)
game.show('.g')
```
%%%% Output: execute_result
![](data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><!-- Generated by graphviz version 2.43.0 (0)--><!-- Pages: 1 --><svg width="495pt" height="190pt"viewBox="0.00 0.00 495.00 190.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="graph0" class="graph" transform="scale(1.0 1.0) rotate(0) translate(4 186)"><polygon fill="white" stroke="transparent" points="-4,4 -4,-186 491,-186 491,4 -4,4"/><text text-anchor="start" x="240.5" y="-166.8" font-family="Lato" font-size="14.00">t</text><text text-anchor="start" x="232.5" y="-151.8" font-family="Lato" font-size="14.00">[all]</text><!-- I --><!-- 0 --><g id="node2" class="node"><title>0</title><polygon fill="#ffffaa" stroke="black" points="64,-144 37,-126 64,-108 91,-126 64,-144"/><text text-anchor="middle" x="64" y="-122.3" font-family="Lato" font-size="14.00">0</text></g><!-- I&#45;&gt;0 --><g id="edge1" class="edge"><title>I&#45;&gt;0</title><path fill="none" stroke="black" d="M1.04,-126C1.93,-126 15.66,-126 29.98,-126"/><polygon fill="black" stroke="black" points="37,-126 30,-129.15 33.5,-126 30,-126 30,-126 30,-126 33.5,-126 30,-122.85 37,-126 37,-126"/></g><!-- 1 --><g id="node3" class="node"><title>1</title><ellipse fill="#ffffaa" stroke="black" cx="145" cy="-126" rx="18" ry="18"/><text text-anchor="middle" x="145" y="-122.3" font-family="Lato" font-size="14.00">1</text></g><!-- 0&#45;&gt;1 --><g id="edge2" class="edge"><title>0&#45;&gt;1</title><path fill="none" stroke="black" d="M82.53,-120.28C93.75,-119.1 108.43,-118.93 120.64,-119.78"/><polygon fill="black" stroke="black" points="127.86,-120.43 120.61,-122.94 124.38,-120.12 120.89,-119.8 120.89,-119.8 120.89,-119.8 124.38,-120.12 121.17,-116.66 127.86,-120.43 127.86,-120.43"/></g><!-- 3 --><g id="node4" class="node"><title>3</title><ellipse fill="#ffffaa" stroke="black" cx="145" cy="-72" rx="18" ry="18"/><text text-anchor="middle" x="145" y="-68.3" font-family="Lato" font-size="14.00">3</text></g><!-- 0&#45;&gt;3 --><g id="edge3" class="edge"><title>0&#45;&gt;3</title><path fill="none" stroke="black" d="M78.05,-117.08C90.47,-108.59 109.36,-95.68 123.74,-85.85"/><polygon fill="black" stroke="black" points="129.6,-81.85 125.59,-88.4 126.71,-83.82 123.82,-85.8 123.82,-85.8 123.82,-85.8 126.71,-83.82 122.04,-83.2 129.6,-81.85 129.6,-81.85"/></g><!-- 1&#45;&gt;0 --><g id="edge4" class="edge"><title>1&#45;&gt;0</title><path fill="none" stroke="black" d="M127.86,-131.57C116.84,-132.84 102.04,-133.09 89.56,-132.3"/><polygon fill="black" stroke="black" points="82.53,-131.72 89.77,-129.16 86.02,-132.01 89.51,-132.3 89.51,-132.3 89.51,-132.3 86.02,-132.01 89.25,-135.44 82.53,-131.72 82.53,-131.72"/></g><!-- 2 --><g id="node5" class="node"><title>2</title><polygon fill="#ffffaa" stroke="black" points="226,-144 199,-126 226,-108 253,-126 226,-144"/><text text-anchor="middle" x="226" y="-122.3" font-family="Lato" font-size="14.00">2</text></g><!-- 1&#45;&gt;2 --><g id="edge5" class="edge"><title>1&#45;&gt;2</title><path fill="none" stroke="black" d="M162.37,-120.41C173.4,-119.15 188.15,-118.92 200.56,-119.71"/><polygon fill="black" stroke="black" points="207.56,-120.29 200.32,-122.85 204.07,-120 200.58,-119.71 200.58,-119.71 200.58,-119.71 204.07,-120 200.84,-116.57 207.56,-120.29 207.56,-120.29"/></g><!-- 3&#45;&gt;2 --><g id="edge8" class="edge"><title>3&#45;&gt;2</title><path fill="none" stroke="black" d="M160.49,-81.9C173.24,-90.62 191.89,-103.37 205.86,-112.92"/><polygon fill="black" stroke="black" points="211.91,-117.05 204.36,-115.7 209.02,-115.08 206.13,-113.1 206.13,-113.1 206.13,-113.1 209.02,-115.08 207.91,-110.5 211.91,-117.05 211.91,-117.05"/></g><!-- 4 --><g id="node7" class="node"><title>4</title><ellipse fill="#ffffaa" stroke="black" cx="226" cy="-72" rx="18" ry="18"/><text text-anchor="middle" x="226" y="-68.3" font-family="Lato" font-size="14.00">4</text></g><!-- 3&#45;&gt;4 --><g id="edge9" class="edge"><title>3&#45;&gt;4</title><path fill="none" stroke="black" d="M163.14,-72C174.12,-72 188.52,-72 200.67,-72"/><polygon fill="black" stroke="black" points="207.89,-72 200.89,-75.15 204.39,-72 200.89,-72 200.89,-72 200.89,-72 204.39,-72 200.89,-68.85 207.89,-72 207.89,-72"/></g><!-- 6 --><g id="node8" class="node"><title>6</title><polygon fill="#ffffaa" stroke="black" points="226,-36 199,-18 226,0 253,-18 226,-36"/><text text-anchor="middle" x="226" y="-14.3" font-family="Lato" font-size="14.00">6</text></g><!-- 3&#45;&gt;6 --><g id="edge10" class="edge"><title>3&#45;&gt;6</title><path fill="none" stroke="black" d="M160.49,-62.1C173.24,-53.38 191.89,-40.63 205.86,-31.08"/><polygon fill="black" stroke="black" points="211.91,-26.95 207.91,-33.5 209.02,-28.92 206.13,-30.9 206.13,-30.9 206.13,-30.9 209.02,-28.92 204.36,-28.3 211.91,-26.95 211.91,-26.95"/></g><!-- 2&#45;&gt;1 --><g id="edge6" class="edge"><title>2&#45;&gt;1</title><path fill="none" stroke="black" d="M207.56,-131.71C196.4,-132.89 181.78,-133.07 169.59,-132.24"/><polygon fill="black" stroke="black" points="162.37,-131.59 169.62,-129.08 165.85,-131.9 169.34,-132.22 169.34,-132.22 169.34,-132.22 165.85,-131.9 169.06,-135.35 162.37,-131.59 162.37,-131.59"/></g><!-- 5 --><g id="node6" class="node"><title>5</title><polygon fill="#ffffaa" stroke="black" points="460,-90 433,-72 460,-54 487,-72 460,-90"/><text text-anchor="middle" x="460" y="-68.3" font-family="Lato" font-size="14.00">5</text></g><!-- 2&#45;&gt;5 --><g id="edge7" class="edge"><title>2&#45;&gt;5</title><path fill="none" stroke="black" d="M246.38,-121.49C287.92,-111.82 385.57,-89.09 432.67,-78.13"/><polygon fill="black" stroke="black" points="439.51,-76.54 433.41,-81.19 436.1,-77.33 432.69,-78.12 432.69,-78.12 432.69,-78.12 436.1,-77.33 431.98,-75.06 439.51,-76.54 439.51,-76.54"/></g><!-- 7 --><g id="node9" class="node"><title>7</title><ellipse fill="#ffffaa" stroke="black" cx="307" cy="-18" rx="18" ry="18"/><text text-anchor="middle" x="307" y="-14.3" font-family="Lato" font-size="14.00">7</text></g><!-- 6&#45;&gt;7 --><g id="edge11" class="edge"><title>6&#45;&gt;7</title><path fill="none" stroke="black" d="M244.53,-12.28C255.75,-11.1 270.43,-10.93 282.64,-11.78"/><polygon fill="black" stroke="black" points="289.86,-12.43 282.61,-14.94 286.38,-12.12 282.89,-11.8 282.89,-11.8 282.89,-11.8 286.38,-12.12 283.17,-8.66 289.86,-12.43 289.86,-12.43"/></g><!-- 7&#45;&gt;6 --><g id="edge12" class="edge"><title>7&#45;&gt;6</title><path fill="none" stroke="black" d="M289.86,-23.57C278.84,-24.84 264.04,-25.09 251.56,-24.3"/><polygon fill="black" stroke="black" points="244.53,-23.72 251.77,-21.16 248.02,-24.01 251.51,-24.3 251.51,-24.3 251.51,-24.3 248.02,-24.01 251.25,-27.44 244.53,-23.72 244.53,-23.72"/></g><!-- 8 --><g id="node10" class="node"><title>8</title><ellipse fill="#ffffaa" stroke="black" cx="379" cy="-49" rx="18" ry="18"/><text text-anchor="middle" x="379" y="-45.3" font-family="Lato" font-size="14.00">8</text></g><!-- 7&#45;&gt;8 --><g id="edge13" class="edge"><title>7&#45;&gt;8</title><path fill="none" stroke="black" d="M323.88,-25.03C333.28,-29.2 345.33,-34.53 355.67,-39.11"/><polygon fill="black" stroke="black" points="362.18,-41.99 354.5,-42.04 358.98,-40.58 355.78,-39.16 355.78,-39.16 355.78,-39.16 358.98,-40.58 357.05,-36.28 362.18,-41.99 362.18,-41.99"/></g><!-- 8&#45;&gt;5 --><g id="edge14" class="edge"><title>8&#45;&gt;5</title><path fill="none" stroke="black" d="M396.37,-53.77C407.17,-56.91 421.54,-61.1 433.79,-64.66"/><polygon fill="black" stroke="black" points="440.72,-66.68 433.12,-67.75 437.36,-65.7 434,-64.72 434,-64.72 434,-64.72 437.36,-65.7 434.88,-61.7 440.72,-66.68 440.72,-66.68"/></g></g></svg>)
<spot.jupyter.SVG object>
%% Cell type:markdown id: tags:
# Solving a game
Solving a game is done my calling `solve_safety_game()` or `solve_parity_game()`. This will attach two additional vectors into the game automaton: one vector stores the winner of each state, and one vector stores (memory-less) strategy for each state, i.e., the transition that should always be taken by the owner of this state in order to win.
The return value of those function is simply the winner for the initial state.
%% Cell type:code id: tags:
``` python
spot.solve_safety_game(game)
```
%%%% Output: execute_result
True
%% Cell type:markdown id: tags:
Calling the `highlight_strategy()` function can be used to decorate the `game` automaton using the winning regions and strategies. Below, green represent the winning region/strategy for player 1 and red those for player 0.
%% Cell type:code id: tags:
``` python
spot.highlight_strategy(game)
game.show('.g')
```
%%%% Output: execute_result
![](data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><!-- Generated by graphviz version 2.43.0 (0)--><!-- Pages: 1 --><svg width="495pt" height="190pt"viewBox="0.00 0.00 495.00 190.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="graph0" class="graph" transform="scale(1.0 1.0) rotate(0) translate(4 186)"><polygon fill="white" stroke="transparent" points="-4,4 -4,-186 491,-186 491,4 -4,4"/><text text-anchor="start" x="240.5" y="-166.8" font-family="Lato" font-size="14.00">t</text><text text-anchor="start" x="232.5" y="-151.8" font-family="Lato" font-size="14.00">[all]</text><!-- I --><!-- 0 --><g id="node2" class="node"><title>0</title><polygon fill="#ffffaa" stroke="#33a02c" stroke-width="2" points="64,-144 37,-126 64,-108 91,-126 64,-144"/><text text-anchor="middle" x="64" y="-122.3" font-family="Lato" font-size="14.00">0</text></g><!-- I&#45;&gt;0 --><g id="edge1" class="edge"><title>I&#45;&gt;0</title><path fill="none" stroke="black" d="M1.04,-126C1.93,-126 15.66,-126 29.98,-126"/><polygon fill="black" stroke="black" points="37,-126 30,-129.15 33.5,-126 30,-126 30,-126 30,-126 33.5,-126 30,-122.85 37,-126 37,-126"/></g><!-- 1 --><g id="node3" class="node"><title>1</title><ellipse fill="#ffffaa" stroke="#33a02c" stroke-width="2" cx="145" cy="-126" rx="18" ry="18"/><text text-anchor="middle" x="145" y="-122.3" font-family="Lato" font-size="14.00">1</text></g><!-- 0&#45;&gt;1 --><g id="edge2" class="edge"><title>0&#45;&gt;1</title><path fill="none" stroke="#33a02c" stroke-width="2" d="M82.53,-120.28C93.75,-119.1 108.43,-118.93 120.64,-119.78"/><polygon fill="#33a02c" stroke="#33a02c" stroke-width="2" points="127.86,-120.43 120.61,-122.94 124.33,-120.62 120.84,-120.3 120.89,-119.8 120.94,-119.3 124.42,-119.62 121.17,-116.66 127.86,-120.43 127.86,-120.43"/></g><!-- 3 --><g id="node4" class="node"><title>3</title><ellipse fill="#ffffaa" stroke="#e31a1c" stroke-width="2" cx="145" cy="-72" rx="18" ry="18"/><text text-anchor="middle" x="145" y="-68.3" font-family="Lato" font-size="14.00">3</text></g><!-- 0&#45;&gt;3 --><g id="edge3" class="edge"><title>0&#45;&gt;3</title><path fill="none" stroke="black" d="M78.05,-117.08C90.47,-108.59 109.36,-95.68 123.74,-85.85"/><polygon fill="black" stroke="black" points="129.6,-81.85 125.59,-88.4 126.71,-83.82 123.82,-85.8 123.82,-85.8 123.82,-85.8 126.71,-83.82 122.04,-83.2 129.6,-81.85 129.6,-81.85"/></g><!-- 1&#45;&gt;0 --><g id="edge4" class="edge"><title>1&#45;&gt;0</title><path fill="none" stroke="black" d="M127.86,-131.57C116.84,-132.84 102.04,-133.09 89.56,-132.3"/><polygon fill="black" stroke="black" points="82.53,-131.72 89.77,-129.16 86.02,-132.01 89.51,-132.3 89.51,-132.3 89.51,-132.3 86.02,-132.01 89.25,-135.44 82.53,-131.72 82.53,-131.72"/></g><!-- 2 --><g id="node5" class="node"><title>2</title><polygon fill="#ffffaa" stroke="#33a02c" stroke-width="2" points="226,-144 199,-126 226,-108 253,-126 226,-144"/><text text-anchor="middle" x="226" y="-122.3" font-family="Lato" font-size="14.00">2</text></g><!-- 1&#45;&gt;2 --><g id="edge5" class="edge"><title>1&#45;&gt;2</title><path fill="none" stroke="black" d="M162.37,-120.41C173.4,-119.15 188.15,-118.92 200.56,-119.71"/><polygon fill="black" stroke="black" points="207.56,-120.29 200.32,-122.85 204.07,-120 200.58,-119.71 200.58,-119.71 200.58,-119.71 204.07,-120 200.84,-116.57 207.56,-120.29 207.56,-120.29"/></g><!-- 3&#45;&gt;2 --><g id="edge8" class="edge"><title>3&#45;&gt;2</title><path fill="none" stroke="black" d="M160.49,-81.9C173.24,-90.62 191.89,-103.37 205.86,-112.92"/><polygon fill="black" stroke="black" points="211.91,-117.05 204.36,-115.7 209.02,-115.08 206.13,-113.1 206.13,-113.1 206.13,-113.1 209.02,-115.08 207.91,-110.5 211.91,-117.05 211.91,-117.05"/></g><!-- 4 --><g id="node7" class="node"><title>4</title><ellipse fill="#ffffaa" stroke="#e31a1c" stroke-width="2" cx="226" cy="-72" rx="18" ry="18"/><text text-anchor="middle" x="226" y="-68.3" font-family="Lato" font-size="14.00">4</text></g><!-- 3&#45;&gt;4 --><g id="edge9" class="edge"><title>3&#45;&gt;4</title><path fill="none" stroke="black" d="M163.14,-72C174.12,-72 188.52,-72 200.67,-72"/><polygon fill="black" stroke="black" points="207.89,-72 200.89,-75.15 204.39,-72 200.89,-72 200.89,-72 200.89,-72 204.39,-72 200.89,-68.85 207.89,-72 207.89,-72"/></g><!-- 6 --><g id="node8" class="node"><title>6</title><polygon fill="#ffffaa" stroke="#e31a1c" stroke-width="2" points="226,-36 199,-18 226,0 253,-18 226,-36"/><text text-anchor="middle" x="226" y="-14.3" font-family="Lato" font-size="14.00">6</text></g><!-- 3&#45;&gt;6 --><g id="edge10" class="edge"><title>3&#45;&gt;6</title><path fill="none" stroke="#e31a1c" stroke-width="2" d="M160.49,-62.1C173.24,-53.38 191.89,-40.63 205.86,-31.08"/><polygon fill="#e31a1c" stroke="#e31a1c" stroke-width="2" points="211.91,-26.95 207.91,-33.5 209.31,-29.33 206.42,-31.31 206.13,-30.9 205.85,-30.48 208.74,-28.51 204.36,-28.3 211.91,-26.95 211.91,-26.95"/></g><!-- 2&#45;&gt;1 --><g id="edge6" class="edge"><title>2&#45;&gt;1</title><path fill="none" stroke="#33a02c" stroke-width="2" d="M207.56,-131.71C196.4,-132.89 181.78,-133.07 169.59,-132.24"/><polygon fill="#33a02c" stroke="#33a02c" stroke-width="2" points="162.37,-131.59 169.62,-129.08 165.9,-131.41 169.39,-131.72 169.34,-132.22 169.3,-132.71 165.81,-132.4 169.06,-135.35 162.37,-131.59 162.37,-131.59"/></g><!-- 5 --><g id="node6" class="node"><title>5</title><polygon fill="#ffffaa" stroke="#e31a1c" stroke-width="2" points="460,-90 433,-72 460,-54 487,-72 460,-90"/><text text-anchor="middle" x="460" y="-68.3" font-family="Lato" font-size="14.00">5</text></g><!-- 2&#45;&gt;5 --><g id="edge7" class="edge"><title>2&#45;&gt;5</title><path fill="none" stroke="black" d="M246.38,-121.49C287.92,-111.82 385.57,-89.09 432.67,-78.13"/><polygon fill="black" stroke="black" points="439.51,-76.54 433.41,-81.19 436.1,-77.33 432.69,-78.12 432.69,-78.12 432.69,-78.12 436.1,-77.33 431.98,-75.06 439.51,-76.54 439.51,-76.54"/></g><!-- 7 --><g id="node9" class="node"><title>7</title><ellipse fill="#ffffaa" stroke="#e31a1c" stroke-width="2" cx="307" cy="-18" rx="18" ry="18"/><text text-anchor="middle" x="307" y="-14.3" font-family="Lato" font-size="14.00">7</text></g><!-- 6&#45;&gt;7 --><g id="edge11" class="edge"><title>6&#45;&gt;7</title><path fill="none" stroke="black" d="M244.53,-12.28C255.75,-11.1 270.43,-10.93 282.64,-11.78"/><polygon fill="black" stroke="black" points="289.86,-12.43 282.61,-14.94 286.38,-12.12 282.89,-11.8 282.89,-11.8 282.89,-11.8 286.38,-12.12 283.17,-8.66 289.86,-12.43 289.86,-12.43"/></g><!-- 7&#45;&gt;6 --><g id="edge12" class="edge"><title>7&#45;&gt;6</title><path fill="none" stroke="black" d="M289.86,-23.57C278.84,-24.84 264.04,-25.09 251.56,-24.3"/><polygon fill="black" stroke="black" points="244.53,-23.72 251.77,-21.16 248.02,-24.01 251.51,-24.3 251.51,-24.3 251.51,-24.3 248.02,-24.01 251.25,-27.44 244.53,-23.72 244.53,-23.72"/></g><!-- 8 --><g id="node10" class="node"><title>8</title><ellipse fill="#ffffaa" stroke="#e31a1c" stroke-width="2" cx="379" cy="-49" rx="18" ry="18"/><text text-anchor="middle" x="379" y="-45.3" font-family="Lato" font-size="14.00">8</text></g><!-- 7&#45;&gt;8 --><g id="edge13" class="edge"><title>7&#45;&gt;8</title><path fill="none" stroke="#e31a1c" stroke-width="2" d="M323.88,-25.03C333.28,-29.2 345.33,-34.53 355.67,-39.11"/><polygon fill="#e31a1c" stroke="#e31a1c" stroke-width="2" points="362.18,-41.99 354.5,-42.04 358.78,-41.03 355.58,-39.62 355.78,-39.16 355.98,-38.7 359.18,-40.12 357.05,-36.28 362.18,-41.99 362.18,-41.99"/></g><!-- 8&#45;&gt;5 --><g id="edge14" class="edge"><title>8&#45;&gt;5</title><path fill="none" stroke="#e31a1c" stroke-width="2" d="M396.37,-53.77C407.17,-56.91 421.54,-61.1 433.79,-64.66"/><polygon fill="#e31a1c" stroke="#e31a1c" stroke-width="2" points="440.72,-66.68 433.12,-67.75 437.22,-66.18 433.86,-65.2 434,-64.72 434.14,-64.24 437.5,-65.22 434.88,-61.7 440.72,-66.68 440.72,-66.68"/></g></g></svg>)
<spot.jupyter.SVG object>
%% Cell type:markdown id: tags:
## Input/Output
......@@ -30,11 +136,11 @@
```
%%%% Output: execute_result
![](data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><!-- Generated by graphviz version 2.43.0 (0)--><!-- Pages: 1 --><svg width="567pt" height="338pt"viewBox="0.00 0.00 566.58 337.76" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="graph0" class="graph" transform="scale(1.0 1.0) rotate(0) translate(4 333.76)"><polygon fill="white" stroke="transparent" points="-4,4 -4,-333.76 562.58,-333.76 562.58,4 -4,4"/><text text-anchor="start" x="197.79" y="-315.56" font-family="Lato" font-size="14.00">Fin(</text><text text-anchor="start" x="220.79" y="-315.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text><text text-anchor="start" x="236.79" y="-315.56" font-family="Lato" font-size="14.00">) &amp; (Inf(</text><text text-anchor="start" x="282.79" y="-315.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text><text text-anchor="start" x="298.79" y="-315.56" font-family="Lato" font-size="14.00">) | Fin(</text><text text-anchor="start" x="336.79" y="-315.56" font-family="Lato" font-size="14.00" fill="#1f78b4">⓿</text><text text-anchor="start" x="352.79" y="-315.56" font-family="Lato" font-size="14.00">))</text><text text-anchor="start" x="223.79" y="-301.56" font-family="Lato" font-size="14.00">[parity max odd 3]</text><!-- I --><!-- 0 --><g id="node2" class="node"><title>0</title><ellipse fill="#ffffaa" stroke="black" cx="56" cy="-171.76" rx="18" ry="18"/><text text-anchor="middle" x="56" y="-168.06" font-family="Lato" font-size="14.00">0</text></g><!-- I&#45;&gt;0 --><g id="edge1" class="edge"><title>I&#45;&gt;0</title><path fill="none" stroke="black" d="M1.15,-171.76C2.79,-171.76 17.15,-171.76 30.63,-171.76"/><polygon fill="black" stroke="black" points="37.94,-171.76 30.94,-174.91 34.44,-171.76 30.94,-171.76 30.94,-171.76 30.94,-171.76 34.44,-171.76 30.94,-168.61 37.94,-171.76 37.94,-171.76"/></g><!-- 1 --><g id="node3" class="node"><title>1</title><polygon fill="#ffffaa" stroke="black" points="148.98,-163.76 126.02,-145.76 148.98,-127.76 171.94,-145.76 148.98,-163.76"/><text text-anchor="middle" x="148.98" y="-142.06" font-family="Lato" font-size="14.00">1</text></g><!-- 0&#45;&gt;1 --><g id="edge2" class="edge"><title>0&#45;&gt;1</title><path fill="none" stroke="black" d="M69.9,-159.68C76.09,-154.68 83.92,-149.43 92,-146.76 101.41,-143.65 112.21,-142.86 121.8,-143.03"/><polygon fill="black" stroke="black" points="128.85,-143.33 121.72,-146.18 125.35,-143.18 121.86,-143.04 121.86,-143.04 121.86,-143.04 125.35,-143.18 121.99,-139.89 128.85,-143.33 128.85,-143.33"/><text text-anchor="start" x="94.5" y="-165.56" font-family="Lato" font-size="14.00">!a</text><text text-anchor="start" x="92" y="-150.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 2 --><g id="node4" class="node"><title>2</title><polygon fill="#ffffaa" stroke="black" points="148.98,-217.76 126.02,-199.76 148.98,-181.76 171.94,-199.76 148.98,-217.76"/><text text-anchor="middle" x="148.98" y="-196.06" font-family="Lato" font-size="14.00">2</text></g><!-- 0&#45;&gt;2 --><g id="edge3" class="edge"><title>0&#45;&gt;2</title><path fill="none" stroke="black" d="M73.69,-176.89C88.1,-181.33 109.07,-187.78 125.05,-192.7"/><polygon fill="black" stroke="black" points="132.01,-194.84 124.39,-195.79 128.66,-193.81 125.32,-192.78 125.32,-192.78 125.32,-192.78 128.66,-193.81 126.24,-189.77 132.01,-194.84 132.01,-194.84"/><text text-anchor="start" x="96.5" y="-205.56" font-family="Lato" font-size="14.00">a</text><text text-anchor="start" x="92" y="-190.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 3 --><g id="node5" class="node"><title>3</title><ellipse fill="#ffffaa" stroke="black" cx="241.96" cy="-60.76" rx="18" ry="18"/><text text-anchor="middle" x="241.96" y="-57.06" font-family="Lato" font-size="14.00">3</text></g><!-- 1&#45;&gt;3 --><g id="edge4" class="edge"><title>1&#45;&gt;3</title><path fill="none" stroke="black" d="M160.06,-136.34C175.16,-122.24 203.86,-95.42 222.7,-77.82"/><polygon fill="black" stroke="black" points="228.21,-72.67 225.24,-79.75 225.65,-75.06 223.09,-77.45 223.09,-77.45 223.09,-77.45 225.65,-75.06 220.94,-75.15 228.21,-72.67 228.21,-72.67"/><text text-anchor="start" x="191.96" y="-126.56" font-family="Lato" font-size="14.00">!b</text><text text-anchor="start" x="189.96" y="-111.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 4 --><g id="node6" class="node"><title>4</title><ellipse fill="#ffffaa" stroke="black" cx="241.96" cy="-182.76" rx="18" ry="18"/><text text-anchor="middle" x="241.96" y="-179.06" font-family="Lato" font-size="14.00">4</text></g><!-- 1&#45;&gt;4 --><g id="edge5" class="edge"><title>1&#45;&gt;4</title><path fill="none" stroke="black" d="M170.91,-146.58C181.75,-147.62 194.98,-149.89 205.96,-154.76 212.12,-157.49 218.12,-161.58 223.37,-165.8"/><polygon fill="black" stroke="black" points="228.73,-170.36 221.36,-168.22 226.07,-168.09 223.4,-165.83 223.4,-165.83 223.4,-165.83 226.07,-168.09 225.44,-163.43 228.73,-170.36 228.73,-170.36"/><text text-anchor="start" x="193.96" y="-173.56" font-family="Lato" font-size="14.00">b</text><text text-anchor="start" x="189.96" y="-158.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 2&#45;&gt;4 --><g id="edge6" class="edge"><title>2&#45;&gt;4</title><path fill="none" stroke="black" d="M167.95,-196.4C181.93,-193.79 201.45,-190.14 216.79,-187.27"/><polygon fill="black" stroke="black" points="223.94,-185.94 217.64,-190.32 220.5,-186.58 217.06,-187.22 217.06,-187.22 217.06,-187.22 220.5,-186.58 216.48,-184.13 223.94,-185.94 223.94,-185.94"/><text text-anchor="start" x="193.96" y="-210.56" font-family="Lato" font-size="14.00">b</text><text text-anchor="start" x="189.96" y="-195.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 5 --><g id="node7" class="node"><title>5</title><ellipse fill="#ffffaa" stroke="black" cx="427.92" cy="-140.76" rx="18" ry="18"/><text text-anchor="middle" x="427.92" y="-137.06" font-family="Lato" font-size="14.00">5</text></g><!-- 2&#45;&gt;5 --><g id="edge7" class="edge"><title>2&#45;&gt;5</title><path fill="none" stroke="black" d="M160.75,-208.85C168.39,-214.75 179.16,-222.01 189.96,-225.76 275.06,-255.28 319.26,-296.01 391.92,-242.76 413.34,-227.05 401.22,-210.86 409.92,-185.76 412.38,-178.66 415.21,-170.99 417.85,-164.03"/><polygon fill="black" stroke="black" points="420.4,-157.35 420.84,-165.01 419.15,-160.62 417.9,-163.89 417.9,-163.89 417.9,-163.89 419.15,-160.62 414.96,-162.76 420.4,-157.35 420.4,-157.35"/><text text-anchor="start" x="279.96" y="-282.56" font-family="Lato" font-size="14.00">!b</text><text text-anchor="start" x="277.96" y="-267.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 6 --><g id="node8" class="node"><title>6</title><polygon fill="#ffffaa" stroke="black" points="528.25,-71.76 505.29,-53.76 528.25,-35.76 551.21,-53.76 528.25,-71.76"/><text text-anchor="middle" x="528.25" y="-50.06" font-family="Lato" font-size="14.00">6</text></g><!-- 3&#45;&gt;6 --><g id="edge8" class="edge"><title>3&#45;&gt;6</title><path fill="none" stroke="black" d="M257.63,-51.19C263.78,-47.39 271.08,-43.12 277.96,-39.76 319.9,-19.23 330.01,-10.35 375.92,-1.76 425.97,7.61 481.93,-23.1 509.68,-41.29"/><polygon fill="black" stroke="black" points="515.79,-45.4 508.22,-44.11 512.88,-43.45 509.98,-41.5 509.98,-41.5 509.98,-41.5 512.88,-43.45 511.74,-38.88 515.79,-45.4 515.79,-45.4"/><text text-anchor="start" x="378.42" y="-20.56" font-family="Lato" font-size="14.00">!a</text><text text-anchor="start" x="375.92" y="-5.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 7 --><g id="node9" class="node"><title>7</title><polygon fill="#ffffaa" stroke="black" points="334.94,-124.76 311.98,-106.76 334.94,-88.76 357.89,-106.76 334.94,-124.76"/><text text-anchor="middle" x="334.94" y="-103.06" font-family="Lato" font-size="14.00">7</text></g><!-- 3&#45;&gt;7 --><g id="edge9" class="edge"><title>3&#45;&gt;7</title><path fill="none" stroke="black" d="M258.39,-68.56C273.79,-76.35 297.5,-88.33 314.24,-96.8"/><polygon fill="black" stroke="black" points="320.51,-99.97 312.84,-99.62 317.38,-98.39 314.26,-96.81 314.26,-96.81 314.26,-96.81 317.38,-98.39 315.68,-94 320.51,-99.97 320.51,-99.97"/><text text-anchor="start" x="282.46" y="-104.56" font-family="Lato" font-size="14.00">a</text><text text-anchor="start" x="277.96" y="-89.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 8 --><g id="node10" class="node"><title>8</title><polygon fill="#ffffaa" stroke="black" points="334.94,-222.76 311.98,-204.76 334.94,-186.76 357.89,-204.76 334.94,-222.76"/><text text-anchor="middle" x="334.94" y="-201.06" font-family="Lato" font-size="14.00">8</text></g><!-- 4&#45;&gt;8 --><g id="edge10" class="edge"><title>4&#45;&gt;8</title><path fill="none" stroke="black" d="M259.64,-186.79C273.79,-190.21 294.25,-195.16 310.12,-199"/><polygon fill="black" stroke="black" points="317.05,-200.67 309.5,-202.09 313.65,-199.85 310.24,-199.03 310.24,-199.03 310.24,-199.03 313.65,-199.85 310.98,-195.97 317.05,-200.67 317.05,-200.67"/><text text-anchor="start" x="281.46" y="-213.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="277.96" y="-198.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 5&#45;&gt;6 --><g id="edge12" class="edge"><title>5&#45;&gt;6</title><path fill="none" stroke="black" d="M442.18,-129.03C460.14,-113.14 492.15,-84.82 511.36,-67.81"/><polygon fill="black" stroke="black" points="516.89,-62.92 513.73,-69.92 514.27,-65.24 511.65,-67.56 511.65,-67.56 511.65,-67.56 514.27,-65.24 509.56,-65.2 516.89,-62.92 516.89,-62.92"/><text text-anchor="start" x="466.42" y="-125.56" font-family="Lato" font-size="14.00">!a</text><text text-anchor="start" x="463.92" y="-110.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 5&#45;&gt;7 --><g id="edge11" class="edge"><title>5&#45;&gt;7</title><path fill="none" stroke="black" d="M409.86,-142.24C399.69,-142.52 386.71,-141.81 375.92,-137.76 366.67,-134.29 357.82,-127.88 350.82,-121.79"/><polygon fill="black" stroke="black" points="345.4,-116.81 352.69,-119.22 347.98,-119.18 350.56,-121.55 350.56,-121.55 350.56,-121.55 347.98,-119.18 348.43,-123.87 345.4,-116.81 345.4,-116.81"/><text text-anchor="start" x="380.42" y="-159.56" font-family="Lato" font-size="14.00">a</text><text text-anchor="start" x="375.92" y="-144.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 6&#45;&gt;3 --><g id="edge13" class="edge"><title>6&#45;&gt;3</title><path fill="none" stroke="black" d="M505.57,-54.29C453.62,-55.57 322.27,-58.81 267.52,-60.15"/><polygon fill="black" stroke="black" points="260.31,-60.33 267.23,-57.01 263.81,-60.25 267.31,-60.16 267.31,-60.16 267.31,-60.16 263.81,-60.25 267.39,-63.31 260.31,-60.33 260.31,-60.33"/><text text-anchor="start" x="379.42" y="-75.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="375.92" y="-60.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 7&#45;&gt;5 --><g id="edge14" class="edge"><title>7&#45;&gt;5</title><path fill="none" stroke="black" d="M352.29,-102.15C363.83,-99.77 379.4,-98.37 391.92,-103.76 400.16,-107.31 407.38,-113.87 413.08,-120.49"/><polygon fill="black" stroke="black" points="417.5,-126 410.66,-122.51 415.31,-123.27 413.12,-120.54 413.12,-120.54 413.12,-120.54 415.31,-123.27 415.57,-118.57 417.5,-126 417.5,-126"/><text text-anchor="start" x="379.42" y="-122.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="375.92" y="-107.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 8&#45;&gt;4 --><g id="edge15" class="edge"><title>8&#45;&gt;4</title><path fill="none" stroke="black" d="M327.6,-192.49C320.95,-181.1 309.32,-164.86 293.96,-157.76 282.73,-152.57 270.27,-158.46 260.47,-165.83"/><polygon fill="black" stroke="black" points="255.04,-170.26 258.47,-163.39 257.75,-168.04 260.47,-165.83 260.47,-165.83 260.47,-165.83 257.75,-168.04 262.46,-168.27 255.04,-170.26 255.04,-170.26"/><text text-anchor="start" x="281.96" y="-176.56" font-family="Lato" font-size="14.00">b</text><text text-anchor="start" x="277.96" y="-161.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 9 --><g id="node11" class="node"><title>9</title><ellipse fill="#ffffaa" stroke="black" cx="427.92" cy="-212.76" rx="18" ry="18"/><text text-anchor="middle" x="427.92" y="-209.06" font-family="Lato" font-size="14.00">9</text></g><!-- 8&#45;&gt;9 --><g id="edge16" class="edge"><title>8&#45;&gt;9</title><path fill="none" stroke="black" d="M356.13,-206.53C369.86,-207.74 388.1,-209.35 402.62,-210.62"/><polygon fill="black" stroke="black" points="409.84,-211.26 402.59,-213.78 406.35,-210.95 402.86,-210.64 402.86,-210.64 402.86,-210.64 406.35,-210.95 403.14,-207.51 409.84,-211.26 409.84,-211.26"/><text text-anchor="start" x="377.92" y="-227.56" font-family="Lato" font-size="14.00">!b</text><text text-anchor="start" x="375.92" y="-212.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 10 --><g id="node12" class="node"><title>10</title><polygon fill="#ffffaa" stroke="black" points="528.25,-229.76 498.08,-211.76 528.25,-193.76 558.41,-211.76 528.25,-229.76"/><text text-anchor="middle" x="528.25" y="-208.06" font-family="Lato" font-size="14.00">10</text></g><!-- 9&#45;&gt;10 --><g id="edge17" class="edge"><title>9&#45;&gt;10</title><path fill="none" stroke="black" d="M441.39,-200.41C447.61,-195.11 455.58,-189.52 463.92,-186.76 479.35,-181.65 496.47,-189.25 509.02,-197.37"/><polygon fill="black" stroke="black" points="514.78,-201.34 507.23,-199.96 511.9,-199.36 509.02,-197.37 509.02,-197.37 509.02,-197.37 511.9,-199.36 510.81,-194.78 514.78,-201.34 514.78,-201.34"/><text text-anchor="start" x="467.42" y="-205.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="463.92" y="-190.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 10&#45;&gt;9 --><g id="edge18" class="edge"><title>10&#45;&gt;9</title><path fill="none" stroke="black" d="M503.51,-215.16C491.63,-216.48 477.02,-217.51 463.92,-216.76 460.44,-216.56 456.77,-216.25 453.17,-215.89"/><polygon fill="black" stroke="black" points="445.97,-215.1 453.27,-212.73 449.45,-215.48 452.93,-215.87 452.93,-215.87 452.93,-215.87 449.45,-215.48 452.59,-219 445.97,-215.1 445.97,-215.1"/><text text-anchor="start" x="467.42" y="-235.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="463.92" y="-220.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g></g></svg>)
<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f9bf8477330> >
<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fa3979355d0> >
%% Cell type:markdown id: tags:
In the graphical output, player 0 is represented by circles (or ellipses or rounded rectangles depending on the situations), while player 1's states are diamond shaped. In the case of `ltlsynt`, player 0 plays the role of the environment, and player 1 plays the role of the controler.
......@@ -46,15 +152,11 @@
print(game.to_str('hoa'))
```
%% Cell type:markdown id: tags:
# Solving games
%% Cell type:markdown id: tags:
The `solve_parity_game()` function returns the player winning from the initial state (`False` for player 0, and `True` for player 1).
Here is the solution of this particular game.
%% Cell type:code id: tags:
``` python
spot.solve_parity_game(game)
......@@ -62,21 +164,21 @@
%%%% Output: execute_result
True
%% Cell type:markdown id: tags:
Additional information about the player winning in each state, and the strategy have been stored in the automaton but are not displayed by default.
Calling the `highlight_strategy` function will decorate the game's automaton with colors showing the winning regions (states from which a player has a strategy to win), and strategy (which transition should be used for each winning state owned by that player) of a given player. Here green corresponds to player 1 (who tries to satisfy the acceptance condition), and red to player 0 (who tries not to).
%% Cell type:code id: tags:
``` python
spot.highlight_strategy(game)
```
%%%% Output: execute_result
![](data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><!-- Generated by graphviz version 2.43.0 (0)--><!-- Pages: 1 --><svg width="567pt" height="338pt"viewBox="0.00 0.00 566.58 337.76" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="graph0" class="graph" transform="scale(1.0 1.0) rotate(0) translate(4 333.76)"><polygon fill="white" stroke="transparent" points="-4,4 -4,-333.76 562.58,-333.76 562.58,4 -4,4"/><text text-anchor="start" x="197.79" y="-315.56" font-family="Lato" font-size="14.00">Fin(</text><text text-anchor="start" x="220.79" y="-315.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text><text text-anchor="start" x="236.79" y="-315.56" font-family="Lato" font-size="14.00">) &amp; (Inf(</text><text text-anchor="start" x="282.79" y="-315.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text><text text-anchor="start" x="298.79" y="-315.56" font-family="Lato" font-size="14.00">) | Fin(</text><text text-anchor="start" x="336.79" y="-315.56" font-family="Lato" font-size="14.00" fill="#1f78b4">⓿</text><text text-anchor="start" x="352.79" y="-315.56" font-family="Lato" font-size="14.00">))</text><text text-anchor="start" x="223.79" y="-301.56" font-family="Lato" font-size="14.00">[parity max odd 3]</text><!-- I --><!-- 0 --><g id="node2" class="node"><title>0</title><ellipse fill="#ffffaa" stroke="#33a02c" stroke-width="2" cx="56" cy="-171.76" rx="18" ry="18"/><text text-anchor="middle" x="56" y="-168.06" font-family="Lato" font-size="14.00">0</text></g><!-- I&#45;&gt;0 --><g id="edge1" class="edge"><title>I&#45;&gt;0</title><path fill="none" stroke="black" d="M1.15,-171.76C2.79,-171.76 17.15,-171.76 30.63,-171.76"/><polygon fill="black" stroke="black" points="37.94,-171.76 30.94,-174.91 34.44,-171.76 30.94,-171.76 30.94,-171.76 30.94,-171.76 34.44,-171.76 30.94,-168.61 37.94,-171.76 37.94,-171.76"/></g><!-- 1 --><g id="node3" class="node"><title>1</title><polygon fill="#ffffaa" stroke="#33a02c" stroke-width="2" points="148.98,-163.76 126.02,-145.76 148.98,-127.76 171.94,-145.76 148.98,-163.76"/><text text-anchor="middle" x="148.98" y="-142.06" font-family="Lato" font-size="14.00">1</text></g><!-- 0&#45;&gt;1 --><g id="edge2" class="edge"><title>0&#45;&gt;1</title><path fill="none" stroke="black" d="M69.9,-159.68C76.09,-154.68 83.92,-149.43 92,-146.76 101.41,-143.65 112.21,-142.86 121.8,-143.03"/><polygon fill="black" stroke="black" points="128.85,-143.33 121.72,-146.18 125.35,-143.18 121.86,-143.04 121.86,-143.04 121.86,-143.04 125.35,-143.18 121.99,-139.89 128.85,-143.33 128.85,-143.33"/><text text-anchor="start" x="94.5" y="-165.56" font-family="Lato" font-size="14.00">!a</text><text text-anchor="start" x="92" y="-150.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 2 --><g id="node4" class="node"><title>2</title><polygon fill="#ffffaa" stroke="#33a02c" stroke-width="2" points="148.98,-217.76 126.02,-199.76 148.98,-181.76 171.94,-199.76 148.98,-217.76"/><text text-anchor="middle" x="148.98" y="-196.06" font-family="Lato" font-size="14.00">2</text></g><!-- 0&#45;&gt;2 --><g id="edge3" class="edge"><title>0&#45;&gt;2</title><path fill="none" stroke="black" d="M73.69,-176.89C88.1,-181.33 109.07,-187.78 125.05,-192.7"/><polygon fill="black" stroke="black" points="132.01,-194.84 124.39,-195.79 128.66,-193.81 125.32,-192.78 125.32,-192.78 125.32,-192.78 128.66,-193.81 126.24,-189.77 132.01,-194.84 132.01,-194.84"/><text text-anchor="start" x="96.5" y="-205.56" font-family="Lato" font-size="14.00">a</text><text text-anchor="start" x="92" y="-190.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 3 --><g id="node5" class="node"><title>3</title><ellipse fill="#ffffaa" stroke="#e31a1c" stroke-width="2" cx="241.96" cy="-60.76" rx="18" ry="18"/><text text-anchor="middle" x="241.96" y="-57.06" font-family="Lato" font-size="14.00">3</text></g><!-- 1&#45;&gt;3 --><g id="edge4" class="edge"><title>1&#45;&gt;3</title><path fill="none" stroke="black" d="M160.06,-136.34C175.16,-122.24 203.86,-95.42 222.7,-77.82"/><polygon fill="black" stroke="black" points="228.21,-72.67 225.24,-79.75 225.65,-75.06 223.09,-77.45 223.09,-77.45 223.09,-77.45 225.65,-75.06 220.94,-75.15 228.21,-72.67 228.21,-72.67"/><text text-anchor="start" x="191.96" y="-126.56" font-family="Lato" font-size="14.00">!b</text><text text-anchor="start" x="189.96" y="-111.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 4 --><g id="node6" class="node"><title>4</title><ellipse fill="#ffffaa" stroke="#33a02c" stroke-width="2" cx="241.96" cy="-182.76" rx="18" ry="18"/><text text-anchor="middle" x="241.96" y="-179.06" font-family="Lato" font-size="14.00">4</text></g><!-- 1&#45;&gt;4 --><g id="edge5" class="edge"><title>1&#45;&gt;4</title><path fill="none" stroke="#33a02c" stroke-width="2" d="M170.91,-146.58C181.75,-147.62 194.98,-149.89 205.96,-154.76 212.12,-157.49 218.12,-161.58 223.37,-165.8"/><polygon fill="#33a02c" stroke="#33a02c" stroke-width="2" points="228.73,-170.36 221.36,-168.22 225.74,-168.48 223.08,-166.21 223.4,-165.83 223.72,-165.44 226.39,-167.71 225.44,-163.43 228.73,-170.36 228.73,-170.36"/><text text-anchor="start" x="193.96" y="-173.56" font-family="Lato" font-size="14.00">b</text><text text-anchor="start" x="189.96" y="-158.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 2&#45;&gt;4 --><g id="edge6" class="edge"><title>2&#45;&gt;4</title><path fill="none" stroke="#33a02c" stroke-width="2" d="M167.95,-196.4C181.93,-193.79 201.45,-190.14 216.79,-187.27"/><polygon fill="#33a02c" stroke="#33a02c" stroke-width="2" points="223.94,-185.94 217.64,-190.32 220.6,-187.07 217.15,-187.72 217.06,-187.22 216.97,-186.73 220.41,-186.09 216.48,-184.13 223.94,-185.94 223.94,-185.94"/><text text-anchor="start" x="193.96" y="-210.56" font-family="Lato" font-size="14.00">b</text><text text-anchor="start" x="189.96" y="-195.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 5 --><g id="node7" class="node"><title>5</title><ellipse fill="#ffffaa" stroke="#e31a1c" stroke-width="2" cx="427.92" cy="-140.76" rx="18" ry="18"/><text text-anchor="middle" x="427.92" y="-137.06" font-family="Lato" font-size="14.00">5</text></g><!-- 2&#45;&gt;5 --><g id="edge7" class="edge"><title>2&#45;&gt;5</title><path fill="none" stroke="black" d="M160.75,-208.85C168.39,-214.75 179.16,-222.01 189.96,-225.76 275.06,-255.28 319.26,-296.01 391.92,-242.76 413.34,-227.05 401.22,-210.86 409.92,-185.76 412.38,-178.66 415.21,-170.99 417.85,-164.03"/><polygon fill="black" stroke="black" points="420.4,-157.35 420.84,-165.01 419.15,-160.62 417.9,-163.89 417.9,-163.89 417.9,-163.89 419.15,-160.62 414.96,-162.76 420.4,-157.35 420.4,-157.35"/><text text-anchor="start" x="279.96" y="-282.56" font-family="Lato" font-size="14.00">!b</text><text text-anchor="start" x="277.96" y="-267.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 6 --><g id="node8" class="node"><title>6</title><polygon fill="#ffffaa" stroke="#e31a1c" stroke-width="2" points="528.25,-71.76 505.29,-53.76 528.25,-35.76 551.21,-53.76 528.25,-71.76"/><text text-anchor="middle" x="528.25" y="-50.06" font-family="Lato" font-size="14.00">6</text></g><!-- 3&#45;&gt;6 --><g id="edge8" class="edge"><title>3&#45;&gt;6</title><path fill="none" stroke="black" d="M257.63,-51.19C263.78,-47.39 271.08,-43.12 277.96,-39.76 319.9,-19.23 330.01,-10.35 375.92,-1.76 425.97,7.61 481.93,-23.1 509.68,-41.29"/><polygon fill="black" stroke="black" points="515.79,-45.4 508.22,-44.11 512.88,-43.45 509.98,-41.5 509.98,-41.5 509.98,-41.5 512.88,-43.45 511.74,-38.88 515.79,-45.4 515.79,-45.4"/><text text-anchor="start" x="378.42" y="-20.56" font-family="Lato" font-size="14.00">!a</text><text text-anchor="start" x="375.92" y="-5.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 7 --><g id="node9" class="node"><title>7</title><polygon fill="#ffffaa" stroke="#e31a1c" stroke-width="2" points="334.94,-124.76 311.98,-106.76 334.94,-88.76 357.89,-106.76 334.94,-124.76"/><text text-anchor="middle" x="334.94" y="-103.06" font-family="Lato" font-size="14.00">7</text></g><!-- 3&#45;&gt;7 --><g id="edge9" class="edge"><title>3&#45;&gt;7</title><path fill="none" stroke="#e31a1c" stroke-width="2" d="M258.39,-68.56C273.79,-76.35 297.5,-88.33 314.24,-96.8"/><polygon fill="#e31a1c" stroke="#e31a1c" stroke-width="2" points="320.51,-99.97 312.84,-99.62 317.16,-98.84 314.03,-97.26 314.26,-96.81 314.49,-96.36 317.61,-97.94 315.68,-94 320.51,-99.97 320.51,-99.97"/><text text-anchor="start" x="282.46" y="-104.56" font-family="Lato" font-size="14.00">a</text><text text-anchor="start" x="277.96" y="-89.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 8 --><g id="node10" class="node"><title>8</title><polygon fill="#ffffaa" stroke="#33a02c" stroke-width="2" points="334.94,-222.76 311.98,-204.76 334.94,-186.76 357.89,-204.76 334.94,-222.76"/><text text-anchor="middle" x="334.94" y="-201.06" font-family="Lato" font-size="14.00">8</text></g><!-- 4&#45;&gt;8 --><g id="edge10" class="edge"><title>4&#45;&gt;8</title><path fill="none" stroke="black" d="M259.64,-186.79C273.79,-190.21 294.25,-195.16 310.12,-199"/><polygon fill="black" stroke="black" points="317.05,-200.67 309.5,-202.09 313.65,-199.85 310.24,-199.03 310.24,-199.03 310.24,-199.03 313.65,-199.85 310.98,-195.97 317.05,-200.67 317.05,-200.67"/><text text-anchor="start" x="281.46" y="-213.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="277.96" y="-198.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 5&#45;&gt;6 --><g id="edge12" class="edge"><title>5&#45;&gt;6</title><path fill="none" stroke="black" d="M442.18,-129.03C460.14,-113.14 492.15,-84.82 511.36,-67.81"/><polygon fill="black" stroke="black" points="516.89,-62.92 513.73,-69.92 514.27,-65.24 511.65,-67.56 511.65,-67.56 511.65,-67.56 514.27,-65.24 509.56,-65.2 516.89,-62.92 516.89,-62.92"/><text text-anchor="start" x="466.42" y="-125.56" font-family="Lato" font-size="14.00">!a</text><text text-anchor="start" x="463.92" y="-110.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 5&#45;&gt;7 --><g id="edge11" class="edge"><title>5&#45;&gt;7</title><path fill="none" stroke="#e31a1c" stroke-width="2" d="M409.86,-142.24C399.69,-142.52 386.71,-141.81 375.92,-137.76 366.67,-134.29 357.82,-127.88 350.82,-121.79"/><polygon fill="#e31a1c" stroke="#e31a1c" stroke-width="2" points="345.4,-116.81 352.69,-119.22 348.32,-118.81 350.9,-121.18 350.56,-121.55 350.22,-121.91 347.64,-119.55 348.43,-123.87 345.4,-116.81 345.4,-116.81"/><text text-anchor="start" x="380.42" y="-159.56" font-family="Lato" font-size="14.00">a</text><text text-anchor="start" x="375.92" y="-144.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 6&#45;&gt;3 --><g id="edge13" class="edge"><title>6&#45;&gt;3</title><path fill="none" stroke="black" d="M505.57,-54.29C453.62,-55.57 322.27,-58.81 267.52,-60.15"/><polygon fill="black" stroke="black" points="260.31,-60.33 267.23,-57.01 263.81,-60.25 267.31,-60.16 267.31,-60.16 267.31,-60.16 263.81,-60.25 267.39,-63.31 260.31,-60.33 260.31,-60.33"/><text text-anchor="start" x="379.42" y="-75.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="375.92" y="-60.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 7&#45;&gt;5 --><g id="edge14" class="edge"><title>7&#45;&gt;5</title><path fill="none" stroke="black" d="M352.29,-102.15C363.83,-99.77 379.4,-98.37 391.92,-103.76 400.16,-107.31 407.38,-113.87 413.08,-120.49"/><polygon fill="black" stroke="black" points="417.5,-126 410.66,-122.51 415.31,-123.27 413.12,-120.54 413.12,-120.54 413.12,-120.54 415.31,-123.27 415.57,-118.57 417.5,-126 417.5,-126"/><text text-anchor="start" x="379.42" y="-122.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="375.92" y="-107.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 8&#45;&gt;4 --><g id="edge15" class="edge"><title>8&#45;&gt;4</title><path fill="none" stroke="black" d="M327.6,-192.49C320.95,-181.1 309.32,-164.86 293.96,-157.76 282.73,-152.57 270.27,-158.46 260.47,-165.83"/><polygon fill="black" stroke="black" points="255.04,-170.26 258.47,-163.39 257.75,-168.04 260.47,-165.83 260.47,-165.83 260.47,-165.83 257.75,-168.04 262.46,-168.27 255.04,-170.26 255.04,-170.26"/><text text-anchor="start" x="281.96" y="-176.56" font-family="Lato" font-size="14.00">b</text><text text-anchor="start" x="277.96" y="-161.56" font-family="Lato" font-size="14.00" fill="#ff7f00">❷</text></g><!-- 9 --><g id="node11" class="node"><title>9</title><ellipse fill="#ffffaa" stroke="#33a02c" stroke-width="2" cx="427.92" cy="-212.76" rx="18" ry="18"/><text text-anchor="middle" x="427.92" y="-209.06" font-family="Lato" font-size="14.00">9</text></g><!-- 8&#45;&gt;9 --><g id="edge16" class="edge"><title>8&#45;&gt;9</title><path fill="none" stroke="#33a02c" stroke-width="2" d="M356.13,-206.53C369.86,-207.74 388.1,-209.35 402.62,-210.62"/><polygon fill="#33a02c" stroke="#33a02c" stroke-width="2" points="409.84,-211.26 402.59,-213.78 406.31,-211.45 402.82,-211.14 402.86,-210.64 402.91,-210.15 406.39,-210.45 403.14,-207.51 409.84,-211.26 409.84,-211.26"/><text text-anchor="start" x="377.92" y="-227.56" font-family="Lato" font-size="14.00">!b</text><text text-anchor="start" x="375.92" y="-212.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 10 --><g id="node12" class="node"><title>10</title><polygon fill="#ffffaa" stroke="#33a02c" stroke-width="2" points="528.25,-229.76 498.08,-211.76 528.25,-193.76 558.41,-211.76 528.25,-229.76"/><text text-anchor="middle" x="528.25" y="-208.06" font-family="Lato" font-size="14.00">10</text></g><!-- 9&#45;&gt;10 --><g id="edge17" class="edge"><title>9&#45;&gt;10</title><path fill="none" stroke="black" d="M441.39,-200.41C447.61,-195.11 455.58,-189.52 463.92,-186.76 479.35,-181.65 496.47,-189.25 509.02,-197.37"/><polygon fill="black" stroke="black" points="514.78,-201.34 507.23,-199.96 511.9,-199.36 509.02,-197.37 509.02,-197.37 509.02,-197.37 511.9,-199.36 510.81,-194.78 514.78,-201.34 514.78,-201.34"/><text text-anchor="start" x="467.42" y="-205.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="463.92" y="-190.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g><!-- 10&#45;&gt;9 --><g id="edge18" class="edge"><title>10&#45;&gt;9</title><path fill="none" stroke="#33a02c" stroke-width="2" d="M503.51,-215.16C491.63,-216.48 477.02,-217.51 463.92,-216.76 460.44,-216.56 456.77,-216.25 453.17,-215.89"/><polygon fill="#33a02c" stroke="#33a02c" stroke-width="2" points="445.97,-215.1 453.27,-212.73 449.51,-214.99 452.98,-215.37 452.93,-215.87 452.88,-216.36 449.4,-215.98 452.59,-219 445.97,-215.1 445.97,-215.1"/><text text-anchor="start" x="467.42" y="-235.56" font-family="Lato" font-size="14.00">1</text><text text-anchor="start" x="463.92" y="-220.56" font-family="Lato" font-size="14.00" fill="#ff4da0">❶</text></g></g></svg>)
<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f9bf83e1060> >
<spot.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fa37f087db0> >
%% Cell type:code id: tags:
``` python
```
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment