rename wrap/python/ to python/

* wrap/python/: Rename to...
* python/: ... this.
* wrap/: Delete.
* Makefile.am, README, configure.ac, debian/python3-spot.examples,
debian/rules, doc/org/.dir-locals.el.in, doc/org/init.el.in,
spot/sanity/ipynb.test: Adjust.
This commit is contained in:
Alexandre Duret-Lutz 2015-12-25 11:55:31 +01:00
parent 74ec9c54c4
commit 34c3c1cedc
62 changed files with 24 additions and 48 deletions

3
python/tests/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
Makefile
Makefile.in
run

67
python/tests/Makefile.am Normal file
View file

@ -0,0 +1,67 @@
## -*- coding: utf-8 -*-
## Copyright (C) 2010, 2012, 2013, 2014, 2015 Labortatoire de
## Recherche et Développement de l'EPITA.
## Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
## département Systèmes Répartis Coopératifs (SRC), Université Pierre
## et Marie Curie.
##
## This file is part of Spot, a model checking library.
##
## Spot is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## Spot is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
## License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
EXTRA_DIST = \
$(TESTS) \
ltl2tgba.py \
ipnbdoctest.py
LOG_COMPILER = ./run
LOG_DRIVER = $(TEST_LOG_DRIVER)
# ensure run is rebuilt before the tests are run.
check_SCRIPTS = run
TESTS = \
acc_cond.ipynb \
accparse.ipynb \
accparse2.py \
alarm.py \
automata.ipynb \
automata-io.ipynb \
bddnqueen.py \
decompose.ipynb \
formulas.ipynb \
implies.py \
interdep.py \
ltl2tgba.test \
ltlparse.py \
ltlsimple.py \
minato.py \
optionmap.py \
parsetgba.py \
piperead.ipynb \
product.ipynb \
randaut.ipynb \
randgen.py \
randltl.ipynb \
relabel.py \
remfin.py \
satmin.py \
setxor.py \
testingaut.ipynb
SUFFIXES = .ipynb .html
.ipynb.html:
$(IPYTHON) nbconvert $< --to html
.PHONY: nb-html
nb-html: $(TESTS:.ipynb=.html)

1444
python/tests/acc_cond.ipynb Normal file

File diff suppressed because it is too large Load diff

177
python/tests/accparse.ipynb Normal file
View file

@ -0,0 +1,177 @@
{
"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.4.3+"
},
"name": "",
"signature": "sha256:1ee7951bed30652ae110a14b210541829221552eb944ff01f25236179673dd5b"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": true,
"input": [
"import spot\n",
"spot.setup()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"c = spot.acc_code('Inf(0)&Fin(1)|Inf(2)&Fin(3)'); c"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"text": [
"(Fin(1) & Inf(0)) | (Fin(3) & Inf(2))"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"c.to_dnf()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"text": [
"(Fin(1) & Inf(0)) | (Fin(3) & Inf(2))"
]
}
],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"c.to_cnf()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 4,
"text": [
"(Inf(0) | Inf(2)) & (Fin(3) | Inf(0)) & (Fin(1) | Inf(2)) & (Fin(1)|Fin(3))"
]
}
],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for acc in ['all', 't', \n",
" 'Buchi', 'generalized-Buchi 3', 'generalized-Buchi 0',\n",
" 'co-Buchi', 'generalized-co-Buchi 3', 'generalized-co-Buchi 0',\n",
" 'Rabin 2', 'Rabin 0',\n",
" 'Streett 2', 'Streett 0',\n",
" 'generalized-Rabin 3 1 2 3', 'generalized-Rabin 0',\n",
" 'parity min even 6', 'parity max odd 6', 'parity max even 6', 'parity min odd 6',\n",
" 'parity min even 5', 'parity max odd 5', 'parity max even 5', 'parity min odd 5',\n",
" 'parity min even 2', 'parity max odd 2', 'parity max even 2', 'parity min odd 2',\n",
" 'parity min even 1', 'parity max odd 1', 'parity max even 1', 'parity min odd 1',\n",
" 'parity min even 0', 'parity max odd 0', 'parity max even 0', 'parity min odd 0',\n",
" ]:\n",
" print(acc, ': ', spot.acc_code(acc), sep='')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"all: t\n",
"t: t\n",
"Buchi: Inf(0)\n",
"generalized-Buchi 3: Inf(0)&Inf(1)&Inf(2)\n",
"generalized-Buchi 0: t\n",
"co-Buchi: Fin(0)\n",
"generalized-co-Buchi 3: Fin(0)|Fin(1)|Fin(2)\n",
"generalized-co-Buchi 0: f\n",
"Rabin 2: (Fin(0) & Inf(1)) | (Fin(2) & Inf(3))\n",
"Rabin 0: f\n",
"Streett 2: (Fin(0) | Inf(1)) & (Fin(2) | Inf(3))\n",
"Streett 0: t\n",
"generalized-Rabin 3 1 2 3: (Fin(0) & Inf(1)) | (Fin(2) & (Inf(3)&Inf(4))) | (Fin(5) & (Inf(6)&Inf(7)&Inf(8)))\n",
"generalized-Rabin 0: f\n",
"parity min even 6: Inf(0) | (Fin(1) & (Inf(2) | (Fin(3) & (Inf(4) | Fin(5)))))\n",
"parity max odd 6: Inf(5) | (Fin(4) & (Inf(3) | (Fin(2) & (Inf(1) | Fin(0)))))\n",
"parity max even 6: Fin(5) & (Inf(4) | (Fin(3) & (Inf(2) | (Fin(1) & Inf(0)))))\n",
"parity min odd 6: Fin(0) & (Inf(1) | (Fin(2) & (Inf(3) | (Fin(4) & Inf(5)))))\n",
"parity min even 5: Inf(0) | (Fin(1) & (Inf(2) | (Fin(3) & Inf(4))))\n",
"parity max odd 5: Fin(4) & (Inf(3) | (Fin(2) & (Inf(1) | Fin(0))))\n",
"parity max even 5: Inf(4) | (Fin(3) & (Inf(2) | (Fin(1) & Inf(0))))\n",
"parity min odd 5: Fin(0) & (Inf(1) | (Fin(2) & (Inf(3) | Fin(4))))\n",
"parity min even 2: Inf(0) | Fin(1)\n",
"parity max odd 2: Inf(1) | Fin(0)\n",
"parity max even 2: Fin(1) & Inf(0)\n",
"parity min odd 2: Fin(0) & Inf(1)\n",
"parity min even 1: Inf(0)\n",
"parity max odd 1: Fin(0)\n",
"parity max even 1: Inf(0)\n",
"parity min odd 1: Fin(0)\n",
"parity min even 0: t\n",
"parity max odd 0: t\n",
"parity max even 0: f\n",
"parity min odd 0: f\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
}
],
"metadata": {}
}
]
}

93
python/tests/accparse2.py Normal file
View file

@ -0,0 +1,93 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2015 Laboratoire de Recherche et Développement
# de l'Epita
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import spot
a = spot.acc_cond(5)
a.set_acceptance(spot.acc_code('parity min odd 5'))
assert(a.is_parity() == [True, False, True])
a.set_acceptance('parity max even 5')
assert(a.is_parity() == [True, True, False])
a.set_acceptance('generalized-Buchi 5')
assert(a.is_parity()[0] == False)
assert(a.is_parity(True)[0] == False)
a.set_acceptance('Inf(4) | (Fin(3)&Inf(2)) | (Fin(3)&Fin(1)&Inf(0))')
assert(a.is_parity()[0] == False)
assert(a.is_parity(True) == [True, True, False])
a = spot.acc_cond(0)
a.set_acceptance('all')
assert(a.is_rabin() == -1)
assert(a.is_streett() == 0)
assert(a.is_parity() == [True, True, True])
a.set_acceptance('none')
assert(a.is_rabin() == 0)
assert(a.is_streett() == -1)
assert(a.is_parity() == [True, True, False])
a = spot.acc_cond('(Fin(0)&Inf(1))')
assert(a.is_rabin() == 1)
assert(a.is_streett() == -1)
a.set_acceptance('Inf(1)&Fin(0)')
assert(a.is_rabin() == 1)
assert(a.is_streett() == -1)
a.set_acceptance('(Fin(0)|Inf(1))')
assert(a.is_rabin() == -1)
assert(a.is_streett() == 1)
a.set_acceptance('Inf(1)|Fin(0)')
assert(a.is_rabin() == -1)
assert(a.is_streett() == 1)
a = spot.acc_cond('(Fin(0)&Inf(1))|(Fin(2)&Inf(3))')
assert(a.is_rabin() == 2)
assert(a.is_streett() == -1)
a.set_acceptance(spot.acc_code('(Inf(3)&Fin(2))|(Fin(0)&Inf(1))'))
assert(a.is_rabin() == 2)
assert(a.is_streett() == -1)
a.set_acceptance(spot.acc_code('(Inf(2)&Fin(3))|(Fin(0)&Inf(1))'))
assert(a.is_rabin() == -1)
assert(a.is_streett() == -1)
a.set_acceptance(spot.acc_code('(Inf(3)&Fin(2))|(Fin(2)&Inf(1))'))
assert(a.is_rabin() == -1)
assert(a.is_streett() == -1)
a.set_acceptance(spot.acc_code('(Inf(1)&Fin(0))|(Fin(0)&Inf(1))'))
assert(a.is_rabin() == -1)
assert(a.is_streett() == -1)
a.set_acceptance('(Fin(0)&Inf(1))|(Inf(1)&Fin(0))|(Inf(3)&Fin(2))')
assert(a.is_rabin() == 2)
assert(a.is_streett() == -1)
a.set_acceptance('(Fin(0)|Inf(1))&(Fin(2)|Inf(3))')
assert(a.is_rabin() == -1)
assert(a.is_streett() == 2)
a.set_acceptance('(Inf(3)|Fin(2))&(Fin(0)|Inf(1))')
assert(a.is_rabin() == -1)
assert(a.is_streett() == 2)
a.set_acceptance('(Inf(2)|Fin(3))&(Fin(0)|Inf(1))')
assert(a.is_rabin() == -1)
assert(a.is_streett() == -1)
a.set_acceptance('(Inf(3)|Fin(2))&(Fin(2)|Inf(1))')
assert(a.is_rabin() == -1)
assert(a.is_streett() == -1)
a.set_acceptance('(Inf(1)|Fin(0))&(Fin(0)|Inf(1))')
assert(a.is_rabin() == -1)
assert(a.is_streett() == -1)
a.set_acceptance('(Fin(0)|Inf(1))&(Inf(1)|Fin(0))&(Inf(3)|Fin(2))')
assert(a.is_rabin() == -1)
assert(a.is_streett() == 2)

66
python/tests/alarm.py Executable file
View file

@ -0,0 +1,66 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2012, 2014, 2015 Laboratoire de Recherche et Développement
# de l'Epita
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import spot
import time
import signal
import sys
import os
def alarm_handler(signum, frame):
sys.stdout.write("signaled\n")
os.kill(child, signal.SIGTERM)
exit(0)
f = """!(G(F(P_Rbt2.observe)&& F(P_Rbt3.observe) &&
F(P_rbt1.observe)&& F(P_Rbt1.plus || P_Rbt1.moins || P_Rbt1.stop)&&
F(P_Rbt3.plus || P_Rbt3.moins || P_Rbt3.stop) && F(P_Rbt2.plus ||
P_Rbt2.moins || P_Rbt2.stop))-> G((F "map[0]==1") && (F "map[1]==1")
&& (F "map[2]==1") && (F "map[3]==1") && (F "map[4]==1") && (F
"map[5]==1") && (F "map[6]==1") && (F "map[7]==1") && (F "map[8]==1")
&& (F "map[9]==1") && (F "map[0]==2") && (F "map[1]==2") && (F
"map[2]==2") && (F "map[3]==2") && (F "map[4]==2") && (F "map[5]==2")
&& (F "map[6]==2") && (F "map[7]==2") && (F "map[8]==2") && (F
"map[9]==2") && (F "map[0]==3") && (F "map[1]==3") && (F "map[2]==3")
&& (F "map[3]==3") && (F "map[4]==3") && (F "map[5]==3") && (F
"map[6]==3") && (F "map[7]==3") && (F "map[8]==3") && (F
"map[9]==3")))"""
e = spot.default_environment.instance()
p = spot.empty_parse_error_list()
f = spot.parse_infix_psl(f, p, e)
d = spot.make_bdd_dict()
spot.unblock_signal(signal.SIGALRM)
spot.unblock_signal(signal.SIGTERM)
os.setpgrp()
child = os.fork()
if child != 0:
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(2)
os.waitpid(child, 0)
# If the child returns, before we get the alarm it's a bug.
exit(1)
# This is expected to take WAY more that 2s.
print("Before")
spot.ltl_to_tgba_fm(f, d, True)
print("After")
exit(1)

View file

