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:
parent
74ec9c54c4
commit
34c3c1cedc
62 changed files with 24 additions and 48 deletions
13
python/.gitignore
vendored
Normal file
13
python/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
||||
*.la
|
||||
spot_impl.py*
|
||||
buddy.py*
|
||||
*.lo
|
||||
*.loT
|
||||
*_wrap.*
|
||||
*.pyc
|
||||
*/spotimg
|
||||
ajax/*.py
|
||||
65
python/Makefile.am
Normal file
65
python/Makefile.am
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2010, 2011, 2013, 2014, 2015 Laboratoire de Recherche
|
||||
## et Development 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/>.
|
||||
|
||||
SUBDIRS = . ajax tests
|
||||
|
||||
AM_CPPFLAGS = -I$(PYTHONINC) -I$(top_builddir) -I$(top_srcdir) \
|
||||
$(BUDDY_CPPFLAGS) -DSWIG_TYPE_TABLE=spot
|
||||
|
||||
# Disable fastproxy, because IPython 2 bogusly ignores _repr_latex_
|
||||
# when -fastproxy is used.
|
||||
# https://github.com/ipython/ipython/issues/7003
|
||||
# Once a fixed version of IPython hits Debian stable, we can remove
|
||||
# this.
|
||||
SWIGFLAGS = -c++ -python -py3 -O -nofastproxy
|
||||
|
||||
EXTRA_DIST = spot_impl.i buddy.i
|
||||
python_PYTHON = $(srcdir)/spot_impl.py $(srcdir)/buddy.py spot.py
|
||||
pyexec_LTLIBRARIES = _spot_impl.la _buddy.la
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
$(srcdir)/spot_impl_wrap.cxx $(srcdir)/spot_impl.py \
|
||||
$(srcdir)/buddy_wrap.cxx $(srcdir)/buddy.py
|
||||
|
||||
## spot
|
||||
|
||||
_spot_impl_la_SOURCES = $(srcdir)/spot_impl_wrap.cxx
|
||||
_spot_impl_la_LDFLAGS = -avoid-version -module $(SYMBOLIC_LDFLAGS)
|
||||
_spot_impl_la_LIBADD = $(top_builddir)/spot/libspot.la
|
||||
|
||||
$(srcdir)/spot_impl_wrap.cxx: $(srcdir)/spot_impl.i
|
||||
$(SWIG) $(SWIGFLAGS) -I$(srcdir) -I$(top_srcdir) $(srcdir)/spot_impl.i
|
||||
|
||||
$(srcdir)/spot_impl.py: $(srcdir)/spot_impl.i
|
||||
$(MAKE) $(AM_MAKEFLAGS) spot_impl_wrap.cxx
|
||||
|
||||
|
||||
## buddy
|
||||
|
||||
_buddy_la_SOURCES = $(srcdir)/buddy_wrap.cxx
|
||||
_buddy_la_LDFLAGS = -avoid-version -module $(BUDDY_LDFLAGS) $(SYMBOLIC_LDFLAGS)
|
||||
|
||||
$(srcdir)/buddy_wrap.cxx: $(srcdir)/buddy.i
|
||||
$(SWIG) $(SWIGFLAGS) $(BUDDY_CPPFLAGS) $(srcdir)/buddy.i
|
||||
|
||||
$(srcdir)/buddy.py: $(srcdir)/buddy.i
|
||||
$(MAKE) $(AM_MAKEFLAGS) buddy_wrap.cxx
|
||||
41
python/ajax/Makefile.am
Normal file
41
python/ajax/Makefile.am
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2011, 2012, 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/>.
|
||||
|
||||
nodist_noinst_SCRIPTS = spotcgi.py
|
||||
EXTRA_DIST = $(srcdir)/spotcgi.in README trans.html css/trans.css \
|
||||
css/tipTip.css js/jquery.tipTip.minified.js js/jquery.ba-bbq.min.js \
|
||||
js/jquery.ba-dotimeout.min.js logos/lip6sys64.png logos/lrde64.png \
|
||||
logos/spot64s.png logos/mail.png css/loading.gif protocol.txt
|
||||
|
||||
CLEANFILES = $(nodist_noinst_SCRIPTS)
|
||||
|
||||
spotcgi.py: $(srcdir)/spotcgi.in Makefile
|
||||
sed -e 's|[@]PYTHON[@]|@PYTHON@|g' \
|
||||
-e 's|[@]pythondir[@]|@pythondir@|g' \
|
||||
-e 's|[@]srcdir[@]|@srcdir@|g' \
|
||||
-e 's|[@]top_builddir[@]|@top_builddir@|g' \
|
||||
-e 's|[@]PACKAGE_VERSION[@]|@PACKAGE_VERSION@|g' \
|
||||
-e 's|[@]DOT[@]|@DOT@|g' \
|
||||
-e 's|[@]LTL3BA[@]|@LTL3BA@|g' \
|
||||
<$(srcdir)/spotcgi.in >spotcgi.tmp
|
||||
chmod +x spotcgi.tmp
|
||||
mv -f spotcgi.tmp $@
|
||||
|
||||
clean-local:
|
||||
rm -rf spotimg
|
||||
90
python/ajax/README
Normal file
90
python/ajax/README
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
ltl2tgba.html is a dynamic web page that translates user-supplied LTL
|
||||
formulae to Transition-based Generalized Büchi Automata. The actual
|
||||
translation work is performed by a CGI script in Python: spotcgi.py.
|
||||
|
||||
There are two ways to use the script: using a web server such as
|
||||
Apache, or standalone.
|
||||
|
||||
In both cases you should ensure that the command `dot', from the
|
||||
GraphViz package, is in the PATH. configure should have picked it up.
|
||||
|
||||
The "ltl3ba" tab will only be enabled if ltl3ba is available (as
|
||||
checked by ./configure) and supports options -v/-T/-T3 (checked by the
|
||||
CGI script). These option were introduced into ltl3ba version 1.1.0.
|
||||
|
||||
|
||||
Standalone usage
|
||||
================
|
||||
|
||||
Simply run spotcgi.py from this directory. This will create a directory
|
||||
called spotimg/ in the current directory (this will hold the generated
|
||||
pictures) and start an HTTP server on port 8000. Point your browser
|
||||
to http://localhost:8000/trans.html and you should be OK.
|
||||
|
||||
After you have killed the server process (e.g. with Control-C),
|
||||
you may want to erase the spotimg/ directory.
|
||||
|
||||
|
||||
Installing on a real web server
|
||||
===============================
|
||||
|
||||
1) Install Spot first (run `make install' from the top-level).
|
||||
|
||||
The CGI script uses the Python bindings and assume they
|
||||
have been installed. Near the top of the script, you
|
||||
should see a call to sys.path.insert(), with the expected
|
||||
location of the Python bindings for spot. This path was
|
||||
configured from ./configure's arguments and you should not
|
||||
have to fiddle with it. I'm mentionning it just in case.
|
||||
|
||||
2) Copy spotcgi.py to some place were CGI execution is allowed.
|
||||
Depending on your HTTP server's configuration, you may have
|
||||
to rename the script as spotcgi.cgi or something else, so
|
||||
that the server accepts to run it.
|
||||
|
||||
Apache users in trouble should look at the following options
|
||||
before digging the Apache manual deeper. These can go
|
||||
in a .htaccess file (if allowed).
|
||||
|
||||
# Treat *.py files as CGI scripts
|
||||
AddHandler cgi-script .py
|
||||
|
||||
# Allow CGI execution in some directory.
|
||||
Options +ExecCGI
|
||||
|
||||
3) In the directory where you have installed spotcgi.py,
|
||||
create a subdirectory called spotimg/. This is where
|
||||
the script will cache its images and other temporary
|
||||
files. (If you want to change this name, see the imgdir
|
||||
variable at the top of the script.)
|
||||
|
||||
This directory must be writable by the Unix user that
|
||||
will run the script when the HTTP server processes the
|
||||
request.
|
||||
|
||||
spotcgi.py purges old files at most once every hour.
|
||||
|
||||
4) Copy the directories css/, js/, and logos/ along with trans.html
|
||||
to their destination. You may have to adjust a few paths at the
|
||||
top of the html page.
|
||||
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
When working on the script, remember that the contents of spotimg/ is
|
||||
used as a cache and that a request will not be processed again if its
|
||||
result is in the cache. So if you don't understand why the change you
|
||||
have performed has no effect, make sure you are performing some fresh
|
||||
query, or wipe the contents of the cache (i.e., erase all files inside
|
||||
spotimg/ but not the spotimg/ directory itself).
|
||||
|
||||
|
||||
The hash string displayed in the web browser is the query string sent
|
||||
to the CGI script, so you can simulate the call from the command line
|
||||
with a command like this:
|
||||
|
||||
% export QUERY_STRING="f=a+U+b&r=br&r=lf&r=si&r=eu&o=a&ff=o&mf=d&af=t&ra=t&rf=p&t=fm&fm=od&fm=sm&la=sp&ta=lc&as=ps&ec=Cou99&eo="
|
||||
% export SCRIPT_NAME=spotcgi.py
|
||||
% export SERVER_SOFTWARE=SimpleHTTP
|
||||
% ./spotcgi.py
|
||||
BIN
python/ajax/css/loading.gif
Normal file
BIN
python/ajax/css/loading.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
114
python/ajax/css/tipTip.css
Normal file
114
python/ajax/css/tipTip.css
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/* TipTip CSS - Version 1.2 */
|
||||
|
||||
#tiptip_holder {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_top {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_bottom {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_right {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_left {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#tiptip_content {
|
||||
font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
|
||||
font-size: 1em;
|
||||
color: #fff;
|
||||
text-shadow: 0 0 2px #000;
|
||||
padding: 4px 8px;
|
||||
border: 1px solid rgba(255,255,255,0.25);
|
||||
background-color: rgb(25,25,25);
|
||||
background-color: rgba(25,25,25,0.92);
|
||||
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(transparent), to(#000));
|
||||
border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
box-shadow: 0 0 3px #555;
|
||||
-webkit-box-shadow: 0 0 3px #555;
|
||||
-moz-box-shadow: 0 0 3px #555;
|
||||
}
|
||||
|
||||
#tiptip_arrow, #tiptip_arrow_inner {
|
||||
position: absolute;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: 6px;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_top #tiptip_arrow {
|
||||
border-top-color: #fff;
|
||||
border-top-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_bottom #tiptip_arrow {
|
||||
border-bottom-color: #fff;
|
||||
border-bottom-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_right #tiptip_arrow {
|
||||
border-right-color: #fff;
|
||||
border-right-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_left #tiptip_arrow {
|
||||
border-left-color: #fff;
|
||||
border-left-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
||||
margin-top: -7px;
|
||||
margin-left: -6px;
|
||||
border-top-color: rgb(25,25,25);
|
||||
border-top-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
||||
margin-top: -5px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: rgb(25,25,25);
|
||||
border-bottom-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_right #tiptip_arrow_inner {
|
||||
margin-top: -6px;
|
||||
margin-left: -5px;
|
||||
border-right-color: rgb(25,25,25);
|
||||
border-right-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
#tiptip_holder.tip_left #tiptip_arrow_inner {
|
||||
margin-top: -6px;
|
||||
margin-left: -7px;
|
||||
border-left-color: rgb(25,25,25);
|
||||
border-left-color: rgba(25,25,25,0.92);
|
||||
}
|
||||
|
||||
/* Webkit Hacks */
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
#tiptip_content {
|
||||
padding: 4px 8px 5px 8px;
|
||||
background-color: rgba(45,45,45,0.88);
|
||||
}
|
||||
#tiptip_holder.tip_bottom #tiptip_arrow_inner {
|
||||
border-bottom-color: rgba(45,45,45,0.88);
|
||||
}
|
||||
#tiptip_holder.tip_top #tiptip_arrow_inner {
|
||||
border-top-color: rgba(20,20,20,0.92);
|
||||
}
|
||||
}
|
||||
139
python/ajax/css/trans.css
Normal file
139
python/ajax/css/trans.css
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
html {overflow-y:scroll;}
|
||||
|
||||
.ltl2tgba .ui-widget {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
input.formula {
|
||||
width: 720px;
|
||||
}
|
||||
|
||||
span#send {
|
||||
width: 60px;
|
||||
margin-left: 4px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
-moz-box-shadow: 2px 2px 2px #888888;
|
||||
-webkit-box-shadow: 2px 1px 2px #888888;
|
||||
box-shadow: 2px 2px 2px #888888;
|
||||
}
|
||||
|
||||
div.ltl2tgba {
|
||||
width: 800px;
|
||||
position:relative;
|
||||
left:0px;
|
||||
top:0px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
z-index:10;
|
||||
}
|
||||
|
||||
#spotlogo {
|
||||
position:fixed;
|
||||
left:10px;
|
||||
top:10px;
|
||||
z-index:1;
|
||||
}
|
||||
#lrdelogo {
|
||||
position:fixed;
|
||||
left:10px;
|
||||
bottom:84px;
|
||||
z-index:1;
|
||||
}
|
||||
#lip6logo {
|
||||
position:fixed;
|
||||
left:10px;
|
||||
bottom:10px;
|
||||
z-index:1;
|
||||
}
|
||||
#mailicon {
|
||||
position:fixed;
|
||||
left:10px;
|
||||
top:84px;
|
||||
z-index:1;
|
||||
}
|
||||
|
||||
.ltldoc {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.ltltable
|
||||
{
|
||||
border-collapse:collapse;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.ltldocrow {
|
||||
font-weight: bold;
|
||||
vertical-align:top;
|
||||
}
|
||||
|
||||
.ltl2tgba div.ui-widget-content {
|
||||
padding: 3px;
|
||||
margin: 2px 0px;
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
.ltl2tgba h3 {
|
||||
font-size:1em;
|
||||
margin: 0;
|
||||
padding: 0px 0.2em 0px;
|
||||
border-bottom:1px solid #eee;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.floatright {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.colleft {
|
||||
float: left;
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.ltl2tgba .head .ui-icon {
|
||||
float: right;
|
||||
margin: 1px 0px;
|
||||
}
|
||||
|
||||
.ltl2tgba .formula, #tiptip_content .formula {
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.ltl2tgba .error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.ltl2tgba .parse-error {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
color: red;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.ltl2tgba .ec-error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.ltl2tgba .loading {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ltl2tgba .neverclaim, .ltl2tgba .accrun {
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
#ltl3ba-tab {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.ui-button-text-only .ui-button-text { padding: .1em .3em; }
|
||||
.ui-tabs .ui-tabs-nav li a { float: left; padding: .1em .3em; text-decoration: none; }
|
||||
18
python/ajax/js/jquery.ba-bbq.min.js
vendored
Normal file
18
python/ajax/js/jquery.ba-bbq.min.js
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* jQuery BBQ: Back Button & Query Library - v1.3pre - 8/26/2010
|
||||
* http://benalman.com/projects/jquery-bbq-plugin/
|
||||
*
|
||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://benalman.com/about/license/
|
||||
*/
|
||||
(function($,r){var h,n=Array.prototype.slice,t=decodeURIComponent,a=$.param,j,c,m,y,b=$.bbq=$.bbq||{},s,x,k,e=$.event.special,d="hashchange",B="querystring",F="fragment",z="elemUrlAttr",l="href",w="src",p=/^.*\?|#.*$/g,u,H,g,i,C,E={};function G(I){return typeof I==="string"}function D(J){var I=n.call(arguments,1);return function(){return J.apply(this,I.concat(n.call(arguments)))}}function o(I){return I.replace(H,"$2")}function q(I){return I.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(K,P,I,L,J){var R,O,N,Q,M;if(L!==h){N=I.match(K?H:/^([^#?]*)\??([^#]*)(#?.*)/);M=N[3]||"";if(J===2&&G(L)){O=L.replace(K?u:p,"")}else{Q=m(N[2]);L=G(L)?m[K?F:B](L):L;O=J===2?L:J===1?$.extend({},L,Q):$.extend({},Q,L);O=j(O);if(K){O=O.replace(g,t)}}R=N[1]+(K?C:O||!N[1]?"?":"")+O+M}else{R=P(I!==h?I:location.href)}return R}a[B]=D(f,0,q);a[F]=c=D(f,1,o);a.sorted=j=function(J,K){var I=[],L={};$.each(a(J,K).split("&"),function(P,M){var O=M.replace(/(?:%5B|=).*$/,""),N=L[O];if(!N){N=L[O]=[];I.push(O)}N.push(M)});return $.map(I.sort(),function(M){return L[M]}).join("&")};c.noEscape=function(J){J=J||"";var I=$.map(J.split(""),encodeURIComponent);g=new RegExp(I.join("|"),"g")};c.noEscape(",/");c.ajaxCrawlable=function(I){if(I!==h){if(I){u=/^.*(?:#!|#)/;H=/^([^#]*)(?:#!|#)?(.*)$/;C="#!"}else{u=/^.*#/;H=/^([^#]*)#?(.*)$/;C="#"}i=!!I}return i};c.ajaxCrawlable(0);$.deparam=m=function(L,I){var K={},J={"true":!0,"false":!1,"null":null};$.each(L.replace(/\+/g," ").split("&"),function(O,T){var N=T.split("="),S=t(N[0]),M,R=K,P=0,U=S.split("]["),Q=U.length-1;if(/\[/.test(U[0])&&/\]$/.test(U[Q])){U[Q]=U[Q].replace(/\]$/,"");U=U.shift().split("[").concat(U);Q=U.length-1}else{Q=0}if(N.length===2){M=t(N[1]);if(I){M=M&&!isNaN(M)?+M:M==="undefined"?h:J[M]!==h?J[M]:M}if(Q){for(;P<=Q;P++){S=U[P]===""?R.length:U[P];R=R[S]=P<Q?R[S]||(U[P+1]&&isNaN(U[P+1])?{}:[]):M}}else{if($.isArray(K[S])){K[S].push(M)}else{if(K[S]!==h){K[S]=[K[S],M]}else{K[S]=M}}}}else{if(S){K[S]=I?h:""}}});return K};function A(K,I,J){if(I===h||typeof I==="boolean"){J=I;I=a[K?F:B]()}else{I=G(I)?I.replace(K?u:p,""):I}return m(I,J)}m[B]=D(A,0);m[F]=y=D(A,1);$[z]||($[z]=function(I){return $.extend(E,I)})({a:l,base:l,iframe:w,img:w,input:w,form:"action",link:l,script:w});k=$[z];function v(L,J,K,I){if(!G(K)&&typeof K!=="object"){I=K;K=J;J=h}return this.each(function(){var O=$(this),M=J||k()[(this.nodeName||"").toLowerCase()]||"",N=M&&O.attr(M)||"";O.attr(M,a[L](N,K,I))})}$.fn[B]=D(v,B);$.fn[F]=D(v,F);b.pushState=s=function(L,I){if(G(L)&&/^#/.test(L)&&I===h){I=2}var K=L!==h,J=c(location.href,K?L:{},K?I:2);location.href=J};b.getState=x=function(I,J){return I===h||typeof I==="boolean"?y(I):y(J)[I]};b.removeState=function(I){var J={};if(I!==h){J=x();$.each($.isArray(I)?I:arguments,function(L,K){delete J[K]})}s(J,2)};e[d]=$.extend(e[d],{add:function(I){var K;function J(M){var L=M[F]=c();M.getState=function(N,O){return N===h||typeof N==="boolean"?m(L,N):m(L,O)[N]};K.apply(this,arguments)}if($.isFunction(I)){K=I;return J}else{K=I.handler;I.handler=J}}})})(jQuery,this);
|
||||
/*
|
||||
* jQuery hashchange event - v1.3 - 7/21/2010
|
||||
* http://benalman.com/projects/jquery-hashchange-plugin/
|
||||
*
|
||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://benalman.com/about/license/
|
||||
*/
|
||||
(function($,e,b){var c="hashchange",h=document,f,g=$.event.special,i=h.documentMode,d="on"+c in e&&(i===b||i>7);function a(j){j=j||location.href;return"#"+j.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[c]=function(j){return j?this.bind(c,j):this.trigger(c)};$.fn[c].delay=50;g[c]=$.extend(g[c],{setup:function(){if(d){return false}$(f.start)},teardown:function(){if(d){return false}$(f.stop)}});f=(function(){var j={},p,m=a(),k=function(q){return q},l=k,o=k;j.start=function(){p||n()};j.stop=function(){p&&clearTimeout(p);p=b};function n(){var r=a(),q=o(m);if(r!==m){l(m=r,q);$(e).trigger(c)}else{if(q!==m){location.href=location.href.replace(/#.*/,"")+q}}p=setTimeout(n,$.fn[c].delay)}$.browser.msie&&!d&&(function(){var q,r;j.start=function(){if(!q){r=$.fn[c].src;r=r&&r+a();q=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){r||l(a());n()}).attr("src",r||"javascript:0").insertAfter("body")[0].contentWindow;h.onpropertychange=function(){try{if(event.propertyName==="title"){q.document.title=h.title}}catch(s){}}}};j.stop=k;o=function(){return a(q.location.href)};l=function(v,s){var u=q.document,t=$.fn[c].domain;if(v!==s){u.title=h.title;u.open();t&&u.write('<script>document.domain="'+t+'"<\/script>');u.close();q.location.hash=v}}})();return j})()})(jQuery,this);
|
||||
9
python/ajax/js/jquery.ba-dotimeout.min.js
vendored
Normal file
9
python/ajax/js/jquery.ba-dotimeout.min.js
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010
|
||||
* http://benalman.com/projects/jquery-dotimeout-plugin/
|
||||
*
|
||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://benalman.com/about/license/
|
||||
*/
|
||||
(function($){var a={},c="doTimeout",d=Array.prototype.slice;$[c]=function(){return b.apply(window,[0].concat(d.call(arguments)))};$.fn[c]=function(){var f=d.call(arguments),e=b.apply(this,[c+f[0]].concat(f));return typeof f[0]==="number"||typeof f[1]==="number"?this:e};function b(l){var m=this,h,k={},g=l?$.fn:$,n=arguments,i=4,f=n[1],j=n[2],p=n[3];if(typeof f!=="string"){i--;f=l=0;j=n[1];p=n[2]}if(l){h=m.eq(0);h.data(l,k=h.data(l)||{})}else{if(f){k=a[f]||(a[f]={})}}k.id&&clearTimeout(k.id);delete k.id;function e(){if(l){h.removeData(l)}else{if(f){delete a[f]}}}function o(){k.id=setTimeout(function(){k.fn()},j)}if(p){k.fn=function(q){if(typeof p==="string"){p=g[p]}p.apply(m,d.call(n,i))===true&&!q?o():e()};o()}else{if(k.fn){j===undefined?e():k.fn(j===false);return true}else{e()}}}})(jQuery);
|
||||
21
python/ajax/js/jquery.tipTip.minified.js
Normal file
21
python/ajax/js/jquery.tipTip.minified.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* TipTip
|
||||
* Copyright 2010 Drew Wilson
|
||||
* www.drewwilson.com
|
||||
* code.drewwilson.com/entry/tiptip-jquery-plugin
|
||||
*
|
||||
* Version 1.3 - Updated: Mar. 23, 2010
|
||||
*
|
||||
* This Plug-In will create a custom tooltip to replace the default
|
||||
* browser tooltip. It is extremely lightweight and very smart in
|
||||
* that it detects the edges of the browser window and will make sure
|
||||
* the tooltip stays within the current window size. As a result the
|
||||
* tooltip will adjust itself to be displayed above, below, to the left
|
||||
* or to the right depending on what is necessary to stay within the
|
||||
* browser window. It is completely customizable as well via CSS.
|
||||
*
|
||||
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*/
|
||||
(function($){$.fn.tipTip=function(options){var defaults={activation:"hover",keepAlive:false,maxWidth:"200px",edgeOffset:3,defaultPosition:"bottom",delay:400,fadeIn:200,fadeOut:200,attribute:"title",content:false,enter:function(){},exit:function(){}};var opts=$.extend(defaults,options);if($("#tiptip_holder").length<=0){var tiptip_holder=$('<div id="tiptip_holder" style="max-width:'+opts.maxWidth+';"></div>');var tiptip_content=$('<div id="tiptip_content"></div>');var tiptip_arrow=$('<div id="tiptip_arrow"></div>');$("body").append(tiptip_holder.html(tiptip_content).prepend(tiptip_arrow.html('<div id="tiptip_arrow_inner"></div>')))}else{var tiptip_holder=$("#tiptip_holder");var tiptip_content=$("#tiptip_content");var tiptip_arrow=$("#tiptip_arrow")}return this.each(function(){var org_elem=$(this);if(opts.content){var org_title=opts.content}else{var org_title=org_elem.attr(opts.attribute)}if(org_title!=""){if(!opts.content){org_elem.removeAttr(opts.attribute)}var timeout=false;if(opts.activation=="hover"){org_elem.hover(function(){active_tiptip()},function(){if(!opts.keepAlive){deactive_tiptip()}});if(opts.keepAlive){tiptip_holder.hover(function(){},function(){deactive_tiptip()})}}else if(opts.activation=="focus"){org_elem.focus(function(){active_tiptip()}).blur(function(){deactive_tiptip()})}else if(opts.activation=="click"){org_elem.click(function(){active_tiptip();return false}).hover(function(){},function(){if(!opts.keepAlive){deactive_tiptip()}});if(opts.keepAlive){tiptip_holder.hover(function(){},function(){deactive_tiptip()})}}function active_tiptip(){opts.enter.call(this);tiptip_content.html(org_title);tiptip_holder.hide().removeAttr("class").css("margin","0");tiptip_arrow.removeAttr("style");var top=parseInt(org_elem.offset()['top']);var left=parseInt(org_elem.offset()['left']);var org_width=parseInt(org_elem.outerWidth());var org_height=parseInt(org_elem.outerHeight());var tip_w=tiptip_holder.outerWidth();var tip_h=tiptip_holder.outerHeight();var w_compare=Math.round((org_width-tip_w)/2);var h_compare=Math.round((org_height-tip_h)/2);var marg_left=Math.round(left+w_compare);var marg_top=Math.round(top+org_height+opts.edgeOffset);var t_class="";var arrow_top="";var arrow_left=Math.round(tip_w-12)/2;if(opts.defaultPosition=="bottom"){t_class="_bottom"}else if(opts.defaultPosition=="top"){t_class="_top"}else if(opts.defaultPosition=="left"){t_class="_left"}else if(opts.defaultPosition=="right"){t_class="_right"}var right_compare=(w_compare+left)<parseInt($(window).scrollLeft());var left_compare=(tip_w+left)>parseInt($(window).width());if((right_compare&&w_compare<0)||(t_class=="_right"&&!left_compare)||(t_class=="_left"&&left<(tip_w+opts.edgeOffset+5))){t_class="_right";arrow_top=Math.round(tip_h-13)/2;arrow_left=-12;marg_left=Math.round(left+org_width+opts.edgeOffset);marg_top=Math.round(top+h_compare)}else if((left_compare&&w_compare<0)||(t_class=="_left"&&!right_compare)){t_class="_left";arrow_top=Math.round(tip_h-13)/2;arrow_left=Math.round(tip_w);marg_left=Math.round(left-(tip_w+opts.edgeOffset+5));marg_top=Math.round(top+h_compare)}var top_compare=(top+org_height+opts.edgeOffset+tip_h+8)>parseInt($(window).height()+$(window).scrollTop());var bottom_compare=((top+org_height)-(opts.edgeOffset+tip_h+8))<0;if(top_compare||(t_class=="_bottom"&&top_compare)||(t_class=="_top"&&!bottom_compare)){if(t_class=="_top"||t_class=="_bottom"){t_class="_top"}else{t_class=t_class+"_top"}arrow_top=tip_h;marg_top=Math.round(top-(tip_h+5+opts.edgeOffset))}else if(bottom_compare|(t_class=="_top"&&bottom_compare)||(t_class=="_bottom"&&!top_compare)){if(t_class=="_top"||t_class=="_bottom"){t_class="_bottom"}else{t_class=t_class+"_bottom"}arrow_top=-12;marg_top=Math.round(top+org_height+opts.edgeOffset)}if(t_class=="_right_top"||t_class=="_left_top"){marg_top=marg_top+5}else if(t_class=="_right_bottom"||t_class=="_left_bottom"){marg_top=marg_top-5}if(t_class=="_left_top"||t_class=="_left_bottom"){marg_left=marg_left+5}tiptip_arrow.css({"margin-left":arrow_left+"px","margin-top":arrow_top+"px"});tiptip_holder.css({"margin-left":marg_left+"px","margin-top":marg_top+"px"}).attr("class","tip"+t_class);if(timeout){clearTimeout(timeout)}timeout=setTimeout(function(){tiptip_holder.stop(true,true).fadeIn(opts.fadeIn)},opts.delay)}function deactive_tiptip(){opts.exit.call(this);if(timeout){clearTimeout(timeout)}tiptip_holder.fadeOut(opts.fadeOut)}}})}})(jQuery);
|
||||
BIN
python/ajax/logos/lip6sys64.png
Normal file
BIN
python/ajax/logos/lip6sys64.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
python/ajax/logos/lrde64.png
Normal file
BIN
python/ajax/logos/lrde64.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.4 KiB |
BIN
python/ajax/logos/mail.png
Normal file
BIN
python/ajax/logos/mail.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
BIN
python/ajax/logos/spot64s.png
Normal file
BIN
python/ajax/logos/spot64s.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
124
python/ajax/protocol.txt
Normal file
124
python/ajax/protocol.txt
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
This outlines the arguments passed by ltl2tgba.html to spot.py.
|
||||
|
||||
|
||||
Specifying the formula to work with
|
||||
|
||||
f=... the formula
|
||||
|
||||
Formula simplifications (pick many)
|
||||
|
||||
r=br enable Basic Reductions
|
||||
r=lf allow larger formulas
|
||||
r=si enable Syntactic Implications
|
||||
r=eu enable Eventuality and Universality
|
||||
r=lc enable Language Containment
|
||||
|
||||
Choosing the desired output (pick one)
|
||||
|
||||
o=v output version (no other argument needed)
|
||||
o=f output formula
|
||||
o=m output monitor
|
||||
o=a output automaton
|
||||
o=r output run
|
||||
o=t output testing automaton
|
||||
o=v3 output LTL3BA's version (no other argument needed)
|
||||
|
||||
Type of formula output if o=f (pick one)
|
||||
|
||||
ff=o Spot syntax
|
||||
ff=i Spin syntax
|
||||
ff=l LBT syntax
|
||||
ff=g graphviz output of the AST
|
||||
ff=p property dump
|
||||
|
||||
Type of automaton if o=a (pick one)
|
||||
|
||||
af=t TGBA
|
||||
af=s SBA
|
||||
af=i Spin neverclaim
|
||||
|
||||
Type of monitor if o=m (pick one)
|
||||
|
||||
mf=d deterministic
|
||||
mf=n nondeterministic
|
||||
|
||||
Type of automaton for run if o=r (pick one)
|
||||
|
||||
ra=t run on TGBA
|
||||
ra=s run on SBA
|
||||
|
||||
Type of run output if o=r (pick one)
|
||||
|
||||
rf=p print run as text
|
||||
rf=d draw run
|
||||
|
||||
Type of testing automaton if o=t (pick one)
|
||||
|
||||
tf=t TA
|
||||
tf=g GTA
|
||||
tf=a TGTA
|
||||
|
||||
Translator algorithm (pick one)
|
||||
|
||||
t=fm Couvreur/FM
|
||||
t=la Couvreur/LaCIM
|
||||
t=ta Tauriainen/TAA
|
||||
t=l3 LTL3BA
|
||||
t=cs Compositional Suspension
|
||||
|
||||
Couvreur/FM options if t=fm (pick many)
|
||||
|
||||
fm=od Optimize Determinism
|
||||
fm=sm Symbolic Merge
|
||||
fm=bp Branching Postponement
|
||||
fm=fl Fair-Loop approximations
|
||||
|
||||
Couvreur/LA options if t=la
|
||||
|
||||
la=sp Symbolic Pruning
|
||||
|
||||
Tauriainen/TAA options if t=ta
|
||||
|
||||
ta=lc refined rules based on Language Containment
|
||||
|
||||
LTL3BA output options if t=l3 (pick one)
|
||||
|
||||
lo=T output a TGBA
|
||||
lo=U output a BA
|
||||
|
||||
LTL3BA processing options if t=l3 (pick many)
|
||||
|
||||
l3=l LTL formula simplification
|
||||
l3=P suspension in TGBA construction
|
||||
l3=A suspension in alternating automaton construction
|
||||
l3=C SCC simplifications
|
||||
l3=M more deterministic output
|
||||
l3=S direct simulation
|
||||
l3=o on-the-fly simplifications
|
||||
l3=p a-posteriori simplifications
|
||||
|
||||
Compositional Suspension options (pick many)
|
||||
|
||||
cs=w WDBA minimization
|
||||
cs=s simulation
|
||||
cs=e early start of suspended automatas
|
||||
cs=c do not compose suspended formulae (for debugging)
|
||||
cs=o compose obligation subformulae
|
||||
|
||||
Automaton simplifications (pick many)
|
||||
|
||||
as=ps Prune SCC
|
||||
as=wd WDBA minimiztion
|
||||
as=ds Direct Simulation reduction
|
||||
as=rs Reverse Simulation reduction
|
||||
as=is Iterated Simulation reduction (disables ds and rs)
|
||||
|
||||
Testing Automaton options (pick many)
|
||||
|
||||
to=l add a catch-all livelock state
|
||||
to=s produce single-pass variant
|
||||
to=m merge bisimilar states
|
||||
|
||||
Global options
|
||||
|
||||
g=8 Enable UTF-8 output.
|
||||
850
python/ajax/spotcgi.in
Executable file
850
python/ajax/spotcgi.in
Executable file
|
|
@ -0,0 +1,850 @@
|
|||
#!@PYTHON@
|
||||
# -*- mode: python; coding: utf-8 -*-
|
||||
# Copyright (C) 2011, 2012, 2013, 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 sys
|
||||
|
||||
script = ('SCRIPT_NAME' in os.environ)
|
||||
|
||||
if script:
|
||||
# 3600s = 1h
|
||||
sys.stdout.write("""Cache-Control: max-age=3600
|
||||
Content-Type: text/html
|
||||
|
||||
""")
|
||||
|
||||
# Directory for temporary files (images and other auxiliary files).
|
||||
imgdir = 'spotimg'
|
||||
|
||||
# Cache lookup for the QUERY_STRING
|
||||
qs = os.getenv('QUERY_STRING')
|
||||
if qs:
|
||||
import hashlib
|
||||
# We (optimistically) assume no collision from sha1(qs)
|
||||
cachedir = imgdir + '/' + hashlib.sha1(qs.encode('utf-8')).hexdigest()
|
||||
cachename = cachedir + '/html'
|
||||
try:
|
||||
# Is this a request we have already processed?
|
||||
cache = open(cachename, "rb", 0)
|
||||
if hasattr(sys.stdout, 'buffer'):
|
||||
# Python 3+
|
||||
sys.stdout.flush()
|
||||
sys.stdout.buffer.write(cache.read())
|
||||
else:
|
||||
# Python 2.x
|
||||
sys.stdout.write(cache.read())
|
||||
# Touch the directory containing the files we used, so
|
||||
# it that it survives the browser's cache.
|
||||
os.utime(cachedir, None)
|
||||
exit(0)
|
||||
except IOError:
|
||||
# We failed to open the file.
|
||||
# Let's run the rest of the script to create it.
|
||||
pass
|
||||
elif script:
|
||||
sys.stdout.write("<b>QUERY_STRING unset!</b>\n")
|
||||
exit(0)
|
||||
|
||||
# Location of the dot command
|
||||
dot = '@DOT@'
|
||||
dot_bgcolor = '-Gbgcolor=#FFFFFF00'
|
||||
|
||||
svg_output = False # SVG output used to working well with Firefox
|
||||
# only. It now seems to work with recent Chrome
|
||||
# versions as well, but it is still a problem with
|
||||
# Safari, and IE.
|
||||
output_both = True # Create both PNG and SVG. If svg_output is False,
|
||||
# the SVG will be given as a link under the PNG.
|
||||
# Otherwise the PNG is used as alternate contents
|
||||
# for the SVG object.
|
||||
|
||||
if not script:
|
||||
# If this is not run as a cgi script, let's start an HTTP server.
|
||||
try:
|
||||
# Python 3+
|
||||
from http.server import CGIHTTPRequestHandler, HTTPServer
|
||||
except ImportError:
|
||||
# Python 2.x
|
||||
from CGIHTTPServer import CGIHTTPRequestHandler
|
||||
from BaseHTTPServer import HTTPServer
|
||||
|
||||
class MyHandler(CGIHTTPRequestHandler):
|
||||
def is_cgi(self):
|
||||
if self.path.startswith('/cgi-bin/spotcgi.py'):
|
||||
self.cgi_info = '', self.path[9:]
|
||||
return True
|
||||
return False
|
||||
MyHandler.extensions_map[".hoa"] = 'text/x-hoa'
|
||||
|
||||
server_address=('', 8000)
|
||||
if not os.access(imgdir, os.F_OK):
|
||||
# 493 = 0755 but we would have to write 0755 or 0o755
|
||||
# depending on the python version...
|
||||
os.mkdir(imgdir, 493)
|
||||
sys.stdout.write("Directory spotimg/ created.\n")
|
||||
httpd = HTTPServer(server_address, MyHandler)
|
||||
sys.stdout.write("Point your browser to http://localhost:8000/trans.html\n")
|
||||
httpd.serve_forever()
|
||||
|
||||
import cgi
|
||||
import signal
|
||||
import time
|
||||
import os.path
|
||||
|
||||
# We do not output in cachedir directely, in case two
|
||||
# CGI scripts process the same request concurrently.
|
||||
tmpdir = cachedir + '-' + str(os.getpid())
|
||||
cachename = tmpdir + '/html'
|
||||
|
||||
sys.stdout.flush()
|
||||
# Reopen stdout without buffering
|
||||
sys.stdout = os.fdopen(sys.stdout.fileno(), "wb", 0)
|
||||
|
||||
# Redirect stderr to stdout at a low level (so that
|
||||
# even errors from subprocesses get printed).
|
||||
os.dup2(sys.stdout.fileno(), sys.stderr.fileno())
|
||||
|
||||
import cgitb
|
||||
sys.excepthook = cgitb.Hook(file=sys.stderr)
|
||||
|
||||
# Create the temporary cache directory
|
||||
os.mkdir(tmpdir, 493) # See comment above about 0o755 or 0755.
|
||||
|
||||
# Redirect stdout to the cache file, at a low level
|
||||
# for similar reason.
|
||||
fd = os.open(cachename, os.O_CREAT | os.O_WRONLY, 420) # 420 = 0644
|
||||
os.dup2(fd, sys.stdout.fileno())
|
||||
|
||||
# We had to reopen stdout in binary mode to enable unbuffered output,
|
||||
# (disallowed on text I/O by Python 3.x) so starting now, we are not
|
||||
# allowed to send strings to sys.stdout. Always use the following
|
||||
# method instead.
|
||||
def unbufprint(s):
|
||||
if sys.getdefaultencoding() != 'ascii' and type(s) != bytes:
|
||||
sys.stdout.write(s.encode("utf-8"))
|
||||
else:
|
||||
sys.stdout.write(s)
|
||||
|
||||
def finish(kill = False):
|
||||
# Output the result and exit.
|
||||
os.dup2(sys.stderr.fileno(), sys.stdout.fileno())
|
||||
|
||||
cache = open(cachename, "rb", 0)
|
||||
sys.stdout.write(cache.read())
|
||||
|
||||
# Rename tmpdir to its permanent name for caching purpose.
|
||||
# os.rename will fail if cachedir already exist. Since we tested
|
||||
# that initially, it can only happen when two CGI script are
|
||||
# processing the same request concurrently. In that case the
|
||||
# other result is as good as ours, so we just ignore the error.
|
||||
# (We don't bother removing the temporary directory -- it will be
|
||||
# removed by the next cache prune and cannot be created again in
|
||||
# the meantime.)
|
||||
try:
|
||||
os.rename(tmpdir, cachedir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if kill:
|
||||
# Kill all children
|
||||
os.kill(0, signal.SIGTERM)
|
||||
# Should we prune the cache?
|
||||
stamp = imgdir + '/cache.stamp'
|
||||
now = time.time()
|
||||
try:
|
||||
# Prune at most once every hour
|
||||
if now - os.path.getmtime(stamp) < 3600:
|
||||
exit(0)
|
||||
except OSError:
|
||||
# It's OK if the file did not exist.
|
||||
# We will create it.
|
||||
pass
|
||||
# Erase all directories that are older than 2 hours, and all
|
||||
# files that have only one hardlinks. Files that have more than
|
||||
# one hardlinks are referenced to by directories; so the hardlink
|
||||
# count will decrease when the directory is purged.
|
||||
os.system('find ' + imgdir + ' -mindepth 1 -maxdepth 1 -mmin +120 '
|
||||
+ '\( -type d -o -links 1 \) -exec rm -rf {} +')
|
||||
# Create or update the stamp so we know when to run the next prune.
|
||||
open(stamp, "wb", 0)
|
||||
exit(0)
|
||||
|
||||
# Assume Spot is installed
|
||||
sys.path.insert(0, '@pythondir@')
|
||||
|
||||
if ('SERVER_SOFTWARE' in os.environ and
|
||||
os.environ['SERVER_SOFTWARE'].startswith('SimpleHTTP')):
|
||||
# We might be running from the build tree (but it's not sure).
|
||||
# Add the build and source directories first in the search path.
|
||||
# If we are not in the right place, python will find the installed
|
||||
# libraries later.
|
||||
sys.path.insert(0, '@srcdir@/../.libs')
|
||||
sys.path.insert(0, '@srcdir@/..')
|
||||
sys.path.insert(0, '../.libs')
|
||||
sys.path.insert(0, '..')
|
||||
# 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).
|
||||
m = '../.libs:@top_builddir@/spot/.libs:@top_builddir@/buddy/spot/.libs'
|
||||
os.environ['DYLD_LIBRARY_PATH'] = m
|
||||
|
||||
try:
|
||||
# execfile('ltl2tgba.opt') no longuer work with Python 3.
|
||||
exec(compile(open("ltl2tgba.opt").read(), "ltl2tgba.opt", 'exec'))
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
import spot
|
||||
import buddy
|
||||
|
||||
spot.setup(size='8.2,8.2',fillcolor='#FDEDD3')
|
||||
|
||||
def alarm_handler(signum, frame):
|
||||
unbufprint("""<p><font color="red">The script was aborted because
|
||||
it has been running for too long.</font> Please try a shorter formula,
|
||||
or different options.
|
||||
If you want to benchmark big formulae it is
|
||||
better to install Spot on your own computer.</p>\n""")
|
||||
finish(kill = True)
|
||||
|
||||
def run_dot(basename, ext):
|
||||
outname = basename + '.' + ext
|
||||
# Do not call "dot" to generate a file that already exists.
|
||||
if not os.access(outname, os.F_OK):
|
||||
os.spawnlp(os.P_WAIT, dot, dot, dot_bgcolor, '-T' + ext,
|
||||
'-o', outname, basename + '.txt')
|
||||
# Create a unused hardlink that points to the output picture
|
||||
# just to remember how many cache entries are sharing it.
|
||||
os.link(outname, tmpdir + "/" + ext)
|
||||
|
||||
def render_dot(basename, hoaname = None):
|
||||
unbufprint('<div class="dot">')
|
||||
b = cgi.escape(basename)
|
||||
|
||||
if svg_output or output_both:
|
||||
run_dot(basename, 'svg')
|
||||
if not svg_output or output_both:
|
||||
run_dot(basename, 'png')
|
||||
pngstr = '<img src="' + b + '.png">'
|
||||
|
||||
if svg_output:
|
||||
unbufprint('<object type="image/svg+xml" data="' + b + '.svg">')
|
||||
if output_both:
|
||||
unbufprint(pngstr)
|
||||
else:
|
||||
unbufprint('Your browser does not support SVG.')
|
||||
unbufprint('</object>' + '<br>(<a href="' + b
|
||||
+ '.txt">dot</a>)')
|
||||
else:
|
||||
unbufprint('<img src="' + b + '.png"><br>(<a href="' + b
|
||||
+ '.txt">dot</a>)')
|
||||
if output_both:
|
||||
unbufprint(' (<a href="' + b + '.svg">svg</a>)')
|
||||
if hoaname:
|
||||
unbufprint(' (<a href="' + hoaname + '">hoa</a>)')
|
||||
unbufprint('</div>\n')
|
||||
|
||||
def save_hoa(automaton):
|
||||
hoasrc = spot.ostringstream()
|
||||
spot.print_hoa(hoasrc, automaton, 't' if buchi_type == 't' else '')
|
||||
hoasrc = hoasrc.str()
|
||||
hoasrc += '\n'
|
||||
if sys.getdefaultencoding() != 'ascii':
|
||||
hoasrc = hoasrc.encode('utf-8')
|
||||
autprefix = (imgdir + '/' + hashlib.sha1(hoasrc).hexdigest())
|
||||
hoaname = autprefix + '.hoa'
|
||||
if not os.access(hoaname, os.F_OK):
|
||||
hoaout = open(hoaname, "wb", 0)
|
||||
hoaout.write(hoasrc)
|
||||
hoaout.close()
|
||||
# Create a unused hardlink that points to the output HOA
|
||||
# just to remember how many cache entries are sharing it.
|
||||
os.link(hoaname, tmpdir + "/hoa")
|
||||
return hoaname
|
||||
|
||||
def render_dot_maybe(dotsrc, dont_run_dot, hoaname = None):
|
||||
# The dot output is named after the SHA1 of the dot source.
|
||||
# This way we can cache two different requests that generate
|
||||
# the same automaton (e.g., when changing a simplification
|
||||
# option that has no influence).
|
||||
if sys.getdefaultencoding() != 'ascii':
|
||||
dotsrc = dotsrc.encode('utf-8')
|
||||
# If the text rendering engine (usually Pango) used by dot does
|
||||
# not draw overlines correctly, uncomment the following two
|
||||
# lines. Pango 1.28.4 seems not to support combining overline
|
||||
# while 1.30 does.
|
||||
#import re
|
||||
#dotsrc = re.sub(r'(.)(̅|̄)', r'¬\1', dotsrc);
|
||||
autprefix = (imgdir + '/' + hashlib.sha1(dotsrc).hexdigest())
|
||||
dotname = autprefix + '.txt'
|
||||
if not os.access(dotname, os.F_OK):
|
||||
dotout = open(dotname, "wb", 0)
|
||||
dotout.write(dotsrc)
|
||||
dotout.close()
|
||||
# Create a unused hardlink that points to the output picture
|
||||
# just to remember how many cache entries are sharing it.
|
||||
os.link(dotname, tmpdir + "/txt")
|
||||
|
||||
if dont_run_dot:
|
||||
unbufprint('<p>' + dont_run_dot + ''' to be rendered on-line.
|
||||
However you may download the <a href="''' + cgi.escape(autprefix)
|
||||
+ '.txt">source in dot format</a> and render it yourself.</p>\n')
|
||||
else:
|
||||
render_dot(autprefix, hoaname)
|
||||
|
||||
def render_automaton(automaton, dont_run_dot):
|
||||
hoaname = None
|
||||
dotsrc = spot.ostringstream()
|
||||
if isinstance(automaton, spot.ta): # TA/GTA
|
||||
spot.print_dot(dotsrc, automaton)
|
||||
elif hasattr(automaton, 'get_ta'): # TGTA
|
||||
spot.print_dot(dotsrc, automaton.get_ta())
|
||||
else: # TGBA
|
||||
if not dont_run_dot:
|
||||
hoaname = save_hoa(automaton)
|
||||
spot.print_dot(dotsrc, automaton, '.t' if buchi_type == 't' else '.')
|
||||
render_dot_maybe(dotsrc.str(), dont_run_dot, hoaname)
|
||||
|
||||
def render_formula(f):
|
||||
dotsrc = spot.ostringstream()
|
||||
spot.print_dot_psl(dotsrc, f)
|
||||
render_dot_maybe(dotsrc.str(), False)
|
||||
|
||||
def print_stats(automaton, detinfo = False, ta = False):
|
||||
if ta: # TA/GTA
|
||||
if hasattr(automaton, 'get_ta'): # TGTA
|
||||
automaton = automaton.get_ta()
|
||||
stats = spot.stats_reachable(automaton)
|
||||
detinfo = False
|
||||
else:
|
||||
if (buchi_type == 't' and automaton.prop_inherently_weak() and
|
||||
automaton.acc().is_buchi()):
|
||||
unbufprint("Note: this is a weak automaton, using transition-based "
|
||||
"or generalized acceptance does not bring any benefit."
|
||||
"</br>")
|
||||
stats = spot.sub_stats_reachable(automaton)
|
||||
unbufprint("<p>%d state" % stats.states)
|
||||
if stats.states > 1:
|
||||
unbufprint("s")
|
||||
if detinfo:
|
||||
nondet = spot.count_nondet_states(automaton)
|
||||
if nondet == 0:
|
||||
unbufprint(" (deterministic)")
|
||||
else:
|
||||
unbufprint(" (%d nondeterministic)" % nondet)
|
||||
if not hasattr(stats, 'transitions'):
|
||||
unbufprint(", %d edge" % stats.edges)
|
||||
if stats.edges > 1:
|
||||
unbufprint("s")
|
||||
else:
|
||||
unbufprint(", %d edge%s (%d transition%s)"
|
||||
% (stats.edges, 's' if stats.edges > 1 else '',
|
||||
stats.transitions, 's' if stats.transitions > 1 else ''))
|
||||
if hasattr(automaton, 'get_acceptance'):
|
||||
acc = automaton.get_acceptance()
|
||||
if (automaton.is_sba() and automaton.acc().is_buchi() and
|
||||
buchi_type != 't'):
|
||||
unbufprint(", acceptance condition: Büchi")
|
||||
else:
|
||||
unbufprint(", acceptance condition: " + str(acc))
|
||||
if acc.is_tt():
|
||||
unbufprint(" (all cycles are accepting)")
|
||||
unbufprint("</p>\n")
|
||||
# Decide whether we will render the automaton or not.
|
||||
# (A webserver is not a computation center...)
|
||||
if stats.states > 64:
|
||||
return "Automaton has too many states"
|
||||
if float(stats.edges)/stats.states > 10:
|
||||
return "Automaton has too many edges per state"
|
||||
return False
|
||||
|
||||
def format_formula(f, kind='div'):
|
||||
if utf8:
|
||||
s = f.to_str('utf8')
|
||||
else:
|
||||
s = f.to_str()
|
||||
return '<%s class="formula spot-format">%s</%s>' % (kind, s, kind)
|
||||
|
||||
form = cgi.FieldStorage()
|
||||
|
||||
output_type = form.getfirst('o', 'v');
|
||||
|
||||
# Version requested.
|
||||
if output_type == 'v':
|
||||
unbufprint('Spot version %s\n' % spot.version())
|
||||
finish()
|
||||
|
||||
# ltl3ba's version
|
||||
if output_type == 'v3':
|
||||
import subprocess
|
||||
try:
|
||||
l3proc = subprocess.Popen(['@LTL3BA@', '-v'], stdout=subprocess.PIPE)
|
||||
(ver, err) = l3proc.communicate()
|
||||
# -M[0|1] is new in 1.1.1, and we use it.
|
||||
l3proc = subprocess.Popen(['@LTL3BA@', '-h'], stdout=subprocess.PIPE)
|
||||
(out, err) = l3proc.communicate()
|
||||
if out.find(b'-M[') < 0:
|
||||
err = 1
|
||||
else:
|
||||
err = 0
|
||||
except:
|
||||
err = 1
|
||||
if err != 0:
|
||||
unbufprint('not available')
|
||||
else:
|
||||
unbufprint(ver.replace(b"\n", b"<br>"))
|
||||
finish()
|
||||
|
||||
spot.unblock_signal(signal.SIGALRM)
|
||||
spot.unblock_signal(signal.SIGTERM)
|
||||
os.setpgrp()
|
||||
|
||||
child = os.fork()
|
||||
if child != 0:
|
||||
# In parent. We are just waiting for the termination of the
|
||||
# child, or for the timeout alarm. On SIGALRM, we will kill the
|
||||
# child.
|
||||
#
|
||||
# We cannot avoid forking, because Python will not deliver a
|
||||
# signal when a C function is running. So if Spot takes too long
|
||||
# to translate some formula, it would not get interrupted.
|
||||
signal.signal(signal.SIGALRM, alarm_handler)
|
||||
signal.alarm(30)
|
||||
os.waitpid(child, 0)
|
||||
exit(0)
|
||||
|
||||
# Global options
|
||||
utf8 = False
|
||||
for g in form.getlist('g'):
|
||||
if g == '8':
|
||||
utf8 = True
|
||||
spot.enable_utf8()
|
||||
|
||||
formula = form.getfirst('f', '')
|
||||
|
||||
env = spot.default_environment.instance()
|
||||
pel = spot.empty_parse_error_list()
|
||||
f = spot.parse_infix_psl(formula, pel, env)
|
||||
|
||||
if pel:
|
||||
# Try the LBT parser in case someone is throwing LBT formulas at us.
|
||||
pel2 = spot.empty_parse_error_list()
|
||||
g = spot.parse_prefix_ltl(formula, pel2, env)
|
||||
if pel2:
|
||||
unbufprint('<div class="parse-error">')
|
||||
err = spot.format_parse_errors(spot.get_cout(), formula, pel)
|
||||
unbufprint('</div>')
|
||||
else:
|
||||
f = g
|
||||
|
||||
# Do not continue if we could not parse anything sensible.
|
||||
if not f:
|
||||
finish()
|
||||
|
||||
# Formula simplifications
|
||||
simpopt = spot.tl_simplifier_options(False, False, False,
|
||||
False, False, False, True)
|
||||
dored = False
|
||||
for r in form.getlist('r'):
|
||||
dored = True
|
||||
if r == 'br':
|
||||
simpopt.reduce_basics = True
|
||||
elif r == 'lf':
|
||||
simpopt.reduce_size_strictly = False
|
||||
elif r == 'si':
|
||||
simpopt.synt_impl = True
|
||||
elif r == 'eu':
|
||||
simpopt.event_univ = True
|
||||
elif r == 'lc':
|
||||
simpopt.containment_checks = True
|
||||
simpopt.containment_checks_stronger = True
|
||||
if dored:
|
||||
# Not keeping the ltl simplifier aive will also clear the as_bdd()
|
||||
# cache.
|
||||
f = spot.tl_simplifier(simpopt).simplify(f)
|
||||
|
||||
# Formula manipulation only.
|
||||
if output_type == 'f':
|
||||
formula_format = form.getfirst('ff', 'o')
|
||||
# o = Spot, i = Spin, l = LBT, g = GraphViz, p = properties
|
||||
if formula_format == 'o':
|
||||
unbufprint(format_formula(f))
|
||||
elif formula_format == 'i':
|
||||
unbufprint('<div class="formula spin-format">'
|
||||
+ spot.str_spin_ltl(f) + '</div>')
|
||||
if f.is_psl_formula() and not f.is_ltl_formula():
|
||||
s = ''
|
||||
if simpopt.reduce_size_strictly:
|
||||
s = '<br><b>Try enabling larger formula rewritings.</b>'
|
||||
unbufprint('<div class="error">The above formula contains PSL operators that Spin will not understand.%s</div>' % s)
|
||||
elif formula_format == 'l':
|
||||
if not f.is_ltl_formula():
|
||||
unbufprint('<div class="error">PSL formulas cannot be expressed in this format.</div>')
|
||||
else:
|
||||
unbufprint('<div class="formula lbt-format">' + spot.str_lbt_ltl(f) + '</div>')
|
||||
elif formula_format == 'g':
|
||||
render_formula(f)
|
||||
elif formula_format == 'p':
|
||||
if utf8:
|
||||
s = spot.str_utf8_psl(f)
|
||||
else:
|
||||
s = str(f)
|
||||
unbufprint('Properties for ' + format_formula(f, 'span') + '<ul>\n')
|
||||
for p in spot.list_formula_props(f):
|
||||
unbufprint('<li>%s</li>\n' % p)
|
||||
|
||||
# Attempt to refine the hierarchy class using WDBA minimization
|
||||
if not f.is_syntactic_safety() or not f.is_syntactic_guarantee():
|
||||
dict = spot.bdd_dict()
|
||||
automaton = spot.ltl_to_tgba_fm(f, dict, False, True)
|
||||
minimized = spot.minimize_obligation(automaton, f)
|
||||
if minimized != automaton:
|
||||
g = spot.is_terminal_automaton(minimized)
|
||||
s = spot.is_safety_mwdba(minimized)
|
||||
if s and not f.is_syntactic_safety():
|
||||
unbufprint('<li>pathologic safety</li>')
|
||||
if g and not f.is_syntactic_guarantee():
|
||||
unbufprint('<li>pathologic guarantee</li>')
|
||||
if not f.is_syntactic_obligation():
|
||||
unbufprint('<li>obligation (although not syntactically)</li>')
|
||||
else:
|
||||
unbufprint('<li>not an obligation</li>')
|
||||
minimized = 0
|
||||
automaton = 0
|
||||
if not f.is_syntactic_stutter_invariant():
|
||||
if spot.is_stutter_invariant(f):
|
||||
unbufprint('<li>stutter invariant</li>')
|
||||
else:
|
||||
unbufprint('<li>stutter sensitive</li>')
|
||||
unbufprint('</ul>\n')
|
||||
finish()
|
||||
|
||||
# Formula translation.
|
||||
translator = form.getfirst('t', 'fm')
|
||||
|
||||
if f.is_psl_formula() and not f.is_ltl_formula() and translator != 'fm':
|
||||
unbufprint('''<div class="error">The PSL formula %s
|
||||
cannot be translated using this algorithm. Please use Couveur/FM.'''
|
||||
% format_formula(f, 'span'))
|
||||
finish()
|
||||
|
||||
dict = spot.make_bdd_dict()
|
||||
|
||||
if output_type == 't' and not spot.is_stutter_invariant(f):
|
||||
unbufprint('<b>Warning:</b> Testing automata are only valid '
|
||||
+ 'for stutter-insensitive formulas, but the input is not.</br>')
|
||||
|
||||
# Should the automaton be displayed as a SBA?
|
||||
issba = False
|
||||
|
||||
if translator == 'fm':
|
||||
exprop = False
|
||||
symb_merge = False
|
||||
branching_postponement = False
|
||||
fair_loop_approx = False
|
||||
for fm in form.getlist('fm'):
|
||||
if fm == 'od':
|
||||
exprop = True
|
||||
elif fm == 'sm':
|
||||
symb_merge = True
|
||||
elif fm == 'bp':
|
||||
branching_postponement = True
|
||||
elif fm == 'fl':
|
||||
fair_loop_approx = True
|
||||
automaton = spot.ltl_to_tgba_fm(f, dict,
|
||||
exprop, symb_merge,
|
||||
branching_postponement, fair_loop_approx)
|
||||
elif translator == 'ta':
|
||||
refined_rules = False
|
||||
if form.getfirst('ta', '') == 'lc':
|
||||
refined_rules = True
|
||||
automaton = spot.ensure_digraph(spot.ltl_to_taa(f, dict, refined_rules))
|
||||
|
||||
elif translator == 'l3':
|
||||
l3out = '-H2'
|
||||
# 1.0.1 had determinization and simulation turned off by default,
|
||||
# we need -M0 and -S0 with 1.1.1 for the same effect
|
||||
l3opt = { '-l', '-P', '-A', '-c', '-C', '-o', '-p', '-M0', '-S0' }
|
||||
for lo in form.getfirst('lo', 'T'):
|
||||
if lo == 'U':
|
||||
l3out = '-H3'
|
||||
issba = True
|
||||
for l3 in form.getlist('l3'):
|
||||
if l3 == 'l':
|
||||
l3opt.remove('-l')
|
||||
elif l3 == 'P':
|
||||
l3opt.remove('-P')
|
||||
elif l3 == 'A':
|
||||
l3opt.remove('-A')
|
||||
elif l3 == 'C':
|
||||
l3opt.remove('-C')
|
||||
l3opt.remove('-c')
|
||||
elif l3 == 'M':
|
||||
l3opt.remove('-M0')
|
||||
l3opt.add('-M1')
|
||||
elif l3 == 'S':
|
||||
l3opt.remove('-S0')
|
||||
l3opt.add('-S2') # was -S in 1.0.1
|
||||
elif l3 == 'o':
|
||||
l3opt.remove('-o')
|
||||
elif l3 == 'p':
|
||||
l3opt.remove('-p')
|
||||
args = ["@LTL3BA@", l3out]
|
||||
args.extend(l3opt)
|
||||
# Relabel the formula in case it contains unsupported atomic
|
||||
# propositions (e.g., starting with _ or double-quoted).
|
||||
m = spot.relabeling_map()
|
||||
g = spot.relabel(f, spot.Pnn, m)
|
||||
args.extend(['-f', "'" + spot.str_spin_ltl(g) + "' |"])
|
||||
try:
|
||||
automaton = spot.automaton(" ".join(args))
|
||||
except RuntimeError as e:
|
||||
unbufprint('<div class="error">{}</div>'.format(e))
|
||||
finish()
|
||||
spot.relabel_here(automaton, m)
|
||||
elif translator == 'cs':
|
||||
donot_inject = False
|
||||
cs_nowdba = True
|
||||
cs_nosimul = True
|
||||
cs_early_start = False
|
||||
for cs in form.getlist('cs'):
|
||||
if cs == 'c':
|
||||
donot_inject = True
|
||||
elif cs == 'w':
|
||||
cs_nowdba = False
|
||||
elif cs == 's':
|
||||
cs_nosimul = False
|
||||
elif cs == 'e':
|
||||
cs_early_start = True
|
||||
|
||||
automaton = spot.compsusp(f, dict, cs_nowdba, cs_nosimul,
|
||||
cs_early_start, donot_inject)
|
||||
else:
|
||||
unbufprint('''<div class="error">unsupported translator</div>''')
|
||||
finish()
|
||||
|
||||
buchi_type = None
|
||||
|
||||
# Monitor output
|
||||
if output_type == 'm':
|
||||
issba = True
|
||||
mf = form.getfirst('mf', 'd')
|
||||
pp = spot.postprocessor()
|
||||
pp.set_type(spot.postprocessor.Monitor)
|
||||
if mf == 'd':
|
||||
pp.set_pref(spot.postprocessor.Deterministic)
|
||||
elif mf == 'n':
|
||||
pp.set_pref(spot.postprocessor.Small)
|
||||
automaton = pp.run(automaton, f)
|
||||
unbufprint('<div class="automata-stats">')
|
||||
dont_run_dot = print_stats(automaton)
|
||||
unbufprint('</div>')
|
||||
automaton.set_name(str(f))
|
||||
render_automaton(automaton, dont_run_dot)
|
||||
automaton = 0
|
||||
finish()
|
||||
|
||||
# Automaton simplifications
|
||||
prune_scc = False
|
||||
wdba_minimize = False
|
||||
direct_simul = False
|
||||
reverse_simul = False
|
||||
iterated_simul = False
|
||||
for s in form.getlist('as'):
|
||||
if s == 'ps':
|
||||
prune_scc = True
|
||||
elif s == 'wd':
|
||||
wdba_minimize = True
|
||||
elif s == 'ds':
|
||||
direct_simul = True
|
||||
elif s == 'rs':
|
||||
reverse_simul = True
|
||||
elif s == 'is':
|
||||
iterated_simul = True
|
||||
|
||||
ta_type = None
|
||||
|
||||
if output_type == 'a':
|
||||
buchi_type = form.getfirst('af', 't')
|
||||
elif output_type == 'r':
|
||||
buchi_type = form.getfirst('ra', 't')
|
||||
elif output_type == 't':
|
||||
ta_type = form.getfirst('tf', 't')
|
||||
else:
|
||||
unbufprint("Unkown output type 'o=%s'.\n" % output_type)
|
||||
automaton = 0
|
||||
finish()
|
||||
|
||||
degen = False
|
||||
neverclaim = False
|
||||
|
||||
if buchi_type == 's' or ta_type == 't':
|
||||
degen = True
|
||||
elif buchi_type == 'i':
|
||||
degen = True
|
||||
neverclaim = True
|
||||
|
||||
if output_type == 't':
|
||||
ta_type = form.getfirst('tf', 't')
|
||||
if ta_type == 't':
|
||||
degen = True
|
||||
|
||||
if prune_scc:
|
||||
# Do not suppress all useless acceptance conditions if
|
||||
# degeneralization or simulation is requested: keeping those that
|
||||
# lead to accepting states usually helps.
|
||||
automaton = spot.scc_filter(automaton, not (degen
|
||||
or direct_simul
|
||||
or reverse_simul
|
||||
or iterated_simul))
|
||||
|
||||
if wdba_minimize:
|
||||
minimized = spot.minimize_obligation(automaton, f)
|
||||
if minimized != automaton:
|
||||
automaton = minimized
|
||||
minimized = 0
|
||||
degen = False # No need to degeneralize anymore
|
||||
direct_simul = False # No need to simulate anymore
|
||||
reverse_simul = False
|
||||
iterated_simul = False
|
||||
|
||||
if direct_simul and not iterated_simul:
|
||||
automaton = spot.simulation(automaton)
|
||||
if reverse_simul and not iterated_simul:
|
||||
automaton = spot.cosimulation(automaton)
|
||||
if iterated_simul:
|
||||
automaton = spot.iterated_simulations(automaton)
|
||||
|
||||
if prune_scc and (direct_simul or reverse_simul):
|
||||
# Make a second pass after the simulation, since these might leave
|
||||
# extra acceptance conditions.
|
||||
automaton = spot.scc_filter(automaton, not degen)
|
||||
|
||||
if degen or neverclaim:
|
||||
degen = spot.degeneralize(automaton)
|
||||
else:
|
||||
degen = automaton
|
||||
|
||||
# Buchi Automaton Output
|
||||
if output_type == 'a':
|
||||
if buchi_type == 'i':
|
||||
s = spot.ostringstream()
|
||||
spot.print_never_claim(s, degen)
|
||||
unbufprint('<div class="neverclaim">%s</div>' % cgi.escape(s.str()))
|
||||
del s
|
||||
else: # 't' or 's'
|
||||
dont_run_dot = print_stats(degen, True)
|
||||
automaton.set_name(str(f))
|
||||
render_automaton(degen, dont_run_dot)
|
||||
degen = 0
|
||||
automaton = 0
|
||||
finish()
|
||||
|
||||
# Testing automaton Output
|
||||
if output_type == 't':
|
||||
livelock = False
|
||||
singlepass = False
|
||||
bisimulation = False
|
||||
for to in form.getlist('to'):
|
||||
if to == 'l':
|
||||
livelock = True
|
||||
elif to == 's':
|
||||
singlepass = True
|
||||
elif to == 'm':
|
||||
bisimulation = True
|
||||
propset = spot.atomic_prop_collect_as_bdd(f, automaton)
|
||||
if ta_type == 'a':
|
||||
tautomaton = spot.tgba_to_tgta(degen, propset)
|
||||
if bisimulation:
|
||||
tautomaton = spot.minimize_tgta(tautomaton)
|
||||
else:
|
||||
tautomaton = spot.tgba_to_ta(degen, propset,
|
||||
True, True, singlepass, livelock)
|
||||
if bisimulation:
|
||||
tautomaton = spot.minimize_ta(tautomaton)
|
||||
dont_run_dot = print_stats(tautomaton, ta = True)
|
||||
render_automaton(tautomaton, dont_run_dot)
|
||||
tautomaton = 0
|
||||
degen = 0
|
||||
automaton = 0
|
||||
finish()
|
||||
|
||||
# Buchi Run Output
|
||||
if output_type == 'r':
|
||||
|
||||
print_acc_run = False
|
||||
s = form.getfirst('rf', 'd')
|
||||
draw_acc_run = False
|
||||
if s == 'p':
|
||||
print_acc_run = True
|
||||
elif s == 'd':
|
||||
draw_acc_run = True
|
||||
|
||||
err = ""
|
||||
opt = (form.getfirst('ec', 'Cou99') + "(" +
|
||||
form.getfirst('eo', '') + ")")
|
||||
eci, err = spot.make_emptiness_check_instantiator(opt)
|
||||
|
||||
if not eci:
|
||||
unbufprint('<div class="parse-error">Cannot parse "' + opt
|
||||
+ '" near "' + err + '".</div>')
|
||||
ec = 0
|
||||
else:
|
||||
ec_a = 0
|
||||
n_acc = degen.acc().num_sets()
|
||||
n_max = eci.max_acceptance_conditions()
|
||||
n_min = eci.min_acceptance_conditions()
|
||||
if (n_acc <= n_max):
|
||||
if (n_acc >= n_min):
|
||||
ec_a = degen
|
||||
else:
|
||||
unbufprint('<div class="ec-error">Cannot run ' + opt
|
||||
+ ' on automata with less than ' + str(n_min)
|
||||
+ ' acceptance condition.<br/>Please build '
|
||||
+ 'a degeneralized Büchi automaton if you '
|
||||
+ 'want to try this algorithm.</div>')
|
||||
else:
|
||||
unbufprint('<div class="ec-error">Cannot run ' + opt
|
||||
+ ' on automata with more than ' + str(n_max)
|
||||
+ ' acceptance condition.<br/>Please build '
|
||||
+ 'a degeneralized Büchi automaton if you '
|
||||
+ 'want to try this algorithm.</div>')
|
||||
if ec_a:
|
||||
ec = eci.instantiate(ec_a)
|
||||
else:
|
||||
ec = 0
|
||||
|
||||
if ec:
|
||||
ec_res = ec.check()
|
||||
if not ec_res:
|
||||
unbufprint('<div class="ec">No accepting run found.</div>')
|
||||
else:
|
||||
ec_run = ec_res.accepting_run()
|
||||
unbufprint('<div class="ec">An accepting run was found.<br/>')
|
||||
if ec_run:
|
||||
if print_acc_run:
|
||||
unbufprint('<div class="accrun">%s</div>' %
|
||||
cgi.escape(str(ec_run)))
|
||||
if draw_acc_run:
|
||||
render_automaton(ec_run.as_twa(), False)
|
||||
del ec_run
|
||||
del ec_res
|
||||
unbufprint('</div>')
|
||||
finish()
|
||||
758
python/ajax/trans.html
Normal file
758
python/ajax/trans.html
Normal file
|
|
@ -0,0 +1,758 @@
|
|||
<!doctype HTML public "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Spot's online LTL-to-TGBA translator</title>
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
|
||||
<meta name="keywords" content="Spot,LTL,automata,Büchi,translation,TGBA">
|
||||
<meta name="description" content="Translate LTL or PSL formulas into Büchi automata online using the Spot model-checking library">
|
||||
<link rev=Made href="mailto:spot@lrde.epita.fr" title="Spot's discussion list">
|
||||
<link rel="stylesheet" href="css/tipTip.css">
|
||||
<link rel="icon" href="http://spot.lrde.epita.fr/img/favicon.ico" type="image/x-icon">
|
||||
<link rel="shortcut icon" href="http://spot.lrde.epita.fr/img/favicon.ico" type="image/x-icon">
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/themes/ui-lightness/jquery-ui.css">
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js"></script>
|
||||
<link rel="stylesheet" href="css/trans.css">
|
||||
<script type="text/javascript" src="js/jquery.tipTip.minified.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.ba-bbq.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery.ba-dotimeout.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function(){
|
||||
$.spotvars = { autoupdate: false,
|
||||
scrolldown: true,
|
||||
internalchange: false};
|
||||
$(".tabs").tabs();
|
||||
$("#send").button();
|
||||
$("#results").hide();
|
||||
$("abbr").tipTip({maxWidth: "300px", delay: 1000,
|
||||
edgeOffset: 3,
|
||||
defaultPosition: "below"});
|
||||
$(".rtip").tipTip({maxWidth: "300px", delay: 1000,
|
||||
edgeOffset: 10,
|
||||
defaultPosition: "right"});
|
||||
$(".btip").tipTip({maxWidth: "300px", delay: 1000,
|
||||
edgeOffset: 10,
|
||||
defaultPosition: "bottom"});
|
||||
$(".ftip").tipTip({maxWidth: "300px", delay: 1000,
|
||||
edgeOffset: 4,
|
||||
defaultPosition: "left",
|
||||
content: "<b>Click<\/b> to fold/unfold.<br><b>Ctrl+Click<\/b> to remove (any option set will remain set)."
|
||||
});
|
||||
$(".restip").tipTip({maxWidth: "300px", delay: 1000,
|
||||
edgeOffset: 4,
|
||||
defaultPosition: "left",
|
||||
content: "<b>Click<\/b> to fold/unfold.<br><b>Ctrl+Click<\/b> to remove."
|
||||
});
|
||||
$(".ltltip").tipTip({maxWidth: "300px", delay: 1000,
|
||||
edgeOffset: 4,
|
||||
defaultPosition: "left",
|
||||
content: "<b>Click<\/b> to fold/unfold."
|
||||
});
|
||||
$("#brcheckbox").change(function() {
|
||||
if (!$(this).is(':checked')) {
|
||||
$("#lfcheckbox").removeAttr('checked');
|
||||
}
|
||||
})
|
||||
|
||||
$("#lfcheckbox").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#brcheckbox").attr('checked', true);
|
||||
}
|
||||
})
|
||||
|
||||
$("#ltl3ba-T").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#ltl3ba-S").removeAttr('checked');
|
||||
}
|
||||
})
|
||||
$("#ltl3ba-S").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#ltl3ba-U").attr('checked', true);
|
||||
}
|
||||
})
|
||||
$("#to-s").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#to-l").removeAttr('checked');
|
||||
}
|
||||
})
|
||||
$("#to-l").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#to-s").removeAttr('checked');
|
||||
}
|
||||
})
|
||||
$("#tf-t,#tf-g").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#to-l,#to-s").removeAttr('disabled');
|
||||
}
|
||||
})
|
||||
$("#tf-a").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#to-l,#to-s").attr('disabled', true);
|
||||
}
|
||||
})
|
||||
$("#as-ds,#as-rs").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#as-is").removeAttr('checked');
|
||||
}
|
||||
})
|
||||
$("#as-is").change(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$("#as-ds,#as-rs").removeAttr('checked');
|
||||
}
|
||||
})
|
||||
|
||||
function hideOrShowPanels(output, duration) {
|
||||
switch (output)
|
||||
{
|
||||
case 'f':
|
||||
$('#translator-tabs,#autsimp-tabs,#run-tabs,#tester-tabs').hide(duration);
|
||||
break;
|
||||
case 'm':
|
||||
$('#autsimp-tabs,#run-tabs,#tester-tabs').hide(duration);
|
||||
$('#translator-tabs').not('.killed').show(duration);
|
||||
break;
|
||||
case 'a':
|
||||
$('#translator-tabs,#autsimp-tabs').not('.killed').show(duration);
|
||||
$('#run-tabs,#tester-tabs').hide(duration);
|
||||
break;
|
||||
case 't':
|
||||
$('#translator-tabs,#autsimp-tabs,#tester-tabs').not('.killed').show(duration);
|
||||
$('#run-tabs').hide(duration);
|
||||
break;
|
||||
case 'r':
|
||||
$('#translator-tabs,#autsimp-tabs,#run-tabs').not('.killed').show(duration);
|
||||
$('#tester-tabs').hide(duration);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function updateFormFromHash(duration) {
|
||||
var hashparam = jQuery.deparam.fragment();
|
||||
if (jQuery.isEmptyObject(hashparam))
|
||||
return;
|
||||
if (!$.spotvars.internalchange)
|
||||
$("input,select", "#trform").each(function() {
|
||||
var name = this.name;
|
||||
var value = [];
|
||||
if (name && hashparam[name] != undefined) {
|
||||
value = hashparam[name];
|
||||
if (value.constructor != Array)
|
||||
value = [value];
|
||||
}
|
||||
switch(this.type || this.tagName.toLowerCase()) {
|
||||
case "radio":
|
||||
case "checkbox":
|
||||
this.checked = false;
|
||||
for(var i = 0; i < value.length; i++) {
|
||||
this.checked |= (value[i] == this.value);
|
||||
}
|
||||
break;
|
||||
case "select":
|
||||
for(var opt = 0; opt < this.options.length; opt++) {
|
||||
var option = this.options[opt];
|
||||
option.selected = false;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
option.selected |= (value[i] == option.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.value=value.join(',');
|
||||
}
|
||||
});
|
||||
$("#brcheckbox,#tf-a").change();
|
||||
$.spotvars.autoupdate = true;
|
||||
$.spotvars.internalchange = false;
|
||||
var o = $('input[name="o"]').val();
|
||||
hideOrShowPanels(o, duration);
|
||||
$("#output-tabs").tabs('option', 'active',
|
||||
$('#output-tabs a[href="#tabs-o' + o + '"]').parent().index() - 1);
|
||||
var t = $('input[name="t"]').val();
|
||||
$("#translator-tabs").tabs('option', 'active',
|
||||
$('#translator-tabs a[href="#tabs-t' + t + '"]').parent().index() - 1);
|
||||
updateResults();
|
||||
}
|
||||
|
||||
$(window).bind('hashchange', function(e) { updateFormFromHash('fast') });
|
||||
|
||||
$.get("/cgi-bin/spotcgi.py", "o=v", function(data) {
|
||||
$("#spottip").attr("title", "This page uses <b>" + data + "<\/b> to process LTL formulas and automata. Please download the <b>Spot<\/b> library and install it on your computer if you want to do the same from the command line, or from another program.")
|
||||
.tipTip({maxWidth: "400px", delay: 1000,
|
||||
edgeOffset: 10,
|
||||
defaultPosition: "right"});
|
||||
});
|
||||
|
||||
$.get("/cgi-bin/spotcgi.py", "o=v3", function(data) {
|
||||
if (data != 'not available') {
|
||||
$("#ltl3ba-link").attr("title", data)
|
||||
.tipTip({maxWidth: "400px", delay: 1000,
|
||||
edgeOffset: 10,
|
||||
defaultPosition: "right"});
|
||||
} else {
|
||||
var index = $('#translator-tabs a[href="#tabs-tl3"]').parent().index();
|
||||
$("#translator-tabs").tabs("option", "disabled", [index - 1]);
|
||||
}
|
||||
});
|
||||
|
||||
function fold(ui, callback) {
|
||||
var icon = ui.children(".ui-icon");
|
||||
icon.removeClass("ui-icon-circle-arrow-n")
|
||||
.addClass("ui-icon-circle-arrow-s");
|
||||
ui.siblings('[class!="dontcollapse"]').hide('fast', callback);
|
||||
}
|
||||
function unfold(ui, noshowsiblings) {
|
||||
var icon = ui.children(".ui-icon");
|
||||
icon.removeClass("ui-icon-circle-arrow-s")
|
||||
.addClass("ui-icon-circle-arrow-n");
|
||||
if (!noshowsiblings) {
|
||||
ui.siblings('[class!="dontcollapse"]').show('fast');
|
||||
}
|
||||
}
|
||||
|
||||
function foldToggle(ui) {
|
||||
var icon = ui.children(".ui-icon");
|
||||
if (icon.hasClass("ui-icon-circle-arrow-n")) {
|
||||
icon.removeClass("ui-icon-circle-arrow-n")
|
||||
.addClass("ui-icon-circle-arrow-s");
|
||||
ui.siblings('[class!="dontcollapse"]').hide('fast');
|
||||
} else {
|
||||
icon.removeClass("ui-icon-circle-arrow-s")
|
||||
.addClass("ui-icon-circle-arrow-n");
|
||||
ui.siblings('[class!="dontcollapse"]').show('fast');
|
||||
}
|
||||
}
|
||||
|
||||
function updateHash() {
|
||||
var str = $("#trform").serialize();
|
||||
// This will trigger updateResults.
|
||||
window.location.hash = "#" + str;
|
||||
$.spotvars.internalchange = true;
|
||||
// updateResults();
|
||||
}
|
||||
|
||||
function updateResults() {
|
||||
// If the answer takes more that 200ms to arrive,
|
||||
// display a busy indicator.
|
||||
$.doTimeout('res-update', 200, function(){
|
||||
$("#results-body").hide();
|
||||
$("#results-loading").show();
|
||||
$("#results").show();
|
||||
unfold($("#results-head"), true);
|
||||
})
|
||||
// don't read window.location.hash, because
|
||||
// it has been %-decoded by firefox, which
|
||||
// cause problems when formulae include '&'.
|
||||
var fragment = location.href.replace(/^[^#]*#?(.*)$/, '$1');
|
||||
console.log("fragment: " + fragment);
|
||||
$("#results-body")
|
||||
.load("/cgi-bin/spotcgi.py",
|
||||
fragment,
|
||||
function(response, status, xhr) {
|
||||
$.doTimeout('res-update');
|
||||
if (status == "error") {
|
||||
var msg = "Sorry but there was an error: ";
|
||||
$("#results-body").html(msg + xhr.status + " "
|
||||
+ xhr.statusText);
|
||||
}
|
||||
$("#results-loading").hide();
|
||||
$("#results-body").show();
|
||||
$("#results").show();
|
||||
unfold($("#results-head"), true);
|
||||
fold($("#ltl-head"), function() {
|
||||
if ($.spotvars.scrolldown)
|
||||
$('html,body').animate({scrollTop: $("#results-head").offset().top}, 'slow');
|
||||
$.spotvars.scrolldown = false;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function autoUpdate() {
|
||||
if ($.spotvars.autoupdate)
|
||||
updateHash();
|
||||
return $.spotvars.autoupdate;
|
||||
}
|
||||
|
||||
$("#send").click(updateHash);
|
||||
$("input,select").change(autoUpdate);
|
||||
$('input[name="f"]').attr('spellcheck', false).focus()
|
||||
.keydown(function(e){
|
||||
if (e.keyCode == 13) {
|
||||
$.spotvars.scrolldown = true;
|
||||
updateHash();
|
||||
}
|
||||
});
|
||||
$('.collapsible .head').click(function(e) {
|
||||
var cl = e.target.classList;
|
||||
if (!cl.contains('head')
|
||||
&& !cl.contains('ui-icon-circle-arrow-n')
|
||||
&& !cl.contains('ui-icon-circle-arrow-s')) {
|
||||
return true;
|
||||
}
|
||||
if (e.ctrlKey) {
|
||||
if ($(this).attr('id') != 'ltl-head')
|
||||
$(this).parent().hide('fast').addClass("killed");
|
||||
} else {
|
||||
foldToggle($(this));
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$("#output-tabs").on("tabsactivate", function(event, ui) {
|
||||
var v = ui.newPanel[0].id[6]; // 'tabs-om' => 'm'.
|
||||
$('input[name="o"]').val(v)
|
||||
if (!autoUpdate())
|
||||
hideOrShowPanels(v, 'fast')
|
||||
return true;
|
||||
});
|
||||
$('#output-tabs').tabs('option', 'active', $('#tabs-oa').index());
|
||||
$('#translator-tabs').on("tabsactivate", function(event, ui) {
|
||||
$('input[name="t"]').val(ui.newPanel[0].id.substring(6));
|
||||
autoUpdate();
|
||||
return true;
|
||||
});
|
||||
|
||||
// Update the form from the hash value
|
||||
updateFormFromHash(0);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="spotlogo">
|
||||
<a href="http://spot.lrde.epita.fr/"><img border=0 src="logos/spot64s.png" alt="Spot Logo" class="rtip" id="spottip" title="This page uses the <b>Spot</b> library to process LTL formulas and automata. Please download <b>Spot</b> and install it on your computer if you want to do the same from the command line, or from another program."></a></div>
|
||||
<div id="mailicon">
|
||||
<a href="mailto:spot@lrde.epita.fr"><img border=0 src="logos/mail.png" alt="Spot Logo" class="rtip" title="A bug? A question? Please e-mail us at <b>spot@lrde.epita.fr</b>."></a></div>
|
||||
<div id="lrdelogo">
|
||||
<a href="https://www.lrde.epita.fr/"><img border=0 src="logos/lrde64.png" alt="LRDE Logo"></a></div>
|
||||
<div id="lip6logo">
|
||||
<a href="http://www.lip6.fr/"><img border=0 src="logos/lip6sys64.png" alt="LIP6 Logo"></a></div>
|
||||
<div class="ltl2tgba">
|
||||
<!-- The action below will not be used. -->
|
||||
<FORM id="trform" action="#"><P>
|
||||
<div class="ui-widget ui-widget-content ui-corner-all collapsible shadow">
|
||||
<h3 id="ltl-head" class="ui-widget-header ui-corner-all head">LTL (or PSL) Formula to translate<span class="ui-icon ui-icon-circle-arrow-n ltltip">Fold</span></h3>
|
||||
<div class="dontcollapse">
|
||||
<INPUT class="formula" type="text" name="f" value=""><span id="send" class="btip" title="Submit the formula and all options. You may simply hit <b>enter</b> after typing the formula. After the first submission the form will auto-update itself anytime you change an option.">Send</span></div>
|
||||
<div id="ltl-help">
|
||||
<p>Use alphanumeric identifiers or double-quoted strings for atomic
|
||||
propositions, and parentheses for grouping.<BR>Identifiers cannot
|
||||
start with the letter of a prefix operator (<span class="formula">F</span>,
|
||||
<span class="formula">G</span>, or <span class="formula">X</span>): for instance <span class="formula">GFa</span>
|
||||
means <span class="formula">G(F(a))</span>. Use <span class="formula">"GFa"</span> if you really want
|
||||
to refer to <span class="formula">GFa</span> as a proposition.<br>Conversely, infix
|
||||
letter operators are not assumed to be operators if they are part of
|
||||
an identifier: <span class="formula">aUb</span> is an atomic proposition, unlike
|
||||
<span class="formula">a U b</span> and <span class="formula">(a)U(b)</span>.</p>
|
||||
<table border="0" width="100%" rules="groups" frame="void" cellpadding="3" cellspacing="0" class="ltltable">
|
||||
<colgroup>
|
||||
<colgroup span=2>
|
||||
<colgroup span=2>
|
||||
<colgroup span=2>
|
||||
<colgroup span=2>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th colspan=2>Constants</th>
|
||||
<th colspan=2>Unary operators</th>
|
||||
<th colspan=4>Binary operators (infix)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="ltldocrow" rowspan=3>Boolean</td>
|
||||
<td class="ltldoc">false:</td><td><span class="formula">0</span> <span class="formula">false</span></td>
|
||||
<td class="ltldoc">not:</td><td><span class="formula">!</span> <span class="formula">~</span></td>
|
||||
<td class="ltldoc">and:</td><td><span class="formula">&</span> <span class="formula">&&</span>
|
||||
<span class="formula">/\</span></td>
|
||||
<td class="ltldoc">implies:</td><td><span class="formula">-></span>
|
||||
<span class="formula">--></span>
|
||||
<span class="formula">=></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="ltldoc">true:</td><td><span class="formula">1</span> <span class="formula">true</span></td>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">or:</td><td><span class="formula">|</span> <span class="formula">||</span>
|
||||
<span class="formula">+</span> <span class="formula">\/</span></td>
|
||||
<td class="ltldoc">equivalent:</td><td><span class="formula"><-></span>
|
||||
<span class="formula"><--></span>
|
||||
<span class="formula"><=></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td></td>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">xor:</td><td><span class="formula">xor</span> <span class="formula">^</span></td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="ltldocrow" rowspan=3><ABBR title="Linear-time Temporal Logic">LTL</ABBR></td>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">eventually:</td><td><span class="formula">F</span>
|
||||
<span class="formula"><></span></td>
|
||||
<td class="ltldoc">(strong) until:</td><td><span class="formula">U</span></td>
|
||||
<td class="ltldoc">weak until:</td><td><span class="formula">W</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">always:</td><td><span class="formula">G</span>
|
||||
<span class="formula">[]</span></td>
|
||||
<td class="ltldoc">(weak) release:</td><td><span class="formula">R</span>
|
||||
<span class="formula">V</span></td>
|
||||
<td class="ltldoc">strong release:</td><td><span class="formula">M</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">next:</td><td><span class="formula">X</span> <span class="formula">()</span></td>
|
||||
<td></td><td></td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="ltldocrow" rowspan=4><ABBR title="Sequential Extended Regular
|
||||
Expression">SERE</ABBR></td>
|
||||
<td class="ltldoc">ε:</td><td><span class="formula">[*0]</span></td>
|
||||
<td class="ltldoc">Kleene star:</td><td><span class="formula">[*] </span><span class="formula">[+]</span> <span class="formula">[*</span><i>i..j</i><span class="formula">]</span></td>
|
||||
<td class="ltldoc">concatenation:</td><td><span class="formula">;</span></td>
|
||||
<td class="ltldoc">fusion:</td><td><span class="formula">:</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">goto:</td><td><span class="formula">[-></span><i>i..j</i><span class="formula">]</span></td>
|
||||
<td class="ltldoc">intersection:</td><td><span class="formula">&&</span> <span class="formula">/\</span></td>
|
||||
<td class="ltldoc"><ABBR title="Non-Length-Matching">NLM</ABBR> and:</td><td><span class="formula">&</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">nonconsec. rep.:</td><td><span class="formula">[=</span><i>i..j</i><span class="formula">]</span></td>
|
||||
<td class="ltldoc">union:</td><td><span class="formula">|</span> <span class="formula">||</span> <span class="formula">+</span> <span class="formula">\/</span></td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc"><abbr title="The operator <span class='formula'>[:+]</span> corresponds to the <span class='formula'>⊕</span> operator introduced by Dax et al. (<i>Specification Languages for Stutter-Invariant Regular Properties</i>, ATVA'09). The other two are generalizations to different bounds.">iterated fusion</abbr>:</td><td><span class="formula">[:*] </span><span class="formula">[:+]</span> <span class="formula">[:*</span><i>i..j</i><span class="formula">]</span></td>
|
||||
<td></td><td></td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="ltldocrow" rowspan=2><ABBR title="Property Specification Language">PSL</ABBR></td>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">weak closure:</td><td><span class="formula">{</span><i>s</i><span class="formula">}</span></td>
|
||||
<td class="ltldoc">triggers:</td><td><span class="formula">{</span><i>s</i><span class="formula">}[]-></span><i>p</i><br><span class="formula">{</span><i>s</i><span class="formula">}|-></span><i>p</i><br><span class="formula">{</span><i>s</i><span class="formula">}(</span><i>p</i><span class="formula">)</span></td>
|
||||
<td class="ltldoc"><ABBR title="Non-Overlapping">Non-Ov.</ABBR> trigger:</td><td><span class="formula">{</span><i>s</i><span class="formula">}[]=></span><i>p</i><br><span class="formula">{</span><i>s</i><span class="formula">}|=></span><i>p</i></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td><td></td>
|
||||
<td class="ltldoc">strong closure:</td><td><span class="formula">{</span><i>s</i><span class="formula">}!</span></td>
|
||||
<td class="ltldoc">seq:</td><td><span class="formula">{</span><i>s</i><span class="formula">}<>-></span><i>p</i></td>
|
||||
<td class="ltldoc"><ABBR title="Non-Overlapping">Non-Ov.</ABBR> seq:</td><td><span class="formula">{</span><i>s</i><span class="formula">}<>=></span><i>p</i></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui-widget ui-widget-content ui-corner-all collapsible shadow">
|
||||
<h3 class="ui-widget-header ui-corner-all head">Formula Simplifications<span class="ui-icon ui-icon-circle-arrow-n ftip">Fold</span></h3>
|
||||
<div>
|
||||
<label class="rtip" title="Apply simple, unconditional rewriting rules to simplify formula. For instance <span class='formula'>F(a)|F(b)</span> is rewritten as <span class='formula'>F(a|b)</span>.">
|
||||
<INPUT id="brcheckbox" type="checkbox" name="r" value="br" checked>
|
||||
basic rewritings
|
||||
</label>
|
||||
<label class="rtip" title="Enable basic rewriting rules that may produce bigger formulas.">
|
||||
<INPUT id="lfcheckbox" type="checkbox" name="r" value="lf" checked>
|
||||
allow larger formulas
|
||||
</label><br>
|
||||
<label class="rtip" title="Use rewriting rules based on implications between subformulas, when these implications can be proved syntactically. For instance <span class='formula'>a U Fa</span> can be reduced to <span class='formula'>Fa</span> because the latter is obviously implied by <span class='formula'>a</span>.">
|
||||
<INPUT type="checkbox" name="r" value="si" checked>
|
||||
syntactic implication
|
||||
</label><br>
|
||||
<label class="rtip" title="Apply simplification rules when subformulas are <b>pure eventuality</b> or <b>purely universal</b>. For instance <span class='formula'>FGFa</span> can be rewritten to <span class='formula'>GFa</span> because the latter is a pure eventuality.">
|
||||
<INPUT type="checkbox" name="r" value="eu" checked>
|
||||
eventuality and universality
|
||||
</label><br>
|
||||
<label class="rtip" title="Try to reduce the formula by testing inclusion between automata built for various subformulas. This can be rather slow on large formulas.">
|
||||
<INPUT type="checkbox" name="r" value="lc">
|
||||
language containment
|
||||
</label>
|
||||
<label class="rtip floatright" title="Encode all formulas using UTF-8 characters.">
|
||||
<INPUT type="checkbox" name="g" value="8">
|
||||
UTF-8 output
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="output-tabs" class="tabs collapsible shadow">
|
||||
<ul class="head">
|
||||
<li>Desired Output:</li>
|
||||
<li><a href="#tabs-of" class="btip" title="Simplify the formula, but do not convert it as an automaton.">Formula</a></li>
|
||||
<li><a href="#tabs-om" class="btip" title="Create a monitor accepting all finite prefixes compatible with the formula.">Monitor</a></li>
|
||||
<li><a href="#tabs-oa" class="btip" title="Translate the LTL formula into Büchi automaton.">Büchi Automaton</a></li>
|
||||
<li><a href="#tabs-or" class="btip" title="Translate the LTL formula into Büchi automaton, and exhibit an accepting run.">Büchi Run</a></li>
|
||||
<li><a href="#tabs-ot" class="btip" title="Translate the LTL formula into a Testing Automaton, or some variant.">Testing Automaton</a></li>
|
||||
<li class="ui-icon ui-icon-circle-arrow-n ftip">Fold</li>
|
||||
</ul>
|
||||
<input type="hidden" name="o">
|
||||
<div>
|
||||
<div id="tabs-of">
|
||||
Output the (simplified) formula as:<br>
|
||||
<label class="rtip" title="Use letter operators (such as <span class='formula'>G</span> or <span class='formula'>F</span>) when possible, and unless UTF-8 output is activated.">
|
||||
<INPUT type="radio" name="ff" value="o" checked>
|
||||
text in Spot's syntax
|
||||
</label><br>
|
||||
<label class="rtip" title="This output can be given to Spin or any other tool using a similar syntax. Spot can also read it back. Operators such as such as <span class='formula'>M</span> and <span class='formula'>W</span>, which are not supported by Spin are rewritten away.">
|
||||
<INPUT type="radio" name="ff" value="i">
|
||||
text in Spin's syntax
|
||||
</label><br>
|
||||
<label class="rtip" title="This output can be given to LBT, LBTT, ltl2dstar, scheck, or any other tool using a similar syntax. Spot can also read it back. The original syntax only support atomic propositions named <span class='formula'>p0</span>, <span class='formula'>p1</span>, etc. As an extension, also supported by ltl2dstar, other atomic proposition are enclosed in double quotes. PSL formulas are not supported.">
|
||||
<INPUT type="radio" name="ff" value="l">
|
||||
text in LBT's syntax
|
||||
</label><br>
|
||||
<label class="rtip" title="A graphical representation of Spot's internal representation. Actually this is not a tree but an acyclic graph, because equal subformulas are shared.">
|
||||
<INPUT type="radio" name="ff" value="g">
|
||||
a syntactic tree
|
||||
</label><br>
|
||||
<label class="rtip" title="Various properties of the formula.">
|
||||
<INPUT type="radio" name="ff" value="p">
|
||||
property information
|
||||
</label><br>
|
||||
</div>
|
||||
<div id="tabs-om">
|
||||
Translate the (simplified) formula as:<br>
|
||||
<label class="rtip" title="A deterministic monitor is a DFA that accepts all the prefixes of the executions that satisfy the formula.">
|
||||
<INPUT type="radio" name="mf" value="d" checked>
|
||||
a deterministic monitor
|
||||
</label><br>
|
||||
<label class="rtip" title="A nondeterministic monitor is an NFA that accepts all the prefixes of the executions that satisfy the formula.">
|
||||
<INPUT type="radio" name="mf" value="n" checked>
|
||||
a nondeterministic monitor
|
||||
</label><br>
|
||||
</div>
|
||||
<div id="tabs-oa">
|
||||
Translate the (simplified) formula as:<br>
|
||||
<label class="rtip" title="A Transition-based Generalized Büchi Automaton (TGBA) is the main kind of automaton used by Spot. It is what all the translation algorithm below will output.">
|
||||
<INPUT type="radio" name="af" value="t" checked>
|
||||
a transition-based generalized Büchi automaton
|
||||
</label><br>
|
||||
<label class="rtip" title="Degeneralize the TGBA to obtain a Büchi automaton with a single set of accepting states.">
|
||||
<INPUT type="radio" name="af" value="s">
|
||||
a state-based degeneralized Büchi automaton
|
||||
</label><br>
|
||||
<label class="rtip" title="Degeneralize the TGBA to obtain a Büchi automaton with a single set of accepting states (as with previous option), then output the automaton as a neverclaim that can be fed to Spin.">
|
||||
<INPUT type="radio" name="af" value="i">
|
||||
a Spin neverclaim
|
||||
</label><br>
|
||||
</div>
|
||||
<div id="tabs-or">
|
||||
Translate the (simplified) formula as:<br>
|
||||
<label class="rtip" title="A Transition-based Generalized Büchi Automaton (TGBA) is the main kind of automaton used by Spot. It is what all the translation algorithm below will output.">
|
||||
<INPUT type="radio" name="ra" value="t" checked>
|
||||
a transition-based generalized Büchi automaton
|
||||
</label><br>
|
||||
<label class="rtip" title="Degeneralize the TGBA to obtain a Büchi automaton with a single set of accepting states.">
|
||||
<INPUT type="radio" name="ra" value="s">
|
||||
a state-based degeneralized Büchi automaton
|
||||
</label><br>
|
||||
then<br>
|
||||
<label class="rtip" title="Produce a textual description of run accepted by the automaton.">
|
||||
<INPUT type="radio" name="rf" value="p">
|
||||
print an accepting run
|
||||
</label><br>
|
||||
<label class="rtip" title="Use color to show an accepting run in the automaton.">
|
||||
<INPUT type="radio" name="rf" value="d" checked>
|
||||
draw an accepting run as a lasso-shaped automaton
|
||||
</label><br>
|
||||
</div>
|
||||
<div id="tabs-ot">
|
||||
Translate the (simplified) formula into a Büchi automaton, and then convert it into:<br>
|
||||
<label class="rtip" title="Instead of reading valuations of all atomic propositions testing automata only watch the changes to these valuation. A transitions labeled by <span class='formula'>a</span> may be crossed only if these atomic proposition change in the system. Additionally, testing automata have two acceptance conditions: states can be Büchi accepting or livelock accepting (or both, or none).">
|
||||
<INPUT id="tf-t" type="radio" name="tf" value="t">
|
||||
a Testing Automaton (TA)
|
||||
</label><br>
|
||||
<label class="rtip" title="GTA are testing automata extended with multiple Büchi acceptance conditions.">
|
||||
<INPUT id="tf-g" type="radio" name="tf" value="g">
|
||||
a Generalized Testing Automaton (GTA)
|
||||
</label><br>
|
||||
<label class="rtip" title="TGTA are similar to TGBA except instead of reading valuations of all atomic propositions testing automata only watch the changes to these valuation. They have multiple Büchi acceptance conditions on transitions, but no livelock acceptance.">
|
||||
<INPUT id="tf-a" type="radio" name="tf" value="a" checked>
|
||||
a Transition-based Generalized Testing Automaton (TGTA)
|
||||
</label><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="translator-tabs" class="tabs collapsible shadow">
|
||||
<ul class="head">
|
||||
<li>Translator Algorithm:</li>
|
||||
<li><a href="#tabs-tfm" class="btip" title="A tableau construction that uses BDDs to symbolically represent each state of the automaton. This produces better results than Tauriainen/TAA, and is the only algorithm that has been extended to support PSL operators.">Couvreur/FM</a></li>
|
||||
<li><a href="#tabs-tta" class="btip" title="An implementation of Heikki Tauriainen's Ph.D. thesis algorithm to translate LTL formulas via very weak alternating automata with transition-based generalized acceptance conditions.">Tauriainen/TAA</a></li>
|
||||
<li><a href="#tabs-tcs" class="btip" title="Compositional suspension.<br>A technique presented at Spin'13. Suspendable formulas are formulas such as <span class='formula'>GFa</span> or <span class='formula'>FGb</span> whose verification can always be postponed by a finite number of step. In this approach, we extract all suspendable subformulas, translate them separately from the main, skeleton automaton, only to merge them back in the accepting SCC. This translation uses Couvreur/FM for the intermediate parts.">Comp.Susp.</a></li>
|
||||
<li id="ltl3ba-tab"><a href="#tabs-tl3" class="btip" title="An improved version of LTL2BA, overhauled by Tomáš Babiak during his Ph.D., and described at TACAS'12.<br>LTL3BA is not part of Spot. Options in this tab correspond to options offered by LTL3BA, and have some overlap with the options offered by Spot that are still applied before (LTL simplifications) and after (automata simplifications) LTL3BA is called.">LTL3BA</a></li>
|
||||
<li class="ui-icon ui-icon-circle-arrow-n ftip">Fold</li>
|
||||
</ul>
|
||||
<input type="hidden" name="t" value="fm">
|
||||
<div>
|
||||
<div id="tabs-tfm">
|
||||
<label class="rtip" title="Try to optimize the automaton for determinism when building it. Warning: this option can be expensive if the formula uses a lot of different atomic propositions because the algorithm has to consider all possible valuations.">
|
||||
<INPUT type="checkbox" name="fm" value="od" checked>
|
||||
optimize determinism
|
||||
</label><br>
|
||||
<label class="rtip" title="All states that share the same set of outgoing transitions will be merged. This optimization comes for free in the implementation, so there is no point in disabling it unless you want to study its effect.">
|
||||
<INPUT type="checkbox" name="fm" value="sm" checked>
|
||||
merge states with same symbolic successor representation
|
||||
</label><br>
|
||||
<label class="rtip" title="Attempt to delay non-deterministic branching. It sometimes helps to reduce the indeterminism (look at the effect on <span class='formula'>X(a) R b</span>), but it may also produce bigger automata.">
|
||||
<INPUT type="checkbox" name="fm" value="bp">
|
||||
branching postponement
|
||||
</label><br>
|
||||
<label class="rtip" title="Try to syntactically detect if a state can be part of a fair loop, and if so, do not use acceptance conditions for that state. This optimization seems to have more negative effects than positive effects...">
|
||||
<INPUT type="checkbox" name="fm" value="fl">
|
||||
fair-loop approximations
|
||||
</label><br>
|
||||
</div>
|
||||
<div id="tabs-tta">
|
||||
<label class="rtip" title="Enable a refined set of translation rules, based on language inclusion between subformulas. Because language inclusion between formula is tested using automata operations on translations for subformulas, this option can be slow.">
|
||||
<INPUT type="checkbox" name="ta" value="lc" checked>
|
||||
language containment
|
||||
</label><br>
|
||||
</div>
|
||||
<div id="tabs-tl3">
|
||||
Use <a href="http://sourceforge.net/projects/ltl3ba/" id="ltl3ba-link">LTL3BA</a> to build:
|
||||
<label class="rtip" title="Stop LTL3BA once it has built a Transition-based Generalized Büchi Automaton. Spot will take it from here and optionally apply more optimizations.">
|
||||
<INPUT id="ltl3ba-T" type="radio" name="lo" value="T" checked>
|
||||
a TGBA
|
||||
</label> or <label class="rtip" title="Run LTL3BA until it produces its final Büchi Automaton. Spot will consider this BA has a TGBA if further optimizations have been requested below.">
|
||||
<INPUT id="ltl3ba-U" type="radio" name="lo" value="U">
|
||||
a BA
|
||||
</label><br>
|
||||
<div class="colleft">
|
||||
<label class="rtip" title="LTL simplifications performed in LTL3BA are independent of those Spot may have performed upstream.">
|
||||
<INPUT type="checkbox" name="l3" value="l" checked>
|
||||
LTL simplifications
|
||||
</label><br>
|
||||
<label class="rtip" title="See next tooltip for an explanation of suspension. LTL3BA supports suspension also in the construction of an intermediate alternating automaton, where it is only used for one step.">
|
||||
<INPUT type="checkbox" name="l3" value="A" checked>
|
||||
suspension in alternating automaton
|
||||
</label><br>
|
||||
<label class="rtip" title="Suspension is a technique to postpone the verification of some subformulae. An easy way to picture it is to look at the formula <span class='formula'>F(a)&GF(b)</span>: the <span class='formula'>GF(b)</span> part does not need to be checked before some <span class='formula'>a</span> has been seen. On this example, suspension amounts to translating <span class='formula'>F(a&GF(b))</span> but the technique is more general than such LTL rewritings.">
|
||||
<INPUT type="checkbox" name="l3" value="P" checked>
|
||||
suspension in TGBA
|
||||
</label><br>
|
||||
<label class="rtip" title="During the construction, each newly created transition or state is immediately compared to existing transitions or states and merged if possible.">
|
||||
<INPUT type="checkbox" name="l3" value="o" checked>
|
||||
on-the-fly simplifications
|
||||
</label><br>
|
||||
</div>
|
||||
<label class="rtip" title="Perform the same simplifications as the on-the-fly simplification but on the final automaton, plus some SCC simplifications.">
|
||||
<INPUT type="checkbox" name="l3" value="p" checked>
|
||||
a-posteriori simplifications
|
||||
</label><br>
|
||||
<label class="rtip" title="Compute Strongly Connected Components to simplify the automaton.">
|
||||
<INPUT type="checkbox" name="l3" value="C" checked>
|
||||
SCC simplifications
|
||||
</label><br>
|
||||
<label class="rtip" title="Try to improve the automaton's determinism when building it. This may produce larger automata.">
|
||||
<INPUT type="checkbox" name="l3" value="M" checked>
|
||||
more deterministic output
|
||||
</label><br>
|
||||
<label class="rtip" title="Compute a direct (a.k.a. strong fair) simulation relation to reduce the size of the Büchi automaton.">
|
||||
<INPUT id="ltl3ba-S" type="checkbox" name="l3" value="S">
|
||||
direct simulation on BA
|
||||
</label><br>
|
||||
</div>
|
||||
<div id="tabs-tcs">
|
||||
<label class="rtip" title="Apply WDBA minimization on skeleton automaton when possible.">
|
||||
<INPUT type="checkbox" name="cs" value="w">
|
||||
WDBA minimization of intermediate automaton
|
||||
</label><br>
|
||||
<label class="rtip" title="Apply direct simulation on skeleton automaton. This is only done when the WDBA minimization could not work.">
|
||||
<INPUT type="checkbox" name="cs" value="s" checked>
|
||||
direct simulation on intermediate automaton
|
||||
</label><br>
|
||||
<label class="rtip" title="Start suspension on transitions that enter accepting SCCs instead of waiting to be in the SCC. (Not discussed in the Spin'13 paper.)">
|
||||
<INPUT type="checkbox" name="cs" value="e">
|
||||
early start of suspended automata
|
||||
</label><br>
|
||||
<label class="rtip" title="Output the skeleton automaton, with suspension labels showing where suspended formulae should be attached.
|
||||
Unlike in our Spin'13 paper, we consider negated suspension labels and missing suspension labels
|
||||
equivalently: the important data is the place of the positive suspension labels.">
|
||||
<INPUT type="checkbox" name="cs" value="c">
|
||||
do not compose suspended formulas (for debugging)
|
||||
</label><br>
|
||||
<!--
|
||||
<label class="rtip" title="Consider obligation subformulas as atomic propositions initially, and compose their WDBA-minimized translation.">
|
||||
<INPUT type="checkbox" name="cs" value="o">
|
||||
compose WDBA-minimized obligation sub-formulas
|
||||
</label><br> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="autsimp-tabs" class="ui-widget ui-widget-content ui-corner-all collapsible shadow">
|
||||
<h3 class="ui-widget-header ui-corner-all head">Automaton Simplifications<span class="ui-icon ui-icon-circle-arrow-n ftip">Fold</span></h3>
|
||||
<div>
|
||||
<label class="rtip" title="Compute the SCCs of the automaton. Eliminate all the useless SCCs (i.e. those that cannot be part of an accepting run). Also attempt to remove redundant acceptance conditions.">
|
||||
<INPUT type="checkbox" name="as" value="ps" checked>
|
||||
prune unaccepting SCCs
|
||||
</label><br>
|
||||
<label class="rtip" title="<b>Obligation properties</b> are properties that can be represented by a Weak Deterministic Büchi Automaton (WDBA). Any WDBA has a minimal form that can be constructed in a way that is similar to DFA minimization.<br>Using this option, any automaton (WDBA or not) will be tentatively determinized and minimized; the result will be used only if it is equivalent to the original automaton (i.e., if the property was indeed an obligation property).">
|
||||
<INPUT type="checkbox" name="as" value="wd">
|
||||
determinize and minimize obligation properties
|
||||
</label><br>
|
||||
<label class="rtip" title="Attempt to reduce the automaton by using <b>direct simulation</b> on the TGBA. Basically a state <b>A</b> can be merged into a state <b>B</b> if the <b>suffixes</b> reachable from <b>A</b> are included into those reachable from <b>B</b>. This algorithm may also improve determinism as a side effect.">
|
||||
<INPUT id="as-ds" type="checkbox" name="as" value="ds">
|
||||
direct simulation
|
||||
</label>
|
||||
<label class="rtip" title="Attempt to reduce the automaton by using <b>reverse simulation</b> on the TGBA. Basically a state <b>A</b> can be merged into a state <b>B</b> if the <b>prefixes</b> reachable from <b>A</b> are included into those reachable from <b>B</b> This can also improve codeterminism as a side effect.">
|
||||
<INPUT id="as-rs" type="checkbox" name="as" value="rs">
|
||||
reverse simulation
|
||||
</label>
|
||||
<label class="rtip" title="Apply <b>direct</b> and <b>reverse simulation</b> alternatively until the automaton is not reduced further.">
|
||||
<INPUT id="as-is" type="checkbox" name="as" value="is">
|
||||
iterated simulations
|
||||
</label><br>
|
||||
</div>
|
||||
</div>
|
||||
<div id="run-tabs" class="ui-widget ui-widget-content ui-corner-all collapsible shadow">
|
||||
<h3 class="ui-widget-header ui-corner-all
|
||||
head">Emptiness-check Algorithm<span class="ui-icon ui-icon-circle-arrow-n ftip">Fold</span></h3>
|
||||
<div>
|
||||
Search accepting run using algorithm:
|
||||
<select name="ec">
|
||||
<option value="Cou99" selected>Cou99</option>
|
||||
<option value="CVWY90">CVWY90</option>
|
||||
<option value="GV04">GV04</option>
|
||||
<option value="SE05">SE05</option>
|
||||
<option value="Tau03">Tau03</option>
|
||||
<option value="Tau03_opt">Tau03_opt</option>
|
||||
</select> with these
|
||||
<a href="http://spot.lip6.fr/wiki/EmptinessCheckOptions">options</a>:
|
||||
<INPUT type="text" maxlength="40" name="eo" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div id="tester-tabs" class="ui-widget ui-widget-content ui-corner-all collapsible shadow">
|
||||
<h3 class="ui-widget-header ui-corner-all head">Testing Automaton Options<span class="ui-icon ui-icon-circle-arrow-n ftip">Fold</span></h3>
|
||||
<div>
|
||||
<label class="rtip" title="Divert all livelock accepting paths to a single livelock acceptance state.">
|
||||
<INPUT id="to-l" type="checkbox" name="to" value="l">
|
||||
use a catch-all livelock state
|
||||
</label><br>
|
||||
<label class="rtip" title="Ensure that all livelock accepting states are also Büchi-accepting, so that the testing automaton can be tested for emptiness in a single pass.">
|
||||
<INPUT id="to-s" type="checkbox" name="to" value="s" checked>
|
||||
produce a single-pass testing automaton
|
||||
</label><br>
|
||||
<label class="rtip" title="Merge bisimilar states in the final testing automaton.">
|
||||
<INPUT type="checkbox" name="to" value="m" checked>
|
||||
merge bisimilar states
|
||||
</label><br>
|
||||
</div>
|
||||
</div>
|
||||
</FORM>
|
||||
<div id="results" class="ui-widget ui-widget-content ui-corner-all collapsible shadow">
|
||||
<h3 id="results-head" class="ui-widget-header ui-corner-all head">Results<span class="ui-icon ui-icon-circle-arrow-n restip">Fold</span></h3>
|
||||
<div id="results-loading" class="dontcollapse"><img src="css/loading.gif" class="loading" border=0 alt="loading..."></div>
|
||||
<div id="results-body">
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
365
python/buddy.i
Normal file
365
python/buddy.i
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
// -*- 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/>.
|
||||
|
||||
// This is derived from Buddy's headers, distributed with the
|
||||
// following license:
|
||||
|
||||
/*========================================================================
|
||||
Copyright (C) 1996-2003 by Jorn Lind-Nielsen
|
||||
All rights reserved
|
||||
|
||||
Permission is hereby granted, without written agreement and without
|
||||
license or royalty fees, to use, reproduce, prepare derivative
|
||||
works, distribute, and display this software and its documentation
|
||||
for any purpose, provided that (1) the above copyright notice and
|
||||
the following two paragraphs appear in all copies of the source code
|
||||
and (2) redistributions, including without limitation binaries,
|
||||
reproduce these notices in the supporting documentation. Substantial
|
||||
modifications to this software may be copyrighted by their authors
|
||||
and need not follow the licensing terms described here, provided
|
||||
that the new terms are clearly indicated in all files where they apply.
|
||||
|
||||
IN NO EVENT SHALL JORN LIND-NIELSEN, OR DISTRIBUTORS OF THIS
|
||||
SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
|
||||
INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
|
||||
SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE
|
||||
ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
JORN LIND-NIELSEN SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
|
||||
OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
MODIFICATIONS.
|
||||
========================================================================*/
|
||||
|
||||
%{
|
||||
// Workaround for SWIG 2.0.2 using ptrdiff_t but not including cstddef.
|
||||
// It matters with g++ 4.6.
|
||||
#include <cstddef>
|
||||
%}
|
||||
|
||||
%module buddy
|
||||
|
||||
%include "std_string.i"
|
||||
|
||||
%{
|
||||
#include <sstream>
|
||||
#include "bddx.h"
|
||||
#include "fddx.h"
|
||||
#include "bvecx.h"
|
||||
%}
|
||||
|
||||
%typemap(in) (int* input_buf, int input_buf_size) {
|
||||
if (!PySequence_Check($input))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "Expected a sequence");
|
||||
return 0;
|
||||
}
|
||||
$2 = PySequence_Length($input);
|
||||
$1 = (int*) malloc($2 * sizeof(int));
|
||||
for (int i = 0; i < $2; ++i)
|
||||
{
|
||||
PyObject* o = PySequence_GetItem($input, i);
|
||||
if (PyInt_Check(o))
|
||||
{
|
||||
$1[i] = PyInt_AsLong(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"Sequence elements must be integers");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
%typemap(freearg) (int* input_buf, int input_buf_size) {
|
||||
if ($1)
|
||||
free($1);
|
||||
}
|
||||
|
||||
|
||||
%inline {
|
||||
struct const_int_ptr
|
||||
{
|
||||
const_int_ptr(const int* ptr)
|
||||
: ptr(ptr)
|
||||
{
|
||||
}
|
||||
const int* ptr;
|
||||
};
|
||||
}
|
||||
|
||||
%extend const_int_ptr {
|
||||
int
|
||||
__getitem__(int i)
|
||||
{
|
||||
return self->ptr[i];
|
||||
}
|
||||
}
|
||||
|
||||
struct bdd
|
||||
{
|
||||
int id(void) const;
|
||||
};
|
||||
|
||||
int bdd_init(int, int);
|
||||
void bdd_done(void);
|
||||
int bdd_setvarnum(int);
|
||||
int bdd_extvarnum(int);
|
||||
int bdd_isrunning(void);
|
||||
int bdd_setmaxnodenum(int);
|
||||
int bdd_setmaxincrease(int);
|
||||
int bdd_setminfreenodes(int);
|
||||
int bdd_getnodenum(void);
|
||||
int bdd_getallocnum(void);
|
||||
char* bdd_versionstr(void);
|
||||
int bdd_versionnum(void);
|
||||
void bdd_fprintstat(FILE *);
|
||||
void bdd_printstat(void);
|
||||
const char *bdd_errstring(int);
|
||||
void bdd_clear_error(void);
|
||||
|
||||
bdd bdd_ithvar(int v);
|
||||
bdd bdd_nithvar(int v);
|
||||
int bdd_var(const bdd &r);
|
||||
bdd bdd_low(const bdd &r);
|
||||
bdd bdd_high(const bdd &r);
|
||||
int bdd_scanset(const bdd &r, int *&v, int &n);
|
||||
bdd bdd_makeset(int *v, int n);
|
||||
int bdd_setbddpair(bddPair *p, int ov, const bdd &nv);
|
||||
bdd bdd_replace(const bdd &r, bddPair *p);
|
||||
bdd bdd_compose(const bdd &f, const bdd &g, int v);
|
||||
bdd bdd_veccompose(const bdd &f, bddPair *p);
|
||||
bdd bdd_restrict(const bdd &r, const bdd &var);
|
||||
bdd bdd_constrain(const bdd &f, const bdd &c);
|
||||
bdd bdd_simplify(const bdd &d, const bdd &b);
|
||||
bdd bdd_ibuildcube(int v, int w, int *a);
|
||||
bdd bdd_not(const bdd &r);
|
||||
bdd bdd_apply(const bdd &l, const bdd &r, int op);
|
||||
bdd bdd_and(const bdd &l, const bdd &r);
|
||||
bdd bdd_or(const bdd &l, const bdd &r);
|
||||
bdd bdd_xor(const bdd &l, const bdd &r);
|
||||
bdd bdd_imp(const bdd &l, const bdd &r);
|
||||
bdd bdd_biimp(const bdd &l, const bdd &r);
|
||||
bdd bdd_setxor(const bdd &l, const bdd &r);
|
||||
int bdd_implies(const bdd &l, const bdd &r);
|
||||
bdd bdd_ite(const bdd &f, const bdd &g, const bdd &h);
|
||||
bdd bdd_exist(const bdd &r, const bdd &var);
|
||||
bdd bdd_existcomp(const bdd &r, const bdd &var);
|
||||
bdd bdd_forall(const bdd &r, const bdd &var);
|
||||
bdd bdd_forallcomp(const bdd &r, const bdd &var);
|
||||
bdd bdd_unique(const bdd &r, const bdd &var);
|
||||
bdd bdd_uniquecomp(const bdd &r, const bdd &var);
|
||||
bdd bdd_appex(const bdd &l, const bdd &r, int op, const bdd &var);
|
||||
bdd bdd_appexcomp(const bdd &l, const bdd &r, int op, const bdd &var);
|
||||
bdd bdd_appall(const bdd &l, const bdd &r, int op, const bdd &var);
|
||||
bdd bdd_appallcomp(const bdd &l, const bdd &r, int op, const bdd &var);
|
||||
bdd bdd_appuni(const bdd &l, const bdd &r, int op, const bdd &var);
|
||||
bdd bdd_appunicomp(const bdd &l, const bdd &r, int op, const bdd &var);
|
||||
bdd bdd_support(const bdd &r);
|
||||
bdd bdd_satone(const bdd &r);
|
||||
bdd bdd_satoneset(const bdd &r, const bdd &var, const bdd &pol);
|
||||
bdd bdd_fullsatone(const bdd &r);
|
||||
void bdd_allsat(const bdd &r, bddallsathandler handler);
|
||||
double bdd_satcount(const bdd &r);
|
||||
double bdd_satcountset(const bdd &r, const bdd &varset);
|
||||
double bdd_satcountln(const bdd &r);
|
||||
double bdd_satcountlnset(const bdd &r, const bdd &varset);
|
||||
int bdd_nodecount(const bdd &r);
|
||||
int* bdd_varprofile(const bdd &r);
|
||||
double bdd_pathcount(const bdd &r);
|
||||
void bdd_fprinttable(FILE *file, const bdd &r);
|
||||
void bdd_printtable(const bdd &r);
|
||||
void bdd_fprintset(FILE *file, const bdd &r);
|
||||
void bdd_printset(const bdd &r);
|
||||
void bdd_printdot(const bdd &r);
|
||||
void bdd_fprintdot(FILE* ofile, const bdd &r);
|
||||
int bdd_fnprintdot(char* fname, const bdd &r);
|
||||
int bdd_fnsave(char *fname, const bdd &r);
|
||||
int bdd_save(FILE *ofile, const bdd &r);
|
||||
int bdd_fnload(char *fname, bdd &r);
|
||||
int bdd_load(FILE *ifile, bdd &r);
|
||||
int bdd_addvarblock(const bdd &v, int f);
|
||||
|
||||
extern const bdd bddfalse;
|
||||
extern const bdd bddtrue;
|
||||
|
||||
#define bddop_and 0
|
||||
#define bddop_xor 1
|
||||
#define bddop_or 2
|
||||
#define bddop_nand 3
|
||||
#define bddop_nor 4
|
||||
#define bddop_imp 5
|
||||
#define bddop_biimp 6
|
||||
#define bddop_diff 7
|
||||
#define bddop_less 8
|
||||
#define bddop_invimp 9
|
||||
|
||||
#define BDD_REORDER_NONE 0
|
||||
#define BDD_REORDER_WIN2 1
|
||||
#define BDD_REORDER_WIN2ITE 2
|
||||
#define BDD_REORDER_SIFT 3
|
||||
#define BDD_REORDER_SIFTITE 4
|
||||
#define BDD_REORDER_WIN3 5
|
||||
#define BDD_REORDER_WIN3ITE 6
|
||||
#define BDD_REORDER_RANDOM 7
|
||||
|
||||
%extend bdd {
|
||||
// For Python 2.0
|
||||
int __cmp__(bdd* b) { return b->id() - self->id(); }
|
||||
|
||||
// For Python 2.1+ and Python 3
|
||||
bool __le__(bdd* b) { return self->id() <= b->id(); }
|
||||
bool __lt__(bdd* b) { return self->id() < b->id(); }
|
||||
bool __eq__(bdd* b) { return self->id() == b->id(); }
|
||||
bool __ne__(bdd* b) { return self->id() != b->id(); }
|
||||
bool __ge__(bdd* b) { return self->id() >= b->id(); }
|
||||
bool __gt__(bdd* b) { return self->id() > b->id(); }
|
||||
|
||||
|
||||
std::string
|
||||
__str__(void)
|
||||
{
|
||||
std::ostringstream res;
|
||||
res << "bdd(id=" << self->id() << ")";
|
||||
return res.str();
|
||||
}
|
||||
|
||||
bdd __and__(bdd& other) { return *self & other; }
|
||||
bdd __xor__(bdd& other) { return *self ^ other; }
|
||||
bdd __or__(bdd& other) { return *self | other; }
|
||||
bdd __rshift__(bdd& other) { return *self >> other; }
|
||||
bdd __lshift__(bdd& other) { return *self << other; }
|
||||
bdd __sub__(bdd& other) { return *self - other; }
|
||||
bdd __neg__(void) { return !*self; }
|
||||
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
int fdd_extdomain(int* input_buf, int input_buf_size);
|
||||
int fdd_overlapdomain(int, int);
|
||||
void fdd_clearall(void);
|
||||
int fdd_domainnum(void);
|
||||
int fdd_domainsize(int);
|
||||
int fdd_varnum(int);
|
||||
const_int_ptr fdd_vars(int);
|
||||
bdd fdd_ithvar(int, int);
|
||||
int fdd_scanvar(bdd, int);
|
||||
int* fdd_scanallvar(bdd);
|
||||
bdd fdd_ithset(int);
|
||||
bdd fdd_domain(int);
|
||||
bdd fdd_equals(int, int);
|
||||
void fdd_printset(bdd);
|
||||
void fdd_fprintset(FILE*, bdd);
|
||||
int fdd_scanset(const bdd &, int *&, int &);
|
||||
bdd fdd_makeset(int*, int);
|
||||
int fdd_intaddvarblock(int, int, int);
|
||||
int fdd_setpair(bddPair*, int, int);
|
||||
int fdd_setpairs(bddPair*, int*, int*, int);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
bvec bvec_copy(bvec v);
|
||||
bvec bvec_true(int bitnum);
|
||||
bvec bvec_false(int bitnum);
|
||||
bvec bvec_con(int bitnum, int val);
|
||||
bvec bvec_var(int bitnum, int offset, int step);
|
||||
bvec bvec_varfdd(int var);
|
||||
bvec bvec_varvec(int bitnum, int *var);
|
||||
bvec bvec_coerce(int bitnum, bvec v);
|
||||
int bvec_isconst(bvec e);
|
||||
int bvec_val(bvec e);
|
||||
bvec bvec_map1(const bvec&, bdd (*fun)(const bdd &));
|
||||
bvec bvec_map2(const bvec&, const bvec&, bdd (*fun)(const bdd &, const bdd &));
|
||||
bvec bvec_map3(const bvec&, const bvec&, const bvec &,
|
||||
bdd (*fun)(const bdd &, const bdd &, const bdd &));
|
||||
|
||||
bvec bvec_add(bvec left, bvec right);
|
||||
bvec bvec_sub(bvec left, bvec right);
|
||||
bvec bvec_mulfixed(bvec e, int c);
|
||||
bvec bvec_mul(bvec left, bvec right);
|
||||
int bvec_divfixed(const bvec &, int c, bvec &, bvec &);
|
||||
int bvec_div(const bvec &, const bvec &, bvec &, bvec &);
|
||||
bvec bvec_ite(bdd a, bvec b, bvec c);
|
||||
bvec bvec_shlfixed(bvec e, int pos, bdd c);
|
||||
bvec bvec_shl(bvec l, bvec r, bdd c);
|
||||
bvec bvec_shrfixed(bvec e, int pos, bdd c);
|
||||
bvec bvec_shr(bvec l, bvec r, bdd c);
|
||||
bdd bvec_lth(bvec left, bvec right);
|
||||
bdd bvec_lte(bvec left, bvec right);
|
||||
bdd bvec_gth(bvec left, bvec right);
|
||||
bdd bvec_gte(bvec left, bvec right);
|
||||
bdd bvec_equ(bvec left, bvec right);
|
||||
bdd bvec_neq(bvec left, bvec right);
|
||||
|
||||
class bvec
|
||||
{
|
||||
public:
|
||||
bvec(void);
|
||||
bvec(int bitnum);
|
||||
bvec(int bitnum, int val);
|
||||
bvec(const bvec &v);
|
||||
~bvec(void);
|
||||
|
||||
void set(int i, const bdd &b);
|
||||
int bitnum(void) const;
|
||||
int empty(void) const;
|
||||
bvec operator=(const bvec &src);
|
||||
|
||||
bvec operator&(const bvec &a) const;
|
||||
bvec operator^(const bvec &a) const;
|
||||
bvec operator|(const bvec &a) const;
|
||||
bvec operator!(void) const;
|
||||
bvec operator<<(int a) const;
|
||||
bvec operator<<(const bvec &a) const;
|
||||
bvec operator>>(int a) const;
|
||||
bvec operator>>(const bvec &a) const;
|
||||
bvec operator+(const bvec &a) const;
|
||||
bvec operator-(const bvec &a) const;
|
||||
bvec operator*(int a) const;
|
||||
bvec operator*(const bvec a) const;
|
||||
bdd operator<(const bvec &a) const;
|
||||
bdd operator<=(const bvec &a) const;
|
||||
bdd operator>(const bvec &a) const;
|
||||
bdd operator>=(const bvec &a) const;
|
||||
bdd operator==(const bvec &a) const;
|
||||
bdd operator!=(const bvec &a) const;
|
||||
};
|
||||
|
||||
|
||||
%extend bvec {
|
||||
std::string
|
||||
__str__(void)
|
||||
{
|
||||
std::ostringstream res;
|
||||
res << "bvec(bitnum=" << self->bitnum() << ")";
|
||||
return res.str();
|
||||
}
|
||||
|
||||
bdd
|
||||
__getitem__(int i)
|
||||
{
|
||||
return (*self)[i];
|
||||
}
|
||||
}
|
||||
874
python/spot.py
Normal file
874
python/spot.py
Normal file
|
|
@ -0,0 +1,874 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 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 sys
|
||||
|
||||
|
||||
if sys.hexversion < 0x03030000:
|
||||
sys.exit("This module requires Python 3.3 or newer")
|
||||
|
||||
|
||||
from spot_impl import *
|
||||
import subprocess
|
||||
import os
|
||||
import signal
|
||||
from functools import lru_cache
|
||||
|
||||
|
||||
def _extend(*classes):
|
||||
"""
|
||||
Decorator that extends all the given classes with the contents
|
||||
of the class currently being defined.
|
||||
"""
|
||||
def wrap(this):
|
||||
for cls in classes:
|
||||
for (name, val) in this.__dict__.items():
|
||||
if name not in ('__dict__', '__weakref__') \
|
||||
and not (name == '__doc__' and val is None):
|
||||
setattr(cls, name, val)
|
||||
return classes[0]
|
||||
return wrap
|
||||
|
||||
_show_default = None
|
||||
|
||||
def setup(**kwargs):
|
||||
"""Configure Spot for fancy display.
|
||||
|
||||
This is manly useful in Jupyter/IPython.
|
||||
|
||||
Note that this function needs to be called before any automaton is
|
||||
displayed. Afterwards it will have no effect (you should restart
|
||||
Python, or the Jupyter/IPython Kernel).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
bullets : bool
|
||||
whether to display acceptance conditions as UTF8 bullets
|
||||
(default: True)
|
||||
fillcolor : str
|
||||
the color to use for states (default: '#ffffaa')
|
||||
size : str
|
||||
the width and height of the GraphViz output in inches
|
||||
(default: '10.2,5')
|
||||
font : str
|
||||
the font to use in the GraphViz output (default: 'Lato')
|
||||
show_default : str
|
||||
default options for show()
|
||||
"""
|
||||
import os
|
||||
|
||||
s = ('size="{}" node[style=filled,fillcolor="{}"] '
|
||||
'edge[arrowhead=vee, arrowsize=.7]')
|
||||
os.environ['SPOT_DOTEXTRA'] = s.format(kwargs.get('size', '10.2,5'),
|
||||
kwargs.get('fillcolor', '#ffffaa'))
|
||||
|
||||
bullets = 'B' if kwargs.get('bullets', True) else ''
|
||||
d = 'rf({})'.format(kwargs.get('font', 'Lato')) + bullets
|
||||
global _show_default
|
||||
_show_default = kwargs.get('show_default', None)
|
||||
os.environ['SPOT_DOTDEFAULT'] = d
|
||||
|
||||
|
||||
# In version 3.0.2, Swig puts strongly typed enum in the main
|
||||
# namespace without prefixing them. Latter versions fix this. So we
|
||||
# can remove for following hack once 3.0.2 is no longer used in our
|
||||
# build farm.
|
||||
if 'op_ff' not in globals():
|
||||
for i in ('ff', 'tt', 'eword', 'ap', 'Not', 'X', 'F', 'G',
|
||||
'Closure', 'NegClosure', 'NegClosureMarked',
|
||||
'Xor', 'Implies', 'Equiv', 'U', 'R', 'W', 'M',
|
||||
'EConcat', 'EConcatMarked', 'UConcat', 'Or',
|
||||
'OrRat', 'And', 'AndRat', 'AndNLM', 'Concat',
|
||||
'Fusion', 'Star', 'FStar'):
|
||||
globals()['op_' + i] = globals()[i]
|
||||
del globals()[i]
|
||||
|
||||
|
||||
# Global BDD dict so that we do not have to create one in user code.
|
||||
_bdd_dict = make_bdd_dict()
|
||||
|
||||
|
||||
# Add a small LRU cache so that when we display automata into a
|
||||
# interactive widget, we avoid some repeated calls to dot for
|
||||
# identical inputs.
|
||||
@lru_cache(maxsize=64)
|
||||
def _str_to_svg(str):
|
||||
dotty = subprocess.Popen(['dot', '-Tsvg'],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
dotty.stdin.write(str)
|
||||
res = dotty.communicate()
|
||||
return res[0].decode('utf-8')
|
||||
|
||||
|
||||
def _ostream_to_svg(ostr):
|
||||
return _str_to_svg(ostr.str().encode('utf-8'))
|
||||
|
||||
|
||||
@_extend(twa, ta)
|
||||
class twa:
|
||||
def _repr_svg_(self, opt=None):
|
||||
"""Output the automaton as SVG"""
|
||||
ostr = ostringstream()
|
||||
if opt is None:
|
||||
global _show_default
|
||||
opt = _show_default
|
||||
print_dot(ostr, self, opt)
|
||||
return _ostream_to_svg(ostr)
|
||||
|
||||
def show(self, opt=None):
|
||||
"""Display the automaton as SVG, in the IPython/Jupyter notebook"""
|
||||
if opt is None:
|
||||
global _show_default
|
||||
opt = _show_default
|
||||
# Load the SVG function only if we need it. This way the
|
||||
# bindings can still be used outside of IPython if IPython is
|
||||
# not installed.
|
||||
from IPython.display import SVG
|
||||
return SVG(self._repr_svg_(opt))
|
||||
|
||||
|
||||
@_extend(twa)
|
||||
class twa:
|
||||
def to_str(a, format='hoa', opt=None):
|
||||
format = format.lower()
|
||||
if format == 'hoa':
|
||||
ostr = ostringstream()
|
||||
print_hoa(ostr, a, opt)
|
||||
return ostr.str()
|
||||
if format == 'dot':
|
||||
ostr = ostringstream()
|
||||
print_dot(ostr, a, opt)
|
||||
return ostr.str()
|
||||
if format == 'spin':
|
||||
ostr = ostringstream()
|
||||
print_never_claim(ostr, a, opt)
|
||||
return ostr.str()
|
||||
if format == 'lbtt':
|
||||
ostr = ostringstream()
|
||||
print_lbtt(ostr, a, opt)
|
||||
return ostr.str()
|
||||
raise ValueError("unknown string format: " + format)
|
||||
|
||||
def save(a, filename, format='hoa', opt=None, append=False):
|
||||
with open(filename, 'a' if append else 'w') as f:
|
||||
s = a.to_str(format, opt)
|
||||
f.write(s)
|
||||
if s[-1] != '\n':
|
||||
f.write('\n')
|
||||
return a
|
||||
|
||||
|
||||
@_extend(formula)
|
||||
class formula:
|
||||
def __init__(self, str):
|
||||
"""Parse the given string to create a formula."""
|
||||
self.this = parse_formula(str)
|
||||
|
||||
def show_ast(self):
|
||||
"""Display the syntax tree of the formula."""
|
||||
# Load the SVG function only if we need it. This way the bindings
|
||||
# can still be used outside of IPython if IPython is not
|
||||
# installed.
|
||||
from IPython.display import SVG
|
||||
ostr = ostringstream()
|
||||
print_dot_psl(ostr, self)
|
||||
return SVG(_ostream_to_svg(ostr))
|
||||
|
||||
def to_str(self, format='spot', parenth=False):
|
||||
if format == 'spot' or format == 'f':
|
||||
return str_psl(self, parenth)
|
||||
elif format == 'spin' or format == 's':
|
||||
return str_spin_ltl(self, parenth)
|
||||
elif format == 'utf8' or format == '8':
|
||||
return str_utf8_psl(self, parenth)
|
||||
elif format == 'lbt' or format == 'l':
|
||||
return str_lbt_ltl(self)
|
||||
elif format == 'wring' or format == 'w':
|
||||
return str_wring_ltl(self)
|
||||
elif format == 'latex' or format == 'x':
|
||||
return str_latex_psl(self, parenth)
|
||||
elif format == 'sclatex' or format == 'X':
|
||||
return str_sclatex_psl(self, parenth)
|
||||
else:
|
||||
raise ValueError("unknown string format: " + format)
|
||||
|
||||
def __format__(self, spec):
|
||||
"""Format the formula according to `spec`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
spec : str, optional
|
||||
a list of letters that specify how the formula
|
||||
should be formatted.
|
||||
|
||||
Supported specifiers
|
||||
--------------------
|
||||
|
||||
- 'f': use Spot's syntax (default)
|
||||
- '8': use Spot's syntax in UTF-8 mode
|
||||
- 's': use Spin's syntax
|
||||
- 'l': use LBT's syntax
|
||||
- 'w': use Wring's syntax
|
||||
- 'x': use LaTeX output
|
||||
- 'X': use self-contained LaTeX output
|
||||
|
||||
Add some of those letters for additional options:
|
||||
|
||||
- 'p': use full parentheses
|
||||
- 'c': escape the formula for CSV output (this will
|
||||
enclose the formula in double quotes, and escape
|
||||
any included double quotes)
|
||||
- 'h': escape the formula for HTML output
|
||||
- 'd': escape double quotes and backslash,
|
||||
for use in C-strings (the outermost double
|
||||
quotes are *not* added)
|
||||
- 'q': quote and escape for shell output, using single
|
||||
quotes or double quotes depending on the contents.
|
||||
|
||||
- ':spec': pass the remaining specification to the
|
||||
formating function for strings.
|
||||
|
||||
"""
|
||||
|
||||
syntax = 'f'
|
||||
parent = False
|
||||
escape = None
|
||||
|
||||
while spec:
|
||||
c, spec = spec[0], spec[1:]
|
||||
if c in ('f', 's', '8', 'l', 'w', 'x', 'X'):
|
||||
syntax = c
|
||||
elif c == 'p':
|
||||
parent = True
|
||||
elif c in ('c', 'd', 'h', 'q'):
|
||||
escape = c
|
||||
elif c == ':':
|
||||
break
|
||||
else:
|
||||
raise ValueError("unknown format specification: " + c + spec)
|
||||
|
||||
s = self.to_str(syntax, parent)
|
||||
|
||||
if escape == 'c':
|
||||
o = ostringstream()
|
||||
escape_rfc4180(o, s)
|
||||
s = '"' + o.str() + '"'
|
||||
elif escape == 'd':
|
||||
s = escape_str(s)
|
||||
elif escape == 'h':
|
||||
o = ostringstream()
|
||||
escape_html(o, s)
|
||||
s = o.str()
|
||||
elif escape == 'q':
|
||||
o = ostringstream()
|
||||
quote_shell_string(o, s)
|
||||
s = o.str()
|
||||
|
||||
return s.__format__(spec)
|
||||
|
||||
def traverse(self, func):
|
||||
if func(self):
|
||||
return
|
||||
for f in self:
|
||||
f.traverse(func)
|
||||
|
||||
def map(self, func):
|
||||
k = self.kind()
|
||||
if k in (op_ff, op_tt, op_eword, op_ap):
|
||||
return self
|
||||
if k in (op_Not, op_X, op_F, op_G, op_Closure,
|
||||
op_NegClosure, op_NegClosureMarked):
|
||||
return formula.unop(k, func(self[0]))
|
||||
if k in (op_Xor, op_Implies, op_Equiv, op_U, op_R, op_W,
|
||||
op_M, op_EConcat, op_EConcatMarked, op_UConcat):
|
||||
return formula.binop(k, func(self[0]), func(self[1]))
|
||||
if k in (op_Or, op_OrRat, op_And, op_AndRat, op_AndNLM,
|
||||
op_Concat, op_Fusion):
|
||||
return formula.multop(k, [func(x) for x in self])
|
||||
if k in (op_Star, op_FStar):
|
||||
return formula.bunop(k, func(self[0]), self.min(), self.max())
|
||||
raise ValueError("unknown type of formula")
|
||||
|
||||
|
||||
def automata(*sources, timeout=None, ignore_abort=True,
|
||||
trust_hoa=True, debug=False):
|
||||
"""Read automata from a list of sources.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
*sources : list of str
|
||||
These sources can be either commands (end with `|`),
|
||||
textual represantations of automata (contain `\n`),
|
||||
or filenames (else).
|
||||
timeout : int, optional
|
||||
Number of seconds to wait for the result of a command.
|
||||
If None (the default), not limit is used.
|
||||
ignore_abort : bool, optional
|
||||
If True (the default), skip HOA atomata that ends with
|
||||
`--ABORT--`, and return the next automaton in the stream.
|
||||
If False, aborted automata are reported as syntax errors.
|
||||
trust_hoa : bool, optional
|
||||
If True (the default), supported HOA properies that
|
||||
cannot be easily verified are trusted.
|
||||
debug : bool, optional
|
||||
Whether to run the parser in debug mode.
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
The automata can be written in the `HOA format`_, as `never
|
||||
claims`_, in `LBTT's format`_, or in `ltl2dstar's format`_.
|
||||
|
||||
.. _HOA format: http://adl.github.io/hoaf/
|
||||
.. _never claims: http://spinroot.com/spin/Man/never.html
|
||||
.. _LBTT's format:
|
||||
http://www.tcs.hut.fi/Software/lbtt/doc/html/Format-for-automata.html
|
||||
.. _ltl2dstar's format:
|
||||
http://www.ltl2dstar.de/docs/ltl2dstar.html#output-format-dstar
|
||||
|
||||
If an argument ends with a `|`, then this argument is interpreted as
|
||||
a shell command, and the output of that command (without the `|`)
|
||||
is parsed.
|
||||
|
||||
If an argument contains a newline, then it is interpreted as
|
||||
actual contents to be parsed.
|
||||
|
||||
Otherwise, the argument is assumed to be a filename.
|
||||
|
||||
The result of this function is a generator on all the automata
|
||||
objects read from these sources. The typical usage is::
|
||||
|
||||
for aut in spot.automata(filename, command, ...):
|
||||
# do something with aut
|
||||
|
||||
When the source is a command, and no `timeout` is specified,
|
||||
parsing is done straight out of the pipe connecting the
|
||||
command. So
|
||||
|
||||
for aut in spot.automata('randaut -H -n 10 2 |'):
|
||||
process(aut)
|
||||
|
||||
will call `process(aut)` on each automaton as soon as it is output by
|
||||
`randaut`, and without waiting for `randaut` to terminate.
|
||||
|
||||
However if `timeout` is passed, then `automata()` will wait for
|
||||
the entire command to terminate before parsing its entire output.
|
||||
If one command takes more than `timeout` seconds,
|
||||
`subprocess.TimeoutExpired` is raised.
|
||||
|
||||
If any command terminates with a non-zero error,
|
||||
`subprocess.CalledProcessError` is raised.
|
||||
"""
|
||||
|
||||
o = automaton_parser_options()
|
||||
o.debug = debug
|
||||
o.ignore_abort = ignore_abort
|
||||
o.trust_hoa = trust_hoa
|
||||
o.raise_errors = True
|
||||
for filename in sources:
|
||||
try:
|
||||
p = None
|
||||
proc = None
|
||||
if filename[-1] == '|':
|
||||
# universal_newlines for str output instead of bytes
|
||||
# when the pipe is read from Python (which happens
|
||||
# when timeout is set).
|
||||
proc = subprocess.Popen(filename[:-1], shell=True,
|
||||
preexec_fn=os.setsid,
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE)
|
||||
if timeout is None:
|
||||
p = automaton_stream_parser(proc.stdout.fileno(),
|
||||
filename, o)
|
||||
else:
|
||||
try:
|
||||
out, err = proc.communicate(timeout=timeout)
|
||||
except subprocess.TimeoutExpired:
|
||||
# Using subprocess.check_output() with timeout
|
||||
# would just kill the shell, not its children.
|
||||
os.killpg(proc.pid, signal.SIGKILL)
|
||||
raise
|
||||
else:
|
||||
ret = proc.wait()
|
||||
if ret:
|
||||
raise subprocess.CalledProcessError(ret,
|
||||
filename[:-1])
|
||||
finally:
|
||||
proc = None
|
||||
p = automaton_stream_parser(out, filename, o)
|
||||
elif '\n' in filename:
|
||||
p = automaton_stream_parser(filename, "<string>", o)
|
||||
else:
|
||||
p = automaton_stream_parser(filename, o)
|
||||
a = True
|
||||
while a:
|
||||
# This returns None when we reach the end of the file.
|
||||
a = p.parse(_bdd_dict).aut
|
||||
if a:
|
||||
yield a
|
||||
finally:
|
||||
# Make sure we destroy the parser (p) and the subprocess
|
||||
# (prop) in the correct order...
|
||||
del p
|
||||
if proc is not None:
|
||||
if not a:
|
||||
# We reached the end of the stream. Wait for the
|
||||
# process to finish, so that we get its exit code.
|
||||
ret = proc.wait()
|
||||
else:
|
||||
# if a != None, we probably got there through an
|
||||
# exception, and the subprocess might still be
|
||||
# running. Check if an exit status is available
|
||||
# just in case.
|
||||
ret = proc.poll()
|
||||
del proc
|
||||
if ret:
|
||||
raise subprocess.CalledProcessError(ret, filename[:-1])
|
||||
# deleting o explicitely now prevents Python 3.5 from
|
||||
# reporting the following error: "<built-in function
|
||||
# delete_automaton_parser_options> returned a result with
|
||||
# an error set". It's not clear to me if the bug is in Python
|
||||
# or Swig. At least it's related to the use of generators.
|
||||
del o
|
||||
return
|
||||
|
||||
|
||||
def automaton(filename, **kwargs):
|
||||
"""Read a single automaton from a file.
|
||||
|
||||
See `spot.automata` for a list of supported formats."""
|
||||
try:
|
||||
return next(automata(filename, **kwargs))
|
||||
except StopIteration:
|
||||
raise RuntimeError("Failed to read automaton from {}".format(filename))
|
||||
|
||||
|
||||
def _postproc_translate_options(obj, default_type, *args):
|
||||
type_ = None
|
||||
pref_ = None
|
||||
optm_ = None
|
||||
comp_ = 0
|
||||
unam_ = 0
|
||||
sbac_ = 0
|
||||
|
||||
def type_set(val):
|
||||
nonlocal type_
|
||||
if type_ is not None and type_ != val:
|
||||
raise ValueError("type cannot be both {} and {}"
|
||||
.format(type_, val))
|
||||
elif val == 'generic':
|
||||
type_ = postprocessor.Generic
|
||||
elif val == 'tgba':
|
||||
type_ = postprocessor.TGBA
|
||||
elif val == 'ba':
|
||||
type_ = postprocessor.BA
|
||||
else:
|
||||
assert(val == 'monitor')
|
||||
type_ = postprocessor.Monitor
|
||||
|
||||
def pref_set(val):
|
||||
nonlocal pref_
|
||||
if pref_ is not None and pref_ != val:
|
||||
raise ValueError("preference cannot be both {} and {}"
|
||||
.format(pref_, val))
|
||||
elif val == 'small':
|
||||
pref_ = postprocessor.Small
|
||||
elif val == 'deterministic':
|
||||
pref_ = postprocessor.Deterministic
|
||||
else:
|
||||
assert(val == 'any')
|
||||
pref_ = postprocessor.Any
|
||||
|
||||
def optm_set(val):
|
||||
nonlocal optm_
|
||||
if optm_ is not None and optm_ != val:
|
||||
raise ValueError("optimization level cannot be both {} and {}"
|
||||
.format(optm_, val))
|
||||
if val == 'high':
|
||||
optm_ = postprocessor.High
|
||||
elif val.startswith('med'):
|
||||
optm_ = postprocessor.Medium
|
||||
else:
|
||||
assert(val == 'low')
|
||||
optm_ = postprocessor.Low
|
||||
|
||||
def misc_set(val):
|
||||
nonlocal comp_, unam_, sbac_
|
||||
if val == 'complete':
|
||||
comp_ = postprocessor.Complete
|
||||
elif val == 'sbacc' or val == 'state-based-acceptance':
|
||||
sbac_ = postprocessor.SBAcc
|
||||
else:
|
||||
assert(val == 'unambiguous')
|
||||
unam_ = postprocessor.Unambiguous
|
||||
|
||||
options = {
|
||||
'tgba': type_set,
|
||||
'ba': type_set,
|
||||
'monitor': type_set,
|
||||
'generic': type_set,
|
||||
'small': pref_set,
|
||||
'deterministic': pref_set,
|
||||
'any': pref_set,
|
||||
'high': optm_set,
|
||||
'medium': optm_set,
|
||||
'low': optm_set,
|
||||
'complete': misc_set,
|
||||
'unambiguous': misc_set,
|
||||
'statebasedacceptance': misc_set,
|
||||
'sbacc': misc_set,
|
||||
}
|
||||
|
||||
for arg in args:
|
||||
arg = arg.lower()
|
||||
fn = options.get(arg)
|
||||
if fn:
|
||||
fn(arg)
|
||||
else:
|
||||
# arg is not an know option, but maybe it is a prefix of
|
||||
# one of them
|
||||
compat = []
|
||||
f = None
|
||||
for key, fn in options.items():
|
||||
if key.startswith(arg):
|
||||
compat.append(key)
|
||||
f = fn
|
||||
lc = len(compat)
|
||||
if lc == 1:
|
||||
f(compat[0])
|
||||
elif lc < 1:
|
||||
raise ValueError("unknown option '{}'".format(arg))
|
||||
else:
|
||||
raise ValueError("ambiguous option '{}' is prefix of {}"
|
||||
.format(arg, str(compat)))
|
||||
|
||||
if type_ is None:
|
||||
type_ = default_type
|
||||
if pref_ is None:
|
||||
pref_ = postprocessor.Small
|
||||
if optm_ is None:
|
||||
optm_ = postprocessor.High
|
||||
|
||||
obj.set_type(type_)
|
||||
obj.set_pref(pref_ | comp_ | unam_ | sbac_)
|
||||
obj.set_level(optm_)
|
||||
|
||||
|
||||
def translate(formula, *args):
|
||||
"""Translate a formula into an automaton.
|
||||
|
||||
Keep in mind that 'Deterministic' expresses just a preference that
|
||||
may not be satisfied.
|
||||
|
||||
The optional arguments should be strings among the following:
|
||||
- at most one in 'TGBA', 'BA', or 'Monitor'
|
||||
(type of automaton to build)
|
||||
- at most one in 'Small', 'Deterministic', 'Any'
|
||||
(preferred characteristics of the produced automaton)
|
||||
- at most one in 'Low', 'Medium', 'High'
|
||||
(optimization level)
|
||||
- any combination of 'Complete', 'Unambiguous', and
|
||||
'StateBasedAcceptance' (or 'SBAcc' for short)
|
||||
|
||||
The default corresponds to 'tgba', 'small' and 'high'.
|
||||
"""
|
||||
a = translator(_bdd_dict)
|
||||
_postproc_translate_options(a, postprocessor.TGBA, *args)
|
||||
if type(formula) == str:
|
||||
formula = parse_formula(formula)
|
||||
return a.run(formula)
|
||||
|
||||
|
||||
formula.translate = translate
|
||||
|
||||
|
||||
def postprocess(automaton, *args, formula=None):
|
||||
"""Post process an automaton.
|
||||
|
||||
This applies a number of simlification algorithms, depending on
|
||||
the options supplied. Keep in mind that 'Deterministic' expresses
|
||||
just a preference that may not be satisfied if the input is
|
||||
not already 'Deterministic'.
|
||||
|
||||
The optional arguments should be strings among the following:
|
||||
- at most one in 'Generic', 'TGBA', 'BA', or 'Monitor'
|
||||
(type of automaton to build)
|
||||
- at most one in 'Small', 'Deterministic', 'Any'
|
||||
(preferred characteristics of the produced automaton)
|
||||
- at most one in 'Low', 'Medium', 'High'
|
||||
(optimization level)
|
||||
- any combination of 'Complete' and 'StateBasedAcceptance'
|
||||
(or 'SBAcc' for short)
|
||||
|
||||
The default corresponds to 'generic', 'small' and 'high'.
|
||||
|
||||
If a formula denoted by this automaton is known, pass it to as the
|
||||
optional `formula` argument; it can help some algorithms by
|
||||
providing an easy way to complement the automaton.
|
||||
"""
|
||||
p = postprocessor()
|
||||
if type(automaton) == str:
|
||||
automaton = globals()['automaton'](automaton)
|
||||
_postproc_translate_options(p, postprocessor.Generic, *args)
|
||||
return p.run(automaton, formula)
|
||||
|
||||
|
||||
twa.postprocess = postprocess
|
||||
|
||||
# Wrap C++-functions into lambdas so that they get converted into
|
||||
# instance methods (i.e., self passed as first argument
|
||||
# automatically), because only used-defined functions are converted as
|
||||
# instance methods.
|
||||
def _add_twa_graph(meth):
|
||||
setattr(twa_graph, meth, (lambda self, *args, **kwargs:
|
||||
globals()[meth](self, *args, **kwargs)))
|
||||
|
||||
for meth in ('scc_filter', 'scc_filter_states',
|
||||
'is_deterministic', 'is_unambiguous'):
|
||||
_add_twa_graph(meth)
|
||||
|
||||
# Wrapper around a formula iterator to which we add some methods of formula
|
||||
# (using _addfilter and _addmap), so that we can write things like
|
||||
# formulas.simplify().is_X_free().
|
||||
class formulaiterator:
|
||||
def __init__(self, formulas):
|
||||
self._formulas = formulas
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
return next(self._formulas)
|
||||
|
||||
|
||||
# fun shoud be a predicate and should be a method of formula.
|
||||
# _addfilter adds this predicate as a filter whith the same name in
|
||||
# formulaiterator.
|
||||
def _addfilter(fun):
|
||||
def filtf(self, *args, **kwargs):
|
||||
it = filter(lambda f: getattr(f, fun)(*args, **kwargs), self)
|
||||
return formulaiterator(it)
|
||||
|
||||
def nfiltf(self, *args, **kwargs):
|
||||
it = filter(lambda f: not getattr(f, fun)(*args, **kwargs), self)
|
||||
return formulaiterator(it)
|
||||
|
||||
if fun[:3] == 'is_':
|
||||
notfun = 'is_not_' + fun[3:]
|
||||
elif fun[:4] == 'has_':
|
||||
notfun = 'has_no_' + fun[4:]
|
||||
else:
|
||||
notfun = 'not_' + fun
|
||||
setattr(formulaiterator, fun, filtf)
|
||||
setattr(formulaiterator, notfun, nfiltf)
|
||||
|
||||
|
||||
# fun should be a function taking a formula as its first parameter and
|
||||
# returning a formula. _addmap adds this function as a method of
|
||||
# formula and formulaiterator.
|
||||
def _addmap(fun):
|
||||
def mapf(self, *args, **kwargs):
|
||||
return formulaiterator(map(lambda f: getattr(f, fun)(*args, **kwargs),
|
||||
self))
|
||||
setattr(formula, fun,
|
||||
lambda self, *args, **kwargs:
|
||||
globals()[fun](self, *args, **kwargs))
|
||||
setattr(formulaiterator, fun, mapf)
|
||||
|
||||
|
||||
def randltl(ap, n=-1, **kwargs):
|
||||
"""Generate random formulas.
|
||||
|
||||
Returns a random formula iterator.
|
||||
|
||||
ap: the number of atomic propositions used to generate random formulas.
|
||||
|
||||
n: number of formulas to generate, or unbounded if n < 0.
|
||||
|
||||
**kwargs:
|
||||
seed: seed for the random number generator (0).
|
||||
output: can be 'ltl', 'psl', 'bool' or 'sere' ('ltl').
|
||||
allow_dups: allow duplicate formulas (False).
|
||||
tree_size: tree size of the formulas generated, before mandatory
|
||||
simplifications (15)
|
||||
boolean_priorities: set priorities for Boolean formulas.
|
||||
ltl_priorities: set priorities for LTL formulas.
|
||||
sere_priorities: set priorities for SERE formulas.
|
||||
dump_priorities: show current priorities, do not generate any formula.
|
||||
simplify:
|
||||
0 No rewriting
|
||||
1 basic rewritings and eventual/universal rules
|
||||
2 additional syntactic implication rules
|
||||
3 (default) better implications using containment
|
||||
"""
|
||||
opts = option_map()
|
||||
output_map = {
|
||||
"ltl": OUTPUTLTL,
|
||||
"psl": OUTPUTPSL,
|
||||
"bool": OUTPUTBOOL,
|
||||
"sere": OUTPUTSERE
|
||||
}
|
||||
|
||||
if isinstance(ap, list):
|
||||
aprops = atomic_prop_set()
|
||||
for elt in ap:
|
||||
aprops.insert(formula.ap(elt))
|
||||
ap = aprops
|
||||
ltl_priorities = kwargs.get("ltl_priorities", None)
|
||||
sere_priorities = kwargs.get("sere_priorities", None)
|
||||
boolean_priorities = kwargs.get("boolean_priorities", None)
|
||||
output = output_map[kwargs.get("output", "ltl")]
|
||||
opts.set("output", output)
|
||||
opts.set("seed", kwargs.get("seed", 0))
|
||||
tree_size = kwargs.get("tree_size", 15)
|
||||
if isinstance(tree_size, tuple):
|
||||
tree_size_min, tree_size_max = tree_size
|
||||
else:
|
||||
tree_size_min = tree_size_max = tree_size
|
||||
opts.set("tree_size_min", tree_size_min)
|
||||
opts.set("tree_size_max", tree_size_max)
|
||||
opts.set("unique", not kwargs.get("allow_dups", False))
|
||||
opts.set("wf", kwargs.get("weak_fairness", False))
|
||||
simpl_level = kwargs.get("simplify", 0)
|
||||
if simpl_level > 3 or simpl_level < 0:
|
||||
sys.stderr.write('invalid simplification level: ' + simpl_level)
|
||||
return
|
||||
opts.set("simplification_level", simpl_level)
|
||||
|
||||
rg = randltlgenerator(ap, opts, ltl_priorities, sere_priorities,
|
||||
boolean_priorities)
|
||||
|
||||
dump_priorities = kwargs.get("dump_priorities", False)
|
||||
if dump_priorities:
|
||||
dumpstream = ostringstream()
|
||||
if output == OUTPUTLTL:
|
||||
print('Use argument ltl_priorities=STRING to set the following '
|
||||
'LTL priorities:\n')
|
||||
rg.dump_ltl_priorities(dumpstream)
|
||||
print(dumpstream.str())
|
||||
elif output == OUTPUTBOOL:
|
||||
print('Use argument boolean_priorities=STRING to set the '
|
||||
'following Boolean formula priorities:\n')
|
||||
rg.dump_bool_priorities(dumpstream)
|
||||
print(dumpstream.str())
|
||||
elif output == OUTPUTPSL or output == OUTPUTSERE:
|
||||
if output != OUTPUTSERE:
|
||||
print('Use argument ltl_priorities=STRING to set the '
|
||||
'following LTL priorities:\n')
|
||||
rg.dump_psl_priorities(dumpstream)
|
||||
print(dumpstream.str())
|
||||
print('Use argument sere_priorities=STRING to set the '
|
||||
'following SERE priorities:\n')
|
||||
rg.dump_sere_priorities(dumpstream)
|
||||
print(dumpstream.str())
|
||||
print('Use argument boolean_priorities=STRING to set the '
|
||||
'following Boolean formula priorities:\n')
|
||||
rg.dump_sere_bool_priorities(dumpstream)
|
||||
print(dumpstream.str())
|
||||
else:
|
||||
sys.stderr.write("internal error: unknown type of output")
|
||||
return
|
||||
|
||||
class _randltliterator:
|
||||
def __init__(self, rg, n):
|
||||
self.rg = rg
|
||||
self.i = 0
|
||||
self.n = n
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.i == self.n:
|
||||
raise StopIteration
|
||||
f = self.rg.next()
|
||||
if f is None:
|
||||
sys.stderr.write("Warning: could not generate a new "
|
||||
"unique formula after {} trials.\n"
|
||||
.format(MAX_TRIALS))
|
||||
raise StopIteration
|
||||
self.i += 1
|
||||
return f
|
||||
|
||||
return formulaiterator(_randltliterator(rg, n))
|
||||
|
||||
|
||||
def simplify(f, **kwargs):
|
||||
level = kwargs.get('level', None)
|
||||
if level is not None:
|
||||
return tl_simplifier(tl_simplifier_options(level)).simplify(f)
|
||||
|
||||
basics = kwargs.get('basics', True)
|
||||
synt_impl = kwargs.get('synt_impl', True)
|
||||
event_univ = kwargs.get('event_univ', True)
|
||||
cont_checks = kwargs.get('containment_checks', False)
|
||||
cont_checks_stronger = kwargs.get('containment_checks_stronger', False)
|
||||
nenoform_stop_on_boolean = kwargs.get('nenoform_stop_on_boolean', False)
|
||||
reduce_size_strictly = kwargs.get('reduce_size_strictly', False)
|
||||
boolean_to_isop = kwargs.get('boolean_to_isop', False)
|
||||
favor_event_univ = kwargs.get('favor_event_univ', False)
|
||||
|
||||
simp_opts = tl_simplifier_options(basics,
|
||||
synt_impl,
|
||||
event_univ,
|
||||
cont_checks,
|
||||
cont_checks_stronger,
|
||||
nenoform_stop_on_boolean,
|
||||
reduce_size_strictly,
|
||||
boolean_to_isop,
|
||||
favor_event_univ)
|
||||
return tl_simplifier(simp_opts).simplify(f)
|
||||
|
||||
|
||||
for fun in dir(formula):
|
||||
if (callable(getattr(formula, fun)) and (fun[:3] == 'is_' or
|
||||
fun[:4] == 'has_')):
|
||||
_addfilter(fun)
|
||||
|
||||
for fun in ['remove_x', 'relabel', 'relabel_bse',
|
||||
'simplify', 'unabbreviate']:
|
||||
_addmap(fun)
|
||||
|
||||
|
||||
|
||||
# Better interface to the corresponding C++ function.
|
||||
def sat_minimize(aut, acc=None, colored=False,
|
||||
state_based=False, states=0,
|
||||
max_states=0, dichotomy=False):
|
||||
args=''
|
||||
if acc is not None:
|
||||
if type(acc) is not str:
|
||||
raise ValueError("argument 'acc' should be a string")
|
||||
args += ',acc="' + acc + '"'
|
||||
if colored:
|
||||
args += ',colored'
|
||||
if states:
|
||||
if type(states) is not int or states < 0:
|
||||
raise ValueError("argument 'states' should be a positive integer")
|
||||
args += ',states=' + str(states)
|
||||
if max_states:
|
||||
if type(max_states) is not int or max_states < 0:
|
||||
raise ValueError("argument 'states' should be a positive integer")
|
||||
args += ',max-states=' + str(max_states)
|
||||
if dichotomy:
|
||||
args += ',dichotomy';
|
||||
from spot_impl import sat_minimize as sm
|
||||
return sm(aut, args, state_based)
|
||||
694
python/spot_impl.i
Normal file
694
python/spot_impl.i
Normal file
|
|
@ -0,0 +1,694 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire de
|
||||
// Recherche et Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2003, 2004, 2005, 2006 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/>.
|
||||
|
||||
%{
|
||||
// Workaround for SWIG 2.0.2 using ptrdiff_t but not including cstddef.
|
||||
// It matters with g++ 4.6.
|
||||
#include <cstddef>
|
||||
%}
|
||||
|
||||
%module(director="1") spot_impl
|
||||
|
||||
%include "std_shared_ptr.i"
|
||||
%include "std_vector.i"
|
||||
%include "std_string.i"
|
||||
%include "std_list.i"
|
||||
%include "std_set.i"
|
||||
%include "std_map.i"
|
||||
%include "std_pair.i"
|
||||
%include "stdint.i"
|
||||
%include "exception.i"
|
||||
%include "typemaps.i"
|
||||
|
||||
// git grep 'typedef.*std::shared_ptr' | grep -v const |
|
||||
// sed 's/.*<\(.*\)>.*/%shared_ptr(spot::\1)/g'
|
||||
%shared_ptr(spot::dstar_aut)
|
||||
%shared_ptr(spot::parsed_aut)
|
||||
%shared_ptr(spot::fair_kripke)
|
||||
%shared_ptr(spot::kripke)
|
||||
%shared_ptr(spot::kripke_graph)
|
||||
%shared_ptr(spot::kripke)
|
||||
%shared_ptr(spot::ta)
|
||||
%shared_ptr(spot::ta_explicit)
|
||||
%shared_ptr(spot::ta_product)
|
||||
%shared_ptr(spot::tgta)
|
||||
%shared_ptr(spot::tgta_explicit)
|
||||
%shared_ptr(spot::bdd_dict)
|
||||
%shared_ptr(spot::twa)
|
||||
%shared_ptr(spot::twa_graph)
|
||||
%shared_ptr(spot::twa_product)
|
||||
%shared_ptr(spot::twa_product_init)
|
||||
%shared_ptr(spot::taa_tgba)
|
||||
%shared_ptr(spot::taa_tgba_string)
|
||||
%shared_ptr(spot::taa_tgba_formula)
|
||||
%shared_ptr(spot::twa_safra_complement)
|
||||
%shared_ptr(spot::twa_run)
|
||||
%shared_ptr(spot::emptiness_check_result)
|
||||
%shared_ptr(spot::emptiness_check)
|
||||
%shared_ptr(spot::emptiness_check_instantiator)
|
||||
%shared_ptr(spot::tgbasl)
|
||||
|
||||
%import "buddy.i"
|
||||
|
||||
%{
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <signal.h>
|
||||
|
||||
#include <spot/misc/common.hh>
|
||||
#include <spot/misc/version.hh>
|
||||
#include <spot/misc/minato.hh>
|
||||
#include <spot/misc/optionmap.hh>
|
||||
#include <spot/misc/random.hh>
|
||||
#include <spot/misc/escape.hh>
|
||||
|
||||
#include <spot/tl/formula.hh>
|
||||
|
||||
#include <spot/tl/environment.hh>
|
||||
#include <spot/tl/defaultenv.hh>
|
||||
|
||||
#include <spot/tl/parse.hh>
|
||||
|
||||
#include <spot/twa/bdddict.hh>
|
||||
|
||||
#include <spot/tl/apcollect.hh>
|
||||
#include <spot/tl/dot.hh>
|
||||
#include <spot/tl/nenoform.hh>
|
||||
#include <spot/tl/print.hh>
|
||||
#include <spot/tl/simplify.hh>
|
||||
#include <spot/tl/unabbrev.hh>
|
||||
#include <spot/tl/randomltl.hh>
|
||||
#include <spot/tl/length.hh>
|
||||
#include <spot/tl/remove_x.hh>
|
||||
#include <spot/tl/relabel.hh>
|
||||
|
||||
#include <spot/twa/bddprint.hh>
|
||||
#include <spot/twa/fwd.hh>
|
||||
#include <spot/twa/acc.hh>
|
||||
#include <spot/twa/twa.hh>
|
||||
#include <spot/twa/taatgba.hh>
|
||||
#include <spot/twa/twaproduct.hh>
|
||||
|
||||
#include <spot/twaalgos/cleanacc.hh>
|
||||
#include <spot/twaalgos/degen.hh>
|
||||
#include <spot/twaalgos/dot.hh>
|
||||
#include <spot/twaalgos/copy.hh>
|
||||
#include <spot/twaalgos/complete.hh>
|
||||
#include <spot/twaalgos/complement.hh>
|
||||
#include <spot/twaalgos/emptiness.hh>
|
||||
#include <spot/twaalgos/gtec/gtec.hh>
|
||||
#include <spot/twaalgos/lbtt.hh>
|
||||
#include <spot/twaalgos/ltl2taa.hh>
|
||||
#include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
#include <spot/twaalgos/compsusp.hh>
|
||||
#include <spot/twaalgos/magic.hh>
|
||||
#include <spot/twaalgos/minimize.hh>
|
||||
#include <spot/twaalgos/neverclaim.hh>
|
||||
#include <spot/twaalgos/remfin.hh>
|
||||
#include <spot/twaalgos/strength.hh>
|
||||
#include <spot/twaalgos/sccfilter.hh>
|
||||
#include <spot/twaalgos/stats.hh>
|
||||
#include <spot/twaalgos/isdet.hh>
|
||||
#include <spot/twaalgos/isunamb.hh>
|
||||
#include <spot/twaalgos/simulation.hh>
|
||||
#include <spot/twaalgos/postproc.hh>
|
||||
#include <spot/twaalgos/product.hh>
|
||||
#include <spot/twaalgos/stutter.hh>
|
||||
#include <spot/twaalgos/translate.hh>
|
||||
#include <spot/twaalgos/hoa.hh>
|
||||
#include <spot/twaalgos/dtwasat.hh>
|
||||
#include <spot/twaalgos/relabel.hh>
|
||||
|
||||
#include <spot/parseaut/public.hh>
|
||||
|
||||
#include <spot/ta/ta.hh>
|
||||
#include <spot/ta/tgta.hh>
|
||||
#include <spot/ta/taexplicit.hh>
|
||||
#include <spot/ta/tgtaexplicit.hh>
|
||||
#include <spot/taalgos/tgba2ta.hh>
|
||||
#include <spot/taalgos/dot.hh>
|
||||
#include <spot/taalgos/stats.hh>
|
||||
#include <spot/taalgos/minimize.hh>
|
||||
|
||||
using namespace spot;
|
||||
%}
|
||||
|
||||
|
||||
// Swig come with iterators that implement a decrement method.
|
||||
// This is not supported in our "successor" iterators.
|
||||
%fragment("ForwardIterator_T","header",fragment="SwigPyIterator_T") {
|
||||
namespace swig
|
||||
{
|
||||
template<typename OutIterator,
|
||||
typename ValueType =
|
||||
typename std::iterator_traits<OutIterator>::value_type,
|
||||
typename FromOper = from_oper<ValueType> >
|
||||
class ForwardIterator_T : public SwigPyIterator_T<OutIterator>
|
||||
{
|
||||
public:
|
||||
FromOper from;
|
||||
typedef OutIterator out_iterator;
|
||||
typedef ValueType value_type;
|
||||
typedef SwigPyIterator_T<out_iterator> base;
|
||||
typedef ForwardIterator_T<OutIterator, ValueType, FromOper> self_type;
|
||||
|
||||
ForwardIterator_T(out_iterator curr, out_iterator first,
|
||||
out_iterator last, PyObject *seq)
|
||||
: SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last)
|
||||
{
|
||||
}
|
||||
|
||||
PyObject *value() const {
|
||||
if (base::current == end) {
|
||||
throw stop_iteration();
|
||||
} else {
|
||||
return from(static_cast<const value_type&>(*(base::current)));
|
||||
}
|
||||
}
|
||||
|
||||
SwigPyIterator *copy() const
|
||||
{
|
||||
return new self_type(*this);
|
||||
}
|
||||
|
||||
SwigPyIterator *incr(size_t n = 1)
|
||||
{
|
||||
while (n--) {
|
||||
if (base::current == end) {
|
||||
throw stop_iteration();
|
||||
} else {
|
||||
++base::current;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private:
|
||||
out_iterator begin;
|
||||
out_iterator end;
|
||||
};
|
||||
|
||||
template<typename OutIter>
|
||||
inline SwigPyIterator*
|
||||
make_forward_iterator(const OutIter& current,
|
||||
const OutIter& begin,
|
||||
const OutIter& end, PyObject *seq = 0)
|
||||
{
|
||||
return new ForwardIterator_T<OutIter>(current, begin, end, seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
%fragment("ForwardIterator_T");
|
||||
|
||||
// For spot::emptiness_check_instantiator::construct and any other
|
||||
// function that return errors via a "char **err" argument.
|
||||
%typemap(in, numinputs=0) char** OUTPUT (char* temp) {
|
||||
$1 = &temp;
|
||||
}
|
||||
%typemap(argout) char** OUTPUT {
|
||||
PyObject *obj = SWIG_FromCharPtr(*$1);
|
||||
if (!$result) {
|
||||
$result = obj;
|
||||
//# If the function returns null_ptr (i.e. Py_None), we
|
||||
//# don't want to override it with OUTPUT as in the
|
||||
//# default implementation of t_output_helper.
|
||||
// } else if ($result == Py_None) {
|
||||
// Py_DECREF($result);
|
||||
// $result = obj;
|
||||
} else {
|
||||
if (!PyList_Check($result)) {
|
||||
PyObject *o2 = $result;
|
||||
$result = PyList_New(1);
|
||||
PyList_SetItem($result, 0, o2);
|
||||
}
|
||||
PyList_Append($result, obj);
|
||||
Py_DECREF(obj);
|
||||
}
|
||||
|
||||
};
|
||||
%apply char** OUTPUT { char** err };
|
||||
|
||||
// This is mainly for acc_cond::is_parity()
|
||||
%typemap(in, numinputs=0) bool& (bool temp) {
|
||||
$1 = &temp;
|
||||
};
|
||||
%typemap(argout) bool& {
|
||||
PyObject *obj = SWIG_From_bool(*$1);
|
||||
if (!$result) {
|
||||
$result = obj;
|
||||
} else {
|
||||
if (!PyList_Check($result)) {
|
||||
PyObject *o2 = $result;
|
||||
$result = PyList_New(1);
|
||||
PyList_SetItem($result, 0, o2);
|
||||
}
|
||||
PyList_Append($result, obj);
|
||||
Py_DECREF(obj);
|
||||
}
|
||||
};
|
||||
|
||||
// Allow None to be passed for formula. Some functions like
|
||||
// postprocessor::run() take an optional formula that defaults to
|
||||
// nullptr. So it make sense to have function that take formulas that
|
||||
// default to None on the Python side.
|
||||
%typemap(in) spot::formula {
|
||||
void *tmp;
|
||||
int res = SWIG_ConvertPtr($input, &tmp, $descriptor(spot::formula*), 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
%argument_fail(res, "spot::formula", $symname, $argnum);
|
||||
}
|
||||
if (tmp) {
|
||||
spot::formula* temp = reinterpret_cast< spot::formula * >(tmp);
|
||||
$1 = *temp;
|
||||
if (SWIG_IsNewObj(res)) delete temp;
|
||||
}
|
||||
// if tmp == nullptr, then the default value of $1 is fine.
|
||||
}
|
||||
|
||||
%typemap(typecheck) spot::formula {
|
||||
$1 = SWIG_CheckState(SWIG_ConvertPtr($input, nullptr,
|
||||
$descriptor(spot::formula*), 0));
|
||||
}
|
||||
|
||||
%typemap(out) spot::formula {
|
||||
if (!$1)
|
||||
$result = SWIG_Py_Void();
|
||||
else
|
||||
$result = SWIG_NewPointerObj(new spot::formula($1), $descriptor(spot::formula*), SWIG_POINTER_OWN);
|
||||
}
|
||||
|
||||
%typemap(out) std::string* {
|
||||
if (!$1)
|
||||
$result = SWIG_Py_Void();
|
||||
else
|
||||
$result = SWIG_FromCharPtr($1->c_str());
|
||||
}
|
||||
|
||||
%exception {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (const spot::parse_error& e)
|
||||
{
|
||||
std::string er("\n");
|
||||
er += e.what();
|
||||
SWIG_exception(SWIG_SyntaxError, er.c_str());
|
||||
}
|
||||
catch (const std::invalid_argument& e)
|
||||
{
|
||||
SWIG_exception(SWIG_ValueError, e.what());
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
SWIG_exception(SWIG_RuntimeError, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
%include <spot/misc/common.hh>
|
||||
%include <spot/misc/version.hh>
|
||||
%include <spot/misc/minato.hh>
|
||||
%include <spot/misc/optionmap.hh>
|
||||
%include <spot/misc/random.hh>
|
||||
%include <spot/misc/escape.hh>
|
||||
|
||||
%implicitconv std::vector<spot::formula>;
|
||||
|
||||
%include <spot/tl/formula.hh>
|
||||
|
||||
namespace std {
|
||||
%template(liststr) list<std::string>;
|
||||
%template(vectorformula) vector<spot::formula>;
|
||||
%template(vectorunsigned) vector<unsigned>;
|
||||
%template(vectorstring) vector<string>;
|
||||
%template(atomic_prop_set) set<spot::formula>;
|
||||
%template(relabeling_map) map<spot::formula, spot::formula>;
|
||||
}
|
||||
|
||||
%include <spot/tl/environment.hh>
|
||||
%include <spot/tl/defaultenv.hh>
|
||||
|
||||
%include <spot/tl/parse.hh>
|
||||
|
||||
/* these must come before apcollect.hh */
|
||||
%include <spot/twa/bdddict.hh>
|
||||
%include <spot/twa/bddprint.hh>
|
||||
%include <spot/twa/fwd.hh>
|
||||
%implicitconv spot::acc_cond::mark_t;
|
||||
%implicitconv spot::acc_cond::acc_code;
|
||||
%feature("flatnested") spot::acc_cond::mark_t;
|
||||
%feature("flatnested") spot::acc_cond::acc_code;
|
||||
%apply bool* OUTPUT {bool& max, bool& odd};
|
||||
%include <spot/twa/acc.hh>
|
||||
%template(pair_bool_mark) std::pair<bool, spot::acc_cond::mark_t>;
|
||||
|
||||
%include <spot/twa/twa.hh>
|
||||
|
||||
%include <spot/tl/apcollect.hh>
|
||||
%include <spot/tl/dot.hh>
|
||||
%include <spot/tl/nenoform.hh>
|
||||
%include <spot/tl/print.hh>
|
||||
%include <spot/tl/simplify.hh>
|
||||
%include <spot/tl/unabbrev.hh>
|
||||
%include <spot/tl/randomltl.hh>
|
||||
%include <spot/tl/length.hh>
|
||||
%include <spot/tl/remove_x.hh>
|
||||
%include <spot/tl/relabel.hh>
|
||||
|
||||
%include <spot/twa/taatgba.hh>
|
||||
%include <spot/twa/twaproduct.hh>
|
||||
|
||||
%include <spot/graph/graph.hh>
|
||||
%nodefaultctor spot::digraph;
|
||||
%nodefaultctor spot::internal::state_out;
|
||||
%traits_swigtype(spot::internal::edge_storage<unsigned int, unsigned int, unsigned int, spot::internal::boxed_label<spot::twa_graph_edge_data, false> >);
|
||||
%fragment(SWIG_Traits_frag(spot::internal::edge_storage<unsigned int, unsigned int, unsigned int, spot::internal::boxed_label<spot::twa_graph_edge_data, false> >));
|
||||
|
||||
%typemap(out, optimal="1") spot::internal::state_out<spot::digraph<spot::twa_graph_state, spot::twa_graph_edge_data>> {
|
||||
$result = SWIG_NewPointerObj(new $1_ltype($1), $&1_descriptor,
|
||||
SWIG_POINTER_OWN);
|
||||
}
|
||||
|
||||
%noexception spot::twa_graph::out;
|
||||
%include <spot/twa/twagraph.hh>
|
||||
|
||||
%template(twa_graph_state_out) spot::internal::state_out<spot::digraph<spot::twa_graph_state, spot::twa_graph_edge_data>>;
|
||||
%template(twa_graph_edge_boxed_data) spot::internal::boxed_label<spot::twa_graph_edge_data, false>;
|
||||
%template(twa_graph_edge_storage) spot::internal::edge_storage<unsigned int, unsigned int, unsigned int, spot::internal::boxed_label<spot::twa_graph_edge_data, false> >;
|
||||
|
||||
// Should come after the definition of twa_graph
|
||||
|
||||
%include <spot/twaalgos/cleanacc.hh>
|
||||
%include <spot/twaalgos/degen.hh>
|
||||
%include <spot/twaalgos/dot.hh>
|
||||
%include <spot/twaalgos/copy.hh>
|
||||
%include <spot/twaalgos/complete.hh>
|
||||
%include <spot/twaalgos/complement.hh>
|
||||
%include <spot/twaalgos/emptiness.hh>
|
||||
%include <spot/twaalgos/gtec/gtec.hh>
|
||||
%include <spot/twaalgos/lbtt.hh>
|
||||
%include <spot/twaalgos/ltl2taa.hh>
|
||||
%include <spot/twaalgos/ltl2tgba_fm.hh>
|
||||
%include <spot/twaalgos/compsusp.hh>
|
||||
%include <spot/twaalgos/magic.hh>
|
||||
%include <spot/twaalgos/minimize.hh>
|
||||
%include <spot/twaalgos/neverclaim.hh>
|
||||
%include <spot/twaalgos/remfin.hh>
|
||||
%include <spot/twaalgos/strength.hh>
|
||||
%include <spot/twaalgos/sccfilter.hh>
|
||||
%include <spot/twaalgos/stats.hh>
|
||||
%include <spot/twaalgos/isdet.hh>
|
||||
%include <spot/twaalgos/isunamb.hh>
|
||||
%include <spot/twaalgos/simulation.hh>
|
||||
%include <spot/twaalgos/postproc.hh>
|
||||
%include <spot/twaalgos/product.hh>
|
||||
%include <spot/twaalgos/stutter.hh>
|
||||
%include <spot/twaalgos/translate.hh>
|
||||
%include <spot/twaalgos/hoa.hh>
|
||||
%include <spot/twaalgos/dtwasat.hh>
|
||||
%include <spot/twaalgos/relabel.hh>
|
||||
|
||||
%include <spot/parseaut/public.hh>
|
||||
|
||||
%include <spot/ta/ta.hh>
|
||||
%include <spot/ta/tgta.hh>
|
||||
%include <spot/ta/taexplicit.hh>
|
||||
%include <spot/ta/tgtaexplicit.hh>
|
||||
%include <spot/taalgos/tgba2ta.hh>
|
||||
%include <spot/taalgos/dot.hh>
|
||||
%include <spot/taalgos/stats.hh>
|
||||
%include <spot/taalgos/minimize.hh>
|
||||
|
||||
|
||||
#undef ltl
|
||||
|
||||
%exception spot::formula::__getitem__ {
|
||||
try {
|
||||
$action
|
||||
}
|
||||
catch (const std::runtime_error& e)
|
||||
{
|
||||
SWIG_exception(SWIG_IndexError, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
%extend spot::formula {
|
||||
// __cmp__ is for Python 2.0
|
||||
int __cmp__(spot::formula b) { return self->id() - b.id(); }
|
||||
size_t __hash__() { return self->id(); }
|
||||
unsigned __len__() { return self->size(); }
|
||||
formula __getitem__(unsigned pos) { return (*self)[pos]; }
|
||||
|
||||
std::string __repr__() { return spot::str_psl(*self); }
|
||||
std::string _repr_latex_()
|
||||
{
|
||||
return std::string("$") + spot::str_sclatex_psl(*self) + '$';
|
||||
}
|
||||
std::string __str__() { return spot::str_psl(*self); }
|
||||
}
|
||||
|
||||
%extend spot::bdd_dict {
|
||||
bool operator==(const spot::bdd_dict& b) const
|
||||
{
|
||||
return self == &b;
|
||||
}
|
||||
|
||||
bool operator!=(const spot::bdd_dict& b) const
|
||||
{
|
||||
return self != &b;
|
||||
}
|
||||
}
|
||||
|
||||
%extend spot::twa {
|
||||
void set_name(std::string name)
|
||||
{
|
||||
self->set_named_prop("automaton-name", new std::string(name));
|
||||
}
|
||||
|
||||
std::string* get_name()
|
||||
{
|
||||
return self->get_named_prop<std::string>("automaton-name");
|
||||
}
|
||||
|
||||
void set_state_names(std::vector<std::string> names)
|
||||
{
|
||||
self->set_named_prop("state-names",
|
||||
new std::vector<std::string>(std::move(names)));
|
||||
}
|
||||
|
||||
std::vector<std::string>* get_state_names()
|
||||
{
|
||||
return self->get_named_prop<std::vector<std::string>>("state-names");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%extend spot::internal::state_out<spot::digraph<spot::twa_graph_state, spot::twa_graph_edge_data>> {
|
||||
swig::SwigPyIterator* __iter__(PyObject **PYTHON_SELF)
|
||||
{
|
||||
return swig::make_forward_iterator(self->begin(), self->begin(),
|
||||
self->end(), *PYTHON_SELF);
|
||||
}
|
||||
}
|
||||
|
||||
%extend spot::acc_cond::acc_code {
|
||||
std::string __repr__()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << *self;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string __str__()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << *self;
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
%extend spot::acc_cond::mark_t {
|
||||
// http://comments.gmane.org/gmane.comp.programming.swig/14822
|
||||
mark_t(const std::vector<unsigned>& f)
|
||||
{
|
||||
return new spot::acc_cond::mark_t(f.begin(), f.end());
|
||||
}
|
||||
|
||||
std::string __repr__()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << *self;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string __str__()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << *self;
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
%extend spot::acc_cond {
|
||||
std::string __repr__()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << *self;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string __str__()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << *self;
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
%extend spot::twa_run {
|
||||
std::string __str__()
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << *self;
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
%nodefaultctor std::ostream;
|
||||
namespace std {
|
||||
class ostream {};
|
||||
class ofstream : public ostream
|
||||
{
|
||||
public:
|
||||
ofstream(const char *fn);
|
||||
~ofstream();
|
||||
};
|
||||
class ostringstream : public ostream
|
||||
{
|
||||
public:
|
||||
ostringstream();
|
||||
std::string str() const;
|
||||
~ostringstream();
|
||||
};
|
||||
}
|
||||
|
||||
%inline %{
|
||||
bool fnode_instances_check()
|
||||
{
|
||||
return spot::fnode::instances_check();
|
||||
}
|
||||
|
||||
spot::parse_error_list
|
||||
empty_parse_error_list()
|
||||
{
|
||||
parse_error_list l;
|
||||
return l;
|
||||
}
|
||||
|
||||
spot::parse_aut_error_list
|
||||
empty_parse_aut_error_list()
|
||||
{
|
||||
parse_aut_error_list l;
|
||||
return l;
|
||||
}
|
||||
|
||||
spot::twa_graph_ptr
|
||||
ensure_digraph(const spot::twa_ptr& a)
|
||||
{
|
||||
auto aa = std::dynamic_pointer_cast<spot::twa_graph>(a);
|
||||
if (aa)
|
||||
return aa;
|
||||
return spot::make_twa_graph(a, spot::twa::prop_set::all());
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
get_cout()
|
||||
{
|
||||
return std::cout;
|
||||
}
|
||||
|
||||
void
|
||||
nl_cout()
|
||||
{
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
get_cerr()
|
||||
{
|
||||
return std::cerr;
|
||||
}
|
||||
|
||||
void
|
||||
nl_cerr()
|
||||
{
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
print_on(std::ostream& on, const std::string& what)
|
||||
{
|
||||
on << what;
|
||||
}
|
||||
|
||||
int
|
||||
unblock_signal(int signum)
|
||||
{
|
||||
sigset_t set;
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, signum);
|
||||
return sigprocmask(SIG_UNBLOCK, &set, 0);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%extend spot::parse_error_list {
|
||||
|
||||
bool
|
||||
__nonzero__()
|
||||
{
|
||||
return !self->empty();
|
||||
}
|
||||
|
||||
bool
|
||||
__bool__()
|
||||
{
|
||||
return !self->empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
%extend spot::parse_aut_error_list {
|
||||
|
||||
bool
|
||||
__nonzero__()
|
||||
{
|
||||
return !self->empty();
|
||||
}
|
||||
|
||||
bool
|
||||
__bool__()
|
||||
{
|
||||
return !self->empty();
|
||||
}
|
||||
|
||||
}
|
||||
3
python/tests/.gitignore
vendored
Normal file
3
python/tests/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
Makefile
|
||||
Makefile.in
|
||||
run
|
||||
67
python/tests/Makefile.am
Normal file
67
python/tests/Makefile.am
Normal 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
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
177
python/tests/accparse.ipynb
Normal 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
93
python/tests/accparse2.py
Normal 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
66
python/tests/alarm.py
Executable 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)
|
||||
862
python/tests/automata-io.ipynb
Normal file
862
python/tests/automata-io.ipynb
Normal 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 & !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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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 & !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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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 & !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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->0 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>0->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 & !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->1 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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 & !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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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 & !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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->0 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>0->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 & !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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->1 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->1 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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
3175
python/tests/automata.ipynb
Normal file
File diff suppressed because it is too large
Load diff
107
python/tests/bddnqueen.py
Executable file
107
python/tests/bddnqueen.py
Executable 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
5010
python/tests/decompose.ipynb
Normal file
File diff suppressed because it is too large
Load diff
727
python/tests/formulas.ipynb
Normal file
727
python/tests/formulas.ipynb
Normal 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->1 -->\n",
|
||||
"<g class=\"edge\" id=\"edge6\"><title>0->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->7 -->\n",
|
||||
"<g class=\"edge\" id=\"edge9\"><title>0->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge1\"><title>1->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->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge3\"><title>1->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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge5\"><title>1->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->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge2\"><title>3->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->6 -->\n",
|
||||
"<g class=\"edge\" id=\"edge4\"><title>5->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->8 -->\n",
|
||||
"<g class=\"edge\" id=\"edge8\"><title>7->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->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge7\"><title>8->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
61
python/tests/implies.py
Executable 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
58
python/tests/interdep.py
Executable 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
261
python/tests/ipnbdoctest.py
Executable 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
132
python/tests/ltl2tgba.py
Executable 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
50
python/tests/ltl2tgba.test
Executable 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
45
python/tests/ltlparse.py
Executable 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
118
python/tests/ltlsimple.py
Executable 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
47
python/tests/minato.py
Executable 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
59
python/tests/optionmap.py
Executable 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
43
python/tests/parsetgba.py
Executable 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
499
python/tests/piperead.ipynb
Normal 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->0 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>0->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 & !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->1 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->0 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>0->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->0 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>0->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 & !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->1 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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 & !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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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
2001
python/tests/product.ipynb
Normal file
File diff suppressed because it is too large
Load diff
2285
python/tests/randaut.ipynb
Normal file
2285
python/tests/randaut.ipynb
Normal file
File diff suppressed because it is too large
Load diff
26
python/tests/randgen.py
Executable file
26
python/tests/randgen.py
Executable 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
677
python/tests/randltl.ipynb
Normal 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
32
python/tests/relabel.py
Normal 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
49
python/tests/remfin.py
Normal 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
56
python/tests/run.in
Executable 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
49
python/tests/satmin.py
Normal 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
49
python/tests/setxor.py
Executable 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()
|
||||
651
python/tests/testingaut.ipynb
Normal file
651
python/tests/testingaut.ipynb
Normal 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->1 -->\n",
|
||||
"<g id=\"edge1\" class=\"edge\"><title>I->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->1 -->\n",
|
||||
"<g id=\"edge4\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge3\" class=\"edge\"><title>1->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->0 -->\n",
|
||||
"<g id=\"edge2\" class=\"edge\"><title>0->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->1 -->\n",
|
||||
"<g class=\"edge\" id=\"edge1\"><title>0->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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 1->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge2\"><title>1->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 & 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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 1->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge3\"><title>1->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 & 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 & !b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 1->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge4\"><title>1->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 & !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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 2->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge5\"><title>2->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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 2->6 -->\n",
|
||||
"<g class=\"edge\" id=\"edge6\"><title>2->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 & !b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 2->7 -->\n",
|
||||
"<g class=\"edge\" id=\"edge7\"><title>2->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 & !b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 2->8 -->\n",
|
||||
"<g class=\"edge\" id=\"edge8\"><title>2->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge14\"><title>3->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->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge13\"><title>3->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->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge15\"><title>3->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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge9\"><title>3->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->6 -->\n",
|
||||
"<g class=\"edge\" id=\"edge10\"><title>3->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->7 -->\n",
|
||||
"<g class=\"edge\" id=\"edge11\"><title>3->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->8 -->\n",
|
||||
"<g class=\"edge\" id=\"edge12\"><title>3->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 & !b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 3->9 -->\n",
|
||||
"<g class=\"edge\" id=\"edge16\"><title>3->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge18\"><title>4->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->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge17\"><title>4->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->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge19\"><title>4->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->9 -->\n",
|
||||
"<g class=\"edge\" id=\"edge20\"><title>4->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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge21\"><title>5->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->6 -->\n",
|
||||
"<g class=\"edge\" id=\"edge22\"><title>5->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->7 -->\n",
|
||||
"<g class=\"edge\" id=\"edge23\"><title>5->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->8 -->\n",
|
||||
"<g class=\"edge\" id=\"edge24\"><title>5->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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge25\"><title>6->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->6 -->\n",
|
||||
"<g class=\"edge\" id=\"edge26\"><title>6->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->7 -->\n",
|
||||
"<g class=\"edge\" id=\"edge27\"><title>6->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->8 -->\n",
|
||||
"<g class=\"edge\" id=\"edge28\"><title>6->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->1 -->\n",
|
||||
"<g class=\"edge\" id=\"edge1\"><title>0->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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 1->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge2\"><title>1->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 & 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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 1->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge3\"><title>1->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 & 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 & !b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 1->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge4\"><title>1->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 & !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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 2->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge5\"><title>2->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge7\"><title>3->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->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge8\"><title>3->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 & b</text>\n",
|
||||
"</g>\n",
|
||||
"<!-- 3->6 -->\n",
|
||||
"<g class=\"edge\" id=\"edge6\"><title>3->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge10\"><title>4->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->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge9\"><title>4->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->6 -->\n",
|
||||
"<g class=\"edge\" id=\"edge11\"><title>5->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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge12\"><title>6->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->1 -->\n",
|
||||
"<g class=\"edge\" id=\"edge1\"><title>0->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge2\"><title>1->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 & 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->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge3\"><title>1->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 & 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->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge4\"><title>1->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 & !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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge5\"><title>2->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge7\"><title>3->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->4 -->\n",
|
||||
"<g class=\"edge\" id=\"edge8\"><title>3->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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge6\"><title>3->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->2 -->\n",
|
||||
"<g class=\"edge\" id=\"edge10\"><title>4->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->3 -->\n",
|
||||
"<g class=\"edge\" id=\"edge9\"><title>4->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->5 -->\n",
|
||||
"<g class=\"edge\" id=\"edge11\"><title>5->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": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue