{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from IPython.display import display\n",
"import spot\n",
"spot.setup()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To build an automaton, simply call `translate()` with a formula, and a list of options to characterize the automaton you want (those options have the same name as the long options name of the `ltl2tgba` tool, and they can be abbreviated)."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1043b73f0> >"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = spot.translate('(a U b) & GFc & GFd', 'BA', 'complete'); a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The call the `spot.setup()` in the first cells has installed a default style for the graphviz output. If you want to change this style temporarily, you can call the `show(style)` method explicitely. For instance here is a vertical layout with the default font of GraphViz."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.show(\"v\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you want to add some style options to the existing one, pass a dot to the `show()` function in addition to your own style options:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.show(\".ast\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `translate()` function can also be called with a formula object. Either as a function, or as a method."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/latex": [
"$a \\mathbin{\\mathsf{U}} b$"
],
"text/plain": [
"a U b"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f = spot.formula('a U b'); f"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042bc900> >"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.translate(f)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce7b0> >"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f.translate()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When used as a method, all the arguments are translation options. Here is a monitor:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1043b7390> >"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f.translate('mon')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following three cells show a formulas for which it makes a difference to select `'small'` or `'deterministic'`."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/latex": [
"$\\mathsf{G} a \\lor \\mathsf{G} b \\lor \\mathsf{G} c$"
],
"text/plain": [
"Ga | Gb | Gc"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f = spot.formula('Ga | Gb | Gc'); f"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f.translate('ba', 'small').show('.v')"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"f.translate('ba', 'det').show('v.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here is how to build an unambiguous automaton:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce870> >"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.translate('GFa -> GFb', 'unambig')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Compare with the standard translation:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042bc660> >"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.translate('GFa -> GFb')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And here is the automaton above with state-based acceptance:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce6c0> >"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.translate('GFa -> GFb', 'sbacc')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some example of running the self-loopization algorithm on an automaton:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1043dd600> >"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = spot.translate('F(a & X(!a &Xb))', \"any\"); a"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce600> >"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.sl(a)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.is_empty()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reading from file (see `automaton-io.ipynb` for more examples)."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Writing example1.aut\n"
]
}
],
"source": [
"%%file example1.aut\n",
"HOA: v1\n",
"States: 3\n",
"Start: 0\n",
"AP: 2 \"a\" \"b\"\n",
"acc-name: Buchi\n",
"Acceptance: 4 Inf(0)&Fin(1)&Fin(3) | Inf(2)&Inf(3) | Inf(1)\n",
"--BODY--\n",
"State: 0 {3}\n",
"[t] 0\n",
"[0] 1 {1}\n",
"[!0] 2 {0}\n",
"State: 1 {3}\n",
"[1] 0\n",
"[0&1] 1 {0}\n",
"[!0&1] 2 {2}\n",
"State: 2\n",
"[!1] 0\n",
"[0&!1] 1 {0}\n",
"[!0&!1] 2 {0}\n",
"--END--"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042bc8d0> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"a = spot.automaton('example1.aut')\n",
"display(a.show('.a'))\n",
"display(spot.remove_fin(a).show('.a'))\n",
"display(a.postprocess('TGBA', 'complete').show('.a'))\n",
"display(a.postprocess('BA'))"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"!rm example1.aut"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce780> >"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.complete(a)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce8a0> >"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.complete(spot.translate('Ga'))"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Using +1 in the display options is a convient way to shift the \n",
"# set numbers in the output, as an aid in reading the product.\n",
"a1 = spot.translate('a W c'); display(a1.show('.bat'))\n",
"a2 = spot.translate('a U b'); display(a2.show('.bat+1'))\n",
"# the product should display pairs of states, unless asked not to (using 1).\n",
"p = spot.product(a1, a2); display(p.show('.bat')); display(p.show('.bat1'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Explicit determinization after translation:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce810> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"a = spot.translate('FGa')\n",
"display(a)\n",
"display(a.is_deterministic())"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
""
],
"text/plain": [
""
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.tgba_determinize(a).show('.ba')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Determinization by `translate()`. The `generic` option allows any acceptance condition to be used instead of the default generalized Büchi."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce7e0> >"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"aut = spot.translate('FGa', 'generic', 'deterministic'); aut"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Adding an atomic proposition to all edges"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce7e0> >"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import buddy\n",
"b = buddy.bdd_ithvar(aut.register_ap('b'))\n",
"for e in aut.edges():\n",
" e.cond &= b\n",
"aut"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Adding an atomic proposition to the edge between 0 and 1:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"\n",
"\n",
"\n",
"\n",
"\n"
],
"text/plain": [
" *' at 0x7fb1042ce7e0> >"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c = buddy.bdd_ithvar(aut.register_ap('c'))\n",
"for e in aut.out(0):\n",
" if e.dst == 1:\n",
" e.cond &= c\n",
"aut"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}