{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import spot\n",
"spot.setup()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Support for parity games\n",
"\n",
"The support for parity games is currently quite rudimentary, as Spot currently only uses those games in `ltlsynt`.\n",
"\n",
"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.\n",
"\n",
"Player 1 is winning if it has a strategy to satisfy the acceptance condition regardless of player 0's moves.\n",
"Player 0 is winning if it has a strategy to not satisfy the acceptance codition regardless of player 1's moves."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Input/Output\n",
"\n",
"An extension of the HOA format makes it possible to store the `state-player` property. This allows us to read the parity game constructed by `ltlsynt` using `spot.automaton()` like any other automaton."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7f9bf8477330> >"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"game = spot.automaton(\"ltlsynt --ins=a --outs=b -f '!b & GFa <-> Gb' --print-game-hoa |\");\n",
"game"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"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.\n",
"\n",
"In the HOA output, a header `spot-state-player` (or `spot.state-player` in HOA 1.1) lists the owner of each state."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"HOA: v1\n",
"States: 11\n",
"Start: 0\n",
"AP: 2 \"b\" \"a\"\n",
"acc-name: parity max odd 3\n",
"Acceptance: 3 Fin(2) & (Inf(1) | Fin(0))\n",
"properties: trans-labels explicit-labels trans-acc colored complete\n",
"properties: deterministic\n",
"spot-state-player: 0 1 1 0 0 0 1 1 1 0 1\n",
"--BODY--\n",
"State: 0\n",
"[!1] 1 {1}\n",
"[1] 2 {1}\n",
"State: 1\n",
"[!0] 3 {1}\n",
"[0] 4 {1}\n",
"State: 2\n",
"[0] 4 {1}\n",
"[!0] 5 {1}\n",
"State: 3\n",
"[!1] 6 {1}\n",
"[1] 7 {2}\n",
"State: 4\n",
"[t] 8 {2}\n",
"State: 5\n",
"[1] 7 {2}\n",
"[!1] 6 {1}\n",
"State: 6\n",
"[t] 3 {1}\n",
"State: 7\n",
"[t] 5 {2}\n",
"State: 8\n",
"[0] 4 {2}\n",
"[!0] 9 {1}\n",
"State: 9\n",
"[t] 10 {1}\n",
"State: 10\n",
"[t] 9 {1}\n",
"--END--\n"
]
}
],
"source": [
"print(game.to_str('hoa'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Solving games"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `solve_parity_game()` function returns the player winning from the initial state (`False` for player 0, and `True` for player 1)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.solve_parity_game(game)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Additional information about the player winning in each state, and the strategy have been stored in the automaton but are not displayed by default.\n",
"\n",
"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",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7f9bf83e1060> >"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.highlight_strategy(game)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.6rc1"
}
},
"nbformat": 4,
"nbformat_minor": 4
}