{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "4f84fa79",
"metadata": {},
"outputs": [],
"source": [
"import spot\n",
"spot.setup()\n",
"from spot.jupyter import display_inline"
]
},
{
"cell_type": "markdown",
"id": "4ad017a0",
"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 represents 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 controllable, so only job is to decide what output signal to produce.\n",
"\n",
"# Reactive synthesis in four steps\n",
"\n",
"A strategy/control circuit can be derived more conveniently from an LTL/PSL specification.\n",
"The process is decomposed in three steps:\n",
"- Creating the game\n",
"- Solving the game\n",
"- Simplifying the winning strategy\n",
"- Building the circuit from the strategy\n",
"\n",
"Each of these steps is parameterized 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 `ltl_to_game` function takes the LTL specification, and the list of controllable 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": "e333be09",
"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",
"Fin( \n",
"⓿ \n",
") \n",
"[co-Büchi] \n",
"\n",
"\n",
"\n",
"0 \n",
"\n",
"0 \n",
" \n",
"\n",
"\n",
"I->0 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"10 \n",
" \n",
"10 \n",
" \n",
"\n",
"\n",
"0->10 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"11 \n",
" \n",
"11 \n",
" \n",
"\n",
"\n",
"0->11 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"12 \n",
" \n",
"12 \n",
" \n",
"\n",
"\n",
"0->12 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"13 \n",
" \n",
"13 \n",
" \n",
"\n",
"\n",
"0->13 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"10->8 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"7 \n",
"\n",
"7 \n",
" \n",
"\n",
"\n",
"11->7 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"9 \n",
"\n",
"9 \n",
" \n",
"\n",
"\n",
"12->9 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"5 \n",
"\n",
"5 \n",
" \n",
"\n",
"\n",
"13->5 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"14 \n",
" \n",
"14 \n",
" \n",
"\n",
"\n",
"1->14 \n",
" \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"16 \n",
" \n",
"16 \n",
" \n",
"\n",
"\n",
"1->16 \n",
" \n",
" \n",
"!i0 \n",
" \n",
"\n",
"\n",
"15 \n",
"\n",
"15 \n",
" \n",
"\n",
"\n",
"14->15 \n",
" \n",
" \n",
"1 \n",
"⓿ \n",
" \n",
"\n",
"\n",
"16->1 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"2 \n",
"\n",
"2 \n",
" \n",
"\n",
"\n",
"2->14 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"17 \n",
" \n",
"17 \n",
" \n",
"\n",
"\n",
"2->17 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"17->2 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"3 \n",
"\n",
"3 \n",
" \n",
"\n",
"\n",
"3->14 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"3->16 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"3->17 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"18 \n",
" \n",
"18 \n",
" \n",
"\n",
"\n",
"3->18 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"18->3 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"4 \n",
"\n",
"4 \n",
" \n",
"\n",
"\n",
"19 \n",
" \n",
"19 \n",
" \n",
"\n",
"\n",
"4->19 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"20 \n",
" \n",
"20 \n",
" \n",
"\n",
"\n",
"4->20 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"19->4 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"20->5 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"21 \n",
" \n",
"21 \n",
" \n",
"\n",
"\n",
"5->21 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"22 \n",
" \n",
"22 \n",
" \n",
"\n",
"\n",
"5->22 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"21->4 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"22->5 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"6->19 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"6->20 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"23 \n",
" \n",
"23 \n",
" \n",
"\n",
"\n",
"6->23 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"24 \n",
" \n",
"24 \n",
" \n",
"\n",
"\n",
"6->24 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"23->1 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"23->6 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"24->1 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"24->9 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"7->20 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"25 \n",
" \n",
"25 \n",
" \n",
"\n",
"\n",
"7->25 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"25->2 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"25->7 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"8->20 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"8->24 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"8->25 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"26 \n",
" \n",
"26 \n",
" \n",
"\n",
"\n",
"8->26 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"26->3 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"26->8 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"9->21 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"9->22 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"27 \n",
" \n",
"27 \n",
" \n",
"\n",
"\n",
"9->27 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"28 \n",
" \n",
"28 \n",
" \n",
"\n",
"\n",
"9->28 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"27->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"27->6 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"28->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"28->9 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"15->14 \n",
" \n",
" \n",
"1 \n",
"⓿ \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"Fin( \n",
"⓿ \n",
") \n",
"[co-Büchi] \n",
"\n",
"\n",
"\n",
"0 \n",
"\n",
"0 \n",
" \n",
"\n",
"\n",
"I->0 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"10 \n",
" \n",
"10 \n",
" \n",
"\n",
"\n",
"0->10 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"11 \n",
" \n",
"11 \n",
" \n",
"\n",
"\n",
"0->11 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"12 \n",
" \n",
"12 \n",
" \n",
"\n",
"\n",
"0->12 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"13 \n",
" \n",
"13 \n",
" \n",
"\n",
"\n",
"0->13 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"10->8 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"7 \n",
"\n",
"7 \n",
" \n",
"\n",
"\n",
"11->7 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"9 \n",
"\n",
"9 \n",
" \n",
"\n",
"\n",
"12->9 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"5 \n",
"\n",
"5 \n",
" \n",
"\n",
"\n",
"13->5 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"14 \n",
" \n",
"14 \n",
" \n",
"\n",
"\n",
"1->14 \n",
" \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"16 \n",
" \n",
"16 \n",
" \n",
"\n",
"\n",
"1->16 \n",
" \n",
" \n",
"!i0 \n",
" \n",
"\n",
"\n",
"15 \n",
"\n",
"15 \n",
" \n",
"\n",
"\n",
"14->15 \n",
" \n",
" \n",
"1 \n",
"⓿ \n",
" \n",
"\n",
"\n",
"16->1 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"2 \n",
"\n",
"2 \n",
" \n",
"\n",
"\n",
"2->14 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"17 \n",
" \n",
"17 \n",
" \n",
"\n",
"\n",
"2->17 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"17->2 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"3 \n",
"\n",
"3 \n",
" \n",
"\n",
"\n",
"3->14 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"3->16 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"3->17 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"18 \n",
" \n",
"18 \n",
" \n",
"\n",
"\n",
"3->18 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"18->3 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"4 \n",
"\n",
"4 \n",
" \n",
"\n",
"\n",
"19 \n",
" \n",
"19 \n",
" \n",
"\n",
"\n",
"4->19 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"20 \n",
" \n",
"20 \n",
" \n",
"\n",
"\n",
"4->20 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"19->4 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"20->5 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"21 \n",
" \n",
"21 \n",
" \n",
"\n",
"\n",
"5->21 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"22 \n",
" \n",
"22 \n",
" \n",
"\n",
"\n",
"5->22 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"21->4 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"22->5 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"6->19 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"6->20 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"23 \n",
" \n",
"23 \n",
" \n",
"\n",
"\n",
"6->23 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"24 \n",
" \n",
"24 \n",
" \n",
"\n",
"\n",
"6->24 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"23->1 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"23->6 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"24->1 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"24->9 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"7->20 \n",
" \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"25 \n",
" \n",
"25 \n",
" \n",
"\n",
"\n",
"7->25 \n",
" \n",
" \n",
"!i1 \n",
" \n",
"\n",
"\n",
"25->2 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"25->7 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"8->20 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"8->24 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"8->25 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"26 \n",
" \n",
"26 \n",
" \n",
"\n",
"\n",
"8->26 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"26->3 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"26->8 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"9->21 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"9->22 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"27 \n",
" \n",
"27 \n",
" \n",
"\n",
"\n",
"9->27 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"28 \n",
" \n",
"28 \n",
" \n",
"\n",
"\n",
"9->28 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"27->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"27->6 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"28->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"28->9 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"15->14 \n",
" \n",
" \n",
"1 \n",
"⓿ \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb32a0> >"
]
},
"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.ltl_to_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": "4d030586",
"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": "f13ac820",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found a solution: True\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"Fin( \n",
"⓿ \n",
") \n",
"[co-Büchi] \n",
"\n",
"\n",
"\n",
"0 \n",
"\n",
"0 \n",
" \n",
"\n",
"\n",
"I->0 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"10 \n",
" \n",
"10 \n",
" \n",
"\n",
"\n",
"0->10 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"11 \n",
" \n",
"11 \n",
" \n",
"\n",
"\n",
"0->11 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"12 \n",
" \n",
"12 \n",
" \n",
"\n",
"\n",
"0->12 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"13 \n",
" \n",
"13 \n",
" \n",
"\n",
"\n",
"0->13 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"10->8 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"7 \n",
"\n",
"7 \n",
" \n",
"\n",
"\n",
"11->7 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"9 \n",
"\n",
"9 \n",
" \n",
"\n",
"\n",
"12->9 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"5 \n",
"\n",
"5 \n",
" \n",
"\n",
"\n",
"13->5 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"14 \n",
" \n",
"14 \n",
" \n",
"\n",
"\n",
"1->14 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"16 \n",
" \n",
"16 \n",
" \n",
"\n",
"\n",
"1->16 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"15 \n",
"\n",
"15 \n",
" \n",
"\n",
"\n",
"14->15 \n",
" \n",
" \n",
"⓿ \n",
" \n",
"\n",
"\n",
"16->1 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
"\n",
"2 \n",
" \n",
"\n",
"\n",
"2->14 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"17 \n",
" \n",
"17 \n",
" \n",
"\n",
"\n",
"2->17 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"17->2 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"3 \n",
"\n",
"3 \n",
" \n",
"\n",
"\n",
"3->14 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"3->16 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"3->17 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"18 \n",
" \n",
"18 \n",
" \n",
"\n",
"\n",
"3->18 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"18->3 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"4 \n",
"\n",
"4 \n",
" \n",
"\n",
"\n",
"19 \n",
" \n",
"19 \n",
" \n",
"\n",
"\n",
"4->19 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"20 \n",
" \n",
"20 \n",
" \n",
"\n",
"\n",
"4->20 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"19->4 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"20->5 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"21 \n",
" \n",
"21 \n",
" \n",
"\n",
"\n",
"5->21 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"22 \n",
" \n",
"22 \n",
" \n",
"\n",
"\n",
"5->22 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"21->4 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"22->5 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"6->19 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"6->20 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"23 \n",
" \n",
"23 \n",
" \n",
"\n",
"\n",
"6->23 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"24 \n",
" \n",
"24 \n",
" \n",
"\n",
"\n",
"6->24 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"23->1 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"23->6 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"24->1 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"24->9 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"7->20 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"25 \n",
" \n",
"25 \n",
" \n",
"\n",
"\n",
"7->25 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"25->2 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"25->7 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"8->20 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"8->24 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"8->25 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"26 \n",
" \n",
"26 \n",
" \n",
"\n",
"\n",
"8->26 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"26->3 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"26->8 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"9->21 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"9->22 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"27 \n",
" \n",
"27 \n",
" \n",
"\n",
"\n",
"9->27 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"28 \n",
" \n",
"28 \n",
" \n",
"\n",
"\n",
"9->28 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"27->1 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"27->6 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"28->1 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"28->9 \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": "98aa1402",
"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 have the form `(ins)&(outs)` where `ins` and `outs` are Boolean formulas representing possible inputs and outputs (they could be more than just conjunctions of atomic proposition). Mealy machines with this type of labels are called \"separated\" in Spot."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "4c93add7",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"simplification lvl 0 : No simplification\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
"!i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"2 \n",
"\n",
"2 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"3 \n",
"\n",
"3 \n",
" \n",
"\n",
"\n",
"0->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"4 \n",
"\n",
"4 \n",
" \n",
"\n",
"\n",
"0->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->2 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->2 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->4 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"3->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"3->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"5 \n",
"\n",
"5 \n",
" \n",
"\n",
"\n",
"3->5 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"3->6 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"4->4 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"4->5 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"5->4 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"5->5 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->5 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->6 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
"!i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"2 \n",
"\n",
"2 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"3 \n",
"\n",
"3 \n",
" \n",
"\n",
"\n",
"0->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"4 \n",
"\n",
"4 \n",
" \n",
"\n",
"\n",
"0->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->2 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->2 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->4 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"3->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"3->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"5 \n",
"\n",
"5 \n",
" \n",
"\n",
"\n",
"3->5 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"3->6 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"4->4 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"4->5 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"5->4 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"5->5 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->3 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->4 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->5 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"6->6 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb2ca0> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"simplification lvl 1 : bisimulation-based reduction\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
"!i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"2 \n",
"\n",
"2 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->2 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->2 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"2->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"2->2 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"2->2 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
"!i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"2 \n",
"\n",
"2 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->2 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->2 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"2->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"2->2 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"2->2 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb3b40> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"simplification lvl 2 : bisimulation-based reduction with output assignement\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0 \n",
"\n",
"0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0 \n",
"\n",
"0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb3480> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"simplification lvl 3 : SAT-based exact minimization\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb2dc0> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"simplification lvl 4 : First 1 then 3 (exact)\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"!i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"!i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb3e40> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"simplification lvl 5 : First 2 then 3 (not exact)\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb2ca0> >"
]
},
"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 assignement\n",
"# 3 : SAT-based exact minimization\n",
"# 4 : First 1 then 3 (exact)\n",
"# 5 : First 2 then 3 (not exact)\n",
"\n",
"descr = [\"0 : No simplification\", \n",
" \"1 : bisimulation-based reduction\", \n",
" \"2 : bisimulation-based reduction with output assignement\",\n",
" \"3 : SAT-based exact minimization\",\n",
" \"4 : First 1 then 3 (exact)\",\n",
" \"5 : First 2 then 3 (not exact)\"]\n",
"\n",
"\n",
"for i in range(6):\n",
" print(\"simplification lvl \", descr[i])\n",
" si.minimize_lvl = i\n",
" mealy = spot.solved_game_to_mealy(game, si)\n",
" spot.simplify_mealy_here(mealy, si.minimize_lvl, False)\n",
" display(mealy)"
]
},
{
"cell_type": "markdown",
"id": "9d8d52f6",
"metadata": {},
"source": [
"If needed, a separated Mealy machine can be turned into game shape using `split_separated_mealy()`, which is more efficient than `split_2step()`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "707f4cf6",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"\n",
"
\n",
"\n",
" \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",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
" \n",
"!i0 & i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"!i0 & !i1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n",
"
\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",
"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",
"0->3 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"2->1 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"3->0 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"4 \n",
" \n",
"\n",
"\n",
"1->4 \n",
" \n",
" \n",
"i0 & i1 \n",
" \n",
"\n",
"\n",
"1->4 \n",
" \n",
" \n",
"!i0 & i1 \n",
" \n",
"\n",
"\n",
"5 \n",
" \n",
"5 \n",
" \n",
"\n",
"\n",
"1->5 \n",
" \n",
" \n",
"i0 & !i1 \n",
" \n",
"\n",
"\n",
"1->5 \n",
" \n",
" \n",
"!i0 & !i1 \n",
" \n",
"\n",
"\n",
"4->0 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"5->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display_inline(mealy, spot.split_separated_mealy(mealy), per_row=2)"
]
},
{
"cell_type": "markdown",
"id": "b9e4412e",
"metadata": {},
"source": [
"# Converting the separated Mealy machine to AIG\n",
"\n",
"A separated Mealy machine can be converted to a circuit in the [AIGER format](http://fmv.jku.at/aiger/FORMAT.aiger) using `mealy_machine_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": 6,
"id": "9f344931",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
" \n",
"L0_out \n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"L0 \n",
" \n",
"L0_in \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"2->L0 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"i0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
" \n",
"L0_out \n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"L0 \n",
" \n",
"L0_in \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"2->L0 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"i0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb21f0> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"aig = spot.mealy_machine_to_aig(mealy, \"isop\")\n",
"display(aig)"
]
},
{
"cell_type": "markdown",
"id": "92bbe8d0",
"metadata": {},
"source": [
"While we are at it, let us mention that you can render those circuits horizontally as follows:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "3ae7ce32",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
" \n",
"L0_out \n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6->o0:w \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"L0 \n",
" \n",
"L0_in \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"2->L0 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"i0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
""
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"aig.show('h')"
]
},
{
"cell_type": "markdown",
"id": "44fbc0ac",
"metadata": {},
"source": [
"To encode the circuit in the AIGER format (ASCII version) use:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "566715d5",
"metadata": {},
"outputs": [
{
"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": [
"print(aig.to_str())"
]
},
{
"cell_type": "markdown",
"id": "ef304f36",
"metadata": {},
"source": [
"# Adding more inputs and outputs by force"
]
},
{
"cell_type": "markdown",
"id": "5c2b0b78",
"metadata": {},
"source": [
"It can happen that propositions declared as output are omitted 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": 9,
"id": "874c7df1",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"Inf( \n",
"⓿ \n",
") \n",
"[Büchi] \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",
"7 \n",
" \n",
"7 \n",
" \n",
"\n",
"\n",
"3->7 \n",
" \n",
" \n",
"!i0 \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",
"6->0 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6->2 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"7->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"Inf( \n",
"⓿ \n",
") \n",
"[Büchi] \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",
"7 \n",
" \n",
"7 \n",
" \n",
"\n",
"\n",
"3->7 \n",
" \n",
" \n",
"!i0 \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",
"6->0 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6->2 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"7->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfc9920> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"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 \n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"4 \n",
" \n",
"\n",
"\n",
"0->4 \n",
" \n",
" \n",
"!i0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"2->1 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"3 \n",
"\n",
"3 \n",
" \n",
"\n",
"\n",
"4->3 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"5 \n",
" \n",
"5 \n",
" \n",
"\n",
"\n",
"1->5 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"5->1 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"3->4 \n",
" \n",
" \n",
"1 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\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 \n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"4 \n",
" \n",
"\n",
"\n",
"0->4 \n",
" \n",
" \n",
"!i0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"2->1 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"3 \n",
"\n",
"3 \n",
" \n",
"\n",
"\n",
"4->3 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"5 \n",
" \n",
"5 \n",
" \n",
"\n",
"\n",
"1->5 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"5->1 \n",
" \n",
" \n",
"1 \n",
" \n",
"\n",
"\n",
"3->4 \n",
" \n",
" \n",
"1 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb3480> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\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 \n",
" \n",
"\n",
"\n",
"3 \n",
" \n",
"3 \n",
" \n",
"\n",
"\n",
"0->3 \n",
" \n",
" \n",
"!i0 \n",
" \n",
"\n",
"\n",
"2->0 \n",
" \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"3->1 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->3 \n",
" \n",
" \n",
"1 \n",
" \n",
" \n",
" \n",
"
\n",
"\n",
"\n",
"\n",
"
\n",
"\n",
" \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",
" \n",
"i0 \n",
"/ \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"1 \n",
"\n",
"1 \n",
" \n",
"\n",
"\n",
"0->1 \n",
" \n",
" \n",
" \n",
"!i0 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"1->1 \n",
" \n",
" \n",
" \n",
"1 \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
" \n",
" \n",
"
"
],
"text/plain": [
""
]
},
"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",
"L0 \n",
" \n",
"L0_in \n",
" \n",
"\n",
"\n",
"6->L0 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6->o0:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
" \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\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",
"L0 \n",
" \n",
"L0_in \n",
" \n",
"\n",
"\n",
"6->L0 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"6->o0:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
" \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb2ca0> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"game = spot.ltl_to_game(\"i0 <-> F((Go1 -> Fi1) U o0)\", [\"o0\", \"o1\"])\n",
"spot.solve_game(game)\n",
"spot.highlight_strategy(game)\n",
"display(game)\n",
"mealy = spot.solved_game_to_mealy(game)\n",
"display(mealy)\n",
"spot.simplify_mealy_here(mealy, 2, True)\n",
"display_inline(mealy, spot.unsplit_mealy(mealy))\n",
"aig = spot.mealy_machine_to_aig(mealy, \"isop\")\n",
"display(aig)"
]
},
{
"cell_type": "markdown",
"id": "c564dba3",
"metadata": {},
"source": [
"To force the presence of extra variables in the circuit, they can be passed to `mealy_machine_to_aig()`."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "c31a3b38",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
" \n",
"L0_out \n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"6->8 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"L0 \n",
" \n",
"L0_in \n",
" \n",
"\n",
"\n",
"8->L0 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"8->o0:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->8 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"0 \n",
" \n",
"False \n",
" \n",
"\n",
"\n",
"0->o1:s \n",
" \n",
" \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
" \n",
"L0_out \n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"6->8 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"L0 \n",
" \n",
"L0_in \n",
" \n",
"\n",
"\n",
"8->L0 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"8->o0:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->8 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"i1 \n",
" \n",
"\n",
"\n",
"0 \n",
" \n",
"False \n",
" \n",
"\n",
"\n",
"0->o1:s \n",
" \n",
" \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb3bd0> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display(spot.mealy_machine_to_aig(mealy, \"isop\", [\"i0\", \"i1\"], [\"o0\", \"o1\"]))"
]
},
{
"cell_type": "markdown",
"id": "3323fc84",
"metadata": {},
"source": [
"# Combining Mealy machines\n",
"\n",
"It can happen that the complete specification of the controller can be separated into sub-specifications with DISJOINT output propositions, see Finkbeiner et al. Specification Decomposition for Reactive Synthesis.\n",
"This results in multiple Mealy machines which have to be converted into one single AIG circuit.\n",
"\n",
"This can be done in two ways:\n",
"\n",
"1. Using the function `mealy_machines_to_aig()`, which takes a vector of separated Mealy machines as argument.\n",
"2. Combine the mealy machines into one before passing it to `mealy_machine_to aig(). This currently only supports input complete machines of the same type (mealy/separated mealy/split mealy)\n",
"\n",
"Note that the method version is usually preferable as it is faster.\n",
"Also note that in order for this to work, all mealy machines need to share the same `bdd_dict`. This can be ensured by passing a common options structure."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "5d8e4cdb",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Solved games:\n"
]
},
{
"data": {
"text/html": [
"\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) | (i0 & i1) \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"2 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->0 \n",
" \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n",
"
\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) | (i0 & i1) \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"2 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"2->0 \n",
" \n",
" \n",
"!o1 \n",
" \n",
" \n",
" \n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Reduced strategies:\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"\n",
"
\n",
"\n",
" \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",
" \n",
"(!i0 & !i1) | (i0 & i1) \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
"/ \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n",
"
\n",
"\n",
"\n",
"\n",
"
\n",
"\n",
" \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",
" \n",
"(!i0 & !i1) | (i0 & i1) \n",
"/ \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
"/ \n",
" \n",
"!o1 \n",
" \n",
" \n",
" \n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Circuit implementing both machines from a vector of machines:\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"10->o1:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
"\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"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"10->o1:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
"\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"
],
"text/plain": [
" *' at 0x7f655e8c5200> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Combining the two machines into one.\n"
]
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"\n",
"0 \n",
"\n",
"0,0 \n",
" \n",
"\n",
"\n",
"I->0 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"(!i0 & !i1) | (i0 & i1) \n",
"/ \n",
" \n",
"!o0 & o1 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
"/ \n",
" \n",
"o0 & !o1 \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"\n",
"0 \n",
"\n",
"0,0 \n",
" \n",
"\n",
"\n",
"I->0 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"(!i0 & !i1) | (i0 & i1) \n",
"/ \n",
" \n",
"!o0 & o1 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
"/ \n",
" \n",
"o0 & !o1 \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfb2ca0> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"10->o1:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
"\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"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"o1 \n",
" \n",
"\n",
"\n",
"10->o1:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
"\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"
],
"text/plain": [
" *' at 0x7f654cfb2700> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"g1 = spot.ltl_to_game(\"G((i0 xor i1) <-> o0)\", [\"o0\"], si)\n",
"g2 = spot.ltl_to_game(\"G((i0 xor i1) <-> (!o1))\", [\"o1\"], si)\n",
"spot.solve_game(g1)\n",
"spot.highlight_strategy(g1)\n",
"spot.solve_game(g2)\n",
"spot.highlight_strategy(g2)\n",
"print(\"Solved games:\")\n",
"display_inline(g1, g2)\n",
"strat1 = spot.solved_game_to_separated_mealy(g1)\n",
"strat2 = spot.solved_game_to_separated_mealy(g2)\n",
"print(\"Reduced strategies:\")\n",
"display_inline(strat1, strat2)\n",
"#Method 1\n",
"print(\"Circuit implementing both machines from a vector of machines:\")\n",
"aig = spot.mealy_machines_to_aig([strat1, strat2], \"isop\")\n",
"display(aig)\n",
"#Method 2\n",
"strat_comb = spot.mealy_product(strat1, strat2)\n",
"print(\"Combining the two machines into one.\")\n",
"display(strat_comb)\n",
"aig_comb = spot.mealy_machine_to_aig(strat_comb, \"isop\")\n",
"display(aig_comb)"
]
},
{
"cell_type": "markdown",
"id": "c7a1986f",
"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",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"d \n",
" \n",
"\n",
"\n",
"6->o1:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"c \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"a \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2->8 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"b \n",
" \n",
"\n",
"\n",
"4->6 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"4->8 \n",
" \n",
"\n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o1 \n",
" \n",
"d \n",
" \n",
"\n",
"\n",
"6->o1:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"c \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"a \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"2->8 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"4 \n",
" \n",
"b \n",
" \n",
"\n",
"\n",
"4->6 \n",
" \n",
" \n",
" \n",
"\n",
"\n",
"4->8 \n",
" \n",
"\n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfc9230> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"this_aig = spot.aiger_circuit(aag_txt)\n",
"display(this_aig)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "0ad6c566",
"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": [
"print(this_aig.to_str())"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "2e1996c1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"((2, 4), (3, 5), (7, 9))\n"
]
}
],
"source": [
"print(this_aig.gates())"
]
},
{
"cell_type": "markdown",
"id": "41a8e042",
"metadata": {},
"source": [
"An AIG circuit can be transformed into a monitor/Mealy machine. This can be used for instance to check that it does not intersect the negation of the specification."
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "7399ea38",
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"!a & !b \n",
"/ \n",
" \n",
"!c & !d \n",
" \n",
"a & b \n",
"/ \n",
" \n",
"!c & d \n",
" \n",
"(!a & b) | (a & !b) \n",
"/ \n",
" \n",
"c & !d \n",
" \n",
" \n",
" \n"
],
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" \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",
" \n",
"!a & !b \n",
"/ \n",
" \n",
"!c & !d \n",
" \n",
"a & b \n",
"/ \n",
" \n",
"!c & d \n",
" \n",
"(!a & b) | (a & !b) \n",
"/ \n",
" \n",
"c & !d \n",
" \n",
" \n",
" \n"
],
"text/plain": [
" *' at 0x7f654cfcb720> >"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"this_aig.as_automaton()"
]
},
{
"cell_type": "markdown",
"id": "7ac06afc",
"metadata": {},
"source": [
"Note that the generation of aiger circuits from Mealy machines is flexible and accepts separated Mealy machines\n",
"as well as split Mealy machines."
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "bac68923",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"\n",
"
\n",
"\n",
" \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",
" \n",
"(!i0 & !i1) | (i0 & i1) \n",
"/ \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"0->0 \n",
" \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
"/ \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n",
"
\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) | (i0 & i1) \n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"2 \n",
" \n",
"\n",
"\n",
"0->2 \n",
" \n",
" \n",
"(!i0 & i1) | (i0 & !i1) \n",
" \n",
"\n",
"\n",
"1->0 \n",
" \n",
" \n",
"!o0 \n",
" \n",
"\n",
"\n",
"2->0 \n",
" \n",
" \n",
"o0 \n",
" \n",
" \n",
" \n",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"('o0',)\n",
"('o0',)\n"
]
}
],
"source": [
"strat1_s = spot.split_separated_mealy(strat1)\n",
"display_inline(strat1, strat1_s)\n",
"print(spot.get_synthesis_output_aps(strat1))\n",
"print(spot.get_synthesis_output_aps(strat1_s))"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "03ceb2a8",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"\n",
"
\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
"\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",
"
\n",
"\n",
"\n",
"\n",
"
\n",
"\n",
" \n",
"\n",
"\n",
"6 \n",
"\n",
"6 \n",
" \n",
"\n",
"\n",
"10 \n",
"\n",
"10 \n",
" \n",
"\n",
"\n",
"6->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"8 \n",
"\n",
"8 \n",
" \n",
"\n",
"\n",
"8->10 \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"o0 \n",
" \n",
"o0 \n",
" \n",
"\n",
"\n",
"10->o0:s \n",
" \n",
"\n",
" \n",
"\n",
"\n",
"2 \n",
" \n",
"i0 \n",
" \n",
"\n",
"\n",
"2->6 \n",
" \n",
"\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",
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display_inline(spot.mealy_machine_to_aig(strat1, \"isop\"), spot.mealy_machine_to_aig(strat1_s, \"isop\"))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.11.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}