@ -0,0 +1,862 @@
{
"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.4.3+"
},
"name": "",
"signature": "sha256:79ee85572b2a0147d88b2d3d355977e3f34dadb82bd7e8589bdbb2cf2a539b0b"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.display import display\n",
"import spot\n",
"spot.setup()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"a = spot.translate('a U b')\n",
"for fmt in ('hoa', 'spin', 'dot', 'lbtt'):\n",
" print(a.to_str(fmt))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"HOA: v1\n",
"States: 2\n",
"Start: 1\n",
"AP: 2 \"a\" \"b\"\n",
"acc-name: Buchi\n",
"Acceptance: 1 Inf(0)\n",
"properties: trans-labels explicit-labels state-acc deterministic\n",
"properties: stutter-invariant terminal\n",
"--BODY--\n",
"State: 0 {0}\n",
"[t] 0\n",
"State: 1\n",
"[1] 0\n",
"[0&!1] 1\n",
"--END--\n",
"never {\n",
"T0_init:\n",
" if\n",
" :: (b) -> goto accept_all\n",
" :: ((a) && (!(b))) -> goto T0_init\n",
" fi;\n",
"accept_all:\n",
" skip\n",
"}\n",
"\n",
"digraph G {\n",
" rankdir=LR\n",
" node [shape=\"circle\"]\n",
" fontname=\"Lato\"\n",
" node [fontname=\"Lato\"]\n",
" edge [fontname=\"Lato\"]\n",
" size=\"10.2,5\" node[style=filled,fillcolor=\"#ffffaa\"] edge[arrowhead=vee, arrowsize=.7]\n",
" I [label=\"\", style=invis, width=0]\n",
" I -> 1\n",
" 0 [label=\"0\", peripheries=2]\n",
" 0 -> 0 [label=<1>]\n",
" 1 [label=\"1\"]\n",
" 1 -> 0 [label=<b>]\n",
" 1 -> 1 [label=<a &amp; !b>]\n",
"}\n",
"\n",
"2 1\n",
"0 1 -1\n",
"1 \"b\"\n",
"0 & \"a\" ! \"b\"\n",
"-1\n",
"1 0 0 -1\n",
"1 t\n",
"-1\n",
"\n"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"a.save('example.aut').save('example.aut', format='lbtt', append=True)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M74.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</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=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f4414147600> >"
]
}
],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!cat example.aut"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"HOA: v1\r\n",
"States: 2\r\n",
"Start: 1\r\n",
"AP: 2 \"a\" \"b\"\r\n",
"acc-name: Buchi\r\n",
"Acceptance: 1 Inf(0)\r\n",
"properties: trans-labels explicit-labels state-acc deterministic\r\n",
"properties: stutter-invariant terminal\r\n",
"--BODY--\r\n",
"State: 0 {0}\r\n",
"[t] 0\r\n",
"State: 1\r\n",
"[1] 0\r\n",
"[0&!1] 1\r\n",
"--END--\r\n",
"2 1\r\n",
"0 1 -1\r\n",
"1 \"b\"\r\n",
"0 & \"a\" ! \"b\"\r\n",
"-1\r\n",
"1 0 0 -1\r\n",
"1 t\r\n",
"-1\r\n"
]
}
],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for a in spot.automata('example.aut'):\n",
" display(a)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M74.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</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=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f4414157570> >"
]
},
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.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,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\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,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" 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.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f4414157660> >"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Test `--ABORT--`\n",
"----------------"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file example.aut\n",
"HOA: v1\n",
"States: 2\n",
"Start: 1\n",
"AP: 2 \"a\" \"b\"\n",
"acc-name: Buchi\n",
"Acceptance: 1 Inf(0)\n",
"--BODY--\n",
"State: 0 {0}\n",
"[t] 0\n",
"--ABORT-- /* the previous automaton should be ignored */\n",
"HOA: v1\n",
"States: 2\n",
"Start: 1\n",
"AP: 2 \"a\" \"b\"\n",
"Acceptance: 1 Inf(0)\n",
"--BODY--\n",
"State: 0 {0}\n",
"[t] 0\n",
"State: 1\n",
"[1] 0\n",
"[0&!1] 1\n",
"--END--"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting example.aut\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for a in spot.automata('example.aut'):\n",
" display(a)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M74.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</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=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f441765be40> >"
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for a in spot.automata(\"\"\"\n",
"HOA: v1\n",
"States: 2\n",
"Start: 1\n",
"name: \"Hello world\"\n",
"AP: 2 \"a\" \"b\"\n",
"Acceptance: 1 Inf(0)\n",
"--BODY--\n",
"State: 0 {0}\n",
"[t] 0\n",
"State: 1\n",
"[1] 0\n",
"[0&!1] 1\n",
"--END--\n",
"HOA: v1\n",
"States: 1\n",
"Start: 0\n",
"name: \"Hello world 2\"\n",
"AP: 2 \"a\" \"b\"\n",
"Acceptance: 2 Inf(0)&Inf(1)\n",
"--BODY--\n",
"State: 0 {0}\n",
"[t] 0 {1}\n",
"[0&!1] 0\n",
"--END--\n",
"\"\"\"):\n",
" display(a)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M74.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</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=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f4414157690> >"
]
},
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"83pt\" height=\"138pt\"\n",
" viewBox=\"0.00 0.00 82.50 138.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 134)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-134 78.5,-134 78.5,4 -4,4\"/>\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=\"M52.7643,-35.7817C52.2144,-45.3149 53.293,-54 56,-54 57.988,-54 59.0977,-49.3161 59.3292,-43.0521\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"59.2357,-35.7817 62.4756,-42.7406 59.2808,-39.2814 59.3258,-42.7812 59.3258,-42.7812 59.3258,-42.7812 59.2808,-39.2814 56.1761,-42.8217 59.2357,-35.7817 59.2357,-35.7817\"/>\n",
"<text text-anchor=\"start\" x=\"51.5\" y=\"-71.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"<text text-anchor=\"start\" x=\"40\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"<text text-anchor=\"start\" x=\"56\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#f17cb0\">\u2776</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.9375,-35.5938C47.5625,-56.125 49.25,-82 56,-82 61.9854,-82 63.9902,-61.6553 62.0146,-42.7315\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"61.0625,-35.5938 65.1104,-42.1158 61.5253,-39.063 61.9881,-42.5323 61.9881,-42.5323 61.9881,-42.5323 61.5253,-39.063 58.8657,-42.9488 61.0625,-35.5938 61.0625,-35.5938\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-100.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"<text text-anchor=\"start\" x=\"48\" y=\"-85.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f441765be40> >"
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Test syntax errors\n",
"------------------"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file example.aut\n",
"HOA: v1\n",
"States: 2\n",
"Start: 1\n",
"AP: 2 \"a\" \"b\"\n",
"acc-name: Buchi\n",
"Acceptance: 1 Inf(0)\n",
"--BODY--\n",
"State: 0 {0}\n",
"[t] 1\n",
"State: 1\n",
"[t] 1\n",
"--END--\n",
"HOA: v1\n",
"States: 2\n",
"Start: 1\n",
"AP: 2 \"a\" \"b\"\n",
"Acceptance: 1 Inf(0)\n",
"--BODY--\n",
"State: 0 {0}\n",
"[a] 3\n",
"State: 1\n",
"[1] 0\n",
"[0&!1] 1\n",
"--END--"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Overwriting example.aut\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for a in spot.automata('example.aut'):\n",
" display(a)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"133pt\" height=\"101pt\"\n",
" viewBox=\"0.00 0.00 133.00 101.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 97)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-97 129,-97 129,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"107\" cy=\"-42\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"107\" y=\"-38.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M23.0602,-62.9848C24.6706,-62.5773 58.2688,-54.0766 82.2014,-48.0213\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"89.2724,-46.2323 83.2589,-51.0031 85.8793,-47.0908 82.4862,-47.9493 82.4862,-47.9493 82.4862,-47.9493 85.8793,-47.0908 81.7135,-44.8956 89.2724,-46.2323 89.2724,-46.2323\"/>\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=\"M99.9688,-58.6641C98.4062,-68.625 100.75,-78 107,-78 111.688,-78 114.178,-72.7266 114.471,-65.8876\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"114.031,-58.6641 117.601,-65.4598 114.244,-62.1576 114.456,-65.6511 114.456,-65.6511 114.456,-65.6511 114.244,-62.1576 111.312,-65.8425 114.031,-58.6641 114.031,-58.6641\"/>\n",
"<text text-anchor=\"middle\" x=\"107\" y=\"-81.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"22\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"22\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"22\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M43.5169,-26.9438C55.3149,-29.7867 70.1833,-33.3695 82.4561,-36.3268\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"89.3394,-37.9854 81.7962,-39.4079 85.9368,-37.1655 82.5342,-36.3455 82.5342,-36.3455 82.5342,-36.3455 85.9368,-37.1655 83.2721,-33.2832 89.3394,-37.9854 89.3394,-37.9854\"/>\n",
"<text text-anchor=\"middle\" x=\"66.5\" y=\"-37.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f44141578d0> >"
]
},
{
"ename": "SyntaxError",
"evalue": "\nexample.aut:20.2: syntax error, unexpected identifier\nexample.aut:20.1-3: ignoring this invalid label\nexample.aut:20.5: state number is larger than state count...\nexample.aut:14.1-9: ... declared here.\n (<string>)",
"output_type": "pyerr",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<string>\"\u001b[0;36m, line \u001b[0;32munknown\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m \nexample.aut:20.2: syntax error, unexpected identifier\nexample.aut:20.1-3: ignoring this invalid label\nexample.aut:20.5: state number is larger than state count...\nexample.aut:14.1-9: ... declared here.\n\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.automaton('example.aut', timeout=100)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 11,
"svg": [
"<?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=\"133pt\" height=\"101pt\"\n",
" viewBox=\"0.00 0.00 133.00 101.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 97)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-97 129,-97 129,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"107\" cy=\"-42\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"107\" y=\"-38.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M23.0602,-62.9848C24.6706,-62.5773 58.2688,-54.0766 82.2014,-48.0213\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"89.2724,-46.2323 83.2589,-51.0031 85.8793,-47.0908 82.4862,-47.9493 82.4862,-47.9493 82.4862,-47.9493 85.8793,-47.0908 81.7135,-44.8956 89.2724,-46.2323 89.2724,-46.2323\"/>\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=\"M99.9688,-58.6641C98.4062,-68.625 100.75,-78 107,-78 111.688,-78 114.178,-72.7266 114.471,-65.8876\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"114.031,-58.6641 117.601,-65.4598 114.244,-62.1576 114.456,-65.6511 114.456,-65.6511 114.456,-65.6511 114.244,-62.1576 111.312,-65.8425 114.031,-58.6641 114.031,-58.6641\"/>\n",
"<text text-anchor=\"middle\" x=\"107\" y=\"-81.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"22\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"22\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"22\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M43.5169,-26.9438C55.3149,-29.7867 70.1833,-33.3695 82.4561,-36.3268\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"89.3394,-37.9854 81.7962,-39.4079 85.9368,-37.1655 82.5342,-36.3455 82.5342,-36.3455 82.5342,-36.3455 85.9368,-37.1655 83.2721,-33.2832 89.3394,-37.9854 89.3394,-37.9854\"/>\n",
"<text text-anchor=\"middle\" x=\"66.5\" y=\"-37.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f44141578a0> >"
]
}
],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.automaton('non-existing-cmd |')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "CalledProcessError",
"evalue": "Command 'non-existing-cmd ' returned non-zero exit status 127",
"output_type": "pyerr",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mCalledProcessError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-12-2b2d1b66dcd6>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mspot\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautomaton\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'non-existing-cmd |'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomaton\u001b[0;34m(filename, **kwargs)\u001b[0m\n\u001b[1;32m 404\u001b[0m See `spot.automata` for a list of supported formats.\"\"\"\n\u001b[1;32m 405\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 406\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mautomata\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 407\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 408\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Failed to read automaton from {}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomata\u001b[0;34m(timeout, *sources)\u001b[0m\n\u001b[1;32m 395\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mproc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 396\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 397\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0msubprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCalledProcessError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfilename\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 398\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 399\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mCalledProcessError\u001b[0m: Command 'non-existing-cmd ' returned non-zero exit status 127"
]
}
],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.automaton('sleep 3; cat example.aut |', timeout=1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "TimeoutExpired",
"evalue": "Command 'sleep 3; cat example.aut ' timed out after 1 seconds",
"output_type": "pyerr",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTimeoutExpired\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-13-d9c814f4e517>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mspot\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautomaton\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'sleep 3; cat example.aut |'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomaton\u001b[0;34m(filename, **kwargs)\u001b[0m\n\u001b[1;32m 404\u001b[0m See `spot.automata` for a list of supported formats.\"\"\"\n\u001b[1;32m 405\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 406\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mautomata\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 407\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 408\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Failed to read automaton from {}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomata\u001b[0;34m(timeout, *sources)\u001b[0m\n\u001b[1;32m 366\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 367\u001b[0m out = subprocess.check_output(filename[:-1], shell=True,\n\u001b[0;32m--> 368\u001b[0;31m timeout=timeout)\n\u001b[0m\u001b[1;32m 369\u001b[0m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mautomaton_stream_parser\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 370\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0;34m'\\n'\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfilename\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/lib/python3.4/subprocess.py\u001b[0m in \u001b[0;36mcheck_output\u001b[0;34m(timeout, *popenargs, **kwargs)\u001b[0m\n\u001b[1;32m 611\u001b[0m \u001b[0mprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkill\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 612\u001b[0m \u001b[0moutput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0munused_err\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcommunicate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 613\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTimeoutExpired\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0moutput\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 614\u001b[0m \u001b[0;32mexcept\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 615\u001b[0m \u001b[0mprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkill\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mTimeoutExpired\u001b[0m: Command 'sleep 3; cat example.aut ' timed out after 1 seconds"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"rm example.aut"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 14
}
],
"metadata": {}
}
]
}

3175
python/tests/automata.ipynb Normal file

File diff suppressed because it is too large Load diff

107
python/tests/bddnqueen.py Executable file
View file

@ -0,0 +1,107 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2010, 2011, 2012, 2014 Laboratoire de Recherche et
# Développement de l'EPITA.
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6
# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
# Pierre et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Python translation of the C++ example from the BuDDy distribution.
# (compare with buddy/examples/queen/queen.cxx)
import sys
from buddy import *
# Build the requirements for all other fields than (i,j) assuming
# that (i,j) has a queen.
def build(i, j):
a = b = c = d = bddtrue
# No one in the same column.
for l in side:
if l != j:
a &= X[i][j] >> -X[i][l]
# No one in the same row.
for k in side:
if k != i:
b &= X[i][j] >> -X[k][j]
# No one in the same up-right diagonal.
for k in side:
ll = k - i + j
if ll >= 0 and ll < N:
if k != i:
c &= X[i][j] >> -X[k][ll]
# No one in the same down-right diagonal.
for k in side:
ll = i + j - k
if ll >= 0 and ll < N:
if k != i:
c &= X[i][j] >> -X[k][ll]
global queen
queen &= a & b & c & d
# Get the number of queens from the command-line, or default to 8.
if len(sys.argv) > 1:
N = int(argv[1])
else:
N = 8
side = range(N)
# Initialize with 100000 nodes, 10000 cache entries and NxN variables.
bdd_init(N * N * 256, 10000)
bdd_setvarnum(N * N)
queen = bddtrue
# Build variable array.
X = [[bdd_ithvar(i*N+j) for j in side] for i in side]
# Place a queen in each row.
for i in side:
e = bddfalse
for j in side:
e |= X[i][j]
queen &= e
# Build requirements for each variable(field).
for i in side:
for j in side:
sys.stdout.write("Adding position %d, %d\n" % (i, j))
build(i, j)
# Print the results.
sys.stdout.write("There are %d solutions, one is:\n" %
bdd_satcount(queen))
solution = bdd_satone(queen)
bdd_printset(solution)
from spot import nl_cout
nl_cout()
# Cleanup all BDD variables before calling bdd_done(), otherwise
# bdd_delref will be called after bdd_done() and this is unsafe in
# optimized builds.
X = e = queen = solution = 0
bdd_done()

5010
python/tests/decompose.ipynb Normal file

File diff suppressed because it is too large Load diff

727
python/tests/formulas.ipynb Normal file
View file

@ -0,0 +1,727 @@
{
"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.4.3+"
},
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Handling LTL and PSL formulas\n",
"============================="
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import spot"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For interactive use, formulas can be entered as text strings and passed to the `spot.formula` constructor."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.formula('p1 U p2 R (p3 & !p4)')\n",
"f"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$p_{1} \\mathbin{\\mathsf{U}} (p_{2} \\mathbin{\\mathsf{R}} (p_{3} \\land \\lnot p_{4}))$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"text": [
"p1 U (p2 R (p3 & !p4))"
]
}
],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"g = spot.formula('{a;b*;c[+]}<>->GFb'); g"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$\\{a \\mathbin{\\mathsf{;}} b^{\\star} \\mathbin{\\mathsf{;}} c^+\\}\\mathrel{\\Diamond\\kern-1.7pt\\raise.4pt\\hbox{$\\mathord{\\rightarrow}$}} \\mathsf{G} \\mathsf{F} b$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"text": [
"{a;b[*];c[+]}<>-> GFb"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"By default the parser recognizes an infix syntax, but when this fails, it tries to read the formula with the [LBT](http://www.tcs.hut.fi/Software/maria/tools/lbt/) syntax:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"h = spot.formula('& | a b c'); h"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$c \\land (a \\lor b)$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 4,
"text": [
"c & (a | b)"
]
}
],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"By default, a formula object is presented using mathjax as above.\n",
"When a formula is converted to string you get Spot's syntax by default:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"str(f)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 5,
"text": [
"'p1 U (p2 R (p3 & !p4))'"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you prefer to print the string in another syntax, you may use the `to_str()` method, with an argument that indicates the output format to use. The `latex` format assumes that you will the define macros such as `\\U`, `\\R` to render all operators as you wish. On the otherhand, the `sclatex` (with `sc` for self-contained) format hard-codes the rendering of each of those operators: this is typically the output that is used to render formulas using MathJax in a notebook. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for i in ['spot', 'spin', 'lbt', 'wring', 'utf8', 'latex', 'sclatex']:\n",
" print(\"%-10s%s\" % (i, f.to_str(i)))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"spot p1 U (p2 R (p3 & !p4))\n",
"spin p1 U (p2 V (p3 && !p4))\n",
"lbt U p1 V p2 & p3 ! p4\n",
"wring (p1=1) U ((p2=1) R ((p3=1) * (p4=0)))\n",
"utf8 p1 U (p2 R (p3\u2227\u00acp4))\n",
"latex p_{1} \\U (p_{2} \\R (p_{3} \\land \\lnot p_{4}))\n",
"sclatex p_{1} \\mathbin{\\mathsf{U}} (p_{2} \\mathbin{\\mathsf{R}} (p_{3} \\land \\lnot p_{4}))\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Formulas output via `format()` can also use some convenient shorthand to select the syntax:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print(\"\"\"\\\n",
"Spin: {0:s}\n",
"Spin+parentheses: {0:sp}\n",
"Spot (default): {0}\n",
"Spot+shell quotes: {0:q}\n",
"LBT, right aligned: {0:l:~>40}\"\"\".format(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Spin: p1 U (p2 V (p3 && !p4))\n",
"Spin+parentheses: (p1) U ((p2) V ((p3) && (!(p4))))\n",
"Spot (default): p1 U (p2 R (p3 & !p4))\n",
"Spot+shell quotes: 'p1 U (p2 R (p3 & !p4))'\n",
"LBT, right aligned: ~~~~~~~~~~~~~~~~~~~~~U p1 V p2 & p3 ! p4\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The specifiers that can be used with `format` are documented as follows:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"help(spot.formula.__format__)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Help on function __format__ in module spot:\n",
"\n",
"__format__(self, spec)\n",
" Format the formula according to `spec`.\n",
" \n",
" Parameters\n",
" ----------\n",
" spec : str, optional\n",
" a list of letters that specify how the formula\n",
" should be formatted.\n",
" \n",
" Supported specifiers\n",
" --------------------\n",
" \n",
" - 'f': use Spot's syntax (default)\n",
" - '8': use Spot's syntax in UTF-8 mode\n",
" - 's': use Spin's syntax\n",
" - 'l': use LBT's syntax\n",
" - 'w': use Wring's syntax\n",
" - 'x': use LaTeX output\n",
" - 'X': use self-contained LaTeX output\n",
" \n",
" Add some of those letters for additional options:\n",
" \n",
" - 'p': use full parentheses\n",
" - 'c': escape the formula for CSV output (this will\n",
" enclose the formula in double quotes, and escape\n",
" any included double quotes)\n",
" - 'h': escape the formula for HTML output\n",
" - 'd': escape double quotes and backslash,\n",
" for use in C-strings (the outermost double\n",
" quotes are *not* added)\n",
" - 'q': quote and escape for shell output, using single\n",
" quotes or double quotes depending on the contents.\n",
" \n",
" - ':spec': pass the remaining specification to the\n",
" formating function for strings.\n",
"\n"
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A `spot.formula` object has a number of built-in predicates whose value have been computed when the formula was constructed. For instance you can check whether a formula is in negative normal form using `is_in_nenoform()`, and you can make sure it is an LTL formula (i.e. not a PSL formula) using `is_ltl_formula()`:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f.is_in_nenoform() and f.is_ltl_formula()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 9,
"text": [
"True"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"g.is_ltl_formula()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 10,
"text": [
"False"
]
}
],
"prompt_number": 10
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Similarly, `is_syntactic_stutter_invariant()` tells wether the structure of the formula guarranties it to be stutter invariant. For LTL formula, this means the `X` operator should not be used. For PSL formula, this function capture all formulas built using the [siPSL grammar](http://www.daxc.de/eth/paper/09atva.pdf)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f.is_syntactic_stutter_invariant()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 11,
"text": [
"True"
]
}
],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.formula('{a[*];b}<>->c').is_syntactic_stutter_invariant()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"text": [
"False"
]
}
],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.formula('{a[+];b[*]}<>->d').is_syntactic_stutter_invariant()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"text": [
"True"
]
}
],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`spot.relabel` renames the atomic propositions that occur in a formula, using either letters, or numbered propositions:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"gf = spot.formula('(GF_foo_) && \"a > b\" && \"proc[2]@init\"'); gf"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$``\\mathit{a > b}\\textrm{''} \\land ``\\mathit{proc[2]@init}\\textrm{''} \\land \\mathsf{G} \\mathsf{F} \\mathit{\\_foo\\_}$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 14,
"text": [
"\"a > b\" & \"proc[2]@init\" & GF_foo_"
]
}
],
"prompt_number": 14
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.relabel(gf, spot.Abc)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$a \\land b \\land \\mathsf{G} \\mathsf{F} c$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 15,
"text": [
"a & b & GFc"
]
}
],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.relabel(gf, spot.Pnn)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$p_{0} \\land p_{1} \\land \\mathsf{G} \\mathsf{F} p_{2}$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 16,
"text": [
"p0 & p1 & GFp2"
]
}
],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The AST of any formula can be displayed with `show_ast()`. Despite the name, this is not a tree but a DAG, because identical subtrees are merged. Binary operators have their left and right operands denoted with `L` and `R`, while non-commutative n-ary operators have their operands numbered."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print(g); g.show_ast()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{a;b[*];c[+]}<>-> GFb\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 17,
"svg": [
"<svg height=\"260pt\" viewBox=\"0.00 0.00 269.00 260.00\" width=\"269pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 256)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" points=\"-4,4 -4,-256 265,-256 265,4 -4,4\" stroke=\"none\"/>\n",
"<!-- 0 -->\n",
"<g class=\"node\" id=\"node1\"><title>0</title>\n",
"<ellipse cx=\"106\" cy=\"-234\" fill=\"none\" rx=\"40.8928\" ry=\"18\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"106\" y=\"-230.3\">EConcat</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g class=\"node\" id=\"node2\"><title>1</title>\n",
"<ellipse cx=\"155\" cy=\"-162\" fill=\"none\" rx=\"35.9954\" ry=\"18\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"155\" y=\"-158.3\">Concat</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g class=\"edge\" id=\"edge6\"><title>0-&gt;1</title>\n",
"<path d=\"M117.612,-216.411C123.593,-207.868 131.005,-197.278 137.649,-187.787\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"140.604,-189.669 143.471,-179.47 134.869,-185.655 140.604,-189.669\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"113.112\" y=\"-205.211\">L</text>\n",
"</g>\n",
"<!-- 7 -->\n",
"<g class=\"node\" id=\"node8\"><title>7</title>\n",
"<ellipse cx=\"58\" cy=\"-162\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"58\" y=\"-158.3\">G</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;7 -->\n",
"<g class=\"edge\" id=\"edge9\"><title>0-&gt;7</title>\n",
"<path d=\"M94.6247,-216.411C88.6815,-207.744 81.2945,-196.971 74.7146,-187.375\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"77.5052,-185.256 68.9633,-178.988 71.732,-189.215 77.5052,-185.256\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"89.6247\" y=\"-205.211\">R</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g class=\"node\" id=\"node3\"><title>2</title>\n",
"<polygon fill=\"none\" points=\"261,-36 207,-36 207,-0 261,-0 261,-36\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"234\" y=\"-14.3\">a</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge1\"><title>1-&gt;2</title>\n",
"<path d=\"M173.171,-146.485C184.356,-136.683 198.19,-122.858 207,-108 218.359,-88.8432 225.316,-64.4933 229.316,-46.1073\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"232.797,-46.5497 231.341,-36.0554 225.935,-45.1672 232.797,-46.5497\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"169.671\" y=\"-135.285\">1</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g class=\"node\" id=\"node4\"><title>3</title>\n",
"<ellipse cx=\"99\" cy=\"-90\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"99\" y=\"-86.3\">Star</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge3\"><title>1-&gt;3</title>\n",
"<path d=\"M142.293,-145.116C135.032,-136.04 125.792,-124.49 117.715,-114.393\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"120.252,-111.962 111.272,-106.34 114.786,-116.335 120.252,-111.962\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"138.793\" y=\"-133.916\">2</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g class=\"node\" id=\"node6\"><title>5</title>\n",
"<ellipse cx=\"171\" cy=\"-90\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"171\" y=\"-86.3\">Star</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge5\"><title>1-&gt;5</title>\n",
"<path d=\"M158.873,-144.055C160.655,-136.261 162.812,-126.822 164.811,-118.079\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"168.235,-118.804 167.051,-108.275 161.411,-117.244 168.235,-118.804\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"155.373\" y=\"-132.855\">3</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g class=\"node\" id=\"node5\"><title>4</title>\n",
"<polygon fill=\"none\" points=\"81,-36 27,-36 27,-0 81,-0 81,-36\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"54\" y=\"-14.3\">b</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge2\"><title>3-&gt;4</title>\n",
"<path d=\"M88.7888,-73.1159C83.4437,-64.8013 76.7639,-54.4105 70.6903,-44.9627\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"73.4681,-42.8113 65.1164,-36.2921 67.5799,-46.5966 73.4681,-42.8113\" stroke=\"black\"/>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g class=\"node\" id=\"node7\"><title>6</title>\n",
"<polygon fill=\"none\" points=\"189,-36 135,-36 135,-0 189,-0 189,-36\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"162\" y=\"-14.3\">c</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;6 -->\n",
"<g class=\"edge\" id=\"edge4\"><title>5-&gt;6</title>\n",
"<path d=\"M168.821,-72.055C167.83,-64.3456 166.632,-55.0269 165.518,-46.3642\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"168.968,-45.7473 164.221,-36.2753 162.025,-46.64 168.968,-45.7473\" stroke=\"black\"/>\n",
"</g>\n",
"<!-- 8 -->\n",
"<g class=\"node\" id=\"node9\"><title>8</title>\n",
"<ellipse cx=\"27\" cy=\"-90\" fill=\"none\" rx=\"27\" ry=\"18\" stroke=\"black\"/>\n",
"<text font-family=\"Times,serif\" font-size=\"14.00\" text-anchor=\"middle\" x=\"27\" y=\"-86.3\">F</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;8 -->\n",
"<g class=\"edge\" id=\"edge8\"><title>7-&gt;8</title>\n",
"<path d=\"M50.6534,-144.411C46.9858,-136.129 42.4667,-125.925 38.3646,-116.662\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"41.5434,-115.196 34.2938,-107.47 35.1429,-118.031 41.5434,-115.196\" stroke=\"black\"/>\n",
"</g>\n",
"<!-- 8&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge7\"><title>8-&gt;4</title>\n",
"<path d=\"M33.3986,-72.411C36.4351,-64.5386 40.1417,-54.9289 43.5695,-46.0421\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"46.9373,-47.0364 47.2705,-36.4468 40.4062,-44.5172 46.9373,-47.0364\" stroke=\"black\"/>\n",
"</g>\n",
"</g>\n",
"</svg>"
],
"text": [
"<IPython.core.display.SVG object>"
]
}
],
"prompt_number": 17
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.formula('F(a & X(!a & b))'); f"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$\\mathsf{F} (a \\land \\mathsf{X} (\\lnot a \\land b))$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 18,
"text": [
"F(a & X(!a & b))"
]
}
],
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Etessami's rule for removing X (valid only in stutter-invariant formulas)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.remove_x(f)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$\\mathsf{F} (a \\land ((a \\land (a \\mathbin{\\mathsf{U}} (\\lnot a \\land 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 b)) \\land ((\\lnot b \\mathbin{\\mathsf{U}} a) \\lor (b \\mathbin{\\mathsf{U}} a))) \\lor (b \\land (b \\mathbin{\\mathsf{U}} (\\lnot a \\land b \\land \\lnot 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 ((\\lnot a \\mathbin{\\mathsf{U}} b) \\lor (a \\mathbin{\\mathsf{U}} b))) \\lor (\\lnot a \\land b \\land (\\mathsf{G} \\lnot a \\lor \\mathsf{G} a) \\land (\\mathsf{G} \\lnot b \\lor \\mathsf{G} b))))$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 19,
"text": [
"F(a & ((a & (a U (!a & b)) & ((!b U !a) | (b U !a))) | (!a & (!a U (a & !a & b)) & ((!b U a) | (b U a))) | (b & (b U (!a & b & !b)) & ((!a U !b) | (a U !b))) | (!b & (!b U (!a & b)) & ((!a U b) | (a U b))) | (!a & b & (G!a | Ga) & (G!b | Gb))))"
]
}
],
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Removing abbreviated operators"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.formula(\"G(a xor b) -> F(a <-> b)\")\n",
"spot.unabbreviate(f, \"GF^\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$(\\bot \\mathbin{\\mathsf{R}} \\lnot (a \\leftrightarrow b)) \\rightarrow (\\top \\mathbin{\\mathsf{U}} (a \\leftrightarrow b))$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 20,
"text": [
"(0 R !(a <-> b)) -> (1 U (a <-> b))"
]
}
],
"prompt_number": 20
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.unabbreviate(f, \"GF^ei\")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"latex": [
"$(\\top \\mathbin{\\mathsf{U}} ((a \\land b) \\lor (\\lnot a \\land \\lnot b))) \\lor \\lnot (\\bot \\mathbin{\\mathsf{R}} ((\\lnot a \\land b) \\lor (a \\land \\lnot b)))$"
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 21,
"text": [
"(1 U ((a & b) | (!a & !b))) | !(0 R ((!a & b) | (a & !b)))"
]
}
],
"prompt_number": 21
}
],
"metadata": {}
}
]
}

