{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "4d896402", "metadata": {}, "outputs": [], "source": [ "import spot, buddy" ] }, { "cell_type": "markdown", "id": "94e87f9c", "metadata": {}, "source": [ "# Partitioned relabeling\n", "\n", "Partitioned relabeling will:\n", "First compute a partition over all conditions appearing in the automaton.\n", "That is, the set of new conditions is such that (1) they do not overlap (2) all valuations that verify some condition in the original automaton also verify (exactly one) of the new conditions.\n", "These new conditions can be thought of as letters in a \"classical\" sense.\n", "Then we create new aps and encode the \"number\" of these letters using the fresh aps, resulting in new letters which are a single valuation over the fresh aps.\n", "\n", "This can be helpful if there are many aps, but few different conditions over them\n", "\n", "The algorithm comes in two flavours:\n", "\n", "We maintain the original number of edges. Therefore the new label correspond to a disjunction over new letters (split=False).\n", "We split each edge into its letters, creating more edges (split=True)." ] }, { "cell_type": "code", "execution_count": 2, "id": "62123fa9", "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", "1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "a\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "a & b0 & b1 & b2\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "a & !b0 & !b1 & !b2\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b0311a80> >" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#Relabeling a graph\n", "aut = spot.make_twa_graph()\n", "aut.new_states(5)\n", "\n", "a = buddy.bdd_ithvar(aut.register_ap(\"a\"))\n", "na = buddy.bdd_nithvar(aut.register_ap(\"a\"))\n", "b0 = buddy.bdd_ithvar(aut.register_ap(\"b0\"))\n", "nb0 = buddy.bdd_nithvar(aut.register_ap(\"b0\"))\n", "b1 = buddy.bdd_ithvar(aut.register_ap(\"b1\"))\n", "nb1 = buddy.bdd_nithvar(aut.register_ap(\"b1\"))\n", "b2 = buddy.bdd_ithvar(aut.register_ap(\"b2\"))\n", "nb2 = buddy.bdd_nithvar(aut.register_ap(\"b2\"))\n", "\n", "aut.new_edge(0,1,buddy.bddtrue)\n", "aut.new_edge(0,2,a)\n", "aut.new_edge(0,3,a&b0&b1&b2)\n", "aut.new_edge(0,4,a&nb0&nb1&nb2)\n", "\n", "aut" ] }, { "cell_type": "code", "execution_count": 3, "id": "d4c8e977", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\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", "1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "__nv0 | __nv1\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "!__nv0 & __nv1\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "__nv0 & __nv1\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b0311a80> >" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "relabel_dict = spot.partitioned_relabel_here(aut)\n", "\n", "print(relabel_dict.size())\n", "aut" ] }, { "cell_type": "code", "execution_count": 4, "id": "6f90a095", "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", "1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "a\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "a & b0 & b1 & b2\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "a & !b0 & !b1 & !b2\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b0311a80> >" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Undo the relabeling\n", "spot.relabel_here(aut, relabel_dict)\n", "aut" ] }, { "cell_type": "code", "execution_count": 5, "id": "513067ab", "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", "1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "a\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "a & b0 & b1 & b2\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "a & !b0 & !b1 & !b2\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b02c0d50> >" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "HOA: v1\n", "States: 5\n", "Start: 0\n", "AP: 6 \"a\" \"b0\" \"b1\" \"b2\" \"__nv0\" \"__nv1\"\n", "acc-name: all\n", "Acceptance: 0 t\n", "properties: trans-labels explicit-labels state-acc\n", "--BODY--\n", "State: 0\n", "[!4&!5] 1\n", "[4&!5] 2\n", "[!4&5] 3\n", "[4&5] 4\n", "[4&!5] 1\n", "[4&5] 1\n", "[!4&5] 1\n", "[4&5] 2\n", "[!4&5] 2\n", "State: 1\n", "State: 2\n", "State: 3\n", "State: 4\n", "--END--\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", "!__nv0 & !__nv1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "__nv0 & !__nv1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "__nv0 & __nv1\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "!__nv0 & __nv1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "__nv0 & !__nv1\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "__nv0 & __nv1\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "!__nv0 & __nv1\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "!__nv0 & __nv1\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "__nv0 & __nv1\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b02c0d50> >" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Relabeling the same graph using the split option\n", "aut = spot.make_twa_graph()\n", "aut.new_states(5)\n", "\n", "a = buddy.bdd_ithvar(aut.register_ap(\"a\"))\n", "na = buddy.bdd_nithvar(aut.register_ap(\"a\"))\n", "b0 = buddy.bdd_ithvar(aut.register_ap(\"b0\"))\n", "nb0 = buddy.bdd_nithvar(aut.register_ap(\"b0\"))\n", "b1 = buddy.bdd_ithvar(aut.register_ap(\"b1\"))\n", "nb1 = buddy.bdd_nithvar(aut.register_ap(\"b1\"))\n", "b2 = buddy.bdd_ithvar(aut.register_ap(\"b2\"))\n", "nb2 = buddy.bdd_nithvar(aut.register_ap(\"b2\"))\n", "\n", "aut.new_edge(0,1,buddy.bddtrue)\n", "aut.new_edge(0,2,a)\n", "aut.new_edge(0,3,a&b0&b1&b2)\n", "aut.new_edge(0,4,a&nb0&nb1&nb2)\n", "\n", "display(aut)\n", "xx = spot.partitioned_relabel_here(aut, True)\n", "print(aut.to_str(\"hoa\"))\n", "aut" ] }, { "cell_type": "code", "execution_count": 6, "id": "50c6a08b", "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", "!a\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "(a & !b0 & b2) | (a & b0 & !b2) | (a & !b1 & b2) | (a & b1 & !b2)\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "a & !b0 & !b1 & !b2\n", "\n", "\n", "\n", "0->1\n", "\n", "\n", "a & b0 & b1 & b2\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "(a & !b0 & b2) | (a & b0 & !b2) | (a & !b1 & b2) | (a & b1 & !b2)\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "a & !b0 & !b1 & !b2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "a & b0 & b1 & b2\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "a & b0 & b1 & b2\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "a & !b0 & !b1 & !b2\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b02c0d50> >" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Undo the relabeling -> disjoint conditions over the original ap\n", "spot.relabel_here(aut, relabel_dict)\n", "aut" ] }, { "cell_type": "code", "execution_count": 7, "id": "d2efd313", "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", "1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "a\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "a & b\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "a & !b\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "0->5\n", "\n", "\n", "c\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b02c90f0> >" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "HOA: v1\n", "States: 6\n", "Start: 0\n", "AP: 5 \"a\" \"__nv0\" \"__nv1\" \"b\" \"c\"\n", "acc-name: all\n", "Acceptance: 0 t\n", "properties: trans-labels explicit-labels state-acc\n", "--BODY--\n", "State: 0\n", "[!1 | !2] 1\n", "[!1&2 | 1&!2] 2\n", "[!1&2] 3\n", "[1&!2] 4\n", "[4] 5\n", "State: 1\n", "State: 2\n", "State: 3\n", "State: 4\n", "State: 5\n", "--END--\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", "!__nv0 | !__nv1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "(__nv0 & !__nv1) | (!__nv0 & __nv1)\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "!__nv0 & __nv1\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "__nv0 & !__nv1\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "0->5\n", "\n", "\n", "c\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b02c90f0> >" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Working only on a subset of the aps\n", "# Note that True is always relabeled\n", "\n", "aut = spot.make_twa_graph()\n", "aut.new_states(6)\n", "\n", "a = buddy.bdd_ithvar(aut.register_ap(\"a\"))\n", "na = buddy.bdd_nithvar(aut.register_ap(\"a\"))\n", "b = buddy.bdd_ithvar(aut.register_ap(\"b\"))\n", "nb = buddy.bdd_nithvar(aut.register_ap(\"b\"))\n", "c = buddy.bdd_ithvar(aut.register_ap(\"c\"))\n", "nc = buddy.bdd_nithvar(aut.register_ap(\"c\"))\n", "\n", "aut.new_edge(0,1,buddy.bddtrue)\n", "aut.new_edge(0,2,a)\n", "aut.new_edge(0,3,a&b)\n", "aut.new_edge(0,4,a&nb)\n", "aut.new_edge(0,5,c)\n", "\n", "display(aut)\n", "\n", "concerned_aps = a & b # concerned aps are given as a conjunction of positive aps\n", "# As partitioning can be exponentially costly,\n", "# one can limit the number of new letters generated before abadoning\n", "# This can be done either as a hard limit and/or as the number of current condition\n", "# times a factor\n", "relabel_dict = spot.partitioned_relabel_here(aut, False, 1000, 1000, concerned_aps)\n", "print(aut.to_str(\"hoa\"))\n", "aut" ] }, { "cell_type": "code", "execution_count": 8, "id": "1fbc8813", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "HOA: v1\n", "States: 6\n", "Start: 0\n", "AP: 3 \"a\" \"b\" \"c\"\n", "acc-name: all\n", "Acceptance: 0 t\n", "properties: trans-labels explicit-labels state-acc\n", "--BODY--\n", "State: 0\n", "[t] 1\n", "[0] 2\n", "[0&1] 3\n", "[0&!1] 4\n", "[2] 5\n", "State: 1\n", "State: 2\n", "State: 3\n", "State: 4\n", "State: 5\n", "--END--\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", "1\n", "\n", "\n", "\n", "2\n", "\n", "2\n", "\n", "\n", "\n", "0->2\n", "\n", "\n", "a\n", "\n", "\n", "\n", "3\n", "\n", "3\n", "\n", "\n", "\n", "0->3\n", "\n", "\n", "a & b\n", "\n", "\n", "\n", "4\n", "\n", "4\n", "\n", "\n", "\n", "0->4\n", "\n", "\n", "a & !b\n", "\n", "\n", "\n", "5\n", "\n", "5\n", "\n", "\n", "\n", "0->5\n", "\n", "\n", "c\n", "\n", "\n", "\n" ], "text/plain": [ " *' at 0x7f65b02c90f0> >" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#undo partial relabeling\n", "spot.relabel_here(aut, relabel_dict)\n", "print(aut.to_str(\"hoa\"))\n", "aut" ] } ], "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.8.10" } }, "nbformat": 4, "nbformat_minor": 5 }