{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import spot\n", "spot.setup()\n", "from spot.jupyter import display_inline\n", "def display2(*args):\n", " display_inline(*args, per_row=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Definitions and examples for parity acceptance" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In Spot a **parity acceptance** is defined by a **kind**, a **style** and a **numsets**:\n", "+ The **kind** can be either **max** or **min**.\n", "+ The **style** can be either **odd** or **even**.\n", "+ The **numsets** is the number of acceptance sets (a.k.a. colors) used by the parity acceptance.\n", " \n", "Here are some examples:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "parity min odd 1 = Fin(0)\n", "parity min odd 2 = Fin(0) & Inf(1)\n", "parity min odd 3 = Fin(0) & (Inf(1) | Fin(2))\n", "parity min odd 4 = Fin(0) & (Inf(1) | (Fin(2) & Inf(3)))\n", "parity min even 1 = Inf(0)\n", "parity min even 2 = Inf(0) | Fin(1)\n", "parity min even 3 = Inf(0) | (Fin(1) & Inf(2))\n", "parity min even 4 = Inf(0) | (Fin(1) & (Inf(2) | Fin(3)))\n", "parity max odd 1 = Fin(0)\n", "parity max odd 2 = Inf(1) | Fin(0)\n", "parity max odd 3 = Fin(2) & (Inf(1) | Fin(0))\n", "parity max odd 4 = Inf(3) | (Fin(2) & (Inf(1) | Fin(0)))\n", "parity max even 1 = Inf(0)\n", "parity max even 2 = Fin(1) & Inf(0)\n", "parity max even 3 = Inf(2) | (Fin(1) & Inf(0))\n", "parity max even 4 = Fin(3) & (Inf(2) | (Fin(1) & Inf(0)))\n" ] } ], "source": [ "for kind in ['min', 'max']:\n", " for style in ['odd', 'even']:\n", " for sets in range(1, 5):\n", " name = 'parity {} {} {}'.format(kind, style, sets)\n", " print('{:17} = {}'.format(name, spot.acc_code(name)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course the case of parity automata with a single color is a bit degenerate, as the same formula corresponds to two parity conditions of different kinds. \n", "\n", "In addition to the above, an automaton is said to be **colored** if each of its edges (or states) has exactly one color. Automata that people usually call *parity automata* correspond in Spot to *colored* automata with *parity acceptance*. For this reason try to use the term *automata with parity acceptance* rather than *parity automata* for automata that are not *colored*." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Generate a few random automata for the upcoming examples.\n", "maxodd4, maxodd5, minodd4, minodd5, maxeven4 = spot.automata(\"\"\"\n", "randaut -A 'parity max odd 4' -Q4 -e.4 2;\n", "randaut -A 'parity max odd 5' -Q4 -e.4 2;\n", "randaut -A 'parity min odd 4' -Q4 -e.4 2;\n", "randaut -A 'parity min odd 5' -Q4 -e.4 2;\n", "randaut -A 'parity max even 4' -Q4 -e.4 2|\"\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Testing parity and colored\n", "\n", "`is_parity()` is a method of `spot.acc_cond` that returns three Boolean values: \n", "1. whether the condition is a parity condition,\n", "2. whether it has `max` kind,\n", "3. whether it has `odd` style." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[True, True, True]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "maxodd4.acc().is_parity()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[True, True, False]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "maxeven4.acc().is_parity()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[True, False, True]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "minodd5.acc().is_parity()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default, `is_parity()` will match only conditions that are exactly equal to what the HOA format defines for the relevant configuration. For instance, the formula for `min odd 4` should be exactly the following:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fin(0) & (Inf(1) | (Fin(2) & Inf(3)))\n" ] } ], "source": [ "print(spot.acc_code(\"parity min odd 4\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However there are many formulas that are equivalent to the above. For instance the following `testacc` acceptance condition is logically equivalent to `parity min odd 4`. Passing it through `is_parity()` will fail: the first Boolean returned is False, and the remaining one should be ignored." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[False, False, True]\n" ] } ], "source": [ "testacc = spot.acc_cond(\"(Fin(0) & Inf(1)) | (Fin(0) & Fin(2) & Inf(3))\")\n", "print(testacc.is_parity())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To test logical equivalence to a Parity condition, pass a `True` argument to `is_parity()`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[True, False, True]\n" ] } ], "source": [ "print(testacc.is_parity(True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To test if an automaton is colored, use `is_colored`. Not this technically, this property is orthogonal to the fact the the automaton uses the acceptance conditions. It just states that each edge (or state) belongs to exactly one acceptance set." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.is_colored(minodd4)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spot.is_colored(spot.colorize_parity(minodd4)) # See below for `colorize_parity()`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Functions for altering automata with parity acceptance\n", "\n", "- [`change_parity()`](#Change-parity) can be used to alter the [*style*](#Changing-the-style), or [*kind*](#Changing-the-kind) of a parity acceptance. For instance if you have an automaton with `parity min even` acceptance and want an automaton with `parity max odd`, this is the function to use.\n", "- [`colorize_parity()`](#Colorize-parity) transforms an automaton with parity acceptance into a colored automaton with parity acceptance (a.k.a., parity automaton).\n", "- [`cleanup_parity()`](#Cleanup-parity) remove from the acceptance condition colors that are unused in the automaton, while keeping it a parity acceptance.\n", "- [`reduce_parity()`](#Reduce-parity) minimize the number of colors used in the automaton, producing the smallest parity acceptance condition possible for this automaton." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Change parity\n", "\n", "This section describes the `change_parity()` method, that allows switching between different kinds and styles.\n", "Its takes three arguments:\n", "1. the automaton to modify\n", "2. the desired kind (`spot.parity_kind_any`, `spot.parity_kind_same`, `spot.parity_kind_max`, `spot.parity_kind_min`)\n", "3. the desired style (`spot.parity_style_any`, `spot.parity_style_same`, `spot.parity_style_odd`, `spot.parity_style_even`)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Changing the **style**\n", "\n", "Changing the style from `odd` to `even` or vice-versa can be done by adding a new color 0 and shifting all original colors by one, keeping the maximum or minimum color in case an edge has multiple colors.\n", "\n", "When the acceptance is a parity `max`, all the transitions that do not belong to any acceptance set will have the new color.\n", "\n", "### max odd 5 → max even 6" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "