{
"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"
],
"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"
],
"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"
],
"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"
],
"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"
],
"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"
],
"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"
],
"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"
],
"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"
],
"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
}