61
python/tests/implies.py Executable file
View file

@ -0,0 +1,61 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2012 Laboratoire de Recherche et Développement
# de l'EPITA.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
from buddy import *
bdd_init(10000, 10000)
bdd_setvarnum(5)
V = [bdd_ithvar(i) for i in range(5)]
a = V[0] & V[1] & -V[2]
b = V[0] & V[1] & -V[2] & -V[3]
c = -V[0] & V[1] & -V[2] & -V[3]
d = V[1] & -V[2]
e = V[1] & V[2] & -V[3] & V[4]
f = V[0] & -V[3] & V[4]
g = -V[0] | V[1]
assert(bdd_implies(b,a))
assert(not bdd_implies(a,b))
assert(not bdd_implies(c,a))
assert(bdd_implies(a,d))
assert(bdd_implies(b,d))
assert(bdd_implies(c,d))
assert(bdd_implies(d,d))
assert(not bdd_implies(e,d))
assert(not bdd_implies(d,e))
assert(not bdd_implies(f,e))
assert(not bdd_implies(e,f))
assert(bdd_implies(bddfalse,f))
assert(not bdd_implies(bddtrue,f))
assert(bdd_implies(f,bddtrue))
assert(not bdd_implies(f,bddfalse))
assert(bdd_implies(a,g))
a = (-V[2] & (-V[1] | V[0])) | (-V[0] & V[1] & V[2])
b = V[1] | -V[2]
assert(bdd_implies(a,b))
# Cleanup all BDD variables before calling bdd_done(), otherwise
# bdd_delref will be called after bdd_done() and this is unsafe in
# optimized builds.
V = a = b = c = d = e = f = g = 0;
bdd_done()

58
python/tests/interdep.py Executable file
View file

@ -0,0 +1,58 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2010, 2012, 2014, 2015 Laboratoire de Recherche et
# Développement de l'EPITA.
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6
# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
# Pierre et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Make sure that interdependencies between the spot and buddy wrappers
# are not problematic.
import buddy
import spot
import sys
simp = spot.tl_simplifier()
e = spot.default_environment.instance()
p = spot.empty_parse_error_list()
f = spot.parse_infix_psl('GFa', p, e)
d = simp.get_dict()
a = spot.ltl_to_tgba_fm(f, d)
g = spot.parse_infix_boolean('b&c', p, e)
b = simp.as_bdd(g)
buddy.bdd_printset(b); spot.nl_cout()
del g
s0 = a.get_init_state()
it = a.succ_iter(s0)
it.first()
while not it.done():
c = it.cond()
sys.stdout.write("%s\n" % c)
b &= c # `&=' is defined only in buddy. So if this statement works
# it means buddy can grok spot's objects.
buddy.bdd_printset(c); spot.nl_cout()
it.next()
buddy.bdd_printset(b); spot.nl_cout()
sys.stdout.write("%s\n" % b)
del it
del s0
del b
del c
del f
del simp

261
python/tests/ipnbdoctest.py Executable file
View file

