{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import spot\n", "from buddy import bddtrue\n", "spot.setup()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Support for games\n", "\n", "The support for games is currently quite rudimentary, as Spot currently only uses those games in `ltlsynt`.\n", "\n", "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.\n", "\n", "The support is currently restricted to games that use:\n", "- `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).\n", "- max odd parity acceptance: player 0 can win if the maximal value seen infinitely often is even" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Creating games from scratch\n", "\n", "Games can be [created like any automaton](https://spot.lrde.epita.fr/tut22.html). \n", "Using `set_state_players()` will fix the state owners." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "1->2\n", "\n", "\n", "\n", "\n", "\n", "3->2\n", "\n", "\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "3->4\n", "\n", "\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "3->6\n", "\n", "\n", "\n", "\n", "\n", "2->1\n", "\n", "\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "2->5\n", "\n", "\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "6->7\n", "\n", "\n", "\n", "\n", "\n", "7->6\n", "\n", "\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "7->8\n", "\n", "\n", "\n", "\n", "\n", "8->5\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bdict = spot.make_bdd_dict();\n", "game = spot.make_twa_graph(bdict)\n", "game.new_states(9)\n", "for (s, d) in ((0,1), (0, 3), \n", " (1, 0), (1, 2),\n", " (2, 1), (2, 5),\n", " (3, 2), (3, 4), (3, 6),\n", " (6, 7),\n", " (7, 6), (7, 8),\n", " (8, 5)):\n", " game.new_edge(s, d, bddtrue)\n", "spot.set_state_players(game, [True, False, True, False, True, True, True, False, False])\n", "game.show('.g') # Use \"g\" to hide the irrelevant edge labels." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `set_state_players()` function takes a list of owner for each of the states in the automaton. In the output,\n", "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). \n", "\n", "\n", "State ownership can also be manipulated by the following functions:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(True, False, True, False, True, True, True, False, False)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.get_state_players(game)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.get_state_player(game, 4)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "1->2\n", "\n", "\n", "\n", "\n", "\n", "3->2\n", "\n", "\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "3->4\n", "\n", "\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "3->6\n", "\n", "\n", "\n", "\n", "\n", "2->1\n", "\n", "\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "2->5\n", "\n", "\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "6->7\n", "\n", "\n", "\n", "\n", "\n", "7->6\n", "\n", "\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "7->8\n", "\n", "\n", "\n", "\n", "\n", "8->5\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.set_state_player(game, 4, False)\n", "game.show('.g')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Solving a game - The \"old\" way\n", "\n", "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. \n", "\n", "The return value of those function is simply the winner for the initial state." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.solve_safety_game(game)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "1->2\n", "\n", "\n", "\n", "\n", "\n", "3->2\n", "\n", "\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "3->4\n", "\n", "\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "3->6\n", "\n", "\n", "\n", "\n", "\n", "2->1\n", "\n", "\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "2->5\n", "\n", "\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "6->7\n", "\n", "\n", "\n", "\n", "\n", "7->6\n", "\n", "\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "7->8\n", "\n", "\n", "\n", "\n", "\n", "8->5\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.highlight_strategy(game)\n", "game.show('.g')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Solving a game - The new interface\n", "\n", "A strategy/control circuit can now be derived more conveniently from a LTL/PSL specification.\n", "The process is decomposed in to three steps:\n", "- Creating the game\n", "- Solving the game\n", "- Obtaining the strategy\n", "\n", "Each of these steps is parametrized by the same option structure called `synthesis_info`." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "game has 29 states and 55 edges\n", "output propositions are: o0\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Inf(\n", "\n", ") | (Fin(\n", "\n", ") & (Inf(\n", "\n", ") | Fin(\n", "\n", ")))\n", "[parity max odd 4]\n", "\n", "\n", "\n", "9\n", "\n", "9\n", "\n", "\n", "\n", "I->9\n", "\n", "\n", "\n", "\n", "\n", "25\n", "\n", "25\n", "\n", "\n", "\n", "9->25\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "\n", "26\n", "\n", "26\n", "\n", "\n", "\n", "9->26\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "\n", "27\n", "\n", "27\n", "\n", "\n", "\n", "9->27\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "\n", "28\n", "\n", "28\n", "\n", "\n", "\n", "9->28\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "10\n", "\n", "10\n", "\n", "\n", "\n", "0->10\n", "\n", "\n", "!i1\n", "\n", "\n", "\n", "\n", "11\n", "\n", "11\n", "\n", "\n", "\n", "0->11\n", "\n", "\n", "i1\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "10->1\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "11->0\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "12\n", "\n", "12\n", "\n", "\n", "\n", "1->12\n", "\n", "\n", "!i1\n", "\n", "\n", "\n", "\n", "13\n", "\n", "13\n", "\n", "\n", "\n", "1->13\n", "\n", "\n", "i1\n", "\n", "\n", "\n", "\n", "12->1\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "13->0\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "14\n", "\n", "14\n", "\n", "\n", "\n", "2->14\n", "\n", "\n", "i1\n", "\n", "\n", "\n", "\n", "16\n", "\n", "16\n", "\n", "\n", "\n", "2->16\n", "\n", "\n", "!i1\n", "\n", "\n", "\n", "\n", "15\n", "\n", "15\n", "\n", "\n", "\n", "14->15\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "16->2\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "3->13\n", "\n", "\n", "i1\n", "\n", "\n", "\n", "\n", "17\n", "\n", "17\n", "\n", "\n", "\n", "3->17\n", "\n", "\n", "!i1\n", "\n", "\n", "\n", "\n", "17->2\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "17->3\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "4->14\n", "\n", "\n", "i0\n", "\n", "\n", "\n", "\n", "18\n", "\n", "18\n", "\n", "\n", "\n", "4->18\n", "\n", "\n", "!i0\n", "\n", "\n", "\n", "\n", "18->4\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "5->14\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "\n", "5->16\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "\n", "5->18\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "\n", "19\n", "\n", "19\n", "\n", "\n", "\n", "5->19\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "\n", "19->5\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "6->10\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "\n", "6->11\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "\n", "20\n", "\n", "20\n", "\n", "\n", "\n", "6->20\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "\n", "21\n", "\n", "21\n", "\n", "\n", "\n", "6->21\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "\n", "20->4\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "20->7\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "21->4\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "21->6\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "7->12\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "\n", "7->13\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "\n", "22\n", "\n", "22\n", "\n", "\n", "\n", "7->22\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "\n", "23\n", "\n", "23\n", "\n", "\n", "\n", "7->23\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "\n", "22->4\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "22->7\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "23->4\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "23->6\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "8->13\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "\n", "8->17\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "\n", "8->23\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "\n", "24\n", "\n", "24\n", "\n", "\n", "\n", "8->24\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "\n", "24->5\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n", "24->8\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "\n", "25->8\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "26->3\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "27->6\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "28->0\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "15->14\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f78f67a4450> >" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "#Create the game\n", "gi = spot.synthesis_info()\n", "gi.s = spot.synthesis_info.algo_LAR # Use LAR algorithm\n", "\n", "game = spot.create_game(\"G((F(i0) && F(i1))->(G(i1<->(X(o0)))))\", [\"o0\"], gi)\n", "print(\"game has\", game.num_states(), \"states and\", game.num_edges(), \"edges\")\n", "print(\"output propositions are:\", \", \".join(spot.get_synthesis_output_aps(game)))\n", "display(game)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Found a solution: True\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Inf(\n", "\n", ") | (Fin(\n", "\n", ") & (Inf(\n", "\n", ") | Fin(\n", "\n", ")))\n", "[parity max odd 4]\n", "\n", "\n", "\n", "9\n", "\n", "9\n", "\n", "\n", "\n", "I->9\n", "\n", "\n", "\n", "\n", "\n", "25\n", "\n", "25\n", "\n", "\n", "\n", "9->25\n", "\n", "\n", "\n", "\n", "\n", "\n", "26\n", "\n", "26\n", "\n", "\n", "\n", "9->26\n", "\n", "\n", "\n", "\n", "\n", "\n", "27\n", "\n", "27\n", "\n", "\n", "\n", "9->27\n", "\n", "\n", "\n", "\n", "\n", "\n", "28\n", "\n", "28\n", "\n", "\n", "\n", "9->28\n", "\n", "\n", "\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "10\n", "\n", "10\n", "\n", "\n", "\n", "0->10\n", "\n", "\n", "\n", "\n", "\n", "\n", "11\n", "\n", "11\n", "\n", "\n", "\n", "0->11\n", "\n", "\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "10->1\n", "\n", "\n", "\n", "\n", "\n", "\n", "11->0\n", "\n", "\n", "\n", "\n", "\n", "\n", "12\n", "\n", "12\n", "\n", "\n", "\n", "1->12\n", "\n", "\n", "\n", "\n", "\n", "\n", "13\n", "\n", "13\n", "\n", "\n", "\n", "1->13\n", "\n", "\n", "\n", "\n", "\n", "\n", "12->1\n", "\n", "\n", "\n", "\n", "\n", "\n", "13->0\n", "\n", "\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "14\n", "\n", "14\n", "\n", "\n", "\n", "2->14\n", "\n", "\n", "\n", "\n", "\n", "\n", "16\n", "\n", "16\n", "\n", "\n", "\n", "2->16\n", "\n", "\n", "\n", "\n", "\n", "\n", "15\n", "\n", "15\n", "\n", "\n", "\n", "14->15\n", "\n", "\n", "\n", "\n", "\n", "\n", "16->2\n", "\n", "\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "3->13\n", "\n", "\n", "\n", "\n", "\n", "\n", "17\n", "\n", "17\n", "\n", "\n", "\n", "3->17\n", "\n", "\n", "\n", "\n", "\n", "\n", "17->2\n", "\n", "\n", "\n", "\n", "\n", "\n", "17->3\n", "\n", "\n", "\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "4->14\n", "\n", "\n", "\n", "\n", "\n", "\n", "18\n", "\n", "18\n", "\n", "\n", "\n", "4->18\n", "\n", "\n", "\n", "\n", "\n", "\n", "18->4\n", "\n", "\n", "\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "5->14\n", "\n", "\n", "\n", "\n", "\n", "\n", "5->16\n", "\n", "\n", "\n", "\n", "\n", "\n", "5->18\n", "\n", "\n", "\n", "\n", "\n", "\n", "19\n", "\n", "19\n", "\n", "\n", "\n", "5->19\n", "\n", "\n", "\n", "\n", "\n", "\n", "19->5\n", "\n", "\n", "\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "6->10\n", "\n", "\n", "\n", "\n", "\n", "\n", "6->11\n", "\n", "\n", "\n", "\n", "\n", "\n", "20\n", "\n", "20\n", "\n", "\n", "\n", "6->20\n", "\n", "\n", "\n", "\n", "\n", "\n", "21\n", "\n", "21\n", "\n", "\n", "\n", "6->21\n", "\n", "\n", "\n", "\n", "\n", "\n", "20->4\n", "\n", "\n", "\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "20->7\n", "\n", "\n", "\n", "\n", "\n", "\n", "21->4\n", "\n", "\n", "\n", "\n", "\n", "\n", "21->6\n", "\n", "\n", "\n", "\n", "\n", "\n", "7->12\n", "\n", "\n", "\n", "\n", "\n", "\n", "7->13\n", "\n", "\n", "\n", "\n", "\n", "\n", "22\n", "\n", "22\n", "\n", "\n", "\n", "7->22\n", "\n", "\n", "\n", "\n", "\n", "\n", "23\n", "\n", "23\n", "\n", "\n", "\n", "7->23\n", "\n", "\n", "\n", "\n", "\n", "\n", "22->4\n", "\n", "\n", "\n", "\n", "\n", "\n", "22->7\n", "\n", "\n", "\n", "\n", "\n", "\n", "23->4\n", "\n", "\n", "\n", "\n", "\n", "\n", "23->6\n", "\n", "\n", "\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "8->13\n", "\n", "\n", "\n", "\n", "\n", "\n", "8->17\n", "\n", "\n", "\n", "\n", "\n", "\n", "8->23\n", "\n", "\n", "\n", "\n", "\n", "\n", "24\n", "\n", "24\n", "\n", "\n", "\n", "8->24\n", "\n", "\n", "\n", "\n", "\n", "\n", "24->5\n", "\n", "\n", "\n", "\n", "\n", "\n", "24->8\n", "\n", "\n", "\n", "\n", "\n", "\n", "25->8\n", "\n", "\n", "\n", "\n", "\n", "\n", "26->3\n", "\n", "\n", "\n", "\n", "\n", "\n", "27->6\n", "\n", "\n", "\n", "\n", "\n", "\n", "28->0\n", "\n", "\n", "\n", "\n", "\n", "\n", "15->14\n", "\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#Solve the game\n", "print(\"Found a solution:\", spot.solve_game(game))\n", "spot.highlight_strategy(game)\n", "game.show('.g')" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "simplification lvl 0\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "!i0 & !i1 & !o0\n", "\n", "\n", "\n", "1->2\n", "\n", "\n", "i0 & !i1 & !o0\n", "\n", "\n", "\n", "1->3\n", "\n", "\n", "!i0 & i1 & !o0\n", "\n", "\n", "\n", "1->4\n", "\n", "\n", "i0 & i1 & !o0\n", "\n", "\n", "\n", "2->2\n", "\n", "\n", "!i1 & !o0\n", "\n", "\n", "\n", "2->4\n", "\n", "\n", "i1 & !o0\n", "\n", "\n", "\n", "3->3\n", "\n", "\n", "!i0 & i1 & o0\n", "\n", "\n", "\n", "3->4\n", "\n", "\n", "i0 & i1 & o0\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "3->5\n", "\n", "\n", "i0 & !i1 & o0\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "3->6\n", "\n", "\n", "!i0 & !i1 & o0\n", "\n", "\n", "\n", "4->4\n", "\n", "\n", "i1 & o0\n", "\n", "\n", "\n", "4->5\n", "\n", "\n", "!i1 & o0\n", "\n", "\n", "\n", "5->4\n", "\n", "\n", "i1 & !o0\n", "\n", "\n", "\n", "5->5\n", "\n", "\n", "!i1 & !o0\n", "\n", "\n", "\n", "6->3\n", "\n", "\n", "!i0 & i1 & !o0\n", "\n", "\n", "\n", "6->4\n", "\n", "\n", "i0 & i1 & !o0\n", "\n", "\n", "\n", "6->5\n", "\n", "\n", "i0 & !i1 & !o0\n", "\n", "\n", "\n", "6->6\n", "\n", "\n", "!i0 & !i1 & !o0\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "simplification lvl 1\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "i0 & !i1 & !o0\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "!i0 & !i1 & !o0\n", "\n", "\n", "\n", "1->2\n", "\n", "\n", "i0 & i1 & !o0\n", "\n", "\n", "\n", "1->2\n", "\n", "\n", "!i0 & i1 & !o0\n", "\n", "\n", "\n", "2->1\n", "\n", "\n", "i0 & !i1 & o0\n", "\n", "\n", "\n", "2->1\n", "\n", "\n", "!i0 & !i1 & o0\n", "\n", "\n", "\n", "2->2\n", "\n", "\n", "i0 & i1 & o0\n", "\n", "\n", "\n", "2->2\n", "\n", "\n", "!i0 & i1 & o0\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "simplification lvl 2\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "I->1\n", "\n", "\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "i0 & i1 & o0\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "!i0 & i1 & o0\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "i0 & !i1 & o0\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "!i0 & !i1 & o0\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "i0 & i1 & !o0\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "!i0 & i1 & !o0\n", "\n", "\n", "\n", "0->0\n", "\n", "\n", "i0 & !i1 & !o0\n", "\n", "\n", "\n", "0->0\n", "\n", "\n", "!i0 & !i1 & !o0\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "simplification lvl 3\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "0->0\n", "\n", "\n", "i1 & o0\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "!i1 & o0\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "i1 & !o0\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "!i1 & !o0\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "simplification lvl 4\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "0->0\n", "\n", "\n", "!i1 & !o0\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "i1 & !o0\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "!i1 & o0\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "i1 & o0\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "simplification lvl 5\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "0->0\n", "\n", "\n", "i1 & o0\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "!i1 & o0\n", "\n", "\n", "\n", "1->0\n", "\n", "\n", "i1 & !o0\n", "\n", "\n", "\n", "1->1\n", "\n", "\n", "!i1 & !o0\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Create the strategy\n", "# We have different levels of simplification:\n", "# 0 : No simplification\n", "# 1 : bisimulation-based reduction\n", "# 2 : bisimulation-based reduction with output output assignement\n", "# 3 : SAT-based exact minimization\n", "# 4 : First 1 then 3 (exact)\n", "# 5 : First 2 then 3 (not exact)\n", "for i in range(6):\n", " print(\"simplification lvl\", i)\n", " gi.minimize_lvl = i\n", " strat = spot.create_strategy(game, gi)\n", " display(strat.show())" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "0->6\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "0->8\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "2->1\n", "\n", "\n", "1\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "4->3\n", "\n", "\n", "1\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "6->5\n", "\n", "\n", "1\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "8->7\n", "\n", "\n", "1\n", "\n", "\n", "\n", "13\n", "\n", "13\n", "\n", "\n", "\n", "1->13\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "18\n", "\n", "18\n", "\n", "\n", "\n", "1->18\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "19\n", "\n", "19\n", "\n", "\n", "\n", "1->19\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "20\n", "\n", "20\n", "\n", "\n", "\n", "1->20\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "13->7\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "18->5\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "19->3\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "20->1\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "3->13\n", "\n", "\n", "i1\n", "\n", "\n", "\n", "3->19\n", "\n", "\n", "!i1\n", "\n", "\n", "\n", "10\n", "\n", "10\n", "\n", "\n", "\n", "5->10\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "11\n", "\n", "11\n", "\n", "\n", "\n", "5->11\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "15\n", "\n", "15\n", "\n", "\n", "\n", "5->15\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "16\n", "\n", "16\n", "\n", "\n", "\n", "5->16\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "9\n", "\n", "9\n", "\n", "\n", "\n", "10->9\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "11->7\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "14\n", "\n", "14\n", "\n", "\n", "\n", "15->14\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "16->5\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "7->10\n", "\n", "\n", "!i1\n", "\n", "\n", "\n", "7->11\n", "\n", "\n", "i1\n", "\n", "\n", "\n", "9->13\n", "\n", "\n", "i1\n", "\n", "\n", "\n", "12\n", "\n", "12\n", "\n", "\n", "\n", "9->12\n", "\n", "\n", "!i1\n", "\n", "\n", "\n", "12->9\n", "\n", "\n", "!o0\n", "\n", "\n", "\n", "14->13\n", "\n", "\n", "i0 & i1\n", "\n", "\n", "\n", "14->18\n", "\n", "\n", "!i0 & i1\n", "\n", "\n", "\n", "14->12\n", "\n", "\n", "i0 & !i1\n", "\n", "\n", "\n", "17\n", "\n", "17\n", "\n", "\n", "\n", "14->17\n", "\n", "\n", "!i0 & !i1\n", "\n", "\n", "\n", "17->14\n", "\n", "\n", "!o0\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f78f67a4c90> >" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.apply_strategy(game, False, False)" ] }, { "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": 12, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Fin(\n", "\n", ") & (Inf(\n", "\n", ") | (Fin(\n", "\n", ") & (Inf(\n", "\n", ") | Fin(\n", "\n", "))))\n", "[parity max odd 5]\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "I->4\n", "\n", "\n", "\n", "\n", "\n", "10\n", "\n", "10\n", "\n", "\n", "\n", "4->10\n", "\n", "\n", "!a\n", "\n", "\n", "\n", "\n", "11\n", "\n", "11\n", "\n", "\n", "\n", "4->11\n", "\n", "\n", "a\n", "\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "0->5\n", "\n", "\n", "!a\n", "\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "0->6\n", "\n", "\n", "a\n", "\n", "\n", "\n", "\n", "5->0\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "6->1\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "1->6\n", "\n", "\n", "a\n", "\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "1->7\n", "\n", "\n", "!a\n", "\n", "\n", "\n", "\n", "7->0\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "2->8\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "8->2\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "9\n", "\n", "9\n", "\n", "\n", "\n", "3->9\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "9->2\n", "\n", "\n", "!b\n", "\n", "\n", "\n", "\n", "9->3\n", "\n", "\n", "b\n", "\n", "\n", "\n", "\n", "10->0\n", "\n", "\n", "!b\n", "\n", "\n", "\n", "\n", "10->3\n", "\n", "\n", "b\n", "\n", "\n", "\n", "\n", "11->1\n", "\n", "\n", "!b\n", "\n", "\n", "\n", "\n", "11->3\n", "\n", "\n", "b\n", "\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f78f67a4330> >" ] }, "execution_count": 12, "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": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "HOA: v1\n", "States: 12\n", "Start: 4\n", "AP: 2 \"b\" \"a\"\n", "acc-name: parity max odd 5\n", "Acceptance: 5 Fin(4) & (Inf(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 0 0 0 0 1 1 1 1 1 1 1\n", "--BODY--\n", "State: 0\n", "[!1] 5 {1}\n", "[1] 6 {1}\n", "State: 1\n", "[1] 6 {1}\n", "[!1] 7 {1}\n", "State: 2\n", "[t] 8 {1}\n", "State: 3\n", "[t] 9 {1}\n", "State: 4\n", "[!1] 10 {1}\n", "[1] 11 {1}\n", "State: 5\n", "[t] 0 {3}\n", "State: 6\n", "[t] 1 {4}\n", "State: 7\n", "[t] 0 {4}\n", "State: 8\n", "[t] 2 {3}\n", "State: 9\n", "[!0] 2 {3}\n", "[0] 3 {4}\n", "State: 10\n", "[!0] 0 {3}\n", "[0] 3 {3}\n", "State: 11\n", "[!0] 1 {3}\n", "[0] 3 {3}\n", "--END--\n" ] } ], "source": [ "print(game.to_str('hoa'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is the solution of this particular game." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.solve_parity_game(game)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Fin(\n", "\n", ") & (Inf(\n", "\n", ") | (Fin(\n", "\n", ") & (Inf(\n", "\n", ") | Fin(\n", "\n", "))))\n", "[parity max odd 5]\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "I->4\n", "\n", "\n", "\n", "\n", "\n", "10\n", "\n", "10\n", "\n", "\n", "\n", "4->10\n", "\n", "\n", "!a\n", "\n", "\n", "\n", "\n", "11\n", "\n", "11\n", "\n", "\n", "\n", "4->11\n", "\n", "\n", "a\n", "\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "0->5\n", "\n", "\n", "!a\n", "\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "0->6\n", "\n", "\n", "a\n", "\n", "\n", "\n", "\n", "5->0\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "6->1\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "1->6\n", "\n", "\n", "a\n", "\n", "\n", "\n", "\n", "7\n", "\n", "7\n", "\n", "\n", "\n", "1->7\n", "\n", "\n", "!a\n", "\n", "\n", "\n", "\n", "7->0\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "2->8\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "8->2\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "9\n", "\n", "9\n", "\n", "\n", "\n", "3->9\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "9->2\n", "\n", "\n", "!b\n", "\n", "\n", "\n", "\n", "9->3\n", "\n", "\n", "b\n", "\n", "\n", "\n", "\n", "10->0\n", "\n", "\n", "!b\n", "\n", "\n", "\n", "\n", "10->3\n", "\n", "\n", "b\n", "\n", "\n", "\n", "\n", "11->1\n", "\n", "\n", "!b\n", "\n", "\n", "\n", "\n", "11->3\n", "\n", "\n", "b\n", "\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f79040eeed0> >" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.highlight_strategy(game)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Reading an aiger-file

\n", "\n", "

Read an aiger file. Note that we do not support the full \n", " syntax, but are restricted to:\n", "

    \n", "
  • Input variables start at index 2 and are consecutively numbered.
  • \n", "
  • Latch variables start at index (1 + #inputs) * 2 and are consecutively numbered.
  • \n", "
  • If inputs or outputs are named in the comments, all of them have to be named.
  • \n", "
  • Gate number $n$ can only have latches, inputs or previously defined gates ($\n", "
\n", "

" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "aag 5 2 0 2 3\n", "2\n", "4\n", "10\n", "6\n", "6 2 4\n", "8 3 5\n", "10 7 9\n", "i0 a\n", "i1 b\n", "o0 c\n", "o1 d\n" ] } ], "source": [ "#aiger file \n", "aag_txt = \"\"\"aag 5 2 0 2 3\n", "2\n", "4\n", "10\n", "6\n", "6 2 4\n", "8 3 5\n", "10 7 9\n", "i0 a\n", "i1 b\n", "o0 c\n", "o1 d\"\"\"\n", "print(aag_txt)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "this_aig = spot.aiger_circuit(aag_txt)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "2\n", "\n", "i0\n", "\n", "\n", "\n", "6\n", "\n", "6\n", "\n", "\n", "\n", "2->6\n", "\n", "\n", "\n", "\n", "\n", "8\n", "\n", "8\n", "\n", "\n", "\n", "2->8\n", "\n", "\n", "\n", "\n", "\n", "4\n", "\n", "i1\n", "\n", "\n", "\n", "4->6\n", "\n", "\n", "\n", "\n", "\n", "4->8\n", "\n", "\n", "\n", "\n", "\n", "10\n", "\n", "10\n", "\n", "\n", "\n", "6->10\n", "\n", "\n", "\n", "\n", "\n", "o1o1\n", "\n", "o1\n", "\n", "\n", "\n", "6->o1o1:s\n", "\n", "\n", "\n", "\n", "\n", "8->10\n", "\n", "\n", "\n", "\n", "\n", "o0o0\n", "\n", "o0\n", "\n", "\n", "\n", "10->o0o0:s\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(this_aig.show())" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "aag 5 2 0 2 3\n", "2\n", "4\n", "10\n", "6\n", "6 2 4\n", "8 3 5\n", "10 7 9\n", "i0 i0\n", "i1 i1\n", "o0 o0\n", "o1 o1\n" ] } ], "source": [ "print(this_aig.to_str())" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "((2, 4), (3, 5), (7, 9))\n" ] } ], "source": [ "print(this_aig.gates())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Verifying an implementation

\n", "\n", "

\n", " An aiger circuit can be transformed into a monitor. If the aiger represents the implementation of a strategy in the context of active control, it can be check for correctness. This is done by computing the intersecting of the monitor and the negation of the specification.\n", "

" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "t\n", "[all]\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "I->0\n", "\n", "\n", "\n", "\n", "\n", "0->0\n", "\n", "\n", "(!i0 & !i1 & !o0 & !o1) | (!i0 & i1 & o0 & !o1) | (i0 & !i1 & o0 & !o1) | (i0 & i1 & !o0 & o1)\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f78f67b83c0> >" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "aigasmon = this_aig.as_automaton()\n", "display(aigasmon)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Incomplete circuit

\n", "\n", "

\n", " It can happen that propositions declared as output are ommited in the aig circuit.\n", " This happens if the output does not appear in the strategy. Since it does not appear in the\n", " strategy it can take arbritrary values.\n", "

" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] }, { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Inf(\n", "\n", ") | (Fin(\n", "\n", ") & (Inf(\n", "\n", ") | Fin(\n", "\n", ")))\n", "[parity max odd 4]\n", "\n", "\n", "\n", "1\n", "\n", "1\n", "\n", "\n", "\n", "I->1\n", "\n", "\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "1->3\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "0\n", "\n", "0\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "2->0\n", "\n", "\n", "1\n", "\n", "\n", "\n", "\n", "3->0\n", "\n", "\n", "o0\n", "\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f78f67b8c00> >" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "game = spot.create_game(\"o0\", [\"o0\", \"o1\"])\n", "print(spot.solve_game(game))\n", "spot.highlight_strategy(game)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "o0o0\n", "\n", "o0\n", "\n", "\n", "\n", "0\n", "\n", "Const\n", "\n", "\n", "\n", "0->o0o0:s\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ " >" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "strat = spot.create_strategy(game)\n", "aig = spot.strategy_to_aig(strat, \"isop\")\n", "aig" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By handing over the input and output propositions explicitly, you can force their occurrence in the propositions of the circuit" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "o0o0\n", "\n", "o0\n", "\n", "\n", "\n", "0\n", "\n", "Const\n", "\n", "\n", "\n", "0->o0o0:s\n", "\n", "\n", "\n", "\n", "\n", "o1o1\n", "\n", "o1\n", "\n", "\n", "\n", "0->o1o1:s\n", "\n", "\n", "\n", "\n", "\n" ], "text/plain": [ " >" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "aig2 = spot.strategy_to_aig(strat, \"isop\", [], [\"o0\", \"o1\"])\n", "aig2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.9.2" } }, "nbformat": 4, "nbformat_minor": 4 }