spot/tests/python/stutter-inv.ipynb
Alexandre Duret-Lutz 58e64e752c python: upgrade notebook format to v4
Fixes #311.

* tests/python/ipnbdoctest.py: Adjust to process the new format,
with a lot of inspiration from Vcsn's copy of this file.
* tests/python/_altscc.ipynb, tests/python/_aux.ipynb,
tests/python/acc_cond.ipynb, tests/python/accparse.ipynb,
tests/python/alternation.ipynb, tests/python/atva16-fig2a.ipynb,
tests/python/atva16-fig2b.ipynb, tests/python/automata-io.ipynb,
tests/python/automata.ipynb, tests/python/decompose.ipynb,
tests/python/formulas.ipynb, tests/python/gen.ipynb,
tests/python/highlighting.ipynb, tests/python/ltsmin-dve.ipynb,
tests/python/ltsmin-pml.ipynb, tests/python/parity.ipynb,
tests/python/piperead.ipynb, tests/python/product.ipynb,
tests/python/randaut.ipynb, tests/python/randltl.ipynb,
tests/python/stutter-inv.ipynb, tests/python/testingaut.ipynb,
tests/python/word.ipynb: Upgrade to the new format.
* NEWS: Mention the change.
2018-01-07 12:59:59 +01:00

2834 lines
155 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import spot\n",
"spot.setup(show_default='.ban')\n",
"from IPython.display import display"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Stutter-invariant languages\n",
"\n",
"A language $L$ is said to be _stutter-invariant_ iff $\\ell_0\\ldots\\ell_{i-1}\\ell_i\\ell_{i+1}\\ldots\\in L \\iff \\ell_0\\ldots\\ell_{i-1}\\ell_i\\ell_i\\ell_{i+1}\\ldots\\in L$, i.e., if duplicating a letter in a word or removing a duplicated letter does not change the membership of that word to $L$. These languages are also called _stutter-insensitive_. We use the adjective _sutter-sensitive_ to describe a language that is not stutter-invariant. Of course we can extend this vocabulary to LTL formulas or automata that represent stutter-invariant languages.\n",
"\n",
"Stutter-invariant languages play an important role in model checking. When verifying a stutter-invariant specification against a system, we know that we have some freedom in how we discretize the time in the model: as long as we do not hide changes of model variables that are observed by the specification, we can merge multiple steps of the model. This, combined by careful analysis of actions of the model that are independent, is the basis for a set of techniques known as _partial-order reductions_ (POR) that postpone the visit of some successors in the model, because we know we can always visit them later."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stutter-invariant formulas\n",
"\n",
"When the specification is expressed as an LTL formula, a well known way to ensure it is _stutter-invariant_ is to forbid the use of the `X` operator. Testing whether a formula is `X`-free can be done in constant time using the `is_syntactic_stutter_invariant()` method."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n"
]
}
],
"source": [
"f = spot.formula('a U b')\n",
"print(f.is_syntactic_stutter_invariant())"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"False\n"
]
}
],
"source": [
"f = spot.formula('a U Xb')\n",
"print(f.is_syntactic_stutter_invariant())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However some formula are syntactic-invariant despite their use of `X`. Spot implements some [automaton-based check](https://www.lrde.epita.fr/~adl/dl/adl/michaud.15.spin.pdf) to detect stutter-invariance reliably and efficiently. This can be tested with the `is_stutter_invariant()` function."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"False\n",
"True\n"
]
}
],
"source": [
"g = spot.formula('F(a & X(!a & Gb))')\n",
"print(g.is_syntactic_stutter_invariant())\n",
"print(spot.is_stutter_invariant(g))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Of course this `is_stutter_invariant()` function first checks whether the formula is `X`-free before wasting time building automata, so if you want to detect stutter-invariant formulas in your model checker, this is the only function to use. Also, if you hapen to already have an automaton `aut_g` for `g`, you should pass it as a second argument to avoid it being recomputed: `spot.is_stutter_invariant(g, aut_g)`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is also known that any stutter-invariant LTL formula can be converted to an `X`-free LTL formula. Several proofs of that exist. Spot implements the rewriting of [K. Etessami](http://homepages.inf.ed.ac.uk/kousha/note_on_stut_tl_lpi.ps) under the name `remove_x()`. Note that the output of this function is only equivalent to its input if the latter is stutter-invariant."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/latex": [
"$\\mathsf{F} (a \\land ((a \\land (a \\mathbin{\\mathsf{U}} (\\lnot a \\land \\mathsf{G} b)) \\land ((\\lnot b \\mathbin{\\mathsf{U}} \\lnot a) \\lor (b \\mathbin{\\mathsf{U}} \\lnot a))) \\lor (\\lnot a \\land (\\lnot a \\mathbin{\\mathsf{U}} (a \\land \\lnot a \\land \\mathsf{G} b)) \\land ((\\lnot b \\mathbin{\\mathsf{U}} a) \\lor (b \\mathbin{\\mathsf{U}} a))) \\lor (b \\land (b \\mathbin{\\mathsf{U}} (\\lnot a \\land \\lnot b \\land \\mathsf{G} b)) \\land ((\\lnot a \\mathbin{\\mathsf{U}} \\lnot b) \\lor (a \\mathbin{\\mathsf{U}} \\lnot b))) \\lor (\\lnot b \\land (\\lnot b \\mathbin{\\mathsf{U}} (\\lnot a \\land b \\land \\mathsf{G} b)) \\land ((\\lnot a \\mathbin{\\mathsf{U}} b) \\lor (a \\mathbin{\\mathsf{U}} b))) \\lor (\\lnot a \\land \\mathsf{G} b \\land (\\mathsf{G} \\lnot a \\lor \\mathsf{G} a) \\land (\\mathsf{G} b \\lor \\mathsf{G} \\lnot b))))$"
],
"text/plain": [
"F(a & ((a & (a U (!a & Gb)) & ((!b U !a) | (b U !a))) | (!a & (!a U (a & !a & Gb)) & ((!b U a) | (b U a))) | (b & (b U (!a & !b & Gb)) & ((!a U !b) | (a U !b))) | (!b & (!b U (!a & b & Gb)) & ((!a U b) | (a U b))) | (!a & Gb & (G!a | Ga) & (Gb | G!b))))"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.remove_x(g)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stutter-invariant automata"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Similarly to formulas, automata use a few bits to store some known properties about themselves, like whether they represent a stutter-invariant language. This property can be checked with the `prop_stutter_invariant()` method, but that returns a `trival` instance (i.e., yes, no, or maybe). Some algorithms will update that property whenever that is cheap or expliclitely asked for. For instance `spot.translate()` only sets the property if the translated formula is `X`-free."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"maybe\n"
]
}
],
"source": [
"aut = spot.translate(g)\n",
"print(aut.prop_stutter_invariant())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As suggested above, we can call `is_stutter_invariant()` by passing a formula and its automaton, to save on one translation. A second translation is still needed to complement the automaton."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n"
]
}
],
"source": [
"print(spot.is_stutter_invariant(g, aut))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that `prop_stutter_invariant()` was updated as a side-effect so that any futher call to `is_stutter_invariant()` with this automaton will be instantaneous."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"yes\n"
]
}
],
"source": [
"print(aut.prop_stutter_invariant())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You have to be aware of this property being set in your back because if while playing with `is_stutter_invariant()` you the incorrect formula for an automaton by mistake, the automaton will have its property set incorrectly, and running `is_stutter_inariant()` with the correct formula will simply return the cached property.\n",
"\n",
"In doubt, you can always reset the property as follows:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"maybe\n"
]
}
],
"source": [
"aut.prop_stutter_invariant(spot.trival_maybe())\n",
"print(aut.prop_stutter_invariant())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In case you have an automaton for which you do not have formula, you can also use `is_stutter_invariant()` by passing this automaton as the first argument. In that case a negated automaton will be constructed by determinization. If you do happen to have a negated automaton handy, you can pass it as a second argument to avoid that."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"163pt\" height=\"84pt\"\n",
" viewBox=\"0.00 0.00 163.00 84.35\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 80.3516)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-80.3516 159,-80.3516 159,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"74.5\" y=\"-61.1516\" font-family=\"Lato\" font-size=\"14.00\">t</text>\n",
"<text text-anchor=\"start\" x=\"66.5\" y=\"-46.1516\" font-family=\"Lato\" font-size=\"14.00\">[all]</text>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-20.3516\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-16.6516\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-20.3516C2.79388,-20.3516 17.1543,-20.3516 30.6317,-20.3516\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-20.3516 30.9419,-23.5017 34.4419,-20.3516 30.9419,-20.3517 30.9419,-20.3517 30.9419,-20.3517 34.4419,-20.3516 30.9418,-17.2017 37.9419,-20.3516 37.9419,-20.3516\"/>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"137\" cy=\"-20.3516\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"137\" y=\"-16.6516\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.1418,-20.3516C85.1153,-20.3516 99.5214,-20.3516 111.67,-20.3516\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.892,-20.3516 111.892,-23.5017 115.392,-20.3516 111.892,-20.3517 111.892,-20.3517 111.892,-20.3517 115.392,-20.3516 111.892,-17.2017 118.892,-20.3516 118.892,-20.3516\"/>\n",
"<text text-anchor=\"start\" x=\"93\" y=\"-24.1516\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>1&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M122.524,-9.39411C114.011,-3.78441 102.645,1.35158 92,-1.35158 87.1374,-2.58634 82.2193,-4.64763 77.668,-6.96768\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"71.3113,-10.4859 75.9105,-4.34007 74.3736,-8.79098 77.4359,-7.09611 77.4359,-7.09611 77.4359,-7.09611 74.3736,-8.79098 78.9613,-9.85216 71.3113,-10.4859 71.3113,-10.4859\"/>\n",
"<text text-anchor=\"middle\" x=\"96.5\" y=\"-5.15158\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce55870> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"False\n"
]
}
],
"source": [
"a1 = spot.automaton('''HOA: v1 \n",
"AP: 1 \"a\" \n",
"States: 2 \n",
"Start: 0 \n",
"Acceptance: 0 t\n",
"--BODY-- \n",
"State: 0 [0] 1 \n",
"State: 1 [t] 0 \n",
"--END--''')\n",
"display(a1)\n",
"print(spot.is_stutter_invariant(a1))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Explaining why a formula is not sutter-invariant"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As explained in our [Spin'15 paper](https://www.lrde.epita.fr/~adl/dl/adl/michaud.15.spin.pdf) the sutter-invariant checks are implemented using simple operators suchs as `spot.closure(aut)`, that augment the language of L by adding words that can be obtained by removing duplicated letters, and `spot.sl(aut)` or `spot.sl2(aut)` that both augment the language that L by adding words that can be obtained by duplicating letters. The default `is_stutter_invariant()` function is implemented as `spot.product(spot.closure(aut), spot.closure(neg_aut)).is_empty()`, but that is just one possible implementation selected because it was more efficient.\n",
"\n",
"Using these bricks, we can modify the original algorithm so it uses a counterexample to explain why a formula is stutter-sensitive."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def explain_stut(f):\n",
" f = spot.formula(f)\n",
" pos = spot.translate(f)\n",
" neg = spot.translate(spot.formula_Not(f))\n",
" word = spot.product(spot.closure(pos), spot.closure(neg)).accepting_word()\n",
" if word is None:\n",
" print(f, \"is stutter invariant\")\n",
" return\n",
" word.simplify()\n",
" waut = word.as_automaton()\n",
" if waut.intersects(pos):\n",
" acc, rej, aut = \"accepted\", \"rejected\", neg\n",
" else:\n",
" acc, rej, aut = \"rejected\", \"accepted\", pos\n",
" word2 = spot.sl2(waut).intersecting_word(aut)\n",
" word2.simplify()\n",
" print(\"\"\"{} is {} by {}\n",
" but if we stutter some of its letters, we get\n",
"{} which is {} by {}\"\"\".format(word, acc, f, word2, rej, f))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cycle{!a & !b; a & b} is rejected by GF(a & Xb)\n",
" but if we stutter some of its letters, we get\n",
"cycle{!a & !b; a & b; a & b} which is accepted by GF(a & Xb)\n"
]
}
],
"source": [
"explain_stut('GF(a & Xb)')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Detecting stutter-invariant states\n",
"\n",
"Even if the language of an automaton is not sutter invariant, some of its states may recognize a stutter-invariant language. (We assume the language of a state is the language the automaton would have when starting from this state.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### First example\n",
"\n",
"For instance let us build a disjunction of a stutter-invariant formula and a stutter-sensitive one:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n",
"False\n",
"False\n"
]
}
],
"source": [
"f1 = spot.formula('F(a & X!a & XF(b & X!b & Ga))')\n",
"f2 = spot.formula('F(a & Xa & XXa & G!b)')\n",
"f = spot.formula_Or([f1, f2])\n",
"\n",
"print(spot.is_stutter_invariant(f1))\n",
"print(spot.is_stutter_invariant(f2))\n",
"print(spot.is_stutter_invariant(f))"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"518pt\" height=\"230pt\"\n",
" viewBox=\"0.00 0.00 518.00 230.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 226)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-226 514,-226 514,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"234\" y=\"-207.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"256\" y=\"-207.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"272\" y=\"-207.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"232\" y=\"-193.8\" font-family=\"Lato\" font-size=\"14.00\">[Büchi]</text>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-78\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-74.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-78C2.79388,-78 17.1543,-78 30.6317,-78\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-78 30.9419,-81.1501 34.4419,-78 30.9419,-78.0001 30.9419,-78.0001 30.9419,-78.0001 34.4419,-78 30.9418,-74.8501 37.9419,-78 37.9419,-78\"/>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-95.0373C48.3189,-104.858 50.4453,-114 56,-114 60.166,-114 62.4036,-108.858 62.7128,-102.143\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-95.0373 65.8541,-101.882 62.5434,-98.5335 62.7076,-102.03 62.7076,-102.03 62.7076,-102.03 62.5434,-98.5335 59.561,-102.177 62.3792,-95.0373 62.3792,-95.0373\"/>\n",
"<text text-anchor=\"start\" x=\"51.5\" y=\"-117.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"165\" cy=\"-103\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"start\" x=\"160.5\" y=\"-99.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.7188,-81.9062C91.6218,-86.0892 120.176,-92.7606 140.371,-97.4793\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"147.399,-99.1212 139.866,-100.596 143.99,-98.3248 140.582,-97.5285 140.582,-97.5285 140.582,-97.5285 143.99,-98.3248 141.299,-94.4611 147.399,-99.1212 147.399,-99.1212\"/>\n",
"<text text-anchor=\"start\" x=\"107\" y=\"-98.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node4\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"165\" cy=\"-49\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"165\" y=\"-45.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;2 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.7153,-73.1495C79.4994,-71.4909 86.0282,-69.6409 92,-68 108.136,-63.5664 126.361,-58.7589 140.438,-55.0891\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"147.388,-53.2817 141.406,-58.0921 144.001,-54.1626 140.613,-55.0435 140.613,-55.0435 140.613,-55.0435 144.001,-54.1626 139.82,-51.9949 147.388,-53.2817 147.388,-53.2817\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-71.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node5\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"274\" cy=\"-105\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"274\" y=\"-101.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;3 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M183.191,-103.321C200.897,-103.652 228.648,-104.171 248.616,-104.544\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"255.851,-104.679 248.794,-107.698 252.352,-104.614 248.852,-104.549 248.852,-104.549 248.852,-104.549 252.352,-104.614 248.911,-101.399 255.851,-104.679 255.851,-104.679\"/>\n",
"<text text-anchor=\"start\" x=\"214\" y=\"-108.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g id=\"node6\" class=\"node\"><title>5</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"274\" cy=\"-48\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"274\" y=\"-44.3\" font-family=\"Lato\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;5 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>2&#45;&gt;5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M183.191,-48.8393C200.897,-48.6739 228.648,-48.4145 248.616,-48.2279\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"255.851,-48.1603 248.881,-51.3756 252.351,-48.193 248.852,-48.2258 248.852,-48.2258 248.852,-48.2258 252.351,-48.193 248.822,-45.0759 255.851,-48.1603 255.851,-48.1603\"/>\n",
"<text text-anchor=\"start\" x=\"201\" y=\"-52.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M264.767,-120.541C262.169,-130.909 265.246,-141 274,-141 280.702,-141 284.077,-135.085 284.124,-127.659\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"283.233,-120.541 287.229,-127.095 283.668,-124.014 284.103,-127.487 284.103,-127.487 284.103,-127.487 283.668,-124.014 280.977,-127.879 283.233,-120.541 283.233,-120.541\"/>\n",
"<text text-anchor=\"start\" x=\"269.5\" y=\"-144.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node7\" class=\"node\"><title>4</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"383\" cy=\"-120\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"383\" y=\"-116.3\" font-family=\"Lato\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>3&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M292.191,-107.41C309.975,-109.903 337.892,-113.817 357.88,-116.619\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"364.851,-117.596 357.482,-119.744 361.385,-117.11 357.919,-116.624 357.919,-116.624 357.919,-116.624 361.385,-117.11 358.356,-113.505 364.851,-117.596 364.851,-117.596\"/>\n",
"<text text-anchor=\"start\" x=\"311.5\" y=\"-118.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; b</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g id=\"node9\" class=\"node\"><title>6</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"383\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"383\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;6 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>5&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M291.719,-43.3125C309.7,-38.2709 338.426,-30.2169 358.637,-24.5505\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"365.399,-22.6546 359.509,-27.5774 362.029,-23.5995 358.659,-24.5444 358.659,-24.5444 358.659,-24.5444 362.029,-23.5995 357.808,-21.5114 365.399,-22.6546 365.399,-22.6546\"/>\n",
"<text text-anchor=\"start\" x=\"310\" y=\"-41.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 7 -->\n",
"<g id=\"node8\" class=\"node\"><title>7</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"492\" cy=\"-120\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"492\" y=\"-116.3\" font-family=\"Lato\" font-size=\"14.00\">7</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;7 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>4&#45;&gt;7</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M401.191,-120C418.897,-120 446.648,-120 466.616,-120\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"473.851,-120 466.851,-123.15 470.351,-120 466.851,-120 466.851,-120 466.851,-120 470.351,-120 466.851,-116.85 473.851,-120 473.851,-120\"/>\n",
"<text text-anchor=\"start\" x=\"419\" y=\"-123.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;7 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>7&#45;&gt;7</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M482.767,-135.541C480.169,-145.909 483.246,-156 492,-156 498.702,-156 502.077,-150.085 502.124,-142.659\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"501.233,-135.541 505.229,-142.095 501.668,-139.014 502.103,-142.487 502.103,-142.487 502.103,-142.487 501.668,-139.014 498.977,-142.879 501.233,-135.541 501.233,-135.541\"/>\n",
"<text text-anchor=\"start\" x=\"488.5\" y=\"-174.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"484\" y=\"-159.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;6 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>6&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M373.767,-33.5414C371.169,-43.9087 374.246,-54 383,-54 389.702,-54 393.077,-48.0847 393.124,-40.6591\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"392.233,-33.5414 396.229,-40.0955 392.668,-37.0143 393.103,-40.4871 393.103,-40.4871 393.103,-40.4871 392.668,-37.0143 389.977,-40.8788 392.233,-33.5414 392.233,-33.5414\"/>\n",
"<text text-anchor=\"start\" x=\"376.5\" y=\"-72.8\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n",
"<text text-anchor=\"start\" x=\"375\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce2e900> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"pos = spot.translate(f)\n",
"display(pos)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"While the automaton as a whole is stutter-sensitive, we can see that eventually we will enter a sub-automaton that is stutter-invariant.\n",
"\n",
"The `stutter_invariant_states()` function returns a Boolean vector indiced by the state number. A state is marked as `True` if either its language is stutter-invariant, or if it can only be reached via a stutter-invariant state (see the second example later). As always, the second argument, `f`, can be omitted (pass `None`) if the formula is unknown, or it can be replaced by a negated automaton if it is known. "
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(False, True, False, True, True, True, True, True)"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.stutter_invariant_states(pos, f)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For convenience, the `highligh_...()` version colors the stutter-invariant states of the automaton for display.\n",
"(That 5 is the color number for red in Spot's hard-coded palette.)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"518pt\" height=\"230pt\"\n",
" viewBox=\"0.00 0.00 518.00 230.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 226)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-226 514,-226 514,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"234\" y=\"-207.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"256\" y=\"-207.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"272\" y=\"-207.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"232\" y=\"-193.8\" font-family=\"Lato\" font-size=\"14.00\">[Büchi]</text>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-78\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-74.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-78C2.79388,-78 17.1543,-78 30.6317,-78\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-78 30.9419,-81.1501 34.4419,-78 30.9419,-78.0001 30.9419,-78.0001 30.9419,-78.0001 34.4419,-78 30.9418,-74.8501 37.9419,-78 37.9419,-78\"/>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-95.0373C48.3189,-104.858 50.4453,-114 56,-114 60.166,-114 62.4036,-108.858 62.7128,-102.143\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-95.0373 65.8541,-101.882 62.5434,-98.5335 62.7076,-102.03 62.7076,-102.03 62.7076,-102.03 62.5434,-98.5335 59.561,-102.177 62.3792,-95.0373 62.3792,-95.0373\"/>\n",
"<text text-anchor=\"start\" x=\"51.5\" y=\"-117.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"165\" cy=\"-103\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"start\" x=\"160.5\" y=\"-99.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.7188,-81.9062C91.6218,-86.0892 120.176,-92.7606 140.371,-97.4793\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"147.399,-99.1212 139.866,-100.596 143.99,-98.3248 140.582,-97.5285 140.582,-97.5285 140.582,-97.5285 143.99,-98.3248 141.299,-94.4611 147.399,-99.1212 147.399,-99.1212\"/>\n",
"<text text-anchor=\"start\" x=\"107\" y=\"-98.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node4\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"165\" cy=\"-49\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"165\" y=\"-45.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;2 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.7153,-73.1495C79.4994,-71.4909 86.0282,-69.6409 92,-68 108.136,-63.5664 126.361,-58.7589 140.438,-55.0891\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"147.388,-53.2817 141.406,-58.0921 144.001,-54.1626 140.613,-55.0435 140.613,-55.0435 140.613,-55.0435 144.001,-54.1626 139.82,-51.9949 147.388,-53.2817 147.388,-53.2817\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-71.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node5\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"274\" cy=\"-105\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"274\" y=\"-101.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;3 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M183.191,-103.321C200.897,-103.652 228.648,-104.171 248.616,-104.544\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"255.851,-104.679 248.794,-107.698 252.352,-104.614 248.852,-104.549 248.852,-104.549 248.852,-104.549 252.352,-104.614 248.911,-101.399 255.851,-104.679 255.851,-104.679\"/>\n",
"<text text-anchor=\"start\" x=\"214\" y=\"-108.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g id=\"node6\" class=\"node\"><title>5</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"274\" cy=\"-48\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"274\" y=\"-44.3\" font-family=\"Lato\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;5 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>2&#45;&gt;5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M183.191,-48.8393C200.897,-48.6739 228.648,-48.4145 248.616,-48.2279\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"255.851,-48.1603 248.881,-51.3756 252.351,-48.193 248.852,-48.2258 248.852,-48.2258 248.852,-48.2258 252.351,-48.193 248.822,-45.0759 255.851,-48.1603 255.851,-48.1603\"/>\n",
"<text text-anchor=\"start\" x=\"201\" y=\"-52.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M264.767,-120.541C262.169,-130.909 265.246,-141 274,-141 280.702,-141 284.077,-135.085 284.124,-127.659\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"283.233,-120.541 287.229,-127.095 283.668,-124.014 284.103,-127.487 284.103,-127.487 284.103,-127.487 283.668,-124.014 280.977,-127.879 283.233,-120.541 283.233,-120.541\"/>\n",
"<text text-anchor=\"start\" x=\"269.5\" y=\"-144.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node7\" class=\"node\"><title>4</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"383\" cy=\"-120\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"383\" y=\"-116.3\" font-family=\"Lato\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>3&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M292.191,-107.41C309.975,-109.903 337.892,-113.817 357.88,-116.619\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"364.851,-117.596 357.482,-119.744 361.385,-117.11 357.919,-116.624 357.919,-116.624 357.919,-116.624 361.385,-117.11 358.356,-113.505 364.851,-117.596 364.851,-117.596\"/>\n",
"<text text-anchor=\"start\" x=\"311.5\" y=\"-118.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; b</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g id=\"node9\" class=\"node\"><title>6</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"383\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"383\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;6 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>5&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M291.719,-43.3125C309.7,-38.2709 338.426,-30.2169 358.637,-24.5505\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"365.399,-22.6546 359.509,-27.5774 362.029,-23.5995 358.659,-24.5444 358.659,-24.5444 358.659,-24.5444 362.029,-23.5995 357.808,-21.5114 365.399,-22.6546 365.399,-22.6546\"/>\n",
"<text text-anchor=\"start\" x=\"310\" y=\"-41.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 7 -->\n",
"<g id=\"node8\" class=\"node\"><title>7</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"492\" cy=\"-120\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"492\" y=\"-116.3\" font-family=\"Lato\" font-size=\"14.00\">7</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;7 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>4&#45;&gt;7</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M401.191,-120C418.897,-120 446.648,-120 466.616,-120\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"473.851,-120 466.851,-123.15 470.351,-120 466.851,-120 466.851,-120 466.851,-120 470.351,-120 466.851,-116.85 473.851,-120 473.851,-120\"/>\n",
"<text text-anchor=\"start\" x=\"419\" y=\"-123.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;7 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>7&#45;&gt;7</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M482.767,-135.541C480.169,-145.909 483.246,-156 492,-156 498.702,-156 502.077,-150.085 502.124,-142.659\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"501.233,-135.541 505.229,-142.095 501.668,-139.014 502.103,-142.487 502.103,-142.487 502.103,-142.487 501.668,-139.014 498.977,-142.879 501.233,-135.541 501.233,-135.541\"/>\n",
"<text text-anchor=\"start\" x=\"488.5\" y=\"-174.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"484\" y=\"-159.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;6 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>6&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M373.767,-33.5414C371.169,-43.9087 374.246,-54 383,-54 389.702,-54 393.077,-48.0847 393.124,-40.6591\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"392.233,-33.5414 396.229,-40.0955 392.668,-37.0143 393.103,-40.4871 393.103,-40.4871 393.103,-40.4871 392.668,-37.0143 389.977,-40.8788 392.233,-33.5414 392.233,-33.5414\"/>\n",
"<text text-anchor=\"start\" x=\"376.5\" y=\"-72.8\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n",
"<text text-anchor=\"start\" x=\"375\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce2e900> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"spot.highlight_stutter_invariant_states(pos, f, 5)\n",
"display(pos)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Such a procedure gives us map of where POR can be enabled when model checking using such an automaton."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Second example"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This second example illustrates the fact that a state can be marked if it it not sutter-invariant but appear below a stutter-invariant state. We build our example automaton as the disjuction of the following two stutter-sensitive formulas, whose union is equivalent to the sutter-invariant formula `GF!a`."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"g1 = spot.formula('GF(a & Xa) & GF!a')\n",
"g2 = spot.formula('!GF(a & Xa) & GF!a')\n",
"g = spot.formula_Or([g1, g2])"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"False\n",
"False\n",
"True\n"
]
}
],
"source": [
"print(spot.is_stutter_invariant(g1))\n",
"print(spot.is_stutter_invariant(g2))\n",
"print(spot.is_stutter_invariant(g))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here are the automata for `g1` and `g2`, note that none of the states are stutter-invariant."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"170pt\" height=\"178pt\"\n",
" viewBox=\"0.00 0.00 170.00 177.75\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 173.75)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-173.75 166,-173.75 166,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"25\" y=\"-155.55\" font-family=\"Lato\" font-size=\"14.00\">G(F(a &amp; Xa) &amp; F!a)</text>\n",
"<text text-anchor=\"start\" x=\"34\" y=\"-141.55\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"56\" y=\"-141.55\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"72\" y=\"-141.55\" font-family=\"Lato\" font-size=\"14.00\">)&amp;Inf(</text>\n",
"<text text-anchor=\"start\" x=\"108\" y=\"-141.55\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"<text text-anchor=\"start\" x=\"124\" y=\"-141.55\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"37\" y=\"-127.55\" font-family=\"Lato\" font-size=\"14.00\">[gen. Büchi 2]</text>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-20.7502\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-17.0502\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-20.7502C2.79388,-20.7502 17.1543,-20.7502 30.6317,-20.7502\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-20.7502 30.9419,-23.9003 34.4419,-20.7502 30.9419,-20.7503 30.9419,-20.7503 30.9419,-20.7503 34.4419,-20.7502 30.9418,-17.6003 37.9419,-20.7502 37.9419,-20.7502\"/>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M52.7643,-38.5319C52.2144,-48.0651 53.293,-56.7502 56,-56.7502 57.988,-56.7502 59.0977,-52.0663 59.3292,-45.8023\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"59.2357,-38.5319 62.4756,-45.4908 59.2808,-42.0316 59.3258,-45.5313 59.3258,-45.5313 59.3258,-45.5313 59.2808,-42.0316 56.1761,-45.5719 59.2357,-38.5319 59.2357,-38.5319\"/>\n",
"<text text-anchor=\"start\" x=\"50.5\" y=\"-75.5502\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"48\" y=\"-60.5502\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M50.9906,-38.3273C47.5451,-59.4682 49.2148,-86.7502 56,-86.7502 62.043,-86.7502 64.0285,-65.1097 61.9564,-45.4408\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"61.0094,-38.3273 65.0556,-44.8504 61.4713,-41.7967 61.9332,-45.2661 61.9332,-45.2661 61.9332,-45.2661 61.4713,-41.7967 58.8107,-45.6818 61.0094,-38.3273 61.0094,-38.3273\"/>\n",
"<text text-anchor=\"start\" x=\"52.5\" y=\"-90.5502\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"144\" cy=\"-20.7502\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"144\" y=\"-17.0502\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.4034,-20.7502C87.1928,-20.7502 104.732,-20.7502 118.874,-20.7502\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"125.916,-20.7502 118.916,-23.9003 122.416,-20.7502 118.916,-20.7503 118.916,-20.7503 118.916,-20.7503 122.416,-20.7502 118.916,-17.6003 125.916,-20.7502 125.916,-20.7502\"/>\n",
"<text text-anchor=\"start\" x=\"96.5\" y=\"-39.5502\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-24.5502\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;0 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M128.689,-10.8844C122.598,-7.25669 115.237,-3.58794 108,-1.75016 101.108,-0 98.8924,-0 92,-1.75016 87.1374,-2.98492 82.2193,-5.0462 77.668,-7.36626\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"71.3113,-10.8844 75.9105,-4.73864 74.3736,-9.18956 77.4359,-7.49469 77.4359,-7.49469 77.4359,-7.49469 74.3736,-9.18956 78.9613,-10.2507 71.3113,-10.8844 71.3113,-10.8844\"/>\n",
"<text text-anchor=\"start\" x=\"96.5\" y=\"-5.55016\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M136.332,-37.0404C134.483,-47.1393 137.039,-56.7502 144,-56.7502 149.221,-56.7502 151.964,-51.3441 152.229,-44.3805\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"151.668,-37.0404 155.342,-43.7801 151.935,-40.5303 152.201,-44.0201 152.201,-44.0201 152.201,-44.0201 151.935,-40.5303 149.06,-44.2601 151.668,-37.0404 151.668,-37.0404\"/>\n",
"<text text-anchor=\"start\" x=\"140.5\" y=\"-75.5502\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"136\" y=\"-60.5502\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce2e8d0> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"253pt\" height=\"172pt\"\n",
" viewBox=\"0.00 0.00 253.00 172.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 168)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-168 249,-168 249,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"88.5\" y=\"-149.8\" font-family=\"Lato\" font-size=\"14.00\">FG(!a | X!a)</text>\n",
"<text text-anchor=\"start\" x=\"101.5\" y=\"-135.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"123.5\" y=\"-135.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"139.5\" y=\"-135.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"99.5\" y=\"-121.8\" font-family=\"Lato\" font-size=\"14.00\">[Büchi]</text>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-18C2.79388,-18 17.1543,-18 30.6317,-18\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-18 30.9419,-21.1501 34.4419,-18 30.9419,-18.0001 30.9419,-18.0001 30.9419,-18.0001 34.4419,-18 30.9418,-14.8501 37.9419,-18 37.9419,-18\"/>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-35.0373C48.3189,-44.8579 50.4453,-54 56,-54 60.166,-54 62.4036,-48.8576 62.7128,-42.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-35.0373 65.8541,-41.8818 62.5434,-38.5335 62.7076,-42.0296 62.7076,-42.0296 62.7076,-42.0296 62.5434,-38.5335 59.561,-42.1774 62.3792,-35.0373 62.3792,-35.0373\"/>\n",
"<text text-anchor=\"start\" x=\"51.5\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"139\" cy=\"-48\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"start\" x=\"134.5\" y=\"-44.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.003,-23.927C85.017,-28.3767 101.638,-34.5325 115.064,-39.5053\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"121.753,-41.9826 114.095,-42.5052 118.471,-40.767 115.189,-39.5513 115.189,-39.5513 115.189,-39.5513 118.471,-40.767 116.283,-36.5974 121.753,-41.9826 121.753,-41.9826\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-37.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node4\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"227\" cy=\"-30\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"227\" y=\"-26.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;2 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.3505,-13.1706C93.2093,-7.96467 127.69,-1.04806 157,-6 173.081,-8.71684 190.415,-14.7595 203.687,-20.1014\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"210.229,-22.8097 202.557,-23.0425 206.995,-21.4709 203.762,-20.1321 203.762,-20.1321 203.762,-20.1321 206.995,-21.4709 204.966,-17.2216 210.229,-22.8097 210.229,-22.8097\"/>\n",
"<text text-anchor=\"start\" x=\"135.5\" y=\"-9.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M131.969,-64.6641C130.406,-74.625 132.75,-84 139,-84 143.688,-84 146.178,-78.7266 146.471,-71.8876\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"146.031,-64.6641 149.601,-71.4598 146.244,-68.1576 146.456,-71.6511 146.456,-71.6511 146.456,-71.6511 146.244,-68.1576 143.312,-71.8425 146.031,-64.6641 146.031,-64.6641\"/>\n",
"<text text-anchor=\"start\" x=\"133.5\" y=\"-102.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"131\" y=\"-87.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;2 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>1&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M155.003,-56.5894C165.311,-61.3438 179.21,-65.4707 191,-61 197.945,-58.3667 204.396,-53.6555 209.82,-48.6883\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"214.881,-43.7031 212.105,-50.8594 212.388,-46.1591 209.894,-48.6152 209.894,-48.6152 209.894,-48.6152 212.388,-46.1591 207.684,-46.3709 214.881,-43.7031 214.881,-43.7031\"/>\n",
"<text text-anchor=\"start\" x=\"179.5\" y=\"-80.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"175\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;1 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M209.173,-26.2984C199.09,-24.7439 186.112,-23.9222 175,-27 169.835,-28.4305 164.668,-30.8484 159.95,-33.5456\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"153.837,-37.33 158.131,-30.967 156.813,-35.4876 159.789,-33.6452 159.789,-33.6452 159.789,-33.6452 156.813,-35.4876 161.447,-36.3235 153.837,-37.33 153.837,-37.33\"/>\n",
"<text text-anchor=\"start\" x=\"177.5\" y=\"-45.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"175\" y=\"-30.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce61d50> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"aut1 = spot.translate(g1)\n",
"aut1.set_name(str(g1))\n",
"spot.highlight_stutter_invariant_states(aut1, g1, 5)\n",
"display(aut1)\n",
"\n",
"aut2 = spot.translate(g2)\n",
"aut2.set_name(str(g2))\n",
"spot.highlight_stutter_invariant_states(aut2, g2, 5)\n",
"display(aut2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we build the sum of these two automata. The stutter-invariance check detects that the initial state is stutter-invariant (i.e., the entire language is stutter-invariant) so all states below it are marked despite the fact that the language recognized from these individual states would not be stutter-invariant."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"338pt\" height=\"360pt\"\n",
" viewBox=\"0.00 0.00 337.93 360.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(0.996858 0.996858) rotate(0) translate(4 357.135)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-357.135 335,-357.135 335,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"89\" y=\"-338.935\" font-family=\"Lato\" font-size=\"14.00\">(Inf(</text>\n",
"<text text-anchor=\"start\" x=\"114\" y=\"-338.935\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"130\" y=\"-338.935\" font-family=\"Lato\" font-size=\"14.00\">)&amp;Inf(</text>\n",
"<text text-anchor=\"start\" x=\"166\" y=\"-338.935\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"<text text-anchor=\"start\" x=\"182\" y=\"-338.935\" font-family=\"Lato\" font-size=\"14.00\">)) | Inf(</text>\n",
"<text text-anchor=\"start\" x=\"222\" y=\"-338.935\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff7f00\">❷</text>\n",
"<text text-anchor=\"start\" x=\"238\" y=\"-338.935\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"130.5\" y=\"-324.935\" font-family=\"Lato\" font-size=\"14.00\">[Fin&#45;less 3]</text>\n",
"<!-- I -->\n",
"<!-- 5 -->\n",
"<g id=\"node2\" class=\"node\"><title>5</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"56\" cy=\"-80.1347\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-76.4347\" font-family=\"Lato\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- I&#45;&gt;5 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-80.1347C2.79388,-80.1347 17.1543,-80.1347 30.6317,-80.1347\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-80.1347 30.9419,-83.2848 34.4419,-80.1348 30.9419,-80.1348 30.9419,-80.1348 30.9419,-80.1348 34.4419,-80.1348 30.9418,-76.9848 37.9419,-80.1347 37.9419,-80.1347\"/>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"137\" cy=\"-218.135\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"137\" y=\"-214.435\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;0 -->\n",
"<g id=\"edge16\" class=\"edge\"><title>5&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M60.142,-97.8716C64.552,-119.133 74.1191,-155.143 92,-181.135 98.1307,-190.046 106.956,-198.044 115.096,-204.304\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"121.131,-208.738 113.625,-207.132 118.311,-206.666 115.49,-204.593 115.49,-204.593 115.49,-204.593 118.311,-206.666 117.356,-202.055 121.131,-208.738 121.131,-208.738\"/>\n",
"<text text-anchor=\"middle\" x=\"96.5\" y=\"-193.935\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node4\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"225\" cy=\"-200.135\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"225\" y=\"-196.435\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;1 -->\n",
"<g id=\"edge14\" class=\"edge\"><title>5&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M68.9809,-93.5334C80.8933,-106.399 100.075,-125.924 119,-140.135 145.779,-160.243 179.948,-178.586 201.904,-189.557\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"208.304,-192.719 200.633,-192.442 205.166,-191.169 202.028,-189.618 202.028,-189.618 202.028,-189.618 205.166,-191.169 203.423,-186.794 208.304,-192.719 208.304,-192.719\"/>\n",
"<text text-anchor=\"start\" x=\"133.5\" y=\"-166.935\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node5\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"137\" cy=\"-80.1347\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"137\" y=\"-76.4347\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;2 -->\n",
"<g id=\"edge17\" class=\"edge\"><title>5&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.1418,-80.1347C85.1153,-80.1347 99.5214,-80.1347 111.67,-80.1347\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.892,-80.1347 111.892,-83.2848 115.392,-80.1348 111.892,-80.1348 111.892,-80.1348 111.892,-80.1348 115.392,-80.1348 111.892,-76.9848 118.892,-80.1347 118.892,-80.1347\"/>\n",
"<text text-anchor=\"middle\" x=\"96.5\" y=\"-83.9347\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node6\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"225\" cy=\"-29.1347\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"225\" y=\"-25.4347\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;3 -->\n",
"<g id=\"edge13\" class=\"edge\"><title>5&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M70.1607,-68.239C82.0078,-58.3029 100.373,-44.7335 119,-38.1347 145.38,-28.7895 177.723,-27.3989 199.484,-27.7934\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"206.713,-27.9973 199.627,-30.9486 203.215,-27.8986 199.716,-27.7999 199.716,-27.7999 199.716,-27.7999 203.215,-27.8986 199.805,-24.6511 206.713,-27.9973 206.713,-27.9973\"/>\n",
"<text text-anchor=\"start\" x=\"131.5\" y=\"-41.9347\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node7\" class=\"node\"><title>4</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"313\" cy=\"-48.1347\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"313\" y=\"-44.4347\" font-family=\"Lato\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;4 -->\n",
"<g id=\"edge15\" class=\"edge\"><title>5&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M68.1907,-66.2828C74.6999,-58.6833 83.3143,-49.3648 92,-42.1347 133.591,-7.51392 153.092,-6.85489 207,-2.13474 238.606,0.632674 250.214,0.869389 277,-16.1347 283.36,-20.1723 289.645,-25.4116 295.096,-30.4779\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"300.241,-35.4355 293.014,-32.8465 297.72,-33.0069 295.2,-30.5783 295.2,-30.5783 295.2,-30.5783 297.72,-33.0069 297.386,-28.31 300.241,-35.4355 300.241,-35.4355\"/>\n",
"<text text-anchor=\"start\" x=\"177.5\" y=\"-8.93474\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M133.405,-235.916C132.794,-245.45 133.992,-254.135 137,-254.135 139.209,-254.135 140.442,-249.451 140.699,-243.187\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"140.595,-235.916 143.845,-242.871 140.645,-239.416 140.695,-242.916 140.695,-242.916 140.695,-242.916 140.645,-239.416 137.546,-242.961 140.595,-235.916 140.595,-235.916\"/>\n",
"<text text-anchor=\"start\" x=\"131.5\" y=\"-272.935\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"129\" y=\"-257.935\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M131.494,-235.384C127.587,-256.569 129.422,-284.135 137,-284.135 143.749,-284.135 145.943,-262.269 143.582,-242.52\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"142.506,-235.384 146.665,-241.836 143.028,-238.845 143.55,-242.306 143.55,-242.306 143.55,-242.306 143.028,-238.845 140.435,-242.775 142.506,-235.384 142.506,-235.384\"/>\n",
"<text text-anchor=\"start\" x=\"133.5\" y=\"-287.935\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M152.796,-209.188C158.84,-206.01 166.038,-202.808 173,-201.135 181.525,-199.086 191.083,-198.472 199.601,-198.49\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"206.766,-198.648 199.698,-201.643 203.267,-198.571 199.768,-198.493 199.768,-198.493 199.768,-198.493 203.267,-198.571 199.837,-195.344 206.766,-198.648 206.766,-198.648\"/>\n",
"<text text-anchor=\"start\" x=\"177.5\" y=\"-219.935\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"173\" y=\"-204.935\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;0 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M212.881,-213.838C206.643,-220.419 198.26,-227.624 189,-231.135 179.605,-234.697 168.87,-232.8 159.681,-229.477\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"153.003,-226.724 160.675,-226.48 156.239,-228.058 159.475,-229.392 159.475,-229.392 159.475,-229.392 156.239,-228.058 158.274,-232.304 153.003,-226.724 153.003,-226.724\"/>\n",
"<text text-anchor=\"start\" x=\"177.5\" y=\"-235.935\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M217.332,-216.425C215.483,-226.524 218.039,-236.135 225,-236.135 230.221,-236.135 232.964,-230.729 233.229,-223.765\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"232.668,-216.425 236.342,-223.165 232.935,-219.915 233.201,-223.405 233.201,-223.405 233.201,-223.405 232.935,-219.915 230.06,-223.645 232.668,-216.425 232.668,-216.425\"/>\n",
"<text text-anchor=\"start\" x=\"221.5\" y=\"-254.935\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"217\" y=\"-239.935\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M129.969,-96.7988C128.406,-106.76 130.75,-116.135 137,-116.135 141.688,-116.135 144.178,-110.861 144.471,-104.022\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"144.031,-96.7988 147.601,-103.595 144.244,-100.292 144.456,-103.786 144.456,-103.786 144.456,-103.786 144.244,-100.292 141.312,-103.977 144.031,-96.7988 144.031,-96.7988\"/>\n",
"<text text-anchor=\"middle\" x=\"137\" y=\"-119.935\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>2&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M152.98,-71.2512C166.792,-63.0606 187.435,-50.8189 202.91,-41.6413\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"209.192,-37.9165 204.777,-44.1965 206.181,-39.7017 203.171,-41.487 203.171,-41.487 203.171,-41.487 206.181,-39.7017 201.564,-38.7776 209.192,-37.9165 209.192,-37.9165\"/>\n",
"<text text-anchor=\"start\" x=\"175.5\" y=\"-62.9347\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;4 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>2&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M153.267,-87.8495C173.671,-97.1907 210.98,-110.884 243,-104.135 259.161,-100.728 263.751,-98.9961 277,-89.1347 284.625,-83.4596 291.709,-75.8342 297.48,-68.6994\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"302.003,-62.8751 300.198,-70.3359 299.856,-65.6395 297.71,-68.4039 297.71,-68.4039 297.71,-68.4039 299.856,-65.6395 295.222,-66.4719 302.003,-62.8751 302.003,-62.8751\"/>\n",
"<text text-anchor=\"start\" x=\"221.5\" y=\"-108.935\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M217.332,-45.425C215.483,-55.5239 218.039,-65.1347 225,-65.1347 230.221,-65.1347 232.964,-59.7286 233.229,-52.7651\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"232.668,-45.425 236.342,-52.1647 232.935,-48.9148 233.201,-52.4047 233.201,-52.4047 233.201,-52.4047 232.935,-48.9148 230.06,-52.6447 232.668,-45.425 232.668,-45.425\"/>\n",
"<text text-anchor=\"start\" x=\"219.5\" y=\"-83.9347\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"217\" y=\"-68.9347\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff7f00\">❷</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>3&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M242.417,-23.7475C252.584,-21.2508 265.793,-19.5434 277,-23.1347 282.929,-25.0347 288.708,-28.3489 293.807,-31.9545\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"299.447,-36.2538 291.971,-34.5156 296.664,-34.1321 293.88,-32.0104 293.88,-32.0104 293.88,-32.0104 296.664,-34.1321 295.79,-29.5051 299.447,-36.2538 299.447,-36.2538\"/>\n",
"<text text-anchor=\"start\" x=\"265.5\" y=\"-41.9347\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"261\" y=\"-26.9347\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff7f00\">❷</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;3 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>4&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M295.59,-52.9645C285.426,-55.1732 272.217,-56.6112 261,-53.1347 255.359,-51.3865 249.819,-48.3801 244.87,-45.0748\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"238.954,-40.8006 246.473,-42.3468 241.791,-42.8503 244.628,-44.9001 244.628,-44.9001 244.628,-44.9001 241.791,-42.8503 242.784,-47.4534 238.954,-40.8006 238.954,-40.8006\"/>\n",
"<text text-anchor=\"start\" x=\"263.5\" y=\"-73.9347\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"261\" y=\"-58.9347\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff7f00\">❷</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce2ea50> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"HOA: v1\n",
"States: 6\n",
"Start: 5\n",
"AP: 1 \"a\"\n",
"Acceptance: 3 (Inf(0)&Inf(1)) | Inf(2)\n",
"properties: trans-labels explicit-labels trans-acc stutter-invariant\n",
"--BODY--\n",
"State: 0\n",
"[!0] 0 {1}\n",
"[0] 0\n",
"[0] 1 {0}\n",
"State: 1\n",
"[0] 0\n",
"[0] 1 {0}\n",
"State: 2\n",
"[t] 2\n",
"[!0] 3\n",
"[0] 4\n",
"State: 3\n",
"[!0] 3 {2}\n",
"[0] 4 {2}\n",
"State: 4\n",
"[!0] 3 {2}\n",
"State: 5\n",
"[!0] 3\n",
"[0] 1\n",
"[0] 4\n",
"[t] 0\n",
"[t] 2\n",
"--END--\n"
]
}
],
"source": [
"aut = spot.sum(aut1, aut2)\n",
"# At this point it is unknown if AUT is stutter-invariant\n",
"assert(aut.prop_stutter_invariant().is_maybe())\n",
"spot.highlight_stutter_invariant_states(aut, g, 5)\n",
"display(aut)\n",
"# The stutter_invariant property is set on AUT as a side effect\n",
"# of calling sutter_invariant_states() or any variant of it.\n",
"assert(aut.prop_stutter_invariant().is_true())\n",
"\n",
"print(aut.to_str())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Third example\n",
"\n",
"These procedures work regardless of the acceptance condition. Here is an example with co-Büchi acceptance.\n",
"\n",
"In this case we do not even have a formula to pass as second argument, so the check will perform a complementation by determinization."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"349pt\" height=\"122pt\"\n",
" viewBox=\"0.00 0.00 348.74 121.87\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 117.87)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-117.87 344.74,-117.87 344.74,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"147.87\" y=\"-99.6701\" font-family=\"Lato\" font-size=\"14.00\">Fin(</text>\n",
"<text text-anchor=\"start\" x=\"172.87\" y=\"-99.6701\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"188.87\" y=\"-99.6701\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"137.87\" y=\"-85.6701\" font-family=\"Lato\" font-size=\"14.00\">[co&#45;Büchi]</text>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-26.8701\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-23.1701\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- I&#45;&gt;0 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-26.8701C2.79388,-26.8701 17.1543,-26.8701 30.6317,-26.8701\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-26.8701 30.9419,-30.0202 34.4419,-26.8701 30.9419,-26.8702 30.9419,-26.8702 30.9419,-26.8702 34.4419,-26.8701 30.9418,-23.7202 37.9419,-26.8701 37.9419,-26.8701\"/>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-43.9074C48.3189,-53.728 50.4453,-62.8701 56,-62.8701 60.166,-62.8701 62.4036,-57.7276 62.7128,-51.0134\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-43.9074 65.8541,-50.7519 62.5434,-47.4035 62.7076,-50.8997 62.7076,-50.8997 62.7076,-50.8997 62.5434,-47.4035 59.561,-51.0474 62.3792,-43.9074 62.3792,-43.9074\"/>\n",
"<text text-anchor=\"start\" x=\"52.5\" y=\"-66.6701\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node3\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"139\" cy=\"-26.8701\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"139\" y=\"-23.1701\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;2 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.178,-26.8701C85.6688,-26.8701 100.959,-26.8701 113.693,-26.8701\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"120.847,-26.8701 113.847,-30.0202 117.347,-26.8701 113.847,-26.8702 113.847,-26.8702 113.847,-26.8702 117.347,-26.8701 113.847,-23.7202 120.847,-26.8701 120.847,-26.8701\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-30.6701\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;0 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>2&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M124.262,-16.096C115.3,-10.3598 103.222,-5.02044 92,-7.87006 87.1374,-9.10482 82.2193,-11.1661 77.668,-13.4862\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"71.3113,-17.0043 75.9105,-10.8585 74.3736,-15.3095 77.4359,-13.6146 77.4359,-13.6146 77.4359,-13.6146 74.3736,-15.3095 78.9613,-16.3706 71.3113,-17.0043 71.3113,-17.0043\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-11.6701\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node5\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"222\" cy=\"-26.8701\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-23.1701\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>2&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M157.178,-26.8701C168.669,-26.8701 183.959,-26.8701 196.693,-26.8701\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"203.847,-26.8701 196.847,-30.0202 200.347,-26.8701 196.847,-26.8702 196.847,-26.8702 196.847,-26.8702 200.347,-26.8701 196.847,-23.7202 203.847,-26.8701 203.847,-26.8701\"/>\n",
"<text text-anchor=\"start\" x=\"175\" y=\"-30.6701\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node4\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"313.87\" cy=\"-26.8701\" rx=\"26.7407\" ry=\"26.7407\"/>\n",
"<text text-anchor=\"start\" x=\"309.37\" y=\"-30.6701\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"<text text-anchor=\"start\" x=\"305.87\" y=\"-15.6701\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;3 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M290.411,-13.5677C280.568,-9.28812 268.816,-6.2518 258,-8.87006 253.27,-10.015 248.463,-11.916 243.988,-14.0638\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"237.717,-17.3277 242.472,-11.3018 240.822,-15.7119 243.926,-14.096 243.926,-14.096 243.926,-14.096 240.822,-15.7119 245.38,-16.8903 237.717,-17.3277 237.717,-17.3277\"/>\n",
"<text text-anchor=\"start\" x=\"260\" y=\"-12.6701\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;1 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>3&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M240.328,-26.8701C251.431,-26.8701 266.206,-26.8701 279.524,-26.8701\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"286.74,-26.8701 279.74,-30.0202 283.24,-26.8701 279.74,-26.8702 279.74,-26.8702 279.74,-26.8702 283.24,-26.8701 279.74,-23.7202 286.74,-26.8701 286.74,-26.8701\"/>\n",
"<text text-anchor=\"start\" x=\"258\" y=\"-30.6701\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce2e960> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"aut = spot.automaton('randaut --seed=30 -Q4 -A\"Fin(0)\" a |')\n",
"spot.highlight_stutter_invariant_states(aut, None, 5)\n",
"display(aut)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the negated automaton is already known, it can be passed as second argument (instead of the positive formula) to avoid unnecessary work."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Sutter-invariance at the letter level\n",
"\n",
"Instead of marking each state as stuttering or not, we can list the letters that we can stutter in each state.\n",
"More precisely, a state $q$ is _stutter-invariant for letter $a$_ if the membership to $L(q)$ of any word starting with $a$ is preserved by the operations that duplicate letters or remove duplicates. \n",
"\n",
"$(\\ell_0\\ldots\\ell_{i-1}\\ell_i\\ell_{i+1}\\ldots\\in L(q) \\land \\ell_0=a) \\iff (\\ell_0\\ldots\\ell_{i-1}\\ell_i\\ell_i\\ell_{i+1}\\ldots\\in L(q)\\land \\ell_0=a)$\n",
"\n",
"Under this definition, we can also say that $q$ is _stutter-invariant_ iff it is _stutter-invariant for any letter_.\n",
"\n",
"For instance consider the following automaton, for which all words that start with $b$ are stutter invariant.\n",
"The initial state may not be declared as stutter-invariant because of words that start with $\\lnot b$."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"281pt\" height=\"227pt\"\n",
" viewBox=\"0.00 0.00 281.48 226.74\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 222.74)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-222.74 277.48,-222.74 277.48,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"115.74\" y=\"-204.54\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"137.74\" y=\"-204.54\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"153.74\" y=\"-204.54\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"113.74\" y=\"-190.54\" font-family=\"Lato\" font-size=\"14.00\">[Büchi]</text>\n",
"<!-- I -->\n",
"<!-- 3 -->\n",
"<g id=\"node2\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-81.8701\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-78.1701\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- I&#45;&gt;3 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-81.8701C2.79388,-81.8701 17.1543,-81.8701 30.6317,-81.8701\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-81.8701 30.9419,-85.0202 34.4419,-81.8701 30.9419,-81.8702 30.9419,-81.8702 30.9419,-81.8702 34.4419,-81.8701 30.9418,-78.7202 37.9419,-81.8701 37.9419,-81.8701\"/>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"149.87\" cy=\"-122.87\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"149.87\" y=\"-119.17\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;0 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>3&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.0025,-89.0117C87.7569,-95.5963 109.809,-105.438 126.341,-112.816\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"133.051,-115.81 125.375,-115.834 129.855,-114.384 126.659,-112.957 126.659,-112.957 126.659,-112.957 129.855,-114.384 127.942,-110.081 133.051,-115.81 133.051,-115.81\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-106.67\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node5\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"149.87\" cy=\"-26.8701\" rx=\"26.7407\" ry=\"26.7407\"/>\n",
"<text text-anchor=\"start\" x=\"145.37\" y=\"-30.6701\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"<text text-anchor=\"start\" x=\"141.87\" y=\"-15.6701\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;1 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>3&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M71.7605,-73.0334C84.7461,-65.2593 104.025,-53.7175 120.057,-44.1197\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"126.247,-40.4137 121.859,-46.7121 123.244,-42.2116 120.241,-44.0094 120.241,-44.0094 120.241,-44.0094 123.244,-42.2116 118.623,-41.3067 126.247,-40.4137 126.247,-40.4137\"/>\n",
"<text text-anchor=\"start\" x=\"94\" y=\"-65.6701\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node4\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"246.61\" cy=\"-122.87\" rx=\"26.7407\" ry=\"26.7407\"/>\n",
"<text text-anchor=\"start\" x=\"242.11\" y=\"-126.67\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"<text text-anchor=\"start\" x=\"238.61\" y=\"-111.67\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;2 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M168.247,-122.87C180.55,-122.87 197.439,-122.87 212.298,-122.87\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"219.401,-122.87 212.401,-126.02 215.901,-122.87 212.401,-122.87 212.401,-122.87 212.401,-122.87 215.901,-122.87 212.401,-119.72 219.401,-122.87 219.401,-122.87\"/>\n",
"<text text-anchor=\"start\" x=\"194.74\" y=\"-126.67\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M237.689,-148.24C237.074,-158.794 240.048,-167.74 246.61,-167.74 251.635,-167.74 254.555,-162.496 255.372,-155.301\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"255.531,-148.24 258.523,-155.309 255.452,-151.739 255.374,-155.238 255.374,-155.238 255.374,-155.238 255.452,-151.739 252.224,-155.167 255.531,-148.24 255.531,-148.24\"/>\n",
"<text text-anchor=\"middle\" x=\"246.61\" y=\"-171.54\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M140.949,-52.2401C140.334,-62.7939 143.308,-71.7401 149.87,-71.7401 154.894,-71.7401 157.815,-66.496 158.632,-59.3013\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"158.791,-52.2401 161.783,-59.3092 158.712,-55.7392 158.633,-59.2383 158.633,-59.2383 158.633,-59.2383 158.712,-55.7392 155.484,-59.1674 158.791,-52.2401 158.791,-52.2401\"/>\n",
"<text text-anchor=\"start\" x=\"145.37\" y=\"-75.5401\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79ce55e10> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"f = spot.formula('(!b&Xa) | Gb')\n",
"pos = spot.translate(f)\n",
"spot.highlight_stutter_invariant_states(pos, f, 5)\n",
"display(pos)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `stutter_invariant_letters()` functions returns a vector of BDDs indexed by state numbers. The BDD at index $q$ specifies all letters $\\ell$ for which state $q$ would be stuttering. Note that if $q$ is stutter-invariant or reachable from a stutter-invariant state, the associated BDD will be `bddtrue` (printed as `1` below).\n",
"\n",
"This interface is a bit inconveniant to use interactively, due to the fact that we need a `spot.bdd_dict` object to print a BDD."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"sil_vec[0] = 1\n",
"sil_vec[1] = 1\n",
"sil_vec[2] = 1\n",
"sil_vec[3] = b\n"
]
}
],
"source": [
"sil_vec = spot.stutter_invariant_letters(pos, f)\n",
"for q in range(pos.num_states()):\n",
" print(\"sil_vec[{}] =\".format(q), spot.bdd_format_formula(pos.get_dict(), sil_vec[q]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The set of stutter-invariant states is not always forward closed\n",
"\n",
"Consider the following automaton, which is a variant of our second example above. \n",
"\n",
"The language accepted from state (2) is `!GF(a & Xa) & GF!a` (this can be simplified to `FG(!a | X!a)`), while the language accepted from state (0) is `GF(a & Xa) & GF!a`. Therefore. the language accepted from state (5) is `a & X(GF!a)`. Since this is equivalent to `a & GF(!a)` state (5) recognizes stutter-invariant language, but as we can see, it is not the case that all states below (5) are also marked. In fact, states (0) can also be reached via states (7) and (6), recognizing respectively `(a & X(a & GF!a)) | (!a & X(!a & GF(a & Xa) & GF!a))` and `!a & GF(a & Xa) & GF!a))`, i.e., two stutter-sentive languages."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"440pt\" height=\"295pt\"\n",
" viewBox=\"0.00 0.00 440.00 295.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 291)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-291 436,-291 436,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"169\" y=\"-272.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"191\" y=\"-272.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"207\" y=\"-272.8\" font-family=\"Lato\" font-size=\"14.00\">)&amp;Inf(</text>\n",
"<text text-anchor=\"start\" x=\"243\" y=\"-272.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"<text text-anchor=\"start\" x=\"259\" y=\"-272.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"172\" y=\"-258.8\" font-family=\"Lato\" font-size=\"14.00\">[gen. Büchi 2]</text>\n",
"<!-- I -->\n",
"<!-- 7 -->\n",
"<g id=\"node2\" class=\"node\"><title>7</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-55\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-51.3\" font-family=\"Lato\" font-size=\"14.00\">7</text>\n",
"</g>\n",
"<!-- I&#45;&gt;7 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;7</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-55C2.79388,-55 17.1543,-55 30.6317,-55\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-55 30.9419,-58.1501 34.4419,-55 30.9419,-55.0001 30.9419,-55.0001 30.9419,-55.0001 34.4419,-55 30.9418,-51.8501 37.9419,-55 37.9419,-55\"/>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g id=\"node8\" class=\"node\"><title>5</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"139\" cy=\"-80\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"139\" y=\"-76.3\" font-family=\"Lato\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;5 -->\n",
"<g id=\"edge17\" class=\"edge\"><title>7&#45;&gt;5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.3916,-60.0591C85.2489,-63.7188 101.441,-68.7164 114.649,-72.7928\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"121.633,-74.9484 114.015,-75.8938 118.288,-73.9162 114.944,-72.8839 114.944,-72.8839 114.944,-72.8839 118.288,-73.9162 115.873,-69.874 121.633,-74.9484 121.633,-74.9484\"/>\n",
"<text text-anchor=\"start\" x=\"94\" y=\"-72.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g id=\"node9\" class=\"node\"><title>6</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"139\" cy=\"-26\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"139\" y=\"-22.3\" font-family=\"Lato\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;6 -->\n",
"<g id=\"edge16\" class=\"edge\"><title>7&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.3916,-49.1314C85.4374,-44.8187 101.957,-38.9043 115.276,-34.1356\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"121.909,-31.7609 116.381,-37.0861 118.614,-32.9407 115.319,-34.1205 115.319,-34.1205 115.319,-34.1205 118.614,-32.9407 114.257,-31.1548 121.909,-31.7609 121.909,-31.7609\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-46.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"222\" cy=\"-26\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-22.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M218.405,-43.7817C217.794,-53.3149 218.992,-62 222,-62 224.209,-62 225.442,-57.3161 225.699,-51.0521\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"225.595,-43.7817 228.845,-50.736 225.645,-47.2814 225.695,-50.781 225.695,-50.781 225.695,-50.781 225.645,-47.2814 222.546,-50.8261 225.595,-43.7817 225.595,-43.7817\"/>\n",
"<text text-anchor=\"start\" x=\"216.5\" y=\"-80.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"214\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M216.494,-43.249C212.587,-64.4346 214.422,-92 222,-92 228.749,-92 230.943,-70.1347 228.582,-50.3851\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"227.506,-43.249 231.665,-49.7011 228.028,-46.7099 228.55,-50.1708 228.55,-50.1708 228.55,-50.1708 228.028,-46.7099 225.435,-50.6405 227.506,-43.249 227.506,-43.249\"/>\n",
"<text text-anchor=\"start\" x=\"218.5\" y=\"-95.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node4\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"310\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"310\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M240.054,-26.953C249.988,-27.2707 262.738,-27.2707 274,-26 277.699,-25.5827 281.577,-24.9247 285.349,-24.1611\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"292.397,-22.5979 286.245,-27.1889 288.98,-23.3557 285.563,-24.1136 285.563,-24.1136 285.563,-24.1136 288.98,-23.3557 284.881,-21.0383 292.397,-22.5979 292.397,-22.5979\"/>\n",
"<text text-anchor=\"start\" x=\"262.5\" y=\"-46.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"258\" y=\"-31.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;0 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M293.307,-10.8511C283.186,-7.16666 269.764,-4.01278 258,-7 253.137,-8.23476 248.219,-10.296 243.668,-12.6161\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"237.311,-16.1343 241.91,-9.98848 240.374,-14.4394 243.436,-12.7445 243.436,-12.7445 243.436,-12.7445 240.374,-14.4394 244.961,-15.5006 237.311,-16.1343 237.311,-16.1343\"/>\n",
"<text text-anchor=\"start\" x=\"262.5\" y=\"-10.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M302.332,-34.2903C300.483,-44.3892 303.039,-54 310,-54 315.221,-54 317.964,-48.5939 318.229,-41.6304\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"317.668,-34.2903 321.342,-41.0299 317.935,-37.7801 318.201,-41.2699 318.201,-41.2699 318.201,-41.2699 317.935,-37.7801 315.06,-41.5099 317.668,-34.2903 317.668,-34.2903\"/>\n",
"<text text-anchor=\"start\" x=\"306.5\" y=\"-72.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"302\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node5\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"222\" cy=\"-161\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-157.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M214.969,-177.664C213.406,-187.625 215.75,-197 222,-197 226.688,-197 229.178,-191.727 229.471,-184.888\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"229.031,-177.664 232.601,-184.46 229.244,-181.158 229.456,-184.651 229.456,-184.651 229.456,-184.651 229.244,-181.158 226.312,-184.842 229.031,-177.664 229.031,-177.664\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-200.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node6\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"310\" cy=\"-187\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"310\" y=\"-183.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>2&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M239.582,-166.013C252.669,-169.97 271.086,-175.538 285.662,-179.944\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"292.469,-182.002 284.857,-182.992 289.119,-180.989 285.769,-179.977 285.769,-179.977 285.769,-179.977 289.119,-180.989 286.68,-176.961 292.469,-182.002 292.469,-182.002\"/>\n",
"<text text-anchor=\"start\" x=\"260.5\" y=\"-179.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node7\" class=\"node\"><title>4</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"414\" cy=\"-169\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"414\" y=\"-165.3\" font-family=\"Lato\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;4 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>2&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M239.545,-156.043C253.408,-152.161 273.796,-147.083 292,-145 307.896,-143.181 312.151,-142.805 328,-145 349.53,-147.981 373.278,-155.019 390.187,-160.708\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"396.988,-163.047 389.344,-163.749 393.678,-161.909 390.369,-160.77 390.369,-160.77 390.369,-160.77 393.678,-161.909 391.393,-157.791 396.988,-163.047 396.988,-163.047\"/>\n",
"<text text-anchor=\"start\" x=\"306.5\" y=\"-148.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M302.332,-203.29C300.483,-213.389 303.039,-223 310,-223 315.221,-223 317.964,-217.594 318.229,-210.63\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"317.668,-203.29 321.342,-210.03 317.935,-206.78 318.201,-210.27 318.201,-210.27 318.201,-210.27 317.935,-206.78 315.06,-210.51 317.668,-203.29 317.668,-203.29\"/>\n",
"<text text-anchor=\"start\" x=\"304.5\" y=\"-240.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"294\" y=\"-226.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"310\" y=\"-226.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>3&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M325.792,-178.037C331.836,-174.857 339.034,-171.657 346,-170 359.907,-166.692 375.901,-166.329 388.773,-166.846\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"395.952,-167.237 388.791,-170.002 392.458,-167.047 388.963,-166.857 388.963,-166.857 388.963,-166.857 392.458,-167.047 389.134,-163.711 395.952,-167.237 395.952,-167.237\"/>\n",
"<text text-anchor=\"start\" x=\"358.5\" y=\"-187.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"346\" y=\"-173.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"362\" y=\"-173.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;3 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>4&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M401.404,-182.139C395.156,-188.216 386.908,-194.789 378,-198 363.778,-203.126 346.99,-200.356 333.777,-196.314\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"326.843,-193.979 334.482,-193.227 330.16,-195.096 333.477,-196.213 333.477,-196.213 333.477,-196.213 330.16,-195.096 332.472,-199.198 326.843,-193.979 326.843,-193.979\"/>\n",
"<text text-anchor=\"start\" x=\"356.5\" y=\"-217.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"346\" y=\"-203.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"362\" y=\"-203.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;0 -->\n",
"<g id=\"edge13\" class=\"edge\"><title>5&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M154.481,-70.3459C167.382,-61.7455 186.39,-49.0731 200.788,-39.475\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"206.644,-35.5705 202.567,-42.0744 203.732,-37.512 200.82,-39.4535 200.82,-39.4535 200.82,-39.4535 203.732,-37.512 199.072,-36.8325 206.644,-35.5705 206.644,-35.5705\"/>\n",
"<text text-anchor=\"start\" x=\"177\" y=\"-60.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;2 -->\n",
"<g id=\"edge14\" class=\"edge\"><title>5&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M152.302,-92.3022C165.98,-105.98 188.177,-128.177 203.624,-143.624\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"208.582,-148.582 201.405,-145.86 206.107,-146.107 203.632,-143.632 203.632,-143.632 203.632,-143.632 206.107,-146.107 205.86,-141.405 208.582,-148.582 208.582,-148.582\"/>\n",
"<text text-anchor=\"start\" x=\"177\" y=\"-128.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;0 -->\n",
"<g id=\"edge15\" class=\"edge\"><title>6&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M157.178,-26C168.669,-26 183.959,-26 196.693,-26\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"203.847,-26 196.847,-29.1501 200.347,-26 196.847,-26.0001 196.847,-26.0001 196.847,-26.0001 200.347,-26 196.847,-22.8501 203.847,-26 203.847,-26\"/>\n",
"<text text-anchor=\"start\" x=\"175\" y=\"-29.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79cdf1ba0> >"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ex1 = spot.automaton(\"\"\"HOA: v1 \n",
"States: 8 Start: 7 AP: 1 \"a\" Acceptance: 2 (Inf(0)&Inf(1))\n",
"--BODY--\n",
"State: 0 [!0] 0 {1} [0] 0 [0] 1 {0}\n",
"State: 1 [0] 0 [0] 1 {0}\n",
"State: 2 [t] 2 [!0] 3 [0] 4\n",
"State: 3 [!0] 3 {0 1} [0] 4 {0 1}\n",
"State: 4 [!0] 3 {0 1}\n",
"State: 5 [0] 0 [0] 2\n",
"State: 6 [!0] 0\n",
"State: 7 [!0] 6 [0] 5\n",
"--END--\"\"\")\n",
"spot.highlight_stutter_invariant_states(ex1,None, 5)\n",
"display(ex1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This situation can be tested with `spot.is_stutter_invariant_forward_closed()`. The function returns `-1` if the successor of any stutter-invariant state is it is also a stutter-invariant state, otherwise it return the number of one stutter-sensitive state that has a stutter-invariant state as predecessor."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sistates = spot.stutter_invariant_states(ex1)\n",
"spot.is_stutter_invariant_forward_closed(ex1, sistates)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In cases where we prefer to have a forward-closed set of stutter-invariant states, it is always possible to duplicate\n",
"the problematic states. The `make_stutter_invariant_foward_closed_inplace()` modifies the automaton in place, and also returns an updated copie of the vector of stutter-invariant states."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: G Pages: 1 -->\n",
"<svg width=\"387pt\" height=\"360pt\"\n",
" viewBox=\"0.00 0.00 387.29 360.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(0.880196 0.880196) rotate(0) translate(4 405)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-405 436,-405 436,4 -4,4\"/>\n",
"<text text-anchor=\"start\" x=\"169\" y=\"-386.8\" font-family=\"Lato\" font-size=\"14.00\">Inf(</text>\n",
"<text text-anchor=\"start\" x=\"191\" y=\"-386.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"207\" y=\"-386.8\" font-family=\"Lato\" font-size=\"14.00\">)&amp;Inf(</text>\n",
"<text text-anchor=\"start\" x=\"243\" y=\"-386.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"<text text-anchor=\"start\" x=\"259\" y=\"-386.8\" font-family=\"Lato\" font-size=\"14.00\">)</text>\n",
"<text text-anchor=\"start\" x=\"172\" y=\"-372.8\" font-family=\"Lato\" font-size=\"14.00\">[gen. Büchi 2]</text>\n",
"<!-- I -->\n",
"<!-- 7 -->\n",
"<g id=\"node2\" class=\"node\"><title>7</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-120\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-116.3\" font-family=\"Lato\" font-size=\"14.00\">7</text>\n",
"</g>\n",
"<!-- I&#45;&gt;7 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;7</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-120C2.79388,-120 17.1543,-120 30.6317,-120\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-120 30.9419,-123.15 34.4419,-120 30.9419,-120 30.9419,-120 30.9419,-120 34.4419,-120 30.9418,-116.85 37.9419,-120 37.9419,-120\"/>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g id=\"node8\" class=\"node\"><title>5</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"139\" cy=\"-153\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"139\" y=\"-149.3\" font-family=\"Lato\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;5 -->\n",
"<g id=\"edge17\" class=\"edge\"><title>7&#45;&gt;5</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M73.003,-126.52C85.0955,-131.446 101.855,-138.274 115.327,-143.763\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"122.03,-146.494 114.359,-146.77 118.789,-145.173 115.548,-143.853 115.548,-143.853 115.548,-143.853 118.789,-145.173 116.736,-140.935 122.03,-146.494 122.03,-146.494\"/>\n",
"<text text-anchor=\"start\" x=\"94\" y=\"-142.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g id=\"node10\" class=\"node\"><title>6</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"139\" cy=\"-79\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"139\" y=\"-75.3\" font-family=\"Lato\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;6 -->\n",
"<g id=\"edge16\" class=\"edge\"><title>7&#45;&gt;6</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M72.6176,-112.095C85.0229,-105.816 102.513,-96.9624 116.283,-89.9926\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"122.705,-86.7419 117.882,-92.7137 119.582,-88.3226 116.46,-89.9033 116.46,-89.9033 116.46,-89.9033 119.582,-88.3226 115.037,-87.0928 122.705,-86.7419 122.705,-86.7419\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-105.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"222\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M218.405,-35.7817C217.794,-45.3149 218.992,-54 222,-54 224.209,-54 225.442,-49.3161 225.699,-43.0521\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"225.595,-35.7817 228.845,-42.736 225.645,-39.2814 225.695,-42.781 225.695,-42.781 225.695,-42.781 225.645,-39.2814 222.546,-42.8261 225.595,-35.7817 225.595,-35.7817\"/>\n",
"<text text-anchor=\"start\" x=\"216.5\" y=\"-72.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"214\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;0 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>0&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M216.494,-35.249C212.587,-56.4346 214.422,-84 222,-84 228.749,-84 230.943,-62.1347 228.582,-42.3851\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"227.506,-35.249 231.665,-41.7011 228.028,-38.7099 228.55,-42.1708 228.55,-42.1708 228.55,-42.1708 228.028,-38.7099 225.435,-42.6405 227.506,-35.249 227.506,-35.249\"/>\n",
"<text text-anchor=\"start\" x=\"218.5\" y=\"-87.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node4\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"310\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"310\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>0&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M239.137,-24.1997C244.986,-26.1442 251.704,-28.034 258,-29 266.972,-30.3767 276.852,-29.5592 285.508,-28.072\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"292.444,-26.6986 286.189,-31.1484 289.01,-27.3785 285.577,-28.0584 285.577,-28.0584 285.577,-28.0584 289.01,-27.3785 284.965,-24.9683 292.444,-26.6986 292.444,-26.6986\"/>\n",
"<text text-anchor=\"start\" x=\"262.5\" y=\"-48.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"258\" y=\"-33.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;0 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>1&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M293.258,-15.3664C287.332,-13.201 280.463,-11.0772 274,-10 265.021,-8.50356 255.14,-9.45363 246.485,-11.1445\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"239.55,-12.7017 245.69,-8.09454 242.965,-11.9349 246.38,-11.168 246.38,-11.168 246.38,-11.168 242.965,-11.9349 247.07,-14.2415 239.55,-12.7017 239.55,-12.7017\"/>\n",
"<text text-anchor=\"start\" x=\"262.5\" y=\"-13.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M302.332,-38.2903C300.483,-48.3892 303.039,-58 310,-58 315.221,-58 317.964,-52.5939 318.229,-45.6304\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"317.668,-38.2903 321.342,-45.0299 317.935,-41.7801 318.201,-45.2699 318.201,-45.2699 318.201,-45.2699 317.935,-41.7801 315.06,-45.5099 317.668,-38.2903 317.668,-38.2903\"/>\n",
"<text text-anchor=\"start\" x=\"306.5\" y=\"-76.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"302\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node5\" class=\"node\"><title>2</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"222\" cy=\"-288\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-284.3\" font-family=\"Lato\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;2 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>2&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M214.969,-304.664C213.406,-314.625 215.75,-324 222,-324 226.688,-324 229.178,-318.727 229.471,-311.888\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"229.031,-304.664 232.601,-311.46 229.244,-308.158 229.456,-311.651 229.456,-311.651 229.456,-311.651 229.244,-308.158 226.312,-311.842 229.031,-304.664 229.031,-304.664\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-327.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node6\" class=\"node\"><title>3</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"310\" cy=\"-301\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"310\" y=\"-297.3\" font-family=\"Lato\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>2&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M239.991,-290.568C252.83,-292.509 270.624,-295.199 284.928,-297.361\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"292.044,-298.437 284.652,-300.505 288.584,-297.914 285.123,-297.391 285.123,-297.391 285.123,-297.391 288.584,-297.914 285.594,-294.276 292.044,-298.437 292.044,-298.437\"/>\n",
"<text text-anchor=\"start\" x=\"260.5\" y=\"-298.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node7\" class=\"node\"><title>4</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"414\" cy=\"-283\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"414\" y=\"-279.3\" font-family=\"Lato\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;4 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>2&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M238.056,-279.602C251.671,-272.52 272.511,-262.929 292,-259 326.394,-252.066 366.321,-263.836 390.614,-273.21\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"397.331,-275.896 389.661,-276.222 394.081,-274.596 390.831,-273.297 390.831,-273.297 390.831,-273.297 394.081,-274.596 392,-270.372 397.331,-275.896 397.331,-275.896\"/>\n",
"<text text-anchor=\"start\" x=\"306.5\" y=\"-262.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>3&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M302.332,-317.29C300.483,-327.389 303.039,-337 310,-337 315.221,-337 317.964,-331.594 318.229,-324.63\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"317.668,-317.29 321.342,-324.03 317.935,-320.78 318.201,-324.27 318.201,-324.27 318.201,-324.27 317.935,-320.78 315.06,-324.51 317.668,-317.29 317.668,-317.29\"/>\n",
"<text text-anchor=\"start\" x=\"304.5\" y=\"-354.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"294\" y=\"-340.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"310\" y=\"-340.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>3&#45;&gt;4</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M326.843,-307.979C340.685,-313.059 361.144,-318.076 378,-312 384.542,-309.642 390.728,-305.471 396.027,-301.014\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"401.404,-296.139 398.334,-303.174 398.811,-298.49 396.218,-300.841 396.218,-300.841 396.218,-300.841 398.811,-298.49 394.102,-298.507 401.404,-296.139 401.404,-296.139\"/>\n",
"<text text-anchor=\"start\" x=\"358.5\" y=\"-331.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"346\" y=\"-317.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"362\" y=\"-317.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;3 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>4&#45;&gt;3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M396.155,-279.393C382.406,-277.121 362.607,-275.4 346,-280 340.835,-281.43 335.668,-283.848 330.95,-286.546\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"324.837,-290.33 329.131,-283.967 327.813,-288.488 330.789,-286.645 330.789,-286.645 330.789,-286.645 327.813,-288.488 332.447,-289.323 324.837,-290.33 324.837,-290.33\"/>\n",
"<text text-anchor=\"start\" x=\"356.5\" y=\"-297.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"346\" y=\"-283.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"<text text-anchor=\"start\" x=\"362\" y=\"-283.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;2 -->\n",
"<g id=\"edge14\" class=\"edge\"><title>5&#45;&gt;2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M148.985,-168.459C161.251,-189.495 184.001,-228.267 204,-261 205.213,-262.985 206.485,-265.046 207.765,-267.104\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"211.575,-273.19 205.191,-268.928 209.718,-270.224 207.861,-267.257 207.861,-267.257 207.861,-267.257 209.718,-270.224 210.531,-265.586 211.575,-273.19 211.575,-273.19\"/>\n",
"<text text-anchor=\"start\" x=\"177\" y=\"-231.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 8 -->\n",
"<g id=\"node9\" class=\"node\"><title>8</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"222\" cy=\"-153\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"222\" y=\"-149.3\" font-family=\"Lato\" font-size=\"14.00\">8</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;8 -->\n",
"<g id=\"edge13\" class=\"edge\"><title>5&#45;&gt;8</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M157.178,-153C168.669,-153 183.959,-153 196.693,-153\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"203.847,-153 196.847,-156.15 200.347,-153 196.847,-153 196.847,-153 196.847,-153 200.347,-153 196.847,-149.85 203.847,-153 203.847,-153\"/>\n",
"<text text-anchor=\"start\" x=\"177\" y=\"-156.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;8 -->\n",
"<g id=\"edge18\" class=\"edge\"><title>8&#45;&gt;8</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M218.405,-170.782C217.794,-180.315 218.992,-189 222,-189 224.209,-189 225.442,-184.316 225.699,-178.052\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"225.595,-170.782 228.845,-177.736 225.645,-174.281 225.695,-177.781 225.695,-177.781 225.695,-177.781 225.645,-174.281 222.546,-177.826 225.595,-170.782 225.595,-170.782\"/>\n",
"<text text-anchor=\"start\" x=\"216.5\" y=\"-207.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"<text text-anchor=\"start\" x=\"214\" y=\"-192.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#ff4da0\">❶</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;8 -->\n",
"<g id=\"edge19\" class=\"edge\"><title>8&#45;&gt;8</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M216.494,-170.249C212.587,-191.435 214.422,-219 222,-219 228.749,-219 230.943,-197.135 228.582,-177.385\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"227.506,-170.249 231.665,-176.701 228.028,-173.71 228.55,-177.171 228.55,-177.171 228.55,-177.171 228.028,-173.71 225.435,-177.64 227.506,-170.249 227.506,-170.249\"/>\n",
"<text text-anchor=\"start\" x=\"218.5\" y=\"-222.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 9 -->\n",
"<g id=\"node11\" class=\"node\"><title>9</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"#e31a1c\" stroke-width=\"2\" cx=\"310\" cy=\"-140\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"310\" y=\"-136.3\" font-family=\"Lato\" font-size=\"14.00\">9</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;9 -->\n",
"<g id=\"edge20\" class=\"edge\"><title>8&#45;&gt;9</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M240.047,-151.34C249.979,-150.287 262.729,-148.787 274,-147 277.655,-146.42 281.509,-145.73 285.271,-145.013\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"292.314,-143.621 286.058,-148.068 288.881,-144.3 285.447,-144.978 285.447,-144.978 285.447,-144.978 288.881,-144.3 284.837,-141.888 292.314,-143.621 292.314,-143.621\"/>\n",
"<text text-anchor=\"start\" x=\"262.5\" y=\"-168.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"258\" y=\"-153.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;0 -->\n",
"<g id=\"edge15\" class=\"edge\"><title>6&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M153.741,-68.6522C166.774,-58.8372 186.499,-43.9826 201.222,-32.8944\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"207.192,-28.3986 203.495,-35.1259 204.396,-30.5041 201.6,-32.6097 201.6,-32.6097 201.6,-32.6097 204.396,-30.5041 199.705,-30.0934 207.192,-28.3986 207.192,-28.3986\"/>\n",
"<text text-anchor=\"start\" x=\"175\" y=\"-56.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"<!-- 9&#45;&gt;8 -->\n",
"<g id=\"edge21\" class=\"edge\"><title>9&#45;&gt;8</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M293.653,-132.073C283.438,-127.847 269.78,-124.225 258,-128 252.071,-129.9 246.292,-133.214 241.193,-136.82\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"235.553,-141.119 239.21,-134.37 238.336,-138.997 241.12,-136.876 241.12,-136.876 241.12,-136.876 238.336,-138.997 243.029,-139.381 235.553,-141.119 235.553,-141.119\"/>\n",
"<text text-anchor=\"start\" x=\"262.5\" y=\"-131.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"</g>\n",
"<!-- 9&#45;&gt;9 -->\n",
"<g id=\"edge22\" class=\"edge\"><title>9&#45;&gt;9</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M302.332,-156.29C300.483,-166.389 303.039,-176 310,-176 315.221,-176 317.964,-170.594 318.229,-163.63\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"317.668,-156.29 321.342,-163.03 317.935,-159.78 318.201,-163.27 318.201,-163.27 318.201,-163.27 317.935,-159.78 315.06,-163.51 317.668,-156.29 317.668,-156.29\"/>\n",
"<text text-anchor=\"start\" x=\"306.5\" y=\"-194.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"302\" y=\"-179.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#1f78b4\">⓿</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<spot.impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7fc79cdf1ba0> >"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"(False, False, True, True, True, True, False, False, True, True)\n"
]
}
],
"source": [
"sistates2 = spot.make_stutter_invariant_forward_closed_inplace(ex1, sistates)\n",
"spot.highlight_stutter_invariant_states(ex1, None, 5)\n",
"display(ex1)\n",
"print(sistates2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now, state 0 is no longuer a problem."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"-1"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spot.is_stutter_invariant_forward_closed(ex1, sistates2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's see how infrequently the set of stutter-invarant states is not closed."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import spot.gen as gen\n",
"\n",
"try:\n",
" import pandas\n",
"except ImportError:\n",
" import sys; sys.exit(77) # Our test suite will skip the rest if Pandas is missing"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style>\n",
" .dataframe thead tr:only-child th {\n",
" text-align: right;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: left;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>formula</th>\n",
" <th>states</th>\n",
" <th>SIstates</th>\n",
" <th>fwd_closed</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Fp0 -&gt; (!p0 U (!p0 &amp; p1 &amp; X(!p0 U p2)))</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Fp0 -&gt; (!p1 U (p0 | (!p1 &amp; p2 &amp; X(!p1 U p3))))</td>\n",
" <td>4</td>\n",
" <td>3</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>G!p0 | (!p0 U ((p0 &amp; Fp1) -&gt; (!p1 U (!p1 &amp; p2 ...</td>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>G((p0 &amp; Fp1) -&gt; (!p2 U (p1 | (!p2 &amp; p3 &amp; X(!p2...</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>G(p0 -&gt; (Fp1 -&gt; (!p1 U (p2 | (!p1 &amp; p3 &amp; X(!p1...</td>\n",
" <td>3</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>F(p0 &amp; XFp1) -&gt; (!p0 U p2)</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Fp0 -&gt; (!(!p0 &amp; p1 &amp; X(!p0 U (!p0 &amp; p2))) U (p...</td>\n",
" <td>4</td>\n",
" <td>3</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>G!p0 | (!p0 U (p0 &amp; (F(p1 &amp; XFp2) -&gt; (!p1 U p3...</td>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>G((p0 &amp; Fp1) -&gt; (!(!p1 &amp; p2 &amp; X(!p1 U (!p1 &amp; p...</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>G(p0 -&gt; ((!(!p1 &amp; p2 &amp; X(!p1 U (!p1 &amp; p3))) U ...</td>\n",
" <td>3</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>G((p0 &amp; XFp1) -&gt; XF(p1 &amp; Fp2))</td>\n",
" <td>6</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>Fp0 -&gt; (((p1 &amp; X(!p0 U p2)) -&gt; X(!p0 U (p2 &amp; F...</td>\n",
" <td>6</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>G(p0 -&gt; G((p1 &amp; XFp2) -&gt; X(!p2 U (p2 &amp; Fp3))))</td>\n",
" <td>5</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>G((p0 &amp; Fp1) -&gt; (((p2 &amp; X(!p1 U p3)) -&gt; X(!p1 ...</td>\n",
" <td>10</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>G(p0 -&gt; (((p1 &amp; X(!p2 U p3)) -&gt; X(!p2 U (p3 &amp; ...</td>\n",
" <td>10</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>G(p0 -&gt; F(p1 &amp; XFp2))</td>\n",
" <td>4</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>Fp0 -&gt; ((p1 -&gt; (!p0 U (!p0 &amp; p2 &amp; X(!p0 U p3))...</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>G(p0 -&gt; G(p1 -&gt; (p2 &amp; XFp3)))</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>G((p0 &amp; Fp1) -&gt; ((p2 -&gt; (!p1 U (!p1 &amp; p3 &amp; X(!...</td>\n",
" <td>4</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>G(p0 -&gt; ((p1 -&gt; (!p2 U (!p2 &amp; p3 &amp; X(!p2 U p4)...</td>\n",
" <td>6</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>G(p0 -&gt; F(p1 &amp; !p2 &amp; X(!p2 U p3)))</td>\n",
" <td>4</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>Fp0 -&gt; ((p1 -&gt; (!p0 U (!p0 &amp; p2 &amp; !p3 &amp; X((!p0...</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>G(p0 -&gt; G(p1 -&gt; (p2 &amp; !p3 &amp; X(!p3 U p4))))</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>23</th>\n",
" <td>G((p0 &amp; Fp1) -&gt; ((p2 -&gt; (!p1 U (!p1 &amp; p3 &amp; !p4...</td>\n",
" <td>4</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>24</th>\n",
" <td>G(p0 -&gt; ((p1 -&gt; (!p2 U (!p2 &amp; p3 &amp; !p4 &amp; X((!p...</td>\n",
" <td>6</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25</th>\n",
" <td>p0 U (p1 &amp; X(p2 U p3))</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>26</th>\n",
" <td>p0 U (p1 &amp; X(p2 &amp; F(p3 &amp; XF(p4 &amp; XF(p5 &amp; XFp6)...</td>\n",
" <td>7</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>27</th>\n",
" <td>F(p0 &amp; XGp1)</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>28</th>\n",
" <td>F(p0 &amp; X(p1 &amp; XFp2))</td>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>29</th>\n",
" <td>F(p0 &amp; X(p1 U p2))</td>\n",
" <td>3</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>33</th>\n",
" <td>G((p0 &amp; p1 &amp; !p2 &amp; Xp2) -&gt; X(p3 | X(!p1 | p3)))</td>\n",
" <td>3</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>34</th>\n",
" <td>G((p0 &amp; p1 &amp; !p2 &amp; Xp2) -&gt; X(X!p1 | (p2 U (!p2...</td>\n",
" <td>5</td>\n",
" <td>5</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>35</th>\n",
" <td>G(p0 &amp; p1 &amp; !p2 &amp; Xp2) -&gt; X(X!p1 | (p2 U (!p2 ...</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>36</th>\n",
" <td>G((!p0 &amp; p1) -&gt; Xp2)</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>37</th>\n",
" <td>G(p0 -&gt; X(p0 | p1))</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>38</th>\n",
" <td>G((!(p1 &lt;-&gt; Xp1) | !(p0 &lt;-&gt; Xp0) | !(p2 &lt;-&gt; Xp...</td>\n",
" <td>34</td>\n",
" <td>34</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>39</th>\n",
" <td>G((p0 &amp; !p1 &amp; Xp1 &amp; Xp0) -&gt; (p2 -&gt; Xp3))</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>40</th>\n",
" <td>G(p0 -&gt; X(!p0 U p1))</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>41</th>\n",
" <td>G((!p0 &amp; Xp0) -&gt; X((p0 U p1) | Gp0))</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>42</th>\n",
" <td>G((!p0 &amp; Xp0) -&gt; X(p0 U (p0 &amp; !p1 &amp; X(p0 &amp; p1))))</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>43</th>\n",
" <td>G((!p0 &amp; Xp0) -&gt; X(p0 U (p0 &amp; !p1 &amp; X(p0 &amp; p1 ...</td>\n",
" <td>6</td>\n",
" <td>6</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>44</th>\n",
" <td>G((p0 &amp; X!p0) -&gt; X(!p0 U (!p0 &amp; !p1 &amp; X(!p0 &amp; ...</td>\n",
" <td>6</td>\n",
" <td>6</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>45</th>\n",
" <td>G((p0 &amp; X!p0) -&gt; X(!p0 U (!p0 &amp; !p1 &amp; X(!p0 &amp; ...</td>\n",
" <td>8</td>\n",
" <td>8</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>46</th>\n",
" <td>G((!p0 &amp; Xp0) -&gt; X(!(!p0 &amp; Xp0) U (!p1 &amp; Xp1)))</td>\n",
" <td>6</td>\n",
" <td>6</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>47</th>\n",
" <td>G(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 ...</td>\n",
" <td>12</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>48</th>\n",
" <td>G((Xp0 -&gt; p0) -&gt; (p1 &lt;-&gt; Xp1))</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>49</th>\n",
" <td>G((Xp0 -&gt; p0) -&gt; ((p1 -&gt; Xp1) &amp; (!p1 -&gt; X!p1)))</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50</th>\n",
" <td>p0 &amp; XG!p0</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>51</th>\n",
" <td>XG(p0 -&gt; (G!p1 | (!Xp1 U p2)))</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>52</th>\n",
" <td>XG((p0 &amp; !p1) -&gt; (G!p1 | (!p1 U p2)))</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>53</th>\n",
" <td>XG((p0 &amp; p1) -&gt; (Gp1 | (p1 U p2)))</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>54</th>\n",
" <td>Xp0 &amp; G((!p0 &amp; Xp0) -&gt; XXp0)</td>\n",
" <td>5</td>\n",
" <td>0</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>55</th>\n",
" <td>(Xp0 U Xp1) | !X(p0 U p1)</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>56</th>\n",
" <td>(Xp0 U p1) | !X(p0 U (p0 &amp; p1))</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>57</th>\n",
" <td>((Xp0 U p1) | !X(p0 U (p0 &amp; p1))) &amp; G(p0 -&gt; Fp1)</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>58</th>\n",
" <td>((Xp0 U Xp1) | !X(p0 U p1)) &amp; G(p0 -&gt; Fp1)</td>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>59</th>\n",
" <td>!G(p0 -&gt; X(p1 R p2))</td>\n",
" <td>3</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>60</th>\n",
" <td>(p0 &amp; Xp1) R X(((p2 U p3) R p0) U (p2 R p0))</td>\n",
" <td>5</td>\n",
" <td>3</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>61</th>\n",
" <td>G(p0 | XGp1) &amp; G(p2 | XG!p1)</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" <td>True</td>\n",
" </tr>\n",
" <tr>\n",
" <th>62</th>\n",
" <td>G(p0 | (Xp1 &amp; X!p1))</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>True</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>63 rows × 4 columns</p>\n",
"</div>"
],
"text/plain": [
" formula states SIstates \\\n",
"0 Fp0 -> (!p0 U (!p0 & p1 & X(!p0 U p2))) 3 2 \n",
"1 Fp0 -> (!p1 U (p0 | (!p1 & p2 & X(!p1 U p3)))) 4 3 \n",
"2 G!p0 | (!p0 U ((p0 & Fp1) -> (!p1 U (!p1 & p2 ... 4 2 \n",
"3 G((p0 & Fp1) -> (!p2 U (p1 | (!p2 & p3 & X(!p2... 4 1 \n",
"4 G(p0 -> (Fp1 -> (!p1 U (p2 | (!p1 & p3 & X(!p1... 3 0 \n",
"5 F(p0 & XFp1) -> (!p0 U p2) 3 2 \n",
"6 Fp0 -> (!(!p0 & p1 & X(!p0 U (!p0 & p2))) U (p... 4 3 \n",
"7 G!p0 | (!p0 U (p0 & (F(p1 & XFp2) -> (!p1 U p3... 4 2 \n",
"8 G((p0 & Fp1) -> (!(!p1 & p2 & X(!p1 U (!p1 & p... 4 1 \n",
"9 G(p0 -> ((!(!p1 & p2 & X(!p1 U (!p1 & p3))) U ... 3 0 \n",
"10 G((p0 & XFp1) -> XF(p1 & Fp2)) 6 1 \n",
"11 Fp0 -> (((p1 & X(!p0 U p2)) -> X(!p0 U (p2 & F... 6 2 \n",
"12 G(p0 -> G((p1 & XFp2) -> X(!p2 U (p2 & Fp3)))) 5 0 \n",
"13 G((p0 & Fp1) -> (((p2 & X(!p1 U p3)) -> X(!p1 ... 10 2 \n",
"14 G(p0 -> (((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & ... 10 0 \n",
"15 G(p0 -> F(p1 & XFp2)) 4 0 \n",
"16 Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & X(!p0 U p3))... 4 1 \n",
"17 G(p0 -> G(p1 -> (p2 & XFp3))) 3 3 \n",
"18 G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & X(!... 4 0 \n",
"19 G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & X(!p2 U p4)... 6 2 \n",
"20 G(p0 -> F(p1 & !p2 & X(!p2 U p3))) 4 0 \n",
"21 Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & !p3 & X((!p0... 4 1 \n",
"22 G(p0 -> G(p1 -> (p2 & !p3 & X(!p3 U p4)))) 3 3 \n",
"23 G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & !p4... 4 0 \n",
"24 G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & !p4 & X((!p... 6 2 \n",
"25 p0 U (p1 & X(p2 U p3)) 3 2 \n",
"26 p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)... 7 2 \n",
"27 F(p0 & XGp1) 2 2 \n",
"28 F(p0 & X(p1 & XFp2)) 4 2 \n",
"29 F(p0 & X(p1 U p2)) 3 1 \n",
".. ... ... ... \n",
"33 G((p0 & p1 & !p2 & Xp2) -> X(p3 | X(!p1 | p3))) 3 0 \n",
"34 G((p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2... 5 5 \n",
"35 G(p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 ... 1 1 \n",
"36 G((!p0 & p1) -> Xp2) 2 0 \n",
"37 G(p0 -> X(p0 | p1)) 2 2 \n",
"38 G((!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp... 34 34 \n",
"39 G((p0 & !p1 & Xp1 & Xp0) -> (p2 -> Xp3)) 2 2 \n",
"40 G(p0 -> X(!p0 U p1)) 2 0 \n",
"41 G((!p0 & Xp0) -> X((p0 U p1) | Gp0)) 3 3 \n",
"42 G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1)))) 4 4 \n",
"43 G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1 ... 6 6 \n",
"44 G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & ... 6 6 \n",
"45 G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & ... 8 8 \n",
"46 G((!p0 & Xp0) -> X(!(!p0 & Xp0) U (!p1 & Xp1))) 6 6 \n",
"47 G(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 ... 12 0 \n",
"48 G((Xp0 -> p0) -> (p1 <-> Xp1)) 4 4 \n",
"49 G((Xp0 -> p0) -> ((p1 -> Xp1) & (!p1 -> X!p1))) 4 4 \n",
"50 p0 & XG!p0 2 1 \n",
"51 XG(p0 -> (G!p1 | (!Xp1 U p2))) 4 1 \n",
"52 XG((p0 & !p1) -> (G!p1 | (!p1 U p2))) 3 2 \n",
"53 XG((p0 & p1) -> (Gp1 | (p1 U p2))) 3 2 \n",
"54 Xp0 & G((!p0 & Xp0) -> XXp0) 5 0 \n",
"55 (Xp0 U Xp1) | !X(p0 U p1) 1 1 \n",
"56 (Xp0 U p1) | !X(p0 U (p0 & p1)) 1 1 \n",
"57 ((Xp0 U p1) | !X(p0 U (p0 & p1))) & G(p0 -> Fp1) 2 2 \n",
"58 ((Xp0 U Xp1) | !X(p0 U p1)) & G(p0 -> Fp1) 2 2 \n",
"59 !G(p0 -> X(p1 R p2)) 3 1 \n",
"60 (p0 & Xp1) R X(((p2 U p3) R p0) U (p2 R p0)) 5 3 \n",
"61 G(p0 | XGp1) & G(p2 | XG!p1) 3 2 \n",
"62 G(p0 | (Xp1 & X!p1)) 1 1 \n",
"\n",
" fwd_closed \n",
"0 True \n",
"1 True \n",
"2 True \n",
"3 True \n",
"4 True \n",
"5 True \n",
"6 True \n",
"7 True \n",
"8 True \n",
"9 True \n",
"10 True \n",
"11 True \n",
"12 True \n",
"13 True \n",
"14 True \n",
"15 True \n",
"16 True \n",
"17 True \n",
"18 True \n",
"19 True \n",
"20 True \n",
"21 True \n",
"22 True \n",
"23 True \n",
"24 True \n",
"25 True \n",
"26 True \n",
"27 True \n",
"28 True \n",
"29 True \n",
".. ... \n",
"33 True \n",
"34 True \n",
"35 True \n",
"36 True \n",
"37 True \n",
"38 True \n",
"39 True \n",
"40 True \n",
"41 True \n",
"42 True \n",
"43 True \n",
"44 True \n",
"45 True \n",
"46 True \n",
"47 True \n",
"48 True \n",
"49 True \n",
"50 True \n",
"51 True \n",
"52 True \n",
"53 True \n",
"54 True \n",
"55 True \n",
"56 True \n",
"57 True \n",
"58 True \n",
"59 True \n",
"60 True \n",
"61 True \n",
"62 True \n",
"\n",
"[63 rows x 4 columns]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Let's consider the LTL formula from the following 5 sources,\n",
"# and restrict ourselves to formulas that are not stutter-invariant.\n",
"formulas = [ f for f in gen.ltl_patterns(gen.LTL_DAC_PATTERNS, \n",
" gen.LTL_EH_PATTERNS, \n",
" gen.LTL_HKRSS_PATTERNS, \n",
" gen.LTL_P_PATTERNS, \n",
" gen.LTL_SB_PATTERNS)\n",
" if not f.is_syntactic_stutter_invariant() ]\n",
"\n",
"fmt_txt = []\n",
"aut_size = []\n",
"sistates_size = []\n",
"fwd_closed = []\n",
"\n",
"for f in formulas:\n",
" fmt_txt.append(f.to_str())\n",
" aut = spot.translate(f)\n",
" aut_size.append(aut.num_states())\n",
" sistates = spot.stutter_invariant_states(aut, f)\n",
" sistates_size.append(sum(sistates))\n",
" fwd_closed.append(spot.is_stutter_invariant_forward_closed(aut, sistates) == -1)\n",
" \n",
"# Put everything in a data frame for display.\n",
"df = pandas.DataFrame({'formula': fmt_txt, 'states': aut_size, 'SIstates': sistates_size, 'fwd_closed': fwd_closed},\n",
" columns=['formula','states','SIstates','fwd_closed'])\n",
"display(df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There is no instance of set of stutter-invariant states that is not closed in these example formulas."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"(63, 63)"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sum(fwd_closed), len(fwd_closed)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here is the percentage of stutter-invarant states."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"55.90277777777778"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"100*sum(sistates_size)/sum(aut_size)"
]
}
],
"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.4rc1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}