@ -0,0 +1,261 @@
#!/usr/bin/env python
"""
simple example script for running and testing notebooks.
Usage: `ipnbdoctest.py foo.ipynb [bar.ipynb [...]]`
Each cell is submitted to the kernel, and the outputs are compared
with those stored in the notebook.
"""
from __future__ import print_function
import os,sys,time
import base64
import re
from difflib import unified_diff as diff
from collections import defaultdict
try:
from queue import Empty
except ImportError:
print('Python 3.x is needed to run this script.')
sys.exit(77)
import imp
try:
imp.find_module('IPython')
except:
print('IPython is needed to run this script.')
sys.exit(77)
try:
from IPython.kernel import KernelManager
except ImportError:
from IPython.zmq.blockingkernelmanager import BlockingKernelManager as KernelManager
# Until Debian ships IPython 3.0, we stick to the v3 format.
from IPython.nbformat import v3 as nbformat
def compare_png(a64, b64):
"""compare two b64 PNGs (incomplete)"""
try:
import Image
except ImportError:
pass
adata = base64.decodestring(a64)
bdata = base64.decodestring(b64)
return True
def sanitize(s):
"""sanitize a string for comparison.
fix universal newlines, strip trailing newlines, and normalize likely
random values (memory addresses and UUIDs)
"""
if not isinstance(s, str):
return s
# normalize newline:
s = s.replace('\r\n', '\n')
# ignore trailing newlines (but not space)
s = s.rstrip('\n')
# remove hex addresses:
s = re.sub(r'at 0x[a-f0-9]+', 'object', s)
# normalize UUIDs:
s = re.sub(r'[a-f0-9]{8}(\-[a-f0-9]{4}){3}\-[a-f0-9]{12}', 'U-U-I-D', s)
# normalize graphviz version
s = re.sub(r'Generated by graphviz version.*', 'VERSION', s)
# ignore %timeit results
s = re.sub(r'^[0-9]+ loops, best of 3:.*per loop', '', s)
# SVG generated by graphviz may put note at different positions
# depending on the graphviz build. Let's just strip anything that
# look like a position.
s = re.sub(r'<path[^/]* d="[^"]*"', '<path', s)
s = re.sub(r'points="[^"]*"', 'points=""', s)
s = re.sub(r'x="[0-9.-]+"', 'x=""', s)
s = re.sub(r'y="[0-9.-]+"', 'y=""', s)
s = re.sub(r'width="[0-9.]+pt"', 'width=""', s)
s = re.sub(r'height="[0-9.]+pt"', 'height=""', s)
s = re.sub(r'viewBox="[0-9 .-]*"', 'viewbox=""', s)
s = re.sub(r'transform="[^"]*"', 'transform=""', s)
return s
def consolidate_outputs(outputs):
"""consolidate outputs into a summary dict (incomplete)"""
data = defaultdict(list)
data['stdout'] = ''
data['stderr'] = ''
for out in outputs:
if out.type == 'stream':
data[out.stream] += out.text
elif out.type == 'pyerr':
data['pyerr'] = dict(ename=out.ename, evalue=out.evalue)
else:
for key in ('png', 'svg', 'latex', 'html',
'javascript', 'text', 'jpeg',):
if key in out:
data[key].append(out[key])
return data
def compare_outputs(test, ref, skip_cmp=('png', 'traceback',
'latex', 'prompt_number')):
for key in ref:
if key not in test:
print("missing key: %s != %s" % (test.keys(), ref.keys()))
return False
elif key not in skip_cmp:
exp = sanitize(ref[key])
eff = sanitize(test[key])
if exp != eff:
print("mismatch %s:" % key)
if exp[:-1] != '\n':
exp += '\n'
if eff[:-1] != '\n':
eff += '\n'
print(''.join(diff(exp.splitlines(1), eff.splitlines(1),
fromfile='expected', tofile='effective')))
return False
return True
def _wait_for_ready_backport(kc):
"""Backport BlockingKernelClient.wait_for_ready from IPython 3"""
# Wait for kernel info reply on shell channel
kc.kernel_info()
while True:
msg = kc.get_shell_msg(block=True, timeout=30)
if msg['msg_type'] == 'kernel_info_reply':
break
# Flush IOPub channel
while True:
try:
msg = kc.get_iopub_msg(block=True, timeout=0.2)
except Empty:
break
def run_cell(kc, cell):
# print cell.input
kc.execute(cell.input)
# wait for finish, maximum 20s
kc.get_shell_msg(timeout=20)
outs = []
while True:
try:
msg = kc.get_iopub_msg(timeout=0.2)
except Empty:
break
msg_type = msg['msg_type']
if msg_type in ('status', 'pyin', 'execute_input'):
continue
elif msg_type == 'clear_output':
outs = []
continue
content = msg['content']
# print (msg_type, content)
if msg_type == 'execute_result':
msg_type = 'pyout'
elif msg_type == 'error':
msg_type = 'pyerr'
out = nbformat.NotebookNode(output_type=msg_type)
if msg_type == 'stream':
out.stream = content['name']
if 'text' in content:
out.text = content['text']
else:
out.text = content['data']
elif msg_type in ('display_data', 'pyout'):
out['metadata'] = content['metadata']
for mime, data in content['data'].items():
attr = mime.split('/')[-1].lower()
# this gets most right, but fix svg+html, plain
attr = attr.replace('+xml', '').replace('plain', 'text')
setattr(out, attr, data)
if 'execution_count' in content:
out.prompt_number = content['execution_count']
elif msg_type == 'pyerr':
out.ename = content['ename']
out.evalue = content['evalue']
out.traceback = content['traceback']
else:
print("unhandled iopub msg:", msg_type)
outs.append(out)
return outs
def test_notebook(nb):
km = KernelManager()
# Do not save the history to disk, as it can yield spurious lock errors.
# See https://github.com/ipython/ipython/issues/2845
km.start_kernel(extra_arguments=['--HistoryManager.hist_file=:memory:'],
stderr=open(os.devnull, 'w'))
kc = km.client()
kc.start_channels()
try:
kc.wait_for_ready()
except AttributeError:
_wait_for_ready_backport(kc)
successes = 0
failures = 0
errors = 0
for ws in nb.worksheets:
for i, cell in enumerate(ws.cells):
if cell.cell_type != 'code':
continue
try:
outs = run_cell(kc, cell)
except Exception as e:
print("failed to run cell:", repr(e))
print(cell.input)
errors += 1
continue
failed = False
if len(outs) != len(cell.outputs):
print("output length mismatch (expected {}, got {})".format(
len(cell.outputs), len(outs)))
failed = True
for out, ref in zip(outs, cell.outputs):
if not compare_outputs(out, ref):
failed = True
print("cell %d: " % i, end="")
if failed:
print("FAIL")
failures += 1
else:
print("OK")
successes += 1
print()
print("tested notebook %s" % nb.metadata.name)
print(" %3i cells successfully replicated" % successes)
if failures:
print(" %3i cells mismatched output" % failures)
if errors:
print(" %3i cells failed to complete" % errors)
kc.stop_channels()
km.shutdown_kernel()
del km
if failures | errors:
sys.exit(1)
if __name__ == '__main__':
for ipynb in sys.argv[1:]:
print("testing %s" % ipynb)
with open(ipynb) as f:
nb = nbformat.reads_json(f.read())
test_notebook(nb)

132
python/tests/ltl2tgba.py Executable file
View file

@ -0,0 +1,132 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2009, 2010, 2012, 2014, 2015 Laboratoire de Recherche et
# Développement de l'Epita (LRDE).
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is a python implementation of a small ltl2tgba translator that calls the
# translation and simplifications functions itself. It's better to use the
# translate() function today.
import sys
import getopt
import spot
def usage(prog):
sys.stderr.write("""Usage: %s [OPTIONS...] formula
Options:
-d turn on traces during parsing
-D degeneralize the automaton
-f use Couvreur's FM algorithm for translation
-t display reachable states in LBTT's format
-T use ltl2taa for translation
-v display the BDD variables used by the automaton
-W minimize obligation properties
""" % prog)
sys.exit(2)
prog = sys.argv[0]
try:
opts, args = getopt.getopt(sys.argv[1:], 'dDftTvW')
except getopt.GetoptError:
usage(prog)
exit_code = 0
debug_opt = False
degeneralize_opt = None
output = 0
fm_opt = 0
taa_opt = 0
wdba = 0
for o, a in opts:
if o == '-d':
debug_opt = True
elif o == '-D':
degeneralize_opt = 1
elif o == '-f':
fm_opt = 1
elif o == '-t':
output = 6
elif o == '-T':
taa_opt = 1
elif o == '-v':
output = 5
elif o == '-W':
wdba = 1
else:
usage(prog)
if len(args) != 1:
usage(prog)
cout = spot.get_cout()
cerr = spot.get_cerr()
e = spot.default_environment.instance()
p = spot.empty_parse_error_list()
f = spot.parse_infix_psl(args[0], p, e, debug_opt)
if spot.format_parse_errors(cerr, args[0], p):
exit_code = 1
dict = spot.make_bdd_dict()
if f:
if fm_opt:
a = spot.ltl_to_tgba_fm(f, dict)
concrete = 0
elif taa_opt:
a = concrete = spot.ltl_to_taa(f, dict)
else:
assert "unspecified translator"
if wdba:
a = spot.ensure_digraph(a)
a = spot.minimize_obligation(a, f)
del f
degeneralized = None
if degeneralize_opt:
a = degeneralized = spot.degeneralize(a)
if output == 0:
spot.print_dot(cout, a)
elif output == 5:
a.get_dict().dump(cout)
elif output == 6:
spot.print_lbtt(cout, a)
else:
assert "unknown output option"
if degeneralize_opt:
del degeneralized
# Must delete absolutely all references to an automaton
# so that the C++ destructor gets called.
del a, concrete
else:
exit_code = 1
del dict
assert spot.fnode_instances_check()

50
python/tests/ltl2tgba.test Executable file
View file

@ -0,0 +1,50 @@
#!/bin/sh
# Copyright (C) 2014 Laboratoire de Recherche et
# Développement de l'EPITA.
# Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
set -e
# We don't check the output, but just running these might be enough to
# trigger assertions.
./run $srcdir/ltl2tgba.py -T a
./run $srcdir/ltl2tgba.py -T 'a U b'
./run $srcdir/ltl2tgba.py -T 'X a'
./run $srcdir/ltl2tgba.py -T 'a & b & c'
./run $srcdir/ltl2tgba.py -T 'a | b | (c U (d & (g U (h ^ i))))'
./run $srcdir/ltl2tgba.py -T 'Xa & (b U !a) & (b U !a)'
./run $srcdir/ltl2tgba.py -T 'Fa & Xb & GFc & Gd'
./run $srcdir/ltl2tgba.py -T 'Fa & Xa & GFc & Gc'
./run $srcdir/ltl2tgba.py -T 'Fc & X(a | Xb) & GF(a | Xb) & Gc'
./run $srcdir/ltl2tgba.py -f a
./run $srcdir/ltl2tgba.py -f 'a U b'
./run $srcdir/ltl2tgba.py -f 'X a'
./run $srcdir/ltl2tgba.py -f 'a & b & c'
./run $srcdir/ltl2tgba.py -f 'a | b | (c U (d & (g U (h ^ i))))'
./run $srcdir/ltl2tgba.py -f 'Xa & (b U !a) & (b U !a)'
./run $srcdir/ltl2tgba.py -f 'Fa & Xb & GFc & Gd'
./run $srcdir/ltl2tgba.py -f 'Fa & Xa & GFc & Gc'
./run $srcdir/ltl2tgba.py -f 'Fc & X(a | Xb) & GF(a | Xb) & Gc'
./run $srcdir/ltl2tgba.py -W -f 'Ga | Gb | Gc'
./run $srcdir/ltl2tgba.py -W -T 'Ga | Gb | Gc'

45
python/tests/ltlparse.py Executable file
View file

@ -0,0 +1,45 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2009, 2010, 2012, 2014, 2015 Laboratoire de Recherche et
# Développement de l'Epita (LRDE).
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import spot
e = spot.default_environment.instance()
p = spot.empty_parse_error_list()
l = ['GFa', 'a U (((b)) xor c)', '!(FFx <=> Fx)', 'a \/ a \/ b \/ a \/ a'];
for str1 in l:
f = spot.parse_infix_psl(str1, p, e, False)
if spot.format_parse_errors(spot.get_cout(), str1, p):
sys.exit(1)
str2 = str(f)
del f
sys.stdout.write(str2 + "\n")
# Try to reparse the stringified formula
f = spot.parse_infix_psl(str2, p, e)
if spot.format_parse_errors(spot.get_cout(), str2, p):
sys.exit(1)
sys.stdout.write(str(f) + "\n")
del f
assert spot.fnode_instances_check()

118
python/tests/ltlsimple.py Executable file
View file

@ -0,0 +1,118 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2009, 2010, 2012, 2015 Laboratoire de Recherche et Développement
# de l'Epita (LRDE).
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systemes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import spot
import sys
#----------------------------------------------------------------------
a = spot.formula.ap('a')
b = spot.formula.ap('b')
c = spot.formula.ap('c')
c2 = spot.formula.ap('c')
assert c == c2
op = spot.formula.And([a, b])
op2 = spot.formula.And([op, c])
op3 = spot.formula.And([a, c, b])
assert op2 == op3
# The symbol for a subformula which hasn't been cloned is better
# suppressed, so we don't attempt to reuse it elsewhere.
del op, c
sys.stdout.write('op2 = %s\n' % str(op2))
del a, b, c2
sys.stdout.write('op3 = %s\n' % str(op3))
assert op2 == op3
op4 = spot.formula.Or([op2, op3])
sys.stdout.write('op4 = %s\n' % str(op4))
assert op4 == op2
del op2, op3, op4
#----------------------------------------------------------------------
a = spot.formula.ap('a')
b = spot.formula.ap('b')
c = spot.formula.ap('c')
T = spot.formula.tt()
F = spot.formula.ff()
f1 = spot.formula.Equiv(c, a)
f2 = spot.formula.Implies(a, b)
f3 = spot.formula.Xor(b, c)
f4 = spot.formula.Not(f3); del f3
f5 = spot.formula.Xor(F, c)
del a, b, c, T, F, f1, f2, f4, f5
assert spot.fnode_instances_check()
#----------------------------------------------------------------------
assert str([x for x in spot.formula('a &b & c')]) == '[a, b, c]'
def switch_g_f(x):
if x._is(spot.op_G):
return spot.formula.F(switch_g_f(x[0]))
if x._is(spot.op_F):
return spot.formula.G(switch_g_f(x[0]))
return x.map(switch_g_f)
f = spot.formula('GFa & XFGb & Fc & G(a | b | Fd)')
assert str(switch_g_f(f)) == 'FGa & XGFb & Gc & F(a | b | Gd)'
x = 0
def count_g(f):
global x
if f._is(spot.op_G):
x += 1
f.traverse(count_g)
assert x == 3
#----------------------------------------------------------------------
# The example from tut01.org
formula = spot.formula('a U b U "$strange[0]=name"')
res = """\
Default output: {f}
Spin syntax: {f:s}
(Spin syntax): {f:sp}
Default for shell: echo {f:q} | ...
LBT for shell: echo {f:lq} | ...
Default for CSV: ...,{f:c},...
Wring, centered: {f:w:~^50}""".format(f = formula)
assert res == """\
Default output: a U (b U "$strange[0]=name")
Spin syntax: a U (b U ($strange[0]=name))
(Spin syntax): (a) U ((b) U ($strange[0]=name))
Default for shell: echo 'a U (b U "$strange[0]=name")' | ...
LBT for shell: echo 'U "a" U "b" "$strange[0]=name"' | ...
Default for CSV: ...,"a U (b U ""$strange[0]=name"")",...
Wring, centered: ~~~~~(a=1) U ((b=1) U ("$strange[0]=name"=1))~~~~~"""

47
python/tests/minato.py Executable file
View file

@ -0,0 +1,47 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2010, 2012, 2013, 2014 Laboratoire de Recherche et
# Développement de l'Epita
# Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import buddy
import sys
buddy.bdd_init(10000, 10000)
buddy.bdd_setvarnum(3)
a = buddy.bdd_ithvar(0)
b = buddy.bdd_ithvar(1)
c = buddy.bdd_ithvar(2)
w = -a & -b | -c & b | a & -b
import spot
isop = spot.minato_isop(w)
i = isop.next()
l = []
while i != buddy.bddfalse:
buddy.bdd_printset(i)
spot.nl_cout()
l.append(i)
i = isop.next()
sys.exit(l == [-a, -c])

59
python/tests/optionmap.py Executable file
View file

