diff --git a/NEWS b/NEWS index 2cf1a36aa..b1dbd61e8 100644 --- a/NEWS +++ b/NEWS @@ -289,6 +289,7 @@ New in spot 2.9.8.dev (not yet released) https://spot.lrde.epita.fr/tut40.html for examples. - Bindings for functions related to syntethis and aig-circuits. + See https://spot.lrde.epita.fr/ipynb/synthesis.html - spot::twa::prop_set was previously abstent from the Python bindings, making it impossible to call make_twa_graph() for copying diff --git a/doc/org/tut.org b/doc/org/tut.org index 0953c5cd3..12c700a3f 100644 --- a/doc/org/tut.org +++ b/doc/org/tut.org @@ -74,6 +74,7 @@ real notebooks instead. - [[https://spot.lrde.epita.fr/ipynb/parity.html][=parity.ipynb=]] documents algorithms for manipulating parity automata in Python - [[https://spot.lrde.epita.fr/ipynb/games.html][=games.ipynb=]] illustrates support for games +- [[https://spot.lrde.epita.fr/ipynb/synthesis.html][=synthesis.ipynb=]] illustrates support for game-based LTL reactive synthesis - [[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=]] diff --git a/tests/Makefile.am b/tests/Makefile.am index 73232ef7d..25ce31fe5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -370,6 +370,7 @@ TESTS_ipython = \ python/randltl.ipynb \ python/satmin.ipynb \ python/stutter-inv.ipynb \ + python/synthesis.ipynb \ python/testingaut.ipynb \ python/twagraph-internals.ipynb \ python/word.ipynb \ diff --git a/tests/python/games.ipynb b/tests/python/games.ipynb index 571184ae7..f6277d0f6 100644 --- a/tests/python/games.ipynb +++ b/tests/python/games.ipynb @@ -23,7 +23,7 @@ "\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" + "- `parity` acceptance of any form (`max odd`, `max even`, `min odd`, `min even`): player 0 can win if the maximal (or minimal) value seen infinitely often is even (or odd)" ] }, { @@ -454,11 +454,13 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Solving a game - The \"old\" way\n", + "# Solving a game\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", + "Solving a game is done my calling `solve_game()`. This function actually dispatches to `solve_safety_game()` (if the acceptance is `t`) or to `solve_parity_game()` (if the acceptance is any parity condition). You may call these functions directly if desired, but using `solve_game()` makes it possible for future version of Spot to dispatch to some better function if we add some.\n", "\n", - "The return value of those function is simply the winner for the initial state." + "These functions 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 functions is simply the winner for the initial state." ] }, { @@ -478,7 +480,7 @@ } ], "source": [ - "spot.solve_safety_game(game)" + "spot.solve_game(game)" ] }, { @@ -664,2483 +666,6 @@ "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": {}, @@ -3152,8 +677,10 @@ }, { "cell_type": "code", - "execution_count": 12, - "metadata": {}, + "execution_count": 8, + "metadata": { + "scrolled": false + }, "outputs": [ { "data": { @@ -3407,10 +934,10 @@ "\n" ], "text/plain": [ - " *' at 0x7f78f67a4330> >" + " *' at 0x7f5c143ec630> >" ] }, - "execution_count": 12, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -3431,7 +958,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -3495,7 +1022,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -3504,7 +1031,7 @@ "True" ] }, - "execution_count": 14, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -3515,7 +1042,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -3770,10 +1297,10 @@ "\n" ], "text/plain": [ - " *' at 0x7f79040eeed0> >" + " *' at 0x7f5c143fdf30> >" ] }, - "execution_count": 15, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -3781,570 +1308,6 @@ "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": { diff --git a/tests/python/synthesis.ipynb b/tests/python/synthesis.ipynb new file mode 100644 index 000000000..09a8febff --- /dev/null +++ b/tests/python/synthesis.ipynb @@ -0,0 +1,3573 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "acbc10d9", + "metadata": {}, + "outputs": [], + "source": [ + "import spot\n", + "spot.setup()" + ] + }, + { + "cell_type": "markdown", + "id": "9a6831b2", + "metadata": {}, + "source": [ + "This notebook presents functions that can be used to solve the Reactive Synthesis problem using games.\n", + "If you are not familiar with how Spot represent games, please read the `games` notebook first.\n", + "\n", + "In Reactive Synthesis, the goal is to build an electronic circuit that reacts to some input signals by producing some output signals, under some LTL constraints that tie both input and output. Of course the input signals are not controlable, so only job is to decide what output signal to produce.\n", + "\n", + "# Reactive synthesis in three steps\n", + "\n", + "A strategy/control circuit can be derived more conveniently from an 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 a structure called `synthesis_info`. This structure stores some additional data needed to pass fine-tuning options or to store statistics.\n", + "\n", + "The `create_game` function takes the LTL specification, and the list of controlable atomic propositions (or output signals). It returns a two-player game, where player 0 plays the input variables (and wants to invalidate the acceptance condition), and player 1 plays the output variables (and wants to satisfy the output condition). The conversion from LTL to parity automata can use one of many algorithms, and can be specified in the `synthesis_info` structure (this works like the `--algo=` option of `ltlsynt`)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "eb46d524", + "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 0x7fa0f4223360> >" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "si = spot.synthesis_info()\n", + "si.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\"], si)\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": "markdown", + "id": "a2f7d570", + "metadata": {}, + "source": [ + "Solving the game, is done with `solve_game()` as with any game. There is also a version that takes a `synthesis_info` as second argument in case the time it takes has to be recorded. Here passing `si` or not makes no difference." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b46ddd69", + "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": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(\"Found a solution:\", spot.solve_game(game, si))\n", + "spot.highlight_strategy(game)\n", + "game.show('.g')" + ] + }, + { + "cell_type": "markdown", + "id": "6e1b2985", + "metadata": {}, + "source": [ + "Once a strategy has been found, it can be extracted as an automaton and simplified using 6 different levels (the default is 2). The output should be interpreted as a mealy automaton, where transition are labeled by combination of input assignments and associated output assignments." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "3574558b", + "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": [ + "# 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", + " si.minimize_lvl = i\n", + " strat = spot.create_strategy(game, si)\n", + " display(strat.show())" + ] + }, + { + "cell_type": "markdown", + "id": "95018bed", + "metadata": {}, + "source": [ + "Alternatively, the `apply_strategy` is a more low-level function that can be used to restrict the automaton to the part where player 1 is winning, without simplifying it. It's second argument controls whether pairs of transitions corresponding to each player should be fused back into a single transition. The third argument controls whether the game's acceptance condition should be copied." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "eadda15f", + "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 0x7fa0f4b39690> >" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spot.apply_strategy(game, False, False)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "515e06a8", + "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", + "!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": [ + " *' at 0x7fa0f4b395a0> >" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "spot.apply_strategy(game, True, False)" + ] + }, + { + "cell_type": "markdown", + "id": "aab74aac", + "metadata": {}, + "source": [ + "# Converting the strategy to AIGER\n", + "\n", + "A strategy can be converted to a circuit in the [AIGER format](http://fmv.jku.at/aiger/FORMAT.aiger) using `strategy_to_aig()`. This takes a second argument specifying what type of encoding to use (exactly like `ltlsynt`'s `--aiger=...` option). \n", + "\n", + "In this case, the circuit is quite simple: `o0` should be the negation of previous value of `i1`. This is done by storing the value of `i1` in a latch. And the value if `i0` can be ignored." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f7585a73", + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "L0_out\n", + "\n", + "\n", + "\n", + "o0o0\n", + "\n", + "o0\n", + "\n", + "\n", + "\n", + "6->o0o0:s\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "i1\n", + "\n", + "\n", + "\n", + "L0\n", + "\n", + "L0\n", + "\n", + "\n", + "\n", + "2->L0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "i0\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " >" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "aag 3 2 1 1 0\n", + "2\n", + "4\n", + "6 3\n", + "7\n", + "i0 i1\n", + "i1 i0\n", + "o0 o0\n" + ] + } + ], + "source": [ + "aig = spot.strategy_to_aig(strat, \"isop\")\n", + "display(aig)\n", + "print(aig.to_str())" + ] + }, + { + "cell_type": "markdown", + "id": "a40e4c28", + "metadata": {}, + "source": [ + "# Adding more inputs and outputs by force" + ] + }, + { + "cell_type": "markdown", + "id": "4b8a9809", + "metadata": {}, + "source": [ + "It can happen that propositions declared as output are ommited in the aig circuit (either because they are not part of the specification, or because they do not appear in the winning strategy). In that case those \n", + "values can take arbitrary values.\n", + "\n", + "For instance so following constraint mention `o1` and `i1`, but those atomic proposition are actually unconstrained (`F(... U x)` can be simplified to `Fx`). Without any indication, the circuit built will ignore those variables:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "efc7c557", + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Inf(\n", + "\n", + ") | (Fin(\n", + "\n", + ") & (Inf(\n", + "\n", + ") | (Fin(\n", + "\n", + ") & (Inf(\n", + "\n", + ") | Fin(\n", + "\n", + ")))))\n", + "[parity max odd 6]\n", + "\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "I->3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "3->6\n", + "\n", + "\n", + "i0\n", + "\n", + "\n", + "\n", + "\n", + "7\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "3->7\n", + "\n", + "\n", + "!i0\n", + "\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "4->0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "5\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "1->5\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "5->1\n", + "\n", + "\n", + "!o0\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "2->6\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "6->0\n", + "\n", + "\n", + "o0\n", + "\n", + "\n", + "\n", + "\n", + "6->2\n", + "\n", + "\n", + "!o0\n", + "\n", + "\n", + "\n", + "\n", + "7->1\n", + "\n", + "\n", + "!o0\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " *' at 0x7fa0f4223090> >" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "L0_out\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "4->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "i0\n", + "\n", + "\n", + "\n", + "2->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "L0\n", + "\n", + "L0\n", + "\n", + "\n", + "\n", + "6->L0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "o0o0\n", + "\n", + "o0\n", + "\n", + "\n", + "\n", + "6->o0o0:s\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " >" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "game = spot.create_game(\"i0 <-> F((Go1 -> Fi1) U o0)\", [\"o0\", \"o1\"])\n", + "spot.solve_game(game)\n", + "spot.highlight_strategy(game)\n", + "display(game)\n", + "strat = spot.create_strategy(game)\n", + "aig = spot.strategy_to_aig(strat, \"isop\")\n", + "display(aig)" + ] + }, + { + "cell_type": "markdown", + "id": "c328c4d8", + "metadata": {}, + "source": [ + "To force the presence of extra variables in the circuit, they can be passed to `strategy_to_aig()`." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f9f8d0e3", + "metadata": {}, + "outputs": [ + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "4\n", + "\n", + "L0_out\n", + "\n", + "\n", + "\n", + "6\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "4->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "2\n", + "\n", + "i0\n", + "\n", + "\n", + "\n", + "2->6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "L0\n", + "\n", + "L0\n", + "\n", + "\n", + "\n", + "6->L0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "o0o0\n", + "\n", + "o0\n", + "\n", + "\n", + "\n", + "6->o0o0:s\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "o1o1\n", + "\n", + "o1\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "Const\n", + "\n", + "\n", + "\n", + "0->o1o1:s\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "o2i1\n", + "\n", + "i1\n", + "\n", + "\n", + "\n", + "0->o2i1:s\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + " >" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(spot.strategy_to_aig(strat, \"isop\", [\"i0\", \"i1\"], [\"o0\", \"o1\"]))" + ] + }, + { + "cell_type": "markdown", + "id": "a330b169", + "metadata": {}, + "source": [ + "# Reading an AIGER-file\n", + "\n", + "Note that we do not support the full [AIGER syntax](http://fmv.jku.at/aiger/FORMAT.aiger). Our restrictions corresponds to the conventions used in the type of AIGER file we output:\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 some inputs or outputs are named in comments, all of them have to be named.\n", + "- Gate number $n$ can only connect to latches, inputs, or previously defined gates ($\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": [ + "this_aig = spot.aiger_circuit(aag_txt)\n", + "display(this_aig)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "000f3948", + "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": 13, + "id": "60e8b21a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "((2, 4), (3, 5), (7, 9))\n" + ] + } + ], + "source": [ + "print(this_aig.gates())" + ] + }, + { + "cell_type": "markdown", + "id": "2213a2a2", + "metadata": {}, + "source": [ + "An aiger circuit can be transformed into a monitor. This can help for instance to verify that it does not intersect the negation of the specification." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "f5d49a9e", + "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 0x7fa0f4223c60> >" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "this_aig.as_automaton()" + ] + } + ], + "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": 5 +}