@ -0,0 +1,59 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2010, 2012 Laboratoire de Recherche et Développement
# de l'EPITA.
# Copyright (C) 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import spot
o = spot.option_map()
res = o.parse_options("optA, opta=2M, optb =4 ; optB = 7\
, optC= 10")
assert not res
assert o.get('optA') == 1
assert o.get('opta') == 2*1024*1024
assert o.get('optb') == 4
assert o.get('optB') == 7
assert o.get('optC') == 10
assert o.get('none') == 0
assert o.get('none', 16) == 16
o.set('optb', 40)
assert o.get('optb') == 40
res = o.parse_options("!optA !optb optC, !optB")
assert not res
assert o.get('optA') == 0
assert o.get('opta') == 2*1024*1024
assert o.get('optb') == 0
assert o.get('optB') == 0
assert o.get('optC') == 1
res = o.parse_options("!")
assert res == "!"
res = o.parse_options("foo, !opt = 1")
assert res == "!opt = 1"
res = o.parse_options("foo=3, opt == 1")
assert res == "opt == 1"
res = o.parse_options("foo=3opt == 1")
assert res == "3opt == 1"

43
python/tests/parsetgba.py Executable file
View file

@ -0,0 +1,43 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2012, 2014, 2015 Laboratoire de Recherche et Développement
# de l'Epita (LRDE).
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import spot
contents = '''
HOA: v1 name: "a U b" States: 2 Start: 1 AP: 2 "a" "b" acc-name: Buchi
Acceptance: 1 Inf(0) properties: trans-labels explicit-labels state-acc
deterministic --BODY-- State: 0 {0} [t] 0 State: 1 [1] 0 [0&!1] 1 --END--
'''
filename = 'parsetgba.hoa'
out = open(filename, 'w+')
out.write(contents)
out.close()
a = spot.parse_aut(filename, spot.make_bdd_dict())
assert not a.errors
spot.print_dot(spot.get_cout(), a.aut)
del a
os.unlink(filename)

499
python/tests/piperead.ipynb Normal file
View file

@ -0,0 +1,499 @@
{
"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.4.3+"
},
"name": "",
"signature": "sha256:471d70bbd30f4ffde7ebceb35a8f4a1ca66baba3ad959b99d4bb72ef81e4d5cf"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.display import display \n",
"import spot\n",
"spot.setup()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Reading automata output from processes\n",
"\n",
"If an argument of `spot.automata` ends with `|`, then it is interpreted as a shell command that outputs one automaton or more."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for a in spot.automata('ltl2tgba -s \"a U b\"; ltl2tgba --lbtt \"b\"|', 'ltl2tgba -H \"GFa\" \"a & GFb\"|'):\n",
" display(a)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.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,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\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,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" 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.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f1084090540> >"
]
},
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.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,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" 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.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</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=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f1084090600> >"
]
},
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"82pt\" height=\"125pt\"\n",
" viewBox=\"0.00 0.00 82.00 125.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 121)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-121 78,-121 78,4 -4,4\"/>\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=\"M52.7643,-35.7817C52.2144,-45.3149 53.293,-54 56,-54 57.988,-54 59.0977,-49.3161 59.3292,-43.0521\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"59.2357,-35.7817 62.4756,-42.7406 59.2808,-39.2814 59.3258,-42.7812 59.3258,-42.7812 59.3258,-42.7812 59.2808,-39.2814 56.1761,-42.8217 59.2357,-35.7817 59.2357,-35.7817\"/>\n",
"<text text-anchor=\"start\" x=\"52.5\" y=\"-72.8\" font-family=\"Lato\" font-size=\"14.00\">a</text>\n",
"<text text-anchor=\"start\" x=\"48\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</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,-35.5771C47.5451,-56.718 49.2148,-84 56,-84 62.043,-84 64.0285,-62.3596 61.9564,-42.6907\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"61.0094,-35.5771 65.0556,-42.1002 61.4713,-39.0465 61.9332,-42.5159 61.9332,-42.5159 61.9332,-42.5159 61.4713,-39.0465 58.8107,-42.9316 61.0094,-35.5771 61.0094,-35.5771\"/>\n",
"<text text-anchor=\"start\" x=\"50.5\" y=\"-87.8\" font-family=\"Lato\" font-size=\"14.00\">!a</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f1084090540> >"
]
},
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"161pt\" height=\"125pt\"\n",
" viewBox=\"0.00 0.00 161.00 125.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 121)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-121 157,-121 157,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</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\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</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 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"135\" cy=\"-18\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"135\" y=\"-14.3\" font-family=\"Lato\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;0 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M74.0888,-18C84.5562,-18 98.1196,-18 109.693,-18\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"116.959,-18 109.959,-21.1501 113.459,-18 109.959,-18.0001 109.959,-18.0001 109.959,-18.0001 113.459,-18 109.959,-14.8501 116.959,-18 116.959,-18\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-21.8\" 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=\"M131.584,-35.7817C131.004,-45.3149 132.143,-54 135,-54 137.098,-54 138.27,-49.3161 138.514,-43.0521\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"138.416,-35.7817 141.66,-42.7383 138.463,-39.2814 138.511,-42.7811 138.511,-42.7811 138.511,-42.7811 138.463,-39.2814 135.361,-42.8239 138.416,-35.7817 138.416,-35.7817\"/>\n",
"<text text-anchor=\"start\" x=\"130.5\" y=\"-72.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"<text text-anchor=\"start\" x=\"127\" y=\"-57.8\" font-family=\"Lato\" font-size=\"14.00\" fill=\"#5da5da\">\u24ff</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=\"M129.769,-35.249C126.057,-56.4346 127.801,-84 135,-84 141.412,-84 143.496,-62.1347 141.253,-42.3851\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"140.231,-35.249 144.342,-41.7316 140.727,-38.7137 141.223,-42.1783 141.223,-42.1783 141.223,-42.1783 140.727,-38.7137 138.105,-42.625 140.231,-35.249 140.231,-35.249\"/>\n",
"<text text-anchor=\"start\" x=\"128.5\" y=\"-87.8\" font-family=\"Lato\" font-size=\"14.00\">!b</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f1084090600> >"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A single automaton can be read using `spot.automaton()`, with the same convention."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.automaton('ltl2tgba -s6 \"a U b\"|')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 0 -->\n",
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.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,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\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,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" 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.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f10840a0570> >"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Error handling\n",
"\n",
"If the shell command terminates with a non-zero exit status, we should get an exception."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.automaton('non-existing-command|')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "CalledProcessError",
"evalue": "Command 'non-existing-command' returned non-zero exit status 127",
"output_type": "pyerr",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mCalledProcessError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-4-765c7cc6937f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mspot\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautomaton\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'non-existing-command|'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomaton\u001b[0;34m(filename, **kwargs)\u001b[0m\n\u001b[1;32m 404\u001b[0m See `spot.automata` for a list of supported formats.\"\"\"\n\u001b[1;32m 405\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 406\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mautomata\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 407\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 408\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Failed to read automaton from {}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomata\u001b[0;34m(timeout, *sources)\u001b[0m\n\u001b[1;32m 395\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mproc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 396\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 397\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0msubprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCalledProcessError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfilename\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 398\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 399\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mCalledProcessError\u001b[0m: Command 'non-existing-command' returned non-zero exit status 127"
]
}
],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for a in spot.automata(\"ltl2tgba -H 'a U b'|\", 'ltl2tgba -f \"syntax U U error\"|'):\n",
" display(a)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"37.5\" y=\"-61.8\" font-family=\"Lato\" font-size=\"14.00\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 0 -->\n",
"<g id=\"node3\" class=\"node\"><title>0</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M74.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</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=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f10840a00c0> >"
]
},
{
"ename": "CalledProcessError",
"evalue": "Command 'ltl2tgba -f \"syntax U U error\"' returned non-zero exit status 2",
"output_type": "pyerr",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mCalledProcessError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-5-21a24ff75c32>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0ma\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mspot\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautomata\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"ltl2tgba -H 'a U b'|\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'ltl2tgba -f \"syntax U U error\"|'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mdisplay\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomata\u001b[0;34m(timeout, *sources)\u001b[0m\n\u001b[1;32m 395\u001b[0m \u001b[0;32mdel\u001b[0m \u001b[0mproc\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 396\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 397\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0msubprocess\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCalledProcessError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfilename\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 398\u001b[0m \u001b[0;32mreturn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 399\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mCalledProcessError\u001b[0m: Command 'ltl2tgba -f \"syntax U U error\"' returned non-zero exit status 2"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reading an empty file with `spot.automaton()` is an error."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.automaton('true|')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"ename": "RuntimeError",
"evalue": "Failed to read automaton from true|",
"output_type": "pyerr",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-6-f4e056a50029>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mspot\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautomaton\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'true|'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/home/adl/git/spot/wrap/python/spot.py\u001b[0m in \u001b[0;36mautomaton\u001b[0;34m(filename, **kwargs)\u001b[0m\n\u001b[1;32m 406\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mnext\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mautomata\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 407\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mStopIteration\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 408\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Failed to read automaton from {}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 409\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 410\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mRuntimeError\u001b[0m: Failed to read automaton from true|"
]
}
],
"prompt_number": 6
}
],
"metadata": {}
}
]
}

2001
python/tests/product.ipynb Normal file

File diff suppressed because it is too large Load diff

2285
python/tests/randaut.ipynb Normal file

File diff suppressed because it is too large Load diff

26
python/tests/randgen.py Executable file
View file

@ -0,0 +1,26 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2015 Laboratoire de Recherche et Développement de
# l'Epita (LRDE).
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import spot
o = spot.option_map()
g = spot.randltlgenerator(0, o)
assert str(g.next()) == '1'
assert str(g.next()) == '0'
assert str(g.next()) == 'None'

677
python/tests/randltl.ipynb Normal file
View file

@ -0,0 +1,677 @@
{
"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.4.3+"
},
"name": "",
"signature": "sha256:c1de5aacd024bbec64b75f61a13e53562185c906051312d9ce5067236b7899d4"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Documentation for spot's randltl python binding"
]
},
{
"cell_type": "code",
"collapsed": true,
"input": [
"import spot"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Basic usage"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generate random formulas from specified atomic propositions:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(['a', 'b', 'c'])\n",
"for i in range(3):\n",
" print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"0 R b\n",
"F(XG(F!b M Fb) W (b R a))\n"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generate random formulas using 3 atomic propositions:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3)\n",
"for i in range(3):\n",
" print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"0 R p1\n",
"F(XG(F!p1 M Fp1) W (p1 R p0))\n"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"By default, there is no limit to the number of formulas generated.<br/>\n",
"To specify a number of formulas:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, 4)\n",
"for formula in f:\n",
" print(formula)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"0 R p1\n",
"F(XG(F!p1 M Fp1) W (p1 R p0))\n",
"F(p0 R !p2)\n"
]
}
],
"prompt_number": 4
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Keyword arguments"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"seed"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Seed for the pseudo random number generator (default: 0)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, seed=11)\n",
"print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"G(p1 U Gp0)\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"output"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Type of formulas to output: 'ltl', 'psl', 'bool' or 'sere' (default: 'ltl')."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, output='psl', seed=332)\n",
"print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{{p0 && p2}[*]}<>-> (Fp2 & Fp0)\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"allow_dups"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Allow duplicate formulas (default: False)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(1, allow_dups=True)\n",
"print(next(f))\n",
"print(next(f))\n",
"print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"0\n",
"Fp0\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"tree_size"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tree size of the formulas generated, before mandatory simplifications (default: 15)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, tree_size=30, seed=11)\n",
"print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"G(((p0 U !Xp1) M Gp1) U Gp0)\n"
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A range can be specified as a tuple:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, tree_size=(1, 40))\n",
"print(next(f))\n",
"print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"X!(Gp1 M p2) R (!p2 M Xp1)\n",
"F(G(F(Gp0 R (1 U Fp2)) M (p2 -> Gp0)) M F((p0 | Fp0) W Gp2))\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"boolean_priorities, ltl_priorities, sere_priorities, dump_priorities"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, output='bool', boolean_priorities='and=10,or=0')\n",
"for i in range(5):\n",
" print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"!p2 & (p1 <-> p2)\n",
"p2\n",
"p0 & ((p1 & p2) <-> !(!p0 & p1 & p2))\n",
"1\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To see which operators are available along with their default priorities:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.randltl(3, output='psl', dump_priorities=True)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Use argument ltl_priorities=STRING to set the following LTL priorities:\n",
"\n",
"ap\t3\n",
"false\t1\n",
"true\t1\n",
"not\t1\n",
"F\t1\n",
"G\t1\n",
"X\t1\n",
"Closure\t1\n",
"equiv\t1\n",
"implies\t1\n",
"xor\t1\n",
"R\t1\n",
"U\t1\n",
"W\t1\n",
"M\t1\n",
"and\t1\n",
"or\t1\n",
"EConcat\t1\n",
"UConcat\t1\n",
"\n",
"Use argument sere_priorities=STRING to set the following SERE priorities:\n",
"\n",
"ap\t3\n",
"false\t1\n",
"true\t1\n",
"not\t1\n",
"F\t1\n",
"G\t1\n",
"X\t1\n",
"Closure\t1\n",
"equiv\t1\n",
"implies\t1\n",
"xor\t1\n",
"R\t1\n",
"U\t1\n",
"W\t1\n",
"M\t1\n",
"and\t1\n",
"or\t1\n",
"EConcat\t1\n",
"UConcat\t1\n",
"eword\t1\n",
"boolform\t1\n",
"star\t1\n",
"star_b\t1\n",
"fstar\t1\n",
"fstar_b\t1\n",
"and\t1\n",
"andNLM\t1\n",
"or\t1\n",
"concat\t1\n",
"fusion\t1\n",
"\n",
"Use argument boolean_priorities=STRING to set the following Boolean formula priorities:\n",
"\n",
"ap\t3\n",
"false\t1\n",
"true\t1\n",
"not\t1\n",
"F\t1\n",
"G\t1\n",
"X\t1\n",
"Closure\t1\n",
"equiv\t1\n",
"implies\t1\n",
"xor\t1\n",
"R\t1\n",
"U\t1\n",
"W\t1\n",
"M\t1\n",
"and\t1\n",
"or\t1\n",
"EConcat\t1\n",
"UConcat\t1\n",
"eword\t1\n",
"boolform\t1\n",
"star\t1\n",
"star_b\t1\n",
"fstar\t1\n",
"fstar_b\t1\n",
"and\t1\n",
"andNLM\t1\n",
"or\t1\n",
"concat\t1\n",
"fusion\t1\n",
"ap\t3\n",
"false\t1\n",
"true\t1\n",
"not\t1\n",
"equiv\t1\n",
"implies\t1\n",
"xor\t1\n",
"and\t1\n",
"or\t1\n",
"\n"
]
}
],
"prompt_number": 11
},
{
"cell_type": "heading",
"level": 3,
"metadata": {},
"source": [
"simplify"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"0 No rewriting<br/>\n",
"1 basic rewritings and eventual/universal rules<br/>\n",
"2 additional syntactic implication rules<br/>\n",
"3 better implications using containment<br/>\n",
"default: 3"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, simplify=0, seed=5)\n",
"print(next(f))\n",
"f = spot.randltl(3, simplify=3, seed=5)\n",
"print(next(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"G!(!p1 & (Xp2 | F(p0 R Xp2)))\n",
"G(p1 | (X!p2 & G(!p0 U X!p2)))\n"
]
}
],
"prompt_number": 12
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Filters and maps"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"most boolean functions found in the class formula can be used to filter the random formula generator like this:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, 20).is_syntactic_stutter_invariant()\n",
"for formula in f:\n",
" print(formula)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"0 R p2\n",
"F(p0 R !p1)\n",
"G(p0 | Fp2) W (FGp2 R !p2)\n",
"(p2 R G!p1) | G(p2 U !p0)\n",
"(p2 W p0) U p2\n",
"F!G(!Gp1 W p1)\n",
"G!p1 & (!((p2 & Fp1) M p1) U p1)\n"
]
}
],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"likewise, functions from formula to formula can be applied to map the iterator:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(2, 6).remove_x()\n",
"for formula in f:\n",
" print(formula)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"!(F!p1 M 1)\n",
"(Gp0 | Fp1) M 1\n",
"F!(!p1 <-> FGp1)\n",
"Gp1 U (p1 U GFp1)\n",
"(!p1 U p1) U ((p0 & (p0 U (!p0 & (!p0 -> Fp1))) & ((!p1 U !p0) | (p1 U !p0))) | (!p0 & (!p0 U (p0 & (!p0 -> Fp1))) & ((!p1 U p0) | (p1 U p0))) | (p1 & (p1 U (!p1 & (!p0 -> Fp1))) & ((!p0 U !p1) | (p0 U !p1))) | (!p1 & (!p1 U (p1 & (!p0 -> Fp1))) & ((!p0 U p1) | (p0 U p1))) | ((!p0 -> Fp1) & (Gp0 | G!p0) & (Gp1 | G!p1)))\n"
]
}
],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since the boolean filters and mapping functions return an iterator of the same type, these operations can be chained like this:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.randltl(3, 20).is_syntactic_stutter_invariant().relabel(spot.Abc).simplify()\n",
"for formula in f:\n",
" print(formula)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"Ga\n",
"F(a R !b)\n",
"G(a | Fb) | (FGb R !b)\n",
"G!b | G(a U !c)\n",
"b U a\n",
"0\n",
"0\n"
]
}
],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for formula in spot.randltl(3, 10).simplify().unabbreviate(\"WMGFR\"): print(formula)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"0\n",
"!(1 U !p1)\n",
"1 U ((p0 U ((p0 & p1) | !(1 U !p0))) | !(1 U !((1 U !p1) & (1 U p1))))\n",
"1 U (!p2 U ((p0 & !p2) | !(1 U p2)))\n",
"(!p1 U ((!p1 & (1 U !(1 U !p1))) | !(1 U p1))) | !(1 U !(p0 | (1 U p1)))\n",
"X(p2 & X(p2 U (!p0 | !(1 U !p2))))\n",
"(1 U p2) | (X(!p2 | !(1 U !p2)) U ((1 U p2) U (!p1 & (1 U p2))))\n",
"XX!(1 U !((X!p1 U (!p2 U (!p0 & !p2))) | X!(1 U !p0)))\n",
"XX(1 U (p1 U ((p0 & p1) | !(1 U !p1))))\n",
"p2 & Xp0\n"
]
}
],
"prompt_number": 16
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
}
],
"metadata": {}
}
]
}

32
python/tests/relabel.py Normal file
View file

@ -0,0 +1,32 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2015 Laboratoire de Recherche et Développement
# de l'Epita
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import spot
f = spot.formula('GF(a & b) -> (FG(a & b) & Gc)')
m = spot.relabeling_map()
g = spot.relabel_bse(f, spot.Pnn, m)
res = ""
for old, new in m.items():
res += "#define {} {}\n".format(old, new)
res += str(g)
print(res)
assert(res == """#define p0 a & b
#define p1 c
GFp0 -> (FGp0 & Gp1)""")

49
python/tests/remfin.py Normal file
View file

@ -0,0 +1,49 @@
import spot
# This test used to trigger an assertion (or a segfault)
# in scc_filter_states().
aut = spot.automaton("""
HOA: v1
States: 3
Start: 1
AP: 1 "a"
Acceptance: 1 Inf(0)
--BODY--
State: 0 {0}
[t] 0
State: 1
[!0] 0
[0] 2
State: 2
[t] 2
--END--
""")
aut.prop_inherently_weak(True)
aut = spot.dtwa_complement(aut)
aut1 = spot.scc_filter_states(aut)
assert(aut1.to_str('hoa') == """HOA: v1
States: 2
Start: 0
AP: 1 "a"
acc-name: co-Buchi
Acceptance: 1 Fin(0)
properties: trans-labels explicit-labels state-acc deterministic
properties: inherently-weak
--BODY--
State: 0
[0] 1
State: 1
[t] 1
--END--""")
assert(aut.scc_filter_states().to_str() == aut1.to_str())
assert(aut1.get_name() == None)
aut1.set_name("test me")
assert(aut1.get_name() == "test me")
# The method is the same as the function
a = spot.translate('true', 'low', 'any')
assert(a.prop_deterministic() == False)
assert(a.prop_unambiguous() == False)
assert(a.is_deterministic() == True)
assert(a.is_unambiguous() == True)

56
python/tests/run.in Executable file
View file

@ -0,0 +1,56 @@
#!/bin/sh
# -*- coding: utf-8 -*-
# Copyright (C) 2010, 2011, 2014, 2015 Laboratoire de Recherche et
# Developpement de l'EPITA (LRDE).
# Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6
# (LIP6), département Systèmes Répartis Coopératifs (SRC), Université
# Pierre et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Darwin needs some help in figuring out where non-installed libtool
# libraries are (on this platform libtool encodes the expected final
# path of dependent libraries in each library).
modpath='../.libs:@top_builddir@/spot/.libs:@top_builddir@/buddy/spot/.libs'
# .. is for the *.py files, and ../.libs for the *.so. We used to
# rely on a module called ltihooks.py to teach the import function how
# to load a Libtool library, but it started to cause issues with
# Python 2.6.
pypath='..:../.libs:@srcdir@/..:@srcdir@/../.libs:$PYTHONPATH'
PATH="@abs_top_builddir@/spot/bin:$PATH"
export PATH
test -z "$1" &&
PYTHONPATH=$pypath DYLD_LIBRARY_PATH=$modpath exec @PYTHON@
case $1 in
*.ipynb)
PYTHONPATH=$pypath DYLD_LIBRARY_PATH=$modpath \
exec $PREFIXCMD @PYTHON@ @srcdir@/ipnbdoctest.py "$@";;
*.py)
PYTHONPATH=$pypath DYLD_LIBRARY_PATH=$modpath \
exec $PREFIXCMD @PYTHON@ "$@";;
*.test)
exec sh -x "$@";;
*python*)
PYTHONPATH=$pypath DYLD_LIBRARY_PATH=$modpath \
exec $PREFIXCMD "$@";;
*)
echo "Unknown extension" >&2
exit 2;;
esac

49
python/tests/satmin.py Normal file
View file

@ -0,0 +1,49 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2015 Laboratoire de Recherche et Développement
# de l'Epita
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import shutil
import sys
import spot
# Ignore the test if glucose is not installed.
if shutil.which("glucose") == None:
sys.exit(77)
aut = spot.translate('GFa & GFb', 'BA')
assert aut.num_sets() == 1
assert aut.num_states() == 3
assert aut.is_deterministic()
min1 = spot.sat_minimize(aut, acc='Rabin 1')
assert min1.num_sets() == 2
assert min1.num_states() == 2
min2 = spot.sat_minimize(aut, acc='Streett 2', dichotomy=True)
assert min2.num_sets() == 4
assert min2.num_states() == 1
min3 = spot.sat_minimize(aut, acc='Rabin 2',
state_based=True, max_states=5, dichotomy=True)
assert min3.num_sets() == 4
assert min3.num_states() == 3
min4 = spot.sat_minimize(aut, acc='parity max odd 3',
colored=True, dichotomy=True)
assert min4.num_sets() == 3
assert min4.num_states() == 2

49
python/tests/setxor.py Executable file
View file

@ -0,0 +1,49 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2010, 2011 Laboratoire de Recherche et Développement
# de l'EPITA.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
from buddy import *
bdd_init(10000, 10000)
bdd_setvarnum(5)
V = [bdd_ithvar(i) for i in range(5)]
a = V[0] & -V[1] & V[2] & -V[3]
b = V[0] & V[1] & V[2] & -V[3]
c = -V[0] & V[1] & -V[2] & -V[3]
assert(c == bdd_setxor(a,b))
assert(c == bdd_setxor(b,a))
assert(a == bdd_setxor(b,c))
assert(a == bdd_setxor(c,b))
assert(b == bdd_setxor(a,c))
assert(b == bdd_setxor(c,a))
d = V[1] & V[2] & -V[3] & V[4]
e = V[0] & V[1] & -V[2] & -V[3] & V[4]
assert(e == bdd_setxor(a,d))
assert(e == bdd_setxor(d,a))
# Cleanup all BDD variables before calling bdd_done(), otherwise
# bdd_delref will be called after bdd_done() and this is unsafe in
# optimized builds.
V = a = b = c = d = e = 0;
bdd_done()

View file

@ -0,0 +1,651 @@
{
"metadata": {
"name": "",
"signature": "sha256:1a85b698ebae51aaba0387d782d1cf5c6cdf54f69dd6b4b9c7189f8676eb4c88"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.display import display, HTML\n",
"import spot\n",
"spot.setup()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To translate a formula into a Testing Automaton\n",
"\n",
"Start by building a Buchi automaton"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f = spot.formula('a U Gb')\n",
"a = f.translate('ba')\n",
"a"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 2,
"svg": [
"<?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=\"171pt\" height=\"85pt\"\n",
" viewBox=\"0.00 0.00 171.00 85.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 81)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-81 167,-81 167,4 -4,4\"/>\n",
"<!-- I -->\n",
"<!-- 1 -->\n",
"<g id=\"node2\" class=\"node\"><title>1</title>\n",
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"56\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"56\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- I&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>I&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1.15491,-22C2.79388,-22 17.1543,-22 30.6317,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"37.9419,-22 30.9419,-25.1501 34.4419,-22 30.9419,-22.0001 30.9419,-22.0001 30.9419,-22.0001 34.4419,-22 30.9418,-18.8501 37.9419,-22 37.9419,-22\"/>\n",
"</g>\n",
"<!-- 1&#45;&gt;1 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>1&#45;&gt;1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M49.6208,-39.0373C48.3189,-48.8579 50.4453,-58 56,-58 60.166,-58 62.4036,-52.8576 62.7128,-46.1433\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"62.3792,-39.0373 65.8541,-45.8818 62.5434,-42.5335 62.7076,-46.0296 62.7076,-46.0296 62.7076,-46.0296 62.5434,-42.5335 59.561,-46.1774 62.3792,-39.0373 62.3792,-39.0373\"/>\n",
"<text text-anchor=\"start\" x=\"52.5\" y=\"-61.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=\"141\" cy=\"-22\" rx=\"18\" ry=\"18\"/>\n",
"<ellipse fill=\"none\" stroke=\"black\" cx=\"141\" cy=\"-22\" rx=\"22\" ry=\"22\"/>\n",
"<text text-anchor=\"middle\" x=\"141\" y=\"-18.3\" font-family=\"Lato\" font-size=\"14.00\">0</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=\"M74.1977,-22C85.0734,-22 99.3874,-22 111.887,-22\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"118.997,-22 111.997,-25.1501 115.497,-22 111.997,-22.0001 111.997,-22.0001 111.997,-22.0001 115.497,-22 111.997,-18.8501 118.997,-22 118.997,-22\"/>\n",
"<text text-anchor=\"start\" x=\"92\" y=\"-25.8\" font-family=\"Lato\" font-size=\"14.00\">b</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=\"M132.994,-42.5808C131.886,-52.8447 134.555,-62 141,-62 145.834,-62 148.544,-56.8502 149.129,-49.9451\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.006,-42.5808 152.273,-49.5273 149.065,-46.0803 149.123,-49.5798 149.123,-49.5798 149.123,-49.5798 149.065,-46.0803 145.973,-49.6324 149.006,-42.5808 149.006,-42.5808\"/>\n",
"<text text-anchor=\"start\" x=\"136.5\" y=\"-65.8\" font-family=\"Lato\" font-size=\"14.00\">b</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text": [
"<spot_impl.twa_graph; proxy of <Swig Object of type 'std::shared_ptr< spot::twa_graph > *' at 0x7f2e817bf6c0> >"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, gather all the atomic proposition in the formula, and create an automaton with changesets"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"propset = spot.atomic_prop_collect_as_bdd(f, a)\n",
"ta = spot.tgba_to_ta(a, propset, True, True, False, False, True)\n",
"ta.show('.A')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"svg": [
"<svg height=\"295pt\" viewBox=\"0.00 0.00 734.00 295.42\" width=\"734pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g class=\"graph\" id=\"graph0\" transform=\"scale(0.749788 0.749788) rotate(0) translate(4 390)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" points=\"-4,4 -4,-390 974.944,-390 974.944,4 -4,4\" stroke=\"none\"/>\n",
"<!-- 0 -->\n",
"<!-- 1 -->\n",
"<g class=\"node\" id=\"node2\"><title>1</title>\n",
"<ellipse cx=\"62.6978\" cy=\"-256\" fill=\"#ffffaa\" rx=\"24.8972\" ry=\"24.8972\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"62.6978\" y=\"-252.3\">init</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g class=\"edge\" id=\"edge1\"><title>0-&gt;1</title>\n",
"<path d=\"M1.04399,-256C1.93865,-256 16.3331,-256 30.8732,-256\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"37.9642,-256 30.9643,-259.15 34.4642,-256 30.9642,-256 30.9642,-256 30.9642,-256 34.4642,-256 30.9642,-252.85 37.9642,-256 37.9642,-256\" stroke=\"black\"/>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g class=\"node\" id=\"node3\"><title>2</title>\n",
"<ellipse cx=\"482.365\" cy=\"-190\" fill=\"#ffffaa\" rx=\"37.4533\" ry=\"37.4533\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"482.365\" y=\"-193.8\">1</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"482.365\" y=\"-178.8\">!a &amp; b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge2\"><title>1-&gt;2</title>\n",
"<path d=\"M80.0021,-274.105C115.083,-310.768 201.199,-388.632 283.106,-368 356.606,-349.486 378.744,-332.757 424.06,-272 434.518,-257.978 432.39,-251.576 442.06,-237 445.119,-232.388 448.559,-227.709 452.097,-223.181\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"456.612,-217.543 454.696,-224.976 454.424,-220.275 452.237,-223.008 452.237,-223.008 452.237,-223.008 454.424,-220.275 449.778,-221.039 456.612,-217.543 456.612,-217.543\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"264.606\" y=\"-374.8\">!a &amp; b</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g class=\"node\" id=\"node4\"><title>3</title>\n",
"<ellipse cx=\"192.751\" cy=\"-152\" fill=\"#ffffaa\" rx=\"35.2113\" ry=\"35.2113\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"192.751\" y=\"-155.8\">1</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"192.751\" y=\"-140.8\">a &amp; b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge3\"><title>1-&gt;3</title>\n",
"<path d=\"M82.3178,-240.878C102.354,-224.605 134.612,-198.406 158.925,-178.66\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"164.609,-174.044 161.161,-180.902 161.892,-176.25 159.175,-178.457 159.175,-178.457 159.175,-178.457 161.892,-176.25 157.189,-176.012 164.609,-174.044 164.609,-174.044\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"122.396\" y=\"-223.8\">a &amp; b</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g class=\"node\" id=\"node5\"><title>4</title>\n",
"<ellipse cx=\"338.583\" cy=\"-205\" fill=\"#ffffaa\" rx=\"37.4533\" ry=\"37.4533\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"338.583\" y=\"-208.8\">1</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"338.583\" y=\"-193.8\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge4\"><title>1-&gt;4</title>\n",
"<path d=\"M87.1814,-252.544C119.148,-247.749 178.107,-238.579 228.106,-229 250.158,-224.775 274.574,-219.483 294.742,-214.943\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"301.687,-213.372 295.555,-217.989 298.274,-214.145 294.86,-214.917 294.86,-214.917 294.86,-214.917 298.274,-214.145 294.165,-211.844 301.687,-213.372 301.687,-213.372\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"192.751\" y=\"-245.8\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g class=\"node\" id=\"node6\"><title>5</title>\n",
"<ellipse cx=\"628.025\" cy=\"-158\" fill=\"#ffffaa\" rx=\"35.2259\" ry=\"35.2259\" stroke=\"black\"/>\n",
"<ellipse cx=\"628.025\" cy=\"-158\" fill=\"none\" rx=\"39.2112\" ry=\"39.2112\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"628.025\" y=\"-161.8\">0</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"628.025\" y=\"-146.8\">a &amp; b</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge5\"><title>2-&gt;5</title>\n",
"<path d=\"M519.246,-182.008C538.352,-177.752 562.03,-172.478 582.322,-167.958\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"589.345,-166.393 583.198,-170.99 585.929,-167.154 582.513,-167.915 582.513,-167.915 582.513,-167.915 585.929,-167.154 581.828,-164.84 589.345,-166.393 589.345,-166.393\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"555.67\" y=\"-180.8\">{a}</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g class=\"node\" id=\"node7\"><title>6</title>\n",
"<ellipse cx=\"774.857\" cy=\"-158\" fill=\"#ffffaa\" rx=\"37.4556\" ry=\"37.4556\" stroke=\"black\"/>\n",
"<ellipse cx=\"774.857\" cy=\"-158\" fill=\"none\" rx=\"41.4533\" ry=\"41.4533\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"774.857\" y=\"-161.8\">0</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"774.857\" y=\"-146.8\">!a &amp; b</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;6 -->\n",
"<g class=\"edge\" id=\"edge6\"><title>2-&gt;6</title>\n",
"<path d=\"M514.661,-209.497C551.574,-229.937 614.593,-256.796 667.38,-239 694.942,-229.708 721.017,-210.125 740.465,-192.542\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"745.771,-187.646 742.763,-194.708 743.199,-190.02 740.627,-192.393 740.627,-192.393 740.627,-192.393 743.199,-190.02 738.49,-190.078 745.771,-187.646 745.771,-187.646\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"628.025\" y=\"-248.8\">{}</text>\n",
"</g>\n",
"<!-- 7 -->\n",
"<g class=\"node\" id=\"node8\"><title>7</title>\n",
"<ellipse cx=\"926.639\" cy=\"-61\" fill=\"#ffffaa\" rx=\"37.4556\" ry=\"37.4556\" stroke=\"black\"/>\n",
"<ellipse cx=\"926.639\" cy=\"-61\" fill=\"none\" rx=\"41.4533\" ry=\"41.4533\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"926.639\" y=\"-64.8\">0</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"926.639\" y=\"-49.8\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;7 -->\n",
"<g class=\"edge\" id=\"edge7\"><title>2-&gt;7</title>\n",
"<path d=\"M510.516,-164.88C530.742,-147.339 559.75,-124.548 588.67,-110 683.063,-62.5163 809.91,-57.452 877.879,-58.7202\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"885.07,-58.8824 878.001,-61.8737 881.571,-58.8034 878.072,-58.7245 878.072,-58.7245 878.072,-58.7245 881.571,-58.8034 878.143,-55.5753 885.07,-58.8824 885.07,-58.8824\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"700.38\" y=\"-80.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 8 -->\n",
"<g class=\"node\" id=\"node9\"><title>8</title>\n",
"<ellipse cx=\"926.639\" cy=\"-289\" fill=\"#ffffaa\" rx=\"40.1285\" ry=\"40.1285\" stroke=\"black\"/>\n",
"<ellipse cx=\"926.639\" cy=\"-289\" fill=\"none\" rx=\"44.111\" ry=\"44.111\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"926.639\" y=\"-292.8\">0</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"926.639\" y=\"-277.8\">!a &amp; !b</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;8 -->\n",
"<g class=\"edge\" id=\"edge8\"><title>2-&gt;8</title>\n",
"<path d=\"M508.636,-216.791C518.105,-225.87 529.33,-235.58 540.67,-243 560.155,-255.749 566.391,-257.228 588.67,-264 693.763,-295.945 724.494,-290.456 834.334,-291 847.667,-291.066 851.002,-291.217 864.334,-291 867.837,-290.943 871.453,-290.867 875.095,-290.779\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"882.106,-290.595 875.191,-293.928 878.607,-290.687 875.108,-290.779 875.108,-290.779 875.108,-290.779 878.607,-290.687 875.026,-287.63 882.106,-290.595 882.106,-290.595\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"700.38\" y=\"-292.8\">{b}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge14\"><title>3-&gt;2</title>\n",
"<path d=\"M227.758,-145.527C264.685,-139.647 325.2,-133.376 376.06,-144 399.22,-148.838 423.521,-159.065 442.935,-168.65\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"449.323,-171.868 441.655,-171.532 446.198,-170.293 443.072,-168.719 443.072,-168.719 443.072,-168.719 446.198,-170.293 444.489,-165.906 449.323,-171.868 449.323,-171.868\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"338.583\" y=\"-147.8\">{a}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge13\"><title>3-&gt;3</title>\n",
"<path d=\"M179.627,-185.086C179.558,-196.323 183.933,-205.355 192.751,-205.355 199.64,-205.355 203.817,-199.843 205.282,-192.073\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"205.875,-185.086 208.422,-192.327 205.579,-188.574 205.283,-192.061 205.283,-192.061 205.283,-192.061 205.579,-188.574 202.145,-191.795 205.875,-185.086 205.875,-185.086\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"192.751\" y=\"-209.155\">{}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge15\"><title>3-&gt;4</title>\n",
"<path d=\"M222.222,-171.683C229.739,-176.234 238.017,-180.702 246.106,-184 261.284,-190.188 278.659,-194.756 294.16,-198.021\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"301.135,-199.43 293.65,-201.131 297.705,-198.737 294.274,-198.044 294.274,-198.044 294.274,-198.044 297.705,-198.737 294.898,-194.956 301.135,-199.43 301.135,-199.43\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"264.606\" y=\"-199.8\">{b}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge9\"><title>3-&gt;5</title>\n",
"<path d=\"M226.397,-140.622C232.858,-138.77 239.641,-137.1 246.106,-136 366.378,-115.533 510.752,-135.902 582.298,-148.943\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"589.408,-150.259 581.951,-152.082 585.966,-149.622 582.525,-148.985 582.525,-148.985 582.525,-148.985 585.966,-149.622 583.098,-145.887 589.408,-150.259 589.408,-150.259\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"409.06\" y=\"-133.8\">{}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;6 -->\n",
"<g class=\"edge\" id=\"edge10\"><title>3-&gt;6</title>\n",
"<path d=\"M224.377,-135.817C231.353,-132.741 238.851,-129.896 246.106,-128 427.419,-80.611 484.163,-70.6112 667.38,-110 689.822,-114.825 713.237,-124.768 732.376,-134.36\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"738.695,-137.592 731.028,-137.209 735.579,-135.998 732.463,-134.405 732.463,-134.405 732.463,-134.405 735.579,-135.998 733.897,-131.6 738.695,-137.592 738.695,-137.592\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"482.365\" y=\"-91.8\">{a}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;7 -->\n",
"<g class=\"edge\" id=\"edge11\"><title>3-&gt;7</title>\n",
"<path d=\"M207.136,-119.392C227.894,-74.7296 272.369,-0 337.583,-0 337.583,-0 337.583,-0 775.857,-0 815.143,-0 856.228,-18.222 885.41,-34.7474\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"891.821,-38.4592 884.185,-37.6779 888.792,-36.7055 885.763,-34.9518 885.763,-34.9518 885.763,-34.9518 888.792,-36.7055 887.342,-32.2257 891.821,-38.4592 891.821,-38.4592\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"555.67\" y=\"-3.8\">{b}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;8 -->\n",
"<g class=\"edge\" id=\"edge12\"><title>3-&gt;8</title>\n",
"<path d=\"M209.097,-183.411C215.207,-196.222 222.181,-211.233 228.106,-225 257.834,-294.071 262.386,-354 337.583,-354 337.583,-354 337.583,-354 775.857,-354 814.76,-354 854.998,-335.32 883.959,-317.988\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"889.963,-314.317 885.634,-320.656 886.977,-316.142 883.991,-317.968 883.991,-317.968 883.991,-317.968 886.977,-316.142 882.348,-315.281 889.963,-314.317 889.963,-314.317\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"555.67\" y=\"-357.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 9 -->\n",
"<g class=\"node\" id=\"node10\"><title>9</title>\n",
"<ellipse cx=\"482.365\" cy=\"-286\" fill=\"#ffffaa\" rx=\"40.1111\" ry=\"40.1111\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"482.365\" y=\"-289.8\">1</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"482.365\" y=\"-274.8\">!a &amp; !b</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;9 -->\n",
"<g class=\"edge\" id=\"edge16\"><title>3-&gt;9</title>\n",
"<path d=\"M208.952,-183.615C226.27,-215.577 257.875,-263.141 301.106,-284 343.123,-304.273 397.325,-301.615 435.276,-295.857\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"442.641,-294.67 436.231,-298.894 439.186,-295.227 435.73,-295.784 435.73,-295.784 435.73,-295.784 439.186,-295.227 435.229,-292.674 442.641,-294.67 442.641,-294.67\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"338.583\" y=\"-302.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge18\"><title>4-&gt;2</title>\n",
"<path d=\"M376.095,-201.137C394.949,-199.143 418.082,-196.695 437.857,-194.603\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"444.976,-193.85 438.346,-197.719 441.496,-194.218 438.015,-194.586 438.015,-194.586 438.015,-194.586 441.496,-194.218 437.684,-191.454 444.976,-193.85 444.976,-193.85\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"409.06\" y=\"-202.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge17\"><title>4-&gt;3</title>\n",
"<path d=\"M309.772,-180.571C301.655,-174.596 292.444,-168.826 283.106,-165 268.272,-158.921 251.03,-155.624 235.672,-153.857\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"228.302,-153.107 235.585,-150.682 231.784,-153.461 235.266,-153.816 235.266,-153.816 235.266,-153.816 231.784,-153.461 234.947,-156.95 228.302,-153.107 228.302,-153.107\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"264.606\" y=\"-168.8\">{b}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge19\"><title>4-&gt;4</title>\n",
"<path d=\"M325.461,-240.213C325.596,-251.517 329.97,-260.477 338.583,-260.477 345.312,-260.477 349.454,-255.008 351.008,-247.226\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"351.705,-240.213 354.147,-247.49 351.359,-243.696 351.012,-247.179 351.012,-247.179 351.012,-247.179 351.359,-243.696 347.878,-246.867 351.705,-240.213 351.705,-240.213\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"338.583\" y=\"-264.277\">{}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;9 -->\n",
"<g class=\"edge\" id=\"edge20\"><title>4-&gt;9</title>\n",
"<path d=\"M371.402,-223.178C391.924,-234.903 418.8,-250.257 440.845,-262.851\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"446.925,-266.325 439.285,-265.587 443.886,-264.589 440.847,-262.852 440.847,-262.852 440.847,-262.852 443.886,-264.589 442.41,-260.117 446.925,-266.325 446.925,-266.325\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"409.06\" y=\"-256.8\">{a}</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge21\"><title>5-&gt;5</title>\n",
"<path d=\"M614.546,-195.236C614.884,-206.528 619.377,-215.355 628.025,-215.355 634.782,-215.355 639.002,-209.968 640.686,-202.226\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"641.505,-195.236 643.819,-202.555 641.098,-198.712 640.691,-202.189 640.691,-202.189 640.691,-202.189 641.098,-198.712 637.562,-201.822 641.505,-195.236 641.505,-195.236\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"628.025\" y=\"-219.155\">{}</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;6 -->\n",
"<g class=\"edge\" id=\"edge22\"><title>5-&gt;6</title>\n",
"<path d=\"M666.037,-146.689C672.431,-145.156 679.056,-143.827 685.38,-143 698.601,-141.271 702.152,-141.33 715.38,-143 719.444,-143.513 723.629,-144.219 727.805,-145.047\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"734.8,-146.543 727.296,-148.159 731.377,-145.811 727.955,-145.078 727.955,-145.078 727.955,-145.078 731.377,-145.811 728.613,-141.998 734.8,-146.543 734.8,-146.543\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"700.38\" y=\"-146.8\">{a}</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;7 -->\n",
"<g class=\"edge\" id=\"edge23\"><title>5-&gt;7</title>\n",
"<path d=\"M659.754,-134.347C679.693,-120.18 706.822,-103.027 733.38,-93 780.616,-75.1666 838.104,-67.2507 877.845,-63.7498\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"885.052,-63.146 878.34,-66.8694 881.565,-63.4382 878.077,-63.7304 878.077,-63.7304 878.077,-63.7304 881.565,-63.4382 877.814,-60.5914 885.052,-63.146 885.052,-63.146\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"774.857\" y=\"-96.8\">{b}</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;8 -->\n",
"<g class=\"edge\" id=\"edge24\"><title>5-&gt;8</title>\n",
"<path d=\"M656.84,-185.638C676.645,-203.852 704.731,-226.867 733.38,-241 778.691,-263.352 835.286,-275.855 875.308,-282.454\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"882.581,-283.618 875.171,-285.622 879.125,-283.065 875.669,-282.512 875.669,-282.512 875.669,-282.512 879.125,-283.065 876.167,-279.401 882.581,-283.618 882.581,-283.618\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"774.857\" y=\"-274.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge25\"><title>6-&gt;5</title>\n",
"<path d=\"M733.217,-158C715.031,-158 693.51,-158 674.762,-158\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"667.457,-158 674.457,-154.85 670.957,-158 674.457,-158 674.457,-158 674.457,-158 670.957,-158 674.457,-161.15 667.457,-158 667.457,-158\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"700.38\" y=\"-161.8\">{a}</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;6 -->\n",
"<g class=\"edge\" id=\"edge26\"><title>6-&gt;6</title>\n",
"<path d=\"M761.024,-197.182C761.502,-208.618 766.113,-217.477 774.857,-217.477 781.688,-217.477 785.997,-212.07 787.784,-204.251\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"788.691,-197.182 790.924,-204.526 788.245,-200.654 787.8,-204.125 787.8,-204.125 787.8,-204.125 788.245,-200.654 784.675,-203.724 788.691,-197.182 788.691,-197.182\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"774.857\" y=\"-221.277\">{}</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;7 -->\n",
"<g class=\"edge\" id=\"edge27\"><title>6-&gt;7</title>\n",
"<path d=\"M810.22,-135.746C832.578,-121.267 861.832,-102.322 885.294,-87.1277\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"891.436,-83.1502 887.273,-89.5993 888.498,-85.0527 885.56,-86.9553 885.56,-86.9553 885.56,-86.9553 888.498,-85.0527 883.848,-84.3113 891.436,-83.1502 891.436,-83.1502\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"849.334\" y=\"-122.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;8 -->\n",
"<g class=\"edge\" id=\"edge28\"><title>6-&gt;8</title>\n",
"<path d=\"M806.529,-184.826C829.843,-205.216 862.064,-233.397 887.115,-255.307\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"892.669,-260.165 885.327,-257.927 890.035,-257.861 887.4,-255.556 887.4,-255.556 887.4,-255.556 890.035,-257.861 889.474,-253.185 892.669,-260.165 892.669,-260.165\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"849.334\" y=\"-239.8\">{b}</text>\n",
"</g>\n",
"</g>\n",
"</svg>"
],
"text": [
"<IPython.core.display.SVG at 0x7f2e80d6fc50>"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, remove dead states, and remove stuttering transitions (i.e., transitions labeled by `{}`), marking as *livelock accepting* (rectangles) any states from which there exists a an accepting path labeled by `{}`."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ta = spot.tgba_to_ta(a, propset, True, True, False, False, False)\n",
"ta.show('.A')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 4,
"svg": [
"<svg height=\"161pt\" viewBox=\"0.00 0.00 715.35 161.00\" width=\"715pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 157)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" points=\"-4,4 -4,-157 711.349,-157 711.349,4 -4,4\" stroke=\"none\"/>\n",
"<!-- 0 -->\n",
"<!-- 1 -->\n",
"<g class=\"node\" id=\"node2\"><title>1</title>\n",
"<ellipse cx=\"62.6978\" cy=\"-68\" fill=\"#ffffaa\" rx=\"24.8972\" ry=\"24.8972\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"62.6978\" y=\"-64.3\">init</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g class=\"edge\" id=\"edge1\"><title>0-&gt;1</title>\n",
"<path d=\"M1.04399,-68C1.93865,-68 16.3331,-68 30.8732,-68\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"37.9642,-68 30.9643,-71.1501 34.4642,-68 30.9642,-68.0001 30.9642,-68.0001 30.9642,-68.0001 34.4642,-68 30.9642,-64.8501 37.9642,-68 37.9642,-68\" stroke=\"black\"/>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g class=\"node\" id=\"node3\"><title>2</title>\n",
"<polygon fill=\"#ffffaa\" points=\"479.349,-148 425.349,-148 425.349,-110 479.349,-110 479.349,-148\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"452.349\" y=\"-132.8\">1</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"452.349\" y=\"-117.8\">!a &amp; b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge2\"><title>1-&gt;2</title>\n",
"<path d=\"M85.1066,-78.4223C91.5527,-81.3783 98.6955,-84.476 105.396,-87 183.158,-116.294 202.189,-128.87 284.396,-141 317.351,-145.863 326.044,-141.694 359.349,-141 380.696,-140.555 386.184,-141.822 407.349,-139 410.85,-138.533 414.484,-137.92 418.093,-137.228\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"424.966,-135.815 418.744,-140.31 421.537,-136.52 418.109,-137.225 418.109,-137.225 418.109,-137.225 421.537,-136.52 417.475,-134.139 424.966,-135.815 424.966,-135.815\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.896\" y=\"-141.8\">!a &amp; b</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g class=\"node\" id=\"node4\"><title>3</title>\n",
"<polygon fill=\"#ffffaa\" points=\"211.396,-87 157.396,-87 157.396,-49 211.396,-49 211.396,-87\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"184.396\" y=\"-71.8\">1</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"184.396\" y=\"-56.8\">a &amp; b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge3\"><title>1-&gt;3</title>\n",
"<path d=\"M87.6328,-68C105.497,-68 130.135,-68 149.947,-68\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"157.006,-68 150.006,-71.1501 153.506,-68 150.006,-68.0001 150.006,-68.0001 150.006,-68.0001 153.506,-68 150.006,-64.8501 157.006,-68 157.006,-68\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"122.396\" y=\"-71.8\">a &amp; b</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g class=\"node\" id=\"node5\"><title>4</title>\n",
"<ellipse cx=\"321.872\" cy=\"-65\" fill=\"#ffffaa\" rx=\"37.4533\" ry=\"37.4533\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"321.872\" y=\"-68.8\">1</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"321.872\" y=\"-53.8\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge4\"><title>1-&gt;4</title>\n",
"<path d=\"M84.3656,-55.3514C102.769,-44.8778 130.817,-30.8075 157.396,-25 199.902,-15.7122 248.27,-30.763 281.299,-44.9807\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"288.106,-47.9929 280.43,-48.041 284.905,-46.5767 281.705,-45.1604 281.705,-45.1604 281.705,-45.1604 284.905,-46.5767 282.979,-42.2798 288.106,-47.9929 288.106,-47.9929\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"184.396\" y=\"-28.8\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g class=\"node\" id=\"node6\"><title>5</title>\n",
"<polygon fill=\"#ffffaa\" points=\"589.349,-123 535.349,-123 535.349,-85 589.349,-85 589.349,-123\" stroke=\"black\"/>\n",
"<polygon fill=\"none\" points=\"593.349,-127 531.349,-127 531.349,-81 593.349,-81 593.349,-127\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"562.349\" y=\"-107.8\">0</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"562.349\" y=\"-92.8\">a &amp; b</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge5\"><title>2-&gt;5</title>\n",
"<path d=\"M479.493,-122.948C492.905,-119.844 509.474,-116.008 524.19,-112.602\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"531.242,-110.969 525.133,-115.617 527.833,-111.758 524.423,-112.548 524.423,-112.548 524.423,-112.548 527.833,-111.758 523.712,-109.479 531.242,-110.969 531.242,-110.969\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"505.349\" y=\"-121.8\">{a}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge7\"><title>3-&gt;2</title>\n",
"<path d=\"M211.569,-81.698C231.123,-91.3492 258.782,-103.791 284.396,-111 324.55,-122.302 335.856,-119.702 377.349,-124 390.625,-125.375 405.282,-126.456 418.026,-127.256\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"425.283,-127.695 418.105,-130.417 421.789,-127.484 418.295,-127.273 418.295,-127.273 418.295,-127.273 421.789,-127.484 418.485,-124.128 425.283,-127.695 425.283,-127.695\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"321.872\" y=\"-125.8\">{a}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge8\"><title>3-&gt;4</title>\n",
"<path d=\"M211.405,-55.4294C217.198,-53.1796 223.403,-51.1784 229.396,-50 245.554,-46.8226 263.411,-48.582 279.026,-51.8391\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"286.029,-53.4287 278.505,-54.951 282.616,-52.6539 279.203,-51.8791 279.203,-51.8791 279.203,-51.8791 282.616,-52.6539 279.9,-48.8073 286.029,-53.4287 286.029,-53.4287\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.896\" y=\"-53.8\">{b}</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g class=\"node\" id=\"node7\"><title>6</title>\n",
"<polygon fill=\"#ffffaa\" points=\"703.349,-85 649.349,-85 649.349,-47 703.349,-47 703.349,-85\" stroke=\"black\"/>\n",
"<polygon fill=\"none\" points=\"707.349,-89 645.349,-89 645.349,-43 707.349,-43 707.349,-89\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"676.349\" y=\"-69.8\">0</text>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"676.349\" y=\"-54.8\">!a &amp; b</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;6 -->\n",
"<g class=\"edge\" id=\"edge6\"><title>3-&gt;6</title>\n",
"<path d=\"M207.657,-48.6958C233.192,-28.592 277.186,-0 320.872,-0 320.872,-0 320.872,-0 563.349,-0 595.255,-0 626.076,-20.1262 647.282,-38.1505\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"652.73,-42.9164 645.387,-40.6786 650.096,-40.612 647.461,-38.3076 647.461,-38.3076 647.461,-38.3076 650.096,-40.612 649.535,-35.9367 652.73,-42.9164 652.73,-42.9164\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"452.349\" y=\"-3.8\">{a}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge10\"><title>4-&gt;2</title>\n",
"<path d=\"M355.625,-81.3155C374.995,-90.9647 399.44,-103.142 418.778,-112.775\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"425.126,-115.937 417.456,-115.635 421.993,-114.376 418.86,-112.816 418.86,-112.816 418.86,-112.816 421.993,-114.376 420.265,-109.996 425.126,-115.937 425.126,-115.937\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"392.349\" y=\"-109.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge9\"><title>4-&gt;3</title>\n",
"<path d=\"M284.333,-65.8091C263.851,-66.2627 238.5,-66.824 218.588,-67.265\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"211.517,-67.4216 218.445,-64.1173 215.016,-67.344 218.515,-67.2665 218.515,-67.2665 218.515,-67.2665 215.016,-67.344 218.585,-70.4157 211.517,-67.4216 211.517,-67.4216\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.896\" y=\"-70.8\">{b}</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;6 -->\n",
"<g class=\"edge\" id=\"edge11\"><title>5-&gt;6</title>\n",
"<path d=\"M587.188,-80.8632C594.396,-75.2601 602.707,-70.0196 611.349,-67 619.709,-64.0787 629.067,-62.8793 637.99,-62.6129\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"645.027,-62.5842 638.04,-65.7628 641.527,-62.5985 638.027,-62.6128 638.027,-62.6128 638.027,-62.6128 641.527,-62.5985 638.014,-59.4629 645.027,-62.5842 645.027,-62.5842\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"619.349\" y=\"-70.8\">{a}</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge12\"><title>6-&gt;5</title>\n",
"<path d=\"M645.252,-76.2114C631.432,-80.9005 614.911,-86.5056 600.339,-91.4496\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"593.363,-93.8167 598.98,-88.5846 596.677,-92.6921 599.992,-91.5676 599.992,-91.5676 599.992,-91.5676 596.677,-92.6921 601.004,-94.5505 593.363,-93.8167 593.363,-93.8167\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"619.349\" y=\"-90.8\">{a}</text>\n",
"</g>\n",
"</g>\n",
"</svg>"
],
"text": [
"<IPython.core.display.SVG at 0x7f2e89e119b0>"
]
}
],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, use bisimulation to minimize the number of states."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"spot.minimize_ta(ta).show('.A')"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 5,
"svg": [
"<svg height=\"178pt\" viewBox=\"0.00 0.00 562.40 178.00\" width=\"562pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 174)\">\n",
"<title>G</title>\n",
"<polygon fill=\"white\" points=\"-4,4 -4,-174 558.396,-174 558.396,4 -4,4\" stroke=\"none\"/>\n",
"<!-- 0 -->\n",
"<!-- 1 -->\n",
"<g class=\"node\" id=\"node2\"><title>1</title>\n",
"<ellipse cx=\"62.6978\" cy=\"-144\" fill=\"#ffffaa\" rx=\"24.8972\" ry=\"24.8972\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"62.6978\" y=\"-140.3\">init</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g class=\"edge\" id=\"edge1\"><title>0-&gt;1</title>\n",
"<path d=\"M1.04399,-144C1.93865,-144 16.3331,-144 30.8732,-144\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"37.9642,-144 30.9643,-147.15 34.4642,-144 30.9642,-144 30.9642,-144 30.9642,-144 34.4642,-144 30.9642,-140.85 37.9642,-144 37.9642,-144\" stroke=\"black\"/>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g class=\"node\" id=\"node3\"><title>2</title>\n",
"<polygon fill=\"#ffffaa\" points=\"440.396,-84 386.396,-84 386.396,-48 440.396,-48 440.396,-84\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"413.396\" y=\"-62.3\">2</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge2\"><title>1-&gt;2</title>\n",
"<path d=\"M86.9099,-150.505C92.8863,-151.92 99.3405,-153.225 105.396,-154 200.719,-166.201 229.01,-160.734 320.396,-131 342.539,-123.795 349.163,-123.127 368.396,-110 376.786,-104.273 384.949,-96.8174 391.919,-89.675\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"397.001,-84.3081 394.476,-91.5568 394.595,-86.8495 392.188,-89.3909 392.188,-89.3909 392.188,-89.3909 394.595,-86.8495 389.901,-87.225 397.001,-84.3081 397.001,-84.3081\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.896\" y=\"-158.8\">!a &amp; b</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g class=\"node\" id=\"node4\"><title>3</title>\n",
"<polygon fill=\"#ffffaa\" points=\"211.396,-94 157.396,-94 157.396,-58 211.396,-58 211.396,-94\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"184.396\" y=\"-72.3\">3</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge3\"><title>1-&gt;3</title>\n",
"<path d=\"M83.2503,-129.536C90.1123,-124.694 97.9646,-119.411 105.396,-115 119.96,-106.355 136.69,-97.8185 150.912,-90.9462\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"157.253,-87.9113 152.299,-93.7747 154.096,-89.4223 150.939,-90.9333 150.939,-90.9333 150.939,-90.9333 154.096,-89.4223 149.579,-88.092 157.253,-87.9113 157.253,-87.9113\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"122.396\" y=\"-118.8\">a &amp; b</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g class=\"node\" id=\"node5\"><title>4</title>\n",
"<ellipse cx=\"302.396\" cy=\"-104\" fill=\"#ffffaa\" rx=\"18\" ry=\"18\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"302.396\" y=\"-100.3\">1</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge4\"><title>1-&gt;4</title>\n",
"<path d=\"M87.4738,-142.898C125.721,-140.694 203.038,-134.451 266.396,-118 270.535,-116.925 274.841,-115.487 278.96,-113.941\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"285.651,-111.282 280.309,-116.794 282.399,-112.575 279.146,-113.867 279.146,-113.867 279.146,-113.867 282.399,-112.575 277.983,-110.94 285.651,-111.282 285.651,-111.282\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"184.396\" y=\"-139.8\">a &amp; !b</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g class=\"node\" id=\"node6\"><title>5</title>\n",
"<polygon fill=\"#ffffaa\" points=\"550.396,-40 496.396,-40 496.396,-4 550.396,-4 550.396,-40\" stroke=\"black\"/>\n",
"<polygon fill=\"none\" points=\"554.396,-44 492.396,-44 492.396,-3.55271e-15 554.396,-3.55271e-15 554.396,-44\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"523.396\" y=\"-18.3\">4</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge5\"><title>2-&gt;5</title>\n",
"<path d=\"M440.539,-55.3488C454.074,-49.8349 470.822,-43.0113 485.637,-36.9757\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"492.289,-34.2656 486.995,-39.8239 489.048,-35.5862 485.807,-36.9067 485.807,-36.9067 485.807,-36.9067 489.048,-35.5862 484.618,-33.9895 492.289,-34.2656 492.289,-34.2656\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"466.396\" y=\"-51.8\">{a}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge7\"><title>3-&gt;2</title>\n",
"<path d=\"M211.404,-70.9547C217.306,-69.898 223.556,-68.8483 229.396,-68 269.507,-62.1732 279.873,-61.1195 320.396,-62 339.836,-62.4224 361.57,-63.3463 379.03,-64.1999\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"386.233,-64.5597 379.084,-67.3564 382.737,-64.385 379.241,-64.2103 379.241,-64.2103 379.241,-64.2103 382.737,-64.385 379.399,-61.0642 386.233,-64.5597 386.233,-64.5597\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"302.396\" y=\"-65.8\">{a}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;4 -->\n",
"<g class=\"edge\" id=\"edge8\"><title>3-&gt;4</title>\n",
"<path d=\"M211.657,-72.1843C227.874,-70.8265 248.862,-70.9018 266.396,-77 272.543,-79.1381 278.459,-82.823 283.622,-86.7951\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"289.305,-91.5145 281.908,-89.4661 286.613,-89.2786 283.92,-87.0426 283.92,-87.0426 283.92,-87.0426 286.613,-89.2786 285.932,-84.6192 289.305,-91.5145 289.305,-91.5145\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.896\" y=\"-80.8\">{b}</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge6\"><title>3-&gt;5</title>\n",
"<path d=\"M211.649,-65.47C217.427,-63.4301 223.564,-61.4721 229.396,-60 319.354,-37.2923 428.464,-27.7027 484.752,-24.03\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"492.008,-23.5705 485.221,-27.1567 488.515,-23.7917 485.022,-24.013 485.022,-24.013 485.022,-24.013 488.515,-23.7917 484.823,-20.8693 492.008,-23.5705 492.008,-23.5705\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"353.396\" y=\"-42.8\">{a}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;2 -->\n",
"<g class=\"edge\" id=\"edge10\"><title>4-&gt;2</title>\n",
"<path d=\"M319.95,-98.2286C335.72,-92.7311 359.903,-84.3003 379.58,-77.4404\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"386.331,-75.0869 380.758,-80.3657 383.026,-76.2391 379.721,-77.3913 379.721,-77.3913 379.721,-77.3913 383.026,-76.2391 378.684,-74.4168 386.331,-75.0869 386.331,-75.0869\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"353.396\" y=\"-94.8\">{a, b}</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;3 -->\n",
"<g class=\"edge\" id=\"edge9\"><title>4-&gt;3</title>\n",
"<path d=\"M284.335,-102.054C269.627,-100.164 247.903,-96.8631 229.396,-92 225.851,-91.0685 222.189,-89.9687 218.563,-88.7888\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"211.671,-86.4443 219.312,-85.7166 214.984,-87.5715 218.298,-88.6988 218.298,-88.6988 218.298,-88.6988 214.984,-87.5715 217.283,-91.6809 211.671,-86.4443 211.671,-86.4443\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"247.896\" y=\"-102.8\">{b}</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;5 -->\n",
"<g class=\"edge\" id=\"edge11\"><title>5-&gt;5</title>\n",
"<path d=\"M513.021,-44.2124C512.172,-53.7952 515.63,-62 523.396,-62 529.098,-62 532.478,-57.5751 533.535,-51.4291\" fill=\"none\" stroke=\"black\"/>\n",
"<polygon fill=\"black\" points=\"533.77,-44.2124 536.69,-51.3112 533.656,-47.7105 533.542,-51.2086 533.542,-51.2086 533.542,-51.2086 533.656,-47.7105 530.394,-51.1061 533.77,-44.2124 533.77,-44.2124\" stroke=\"black\"/>\n",
"<text font-family=\"Lato\" font-size=\"14.00\" text-anchor=\"middle\" x=\"523.396\" y=\"-65.8\">{a}</text>\n",
"</g>\n",
"</g>\n",
"</svg>"
],
"text": [
"<IPython.core.display.SVG at 0x7f2e884949e8>"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}